@weborigami/async-tree 0.5.2 → 0.5.4
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/src/Tree.js +14 -3
- package/src/operations/map.js +6 -0
- package/src/utilities.js +41 -37
- package/test/operations/map.test.js +3 -5
- package/test/operations/paginate.test.js +2 -1
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/async-tree",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Asynchronous tree drivers based on standard JavaScript classes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./main.js",
|
|
7
7
|
"browser": "./browser.js",
|
|
8
8
|
"types": "./index.ts",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@weborigami/types": "0.5.
|
|
10
|
+
"@weborigami/types": "0.5.4"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@types/node": "24.3.0",
|
package/src/Tree.js
CHANGED
|
@@ -337,10 +337,21 @@ export async function paths(treelike, options = {}) {
|
|
|
337
337
|
/**
|
|
338
338
|
* Converts an asynchronous tree into a synchronous plain JavaScript object.
|
|
339
339
|
*
|
|
340
|
-
* The result's keys will be the tree's keys cast to strings. Any
|
|
341
|
-
*
|
|
340
|
+
* The result's keys will be the tree's keys cast to strings. Any trailing
|
|
341
|
+
* slashes in keys will be removed.
|
|
342
342
|
*
|
|
343
|
-
* Any
|
|
343
|
+
* Any tree value that is itself a tree will be recursively converted to a plain
|
|
344
|
+
* object.
|
|
345
|
+
*
|
|
346
|
+
* If the tree is array-like (its keys are integers and fill the range
|
|
347
|
+
* 0..length-1), then the result will be an array. The order of the keys will
|
|
348
|
+
* determine the order of the values in the array -- but the numeric value of
|
|
349
|
+
* the keys will be ignored.
|
|
350
|
+
*
|
|
351
|
+
* For example, a tree like `{ 1: "b", 0: "a", 2: "c" }` is array-like because
|
|
352
|
+
* its keys are all integers and fill the range 0..2. The result will be the
|
|
353
|
+
* array `["b", "a", "c" ]` because the tree has the keys in that order. The
|
|
354
|
+
* specific values of the keys (0, 1, and 2) are ignored.
|
|
344
355
|
*
|
|
345
356
|
* @param {Treelike} treelike
|
|
346
357
|
* @returns {Promise<PlainObject|Array>}
|
package/src/operations/map.js
CHANGED
|
@@ -171,6 +171,12 @@ function validateOptions(options) {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
if (!valueFn && !keyFn) {
|
|
175
|
+
throw new TypeError(
|
|
176
|
+
`map: You must specify a value function or a key function`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
174
180
|
deep ??= false;
|
|
175
181
|
description ??= "key/value map";
|
|
176
182
|
needsSourceValue ??= true;
|
package/src/utilities.js
CHANGED
|
@@ -55,36 +55,40 @@ export function box(value) {
|
|
|
55
55
|
/**
|
|
56
56
|
* Create an array or plain object from the given keys and values.
|
|
57
57
|
*
|
|
58
|
-
* If the given plain object has only
|
|
59
|
-
*
|
|
60
|
-
* values.
|
|
58
|
+
* If the given plain object has only integer keys, and the set of integers is
|
|
59
|
+
* complete from 0 to length-1, assume the values are a result of array
|
|
60
|
+
* transformations and the values are the desired result; return them as is.
|
|
61
|
+
* Otherwise, create a plain object with the keys and values.
|
|
61
62
|
*
|
|
62
63
|
* @param {any[]} keys
|
|
63
64
|
* @param {any[]} values
|
|
64
65
|
*/
|
|
65
66
|
export function castArrayLike(keys, values) {
|
|
66
|
-
|
|
67
|
+
if (keys.length === 0) {
|
|
68
|
+
// Empty keys/values means an empty object, not an empty array
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
67
71
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// Not array-like
|
|
78
|
-
isArrayLike = false;
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
expectedIndex++;
|
|
72
|
+
let onlyNumericKeys = true;
|
|
73
|
+
const numberSeen = new Array(keys.length);
|
|
74
|
+
for (const key of keys) {
|
|
75
|
+
const n = Number(key);
|
|
76
|
+
if (isNaN(n) || !Number.isInteger(n) || n < 0 || n >= keys.length) {
|
|
77
|
+
onlyNumericKeys = false;
|
|
78
|
+
break;
|
|
79
|
+
} else {
|
|
80
|
+
numberSeen[n] = true;
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
// If any number from 0..length-1 is missing, we can't treat this as an array
|
|
85
|
+
const allNumbersSeen = onlyNumericKeys && numberSeen.every((v) => v);
|
|
86
|
+
if (allNumbersSeen) {
|
|
87
|
+
return values;
|
|
88
|
+
} else {
|
|
89
|
+
// Return a plain object with the (key, value) pairs
|
|
90
|
+
return Object.fromEntries(keys.map((key, i) => [key, values[i]]));
|
|
91
|
+
}
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
/**
|
|
@@ -328,6 +332,22 @@ export function setParent(child, parent) {
|
|
|
328
332
|
}
|
|
329
333
|
}
|
|
330
334
|
|
|
335
|
+
function toBase64(object) {
|
|
336
|
+
if (typeof Buffer !== "undefined") {
|
|
337
|
+
// Node.js environment
|
|
338
|
+
return Buffer.from(object).toString("base64");
|
|
339
|
+
} else {
|
|
340
|
+
// Browser environment
|
|
341
|
+
let binary = "";
|
|
342
|
+
const bytes = new Uint8Array(object);
|
|
343
|
+
const len = bytes.byteLength;
|
|
344
|
+
for (let i = 0; i < len; i++) {
|
|
345
|
+
binary += String.fromCharCode(bytes[i]);
|
|
346
|
+
}
|
|
347
|
+
return btoa(binary);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
331
351
|
/**
|
|
332
352
|
* Convert the given input to the plainest possible JavaScript value. This
|
|
333
353
|
* helper is intended for functions that want to accept an argument from the ori
|
|
@@ -390,22 +410,6 @@ export async function toPlainValue(input) {
|
|
|
390
410
|
}
|
|
391
411
|
}
|
|
392
412
|
|
|
393
|
-
function toBase64(object) {
|
|
394
|
-
if (typeof Buffer !== "undefined") {
|
|
395
|
-
// Node.js environment
|
|
396
|
-
return Buffer.from(object).toString("base64");
|
|
397
|
-
} else {
|
|
398
|
-
// Browser environment
|
|
399
|
-
let binary = "";
|
|
400
|
-
const bytes = new Uint8Array(object);
|
|
401
|
-
const len = bytes.byteLength;
|
|
402
|
-
for (let i = 0; i < len; i++) {
|
|
403
|
-
binary += String.fromCharCode(bytes[i]);
|
|
404
|
-
}
|
|
405
|
-
return btoa(binary);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
413
|
/**
|
|
410
414
|
* Return a string form of the object, handling cases not generally handled by
|
|
411
415
|
* the standard JavaScript `toString()` method:
|
|
@@ -6,15 +6,13 @@ import map from "../../src/operations/map.js";
|
|
|
6
6
|
import * as trailingSlash from "../../src/trailingSlash.js";
|
|
7
7
|
|
|
8
8
|
describe("map", () => {
|
|
9
|
-
test("
|
|
9
|
+
test("throws if no key or value function is supplied", async () => {
|
|
10
10
|
const tree = {
|
|
11
11
|
a: "letter a",
|
|
12
12
|
b: "letter b",
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
a: "letter a",
|
|
17
|
-
b: "letter b",
|
|
14
|
+
assert.throws(() => {
|
|
15
|
+
map(tree, {});
|
|
18
16
|
});
|
|
19
17
|
});
|
|
20
18
|
|
|
@@ -13,7 +13,8 @@ describe("paginate", () => {
|
|
|
13
13
|
e: 5,
|
|
14
14
|
};
|
|
15
15
|
const paginated = await paginate.call(null, treelike, 2);
|
|
16
|
-
|
|
16
|
+
const plain = await Tree.plain(paginated);
|
|
17
|
+
assert.deepEqual(await plain, {
|
|
17
18
|
1: {
|
|
18
19
|
items: { a: 1, b: 2 },
|
|
19
20
|
nextPage: 2,
|