@angular/core
Version:
Angular - the core framework
188 lines (182 loc) • 5.93 kB
JavaScript
/**
* @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