Skip to content

Commit

Permalink
fix(cordis): only validate plugin when applied
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 15, 2024
1 parent 9ebab6f commit d84c56c
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 17 deletions.
27 changes: 14 additions & 13 deletions packages/core/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ declare module './context.ts' {

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

constructor(private root: Context, config: any) {
defineProperty(this, Context.origin, root)
Expand All @@ -79,33 +79,34 @@ export class Registry<C extends Context = Context> {
return this._internal.size
}

resolve(plugin: Plugin) {
resolve(plugin: Plugin, assert = false): Function | undefined {
// Allow `null` as a special case.
if (plugin === null) return plugin
if (typeof plugin === 'function') return plugin
if (isApplicable(plugin)) return plugin.apply
throw new Error('invalid plugin, expect function or object with an "apply" method, received ' + typeof plugin)
if (assert) throw new Error('invalid plugin, expect function or object with an "apply" method, received ' + typeof plugin)
}

get(plugin: Plugin) {
return this._internal.get(this.resolve(plugin))
const key = this.resolve(plugin)
return key && this._internal.get(key)
}

has(plugin: Plugin) {
return this._internal.has(this.resolve(plugin))
const key = this.resolve(plugin)
return !!key && this._internal.has(key)
}

set(plugin: Plugin, state: MainScope<C>) {
const oldValue = this._internal.get(this.resolve(plugin))
this._internal.set(this.resolve(plugin), state)
return oldValue
const key = this.resolve(plugin)
key && this._internal.set(key, state)
}

delete(plugin: Plugin) {
plugin = this.resolve(plugin)
const runtime = this.get(plugin)
const key = this.resolve(plugin)
const runtime = key && this._internal.get(key)
if (!runtime) return
this._internal.delete(plugin)
this._internal.delete(key)
runtime.dispose()
return runtime
}
Expand All @@ -122,7 +123,7 @@ export class Registry<C extends Context = Context> {
return this._internal.entries()
}

forEach(callback: (value: MainScope<C>, key: Plugin, map: Map<Plugin, MainScope<C>>) => void) {
forEach(callback: (value: MainScope<C>, key: Function, map: Map<Plugin, MainScope<C>>) => void) {
return this._internal.forEach(callback)
}

Expand All @@ -136,7 +137,7 @@ export class Registry<C extends Context = Context> {

plugin(plugin: Plugin<C>, config?: any) {
// check if it's a valid plugin
this.resolve(plugin)
this.resolve(plugin, true)

const context: Context = this[Context.origin]
context.scope.assertActive()
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,11 @@ export class MainScope<C extends Context = Context> extends EffectScope<C> {

constructor(registry: Registry<C>, public plugin: Plugin, config: any, error?: any) {
super(registry[Context.origin] as C, config)
registry.set(plugin, this)
if (!plugin) {
this.name = 'root'
this.isActive = true
} else {
registry.set(plugin, this)
this.setup()
this.init(error)
}
Expand Down
6 changes: 3 additions & 3 deletions packages/core/tests/dispose.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@ describe('Disposables', () => {

// 4 handlers by now
expect(callback.mock.calls).to.have.length(0)
expect(root.registry.size).to.equal(4)
expect(root.registry.size).to.equal(3)
root.emit(event)
expect(callback.mock.calls).to.have.length(4)

// only 1 handler left
callback.mock.resetCalls()
expect(fork.dispose()).to.be.true
expect(root.registry.size).to.equal(1)
expect(root.registry.size).to.equal(0)
root.emit(event)
expect(callback.mock.calls).to.have.length(1)

// subsequent calls should be noop
callback.mock.resetCalls()
expect(fork.dispose()).to.be.false
expect(root.registry.size).to.equal(1)
expect(root.registry.size).to.equal(0)
root.emit(event)
expect(callback.mock.calls).to.have.length(1)
})
Expand Down

0 comments on commit d84c56c

Please sign in to comment.