@weborigami/origami 0.5.4 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/index.ts +0 -4
  2. package/main.js +2 -9
  3. package/package.json +4 -5
  4. package/src/cli/cli.js +10 -8
  5. package/src/common/documentObject.js +3 -3
  6. package/src/common/loadJsDom.js +13 -0
  7. package/src/common/utilities.d.ts +0 -2
  8. package/src/common/utilities.js +1 -55
  9. package/src/dev/ExplorableSiteTransform.js +2 -6
  10. package/src/dev/OriCommandTransform.js +25 -7
  11. package/src/dev/changes.js +10 -5
  12. package/src/dev/code.js +1 -6
  13. package/src/dev/copy.js +4 -8
  14. package/src/dev/crawler/audit.js +8 -8
  15. package/src/dev/crawler/crawl.js +3 -5
  16. package/src/dev/crawler/findPaths.js +9 -3
  17. package/src/dev/crawler/pathsInHtml.js +4 -3
  18. package/src/dev/debug.js +4 -7
  19. package/src/dev/dev.js +4 -2
  20. package/src/dev/explore.js +17 -39
  21. package/src/dev/help.js +0 -4
  22. package/src/dev/help.yaml +18 -14
  23. package/src/dev/log.js +1 -2
  24. package/src/dev/serve.js +5 -18
  25. package/src/dev/svg.js +5 -5
  26. package/src/dev/treeDot.js +5 -6
  27. package/src/dev/watch.js +8 -12
  28. package/src/initializeBuiltins.js +23 -0
  29. package/src/origami/csv.js +1 -5
  30. package/src/origami/document.js +2 -5
  31. package/src/origami/fetch.js +4 -8
  32. package/src/origami/htmlDom.js +3 -2
  33. package/src/origami/image/format.js +0 -5
  34. package/src/origami/image/resize.js +0 -3
  35. package/src/origami/indexPage.js +4 -4
  36. package/src/origami/inline.js +4 -10
  37. package/src/origami/json.js +2 -6
  38. package/src/origami/jsonKeys.js +4 -10
  39. package/src/origami/jsonParse.js +1 -1
  40. package/src/origami/mdHtml.js +5 -9
  41. package/src/origami/mdOutline.js +3 -3
  42. package/src/origami/once.js +3 -7
  43. package/src/origami/ori.js +21 -24
  44. package/src/origami/origami.js +1 -4
  45. package/src/origami/pack.js +0 -5
  46. package/src/origami/post.js +4 -3
  47. package/src/origami/rss.js +7 -8
  48. package/src/origami/sitemap.js +7 -9
  49. package/src/origami/static.js +7 -9
  50. package/src/origami/string.js +1 -14
  51. package/src/origami/unpack.js +0 -5
  52. package/src/origami/yaml.js +1 -5
  53. package/src/origami/yamlParse.js +1 -1
  54. package/src/server/constructResponse.js +3 -3
  55. package/src/server/server.js +8 -59
  56. package/src/builtinsProgram.js +0 -65
  57. package/src/builtinsShell.js +0 -18
  58. package/src/cli/getConfig.js +0 -11
  59. package/src/common/ConstantTree.js +0 -18
  60. package/src/common/constructHref.js +0 -20
  61. package/src/common/constructSiteTree.js +0 -34
  62. package/src/common/fetchAndHandleExtension.js +0 -27
  63. package/src/handlers/css.handler.js +0 -7
  64. package/src/handlers/csv.handler.js +0 -126
  65. package/src/handlers/handlerBuiltins.js +0 -27
  66. package/src/handlers/handlers.js +0 -33
  67. package/src/handlers/htm.handler.js +0 -2
  68. package/src/handlers/html.handler.js +0 -7
  69. package/src/handlers/jpeg.handler.js +0 -62
  70. package/src/handlers/jpg.handler.js +0 -2
  71. package/src/handlers/js.handler.js +0 -20
  72. package/src/handlers/json.handler.js +0 -27
  73. package/src/handlers/md.handler.js +0 -7
  74. package/src/handlers/mjs.handler.js +0 -2
  75. package/src/handlers/ori.handler.js +0 -55
  76. package/src/handlers/oridocument.handler.js +0 -78
  77. package/src/handlers/parseFrontMatter.js +0 -16
  78. package/src/handlers/processUnpackedContent.js +0 -35
  79. package/src/handlers/ts.handler.js +0 -1
  80. package/src/handlers/txt.handler.js +0 -91
  81. package/src/handlers/wasm.handler.js +0 -17
  82. package/src/handlers/xhtml.handler.js +0 -2
  83. package/src/handlers/yaml.handler.js +0 -36
  84. package/src/handlers/yml.handler.js +0 -2
  85. package/src/origami/config.js +0 -18
  86. package/src/origami/project.js +0 -111
  87. package/src/protocols/explore.js +0 -19
  88. package/src/protocols/files.js +0 -31
  89. package/src/protocols/http.js +0 -18
  90. package/src/protocols/https.js +0 -18
  91. package/src/protocols/httpstree.js +0 -19
  92. package/src/protocols/httptree.js +0 -19
  93. package/src/protocols/js.js +0 -13
  94. package/src/protocols/node.js +0 -13
  95. package/src/protocols/package.js +0 -70
  96. package/src/tree/addNextPrevious.js +0 -22
  97. package/src/tree/cache.js +0 -22
  98. package/src/tree/calendar.js +0 -1
  99. package/src/tree/clear.js +0 -19
  100. package/src/tree/concat.js +0 -17
  101. package/src/tree/constant.js +0 -1
  102. package/src/tree/deepMap.js +0 -32
  103. package/src/tree/deepMerge.js +0 -18
  104. package/src/tree/deepReverse.js +0 -23
  105. package/src/tree/deepTake.js +0 -26
  106. package/src/tree/deepValues.js +0 -22
  107. package/src/tree/defineds.js +0 -30
  108. package/src/tree/filter.js +0 -19
  109. package/src/tree/first.js +0 -19
  110. package/src/tree/fromFn.js +0 -29
  111. package/src/tree/globKeys.js +0 -19
  112. package/src/tree/group.js +0 -26
  113. package/src/tree/inners.js +0 -30
  114. package/src/tree/keys.js +0 -15
  115. package/src/tree/length.js +0 -15
  116. package/src/tree/map.d.ts +0 -11
  117. package/src/tree/map.js +0 -125
  118. package/src/tree/mask.js +0 -19
  119. package/src/tree/match.js +0 -79
  120. package/src/tree/merge.js +0 -41
  121. package/src/tree/paginate.js +0 -20
  122. package/src/tree/parent.js +0 -15
  123. package/src/tree/plain.js +0 -15
  124. package/src/tree/regExpKeys.js +0 -19
  125. package/src/tree/reverse.js +0 -17
  126. package/src/tree/setDeep.js +0 -49
  127. package/src/tree/shuffle.js +0 -57
  128. package/src/tree/sort.js +0 -52
  129. package/src/tree/take.js +0 -19
  130. package/src/tree/tree.js +0 -52
  131. package/src/tree/values.js +0 -15
@@ -1,29 +0,0 @@
1
- import { FunctionTree, isUnpackable } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
- import { toFunction } from "../common/utilities.js";
4
-
5
- /**
6
- * Create a tree from a function and a set of keys.
7
- *
8
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
- * @typedef {import("../../index.ts").Invocable} Invocable
11
- *
12
- * @this {AsyncTree|null}
13
- * @param {Invocable} [invocable]
14
- */
15
- export default async function fromFn(invocable, keys = []) {
16
- assertTreeIsDefined(this, "fromFn");
17
- if (invocable === undefined) {
18
- throw new Error(
19
- "An Origami function was called with an initial argument, but its value is undefined."
20
- );
21
- }
22
- const fn = toFunction(invocable);
23
- if (isUnpackable(keys)) {
24
- keys = await keys.unpack();
25
- }
26
- const tree = new FunctionTree(fn, keys);
27
- tree.parent = this;
28
- return tree;
29
- }
@@ -1,19 +0,0 @@
1
- import { setParent } from "@weborigami/async-tree";
2
- import globKeys from "@weborigami/async-tree/src/operations/globKeys.js";
3
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
4
-
5
- /**
6
- * Define a tree whose keys are globs.
7
- *
8
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
- *
11
- * @param {Treelike} tree
12
- * @this {AsyncTree|null}
13
- */
14
- export default async function globKeysBuiltin(tree) {
15
- assertTreeIsDefined(this, "globs");
16
- const result = globKeys(tree);
17
- setParent(this, result);
18
- return result;
19
- }
package/src/tree/group.js DELETED
@@ -1,26 +0,0 @@
1
- import { group as groupTransform } from "@weborigami/async-tree";
2
- import getTreeArgument from "../common/getTreeArgument.js";
3
- import { toFunction } from "../common/utilities.js";
4
-
5
- /**
6
- * Map a tree to a new tree with the values from the original tree grouped by
7
- * the given function.
8
- *
9
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
10
- *
11
- * @this {AsyncTree|null}
12
- * @param {import("@weborigami/async-tree").Treelike} treelike
13
- * @param {import("../../index.ts").Invocable} groupKey
14
- */
15
- export default async function groupBuiltin(treelike, groupKey) {
16
- const tree = await getTreeArgument(this, arguments, treelike, "group");
17
-
18
- const groupKeyFn = toFunction(groupKey);
19
- // Have the group key function run in this tree.
20
- const extendedGroupKeyFn = groupKeyFn.bind(tree);
21
-
22
- // @ts-ignore
23
- const grouped = await groupTransform(tree, extendedGroupKeyFn);
24
- grouped.parent = tree;
25
- return grouped;
26
- }
@@ -1,30 +0,0 @@
1
- import { trailingSlash, Tree } from "@weborigami/async-tree";
2
- import getTreeArgument from "../common/getTreeArgument.js";
3
-
4
- /**
5
- * Return the interior nodes of the tree. This relies on subtree keys having
6
- * trailing slashes.
7
- *
8
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
- * @this {AsyncTree|null}
11
- * @param {Treelike} [treelike]
12
- */
13
- export default async function inners(treelike) {
14
- const tree = await getTreeArgument(this, arguments, treelike, "inners");
15
-
16
- const result = {
17
- async get(key) {
18
- const value = await tree.get(key);
19
- return Tree.isAsyncTree(value) ? inners.call(this, value) : undefined;
20
- },
21
-
22
- async keys() {
23
- const keys = [...(await tree.keys())];
24
- const subtreeKeys = keys.filter(trailingSlash.has);
25
- return subtreeKeys;
26
- },
27
- };
28
-
29
- return result;
30
- }
package/src/tree/keys.js DELETED
@@ -1,15 +0,0 @@
1
- import getTreeArgument from "../common/getTreeArgument.js";
2
-
3
- /**
4
- * Return the top-level keys in the tree as an array.
5
- *
6
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
7
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
8
- * @this {AsyncTree|null}
9
- * @param {Treelike} [treelike]
10
- */
11
- export default async function keys(treelike) {
12
- const tree = await getTreeArgument(this, arguments, treelike, "keys");
13
- const keys = await tree.keys();
14
- return Array.from(keys);
15
- }
@@ -1,15 +0,0 @@
1
- import getTreeArgument from "../common/getTreeArgument.js";
2
-
3
- /**
4
- * Return the number of keys in the tree.
5
- *
6
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
7
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
8
- * @this {AsyncTree|null}
9
- * @param {Treelike} [treelike]
10
- */
11
- export default async function length(treelike) {
12
- const tree = await getTreeArgument(this, arguments, treelike, "length");
13
- const keys = Array.from(await tree.keys());
14
- return keys.length;
15
- }
package/src/tree/map.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { TreeMapOptions as AsyncTreeMapOptions, Treelike, ValueKeyFn } from "@weborigami/async-tree";
2
- import { AsyncTree } from "@weborigami/types";
3
-
4
- /* Add more properties to TreeMapOptions */
5
- type TreeMapOptions = AsyncTreeMapOptions &{
6
- description?: string;
7
- extension?: string;
8
- needsSourceValue?: boolean;
9
- };
10
-
11
- export default function treeMap(treelike: Treelike, options: ValueKeyFn | TreeMapOptions): AsyncTree;
package/src/tree/map.js DELETED
@@ -1,125 +0,0 @@
1
- import {
2
- isPlainObject,
3
- isUnpackable,
4
- map as mapTransform,
5
- } from "@weborigami/async-tree";
6
- import getTreeArgument from "../common/getTreeArgument.js";
7
- import { toFunction } from "../common/utilities.js";
8
-
9
- /**
10
- * Map a hierarchical tree of keys and values to a new tree of keys and values.
11
- *
12
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
13
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
14
- * @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
15
- * @typedef {import("./map.js").TreeMapOptions} TreeMapOptions
16
- *
17
- * @this {AsyncTree|null}
18
- * @param {Treelike} treelike
19
- * @param {ValueKeyFn|TreeMapOptions} operation
20
- */
21
- export default async function map(treelike, operation) {
22
- if (isUnpackable(operation)) {
23
- operation = await operation.unpack();
24
- }
25
- // The tree in which the map operation happens
26
- const context = this;
27
- const options = extendedOptions(context, operation);
28
-
29
- // The tree we're going to map
30
- const source = await getTreeArgument(
31
- this,
32
- arguments,
33
- treelike,
34
- "map",
35
- options?.deep
36
- );
37
-
38
- const mapped = mapTransform(source, options);
39
- mapped.parent = context;
40
- return mapped;
41
- }
42
-
43
- /**
44
- * Return a function that transforms a tree of keys and values to a new tree of
45
- * keys and values.
46
- *
47
- * @param {AsyncTree|null} context
48
- * @param {ValueKeyFn|TreeMapOptions} operation
49
- */
50
- function extendedOptions(context, operation) {
51
- // Identify whether the map instructions take the form of a value function or
52
- // a dictionary of options.
53
- /** @type {TreeMapOptions} */
54
- let options;
55
- /** @type {ValueKeyFn|undefined} */
56
- let valueFn;
57
- if (isPlainObject(operation)) {
58
- // @ts-ignore
59
- options = operation;
60
- if (`value` in options && !options.value) {
61
- throw new TypeError(`map: The value function is not defined.`);
62
- }
63
- valueFn = options?.value;
64
- } else if (
65
- typeof operation === "function" ||
66
- typeof (/** @type {any} */ (operation)?.unpack) === "function"
67
- ) {
68
- valueFn = operation;
69
- options = {};
70
- } else if (operation === undefined) {
71
- /** @type {any} */
72
- const error = new TypeError(`map: The second parameter was undefined.`);
73
- error.position = 1;
74
- throw error;
75
- } else {
76
- throw new TypeError(
77
- `map: You must specify a value function or options dictionary as the second parameter.`
78
- );
79
- }
80
-
81
- const { deep, extension, needsSourceValue } = options;
82
- const description = options.description ?? `map ${extension ?? ""}`;
83
- let keyFn = options.key;
84
- let inverseKeyFn = options.inverseKey;
85
-
86
- if (valueFn) {
87
- // @ts-ignore
88
- valueFn = toFunction(valueFn);
89
- // By default, run the value function in the context of this tree so that
90
- // Origami builtins can be used as value functions.
91
- // @ts-ignore
92
- const bound = valueFn.bind(context);
93
- // Transfer sidecar functions
94
- // @ts-ignore
95
- Object.assign(bound, valueFn);
96
- valueFn = bound;
97
- }
98
-
99
- if (!extension) {
100
- if (keyFn) {
101
- // Extend the key function to include a value parameter
102
- keyFn = extendKeyFn(keyFn);
103
- }
104
- }
105
-
106
- return {
107
- deep,
108
- description,
109
- extension,
110
- inverseKey: inverseKeyFn,
111
- key: keyFn,
112
- needsSourceValue,
113
- value: valueFn,
114
- };
115
- }
116
-
117
- // Extend the key function to include a value parameter
118
- function extendKeyFn(keyFn) {
119
- keyFn = toFunction(keyFn);
120
- return async function keyWithValueFn(sourceKey, sourceTree) {
121
- const sourceValue = await sourceTree.get(sourceKey);
122
- const resultKey = await keyFn(sourceValue, sourceKey, sourceTree);
123
- return resultKey;
124
- };
125
- }
package/src/tree/mask.js DELETED
@@ -1,19 +0,0 @@
1
- import { mask } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
-
4
- /**
5
- * Apply a mask to a tree
6
- *
7
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
8
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
9
- *
10
- * @this {AsyncTree|null}
11
- * @param {Treelike} sourceTreelike
12
- * @param {Treelike} maskTreelike
13
- */
14
- export default async function maskBuiltin(sourceTreelike, maskTreelike) {
15
- assertTreeIsDefined(this, "mask");
16
- const result = mask(sourceTreelike, maskTreelike);
17
- result.parent = this;
18
- return result;
19
- }
package/src/tree/match.js DELETED
@@ -1,79 +0,0 @@
1
- import { Tree } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
-
4
- /**
5
- * Return a tree with the indicated keys (if provided).
6
- *
7
- * The pattern can a string with a simplified pattern syntax that tries to match
8
- * against the entire key and uses brackets to identify named wildcard values.
9
- * E.g. `[name].html` will match `Alice.html` with wildcard values { name:
10
- * "Alice" }.
11
- *
12
- * The pattern can also be a JavaScript regular expression.
13
- *
14
- * If a key is requested, match against the given pattern and, if matches,
15
- * invokes the given function with an object containing the matched values.
16
- *
17
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
18
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
19
- * @typedef {import("../../index.ts").Invocable} Invocable
20
- *
21
- * @this {AsyncTree|null}
22
- * @param {string|RegExp} pattern
23
- * @param {Invocable} resultFn
24
- * @param {Treelike} [keys]
25
- */
26
- export default function match(pattern, resultFn, keys = []) {
27
- assertTreeIsDefined(this, "match");
28
- let regex;
29
- if (typeof pattern === "string") {
30
- // Convert the simple pattern format into a regular expression.
31
- const regexText = pattern.replace(
32
- /\[(?<variable>.+)\]/g,
33
- (match, p1, offset, string, groups) => `(?<${groups.variable}>.+)`
34
- );
35
- regex = new RegExp(`^${regexText}$`);
36
- } else if (pattern instanceof RegExp) {
37
- regex = pattern;
38
- } else {
39
- throw new Error(`match(): Unsupported pattern`);
40
- }
41
-
42
- const tree = this;
43
-
44
- const result = {
45
- async get(key) {
46
- const keyMatch = regex.exec(key);
47
- if (!keyMatch) {
48
- return undefined;
49
- }
50
-
51
- if (
52
- typeof resultFn !== "function" &&
53
- !(Tree.isAsyncTree(resultFn) && "parent" in resultFn)
54
- ) {
55
- // Simple return value; return as is
56
- return resultFn;
57
- }
58
-
59
- // Copy the `groups` property to a real object
60
- const matches = { ...keyMatch.groups };
61
-
62
- // Invoke the result function with the extended scope.
63
- let value;
64
- if (typeof resultFn === "function") {
65
- value = await resultFn.call(this, matches);
66
- } else {
67
- value = Object.create(resultFn);
68
- }
69
-
70
- return value;
71
- },
72
-
73
- async keys() {
74
- return typeof keys === "function" ? await keys.call(tree) : keys;
75
- },
76
- };
77
-
78
- return result;
79
- }
package/src/tree/merge.js DELETED
@@ -1,41 +0,0 @@
1
- import { isPlainObject, isUnpackable, merge } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
-
4
- /**
5
- * Create a tree that's the result of merging the given trees.
6
- *
7
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
8
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
9
- *
10
- * @this {AsyncTree|null}
11
- * @param {(Treelike|null)[]} trees
12
- */
13
- export default async function treeMerge(...trees) {
14
- assertTreeIsDefined(this, "merge");
15
-
16
- // Filter out null or undefined trees.
17
- /** @type {Treelike[]}
18
- * @ts-ignore */
19
- const filtered = trees.filter((tree) => tree);
20
-
21
- if (filtered.length === 1) {
22
- // Only one tree, no need to merge.
23
- return filtered[0];
24
- }
25
-
26
- // Unpack any packed objects.
27
- const unpacked = await Promise.all(
28
- filtered.map((obj) =>
29
- isUnpackable(obj) ? /** @type {any} */ (obj).unpack() : obj
30
- )
31
- );
32
-
33
- // If all trees are plain objects, return a plain object.
34
- if (unpacked.every((tree) => isPlainObject(tree))) {
35
- return merge(...unpacked);
36
- }
37
-
38
- // Merge the trees.
39
- const result = merge(...unpacked);
40
- return result;
41
- }
@@ -1,20 +0,0 @@
1
- import { paginate } from "@weborigami/async-tree";
2
- import getTreeArgument from "../common/getTreeArgument.js";
3
-
4
- /**
5
- * Return a new grouping of the treelike's values into chunks of the specified
6
- * size.
7
- *
8
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
- *
11
- * @this {AsyncTree|null}
12
- * @param {Treelike} [treelike]
13
- * @param {number} [size=10]
14
- */
15
- export default async function paginateBuiltin(treelike, size = 10) {
16
- const tree = await getTreeArgument(this, arguments, treelike, "paginate");
17
- const paginated = await paginate(tree, size);
18
- paginated.parent = this;
19
- return paginated;
20
- }
@@ -1,15 +0,0 @@
1
- import getTreeArgument from "../common/getTreeArgument.js";
2
-
3
- /**
4
- * Returns the parent of the current tree.
5
- *
6
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
7
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
8
- *
9
- * @this {AsyncTree|null}
10
- * @param {Treelike} [treelike]
11
- */
12
- export default async function parent(treelike) {
13
- const tree = await getTreeArgument(this, arguments, treelike, "parent");
14
- return tree.parent;
15
- }
package/src/tree/plain.js DELETED
@@ -1,15 +0,0 @@
1
- import { Tree } from "@weborigami/async-tree";
2
- import getTreeArgument from "../common/getTreeArgument.js";
3
-
4
- /**
5
- * Return the interior nodes of the tree.
6
- *
7
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
8
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
9
- * @this {AsyncTree|null}
10
- * @param {Treelike} [treelike]
11
- */
12
- export default async function plain(treelike) {
13
- const tree = await getTreeArgument(this, arguments, treelike, "plain");
14
- return Tree.plain(tree);
15
- }
@@ -1,19 +0,0 @@
1
- import { setParent } from "@weborigami/async-tree";
2
- import regExpKeys from "@weborigami/async-tree/src/operations/regExpKeys.js";
3
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
4
-
5
- /**
6
- * Define a tree whose keys are regular expression strings.
7
- *
8
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
- *
11
- * @param {Treelike} tree
12
- * @this {AsyncTree|null}
13
- */
14
- export default async function regExpKeysBuiltin(tree) {
15
- assertTreeIsDefined(this, "regExpKeys");
16
- const result = regExpKeys(tree);
17
- setParent(this, result);
18
- return result;
19
- }
@@ -1,17 +0,0 @@
1
- import { reverse } from "@weborigami/async-tree";
2
- import getTreeArgument from "../common/getTreeArgument.js";
3
-
4
- /**
5
- * Reverse the order of the top-level keys in the tree.
6
- *
7
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
8
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
9
- *
10
- * @this {AsyncTree|null}
11
- * @param {Treelike} [treelike]
12
- */
13
- export default async function reverseBuiltin(treelike) {
14
- const tree = await getTreeArgument(this, arguments, treelike, "reverse");
15
- const reversed = reverse(tree);
16
- return reversed;
17
- }
@@ -1,49 +0,0 @@
1
- import { Tree } from "@weborigami/async-tree";
2
-
3
- /**
4
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
5
- *
6
- * @this {import("@weborigami/types").AsyncTree|null}
7
- * @param {Treelike} target
8
- * @param {Treelike} source
9
- */
10
- export default async function setDeep(target, source) {
11
- const targetTree = Tree.from(target, { parent: this });
12
- const sourceTree = Tree.from(source, { parent: this });
13
- await applyUpdates(sourceTree, targetTree);
14
- }
15
-
16
- // Apply all updates from the source to the target.
17
- async function applyUpdates(source, target) {
18
- // Fire off requests to update all keys, then wait for all of them to finish.
19
- const promises = [];
20
- for (const key of await source.keys()) {
21
- const updateKeyPromise = applyUpdateForKey(source, target, key);
22
- promises.push(updateKeyPromise);
23
- }
24
- await Promise.all(promises);
25
-
26
- // HACK: Transforms like KeysTransform that maintain caches will need to
27
- // recalculate things now that updates have been applied. This should be an
28
- // automatic part of calling set() -- but triggering those changes inside
29
- // set() produces cases where set() and get() calls can be interleaved. The
30
- // atomicity of set() needs to be reconsidered. For now, we work around the
31
- // problem by triggering `onChange` after the updates have been applied.
32
- target.onChange?.();
33
- }
34
-
35
- // Copy the value for the given key from the source to the target.
36
- async function applyUpdateForKey(source, target, key) {
37
- const sourceValue = await source.get(key);
38
- if (Tree.isAsyncTree(sourceValue)) {
39
- const targetValue = await target.get(key);
40
- if (Tree.isAsyncTree(targetValue)) {
41
- // Both source and target are async dictionaries; recurse.
42
- await applyUpdates(sourceValue, targetValue);
43
- return;
44
- }
45
- }
46
-
47
- // Copy the value from the source to the target.
48
- await target.set(key, sourceValue);
49
- }
@@ -1,57 +0,0 @@
1
- import getTreeArgument from "../common/getTreeArgument.js";
2
-
3
- /**
4
- * Return a new tree with the original's keys shuffled
5
- *
6
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
7
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
8
- *
9
- * @this {AsyncTree|null}
10
- * @param {Treelike} [treelike]
11
- * @param {boolean} [reshuffle]
12
- */
13
- export default async function shuffleTree(treelike, reshuffle = false) {
14
- // Special case: If the treelike is an array, shuffle it directly. Otherwise
15
- // we'll end up shuffling the array's indexes, and if this is directly
16
- // displayed by the ori CLI, this will end up creating a plain object. Even
17
- // though this object will be created with the keys in the correct shuffled
18
- // order, a JS object will always return numeric keys in numeric order --
19
- // undoing the shuffle.
20
- if (Array.isArray(treelike)) {
21
- const array = treelike.slice();
22
- shuffle(array);
23
- return array;
24
- }
25
-
26
- const tree = await getTreeArgument(this, arguments, treelike, "shuffle");
27
-
28
- let keys;
29
- return {
30
- async get(key) {
31
- return tree.get(key);
32
- },
33
-
34
- async keys() {
35
- if (!keys || reshuffle) {
36
- keys = Array.from(await tree.keys());
37
- shuffle(keys);
38
- }
39
- return keys;
40
- },
41
- };
42
- }
43
-
44
- /*
45
- * Shuffle an array.
46
- *
47
- * Performs a Fisher-Yates shuffle. From http://sedition.com/perl/javascript-fy.html
48
- */
49
- export function shuffle(array) {
50
- let i = array.length;
51
- while (--i >= 0) {
52
- const j = Math.floor(Math.random() * (i + 1));
53
- const temp = array[i];
54
- array[i] = array[j];
55
- array[j] = temp;
56
- }
57
- }
package/src/tree/sort.js DELETED
@@ -1,52 +0,0 @@
1
- import { sort as sortTransform } from "@weborigami/async-tree";
2
- import getTreeArgument from "../common/getTreeArgument.js";
3
- import { toFunction } from "../common/utilities.js";
4
-
5
- /**
6
- * Return a new tree with the original's keys sorted.
7
- *
8
- * If the `options` include a `sortKey` function, that will be invoked for each
9
- * key in the tree to produce a sort key. If no `sortKey` function is provided,
10
- * the original keys will be used as sort keys.
11
- *
12
- * If the `options` include a `compare` function, that will be used to compare
13
- * sort keys.
14
- *
15
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
16
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
17
- * @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
18
- * @typedef {{ compare?: (a: any, b: any) => number, sortKey?: ValueKeyFn }}
19
- * SortOptions
20
- *
21
- * @this {AsyncTree|null}
22
- * @param {Treelike} [treelike]
23
- * @param {SortOptions|ValueKeyFn} [options]
24
- */
25
- export default async function sortBuiltin(treelike, options) {
26
- const tree = await getTreeArgument(this, arguments, treelike, "sort");
27
-
28
- if (typeof options === "function") {
29
- // Take the function as the `sortKey` option
30
- options = { sortKey: options };
31
- }
32
-
33
- const compare = options?.compare;
34
- let extendedSortKeyFn;
35
- if (options?.sortKey) {
36
- const originalSortKey = toFunction(options?.sortKey);
37
- const parent = this;
38
- extendedSortKeyFn = async (key, tree) => {
39
- const value = await tree.get(key);
40
- const sortKey = await originalSortKey.call(parent, value, key);
41
- return sortKey;
42
- };
43
- }
44
-
45
- const sorted = await sortTransform(tree, {
46
- compare,
47
- sortKey: extendedSortKeyFn,
48
- });
49
-
50
- sorted.parent = this;
51
- return sorted;
52
- }