@weborigami/async-tree 0.0.44 → 0.0.46

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.
package/index.ts CHANGED
@@ -35,7 +35,7 @@ export type Treelike =
35
35
  NativeTreelike |
36
36
  Unpackable<NativeTreelike>;
37
37
 
38
- export type TreeTransform = (tree: AsyncTree) => AsyncTree;
38
+ export type TreeTransform = (treelike: Treelike) => AsyncTree;
39
39
 
40
40
  export type Unpackable<T> = {
41
41
  unpack(): Promise<T>
package/main.js CHANGED
@@ -15,9 +15,9 @@ export * as keysJson from "./src/keysJson.js";
15
15
  export { default as cache } from "./src/operations/cache.js";
16
16
  export { default as merge } from "./src/operations/merge.js";
17
17
  export { default as mergeDeep } from "./src/operations/mergeDeep.js";
18
- export { default as cachedKeyMaps } from "./src/transforms/cachedKeyMaps.js";
18
+ export { default as cachedKeyFunctions } from "./src/transforms/cachedKeyFunctions.js";
19
19
  export { default as groupBy } from "./src/transforms/groupBy.js";
20
- export { default as keyMapsForExtensions } from "./src/transforms/keyMapsForExtensions.js";
20
+ export { default as keyFunctionsForExtensions } from "./src/transforms/keyFunctionsForExtensions.js";
21
21
  export { default as map } from "./src/transforms/map.js";
22
22
  export { default as sort } from "./src/transforms/sort.js";
23
23
  export { default as sortBy } from "./src/transforms/sortBy.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/async-tree",
3
- "version": "0.0.44",
3
+ "version": "0.0.46",
4
4
  "description": "Asynchronous tree drivers based on standard JavaScript classes",
5
5
  "type": "module",
6
6
  "main": "./main.js",
@@ -11,7 +11,7 @@
11
11
  "typescript": "5.3.3"
12
12
  },
13
13
  "dependencies": {
14
- "@weborigami/types": "0.0.44"
14
+ "@weborigami/types": "0.0.46"
15
15
  },
16
16
  "scripts": {
17
17
  "test": "node --test --test-reporter=spec",
package/src/FileTree.js CHANGED
@@ -128,12 +128,15 @@ export default class FileTree {
128
128
  return this;
129
129
  }
130
130
 
131
- // Treat null value as empty string; will create an empty file.
132
- if (value === null) {
133
- value = "";
131
+ if (typeof value === "function") {
132
+ // Invoke function; write out the result.
133
+ value = await value();
134
134
  }
135
135
 
136
- if (value instanceof ArrayBuffer) {
136
+ if (value === null) {
137
+ // Treat null value as empty string; will create an empty file.
138
+ value = "";
139
+ } else if (value instanceof ArrayBuffer) {
137
140
  // Convert ArrayBuffer to Uint8Array, which Node.js can write directly.
138
141
  value = new Uint8Array(value);
139
142
  }
package/src/Tree.d.ts CHANGED
@@ -11,7 +11,7 @@ export function isAsyncMutableTree(obj: any): obj is AsyncMutableTree;
11
11
  export function isAsyncTree(obj: any): obj is AsyncTree;
12
12
  export function isKeyForSubtree(tree: AsyncTree, obj: any): Promise<boolean>;
13
13
  export function isTreelike(obj: any): obj is Treelike;
14
- export function map(tree: Treelike, valueMap: ValueKeyFn): AsyncTree;
14
+ export function map(tree: Treelike, valueFn: ValueKeyFn): AsyncTree;
15
15
  export function mapReduce(tree: Treelike, mapFn: ValueKeyFn|null, reduceFn: ReduceFn): Promise<any>;
16
16
  export function plain(tree: Treelike): Promise<PlainObject>;
17
17
  export function remove(AsyncTree: AsyncMutableTree, key: any): Promise<boolean>;
package/src/Tree.js CHANGED
@@ -212,11 +212,11 @@ export async function isKeyForSubtree(tree, key) {
212
212
  * Return a new tree with deeply-mapped values of the original tree.
213
213
  *
214
214
  * @param {Treelike} treelike
215
- * @param {ValueKeyFn} valueMap
215
+ * @param {ValueKeyFn} valueFn
216
216
  */
217
- export function map(treelike, valueMap) {
217
+ export function map(treelike, valueFn) {
218
218
  const tree = from(treelike);
219
- return mapTransform({ deep: true, valueMap })(tree);
219
+ return mapTransform({ deep: true, value: valueFn })(tree);
220
220
  }
221
221
 
222
222
  /**
@@ -230,10 +230,10 @@ export function map(treelike, valueMap) {
230
230
  * reduceFn, which should consolidate those into a single result.
231
231
  *
232
232
  * @param {Treelike} treelike
233
- * @param {ValueKeyFn|null} valueMap
233
+ * @param {ValueKeyFn|null} valueFn
234
234
  * @param {ReduceFn} reduceFn
235
235
  */
236
- export async function mapReduce(treelike, valueMap, reduceFn) {
236
+ export async function mapReduce(treelike, valueFn, reduceFn) {
237
237
  const tree = from(treelike);
238
238
 
239
239
  // We're going to fire off all the get requests in parallel, as quickly as
@@ -244,9 +244,9 @@ export async function mapReduce(treelike, valueMap, reduceFn) {
244
244
  tree.get(key).then((value) =>
245
245
  // If the value is a subtree, recurse.
246
246
  isAsyncTree(value)
247
- ? mapReduce(value, valueMap, reduceFn)
248
- : valueMap
249
- ? valueMap(value, key, tree)
247
+ ? mapReduce(value, valueFn, reduceFn)
248
+ : valueFn
249
+ ? valueFn(value, key, tree)
250
250
  : value
251
251
  )
252
252
  );
@@ -9,13 +9,17 @@ import { ObjectTree, Tree } from "@weborigami/async-tree";
9
9
  *
10
10
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
11
11
  * @typedef {import("@weborigami/types").AsyncMutableTree} AsyncMutableTree
12
+ * @typedef {import("../../index.ts").Treelike} Treelike
12
13
  *
13
- * @param {AsyncTree} source
14
+ * @param {Treelike} sourceTreelike
14
15
  * @param {AsyncMutableTree} [cacheTree]
15
- * @param {AsyncTree} [filter]
16
+ * @param {Treelike} [filterTreelike]
16
17
  * @returns {AsyncTree & { description: string }}
17
18
  */
18
- export default function treeCache(source, cacheTree, filter) {
19
+ export default function treeCache(sourceTreelike, cacheTree, filterTreelike) {
20
+ const source = Tree.from(sourceTreelike);
21
+ const filter = filterTreelike ? Tree.from(filterTreelike) : undefined;
22
+
19
23
  /** @type {AsyncMutableTree} */
20
24
  const cache = cacheTree ?? new ObjectTree({});
21
25
  return {
@@ -3,18 +3,18 @@ import * as Tree from "../Tree.js";
3
3
  const treeToCaches = new WeakMap();
4
4
 
5
5
  /**
6
- * Given a keyMap, return a new keyMap and inverseKeyMap that cache the results of
7
- * the original keyMap.
6
+ * Given a key function, return a new key function and inverse key function that
7
+ * cache the results of the original.
8
8
  *
9
9
  * @typedef {import("../../index.ts").KeyFn} KeyFn
10
10
  *
11
- * @param {KeyFn} keyMap
11
+ * @param {KeyFn} keyFn
12
12
  * @param {boolean} [deep]
13
- * @returns {{ keyMap: KeyFn, inverseKeyMap: KeyFn }}
13
+ * @returns {{ key: KeyFn, inverseKey: KeyFn }}
14
14
  */
15
- export default function createCachedKeysTransform(keyMap, deep = false) {
15
+ export default function createCachedKeysTransform(keyFn, deep = false) {
16
16
  return {
17
- async inverseKeyMap(resultKey, tree) {
17
+ async inverseKey(resultKey, tree) {
18
18
  const caches = getCachesForTree(tree);
19
19
 
20
20
  // First check to see if we've already computed an source key for this
@@ -37,7 +37,7 @@ export default function createCachedKeysTransform(keyMap, deep = false) {
37
37
  if (deep && (await Tree.isKeyForSubtree(tree, sourceKey))) {
38
38
  computedResultKey = sourceKey;
39
39
  } else {
40
- computedResultKey = await keyMap(sourceKey, tree);
40
+ computedResultKey = await keyFn(sourceKey, tree);
41
41
  }
42
42
 
43
43
  caches.sourceKeyToResultKey.set(sourceKey, computedResultKey);
@@ -52,7 +52,7 @@ export default function createCachedKeysTransform(keyMap, deep = false) {
52
52
  return undefined;
53
53
  },
54
54
 
55
- async keyMap(sourceKey, tree) {
55
+ async key(sourceKey, tree) {
56
56
  const keyMaps = getCachesForTree(tree);
57
57
 
58
58
  // First check to see if we've already computed an result key for this
@@ -62,7 +62,7 @@ export default function createCachedKeysTransform(keyMap, deep = false) {
62
62
  return keyMaps.sourceKeyToResultKey.get(sourceKey);
63
63
  }
64
64
 
65
- const resultKey = await keyMap(sourceKey, tree);
65
+ const resultKey = await keyFn(sourceKey, tree);
66
66
 
67
67
  // Cache the mappings from source key <-> result key for next time.
68
68
  keyMaps.sourceKeyToResultKey.set(sourceKey, resultKey);
@@ -11,7 +11,8 @@ export default function createGroupByTransform(groupKeyFn) {
11
11
  /**
12
12
  * @type {import("../../index.ts").TreeTransform}
13
13
  */
14
- return async function groupByTransform(tree) {
14
+ return async function groupByTransform(treelike) {
15
+ const tree = Tree.from(treelike);
15
16
  const result = {};
16
17
  for (const key of await tree.keys()) {
17
18
  const value = await tree.get(key);
@@ -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
  },
@@ -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
  };
@@ -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 * as Tree from "../Tree.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 * as Tree from "../Tree.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 = [];
@@ -22,7 +25,8 @@ export default function createSortByTransform(sortKeyFn) {
22
25
  keysAndSortKeys.sort((a, b) =>
23
26
  a.sortKey < b.sortKey ? -1 : a.sortKey > b.sortKey ? 1 : 0
24
27
  );
25
- return keysAndSortKeys.map(({ key }) => key);
28
+ const sortedKeys = keysAndSortKeys.map(({ key }) => key);
29
+ return sortedKeys;
26
30
  };
27
31
  return transform;
28
32
  };
@@ -1,9 +1,9 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
3
  import ObjectTree from "../../src/ObjectTree.js";
4
- import cachedKeyMaps from "../../src/transforms/cachedKeyMaps.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
  });
@@ -2,29 +2,29 @@ import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
3
  import ObjectTree from "../../src/ObjectTree.js";
4
4
  import * as Tree from "../../src/Tree.js";
5
- import keyMapsForExtensions from "../../src/transforms/keyMapsForExtensions.js";
5
+ import keyFunctionsForExtensions from "../../src/transforms/keyFunctionsForExtensions.js";
6
6
  import map from "../../src/transforms/map.js";
7
7
 
8
8
  describe("keyMapsForExtensions", () => {
9
9
  test("returns key functions that pass a matching key through", async () => {
10
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
10
+ const { inverseKey, key } = keyFunctionsForExtensions({
11
11
  sourceExtension: "txt",
12
12
  });
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);
13
+ assert.equal(await inverseKey("file.txt"), "file.txt");
14
+ assert.equal(await key("file.txt"), "file.txt");
15
+ assert.equal(await inverseKey("file.foo"), undefined);
16
+ assert.equal(await key("file.foo"), undefined);
17
17
  });
18
18
 
19
19
  test("returns key functions that can map extensions", async () => {
20
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
20
+ const { inverseKey, key } = keyFunctionsForExtensions({
21
21
  resultExtension: "html",
22
22
  sourceExtension: "md",
23
23
  });
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);
24
+ assert.equal(await inverseKey("file.html"), "file.md");
25
+ assert.equal(await key("file.md"), "file.html");
26
+ assert.equal(await inverseKey("file.foo"), undefined);
27
+ assert.equal(await key("file.foo"), undefined);
28
28
  });
29
29
 
30
30
  test("works with map to handle keys that end in a given resultExtension", async () => {
@@ -33,13 +33,13 @@ describe("keyMapsForExtensions", () => {
33
33
  file2: "won't be mapped",
34
34
  "file3.foo": "won't be mapped",
35
35
  });
36
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
36
+ const { inverseKey, key } = keyFunctionsForExtensions({
37
37
  sourceExtension: "txt",
38
38
  });
39
39
  const transform = map({
40
- inverseKeyMap,
41
- keyMap,
42
- valueMap: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
40
+ inverseKey,
41
+ key,
42
+ value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
43
43
  });
44
44
  const fixture = transform(files);
45
45
  assert.deepEqual(await Tree.plain(fixture), {
@@ -53,14 +53,14 @@ describe("keyMapsForExtensions", () => {
53
53
  file2: "won't be mapped",
54
54
  "file3.foo": "won't be mapped",
55
55
  });
56
- const { inverseKeyMap, keyMap } = keyMapsForExtensions({
56
+ const { inverseKey, key } = keyFunctionsForExtensions({
57
57
  resultExtension: "upper",
58
58
  sourceExtension: "txt",
59
59
  });
60
60
  const transform = map({
61
- inverseKeyMap,
62
- keyMap,
63
- valueMap: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
61
+ inverseKey,
62
+ key,
63
+ value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
64
64
  });
65
65
  const fixture = transform(files);
66
66
  assert.deepEqual(await Tree.plain(fixture), {
@@ -1,18 +1,18 @@
1
1
  import assert from "node:assert";
2
2
  import { describe, test } from "node:test";
3
+ import { ObjectTree } from "../../main.js";
3
4
  import DeepObjectTree from "../../src/DeepObjectTree.js";
4
5
  import FunctionTree from "../../src/FunctionTree.js";
5
- import ObjectTree from "../../src/ObjectTree.js";
6
6
  import * as Tree from "../../src/Tree.js";
7
7
  import map from "../../src/transforms/map.js";
8
8
 
9
9
  describe("map", () => {
10
- test("returns identity graph if no keyMap or valueMap", async () => {
11
- const tree = new ObjectTree({
10
+ test("returns identity graph if no key or value", async () => {
11
+ const tree = {
12
12
  a: "letter a",
13
13
  b: "letter b",
14
- });
15
- const mapped = map({})(tree);
14
+ };
15
+ const mapped = map()(tree);
16
16
  assert.deepEqual(await Tree.plain(mapped), {
17
17
  a: "letter a",
18
18
  b: "letter b",
@@ -26,7 +26,7 @@ describe("map", () => {
26
26
  c: undefined, // Won't be mapped
27
27
  });
28
28
  const uppercaseValues = map({
29
- valueMap: (sourceValue, sourceKey, innerTree) => {
29
+ value: (sourceValue, sourceKey, innerTree) => {
30
30
  assert(sourceKey === "a" || sourceKey === "b");
31
31
  assert.equal(innerTree, tree);
32
32
  return sourceValue.toUpperCase();
@@ -41,13 +41,12 @@ describe("map", () => {
41
41
  });
42
42
 
43
43
  test("interprets a single function argument as the value function", async () => {
44
- const tree = new ObjectTree({
44
+ const tree = {
45
45
  a: "letter a",
46
46
  b: "letter b",
47
- });
48
- const uppercaseValues = map((sourceValue, sourceKey, innerTree) => {
47
+ };
48
+ const uppercaseValues = map((sourceValue, sourceKey, tree) => {
49
49
  assert(sourceKey === "a" || sourceKey === "b");
50
- assert.equal(innerTree, tree);
51
50
  return sourceValue.toUpperCase();
52
51
  });
53
52
  const mapped = uppercaseValues(tree);
@@ -57,14 +56,14 @@ describe("map", () => {
57
56
  });
58
57
  });
59
58
 
60
- test("maps keys using keyMap and inverseKeyMap", async () => {
61
- const tree = new ObjectTree({
59
+ test("maps keys using key and inverseKey", async () => {
60
+ const tree = {
62
61
  a: "letter a",
63
62
  b: "letter b",
64
- });
63
+ };
65
64
  const doubleKeys = map({
66
- keyMap: async (sourceKey, tree) => `_${sourceKey}`,
67
- inverseKeyMap: async (resultKey, tree) => resultKey.slice(1),
65
+ key: async (sourceKey, tree) => `_${sourceKey}`,
66
+ inverseKey: async (resultKey, tree) => resultKey.slice(1),
68
67
  });
69
68
  const mapped = doubleKeys(tree);
70
69
  assert.deepEqual(await Tree.plain(mapped), {
@@ -74,15 +73,14 @@ describe("map", () => {
74
73
  });
75
74
 
76
75
  test("maps keys and values", async () => {
77
- const tree = new ObjectTree({
76
+ const tree = {
78
77
  a: "letter a",
79
78
  b: "letter b",
80
- });
79
+ };
81
80
  const doubleKeysUppercaseValues = map({
82
- keyMap: async (sourceKey, tree) => `_${sourceKey}`,
83
- inverseKeyMap: async (resultKey, tree) => resultKey.slice(1),
84
- valueMap: async (sourceValue, sourceKey, tree) =>
85
- sourceValue.toUpperCase(),
81
+ key: async (sourceKey, tree) => `_${sourceKey}`,
82
+ inverseKey: async (resultKey, tree) => resultKey.slice(1),
83
+ value: async (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
86
84
  });
87
85
  const mapped = doubleKeysUppercaseValues(tree);
88
86
  assert.deepEqual(await Tree.plain(mapped), {
@@ -92,16 +90,16 @@ describe("map", () => {
92
90
  });
93
91
 
94
92
  test("a shallow map is applied to async subtrees too", async () => {
95
- const tree = new ObjectTree({
93
+ const tree = {
96
94
  a: "letter a",
97
95
  more: {
98
96
  b: "letter b",
99
97
  },
100
- });
98
+ };
101
99
  const doubleKeys = map({
102
- keyMap: async (sourceKey, tree) => `_${sourceKey}`,
103
- inverseKeyMap: async (resultKey, tree) => resultKey.slice(1),
104
- valueMap: async (sourceValue, sourceKey, tree) => sourceKey,
100
+ key: async (sourceKey, tree) => `_${sourceKey}`,
101
+ inverseKey: async (resultKey, tree) => resultKey.slice(1),
102
+ value: async (sourceValue, sourceKey, tree) => sourceKey,
105
103
  });
106
104
  const mapped = doubleKeys(tree);
107
105
  assert.deepEqual(await Tree.plain(mapped), {
@@ -110,14 +108,14 @@ describe("map", () => {
110
108
  });
111
109
  });
112
110
 
113
- test("valueMap can provide a default keyMap and inverseKeyMap", async () => {
111
+ test("value can provide a default key and inverse key functions", async () => {
114
112
  const uppercase = (s) => s.toUpperCase();
115
- uppercase.keyMap = (sourceKey) => `_${sourceKey}`;
116
- uppercase.inverseKeyMap = (resultKey) => resultKey.slice(1);
117
- const tree = new ObjectTree({
113
+ uppercase.key = (sourceKey) => `_${sourceKey}`;
114
+ uppercase.inverseKey = (resultKey) => resultKey.slice(1);
115
+ const tree = {
118
116
  a: "letter a",
119
117
  b: "letter b",
120
- });
118
+ };
121
119
  const mapped = map(uppercase)(tree);
122
120
  assert.deepEqual(await Tree.plain(mapped), {
123
121
  _a: "LETTER A",
@@ -134,7 +132,7 @@ describe("map", () => {
134
132
  });
135
133
  const uppercaseValues = map({
136
134
  deep: true,
137
- valueMap: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
135
+ value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
138
136
  });
139
137
  const mapped = uppercaseValues(tree);
140
138
  assert.deepEqual(await Tree.plain(mapped), {
@@ -154,8 +152,8 @@ describe("map", () => {
154
152
  });
155
153
  const doubleKeys = map({
156
154
  deep: true,
157
- keyMap: async (sourceKey, tree) => `_${sourceKey}`,
158
- inverseKeyMap: async (resultKey, tree) => resultKey.slice(1),
155
+ key: async (sourceKey, tree) => `_${sourceKey}`,
156
+ inverseKey: async (resultKey, tree) => resultKey.slice(1),
159
157
  });
160
158
  const mapped = doubleKeys(tree);
161
159
  assert.deepEqual(await Tree.plain(mapped), {
@@ -175,10 +173,9 @@ describe("map", () => {
175
173
  });
176
174
  const doubleKeysUppercaseValues = map({
177
175
  deep: true,
178
- keyMap: async (sourceKey, tree) => `_${sourceKey}`,
179
- inverseKeyMap: async (resultKey, tree) => resultKey.slice(1),
180
- valueMap: async (sourceValue, sourceKey, tree) =>
181
- sourceValue.toUpperCase(),
176
+ key: async (sourceKey, tree) => `_${sourceKey}`,
177
+ inverseKey: async (resultKey, tree) => resultKey.slice(1),
178
+ value: async (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
182
179
  });
183
180
  const mapped = doubleKeysUppercaseValues(tree);
184
181
  assert.deepEqual(await Tree.plain(mapped), {
@@ -196,7 +193,7 @@ describe("map", () => {
196
193
  }, ["a", "b", "c"]);
197
194
  const mapped = map({
198
195
  needsSourceValue: false,
199
- valueMap: () => "X",
196
+ value: () => "X",
200
197
  })(tree);
201
198
  assert.deepEqual(await Tree.plain(mapped), {
202
199
  a: "X",