Skip to main content
Module

x/vue3_reactivity/src/effectScope.ts

vue3_reactivity is forck by @vue/reactivity for deno.
Latest
File
import { ReactiveEffect } from './effect.ts'import { warn } from './warning.ts'import { __DEV__ } from "../dev.ts";
let activeEffectScope: EffectScope | undefined
export class EffectScope { /** * @internal */ active = true /** * @internal */ effects: ReactiveEffect[] = [] /** * @internal */ cleanups: (() => void)[] = []
/** * only assigned by undetached scope * @internal */ parent: EffectScope | undefined /** * record undetached scopes * @internal */ scopes: EffectScope[] | undefined /** * track a child scope's index in its parent's scopes array for optimized * removal * @internal */ private index: number | undefined
constructor(detached = false) { if (!detached && activeEffectScope) { this.parent = activeEffectScope this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push( this ) - 1 } }
run<T>(fn: () => T): T | undefined { if (this.active) { const currentEffectScope = activeEffectScope try { activeEffectScope = this return fn() } finally { activeEffectScope = currentEffectScope } } else if (__DEV__) { warn(`cannot run an inactive effect scope.`) } }
/** * This should only be called on non-detached scopes * @internal */ on() { activeEffectScope = this }
/** * This should only be called on non-detached scopes * @internal */ off() { activeEffectScope = this.parent }
stop(fromParent?: boolean) { if (this.active) { let i, l for (i = 0, l = this.effects.length; i < l; i++) { this.effects[i].stop() } for (i = 0, l = this.cleanups.length; i < l; i++) { this.cleanups[i]() } if (this.scopes) { for (i = 0, l = this.scopes.length; i < l; i++) { this.scopes[i].stop(true) } } // nested scope, dereference from parent to avoid memory leaks if (this.parent && !fromParent) { // optimized O(1) removal const last = this.parent.scopes!.pop() if (last && last !== this) { this.parent.scopes![this.index!] = last last.index = this.index! } } this.active = false } }}
export function effectScope(detached?: boolean) { return new EffectScope(detached)}
export function recordEffectScope( effect: ReactiveEffect, scope: EffectScope | undefined = activeEffectScope) { if (scope && scope.active) { scope.effects.push(effect) }}
export function getCurrentScope() { return activeEffectScope}
export function onScopeDispose(fn: () => void) { if (activeEffectScope) { activeEffectScope.cleanups.push(fn) } else if (__DEV__) { warn( `onScopeDispose() is called when there is no active effect scope` + ` to be associated with.` ) }}