@tko/computed
Version:
TKO Computed Observables
1,535 lines (1,506 loc) • 56.8 kB
JavaScript
// @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