UNPKG

30.4 kBSource Map (JSON)View Raw
1{"version":3,"file":"signals-core.min.js","sources":["../src/index.ts"],"sourcesContent":["// An named symbol/brand for detecting Signal instances even when they weren't\n// created using the same signals library version.\nconst BRAND_SYMBOL = Symbol.for(\"preact-signals\");\n\n// Flags for Computed and Effect.\nconst RUNNING = 1 << 0;\nconst NOTIFIED = 1 << 1;\nconst OUTDATED = 1 << 2;\nconst DISPOSED = 1 << 3;\nconst HAS_ERROR = 1 << 4;\nconst TRACKING = 1 << 5;\n\n// A linked list node used to track dependencies (sources) and dependents (targets).\n// Also used to remember the source's last version number that the target saw.\ntype Node = {\n\t// A source whose value the target depends on.\n\t_source: Signal;\n\t_prevSource?: Node;\n\t_nextSource?: Node;\n\n\t// A target that depends on the source and should be notified when the source changes.\n\t_target: Computed | Effect;\n\t_prevTarget?: Node;\n\t_nextTarget?: Node;\n\n\t// The version number of the source that target has last seen. We use version numbers\n\t// instead of storing the source value, because source values can take arbitrary amount\n\t// of memory, and computeds could hang on to them forever because they're lazily evaluated.\n\t// Use the special value -1 to mark potentially unused but recyclable nodes.\n\t_version: number;\n\n\t// Used to remember & roll back the source's previous `._node` value when entering &\n\t// exiting a new evaluation context.\n\t_rollbackNode?: Node;\n};\n\nfunction startBatch() {\n\tbatchDepth++;\n}\n\nfunction endBatch() {\n\tif (batchDepth > 1) {\n\t\tbatchDepth--;\n\t\treturn;\n\t}\n\n\tlet error: unknown;\n\tlet hasError = false;\n\n\twhile (batchedEffect !== undefined) {\n\t\tlet effect: Effect | undefined = batchedEffect;\n\t\tbatchedEffect = undefined;\n\n\t\tbatchIteration++;\n\n\t\twhile (effect !== undefined) {\n\t\t\tconst next: Effect | undefined = effect._nextBatchedEffect;\n\t\t\teffect._nextBatchedEffect = undefined;\n\t\t\teffect._flags &= ~NOTIFIED;\n\n\t\t\tif (!(effect._flags & DISPOSED) && needsToRecompute(effect)) {\n\t\t\t\ttry {\n\t\t\t\t\teffect._callback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!hasError) {\n\t\t\t\t\t\terror = err;\n\t\t\t\t\t\thasError = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\teffect = next;\n\t\t}\n\t}\n\tbatchIteration = 0;\n\tbatchDepth--;\n\n\tif (hasError) {\n\t\tthrow error;\n\t}\n}\n\n/**\n * Combine multiple value updates into one \"commit\" at the end of the provided callback.\n *\n * Batches can be nested and changes are only flushed once the outermost batch callback\n * completes.\n *\n * Accessing a signal that has been modified within a batch will reflect its updated\n * value.\n *\n * @param fn The callback function.\n * @returns The value returned by the callback.\n */\nfunction batch<T>(fn: () => T): T {\n\tif (batchDepth > 0) {\n\t\treturn fn();\n\t}\n\t/*@__INLINE__**/ startBatch();\n\ttry {\n\t\treturn fn();\n\t} finally {\n\t\tendBatch();\n\t}\n}\n\n// Currently evaluated computed or effect.\nlet evalContext: Computed | Effect | undefined = undefined;\n\n/**\n * Run a callback function that can access signal values without\n * subscribing to the signal updates.\n *\n * @param fn The callback function.\n * @returns The value returned by the callback.\n */\nfunction untracked<T>(fn: () => T): T {\n\tconst prevContext = evalContext;\n\tevalContext = undefined;\n\ttry {\n\t\treturn fn();\n\t} finally {\n\t\tevalContext = prevContext;\n\t}\n}\n\n// Effects collected into a batch.\nlet batchedEffect: Effect | undefined = undefined;\nlet batchDepth = 0;\nlet batchIteration = 0;\n\n// A global version number for signals, used for fast-pathing repeated\n// computed.peek()/computed.value calls when nothing has changed globally.\nlet globalVersion = 0;\n\nfunction addDependency(signal: Signal): Node | undefined {\n\tif (evalContext === undefined) {\n\t\treturn undefined;\n\t}\n\n\tlet node = signal._node;\n\tif (node === undefined || node._target !== evalContext) {\n\t\t/**\n\t\t * `signal` is a new dependency. Create a new dependency node, and set it\n\t\t * as the tail of the current context's dependency list. e.g:\n\t\t *\n\t\t * { A <-> B }\n\t\t * ↑ ↑\n\t\t * tail node (new)\n\t\t * ↓\n\t\t * { A <-> B <-> C }\n\t\t * ↑\n\t\t * tail (evalContext._sources)\n\t\t */\n\t\tnode = {\n\t\t\t_version: 0,\n\t\t\t_source: signal,\n\t\t\t_prevSource: evalContext._sources,\n\t\t\t_nextSource: undefined,\n\t\t\t_target: evalContext,\n\t\t\t_prevTarget: undefined,\n\t\t\t_nextTarget: undefined,\n\t\t\t_rollbackNode: node,\n\t\t};\n\n\t\tif (evalContext._sources !== undefined) {\n\t\t\tevalContext._sources._nextSource = node;\n\t\t}\n\t\tevalContext._sources = node;\n\t\tsignal._node = node;\n\n\t\t// Subscribe to change notifications from this dependency if we're in an effect\n\t\t// OR evaluating a computed signal that in turn has subscribers.\n\t\tif (evalContext._flags & TRACKING) {\n\t\t\tsignal._subscribe(node);\n\t\t}\n\t\treturn node;\n\t} else if (node._version === -1) {\n\t\t// `signal` is an existing dependency from a previous evaluation. Reuse it.\n\t\tnode._version = 0;\n\n\t\t/**\n\t\t * If `node` is not already the current tail of the dependency list (i.e.\n\t\t * there is a next node in the list), then make the `node` the new tail. e.g:\n\t\t *\n\t\t * { A <-> B <-> C <-> D }\n\t\t * ↑ ↑\n\t\t * node ┌─── tail (evalContext._sources)\n\t\t * └─────│─────┐\n\t\t * ↓ ↓\n\t\t * { A <-> C <-> D <-> B }\n\t\t * ↑\n\t\t * tail (evalContext._sources)\n\t\t */\n\t\tif (node._nextSource !== undefined) {\n\t\t\tnode._nextSource._prevSource = node._prevSource;\n\n\t\t\tif (node._prevSource !== undefined) {\n\t\t\t\tnode._prevSource._nextSource = node._nextSource;\n\t\t\t}\n\n\t\t\tnode._prevSource = evalContext._sources;\n\t\t\tnode._nextSource = undefined;\n\n\t\t\tevalContext._sources!._nextSource = node;\n\t\t\tevalContext._sources = node;\n\t\t}\n\n\t\t// We can assume that the currently evaluated effect / computed signal is already\n\t\t// subscribed to change notifications from `signal` if needed.\n\t\treturn node;\n\t}\n\treturn undefined;\n}\n\n/**\n * The base class for plain and computed signals.\n */\n// @ts-ignore: \"Cannot redeclare exported variable 'Signal'.\"\n//\n// A function with the same name is defined later, so we need to ignore TypeScript's\n// warning about a redeclared variable.\n//\n// The class is declared here, but later implemented with ES5-style prototypes.\n// This enables better control of the transpiled output size.\ndeclare class Signal<T = any> {\n\t/** @internal */\n\t_value: unknown;\n\n\t/**\n\t * @internal\n\t * Version numbers should always be >= 0, because the special value -1 is used\n\t * by Nodes to signify potentially unused but recyclable nodes.\n\t */\n\t_version: number;\n\n\t/** @internal */\n\t_node?: Node;\n\n\t/** @internal */\n\t_targets?: Node;\n\n\tconstructor(value?: T);\n\n\t/** @internal */\n\t_refresh(): boolean;\n\n\t/** @internal */\n\t_subscribe(node: Node): void;\n\n\t/** @internal */\n\t_unsubscribe(node: Node): void;\n\n\tsubscribe(fn: (value: T) => void): () => void;\n\n\tvalueOf(): T;\n\n\ttoString(): string;\n\n\ttoJSON(): T;\n\n\tpeek(): T;\n\n\tbrand: typeof BRAND_SYMBOL;\n\n\tget value(): T;\n\tset value(value: T);\n}\n\n/** @internal */\n// @ts-ignore: \"Cannot redeclare exported variable 'Signal'.\"\n//\n// A class with the same name has already been declared, so we need to ignore\n// TypeScript's warning about a redeclared variable.\n//\n// The previously declared class is implemented here with ES5-style prototypes.\n// This enables better control of the transpiled output size.\nfunction Signal(this: Signal, value?: unknown) {\n\tthis._value = value;\n\tthis._version = 0;\n\tthis._node = undefined;\n\tthis._targets = undefined;\n}\n\nSignal.prototype.brand = BRAND_SYMBOL;\n\nSignal.prototype._refresh = function () {\n\treturn true;\n};\n\nSignal.prototype._subscribe = function (node) {\n\tif (this._targets !== node && node._prevTarget === undefined) {\n\t\tnode._nextTarget = this._targets;\n\t\tif (this._targets !== undefined) {\n\t\t\tthis._targets._prevTarget = node;\n\t\t}\n\t\tthis._targets = node;\n\t}\n};\n\nSignal.prototype._unsubscribe = function (node) {\n\t// Only run the unsubscribe step if the signal has any subscribers to begin with.\n\tif (this._targets !== undefined) {\n\t\tconst prev = node._prevTarget;\n\t\tconst next = node._nextTarget;\n\t\tif (prev !== undefined) {\n\t\t\tprev._nextTarget = next;\n\t\t\tnode._prevTarget = undefined;\n\t\t}\n\t\tif (next !== undefined) {\n\t\t\tnext._prevTarget = prev;\n\t\t\tnode._nextTarget = undefined;\n\t\t}\n\t\tif (node === this._targets) {\n\t\t\tthis._targets = next;\n\t\t}\n\t}\n};\n\nSignal.prototype.subscribe = function (fn) {\n\treturn effect(() => {\n\t\tconst value = this.value;\n\n\t\tconst prevContext = evalContext;\n\t\tevalContext = undefined;\n\t\ttry {\n\t\t\tfn(value);\n\t\t} finally {\n\t\t\tevalContext = prevContext;\n\t\t}\n\t});\n};\n\nSignal.prototype.valueOf = function () {\n\treturn this.value;\n};\n\nSignal.prototype.toString = function () {\n\treturn this.value + \"\";\n};\n\nSignal.prototype.toJSON = function () {\n\treturn this.value;\n};\n\nSignal.prototype.peek = function () {\n\tconst prevContext = evalContext;\n\tevalContext = undefined;\n\ttry {\n\t\treturn this.value;\n\t} finally {\n\t\tevalContext = prevContext;\n\t}\n};\n\nObject.defineProperty(Signal.prototype, \"value\", {\n\tget(this: Signal) {\n\t\tconst node = addDependency(this);\n\t\tif (node !== undefined) {\n\t\t\tnode._version = this._version;\n\t\t}\n\t\treturn this._value;\n\t},\n\tset(this: Signal, value) {\n\t\tif (value !== this._value) {\n\t\t\tif (batchIteration > 100) {\n\t\t\t\tthrow new Error(\"Cycle detected\");\n\t\t\t}\n\n\t\t\tthis._value = value;\n\t\t\tthis._version++;\n\t\t\tglobalVersion++;\n\n\t\t\t/**@__INLINE__*/ startBatch();\n\t\t\ttry {\n\t\t\t\tfor (\n\t\t\t\t\tlet node = this._targets;\n\t\t\t\t\tnode !== undefined;\n\t\t\t\t\tnode = node._nextTarget\n\t\t\t\t) {\n\t\t\t\t\tnode._target._notify();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tendBatch();\n\t\t\t}\n\t\t}\n\t},\n});\n\n/**\n * Create a new plain signal.\n *\n * @param value The initial value for the signal.\n * @returns A new signal.\n */\nfunction signal<T>(value: T): Signal<T> {\n\treturn new Signal(value);\n}\n\nfunction needsToRecompute(target: Computed | Effect): boolean {\n\t// Check the dependencies for changed values. The dependency list is already\n\t// in order of use. Therefore if multiple dependencies have changed values, only\n\t// the first used dependency is re-evaluated at this point.\n\tfor (\n\t\tlet node = target._sources;\n\t\tnode !== undefined;\n\t\tnode = node._nextSource\n\t) {\n\t\t// If there's a new version of the dependency before or after refreshing,\n\t\t// or the dependency has something blocking it from refreshing at all (e.g. a\n\t\t// dependency cycle), then we need to recompute.\n\t\tif (\n\t\t\tnode._source._version !== node._version ||\n\t\t\t!node._source._refresh() ||\n\t\t\tnode._source._version !== node._version\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\t// If none of the dependencies have changed values since last recompute then\n\t// there's no need to recompute.\n\treturn false;\n}\n\nfunction prepareSources(target: Computed | Effect) {\n\t/**\n\t * 1. Mark all current sources as re-usable nodes (version: -1)\n\t * 2. Set a rollback node if the current node is being used in a different context\n\t * 3. Point 'target._sources' to the tail of the doubly-linked list, e.g:\n\t *\n\t * { undefined <- A <-> B <-> C -> undefined }\n\t * ↑ ↑\n\t * │ └──────┐\n\t * target._sources = A; (node is head) │\n\t * ↓ │\n\t * target._sources = C; (node is tail) ─┘\n\t */\n\tfor (\n\t\tlet node = target._sources;\n\t\tnode !== undefined;\n\t\tnode = node._nextSource\n\t) {\n\t\tconst rollbackNode = node._source._node;\n\t\tif (rollbackNode !== undefined) {\n\t\t\tnode._rollbackNode = rollbackNode;\n\t\t}\n\t\tnode._source._node = node;\n\t\tnode._version = -1;\n\n\t\tif (node._nextSource === undefined) {\n\t\t\ttarget._sources = node;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction cleanupSources(target: Computed | Effect) {\n\tlet node = target._sources;\n\tlet head = undefined;\n\n\t/**\n\t * At this point 'target._sources' points to the tail of the doubly-linked list.\n\t * It contains all existing sources + new sources in order of use.\n\t * Iterate backwards until we find the head node while dropping old dependencies.\n\t */\n\twhile (node !== undefined) {\n\t\tconst prev = node._prevSource;\n\n\t\t/**\n\t\t * The node was not re-used, unsubscribe from its change notifications and remove itself\n\t\t * from the doubly-linked list. e.g:\n\t\t *\n\t\t * { A <-> B <-> C }\n\t\t * ↓\n\t\t * { A <-> C }\n\t\t */\n\t\tif (node._version === -1) {\n\t\t\tnode._source._unsubscribe(node);\n\n\t\t\tif (prev !== undefined) {\n\t\t\t\tprev._nextSource = node._nextSource;\n\t\t\t}\n\t\t\tif (node._nextSource !== undefined) {\n\t\t\t\tnode._nextSource._prevSource = prev;\n\t\t\t}\n\t\t} else {\n\t\t\t/**\n\t\t\t * The new head is the last node seen which wasn't removed/unsubscribed\n\t\t\t * from the doubly-linked list. e.g:\n\t\t\t *\n\t\t\t * { A <-> B <-> C }\n\t\t\t * ↑ ↑ ↑\n\t\t\t * │ │ └ head = node\n\t\t\t * │ └ head = node\n\t\t\t * └ head = node\n\t\t\t */\n\t\t\thead = node;\n\t\t}\n\n\t\tnode._source._node = node._rollbackNode;\n\t\tif (node._rollbackNode !== undefined) {\n\t\t\tnode._rollbackNode = undefined;\n\t\t}\n\n\t\tnode = prev;\n\t}\n\n\ttarget._sources = head;\n}\n\ndeclare class Computed<T = any> extends Signal<T> {\n\t_fn: () => T;\n\t_sources?: Node;\n\t_globalVersion: number;\n\t_flags: number;\n\n\tconstructor(fn: () => T);\n\n\t_notify(): void;\n\tget value(): T;\n}\n\nfunction Computed(this: Computed, fn: () => unknown) {\n\tSignal.call(this, undefined);\n\n\tthis._fn = fn;\n\tthis._sources = undefined;\n\tthis._globalVersion = globalVersion - 1;\n\tthis._flags = OUTDATED;\n}\n\nComputed.prototype = new Signal() as Computed;\n\nComputed.prototype._refresh = function () {\n\tthis._flags &= ~NOTIFIED;\n\n\tif (this._flags & RUNNING) {\n\t\treturn false;\n\t}\n\n\t// If this computed signal has subscribed to updates from its dependencies\n\t// (TRACKING flag set) and none of them have notified about changes (OUTDATED\n\t// flag not set), then the computed value can't have changed.\n\tif ((this._flags & (OUTDATED | TRACKING)) === TRACKING) {\n\t\treturn true;\n\t}\n\tthis._flags &= ~OUTDATED;\n\n\tif (this._globalVersion === globalVersion) {\n\t\treturn true;\n\t}\n\tthis._globalVersion = globalVersion;\n\n\t// Mark this computed signal running before checking the dependencies for value\n\t// changes, so that the RUNNING flag can be used to notice cyclical dependencies.\n\tthis._flags |= RUNNING;\n\tif (this._version > 0 && !needsToRecompute(this)) {\n\t\tthis._flags &= ~RUNNING;\n\t\treturn true;\n\t}\n\n\tconst prevContext = evalContext;\n\ttry {\n\t\tprepareSources(this);\n\t\tevalContext = this;\n\t\tconst value = this._fn();\n\t\tif (\n\t\t\tthis._flags & HAS_ERROR ||\n\t\t\tthis._value !== value ||\n\t\t\tthis._version === 0\n\t\t) {\n\t\t\tthis._value = value;\n\t\t\tthis._flags &= ~HAS_ERROR;\n\t\t\tthis._version++;\n\t\t}\n\t} catch (err) {\n\t\tthis._value = err;\n\t\tthis._flags |= HAS_ERROR;\n\t\tthis._version++;\n\t}\n\tevalContext = prevContext;\n\tcleanupSources(this);\n\tthis._flags &= ~RUNNING;\n\treturn true;\n};\n\nComputed.prototype._subscribe = function (node) {\n\tif (this._targets === undefined) {\n\t\tthis._flags |= OUTDATED | TRACKING;\n\n\t\t// A computed signal subscribes lazily to its dependencies when it\n\t\t// gets its first subscriber.\n\t\tfor (\n\t\t\tlet node = this._sources;\n\t\t\tnode !== undefined;\n\t\t\tnode = node._nextSource\n\t\t) {\n\t\t\tnode._source._subscribe(node);\n\t\t}\n\t}\n\tSignal.prototype._subscribe.call(this, node);\n};\n\nComputed.prototype._unsubscribe = function (node) {\n\t// Only run the unsubscribe step if the computed signal has any subscribers.\n\tif (this._targets !== undefined) {\n\t\tSignal.prototype._unsubscribe.call(this, node);\n\n\t\t// Computed signal unsubscribes from its dependencies when it loses its last subscriber.\n\t\t// This makes it possible for unreferences subgraphs of computed signals to get garbage collected.\n\t\tif (this._targets === undefined) {\n\t\t\tthis._flags &= ~TRACKING;\n\n\t\t\tfor (\n\t\t\t\tlet node = this._sources;\n\t\t\t\tnode !== undefined;\n\t\t\t\tnode = node._nextSource\n\t\t\t) {\n\t\t\t\tnode._source._unsubscribe(node);\n\t\t\t}\n\t\t}\n\t}\n};\n\nComputed.prototype._notify = function () {\n\tif (!(this._flags & NOTIFIED)) {\n\t\tthis._flags |= OUTDATED | NOTIFIED;\n\n\t\tfor (\n\t\t\tlet node = this._targets;\n\t\t\tnode !== undefined;\n\t\t\tnode = node._nextTarget\n\t\t) {\n\t\t\tnode._target._notify();\n\t\t}\n\t}\n};\n\nObject.defineProperty(Computed.prototype, \"value\", {\n\tget(this: Computed) {\n\t\tif (this._flags & RUNNING) {\n\t\t\tthrow new Error(\"Cycle detected\");\n\t\t}\n\t\tconst node = addDependency(this);\n\t\tthis._refresh();\n\t\tif (node !== undefined) {\n\t\t\tnode._version = this._version;\n\t\t}\n\t\tif (this._flags & HAS_ERROR) {\n\t\t\tthrow this._value;\n\t\t}\n\t\treturn this._value;\n\t},\n});\n\n/**\n * An interface for read-only signals.\n */\ninterface ReadonlySignal<T = any> extends Signal<T> {\n\treadonly value: T;\n}\n\n/**\n * Create a new signal that is computed based on the values of other signals.\n *\n * The returned computed signal is read-only, and its value is automatically\n * updated when any signals accessed from within the callback function change.\n *\n * @param fn The effect callback.\n * @returns A new read-only signal.\n */\nfunction computed<T>(fn: () => T): ReadonlySignal<T> {\n\treturn new Computed(fn);\n}\n\nfunction cleanupEffect(effect: Effect) {\n\tconst cleanup = effect._cleanup;\n\teffect._cleanup = undefined;\n\n\tif (typeof cleanup === \"function\") {\n\t\t/*@__INLINE__**/ startBatch();\n\n\t\t// Run cleanup functions always outside of any context.\n\t\tconst prevContext = evalContext;\n\t\tevalContext = undefined;\n\t\ttry {\n\t\t\tcleanup();\n\t\t} catch (err) {\n\t\t\teffect._flags &= ~RUNNING;\n\t\t\teffect._flags |= DISPOSED;\n\t\t\tdisposeEffect(effect);\n\t\t\tthrow err;\n\t\t} finally {\n\t\t\tevalContext = prevContext;\n\t\t\tendBatch();\n\t\t}\n\t}\n}\n\nfunction disposeEffect(effect: Effect) {\n\tfor (\n\t\tlet node = effect._sources;\n\t\tnode !== undefined;\n\t\tnode = node._nextSource\n\t) {\n\t\tnode._source._unsubscribe(node);\n\t}\n\teffect._fn = undefined;\n\teffect._sources = undefined;\n\n\tcleanupEffect(effect);\n}\n\nfunction endEffect(this: Effect, prevContext?: Computed | Effect) {\n\tif (evalContext !== this) {\n\t\tthrow new Error(\"Out-of-order effect\");\n\t}\n\tcleanupSources(this);\n\tevalContext = prevContext;\n\n\tthis._flags &= ~RUNNING;\n\tif (this._flags & DISPOSED) {\n\t\tdisposeEffect(this);\n\t}\n\tendBatch();\n}\n\ndeclare class Effect {\n\t_fn?: () => unknown;\n\t_cleanup?: () => unknown;\n\t_sources?: Node;\n\t_nextBatchedEffect?: Effect;\n\t_flags: number;\n\n\tconstructor(fn: () => unknown);\n\n\t_callback(): void;\n\t_start(): () => void;\n\t_notify(): void;\n\t_dispose(): void;\n}\n\nfunction Effect(this: Effect, fn: () => unknown) {\n\tthis._fn = fn;\n\tthis._cleanup = undefined;\n\tthis._sources = undefined;\n\tthis._nextBatchedEffect = undefined;\n\tthis._flags = TRACKING;\n}\n\nEffect.prototype._callback = function () {\n\tconst finish = this._start();\n\ttry {\n\t\tif (this._flags & DISPOSED) return;\n\t\tif (this._fn === undefined) return;\n\n\t\tconst cleanup = this._fn();\n\t\tif (typeof cleanup === \"function\") {\n\t\t\tthis._cleanup = cleanup as () => unknown;\n\t\t}\n\t} finally {\n\t\tfinish();\n\t}\n};\n\nEffect.prototype._start = function () {\n\tif (this._flags & RUNNING) {\n\t\tthrow new Error(\"Cycle detected\");\n\t}\n\tthis._flags |= RUNNING;\n\tthis._flags &= ~DISPOSED;\n\tcleanupEffect(this);\n\tprepareSources(this);\n\n\t/*@__INLINE__**/ startBatch();\n\tconst prevContext = evalContext;\n\tevalContext = this;\n\treturn endEffect.bind(this, prevContext);\n};\n\nEffect.prototype._notify = function () {\n\tif (!(this._flags & NOTIFIED)) {\n\t\tthis._flags |= NOTIFIED;\n\t\tthis._nextBatchedEffect = batchedEffect;\n\t\tbatchedEffect = this;\n\t}\n};\n\nEffect.prototype._dispose = function () {\n\tthis._flags |= DISPOSED;\n\n\tif (!(this._flags & RUNNING)) {\n\t\tdisposeEffect(this);\n\t}\n};\n\n/**\n * Create an effect to run arbitrary code in response to signal changes.\n *\n * An effect tracks which signals are accessed within the given callback\n * function `fn`, and re-runs the callback when those signals change.\n *\n * The callback may return a cleanup function. The cleanup function gets\n * run once, either when the callback is next called or when the effect\n * gets disposed, whichever happens first.\n *\n * @param fn The effect callback.\n * @returns A function for disposing the effect.\n */\nfunction effect(fn: () => unknown): () => void {\n\tconst effect = new Effect(fn);\n\ttry {\n\t\teffect._callback();\n\t} catch (err) {\n\t\teffect._dispose();\n\t\tthrow err;\n\t}\n\t// Return a bound function instead of a wrapper like `() => effect._dispose()`,\n\t// because bound functions seem to be just as fast and take up a lot less memory.\n\treturn effect._dispose.bind(effect);\n}\n\nexport { signal, computed, effect, batch, untracked, Signal, ReadonlySignal };\n"],"names":["g","f","exports","module","define","amd","globalThis","self","preactSignalsCore","this","BRAND_SYMBOL","Symbol","endBatch","batchDepth","error","hasError","undefined","batchedEffect","effect","batchIteration","next","_nextBatchedEffect","_flags","needsToRecompute","_callback","err","evalContext","globalVersion","addDependency","signal","node","_node","_target","_version","_source","_prevSource","_sources","_nextSource","_prevTarget","_nextTarget","_rollbackNode","_subscribe","Signal","value","_value","_targets","prototype","brand","_refresh","_unsubscribe","prev","subscribe","fn","_this","prevContext","valueOf","toString","toJSON","peek","Object","defineProperty","get","set","Error","_notify","target","prepareSources","rollbackNode","cleanupSources","head","Computed","call","_fn","_globalVersion","OUTDATED","cleanupEffect","cleanup","_cleanup","disposeEffect","endEffect","Effect","finish","_start","bind","_dispose","batch","computed","untracked"],"mappings":"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"}
\No newline at end of file