ixfx
Version:
A framework for programming interactivity
467 lines (462 loc) • 14.6 kB
JavaScript
import {
StackMutable,
TraverseObject_exports,
TreeMutable_exports,
asDynamicTraversable,
asDynamicTraversable2,
compare,
createNode,
getRoot,
remove,
toStringDeep
} from "./chunk-C5TMTNJN.js";
import {
QueueMutable
} from "./chunk-VYCNRTDD.js";
import {
toStringAbbreviate
} from "./chunk-F2KVRMEV.js";
import {
isEqualDefault
} from "./chunk-6UZ3OSJO.js";
import {
__export
} from "./chunk-L5EJU35C.js";
// src/collections/tree/index.ts
var tree_exports = {};
__export(tree_exports, {
FromObject: () => TraverseObject_exports,
Mutable: () => TreeMutable_exports,
Pathed: () => Pathed_exports,
Traverse: () => TraversableTree_exports,
compare: () => compare,
isTraversable: () => isTraversable,
isTreeNode: () => isTreeNode,
toTraversable: () => toTraversable
});
// src/collections/tree/Pathed.ts
var Pathed_exports = {};
__export(Pathed_exports, {
addValueByPath: () => addValueByPath,
childrenLengthByPath: () => childrenLengthByPath,
clearValuesByPath: () => clearValuesByPath,
create: () => create,
removeByPath: () => removeByPath,
valueByPath: () => valueByPath,
valuesByPath: () => valuesByPath
});
var create = (pathOpts = {}) => {
let root;
const add = (value, path) => {
const n = addValueByPath(value, path, root, pathOpts);
if (root === void 0) {
root = getRoot(n);
}
};
const prettyPrint = () => {
if (root === void 0) return `(empty)`;
return toStringDeep(root);
};
const getValue = (path) => {
if (root === void 0) return;
return valueByPath(path, root, pathOpts);
};
const remove2 = (path) => {
if (root === void 0) return false;
return removeByPath(path, root, pathOpts);
};
const hasPath = (path) => {
if (root === void 0) return false;
const c = findChildByPath(path, root, pathOpts);
return c !== void 0;
};
const getNode = (path) => {
if (root === void 0) return;
const c = findChildByPath(path, root, pathOpts);
return c;
};
const childrenLength2 = (path) => {
if (root === void 0) return 0;
const c = findChildByPath(path, root, pathOpts);
if (c === void 0) return 0;
return c.childrenStore.length;
};
const getValues = (path) => {
if (root === void 0) return [];
return valuesByPath(path, root, pathOpts);
};
const getRoot2 = () => {
return root;
};
const clearValues = (path) => {
if (root === void 0) return false;
return clearValuesByPath(path, root, pathOpts);
};
return { getRoot: getRoot2, add, prettyPrint, remove: remove2, getValue, getValues, hasPath, childrenLength: childrenLength2, getNode, clearValues };
};
var addValueByPath = (value, path, node, pathOpts = {}) => {
const separator = pathOpts.separator ?? `.`;
const duplicatePath = pathOpts.duplicates ?? `overwrite`;
const split = path.split(separator);
let count = 0;
for (const p of split) {
const lastEntry = count === split.length - 1;
const found = findChildByLabel(p, node);
if (found === void 0) {
const labelled = {
value: lastEntry ? value : void 0,
label: p
};
node = createNode(labelled, node);
} else {
node = found;
if (lastEntry) {
switch (duplicatePath) {
case `ignore`: {
break;
}
case `allow`: {
const existing = getValuesFromNode(node);
node.value = {
values: [...existing, value],
label: p
};
break;
}
case `overwrite`: {
node.value = {
value,
label: p
};
break;
}
}
} else {
node = found;
}
}
count++;
}
if (node === void 0) throw new Error(`Could not create tree`);
return node;
};
var removeByPath = (path, root, pathOpts = {}) => {
if (root === void 0) return false;
const c = findChildByPath(path, root, pathOpts);
if (c === void 0) return false;
remove(c);
return true;
};
var clearValuesByPath = (path, root, pathOpts = {}) => {
if (root === void 0) return false;
const c = findChildByPath(path, root, pathOpts);
if (c === void 0) return false;
c.value = {
label: c.value?.label ?? ``,
value: void 0
};
return true;
};
var childrenLengthByPath = (path, node, pathOpts = {}) => {
if (node === void 0) return 0;
const c = findChildByPath(path, node, pathOpts);
if (c === void 0) return 0;
return c.childrenStore.length;
};
var findChildByLabel = (label, node) => {
if (node === void 0) return void 0;
if (label === void 0) throw new Error(`Parameter 'label' cannot be undefined`);
if (node.value?.label === label) return node;
for (const c of node.childrenStore) {
if (c.value?.label === label) return c;
}
};
var valueByPath = (path, node, pathOpts = {}) => {
const values = valuesByPath(path, node, pathOpts);
if (values.length === 0) return void 0;
if (values.length > 1) throw new Error(`Multiple values at path. Use getValues instead`);
return values[0];
};
var getValuesFromNode = (c) => {
if (c.value === void 0) return [];
if (`values` in c.value) return c.value.values;
if (`value` in c.value) {
if (c.value.value === void 0) return [];
return [c.value.value];
}
return [];
};
var findChildByPath = (path, node, pathOpts = {}) => {
const separator = pathOpts.separator ?? `.`;
const split = path.split(separator);
let c = node;
for (const p of split) {
c = findChildByLabel(p, c);
if (c === void 0) {
return;
}
}
return c;
};
var valuesByPath = (path, node, pathOpts = {}) => {
const separator = pathOpts.separator ?? `.`;
const split = path.split(separator);
let c = node;
for (const p of split) {
c = findChildByLabel(p, c);
if (c === void 0) {
return [];
}
}
return getValuesFromNode(c);
};
// src/collections/tree/TraversableTree.ts
var TraversableTree_exports = {};
__export(TraversableTree_exports, {
breadthFirst: () => breadthFirst,
childrenLength: () => childrenLength,
couldAddChild: () => couldAddChild,
depthFirst: () => depthFirst,
find: () => find,
findAnyChildByValue: () => findAnyChildByValue,
findAnyParentByValue: () => findAnyParentByValue,
findByValue: () => findByValue,
findChildByValue: () => findChildByValue,
findParentByValue: () => findParentByValue,
followValue: () => followValue,
hasAnyChild: () => hasAnyChild,
hasAnyChildValue: () => hasAnyChildValue,
hasAnyParent: () => hasAnyParent,
hasAnyParentValue: () => hasAnyParentValue,
hasChild: () => hasChild,
hasChildValue: () => hasChildValue,
hasParent: () => hasParent,
hasParentValue: () => hasParentValue,
parents: () => parents,
siblings: () => siblings,
toString: () => toString,
toStringDeep: () => toStringDeep2
});
var childrenLength = (tree) => {
return [...tree.children()].length;
};
var hasAnyParent = (child, possibleParent, eq) => {
return hasParent(child, possibleParent, eq, Number.MAX_SAFE_INTEGER);
};
var hasAnyParentValue = (child, possibleParentValue, eq) => {
return hasParentValue(child, possibleParentValue, eq, Number.MAX_SAFE_INTEGER);
};
var findAnyParentByValue = (child, possibleParentValue, eq) => {
return findParentByValue(child, possibleParentValue, eq, Number.MAX_SAFE_INTEGER);
};
var hasParent = (child, possibleParent, eq = isEqualDefault, maxDepth = 0) => {
if (maxDepth < 0) return false;
const isChildTrav = isTraversable(child);
const isParentTrav = isTraversable(possibleParent);
const p = isChildTrav ? child.getParent() : child.parent;
if (p === void 0) return false;
if (eq(p, possibleParent)) return true;
const pId = isChildTrav ? p.getIdentity() : p.value;
const ppId = isParentTrav ? possibleParent.getIdentity() : possibleParent.value;
if (eq(pId, ppId)) return true;
return hasParent(p, possibleParent, eq, maxDepth - 1);
};
var hasParentValue = (child, possibleParentValue, eq = isEqualDefault, maxDepth = 0) => {
if (maxDepth < 0) return false;
const p = `getParent` in child ? child.getParent() : child.parent;
if (p === void 0) return false;
const value = `getValue` in p ? p.getValue() : p.value;
if (eq(value, possibleParentValue)) return true;
return hasParentValue(p, possibleParentValue, eq, maxDepth - 1);
};
var findParentByValue = (child, possibleParentValue, eq = isEqualDefault, maxDepth = 0) => {
if (maxDepth < 0) return;
const p = `getParent` in child ? child.getParent() : child.parent;
if (p === void 0) return;
const value = `getValue` in p ? p.getValue() : p.value;
if (eq(value, possibleParentValue)) return p;
return findParentByValue(p, possibleParentValue, eq, maxDepth - 1);
};
var couldAddChild = (parent, prospectiveChild, eq = isEqualDefault) => {
if (eq(parent, prospectiveChild)) throw new Error(`Child equals parent`);
if (hasAnyChild(parent, prospectiveChild, eq)) {
throw new Error(`Circular. Parent already has child`);
}
if (hasAnyChild(prospectiveChild, parent, eq)) {
throw new Error(`Prospective child has parent as child relation`);
}
};
var hasAnyChild = (parent, possibleChild, eq = isEqualDefault) => {
return hasChild(parent, possibleChild, eq, Number.MAX_SAFE_INTEGER);
};
var hasAnyChildValue = (parent, possibleChildValue, eq = isEqualDefault) => {
return hasChildValue(parent, possibleChildValue, eq, Number.MAX_SAFE_INTEGER);
};
var hasChild = (parent, possibleChild, eq = isEqualDefault, maxDepth = 0) => {
if (maxDepth < 0) return false;
if (eq(parent, possibleChild)) return true;
const pId = `getIdentity` in parent ? parent.getIdentity() : parent.value;
const pcId = `getIdentity` in possibleChild ? possibleChild.getIdentity() : possibleChild.value;
if (eq(pId, pcId)) return true;
for (const c of breadthFirst(parent, maxDepth)) {
const cId = `getIdentity` in c ? c.getIdentity() : c.value;
if (eq(c, possibleChild)) return true;
if (eq(cId, pcId)) return true;
}
return false;
};
var hasChildValue = (parent, possibleValue, eq = isEqualDefault, maxDepth = 0) => {
if (maxDepth < 0) return false;
if (eq(parent.getValue(), possibleValue)) return true;
for (const c of breadthFirst(parent, maxDepth)) {
if (eq(c.getValue(), possibleValue)) return true;
}
return false;
};
function* siblings(node) {
const p = node.getParent();
if (p === void 0) return;
for (const s of p.children()) {
if (s === node) continue;
yield s;
}
}
function* parents(node) {
if (isTraversable(node)) {
let p = node.getParent();
while (p !== void 0) {
yield p;
p = p.getParent();
}
} else {
let p = node.parent;
while (p !== void 0) {
yield p;
p = p.parent;
}
}
}
function findAnyChildByValue(parent, possibleValue, eq = isEqualDefault) {
return findChildByValue(parent, possibleValue, eq, Number.MAX_SAFE_INTEGER);
}
function findChildByValue(parent, possibleValue, eq = isEqualDefault, maxDepth = 0) {
if (maxDepth < 0) return;
const isTraver = isTraversable(parent);
if (isTraver) {
if (eq(parent.getValue(), possibleValue)) return parent;
} else {
if (eq(parent.value, possibleValue)) return parent;
}
for (const d of breadthFirst(parent, maxDepth)) {
if (isTraver) {
if (eq(d.getValue(), possibleValue)) return d;
} else {
if (eq(d.value, possibleValue)) return d;
}
}
return;
}
function* depthFirst(root) {
if (!root) return;
const stack = new StackMutable();
let entry = root;
while (entry) {
const entries = isTraversable(entry) ? [...entry.children()] : [...entry.childrenStore];
stack.push(...entries);
if (stack.isEmpty) break;
entry = stack.pop();
if (entry) yield entry;
}
}
function* breadthFirst(root, depth = Number.MAX_SAFE_INTEGER) {
if (!root) return;
const isTrav = isTraversable(root);
const queue = isTrav ? new QueueMutable() : new QueueMutable();
let entry = root;
while (entry) {
if (depth < 0) return;
if (entry !== void 0) {
const kids = `childrenStore` in entry ? entry.childrenStore : entry.children();
for (const c of kids) {
yield c;
queue.enqueue(c);
}
}
entry = queue.dequeue();
depth--;
}
}
function find(root, predicate, order = `breadth`) {
if (predicate(root)) return root;
const iter = order === `breadth` ? breadthFirst : depthFirst;
for (const c of iter(root)) {
if (predicate(c)) return c;
}
}
function findByValue(root, predicate, order = `breadth`) {
if (predicate(root.getValue())) return root;
const iter = order === `breadth` ? breadthFirst : depthFirst;
for (const c of iter(root)) {
if (predicate(c.getValue())) return c;
}
}
function* followValue(root, continuePredicate, depth = 1) {
for (const c of root.children()) {
if (continuePredicate(c.getValue(), depth)) {
yield c.getValue();
yield* followValue(c, continuePredicate, depth + 1);
}
}
}
function toStringDeep2(node, depth = 0) {
if (node === void 0) return `(undefined)`;
if (node === null) return `(null)`;
const v = node.getValue();
let type = typeof v;
if (Array.isArray(v)) type = `array`;
let t = ` `.repeat(depth) + `value: ${JSON.stringify(v)} (${type})
`;
for (const n of node.children()) {
t += toStringDeep2(n, depth + 1);
}
return t;
}
function toString(...nodes) {
let t = ``;
for (const node of nodes) {
const v = node.getValue();
const vString = toStringAbbreviate(v);
const children = [...node.children()];
const parent = node.getParent();
let type = typeof v;
if (Array.isArray(v)) type = `array`;
t += `value: ${vString} (${type}) kids: ${children.length} parented: ${parent ? `y` : `n`}
`;
}
return t;
}
// src/collections/tree/index.ts
var toTraversable = (node) => {
if (isTraversable(node)) return node;
if (isTreeNode(node)) return asDynamicTraversable(node);
if (typeof node === `object`) return asDynamicTraversable2(node);
throw new Error(`Parameter 'node' not convertible`);
};
var isTreeNode = (node) => {
if (`parent` in node && `childrenStore` in node && `value` in node) {
if (Array.isArray(node.childrenStore)) return true;
}
return false;
};
var isTraversable = (node) => {
return `children` in node && `getParent` in node && `getValue` in node && `getIdentity` in node;
};
export {
Pathed_exports,
TraversableTree_exports,
toTraversable,
isTreeNode,
isTraversable,
tree_exports
};
//# sourceMappingURL=chunk-MXGDX5JU.js.map