@weborigami/async-tree 0.5.3 → 0.5.5

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 (159) hide show
  1. package/index.ts +16 -6
  2. package/package.json +2 -2
  3. package/shared.js +20 -30
  4. package/src/Tree.js +62 -502
  5. package/src/constants.js +2 -0
  6. package/src/drivers/BrowserFileTree.js +9 -10
  7. package/src/drivers/DeepMapTree.js +3 -3
  8. package/src/drivers/DeepObjectTree.js +4 -5
  9. package/src/drivers/DeferredTree.js +2 -2
  10. package/src/drivers/FileTree.js +11 -33
  11. package/src/drivers/FunctionTree.js +1 -1
  12. package/src/drivers/MapTree.js +6 -6
  13. package/src/drivers/ObjectTree.js +4 -3
  14. package/src/drivers/SetTree.js +1 -1
  15. package/src/drivers/SiteTree.js +1 -1
  16. package/src/drivers/constantTree.js +1 -1
  17. package/src/extension.js +5 -3
  18. package/src/jsonKeys.js +5 -7
  19. package/src/operations/addNextPrevious.js +10 -9
  20. package/src/operations/assign.js +40 -0
  21. package/src/operations/cache.js +18 -12
  22. package/src/operations/cachedKeyFunctions.js +15 -4
  23. package/src/operations/clear.js +20 -0
  24. package/src/operations/concat.js +17 -0
  25. package/src/operations/deepMap.js +25 -0
  26. package/src/operations/deepMerge.js +11 -25
  27. package/src/operations/deepReverse.js +6 -7
  28. package/src/operations/deepTake.js +6 -7
  29. package/src/operations/deepText.js +4 -4
  30. package/src/operations/deepValuesIterator.js +8 -6
  31. package/src/operations/defineds.js +32 -0
  32. package/src/operations/delete.js +20 -0
  33. package/src/operations/entries.js +16 -0
  34. package/src/operations/extensionKeyFunctions.js +1 -1
  35. package/src/operations/filter.js +7 -8
  36. package/src/operations/first.js +18 -0
  37. package/src/operations/forEach.js +20 -0
  38. package/src/operations/from.js +77 -0
  39. package/src/operations/fromFn.js +26 -0
  40. package/src/operations/globKeys.js +8 -8
  41. package/src/operations/group.js +9 -7
  42. package/src/operations/has.js +16 -0
  43. package/src/operations/indent.js +4 -2
  44. package/src/operations/inners.js +29 -0
  45. package/src/operations/invokeFunctions.js +5 -4
  46. package/src/operations/isAsyncMutableTree.js +15 -0
  47. package/src/operations/isAsyncTree.js +21 -0
  48. package/src/operations/isTraversable.js +15 -0
  49. package/src/operations/isTreelike.js +33 -0
  50. package/src/operations/json.js +4 -3
  51. package/src/operations/keys.js +14 -0
  52. package/src/operations/length.js +15 -0
  53. package/src/operations/map.js +157 -95
  54. package/src/operations/mapExtension.js +27 -0
  55. package/src/operations/mapReduce.js +44 -0
  56. package/src/operations/mask.js +18 -16
  57. package/src/operations/match.js +74 -0
  58. package/src/operations/merge.js +22 -20
  59. package/src/operations/paginate.js +3 -5
  60. package/src/operations/parent.js +13 -0
  61. package/src/operations/paths.js +51 -0
  62. package/src/operations/plain.js +34 -0
  63. package/src/operations/regExpKeys.js +4 -5
  64. package/src/operations/remove.js +14 -0
  65. package/src/operations/reverse.js +4 -6
  66. package/src/operations/root.js +17 -0
  67. package/src/operations/scope.js +4 -6
  68. package/src/operations/setDeep.js +50 -0
  69. package/src/operations/shuffle.js +46 -0
  70. package/src/operations/sort.js +19 -12
  71. package/src/operations/take.js +3 -5
  72. package/src/operations/text.js +3 -3
  73. package/src/operations/toFunction.js +14 -0
  74. package/src/operations/traverse.js +25 -0
  75. package/src/operations/traverseOrThrow.js +64 -0
  76. package/src/operations/traversePath.js +16 -0
  77. package/src/operations/values.js +15 -0
  78. package/src/operations/withKeys.js +33 -0
  79. package/src/utilities/TypedArray.js +2 -0
  80. package/src/utilities/box.js +20 -0
  81. package/src/utilities/castArraylike.js +38 -0
  82. package/src/utilities/getParent.js +33 -0
  83. package/src/utilities/getRealmObjectPrototype.js +19 -0
  84. package/src/utilities/getTreeArgument.js +43 -0
  85. package/src/utilities/isPacked.js +20 -0
  86. package/src/utilities/isPlainObject.js +29 -0
  87. package/src/utilities/isPrimitive.js +13 -0
  88. package/src/utilities/isStringlike.js +25 -0
  89. package/src/utilities/isUnpackable.js +13 -0
  90. package/src/utilities/keysFromPath.js +34 -0
  91. package/src/utilities/naturalOrder.js +9 -0
  92. package/src/utilities/pathFromKeys.js +18 -0
  93. package/src/utilities/setParent.js +38 -0
  94. package/src/utilities/toFunction.js +41 -0
  95. package/src/utilities/toPlainValue.js +95 -0
  96. package/src/utilities/toString.js +37 -0
  97. package/test/drivers/ExplorableSiteTree.test.js +1 -1
  98. package/test/drivers/FileTree.test.js +1 -1
  99. package/test/drivers/calendarTree.test.js +1 -1
  100. package/test/jsonKeys.test.js +1 -1
  101. package/test/operations/assign.test.js +54 -0
  102. package/test/operations/cache.test.js +1 -1
  103. package/test/operations/cachedKeyFunctions.test.js +16 -16
  104. package/test/operations/clear.test.js +34 -0
  105. package/test/operations/deepMap.test.js +29 -0
  106. package/test/operations/deepMerge.test.js +2 -6
  107. package/test/operations/deepReverse.test.js +1 -1
  108. package/test/operations/defineds.test.js +25 -0
  109. package/test/operations/delete.test.js +20 -0
  110. package/test/operations/entries.test.js +18 -0
  111. package/test/operations/extensionKeyFunctions.test.js +10 -10
  112. package/test/operations/first.test.js +15 -0
  113. package/test/operations/fixtures/README.md +1 -0
  114. package/test/operations/forEach.test.js +22 -0
  115. package/test/operations/from.test.js +67 -0
  116. package/test/operations/globKeys.test.js +3 -3
  117. package/test/operations/has.test.js +15 -0
  118. package/test/operations/inners.test.js +30 -0
  119. package/test/operations/invokeFunctions.test.js +1 -1
  120. package/test/operations/isAsyncMutableTree.test.js +17 -0
  121. package/test/operations/isAsyncTree.test.js +26 -0
  122. package/test/operations/isTreelike.test.js +13 -0
  123. package/test/operations/keys.test.js +15 -0
  124. package/test/operations/length.test.js +15 -0
  125. package/test/operations/map.test.js +62 -45
  126. package/test/operations/mapExtension.test.js +0 -0
  127. package/test/operations/mapReduce.test.js +23 -0
  128. package/test/operations/mask.test.js +1 -1
  129. package/test/operations/match.test.js +33 -0
  130. package/test/operations/merge.test.js +23 -9
  131. package/test/operations/paginate.test.js +2 -1
  132. package/test/operations/parent.test.js +15 -0
  133. package/test/operations/paths.test.js +40 -0
  134. package/test/operations/plain.test.js +69 -0
  135. package/test/operations/reverse.test.js +1 -1
  136. package/test/operations/scope.test.js +1 -1
  137. package/test/operations/setDeep.test.js +53 -0
  138. package/test/operations/shuffle.test.js +18 -0
  139. package/test/operations/sort.test.js +3 -3
  140. package/test/operations/toFunction.test.js +16 -0
  141. package/test/operations/traverse.test.js +43 -0
  142. package/test/operations/traversePath.test.js +16 -0
  143. package/test/operations/values.test.js +18 -0
  144. package/test/operations/withKeys.test.js +21 -0
  145. package/test/utilities/box.test.js +26 -0
  146. package/test/utilities/getRealmObjectPrototype.test.js +11 -0
  147. package/test/utilities/isPlainObject.test.js +13 -0
  148. package/test/utilities/keysFromPath.test.js +14 -0
  149. package/test/utilities/naturalOrder.test.js +11 -0
  150. package/test/utilities/pathFromKeys.test.js +12 -0
  151. package/test/utilities/setParent.test.js +34 -0
  152. package/test/utilities/toFunction.test.js +34 -0
  153. package/test/utilities/toPlainValue.test.js +27 -0
  154. package/test/utilities/toString.test.js +22 -0
  155. package/src/Tree.d.ts +0 -24
  156. package/src/utilities.d.ts +0 -21
  157. package/src/utilities.js +0 -439
  158. package/test/Tree.test.js +0 -407
  159. package/test/utilities.test.js +0 -141
@@ -0,0 +1,18 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import values from "../../src/operations/values.js";
4
+
5
+ describe("values", () => {
6
+ test("returns the tree's values as an array", async () => {
7
+ const fixture = {
8
+ "Alice.md": "Hello, **Alice**.",
9
+ "Bob.md": "Hello, **Bob**.",
10
+ "Carol.md": "Hello, **Carol**.",
11
+ };
12
+ assert.deepEqual(await values(fixture), [
13
+ "Hello, **Alice**.",
14
+ "Hello, **Bob**.",
15
+ "Hello, **Carol**.",
16
+ ]);
17
+ });
18
+ });
@@ -0,0 +1,21 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import { Tree } from "../../src/internal.js";
4
+ import withKeys from "../../src/operations/withKeys.js";
5
+
6
+ describe("withKeys", () => {
7
+ test("applies the indicated keys", async () => {
8
+ const result = await withKeys(
9
+ {
10
+ a: 1,
11
+ b: 2,
12
+ c: 3,
13
+ },
14
+ ["a", "c"]
15
+ );
16
+ assert.deepEqual(await Tree.plain(result), {
17
+ a: 1,
18
+ c: 3,
19
+ });
20
+ });
21
+ });
@@ -0,0 +1,26 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import box from "../../src/utilities/box.js";
4
+
5
+ describe("box", () => {
6
+ test("returns a boxed value", () => {
7
+ const string = "string";
8
+ const stringObject = box(string);
9
+ assert(stringObject instanceof String);
10
+ assert.equal(stringObject, string);
11
+
12
+ const number = 1;
13
+ const numberObject = box(number);
14
+ assert(numberObject instanceof Number);
15
+ assert.equal(numberObject, number);
16
+
17
+ const boolean = true;
18
+ const booleanObject = box(boolean);
19
+ assert(booleanObject instanceof Boolean);
20
+ assert.equal(booleanObject, boolean);
21
+
22
+ const object = {};
23
+ const boxedObject = box(object);
24
+ assert.equal(boxedObject, object);
25
+ });
26
+ });
@@ -0,0 +1,11 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import getRealmObjectPrototype from "../../src/utilities/getRealmObjectPrototype.js";
4
+
5
+ describe("getRealmObjectPrototype", () => {
6
+ test("returns the object's root prototype", () => {
7
+ const object = {};
8
+ const proto = getRealmObjectPrototype(object);
9
+ assert.equal(proto, Object.prototype);
10
+ });
11
+ });
@@ -0,0 +1,13 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import isPlainObject from "../../src/utilities/isPlainObject.js";
4
+
5
+ describe("isPlainObject", () => {
6
+ test("returns true if the object is a plain object", () => {
7
+ assert.equal(isPlainObject({}), true);
8
+ assert.equal(isPlainObject(new Object()), true);
9
+ assert.equal(isPlainObject(Object.create(null)), true);
10
+ class Foo {}
11
+ assert.equal(isPlainObject(new Foo()), false);
12
+ });
13
+ });
@@ -0,0 +1,14 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import keysFromPath from "../../src/utilities/keysFromPath.js";
4
+
5
+ describe("keysFromPath", () => {
6
+ test("returns the keys from a slash-separated path", () => {
7
+ assert.deepEqual(keysFromPath(""), []);
8
+ assert.deepEqual(keysFromPath("/"), []);
9
+ assert.deepEqual(keysFromPath("a/b/c"), ["a/", "b/", "c"]);
10
+ assert.deepEqual(keysFromPath("a/b/c/"), ["a/", "b/", "c/"]);
11
+ assert.deepEqual(keysFromPath("/foo/"), ["foo/"]);
12
+ assert.deepEqual(keysFromPath("a///b"), ["a/", "b"]);
13
+ });
14
+ });
@@ -0,0 +1,11 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import naturalOrder from "../../src/utilities/naturalOrder.js";
4
+
5
+ describe("naturalOrder", () => {
6
+ test("compares strings in natural order", () => {
7
+ const strings = ["file10", "file1", "file9"];
8
+ strings.sort(naturalOrder);
9
+ assert.deepEqual(strings, ["file1", "file9", "file10"]);
10
+ });
11
+ });
@@ -0,0 +1,12 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import pathFromKeys from "../../src/utilities/pathFromKeys.js";
4
+
5
+ describe("pathFromKeys", () => {
6
+ test("returns a slash-separated path from keys", () => {
7
+ assert.equal(pathFromKeys([]), "");
8
+ assert.equal(pathFromKeys(["a", "b", "c"]), "a/b/c");
9
+ assert.equal(pathFromKeys(["a/", "b/", "c"]), "a/b/c");
10
+ assert.equal(pathFromKeys(["a/", "b/", "c/"]), "a/b/c/");
11
+ });
12
+ });
@@ -0,0 +1,34 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import ObjectTree from "../../src/drivers/ObjectTree.js";
4
+ import * as symbols from "../../src/symbols.js";
5
+ import setParent from "../../src/utilities/setParent.js";
6
+
7
+ describe("setParent", () => {
8
+ test("sets a child's parent", () => {
9
+ const parent = new ObjectTree({});
10
+
11
+ // Set [symbols.parent] on a plain object.
12
+ const object = {};
13
+ setParent(object, parent);
14
+ assert.equal(object[symbols.parent], parent);
15
+
16
+ // Leave [symbols.parent] alone if it's already set.
17
+ const childWithParent = {
18
+ [symbols.parent]: "parent",
19
+ };
20
+ setParent(childWithParent, parent);
21
+ assert.equal(childWithParent[symbols.parent], "parent");
22
+
23
+ // Set `parent` on a tree.
24
+ const tree = new ObjectTree({});
25
+ setParent(tree, parent);
26
+ assert.equal(tree.parent, parent);
27
+
28
+ // Leave `parent` alone if it's already set.
29
+ const treeWithParent = new ObjectTree({});
30
+ treeWithParent.parent = "parent";
31
+ setParent(treeWithParent, parent);
32
+ assert.equal(treeWithParent.parent, "parent");
33
+ });
34
+ });
@@ -0,0 +1,34 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import ObjectTree from "../../src/drivers/ObjectTree.js";
4
+ import toFunction from "../../src/utilities/toFunction.js";
5
+
6
+ describe("toFunction", () => {
7
+ test("returns a plain function as is", () => {
8
+ const fn = () => {};
9
+ assert.equal(toFunction(fn), fn);
10
+ });
11
+
12
+ test("returns a tree's getter as a function", async () => {
13
+ const tree = new ObjectTree({
14
+ a: 1,
15
+ });
16
+ const fn = toFunction(tree);
17
+ // @ts-ignore
18
+ assert.equal(await fn("a"), 1);
19
+ });
20
+
21
+ test("can use a packed object's `unpack` as a function", async () => {
22
+ const obj = new String();
23
+ /** @type {any} */ (obj).unpack = () => () => "result";
24
+ const fn = toFunction(obj);
25
+ // @ts-ignore
26
+ assert.equal(await fn(), "result");
27
+ });
28
+
29
+ test("returns null for something that's not a function", () => {
30
+ // @ts-ignore
31
+ const result = toFunction("this is not a function");
32
+ assert.equal(result, null);
33
+ });
34
+ });
@@ -0,0 +1,27 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import toPlainValue from "../../src/utilities/toPlainValue.js";
4
+
5
+ describe("toPlainValue", () => {
6
+ test("returns the plainest representation of an object", async () => {
7
+ class User {
8
+ constructor(name) {
9
+ this.name = name;
10
+ }
11
+ }
12
+
13
+ assert.equal(await toPlainValue(1), 1);
14
+ assert.equal(await toPlainValue("string"), "string");
15
+ assert.deepEqual(await toPlainValue({ a: 1 }), { a: 1 });
16
+ assert.equal(
17
+ await toPlainValue(new TextEncoder().encode("bytes")),
18
+ "bytes"
19
+ );
20
+ // ArrayBuffer with non-printable characters should be returned as base64
21
+ assert.equal(await toPlainValue(new Uint8Array([1, 2, 3]).buffer), "AQID");
22
+ assert.equal(await toPlainValue(async () => "result"), "result");
23
+ assert.deepEqual(await toPlainValue(new User("Alice")), {
24
+ name: "Alice",
25
+ });
26
+ });
27
+ });
@@ -0,0 +1,22 @@
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import toString from "../../src/utilities/toString.js";
4
+
5
+ describe("toString", () => {
6
+ test("returns the value of an object's `toString` method", () => {
7
+ const object = {
8
+ toString: () => "text",
9
+ };
10
+ assert.equal(toString(object), "text");
11
+ });
12
+
13
+ test("returns null for an object with no useful `toString`", () => {
14
+ const object = {};
15
+ assert.equal(toString(object), null);
16
+ });
17
+
18
+ test("decodes an ArrayBuffer as UTF-8", () => {
19
+ const arrayBuffer = new TextEncoder().encode("text").buffer;
20
+ assert.equal(toString(arrayBuffer), "text");
21
+ });
22
+ });
package/src/Tree.d.ts DELETED
@@ -1,24 +0,0 @@
1
- import type { AsyncMutableTree, AsyncTree } from "@weborigami/types";
2
- import { PlainObject, ReduceFn, Treelike, TreeMapOptions, ValueKeyFn } from "../index.ts";
3
-
4
- export function assign(target: Treelike, source: Treelike): Promise<AsyncTree>;
5
- export function clear(AsyncTree: AsyncMutableTree): Promise<void>;
6
- export function entries(AsyncTree: AsyncTree): Promise<IterableIterator<any>>;
7
- export function forEach(AsyncTree: AsyncTree, callbackfn: (value: any, key: any) => Promise<void>): Promise<void>;
8
- export function from(obj: any, options?: { deep?: boolean, parent?: AsyncTree|null }): AsyncTree;
9
- export function has(AsyncTree: AsyncTree, key: any): Promise<boolean>;
10
- export function isAsyncMutableTree(obj: any): obj is AsyncMutableTree;
11
- export function isAsyncTree(obj: any): obj is AsyncTree;
12
- export function isTraversable(obj: any): boolean;
13
- export function isTreelike(obj: any): obj is Treelike;
14
- export function map(tree: Treelike, options: TreeMapOptions|ValueKeyFn): AsyncTree;
15
- export function mapReduce(tree: Treelike, mapFn: ValueKeyFn | null, reduceFn: ReduceFn): Promise<any>;
16
- export function paths(tree: Treelike, options?: { assumeSlashes?: boolean, base?: string }): string[];
17
- export function plain(tree: Treelike): Promise<PlainObject>;
18
- export function root(tree: Treelike): AsyncTree;
19
- export function remove(AsyncTree: AsyncMutableTree, key: any): Promise<boolean>;
20
- export function toFunction(tree: Treelike): Function;
21
- export function traverse(tree: Treelike, ...keys: any[]): Promise<any>;
22
- export function traverseOrThrow(tree: Treelike, ...keys: any[]): Promise<any>;
23
- export function traversePath(tree: Treelike, path: string): Promise<any>;
24
- export function values(tree: Treelike): Promise<IterableIterator<any>>;
@@ -1,21 +0,0 @@
1
- import { AsyncTree } from "@weborigami/types";
2
- import { Packed, PlainObject, StringLike } from "../index.ts";
3
-
4
- export function assertIsTreelike(object: any, operation: string, position?: number): void;
5
- export function box(value: any): any;
6
- export function castArrayLike(keys: any[], values: any[]): any;
7
- export function getParent(object: any, options?: any): AsyncTree|null;
8
- export function getRealmObjectPrototype(object: any): any;
9
- export const hiddenFileNames: string[];
10
- export function isPacked(obj: any): obj is Packed;
11
- export function isPlainObject(obj: any): obj is PlainObject;
12
- export function isPrimitive(obj: any): boolean;
13
- export function isStringLike(obj: any): obj is StringLike;
14
- export function isUnpackable(obj): obj is { unpack: () => any };
15
- export function keysFromPath(path: string): string[];
16
- export const naturalOrder: (a: string, b: string) => number;
17
- export function pathFromKeys(keys: string[]): string;
18
- export function pipeline(start: any, ...functions: Function[]): Promise<any>;
19
- export function setParent(child: any, parent: AsyncTree|null): void;
20
- export function toPlainValue(object: any): Promise<any>;
21
- export function toString(object: any): string;