@weborigami/async-tree 0.5.8 → 0.6.1
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 +43 -35
- package/main.js +1 -2
- package/package.json +4 -7
- package/shared.js +74 -12
- package/src/Tree.js +11 -2
- package/src/drivers/AsyncMap.js +237 -0
- package/src/drivers/{BrowserFileTree.js → BrowserFileMap.js} +54 -38
- package/src/drivers/{calendarTree.js → CalendarMap.js} +80 -63
- package/src/drivers/ConstantMap.js +28 -0
- package/src/drivers/{ExplorableSiteTree.js → ExplorableSiteMap.js} +7 -7
- package/src/drivers/FileMap.js +238 -0
- package/src/drivers/{FunctionTree.js → FunctionMap.js} +19 -22
- package/src/drivers/ObjectMap.js +151 -0
- package/src/drivers/SetMap.js +13 -0
- package/src/drivers/{SiteTree.js → SiteMap.js} +17 -20
- package/src/drivers/SyncMap.js +260 -0
- package/src/jsonKeys.d.ts +2 -2
- package/src/jsonKeys.js +20 -5
- package/src/operations/addNextPrevious.js +35 -36
- package/src/operations/assign.js +27 -23
- package/src/operations/cache.js +30 -36
- package/src/operations/cachedKeyFunctions.js +1 -1
- package/src/operations/calendar.js +5 -0
- package/src/operations/child.js +35 -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 +30 -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 +28 -30
- package/src/operations/mapExtension.js +20 -16
- package/src/operations/mapReduce.js +38 -24
- package/src/operations/mask.js +54 -29
- 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 +20 -22
- package/src/operations/plain.js +6 -6
- package/src/operations/reduce.js +16 -0
- 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/set.js +20 -0
- 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 +14 -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 +18 -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 +24 -13
- 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 +21 -19
- package/test/SampleAsyncMap.js +34 -0
- package/test/browser/assert.js +20 -0
- package/test/browser/index.html +53 -21
- package/test/drivers/AsyncMap.test.js +119 -0
- package/test/drivers/{BrowserFileTree.test.js → BrowserFileMap.test.js} +50 -33
- package/test/drivers/{calendarTree.test.js → CalendarMap.test.js} +17 -19
- package/test/drivers/ConstantMap.test.js +15 -0
- package/test/drivers/{ExplorableSiteTree.test.js → ExplorableSiteMap.test.js} +29 -14
- package/test/drivers/FileMap.test.js +156 -0
- package/test/drivers/FunctionMap.test.js +56 -0
- package/test/drivers/ObjectMap.test.js +194 -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 +335 -0
- package/test/jsonKeys.test.js +18 -6
- package/test/operations/addNextPrevious.test.js +3 -2
- package/test/operations/assign.test.js +30 -35
- package/test/operations/cache.test.js +17 -12
- package/test/operations/cachedKeyFunctions.test.js +12 -9
- package/test/operations/child.test.js +34 -0
- package/test/operations/clear.test.js +6 -27
- package/test/operations/deepEntries.test.js +32 -0
- package/test/operations/deepMerge.test.js +23 -16
- 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 +25 -31
- package/test/operations/globKeys.test.js +9 -9
- package/test/operations/groupBy.test.js +6 -5
- package/test/operations/inners.test.js +17 -14
- 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 +40 -30
- package/test/operations/mapExtension.test.js +6 -6
- package/test/operations/mapReduce.test.js +14 -12
- package/test/operations/mask.test.js +16 -3
- package/test/operations/match.test.js +2 -2
- package/test/operations/merge.test.js +20 -14
- package/test/operations/paginate.test.js +5 -5
- package/test/operations/parent.test.js +3 -3
- package/test/operations/paths.test.js +20 -27
- package/test/operations/plain.test.js +8 -8
- package/test/operations/regExpKeys.test.js +22 -18
- package/test/operations/reverse.test.js +4 -3
- package/test/operations/scope.test.js +6 -5
- package/test/operations/set.test.js +11 -0
- 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 +17 -5
- package/test/operations/withKeys.test.js +2 -2
- package/test/utilities/castArrayLike.test.js +53 -0
- 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
package/browser.js
CHANGED
package/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import AsyncMap from "./src/drivers/AsyncMap.js";
|
|
2
2
|
|
|
3
3
|
export * from "./main.js";
|
|
4
4
|
|
|
5
|
-
export type Invocable = Function |
|
|
5
|
+
export type Invocable = Function | Maplike | Unpackable;
|
|
6
6
|
|
|
7
|
-
export type KeyFn = (key: any,
|
|
7
|
+
export type KeyFn = (key: any, map: SyncOrAsyncMap) => any;
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* An object with a non-trivial `toString` method.
|
|
@@ -17,36 +17,23 @@ export type HasString = {
|
|
|
17
17
|
toString(): string;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
unpack?(): Promise<any>;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type PlainObject = {
|
|
30
|
-
[key: string]: any;
|
|
20
|
+
export type MapExtensionOptions = {
|
|
21
|
+
deep?: boolean;
|
|
22
|
+
description?: string;
|
|
23
|
+
extension?: string;
|
|
24
|
+
needsSourceValue?: boolean;
|
|
25
|
+
value?: ValueKeyFn;
|
|
31
26
|
};
|
|
32
27
|
|
|
33
|
-
export type
|
|
34
|
-
|
|
35
|
-
export type Stringlike = string | HasString;
|
|
36
|
-
|
|
37
|
-
export type NativeTreelike =
|
|
28
|
+
export type Maplike =
|
|
38
29
|
any[] |
|
|
39
|
-
|
|
30
|
+
Iterator<any> |
|
|
40
31
|
Function |
|
|
41
|
-
|
|
32
|
+
SyncOrAsyncMap |
|
|
42
33
|
PlainObject |
|
|
43
34
|
Set<any>;
|
|
44
35
|
|
|
45
|
-
export type
|
|
46
|
-
NativeTreelike |
|
|
47
|
-
Unpackable;
|
|
48
|
-
|
|
49
|
-
export type TreeMapOptions = {
|
|
36
|
+
export type MapOptions = {
|
|
50
37
|
deep?: boolean;
|
|
51
38
|
description?: string;
|
|
52
39
|
extension?: string;
|
|
@@ -56,15 +43,36 @@ export type TreeMapOptions = {
|
|
|
56
43
|
value?: ValueKeyFn;
|
|
57
44
|
};
|
|
58
45
|
|
|
59
|
-
export
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
46
|
+
export interface SyncTree<MapType> {
|
|
47
|
+
child(key: any): MapType;
|
|
48
|
+
parent: MapType | null;
|
|
49
|
+
trailingSlashKeys: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface AsyncTree<MapType> {
|
|
53
|
+
child(key: any): Promise<MapType>;
|
|
54
|
+
parent: MapType | null;
|
|
55
|
+
trailingSlashKeys: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A packed value is one that can be written to a file via fs.writeFile or into
|
|
60
|
+
* an HTTP response via response.write, or readily converted to such a form.
|
|
61
|
+
*/
|
|
62
|
+
export type Packed = (ArrayBuffer | Buffer | ReadableStream | string | String | TypedArray) & {
|
|
63
|
+
parent?: SyncOrAsyncMap|null;
|
|
64
|
+
unpack?(): Promise<any>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type PlainObject = {
|
|
68
|
+
[key: string]: any;
|
|
65
69
|
};
|
|
66
|
-
|
|
67
|
-
export type
|
|
70
|
+
|
|
71
|
+
export type ReduceFn = (mapped: Map<any, any>, source: SyncOrAsyncMap) => any | Promise<any>;
|
|
72
|
+
|
|
73
|
+
export type Stringlike = string | HasString;
|
|
74
|
+
|
|
75
|
+
export type SyncOrAsyncMap = Map<any, any> | AsyncMap;
|
|
68
76
|
|
|
69
77
|
export type TypedArray =
|
|
70
78
|
Float32Array |
|
|
@@ -86,4 +94,4 @@ export type Unpackable = {
|
|
|
86
94
|
*/
|
|
87
95
|
export type UnpackFunction = (input: Packed, options?: any) => any;
|
|
88
96
|
|
|
89
|
-
export type ValueKeyFn = (value: any, key: any,
|
|
97
|
+
export type ValueKeyFn = (value: any, key: any, map: SyncOrAsyncMap) => any;
|
package/main.js
CHANGED
package/package.json
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/async-tree",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
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
|
-
"dependencies": {
|
|
10
|
-
"@weborigami/types": "0.5.8"
|
|
11
|
-
},
|
|
12
9
|
"devDependencies": {
|
|
13
|
-
"@types/node": "24.
|
|
14
|
-
"puppeteer": "24.
|
|
15
|
-
"typescript": "5.9.
|
|
10
|
+
"@types/node": "24.10.1",
|
|
11
|
+
"puppeteer": "24.30.0",
|
|
12
|
+
"typescript": "5.9.3"
|
|
16
13
|
},
|
|
17
14
|
"scripts": {
|
|
18
15
|
"headlessTest": "node test/browser/headlessTest.js",
|
package/shared.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
// Exports for both Node.js and browser
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export { default as
|
|
11
|
-
export { default as
|
|
12
|
-
export { default as
|
|
13
|
-
export { default as
|
|
3
|
+
import { default as ExplorableSiteMap } from "./src/drivers/ExplorableSiteMap.js";
|
|
4
|
+
import { default as FileMap } from "./src/drivers/FileMap.js";
|
|
5
|
+
import { default as FunctionMap } from "./src/drivers/FunctionMap.js";
|
|
6
|
+
import { default as ObjectMap } from "./src/drivers/ObjectMap.js";
|
|
7
|
+
import { default as SetMap } from "./src/drivers/SetMap.js";
|
|
8
|
+
import { default as SiteMap } from "./src/drivers/SiteMap.js";
|
|
9
|
+
|
|
10
|
+
export { default as AsyncMap } from "./src/drivers/AsyncMap.js";
|
|
11
|
+
export { default as CalendarMap } from "./src/drivers/CalendarMap.js";
|
|
12
|
+
export { default as ConstantMap } from "./src/drivers/ConstantMap.js";
|
|
13
|
+
export { default as SyncMap } from "./src/drivers/SyncMap.js";
|
|
14
|
+
export * as extension from "./src/extension.js";
|
|
14
15
|
export * as jsonKeys from "./src/jsonKeys.js";
|
|
16
|
+
export { default as reduce } from "./src/operations/reduce.js";
|
|
15
17
|
export { default as scope } from "./src/operations/scope.js";
|
|
16
18
|
export * as symbols from "./src/symbols.js";
|
|
17
19
|
export * as trailingSlash from "./src/trailingSlash.js";
|
|
@@ -19,9 +21,9 @@ export { default as TraverseError } from "./src/TraverseError.js";
|
|
|
19
21
|
export * as Tree from "./src/Tree.js";
|
|
20
22
|
export { default as box } from "./src/utilities/box.js";
|
|
21
23
|
export { default as castArraylike } from "./src/utilities/castArraylike.js";
|
|
24
|
+
export { default as getTreeArgument } from "./src/utilities/getMapArgument.js";
|
|
22
25
|
export { default as getParent } from "./src/utilities/getParent.js";
|
|
23
26
|
export { default as getRealmObjectPrototype } from "./src/utilities/getRealmObjectPrototype.js";
|
|
24
|
-
export { default as getTreeArgument } from "./src/utilities/getTreeArgument.js";
|
|
25
27
|
export { default as isPacked } from "./src/utilities/isPacked.js";
|
|
26
28
|
export { default as isPlainObject } from "./src/utilities/isPlainObject.js";
|
|
27
29
|
export { default as isStringlike } from "./src/utilities/isStringlike.js";
|
|
@@ -32,3 +34,63 @@ export { default as pathFromKeys } from "./src/utilities/pathFromKeys.js";
|
|
|
32
34
|
export { default as setParent } from "./src/utilities/setParent.js";
|
|
33
35
|
export { default as toPlainValue } from "./src/utilities/toPlainValue.js";
|
|
34
36
|
export { default as toString } from "./src/utilities/toString.js";
|
|
37
|
+
|
|
38
|
+
export { ExplorableSiteMap, FileMap, FunctionMap, ObjectMap, SetMap, SiteMap };
|
|
39
|
+
|
|
40
|
+
export class DeepObjectMap extends ObjectMap {
|
|
41
|
+
constructor(object) {
|
|
42
|
+
super(object, { deep: true });
|
|
43
|
+
console.warn("DeepObjectMap is deprecated. Please use ObjectMap instead.");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class ObjectTree extends ObjectMap {
|
|
48
|
+
constructor(...args) {
|
|
49
|
+
super(...args);
|
|
50
|
+
console.warn("ObjectTree is deprecated. Please use ObjectMap instead.");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class DeepObjectTree extends ObjectMap {
|
|
55
|
+
constructor(object) {
|
|
56
|
+
super(object, { deep: true });
|
|
57
|
+
console.warn("DeepObjectTree is deprecated. Please use ObjectMap instead.");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class ExplorableSiteTree extends ExplorableSiteMap {
|
|
62
|
+
constructor(href) {
|
|
63
|
+
super(href);
|
|
64
|
+
console.warn(
|
|
65
|
+
"ExplorableSiteTree is deprecated. Please use ExplorableSiteMap instead."
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export class FileTree extends FileMap {
|
|
71
|
+
constructor(...args) {
|
|
72
|
+
super(...args);
|
|
73
|
+
console.warn("FileTree is deprecated. Please use FileMap instead.");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export class FunctionTree extends FunctionMap {
|
|
78
|
+
constructor(...args) {
|
|
79
|
+
super(...args);
|
|
80
|
+
console.warn("FunctionTree is deprecated. Please use FunctionMap instead.");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class SetTree extends SetMap {
|
|
85
|
+
constructor(set) {
|
|
86
|
+
super(set);
|
|
87
|
+
console.warn("SetTree is deprecated. Please use SetMap instead.");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export class SiteTree extends SiteMap {
|
|
92
|
+
constructor(...args) {
|
|
93
|
+
super(...args);
|
|
94
|
+
console.warn("SiteTree is deprecated. Please use SiteMap instead.");
|
|
95
|
+
}
|
|
96
|
+
}
|
package/src/Tree.js
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
* Collection of functions for working with async trees
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export { default as calendar } from "./drivers/calendarTree.js";
|
|
6
|
-
export { default as constant } from "./drivers/constantTree.js";
|
|
7
5
|
export { default as addNextPrevious } from "./operations/addNextPrevious.js";
|
|
8
6
|
export { default as assign } from "./operations/assign.js";
|
|
9
7
|
export { default as cache } from "./operations/cache.js";
|
|
8
|
+
export { default as calendar } from "./operations/calendar.js";
|
|
9
|
+
export { default as child } from "./operations/child.js";
|
|
10
10
|
export { default as clear } from "./operations/clear.js";
|
|
11
|
+
export { default as constant } from "./operations/constant.js";
|
|
12
|
+
export { default as deepEntries } from "./operations/deepEntries.js";
|
|
11
13
|
export { default as deepMap } from "./operations/deepMap.js";
|
|
12
14
|
export { default as deepMerge } from "./operations/deepMerge.js";
|
|
13
15
|
export { default as deepReverse } from "./operations/deepReverse.js";
|
|
@@ -30,6 +32,9 @@ export { default as inners } from "./operations/inners.js";
|
|
|
30
32
|
export { default as invokeFunctions } from "./operations/invokeFunctions.js";
|
|
31
33
|
export { default as isAsyncMutableTree } from "./operations/isAsyncMutableTree.js";
|
|
32
34
|
export { default as isAsyncTree } from "./operations/isAsyncTree.js";
|
|
35
|
+
export { default as isMap } from "./operations/isMap.js";
|
|
36
|
+
export { default as isMaplike } from "./operations/isMaplike.js";
|
|
37
|
+
export { default as isReadOnlyMap } from "./operations/isReadOnlyMap.js";
|
|
33
38
|
export { default as isTraversable } from "./operations/isTraversable.js";
|
|
34
39
|
export { default as isTreelike } from "./operations/isTreelike.js";
|
|
35
40
|
export { default as json } from "./operations/json.js";
|
|
@@ -45,12 +50,16 @@ export { default as paginate } from "./operations/paginate.js";
|
|
|
45
50
|
export { default as parent } from "./operations/parent.js";
|
|
46
51
|
export { default as paths } from "./operations/paths.js";
|
|
47
52
|
export { default as plain } from "./operations/plain.js";
|
|
53
|
+
export { default as reduce } from "./operations/reduce.js";
|
|
48
54
|
export { default as regExpKeys } from "./operations/regExpKeys.js";
|
|
49
55
|
export { default as reverse } from "./operations/reverse.js";
|
|
50
56
|
export { default as root } from "./operations/root.js";
|
|
51
57
|
export { default as scope } from "./operations/scope.js";
|
|
58
|
+
export { default as set } from "./operations/set.js";
|
|
52
59
|
export { default as shuffle } from "./operations/shuffle.js";
|
|
60
|
+
export { default as size } from "./operations/size.js";
|
|
53
61
|
export { default as sort } from "./operations/sort.js";
|
|
62
|
+
export { default as sync } from "./operations/sync.js";
|
|
54
63
|
export { default as take } from "./operations/take.js";
|
|
55
64
|
export { default as text } from "./operations/text.js";
|
|
56
65
|
export { default as toFunction } from "./operations/toFunction.js";
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import isMap from "../operations/isMap.js";
|
|
2
|
+
import * as trailingSlash from "../trailingSlash.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Base class for asynchronous maps. These have the same interface as Map but the methods
|
|
6
|
+
* are asynchronous.
|
|
7
|
+
*
|
|
8
|
+
* @typedef {import("../../index.ts").AsyncTree<AsyncMap>} AsyncTree
|
|
9
|
+
* @implements {AsyncTree}
|
|
10
|
+
*/
|
|
11
|
+
export default class AsyncMap {
|
|
12
|
+
/** @type {AsyncMap|null} */
|
|
13
|
+
_parent = null;
|
|
14
|
+
|
|
15
|
+
_readOnly;
|
|
16
|
+
|
|
17
|
+
[Symbol.asyncIterator]() {
|
|
18
|
+
return this.entries();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Return the child node for the given key, creating it if necessary.
|
|
23
|
+
*/
|
|
24
|
+
async child(key) {
|
|
25
|
+
let result = await this.get(key);
|
|
26
|
+
|
|
27
|
+
// If child is already a map we can use it as is
|
|
28
|
+
if (!isMap(result)) {
|
|
29
|
+
// Create new child node using no-arg constructor
|
|
30
|
+
result = new /** @type {any} */ (this.constructor)();
|
|
31
|
+
await this.set(key, result);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
result.parent = this;
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Remove all key/value entries from the map.
|
|
40
|
+
*
|
|
41
|
+
* This method invokes the `keys()` and `delete()` methods.
|
|
42
|
+
*/
|
|
43
|
+
async clear() {
|
|
44
|
+
const promises = [];
|
|
45
|
+
for await (const key of this.keys()) {
|
|
46
|
+
promises.push(this.delete(key));
|
|
47
|
+
}
|
|
48
|
+
await Promise.all(promises);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Removes the entry for the given key, return true if an entry was removed
|
|
53
|
+
* and false if there was no entry for the key.
|
|
54
|
+
*
|
|
55
|
+
* @param {any} key
|
|
56
|
+
* @returns {Promise<boolean>}
|
|
57
|
+
*/
|
|
58
|
+
async delete(key) {
|
|
59
|
+
throw new Error("delete() not implemented");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns a new `AsyncIterator` object that contains a two-member array of
|
|
64
|
+
* [key, value] for each element in the map in insertion order.
|
|
65
|
+
*
|
|
66
|
+
* This method invokes the `keys()` and `get()` methods.
|
|
67
|
+
*
|
|
68
|
+
* @returns {AsyncIterableIterator<[any, any]>}
|
|
69
|
+
*/
|
|
70
|
+
async *entries() {
|
|
71
|
+
const keys = [];
|
|
72
|
+
const valuePromises = [];
|
|
73
|
+
// Invoke get() calls without waiting; some may take longer than others
|
|
74
|
+
for await (const key of this.keys()) {
|
|
75
|
+
keys.push(key);
|
|
76
|
+
valuePromises.push(this.get(key));
|
|
77
|
+
}
|
|
78
|
+
// Now wait for all promises to resolve
|
|
79
|
+
const values = await Promise.all(valuePromises);
|
|
80
|
+
for (let i = 0; i < keys.length; i++) {
|
|
81
|
+
yield [keys[i], values[i]];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Calls `callback` once for each key/value pair in the map, in insertion order.
|
|
87
|
+
*
|
|
88
|
+
* This method invokes the `entries()` method.
|
|
89
|
+
*
|
|
90
|
+
* @param {(value: any, key: any, thisArg: any) => Promise<void>} callback
|
|
91
|
+
* @param {any?} thisArg
|
|
92
|
+
*/
|
|
93
|
+
async forEach(callback, thisArg = this) {
|
|
94
|
+
for await (const [key, value] of this.entries()) {
|
|
95
|
+
await callback(value, key, thisArg);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Returns the value associated with the key, or undefined if there is none.
|
|
101
|
+
*
|
|
102
|
+
* @param {any} key
|
|
103
|
+
* @returns {Promise<any>}
|
|
104
|
+
*/
|
|
105
|
+
async get(key) {
|
|
106
|
+
throw new Error("get() not implemented");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Groups items from an async iterable into an AsyncMap according to the keys
|
|
111
|
+
* returned by the given function.
|
|
112
|
+
*
|
|
113
|
+
* @param {Iterable<any>|AsyncIterable<any>} iterable
|
|
114
|
+
* @param {(element: any, index: any) => Promise<any>} keyFn
|
|
115
|
+
* @returns {Promise<Map>}
|
|
116
|
+
*/
|
|
117
|
+
static async groupBy(iterable, keyFn) {
|
|
118
|
+
const map = new Map();
|
|
119
|
+
let index = 0;
|
|
120
|
+
for await (const element of iterable) {
|
|
121
|
+
const key = await keyFn(element, index);
|
|
122
|
+
if (!map.has(key)) {
|
|
123
|
+
map.set(key, []);
|
|
124
|
+
}
|
|
125
|
+
map.get(key).push(element);
|
|
126
|
+
index++;
|
|
127
|
+
}
|
|
128
|
+
return map;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Returns true if the given key appears in the set returned by keys().
|
|
133
|
+
*
|
|
134
|
+
* It doesn't matter whether the value returned by get() is defined or not.
|
|
135
|
+
*
|
|
136
|
+
* If the requested key has a trailing slash but has no associated value, but
|
|
137
|
+
* the alternate form with a slash does appear, this returns true.
|
|
138
|
+
*
|
|
139
|
+
* @param {any} key
|
|
140
|
+
*/
|
|
141
|
+
async has(key) {
|
|
142
|
+
const alternateKey = !trailingSlash.has(key)
|
|
143
|
+
? trailingSlash.add(key)
|
|
144
|
+
: null;
|
|
145
|
+
for await (const k of this.keys()) {
|
|
146
|
+
if (k === key) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
if (alternateKey && k === alternateKey) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Returns a new `AsyncIterator` object that contains the keys for each
|
|
158
|
+
* element in the map in insertion order.
|
|
159
|
+
*
|
|
160
|
+
* @returns {AsyncIterableIterator<any>}
|
|
161
|
+
*/
|
|
162
|
+
async *keys() {
|
|
163
|
+
throw new Error("keys() not implemented");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The parent of this node in a tree.
|
|
168
|
+
*/
|
|
169
|
+
get parent() {
|
|
170
|
+
return this._parent;
|
|
171
|
+
}
|
|
172
|
+
set parent(parent) {
|
|
173
|
+
this._parent = parent;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* True if the object is read-only. This will be true if `get()` has been
|
|
178
|
+
* overridden but `set()` and `delete()` have not.
|
|
179
|
+
*/
|
|
180
|
+
get readOnly() {
|
|
181
|
+
return (
|
|
182
|
+
this.get !== AsyncMap.prototype.get &&
|
|
183
|
+
(this.set === AsyncMap.prototype.set ||
|
|
184
|
+
this.delete === AsyncMap.prototype.delete)
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Sets the value for the given key.
|
|
190
|
+
*
|
|
191
|
+
* @param {any} key
|
|
192
|
+
* @param {any} value
|
|
193
|
+
* @returns {Promise<AsyncMap>}
|
|
194
|
+
*/
|
|
195
|
+
async set(key, value) {
|
|
196
|
+
throw new Error("set() not implemented");
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Returns the number of keys in the map.
|
|
201
|
+
*
|
|
202
|
+
* The `size` property invokes an overridden `keys()` to ensure proper
|
|
203
|
+
* behavior in subclasses. Because a subclass may not enforce a direct
|
|
204
|
+
* correspondence between `keys()` and `get()`, the size may not reflect the
|
|
205
|
+
* number of values that can be retrieved.
|
|
206
|
+
*
|
|
207
|
+
* @type {Promise<number>}
|
|
208
|
+
*/
|
|
209
|
+
get size() {
|
|
210
|
+
return (async () => {
|
|
211
|
+
let count = 0;
|
|
212
|
+
for await (const _ of this.keys()) {
|
|
213
|
+
count++;
|
|
214
|
+
}
|
|
215
|
+
return count;
|
|
216
|
+
})();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
trailingSlashKeys = false;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Returns a new `AsyncIterator` object that contains the values for each
|
|
223
|
+
* element in the map in insertion order.
|
|
224
|
+
*
|
|
225
|
+
* @returns {AsyncIterableIterator<any>}
|
|
226
|
+
*/
|
|
227
|
+
async *values() {
|
|
228
|
+
const valuePromises = [];
|
|
229
|
+
// Invoke get() calls without waiting; some may take longer than others
|
|
230
|
+
for await (const key of this.keys()) {
|
|
231
|
+
valuePromises.push(this.get(key));
|
|
232
|
+
}
|
|
233
|
+
// Now wait for all promises to resolve
|
|
234
|
+
const values = await Promise.all(valuePromises);
|
|
235
|
+
yield* values;
|
|
236
|
+
}
|
|
237
|
+
}
|