recma-static-refiner 0.9.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/call-utils.ts","../src/rule-validator.ts","../src/jsx-callsite-resolver.ts","../src/validator.ts","../src/differ/utils.ts","../src/differ/strategies.ts","../src/differ/index.ts","../src/guards.ts","../src/utils/path-utils.ts","../src/object-overlay.ts","../src/patch-planner.ts","../src/extractor/constants.ts","../src/extractor/static-resolver.ts","../src/extractor/key-extractor.ts","../src/expression-ref.ts","../src/utils/array-utils.ts","../src/utils/type-guards.ts","../src/utils/property-path-key.ts","../src/patcher-object.ts","../src/consolidatePatches.ts","../src/report.ts","../src/prune-patches.ts","../src/extractor/index.ts","../src/patch-guards.ts","../src/derive-patches.ts","../src/visitor.ts","../src/types/registry.ts","../src/index.ts"],"names":["is","traverse"],"mappings":"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","file":"index.js","sourcesContent":["import type { NodePath, types } from 'estree-toolkit';\nimport { is } from 'estree-toolkit';\n\n/**\n * JSX factory export names documented for the React automatic runtime.\n *\n * - Production runtime uses `jsx` and `jsxs`.\n * - Development runtime uses `jsxDEV`.\n *\n * Compilers frequently alias these imports to local identifiers (e.g. `jsx` → `_jsx`),\n * so callsites may use underscored names even though the export name is unchanged.\n */\nconst JSX_FACTORY_EXPORTS = new Set(['jsx', 'jsxs', 'jsxDEV']);\n\nfunction normalizeJsxFactoryName(name: string): string {\n return name.startsWith('_') ? name.slice(1) : name;\n}\n\n/**\n * Returns the NodePath for the Nth argument of a CallExpression.\n *\n * @param callPath\n * NodePath expected to reference a CallExpression.\n * @param index\n * Zero-based argument index.\n * @returns\n * NodePath for the argument at `index`, or `null` if the node is not a call\n * expression or the argument does not exist.\n */\nexport function getCallArgumentPath(\n callPath: NodePath,\n index: number\n): NodePath | null {\n const node = callPath.node;\n\n // Guard: only CallExpressions have an `arguments` list.\n if (!node || !is.callExpression(node)) return null;\n\n const argPaths = callPath.get('arguments');\n\n // Guard: estree-toolkit returns an array of NodePaths for `arguments`.\n if (!Array.isArray(argPaths)) return null;\n\n return argPaths.at(index) ?? null;\n}\n\n/**\n * Type guard for the JSX factory \"props argument\" path.\n *\n * This checks the *argument node kind* only:\n * - `true` when the argument exists and its node is an ESTree `Expression`.\n * - `false` when the argument is missing or is a non-expression node\n * (e.g. a SpreadElement in `jsx(Component, ...args)`).\n *\n * Note:\n * This does not validate the contents of the expression.\n * For example, `jsx(Component, { ...props })` passes here because the argument\n * is an ObjectExpression; spreads inside object/array literals are handled\n * later by the extractor's dynamic-value policy.\n *\n * @param path\n * Candidate NodePath for the props argument.\n * @returns\n * `true` if the path exists and points to an Expression node.\n */\nfunction isJsxPropsArgumentExpressionPath(\n path: NodePath | null\n): path is NodePath<types.Expression> {\n return !!path?.node && is.expression(path.node);\n}\n\n/**\n * Extracts the component and props argument NodePaths from a JSX factory call.\n *\n * Supported call targets (including common local aliasing):\n * - `jsx(Component, props)` / `_jsx(Component, props)`\n * - `jsxs(Component, props)` / `_jsxs(Component, props)`\n * - `jsxDEV(Component, props, ...)` / `_jsxDEV(Component, props, ...)`\n *\n * @param callPath\n * NodePath that may reference a JSX factory CallExpression.\n * @returns\n * - `{ componentPath, propsPath }` when:\n * 1. the callee matches a supported JSX factory name, and\n * 2. the first argument (component) exists, and\n * 3. the second argument (props) exists and is an `Expression`.\n * - `null` when any of the above conditions are not met (e.g. non-matching callee,\n * missing arguments, or a non-expression props argument such as a spread argument).\n */\nexport function getJsxRuntimeCallArgs(\n callPath: NodePath\n): { componentPath: NodePath; propsPath: NodePath<types.Expression> } | null {\n const node = callPath.node;\n\n // Guard: must be a call expression to have arguments + a callee.\n if (!node || !is.callExpression(node)) return null;\n\n // Guard: only supports identifier callees (e.g. `jsx`, `_jsx`), not `obj.jsx(...)`.\n if (!is.identifier(node.callee)) return null;\n\n // Normalize local alias names (e.g. `_jsx` -> `jsx`) and match official exports.\n const calleeName = normalizeJsxFactoryName(node.callee.name);\n if (!JSX_FACTORY_EXPORTS.has(calleeName)) return null;\n\n // JSX factory signature: (Component, props, ...)\n const componentPath = getCallArgumentPath(callPath, 0);\n const propsPath = getCallArgumentPath(callPath, 1);\n\n if (!componentPath) return null;\n // Guard: require the props *argument* to be an Expression node.\n if (!isJsxPropsArgumentExpressionPath(propsPath)) return null;\n\n return { componentPath, propsPath };\n}\n","import type { ComponentRuleBase } from './types';\n\n/**\n * Validates the runtime integrity of a `ComponentRule`.\n *\n * This function enforces the structural contract of a rule object at runtime.\n * It ensures the input is a non-null object and satisfies the logical\n * requirement that at least one configuration property ('schema', 'derive', or\n * 'pruneKeys') must be defined.\n *\n * @param rule - The rule object from the registry.\n * @param componentName - The component name context for error reporting.\n * @returns The validated rule object.\n * @throws Error if the rule is not an object or lacks active configuration.\n */\nexport function validateRule(\n rule: ComponentRuleBase | undefined | null,\n componentName: string\n): ComponentRuleBase {\n // 1. Validate object structure\n if (!rule || typeof rule !== 'object') {\n throw new Error(\n `[ValidationPlugin] Invalid rule for \"${componentName}\": Expected a rule object, got ${typeof rule}.`\n );\n }\n\n // 2. Validate functional requirements\n const isEffective =\n rule.schema != null || rule.derive != null || rule.pruneKeys != null;\n\n if (!isEffective) {\n throw new Error(\n `[ValidationPlugin] Invalid rule for \"${componentName}\": The rule is empty. ` +\n `It must define at least one of: 'schema', 'derive', or 'pruneKeys'.`\n );\n }\n\n return rule;\n}\n","import type { NodePath, types } from 'estree-toolkit';\nimport { is } from 'estree-toolkit';\n\nimport type { RuleMap, ComponentRuleBase } from './types';\nimport { getJsxRuntimeCallArgs } from './call-utils';\nimport { validateRule } from './rule-validator';\n\n/**\n * Data extracted from a JSX runtime callsite that matches a registered component.\n *\n * Matching rules live on `ResolveComponentMatch`. This type only describes the\n * data returned on success.\n */\nexport type ComponentMatch = {\n /**\n * Statically resolved component name from the JSX runtime call’s first argument.\n *\n * Examples:\n * - `_jsx(TimelineIngestor, props)` -> `\"TimelineIngestor\"`\n * - `_jsx(\"TimelineIngestor\", props)` -> `\"TimelineIngestor\"` (rare but valid)\n */\n componentName: string;\n\n /**\n * Canonical rule configuration for this component.\n *\n * Represents the validated registry entry used by the processing pipeline.\n *\n * Guarantees:\n * - The object is a structurally valid `ComponentRuleBase`.\n * - At least one feature (`schema`, `derive`, `pruneKeys`) is active.\n */\n componentRule: ComponentRuleBase;\n\n /**\n * NodePath for the props argument expression in the JSX runtime call.\n *\n * This points at the second argument in calls like:\n * `_jsx(Component, propsExpr)`\n *\n * It is later used as:\n * - the extraction root (decode static values from the props expression), and\n * - the mutation target (apply leaf-only patches back into the same AST subtree).\n */\n propsExpressionPath: NodePath<types.Expression>;\n};\n\n/**\n * Resolves a `ComponentMatch` from a CallExpression path.\n *\n * Returns a match only when ALL of these are true:\n * 1. The node is a CallExpression to a supported JSX factory (`jsx`, `jsxs`, `jsxDEV`),\n * including common local aliases like `_jsx`.\n * 2. The component argument (arg0) exists and a stable name can be resolved statically\n * (Identifier or string Literal).\n * 3. The resolved component name exists in the rule registry.\n * 4. The props argument (arg1) exists and is an ESTree Expression.\n *\n * Returns `null` when any check fails (the callsite is skipped).\n *\n * Note:\n * A successful match does NOT guarantee props are statically extractable or patchable.\n * That is decided later by extraction + patching policy.\n */\nexport type ResolveComponentMatch = (\n path: NodePath<types.CallExpression>\n) => ComponentMatch | null;\n\n/**\n * Attempts to resolve a stable component name from the JSX runtime factory\n * \"component\" argument.\n *\n * Accepted forms:\n * - `Identifier`\n * → `Card` in `jsx(Card, props)`\n * - string literal (`Literal` with `value: string`)\n * → `\"Card\"` in `jsx(\"Card\", props)` (rare but valid)\n *\n * All other node shapes are treated as unsupported (e.g. `UI.Card`,\n * `getComp()`) and return `null`.\n *\n * @param node\n * AST node used as the first argument to the JSX runtime factory call.\n * @returns\n * The component name if it can be resolved statically; otherwise `null`.\n */\nfunction extractComponentName(node: types.Node | null): string | null {\n if (!node) return null;\n\n // `jsx(Card, props)` → Card\n if (is.identifier(node)) {\n return node.name;\n }\n\n // `jsx(\"Card\", props)` → \"Card\"\n if (is.literal(node) && typeof node.value === 'string') {\n return node.value;\n }\n\n return null;\n}\n\n/**\n * Creates a `ResolveComponentMatch` function for a given rule registry.\n *\n * Match criteria\n * --------------\n * 1. JSX runtime call:\n * - Detect a supported JSX factory callsite and extract argument NodePaths.\n * - Must yield a component argument (arg0) and a props argument (arg1),\n * where arg1 is an ESTree Expression.\n *\n * 2. Component name:\n * - Resolve a stable component name from the component argument.\n * - Unsupported shapes (e.g. `UI.Card`, `getComp()`) are skipped.\n *\n * 3. Registry membership:\n * - Only proceed when the resolved component name exists in `rules`.\n *\n * 4. Rule validation:\n * - Ensure the registry entry conforms to the `ComponentRule` shape so\n * downstream processing relies on a guaranteed interface.\n * - Prevents empty or malformed configuration objects from entering the pipeline.\n *\n * Implementation note:\n * - Component-name membership is checked via a precomputed `Set` for O(1) lookups.\n */\nexport function createComponentResolver(rules: RuleMap): ResolveComponentMatch {\n const registeredComponentNames = new Set(Object.keys(rules));\n\n return (path: NodePath<types.CallExpression>): ComponentMatch | null => {\n // 1. Match JSX runtime call.\n const args = getJsxRuntimeCallArgs(path);\n if (!args) return null;\n\n // 2. Resolve component name.\n const componentName = extractComponentName(args.componentPath.node);\n if (!componentName) return null;\n\n // 3. Check registry membership.\n if (!registeredComponentNames.has(componentName)) return null;\n\n // Registry lookup is keyed by the resolved name; treat missing as non-match.\n const ruleEntry = rules[componentName];\n if (!ruleEntry) return null;\n\n // 4. Validate Registry Entry.\n const componentRule = validateRule(ruleEntry, componentName);\n\n return {\n componentName,\n componentRule,\n propsExpressionPath: args.propsPath\n };\n };\n}\n","import type { BaseProps, ComponentSchema, InferOutput } from './types';\n\n/**\n * Validates and transforms props using a Standard Schema V1 compliant validator.\n *\n * This function abstracts the validation logic by leveraging the `~standard`\n * property defined by the Standard Schema V1 specification.\n *\n * About `~standard`:\n * - Purpose:\n * It acts as a universal adapter, allowing the plugin to work generically\n * with Zod, Valibot, ArkType, and others without library-specific adapters.\n *\n * Schema Object Layout:\n * ```ts\n * const schema = {\n * // 1. Universal Adapter (Result Pattern):\n * // - Returns an object ({ value } or { issues }).\n * // - Does NOT throw errors.\n * // - Ensures safe, consistent handling across libraries.\n * \"~standard\": {\n * validate: (input) => Result\n * },\n *\n * // 2. Library-Specific Internals (Ignored):\n * // - Native methods (like .parse) typically throw exceptions.\n * // - Ignored to maintain generic compatibility via the spec.\n * parse,\n * ...otherLibrarySpecificProps\n * };\n * ```\n *\n * @template S - The specific schema type extending `ComponentSchema`.\n * @template Props - The fallback props interface extending `BaseProps`.\n *\n * @param schema - The schema instance (must contain `~standard`) or undefined.\n * @param inputProps - The raw props extracted from the AST.\n * @param componentName - The name of the component (used for error reporting).\n * @returns The validated (and potentially transformed) props.\n *\n * @throws\n * - If the schema object is invalid (missing `~standard`).\n * - If the validator returns a Promise (async validation is not supported).\n * - If validation fails (issues reported by the schema).\n */\n\n/**\n * Public Overload:\n * Establishes the strict type contract using generics.\n *\n * Implementation Note - Overloads:\n * The return type `InferOutput<S, Props>` is a conditional type.\n * TypeScript cannot automatically verify inside the function body that the\n * runtime return values (which are `unknown`) satisfy this complex condition.\n *\n * Separating the signature from the implementation avoids the need for manual\n * type assertions (`as`) on every return statement, keeping the body clean.\n */\nexport function validateWithSchema<\n S extends ComponentSchema,\n Props extends BaseProps = BaseProps\n>(schema: S, inputProps: unknown, componentName: string): InferOutput<S, Props>;\n\nexport function validateWithSchema(\n schema: ComponentSchema,\n inputProps: unknown,\n componentName: string\n) {\n if (!schema) {\n return inputProps;\n }\n\n // Fail-safe:\n // Verify compliance (see 'Schema Object Layout' in JSDoc).\n // Guards against plain objects or malformed configurations being treated as schemas.\n if (!('~standard' in schema)) {\n throw new Error(\n `The schema for \"${componentName}\" is invalid. Expected an object with the \"~standard\" property (e.g. Zod, Valibot), but received a plain object.`\n );\n }\n\n const result = schema['~standard'].validate(inputProps);\n\n // AST traversal is strictly synchronous.\n // Promise-returning validators cannot be awaited during the visitor cycle.\n if (result instanceof Promise) {\n throw new Error(\n `Async schema validation is not supported for \"${componentName}\".`\n );\n }\n\n // Handle 'Result Pattern' (see JSDoc).\n // Unlike native methods (e.g. parse), issues must be checked manually to halt compilation.\n const [firstIssue] = result.issues ?? [];\n if (firstIssue) {\n const issuePath = firstIssue.path?.join('.') ?? 'unknown';\n throw new Error(\n `Invalid props for \"${componentName}\" at \"${issuePath}\": ${firstIssue.message}`\n );\n }\n\n // Some validators only report issues and do not return a decoded `value`.\n if ('value' in result) {\n return result.value;\n }\n\n return inputProps;\n}\n","import type { Container, Node, Options, DiffResult } from './types';\n\n/**\n * Defines the internal tag strings for \"Rich\" built-in types that should be\n * treated as atomic values rather than traversable containers.\n *\n * Uses the exact internal tag strings returned by `Object.prototype.toString`\n * (e.g., \"[object Date]\") instead of checking `constructor.name`.\n *\n * Rationale for using `Object.prototype.toString.call(value)`:\n * 1. Minification Safety:\n * Build tools often rename class constructors to save space\n * (e.g., `Date` becomes `class d`).\n * -> Relying on `.constructor.name` breaks in production.\n * The internal tag `\"[object Date]\"` is guaranteed by the spec and\n * cannot be minified.\n * 2. Robustness:\n * The `.constructor` property is mutable and can be spoofed or deleted.\n * -> `Object.prototype.toString` accesses the internal slot of the object.\n */\nconst Tag = {\n String: '[object String]',\n Number: '[object Number]',\n Boolean: '[object Boolean]',\n BigInt: '[object BigInt]',\n Date: '[object Date]',\n RegExp: '[object RegExp]'\n} as const;\n\n/**\n * A lookup set for O(1) checking of rich types.\n */\nconst RICH_TYPES = new Set<string>([\n // Boxed Primitives\n Tag.String,\n Tag.Number,\n Tag.Boolean,\n Tag.BigInt,\n // Complex Types\n Tag.Date,\n Tag.RegExp\n]);\n\n/**\n * Determines if a value is a \"Rich\" built-in type\n * (Date, RegExp, String, Number, Boolean).\n *\n * Relies on the safe type identification logic defined in `Tag` to avoid\n * issues with minification or cross-realm objects.\n *\n * @param value - The object to inspect.\n * @returns `true` if the object is one of the supported rich types.\n */\nexport function isRichType(value: object): boolean {\n return RICH_TYPES.has(Object.prototype.toString.call(value));\n}\n\n/**\n * Extracts the underlying primitive value from a wrapper object.\n *\n * Precondition:\n * The input object must be a valid wrapper type (`Number`, `String`, `Boolean`)\n * that implements `.valueOf()`.\n *\n * @template T - The expected primitive return type.\n * @param wrapper - The wrapper object to unbox.\n * @returns The unboxed primitive value.\n */\nfunction unbox<T>(wrapper: object): T {\n // Asserts a structural contract containing .valueOf() to allow property\n // access while maintaining type safety.\n return (wrapper as { valueOf(): T }).valueOf();\n}\n\n/**\n * Compares two objects representing atomic static values by their content\n * rather than their reference.\n *\n * Supported types:\n * - Boxed Primitives:\n * - `Number`, `String`, `Boolean`, `BigInt`.\n * - Complex Types:\n * - `Date` (compared by timestamp),\n * - `RegExp` (compared by pattern).\n *\n * Uses strict internal type tags to ensure safety before unboxing or converting\n * values for comparison.\n *\n * @param left - The first object to compare.\n * @param right - The second object to compare.\n * @returns `true` if both objects represent the same value.\n */\nexport function areBoxedPrimitivesEqual(left: object, right: object): boolean {\n const leftTypeTag = Object.prototype.toString.call(left);\n const rightTypeTag = Object.prototype.toString.call(right);\n\n // If underlying types are different (e.g. String vs Number), they cannot be equal.\n if (leftTypeTag !== rightTypeTag) return false;\n\n switch (leftTypeTag) {\n // Group 1: Rely on .valueOf() (via unbox)\n case Tag.Number: {\n const leftValue = unbox<number>(left);\n const rightValue = unbox<number>(right);\n\n /**\n * 1. Special Handling for NaN\n * In JavaScript, `NaN === NaN` is false.\n * This check treats two NaN values as equal to prevent reporting a\n * change whenever a value remains NaN.\n */\n if (Number.isNaN(leftValue)) {\n return Number.isNaN(rightValue);\n }\n\n /**\n * 2. Standard Equality (Infinity & Finite Numbers)\n * Unlike NaN, Infinity adheres to standard strict equality rules:\n * - Infinity === Infinity -> true\n * - Infinity === -Infinity -> false\n */\n return leftValue === rightValue;\n }\n\n case Tag.String:\n return unbox<string>(left) === unbox<string>(right);\n case Tag.Boolean:\n return unbox<boolean>(left) === unbox<boolean>(right);\n case Tag.BigInt:\n return unbox<bigint>(left) === unbox<bigint>(right);\n case Tag.Date:\n return unbox<number>(left) === unbox<number>(right);\n\n // Group 2: Relies on .toString()\n case Tag.RegExp:\n return left.toString() === right.toString();\n\n default:\n return false;\n }\n}\n\n/**\n * Determines if two arrays are shallowly equal.\n *\n * This function handles comparison with the following priorities:\n *\n * 1. Reference Equality:\n * Returns `true` immediately if inputs refer to the same array instance.\n * 2. Content Equality:\n * Returns `true` if both arrays contain the same elements in the same order.\n * 3. Safety:\n * Accepts `null` or `undefined` arguments without throwing runtime errors.\n *\n * Note:\n * Uses `Object.is` for comparison. This differs from strict equality (`===`) in two ways:\n * 1. NaN Handling:\n * Treats `NaN` as equal to `NaN` (whereas `NaN === NaN` is false).\n * 2. Signed Zeros:\n * Treats `+0` and `-0` as distinct values (whereas `+0 === -0` is true).\n *\n * @template V - The type of elements in the array.\n * @param left - The first array to compare.\n * @param right - The second array to compare.\n * @returns `true` if the arrays are referentially or content-wise equal.\n */\nexport function areArraysShallowEqual<V>(\n left: readonly V[],\n right: readonly V[]\n): boolean {\n if (left === right) return true;\n\n // Verify lengths are equal, safely handling null or undefined inputs.\n if (left?.length !== right?.length) return false;\n\n /*\n * Checks if every element in 'left' matches the element at the same index in 'right'\n * Returns false immediately if a mismatch is found.\n */\n return left.every((val, index) => Object.is(val, right[index]));\n}\n\n/**\n * Merges the provided partial options with the library's default configuration.\n *\n * Default settings:\n * - `trackCircularReferences`: `true` (prevents stack overflows).\n * - `arrays`: `'atomic'` (treats arrays as single units).\n * - `arrayEquality`: `'reference'` (strictest and fastest equality check).\n * - `keysToSkip`: `[]` (skips nothing).\n *\n * @param options - The user-provided partial options.\n * @returns A complete `Options` object with all fields initialized.\n */\nexport function normalizeOptions(options: Partial<Options>): Options {\n return {\n trackCircularReferences: true,\n arrays: 'atomic',\n arrayEquality: 'reference',\n keysToSkip: [],\n ...options\n };\n}\n\n/**\n * Determines if a value is a traversable container (Object or Array) rather\n * than a primitive or null.\n * Acts as a type guard to narrow `unknown` values to `Container<V>`.\n *\n * @template V - The type of leaf values within the container.\n * @param value - The value to inspect.\n * @returns `true` if the value is a non-null object.\n */\nexport function isContainer<V>(value: unknown): value is Container<V> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Retrieves a child node from a container using a unified string key access\n * mechanism.\n *\n * Implementation Detail:\n * 1. Strict Indexing:\n * TypeScript enforces strict rules where Arrays must be accessed via numeric\n * indices, while Objects use string keys.\n * 2. Runtime Disambiguation:\n * The function checks `Array.isArray` to determine the underlying container type.\n * 3. Type Compliance:\n * If the container is an Array, the key is converted to a `number`.\n * This satisfies the type definition while preserving strict type safety.\n *\n * @template V - The type of leaf values within the container.\n * @param container - The parent node (Object or Array).\n * @param key - The property name or index as a string (typically from `Object.keys`).\n * @returns The value at the specified key, or `undefined`.\n */\nexport function getSafeValue<V>(\n container: Container<V>,\n key: string\n): Node<V> | undefined {\n if (Array.isArray(container)) {\n return container[Number(key)];\n }\n return container[key];\n}\n\n/**\n * Determines if a specific key should be skipped during comparison based on the\n * configuration.\n *\n * Rules:\n * 1. Object Scope:\n * Keys are ignored if they appear in `keysToSkip` AND the parent container\n * is an object.\n * 2. Array Integrity:\n * Array indices are *never* skipped (even if `keysToSkip` contains numeric\n * strings) to ensure sequence order is preserved.\n *\n * @param key - The property key to check.\n * @param isContainerArray - Indicates if the parent container is an array.\n * @param keysToSkip - The list of keys to ignore (optional).\n * @returns `true` if the key should be ignored.\n */\nexport function shouldSkipKey(\n key: string,\n isContainerArray: boolean,\n keysToSkip?: readonly string[]\n): boolean {\n // 1. Array Guard:\n // Indices must be preserved to maintain sequence integrity.\n if (isContainerArray) return false;\n\n // 2. Availability Check:\n // Exit early if the skip list is missing or undefined.\n if (!keysToSkip) return false;\n\n // 3. Membership Check:\n // Determine if the key is explicitly excluded.\n return keysToSkip.includes(key);\n}\n\n/**\n * Converts a raw iteration key (string) into the correct path segment type.\n *\n * - If the container is an Array, the key is converted to a `number`.\n * - If the container is an Object, the key remains a `string`.\n *\n * @param key - The raw key string.\n * @param isContainerArray - Indicates if the parent container is an array.\n * @returns A number if the container is an array, otherwise the original string.\n */\nexport function formatPathKey(\n key: string,\n isContainerArray: boolean\n): string | number {\n return isContainerArray ? Number(key) : key;\n}\n\n/**\n * Prepends a path segment to the `path` array of every difference in the\n * provided list.\n *\n * This is used during the recursive \"bubble up\" phase to construct the full\n * path from the root to the leaf difference.\n *\n * Performance Note:\n * This function uses in-place mutation (`unshift`) to support the \"Bottom-Up\"\n * path construction strategy.\n *\n * @see compareChildren - For the detailed architectural rationale regarding\n * Bottom-Up (lazy) vs. Top-Down (eager) path construction.\n *\n * @template TNode - The type of the node value (usually `Node<V>`).\n * @param differences - The list of differences generated from child nodes.\n * @param pathSegment - The current property key or index to prepend.\n * @returns The same array of differences with updated paths (mutated in place for performance).\n */\nexport function prependPath<TNode>(\n differences: DiffResult<TNode>[],\n pathSegment: string | number\n): DiffResult<TNode>[] {\n for (const difference of differences) {\n difference.path.unshift(pathSegment);\n }\n return differences;\n}\n\n/**\n * Factory function to construct a `DiffChange` object.\n * Standardizes the creation of modification events.\n *\n * @template V - The type of leaf values.\n * @param path - The full path to the changed node.\n * @param value - The new value in the current state.\n * @param oldValue - The previous value in the old state.\n * @returns A structured `DiffChange` object.\n */\nexport function createChange<V>(\n path: (string | number)[],\n value: Node<V>,\n oldValue: Node<V>\n): DiffResult<Node<V>> {\n return { type: 'CHANGE', path, value, oldValue };\n}\n\n/**\n * Factory function to construct a `DiffCreate` object.\n * Standardizes the creation of addition events.\n *\n * @template V - The type of leaf values.\n * @param path - The full path to the new node.\n * @param value - The value that was added.\n * @returns A structured `DiffResult` object representing a creation.\n */\nexport function createCreate<V>(\n path: (string | number)[],\n value: Node<V>\n): DiffResult<Node<V>> {\n return { type: 'CREATE', path, value };\n}\n\n/**\n * Factory function to construct a `DiffRemove` object.\n * Standardizes the creation of deletion events.\n *\n * @template V - The type of leaf values.\n * @param path - The full path to the removed node.\n * @param oldValue - The value that was removed.\n * @returns A structured `DiffResult` object representing a removal.\n */\nexport function createRemove<V>(\n path: (string | number)[],\n oldValue: Node<V>\n): DiffResult<Node<V>> {\n return { type: 'REMOVE', path, oldValue };\n}\n","import type { NodeArray, Options, DiffResult, Node } from './types';\nimport { areArraysShallowEqual, createChange } from './utils';\n\n/**\n * Defines the signature for functions that determine if two arrays are equivalent\n * according to a specific 'atomic' equality logic (e.g., reference vs shallow).\n */\ntype ArrayComparator<V> = (a: NodeArray<V>, b: NodeArray<V>) => boolean;\n\n/**\n * Represents the active strategy for handling array comparisons.\n * This discriminated union encapsulates the logic required for the selected mode.\n */\nexport type ArrayStrategy<V> =\n | {\n /**\n * Identifies the strategy where arrays are traversed index-by-index (recursion).\n */\n mode: 'diff';\n }\n | {\n /**\n * Identifies the strategy where arrays are skipped entirely (treated as always equal).\n */\n mode: 'ignore';\n }\n | {\n /**\n * Identifies the strategy where arrays are compared as a single unit.\n */\n mode: 'atomic';\n /**\n * The specific equality function (e.g., reference check or shallow comparison)\n * configured to determine if the array node has changed.\n */\n comparator: ArrayComparator<V>;\n };\n\n/**\n * Factory function that selects and configures the appropriate array comparison strategy\n * based on the provided user options.\n *\n * For 'atomic' mode, this resolves the specific `ArrayComparator` (reference vs shallow)\n * needed to perform the equality check.\n *\n * @param options - The full options object containing `arrays` and `arrayEquality` settings.\n * @returns The configured strategy object ready for use in the diffing loop.\n */\nexport function getArrayStrategy<V>(options: Options): ArrayStrategy<V> {\n switch (options.arrays) {\n case 'diff':\n return { mode: 'diff' };\n case 'ignore':\n return { mode: 'ignore' };\n case 'atomic': {\n const comparator: ArrayComparator<V> =\n options.arrayEquality === 'reference'\n ? (a, b) => a === b\n : (a, b) => areArraysShallowEqual(a, b);\n return { mode: 'atomic', comparator };\n }\n default:\n throw new Error(`Invalid array policy: ${options.arrays}`);\n }\n}\n\n/**\n * Executes the selected array strategy against two array nodes.\n *\n * This function determines the next step in the algorithm:\n * 1. **Atomic/Ignore**: Handles the comparison immediately and returns any resulting diffs.\n * Signals `shouldRecurse: false` because the array is treated as a leaf or ignored.\n * 2. **Diff**: Returns `shouldRecurse: true`, signaling the caller to iterate over\n * the array indices and compare them individually.\n *\n * @param strategy - The active array strategy configuration.\n * @param previous - The array from the base state.\n * @param current - The array from the new state.\n * @returns An object containing the recursion instruction and any immediate diffs.\n */\nexport function checkArrayStrategy<V>(\n strategy: ArrayStrategy<V>,\n previous: NodeArray<V>,\n current: NodeArray<V>\n): { shouldRecurse: boolean; diffs: DiffResult<Node<V>>[] } {\n switch (strategy.mode) {\n case 'ignore':\n // Treat arrays as always equal; emit no diffs and do not traverse.\n return { shouldRecurse: false, diffs: [] };\n\n case 'atomic':\n // Check equality using the configured comparator.\n // If equal: emit no diffs.\n // If different: emit one atomic CHANGE for the entire array.\n return strategy.comparator(previous, current)\n ? { shouldRecurse: false, diffs: [] }\n : {\n shouldRecurse: false,\n diffs: [createChange([], current, previous)]\n };\n\n case 'diff':\n // Signal the caller to perform standard index-by-index recursion.\n return { shouldRecurse: true, diffs: [] };\n }\n}\n","import type { Container, CycleEntry, DiffResult, Node, Options } from './types';\n\nimport {\n areBoxedPrimitivesEqual,\n createChange,\n createCreate,\n createRemove,\n formatPathKey,\n getSafeValue,\n isContainer,\n shouldSkipKey,\n isRichType,\n normalizeOptions,\n prependPath\n} from './utils';\n\nimport {\n type ArrayStrategy,\n checkArrayStrategy,\n getArrayStrategy\n} from './strategies';\n\n/**\n * Checks if the current pair of containers has already been processed in the\n * current recursion stack.\n *\n * Logic:\n * 1. Traversal:\n * Iterates through the provided `stack`\n * (the history of the current recursion path).\n * 2. Comparison:\n * Checks if the exact pair of references (`previous` and `current`) matches\n * any pair already recorded in the history.\n * 3. Detection:\n * If a match is found, it confirms a circular reference\n * (a \"back-edge\" in the graph traversal).\n *\n * @template V - The type of leaf values within the containers.\n * @param stack - The current recursion path history (list of ancestor pairs).\n * @param previous - The container from the base state currently being visited.\n * @param current - The container from the new state currently being visited.\n * @returns `true` if the pair exists in the stack, indicating a cycle.\n */\nfunction isCycleDetected<V>(\n stack: readonly CycleEntry<V>[],\n previous: Container<V>,\n current: Container<V>\n): boolean {\n for (const [seenPrevious, seenCurrent] of stack) {\n // If both sides match an ancestor pair by reference, we have looped.\n if (seenPrevious === previous && seenCurrent === current) return true;\n }\n return false;\n}\n\n/**\n * Conditionally adds the current pair of containers to the recursion history stack.\n *\n * Logic:\n * 1. Configuration Check:\n * Verifies if `trackCircularReferences` is enabled in the options.\n * If disabled, the function returns the original stack immediately (no-op).\n * 2. Entry Creation:\n * Constructs a `CycleEntry` tuple containing the `previous` and `current`\n * container references.\n * 3. Immutable Update:\n * Returns a **new** array containing the existing history plus the new entry.\n * This ensures the stack is strictly path-scoped and does not leak to sibling branches.\n *\n * @template V - The type of leaf values within the containers.\n * @param options - The global configuration object.\n * @param stack - The current recursion path history.\n * @param previous - The container from the base state.\n * @param current - The container from the new state.\n * @returns A new stack array with the entry added, or the original stack if tracking is disabled.\n */\nfunction pushCycleEntry<V>(\n options: Options,\n stack: readonly CycleEntry<V>[],\n previous: Container<V>,\n current: Container<V>\n): readonly CycleEntry<V>[] {\n if (!options.trackCircularReferences) return stack;\n\n // Create the tuple explicitly to satisfy the CycleEntry type definition\n const newEntry: CycleEntry<V> = [previous, current];\n return stack.concat([newEntry]);\n}\n\n/**\n * Iterates over the keys (or indices) of two containers to identify additions,\n * removals, and modifications.\n *\n * Logic:\n * 1. Deletions & Updates: Iterates over keys in the `previousContainer`.\n * - If a key is missing in `currentContainer`, emits a `REMOVE`.\n * - If a key exists in both, proceeds to recursive or shallow comparison.\n * 2. Recursion: If both values are traversable containers, checks for cycles and recurses.\n * 3. Leaf Comparison: If values are primitives or \"Rich Types\" (e.g., Date), compares them by value/reference.\n * 4. Additions: Iterates over keys in the `currentContainer`.\n * - If a key is missing in `previousContainer`, emits a `CREATE`.\n *\n * Execution Flow (Depth-First, Bottom-Up):\n * The algorithm performs a Depth-First Traversal, descending into the tree\n * until it identifies a specific node (leaf or container) that has changed.\n * Once a difference is detected, the full property path is constructed lazily\n * as the recursion stack returns.\n *\n * Trace Example:\n * _Comparing `prev: { users: [{ name: \"Alice\" }] }` vs\n * `curr: { users: [{ name: \"Bob\" }] }`_\n *\n * 1. Dive (Root → Leaf):\n * - Root: Iterates keys. Finds `\"users\"`.\n * - Condition: Both values are Arrays (compatible containers).\n * - Action: Recurse into the Array.\n * - Array: Iterates indices. Finds index `0`.\n * - Condition: Both values are Objects (compatible containers).\n * - Action: Recurse into the Object.\n * - Leaf: Iterates keys. Finds `\"name\"`.\n * - Condition: Values are strings (Atomic/Leaves), not containers.\n * - Action: Compare values directly.\n *\n * 2. Detection (Leaf Level):\n * - Compares `\"Alice\"` vs `\"Bob\"`. Mismatch found.\n * - Diff Created: `{ type: 'CHANGE', path: ['name'], ... }`\n *\n * 3. Bubble Up (Leaf → Root):\n * - Recursion returns to Array Level. Prepends index `0`.\n * -> Path updates to `[0, 'name']`.\n * - Recursion returns to Root Level. Prepends key `\"users\"`.\n * -> Path updates to `['users', 0, 'name']`.\n *\n * Rationale for Bottom-Up Strategy:\n * 1. GC Pressure:\n * A Top-Down approach (passing accumulated paths down) forces array\n * allocation for *every* node visited, creating significant Garbage\n * Collection overhead.\n * 2. Laziness:\n * The Bottom-Up approach is lazy; the cost of path construction (array\n * allocation + shifting) is incurred only when actual differences are\n * detected.\n *\n * @template V - The type of leaf values in the tree structure.\n * @param previousContainer - The container from the base state.\n * @param currentContainer - The container from the new state.\n * @param options - The normalized configuration object.\n * @param cycleStack - The current recursion history for cycle detection.\n * @param arrayStrategy - The pre-calculated strategy for array comparisons.\n * @returns An array of differences found within these containers.\n */\nfunction compareChildren<V>(\n previousContainer: Container<V>,\n currentContainer: Container<V>,\n options: Options,\n cycleStack: readonly CycleEntry<V>[],\n arrayStrategy: ArrayStrategy<V>\n): DiffResult<Node<V>>[] {\n const differences: DiffResult<Node<V>>[] = [];\n\n const isPreviousArray = Array.isArray(previousContainer);\n const isCurrentArray = Array.isArray(currentContainer);\n const previousKeys = Object.keys(previousContainer);\n\n // =========================================================================\n // Phase 1: Detect Removals and Modifications\n //\n // Strategy: Iterate over the OLD state (`previousContainer`).\n // 1. If a key is missing in the NEW state, it was REMOVED.\n // 2. If a key exists in both, compare values to find CHANGES.\n // =========================================================================\n for (const key of previousKeys) {\n // 1. Configuration Check (Skip List)\n if (shouldSkipKey(key, isPreviousArray, options.keysToSkip)) continue;\n\n const previousValue = getSafeValue(previousContainer, key)!;\n const pathSegment = formatPathKey(key, isPreviousArray);\n\n // 2. Removal Check\n if (!(key in currentContainer)) {\n differences.push(createRemove([pathSegment], previousValue));\n continue;\n }\n\n const currentValue = getSafeValue(currentContainer, key)!;\n\n // -----------------------------------------------------------------------\n // Step 3: Deep Comparison (Recursion)\n //\n // Strategy:\n // 1. Validate: Both values must be compatible containers (e.g., both Arrays or both Objects).\n // 2. Guard: Check for circular references (if tracking is enabled).\n // 3. Filter: \"Rich Types\" (Date, RegExp) are treated as atomic leaves, not containers.\n // 4. Execute: Recurse into children and prepend the current path segment to results.\n // -----------------------------------------------------------------------\n if (\n isContainer(previousValue) &&\n isContainer(currentValue) &&\n Array.isArray(previousValue) === Array.isArray(currentValue)\n ) {\n if (\n options.trackCircularReferences &&\n isCycleDetected(cycleStack, previousValue, currentValue)\n ) {\n continue;\n }\n\n if (!isRichType(previousValue)) {\n const nextStack = pushCycleEntry(\n options,\n cycleStack,\n previousValue,\n currentValue\n );\n\n const childDiffs = compare(\n previousValue,\n currentValue,\n options,\n nextStack,\n arrayStrategy\n );\n\n differences.push(...prependPath(childDiffs, pathSegment));\n continue;\n }\n }\n\n // -----------------------------------------------------------------------\n // Step 4: Leaf Comparison (Shallow)\n //\n // Condition: Values are Primitives, \"Rich Types\", or Mismatched Containers.\n // Strategy:\n // 1. Compare values directly using `Object.is`.\n // 2. handle \"Boxed Primitives\" (e.g., `new Number(1)`) explicitly to ensure value equality.\n // 3. Emit a CHANGE if values differ.\n // -----------------------------------------------------------------------\n const hasValueMismatch = !Object.is(previousValue, currentValue);\n\n const areBoxedPrimitives =\n isContainer(previousValue) &&\n isContainer(currentValue) &&\n areBoxedPrimitivesEqual(previousValue, currentValue);\n\n if (hasValueMismatch && !areBoxedPrimitives) {\n differences.push(\n createChange([pathSegment], currentValue, previousValue)\n );\n }\n }\n\n // =========================================================================\n // Phase 2: Detect Additions\n //\n // Strategy: Iterate over the NEW state (`currentContainer`).\n // 1. If a key is missing in the OLD state, it was CREATED.\n // 2. Note: Modifications were already caught in Phase 1, skip them here.\n // =========================================================================\n const currentKeys = Object.keys(currentContainer);\n\n for (const key of currentKeys) {\n if (shouldSkipKey(key, isCurrentArray, options.keysToSkip)) continue;\n\n if (!(key in previousContainer)) {\n const currentValue = getSafeValue(currentContainer, key)!;\n differences.push(\n createCreate([formatPathKey(key, isCurrentArray)], currentValue)\n );\n }\n }\n\n return differences;\n}\n\n/**\n * The central recursive dispatch function. Determines the comparison method\n * based on node type and configuration.\n *\n * Logic:\n * 1. Array Optimization:\n * If both nodes are arrays, consults the active `ArrayStrategy`.\n * - If the strategy is `'atomic'` or `'ignore'`, it performs the check\n * immediately and returns results.\n * - If the strategy is `'diff'`, it proceeds to step 2.\n * 2. Traversal:\n * Delegates to `compareChildren` to iterate over keys (for Objects) or\n * indices (for Arrays in 'diff' mode) and recursively compare child nodes.\n *\n * @template V - The type of leaf values in the tree structure.\n * @param previous - The container from the base state.\n * @param current - The container from the new state.\n * @param options - The normalized configuration object.\n * @param cycleStack - The current recursion history for cycle detection.\n * @param arrayStrategy - The pre-calculated strategy for array comparisons.\n * @returns An array of differences found at this level or below.\n */\nfunction compare<V>(\n previous: Container<V>,\n current: Container<V>,\n options: Options,\n cycleStack: readonly CycleEntry<V>[],\n arrayStrategy: ArrayStrategy<V>\n): DiffResult<Node<V>>[] {\n // 1. Array Strategy Check\n if (Array.isArray(previous) && Array.isArray(current)) {\n const { shouldRecurse, diffs } = checkArrayStrategy(\n arrayStrategy,\n previous,\n current\n );\n\n // 2. Early Exit (Atomic/Ignore)\n if (!shouldRecurse) return diffs;\n }\n\n // 3. Recursive Traversal (Objects or 'diff' mode Arrays)\n return compareChildren(previous, current, options, cycleStack, arrayStrategy);\n}\n\n/**\n * Calculates the deep structural difference between two traversable containers\n * (Objects or Arrays).\n *\n * Logic:\n * 1. Configuration:\n * Normalizes the provided `options` by merging them with library defaults\n * (e.g., enabling circular reference tracking, setting array mode to 'atomic').\n * 2. Strategy Resolution:\n * Constructs the specific `ArrayStrategy` object required to handle array\n * comparisons (Atomic vs Diff) based on the configuration.\n * 3. Execution:\n * Initiates the recursive comparison algorithm starting at the provided root\n * nodes with an empty recursion history.\n *\n * @template V - The type of leaf values in the tree structure.\n * @param previous - The original structure (base state).\n * @param current - The new structure (updated state).\n * @param options - Optional configuration settings to customize behavior.\n * @returns An array of differences describing the operations required to transform `previous` into `current`.\n */\nexport function diff<V>(\n previous: Container<V>,\n current: Container<V>,\n options: Partial<Options> = {}\n): DiffResult<Node<V>>[] {\n const normalized = normalizeOptions(options);\n const strategy = getArrayStrategy<V>(normalized);\n\n // Pass '[]' (empty array) as the initial cycleStack.\n // This initializes the recursion state while keeping the public API clean.\n return compare(previous, current, normalized, [], strategy);\n}\n","import { type ObjectExpression } from 'estree';\nimport { type types, is } from 'estree-toolkit';\nimport { type PropertyPath } from './types';\n\n/**\n * Determines whether a node is a \"patchable props root\" for this patcher.\n *\n * Patchable (in this module) means:\n * - The node is an object literal (`ObjectExpression`) that provides a stable local\n * `properties[]` container for traversal and leaf-only edits.\n * - Leaf-only edits are limited to:\n * - replacing existing `Property.value` nodes\n * - editing existing `ArrayExpression.elements[index]` slots *within* that literal subtree\n *\n * JSX / compiled output context\n * -----------------------------\n * This function targets the wrapper object literal that becomes the props argument in the\n * compiled component call, conceptually:\n *\n * _jsx(Component, { ...propsHere })\n *\n * Array patching depends on this wrapper object:\n * - Arrays are patched only when they appear as values inside the wrapper object:\n *\n * <Comp items={[1, 2, 3]} />\n * // wrapper: { items: [1, 2, 3] } (ObjectExpression root)\n *\n * - An `ArrayExpression` is never treated as a valid props root. If the root expression is\n * not the wrapper object literal (Identifier, CallExpression, conditional/logical\n * expressions, spreads, etc.), there is no stable local object-literal structure to edit\n * safely under the leaf-only strategy.\n *\n * @param node\n * Candidate AST node.\n * @returns\n * `true` if `node` is an `ObjectExpression`; otherwise `false`.\n */\nexport function isPatchablePropsRoot(\n node: types.Node | null | undefined\n): node is ObjectExpression {\n return !!node && is.objectExpression(node);\n}\n\n/**\n * Checks whether a value is an array.\n *\n * Wrapper around `Array.isArray` that acts as a TypeScript **type guard**\n * (`value is T[]`). Note: `T` is not validated at runtime.\n *\n * @typeParam T Assumed element type (defaults to `unknown`).\n * @param value Value to test.\n * @returns `true` if `value` is an array.\n */\nexport function isArray<T = unknown>(value: unknown): value is T[] {\n return Array.isArray(value);\n}\n\n/**\n * Checks whether a `PropertyPath` segment is a valid, existing array index.\n *\n * Guarantees:\n * 1. Numeric-only indexing\n * - Array path segments must be numbers.\n * - Prevents treating array object properties (e.g. \"length\", \"map\", custom props)\n * as traversable path segments.\n *\n * 2. Property existence (not value inspection)\n * - Checks whether the index exists on the array, regardless of the stored value.\n * - Avoids value-based checks that would treat `undefined` as “missing”.\n *\n * 3. Own-property only\n * - Uses `Object.hasOwn(arr, key)` rather than `key in arr`.\n * - The `in` operator checks the prototype chain and can report an index as\n * present if numeric properties exist on `Array.prototype`.\n * - `Object.hasOwn` restricts the check to the array instance itself, matching\n * traversal semantics where the path succeeds only when the array explicitly\n * contains that index.\n *\n * 4. Order matters\n * - The numeric type check happens before the existence lookup.\n * - Ensures string keys never pass due to unrelated array properties.\n *\n * @template T\n * Element type of the array (compile-time only).\n * @param arr\n * Array instance to check.\n * @param key\n * Candidate path segment (must be a number to be a valid array index).\n * @returns\n * `true` if `key` is a number and that index exists as an own property on `arr`;\n * otherwise `false`. When `true`, TypeScript narrows `key` to `number`.\n */\nexport function hasArrayIndex<T>(\n arr: readonly T[],\n key: string | number\n): key is number {\n return typeof key === 'number' && Object.hasOwn(arr, key);\n}\n\n/**\n * Determines whether a value is a \"plain object\" (a simple POJO / dictionary\n * object).\n *\n * A value is considered plain if all of the following are true:\n * 1. It is not `null`.\n * 2. `typeof value === \"object\"`.\n * 3. Its prototype is either:\n * - `Object.prototype` (typical object literals / `new Object()`), or\n * - `null` (objects created via `Object.create(null)`).\n *\n * As a result, this returns `false` for common non-plain objects such as:\n * - Arrays\n * - Dates\n * - Maps and Sets\n * - Class instances\n * - Errors, RegExps, DOM nodes, and other host/boxed objects\n *\n * TypeScript:\n * - This function is a **type guard** because it returns a type predicate\n * (`value is ...`).\n * - When it returns `true`, TypeScript will narrow `value` to\n * `Record<PropertyKey, T>` in that branch.\n * - The generic `T` is a compile-time hint only; it is **not** validated at\n * runtime.\n *\n * @typeParam T\n * The (assumed) type of the object's property values after a successful check.\n * @param value\n * The value to test.\n * @returns\n * `true` if `value` is a plain object; otherwise `false`.\n */\nexport function isPlainObject<T = unknown>(\n value: unknown\n): value is Record<PropertyKey, T> {\n if (typeof value !== 'object' || value === null) return false;\n\n const proto = Object.getPrototypeOf(value);\n return proto === null || proto === Object.prototype;\n}\n\n/**\n * Narrowing helper for \"object-like\" values.\n *\n * Many type guards start from `unknown`. This helper provides a safe first step:\n * it checks that the value is a non-null object so properties can be read without\n * runtime errors and without type assertions.\n *\n * @param value\n * Unknown value to test.\n * @returns\n * `true` if `value` is a non-null object; otherwise `false`.\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Type guard for `PropertyPath` (type narrowing predicate).\n *\n * A `PropertyPath` is the patch planner's stable addressing format for nested props:\n * an array of segments where:\n * - `string` segments address object keys (e.g. `\"items\"`, `\"id\"`)\n * - `number` segments address array indices (e.g. `0`, `1`)\n *\n * This guard is used when a `PropertyPath` is obtained from an untyped source (most\n * commonly `JSON.parse` of a serialized path key) to avoid type assertions.\n *\n * @param value\n * Unknown value to validate.\n * @returns\n * `true` if `value` is an array of `(string | number)` segments; otherwise `false`.\n */\nexport function isPropertyPath(value: unknown): value is PropertyPath {\n return (\n Array.isArray(value) &&\n value.every(seg => typeof seg === 'string' || typeof seg === 'number')\n );\n}\n\n/**\n * Checks whether a value is a traversable container.\n *\n * A value is considered traversable if it is:\n * 1. An Array, or\n * 2. A plain object (POJO / dictionary-like object).\n *\n * @param value Value to test.\n * @returns `true` if `value` is traversable; otherwise `false`.\n */\nexport function isTraversable(\n value: unknown\n): value is Record<PropertyKey, unknown> | unknown[] {\n // Check arrays first since `Array.isArray` is usually a cheap, optimized\n // built-in.\n return isArray(value) || isPlainObject(value);\n}\n","import { hasArrayIndex, isArray, isPlainObject } from '../guards';\nimport { PropertyPath } from '../types';\n\n/**\n * Checks whether a single object key is configured to be preserved.\n *\n * Implicitly coerces numeric keys to strings to match standard JavaScript\n * behavior (e.g., matching AST key `0` against config `\"0\"`).\n *\n * @param key\n * The object key to test.\n * @param preservedKeys\n * The configured preserve set.\n * @returns\n * `true` if the key (normalized to string) is present in `preservedKeys`.\n */\nexport function isKeyPreserved(\n key: string | number,\n preservedKeys: ReadonlySet<string>\n): boolean {\n const lookupKey = String(key);\n return preservedKeys.has(lookupKey);\n}\n\n/**\n * Checks whether a property path should be excluded from diffing/patching.\n *\n * Once a preserved key appears anywhere in the path, the entire subtree beneath\n * that key is treated as opaque and skipped.\n *\n * Example:\n * - preservedKeys = new Set(['children'])\n * - path = ['children'] -> preserved (true)\n * - path = ['children', 0] -> preserved (true)\n * - path = ['props', 'children', 1] -> preserved (true)\n * - path = ['title'] -> not preserved (false)\n *\n * @param path\n * The property path segments produced by diffing.\n * @param preservedKeys\n * Keys that should cause the path (and its subtree) to be preserved.\n * @returns\n * `true` if any string segment in `path` matches a preserved key; otherwise `false`.\n */\nexport function isPathPreserved(\n path: PropertyPath,\n preservedKeys: ReadonlySet<string>\n): boolean {\n for (const segment of path) {\n if (typeof segment === 'string' && isKeyPreserved(segment, preservedKeys)) {\n return true;\n }\n }\n return false;\n}\n\nexport const TRAVERSE_MISSING = Symbol('recma.traverse.missing');\n\n/**\n * Performs a single, guarded traversal step into a container value.\n *\n * Traversal rules:\n * 1. Arrays: the segment must be a numeric index that exists on the array.\n * 2. Objects: the segment must be an own property key.\n * 3. Everything else: not traversable.\n *\n * @param current\n * The current container value to traverse into.\n * @param key\n * The next path segment (array index or object key).\n * @returns\n * The value at `current[key]`, or `TRAVERSE_MISSING` if the step is invalid.\n */\nexport function traverseStep(\n current: unknown,\n key: string | number\n): unknown | typeof TRAVERSE_MISSING {\n // 1. Arrays\n if (isArray(current)) {\n if (!hasArrayIndex(current, key)) return TRAVERSE_MISSING;\n return current[key];\n }\n\n // 2. Objects\n if (isPlainObject(current)) {\n // Own-property check: ignores prototype/inherited properties to ensure\n // traversal only follows keys defined directly on the object instance.\n if (!Object.hasOwn(current, key)) return TRAVERSE_MISSING;\n\n return current[key];\n }\n\n // 3. Not traversable\n return TRAVERSE_MISSING;\n}\n\n/**\n * Checks whether a `PropertyPath` exists within the original, extracted structure.\n *\n * Purpose:\n * - Enforces the current \"leaf-only\" constraint by answering a single question:\n * \"Is there already something at this path that can be updated?\"\n *\n * Current behavior:\n * - Returns `true` only when every segment can be traversed successfully using\n * the same traversal rules as the differ/patcher (arrays by numeric index,\n * objects by own keys).\n * - Returns `false` when any segment is missing or the structure is not traversable.\n *\n * Why this matters:\n * - The current patching strategy replaces values of existing AST nodes and does\n * not insert new structural nodes (e.g. adding a missing property).\n * - This function can be used as a guard to avoid producing patches that would\n * require structural insertion (such as schema defaults for missing props).\n *\n * Future extension:\n * - If structural \"CREATE\" is implemented, this function remains useful for\n * verifying parent/container existence (e.g. checking `path.slice(0, -1)`)\n * before attempting an insertion.\n *\n * @param root\n * Root value to traverse.\n * @param path\n * Path segments to check for existence.\n * @returns\n * `true` if every segment can be traversed successfully; otherwise `false`.\n */\nexport function hasPath(root: unknown, path: PropertyPath): boolean {\n let current: unknown = root;\n\n for (const key of path) {\n const next = traverseStep(current, key);\n if (next === TRAVERSE_MISSING) return false;\n current = next;\n }\n\n return true;\n}\n","import { isPlainObject } from './guards';\nimport { isKeyPreserved } from './utils/path-utils';\n\n/**\n * A plain object record restricted to string keys.\n *\n * This type definition intentionally excludes `symbol` keys to align with the\n * runtime behavior of `Object.keys()`, which is used for iteration in the\n * overlay logic.\n *\n * - Strings & Numbers: Supported\n * Numeric keys are implicitly converted to strings by the JavaScript runtime.\n * - Symbols: Excluded.\n * This utility is designed for standard data structures and does not support\n * the structural merging of Symbol-keyed properties.\n */\nexport type PlainObjectRecord = Record<string, unknown>;\n\n/**\n * Core implementation of the object overlay logic.\n *\n * The execution flow follows a **Filter → Traverse → Commit** pipeline:\n *\n * 1. Filter Phase (Exclusion Rules):\n *\n * 1.1 Preservation Rule (Value Integrity):\n * Keys listed in `preservedKeys` (e.g., `children`) are skipped entirely.\n * This ensures that specialized runtime constructs in `base` are\n * protected from being overwritten by overlay results.\n *\n * 1.2 Injection Rule (Structural Stability):\n * Keys present in `overlay` but missing from `base` are skipped.\n * This prevents structural expansion, ensuring that the merge operation\n * strictly adheres to the fixed topology of the base object.\n *\n * 2. Traverse Phase (Recursion):\n *\n * For keys passing the exclusion rules, the function delegates to the\n * internal value dispatcher (`overlayValue`) to handle type-specific\n * overlay logic.\n *\n * 3. Commit Phase (Update & Optimization):\n *\n * 3.1 Change Detection (Commit Guard):\n * Updates are skipped if the merged value is equivalent to the existing\n * value. Equality checks adhere to the Comparison Policy defined above.\n *\n * 3.2 Lazy Allocation (Reference Preservation):\n * A new object container is allocated only when a property value diverges\n * from the base source. If all values match, the original object is\n * returned to preserve referential equality.\n *\n * @param base The source object (structural foundation).\n * @param overlay The object containing new values to apply.\n * @param preservedKeys Set of keys to exclude from the overlay process.\n * @returns A new object with overlay values applied, or the original base if no changes occurred.\n */\nfunction overlayObject(\n base: PlainObjectRecord,\n overlay: PlainObjectRecord,\n preservedKeys: ReadonlySet<string>\n): PlainObjectRecord {\n let resultObject: PlainObjectRecord | undefined;\n\n for (const candidateKey of Object.keys(overlay)) {\n // 1.1 Filter Phase (Preservation Rule)\n if (isKeyPreserved(candidateKey, preservedKeys)) continue;\n\n // 1.2 Filter Phase (Injection Rule)\n if (!Object.hasOwn(base, candidateKey)) continue;\n\n const basePropValue = base[candidateKey];\n const overlayPropValue = overlay[candidateKey];\n\n // 2. Traverse Phase (Recursion)\n const mergedValue = overlayValue(\n basePropValue,\n overlayPropValue,\n preservedKeys\n );\n\n // 3.1 Commit Phase (Change Detection)\n if (Object.is(mergedValue, basePropValue)) continue;\n\n // 3.2 Commit Phase (Lazy Allocation)\n // Allocate a new object container only upon the first confirmed\n // divergence.\n if (!resultObject) resultObject = { ...base };\n resultObject[candidateKey] = mergedValue;\n }\n\n return resultObject ?? base;\n}\n\n/**\n * Internal dispatcher for arbitrary values.\n *\n * Implements the **Mutual Recursion** pattern to decouple:\n *\n * - Iteration Logic (`overlayObject`):\n * Key traversal, exclusion filtering, and write optimization.\n * - Structural Resolution (`overlayValue`):\n * Identifies the data topology to apply the matching overlay strategy.\n *\n * This separation keeps the update loop in `overlayObject` clean and focused on\n * the \"Filter → Traverse → Commit\" pipeline without cluttering it with type\n * checks.\n *\n * ---\n *\n * Applies specific structural strategies based on the value type, mapping to\n * the high-level strategies defined in `overlayObject`:\n *\n * 1. Subtree Pruning:\n * Checks for identity before inspecting types.\n * If the values are equivalent according to the global Comparison Policy,\n * the original base reference is returned.\n * -> This halts recursion for unchanged subtrees.\n *\n * 2. Array Strategy (Atomic Replacement):\n * Arrays are treated as atomic units.\n * -> The overlay array strictly replaces the base array.\n * (Index-by-index merging is prohibited to prevent data corruption.)\n *\n * 3. Object Strategy (Recursive Merge):\n * Objects are treated as open sets.\n * -> Execution delegates to `overlayObject` to apply the Left Join logic,\n * preserving keys that exist in the base object but are missing from the overlay.\n *\n * 4. Primitive Strategy (Value Replacement):\n * Primitives are treated as terminal values.\n * -> The overlay value overwrites the base value.\n *\n * @param basePropValue The value derived from the base object property.\n * @param overlayPropValue The value derived from the overlay object property.\n * @param preservedKeys Set of keys to exclude during recursive object merges.\n * @returns The resolved value based on the specific overlay strategy.\n */\nfunction overlayValue(\n basePropValue: unknown,\n overlayPropValue: unknown,\n preservedKeys: ReadonlySet<string>\n): unknown {\n // 1. Subtree Pruning\n if (Object.is(basePropValue, overlayPropValue)) return basePropValue;\n\n // 2. Array Strategy (Atomic Replacement)\n if (Array.isArray(basePropValue) && Array.isArray(overlayPropValue)) {\n return overlayPropValue;\n }\n\n // 3. Object Strategy (Recursive Merge)\n if (isPlainObject(basePropValue) && isPlainObject(overlayPropValue)) {\n return overlayObject(basePropValue, overlayPropValue, preservedKeys);\n }\n\n // 4. Primitive Strategy (Value Replacement)\n return overlayPropValue;\n}\n\n/**\n * Overlays overlay object properties onto a base object.\n *\n * Acts as the public entry point for the object overlay strategy.\n *\n * This function orchestrates the overlay process using distinct strategies:\n *\n * 1. Merge Strategy (Left Join):\n * Merges overlay values into the base object, establishing the base as the\n * definitive structural template.\n * This strategy merges data while strictly respecting the topology of the\n * base object.\n *\n * 1.1 Structural Definition:\n * The `base` serves as the structural base, defining which keys exist in\n * the base object.\n *\n * 1.2 Passthrough Preservation:\n * Keys present in the base but missing from the overlay are explicitly\n * retained (never deleted), ensuring that \"Passthrough Props\" survive\n * validation.\n *\n * 1.3 Value Replacement:\n * For keys present in both, the value from `overlay` overwrites the\n * base value. This enables safe type conversion (e.g., `'1'` → `1`)\n * without modifying the key structure.\n *\n * 2. Traversal Strategy:\n * The logic relies on recursive depth-first traversal.\n * For every key passing the exclusion rules, the function delegates to the\n * internal `overlayValue` dispatcher. This ensures that:\n * - Nested objects are merged recursively (applying the Left Join deep).\n * - Arrays and Primitives are handled as **direct replacements** (stopping recursion).\n *\n * 3. Comparison Policy:\n * All equality checks throughout the pipeline use `Object.is`.\n * This ensures:\n * - Referential Equality: For objects and arrays.\n * - Strict Equality: For standard primitives.\n * - NaN Stability: Prevents unnecessary allocation on `NaN`\n * (where `NaN !== NaN` would otherwise trigger a false positive).\n *\n * ---\n *\n * Examples:\n *\n * Scenario 1: Value Replacement & Passthrough\n * // Case: Validating a numeric prop while keeping a CSS class.\n * base = { zIndex: \"50\", className: \"sticky-header\" }\n * overlay = { zIndex: 50 } // Schema converts string to number\n * result = { zIndex: 50, className: \"sticky-header\" }\n * // -> 'zIndex' is updated (from \"50\" to 50).\n * // -> 'className' is preserved (missing from overlay).\n *\n * Scenario 2: Value Integrity (Preservation Rule)\n * // Case: Validating a variant prop while 'children' contains specialized data.\n * base = { children: <ComplexValue>, variant: \"flat\" }\n * overlay = { children: \"Button Text\", variant: \"solid\" }\n * preservedKeys = new Set([\"children\"])\n * result = { children: <ComplexValue>, variant: \"solid\" }\n * // -> 'children' is skipped entirely (Base value wins).\n * // -> 'variant' is updated normally (from \"flat\" to \"solid\").\n *\n * Scenario 3: Structural Stability (Injection Rule)\n * // Case: Schema defines a default value for a missing prop.\n * base = { label: \"Submit\" }\n * overlay = { label: \"Submit\", disabled: false } // Schema adds default\n * result = { label: \"Submit\" }\n * // -> 'disabled' is skipped. Adding it would extend the defined structure,\n * // which is prohibited.\n *\n * @param base The source object (structural foundation).\n * @param overlay The object containing new values to apply.\n * @param preservedKeys Set of keys to exclude from the overlay process.\n * @returns The final merged object representing the updated state.\n *\n * @see overlayObject for the detailed execution pipeline\n */\nexport function applyOverlay(\n base: PlainObjectRecord,\n overlay: PlainObjectRecord,\n preservedKeys: ReadonlySet<string>\n): PlainObjectRecord {\n // Skip the overlay operation entirely if the root inputs are already\n // identical (Comparison Policy).\n if (Object.is(base, overlay)) return base;\n\n // Delegate to the internal object iterator.\n return overlayObject(base, overlay, preservedKeys);\n}\n","import type {\n PreservedSubtreeLifecycle,\n LeafOnlyPatchingConstraint\n} from './architecture';\n\nimport type { SetPropertyPatch } from './types';\n\nimport { diff } from './differ/index';\nimport { isPlainObject } from './guards';\nimport { applyOverlay } from './object-overlay';\n\n/**\n * Patch planning strategy\n * -----------------------\n *\n * This module reconciles the **Extracted Props** (Static Data View) with\n * the **Validated Props** (Schema Output) to determine permissible updates.\n *\n * It implements the **Patch Planning** phase (Section C) of the\n * {@link PreservedSubtreeLifecycle}.\n *\n * 1. Structural Integrity (Entry Guard)\n * -------------------------------------\n * Before processing, the root inputs are verified to be strict Plain Object records.\n *\n * 1.1 Scope & Rationale:\n * This restriction applies only to the root container, based on the following:\n * - React Semantics:\n * A Props Container is structurally a Plain Object.\n * Passing an Array or Primitive as the root (e.g., `_jsx(C, [1, 2])`) is invalid.\n * - Algorithm Safety:\n * The diffing engine iterates keys immediately.\n * Passing `null` or primitives would result in runtime errors.\n * - Fail-Soft Strategy:\n * If inputs are structurally invalid, an empty patch set is returned (No-Op).\n * This preserves the source state rather than applying patches based on\n * malformed data.\n *\n * 1.2 Leaf Flexibility:\n * Leaf values retain full flexibility. The structural restriction does not\n * apply recursively because:\n * - Diffing:\n * The engine handles complex leaves natively:\n * - Arrays are managed via the aligned strategy (see Section 2).\n * - \"Rich Types\" (Dates, RegExps) are identified via `isRichType` and\n * compared by value.\n * - Patching:\n * The downstream consumer is capable of serializing these complex types\n * into valid output code.\n *\n * 2. Array Strategy Alignment\n * ---------------------------\n * The implementation maintains a structural invariant by strictly coupling the\n * **Target Construction** phase with the **Change Detection** phase.\n * The default configuration of the `diff` utility is implicitly relied upon to\n * enforce the following alignment:\n *\n * 2.1 Target Construction (Follows Overlay Strategy):\n * The `applyOverlay` utility enforces \"Atomic Replacement\" for arrays.\n * Arrays are strictly replaced rather than merged index-by-index.\n * This ensures a new container reference is produced upon any change.\n *\n * 2.2 Change Detection (Follows Diff Strategy):\n * The `diff` defaults are used to match the Overlay logic:\n * - `arrays: 'atomic'`: Aligns with the overlay swap.\n * Reports a single replacement operation for the whole array rather than\n * granular index-by-index patches.\n * - `arrayEquality: 'reference'`: Aligns with the allocation policy.\n * Detects the new container references created by the overlay, even if\n * internal values are structurally identical.\n *\n * 3. Diff Resolution Protocol\n * ---------------------------\n * The Planner translates raw `diff` operations into permissible patch actions,\n * strictly enforcing the Leaf-Only Constraint:\n *\n * 3.1. CHANGE (\"Coercion\")\n * -------------------\n * - Definition: The schema defines a different value for a key that exists in the extracted props.\n * - Policy: APPLIED.\n * - Reasoning: Safe leaf modification.\n * See {@link LeafOnlyPatchingConstraint} (Coercion).\n *\n * Scenario: Type Correction\n * - Extracted: `<Component zIndex=\"50\" />` (String)\n * - Schema: `zIndex=50` (Number)\n * - Action: UPDATE \"50\" -> 50\n *\n * Scenario: Value Replacement\n * - Extracted: `<Component variant=\"flat\" />`\n * - Schema: `variant=\"solid\"`\n * - Action: UPDATE \"flat\" -> \"solid\"\n *\n * 3.2. CREATE (\"Injection\")\n * --------------------\n * - Definition: The schema defines a key that is absent in the extracted props.\n * - Policy: IGNORED.\n * - Reasoning: Structural insertion is unsafe due to Spread ambiguity.\n * See {@link LeafOnlyPatchingConstraint} (Injection).\n *\n * Scenario: Schema Defaults\n * - Extracted: `<Component label=\"Submit\" />` ('disabled' prop missing)\n * - Schema: `disabled=false` (Default injected by Schema)\n * - Action: IGNORE. Defaults must be applied by the runtime component.\n *\n * 3.3. REMOVE (\"Stripping\")\n * --------------------\n * - Definition: The extracted props contain a key that is absent in the schema.\n * - Policy: IGNORED.\n * - Reasoning: Schema cannot delete Passthrough Props.\n * See {@link LeafOnlyPatchingConstraint} (Stripping).\n *\n * Scenario: Passthrough Props\n * - Extracted: `<Component label=\"Submit\" className=\"sticky-header\" />`\n * - Schema: Defines `label` only (Validator strips unknown keys)\n * - Result: Validated Props is `{ label: \"Submit\" }` (`className` removed)\n * - Action: IGNORE (Preserve `className`).\n *\n * @param extractedProps - Raw extracted static props.\n * @param validatedProps - Schema-validated props.\n * @param preservedKeys - Protected runtime keys.\n * @returns Coercion patches (CHANGE only).\n */\nexport function calculatePatches(\n extractedProps: unknown,\n validatedProps: unknown,\n preservedKeys: ReadonlySet<string>\n): SetPropertyPatch[] {\n // 1. Structural Integrity Check.\n if (!isPlainObject(extractedProps) || !isPlainObject(validatedProps)) {\n return [];\n }\n\n // 2.1 Target Construction: Apply Overlay Strategy.\n const diffTarget = applyOverlay(\n extractedProps,\n validatedProps,\n preservedKeys\n );\n\n // 2.2 Change Detection: Apply Diff Strategy.\n const difference = diff(extractedProps, diffTarget);\n\n const patches: SetPropertyPatch[] = [];\n\n for (const entry of difference) {\n // 3.1. Handle CHANGE (Coercion)\n if (entry.type === 'CHANGE') {\n patches.push({\n operation: 'set',\n path: entry.path,\n value: entry.value\n });\n continue;\n }\n\n // 3.2. Handle CREATE (Injection)\n if (entry.type === 'CREATE') {\n continue;\n }\n\n // 3.3. Handle REMOVE (Stripping)\n if (entry.type === 'REMOVE') {\n continue;\n }\n }\n\n return patches;\n}\n","/**\n * Represents a successful static resolution.\n *\n * Meaning:\n * - The input node was statically resolvable under the current resolver allowlist.\n * - The returned `value` is what the node **evaluates to** under JavaScript\n * evaluation rules (i.e., a compile-time simulation of runtime semantics).\n *\n * Usage:\n * - Consumers should branch on `result.success`.\n * - When `success: true`, `value` is available and should be treated as the\n * node's evaluated constant.\n */\nexport type StaticSuccess<T> = {\n /**\n * Discriminant flag indicating the resolution succeeded.\n */\n success: true;\n\n /**\n * The value the node evaluates to (static evaluation result).\n *\n * Note:\n * This may legitimately be `undefined`; this is distinct from failure\n * (`success: false`).\n */\n value: T;\n};\n\n/**\n * Represents a failed static resolution.\n *\n * Meaning:\n * - The input node could not be resolved to a static evaluated value under the\n * current resolver allowlist (e.g., dynamic identifiers, function calls,\n * unsupported operators, etc.).\n *\n * Contract:\n * - Failure carries no value payload.\n * - Callers should treat this as \"dynamic / unresolvable\" and apply their\n * container policy (omit key, bail out, etc.).\n */\nexport type StaticFailure = {\n /**\n * Discriminant flag indicating the resolution failed.\n */\n success: false;\n};\n\n/**\n * Discriminated union representing the outcome of a static resolution attempt.\n *\n * Pattern:\n * - `success: true` => an evaluated value is available (`StaticSuccess<T>`)\n * - `success: false` => resolution failed (`StaticFailure`)\n *\n * Rationale:\n * This pattern cleanly distinguishes:\n * - \"evaluates to undefined\" (success with `value === undefined`)\n * from:\n * - \"could not resolve\" (failure)\n */\nexport type StaticResult<T = unknown> = StaticSuccess<T> | StaticFailure;\n\n/**\n * Canonical failure sentinel for \"unresolvable\".\n *\n * Notes:\n * - Shared sentinel avoids repeated object allocation at failure sites.\n * - Typed as `StaticFailure` to preserve the discriminant precisely.\n */\nexport const UNRESOLVED: StaticFailure = { success: false } as const;\n\n/**\n * Constructs a successful static resolution result.\n *\n * @param value\n * The evaluated value to wrap (result of static evaluation).\n * @returns\n * A {@link StaticSuccess} wrapper containing `value`.\n */\nexport function resolved<T>(value: T): StaticSuccess<T> {\n return { success: true, value };\n}\n\n/**\n * Internal control sentinel for static extraction.\n *\n * Semantics:\n * Represents a \"Non-static\" signal within the recursion engine.\n * It indicates that a subtree does not match the definitions in\n * {@link StaticDataPatterns} and cannot be decoded into a static value.\n *\n * Architecture:\n * When extraction cannot produce a deterministic value, the extractor returns\n * this sentinel to signal that the subtree is non-static.\n *\n * Call sites handle this signal based on their context:\n *\n * 1. Recursive Containers (Internal):\n * - Arrays: Reject the entire array (Strict Policy).\n * - Objects: Omit the specific property (Partial Policy).\n *\n * 2. Root Boundary (External):\n * - Treat the result as non-extractable (return `null` or `undefined`).\n *\n * Implementation Strategy:\n * Uses `Symbol.for` to ensure global identity.\n * This guarantees that the signal returned by the recursion engine matches the\n * check performed by adapters (like `extractStaticProps`), even if they are\n * loaded from duplicate module instances (\"Dual Package\" hazard).\n *\n * Contract:\n * - Internal: Used strictly for recursion control.\n * - Public: Must NEVER leak into the final data model.\n */\nexport const SKIP_VALUE = Symbol.for('recma.extraction.skip');\n","import { is, types } from 'estree-toolkit';\nimport { type StaticResult, UNRESOLVED, resolved } from './constants';\n\n/**\n * Resolves atomic values from ESTree `Literal` nodes.\n *\n * Supported Types:\n * - Primitives: `string`, `number`, `boolean`, `bigint`.\n * - Special Literals: `null`, `RegExp`.\n *\n * ---\n *\n * Architectural Note:\n * Why are Objects handled in a \"Literal\" resolver?\n *\n * Structural containers like `ObjectExpression` (`{}`) are handled via\n * recursion in the main loop. In contrast, this function handles specific\n * *atomic tokens* that present a unique combination of traits:\n * 1. They parse as `Literal` nodes (atomic leaves).\n * 2. They evaluate to `typeof === 'object'` at runtime.\n *\n * Case Breakdown:\n * A. `null` (The Null Literal)\n * - Code: `const x = null;`\n * - AST: `{ type: \"Literal\", value: null }`\n * - Reason: Syntactically atomic.\n * 1. It is a single token, not a structure.\n * 2. In JS, `typeof null === 'object'` is a known legacy quirk.\n * 3. It is a standard static primitive value.\n *\n * B. `RegExp` (The Regex Literal)\n * - Code: `const x = /abc/g;`\n * - AST: `{ type: \"Literal\", value: <RegExp Object>, regex: { pattern: \"abc\", flags: \"g\" } }`\n * - Reason: Syntactic Sugar.\n * 1. The parser sees `/.../` syntax and marks it as type `Literal`.\n * 2. The parser automatically instantiates a `RegExp` object\n * and attaches it to `node.value`.\n * 3. Thus, `node.value` is an instance of `RegExp` despite the\n * node not being a `NewExpression`.\n *\n * C. `Date` (Exclusion)\n * - Code: `const x = new Date();`\n * - AST: `{ type: \"NewExpression\", callee: { name: \"Date\" } }`\n * - Reason: No Literal Syntax.\n * 1. JavaScript has no \"Date Literal\" syntax.\n * 2. Dates are always created via constructors (`new ...`).\n * 3. They appear as `NewExpression` nodes, never as `Literal` nodes,\n * so this function never encounters them.\n *\n * @param node\n * The AST node to inspect.\n * @returns\n * A `StaticResult`:\n * - `success: true` when `node` is a supported `Literal` form\n * - `success: false` otherwise\n */\nfunction tryResolveLiteral(node: types.Node): StaticResult {\n if (is.literal(node)) {\n // Access the native JavaScript value pre-evaluated by the parser.\n // (e.g., a real BigInt, RegExp instance, or primitive).\n switch (typeof node.value) {\n case 'string':\n case 'number':\n case 'boolean':\n case 'bigint':\n return resolved(node.value);\n\n case 'object':\n // Case A: Null\n if (node.value === null) {\n return resolved(null);\n }\n // Case B: RegExp\n if (node.value instanceof RegExp) {\n return resolved(node.value);\n }\n break;\n }\n }\n return UNRESOLVED;\n}\n\n/**\n * Resolves values from ESTree `Identifier` nodes that represent global constants.\n *\n * Supported Values:\n * - `undefined`, `NaN`, `Infinity`.\n *\n * ---\n *\n * 1. Architectural Note: Constant Folding\n * Although `undefined`, `NaN`, and `Infinity` are syntactically Identifiers\n * (variable names), static analysis treats them as Constants.\n *\n * - Syntax:\n * `const x = undefined;` -> AST: `{ type: \"Identifier\", name: \"undefined\" }`\n *\n * - Context:\n * Unlike `null` (a keyword), these are technically global variables.\n *\n * Rationale: Primitive Resolution & Syntactic Unification\n * Mapping these identifier names to their underlying runtime values allows\n * the system to treat different syntactic forms as equivalent.\n *\n * Principle: Semantic Equivalence\n * JavaScript often allows multiple syntactic forms for the same value.\n * Resolving the runtime value rather than preserving the AST structure\n * ensures that distinct source patterns produce identical data.\n *\n * Example: Unifying `undefined`\n * 1. Identifier Form: `undefined` (Handled here).\n * 2. Unary Form: `void 0` (Requires Unary support).\n *\n * Both forms evaluate to the primitive `undefined`.\n * Although this function currently only handles the Identifier form, the\n * architecture is designed to unify these into the same constant once Unary\n * expression support is enabled in the future.\n *\n * 2. Usage Symmetry (Positional Equivalence)\n * The principle of equivalence extends to **Syntactic Position**.\n * This function resolves based strictly on the Node Type (`Identifier`) and\n * ignores the grammatical context (e.g., Key vs. Value).\n * This ensures identical output for the same constant regardless of where it\n * appears in the structure.\n *\n * Scenario A: As a Value\n * - Code: `{ offset: NaN }`\n * - AST:\n * ```json\n * {\n * \"type\": \"Property\",\n * \"value\": { // <--- Position: Value\n * \"type\": \"Identifier\", // <--- Input Node (Passed to function)\n * \"name\": \"NaN\" // <--- Checked Name\n * }\n * }\n * ```\n * - Result: Returns the number `NaN`.\n *\n * Scenario B: As a Key (Computed Property)\n * - Code: `{ [NaN]: \"data\" }`\n * - AST:\n * ```json\n * {\n * \"type\": \"Property\",\n * \"key\": { // <--- Position: Key\n * \"type\": \"Identifier\", // <--- Input Node (Passed to function)\n * \"name\": \"NaN\" // <--- Checked Name\n * },\n * \"value\": { \"value\": \"data\" }\n * }\n * ```\n * - Result: Returns the number `NaN`.\n *\n * @param node\n * The AST node to inspect.\n * @returns\n * A `StaticResult`:\n * - `success: true` when `node` is a supported global-constant identifier\n * - `success: false` otherwise\n */\nfunction tryResolveIdentifier(node: types.Node): StaticResult {\n if (is.identifier(node)) {\n // Switch on `node.name` (the variable name).\n // Unlike Literals (which store data in `.value`), Identifiers store\n // the label they refer to in the `.name` property.\n switch (node.name) {\n case 'undefined':\n return resolved(undefined);\n case 'NaN':\n return resolved(NaN);\n case 'Infinity':\n return resolved(Infinity);\n }\n }\n return UNRESOLVED;\n}\n\n/**\n * Resolves static template strings by stitching together text and static\n * values.\n *\n * ---\n *\n * 1. AST Structure (The \"Bookend\" Rule)\n * A Template Literal always starts and ends with a Quasi (static text).\n * The parser enforces a strict alternating structure:\n * [Quasi] -> [Expr] -> [Quasi].\n *\n * If a template ends with an expression (e.g., `${x}`), the parser must\n * insert an empty string Quasi at the end (\"\") to close the structure.\n * This guarantees that Quasis.length === Expressions.length + 1.\n *\n * 2. Algorithmic Strategy (The \"Zipper\" Pattern)\n * Iterating over `quasis` (instead of `expressions`) ensures the structural\n * frame is respected. This covers every node in order, including the \"Tail\"\n * (the final text part) which has no following expression.\n *\n * 3. Implementation Details\n * [A] Safety: Invalid Escape Sequences\n * The `cooked` property represents the interpreted string value, whereas\n * `raw` represents the source text with escape sequences preserved.\n * - Requirement:\n * Resolution must use `cooked` to capture the actual runtime string.\n * Example: `Line\\nBreak`\n * - `cooked`: \"Line\\nBreak\" (Contains actual newline character).\n * - `raw`: \"Line\\\\nBreak\" (Contains literal backslash and 'n').\n * - Safety:\n * In ES2018+, templates can contain invalid escapes (e.g., `\\u` without digits).\n * In such cases, `cooked` is undefined. If the string cannot be interpreted,\n * resolution is considered failed.\n *\n * [B] Recursion & Value Resolution\n * To handle the interpolation `${...}`, the logic delegates to the\n * Master Dispatcher (`tryResolveStaticValue`).\n * Important:\n * Its specific role here is to resolve the *Expression Node* into a\n * concrete *Static Value*. *\n * - Recursion:\n * This allows for nested templates (e.g., `${ `inner` }`).\n * - Dynamics (All-or-Nothing):\n * If a single interpolation fails resolution (e.g., runtime props,\n * function calls, or unsupported operators like `${1+1}`), the entire\n * template is rejected. Partial resolution is not possible.\n *\n * [C] Spec Compliance: Stringification\n * Explicit string conversion (via `${}`) is required before adding values to the\n * accumulator array.\n * - Reason: `Array.prototype.join('')` converts null/undefined to empty strings (\"\").\n * - Requirement: Template literals must convert them to string representations\n * (\"null\", \"undefined\").\n *\n * ---\n *\n * Examples\n *\n * 1. Standard Interpolation\n * - Code: `v${ 1 }.${ 0 }`\n * - Quasis: [ \"v\", \".\", \"\" ]\n * -> The empty tail closes the template after `${0}`\n * - Exprs: [ 1, 0 ]\n * - Logic: \"v\" + String(1) + \".\" + String(0) + \"\" -> \"v1.0\"\n *\n * 2. Nested Template (Recursion)\n * - Code: `group-${ `item-${ 100 }` }-active`\n *\n * Outer Node:\n * - Quasis: [ \"group-\", \"-active\" ]\n * -> Ends with text \"-active\", so no empty tail needed\n * - Exprs: [ TemplateLiteral (Inner) ]\n *\n * Inner Node:\n * - Quasis: [ \"item-\", \"\" ]\n * -> Ends with `${100}`, so empty tail required\n * - Exprs: [ 100 ]\n *\n * Logic Flow:\n * 1. Outer Loop 0: Push \"group-\"\n * 2. Outer Expr 0: Recurse into Inner Template...\n * a. Inner Loop 0: Push \"item-\"\n * b. Inner Expr 0: Resolve 100 -> Push \"100\"\n * c. Inner Loop 1: Push \"\" (Tail)\n * -> Return \"item-100\"\n * 3. Outer Loop 1: Push \"-active\"\n * -> Result: \"group-item-100-active\"\n *\n * @param node\n * The AST node to inspect.\n * @returns\n * A `StaticResult`:\n * - `success: true` when the template and all interpolations are statically resolvable\n * - `success: false` otherwise\n */\nfunction tryResolveTemplate(node: types.Node): StaticResult {\n if (is.templateLiteral(node)) {\n const parts: string[] = [];\n\n // Iterates over Quasis to frame the structure\n // See [2] Algorithmic Strategy\n for (const [index, quasi] of node.quasis.entries()) {\n // Step 1: Resolve Quasi (The Static Text)\n // See [A] Safety: Invalid Escape Sequences.\n const text = quasi.value.cooked;\n if (typeof text !== 'string') return UNRESOLVED;\n\n parts.push(text);\n\n // Step 2: Resolve Expression (The Interpolation `${...}`)\n // Loop runs N+1 times (Quasis); this block runs N times (Expressions).\n if (index < node.expressions.length) {\n // See [B] Recursion & Value Resolution\n const exprResult = tryResolveStaticValue(node.expressions[index]);\n\n if (!exprResult.success) return UNRESOLVED;\n\n // See [C] Spec Compliance: Stringification\n parts.push(`${exprResult.value}`);\n }\n }\n\n return resolved(parts.join(''));\n }\n return UNRESOLVED;\n}\n\n/**\n * Master Dispatcher: Static Value Resolution\n *\n * Orchestrates the resolution of AST nodes into atomic static values.\n *\n * ---\n *\n * 1. Scope: Strictly Declarative Data\n * This function resolves AST nodes that represent atomic static constants\n * explicitly defined in the source code. It covers primitives, global\n * constants, and deterministic string composition.\n *\n * 2. Implementation Limits (Deferred Support)\n * While strictly static and deterministic, the following operations are\n * currently excluded to maintain implementation simplicity.\n * They will return UNRESOLVED until support is added:\n *\n * - Unary Operators: Math/Logic on scalars (e.g., `-1`, `!true`, `void 0`)\n * - Binary Operators: Arithmetic (e.g., `1 + 1`)\n * - Logical Operators: Short-circuiting (e.g., `true || \"default\"`, `null ?? \"val\"`)\n * - Conditional Logic: Ternary operators (e.g., `true ? \"a\" : \"b\"`)\n * - Sequence Expressions: Comma operators (e.g., `(0, 10)`)\n *\n * @param node\n * The AST node to inspect.\n * @returns\n * A `StaticResult`:\n * - `success: true` with the value the node evaluates to when a resolution strategy succeeds\n * - `success: false` otherwise\n */\nexport function tryResolveStaticValue(node: types.Node): StaticResult {\n let result: StaticResult;\n\n // 1. Atomic Constants\n if ((result = tryResolveLiteral(node)).success) return result;\n if ((result = tryResolveIdentifier(node)).success) return result;\n\n // 2. String Interpolation\n if ((result = tryResolveTemplate(node)).success) return result;\n\n // 3. Fallback\n // The node did not qualify for any supported static strategy.\n // It is treated as dynamic (unresolvable).\n //\n // This catches:\n // - Runtime Dynamics (Variables, Function Calls, Member Access).\n // - Deferred Static Logic (see Section 2: Implementation Limits).\n return UNRESOLVED;\n}\n","import { is, types } from 'estree-toolkit';\nimport { tryResolveStaticValue } from './static-resolver';\n\n/**\n * Extracts the static name from a property key when it is defined as a\n * non-computed Identifier.\n *\n * ---\n *\n * 1. Concept: Labels vs. References\n * In JavaScript objects, an Identifier in the key position acts as a\n * Static Label (string), not a Variable Reference.\n *\n * 2. Scenarios\n *\n * Scenario A: Static Label (Handled)\n * - Code: `{ myVar: 1 }`\n * - AST:\n * ```json\n * {\n * \"type\": \"Property\",\n * \"computed\": false, // <--- Switch: Label Mode\n * \"key\": {\n * \"type\": \"Identifier\",\n * \"name\": \"myVar\" // <--- Extracted Name\n * }\n * }\n * ```\n * - Logic: Since `computed` is false, the identifier represents the literal\n * string \"myVar\", independent of any variable scope.\n * - Result: Returns \"myVar\".\n *\n * Scenario B: Variable Reference (Rejected)\n * - Code: `{ [myVar]: 1 }`\n * - AST:\n * ```json\n * {\n * \"type\": \"Property\",\n * \"computed\": true, // <--- Switch: Expression Mode\n * \"key\": {\n * \"type\": \"Identifier\",\n * \"name\": \"myVar\"\n * }\n * }\n * ```\n * - Logic: Since `computed` is true, this is a variable lookup.\n * This function steps aside to allow the Static Resolver to\n * evaluate it.\n * - Result: Returns null.\n * - Outcome: The node falls through to the Static Resolver, which attempts\n * to resolve `myVar`.\n * It fails (because `myVar` is dynamic), and the property is\n * correctly skipped.\n *\n * 3. Architectural Necessity (The Syntax Filter)\n * This function acts as a filter to prevent the Static Resolver from incorrectly\n * evaluating labels as variables.\n *\n * - Context:\n * The Static Resolver (`tryResolveStaticValue`) determines what a node\n * *evaluates to* (simulating runtime behavior).\n * It treats every Identifier as a Variable Reference to be looked up.\n *\n * - The Conflict:\n * If the key from `{ myVar: 1 }` is passed to the resolver:\n * 1. The resolver interprets `myVar` as a Variable Reference.\n * 2. It attempts to look up the value (checking global constants).\n * 3. It fails (since `myVar` is not a constant) and rejects the valid static key.\n *\n * - The Solution:\n * By filtering for `computed: false`, this helper captures Static Labels\n * immediately based on syntax.\n * -> This bypasses the expression evaluation logic entirely for static named keys.\n *\n * 4. Filtering Logic & Distinction\n * This function enforces strict syntactic rules to isolate Labels (Syntax)\n * from Values (Data).\n *\n * - Filter 1: `!computed`\n * Rejects variable references (e.g., `{ [key]: ... }`). These belong to the\n * Data Path (`tryResolveStaticValue`) for resolution.\n *\n * - Filter 2: `is.identifier`\n * - Accepts: Identifiers (e.g., `{ key: ... }`).\n * - Rejects: Literals (e.g., `{ \"key\": ... }`).\n *\n * Distinction:\n * - An Identifier (`key`) is a Name (Syntax). It belongs here.\n * - A Literal (`\"key\"`) is a Value (Data).\n * -> All Values must be handled by the Static Resolver.\n *\n * @param property\n * The property node to inspect.\n * @returns\n * The identifier name string if the key acts as a static label; otherwise null.\n */\nfunction tryExtractNamedKey(property: types.Property): string | null {\n if (!property.computed && is.identifier(property.key)) {\n return property.key.name;\n }\n return null;\n}\n\n/**\n * Extracts the key name from an Object Property.\n *\n * ---\n *\n * 1. Objective: Static Key Determination\n * The primary goal is to determine the key (property name) of an object\n * property so it can be uniquely addressed within the extracted data model.\n *\n * - Role: Determines the **Key Node**'s static address (`string` or `number`).\n * This address is required to construct the property path *before* the\n * main recursive engine descends into the **Value Node**.\n * - Output: Returns a valid path segment if the key is static and addressable.\n * Returns `null` if the key is dynamic or not addressable.\n *\n * 2. Architectural Pathways: Syntax vs. Data\n * The extraction logic chooses a strategy based on whether the key acts as a\n * syntactic label (unique to keys) or as an expression (shared with values).\n *\n * [A] Pathway: Syntax (Key-Specific Labels)\n * Handled by `tryExtractNamedKey`.\n * - Logic: This strategy is **unique to the Key position**.\n * - Rule: It respects the grammar rule where a non-computed Identifier\n * acts as a string label (e.g., `{ a: 1 }` -> \"a\").\n * - Context Constraint:\n * This logic must never be applied to a Value node. For example, in\n * `{ p: a }`, applying this logic would incorrectly treat the variable\n * `a` as the string literal \"a\".\n *\n * [B] Pathway: Data (Universal Resolution)\n * Handled by `tryResolveStaticValue`.\n * - Logic: This strategy is **universal (shared with Values)**.\n * - Rule: It applies when the key is Computed or a Literal (e.g., `{ [NaN]: 1 }`).\n * The node is treated exactly like a Value expression.\n * - Consistency Guarantee:\n * By using the shared resolver, the system ensures that static constants\n * (like `NaN` or template strings) resolve identically regardless of\n * whether they appear on the left (Key) or right (Value) side of the colon.\n *\n * 3. Context: The Extraction Lifecycle\n * This function represents Step A of the property processing cycle.\n * The Main Loop decomposes properties into two distinct operations.\n *\n * 3.1 Syntax Path (Static Labels)\n *\n * Trace 1: Standard Property `{ a: \"b\" }`\n *\n * [Level 1] Property Context\n * - Step A (Key - Syntax Path): `extractPropertyKey` calls `tryExtractNamedKey`.\n * -> Extracts name `\"a\"` from Identifier.\n * < RETURN: \"a\" (Control returns to Main Loop)\n *\n * - Step B (Value - Caller): Value is Literal `\"b\"`. Must Recurse.\n * > ENTER Level 2: `extractStaticValueFromExpression(\"b\")`\n *\n * [Level 2] Atomic Value Resolution\n * - Logic: Node is a leaf (Atomic). Recursion stops.\n * - Action: Calls `tryResolveStaticValue`.\n * -> Resolves Literal `\"b\"` -> `\"b\"`.\n * < EXIT Level 2: Returns `\"b\"`.\n *\n * - Resume Level 1: Capture return value `\"b\"`.\n * - Step C (Assign - Caller): `result[\"a\"] = \"b\"`.\n * < EXIT Level 1: Loop Continues / Returns Result.\n *\n * 3.2 Data Path (Resolved Keys)\n *\n * Trace 2: Flat Object `{ [NaN]: \"b\" }`\n *\n * [Level 1] Property Context\n * - Step A (Key - Data Path): `extractPropertyKey` calls `tryResolveStaticValue`.\n * -> Resolves Key Node `[NaN]` -> Number `NaN`.\n * < RETURN: NaN (Control returns to Main Loop)\n *\n * - Step B (Value - Caller): Value is Literal `\"b\"`. Must Recurse.\n * > ENTER Level 2: `extractStaticValueFromExpression(\"b\")`\n *\n * [Level 2] Atomic Value Resolution\n * - Logic: Node is a leaf (Atomic). Recursion stops.\n * - Action: Calls `tryResolveStaticValue`.\n * -> Resolves Literal `\"b\"` -> `\"b\"`.\n * < EXIT Level 2: Returns `\"b\"`.\n *\n * - Resume Level 1: Capture return value `\"b\"`.\n * - Step C (Assign - Caller): `result[NaN] = \"b\"`.\n * < EXIT Level 1: Loop Continues / Returns Result.\n *\n * ---\n *\n * Trace 3: Nested Object `{ [NaN]: { b: 4 } }`\n *\n * [Level 1] Outer Property Context\n * - Step A (Key - Data Path): `extractPropertyKey` calls `tryResolveStaticValue`.\n * -> Resolves Key Node `[NaN]` -> Number `NaN`.\n * < RETURN: NaN (Control returns to Main Loop)\n *\n * - Step B (Value - Caller): Value is Object `{ b: 4 }`. Must Recurse.\n * > ENTER Level 2: `extractStaticValueFromExpression({ b: 4 })`\n *\n * [Level 2] Inner Property Context\n * - Step A (Key - Syntax Path): `extractPropertyKey` calls `tryExtractNamedKey`.\n * -> Extracts name `\"b\"` from Identifier.\n * < RETURN: \"b\" (Control returns to Main Loop)\n *\n * - Step B (Value - Caller): Value is Literal `4`. Must Recurse.\n * > ENTER Level 3: `extractStaticValueFromExpression(4)`\n *\n * [Level 3] Atomic Value Resolution\n * - Logic: Node is a leaf (Atomic). Recursion stops.\n * - Action: Calls `tryResolveStaticValue`.\n * -> Resolves Literal `4` -> `4`.\n * < EXIT Level 3: Returns `4`.\n *\n * - Resume Level 2: Capture return value `4`.\n * - Step C (Inner Assign - Caller): `innerResult[\"b\"] = 4`.\n * < EXIT Level 2: Returns `{ b: 4 }`.\n *\n * - Resume Level 1: Capture return value `{ b: 4 }`.\n * - Step C (Outer Assign - Caller): `result[NaN] = { b: 4 }`.\n * < EXIT Level 1: Loop Continues / Returns Result.\n *\n * 4. Implementation Details\n * [A] Static Named Keys (Syntax)\n * If non-computed Identifier, extracts name directly.\n * Example: `{ a: ... }` -> Key is \"a\".\n *\n * [B] Data Resolution\n * If the key is a Literal or a Computed Expression, it represents data.\n * The logic delegates to the Static Resolver (`tryResolveStaticValue`) to\n * resolve the static value of the key node.\n * Examples:\n * - Literal: { \"a\": ... } -> Key is \"a\".\n * - Computed: { [\"a\"]: ... } -> Key is \"a\".\n * - Computed: { [1]: ... } -> Key is 1.\n * - Computed: { [NaN]: ... } -> Key is NaN.\n * - Computed (Template): { [`id-${1}`]: ... } -> Key is \"id-1\".\n *\n * [C] Key Type Constraints (Strict Validation)\n * The resolved value is strictly validated against an allowlist of types.\n * \n * 1. `string`\n * - Example: `\"title\"`, `\"data-id\"`\n * - Action: Accepted.\n * - Result: Used for standard Dot Notation paths (e.g., `props.title`).\n\n * 2. `number`\n * - Example: `0`, `1`, `NaN`\n * - Action: Accepted (Preserved as numeric primitive).\n * - Result: Used for Bracket Notation paths (e.g., `props[0]`, `props[NaN]`).\n * Note: Brackets are mandatory for integers (`props.0` is invalid),\n * so this formatting is enforced for all numeric types for consistency.\n *\n * 3. `symbol`\n * - Example: `Symbol('id')`\n * - Action: Rejected (Returns `null`).\n * - Reason: Structural Limitation. Symbols cannot be serialized to JSON\n * nor uniquely addressed in a static diagnostic string.\n *\n * 4. `null`, `undefined`, `boolean`, `bigint`\n * - Example: `null`, `true`, `1n`\n * - Action: Rejected (Returns `null`).\n * - Reason: Policy Rejection. Unlike the JS runtime (which coerces these\n * to strings), these types are treated as logic errors to\n * prevent polluting the output with unintended keys.\n * \n * [D] Policy Divergence (The Rationale for [C])\n * The constraints in [C] deliberately diverge from the JS Runtime to\n * ensure Data Safety.\n *\n * - Runtime Behavior: Implicit Coercion\n * JS automatically coerces non-string primitives used as computed keys.\n * e.g., `{ [null]: 1 }` -> `{ \"null\": 1 }`\n *\n * - Extractor Behavior: Strict Rejection\n * This extractor explicitly rejects these types (returning `null`).\n * Rationale: In static analysis, a key resolving to `null` or `undefined`\n * usually indicates a logic error or unresolved variable. Omission is\n * safer than polluting the output model with garbage keys.\n *\n * @param property\n * The property node to inspect.\n * @returns\n * A valid path segment (`string` or `number`) if the key is statically\n * addressable; otherwise `null`.\n */\nexport function extractPropertyKey(\n property: types.Property\n): string | number | null {\n // [A] Static Named Keys (Syntax)\n const namedKey = tryExtractNamedKey(property);\n if (namedKey !== null) {\n return namedKey;\n }\n\n // [B] Data Resolution\n const resolution = tryResolveStaticValue(property.key);\n\n if (resolution.success) {\n const resolvedValue = resolution.value;\n\n // [C] Key Type Constraints\n // See Section [D] \"Policy Divergence\" in JSDoc for rationale.\n if (\n typeof resolvedValue === 'string' ||\n typeof resolvedValue === 'number'\n ) {\n return resolvedValue;\n }\n }\n\n // Dynamic Key, Symbol, or Unsupported\n return null;\n}\n","import { types } from 'estree-toolkit';\n\nimport type {\n ExpressionRefPlaceholder,\n PreservedSubtreeLifecycle\n} from './architecture';\n\nimport { isPropertyPath, isRecord } from './guards';\nimport { type PropertyPath } from './types';\n\n/**\n * Discriminant brand used to identify ExpressionRef objects.\n *\n * Implementation Strategy:\n *\n * 1. Mechanism: Global Identity\n * `Symbol.for('...')` registers the symbol in the global runtime registry.\n * This ensures that every call with the same key returns the exact same\n * primitive reference, regardless of where the code is executed within the\n * JavaScript environment.\n *\n * 2. The Hazard: \"Dual Package\" / Multiple Bundles\n * If standard `Symbol()` were used, it would create a strictly unique reference\n * every time the module is evaluated. In complex build setups, the library\n * might be loaded twice (e.g., once by the app, once by a plugin dependency):\n *\n * my-project/\n * node_modules/\n * my-library/ <-- Instance 1 (Evaluates Symbol A)\n * other-plugin/\n * node_modules/\n * my-library/ <-- Instance 2 (Evaluates Symbol B)\n *\n * In this scenario, `Symbol A !== Symbol B`. A type guard running in Instance 2\n * would fail to recognize data created by Instance 1.\n *\n * 3. Application: Extractor-Patcher Agreement\n * In this architecture, `ExpressionRef` objects are persistent data carriers\n * that bridge two distinct lifecycle phases:\n * - Creation: The Extractor produces these objects.\n * - Consumption: The Patcher consumes them (via type guards like `isExpressionRef`).\n * These phases often run in different contexts (e.g., distinct build steps or\n * bundle chunks). They must agree on the brand identity to successfully\n * hand off the preserved subtrees.\n *\n * 4. Naming Convention\n * The prefix `recma.preservation` indicates that this symbol underpins the\n * \"Preserved Subtree\" mechanism. This is a shared architectural concept\n * spanning both extraction and patching, rather than a utility scoped strictly\n * to the extractor.\n */\nconst EXPRESSION_REF_KIND = Symbol.for('recma.preservation.expression_ref');\n\n/**\n * Concrete implementation of the {@link ExpressionRefPlaceholder}.\n *\n * This value is carried through extraction/validation as plain data.\n * The actual ESTree expression is stored separately in the side channel.\n */\ntype ExpressionRef = {\n /**\n * Discriminant brand tag.\n * See {@link ExpressionRefPlaceholder} (Structure: Brand).\n */\n __kind: typeof EXPRESSION_REF_KIND;\n\n /**\n * Path to the preserved subtree within extracted props.\n * See {@link ExpressionRefPlaceholder} (Structure: Pointer).\n */\n path: PropertyPath;\n};\n\n/**\n * Resolves an {@link ExpressionRef} placeholder back into its original ESTree\n * expression.\n *\n * This implements the restoration step of the {@link PreservedSubtreeLifecycle}.\n * It retrieves the original runtime AST node from the \"Side Channel\" capture\n * map using the path stored in the placeholder.\n *\n * Returning `null` signals that the placeholder cannot be resolved, and patch\n * application should fail.\n *\n * @param ref\n * The placeholder identifying the location of the preserved subtree.\n * @returns\n * The original ESTree node to inline, or `null` if the reference is lost.\n */\nexport type ExpressionRefResolver = (\n ref: ExpressionRef\n) => types.Expression | null;\n\n/**\n * Creates an {@link ExpressionRef} placeholder for a preserved subtree at `path`.\n *\n * @param path\n * Path where the preserved expression is located (e.g. `[\"children\"]`, `[\"slots\", 0]`).\n * @returns\n * The placeholder object. Example structure:\n * `{ __kind: Symbol(recma.preservation.expression_ref), path: [\"children\"] }`\n */\nexport function createExpressionRef(path: PropertyPath): ExpressionRef {\n return { __kind: EXPRESSION_REF_KIND, path };\n}\n\n/**\n * Type guard for {@link ExpressionRef}.\n *\n * Checks if a value is a valid placeholder object by verifying the branded\n * `__kind` tag and the `path` structure.\n *\n * This is used during the **Patching** phase to detect placeholders that need\n * to be resolved back to AST nodes. See {@link PreservedSubtreeLifecycle}.\n *\n * @param value\n * Unknown value to test.\n * @returns\n * `true` if `value` is an `ExpressionRef`; otherwise `false`.\n */\nexport function isExpressionRef(value: unknown): value is ExpressionRef {\n if (!isRecord(value)) return false;\n\n // 1. Brand check\n if (value.__kind !== EXPRESSION_REF_KIND) return false;\n\n // 2. Shape check\n return isPropertyPath(value.path);\n}\n","/**\n * Ensures a sparse array preserves an elision (`,,`) at a specific slot index.\n *\n * Context\n * -------\n * ESTree encodes array elisions as `null` slots in `ArrayExpression.elements`.\n * In JavaScript, an elision is a *missing* element/property at a slot index,\n * which is observably different from an explicitly present element whose value\n * happens to be `undefined`.\n *\n * This distinction can be tested with the `in` operator:\n * - `slotIndex in array` checks whether the array has an own property for that index\n * (i.e. whether the element exists), not what its value is.\n *\n * Example:\n * const sparse = ['start', , 'end'];\n * const explicitUndefined = ['start', undefined, 'end'];\n *\n * sparse[1] === undefined; // true\n * explicitUndefined[1] === undefined; // true\n *\n * 1 in sparse; // false (slot index 1 is missing)\n * 1 in explicitUndefined; // true (slot index 1 is present)\n *\n * Preservation rule\n * -----------------\n * This helper increases `result.length` without assigning `result[slotIndex]`.\n * Extending `length` creates holes for any unassigned indices up to `slotIndex`,\n * keeping `slotIndex in result` false.\n *\n * @param result\n * Output array being constructed during extraction.\n * @param slotIndex\n * Slot index of the elision to preserve.\n */\nexport function preserveArrayElision(\n result: unknown[],\n slotIndex: number\n): void {\n // Extend the array to include `slotIndex` without writing an element.\n // This creates/keeps a hole at `slotIndex` (and any earlier unassigned slots).\n if (result.length < slotIndex + 1) result.length = slotIndex + 1;\n}\n\n/**\n * Returns `true` when a given array slot is an elision (a real sparse slot / “hole”).\n *\n * JavaScript distinction:\n * - An elision is a *missing* element/property at a slot index.\n * - This is different from an explicitly present element whose value is `undefined`.\n *\n * Detection:\n * - `slotIndex in array` checks whether the array has an own property for that index.\n * - For elisions, `slotIndex in array` is `false`.\n *\n * @param array\n * Array being encoded.\n * @param slotIndex\n * Slot index to test.\n */\nexport function isArrayElision(\n array: ReadonlyArray<unknown>,\n slotIndex: number\n): boolean {\n return !(slotIndex in array);\n}\n","export type Guard<T> = (value: unknown) => value is T;\n\n/**\n * Mapping of JavaScript `typeof` results to corresponding TypeScript types.\n * Used by the {@link is} factory.\n */\ntype PrimitiveTypeMap = {\n boolean: boolean;\n number: number;\n bigint: bigint;\n string: string;\n symbol: symbol;\n undefined: undefined;\n};\n\n/**\n * Creates a guard for a built-in primitive `typeof` check.\n *\n * @template T One of the keys of {@link PrimitiveTypeMap}.\n * @param type The primitive type keyword to compare against `typeof value`.\n * @returns A guard that returns `true` iff `typeof value === type`.\n */\nexport function is<T extends keyof PrimitiveTypeMap>(\n type: T\n): Guard<PrimitiveTypeMap[T]> {\n return (value: unknown): value is PrimitiveTypeMap[T] =>\n typeof value === type;\n}\n\n/** Guard verifying the value is a string. */\nexport const isString = is('string');\n\n/** Guard verifying the value is a number (including NaN/Infinity). */\nexport const isNumber = is('number');\n\n/** Guard verifying the value is a boolean. */\nexport const isBoolean = is('boolean');\n\n/** Guard verifying the value is a bigint. */\nexport const isBigInt = is('bigint');\n\n/** Guard verifying the value is a symbol. */\nexport const isSymbol = is('symbol');\n\n/** Guard verifying the value is undefined. */\nexport const isUndefined = is('undefined');\n\n/**\n * Guard verifying the value is `null`.\n *\n * Note:\n * `null` is a primitive value in JavaScript, but `typeof null === \"object\"` for\n * historical reasons, so it cannot be expressed via the `is(...)` factory.\n *\n * @param value\n * Candidate runtime value to test.\n * @returns\n * `true` iff {@link value} is exactly `null`.\n */\nexport function isNull(value: unknown): value is null {\n return value === null;\n}\n\n/**\n * Guard verifying the value is `NaN`.\n *\n * Note:\n * Uses `Number.isNaN` (no coercion), composed from {@link isNumber}.\n * This intentionally differs from the global `isNaN(...)`, which coerces inputs.\n *\n * @param value\n * Candidate runtime value to test.\n * @returns\n * `true` iff {@link value} is a number and is `NaN`.\n */\nexport function isNaNValue(value: unknown): value is number {\n return isNumber(value) && Number.isNaN(value);\n}\n\n/**\n * Guard verifying the value is a finite number.\n *\n * Semantics:\n * - true for: 0, 1, -1, 1.5, -0\n * - false for: NaN, Infinity, -Infinity, non-numbers\n *\n * @param value\n * Candidate runtime value to test.\n * @returns\n * `true` iff {@link value} is a number and is finite.\n */\nexport function isFiniteValue(value: unknown): value is number {\n return isNumber(value) && Number.isFinite(value);\n}\n\n/**\n * Guard verifying the value is `Infinity`.\n *\n * Note:\n * `Infinity` is a number value (`typeof Infinity === \"number\"`), so this is a\n * specialized refinement of {@link isNumber}.\n *\n * @param value\n * Candidate runtime value to test.\n * @returns\n * `true` iff {@link value} is exactly `Infinity`.\n */\nexport function isInfinityValue(value: unknown): value is number {\n return isNumber(value) && value === Infinity;\n}\n\n/**\n * Guard verifying the value is `-Infinity`.\n *\n * Note:\n * `-Infinity` is a number value (`typeof -Infinity === \"number\"`), so this is a\n * specialized refinement of {@link isNumber}.\n *\n * @param value\n * Candidate runtime value to test.\n * @returns\n * `true` iff {@link value} is exactly `-Infinity`.\n */\nexport function isNegativeInfinityValue(value: unknown): value is number {\n return isNumber(value) && value === -Infinity;\n}\n\n/**\n * Guard verifying the value is `-0`.\n *\n * Why `Object.is`:\n * JavaScript equality cannot distinguish `-0` from `0`:\n * - `-0 === 0` is true\n * - `-0 == 0` is true\n *\n * `Object.is` can distinguish them:\n * - `Object.is(-0, 0)` is false\n * - `Object.is(-0, -0)` is true\n * - `Object.is(0, 0)` is true\n *\n * Note:\n * This is composed from {@link isNumber} so the guard only claims `number`\n * when the runtime type is actually `number`.\n *\n * @param value\n * Candidate runtime value to test.\n * @returns\n * `true` iff {@link value} is a number and is exactly `-0`.\n */\nexport function isNegativeZeroValue(value: unknown): value is number {\n return isNumber(value) && Object.is(value, -0);\n}\n\n/**\n * Map for complex runtime categories to concrete TypeScript types.\n */\ntype ComplexTypeMap = {\n object: Record<string, unknown>;\n function: (...args: unknown[]) => unknown;\n array: unknown[];\n};\n\n/**\n * Creates a guard verifying the given value matches a complex runtime category.\n *\n * Notes:\n * - `\"object\"` excludes `null` and arrays.\n * - `\"array\"` uses `Array.isArray`.\n * - `\"function\"` uses `typeof === \"function\"`.\n */\nexport function isComplex<T extends keyof ComplexTypeMap>(\n type: T\n): Guard<ComplexTypeMap[T]> {\n return (value: unknown): value is ComplexTypeMap[T] => {\n if (value === null) return false;\n\n if (type === 'array') {\n return Array.isArray(value);\n }\n\n if (type === 'object') {\n return typeof value === 'object' && !Array.isArray(value);\n }\n\n if (type === 'function') {\n return typeof value === 'function';\n }\n\n return false;\n };\n}\n\n/** Guard verifying the value is a non-null object (excluding arrays). */\nexport const isObject = isComplex('object');\n\n/** Guard verifying the value is a function. */\nexport const isFunction = isComplex('function');\n\n/** Guard verifying the value is an array. */\nexport const isArray = isComplex('array');\n\n/**\n * Creates a guard verifying the value is an array whose elements all satisfy `elementGuard`.\n *\n * @param elementGuard\n * Guard used to validate each element.\n * @returns\n * A guard that narrows to `T[]` when the input is an array and every element passes.\n */\nexport function isArrayOf<T>(elementGuard: Guard<T>): Guard<T[]> {\n return (value: unknown): value is T[] =>\n isArray(value) && value.every(elementGuard);\n}\n\n/**\n * Creates a guard verifying the value is an object whose values all satisfy `valueGuard`.\n *\n * Notes:\n * - This validates enumerable own-property values via `Object.values(...)`.\n * - Keys are not validated; only value shapes are constrained.\n *\n * @param valueGuard\n * Guard used to validate each object value.\n * @returns\n * A guard that narrows to `Record<string, T>` when the input is a non-null\n * non-array object and every value passes.\n */\nexport function isObjectOf<T>(valueGuard: Guard<T>): Guard<Record<string, T>> {\n return (value: unknown): value is Record<string, T> =>\n isObject(value) && Object.values(value).every(valueGuard);\n}\n","import type { PropertyPath } from '../types';\nimport {\n isInfinityValue,\n isNaNValue,\n isNegativeInfinityValue,\n isNegativeZeroValue,\n isNumber\n} from './type-guards';\n\n/**\n * PropertyPath segments are the only units that participate in patch indexing.\n * Keep this narrow and strict: a segment is either a string key or a numeric index/key.\n */\nexport type PropertyPathSegment = string | number;\n\n/**\n * Canonicalizing PropertyPath for stable indexing\n * -----------------------------------------------\n * Patch planning and patch application must agree on a canonical, comparable key\n * for a logical {@link PropertyPath} (e.g. `[\"items\", 0, \"id\"]`).\n *\n * The implementation uses {@link JSON.stringify} as the canonical key encoding.\n * However, JSON has a lossy edge case: it cannot represent non-finite numbers.\n *\n * Examples (lossy):\n * - `JSON.stringify([NaN])` -> `\"[null]\"`\n * - `JSON.stringify([Infinity])` -> `\"[null]\"`\n * - `JSON.stringify([-Infinity])` -> `\"[null]\"`\n *\n * If a path segment is ever a non-finite number (whether produced by the static\n * resolver, introduced by future resolver expansions, or supplied externally),\n * that lossiness can cause collisions in Map/Set indexing.\n *\n * This module prevents that by canonicalizing such segments into stable string\n * tokens before stringification, while keeping finite numbers as numbers.\n *\n * Provenance visibility:\n * Canonicalization is split into stages (Identifier / Unary / Arithmetic / Template)\n * to mirror the resolver architecture (e.g. `tryResolveIdentifier` today, and future\n * unary/binary support), so it remains obvious which class of operation introduced\n * which kind of segment.\n */\n\n/**\n * A single canonicalization strategy applied to one path segment.\n *\n * Note:\n * This operates on segments (not on full JSON trees), which keeps typing strict\n * and avoids JSON.stringify's \"root container\" callback signature.\n */\nexport type SegmentCanonicalizer = (\n segment: PropertyPathSegment\n) => PropertyPathSegment;\n\n/**\n * Dispatcher: runs a list of segment canonicalizers in order.\n *\n * This mirrors the resolver dispatcher style (e.g. `tryResolveLiteral -> tryResolveIdentifier -> ...`),\n * but applies to PropertyPath serialization stability rather than AST evaluation.\n *\n * @param canonicalizers\n * Ordered list of canonicalization strategies to apply.\n * @returns\n * A single canonicalizer that applies all strategies in sequence.\n */\nfunction composeSegmentCanonicalizers(\n canonicalizers: ReadonlyArray<SegmentCanonicalizer>\n): SegmentCanonicalizer {\n return function canonicalizeComposed(\n segment: PropertyPathSegment\n ): PropertyPathSegment {\n let currentSegment = segment;\n for (const canonicalize of canonicalizers) {\n currentSegment = canonicalize(currentSegment);\n }\n return currentSegment;\n };\n}\n\n/**\n * Identifier-domain canonicalization.\n *\n * Handles non-finite numeric constants that can arise directly from identifier\n * resolution (e.g. `NaN`, `Infinity`).\n *\n * Note:\n * `-Infinity` is not an identifier constant and is intentionally excluded here.\n *\n * @param segment\n * The current path segment to canonicalize.\n * @returns\n * The canonicalized segment (may be converted to a string token).\n */\nfunction canonicalizeIdentifierNumberConstants(\n segment: PropertyPathSegment\n): PropertyPathSegment {\n if (!isNumber(segment)) return segment;\n\n if (isNaNValue(segment)) return 'NaN';\n if (isInfinityValue(segment)) return 'Infinity';\n\n return segment;\n}\n\n/**\n * Template-domain canonicalization.\n *\n * Currently a no-op because template resolution yields strings, which are already\n * stable path segments. Kept for symmetry and future extension.\n *\n * @param segment\n * The current path segment to canonicalize.\n * @returns\n * The segment unchanged.\n */\nfunction canonicalizeTemplateResults(\n segment: PropertyPathSegment\n): PropertyPathSegment {\n return segment;\n}\n\n/**\n * Unary-domain canonicalization.\n *\n * Handles numeric edge cases commonly introduced by unary forms (or unary-like results)\n * and ensures deterministic representation for path-key serialization.\n *\n * @param segment\n * The current path segment to canonicalize.\n * @returns\n * The canonicalized segment:\n * - `-0` is normalized to `0`\n * - `-Infinity` is preserved as the string token `\"-Infinity\"`\n * - other values are returned unchanged\n */\nexport function canonicalizeUnaryNumberResults(\n segment: PropertyPathSegment\n): PropertyPathSegment {\n if (!isNumber(segment)) return segment;\n\n // Canonicalize -0 to 0 to align with stable property-name semantics.\n if (isNegativeZeroValue(segment)) return 0;\n\n // Preserve negative infinity as a stable token (JSON cannot represent it).\n if (isNegativeInfinityValue(segment)) return '-Infinity';\n\n return segment;\n}\n\n/**\n * Arithmetic-domain canonicalization (future-facing).\n *\n * Safety net for any numeric results produced by arithmetic/binary evaluation once supported\n * (and for externally constructed paths today).\n *\n * @param segment\n * The current path segment to canonicalize.\n * @returns\n * The canonicalized segment (non-finite numbers become stable string tokens).\n */\nexport function canonicalizeArithmeticNumberResults(\n segment: PropertyPathSegment\n): PropertyPathSegment {\n if (!isNumber(segment)) return segment;\n\n if (isNaNValue(segment)) return 'NaN';\n if (isInfinityValue(segment)) return 'Infinity';\n if (isNegativeInfinityValue(segment)) return '-Infinity';\n\n return segment;\n}\n\n/**\n * Master segment canonicalizer for PropertyPath stringification.\n *\n * Ordering is not about correctness (each step is value-based and idempotent),\n * but about keeping provenance explicit and maintainable as resolver capabilities grow.\n */\nconst propertyPathSegmentCanonicalizer: SegmentCanonicalizer =\n composeSegmentCanonicalizers([\n canonicalizeIdentifierNumberConstants,\n canonicalizeTemplateResults\n // canonicalizeUnaryNumberResults,\n // canonicalizeArithmeticNumberResults\n ]);\n\n/**\n * Produces a canonicalized copy of a {@link PropertyPath} suitable for stable string keys.\n * Does not mutate the input path.\n *\n * @param path\n * The logical property path to canonicalize.\n * @returns\n * A new array of canonicalized path segments.\n */\nfunction canonicalizePropertyPath(path: PropertyPath): PropertyPathSegment[] {\n return path.map(segment => propertyPathSegmentCanonicalizer(segment));\n}\n\n/**\n * Produces the canonical key used for Map/Set lookups.\n *\n * Use this everywhere you currently use `JSON.stringify(PropertyPath)` for indexing.\n *\n * @param path\n * The logical property path to stringify.\n * @returns\n * A stable, canonical string key for indexing.\n */\nexport function stringifyPropertyPath(path: PropertyPath): string {\n return JSON.stringify(canonicalizePropertyPath(path));\n}\n","import { type AssignmentProperty } from 'estree';\nimport {\n type NodePath,\n type Visitors,\n types,\n is,\n traverse\n} from 'estree-toolkit';\nimport { valueToEstree } from 'estree-util-value-to-estree';\n\nimport type {\n StaticDataPatterns,\n PreservedPropStrategy,\n PreservedSubtreeLifecycle\n} from './architecture';\nimport type { PropertyPatch, PropertyPath } from './types';\n\nimport { extractPropertyKey } from './extractor/key-extractor';\nimport { isPatchablePropsRoot, isPlainObject } from './guards';\n\nimport { type ExpressionRefResolver, isExpressionRef } from './expression-ref';\n\nimport { isArrayElision } from './utils/array-utils';\nimport { isKeyPreserved } from './utils/path-utils';\nimport { stringifyPropertyPath } from './utils/property-path-key';\n\n/**\n * Select the first remaining unapplied patch key.\n *\n * Selection order\n * ---------------\n * 1. Prefer unapplied \"set\" patches (`setPatchByPathKey`) if any remain.\n * - Reason: \"set\" patches are the more informative / primary operations.\n * - The map keys are already canonical `pathKey` strings.\n *\n * 2. Otherwise pick an unapplied \"delete\" key (`deletePathKeys`) if any remain.\n * - The set stores canonical `pathKey` strings as well.\n *\n * Return value\n * ------------\n * - returns the canonical `pathKey` string (e.g. '[\"items\",1,\"id\"]')\n * - returns `undefined` if nothing remains unapplied\n */\nexport function getFirstUnappliedPathKey(\n setPatchByPathKey: Map<string, Extract<PropertyPatch, { operation: 'set' }>>,\n deletePathKeys: Set<string>\n): string | undefined {\n const firstSetKeyIterator = setPatchByPathKey.keys().next();\n if (!firstSetKeyIterator.done) return firstSetKeyIterator.value;\n\n const firstDeleteKeyIterator = deletePathKeys.values().next();\n if (!firstDeleteKeyIterator.done) return firstDeleteKeyIterator.value;\n\n return undefined;\n}\n\n/**\n * Rebuilds an ESTree `Expression` from an extracted/validated JS value.\n *\n * Responsibilities\n * ----------------\n * 1. Inline preserved-subtree placeholders:\n * - `ExpressionRef` values (e.g. for `children`) are resolved back to their\n * original captured ESTree expression and inlined into the output.\n *\n * 2. Encode data-like values:\n * - Arrays -> `ArrayExpression`\n * - Plain objects -> `ObjectExpression`\n * - Primitives/null -> `valueToEstree(...)`\n *\n * @param value\n * JS value to encode as an ESTree `Expression` (may include `ExpressionRef`\n * placeholders).\n * @param expressionRefResolver\n * Resolver used to inline `ExpressionRef` placeholders into real ESTree\n * expressions.\n * @returns\n * ESTree `Expression` node representing `value`.\n */\nfunction buildEstreeValue(\n value: unknown,\n expressionRefResolver: ExpressionRefResolver\n): types.Expression {\n /**\n * 1. Inline ExpressionRef placeholders (inline-only)\n */\n if (isExpressionRef(value)) {\n const resolvedExpression = expressionRefResolver(value);\n if (!resolvedExpression) {\n throw new Error(\n `[recma] Cannot inline ExpressionRef at path \"${value.path.join('.')}\".`\n );\n }\n return resolvedExpression;\n }\n\n /**\n * 2. Encode data-like values into ESTree\n */\n if (Array.isArray(value)) {\n const elements: Array<types.Expression | null> = new Array(value.length);\n\n for (let slotIndex = 0; slotIndex < value.length; slotIndex++) {\n // Elision (`,,`): encode as `null` in `ArrayExpression.elements`.\n if (isArrayElision(value, slotIndex)) {\n elements[slotIndex] = null;\n continue;\n }\n\n elements[slotIndex] = buildEstreeValue(\n value[slotIndex],\n expressionRefResolver\n );\n }\n\n return {\n type: 'ArrayExpression',\n elements\n } satisfies types.ArrayExpression;\n }\n\n if (isPlainObject(value)) {\n const properties: types.Property[] = [];\n\n for (const [key, child] of Object.entries(value)) {\n properties.push({\n type: 'Property',\n\n /**\n * Static object key (no brackets):\n * - `{ foo: 1 }` ✅\n * - `{ [foo]: 1 }` ❌\n */\n computed: false,\n\n /**\n * Always emit explicit key/value pairs:\n * - `{ foo: foo }` ✅\n * - `{ foo }` ❌ (shorthand)\n */\n shorthand: false,\n\n /**\n * Not method syntax:\n * - `{ foo: () => {} }` ✅ (value is an expression)\n * - `{ foo() {} }` ❌ (method)\n */\n method: false,\n\n /**\n * Regular initializer property:\n * - `{ foo: value }` ✅\n * - `{ get foo() {} }` ❌\n * - `{ set foo(v) {} }` ❌\n */\n kind: 'init',\n\n /**\n * Use a string-literal key so any JS object key is representable\n * (including keys that are not valid identifiers, e.g. `\"data-id\"`, `\"1\"`, `\"a b\"`).\n */\n key: { type: 'Literal', value: key },\n\n /**\n * Encode the value as an ESTree expression.\n * \"Recursive\" means nested arrays/objects are encoded by calling `buildEstreeValue`\n * again for their children until primitives/ExpressionRefs are reached.\n */\n value: buildEstreeValue(child, expressionRefResolver)\n });\n }\n\n return {\n type: 'ObjectExpression',\n properties\n } satisfies types.ObjectExpression;\n }\n\n /**\n * Fallback: encode simple \"leaf\" values as ESTree expressions.\n *\n * Examples:\n * 1. \"x\" -> Literal(\"x\")\n * 2. 1 -> Literal(1)\n * 3. true -> Literal(true)\n * 4. null -> Literal(null)\n */\n return valueToEstree(value);\n}\n\n/**\n * Attempts to append an object-key segment (e.g. `\"meta\"`, `\"id\"`) when the current\n * cursor is a `Property` inside an `ObjectExpression`.\n *\n * Return values (3-state):\n * - `NodePath` : matched; a segment was appended and the returned path is the next cursor.\n * - `undefined` : not applicable; caller should try other segment types and keep climbing.\n * - `null` : applicable but unsupported (dynamic/computed key); path reconstruction\n * cannot continue and the caller should abort with `null`.\n *\n * @param cursor\n * Current node path while walking upward through the AST.\n * @param pathSegments\n * Collected `PropertyPath` segments (built in reverse order while climbing).\n * @returns\n * Next cursor on match, `undefined` if not applicable, or `null` if the key is dynamic.\n */\nfunction tryAppendObjectKeySegment(\n cursor: NodePath<types.Node>,\n pathSegments: PropertyPath\n): NodePath<types.Node> | null | undefined {\n const parentNode = cursor.parentPath?.node;\n if (!parentNode) return undefined;\n\n if (is.property(cursor.node) && is.objectExpression(parentNode)) {\n const keySegment = extractPropertyKey(cursor.node);\n\n // computed/dynamic key cannot be represented as PropertyPath\n if (keySegment === null) return null;\n\n pathSegments.push(keySegment);\n return cursor.parentPath;\n }\n\n return undefined;\n}\n\n/**\n * Attempts to append an array-index segment (e.g. `0`, `1`, `2`) when the current\n * cursor is a node occupying an `elements[index]` slot in an `ArrayExpression`.\n *\n * Return values (2-state):\n * - `NodePath` : matched; an index segment was appended and the returned path is the next cursor.\n * - `undefined` : not applicable; caller should try other segment types and keep climbing.\n *\n * @param cursor\n * Current node path while walking upward through the AST.\n * @param pathSegments\n * Collected `PropertyPath` segments (built in reverse order while climbing).\n * @returns\n * Next cursor on match, otherwise `undefined`.\n */\n// function tryAppendArrayIndexSegment(\n// cursor: NodePath<types.Node>,\n// pathSegments: PropertyPath\n// ): NodePath<types.Node> | undefined {\n// const parentNode = cursor.parentPath?.node;\n// if (!parentNode) return undefined;\n\n// if (is.arrayExpression(parentNode) && typeof cursor.key === 'number') {\n// const indexSegment = cursor.key;\n// pathSegments.push(indexSegment);\n// return cursor.parentPath;\n// }\n\n// return undefined;\n// }\n\n/**\n * Computes the logical `PropertyPath` from the patchable props root to `targetPath`.\n *\n * The patcher uses this mapping to translate an AST position (`NodePath`) into the\n * `(string | number)[]` addressing used by the patch planner (e.g. `[\"items\", 0, \"id\"]`).\n *\n * Unsupported / dynamic shapes return `null`:\n * - computed/dynamic object keys\n * - other AST relationships that cannot be expressed as a `PropertyPath`\n *\n * @param targetPath\n * Node path within the props object literal subtree.\n * @returns\n * Root-relative `PropertyPath` for the node, or `null` if the path cannot be represented.\n */\nfunction getRelativePathFromRoot(\n targetPath: NodePath<types.Node>\n): PropertyPath | null {\n const pathSegments: PropertyPath = [];\n let cursor: NodePath<types.Node> | null = targetPath;\n\n // Walk upward from the target node until the props root is reached.\n while (cursor?.parentPath) {\n const parentNode = cursor.parentPath.node;\n const node = cursor.node;\n if (!parentNode || !node) break;\n\n /**\n * 1. Property value -> hop to the owning Property node.\n * This keeps the cursor at the \"property container\" level so the next\n * step can record the property key segment.\n */\n if (is.property(parentNode) && cursor.key === 'value') {\n cursor = cursor.parentPath as NodePath<types.Node>;\n continue;\n }\n\n /**\n * 2. Object property segment (e.g. .meta / .id)\n */\n const nextFromObject = tryAppendObjectKeySegment(cursor, pathSegments);\n if (nextFromObject === null) return null; // dynamic/computed key\n if (nextFromObject) {\n cursor = nextFromObject;\n continue;\n }\n\n /**\n * 3. Array index segment (e.g. [0], [1])\n */\n // const nextFromArray = tryAppendArrayIndexSegment(cursor, pathSegments);\n // if (nextFromArray) {\n // cursor = nextFromArray;\n // continue;\n // }\n\n // Otherwise keep climbing.\n cursor = cursor.parentPath as NodePath<types.Node>;\n }\n\n // Segments were collected while walking upward (leaf -> root), so reverse them\n // to produce root -> leaf order (e.g. [\"items\", 0, \"id\"]).\n return pathSegments.reverse();\n}\n\ntype PatchIndex = {\n /**\n * Lookup for \"set\" operations by serialized path key.\n *\n * Note:\n * Only one set patch can exist per pathKey; later patches overwrite earlier ones.\n */\n setPatchByPathKey: Map<string, Extract<PropertyPatch, { operation: 'set' }>>;\n\n /**\n * Membership set of serialized path keys to delete.\n */\n deletePathKeys: Set<string>;\n};\n\n/**\n * Builds fast lookup tables keyed by a canonical path key.\n *\n * Why this exists\n * ---------------\n * During AST traversal a fresh `PropertyPath` array (e.g. `[\"items\", 0, \"id\"]`)\n * is computed for each visited node. Patch presence must be checked without\n * scanning the full patch list every time.\n *\n * The challenge: Map keys are identity-based for arrays/objects\n * -------------------------------------------------------------\n * Using `Map<PropertyPath, Patch>` does NOT work because arrays are compared by\n * reference identity, not by “same contents”:\n *\n * const m = new Map<(string|number)[], string>();\n * m.set([\"items\", 0, \"id\"], \"patch\");\n * m.get([\"items\", 0, \"id\"]); // undefined (different array instance)\n *\n * Middle ground: JSON.stringify as a canonical key\n * ------------------------------------------------\n * `PropertyPath` is converted to a stable string key via `JSON.stringify`.\n * This gives value-like equality (same segments => same key) with minimal code:\n *\n * const key = JSON.stringify([\"items\", 0, \"id\"]); // '[\"items\",0,\"id\"]'\n *\n * Tradeoff:\n * String allocation occurs, but the implementation remains small, flat, and\n * unambiguous for `(string | number)[]`.\n *\n * @param patches\n * Patch list produced by the planner.\n * @returns\n * Lookup structures used during traversal:\n * - `setPatchByPathKey`: serialized path -> \"set\" patch\n * - `deletePathKeys`: serialized paths to delete\n */\nfunction buildPatchIndex(patches: readonly PropertyPatch[]): PatchIndex {\n const setPatchByPathKey = new Map<\n string,\n Extract<PropertyPatch, { operation: 'set' }>\n >();\n const deletePathKeys = new Set<string>();\n\n for (const patch of patches) {\n const pathKey = stringifyPropertyPath(patch.path);\n\n if (patch.operation === 'set') {\n setPatchByPathKey.set(pathKey, patch); // last one wins\n } else {\n deletePathKeys.add(pathKey);\n }\n }\n\n return { setPatchByPathKey, deletePathKeys };\n}\n\ntype PatchApplyState = {\n preservedKeys: ReadonlySet<string>;\n setPatchByPathKey: Map<string, Extract<PropertyPatch, { operation: 'set' }>>;\n deletePathKeys: Set<string>;\n expressionRefResolver: ExpressionRefResolver;\n};\n\nfunction applyObjectPropertyPatchesIfNeeded(\n path: NodePath<AssignmentProperty | types.Property, types.Node>,\n state: PatchApplyState\n) {\n /**\n * 1. Preconditions\n * ----------------\n * Only proceed when the `Property` node exists and has a static key.\n */\n if (!path.node) return;\n\n const propertyKey = extractPropertyKey(path.node);\n if (propertyKey === null) return;\n\n /**\n * 2. Skip preserved runtime-expression subtrees\n * ---------------------------------------------\n *\n * Patch application traverses and edits the compiled ESTree AST (not the\n * extracted/validated JS values). Some props (e.g. `children`) are treated as\n * preserved runtime-expression subtrees: their values may contain JSX, calls,\n * or functions and must be preserved as-is.\n *\n * Why traversal is skipped:\n * 1. Extraction-time representation differs from patch-time traversal:\n * extraction may model these values as `ExpressionRef` placeholders, but\n * patching walks the real AST subtree, which still contains the original\n * runtime expression.\n * 2. Safety:\n * descending into these subtrees risks applying patches inside runtime code\n * that was intentionally excluded from static evaluation.\n *\n * Result:\n * - Traversal does not descend into the subtree.\n * - Any patch targeting this property or anything below it remains unapplied\n * and is surfaced by reporting.\n */\n if (isKeyPreserved(propertyKey, state.preservedKeys)) {\n // Prevent traversal from entering the runtime-expression subtree.\n path.skipChildren();\n return;\n }\n\n /**\n * 3. Compute lookup key for this property\n * --------------------------------------\n * `getRelativePathFromRoot` maps the current `Property` node back to a logical\n * `PropertyPath` from the props root (e.g. [\"title\"], [\"items\", 1, \"id\"]).\n *\n * This works uniformly for:\n * - top-level props: [\"title\"]\n * - nested object props: [\"meta\", \"author\", \"name\"]\n * - object props inside arrays: [\"items\", 1, \"id\"]\n *\n * The property value node type is not relevant here: `value` may be a Literal,\n * ObjectExpression, ArrayExpression, etc. The patcher replaces the `value`\n * expression in-place (leaf-only).\n */\n const propPath = getRelativePathFromRoot(path);\n if (!propPath) return;\n\n const pathKey = stringifyPropertyPath(propPath);\n\n /**\n * 4. Apply deletion (remove property entry)\n * -----------------------------------------\n * Deletes at object-key level remove the `Property` node.\n */\n if (state.deletePathKeys.has(pathKey)) {\n path.remove();\n state.deletePathKeys.delete(pathKey);\n return;\n }\n\n /**\n * 5. Apply set (replace property value expression)\n * -----------------------------------------------\n */\n const patch = state.setPatchByPathKey.get(pathKey);\n if (!patch) return;\n\n path\n .get('value')\n .replaceWith(buildEstreeValue(patch.value, state.expressionRefResolver));\n\n state.setPatchByPathKey.delete(pathKey);\n}\n\n// function applyArrayElementPatchesIfNeeded(\n// path: NodePath<types.ArrayExpression>,\n// state: PatchApplyState\n// ) {\n// /**\n// * 1. Preconditions\n// * ----------------\n// * Only proceed when the current node exists and can be mapped to a `PropertyPath`.\n// */\n// if (!path.node) return;\n\n// const arrayPath = getRelativePathFromRoot(path);\n// if (!arrayPath) return;\n\n// /**\n// * 2. Iterate array slots\n// * ----------------------\n// * Array patches target index slots (e.g. [\"items\", 1]). The visitor runs on the\n// * parent `ArrayExpression`, so it iterates `elements[index]` directly to ensure\n// * every index is checked regardless of the element node type.\n// *\n// * `path.get('elements')` is used to obtain `NodePath`s for each slot so existing\n// * elements can be replaced via `replaceWith(...)`.\n// *\n// * Note:\n// * This currently scans all array slots. If very large array literals become common and\n// * only a small subset of indices are patched, an optimization can index slot-level\n// * patches by `arrayPath` to visit only the touched indices (O(k) vs O(n)).\n// */\n// const elementPaths = path.get('elements') as NodePath<types.Node>[];\n\n// for (let index = 0; index < elementPaths.length; index++) {\n// const elementPath = elementPaths[index];\n\n// /**\n// * 3. Compute lookup key for this slot\n// * ----------------------------------\n// */\n// const itemPath: PropertyPath = [...arrayPath, index];\n// const pathKey = stringifyPropertyPath(itemPath);\n\n// /**\n// * Array slot vs. nested property (important distinction)\n// * ------------------------------------------------------\n// * This function applies slot-level patches that target the element itself:\n// * - delete [\"items\", 1] => creates a hole at index 1 (indices do not shift)\n// * - set [\"items\", 1] => replaces the entire element at index 1\n// *\n// * Nested paths target properties inside an element object and are handled\n// * later by the `Property` visitor during traversal:\n// * - set [\"items\", 1, \"id\"] => updates the `id` property inside items[1]\n// * (no hole; the element object remains in place)\n// */\n\n// /**\n// * 4. Apply deletion (keeps array shape)\n// * -------------------------------------\n// * Deletions produce a hole to avoid shifting indices.\n// *\n// * Array-index deletes are supported here (delete => hole to avoid shifting indices).\n// * In the current pipeline, delete patches are typically produced for:\n// * 1. Object-key removals from diffing (when enabled).\n// * 2. Explicit prune steps (object keys only).\n// * Numeric-path deletes are only possible if an upstream planner emits them explicitly.\n// */\n// if (state.deletePathKeys.has(pathKey)) {\n// path.node.elements[index] = null;\n// state.deletePathKeys.delete(pathKey);\n// continue;\n// }\n\n// /**\n// * 5. Apply set (replace element or fill hole)\n// * -------------------------------------------\n// * Slot-level set replaces the entire element expression at `elements[index]`\n// * or fills the slot if it is currently empty.\n// */\n// const patch = state.setPatchByPathKey.get(pathKey);\n// if (!patch) continue;\n\n// const newValue = buildEstreeValue(patch.value, state.expressionRefResolver);\n\n// if (elementPath?.node) {\n// // Use the visitor method to preserve traversal context when the node exists.\n// elementPath.replaceWith(newValue);\n// } else {\n// // If the slot is currently a hole (null), `elementPath.replaceWith`\n// // cannot be used because there is no node to replace.\n// // Direct assignment to the parent AST node is required to fill the hole.\n// path.node.elements[index] = newValue;\n// }\n\n// state.setPatchByPathKey.delete(pathKey);\n// }\n// }\n\nexport type ApplyPatchesOptions = {\n /**\n * Resolver used to inline ExpressionRef placeholders back into real ESTree expressions.\n */\n expressionRefResolver: ExpressionRefResolver;\n};\n\nexport type ApplyPatchesResult = {\n /**\n * A canonical key for one remaining unapplied patch, used as the primary\n * “pointer” for diagnostics.\n *\n * Canonical key format:\n * - Produced by `JSON.stringify(PropertyPath)`\n * - Example: '[\"items\",1,\"id\"]'\n *\n * Selection order:\n * - Prefer remaining \"set\" keys, otherwise return a remaining \"delete\" key.\n */\n firstUnappliedPathKey?: string;\n\n /**\n * Canonical keys for unapplied \"set\" operations.\n *\n * Each key corresponds to a planned `set` patch that could not be applied\n * during traversal (e.g. the target path does not exist in the AST, or the\n * AST shape is non-literal where leaf-only edits are not possible).\n */\n remainingSetPathKeys: string[];\n\n /**\n * Canonical keys for unapplied \"delete\" operations.\n *\n * Each key corresponds to a planned `delete` patch that could not be applied.\n * Deletes can target object properties (removing a `Property`) or array slots\n * (clearing an element), but are still constrained by leaf-only rules.\n */\n remainingDeletePathKeys: string[];\n\n /**\n * Total number of remaining unapplied \"set\" patch keys.\n *\n * Convenience field derived from `remainingSetPathKeys.length`.\n */\n remainingSetCount: number;\n\n /**\n * Total number of remaining unapplied \"delete\" patch keys.\n *\n * Convenience field derived from `remainingDeletePathKeys.length`.\n */\n remainingDeleteCount: number;\n};\n\n/**\n * Finalizes an ApplyPatchesResult snapshot from the patch-application indexes.\n *\n * Patch application uses canonical path keys (`JSON.stringify(PropertyPath)`) as\n * the single source of truth for patch indexing:\n * - `setPatchByPathKey` holds remaining unapplied \"set\" patches\n * - `deletePathKeys` holds remaining unapplied \"delete\" patches\n *\n * As patches are applied during traversal, entries are removed from these\n * collections. Any keys that remain represent patches that could not be applied\n * under the current AST shape (e.g. missing path, non-literal root, array holes).\n *\n * @param setPatchByPathKey\n * Map of remaining unapplied \"set\" patches keyed by canonical path key.\n * @param deletePathKeys\n * Set of remaining unapplied \"delete\" patch keys in canonical key form.\n * @returns\n * Snapshot describing:\n * - one primary unapplied key for diagnostics (`firstUnappliedPathKey`), and\n * - complete remaining key lists + counts for reporting/summary.\n */\nfunction finalizeApplyPatchesResult(\n setPatchByPathKey: Map<string, Extract<PropertyPatch, { operation: 'set' }>>,\n deletePathKeys: Set<string>\n): ApplyPatchesResult {\n const remainingSetPathKeys = Array.from(setPatchByPathKey.keys());\n const remainingDeletePathKeys = Array.from(deletePathKeys.values());\n\n const firstUnappliedPathKey = getFirstUnappliedPathKey(\n setPatchByPathKey,\n deletePathKeys\n );\n\n return {\n firstUnappliedPathKey,\n remainingSetPathKeys,\n remainingDeletePathKeys,\n remainingSetCount: remainingSetPathKeys.length,\n remainingDeleteCount: remainingDeletePathKeys.length\n };\n}\n\n/**\n * Creates the ESTree visitor implementation for applying patches.\n *\n * Only two visitor hooks are required:\n * 1. `Property`\n * - Applies object-key patches by replacing/removing `Property` nodes.\n * 2. `ArrayExpression`\n * - Applies array-index patches by iterating the array `elements`\n * (via `applyArrayElementPatchesIfNeeded`).\n *\n * Not needed (and why):\n * - `Literal` / `ObjectExpression` visitors for array patching.\n * Array elements are not limited to literals or object literals; they can be any\n * expression node type (Identifier, CallExpression, JSXElement, etc.).\n *\n * If array patching only ran in `Literal` / `ObjectExpression` visitors, then element\n * patches are applied only when the element happens to be one of those types and are\n * silently missed for other element types.\n *\n * Example (why patch at `ArrayExpression`):\n *\n * // Source\n * items={[ 1, foo, { a: 1 }, foo() ]}\n *\n * // Element node types:\n * // index 0 -> Literal\n * // index 1 -> Identifier\n * // index 2 -> ObjectExpression\n * // index 3 -> CallExpression\n *\n * // Patches targeting these indices:\n * // [\"items\", 0] // would be observed by a `Literal` visitor\n * // [\"items\", 1] // would be missed without an `Identifier` visitor\n * // [\"items\", 2] // would be observed by an `ObjectExpression` visitor\n * // [\"items\", 3] // would be missed without a `CallExpression` visitor\n *\n * Applying array-index patches from the parent `ArrayExpression` iterates `elements[0..n]`,\n * so every index is checked regardless of the element node type.\n *\n * @returns\n * A visitor object compatible with `estree-toolkit` traversal.\n */\nfunction createPatchApplicationVisitors(): Visitors<PatchApplyState> {\n return {\n Property(path, state) {\n applyObjectPropertyPatchesIfNeeded(path, state);\n }\n\n // ArrayExpression(path, state) {\n // applyArrayElementPatchesIfNeeded(path, state);\n // }\n };\n}\n\n/**\n * Applies a list of patches to the ESTree AST.\n *\n * This function handles the physical mutation of the AST. It performs the final\n * step of the {@link PreservedSubtreeLifecycle} (\"ExpressionRef Round-Trip\"):\n *\n * 1. **Data Props:**\n * Static values are encoded directly into ESTree nodes (e.g., `Literal`,\n * `ArrayExpression`). See {@link StaticDataPatterns}.\n *\n * 2. **Preserved Props:**\n * Opaque runtime subtrees (captured as `ExpressionRef` placeholders) are\n * resolved back to their original AST nodes and inlined.\n * See {@link PreservedPropStrategy}.\n *\n * @param propsRootPath - NodePath to the props ObjectExpression.\n * @param patches - List of operations to apply.\n * @param preservedKeys - Keys that must be skipped during traversal.\n * @param options - Contains the `expressionRefResolver`.\n */\nexport function applyPatchesToEstree(\n propsRootPath: NodePath<types.Node>,\n patches: PropertyPatch[],\n preservedKeys: ReadonlySet<string>,\n options: ApplyPatchesOptions\n): ApplyPatchesResult {\n /**\n * Entry guard:\n * Leaf-only patching requires a patchable props root (see `isPatchablePropsRoot`).\n * If the root is not patchable, no patches can be applied safely, so patch\n * application returns with all patches still tracked as unapplied for\n * reporting.\n */\n\n // Precompute O(1) patch lookups by pathKey during traversal.\n // Also used to report unapplied patches on early exit.\n const { setPatchByPathKey, deletePathKeys } = buildPatchIndex(patches);\n\n if (!isPatchablePropsRoot(propsRootPath.node)) {\n // Non-literal props roots cannot be edited under leaf-only patching;\n // return all patches as unapplied.\n return finalizeApplyPatchesResult(setPatchByPathKey, deletePathKeys);\n }\n\n const state: PatchApplyState = {\n preservedKeys,\n setPatchByPathKey,\n deletePathKeys,\n expressionRefResolver: options.expressionRefResolver\n };\n\n // Create visitors with the documented strategy\n const visitors = createPatchApplicationVisitors();\n\n traverse(propsRootPath.node, visitors, state);\n\n return finalizeApplyPatchesResult(setPatchByPathKey, deletePathKeys);\n}\n","import type { PatchGroup, PatchPhase, PropertyPatch } from './types';\nimport { stringifyPropertyPath } from './utils/property-path-key';\n\n/**\n * Merges patch groups from multiple phases, deduplicating by path and tracking origin.\n *\n * Deduplication (\"last writer wins\"):\n * When multiple phases target the same canonical `pathKey` (e.g., `diff` sets\n * 'someKey' and `prune` deletes 'someKey'), the later phase in the input order\n * overwrites the earlier entry in `patchByPathKey`.\n * Only the final winning patch is retained; earlier patches for that path are\n * discarded and will not be applied.\n *\n * Recording the source phase:\n * The `phaseByPathKey` map records which phase \"won\" for each path, used later\n * for diagnostic annotations and actionable hints.\n *\n * @param groups - Array of patch groups in priority order (typically: diff → derive → prune).\n * Later groups overwrite earlier ones for the same pathKey.\n * @returns Object containing:\n * - `patches`: Winning patches per unique path\n * - `phaseByPathKey`: Winning phase per unique path\n */\nexport function consolidatePatches(groups: readonly PatchGroup[]): {\n patches: PropertyPatch[];\n phaseByPathKey: Map<string, PatchPhase>;\n} {\n const patchByPathKey = new Map<string, PropertyPatch>();\n const phaseByPathKey = new Map<string, PatchPhase>();\n\n for (const { phase, patches } of groups) {\n for (const patch of patches) {\n const pathKey = stringifyPropertyPath(patch.path);\n\n // Last writer wins for both patch and phase\n patchByPathKey.set(pathKey, patch);\n phaseByPathKey.set(pathKey, phase);\n }\n }\n\n return {\n patches: Array.from(patchByPathKey.values()),\n phaseByPathKey\n };\n}\n","import type { ZeroTolerancePatchPolicy } from './architecture';\nimport type { PatchPhase } from './types';\n\nimport { isPropertyPath } from './guards';\n\n/**\n * Phase safety & user actionability\n * ---------------------------------\n * Not all unapplied patches indicate user-recoverable errors. While the patch\n * planning pipeline includes safeguards to prevent generating invalid patches,\n * application failure modes differ by phase.\n *\n * Planning safeguards\n * -------------------\n * These prevent bad patches from being generated in the first place,\n * satisfying the {@link LeafOnlyPatchingConstraint}:\n * - `diff` (Schema Coercion): Only produces CHANGE operations for existing paths,\n * omitting CREATE/REMOVE.\n * - `prune` (Key Removal): Only iterates keys present in the extracted static props.\n *\n * Application failure modes\n * -------------------------\n * Despite planning safeguards, patches can fail during AST application when the\n * runtime AST structure prevents leaf-only editing:\n * - Non-literal property keys (computed/dynamic) prevent `PropertyPath` reconstruction\n * - Preserved keys block traversal into subtrees where patches were planned\n * - Non-patchable props roots (e.g. spread elements) prevent any application\n *\n * Note:\n * Even when structural constraints prevent application, the phase metadata\n * assigned during planning is preserved and reported via the canonical key\n * lookup.\n *\n * Phase-specific recovery\n * -----------------------\n *\n * - `derive`: User-defined logic may target paths missing from the AST (violating\n * the leaf-only constraint).\n * **User-recoverable:** Ensure placeholder props exist in MDX (e.g. `test={null}`)\n * before derivation attempts to set `test`.\n *\n * - `diff` / `prune`: Failures indicate structural AST constraints (dynamic keys,\n * preserved subtrees) that violate leaf-only editing.\n * **Not user-recoverable** via MDX edits; requires component architecture changes\n * (removing computed keys, restructuring props).\n *\n * Hint policy\n * -----------\n * Consequently, actionable hints are only provided for `derive` phase failures.\n * `diff` and `prune` failures are reported under the zero-tolerance policy but\n * offer no remediation steps—the constraint violation is architectural, not\n * configurational.\n */\n\nexport type PatchReportOptions = {\n /**\n * The display name of the component being validated (e.g. \"CustomComponent\").\n * Used to identify the target in the error header.\n */\n componentName: string;\n\n /**\n * Retrieves the pipeline phase (e.g. 'diff', 'derive') for a given path key.\n * Used to annotate the error with the origin of the failure.\n */\n getPatchPhaseByPathKey: (pathKey: string) => PatchPhase | undefined;\n\n /**\n * Context used to append a statistical summary to the error message.\n *\n * The error includes a footer line detailing the total count\n * of unapplied patches and a preview of specific paths.\n */\n summaryContext: PatchSummaryContext;\n};\n\nexport type PatchSummaryContext = {\n /**\n * Canonical keys for all 'set' patches that failed.\n */\n remainingSetPathKeys: readonly string[];\n\n /**\n * Canonical keys for all 'delete' patches that failed.\n */\n remainingDeletePathKeys: readonly string[];\n\n /**\n * Maximum number of specific paths to list in the summary string.\n * @default 5\n */\n maxPreviewPaths?: number;\n};\n\n/**\n * Formats a canonical `pathKey` into a human-readable dotted path.\n *\n * Parses the JSON-encoded `PropertyPath` and joins with dots.\n * If parsing fails or results in an empty path, falls back to returning\n * the raw `pathKey` string for debugging purposes.\n *\n * @param pathKey - Canonical string key (e.g., `'[\"items\",1,\"id\"]'`)\n * @returns Human-readable dotted path (e.g., `\"items.1.id\"`),\n * or the raw `pathKey` if parsing fails\n */\nfunction formatPathKeyForDisplay(pathKey: string): string {\n try {\n const parsed = JSON.parse(pathKey);\n if (isPropertyPath(parsed) && parsed.length > 0) {\n return parsed.join('.');\n }\n } catch {\n // Fall through to return raw pathKey\n }\n return pathKey;\n}\n\n/**\n * Formats a human-readable summary of unapplied patch operations (set/delete)\n * grouped by phase with an optional preview of affected paths.\n *\n * @param context - Context containing remaining path keys and display configuration\n * @param getPhase - Function to resolve the phase for a given path key\n * @returns Formatted summary string (e.g.\n * `Summary: unapplied set=3 (diff=2, derive=1), delete=1 (prune=1);\n * preview: \"props.title\" (diff), … (2 more)`);\n * undefined if no unapplied operations remain\n */\nfunction formatPatchFailureSummary(\n context: PatchSummaryContext,\n getPhase: (pathKey: string) => PatchPhase | undefined\n): string | undefined {\n const setKeys = context.remainingSetPathKeys;\n const deleteKeys = context.remainingDeletePathKeys;\n\n // Nothing to report\n if (setKeys.length === 0 && deleteKeys.length === 0) return undefined;\n\n const parts: string[] = [];\n const operationParts: string[] = [];\n\n if (setKeys.length > 0) {\n const setPhaseStats = formatPhaseDistribution(setKeys, getPhase);\n operationParts.push(\n `set=${setKeys.length}${setPhaseStats ? ` (${setPhaseStats})` : ''}`\n );\n }\n\n if (deleteKeys.length > 0) {\n const deletePhaseStats = formatPhaseDistribution(deleteKeys, getPhase);\n operationParts.push(\n `delete=${deleteKeys.length}${deletePhaseStats ? ` (${deletePhaseStats})` : ''}`\n );\n }\n\n parts.push(`Summary: unapplied ${operationParts.join(', ')}`);\n\n const allKeys = [...setKeys, ...deleteKeys];\n const previewLimit =\n context.maxPreviewPaths != null ? context.maxPreviewPaths : 5;\n\n // Respect disabled preview\n if (previewLimit > 0) {\n const previewStats = formatPathPreview(allKeys, previewLimit, getPhase);\n if (previewStats) {\n parts.push(previewStats);\n }\n }\n\n return parts.join('; ');\n}\n\n/**\n * Aggregates path keys by their resolved phase and formats as a comma-separated\n * key-value list (e.g. \"phase1=3, phase2=5\").\n *\n * @param pathKeys - Array of path keys to analyze\n * @param getPhase - Function to resolve the phase for each key\n * @returns Formatted distribution string; undefined if input array is empty\n */\nfunction formatPhaseDistribution(\n pathKeys: readonly string[],\n getPhase: (key: string) => PatchPhase | undefined\n): string | undefined {\n // Empty input guard\n if (pathKeys.length === 0) return undefined;\n\n const countByPhase = new Map<string, number>();\n\n for (const key of pathKeys) {\n const phase = getPhase(key) ?? 'unknown';\n const current = countByPhase.get(phase) ?? 0;\n countByPhase.set(phase, current + 1);\n }\n\n return Array.from(countByPhase.entries())\n .map(([phase, count]) => `${phase}=${count}`)\n .join(', ');\n}\n\n/**\n * Formats a limited preview list of path keys with their associated phases.\n *\n * @param pathKeys - Array of path keys to preview\n * @param limit - Maximum number of items to display\n * @param getPhase - Function to resolve the phase for each key\n * @returns Formatted preview string; undefined if input is empty or limit is <= 0\n */\nfunction formatPathPreview(\n pathKeys: readonly string[],\n limit: number,\n getPhase: (key: string) => PatchPhase | undefined\n): string | undefined {\n // Invalid state guard\n if (pathKeys.length === 0 || limit <= 0) return undefined;\n\n const items = pathKeys.slice(0, limit).map(key => {\n const phase = getPhase(key) ?? 'unknown';\n return `\"${formatPathKeyForDisplay(key)}\" (${phase})`;\n });\n\n // Truncation indicator\n if (pathKeys.length > limit) {\n items.push(`… (${pathKeys.length - limit} more)`);\n }\n\n return `preview: ${items.join(', ')}`;\n}\n\n/**\n * Formats an actionable hint for patch failures based on phase.\n *\n * Only the `derive` phase provides user-recoverable guidance.\n * Other phases return undefined;\n * see \"Phase safety & user actionability\" section for the safeguard rationale.\n *\n * @param phase - The pipeline phase, or undefined if unknown\n * @returns Actionable hint for `derive`; undefined otherwise\n */\nfunction formatPatchFailureHint(\n phase: PatchPhase | undefined\n): string | undefined {\n switch (phase) {\n case 'derive':\n return (\n 'Hint: derive patches are leaf-only. Ensure the prop exists in MDX ' +\n '(e.g. <CustomComponent test={...} />) before setting it.'\n );\n\n // covers diff, prune, and undefined\n default:\n return undefined;\n }\n}\n\n/**\n * Report (and throw) when patch application could not fully apply all patches.\n *\n * Canonical key contract\n * ----------------------\n * This API uses the canonical path key (`pathKey`) as the single source of truth\n * for both patch indexing and error reporting. By accepting the already-serialized\n * key, this function ensures:\n *\n * - Phase provenance lookups reference exactly the same key used during application\n * - Remaining patch identification uses the same indexing scheme without re-serialization\n * - Zero risk of key mismatch between the patch that failed and its diagnostic metadata\n *\n * Throw behavior (zero-tolerance)\n * -------------------------------\n * Always throws Error for any unapplied patch, per {@link ZeroTolerancePatchPolicy}.\n *\n * @param firstUnappliedPathKey - Canonical string key of the first failed patch\n * @param options - Reporting configuration including component name, phase resolver, and summary context\n * @throws Always throws with formatted message describing the first unapplied patch\n * @returns never\n */\nexport function reportPatchFailure(\n firstUnappliedPathKey: string,\n options: PatchReportOptions\n): never {\n // 1. Look up provenance\n const phase = options.getPatchPhaseByPathKey(firstUnappliedPathKey);\n\n // 2. Format for human path display (e.g. '[\"items\",1,\"id\"]' → \"items.1.id\")\n const propPath = formatPathKeyForDisplay(firstUnappliedPathKey);\n\n // 3. Attach actionable hint based on phase\n const hint = formatPatchFailureHint(phase);\n\n // 4. Build optional phase annotation\n const phaseAnnotation = phase ? ` (phase: ${phase})` : '';\n\n // 5. Format summary statistics for all unapplied patches\n const summaryLine = formatPatchFailureSummary(\n options.summaryContext,\n options.getPatchPhaseByPathKey\n );\n\n // 6. Assemble final error string with optional components\n const messageParts = [\n `[recma] Cannot fully apply patches for ${options.componentName}.`,\n `First un-applied path: \"${propPath}\"${phaseAnnotation} (non-literal AST shape or missing path)`\n ];\n\n if (hint) messageParts.push(hint);\n if (summaryLine) messageParts.push(summaryLine);\n\n const message = messageParts.join('\\n');\n\n // 7. Throw - stop execution (fatal build error)\n throw new Error(message);\n}\n","import type {\n AstTopologyMismatch,\n LeafOnlyPatchingConstraint\n} from './architecture';\nimport type { DeletePropertyPatch } from './types';\nimport { isPlainObject } from './guards';\n\n/**\n * Creates `delete` patches for root-level keys present in `existingProps`.\n *\n * Only keys found in `existingProps` are considered for deletion.\n *\n * Targeted Pruning (Escape Hatch)\n * -------------------------------\n * This operation provides manual override capabilities that are generally\n * restricted by the {@link LeafOnlyPatchingConstraint}.\n *\n * Operational Constraints\n * -----------------------\n *\n * PRUNING (Targeted Deletion)\n * - Context: Manual Configuration (Component Rule).\n * - Mechanism: Removing `Property` nodes from the root `ObjectExpression`.\n * - Rationale: Explicit Cleanup (vs. Indiscriminate Data Loss).\n * 1. Physical Safety:\n * Mitigated by validating against `existingProps` (guaranteed\n * static values). This prevents targeting hidden topology\n * (spreads) described in {@link AstTopologyMismatch}.\n * 2. Logical Safety:\n * Safeguarded by deliberate configuration. Unlike automatic schema\n * stripping, this is a user-defined operation to remove\n * specific legacy props.\n * - Policy: ✅ PERMITTED.\n * Authorized because the key is verified to exist in the\n * static props (Targeted Pruning).\n *\n * Safety invariant\n * ----------------\n * Preserved keys (e.g. `children`) must never be pruned.\n * These represent complex runtime subtrees preserved from the source.\n * Deleting them would irrecoverably drop dynamic content or logic from the\n * compiled output (no reconstruction/inlining possible later).\n *\n * @param existingProps - Source props object providing existing keys eligible\n * for pruning.\n * @param pruneKeys - Keys to remove if present in `existingProps`\n * @param preservedKeys - Keys to protect from deletion (e.g. `children`)\n * @returns Array of delete patches for existing, non-preserved root keys\n */\nexport function planPrunePatches(\n existingProps: unknown,\n pruneKeys: ReadonlyArray<string> | undefined,\n preservedKeys: ReadonlySet<string>\n): DeletePropertyPatch[] {\n // No keys configured to prune\n if (!pruneKeys || pruneKeys.length === 0) return [];\n\n // Input is not a plain object (safeguard)\n if (!isPlainObject(existingProps)) return [];\n\n const patches: DeletePropertyPatch[] = [];\n const uniquePruneKeys = new Set(pruneKeys);\n\n // Only iterate keys to prune\n for (const key of uniquePruneKeys) {\n // Safety invariant: never touch preserved runtime keys\n if (preservedKeys.has(key)) continue;\n\n // Topology Safety:\n // Only target explicit properties verified to exist.\n if (Object.hasOwn(existingProps, key)) {\n patches.push({ operation: 'delete', path: [key] });\n }\n }\n\n return patches;\n}\n","import type { types } from 'estree-toolkit';\nimport { is } from 'estree-toolkit';\n\nimport type {\n StaticDataPatterns,\n PreservedPropStrategy,\n PreservedSubtreeLifecycle,\n ExpressionRefPlaceholder\n} from '../architecture';\n\nimport type { PropertyPath } from '../types';\n\nimport { isKeyPreserved } from '../utils/path-utils';\nimport { createExpressionRef } from '../expression-ref';\nimport { isPlainObject } from '../guards';\nimport { preserveArrayElision } from '../utils/array-utils';\n\nimport { extractPropertyKey } from './key-extractor';\nimport { tryResolveStaticValue } from './static-resolver';\nimport { SKIP_VALUE } from './constants';\n\ntype PreservedExpressionInfo = {\n path: PropertyPath;\n expression: types.Expression;\n};\n\nexport type ExtractOptions = {\n preservedKeys: ReadonlySet<string>;\n onPreservedExpression?: (info: PreservedExpressionInfo) => void;\n};\n\n/**\n * Builds a human-readable path label for diagnostics.\n *\n * Used to produce clear error messages while walking nested props structures.\n * String segments are appended using dot notation, numeric segments use bracket\n * notation.\n *\n * Example:\n * formatPath(\"Component.props\", \"items\") -> \"Component.props.items\"\n * formatPath(\"Component.props.items\", 0) -> \"Component.props.items[0]\"\n * formatPath(\"Component.props.items[0]\", \"id\") -> \"Component.props.items[0].id\"\n *\n * @param base\n * Current path label prefix (e.g. `\"Component.props\"`).\n * @param segment\n * Next segment to append:\n * - `string` for an object key (e.g. `\"items\"`, `\"id\"`)\n * - `number` for an array index (e.g. `0`, `1`)\n * @returns\n * A new path label with `segment` appended.\n */\nexport function formatPath(base: string, segment: string | number): string {\n return typeof segment === 'number'\n ? `${base}[${segment}]`\n : `${base}.${segment}`;\n}\n\n/**\n * POLICY: Strict Integration\n *\n * - Protocol: Enforces **Positional Integrity**.\n * - Behavior: If the value is static, it is added. If dynamic, the **current container** rejects.\n * - Context: Array Strategy (All-or-Nothing).\n *\n * @param target - The results array\n * @param value - The potentially static value\n * @returns `SKIP_VALUE` if integrity is compromised, otherwise `void`\n */\nfunction integrateArrayElement(\n target: unknown[],\n value: unknown | typeof SKIP_VALUE\n): void | typeof SKIP_VALUE {\n if (value === SKIP_VALUE) {\n return SKIP_VALUE;\n }\n target.push(value);\n}\n\n/**\n * POLICY: Selective Integration\n *\n * - Protocol: Enforces **Partial Extraction**.\n * - Behavior: If the value is static, it is included. If dynamic, it is **silently omitted**.\n * - Context: Object Strategy (Best-Effort).\n *\n * @param target - The results object\n * @param key - The property key\n * @param value - The potentially static value\n */\nfunction integrateObjectEntry(\n target: Record<string, unknown>,\n key: string | number,\n value: unknown | typeof SKIP_VALUE\n): void {\n if (value !== SKIP_VALUE) {\n target[key] = value;\n }\n}\n\n/**\n * Arrays (Position-Addressed) -> STRICT POLICY\n * See {@link StaticDataPatterns} for structural definitions.\n *\n * - Goal: Preserve positional integrity.\n * - Rule: If *any* element is dynamic (including spreads), the **entire array**\n * is rejected (returns `SKIP_VALUE`).\n * - Elisions: Preserved as sparse slots (hole ≠ explicit `undefined`).\n * - Rationale: Partial extraction is impossible because missing indices would\n * corrupt the data structure.\n *\n * Control Flow & Propagation:\n * This function implements a \"Fail-Fast\" recursion strategy.\n *\n * 1. Local Abort:\n * Processing of the current array stops immediately.\n * Subsequent elements are ignored as a single dynamic slot invalidates the\n * entire array.\n * - Example: In `[1, dynamic = failure, 2]`\n * -> the failure at index 1 triggers the abort, leaving index 2\n *\n * 2. Upstream Propagation:\n * The abort signal (`SKIP_VALUE`) is returned to the parent frame,\n * triggering the resolution logic for container hierarchies (various\n * Array/Object constellations) reflected in the extractor unit tests.\n * - Parent is **Array**: Triggers a Chain Reaction.\n * -> The parent aborts itself (propagating failure further up).\n * - Parent is **Object**: Triggers Containment.\n * -> The parent omits this key (absorbing failure).\n *\n * 3. Termination Condition (Propagation Boundary):\n * The chain reaction halts only when the signal encounters:\n * - A **Partial Policy** (Object):\n * The container absorbs the failure (omits the key) and returns a valid\n * result, stopping the chain.\n * - The **Public Adapter** (Root):\n * The entry point intercepts the signal and converts it to `null`,\n * enforcing a safe exit.\n *\n * @param expressionNode\n * The ArrayExpression node to decode.\n * @param options\n * Configuration for preserved keys and side-effect callbacks.\n * @param pathLabel\n * Human-readable path label for diagnostics (e.g. `\"props.items\"`).\n * @param pathSegments\n * Logical path segments used for tracing.\n * @returns\n * - The fully resolved static array (if integrity checks pass).\n * - `SKIP_VALUE` (symbol) if *any* element was dynamic (Strict Bailout).\n */\nfunction extractStaticValueFromArrayExpression(\n expressionNode: types.ArrayExpression,\n options: ExtractOptions,\n pathLabel: string,\n pathSegments: PropertyPath\n): unknown[] | typeof SKIP_VALUE {\n const candidate: unknown[] = [];\n\n for (const [index, elementNode] of expressionNode.elements.entries()) {\n /**\n * PHASE 1: STRUCTURAL INTEGRITY (Pre-Recursion)\n * Validate that the slot itself is statically addressable.\n *\n * 1. Check: Elision (Sparse Array Hole)\n * Rationale: A hole is structurally valid in a sparse array; it is not undefined.\n * Action: Preserve the empty slot to maintain index alignment.\n *\n * 2. Check: Spread Element (Structural Violation)\n * Rationale: Spreads make indices non-deterministic at static time.\n * Action: Execute \"Fail-Fast\" abort (see \"Control Flow & Propagation\" above).\n */\n if (elementNode === null) {\n preserveArrayElision(candidate, index);\n continue;\n }\n\n if (is.spreadElement(elementNode)) {\n return SKIP_VALUE;\n }\n\n /**\n * PHASE 2: RECURSION (Value Resolution)\n * The slot is structurally valid. Recursively resolve its content.\n */\n const elementLabel = formatPath(pathLabel, index);\n const elementPath: PropertyPath = [...pathSegments, index];\n\n const extracted = extractStaticValueFromExpression(\n elementNode,\n options,\n elementLabel,\n elementPath\n );\n\n /**\n * PHASE 3: INTEGRATION & SEMANTIC INTEGRITY (Post-Recursion)\n * Enforce the Strict Policy on the resolved value.\n *\n * 1. Check: Dynamic Value (Semantic Violation)\n * Rationale: Arrays require all elements to be static to ensure data integrity.\n * Action: Delegate validation to 'integrateArrayElement' policy.\n *\n * 2. Check: Strict Bailout Signal (SKIP_VALUE returned by policy)\n * Rationale: Positional integrity is compromised; further processing is futile.\n * Action: Execute \"Fail-Fast\" abort (see \"Control Flow & Propagation\" above).\n */\n const integrationStatus = integrateArrayElement(candidate, extracted);\n\n if (integrationStatus === SKIP_VALUE) {\n return SKIP_VALUE;\n }\n }\n\n /**\n * Completion Exit: Static Container Resolved.\n *\n * The candidate has passed all Structural and Semantic checks.\n * (The Strict Policy is satisfied, guaranteeing a valid static array).\n */\n return candidate;\n}\n\n/**\n * Objects (Key-Addressed) -> PARTIAL POLICY\n * See {@link StaticDataPatterns} for structural definitions.\n *\n * - Goal: Extract maximum static subset.\n * - Rule: If a value or key is dynamic, **only that entry** is omitted.\n * - Spreads: Object spreads are skipped; extracted values may not reflect\n * runtime-final values when spreads are present.\n * - Rationale: Keys are structurally independent; skipping dynamic entries\n * yields the best-available static subset.\n *\n * Preservation (Opaque Subtrees)\n * See {@link PreservedPropStrategy}.\n *\n * Keys matching `options.preservedKeys` bypass the static data check.\n * - The raw AST is captured via `onPreservedExpression`.\n * - The static value is substituted by an {@link ExpressionRefPlaceholder} in the result.\n *\n * @param expressionNode\n * The ObjectExpression node to decode.\n * @param options\n * Configuration for preserved keys and side-effect callbacks.\n * @param pathLabel\n * Human-readable path label for diagnostics (e.g. `\"props.style\"`).\n * @param pathSegments\n * Logical path segments used for tracing.\n * @returns\n * The extracted plain object containing the subset of valid static keys.\n * (Always returns an object; never returns `SKIP_VALUE`).\n */\nfunction extractStaticValueFromObjectExpression(\n expressionNode: types.ObjectExpression,\n options: ExtractOptions,\n pathLabel: string,\n pathSegments: PropertyPath\n): Record<string, unknown> {\n const aggregate: Record<string, unknown> = {};\n\n for (const propertyNode of expressionNode.properties) {\n /**\n * PHASE 1: FILTERING (Structural Validation)\n * Identify and skip entries that cannot be statically mapped.\n *\n * 1. Check: Spread Element\n * Rationale: Spreads are not statically addressable keys.\n * Action: Skip entry (Partial Policy).\n *\n * 2. Check: Key Resolution\n * Rationale: A stable static key is required to map the value.\n * Action: Skip entry if key is dynamic (Partial Policy).\n */\n if (is.spreadElement(propertyNode)) {\n continue;\n }\n\n const key = extractPropertyKey(propertyNode);\n if (key === null) {\n continue;\n }\n\n const valueLabel = formatPath(pathLabel, key);\n const valuePath: PropertyPath = [...pathSegments, key];\n\n /**\n * PHASE 2: INTERCEPTION (Alternative Strategy)\n * Handle specific keys defined in options by bypassing standard recursion.\n * (See {@link PreservedSubtreeLifecycle} for the round-trip mechanics).\n *\n * 1. Check: Preserved Key (Opaque Subtree)\n * Rationale: Key is explicitly preserved by configuration.\n * Action: Execute Preservation Strategy (see \"Preservation\" above) and\n * continue.\n */\n if (isKeyPreserved(key, options.preservedKeys)) {\n if (is.expression(propertyNode.value)) {\n options.onPreservedExpression?.({\n path: valuePath,\n expression: propertyNode.value\n });\n }\n aggregate[key] = createExpressionRef(valuePath);\n continue;\n }\n\n /**\n * PHASE 3: RECURSION (Standard Strategy)\n * Attempt to resolve the value statically.\n */\n const extracted = extractStaticValueFromExpression(\n propertyNode.value,\n options,\n valueLabel,\n valuePath\n );\n\n /**\n * PHASE 4: INTEGRATION (Partial Policy)\n * Apply the Selective Integration policy.\n *\n * 1. Check: Value Integration\n * Rationale: Objects allow partial extraction; dynamic values should not\n * invalidate the container.\n * Action: Apply Selective Integration (omit if dynamic, assign if valid).\n */\n integrateObjectEntry(aggregate, key, extracted);\n }\n\n /**\n * Completion Exit: Best-Effort Result.\n *\n * This function always succeeds in returning an object (containing the\n * subset of valid static keys). It never returns {@link SKIP_VALUE}.\n *\n * Containment Effect:\n * By guaranteeing a valid result object (even if empty), this function\n * absorbs internal dynamic failures so they do not propagate upstream.\n *\n * - Upstream Arrays: Prevent \"Strict Propagation\" (the array accepts the\n * partial object as a valid element instead of aborting).\n * - Upstream Objects: Safely assign the partial object to the target key.\n */\n return aggregate;\n}\n\n/**\n * Recursively decodes an ESTree node into a plain static JavaScript value.\n *\n * This function acts as the core engine for converting AST structures (Syntax)\n * into analysis-ready data (Semantics). It enforces a strict separation between\n * \"Static Data\" (extractable) and \"Runtime Logic\" (skipped).\n *\n * Core Mechanisms:\n * 1. Recursive State Machine\n * The function traverses the tree depth-first to enforce the structural rules\n * defined in {@link StaticDataPatterns}.\n * It communicates with upstream callers via two distinct return signals:\n * - Data Payload: A valid JS value (primitive, array, object) indicates success.\n * - `SKIP_VALUE`: A control signal indicating the node is dynamic/unsupported.\n *\n * 2. Container Strategies (Polymorphic Handling)\n * The extraction logic adapts based on the container type:\n * - Arrays: See {@link extractStaticValueFromArrayExpression}.\n * - Objects: See {@link extractStaticValueFromObjectExpression}.\n *\n * 3. Fallthrough (Runtime Logic)\n * Any node not strictly resolvable as data (Identifiers, FunctionCalls, JSX\n * Elements, Binary Expressions) falls through to the default case and\n * returns `SKIP_VALUE`.\n *\n * @param expressionNode\n * The AST node to decode.\n * @param options\n * Configuration for preserved keys and side-effect callbacks.\n * @param pathLabel\n * Human-readable path label for diagnostics (e.g., `\"Component.props.items[0]\"`).\n * @param pathSegments\n * Logical path segments used for tracing.\n * @returns\n * - The extracted static value (if successful).\n * - `SKIP_VALUE` (symbol) if the node or its subtree is dynamic/unsupported.\n */\nexport function extractStaticValueFromExpression(\n expressionNode: types.Node,\n options: ExtractOptions,\n pathLabel: string,\n pathSegments: PropertyPath = []\n): unknown {\n /**\n * 1. Direct expression resolution\n * Attempt deterministic resolution under current rules.\n * - Success: return the resolved value (subtree complete).\n * - Failure: fall through to container logic (arrays/objects) below.\n */\n const staticResolution = tryResolveStaticValue(expressionNode);\n\n /**\n * Note (return early):\n * - Terminal: if resolution succeeds, return the resolver payload for this node.\n * - Recursive: otherwise, continue into the array/object cases below and\n * recurse into their contents.\n */\n if (staticResolution.success) {\n return staticResolution.value;\n }\n\n /**\n * 2. ArrayExpression\n * Details: See {@link extractStaticValueFromArrayExpression}.\n */\n if (is.arrayExpression(expressionNode)) {\n return extractStaticValueFromArrayExpression(\n expressionNode,\n options,\n pathLabel,\n pathSegments\n );\n }\n\n /**\n * 3. ObjectExpression\n * Details: See {@link extractStaticValueFromObjectExpression}.\n */\n if (is.objectExpression(expressionNode)) {\n return extractStaticValueFromObjectExpression(\n expressionNode,\n options,\n pathLabel,\n pathSegments\n );\n }\n\n /**\n * 4. FALLTHROUGH: Dynamic / Unsupported Expression.\n *\n * The node could not be resolved to a static value.\n *\n * RECURSION SIGNAL:\n * Returns {@link SKIP_VALUE}.\n *\n * INTERPRETATION (Upstream Responsibility):\n * - Recursive Containers:\n * Apply Integration Policy (Strict Abort or Partial Omission).\n * - Root Adapter:\n * Applies Safety Policy (Converts signal to `null`).\n */\n return SKIP_VALUE;\n}\n\n/**\n * Extracts a statically-representable object.\n *\n * Adapter for static extraction specific to Component Props.\n * This function exists to ensure the result is a dictionary (a plain object)\n * before it enters validation and patch planning.\n *\n * Return Policy\n * This function returns an object only when both conditions hold:\n *\n * 1. The expression is statically extractable.\n * - If extraction returns {@link SKIP_VALUE}, the input is considered **non-static**\n * under the current extractor rules. This covers:\n * - **Dynamic** expressions (runtime-dependent), and\n * - **Unsupported** expression forms (not yet handled by the static resolver).\n *\n * 2. The extracted value is a plain object.\n *\n * If either condition fails, this function returns `null`.\n *\n * Domain Policy: Use Case Driven (Shape Constraint)\n *\n * - The Restriction:\n * This adapter explicitly rejects Arrays and Primitives, returning `null`.\n * While the generic engine (`extractStaticValueFromExpression`) supports\n * these types, they are invalid here because the target model must\n * structurally be a plain object (dictionary).\n *\n * - The Distinction:\n * This is distinct from the \"Key Type Constraints\" defined in\n * `key-extractor > extractPropertyKey`\n * Key constraints are safety-driven (preventing bugs), whereas this\n * restriction is domain-driven (enforcing the Component data model).\n *\n * @param propsNode\n * ESTree node representing the props expression to extract from.\n * @param options\n * Options forwarded to {@link extractStaticValueFromExpression}.\n * @param pathLabel\n * Human-readable label used for diagnostics (e.g. `\"Component.props\"`).\n * @returns\n * The extracted object, or `null`.\n */\nexport function extractStaticProps(\n propsNode: types.Node,\n options: ExtractOptions,\n pathLabel: string\n): Record<string, unknown> | null {\n const extracted = extractStaticValueFromExpression(\n propsNode,\n options,\n pathLabel\n );\n\n // Non-static root.\n if (extracted === SKIP_VALUE) return null;\n\n // Shape Constraint: See \"Domain Policy\" in JSDoc.\n if (!isPlainObject(extracted)) return null;\n\n return extracted;\n}\n","import type { PropertyPatch } from './types';\nimport { stringifyPropertyPath } from './utils/property-path-key';\n\ntype PreservationCheckOptions = {\n /**\n * Scope of the restriction check:\n * - 'root-only': Only check the top-level property key (e.g. props.children).\n * - 'anywhere': Check all segments in the path (e.g. props.items[0].children).\n */\n scope: 'root-only' | 'anywhere';\n\n /**\n * Label used in error messages to describe the restricted keys\n * (e.g. \"preserved\", \"ignored\", \"restricted\").\n */\n keyTypeLabel: string;\n};\n\n/**\n * Finds the first restricted key in a patch path based on the check scope.\n *\n * @param patch - The patch containing the path to check.\n * @param restrictedKeys - Set of keys that must not be targeted.\n * @param scope - Checking scope determining whether to check root only or any segment.\n * @returns The first restricted key string found, or null if path is valid.\n *\n * @example\n * // Root-only check (depth 0 only)\n * findRestrictedKey({ path: ['children'] }, new Set(['children']), 'root-only');\n * // Returns: 'children'\n *\n * @example\n * // Anywhere check (finds nested violations)\n * findRestrictedKey({ path: ['items', 0, 'children'] }, new Set(['children']), 'anywhere');\n * // Returns: 'children'\n */\nfunction findRestrictedKey(\n patch: PropertyPatch,\n restrictedKeys: ReadonlySet<string>,\n scope: 'root-only' | 'anywhere'\n): string | null {\n if (scope === 'root-only') {\n const [first] = patch.path;\n return typeof first === 'string' && restrictedKeys.has(first)\n ? first\n : null;\n }\n\n for (const segment of patch.path) {\n if (typeof segment === 'string' && restrictedKeys.has(segment)) {\n return segment;\n }\n }\n return null;\n}\n\n/** Helper to capitalize first letter for error messages */\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Asserts that patches respect preservation constraints by not targeting restricted keys.\n * Constructs and throws descriptive error messages when violations are detected,\n * including the full path context for 'anywhere' scope violations.\n *\n * @param patches - Array of patches to validate against preservation constraints.\n * @param restrictedKeys - Set of keys that must not be targeted by any patch.\n * @param componentName - Display name of the component for diagnostic context.\n * @param options - Configuration specifying check scope (root-only/anywhere) and\n * key type label for error message construction.\n * @returns void\n * @throws When any patch targets a restricted key. The error message is\n * dynamically constructed to include:\n * - The key type label (e.g. \"preserved\")\n * - The specific violated key name\n * - The component name\n * - The full JSON path (if scope is 'anywhere')\n */\nexport function assertPatchesRespectPreservation(\n patches: readonly PropertyPatch[],\n restrictedKeys: ReadonlySet<string>,\n componentName: string,\n options: PreservationCheckOptions\n): void {\n for (const patch of patches) {\n const violatedKey = findRestrictedKey(patch, restrictedKeys, options.scope);\n\n // No violation found for this patch\n if (!violatedKey) continue;\n\n // Construct error message dynamically based on scope and options\n const pathDetail =\n options.scope === 'anywhere'\n ? ` at ${stringifyPropertyPath(patch.path)}`\n : '';\n\n const capitalizedLabel = capitalize(options.keyTypeLabel);\n\n throw new Error(\n `[recma] Patch targets ${options.keyTypeLabel} key \"${violatedKey}\"${pathDetail} for ${componentName}. ` +\n `${capitalizedLabel} keys must not be patched as they represent runtime-owned subtrees.`\n );\n }\n}\n","import type {\n BaseProps,\n ComponentSchema,\n DeriveFunction,\n InferOutput,\n SetPropertyPatch\n} from './types';\n\n/**\n * Generates `set` patches from user-defined derivation logic.\n *\n * Computed Derivation (Value Overlay)\n * -----------------------------------\n * This operation executes the `derive` hook defined in the component rule,\n * translating the user's emitted values into AST mutation instructions.\n *\n * Operational Constraints\n * -----------------------\n *\n * DERIVATION (Computed Assignment)\n * - Context: Manual Configuration (Component Rule).\n * - Mechanism: Functional Callback (`deriveFn`).\n * - Rationale: Data Synthesis.\n * Allows the transformation of simple authoring props (e.g. `slug`)\n * into complex runtime props (e.g. `initialState`) that would be\n * tedious or impossible to author manually in JSX.\n * - Policy: ✅ PERMITTED.\n * Authorized because it operates as a \"Value Overlay\". It writes\n * strictly typed values into the AST, relying on the Patcher's\n * safety checks to handle property insertion or overwriting.\n *\n * Execution Flow:\n * 1. Checks if a `derive` hook exists (returns empty if not).\n * 2. Invokes the hook with `derivationInput`.\n * 3. Captures emitted values via the `set` callback.\n * 4. Maps entries to `SetPropertyPatch` instructions.\n *\n * @template Props - The component's props interface.\n * @template S - The schema type used for validation (controls input inference).\n *\n * @param deriveFn - The derivation hook from the rule (optional).\n * @param derivationInput - The input data for the derivation hook.\n * Represents the output of the upstream validation/normalization\n * phase (either schema-coerced data or raw props).\n * @returns Array of patches to apply the derived values.\n */\nexport function collectDerivePatches<\n Props extends BaseProps,\n S extends ComponentSchema = undefined\n>(\n deriveFn: DeriveFunction<Props, S> | undefined,\n derivationInput: InferOutput<S, Props>\n): SetPropertyPatch[] {\n // Fallback Pattern:\n // If no derivation logic is defined, this phase is a no-op.\n if (!deriveFn) return [];\n\n const patches: SetPropertyPatch[] = [];\n\n // Execute the user-defined hook.\n // The `set` callback acts as the collector, buffering values into the patch list.\n deriveFn(derivationInput, values => {\n for (const [key, value] of Object.entries(values)) {\n patches.push({ operation: 'set', path: [key], value });\n }\n });\n\n return patches;\n}\n","import type { Visitors, NodePath, types } from 'estree-toolkit';\nimport type { PluginOptions } from './types';\nimport type {\n ResolveComponentMatch,\n ComponentMatch\n} from './jsx-callsite-resolver';\n\nimport { validateWithSchema } from './validator';\nimport { calculatePatches } from './patch-planner';\nimport { applyPatchesToEstree } from './patcher-object';\nimport { consolidatePatches } from './consolidatePatches';\nimport { reportPatchFailure } from './report';\nimport { planPrunePatches } from './prune-patches';\nimport { extractStaticProps } from './extractor/index';\nimport { assertPatchesRespectPreservation } from './patch-guards';\nimport { stringifyPropertyPath } from './utils/property-path-key';\nimport { collectDerivePatches } from './derive-patches';\n\n/**\n * Processes a single matched component callsite.\n *\n * Pipeline overview\n * -----------------\n * 1. Extract\n * - Decode the props argument expression into a plain JS value.\n * - Preserves configured keys (e.g. `children`) by inserting ExpressionRef placeholders\n * and capturing the original ESTree expressions for later re-inlining.\n *\n * 2. Validate & Transform\n * - Invokes the validation strategy defined by `rule.schema`.\n * - Schema Mode: Validates and transforms extracted props into strict values.\n * - Passthrough Mode: Uses raw extracted props (when schema is undefined).\n * - Result: Canonical `derivationInput` used for diffing and derivation.\n *\n * 3. Plan Patches\n * Conditionally collects patches from three potential sources for\n * consolidation and guarding. All sources are optional; active only when\n * the corresponding rule property is provided (see {@link ComponentRule}):\n *\n * 3.1 Diff patches\n * - Transformation patches representing validation changes (extracted → derivationInput).\n * - Emitted only when Step 2 produces values differing from extraction.\n * - Uses superset view (overlay strategy) to avoid stripping passthrough props.\n *\n * 3.2 Derive patches\n * - Computed assignments from user-defined derivation logic.\n *\n * 3.3 Prune patches\n * - Explicit deletions for configured keys present in source.\n *\n * 3.4 Consolidate patches\n * - Merge/deduplicate: later phases overwrite earlier ones.\n * - Records originating phase per path for diagnostics.\n *\n * 3.5 Assert Preservation Constraints\n * - Defensive assertion ensuring no patch targets preserved keys\n * (keeps runtime subtrees untouched).\n *\n * 4. Apply\n * - Apply consolidated patches to the props ObjectExpression in-place (leaf-only).\n * - Returns unapplied patch keys when the AST shape is non-literal or paths are missing.\n *\n * 5. Report\n * - If anything remains unapplied, report the first unapplied path and include a summary\n * (counts + examples) with provenance via `getPatchPhaseByPathKey`.\n *\n * Control knobs\n * -------------\n * - `options.applyTransforms` toggles write-back (validation-only when false).\n */\nfunction processComponent(\n match: ComponentMatch,\n options: PluginOptions,\n preservedKeys: Set<string>\n) {\n const { componentName, componentRule, propsExpressionPath } = match;\n\n const applyTransforms = options.applyTransforms ?? true;\n\n const propsNode = propsExpressionPath.node;\n if (!propsNode) return;\n\n // Captured original ESTree expressions for preserved runtime subtrees (e.g. `children`).\n const preservedExpressionsByPath = new Map<string, types.Expression>();\n\n // 1. Extract\n const extractedProps = extractStaticProps(\n propsNode,\n {\n preservedKeys,\n onPreservedExpression: info => {\n preservedExpressionsByPath.set(\n stringifyPropertyPath(info.path),\n info.expression\n );\n }\n },\n `${componentName}.props`\n );\n\n // 2. Validate & Transform\n const derivationInput = validateWithSchema(\n componentRule.schema,\n extractedProps,\n componentName\n );\n\n if (!applyTransforms) return;\n\n // 3.1 Diff\n const diffPatches = calculatePatches(\n extractedProps,\n derivationInput,\n preservedKeys\n );\n\n // 3.2 Derive\n const derivedPatches = collectDerivePatches(\n componentRule.derive,\n derivationInput\n );\n\n // 3.3 Prune\n const prunePatches = planPrunePatches(\n extractedProps,\n componentRule.pruneKeys,\n preservedKeys\n );\n\n // 3.4 Consolidate\n const { patches, phaseByPathKey } = consolidatePatches([\n { phase: 'diff', patches: diffPatches },\n { phase: 'derive', patches: derivedPatches },\n { phase: 'prune', patches: prunePatches }\n ]);\n\n // 3.5 Validate preservation constraints\n assertPatchesRespectPreservation(patches, preservedKeys, componentName, {\n scope: 'root-only',\n keyTypeLabel: 'preserved'\n });\n\n if (patches.length === 0) return;\n\n // 4. Apply\n const applyResult = applyPatchesToEstree(\n propsExpressionPath,\n patches,\n preservedKeys,\n {\n expressionRefResolver: ref =>\n preservedExpressionsByPath.get(stringifyPropertyPath(ref.path)) ?? null\n }\n );\n\n // 5. Report\n if (applyResult.firstUnappliedPathKey) {\n reportPatchFailure(applyResult.firstUnappliedPathKey, {\n componentName,\n getPatchPhaseByPathKey: pathKey => phaseByPathKey.get(pathKey),\n summaryContext: {\n remainingSetPathKeys: applyResult.remainingSetPathKeys,\n remainingDeletePathKeys: applyResult.remainingDeletePathKeys\n }\n });\n }\n}\n\n/**\n * Visitor Factory\n * ----------------\n * Composes a callsite resolver and a processor.\n *\n * In this plugin, the resolver is a match-and-extract function:\n * - It checks whether a visited CallExpression is a supported JSX runtime factory call.\n * - On match, it returns a `ComponentMatch` containing the execution context:\n * 1. Identity:\n * The resolved component name (e.g., \"CustomComponent\").\n * 2. Behavior:\n * The active rule configuration (validated registry entry).\n * 3. Target:\n * The `NodePath` pointing to the props argument expression.\n * It serves as both the **extraction source** (reading initial values) and\n * the **mutation target** (applying patches).\n *\n * Example:\n * In `_jsx(Component, { id: \"1\" })`, it targets the `{ id: \"1\" }` object.\n *\n * - On non-match, it returns `null` and the callsite is skipped.\n */\nexport function createScopedVisitor(\n resolveComponentMatch: ResolveComponentMatch,\n options: PluginOptions\n): Visitors<unknown> {\n const preservedKeys = new Set(options.preservedKeys ?? ['children']);\n\n return {\n CallExpression(path: NodePath<types.CallExpression>) {\n // 1. Resolve:\n // Does this callsite match a registered JSX runtime component?\n const match = resolveComponentMatch(path);\n\n // 2. Skip non-matches.\n if (!match) return;\n\n // 3. Process the matched callsite.\n processComponent(match, options, preservedKeys);\n }\n };\n}\n","import type { BaseProps, ComponentSchema } from './primitives';\nimport type { ComponentRule, ComponentRuleBase } from './rules';\n\n/**\n * The generic constraint for rule inference.\n *\n * Purpose:\n * Used by `defineRuleRegistry` to validate the input structure while allowing\n * specific subtypes to pass through via generics.\n *\n * Structure:\n * - Key (`string`):\n * Represents the component name (e.g., \"CustomComponent\").\n * Must match the identifier used in the JSX callsite.\n * - Value ({@link ComponentRuleBase}):\n * The \"Common Denominator\" type for rules.\n * It allows rules with different specific prop interfaces to coexist in the\n * same object because they all satisfy the base contract of operating on an\n * `object`.\n */\nexport type RuleRegistryConstraint = Record<string, ComponentRuleBase>;\n\n/**\n * The concrete registry structure used by the plugin runtime.\n *\n * Purpose:\n * Represents the lookup table used by the component resolver to match AST\n * callsites. Specific prop interfaces are abstracted away at this stage;\n * the runtime relies solely on the structural contract of {@link ComponentRuleBase}\n * to ensure uniform and safe execution.\n */\nexport type RuleMap = RuleRegistryConstraint;\n\n/**\n * Creates the rule registry with strict type inference.\n *\n * Acts as an identity function that validates the input structure against\n * {@link RuleRegistryConstraint} without widening the type. This preserves\n * specific `Props` interfaces for downstream tooling while enforcing the\n * registry contract.\n *\n * @template T - The specific registry shape (inferred).\n * @param registry - The map of component names to rules.\n * @returns The registry object with specific types preserved.\n */\nexport function defineRuleRegistry<T extends RuleRegistryConstraint>(\n registry: T\n): T {\n return registry;\n}\n\n/**\n * Creates a typed rule definition helper for a specific component interface.\n *\n * Implementation Note:\n * Utilizes a curried function pattern to allow explicit definition of the\n * `Props` generic, while automatically inferring the `Schema` type from\n * the provided configuration object.\n *\n * Usage:\n * ```ts\n * defineRule<MyProps>()({\n * schema: MySchema,\n * derive: (props, set) => { ... }\n * })\n * ```\n */\nexport function defineRule<Props extends BaseProps>() {\n return <S extends ComponentSchema = undefined>(\n rule: ComponentRule<Props, S>\n ) => rule;\n}\n\nexport type PluginOptions = {\n /**\n * Defines the behavior rules for each component.\n * Maps component names to their validation, derivation, and pruning logic.\n */\n rules: RuleMap;\n\n /**\n * Controls whether validated values are written back to the compiled output.\n *\n * - `true`: Applies patches to the AST (Transpiler Mode).\n * - `false`: Validates props without modifying the source (Linter / Dry-Run Mode).\n *\n * Scenario: Type Correction\n * - Source: `<Component zIndex=\"50\" />`\n * - Schema: `zIndex` is a number.\n * - `true`: Updates AST to `zIndex={50}`.\n * - `false`: Leaves AST as `zIndex=\"50\"` (throws if validation fails).\n *\n * @default true\n */\n applyTransforms?: boolean;\n\n /**\n * Prop keys identifying **Dynamic Runtime Expressions** (e.g., `children`, `onClick`).\n *\n * Values for these keys are treated as executable code, not static data:\n * - Extraction: Captured as-is; not resolved to static data.\n * - Validation: Passed through via placeholders.\n * - Patching: Protected (traversal stops; the expression remains verbatim).\n *\n * Use this for properties containing variables, functions, or JSX elements.\n *\n * @default ['children']\n */\n preservedKeys?: readonly string[];\n};\n","import type { Plugin, Transformer } from 'unified';\nimport type { Program } from 'estree';\nimport { is, traverse } from 'estree-toolkit';\n\nimport type { PluginOptions } from './types';\nimport { createComponentResolver } from './jsx-callsite-resolver';\nimport { createScopedVisitor } from './visitor';\nexport { defineRule, defineRuleRegistry } from './types';\n\nexport const recmaStaticRefiner: Plugin<[PluginOptions], Program> = options => {\n // 1. Create the callsite resolver.\n // Contract: returns a `ComponentMatch` for supported JSX runtime callsites\n // that target a registered component; otherwise returns `null`.\n const resolveComponentMatch = createComponentResolver(options.rules);\n\n // 2. Create the scoped AST visitor.\n // The visitor uses `resolveComponentMatch` to decide whether a given\n // CallExpression should be processed; non-matches are skipped.\n const visitor = createScopedVisitor(resolveComponentMatch, options);\n\n // 3. Return the unified transformer.\n const transformer: Transformer<Program> = tree => {\n if (!is.program(tree)) return;\n traverse(tree, visitor);\n };\n\n return transformer;\n};\n"]}