Skip to content

Commit

Permalink
feat: simplify context typings
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Feb 5, 2024
1 parent 061043b commit e34e9cf
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 55 deletions.
10 changes: 8 additions & 2 deletions packages/cordis/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@
"import": "./lib/index.mjs",
"types": "./lib/index.d.ts"
},
"./cli": "./lib/cli.mjs",
"./worker": "./lib/worker/index.mjs",
"./cli": {
"default": "./lib/cli.mjs",
"types": "./lib/cli.d.ts"
},
"./worker": {
"default": "./lib/worker/index.mjs",
"types": "./lib/worker/index.d.ts"
},
"./worker/main": "./lib/worker/main.mjs",
"./src/*": "./src/*",
"./package.json": "./package.json"
Expand Down
17 changes: 15 additions & 2 deletions packages/cordis/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ export * from '@cordisjs/core'

export { Logger } from '@cordisjs/logger'

export type EffectScope<C extends Context = Context> = core.EffectScope<C>
export type ForkScope<C extends Context = Context> = core.ForkScope<C>
export type MainScope<C extends Context = Context> = core.MainScope<C>

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

export class Service<C extends Context = Context> extends core.Service<C> {
public logger: logger.Logger

Expand All @@ -15,9 +21,16 @@ export class Service<C extends Context = Context> extends core.Service<C> {
}
}

export namespace Context {
export type Associate<P extends string, C extends Context = Context> = core.Context.Associate<P, C>
}

export class Context extends core.Context {
constructor() {
super()
baseDir: string

constructor(config?: any) {
super(config)
this.baseDir = globalThis.process?.cwd() || ''

this.provide('logger', undefined, true)
this.provide('timer', undefined, true)
Expand Down
13 changes: 5 additions & 8 deletions packages/core/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { Registry } from './registry.ts'
import { getConstructor, isConstructor, isUnproxyable, resolveConfig } from './utils.ts'

export namespace Context {
export type Parameterized<C, T = any> = Omit<C, 'config'> & { config: T }

export interface Config extends Lifecycle.Config, Registry.Config {}
export type Parameterized<C, T = any> = C & { config: T }

/** @deprecated use `string[]` instead */
export interface MixinOptions {
Expand Down Expand Up @@ -42,15 +40,14 @@ export namespace Context {
}
}

export interface Context<T = any> {
[Context.config]: Context.Config
export interface Context {
[Context.shadow]: Dict<symbol>
[Context.internal]: Dict<Context.Internal>
root: Context.Parameterized<this, this[typeof Context.config]>
root: this
realms: Record<string, Record<string, symbol>>
lifecycle: Lifecycle
registry: Registry<this>
config: T
config: any
}

export class Context {
Expand Down Expand Up @@ -195,7 +192,7 @@ export class Context {
})
}

constructor(config?: Context.Config) {
constructor(config?: any) {
const self: Context = new Proxy(this, Context.handler)
config = resolveConfig(getConstructor(this), config)
self[Context.shadow] = Object.create(null)
Expand Down
21 changes: 5 additions & 16 deletions packages/core/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ declare module './context.ts' {
}
}

export namespace Lifecycle {
export interface Config {
maxListeners?: number
}
}

export class Lifecycle {
isActive = false
_tasks = new Set<Promise<void>>()
Expand Down Expand Up @@ -125,11 +119,6 @@ export class Lifecycle {
}

register(label: string, hooks: [Context, any][], listener: any, prepend?: boolean) {
const maxListeners = this.root.config.maxListeners!
if (hooks.length >= maxListeners!) {
this.root.emit('internal/warning', new Error(`max listener count (${maxListeners!}) for ${label} exceeded, which may be caused by a memory leak`))
}

const caller = this[Context.current]
const method = prepend ? 'unshift' : 'push'
hooks[method]([caller, listener])
Expand Down Expand Up @@ -189,16 +178,16 @@ export interface Events<in C extends Context = Context> {
'fork': Plugin.Function<C, C['config']>
'ready'(): Awaitable<void>
'dispose'(): Awaitable<void>
'internal/fork'(fork: ForkScope<Context.Parameterized<C>>): void
'internal/runtime'(runtime: MainScope<Context.Parameterized<C>>): void
'internal/status'(scope: EffectScope<Context.Parameterized<C>>, oldValue: ScopeStatus): void
'internal/fork'(fork: ForkScope<C>): void
'internal/runtime'(runtime: MainScope<C>): void
'internal/status'(scope: EffectScope<C>, oldValue: ScopeStatus): void
'internal/info'(this: C, format: any, ...param: any[]): void
'internal/error'(this: C, format: any, ...param: any[]): void
'internal/warning'(this: C, format: any, ...param: any[]): void
'internal/before-service'(name: string, value: any): void
'internal/service'(name: string, oldValue: any): void
'internal/before-update'(fork: ForkScope<Context.Parameterized<C>>, config: any): void
'internal/update'(fork: ForkScope<Context.Parameterized<C>>, oldConfig: any): void
'internal/before-update'(fork: ForkScope<C>, config: any): void
'internal/update'(fork: ForkScope<C>, oldConfig: any): void
'internal/listener'(this: C, name: string, listener: any, prepend: boolean): void
'internal/event'(type: 'emit' | 'parallel' | 'serial' | 'bail', name: string, args: any[], thisArg: any): void
}
6 changes: 1 addition & 5 deletions packages/core/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,11 @@ declare module './context.ts' {
}
}

export namespace Registry {
export interface Config {}
}

export class Registry<C extends Context = Context> {
private _counter = 0
private _internal = new Map<Plugin<C>, MainScope<C>>()

constructor(private root: Context, config: Registry.Config) {
constructor(private root: Context, config: any) {
defineProperty(this, Context.current, root)
root.scope = new MainScope(this, null!, config)
root.scope.runtime.isReactive = true
Expand Down
4 changes: 1 addition & 3 deletions packages/core/src/service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Awaitable, defineProperty } from 'cosmokit'
import { Context } from './context.ts'

export interface Service extends Context.Associate<'service'> {}

export class Service<C extends Context = Context> {
protected start(): Awaitable<void> {}
protected stop(): Awaitable<void> {}
Expand All @@ -26,7 +24,7 @@ export class Service<C extends Context = Context> {
})

ctx.on('dispose', () => this.stop())
return Context.associate(Context.associate(this, 'service'), name)
return Context.associate(this, name)
}

[Context.filter](ctx: Context) {
Expand Down
12 changes: 1 addition & 11 deletions packages/core/tests/events.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,13 @@ export function createArray<T>(length: number, create: (index: number) => T) {
}

function setup() {
const root = new Context({ maxListeners: 64 })
expect(root.config).to.deep.equal({ maxListeners: 64 })
const root = new Context()
const warn = mock.fn()
root.on('internal/warning', warn)
return { root, warn }
}

describe('Event Listener', () => {
const extraCalls = 7

test('max appended hooks', async () => {
const { root, warn } = setup()
createArray(64 + extraCalls, () => root.on(event, noop))
expect(root.events._hooks[event].length).to.equal(64 + extraCalls)
expect(warn.mock.calls).to.have.length(extraCalls)
})

test('context.prototype.on', () => {
const { root } = setup()
const callback = mock.fn()
Expand Down
2 changes: 1 addition & 1 deletion packages/core/tests/update.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('Update', () => {
const root = new Context()
const listener = mock.fn((value?: number) => {})
const updater = mock.fn(() => {})
const plugin = mock.fn((ctx: Context<Config>) => {
const plugin = mock.fn((ctx: Context) => {
ctx.on(event, () => listener(ctx.config.foo))
// accept only foo
ctx.accept(['foo'], updater, { immediate: true })
Expand Down
7 changes: 0 additions & 7 deletions packages/logger/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export { Logger }

declare module '@cordisjs/core' {
interface Context {
baseDir: string
logger: LoggerService
}
}
Expand All @@ -15,12 +14,6 @@ interface LoggerService {
}

export function apply(ctx: Context) {
ctx.on('fork', () => {})

ctx.root.baseDir = globalThis.process?.cwd() || ''

ctx.provide('logger', undefined, true)

ctx.logger = function (name: string) {
return new Logger(name, { [Context.current]: this })
}
Expand Down

0 comments on commit e34e9cf

Please sign in to comment.