@weborigami/async-tree 0.6.8 → 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 +2 -2
- package/scripts/headlessTest.js +1 -3
- 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
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as trailingSlash from "../trailingSlash.js";
|
|
2
2
|
import TraverseError from "../TraverseError.js";
|
|
3
|
+
import isPacked from "../utilities/isPacked.js";
|
|
3
4
|
import isUnpackable from "../utilities/isUnpackable.js";
|
|
4
5
|
import from from "./from.js";
|
|
6
|
+
import isMaplike from "./isMaplike.js";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Return the value at the corresponding path of keys. Throw if any interior
|
|
@@ -11,11 +13,13 @@ import from from "./from.js";
|
|
|
11
13
|
*
|
|
12
14
|
* @param {Maplike} maplike
|
|
13
15
|
* @param {...any} keys
|
|
16
|
+
* @returns {Promise<any>}
|
|
14
17
|
*/
|
|
15
18
|
export default async function traverseOrThrow(maplike, ...keys) {
|
|
16
|
-
// Start our traversal at the root of the tree.
|
|
17
|
-
/** @type {any} */
|
|
18
19
|
let value = maplike;
|
|
20
|
+
|
|
21
|
+
// For error reporting
|
|
22
|
+
let lastValue = value;
|
|
19
23
|
let position = 0;
|
|
20
24
|
|
|
21
25
|
// Process all the keys.
|
|
@@ -23,16 +27,31 @@ export default async function traverseOrThrow(maplike, ...keys) {
|
|
|
23
27
|
let key;
|
|
24
28
|
while (remainingKeys.length > 0) {
|
|
25
29
|
if (value == null) {
|
|
26
|
-
throw new TraverseError("A null or undefined value
|
|
27
|
-
|
|
30
|
+
throw new TraverseError("A path hit a null or undefined value.", {
|
|
31
|
+
head: maplike,
|
|
32
|
+
lastValue,
|
|
28
33
|
keys,
|
|
29
34
|
position,
|
|
30
35
|
});
|
|
31
36
|
}
|
|
32
37
|
|
|
38
|
+
lastValue = value;
|
|
39
|
+
|
|
33
40
|
// If the value is packed and can be unpacked, unpack it.
|
|
34
|
-
if (
|
|
35
|
-
|
|
41
|
+
if (isPacked(value)) {
|
|
42
|
+
if (typeof (/** @type {any} */ (value).unpack) === "function") {
|
|
43
|
+
value = await value.unpack();
|
|
44
|
+
} else {
|
|
45
|
+
throw new TraverseError(
|
|
46
|
+
"A path hit binary file data that can't be unpacked.",
|
|
47
|
+
{
|
|
48
|
+
head: maplike,
|
|
49
|
+
lastValue,
|
|
50
|
+
keys,
|
|
51
|
+
position,
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
}
|
|
36
55
|
}
|
|
37
56
|
|
|
38
57
|
if (value instanceof Function) {
|
|
@@ -60,8 +79,21 @@ export default async function traverseOrThrow(maplike, ...keys) {
|
|
|
60
79
|
}
|
|
61
80
|
|
|
62
81
|
// If last key ended in a slash and value is unpackable, unpack it.
|
|
63
|
-
if (key && trailingSlash.has(key) &&
|
|
64
|
-
|
|
82
|
+
if (key && trailingSlash.has(key) && !isMaplike(value)) {
|
|
83
|
+
if (isUnpackable(value)) {
|
|
84
|
+
value = await value.unpack();
|
|
85
|
+
} else {
|
|
86
|
+
const message =
|
|
87
|
+
value === undefined
|
|
88
|
+
? "A path tried to unpack a value that doesn't exist."
|
|
89
|
+
: "A path tried to unpack data that's already unpacked.";
|
|
90
|
+
throw new TraverseError(message, {
|
|
91
|
+
head: maplike,
|
|
92
|
+
lastValue,
|
|
93
|
+
keys,
|
|
94
|
+
position,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
65
97
|
}
|
|
66
98
|
|
|
67
99
|
return value;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
1
2
|
import keysFromPath from "../utilities/keysFromPath.js";
|
|
2
3
|
import traverse from "./traverse.js";
|
|
3
4
|
|
|
@@ -7,10 +8,11 @@ import traverse from "./traverse.js";
|
|
|
7
8
|
*
|
|
8
9
|
* @typedef {import("../../index.ts").Maplike} Maplike
|
|
9
10
|
*
|
|
10
|
-
* @param {Maplike}
|
|
11
|
+
* @param {Maplike} maplike
|
|
11
12
|
* @param {string} path
|
|
12
13
|
*/
|
|
13
|
-
export default async function traversePath(
|
|
14
|
+
export default async function traversePath(maplike, path) {
|
|
15
|
+
const map = await args.map(maplike, "Tree.traversePath");
|
|
14
16
|
const keys = keysFromPath(path);
|
|
15
|
-
return traverse(
|
|
17
|
+
return traverse(map, ...keys);
|
|
16
18
|
}
|
package/src/operations/values.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Return the values in 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 values(maplike) {
|
|
11
|
-
const map = await
|
|
11
|
+
const map = await args.map(maplike, "Tree.values");
|
|
12
12
|
let result;
|
|
13
13
|
/** @type {any} */
|
|
14
14
|
let iterable = map.values();
|
package/src/operations/visit.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as args from "../utilities/args.js";
|
|
2
2
|
import reduce from "./reduce.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -9,6 +9,6 @@ import reduce from "./reduce.js";
|
|
|
9
9
|
* @param {Maplike} source
|
|
10
10
|
*/
|
|
11
11
|
export default async function visit(source) {
|
|
12
|
-
const tree = await
|
|
12
|
+
const tree = await args.map(source, "Tree.visit", { deep: true });
|
|
13
13
|
return reduce(tree, () => undefined);
|
|
14
14
|
}
|
|
@@ -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 values from "./values.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -13,10 +13,12 @@ import values from "./values.js";
|
|
|
13
13
|
* @returns {Promise<AsyncMap>}
|
|
14
14
|
*/
|
|
15
15
|
export default async function withKeys(maplike, keysMaplike) {
|
|
16
|
-
const source = await
|
|
17
|
-
const keysMap = await getMapArgument(keysMaplike, "withKeys", {
|
|
16
|
+
const source = await args.map(maplike, "Tree.withKeys", {
|
|
18
17
|
position: 1,
|
|
19
18
|
});
|
|
19
|
+
const keysMap = await args.map(keysMaplike, "Tree.withKeys", {
|
|
20
|
+
position: 2,
|
|
21
|
+
});
|
|
20
22
|
|
|
21
23
|
let keys;
|
|
22
24
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import from from "../operations/from.js";
|
|
2
|
+
import isUnpackable from "./isUnpackable.js";
|
|
3
|
+
import toFunction from "./toFunction.js";
|
|
4
|
+
import toString from "./toString.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Runtime argument checking.
|
|
8
|
+
*
|
|
9
|
+
* These return a particular kind of argument or throw an error.
|
|
10
|
+
*
|
|
11
|
+
* Operations can use these to validate the arguments and provide more helpful
|
|
12
|
+
* error messages.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check a function argument.
|
|
17
|
+
*/
|
|
18
|
+
export function fn(arg, operation, options = {}) {
|
|
19
|
+
if (typeof arg !== "function") {
|
|
20
|
+
/** @type {any} */
|
|
21
|
+
const error = new TypeError(`${operation}: Expected a function argument.`);
|
|
22
|
+
error.position = options.position ?? 1;
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
return arg;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check an invocable argument and return it as a function.
|
|
30
|
+
*
|
|
31
|
+
* @param {import("../../index.ts").Invocable} arg
|
|
32
|
+
* @param {string} operation
|
|
33
|
+
* @returns {Function}
|
|
34
|
+
*/
|
|
35
|
+
export function invocable(arg, operation, options = {}) {
|
|
36
|
+
const fn = toFunction(arg);
|
|
37
|
+
if (!fn) {
|
|
38
|
+
/** @type {any} */
|
|
39
|
+
const error = new TypeError(`${operation}: Expected a function argument.`);
|
|
40
|
+
error.position = options.position ?? 1;
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
return fn;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check a maplike argument and return it as a Map or AsyncMap.
|
|
48
|
+
*
|
|
49
|
+
* @typedef {import("../../index.ts").AsyncMap} AsyncMap
|
|
50
|
+
* @typedef {import("../../index.ts").Maplike} Maplike
|
|
51
|
+
* @typedef {import("../../index.ts").Unpackable} Unpackable
|
|
52
|
+
*
|
|
53
|
+
* @param {Maplike|Unpackable} arg
|
|
54
|
+
* @param {string} operation
|
|
55
|
+
* @param {{ deep?: boolean, position?: number }} [options]
|
|
56
|
+
* @returns {Promise<Map|AsyncMap>}
|
|
57
|
+
*/
|
|
58
|
+
export async function map(arg, operation, options = {}) {
|
|
59
|
+
const deep = options.deep;
|
|
60
|
+
const position = options.position ?? 1;
|
|
61
|
+
|
|
62
|
+
if (isUnpackable(arg)) {
|
|
63
|
+
arg = await arg.unpack();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let map;
|
|
67
|
+
try {
|
|
68
|
+
map = from(arg, { deep });
|
|
69
|
+
} catch (/** @type {any} */ error) {
|
|
70
|
+
let message = error.message ?? error;
|
|
71
|
+
message = `${operation}: ${message}`;
|
|
72
|
+
const newError = new error.constructor(message);
|
|
73
|
+
/** @type {any} */ (newError).position = position;
|
|
74
|
+
throw newError;
|
|
75
|
+
}
|
|
76
|
+
return map;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check a number argument.
|
|
81
|
+
*
|
|
82
|
+
* @param {number} arg
|
|
83
|
+
* @param {string} operation
|
|
84
|
+
*/
|
|
85
|
+
export function number(arg, operation, options = {}) {
|
|
86
|
+
if (typeof arg !== "number" || Number.isNaN(arg)) {
|
|
87
|
+
/** @type {any} */
|
|
88
|
+
const error = new TypeError(`${operation}: Expected a number argument.`);
|
|
89
|
+
error.position = options.position ?? 1;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
return arg;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check a string argument.
|
|
97
|
+
*
|
|
98
|
+
* @param {string} arg
|
|
99
|
+
* @param {string} operation
|
|
100
|
+
*/
|
|
101
|
+
export function string(arg, operation, options = {}) {
|
|
102
|
+
if (typeof arg !== "string") {
|
|
103
|
+
/** @type {any} */
|
|
104
|
+
const error = new TypeError(`${operation}: Expected a string argument.`);
|
|
105
|
+
error.position = options.position ?? 1;
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
return arg;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Check a stringlike argument.
|
|
113
|
+
*
|
|
114
|
+
* @param {import("../../index.ts").Stringlike} arg
|
|
115
|
+
* @param {string} operation
|
|
116
|
+
*/
|
|
117
|
+
export function stringlike(arg, operation, options = {}) {
|
|
118
|
+
const result = toString(arg);
|
|
119
|
+
if (!result) {
|
|
120
|
+
/** @type {any} */
|
|
121
|
+
const error = new TypeError(
|
|
122
|
+
`${operation}: Expected a stringlike argument.`,
|
|
123
|
+
);
|
|
124
|
+
error.position = options.position ?? 1;
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
@@ -9,7 +9,7 @@ import * as symbols from "../symbols.js";
|
|
|
9
9
|
* @typedef {import("../../index.ts").SyncOrAsyncMap} SyncOrAsyncMap
|
|
10
10
|
*
|
|
11
11
|
* @param {*} child
|
|
12
|
-
* @param {
|
|
12
|
+
* @param {any} parent
|
|
13
13
|
*/
|
|
14
14
|
export default function setParent(child, parent) {
|
|
15
15
|
if (isMap(child)) {
|
|
@@ -14,10 +14,10 @@ describe("root", () => {
|
|
|
14
14
|
},
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
|
-
{ deep: true }
|
|
17
|
+
{ deep: true },
|
|
18
18
|
);
|
|
19
19
|
const c = await traverse(tree, "a", "b", "c");
|
|
20
|
-
const r = await root(c);
|
|
20
|
+
const r = c ? await root(c) : undefined;
|
|
21
21
|
assert.strictEqual(r, tree);
|
|
22
22
|
});
|
|
23
23
|
});
|
|
@@ -18,38 +18,7 @@ describe("traverse", () => {
|
|
|
18
18
|
assert.equal(await traverse(tree), tree);
|
|
19
19
|
assert.equal(await traverse(tree, "a1"), 1);
|
|
20
20
|
assert.equal(await traverse(tree, "a2", "b2", "c2"), 4);
|
|
21
|
+
// Should return undefined instead of throwing
|
|
21
22
|
assert.equal(await traverse(tree, "a2", "doesntexist", "c2"), undefined);
|
|
22
23
|
});
|
|
23
|
-
|
|
24
|
-
test("traverses a function with fixed number of arguments", async () => {
|
|
25
|
-
const tree = (a, b) => ({
|
|
26
|
-
c: "Result",
|
|
27
|
-
});
|
|
28
|
-
assert.equal(await traverse(tree, "a", "b", "c"), "Result");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test("traverses from one tree into another", async () => {
|
|
32
|
-
const tree = new ObjectMap({
|
|
33
|
-
a: {
|
|
34
|
-
b: new Map([
|
|
35
|
-
["c", "Hello"],
|
|
36
|
-
["d", "Goodbye"],
|
|
37
|
-
]),
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
assert.equal(await traverse(tree, "a", "b", "c"), "Hello");
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test("unpacks last value if key ends in a slash", async () => {
|
|
44
|
-
const tree = new ObjectMap({
|
|
45
|
-
a: {
|
|
46
|
-
b: Object.assign(new String("packed"), {
|
|
47
|
-
unpack() {
|
|
48
|
-
return "unpacked";
|
|
49
|
-
},
|
|
50
|
-
}),
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
assert.equal(await traverse(tree, "a/", "b/"), "unpacked");
|
|
54
|
-
});
|
|
55
24
|
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, test } from "node:test";
|
|
3
|
+
import ObjectMap from "../../src/drivers/ObjectMap.js";
|
|
4
|
+
import traverseOrThrow from "../../src/operations/traverseOrThrow.js";
|
|
5
|
+
|
|
6
|
+
describe("traverseOrThrow", () => {
|
|
7
|
+
test("traverses a path of keys", async () => {
|
|
8
|
+
const tree = new ObjectMap({
|
|
9
|
+
a1: 1,
|
|
10
|
+
a2: {
|
|
11
|
+
b1: 2,
|
|
12
|
+
b2: {
|
|
13
|
+
c1: 3,
|
|
14
|
+
c2: 4,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
assert.equal(await traverseOrThrow(tree), tree);
|
|
19
|
+
assert.equal(await traverseOrThrow(tree, "a1"), 1);
|
|
20
|
+
assert.equal(await traverseOrThrow(tree, "a2", "b2", "c2"), 4);
|
|
21
|
+
assert.rejects(
|
|
22
|
+
async () => await traverseOrThrow(tree, "a2", "doesntexist", "c2"),
|
|
23
|
+
{
|
|
24
|
+
name: "TraverseError",
|
|
25
|
+
message: "A path hit a null or undefined value.",
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("traverses a function with fixed number of arguments", async () => {
|
|
31
|
+
const tree = (a, b) => ({
|
|
32
|
+
c: "Result",
|
|
33
|
+
});
|
|
34
|
+
assert.equal(await traverseOrThrow(tree, "a", "b", "c"), "Result");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("traverses from one tree into another", async () => {
|
|
38
|
+
const tree = new ObjectMap({
|
|
39
|
+
a: {
|
|
40
|
+
b: new Map([
|
|
41
|
+
["c", "Hello"],
|
|
42
|
+
["d", "Goodbye"],
|
|
43
|
+
]),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
assert.equal(await traverseOrThrow(tree, "a", "b", "c"), "Hello");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("unpacks last value if key ends in a slash", async () => {
|
|
50
|
+
const tree = new ObjectMap({
|
|
51
|
+
a: {
|
|
52
|
+
b: Object.assign(new String("packed"), {
|
|
53
|
+
unpack() {
|
|
54
|
+
return "unpacked";
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
assert.equal(await traverseOrThrow(tree, "a/", "b/"), "unpacked");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("throws if the last key ends in a slash but the value can't be unpacked", async () => {
|
|
63
|
+
const tree = new ObjectMap({
|
|
64
|
+
a: {
|
|
65
|
+
b: 1,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
await assert.rejects(async () => await traverseOrThrow(tree, "a/", "b/"), {
|
|
69
|
+
name: "TraverseError",
|
|
70
|
+
message: "A path tried to unpack data that's already unpacked.",
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import from from "../operations/from.js";
|
|
2
|
-
import isUnpackable from "./isUnpackable.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Convert the indicated argument to a map, or throw an exception.
|
|
6
|
-
*
|
|
7
|
-
* Tree operations can use this to validate the map argument and provide more
|
|
8
|
-
* helpful error messages. This also unpacks a unpackable map argument.
|
|
9
|
-
*
|
|
10
|
-
* @typedef {import("../../index.ts").AsyncMap} AsyncMap
|
|
11
|
-
* @typedef {import("../../index.ts").Maplike} Maplike
|
|
12
|
-
* @typedef {import("../../index.ts").Unpackable} Unpackable
|
|
13
|
-
*
|
|
14
|
-
* @param {Maplike|Unpackable} maplike
|
|
15
|
-
* @param {string} operation
|
|
16
|
-
* @param {{ deep?: boolean, position?: number }} [options]
|
|
17
|
-
* @returns {Promise<Map|AsyncMap>}
|
|
18
|
-
*/
|
|
19
|
-
export default async function getMapArgument(maplike, operation, options = {}) {
|
|
20
|
-
const deep = options.deep;
|
|
21
|
-
const position = options.position ?? 0;
|
|
22
|
-
|
|
23
|
-
if (isUnpackable(maplike)) {
|
|
24
|
-
maplike = await maplike.unpack();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let map;
|
|
28
|
-
try {
|
|
29
|
-
map = from(maplike, { deep });
|
|
30
|
-
} catch (/** @type {any} */ error) {
|
|
31
|
-
let message = error.message ?? error;
|
|
32
|
-
message = `${operation}: ${message}`;
|
|
33
|
-
const newError = new TypeError(message);
|
|
34
|
-
/** @type {any} */ (newError).position = position;
|
|
35
|
-
throw newError;
|
|
36
|
-
}
|
|
37
|
-
return map;
|
|
38
|
-
}
|