You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
30 lines
859 B
JavaScript
30 lines
859 B
JavaScript
"use strict";
|
|
|
|
const isIterable = require("is-iterable");
|
|
const mapAsync = require("../map-async");
|
|
|
|
module.exports = async function treeMapAsync(tree, mapper, options = {}) {
|
|
let key = options.key ?? "children";
|
|
|
|
async function step(subtree) {
|
|
let mapped = await mapper(subtree);
|
|
let modifiedProperties = {};
|
|
|
|
if (isIterable(mapped[key])) {
|
|
modifiedProperties[key] = await mapAsync(mapped[key], step);
|
|
} else if (mapped[key] != null && typeof mapped[key] === "object") {
|
|
modifiedProperties[key] = await step(mapped[key]);
|
|
}
|
|
|
|
// We track modified properties separately and (immutably) merge them at the end, because it's the fastest way to ensure that we don't mutate the input object under any circumstances
|
|
return {
|
|
... mapped,
|
|
... modifiedProperties
|
|
};
|
|
}
|
|
|
|
return isIterable(tree)
|
|
? mapAsync(tree, step)
|
|
: step(tree);
|
|
};
|