@weborigami/async-tree 0.0.45 → 0.0.47

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 (49) hide show
  1. package/index.ts +18 -1
  2. package/main.js +4 -5
  3. package/package.json +4 -4
  4. package/src/BrowserFileTree.js +1 -1
  5. package/src/DeepMapTree.js +1 -1
  6. package/src/DeepObjectTree.js +1 -2
  7. package/src/DeferredTree.js +22 -9
  8. package/src/FileTree.js +24 -20
  9. package/src/FunctionTree.js +0 -4
  10. package/src/MapTree.js +1 -1
  11. package/src/ObjectTree.js +1 -1
  12. package/src/SetTree.js +1 -1
  13. package/src/SiteTree.js +1 -6
  14. package/src/Tree.d.ts +2 -1
  15. package/src/Tree.js +56 -45
  16. package/src/internal.js +15 -0
  17. package/src/keysJson.js +1 -1
  18. package/src/operations/cache.js +9 -5
  19. package/src/operations/mergeDeep.js +1 -1
  20. package/src/symbols.js +1 -0
  21. package/src/transforms/{cachedKeyMaps.js → cachedKeyFunctions.js} +10 -10
  22. package/src/transforms/groupBy.js +4 -4
  23. package/src/transforms/{keyMapsForExtensions.js → keyFunctionsForExtensions.js} +4 -4
  24. package/src/transforms/map.js +29 -28
  25. package/src/transforms/regExpKeys.js +3 -2
  26. package/src/transforms/sort.js +4 -1
  27. package/src/transforms/sortBy.js +4 -1
  28. package/src/utilities.d.ts +3 -1
  29. package/src/utilities.js +37 -9
  30. package/test/BrowserFileTree.test.js +1 -1
  31. package/test/DeepObjectTree.test.js +1 -2
  32. package/test/DeferredTree.test.js +1 -2
  33. package/test/FileTree.test.js +1 -1
  34. package/test/FunctionTree.test.js +0 -6
  35. package/test/ObjectTree.test.js +1 -2
  36. package/test/SetTree.test.js +1 -1
  37. package/test/SiteTree.test.js +1 -1
  38. package/test/Tree.test.js +12 -22
  39. package/test/operations/cache.test.js +1 -2
  40. package/test/operations/merge.test.js +1 -1
  41. package/test/operations/mergeDeep.test.js +1 -2
  42. package/test/transforms/cachedKeyMaps.test.js +13 -13
  43. package/test/transforms/groupBy.test.js +1 -1
  44. package/test/transforms/keyMapsForExtensions.test.js +20 -21
  45. package/test/transforms/map.test.js +36 -41
  46. package/test/transforms/regExpKeys.test.js +1 -2
  47. package/test/transforms/sort.test.js +1 -1
  48. package/test/transforms/sortBy.test.js +1 -1
  49. package/test/transforms/sortNatural.test.js +1 -1
@@ -2,14 +2,14 @@
2
2
  * Given a source resultExtension and a result resultExtension, return a pair of key
3
3
  * functions that map between them.
4
4
  *
5
- * The resulting `inverseKeyMap` and `keyMap` functions are compatible with those
5
+ * The resulting `inverseKey` and `key` functions are compatible with those
6
6
  * expected by map and other transforms.
7
7
  *
8
8
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
9
  * @param {{ resultExtension?: string, sourceExtension: string }}
10
10
  * options
11
11
  */
12
- export default function keyMapsForExtensions({
12
+ export default function keyFunctionsForExtensions({
13
13
  resultExtension,
14
14
  sourceExtension,
15
15
  }) {
@@ -18,12 +18,12 @@ export default function keyMapsForExtensions({
18
18
  }
19
19
 
20
20
  return {
21
- async inverseKeyMap(resultKey, tree) {
21
+ async inverseKey(resultKey, tree) {
22
22
  const basename = matchExtension(resultKey, resultExtension);
23
23
  return basename ? `${basename}${dotPrefix(sourceExtension)}` : undefined;
24
24
  },
25
25
 
26
- async keyMap(sourceKey, tree) {
26
+ async key(sourceKey, tree) {
27
27
  const basename = matchExtension(sourceKey, sourceExtension);
28
28
  return basename ? `${basename}${dotPrefix(resultExtension)}` : undefined;
29
29
  },
@@ -1,4 +1,4 @@
1
- import * as Tree from "../Tree.js";
1
+ import { Tree } from "../internal.js";
2
2
 
3
3
  /**
4
4
  * Return a transform function that maps the keys and/or values of a tree.
@@ -6,63 +6,64 @@ import * as Tree from "../Tree.js";
6
6
  * @typedef {import("../../index.ts").KeyFn} KeyFn
7
7
  * @typedef {import("../../index.ts").ValueKeyFn} ValueKeyFn
8
8
  *
9
- * @param {ValueKeyFn|{ deep?: boolean, description?: string, needsSourceValue?: boolean, inverseKeyMap?: KeyFn, keyMap?: KeyFn, valueMap?: ValueKeyFn }} options
9
+ * @param {ValueKeyFn|{ deep?: boolean, description?: string, needsSourceValue?: boolean, inverseKey?: KeyFn, key?: KeyFn, value?: ValueKeyFn }} options
10
10
  */
11
- export default function createMapTransform(options) {
11
+ export default function createMapTransform(options = {}) {
12
12
  let deep;
13
13
  let description;
14
- let inverseKeyMap;
15
- let keyMap;
14
+ let inverseKeyFn;
15
+ let keyFn;
16
16
  let needsSourceValue;
17
- let valueMap;
17
+ let valueFn;
18
18
  if (typeof options === "function") {
19
- // Take the single function argument as the valueMap
20
- valueMap = options;
19
+ // Take the single function argument as the valueFn
20
+ valueFn = options;
21
21
  } else {
22
22
  deep = options.deep;
23
23
  description = options.description;
24
- inverseKeyMap = options.inverseKeyMap;
25
- keyMap = options.keyMap;
24
+ inverseKeyFn = options.inverseKey;
25
+ keyFn = options.key;
26
26
  needsSourceValue = options.needsSourceValue;
27
- valueMap = options.valueMap;
27
+ valueFn = options.value;
28
28
  }
29
29
 
30
30
  deep ??= false;
31
31
  description ??= "key/value map";
32
32
  // @ts-ignore
33
- inverseKeyMap ??= valueMap?.inverseKeyMap;
33
+ inverseKeyFn ??= valueFn?.inverseKey;
34
34
  // @ts-ignore
35
- keyMap ??= valueMap?.keyMap;
35
+ keyFn ??= valueFn?.key;
36
36
  needsSourceValue ??= true;
37
37
 
38
- if ((keyMap && !inverseKeyMap) || (!keyMap && inverseKeyMap)) {
38
+ if ((keyFn && !inverseKeyFn) || (!keyFn && inverseKeyFn)) {
39
39
  throw new TypeError(
40
- `map: You must specify both keyMap and inverseKeyMap, or neither.`
40
+ `map: You must specify both key and inverseKey functions, or neither.`
41
41
  );
42
42
  }
43
43
 
44
44
  /**
45
45
  * @type {import("../../index.ts").TreeTransform}
46
46
  */
47
- return function map(tree) {
47
+ return function map(treelike) {
48
+ const tree = Tree.from(treelike);
48
49
  // The transformed tree is actually an extension of the original tree's
49
50
  // prototype chain. This allows the transformed tree to inherit any
50
- // properties/methods that do not need to be specified. For example, the
51
- // `parent` of the transformed tree is the original tree's parent.
51
+ // properties/methods. For example, the `parent` of the transformed tree is
52
+ // the original tree's parent.
52
53
  const transformed = Object.create(tree);
53
54
 
54
55
  transformed.description = description;
55
56
 
56
- if (keyMap || valueMap) {
57
+ if (keyFn || valueFn) {
57
58
  transformed.get = async (resultKey) => {
58
59
  // Step 1: Map the result key to the source key.
59
60
  const isSubtree = deep && (await Tree.isKeyForSubtree(tree, resultKey));
60
61
  const sourceKey =
61
- !isSubtree && inverseKeyMap
62
- ? await inverseKeyMap(resultKey, tree)
62
+ !isSubtree && inverseKeyFn
63
+ ? await inverseKeyFn(resultKey, tree)
63
64
  : resultKey;
64
65
 
65
- if (!sourceKey) {
66
+ if (sourceKey == null) {
66
67
  // No source key means no value.
67
68
  return undefined;
68
69
  }
@@ -85,9 +86,9 @@ export default function createMapTransform(options) {
85
86
  } else if (deep && Tree.isAsyncTree(sourceValue)) {
86
87
  // Map a subtree.
87
88
  resultValue = map(sourceValue);
88
- } else if (valueMap) {
89
+ } else if (valueFn) {
89
90
  // Map a single value.
90
- resultValue = await valueMap(sourceValue, sourceKey, tree);
91
+ resultValue = await valueFn(sourceValue, sourceKey, tree);
91
92
  } else {
92
93
  // Return source value as is.
93
94
  resultValue = sourceValue;
@@ -97,9 +98,9 @@ export default function createMapTransform(options) {
97
98
  };
98
99
  }
99
100
 
100
- if (keyMap) {
101
+ if (keyFn) {
101
102
  transformed.keys = async () => {
102
- // Apply the keyMap to source keys for leaf values (not subtrees).
103
+ // Apply the keyFn to source keys for leaf values (not subtrees).
103
104
  const sourceKeys = Array.from(await tree.keys());
104
105
  const mapped = await Promise.all(
105
106
  sourceKeys.map(async (sourceKey) => {
@@ -107,12 +108,12 @@ export default function createMapTransform(options) {
107
108
  if (deep && (await Tree.isKeyForSubtree(tree, sourceKey))) {
108
109
  resultKey = sourceKey;
109
110
  } else {
110
- resultKey = await keyMap(sourceKey, tree);
111
+ resultKey = await keyFn(sourceKey, tree);
111
112
  }
112
113
  return resultKey;
113
114
  })
114
115
  );
115
- // Filter out any cases where the keyMap returned undefined.
116
+ // Filter out any cases where the keyFn returned undefined.
116
117
  const resultKeys = mapped.filter((key) => key !== undefined);
117
118
  return resultKeys;
118
119
  };
@@ -1,4 +1,4 @@
1
- import * as Tree from "../Tree.js";
1
+ import { Tree } from "../internal.js";
2
2
 
3
3
  /**
4
4
  * A tree whose keys are strings interpreted as regular expressions.
@@ -10,7 +10,8 @@ import * as Tree from "../Tree.js";
10
10
  *
11
11
  * @type {import("../../index.ts").TreeTransform}
12
12
  */
13
- export default async function regExpKeys(tree) {
13
+ export default async function regExpKeys(treelike) {
14
+ const tree = Tree.from(treelike);
14
15
  const map = new Map();
15
16
 
16
17
  // We build the output tree first so that we can refer to it when setting
@@ -1,3 +1,5 @@
1
+ import { Tree } from "../internal.js";
2
+
1
3
  /**
2
4
  * Return a transform function that sorts a tree's keys.
3
5
  *
@@ -10,7 +12,8 @@ export default function createSortTransform(compareFn) {
10
12
  /**
11
13
  * @type {import("../../index.ts").TreeTransform}
12
14
  */
13
- return function sortTransform(tree) {
15
+ return function sortTransform(treelike) {
16
+ const tree = Tree.from(treelike);
14
17
  const transform = Object.create(tree);
15
18
  transform.keys = async () => {
16
19
  const keys = Array.from(await tree.keys());
@@ -1,3 +1,5 @@
1
+ import { Tree } from "../internal.js";
2
+
1
3
  /**
2
4
  * Return a transform function that sorts a tree's keys.
3
5
  *
@@ -11,7 +13,8 @@ export default function createSortByTransform(sortKeyFn) {
11
13
  /**
12
14
  * @type {import("../../index.ts").TreeTransform}
13
15
  */
14
- return function sortByTransform(tree) {
16
+ return function sortByTransform(treelike) {
17
+ const tree = Tree.from(treelike);
15
18
  const transform = Object.create(tree);
16
19
  transform.keys = async () => {
17
20
  const keysAndSortKeys = [];
@@ -1,9 +1,11 @@
1
- import { PlainObject, StringLike } from "../index.ts";
1
+ import { Packed, PlainObject, StringLike } from "../index.ts";
2
2
 
3
3
  export function castArrayLike(object: any): any;
4
4
  export function getRealmObjectPrototype(object: any): any;
5
5
  export const hiddenFileNames: string[];
6
+ export function isPacked(object: any): object is Packed;
6
7
  export function isPlainObject(object: any): object is PlainObject;
8
+ export function isUnpackable(object): object is { unpack: () => any };
7
9
  export function isStringLike(obj: any): obj is StringLike;
8
10
  export function keysFromPath(path: string): string[];
9
11
  export const naturalSortCompareFn: (a: string, b: string) => number;
package/src/utilities.js CHANGED
@@ -1,3 +1,5 @@
1
+ const TypedArray = Object.getPrototypeOf(Uint8Array);
2
+
1
3
  /**
2
4
  * If the given plain object has only sequential integer keys, return it as an
3
5
  * array. Otherwise return it as is.
@@ -19,9 +21,6 @@ export function castArrayLike(object) {
19
21
  return hasKeys ? Object.values(object) : object;
20
22
  }
21
23
 
22
- // Names of OS-generated files that should not be enumerated
23
- export const hiddenFileNames = [".DS_Store"];
24
-
25
24
  /**
26
25
  * Return the Object prototype at the root of the object's prototype chain.
27
26
  *
@@ -38,6 +37,27 @@ export function getRealmObjectPrototype(object) {
38
37
  return proto;
39
38
  }
40
39
 
40
+ // Names of OS-generated files that should not be enumerated
41
+ export const hiddenFileNames = [".DS_Store"];
42
+
43
+ /**
44
+ * Return true if the object is in a packed form (or can be readily packed into
45
+ * a form) that can be given to fs.writeFile or response.write().
46
+ *
47
+ * @param {any} object
48
+ * @returns {object is import("../index.ts").Packed}
49
+ */
50
+ export function isPacked(object) {
51
+ return (
52
+ typeof object === "string" ||
53
+ object instanceof ArrayBuffer ||
54
+ object instanceof Buffer ||
55
+ object instanceof ReadableStream ||
56
+ object instanceof String ||
57
+ object instanceof TypedArray
58
+ );
59
+ }
60
+
41
61
  /**
42
62
  * Return true if the object is a plain JavaScript object created by `{}`,
43
63
  * `new Object()`, or `Object.create(null)`.
@@ -46,6 +66,7 @@ export function getRealmObjectPrototype(object) {
46
66
  * `Module`) as plain objects.
47
67
  *
48
68
  * @param {any} object
69
+ * @returns {object is import("../index.ts").PlainObject}
49
70
  */
50
71
  export function isPlainObject(object) {
51
72
  // From https://stackoverflow.com/q/51722354/76472
@@ -67,15 +88,15 @@ export function isPlainObject(object) {
67
88
  * Return true if the object is a string or object with a non-trival `toString`
68
89
  * method.
69
90
  *
70
- * @param {any} obj
71
- * @returns {obj is import("@weborigami/async-tree").StringLike}
91
+ * @param {any} object
92
+ * @returns {obj is import("../index.ts").StringLike}
72
93
  */
73
- export function isStringLike(obj) {
74
- if (typeof obj === "string") {
94
+ export function isStringLike(object) {
95
+ if (typeof object === "string") {
75
96
  return true;
76
- } else if (obj?.toString === undefined) {
97
+ } else if (object?.toString === undefined) {
77
98
  return false;
78
- } else if (obj.toString === getRealmObjectPrototype(obj).toString) {
99
+ } else if (object.toString === getRealmObjectPrototype(object).toString) {
79
100
  // The stupid Object.prototype.toString implementation always returns
80
101
  // "[object Object]", so if that's the only toString method the object has,
81
102
  // we return false.
@@ -85,6 +106,13 @@ export function isStringLike(obj) {
85
106
  }
86
107
  }
87
108
 
109
+ export function isUnpackable(object) {
110
+ return (
111
+ isPacked(object) &&
112
+ typeof (/** @type {any} */ (object).unpack) === "function"
113
+ );
114
+ }
115
+
88
116
  /**
89
117
  * Given a path like "/foo/bar/baz", return an array of keys like ["foo", "bar",
90
118
  * "baz"].
@@ -1,7 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
3
  import BrowserFileTree from "../src/BrowserFileTree.js";
4
- import * as Tree from "../src/Tree.js";
4
+ import { Tree } from "../src/internal.js";
5
5
 
6
6
  // Skip these tests if we're not in a browser.
7
7
  const isBrowser = typeof window !== "undefined";
@@ -1,7 +1,6 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import DeepObjectTree from "../src/DeepObjectTree.js";
4
- import * as Tree from "../src/Tree.js";
3
+ import { DeepObjectTree, Tree } from "../src/internal.js";
5
4
 
6
5
  describe("DeepObjectTree", () => {
7
6
  test("returns an ObjectTree for value that's a plain sub-object or sub-array", async () => {
@@ -1,8 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
3
  import DeferredTree from "../src/DeferredTree.js";
4
- import ObjectTree from "../src/ObjectTree.js";
5
- import * as Tree from "../src/Tree.js";
4
+ import { ObjectTree, Tree } from "../src/internal.js";
6
5
 
7
6
  describe("DeferredTree", () => {
8
7
  test("lazy-loads a treelike object", async () => {
@@ -4,7 +4,7 @@ import path from "node:path";
4
4
  import { describe, test } from "node:test";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import FileTree from "../src/FileTree.js";
7
- import * as Tree from "../src/Tree.js";
7
+ import { Tree } from "../src/internal.js";
8
8
 
9
9
  const dirname = path.dirname(fileURLToPath(import.meta.url));
10
10
  const tempDirectory = path.join(dirname, "fixtures/temp");
@@ -18,12 +18,6 @@ describe("FunctionTree", async () => {
18
18
  assert.equal(alice, "Hello, **Alice**.");
19
19
  });
20
20
 
21
- test("unpacking the tree returns the function itself", async () => {
22
- const fn = () => true;
23
- const fixture = new FunctionTree(fn);
24
- assert.equal(await fixture.unpack(), fn);
25
- });
26
-
27
21
  test("getting a value from function with multiple arguments curries the function", async () => {
28
22
  const fixture = new FunctionTree((a, b, c) => a + b + c);
29
23
  const fnA = await fixture.get(1);
@@ -1,7 +1,6 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import ObjectTree from "../src/ObjectTree.js";
4
- import * as Tree from "../src/Tree.js";
3
+ import { ObjectTree, Tree } from "../src/internal.js";
5
4
 
6
5
  describe("ObjectTree", () => {
7
6
  test("can get the keys of the tree", async () => {
@@ -1,7 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import ObjectTree from "../src/ObjectTree.js";
4
3
  import SetTree from "../src/SetTree.js";
4
+ import { ObjectTree } from "../src/internal.js";
5
5
 
6
6
  describe("SetTree", () => {
7
7
  test("can get the keys of the tree", async () => {
@@ -1,7 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import { beforeEach, describe, mock, test } from "node:test";
3
3
  import SiteTree from "../src/SiteTree.js";
4
- import * as Tree from "../src/Tree.js";
4
+ import { Tree } from "../src/internal.js";
5
5
 
6
6
  const mockHost = "https://mock";
7
7
 
package/test/Tree.test.js CHANGED
@@ -1,9 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import { DeepObjectTree } from "../main.js";
4
3
  import MapTree from "../src/MapTree.js";
5
- import ObjectTree from "../src/ObjectTree.js";
6
- import * as Tree from "../src/Tree.js";
4
+ import { DeepObjectTree, ObjectTree, Tree } from "../src/internal.js";
7
5
 
8
6
  describe("Tree", () => {
9
7
  test("assign applies one tree to another", async () => {
@@ -89,13 +87,10 @@ describe("Tree", () => {
89
87
  });
90
88
 
91
89
  test("from() uses an object's unpack() method if defined", async () => {
92
- const obj = {
93
- unpack() {
94
- return {
95
- a: "Hello, a.",
96
- };
97
- },
98
- };
90
+ const obj = new String();
91
+ /** @type {any} */ (obj).unpack = () => ({
92
+ a: "Hello, a.",
93
+ });
99
94
  const tree = Tree.from(obj);
100
95
  assert.deepEqual(await Tree.plain(tree), {
101
96
  a: "Hello, a.",
@@ -103,13 +98,10 @@ describe("Tree", () => {
103
98
  });
104
99
 
105
100
  test("from() creates a deferred tree if unpack() returns a promise", async () => {
106
- const obj = {
107
- async unpack() {
108
- return {
109
- a: "Hello, a.",
110
- };
111
- },
112
- };
101
+ const obj = new String();
102
+ /** @type {any} */ (obj).unpack = async () => ({
103
+ a: "Hello, a.",
104
+ });
113
105
  const tree = Tree.from(obj);
114
106
  assert.deepEqual(await Tree.plain(tree), {
115
107
  a: "Hello, a.",
@@ -299,12 +291,10 @@ describe("Tree", () => {
299
291
  });
300
292
 
301
293
  test("traversing a final empty string can unpack the last value", async () => {
294
+ const unpackable = new String();
295
+ /** @type {any} */ (unpackable).unpack = () => "Content";
302
296
  const tree = {
303
- unpackable: {
304
- unpack() {
305
- return "Content";
306
- },
307
- },
297
+ unpackable,
308
298
  };
309
299
  const result = await Tree.traverse(tree, "unpackable", "");
310
300
  assert.equal(result, "Content");
@@ -1,7 +1,6 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import ObjectTree from "../../src/ObjectTree.js";
4
- import * as Tree from "../../src/Tree.js";
3
+ import { ObjectTree, Tree } from "../../src/internal.js";
5
4
  import cache from "../../src/operations/cache.js";
6
5
 
7
6
  describe("cache", () => {
@@ -1,6 +1,6 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import * as Tree from "../../src/Tree.js";
3
+ import { Tree } from "../../src/internal.js";
4
4
  import merge from "../../src/operations/merge.js";
5
5
 
6
6
  describe("merge", () => {
@@ -1,7 +1,6 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import DeepObjectTree from "../../src/DeepObjectTree.js";
4
- import * as Tree from "../../src/Tree.js";
3
+ import { DeepObjectTree, Tree } from "../../src/internal.js";
5
4
  import mergeDeep from "../../src/operations/mergeDeep.js";
6
5
 
7
6
  describe("mergeDeep", () => {
@@ -1,9 +1,9 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import ObjectTree from "../../src/ObjectTree.js";
4
- import cachedKeyMaps from "../../src/transforms/cachedKeyMaps.js";
3
+ import { ObjectTree } from "../../src/internal.js";
4
+ import cachedKeyFunctions from "../../src/transforms/cachedKeyFunctions.js";
5
5
 
6
- describe("cachedKeyMaps", () => {
6
+ describe("cachedKeyFunctions", () => {
7
7
  test("maps keys with caching", async () => {
8
8
  const tree = new ObjectTree({
9
9
  a: "letter a",
@@ -16,26 +16,26 @@ describe("cachedKeyMaps", () => {
16
16
  return `_${sourceKey}`;
17
17
  };
18
18
 
19
- const { inverseKeyMap, keyMap } = cachedKeyMaps(underscoreKeys);
19
+ const { inverseKey, key } = cachedKeyFunctions(underscoreKeys);
20
20
 
21
- assert.equal(await inverseKeyMap("_a", tree), "a"); // Cache miss
21
+ assert.equal(await inverseKey("_a", tree), "a"); // Cache miss
22
22
  assert.equal(callCount, 1);
23
- assert.equal(await inverseKeyMap("_a", tree), "a");
23
+ assert.equal(await inverseKey("_a", tree), "a");
24
24
  assert.equal(callCount, 1);
25
- assert.equal(await inverseKeyMap("_b", tree), "b"); // Cache miss
25
+ assert.equal(await inverseKey("_b", tree), "b"); // Cache miss
26
26
  assert.equal(callCount, 2);
27
27
 
28
- assert.equal(await keyMap("a", tree), "_a");
29
- assert.equal(await keyMap("a", tree), "_a");
30
- assert.equal(await keyMap("b", tree), "_b");
28
+ assert.equal(await key("a", tree), "_a");
29
+ assert.equal(await key("a", tree), "_a");
30
+ assert.equal(await key("b", tree), "_b");
31
31
  assert.equal(callCount, 2);
32
32
 
33
33
  // `c` isn't in tree, so we should get undefined.
34
- assert.equal(await inverseKeyMap("_c", tree), undefined);
34
+ assert.equal(await inverseKey("_c", tree), undefined);
35
35
  // But key mapping is still possible.
36
- assert.equal(await keyMap("c", tree), "_c");
36
+ assert.equal(await key("c", tree), "_c");
37
37
  // And now we have a cache hit.
38
- assert.equal(await inverseKeyMap("_c", tree), "c");
38
+ assert.equal(await inverseKey("_c", tree), "c");
39
39
  assert.equal(callCount, 3);
40
40
  });
41
41
  });
@@ -1,6 +1,6 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import * as Tree from "../../src/Tree.js";
3
+ import { Tree } from "../../src/internal.js";
4
4
  import groupBy from "../../src/transforms/groupBy.js";
5
5
 
6
6
  describe("groupBy transform", () => {
@@ -1,30 +1,29 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
- import ObjectTree from "../../src/ObjectTree.js";
4
- import * as Tree from "../../src/Tree.js";
5
- import keyMapsForExtensions from "../../src/transforms/keyMapsForExtensions.js";
3
+ import { ObjectTree, Tree } from "../../src/internal.js";
4
+ import keyFunctionsForExtensions from "../../src/transforms/keyFunctionsForExtensions.js";
6
5
  import map from "../../src/transforms/map.js";
7
6
 
8
7
  describe("keyMapsForExtensions", () => {
9
8
  test("returns key functions that pass a matching key through", async () => {
10
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
9
+ const { inverseKey, key } = keyFunctionsForExtensions({
11
10
  sourceExtension: "txt",
12
11
  });
13
- assert.equal(await inverseKeyMap("file.txt"), "file.txt");
14
- assert.equal(await keyMap("file.txt"), "file.txt");
15
- assert.equal(await inverseKeyMap("file.foo"), undefined);
16
- assert.equal(await keyMap("file.foo"), undefined);
12
+ assert.equal(await inverseKey("file.txt"), "file.txt");
13
+ assert.equal(await key("file.txt"), "file.txt");
14
+ assert.equal(await inverseKey("file.foo"), undefined);
15
+ assert.equal(await key("file.foo"), undefined);
17
16
  });
18
17
 
19
18
  test("returns key functions that can map extensions", async () => {
20
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
19
+ const { inverseKey, key } = keyFunctionsForExtensions({
21
20
  resultExtension: "html",
22
21
  sourceExtension: "md",
23
22
  });
24
- assert.equal(await inverseKeyMap("file.html"), "file.md");
25
- assert.equal(await keyMap("file.md"), "file.html");
26
- assert.equal(await inverseKeyMap("file.foo"), undefined);
27
- assert.equal(await keyMap("file.foo"), undefined);
23
+ assert.equal(await inverseKey("file.html"), "file.md");
24
+ assert.equal(await key("file.md"), "file.html");
25
+ assert.equal(await inverseKey("file.foo"), undefined);
26
+ assert.equal(await key("file.foo"), undefined);
28
27
  });
29
28
 
30
29
  test("works with map to handle keys that end in a given resultExtension", async () => {
@@ -33,13 +32,13 @@ describe("keyMapsForExtensions", () => {
33
32
  file2: "won't be mapped",
34
33
  "file3.foo": "won't be mapped",
35
34
  });
36
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
35
+ const { inverseKey, key } = keyFunctionsForExtensions({
37
36
  sourceExtension: "txt",
38
37
  });
39
38
  const transform = map({
40
- inverseKeyMap,
41
- keyMap,
42
- valueMap: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
39
+ inverseKey,
40
+ key,
41
+ value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
43
42
  });
44
43
  const fixture = transform(files);
45
44
  assert.deepEqual(await Tree.plain(fixture), {
@@ -53,14 +52,14 @@ describe("keyMapsForExtensions", () => {
53
52
  file2: "won't be mapped",
54
53
  "file3.foo": "won't be mapped",
55
54
  });
56
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
55
+ const { inverseKey, key } = keyFunctionsForExtensions({
57
56
  resultExtension: "upper",
58
57
  sourceExtension: "txt",
59
58
  });
60
59
  const transform = map({
61
- inverseKeyMap,
62
- keyMap,
63
- valueMap: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
60
+ inverseKey,
61
+ key,
62
+ value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
64
63
  });
65
64
  const fixture = transform(files);
66
65
  assert.deepEqual(await Tree.plain(fixture), {