@weborigami/async-tree 0.6.9 → 0.6.10
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 +1 -1
- package/shared.js +2 -1
- package/src/TraverseError.js +6 -3
- package/src/drivers/CalendarMap.js +12 -4
- package/src/operations/addNextPrevious.js +2 -2
- package/src/operations/assign.js +7 -3
- package/src/operations/cache.js +4 -4
- package/src/operations/child.js +2 -2
- package/src/operations/clear.js +3 -3
- package/src/operations/deepEntries.js +3 -3
- package/src/operations/deepMap.js +2 -2
- package/src/operations/deepMerge.js +15 -2
- package/src/operations/deepReverse.js +4 -2
- package/src/operations/deepTake.js +3 -2
- package/src/operations/deepText.js +5 -4
- package/src/operations/deepValuesIterator.js +3 -3
- package/src/operations/delete.js +4 -5
- package/src/operations/entries.js +2 -2
- package/src/operations/filter.js +2 -2
- package/src/operations/first.js +2 -2
- package/src/operations/forEach.js +6 -2
- package/src/operations/from.js +5 -2
- package/src/operations/globKeys.js +2 -2
- package/src/operations/groupBy.js +5 -4
- package/src/operations/has.js +2 -2
- package/src/operations/indent.js +9 -3
- package/src/operations/inners.js +2 -2
- package/src/operations/invokeFunctions.js +2 -2
- package/src/operations/json.js +2 -2
- package/src/operations/keys.js +2 -2
- package/src/operations/length.js +2 -2
- package/src/operations/map.js +22 -18
- package/src/operations/mapExtension.js +3 -3
- package/src/operations/mapReduce.js +4 -4
- package/src/operations/mask.js +6 -6
- package/src/operations/match.js +7 -18
- package/src/operations/merge.js +13 -2
- package/src/operations/paginate.js +3 -2
- package/src/operations/parent.js +2 -2
- package/src/operations/paths.js +2 -2
- package/src/operations/plain.js +2 -2
- package/src/operations/reduce.js +2 -2
- package/src/operations/regExpKeys.js +5 -3
- package/src/operations/reverse.js +2 -2
- package/src/operations/root.js +2 -2
- package/src/operations/scope.js +5 -4
- package/src/operations/set.js +2 -2
- package/src/operations/shuffle.js +2 -2
- package/src/operations/size.js +2 -2
- package/src/operations/sort.js +4 -4
- package/src/operations/sync.js +2 -2
- package/src/operations/take.js +3 -2
- package/src/operations/toFunction.js +2 -2
- package/src/operations/traverse.js +3 -1
- package/src/operations/traverseOrThrow.js +40 -8
- package/src/operations/traversePath.js +5 -3
- package/src/operations/values.js +2 -2
- package/src/operations/visit.js +2 -2
- package/src/operations/withKeys.js +5 -3
- package/src/utilities/args.js +128 -0
- package/src/utilities/interop.js +9 -0
- package/src/utilities/setParent.js +1 -1
- package/test/operations/root.test.js +2 -2
- package/test/operations/traverse.test.js +1 -32
- package/test/operations/traverseOrThrow.test.js +73 -0
- package/src/utilities/getMapArgument.js +0 -38
package/package.json
CHANGED
package/shared.js
CHANGED
|
@@ -19,11 +19,12 @@ export * as symbols from "./src/symbols.js";
|
|
|
19
19
|
export * as trailingSlash from "./src/trailingSlash.js";
|
|
20
20
|
export { default as TraverseError } from "./src/TraverseError.js";
|
|
21
21
|
export * as Tree from "./src/Tree.js";
|
|
22
|
+
export * as args from "./src/utilities/args.js";
|
|
22
23
|
export { default as box } from "./src/utilities/box.js";
|
|
23
24
|
export { default as castArraylike } from "./src/utilities/castArraylike.js";
|
|
24
|
-
export { default as getTreeArgument } from "./src/utilities/getMapArgument.js";
|
|
25
25
|
export { default as getParent } from "./src/utilities/getParent.js";
|
|
26
26
|
export { default as getRealmObjectPrototype } from "./src/utilities/getRealmObjectPrototype.js";
|
|
27
|
+
export { default as interop } from "./src/utilities/interop.js";
|
|
27
28
|
export { default as isPacked } from "./src/utilities/isPacked.js";
|
|
28
29
|
export { default as isPlainObject } from "./src/utilities/isPlainObject.js";
|
|
29
30
|
export { default as isPrimitive } from "./src/utilities/isPrimitive.js";
|
package/src/TraverseError.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Error class thrown by Tree.traverseOrThrow()
|
|
3
3
|
*/
|
|
4
|
-
export default class TraverseError extends
|
|
5
|
-
constructor(message, options) {
|
|
4
|
+
export default class TraverseError extends Error {
|
|
5
|
+
constructor(message, options = {}) {
|
|
6
6
|
super(message);
|
|
7
7
|
this.name = "TraverseError";
|
|
8
|
-
|
|
8
|
+
this.head = options.head;
|
|
9
|
+
this.lastValue = options.lastValue;
|
|
10
|
+
this.keys = options.keys;
|
|
11
|
+
this.position = options.position;
|
|
9
12
|
}
|
|
10
13
|
}
|
|
@@ -48,8 +48,8 @@ export default class CalendarMap extends SyncMap {
|
|
|
48
48
|
end.day = end.month
|
|
49
49
|
? daysInMonth(end.year, end.month)
|
|
50
50
|
: end.year
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
? 31 // Last day of December
|
|
52
|
+
: today.getDate();
|
|
53
53
|
}
|
|
54
54
|
if (end.month === undefined) {
|
|
55
55
|
end.month = end.year ? 12 : today.getMonth() + 1;
|
|
@@ -77,7 +77,7 @@ export default class CalendarMap extends SyncMap {
|
|
|
77
77
|
keys() {
|
|
78
78
|
return Array.from(
|
|
79
79
|
{ length: this.end.year - this.start.year + 1 },
|
|
80
|
-
(_, i) => this.start.year + i
|
|
80
|
+
(_, i) => this.start.year + i,
|
|
81
81
|
)[Symbol.iterator]();
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -91,6 +91,14 @@ function dateParts(date) {
|
|
|
91
91
|
year = parts[0] ? parseInt(parts[0]) : undefined;
|
|
92
92
|
month = parts[1] ? parseInt(parts[1]) : undefined;
|
|
93
93
|
day = parts[2] ? parseInt(parts[2]) : undefined;
|
|
94
|
+
|
|
95
|
+
if (
|
|
96
|
+
(year && isNaN(year)) ||
|
|
97
|
+
(month && isNaN(month)) ||
|
|
98
|
+
(day && isNaN(day))
|
|
99
|
+
) {
|
|
100
|
+
throw new TypeError(`Tree.calendar: invalid date: ${date}`);
|
|
101
|
+
}
|
|
94
102
|
}
|
|
95
103
|
return { year, month, day };
|
|
96
104
|
}
|
|
@@ -135,7 +143,7 @@ function daysForMonthMap(year, month, start, end, valueFn) {
|
|
|
135
143
|
*keys() {
|
|
136
144
|
const days = Array.from(
|
|
137
145
|
{ length: daysInMonth(year, month) },
|
|
138
|
-
(_, i) => i + 1
|
|
146
|
+
(_, i) => i + 1,
|
|
139
147
|
);
|
|
140
148
|
yield* days
|
|
141
149
|
.filter((day) => this.inRange(day))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import AsyncMap from "../drivers/AsyncMap.js";
|
|
2
|
-
import
|
|
2
|
+
import * as args from "../utilities/args.js";
|
|
3
3
|
import keys from "./keys.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -9,7 +9,7 @@ import keys from "./keys.js";
|
|
|
9
9
|
* @returns {Promise<AsyncMap>}
|
|
10
10
|
*/
|
|
11
11
|
export default async function addNextPrevious(maplike) {
|
|
12
|
-
const source = await
|
|
12
|
+
const source = await args.map(maplike, "Tree.addNextPrevious");
|
|
13
13
|
let sourceKeys;
|
|
14
14
|
|
|
15
15
|
return Object.assign(new AsyncMap(), {
|
package/src/operations/assign.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import child from "./child.js";
|
|
3
3
|
import isMaplike from "./isMaplike.js";
|
|
4
4
|
|
|
@@ -15,8 +15,12 @@ import isMaplike from "./isMaplike.js";
|
|
|
15
15
|
* @param {Maplike} source
|
|
16
16
|
*/
|
|
17
17
|
export default async function assign(target, source) {
|
|
18
|
-
const targetTree = await
|
|
19
|
-
|
|
18
|
+
const targetTree = await args.map(target, "Tree.assign", {
|
|
19
|
+
position: 1,
|
|
20
|
+
});
|
|
21
|
+
const sourceTree = await args.map(source, "Tree.assign", {
|
|
22
|
+
position: 2,
|
|
23
|
+
});
|
|
20
24
|
if ("readOnly" in targetTree && targetTree.readOnly) {
|
|
21
25
|
throw new TypeError("assign: Target must be a read/write map");
|
|
22
26
|
}
|
package/src/operations/cache.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AsyncMap from "../drivers/AsyncMap.js";
|
|
2
2
|
import SyncMap from "../drivers/SyncMap.js";
|
|
3
|
-
import
|
|
3
|
+
import * as args from "../utilities/args.js";
|
|
4
4
|
import child from "./child.js";
|
|
5
5
|
import isMap from "./isMap.js";
|
|
6
6
|
import isReadOnlyMap from "./isReadOnlyMap.js";
|
|
@@ -19,14 +19,14 @@ import keys from "./keys.js";
|
|
|
19
19
|
* @returns {Promise<SyncMap|AsyncMap>}
|
|
20
20
|
*/
|
|
21
21
|
export default async function treeCache(sourceMaplike, cacheMaplike) {
|
|
22
|
-
const source = await
|
|
23
|
-
position:
|
|
22
|
+
const source = await args.map(sourceMaplike, "Tree.cache", {
|
|
23
|
+
position: 1,
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
let cache;
|
|
27
27
|
if (cacheMaplike) {
|
|
28
28
|
cache = /** @type {any} */ (
|
|
29
|
-
await
|
|
29
|
+
await args.map(cacheMaplike, "Tree.cache", { position: 2 })
|
|
30
30
|
);
|
|
31
31
|
// @ts-ignore
|
|
32
32
|
if (isReadOnlyMap(cache)) {
|
package/src/operations/child.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import setParent from "../utilities/setParent.js";
|
|
3
3
|
import isMap from "./isMap.js";
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ import isMap from "./isMap.js";
|
|
|
10
10
|
* @param {Maplike} maplike
|
|
11
11
|
*/
|
|
12
12
|
export default async function child(maplike, key) {
|
|
13
|
-
const map = await
|
|
13
|
+
const map = await args.map(maplike, "Tree.child", { position: 0 });
|
|
14
14
|
|
|
15
15
|
let result;
|
|
16
16
|
|
package/src/operations/clear.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Remove all entries from the map.
|
|
@@ -8,9 +8,9 @@ import getMapArgument from "../utilities/getMapArgument.js";
|
|
|
8
8
|
* @param {Maplike} maplike
|
|
9
9
|
*/
|
|
10
10
|
export default async function clear(maplike) {
|
|
11
|
-
const map = await
|
|
11
|
+
const map = await args.map(maplike, "Tree.clear");
|
|
12
12
|
if ("readOnly" in map && map.readOnly) {
|
|
13
|
-
throw new TypeError("clear: target map is read-only");
|
|
13
|
+
throw new TypeError("Tree.clear: target map is read-only");
|
|
14
14
|
}
|
|
15
15
|
const promises = [];
|
|
16
16
|
for await (const key of map.keys()) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import entries from "./entries.js";
|
|
3
3
|
import isMap from "./isMap.js";
|
|
4
4
|
|
|
@@ -10,14 +10,14 @@ import isMap from "./isMap.js";
|
|
|
10
10
|
* @param {Maplike} maplike
|
|
11
11
|
*/
|
|
12
12
|
export default async function deepEntries(maplike) {
|
|
13
|
-
const tree = await
|
|
13
|
+
const tree = await args.map(maplike, "Tree.deepEntries");
|
|
14
14
|
|
|
15
15
|
const treeEntries = await entries(tree);
|
|
16
16
|
const result = await Promise.all(
|
|
17
17
|
treeEntries.map(async ([key, value]) => {
|
|
18
18
|
const resolvedValue = isMap(value) ? await deepEntries(value) : value;
|
|
19
19
|
return [key, resolvedValue];
|
|
20
|
-
})
|
|
20
|
+
}),
|
|
21
21
|
);
|
|
22
22
|
return result;
|
|
23
23
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import isPlainObject from "../utilities/isPlainObject.js";
|
|
3
3
|
import map from "./map.js";
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ import map from "./map.js";
|
|
|
15
15
|
* @returns {Promise<AsyncMap>}
|
|
16
16
|
*/
|
|
17
17
|
export default async function deepMap(maplike, options) {
|
|
18
|
-
const tree = await
|
|
18
|
+
const tree = await args.map(maplike, "Tree.deepMap", { deep: true });
|
|
19
19
|
const withDeep = isPlainObject(options)
|
|
20
20
|
? // Dictionary
|
|
21
21
|
{ ...options, deep: true }
|
|
@@ -18,9 +18,22 @@ export default async function deepMerge(...maplikes) {
|
|
|
18
18
|
const filtered = maplikes.filter((source) => source);
|
|
19
19
|
const unpacked = await Promise.all(
|
|
20
20
|
filtered.map(async (source) =>
|
|
21
|
-
isUnpackable(source) ? await source.unpack() : source
|
|
22
|
-
)
|
|
21
|
+
isUnpackable(source) ? await source.unpack() : source,
|
|
22
|
+
),
|
|
23
23
|
);
|
|
24
|
+
|
|
25
|
+
// If any argument isn't maplike, throw an error.
|
|
26
|
+
for (const index in unpacked) {
|
|
27
|
+
if (!isMaplike(unpacked[index])) {
|
|
28
|
+
/** @type {any} */
|
|
29
|
+
const error = new TypeError(
|
|
30
|
+
`Tree.deepMerge: an argument wasn't maplike.`,
|
|
31
|
+
);
|
|
32
|
+
error.position = Number(index) + 1;
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
const sources = unpacked.map((maplike) => from(maplike, { deep: true }));
|
|
25
38
|
|
|
26
39
|
return Object.assign(new AsyncMap(), {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import AsyncMap from "../drivers/AsyncMap.js";
|
|
2
|
-
import
|
|
2
|
+
import * as args from "../utilities/args.js";
|
|
3
3
|
import isMap from "./isMap.js";
|
|
4
4
|
import keys from "./keys.js";
|
|
5
5
|
|
|
@@ -12,7 +12,9 @@ import keys from "./keys.js";
|
|
|
12
12
|
* @returns {Promise<AsyncMap>}
|
|
13
13
|
*/
|
|
14
14
|
export default async function deepReverse(maplike) {
|
|
15
|
-
const source = await
|
|
15
|
+
const source = await args.map(maplike, "Tree.deepReverse", {
|
|
16
|
+
deep: true,
|
|
17
|
+
});
|
|
16
18
|
|
|
17
19
|
return Object.assign(new AsyncMap(), {
|
|
18
20
|
description: "deepReverse",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import from from "./from.js";
|
|
3
3
|
import isMap from "./isMap.js";
|
|
4
4
|
|
|
@@ -13,7 +13,8 @@ import isMap from "./isMap.js";
|
|
|
13
13
|
* @param {number} count
|
|
14
14
|
*/
|
|
15
15
|
export default async function deepTake(maplike, count) {
|
|
16
|
-
const tree = await
|
|
16
|
+
const tree = await args.map(maplike, "Tree.deepTake", { deep: true });
|
|
17
|
+
count = args.number(count, "Tree.deepTake", { position: 2 });
|
|
17
18
|
const { values } = await traverse(tree, count);
|
|
18
19
|
return from(values, { deep: true });
|
|
19
20
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
|
+
import interop from "../utilities/interop.js";
|
|
2
3
|
import toString from "../utilities/toString.js";
|
|
3
4
|
import deepValuesIterator from "./deepValuesIterator.js";
|
|
4
5
|
|
|
@@ -8,7 +9,7 @@ import deepValuesIterator from "./deepValuesIterator.js";
|
|
|
8
9
|
* @param {import("../../index.ts").Maplike} maplike
|
|
9
10
|
*/
|
|
10
11
|
export default async function deepText(maplike) {
|
|
11
|
-
const tree = await
|
|
12
|
+
const tree = await args.map(maplike, "Tree.deepText", { deep: true });
|
|
12
13
|
const strings = [];
|
|
13
14
|
for await (const value of deepValuesIterator(tree, { expand: true })) {
|
|
14
15
|
let string;
|
|
@@ -20,8 +21,8 @@ export default async function deepText(maplike) {
|
|
|
20
21
|
string = toString(value);
|
|
21
22
|
}
|
|
22
23
|
if (value === null || value === undefined) {
|
|
23
|
-
const message = `Warning: a template encountered a ${string} value
|
|
24
|
-
|
|
24
|
+
const message = `Warning: a template encountered a ${string} value.`;
|
|
25
|
+
interop.warn(message);
|
|
25
26
|
}
|
|
26
27
|
strings.push(string);
|
|
27
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import isMap from "./isMap.js";
|
|
3
3
|
import isMaplike from "./isMaplike.js";
|
|
4
4
|
|
|
@@ -14,9 +14,9 @@ import isMaplike from "./isMaplike.js";
|
|
|
14
14
|
*/
|
|
15
15
|
export default async function* deepValuesIterator(
|
|
16
16
|
maplike,
|
|
17
|
-
options = { expand: false }
|
|
17
|
+
options = { expand: false },
|
|
18
18
|
) {
|
|
19
|
-
const tree = await
|
|
19
|
+
const tree = await args.map(maplike, "Tree.deepValuesIterator", {
|
|
20
20
|
deep: true,
|
|
21
21
|
});
|
|
22
22
|
|
package/src/operations/delete.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Removes the value for the given key from the specific node of the tree.
|
|
3
5
|
*
|
|
@@ -6,11 +8,8 @@
|
|
|
6
8
|
* @param {Maplike} maplike
|
|
7
9
|
* @param {any} key
|
|
8
10
|
*/
|
|
9
|
-
|
|
10
|
-
import getMapArgument from "../utilities/getMapArgument.js";
|
|
11
|
-
|
|
12
|
-
// `delete` is a reserved word in JavaScript, so we use `del` instead.
|
|
13
11
|
export default async function del(maplike, key) {
|
|
14
|
-
|
|
12
|
+
// `delete` is reserved word so can't use that as function name
|
|
13
|
+
const map = await args.map(maplike, "Tree.delete");
|
|
15
14
|
return map.delete(key);
|
|
16
15
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns an array of `[key, value]` for each entry in the map.
|
|
@@ -9,7 +9,7 @@ import getMapArgument from "../utilities/getMapArgument.js";
|
|
|
9
9
|
* @returns {Promise<Array<[any, any]>>}
|
|
10
10
|
*/
|
|
11
11
|
export default async function entries(maplike) {
|
|
12
|
-
const map = await
|
|
12
|
+
const map = await args.map(maplike, "Tree.entries");
|
|
13
13
|
if (map instanceof Map) {
|
|
14
14
|
return Array.from(map.entries());
|
|
15
15
|
} else {
|
package/src/operations/filter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import map from "./map.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -23,7 +23,7 @@ export default async function filter(maplike, options) {
|
|
|
23
23
|
deep = options.deep ?? false;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const tree = await
|
|
26
|
+
const tree = await args.map(maplike, "Tree.filter", { deep });
|
|
27
27
|
return map(tree, {
|
|
28
28
|
deep,
|
|
29
29
|
|
package/src/operations/first.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Return the first value in the tree.
|
|
@@ -8,7 +8,7 @@ import getMapArgument from "../utilities/getMapArgument.js";
|
|
|
8
8
|
* @param {Maplike} maplike
|
|
9
9
|
*/
|
|
10
10
|
export default async function first(maplike) {
|
|
11
|
-
const map = await
|
|
11
|
+
const map = await args.map(maplike, "Tree.first");
|
|
12
12
|
let firstKey;
|
|
13
13
|
for await (const key of map.keys()) {
|
|
14
14
|
// Just needed to get first key
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Calls callbackFn once for each key-value pair present in the map.
|
|
@@ -9,7 +9,11 @@ import getMapArgument from "../utilities/getMapArgument.js";
|
|
|
9
9
|
* @param {Function} callbackFn
|
|
10
10
|
*/
|
|
11
11
|
export default async function forEach(maplike, callbackFn) {
|
|
12
|
-
const map = await
|
|
12
|
+
const map = await args.map(maplike, "Tree.forEach");
|
|
13
|
+
if (typeof callbackFn !== "function") {
|
|
14
|
+
throw new TypeError("Tree.forEach: Expected a function argument.");
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
for await (const key of map.keys()) {
|
|
14
18
|
const value = await map.get(key);
|
|
15
19
|
await callbackFn(value, key, map);
|
package/src/operations/from.js
CHANGED
|
@@ -6,6 +6,7 @@ import * as symbols from "../symbols.js";
|
|
|
6
6
|
import box from "../utilities/box.js";
|
|
7
7
|
import isPlainObject from "../utilities/isPlainObject.js";
|
|
8
8
|
import setParent from "../utilities/setParent.js";
|
|
9
|
+
import TypedArray from "../utilities/TypedArray.js";
|
|
9
10
|
import isMap from "./isMap.js";
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -26,11 +27,11 @@ export default function from(object, options = {}) {
|
|
|
26
27
|
const deep = options.deep ?? object?.[symbols.deep];
|
|
27
28
|
let map;
|
|
28
29
|
if (object == null) {
|
|
29
|
-
throw new
|
|
30
|
+
throw new ReferenceError("The map argument wasn't defined.");
|
|
30
31
|
} else if (object instanceof Promise) {
|
|
31
32
|
// A common mistake
|
|
32
33
|
throw new TypeError(
|
|
33
|
-
"The
|
|
34
|
+
"The map argument was a Promise. Did you mean to use await?",
|
|
34
35
|
);
|
|
35
36
|
} else if (isMap(object)) {
|
|
36
37
|
// Already a map
|
|
@@ -39,6 +40,8 @@ export default function from(object, options = {}) {
|
|
|
39
40
|
map = new FunctionMap(object);
|
|
40
41
|
} else if (object instanceof Set) {
|
|
41
42
|
map = new SetMap(object);
|
|
43
|
+
} else if (object instanceof ArrayBuffer || object instanceof TypedArray) {
|
|
44
|
+
throw new TypeError("Can't treat binary file data as a map.");
|
|
42
45
|
} else if (isPlainObject(object) || object instanceof Array) {
|
|
43
46
|
map = new ObjectMap(object, { deep });
|
|
44
47
|
// @ts-ignore
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import AsyncMap from "../drivers/AsyncMap.js";
|
|
2
2
|
import ObjectMap from "../drivers/ObjectMap.js";
|
|
3
3
|
import * as trailingSlash from "../trailingSlash.js";
|
|
4
|
-
import
|
|
4
|
+
import * as args from "../utilities/args.js";
|
|
5
5
|
import isMap from "./isMap.js";
|
|
6
6
|
import merge from "./merge.js";
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ const globstar = "**";
|
|
|
9
9
|
const globstarSlash = `${globstar}/`;
|
|
10
10
|
|
|
11
11
|
export default async function globKeys(maplike) {
|
|
12
|
-
const source = await
|
|
12
|
+
const source = await args.map(maplike, "Tree.globKeys", { deep: true });
|
|
13
13
|
return Object.assign(new AsyncMap(), {
|
|
14
14
|
async get(key) {
|
|
15
15
|
if (typeof key !== "string") {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import SyncMap from "../drivers/SyncMap.js";
|
|
2
|
-
import
|
|
2
|
+
import * as args from "../utilities/args.js";
|
|
3
3
|
import entries from "./entries.js";
|
|
4
4
|
import isMaplike from "./isMaplike.js";
|
|
5
5
|
import values from "./values.js";
|
|
@@ -12,19 +12,20 @@ import values from "./values.js";
|
|
|
12
12
|
* @param {import("../../index.ts").ValueKeyFn} groupKeyFn
|
|
13
13
|
*/
|
|
14
14
|
export default async function groupBy(maplike, groupKeyFn) {
|
|
15
|
-
const source = await
|
|
15
|
+
const source = await args.map(maplike, "Tree.groupBy");
|
|
16
|
+
const fn = args.invocable(groupKeyFn, "Tree.groupBy", { position: 2 });
|
|
16
17
|
|
|
17
18
|
const result = new SyncMap();
|
|
18
19
|
const sourceEntries = await entries(source);
|
|
19
20
|
|
|
20
21
|
// Are all the keys integers?
|
|
21
22
|
const integerKeys = sourceEntries.every(
|
|
22
|
-
([key]) => !Number.isNaN(parseInt(key))
|
|
23
|
+
([key]) => !Number.isNaN(parseInt(key)),
|
|
23
24
|
);
|
|
24
25
|
|
|
25
26
|
for (const [key, value] of sourceEntries) {
|
|
26
27
|
// Get the groups for this value.
|
|
27
|
-
let groups = await
|
|
28
|
+
let groups = await fn(value, key, source);
|
|
28
29
|
if (!groups) {
|
|
29
30
|
continue;
|
|
30
31
|
}
|
package/src/operations/has.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns true if the map has the given key, false otherwise.
|
|
@@ -9,6 +9,6 @@ import getMapArgument from "../utilities/getMapArgument.js";
|
|
|
9
9
|
* @param {any} key
|
|
10
10
|
*/
|
|
11
11
|
export default async function has(maplike, key) {
|
|
12
|
-
const map = await
|
|
12
|
+
const map = await args.map(maplike, "Tree.has");
|
|
13
13
|
return map.has(key);
|
|
14
14
|
}
|
package/src/operations/indent.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import interop from "../utilities/interop.js";
|
|
1
2
|
import toString from "../utilities/toString.js";
|
|
2
3
|
import deepText from "./deepText.js";
|
|
3
4
|
import isMaplike from "./isMaplike.js";
|
|
@@ -21,7 +22,7 @@ export default async function indent(strings, ...values) {
|
|
|
21
22
|
}
|
|
22
23
|
const { blockIndentations, strings: modifiedStrings } = modified;
|
|
23
24
|
const valueTexts = await Promise.all(
|
|
24
|
-
values.map((value) => (isMaplike(value) ? deepText(value) : value))
|
|
25
|
+
values.map((value) => (isMaplike(value) ? deepText(value) : value)),
|
|
25
26
|
);
|
|
26
27
|
return joinBlocks(modifiedStrings, valueTexts, blockIndentations);
|
|
27
28
|
}
|
|
@@ -31,7 +32,12 @@ export default async function indent(strings, ...values) {
|
|
|
31
32
|
function joinBlocks(strings, values, blockIndentations) {
|
|
32
33
|
let result = strings[0];
|
|
33
34
|
for (let i = 0; i < values.length; i++) {
|
|
34
|
-
|
|
35
|
+
const value = values[i];
|
|
36
|
+
let text = toString(value);
|
|
37
|
+
if (value == null) {
|
|
38
|
+
const message = `Warning: a template encountered a ${text} value.`;
|
|
39
|
+
interop.warn(message);
|
|
40
|
+
}
|
|
35
41
|
if (text) {
|
|
36
42
|
const blockIndentation = blockIndentations[i];
|
|
37
43
|
if (blockIndentation) {
|
|
@@ -77,7 +83,7 @@ function modifyStrings(strings) {
|
|
|
77
83
|
const indentationRegex = new RegExp(`\n${indent}`, "g");
|
|
78
84
|
// The `replaceAll` also converts strings to a real array.
|
|
79
85
|
modified = strings.map((string) =>
|
|
80
|
-
string.replaceAll(indentationRegex, "\n")
|
|
86
|
+
string.replaceAll(indentationRegex, "\n"),
|
|
81
87
|
);
|
|
82
88
|
// Remove indentation from last line of last string
|
|
83
89
|
modified[modified.length - 1] = modified
|
package/src/operations/inners.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AsyncMap from "../drivers/AsyncMap.js";
|
|
2
2
|
import * as trailingSlash from "../trailingSlash.js";
|
|
3
|
-
import
|
|
3
|
+
import * as args from "../utilities/args.js";
|
|
4
4
|
import isMap from "./isMap.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -12,7 +12,7 @@ import isMap from "./isMap.js";
|
|
|
12
12
|
* @param {Maplike} maplike
|
|
13
13
|
*/
|
|
14
14
|
export default async function inners(maplike) {
|
|
15
|
-
const source = await
|
|
15
|
+
const source = await args.map(maplike, "Tree.inners");
|
|
16
16
|
|
|
17
17
|
return Object.assign(new AsyncMap(), {
|
|
18
18
|
async get(key) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import AsyncMap from "../drivers/AsyncMap.js";
|
|
2
|
-
import
|
|
2
|
+
import * as args from "../utilities/args.js";
|
|
3
3
|
import isMap from "./isMap.js";
|
|
4
4
|
|
|
5
5
|
export default async function invokeFunctions(maplike) {
|
|
6
|
-
const source = await
|
|
6
|
+
const source = await args.map(maplike, "Tree.invokeFunctions", {
|
|
7
7
|
deep: true,
|
|
8
8
|
});
|
|
9
9
|
|
package/src/operations/json.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import toPlainValue from "../utilities/toPlainValue.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -7,7 +7,7 @@ import toPlainValue from "../utilities/toPlainValue.js";
|
|
|
7
7
|
* @param {import("../../index.ts").Maplike} maplike
|
|
8
8
|
*/
|
|
9
9
|
export default async function json(maplike) {
|
|
10
|
-
const tree = await
|
|
10
|
+
const tree = await args.map(maplike, "Tree.json");
|
|
11
11
|
const value = await toPlainValue(tree);
|
|
12
12
|
return JSON.stringify(value, null, 2);
|
|
13
13
|
}
|
package/src/operations/keys.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Return the keys of the map.
|
|
@@ -8,7 +8,7 @@ import getMapArgument from "../utilities/getMapArgument.js";
|
|
|
8
8
|
* @param {Maplike} maplike
|
|
9
9
|
*/
|
|
10
10
|
export default async function keys(maplike) {
|
|
11
|
-
const map = await
|
|
11
|
+
const map = await args.map(maplike, "Tree.keys");
|
|
12
12
|
let keys;
|
|
13
13
|
let iterable = map.keys();
|
|
14
14
|
if (Symbol.asyncIterator in iterable) {
|
package/src/operations/length.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import keys from "./keys.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -10,7 +10,7 @@ import keys from "./keys.js";
|
|
|
10
10
|
*/
|
|
11
11
|
export default async function length(maplike) {
|
|
12
12
|
console.warn("Tree.length() is deprecated. Use Tree.size() instead.");
|
|
13
|
-
const tree = await
|
|
13
|
+
const tree = await args.map(maplike, "Tree.length");
|
|
14
14
|
const treeKeys = await keys(tree);
|
|
15
15
|
return treeKeys.length;
|
|
16
16
|
}
|