UNPKG

simple-bound

Version:

A simple and customizable reactive data-binding library.

89 lines 3.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const binding_1 = require("../binding"); const util_1 = require("../util"); const base_1 = require("./base"); /** * Allows multiple full-object bindings. * Stores bindings and binds objects together, providing the highest possible abstraction level for bindings. * * @extends {BaseBound<T>} * @template T captures a type of proto object for later usage in binding type inference */ class Bound extends base_1.default { /** * Creates an instance of Bound using a proto object. * @param proto used as an object prototype for the creation of boundObject and storage. Doesn't become bound itself. * @param [plugins] to plug into the binding events. Do not work yet. */ //TODO: Bound plugins! constructor(proto, plugins) { super(proto, plugins); this.storage = {}; const original = JSON.parse(JSON.stringify(proto)); for (const key in original) { if (typeof original[key] === 'object') { // If the value is object - then treat it like another bound target const bound = new Bound(original[key], (plugins || {})[key]); this.boundObject[key] = bound.boundObject; this.storage[key] = bound.storage; } else { const binding = new binding_1.default(false, original[key], [(plugins || {})[key]]); binding.addSubscriber(this.boundObject, key); this.storage[key] = binding; } } } /** * Binds an object to all other current subscribers * * @template U used to capture the bound object type. Must extends original template type. * @param obj to bind * @param [twoWay] whether the binding should be two-way */ //TODO: rework this function. It's a mess. bind(obj, twoWay = true) { const __bind = (_obj, _twoWay = true, path = '') => { Object.defineProperty(_obj, '__bound__', { value: util_1.fromPath(this.boundObject, path).__bound__, writable: true }); for (const key in util_1.fromPath(this.storage, path)) { const nextPath = !path ? key : `${path}.${key}`; const nextStorage = util_1.fromPath(this.storage, nextPath); const nextValue = _obj[key]; if (nextStorage instanceof binding_1.default) { nextStorage.addSubscriber(_obj, key, _twoWay ? 'master' : 'slave'); } else { __bind(nextValue, _twoWay, nextPath); } } }; __bind(obj, twoWay); return this; } /** * Unbinds an object and destroys all of its listeners * * @param obj reference of object to be unbound */ unbind(obj) { const __unbind = (_obj, path = '') => { _obj.__bound__ = undefined; for (const key in util_1.fromPath(this.storage, path)) { const nextPath = !path ? key : `${path}.${key}`; const nextStorage = util_1.fromPath(this.storage, nextPath); const nextValue = _obj[key]; if (nextStorage instanceof binding_1.default) { nextStorage.removeSubscriber(_obj, key); } else { _obj[key] = __unbind(nextValue, nextPath); } } return JSON.parse(JSON.stringify(_obj)); }; return __unbind(obj); } } exports.default = Bound; //# sourceMappingURL=bound.js.map