"use strict";
// Generated by scripts/build-editor-compiler.mjs. Do not edit directly.
// WRN editor compiler source hash: 196a514b18fb6e31fdd8f4ca667a76b0b62cab547af33725ba78564d70bbc01b
// WRN editor compiler generator hash: c71e7fe4258c97b73b384ff14b321f0cf0b30cc2ed0322f5f84b04e757159b18
// Generated with TypeScript: 5.9.3
const __nodeRequire = require;
const __path = __nodeRequire("node:path");
const __modules = {
"packages/compiler/src/analysis.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.optimizeAst = optimizeAst;
exports.analyzeOptimizations = analyzeOptimizations;
exports.analyzeRuntimeRequirements = analyzeRuntimeRequirements;
function identifiers(value) {
    return new Set(value.match(/[A-Za-z_$][\w$]*/g) ?? []);
}
function literalBoolean(expression) {
    if (expression === null)
        return true;
    const value = expression.trim();
    if (value === "true")
        return true;
    if (value === "false" ||
        value === "null" ||
        value === "undefined" ||
        value === "0" ||
        value === "''" ||
        value === '""')
        return false;
    if (/^-?(?:[1-9]\d*|0?\.\d+)$/.test(value) || /^(['"]).+\1$/.test(value))
        return true;
    return undefined;
}
function optimizeNodes(nodes, report) {
    const output = [];
    for (const node of nodes) {
        if (node.type === "element")
            output.push({
                ...node,
                attrs: node.attrs.map((attribute) => ({ ...attribute })),
                children: optimizeNodes(node.children, report),
            });
        else if (node.type === "each")
            output.push({
                ...node,
                body: optimizeNodes(node.body, report),
                empty: optimizeNodes(node.empty, report),
            });
        else if (node.type === "if") {
            let selected;
            let dynamic = false;
            for (const branch of node.branches) {
                const value = literalBoolean(branch.cond);
                if (value === undefined) {
                    dynamic = true;
                    break;
                }
                report.eliminated++;
                if (value) {
                    selected = branch.body;
                    break;
                }
            }
            if (dynamic)
                output.push({
                    ...node,
                    branches: node.branches.map((branch) => ({
                        ...branch,
                        body: optimizeNodes(branch.body, report),
                    })),
                });
            else if (selected)
                output.push(...optimizeNodes(selected, report));
        }
        else
            output.push({ ...node });
    }
    return output;
}
/** Safe compile-time folding for literal conditional branches. */
function optimizeAst(ast) {
    const report = { eliminated: 0 };
    return {
        ast: { ...ast, view: optimizeNodes(ast.view, report) },
        eliminatedBranches: report.eliminated,
    };
}
function analyzeOptimizations(ast) {
    const used = new Set();
    let staticNodes = 0;
    let reactiveRegions = 0;
    const componentNames = new Set();
    const staticClasses = new Set();
    const visit = (nodes) => {
        for (const node of nodes) {
            if (node.type === "text") {
                const refs = identifiers(node.value);
                refs.forEach((name) => used.add(name));
                if (node.value.includes("{"))
                    reactiveRegions++;
                else
                    staticNodes++;
            }
            else if (node.type === "element") {
                if (/^[A-Z]/.test(node.tag))
                    componentNames.add(node.tag);
                let reactive = false;
                for (const attribute of node.attrs) {
                    identifiers(attribute.value).forEach((name) => used.add(name));
                    reactive ||= attribute.event || attribute.value.includes("{");
                    if (attribute.name === "class" && !attribute.value.includes("{"))
                        for (const name of attribute.value.split(/\s+/))
                            if (name)
                                staticClasses.add(name);
                }
                if (reactive)
                    reactiveRegions++;
                else
                    staticNodes++;
                visit(node.children);
            }
            else if (node.type === "each") {
                identifiers(`${node.list} ${node.key ?? ""}`).forEach((name) => used.add(name));
                reactiveRegions++;
                visit(node.body);
                visit(node.empty);
            }
            else {
                for (const branch of node.branches) {
                    identifiers(branch.cond ?? "").forEach((name) => used.add(name));
                    visit(branch.body);
                }
                reactiveRegions++;
            }
        }
    };
    visit(ast.view);
    const handlerReferences = new Set(used);
    const executable = [
        ...ast.runtimeFunctions.map((fn) => fn.body),
        ...ast.functions,
        ...ast.effects.map((effect) => effect.body),
        ...ast.watches.map((watch) => watch.body),
        ...ast.actions.map((action) => action.body),
    ].join("\n");
    identifiers(executable).forEach((name) => used.add(name));
    const localCss = new Set(ast.styles.flatMap((style) => [...style.matchAll(/\.([_a-zA-Z][\w-]*)/g)].map((match) => match[1])));
    const optimized = optimizeAst(ast);
    const assignmentCounts = ast.runtimeFunctions.map((fn) => ast.states.filter((state) => new RegExp(`\\b${state.name}\\s*(?:[+*/-]?=|\\+\\+|--)`).test(fn.body)).length);
    return {
        staticNodes,
        reactiveRegions,
        eliminatedBranches: optimized.eliminatedBranches,
        unusedState: ast.states.filter((state) => !used.has(state.name)).map((state) => state.name),
        unusedHandlers: ast.runtimeFunctions
            .filter((fn) => fn.runtime !== "server" && !handlerReferences.has(fn.name))
            .map((fn) => fn.name),
        constantProps: ast.props
            .filter((prop) => /^(?:-?\d+(?:\.\d+)?|true|false|null|(['"]).*\1)$/.test(prop.default.trim()))
            .map((prop) => prop.name),
        unusedLocalCssClasses: [...localCss].filter((name) => !staticClasses.has(name)).sort(),
        batchableStateUpdates: assignmentCounts
            .filter((count) => count > 1)
            .reduce((sum, count) => sum + count - 1, 0),
        memoizableComponents: [...componentNames].sort(),
        preloadDependencies: ast.structuredImports
            .filter((entry) => !entry.typeOnly && !entry.source.startsWith("node:"))
            .map((entry) => entry.source),
        serverOnlyModules: ast.structuredImports
            .filter((entry) => entry.source.startsWith("node:") || ast.runtime === "server")
            .map((entry) => entry.source),
    };
}
function hasEvent(nodes) {
    for (const node of nodes) {
        if (node.type === "element") {
            if (node.attrs.some((attribute) => attribute.event))
                return true;
            if (hasEvent(node.children))
                return true;
        }
        else if (node.type === "each") {
            if (hasEvent(node.body) || hasEvent(node.empty))
                return true;
        }
        else if (node.type === "if") {
            if (node.branches.some((branch) => hasEvent(branch.body)))
                return true;
        }
    }
    return false;
}
function analyzeRuntimeRequirements(ast) {
    const reasons = [];
    const clientFunctions = ast.runtimeFunctions.some((fn) => fn.runtime !== "server");
    const clientState = ast.states.some((state) => state.runtime !== "server");
    const interactive = clientFunctions ||
        clientState ||
        ast.effects.length > 0 ||
        ast.watches.length > 0 ||
        hasEvent(ast.view);
    if (interactive)
        reasons.push("client interactivity");
    const requestData = ast.loads.length > 0 ||
        ast.actions.length > 0 ||
        ast.dataApis.length > 0 ||
        ast.apis.length > 0 ||
        ast.realtimes.length > 0 ||
        ast.runtimeFunctions.some((fn) => fn.runtime === "server") ||
        ast.states.some((state) => state.runtime === "server");
    if (requestData)
        reasons.push("server/request data");
    const authenticated = /^(?:required|true)$/i.test(ast.security.auth ?? "");
    if (authenticated)
        reasons.push("authentication required");
    const streaming = /^(?:true|required)$/i.test(ast.security.streaming ?? "");
    if (streaming)
        reasons.push("streaming enabled");
    let kind;
    if (streaming)
        kind = "streaming-ssr";
    else if (authenticated)
        kind = "authenticated-ssr";
    else if (requestData && interactive)
        kind = "dynamic";
    else if (requestData)
        kind = "request-ssr";
    else if (interactive)
        kind = "static-interactive";
    else
        kind = "static";
    if (ast.renderMode === "static") {
        kind = "static";
        reasons.push("explicit static rendering");
    }
    else if (ast.renderMode === "server") {
        kind = requestData ? "request-ssr" : "static";
        reasons.push("explicit server rendering");
    }
    else if (ast.renderMode === "client") {
        kind = "static-interactive";
        reasons.push("explicit client rendering");
    }
    else if (ast.renderMode === "partial-static") {
        kind = "streaming-ssr";
        reasons.push("partial-static shell with streamed dynamic regions");
    }
    const clientDisabled = ast.renderMode === "static" || ast.renderMode === "server";
    const serverDisabled = ast.renderMode === "client";
    return {
        kind,
        canPrerender: kind === "static" || kind === "static-interactive",
        needsClientRuntime: !clientDisabled &&
            (interactive || ast.renderMode === "client") &&
            ast.hydrate !== "none" &&
            ast.runtime !== "server",
        needsServerRuntime: !serverDisabled &&
            (requestData ||
                authenticated ||
                streaming ||
                ast.renderMode === "server" ||
                ["server", "edge", "worker", "service-worker"].includes(ast.runtime ?? "")),
        hydrationStrategy: clientDisabled ? null : interactive ? (ast.hydrate ?? "load") : null,
        reasons,
        optimization: analyzeOptimizations(ast),
        cachePolicy: { ...(ast.cache ?? {}) },
        requiredPermission: ast.security.permission ?? null,
    };
}

},
"packages/compiler/src/cache.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DependencyGraph = void 0;
exports.compilationKey = compilationKey;
exports.createCompilationCache = createCompilationCache;
const node_crypto_1 = require("node:crypto");
const syntax_1 = require("@wrnexus/syntax");
const codegen_ts_1 = require("./codegen.js");
function compileSource(source, filePath) {
    const richDiagnostics = (0, syntax_1.diagnose)(source, { file: filePath, accessibility: true });
    const errors = richDiagnostics.filter((diagnostic) => diagnostic.severity === "error");
    if (errors.length > 0) {
        throw new syntax_1.ParseError(errors.map((diagnostic) => diagnostic.message).join("\n"), errors[0].code);
    }
    const ast = (0, syntax_1.parse)(source);
    return {
        code: `// compiled from .wrn\n${(0, codegen_ts_1.generate)(ast)}`,
        ast,
        diagnostics: richDiagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`),
        richDiagnostics,
    };
}
function compilationKey(source, file = "<inline .wrn>", salt = "") {
    return (0, node_crypto_1.createHash)("sha256")
        .update(file)
        .update("\0")
        .update(salt)
        .update("\0")
        .update(source)
        .digest("hex");
}
function createCompilationCache(options = {}) {
    const maxEntries = options.maxEntries ?? 500;
    if (!Number.isInteger(maxEntries) || maxEntries < 1)
        throw new RangeError("maxEntries must be positive");
    const now = options.now ?? Date.now;
    const entries = new Map();
    let hits = 0;
    let misses = 0;
    function touch(key, value) {
        entries.delete(key);
        entries.set(key, value);
        while (entries.size > maxEntries)
            entries.delete(entries.keys().next().value);
    }
    return {
        compile(source, file = "<inline .wrn>", salt = "") {
            const key = compilationKey(source, file, salt);
            const existing = entries.get(key);
            if (existing) {
                hits++;
                touch(key, existing);
                return existing;
            }
            misses++;
            const result = compileSource(source, file);
            const entry = {
                ...result,
                key,
                file,
                sourceHash: (0, node_crypto_1.createHash)("sha256").update(source).digest("hex"),
                createdAt: now(),
            };
            touch(key, entry);
            return entry;
        },
        get(key) {
            const entry = entries.get(key);
            if (entry)
                touch(key, entry);
            return entry;
        },
        invalidate(file) {
            let removed = 0;
            for (const [key, entry] of entries) {
                if (!file || entry.file === file) {
                    entries.delete(key);
                    removed++;
                }
            }
            return removed;
        },
        clear() {
            entries.clear();
        },
        size: () => entries.size,
        stats: () => ({ hits, misses, entries: entries.size }),
    };
}
class DependencyGraph {
    #dependencies = new Map();
    #dependents = new Map();
    set(file, dependencies) {
        this.remove(file);
        const values = new Set(dependencies);
        this.#dependencies.set(file, values);
        for (const dependency of values) {
            const set = this.#dependents.get(dependency) ?? new Set();
            set.add(file);
            this.#dependents.set(dependency, set);
        }
    }
    remove(file) {
        for (const dependency of this.#dependencies.get(file) ?? []) {
            const set = this.#dependents.get(dependency);
            set?.delete(file);
            if (set?.size === 0)
                this.#dependents.delete(dependency);
        }
        this.#dependencies.delete(file);
    }
    dependencies(file) {
        return [...(this.#dependencies.get(file) ?? [])].sort();
    }
    dependents(file) {
        return [...(this.#dependents.get(file) ?? [])].sort();
    }
    affected(file) {
        const found = new Set();
        const queue = [file];
        while (queue.length) {
            const current = queue.shift();
            for (const dependent of this.#dependents.get(current) ?? []) {
                if (found.has(dependent))
                    continue;
                found.add(dependent);
                queue.push(dependent);
            }
        }
        return [...found].sort();
    }
}
exports.DependencyGraph = DependencyGraph;

},
"packages/compiler/src/client-codegen.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.browserModuleRequired = browserModuleRequired;
exports.generateBrowserModule = generateBrowserModule;
const syntax_1 = require("@wrnexus/syntax");
const RESERVED_BINDINGS = new Set([
    "await",
    "break",
    "case",
    "catch",
    "class",
    "const",
    "continue",
    "debugger",
    "default",
    "delete",
    "do",
    "else",
    "enum",
    "export",
    "extends",
    "false",
    "finally",
    "for",
    "function",
    "if",
    "implements",
    "import",
    "in",
    "instanceof",
    "interface",
    "let",
    "new",
    "null",
    "package",
    "private",
    "protected",
    "public",
    "return",
    "static",
    "super",
    "switch",
    "this",
    "throw",
    "true",
    "try",
    "typeof",
    "var",
    "void",
    "while",
    "with",
    "yield",
]);
const RUNTIME_BINDINGS = new Set([
    "context",
    "state",
    "output",
    "server",
    "props",
    "refs",
    "event",
    "payload",
]);
function safeIdentifier(name) {
    return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) && !RESERVED_BINDINGS.has(name);
}
function identifierReferenced(source, name) {
    const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    return new RegExp(`(?:^|[^A-Za-z0-9_$])${escaped}(?![A-Za-z0-9_$])`).test(source);
}
function viewReferenceSource(nodes) {
    return nodes.flatMap((node) => {
        if (node.type === "text")
            return [node.value];
        if (node.type === "each") {
            return [
                node.list,
                node.key ?? "",
                ...viewReferenceSource(node.body),
                ...viewReferenceSource(node.empty),
            ];
        }
        if (node.type === "if") {
            return node.branches.flatMap((branch) => [
                branch.cond ?? "",
                ...viewReferenceSource(branch.body),
            ]);
        }
        return [...node.attrs.map((attr) => attr.value), ...viewReferenceSource(node.children)];
    });
}
function browserReferenceSource(ast, functions) {
    return [
        ...functions.flatMap((fn) => [fn.source, fn.body]),
        ...ast.computed.map((entry) => entry.expr),
        ...ast.effects,
        ast.lifecycle.mount ?? "",
        ast.lifecycle.update ?? "",
        ast.lifecycle.unmount ?? "",
        ...viewReferenceSource(ast.view),
    ].join("\n");
}
function renderSelectedImport(entry, source) {
    if (entry.typeOnly)
        return null;
    const isStore = entry.source.endsWith(".wrn") && /(?:^|\/)stores?\//.test(entry.source);
    if (entry.source.endsWith(".wrn") && !isStore)
        return null;
    const defaultImport = entry.defaultImport && (isStore || identifierReferenced(source, entry.defaultImport))
        ? entry.defaultImport
        : undefined;
    const namespaceImport = entry.namespaceImport && (isStore || identifierReferenced(source, entry.namespaceImport))
        ? entry.namespaceImport
        : undefined;
    const namedImports = entry.namedImports.filter((item) => !item.typeOnly && (isStore || identifierReferenced(source, item.local)));
    const bindings = [
        ...(defaultImport ? [defaultImport] : []),
        ...(namespaceImport ? [namespaceImport] : []),
        ...namedImports.map((item) => item.local),
    ].filter(safeIdentifier);
    const hasBindings = Boolean(defaultImport || namespaceImport || namedImports.length);
    const sideEffectOnly = !entry.defaultImport && !entry.namespaceImport && entry.namedImports.length === 0;
    if (!hasBindings && !sideEffectOnly)
        return null;
    if (sideEffectOnly)
        return { code: entry.raw, bindings: [] };
    const clauses = [];
    if (defaultImport)
        clauses.push(defaultImport);
    if (namespaceImport)
        clauses.push(`* as ${namespaceImport}`);
    if (namedImports.length) {
        clauses.push(`{ ${namedImports
            .map((item) => item.imported === item.local ? item.imported : `${item.imported} as ${item.local}`)
            .join(", ")} }`);
    }
    return {
        code: `import ${clauses.join(", ")} from ${JSON.stringify(entry.source)};`,
        bindings,
    };
}
function selectedBrowserImports(ast, functions) {
    const referenceSource = browserReferenceSource(ast, functions);
    return ast.structuredImports
        .map((entry) => renderSelectedImport(entry, referenceSource))
        .filter((entry) => entry !== null);
}
function browserModuleRequired(ast) {
    const functions = ast.runtimeFunctions.filter((fn) => ["legacy", "client", "shared"].includes(fn.runtime));
    return functions.length > 0 || selectedBrowserImports(ast, functions).length > 0;
}
function _functionEntry(ast, fn, availableFunctions) {
    const parameterNames = new Set(fn.parameters.map((parameter) => parameter.name));
    /*
     * Names the function body declares for itself.
     *
     * Props and state are destructured into the SAME scope as the body, so a
     * body that declares `var size` when `size` is also a prop produced
     * "Identifier 'size' has already been declared" and the entire module
     * failed to parse -- taking every function in the component down with it,
     * with nothing to point at the one line responsible. Skipping the alias for
     * a shadowed name is also what plain JavaScript does: inside that function
     * the local wins.
     */
    const declaredLocals = new Set();
    for (const match of fn.body.matchAll(/\b(?:var|let|const)\s+([A-Za-z_$][\w$]*)|\bfunction\s+([A-Za-z_$][\w$]*)/g)) {
        const name = match[1] ?? match[2];
        if (name)
            declaredLocals.add(name);
    }
    const stateNames = ast.states
        .filter((state) => state.runtime !== "server" &&
        safeIdentifier(state.name) &&
        !RUNTIME_BINDINGS.has(state.name) &&
        !parameterNames.has(state.name) &&
        !declaredLocals.has(state.name))
        .map((state) => state.name);
    const stateSet = new Set(stateNames);
    const propNames = ast.props
        .filter((prop) => safeIdentifier(prop.name) &&
        !RUNTIME_BINDINGS.has(prop.name) &&
        !parameterNames.has(prop.name) &&
        !stateSet.has(prop.name) &&
        !declaredLocals.has(prop.name))
        .map((prop) => prop.name);
    const functionAliases = availableFunctions.filter((name) => safeIdentifier(name) &&
        !RUNTIME_BINDINGS.has(name) &&
        !parameterNames.has(name) &&
        !stateSet.has(name) &&
        !propNames.includes(name) &&
        !declaredLocals.has(name));
    const parameters = fn.parameters.map((parameter) => parameter.name).join(", ");
    const initialStateSnapshot = stateNames.length
        ? `const __wrnexusInitialState = { ${stateNames.map((name) => `${JSON.stringify(name)}: context.state.${name}`).join(", ")} };`
        : "";
    const stateAliases = stateNames.length ? `let { ${stateNames.join(", ")} } = context.state;` : "";
    const propAliases = propNames.length ? `const { ${propNames.join(", ")} } = context.props;` : "";
    const syncStateToContext = stateNames.map((name) => `context.state.${name} = ${name};`).join(" ");
    const syncStateFromContext = stateNames
        .map((name) => `${name} = context.state.${name};`)
        .join(" ");
    const peerAliases = !stateNames.length
        ? functionAliases
            .map((name) => `const ${name} = (...__wrnexusPeerArgs) => context.functions[${JSON.stringify(name)}](...__wrnexusPeerArgs);`)
            .join("\n")
        : `const __wrnexusFlush = () => { ${syncStateToContext} };
    const __wrnexusRestore = () => { ${syncStateFromContext} };
    const __wrnexusPeer = (name, args) => {
      __wrnexusFlush();
      let result;
      try {
        result = context.functions[name](...args);
      } catch (error) {
        __wrnexusRestore();
        throw error;
      }
      if (result && typeof result.then === "function") {
        return Promise.resolve(result).finally(__wrnexusRestore);
      }
      __wrnexusRestore();
      return result;
    };
    ${functionAliases.map((name) => `const ${name} = (...__wrnexusPeerArgs) => __wrnexusPeer(${JSON.stringify(name)}, __wrnexusPeerArgs);`).join("\n")}`;
    const copyBack = stateNames
        .map((name) => `if (!Object.is(${name}, __wrnexusInitialState[${JSON.stringify(name)}])) context.state.${name} = ${name};`)
        .join("\n");
    const commitBinding = stateNames.length
        ? `const __wrnexusCommit = () => { ${copyBack} };
    ${!parameterNames.has("commit") && !declaredLocals.has("commit") && !functionAliases.includes("commit") ? "const commit = __wrnexusCommit;" : ""}
    ${!parameterNames.has("setTimeout") &&
            !declaredLocals.has("setTimeout") &&
            !functionAliases.includes("setTimeout")
            ? `const setTimeout = (callback, delay, ...args) => globalThis.setTimeout(() => {
      try { return callback(...args); } finally { __wrnexusCommit(); }
    }, delay);`
            : ""}`
        : "";
    const body = (0, syntax_1.eraseFunctionTypes)(fn.body);
    const runtimeBindings = [
        !parameterNames.has("output") ? "const output = context.output;" : "",
        !parameterNames.has("server") ? "const server = context.server;" : "",
        !parameterNames.has("props") ? "const props = context.props;" : "",
        !parameterNames.has("refs") ? "const refs = context.refs;" : "",
    ]
        .filter(Boolean)
        .join("\n    ");
    return `${JSON.stringify(fn.name)}: ${fn.async ? "async " : ""}function(context${parameters ? `, ${parameters}` : ""}) {
    ${initialStateSnapshot}
    ${stateAliases}
    ${propAliases}
    ${commitBinding}
    ${peerAliases}
    ${runtimeBindings}
    try {
      ${body}
    } finally {
      ${stateNames.length ? "__wrnexusCommit();" : ""}
    }
  }`;
}
function generateBrowserModule(ast) {
    const functions = ast.runtimeFunctions.filter((fn) => ["legacy", "client", "shared"].includes(fn.runtime));
    const functionNames = functions.map((fn) => fn.name);
    const state = ast.states.filter((entry) => entry.runtime !== "server").map((entry) => entry.name);
    const selectedImports = selectedBrowserImports(ast, functions);
    const imports = selectedImports.map((entry) => entry.code).join("\n");
    const importedBindings = [...new Set(selectedImports.flatMap((entry) => entry.bindings))];
    const sharedState = state.filter((name) => safeIdentifier(name) && !RUNTIME_BINDINGS.has(name));
    const sharedProps = ast.props
        .map((entry) => entry.name)
        .filter((name) => safeIdentifier(name) && !RUNTIME_BINDINGS.has(name) && !sharedState.includes(name));
    const callableAliases = functionNames.filter((name) => safeIdentifier(name) &&
        !RUNTIME_BINDINGS.has(name) &&
        !sharedState.includes(name) &&
        !sharedProps.includes(name));
    const sharedCommit = sharedState.map((name) => `context.state.${name} = ${name};`).join(" ");
    const sharedRestore = [
        ...sharedState.map((name) => `${name} = context.state.${name};`),
        ...sharedProps.map((name) => `${name} = context.props.${name};`),
    ].join(" ");
    const hasAuthoredCommit = callableAliases.includes("commit");
    const hasAuthoredSetTimeout = callableAliases.includes("setTimeout");
    const implementations = functions
        .map((fn) => {
        const parameters = fn.parameters.map((parameter) => parameter.name).join(", ");
        return `${JSON.stringify(fn.name)}: ${fn.async ? "async " : ""}function(${parameters}) {
        try { ${(0, syntax_1.eraseFunctionTypes)(fn.body)} } finally { __wrnexusCommit(); }
      }`;
    })
        .join(",\n");
    return `// generated WRNexusJS browser module for ${ast.name}
${imports}
export const __wrnexusClientFunctions = {
${functions
        .map((fn) => `  ${JSON.stringify(fn.name)}: (context, ...args) => __wrnexusBindings(context)[${JSON.stringify(fn.name)}](...args)`)
        .join(",\n")}
};
export const __wrnexusClientState = ${JSON.stringify(state)};
export const __wrnexusOutputs = ${JSON.stringify(ast.outputs)};
export const __wrnexusImportedBindings = { ${importedBindings.join(", ")} };
function __wrnexusCreateClientFunctions(context) {
  ${sharedState.length ? `let { ${sharedState.join(", ")} } = context.state;` : ""}
  ${sharedProps.length ? `let { ${sharedProps.join(", ")} } = context.props;` : ""}
  const output = context.output;
  const server = context.server;
  const props = context.props;
  const refs = context.refs;
  const __wrnexusCommit = () => { ${sharedCommit} };
  const __wrnexusRestore = () => { ${sharedRestore} };
  ${!hasAuthoredCommit ? "const commit = __wrnexusCommit;" : ""}
  ${!hasAuthoredSetTimeout
        ? `const setTimeout = (callback, delay, ...args) => globalThis.setTimeout(() => {
    try { return callback(...args); } finally { __wrnexusCommit(); }
  }, delay);`
        : ""}
  const implementations = {
    ${implementations}
  };
  ${callableAliases.map((name) => `const ${name} = (...args) => implementations[${JSON.stringify(name)}](...args);`).join("\n  ")}
  const functions = {};
  for (const name of Object.keys(implementations)) {
    functions[name] = (...args) => {
      __wrnexusRestore();
      return implementations[name](...args);
    };
  }
  return functions;
}
function __wrnexusBindings(context) {
  return context.__wrnexusBoundFunctions ||
    (context.__wrnexusBoundFunctions = __wrnexusCreateClientFunctions(context));
}
export function bindClientScope(context) {
  return __wrnexusBindings(context);
}
`;
}

},
"packages/compiler/src/codegen.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
/**
 * Code generation: lower a `.wrn` AST to TypeScript that targets the framework's
 * existing primitives.
 *
 *   state              -> a `data-scope` declaration consumed by the runtime
 *   view               -> an HTML string returned by a page component
 *   @event="..."       -> data-on-<event>="..."
 *   "...{expr}..."     -> text kept verbatim ({expr} is mustache for runtime)
 *   api="<name>"       -> SSR/client data binding declared in a mode block
 *   ssrGet/ssrText     -> legacy server-side API fetch + render
 *   csrGet/csrText     -> legacy browser-side API fetch + render
 *   style              -> tagged local stylesheet metadata promoted by SSR
 *   functions          -> server-only helpers for API/realtime code
 *   api M /p {b}       -> export const M = async (ctx) => { b }
 *   realtime {..}      -> export const websocket = { evt(ws, ...args) { b } }
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.generate = generate;
exports.parseForExpr = parseForExpr;
const node_buffer_1 = require("node:buffer");
const parser_ts_1 = require("./parser.js");
const types_ts_1 = require("./types.js");
const syntax_1 = require("@wrnexus/syntax");
const store_codegen_ts_1 = require("./store-codegen.js");
const analysis_ts_1 = require("./analysis.js");
const client_codegen_ts_1 = require("./client-codegen.js");
function isComponentTag(tag) {
    return /^[A-Z][A-Za-z0-9_$]*$/.test(tag);
}
const HTML_BOOLEAN_ATTRIBUTES = new Set([
    "allowfullscreen",
    "async",
    "autofocus",
    "autoplay",
    "checked",
    "controls",
    "default",
    "defer",
    "disabled",
    "formnovalidate",
    "hidden",
    "inert",
    "ismap",
    "itemscope",
    "loop",
    "multiple",
    "muted",
    "nomodule",
    "novalidate",
    "open",
    "playsinline",
    "readonly",
    "required",
    "reversed",
    "selected",
]);
function isHtmlBooleanAttribute(name) {
    return HTML_BOOLEAN_ATTRIBUTES.has(name.toLowerCase());
}
const URL_ATTRIBUTES = new Set([
    "href",
    "src",
    "action",
    "formaction",
    "poster",
    "cite",
    "background",
    "xlink:href",
]);
function stripAsciiControlAndSpace(value) {
    let result = "";
    for (const character of value) {
        if (character.charCodeAt(0) > 0x20)
            result += character;
    }
    return result;
}
function sanitizeUrlAttribute(value) {
    const compact = stripAsciiControlAndSpace(value.trim());
    const lower = compact.toLowerCase();
    if (/^(?:javascript|vbscript|file):/.test(lower))
        return "about:blank";
    if (/^data:(?!image\/(?:png|gif|jpeg|webp|avif);)/.test(lower))
        return "about:blank";
    return value;
}
function safeAttributeValue(name, value) {
    if (!URL_ATTRIBUTES.has(name.toLowerCase()) || value.includes("{"))
        return value;
    return sanitizeUrlAttribute(value);
}
/** Escape a value placed inside a double-quoted HTML attribute. */
function attrEscape(value) {
    return value
        .replace(/&/g, "&amp;")
        .replace(/"/g, "&quot;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;");
}
/** Make HTML safe to embed inside a JS template literal. */
function templateEscape(html) {
    return html.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
}
function styleEscape(css) {
    return css.replace(/<\/style/gi, "<\\/style");
}
function attrValue(attrs, name) {
    return attrs.find((attr) => !attr.event && attr.name === name)?.value;
}
function renderAttr(attr) {
    if (attr.event)
        return ` ${eventAttribute(attr.name)}="${attrEscape(attr.value)}"`;
    switch (attr.name) {
        case "api":
        case "ssrGet":
        case "ssrText":
        case "csrGet":
        case "csrText":
            return "";
        default:
            return attr.boolean
                ? ` ${attr.name}`
                : ` ${attr.name}="${attrEscape(safeAttributeValue(attr.name, attr.value))}"`;
    }
}
function eventAttribute(name) {
    if (name.startsWith("window:")) {
        return `data-on-window-${name.slice("window:".length)}`;
    }
    if (name.startsWith("document:")) {
        return `data-on-document-${name.slice("document:".length)}`;
    }
    if (name.startsWith("browser-")) {
        return `data-on-wrnexus-browser-${name.slice(8)}`;
    }
    if (name.startsWith("mobile-")) {
        return `data-on-wrnexus-mobile-${name.slice(7)}`;
    }
    return `data-on-${name}`;
}
/**
 * Event attribute for a handler written on a *component tag*
 * (`<Modal @confirm="save()">`).
 *
 * These need their own attribute name. The mount's attributes are forwarded
 * into the component and land on its view root, i.e. inside the component's
 * own `data-scope` -- but the statement (`save()`) belongs to the parent that
 * wrote the tag. Emitting `data-on-confirm` makes the child's runtime bind it
 * against the child's scope, where the parent's functions and state do not
 * exist, so the handler silently does nothing. `data-wrn-out-*` is ignored by
 * the child and claimed by the mounting scope instead.
 *
 * `window:`/`document:` (and the browser/mobile bridges) keep the plain
 * `data-on-*` form: those bind to a global target rather than to the element,
 * and the runtime has no component-output path for them.
 */
function componentEventAttribute(name) {
    if (name.startsWith("window:") ||
        name.startsWith("document:") ||
        name.startsWith("browser-") ||
        name.startsWith("mobile-")) {
        return eventAttribute(name);
    }
    return `data-wrn-out-${name}`;
}
function reactiveAttrValue(raw, reactive) {
    let found = false;
    const value = raw.replace(/\{([^{}]+)\}/g, (whole, inner) => {
        const expr = inner.trim();
        if (!exprRefsState(expr, reactive.stateNames))
            return whole;
        found = true;
        try {
            const result = new Function("with(this){return (" + expr + ");}").call(reactive.scope);
            return result == null ? "" : String(result);
        }
        catch {
            return whole;
        }
    });
    return found ? value : null;
}
function renderAttrs(attrs, csrId, reactive = null, dynamicExpressions) {
    let bindIndex = 0;
    const rendered = attrs
        .map((attr) => {
        const base = renderAttr(attr);
        if (!reactive || attr.event || attr.boolean || !base || !attr.value.includes("{"))
            return base;
        const expression = wholeAttributeExpression(attr.value);
        if (expression &&
            exprRefsState(expression, reactive.runtimeStateNames) &&
            dynamicExpressions) {
            dynamicExpressions.push(`\${__wrnexusPropAttr(${expression})}`);
            const sentinel = `\x00WRNEACH${dynamicExpressions.length - 1}\x00`;
            const marker = JSON.stringify([attr.name, attr.value]);
            return ` ${attr.name}="${sentinel}" data-wrn-bind-${bindIndex++}="${attrEscape(marker)}"`;
        }
        const initial = reactiveAttrValue(attr.value, reactive);
        if (initial === null)
            return base;
        const marker = JSON.stringify([attr.name, attr.value]);
        return ` ${attr.name}="${attrEscape(URL_ATTRIBUTES.has(attr.name.toLowerCase()) ? sanitizeUrlAttribute(initial) : initial)}" data-wrn-bind-${bindIndex++}="${attrEscape(marker)}"`;
    })
        .join("");
    return csrId ? `${rendered} data-wrnexus-csr="${attrEscape(csrId)}"` : rendered;
}
/**
 * Replace i18n text sugar `{t:key}` with a `<span data-t="key">` marker the
 * runtime resolves server-side. Other `{expr}` mustaches are left untouched.
 */
function substituteTMarkers(text) {
    return text.replace(/\{t:([^{}]+)\}/g, (_m, key) => `<span data-t="${attrEscape(key.trim())}"></span>`);
}
/** Escape a value for safe embedding in HTML text. */
function htmlTextEscape(value) {
    return value.replace(/[&<>]/g, (c) => (c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&gt;"));
}
/**
 * Evaluate a page's `state` seed expressions at compile time to obtain the
 * initial SSR values used to bake `data-text` spans. Seeds may reference
 * earlier ones; anything that can't be evaluated becomes `undefined`.
 */
function evalStateSeeds(states) {
    const scope = {};
    for (const s of states) {
        try {
            scope[s.name] = new Function("with(this){return (" + s.expr + ");}").call(scope);
        }
        catch {
            scope[s.name] = undefined;
        }
    }
    return scope;
}
/**
 * Page text compilation: resolve `{t:key}` i18n markers, then bake state
 * interpolations (`{count}`, `{count * 2}`) into `data-text` spans carrying the
 * evaluated initial value — so no-JS clients see real content and the reactive
 * runtime keeps it live. Non-state `{expr}` and un-evaluable expressions are
 * left as literal client mustaches.
 */
function substituteReactiveText(raw, reactive, dynamicExpressions) {
    const text = substituteTMarkers(raw);
    if (!reactive || reactive.stateNames.size === 0)
        return text;
    return text.replace(/\{([^{}]+)\}/g, (whole, inner) => {
        const expr = inner.trim();
        if (expr.startsWith("t:") || !exprRefsState(expr, reactive.stateNames))
            return whole;
        if (exprRefsState(expr, reactive.runtimeStateNames) && dynamicExpressions) {
            dynamicExpressions.push(`\${__wrnexusEscapeHtml(${expr})}`);
            const sentinel = `\x00WRNEACH${dynamicExpressions.length - 1}\x00`;
            return `<span data-text="${attrEscape(expr)}">${sentinel}</span>`;
        }
        let value;
        try {
            value = new Function("with(this){return (" + expr + ");}").call(reactive.scope);
        }
        catch {
            return whole; // can't evaluate → keep as a client-only mustache
        }
        const baked = htmlTextEscape(value == null ? "" : String(value));
        return `<span data-text="${attrEscape(expr)}">${baked}</span>`;
    });
}
/**
 * Bake a loop-body text run into template-literal source: static text is escaped
 * for the literal, `{expr}` becomes `${__wrnexusEscapeHtml(expr)}` (server-rendered,
 * escaped), and `{t:key}` becomes a `data-t` marker resolved later by translateHtml.
 */
function bakeLoopText(raw) {
    let out = "";
    let last = 0;
    let m;
    const re = /\{([^{}]+)\}/g;
    while ((m = re.exec(raw))) {
        out += escLit(raw.slice(last, m.index));
        const expr = m[1].trim();
        if (expr.startsWith("t:")) {
            out += escLit(`<span data-t="${attrEscape(expr.slice(2).trim())}"></span>`);
        }
        else {
            out += "${__wrnexusEscapeHtml(" + expr + ")}";
        }
        last = m.index + m[0].length;
    }
    return out + escLit(raw.slice(last));
}
/** Bake a loop-body attribute value (same rules as text; escapeHtml is attribute-safe). */
function bakeLoopAttr(raw, typed = false) {
    const wholeExpression = wholeAttributeExpression(raw);
    if (typed && wholeExpression)
        return "${__wrnexusPropAttr(" + wholeExpression + ")}";
    if (!raw.includes("{"))
        return escLit(attrEscape(raw));
    let out = "";
    let last = 0;
    let m;
    const re = /\{([^{}]+)\}/g;
    while ((m = re.exec(raw))) {
        out += escLit(attrEscape(raw.slice(last, m.index)));
        out += "${__wrnexusEscapeHtml(" + m[1].trim() + ")}";
        last = m.index + m[0].length;
    }
    return out + escLit(attrEscape(raw.slice(last)));
}
/** Render one loop-body node to template-literal source (nested loops inline). */
function renderLoopBody(node) {
    if (node.type === "text") {
        return bakeLoopText(node.value);
    }
    if (node.type === "each") {
        return compileEachExpr(node);
    }
    if (node.type === "if") {
        return compileIfExpr(node);
    }
    const componentTag = isComponentTag(node.tag);
    const attrs = node.attrs
        .filter((attr) => attr.name !== "data-component")
        .map((attr) => {
        const name = attr.event
            ? componentTag
                ? componentEventAttribute(attr.name)
                : eventAttribute(attr.name)
            : attr.name;
        if (attr.boolean) {
            return escLit(` ${name}`);
        }
        return escLit(` ${name}="`) + bakeLoopAttr(attr.value, componentTag) + escLit(`"`);
    })
        .join("");
    const inner = node.children.map(renderLoopBody).join("");
    if (node.tag === "Static")
        return inner;
    if (node.tag === "Dynamic")
        return (escLit('<wrn-dynamic-region data-wrn-dynamic="true">') +
            inner +
            escLit("</wrn-dynamic-region>"));
    if (node.tag === "KeepAlive") {
        const key = node.attrs.find((attribute) => attribute.name === "key")?.value ?? "default";
        return (escLit('<div data-wrn-keepalive="') +
            bakeLoopAttr(key) +
            escLit(`">`) +
            inner +
            escLit("</div>"));
    }
    if (node.tag === "Portal") {
        const target = node.attrs.find((attribute) => attribute.name === "to")?.value ?? "body";
        return (escLit('<div data-wrn-portal="') +
            bakeLoopAttr(target) +
            escLit('">') +
            inner +
            escLit("</div>"));
    }
    if (node.tag === "Transition") {
        const name = node.attrs.find((attribute) => attribute.name === "name")?.value ?? "wrn-transition";
        return (escLit('<div data-wrn-transition="') +
            bakeLoopAttr(name) +
            escLit('">') +
            inner +
            escLit("</div>"));
    }
    if (node.tag === "Component") {
        const selected = node.attrs.find((attribute) => attribute.name === "is")?.value ?? "";
        return (escLit('<div data-wrn-dynamic-component="') +
            bakeLoopAttr(selected) +
            escLit('">') +
            inner +
            escLit("</div>"));
    }
    if (componentTag) {
        return (escLit(`<div data-component="${attrEscape(node.tag)}"`) +
            attrs +
            escLit(">") +
            inner +
            escLit("</div>"));
    }
    if (parser_ts_1.VOID_ELEMENTS.has(node.tag.toLowerCase())) {
        return escLit(`<${node.tag}`) + attrs + escLit(">");
    }
    return escLit(`<${node.tag}`) + attrs + escLit(">") + inner + escLit(`</${node.tag}>`);
}
/**
 * Compile a `{#each list as item}` block to a `${…}` template-literal interpolation
 * that iterates the (server-evaluated) list and joins the per-item body. `list` is a
 * JS expression evaluated where `ssr` data bindings are in scope as raw named values.
 */
function compileEachExpr(node) {
    const item = node.item;
    const index = node.index ?? "__wi";
    const body = node.body.map(renderLoopBody).join("");
    const empty = node.empty.map(renderLoopBody).join("");
    return ("${(() => { const __wl = Array.isArray(" +
        node.list +
        ") ? (" +
        node.list +
        ") : []; return __wl.length ? __wl.map((" +
        item +
        ", " +
        index +
        ") => `" +
        body +
        '`).join("") : `' +
        empty +
        "`; })()}");
}
/**
 * Compile a `{#if}` block to a `${…}` template-literal interpolation: a nested ternary
 * that renders the first truthy branch's body (or the `{:else}` body, or "" when neither).
 * Conditions are JS expressions evaluated in the surrounding server scope.
 */
function compileIfExpr(node) {
    let expr = "``"; // no matching branch → empty string
    for (let k = node.branches.length - 1; k >= 0; k--) {
        const b = node.branches[k];
        const bodySrc = "`" + b.body.map(renderLoopBody).join("") + "`";
        expr = b.cond === null ? bodySrc : "(" + b.cond + ") ? " + bodySrc + " : " + expr;
    }
    return "${" + expr + "}";
}
/**
 * Collect every server-control expression in a view (recursively): `{#each}` list
 * expressions and `{#if}` conditions. Used to wire up raw SSR data consts.
 */
function collectControlExprs(nodes, out = []) {
    for (const node of nodes) {
        if (node.type === "text")
            continue;
        if (node.type === "each") {
            out.push(node.list);
            collectControlExprs(node.body, out);
            collectControlExprs(node.empty, out);
        }
        else if (node.type === "if") {
            for (const b of node.branches) {
                if (b.cond)
                    out.push(b.cond);
                collectControlExprs(b.body, out);
            }
        }
        else if (node.type === "element") {
            collectControlExprs(node.children, out);
        }
    }
    return out;
}
function renderNode(node, ssrBindings, csrBindings, apiBindings, loops, reactive = null) {
    if (node.type === "text")
        return substituteReactiveText(node.value, reactive, loops); // {t:key} + state baking
    // Server control block (loop / conditional) → a sentinel that survives
    // templateEscape, swapped for its real `${…}` code after escaping.
    if (node.type === "each" || node.type === "if") {
        loops.push(node.type === "each" ? compileEachExpr(node) : compileIfExpr(node));
        return `\x00WRNEACH${loops.length - 1}\x00`;
    }
    if (node.tag === "Static" || node.tag === "Dynamic") {
        const inner = node.children
            .map((child) => renderNode(child, ssrBindings, csrBindings, apiBindings, loops, reactive))
            .join("");
        return node.tag === "Static"
            ? inner
            : `<wrn-dynamic-region data-wrn-dynamic="true">${inner}</wrn-dynamic-region>`;
    }
    if (node.tag === "Portal" || node.tag === "Transition" || node.tag === "Component") {
        const inner = node.children
            .map((child) => renderNode(child, ssrBindings, csrBindings, apiBindings, loops, reactive))
            .join("");
        const attribute = node.tag === "Portal"
            ? "data-wrn-portal"
            : node.tag === "Transition"
                ? "data-wrn-transition"
                : "data-wrn-dynamic-component";
        const source = node.tag === "Portal" ? "to" : node.tag === "Transition" ? "name" : "is";
        const fallback = node.tag === "Portal" ? "body" : node.tag === "Transition" ? "wrn-transition" : "";
        const original = node.attrs.find((item) => item.name === source);
        const rendered = original
            ? renderAttrs([{ ...original, name: attribute }], undefined, reactive, loops)
            : ` ${attribute}="${attrEscape(fallback)}"`;
        return `<div${rendered}>${inner}</div>`;
    }
    if (node.tag === "Async") {
        const source = attrValue(node.attrs, "source") ?? "data";
        const retries = attrValue(node.attrs, "retries") ?? "2";
        const tags = attrValue(node.attrs, "tags") ?? source;
        const serverResolved = attrValue(node.attrs, "data-wrn-async-server") === "true";
        const branchElement = (name) => node.children.find((child) => child.type === "element" && child.tag === name);
        const branch = (name) => {
            const element = branchElement(name);
            return (element?.children ?? [])
                .map((child) => renderNode(child, ssrBindings, csrBindings, apiBindings, loops, reactive))
                .join("");
        };
        const loading = branch("Loading");
        const success = branch("Success");
        const error = branch("Error");
        const successElement = branchElement("Success");
        const errorElement = branchElement("Error");
        const identifier = (value, fallback) => value && isSafeGeneratedIdentifier(value) ? value : fallback;
        const successAlias = identifier(successElement ? attrValue(successElement.attrs, "data") : undefined, identifier(source, "data"));
        const errorAlias = identifier(errorElement ? attrValue(errorElement.attrs, "error") : undefined, "error");
        const nested = (value) => value.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
        const scoped = (value, alias, expression) => {
            const index = loops.push(`\${(() => { const ${alias} = ${expression}; return \`${nested(value)}\`; })()}`) - 1;
            return `\x00WRNEACH${index}\x00`;
        };
        const successTemplate = scoped(success, successAlias, `(ctx[${JSON.stringify(source)}] ?? {})`);
        const errorTemplate = scoped(error, errorAlias, `{ message: "" }`);
        let initial = loading;
        if (serverResolved) {
            const sourcePattern = successAlias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
            const serverSuccess = success.replace(new RegExp(`\\{\\s*(${sourcePattern}(?:\\.[A-Za-z_$][\\w$]*)*)\\s*\\}`, "g"), (_whole, expression) => `\${__wrnexusEscapeHtml(${expression})}`);
            const index = loops.push(`\${ctx[${JSON.stringify(source)}] !== undefined ? (() => { const ${successAlias} = ctx[${JSON.stringify(source)}]; return \`${nested(serverSuccess)}\`; })() : \`${nested(loading)}\`}`) - 1;
            initial = `\x00WRNEACH${index}\x00`;
        }
        return `<section data-wrn-async="${attrEscape(source)}" data-wrn-async-tags="${attrEscape(tags)}" data-wrn-async-retries="${attrEscape(retries)}"${serverResolved ? ' data-wrn-async-resolved="true"' : ""} aria-busy="${serverResolved ? "false" : "true"}"><div data-wrn-async-content>${initial}</div><template data-wrn-async-loading>${loading}</template><template data-wrn-async-success data-wrn-async-alias="${attrEscape(successAlias)}">${successTemplate}</template><template data-wrn-async-error data-wrn-async-alias="${attrEscape(errorAlias)}">${errorTemplate}</template></section>`;
    }
    if (node.tag === "KeepAlive") {
        const key = attrValue(node.attrs, "key") ?? "default";
        const inner = node.children
            .map((child) => renderNode(child, ssrBindings, csrBindings, apiBindings, loops, reactive))
            .join("");
        return `<div data-wrn-keepalive="${attrEscape(key)}">${inner}</div>`;
    }
    if (isComponentTag(node.tag)) {
        return renderPageComponentInvocation(node, ssrBindings, csrBindings, apiBindings, loops, reactive);
    }
    const apiName = attrValue(node.attrs, "api");
    const apiBinding = apiName ? apiBindings.get(apiName) : undefined;
    if (apiName && !apiBinding) {
        throw new Error(`Unknown .wrn api binding "${apiName}"`);
    }
    const ssrGet = attrValue(node.attrs, "ssrGet");
    const ssrText = attrValue(node.attrs, "ssrText");
    const csrGet = attrValue(node.attrs, "csrGet");
    const csrText = attrValue(node.attrs, "csrText");
    const csrId = apiBinding?.mode === "client"
        ? csrMarker(csrBindings, renderBinding(apiBinding))
        : csrGet && csrText
            ? csrMarker(csrBindings, {
                method: "GET",
                path: apiRoutePath(csrGet),
                body: expressionBody(csrText),
                helpers: "",
            })
            : undefined;
    // Void elements (<br>, <img>, …) have no closing tag and no children.
    if (parser_ts_1.VOID_ELEMENTS.has(node.tag.toLowerCase())) {
        return `<${node.tag}${renderAttrs(node.attrs, csrId, reactive, loops)}>`;
    }
    const inner = apiBinding?.mode === "ssr"
        ? ssrMarker(ssrBindings, renderBinding(apiBinding))
        : ssrGet && ssrText
            ? ssrMarker(ssrBindings, {
                method: "GET",
                path: apiRoutePath(ssrGet),
                body: expressionBody(ssrText),
                helpers: "",
            })
            : node.children
                .map((child) => renderNode(child, ssrBindings, csrBindings, apiBindings, loops, reactive))
                .join("");
    return `<${node.tag}${renderAttrs(node.attrs, csrId, reactive, loops)}>${inner}</${node.tag}>`;
}
function renderPageComponentInvocation(node, ssrBindings, csrBindings, apiBindings, loops, reactive) {
    const attrs = node.attrs
        .filter((attr) => attr.name !== "data-component")
        .map((attr) => renderPageComponentAttr(attr, loops))
        .join("");
    const inner = node.children
        .map((child) => renderNode(child, ssrBindings, csrBindings, apiBindings, loops, reactive))
        .join("");
    return `<div data-component="${attrEscape(node.tag)}"` + `${attrs}>${inner}</div>`;
}
function renderNestedComponentInvocation(node, ctx) {
    let bindIndex = 0;
    const attrs = node.attrs
        .filter((attr) => attr.name !== "data-component")
        .map((attr) => {
        const spread = /^\{\.\.\.([A-Za-z_$][\w$]*)\}$/.exec(attr.name);
        if (spread) {
            return `\${__wireSpreadAttrs(${ctx.resolveExpr(spread[1])})}`;
        }
        if (attr.event) {
            return (escLit(` ${componentEventAttribute(attr.name)}="`) +
                escLit(attrEscape(attr.value)) +
                escLit(`"`));
        }
        if (attr.boolean) {
            return ` ${attr.name}`;
        }
        const wholeExpression = wholeAttributeExpression(attr.value);
        const compiledValue = wholeExpression
            ? `\${__wireProp(${ctx.resolveExpr(wholeExpression)})}`
            : compileAttrValue(attr.value, ctx);
        const rendered = ` ${attr.name}="${compiledValue}"`;
        if (!attr.value.includes("{") ||
            (!exprRefsState(attr.value, ctx.stateNames) && !exprRefsState(attr.value, ctx.propNames))) {
            return rendered;
        }
        const marker = attrEscape(JSON.stringify([attr.name, attr.value]));
        return rendered + ` data-wrn-prop-bind-${bindIndex++}="${escLit(marker)}"`;
    })
        .join("");
    const loops = loopVarsOf(node);
    const childCtx = loops.length > 0
        ? {
            ...ctx,
            forwardRestAttrs: false,
            loopVars: new Set([...(ctx.loopVars ?? []), ...loops]),
        }
        : { ...ctx, forwardRestAttrs: false };
    const inner = node.children.map((child) => renderComponentNode(child, childCtx)).join("");
    return (`<div data-component="${attrEscape(node.tag)}"` +
        `${ctx.forwardRestAttrs ? "${__wireSpreadAttrs(__attrs)}" : ""}` +
        `${attrs}>${inner}</div>`);
}
function ssrMarker(bindings, binding) {
    const marker = `<!--wrnexus-ssr:${bindings.length}-->`;
    bindings.push({ marker, ...binding });
    return marker;
}
function csrMarker(bindings, binding) {
    const id = String(bindings.length);
    bindings.push({ id, ...binding });
    return id;
}
function renderBinding(binding) {
    return {
        method: binding.method,
        path: binding.path,
        body: binding.body,
        helpers: binding.helpers,
    };
}
function hasClientBehavior(nodes) {
    return nodes.some((node) => {
        // `{t:key}` is i18n sugar resolved server-side — not client reactivity.
        if (node.type === "text")
            return /\{(?!t:)[^{}]+\}/.test(node.value);
        // Server control blocks render on the server; they don't add client reactivity.
        if (node.type === "each") {
            return hasClientBehavior(node.body) || hasClientBehavior(node.empty);
        }
        if (node.type === "if") {
            return node.branches.some((branch) => hasClientBehavior(branch.body));
        }
        return (node.attrs.some((attr) => attr.event || attr.name === "csrGet" || attr.name === "csrText") ||
            hasClientBehavior(node.children));
    });
}
function apiRoutePath(path) {
    const trimmed = path.trim();
    if (!trimmed.startsWith("/")) {
        throw new Error(`.wrn API paths must start with "/": ${path}`);
    }
    if (trimmed.includes("\0") || trimmed.includes("\\") || /(^|\/)\.\.(\/|$)/.test(trimmed)) {
        throw new Error(`Unsafe .wrn API path: ${path}`);
    }
    if (trimmed === "/api" || trimmed.startsWith("/api/"))
        return trimmed;
    return `/api${trimmed}`;
}
function expressionBody(expr) {
    return `return (${expr});`;
}
function dataBody(source) {
    const trimmed = source.trim();
    if (!trimmed)
        return "return undefined;";
    return /\breturn\b/.test(trimmed) ? trimmed : expressionBody(trimmed);
}
function modeHelpers(ast, mode, sharedHelpers) {
    return [
        sharedHelpers,
        ...ast.modeFunctions
            .filter((block) => block.mode === mode)
            .map((block) => block.body.trim())
            .filter(Boolean),
    ]
        .filter(Boolean)
        .join("\n\n");
}
function apiBindingMap(ast, sharedHelpers) {
    const bindings = new Map();
    for (const block of ast.dataApis) {
        if (bindings.has(block.name)) {
            throw new Error(`Duplicate .wrn api binding "${block.name}"`);
        }
        bindings.set(block.name, {
            mode: block.mode,
            method: block.method,
            path: apiRoutePath(block.path),
            body: dataBody(block.body),
            helpers: modeHelpers(ast, block.mode, sharedHelpers),
        });
    }
    return bindings;
}
function ssrRuntimeSource() {
    return `const __wrnexusHtmlEscapes = { "&": "&amp;", "<": "&lt;", ">": "&gt;", "\\"": "&quot;", "'": "&#39;" };
function __wrnexusEscapeHtml(value: unknown): string {
  return String(value).replace(/[&<>"']/g, (ch) => __wrnexusHtmlEscapes[ch] ?? ch);
}

type __WrnexusContext = import("@wrnexus/core").Context & {
  __wrnexusCallApi?: (path: string, method: string) => Promise<unknown>;
  localStorage?: unknown;
};

function __wrnexusEvalData(data: unknown, body: string, helpers = "", ctx: __WrnexusContext): unknown {
  const adapters = {
    cookies: ctx.cookies,
    session: ctx.session,
    localStorage: ctx.localStorage,
  };
  return new Function("$data", "$adapters", "const cookies = $adapters.cookies;\\nconst session = $adapters.session;\\nconst localStorage = $adapters.localStorage;\\nwith ($data ?? {}) {\\n" + helpers + "\\n" + body + "\\n}")(data, adapters);
}

function __wrnexusPropAttr(
  value: unknown,
): string {
  const serialized =
    value !== null &&
    typeof value === "object"
      ? JSON.stringify(value)
      : String(value == null ? "" : value);

  return serialized.replace(
    /[&<>"]/g,
    (character) =>
      character === "&"
        ? "&amp;"
        : character === "<"
          ? "&lt;"
          : character === ">"
            ? "&gt;"
            : "&quot;",
  );
}

async function __wrnexusCallApi(path: string, method: string, ctx: __WrnexusContext): Promise<unknown> {
  if (typeof ctx.__wrnexusCallApi === "function") {
    return await ctx.__wrnexusCallApi(path, method);
  }

  const url = new URL(path, ctx.req.url);
  const res = await fetch(new Request(url, { method, headers: ctx.req.headers }));
  if (!res.ok) {
    throw new Error(".wrn data API request failed with status " + res.status);
  }

  const type = res.headers.get("content-type") || "";
  return type.includes("application/json") ? await res.json() : await res.text();
}

async function __wrnexusRenderSsrBindings(html: string, ctx: __WrnexusContext): Promise<string> {
  for (const binding of __wrnexusSsrBindings) {
    const data = await __wrnexusCallApi(binding.path, binding.method, ctx);
    const value = __wrnexusEvalData(data, binding.body, binding.helpers, ctx);
    html = html.replace(binding.marker, __wrnexusEscapeHtml(value));
  }
  return html;
}`;
}
function stableHash(value) {
    let hash = 0x811c9dc5;
    for (let index = 0; index < value.length; index++) {
        hash ^= value.charCodeAt(index);
        hash = Math.imul(hash, 0x01000193);
    }
    return (hash >>> 0).toString(36);
}
function hydrationId(ast) {
    const shape = JSON.stringify({
        kind: ast.kind,
        name: ast.name,
        props: ast.props.map((entry) => entry.name),
        events: ast.events.map((entry) => entry.name),
        states: ast.states.map((entry) => entry.name),
        computed: ast.computed.map((entry) => entry.name),
        view: ast.view,
    });
    return `${ast.name}:${stableHash(shape)}`;
}
function localStyleId(ast) {
    return `wrn-${ast.kind}-${stableHash(`${ast.kind}:${ast.name}`)}`;
}
function localStyleTag(ast, styles) {
    if (!styles.length)
        return "";
    const id = localStyleId(ast);
    const css = styles.map(styleEscape).join("\n");
    return `<style data-wrnexus-style="${attrEscape(ast.name)}" data-wrnexus-style-id="${attrEscape(id)}" data-wrnexus-style-owner="${attrEscape(ast.name)}" data-wrnexus-style-kind="${attrEscape(ast.kind)}">\n${css}\n</style>`;
}
function localStyleExport(ast, styles) {
    if (!styles.length)
        return null;
    return `export const __wrnexusStyles = ${JSON.stringify([
        {
            id: localStyleId(ast),
            owner: ast.name,
            kind: ast.kind,
            css: styles.join("\n"),
        },
    ], null, 2)};`;
}
function isStoreImportSource(source) {
    return /(?:^|\/)stores?\//.test(source) || source.startsWith("@wrnexus/store");
}
function importedStoreBindings(ast) {
    return ast.structuredImports
        .filter((entry) => entry.defaultImport && entry.source.endsWith(".wrn") && isStoreImportSource(entry.source))
        .map((entry) => ({
        local: entry.defaultImport,
        internal: `__wrnexusStoreDefinition_${entry.defaultImport}`,
    }));
}
function generatedImports(ast) {
    const stores = new Map(importedStoreBindings(ast).map((entry) => [entry.local, entry.internal]));
    return ast.structuredImports.map((entry) => {
        if (!entry.defaultImport)
            return entry.raw;
        const internal = stores.get(entry.defaultImport);
        return internal
            ? entry.raw.replace(new RegExp(`^(\\s*import\\s+(?:type\\s+)?)(?:${entry.defaultImport.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")})(\\s+from\\s+)`), `$1${internal}$2`)
            : entry.raw;
    });
}
function isSafeGeneratedIdentifier(name) {
    return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
}
function generateSsrStateAliases(stateNames) {
    const names = [...new Set(stateNames)].filter(isSafeGeneratedIdentifier);
    if (!names.length) {
        return "";
    }
    return `const { ${names.join(", ")} } = __state;\n`;
}
function orderPageStates(entries) {
    if (entries.length < 2)
        return entries;
    const byName = new Map(entries.map((entry) => [entry.name, entry]));
    const visiting = new Set();
    const visited = new Set();
    const ordered = [];
    const visit = (name) => {
        if (visited.has(name))
            return;
        if (visiting.has(name)) {
            throw new Error(`WRN-STATE-CYCLE: state value '${name}' has a dependency cycle.`);
        }
        const entry = byName.get(name);
        if (!entry)
            return;
        visiting.add(name);
        for (const dependency of byName.keys()) {
            if (dependency !== name &&
                new RegExp(`\\b${dependency.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`).test(entry.expr)) {
                visit(dependency);
            }
        }
        visiting.delete(name);
        visited.add(name);
        ordered.push(entry);
    };
    for (const entry of entries)
        visit(entry.name);
    return ordered;
}
function generateSsrStateInitializer(entries) {
    const ordered = orderPageStates(entries);
    const declarations = ordered
        .filter((entry) => isSafeGeneratedIdentifier(entry.name))
        .map((entry) => `const ${entry.name} = (() => { try { return (${entry.expr}); } catch { return undefined; } })();`)
        .join(" ");
    const values = entries
        .map((entry) => {
        if (isSafeGeneratedIdentifier(entry.name)) {
            return `${JSON.stringify(entry.name)}: ${entry.name}`;
        }
        return `${JSON.stringify(entry.name)}: (() => { try { return (${entry.expr}); } catch { return undefined; } })()`;
    })
        .join(", ");
    return `(() => { ${declarations} return { ${values} }; })()`;
}
function orderPageComputed(entries) {
    if (entries.length < 2)
        return entries;
    const byName = new Map(entries.map((entry) => [entry.name, entry]));
    const visiting = new Set();
    const visited = new Set();
    const ordered = [];
    const visit = (name) => {
        if (visited.has(name))
            return;
        if (visiting.has(name)) {
            throw new Error(`WRN-COMPUTED-CYCLE: computed value '${name}' has a dependency cycle.`);
        }
        const entry = byName.get(name);
        if (!entry)
            return;
        visiting.add(name);
        for (const dependency of byName.keys()) {
            if (dependency !== name &&
                new RegExp(`\\b${dependency.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`).test(entry.expr)) {
                visit(dependency);
            }
        }
        visiting.delete(name);
        visited.add(name);
        ordered.push(entry);
    };
    for (const entry of entries)
        visit(entry.name);
    return ordered;
}
function generateSsrComputedAliases(entries) {
    return orderPageComputed(entries)
        .filter((entry) => isSafeGeneratedIdentifier(entry.name))
        .map((entry) => `const ${entry.name} = (() => { try { return (${entry.expr}); } catch { return undefined; } })();`)
        .join("\n");
}
function runtimeComputedNames(states, computed, runtimeRoots = []) {
    const entries = [...states, ...computed];
    const runtime = new Set([
        ...runtimeRoots,
        ...entries.filter((entry) => /\bctx\b/.test(entry.expr)).map((entry) => entry.name),
    ]);
    let changed = true;
    while (changed) {
        changed = false;
        for (const entry of entries) {
            if (runtime.has(entry.name))
                continue;
            if ([...runtime].some((name) => new RegExp(`\\b${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`).test(entry.expr))) {
                runtime.add(entry.name);
                changed = true;
            }
        }
    }
    return runtime;
}
function hydrationAttribute(ast) {
    const strategy = ["static", "server"].includes(ast.renderMode ?? "")
        ? "none"
        : (ast.hydrate ?? "load");
    const hasBrowserModule = (0, client_codegen_ts_1.browserModuleRequired)(ast);
    const moduleAttribute = hasBrowserModule
        ? ' data-wrn-client-module="__WRNEXUS_CLIENT_MODULE__"'
        : "";
    return ` data-wrn-hydration="${attrEscape(hydrationId(ast))}" data-wrn-hydrate="${attrEscape(strategy)}" data-wrn-runtime="${attrEscape(ast.runtime ?? "universal")}"${moduleAttribute}`;
}
function targetFunctions(ast, target) {
    const runtimes = target === "browser"
        ? ["legacy", "client", "shared"]
        : ["legacy", "server", "shared"];
    return ast.functions
        .map((body) => (0, syntax_1.stripRuntimeFunctionModifiers)(body, [...runtimes]))
        .map((body) => body.trim())
        .filter(Boolean)
        .join("\n\n");
}
function publicOutputNames(ast) {
    return [
        ...new Set([
            ...ast.outputs.map((output) => output.name),
            ...ast.events.map((event) => event.name),
        ]),
    ];
}
function prepareActionForms(nodes, actions) {
    for (const node of nodes) {
        if (node.type === "text")
            continue;
        if (node.type === "each") {
            prepareActionForms(node.body, actions);
            prepareActionForms(node.empty, actions);
            continue;
        }
        if (node.type === "if") {
            node.branches.forEach((branch) => prepareActionForms(branch.body, actions));
            continue;
        }
        prepareActionForms(node.children, actions);
        if (node.tag.toLowerCase() !== "form")
            continue;
        const submit = node.attrs.find((attr) => attr.event && attr.name === "submit");
        if (!submit || !actions.has(submit.value.trim()))
            continue;
        const name = submit.value.trim();
        node.attrs = node.attrs.filter((attr) => attr !== submit);
        if (!node.attrs.some((attr) => !attr.event && attr.name === "method")) {
            node.attrs.push({ name: "method", value: "post", event: false });
        }
        node.attrs.push({ name: "data-wrn-action", value: name, event: false });
        node.children.unshift({
            type: "element",
            tag: "input",
            attrs: [
                { name: "type", value: "hidden", event: false },
                { name: "name", value: "_wrnexus_action", event: false },
                { name: "value", value: name, event: false },
            ],
            children: [],
        });
    }
}
function markServerAsyncBoundaries(nodes, serverLoads) {
    for (const node of nodes) {
        if (node.type === "text")
            continue;
        if (node.type === "each") {
            markServerAsyncBoundaries(node.body, serverLoads);
            markServerAsyncBoundaries(node.empty, serverLoads);
            continue;
        }
        if (node.type === "if") {
            node.branches.forEach((branch) => markServerAsyncBoundaries(branch.body, serverLoads));
            continue;
        }
        if (node.tag === "Async") {
            const source = attrValue(node.attrs, "source") ?? "data";
            if (serverLoads.has(source) &&
                !node.attrs.some((attribute) => attribute.name === "data-wrn-async-server")) {
                node.attrs.push({ name: "data-wrn-async-server", value: "true", event: false });
            }
        }
        markServerAsyncBoundaries(node.children, serverLoads);
    }
}
function generate(ast) {
    ast = (0, analysis_ts_1.optimizeAst)(ast).ast;
    if (ast.kind === "global-store" || ast.kind === "page-store")
        return (0, store_codegen_ts_1.generateStoreModule)(ast);
    if (ast.kind === "component" || ast.kind === "layout") {
        return generateComponent(ast);
    }
    const out = [];
    prepareActionForms(ast.view, new Set(ast.actions.map((action) => action.name)));
    markServerAsyncBoundaries(ast.view, new Set(ast.loads
        .filter((load) => load.mode === "server" && !load.deferred && load.name)
        .map((load) => load.name)));
    if (ast.actions.length > 0) {
        out.push(`import { createActionClient } from "@wrnexus/csr";\nimport type { InferSchema } from "@wrnexus/validation";`);
    }
    if (ast.imports.length > 0)
        out.push(generatedImports(ast).join("\n"));
    const ssrBindings = [];
    const csrBindings = [];
    const helpers = targetFunctions(ast, "server");
    const apiBindings = apiBindingMap(ast, helpers);
    const typeSource = ast.types
        .map((body) => body.trim())
        .filter(Boolean)
        .join("\n\n");
    if (typeSource)
        out.push(typeSource);
    if (helpers) {
        out.push(`// --- .wrn functions ---\n${helpers}`);
    }
    // --- Page metadata / SEO ---
    out.push(`export const meta = ${JSON.stringify({ title: ast.name, ...ast.seo }, null, 2)};`);
    if (ast.layout)
        out.push(`export const layout = ${ast.layoutIsSymbol ? ast.layout : JSON.stringify(ast.layout)};`);
    out.push(`export const __wrnexusRuntime = ${JSON.stringify(ast.runtime ?? "universal")};`);
    out.push(`export const __wrnexusRender = ${JSON.stringify(ast.renderMode ?? "hybrid")};`);
    out.push(`export const __wrnexusHydrate = ${JSON.stringify(["static", "server"].includes(ast.renderMode ?? "") ? "none" : (ast.hydrate ?? "load"))};`);
    out.push(`export const __wrnexusHydrationId = ${JSON.stringify(hydrationId(ast))};`);
    if (Object.keys(ast.cache ?? {}).length > 0)
        out.push(`export const __wrnexusCache = ${JSON.stringify(ast.cache, null, 2)};`);
    if (Object.keys(ast.security).length > 0) {
        out.push(`export const __wrnexusSecurity = ${JSON.stringify(ast.security, null, 2)};`);
    }
    if (Object.keys(ast.navigation).length > 0) {
        out.push(`export const __wrnexusNavigation = ${JSON.stringify(ast.navigation, null, 2)};`);
    }
    // --- View -> default page component ---
    const orderedStates = orderPageStates(ast.states);
    const browserStates = ast.states.filter((state) => state.runtime !== "server");
    const seedScope = evalStateSeeds(orderedStates);
    const orderedComputed = orderPageComputed(ast.computed);
    for (const entry of orderedComputed) {
        try {
            seedScope[entry.name] = new Function("with(this){return (" + entry.expr + ");}").call(seedScope);
        }
        catch {
            seedScope[entry.name] = undefined;
        }
    }
    const reactiveNames = [
        ...browserStates.map((entry) => entry.name),
        ...ast.computed.map((entry) => entry.name),
    ];
    const storeBindings = importedStoreBindings(ast);
    const runtimeRoots = [
        ...storeBindings.map((entry) => entry.local),
        ...ast.loads
            .filter((load) => load.mode === "server" && !load.deferred && load.name)
            .map((load) => load.name),
    ];
    const runtimeStateNames = runtimeComputedNames(orderedStates, orderedComputed, runtimeRoots);
    const reactive = reactiveNames.length > 0
        ? { stateNames: new Set(reactiveNames), runtimeStateNames, scope: seedScope }
        : null;
    const loops = [];
    let html = ast.view
        .map((node) => renderNode(node, ssrBindings, csrBindings, apiBindings, loops, reactive))
        .join("");
    const styles = ast.styles.map((body) => body.trim()).filter(Boolean);
    const pageBehavior = ast.runtime === "server" ? null : componentBehavior(ast);
    const needsClientRuntime = ast.runtime !== "server" &&
        (browserStates.length > 0 ||
            ast.computed.length > 0 ||
            hasClientBehavior(ast.view) ||
            pageBehavior !== null);
    if (needsClientRuntime) {
        const scopePlaceholder = "__WRNEXUS_DYNAMIC_SCOPE__";
        html = `<div data-scope="${scopePlaceholder}"${behaviorAttribute(pageBehavior)}${hydrationAttribute(ast)}>${html}</div>`;
    }
    const pageStyleTag = localStyleTag(ast, styles);
    if (pageStyleTag) {
        html = `${pageStyleTag}${html}`;
    }
    if (ast.renderMode === "client") {
        const clientRoot = hydrationId(ast);
        html = `<div data-wrn-client-root="${clientRoot}" aria-busy="true"></div><template data-wrn-client-template="${clientRoot}">${html}</template>`;
    }
    const pageStyleExport = localStyleExport(ast, styles);
    if (pageStyleExport)
        out.push(pageStyleExport);
    if (csrBindings.length > 0) {
        out.push(`export const __wrnexusCsr = ${JSON.stringify(csrBindings, null, 2)};`);
    }
    if (pageBehavior) {
        out.push(`export const __wrnexusBehavior = ${JSON.stringify(pageBehavior, null, 2)};`);
    }
    // Escape the static HTML for the template literal, then swap loop sentinels for
    // their real `${…}` code (which must NOT be escaped).
    let body = templateEscape(html);
    let staticShellBody;
    if (ast.renderMode === "partial-static") {
        const shellHtml = html.replace(/<wrn-dynamic-region\b[^>]*>[\s\S]*?<\/wrn-dynamic-region>/gi, '<wrn-dynamic-region data-wrn-dynamic="true"></wrn-dynamic-region>');
        staticShellBody = templateEscape(shellHtml);
    }
    const dynamicStateInitializer = generateSsrStateInitializer(orderedStates);
    const stateType = ast.states.length > 0
        ? `{ ${ast.states
            .map((state) => `${JSON.stringify(state.name)}: ${state.valueType ?? "unknown"}`)
            .join("; ")} }`
        : "Record<string, never>";
    const hydrationStateNames = JSON.stringify(browserStates.map((state) => state.name));
    const ssrStateAliases = generateSsrStateAliases(ast.states.map((state) => state.name));
    const ssrComputedAliases = generateSsrComputedAliases(orderedComputed);
    const storeDeclarations = storeBindings
        .map((entry) => `        const ${entry.local} = await ctx.__wrnexusUseStore(${entry.internal});`)
        .join("\n");
    const serverLoadAliases = ast.loads
        .filter((load) => load.mode === "server" && !load.deferred && load.name)
        .map((load) => `        const ${load.name} = ctx[${JSON.stringify(load.name)}];`)
        .join("\n");
    // Inner dynamic expressions are registered before the wrapper that scopes
    // them (for example an Async branch alias). Resolve from the outside in so a
    // wrapper sentinel is expanded before its nested sentinels are visited.
    for (let idx = loops.length - 1; idx >= 0; idx--) {
        const code = loops[idx];
        body = body.replaceAll(`\x00WRNEACH${idx}\x00`, code);
        if (staticShellBody?.includes(`\x00WRNEACH${idx}\x00`)) {
            staticShellBody = staticShellBody.replaceAll(`\x00WRNEACH${idx}\x00`, code);
        }
    }
    // Server loops iterate raw SSR data. Declare a named const for every `ssr` data
    // binding a loop references, so `{#each <name> as …}` can iterate the real value.
    const loopConsts = [];
    if (loops.length > 0) {
        const lists = collectControlExprs(ast.view);
        for (const [name, binding] of apiBindings) {
            if (binding.mode !== "ssr")
                continue;
            if (!lists.some((expr) => new RegExp(`\\b${name}\\b`).test(expr)))
                continue;
            loopConsts.push(`  const ${name} = __wrnexusEvalData(await __wrnexusCallApi(${JSON.stringify(binding.path)}, ${JSON.stringify(binding.method)}, ctx), ${JSON.stringify(binding.body)}, ${JSON.stringify(binding.helpers)}, ctx);`);
        }
    }
    const needsSsrRuntime = ssrBindings.length > 0 || loops.length > 0 || runtimeStateNames.size > 0;
    if (needsSsrRuntime) {
        out.push(ssrRuntimeSource());
        out.push(`const __wrnexusSsrBindings = ${JSON.stringify(ssrBindings, null, 2)};`);
        const decls = loopConsts.length > 0 ? loopConsts.join("\n") + "\n" : "";
        out.push(`export default async function ${ast.name}(ctx: __WrnexusContext) {
        ${storeDeclarations}
        ${serverLoadAliases}
      ${decls}
        const __state: ${stateType} = ${dynamicStateInitializer};
        ${ssrStateAliases}
        ${ssrComputedAliases}
        const __hydrationState = Object.fromEntries(${hydrationStateNames}.map((key) => [key, Reflect.get(__state, key)]));
        const __scopeValue = Object.entries(__hydrationState)
          .map(([key, value]) => {
            let encoded: string;
            try {
              encoded = value === undefined ? "undefined" : JSON.stringify(value);
            } catch {
              encoded = JSON.stringify(String(value));
            }
            return key + ": " + encoded;
          })
          .join(", ")
          .replace(/&/g, "&amp;")
          .replace(/"/g, "&quot;")
          .replace(/</g, "&lt;")
          .replace(/>/g, "&gt;");

        const html = \`${body}\`.replace(
          "__WRNEXUS_DYNAMIC_SCOPE__",
          __scopeValue,
        );

        return await __wrnexusRenderSsrBindings(html, ctx);
      }`);
    }
    else {
        out.push(`export default ${storeBindings.length > 0 ? "async " : ""}function ${ast.name}(ctx: import("@wrnexus/core").Context) {
        ${storeDeclarations}
        ${serverLoadAliases}
        const __state: ${stateType} = ${dynamicStateInitializer};
        ${ssrStateAliases}
        ${ssrComputedAliases}
        const __hydrationState = Object.fromEntries(${hydrationStateNames}.map((key) => [key, Reflect.get(__state, key)]));
        const __scopeValue = Object.entries(__hydrationState)
          .map(([key, value]) => {
            let encoded: string;
            try {
              encoded = value === undefined ? "undefined" : JSON.stringify(value);
            } catch {
              encoded = JSON.stringify(String(value));
            }
            return key + ": " + encoded;
          })
          .join(", ")
          .replace(/&/g, "&amp;")
          .replace(/"/g, "&quot;")
          .replace(/</g, "&lt;")
          .replace(/>/g, "&gt;");

        return \`${body}\`.replace(
          "__WRNEXUS_DYNAMIC_SCOPE__",
          __scopeValue,
        );
      }`);
    }
    if (staticShellBody !== undefined) {
        out.push(`export async function __wrnexusBuildStaticShell(ctx: import("@wrnexus/core").Context = {} as import("@wrnexus/core").Context) {
        ${storeDeclarations}
        ${serverLoadAliases}
        ${loopConsts.length > 0 ? loopConsts.join("\n") : ""}
        const __state: ${stateType} = ${dynamicStateInitializer};
        ${ssrStateAliases}
        ${ssrComputedAliases}
        const __hydrationState = Object.fromEntries(${hydrationStateNames}.map((key) => [key, Reflect.get(__state, key)]));
        const __scopeValue = Object.entries(__hydrationState)
          .map(([key, value]) => {
            let encoded: string;
            try {
              encoded = value === undefined ? "undefined" : JSON.stringify(value);
            } catch {
              encoded = JSON.stringify(String(value));
            }
            return key + ": " + encoded;
          })
          .join(", ")
          .replace(/&/g, "&amp;")
          .replace(/"/g, "&quot;")
          .replace(/</g, "&lt;")
          .replace(/>/g, "&gt;");
        return \`${staticShellBody}\`.replace("__WRNEXUS_DYNAMIC_SCOPE__", __scopeValue);
      }`);
    }
    if (ast.loads.length > 0) {
        const serverLoads = ast.loads.filter((entry) => entry.mode === "server" && !entry.deferred);
        const publicClientLoads = ast.loads.filter((entry) => entry.mode === "client" || entry.deferred);
        const namedByName = new Map(ast.loads.filter((entry) => entry.name).map((entry) => [entry.name, entry]));
        const clientNames = new Set(publicClientLoads.flatMap((entry) => (entry.name ? [entry.name] : [])));
        const includeDependencies = (name) => {
            for (const dependency of namedByName.get(name)?.dependsOn ?? []) {
                if (clientNames.has(dependency))
                    continue;
                clientNames.add(dependency);
                includeDependencies(dependency);
            }
        };
        for (const name of [...clientNames])
            includeDependencies(name);
        const clientLoads = ast.loads.filter((entry) => !entry.name || clientNames.has(entry.name));
        const renderLoads = (exportName, execution, exposed) => {
            const declarations = execution
                .filter((entry) => entry.name)
                .map((entry) => {
                const dependencies = (entry.dependsOn ?? [])
                    .map((dependency) => `const ${dependency} = await __load_${dependency}();`)
                    .join("\n");
                return `  let __promise_${entry.name}: Promise<unknown> | undefined;
  const __load_${entry.name} = () => (__promise_${entry.name} ??= (async () => {
    ${dependencies}
    ${entry.body}
  })());`;
            })
                .join("\n");
            const visible = exposed.filter((entry) => entry.name);
            return `export async function ${exportName}(ctx: import("@wrnexus/core").Context) {
${exposed
                .filter((entry) => !entry.name)
                .map((entry) => entry.body)
                .join("\n")}
${declarations}
${visible.length
                ? `  const __values = await Promise.all([${visible.map((entry) => `__load_${entry.name}()`).join(", ")}]);
  return { ${visible.map((entry, index) => `${JSON.stringify(entry.name)}: __values[${index}]`).join(", ")} };`
                : ""}
}`;
        };
        if (serverLoads.length > 0)
            out.push(renderLoads("__wrnexusLoad", serverLoads, serverLoads));
        if (publicClientLoads.length > 0)
            out.push(renderLoads("__wrnexusClientLoad", clientLoads, publicClientLoads));
    }
    if (ast.actions.length > 0) {
        for (const action of ast.actions) {
            if (!action.schema) {
                out.push(`export async function ${action.name}(${action.args.join(", ")}) {${action.body}}`);
                continue;
            }
            out.push(`export async function ${action.name}(input: InferSchema<typeof ${action.schema}>, ctx: import("@wrnexus/core").Context) {
  const invalidate = (...tags: string[]) => {
    const bucket = (ctx.locals.__wrnexusInvalidatedTags ??= []);
    bucket.push(...tags.flat());
  };
${action.body}
}`);
        }
        out.push(`export const __wrnexusActions = { ${ast.actions
            .map((action) => `${action.name}: { run: ${action.name}, schema: ${action.schema ?? "undefined"} }`)
            .join(", ")} };`);
        out.push(`export const __wrnexusActionClients = {
${ast.actions
            .map((action) => `  ${action.name}: createActionClient<${action.schema ? `InferSchema<typeof ${action.schema}>` : "Record<string, unknown>"}, Awaited<ReturnType<typeof ${action.name}>>>("", ${JSON.stringify(action.name)}),`)
            .join("\n")}
};`);
    }
    // --- API blocks -> method handlers ---
    if (ast.apis.length > 0) {
        ast.apis.forEach((api, index) => {
            const name = `__wrnexusApi_${api.method}_${index}`;
            out.push(`// ${api.method} ${apiRoutePath(api.path)}
const ${name} = async (ctx: import("@wrnexus/core").Context) => {${api.body}};`);
        });
        const entries = ast.apis.map((api, index) => `  ${JSON.stringify(`${api.method} ${apiRoutePath(api.path)}`)}: __wrnexusApi_${api.method}_${index},`);
        out.push(`export const __wrnexusApi = {\n${entries.join("\n")}\n};`);
        const exported = new Set();
        ast.apis.forEach((api, index) => {
            if (exported.has(api.method))
                return;
            exported.add(api.method);
            out.push(`export const ${api.method} = __wrnexusApi_${api.method}_${index};`);
        });
    }
    // --- Realtime blocks -> a websocket export ---
    if (ast.realtimes.length > 0) {
        const handlers = ast.realtimes.flatMap((rt) => rt.handlers.map((h) => {
            const params = ["ws", ...h.args].join(", ");
            return `  ${h.event}(${params}: Event) {${h.body}},`;
        }));
        out.push(`export const websocket = {\n${handlers.join("\n")}\n};`);
    }
    return out.join("\n\n") + "\n";
}
/** Parse a `data-for="item in list [key expr]"` / `"item, i in list [key expr]"` directive. */
function parseForExpr(value) {
    const m = /^\s*([A-Za-z_$][\w$]*)\s*(?:,\s*([A-Za-z_$][\w$]*)\s*)?\s+in\s+([\s\S]+?)(?:\s+key\s+([\s\S]+?))?\s*$/.exec(value);
    if (!m)
        return null;
    return { item: m[1], index: m[2], list: m[3].trim(), key: m[4]?.trim() };
}
/** The loop variables a node introduces via `data-for`, if any. */
function loopVarsOf(node) {
    if (node.type !== "element")
        return [];
    const attr = node.attrs.find((a) => !a.event && a.name === "data-for");
    if (!attr)
        return [];
    const parsed = parseForExpr(attr.value);
    return parsed ? [parsed.item, ...(parsed.index ? [parsed.index] : [])] : [];
}
/** JS reserved words that cannot be used as a plain `const` name. */
const JS_RESERVED = new Set([
    "class",
    "for",
    "default",
    "function",
    "return",
    "if",
    "else",
    "new",
    "delete",
    "typeof",
    "in",
    "instanceof",
    "void",
    "do",
    "while",
    "switch",
    "case",
    "break",
    "continue",
    "this",
    "super",
    "import",
    "export",
    "extends",
    "var",
    "let",
    "const",
    "null",
    "true",
    "false",
    "try",
    "catch",
    "finally",
    "throw",
    "yield",
    "await",
    "enum",
    "with",
    "debugger",
    "implements",
    "interface",
    "package",
    "private",
    "protected",
    "public",
    "static",
]);
/** A JS reference for a prop/state name (reserved words get a `__p_` prefix). */
function safeRef(name) {
    return JS_RESERVED.has(name) ? `__p_${name}` : name;
}
/** Escape a literal segment so it is safe inside a JS template literal. */
function escLit(s) {
    return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
}
function componentBehavior(ast) {
    const functions = (0, types_ts_1.eraseFunctionTypes)(targetFunctions(ast, "browser"));
    const computed = ast.computed.map((entry) => ({ name: entry.name, expr: entry.expr.trim() }));
    const effects = ast.effects.map((entry) => entry.body.trim()).filter(Boolean);
    const lifecycle = {
        ...(ast.lifecycle.mount?.trim() ? { mount: ast.lifecycle.mount.trim() } : {}),
        ...(ast.lifecycle.update?.trim() ? { update: ast.lifecycle.update.trim() } : {}),
        ...(ast.lifecycle.unmount?.trim() ? { unmount: ast.lifecycle.unmount.trim() } : {}),
    };
    const watches = ast.watches.map((watch) => ({
        state: watch.state,
        body: watch.body.trim(),
    }));
    if (!functions &&
        ast.outputs.length === 0 &&
        computed.length === 0 &&
        effects.length === 0 &&
        Object.keys(lifecycle).length === 0 &&
        watches.length === 0) {
        return null;
    }
    return {
        functions,
        outputs: ast.outputs,
        computed,
        effects,
        lifecycle,
        watches,
    };
}
function behaviorAttribute(behavior) {
    if (!behavior) {
        return "";
    }
    const encoded = node_buffer_1.Buffer.from(JSON.stringify(behavior), "utf8").toString("base64");
    return ` data-wrn-behavior="${encoded}"`;
}
const INTERP_RE = /\{([^{}]+)\}/g;
function exprRefsState(expr, stateNames) {
    for (const name of stateNames) {
        if (new RegExp(`\\b${name}\\b`).test(expr))
            return true;
    }
    return false;
}
function exprRefsComponentReactiveValue(expr, ctx) {
    return (exprRefsState(expr, ctx.stateNames) ||
        exprRefsState(expr, ctx.propNames) ||
        exprRefsState(expr, ctx.functionNames));
}
function viewHasEvents(nodes) {
    return nodes.some((node) => {
        if (node.type === "text")
            return false;
        if (node.type === "each") {
            return viewHasEvents(node.body) || viewHasEvents(node.empty);
        }
        if (node.type === "if") {
            return node.branches.some((branch) => viewHasEvents(branch.body));
        }
        return node.attrs.some((attr) => attr.event) || viewHasEvents(node.children);
    });
}
function viewHasServerEach(nodes) {
    return nodes.some((node) => {
        if (node.type === "text")
            return false;
        if (node.type === "each")
            return true;
        if (node.type === "if") {
            return node.branches.some((branch) => viewHasServerEach(branch.body));
        }
        return viewHasServerEach(node.children);
    });
}
function viewHasRestAttributeSpread(nodes) {
    return nodes.some((node) => {
        if (node.type === "text")
            return false;
        if (node.type === "each") {
            return viewHasRestAttributeSpread(node.body) || viewHasRestAttributeSpread(node.empty);
        }
        if (node.type === "if") {
            return node.branches.some((branch) => viewHasRestAttributeSpread(branch.body));
        }
        return (node.attrs.some((attr) => /^\{\.\.\.([A-Za-z_$][\w$]*)\}$/.test(attr.name)) ||
            viewHasRestAttributeSpread(node.children));
    });
}
/**
 * Compile a text node. Interpolations that reference state stay as client
 * mustaches (`{expr}`, hydrated by the reactive runtime); interpolations of
 * props/constants are baked server-side (`${__wireHtml(expr)}`), so static
 * components render correct HTML with zero JavaScript.
 */
function compileText(raw, ctx) {
    let out = "";
    let last = 0;
    let m;
    INTERP_RE.lastIndex = 0;
    while ((m = INTERP_RE.exec(raw))) {
        out += escLit(raw.slice(last, m.index));
        const expr = m[1].trim();
        if (expr.startsWith("t:")) {
            // i18n sugar: {t:key} → a marker resolved server-side by translateHtml.
            out += escLit(`<span data-t="${attrEscape(expr.slice(2).trim())}"></span>`);
        }
        else if (ctx.loopVars && exprRefsState(expr, ctx.loopVars)) {
            // Loop variable (from data-for): leave a literal client mustache — the
            // list renderer fills it per item; it has no server-side value.
            out += escLit(`{${expr}}`);
        }
        else if (expr === "content") {
            out += `\${__wireRaw(${ctx.resolveExpr(expr)})}`;
        }
        else if (exprRefsComponentReactiveValue(expr, ctx)) {
            // State interpolation: bake the initial value AND keep it reactive via a
            // data-text span, so no-JS clients see the real value and hydration
            // updates it in place. `count` → `<span data-text="count">0</span>`.
            out +=
                escLit(`<span data-text="${attrEscape(expr)}">`) +
                    `\${__wireHtml(${ctx.resolveExpr(expr)})}` +
                    escLit(`</span>`);
        }
        else {
            out += `\${__wireHtml(${ctx.resolveExpr(expr)})}`;
        }
        last = m.index + m[0].length;
    }
    return out + escLit(raw.slice(last));
}
/** Compile an attribute value; `{expr}` is baked server-side (loop vars stay literal). */
function compileAttrValue(raw, ctx) {
    if (!raw.includes("{"))
        return escLit(attrEscape(raw));
    let out = "";
    let last = 0;
    let m;
    INTERP_RE.lastIndex = 0;
    while ((m = INTERP_RE.exec(raw))) {
        out += escLit(attrEscape(raw.slice(last, m.index)));
        const expr = m[1].trim();
        if (ctx.loopVars && exprRefsState(expr, ctx.loopVars)) {
            out += escLit(`{${expr}}`); // hydrated per-item by the list renderer
        }
        else {
            out += `\${__wireAttr(${ctx.resolveExpr(expr)})}`;
        }
        last = m.index + m[0].length;
    }
    return out + escLit(attrEscape(raw.slice(last)));
}
function renderComponentIfNode(node, ctx) {
    let expression = "``";
    for (let index = node.branches.length - 1; index >= 0; index--) {
        const branch = node.branches[index];
        const body = branch.body.map((child) => renderComponentNode(child, ctx)).join("");
        const bodyExpression = "`" + body + "`";
        expression =
            branch.cond === null
                ? bodyExpression
                : `(${ctx.resolveExpr(branch.cond)}) ? ${bodyExpression} : ${expression}`;
    }
    return "${" + expression + "}";
}
function renderComponentEachNode(node, ctx) {
    const item = node.item;
    const index = node.index ?? "__wi";
    const list = ctx.resolveExpr(node.list);
    const childCtx = {
        ...ctx,
        serverLocals: new Set([...(ctx.serverLocals ?? []), item, index]),
    };
    const body = node.body.map((child) => renderComponentNode(child, childCtx)).join("");
    const empty = node.empty.map((child) => renderComponentNode(child, ctx)).join("");
    return ("${(() => { const __wl = Array.isArray(" +
        list +
        ") ? (" +
        list +
        ") : []; return __wl.length ? __wl.map((" +
        item +
        ", " +
        index +
        ") => `" +
        body +
        '`).join("") : `' +
        empty +
        "`; })()}");
}
function serverLoopLocalsAttribute(ctx) {
    const locals = [...(ctx.serverLocals ?? [])];
    if (locals.length === 0) {
        return "";
    }
    const entries = locals.map((name) => `${JSON.stringify(name)}: ${name}`).join(", ");
    return ` data-wrn-loop-locals="\${__wrnexusEncodeLoopLocals({ ${entries} })}"`;
}
function unwrapDirectiveExpression(raw) {
    const value = raw.trim();
    if (!value.startsWith("{") || !value.endsWith("}")) {
        return value;
    }
    let depth = 0;
    let quote = null;
    let escaped = false;
    for (let index = 0; index < value.length; index++) {
        const char = value[index];
        if (escaped) {
            escaped = false;
            continue;
        }
        if (quote) {
            if (char === "\\") {
                escaped = true;
            }
            else if (char === quote) {
                quote = null;
            }
            continue;
        }
        if (char === '"' || char === "'" || char === "`") {
            quote = char;
            continue;
        }
        if (char === "{")
            depth++;
        if (char === "}")
            depth--;
        if (depth === 0 && index < value.length - 1) {
            return value;
        }
    }
    return depth === 0 ? value.slice(1, -1).trim() : value;
}
/** Render a component view node into template-literal-ready source. */
function renderComponentNode(node, ctx) {
    if (node.type === "text")
        return compileText(node.value, ctx);
    if (node.type === "each") {
        return renderComponentEachNode(node, ctx);
    }
    if (node.type === "if") {
        return renderComponentIfNode(node, ctx);
    }
    if (node.tag === "Static" || node.tag === "Dynamic") {
        const inner = node.children.map((child) => renderComponentNode(child, ctx)).join("");
        return node.tag === "Static"
            ? inner
            : `<wrn-dynamic-region data-wrn-dynamic="true">${inner}</wrn-dynamic-region>`;
    }
    if (node.tag === "KeepAlive") {
        const key = node.attrs.find((attribute) => attribute.name === "key")?.value ?? "default";
        const inner = node.children.map((child) => renderComponentNode(child, ctx)).join("");
        return `<div data-wrn-keepalive="${compileAttrValue(key, ctx)}">${inner}</div>`;
    }
    if (node.tag === "Portal" || node.tag === "Transition" || node.tag === "Component") {
        const inner = node.children.map((child) => renderComponentNode(child, ctx)).join("");
        const attribute = node.tag === "Portal"
            ? "data-wrn-portal"
            : node.tag === "Transition"
                ? "data-wrn-transition"
                : "data-wrn-dynamic-component";
        const source = node.tag === "Portal" ? "to" : node.tag === "Transition" ? "name" : "is";
        const fallback = node.tag === "Portal" ? "body" : node.tag === "Transition" ? "wrn-transition" : "";
        const raw = node.attrs.find((item) => item.name === source)?.value ?? fallback;
        return `<div ${attribute}="${compileAttrValue(raw, ctx)}">${inner}</div>`;
    }
    if (isComponentTag(node.tag)) {
        return renderNestedComponentInvocation(node, ctx);
    }
    const loopVariables = loopVarsOf(node);
    const elementContext = {
        ...ctx,
        forwardRestAttrs: false,
        ...(loopVariables.length > 0
            ? { loopVars: new Set([...(ctx.loopVars ?? []), ...loopVariables]) }
            : {}),
    };
    let bindIndex = 0;
    const staticClasses = [];
    const conditionalClasses = [];
    for (const attr of node.attrs) {
        if (!attr.event && attr.name === "class") {
            staticClasses.push(attr.value);
        }
        if (!attr.event && attr.name.startsWith("class:")) {
            conditionalClasses.push({
                className: attr.name.slice("class:".length),
                expression: unwrapDirectiveExpression(attr.value),
            });
        }
    }
    const isExplicitComponentMount = node.attrs.some((attribute) => attribute.name === "data-component");
    const attrs = node.attrs
        .filter((a) => a.name !== "class" && !a.name.startsWith("class:"))
        .map((a) => {
        const spread = /^\{\.\.\.([A-Za-z_$][\w$]*)\}$/.exec(a.name);
        if (spread) {
            return `\${__wireSpreadAttrs(${elementContext.resolveExpr(spread[1])})}`;
        }
        if (a.event) {
            return ` ${eventAttribute(a.name)}="${escLit(attrEscape(a.value))}"`;
        }
        if (a.boolean) {
            return ` ${a.name}`;
        }
        if (isHtmlBooleanAttribute(a.name)) {
            const expression = wholeAttributeExpression(a.value);
            if (expression) {
                const referencesState = exprRefsComponentReactiveValue(a.value, ctx);
                const referencesLoopVariable = elementContext.loopVars
                    ? exprRefsState(a.value, elementContext.loopVars)
                    : false;
                const referencesServerLocal = ctx.serverLocals
                    ? exprRefsState(a.value, ctx.serverLocals)
                    : false;
                const marker = referencesState || referencesLoopVariable || referencesServerLocal
                    ? ` data-wrn-bind-${bindIndex++}="${escLit(attrEscape(JSON.stringify([a.name, a.value])))}"`
                    : "";
                /*
                 * A boolean attribute whose expression names a loop variable cannot
                 * be resolved on the server: __wireBooleanAttr runs at render time,
                 * where `row` or `item` simply does not exist, and the emitted
                 * module blew up. Leave the attribute off the server output and let
                 * the client bind set it -- the runtime toggles boolean attributes
                 * rather than stringifying them, so `checked={isSelected(row)}`
                 * behaves correctly once hydrated.
                 */
                if (referencesLoopVariable) {
                    return ` data-wrn-bind-${bindIndex++}="${escLit(attrEscape(JSON.stringify([a.name, a.value])))}"`;
                }
                return `\${__wireBooleanAttr(${JSON.stringify(a.name)}, ${elementContext.resolveExpr(expression)})}${marker}`;
            }
            if (a.value === "false")
                return "";
            if (a.value === "true" || a.value === "")
                return ` ${a.name}`;
        }
        const wholeExpression = wholeAttributeExpression(a.value);
        /*
         * data-show carries an EXPRESSION, not a value. The client re-evaluates
         * whatever string it finds in the attribute on every state change, so
         * interpolating `{open || visible}` down to the literal "false" at
         * render time froze the directive: the element could never be shown
         * again, no matter what the state did. A data-wrn-bind marker did not
         * save it either -- the bind rewrites the same attribute the directive
         * reads, and the directive had already captured "false" as its
         * expression. Emitting the expression verbatim (the form Modal uses,
         * data-show="isOpen()") makes both authoring styles behave the same.
         */
        if (a.name === "data-show" && wholeExpression) {
            return ` data-show="${escLit(attrEscape(wholeExpression))}"`;
        }
        const compiledValue = isExplicitComponentMount && wholeExpression
            ? `\${__wireProp(${elementContext.resolveExpr(wholeExpression)})}`
            : compileAttrValue(a.value, elementContext);
        const rendered = ` ${a.name}="${compiledValue}"`;
        const referencesState = exprRefsComponentReactiveValue(a.value, ctx);
        const referencesLoopVariable = elementContext.loopVars
            ? exprRefsState(a.value, elementContext.loopVars)
            : false;
        const referencesServerLocal = ctx.serverLocals
            ? exprRefsState(a.value, ctx.serverLocals)
            : false;
        if (!a.value.includes("{") ||
            (!referencesState && !referencesLoopVariable && !referencesServerLocal)) {
            return rendered;
        }
        const marker = attrEscape(JSON.stringify([a.name, a.value]));
        return `${rendered} data-wrn-bind-${bindIndex++}="${escLit(marker)}"`;
    })
        .join("");
    const initialConditionalClasses = conditionalClasses
        .map(({ className, expression }) => {
        const referencesLoopVariable = elementContext.loopVars
            ? exprRefsState(expression, elementContext.loopVars)
            : false;
        // data-for variables do not exist during
        // initial server rendering.
        if (referencesLoopVariable) {
            return "";
        }
        return `\${(${ctx.resolveExpr(expression)}) ? ${JSON.stringify(` ${className}`)} : ""}`;
    })
        .join("");
    const staticClassValue = staticClasses.join(" ");
    const classReferencesState = exprRefsComponentReactiveValue(staticClassValue, ctx);
    const classReferencesLoopVariable = elementContext.loopVars
        ? exprRefsState(staticClassValue, elementContext.loopVars)
        : false;
    const classReferencesServerLocal = ctx.serverLocals
        ? exprRefsState(staticClassValue, ctx.serverLocals)
        : false;
    const classHasReactiveExpression = staticClassValue.includes("{") &&
        (classReferencesState || classReferencesLoopVariable || classReferencesServerLocal);
    const classAttribute = staticClasses.length > 0 || conditionalClasses.length > 0
        ? ` class="${compileAttrValue(staticClassValue, elementContext)}${initialConditionalClasses}"`
        : "";
    const classReactiveBinding = classHasReactiveExpression
        ? ` data-wrn-bind-class="${escLit(attrEscape(JSON.stringify(["class", staticClassValue])))}"`
        : "";
    const classBindings = conditionalClasses
        .map(({ className, expression }, index) => {
        const marker = attrEscape(JSON.stringify([className, expression]));
        return ` data-wrn-class-${index}="${escLit(marker)}"`;
    })
        .join("");
    const loopLocalsAttribute = serverLoopLocalsAttribute(ctx);
    const allAttrs = `${loopLocalsAttribute}` +
        `${ctx.forwardRestAttrs ? "${__wireSpreadAttrs(__attrs)}" : ""}` +
        `${ctx.eventNames?.length ? ` data-wrn-events="${attrEscape(ctx.eventNames.join(","))}"` : ""}` +
        `${classAttribute}` +
        `${classReactiveBinding}` +
        `${classBindings}` +
        `${attrs}`;
    if (parser_ts_1.VOID_ELEMENTS.has(node.tag.toLowerCase())) {
        return `<${node.tag}${allAttrs}>`;
    }
    const inner = node.children.map((child) => renderComponentNode(child, elementContext)).join("");
    return `<${node.tag}${allAttrs}>${inner}</${node.tag}>`;
}
function generateComponent(ast) {
    const out = [];
    if (ast.imports.length > 0)
        out.push(generatedImports(ast).join("\n"));
    const hasServerEach = viewHasServerEach(ast.view);
    const effectiveProps = ast.kind === "layout" && !ast.props.some((prop) => prop.name === "content")
        ? [
            {
                name: "content",
                default: '""',
                valueType: "string",
                required: false,
            },
            ...ast.props,
        ]
        : ast.props;
    const browserStates = ast.states.filter((state) => state.runtime !== "server");
    const stateNames = new Set([
        ...browserStates.map((entry) => entry.name),
        ...ast.computed.map((entry) => entry.name),
    ]);
    const nameRefs = new Map();
    for (const p of effectiveProps) {
        nameRefs.set(p.name, safeRef(p.name));
    }
    if (!nameRefs.has("attrs")) {
        nameRefs.set("attrs", "__attrs");
    }
    for (const s of ast.states)
        nameRefs.set(s.name, safeRef(s.name));
    for (const entry of ast.computed)
        nameRefs.set(entry.name, safeRef(entry.name));
    const resolveExpr = (expr) => {
        let result = expr;
        for (const [name, ref] of nameRefs) {
            if (name !== ref)
                result = result.replace(new RegExp(`\\b${name}\\b`, "g"), ref);
        }
        return result;
    };
    const ctx = {
        stateNames,
        propNames: new Set(effectiveProps.map((entry) => entry.name)),
        functionNames: new Set(ast.runtimeFunctions.filter((fn) => fn.runtime !== "server").map((fn) => fn.name)),
        resolveExpr,
        eventNames: publicOutputNames(ast),
    };
    const serverFunctions = targetFunctions(ast, "server");
    const hasExplicitRestSpread = viewHasRestAttributeSpread(ast.view);
    const rootElementIndex = ast.view.findIndex((node) => node.type === "element");
    const automaticallyForwardRootAttrs = !hasExplicitRestSpread &&
        !effectiveProps.some((prop) => prop.name === "attrs") &&
        rootElementIndex >= 0;
    const viewCode = ast.view
        .map((node, index) => renderComponentNode(node, automaticallyForwardRootAttrs && index === rootElementIndex
        ? { ...ctx, forwardRestAttrs: true }
        : ctx))
        .join("");
    const styles = ast.styles.map((body) => body.trim()).filter(Boolean);
    const styleTag = escLit(localStyleTag(ast, styles));
    // Props remain server-rendered and also become signals so a parent can drive
    // a mounted child after hydration.
    const behavior = componentBehavior(ast);
    const needsScope = ast.runtime !== "server" &&
        (effectiveProps.length > 0 ||
            browserStates.length > 0 ||
            ast.computed.length > 0 ||
            viewHasEvents(ast.view) ||
            behavior !== null);
    if (hasServerEach || needsScope) {
        out.push(`import { Buffer as __WrnexusBuffer } from "node:buffer";`);
    }
    const scopeKeys = [
        ...effectiveProps.map((prop) => prop.name),
        ...browserStates.map((state) => state.name),
    ];
    const behaviorAttr = behaviorAttribute(behavior);
    const decls = [];
    for (const prop of effectiveProps) {
        if (prop.required) {
            decls.push(`  if (__p[${JSON.stringify(prop.name)}] === undefined) throw new TypeError(${JSON.stringify(`${ast.name} requires prop '${prop.name}' (${prop.valueType ?? "unknown"})`)});`);
        }
        decls.push(`  const ${nameRefs.get(prop.name)}: ${prop.valueType ?? "unknown"} = __coerce(__p[${JSON.stringify(prop.name)}], (${resolveExpr(prop.default)}), ${JSON.stringify((0, types_ts_1.runtimeTypeOf)(prop.valueType))}, ${JSON.stringify(prop.name)}) as ${prop.valueType ?? "unknown"};`);
    }
    if (!effectiveProps.some((prop) => prop.name === "attrs")) {
        decls.push(`  const __attrs = __restProps(__p, new Set(${JSON.stringify(effectiveProps.map((prop) => prop.name))}));`);
    }
    for (const state of ast.states) {
        decls.push(`  let ${nameRefs.get(state.name)}${state.valueType ? `: ${state.valueType}` : ""} = (${resolveExpr(state.expr)});`);
    }
    for (const entry of ast.computed) {
        decls.push(`  const ${nameRefs.get(entry.name)} = (${resolveExpr(entry.expr)});`);
    }
    const returnExpr = needsScope
        ? "`" +
            styleTag +
            `<div data-scope="\${__scope}" data-wrn-scope="\${__scopePayload}"${behaviorAttr}${hydrationAttribute(ast)}>` +
            viewCode +
            "</div>`"
        : "`" + styleTag + viewCode + "`";
    const scopeLine = needsScope && scopeKeys.length > 0
        ? `  const __scopeState = { ${scopeKeys
            .map((key) => `${JSON.stringify(key)}: ${nameRefs.get(key)}`)
            .join(", ")} };\n  const __scope = __wrnexusScopeDecl(__scopeState);\n  const __scopePayload = __WrnexusBuffer.from(JSON.stringify(__scopeState), "utf8").toString("base64");\n`
        : needsScope
            ? `  const __scopeState = {};\n  const __scope = "";\n  const __scopePayload = __WrnexusBuffer.from("{}", "utf8").toString("base64");\n`
            : "";
    if (ast.kind === "layout") {
        out.push(`export const __wrnexusLayout = ${JSON.stringify(ast.name)};`);
    }
    else {
        out.push(`export const __wrnexusComponent = ${JSON.stringify(ast.name)};`);
    }
    out.push(`export const __wrnexusRuntime = ${JSON.stringify(ast.runtime ?? "universal")};`);
    out.push(`export const __wrnexusRender = ${JSON.stringify(ast.renderMode ?? "hybrid")};`);
    out.push(`export const __wrnexusHydrate = ${JSON.stringify(["static", "server"].includes(ast.renderMode ?? "") ? "none" : (ast.hydrate ?? "load"))};`);
    out.push(`export const __wrnexusHydrationId = ${JSON.stringify(hydrationId(ast))};`);
    if (Object.keys(ast.cache ?? {}).length > 0)
        out.push(`export const __wrnexusCache = ${JSON.stringify(ast.cache, null, 2)};`);
    if (Object.keys(ast.security).length > 0) {
        out.push(`export const __wrnexusSecurity = ${JSON.stringify(ast.security, null, 2)};`);
    }
    if (Object.keys(ast.navigation).length > 0) {
        out.push(`export const __wrnexusNavigation = ${JSON.stringify(ast.navigation, null, 2)};`);
    }
    const componentStyleExport = localStyleExport(ast, styles);
    if (componentStyleExport)
        out.push(componentStyleExport);
    if (behavior) {
        out.push(`export const __wrnexusBehavior = ${JSON.stringify(behavior, null, 2)};`);
    }
    const typeSource = ast.types
        .map((body) => body.trim())
        .filter(Boolean)
        .join("\n\n");
    if (typeSource)
        out.push(typeSource);
    if (effectiveProps.length > 0) {
        out.push(`export interface ${ast.name}Props {\n  [attribute: string]: unknown;\n${effectiveProps
            .map((prop) => `  ${JSON.stringify(prop.name)}${prop.required ? "" : "?"}: ${prop.valueType ?? "unknown"};`)
            .join("\n")}\n}`);
    }
    if (ast.outputs.length > 0) {
        out.push(`export interface ${ast.name}Outputs {\n${ast.outputs
            .map((output) => `  ${JSON.stringify(output.name)}(${output.payload ? `${output.payload.name}${output.payload.optional ? "?" : ""}: ${output.payload.valueType}` : ""}): void;`)
            .join("\n")}\n}`);
    }
    out.push(`function __coerce(v: unknown, def: unknown, declared: string = "unknown", propName: string = "prop"): unknown {
  if (v === undefined || v === null) {
    return def;
  }

  if (declared === "number" || typeof def === "number") {
    const parsed = Number(v);
    if (!Number.isFinite(parsed)) throw new TypeError("Expected a finite number prop");
    return parsed;
  }

  if (declared === "boolean" || typeof def === "boolean") {
    if (v === true || v === "" || v === "true" || v === 1 || v === "1") return true;
    if (v === false || v === "false" || v === 0 || v === "0") return false;
    throw new TypeError("Expected a boolean prop");
  }

  if (declared === "array" || Array.isArray(def)) {
    if (Array.isArray(v)) {
      return v;
    }

    if (typeof v === "string") {
      try {
        const parsed = JSON.parse(v);
        if (!Array.isArray(parsed)) throw new TypeError("Expected an array prop '" + propName + "'");
        return parsed;
      } catch {
        throw new TypeError("Expected an array prop '" + propName + "'");
      }
    }

    throw new TypeError("Expected an array prop '" + propName + "'");
  }

  if (declared === "object" || (def !== null && typeof def === "object")) {
    if (
      v !== null &&
      typeof v === "object" &&
      !Array.isArray(v)
    ) {
      return v;
    }

    if (typeof v === "string") {
      try {
        const parsed = JSON.parse(v);

        if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
          throw new TypeError("Expected an object prop '" + propName + "'");
        }
        return parsed;
      } catch {
        throw new TypeError("Expected an object prop '" + propName + "'");
      }
    }

    throw new TypeError("Expected an object prop '" + propName + "'");
  }

  if (declared === "bigint") return BigInt(v as string | number | bigint | boolean);
  if (declared === "function" && typeof v !== "function") {
    throw new TypeError("Expected a function prop");
  }
  return declared === "unknown" && def === undefined ? v : String(v);
}

function __restProps(
  props: Record<string, unknown>,
  declared: Set<string>,
): Record<string, unknown> {
  return Object.fromEntries(
    Object.entries(props).filter(([name]) => !declared.has(name)),
  );
}

function __wireHtml(v: unknown): string {
  return String(v == null ? "" : v).replace(
    /[&<>]/g,
    (c) =>
      c === "&"
        ? "&amp;"
        : c === "<"
          ? "&lt;"
          : "&gt;",
  );
}

function __wireAttr(v: unknown): string {
  return String(v == null ? "" : v).replace(
    /[&<>"]/g,
    (c) =>
      c === "&"
        ? "&amp;"
        : c === "<"
          ? "&lt;"
          : c === ">"
            ? "&gt;"
            : "&quot;",
  );
}

function __wireBooleanAttr(name: string, value: unknown): string {
  return value === true ||
    value === "true" ||
    value === "" ||
    value === 1 ||
    value === "1" ||
    value === name
    ? " " + name
    : "";
}

function __wireSpreadAttrs(value: unknown): string {
  if (value === null || typeof value !== "object" || Array.isArray(value)) return "";

  const booleanAttributes = new Set(${JSON.stringify([...HTML_BOOLEAN_ATTRIBUTES])});
  const attributes: string[] = [];

  for (const [name, raw] of Object.entries(value)) {
    const lowerName = name.toLowerCase();
    if (
      !/^[A-Za-z_:][A-Za-z0-9_.:-]*$/.test(name) ||
      lowerName.startsWith("on") ||
      lowerName === "style" ||
      lowerName === "slot" ||
      lowerName === "data-component" ||
      // Internal markers must not leak through a spread. Parent-owned output
      // and prop bindings ride from the mount onto the
      // rendered child root so the mounting scope can bind them there.
      (lowerName.startsWith("data-wrn") &&
        !lowerName.startsWith("data-wrn-out-") &&
        !lowerName.startsWith("data-wrn-prop-bind-"))
    ) {
      continue;
    }

    if (booleanAttributes.has(lowerName)) {
      attributes.push(__wireBooleanAttr(name, raw));
      continue;
    }

    if (raw === false || raw === null || raw === undefined) continue;
    attributes.push(" " + name + '="' + __wireAttr(raw) + '"');
  }

  return attributes.join("");
}

function __wireProp(v: unknown): string {
  const value =
    v !== null && typeof v === "object"
      ? JSON.stringify(v)
      : String(v == null ? "" : v);

  return __wireAttr(value);
}

function __wireRaw(v: unknown): string {
  return String(v == null ? "" : v);
}`);
    if (hasServerEach) {
        out.push(`function __wrnexusEncodeLoopLocals(value: Record<string, unknown>): string {
  return __WrnexusBuffer.from(JSON.stringify(value), "utf8").toString("base64");
}`);
    }
    if (needsScope) {
        out.push(`function __wrnexusSerializeScopeValue(value: unknown): string {
    if (value === undefined) {
      return "undefined";
    }

    if (value === null) {
      return "null";
    }

    if (typeof value === "number") {
      return Number.isFinite(value)
        ? String(value)
        : "null";
    }

    if (typeof value === "boolean") {
      return value ? "true" : "false";
    }

    if (typeof value === "string") {
      return JSON.stringify(value);
    }

    try {
      const serialized = JSON.stringify(value);

      return serialized === undefined
        ? "undefined"
        : serialized;
    } catch {
      return "null";
    }
  }

  function __wrnexusScopeDecl(obj: Record<string, unknown>): string {
    return Object.keys(obj)
      .map(
        (key) =>
          key +
          ": " +
          __wrnexusSerializeScopeValue(
            obj[key],
          ),
      )
      .join(", ")
      .replace(/&/g, "&amp;")
      .replace(/"/g, "&quot;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;");
  }`);
    }
    const serverFunctionSource = serverFunctions ? `${serverFunctions}\n` : "";
    out.push(`export function render(props: ${effectiveProps.length > 0 ? `${ast.name}Props` : "Record<string, unknown>"} = {} as ${effectiveProps.length > 0 ? `${ast.name}Props` : "Record<string, unknown>"}): string {\n` +
        `  const __p = props || {};\n` +
        (decls.length > 0 ? decls.join("\n") + "\n" : "") +
        serverFunctionSource +
        scopeLine +
        `  return ${returnExpr};\n` +
        `}`);
    out.push(`export default { name: ${JSON.stringify(ast.name)}, kind: ${JSON.stringify(ast.kind)}, render };`);
    return out.join("\n\n") + "\n";
}
function __wireRaw(v) {
    return String(v == null ? "" : v);
}
function wholeAttributeExpression(value) {
    const match = /^\s*\{([\s\S]+)\}\s*$/.exec(value);
    return match?.[1]?.trim() || null;
}
function __wireHtml(v) {
    return String(v == null ? "" : v).replace(/[&<>]/g, (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&gt;");
}
function __wireAttr(v) {
    return String(v == null ? "" : v).replace(/[&<>"]/g, (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : c === ">" ? "&gt;" : "&quot;");
}
function __wireProp(v) {
    const value = v !== null && typeof v === "object" ? JSON.stringify(v) : String(v == null ? "" : v);
    return __wireAttr(value);
}
function renderPageComponentAttr(attr, dynamicExpressions) {
    if (attr.event) {
        return ` ${componentEventAttribute(attr.name)}="${attrEscape(attr.value)}"`;
    }
    if (attr.boolean) {
        return ` ${attr.name}`;
    }
    const expression = wholeAttributeExpression(attr.value);
    if (!expression) {
        return ` ${attr.name}="${attrEscape(safeAttributeValue(attr.name, attr.value))}"`;
    }
    dynamicExpressions.push(`\${__wrnexusPropAttr(${expression})}`);
    const marker = `\x00WRNEACH${dynamicExpressions.length - 1}\x00`;
    return ` ${attr.name}="${marker}"`;
}

},
"packages/compiler/src/component-contract.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createComponentContract = createComponentContract;
function unionOptions(type) {
    if (!type || !type.includes("|"))
        return undefined;
    const values = type
        .split("|")
        .map((part) => part.trim())
        .filter((part) => /^(?:"[^"]*"|'[^']*')$/.test(part))
        .map((part) => part.slice(1, -1));
    return values.length ? values : undefined;
}
function createComponentContract(ast) {
    return {
        name: ast.name,
        kind: ast.kind,
        props: ast.props.map((prop) => ({
            name: prop.name,
            type: prop.valueType ?? "unknown",
            required: prop.required,
            ...(prop.default !== "undefined" ? { default: prop.default } : {}),
            ...(unionOptions(prop.valueType) ? { options: unionOptions(prop.valueType) } : {}),
        })),
        outputs: ast.outputs.map((output) => ({
            name: output.name,
            ...(output.payload
                ? { payloadName: output.payload.name, payloadType: output.payload.valueType }
                : {}),
        })),
        functions: ast.runtimeFunctions.map((fn) => ({
            name: fn.name,
            runtime: fn.runtime,
            async: fn.async,
            parameters: fn.parameters.map((param) => ({
                name: param.name,
                type: param.valueType ?? "unknown",
                optional: param.optional,
            })),
            returnType: fn.returnType ?? (fn.async ? "Promise<unknown>" : "unknown"),
        })),
        states: ast.states.map((state) => ({
            name: state.name,
            runtime: state.runtime,
            type: state.valueType ?? "unknown",
            initializer: state.expr,
        })),
        computed: ast.computed.map((entry) => ({
            name: entry.name,
            type: entry.valueType ?? "unknown",
            expression: entry.expr,
        })),
        imports: ast.structuredImports.map((entry) => ({
            source: entry.source,
            typeOnly: entry.typeOnly,
            ...(entry.defaultImport ? { defaultImport: entry.defaultImport } : {}),
            namedImports: entry.namedImports.map((named) => named.local),
        })),
    };
}

},
"packages/compiler/src/import-resolver.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveWrnImport = resolveWrnImport;
exports.resolveWrnImports = resolveWrnImports;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
function candidates(path) {
    return (0, node_path_1.extname)(path)
        ? [path]
        : [
            path,
            `${path}.wrn`,
            `${path}.ts`,
            `${path}.d.ts`,
            (0, node_path_1.join)(path, "index.wrn"),
            (0, node_path_1.join)(path, "index.ts"),
        ];
}
function resolveWrnImport(declaration, importer, options) {
    const source = declaration.source;
    const aliases = {
        "@": "./app",
        ...(options.aliases ?? {}),
    };
    const alias = Object.keys(aliases)
        .filter((key) => key.length > 0 && (source === key || source.startsWith(`${key}/`)))
        .sort((left, right) => right.length - left.length)[0];
    if (!source.startsWith(".") && !alias)
        return { declaration, resolved: source };
    const base = alias
        ? (0, node_path_1.resolve)(options.appRoot, aliases[alias], source === alias ? "" : source.slice(alias.length + 1))
        : (0, node_path_1.resolve)((0, node_path_1.dirname)(importer), source);
    const found = candidates(base).find((candidate) => {
        if (!(0, node_fs_1.existsSync)(candidate))
            return false;
        try {
            return (0, node_fs_1.statSync)(candidate).isFile();
        }
        catch {
            return false;
        }
    });
    if (found)
        return { declaration, resolved: (0, node_fs_1.realpathSync)(found) };
    const severity = (options.mode ?? "compatible") === "explicit" ? "error" : "warning";
    return {
        declaration,
        diagnostic: {
            code: "WRN-IMPORT-NOT-FOUND",
            message: `Cannot resolve import '${source}' from ${importer}`,
            severity,
        },
    };
}
function resolveWrnImports(declarations, importer, options) {
    return declarations.map((declaration) => resolveWrnImport(declaration, importer, options));
}

},
"packages/compiler/src/index.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
/**
 * @wrnexus/compiler — the `.wrn` language compiler.
 *
 * Parsing and language diagnostics are provided by the canonical
 * `@wrnexus/syntax` package. This package owns platform-specific codegen.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.DependencyGraph = exports.createCompilationCache = exports.compilationKey = exports.runtimeTypeOf = exports.inferredRuntimeType = exports.eraseFunctionTypes = exports.LexError = exports.Lexer = exports.NativeCompileError = exports.generateNative = exports.runtimeCapabilities = exports.analyzeRuntimeImports = exports.optimizeAst = exports.analyzeRuntimeRequirements = exports.analyzeOptimizations = exports.createWrnSourceMap = exports.resolveWrnImports = exports.resolveWrnImport = exports.createComponentContract = exports.generateStoreModule = exports.generateStoreBrowserModule = exports.generateDeclarations = exports.rpcManifest = exports.generateServerFunctionsModule = exports.generateBrowserModule = exports.generateTargets = exports.generate = exports.ParseError = exports.parse = exports.formatDiagnostic = exports.diagnosticFromError = exports.diagnose = exports.assertValidAst = exports.formatWrn = void 0;
exports.compileNativeWireFile = compileNativeWireFile;
exports.compileWireFile = compileWireFile;
exports.compile = compile;
const syntax_1 = require("@wrnexus/syntax");
var syntax_2 = require("@wrnexus/syntax");
Object.defineProperty(exports, "formatWrn", { enumerable: true, get: function () { return syntax_2.formatWrn; } });
const codegen_ts_1 = require("./codegen.js");
const native_codegen_ts_1 = require("./native-codegen.js");
var syntax_3 = require("@wrnexus/syntax");
Object.defineProperty(exports, "assertValidAst", { enumerable: true, get: function () { return syntax_3.assertValidAst; } });
Object.defineProperty(exports, "diagnose", { enumerable: true, get: function () { return syntax_3.diagnose; } });
Object.defineProperty(exports, "diagnosticFromError", { enumerable: true, get: function () { return syntax_3.diagnosticFromError; } });
Object.defineProperty(exports, "formatDiagnostic", { enumerable: true, get: function () { return syntax_3.formatDiagnostic; } });
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return syntax_3.parse; } });
Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return syntax_3.ParseError; } });
var codegen_ts_2 = require("./codegen.js");
Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return codegen_ts_2.generate; } });
var targets_ts_1 = require("./targets.js");
Object.defineProperty(exports, "generateTargets", { enumerable: true, get: function () { return targets_ts_1.generateTargets; } });
var client_codegen_ts_1 = require("./client-codegen.js");
Object.defineProperty(exports, "generateBrowserModule", { enumerable: true, get: function () { return client_codegen_ts_1.generateBrowserModule; } });
var server_codegen_ts_1 = require("./server-codegen.js");
Object.defineProperty(exports, "generateServerFunctionsModule", { enumerable: true, get: function () { return server_codegen_ts_1.generateServerFunctionsModule; } });
Object.defineProperty(exports, "rpcManifest", { enumerable: true, get: function () { return server_codegen_ts_1.rpcManifest; } });
var type_codegen_ts_1 = require("./type-codegen.js");
Object.defineProperty(exports, "generateDeclarations", { enumerable: true, get: function () { return type_codegen_ts_1.generateDeclarations; } });
var store_codegen_ts_1 = require("./store-codegen.js");
Object.defineProperty(exports, "generateStoreBrowserModule", { enumerable: true, get: function () { return store_codegen_ts_1.generateStoreBrowserModule; } });
Object.defineProperty(exports, "generateStoreModule", { enumerable: true, get: function () { return store_codegen_ts_1.generateStoreModule; } });
var component_contract_ts_1 = require("./component-contract.js");
Object.defineProperty(exports, "createComponentContract", { enumerable: true, get: function () { return component_contract_ts_1.createComponentContract; } });
var import_resolver_ts_1 = require("./import-resolver.js");
Object.defineProperty(exports, "resolveWrnImport", { enumerable: true, get: function () { return import_resolver_ts_1.resolveWrnImport; } });
Object.defineProperty(exports, "resolveWrnImports", { enumerable: true, get: function () { return import_resolver_ts_1.resolveWrnImports; } });
var source_map_ts_1 = require("./source-map.js");
Object.defineProperty(exports, "createWrnSourceMap", { enumerable: true, get: function () { return source_map_ts_1.createWrnSourceMap; } });
var analysis_ts_1 = require("./analysis.js");
Object.defineProperty(exports, "analyzeOptimizations", { enumerable: true, get: function () { return analysis_ts_1.analyzeOptimizations; } });
Object.defineProperty(exports, "analyzeRuntimeRequirements", { enumerable: true, get: function () { return analysis_ts_1.analyzeRuntimeRequirements; } });
Object.defineProperty(exports, "optimizeAst", { enumerable: true, get: function () { return analysis_ts_1.optimizeAst; } });
var runtime_capabilities_ts_1 = require("./runtime-capabilities.js");
Object.defineProperty(exports, "analyzeRuntimeImports", { enumerable: true, get: function () { return runtime_capabilities_ts_1.analyzeRuntimeImports; } });
Object.defineProperty(exports, "runtimeCapabilities", { enumerable: true, get: function () { return runtime_capabilities_ts_1.runtimeCapabilities; } });
var native_codegen_ts_2 = require("./native-codegen.js");
Object.defineProperty(exports, "generateNative", { enumerable: true, get: function () { return native_codegen_ts_2.generateNative; } });
Object.defineProperty(exports, "NativeCompileError", { enumerable: true, get: function () { return native_codegen_ts_2.NativeCompileError; } });
var syntax_4 = require("@wrnexus/syntax");
Object.defineProperty(exports, "Lexer", { enumerable: true, get: function () { return syntax_4.Lexer; } });
Object.defineProperty(exports, "LexError", { enumerable: true, get: function () { return syntax_4.LexError; } });
var syntax_5 = require("@wrnexus/syntax");
Object.defineProperty(exports, "eraseFunctionTypes", { enumerable: true, get: function () { return syntax_5.eraseFunctionTypes; } });
Object.defineProperty(exports, "inferredRuntimeType", { enumerable: true, get: function () { return syntax_5.inferredRuntimeType; } });
Object.defineProperty(exports, "runtimeTypeOf", { enumerable: true, get: function () { return syntax_5.runtimeTypeOf; } });
/** Compile `.wrn` source into an Expo Router React Native screen. */
function compileNativeWireFile(source) {
    const ast = (0, syntax_1.parse)(source);
    (0, syntax_1.assertValidAst)(ast);
    return (0, native_codegen_ts_1.generateNative)(ast);
}
/**
 * Compile `.wrn` source into TypeScript source. Errors include a stable code,
 * source location, code frame, and actionable hint whenever available.
 */
function compileWireFile(source, filePath = "<inline .wrn>") {
    try {
        const ast = (0, syntax_1.parse)(source);
        (0, syntax_1.assertValidAst)(ast, { file: filePath, accessibility: true });
        return `// compiled from .wrn\n${(0, codegen_ts_1.generate)(ast)}`;
    }
    catch (error) {
        const diagnostic = (0, syntax_1.diagnosticFromError)(source, error, { file: filePath });
        throw new Error(`Failed to parse ${filePath}:\n\n${(0, syntax_1.formatDiagnostic)(source, diagnostic)}`, {
            cause: error,
        });
    }
}
/** Richer entry point returning the AST and structured diagnostics. */
function compile(source, filePath = "<inline .wrn>") {
    const richDiagnostics = (0, syntax_1.diagnose)(source, { file: filePath, accessibility: true });
    const errors = richDiagnostics.filter((diagnostic) => diagnostic.severity === "error");
    if (errors.length > 0) {
        throw new syntax_1.ParseError(errors.map((diagnostic) => diagnostic.message).join("\n"), errors[0].code);
    }
    const ast = (0, syntax_1.parse)(source);
    return {
        code: `// compiled from .wrn\n${(0, codegen_ts_1.generate)(ast)}`,
        ast,
        diagnostics: richDiagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`),
        richDiagnostics,
    };
}
var cache_ts_1 = require("./cache.js");
Object.defineProperty(exports, "compilationKey", { enumerable: true, get: function () { return cache_ts_1.compilationKey; } });
Object.defineProperty(exports, "createCompilationCache", { enumerable: true, get: function () { return cache_ts_1.createCompilationCache; } });
Object.defineProperty(exports, "DependencyGraph", { enumerable: true, get: function () { return cache_ts_1.DependencyGraph; } });

},
"packages/compiler/src/native-codegen.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NativeCompileError = void 0;
exports.generateNative = generateNative;
class NativeCompileError extends Error {
    constructor(message) {
        super(message);
        this.name = "NativeCompileError";
    }
}
exports.NativeCompileError = NativeCompileError;
const tagMap = {
    div: "View",
    main: "View",
    section: "View",
    article: "View",
    nav: "View",
    header: "View",
    footer: "View",
    aside: "View",
    form: "View",
    ul: "View",
    ol: "View",
    li: "View",
    p: "Text",
    span: "Text",
    strong: "Text",
    em: "Text",
    small: "Text",
    label: "Text",
    h1: "Text",
    h2: "Text",
    h3: "Text",
    h4: "Text",
    h5: "Text",
    h6: "Text",
    button: "Pressable",
    a: "Pressable",
    input: "TextInput",
    textarea: "TextInput",
    img: "Image",
    view: "View",
    text: "Text",
    pressable: "Pressable",
    textinput: "TextInput",
    image: "Image",
    scrollview: "ScrollView",
    safeareaview: "SafeAreaView",
    flatlist: "FlatList",
    activityindicator: "ActivityIndicator",
};
const attrMap = {
    class: "style",
    className: "style",
    src: "source",
    alt: "accessibilityLabel",
    placeholder: "placeholder",
    disabled: "disabled",
    value: "value",
    href: "__href",
    "aria-label": "accessibilityLabel",
};
function expression(value) {
    const exact = /^\{([\s\S]+)\}$/.exec(value.trim());
    return exact?.[1]?.trim() ?? null;
}
function textJsx(value) {
    const pieces = [];
    let last = 0;
    for (const match of value.matchAll(/\{([^{}]+)\}/g)) {
        if (match.index > last)
            pieces.push(value.slice(last, match.index));
        const expr = match[1].trim();
        pieces.push(expr.startsWith("t:") ? `{${JSON.stringify(expr.slice(2).trim())}}` : `{${expr}}`);
        last = match.index + match[0].length;
    }
    pieces.push(value.slice(last));
    return pieces.join("").replace(/([<>])/g, (char) => (char === "<" ? "&lt;" : "&gt;"));
}
function eventBody(value, states) {
    let body = expression(value) ?? value;
    for (const state of states) {
        const cap = state[0].toUpperCase() + state.slice(1);
        body = body
            .replace(new RegExp(`\\b${state}\\+\\+`, "g"), `set${cap}(value => value + 1)`)
            .replace(new RegExp(`\\b${state}--`, "g"), `set${cap}(value => value - 1)`)
            .replace(new RegExp(`\\b${state}\\s*=\\s*([^;]+)`, "g"), `set${cap}($1)`);
    }
    return `() => { ${body} }`;
}
function renderAttrs(attrs, states) {
    return attrs
        .map((attr) => {
        if (attr.event) {
            if (attr.name.startsWith("browser-"))
                return "";
            const eventName = attr.name.startsWith("mobile-") ? attr.name.slice(7) : attr.name;
            const event = eventName === "click" || eventName === "press"
                ? "onPress"
                : eventName === "input" || eventName === "change"
                    ? "onChangeText"
                    : `on${eventName[0].toUpperCase()}${eventName.slice(1)}`;
            return ` ${event}={${eventBody(attr.value, states)}}`;
        }
        if (attr.name === "data-native-browser" || attr.name.startsWith("data-native-on-browser-"))
            return "";
        if (attr.name === "data-native-options" ||
            attr.name === "data-native-only" ||
            attr.name === "data-native-requires" ||
            attr.name === "data-native-unsupported")
            return "";
        if (attr.name === "data-native-mobile") {
            throw new NativeCompileError(`Declarative native capability "${attr.value}" currently targets browser/Capacitor pages. In Expo output, call the installed Expo package from an @mobile-event handler.`);
        }
        const name = attrMap[attr.name] ?? attr.name;
        if (name === "__href")
            return ` onPress={() => router.push(${JSON.stringify(attr.value)})}`;
        if (name === "source") {
            const expr = expression(attr.value);
            return ` source={${expr ? `{ uri: ${expr} }` : `{ uri: ${JSON.stringify(attr.value)} }`}}`;
        }
        if (name === "style" && attr.name !== "style") {
            return ` style={[${attr.value
                .split(/\s+/)
                .filter(Boolean)
                .map((value) => `styles[${JSON.stringify(value)}]`)
                .join(", ")} ]}`;
        }
        if (name === "style") {
            const inlineExpression = expression(attr.value);
            if (inlineExpression)
                return ` style={${inlineExpression}}`;
            throw new NativeCompileError('Inline CSS strings are not portable to native; use class="name" and a page style block');
        }
        if (attr.boolean)
            return ` ${name}`;
        const expr = expression(attr.value);
        return expr ? ` ${name}={${expr}}` : ` ${name}=${JSON.stringify(attr.value)}`;
    })
        .join("");
}
function renderNode(node, states, key) {
    if (node.type === "text")
        return textJsx(node.value);
    if (node.type === "each") {
        const params = node.index ? `${node.item}, ${node.index}` : `${node.item}, __index`;
        const body = node.body
            .map((child, index) => renderNode(child, states, index === 0 ? (node.index ?? "__index") : undefined))
            .join("");
        const empty = node.empty.map((child) => renderNode(child, states)).join("");
        return `{(${node.list})?.length ? (${node.list}).map((${params}) => <>${body}</>) : <>${empty}</>}`;
    }
    if (node.type === "if") {
        const result = node.branches.reduceRight((fallback, branch) => branch.cond === null
            ? `<>${branch.body.map((child) => renderNode(child, states)).join("")}</>`
            : `(${branch.cond}) ? <>${branch.body.map((child) => renderNode(child, states)).join("")}</> : ${fallback}`, "null");
        return `{${result}}`;
    }
    const nativeOnly = node.attrs.find((attr) => !attr.event && attr.name === "data-native-only")?.value;
    if (nativeOnly === "browser" || nativeOnly === "web")
        return "";
    const nativeTag = tagMap[node.tag.toLowerCase()] ?? (/^[A-Z]/.test(node.tag) ? node.tag : undefined);
    if (!nativeTag)
        throw new NativeCompileError(`HTML element <${node.tag}> has no native equivalent`);
    const attrs = renderAttrs(node.attrs, states) + (key ? ` key={${key}}` : "");
    if (nativeTag === "TextInput" || nativeTag === "Image" || nativeTag === "ActivityIndicator")
        return `<${nativeTag}${attrs} />`;
    const children = node.children
        .map((child) => {
        if (child.type !== "text")
            return renderNode(child, states);
        if (!child.value.trim())
            return "";
        const text = textJsx(child.value);
        return nativeTag === "Text" ? text : `<Text>${text}</Text>`;
    })
        .join("");
    return `<${nativeTag}${attrs}>${children}</${nativeTag}>`;
}
function nativeStyles(blocks) {
    const entries = [];
    for (const block of blocks) {
        for (const match of block.matchAll(/\.([A-Za-z_][\w-]*)\s*\{([^}]*)\}/g)) {
            const props = [];
            for (const declaration of match[2].split(";")) {
                const colon = declaration.indexOf(":");
                if (colon < 0)
                    continue;
                const name = declaration
                    .slice(0, colon)
                    .trim()
                    .replace(/-([a-z])/g, (_, c) => c.toUpperCase());
                let value = declaration.slice(colon + 1).trim();
                if (/^-?\d+(?:\.\d+)?px$/.test(value))
                    value = Number(value.slice(0, -2));
                props.push(`${JSON.stringify(name)}: ${typeof value === "number" ? value : JSON.stringify(value)}`);
            }
            entries.push(`${JSON.stringify(match[1])}: { ${props.join(", ")} }`);
        }
    }
    return `const styles = StyleSheet.create({ ${entries.join(",\n")} });`;
}
/** Compile a parsed `.wrn` page to an Expo Router React Native screen. */
function generateNative(ast) {
    if (ast.kind !== "page")
        throw new NativeCompileError("Native route compilation currently accepts page files only");
    if (ast.dataApis.length)
        throw new NativeCompileError("Data API blocks are not yet portable to native screens; fetch through the generated native backend helper");
    const states = new Set(ast.states.map((state) => state.name));
    const hooks = ast.states
        .map((state) => {
        const cap = state.name[0].toUpperCase() + state.name.slice(1);
        return `  const [${state.name}, set${cap}] = useState${state.valueType ? `<${state.valueType}>` : ""}(${state.expr});`;
    })
        .join("\n");
    const body = ast.view.map((node) => renderNode(node, states)).join("");
    const typeSource = ast.types
        .map((block) => block.trim())
        .filter(Boolean)
        .join("\n\n");
    return `// generated from .wrn for Expo/React Native\nimport React, { useState } from "react";\nimport { ActivityIndicator, FlatList, Image, Pressable, SafeAreaView, ScrollView, StyleSheet, Text, TextInput, View } from "react-native";\nimport { useRouter } from "expo-router";\n${ast.imports.join("\n")}\n\n${typeSource}\n\nexport default function ${ast.name}() {\n  const router = useRouter();\n${hooks}\n  return <>${body}</>;\n}\n\n${nativeStyles(ast.styles)}\n`;
}

},
"packages/compiler/src/parser.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
/** @deprecated Import parser APIs from @wrnexus/syntax. */
__exportStar(require("@wrnexus/syntax/parser"), exports);

},
"packages/compiler/src/runtime-capabilities.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runtimeCapabilities = runtimeCapabilities;
exports.analyzeRuntimeImports = analyzeRuntimeImports;
const CAPABILITIES = {
    bun: new Set([
        "filesystem",
        "tcp",
        "process",
        "websocket",
        "crypto",
        "streams",
        "background-tasks",
    ]),
    node: new Set([
        "filesystem",
        "tcp",
        "process",
        "websocket",
        "crypto",
        "streams",
        "background-tasks",
    ]),
    edge: new Set(["websocket", "crypto", "streams", "background-tasks"]),
    worker: new Set(["websocket", "crypto", "streams", "background-tasks"]),
    "service-worker": new Set(["crypto", "streams", "background-tasks"]),
    browser: new Set(["websocket", "crypto", "streams"]),
};
const MODULE_CAPABILITIES = [
    [/^(?:node:)?(?:fs|path|os)(?:\/|$)/, "filesystem"],
    [/^(?:node:)?(?:net|tls|dgram|http2)(?:\/|$)/, "tcp"],
    [/^(?:node:)?(?:child_process|cluster|worker_threads)(?:\/|$)/, "process"],
];
function runtimeCapabilities(runtime) {
    return CAPABILITIES[runtime];
}
function analyzeRuntimeImports(source, runtime) {
    const modules = [
        ...source.matchAll(/\b(?:import\s+(?:[\s\S]*?\s+from\s+)?|require\s*\()\s*["']([^"']+)["']/g),
    ].map((match) => match[1]);
    const available = runtimeCapabilities(runtime);
    return modules.flatMap((module) => {
        const requirement = MODULE_CAPABILITIES.find(([pattern]) => pattern.test(module));
        if (!requirement || available.has(requirement[1]))
            return [];
        return [
            {
                code: "WRN-RUNTIME-CAPABILITY",
                runtime,
                module,
                capability: requirement[1],
                message: `Module '${module}' requires ${requirement[1]}, which is unavailable in the ${runtime} runtime.`,
            },
        ];
    });
}

},
"packages/compiler/src/server-codegen.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.remotelyReferencedServerFunctions = remotelyReferencedServerFunctions;
exports.rpcManifest = rpcManifest;
exports.generateServerFunctionsModule = generateServerFunctionsModule;
const syntax_1 = require("@wrnexus/syntax");
function stableId(value) {
    let hash = 0x811c9dc5;
    for (let index = 0; index < value.length; index++) {
        hash ^= value.charCodeAt(index);
        hash = Math.imul(hash, 0x01000193);
    }
    return `wrn_${(hash >>> 0).toString(36)}`;
}
/**
 * Remote exposure is reference based in v0.6. A server function is included in
 * the RPC manifest only when browser-capable code calls `server.<name>(...)`.
 * Server functions remain available to SSR/server modules without becoming
 * remotely callable by default.
 */
function remotelyReferencedServerFunctions(ast) {
    const browserSources = ast.runtimeFunctions
        .filter((fn) => ["legacy", "client", "shared"].includes(fn.runtime))
        .map((fn) => fn.body);
    for (const [hook, body] of Object.entries(ast.storeLifecycle)) {
        if (hook !== "serverInit" && body)
            browserSources.push(body);
    }
    const names = new Set();
    const call = /\bserver\.([A-Za-z_$][\w$]*)\s*\(/g;
    for (const source of browserSources) {
        for (const match of source.matchAll(call))
            names.add(match[1]);
    }
    return names;
}
function rpcManifest(ast) {
    const exposed = remotelyReferencedServerFunctions(ast);
    return ast.runtimeFunctions
        .filter((fn) => fn.runtime === "server" && exposed.has(fn.name))
        .map((fn) => ({
        id: stableId(`${ast.name}:${fn.name}`),
        component: ast.name,
        function: fn.name,
        parameters: fn.parameters.map((param) => ({
            name: param.name,
            type: param.valueType ?? "unknown",
            optional: param.optional,
        })),
        returnType: fn.returnType ?? (fn.async ? "Promise<unknown>" : "unknown"),
    }));
}
function generateServerFunctionsModule(ast) {
    const source = ast.functions
        .map((body) => (0, syntax_1.stripRuntimeFunctionModifiers)(body, ["legacy", "server", "shared"]))
        .filter(Boolean)
        .join("\n\n");
    const names = ast.runtimeFunctions
        .filter((fn) => ["legacy", "server", "shared"].includes(fn.runtime))
        .map((fn) => fn.name);
    const manifest = rpcManifest(ast);
    return `// generated WRNexusJS server module for ${ast.name}\n${source}\n\nexport const __wrnexusServerFunctions = { ${[...new Set(names)].join(", ")} };\nexport const __wrnexusRpcManifest = ${JSON.stringify(manifest, null, 2)};\n`;
}

},
"packages/compiler/src/source-map.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createWrnSourceMap = createWrnSourceMap;
function createWrnSourceMap(source, generated) {
    const sourceLines = source.split(/\r?\n/).length;
    const generatedLines = generated.split(/\r?\n/).length;
    const mappings = Array.from({ length: Math.min(sourceLines, generatedLines) }, (_, index) => ({
        generatedLine: index + 1,
        sourceLine: index + 1,
        sourceColumn: 1,
        kind: "line",
    }));
    return { version: 1, source, generated, mappings };
}

},
"packages/compiler/src/store-codegen.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateStoreModule = generateStoreModule;
exports.generateStoreBrowserModule = generateStoreBrowserModule;
const syntax_1 = require("@wrnexus/syntax");
const type_codegen_ts_1 = require("./type-codegen.js");
const server_codegen_ts_1 = require("./server-codegen.js");
const RESERVED_BINDINGS = new Set([
    "await",
    "break",
    "case",
    "catch",
    "class",
    "const",
    "continue",
    "debugger",
    "default",
    "delete",
    "do",
    "else",
    "enum",
    "export",
    "extends",
    "false",
    "finally",
    "for",
    "function",
    "if",
    "implements",
    "import",
    "in",
    "instanceof",
    "interface",
    "let",
    "new",
    "null",
    "package",
    "private",
    "protected",
    "public",
    "return",
    "static",
    "super",
    "switch",
    "this",
    "throw",
    "true",
    "try",
    "typeof",
    "var",
    "void",
    "while",
    "with",
    "yield",
]);
function safeBinding(name) {
    return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) && !RESERVED_BINDINGS.has(name);
}
function stateObject(ast, runtime) {
    const entries = ast.states
        .filter((state) => state.runtime === runtime)
        .map((state) => `${JSON.stringify(state.name)}: (${state.expr})`);
    return `{ ${entries.join(", ")} }`;
}
function actionSource(fn, stateNames, eraseTypes = false) {
    const parameterNames = new Set(fn.parameters.map((param) => param.name));
    const params = fn.parameters.map((param) => param.name).join(", ");
    const aliases = stateNames.filter((name) => safeBinding(name) && !parameterNames.has(name));
    const aliasSource = aliases.length ? `let { ${aliases.join(", ")} } = context.state;` : "";
    const runtimeAliases = ["server"]
        .filter((name) => !parameterNames.has(name))
        .map((name) => `const ${name} = context.${name};`)
        .join("\n");
    const copyBack = aliases.map((name) => `context.state.${name} = ${name};`).join("\n");
    const body = eraseTypes ? (0, syntax_1.eraseFunctionTypes)(fn.body) : fn.body;
    return `{ runtime: ${JSON.stringify(fn.runtime)}, handler: ${fn.async ? "async " : ""}function(context${params ? `, ${params}` : ""}) { ${runtimeAliases}\n${aliasSource}\ntry { ${body} } finally { ${copyBack} } } }`;
}
function persistedCallback(source, functionName) {
    if (!source?.trim())
        return undefined;
    const body = (0, syntax_1.eraseFunctionTypes)(source);
    if (functionName === "migrate") {
        return `(value, fromVersion, toVersion) => {\n${body}\nif (typeof migrate === "function") return migrate(value, fromVersion, toVersion);\nreturn value;\n}`;
    }
    return `(value) => {\n${body}\nif (typeof validate === "function") return validate(value);\nreturn value && typeof value === "object" && !Array.isArray(value) ? value : null;\n}`;
}
function persistenceSource(ast) {
    if (!ast.persist)
        return "undefined";
    const migrate = persistedCallback(ast.persist.migrations, "migrate");
    const validate = persistedCallback(ast.persist.validation, "validate");
    return `{ storage: ${JSON.stringify(ast.persist.storage)}, include: ${JSON.stringify(ast.persist.include)}, version: ${ast.persist.version}${migrate ? `, migrate: ${migrate}` : ""}${validate ? `, validate: ${validate}` : ""} }`;
}
function lifecycleSource(ast, stateNames, browser) {
    return Object.entries(ast.storeLifecycle)
        .filter(([name]) => !browser || name !== "serverInit")
        .map(([name, body]) => {
        const aliases = stateNames.filter(safeBinding);
        const aliasSource = aliases.length ? `let { ${aliases.join(", ")} } = context.state;` : "";
        const runtimeAliases = browser ? "const server = context.server;" : "";
        const copyBack = aliases.map((state) => `context.state.${state} = ${state};`).join("\n");
        const emittedBody = browser ? (0, syntax_1.eraseFunctionTypes)(body) : body;
        return `${name}: async (context) => { ${runtimeAliases} ${aliasSource} try { ${emittedBody} } finally { ${copyBack} } }`;
    })
        .join(",\n");
}
function generateStoreModule(ast) {
    if (ast.kind !== "global-store" && ast.kind !== "page-store") {
        throw new Error("generateStoreModule requires a store AST");
    }
    const stateNames = ast.states.map((state) => state.name);
    const safeStateNames = stateNames.filter(safeBinding);
    const computed = ast.computed
        .map((entry) => `${JSON.stringify(entry.name)}: (state) => { ${safeStateNames.length ? `const { ${safeStateNames.join(", ")} } = state;` : ""} return (${entry.expr}); }`)
        .join(",\n");
    const actionGroups = new Map();
    for (const fn of ast.runtimeFunctions) {
        const group = actionGroups.get(fn.name) ?? [];
        group.push(fn);
        actionGroups.set(fn.name, group);
    }
    const actions = Array.from(actionGroups, ([name, functions]) => `${JSON.stringify(name)}: [${functions.map((fn) => actionSource(fn, stateNames)).join(", ")}]`).join(",\n");
    const persistence = persistenceSource(ast);
    const lifecycle = lifecycleSource(ast, stateNames, false);
    const manifest = (0, server_codegen_ts_1.rpcManifest)(ast);
    const remoteFunctions = manifest.map((entry) => entry.function);
    const rpcWrappers = remoteFunctions
        .map((name) => `${JSON.stringify(name)}: async (...received) => {
    const rpcContext = received.pop();
    if (!rpcContext || !rpcContext.request) throw new Error("WRN-RPC-CONTEXT: request context is required");
    let container = __wrnexusRpcContainers.get(rpcContext.request);
    if (!container) {
      const url = new URL(rpcContext.request.url);
      container = createRequestStoreContainer(rpcContext.request, url.pathname + url.search);
      __wrnexusRpcContainers.set(rpcContext.request, container);
    }
    const store = await container.use(${ast.name});
    const action = store.actions[${JSON.stringify(name)}];
    if (typeof action !== "function") throw new Error(${JSON.stringify(`WRN-RPC-FUNCTION: store action '${name}' is unavailable on the server`)});
    return action(...received);
  }`)
        .join(",\n");
    return `${ast.imports.join("\n")}\nimport { defineStore } from "@wrnexus/store";\nimport { createRequestStoreContainer } from "@wrnexus/store/server";\n\n${ast.types.join("\n\n")}\n\nexport const ${ast.name} = defineStore({\n  name: ${JSON.stringify(ast.name)},\n  kind: ${JSON.stringify(ast.storeKind)},\n  createSharedState: () => (${stateObject(ast, "shared")}),\n  createClientState: () => (${stateObject(ast, "client")}),\n  createServerState: () => (${stateObject(ast, "server")}),\n  computed: { ${computed} },\n  actions: { ${actions} },\n  persist: ${persistence},\n  lifecycle: { ${lifecycle} },\n});\n\nexport default ${ast.name};\n\nconst __wrnexusRpcContainers = new WeakMap();\nexport const __wrnexusServerFunctions = {\n${rpcWrappers}\n};\nexport const __wrnexusRpcManifest = ${JSON.stringify(manifest, null, 2)};\n\n${(0, type_codegen_ts_1.generateDeclarations)(ast)}\n`;
}
/** Standalone browser artifact for an imported `.wrn` store. */
function generateStoreBrowserModule(ast) {
    if (ast.kind !== "global-store" && ast.kind !== "page-store") {
        throw new Error("generateStoreBrowserModule requires a store AST");
    }
    const browserStates = ast.states.filter((state) => state.runtime !== "server");
    const stateNames = browserStates.map((state) => state.name);
    const safeStateNames = stateNames.filter(safeBinding);
    const initialState = `{ ${browserStates.map((state) => `${JSON.stringify(state.name)}: (${state.expr})`).join(", ")} }`;
    const computed = ast.computed
        .map((entry) => `${JSON.stringify(entry.name)}: (state) => { ${safeStateNames.length ? `const { ${safeStateNames.join(", ")} } = state;` : ""} return (${entry.expr}); }`)
        .join(",\n");
    const groups = new Map();
    for (const fn of ast.runtimeFunctions.filter((entry) => ["client", "shared", "legacy"].includes(entry.runtime))) {
        const group = groups.get(fn.name) ?? [];
        group.push(fn);
        groups.set(fn.name, group);
    }
    const actions = Array.from(groups, ([name, functions]) => `${JSON.stringify(name)}: [${functions.map((fn) => actionSource(fn, stateNames, true)).join(", ")}]`).join(",\n");
    const persistence = persistenceSource(ast);
    const lifecycleEntries = lifecycleSource(ast, stateNames, true);
    return `// generated WRNexusJS browser store module for ${ast.name}
const __root = globalThis;
const __registry = __root.__wrnexusStoreRegistry || (__root.__wrnexusStoreRegistry = new Map());
const __hydrationNode = typeof document !== "undefined" ? document.querySelector("script[data-wrnexus-store-hydration]") : null;
let __hydration = {};
try { __hydration = __hydrationNode ? JSON.parse(__hydrationNode.textContent || "{}") : {}; } catch (_) {}
function __clone(value) { try { return structuredClone(value); } catch (_) { return JSON.parse(JSON.stringify(value)); } }
function __storage(kind) { if (typeof window === "undefined") return null; return kind === "local" ? window.localStorage : kind === "session" ? window.sessionStorage : null; }
function __diagnostic(code, message, details) {
  const detail = { code, message, store: ${JSON.stringify(ast.name)}, details };
  try { __root.dispatchEvent && __root.dispatchEvent(new CustomEvent("wrnexus:store-diagnostic", { detail })); } catch (_) {}
  if (typeof console !== "undefined" && console.warn) console.warn("[wrnexus:store] " + code + ": " + message, details || "");
}
function __csrfToken() {
  if (typeof document === "undefined") return undefined;
  const match = /(?:^|;\\s*)wire-csrf=([^;]+)/.exec(document.cookie || "");
  return match ? decodeURIComponent(match[1]) : undefined;
}
async function __callServerFunction(storeName, functionName, args, options) {
  options = options || {};
  const csrf = options.csrfToken || __csrfToken();
  const traceId = options.traceId || (globalThis.crypto && crypto.randomUUID ? crypto.randomUUID() : String(Date.now()));
  const response = await fetch(options.endpoint || "/__wrnexus/rpc", {
    method: "POST",
    credentials: "same-origin",
    signal: options.signal,
    headers: Object.assign({ "content-type": "application/json", "x-request-id": traceId }, csrf ? { "x-csrf-token": csrf } : {}, options.headers || {}),
    body: JSON.stringify({ component: storeName, function: functionName, args: args }),
  });
  const payload = await response.json().catch(function () { return null; });
  if (!response.ok || !payload || !payload.ok) {
    const error = new Error(payload && payload.error && payload.error.message || "Server call failed (" + response.status + ")");
    error.code = payload && payload.error && payload.error.code || "WRN-RPC-FAILED";
    error.status = response.status;
    error.details = payload && payload.error && payload.error.details;
    error.traceId = payload && payload.error && payload.error.traceId || traceId;
    throw error;
  }
  return payload.value;
}
function __compatible(expected, value) {
  if (expected === null || value === null) return expected === value || expected === null;
  if (Array.isArray(expected)) return Array.isArray(value);
  return typeof expected === typeof value;
}
function __create(definition) {
  const routeId = typeof location !== "undefined" ? location.pathname + location.search : "default";
  const key = definition.kind === "page" ? definition.name + "@" + routeId : definition.name;
  if (__registry.has(key)) return __registry.get(key);
  let currentDefinition = definition;
  const listeners = new Set();
  const initial = currentDefinition.createState();
  let restored = null;
  if (currentDefinition.persist) {
    try {
      const storage = __storage(currentDefinition.persist.storage);
      const rawValue = storage && storage.getItem("wrnexus:store:" + currentDefinition.name);
      const parsed = rawValue ? JSON.parse(rawValue) : null;
      if (parsed) {
        let candidate = parsed.state;
        const fromVersion = Number(parsed.version || 0);
        if (fromVersion !== currentDefinition.persist.version) {
          if (typeof currentDefinition.persist.migrate === "function") candidate = currentDefinition.persist.migrate(candidate, fromVersion, currentDefinition.persist.version);
          else { __diagnostic("WRN-PERSIST-VERSION", "Persisted state version cannot be restored without a migration.", { fromVersion, toVersion: currentDefinition.persist.version }); candidate = null; }
        }
        if (candidate && typeof currentDefinition.persist.validate === "function") candidate = currentDefinition.persist.validate(candidate);
        if (candidate && typeof candidate === "object" && !Array.isArray(candidate)) {
          restored = {};
          currentDefinition.persist.include.forEach(function (name) { if (Object.prototype.hasOwnProperty.call(candidate, name)) restored[name] = candidate[name]; });
        } else if (candidate != null) {
          __diagnostic("WRN-PERSIST-INVALID", "Persisted state failed validation and was reset.", candidate);
        }
      }
    } catch (error) { __diagnostic("WRN-PERSIST-RESTORE", "Persisted state could not be restored and was reset.", error); }
  }
  const raw = Object.assign({}, initial, restored || {}, __hydration[currentDefinition.name] || {});
  let mutable = false;
  let actionName = "direct";
  function persistState() {
    if (!currentDefinition.persist) return;
    try {
      const picked = {};
      currentDefinition.persist.include.forEach(function (name) { picked[name] = raw[name]; });
      const storage = __storage(currentDefinition.persist.storage);
      if (storage) storage.setItem("wrnexus:store:" + currentDefinition.name, JSON.stringify({ version: currentDefinition.persist.version, state: picked }));
    } catch (error) { __diagnostic("WRN-PERSIST-WRITE", "Persisted state could not be written.", error); }
  }
  const state = new Proxy(raw, {
    set(target, property, value) {
      if (!mutable) throw new TypeError("WRN-STORE-READONLY: " + currentDefinition.name + "." + String(property) + " must be changed by a store action.");
      if (Object.is(target[property], value)) return true;
      target[property] = value;
      persistState();
      listeners.forEach(function (listener) { listener(instance.snapshot(), { store: currentDefinition.name, action: actionName, changed: [String(property)] }); });
      return true;
    },
    deleteProperty(target, property) {
      if (!mutable) throw new TypeError("WRN-STORE-READONLY: store state is readonly outside actions");
      return Reflect.deleteProperty(target, property);
    },
  });
  const actions = {};
  const server = new Proxy({}, { get: function (_target, property) { return function () { return __callServerFunction(currentDefinition.name, String(property), Array.prototype.slice.call(arguments)); }; } });
  function installActions() {
    Object.keys(actions).forEach(function (name) { delete actions[name]; });
    Object.entries(currentDefinition.actions || {}).forEach(function (pair) {
      const name = pair[0], candidates = pair[1];
      const selected = candidates.find(function (entry) { return entry.runtime === "client"; }) || candidates.find(function (entry) { return entry.runtime === "shared"; }) || candidates.find(function (entry) { return entry.runtime === "legacy"; });
      if (!selected) return;
      actions[name] = async function () {
        const args = Array.prototype.slice.call(arguments);
        const previousMutable = mutable, previousAction = actionName;
        mutable = true; actionName = name;
        try { return await selected.handler({ state, snapshot: function () { return __clone(state); }, reset: function () { return instance.reset(); }, runtime: "client", routeId, server }, ...args); }
        finally { mutable = previousMutable; actionName = previousAction; }
      };
    });
  }
  installActions();
  const core = {
    name: currentDefinition.name,
    kind: currentDefinition.kind,
    state,
    actions,
    whenReady: Promise.resolve(),
    reset() {
      mutable = true; actionName = "$reset";
      try {
        const next = currentDefinition.createState();
        Object.keys(raw).forEach(function (name) { if (!(name in next)) delete raw[name]; });
        Object.assign(raw, next); persistState();
        listeners.forEach(function (listener) { listener(instance.snapshot(), { store: currentDefinition.name, action: "$reset", changed: Object.keys(next) }); });
      } finally { mutable = false; actionName = "direct"; }
    },
    snapshot() { return Object.freeze(__clone(raw)); },
    subscribe(listener) { listeners.add(listener); return function () { listeners.delete(listener); }; },
    async dispose() {
      mutable = true; actionName = "$dispose";
      try { await currentDefinition.lifecycle && currentDefinition.lifecycle.dispose && currentDefinition.lifecycle.dispose({ state, runtime: "client", routeId, server }); }
      finally { mutable = false; actionName = "direct"; listeners.clear(); __registry.delete(key); }
    },
    async __hotUpdate(nextDefinition) {
      const previous = __clone(raw);
      const nextShape = nextDefinition.createState();
      const preserved = [], reset = [], added = [], removed = [];
      Object.keys(previous).forEach(function (name) {
        if (!(name in nextShape)) { removed.push(name); return; }
        if (__compatible(nextShape[name], previous[name])) { nextShape[name] = previous[name]; preserved.push(name); }
        else reset.push(name);
      });
      Object.keys(nextShape).forEach(function (name) { if (!(name in previous)) added.push(name); });
      currentDefinition = nextDefinition;
      mutable = true; actionName = "$hmr";
      try {
        Object.keys(raw).forEach(function (name) { delete raw[name]; });
        Object.assign(raw, nextShape);
        installActions(); persistState();
      } finally { mutable = false; actionName = "direct"; }
      const result = { store: currentDefinition.name, preserved, reset, added, removed };
      listeners.forEach(function (listener) { listener(instance.snapshot(), { store: currentDefinition.name, action: "$hmr", changed: added.concat(reset, removed) }); });
      try { __root.dispatchEvent && __root.dispatchEvent(new CustomEvent("wrnexus:store-hmr", { detail: result })); } catch (_) {}
      return result;
    },
  };
  const instance = new Proxy(core, {
    get(target, property, receiver) {
      if (Reflect.has(target, property)) return Reflect.get(target, property, receiver);
      if (property in actions) return actions[property];
      if (property in (currentDefinition.computed || {})) return currentDefinition.computed[property](state);
      return state[property];
    },
    set() { throw new TypeError("WRN-STORE-READONLY: store state is readonly outside actions"); },
  });
  __registry.set(key, instance);
  const hydrationSource = __hydration[currentDefinition.name];
  const init = async function () {
    const run = async function (name, hook) {
      if (!hook) return;
      mutable = true; actionName = name;
      try { await hook({ state, runtime: "client", routeId, server }); }
      finally { mutable = false; actionName = "direct"; }
    };
    await run("$clientInit", currentDefinition.lifecycle && currentDefinition.lifecycle.clientInit);
    if (hydrationSource) await run("$hydrate", currentDefinition.lifecycle && currentDefinition.lifecycle.hydrate);
  };
  core.whenReady = init();
  return instance;
}
if (!__root.__wrnexusApplyStoreHotUpdate) {
  __root.__wrnexusApplyStoreHotUpdate = async function (name, definition) {
    const results = [];
    for (const item of Array.from(__registry.values())) if (item.name === name && typeof item.__hotUpdate === "function") results.push(await item.__hotUpdate(definition));
    return results;
  };
}
if (!__root.__wrnexusStoreContainer) {
  __root.__wrnexusStoreContainer = {
    async disposePageStores() { for (const item of Array.from(__registry.values())) if (item.kind === "page") await item.dispose(); },
    async hotUpdate(name, definition) { return __root.__wrnexusApplyStoreHotUpdate(name, definition); },
    inspect() { return Array.from(__registry.values()).map(function (item) { return { name: item.name, kind: item.kind, state: item.snapshot() }; }); },
  };
}
export const ${ast.name}Definition = {
  name: ${JSON.stringify(ast.name)},
  kind: ${JSON.stringify(ast.storeKind)},
  createState: () => (${initialState}),
  computed: { ${computed} },
  actions: { ${actions} },
  persist: ${persistence},
  lifecycle: { ${lifecycleEntries} },
};
export const ${ast.name} = __create(${ast.name}Definition);
export default ${ast.name};
`;
}

},
"packages/compiler/src/targets.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateTargets = generateTargets;
const component_contract_ts_1 = require("./component-contract.js");
const client_codegen_ts_1 = require("./client-codegen.js");
const server_codegen_ts_1 = require("./server-codegen.js");
const type_codegen_ts_1 = require("./type-codegen.js");
const store_codegen_ts_1 = require("./store-codegen.js");
function generateTargets(ast) {
    return {
        server: ast.kind === "global-store" || ast.kind === "page-store"
            ? (0, store_codegen_ts_1.generateStoreModule)(ast)
            : (0, server_codegen_ts_1.generateServerFunctionsModule)(ast),
        browser: ast.kind === "global-store" || ast.kind === "page-store"
            ? (0, store_codegen_ts_1.generateStoreBrowserModule)(ast)
            : (0, client_codegen_ts_1.generateBrowserModule)(ast),
        declarations: (0, type_codegen_ts_1.generateDeclarations)(ast),
        contract: (0, component_contract_ts_1.createComponentContract)(ast),
        rpc: (0, server_codegen_ts_1.rpcManifest)(ast),
    };
}

},
"packages/compiler/src/tokenizer.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
/** @deprecated Import tokenizer APIs from @wrnexus/syntax. */
__exportStar(require("@wrnexus/syntax/tokenizer"), exports);

},
"packages/compiler/src/type-codegen.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateDeclarations = generateDeclarations;
function member(name) {
    return /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name);
}
function params(astParams) {
    return astParams
        .map((param) => `${member(param.name)}${param.optional ? "?" : ""}: ${param.valueType ?? "unknown"}`)
        .join(", ");
}
function generateDeclarations(ast) {
    const inline = ast.types
        .map((body) => body.trim())
        .filter(Boolean)
        .join("\n\n");
    if (ast.kind === "global-store" || ast.kind === "page-store") {
        const state = ast.states
            .filter((entry) => entry.runtime !== "server")
            .map((entry) => `  readonly ${member(entry.name)}: ${entry.valueType ?? "unknown"};`)
            .join("\n");
        const computed = ast.computed
            .map((entry) => `  readonly ${member(entry.name)}: ${entry.valueType ?? "unknown"};`)
            .join("\n");
        const actions = ast.runtimeFunctions
            .filter((fn) => fn.runtime !== "server")
            .map((fn) => `  ${member(fn.name)}(${params(fn.parameters)}): ${fn.returnType ?? (fn.async ? "Promise<unknown>" : "unknown")};`)
            .join("\n");
        return `${inline ? `${inline}\n\n` : ""}export interface ${ast.name}State {\n${state}\n}\n\nexport interface ${ast.name}Computed {\n${computed}\n}\n\nexport interface ${ast.name}Actions {\n${actions}\n}\n\nexport interface ${ast.name}Instance extends ${ast.name}State, ${ast.name}Computed, ${ast.name}Actions {\n  reset(): void;\n  snapshot(): Readonly<${ast.name}State>;\n}\n\ndeclare const store: ${ast.name}Instance;\nexport default store;\n`;
    }
    const props = ast.props
        .map((prop) => `  readonly ${member(prop.name)}${prop.required ? "" : "?"}: ${prop.valueType ?? "unknown"};`)
        .join("\n");
    const outputs = ast.outputs
        .map((output) => `  ${member(output.name)}(${output.payload ? `${member(output.payload.name)}${output.payload.optional ? "?" : ""}: ${output.payload.valueType}` : ""}): void;`)
        .join("\n");
    const clientFunctions = ast.runtimeFunctions
        .filter((fn) => fn.runtime === "client" || fn.runtime === "shared" || fn.runtime === "legacy")
        .map((fn) => `  ${member(fn.name)}(${params(fn.parameters)}): ${fn.returnType ?? (fn.async ? "Promise<unknown>" : "unknown")};`)
        .join("\n");
    const serverFunctions = ast.runtimeFunctions
        .filter((fn) => fn.runtime === "server")
        .map((fn) => `  ${member(fn.name)}(${params(fn.parameters)}): Promise<Awaited<${fn.returnType ?? "unknown"}>>;`)
        .join("\n");
    return `${inline ? `${inline}\n\n` : ""}export interface ${ast.name}Props {\n${props}\n}\n\nexport interface ${ast.name}Outputs {\n${outputs}\n}\n\nexport interface ${ast.name}ClientFunctions {\n${clientFunctions}\n}\n\nexport interface ${ast.name}ServerCalls {\n${serverFunctions}\n}\n`;
}

},
"packages/compiler/src/types.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
/** @deprecated Import language type utilities from @wrnexus/syntax. */
__exportStar(require("@wrnexus/syntax/types"), exports);

},
"packages/syntax/src/diagnostics.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.containsReadonlyPropMutation = containsReadonlyPropMutation;
exports.positionAt = positionAt;
exports.classifyParseError = classifyParseError;
exports.diagnosticFromError = diagnosticFromError;
exports.diagnose = diagnose;
exports.assertValidAst = assertValidAst;
exports.isHydrationStrategy = isHydrationStrategy;
exports.isRuntimeTarget = isRuntimeTarget;
exports.formatDiagnostic = formatDiagnostic;
const parser_ts_1 = require("./parser.js");
const spec_ts_1 = require("./spec.js");
function stripAsciiControlAndSpace(value) {
    let result = "";
    for (const character of value) {
        if (character.charCodeAt(0) > 0x20)
            result += character;
    }
    return result;
}
function maskJavaScriptTrivia(source) {
    let result = "";
    let index = 0;
    let quote = null;
    let lineComment = false;
    let blockComment = false;
    while (index < source.length) {
        const char = source[index];
        const next = source[index + 1];
        if (lineComment) {
            if (char === "\n") {
                lineComment = false;
                result += "\n";
            }
            else
                result += " ";
            index++;
            continue;
        }
        if (blockComment) {
            if (char === "*" && next === "/") {
                result += "  ";
                index += 2;
                blockComment = false;
            }
            else {
                result += char === "\n" ? "\n" : " ";
                index++;
            }
            continue;
        }
        if (quote) {
            if (char === "\\") {
                result += "  ";
                index += Math.min(2, source.length - index);
            }
            else if (char === quote) {
                result += " ";
                index++;
                quote = null;
            }
            else {
                result += char === "\n" ? "\n" : " ";
                index++;
            }
            continue;
        }
        if (char === "/" && next === "/") {
            result += "  ";
            index += 2;
            lineComment = true;
            continue;
        }
        if (char === "/" && next === "*") {
            result += "  ";
            index += 2;
            blockComment = true;
            continue;
        }
        if (char === "'" || char === '"' || char === "`") {
            quote = char;
            result += " ";
            index++;
            continue;
        }
        result += char;
        index++;
    }
    return result;
}
function containsReadonlyPropMutation(body, propName, parameterNames) {
    const code = maskJavaScriptTrivia(body);
    const escaped = propName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    const operator = String.raw `(?:\+\+|--|(?:\*\*|&&|\|\||\?\?|[+\-*/%&|^])?=(?!=|>))`;
    if (new RegExp(String.raw `\bprops\.${escaped}\s*${operator}`).test(code))
        return true;
    if (parameterNames.has(propName))
        return false;
    if (new RegExp(String.raw `\b(?:const|let|var)\s+${escaped}\b`).test(code))
        return false;
    return new RegExp(String.raw `(?:^|[^\w$.])${escaped}\s*${operator}`, "m").test(code);
}
function positionAt(source, offset) {
    const safe = Math.max(0, Math.min(offset, source.length));
    const before = source.slice(0, safe);
    const lines = before.split(/\r?\n/);
    return { offset: safe, line: lines.length, column: (lines.at(-1)?.length ?? 0) + 1 };
}
function offsetFromMessage(message) {
    const match = /offset\s+(\d+)/i.exec(message);
    return match ? Number(match[1]) : undefined;
}
function classifyParseError(message) {
    if (/Expected 'page', 'component', or 'layout'/.test(message))
        return spec_ts_1.WRN_DIAGNOSTIC_CODES.root;
    if (/Unknown (?:page|component|layout|ssr|client) member/.test(message)) {
        return spec_ts_1.WRN_DIAGNOSTIC_CODES.member;
    }
    if (/prop initializer|Expected eq/.test(message))
        return spec_ts_1.WRN_DIAGNOSTIC_CODES.propInitializer;
    if (/State '.+' requires an initializer/.test(message)) {
        return spec_ts_1.WRN_DIAGNOSTIC_CODES.stateInitializer;
    }
    if (/Cannot watch undeclared state/.test(message))
        return spec_ts_1.WRN_DIAGNOSTIC_CODES.watchUndeclared;
    return spec_ts_1.WRN_DIAGNOSTIC_CODES.parse;
}
function diagnosticFromError(source, error, options = {}) {
    const message = error instanceof Error ? error.message : String(error);
    const offset = error instanceof parser_ts_1.ParseError && error.offset !== undefined
        ? error.offset
        : offsetFromMessage(message);
    return {
        code: error instanceof parser_ts_1.ParseError ? error.code : classifyParseError(message),
        severity: "error",
        message,
        file: options.file,
        ...(offset === undefined ? {} : { position: positionAt(source, offset) }),
    };
}
function walk(nodes, visit) {
    for (const node of nodes) {
        visit(node);
        if (node.type === "element")
            walk(node.children, visit);
        else if (node.type === "each") {
            walk(node.body, visit);
            walk(node.empty, visit);
        }
        else if (node.type === "if") {
            for (const branch of node.branches)
                walk(branch.body, visit);
        }
    }
}
function astDiagnostics(ast, options) {
    const diagnostics = [];
    const seen = new Map();
    for (const [kind, declarations] of [
        ["prop", ast.props],
        ["state", ast.states],
        ["computed", ast.computed],
    ]) {
        for (const declaration of declarations) {
            const previous = seen.get(declaration.name);
            if (previous) {
                diagnostics.push({
                    code: spec_ts_1.WRN_DIAGNOSTIC_CODES.duplicateSymbol,
                    severity: "error",
                    message: `Duplicate symbol '${declaration.name}' (${previous} and ${kind}).`,
                    hint: "Rename one declaration so every prop, state, and computed value is unique.",
                    file: options.file,
                });
            }
            else {
                seen.set(declaration.name, kind);
            }
        }
    }
    if (ast.hydrate && !isHydrationStrategy(ast.hydrate)) {
        diagnostics.push({
            code: spec_ts_1.WRN_DIAGNOSTIC_CODES.invalidHydration,
            severity: "error",
            message: `Unknown hydration strategy '${ast.hydrate}'.`,
            hint: "Use load, idle, visible, interaction, none, or media:<query>.",
            file: options.file,
        });
    }
    if (ast.runtime && !isRuntimeTarget(ast.runtime)) {
        diagnostics.push({
            code: spec_ts_1.WRN_DIAGNOSTIC_CODES.invalidRuntime,
            severity: "error",
            message: `Unknown runtime target '${ast.runtime}'.`,
            hint: "Use server, client, or universal.",
            file: options.file,
        });
    }
    let interactive = ast.states.length > 0 || ast.effects.length > 0 || ast.watches.length > 0;
    const urlAttributes = new Set([
        "href",
        "src",
        "action",
        "formaction",
        "poster",
        "cite",
        "background",
        "xlink:href",
    ]);
    walk(ast.view, (node) => {
        if (node.type !== "element")
            return;
        if (node.attrs.some((attribute) => attribute.event))
            interactive = true;
        const tag = node.tag.toLowerCase();
        for (const attribute of node.attrs) {
            if (attribute.event || attribute.boolean || !urlAttributes.has(attribute.name.toLowerCase()))
                continue;
            if (attribute.value.includes("{"))
                continue;
            const value = stripAsciiControlAndSpace(attribute.value.trim()).toLowerCase();
            if (/^(?:javascript|vbscript|file):/.test(value) ||
                /^data:(?!image\/(?:png|gif|jpeg|webp|avif);)/.test(value)) {
                diagnostics.push({
                    code: "WRN-SEC-UNSAFE-URL",
                    severity: "error",
                    message: `Unsafe URL protocol in ${attribute.name} on <${node.tag}>.`,
                    hint: "Use a relative URL, https:, mailto:, tel:, or a framework-validated URL helper.",
                    file: options.file,
                });
            }
        }
        if (tag === "a") {
            const target = node.attrs.find((attribute) => attribute.name === "target")?.value;
            const rel = node.attrs.find((attribute) => attribute.name === "rel")?.value ?? "";
            if (target === "_blank" && !/\bnoopener\b/i.test(rel)) {
                diagnostics.push({
                    code: "WRN-SEC-BLANK-REL",
                    severity: "warning",
                    message: "A target=_blank link should include rel=noopener.",
                    hint: 'Add rel="noopener noreferrer".',
                    file: options.file,
                });
            }
        }
        if (!options.accessibility)
            return;
        if (tag === "img") {
            if (!node.attrs.some((attribute) => attribute.name === "alt")) {
                diagnostics.push({
                    code: spec_ts_1.WRN_DIAGNOSTIC_CODES.accessibility,
                    severity: "warning",
                    message: "Image is missing an alt attribute.",
                    hint: 'Add alt text, or alt="" for a decorative image.',
                    file: options.file,
                });
            }
            const hasWidth = node.attrs.some((attribute) => attribute.name === "width");
            const hasHeight = node.attrs.some((attribute) => attribute.name === "height");
            if (!hasWidth || !hasHeight) {
                diagnostics.push({
                    code: "WRN-PERF-IMAGE-DIMENSIONS",
                    severity: "warning",
                    message: "Image width and height are required to prevent layout shifts.",
                    hint: "Declare intrinsic width and height, or use @wrnexus/image.",
                    file: options.file,
                });
            }
        }
    });
    if (ast.runtime === "server" && interactive) {
        diagnostics.push({
            code: spec_ts_1.WRN_DIAGNOSTIC_CODES.serverInteractive,
            severity: "error",
            message: "A server-only WRN root cannot contain client state, effects, watches, or event handlers.",
            hint: 'Use runtime = "universal" or remove interactive behavior.',
            file: options.file,
        });
    }
    const outputs = new Set(ast.outputs.map((output) => output.name));
    for (const fn of ast.runtimeFunctions) {
        for (const call of fn.body.matchAll(/\boutput\.([A-Za-z_$][\w$]*)\s*\(/g)) {
            const outputName = call[1];
            if (fn.runtime === "server") {
                diagnostics.push({
                    code: "WRN-OUTPUT-SERVER-CALL",
                    severity: "error",
                    message: `Server function '${fn.name}' cannot call output.${outputName}().`,
                    hint: "Return a typed value to the browser and call the output from a client function.",
                    file: options.file,
                });
            }
            else if (!outputs.has(outputName)) {
                diagnostics.push({
                    code: "WRN-OUTPUT-UNKNOWN",
                    severity: "error",
                    message: `Unknown output '${outputName}' called from '${fn.name}'.`,
                    hint: `Declare ${outputName}(payload) inside outputs { ... }.`,
                    file: options.file,
                });
            }
        }
        if (fn.runtime === "client" && /\b(?:process|Bun|Deno|__dirname|require)\b/.test(fn.body)) {
            diagnostics.push({
                code: "WRN-CLIENT-SERVER-API",
                severity: "error",
                message: `Client function '${fn.name}' references a server-only API.`,
                hint: "Move that operation into a server function and call it through server.name(...).",
                file: options.file,
            });
        }
        if (fn.runtime === "server" &&
            /\b(?:window|document|localStorage|sessionStorage|navigator)\b/.test(fn.body)) {
            diagnostics.push({
                code: "WRN-SERVER-BROWSER-API",
                severity: "error",
                message: `Server function '${fn.name}' references a browser-only API.`,
                hint: "Move that code into a client function.",
                file: options.file,
            });
        }
        if (fn.runtime !== "server" &&
            /\b(?:eval\s*\(|new\s+Function\s*\(|document\.write\s*\(|\.innerHTML\s*=|\.outerHTML\s*=|insertAdjacentHTML\s*\()/.test(fn.body)) {
            diagnostics.push({
                code: "WRN-SEC-DOM-SINK",
                severity: "error",
                message: `Client function '${fn.name}' uses an unsafe dynamic-code or HTML sink.`,
                hint: "Use compiled templates, textContent, typed outputs, or a reviewed TrustedHTML sanitizer.",
                file: options.file,
            });
        }
        if (fn.runtime !== "server" && /\b(?:setTimeout|setInterval)\s*\(\s*["'`]/.test(fn.body)) {
            diagnostics.push({
                code: "WRN-SEC-STRING-TIMER",
                severity: "error",
                message: `Client function '${fn.name}' passes a string to a timer.`,
                hint: "Pass a function instead of executable text.",
                file: options.file,
            });
        }
        const parameterNames = new Set(fn.parameters.map((parameter) => parameter.name));
        for (const prop of ast.props) {
            if (containsReadonlyPropMutation(fn.body, prop.name, parameterNames)) {
                diagnostics.push({
                    code: "WRN-PROP-READONLY",
                    severity: "error",
                    message: `Function '${fn.name}' attempts to mutate readonly prop '${prop.name}'.`,
                    hint: "Copy the prop into state before mutating it.",
                    file: options.file,
                });
            }
        }
    }
    for (const state of ast.states) {
        if (state.runtime === "shared" &&
            /^(?:new\s+(?:Map|Set|WeakMap|WeakSet)|(?:async\s+)?function\b|.*=>)/.test(state.expr.trim())) {
            diagnostics.push({
                code: "WRN-STATE-NON-SERIALIZABLE",
                severity: "error",
                message: `Shared state '${state.name}' is not safely serializable.`,
                hint: "Use JSON-compatible data or move the value into client/server state.",
                file: options.file,
            });
        }
        if (state.runtime !== "server" &&
            /\b(?:process\.env|Bun\.env|Deno\.env|ctx\.env|import\.meta\.env)\b/.test(state.expr)) {
            diagnostics.push({
                code: "WRN-SEC-SERVER-SECRET-SOURCE",
                severity: "error",
                message: `Browser-visible state '${state.name}' reads from a server environment source.`,
                hint: "Move environment-backed values into server state and return only an explicitly safe result.",
                file: options.file,
            });
        }
    }
    if (ast.persist) {
        const stateNames = new Set(ast.states.filter((state) => state.runtime !== "server").map((state) => state.name));
        for (const name of ast.persist.include)
            if (!stateNames.has(name))
                diagnostics.push({
                    code: "WRN-PERSIST-UNKNOWN-FIELD",
                    severity: "error",
                    message: `Persist include references unknown or server-only state '${name}'.`,
                    hint: "Persist only declared shared/client state fields.",
                    file: options.file,
                });
        for (const name of ast.persist.include)
            if (/token|password|secret|otp|api.?key/i.test(name))
                diagnostics.push({
                    code: "WRN-PERSIST-SENSITIVE",
                    severity: "error",
                    message: `Sensitive field '${name}' cannot be persisted.`,
                    hint: "Remove secrets, tokens, passwords, OTPs, and API keys from persistence.",
                    file: options.file,
                });
    }
    return diagnostics;
}
function diagnose(source, options = {}) {
    try {
        return astDiagnostics((0, parser_ts_1.parse)(source), options);
    }
    catch (error) {
        return [diagnosticFromError(source, error, options)];
    }
}
function assertValidAst(ast, options = {}) {
    const errors = astDiagnostics(ast, options).filter((diagnostic) => diagnostic.severity === "error");
    if (!errors.length)
        return;
    const first = errors[0];
    throw new parser_ts_1.ParseError(first.message, first.code);
}
function isHydrationStrategy(value) {
    return (spec_ts_1.WRN_HYDRATION_STRATEGIES.includes(value) ||
        (value.startsWith("media:") && value.length > "media:".length));
}
function isRuntimeTarget(value) {
    return spec_ts_1.WRN_RUNTIME_TARGETS.includes(value);
}
function formatDiagnostic(source, diagnostic) {
    const location = diagnostic.position
        ? `${diagnostic.file ?? "<inline .wrn>"}:${diagnostic.position.line}:${diagnostic.position.column}`
        : (diagnostic.file ?? "<inline .wrn>");
    const lines = [
        `${diagnostic.code} ${diagnostic.severity.toUpperCase()}`,
        "",
        diagnostic.message,
        "",
        location,
    ];
    if (diagnostic.position) {
        const sourceLine = source.split(/\r?\n/)[diagnostic.position.line - 1] ?? "";
        lines.push("", sourceLine, `${" ".repeat(Math.max(0, diagnostic.position.column - 1))}^`);
    }
    if (diagnostic.hint)
        lines.push("", `Hint: ${diagnostic.hint}`);
    return lines.join("\n");
}

},
"packages/syntax/src/formatter.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
// The formatter intentionally operates on partially written source. Its small
// scanner values are dynamically shaped, while the public API below remains typed.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatWrn = formatWrn;
const VOID_ELEMENTS = new Set([
    "area",
    "base",
    "br",
    "col",
    "embed",
    "hr",
    "img",
    "input",
    "link",
    "meta",
    "param",
    "source",
    "track",
    "wbr",
]);
function splitPropDeclarations(value) {
    const declarations = [];
    let start = 0;
    let index = 0;
    let quote = null;
    let escaped = false;
    let square = 0;
    let brace = 0;
    let paren = 0;
    let segmentHasColon = false;
    let segmentHasEquals = false;
    const isIdentifierStart = (character) => /[A-Za-z_]/.test(character || "");
    const isIdentifierPart = (character) => /[A-Za-z0-9_]/.test(character || "");
    const beginsDeclaration = (position) => {
        let cursor = position;
        while (cursor < value.length && /[ \t]/.test(value[cursor]))
            cursor += 1;
        if (value.slice(cursor).startsWith("@event")) {
            cursor += "@event".length;
            if (!/\s/.test(value[cursor] || ""))
                return false;
            while (cursor < value.length && /\s/.test(value[cursor]))
                cursor += 1;
            if (!isIdentifierStart(value[cursor]))
                return false;
            cursor += 1;
            while (cursor < value.length && isIdentifierPart(value[cursor]))
                cursor += 1;
            while (cursor < value.length && /[ \t]/.test(value[cursor]))
                cursor += 1;
            return value[cursor] === "=" ? "=" : null;
        }
        if (!isIdentifierStart(value[cursor]))
            return false;
        cursor += 1;
        while (cursor < value.length && isIdentifierPart(value[cursor]))
            cursor += 1;
        if (value[cursor] === "?")
            cursor += 1;
        while (cursor < value.length && /[ \t]/.test(value[cursor]))
            cursor += 1;
        return value[cursor] === "=" || value[cursor] === ":" ? value[cursor] : null;
    };
    while (index < value.length) {
        const character = value[index];
        if (quote !== null) {
            if (escaped)
                escaped = false;
            else if (character === "\\")
                escaped = true;
            else if (character === quote)
                quote = null;
            index += 1;
            continue;
        }
        if (character === '"' || character === "'" || character === "`") {
            quote = character;
            index += 1;
            continue;
        }
        if (character === "[")
            square += 1;
        else if (character === "]" && square > 0)
            square -= 1;
        else if (character === "{")
            brace += 1;
        else if (character === "}" && brace > 0)
            brace -= 1;
        else if (character === "(")
            paren += 1;
        else if (character === ")" && paren > 0)
            paren -= 1;
        const topLevel = square === 0 && brace === 0 && paren === 0;
        if (topLevel && character === ":")
            segmentHasColon = true;
        if (topLevel && character === "=")
            segmentHasEquals = true;
        const candidateDelimiter = topLevel && /\s/.test(character) ? beginsDeclaration(index) : null;
        const beginsNext = candidateDelimiter === ":" ||
            (candidateDelimiter === "=" && (segmentHasEquals || !segmentHasColon));
        if (topLevel &&
            /\s/.test(character) &&
            value.slice(start, index).trim() !== "@event" &&
            beginsNext) {
            const declaration = value.slice(start, index).trim();
            if (declaration)
                declarations.push(declaration);
            while (index < value.length && /\s/.test(value[index]))
                index += 1;
            start = index;
            segmentHasColon = false;
            segmentHasEquals = false;
            continue;
        }
        index += 1;
    }
    const declaration = value.slice(start).trim();
    if (declaration)
        declarations.push(declaration);
    return declarations;
}
function splitOutputDeclarations(value) {
    const declarations = [];
    let start = 0;
    let paren = 0;
    let angle = 0;
    let square = 0;
    let quote = null;
    let escaped = false;
    const startsOutput = (position) => {
        let cursor = position;
        while (cursor < value.length && /\s/.test(value[cursor]))
            cursor += 1;
        if (!/[A-Za-z_$]/.test(value[cursor] || ""))
            return false;
        cursor += 1;
        while (cursor < value.length && /[A-Za-z0-9_$]/.test(value[cursor] || ""))
            cursor += 1;
        while (cursor < value.length && /\s/.test(value[cursor]))
            cursor += 1;
        return value[cursor] === "(";
    };
    for (let index = 0; index < value.length; index += 1) {
        const character = value[index];
        if (quote !== null) {
            if (escaped)
                escaped = false;
            else if (character === "\\")
                escaped = true;
            else if (character === quote)
                quote = null;
            continue;
        }
        if (character === '"' || character === "'" || character === "`") {
            quote = character;
            continue;
        }
        if (character === "(")
            paren += 1;
        else if (character === ")" && paren > 0)
            paren -= 1;
        else if (character === "[")
            square += 1;
        else if (character === "]" && square > 0)
            square -= 1;
        else if (character === "<")
            angle += 1;
        else if (character === ">" && angle > 0)
            angle -= 1;
        if (paren === 0 && square === 0 && angle === 0 && /\s/.test(character) && startsOutput(index)) {
            const declaration = value.slice(start, index).trim();
            if (declaration)
                declarations.push(declaration);
            while (index < value.length && /\s/.test(value[index]))
                index += 1;
            start = index;
            index -= 1;
        }
    }
    const finalDeclaration = value.slice(start).trim();
    if (finalDeclaration)
        declarations.push(finalDeclaration);
    return declarations;
}
function formatInlineDeclarationBlock(value, unit, depth) {
    const match = /^(props|state|computed|outputs)\s*\{([\s\S]*)\}$/.exec(value.trim());
    if (!match)
        return null;
    const declarations = match[1] === "outputs"
        ? splitOutputDeclarations(match[2].trim())
        : splitPropDeclarations(match[2].trim());
    return [
        `${unit.repeat(depth)}${match[1]} {`,
        ...declarations.map((declaration) => `${unit.repeat(depth + 1)}${declaration}`),
        `${unit.repeat(depth)}}`,
    ];
}
function formatInlinePropsBlock(value, unit, depth) {
    const match = /^props\s*\{([\s\S]*)\}$/.exec(value.trim());
    if (!match)
        return null;
    const declarations = splitPropDeclarations(match[1].trim());
    if (declarations.length === 0) {
        return [`${unit.repeat(depth)}props {`, `${unit.repeat(depth)}}`];
    }
    return [
        `${unit.repeat(depth)}props {`,
        ...declarations.map((declaration) => `${unit.repeat(depth + 1)}${declaration}`),
        `${unit.repeat(depth)}}`,
    ];
}
function findOpeningTagEnd(value) {
    let quote = null;
    let escaped = false;
    for (let index = 0; index < value.length; index += 1) {
        const character = value[index];
        if (quote !== null) {
            if (escaped) {
                escaped = false;
                continue;
            }
            if (character === "\\") {
                escaped = true;
                continue;
            }
            if (character === quote) {
                quote = null;
            }
            continue;
        }
        if (character === '"' || character === "'") {
            quote = character;
            continue;
        }
        if (character === ">") {
            return index;
        }
    }
    return -1;
}
function parseAttributes(value) {
    const attributes = [];
    let index = 0;
    while (index < value.length) {
        while (index < value.length && /\s/.test(value[index]))
            index += 1;
        if (index >= value.length)
            break;
        const start = index;
        while (index < value.length && !/[\s=]/.test(value[index]))
            index += 1;
        while (index < value.length && /\s/.test(value[index]))
            index += 1;
        if (value[index] === "=") {
            index += 1;
            while (index < value.length && /\s/.test(value[index]))
                index += 1;
            const quote = value[index];
            if (quote === '"' || quote === "'") {
                index += 1;
                let escaped = false;
                while (index < value.length) {
                    const character = value[index++];
                    if (escaped)
                        escaped = false;
                    else if (character === "\\")
                        escaped = true;
                    else if (character === quote)
                        break;
                }
            }
            else if (value[index] === "{") {
                let depth = 0;
                let expressionQuote = null;
                let escaped = false;
                while (index < value.length) {
                    const character = value[index++];
                    if (expressionQuote !== null) {
                        if (escaped)
                            escaped = false;
                        else if (character === "\\")
                            escaped = true;
                        else if (character === expressionQuote)
                            expressionQuote = null;
                        continue;
                    }
                    if (character === '"' || character === "'" || character === "`") {
                        expressionQuote = character;
                    }
                    else if (character === "{") {
                        depth += 1;
                    }
                    else if (character === "}" && --depth === 0) {
                        break;
                    }
                }
            }
            else {
                while (index < value.length && !/\s/.test(value[index]))
                    index += 1;
            }
        }
        const attribute = value.slice(start, index).trim();
        if (attribute)
            attributes.push(attribute);
    }
    return attributes;
}
function parseStructuredAttribute(attribute) {
    const match = /^([^\s=]+)\s*=\s*\{([\s\S]*)\}$/.exec(attribute);
    if (!match)
        return null;
    const expression = match[2].trim();
    if (!expression.startsWith("[") && !expression.startsWith("{"))
        return null;
    try {
        return {
            name: match[1],
            value: JSON.parse(expression),
        };
    }
    catch {
        return null;
    }
}
function formatAttribute(attribute, indentation, unit) {
    const structured = parseStructuredAttribute(attribute);
    if (!structured)
        return [`${indentation}${attribute}`];
    const jsonLines = JSON.stringify(structured.value, null, unit).split("\n");
    if (jsonLines.length === 1) {
        return [`${indentation}${structured.name}={${jsonLines[0]}}`];
    }
    return [
        `${indentation}${structured.name}={${jsonLines[0]}`,
        ...jsonLines.slice(1, -1).map((line) => `${indentation}${line}`),
        `${indentation}${jsonLines.at(-1)}}`,
    ];
}
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function parseOpeningTag(value) {
    const endIndex = findOpeningTagEnd(value);
    if (endIndex === -1) {
        return null;
    }
    const openingPart = value.slice(0, endIndex + 1);
    const remainder = value.slice(endIndex + 1).trim();
    const match = /^<([A-Za-z][\w$:.-]*)([\s\S]*?)(\/?)>$/.exec(openingPart);
    if (!match) {
        return null;
    }
    const tagName = match[1];
    const attributes = parseAttributes(match[2].trim());
    const selfClosing = match[3] === "/";
    const escapedTagName = escapeRegExp(tagName);
    const immediateClosing = new RegExp(`^<\\/${escapedTagName}\\s*>`, "i").test(remainder);
    const trailingClosingMatch = new RegExp(`^([\\s\\S]*?)<\\/${escapedTagName}\\s*>$`, "i").exec(remainder);
    const trailingClosing = trailingClosingMatch !== null;
    const inlineContent = trailingClosing ? trailingClosingMatch[1].trim() : "";
    const inlineClosing = trailingClosing && inlineContent.length === 0;
    const closesInRemainder = immediateClosing || trailingClosing;
    return {
        tagName,
        attributes,
        selfClosing,
        inlineClosing,
        immediateClosing,
        trailingClosing,
        inlineContent,
        closesInRemainder,
        remainder,
    };
}
function formatOpeningTag(value, unit, depth, printWidth = 100, multilineAttributes = true) {
    const parsed = parseOpeningTag(value);
    if (!parsed) {
        return {
            lines: [`${unit.repeat(depth)}${value.trim()}`],
            opensElement: false,
        };
    }
    const baseIndent = unit.repeat(depth);
    const childIndent = unit.repeat(depth + 1);
    const normalizedOpening = `<${parsed.tagName}` +
        `${parsed.attributes.length ? ` ${parsed.attributes.join(" ")}` : ""}` +
        `${parsed.selfClosing ? " /" : ""}>`;
    const normalizedSingleLine = `${normalizedOpening}${parsed.remainder}`;
    const shouldBreak = value.includes("\n") ||
        (multilineAttributes && parsed.attributes.length > 0) ||
        baseIndent.length + normalizedSingleLine.length > printWidth;
    const opensElement = !parsed.selfClosing &&
        !parsed.closesInRemainder &&
        !VOID_ELEMENTS.has(parsed.tagName.toLowerCase());
    if (!shouldBreak) {
        return {
            lines: [`${baseIndent}${normalizedSingleLine}`],
            opensElement,
        };
    }
    if (parsed.attributes.length === 0 && !parsed.selfClosing) {
        const lines = [`${baseIndent}<${parsed.tagName}>`];
        if (parsed.trailingClosing) {
            if (parsed.inlineContent)
                lines.push(`${childIndent}${parsed.inlineContent}`);
            lines.push(`${baseIndent}</${parsed.tagName}>`);
        }
        else if (parsed.remainder) {
            lines.push(`${childIndent}${parsed.remainder}`);
        }
        return { lines, opensElement };
    }
    const lines = [
        `${baseIndent}<${parsed.tagName}`,
        ...parsed.attributes.flatMap((attribute) => formatAttribute(attribute, childIndent, unit)),
    ];
    if (parsed.selfClosing) {
        lines.push(`${baseIndent}/>`);
        return {
            lines,
            opensElement,
        };
    }
    lines.push(`${baseIndent}>`);
    if (parsed.trailingClosing) {
        if (parsed.inlineContent) {
            lines.push(`${childIndent}${parsed.inlineContent}`);
        }
        lines.push(`${baseIndent}</${parsed.tagName}>`);
    }
    else if (parsed.remainder) {
        lines.push(`${parsed.immediateClosing ? baseIndent : childIndent}${parsed.remainder}`);
    }
    return {
        lines,
        opensElement,
    };
}
function isMultilineOpeningTagStart(value) {
    if (!value.startsWith("<")) {
        return false;
    }
    if (value.startsWith("</") ||
        value.startsWith("<!--") ||
        value.startsWith("<!") ||
        value.startsWith("<?")) {
        return false;
    }
    return findOpeningTagEnd(value) === -1;
}
function isClosingTag(value) {
    return /^<\/[A-Za-z][\w$:.-]*\s*>/.test(value);
}
/**
 * Preserve compact, already-balanced HTML fragments as one line.
 *
 * A line such as `<span>Page</span><b>→</b><span>API</span>` is valid and
 * intentionally compact. Expanding only its first opening tag makes later
 * formatter passes treat the remaining siblings as children, causing runaway
 * indentation and false closing-tag diagnostics. Balanced fragments are kept
 * intact while normal multiline opening tags continue through the formatter.
 */
function isBalancedInlineHtmlFragment(value) {
    if (!value.startsWith("<") || value.startsWith("</") || value.startsWith("<!--")) {
        return false;
    }
    const stack = [];
    let tagCount = 0;
    let rootCount = 0;
    let hasNestedElement = false;
    let hasOutsideText = false;
    let index = 0;
    while (index < value.length) {
        const tagStart = value.indexOf("<", index);
        if (tagStart === -1) {
            if (stack.length === 0 && value.slice(index).trim())
                hasOutsideText = true;
            break;
        }
        if (stack.length === 0 && value.slice(index, tagStart).trim())
            hasOutsideText = true;
        if (value.startsWith("<!--", tagStart)) {
            const commentEnd = value.indexOf("-->", tagStart + 4);
            if (commentEnd === -1)
                return false;
            index = commentEnd + 3;
            continue;
        }
        const relativeEnd = findOpeningTagEnd(value.slice(tagStart));
        if (relativeEnd === -1)
            return false;
        const tag = value.slice(tagStart, tagStart + relativeEnd + 1);
        const match = /^<\/?([A-Za-z][\w$:.-]*)[\s\S]*?>$/.exec(tag);
        if (!match) {
            index = tagStart + 1;
            continue;
        }
        tagCount += 1;
        const tagName = match[1];
        const normalizedName = /^[a-z]/.test(tagName) ? tagName.toLowerCase() : tagName;
        const closing = tag.startsWith("</");
        const selfClosing = /\/\s*>$/.test(tag);
        const voidElement = VOID_ELEMENTS.has(tagName.toLowerCase());
        if (closing) {
            if (stack.at(-1) !== normalizedName)
                return false;
            stack.pop();
        }
        else {
            if (stack.length === 0)
                rootCount += 1;
            else
                hasNestedElement = true;
            if (!selfClosing && !voidElement)
                stack.push(normalizedName);
        }
        index = tagStart + relativeEnd + 1;
    }
    return (tagCount >= 2 && stack.length === 0 && (rootCount > 1 || hasNestedElement || hasOutsideText));
}
function isControlBlockOpen(value) {
    return /^\{#(?:if|each)\b[\s\S]*\}$/.test(value);
}
function isControlBlockMiddle(value) {
    return /^\{:(?:else(?:\s+if\b[\s\S]*)?|empty)\}$/.test(value);
}
function isControlBlockClose(value) {
    return /^\{\/(?:if|each)\}$/.test(value);
}
function countLeadingClosingBraces(value) {
    let index = 0;
    let count = 0;
    while (index < value.length) {
        while (index < value.length && /\s/.test(value[index])) {
            index += 1;
        }
        if (value[index] !== "}" && value[index] !== "]") {
            break;
        }
        count += 1;
        index += 1;
    }
    return count;
}
/**
 * Count braces outside strings and HTML comments.
 *
 * This supports WRN blocks, function bodies, lifecycle hooks,
 * watcher bodies and multiline JavaScript object literals.
 */
function countStructuralBraces(value) {
    let openings = 0;
    let closings = 0;
    let quote = null;
    let escaped = false;
    let htmlComment = false;
    for (let index = 0; index < value.length; index += 1) {
        if (!quote && !htmlComment && value.startsWith("<!--", index)) {
            htmlComment = true;
            index += 3;
            continue;
        }
        if (htmlComment && value.startsWith("-->", index)) {
            htmlComment = false;
            index += 2;
            continue;
        }
        if (htmlComment) {
            continue;
        }
        const character = value[index];
        if (quote !== null) {
            if (escaped) {
                escaped = false;
                continue;
            }
            if (character === "\\") {
                escaped = true;
                continue;
            }
            if (character === quote) {
                quote = null;
            }
            continue;
        }
        if (character === '"' || character === "'" || character === "`") {
            quote = character;
            continue;
        }
        if (character === "{") {
            openings += 1;
        }
        else if (character === "}") {
            closings += 1;
        }
        else if (character === "[") {
            openings += 1;
        }
        else if (character === "]") {
            closings += 1;
        }
    }
    return {
        openings,
        closings,
    };
}
function collectOpeningTag(inputLines, startIndex) {
    const collected = [inputLines[startIndex].trim()];
    let index = startIndex;
    while (index + 1 < inputLines.length) {
        const joined = collected.join(" ");
        if (findOpeningTagEnd(joined) !== -1) {
            break;
        }
        index += 1;
        collected.push(inputLines[index].trim());
    }
    return {
        // Preserve the fact that the opening tag was already multiline so a
        // second formatter pass cannot collapse it back to one line.
        value: collected.join("\n"),
        endIndex: index,
    };
}
function isPreservedRawBlockStart(value) {
    return (/<pre(?:\s|>)/i.test(value) &&
        !/<\/pre\s*>/i.test(value.slice(0, value.search(/<pre(?:\s|>)/i))));
}
function hasPreservedRawBlockEnd(value) {
    return /<\/pre\s*>/i.test(value);
}
function transformOutsidePreservedRawBlocks(lines, transformLine) {
    const output = [];
    let preserving = false;
    for (const line of lines) {
        if (preserving) {
            output.push(line);
            if (hasPreservedRawBlockEnd(line))
                preserving = false;
            continue;
        }
        if (isPreservedRawBlockStart(line)) {
            output.push(line);
            preserving = !hasPreservedRawBlockEnd(line);
            continue;
        }
        output.push(...transformLine(line));
    }
    return output;
}
function collectPreservedRawBlock(lines, startIndex) {
    const collected = [lines[startIndex]];
    let index = startIndex;
    while (!hasPreservedRawBlockEnd(collected.at(-1) || "") && index + 1 < lines.length) {
        index += 1;
        collected.push(lines[index]);
    }
    return { lines: collected, endIndex: index };
}
/**
 * Put WRN template control markers on their own lines before indentation.
 *
 * Authors commonly write compact fragments such as
 * `{#if loading}<span>…</span>{/if}`. Treating that as one line prevents the
 * normal HTML and control-block formatters from seeing its structure.
 */
function expandInlineControlBlocks(lines) {
    const marker = /(\{#(?:if|each)\b[^}]*\}|\{:(?:else(?:\s+if\b[^}]*)?|empty)\}|\{\/(?:if|each)\})/g;
    return transformOutsidePreservedRawBlocks(lines, (line) => {
        if (!marker.test(line))
            return [line];
        marker.lastIndex = 0;
        const indentation = line.match(/^\s*/)?.[0] ?? "";
        const segments = line
            .split(marker)
            .map((segment) => segment.trim())
            .filter(Boolean);
        return segments.map((segment) => `${indentation}${segment}`);
    });
}
function expandStructuredStateDeclarations(lines, unit) {
    return transformOutsidePreservedRawBlocks(lines, (line) => {
        const match = /^(\s*state\s+[A-Za-z_$][\w$]*\s*=\s*)([\\[{][\s\S]*)$/.exec(line);
        if (!match)
            return [line];
        try {
            const parsed = JSON.parse(match[2].trim());
            const jsonLines = JSON.stringify(parsed, null, unit).split("\n");
            if (jsonLines.length === 1)
                return [`${match[1]}${jsonLines[0]}`];
            const leading = match[1].match(/^\s*/)?.[0] ?? "";
            return [
                `${match[1]}${jsonLines[0]}`,
                ...jsonLines.slice(1).map((jsonLine) => `${leading}${jsonLine}`),
            ];
        }
        catch {
            return [line];
        }
    });
}
function formatWrnPass(source, options = {}) {
    const unit = options.insertSpaces === false ? "\t" : " ".repeat(options.tabSize ?? 4);
    const printWidth = options.printWidth ?? 100;
    const multilineAttributes = options.multilineAttributes !== false;
    let codeDepth = 0;
    let htmlDepth = 0;
    let controlDepth = 0;
    let index = 0;
    const sourceLines = source.replace(/\r\n/g, "\n").split("\n");
    const inputLines = expandInlineControlBlocks(expandStructuredStateDeclarations(sourceLines, unit));
    const output = [];
    let previousWasBlank = false;
    while (index < inputLines.length) {
        const originalLine = inputLines[index];
        let value = originalLine.trim();
        if (value === "") {
            if (!previousWasBlank && output.length > 0) {
                output.push("");
            }
            previousWasBlank = true;
            index += 1;
            continue;
        }
        previousWasBlank = false;
        if (/^import\b/.test(value)) {
            const importLines = [value];
            while (!/(?:\bfrom\s+)?["'][^"']+["']\s*;?$/.test(importLines[importLines.length - 1]) &&
                index + 1 < inputLines.length) {
                index += 1;
                importLines.push(inputLines[index].trim());
            }
            output.push(importLines[0], ...importLines.slice(1).map((line) => `${unit}${line}`));
            index += 1;
            continue;
        }
        if (isPreservedRawBlockStart(value)) {
            const collected = collectPreservedRawBlock(inputLines, index);
            const depth = codeDepth + htmlDepth + controlDepth;
            output.push(`${unit.repeat(depth)}${collected.lines[0].trimStart()}`);
            output.push(...collected.lines.slice(1));
            index = collected.endIndex + 1;
            continue;
        }
        if (isMultilineOpeningTagStart(value)) {
            const collected = collectOpeningTag(inputLines, index);
            value = collected.value;
            index = collected.endIndex;
        }
        const inlineDeclaration = formatInlineDeclarationBlock(value, unit, codeDepth + htmlDepth);
        const inlineProps = inlineDeclaration ?? formatInlinePropsBlock(value, unit, codeDepth + htmlDepth);
        if (inlineProps) {
            output.push(...inlineProps);
            index += 1;
            continue;
        }
        const leadingClosingBraces = countLeadingClosingBraces(value);
        const closesControlBlock = isControlBlockClose(value);
        const continuesControlBlock = isControlBlockMiddle(value);
        const lineControlDepth = closesControlBlock || continuesControlBlock ? Math.max(0, controlDepth - 1) : controlDepth;
        const lineCodeDepth = Math.max(0, codeDepth - leadingClosingBraces);
        let lineHtmlDepth = htmlDepth;
        if (isClosingTag(value)) {
            lineHtmlDepth = Math.max(0, htmlDepth - 1);
        }
        const depth = lineCodeDepth + lineHtmlDepth + lineControlDepth;
        const inlineFragmentFits = unit.repeat(depth).length + value.length <= printWidth;
        if (isBalancedInlineHtmlFragment(value) && inlineFragmentFits) {
            output.push(`${unit.repeat(depth)}${value}`);
        }
        else if (value.startsWith("<") &&
            !value.startsWith("</") &&
            !value.startsWith("<!--") &&
            !value.startsWith("<!") &&
            !value.startsWith("<?")) {
            const formattedTag = formatOpeningTag(value, unit, depth, printWidth, multilineAttributes);
            output.push(...formattedTag.lines);
            if (formattedTag.opensElement) {
                htmlDepth += 1;
            }
        }
        else {
            output.push(`${unit.repeat(depth)}${value}`);
        }
        if (isClosingTag(value)) {
            htmlDepth = lineHtmlDepth;
        }
        const braces = countStructuralBraces(value);
        codeDepth = Math.max(0, lineCodeDepth + braces.openings - Math.max(0, braces.closings - leadingClosingBraces));
        if (isControlBlockOpen(value) || continuesControlBlock) {
            controlDepth = lineControlDepth + 1;
        }
        else if (closesControlBlock) {
            controlDepth = lineControlDepth;
        }
        index += 1;
    }
    while (output.length > 0 && output[output.length - 1] === "") {
        output.pop();
    }
    return `${output.join("\n")}\n`;
}
/** Format to a bounded fixed point so one call is always safe for editor-on-save and migrations. */
function formatWrn(source, options = {}) {
    let current = source;
    const seen = new Set();
    for (let pass = 0; pass < 8; pass++) {
        const formatted = formatWrnPass(current, options);
        if (formatted === current)
            return formatted;
        if (seen.has(formatted))
            return [...seen, formatted].sort()[0];
        seen.add(current);
        current = formatted;
    }
    return current;
}

},
"packages/syntax/src/index.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.stripRuntimeFunctionModifiers = exports.parseStructuredImports = exports.parseStoreLifecycle = exports.parseStateDeclarations = exports.parseRuntimeFunctions = exports.parsePersist = exports.parseOutputs = exports.parseComputedDeclarations = exports.supportsSyntaxFeature = exports.diagnosticSummary = exports.sliceSource = exports.createSourceRange = exports.WRN_SYNTAX_FEATURES = exports.WRN_SYNTAX_VERSION = exports.positionAt = exports.isRuntimeTarget = exports.isHydrationStrategy = exports.formatDiagnostic = exports.diagnosticFromError = exports.diagnose = exports.containsReadonlyPropMutation = exports.classifyParseError = exports.assertValidAst = exports.validateTypedInitializer = exports.runtimeTypeOf = exports.inferredRuntimeType = exports.eraseFunctionTypes = exports.VOID_ELEMENTS = exports.ParseError = exports.parseHtmlView = exports.parse = exports.formatWrn = exports.LexError = exports.Lexer = void 0;
var tokenizer_ts_1 = require("./tokenizer.js");
Object.defineProperty(exports, "Lexer", { enumerable: true, get: function () { return tokenizer_ts_1.Lexer; } });
Object.defineProperty(exports, "LexError", { enumerable: true, get: function () { return tokenizer_ts_1.LexError; } });
var formatter_ts_1 = require("./formatter.js");
Object.defineProperty(exports, "formatWrn", { enumerable: true, get: function () { return formatter_ts_1.formatWrn; } });
var parser_ts_1 = require("./parser.js");
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parser_ts_1.parse; } });
Object.defineProperty(exports, "parseHtmlView", { enumerable: true, get: function () { return parser_ts_1.parseHtmlView; } });
Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return parser_ts_1.ParseError; } });
Object.defineProperty(exports, "VOID_ELEMENTS", { enumerable: true, get: function () { return parser_ts_1.VOID_ELEMENTS; } });
var types_ts_1 = require("./types.js");
Object.defineProperty(exports, "eraseFunctionTypes", { enumerable: true, get: function () { return types_ts_1.eraseFunctionTypes; } });
Object.defineProperty(exports, "inferredRuntimeType", { enumerable: true, get: function () { return types_ts_1.inferredRuntimeType; } });
Object.defineProperty(exports, "runtimeTypeOf", { enumerable: true, get: function () { return types_ts_1.runtimeTypeOf; } });
Object.defineProperty(exports, "validateTypedInitializer", { enumerable: true, get: function () { return types_ts_1.validateTypedInitializer; } });
var diagnostics_ts_1 = require("./diagnostics.js");
Object.defineProperty(exports, "assertValidAst", { enumerable: true, get: function () { return diagnostics_ts_1.assertValidAst; } });
Object.defineProperty(exports, "classifyParseError", { enumerable: true, get: function () { return diagnostics_ts_1.classifyParseError; } });
Object.defineProperty(exports, "containsReadonlyPropMutation", { enumerable: true, get: function () { return diagnostics_ts_1.containsReadonlyPropMutation; } });
Object.defineProperty(exports, "diagnose", { enumerable: true, get: function () { return diagnostics_ts_1.diagnose; } });
Object.defineProperty(exports, "diagnosticFromError", { enumerable: true, get: function () { return diagnostics_ts_1.diagnosticFromError; } });
Object.defineProperty(exports, "formatDiagnostic", { enumerable: true, get: function () { return diagnostics_ts_1.formatDiagnostic; } });
Object.defineProperty(exports, "isHydrationStrategy", { enumerable: true, get: function () { return diagnostics_ts_1.isHydrationStrategy; } });
Object.defineProperty(exports, "isRuntimeTarget", { enumerable: true, get: function () { return diagnostics_ts_1.isRuntimeTarget; } });
Object.defineProperty(exports, "positionAt", { enumerable: true, get: function () { return diagnostics_ts_1.positionAt; } });
__exportStar(require("./spec.js"), exports);
var versioning_ts_1 = require("./versioning.js");
Object.defineProperty(exports, "WRN_SYNTAX_VERSION", { enumerable: true, get: function () { return versioning_ts_1.WRN_SYNTAX_VERSION; } });
Object.defineProperty(exports, "WRN_SYNTAX_FEATURES", { enumerable: true, get: function () { return versioning_ts_1.WRN_SYNTAX_FEATURES; } });
Object.defineProperty(exports, "createSourceRange", { enumerable: true, get: function () { return versioning_ts_1.createSourceRange; } });
Object.defineProperty(exports, "sliceSource", { enumerable: true, get: function () { return versioning_ts_1.sliceSource; } });
Object.defineProperty(exports, "diagnosticSummary", { enumerable: true, get: function () { return versioning_ts_1.diagnosticSummary; } });
Object.defineProperty(exports, "supportsSyntaxFeature", { enumerable: true, get: function () { return versioning_ts_1.supportsSyntaxFeature; } });
var v060_ts_1 = require("./v060.js");
Object.defineProperty(exports, "parseComputedDeclarations", { enumerable: true, get: function () { return v060_ts_1.parseComputedDeclarations; } });
Object.defineProperty(exports, "parseOutputs", { enumerable: true, get: function () { return v060_ts_1.parseOutputs; } });
Object.defineProperty(exports, "parsePersist", { enumerable: true, get: function () { return v060_ts_1.parsePersist; } });
Object.defineProperty(exports, "parseRuntimeFunctions", { enumerable: true, get: function () { return v060_ts_1.parseRuntimeFunctions; } });
Object.defineProperty(exports, "parseStateDeclarations", { enumerable: true, get: function () { return v060_ts_1.parseStateDeclarations; } });
Object.defineProperty(exports, "parseStoreLifecycle", { enumerable: true, get: function () { return v060_ts_1.parseStoreLifecycle; } });
Object.defineProperty(exports, "parseStructuredImports", { enumerable: true, get: function () { return v060_ts_1.parseStructuredImports; } });
Object.defineProperty(exports, "stripRuntimeFunctionModifiers", { enumerable: true, get: function () { return v060_ts_1.stripRuntimeFunctionModifiers; } });

},
"packages/syntax/src/parser.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParseError = exports.VOID_ELEMENTS = void 0;
exports.parse = parse;
exports.parseHtmlView = parseHtmlView;
const spec_ts_1 = require("./spec.js");
/**
 * Recursive-descent parser for `.wrn`, producing a small AST.
 *
 * Grammar (subset of the vision, but real):
 *
 *   page <Name> {
 *     types { <TypeScript declarations> }
 *     props { <ident>: <type> [= <expr>] } // no default means required
 *     state <ident>: <type> = <expr>       // type annotation is optional
 *     view { <html> }                   // plain HTML (see parseHtmlView)
 *     seo { title = "Home" description = "..." }
 *     ssr { api <name> <METHOD> <path> { <render js> } functions { <raw js> } }
 *     client { api <name> <METHOD> <path> { <render js> } functions { <raw js> } }
 *     style { <raw css> }               // zero or more, inlined with the page
 *     functions { <raw js> }            // zero or more, shared helpers
 *     api <METHOD> <path> { <raw js> }  // zero or more
 *     realtime <name> { on <evt>(<args>) { <raw js> } * }  // zero or more
 *   }
 *
 * The `view` block is written as ordinary HTML — nothing new to learn. Text may
 * contain `{expr}` interpolation, attributes may be hyphenated (`data-*`), and
 * `@event="..."` declares a client event binding. See `parseHtmlView`.
 */
const tokenizer_ts_1 = require("./tokenizer.js");
const types_ts_1 = require("./types.js");
const v060_ts_1 = require("./v060.js");
/**
 * HTML void elements: they have no children and no closing tag.
 * @see https://html.spec.whatwg.org/multipage/syntax.html#void-elements
 */
exports.VOID_ELEMENTS = new Set([
    "area",
    "base",
    "br",
    "col",
    "embed",
    "hr",
    "img",
    "input",
    "link",
    "meta",
    "param",
    "source",
    "track",
    "wbr",
]);
class ParseError extends Error {
    code;
    offset;
    constructor(message, code = "WRN-PARSE-001") {
        super(message);
        this.name = "ParseError";
        this.code = code;
        const match = /offset\s+(\d+)/i.exec(message);
        this.offset = match ? Number(match[1]) : undefined;
    }
}
exports.ParseError = ParseError;
function parseSeoBlock(body) {
    const out = {};
    const pair = /([A-Za-z][A-Za-z0-9_-]*)\s*=\s*(?:"((?:\\.|[^"\\])*)"|'((?:\\.|[^'\\])*)'|([^\n;]+))/g;
    for (const match of body.matchAll(pair)) {
        const key = match[1];
        const rawValue = match[2] ?? match[3] ?? match[4] ?? "";
        out[key] = unescapeSeoValue(rawValue.trim());
    }
    return out;
}
function unescapeSeoValue(value) {
    return value.replace(/\\(["'\\nrt])/g, (_match, ch) => {
        if (ch === "n")
            return "\n";
        if (ch === "r")
            return "\r";
        if (ch === "t")
            return "\t";
        return ch;
    });
}
function parse(source) {
    const lx = new tokenizer_ts_1.Lexer(source);
    const imports = [];
    const importPattern = /import\s+(?:type\s+)?(?:[\s\S]*?\s+from\s+)?["'][^"'\r\n]+["']\s*;?/y;
    while (true) {
        while (/\s/u.test(source[lx.pos] ?? ""))
            lx.pos++;
        if (source.startsWith("//", lx.pos)) {
            while (lx.pos < source.length && source[lx.pos] !== "\n")
                lx.pos++;
            continue;
        }
        importPattern.lastIndex = lx.pos;
        const statement = importPattern.exec(source);
        if (!statement)
            break;
        imports.push(statement[0].trim());
        lx.pos = importPattern.lastIndex;
    }
    const expect = (type) => {
        const t = lx.next();
        if (t.type !== type) {
            throw new ParseError(`Expected ${type} but got '${t.value || t.type}' at offset ${t.pos}`);
        }
        return t;
    };
    const expectKeyword = (kw) => {
        const t = lx.next();
        if (t.type !== "ident" || t.value !== kw) {
            throw new ParseError(`Expected '${kw}' but got '${t.value || t.type}' at offset ${t.pos}`);
        }
    };
    try {
        // A file may contain a page, component, layout, global store, or page store.
        const opener = lx.next();
        if (opener.type !== "ident" ||
            !["page", "component", "layout", "global"].includes(opener.value)) {
            throw new ParseError(`Expected 'page', 'component', 'layout', 'global store', or 'page store' but got '${opener.value || opener.type}' at offset ${opener.pos}`);
        }
        let kind;
        let storeKind;
        let name;
        if (opener.value === "global") {
            expectKeyword("store");
            kind = "global-store";
            storeKind = "global";
            name = expect("ident").value;
        }
        else if (opener.value === "page" &&
            lx.peek().type === "ident" &&
            lx.peek().value === "store") {
            lx.next();
            kind = "page-store";
            storeKind = "page";
            name = expect("ident").value;
        }
        else {
            kind = opener.value;
            name = expect("ident").value;
        }
        expect("lbrace");
        let layout;
        let layoutIsSymbol = false;
        let runtime;
        let renderMode;
        let hydrate;
        const props = [];
        const events = [];
        const outputs = [];
        const types = [];
        const states = [];
        const computed = [];
        const effects = [];
        const loads = [];
        const actions = [];
        const security = {};
        const cache = {};
        const navigation = {};
        const seo = {};
        const view = [];
        const styles = [];
        const functions = [];
        const runtimeFunctions = [];
        const dataApis = [];
        const modeFunctions = [];
        const lifecycle = {};
        let storeLifecycle = {};
        let persist;
        const watches = [];
        const apis = [];
        const realtimes = [];
        while (lx.peek().type !== "rbrace") {
            const kw = lx.peek();
            if (kw.type === "eof")
                throw new ParseError(`Unexpected end of input inside ${kind}`);
            if (kw.type !== "ident") {
                throw new ParseError(`Expected a ${kind} member keyword at offset ${kw.pos}`);
            }
            switch (kw.value) {
                case "layout": {
                    // layout = "public" — selects app/layouts/<name>.wrn for this page.
                    lx.next();
                    expect("eq");
                    const layoutToken = lx.next();
                    if (layoutToken.type !== "string" && layoutToken.type !== "ident") {
                        throw new ParseError(`Expected a layout string or imported symbol at offset ${layoutToken.pos}`);
                    }
                    layout = layoutToken.value;
                    layoutIsSymbol = layoutToken.type === "ident";
                    break;
                }
                case "runtime": {
                    lx.next();
                    expect("eq");
                    const value = expect("string").value;
                    if (!spec_ts_1.WRN_RUNTIME_TARGETS.includes(value)) {
                        throw new ParseError(`Unknown runtime target '${value}' at offset ${kw.pos}`, "WRN-RUNTIME-TARGET");
                    }
                    runtime = value;
                    break;
                }
                case "render": {
                    lx.next();
                    expect("eq");
                    const value = expect("string").value;
                    if (!["static", "server", "hybrid", "client", "partial-static"].includes(value))
                        throw new ParseError(`Unknown render mode '${value}' at offset ${kw.pos}`, "WRN-RENDER-MODE");
                    renderMode = value;
                    break;
                }
                case "hydrate": {
                    lx.next();
                    expect("eq");
                    const value = expect("string").value;
                    hydrate = value === "never" ? "none" : value;
                    break;
                }
                case "props": {
                    // props { name: Type = <default>; @event name = function }
                    lx.next();
                    expect("lbrace");
                    while (true) {
                        if (lx.startsWithBlockComment()) {
                            throw new ParseError("Block comments are not allowed inside props {}; use // line comments instead", "WRN-PROPS-BLOCK-COMMENT");
                        }
                        if (lx.peek().type === "rbrace")
                            break;
                        const t = lx.peek();
                        if (t.type === "eof")
                            throw new ParseError("Unexpected end of input inside props");
                        if (t.type === "at") {
                            lx.next();
                            const declarationKind = expect("ident");
                            if (declarationKind.value !== "event") {
                                throw new ParseError(`Expected '@event' but got '@${declarationKind.value}' at offset ${declarationKind.pos}`);
                            }
                            const eventName = expect("ident").value;
                            expect("eq");
                            const marker = lx.readPropInitializer();
                            if (marker !== "function") {
                                throw new ParseError(`Event '${eventName}' must be declared as '@event ${eventName} = function'`);
                            }
                            events.push({ name: eventName });
                            continue;
                        }
                        if (t.type !== "ident") {
                            throw new ParseError(`Expected a prop name at offset ${t.pos}`);
                        }
                        const pName = expect("ident").value;
                        const optional = lx.peek().type === "question" ? (lx.next(), true) : false;
                        let valueType;
                        let hasDefault = false;
                        if (lx.peek().type === "colon") {
                            lx.next();
                            const annotation = lx.readTypeAnnotation();
                            valueType = annotation.type;
                            hasDefault = annotation.hasDefault;
                        }
                        else {
                            expect("eq");
                            hasDefault = true;
                        }
                        const defaultValue = hasDefault ? lx.readPropInitializer() : "undefined";
                        props.push({
                            name: pName,
                            valueType,
                            required: !hasDefault && !optional,
                            default: defaultValue,
                        });
                    }
                    expect("rbrace");
                    break;
                }
                case "state": {
                    lx.next();
                    if (lx.peek().type === "lbrace") {
                        const grouped = (0, v060_ts_1.parseStateDeclarations)(lx.readBalancedBraces(), "shared");
                        states.push(...grouped);
                        break;
                    }
                    const sName = expect("ident").value;
                    let valueType;
                    if (lx.peek().type === "colon") {
                        lx.next();
                        const annotation = lx.readTypeAnnotation();
                        valueType = annotation.type;
                        if (!annotation.hasDefault)
                            throw new ParseError(`State '${sName}' requires an initializer`);
                    }
                    else {
                        expect("eq");
                    }
                    states.push({
                        name: sName,
                        valueType,
                        expr: lx.readPropInitializer(),
                        runtime: "shared",
                    });
                    break;
                }
                case "computed": {
                    lx.next();
                    if (lx.peek().type === "lbrace") {
                        computed.push(...(0, v060_ts_1.parseComputedDeclarations)(lx.readBalancedBraces()));
                    }
                    else {
                        const cName = expect("ident").value;
                        let valueType;
                        if (lx.peek().type === "colon") {
                            lx.next();
                            const annotation = lx.readTypeAnnotation();
                            valueType = annotation.type;
                            if (!annotation.hasDefault)
                                throw new ParseError(`Computed '${cName}' requires an expression`);
                        }
                        else
                            expect("eq");
                        computed.push({ name: cName, valueType, expr: lx.readPropInitializer() });
                    }
                    break;
                }
                case "outputs": {
                    lx.next();
                    try {
                        outputs.push(...(0, v060_ts_1.parseOutputs)(lx.readBalancedBraces()));
                    }
                    catch (error) {
                        throw new ParseError(error instanceof Error ? error.message : String(error), "WRN-OUTPUT-DECLARATION");
                    }
                    break;
                }
                case "effect": {
                    lx.next();
                    effects.push({ body: lx.readBalancedBraces() });
                    break;
                }
                case "types": {
                    lx.next();
                    types.push(lx.readBalancedBraces());
                    break;
                }
                case "view": {
                    lx.next();
                    expect("lbrace");
                    // The view body is plain HTML. Parse it straight off the source
                    // (the token lexer isn't used for markup), then resume after the
                    // block's closing `}`.
                    const { nodes, endPos } = parseHtmlView(lx.src, lx.pos);
                    view.push(...nodes);
                    lx.pos = endPos;
                    expect("rbrace");
                    break;
                }
                case "seo": {
                    lx.next();
                    Object.assign(seo, parseSeoBlock(lx.readBalancedBraces()));
                    break;
                }
                case "security": {
                    lx.next();
                    Object.assign(security, parseSeoBlock(lx.readBalancedBraces()));
                    break;
                }
                case "navigation": {
                    lx.next();
                    Object.assign(navigation, parseSeoBlock(lx.readBalancedBraces()));
                    break;
                }
                case "cache": {
                    lx.next();
                    Object.assign(cache, parseSeoBlock(lx.readBalancedBraces()));
                    break;
                }
                case "load": {
                    lx.next();
                    const first = expect("ident");
                    const mode = first.value === "client" ? "client" : "server";
                    const name = first.value === "server" || first.value === "client"
                        ? lx.peek().type === "ident"
                            ? expect("ident").value
                            : undefined
                        : first.value;
                    const dependsOn = [];
                    let deferred = false;
                    while (lx.peek().type === "ident") {
                        if (lx.peek().value === "defer") {
                            lx.next();
                            deferred = true;
                            continue;
                        }
                        if (lx.peek().value !== "after")
                            break;
                        lx.next();
                        dependsOn.push(expect("ident").value);
                        while (lx.peek().type === "comma") {
                            lx.next();
                            dependsOn.push(expect("ident").value);
                        }
                    }
                    loads.push({
                        mode,
                        name,
                        ...(dependsOn.length ? { dependsOn } : {}),
                        ...(deferred ? { deferred: true } : {}),
                        body: lx.readBalancedBraces(),
                    });
                    break;
                }
                case "action": {
                    lx.next();
                    const actionName = expect("ident").value;
                    const args = [];
                    if (lx.peek().type === "lparen") {
                        lx.next();
                        while (lx.peek().type !== "rparen") {
                            args.push(expect("ident").value);
                            if (lx.peek().type === "comma")
                                lx.next();
                        }
                        expect("rparen");
                    }
                    let schema;
                    if (lx.peek().type === "ident" && lx.peek().value === "using") {
                        lx.next();
                        schema = expect("ident").value;
                    }
                    actions.push({ name: actionName, args, schema, body: lx.readBalancedBraces() });
                    break;
                }
                case "api": {
                    lx.next();
                    const method = expect("ident").value.toUpperCase();
                    const path = lx.readPath();
                    const body = lx.readBalancedBraces();
                    apis.push({ method, path, body });
                    break;
                }
                case "ssr":
                case "client":
                case "server": {
                    const rawMode = kw.value;
                    const mode = rawMode === "client" ? "client" : "ssr";
                    lx.next();
                    if ((rawMode === "client" || rawMode === "server") &&
                        lx.peek().type === "ident" &&
                        lx.peek().value === "state") {
                        lx.next();
                        if (lx.peek().type !== "lbrace")
                            throw new ParseError(`Expected a grouped ${rawMode} state block`);
                        states.push(...(0, v060_ts_1.parseStateDeclarations)(lx.readBalancedBraces(), rawMode));
                        break;
                    }
                    if (mode === "client" && lx.peek().type === "eq") {
                        lx.next();
                        hydrate = expect("string").value;
                        break;
                    }
                    expect("lbrace");
                    while (lx.peek().type !== "rbrace") {
                        const member = lx.peek();
                        if (member.type === "eof") {
                            throw new ParseError(`Unexpected end of input inside ${mode} block`);
                        }
                        if (member.type !== "ident") {
                            throw new ParseError(`Expected a ${mode} member keyword at offset ${member.pos}`);
                        }
                        switch (member.value) {
                            case "api": {
                                lx.next();
                                const name = expect("ident").value;
                                const method = expect("ident").value.toUpperCase();
                                const path = lx.readPath();
                                const body = lx.readBalancedBraces();
                                dataApis.push({ mode, name, method, path, body });
                                break;
                            }
                            case "functions": {
                                lx.next();
                                modeFunctions.push({ mode, body: lx.readBalancedBraces() });
                                break;
                            }
                            default:
                                throw new ParseError(`Unknown ${mode} member '${member.value}' at offset ${member.pos}`);
                        }
                    }
                    expect("rbrace");
                    break;
                }
                case "shared": {
                    lx.next();
                    const member = expect("ident");
                    if (member.value !== "state")
                        throw new ParseError(`Expected 'state' after shared at offset ${member.pos}`);
                    states.push(...(0, v060_ts_1.parseStateDeclarations)(lx.readBalancedBraces(), "shared"));
                    break;
                }
                case "realtime": {
                    lx.next();
                    const rName = expect("ident").value;
                    expect("lbrace");
                    const handlers = [];
                    while (lx.peek().type !== "rbrace") {
                        expectKeyword("on");
                        const event = expect("ident").value;
                        expect("lparen");
                        const args = [];
                        while (lx.peek().type !== "rparen") {
                            args.push(expect("ident").value);
                            if (lx.peek().type === "comma")
                                lx.next();
                        }
                        expect("rparen");
                        handlers.push({ event, args, body: lx.readBalancedBraces() });
                    }
                    expect("rbrace");
                    realtimes.push({ name: rName, handlers });
                    break;
                }
                case "style": {
                    lx.next();
                    styles.push(lx.readBalancedBraces());
                    break;
                }
                case "lifecycle": {
                    lx.next();
                    const body = lx.readBalancedBraces();
                    if (kind === "global-store" || kind === "page-store") {
                        storeLifecycle = (0, v060_ts_1.parseStoreLifecycle)(body);
                        const allowedStoreHooks = new Set(["serverInit", "clientInit", "hydrate", "dispose"]);
                        const hookLexer = new tokenizer_ts_1.Lexer(body);
                        while (hookLexer.peek().type !== "eof") {
                            const token = hookLexer.next();
                            if (token.type !== "ident") {
                                throw new ParseError(`Expected a lifecycle hook at offset ${token.pos}`);
                            }
                            if (!allowedStoreHooks.has(token.value)) {
                                throw new ParseError(`Unknown store lifecycle hook '${token.value}'`);
                            }
                            hookLexer.readBalancedBraces();
                        }
                    }
                    else {
                        const allowedComponentHooks = new Set([
                            "mount",
                            "update",
                            "unmount",
                            "clientInit",
                            "dispose",
                        ]);
                        const hookLexer = new tokenizer_ts_1.Lexer(body);
                        while (hookLexer.peek().type !== "eof") {
                            const token = hookLexer.next();
                            if (token.type !== "ident") {
                                throw new ParseError(`Expected a lifecycle hook at offset ${token.pos}`);
                            }
                            if (!allowedComponentHooks.has(token.value)) {
                                throw new ParseError(`Unknown lifecycle hook '${token.value}'`);
                            }
                            const hookBody = hookLexer.readBalancedBraces();
                            const hook = token.value === "clientInit"
                                ? "mount"
                                : token.value === "dispose"
                                    ? "unmount"
                                    : token.value;
                            if (lifecycle[hook] !== undefined) {
                                throw new ParseError(`Duplicate lifecycle hook '${hook}'`);
                            }
                            lifecycle[hook] = hookBody;
                        }
                    }
                    break;
                }
                case "watch": {
                    lx.next();
                    const stateName = expect("ident").value;
                    const body = lx.readBalancedBraces();
                    watches.push({
                        state: stateName,
                        body,
                    });
                    break;
                }
                case "functions": {
                    lx.next();
                    const body = lx.readBalancedBraces();
                    functions.push(body);
                    try {
                        runtimeFunctions.push(...(0, v060_ts_1.parseRuntimeFunctions)(body));
                    }
                    catch (error) {
                        throw new ParseError(error instanceof Error ? error.message : String(error), "WRN-FUNCTION-DECLARATION");
                    }
                    break;
                }
                case "persist": {
                    lx.next();
                    persist = (0, v060_ts_1.parsePersist)(lx.readBalancedBraces());
                    break;
                }
                default:
                    throw new ParseError(`Unknown page member '${kw.value}' at offset ${kw.pos}`);
            }
        }
        expect("rbrace");
        const declaredStates = new Set(states.map((state) => state.name));
        if (declaredStates.has("page")) {
            throw new ParseError("State name 'page' collides with the WRN 'page' keyword; choose another state name", "WRN-STATE-RESERVED-NAME");
        }
        for (const watcher of watches) {
            if (!declaredStates.has(watcher.state)) {
                throw new ParseError(`Cannot watch undeclared state '${watcher.state}'`);
            }
        }
        for (const prop of props) {
            const problem = (0, types_ts_1.validateTypedInitializer)(`Prop '${prop.name}'`, prop.valueType, prop.default);
            if (problem)
                throw new ParseError(problem);
        }
        for (const state of states) {
            const problem = (0, types_ts_1.validateTypedInitializer)(`State '${state.name}'`, state.valueType, state.expr);
            if (problem)
                throw new ParseError(problem);
        }
        const symbols = new Set();
        for (const declaration of [...props, ...states, ...computed]) {
            if (symbols.has(declaration.name)) {
                throw new ParseError(`Duplicate symbol '${declaration.name}'`, "WRN-SYMBOL-DUPLICATE");
            }
            symbols.add(declaration.name);
        }
        const outputNames = new Set();
        for (const output of outputs) {
            if (outputNames.has(output.name))
                throw new ParseError(`Duplicate output '${output.name}'`, "WRN-OUTPUT-DUPLICATE");
            outputNames.add(output.name);
        }
        const functionKeys = new Set();
        for (const fn of runtimeFunctions) {
            const key = `${fn.runtime}:${fn.name}`;
            if (functionKeys.has(key))
                throw new ParseError(`Duplicate ${fn.runtime} function '${fn.name}'`, "WRN-FUNCTION-DUPLICATE");
            functionKeys.add(key);
        }
        const namedLoads = new Map(loads.filter((load) => load.name).map((load) => [load.name, load]));
        for (const load of namedLoads.values()) {
            for (const dependency of load.dependsOn ?? []) {
                const dependencyLoad = namedLoads.get(dependency);
                if (!dependencyLoad)
                    throw new ParseError(`Load '${load.name}' depends on unknown load '${dependency}'`, "WRN-LOAD-DEPENDENCY");
                if (load.mode === "server" &&
                    !load.deferred &&
                    (dependencyLoad.mode !== "server" || dependencyLoad.deferred))
                    throw new ParseError(`Server load '${load.name}' cannot depend on deferred/client load '${dependency}'`, "WRN-LOAD-PHASE");
            }
        }
        const visiting = new Set();
        const visited = new Set();
        const visitLoad = (name) => {
            if (visiting.has(name))
                throw new ParseError(`Load dependency cycle includes '${name}'`, "WRN-LOAD-CYCLE");
            if (visited.has(name))
                return;
            visiting.add(name);
            for (const dependency of namedLoads.get(name)?.dependsOn ?? [])
                visitLoad(dependency);
            visiting.delete(name);
            visited.add(name);
        };
        for (const name of namedLoads.keys())
            visitLoad(name);
        return {
            type: "page",
            imports,
            structuredImports: (0, v060_ts_1.parseStructuredImports)(imports),
            kind,
            storeKind,
            name,
            layout,
            layoutIsSymbol,
            runtime,
            renderMode,
            hydrate,
            cache,
            props,
            events,
            outputs,
            types,
            states,
            computed,
            effects,
            loads,
            actions,
            security,
            navigation,
            seo,
            view,
            styles,
            functions,
            runtimeFunctions,
            dataApis,
            modeFunctions,
            lifecycle,
            storeLifecycle,
            persist,
            watches,
            apis,
            realtimes,
        };
    }
    catch (err) {
        if (err instanceof tokenizer_ts_1.LexError)
            throw new ParseError(err.message);
        throw err;
    }
}
/**
 * Parse the body of a `view { ... }` block as plain HTML.
 *
 * `src` is the whole `.wrn` source; `pos` points just past the view block's
 * opening `{`. Returns the parsed nodes plus the index of the block's closing
 * `}` (left for the caller to consume). It is intentionally lenient — you write
 * markup the way you already know:
 *
 *   - `<tag attr="v" @event="expr">children</tag>` — elements with attributes
 *   - `<tag/>` and HTML void elements (`<br>`, `<img>`, …) — no closing tag
 *   - text may contain `{expr}` interpolation, kept verbatim for the runtime
 *   - `@event="..."` becomes a client event binding; hyphenated names are fine
 *   - `<!-- comments -->` are dropped
 *
 * `{` and `}` in text are reserved for interpolation; a lone `<` that isn't a
 * tag is treated as literal text.
 */
function parseHtmlView(src, pos) {
    let i = pos;
    const isNameStart = (c) => /[A-Za-z_]/.test(c);
    const isTagNamePart = (c) => /[A-Za-z0-9_$:.-]/.test(c);
    const isWs = (c) => c === " " || c === "\t" || c === "\n" || c === "\r";
    const fail = (msg) => {
        throw new ParseError(`${msg} at offset ${i}`);
    };
    const skipWs = () => {
        while (i < src.length && isWs(src[i]))
            i++;
    };
    /** Read a `{...}` interpolation (brace-balanced and quote-aware), braces included. */
    const readInterpolation = () => {
        const start = i;
        let depth = 0;
        let quote = null;
        for (; i < src.length; i++) {
            const char = src[i];
            if (quote) {
                if (char === "\\" && i + 1 < src.length) {
                    i++;
                    continue;
                }
                if (char === quote)
                    quote = null;
                continue;
            }
            if (char === '"' || char === "'" || char === "`") {
                quote = char;
                continue;
            }
            if (char === "{")
                depth++;
            else if (char === "}" && --depth === 0) {
                i++;
                return src.slice(start, i);
            }
        }
        return fail("Unterminated `{` interpolation in view");
    };
    const readQuoted = () => {
        const quote = src[i];
        if (quote !== '"' && quote !== "'")
            return fail("Expected a quoted attribute value");
        i++;
        const start = i;
        while (i < src.length && src[i] !== quote)
            i++;
        if (i >= src.length)
            return fail("Unterminated attribute value");
        const value = src.slice(start, i);
        i++; // closing quote
        return value;
    };
    const readTagName = () => {
        if (i >= src.length || !isNameStart(src[i])) {
            return fail("Expected a tag name");
        }
        const start = i++;
        while (i < src.length && isTagNamePart(src[i])) {
            i++;
        }
        return src.slice(start, i);
    };
    const readAttributeName = () => {
        if (i >= src.length) {
            return fail("Expected an attribute name");
        }
        const start = i;
        while (i < src.length) {
            const char = src[i];
            const next = src[i + 1];
            if (char === "=" ||
                char === ">" ||
                char === '"' ||
                char === "'" ||
                char === " " ||
                char === "\t" ||
                char === "\n" ||
                char === "\r" ||
                (char === "/" && next === ">")) {
                break;
            }
            i++;
        }
        if (i === start) {
            return fail("Expected an attribute name");
        }
        return src.slice(start, i);
    };
    const parseTag = () => {
        i++; // consume '<'
        const tag = readTagName();
        const attrs = [];
        for (;;) {
            skipWs();
            const c = src[i];
            if (c === undefined)
                return fail(`Unterminated <${tag}> tag`);
            if (c === ">") {
                i++;
                break;
            }
            if (c === "/" && src[i + 1] === ">") {
                i += 2;
                return { type: "element", tag, attrs, children: [] };
            }
            if (c === "@") {
                i++;
                const name = readAttributeName();
                skipWs();
                if (src[i] !== "=")
                    return fail(`Expected '=' after @${name}`);
                i++;
                skipWs();
                attrs.push({ name, value: readQuoted(), event: true });
                continue;
            }
            const name = readAttributeName();
            skipWs();
            if (src[i] === "=") {
                i++;
                skipWs();
                const value = src[i] === '"' || src[i] === "'"
                    ? readQuoted()
                    : src[i] === "{"
                        ? readInterpolation()
                        : fail(`Expected a quoted value or {...} expression after '${name}='`);
                attrs.push({ name, value, event: false });
            }
            else {
                attrs.push({ name, value: "", event: false, boolean: true });
            }
        }
        if (exports.VOID_ELEMENTS.has(tag.toLowerCase())) {
            return { type: "element", tag, attrs, children: [] };
        }
        const children = parseNodeList("element");
        // parseNodeList stops at the parent's closing tag `</`.
        if (src[i] !== "<" || src[i + 1] !== "/")
            return fail(`Expected </${tag}>`);
        i += 2;
        skipWs();
        const close = readTagName();
        if (close !== tag)
            return fail(`Mismatched </${close}>, expected </${tag}>`);
        skipWs();
        if (src[i] !== ">")
            return fail(`Expected '>' to close </${tag}>`);
        i++;
        return { type: "element", tag, attrs, children };
    };
    const EACH_HEADER = /^\{#each\s+([\s\S]+?)\s+as\s+([A-Za-z_$][\w$]*)\s*(?:,\s*([A-Za-z_$][\w$]*))?(?:\s+key\s+([\s\S]+?))?\s*\}$/;
    /** Parse `{#each <list> as <item>[, <index>] [key <expr>]} …body… {:empty} …empty… {/each}`. */
    function parseEach() {
        const header = readInterpolation(); // reads the full `{#each …}`
        const m = EACH_HEADER.exec(header);
        if (!m)
            return fail(`Invalid {#each …} header: ${header}`);
        const list = m[1].trim();
        const item = m[2];
        const index = m[3];
        const key = m[4]?.trim();
        const body = parseNodeList("each"); // stops at {:empty} or {/each}
        let empty = [];
        if (src.startsWith("{:empty}", i)) {
            i += "{:empty}".length;
            empty = parseNodeList("each"); // stops at {/each}
        }
        if (!src.startsWith("{/each}", i))
            return fail("Expected `{/each}` to close `{#each}`");
        i += "{/each}".length;
        return { type: "each", list, item, index, key, body, empty };
    }
    /** Parse `{#if <expr>} … {:else if <expr>} … {:else} … {/if}`. */
    function parseIf() {
        const header = readInterpolation(); // reads the full `{#if …}`
        const m = /^\{#if\s+([\s\S]+?)\s*\}$/.exec(header);
        if (!m)
            return fail(`Invalid {#if …} header: ${header}`);
        const branches = [
            { cond: m[1].trim(), body: parseNodeList("if") },
        ];
        for (;;) {
            if (src.startsWith("{:else if", i)) {
                const h = readInterpolation();
                const mm = /^\{:else if\s+([\s\S]+?)\s*\}$/.exec(h);
                if (!mm)
                    return fail(`Invalid {:else if …}: ${h}`);
                branches.push({ cond: mm[1].trim(), body: parseNodeList("if") });
                continue;
            }
            if (src.startsWith("{:else}", i)) {
                i += "{:else}".length;
                branches.push({ cond: null, body: parseNodeList("if") });
                continue;
            }
            break;
        }
        if (!src.startsWith("{/if}", i))
            return fail("Expected `{/if}` to close `{#if}`");
        i += "{/if}".length;
        return { type: "if", branches };
    }
    /**
     * Parse a run of nodes. `mode` sets the terminator:
     *   - "root":    stops at the view block's closing `}`
     *   - "element": stops at the parent element's closing tag (`</`)
     *   - "each":    stops (without consuming) at `{:empty}` or `{/each}`
     *   - "if":      stops (without consuming) at `{:else …}` or `{/if}`
     * `{#each …}` and `{#if …}` start nested blocks in any mode.
     */
    function parseNodeList(mode) {
        const nodes = [];
        let text = "";
        const flush = () => {
            if (text.length > 0) {
                nodes.push({ type: "text", value: text });
                text = "";
            }
        };
        for (;;) {
            if (i >= src.length) {
                return mode === "root"
                    ? fail("Unexpected end of view (missing `}`)")
                    : fail("Unclosed block");
            }
            const c = src[i];
            if (c === "<") {
                const next = src[i + 1];
                if (next === "/") {
                    flush();
                    break; // parent's closing tag
                }
                if (src.startsWith("<!--", i)) {
                    const end = src.indexOf("-->", i + 4);
                    i = end === -1 ? src.length : end + 3;
                    continue;
                }
                if (next !== undefined && (isNameStart(next) || next === "!")) {
                    flush();
                    nodes.push(parseTag());
                    continue;
                }
                // A lone `<` that doesn't start a tag: treat as literal text.
                text += c;
                i++;
                continue;
            }
            if (c === "{") {
                if (src.startsWith("{#each", i)) {
                    flush();
                    nodes.push(parseEach());
                    continue;
                }
                if (src.startsWith("{#if", i)) {
                    flush();
                    nodes.push(parseIf());
                    continue;
                }
                if (mode === "each" && (src.startsWith("{:empty}", i) || src.startsWith("{/each}", i))) {
                    flush();
                    break; // loop-section terminator; left for parseEach
                }
                if (mode === "if" && (src.startsWith("{:else", i) || src.startsWith("{/if}", i))) {
                    flush();
                    break; // conditional-section terminator; left for parseIf
                }
                text += readInterpolation();
                continue;
            }
            if (c === "}" && mode === "root") {
                flush();
                break; // view terminator; leave `}` for the caller
            }
            text += c;
            i++;
        }
        return nodes;
    }
    const nodes = parseNodeList("root");
    return { nodes, endPos: i };
}

},
"packages/syntax/src/spec.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WRN_DIAGNOSTIC_CODES = exports.WRN_RUNTIME_TARGETS = exports.WRN_HYDRATION_STRATEGIES = exports.WRN_ROOT_MEMBERS = exports.WRN_ROOT_KINDS = exports.WRN_LANGUAGE_VERSION = void 0;
/** Canonical, machine-readable WRN language capabilities. */
exports.WRN_LANGUAGE_VERSION = "0.6";
exports.WRN_ROOT_KINDS = [
    "page",
    "component",
    "layout",
    "global-store",
    "page-store",
];
exports.WRN_ROOT_MEMBERS = [
    "layout",
    "runtime",
    "hydrate",
    "client",
    "types",
    "props",
    "outputs",
    "state",
    "shared",
    "server",
    "computed",
    "effect",
    "watch",
    "lifecycle",
    "view",
    "seo",
    "security",
    "load",
    "action",
    "api",
    "ssr",
    "realtime",
    "style",
    "functions",
    "persist",
];
exports.WRN_HYDRATION_STRATEGIES = ["load", "idle", "visible", "interaction", "none"];
exports.WRN_RUNTIME_TARGETS = [
    "server",
    "client",
    "universal",
    "edge",
    "worker",
    "service-worker",
];
exports.WRN_DIAGNOSTIC_CODES = {
    parse: "WRN-PARSE-001",
    root: "WRN-PARSE-ROOT",
    member: "WRN-PARSE-MEMBER",
    propInitializer: "WRN-PROP-INITIALIZER",
    stateInitializer: "WRN-STATE-INITIALIZER",
    watchUndeclared: "WRN-WATCH-UNDECLARED",
    duplicateSymbol: "WRN-SYMBOL-DUPLICATE",
    invalidHydration: "WRN-HYDRATE-STRATEGY",
    invalidRuntime: "WRN-RUNTIME-TARGET",
    serverInteractive: "WRN-RUNTIME-SERVER-INTERACTIVE",
    accessibility: "WRN-A11Y-001",
    import: "WRN-IMPORT-001",
    function: "WRN-FUNCTION-001",
    client: "WRN-CLIENT-001",
    server: "WRN-SERVER-001",
    output: "WRN-OUTPUT-001",
    type: "WRN-TYPE-001",
    state: "WRN-STATE-001",
    component: "WRN-COMPONENT-001",
    template: "WRN-TEMPLATE-001",
    store: "WRN-STORE-001",
    persist: "WRN-PERSIST-001",
    rpc: "WRN-RPC-001",
    hydration: "WRN-HYDRATION-001",
    migration: "WRN-MIGRATION-001",
};

},
"packages/syntax/src/tokenizer.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
/**
 * Lexer for the `.wrn` language.
 *
 * `.wrn` mixes a small structural grammar (page/state/view/api/realtime) with
 * raw JavaScript bodies. A pure token stream can't represent the raw JS, so the
 * lexer is driven on demand by the parser: it yields structural tokens via
 * `next()`/`peek()`, and exposes `readBalancedBraces()`, `readPath()` and
 * `readToLineEnd()` for the parser to grab raw spans when grammar demands it.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.Lexer = exports.LexError = void 0;
class LexError extends Error {
}
exports.LexError = LexError;
const isWs = (c) => c === " " || c === "\t" || c === "\n" || c === "\r";
const isIdentStart = (c) => /[A-Za-z_]/.test(c);
const isIdentPart = (c) => /[A-Za-z0-9_]/.test(c);
class Lexer {
    src;
    pos = 0;
    constructor(src) {
        this.src = src;
    }
    /** Skip whitespace and `// line comments`. */
    skipTrivia() {
        const { src } = this;
        while (this.pos < src.length) {
            const c = src[this.pos];
            if (isWs(c)) {
                this.pos++;
                continue;
            }
            if (c === "/" && src[this.pos + 1] === "/") {
                while (this.pos < src.length && src[this.pos] !== "\n")
                    this.pos++;
                continue;
            }
            break;
        }
    }
    /** True when the next non-trivia characters open a block comment. */
    startsWithBlockComment() {
        this.skipTrivia();
        return this.src[this.pos] === "/" && this.src[this.pos + 1] === "*";
    }
    /** Read and consume the next structural token. */
    next() {
        this.skipTrivia();
        const { src } = this;
        const pos = this.pos;
        if (pos >= src.length)
            return { type: "eof", value: "", pos };
        const c = src[pos];
        switch (c) {
            case "{":
                this.pos++;
                return { type: "lbrace", value: c, pos };
            case "}":
                this.pos++;
                return { type: "rbrace", value: c, pos };
            case "(":
                this.pos++;
                return { type: "lparen", value: c, pos };
            case ")":
                this.pos++;
                return { type: "rparen", value: c, pos };
            case "@":
                this.pos++;
                return { type: "at", value: c, pos };
            case "=":
                this.pos++;
                return { type: "eq", value: c, pos };
            case ":":
                this.pos++;
                return { type: "colon", value: c, pos };
            case ",":
                this.pos++;
                return { type: "comma", value: c, pos };
            case "?":
                this.pos++;
                return { type: "question", value: c, pos };
            case '"':
            case "'":
                return this.readString(c, pos);
        }
        if (isIdentStart(c)) {
            let v = "";
            while (this.pos < src.length && isIdentPart(src[this.pos]))
                v += src[this.pos++];
            return { type: "ident", value: v, pos };
        }
        throw new LexError(`Unexpected character '${c}' at offset ${pos} (line ${this.lineAt(pos)})`);
    }
    /** Look at the next token without consuming it. */
    peek() {
        const save = this.pos;
        const t = this.next();
        this.pos = save;
        return t;
    }
    readString(quote, pos) {
        const { src } = this;
        let v = "";
        this.pos++; // opening quote
        while (this.pos < src.length) {
            const c = src[this.pos++];
            if (c === "\\") {
                const n = src[this.pos++];
                v += n === "n" ? "\n" : n === "t" ? "\t" : n;
                continue;
            }
            if (c === quote)
                return { type: "string", value: v, pos };
            v += c;
        }
        throw new LexError(`Unterminated string at offset ${pos}`);
    }
    /** Read a route path like `/users/[id]` up to whitespace or `{`. */
    readPath() {
        this.skipTrivia();
        const { src } = this;
        let v = "";
        while (this.pos < src.length && !isWs(src[this.pos]) && src[this.pos] !== "{") {
            v += src[this.pos++];
        }
        if (!v)
            throw new LexError(`Expected a path at offset ${this.pos}`);
        return v;
    }
    /**
     * Read a prop default initializer. The initializer may contain nested arrays,
     * objects, calls, strings, or template literals. At top level it ends at a
     * newline, the closing brace of the props block, or the next inline prop
     * declaration (`name = ...` / `name: Type = ...`).
     */
    readPropInitializer() {
        const { src } = this;
        while (this.pos < src.length && (src[this.pos] === " " || src[this.pos] === "\t")) {
            this.pos++;
        }
        const start = this.pos;
        let square = 0;
        let brace = 0;
        let paren = 0;
        let angle = 0;
        let quote = null;
        const atTopLevel = () => square === 0 && brace === 0 && paren === 0 && angle === 0;
        while (this.pos < src.length) {
            const c = src[this.pos];
            if (quote) {
                this.pos++;
                if (c === "\\" && this.pos < src.length) {
                    this.pos++;
                }
                else if (c === quote) {
                    quote = null;
                }
                continue;
            }
            if (c === '"' || c === "'" || c === "`") {
                quote = c;
                this.pos++;
                continue;
            }
            if (atTopLevel()) {
                if (c === "\n" || c === "\r" || c === "}")
                    break;
                if (c === " " || c === "\t") {
                    let look = this.pos;
                    while (look < src.length && (src[look] === " " || src[look] === "\t"))
                        look++;
                    const rest = src.slice(look);
                    if (/^[A-Za-z_][A-Za-z0-9_]*(?:\s*:[^=\r\n{}]+)?\s*=/.test(rest))
                        break;
                }
            }
            if (c === "[")
                square++;
            else if (c === "]" && square > 0)
                square--;
            else if (c === "{")
                brace++;
            else if (c === "}" && brace > 0)
                brace--;
            else if (c === "(")
                paren++;
            else if (c === ")" && paren > 0)
                paren--;
            else if (c === "<")
                angle++;
            else if (c === ">" && angle > 0)
                angle--;
            this.pos++;
        }
        const value = src.slice(start, this.pos).trim();
        if (!value)
            throw new LexError(`Expected a prop initializer at offset ${start}`);
        return value;
    }
    /** Read the rest of the current line (used for `state x = <expr>`). */
    readToLineEnd() {
        const { src } = this;
        let v = "";
        while (this.pos < src.length && src[this.pos] !== "\n")
            v += src[this.pos++];
        return v.trim();
    }
    /**
     * Read a TypeScript-style type annotation after `:`. Reading stops at a
     * top-level `=` or line ending, while nested object/tuple/generic syntax is
     * preserved. The optional `=` is consumed for the caller.
     */
    readTypeAnnotation() {
        const { src } = this;
        let value = "";
        let angle = 0;
        let square = 0;
        let brace = 0;
        let paren = 0;
        let quote = null;
        while (this.pos < src.length) {
            const c = src[this.pos];
            if (quote) {
                value += c;
                this.pos++;
                if (c === "\\" && this.pos < src.length)
                    value += src[this.pos++];
                else if (c === quote)
                    quote = null;
                continue;
            }
            if (c === '"' || c === "'" || c === "`") {
                quote = c;
                value += c;
                this.pos++;
                continue;
            }
            if (c === "}" && angle === 0 && square === 0 && brace === 0 && paren === 0)
                break;
            if (c === "<")
                angle++;
            else if (c === ">" && angle > 0)
                angle--;
            else if (c === "[")
                square++;
            else if (c === "]" && square > 0)
                square--;
            else if (c === "{")
                brace++;
            else if (c === "}" && brace > 0)
                brace--;
            else if (c === "(")
                paren++;
            else if (c === ")" && paren > 0)
                paren--;
            if (angle === 0 && square === 0 && brace === 0 && paren === 0) {
                if (c === " " || c === "\t") {
                    let look = this.pos;
                    while (look < src.length && (src[look] === " " || src[look] === "\t"))
                        look++;
                    if (/^[A-Za-z_][A-Za-z0-9_]*\??\s*:/.test(src.slice(look)))
                        break;
                }
                if (c === "=") {
                    this.pos++;
                    const type = value.trim();
                    if (!type)
                        throw new LexError(`Expected a type annotation at offset ${this.pos}`);
                    return { type, hasDefault: true };
                }
                if (c === "\n" || c === "\r")
                    break;
            }
            value += c;
            this.pos++;
        }
        const type = value.trim();
        if (!type)
            throw new LexError(`Expected a type annotation at offset ${this.pos}`);
        return { type, hasDefault: false };
    }
    /**
     * Read a `{ ... }` block and return its INNER text (no outer braces), with
     * brace counting that respects string and template literals so a `}` inside a
     * string doesn't end the block early.
     *
     * Comments are skipped as well. Without that, an apostrophe in ordinary
     * prose — `/* the panel's color *\/`, `// the Input's slot` — opened a
     * string that ran to the next apostrophe, swallowing every brace in between
     * and failing the whole component with "Unbalanced braces" pointing at the
     * block's opening line. Comments are where apostrophes actually occur, so
     * that error was almost always a false alarm.
     *
     * A `//` line comment is only recognised at the start of a line (after
     * whitespace), which is where every comment in a `.wrn` file is written.
     * Recognising it mid-line would break the far more common case of a bare
     * URL in view text, where `https://…` is not inside quotes.
     */
    readBalancedBraces() {
        this.skipTrivia();
        const { src } = this;
        if (src[this.pos] !== "{") {
            throw new LexError(`Expected '{' at offset ${this.pos}`);
        }
        const start = this.pos + 1;
        let depth = 0;
        let i = this.pos;
        let str = null;
        /** True while only whitespace has been seen since the last newline. */
        let atLineStart = false;
        for (; i < src.length; i++) {
            const c = src[i];
            if (str) {
                if (c === "\\") {
                    i++;
                    continue;
                }
                if (c === str)
                    str = null;
                continue;
            }
            if (c === "\n") {
                atLineStart = true;
                continue;
            }
            if (c === "/" && src[i + 1] === "*") {
                const close = src.indexOf("*/", i + 2);
                if (close === -1)
                    break; // unterminated: fall through to the error
                i = close + 1;
                atLineStart = false;
                continue;
            }
            if (atLineStart && c === "/" && src[i + 1] === "/") {
                const newline = src.indexOf("\n", i + 2);
                if (newline === -1)
                    break;
                i = newline - 1; // let the loop's own increment land on the newline
                continue;
            }
            if (c !== " " && c !== "\t" && c !== "\r")
                atLineStart = false;
            if (c === '"' || c === "'" || c === "`") {
                str = c;
                continue;
            }
            if (c === "{")
                depth++;
            else if (c === "}") {
                depth--;
                if (depth === 0) {
                    this.pos = i + 1;
                    return src.slice(start, i);
                }
            }
        }
        throw new LexError(`Unbalanced braces starting at offset ${this.pos}`);
    }
    lineAt(pos) {
        let line = 1;
        for (let i = 0; i < pos && i < this.src.length; i++) {
            if (this.src[i] === "\n")
                line++;
        }
        return line;
    }
}
exports.Lexer = Lexer;

},
"packages/syntax/src/types.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
/** Utilities shared by typed `.wrn` parsing, validation, and code generation. */
Object.defineProperty(exports, "__esModule", { value: true });
exports.runtimeTypeOf = runtimeTypeOf;
exports.inferredRuntimeType = inferredRuntimeType;
exports.validateTypedInitializer = validateTypedInitializer;
exports.eraseFunctionTypes = eraseFunctionTypes;
function runtimeTypeOf(annotation) {
    if (!annotation)
        return "unknown";
    const type = annotation.trim().replace(/^readonly\s+/, "");
    const unionParts = type.split("|").map((part) => part.trim());
    const concreteParts = unionParts.filter((part) => !/^(?:null|undefined)$/.test(part));
    if (/^(?:string|String)(?:\s*\|\s*(?:null|undefined))*$/.test(type) ||
        (concreteParts.length > 0 && concreteParts.every((part) => /^(?:"[^"]*"|'[^']*')$/.test(part))))
        return "string";
    if (/^(?:number|Number)(?:\s*\|\s*(?:null|undefined))*$/.test(type) ||
        (concreteParts.length > 0 &&
            concreteParts.every((part) => /^-?(?:\d+\.?\d*|\.\d+)$/.test(part))))
        return "number";
    if (/^(?:boolean|Boolean)(?:\s*\|\s*(?:null|undefined))*$/.test(type) ||
        (concreteParts.length > 0 && concreteParts.every((part) => /^(?:true|false)$/.test(part))))
        return "boolean";
    if (/^bigint(?:\s*\|\s*(?:null|undefined))*$/.test(type))
        return "bigint";
    if (/^(?:Array\s*<|ReadonlyArray\s*<|.+\[\])/.test(type) || /^\[/.test(type))
        return "array";
    if (/^(?:Record\s*<|object\b|\{)/.test(type))
        return "object";
    if (/=>|^(?:Function|\([^)]*\)\s*=>)/.test(type))
        return "function";
    return "unknown";
}
function inferredRuntimeType(expression) {
    const value = expression.trim();
    if (/^["'`]/.test(value))
        return "string";
    if (/^-?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(value))
        return "number";
    if (/^(?:true|false)$/.test(value))
        return "boolean";
    if (/^-?\d+n$/.test(value))
        return "bigint";
    if (value.startsWith("["))
        return "array";
    if (value.startsWith("{") || /^new\s+(?:Map|Set|Date)\b/.test(value))
        return "object";
    if (/^(?:async\s+)?(?:function\b|\([^)]*\)\s*=>|[A-Za-z_$][\w$]*\s*=>)/.test(value)) {
        return "function";
    }
    return "unknown";
}
function validateTypedInitializer(name, annotation, expression) {
    if (!annotation || expression.trim() === "undefined" || expression.trim() === "null")
        return null;
    const expected = runtimeTypeOf(annotation);
    const actual = inferredRuntimeType(expression);
    if (expected === "unknown" || actual === "unknown" || expected === actual)
        return null;
    return `${name} is declared as ${annotation}, but its initializer is ${actual}`;
}
/**
 * Browser behavior is evaluated as JavaScript, so erase TypeScript annotations
 * from ordinary function declarations before serializing it into HTML.
 * Server output retains the original typed source.
 */
function eraseFunctionTypes(source) {
    return source.replace(/(\b(?:async\s+)?function\s+[A-Za-z_$][\w$]*\s*\()([^)]*)(\)\s*)(?::\s*([^{}=>]+)\s*)?(\{)/g, (_whole, open, params, close, _returnType, brace) => {
        const plainParams = params
            .split(",")
            .map((param) => param.replace(/([A-Za-z_$][\w$]*)(\?)?\s*:\s*([^=]+?)(?=\s*=|$)/, "$1").trim())
            .join(", ");
        return `${open}${plainParams}${close}${brace}`;
    });
}

},
"packages/syntax/src/v060.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseRuntimeFunctions = parseRuntimeFunctions;
exports.stripRuntimeFunctionModifiers = stripRuntimeFunctionModifiers;
exports.parseOutputs = parseOutputs;
exports.parseStructuredImports = parseStructuredImports;
exports.parseStateDeclarations = parseStateDeclarations;
exports.parseComputedDeclarations = parseComputedDeclarations;
exports.parsePersist = parsePersist;
exports.parseStoreLifecycle = parseStoreLifecycle;
const tokenizer_ts_1 = require("./tokenizer.js");
function splitTopLevel(input, separator = ",") {
    const parts = [];
    let start = 0;
    let quote = null;
    let angle = 0;
    let square = 0;
    let brace = 0;
    let paren = 0;
    for (let i = 0; i < input.length; i++) {
        const c = input[i];
        if (quote) {
            if (c === "\\")
                i++;
            else if (c === quote)
                quote = null;
            continue;
        }
        if (c === '"' || c === "'" || c === "`") {
            quote = c;
            continue;
        }
        if (c === "<")
            angle++;
        else if (c === ">" && angle > 0)
            angle--;
        else if (c === "[")
            square++;
        else if (c === "]" && square > 0)
            square--;
        else if (c === "{")
            brace++;
        else if (c === "}" && brace > 0)
            brace--;
        else if (c === "(")
            paren++;
        else if (c === ")" && paren > 0)
            paren--;
        else if (c === separator && angle === 0 && square === 0 && brace === 0 && paren === 0) {
            parts.push(input.slice(start, i).trim());
            start = i + 1;
        }
    }
    const tail = input.slice(start).trim();
    if (tail)
        parts.push(tail);
    return parts;
}
function findTopLevelChar(input, wanted) {
    let quote = null;
    let angle = 0;
    let square = 0;
    let brace = 0;
    let paren = 0;
    for (let i = 0; i < input.length; i++) {
        const c = input[i];
        if (quote) {
            if (c === "\\")
                i++;
            else if (c === quote)
                quote = null;
            continue;
        }
        if (c === '"' || c === "'" || c === "`") {
            quote = c;
            continue;
        }
        if (c === "<")
            angle++;
        else if (c === ">" && angle > 0)
            angle--;
        else if (c === "[")
            square++;
        else if (c === "]" && square > 0)
            square--;
        else if (c === "{")
            brace++;
        else if (c === "}" && brace > 0)
            brace--;
        else if (c === "(")
            paren++;
        else if (c === ")" && paren > 0)
            paren--;
        if (c === wanted && angle === 0 && square === 0 && brace === 0 && paren === 0)
            return i;
    }
    return -1;
}
function parseParameters(source) {
    return splitTopLevel(source)
        .filter(Boolean)
        .map((entry) => {
        const eq = findTopLevelChar(entry, "=");
        const declaration = (eq >= 0 ? entry.slice(0, eq) : entry).trim();
        const defaultValue = eq >= 0 ? entry.slice(eq + 1).trim() : undefined;
        const colon = findTopLevelChar(declaration, ":");
        const rawName = (colon >= 0 ? declaration.slice(0, colon) : declaration).trim();
        const optional = rawName.endsWith("?");
        const name = optional ? rawName.slice(0, -1).trim() : rawName;
        const valueType = colon >= 0 ? declaration.slice(colon + 1).trim() : undefined;
        return {
            name,
            optional,
            ...(valueType ? { valueType } : {}),
            ...(defaultValue ? { default: defaultValue } : {}),
        };
    });
}
function skipTrivia(source, start) {
    let i = start;
    while (i < source.length) {
        if (/\s/.test(source[i])) {
            i++;
            continue;
        }
        if (source.startsWith("//", i)) {
            const end = source.indexOf("\n", i + 2);
            i = end < 0 ? source.length : end + 1;
            continue;
        }
        if (source.startsWith("/*", i)) {
            const end = source.indexOf("*/", i + 2);
            i = end < 0 ? source.length : end + 2;
            continue;
        }
        break;
    }
    return i;
}
function readWord(source, start) {
    const match = /^[A-Za-z_$][\w$]*/.exec(source.slice(start));
    return match ? { word: match[0], end: start + match[0].length } : null;
}
function readBalanced(source, start, open, close) {
    if (source[start] !== open)
        throw new Error(`Expected '${open}' at offset ${start}`);
    let depth = 0;
    let quote = null;
    for (let i = start; i < source.length; i++) {
        const c = source[i];
        if (quote) {
            if (c === "\\")
                i++;
            else if (c === quote)
                quote = null;
            continue;
        }
        if (c === '"' || c === "'" || c === "`") {
            quote = c;
            continue;
        }
        if (c === open)
            depth++;
        else if (c === close && --depth === 0)
            return { inner: source.slice(start + 1, i), end: i + 1 };
    }
    throw new Error(`Unbalanced '${open}${close}' starting at offset ${start}`);
}
function parseRuntimeFunctions(source) {
    const declarations = [];
    let i = 0;
    while (i < source.length) {
        i = skipTrivia(source, i);
        const start = i;
        let token = readWord(source, i);
        if (!token) {
            i++;
            continue;
        }
        let runtime = "legacy";
        if (["client", "server", "shared"].includes(token.word)) {
            runtime = token.word;
            i = skipTrivia(source, token.end);
            token = readWord(source, i);
            if (!token)
                continue;
        }
        let isAsync = false;
        if (token.word === "async") {
            isAsync = true;
            i = skipTrivia(source, token.end);
            token = readWord(source, i);
            if (!token)
                continue;
        }
        if (token.word !== "function") {
            i = token.end;
            continue;
        }
        i = skipTrivia(source, token.end);
        const nameToken = readWord(source, i);
        if (!nameToken)
            throw new Error(`Expected function name at offset ${i}`);
        const name = nameToken.word;
        i = skipTrivia(source, nameToken.end);
        const params = readBalanced(source, i, "(", ")");
        i = skipTrivia(source, params.end);
        let returnType;
        if (source[i] === ":") {
            i++;
            const typeStart = i;
            let quote = null;
            let angle = 0;
            let square = 0;
            let paren = 0;
            while (i < source.length) {
                const c = source[i];
                if (quote) {
                    if (c === "\\")
                        i++;
                    else if (c === quote)
                        quote = null;
                    i++;
                    continue;
                }
                if (c === '"' || c === "'" || c === "`")
                    quote = c;
                else if (c === "<")
                    angle++;
                else if (c === ">" && angle > 0)
                    angle--;
                else if (c === "[")
                    square++;
                else if (c === "]" && square > 0)
                    square--;
                else if (c === "(")
                    paren++;
                else if (c === ")" && paren > 0)
                    paren--;
                else if (c === "{" && angle === 0 && square === 0 && paren === 0)
                    break;
                i++;
            }
            returnType = source.slice(typeStart, i).trim();
        }
        i = skipTrivia(source, i);
        const body = readBalanced(source, i, "{", "}");
        i = body.end;
        declarations.push({
            name,
            runtime,
            async: isAsync,
            parameters: parseParameters(params.inner),
            ...(returnType ? { returnType } : {}),
            body: body.inner,
            source: source.slice(start, body.end).trim(),
        });
    }
    return declarations;
}
function stripRuntimeFunctionModifiers(source, include) {
    const allowed = new Set(include);
    return parseRuntimeFunctions(source)
        .filter((entry) => allowed.has(entry.runtime))
        .map((entry) => {
        const params = entry.parameters
            .map((param) => `${param.name}${param.optional ? "?" : ""}${param.valueType ? `: ${param.valueType}` : ""}${param.default ? ` = ${param.default}` : ""}`)
            .join(", ");
        return `${entry.async ? "async " : ""}function ${entry.name}(${params})${entry.returnType ? `: ${entry.returnType}` : ""} {${entry.body}}`;
    })
        .join("\n\n");
}
function parseOutputs(source) {
    const out = [];
    let i = 0;
    while (i < source.length) {
        i = skipTrivia(source, i);
        if (i >= source.length)
            break;
        const nameToken = readWord(source, i);
        if (!nameToken)
            throw new Error(`Expected output name at offset ${i}`);
        i = skipTrivia(source, nameToken.end);
        const args = readBalanced(source, i, "(", ")");
        i = args.end;
        const parameters = parseParameters(args.inner);
        if (parameters.length > 1)
            throw new Error(`Output '${nameToken.word}' accepts zero or one payload`);
        const payload = parameters[0];
        if (payload && !payload.valueType)
            throw new Error(`Output '${nameToken.word}' payload requires a type`);
        out.push({
            name: nameToken.word,
            ...(payload
                ? {
                    payload: {
                        name: payload.name,
                        valueType: payload.valueType,
                        optional: payload.optional,
                    },
                }
                : {}),
        });
    }
    return out;
}
function parseStructuredImports(imports) {
    return imports.map((raw) => {
        const sourceMatch = /\sfrom\s+["']([^"']+)["']|^import\s+["']([^"']+)["']/.exec(raw);
        const source = sourceMatch?.[1] ?? sourceMatch?.[2] ?? "";
        const typeOnly = /^import\s+type\b/.test(raw);
        const clause = raw
            .replace(/^import\s+(?:type\s+)?/, "")
            .replace(/\s+from\s+["'][^"']+["']\s*;?$/, "")
            .trim();
        const declaration = { source, typeOnly, namedImports: [], raw };
        if (!clause || clause.startsWith('"') || clause.startsWith("'"))
            return declaration;
        if (clause.startsWith("*")) {
            declaration.namespaceImport = /\*\s+as\s+([A-Za-z_$][\w$]*)/.exec(clause)?.[1];
            return declaration;
        }
        let rest = clause;
        if (!rest.startsWith("{")) {
            const comma = findTopLevelChar(rest, ",");
            declaration.defaultImport = (comma < 0 ? rest : rest.slice(0, comma)).trim();
            rest = comma < 0 ? "" : rest.slice(comma + 1).trim();
        }
        const named = /^\{([\s\S]*)\}$/.exec(rest)?.[1];
        if (named !== undefined) {
            declaration.namedImports = splitTopLevel(named).map((item) => {
                const localTypeOnly = /^type\s+/.test(item);
                const cleaned = item.replace(/^type\s+/, "").trim();
                const [imported, local] = cleaned.split(/\s+as\s+/);
                return {
                    imported: imported.trim(),
                    local: (local ?? imported).trim(),
                    typeOnly: typeOnly || localTypeOnly,
                };
            });
        }
        return declaration;
    });
}
function parseStateDeclarations(source, runtime) {
    const lx = new tokenizer_ts_1.Lexer(source);
    const out = [];
    while (lx.peek().type !== "eof") {
        const nameToken = lx.next();
        if (nameToken.type !== "ident")
            throw new tokenizer_ts_1.LexError(`Expected a state name at offset ${nameToken.pos}`);
        let valueType;
        if (lx.peek().type === "colon") {
            lx.next();
            const annotation = lx.readTypeAnnotation();
            valueType = annotation.type;
            if (!annotation.hasDefault)
                throw new tokenizer_ts_1.LexError(`State '${nameToken.value}' requires an initializer`);
        }
        else {
            const eq = lx.next();
            if (eq.type !== "eq")
                throw new tokenizer_ts_1.LexError(`Expected '=' after state '${nameToken.value}' at offset ${eq.pos}`);
        }
        out.push({
            name: nameToken.value,
            ...(valueType ? { valueType } : {}),
            expr: lx.readPropInitializer(),
            runtime,
        });
    }
    return out;
}
function parseComputedDeclarations(source) {
    const lx = new tokenizer_ts_1.Lexer(source);
    const out = [];
    while (lx.peek().type !== "eof") {
        const nameToken = lx.next();
        if (nameToken.type !== "ident")
            throw new tokenizer_ts_1.LexError(`Expected a computed name at offset ${nameToken.pos}`);
        let valueType;
        if (lx.peek().type === "colon") {
            lx.next();
            const annotation = lx.readTypeAnnotation();
            valueType = annotation.type;
            if (!annotation.hasDefault)
                throw new tokenizer_ts_1.LexError(`Computed '${nameToken.value}' requires an expression`);
        }
        else {
            const eq = lx.next();
            if (eq.type !== "eq")
                throw new tokenizer_ts_1.LexError(`Expected '=' after computed '${nameToken.value}' at offset ${eq.pos}`);
        }
        out.push({
            name: nameToken.value,
            ...(valueType ? { valueType } : {}),
            expr: lx.readPropInitializer(),
        });
    }
    return out;
}
function nestedBlock(source, name) {
    const match = new RegExp(`\\b${name}\\s*\\{`).exec(source);
    if (!match)
        return undefined;
    const brace = source.indexOf("{", match.index);
    return readBalanced(source, brace, "{", "}").inner.trim() || undefined;
}
function parsePersist(source) {
    const storage = /\bstorage\s*=\s*["'](memory|session|local)["']/.exec(source)?.[1];
    const includeRaw = /\binclude\s*=\s*\[([\s\S]*?)\]/.exec(source)?.[1] ?? "";
    const include = Array.from(includeRaw.matchAll(/["']([^"']+)["']/g), (match) => match[1]);
    const version = Number(/\bversion\s*=\s*(\d+)/.exec(source)?.[1] ?? "1");
    const migrations = nestedBlock(source, "migrations");
    const validation = nestedBlock(source, "validate");
    return {
        storage: storage ?? "memory",
        include,
        version,
        ...(migrations ? { migrations } : {}),
        ...(validation ? { validation } : {}),
    };
}
function parseStoreLifecycle(source) {
    const out = {};
    for (const hook of ["serverInit", "clientInit", "hydrate", "dispose"]) {
        const start = new RegExp(`\\b${hook}\\s*\\{`).exec(source);
        if (!start)
            continue;
        const brace = source.indexOf("{", start.index);
        out[hook] = readBalanced(source, brace, "{", "}").inner;
    }
    return out;
}

},
"packages/syntax/src/versioning.ts": function (module, exports, require, __filename, __dirname) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WRN_SYNTAX_FEATURES = exports.WRN_SYNTAX_VERSION = void 0;
exports.createSourceRange = createSourceRange;
exports.sliceSource = sliceSource;
exports.diagnosticSummary = diagnosticSummary;
exports.supportsSyntaxFeature = supportsSyntaxFeature;
/** Current stable syntax contract. Bump only when parsers/codegen need migration. */
exports.WRN_SYNTAX_VERSION = "0.4";
exports.WRN_SYNTAX_FEATURES = Object.freeze({
    "typed-declarations": true,
    layouts: true,
    "server-client-blocks": true,
    effects: true,
    watch: true,
    lifecycle: true,
    "embedded-api": true,
    realtime: true,
    "runtime-markers": true,
});
function createSourceRange(start, end) {
    if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) {
        throw new RangeError(`Invalid source range ${start}..${end}`);
    }
    return { start, end };
}
function sliceSource(source, range) {
    return source.slice(range.start, range.end);
}
function diagnosticSummary(diagnostics) {
    const summary = { errors: 0, warnings: 0, info: 0, codes: {} };
    for (const diagnostic of diagnostics) {
        if (diagnostic.severity === "error")
            summary.errors++;
        else if (diagnostic.severity === "warning")
            summary.warnings++;
        else
            summary.info++;
        summary.codes[diagnostic.code] = (summary.codes[diagnostic.code] ?? 0) + 1;
    }
    return summary;
}
function supportsSyntaxFeature(feature) {
    return Object.prototype.hasOwnProperty.call(exports.WRN_SYNTAX_FEATURES, feature);
}

}
};
const __aliases = {
  "@wrnexus/syntax": "packages/syntax/src/index.ts",
  "@wrnexus/syntax/parser": "packages/syntax/src/parser.ts",
  "@wrnexus/syntax/tokenizer": "packages/syntax/src/tokenizer.ts",
  "@wrnexus/syntax/types": "packages/syntax/src/types.ts",
  "@wrnexus/syntax/diagnostics": "packages/syntax/src/diagnostics.ts",
  "@wrnexus/syntax/spec": "packages/syntax/src/spec.ts"
};
const __cache = Object.create(null);
function __normalize(id) {
  const normalized = id.split("\\").join("/");
  return normalized.startsWith("./") ? normalized.slice(2) : normalized;
}
function __resolve(request, parent) {
  if (__aliases[request]) return __aliases[request];
  if (!request.startsWith(".")) return null;
  const base = __normalize(__path.posix.join(__path.posix.dirname(parent), request));
  const candidates = [
    base,
    base.endsWith(".js") ? base.slice(0, -3) + ".ts" : base,
    base.endsWith(".ts") ? base : base + ".ts",
    (base.endsWith("/") ? base.slice(0, -1) : base) + "/index.ts"
  ];
  for (const candidate of candidates) {
    if (__modules[candidate]) return candidate;
  }
  return null;
}
function __load(id) {
  if (__cache[id]) return __cache[id].exports;
  const factory = __modules[id];
  if (!factory) throw new Error("WRN editor compiler module not found: " + id);
  const module = { exports: {} };
  __cache[id] = module;
  const localRequire = (request) => {
    const resolved = __resolve(request, id);
    return resolved ? __load(resolved) : __nodeRequire(request);
  };
  factory(module, module.exports, localRequire, id, __path.posix.dirname(id));
  return module.exports;
}
module.exports = __load("packages/compiler/src/index.ts");
