UNPKG

@wordpress/interactivity

Version:

Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.

136 lines (124 loc) 3.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PropSignal = void 0; var _signals = require("@preact/signals"); var _registry = require("./registry"); var _scopes = require("../scopes"); var _namespaces = require("../namespaces"); var _utils = require("../utils"); /** * External dependencies */ /** * Internal dependencies */ /** * Identifier for property computeds not associated to any scope. */ const NO_SCOPE = {}; /** * Structure that manages reactivity for a property in a state object. It uses * signals to keep track of property value or getter modifications. */ class PropSignal { /** * Proxy that holds the property this PropSignal is associated with. */ /** * Relation of computeds by scope. These computeds are read-only signals * that depend on whether the property is a value or a getter and, * therefore, can return different values depending on the scope in which * the getter is accessed. */ /** * Signal with the value assigned to the related property. */ /** * Signal with the getter assigned to the related property. */ /** * Structure that manages reactivity for a property in a state object, using * signals to keep track of property value or getter modifications. * * @param owner Proxy that holds the property this instance is associated * with. */ constructor(owner) { this.owner = owner; this.computedsByScope = new WeakMap(); } /** * Changes the internal value. If a getter was set before, it is set to * `undefined`. * * @param value New value. */ setValue(value) { this.update({ value }); } /** * Changes the internal getter. If a value was set before, it is set to * `undefined`. * * @param getter New getter. */ setGetter(getter) { this.update({ get: getter }); } /** * Returns the computed that holds the result of evaluating the prop in the * current scope. * * These computeds are read-only signals that depend on whether the property * is a value or a getter and, therefore, can return different values * depending on the scope in which the getter is accessed. * * @return Computed that depends on the scope. */ getComputed() { const scope = (0, _scopes.getScope)() || NO_SCOPE; if (!this.valueSignal && !this.getterSignal) { this.update({}); } if (!this.computedsByScope.has(scope)) { const callback = () => { const getter = this.getterSignal?.value; return getter ? getter.call(this.owner) : this.valueSignal?.value; }; (0, _namespaces.setNamespace)((0, _registry.getNamespaceFromProxy)(this.owner)); this.computedsByScope.set(scope, (0, _signals.computed)((0, _utils.withScope)(callback))); (0, _namespaces.resetNamespace)(); } return this.computedsByScope.get(scope); } /** * Updates the internal signals for the value and the getter of the * corresponding prop. * * @param param0 * @param param0.get New getter. * @param param0.value New value. */ update({ get, value }) { if (!this.valueSignal) { this.valueSignal = (0, _signals.signal)(value); this.getterSignal = (0, _signals.signal)(get); } else if (value !== this.valueSignal.peek() || get !== this.getterSignal.peek()) { (0, _signals.batch)(() => { this.valueSignal.value = value; this.getterSignal.value = get; }); } } } exports.PropSignal = PropSignal; //# sourceMappingURL=signals.js.map