// Bun Snapshot v1, https://bun.sh/docs/test/snapshots

exports[`compiler output remains snapshot-compatible for the canonical component contract 1`] = `
{
  "code": 
"// compiled from .wrn
import Button from "@wrnexus/ui/components/Button.wrn";

import { Buffer as __WrnexusBuffer } from "node:buffer";

export const __wrnexusComponent = "Counter";

export const __wrnexusRuntime = "universal";

export const __wrnexusRender = "hybrid";

export const __wrnexusHydrate = "load";

export const __wrnexusHydrationId = "Counter:1skggk6";

export const __wrnexusBehavior = {
  "functions": "function increment(){\\n      count = count + 1\\n      output.change(count)\\n    }",
  "outputs": [
    {
      "name": "change",
      "payload": {
        "name": "value",
        "valueType": "number",
        "optional": false
      }
    }
  ],
  "computed": [],
  "effects": [],
  "lifecycle": {},
  "watches": []
};

export interface CounterProps {
  [attribute: string]: unknown;
  "label"?: string;
}

export interface CounterOutputs {
  "change"(value: number): void;
}

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 __wrnHtml(v: unknown): string {
  return String(v == null ? "" : v).replace(
    /[&<>]/g,
    (c) =>
      c === "&"
        ? "&amp;"
        : c === "<"
          ? "&lt;"
          : "&gt;",
  );
}

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

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

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

  const booleanAttributes = 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"]);
  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(__wrnBooleanAttr(name, raw));
      continue;
    }

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

  return attributes.join("");
}

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

  return __wrnAttr(value);
}

function __wrnRaw(v: unknown): string {
  return String(v == null ? "" : v);
}

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;");
  }

export function render(props: CounterProps = {} as CounterProps): string {
  const __p = props || {};
  const label: string = __coerce(__p["label"], ("Count"), "string", "label") as string;
  const __attrs = __restProps(__p, new Set(["label"]));
  let count = (0);
  const __scopeState = { "label": label, "count": count };
  const __scope = __wrnexusScopeDecl(__scopeState);
  const __scopePayload = __WrnexusBuffer.from(JSON.stringify(__scopeState), "utf8").toString("base64");
  return \`<div data-scope="\${__scope}" data-wrn-scope="\${__scopePayload}" data-wrn-behavior="eyJmdW5jdGlvbnMiOiJmdW5jdGlvbiBpbmNyZW1lbnQoKXtcbiAgICAgIGNvdW50ID0gY291bnQgKyAxXG4gICAgICBvdXRwdXQuY2hhbmdlKGNvdW50KVxuICAgIH0iLCJvdXRwdXRzIjpbeyJuYW1lIjoiY2hhbmdlIiwicGF5bG9hZCI6eyJuYW1lIjoidmFsdWUiLCJ2YWx1ZVR5cGUiOiJudW1iZXIiLCJvcHRpb25hbCI6ZmFsc2V9fV0sImNvbXB1dGVkIjpbXSwiZWZmZWN0cyI6W10sImxpZmVjeWNsZSI6e30sIndhdGNoZXMiOltdfQ==" data-wrn-hydration="Counter:1skggk6" data-wrn-hydrate="load" data-wrn-runtime="universal" data-wrn-client-module="__WRNEXUS_CLIENT_MODULE__">
    <div data-component="Button"\${__wrnSpreadAttrs(__attrs)} on:click="\${__wrnProp(increment)}"><span data-text="label">\${__wrnHtml(label)}</span>: <span data-text="count">\${__wrnHtml(count)}</span></div>
  </div>\`;
}

export default { name: "Counter", kind: "component", render };
"
,
  "diagnostics": [],
}
`;
