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.
This commit is contained in:
Aria Minaei 2022-11-26 19:22:23 +01:00
parent ae8be59366
commit 1c69cb7055

View file

@ -107,6 +107,7 @@ export class PrismDerivation<V> extends AbstractDerivation<V> {
class PrismScope { class PrismScope {
isPrismScope = true isPrismScope = true
private _subs: Record<string, PrismScope> = {} private _subs: Record<string, PrismScope> = {}
readonly effects: Map<string, IEffect> = new Map()
sub(key: string) { sub(key: string) {
if (!this._subs[key]) { if (!this._subs[key]) {
@ -118,23 +119,20 @@ class PrismScope {
get subs() { get subs() {
return this._subs return this._subs
} }
cleanupEffects() {
for (const effect of this.effects.values()) {
safelyRun(effect.cleanup, undefined)
}
this.effects.clear()
}
} }
function cleanupScopeStack(scope: PrismScope) { function cleanupScopeStack(scope: PrismScope) {
for (const sub of Object.values(scope.subs)) { for (const sub of Object.values(scope.subs)) {
cleanupScopeStack(sub) cleanupScopeStack(sub)
} }
cleanupEffects(scope) scope.cleanupEffects()
}
function cleanupEffects(scope: PrismScope) {
const effects = effectsWeakMap.get(scope)
if (effects) {
for (const effect of effects.values()) {
safelyRun(effect.cleanup, undefined)
}
}
effectsWeakMap.delete(scope)
} }
function safelyRun<T, U>( function safelyRun<T, U>(
@ -160,7 +158,6 @@ const refsWeakMap = new WeakMap<PrismScope, Map<string, IRef<unknown>>>()
type IRef<T> = { type IRef<T> = {
current: T current: T
} }
const effectsWeakMap = new WeakMap<PrismScope, Map<string, IEffect>>()
type IEffect = { type IEffect = {
deps: undefined | unknown[] deps: undefined | unknown[]
@ -209,20 +206,14 @@ function effect(key: string, cb: () => () => void, deps?: unknown[]): void {
if (!scope) { if (!scope) {
throw new Error(`prism.effect() is called outside of a prism() call.`) throw new Error(`prism.effect() is called outside of a prism() call.`)
} }
let effects = effectsWeakMap.get(scope)
if (effects === undefined) { let effect = scope.effects.get(key)
effects = new Map()
effectsWeakMap.set(scope, effects)
}
let effect = effects.get(key)
if (effect === undefined) { if (effect === undefined) {
effect = { effect = {
cleanup: voidFn, cleanup: voidFn,
deps: undefined, deps: undefined,
} }
effects.set(key, effect) scope.effects.set(key, effect)
} }
if (depsHaveChanged(effect.deps, deps)) { if (depsHaveChanged(effect.deps, deps)) {