UNPKG

@difizen/mana-observable

Version:

95 lines (92 loc) 2.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defineProperty = defineProperty; exports.observable = observable; var _config = require("./config"); var _notifiable = require("./notifiable"); var _notifier = require("./notifier"); var _utils = require("./utils"); /* eslint-disable @typescript-eslint/no-explicit-any */ var propertyRelatedNotifier = Symbol('propertyRelatedNotifier'); // redefine observable properties function defineProperty(target, property, defaultValue) { var notifier = _notifier.Notifier.getOrCreate(target, property); /** * notify notifier when property changed */ var onChange = function onChange() { if (_config.ObservableConfig.paused) { return; } _notifier.Notifier.trigger(target, property); }; /** * set observable property value and register onChange listener * @param value * @param notifier */ var handleValue = function handleValue(value) { _utils.InstanceValue.set(target, property, value); if (notifier) { var last = _utils.Observability.getDisposable(propertyRelatedNotifier, notifier); if (last) { last.dispose(); } } if (_notifiable.Notifiable.is(value)) { var valueNotifier = _notifiable.Notifiable.getNotifier(value); if (notifier && valueNotifier) { var toDispose = valueNotifier.onChangeSync(onChange); _utils.Observability.setDisposable(propertyRelatedNotifier, toDispose, notifier); } } }; var initialValue = target[property] === undefined ? defaultValue : target[property]; handleValue(_notifiable.Notifiable.transform(initialValue)); // property getter var getter = function getter() { var value = Reflect.getMetadata(property, target); return value; }; // property setter var setter = function setter(value) { var notifiableValue = _notifiable.Notifiable.transform(value); var oldValue = _utils.InstanceValue.get(target, property); if (notifiableValue !== oldValue) { handleValue(notifiableValue); onChange(); } }; // define property if (Reflect.deleteProperty(target, property)) { Reflect.defineProperty(target, property, { configurable: true, enumerable: true, get: getter, set: setter }); } // mark observable property _utils.ObservableProperties.add(target, property); _utils.Observability.mark(target, property); } function observable(target) { if (!_utils.Observability.canBeObservable(target)) { return target; } var origin = _utils.Observability.getOrigin(target); var properties = _utils.ObservableProperties.find(origin); if (!properties) { var notifiableValue = _notifiable.Notifiable.transform(origin); if (_notifiable.Notifiable.is(notifiableValue)) { _utils.Observability.mark(origin); } return notifiableValue; } properties.forEach(function (property) { return defineProperty(origin, property); }); return origin; }