Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@tko/binding.foreach

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tko/binding.foreach - npm Package Compare versions

Comparing version
4.0.0-beta1.3
to
4.0.0
+85
-74
dist/foreach.js

@@ -1,2 +0,3 @@

// @tko/binding.foreach 🥊 4.0.0-beta1.3 ESM
// @tko/binding.foreach 🥊 4.0.0 ESM
"use strict";
import {

@@ -11,12 +12,4 @@ arrayForEach,

} from "@tko/utils";
import {
isObservable,
unwrap,
observable
} from "@tko/observable";
import {
contextFor,
applyBindingsToDescendants,
AsyncBindingHandler
} from "@tko/bind";
import { isObservable, unwrap, observable } from "@tko/observable";
import { contextFor, applyBindingsToDescendants, AsyncBindingHandler } from "@tko/bind";
const MAX_LIST_SIZE = 9007199254740991;

@@ -28,4 +21,4 @@ function isPlainObject(o) {

function makeTemplateNode(sourceNode) {
var container = document.createElement("div");
var parentNode;
const container = document.createElement("div");
let parentNode;
if (sourceNode.content) {

@@ -47,7 +40,3 @@ parentNode = sourceNode.content;

function valueToChangeAddItem(value, index) {
return {
status: "added",
value,
index
};
return { status: "added", value, index };
}

@@ -67,15 +56,15 @@ const PENDING_DELETE_INDEX_SYM = createSymbolOrString("_ko_ffe_pending_delete_index");

this.$indexHasBeenRequested = false;
this.templateNode = makeTemplateNode(settings.templateNode || (settings.name ? document.getElementById(settings.name).cloneNode(true) : this.$element));
this.templateNode = makeTemplateNode(
settings.templateNode || (settings.name ? document.getElementById(settings.name)?.cloneNode(true) : this.$element)
);
["afterAdd", "beforeRemove", "afterQueueFlush", "beforeQueueFlush"].forEach((p) => {
this[p] = settings[p] || this.allBindings.get(p);
});
this.changeQueue = [];
this.firstLastNodesList = [];
this.indexesToDelete = [];
this.changeQueue = new Array();
this.firstLastNodesList = new Array();
this.indexesToDelete = new Array();
this.rendering_queued = false;
this.pendingDeletes = [];
this.pendingDeletes = new Array();
this.isNotEmpty = observable(Boolean(unwrap(this.data).length));
domData.set(this.$element, "conditional", {
elseChainSatisfied: this.isNotEmpty
});
domData.set(this.$element, "conditional", { elseChainSatisfied: this.isNotEmpty });
virtualElements.emptyNode(this.$element);

@@ -101,19 +90,12 @@ const primeData = unwrap(this.data);

}
// If the array changes we register the change.
onArrayChange(changeSet, isInitial) {
var changeMap = {
added: [],
deleted: []
};
for (var i = 0, len = changeSet.length; i < len; i++) {
const changeMap = { added: [], deleted: [] };
for (let i = 0, len = changeSet.length; i < len; i++) {
if (changeMap.added.length && changeSet[i].status === "added") {
var lastAdd = changeMap.added[changeMap.added.length - 1];
var lastIndex = lastAdd.isBatch ? lastAdd.index + lastAdd.values.length - 1 : lastAdd.index;
let lastAdd = changeMap.added[changeMap.added.length - 1];
const lastIndex = lastAdd.isBatch ? lastAdd.index + lastAdd.values.length - 1 : lastAdd.index;
if (lastIndex + 1 === changeSet[i].index) {
if (!lastAdd.isBatch) {
lastAdd = {
isBatch: true,
status: "added",
index: lastAdd.index,
values: [lastAdd.value]
};
lastAdd = { isBatch: true, status: "added", index: lastAdd.index, values: [lastAdd.value] };
changeMap.added.splice(changeMap.added.length - 1, 1, lastAdd);

@@ -151,5 +133,6 @@ }

}
// Reflect all the changes in the queue in the DOM, then wipe the queue.
processQueue() {
var isEmpty = !unwrap(this.data).length;
var lowestIndexChanged = MAX_LIST_SIZE;
const isEmpty = !unwrap(this.data).length;
let lowestIndexChanged = MAX_LIST_SIZE;
this.startQueueFlush();

@@ -168,3 +151,3 @@ arrayForEach(this.changeQueue, (changeItem) => {

this.endQueueFlush();
this.changeQueue = [];
this.changeQueue = new Array();
if (isEmpty !== !this.isNotEmpty()) {

@@ -174,2 +157,7 @@ this.isNotEmpty(!isEmpty);

}
/**
* Once the $index has been asked for once, start calculating it.
* Note that this significantly degrades performance, from O(1) to O(n)
* for arbitrary changes to the list.
*/
_first$indexRequest(ctx$indexRequestedFrom) {

@@ -198,2 +186,12 @@ this.$indexHasBeenRequested = true;

}
/**
* Return a function that generates the context for a given node.
*
* We generate a single function that reduces our inner-loop calculations,
* which has a good chance of being optimized by the browser.
*
* @param {string} as The name given to each item in the list
* @param {bool} index Whether to calculate indexes
* @return {function} A function(dataValue) that returns the context
*/
createContextGenerator(as) {

@@ -204,3 +202,3 @@ const $ctx = this.$context;

} else {
return (v) => $ctx.createChildContext(v, null, (ctx) => this._contextExtensions(ctx));
return (v) => $ctx.createChildContext(v, void 0, (ctx) => this._contextExtensions(ctx));
}

@@ -213,11 +211,12 @@ }

}
// Process a changeItem with {status: 'added', ...}
added(changeItem) {
var index = changeItem.index;
var valuesToAdd = changeItem.isBatch ? changeItem.values : [changeItem.value];
var referenceElement = this.getLastNodeBeforeIndex(index);
const index = changeItem.index;
const valuesToAdd = changeItem.isBatch ? changeItem.values : [changeItem.value];
const referenceElement = this.getLastNodeBeforeIndex(index);
const allChildNodes = [];
const asyncBindingResults = [];
var children;
for (var i = 0, len = valuesToAdd.length; i < len; ++i) {
var pendingDelete = this.getPendingDeleteFor(valuesToAdd[i]);
const asyncBindingResults = new Array();
let children;
for (let i = 0, len = valuesToAdd.length; i < len; ++i) {
const pendingDelete = this.getPendingDeleteFor(valuesToAdd[i]);
if (pendingDelete && pendingDelete.nodesets.length) {

@@ -227,3 +226,3 @@ children = pendingDelete.nodesets.pop();

} else {
var templateClone = this.templateNode.cloneNode(true);
const templateClone = this.templateNode.cloneNode(true);
children = virtualElements.childNodes(templateClone);

@@ -247,5 +246,5 @@ this.updateFirstLastNodesList(index + i, children);

getNodesForIndex(index) {
let result = [];
const result = new Array();
let ptr = this.firstLastNodesList[index].first;
let last = this.firstLastNodesList[index].last;
const last = this.firstLastNodesList[index].last;
result.push(ptr);

@@ -264,7 +263,11 @@ while (ptr && ptr !== last) {

}
/**
* Get the active (focused) node, if it's a child of the given node.
*/
activeChildElement(node) {
var active = document.activeElement;
const active = document.activeElement;
if (domNodeIsContainedBy(active, node)) {
return active;
}
return null;
}

@@ -276,3 +279,3 @@ insertAllAfter(nodeOrNodeArrayToInsert, insertAfterNode) {

let active = null;
let containerNode = this.$element;
const containerNode = this.$element;
if (nodeOrNodeArrayToInsert.nodeType === void 0 && nodeOrNodeArrayToInsert.length === void 0) {

@@ -298,3 +301,3 @@ throw new Error("Expected a single node or a node array");

active = active || this.activeChildElement(nodeOrNodeArrayToInsert[i]);
var child = nodeOrNodeArrayToInsert[i];
const child = nodeOrNodeArrayToInsert[i];
if (!child) {

@@ -311,20 +314,19 @@ break;

}
// checks if the deleted data item should be handled with delay for a possible reuse at additions
shouldDelayDeletion(data) {
return data && (typeof data === "object" || typeof data === "function");
}
// gets the pending deletion info for this data item
getPendingDeleteFor(data) {
var index = data && data[PENDING_DELETE_INDEX_SYM];
if (index === void 0)
return null;
const index = data && data[PENDING_DELETE_INDEX_SYM];
if (index === void 0) return null;
return this.pendingDeletes[index];
}
// tries to find the existing pending delete info for this data item, and if it can't, it registeres one
getOrCreatePendingDeleteFor(data) {
var pd = this.getPendingDeleteFor(data);
let pd = this.getPendingDeleteFor(data);
if (pd) {
return pd;
}
pd = {
data,
nodesets: []
};
pd = { data, nodesets: [] };
data[PENDING_DELETE_INDEX_SYM] = this.pendingDeletes.length;

@@ -334,5 +336,6 @@ this.pendingDeletes.push(pd);

}
// Process a changeItem with {status: 'deleted', ...}
deleted(changeItem) {
if (this.shouldDelayDeletion(changeItem.value)) {
let pd = this.getOrCreatePendingDeleteFor(changeItem.value);
const pd = this.getOrCreatePendingDeleteFor(changeItem.value);
pd.nodesets.push(this.getNodesForIndex(changeItem.index));

@@ -344,2 +347,3 @@ } else {

}
// removes a set of nodes from the DOM
removeNodes(nodes) {

@@ -350,4 +354,4 @@ if (!nodes.length) {

function removeFn() {
var parent = nodes[0].parentNode;
for (var i = nodes.length - 1; i >= 0; --i) {
const parent = nodes[0].parentNode;
for (let i = nodes.length - 1; i >= 0; --i) {
cleanNode(nodes[i]);

@@ -358,6 +362,3 @@ parent.removeChild(nodes[i]);

if (this.beforeRemove) {
var beforeRemoveReturn = this.beforeRemove({
nodesToRemove: nodes,
foreachInstance: this
}) || {};
const beforeRemoveReturn = this.beforeRemove({ nodesToRemove: nodes, foreachInstance: this }) || {};
if (typeof beforeRemoveReturn.then === "function") {

@@ -370,5 +371,8 @@ beforeRemoveReturn.then(removeFn, options.onError);

}
// flushes the pending delete info store
// this should be called after queue processing has finished, so that data items and remaining (not reused) nodesets get cleaned up
// we also call it on dispose not to leave any mess
flushPendingDeletes() {
for (let i = 0, len = this.pendingDeletes.length; i !== len; ++i) {
var pd = this.pendingDeletes[i];
const pd = this.pendingDeletes[i];
while (pd.nodesets.length) {

@@ -381,4 +385,6 @@ this.removeNodes(pd.nodesets.pop());

}
this.pendingDeletes = [];
this.pendingDeletes = new Array();
}
// We batch our deletion of item indexes in our parallel array.
// See brianmhunt/knockout-fast-foreach#6/#8
clearDeletedIndexes() {

@@ -388,3 +394,3 @@ for (let i = this.indexesToDelete.length - 1; i >= 0; --i) {

}
this.indexesToDelete = [];
this.indexesToDelete = new Array();
}

@@ -410,2 +416,6 @@ updateIndexes(fromIndex) {

}
/**
* Set whether the binding is always synchronous.
* Useful during testing.
*/
static setSync(toggle) {

@@ -429,2 +439,3 @@ const w = options.global;

}
/* TODO: Remove; for legacy/testing */
static get ForEach() {

@@ -431,0 +442,0 @@ return this;

{
"version": 3,
"sources": ["../src/foreach.ts"],
"sourcesContent": ["// index.js\n// --------\n// Fast For Each\n//\n// Employing sound techniques to make a faster Knockout foreach binding.\n// --------\n\nimport {\n arrayForEach, cleanNode, options, virtualElements,\n createSymbolOrString, domData, domNodeIsContainedBy\n} from '@tko/utils'\n\nimport {\n isObservable, unwrap, observable\n} from '@tko/observable'\n\nimport {\n contextFor, applyBindingsToDescendants, AsyncBindingHandler\n} from '@tko/bind'\n\n// Utilities\nconst MAX_LIST_SIZE = 9007199254740991\n\n// from https://github.com/jonschlinkert/is-plain-object\nfunction isPlainObject (o) {\n return !!o && typeof o === 'object' && o.constructor === Object\n}\n\nconst supportsDocumentFragment = options.document && typeof options.document.createDocumentFragment === 'function'\n\n// Get a copy of the (possibly virtual) child nodes of the given element,\n// put them into a container, then empty the given node.\nfunction makeTemplateNode (sourceNode) {\n var container = document.createElement('div')\n var parentNode\n if (sourceNode.content) {\n // For e.g. <template> tags\n parentNode = sourceNode.content\n } else if (sourceNode.tagName === 'SCRIPT') {\n parentNode = document.createElement('div')\n parentNode.innerHTML = sourceNode.text\n } else {\n // Anything else e.g. <div>\n parentNode = sourceNode\n }\n arrayForEach(virtualElements.childNodes(parentNode), function (child) {\n // FIXME - This cloneNode could be expensive; we may prefer to iterate over the\n // parentNode children in reverse (so as not to foul the indexes as childNodes are\n // removed from parentNode when inserted into the container)\n if (child) {\n container.insertBefore(child.cloneNode(true), null)\n }\n })\n return container\n}\n\n// Mimic a KO change item 'add'\nfunction valueToChangeAddItem (value, index) {\n return {\n status: 'added',\n value: value,\n index: index\n }\n}\n\n// store a symbol for caching the pending delete info index in the data item objects\nconst PENDING_DELETE_INDEX_SYM = createSymbolOrString('_ko_ffe_pending_delete_index')\n\n\nexport class ForEachBinding extends AsyncBindingHandler {\n // NOTE: valid valueAccessors include:\n // []\n // observable([])\n // observableArray([])\n // computed\n // {data: array, name: string, as: string}\n\n constructor (params) {\n super(params)\n const settings = {}\n if (isPlainObject(this.value)) {\n Object.assign(settings, this.value)\n }\n\n this.as = settings.as || this.allBindings.get('as')\n\n this.data = settings.data || (unwrap(this.$context.$rawData) === this.value ? this.$context.$rawData : this.value)\n\n this.container = virtualElements.isStartComment(this.$element)\n ? this.$element.parentNode : this.$element\n this.generateContext = this.createContextGenerator(this.as)\n this.$indexHasBeenRequested = false\n\n this.templateNode = makeTemplateNode(\n settings.templateNode || (settings.name\n ? document.getElementById(settings.name).cloneNode(true)\n : this.$element)\n )\n\n ;['afterAdd', 'beforeRemove', 'afterQueueFlush', 'beforeQueueFlush']\n .forEach(p => { this[p] = settings[p] || this.allBindings.get(p) })\n\n this.changeQueue = []\n this.firstLastNodesList = []\n this.indexesToDelete = []\n this.rendering_queued = false\n this.pendingDeletes = []\n\n // Expose the conditional so that if the `foreach` data is empty, successive\n // 'else' bindings will appear.\n this.isNotEmpty = observable(Boolean(unwrap(this.data).length))\n domData.set(this.$element, 'conditional', {\n elseChainSatisfied: this.isNotEmpty\n })\n\n // Remove existing content.\n virtualElements.emptyNode(this.$element)\n\n // Prime content\n const primeData = unwrap(this.data)\n if (primeData && primeData.map) {\n this.onArrayChange(primeData.map(valueToChangeAddItem), true)\n } else {\n this.completeBinding()\n }\n\n // Watch for changes\n if (isObservable(this.data)) {\n if (!this.data.indexOf) {\n // Make sure the observable is trackable.\n this.data = this.data.extend({ trackArrayChanges: true })\n }\n this.changeSubs = this.data.subscribe(this.onArrayChange, this, 'arrayChange')\n }\n }\n\n dispose () {\n if (this.changeSubs) {\n this.changeSubs.dispose()\n }\n this.flushPendingDeletes()\n }\n\n // If the array changes we register the change.\n onArrayChange (changeSet, isInitial) {\n var changeMap = {\n added: [],\n deleted: []\n }\n\n // knockout array change notification index handling:\n // - sends the original array indexes for deletes\n // - sends the new array indexes for adds\n // - sorts them all by index in ascending order\n // because of this, when checking for possible batch additions, any delete can be between to adds with neighboring indexes, so only additions should be checked\n for (var i = 0, len = changeSet.length; i < len; i++) {\n if (changeMap.added.length && changeSet[i].status === 'added') {\n var lastAdd = changeMap.added[changeMap.added.length - 1]\n var lastIndex = lastAdd.isBatch ? lastAdd.index + lastAdd.values.length - 1 : lastAdd.index\n if (lastIndex + 1 === changeSet[i].index) {\n if (!lastAdd.isBatch) {\n // transform the last addition into a batch addition object\n lastAdd = {\n isBatch: true,\n status: 'added',\n index: lastAdd.index,\n values: [lastAdd.value]\n }\n changeMap.added.splice(changeMap.added.length - 1, 1, lastAdd)\n }\n lastAdd.values.push(changeSet[i].value)\n continue\n }\n }\n\n changeMap[changeSet[i].status].push(changeSet[i])\n }\n\n if (changeMap.deleted.length > 0) {\n this.changeQueue.push.apply(this.changeQueue, changeMap.deleted)\n this.changeQueue.push({ status: 'clearDeletedIndexes' })\n }\n\n this.changeQueue.push.apply(this.changeQueue, changeMap.added)\n // Once a change is registered, the ticking count-down starts for the processQueue.\n if (this.changeQueue.length > 0 && !this.rendering_queued) {\n this.rendering_queued = true\n if (isInitial) {\n this.processQueue()\n } else {\n ForEachBinding.animateFrame.call(window, () => this.processQueue())\n }\n }\n }\n\n startQueueFlush () {\n // Callback so folks can do things before the queue flush.\n if (typeof this.beforeQueueFlush === 'function') {\n this.beforeQueueFlush(this.changeQueue)\n }\n }\n\n endQueueFlush () {\n // Callback so folks can do things.\n if (typeof this.afterQueueFlush === 'function') {\n this.afterQueueFlush(this.changeQueue)\n }\n }\n\n // Reflect all the changes in the queue in the DOM, then wipe the queue.\n processQueue () {\n var isEmpty = !unwrap(this.data).length\n var lowestIndexChanged = MAX_LIST_SIZE\n\n this.startQueueFlush()\n\n arrayForEach(this.changeQueue, (changeItem) => {\n if (typeof changeItem.index === 'number') {\n lowestIndexChanged = Math.min(lowestIndexChanged, changeItem.index)\n }\n this[changeItem.status](changeItem)\n })\n this.flushPendingDeletes()\n this.rendering_queued = false\n\n // Update our indexes.\n if (this.$indexHasBeenRequested) {\n this.updateIndexes(lowestIndexChanged)\n }\n\n this.endQueueFlush()\n this.changeQueue = []\n\n // Update the conditional exposed on the domData\n if (isEmpty !== !this.isNotEmpty()) {\n this.isNotEmpty(!isEmpty)\n }\n }\n\n /**\n * Once the $index has been asked for once, start calculating it.\n * Note that this significantly degrades performance, from O(1) to O(n)\n * for arbitrary changes to the list.\n */\n _first$indexRequest (ctx$indexRequestedFrom) {\n this.$indexHasBeenRequested = true\n for (let i = 0, len = this.firstLastNodesList.length; i < len; ++i) {\n const ctx = this.getContextStartingFrom(this.firstLastNodesList[i].first)\n // Overwrite the defineProperty.\n if (ctx) { ctx.$index = observable(i) }\n }\n return ctx$indexRequestedFrom.$index()\n }\n\n _contextExtensions ($ctx) {\n Object.assign($ctx, { $list: this.data })\n if (this.$indexHasBeenRequested) {\n $ctx.$index = $ctx.$index || observable()\n } else {\n Object.defineProperty($ctx, '$index', {\n value: () => this._first$indexRequest($ctx),\n configurable: true,\n writable: true\n })\n }\n return $ctx\n }\n\n /**\n * Return a function that generates the context for a given node.\n *\n * We generate a single function that reduces our inner-loop calculations,\n * which has a good chance of being optimized by the browser.\n *\n * @param {string} as The name given to each item in the list\n * @param {bool} index Whether to calculate indexes\n * @return {function} A function(dataValue) that returns the context\n */\n createContextGenerator (as) {\n const $ctx = this.$context\n if (as) {\n return v => this._contextExtensions($ctx.extend({ [as]: v }))\n } else {\n return v => $ctx.createChildContext(v, null, ctx => this._contextExtensions(ctx))\n }\n }\n\n updateFirstLastNodesList (index, children) {\n const first = children[0]\n const last = children[children.length - 1]\n this.firstLastNodesList.splice(index, 0, { first, last })\n }\n\n // Process a changeItem with {status: 'added', ...}\n added (changeItem) {\n var index = changeItem.index\n var valuesToAdd = changeItem.isBatch ? changeItem.values : [changeItem.value]\n var referenceElement = this.getLastNodeBeforeIndex(index)\n // gather all childnodes for a possible batch insertion\n const allChildNodes = []\n const asyncBindingResults = []\n var children\n\n for (var i = 0, len = valuesToAdd.length; i < len; ++i) {\n // we check if we have a pending delete with reusable nodesets for this data, and if yes, we reuse one nodeset\n var pendingDelete = this.getPendingDeleteFor(valuesToAdd[i])\n if (pendingDelete && pendingDelete.nodesets.length) {\n children = pendingDelete.nodesets.pop()\n this.updateFirstLastNodesList(index + i, children)\n } else {\n var templateClone = this.templateNode.cloneNode(true)\n children = virtualElements.childNodes(templateClone)\n this.updateFirstLastNodesList(index + i, children)\n\n // Apply bindings first, and then process child nodes,\n // because bindings can add childnodes.\n const bindingResult = applyBindingsToDescendants(\n this.generateContext(valuesToAdd[i]), templateClone\n )\n asyncBindingResults.push(bindingResult)\n }\n\n allChildNodes.push(...children)\n }\n\n if (typeof this.afterAdd === 'function') {\n this.afterAdd({\n nodeOrArrayInserted: this.insertAllAfter(allChildNodes, referenceElement),\n foreachInstance: this\n })\n } else {\n this.insertAllAfter(allChildNodes, referenceElement)\n }\n\n this.completeBinding(Promise.all(asyncBindingResults))\n }\n\n getNodesForIndex (index) {\n let result = []\n let ptr = this.firstLastNodesList[index].first\n let last = this.firstLastNodesList[index].last\n result.push(ptr)\n while (ptr && ptr !== last) {\n ptr = ptr.nextSibling\n result.push(ptr)\n }\n return result\n }\n\n getLastNodeBeforeIndex (index) {\n if (index < 1 || index - 1 >= this.firstLastNodesList.length) { return null }\n return this.firstLastNodesList[index - 1].last\n }\n\n /**\n * Get the active (focused) node, if it's a child of the given node.\n */\n activeChildElement (node) {\n var active = document.activeElement\n if (domNodeIsContainedBy(active, node)) {\n return active\n }\n }\n\n insertAllAfter (nodeOrNodeArrayToInsert, insertAfterNode) {\n let frag\n let len\n let i\n let active = null\n let containerNode = this.$element\n\n // Poor man's node and array check.\n if (nodeOrNodeArrayToInsert.nodeType === undefined && nodeOrNodeArrayToInsert.length === undefined) {\n throw new Error('Expected a single node or a node array')\n }\n if (nodeOrNodeArrayToInsert.nodeType !== undefined) {\n active = this.activeChildElement(nodeOrNodeArrayToInsert)\n virtualElements.insertAfter(containerNode, nodeOrNodeArrayToInsert, insertAfterNode)\n return [nodeOrNodeArrayToInsert]\n } else if (nodeOrNodeArrayToInsert.length === 1) {\n active = this.activeChildElement(nodeOrNodeArrayToInsert[0])\n virtualElements.insertAfter(containerNode, nodeOrNodeArrayToInsert[0], insertAfterNode)\n } else if (supportsDocumentFragment) {\n frag = document.createDocumentFragment()\n for (i = 0, len = nodeOrNodeArrayToInsert.length; i !== len; ++i) {\n active = active || this.activeChildElement(nodeOrNodeArrayToInsert[i])\n frag.appendChild(nodeOrNodeArrayToInsert[i])\n }\n virtualElements.insertAfter(containerNode, frag, insertAfterNode)\n } else {\n // Nodes are inserted in reverse order - pushed down immediately after\n // the last node for the previous item or as the first node of element.\n for (i = nodeOrNodeArrayToInsert.length - 1; i >= 0; --i) {\n active = active || this.activeChildElement(nodeOrNodeArrayToInsert[i])\n var child = nodeOrNodeArrayToInsert[i]\n if (!child) { break }\n virtualElements.insertAfter(containerNode, child, insertAfterNode)\n }\n }\n\n if (active) { active.focus() }\n\n return nodeOrNodeArrayToInsert\n }\n\n // checks if the deleted data item should be handled with delay for a possible reuse at additions\n shouldDelayDeletion (data) {\n return data && (typeof data === 'object' || typeof data === 'function')\n }\n\n // gets the pending deletion info for this data item\n getPendingDeleteFor (data) {\n var index = data && data[PENDING_DELETE_INDEX_SYM]\n if (index === undefined) return null\n return this.pendingDeletes[index]\n }\n\n // tries to find the existing pending delete info for this data item, and if it can't, it registeres one\n getOrCreatePendingDeleteFor (data) {\n var pd = this.getPendingDeleteFor(data)\n if (pd) {\n return pd\n }\n pd = {\n data: data,\n nodesets: []\n }\n data[PENDING_DELETE_INDEX_SYM] = this.pendingDeletes.length\n this.pendingDeletes.push(pd)\n return pd\n }\n\n // Process a changeItem with {status: 'deleted', ...}\n deleted (changeItem) {\n // if we should delay the deletion of this data, we add the nodeset to the pending delete info object\n if (this.shouldDelayDeletion(changeItem.value)) {\n let pd = this.getOrCreatePendingDeleteFor(changeItem.value)\n pd.nodesets.push(this.getNodesForIndex(changeItem.index))\n } else { // simple data, just remove the nodes\n this.removeNodes(this.getNodesForIndex(changeItem.index))\n }\n this.indexesToDelete.push(changeItem.index)\n }\n\n // removes a set of nodes from the DOM\n removeNodes (nodes) {\n if (!nodes.length) { return }\n\n function removeFn () {\n var parent = nodes[0].parentNode\n for (var i = nodes.length - 1; i >= 0; --i) {\n cleanNode(nodes[i])\n parent.removeChild(nodes[i])\n }\n }\n\n if (this.beforeRemove) {\n var beforeRemoveReturn = this.beforeRemove({\n nodesToRemove: nodes, foreachInstance: this\n }) || {}\n // If beforeRemove returns a `then`\u2013able e.g. a Promise, we remove\n // the nodes when that thenable completes. We pass any errors to\n // ko.onError.\n if (typeof beforeRemoveReturn.then === 'function') {\n beforeRemoveReturn.then(removeFn, options.onError)\n }\n } else {\n removeFn()\n }\n }\n\n // flushes the pending delete info store\n // this should be called after queue processing has finished, so that data items and remaining (not reused) nodesets get cleaned up\n // we also call it on dispose not to leave any mess\n flushPendingDeletes () {\n for (let i = 0, len = this.pendingDeletes.length; i !== len; ++i) {\n var pd = this.pendingDeletes[i]\n while (pd.nodesets.length) {\n this.removeNodes(pd.nodesets.pop())\n }\n if (pd.data && pd.data[PENDING_DELETE_INDEX_SYM] !== undefined) { delete pd.data[PENDING_DELETE_INDEX_SYM] }\n }\n this.pendingDeletes = []\n }\n\n // We batch our deletion of item indexes in our parallel array.\n // See brianmhunt/knockout-fast-foreach#6/#8\n clearDeletedIndexes () {\n // We iterate in reverse on the presumption (following the unit tests) that KO's diff engine\n // processes diffs (esp. deletes) monotonically ascending i.e. from index 0 -> N.\n for (let i = this.indexesToDelete.length - 1; i >= 0; --i) {\n this.firstLastNodesList.splice(this.indexesToDelete[i], 1)\n }\n this.indexesToDelete = []\n }\n\n updateIndexes (fromIndex) {\n let ctx\n for (let i = fromIndex, len = this.firstLastNodesList.length; i < len; ++i) {\n ctx = this.getContextStartingFrom(this.firstLastNodesList[i].first)\n if (ctx) { ctx.$index(i) }\n }\n }\n\n getContextStartingFrom (node) {\n let ctx\n while (node) {\n ctx = contextFor(node)\n if (ctx) { return ctx }\n node = node.nextSibling\n }\n }\n\n /**\n * Set whether the binding is always synchronous.\n * Useful during testing.\n */\n static setSync (toggle) {\n const w = options.global\n if (toggle) {\n ForEachBinding.animateFrame = function (frame) { frame() }\n } else {\n ForEachBinding.animateFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame ||\n w.mozRequestAnimationFrame || w.msRequestAnimationFrame ||\n function (cb) { return w.setTimeout(cb, 1000 / 60) }\n }\n }\n\n get controlsDescendants () { return true }\n static get allowVirtualElements () { return true }\n\n /* TODO: Remove; for legacy/testing */\n static get ForEach () { return this }\n static get PENDING_DELETE_INDEX_SYM () { return PENDING_DELETE_INDEX_SYM }\n}\n"],
"mappings": "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",
"sourcesContent": ["// index.js\n// --------\n// Fast For Each\n//\n// Employing sound techniques to make a faster Knockout foreach binding.\n// --------\n\nimport {\n arrayForEach,\n cleanNode,\n options,\n virtualElements,\n createSymbolOrString,\n domData,\n domNodeIsContainedBy\n} from '@tko/utils'\n\nimport { isObservable, unwrap, observable } from '@tko/observable'\n\nimport type { ObservableArray } from '@tko/observable'\n\nimport { contextFor, applyBindingsToDescendants, AsyncBindingHandler } from '@tko/bind'\n\nimport type { AllBindings } from '@tko/bind'\n\n// Utilities\nconst MAX_LIST_SIZE = 9007199254740991\n\n// from https://github.com/jonschlinkert/is-plain-object\nfunction isPlainObject(o): o is Record<string, any> {\n return !!o && typeof o === 'object' && o.constructor === Object\n}\n\ninterface ChangeMap {\n added: ChangeAddItem[]\n deleted: any[]\n}\n\ninterface ChangeAddItemBase {\n status: 'added'\n index: number\n}\n\ninterface ChangeAddBatchItem extends ChangeAddItemBase {\n isBatch: true\n values: any[]\n}\n\ninterface ChangeAddOneItem extends ChangeAddItemBase {\n isBatch?: false\n value: any\n}\n\ntype ChangeAddItem = ChangeAddBatchItem | ChangeAddOneItem\n\nconst supportsDocumentFragment = options.document && typeof options.document.createDocumentFragment === 'function'\n\n// Get a copy of the (possibly virtual) child nodes of the given element,\n// put them into a container, then empty the given node.\nfunction makeTemplateNode(sourceNode) {\n const container = document.createElement('div')\n let parentNode\n if (sourceNode.content) {\n // For e.g. <template> tags\n parentNode = sourceNode.content\n } else if (sourceNode.tagName === 'SCRIPT') {\n parentNode = document.createElement('div')\n parentNode.innerHTML = sourceNode.text\n } else {\n // Anything else e.g. <div>\n parentNode = sourceNode\n }\n arrayForEach(virtualElements.childNodes(parentNode), function (child) {\n // FIXME - This cloneNode could be expensive; we may prefer to iterate over the\n // parentNode children in reverse (so as not to foul the indexes as childNodes are\n // removed from parentNode when inserted into the container)\n if (child) {\n container.insertBefore(child.cloneNode(true), null)\n }\n })\n return container\n}\n\n// Mimic a KO change item 'add'\nfunction valueToChangeAddItem(value, index): ChangeAddItem {\n return { status: 'added', value: value, index: index }\n}\n\n// store a symbol for caching the pending delete info index in the data item objects\nconst PENDING_DELETE_INDEX_SYM = createSymbolOrString('_ko_ffe_pending_delete_index')\n\nexport class ForEachBinding extends AsyncBindingHandler {\n // NOTE: valid valueAccessors include:\n // []\n // observable([])\n // observableArray([])\n // computed\n // {data: array, name: string, as: string}\n afterAdd\n override allBindings: AllBindings\n static animateFrame\n as\n beforeRemove\n container\n changeSubs: any\n data\n generateContext\n $indexHasBeenRequested: boolean\n templateNode\n changeQueue: any[]\n firstLastNodesList: { first: Node; last: Node }[]\n indexesToDelete: any[]\n isNotEmpty: any\n rendering_queued: boolean\n pendingDeletes: any[]\n afterQueueFlush\n beforeQueueFlush\n\n constructor(params) {\n super(params)\n const settings: any = {}\n if (isPlainObject(this.value)) {\n Object.assign(settings, this.value)\n }\n\n this.as = settings.as || this.allBindings.get('as')\n\n this.data = settings.data || (unwrap(this.$context.$rawData) === this.value ? this.$context.$rawData : this.value)\n\n this.container = virtualElements.isStartComment(this.$element) ? this.$element.parentNode : this.$element\n this.generateContext = this.createContextGenerator(this.as)\n this.$indexHasBeenRequested = false\n\n this.templateNode = makeTemplateNode(\n settings.templateNode || (settings.name ? document.getElementById(settings.name)?.cloneNode(true) : this.$element)\n )\n ;['afterAdd', 'beforeRemove', 'afterQueueFlush', 'beforeQueueFlush'].forEach(p => {\n this[p] = settings[p] || this.allBindings.get(p)\n })\n\n this.changeQueue = new Array()\n this.firstLastNodesList = new Array()\n this.indexesToDelete = new Array()\n this.rendering_queued = false\n this.pendingDeletes = new Array()\n\n // Expose the conditional so that if the `foreach` data is empty, successive\n // 'else' bindings will appear.\n this.isNotEmpty = observable(Boolean(unwrap(this.data).length))\n domData.set(this.$element, 'conditional', { elseChainSatisfied: this.isNotEmpty })\n\n // Remove existing content.\n virtualElements.emptyNode(this.$element)\n\n // Prime content\n const primeData = unwrap(this.data)\n if (primeData && primeData.map) {\n this.onArrayChange(primeData.map(valueToChangeAddItem), true)\n } else {\n this.completeBinding()\n }\n\n // Watch for changes\n if (isObservable(this.data)) {\n if (!(this.data as ObservableArray).indexOf) {\n // Make sure the observable is trackable.\n this.data = this.data.extend({ trackArrayChanges: true })\n }\n this.changeSubs = this.data.subscribe(this.onArrayChange, this, 'arrayChange')\n }\n }\n\n override dispose() {\n if (this.changeSubs) {\n this.changeSubs.dispose()\n }\n this.flushPendingDeletes()\n }\n\n // If the array changes we register the change.\n onArrayChange(changeSet, isInitial) {\n const changeMap: ChangeMap = { added: [], deleted: [] }\n\n // knockout array change notification index handling:\n // - sends the original array indexes for deletes\n // - sends the new array indexes for adds\n // - sorts them all by index in ascending order\n // because of this, when checking for possible batch additions, any delete can be between to adds with neighboring indexes, so only additions should be checked\n for (let i = 0, len = changeSet.length; i < len; i++) {\n if (changeMap.added.length && changeSet[i].status === 'added') {\n let lastAdd = changeMap.added[changeMap.added.length - 1]\n const lastIndex = lastAdd.isBatch ? lastAdd.index + lastAdd.values!.length - 1 : lastAdd.index\n if (lastIndex + 1 === changeSet[i].index) {\n if (!lastAdd.isBatch) {\n // transform the last addition into a batch addition object\n lastAdd = { isBatch: true, status: 'added', index: lastAdd.index, values: [lastAdd.value] }\n changeMap.added.splice(changeMap.added.length - 1, 1, lastAdd)\n }\n lastAdd.values!.push(changeSet[i].value)\n continue\n }\n }\n\n changeMap[changeSet[i].status].push(changeSet[i])\n }\n\n if (changeMap.deleted.length > 0) {\n this.changeQueue.push.apply(this.changeQueue, changeMap.deleted)\n this.changeQueue.push({ status: 'clearDeletedIndexes' })\n }\n\n this.changeQueue.push.apply(this.changeQueue, changeMap.added)\n // Once a change is registered, the ticking count-down starts for the processQueue.\n if (this.changeQueue.length > 0 && !this.rendering_queued) {\n this.rendering_queued = true\n if (isInitial) {\n this.processQueue()\n } else {\n ForEachBinding.animateFrame.call(window, () => this.processQueue())\n }\n }\n }\n\n startQueueFlush() {\n // Callback so folks can do things before the queue flush.\n if (typeof this.beforeQueueFlush === 'function') {\n this.beforeQueueFlush(this.changeQueue)\n }\n }\n\n endQueueFlush() {\n // Callback so folks can do things.\n if (typeof this.afterQueueFlush === 'function') {\n this.afterQueueFlush(this.changeQueue)\n }\n }\n\n // Reflect all the changes in the queue in the DOM, then wipe the queue.\n processQueue() {\n const isEmpty = !unwrap(this.data).length\n let lowestIndexChanged = MAX_LIST_SIZE\n\n this.startQueueFlush()\n\n arrayForEach(this.changeQueue, changeItem => {\n if (typeof changeItem.index === 'number') {\n lowestIndexChanged = Math.min(lowestIndexChanged, changeItem.index)\n }\n this[changeItem.status](changeItem)\n })\n this.flushPendingDeletes()\n this.rendering_queued = false\n\n // Update our indexes.\n if (this.$indexHasBeenRequested) {\n this.updateIndexes(lowestIndexChanged)\n }\n\n this.endQueueFlush()\n this.changeQueue = new Array()\n\n // Update the conditional exposed on the domData\n if (isEmpty !== !this.isNotEmpty()) {\n this.isNotEmpty(!isEmpty)\n }\n }\n\n /**\n * Once the $index has been asked for once, start calculating it.\n * Note that this significantly degrades performance, from O(1) to O(n)\n * for arbitrary changes to the list.\n */\n _first$indexRequest(ctx$indexRequestedFrom) {\n this.$indexHasBeenRequested = true\n for (let i = 0, len = this.firstLastNodesList.length; i < len; ++i) {\n const ctx = this.getContextStartingFrom(this.firstLastNodesList[i].first)\n // Overwrite the defineProperty.\n if (ctx) {\n ctx.$index = observable(i)\n }\n }\n return ctx$indexRequestedFrom.$index()\n }\n\n _contextExtensions($ctx) {\n Object.assign($ctx, { $list: this.data })\n if (this.$indexHasBeenRequested) {\n $ctx.$index = $ctx.$index || observable()\n } else {\n Object.defineProperty($ctx, '$index', {\n value: () => this._first$indexRequest($ctx),\n configurable: true,\n writable: true\n })\n }\n return $ctx\n }\n\n /**\n * Return a function that generates the context for a given node.\n *\n * We generate a single function that reduces our inner-loop calculations,\n * which has a good chance of being optimized by the browser.\n *\n * @param {string} as The name given to each item in the list\n * @param {bool} index Whether to calculate indexes\n * @return {function} A function(dataValue) that returns the context\n */\n createContextGenerator(as) {\n const $ctx = this.$context\n if (as) {\n return v => this._contextExtensions($ctx.extend({ [as]: v }))\n } else {\n return v => $ctx.createChildContext(v, undefined, ctx => this._contextExtensions(ctx))\n }\n }\n\n updateFirstLastNodesList(index, children) {\n const first = children[0]\n const last = children[children.length - 1]\n this.firstLastNodesList.splice(index, 0, { first, last })\n }\n\n // Process a changeItem with {status: 'added', ...}\n added(changeItem: ChangeAddItem) {\n const index = changeItem.index\n const valuesToAdd = changeItem.isBatch ? changeItem.values : [changeItem.value]\n const referenceElement = this.getLastNodeBeforeIndex(index)\n // gather all childnodes for a possible batch insertion\n const allChildNodes: Node[] = []\n const asyncBindingResults = new Array()\n let children\n\n for (let i = 0, len = valuesToAdd.length; i < len; ++i) {\n // we check if we have a pending delete with reusable nodesets for this data, and if yes, we reuse one nodeset\n const pendingDelete = this.getPendingDeleteFor(valuesToAdd[i])\n if (pendingDelete && pendingDelete.nodesets.length) {\n children = pendingDelete.nodesets.pop()\n this.updateFirstLastNodesList(index + i, children)\n } else {\n const templateClone = this.templateNode.cloneNode(true)\n children = virtualElements.childNodes(templateClone)\n this.updateFirstLastNodesList(index + i, children)\n\n // Apply bindings first, and then process child nodes,\n // because bindings can add childnodes.\n const bindingResult = applyBindingsToDescendants(this.generateContext(valuesToAdd[i]), templateClone)\n asyncBindingResults.push(bindingResult)\n }\n\n allChildNodes.push(...children)\n }\n\n if (typeof this.afterAdd === 'function') {\n this.afterAdd({\n nodeOrArrayInserted: this.insertAllAfter(allChildNodes, referenceElement),\n foreachInstance: this\n })\n } else {\n this.insertAllAfter(allChildNodes, referenceElement)\n }\n\n this.completeBinding(Promise.all(asyncBindingResults))\n }\n\n getNodesForIndex(index) {\n const result = new Array()\n let ptr = this.firstLastNodesList[index].first\n const last = this.firstLastNodesList[index].last\n result.push(ptr)\n while (ptr && ptr !== last) {\n ptr = ptr.nextSibling!\n result.push(ptr)\n }\n return result\n }\n\n getLastNodeBeforeIndex(index) {\n if (index < 1 || index - 1 >= this.firstLastNodesList.length) {\n return null\n }\n return this.firstLastNodesList[index - 1].last\n }\n\n /**\n * Get the active (focused) node, if it's a child of the given node.\n */\n activeChildElement(node) {\n const active = document.activeElement\n if (domNodeIsContainedBy(active!, node)) {\n return active\n }\n return null\n }\n\n insertAllAfter(nodeOrNodeArrayToInsert, insertAfterNode) {\n let frag\n let len\n let i\n let active: any = null\n const containerNode = this.$element\n\n // Poor man's node and array check.\n if (nodeOrNodeArrayToInsert.nodeType === undefined && nodeOrNodeArrayToInsert.length === undefined) {\n throw new Error('Expected a single node or a node array')\n }\n if (nodeOrNodeArrayToInsert.nodeType !== undefined) {\n active = this.activeChildElement(nodeOrNodeArrayToInsert)\n virtualElements.insertAfter(containerNode, nodeOrNodeArrayToInsert, insertAfterNode)\n return [nodeOrNodeArrayToInsert]\n } else if (nodeOrNodeArrayToInsert.length === 1) {\n active = this.activeChildElement(nodeOrNodeArrayToInsert[0])\n virtualElements.insertAfter(containerNode, nodeOrNodeArrayToInsert[0], insertAfterNode)\n } else if (supportsDocumentFragment) {\n frag = document.createDocumentFragment()\n for (i = 0, len = nodeOrNodeArrayToInsert.length; i !== len; ++i) {\n active = active || this.activeChildElement(nodeOrNodeArrayToInsert[i])\n frag.appendChild(nodeOrNodeArrayToInsert[i])\n }\n virtualElements.insertAfter(containerNode, frag, insertAfterNode)\n } else {\n // Nodes are inserted in reverse order - pushed down immediately after\n // the last node for the previous item or as the first node of element.\n for (i = nodeOrNodeArrayToInsert.length - 1; i >= 0; --i) {\n active = active || this.activeChildElement(nodeOrNodeArrayToInsert[i])\n const child = nodeOrNodeArrayToInsert[i]\n if (!child) {\n break\n }\n virtualElements.insertAfter(containerNode, child, insertAfterNode)\n }\n }\n\n if (active) {\n active.focus()\n }\n\n return nodeOrNodeArrayToInsert\n }\n\n // checks if the deleted data item should be handled with delay for a possible reuse at additions\n shouldDelayDeletion(data) {\n return data && (typeof data === 'object' || typeof data === 'function')\n }\n\n // gets the pending deletion info for this data item\n getPendingDeleteFor(data: any[]) {\n const index = data && data[PENDING_DELETE_INDEX_SYM]\n if (index === undefined) return null\n return this.pendingDeletes[index]\n }\n\n // tries to find the existing pending delete info for this data item, and if it can't, it registeres one\n getOrCreatePendingDeleteFor(data) {\n let pd = this.getPendingDeleteFor(data)\n if (pd) {\n return pd\n }\n pd = { data: data, nodesets: [] }\n data[PENDING_DELETE_INDEX_SYM] = this.pendingDeletes.length\n this.pendingDeletes.push(pd)\n return pd\n }\n\n // Process a changeItem with {status: 'deleted', ...}\n deleted(changeItem) {\n // if we should delay the deletion of this data, we add the nodeset to the pending delete info object\n if (this.shouldDelayDeletion(changeItem.value)) {\n const pd = this.getOrCreatePendingDeleteFor(changeItem.value)\n pd.nodesets.push(this.getNodesForIndex(changeItem.index))\n } else {\n // simple data, just remove the nodes\n this.removeNodes(this.getNodesForIndex(changeItem.index))\n }\n this.indexesToDelete.push(changeItem.index)\n }\n\n // removes a set of nodes from the DOM\n removeNodes(nodes) {\n if (!nodes.length) {\n return\n }\n\n function removeFn() {\n const parent = nodes[0].parentNode\n for (let i = nodes.length - 1; i >= 0; --i) {\n cleanNode(nodes[i])\n parent.removeChild(nodes[i])\n }\n }\n\n if (this.beforeRemove) {\n const beforeRemoveReturn = this.beforeRemove({ nodesToRemove: nodes, foreachInstance: this }) || {}\n // If beforeRemove returns a `then`\u2013able e.g. a Promise, we remove\n // the nodes when that thenable completes. We pass any errors to\n // ko.onError.\n if (typeof beforeRemoveReturn.then === 'function') {\n beforeRemoveReturn.then(removeFn, options.onError)\n }\n } else {\n removeFn()\n }\n }\n\n // flushes the pending delete info store\n // this should be called after queue processing has finished, so that data items and remaining (not reused) nodesets get cleaned up\n // we also call it on dispose not to leave any mess\n flushPendingDeletes() {\n for (let i = 0, len = this.pendingDeletes.length; i !== len; ++i) {\n const pd = this.pendingDeletes[i]\n while (pd.nodesets.length) {\n this.removeNodes(pd.nodesets.pop())\n }\n if (pd.data && pd.data[PENDING_DELETE_INDEX_SYM] !== undefined) {\n delete pd.data[PENDING_DELETE_INDEX_SYM]\n }\n }\n this.pendingDeletes = new Array()\n }\n\n // We batch our deletion of item indexes in our parallel array.\n // See brianmhunt/knockout-fast-foreach#6/#8\n clearDeletedIndexes() {\n // We iterate in reverse on the presumption (following the unit tests) that KO's diff engine\n // processes diffs (esp. deletes) monotonically ascending i.e. from index 0 -> N.\n for (let i = this.indexesToDelete.length - 1; i >= 0; --i) {\n this.firstLastNodesList.splice(this.indexesToDelete[i], 1)\n }\n this.indexesToDelete = new Array()\n }\n\n updateIndexes(fromIndex) {\n let ctx\n for (let i = fromIndex, len = this.firstLastNodesList.length; i < len; ++i) {\n ctx = this.getContextStartingFrom(this.firstLastNodesList[i].first)\n if (ctx) {\n ctx.$index(i)\n }\n }\n }\n\n getContextStartingFrom(node) {\n let ctx\n while (node) {\n ctx = contextFor(node)\n if (ctx) {\n return ctx\n }\n node = node.nextSibling\n }\n }\n\n /**\n * Set whether the binding is always synchronous.\n * Useful during testing.\n */\n static setSync(toggle) {\n const w = options.global\n if (toggle) {\n ForEachBinding.animateFrame = function (frame) {\n frame()\n }\n } else {\n ForEachBinding.animateFrame =\n w.requestAnimationFrame\n || w.webkitRequestAnimationFrame\n || w.mozRequestAnimationFrame\n || w.msRequestAnimationFrame\n || function (cb) {\n return w.setTimeout(cb, 1000 / 60)\n }\n }\n }\n\n override get controlsDescendants() {\n return true\n }\n static override get allowVirtualElements() {\n return true\n }\n\n /* TODO: Remove; for legacy/testing */\n static get ForEach() {\n return this\n }\n static get PENDING_DELETE_INDEX_SYM() {\n return PENDING_DELETE_INDEX_SYM\n }\n}\n"],
"mappings": "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",
"names": []
}

@@ -1,6 +0,5 @@

// @tko/binding.foreach 🥊 4.0.0-beta1.3 ESM
// @tko/binding.foreach 🥊 4.0.0 ESM
"use strict";
import { ForEachBinding } from "./foreach";
export var bindings = {
foreach: ForEachBinding
};
export const bindings = { foreach: ForEachBinding };
ForEachBinding.setSync(false);
{
"version": 3,
"sources": ["../src/index.ts"],
"sourcesContent": ["import { ForEachBinding } from './foreach'\n\nexport var bindings = {\n foreach: ForEachBinding\n}\n\n// By default, foreach will be async.\nForEachBinding.setSync(false)\n"],
"mappings": ";AAAA;AAEO,WAAI,WAAW;AAAA,EACpB,SAAS;AACX;AAGA,eAAe,QAAQ,KAAK;",
"sourcesContent": ["import { ForEachBinding } from './foreach'\n\nexport const bindings = { foreach: ForEachBinding }\n\n// By default, foreach will be async.\nForEachBinding.setSync(false)\n"],
"mappings": ";;AAAA,SAAS,sBAAsB;AAExB,aAAM,WAAW,EAAE,SAAS,eAAe;AAGlD,eAAe,QAAQ,KAAK;",
"names": []
}

@@ -1,6 +0,5 @@

// @tko/binding.foreach 🥊 4.0.0-beta1.3 MJS
// @tko/binding.foreach 🥊 4.0.0 MJS
"use strict";
import { ForEachBinding } from "./foreach";
export var bindings = {
foreach: ForEachBinding
};
export const bindings = { foreach: ForEachBinding };
ForEachBinding.setSync(false);
{
"version": 3,
"sources": ["../src/index.ts"],
"sourcesContent": ["import { ForEachBinding } from './foreach'\n\nexport var bindings = {\n foreach: ForEachBinding\n}\n\n// By default, foreach will be async.\nForEachBinding.setSync(false)\n"],
"mappings": ";AAAA;AAEO,WAAI,WAAW;AAAA,EACpB,SAAS;AACX;AAGA,eAAe,QAAQ,KAAK;",
"sourcesContent": ["import { ForEachBinding } from './foreach'\n\nexport const bindings = { foreach: ForEachBinding }\n\n// By default, foreach will be async.\nForEachBinding.setSync(false)\n"],
"mappings": ";;AAAA,SAAS,sBAAsB;AAExB,aAAM,WAAW,EAAE,SAAS,eAAe;AAGlD,eAAe,QAAQ,KAAK;",
"names": []
}
{
"version": "4.0.0-beta1.3",
"version": "4.0.0",
"name": "@tko/binding.foreach",

@@ -26,6 +26,6 @@ "description": "Knockout Foreach Binding",

"dependencies": {
"@tko/bind": "^4.0.0-beta1.3",
"@tko/observable": "^4.0.0-beta1.3",
"@tko/provider": "^4.0.0-beta1.3",
"@tko/utils": "^4.0.0-beta1.3",
"@tko/bind": "^4.0.0",
"@tko/observable": "^4.0.0",
"@tko/provider": "^4.0.0",
"@tko/utils": "^4.0.0",
"tslib": "^2.2.0"

@@ -52,4 +52,3 @@ },

"./helpers/*": "./helpers/*"
},
"gitHead": "a8843acb8ae085915115e53a4e057b30731c635e"
}
}
The MIT License (MIT) - http://www.opensource.org/licenses/mit-license.php
Copyright (c) Steven Sanderson, the Knockout.js team, and other contributors
http://knockoutjs.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display