Skip to content

Commit

Permalink
refa: remove fork impl
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Oct 23, 2024
1 parent 511a74e commit 954fdca
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 288 deletions.
16 changes: 8 additions & 8 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ ctx.plugin(Bar)

#### Unload a plugin [](#contents)

`ctx.plugin()` returns a `ForkScope` instance. To unload a plugin, we can use the `dispose()` method of it:
`ctx.plugin()` returns a `EffectScope` instance. To unload a plugin, we can use the `dispose()` method of it:

```ts
// load a plugin
Expand All @@ -218,7 +218,7 @@ const fork = ctx.plugin((ctx) => {
fork.dispose()
```

Some plugins can be loaded multiple times. To unload every fork of a plugin without access to the `ForkScope` instance, we can use `ctx.registry`:
Some plugins can be loaded multiple times. To unload every fork of a plugin without access to the `EffectScope` instance, we can use `ctx.registry`:

```ts
// remove all forks of the plugin
Expand Down Expand Up @@ -666,7 +666,7 @@ If any listener is fulfilled with a value other than `false`, `null` or `undefin

- plugin: `object` the plugin to apply
- config: `object` config for the plugin
- returns: `ForkScope`
- returns: `EffectScope`

Apply a plugin.

Expand Down Expand Up @@ -716,7 +716,7 @@ The plugin runtime associated with the effect scope. If the scope is a runtime,

#### scope.dispose()

### ForkScope
### EffectScope

### MainScope

Expand All @@ -730,7 +730,7 @@ It can be accessed via `ctx.scope.main` or passed-in in some events.

#### runtime.children

- type: [`ForkScope[]`](#forkscope)
- type: [`EffectScope[]`](#forkscope)

#### runtime.isForkable

Expand Down Expand Up @@ -777,11 +777,11 @@ See: [Reusable plugins](#reusable-plugins-)

- runtime: `MainScope`

#### internal/fork(fork)
#### internal/plugin(fork)

- fork: `ForkScope`
- fork: `EffectScope`

#### internal/update(fork, config)

- fork: `ForkScope`
- fork: `EffectScope`
- config: `any`
13 changes: 8 additions & 5 deletions packages/core/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Lifecycle from './events.ts'
import ReflectService from './reflect.ts'
import Registry from './registry.ts'
import { getTraceable, resolveConfig, symbols } from './utils.ts'
import { EffectScope } from './index.ts'

export { Lifecycle, ReflectService, Registry }

Expand Down Expand Up @@ -93,6 +94,7 @@ export class Context {
this[symbols.intercept] = Object.create(null)
const self: Context = new Proxy(this, ReflectService.handler)
self.root = self
this.scope = new EffectScope(this, config, () => {})
self.reflect = new ReflectService(self)
self.registry = new Registry(self, config)
self.lifecycle = new Lifecycle(self)
Expand All @@ -116,11 +118,12 @@ export class Context {
}

get name() {
let runtime = this.runtime
while (runtime && !runtime.name) {
runtime = runtime.parent.runtime
}
return runtime?.name!
let scope = this.scope
do {
if (scope.meta?.name) return scope.meta.name
scope = scope.parent.scope
} while (scope)
return 'root'
}

get events() {
Expand Down
32 changes: 13 additions & 19 deletions packages/core/src/events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Awaitable, defineProperty, Promisify, remove } from 'cosmokit'
import { Context } from './context.ts'
import { EffectScope, ForkScope, MainScope, ScopeStatus } from './scope.ts'
import { EffectScope, ScopeStatus } from './scope.ts'
import { getTraceable, symbols } from './index.ts'
import ReflectService from './reflect.ts'

Expand Down Expand Up @@ -54,6 +54,7 @@ class Lifecycle {
property: 'ctx',
})

// TODO: deprecate these events
ctx.scope.leak(this.on('internal/listener', function (this: Context, name, listener, options: EventOptions) {
const method = options.prepend ? 'unshift' : 'push'
if (name === 'ready') {
Expand All @@ -63,9 +64,6 @@ class Lifecycle {
this.scope.disposables[method](listener as any)
defineProperty(listener, 'name', 'event <dispose>')
return () => remove(this.scope.disposables, listener)
} else if (name === 'fork') {
this.scope.runtime.forkables[method](listener as any)
return this.scope.collect('event <fork>', () => remove(this.scope.runtime.forkables, listener))
}
}))

Expand All @@ -79,10 +77,9 @@ class Lifecycle {

// non-reusable plugin forks are not responsive to isolated service changes
ctx.scope.leak(this.on('internal/before-service', function (this: Context, name) {
for (const runtime of this.registry.values()) {
if (!runtime.inject[name]?.required) continue
const scopes = runtime.isReusable ? runtime.children : [runtime]
for (const scope of scopes) {
for (const meta of this.registry.values()) {
if (!meta.inject[name]?.required) continue
for (const scope of meta.scopes) {
if (!this[symbols.filter](scope.ctx)) continue
scope.updateStatus()
scope.reset()
Expand All @@ -91,10 +88,9 @@ class Lifecycle {
}, { global: true }))

ctx.scope.leak(this.on('internal/service', function (this: Context, name) {
for (const runtime of this.registry.values()) {
if (!runtime.inject[name]?.required) continue
const scopes = runtime.isReusable ? runtime.children : [runtime]
for (const scope of scopes) {
for (const meta of this.registry.values()) {
if (!meta.inject[name]?.required) continue
for (const scope of meta.scopes) {
if (!this[symbols.filter](scope.ctx)) continue
scope.start()
}
Expand All @@ -114,8 +110,8 @@ class Lifecycle {

// inject in ancestor contexts
const checkInject = (scope: EffectScope, name: string) => {
if (!scope.runtime.plugin) return false
for (const key in scope.runtime.inject) {
if (!scope.meta) return false
for (const key in scope.meta.inject) {
if (name === ReflectService.resolveInject(scope.ctx, key)[0]) return true
}
return checkInject(scope.parent.scope, name)
Expand Down Expand Up @@ -218,19 +214,17 @@ class Lifecycle {
export default Lifecycle

export interface Events<in C extends Context = Context> {
'fork'(ctx: C, config: C['config']): void
'ready'(): Awaitable<void>
'dispose'(): Awaitable<void>
'internal/fork'(fork: ForkScope<C>): void
'internal/runtime'(runtime: MainScope<C>): void
'internal/plugin'(fork: EffectScope<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'(this: C, name: string, value: any): void
'internal/service'(this: C, name: string, value: any): void
'internal/before-update'(fork: ForkScope<C>, config: any): void
'internal/update'(fork: ForkScope<C>, oldConfig: any): void
'internal/before-update'(fork: EffectScope<C>, config: any): void
'internal/update'(fork: EffectScope<C>, oldConfig: any): void
'internal/inject'(this: C, name: string): boolean | undefined
'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
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/reflect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ReflectService {
// Case 2: `$` or `_` prefix
if (name[0] === '$' || name[0] === '_') return
// Case 3: access directly from root
if (!ctx.runtime.plugin) return
if (!ctx.scope.meta) return
// Case 4: custom inject checks
if (ctx.bail(ctx, 'internal/inject', name)) return
const lines = error.stack!.split('\n')
Expand Down
Loading

0 comments on commit 954fdca

Please sign in to comment.