UNPKG

deep-state-observer

Version:

Deep state observer is an state management library that will fire listeners only when specified object node (which also can be a wildcard) was changed.

1,138 lines (1,137 loc) 81.5 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; exports.__esModule = true; var wildcard_object_scan_1 = require("./wildcard-object-scan"); var ObjectPath_1 = require("./ObjectPath"); var wildcard_matcher_js_1 = require("./wildcard_matcher.js"); var defaultUpdateOptions = { only: [], source: "", debug: false, data: undefined, queue: false, force: false }; function log(message, info) { console.debug(message, info); } function getDefaultOptions() { return { delimiter: ".", debug: false, extraDebug: false, useMute: true, notRecursive: ";", param: ":", wildcard: "*", experimentalMatch: false, queue: false, defaultBulkValue: true, useCache: false, useSplitCache: false, useIndicesCache: false, maxSimultaneousJobs: 1000, maxQueueRuns: 1000, log: log, Promise: Promise }; } /** * Is object - helper function to determine if specified variable is an object * * @param {any} item * @returns {boolean} */ function isObject(item) { if (item && item.constructor) { return item.constructor.name === "Object"; } return typeof item === "object" && item !== null; } var DeepState = /** @class */ (function () { function DeepState(data, options) { if (data === void 0) { data = {}; } if (options === void 0) { options = {}; } this.jobsRunning = 0; this.updateQueue = []; this.subscribeQueue = []; this.listenersIgnoreCache = new WeakMap(); this.is_match = null; this.destroyed = false; this.queueRuns = 0; this.groupId = 0; this.namedGroups = []; this.numberGroups = []; this.traceId = 0; this.traceMap = new Map(); this.tracing = []; this.savedTrace = []; this.collection = null; this.collections = 0; this.cache = new Map(); this.splitCache = new Map(); this.indices = new Map(); this.indicesCount = new Map(); this.lastExecs = new WeakMap(); this.listeners = new Map(); this.waitingListeners = new Map(); this.options = __assign(__assign({}, getDefaultOptions()), options); this.data = data; this.id = 0; if (!this.options.useCache) { this.pathGet = ObjectPath_1["default"].get; this.pathSet = ObjectPath_1["default"].set; } else { this.pathGet = this.cacheGet; this.pathSet = this.cacheSet; } if (options.Promise) { this.resolved = options.Promise.resolve(); } else { this.resolved = Promise.resolve(); } this.muted = new Set(); this.mutedListeners = new Set(); this.scan = new wildcard_object_scan_1["default"](this.data, this.options.delimiter, this.options.wildcard); this.destroyed = false; } DeepState.prototype.getDefaultListenerOptions = function () { return { bulk: false, bulkValue: this.options.defaultBulkValue, debug: false, source: "", data: undefined, queue: false, group: false }; }; DeepState.prototype.cacheGet = function (pathChunks, data, create) { if (data === void 0) { data = this.data; } if (create === void 0) { create = false; } var path = pathChunks.join(this.options.delimiter); var weakRefValue = this.cache.get(path); if (weakRefValue) { var value_1 = weakRefValue.deref(); if (value_1) { return value_1; } } var value = ObjectPath_1["default"].get(pathChunks, data, create); if (isObject(value) || Array.isArray(value)) { // @ts-ignore-next-line this.cache.set(path, new WeakRef(value)); } return value; }; DeepState.prototype.cacheSet = function (pathChunks, value, data) { if (data === void 0) { data = this.data; } var path = pathChunks.join(this.options.delimiter); if (isObject(value) || Array.isArray(value)) { this.cache.set(path, //@ts-ignore-next-line new WeakRef(value)); } else { this.cache["delete"](path); } return ObjectPath_1["default"].set(pathChunks, value, data); }; /** * Silently update data * @param path string * @param value any * @returns */ DeepState.prototype.silentSet = function (path, value) { return this.pathSet(this.split(path), value, this.data); }; DeepState.prototype.loadWasmMatcher = function (pathToWasmFile) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, (0, wildcard_matcher_js_1["default"])(pathToWasmFile)]; case 1: _a.sent(); this.is_match = wildcard_matcher_js_1.is_match; this.scan = new wildcard_object_scan_1["default"](this.data, this.options.delimiter, this.options.wildcard, this.is_match); return [2 /*return*/]; } }); }); }; DeepState.prototype.same = function (newValue, oldValue) { return ((["number", "string", "undefined", "boolean"].includes(typeof newValue) || newValue === null) && oldValue === newValue); }; DeepState.prototype.getListeners = function () { return this.listeners; }; DeepState.prototype.destroy = function () { this.destroyed = true; this.data = undefined; this.listeners = new Map(); this.waitingListeners = new Map(); this.updateQueue = []; this.jobsRunning = 0; }; DeepState.prototype.match = function (first, second, nested) { if (nested === void 0) { nested = true; } if (this.is_match) return this.is_match(first, second); if (first === second) return true; if (first === this.options.wildcard || second === this.options.wildcard) return true; if (!nested && this.getIndicesCount(this.options.delimiter, first) < this.getIndicesCount(this.options.delimiter, second)) { // first < second because first is a listener path and may be longer but not shorter return false; } return this.scan.match(first, second); }; DeepState.prototype.getIndicesOf = function (searchStr, str) { if (this.options.useIndicesCache && this.indices.has(str)) return this.indices.get(str); var searchStrLen = searchStr.length; if (searchStrLen == 0) { return []; } var startIndex = 0, index, indices = []; while ((index = str.indexOf(searchStr, startIndex)) > -1) { indices.push(index); startIndex = index + searchStrLen; } if (this.options.useIndicesCache) this.indices.set(str, indices); return indices; }; DeepState.prototype.getIndicesCount = function (searchStr, str) { if (this.options.useIndicesCache && this.indicesCount.has(str)) return this.indicesCount.get(str); var searchStrLen = searchStr.length; if (searchStrLen == 0) { return 0; } var startIndex = 0, index, indices = 0; while ((index = str.indexOf(searchStr, startIndex)) > -1) { indices++; startIndex = index + searchStrLen; } if (this.options.useIndicesCache) this.indicesCount.set(str, indices); return indices; }; DeepState.prototype.cutPath = function (longer, shorter) { if (shorter === "") return ""; longer = this.cleanNotRecursivePath(longer); shorter = this.cleanNotRecursivePath(shorter); if (longer === shorter) return longer; var shorterPartsLen = this.getIndicesCount(this.options.delimiter, shorter); var longerParts = this.getIndicesOf(this.options.delimiter, longer); return longer.substring(0, longerParts[shorterPartsLen]); }; DeepState.prototype.trimPath = function (path) { path = this.cleanNotRecursivePath(path); if (path.charAt(0) === this.options.delimiter) { return path.substr(1); } return path; }; DeepState.prototype.split = function (path) { if (path === "") return []; if (!this.options.useSplitCache) { return path.split(this.options.delimiter); } var fromCache = this.splitCache.get(path); if (fromCache) { return fromCache.slice(); } var value = path.split(this.options.delimiter); this.splitCache.set(path, value.slice()); return value; }; DeepState.prototype.isWildcard = function (path) { return path.includes(this.options.wildcard) || this.hasParams(path); }; DeepState.prototype.isNotRecursive = function (path) { return path.endsWith(this.options.notRecursive); }; DeepState.prototype.cleanNotRecursivePath = function (path) { return this.isNotRecursive(path) ? path.substring(0, path.length - 1) : path; }; DeepState.prototype.hasParams = function (path) { return path.includes(this.options.param); }; DeepState.prototype.getParamsInfo = function (path) { var e_1, _a; var paramsInfo = { replaced: "", original: path, params: {} }; var partIndex = 0; var fullReplaced = []; try { for (var _b = __values(this.split(path)), _c = _b.next(); !_c.done; _c = _b.next()) { var part = _c.value; paramsInfo.params[partIndex] = { original: part, replaced: "", name: "" }; var reg = new RegExp("\\".concat(this.options.param, "([^\\").concat(this.options.delimiter, "\\").concat(this.options.param, "]+)"), "g"); var param = reg.exec(part); if (param) { paramsInfo.params[partIndex].name = param[1]; } else { delete paramsInfo.params[partIndex]; fullReplaced.push(part); partIndex++; continue; } reg.lastIndex = 0; paramsInfo.params[partIndex].replaced = part.replace(reg, this.options.wildcard); fullReplaced.push(paramsInfo.params[partIndex].replaced); partIndex++; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); } finally { if (e_1) throw e_1.error; } } paramsInfo.replaced = fullReplaced.join(this.options.delimiter); return paramsInfo; }; DeepState.prototype.getParams = function (paramsInfo, path) { if (!paramsInfo) { return undefined; } var split = this.split(path); var result = {}; for (var partIndex in paramsInfo.params) { var param = paramsInfo.params[partIndex]; result[param.name] = split[partIndex]; } return result; }; DeepState.prototype.waitForAll = function (userPaths, fn) { var e_2, _a; var _this = this; var paths = {}; try { for (var userPaths_1 = __values(userPaths), userPaths_1_1 = userPaths_1.next(); !userPaths_1_1.done; userPaths_1_1 = userPaths_1.next()) { var path = userPaths_1_1.value; paths[path] = { dirty: false }; if (this.hasParams(path)) { paths[path].paramsInfo = this.getParamsInfo(path); } paths[path].isWildcard = this.isWildcard(path); paths[path].isRecursive = !this.isNotRecursive(path); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (userPaths_1_1 && !userPaths_1_1.done && (_a = userPaths_1["return"])) _a.call(userPaths_1); } finally { if (e_2) throw e_2.error; } } this.waitingListeners.set(userPaths, { fn: fn, paths: paths }); fn(paths); return function () { _this.waitingListeners["delete"](userPaths); }; }; DeepState.prototype.executeWaitingListeners = function (updatePath) { var e_3, _a; if (this.destroyed) return; try { for (var _b = __values(this.waitingListeners.values()), _c = _b.next(); !_c.done; _c = _b.next()) { var waitingListener = _c.value; var fn = waitingListener.fn, paths = waitingListener.paths; var dirty = 0; var all = 0; for (var path in paths) { var pathInfo = paths[path]; var match = false; if (pathInfo.isRecursive) updatePath = this.cutPath(updatePath, path); if (pathInfo.isWildcard && this.match(path, updatePath)) match = true; if (updatePath === path) match = true; if (match) { pathInfo.dirty = true; } if (pathInfo.dirty) { dirty++; } all++; } if (dirty === all) { fn(paths); } } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); } finally { if (e_3) throw e_3.error; } } }; DeepState.prototype.subscribeAll = function (userPaths, fn, options) { var e_4, _a; if (options === void 0) { options = this.getDefaultListenerOptions(); } if (this.destroyed) return function () { }; var unsubscribers = []; var index = 0; var groupId = null; if (typeof options.group === "boolean" && options.group) { groupId = ++this.groupId; options.bulk = true; } else if (typeof options.group === "string") { options.bulk = true; groupId = options.group; } try { for (var userPaths_2 = __values(userPaths), userPaths_2_1 = userPaths_2.next(); !userPaths_2_1.done; userPaths_2_1 = userPaths_2.next()) { var userPath = userPaths_2_1.value; unsubscribers.push(this.subscribe(userPath, fn, options, { all: userPaths, index: index, groupId: groupId })); index++; } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (userPaths_2_1 && !userPaths_2_1.done && (_a = userPaths_2["return"])) _a.call(userPaths_2); } finally { if (e_4) throw e_4.error; } } return function unsubscribe() { var e_5, _a; try { for (var unsubscribers_1 = __values(unsubscribers), unsubscribers_1_1 = unsubscribers_1.next(); !unsubscribers_1_1.done; unsubscribers_1_1 = unsubscribers_1.next()) { var unsubscribe_1 = unsubscribers_1_1.value; unsubscribe_1(); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (unsubscribers_1_1 && !unsubscribers_1_1.done && (_a = unsubscribers_1["return"])) _a.call(unsubscribers_1); } finally { if (e_5) throw e_5.error; } } }; }; DeepState.prototype.getCleanListenersCollection = function (values) { if (values === void 0) { values = {}; } return __assign({ listeners: new Map(), isRecursive: false, isWildcard: false, hasParams: false, match: undefined, paramsInfo: undefined, path: undefined, originalPath: undefined, count: 0 }, values); }; DeepState.prototype.getCleanListener = function (fn, options) { if (options === void 0) { options = this.getDefaultListenerOptions(); } return { fn: fn, options: __assign(__assign({}, this.getDefaultListenerOptions()), options), groupId: null }; }; DeepState.prototype.getListenerCollectionMatch = function (listenerPath, isRecursive, isWildcard) { listenerPath = this.cleanNotRecursivePath(listenerPath); var self = this; return function listenerCollectionMatch(path, debug) { if (debug === void 0) { debug = false; } var scopedListenerPath = listenerPath; if (isRecursive) { path = self.cutPath(path, listenerPath); } else { scopedListenerPath = self.cutPath(self.cleanNotRecursivePath(listenerPath), path); } if (debug) { console.log("[getListenerCollectionMatch]", { listenerPath: listenerPath, scopedListenerPath: scopedListenerPath, path: path, isRecursive: isRecursive, isWildcard: isWildcard }); } if (isWildcard && self.match(scopedListenerPath, path, isRecursive)) return true; return scopedListenerPath === path; }; }; DeepState.prototype.getListenersCollection = function (listenerPath, listener) { if (this.listeners.has(listenerPath)) { var listenersCollection_1 = this.listeners.get(listenerPath); listenersCollection_1.listeners.set(++this.id, listener); listener.id = this.id; return listenersCollection_1; } var hasParams = this.hasParams(listenerPath); var paramsInfo; if (hasParams) { paramsInfo = this.getParamsInfo(listenerPath); } var collCfg = { isRecursive: !this.isNotRecursive(listenerPath), isWildcard: this.isWildcard(listenerPath), hasParams: hasParams, paramsInfo: paramsInfo, originalPath: listenerPath, path: hasParams ? paramsInfo.replaced : listenerPath }; if (!collCfg.isRecursive) { collCfg.path = this.cleanNotRecursivePath(collCfg.path); } var listenersCollection = this.getCleanListenersCollection(__assign(__assign({}, collCfg), { match: this.getListenerCollectionMatch(collCfg.path, collCfg.isRecursive, collCfg.isWildcard) })); this.id++; listenersCollection.listeners.set(this.id, listener); listener.id = this.id; this.listeners.set(collCfg.originalPath, listenersCollection); return listenersCollection; }; DeepState.prototype.subscribe = function (listenerPath, fn, options, subscribeAllOptions) { if (options === void 0) { options = this.getDefaultListenerOptions(); } if (subscribeAllOptions === void 0) { subscribeAllOptions = { all: [listenerPath], index: 0, groupId: null }; } if (this.destroyed) return function () { }; this.jobsRunning++; var type = "subscribe"; var listener = this.getCleanListener(fn, options); if (options.group) { options.bulk = true; if (typeof options.group === "string") { listener.groupId = options.group; } else if (subscribeAllOptions.groupId) { listener.groupId = subscribeAllOptions.groupId; } } this.listenersIgnoreCache.set(listener, { truthy: [], falsy: [] }); var listenersCollection = this.getListenersCollection(listenerPath, listener); if (options.debug) { console.log("[subscribe]", { listenerPath: listenerPath, options: options }); } listenersCollection.count++; var shouldFire = true; if (listener.groupId) { if (typeof listener.groupId === "string") { if (this.namedGroups.includes(listener.groupId)) { shouldFire = false; } else { this.namedGroups.push(listener.groupId); } } else if (typeof listener.groupId === "number") { if (this.numberGroups.includes(listener.groupId)) { shouldFire = false; } else { this.numberGroups.push(listener.groupId); } } } if (shouldFire) { var cleanPath = this.cleanNotRecursivePath(listenersCollection.path); var cleanPathChunks = this.split(cleanPath); if (!listenersCollection.isWildcard) { if (!this.isMuted(cleanPath) && !this.isMuted(fn)) { fn(this.pathGet(cleanPathChunks, this.data), { type: type, listener: listener, listenersCollection: listenersCollection, path: { listener: listenerPath, update: undefined, resolved: this.cleanNotRecursivePath(listenerPath) }, params: this.getParams(listenersCollection.paramsInfo, cleanPath), options: options }); } } else { var paths = this.scan.get(cleanPath); if (options.bulk) { var bulkValue = []; for (var path in paths) { if (this.isMuted(path)) continue; bulkValue.push({ path: path, params: this.getParams(listenersCollection.paramsInfo, path), value: paths[path] }); } if (!this.isMuted(fn)) { fn(bulkValue, { type: type, listener: listener, listenersCollection: listenersCollection, path: { listener: listenerPath, update: undefined, resolved: undefined }, options: options, params: undefined }); } } else { for (var path in paths) { if (!this.isMuted(path) && !this.isMuted(fn)) { fn(paths[path], { type: type, listener: listener, listenersCollection: listenersCollection, path: { listener: listenerPath, update: undefined, resolved: this.cleanNotRecursivePath(path) }, params: this.getParams(listenersCollection.paramsInfo, path), options: options }); } } } } } this.debugSubscribe(listener, listenersCollection, listenerPath); this.jobsRunning--; return this.unsubscribe(listenerPath, this.id); }; DeepState.prototype.unsubscribe = function (path, id) { var listeners = this.listeners; if (!listeners.has(path)) return function () { }; var listenersCollection = listeners.get(path); return function unsub() { listenersCollection.listeners["delete"](id); listenersCollection.count--; if (listenersCollection.count === 0) { listeners["delete"](path); } }; }; DeepState.prototype.runQueuedListeners = function () { var _this = this; if (this.destroyed) return; if (this.subscribeQueue.length === 0) return; if (this.jobsRunning === 0) { this.queueRuns = 0; var queue = __spreadArray([], __read(this.subscribeQueue), false); for (var i = 0, len = queue.length; i < len; i++) { queue[i](); } this.subscribeQueue.length = 0; } else { this.queueRuns++; if (this.queueRuns >= this.options.maxQueueRuns) { this.queueRuns = 0; throw new Error("Maximal number of queue runs exhausted."); } else { Promise.resolve() .then(function () { return _this.runQueuedListeners(); })["catch"](function (e) { throw e; }); } } }; DeepState.prototype.getQueueNotifyListeners = function (groupedListeners, queue) { var e_6, _a, e_7, _b; var _this = this; if (queue === void 0) { queue = []; } for (var path in groupedListeners) { if (this.isMuted(path)) continue; var _c = groupedListeners[path], single = _c.single, bulk = _c.bulk; var _loop_1 = function (singleListener) { var e_8, _d; var alreadyInQueue = false; var resolvedIdPath = singleListener.listener.id + ":" + singleListener.eventInfo.path.resolved; if (!singleListener.eventInfo.path.resolved) { resolvedIdPath = singleListener.listener.id + ":" + singleListener.eventInfo.path.listener; } try { for (var queue_1 = (e_8 = void 0, __values(queue)), queue_1_1 = queue_1.next(); !queue_1_1.done; queue_1_1 = queue_1.next()) { var excludedListener = queue_1_1.value; if (resolvedIdPath === excludedListener.resolvedIdPath) { alreadyInQueue = true; break; } } } catch (e_8_1) { e_8 = { error: e_8_1 }; } finally { try { if (queue_1_1 && !queue_1_1.done && (_d = queue_1["return"])) _d.call(queue_1); } finally { if (e_8) throw e_8.error; } } if (alreadyInQueue) { return "continue"; } var time = this_1.debugTime(singleListener); if (!this_1.isMuted(singleListener.listener.fn)) { if (singleListener.listener.options.queue && this_1.jobsRunning) { this_1.subscribeQueue.push(function () { singleListener.listener.fn(singleListener.value ? singleListener.value() : undefined, singleListener.eventInfo); }); } else { var resolvedIdPath_1 = singleListener.listener.id + ":" + singleListener.eventInfo.path.resolved; if (!singleListener.eventInfo.path.resolved) { resolvedIdPath_1 = singleListener.listener.id + ":" + singleListener.eventInfo.path.listener; } queue.push({ id: singleListener.listener.id, resolvedPath: singleListener.eventInfo.path.resolved, resolvedIdPath: resolvedIdPath_1, originalFn: singleListener.listener.fn, fn: function () { singleListener.listener.fn(singleListener.value ? singleListener.value() : undefined, singleListener.eventInfo); }, options: singleListener.listener.options, groupId: singleListener.listener.groupId }); } } this_1.debugListener(time, singleListener); }; var this_1 = this; try { for (var single_1 = (e_6 = void 0, __values(single)), single_1_1 = single_1.next(); !single_1_1.done; single_1_1 = single_1.next()) { var singleListener = single_1_1.value; _loop_1(singleListener); } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (single_1_1 && !single_1_1.done && (_a = single_1["return"])) _a.call(single_1); } finally { if (e_6) throw e_6.error; } } var _loop_2 = function (bulkListener) { var e_9, _e, e_10, _f; var alreadyInQueue = false; try { for (var queue_2 = (e_9 = void 0, __values(queue)), queue_2_1 = queue_2.next(); !queue_2_1.done; queue_2_1 = queue_2.next()) { var excludedListener = queue_2_1.value; if (excludedListener.id === bulkListener.listener.id) { alreadyInQueue = true; break; } } } catch (e_9_1) { e_9 = { error: e_9_1 }; } finally { try { if (queue_2_1 && !queue_2_1.done && (_e = queue_2["return"])) _e.call(queue_2); } finally { if (e_9) throw e_9.error; } } if (alreadyInQueue) return "continue"; var time = this_2.debugTime(bulkListener); var bulkValue = []; try { for (var _g = (e_10 = void 0, __values(bulkListener.value)), _h = _g.next(); !_h.done; _h = _g.next()) { var bulk_2 = _h.value; bulkValue.push(__assign(__assign({}, bulk_2), { value: bulk_2.value ? bulk_2.value() : undefined })); } } catch (e_10_1) { e_10 = { error: e_10_1 }; } finally { try { if (_h && !_h.done && (_f = _g["return"])) _f.call(_g); } finally { if (e_10) throw e_10.error; } } if (!this_2.isMuted(bulkListener.listener.fn)) { if (bulkListener.listener.options.queue && this_2.jobsRunning) { this_2.subscribeQueue.push(function () { if (!_this.jobsRunning) { bulkListener.listener.fn(bulkValue, bulkListener.eventInfo); return true; } return false; }); } else { var resolvedIdPath = bulkListener.listener.id + ":" + bulkListener.eventInfo.path.resolved; if (!bulkListener.eventInfo.path.resolved) { resolvedIdPath = bulkListener.listener.id + ":" + bulkListener.eventInfo.path.listener; } queue.push({ id: bulkListener.listener.id, resolvedPath: bulkListener.eventInfo.path.resolved, resolvedIdPath: resolvedIdPath, originalFn: bulkListener.listener.fn, fn: function () { bulkListener.listener.fn(bulkValue, bulkListener.eventInfo); }, options: bulkListener.listener.options, groupId: bulkListener.listener.groupId }); } } this_2.debugListener(time, bulkListener); }; var this_2 = this; try { for (var bulk_1 = (e_7 = void 0, __values(bulk)), bulk_1_1 = bulk_1.next(); !bulk_1_1.done; bulk_1_1 = bulk_1.next()) { var bulkListener = bulk_1_1.value; _loop_2(bulkListener); } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (bulk_1_1 && !bulk_1_1.done && (_b = bulk_1["return"])) _b.call(bulk_1); } finally { if (e_7) throw e_7.error; } } } Promise.resolve().then(function () { return _this.runQueuedListeners(); }); return queue; }; DeepState.prototype.shouldIgnore = function (listener, updatePath) { var e_11, _a; if (!listener.options.ignore) return false; try { for (var _b = __values(listener.options.ignore), _c = _b.next(); !_c.done; _c = _b.next()) { var ignorePath = _c.value; if (updatePath.startsWith(ignorePath)) { return true; } if (this.is_match && this.is_match(ignorePath, updatePath)) { return true; } else { var cuttedUpdatePath = this.cutPath(updatePath, ignorePath); if (this.match(ignorePath, cuttedUpdatePath)) { return true; } } } } catch (e_11_1) { e_11 = { error: e_11_1 }; } finally { try { if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); } finally { if (e_11) throw e_11.error; } } return false; }; DeepState.prototype.getSubscribedListeners = function (updatePath, newValue, options, type, originalPath) { var e_12, _a; var _this = this; if (type === void 0) { type = "update"; } if (originalPath === void 0) { originalPath = null; } options = __assign(__assign({}, defaultUpdateOptions), options); var listeners = {}; var _loop_3 = function (listenerPath, listenersCollection) { var e_13, _e, e_14, _f; if (listenersCollection.match(updatePath)) { listeners[listenerPath] = { single: [], bulk: [], bulkData: [] }; var params = listenersCollection.paramsInfo ? this_3.getParams(listenersCollection.paramsInfo, updatePath) : undefined; var cutPath_1 = this_3.cutPath(updatePath, listenerPath); var traverse = listenersCollection.isRecursive || listenersCollection.isWildcard; var value = traverse ? function () { return _this.get(cutPath_1); } : function () { return newValue; }; var bulkValue = [{ value: value, path: updatePath, params: params }]; try { for (var _g = (e_13 = void 0, __values(listenersCollection.listeners.values())), _h = _g.next(); !_h.done; _h = _g.next()) { var listener = _h.value; if (this_3.shouldIgnore(listener, updatePath)) { if (listener.options.debug) { console.log("[getSubscribedListeners] Listener was not fired because it was ignored.", { listener: listener, listenersCollection: listenersCollection }); } continue; } if (listener.options.bulk) { listeners[listenerPath].bulk.push({ listener: listener, listenersCollection: listenersCollection, eventInfo: { type: type, listener: listener, path: { listener: listenerPath, update: originalPath ? originalPath : updatePath, resolved: undefined }, params: params, options: options }, value: bulkValue }); } else { listeners[listenerPath].single.push({ listener: listener, listenersCollection: listenersCollection, eventInfo: { type: type, listener: listener, path: { listener: listenerPath, update: originalPath ? originalPath : updatePath, resolved: this_3.cleanNotRecursivePath(updatePath) }, params: params, options: options }, value: value }); } } } catch (e_13_1) { e_13 = { error: e_13_1 }; } finally { try { if (_h && !_h.done && (_e = _g["return"])) _e.call(_g); } finally { if (e_13) throw e_13.error; } } } else if (this_3.options.extraDebug) { // debug var showMatch = false; try { for (var _j = (e_14 = void 0, __values(listenersCollection.listeners.values())), _k = _j.next(); !_k.done; _k = _j.next()) { var listener = _k.value; if (listener.options.debug) { showMatch = true; console.log("[getSubscribedListeners] Listener was not fired because there was no match.", { listener: listener, listenersCollection: listenersCollection, updatePath: updatePath }); } } } catch (e_14_1) { e_14 = { error: e_14_1 }; } finally { try { if (_k && !_k.done && (_f = _j["return"])) _f.call(_j); } finally { if (e_14) throw e_14.error; } } if (showMatch) { listenersCollection.match(updatePath, true); } } }; var this_3 = this; try { for (var _b = __values(this.listeners), _c = _b.next(); !_c.done; _c = _b.next()) { var _d = __read(_c.value, 2), listenerPath = _d[0], listenersCollection = _d[1]; _loop_3(listenerPath, listenersCollection); } } catch (e_12_1) { e_12 = { error: e_12_1 }; } finally { try { if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); } finally { if (e_12) throw e_12.error; } } return listeners; }; DeepState.prototype.notifySubscribedListeners = function (updatePath, newValue, options, type, originalPath) { if (type === void 0) { type = "update"; } if (originalPath === void 0) { originalPath = null; } return this.getQueueNotifyListeners(this.getSubscribedListeners(updatePath, newValue, options, type, originalPath)); }; DeepState.prototype.useBulkValue = function (listenersCollection) { var e_15, _a; try { for (var _b = __values(listenersCollection.listeners), _c = _b.next(); !_c.done; _c = _b.next()) { var _d = __read(_c.value, 2), listenerId = _d[0], listener = _d[1]; if (listener.options.bulk && listener.options.bulkValue) return true; if (!listener.options.bulk) return true; } } catch (e_15_1) { e_15 = { error: e_15_1 }; } finally { try { if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); } finally { if (e_15) throw e_15.error; } } return false; }; DeepState.prototype.getNestedListeners = function (updatePath, newValue, options, type, originalPath) { var e_16, _a; if (type === void 0) { type = "update"; } if (originalPath === void 0) { originalPath = null; } var listeners = {}; var restBelowValues = {}; var _loop_4 = function (listenerPath, listenersCollection) { var e_17, _e, e_18, _f; if (!listenersCollection.isRecursive) return "continue"; // listenerPath may be longer and is shortened - because we want to get listeners underneath change var currentAbovePathCut = this_4.cutPath(listenerPath, updatePath); if (this_4.match(currentAbovePathCut, updatePath)) { listeners[listenerPath] = { single: [], bulk: [] }; // listener is listening below updated node var restBelowPathCut = this_4.trimPath(listenerPath.substr(currentAbovePathCut.length)); var useBulkValue = this_4.useBulkValue(listenersCollection); var wildcardNewValues_1; if (useBulkValue) { wildcardNewValues_1 = restBelowValues[restBelowPathCut] ? restBelowValues[restBelowPathCut] // if those values are already calculated use it : new wildcard_object_scan_1["default"](newValue, this_4.options.delimiter, this_4.options.wildcard).get(restBelowPathCut); restBelowValues[restBelowPathCut] = wildcardNewValues_1; } var params = listenersCollection.paramsInfo ? this_4.getParams(listenersCollection.paramsInfo, updatePath) : undefined; var bulk = []; var bulkListeners = {}; try { for (var _g = (e_17 = void 0, __values(listenersCollection.listeners)), _h = _g.next(); !_h.done; _h = _g.next()) { var _j = __read(_h.value, 2), listenerId = _j[0], listener = _j[1]; if (useBulkValue) { var _loop_5 = function (currentRestPath) { var value = function () { return wildcardNewValues_1[currentRestPath]; }; var fullPath = [updatePath, currentRestPath].join(this_4.options.delimiter); var eventInfo = { type: type, listener: listener, listenersCollection: listenersCollection, path: { listener: listenerPath, update: originalPath ? originalPath : updatePath, resolved: this_4.cleanNotRecursivePath(fullPath) }, params: params, options: options }; if (this_4.shouldIgnore(listener, updatePath)) return "continue"; if (listener.options.bulk) { bulk.push({ value: value, path: fullPath, params: params }); bulkListeners[listenerId] = listener; }