Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@editable-jsx/core

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@editable-jsx/core - npm Package Compare versions

Comparing version
0.1.0
to
0.1.1
+20
-2
dist/index.cjs

@@ -325,5 +325,12 @@ "use strict";

resolve(el) {
const file = el.getAttribute("data-astro-source-file");
let file = el.getAttribute("data-astro-source-file");
let loc = el.getAttribute("data-astro-source-loc") || "";
if (!file) {
const astroAnnotations = getAstroAnnotations(el);
if (astroAnnotations) {
file = astroAnnotations.file;
loc = astroAnnotations.location || "";
}
}
if (!file) return null;
const loc = el.getAttribute("data-astro-source-loc") || "";
const [line, col] = loc.split(":").map(Number);

@@ -334,2 +341,13 @@ const label = file.replace(/^.*\/src\//, "src/");

};
function getAstroAnnotations(el) {
try {
const sourceMap = window.__editableSourceMap__;
if (sourceMap) {
return sourceMap.get(el) ?? null;
}
return null;
} catch {
return null;
}
}
var astroCidStrategy = {

@@ -336,0 +354,0 @@ name: "astro-cid",

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts","../src/element.ts","../src/hmr/suppress.ts","../src/patcher/orchestrate.ts","../src/patcher/text-patcher.ts","../src/patcher/patch-types.ts","../src/resolve/source-resolver.ts","../src/editor/expression-field.ts","../src/editor/class-editor.ts","../src/editor/value-source.ts"],"sourcesContent":["export type {\n BasePatch,\n HmrSuppressMap,\n SaveResult,\n SourceLocation,\n} from \"./types.js\"\n\nexport type {\n EditableAttribute,\n EditableClassNamePart,\n EditableCSSProperty,\n EditableCSSVariable,\n EditableProp,\n EditableProperty,\n EditableText,\n ElementNode,\n FrameworkAdapter,\n PropertyChange,\n} from \"./element.js\"\n\nexport { ComponentTree } from \"./element.js\"\n\nexport {\n createHotUpdateHandler,\n createSuppressMap,\n suppressFile,\n} from \"./hmr/suppress.js\"\n\nexport { applyPatches, groupPatchesByFile } from \"./patcher/orchestrate.js\"\n\nexport {\n replaceAtOffset,\n replaceAtPosition,\n replaceNormalized,\n type ReplaceOptions,\n} from \"./patcher/text-patcher.js\"\n\nexport {\n createPatchDispatcher,\n patchFramework,\n type AstroAttrPatch,\n type AstroExprPatch,\n type CSSPropertyPatch,\n type CSSVariablePatch,\n type JSXAttrPatch,\n type JSXClassNamePatch,\n type Patch,\n type PatchRouter,\n type TextPatch,\n} from \"./patcher/patch-types.js\"\n\nexport {\n sourceResolver,\n type ResolvedSource,\n type SourceStrategy,\n} from \"./resolve/source-resolver.js\"\n\nexport {\n createExpressionField,\n inferActiveLiterals,\n type ExpressionChange,\n type ExpressionLiteral,\n} from \"./editor/expression-field.js\"\n\nexport { createClassEditor } from \"./editor/class-editor.js\"\n\nexport {\n createValueSourceIndicator,\n type ValueSource,\n} from \"./editor/value-source.js\"\n","/**\n * Unified element model for editable-jsx.\n *\n * Every framework (React, Astro, raw HTML) produces ElementNodes\n * through a FrameworkAdapter. The editor UI consumes ElementNodes\n * without knowing which framework produced them.\n *\n * Key invariant: every editable element has a SourceLocation that\n * anchors it to a position in a source file. This is what makes\n * save-to-source work across all frameworks.\n */\n\nimport type { BasePatch, SourceLocation } from \"./types.js\"\n\n// ── Editable Property ───────────────────────────────────────────────\n\n/**\n * A single editable property on an element.\n * The `kind` discriminant determines which patcher handles saves.\n */\nexport type EditableProperty =\n | EditableProp\n | EditableCSSProperty\n | EditableCSSVariable\n | EditableText\n | EditableAttribute\n | EditableClassNamePart\n\n/** Component prop (React) */\nexport interface EditableProp {\n kind: \"prop\"\n name: string\n value: unknown\n serializable: boolean\n source: SourceLocation\n}\n\n/** CSS property on a matched rule */\nexport interface EditableCSSProperty {\n kind: \"css-property\"\n name: string\n value: string\n selector: string\n sourceFile: string\n overridden: boolean\n}\n\n/** CSS custom property (variable) */\nexport interface EditableCSSVariable {\n kind: \"css-variable\"\n name: string\n value: string\n resolvedValue: string\n scope: string\n sourceFile: string\n}\n\n/** Text content of an element */\nexport interface EditableText {\n kind: \"text\"\n value: string\n source: SourceLocation\n}\n\n/** HTML/Astro template attribute */\nexport interface EditableAttribute {\n kind: \"attribute\"\n name: string\n value: string\n source: SourceLocation\n}\n\n/** A single string literal inside a className expression (React) */\nexport interface EditableClassNamePart {\n kind: \"classname-part\"\n value: string\n partSource: SourceLocation\n parentSource: SourceLocation\n type: \"static\" | \"conditional\" | \"fallback\" | \"template\"\n}\n\n// ── Element Node ────────────────────────────────────────────────────\n\n/**\n * Universal representation of one editable element.\n * Produced by a FrameworkAdapter from framework-specific data.\n */\nexport interface ElementNode {\n /** Stable identifier within the editor session */\n id: string\n\n /** Human-readable label (tag name, component name) */\n displayName: string\n\n /** Raw HTML tag or component name */\n elementName: string\n\n /** Source location of the opening tag */\n source: SourceLocation\n\n /** Which file this element lives in */\n sourceFile: string\n\n /** Parent component name (null for plain HTML elements) */\n componentName: string | null\n\n /** Framework that produced this node */\n framework: \"react\" | \"astro\" | \"css\" | \"html\"\n\n /** All editable properties */\n properties: EditableProperty[]\n\n /** Tree relationships */\n parentId: string | null\n childIds: string[]\n\n /** Whether this node has unsaved changes */\n dirty: boolean\n\n /** The live DOM node (null for server-only representations) */\n domNode: Element | null\n}\n\n// ── Property Change ─────────────────────────────────────────────────\n\n/** A pending edit — what the user changed but hasn't saved yet. */\nexport interface PropertyChange {\n property: EditableProperty\n newValue: unknown\n}\n\n// ── Component Tree ──────────────────────────────────────────────────\n\n/**\n * Flat registry of ElementNodes with parent/child lookup.\n */\nexport class ComponentTree {\n nodes: Map<string, ElementNode> = new Map()\n\n roots(): ElementNode[] {\n const result: ElementNode[] = []\n for (const node of this.nodes.values()) {\n if (node.parentId === null) result.push(node)\n }\n return result\n }\n\n upsert(node: ElementNode): void {\n this.nodes.set(node.id, node)\n\n // Update parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent && !parent.childIds.includes(node.id)) {\n parent.childIds.push(node.id)\n }\n }\n }\n\n remove(id: string): void {\n const node = this.nodes.get(id)\n if (!node) return\n\n // Remove from parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent) {\n parent.childIds = parent.childIds.filter((cid) => cid !== id)\n }\n }\n\n this.nodes.delete(id)\n }\n\n walk(visitor: (node: ElementNode, depth: number) => void): void {\n const visited = new Set<string>()\n const visit = (node: ElementNode, depth: number) => {\n if (visited.has(node.id)) return\n visited.add(node.id)\n visitor(node, depth)\n for (const childId of node.childIds) {\n const child = this.nodes.get(childId)\n if (child) visit(child, depth + 1)\n }\n }\n for (const root of this.roots()) {\n visit(root, 0)\n }\n }\n\n get(id: string): ElementNode | undefined {\n return this.nodes.get(id)\n }\n\n clear(): void {\n this.nodes.clear()\n }\n}\n\n// ── Framework Adapter ───────────────────────────────────────────────\n\n/**\n * Each framework implements this interface to bridge its native\n * element representation into the unified ElementNode model.\n *\n * The adapter is the ONLY place where framework-specific knowledge lives.\n * The editor UI, component tree, and save orchestration are all\n * framework-agnostic — they work with ElementNodes and PropertyChanges.\n */\nexport interface FrameworkAdapter<NativeElement = unknown, NativePatch extends BasePatch = BasePatch> {\n /** Framework identifier */\n readonly framework: ElementNode[\"framework\"]\n\n /** Convert a native element to the universal ElementNode. */\n toElementNode(native: NativeElement): ElementNode\n\n /** Convert pending property changes to framework-specific patches. */\n toPatches(node: ElementNode, changes: PropertyChange[]): NativePatch[]\n\n /** Apply framework-specific patches to source files (server-side). */\n applyPatches(patches: NativePatch[]): Promise<void>\n\n /** Live preview a property change in the browser (optional). */\n preview?(node: ElementNode, change: PropertyChange): void\n\n /** Revert a live preview (optional). */\n revertPreview?(node: ElementNode, change: PropertyChange): void\n}\n","import type { HmrSuppressMap } from \"../types.js\"\n\n/**\n * Create a new HMR suppression map.\n */\nexport function createSuppressMap(): HmrSuppressMap {\n return new Map()\n}\n\n/**\n * Mark a file for HMR suppression with auto-expiry.\n *\n * Call this after writing a file to prevent the write from\n * triggering an HMR update (feedback loop). The entry auto-expires\n * after `ttlMs` milliseconds to prevent stale entries from\n * permanently suppressing HMR.\n */\nexport function suppressFile(\n map: HmrSuppressMap,\n file: string,\n ttlMs: number = 5000,\n): void {\n const existing = map.get(file)\n if (existing?.timeout) clearTimeout(existing.timeout)\n\n const timeout = setTimeout(() => map.delete(file), ttlMs)\n map.set(file, { skip: true, timeout })\n}\n\n/**\n * Create a Vite `handleHotUpdate` handler that suppresses\n * HMR for files in the suppress map.\n *\n * Returns `[]` (empty module array) to suppress the update,\n * or `undefined` to let it proceed normally.\n */\nexport function createHotUpdateHandler(\n map: HmrSuppressMap,\n): (ctx: { file: string }) => [] | undefined {\n return ({ file }) => {\n const entry = map.get(file)\n if (entry?.skip) {\n map.delete(file)\n return [] // Suppress HMR update\n }\n return undefined\n }\n}\n","/**\n * Shared patch orchestration — groups patches by file and applies them\n * in parallel with error collection.\n *\n * Used by all framework-specific patchers (JSX/ts-morph, CSS/PostCSS, Astro/compiler).\n */\n\n// ── Per-file mutex ─────────────────────────────────────────────────\n\n/**\n * Simple async mutex: serializes access per key (file path).\n * Two concurrent `applyPatches` calls on the same file will\n * be sequenced rather than racing.\n */\nconst fileLocks = new Map<string, Promise<void>>()\n\nasync function withFileLock(\n file: string,\n fn: () => Promise<void>,\n): Promise<void> {\n // Wait for the previous operation on this file (if any)\n const prev = fileLocks.get(file) ?? Promise.resolve()\n\n // Chain our work after the previous promise.\n // We store the chain BEFORE awaiting so the next caller sees us.\n const current = prev.then(fn, fn)\n fileLocks.set(file, current)\n\n try {\n await current\n } finally {\n // Clean up if we're still the tail of the chain\n if (fileLocks.get(file) === current) {\n fileLocks.delete(file)\n }\n }\n}\n\n/**\n * Group patches by file path.\n *\n * The `getFile` callback extracts the file path from a patch,\n * allowing different patch shapes (e.g., `patch.file` vs `patch.source.fileName`).\n */\nexport function groupPatchesByFile<P>(\n patches: P[],\n getFile: (patch: P) => string,\n): Record<string, P[]> {\n return patches.reduce(\n (acc, patch) => {\n const file = getFile(patch)\n ;(acc[file] = acc[file] || []).push(patch)\n return acc\n },\n {} as Record<string, P[]>,\n )\n}\n\n/**\n * Apply patches in parallel, grouped by file.\n *\n * Calls `applyFileFn` for each file group. Collects errors from\n * individual files and throws a combined error if any failed.\n *\n * Per-file access is serialized via an async mutex so that two\n * concurrent `applyPatches` calls on the same file don't race.\n *\n * @param patches - All patches to apply\n * @param getFile - Extracts the file path from a patch\n * @param applyFileFn - Applies patches to a single file\n */\nexport async function applyPatches<P>(\n patches: P[],\n getFile: (patch: P) => string,\n applyFileFn: (file: string, patches: P[]) => Promise<void>,\n): Promise<void> {\n const grouped = groupPatchesByFile(patches, getFile)\n const errors: Array<{ file: string; error: Error }> = []\n\n await Promise.all(\n Object.entries(grouped).map(async ([file, filePatches]) => {\n try {\n await withFileLock(file, () => applyFileFn(file, filePatches))\n } catch (err: any) {\n console.error(`[editable] Failed to apply patches to ${file}:`, err)\n errors.push({ file, error: err })\n }\n }),\n )\n\n if (errors.length > 0) {\n const fileList = errors.map((e) => e.file).join(\", \")\n throw new Error(\n `Patch failed for ${errors.length} file(s): ${fileList}. ${errors[0].error.message}`,\n )\n }\n}\n","/**\n * TextPatcher — surgical string replacement in source files.\n *\n * This is the \"dumb\" layer: it finds text in a source string and\n * replaces it. It does NOT parse any AST — it works on raw strings.\n *\n * Three replacement strategies:\n * 1. Position-based: find text at exact line:col\n * 2. Normalized: collapse whitespace, search with position map\n * 3. Literal: find exact string at a character offset\n *\n * The \"smart\" layer (ASTPatcher) finds WHERE to replace using\n * framework-specific AST parsing. TextPatcher does the actual splice.\n */\n\nexport interface ReplaceOptions {\n /** If true, only match text between > and < (text node context) */\n textNodeOnly?: boolean\n /** Skip the frontmatter region (--- ... ---) */\n skipFrontmatter?: boolean\n /** Skip content inside <style> blocks */\n skipStyleBlocks?: boolean\n}\n\n/**\n * Replace text at an exact character offset in a source string.\n * Used for expression literal replacement and AST-guided edits.\n */\nexport function replaceAtOffset(\n source: string,\n offset: number,\n oldText: string,\n newText: string,\n): string {\n const actual = source.slice(offset, offset + oldText.length)\n if (actual !== oldText) {\n throw new Error(\n `Text mismatch at offset ${offset}: expected \"${oldText.slice(0, 30)}\", found \"${actual.slice(0, 30)}\"`,\n )\n }\n return source.slice(0, offset) + newText + source.slice(offset + oldText.length)\n}\n\n/**\n * Replace text at a specific line and column (1-based).\n * Falls back to normalized search if not found at the exact position.\n */\nexport function replaceAtPosition(\n source: string,\n line: number,\n col: number,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n if (line > 0) {\n const lines = source.split(\"\\n\")\n const lineIdx = line - 1\n if (lineIdx >= 0 && lineIdx < lines.length) {\n const colIdx = Math.max(0, col - 1)\n const foundIdx = lines[lineIdx].indexOf(oldText, colIdx)\n if (foundIdx !== -1) {\n lines[lineIdx] =\n lines[lineIdx].slice(0, foundIdx) +\n newText +\n lines[lineIdx].slice(foundIdx + oldText.length)\n return lines.join(\"\\n\")\n }\n }\n // Position-based failed — fall through to normalized search\n }\n\n return replaceNormalized(source, oldText, newText, options)\n}\n\n/**\n * Replace text using whitespace-normalized matching.\n *\n * DOM textContent collapses whitespace across lines, but the source\n * may have the text split across multiple lines with indentation.\n * This normalizes both sides and maps positions back to the original.\n *\n * Optionally validates that the match is in text-node context\n * (between > and <, not inside an attribute value).\n */\nexport function replaceNormalized(\n source: string,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n const normalizedOld = oldText.replace(/\\s+/g, \" \").trim()\n if (!normalizedOld) {\n throw new Error(\"Cannot search for empty/whitespace-only text\")\n }\n\n // Determine the search region\n let regionStart = 0\n let regionEnd = source.length\n\n if (options.skipFrontmatter) {\n const fmMatch = source.match(/^---\\r?\\n/)\n if (fmMatch) {\n const fmEnd = source.indexOf(\"\\n---\", fmMatch[0].length)\n if (fmEnd !== -1) regionStart = fmEnd + 4\n }\n }\n\n if (options.skipStyleBlocks) {\n const styleStart = source.indexOf(\"<style\", regionStart)\n if (styleStart !== -1) regionEnd = styleStart\n }\n\n const region = source.slice(regionStart, regionEnd)\n\n // Build normalized version with position map\n const posMap: number[] = []\n let normalized = \"\"\n let inWhitespace = false\n\n for (let i = 0; i < region.length; i++) {\n if (/\\s/.test(region[i])) {\n if (!inWhitespace && normalized.length > 0) {\n normalized += \" \"\n posMap.push(i)\n inWhitespace = true\n }\n } else {\n normalized += region[i]\n posMap.push(i)\n inWhitespace = false\n }\n }\n\n // Search for matches\n let searchFrom = 0\n while (true) {\n const matchIdx = normalized.indexOf(normalizedOld, searchFrom)\n if (matchIdx === -1) {\n throw new Error(\n `Text not found in template: \"${oldText.length > 60 ? oldText.slice(0, 60) + \"...\" : oldText}\"`,\n )\n }\n\n const origStart = posMap[matchIdx]\n const matchEndNorm = matchIdx + normalizedOld.length - 1\n const origEnd =\n matchEndNorm < posMap.length ? posMap[matchEndNorm] + 1 : region.length\n\n // Optionally validate text-node context (between > and <)\n if (options.textNodeOnly) {\n const before = region.slice(0, origStart)\n const lastGt = before.lastIndexOf(\">\")\n const lastLt = before.lastIndexOf(\"<\")\n\n if (lastGt <= lastLt) {\n // Inside a tag (attribute context) — skip this match\n searchFrom = matchIdx + 1\n continue\n }\n }\n\n // Replace in the original source\n const absStart = regionStart + origStart\n const absEnd = regionStart + origEnd\n return source.slice(0, absStart) + newText + source.slice(absEnd)\n }\n}\n","/**\n * Unified Patch Schema — all framework patches are routable through\n * a single discriminated union.\n *\n * The action_type prefix determines which framework handler processes\n * the patch:\n * - \"css.*\" → CSS patcher (PostCSS)\n * - \"astro.*\" → Astro patcher (@astrojs/compiler)\n * - \"jsx.*\" → JSX patcher (ts-morph)\n * - \"text.*\" → Text patcher (normalized search)\n *\n * All patches share: action_type + file.\n * Framework-specific data lives in the patch body.\n */\n\nimport type { BasePatch } from \"../types.js\"\n\n// ── CSS Patches ────────────────────────────────────────────────────\n\nexport interface CSSVariablePatch extends BasePatch {\n action_type: \"css.variable\"\n variable: { name: string; value: string; scope: string }\n styleBlockOffset: number\n}\n\nexport interface CSSPropertyPatch extends BasePatch {\n action_type: \"css.property\"\n property: { selector: string; name: string; value: string }\n}\n\n// ── Text Patches ───────────────────────────────────────────────────\n\nexport interface TextPatch extends BasePatch {\n action_type: \"text.replace\"\n oldText: string\n newText: string\n /** Position hint (0 = use normalized search) */\n line: number\n col: number\n}\n\n// ── Astro Patches ──────────────────────────────────────────────────\n\nexport interface AstroAttrPatch extends BasePatch {\n action_type: \"astro.attribute\"\n elementLine: number\n elementCol: number\n attribute: string\n value: string\n}\n\nexport interface AstroExprPatch extends BasePatch {\n action_type: \"astro.expression\"\n elementLine: number\n elementCol: number\n attribute: string\n oldLiteral: string\n newLiteral: string\n literalOffset: number\n}\n\n// ── JSX Patches ────────────────────────────────────────────────────\n\nexport interface JSXAttrPatch extends BasePatch {\n action_type: \"jsx.attribute\"\n source: { lineNumber: number; columnNumber: number }\n path: string\n value: unknown\n}\n\nexport interface JSXClassNamePatch extends BasePatch {\n action_type: \"jsx.classname\"\n source: { lineNumber: number; columnNumber: number }\n partLine: number\n partCol: number\n oldValue: string\n newValue: string\n}\n\n// ── Union ──────────────────────────────────────────────────────────\n\nexport type Patch =\n | CSSVariablePatch\n | CSSPropertyPatch\n | TextPatch\n | AstroAttrPatch\n | AstroExprPatch\n | JSXAttrPatch\n | JSXClassNamePatch\n\n/**\n * Extract the framework prefix from a patch action_type.\n */\nexport function patchFramework(patch: Patch): string {\n return patch.action_type.split(\".\")[0]\n}\n\n/**\n * Route patches to framework-specific handlers.\n */\nexport type PatchRouter = {\n [framework: string]: (file: string, patches: Patch[]) => Promise<void>\n}\n\n/**\n * Create a patch dispatcher that routes patches by framework prefix.\n */\nexport function createPatchDispatcher(router: PatchRouter) {\n return async (file: string, patches: Patch[]): Promise<void> => {\n // Group by framework\n const byFramework = new Map<string, Patch[]>()\n for (const patch of patches) {\n const fw = patchFramework(patch)\n if (!byFramework.has(fw)) byFramework.set(fw, [])\n byFramework.get(fw)!.push(patch)\n }\n\n // Dispatch to framework handlers sequentially (same file)\n for (const [framework, fwPatches] of byFramework) {\n const handler = router[framework]\n if (!handler) {\n console.warn(`[editable] No handler for patch framework: ${framework}`)\n continue\n }\n await handler(file, fwPatches)\n }\n }\n}\n","/**\n * SourceResolver — canonical \"DOM element → source file + position\" resolution.\n *\n * One module, one interface, one fallback chain. Every framework registers\n * its strategies here instead of implementing its own resolution logic.\n *\n * Strategies are tried in priority order until one succeeds:\n * 1. data-editable-* attributes (our annotation transform)\n * 2. data-astro-source-* attributes (Astro's native dev toolbar)\n * 3. data-astro-cid-* → stylesheet → data-vite-dev-id (CID tracing)\n * 4. Framework-specific strategies (registered by adapters)\n *\n * New frameworks (Vue, Svelte) register a strategy once and\n * get source resolution for free.\n */\n\nimport type { SourceLocation } from \"../types.js\"\n\n/**\n * Resolved source information for a DOM element.\n */\nexport interface ResolvedSource extends SourceLocation {\n /** Human-readable label (e.g., \"src/pages/index.astro\") */\n label: string\n /** How the source was resolved */\n strategy: string\n}\n\n/**\n * A strategy for resolving source location from a DOM element.\n * Returns null if it can't resolve.\n */\nexport interface SourceStrategy {\n /** Strategy name for debugging */\n name: string\n /** Priority (lower = tried first) */\n priority: number\n /** Attempt to resolve source for an element */\n resolve(el: Element): ResolvedSource | null\n}\n\n/**\n * Singleton source resolver with pluggable strategies.\n */\nclass SourceResolverImpl {\n private strategies: SourceStrategy[] = []\n\n /**\n * Register a source resolution strategy.\n */\n register(strategy: SourceStrategy): void {\n this.strategies.push(strategy)\n this.strategies.sort((a, b) => a.priority - b.priority)\n }\n\n /**\n * Resolve the source file and position for a DOM element.\n * Tries all strategies in priority order.\n *\n * Also walks up the DOM tree if the exact element has no source.\n */\n resolve(el: Element): ResolvedSource | null {\n // Try the element itself first\n const direct = this.tryResolve(el)\n if (direct) return direct\n\n // Walk up ancestors\n let current = el.parentElement\n while (current) {\n const resolved = this.tryResolve(current)\n if (resolved) return resolved\n current = current.parentElement\n }\n\n return null\n }\n\n private tryResolve(el: Element): ResolvedSource | null {\n for (const strategy of this.strategies) {\n try {\n const result = strategy.resolve(el)\n if (result) return result\n } catch {\n // Strategy failed — try next\n }\n }\n return null\n }\n}\n\n/**\n * The global source resolver instance.\n * Strategies are registered at module initialization time.\n */\nexport const sourceResolver = new SourceResolverImpl()\n\n// ── Built-in strategies ────────────────────────────────────────────\n\n/**\n * Strategy: data-editable-* attributes (injected by our annotation transform)\n */\nexport const editableAttrsStrategy: SourceStrategy = {\n name: \"data-editable\",\n priority: 10,\n resolve(el) {\n const file = el.getAttribute(\"data-editable-file\")\n if (!file) return null\n\n const line = parseInt(el.getAttribute(\"data-editable-line\") || \"0\", 10)\n const col = parseInt(el.getAttribute(\"data-editable-col\") || \"0\", 10)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line, columnNumber: col, label, strategy: \"data-editable\" }\n },\n}\n\n/**\n * Strategy: data-astro-source-* attributes (Astro's native dev toolbar)\n */\nexport const astroSourceStrategy: SourceStrategy = {\n name: \"data-astro-source\",\n priority: 20,\n resolve(el) {\n const file = el.getAttribute(\"data-astro-source-file\")\n if (!file) return null\n\n const loc = el.getAttribute(\"data-astro-source-loc\") || \"\"\n const [line, col] = loc.split(\":\").map(Number)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line || 0, columnNumber: col || 0, label, strategy: \"data-astro-source\" }\n },\n}\n\n/**\n * Strategy: data-astro-cid-* → stylesheet CSS → data-vite-dev-id\n * Traces the Astro scoping CID through stylesheets to find the source file.\n */\nexport const astroCidStrategy: SourceStrategy = {\n name: \"astro-cid\",\n priority: 30,\n resolve(el) {\n // Find the CID attribute on this element or an ancestor\n let cidAttr: string | null = null\n let current: Element | null = el\n while (current) {\n for (const attr of current.attributes) {\n if (attr.name.startsWith(\"data-astro-cid-\")) {\n cidAttr = attr.name\n break\n }\n }\n if (cidAttr) break\n current = current.parentElement\n }\n if (!cidAttr) return null\n\n // Find the <style> tag whose CSS references this CID\n const cidSelector = `[${cidAttr}]`\n for (const style of document.querySelectorAll(\"style[data-vite-dev-id]\")) {\n if ((style.textContent || \"\").includes(cidSelector)) {\n const devId = style.getAttribute(\"data-vite-dev-id\")!\n const file = devId.split(\"?\")[0]\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n return { fileName: file, lineNumber: 0, columnNumber: 0, label, strategy: \"astro-cid\" }\n }\n }\n\n return null\n },\n}\n\n/**\n * Strategy: CSS stylesheet data-vite-dev-id (for CSS source files)\n */\nexport const viteDevIdStrategy: SourceStrategy = {\n name: \"vite-dev-id\",\n priority: 40,\n resolve(_el) {\n // This strategy works on stylesheets, not elements.\n // Used by the CSS inspector separately.\n return null\n },\n}\n\n// Register built-in strategies\nsourceResolver.register(editableAttrsStrategy)\nsourceResolver.register(astroSourceStrategy)\nsourceResolver.register(astroCidStrategy)\n","/**\n * Expression Field — renders an interactive UI for editing string\n * literals inside JavaScript expressions.\n *\n * Given class={active ? \"on\" : \"off\"} with rendered value \"on\", renders:\n *\n * ┌──────────────────────────────────────────────────┐\n * │ active ? [if ✓: on_____] : [else: off____] │\n * │ ACTIVE (green) inactive (dim) │\n * │ [raw] │\n * └──────────────────────────────────────────────────┘\n *\n * The \"active\" state is inferred by comparing the rendered DOM value\n * against each string literal. Literals whose value appears in the\n * rendered output are marked active; others are dimmed.\n *\n * This is framework-agnostic — works for both React JSX and Astro.\n */\n\nexport interface ExpressionLiteral {\n value: string\n offset: number\n quote: string\n context: string\n}\n\nexport interface ExpressionChange {\n offset: number\n oldValue: string\n newValue: string\n}\n\n/**\n * Determine which string literals are \"active\" (present in the rendered value).\n *\n * For class={active ? \"on\" : \"off\"} with rendered \"on\":\n * - \"on\" → active (it's in the output)\n * - \"off\" → inactive (it's not)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base highlight\":\n * - \"base\" → active\n * - \"highlight\" → active (both are in the output)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base\":\n * - \"base\" → active\n * - \"highlight\" → inactive (conditional was false)\n */\nexport function inferActiveLiterals(\n literals: ExpressionLiteral[],\n renderedValue: string,\n): Map<number, boolean> {\n const result = new Map<number, boolean>()\n\n for (const lit of literals) {\n if (!lit.value) {\n // Empty strings are always \"active\" (they don't add anything)\n result.set(lit.offset, true)\n continue\n }\n\n // Check if this literal's value appears in the rendered output.\n // For class values, the rendered output is space-separated classes,\n // so we check if the literal is a substring or if all its classes are present.\n const literalClasses = lit.value.split(/\\s+/).filter(Boolean)\n const renderedClasses = renderedValue.split(/\\s+/).filter(Boolean)\n\n if (literalClasses.length > 0 && literalClasses.every((c) => renderedClasses.includes(c))) {\n result.set(lit.offset, true)\n } else if (renderedValue.includes(lit.value)) {\n // Direct substring match (for non-class attributes)\n result.set(lit.offset, true)\n } else {\n result.set(lit.offset, false)\n }\n }\n\n return result\n}\n\n/**\n * Create an interactive expression editor.\n *\n * @param expression — the raw expression string (between { and })\n * @param literals — the editable string literals extracted from the expression\n * @param renderedValue — the current rendered value from the DOM (null if unknown)\n * @param onChange — called when any literal is edited\n * @returns the DOM element for the editor\n */\nexport function createExpressionField(\n expression: string,\n literals: ExpressionLiteral[],\n renderedValue: string | null,\n onChange: (changes: ExpressionChange[]) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"expr-field\"\n\n // Infer which literals are active\n const activeMap = renderedValue\n ? inferActiveLiterals(literals, renderedValue)\n : null\n\n // Track pending changes\n const pendingChanges = new Map<number, ExpressionChange>()\n\n // ── Structured view ────────────────────────────────────\n\n const structuredView = document.createElement(\"div\")\n structuredView.className = \"expr-structured\"\n\n if (literals.length === 0) {\n // No editable literals — show as read-only\n const readOnly = document.createElement(\"span\")\n readOnly.className = \"expr-readonly\"\n readOnly.textContent = expression\n readOnly.title = \"No editable string literals in this expression\"\n structuredView.appendChild(readOnly)\n } else {\n // Build the interleaved view: code segments + editable fields\n let lastEnd = 0\n\n for (const lit of literals) {\n // Code segment before this literal\n const codeBefore = expression.slice(lastEnd, lit.offset)\n if (codeBefore.trim()) {\n const codeSpan = document.createElement(\"span\")\n codeSpan.className = \"expr-code\"\n codeSpan.textContent = codeBefore.trim()\n structuredView.appendChild(codeSpan)\n }\n\n // Is this literal active (matches rendered value)?\n const isActive = activeMap?.get(lit.offset) ?? null\n\n // Editable field for the string literal\n const field = createLiteralField(lit, isActive, (newValue) => {\n if (newValue !== lit.value) {\n pendingChanges.set(lit.offset, {\n offset: lit.offset,\n oldValue: lit.value,\n newValue,\n })\n } else {\n pendingChanges.delete(lit.offset)\n }\n onChange(Array.from(pendingChanges.values()))\n })\n structuredView.appendChild(field)\n\n // Calculate end of this literal in the expression\n if (lit.quote === \"`\") {\n lastEnd = lit.offset + lit.value.length\n } else {\n lastEnd = lit.offset + lit.value.length + 2 // +2 for quotes\n }\n }\n\n // Trailing code after the last literal\n const trailingCode = expression.slice(lastEnd).trim()\n if (trailingCode) {\n const trailSpan = document.createElement(\"span\")\n trailSpan.className = \"expr-code\"\n trailSpan.textContent = trailingCode\n structuredView.appendChild(trailSpan)\n }\n }\n\n // ── Rendered value indicator ───────────────────────────\n\n if (renderedValue !== null) {\n const rendered = document.createElement(\"div\")\n rendered.className = \"expr-rendered\"\n rendered.title = \"Current rendered value from the DOM\"\n\n const label = document.createElement(\"span\")\n label.className = \"expr-rendered-label\"\n label.textContent = \"rendered:\"\n\n const val = document.createElement(\"span\")\n val.className = \"expr-rendered-value\"\n val.textContent = renderedValue || \"(empty)\"\n\n rendered.appendChild(label)\n rendered.appendChild(val)\n structuredView.insertBefore(rendered, structuredView.firstChild)\n }\n\n // ── Raw view (hidden by default) ───────────────────────\n\n const rawView = document.createElement(\"div\")\n rawView.className = \"expr-raw\"\n rawView.style.display = \"none\"\n\n const rawTextarea = document.createElement(\"textarea\")\n rawTextarea.className = \"text-edit-input\"\n rawTextarea.value = expression\n rawTextarea.rows = Math.min(6, expression.split(\"\\n\").length + 1)\n rawTextarea.style.fontFamily = \"ui-monospace, monospace\"\n rawTextarea.style.fontSize = \"11px\"\n rawView.appendChild(rawTextarea)\n\n // ── Toggle button ──────────────────────────────────────\n\n const toggleRow = document.createElement(\"div\")\n toggleRow.style.cssText =\n \"display:flex;justify-content:flex-end;margin-top:4px\"\n\n const toggleBtn = document.createElement(\"button\")\n toggleBtn.className = \"btn btn-secondary\"\n toggleBtn.style.cssText = \"padding:2px 6px;font-size:10px\"\n toggleBtn.textContent = \"raw\"\n toggleBtn.title = \"Toggle raw expression editing\"\n\n let isRaw = false\n toggleBtn.addEventListener(\"click\", () => {\n isRaw = !isRaw\n structuredView.style.display = isRaw ? \"none\" : \"\"\n rawView.style.display = isRaw ? \"\" : \"none\"\n toggleBtn.textContent = isRaw ? \"visual\" : \"raw\"\n })\n\n toggleRow.appendChild(toggleBtn)\n\n container.appendChild(structuredView)\n container.appendChild(rawView)\n container.appendChild(toggleRow)\n\n return container\n}\n\n/**\n * Create an editable field for a single string literal.\n *\n * @param lit — the literal metadata\n * @param isActive — true if this literal's value is in the rendered DOM output,\n * false if the condition was falsy, null if unknown\n * @param onChange — called when the input value changes\n */\nfunction createLiteralField(\n lit: ExpressionLiteral,\n isActive: boolean | null,\n onChange: (newValue: string) => void,\n): HTMLElement {\n const wrapper = document.createElement(\"span\")\n wrapper.className = \"expr-literal\"\n if (isActive === true) wrapper.classList.add(\"expr-active\")\n if (isActive === false) wrapper.classList.add(\"expr-inactive\")\n wrapper.title = contextLabel(lit.context) +\n (isActive === true ? \" (currently active)\" : \"\") +\n (isActive === false ? \" (currently inactive)\" : \"\")\n\n // Context badge with active indicator\n const badge = document.createElement(\"span\")\n badge.className = \"expr-badge\"\n if (isActive === true) badge.classList.add(\"expr-badge-active\")\n if (isActive === false) badge.classList.add(\"expr-badge-inactive\")\n const indicator = isActive === true ? \"\\u2713 \" : isActive === false ? \"\\u25CB \" : \"\"\n badge.textContent = indicator + shortContextLabel(lit.context)\n wrapper.appendChild(badge)\n\n // The editable input\n const input = document.createElement(\"input\")\n input.className = \"var-input expr-input\"\n if (isActive === false) input.classList.add(\"expr-input-inactive\")\n input.value = lit.value\n input.style.fontSize = \"11px\"\n\n // Auto-size the input to fit content\n const updateWidth = () => {\n const len = Math.max(input.value.length, 3)\n input.style.width = `${len + 1}ch`\n }\n updateWidth()\n\n input.addEventListener(\"input\", updateWidth)\n input.addEventListener(\"change\", () => onChange(input.value))\n\n wrapper.appendChild(input)\n\n return wrapper\n}\n\n/**\n * Human-readable label for the expression context.\n */\nfunction contextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"Value when condition is true\"\n case \"ternary-alternate\":\n return \"Value when condition is false\"\n case \"conditional\":\n return \"Applied when condition is truthy\"\n case \"fallback\":\n return \"Fallback value\"\n case \"call-arg\":\n return \"Function argument\"\n case \"template-static\":\n return \"Static text in template\"\n case \"object-value\":\n return \"Object property value\"\n case \"array-item\":\n return \"Array item\"\n default:\n return \"Editable value\"\n }\n}\n\n/**\n * Short badge label for the context.\n */\nfunction shortContextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"if\"\n case \"ternary-alternate\":\n return \"else\"\n case \"conditional\":\n return \"when\"\n case \"fallback\":\n return \"or\"\n case \"call-arg\":\n return \"arg\"\n case \"template-static\":\n return \"text\"\n case \"object-value\":\n return \"val\"\n case \"array-item\":\n return \"item\"\n default:\n return \"\"\n }\n}\n","/**\n * Class Editor — renders a tag-style editor for space-separated\n * CSS class strings. Each class is shown as a removable tag,\n * and new classes can be added.\n *\n * Given \"rounded-lg border ring-2 ring-blue-500\":\n *\n * ┌─────────────────────────────────────────────────┐\n * │ [rounded-lg ×] [border ×] [ring-2 ×] │\n * │ [ring-blue-500 ×] │\n * │ [+ add class________________________] │\n * └─────────────────────────────────────────────────┘\n *\n * Each tag can be removed (×) or edited (click to select + type).\n * The \"add class\" input lets you type new classes.\n * onChange fires with the full updated class string.\n */\n\n/**\n * Create a class tag editor for a space-separated class string.\n *\n * @param classes — the current class string (e.g., \"rounded-lg border\")\n * @param onChange — called with the updated class string\n * @returns the DOM element for the editor\n */\nexport function createClassEditor(\n classes: string,\n onChange: (newClasses: string) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"class-editor\"\n\n let currentClasses = classes.split(/\\s+/).filter(Boolean)\n\n function render() {\n container.textContent = \"\"\n\n const tagRow = document.createElement(\"div\")\n tagRow.className = \"class-tags\"\n\n for (let i = 0; i < currentClasses.length; i++) {\n const cls = currentClasses[i]\n const tag = createClassTag(cls, {\n onRemove: () => {\n currentClasses.splice(i, 1)\n onChange(currentClasses.join(\" \"))\n render()\n },\n onEdit: (newValue) => {\n if (newValue.trim()) {\n // Handle pasting multiple classes\n const parts = newValue.trim().split(/\\s+/)\n currentClasses.splice(i, 1, ...parts)\n } else {\n currentClasses.splice(i, 1)\n }\n onChange(currentClasses.join(\" \"))\n render()\n },\n })\n tagRow.appendChild(tag)\n }\n\n container.appendChild(tagRow)\n\n // Add class input\n const addInput = document.createElement(\"input\")\n addInput.className = \"var-input class-add-input\"\n addInput.placeholder = \"+ add class\"\n addInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && addInput.value.trim()) {\n const newClasses = addInput.value.trim().split(/\\s+/)\n currentClasses.push(...newClasses)\n onChange(currentClasses.join(\" \"))\n addInput.value = \"\"\n render()\n }\n })\n\n container.appendChild(addInput)\n }\n\n render()\n return container\n}\n\n/**\n * Create a single class tag element.\n */\nfunction createClassTag(\n className: string,\n handlers: {\n onRemove: () => void\n onEdit: (newValue: string) => void\n },\n): HTMLElement {\n const tag = document.createElement(\"span\")\n tag.className = \"class-tag\"\n\n const label = document.createElement(\"span\")\n label.className = \"class-tag-label\"\n label.textContent = className\n label.title = className\n\n // Click to edit\n label.addEventListener(\"dblclick\", () => {\n const input = document.createElement(\"input\")\n input.className = \"class-tag-edit\"\n input.value = className\n input.style.width = `${Math.max(className.length, 3) + 2}ch`\n\n input.addEventListener(\"blur\", () => {\n handlers.onEdit(input.value)\n })\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n handlers.onEdit(input.value)\n }\n if (e.key === \"Escape\") {\n handlers.onEdit(className) // revert\n }\n })\n\n tag.replaceChild(input, label)\n input.focus()\n input.select()\n })\n\n const removeBtn = document.createElement(\"button\")\n removeBtn.className = \"class-tag-remove\"\n removeBtn.textContent = \"\\u00d7\"\n removeBtn.title = `Remove ${className}`\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation()\n handlers.onRemove()\n })\n\n tag.appendChild(label)\n tag.appendChild(removeBtn)\n\n return tag\n}\n","/**\n * Value Source Indicator — shows whether a value came from\n * a string literal, a variable, or a complex expression.\n *\n * For literal: class=\"hero\"\n * → [literal] \"hero\" — editable directly\n *\n * For variable: class={className}\n * → [variable] className → \"hero container\" — edit in source\n *\n * For expression: class={cn(\"base\", active && \"active\")}\n * → [expression] cn(\"base\", ...) — edit string literals\n */\n\nexport type ValueSource = \"literal\" | \"variable\" | \"expression\"\n\n/**\n * Create a value source indicator element.\n *\n * @param source — the source type\n * @param detail — additional context (variable name, expression preview)\n * @returns the DOM element\n */\nexport function createValueSourceIndicator(\n source: ValueSource,\n detail?: string,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"value-source\"\n\n const badge = document.createElement(\"span\")\n badge.className = `value-source-badge ${source}`\n badge.textContent = source\n\n container.appendChild(badge)\n\n if (detail) {\n const detailSpan = document.createElement(\"span\")\n detailSpan.textContent = detail\n detailSpan.style.fontFamily = \"ui-monospace, monospace\"\n container.appendChild(detailSpan)\n }\n\n // Add context-specific hint\n const hint = document.createElement(\"span\")\n hint.style.color = \"#334155\"\n\n switch (source) {\n case \"literal\":\n hint.textContent = \"— editable\"\n break\n case \"variable\":\n hint.textContent = \"— edit in source\"\n break\n case \"expression\":\n hint.textContent = \"— edit string parts\"\n break\n }\n\n container.appendChild(hint)\n\n return container\n}\n"],"mappings":"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","names":[]}
{"version":3,"sources":["../src/index.ts","../src/element.ts","../src/hmr/suppress.ts","../src/patcher/orchestrate.ts","../src/patcher/text-patcher.ts","../src/patcher/patch-types.ts","../src/resolve/source-resolver.ts","../src/editor/expression-field.ts","../src/editor/class-editor.ts","../src/editor/value-source.ts"],"sourcesContent":["export type {\n BasePatch,\n HmrSuppressMap,\n SaveResult,\n SourceLocation,\n} from \"./types.js\"\n\nexport type {\n EditableAttribute,\n EditableClassNamePart,\n EditableCSSProperty,\n EditableCSSVariable,\n EditableProp,\n EditableProperty,\n EditableText,\n ElementNode,\n FrameworkAdapter,\n PropertyChange,\n} from \"./element.js\"\n\nexport { ComponentTree } from \"./element.js\"\n\nexport {\n createHotUpdateHandler,\n createSuppressMap,\n suppressFile,\n} from \"./hmr/suppress.js\"\n\nexport { applyPatches, groupPatchesByFile } from \"./patcher/orchestrate.js\"\n\nexport {\n replaceAtOffset,\n replaceAtPosition,\n replaceNormalized,\n type ReplaceOptions,\n} from \"./patcher/text-patcher.js\"\n\nexport {\n createPatchDispatcher,\n patchFramework,\n type AstroAttrPatch,\n type AstroExprPatch,\n type CSSPropertyPatch,\n type CSSVariablePatch,\n type JSXAttrPatch,\n type JSXClassNamePatch,\n type Patch,\n type PatchRouter,\n type TextPatch,\n} from \"./patcher/patch-types.js\"\n\nexport {\n sourceResolver,\n type ResolvedSource,\n type SourceStrategy,\n} from \"./resolve/source-resolver.js\"\n\nexport {\n createExpressionField,\n inferActiveLiterals,\n type ExpressionChange,\n type ExpressionLiteral,\n} from \"./editor/expression-field.js\"\n\nexport { createClassEditor } from \"./editor/class-editor.js\"\n\nexport {\n createValueSourceIndicator,\n type ValueSource,\n} from \"./editor/value-source.js\"\n","/**\n * Unified element model for editable-jsx.\n *\n * Every framework (React, Astro, raw HTML) produces ElementNodes\n * through a FrameworkAdapter. The editor UI consumes ElementNodes\n * without knowing which framework produced them.\n *\n * Key invariant: every editable element has a SourceLocation that\n * anchors it to a position in a source file. This is what makes\n * save-to-source work across all frameworks.\n */\n\nimport type { BasePatch, SourceLocation } from \"./types.js\"\n\n// ── Editable Property ───────────────────────────────────────────────\n\n/**\n * A single editable property on an element.\n * The `kind` discriminant determines which patcher handles saves.\n */\nexport type EditableProperty =\n | EditableProp\n | EditableCSSProperty\n | EditableCSSVariable\n | EditableText\n | EditableAttribute\n | EditableClassNamePart\n\n/** Component prop (React) */\nexport interface EditableProp {\n kind: \"prop\"\n name: string\n value: unknown\n serializable: boolean\n source: SourceLocation\n}\n\n/** CSS property on a matched rule */\nexport interface EditableCSSProperty {\n kind: \"css-property\"\n name: string\n value: string\n selector: string\n sourceFile: string\n overridden: boolean\n}\n\n/** CSS custom property (variable) */\nexport interface EditableCSSVariable {\n kind: \"css-variable\"\n name: string\n value: string\n resolvedValue: string\n scope: string\n sourceFile: string\n}\n\n/** Text content of an element */\nexport interface EditableText {\n kind: \"text\"\n value: string\n source: SourceLocation\n}\n\n/** HTML/Astro template attribute */\nexport interface EditableAttribute {\n kind: \"attribute\"\n name: string\n value: string\n source: SourceLocation\n}\n\n/** A single string literal inside a className expression (React) */\nexport interface EditableClassNamePart {\n kind: \"classname-part\"\n value: string\n partSource: SourceLocation\n parentSource: SourceLocation\n type: \"static\" | \"conditional\" | \"fallback\" | \"template\"\n}\n\n// ── Element Node ────────────────────────────────────────────────────\n\n/**\n * Universal representation of one editable element.\n * Produced by a FrameworkAdapter from framework-specific data.\n */\nexport interface ElementNode {\n /** Stable identifier within the editor session */\n id: string\n\n /** Human-readable label (tag name, component name) */\n displayName: string\n\n /** Raw HTML tag or component name */\n elementName: string\n\n /** Source location of the opening tag */\n source: SourceLocation\n\n /** Which file this element lives in */\n sourceFile: string\n\n /** Parent component name (null for plain HTML elements) */\n componentName: string | null\n\n /** Framework that produced this node */\n framework: \"react\" | \"astro\" | \"css\" | \"html\"\n\n /** All editable properties */\n properties: EditableProperty[]\n\n /** Tree relationships */\n parentId: string | null\n childIds: string[]\n\n /** Whether this node has unsaved changes */\n dirty: boolean\n\n /** The live DOM node (null for server-only representations) */\n domNode: Element | null\n}\n\n// ── Property Change ─────────────────────────────────────────────────\n\n/** A pending edit — what the user changed but hasn't saved yet. */\nexport interface PropertyChange {\n property: EditableProperty\n newValue: unknown\n}\n\n// ── Component Tree ──────────────────────────────────────────────────\n\n/**\n * Flat registry of ElementNodes with parent/child lookup.\n */\nexport class ComponentTree {\n nodes: Map<string, ElementNode> = new Map()\n\n roots(): ElementNode[] {\n const result: ElementNode[] = []\n for (const node of this.nodes.values()) {\n if (node.parentId === null) result.push(node)\n }\n return result\n }\n\n upsert(node: ElementNode): void {\n this.nodes.set(node.id, node)\n\n // Update parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent && !parent.childIds.includes(node.id)) {\n parent.childIds.push(node.id)\n }\n }\n }\n\n remove(id: string): void {\n const node = this.nodes.get(id)\n if (!node) return\n\n // Remove from parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent) {\n parent.childIds = parent.childIds.filter((cid) => cid !== id)\n }\n }\n\n this.nodes.delete(id)\n }\n\n walk(visitor: (node: ElementNode, depth: number) => void): void {\n const visited = new Set<string>()\n const visit = (node: ElementNode, depth: number) => {\n if (visited.has(node.id)) return\n visited.add(node.id)\n visitor(node, depth)\n for (const childId of node.childIds) {\n const child = this.nodes.get(childId)\n if (child) visit(child, depth + 1)\n }\n }\n for (const root of this.roots()) {\n visit(root, 0)\n }\n }\n\n get(id: string): ElementNode | undefined {\n return this.nodes.get(id)\n }\n\n clear(): void {\n this.nodes.clear()\n }\n}\n\n// ── Framework Adapter ───────────────────────────────────────────────\n\n/**\n * Each framework implements this interface to bridge its native\n * element representation into the unified ElementNode model.\n *\n * The adapter is the ONLY place where framework-specific knowledge lives.\n * The editor UI, component tree, and save orchestration are all\n * framework-agnostic — they work with ElementNodes and PropertyChanges.\n */\nexport interface FrameworkAdapter<NativeElement = unknown, NativePatch extends BasePatch = BasePatch> {\n /** Framework identifier */\n readonly framework: ElementNode[\"framework\"]\n\n /** Convert a native element to the universal ElementNode. */\n toElementNode(native: NativeElement): ElementNode\n\n /** Convert pending property changes to framework-specific patches. */\n toPatches(node: ElementNode, changes: PropertyChange[]): NativePatch[]\n\n /** Apply framework-specific patches to source files (server-side). */\n applyPatches(patches: NativePatch[]): Promise<void>\n\n /** Live preview a property change in the browser (optional). */\n preview?(node: ElementNode, change: PropertyChange): void\n\n /** Revert a live preview (optional). */\n revertPreview?(node: ElementNode, change: PropertyChange): void\n}\n","import type { HmrSuppressMap } from \"../types.js\"\n\n/**\n * Create a new HMR suppression map.\n */\nexport function createSuppressMap(): HmrSuppressMap {\n return new Map()\n}\n\n/**\n * Mark a file for HMR suppression with auto-expiry.\n *\n * Call this after writing a file to prevent the write from\n * triggering an HMR update (feedback loop). The entry auto-expires\n * after `ttlMs` milliseconds to prevent stale entries from\n * permanently suppressing HMR.\n */\nexport function suppressFile(\n map: HmrSuppressMap,\n file: string,\n ttlMs: number = 5000,\n): void {\n const existing = map.get(file)\n if (existing?.timeout) clearTimeout(existing.timeout)\n\n const timeout = setTimeout(() => map.delete(file), ttlMs)\n map.set(file, { skip: true, timeout })\n}\n\n/**\n * Create a Vite `handleHotUpdate` handler that suppresses\n * HMR for files in the suppress map.\n *\n * Returns `[]` (empty module array) to suppress the update,\n * or `undefined` to let it proceed normally.\n */\nexport function createHotUpdateHandler(\n map: HmrSuppressMap,\n): (ctx: { file: string }) => [] | undefined {\n return ({ file }) => {\n const entry = map.get(file)\n if (entry?.skip) {\n map.delete(file)\n return [] // Suppress HMR update\n }\n return undefined\n }\n}\n","/**\n * Shared patch orchestration — groups patches by file and applies them\n * in parallel with error collection.\n *\n * Used by all framework-specific patchers (JSX/ts-morph, CSS/PostCSS, Astro/compiler).\n */\n\n// ── Per-file mutex ─────────────────────────────────────────────────\n\n/**\n * Simple async mutex: serializes access per key (file path).\n * Two concurrent `applyPatches` calls on the same file will\n * be sequenced rather than racing.\n */\nconst fileLocks = new Map<string, Promise<void>>()\n\nasync function withFileLock(\n file: string,\n fn: () => Promise<void>,\n): Promise<void> {\n // Wait for the previous operation on this file (if any)\n const prev = fileLocks.get(file) ?? Promise.resolve()\n\n // Chain our work after the previous promise.\n // We store the chain BEFORE awaiting so the next caller sees us.\n const current = prev.then(fn, fn)\n fileLocks.set(file, current)\n\n try {\n await current\n } finally {\n // Clean up if we're still the tail of the chain\n if (fileLocks.get(file) === current) {\n fileLocks.delete(file)\n }\n }\n}\n\n/**\n * Group patches by file path.\n *\n * The `getFile` callback extracts the file path from a patch,\n * allowing different patch shapes (e.g., `patch.file` vs `patch.source.fileName`).\n */\nexport function groupPatchesByFile<P>(\n patches: P[],\n getFile: (patch: P) => string,\n): Record<string, P[]> {\n return patches.reduce(\n (acc, patch) => {\n const file = getFile(patch)\n ;(acc[file] = acc[file] || []).push(patch)\n return acc\n },\n {} as Record<string, P[]>,\n )\n}\n\n/**\n * Apply patches in parallel, grouped by file.\n *\n * Calls `applyFileFn` for each file group. Collects errors from\n * individual files and throws a combined error if any failed.\n *\n * Per-file access is serialized via an async mutex so that two\n * concurrent `applyPatches` calls on the same file don't race.\n *\n * @param patches - All patches to apply\n * @param getFile - Extracts the file path from a patch\n * @param applyFileFn - Applies patches to a single file\n */\nexport async function applyPatches<P>(\n patches: P[],\n getFile: (patch: P) => string,\n applyFileFn: (file: string, patches: P[]) => Promise<void>,\n): Promise<void> {\n const grouped = groupPatchesByFile(patches, getFile)\n const errors: Array<{ file: string; error: Error }> = []\n\n await Promise.all(\n Object.entries(grouped).map(async ([file, filePatches]) => {\n try {\n await withFileLock(file, () => applyFileFn(file, filePatches))\n } catch (err: any) {\n console.error(`[editable] Failed to apply patches to ${file}:`, err)\n errors.push({ file, error: err })\n }\n }),\n )\n\n if (errors.length > 0) {\n const fileList = errors.map((e) => e.file).join(\", \")\n throw new Error(\n `Patch failed for ${errors.length} file(s): ${fileList}. ${errors[0].error.message}`,\n )\n }\n}\n","/**\n * TextPatcher — surgical string replacement in source files.\n *\n * This is the \"dumb\" layer: it finds text in a source string and\n * replaces it. It does NOT parse any AST — it works on raw strings.\n *\n * Three replacement strategies:\n * 1. Position-based: find text at exact line:col\n * 2. Normalized: collapse whitespace, search with position map\n * 3. Literal: find exact string at a character offset\n *\n * The \"smart\" layer (ASTPatcher) finds WHERE to replace using\n * framework-specific AST parsing. TextPatcher does the actual splice.\n */\n\nexport interface ReplaceOptions {\n /** If true, only match text between > and < (text node context) */\n textNodeOnly?: boolean\n /** Skip the frontmatter region (--- ... ---) */\n skipFrontmatter?: boolean\n /** Skip content inside <style> blocks */\n skipStyleBlocks?: boolean\n}\n\n/**\n * Replace text at an exact character offset in a source string.\n * Used for expression literal replacement and AST-guided edits.\n */\nexport function replaceAtOffset(\n source: string,\n offset: number,\n oldText: string,\n newText: string,\n): string {\n const actual = source.slice(offset, offset + oldText.length)\n if (actual !== oldText) {\n throw new Error(\n `Text mismatch at offset ${offset}: expected \"${oldText.slice(0, 30)}\", found \"${actual.slice(0, 30)}\"`,\n )\n }\n return source.slice(0, offset) + newText + source.slice(offset + oldText.length)\n}\n\n/**\n * Replace text at a specific line and column (1-based).\n * Falls back to normalized search if not found at the exact position.\n */\nexport function replaceAtPosition(\n source: string,\n line: number,\n col: number,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n if (line > 0) {\n const lines = source.split(\"\\n\")\n const lineIdx = line - 1\n if (lineIdx >= 0 && lineIdx < lines.length) {\n const colIdx = Math.max(0, col - 1)\n const foundIdx = lines[lineIdx].indexOf(oldText, colIdx)\n if (foundIdx !== -1) {\n lines[lineIdx] =\n lines[lineIdx].slice(0, foundIdx) +\n newText +\n lines[lineIdx].slice(foundIdx + oldText.length)\n return lines.join(\"\\n\")\n }\n }\n // Position-based failed — fall through to normalized search\n }\n\n return replaceNormalized(source, oldText, newText, options)\n}\n\n/**\n * Replace text using whitespace-normalized matching.\n *\n * DOM textContent collapses whitespace across lines, but the source\n * may have the text split across multiple lines with indentation.\n * This normalizes both sides and maps positions back to the original.\n *\n * Optionally validates that the match is in text-node context\n * (between > and <, not inside an attribute value).\n */\nexport function replaceNormalized(\n source: string,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n const normalizedOld = oldText.replace(/\\s+/g, \" \").trim()\n if (!normalizedOld) {\n throw new Error(\"Cannot search for empty/whitespace-only text\")\n }\n\n // Determine the search region\n let regionStart = 0\n let regionEnd = source.length\n\n if (options.skipFrontmatter) {\n const fmMatch = source.match(/^---\\r?\\n/)\n if (fmMatch) {\n const fmEnd = source.indexOf(\"\\n---\", fmMatch[0].length)\n if (fmEnd !== -1) regionStart = fmEnd + 4\n }\n }\n\n if (options.skipStyleBlocks) {\n const styleStart = source.indexOf(\"<style\", regionStart)\n if (styleStart !== -1) regionEnd = styleStart\n }\n\n const region = source.slice(regionStart, regionEnd)\n\n // Build normalized version with position map\n const posMap: number[] = []\n let normalized = \"\"\n let inWhitespace = false\n\n for (let i = 0; i < region.length; i++) {\n if (/\\s/.test(region[i])) {\n if (!inWhitespace && normalized.length > 0) {\n normalized += \" \"\n posMap.push(i)\n inWhitespace = true\n }\n } else {\n normalized += region[i]\n posMap.push(i)\n inWhitespace = false\n }\n }\n\n // Search for matches\n let searchFrom = 0\n while (true) {\n const matchIdx = normalized.indexOf(normalizedOld, searchFrom)\n if (matchIdx === -1) {\n throw new Error(\n `Text not found in template: \"${oldText.length > 60 ? oldText.slice(0, 60) + \"...\" : oldText}\"`,\n )\n }\n\n const origStart = posMap[matchIdx]\n const matchEndNorm = matchIdx + normalizedOld.length - 1\n const origEnd =\n matchEndNorm < posMap.length ? posMap[matchEndNorm] + 1 : region.length\n\n // Optionally validate text-node context (between > and <)\n if (options.textNodeOnly) {\n const before = region.slice(0, origStart)\n const lastGt = before.lastIndexOf(\">\")\n const lastLt = before.lastIndexOf(\"<\")\n\n if (lastGt <= lastLt) {\n // Inside a tag (attribute context) — skip this match\n searchFrom = matchIdx + 1\n continue\n }\n }\n\n // Replace in the original source\n const absStart = regionStart + origStart\n const absEnd = regionStart + origEnd\n return source.slice(0, absStart) + newText + source.slice(absEnd)\n }\n}\n","/**\n * Unified Patch Schema — all framework patches are routable through\n * a single discriminated union.\n *\n * The action_type prefix determines which framework handler processes\n * the patch:\n * - \"css.*\" → CSS patcher (PostCSS)\n * - \"astro.*\" → Astro patcher (@astrojs/compiler)\n * - \"jsx.*\" → JSX patcher (ts-morph)\n * - \"text.*\" → Text patcher (normalized search)\n *\n * All patches share: action_type + file.\n * Framework-specific data lives in the patch body.\n */\n\nimport type { BasePatch } from \"../types.js\"\n\n// ── CSS Patches ────────────────────────────────────────────────────\n\nexport interface CSSVariablePatch extends BasePatch {\n action_type: \"css.variable\"\n variable: { name: string; value: string; scope: string }\n styleBlockOffset: number\n}\n\nexport interface CSSPropertyPatch extends BasePatch {\n action_type: \"css.property\"\n property: { selector: string; name: string; value: string }\n}\n\n// ── Text Patches ───────────────────────────────────────────────────\n\nexport interface TextPatch extends BasePatch {\n action_type: \"text.replace\"\n oldText: string\n newText: string\n /** Position hint (0 = use normalized search) */\n line: number\n col: number\n}\n\n// ── Astro Patches ──────────────────────────────────────────────────\n\nexport interface AstroAttrPatch extends BasePatch {\n action_type: \"astro.attribute\"\n elementLine: number\n elementCol: number\n attribute: string\n value: string\n}\n\nexport interface AstroExprPatch extends BasePatch {\n action_type: \"astro.expression\"\n elementLine: number\n elementCol: number\n attribute: string\n oldLiteral: string\n newLiteral: string\n literalOffset: number\n}\n\n// ── JSX Patches ────────────────────────────────────────────────────\n\nexport interface JSXAttrPatch extends BasePatch {\n action_type: \"jsx.attribute\"\n source: { lineNumber: number; columnNumber: number }\n path: string\n value: unknown\n}\n\nexport interface JSXClassNamePatch extends BasePatch {\n action_type: \"jsx.classname\"\n source: { lineNumber: number; columnNumber: number }\n partLine: number\n partCol: number\n oldValue: string\n newValue: string\n}\n\n// ── Union ──────────────────────────────────────────────────────────\n\nexport type Patch =\n | CSSVariablePatch\n | CSSPropertyPatch\n | TextPatch\n | AstroAttrPatch\n | AstroExprPatch\n | JSXAttrPatch\n | JSXClassNamePatch\n\n/**\n * Extract the framework prefix from a patch action_type.\n */\nexport function patchFramework(patch: Patch): string {\n return patch.action_type.split(\".\")[0]\n}\n\n/**\n * Route patches to framework-specific handlers.\n */\nexport type PatchRouter = {\n [framework: string]: (file: string, patches: Patch[]) => Promise<void>\n}\n\n/**\n * Create a patch dispatcher that routes patches by framework prefix.\n */\nexport function createPatchDispatcher(router: PatchRouter) {\n return async (file: string, patches: Patch[]): Promise<void> => {\n // Group by framework\n const byFramework = new Map<string, Patch[]>()\n for (const patch of patches) {\n const fw = patchFramework(patch)\n if (!byFramework.has(fw)) byFramework.set(fw, [])\n byFramework.get(fw)!.push(patch)\n }\n\n // Dispatch to framework handlers sequentially (same file)\n for (const [framework, fwPatches] of byFramework) {\n const handler = router[framework]\n if (!handler) {\n console.warn(`[editable] No handler for patch framework: ${framework}`)\n continue\n }\n await handler(file, fwPatches)\n }\n }\n}\n","/**\n * SourceResolver — canonical \"DOM element → source file + position\" resolution.\n *\n * One module, one interface, one fallback chain. Every framework registers\n * its strategies here instead of implementing its own resolution logic.\n *\n * Strategies are tried in priority order until one succeeds:\n * 1. data-editable-* attributes (our annotation transform)\n * 2. data-astro-source-* attributes (Astro's native dev toolbar)\n * 3. data-astro-cid-* → stylesheet → data-vite-dev-id (CID tracing)\n * 4. Framework-specific strategies (registered by adapters)\n *\n * New frameworks (Vue, Svelte) register a strategy once and\n * get source resolution for free.\n */\n\nimport type { SourceLocation } from \"../types.js\"\n\n/**\n * Resolved source information for a DOM element.\n */\nexport interface ResolvedSource extends SourceLocation {\n /** Human-readable label (e.g., \"src/pages/index.astro\") */\n label: string\n /** How the source was resolved */\n strategy: string\n}\n\n/**\n * A strategy for resolving source location from a DOM element.\n * Returns null if it can't resolve.\n */\nexport interface SourceStrategy {\n /** Strategy name for debugging */\n name: string\n /** Priority (lower = tried first) */\n priority: number\n /** Attempt to resolve source for an element */\n resolve(el: Element): ResolvedSource | null\n}\n\n/**\n * Singleton source resolver with pluggable strategies.\n */\nclass SourceResolverImpl {\n private strategies: SourceStrategy[] = []\n\n /**\n * Register a source resolution strategy.\n */\n register(strategy: SourceStrategy): void {\n this.strategies.push(strategy)\n this.strategies.sort((a, b) => a.priority - b.priority)\n }\n\n /**\n * Resolve the source file and position for a DOM element.\n * Tries all strategies in priority order.\n *\n * Also walks up the DOM tree if the exact element has no source.\n */\n resolve(el: Element): ResolvedSource | null {\n // Try the element itself first\n const direct = this.tryResolve(el)\n if (direct) return direct\n\n // Walk up ancestors\n let current = el.parentElement\n while (current) {\n const resolved = this.tryResolve(current)\n if (resolved) return resolved\n current = current.parentElement\n }\n\n return null\n }\n\n private tryResolve(el: Element): ResolvedSource | null {\n for (const strategy of this.strategies) {\n try {\n const result = strategy.resolve(el)\n if (result) return result\n } catch {\n // Strategy failed — try next\n }\n }\n return null\n }\n}\n\n/**\n * The global source resolver instance.\n * Strategies are registered at module initialization time.\n */\nexport const sourceResolver = new SourceResolverImpl()\n\n// ── Built-in strategies ────────────────────────────────────────────\n\n/**\n * Strategy: data-editable-* attributes (injected by our annotation transform)\n */\nexport const editableAttrsStrategy: SourceStrategy = {\n name: \"data-editable\",\n priority: 10,\n resolve(el) {\n const file = el.getAttribute(\"data-editable-file\")\n if (!file) return null\n\n const line = parseInt(el.getAttribute(\"data-editable-line\") || \"0\", 10)\n const col = parseInt(el.getAttribute(\"data-editable-col\") || \"0\", 10)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line, columnNumber: col, label, strategy: \"data-editable\" }\n },\n}\n\n/**\n * Strategy: data-astro-source-* attributes (Astro's native dev toolbar)\n *\n * IMPORTANT: Astro's dev toolbar STRIPS these attributes from the DOM\n * after page load and stores them in a WeakMap. We check both:\n * 1. The DOM attribute (if it hasn't been stripped yet)\n * 2. Astro's internal WeakMap via getAnnotationsForElement()\n */\nexport const astroSourceStrategy: SourceStrategy = {\n name: \"data-astro-source\",\n priority: 20,\n resolve(el) {\n // 1. Try DOM attributes directly (may already be stripped)\n let file = el.getAttribute(\"data-astro-source-file\")\n let loc = el.getAttribute(\"data-astro-source-loc\") || \"\"\n\n // 2. If stripped, try Astro's internal annotation WeakMap\n if (!file) {\n const astroAnnotations = getAstroAnnotations(el)\n if (astroAnnotations) {\n file = astroAnnotations.file\n loc = astroAnnotations.location || \"\"\n }\n }\n\n if (!file) return null\n\n const [line, col] = loc.split(\":\").map(Number)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line || 0, columnNumber: col || 0, label, strategy: \"data-astro-source\" }\n },\n}\n\n/**\n * Read captured Astro source annotations for an element.\n *\n * Astro's dev toolbar STRIPS data-astro-source-file/loc from the DOM\n * after page load. We capture them before Astro does via an early\n * head-inline script that stores them in window.__editableSourceMap__.\n */\nfunction getAstroAnnotations(\n el: Element,\n): { file: string; location: string } | null {\n try {\n // Read from our pre-captured Map (injected by @editable-jsx/astro)\n const sourceMap = (window as any).__editableSourceMap__ as\n | Map<Element, { file: string; location: string }>\n | undefined\n if (sourceMap) {\n return sourceMap.get(el) ?? null\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Strategy: data-astro-cid-* → stylesheet CSS → data-vite-dev-id\n * Traces the Astro scoping CID through stylesheets to find the source file.\n */\nexport const astroCidStrategy: SourceStrategy = {\n name: \"astro-cid\",\n priority: 30,\n resolve(el) {\n // Find the CID attribute on this element or an ancestor\n let cidAttr: string | null = null\n let current: Element | null = el\n while (current) {\n for (const attr of current.attributes) {\n if (attr.name.startsWith(\"data-astro-cid-\")) {\n cidAttr = attr.name\n break\n }\n }\n if (cidAttr) break\n current = current.parentElement\n }\n if (!cidAttr) return null\n\n // Find the <style> tag whose CSS references this CID\n const cidSelector = `[${cidAttr}]`\n for (const style of document.querySelectorAll(\"style[data-vite-dev-id]\")) {\n if ((style.textContent || \"\").includes(cidSelector)) {\n const devId = style.getAttribute(\"data-vite-dev-id\")!\n const file = devId.split(\"?\")[0]\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n return { fileName: file, lineNumber: 0, columnNumber: 0, label, strategy: \"astro-cid\" }\n }\n }\n\n return null\n },\n}\n\n/**\n * Strategy: CSS stylesheet data-vite-dev-id (for CSS source files)\n */\nexport const viteDevIdStrategy: SourceStrategy = {\n name: \"vite-dev-id\",\n priority: 40,\n resolve(_el) {\n // This strategy works on stylesheets, not elements.\n // Used by the CSS inspector separately.\n return null\n },\n}\n\n// Register built-in strategies\nsourceResolver.register(editableAttrsStrategy)\nsourceResolver.register(astroSourceStrategy)\nsourceResolver.register(astroCidStrategy)\n","/**\n * Expression Field — renders an interactive UI for editing string\n * literals inside JavaScript expressions.\n *\n * Given class={active ? \"on\" : \"off\"} with rendered value \"on\", renders:\n *\n * ┌──────────────────────────────────────────────────┐\n * │ active ? [if ✓: on_____] : [else: off____] │\n * │ ACTIVE (green) inactive (dim) │\n * │ [raw] │\n * └──────────────────────────────────────────────────┘\n *\n * The \"active\" state is inferred by comparing the rendered DOM value\n * against each string literal. Literals whose value appears in the\n * rendered output are marked active; others are dimmed.\n *\n * This is framework-agnostic — works for both React JSX and Astro.\n */\n\nexport interface ExpressionLiteral {\n value: string\n offset: number\n quote: string\n context: string\n}\n\nexport interface ExpressionChange {\n offset: number\n oldValue: string\n newValue: string\n}\n\n/**\n * Determine which string literals are \"active\" (present in the rendered value).\n *\n * For class={active ? \"on\" : \"off\"} with rendered \"on\":\n * - \"on\" → active (it's in the output)\n * - \"off\" → inactive (it's not)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base highlight\":\n * - \"base\" → active\n * - \"highlight\" → active (both are in the output)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base\":\n * - \"base\" → active\n * - \"highlight\" → inactive (conditional was false)\n */\nexport function inferActiveLiterals(\n literals: ExpressionLiteral[],\n renderedValue: string,\n): Map<number, boolean> {\n const result = new Map<number, boolean>()\n\n for (const lit of literals) {\n if (!lit.value) {\n // Empty strings are always \"active\" (they don't add anything)\n result.set(lit.offset, true)\n continue\n }\n\n // Check if this literal's value appears in the rendered output.\n // For class values, the rendered output is space-separated classes,\n // so we check if the literal is a substring or if all its classes are present.\n const literalClasses = lit.value.split(/\\s+/).filter(Boolean)\n const renderedClasses = renderedValue.split(/\\s+/).filter(Boolean)\n\n if (literalClasses.length > 0 && literalClasses.every((c) => renderedClasses.includes(c))) {\n result.set(lit.offset, true)\n } else if (renderedValue.includes(lit.value)) {\n // Direct substring match (for non-class attributes)\n result.set(lit.offset, true)\n } else {\n result.set(lit.offset, false)\n }\n }\n\n return result\n}\n\n/**\n * Create an interactive expression editor.\n *\n * @param expression — the raw expression string (between { and })\n * @param literals — the editable string literals extracted from the expression\n * @param renderedValue — the current rendered value from the DOM (null if unknown)\n * @param onChange — called when any literal is edited\n * @returns the DOM element for the editor\n */\nexport function createExpressionField(\n expression: string,\n literals: ExpressionLiteral[],\n renderedValue: string | null,\n onChange: (changes: ExpressionChange[]) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"expr-field\"\n\n // Infer which literals are active\n const activeMap = renderedValue\n ? inferActiveLiterals(literals, renderedValue)\n : null\n\n // Track pending changes\n const pendingChanges = new Map<number, ExpressionChange>()\n\n // ── Structured view ────────────────────────────────────\n\n const structuredView = document.createElement(\"div\")\n structuredView.className = \"expr-structured\"\n\n if (literals.length === 0) {\n // No editable literals — show as read-only\n const readOnly = document.createElement(\"span\")\n readOnly.className = \"expr-readonly\"\n readOnly.textContent = expression\n readOnly.title = \"No editable string literals in this expression\"\n structuredView.appendChild(readOnly)\n } else {\n // Build the interleaved view: code segments + editable fields\n let lastEnd = 0\n\n for (const lit of literals) {\n // Code segment before this literal\n const codeBefore = expression.slice(lastEnd, lit.offset)\n if (codeBefore.trim()) {\n const codeSpan = document.createElement(\"span\")\n codeSpan.className = \"expr-code\"\n codeSpan.textContent = codeBefore.trim()\n structuredView.appendChild(codeSpan)\n }\n\n // Is this literal active (matches rendered value)?\n const isActive = activeMap?.get(lit.offset) ?? null\n\n // Editable field for the string literal\n const field = createLiteralField(lit, isActive, (newValue) => {\n if (newValue !== lit.value) {\n pendingChanges.set(lit.offset, {\n offset: lit.offset,\n oldValue: lit.value,\n newValue,\n })\n } else {\n pendingChanges.delete(lit.offset)\n }\n onChange(Array.from(pendingChanges.values()))\n })\n structuredView.appendChild(field)\n\n // Calculate end of this literal in the expression\n if (lit.quote === \"`\") {\n lastEnd = lit.offset + lit.value.length\n } else {\n lastEnd = lit.offset + lit.value.length + 2 // +2 for quotes\n }\n }\n\n // Trailing code after the last literal\n const trailingCode = expression.slice(lastEnd).trim()\n if (trailingCode) {\n const trailSpan = document.createElement(\"span\")\n trailSpan.className = \"expr-code\"\n trailSpan.textContent = trailingCode\n structuredView.appendChild(trailSpan)\n }\n }\n\n // ── Rendered value indicator ───────────────────────────\n\n if (renderedValue !== null) {\n const rendered = document.createElement(\"div\")\n rendered.className = \"expr-rendered\"\n rendered.title = \"Current rendered value from the DOM\"\n\n const label = document.createElement(\"span\")\n label.className = \"expr-rendered-label\"\n label.textContent = \"rendered:\"\n\n const val = document.createElement(\"span\")\n val.className = \"expr-rendered-value\"\n val.textContent = renderedValue || \"(empty)\"\n\n rendered.appendChild(label)\n rendered.appendChild(val)\n structuredView.insertBefore(rendered, structuredView.firstChild)\n }\n\n // ── Raw view (hidden by default) ───────────────────────\n\n const rawView = document.createElement(\"div\")\n rawView.className = \"expr-raw\"\n rawView.style.display = \"none\"\n\n const rawTextarea = document.createElement(\"textarea\")\n rawTextarea.className = \"text-edit-input\"\n rawTextarea.value = expression\n rawTextarea.rows = Math.min(6, expression.split(\"\\n\").length + 1)\n rawTextarea.style.fontFamily = \"ui-monospace, monospace\"\n rawTextarea.style.fontSize = \"11px\"\n rawView.appendChild(rawTextarea)\n\n // ── Toggle button ──────────────────────────────────────\n\n const toggleRow = document.createElement(\"div\")\n toggleRow.style.cssText =\n \"display:flex;justify-content:flex-end;margin-top:4px\"\n\n const toggleBtn = document.createElement(\"button\")\n toggleBtn.className = \"btn btn-secondary\"\n toggleBtn.style.cssText = \"padding:2px 6px;font-size:10px\"\n toggleBtn.textContent = \"raw\"\n toggleBtn.title = \"Toggle raw expression editing\"\n\n let isRaw = false\n toggleBtn.addEventListener(\"click\", () => {\n isRaw = !isRaw\n structuredView.style.display = isRaw ? \"none\" : \"\"\n rawView.style.display = isRaw ? \"\" : \"none\"\n toggleBtn.textContent = isRaw ? \"visual\" : \"raw\"\n })\n\n toggleRow.appendChild(toggleBtn)\n\n container.appendChild(structuredView)\n container.appendChild(rawView)\n container.appendChild(toggleRow)\n\n return container\n}\n\n/**\n * Create an editable field for a single string literal.\n *\n * @param lit — the literal metadata\n * @param isActive — true if this literal's value is in the rendered DOM output,\n * false if the condition was falsy, null if unknown\n * @param onChange — called when the input value changes\n */\nfunction createLiteralField(\n lit: ExpressionLiteral,\n isActive: boolean | null,\n onChange: (newValue: string) => void,\n): HTMLElement {\n const wrapper = document.createElement(\"span\")\n wrapper.className = \"expr-literal\"\n if (isActive === true) wrapper.classList.add(\"expr-active\")\n if (isActive === false) wrapper.classList.add(\"expr-inactive\")\n wrapper.title = contextLabel(lit.context) +\n (isActive === true ? \" (currently active)\" : \"\") +\n (isActive === false ? \" (currently inactive)\" : \"\")\n\n // Context badge with active indicator\n const badge = document.createElement(\"span\")\n badge.className = \"expr-badge\"\n if (isActive === true) badge.classList.add(\"expr-badge-active\")\n if (isActive === false) badge.classList.add(\"expr-badge-inactive\")\n const indicator = isActive === true ? \"\\u2713 \" : isActive === false ? \"\\u25CB \" : \"\"\n badge.textContent = indicator + shortContextLabel(lit.context)\n wrapper.appendChild(badge)\n\n // The editable input\n const input = document.createElement(\"input\")\n input.className = \"var-input expr-input\"\n if (isActive === false) input.classList.add(\"expr-input-inactive\")\n input.value = lit.value\n input.style.fontSize = \"11px\"\n\n // Auto-size the input to fit content\n const updateWidth = () => {\n const len = Math.max(input.value.length, 3)\n input.style.width = `${len + 1}ch`\n }\n updateWidth()\n\n input.addEventListener(\"input\", updateWidth)\n input.addEventListener(\"change\", () => onChange(input.value))\n\n wrapper.appendChild(input)\n\n return wrapper\n}\n\n/**\n * Human-readable label for the expression context.\n */\nfunction contextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"Value when condition is true\"\n case \"ternary-alternate\":\n return \"Value when condition is false\"\n case \"conditional\":\n return \"Applied when condition is truthy\"\n case \"fallback\":\n return \"Fallback value\"\n case \"call-arg\":\n return \"Function argument\"\n case \"template-static\":\n return \"Static text in template\"\n case \"object-value\":\n return \"Object property value\"\n case \"array-item\":\n return \"Array item\"\n default:\n return \"Editable value\"\n }\n}\n\n/**\n * Short badge label for the context.\n */\nfunction shortContextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"if\"\n case \"ternary-alternate\":\n return \"else\"\n case \"conditional\":\n return \"when\"\n case \"fallback\":\n return \"or\"\n case \"call-arg\":\n return \"arg\"\n case \"template-static\":\n return \"text\"\n case \"object-value\":\n return \"val\"\n case \"array-item\":\n return \"item\"\n default:\n return \"\"\n }\n}\n","/**\n * Class Editor — renders a tag-style editor for space-separated\n * CSS class strings. Each class is shown as a removable tag,\n * and new classes can be added.\n *\n * Given \"rounded-lg border ring-2 ring-blue-500\":\n *\n * ┌─────────────────────────────────────────────────┐\n * │ [rounded-lg ×] [border ×] [ring-2 ×] │\n * │ [ring-blue-500 ×] │\n * │ [+ add class________________________] │\n * └─────────────────────────────────────────────────┘\n *\n * Each tag can be removed (×) or edited (click to select + type).\n * The \"add class\" input lets you type new classes.\n * onChange fires with the full updated class string.\n */\n\n/**\n * Create a class tag editor for a space-separated class string.\n *\n * @param classes — the current class string (e.g., \"rounded-lg border\")\n * @param onChange — called with the updated class string\n * @returns the DOM element for the editor\n */\nexport function createClassEditor(\n classes: string,\n onChange: (newClasses: string) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"class-editor\"\n\n let currentClasses = classes.split(/\\s+/).filter(Boolean)\n\n function render() {\n container.textContent = \"\"\n\n const tagRow = document.createElement(\"div\")\n tagRow.className = \"class-tags\"\n\n for (let i = 0; i < currentClasses.length; i++) {\n const cls = currentClasses[i]\n const tag = createClassTag(cls, {\n onRemove: () => {\n currentClasses.splice(i, 1)\n onChange(currentClasses.join(\" \"))\n render()\n },\n onEdit: (newValue) => {\n if (newValue.trim()) {\n // Handle pasting multiple classes\n const parts = newValue.trim().split(/\\s+/)\n currentClasses.splice(i, 1, ...parts)\n } else {\n currentClasses.splice(i, 1)\n }\n onChange(currentClasses.join(\" \"))\n render()\n },\n })\n tagRow.appendChild(tag)\n }\n\n container.appendChild(tagRow)\n\n // Add class input\n const addInput = document.createElement(\"input\")\n addInput.className = \"var-input class-add-input\"\n addInput.placeholder = \"+ add class\"\n addInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && addInput.value.trim()) {\n const newClasses = addInput.value.trim().split(/\\s+/)\n currentClasses.push(...newClasses)\n onChange(currentClasses.join(\" \"))\n addInput.value = \"\"\n render()\n }\n })\n\n container.appendChild(addInput)\n }\n\n render()\n return container\n}\n\n/**\n * Create a single class tag element.\n */\nfunction createClassTag(\n className: string,\n handlers: {\n onRemove: () => void\n onEdit: (newValue: string) => void\n },\n): HTMLElement {\n const tag = document.createElement(\"span\")\n tag.className = \"class-tag\"\n\n const label = document.createElement(\"span\")\n label.className = \"class-tag-label\"\n label.textContent = className\n label.title = className\n\n // Click to edit\n label.addEventListener(\"dblclick\", () => {\n const input = document.createElement(\"input\")\n input.className = \"class-tag-edit\"\n input.value = className\n input.style.width = `${Math.max(className.length, 3) + 2}ch`\n\n input.addEventListener(\"blur\", () => {\n handlers.onEdit(input.value)\n })\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n handlers.onEdit(input.value)\n }\n if (e.key === \"Escape\") {\n handlers.onEdit(className) // revert\n }\n })\n\n tag.replaceChild(input, label)\n input.focus()\n input.select()\n })\n\n const removeBtn = document.createElement(\"button\")\n removeBtn.className = \"class-tag-remove\"\n removeBtn.textContent = \"\\u00d7\"\n removeBtn.title = `Remove ${className}`\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation()\n handlers.onRemove()\n })\n\n tag.appendChild(label)\n tag.appendChild(removeBtn)\n\n return tag\n}\n","/**\n * Value Source Indicator — shows whether a value came from\n * a string literal, a variable, or a complex expression.\n *\n * For literal: class=\"hero\"\n * → [literal] \"hero\" — editable directly\n *\n * For variable: class={className}\n * → [variable] className → \"hero container\" — edit in source\n *\n * For expression: class={cn(\"base\", active && \"active\")}\n * → [expression] cn(\"base\", ...) — edit string literals\n */\n\nexport type ValueSource = \"literal\" | \"variable\" | \"expression\"\n\n/**\n * Create a value source indicator element.\n *\n * @param source — the source type\n * @param detail — additional context (variable name, expression preview)\n * @returns the DOM element\n */\nexport function createValueSourceIndicator(\n source: ValueSource,\n detail?: string,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"value-source\"\n\n const badge = document.createElement(\"span\")\n badge.className = `value-source-badge ${source}`\n badge.textContent = source\n\n container.appendChild(badge)\n\n if (detail) {\n const detailSpan = document.createElement(\"span\")\n detailSpan.textContent = detail\n detailSpan.style.fontFamily = \"ui-monospace, monospace\"\n container.appendChild(detailSpan)\n }\n\n // Add context-specific hint\n const hint = document.createElement(\"span\")\n hint.style.color = \"#334155\"\n\n switch (source) {\n case \"literal\":\n hint.textContent = \"— editable\"\n break\n case \"variable\":\n hint.textContent = \"— edit in source\"\n break\n case \"expression\":\n hint.textContent = \"— edit string parts\"\n break\n }\n\n container.appendChild(hint)\n\n return container\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACwIO,IAAM,gBAAN,MAAoB;AAAA,EACzB,QAAkC,oBAAI,IAAI;AAAA,EAE1C,QAAuB;AACrB,UAAM,SAAwB,CAAC;AAC/B,eAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;AACtC,UAAI,KAAK,aAAa,KAAM,QAAO,KAAK,IAAI;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAyB;AAC9B,SAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AAG5B,QAAI,KAAK,UAAU;AACjB,YAAM,SAAS,KAAK,MAAM,IAAI,KAAK,QAAQ;AAC3C,UAAI,UAAU,CAAC,OAAO,SAAS,SAAS,KAAK,EAAE,GAAG;AAChD,eAAO,SAAS,KAAK,KAAK,EAAE;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,IAAkB;AACvB,UAAM,OAAO,KAAK,MAAM,IAAI,EAAE;AAC9B,QAAI,CAAC,KAAM;AAGX,QAAI,KAAK,UAAU;AACjB,YAAM,SAAS,KAAK,MAAM,IAAI,KAAK,QAAQ;AAC3C,UAAI,QAAQ;AACV,eAAO,WAAW,OAAO,SAAS,OAAO,CAAC,QAAQ,QAAQ,EAAE;AAAA,MAC9D;AAAA,IACF;AAEA,SAAK,MAAM,OAAO,EAAE;AAAA,EACtB;AAAA,EAEA,KAAK,SAA2D;AAC9D,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,QAAQ,CAAC,MAAmB,UAAkB;AAClD,UAAI,QAAQ,IAAI,KAAK,EAAE,EAAG;AAC1B,cAAQ,IAAI,KAAK,EAAE;AACnB,cAAQ,MAAM,KAAK;AACnB,iBAAW,WAAW,KAAK,UAAU;AACnC,cAAM,QAAQ,KAAK,MAAM,IAAI,OAAO;AACpC,YAAI,MAAO,OAAM,OAAO,QAAQ,CAAC;AAAA,MACnC;AAAA,IACF;AACA,eAAW,QAAQ,KAAK,MAAM,GAAG;AAC/B,YAAM,MAAM,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EAEA,IAAI,IAAqC;AACvC,WAAO,KAAK,MAAM,IAAI,EAAE;AAAA,EAC1B;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AACF;;;AChMO,SAAS,oBAAoC;AAClD,SAAO,oBAAI,IAAI;AACjB;AAUO,SAAS,aACd,KACA,MACA,QAAgB,KACV;AACN,QAAM,WAAW,IAAI,IAAI,IAAI;AAC7B,MAAI,UAAU,QAAS,cAAa,SAAS,OAAO;AAEpD,QAAM,UAAU,WAAW,MAAM,IAAI,OAAO,IAAI,GAAG,KAAK;AACxD,MAAI,IAAI,MAAM,EAAE,MAAM,MAAM,QAAQ,CAAC;AACvC;AASO,SAAS,uBACd,KAC2C;AAC3C,SAAO,CAAC,EAAE,KAAK,MAAM;AACnB,UAAM,QAAQ,IAAI,IAAI,IAAI;AAC1B,QAAI,OAAO,MAAM;AACf,UAAI,OAAO,IAAI;AACf,aAAO,CAAC;AAAA,IACV;AACA,WAAO;AAAA,EACT;AACF;;;ACjCA,IAAM,YAAY,oBAAI,IAA2B;AAEjD,eAAe,aACb,MACA,IACe;AAEf,QAAM,OAAO,UAAU,IAAI,IAAI,KAAK,QAAQ,QAAQ;AAIpD,QAAM,UAAU,KAAK,KAAK,IAAI,EAAE;AAChC,YAAU,IAAI,MAAM,OAAO;AAE3B,MAAI;AACF,UAAM;AAAA,EACR,UAAE;AAEA,QAAI,UAAU,IAAI,IAAI,MAAM,SAAS;AACnC,gBAAU,OAAO,IAAI;AAAA,IACvB;AAAA,EACF;AACF;AAQO,SAAS,mBACd,SACA,SACqB;AACrB,SAAO,QAAQ;AAAA,IACb,CAAC,KAAK,UAAU;AACd,YAAM,OAAO,QAAQ,KAAK;AACzB,OAAC,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK;AACzC,aAAO;AAAA,IACT;AAAA,IACA,CAAC;AAAA,EACH;AACF;AAeA,eAAsB,aACpB,SACA,SACA,aACe;AACf,QAAM,UAAU,mBAAmB,SAAS,OAAO;AACnD,QAAM,SAAgD,CAAC;AAEvD,QAAM,QAAQ;AAAA,IACZ,OAAO,QAAQ,OAAO,EAAE,IAAI,OAAO,CAAC,MAAM,WAAW,MAAM;AACzD,UAAI;AACF,cAAM,aAAa,MAAM,MAAM,YAAY,MAAM,WAAW,CAAC;AAAA,MAC/D,SAAS,KAAU;AACjB,gBAAQ,MAAM,yCAAyC,IAAI,KAAK,GAAG;AACnE,eAAO,KAAK,EAAE,MAAM,OAAO,IAAI,CAAC;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,WAAW,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI;AACpD,UAAM,IAAI;AAAA,MACR,oBAAoB,OAAO,MAAM,aAAa,QAAQ,KAAK,OAAO,CAAC,EAAE,MAAM,OAAO;AAAA,IACpF;AAAA,EACF;AACF;;;ACpEO,SAAS,gBACd,QACA,QACA,SACA,SACQ;AACR,QAAM,SAAS,OAAO,MAAM,QAAQ,SAAS,QAAQ,MAAM;AAC3D,MAAI,WAAW,SAAS;AACtB,UAAM,IAAI;AAAA,MACR,2BAA2B,MAAM,eAAe,QAAQ,MAAM,GAAG,EAAE,CAAC,aAAa,OAAO,MAAM,GAAG,EAAE,CAAC;AAAA,IACtG;AAAA,EACF;AACA,SAAO,OAAO,MAAM,GAAG,MAAM,IAAI,UAAU,OAAO,MAAM,SAAS,QAAQ,MAAM;AACjF;AAMO,SAAS,kBACd,QACA,MACA,KACA,SACA,SACA,UAA0B,CAAC,GACnB;AACR,MAAI,OAAO,GAAG;AACZ,UAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,UAAM,UAAU,OAAO;AACvB,QAAI,WAAW,KAAK,UAAU,MAAM,QAAQ;AAC1C,YAAM,SAAS,KAAK,IAAI,GAAG,MAAM,CAAC;AAClC,YAAM,WAAW,MAAM,OAAO,EAAE,QAAQ,SAAS,MAAM;AACvD,UAAI,aAAa,IAAI;AACnB,cAAM,OAAO,IACX,MAAM,OAAO,EAAE,MAAM,GAAG,QAAQ,IAChC,UACA,MAAM,OAAO,EAAE,MAAM,WAAW,QAAQ,MAAM;AAChD,eAAO,MAAM,KAAK,IAAI;AAAA,MACxB;AAAA,IACF;AAAA,EAEF;AAEA,SAAO,kBAAkB,QAAQ,SAAS,SAAS,OAAO;AAC5D;AAYO,SAAS,kBACd,QACA,SACA,SACA,UAA0B,CAAC,GACnB;AACR,QAAM,gBAAgB,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACxD,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAGA,MAAI,cAAc;AAClB,MAAI,YAAY,OAAO;AAEvB,MAAI,QAAQ,iBAAiB;AAC3B,UAAM,UAAU,OAAO,MAAM,WAAW;AACxC,QAAI,SAAS;AACX,YAAM,QAAQ,OAAO,QAAQ,SAAS,QAAQ,CAAC,EAAE,MAAM;AACvD,UAAI,UAAU,GAAI,eAAc,QAAQ;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,QAAQ,iBAAiB;AAC3B,UAAM,aAAa,OAAO,QAAQ,UAAU,WAAW;AACvD,QAAI,eAAe,GAAI,aAAY;AAAA,EACrC;AAEA,QAAM,SAAS,OAAO,MAAM,aAAa,SAAS;AAGlD,QAAM,SAAmB,CAAC;AAC1B,MAAI,aAAa;AACjB,MAAI,eAAe;AAEnB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,KAAK,KAAK,OAAO,CAAC,CAAC,GAAG;AACxB,UAAI,CAAC,gBAAgB,WAAW,SAAS,GAAG;AAC1C,sBAAc;AACd,eAAO,KAAK,CAAC;AACb,uBAAe;AAAA,MACjB;AAAA,IACF,OAAO;AACL,oBAAc,OAAO,CAAC;AACtB,aAAO,KAAK,CAAC;AACb,qBAAe;AAAA,IACjB;AAAA,EACF;AAGA,MAAI,aAAa;AACjB,SAAO,MAAM;AACX,UAAM,WAAW,WAAW,QAAQ,eAAe,UAAU;AAC7D,QAAI,aAAa,IAAI;AACnB,YAAM,IAAI;AAAA,QACR,gCAAgC,QAAQ,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,IAAI,QAAQ,OAAO;AAAA,MAC9F;AAAA,IACF;AAEA,UAAM,YAAY,OAAO,QAAQ;AACjC,UAAM,eAAe,WAAW,cAAc,SAAS;AACvD,UAAM,UACJ,eAAe,OAAO,SAAS,OAAO,YAAY,IAAI,IAAI,OAAO;AAGnE,QAAI,QAAQ,cAAc;AACxB,YAAM,SAAS,OAAO,MAAM,GAAG,SAAS;AACxC,YAAM,SAAS,OAAO,YAAY,GAAG;AACrC,YAAM,SAAS,OAAO,YAAY,GAAG;AAErC,UAAI,UAAU,QAAQ;AAEpB,qBAAa,WAAW;AACxB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,cAAc;AAC/B,UAAM,SAAS,cAAc;AAC7B,WAAO,OAAO,MAAM,GAAG,QAAQ,IAAI,UAAU,OAAO,MAAM,MAAM;AAAA,EAClE;AACF;;;AC1EO,SAAS,eAAe,OAAsB;AACnD,SAAO,MAAM,YAAY,MAAM,GAAG,EAAE,CAAC;AACvC;AAYO,SAAS,sBAAsB,QAAqB;AACzD,SAAO,OAAO,MAAc,YAAoC;AAE9D,UAAM,cAAc,oBAAI,IAAqB;AAC7C,eAAW,SAAS,SAAS;AAC3B,YAAM,KAAK,eAAe,KAAK;AAC/B,UAAI,CAAC,YAAY,IAAI,EAAE,EAAG,aAAY,IAAI,IAAI,CAAC,CAAC;AAChD,kBAAY,IAAI,EAAE,EAAG,KAAK,KAAK;AAAA,IACjC;AAGA,eAAW,CAAC,WAAW,SAAS,KAAK,aAAa;AAChD,YAAM,UAAU,OAAO,SAAS;AAChC,UAAI,CAAC,SAAS;AACZ,gBAAQ,KAAK,8CAA8C,SAAS,EAAE;AACtE;AAAA,MACF;AACA,YAAM,QAAQ,MAAM,SAAS;AAAA,IAC/B;AAAA,EACF;AACF;;;ACnFA,IAAM,qBAAN,MAAyB;AAAA,EACf,aAA+B,CAAC;AAAA;AAAA;AAAA;AAAA,EAKxC,SAAS,UAAgC;AACvC,SAAK,WAAW,KAAK,QAAQ;AAC7B,SAAK,WAAW,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,IAAoC;AAE1C,UAAM,SAAS,KAAK,WAAW,EAAE;AACjC,QAAI,OAAQ,QAAO;AAGnB,QAAI,UAAU,GAAG;AACjB,WAAO,SAAS;AACd,YAAM,WAAW,KAAK,WAAW,OAAO;AACxC,UAAI,SAAU,QAAO;AACrB,gBAAU,QAAQ;AAAA,IACpB;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,IAAoC;AACrD,eAAW,YAAY,KAAK,YAAY;AACtC,UAAI;AACF,cAAM,SAAS,SAAS,QAAQ,EAAE;AAClC,YAAI,OAAQ,QAAO;AAAA,MACrB,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAMO,IAAM,iBAAiB,IAAI,mBAAmB;AAO9C,IAAM,wBAAwC;AAAA,EACnD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ,IAAI;AACV,UAAM,OAAO,GAAG,aAAa,oBAAoB;AACjD,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,OAAO,SAAS,GAAG,aAAa,oBAAoB,KAAK,KAAK,EAAE;AACtE,UAAM,MAAM,SAAS,GAAG,aAAa,mBAAmB,KAAK,KAAK,EAAE;AACpE,UAAM,QAAQ,KAAK,QAAQ,cAAc,MAAM;AAE/C,WAAO,EAAE,UAAU,MAAM,YAAY,MAAM,cAAc,KAAK,OAAO,UAAU,gBAAgB;AAAA,EACjG;AACF;AAUO,IAAM,sBAAsC;AAAA,EACjD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ,IAAI;AAEV,QAAI,OAAO,GAAG,aAAa,wBAAwB;AACnD,QAAI,MAAM,GAAG,aAAa,uBAAuB,KAAK;AAGtD,QAAI,CAAC,MAAM;AACT,YAAM,mBAAmB,oBAAoB,EAAE;AAC/C,UAAI,kBAAkB;AACpB,eAAO,iBAAiB;AACxB,cAAM,iBAAiB,YAAY;AAAA,MACrC;AAAA,IACF;AAEA,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM;AAC7C,UAAM,QAAQ,KAAK,QAAQ,cAAc,MAAM;AAE/C,WAAO,EAAE,UAAU,MAAM,YAAY,QAAQ,GAAG,cAAc,OAAO,GAAG,OAAO,UAAU,oBAAoB;AAAA,EAC/G;AACF;AASA,SAAS,oBACP,IAC2C;AAC3C,MAAI;AAEF,UAAM,YAAa,OAAe;AAGlC,QAAI,WAAW;AACb,aAAO,UAAU,IAAI,EAAE,KAAK;AAAA,IAC9B;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,IAAM,mBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ,IAAI;AAEV,QAAI,UAAyB;AAC7B,QAAI,UAA0B;AAC9B,WAAO,SAAS;AACd,iBAAW,QAAQ,QAAQ,YAAY;AACrC,YAAI,KAAK,KAAK,WAAW,iBAAiB,GAAG;AAC3C,oBAAU,KAAK;AACf;AAAA,QACF;AAAA,MACF;AACA,UAAI,QAAS;AACb,gBAAU,QAAQ;AAAA,IACpB;AACA,QAAI,CAAC,QAAS,QAAO;AAGrB,UAAM,cAAc,IAAI,OAAO;AAC/B,eAAW,SAAS,SAAS,iBAAiB,yBAAyB,GAAG;AACxE,WAAK,MAAM,eAAe,IAAI,SAAS,WAAW,GAAG;AACnD,cAAM,QAAQ,MAAM,aAAa,kBAAkB;AACnD,cAAM,OAAO,MAAM,MAAM,GAAG,EAAE,CAAC;AAC/B,cAAM,QAAQ,KAAK,QAAQ,cAAc,MAAM;AAC/C,eAAO,EAAE,UAAU,MAAM,YAAY,GAAG,cAAc,GAAG,OAAO,UAAU,YAAY;AAAA,MACxF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAgBA,eAAe,SAAS,qBAAqB;AAC7C,eAAe,SAAS,mBAAmB;AAC3C,eAAe,SAAS,gBAAgB;;;ACrLjC,SAAS,oBACd,UACA,eACsB;AACtB,QAAM,SAAS,oBAAI,IAAqB;AAExC,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,IAAI,OAAO;AAEd,aAAO,IAAI,IAAI,QAAQ,IAAI;AAC3B;AAAA,IACF;AAKA,UAAM,iBAAiB,IAAI,MAAM,MAAM,KAAK,EAAE,OAAO,OAAO;AAC5D,UAAM,kBAAkB,cAAc,MAAM,KAAK,EAAE,OAAO,OAAO;AAEjE,QAAI,eAAe,SAAS,KAAK,eAAe,MAAM,CAAC,MAAM,gBAAgB,SAAS,CAAC,CAAC,GAAG;AACzF,aAAO,IAAI,IAAI,QAAQ,IAAI;AAAA,IAC7B,WAAW,cAAc,SAAS,IAAI,KAAK,GAAG;AAE5C,aAAO,IAAI,IAAI,QAAQ,IAAI;AAAA,IAC7B,OAAO;AACL,aAAO,IAAI,IAAI,QAAQ,KAAK;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,sBACd,YACA,UACA,eACA,UACa;AACb,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,YAAY;AAGtB,QAAM,YAAY,gBACd,oBAAoB,UAAU,aAAa,IAC3C;AAGJ,QAAM,iBAAiB,oBAAI,IAA8B;AAIzD,QAAM,iBAAiB,SAAS,cAAc,KAAK;AACnD,iBAAe,YAAY;AAE3B,MAAI,SAAS,WAAW,GAAG;AAEzB,UAAM,WAAW,SAAS,cAAc,MAAM;AAC9C,aAAS,YAAY;AACrB,aAAS,cAAc;AACvB,aAAS,QAAQ;AACjB,mBAAe,YAAY,QAAQ;AAAA,EACrC,OAAO;AAEL,QAAI,UAAU;AAEd,eAAW,OAAO,UAAU;AAE1B,YAAM,aAAa,WAAW,MAAM,SAAS,IAAI,MAAM;AACvD,UAAI,WAAW,KAAK,GAAG;AACrB,cAAM,WAAW,SAAS,cAAc,MAAM;AAC9C,iBAAS,YAAY;AACrB,iBAAS,cAAc,WAAW,KAAK;AACvC,uBAAe,YAAY,QAAQ;AAAA,MACrC;AAGA,YAAM,WAAW,WAAW,IAAI,IAAI,MAAM,KAAK;AAG/C,YAAM,QAAQ,mBAAmB,KAAK,UAAU,CAAC,aAAa;AAC5D,YAAI,aAAa,IAAI,OAAO;AAC1B,yBAAe,IAAI,IAAI,QAAQ;AAAA,YAC7B,QAAQ,IAAI;AAAA,YACZ,UAAU,IAAI;AAAA,YACd;AAAA,UACF,CAAC;AAAA,QACH,OAAO;AACL,yBAAe,OAAO,IAAI,MAAM;AAAA,QAClC;AACA,iBAAS,MAAM,KAAK,eAAe,OAAO,CAAC,CAAC;AAAA,MAC9C,CAAC;AACD,qBAAe,YAAY,KAAK;AAGhC,UAAI,IAAI,UAAU,KAAK;AACrB,kBAAU,IAAI,SAAS,IAAI,MAAM;AAAA,MACnC,OAAO;AACL,kBAAU,IAAI,SAAS,IAAI,MAAM,SAAS;AAAA,MAC5C;AAAA,IACF;AAGA,UAAM,eAAe,WAAW,MAAM,OAAO,EAAE,KAAK;AACpD,QAAI,cAAc;AAChB,YAAM,YAAY,SAAS,cAAc,MAAM;AAC/C,gBAAU,YAAY;AACtB,gBAAU,cAAc;AACxB,qBAAe,YAAY,SAAS;AAAA,IACtC;AAAA,EACF;AAIA,MAAI,kBAAkB,MAAM;AAC1B,UAAM,WAAW,SAAS,cAAc,KAAK;AAC7C,aAAS,YAAY;AACrB,aAAS,QAAQ;AAEjB,UAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,UAAM,YAAY;AAClB,UAAM,cAAc;AAEpB,UAAM,MAAM,SAAS,cAAc,MAAM;AACzC,QAAI,YAAY;AAChB,QAAI,cAAc,iBAAiB;AAEnC,aAAS,YAAY,KAAK;AAC1B,aAAS,YAAY,GAAG;AACxB,mBAAe,aAAa,UAAU,eAAe,UAAU;AAAA,EACjE;AAIA,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,YAAY;AACpB,UAAQ,MAAM,UAAU;AAExB,QAAM,cAAc,SAAS,cAAc,UAAU;AACrD,cAAY,YAAY;AACxB,cAAY,QAAQ;AACpB,cAAY,OAAO,KAAK,IAAI,GAAG,WAAW,MAAM,IAAI,EAAE,SAAS,CAAC;AAChE,cAAY,MAAM,aAAa;AAC/B,cAAY,MAAM,WAAW;AAC7B,UAAQ,YAAY,WAAW;AAI/B,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,MAAM,UACd;AAEF,QAAM,YAAY,SAAS,cAAc,QAAQ;AACjD,YAAU,YAAY;AACtB,YAAU,MAAM,UAAU;AAC1B,YAAU,cAAc;AACxB,YAAU,QAAQ;AAElB,MAAI,QAAQ;AACZ,YAAU,iBAAiB,SAAS,MAAM;AACxC,YAAQ,CAAC;AACT,mBAAe,MAAM,UAAU,QAAQ,SAAS;AAChD,YAAQ,MAAM,UAAU,QAAQ,KAAK;AACrC,cAAU,cAAc,QAAQ,WAAW;AAAA,EAC7C,CAAC;AAED,YAAU,YAAY,SAAS;AAE/B,YAAU,YAAY,cAAc;AACpC,YAAU,YAAY,OAAO;AAC7B,YAAU,YAAY,SAAS;AAE/B,SAAO;AACT;AAUA,SAAS,mBACP,KACA,UACA,UACa;AACb,QAAM,UAAU,SAAS,cAAc,MAAM;AAC7C,UAAQ,YAAY;AACpB,MAAI,aAAa,KAAM,SAAQ,UAAU,IAAI,aAAa;AAC1D,MAAI,aAAa,MAAO,SAAQ,UAAU,IAAI,eAAe;AAC7D,UAAQ,QAAQ,aAAa,IAAI,OAAO,KACrC,aAAa,OAAO,wBAAwB,OAC5C,aAAa,QAAQ,0BAA0B;AAGlD,QAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,QAAM,YAAY;AAClB,MAAI,aAAa,KAAM,OAAM,UAAU,IAAI,mBAAmB;AAC9D,MAAI,aAAa,MAAO,OAAM,UAAU,IAAI,qBAAqB;AACjE,QAAM,YAAY,aAAa,OAAO,YAAY,aAAa,QAAQ,YAAY;AACnF,QAAM,cAAc,YAAY,kBAAkB,IAAI,OAAO;AAC7D,UAAQ,YAAY,KAAK;AAGzB,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,YAAY;AAClB,MAAI,aAAa,MAAO,OAAM,UAAU,IAAI,qBAAqB;AACjE,QAAM,QAAQ,IAAI;AAClB,QAAM,MAAM,WAAW;AAGvB,QAAM,cAAc,MAAM;AACxB,UAAM,MAAM,KAAK,IAAI,MAAM,MAAM,QAAQ,CAAC;AAC1C,UAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAAA,EAChC;AACA,cAAY;AAEZ,QAAM,iBAAiB,SAAS,WAAW;AAC3C,QAAM,iBAAiB,UAAU,MAAM,SAAS,MAAM,KAAK,CAAC;AAE5D,UAAQ,YAAY,KAAK;AAEzB,SAAO;AACT;AAKA,SAAS,aAAa,SAAyB;AAC7C,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAKA,SAAS,kBAAkB,SAAyB;AAClD,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;;;ACnTO,SAAS,kBACd,SACA,UACa;AACb,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,YAAY;AAEtB,MAAI,iBAAiB,QAAQ,MAAM,KAAK,EAAE,OAAO,OAAO;AAExD,WAAS,SAAS;AAChB,cAAU,cAAc;AAExB,UAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,WAAO,YAAY;AAEnB,aAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,YAAM,MAAM,eAAe,CAAC;AAC5B,YAAM,MAAM,eAAe,KAAK;AAAA,QAC9B,UAAU,MAAM;AACd,yBAAe,OAAO,GAAG,CAAC;AAC1B,mBAAS,eAAe,KAAK,GAAG,CAAC;AACjC,iBAAO;AAAA,QACT;AAAA,QACA,QAAQ,CAAC,aAAa;AACpB,cAAI,SAAS,KAAK,GAAG;AAEnB,kBAAM,QAAQ,SAAS,KAAK,EAAE,MAAM,KAAK;AACzC,2BAAe,OAAO,GAAG,GAAG,GAAG,KAAK;AAAA,UACtC,OAAO;AACL,2BAAe,OAAO,GAAG,CAAC;AAAA,UAC5B;AACA,mBAAS,eAAe,KAAK,GAAG,CAAC;AACjC,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AACD,aAAO,YAAY,GAAG;AAAA,IACxB;AAEA,cAAU,YAAY,MAAM;AAG5B,UAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,aAAS,YAAY;AACrB,aAAS,cAAc;AACvB,aAAS,iBAAiB,WAAW,CAAC,MAAM;AAC1C,UAAI,EAAE,QAAQ,WAAW,SAAS,MAAM,KAAK,GAAG;AAC9C,cAAM,aAAa,SAAS,MAAM,KAAK,EAAE,MAAM,KAAK;AACpD,uBAAe,KAAK,GAAG,UAAU;AACjC,iBAAS,eAAe,KAAK,GAAG,CAAC;AACjC,iBAAS,QAAQ;AACjB,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,cAAU,YAAY,QAAQ;AAAA,EAChC;AAEA,SAAO;AACP,SAAO;AACT;AAKA,SAAS,eACP,WACA,UAIa;AACb,QAAM,MAAM,SAAS,cAAc,MAAM;AACzC,MAAI,YAAY;AAEhB,QAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,QAAM,YAAY;AAClB,QAAM,cAAc;AACpB,QAAM,QAAQ;AAGd,QAAM,iBAAiB,YAAY,MAAM;AACvC,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,YAAY;AAClB,UAAM,QAAQ;AACd,UAAM,MAAM,QAAQ,GAAG,KAAK,IAAI,UAAU,QAAQ,CAAC,IAAI,CAAC;AAExD,UAAM,iBAAiB,QAAQ,MAAM;AACnC,eAAS,OAAO,MAAM,KAAK;AAAA,IAC7B,CAAC;AACD,UAAM,iBAAiB,WAAW,CAAC,MAAM;AACvC,UAAI,EAAE,QAAQ,SAAS;AACrB,iBAAS,OAAO,MAAM,KAAK;AAAA,MAC7B;AACA,UAAI,EAAE,QAAQ,UAAU;AACtB,iBAAS,OAAO,SAAS;AAAA,MAC3B;AAAA,IACF,CAAC;AAED,QAAI,aAAa,OAAO,KAAK;AAC7B,UAAM,MAAM;AACZ,UAAM,OAAO;AAAA,EACf,CAAC;AAED,QAAM,YAAY,SAAS,cAAc,QAAQ;AACjD,YAAU,YAAY;AACtB,YAAU,cAAc;AACxB,YAAU,QAAQ,UAAU,SAAS;AACrC,YAAU,iBAAiB,SAAS,CAAC,MAAM;AACzC,MAAE,gBAAgB;AAClB,aAAS,SAAS;AAAA,EACpB,CAAC;AAED,MAAI,YAAY,KAAK;AACrB,MAAI,YAAY,SAAS;AAEzB,SAAO;AACT;;;ACtHO,SAAS,2BACd,QACA,QACa;AACb,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,YAAY;AAEtB,QAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,QAAM,YAAY,sBAAsB,MAAM;AAC9C,QAAM,cAAc;AAEpB,YAAU,YAAY,KAAK;AAE3B,MAAI,QAAQ;AACV,UAAM,aAAa,SAAS,cAAc,MAAM;AAChD,eAAW,cAAc;AACzB,eAAW,MAAM,aAAa;AAC9B,cAAU,YAAY,UAAU;AAAA,EAClC;AAGA,QAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,OAAK,MAAM,QAAQ;AAEnB,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,WAAK,cAAc;AACnB;AAAA,IACF,KAAK;AACH,WAAK,cAAc;AACnB;AAAA,IACF,KAAK;AACH,WAAK,cAAc;AACnB;AAAA,EACJ;AAEA,YAAU,YAAY,IAAI;AAE1B,SAAO;AACT;","names":[]}

@@ -284,5 +284,12 @@ // src/element.ts

resolve(el) {
const file = el.getAttribute("data-astro-source-file");
let file = el.getAttribute("data-astro-source-file");
let loc = el.getAttribute("data-astro-source-loc") || "";
if (!file) {
const astroAnnotations = getAstroAnnotations(el);
if (astroAnnotations) {
file = astroAnnotations.file;
loc = astroAnnotations.location || "";
}
}
if (!file) return null;
const loc = el.getAttribute("data-astro-source-loc") || "";
const [line, col] = loc.split(":").map(Number);

@@ -293,2 +300,13 @@ const label = file.replace(/^.*\/src\//, "src/");

};
function getAstroAnnotations(el) {
try {
const sourceMap = window.__editableSourceMap__;
if (sourceMap) {
return sourceMap.get(el) ?? null;
}
return null;
} catch {
return null;
}
}
var astroCidStrategy = {

@@ -295,0 +313,0 @@ name: "astro-cid",

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/element.ts","../src/hmr/suppress.ts","../src/patcher/orchestrate.ts","../src/patcher/text-patcher.ts","../src/patcher/patch-types.ts","../src/resolve/source-resolver.ts","../src/editor/expression-field.ts","../src/editor/class-editor.ts","../src/editor/value-source.ts"],"sourcesContent":["/**\n * Unified element model for editable-jsx.\n *\n * Every framework (React, Astro, raw HTML) produces ElementNodes\n * through a FrameworkAdapter. The editor UI consumes ElementNodes\n * without knowing which framework produced them.\n *\n * Key invariant: every editable element has a SourceLocation that\n * anchors it to a position in a source file. This is what makes\n * save-to-source work across all frameworks.\n */\n\nimport type { BasePatch, SourceLocation } from \"./types.js\"\n\n// ── Editable Property ───────────────────────────────────────────────\n\n/**\n * A single editable property on an element.\n * The `kind` discriminant determines which patcher handles saves.\n */\nexport type EditableProperty =\n | EditableProp\n | EditableCSSProperty\n | EditableCSSVariable\n | EditableText\n | EditableAttribute\n | EditableClassNamePart\n\n/** Component prop (React) */\nexport interface EditableProp {\n kind: \"prop\"\n name: string\n value: unknown\n serializable: boolean\n source: SourceLocation\n}\n\n/** CSS property on a matched rule */\nexport interface EditableCSSProperty {\n kind: \"css-property\"\n name: string\n value: string\n selector: string\n sourceFile: string\n overridden: boolean\n}\n\n/** CSS custom property (variable) */\nexport interface EditableCSSVariable {\n kind: \"css-variable\"\n name: string\n value: string\n resolvedValue: string\n scope: string\n sourceFile: string\n}\n\n/** Text content of an element */\nexport interface EditableText {\n kind: \"text\"\n value: string\n source: SourceLocation\n}\n\n/** HTML/Astro template attribute */\nexport interface EditableAttribute {\n kind: \"attribute\"\n name: string\n value: string\n source: SourceLocation\n}\n\n/** A single string literal inside a className expression (React) */\nexport interface EditableClassNamePart {\n kind: \"classname-part\"\n value: string\n partSource: SourceLocation\n parentSource: SourceLocation\n type: \"static\" | \"conditional\" | \"fallback\" | \"template\"\n}\n\n// ── Element Node ────────────────────────────────────────────────────\n\n/**\n * Universal representation of one editable element.\n * Produced by a FrameworkAdapter from framework-specific data.\n */\nexport interface ElementNode {\n /** Stable identifier within the editor session */\n id: string\n\n /** Human-readable label (tag name, component name) */\n displayName: string\n\n /** Raw HTML tag or component name */\n elementName: string\n\n /** Source location of the opening tag */\n source: SourceLocation\n\n /** Which file this element lives in */\n sourceFile: string\n\n /** Parent component name (null for plain HTML elements) */\n componentName: string | null\n\n /** Framework that produced this node */\n framework: \"react\" | \"astro\" | \"css\" | \"html\"\n\n /** All editable properties */\n properties: EditableProperty[]\n\n /** Tree relationships */\n parentId: string | null\n childIds: string[]\n\n /** Whether this node has unsaved changes */\n dirty: boolean\n\n /** The live DOM node (null for server-only representations) */\n domNode: Element | null\n}\n\n// ── Property Change ─────────────────────────────────────────────────\n\n/** A pending edit — what the user changed but hasn't saved yet. */\nexport interface PropertyChange {\n property: EditableProperty\n newValue: unknown\n}\n\n// ── Component Tree ──────────────────────────────────────────────────\n\n/**\n * Flat registry of ElementNodes with parent/child lookup.\n */\nexport class ComponentTree {\n nodes: Map<string, ElementNode> = new Map()\n\n roots(): ElementNode[] {\n const result: ElementNode[] = []\n for (const node of this.nodes.values()) {\n if (node.parentId === null) result.push(node)\n }\n return result\n }\n\n upsert(node: ElementNode): void {\n this.nodes.set(node.id, node)\n\n // Update parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent && !parent.childIds.includes(node.id)) {\n parent.childIds.push(node.id)\n }\n }\n }\n\n remove(id: string): void {\n const node = this.nodes.get(id)\n if (!node) return\n\n // Remove from parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent) {\n parent.childIds = parent.childIds.filter((cid) => cid !== id)\n }\n }\n\n this.nodes.delete(id)\n }\n\n walk(visitor: (node: ElementNode, depth: number) => void): void {\n const visited = new Set<string>()\n const visit = (node: ElementNode, depth: number) => {\n if (visited.has(node.id)) return\n visited.add(node.id)\n visitor(node, depth)\n for (const childId of node.childIds) {\n const child = this.nodes.get(childId)\n if (child) visit(child, depth + 1)\n }\n }\n for (const root of this.roots()) {\n visit(root, 0)\n }\n }\n\n get(id: string): ElementNode | undefined {\n return this.nodes.get(id)\n }\n\n clear(): void {\n this.nodes.clear()\n }\n}\n\n// ── Framework Adapter ───────────────────────────────────────────────\n\n/**\n * Each framework implements this interface to bridge its native\n * element representation into the unified ElementNode model.\n *\n * The adapter is the ONLY place where framework-specific knowledge lives.\n * The editor UI, component tree, and save orchestration are all\n * framework-agnostic — they work with ElementNodes and PropertyChanges.\n */\nexport interface FrameworkAdapter<NativeElement = unknown, NativePatch extends BasePatch = BasePatch> {\n /** Framework identifier */\n readonly framework: ElementNode[\"framework\"]\n\n /** Convert a native element to the universal ElementNode. */\n toElementNode(native: NativeElement): ElementNode\n\n /** Convert pending property changes to framework-specific patches. */\n toPatches(node: ElementNode, changes: PropertyChange[]): NativePatch[]\n\n /** Apply framework-specific patches to source files (server-side). */\n applyPatches(patches: NativePatch[]): Promise<void>\n\n /** Live preview a property change in the browser (optional). */\n preview?(node: ElementNode, change: PropertyChange): void\n\n /** Revert a live preview (optional). */\n revertPreview?(node: ElementNode, change: PropertyChange): void\n}\n","import type { HmrSuppressMap } from \"../types.js\"\n\n/**\n * Create a new HMR suppression map.\n */\nexport function createSuppressMap(): HmrSuppressMap {\n return new Map()\n}\n\n/**\n * Mark a file for HMR suppression with auto-expiry.\n *\n * Call this after writing a file to prevent the write from\n * triggering an HMR update (feedback loop). The entry auto-expires\n * after `ttlMs` milliseconds to prevent stale entries from\n * permanently suppressing HMR.\n */\nexport function suppressFile(\n map: HmrSuppressMap,\n file: string,\n ttlMs: number = 5000,\n): void {\n const existing = map.get(file)\n if (existing?.timeout) clearTimeout(existing.timeout)\n\n const timeout = setTimeout(() => map.delete(file), ttlMs)\n map.set(file, { skip: true, timeout })\n}\n\n/**\n * Create a Vite `handleHotUpdate` handler that suppresses\n * HMR for files in the suppress map.\n *\n * Returns `[]` (empty module array) to suppress the update,\n * or `undefined` to let it proceed normally.\n */\nexport function createHotUpdateHandler(\n map: HmrSuppressMap,\n): (ctx: { file: string }) => [] | undefined {\n return ({ file }) => {\n const entry = map.get(file)\n if (entry?.skip) {\n map.delete(file)\n return [] // Suppress HMR update\n }\n return undefined\n }\n}\n","/**\n * Shared patch orchestration — groups patches by file and applies them\n * in parallel with error collection.\n *\n * Used by all framework-specific patchers (JSX/ts-morph, CSS/PostCSS, Astro/compiler).\n */\n\n// ── Per-file mutex ─────────────────────────────────────────────────\n\n/**\n * Simple async mutex: serializes access per key (file path).\n * Two concurrent `applyPatches` calls on the same file will\n * be sequenced rather than racing.\n */\nconst fileLocks = new Map<string, Promise<void>>()\n\nasync function withFileLock(\n file: string,\n fn: () => Promise<void>,\n): Promise<void> {\n // Wait for the previous operation on this file (if any)\n const prev = fileLocks.get(file) ?? Promise.resolve()\n\n // Chain our work after the previous promise.\n // We store the chain BEFORE awaiting so the next caller sees us.\n const current = prev.then(fn, fn)\n fileLocks.set(file, current)\n\n try {\n await current\n } finally {\n // Clean up if we're still the tail of the chain\n if (fileLocks.get(file) === current) {\n fileLocks.delete(file)\n }\n }\n}\n\n/**\n * Group patches by file path.\n *\n * The `getFile` callback extracts the file path from a patch,\n * allowing different patch shapes (e.g., `patch.file` vs `patch.source.fileName`).\n */\nexport function groupPatchesByFile<P>(\n patches: P[],\n getFile: (patch: P) => string,\n): Record<string, P[]> {\n return patches.reduce(\n (acc, patch) => {\n const file = getFile(patch)\n ;(acc[file] = acc[file] || []).push(patch)\n return acc\n },\n {} as Record<string, P[]>,\n )\n}\n\n/**\n * Apply patches in parallel, grouped by file.\n *\n * Calls `applyFileFn` for each file group. Collects errors from\n * individual files and throws a combined error if any failed.\n *\n * Per-file access is serialized via an async mutex so that two\n * concurrent `applyPatches` calls on the same file don't race.\n *\n * @param patches - All patches to apply\n * @param getFile - Extracts the file path from a patch\n * @param applyFileFn - Applies patches to a single file\n */\nexport async function applyPatches<P>(\n patches: P[],\n getFile: (patch: P) => string,\n applyFileFn: (file: string, patches: P[]) => Promise<void>,\n): Promise<void> {\n const grouped = groupPatchesByFile(patches, getFile)\n const errors: Array<{ file: string; error: Error }> = []\n\n await Promise.all(\n Object.entries(grouped).map(async ([file, filePatches]) => {\n try {\n await withFileLock(file, () => applyFileFn(file, filePatches))\n } catch (err: any) {\n console.error(`[editable] Failed to apply patches to ${file}:`, err)\n errors.push({ file, error: err })\n }\n }),\n )\n\n if (errors.length > 0) {\n const fileList = errors.map((e) => e.file).join(\", \")\n throw new Error(\n `Patch failed for ${errors.length} file(s): ${fileList}. ${errors[0].error.message}`,\n )\n }\n}\n","/**\n * TextPatcher — surgical string replacement in source files.\n *\n * This is the \"dumb\" layer: it finds text in a source string and\n * replaces it. It does NOT parse any AST — it works on raw strings.\n *\n * Three replacement strategies:\n * 1. Position-based: find text at exact line:col\n * 2. Normalized: collapse whitespace, search with position map\n * 3. Literal: find exact string at a character offset\n *\n * The \"smart\" layer (ASTPatcher) finds WHERE to replace using\n * framework-specific AST parsing. TextPatcher does the actual splice.\n */\n\nexport interface ReplaceOptions {\n /** If true, only match text between > and < (text node context) */\n textNodeOnly?: boolean\n /** Skip the frontmatter region (--- ... ---) */\n skipFrontmatter?: boolean\n /** Skip content inside <style> blocks */\n skipStyleBlocks?: boolean\n}\n\n/**\n * Replace text at an exact character offset in a source string.\n * Used for expression literal replacement and AST-guided edits.\n */\nexport function replaceAtOffset(\n source: string,\n offset: number,\n oldText: string,\n newText: string,\n): string {\n const actual = source.slice(offset, offset + oldText.length)\n if (actual !== oldText) {\n throw new Error(\n `Text mismatch at offset ${offset}: expected \"${oldText.slice(0, 30)}\", found \"${actual.slice(0, 30)}\"`,\n )\n }\n return source.slice(0, offset) + newText + source.slice(offset + oldText.length)\n}\n\n/**\n * Replace text at a specific line and column (1-based).\n * Falls back to normalized search if not found at the exact position.\n */\nexport function replaceAtPosition(\n source: string,\n line: number,\n col: number,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n if (line > 0) {\n const lines = source.split(\"\\n\")\n const lineIdx = line - 1\n if (lineIdx >= 0 && lineIdx < lines.length) {\n const colIdx = Math.max(0, col - 1)\n const foundIdx = lines[lineIdx].indexOf(oldText, colIdx)\n if (foundIdx !== -1) {\n lines[lineIdx] =\n lines[lineIdx].slice(0, foundIdx) +\n newText +\n lines[lineIdx].slice(foundIdx + oldText.length)\n return lines.join(\"\\n\")\n }\n }\n // Position-based failed — fall through to normalized search\n }\n\n return replaceNormalized(source, oldText, newText, options)\n}\n\n/**\n * Replace text using whitespace-normalized matching.\n *\n * DOM textContent collapses whitespace across lines, but the source\n * may have the text split across multiple lines with indentation.\n * This normalizes both sides and maps positions back to the original.\n *\n * Optionally validates that the match is in text-node context\n * (between > and <, not inside an attribute value).\n */\nexport function replaceNormalized(\n source: string,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n const normalizedOld = oldText.replace(/\\s+/g, \" \").trim()\n if (!normalizedOld) {\n throw new Error(\"Cannot search for empty/whitespace-only text\")\n }\n\n // Determine the search region\n let regionStart = 0\n let regionEnd = source.length\n\n if (options.skipFrontmatter) {\n const fmMatch = source.match(/^---\\r?\\n/)\n if (fmMatch) {\n const fmEnd = source.indexOf(\"\\n---\", fmMatch[0].length)\n if (fmEnd !== -1) regionStart = fmEnd + 4\n }\n }\n\n if (options.skipStyleBlocks) {\n const styleStart = source.indexOf(\"<style\", regionStart)\n if (styleStart !== -1) regionEnd = styleStart\n }\n\n const region = source.slice(regionStart, regionEnd)\n\n // Build normalized version with position map\n const posMap: number[] = []\n let normalized = \"\"\n let inWhitespace = false\n\n for (let i = 0; i < region.length; i++) {\n if (/\\s/.test(region[i])) {\n if (!inWhitespace && normalized.length > 0) {\n normalized += \" \"\n posMap.push(i)\n inWhitespace = true\n }\n } else {\n normalized += region[i]\n posMap.push(i)\n inWhitespace = false\n }\n }\n\n // Search for matches\n let searchFrom = 0\n while (true) {\n const matchIdx = normalized.indexOf(normalizedOld, searchFrom)\n if (matchIdx === -1) {\n throw new Error(\n `Text not found in template: \"${oldText.length > 60 ? oldText.slice(0, 60) + \"...\" : oldText}\"`,\n )\n }\n\n const origStart = posMap[matchIdx]\n const matchEndNorm = matchIdx + normalizedOld.length - 1\n const origEnd =\n matchEndNorm < posMap.length ? posMap[matchEndNorm] + 1 : region.length\n\n // Optionally validate text-node context (between > and <)\n if (options.textNodeOnly) {\n const before = region.slice(0, origStart)\n const lastGt = before.lastIndexOf(\">\")\n const lastLt = before.lastIndexOf(\"<\")\n\n if (lastGt <= lastLt) {\n // Inside a tag (attribute context) — skip this match\n searchFrom = matchIdx + 1\n continue\n }\n }\n\n // Replace in the original source\n const absStart = regionStart + origStart\n const absEnd = regionStart + origEnd\n return source.slice(0, absStart) + newText + source.slice(absEnd)\n }\n}\n","/**\n * Unified Patch Schema — all framework patches are routable through\n * a single discriminated union.\n *\n * The action_type prefix determines which framework handler processes\n * the patch:\n * - \"css.*\" → CSS patcher (PostCSS)\n * - \"astro.*\" → Astro patcher (@astrojs/compiler)\n * - \"jsx.*\" → JSX patcher (ts-morph)\n * - \"text.*\" → Text patcher (normalized search)\n *\n * All patches share: action_type + file.\n * Framework-specific data lives in the patch body.\n */\n\nimport type { BasePatch } from \"../types.js\"\n\n// ── CSS Patches ────────────────────────────────────────────────────\n\nexport interface CSSVariablePatch extends BasePatch {\n action_type: \"css.variable\"\n variable: { name: string; value: string; scope: string }\n styleBlockOffset: number\n}\n\nexport interface CSSPropertyPatch extends BasePatch {\n action_type: \"css.property\"\n property: { selector: string; name: string; value: string }\n}\n\n// ── Text Patches ───────────────────────────────────────────────────\n\nexport interface TextPatch extends BasePatch {\n action_type: \"text.replace\"\n oldText: string\n newText: string\n /** Position hint (0 = use normalized search) */\n line: number\n col: number\n}\n\n// ── Astro Patches ──────────────────────────────────────────────────\n\nexport interface AstroAttrPatch extends BasePatch {\n action_type: \"astro.attribute\"\n elementLine: number\n elementCol: number\n attribute: string\n value: string\n}\n\nexport interface AstroExprPatch extends BasePatch {\n action_type: \"astro.expression\"\n elementLine: number\n elementCol: number\n attribute: string\n oldLiteral: string\n newLiteral: string\n literalOffset: number\n}\n\n// ── JSX Patches ────────────────────────────────────────────────────\n\nexport interface JSXAttrPatch extends BasePatch {\n action_type: \"jsx.attribute\"\n source: { lineNumber: number; columnNumber: number }\n path: string\n value: unknown\n}\n\nexport interface JSXClassNamePatch extends BasePatch {\n action_type: \"jsx.classname\"\n source: { lineNumber: number; columnNumber: number }\n partLine: number\n partCol: number\n oldValue: string\n newValue: string\n}\n\n// ── Union ──────────────────────────────────────────────────────────\n\nexport type Patch =\n | CSSVariablePatch\n | CSSPropertyPatch\n | TextPatch\n | AstroAttrPatch\n | AstroExprPatch\n | JSXAttrPatch\n | JSXClassNamePatch\n\n/**\n * Extract the framework prefix from a patch action_type.\n */\nexport function patchFramework(patch: Patch): string {\n return patch.action_type.split(\".\")[0]\n}\n\n/**\n * Route patches to framework-specific handlers.\n */\nexport type PatchRouter = {\n [framework: string]: (file: string, patches: Patch[]) => Promise<void>\n}\n\n/**\n * Create a patch dispatcher that routes patches by framework prefix.\n */\nexport function createPatchDispatcher(router: PatchRouter) {\n return async (file: string, patches: Patch[]): Promise<void> => {\n // Group by framework\n const byFramework = new Map<string, Patch[]>()\n for (const patch of patches) {\n const fw = patchFramework(patch)\n if (!byFramework.has(fw)) byFramework.set(fw, [])\n byFramework.get(fw)!.push(patch)\n }\n\n // Dispatch to framework handlers sequentially (same file)\n for (const [framework, fwPatches] of byFramework) {\n const handler = router[framework]\n if (!handler) {\n console.warn(`[editable] No handler for patch framework: ${framework}`)\n continue\n }\n await handler(file, fwPatches)\n }\n }\n}\n","/**\n * SourceResolver — canonical \"DOM element → source file + position\" resolution.\n *\n * One module, one interface, one fallback chain. Every framework registers\n * its strategies here instead of implementing its own resolution logic.\n *\n * Strategies are tried in priority order until one succeeds:\n * 1. data-editable-* attributes (our annotation transform)\n * 2. data-astro-source-* attributes (Astro's native dev toolbar)\n * 3. data-astro-cid-* → stylesheet → data-vite-dev-id (CID tracing)\n * 4. Framework-specific strategies (registered by adapters)\n *\n * New frameworks (Vue, Svelte) register a strategy once and\n * get source resolution for free.\n */\n\nimport type { SourceLocation } from \"../types.js\"\n\n/**\n * Resolved source information for a DOM element.\n */\nexport interface ResolvedSource extends SourceLocation {\n /** Human-readable label (e.g., \"src/pages/index.astro\") */\n label: string\n /** How the source was resolved */\n strategy: string\n}\n\n/**\n * A strategy for resolving source location from a DOM element.\n * Returns null if it can't resolve.\n */\nexport interface SourceStrategy {\n /** Strategy name for debugging */\n name: string\n /** Priority (lower = tried first) */\n priority: number\n /** Attempt to resolve source for an element */\n resolve(el: Element): ResolvedSource | null\n}\n\n/**\n * Singleton source resolver with pluggable strategies.\n */\nclass SourceResolverImpl {\n private strategies: SourceStrategy[] = []\n\n /**\n * Register a source resolution strategy.\n */\n register(strategy: SourceStrategy): void {\n this.strategies.push(strategy)\n this.strategies.sort((a, b) => a.priority - b.priority)\n }\n\n /**\n * Resolve the source file and position for a DOM element.\n * Tries all strategies in priority order.\n *\n * Also walks up the DOM tree if the exact element has no source.\n */\n resolve(el: Element): ResolvedSource | null {\n // Try the element itself first\n const direct = this.tryResolve(el)\n if (direct) return direct\n\n // Walk up ancestors\n let current = el.parentElement\n while (current) {\n const resolved = this.tryResolve(current)\n if (resolved) return resolved\n current = current.parentElement\n }\n\n return null\n }\n\n private tryResolve(el: Element): ResolvedSource | null {\n for (const strategy of this.strategies) {\n try {\n const result = strategy.resolve(el)\n if (result) return result\n } catch {\n // Strategy failed — try next\n }\n }\n return null\n }\n}\n\n/**\n * The global source resolver instance.\n * Strategies are registered at module initialization time.\n */\nexport const sourceResolver = new SourceResolverImpl()\n\n// ── Built-in strategies ────────────────────────────────────────────\n\n/**\n * Strategy: data-editable-* attributes (injected by our annotation transform)\n */\nexport const editableAttrsStrategy: SourceStrategy = {\n name: \"data-editable\",\n priority: 10,\n resolve(el) {\n const file = el.getAttribute(\"data-editable-file\")\n if (!file) return null\n\n const line = parseInt(el.getAttribute(\"data-editable-line\") || \"0\", 10)\n const col = parseInt(el.getAttribute(\"data-editable-col\") || \"0\", 10)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line, columnNumber: col, label, strategy: \"data-editable\" }\n },\n}\n\n/**\n * Strategy: data-astro-source-* attributes (Astro's native dev toolbar)\n */\nexport const astroSourceStrategy: SourceStrategy = {\n name: \"data-astro-source\",\n priority: 20,\n resolve(el) {\n const file = el.getAttribute(\"data-astro-source-file\")\n if (!file) return null\n\n const loc = el.getAttribute(\"data-astro-source-loc\") || \"\"\n const [line, col] = loc.split(\":\").map(Number)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line || 0, columnNumber: col || 0, label, strategy: \"data-astro-source\" }\n },\n}\n\n/**\n * Strategy: data-astro-cid-* → stylesheet CSS → data-vite-dev-id\n * Traces the Astro scoping CID through stylesheets to find the source file.\n */\nexport const astroCidStrategy: SourceStrategy = {\n name: \"astro-cid\",\n priority: 30,\n resolve(el) {\n // Find the CID attribute on this element or an ancestor\n let cidAttr: string | null = null\n let current: Element | null = el\n while (current) {\n for (const attr of current.attributes) {\n if (attr.name.startsWith(\"data-astro-cid-\")) {\n cidAttr = attr.name\n break\n }\n }\n if (cidAttr) break\n current = current.parentElement\n }\n if (!cidAttr) return null\n\n // Find the <style> tag whose CSS references this CID\n const cidSelector = `[${cidAttr}]`\n for (const style of document.querySelectorAll(\"style[data-vite-dev-id]\")) {\n if ((style.textContent || \"\").includes(cidSelector)) {\n const devId = style.getAttribute(\"data-vite-dev-id\")!\n const file = devId.split(\"?\")[0]\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n return { fileName: file, lineNumber: 0, columnNumber: 0, label, strategy: \"astro-cid\" }\n }\n }\n\n return null\n },\n}\n\n/**\n * Strategy: CSS stylesheet data-vite-dev-id (for CSS source files)\n */\nexport const viteDevIdStrategy: SourceStrategy = {\n name: \"vite-dev-id\",\n priority: 40,\n resolve(_el) {\n // This strategy works on stylesheets, not elements.\n // Used by the CSS inspector separately.\n return null\n },\n}\n\n// Register built-in strategies\nsourceResolver.register(editableAttrsStrategy)\nsourceResolver.register(astroSourceStrategy)\nsourceResolver.register(astroCidStrategy)\n","/**\n * Expression Field — renders an interactive UI for editing string\n * literals inside JavaScript expressions.\n *\n * Given class={active ? \"on\" : \"off\"} with rendered value \"on\", renders:\n *\n * ┌──────────────────────────────────────────────────┐\n * │ active ? [if ✓: on_____] : [else: off____] │\n * │ ACTIVE (green) inactive (dim) │\n * │ [raw] │\n * └──────────────────────────────────────────────────┘\n *\n * The \"active\" state is inferred by comparing the rendered DOM value\n * against each string literal. Literals whose value appears in the\n * rendered output are marked active; others are dimmed.\n *\n * This is framework-agnostic — works for both React JSX and Astro.\n */\n\nexport interface ExpressionLiteral {\n value: string\n offset: number\n quote: string\n context: string\n}\n\nexport interface ExpressionChange {\n offset: number\n oldValue: string\n newValue: string\n}\n\n/**\n * Determine which string literals are \"active\" (present in the rendered value).\n *\n * For class={active ? \"on\" : \"off\"} with rendered \"on\":\n * - \"on\" → active (it's in the output)\n * - \"off\" → inactive (it's not)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base highlight\":\n * - \"base\" → active\n * - \"highlight\" → active (both are in the output)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base\":\n * - \"base\" → active\n * - \"highlight\" → inactive (conditional was false)\n */\nexport function inferActiveLiterals(\n literals: ExpressionLiteral[],\n renderedValue: string,\n): Map<number, boolean> {\n const result = new Map<number, boolean>()\n\n for (const lit of literals) {\n if (!lit.value) {\n // Empty strings are always \"active\" (they don't add anything)\n result.set(lit.offset, true)\n continue\n }\n\n // Check if this literal's value appears in the rendered output.\n // For class values, the rendered output is space-separated classes,\n // so we check if the literal is a substring or if all its classes are present.\n const literalClasses = lit.value.split(/\\s+/).filter(Boolean)\n const renderedClasses = renderedValue.split(/\\s+/).filter(Boolean)\n\n if (literalClasses.length > 0 && literalClasses.every((c) => renderedClasses.includes(c))) {\n result.set(lit.offset, true)\n } else if (renderedValue.includes(lit.value)) {\n // Direct substring match (for non-class attributes)\n result.set(lit.offset, true)\n } else {\n result.set(lit.offset, false)\n }\n }\n\n return result\n}\n\n/**\n * Create an interactive expression editor.\n *\n * @param expression — the raw expression string (between { and })\n * @param literals — the editable string literals extracted from the expression\n * @param renderedValue — the current rendered value from the DOM (null if unknown)\n * @param onChange — called when any literal is edited\n * @returns the DOM element for the editor\n */\nexport function createExpressionField(\n expression: string,\n literals: ExpressionLiteral[],\n renderedValue: string | null,\n onChange: (changes: ExpressionChange[]) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"expr-field\"\n\n // Infer which literals are active\n const activeMap = renderedValue\n ? inferActiveLiterals(literals, renderedValue)\n : null\n\n // Track pending changes\n const pendingChanges = new Map<number, ExpressionChange>()\n\n // ── Structured view ────────────────────────────────────\n\n const structuredView = document.createElement(\"div\")\n structuredView.className = \"expr-structured\"\n\n if (literals.length === 0) {\n // No editable literals — show as read-only\n const readOnly = document.createElement(\"span\")\n readOnly.className = \"expr-readonly\"\n readOnly.textContent = expression\n readOnly.title = \"No editable string literals in this expression\"\n structuredView.appendChild(readOnly)\n } else {\n // Build the interleaved view: code segments + editable fields\n let lastEnd = 0\n\n for (const lit of literals) {\n // Code segment before this literal\n const codeBefore = expression.slice(lastEnd, lit.offset)\n if (codeBefore.trim()) {\n const codeSpan = document.createElement(\"span\")\n codeSpan.className = \"expr-code\"\n codeSpan.textContent = codeBefore.trim()\n structuredView.appendChild(codeSpan)\n }\n\n // Is this literal active (matches rendered value)?\n const isActive = activeMap?.get(lit.offset) ?? null\n\n // Editable field for the string literal\n const field = createLiteralField(lit, isActive, (newValue) => {\n if (newValue !== lit.value) {\n pendingChanges.set(lit.offset, {\n offset: lit.offset,\n oldValue: lit.value,\n newValue,\n })\n } else {\n pendingChanges.delete(lit.offset)\n }\n onChange(Array.from(pendingChanges.values()))\n })\n structuredView.appendChild(field)\n\n // Calculate end of this literal in the expression\n if (lit.quote === \"`\") {\n lastEnd = lit.offset + lit.value.length\n } else {\n lastEnd = lit.offset + lit.value.length + 2 // +2 for quotes\n }\n }\n\n // Trailing code after the last literal\n const trailingCode = expression.slice(lastEnd).trim()\n if (trailingCode) {\n const trailSpan = document.createElement(\"span\")\n trailSpan.className = \"expr-code\"\n trailSpan.textContent = trailingCode\n structuredView.appendChild(trailSpan)\n }\n }\n\n // ── Rendered value indicator ───────────────────────────\n\n if (renderedValue !== null) {\n const rendered = document.createElement(\"div\")\n rendered.className = \"expr-rendered\"\n rendered.title = \"Current rendered value from the DOM\"\n\n const label = document.createElement(\"span\")\n label.className = \"expr-rendered-label\"\n label.textContent = \"rendered:\"\n\n const val = document.createElement(\"span\")\n val.className = \"expr-rendered-value\"\n val.textContent = renderedValue || \"(empty)\"\n\n rendered.appendChild(label)\n rendered.appendChild(val)\n structuredView.insertBefore(rendered, structuredView.firstChild)\n }\n\n // ── Raw view (hidden by default) ───────────────────────\n\n const rawView = document.createElement(\"div\")\n rawView.className = \"expr-raw\"\n rawView.style.display = \"none\"\n\n const rawTextarea = document.createElement(\"textarea\")\n rawTextarea.className = \"text-edit-input\"\n rawTextarea.value = expression\n rawTextarea.rows = Math.min(6, expression.split(\"\\n\").length + 1)\n rawTextarea.style.fontFamily = \"ui-monospace, monospace\"\n rawTextarea.style.fontSize = \"11px\"\n rawView.appendChild(rawTextarea)\n\n // ── Toggle button ──────────────────────────────────────\n\n const toggleRow = document.createElement(\"div\")\n toggleRow.style.cssText =\n \"display:flex;justify-content:flex-end;margin-top:4px\"\n\n const toggleBtn = document.createElement(\"button\")\n toggleBtn.className = \"btn btn-secondary\"\n toggleBtn.style.cssText = \"padding:2px 6px;font-size:10px\"\n toggleBtn.textContent = \"raw\"\n toggleBtn.title = \"Toggle raw expression editing\"\n\n let isRaw = false\n toggleBtn.addEventListener(\"click\", () => {\n isRaw = !isRaw\n structuredView.style.display = isRaw ? \"none\" : \"\"\n rawView.style.display = isRaw ? \"\" : \"none\"\n toggleBtn.textContent = isRaw ? \"visual\" : \"raw\"\n })\n\n toggleRow.appendChild(toggleBtn)\n\n container.appendChild(structuredView)\n container.appendChild(rawView)\n container.appendChild(toggleRow)\n\n return container\n}\n\n/**\n * Create an editable field for a single string literal.\n *\n * @param lit — the literal metadata\n * @param isActive — true if this literal's value is in the rendered DOM output,\n * false if the condition was falsy, null if unknown\n * @param onChange — called when the input value changes\n */\nfunction createLiteralField(\n lit: ExpressionLiteral,\n isActive: boolean | null,\n onChange: (newValue: string) => void,\n): HTMLElement {\n const wrapper = document.createElement(\"span\")\n wrapper.className = \"expr-literal\"\n if (isActive === true) wrapper.classList.add(\"expr-active\")\n if (isActive === false) wrapper.classList.add(\"expr-inactive\")\n wrapper.title = contextLabel(lit.context) +\n (isActive === true ? \" (currently active)\" : \"\") +\n (isActive === false ? \" (currently inactive)\" : \"\")\n\n // Context badge with active indicator\n const badge = document.createElement(\"span\")\n badge.className = \"expr-badge\"\n if (isActive === true) badge.classList.add(\"expr-badge-active\")\n if (isActive === false) badge.classList.add(\"expr-badge-inactive\")\n const indicator = isActive === true ? \"\\u2713 \" : isActive === false ? \"\\u25CB \" : \"\"\n badge.textContent = indicator + shortContextLabel(lit.context)\n wrapper.appendChild(badge)\n\n // The editable input\n const input = document.createElement(\"input\")\n input.className = \"var-input expr-input\"\n if (isActive === false) input.classList.add(\"expr-input-inactive\")\n input.value = lit.value\n input.style.fontSize = \"11px\"\n\n // Auto-size the input to fit content\n const updateWidth = () => {\n const len = Math.max(input.value.length, 3)\n input.style.width = `${len + 1}ch`\n }\n updateWidth()\n\n input.addEventListener(\"input\", updateWidth)\n input.addEventListener(\"change\", () => onChange(input.value))\n\n wrapper.appendChild(input)\n\n return wrapper\n}\n\n/**\n * Human-readable label for the expression context.\n */\nfunction contextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"Value when condition is true\"\n case \"ternary-alternate\":\n return \"Value when condition is false\"\n case \"conditional\":\n return \"Applied when condition is truthy\"\n case \"fallback\":\n return \"Fallback value\"\n case \"call-arg\":\n return \"Function argument\"\n case \"template-static\":\n return \"Static text in template\"\n case \"object-value\":\n return \"Object property value\"\n case \"array-item\":\n return \"Array item\"\n default:\n return \"Editable value\"\n }\n}\n\n/**\n * Short badge label for the context.\n */\nfunction shortContextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"if\"\n case \"ternary-alternate\":\n return \"else\"\n case \"conditional\":\n return \"when\"\n case \"fallback\":\n return \"or\"\n case \"call-arg\":\n return \"arg\"\n case \"template-static\":\n return \"text\"\n case \"object-value\":\n return \"val\"\n case \"array-item\":\n return \"item\"\n default:\n return \"\"\n }\n}\n","/**\n * Class Editor — renders a tag-style editor for space-separated\n * CSS class strings. Each class is shown as a removable tag,\n * and new classes can be added.\n *\n * Given \"rounded-lg border ring-2 ring-blue-500\":\n *\n * ┌─────────────────────────────────────────────────┐\n * │ [rounded-lg ×] [border ×] [ring-2 ×] │\n * │ [ring-blue-500 ×] │\n * │ [+ add class________________________] │\n * └─────────────────────────────────────────────────┘\n *\n * Each tag can be removed (×) or edited (click to select + type).\n * The \"add class\" input lets you type new classes.\n * onChange fires with the full updated class string.\n */\n\n/**\n * Create a class tag editor for a space-separated class string.\n *\n * @param classes — the current class string (e.g., \"rounded-lg border\")\n * @param onChange — called with the updated class string\n * @returns the DOM element for the editor\n */\nexport function createClassEditor(\n classes: string,\n onChange: (newClasses: string) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"class-editor\"\n\n let currentClasses = classes.split(/\\s+/).filter(Boolean)\n\n function render() {\n container.textContent = \"\"\n\n const tagRow = document.createElement(\"div\")\n tagRow.className = \"class-tags\"\n\n for (let i = 0; i < currentClasses.length; i++) {\n const cls = currentClasses[i]\n const tag = createClassTag(cls, {\n onRemove: () => {\n currentClasses.splice(i, 1)\n onChange(currentClasses.join(\" \"))\n render()\n },\n onEdit: (newValue) => {\n if (newValue.trim()) {\n // Handle pasting multiple classes\n const parts = newValue.trim().split(/\\s+/)\n currentClasses.splice(i, 1, ...parts)\n } else {\n currentClasses.splice(i, 1)\n }\n onChange(currentClasses.join(\" \"))\n render()\n },\n })\n tagRow.appendChild(tag)\n }\n\n container.appendChild(tagRow)\n\n // Add class input\n const addInput = document.createElement(\"input\")\n addInput.className = \"var-input class-add-input\"\n addInput.placeholder = \"+ add class\"\n addInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && addInput.value.trim()) {\n const newClasses = addInput.value.trim().split(/\\s+/)\n currentClasses.push(...newClasses)\n onChange(currentClasses.join(\" \"))\n addInput.value = \"\"\n render()\n }\n })\n\n container.appendChild(addInput)\n }\n\n render()\n return container\n}\n\n/**\n * Create a single class tag element.\n */\nfunction createClassTag(\n className: string,\n handlers: {\n onRemove: () => void\n onEdit: (newValue: string) => void\n },\n): HTMLElement {\n const tag = document.createElement(\"span\")\n tag.className = \"class-tag\"\n\n const label = document.createElement(\"span\")\n label.className = \"class-tag-label\"\n label.textContent = className\n label.title = className\n\n // Click to edit\n label.addEventListener(\"dblclick\", () => {\n const input = document.createElement(\"input\")\n input.className = \"class-tag-edit\"\n input.value = className\n input.style.width = `${Math.max(className.length, 3) + 2}ch`\n\n input.addEventListener(\"blur\", () => {\n handlers.onEdit(input.value)\n })\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n handlers.onEdit(input.value)\n }\n if (e.key === \"Escape\") {\n handlers.onEdit(className) // revert\n }\n })\n\n tag.replaceChild(input, label)\n input.focus()\n input.select()\n })\n\n const removeBtn = document.createElement(\"button\")\n removeBtn.className = \"class-tag-remove\"\n removeBtn.textContent = \"\\u00d7\"\n removeBtn.title = `Remove ${className}`\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation()\n handlers.onRemove()\n })\n\n tag.appendChild(label)\n tag.appendChild(removeBtn)\n\n return tag\n}\n","/**\n * Value Source Indicator — shows whether a value came from\n * a string literal, a variable, or a complex expression.\n *\n * For literal: class=\"hero\"\n * → [literal] \"hero\" — editable directly\n *\n * For variable: class={className}\n * → [variable] className → \"hero container\" — edit in source\n *\n * For expression: class={cn(\"base\", active && \"active\")}\n * → [expression] cn(\"base\", ...) — edit string literals\n */\n\nexport type ValueSource = \"literal\" | \"variable\" | \"expression\"\n\n/**\n * Create a value source indicator element.\n *\n * @param source — the source type\n * @param detail — additional context (variable name, expression preview)\n * @returns the DOM element\n */\nexport function createValueSourceIndicator(\n source: ValueSource,\n detail?: string,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"value-source\"\n\n const badge = document.createElement(\"span\")\n badge.className = `value-source-badge ${source}`\n badge.textContent = source\n\n container.appendChild(badge)\n\n if (detail) {\n const detailSpan = document.createElement(\"span\")\n detailSpan.textContent = detail\n detailSpan.style.fontFamily = \"ui-monospace, monospace\"\n container.appendChild(detailSpan)\n }\n\n // Add context-specific hint\n const hint = document.createElement(\"span\")\n hint.style.color = \"#334155\"\n\n switch (source) {\n case \"literal\":\n hint.textContent = \"— editable\"\n break\n case \"variable\":\n hint.textContent = \"— edit in source\"\n break\n case \"expression\":\n hint.textContent = \"— edit string parts\"\n break\n }\n\n container.appendChild(hint)\n\n return container\n}\n"],"mappings":"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","names":[]}
{"version":3,"sources":["../src/element.ts","../src/hmr/suppress.ts","../src/patcher/orchestrate.ts","../src/patcher/text-patcher.ts","../src/patcher/patch-types.ts","../src/resolve/source-resolver.ts","../src/editor/expression-field.ts","../src/editor/class-editor.ts","../src/editor/value-source.ts"],"sourcesContent":["/**\n * Unified element model for editable-jsx.\n *\n * Every framework (React, Astro, raw HTML) produces ElementNodes\n * through a FrameworkAdapter. The editor UI consumes ElementNodes\n * without knowing which framework produced them.\n *\n * Key invariant: every editable element has a SourceLocation that\n * anchors it to a position in a source file. This is what makes\n * save-to-source work across all frameworks.\n */\n\nimport type { BasePatch, SourceLocation } from \"./types.js\"\n\n// ── Editable Property ───────────────────────────────────────────────\n\n/**\n * A single editable property on an element.\n * The `kind` discriminant determines which patcher handles saves.\n */\nexport type EditableProperty =\n | EditableProp\n | EditableCSSProperty\n | EditableCSSVariable\n | EditableText\n | EditableAttribute\n | EditableClassNamePart\n\n/** Component prop (React) */\nexport interface EditableProp {\n kind: \"prop\"\n name: string\n value: unknown\n serializable: boolean\n source: SourceLocation\n}\n\n/** CSS property on a matched rule */\nexport interface EditableCSSProperty {\n kind: \"css-property\"\n name: string\n value: string\n selector: string\n sourceFile: string\n overridden: boolean\n}\n\n/** CSS custom property (variable) */\nexport interface EditableCSSVariable {\n kind: \"css-variable\"\n name: string\n value: string\n resolvedValue: string\n scope: string\n sourceFile: string\n}\n\n/** Text content of an element */\nexport interface EditableText {\n kind: \"text\"\n value: string\n source: SourceLocation\n}\n\n/** HTML/Astro template attribute */\nexport interface EditableAttribute {\n kind: \"attribute\"\n name: string\n value: string\n source: SourceLocation\n}\n\n/** A single string literal inside a className expression (React) */\nexport interface EditableClassNamePart {\n kind: \"classname-part\"\n value: string\n partSource: SourceLocation\n parentSource: SourceLocation\n type: \"static\" | \"conditional\" | \"fallback\" | \"template\"\n}\n\n// ── Element Node ────────────────────────────────────────────────────\n\n/**\n * Universal representation of one editable element.\n * Produced by a FrameworkAdapter from framework-specific data.\n */\nexport interface ElementNode {\n /** Stable identifier within the editor session */\n id: string\n\n /** Human-readable label (tag name, component name) */\n displayName: string\n\n /** Raw HTML tag or component name */\n elementName: string\n\n /** Source location of the opening tag */\n source: SourceLocation\n\n /** Which file this element lives in */\n sourceFile: string\n\n /** Parent component name (null for plain HTML elements) */\n componentName: string | null\n\n /** Framework that produced this node */\n framework: \"react\" | \"astro\" | \"css\" | \"html\"\n\n /** All editable properties */\n properties: EditableProperty[]\n\n /** Tree relationships */\n parentId: string | null\n childIds: string[]\n\n /** Whether this node has unsaved changes */\n dirty: boolean\n\n /** The live DOM node (null for server-only representations) */\n domNode: Element | null\n}\n\n// ── Property Change ─────────────────────────────────────────────────\n\n/** A pending edit — what the user changed but hasn't saved yet. */\nexport interface PropertyChange {\n property: EditableProperty\n newValue: unknown\n}\n\n// ── Component Tree ──────────────────────────────────────────────────\n\n/**\n * Flat registry of ElementNodes with parent/child lookup.\n */\nexport class ComponentTree {\n nodes: Map<string, ElementNode> = new Map()\n\n roots(): ElementNode[] {\n const result: ElementNode[] = []\n for (const node of this.nodes.values()) {\n if (node.parentId === null) result.push(node)\n }\n return result\n }\n\n upsert(node: ElementNode): void {\n this.nodes.set(node.id, node)\n\n // Update parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent && !parent.childIds.includes(node.id)) {\n parent.childIds.push(node.id)\n }\n }\n }\n\n remove(id: string): void {\n const node = this.nodes.get(id)\n if (!node) return\n\n // Remove from parent's childIds\n if (node.parentId) {\n const parent = this.nodes.get(node.parentId)\n if (parent) {\n parent.childIds = parent.childIds.filter((cid) => cid !== id)\n }\n }\n\n this.nodes.delete(id)\n }\n\n walk(visitor: (node: ElementNode, depth: number) => void): void {\n const visited = new Set<string>()\n const visit = (node: ElementNode, depth: number) => {\n if (visited.has(node.id)) return\n visited.add(node.id)\n visitor(node, depth)\n for (const childId of node.childIds) {\n const child = this.nodes.get(childId)\n if (child) visit(child, depth + 1)\n }\n }\n for (const root of this.roots()) {\n visit(root, 0)\n }\n }\n\n get(id: string): ElementNode | undefined {\n return this.nodes.get(id)\n }\n\n clear(): void {\n this.nodes.clear()\n }\n}\n\n// ── Framework Adapter ───────────────────────────────────────────────\n\n/**\n * Each framework implements this interface to bridge its native\n * element representation into the unified ElementNode model.\n *\n * The adapter is the ONLY place where framework-specific knowledge lives.\n * The editor UI, component tree, and save orchestration are all\n * framework-agnostic — they work with ElementNodes and PropertyChanges.\n */\nexport interface FrameworkAdapter<NativeElement = unknown, NativePatch extends BasePatch = BasePatch> {\n /** Framework identifier */\n readonly framework: ElementNode[\"framework\"]\n\n /** Convert a native element to the universal ElementNode. */\n toElementNode(native: NativeElement): ElementNode\n\n /** Convert pending property changes to framework-specific patches. */\n toPatches(node: ElementNode, changes: PropertyChange[]): NativePatch[]\n\n /** Apply framework-specific patches to source files (server-side). */\n applyPatches(patches: NativePatch[]): Promise<void>\n\n /** Live preview a property change in the browser (optional). */\n preview?(node: ElementNode, change: PropertyChange): void\n\n /** Revert a live preview (optional). */\n revertPreview?(node: ElementNode, change: PropertyChange): void\n}\n","import type { HmrSuppressMap } from \"../types.js\"\n\n/**\n * Create a new HMR suppression map.\n */\nexport function createSuppressMap(): HmrSuppressMap {\n return new Map()\n}\n\n/**\n * Mark a file for HMR suppression with auto-expiry.\n *\n * Call this after writing a file to prevent the write from\n * triggering an HMR update (feedback loop). The entry auto-expires\n * after `ttlMs` milliseconds to prevent stale entries from\n * permanently suppressing HMR.\n */\nexport function suppressFile(\n map: HmrSuppressMap,\n file: string,\n ttlMs: number = 5000,\n): void {\n const existing = map.get(file)\n if (existing?.timeout) clearTimeout(existing.timeout)\n\n const timeout = setTimeout(() => map.delete(file), ttlMs)\n map.set(file, { skip: true, timeout })\n}\n\n/**\n * Create a Vite `handleHotUpdate` handler that suppresses\n * HMR for files in the suppress map.\n *\n * Returns `[]` (empty module array) to suppress the update,\n * or `undefined` to let it proceed normally.\n */\nexport function createHotUpdateHandler(\n map: HmrSuppressMap,\n): (ctx: { file: string }) => [] | undefined {\n return ({ file }) => {\n const entry = map.get(file)\n if (entry?.skip) {\n map.delete(file)\n return [] // Suppress HMR update\n }\n return undefined\n }\n}\n","/**\n * Shared patch orchestration — groups patches by file and applies them\n * in parallel with error collection.\n *\n * Used by all framework-specific patchers (JSX/ts-morph, CSS/PostCSS, Astro/compiler).\n */\n\n// ── Per-file mutex ─────────────────────────────────────────────────\n\n/**\n * Simple async mutex: serializes access per key (file path).\n * Two concurrent `applyPatches` calls on the same file will\n * be sequenced rather than racing.\n */\nconst fileLocks = new Map<string, Promise<void>>()\n\nasync function withFileLock(\n file: string,\n fn: () => Promise<void>,\n): Promise<void> {\n // Wait for the previous operation on this file (if any)\n const prev = fileLocks.get(file) ?? Promise.resolve()\n\n // Chain our work after the previous promise.\n // We store the chain BEFORE awaiting so the next caller sees us.\n const current = prev.then(fn, fn)\n fileLocks.set(file, current)\n\n try {\n await current\n } finally {\n // Clean up if we're still the tail of the chain\n if (fileLocks.get(file) === current) {\n fileLocks.delete(file)\n }\n }\n}\n\n/**\n * Group patches by file path.\n *\n * The `getFile` callback extracts the file path from a patch,\n * allowing different patch shapes (e.g., `patch.file` vs `patch.source.fileName`).\n */\nexport function groupPatchesByFile<P>(\n patches: P[],\n getFile: (patch: P) => string,\n): Record<string, P[]> {\n return patches.reduce(\n (acc, patch) => {\n const file = getFile(patch)\n ;(acc[file] = acc[file] || []).push(patch)\n return acc\n },\n {} as Record<string, P[]>,\n )\n}\n\n/**\n * Apply patches in parallel, grouped by file.\n *\n * Calls `applyFileFn` for each file group. Collects errors from\n * individual files and throws a combined error if any failed.\n *\n * Per-file access is serialized via an async mutex so that two\n * concurrent `applyPatches` calls on the same file don't race.\n *\n * @param patches - All patches to apply\n * @param getFile - Extracts the file path from a patch\n * @param applyFileFn - Applies patches to a single file\n */\nexport async function applyPatches<P>(\n patches: P[],\n getFile: (patch: P) => string,\n applyFileFn: (file: string, patches: P[]) => Promise<void>,\n): Promise<void> {\n const grouped = groupPatchesByFile(patches, getFile)\n const errors: Array<{ file: string; error: Error }> = []\n\n await Promise.all(\n Object.entries(grouped).map(async ([file, filePatches]) => {\n try {\n await withFileLock(file, () => applyFileFn(file, filePatches))\n } catch (err: any) {\n console.error(`[editable] Failed to apply patches to ${file}:`, err)\n errors.push({ file, error: err })\n }\n }),\n )\n\n if (errors.length > 0) {\n const fileList = errors.map((e) => e.file).join(\", \")\n throw new Error(\n `Patch failed for ${errors.length} file(s): ${fileList}. ${errors[0].error.message}`,\n )\n }\n}\n","/**\n * TextPatcher — surgical string replacement in source files.\n *\n * This is the \"dumb\" layer: it finds text in a source string and\n * replaces it. It does NOT parse any AST — it works on raw strings.\n *\n * Three replacement strategies:\n * 1. Position-based: find text at exact line:col\n * 2. Normalized: collapse whitespace, search with position map\n * 3. Literal: find exact string at a character offset\n *\n * The \"smart\" layer (ASTPatcher) finds WHERE to replace using\n * framework-specific AST parsing. TextPatcher does the actual splice.\n */\n\nexport interface ReplaceOptions {\n /** If true, only match text between > and < (text node context) */\n textNodeOnly?: boolean\n /** Skip the frontmatter region (--- ... ---) */\n skipFrontmatter?: boolean\n /** Skip content inside <style> blocks */\n skipStyleBlocks?: boolean\n}\n\n/**\n * Replace text at an exact character offset in a source string.\n * Used for expression literal replacement and AST-guided edits.\n */\nexport function replaceAtOffset(\n source: string,\n offset: number,\n oldText: string,\n newText: string,\n): string {\n const actual = source.slice(offset, offset + oldText.length)\n if (actual !== oldText) {\n throw new Error(\n `Text mismatch at offset ${offset}: expected \"${oldText.slice(0, 30)}\", found \"${actual.slice(0, 30)}\"`,\n )\n }\n return source.slice(0, offset) + newText + source.slice(offset + oldText.length)\n}\n\n/**\n * Replace text at a specific line and column (1-based).\n * Falls back to normalized search if not found at the exact position.\n */\nexport function replaceAtPosition(\n source: string,\n line: number,\n col: number,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n if (line > 0) {\n const lines = source.split(\"\\n\")\n const lineIdx = line - 1\n if (lineIdx >= 0 && lineIdx < lines.length) {\n const colIdx = Math.max(0, col - 1)\n const foundIdx = lines[lineIdx].indexOf(oldText, colIdx)\n if (foundIdx !== -1) {\n lines[lineIdx] =\n lines[lineIdx].slice(0, foundIdx) +\n newText +\n lines[lineIdx].slice(foundIdx + oldText.length)\n return lines.join(\"\\n\")\n }\n }\n // Position-based failed — fall through to normalized search\n }\n\n return replaceNormalized(source, oldText, newText, options)\n}\n\n/**\n * Replace text using whitespace-normalized matching.\n *\n * DOM textContent collapses whitespace across lines, but the source\n * may have the text split across multiple lines with indentation.\n * This normalizes both sides and maps positions back to the original.\n *\n * Optionally validates that the match is in text-node context\n * (between > and <, not inside an attribute value).\n */\nexport function replaceNormalized(\n source: string,\n oldText: string,\n newText: string,\n options: ReplaceOptions = {},\n): string {\n const normalizedOld = oldText.replace(/\\s+/g, \" \").trim()\n if (!normalizedOld) {\n throw new Error(\"Cannot search for empty/whitespace-only text\")\n }\n\n // Determine the search region\n let regionStart = 0\n let regionEnd = source.length\n\n if (options.skipFrontmatter) {\n const fmMatch = source.match(/^---\\r?\\n/)\n if (fmMatch) {\n const fmEnd = source.indexOf(\"\\n---\", fmMatch[0].length)\n if (fmEnd !== -1) regionStart = fmEnd + 4\n }\n }\n\n if (options.skipStyleBlocks) {\n const styleStart = source.indexOf(\"<style\", regionStart)\n if (styleStart !== -1) regionEnd = styleStart\n }\n\n const region = source.slice(regionStart, regionEnd)\n\n // Build normalized version with position map\n const posMap: number[] = []\n let normalized = \"\"\n let inWhitespace = false\n\n for (let i = 0; i < region.length; i++) {\n if (/\\s/.test(region[i])) {\n if (!inWhitespace && normalized.length > 0) {\n normalized += \" \"\n posMap.push(i)\n inWhitespace = true\n }\n } else {\n normalized += region[i]\n posMap.push(i)\n inWhitespace = false\n }\n }\n\n // Search for matches\n let searchFrom = 0\n while (true) {\n const matchIdx = normalized.indexOf(normalizedOld, searchFrom)\n if (matchIdx === -1) {\n throw new Error(\n `Text not found in template: \"${oldText.length > 60 ? oldText.slice(0, 60) + \"...\" : oldText}\"`,\n )\n }\n\n const origStart = posMap[matchIdx]\n const matchEndNorm = matchIdx + normalizedOld.length - 1\n const origEnd =\n matchEndNorm < posMap.length ? posMap[matchEndNorm] + 1 : region.length\n\n // Optionally validate text-node context (between > and <)\n if (options.textNodeOnly) {\n const before = region.slice(0, origStart)\n const lastGt = before.lastIndexOf(\">\")\n const lastLt = before.lastIndexOf(\"<\")\n\n if (lastGt <= lastLt) {\n // Inside a tag (attribute context) — skip this match\n searchFrom = matchIdx + 1\n continue\n }\n }\n\n // Replace in the original source\n const absStart = regionStart + origStart\n const absEnd = regionStart + origEnd\n return source.slice(0, absStart) + newText + source.slice(absEnd)\n }\n}\n","/**\n * Unified Patch Schema — all framework patches are routable through\n * a single discriminated union.\n *\n * The action_type prefix determines which framework handler processes\n * the patch:\n * - \"css.*\" → CSS patcher (PostCSS)\n * - \"astro.*\" → Astro patcher (@astrojs/compiler)\n * - \"jsx.*\" → JSX patcher (ts-morph)\n * - \"text.*\" → Text patcher (normalized search)\n *\n * All patches share: action_type + file.\n * Framework-specific data lives in the patch body.\n */\n\nimport type { BasePatch } from \"../types.js\"\n\n// ── CSS Patches ────────────────────────────────────────────────────\n\nexport interface CSSVariablePatch extends BasePatch {\n action_type: \"css.variable\"\n variable: { name: string; value: string; scope: string }\n styleBlockOffset: number\n}\n\nexport interface CSSPropertyPatch extends BasePatch {\n action_type: \"css.property\"\n property: { selector: string; name: string; value: string }\n}\n\n// ── Text Patches ───────────────────────────────────────────────────\n\nexport interface TextPatch extends BasePatch {\n action_type: \"text.replace\"\n oldText: string\n newText: string\n /** Position hint (0 = use normalized search) */\n line: number\n col: number\n}\n\n// ── Astro Patches ──────────────────────────────────────────────────\n\nexport interface AstroAttrPatch extends BasePatch {\n action_type: \"astro.attribute\"\n elementLine: number\n elementCol: number\n attribute: string\n value: string\n}\n\nexport interface AstroExprPatch extends BasePatch {\n action_type: \"astro.expression\"\n elementLine: number\n elementCol: number\n attribute: string\n oldLiteral: string\n newLiteral: string\n literalOffset: number\n}\n\n// ── JSX Patches ────────────────────────────────────────────────────\n\nexport interface JSXAttrPatch extends BasePatch {\n action_type: \"jsx.attribute\"\n source: { lineNumber: number; columnNumber: number }\n path: string\n value: unknown\n}\n\nexport interface JSXClassNamePatch extends BasePatch {\n action_type: \"jsx.classname\"\n source: { lineNumber: number; columnNumber: number }\n partLine: number\n partCol: number\n oldValue: string\n newValue: string\n}\n\n// ── Union ──────────────────────────────────────────────────────────\n\nexport type Patch =\n | CSSVariablePatch\n | CSSPropertyPatch\n | TextPatch\n | AstroAttrPatch\n | AstroExprPatch\n | JSXAttrPatch\n | JSXClassNamePatch\n\n/**\n * Extract the framework prefix from a patch action_type.\n */\nexport function patchFramework(patch: Patch): string {\n return patch.action_type.split(\".\")[0]\n}\n\n/**\n * Route patches to framework-specific handlers.\n */\nexport type PatchRouter = {\n [framework: string]: (file: string, patches: Patch[]) => Promise<void>\n}\n\n/**\n * Create a patch dispatcher that routes patches by framework prefix.\n */\nexport function createPatchDispatcher(router: PatchRouter) {\n return async (file: string, patches: Patch[]): Promise<void> => {\n // Group by framework\n const byFramework = new Map<string, Patch[]>()\n for (const patch of patches) {\n const fw = patchFramework(patch)\n if (!byFramework.has(fw)) byFramework.set(fw, [])\n byFramework.get(fw)!.push(patch)\n }\n\n // Dispatch to framework handlers sequentially (same file)\n for (const [framework, fwPatches] of byFramework) {\n const handler = router[framework]\n if (!handler) {\n console.warn(`[editable] No handler for patch framework: ${framework}`)\n continue\n }\n await handler(file, fwPatches)\n }\n }\n}\n","/**\n * SourceResolver — canonical \"DOM element → source file + position\" resolution.\n *\n * One module, one interface, one fallback chain. Every framework registers\n * its strategies here instead of implementing its own resolution logic.\n *\n * Strategies are tried in priority order until one succeeds:\n * 1. data-editable-* attributes (our annotation transform)\n * 2. data-astro-source-* attributes (Astro's native dev toolbar)\n * 3. data-astro-cid-* → stylesheet → data-vite-dev-id (CID tracing)\n * 4. Framework-specific strategies (registered by adapters)\n *\n * New frameworks (Vue, Svelte) register a strategy once and\n * get source resolution for free.\n */\n\nimport type { SourceLocation } from \"../types.js\"\n\n/**\n * Resolved source information for a DOM element.\n */\nexport interface ResolvedSource extends SourceLocation {\n /** Human-readable label (e.g., \"src/pages/index.astro\") */\n label: string\n /** How the source was resolved */\n strategy: string\n}\n\n/**\n * A strategy for resolving source location from a DOM element.\n * Returns null if it can't resolve.\n */\nexport interface SourceStrategy {\n /** Strategy name for debugging */\n name: string\n /** Priority (lower = tried first) */\n priority: number\n /** Attempt to resolve source for an element */\n resolve(el: Element): ResolvedSource | null\n}\n\n/**\n * Singleton source resolver with pluggable strategies.\n */\nclass SourceResolverImpl {\n private strategies: SourceStrategy[] = []\n\n /**\n * Register a source resolution strategy.\n */\n register(strategy: SourceStrategy): void {\n this.strategies.push(strategy)\n this.strategies.sort((a, b) => a.priority - b.priority)\n }\n\n /**\n * Resolve the source file and position for a DOM element.\n * Tries all strategies in priority order.\n *\n * Also walks up the DOM tree if the exact element has no source.\n */\n resolve(el: Element): ResolvedSource | null {\n // Try the element itself first\n const direct = this.tryResolve(el)\n if (direct) return direct\n\n // Walk up ancestors\n let current = el.parentElement\n while (current) {\n const resolved = this.tryResolve(current)\n if (resolved) return resolved\n current = current.parentElement\n }\n\n return null\n }\n\n private tryResolve(el: Element): ResolvedSource | null {\n for (const strategy of this.strategies) {\n try {\n const result = strategy.resolve(el)\n if (result) return result\n } catch {\n // Strategy failed — try next\n }\n }\n return null\n }\n}\n\n/**\n * The global source resolver instance.\n * Strategies are registered at module initialization time.\n */\nexport const sourceResolver = new SourceResolverImpl()\n\n// ── Built-in strategies ────────────────────────────────────────────\n\n/**\n * Strategy: data-editable-* attributes (injected by our annotation transform)\n */\nexport const editableAttrsStrategy: SourceStrategy = {\n name: \"data-editable\",\n priority: 10,\n resolve(el) {\n const file = el.getAttribute(\"data-editable-file\")\n if (!file) return null\n\n const line = parseInt(el.getAttribute(\"data-editable-line\") || \"0\", 10)\n const col = parseInt(el.getAttribute(\"data-editable-col\") || \"0\", 10)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line, columnNumber: col, label, strategy: \"data-editable\" }\n },\n}\n\n/**\n * Strategy: data-astro-source-* attributes (Astro's native dev toolbar)\n *\n * IMPORTANT: Astro's dev toolbar STRIPS these attributes from the DOM\n * after page load and stores them in a WeakMap. We check both:\n * 1. The DOM attribute (if it hasn't been stripped yet)\n * 2. Astro's internal WeakMap via getAnnotationsForElement()\n */\nexport const astroSourceStrategy: SourceStrategy = {\n name: \"data-astro-source\",\n priority: 20,\n resolve(el) {\n // 1. Try DOM attributes directly (may already be stripped)\n let file = el.getAttribute(\"data-astro-source-file\")\n let loc = el.getAttribute(\"data-astro-source-loc\") || \"\"\n\n // 2. If stripped, try Astro's internal annotation WeakMap\n if (!file) {\n const astroAnnotations = getAstroAnnotations(el)\n if (astroAnnotations) {\n file = astroAnnotations.file\n loc = astroAnnotations.location || \"\"\n }\n }\n\n if (!file) return null\n\n const [line, col] = loc.split(\":\").map(Number)\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n\n return { fileName: file, lineNumber: line || 0, columnNumber: col || 0, label, strategy: \"data-astro-source\" }\n },\n}\n\n/**\n * Read captured Astro source annotations for an element.\n *\n * Astro's dev toolbar STRIPS data-astro-source-file/loc from the DOM\n * after page load. We capture them before Astro does via an early\n * head-inline script that stores them in window.__editableSourceMap__.\n */\nfunction getAstroAnnotations(\n el: Element,\n): { file: string; location: string } | null {\n try {\n // Read from our pre-captured Map (injected by @editable-jsx/astro)\n const sourceMap = (window as any).__editableSourceMap__ as\n | Map<Element, { file: string; location: string }>\n | undefined\n if (sourceMap) {\n return sourceMap.get(el) ?? null\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Strategy: data-astro-cid-* → stylesheet CSS → data-vite-dev-id\n * Traces the Astro scoping CID through stylesheets to find the source file.\n */\nexport const astroCidStrategy: SourceStrategy = {\n name: \"astro-cid\",\n priority: 30,\n resolve(el) {\n // Find the CID attribute on this element or an ancestor\n let cidAttr: string | null = null\n let current: Element | null = el\n while (current) {\n for (const attr of current.attributes) {\n if (attr.name.startsWith(\"data-astro-cid-\")) {\n cidAttr = attr.name\n break\n }\n }\n if (cidAttr) break\n current = current.parentElement\n }\n if (!cidAttr) return null\n\n // Find the <style> tag whose CSS references this CID\n const cidSelector = `[${cidAttr}]`\n for (const style of document.querySelectorAll(\"style[data-vite-dev-id]\")) {\n if ((style.textContent || \"\").includes(cidSelector)) {\n const devId = style.getAttribute(\"data-vite-dev-id\")!\n const file = devId.split(\"?\")[0]\n const label = file.replace(/^.*\\/src\\//, \"src/\")\n return { fileName: file, lineNumber: 0, columnNumber: 0, label, strategy: \"astro-cid\" }\n }\n }\n\n return null\n },\n}\n\n/**\n * Strategy: CSS stylesheet data-vite-dev-id (for CSS source files)\n */\nexport const viteDevIdStrategy: SourceStrategy = {\n name: \"vite-dev-id\",\n priority: 40,\n resolve(_el) {\n // This strategy works on stylesheets, not elements.\n // Used by the CSS inspector separately.\n return null\n },\n}\n\n// Register built-in strategies\nsourceResolver.register(editableAttrsStrategy)\nsourceResolver.register(astroSourceStrategy)\nsourceResolver.register(astroCidStrategy)\n","/**\n * Expression Field — renders an interactive UI for editing string\n * literals inside JavaScript expressions.\n *\n * Given class={active ? \"on\" : \"off\"} with rendered value \"on\", renders:\n *\n * ┌──────────────────────────────────────────────────┐\n * │ active ? [if ✓: on_____] : [else: off____] │\n * │ ACTIVE (green) inactive (dim) │\n * │ [raw] │\n * └──────────────────────────────────────────────────┘\n *\n * The \"active\" state is inferred by comparing the rendered DOM value\n * against each string literal. Literals whose value appears in the\n * rendered output are marked active; others are dimmed.\n *\n * This is framework-agnostic — works for both React JSX and Astro.\n */\n\nexport interface ExpressionLiteral {\n value: string\n offset: number\n quote: string\n context: string\n}\n\nexport interface ExpressionChange {\n offset: number\n oldValue: string\n newValue: string\n}\n\n/**\n * Determine which string literals are \"active\" (present in the rendered value).\n *\n * For class={active ? \"on\" : \"off\"} with rendered \"on\":\n * - \"on\" → active (it's in the output)\n * - \"off\" → inactive (it's not)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base highlight\":\n * - \"base\" → active\n * - \"highlight\" → active (both are in the output)\n *\n * For class={cn(\"base\", active && \"highlight\")} with rendered \"base\":\n * - \"base\" → active\n * - \"highlight\" → inactive (conditional was false)\n */\nexport function inferActiveLiterals(\n literals: ExpressionLiteral[],\n renderedValue: string,\n): Map<number, boolean> {\n const result = new Map<number, boolean>()\n\n for (const lit of literals) {\n if (!lit.value) {\n // Empty strings are always \"active\" (they don't add anything)\n result.set(lit.offset, true)\n continue\n }\n\n // Check if this literal's value appears in the rendered output.\n // For class values, the rendered output is space-separated classes,\n // so we check if the literal is a substring or if all its classes are present.\n const literalClasses = lit.value.split(/\\s+/).filter(Boolean)\n const renderedClasses = renderedValue.split(/\\s+/).filter(Boolean)\n\n if (literalClasses.length > 0 && literalClasses.every((c) => renderedClasses.includes(c))) {\n result.set(lit.offset, true)\n } else if (renderedValue.includes(lit.value)) {\n // Direct substring match (for non-class attributes)\n result.set(lit.offset, true)\n } else {\n result.set(lit.offset, false)\n }\n }\n\n return result\n}\n\n/**\n * Create an interactive expression editor.\n *\n * @param expression — the raw expression string (between { and })\n * @param literals — the editable string literals extracted from the expression\n * @param renderedValue — the current rendered value from the DOM (null if unknown)\n * @param onChange — called when any literal is edited\n * @returns the DOM element for the editor\n */\nexport function createExpressionField(\n expression: string,\n literals: ExpressionLiteral[],\n renderedValue: string | null,\n onChange: (changes: ExpressionChange[]) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"expr-field\"\n\n // Infer which literals are active\n const activeMap = renderedValue\n ? inferActiveLiterals(literals, renderedValue)\n : null\n\n // Track pending changes\n const pendingChanges = new Map<number, ExpressionChange>()\n\n // ── Structured view ────────────────────────────────────\n\n const structuredView = document.createElement(\"div\")\n structuredView.className = \"expr-structured\"\n\n if (literals.length === 0) {\n // No editable literals — show as read-only\n const readOnly = document.createElement(\"span\")\n readOnly.className = \"expr-readonly\"\n readOnly.textContent = expression\n readOnly.title = \"No editable string literals in this expression\"\n structuredView.appendChild(readOnly)\n } else {\n // Build the interleaved view: code segments + editable fields\n let lastEnd = 0\n\n for (const lit of literals) {\n // Code segment before this literal\n const codeBefore = expression.slice(lastEnd, lit.offset)\n if (codeBefore.trim()) {\n const codeSpan = document.createElement(\"span\")\n codeSpan.className = \"expr-code\"\n codeSpan.textContent = codeBefore.trim()\n structuredView.appendChild(codeSpan)\n }\n\n // Is this literal active (matches rendered value)?\n const isActive = activeMap?.get(lit.offset) ?? null\n\n // Editable field for the string literal\n const field = createLiteralField(lit, isActive, (newValue) => {\n if (newValue !== lit.value) {\n pendingChanges.set(lit.offset, {\n offset: lit.offset,\n oldValue: lit.value,\n newValue,\n })\n } else {\n pendingChanges.delete(lit.offset)\n }\n onChange(Array.from(pendingChanges.values()))\n })\n structuredView.appendChild(field)\n\n // Calculate end of this literal in the expression\n if (lit.quote === \"`\") {\n lastEnd = lit.offset + lit.value.length\n } else {\n lastEnd = lit.offset + lit.value.length + 2 // +2 for quotes\n }\n }\n\n // Trailing code after the last literal\n const trailingCode = expression.slice(lastEnd).trim()\n if (trailingCode) {\n const trailSpan = document.createElement(\"span\")\n trailSpan.className = \"expr-code\"\n trailSpan.textContent = trailingCode\n structuredView.appendChild(trailSpan)\n }\n }\n\n // ── Rendered value indicator ───────────────────────────\n\n if (renderedValue !== null) {\n const rendered = document.createElement(\"div\")\n rendered.className = \"expr-rendered\"\n rendered.title = \"Current rendered value from the DOM\"\n\n const label = document.createElement(\"span\")\n label.className = \"expr-rendered-label\"\n label.textContent = \"rendered:\"\n\n const val = document.createElement(\"span\")\n val.className = \"expr-rendered-value\"\n val.textContent = renderedValue || \"(empty)\"\n\n rendered.appendChild(label)\n rendered.appendChild(val)\n structuredView.insertBefore(rendered, structuredView.firstChild)\n }\n\n // ── Raw view (hidden by default) ───────────────────────\n\n const rawView = document.createElement(\"div\")\n rawView.className = \"expr-raw\"\n rawView.style.display = \"none\"\n\n const rawTextarea = document.createElement(\"textarea\")\n rawTextarea.className = \"text-edit-input\"\n rawTextarea.value = expression\n rawTextarea.rows = Math.min(6, expression.split(\"\\n\").length + 1)\n rawTextarea.style.fontFamily = \"ui-monospace, monospace\"\n rawTextarea.style.fontSize = \"11px\"\n rawView.appendChild(rawTextarea)\n\n // ── Toggle button ──────────────────────────────────────\n\n const toggleRow = document.createElement(\"div\")\n toggleRow.style.cssText =\n \"display:flex;justify-content:flex-end;margin-top:4px\"\n\n const toggleBtn = document.createElement(\"button\")\n toggleBtn.className = \"btn btn-secondary\"\n toggleBtn.style.cssText = \"padding:2px 6px;font-size:10px\"\n toggleBtn.textContent = \"raw\"\n toggleBtn.title = \"Toggle raw expression editing\"\n\n let isRaw = false\n toggleBtn.addEventListener(\"click\", () => {\n isRaw = !isRaw\n structuredView.style.display = isRaw ? \"none\" : \"\"\n rawView.style.display = isRaw ? \"\" : \"none\"\n toggleBtn.textContent = isRaw ? \"visual\" : \"raw\"\n })\n\n toggleRow.appendChild(toggleBtn)\n\n container.appendChild(structuredView)\n container.appendChild(rawView)\n container.appendChild(toggleRow)\n\n return container\n}\n\n/**\n * Create an editable field for a single string literal.\n *\n * @param lit — the literal metadata\n * @param isActive — true if this literal's value is in the rendered DOM output,\n * false if the condition was falsy, null if unknown\n * @param onChange — called when the input value changes\n */\nfunction createLiteralField(\n lit: ExpressionLiteral,\n isActive: boolean | null,\n onChange: (newValue: string) => void,\n): HTMLElement {\n const wrapper = document.createElement(\"span\")\n wrapper.className = \"expr-literal\"\n if (isActive === true) wrapper.classList.add(\"expr-active\")\n if (isActive === false) wrapper.classList.add(\"expr-inactive\")\n wrapper.title = contextLabel(lit.context) +\n (isActive === true ? \" (currently active)\" : \"\") +\n (isActive === false ? \" (currently inactive)\" : \"\")\n\n // Context badge with active indicator\n const badge = document.createElement(\"span\")\n badge.className = \"expr-badge\"\n if (isActive === true) badge.classList.add(\"expr-badge-active\")\n if (isActive === false) badge.classList.add(\"expr-badge-inactive\")\n const indicator = isActive === true ? \"\\u2713 \" : isActive === false ? \"\\u25CB \" : \"\"\n badge.textContent = indicator + shortContextLabel(lit.context)\n wrapper.appendChild(badge)\n\n // The editable input\n const input = document.createElement(\"input\")\n input.className = \"var-input expr-input\"\n if (isActive === false) input.classList.add(\"expr-input-inactive\")\n input.value = lit.value\n input.style.fontSize = \"11px\"\n\n // Auto-size the input to fit content\n const updateWidth = () => {\n const len = Math.max(input.value.length, 3)\n input.style.width = `${len + 1}ch`\n }\n updateWidth()\n\n input.addEventListener(\"input\", updateWidth)\n input.addEventListener(\"change\", () => onChange(input.value))\n\n wrapper.appendChild(input)\n\n return wrapper\n}\n\n/**\n * Human-readable label for the expression context.\n */\nfunction contextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"Value when condition is true\"\n case \"ternary-alternate\":\n return \"Value when condition is false\"\n case \"conditional\":\n return \"Applied when condition is truthy\"\n case \"fallback\":\n return \"Fallback value\"\n case \"call-arg\":\n return \"Function argument\"\n case \"template-static\":\n return \"Static text in template\"\n case \"object-value\":\n return \"Object property value\"\n case \"array-item\":\n return \"Array item\"\n default:\n return \"Editable value\"\n }\n}\n\n/**\n * Short badge label for the context.\n */\nfunction shortContextLabel(context: string): string {\n switch (context) {\n case \"ternary-consequent\":\n return \"if\"\n case \"ternary-alternate\":\n return \"else\"\n case \"conditional\":\n return \"when\"\n case \"fallback\":\n return \"or\"\n case \"call-arg\":\n return \"arg\"\n case \"template-static\":\n return \"text\"\n case \"object-value\":\n return \"val\"\n case \"array-item\":\n return \"item\"\n default:\n return \"\"\n }\n}\n","/**\n * Class Editor — renders a tag-style editor for space-separated\n * CSS class strings. Each class is shown as a removable tag,\n * and new classes can be added.\n *\n * Given \"rounded-lg border ring-2 ring-blue-500\":\n *\n * ┌─────────────────────────────────────────────────┐\n * │ [rounded-lg ×] [border ×] [ring-2 ×] │\n * │ [ring-blue-500 ×] │\n * │ [+ add class________________________] │\n * └─────────────────────────────────────────────────┘\n *\n * Each tag can be removed (×) or edited (click to select + type).\n * The \"add class\" input lets you type new classes.\n * onChange fires with the full updated class string.\n */\n\n/**\n * Create a class tag editor for a space-separated class string.\n *\n * @param classes — the current class string (e.g., \"rounded-lg border\")\n * @param onChange — called with the updated class string\n * @returns the DOM element for the editor\n */\nexport function createClassEditor(\n classes: string,\n onChange: (newClasses: string) => void,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"class-editor\"\n\n let currentClasses = classes.split(/\\s+/).filter(Boolean)\n\n function render() {\n container.textContent = \"\"\n\n const tagRow = document.createElement(\"div\")\n tagRow.className = \"class-tags\"\n\n for (let i = 0; i < currentClasses.length; i++) {\n const cls = currentClasses[i]\n const tag = createClassTag(cls, {\n onRemove: () => {\n currentClasses.splice(i, 1)\n onChange(currentClasses.join(\" \"))\n render()\n },\n onEdit: (newValue) => {\n if (newValue.trim()) {\n // Handle pasting multiple classes\n const parts = newValue.trim().split(/\\s+/)\n currentClasses.splice(i, 1, ...parts)\n } else {\n currentClasses.splice(i, 1)\n }\n onChange(currentClasses.join(\" \"))\n render()\n },\n })\n tagRow.appendChild(tag)\n }\n\n container.appendChild(tagRow)\n\n // Add class input\n const addInput = document.createElement(\"input\")\n addInput.className = \"var-input class-add-input\"\n addInput.placeholder = \"+ add class\"\n addInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && addInput.value.trim()) {\n const newClasses = addInput.value.trim().split(/\\s+/)\n currentClasses.push(...newClasses)\n onChange(currentClasses.join(\" \"))\n addInput.value = \"\"\n render()\n }\n })\n\n container.appendChild(addInput)\n }\n\n render()\n return container\n}\n\n/**\n * Create a single class tag element.\n */\nfunction createClassTag(\n className: string,\n handlers: {\n onRemove: () => void\n onEdit: (newValue: string) => void\n },\n): HTMLElement {\n const tag = document.createElement(\"span\")\n tag.className = \"class-tag\"\n\n const label = document.createElement(\"span\")\n label.className = \"class-tag-label\"\n label.textContent = className\n label.title = className\n\n // Click to edit\n label.addEventListener(\"dblclick\", () => {\n const input = document.createElement(\"input\")\n input.className = \"class-tag-edit\"\n input.value = className\n input.style.width = `${Math.max(className.length, 3) + 2}ch`\n\n input.addEventListener(\"blur\", () => {\n handlers.onEdit(input.value)\n })\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n handlers.onEdit(input.value)\n }\n if (e.key === \"Escape\") {\n handlers.onEdit(className) // revert\n }\n })\n\n tag.replaceChild(input, label)\n input.focus()\n input.select()\n })\n\n const removeBtn = document.createElement(\"button\")\n removeBtn.className = \"class-tag-remove\"\n removeBtn.textContent = \"\\u00d7\"\n removeBtn.title = `Remove ${className}`\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation()\n handlers.onRemove()\n })\n\n tag.appendChild(label)\n tag.appendChild(removeBtn)\n\n return tag\n}\n","/**\n * Value Source Indicator — shows whether a value came from\n * a string literal, a variable, or a complex expression.\n *\n * For literal: class=\"hero\"\n * → [literal] \"hero\" — editable directly\n *\n * For variable: class={className}\n * → [variable] className → \"hero container\" — edit in source\n *\n * For expression: class={cn(\"base\", active && \"active\")}\n * → [expression] cn(\"base\", ...) — edit string literals\n */\n\nexport type ValueSource = \"literal\" | \"variable\" | \"expression\"\n\n/**\n * Create a value source indicator element.\n *\n * @param source — the source type\n * @param detail — additional context (variable name, expression preview)\n * @returns the DOM element\n */\nexport function createValueSourceIndicator(\n source: ValueSource,\n detail?: string,\n): HTMLElement {\n const container = document.createElement(\"div\")\n container.className = \"value-source\"\n\n const badge = document.createElement(\"span\")\n badge.className = `value-source-badge ${source}`\n badge.textContent = source\n\n container.appendChild(badge)\n\n if (detail) {\n const detailSpan = document.createElement(\"span\")\n detailSpan.textContent = detail\n detailSpan.style.fontFamily = \"ui-monospace, monospace\"\n container.appendChild(detailSpan)\n }\n\n // Add context-specific hint\n const hint = document.createElement(\"span\")\n hint.style.color = \"#334155\"\n\n switch (source) {\n case \"literal\":\n hint.textContent = \"— editable\"\n break\n case \"variable\":\n hint.textContent = \"— edit in source\"\n break\n case \"expression\":\n hint.textContent = \"— edit string parts\"\n break\n }\n\n container.appendChild(hint)\n\n return container\n}\n"],"mappings":"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","names":[]}
{
"name": "@editable-jsx/core",
"version": "0.1.0",
"version": "0.1.1",
"type": "module",

@@ -5,0 +5,0 @@ "main": "dist/index.cjs",