Skip to content

Commit

Permalink
feat(satori): refactor to ctx.satori service
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Apr 17, 2024
1 parent e5829d1 commit 8f16bf5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 37 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export abstract class Bot<C extends Context = Context, T = any> implements Login
set status(value) {
if (value === this._status) return
this._status = value
if (this.ctx.bots.includes(this)) {
if (this.ctx.bots?.includes(this)) {
this.context.emit('bot-status-updated', this)
this.dispatchLoginEvent('login-updated')
}
Expand Down
59 changes: 25 additions & 34 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,38 @@ export interface Events<C extends Context = Context> extends cordis.Events<C> {
'bot-disconnect'(client: Bot<C>): Awaitable<void>
}

export interface Events<C extends Context = Context> extends cordis.Events<C> {}

export interface Context {
[Context.events]: Events<this>
[Context.session]: Session<this>
satori: Satori<this>
bots: Bot<this>[] & Dict<Bot<this>>
component(name: string, component: Component<GetSession<this>>, options?: Component.Options): () => void
}

export class Context extends cordis.Context {
static readonly session = Symbol('session')
// remove generic type to loosen the constraint
static readonly Session = Session as new (bot: Bot, event: Partial<Event>) => Session

constructor(config?: any) {
super(config)
this.provide('http', undefined, true)
this.provide('satori', undefined, true)
this.plugin(HTTP, config.request)
this.plugin(file)
this.plugin(Satori)
}
}

export class Satori<C extends Context> extends cordis.Service<unknown, C> {
static [cordis.Service.provide] = 'satori'
static [cordis.Service.immediate] = true

constructor(ctx?: C) {
super(ctx)
ctx.mixin('satori', ['bots', 'component'])
}

public bots = new Proxy([], {
get(target, prop) {
if (prop in target || typeof prop === 'symbol') {
Expand All @@ -126,45 +146,16 @@ export class Context extends cordis.Context {
target.splice(bot, 1)
return true
},
}) as Bot<this>[] & Dict<Bot<this>>
}) as Bot<C>[] & Dict<Bot<C>>

constructor(config: Context.Config = {}) {
super(config)
this.provide('http', undefined, true)
this.plugin(HTTP, config.request)
this.plugin(file)
}

component(name: string, component: Component<this[typeof Context.session]>, options: Component.Options = {}) {
component(name: string, component: Component<C[typeof Context.session]>, options: Component.Options = {}) {
const render: Component = async (attrs, children, session) => {
if (options.session && session.type === 'send') {
throw new Error('interactive components is not available outside sessions')
}
const result = await component(attrs, children, session)
return session.transform(h.normalize(result))
}
return this.set('component:' + name, render)
}
}

export namespace Context {
export interface Config {
request?: HTTP.Config
}

export const Config: Config.Static = z.intersect([
z.object({}),
])

namespace Config {
export interface Static extends z<Config> {}
}

export type Associate<P extends string, C extends Context = Context> = cordis.Context.Associate<P, C>
}

export abstract class Service<T = any, C extends Context = Context> extends cordis.Service<T, C> {
[cordis.Service.setup]() {
this.ctx = new Context() as C
return this.ctx.set('component:' + name, render)
}
}
2 changes: 0 additions & 2 deletions packages/core/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ export interface Session {
quote: Message
}

export interface Session extends Context.Associate<'session'> {}

export class Session<C extends Context = Context> {
static counter = 0

Expand Down

0 comments on commit 8f16bf5

Please sign in to comment.