From 1c69cb7055c2ce1ee47e22d28efc75d0c2d0c7be Mon Sep 17 00:00:00 2001 From: Aria Minaei Date: Sat, 26 Nov 2022 19:22:23 +0100 Subject: [PATCH] Save prism effects in the prism scope, rather than a WeakMap ... for easier debugging, but there is a perf regression which I can't yet quantify as the benchmark suit doesn't support comparisons. --- .../dataverse/src/derivations/prism/prism.ts | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/packages/dataverse/src/derivations/prism/prism.ts b/packages/dataverse/src/derivations/prism/prism.ts index a2ff718..b6f2acf 100644 --- a/packages/dataverse/src/derivations/prism/prism.ts +++ b/packages/dataverse/src/derivations/prism/prism.ts @@ -107,6 +107,7 @@ export class PrismDerivation extends AbstractDerivation { class PrismScope { isPrismScope = true private _subs: Record = {} + readonly effects: Map = new Map() sub(key: string) { if (!this._subs[key]) { @@ -118,23 +119,20 @@ class PrismScope { get subs() { return this._subs } + + cleanupEffects() { + for (const effect of this.effects.values()) { + safelyRun(effect.cleanup, undefined) + } + this.effects.clear() + } } function cleanupScopeStack(scope: PrismScope) { for (const sub of Object.values(scope.subs)) { cleanupScopeStack(sub) } - cleanupEffects(scope) -} - -function cleanupEffects(scope: PrismScope) { - const effects = effectsWeakMap.get(scope) - if (effects) { - for (const effect of effects.values()) { - safelyRun(effect.cleanup, undefined) - } - } - effectsWeakMap.delete(scope) + scope.cleanupEffects() } function safelyRun( @@ -160,7 +158,6 @@ const refsWeakMap = new WeakMap>>() type IRef = { current: T } -const effectsWeakMap = new WeakMap>() type IEffect = { deps: undefined | unknown[] @@ -209,20 +206,14 @@ function effect(key: string, cb: () => () => void, deps?: unknown[]): void { if (!scope) { throw new Error(`prism.effect() is called outside of a prism() call.`) } - let effects = effectsWeakMap.get(scope) - if (effects === undefined) { - effects = new Map() - effectsWeakMap.set(scope, effects) - } - - let effect = effects.get(key) + let effect = scope.effects.get(key) if (effect === undefined) { effect = { cleanup: voidFn, deps: undefined, } - effects.set(key, effect) + scope.effects.set(key, effect) } if (depsHaveChanged(effect.deps, deps)) {