UNPKG

@angular/core

Version:

Angular - the core framework

1 lines 9.72 kB
{"version":3,"file":"_untracked-chunk.mjs","sources":["../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/core/primitives/signals/src/linked_signal.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/core/primitives/signals/src/untracked.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {COMPUTING, ERRORED, UNSET} from './computed';\nimport {defaultEquals, ValueEqualityFn} from './equality';\nimport {\n consumerAfterComputation,\n consumerBeforeComputation,\n producerAccessed,\n producerMarkClean,\n producerUpdateValueVersion,\n REACTIVE_NODE,\n ReactiveNode,\n runPostProducerCreatedFn,\n setActiveConsumer,\n SIGNAL,\n} from './graph';\nimport {signalSetFn, signalUpdateFn} from './signal';\n\n// Required as the signals library is in a separate package, so we need to explicitly ensure the\n// global `ngDevMode` type is defined.\ndeclare const ngDevMode: boolean | undefined;\n\nexport type ComputationFn<S, D> = (source: S, previous?: PreviousValue<S, D>) => D;\nexport type PreviousValue<S, D> = {source: S; value: D};\n\nexport interface LinkedSignalNode<S, D> extends ReactiveNode {\n /**\n * Value of the source signal that was used to derive the computed value.\n */\n sourceValue: S;\n\n /**\n * Current state value, or one of the sentinel values (`UNSET`, `COMPUTING`,\n * `ERROR`).\n */\n value: D;\n\n /**\n * If `value` is `ERRORED`, the error caught from the last computation attempt which will\n * be re-thrown.\n */\n error: unknown;\n\n /**\n * The source function represents reactive dependency based on which the linked state is reset.\n */\n source: () => S;\n\n /**\n * The computation function which will produce a new value based on the source and, optionally - previous values.\n */\n computation: ComputationFn<S, D>;\n\n equal: ValueEqualityFn<D>;\n}\n\nexport type LinkedSignalGetter<S, D> = (() => D) & {\n [SIGNAL]: LinkedSignalNode<S, D>;\n};\n\nexport function createLinkedSignal<S, D>(\n sourceFn: () => S,\n computationFn: ComputationFn<S, D>,\n equalityFn?: ValueEqualityFn<D>,\n): LinkedSignalGetter<S, D> {\n const node: LinkedSignalNode<S, D> = Object.create(LINKED_SIGNAL_NODE);\n\n node.source = sourceFn;\n node.computation = computationFn;\n if (equalityFn != undefined) {\n node.equal = equalityFn;\n }\n\n const linkedSignalGetter = () => {\n // Check if the value needs updating before returning it.\n producerUpdateValueVersion(node);\n\n // Record that someone looked at this signal.\n producerAccessed(node);\n\n if (node.value === ERRORED) {\n throw node.error;\n }\n\n return node.value;\n };\n\n const getter = linkedSignalGetter as LinkedSignalGetter<S, D>;\n getter[SIGNAL] = node;\n if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n getter.toString = () =>\n `[LinkedSignal${node.debugName ? ' (' + node.debugName + ')' : ''}: ${String(node.value)}]`;\n }\n\n runPostProducerCreatedFn(node);\n\n return getter;\n}\n\nexport function linkedSignalSetFn<S, D>(node: LinkedSignalNode<S, D>, newValue: D) {\n producerUpdateValueVersion(node);\n signalSetFn(node, newValue);\n producerMarkClean(node);\n}\n\nexport function linkedSignalUpdateFn<S, D>(\n node: LinkedSignalNode<S, D>,\n updater: (value: D) => D,\n): void {\n producerUpdateValueVersion(node);\n // update() on a linked signal can't work if the current state is ERRORED, as there's no value.\n if (node.value === ERRORED) {\n throw node.error;\n }\n signalUpdateFn(node, updater);\n producerMarkClean(node);\n}\n\n// Note: Using an IIFE here to ensure that the spread assignment is not considered\n// a side-effect, ending up preserving `LINKED_SIGNAL_NODE` and `REACTIVE_NODE`.\nexport const LINKED_SIGNAL_NODE: Omit<\n LinkedSignalNode<unknown, unknown>,\n 'computation' | 'source' | 'sourceValue'\n> = /* @__PURE__ */ (() => {\n return {\n ...REACTIVE_NODE,\n value: UNSET,\n dirty: true,\n error: null,\n equal: defaultEquals,\n kind: 'linkedSignal',\n\n producerMustRecompute(node: LinkedSignalNode<unknown, unknown>): boolean {\n // Force a recomputation if there's no current value, or if the current value is in the\n // process of being calculated (which should throw an error).\n return node.value === UNSET || node.value === COMPUTING;\n },\n\n producerRecomputeValue(node: LinkedSignalNode<unknown, unknown>): void {\n if (node.value === COMPUTING) {\n // Our computation somehow led to a cyclic read of itself.\n throw new Error(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'Detected cycle in computations.' : '',\n );\n }\n\n const oldValue = node.value;\n node.value = COMPUTING;\n\n const prevConsumer = consumerBeforeComputation(node);\n let newValue: unknown;\n let wasEqual = false;\n try {\n const newSourceValue = node.source();\n const oldValueValid = oldValue !== UNSET && oldValue !== ERRORED;\n const prev = oldValueValid\n ? {\n source: node.sourceValue,\n value: oldValue,\n }\n : undefined;\n newValue = node.computation(newSourceValue, prev);\n node.sourceValue = newSourceValue;\n // We want to mark this node as errored if calling `equal` throws; however, we don't want\n // to track any reactive reads inside `equal`.\n setActiveConsumer(null);\n wasEqual = oldValueValid && newValue !== ERRORED && node.equal(oldValue, newValue);\n } catch (err) {\n newValue = ERRORED;\n node.error = err;\n } finally {\n consumerAfterComputation(node, prevConsumer);\n }\n\n if (wasEqual) {\n // No change to `valueVersion` - old and new values are\n // semantically equivalent.\n node.value = oldValue;\n return;\n }\n\n node.value = newValue;\n node.version++;\n },\n };\n})();\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {setActiveConsumer} from './graph';\n\n/**\n * Execute an arbitrary function in a non-reactive (non-tracking) context. The executed function\n * can, optionally, return a value.\n */\nexport function untracked<T>(nonReactiveReadsFn: () => T): T {\n const prevConsumer = setActiveConsumer(null);\n // We are not trying to catch any particular errors here, just making sure that the consumers\n // stack is restored in case of errors.\n try {\n return nonReactiveReadsFn();\n } finally {\n setActiveConsumer(prevConsumer);\n }\n}\n"],"names":[],"mappings":"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"}