UNPKG

@angular/core

Version:

Angular - the core framework

188 lines (182 loc) 5.93 kB
/** * @license Angular v21.0.5 * (c) 2010-2025 Google LLC. https://angular.dev/ * License: MIT */ import { SIGNAL, consumerMarkDirty, REACTIVE_NODE, consumerDestroy, isInNotificationPhase, consumerPollProducersForChange, consumerBeforeComputation, consumerAfterComputation } from './_effect-chunk.mjs'; export { BASE_EFFECT_NODE, SIGNAL_NODE, createComputed, createSignal, defaultEquals, finalizeConsumerAfterComputation, getActiveConsumer, isReactive, producerAccessed, producerIncrementEpoch, producerMarkClean, producerNotifyConsumers, producerUpdateValueVersion, producerUpdatesAllowed, resetConsumerBeforeComputation, runEffect, runPostProducerCreatedFn, runPostSignalSetFn, setActiveConsumer, setPostProducerCreatedFn, setPostSignalSetFn, setThrowInvalidWriteToSignalError, signalGetFn, signalSetFn, signalUpdateFn, untracked } from './_effect-chunk.mjs'; export { createLinkedSignal, linkedSignalSetFn, linkedSignalUpdateFn } from './_linked_signal-chunk.mjs'; export { setAlternateWeakRefImpl } from './_weak_ref-chunk.mjs'; const formatter = { header: (sig, config) => { if (!isSignal(sig) || config?.ngSkipFormatting) return null; let value; try { value = sig(); } catch (e) { return ['span', `Signal(⚠️ Error)${e.message ? `: ${e.message}` : ''}`]; } const kind = 'computation' in sig[SIGNAL] ? 'Computed' : 'Signal'; const isPrimitive = value === null || !Array.isArray(value) && typeof value !== 'object'; return ['span', {}, ['span', {}, `${kind}(`], (() => { if (isSignal(value)) { return formatter.header(value, config); } else if (isPrimitive && value !== undefined && typeof value !== 'function') { return ['object', { object: value }]; } else { return prettifyPreview(value); } })(), ['span', {}, `)`]]; }, hasBody: (sig, config) => { if (!isSignal(sig)) return false; try { sig(); } catch { return false; } return !config?.ngSkipFormatting; }, body: (sig, config) => { const color = 'var(--sys-color-primary)'; return ['div', { style: `background: #FFFFFF10; padding-left: 4px; padding-top: 2px; padding-bottom: 2px;` }, ['div', { style: `color: ${color}` }, 'Signal value: '], ['div', { style: `padding-left: .5rem;` }, ['object', { object: sig(), config }]], ['div', { style: `color: ${color}` }, 'Signal function: '], ['div', { style: `padding-left: .5rem;` }, ['object', { object: sig, config: { ...config, ngSkipFormatting: true } }]]]; } }; function prettifyPreview(value) { if (value === null) return 'null'; if (Array.isArray(value)) return `Array(${value.length})`; if (value instanceof Element) return `<${value.tagName.toLowerCase()}>`; if (value instanceof URL) return `URL`; switch (typeof value) { case 'undefined': { return 'undefined'; } case 'function': { if ('prototype' in value) { return 'class'; } else { return '() => {…}'; } } case 'object': { if (value.constructor.name === 'Object') { return '{…}'; } else { return `${value.constructor.name} {}`; } } default: { return ['object', { object: value, config: { ngSkipFormatting: true } }]; } } } function isSignal(value) { return value[SIGNAL] !== undefined; } function installDevToolsSignalFormatter() { globalThis.devtoolsFormatters ??= []; if (!globalThis.devtoolsFormatters.some(f => f === formatter)) { globalThis.devtoolsFormatters.push(formatter); } } function createWatch(fn, schedule, allowSignalWrites) { const node = Object.create(WATCH_NODE); if (allowSignalWrites) { node.consumerAllowSignalWrites = true; } node.fn = fn; node.schedule = schedule; const registerOnCleanup = cleanupFn => { node.cleanupFn = cleanupFn; }; function isWatchNodeDestroyed(node) { return node.fn === null && node.schedule === null; } function destroyWatchNode(node) { if (!isWatchNodeDestroyed(node)) { consumerDestroy(node); node.cleanupFn(); node.fn = null; node.schedule = null; node.cleanupFn = NOOP_CLEANUP_FN; } } const run = () => { if (node.fn === null) { return; } if (isInNotificationPhase()) { throw new Error(typeof ngDevMode !== 'undefined' && ngDevMode ? 'Schedulers cannot synchronously execute watches while scheduling.' : ''); } node.dirty = false; if (node.version > 0 && !consumerPollProducersForChange(node)) { return; } node.version++; const prevConsumer = consumerBeforeComputation(node); try { node.cleanupFn(); node.cleanupFn = NOOP_CLEANUP_FN; node.fn(registerOnCleanup); } finally { consumerAfterComputation(node, prevConsumer); } }; node.ref = { notify: () => consumerMarkDirty(node), run, cleanup: () => node.cleanupFn(), destroy: () => destroyWatchNode(node), [SIGNAL]: node }; return node.ref; } const NOOP_CLEANUP_FN = () => {}; const WATCH_NODE = /* @__PURE__ */(() => { return { ...REACTIVE_NODE, consumerIsAlwaysLive: true, consumerAllowSignalWrites: false, consumerMarkedDirty: node => { if (node.schedule !== null) { node.schedule(node.ref); } }, cleanupFn: NOOP_CLEANUP_FN }; })(); if (typeof ngDevMode === 'undefined' || ngDevMode) { installDevToolsSignalFormatter(); } export { REACTIVE_NODE, SIGNAL, consumerAfterComputation, consumerBeforeComputation, consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, createWatch, installDevToolsSignalFormatter, isInNotificationPhase }; //# sourceMappingURL=primitives-signals.mjs.map