@weborigami/async-tree 0.0.37 → 0.0.39
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/package.json +3 -3
- package/src/operations/cache.js +3 -3
- package/src/transforms/map.js +22 -5
- package/test/transforms/map.test.js +33 -0
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/async-tree",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"description": "Asynchronous tree drivers based on standard JavaScript classes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./main.js",
|
|
7
7
|
"browser": "./browser.js",
|
|
8
8
|
"types": "./index.ts",
|
|
9
9
|
"devDependencies": {
|
|
10
|
-
"@types/node": "20.
|
|
11
|
-
"typescript": "5.
|
|
10
|
+
"@types/node": "20.11.3",
|
|
11
|
+
"typescript": "5.3.3"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@weborigami/types": "*"
|
package/src/operations/cache.js
CHANGED
|
@@ -32,9 +32,9 @@ export default function treeCache(source, cacheTree, filter) {
|
|
|
32
32
|
// Cache miss or interior node cache hit.
|
|
33
33
|
let value = await source.get(key);
|
|
34
34
|
if (value !== undefined) {
|
|
35
|
-
//
|
|
36
|
-
const filterValue =
|
|
37
|
-
const filterMatch = filterValue !== undefined;
|
|
35
|
+
// If a filter is defined, does the key match the filter?
|
|
36
|
+
const filterValue = await filter?.get(key);
|
|
37
|
+
const filterMatch = !filter || filterValue !== undefined;
|
|
38
38
|
if (filterMatch) {
|
|
39
39
|
if (Tree.isAsyncTree(value)) {
|
|
40
40
|
// Construct merged tree for a tree result.
|
package/src/transforms/map.js
CHANGED
|
@@ -6,25 +6,35 @@ 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, inverseKeyMap?: KeyFn, keyMap?: KeyFn, valueMap?: ValueKeyFn }} options
|
|
9
|
+
* @param {ValueKeyFn|{ deep?: boolean, description?: string, needsSourceValue?: boolean, inverseKeyMap?: KeyFn, keyMap?: KeyFn, valueMap?: ValueKeyFn }} options
|
|
10
10
|
*/
|
|
11
11
|
export default function createMapTransform(options) {
|
|
12
12
|
let deep;
|
|
13
13
|
let description;
|
|
14
14
|
let inverseKeyMap;
|
|
15
15
|
let keyMap;
|
|
16
|
+
let needsSourceValue;
|
|
16
17
|
let valueMap;
|
|
17
18
|
if (typeof options === "function") {
|
|
18
19
|
// Take the single function argument as the valueMap
|
|
19
20
|
valueMap = options;
|
|
20
21
|
} else {
|
|
21
|
-
deep = options.deep
|
|
22
|
-
description = options.description
|
|
22
|
+
deep = options.deep;
|
|
23
|
+
description = options.description;
|
|
23
24
|
inverseKeyMap = options.inverseKeyMap;
|
|
24
25
|
keyMap = options.keyMap;
|
|
26
|
+
needsSourceValue = options.needsSourceValue;
|
|
25
27
|
valueMap = options.valueMap;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
deep ??= false;
|
|
31
|
+
description ??= "key/value map";
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
inverseKeyMap ??= valueMap?.inverseKeyMap;
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
keyMap ??= valueMap?.keyMap;
|
|
36
|
+
needsSourceValue ??= true;
|
|
37
|
+
|
|
28
38
|
if ((keyMap && !inverseKeyMap) || (!keyMap && inverseKeyMap)) {
|
|
29
39
|
throw new TypeError(
|
|
30
40
|
`map: You must specify both keyMap and inverseKeyMap, or neither.`
|
|
@@ -58,11 +68,18 @@ export default function createMapTransform(options) {
|
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
// Step 2: Get the source value.
|
|
61
|
-
|
|
71
|
+
let sourceValue;
|
|
72
|
+
if (needsSourceValue) {
|
|
73
|
+
// Normal case: get the value from the source tree.
|
|
74
|
+
sourceValue = await tree.get(sourceKey);
|
|
75
|
+
} else if (deep && (await Tree.isKeyForSubtree(tree, sourceKey))) {
|
|
76
|
+
// Only get the source value if it's a subtree.
|
|
77
|
+
sourceValue = tree;
|
|
78
|
+
}
|
|
62
79
|
|
|
63
80
|
// Step 3: Map the source value to the result value.
|
|
64
81
|
let resultValue;
|
|
65
|
-
if (sourceValue === undefined) {
|
|
82
|
+
if (needsSourceValue && sourceValue === undefined) {
|
|
66
83
|
// No source value means no result value.
|
|
67
84
|
resultValue = undefined;
|
|
68
85
|
} else if (deep && Tree.isAsyncTree(sourceValue)) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
+
import FunctionTree from "../../src/FunctionTree.js";
|
|
3
4
|
import ObjectTree from "../../src/ObjectTree.js";
|
|
4
5
|
import * as Tree from "../../src/Tree.js";
|
|
5
6
|
import map from "../../src/transforms/map.js";
|
|
@@ -108,6 +109,21 @@ describe("map", () => {
|
|
|
108
109
|
});
|
|
109
110
|
});
|
|
110
111
|
|
|
112
|
+
test("valueMap can provide a default keyMap and inverseKeyMap", async () => {
|
|
113
|
+
const uppercase = (s) => s.toUpperCase();
|
|
114
|
+
uppercase.keyMap = (sourceKey) => `_${sourceKey}`;
|
|
115
|
+
uppercase.inverseKeyMap = (resultKey) => resultKey.slice(1);
|
|
116
|
+
const tree = new ObjectTree({
|
|
117
|
+
a: "letter a",
|
|
118
|
+
b: "letter b",
|
|
119
|
+
});
|
|
120
|
+
const mapped = map(uppercase)(tree);
|
|
121
|
+
assert.deepEqual(await Tree.plain(mapped), {
|
|
122
|
+
_a: "LETTER A",
|
|
123
|
+
_b: "LETTER B",
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
111
127
|
test("deep maps values", async () => {
|
|
112
128
|
const tree = new ObjectTree({
|
|
113
129
|
a: "letter a",
|
|
@@ -171,4 +187,21 @@ describe("map", () => {
|
|
|
171
187
|
},
|
|
172
188
|
});
|
|
173
189
|
});
|
|
190
|
+
|
|
191
|
+
test("needsSourceValue can be set to false in cases where the value isn't necessary", async () => {
|
|
192
|
+
let flag = false;
|
|
193
|
+
const tree = new FunctionTree(() => {
|
|
194
|
+
flag = true;
|
|
195
|
+
}, ["a", "b", "c"]);
|
|
196
|
+
const mapped = map({
|
|
197
|
+
needsSourceValue: false,
|
|
198
|
+
valueMap: () => "X",
|
|
199
|
+
})(tree);
|
|
200
|
+
assert.deepEqual(await Tree.plain(mapped), {
|
|
201
|
+
a: "X",
|
|
202
|
+
b: "X",
|
|
203
|
+
c: "X",
|
|
204
|
+
});
|
|
205
|
+
assert(!flag);
|
|
206
|
+
});
|
|
174
207
|
});
|