UNPKG

vasille

Version:

The first Developer eXperience Orientated front-end framework (core library).

114 lines (113 loc) 3.17 kB
import { Destroyable } from "./destroyable.js"; import { Expression } from "../value/expression.js"; import { Reference } from "../value/reference.js"; import { OwningPointer, Pointer } from "../value/pointer.js"; /** * A reactive object * @class Reactive * @extends Destroyable */ export class Reactive extends Destroyable { constructor(input) { super(); /** * A list of user-defined bindings * @type {Set} */ this.bindings = new Set(); this.input = input; this.state = {}; } /** * Create a reference * @param value {*} value to reference * @param name {string} used for debugging internal state */ ref(value, name) { const ref = new Reference(value); this.bindings.add(ref); if (name) { this.addState("ref", name, ref); } return ref; } /** * Create a forward-only pointer * @param value {IValue} value to point * @param name {string} used for debugging internal state */ forward(value, name) { const mirror = new Pointer(value); this.bindings.add(mirror); if (name) { this.addState("forward", name, mirror); } return mirror; } /** * Creates a pointer * @param value {*} default value to point * @param name {string} used for debugging internal state */ own(value, name) { const pointer = new OwningPointer(value); this.bindings.add(pointer); /* istanbul ignore else */ if (name) { this.addState("own", name, pointer); } return pointer; } /** * Register a model/dependency */ register(data, name) { this.bindings.add(data); if (name) { this.addState("model", name, data); } return data; } release(data) { this.bindings.delete(data); } /** * Creates a watcher * @param func {function} function to run on any argument change * @param values */ watch(func, values) { this.bindings.add(new Expression(func, values)); } /** * Creates a computed value * @param func {function} function to run on any argument change * @param values * @param name {string} used for debugging internal state * @return {IValue} the created ivalue */ expr(func, values, name) { const res = new Expression(func, values); this.bindings.add(res); if (name) { this.addState("expr", name, res); } return res; } runOnDestroy(func) { if (this.onDestroy) { console.warn(new Error("You rewrite onDestroy existing handler")); console.log(this.onDestroy); } this.onDestroy = func; } addState(method, name, state) { this.state[name === "#" ? `#${Object.keys(this.state).length}` : name] = [method, state]; } destroy() { super.destroy(); this.bindings.forEach(binding => binding.destroy()); this.bindings.clear(); this.onDestroy?.(); } }