UNPKG

reactronic

Version:

Reactronic - Transactional Reactive State Management

92 lines (91 loc) 2.66 kB
import { misuse } from "./util/Dbg.js"; import { runTransactional, runNonReactive } from "./System.js"; export function refs(owner) { return new Proxy(owner, RefGettingProxy); } export function toggleRefs(owner) { return new Proxy(owner, BoolRefGettingProxy); } export function customToggleRefs(owner, value1, value2) { const handler = new CustomToggleRefGettingProxy(value1, value2); return new Proxy(owner, handler); } export class Ref { constructor(owner, name, index = -1) { this.owner = owner; this.name = name; this.index = index; } get variable() { if (this.index < 0) return this.owner[this.name]; else return this.owner[this.name][this.index]; } set variable(value) { if (this.index < 0) this.owner[this.name] = value; else this.owner[this.name][this.index] = value; } nonReactively() { return runNonReactive(() => this.variable); } signalling() { return this.variable; } nonSignalling() { throw misuse("not implemented"); } static sameRefs(v1, v2) { return v1.owner === v2.owner && v1.name === v2.name && v1.index === v2.index; } static similarRefs(v1, v2) { return v1.owner.constructor === v2.owner.constructor && v1.name === v2.name && v1.index === v2.index; } } export class ToggleRef extends Ref { constructor(owner, name, valueOn, valueOff) { super(owner, name); this.valueOn = valueOn; this.valueOff = valueOff; } toggle() { const o = this.owner; const p = this.name; runTransactional({ hint: `toggle ${o.constructor.name}.${p}` }, () => { const v = o[p]; const isOn = v === this.valueOn || (v instanceof Ref && this.valueOn instanceof Ref && Ref.sameRefs(v, this.valueOn)); if (!isOn) o[p] = this.valueOn; else o[p] = this.valueOff; }); } } const RefGettingProxy = { get: (obj, prop) => { return new Ref(obj, prop); }, }; const BoolRefGettingProxy = { get: (obj, prop) => { return new ToggleRef(obj, prop, true, false); }, }; class CustomToggleRefGettingProxy { constructor(value1, value2) { this.value1 = value1; this.value2 = value2; } get(obj, prop) { return new ToggleRef(obj, prop, this.value1, this.value2); } } Object.defineProperty(Object.prototype, "$$", { configurable: false, enumerable: false, get() { return new Proxy(this, RefGettingProxy); }, });