formats.exposed/public/common/nodePath.js

55 lines
1.2 KiB
JavaScript

// @ts-check
/**
* A node path is an array of indices that can traverse a Node tree.
*
* For example, given the following tree:
*
* ```javascript
* {
* name: "top",
* children: [
* { name: "first" },
* { name: "second", children: [{ name: "grandchild" }] },
* ],
* }
* ```
*
* `[]` is "top", `[0]` is "first", `[1]` is "second", and `[1, 0]` is "grandchild".
*
* @typedef {number[]} NodePath
*/
/**
* @param {unknown} value
* @returns {null | NodePath} The parsed node path, or null if invalid.
*/
export const parse = (value) => {
if (typeof value !== "string") return null;
if (!value) return [];
return value.split(",").map((str) => {
const result = parseInt(str, 10);
if (Number.isFinite(result)) return result;
throw new Error(`Invalid node path: ${value}`);
});
};
/**
* @param {NodePath} a
* @param {NodePath} b
* @returns {boolean}
*/
export const isEqualTo = (a, b) => a.length === b.length && isSupersetOf(a, b);
/**
* @param {NodePath} smaller
* @param {NodePath} bigger
* @returns {boolean}
*/
export const isSupersetOf = (smaller, bigger) => {
for (let i = 0; i < smaller.length; i++) {
if (smaller[i] !== bigger[i]) return false;
}
return true;
};