@weborigami/async-tree 0.5.8 → 0.6.0
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/browser.js +1 -1
- package/index.ts +31 -35
- package/main.js +1 -2
- package/package.json +4 -7
- package/shared.js +77 -12
- package/src/Tree.js +8 -2
- package/src/drivers/AsyncMap.js +210 -0
- package/src/drivers/{BrowserFileTree.js → BrowserFileMap.js} +36 -27
- package/src/drivers/{calendarTree.js → CalendarMap.js} +81 -62
- package/src/drivers/ConstantMap.js +30 -0
- package/src/drivers/DeepObjectMap.js +27 -0
- package/src/drivers/{ExplorableSiteTree.js → ExplorableSiteMap.js} +7 -7
- package/src/drivers/FileMap.js +245 -0
- package/src/drivers/{FunctionTree.js → FunctionMap.js} +19 -22
- package/src/drivers/ObjectMap.js +139 -0
- package/src/drivers/SetMap.js +13 -0
- package/src/drivers/{SiteTree.js → SiteMap.js} +16 -17
- package/src/drivers/SyncMap.js +245 -0
- package/src/jsonKeys.d.ts +2 -2
- package/src/jsonKeys.js +6 -5
- package/src/operations/addNextPrevious.js +35 -36
- package/src/operations/assign.js +30 -21
- package/src/operations/cache.js +29 -35
- package/src/operations/cachedKeyFunctions.js +1 -1
- package/src/operations/calendar.js +5 -0
- package/src/operations/clear.js +13 -12
- package/src/operations/constant.js +5 -0
- package/src/operations/deepEntries.js +23 -0
- package/src/operations/deepMap.js +9 -9
- package/src/operations/deepMerge.js +36 -25
- package/src/operations/deepReverse.js +23 -16
- package/src/operations/deepTake.js +7 -7
- package/src/operations/deepText.js +4 -4
- package/src/operations/deepValues.js +3 -6
- package/src/operations/deepValuesIterator.js +11 -11
- package/src/operations/delete.js +8 -12
- package/src/operations/entries.js +17 -10
- package/src/operations/filter.js +9 -7
- package/src/operations/first.js +12 -10
- package/src/operations/forEach.js +10 -13
- package/src/operations/from.js +31 -39
- package/src/operations/globKeys.js +22 -17
- package/src/operations/group.js +2 -2
- package/src/operations/groupBy.js +24 -22
- package/src/operations/has.js +7 -9
- package/src/operations/indent.js +2 -2
- package/src/operations/inners.js +19 -15
- package/src/operations/invokeFunctions.js +22 -10
- package/src/operations/isAsyncMutableTree.js +5 -12
- package/src/operations/isAsyncTree.js +5 -20
- package/src/operations/isMap.js +39 -0
- package/src/operations/isMaplike.js +34 -0
- package/src/operations/isReadOnlyMap.js +14 -0
- package/src/operations/isTraversable.js +3 -3
- package/src/operations/isTreelike.js +5 -30
- package/src/operations/json.js +4 -12
- package/src/operations/keys.js +17 -8
- package/src/operations/length.js +9 -8
- package/src/operations/map.js +27 -30
- package/src/operations/mapExtension.js +20 -16
- package/src/operations/mapReduce.js +22 -17
- package/src/operations/mask.js +31 -22
- package/src/operations/match.js +13 -9
- package/src/operations/merge.js +43 -35
- package/src/operations/paginate.js +26 -18
- package/src/operations/parent.js +7 -7
- package/src/operations/paths.js +8 -8
- package/src/operations/plain.js +6 -6
- package/src/operations/regExpKeys.js +21 -12
- package/src/operations/reverse.js +21 -15
- package/src/operations/root.js +6 -5
- package/src/operations/scope.js +31 -26
- package/src/operations/shuffle.js +23 -16
- package/src/operations/size.js +13 -0
- package/src/operations/sort.js +55 -40
- package/src/operations/sync.js +21 -0
- package/src/operations/take.js +23 -11
- package/src/operations/text.js +4 -4
- package/src/operations/toFunction.js +7 -7
- package/src/operations/traverse.js +4 -4
- package/src/operations/traverseOrThrow.js +13 -9
- package/src/operations/traversePath.js +2 -2
- package/src/operations/values.js +18 -9
- package/src/operations/withKeys.js +22 -16
- package/src/symbols.js +1 -0
- package/src/utilities/castArraylike.js +10 -2
- package/src/utilities/getMapArgument.js +38 -0
- package/src/utilities/getParent.js +2 -2
- package/src/utilities/isStringlike.js +7 -5
- package/src/utilities/setParent.js +7 -7
- package/src/utilities/toFunction.js +2 -2
- package/src/utilities/toPlainValue.js +22 -18
- package/test/SampleAsyncMap.js +34 -0
- package/test/browser/assert.js +20 -0
- package/test/browser/index.html +54 -21
- package/test/drivers/AsyncMap.test.js +119 -0
- package/test/drivers/{BrowserFileTree.test.js → BrowserFileMap.test.js} +42 -23
- package/test/drivers/{calendarTree.test.js → CalendarMap.test.js} +17 -19
- package/test/drivers/ConstantMap.test.js +15 -0
- package/test/drivers/DeepObjectMap.test.js +36 -0
- package/test/drivers/{ExplorableSiteTree.test.js → ExplorableSiteMap.test.js} +29 -14
- package/test/drivers/FileMap.test.js +185 -0
- package/test/drivers/FunctionMap.test.js +56 -0
- package/test/drivers/ObjectMap.test.js +166 -0
- package/test/drivers/SetMap.test.js +35 -0
- package/test/drivers/{SiteTree.test.js → SiteMap.test.js} +14 -10
- package/test/drivers/SyncMap.test.js +321 -0
- package/test/jsonKeys.test.js +2 -2
- package/test/operations/addNextPrevious.test.js +3 -2
- package/test/operations/assign.test.js +30 -35
- package/test/operations/cache.test.js +8 -6
- package/test/operations/cachedKeyFunctions.test.js +6 -5
- package/test/operations/clear.test.js +6 -27
- package/test/operations/deepEntries.test.js +32 -0
- package/test/operations/deepMerge.test.js +6 -5
- package/test/operations/deepReverse.test.js +2 -2
- package/test/operations/deepTake.test.js +2 -2
- package/test/operations/deepText.test.js +4 -4
- package/test/operations/deepValuesIterator.test.js +2 -2
- package/test/operations/delete.test.js +2 -2
- package/test/operations/extensionKeyFunctions.test.js +6 -5
- package/test/operations/filter.test.js +3 -3
- package/test/operations/from.test.js +23 -31
- package/test/operations/globKeys.test.js +9 -9
- package/test/operations/groupBy.test.js +6 -5
- package/test/operations/inners.test.js +4 -4
- package/test/operations/invokeFunctions.test.js +2 -2
- package/test/operations/isMap.test.js +15 -0
- package/test/operations/isMaplike.test.js +15 -0
- package/test/operations/json.test.js +2 -2
- package/test/operations/keys.test.js +16 -3
- package/test/operations/map.test.js +20 -18
- package/test/operations/mapExtension.test.js +6 -6
- package/test/operations/mapReduce.test.js +2 -2
- package/test/operations/mask.test.js +4 -3
- package/test/operations/match.test.js +2 -2
- package/test/operations/merge.test.js +15 -11
- package/test/operations/paginate.test.js +5 -5
- package/test/operations/parent.test.js +3 -3
- package/test/operations/paths.test.js +6 -6
- package/test/operations/plain.test.js +8 -8
- package/test/operations/regExpKeys.test.js +12 -11
- package/test/operations/reverse.test.js +4 -3
- package/test/operations/scope.test.js +6 -5
- package/test/operations/shuffle.test.js +3 -2
- package/test/operations/sort.test.js +7 -10
- package/test/operations/sync.test.js +43 -0
- package/test/operations/take.test.js +2 -2
- package/test/operations/toFunction.test.js +2 -2
- package/test/operations/traverse.test.js +4 -5
- package/test/operations/withKeys.test.js +2 -2
- package/test/utilities/setParent.test.js +6 -6
- package/test/utilities/toFunction.test.js +2 -2
- package/test/utilities/toPlainValue.test.js +51 -12
- package/src/drivers/DeepMapTree.js +0 -23
- package/src/drivers/DeepObjectTree.js +0 -18
- package/src/drivers/DeferredTree.js +0 -81
- package/src/drivers/FileTree.js +0 -276
- package/src/drivers/MapTree.js +0 -70
- package/src/drivers/ObjectTree.js +0 -158
- package/src/drivers/SetTree.js +0 -34
- package/src/drivers/constantTree.js +0 -19
- package/src/drivers/limitConcurrency.js +0 -63
- package/src/internal.js +0 -16
- package/src/utilities/getTreeArgument.js +0 -43
- package/test/drivers/DeepMapTree.test.js +0 -17
- package/test/drivers/DeepObjectTree.test.js +0 -35
- package/test/drivers/DeferredTree.test.js +0 -22
- package/test/drivers/FileTree.test.js +0 -192
- package/test/drivers/FunctionTree.test.js +0 -46
- package/test/drivers/MapTree.test.js +0 -59
- package/test/drivers/ObjectTree.test.js +0 -163
- package/test/drivers/SetTree.test.js +0 -44
- package/test/drivers/constantTree.test.js +0 -13
- package/test/drivers/limitConcurrency.test.js +0 -41
- package/test/operations/isAsyncMutableTree.test.js +0 -17
- package/test/operations/isAsyncTree.test.js +0 -26
- package/test/operations/isTreelike.test.js +0 -13
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import
|
|
3
|
+
import from from "../../src/operations/from.js";
|
|
4
|
+
import keys from "../../src/operations/keys.js";
|
|
4
5
|
import sort from "../../src/operations/sort.js";
|
|
5
6
|
|
|
6
7
|
describe("sort", () => {
|
|
7
8
|
test("sorts keys using default sort order", async () => {
|
|
8
|
-
const tree =
|
|
9
|
+
const tree = from({
|
|
9
10
|
file10: null,
|
|
10
11
|
file1: null,
|
|
11
12
|
file9: null,
|
|
12
13
|
});
|
|
13
14
|
const sorted = await sort(tree);
|
|
14
|
-
assert.deepEqual(Array.from(await
|
|
15
|
+
assert.deepEqual(Array.from(await keys(sorted)), [
|
|
15
16
|
"file1",
|
|
16
17
|
"file10",
|
|
17
18
|
"file9",
|
|
@@ -19,7 +20,7 @@ describe("sort", () => {
|
|
|
19
20
|
});
|
|
20
21
|
|
|
21
22
|
test("invokes a comparison function", async () => {
|
|
22
|
-
const tree =
|
|
23
|
+
const tree = from({
|
|
23
24
|
b: 2,
|
|
24
25
|
c: 3,
|
|
25
26
|
a: 1,
|
|
@@ -27,7 +28,7 @@ describe("sort", () => {
|
|
|
27
28
|
// Reverse order
|
|
28
29
|
const compare = (a, b) => (a > b ? -1 : a < b ? 1 : 0);
|
|
29
30
|
const sorted = await sort(tree, { compare });
|
|
30
|
-
assert.deepEqual(Array.from(await
|
|
31
|
+
assert.deepEqual(Array.from(await keys(sorted)), ["c", "b", "a"]);
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
test("invokes a sortKey function", async () => {
|
|
@@ -39,10 +40,6 @@ describe("sort", () => {
|
|
|
39
40
|
const sorted = await sort(tree, {
|
|
40
41
|
sortKey: async (value, key, tree) => value.age,
|
|
41
42
|
});
|
|
42
|
-
assert.deepEqual(Array.from(await
|
|
43
|
-
"Bob",
|
|
44
|
-
"Carol",
|
|
45
|
-
"Alice",
|
|
46
|
-
]);
|
|
43
|
+
assert.deepEqual(Array.from(await keys(sorted)), ["Bob", "Carol", "Alice"]);
|
|
47
44
|
});
|
|
48
45
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, test } from "node:test";
|
|
3
|
+
import AsyncMap from "../../src/drivers/AsyncMap.js";
|
|
4
|
+
import sync from "../../src/operations/sync.js";
|
|
5
|
+
|
|
6
|
+
class SampleAsyncMap extends AsyncMap {
|
|
7
|
+
constructor(iterable) {
|
|
8
|
+
super();
|
|
9
|
+
this.map = new Map(iterable);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async get(key) {
|
|
13
|
+
return this.map.get(key);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async *keys() {
|
|
17
|
+
yield* this.map.keys();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("sync", () => {
|
|
22
|
+
test("converts an async tree to a sync tree", async () => {
|
|
23
|
+
const fixture = new SampleAsyncMap([
|
|
24
|
+
["a", 1],
|
|
25
|
+
["b", 2],
|
|
26
|
+
[
|
|
27
|
+
"more",
|
|
28
|
+
new SampleAsyncMap([
|
|
29
|
+
["c", 3],
|
|
30
|
+
["d", 4],
|
|
31
|
+
]),
|
|
32
|
+
],
|
|
33
|
+
]);
|
|
34
|
+
const result = await sync(fixture);
|
|
35
|
+
assert(result instanceof Map);
|
|
36
|
+
assert.strictEqual(result.get("a"), 1);
|
|
37
|
+
assert.strictEqual(result.get("b"), 2);
|
|
38
|
+
const more = result.get("more");
|
|
39
|
+
assert(more instanceof Map);
|
|
40
|
+
assert.strictEqual(more.get("c"), 3);
|
|
41
|
+
assert.strictEqual(more.get("d"), 4);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import
|
|
3
|
+
import plain from "../../src/operations/plain.js";
|
|
4
4
|
import take from "../../src/operations/take.js";
|
|
5
5
|
|
|
6
6
|
describe("take", () => {
|
|
@@ -12,7 +12,7 @@ describe("take", () => {
|
|
|
12
12
|
d: 4,
|
|
13
13
|
};
|
|
14
14
|
const result = await take(tree, 2);
|
|
15
|
-
assert.deepEqual(await
|
|
15
|
+
assert.deepEqual(await plain(result), {
|
|
16
16
|
a: 1,
|
|
17
17
|
b: 2,
|
|
18
18
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import
|
|
3
|
+
import ObjectMap from "../../src/drivers/ObjectMap.js";
|
|
4
4
|
import toFunction from "../../src/operations/toFunction.js";
|
|
5
5
|
|
|
6
6
|
describe("toFunction", () => {
|
|
7
7
|
test("returns a function that invokes a tree's get() method", async () => {
|
|
8
|
-
const tree = new
|
|
8
|
+
const tree = new ObjectMap({
|
|
9
9
|
a: 1,
|
|
10
10
|
b: 2,
|
|
11
11
|
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import
|
|
4
|
-
import ObjectTree from "../../src/drivers/ObjectTree.js";
|
|
3
|
+
import ObjectMap from "../../src/drivers/ObjectMap.js";
|
|
5
4
|
import traverse from "../../src/operations/traverse.js";
|
|
6
5
|
|
|
7
6
|
describe("traverse", () => {
|
|
8
7
|
test("traverses a path of keys", async () => {
|
|
9
|
-
const tree = new
|
|
8
|
+
const tree = new ObjectMap({
|
|
10
9
|
a1: 1,
|
|
11
10
|
a2: {
|
|
12
11
|
b1: 2,
|
|
@@ -30,9 +29,9 @@ describe("traverse", () => {
|
|
|
30
29
|
});
|
|
31
30
|
|
|
32
31
|
test("traverses from one tree into another", async () => {
|
|
33
|
-
const tree = new
|
|
32
|
+
const tree = new ObjectMap({
|
|
34
33
|
a: {
|
|
35
|
-
b: new
|
|
34
|
+
b: new Map([
|
|
36
35
|
["c", "Hello"],
|
|
37
36
|
["d", "Goodbye"],
|
|
38
37
|
]),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import
|
|
3
|
+
import plain from "../../src/operations/plain.js";
|
|
4
4
|
import withKeys from "../../src/operations/withKeys.js";
|
|
5
5
|
|
|
6
6
|
describe("withKeys", () => {
|
|
@@ -13,7 +13,7 @@ describe("withKeys", () => {
|
|
|
13
13
|
},
|
|
14
14
|
["a", "c"]
|
|
15
15
|
);
|
|
16
|
-
assert.deepEqual(await
|
|
16
|
+
assert.deepEqual(await plain(result), {
|
|
17
17
|
a: 1,
|
|
18
18
|
c: 3,
|
|
19
19
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import
|
|
3
|
+
import SyncMap from "../../src/drivers/SyncMap.js";
|
|
4
4
|
import * as symbols from "../../src/symbols.js";
|
|
5
5
|
import setParent from "../../src/utilities/setParent.js";
|
|
6
6
|
|
|
7
7
|
describe("setParent", () => {
|
|
8
8
|
test("sets a child's parent", () => {
|
|
9
|
-
const parent = new
|
|
9
|
+
const parent = new SyncMap();
|
|
10
10
|
|
|
11
11
|
// Set [symbols.parent] on a plain object.
|
|
12
12
|
const object = {};
|
|
@@ -21,14 +21,14 @@ describe("setParent", () => {
|
|
|
21
21
|
assert.equal(childWithParent[symbols.parent], "parent");
|
|
22
22
|
|
|
23
23
|
// Set `parent` on a tree.
|
|
24
|
-
const tree = new
|
|
24
|
+
const tree = new SyncMap();
|
|
25
25
|
setParent(tree, parent);
|
|
26
26
|
assert.equal(tree.parent, parent);
|
|
27
27
|
|
|
28
28
|
// Leave `parent` alone if it's already set.
|
|
29
|
-
const treeWithParent = new
|
|
30
|
-
treeWithParent.parent =
|
|
29
|
+
const treeWithParent = new SyncMap();
|
|
30
|
+
treeWithParent.parent = parent;
|
|
31
31
|
setParent(treeWithParent, parent);
|
|
32
|
-
assert.equal(treeWithParent.parent,
|
|
32
|
+
assert.equal(treeWithParent.parent, parent);
|
|
33
33
|
});
|
|
34
34
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import
|
|
3
|
+
import ObjectMap from "../../src/drivers/ObjectMap.js";
|
|
4
4
|
import toFunction from "../../src/utilities/toFunction.js";
|
|
5
5
|
|
|
6
6
|
describe("toFunction", () => {
|
|
@@ -10,7 +10,7 @@ describe("toFunction", () => {
|
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
test("returns a tree's getter as a function", async () => {
|
|
13
|
-
const tree = new
|
|
13
|
+
const tree = new ObjectMap({
|
|
14
14
|
a: 1,
|
|
15
15
|
});
|
|
16
16
|
const fn = toFunction(tree);
|
|
@@ -3,23 +3,62 @@ import { describe, test } from "node:test";
|
|
|
3
3
|
import toPlainValue from "../../src/utilities/toPlainValue.js";
|
|
4
4
|
|
|
5
5
|
describe("toPlainValue", () => {
|
|
6
|
-
test("returns
|
|
6
|
+
test("returns primitive value as is", async () => {
|
|
7
|
+
assert.equal(await toPlainValue(1), 1);
|
|
8
|
+
assert.equal(await toPlainValue("hello"), "hello");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("invokes functions and resolves promises", async () => {
|
|
12
|
+
assert.equal(
|
|
13
|
+
await toPlainValue(() => "function result"),
|
|
14
|
+
"function result"
|
|
15
|
+
);
|
|
16
|
+
assert.equal(
|
|
17
|
+
await toPlainValue(Promise.resolve("promise result")),
|
|
18
|
+
"promise result"
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("plain object returned as is", async () => {
|
|
23
|
+
const obj = { a: 1, b: 2 };
|
|
24
|
+
assert.deepEqual(await toPlainValue(obj), obj);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("resolves asynchronous object property", async () => {
|
|
28
|
+
const obj = {
|
|
29
|
+
get a() {
|
|
30
|
+
return Promise.resolve(1);
|
|
31
|
+
},
|
|
32
|
+
b: 2,
|
|
33
|
+
};
|
|
34
|
+
assert.deepEqual(await toPlainValue(obj), { a: 1, b: 2 });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("converts maplike to plain object", async () => {
|
|
38
|
+
const map = new Map([
|
|
39
|
+
["a", 1],
|
|
40
|
+
["b", 2],
|
|
41
|
+
]);
|
|
42
|
+
assert.deepEqual(await toPlainValue(map), { a: 1, b: 2 });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("ArrayBuffer with printable characters is returned as text", async () => {
|
|
46
|
+
const encoder = new TextEncoder();
|
|
47
|
+
const buffer = encoder.encode("printable text").buffer;
|
|
48
|
+
assert.equal(await toPlainValue(buffer), "printable text");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("ArrayBuffer with non-printable characters is returned as base64", async () => {
|
|
52
|
+
const buffer = new Uint8Array([1, 2, 3]).buffer;
|
|
53
|
+
assert.equal(await toPlainValue(buffer), "AQID");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("converts class instance to plain object", async () => {
|
|
7
57
|
class User {
|
|
8
58
|
constructor(name) {
|
|
9
59
|
this.name = name;
|
|
10
60
|
}
|
|
11
61
|
}
|
|
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
62
|
assert.deepEqual(await toPlainValue(new User("Alice")), {
|
|
24
63
|
name: "Alice",
|
|
25
64
|
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import isAsyncTree from "../operations/isAsyncTree.js";
|
|
2
|
-
import MapTree from "./MapTree.js";
|
|
3
|
-
|
|
4
|
-
export default class DeepMapTree extends MapTree {
|
|
5
|
-
async get(key) {
|
|
6
|
-
let value = await super.get(key);
|
|
7
|
-
|
|
8
|
-
if (value instanceof Map) {
|
|
9
|
-
value = Reflect.construct(this.constructor, [value]);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (isAsyncTree(value) && !value.parent) {
|
|
13
|
-
value.parent = this;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return value;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** @returns {boolean} */
|
|
20
|
-
isSubtree(value) {
|
|
21
|
-
return value instanceof Map || isAsyncTree(value);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import isAsyncTree from "../operations/isAsyncTree.js";
|
|
2
|
-
import isPlainObject from "../utilities/isPlainObject.js";
|
|
3
|
-
import ObjectTree from "./ObjectTree.js";
|
|
4
|
-
|
|
5
|
-
export default class DeepObjectTree extends ObjectTree {
|
|
6
|
-
async get(key) {
|
|
7
|
-
let value = await super.get(key);
|
|
8
|
-
if (value instanceof Array || isPlainObject(value)) {
|
|
9
|
-
value = Reflect.construct(this.constructor, [value]);
|
|
10
|
-
}
|
|
11
|
-
return value;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** @returns {boolean} */
|
|
15
|
-
isSubtree(value) {
|
|
16
|
-
return value instanceof Array || isPlainObject(value) || isAsyncTree(value);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import from from "../operations/from.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A tree that is loaded lazily.
|
|
5
|
-
*
|
|
6
|
-
* This is useful in situations that must return a tree synchronously. If
|
|
7
|
-
* constructing the tree requires an asynchronous operation, this class can be
|
|
8
|
-
* used as a wrapper that can be returned immediately. The tree will be loaded
|
|
9
|
-
* the first time the keys() or get() functions are called.
|
|
10
|
-
*
|
|
11
|
-
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
12
|
-
* @implements {AsyncTree}
|
|
13
|
-
*/
|
|
14
|
-
export default class DeferredTree {
|
|
15
|
-
/**
|
|
16
|
-
* @param {Function|Promise<any>} loader
|
|
17
|
-
* @param {{ deep?: boolean }} [options]
|
|
18
|
-
*/
|
|
19
|
-
constructor(loader, options) {
|
|
20
|
-
this.loader = loader;
|
|
21
|
-
this.treePromise = null;
|
|
22
|
-
this._tree = null;
|
|
23
|
-
this._parentUntilLoaded = null;
|
|
24
|
-
this._deep = options?.deep;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async get(key) {
|
|
28
|
-
const tree = await this.tree();
|
|
29
|
-
return tree.get(key);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async loadResult() {
|
|
33
|
-
if (!(this.loader instanceof Promise)) {
|
|
34
|
-
this.loader = this.loader();
|
|
35
|
-
}
|
|
36
|
-
return this.loader;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async keys() {
|
|
40
|
-
const tree = await this.tree();
|
|
41
|
-
return tree.keys();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// A deferred tree's parent generally comes from the loaded tree. However, if
|
|
45
|
-
// someone tries to get or set the parent before the tree is loaded, we store
|
|
46
|
-
// that parent reference and apply it once the tree is loaded.
|
|
47
|
-
get parent() {
|
|
48
|
-
return this._tree?.parent ?? this._parentUntilLoaded;
|
|
49
|
-
}
|
|
50
|
-
set parent(parent) {
|
|
51
|
-
if (this._tree && !this._tree.parent) {
|
|
52
|
-
this._tree.parent = parent;
|
|
53
|
-
} else {
|
|
54
|
-
this._parentUntilLoaded = parent;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async tree() {
|
|
59
|
-
if (this._tree) {
|
|
60
|
-
return this._tree;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Use a promise to ensure the treelike is only converted to a tree once.
|
|
64
|
-
this.treePromise ??= this.loadResult().then((treelike) => {
|
|
65
|
-
const options =
|
|
66
|
-
this._deep !== undefined ? { deep: this._deep } : undefined;
|
|
67
|
-
this._tree = from(treelike, options);
|
|
68
|
-
if (this._parentUntilLoaded) {
|
|
69
|
-
// Now that the tree has been loaded, we can set its parent if it hasn't
|
|
70
|
-
// already been set.
|
|
71
|
-
if (!this._tree.parent) {
|
|
72
|
-
this._tree.parent = this._parentUntilLoaded;
|
|
73
|
-
}
|
|
74
|
-
this._parentUntilLoaded = null;
|
|
75
|
-
}
|
|
76
|
-
return this._tree;
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
return this.treePromise;
|
|
80
|
-
}
|
|
81
|
-
}
|