// @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; };