UNPKG

@tko/computed

Version:

TKO Computed Observables

1,535 lines (1,506 loc) 56.8 kB
// @tko/computed 🥊 4.0.0-beta1.3 CommonJS var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // index.ts var computed_exports = {}; __export(computed_exports, { computed: () => computed, isComputed: () => isComputed, isPureComputed: () => isPureComputed, proxy: () => proxy, pureComputed: () => pureComputed, throttleExtender: () => throttleExtender, when: () => when }); module.exports = __toCommonJS(computed_exports); // ../utils/dist/array.js var { isArray } = Array; function arrayForEach(array, action, thisArg) { if (arguments.length > 2) { action = action.bind(thisArg); } for (let i = 0, j = array.length; i < j; ++i) { action(array[i], i, array); } } function arrayIndexOf(array, item) { return (isArray(array) ? array : [...array]).indexOf(item); } function arrayRemoveItem(array, itemToRemove) { var index = arrayIndexOf(array, itemToRemove); if (index > 0) { array.splice(index, 1); } else if (index === 0) { array.shift(); } } function findMovesInArrayComparison(left, right, limitFailedCompares) { if (left.length && right.length) { var failedCompares, l, r, leftItem, rightItem; for (failedCompares = l = 0; (!limitFailedCompares || failedCompares < limitFailedCompares) && (leftItem = left[l]); ++l) { for (r = 0; rightItem = right[r]; ++r) { if (leftItem.value === rightItem.value) { leftItem.moved = rightItem.index; rightItem.moved = leftItem.index; right.splice(r, 1); failedCompares = r = 0; break; } } failedCompares += r; } } } var statusNotInOld = "added"; var statusNotInNew = "deleted"; function compareArrays(oldArray, newArray, options2) { options2 = typeof options2 === "boolean" ? { dontLimitMoves: options2 } : options2 || {}; oldArray = oldArray || []; newArray = newArray || []; if (oldArray.length < newArray.length) { return compareSmallArrayToBigArray(oldArray, newArray, statusNotInOld, statusNotInNew, options2); } else { return compareSmallArrayToBigArray(newArray, oldArray, statusNotInNew, statusNotInOld, options2); } } function compareSmallArrayToBigArray(smlArray, bigArray, statusNotInSml, statusNotInBig, options2) { var myMin = Math.min, myMax = Math.max, editDistanceMatrix = [], smlIndex, smlIndexMax = smlArray.length, bigIndex, bigIndexMax = bigArray.length, compareRange = bigIndexMax - smlIndexMax || 1, maxDistance = smlIndexMax + bigIndexMax + 1, thisRow, lastRow, bigIndexMaxForRow, bigIndexMinForRow; for (smlIndex = 0; smlIndex <= smlIndexMax; smlIndex++) { lastRow = thisRow; editDistanceMatrix.push(thisRow = []); bigIndexMaxForRow = myMin(bigIndexMax, smlIndex + compareRange); bigIndexMinForRow = myMax(0, smlIndex - 1); for (bigIndex = bigIndexMinForRow; bigIndex <= bigIndexMaxForRow; bigIndex++) { if (!bigIndex) { thisRow[bigIndex] = smlIndex + 1; } else if (!smlIndex) { thisRow[bigIndex] = bigIndex + 1; } else if (smlArray[smlIndex - 1] === bigArray[bigIndex - 1]) { thisRow[bigIndex] = lastRow[bigIndex - 1]; } else { var northDistance = lastRow[bigIndex] || maxDistance; var westDistance = thisRow[bigIndex - 1] || maxDistance; thisRow[bigIndex] = myMin(northDistance, westDistance) + 1; } } } var editScript = [], meMinusOne, notInSml = [], notInBig = []; for (smlIndex = smlIndexMax, bigIndex = bigIndexMax; smlIndex || bigIndex; ) { meMinusOne = editDistanceMatrix[smlIndex][bigIndex] - 1; if (bigIndex && meMinusOne === editDistanceMatrix[smlIndex][bigIndex - 1]) { notInSml.push(editScript[editScript.length] = { "status": statusNotInSml, "value": bigArray[--bigIndex], "index": bigIndex }); } else if (smlIndex && meMinusOne === editDistanceMatrix[smlIndex - 1][bigIndex]) { notInBig.push(editScript[editScript.length] = { "status": statusNotInBig, "value": smlArray[--smlIndex], "index": smlIndex }); } else { --bigIndex; --smlIndex; if (!options2.sparse) { editScript.push({ "status": "retained", "value": bigArray[bigIndex] }); } } } findMovesInArrayComparison(notInBig, notInSml, !options2.dontLimitMoves && smlIndexMax * 10); return editScript.reverse(); } // ../utils/dist/options.js var options = { deferUpdates: false, useOnlyNativeEvents: false, protoProperty: "__ko_proto__", defaultBindingAttribute: "data-bind", allowVirtualElements: true, bindingGlobals: /* @__PURE__ */ Object.create(null), bindingProviderInstance: null, createChildContextWithAs: false, jQuery: globalThis.jQuery, Promise: globalThis.Promise, taskScheduler: null, debug: false, global: globalThis, document: globalThis.document, filters: {}, includeDestroyed: false, foreachHidesDestroyed: false, onError: function(e) { throw e; }, set: function(name, value) { options[name] = value; }, getBindingHandler() { }, cleanExternalData() { } }; Object.defineProperty(options, "$", { get: function() { return options.jQuery; } }); var options_default = options; // ../utils/dist/error.js function catchFunctionErrors(delegate) { if (!options_default.onError) { return delegate; } return (...args) => { try { return delegate(...args); } catch (err) { options_default.onError(err); } }; } function deferError(error) { safeSetTimeout(function() { throw error; }, 0); } function safeSetTimeout(handler, timeout) { return setTimeout(catchFunctionErrors(handler), timeout); } // ../utils/dist/async.js function throttle(callback, timeout) { var timeoutInstance; return function(...args) { if (!timeoutInstance) { timeoutInstance = safeSetTimeout(function() { timeoutInstance = void 0; callback(...args); }, timeout); } }; } function debounce(callback, timeout) { var timeoutInstance; return function(...args) { clearTimeout(timeoutInstance); timeoutInstance = safeSetTimeout(() => callback(...args), timeout); }; } // ../utils/dist/ie.js var ieVersion = options_default.document && function() { var version = 3, div = options_default.document.createElement("div"), iElems = div.getElementsByTagName("i"); while (div.innerHTML = "<!--[if gt IE " + ++version + "]><i></i><![endif]-->", iElems[0]) { } if (!version) { const userAgent = window.navigator.userAgent; return ua.match(/MSIE ([^ ]+)/) || ua.match(/rv:([^ )]+)/); } return version > 4 ? version : void 0; }(); // ../utils/dist/object.js function hasOwnProperty(obj, propName) { return Object.prototype.hasOwnProperty.call(obj, propName); } function extend(target, source) { if (source) { for (var prop in source) { if (hasOwnProperty(source, prop)) { target[prop] = source[prop]; } } } return target; } function objectForEach(obj, action) { for (var prop in obj) { if (hasOwnProperty(obj, prop)) { action(prop, obj[prop]); } } } // ../utils/dist/function.js function testOverwrite() { try { Object.defineProperty(function x() { }, "length", {}); return true; } catch (e) { return false; } } var functionSupportsLengthOverwrite = testOverwrite(); function overwriteLengthPropertyIfSupported(fn, descriptor) { if (functionSupportsLengthOverwrite) { Object.defineProperty(fn, "length", descriptor); } } // ../utils/dist/symbol.js var useSymbols = typeof Symbol === "function"; function createSymbolOrString(identifier) { return useSymbols ? Symbol(identifier) : identifier; } // ../utils/dist/jquery.js var jQueryInstance = options_default.global && options_default.global.jQuery; // ../utils/dist/dom/info.js function domNodeIsContainedBy(node, containedByNode) { if (node === containedByNode) { return true; } if (node.nodeType === 11) { return false; } if (containedByNode.contains) { return containedByNode.contains(node.nodeType !== 1 ? node.parentNode : node); } if (containedByNode.compareDocumentPosition) { return (containedByNode.compareDocumentPosition(node) & 16) == 16; } while (node && node != containedByNode) { node = node.parentNode; } return !!node; } function domNodeIsAttachedToDocument(node) { return domNodeIsContainedBy(node, node.ownerDocument.documentElement); } function tagNameLower(element) { return element && element.tagName && element.tagName.toLowerCase(); } // ../utils/dist/dom/data.js var datastoreTime = new Date().getTime(); var dataStoreKeyExpandoPropertyName = `__ko__${datastoreTime}`; var dataStoreSymbol = Symbol("Knockout data"); var dataStore; var uniqueId = 0; var modern = { getDataForNode(node, createIfNotFound) { let dataForNode = node[dataStoreSymbol]; if (!dataForNode && createIfNotFound) { dataForNode = node[dataStoreSymbol] = {}; } return dataForNode; }, clear(node) { if (node[dataStoreSymbol]) { delete node[dataStoreSymbol]; return true; } return false; } }; var IE = { getDataforNode(node, createIfNotFound) { let dataStoreKey = node[dataStoreKeyExpandoPropertyName]; const hasExistingDataStore = dataStoreKey && dataStoreKey !== "null" && dataStore[dataStoreKey]; if (!hasExistingDataStore) { if (!createIfNotFound) { return void 0; } dataStoreKey = node[dataStoreKeyExpandoPropertyName] = "ko" + uniqueId++; dataStore[dataStoreKey] = {}; } return dataStore[dataStoreKey]; }, clear(node) { const dataStoreKey = node[dataStoreKeyExpandoPropertyName]; if (dataStoreKey) { delete dataStore[dataStoreKey]; node[dataStoreKeyExpandoPropertyName] = null; return true; } return false; } }; var { getDataForNode, clear } = ieVersion ? IE : modern; function nextKey() { return uniqueId++ + dataStoreKeyExpandoPropertyName; } function get(node, key) { const dataForNode = getDataForNode(node, false); return dataForNode && dataForNode[key]; } function set(node, key, value) { var dataForNode = getDataForNode(node, value !== void 0); dataForNode && (dataForNode[key] = value); } // ../utils/dist/dom/disposal.js var domDataKey = nextKey(); function getDisposeCallbacksCollection(node, createIfNotFound) { var allDisposeCallbacks = get(node, domDataKey); if (allDisposeCallbacks === void 0 && createIfNotFound) { allDisposeCallbacks = []; set(node, domDataKey, allDisposeCallbacks); } return allDisposeCallbacks; } function destroyCallbacksCollection(node) { set(node, domDataKey, void 0); } function addDisposeCallback(node, callback) { if (typeof callback !== "function") { throw new Error("Callback must be a function"); } getDisposeCallbacksCollection(node, true).push(callback); } function removeDisposeCallback(node, callback) { var callbacksCollection = getDisposeCallbacksCollection(node, false); if (callbacksCollection) { arrayRemoveItem(callbacksCollection, callback); if (callbacksCollection.length === 0) { destroyCallbacksCollection(node); } } } var otherNodeCleanerFunctions = []; function cleanjQueryData(node) { var jQueryCleanNodeFn = jQueryInstance ? jQueryInstance.cleanData : null; if (jQueryCleanNodeFn) { jQueryCleanNodeFn([node]); } } otherNodeCleanerFunctions.push(cleanjQueryData); // ../utils/dist/dom/event.js var knownEvents = {}; var knownEventTypesByEventName = {}; var keyEventTypeName = options_default.global.navigator && /Firefox\/2/i.test(options_default.global.navigator.userAgent) ? "KeyboardEvent" : "UIEvents"; knownEvents[keyEventTypeName] = ["keyup", "keydown", "keypress"]; knownEvents["MouseEvents"] = [ "click", "dblclick", "mousedown", "mouseup", "mousemove", "mouseover", "mouseout", "mouseenter", "mouseleave" ]; objectForEach(knownEvents, function(eventType, knownEventsForType) { if (knownEventsForType.length) { for (var i = 0, j = knownEventsForType.length; i < j; i++) { knownEventTypesByEventName[knownEventsForType[i]] = eventType; } } }); // ../utils/dist/dom/virtualElements.js var commentNodesHaveTextProperty = options_default.document && options_default.document.createComment("test").text === "<!--test-->"; // ../utils/dist/dom/html.js var supportsTemplateTag = options_default.document && "content" in options_default.document.createElement("template"); // ../utils/dist/dom/selectExtensions.js var hasDomDataExpandoProperty = Symbol("Knockout selectExtensions hasDomDataProperty"); var selectExtensions = { optionValueDomDataKey: nextKey(), readValue: function(element) { switch (tagNameLower(element)) { case "option": if (element[hasDomDataExpandoProperty] === true) { return get(element, selectExtensions.optionValueDomDataKey); } return element.value; case "select": return element.selectedIndex >= 0 ? selectExtensions.readValue(element.options[element.selectedIndex]) : void 0; default: return element.value; } }, writeValue: function(element, value, allowUnset) { switch (tagNameLower(element)) { case "option": if (typeof value === "string") { set(element, selectExtensions.optionValueDomDataKey, void 0); if (hasDomDataExpandoProperty in element) { delete element[hasDomDataExpandoProperty]; } element.value = value; } else { set(element, selectExtensions.optionValueDomDataKey, value); element[hasDomDataExpandoProperty] = true; element.value = typeof value === "number" ? value : ""; } break; case "select": if (value === "" || value === null) { value = void 0; } var selection = -1; for (let i = 0, n = element.options.length, optionValue; i < n; ++i) { optionValue = selectExtensions.readValue(element.options[i]); const strictEqual = optionValue === value; const blankEqual = optionValue === "" && value === void 0; const numericEqual = typeof value === "number" && Number(optionValue) === value; if (strictEqual || blankEqual || numericEqual) { selection = i; break; } } if (allowUnset || selection >= 0 || value === void 0 && element.size > 1) { element.selectedIndex = selection; } break; default: if (value === null || value === void 0) { value = ""; } element.value = value; break; } } }; // ../utils/dist/tasks.js var tasks_exports = {}; __export(tasks_exports, { cancel: () => cancel, resetForTesting: () => resetForTesting, runEarly: () => processTasks, schedule: () => schedule }); var taskQueue = []; var taskQueueLength = 0; var nextHandle = 1; var nextIndexToProcess = 0; var w = options_default.global; if (w && w.MutationObserver && !(w.navigator && w.navigator.standalone)) { options_default.taskScheduler = function(callback) { var div = w.document.createElement("div"); new w.MutationObserver(callback).observe(div, { attributes: true }); return function() { div.classList.toggle("foo"); }; }(scheduledProcess); } else if (w && w.document && "onreadystatechange" in w.document.createElement("script")) { options_default.taskScheduler = function(callback) { var script = document.createElement("script"); script.onreadystatechange = function() { script.onreadystatechange = null; document.documentElement.removeChild(script); script = null; callback(); }; document.documentElement.appendChild(script); }; } else { options_default.taskScheduler = function(callback) { setTimeout(callback, 0); }; } function processTasks() { if (taskQueueLength) { var mark = taskQueueLength, countMarks = 0; for (var task; nextIndexToProcess < taskQueueLength; ) { if (task = taskQueue[nextIndexToProcess++]) { if (nextIndexToProcess > mark) { if (++countMarks >= 5e3) { nextIndexToProcess = taskQueueLength; deferError(Error("'Too much recursion' after processing " + countMarks + " task groups.")); break; } mark = taskQueueLength; } try { task(); } catch (ex) { deferError(ex); } } } } } function scheduledProcess() { processTasks(); nextIndexToProcess = taskQueueLength = taskQueue.length = 0; } function scheduleTaskProcessing() { options_default.taskScheduler(scheduledProcess); } function schedule(func) { if (!taskQueueLength) { scheduleTaskProcessing(); } taskQueue[taskQueueLength++] = func; return nextHandle++; } function cancel(handle) { var index = handle - (nextHandle - taskQueueLength); if (index >= nextIndexToProcess && index < taskQueueLength) { taskQueue[index] = null; } } function resetForTesting() { var length = taskQueueLength - nextIndexToProcess; nextIndexToProcess = taskQueueLength = taskQueue.length = 0; return length; } // ../observable/dist/dependencyDetection.js var dependencyDetection_exports = {}; __export(dependencyDetection_exports, { begin: () => begin, end: () => end, getDependencies: () => getDependencies, getDependenciesCount: () => getDependenciesCount, ignore: () => ignore, ignoreDependencies: () => ignore, isInitial: () => isInitial, registerDependency: () => registerDependency }); // ../observable/dist/subscribableSymbol.js var SUBSCRIBABLE_SYM = Symbol("Knockout Subscribable"); function isSubscribable(instance) { return instance && instance[SUBSCRIBABLE_SYM] || false; } // ../observable/dist/dependencyDetection.js var outerFrames = []; var currentFrame; var lastId = 0; function getId() { return ++lastId; } function begin(options2) { outerFrames.push(currentFrame); currentFrame = options2; } function end() { currentFrame = outerFrames.pop(); } function registerDependency(subscribable2) { if (currentFrame) { if (!isSubscribable(subscribable2)) { throw new Error("Only subscribable things can act as dependencies"); } currentFrame.callback.call(currentFrame.callbackTarget, subscribable2, subscribable2._id || (subscribable2._id = getId())); } } function ignore(callback, callbackTarget, callbackArgs) { try { begin(); return callback.apply(callbackTarget, callbackArgs || []); } finally { end(); } } function getDependenciesCount() { if (currentFrame) { return currentFrame.computed.getDependenciesCount(); } } function getDependencies() { if (currentFrame) { return currentFrame.computed.getDependencies(); } } function isInitial() { if (currentFrame) { return currentFrame.isInitial; } } // ../observable/dist/defer.js function deferUpdates(target) { if (target._deferUpdates) { return; } target._deferUpdates = true; target.limit(function(callback) { let handle; let ignoreUpdates = false; return function() { if (!ignoreUpdates) { tasks_exports.cancel(handle); handle = tasks_exports.schedule(callback); try { ignoreUpdates = true; target.notifySubscribers(void 0, "dirty"); } finally { ignoreUpdates = false; } } }; }); } // ../observable/dist/Subscription.js var Subscription = class { constructor(target, observer, disposeCallback) { this._target = target; this._callback = observer.next; this._disposeCallback = disposeCallback; this._isDisposed = false; this._domNodeDisposalCallback = null; } dispose() { if (this._domNodeDisposalCallback) { removeDisposeCallback(this._node, this._domNodeDisposalCallback); } this._isDisposed = true; this._disposeCallback(); } disposeWhenNodeIsRemoved(node) { this._node = node; addDisposeCallback(node, this._domNodeDisposalCallback = this.dispose.bind(this)); } unsubscribe() { this.dispose(); } get closed() { return this._isDisposed; } }; // ../observable/dist/extenders.js var primitiveTypes = { "undefined": 1, "boolean": 1, "number": 1, "string": 1 }; function valuesArePrimitiveAndEqual(a, b) { var oldValueIsPrimitive = a === null || typeof a in primitiveTypes; return oldValueIsPrimitive ? a === b : false; } function applyExtenders(requestedExtenders) { var target = this; if (requestedExtenders) { objectForEach(requestedExtenders, function(key, value) { var extenderHandler = extenders[key]; if (typeof extenderHandler === "function") { target = extenderHandler(target, value) || target; } else { options_default.onError(new Error("Extender not found: " + key)); } }); } return target; } function notify(target, notifyWhen) { target.equalityComparer = notifyWhen == "always" ? null : valuesArePrimitiveAndEqual; } function deferred(target, option) { if (option !== true) { throw new Error("The 'deferred' extender only accepts the value 'true', because it is not supported to turn deferral off once enabled."); } deferUpdates(target); } function rateLimit(target, options2) { var timeout, method, limitFunction; if (typeof options2 === "number") { timeout = options2; } else { timeout = options2.timeout; method = options2.method; } target._deferUpdates = false; limitFunction = method === "notifyWhenChangesStop" ? debounce : throttle; target.limit(function(callback) { return limitFunction(callback, timeout); }); } var extenders = { notify, deferred, rateLimit }; // ../observable/dist/subscribable.js var LATEST_VALUE = Symbol("Knockout latest value"); if (!Symbol.observable) { Symbol.observable = Symbol.for("@tko/Symbol.observable"); } function subscribable() { Object.setPrototypeOf(this, ko_subscribable_fn); ko_subscribable_fn.init(this); } var defaultEvent = "change"; var ko_subscribable_fn = { [SUBSCRIBABLE_SYM]: true, [Symbol.observable]() { return this; }, init(instance) { instance._subscriptions = { change: [] }; instance._versionNumber = 1; }, subscribe(callback, callbackTarget, event) { const isTC39Callback = typeof callback === "object" && callback.next; event = event || defaultEvent; const observer = isTC39Callback ? callback : { next: callbackTarget ? callback.bind(callbackTarget) : callback }; const subscriptionInstance = new Subscription(this, observer, () => { arrayRemoveItem(this._subscriptions[event], subscriptionInstance); if (this.afterSubscriptionRemove) { this.afterSubscriptionRemove(event); } }); if (this.beforeSubscriptionAdd) { this.beforeSubscriptionAdd(event); } if (!this._subscriptions[event]) { this._subscriptions[event] = []; } this._subscriptions[event].push(subscriptionInstance); if (isTC39Callback && LATEST_VALUE in this) { observer.next(this[LATEST_VALUE]); } return subscriptionInstance; }, notifySubscribers(valueToNotify, event) { event = event || defaultEvent; if (event === defaultEvent) { this.updateVersion(); } if (this.hasSubscriptionsForEvent(event)) { const subs = event === defaultEvent && this._changeSubscriptions || [...this._subscriptions[event]]; try { begin(); for (let i = 0, subscriptionInstance; subscriptionInstance = subs[i]; ++i) { if (!subscriptionInstance._isDisposed) { subscriptionInstance._callback(valueToNotify); } } } finally { end(); } } }, getVersion() { return this._versionNumber; }, hasChanged(versionToCheck) { return this.getVersion() !== versionToCheck; }, updateVersion() { ++this._versionNumber; }, hasSubscriptionsForEvent(event) { return this._subscriptions[event] && this._subscriptions[event].length; }, getSubscriptionsCount(event) { if (event) { return this._subscriptions[event] && this._subscriptions[event].length || 0; } else { var total = 0; objectForEach(this._subscriptions, function(eventName, subscriptions) { if (eventName !== "dirty") { total += subscriptions.length; } }); return total; } }, isDifferent(oldValue, newValue) { return !this.equalityComparer || !this.equalityComparer(oldValue, newValue); }, once(cb) { const subs = this.subscribe((nv) => { subs.dispose(); cb(nv); }); }, when(test, returnValue) { const current = this.peek(); const givenRv = arguments.length > 1; const testFn = typeof test === "function" ? test : (v) => v === test; if (testFn(current)) { return options_default.Promise.resolve(givenRv ? returnValue : current); } return new options_default.Promise((resolve, reject) => { const subs = this.subscribe((newValue) => { if (testFn(newValue)) { subs.dispose(); resolve(givenRv ? returnValue : newValue); } }); }); }, yet(test, ...args) { const testFn = typeof test === "function" ? test : (v) => v === test; const negated = (v) => !testFn(v); return this.when(negated, ...args); }, next() { return new Promise((resolve) => this.once(resolve)); }, toString() { return "[object Object]"; }, extend: applyExtenders }; Object.setPrototypeOf(ko_subscribable_fn, Function.prototype); subscribable.fn = ko_subscribable_fn; // ../observable/dist/observable.js function observable(initialValue) { function Observable() { if (arguments.length > 0) { if (Observable.isDifferent(Observable[LATEST_VALUE], arguments[0])) { Observable.valueWillMutate(); Observable[LATEST_VALUE] = arguments[0]; Observable.valueHasMutated(); } return this; } else { registerDependency(Observable); return Observable[LATEST_VALUE]; } } overwriteLengthPropertyIfSupported(Observable, { value: void 0 }); Observable[LATEST_VALUE] = initialValue; subscribable.fn.init(Observable); Object.setPrototypeOf(Observable, observable.fn); if (options_default.deferUpdates) { deferUpdates(Observable); } return Observable; } observable.fn = { equalityComparer: valuesArePrimitiveAndEqual, peek() { return this[LATEST_VALUE]; }, valueHasMutated() { this.notifySubscribers(this[LATEST_VALUE], "spectate"); this.notifySubscribers(this[LATEST_VALUE]); }, valueWillMutate() { this.notifySubscribers(this[LATEST_VALUE], "beforeChange"); }, modify(fn, peek22 = true) { return this(fn(peek22 ? this.peek() : this())); }, isWriteable: true }; function limitNotifySubscribers(value, event) { if (!event || event === defaultEvent) { this._limitChange(value); } else if (event === "beforeChange") { this._limitBeforeChange(value); } else { this._origNotifySubscribers(value, event); } } subscribable.fn.limit = function limit(limitFunction) { var self = this; var selfIsObservable = isObservable(self); var beforeChange = "beforeChange"; var ignoreBeforeChange, notifyNextChange, previousValue, pendingValue, didUpdate; if (!self._origNotifySubscribers) { self._origNotifySubscribers = self.notifySubscribers; self.notifySubscribers = limitNotifySubscribers; } var finish = limitFunction(function() { self._notificationIsPending = false; if (selfIsObservable && pendingValue === self) { pendingValue = self._evalIfChanged ? self._evalIfChanged() : self(); } const shouldNotify = notifyNextChange || didUpdate && self.isDifferent(previousValue, pendingValue); self._notifyNextChange = didUpdate = ignoreBeforeChange = false; if (shouldNotify) { self._origNotifySubscribers(previousValue = pendingValue); } }); Object.assign(self, { _limitChange(value, isDirty) { if (!isDirty || !self._notificationIsPending) { didUpdate = !isDirty; } self._changeSubscriptions = [...self._subscriptions[defaultEvent]]; self._notificationIsPending = ignoreBeforeChange = true; pendingValue = value; finish(); }, _limitBeforeChange(value) { if (!ignoreBeforeChange) { previousValue = value; self._origNotifySubscribers(value, beforeChange); } }, _notifyNextChangeIfValueIsDifferent() { if (self.isDifferent(previousValue, self.peek(true))) { notifyNextChange = true; } }, _recordUpdate() { didUpdate = true; } }); }; Object.setPrototypeOf(observable.fn, subscribable.fn); var protoProperty = observable.protoProperty = options_default.protoProperty; observable.fn[protoProperty] = observable; observable.observablePrototypes = /* @__PURE__ */ new Set([observable]); function isObservable(instance) { const proto = typeof instance === "function" && instance[protoProperty]; if (proto && !observable.observablePrototypes.has(proto)) { throw Error("Invalid object that looks like an observable; possibly from another Knockout instance"); } return !!proto; } function unwrap(value) { return isObservable(value) ? value() : value; } // ../observable/dist/observableArray.changeTracking.js var arrayChangeEventName = "arrayChange"; function trackArrayChanges(target, options2) { target.compareArrayOptions = {}; if (options2 && typeof options2 === "object") { extend(target.compareArrayOptions, options2); } target.compareArrayOptions.sparse = true; if (target.cacheDiffForKnownOperation) { return; } let trackingChanges = false; let cachedDiff = null; let arrayChangeSubscription; let pendingNotifications = 0; let underlyingNotifySubscribersFunction; let underlyingBeforeSubscriptionAddFunction = target.beforeSubscriptionAdd; let underlyingAfterSubscriptionRemoveFunction = target.afterSubscriptionRemove; target.beforeSubscriptionAdd = function(event) { if (underlyingBeforeSubscriptionAddFunction) { underlyingBeforeSubscriptionAddFunction.call(target, event); } if (event === arrayChangeEventName) { trackChanges(); } }; target.afterSubscriptionRemove = function(event) { if (underlyingAfterSubscriptionRemoveFunction) { underlyingAfterSubscriptionRemoveFunction.call(target, event); } if (event === arrayChangeEventName && !target.hasSubscriptionsForEvent(arrayChangeEventName)) { if (underlyingNotifySubscribersFunction) { target.notifySubscribers = underlyingNotifySubscribersFunction; underlyingNotifySubscribersFunction = void 0; } if (arrayChangeSubscription) { arrayChangeSubscription.dispose(); } arrayChangeSubscription = null; trackingChanges = false; } }; function trackChanges() { if (trackingChanges) { return; } trackingChanges = true; underlyingNotifySubscribersFunction = target["notifySubscribers"]; target.notifySubscribers = function(valueToNotify, event) { if (!event || event === defaultEvent) { ++pendingNotifications; } return underlyingNotifySubscribersFunction.apply(this, arguments); }; var previousContents = [].concat(target.peek() === void 0 ? [] : target.peek()); cachedDiff = null; arrayChangeSubscription = target.subscribe(function(currentContents) { let changes; currentContents = [].concat(currentContents || []); if (target.hasSubscriptionsForEvent(arrayChangeEventName)) { changes = getChanges(previousContents, currentContents); } previousContents = currentContents; cachedDiff = null; pendingNotifications = 0; if (changes && changes.length) { target.notifySubscribers(changes, arrayChangeEventName); } }); } function getChanges(previousContents, currentContents) { if (!cachedDiff || pendingNotifications > 1) { cachedDiff = trackArrayChanges.compareArrays(previousContents, currentContents, target.compareArrayOptions); } return cachedDiff; } target.cacheDiffForKnownOperation = function(rawArray, operationName, args) { if (!trackingChanges || pendingNotifications) { return; } var diff = [], arrayLength = rawArray.length, argsLength = args.length, offset = 0; function pushDiff(status, value, index) { return diff[diff.length] = { "status": status, "value": value, "index": index }; } switch (operationName) { case "push": offset = arrayLength; case "unshift": for (let index = 0; index < argsLength; index++) { pushDiff("added", args[index], offset + index); } break; case "pop": offset = arrayLength - 1; case "shift": if (arrayLength) { pushDiff("deleted", rawArray[offset], offset); } break; case "splice": var startIndex = Math.min(Math.max(0, args[0] < 0 ? arrayLength + args[0] : args[0]), arrayLength), endDeleteIndex = argsLength === 1 ? arrayLength : Math.min(startIndex + (args[1] || 0), arrayLength), endAddIndex = startIndex + argsLength - 2, endIndex = Math.max(endDeleteIndex, endAddIndex), additions = [], deletions = []; for (let index = startIndex, argsIndex = 2; index < endIndex; ++index, ++argsIndex) { if (index < endDeleteIndex) { deletions.push(pushDiff("deleted", rawArray[index], index)); } if (index < endAddIndex) { additions.push(pushDiff("added", args[argsIndex], index)); } } findMovesInArrayComparison(deletions, additions); break; default: return; } cachedDiff = diff; }; } trackArrayChanges.compareArrays = compareArrays; extenders.trackArrayChanges = trackArrayChanges; // ../observable/dist/observableArray.js function observableArray(initialValues) { initialValues = initialValues || []; if (typeof initialValues !== "object" || !("length" in initialValues)) { throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined."); } var result = observable(initialValues); Object.setPrototypeOf(result, observableArray.fn); trackArrayChanges(result); overwriteLengthPropertyIfSupported(result, { get: () => result().length }); return result; } observableArray.fn = { remove(valueOrPredicate) { var underlyingArray = this.peek(); var removedValues = []; var predicate = typeof valueOrPredicate === "function" && !isObservable(valueOrPredicate) ? valueOrPredicate : function(value2) { return value2 === valueOrPredicate; }; for (var i = 0; i < underlyingArray.length; i++) { var value = underlyingArray[i]; if (predicate(value)) { if (removedValues.length === 0) { this.valueWillMutate(); } if (underlyingArray[i] !== value) { throw Error("Array modified during remove; cannot remove item"); } removedValues.push(value); underlyingArray.splice(i, 1); i--; } } if (removedValues.length) { this.valueHasMutated(); } return removedValues; }, removeAll(arrayOfValues) { if (arrayOfValues === void 0) { var underlyingArray = this.peek(); var allValues = underlyingArray.slice(0); this.valueWillMutate(); underlyingArray.splice(0, underlyingArray.length); this.valueHasMutated(); return allValues; } if (!arrayOfValues) { return []; } return this["remove"](function(value) { return arrayIndexOf(arrayOfValues, value) >= 0; }); }, destroy(valueOrPredicate) { var underlyingArray = this.peek(); var predicate = typeof valueOrPredicate === "function" && !isObservable(valueOrPredicate) ? valueOrPredicate : function(value2) { return value2 === valueOrPredicate; }; this.valueWillMutate(); for (var i = underlyingArray.length - 1; i >= 0; i--) { var value = underlyingArray[i]; if (predicate(value)) { value["_destroy"] = true; } } this.valueHasMutated(); }, destroyAll(arrayOfValues) { if (arrayOfValues === void 0) { return this.destroy(function() { return true; }); } if (!arrayOfValues) { return []; } return this.destroy(function(value) { return arrayIndexOf(arrayOfValues, value) >= 0; }); }, indexOf(item) { return arrayIndexOf(this(), item); }, replace(oldItem, newItem) { var index = this.indexOf(oldItem); if (index >= 0) { this.valueWillMutate(); this.peek()[index] = newItem; this.valueHasMutated(); } }, sorted(compareFn) { return [...this()].sort(compareFn); }, reversed() { return [...this()].reverse(); }, [Symbol.iterator]: function* () { yield* this(); } }; Object.setPrototypeOf(observableArray.fn, observable.fn); arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function(methodName) { observableArray.fn[methodName] = function() { var underlyingArray = this.peek(); this.valueWillMutate(); this.cacheDiffForKnownOperation(underlyingArray, methodName, arguments); var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments); this.valueHasMutated(); return methodCallResult === underlyingArray ? this : methodCallResult; }; }); arrayForEach(["slice"], function(methodName) { observableArray.fn[methodName] = function() { var underlyingArray = this(); return underlyingArray[methodName].apply(underlyingArray, arguments); }; }); observableArray.trackArrayChanges = trackArrayChanges; // src/computed.ts var computedState = createSymbolOrString("_state"); var DISPOSED_STATE = { dependencyTracking: null, dependenciesCount: 0, isDisposed: true, isStale: false, isDirty: false, isSleeping: false, disposeWhenNodeIsRemoved: null, readFunction: null, _options: null }; function computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget, options2) { if (typeof evaluatorFunctionOrOptions === "object") { options2 = evaluatorFunctionOrOptions; } else { options2 = options2 || {}; if (evaluatorFunctionOrOptions) { options2.read = evaluatorFunctionOrOptions; } } if (typeof options2.read !== "function") { throw Error("Pass a function that returns the value of the computed"); } var writeFunction = options2.write; var state = { latestValue: void 0, isStale: true, isDirty: true, isBeingEvaluated: false, suppressDisposalUntilDisposeWhenReturnsFalse: false, isDisposed: false, pure: false, isSleeping: false, readFunction: options2.read, evaluatorFunctionTarget: evaluatorFunctionTarget || options2.owner, disposeWhenNodeIsRemoved: options2.disposeWhenNodeIsRemoved || options2.disposeWhenNodeIsRemoved || null, disposeWhen: options2.disposeWhen || options2.disposeWhen, domNodeDisposalCallback: null, dependencyTracking: {}, dependenciesCount: 0, evaluationTimeoutInstance: null }; function computedObservable() { if (arguments.length > 0) { if (typeof writeFunction === "function") { writeFunction.apply(state.evaluatorFunctionTarget, arguments); } else { throw new Error("Cannot write a value to a computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters."); } return this; } else { if (!state.isDisposed) { dependencyDetection_exports.registerDependency(computedObservable); } if (state.isDirty || state.isSleeping && computedObservable.haveDependenciesChanged()) { computedObservable.evaluateImmediate(); } return state.latestValue; } } computedObservable[computedState] = state; computedObservable.isWriteable = typeof writeFunction === "function"; subscribable.fn.init(computedObservable); Object.setPrototypeOf(computedObservable, computed.fn); if (options2.pure) { state.pure = true; state.isSleeping = true; extend(computedObservable, pureComputedOverrides); } else if (options2.deferEvaluation) { extend(computedObservable, deferEvaluationOverrides); } if (options_default.deferUpdates) { extenders.deferred(computedObservable, true); } if (options_default.debug) { computedObservable._options = options2; } if (state.disposeWhenNodeIsRemoved) { state.suppressDisposalUntilDisposeWhenReturnsFalse = true; if (!state.disposeWhenNodeIsRemoved.nodeType) { state.disposeWhenNodeIsRemoved = null; } } if (!state.isSleeping && !options2.deferEvaluation) { computedObservable.evaluateImmediate(); } if (state.disposeWhenNodeIsRemoved && computedObservable.isActive()) { addDisposeCallback(state.disposeWhenNodeIsRemoved, state.domNodeDisposalCallback = function() { computedObservable.dispose(); }); } return computedObservable; } function computedDisposeDependencyCallback(id, entryToDispose) { if (entryToDispose !== null && entryToDispose.dispose) { entryToDispose.dispose(); } } function computedBeginDependencyDetectionCallback(subscribable2, id) { var computedObservable = this.computedObservable, state = computedObservable[computedState]; if (!state.isDisposed) { if (this.disposalCount && this.disposalCandidates[id]) { computedObservable.addDependencyTracking(id, subscribable2, this.disposalCandidates[id]); this.disposalCandidates[id] = null; --this.disposalCount; } else if (!state.dependencyTracking[id]) { computedObservable.addDependencyTracking(id, subscribable2, state.isSleeping ? { _target: subscribable2 } : computedObservable.subscribeToDependency(subscribable2)); } if (subscribable2._notificationIsPending) { subscribable2._notifyNextChangeIfValueIsDifferent(); } } } computed.fn = { equalityComparer: valuesArePrimitiveAndEqual, getDependenciesCount() { return this[computedState].dependenciesCount; }, getDependencies() { const dependencyTracking = this[computedState].dependencyTracking; const dependentObservables = []; objectForEach(dependencyTracking, function(id, dependency) { dependentObservables[dependency._order] = dependency._target; }); return dependentObservables; }, addDependencyTracking(id, target, trackingObj) { if (this[computedState].pure && target === this) { throw Error("A 'pure' computed must not be called recursively"); } this[computedState].dependencyTracking[id] = trackingObj; trackingObj._order = this[computedState].dependenciesCount++; trackingObj._version = target.getVersion(); }, haveDependenciesChanged() { var id, dependency, dependencyTracking = this[computedState].dependencyTracking; for (id in dependencyTracking) { if (hasOwnProperty(dependencyTracking, id)) { dependency = dependencyTracking[id]; if (this._evalDelayed && dependency._target._notificationIsPending || dependency._target.hasChanged(dependency._version)) { return true; } } } }, markDirty() { if (this._evalDelayed && !this[computedState].isBeingEvaluated) { this._evalDelayed(false); } }, isActive() { const state = this[computedState]; return state.isDirty || state.dependenciesCount > 0; }, respondToChange() { if (!this._notificationIsPending) { this.evaluatePossiblyAsync(); } else if (this[computedState].isDirty) { this[computedState].isStale = true; } }, subscribeToDependency(target) { if (target._deferUpdates) { var dirtySub = target.subscribe(this.markDirty, this, "dirty"), changeSub = target.subscribe(this.respondToChange, this); return { _target: target, dispose() { dirtySub.dispose(); changeSub.dispose(); } }; } else { return target.subscribe(this.evaluatePossiblyAsync, this); } }, evaluatePossiblyAsync() { var computedObservable = this, throttleEvaluationTimeout = computedObservable.throttleEvaluation; if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) { clearTimeout(this[computedState].evaluationTimeoutInstance); this[computedState].evaluationTimeoutInstance = safeSetTimeout(function() { computedObservable.evaluateImmediate(true); }, throttleEvaluationTimeout); } else if (computedObservable._evalDelayed) { computedObservable._evalDelayed(true); } else { computedObservable.evaluateImmediate(true); } }, evaluateImmediate(notifyChange) { var computedObservable = this, state = computedObservable[computedState], disposeWhen = state.disposeWhen, changed = false; if (state.isBeingEvaluated) { return; } if (state.isDisposed) { return; } if (state.disposeWhenNodeIsRemoved && !domNodeIsAttachedToDocument(state.disposeWhenNodeIsRemoved) || disposeWhen && disposeWhen()) { if (!state.suppressDisposalUntilDisposeWhenReturnsFalse) { computedObservable.dispose(); return; } } else { state.suppressDisposalUntilDisposeWhenReturnsFalse = false; } state.isBeingEvaluated = true; try { changed = this.evaluateImmediate_CallReadWithDependencyDetection(notifyChange); } finally { state.isBeingEvaluated = false; } return changed; }, evaluateImmediate_CallReadWithDependencyDetection(notifyChange) { var computedObservable = this, state = computedObservable[computedState], changed = false; var isInitial2 = state.pure ? void 0 : !state.dependenciesCount, dependencyDetectionContext = { computedObservable, disposalCandidates: state.dependencyTracking, disposalCount: state.dependenciesCount }; dependencyDetection_exports.begin({ callbackTarget: dependencyDetectionContext, callback: computedBeginDependencyDetectionCallback, computed: computedObservable, isInitial: isInitial2 }); state.dependencyTracking = {}; state.dependenciesCount = 0; var newValue = this.evaluateImmediate_CallReadThenEndDependencyDetection(state, dependencyDetectionContext); if (!state.dependenciesCount) { computedObservable.dispose(); changed = true; } else { changed = computedObservable.isDifferent(state.latestValue, newValue); } if (changed) { if (!state.isSleeping) { computedObservable.notifySubscribers(state.latestValue, "beforeChange"); } else { computedObservable.updateVersion(); } state.latestValue = newValue; if (options_default.debug) { computedObservable._latestValue = newValue; } computedObservable.notifySubscribers(state.latestValue, "spectate"); if (!state.isSleeping && notifyChange) { computedObservable.notifySubscribers(state.latestValue); } if (computedObservable._recordUpdate) { computedObservable._recordUpdate(); } } if (isInitial2) { computedObservable.notifySubscribers(state.latestValue, "awake"); } return changed; }, evaluateImmediate_CallReadThenEndDependencyDetection(state, dependencyDetectionContext) { try { var readFunction = state.readFunction; return state.evaluatorFunctionTarget ? readFunction.call(state.evaluatorFunctionTarget) : readFunction(); } finally { dependencyDetection_exports.end(); if (dependencyDetectionContext.disposalCount && !state.isSleeping) { objectForEach(dependencyDetectionContext.disposalCandidates, computedDisposeDependencyCallback); } state.isStale = state.isDirty = false; } }, peek(forceEvaluate) { const state = this[computedState]; if (state.isDirty && (forceEvaluate || !state.dependenciesCount) || state.isSleeping && this.haveDependenciesChanged()) { this.evaluateImmediate(); } return state.latestValue; }, get [LATEST_VALUE]() { return this.peek(); }, limit(limitFunction) { const state = this[computedState]; subscribable.fn.limit.call(this, limitFunction); Object.assign(this, { _evalIfChanged() { if (!this[computedState].isSleeping) { if (this[computedState].isStale) { this.evaluateImmediate(); } else { this[computedState].isDirty = false; } } return state.latestValue; }, _evalDelayed(isChange) { this._limitBeforeChange(state.latestValue); state.isDirty = true; if (isChange) { state.isStale = true; } this._limitChange(this, !isChange); } }); }, dispose() { var state = this[computedState]; if (!state.isSleeping && state.dependencyTracking) { objectForEach(state.dependencyTracking, function(id, dependency) { if (dependency.dispose) { dependency.dispose(); } }); } if (st