@angular/core
Version:
Angular - the core framework
55 lines • 8.8 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { producerAccessed, SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
import { RuntimeError } from '../../errors';
import { signalAsReadonlyFn, } from '../../render3/reactivity/signal';
import { INPUT_SIGNAL_NODE, REQUIRED_UNSET_VALUE } from '../input/input_signal_node';
import { OutputEmitterRef } from '../output/output_emitter_ref';
/**
* Creates a model signal.
*
* @param initialValue The initial value.
* Can be set to {@link REQUIRED_UNSET_VALUE} for required model signals.
* @param options Additional options for the model.
*/
export function createModelSignal(initialValue) {
const node = Object.create(INPUT_SIGNAL_NODE);
const emitterRef = new OutputEmitterRef();
node.value = initialValue;
function getter() {
producerAccessed(node);
assertModelSet(node.value);
return node.value;
}
getter[SIGNAL] = node;
getter.asReadonly = signalAsReadonlyFn.bind(getter);
// TODO: Should we throw an error when updating a destroyed model?
getter.set = (newValue) => {
if (!node.equal(node.value, newValue)) {
signalSetFn(node, newValue);
emitterRef.emit(newValue);
}
};
getter.update = (updateFn) => {
assertModelSet(node.value);
getter.set(updateFn(node.value));
};
getter.subscribe = emitterRef.subscribe.bind(emitterRef);
getter.destroyRef = emitterRef.destroyRef;
if (ngDevMode) {
getter.toString = () => `[Model Signal: ${getter()}]`;
}
return getter;
}
/** Asserts that a model's value is set. */
function assertModelSet(value) {
if (value === REQUIRED_UNSET_VALUE) {
throw new RuntimeError(952 /* RuntimeErrorCode.REQUIRED_MODEL_NO_VALUE */, ngDevMode && 'Model is required but no value is available yet.');
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxfc2lnbmFsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvYXV0aG9yaW5nL21vZGVsL21vZGVsX3NpZ25hbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBQyxNQUFNLGtDQUFrQyxDQUFDO0FBRXZGLE9BQU8sRUFBQyxZQUFZLEVBQW1CLE1BQU0sY0FBYyxDQUFDO0FBRTVELE9BQU8sRUFDTCxrQkFBa0IsR0FHbkIsTUFBTSxpQ0FBaUMsQ0FBQztBQU16QyxPQUFPLEVBQUMsaUJBQWlCLEVBQW1CLG9CQUFvQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDcEcsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sOEJBQThCLENBQUM7QUE0QjlEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBSSxZQUFlO0lBQ2xELE1BQU0sSUFBSSxHQUEwQixNQUFNLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDckUsTUFBTSxVQUFVLEdBQUcsSUFBSSxnQkFBZ0IsRUFBSyxDQUFDO0lBRTdDLElBQUksQ0FBQyxLQUFLLEdBQUcsWUFBWSxDQUFDO0lBRTFCLFNBQVMsTUFBTTtRQUNiLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLE1BQU0sQ0FBQyxVQUFVLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE1BQWEsQ0FBb0IsQ0FBQztJQUU5RSxrRUFBa0U7SUFDbEUsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLFFBQVcsRUFBRSxFQUFFO1FBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUN0QyxXQUFXLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzVCLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxRQUF5QixFQUFFLEVBQUU7UUFDNUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNuQyxDQUFDLENBQUM7SUFFRixNQUFNLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pELE1BQU0sQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQztJQUUxQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsTUFBTSxDQUFDLFFBQVEsR0FBRyxHQUFHLEVBQUUsQ0FBQyxrQkFBa0IsTUFBTSxFQUFFLEdBQUcsQ0FBQztJQUN4RCxDQUFDO0lBRUQsT0FBTyxNQU1KLENBQUM7QUFDTixDQUFDO0FBRUQsMkNBQTJDO0FBQzNDLFNBQVMsY0FBYyxDQUFDLEtBQWM7SUFDcEMsSUFBSSxLQUFLLEtBQUssb0JBQW9CLEVBQUUsQ0FBQztRQUNuQyxNQUFNLElBQUksWUFBWSxxREFFcEIsU0FBUyxJQUFJLGtEQUFrRCxDQUNoRSxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtwcm9kdWNlckFjY2Vzc2VkLCBTSUdOQUwsIHNpZ25hbFNldEZufSBmcm9tICdAYW5ndWxhci9jb3JlL3ByaW1pdGl2ZXMvc2lnbmFscyc7XG5cbmltcG9ydCB7UnVudGltZUVycm9yLCBSdW50aW1lRXJyb3JDb2RlfSBmcm9tICcuLi8uLi9lcnJvcnMnO1xuaW1wb3J0IHtTaWduYWx9IGZyb20gJy4uLy4uL3JlbmRlcjMvcmVhY3Rpdml0eS9hcGknO1xuaW1wb3J0IHtcbiAgc2lnbmFsQXNSZWFkb25seUZuLFxuICBXcml0YWJsZVNpZ25hbCxcbiAgybVXUklUQUJMRV9TSUdOQUwsXG59IGZyb20gJy4uLy4uL3JlbmRlcjMvcmVhY3Rpdml0eS9zaWduYWwnO1xuaW1wb3J0IHtcbiAgSW5wdXRTaWduYWwsXG4gIMm1SU5QVVRfU0lHTkFMX0JSQU5EX1JFQURfVFlQRSxcbiAgybVJTlBVVF9TSUdOQUxfQlJBTkRfV1JJVEVfVFlQRSxcbn0gZnJvbSAnLi4vaW5wdXQvaW5wdXRfc2lnbmFsJztcbmltcG9ydCB7SU5QVVRfU0lHTkFMX05PREUsIElucHV0U2lnbmFsTm9kZSwgUkVRVUlSRURfVU5TRVRfVkFMVUV9IGZyb20gJy4uL2lucHV0L2lucHV0X3NpZ25hbF9ub2RlJztcbmltcG9ydCB7T3V0cHV0RW1pdHRlclJlZn0gZnJvbSAnLi4vb3V0cHV0L291dHB1dF9lbWl0dGVyX3JlZic7XG5pbXBvcnQge091dHB1dFJlZn0gZnJvbSAnLi4vb3V0cHV0L291dHB1dF9yZWYnO1xuXG4vKipcbiAqIEBkZXZlbG9wZXJQcmV2aWV3XG4gKlxuICogT3B0aW9ucyBmb3IgbW9kZWwgc2lnbmFscy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2RlbE9wdGlvbnMge1xuICAvKipcbiAgICogT3B0aW9uYWwgcHVibGljIG5hbWUgb2YgdGhlIGlucHV0IHNpZGUgb2YgdGhlIG1vZGVsLiBUaGUgb3V0cHV0IHNpZGUgd2lsbCBoYXZlIHRoZSBzYW1lXG4gICAqIG5hbWUgYXMgdGhlIGlucHV0LCBidXQgc3VmZml4ZWQgd2l0aCBgQ2hhbmdlYC4gQnkgZGVmYXVsdCwgdGhlIGNsYXNzIGZpZWxkIG5hbWUgaXMgdXNlZC5cbiAgICovXG4gIGFsaWFzPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIGBNb2RlbFNpZ25hbGAgcmVwcmVzZW50cyBhIHNwZWNpYWwgYFNpZ25hbGAgZm9yIGEgZGlyZWN0aXZlL2NvbXBvbmVudCBtb2RlbCBmaWVsZC5cbiAqXG4gKiBBIG1vZGVsIHNpZ25hbCBpcyBhIHdyaXRlYWJsZSBzaWduYWwgdGhhdCBjYW4gYmUgZXhwb3NlZCBhcyBhbiBvdXRwdXQuXG4gKiBXaGVuZXZlciBpdHMgdmFsdWUgaXMgdXBkYXRlZCwgaXQgZW1pdHMgdG8gdGhlIG91dHB1dC5cbiAqXG4gKiBAZGV2ZWxvcGVyUHJldmlld1xuICovXG5leHBvcnQgaW50ZXJmYWNlIE1vZGVsU2lnbmFsPFQ+IGV4dGVuZHMgV3JpdGFibGVTaWduYWw8VD4sIElucHV0U2lnbmFsPFQ+LCBPdXRwdXRSZWY8VD4ge1xuICBbU0lHTkFMXTogSW5wdXRTaWduYWxOb2RlPFQsIFQ+O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtb2RlbCBzaWduYWwuXG4gKlxuICogQHBhcmFtIGluaXRpYWxWYWx1ZSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAqICAgQ2FuIGJlIHNldCB0byB7QGxpbmsgUkVRVUlSRURfVU5TRVRfVkFMVUV9IGZvciByZXF1aXJlZCBtb2RlbCBzaWduYWxzLlxuICogQHBhcmFtIG9wdGlvbnMgQWRkaXRpb25hbCBvcHRpb25zIGZvciB0aGUgbW9kZWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNb2RlbFNpZ25hbDxUPihpbml0aWFsVmFsdWU6IFQpOiBNb2RlbFNpZ25hbDxUPiB7XG4gIGNvbnN0IG5vZGU6IElucHV0U2lnbmFsTm9kZTxULCBUPiA9IE9iamVjdC5jcmVhdGUoSU5QVVRfU0lHTkFMX05PREUpO1xuICBjb25zdCBlbWl0dGVyUmVmID0gbmV3IE91dHB1dEVtaXR0ZXJSZWY8VD4oKTtcblxuICBub2RlLnZhbHVlID0gaW5pdGlhbFZhbHVlO1xuXG4gIGZ1bmN0aW9uIGdldHRlcigpOiBUIHtcbiAgICBwcm9kdWNlckFjY2Vzc2VkKG5vZGUpO1xuICAgIGFzc2VydE1vZGVsU2V0KG5vZGUudmFsdWUpO1xuICAgIHJldHVybiBub2RlLnZhbHVlO1xuICB9XG5cbiAgZ2V0dGVyW1NJR05BTF0gPSBub2RlO1xuICBnZXR0ZXIuYXNSZWFkb25seSA9IHNpZ25hbEFzUmVhZG9ubHlGbi5iaW5kKGdldHRlciBhcyBhbnkpIGFzICgpID0+IFNpZ25hbDxUPjtcblxuICAvLyBUT0RPOiBTaG91bGQgd2UgdGhyb3cgYW4gZXJyb3Igd2hlbiB1cGRhdGluZyBhIGRlc3Ryb3llZCBtb2RlbD9cbiAgZ2V0dGVyLnNldCA9IChuZXdWYWx1ZTogVCkgPT4ge1xuICAgIGlmICghbm9kZS5lcXVhbChub2RlLnZhbHVlLCBuZXdWYWx1ZSkpIHtcbiAgICAgIHNpZ25hbFNldEZuKG5vZGUsIG5ld1ZhbHVlKTtcbiAgICAgIGVtaXR0ZXJSZWYuZW1pdChuZXdWYWx1ZSk7XG4gICAgfVxuICB9O1xuXG4gIGdldHRlci51cGRhdGUgPSAodXBkYXRlRm46ICh2YWx1ZTogVCkgPT4gVCkgPT4ge1xuICAgIGFzc2VydE1vZGVsU2V0KG5vZGUudmFsdWUpO1xuICAgIGdldHRlci5zZXQodXBkYXRlRm4obm9kZS52YWx1ZSkpO1xuICB9O1xuXG4gIGdldHRlci5zdWJzY3JpYmUgPSBlbWl0dGVyUmVmLnN1YnNjcmliZS5iaW5kKGVtaXR0ZXJSZWYpO1xuICBnZXR0ZXIuZGVzdHJveVJlZiA9IGVtaXR0ZXJSZWYuZGVzdHJveVJlZjtcblxuICBpZiAobmdEZXZNb2RlKSB7XG4gICAgZ2V0dGVyLnRvU3RyaW5nID0gKCkgPT4gYFtNb2RlbCBTaWduYWw6ICR7Z2V0dGVyKCl9XWA7XG4gIH1cblxuICByZXR1cm4gZ2V0dGVyIGFzIHR5cGVvZiBnZXR0ZXIgJlxuICAgIFBpY2s8XG4gICAgICBNb2RlbFNpZ25hbDxUPixcbiAgICAgIHwgdHlwZW9mIMm1SU5QVVRfU0lHTkFMX0JSQU5EX1JFQURfVFlQRVxuICAgICAgfCB0eXBlb2YgybVJTlBVVF9TSUdOQUxfQlJBTkRfV1JJVEVfVFlQRVxuICAgICAgfCB0eXBlb2YgybVXUklUQUJMRV9TSUdOQUxcbiAgICA+O1xufVxuXG4vKiogQXNzZXJ0cyB0aGF0IGEgbW9kZWwncyB2YWx1ZSBpcyBzZXQuICovXG5mdW5jdGlvbiBhc3NlcnRNb2RlbFNldCh2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICBpZiAodmFsdWUgPT09IFJFUVVJUkVEX1VOU0VUX1ZBTFVFKSB7XG4gICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihcbiAgICAgIFJ1bnRpbWVFcnJvckNvZGUuUkVRVUlSRURfTU9ERUxfTk9fVkFMVUUsXG4gICAgICBuZ0Rldk1vZGUgJiYgJ01vZGVsIGlzIHJlcXVpcmVkIGJ1dCBubyB2YWx1ZSBpcyBhdmFpbGFibGUgeWV0LicsXG4gICAgKTtcbiAgfVxufVxuIl19