sinwan 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -1
  3. package/dist/cjs/index.development.js +1625 -0
  4. package/dist/cjs/index.development.js.map +32 -0
  5. package/dist/cjs/index.production.min.js +3 -0
  6. package/dist/cjs/index.production.min.js.map +32 -0
  7. package/dist/cjs/jsx/jsx-dev-runtime.development.js +134 -0
  8. package/dist/cjs/jsx/jsx-dev-runtime.development.js.map +10 -0
  9. package/dist/cjs/jsx/jsx-dev-runtime.production.min.js +3 -0
  10. package/dist/cjs/jsx/jsx-dev-runtime.production.min.js.map +10 -0
  11. package/dist/cjs/jsx/jsx-runtime.development.js +126 -0
  12. package/dist/cjs/jsx/jsx-runtime.development.js.map +10 -0
  13. package/dist/cjs/jsx/jsx-runtime.production.min.js +3 -0
  14. package/dist/cjs/jsx/jsx-runtime.production.min.js.map +10 -0
  15. package/dist/cjs/package.json +4 -0
  16. package/dist/cjs/server/index.development.js +929 -0
  17. package/dist/cjs/server/index.development.js.map +22 -0
  18. package/dist/cjs/server/index.production.min.js +3 -0
  19. package/dist/cjs/server/index.production.min.js.map +22 -0
  20. package/dist/component/create.d.ts +75 -0
  21. package/dist/component/create.d.ts.map +1 -0
  22. package/dist/component/index.d.ts +10 -0
  23. package/dist/component/index.d.ts.map +1 -0
  24. package/dist/component/instance.d.ts +78 -0
  25. package/dist/component/instance.d.ts.map +1 -0
  26. package/dist/component/lifecycle.d.ts +40 -0
  27. package/dist/component/lifecycle.d.ts.map +1 -0
  28. package/dist/component/provide-inject.d.ts +39 -0
  29. package/dist/component/provide-inject.d.ts.map +1 -0
  30. package/dist/escaper.d.ts +26 -0
  31. package/dist/escaper.d.ts.map +1 -0
  32. package/dist/esm/index.development.js +1560 -0
  33. package/dist/esm/index.development.js.map +32 -0
  34. package/dist/esm/index.production.min.js +4 -0
  35. package/dist/esm/index.production.min.js.map +32 -0
  36. package/dist/esm/jsx/jsx-dev-runtime.development.js +83 -0
  37. package/dist/esm/jsx/jsx-dev-runtime.development.js.map +10 -0
  38. package/dist/esm/jsx/jsx-dev-runtime.production.min.js +4 -0
  39. package/dist/esm/jsx/jsx-dev-runtime.production.min.js.map +10 -0
  40. package/dist/esm/jsx/jsx-runtime.development.js +87 -0
  41. package/dist/esm/jsx/jsx-runtime.development.js.map +10 -0
  42. package/dist/esm/jsx/jsx-runtime.production.min.js +4 -0
  43. package/dist/esm/jsx/jsx-runtime.production.min.js.map +10 -0
  44. package/dist/esm/package.json +4 -0
  45. package/dist/esm/server/index.development.js +878 -0
  46. package/dist/esm/server/index.development.js.map +22 -0
  47. package/dist/esm/server/index.production.min.js +4 -0
  48. package/dist/esm/server/index.production.min.js.map +22 -0
  49. package/dist/hydration/hydrate.d.ts +29 -0
  50. package/dist/hydration/hydrate.d.ts.map +1 -0
  51. package/dist/hydration/index.d.ts +7 -0
  52. package/dist/hydration/index.d.ts.map +1 -0
  53. package/dist/hydration/markers.d.ts +48 -0
  54. package/dist/hydration/markers.d.ts.map +1 -0
  55. package/dist/hydration/walk.d.ts +32 -0
  56. package/dist/hydration/walk.d.ts.map +1 -0
  57. package/dist/index.d.ts +14 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +7 -0
  60. package/dist/index.mjs +4 -0
  61. package/dist/jsx/jsx-dev-runtime.d.ts +10 -0
  62. package/dist/jsx/jsx-dev-runtime.d.ts.map +1 -0
  63. package/dist/jsx/jsx-runtime.d.ts +54 -0
  64. package/dist/jsx/jsx-runtime.d.ts.map +1 -0
  65. package/dist/jsx/jsx-types.d.ts +637 -0
  66. package/dist/jsx/jsx-types.d.ts.map +1 -0
  67. package/dist/jsx-dev-runtime.d.ts +1 -0
  68. package/dist/jsx-dev-runtime.js +7 -0
  69. package/dist/jsx-dev-runtime.mjs +4 -0
  70. package/dist/jsx-runtime.d.ts +1 -0
  71. package/dist/jsx-runtime.js +7 -0
  72. package/dist/jsx-runtime.mjs +4 -0
  73. package/dist/reactivity/batch.d.ts +27 -0
  74. package/dist/reactivity/batch.d.ts.map +1 -0
  75. package/dist/reactivity/computed.d.ts +41 -0
  76. package/dist/reactivity/computed.d.ts.map +1 -0
  77. package/dist/reactivity/effect.d.ts +79 -0
  78. package/dist/reactivity/effect.d.ts.map +1 -0
  79. package/dist/reactivity/index.d.ts +15 -0
  80. package/dist/reactivity/index.d.ts.map +1 -0
  81. package/dist/reactivity/scheduler.d.ts +35 -0
  82. package/dist/reactivity/scheduler.d.ts.map +1 -0
  83. package/dist/reactivity/signal.d.ts +36 -0
  84. package/dist/reactivity/signal.d.ts.map +1 -0
  85. package/dist/renderer/attributes.d.ts +8 -0
  86. package/dist/renderer/attributes.d.ts.map +1 -0
  87. package/dist/renderer/dom-ops.d.ts +27 -0
  88. package/dist/renderer/dom-ops.d.ts.map +1 -0
  89. package/dist/renderer/events.d.ts +21 -0
  90. package/dist/renderer/events.d.ts.map +1 -0
  91. package/dist/renderer/index.d.ts +12 -0
  92. package/dist/renderer/index.d.ts.map +1 -0
  93. package/dist/renderer/mount.d.ts +30 -0
  94. package/dist/renderer/mount.d.ts.map +1 -0
  95. package/dist/renderer/render-children.d.ts +19 -0
  96. package/dist/renderer/render-children.d.ts.map +1 -0
  97. package/dist/renderer/render-element.d.ts +13 -0
  98. package/dist/renderer/render-element.d.ts.map +1 -0
  99. package/dist/renderer/types.d.ts +63 -0
  100. package/dist/renderer/types.d.ts.map +1 -0
  101. package/dist/server/hydration-markers.d.ts +23 -0
  102. package/dist/server/hydration-markers.d.ts.map +1 -0
  103. package/dist/server/index.d.ts +9 -0
  104. package/dist/server/index.d.ts.map +1 -0
  105. package/dist/server/renderer.d.ts +33 -0
  106. package/dist/server/renderer.d.ts.map +1 -0
  107. package/dist/server/stream.d.ts +12 -0
  108. package/dist/server/stream.d.ts.map +1 -0
  109. package/dist/server.d.ts +1 -0
  110. package/dist/server.js +7 -0
  111. package/dist/server.mjs +4 -0
  112. package/dist/types.d.ts +42 -0
  113. package/dist/types.d.ts.map +1 -0
  114. package/package.json +102 -4
  115. package/bun.lock +0 -26
  116. package/src/index.ts +0 -1
  117. package/tsconfig.json +0 -29
@@ -0,0 +1,22 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/jsx/jsx-runtime.ts", "../../src/escaper.ts", "../../src/server/renderer.ts", "../../src/server/stream.ts", "../../src/reactivity/scheduler.ts", "../../src/reactivity/effect.ts", "../../src/reactivity/signal.ts", "../../src/reactivity/computed.ts", "../../src/hydration/markers.ts", "../../src/renderer/dom-ops.ts", "../../src/renderer/events.ts", "../../src/component/instance.ts", "../../src/server/hydration-markers.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * SinwanJS View Module — JSX Runtime\n *\n * JSX factory that returns SinwanElement structures for the view renderer.\n * Imported automatically when using JSX syntax.\n */\n\nimport type { SinwanElement, SinwanNode } from \"../types.ts\";\nimport type { SinwanIntrinsicElements } from \"./jsx-types\";\n\nexport const Fragment = Symbol(\"Fragment\");\n\n/**\n * A string that has been marked as safe HTML (already escaped).\n * Used for raw HTML injection with explicit trust marking.\n */\nexport class HtmlEscapedString extends String {\n constructor(public readonly value: string) {\n super(value);\n }\n override toString() {\n return this.value;\n }\n}\n\nexport const raw = (str: string) => new HtmlEscapedString(str);\n\n// Fast path for intrinsic elements\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Normalize children into an array of SinwanNode.\n */\nfunction normalizeChildren(children: any): SinwanNode[] {\n if (children == null || typeof children === \"boolean\") return [];\n if (Array.isArray(children)) return children.flat(Infinity);\n return [children];\n}\n\n/**\n * Build an SinwanElement from a component/tag invocation.\n * Shared logic for jsx, jsxs, and jsxDEV.\n */\nfunction buildElement(\n type: any,\n props: any,\n children: SinwanNode[],\n): SinwanElement {\n // Handle Fragment\n if (type === Fragment) {\n return { tag: \"\", props: {}, children };\n }\n\n // Handle functional components\n if (typeof type === \"function\") {\n // Sinwan-tagged component — call it directly\n if (type._SinwanComponent || type._SinwanPage) {\n const result = type(props);\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return result as SinwanElement;\n }\n return { tag: \"\", props: {}, children: normalizeChildren(result) };\n }\n\n // Regular function component\n const result = type(props);\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return result as SinwanElement;\n }\n return { tag: \"\", props: {}, children: normalizeChildren(result) };\n }\n\n // Handle intrinsic HTML elements\n if (typeof type === \"string\") {\n return { tag: type, props: props || {}, children };\n }\n\n // Fallback\n return { tag: \"\", props: {}, children };\n}\n\n/**\n * JSX factory — called for elements with 0 or 1 child.\n * TypeScript auto-imports this in production mode (`react-jsx`).\n */\nexport function jsx(type: any, props: any, key?: any): SinwanElement {\n return buildElement(type, props, normalizeChildren(props?.children));\n}\n\n/**\n * JSX static factory — called for elements with 2+ children.\n * `props.children` is **already an array**, so we skip normalizeChildren.\n */\nexport function jsxs(type: any, props: any, key?: any): SinwanElement {\n const children = props?.children;\n // Children is guaranteed to be an array by the compiler\n return buildElement(\n type,\n props,\n Array.isArray(children)\n ? children.flat(Infinity)\n : normalizeChildren(children),\n );\n}\n\n/**\n * Source location metadata attached by the compiler in dev mode.\n */\nexport interface JSXSource {\n fileName: string;\n lineNumber: number;\n columnNumber: number;\n}\n\n/**\n * JSX dev factory — called in dev mode (`react-jsxdev`).\n * Receives extra source/debug info for better error messages.\n */\nexport function jsxDEV(\n type: any,\n props: any,\n key: any,\n isStaticChildren: boolean,\n source?: JSXSource,\n self?: unknown,\n): SinwanElement {\n const children = isStaticChildren\n ? Array.isArray(props?.children)\n ? props.children.flat(Infinity)\n : normalizeChildren(props?.children)\n : normalizeChildren(props?.children);\n\n const element = buildElement(type, props, children);\n\n // Attach debug metadata (useful for dev-tools / error traces)\n if (source) {\n (element as any).__source = source;\n }\n\n return element;\n}\n\nexport namespace JSX {\n export type Element = SinwanElement | Promise<SinwanElement>;\n export interface IntrinsicAttributes {\n key?: string | number;\n }\n export interface ElementChildrenAttribute {\n children: {};\n }\n export interface IntrinsicElements extends SinwanIntrinsicElements {}\n}\n",
6
+ "/**\n * Sinwan — HTML Escaping\n *\n * Security utilities for sanitizing interpolated values.\n * Runtime-agnostic: prefers `Bun.escapeHTML` when running on Bun (native\n * speed), and falls back to a portable implementation everywhere else\n * (Node, Deno, Cloudflare Workers, browsers).\n */\n\nimport { HtmlEscapedString, raw } from \"./jsx/jsx-runtime\";\n\nexport { HtmlEscapedString, raw };\n\n// ─── Native fast-path detection ─────────────────────────────\n// `Bun` is only defined inside the Bun runtime. We probe it via globalThis\n// so module evaluation never throws on other runtimes.\nconst _bun = (globalThis as any).Bun as\n | { escapeHTML?: (s: string) => string }\n | undefined;\n\nconst _nativeEscape: ((s: string) => string) | undefined =\n typeof _bun?.escapeHTML === \"function\"\n ? _bun.escapeHTML.bind(_bun)\n : undefined;\n\n// ─── Portable fallback ──────────────────────────────────────\n// Covers the five characters that matter inside HTML text and attributes.\nconst HTML_ESCAPE_RE = /[&<>\"']/g;\nconst HTML_ESCAPE_MAP: Record<string, string> = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#39;\",\n};\n\nfunction portableEscape(str: string): string {\n // Avoid a regex pass when nothing to escape (very common case).\n HTML_ESCAPE_RE.lastIndex = 0;\n if (!HTML_ESCAPE_RE.test(str)) return str;\n return str.replace(HTML_ESCAPE_RE, (c) => HTML_ESCAPE_MAP[c]!);\n}\n\n/**\n * Escape HTML entities in any value.\n * Returns \"\" for null/undefined/boolean and pass-through for numbers.\n * Pre-escaped strings (`HtmlEscapedString`) are returned untouched.\n */\nexport function escapeHtml(value: unknown): string {\n if (value == null || typeof value === \"boolean\") return \"\";\n if (typeof value === \"number\") return String(value);\n if (value instanceof HtmlEscapedString) return value.value;\n const s = String(value);\n return _nativeEscape ? _nativeEscape(s) : portableEscape(s);\n}\n\n/**\n * Mark a string as safe HTML (pre-escaped).\n * USE WITH CAUTION - only for trusted content!\n */\nexport function safeHtml(html: string): HtmlEscapedString {\n return raw(html);\n}\n\n/**\n * Check if a value is already escaped HTML.\n */\nexport function isSafeHtml(value: unknown): value is HtmlEscapedString {\n return value instanceof HtmlEscapedString;\n}\n",
7
+ "/**\n * SinwanJS View Module — Renderer & Component Registry\n *\n * Renders Sinwan component trees to HTML strings.\n * Supports async components, caching, and streaming.\n */\n\nimport type {\n SinwanNode,\n SinwanElement,\n SinwanComponent,\n SinwanPage,\n SinwanSlots,\n} from \"../types.ts\";\nimport { HtmlEscapedString, escapeHtml } from \"../escaper.ts\";\n\n// Component cache - maps component identity to render function\nconst componentCache = new WeakMap<SinwanComponent<any>, boolean>();\n\n// Page registry\nconst pageRegistry = new Map<string, SinwanPage<any>>();\n\n/**\n * Register a page renderer by name.\n */\nexport function registerPage<D extends object = {}>(\n name: string,\n page: SinwanPage<D>,\n): void {\n pageRegistry.set(name, page);\n}\n\n/**\n * Get a registered page by name.\n */\nexport function getPage<D extends object = {}>(\n name: string,\n): SinwanPage<D> | undefined {\n return pageRegistry.get(name);\n}\n\n/**\n * Check if a page is registered.\n */\nexport function hasPage(name: string): boolean {\n return pageRegistry.has(name);\n}\n\n/**\n * Render a registered page to an HTML string.\n */\nexport async function renderPage<D extends object = {}>(\n name: string,\n data: D,\n): Promise<string> {\n const page = getPage<D>(name);\n if (!page) {\n throw new Error(`Page \"${name}\" not found in registry`);\n }\n\n const element = await page(data);\n return renderToString(element);\n}\n\n/**\n * Render a node tree to an HTML string.\n * Handles primitives, elements, components, and arrays.\n */\nexport async function renderToString(node: SinwanNode): Promise<string> {\n // Handle null/undefined/boolean\n if (node == null || typeof node === \"boolean\") {\n return \"\";\n }\n\n // Handle strings (escape them)\n if (typeof node === \"string\") {\n return escapeHtml(node);\n }\n\n // Handle numbers\n if (typeof node === \"number\") {\n return String(node);\n }\n\n // Handle pre-escaped HTML\n if (node instanceof HtmlEscapedString) {\n return node.value;\n }\n\n // Handle arrays - render each child and concatenate\n if (Array.isArray(node)) {\n const results = await Promise.all(\n node.map((child) => renderToString(child)),\n );\n return results.join(\"\");\n }\n\n // Handle promises (async components)\n if (node instanceof Promise) {\n return renderElement(await node);\n }\n\n // Handle elements\n return renderElement(node);\n}\n\n/**\n * Render an element to HTML string.\n */\nasync function renderElement(element: SinwanElement): Promise<string> {\n const { tag, props, children } = element;\n\n // Handle functional components\n if (typeof tag === \"function\") {\n const result = await tag(props);\n return renderToString(result);\n }\n\n // Handle intrinsic HTML elements\n if (typeof tag === \"string\") {\n return renderIntrinsicElement(tag, props, children);\n }\n\n // Fallback - shouldn't happen with valid JSX\n return renderToString(children);\n}\n\n// Void elements that don't have closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Render an intrinsic HTML element.\n */\nasync function renderIntrinsicElement(\n tag: string,\n props: Record<string, unknown>,\n children: SinwanNode[],\n): Promise<string> {\n const attrs = renderAttributes(props);\n\n // Void elements have no children and no closing tag\n if (VOID_ELEMENTS.has(tag)) {\n return attrs ? `<${tag}${attrs}>` : `<${tag}>`;\n }\n\n // Render children (handles dangerouslySetInnerHTML)\n const childrenHtml = await renderChildren(children, props);\n\n // Build element\n return attrs\n ? `<${tag}${attrs}>${childrenHtml}</${tag}>`\n : `<${tag}>${childrenHtml}</${tag}>`;\n}\n\n/**\n * Render HTML attributes from props.\n */\nfunction renderAttributes(props: Record<string, unknown>): string {\n let attrs = \"\";\n\n for (const [key, value] of Object.entries(props)) {\n // Skip children and special props\n if (key === \"children\") continue;\n\n // Skip null/undefined/false values\n if (value == null || value === false) continue;\n\n // Handle boolean true (just the attribute name)\n if (value === true) {\n attrs += ` ${key}`;\n continue;\n }\n\n // Handle dangerous HTML (trusted only)\n if (key === \"dangerouslySetInnerHTML\") {\n // This is handled during children rendering, not as an attribute\n continue;\n }\n\n // Handle className -> class\n const attrName = key === \"className\" ? \"class\" : key;\n\n // Handle htmlFor -> for\n const finalName = attrName === \"htmlFor\" ? \"for\" : attrName;\n\n // Escape the attribute value\n const attrValue = escapeHtml(String(value));\n attrs += ` ${finalName}=\"${attrValue}\"`;\n }\n\n return attrs;\n}\n\n/**\n * Render children, with special handling for dangerouslySetInnerHTML.\n */\nasync function renderChildren(\n children: SinwanNode[],\n props: Record<string, unknown>,\n): Promise<string> {\n // Check for dangerous inner HTML\n const dangerous = props.dangerouslySetInnerHTML as\n | { __html?: string }\n | undefined;\n if (dangerous && typeof dangerous.__html === \"string\") {\n return dangerous.__html; // Trust the HTML (user explicitly marked safe)\n }\n\n return renderToString(children);\n}\n\n// Wire up dangerouslySetInnerHTML handling by patching renderIntrinsicElement\nconst originalRenderIntrinsic = renderIntrinsicElement;\n\n/**\n * Check if children is a slots object (named slots).\n */\nexport function isSlots(children: unknown): children is SinwanSlots {\n return (\n children != null &&\n typeof children === \"object\" &&\n !Array.isArray(children) &&\n !(children instanceof HtmlEscapedString)\n );\n}\n",
8
+ "/**\n * SinwanJS View Module — Streaming SSR\n *\n * Progressive HTML streaming using Bun's native ReadableStream.\n * Streams chunks as they resolve without waiting for full tree.\n */\n\nimport type { SinwanNode, SinwanElement, SinwanPage } from \"../types.ts\";\nimport { HtmlEscapedString, escapeHtml } from \"../escaper.ts\";\n\n// Void elements that don't have closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Stream a page to a ReadableStream.\n */\nexport function streamPage<D extends object = {}>(\n page: SinwanPage<D>,\n data: D,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n // Resolve the page component\n const element = await page(data);\n\n // Stream the element tree\n await streamNode(element, controller, encoder);\n\n // Close the stream\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n\n/**\n * Stream a node tree to a controller.\n */\nasync function streamNode(\n node: SinwanNode,\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n): Promise<void> {\n // Handle null/undefined/boolean\n if (node == null || typeof node === \"boolean\") {\n return;\n }\n\n // Handle strings (escape them)\n if (typeof node === \"string\") {\n controller.enqueue(encoder.encode(escapeHtml(node)));\n return;\n }\n\n // Handle numbers\n if (typeof node === \"number\") {\n controller.enqueue(encoder.encode(String(node)));\n return;\n }\n\n // Handle pre-escaped HTML\n if (node instanceof HtmlEscapedString) {\n controller.enqueue(encoder.encode(node.value));\n return;\n }\n\n // Handle arrays - stream each child\n if (Array.isArray(node)) {\n for (const child of node) {\n await streamNode(child, controller, encoder);\n }\n return;\n }\n\n // Handle async elements (Promise<SinwanElement>)\n if (node instanceof Promise) {\n const resolved = await node;\n await streamElement(resolved, controller, encoder);\n return;\n }\n\n // Handle elements\n await streamElement(node, controller, encoder);\n}\n\n/**\n * Stream an element to the controller.\n */\nasync function streamElement(\n element: SinwanElement,\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n): Promise<void> {\n const { tag, props, children } = element;\n\n // Handle functional components\n if (typeof tag === \"function\") {\n const result = await tag(props);\n await streamNode(result, controller, encoder);\n return;\n }\n\n // Handle intrinsic HTML elements\n if (typeof tag === \"string\") {\n await streamIntrinsicElement(tag, props, children, controller, encoder);\n return;\n }\n\n // Fallback\n await streamNode(children, controller, encoder);\n}\n\n/**\n * Stream an intrinsic HTML element.\n */\nasync function streamIntrinsicElement(\n tag: string,\n props: Record<string, unknown>,\n children: SinwanNode[],\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n): Promise<void> {\n const attrs = renderAttributes(props);\n\n // Check for dangerous inner HTML\n const dangerous = props.dangerouslySetInnerHTML as\n | { __html?: string }\n | undefined;\n\n // Void elements have no children and no closing tag\n if (VOID_ELEMENTS.has(tag)) {\n const html = attrs ? `<${tag}${attrs}>` : `<${tag}>`;\n controller.enqueue(encoder.encode(html));\n return;\n }\n\n // Opening tag\n const openTag = attrs ? `<${tag}${attrs}>` : `<${tag}>`;\n controller.enqueue(encoder.encode(openTag));\n\n // Children or dangerous HTML\n if (dangerous && typeof dangerous.__html === \"string\") {\n controller.enqueue(encoder.encode(dangerous.__html));\n } else {\n await streamNode(children, controller, encoder);\n }\n\n // Closing tag\n controller.enqueue(encoder.encode(`</${tag}>`));\n}\n\n/**\n * Render HTML attributes from props.\n */\nfunction renderAttributes(props: Record<string, unknown>): string {\n let attrs = \"\";\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\" || key === \"dangerouslySetInnerHTML\") continue;\n if (value == null || value === false) continue;\n\n if (value === true) {\n attrs += ` ${key}`;\n continue;\n }\n\n const attrName =\n key === \"className\" ? \"class\" : key === \"htmlFor\" ? \"for\" : key;\n const attrValue = escapeHtml(String(value));\n attrs += ` ${attrName}=\"${attrValue}\"`;\n }\n\n return attrs;\n}\n",
9
+ "/**\n * SinwanJS Reactivity — Scheduler\n *\n * Microtask-based flush queue for batching reactive updates.\n * Effects are NOT run synchronously on signal write — they are\n * queued and flushed in a microtask (like Vue's nextTick).\n */\n\nexport interface EffectNode {\n id: number;\n run(): void;\n active: boolean;\n}\n\nconst pendingEffects = new Set<EffectNode>();\nlet flushScheduled = false;\nlet isFlushing = false;\n\n// Pending nextTick callbacks\nconst pendingCallbacks: (() => void)[] = [];\n\n/**\n * Schedule an effect for the next microtask flush.\n */\nexport function scheduleEffect(effect: EffectNode): void {\n if (!effect.active) return;\n pendingEffects.add(effect);\n scheduleFlush();\n}\n\n/**\n * Remove a scheduled effect (e.g. when disposed before flush).\n */\nexport function unscheduleEffect(effect: EffectNode): void {\n pendingEffects.delete(effect);\n}\n\n/**\n * Schedule the microtask flush if not already scheduled.\n */\nfunction scheduleFlush(): void {\n if (!flushScheduled) {\n flushScheduled = true;\n queueMicrotask(flush);\n }\n}\n\n/**\n * Flush all pending effects. Effects added during flush are\n * processed in the same pass (convergence loop with a safety limit).\n */\nfunction flush(): void {\n isFlushing = true;\n\n // Sort by id to guarantee parent-before-child execution order\n const sorted = [...pendingEffects].sort((a, b) => a.id - b.id);\n pendingEffects.clear();\n\n for (const effect of sorted) {\n if (effect.active) {\n effect.run();\n }\n }\n\n // If new effects were queued during the flush, drain them too\n // (safety limit to prevent infinite loops)\n let safety = 10;\n while (pendingEffects.size > 0 && safety-- > 0) {\n const next = [...pendingEffects].sort((a, b) => a.id - b.id);\n pendingEffects.clear();\n for (const effect of next) {\n if (effect.active) {\n effect.run();\n }\n }\n }\n\n flushScheduled = false;\n isFlushing = false;\n\n // Run nextTick callbacks after all effects\n const cbs = pendingCallbacks.splice(0);\n for (const cb of cbs) {\n cb();\n }\n}\n\n/**\n * Returns true if the scheduler is currently flushing effects.\n */\nexport function isFlushingEffects(): boolean {\n return isFlushing;\n}\n\n/**\n * Queue a callback that runs after the next reactive flush completes.\n * Similar to Vue's nextTick().\n */\nexport function nextTick(fn?: () => void): Promise<void> {\n return new Promise<void>((resolve) => {\n const callback = () => {\n fn?.();\n resolve();\n };\n if (flushScheduled || isFlushing) {\n // Effects are pending — run after they flush\n pendingCallbacks.push(callback);\n } else {\n // No pending effects — run on next microtask\n queueMicrotask(callback);\n }\n });\n}\n\n/**\n * Force synchronous flush of all pending effects.\n * Primarily for testing and batch().\n */\nexport function flushSync(): void {\n if (flushScheduled) {\n flushScheduled = false;\n flush();\n }\n}\n",
10
+ "/**\n * SinwanJS Reactivity — Effect\n *\n * Fine-grained effect system with automatic dependency tracking.\n * When an effect runs, any signal reads are tracked as dependencies.\n * When those signals change, the effect is re-scheduled.\n */\n\nimport { type EffectNode, scheduleEffect, unscheduleEffect } from \"./scheduler.ts\";\n\n// ─── Global tracking state ─────────────────────────────────\n\nlet activeEffect: ReactiveEffect | null = null;\nconst effectStack: ReactiveEffect[] = [];\nlet effectIdCounter = 0;\n\n// ─── Subscription interface ────────────────────────────────\n\n/**\n * A Dep is any object that can track subscribers.\n * Signals and computeds implement this internally.\n */\nexport interface Dep {\n subscribers: Set<ReactiveEffect>;\n}\n\n// ─── ReactiveEffect ────────────────────────────────────────\n\nexport type CleanupFn = () => void;\nexport type EffectFn = () => CleanupFn | void;\n\nexport class ReactiveEffect implements EffectNode {\n id: number;\n active = true;\n\n /** The user-supplied function */\n private fn: EffectFn;\n\n /** Cleanup returned from the last run */\n private cleanup: CleanupFn | void = undefined;\n\n /** All deps this effect is subscribed to (for bidirectional cleanup) */\n deps: Set<Dep> = new Set();\n\n constructor(fn: EffectFn) {\n this.id = effectIdCounter++;\n this.fn = fn;\n }\n\n /**\n * Execute the effect function while tracking dependencies.\n */\n run(): void {\n if (!this.active) return;\n\n // Prevent infinite re-entry\n if (effectStack.includes(this)) return;\n\n // Clean up previous dependencies\n this.cleanupDeps();\n\n // Run user cleanup from previous execution\n if (this.cleanup) {\n this.cleanup();\n this.cleanup = undefined;\n }\n\n // Push onto the tracking stack\n effectStack.push(this);\n const prevEffect = activeEffect;\n activeEffect = this;\n\n try {\n const result = this.fn();\n if (typeof result === \"function\") {\n this.cleanup = result;\n }\n } finally {\n activeEffect = prevEffect;\n effectStack.pop();\n }\n }\n\n /**\n * Unsubscribe from all current deps so stale deps don't trigger this effect.\n */\n private cleanupDeps(): void {\n for (const dep of this.deps) {\n dep.subscribers.delete(this);\n }\n this.deps.clear();\n }\n\n /**\n * Notify the scheduler that this effect should re-run.\n */\n notify(): void {\n scheduleEffect(this);\n }\n\n /**\n * Permanently dispose this effect — stop tracking & unsubscribe.\n */\n dispose(): void {\n if (!this.active) return;\n this.active = false;\n\n // Run user cleanup\n if (this.cleanup) {\n this.cleanup();\n this.cleanup = undefined;\n }\n\n this.cleanupDeps();\n unscheduleEffect(this);\n }\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Create a reactive effect.\n *\n * The effect function runs immediately to establish initial dependencies.\n * It re-runs whenever any tracked signal changes.\n * Returns a dispose function to stop the effect.\n *\n * @example\n * const count = signal(0);\n * const dispose = effect(() => {\n * console.log(\"count is\", count.value);\n * });\n * // logs \"count is 0\" immediately\n *\n * count.value = 1;\n * // logs \"count is 1\" on next microtask\n *\n * dispose(); // stops tracking\n */\nexport function effect(fn: EffectFn): CleanupFn {\n const e = new ReactiveEffect(fn);\n // Run immediately (synchronous first run for initial tracking)\n e.run();\n return () => e.dispose();\n}\n\n// ─── Tracking helpers (used by signals/computed) ───────────\n\n/**\n * Track a dependency from the currently active effect.\n * Called by signal.value getters.\n */\nexport function track(dep: Dep): void {\n if (activeEffect) {\n dep.subscribers.add(activeEffect);\n activeEffect.deps.add(dep);\n }\n}\n\n/**\n * Trigger all subscribers of a dependency.\n * Called by signal.value setters.\n */\nexport function trigger(dep: Dep): void {\n // Copy to avoid modification during iteration\n const effects = [...dep.subscribers];\n for (const effect of effects) {\n effect.notify();\n }\n}\n\n/**\n * Returns the currently active effect (for advanced usage).\n */\nexport function getActiveEffect(): ReactiveEffect | null {\n return activeEffect;\n}\n",
11
+ "/**\n * SinwanJS Reactivity — Signal\n *\n * A signal is a reactive container for a single value.\n * Reading `.value` tracks the current effect as a subscriber.\n * Writing `.value` notifies all subscribers.\n *\n * Inspired by Vue 3 ref(), Solid signals, Preact signals.\n */\n\nimport { type Dep, track, trigger } from \"./effect.ts\";\n\n// ─── Signal interface ──────────────────────────────────────\n\nexport interface Signal<T> {\n /** Get or set the reactive value. Reading tracks; writing notifies. */\n value: T;\n\n /** Read the value without tracking dependencies. */\n peek(): T;\n\n /** Manually subscribe to changes. Returns an unsubscribe function. */\n subscribe(fn: (value: T) => void): () => void;\n}\n\n// Brand for type-checking\nconst SIGNAL_BRAND = Symbol(\"Sinwan:signal\");\n\n// ─── Implementation ────────────────────────────────────────\n\nclass SignalImpl<T> implements Signal<T>, Dep {\n [SIGNAL_BRAND] = true;\n\n subscribers = new Set<import(\"./effect.ts\").ReactiveEffect>();\n private _value: T;\n private _manualSubs = new Set<(value: T) => void>();\n\n constructor(initial: T) {\n this._value = initial;\n }\n\n get value(): T {\n track(this);\n return this._value;\n }\n\n set value(newValue: T) {\n if (Object.is(this._value, newValue)) return;\n this._value = newValue;\n trigger(this);\n\n // Notify manual subscribers\n for (const fn of this._manualSubs) {\n fn(newValue);\n }\n }\n\n peek(): T {\n return this._value;\n }\n\n subscribe(fn: (value: T) => void): () => void {\n this._manualSubs.add(fn);\n return () => {\n this._manualSubs.delete(fn);\n };\n }\n\n /**\n * toString() for interpolation in templates.\n */\n toString(): string {\n return String(this.value);\n }\n\n /**\n * valueOf() for numeric operations.\n */\n valueOf(): T {\n return this.value;\n }\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Create a reactive signal.\n *\n * @example\n * const count = signal(0);\n * console.log(count.value); // 0\n *\n * effect(() => {\n * console.log(count.value); // re-runs when count changes\n * });\n *\n * count.value = 5; // triggers the effect\n */\nexport function signal<T>(initial: T): Signal<T> {\n return new SignalImpl(initial);\n}\n\n/**\n * Type guard: check if a value is a Signal.\n */\nexport function isSignal(value: unknown): value is Signal<unknown> {\n return (\n value != null && typeof value === \"object\" && SIGNAL_BRAND in (value as any)\n );\n}\n",
12
+ "/**\n * SinwanJS Reactivity — Computed\n *\n * A computed is a derived reactive value that lazily re-evaluates\n * when its dependencies change. It caches the result and only\n * recomputes when actually read after a dependency has changed.\n *\n * Design: The computed does NOT use the scheduler for its own\n * re-evaluation. When a dependency changes, it marks itself dirty\n * and triggers downstream subscribers (which ARE scheduled).\n * The actual re-evaluation happens lazily on `.value` access.\n *\n * Inspired by Vue 3 computed(), Solid createMemo().\n */\n\nimport { type Dep, track, trigger, ReactiveEffect } from \"./effect.ts\";\n\n// ─── Computed interface ────────────────────────────────────\n\nexport interface Computed<T> {\n /** Read the computed value (lazy evaluation, cached). */\n readonly value: T;\n\n /** Read without tracking. */\n peek(): T;\n}\n\n// Brand for type-checking\nconst COMPUTED_BRAND = Symbol(\"Sinwan:computed\");\n\n// ─── Implementation ────────────────────────────────────────\n\nclass ComputedImpl<T> implements Computed<T>, Dep {\n [COMPUTED_BRAND] = true;\n\n subscribers = new Set<ReactiveEffect>();\n\n _value!: T;\n _dirty = true;\n _effect: ReactiveEffect;\n\n constructor(getter: () => T) {\n const self = this;\n\n // Internal effect solely for dependency tracking.\n // The fn wraps the getter — it writes to self._value as a side effect.\n this._effect = new ReactiveEffect(() => {\n self._value = getter();\n });\n\n // Override notify: don't schedule this effect via the scheduler.\n // Instead mark dirty and propagate to our own subscribers.\n this._effect.notify = function () {\n if (!self._dirty) {\n self._dirty = true;\n trigger(self);\n }\n };\n\n // Run once synchronously to establish deps and cache initial value\n this._effect.run();\n this._dirty = false;\n }\n\n get value(): T {\n track(this);\n\n if (this._dirty) {\n this._effect.run();\n this._dirty = false;\n }\n\n return this._value;\n }\n\n peek(): T {\n if (this._dirty) {\n this._effect.run();\n this._dirty = false;\n }\n return this._value;\n }\n\n /**\n * toString() for template interpolation.\n */\n toString(): string {\n return String(this.value);\n }\n\n /**\n * valueOf() for numeric operations.\n */\n valueOf(): T {\n return this.value;\n }\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Create a computed reactive value.\n *\n * The getter function is tracked — when any signal it reads changes,\n * the computed is marked dirty and will re-evaluate on next `.value` read.\n *\n * @example\n * const count = signal(2);\n * const doubled = computed(() => count.value * 2);\n *\n * console.log(doubled.value); // 4\n *\n * count.value = 5;\n * console.log(doubled.value); // 10\n */\nexport function computed<T>(getter: () => T): Computed<T> {\n return new ComputedImpl(getter);\n}\n\n/**\n * Type guard: check if a value is a Computed.\n */\nexport function isComputed(value: unknown): value is Computed<unknown> {\n return (\n value != null &&\n typeof value === \"object\" &&\n COMPUTED_BRAND in (value as any)\n );\n}\n",
13
+ "/// <reference lib=\"dom\" />\n\n/**\n * SinwanJS Hydration — Marker Protocol\n *\n * Constants and helpers for the hydration marker format:\n *\n * data-sinwan-id=\"c0\" — component boundary\n * <!--sinwan-t:0-->val<!--/sinwan-t--> — reactive text boundary\n * data-sinwan-ev=\"click:0\" — event binding reference\n */\n\n// ─── Constants ─────────────────────────────────────────────\n\n/** Attribute on the root element of each component instance. */\nexport const COMP_ID_ATTR = \"data-sinwan-id\";\n\n/** Prefix for component IDs. */\nexport const COMP_ID_PREFIX = \"c\";\n\n/** Opening comment prefix for reactive text slots: `Sinwan-t:N` */\nexport const TEXT_MARKER_OPEN = \"sinwan-t:\";\n\n/** Closing comment for reactive text slots. */\nexport const TEXT_MARKER_CLOSE = \"/sinwan-t\";\n\n/** Attribute for event binding references. */\nexport const EVENT_ATTR = \"data-sinwan-ev\";\n\n// ─── Server-side marker generation ────────────────────────\n\n/** Build a component ID string, e.g. `\"c0\"`. */\nexport function compId(index: number): string {\n return `${COMP_ID_PREFIX}${index}`;\n}\n\n/** Build an opening text marker comment string. */\nexport function textMarkerOpen(index: number): string {\n return `<!--${TEXT_MARKER_OPEN}${index}-->`;\n}\n\n/** Build a closing text marker comment string. */\nexport function textMarkerCloseStr(): string {\n return `<!--${TEXT_MARKER_CLOSE}-->`;\n}\n\n/** Build an event attribute value, e.g. `\"click:0\"`. */\nexport function eventAttrValue(event: string, index: number): string {\n return `${event}:${index}`;\n}\n\n// ─── Client-side marker parsing ───────────────────────────\n\n/**\n * Check if a comment node is a reactive text opening marker.\n * Returns the slot index, or -1 if not a marker.\n */\nexport function parseTextOpenMarker(node: Comment): number {\n const data = node.data;\n if (data.startsWith(TEXT_MARKER_OPEN)) {\n const idx = parseInt(data.slice(TEXT_MARKER_OPEN.length), 10);\n return Number.isNaN(idx) ? -1 : idx;\n }\n return -1;\n}\n\n/**\n * Check if a comment node is a reactive text closing marker.\n */\nexport function isTextCloseMarker(node: Comment): boolean {\n return node.data === TEXT_MARKER_CLOSE;\n}\n\n/**\n * Parse `data-sinwan-ev` attribute value into event entries.\n * Format: `\"click:0\"` or `\"click:0,input:1\"` for multiple.\n * Returns array of `[eventName, handlerIndex]` tuples.\n */\nexport function parseEventAttr(value: string): [string, number][] {\n return value.split(\",\").map((pair) => {\n const [event, idx] = pair.split(\":\");\n return [event!, parseInt(idx!, 10)];\n });\n}\n\n/**\n * Parse `data-sinwan-id` into the component index.\n * e.g., `\"c3\"` → `3`\n */\nexport function parseCompId(value: string): number {\n return parseInt(value.slice(COMP_ID_PREFIX.length), 10);\n}\n",
14
+ "/// <reference lib=\"dom\" />\n\n/**\n * SinwanJS Client Renderer — DOM Operations\n *\n * Thin abstraction over native DOM APIs for testability\n * and potential future server-side DOM (e.g., happy-dom, linkedom).\n */\n\nexport interface DOMOps {\n createElement(tag: string): Element;\n createTextNode(text: string): Text;\n createComment(text: string): Comment;\n setAttribute(el: Element, key: string, value: string): void;\n removeAttribute(el: Element, key: string): void;\n setProperty(el: Element, key: string, value: unknown): void;\n insertBefore(parent: Node, child: Node, anchor: Node | null): void;\n appendChild(parent: Node, child: Node): void;\n remove(node: Node): void;\n setTextContent(node: Text, text: string): void;\n addEventListener(el: Element, event: string, handler: EventListener): void;\n removeEventListener(el: Element, event: string, handler: EventListener): void;\n parentNode(node: Node): Node | null;\n nextSibling(node: Node): Node | null;\n}\n\n/**\n * Default DOM operations using native browser APIs.\n */\nexport const domOps: DOMOps = {\n createElement(tag: string): Element {\n return document.createElement(tag);\n },\n\n createTextNode(text: string): Text {\n return document.createTextNode(text);\n },\n\n createComment(text: string): Comment {\n return document.createComment(text);\n },\n\n setAttribute(el: Element, key: string, value: string): void {\n el.setAttribute(key, value);\n },\n\n removeAttribute(el: Element, key: string): void {\n el.removeAttribute(key);\n },\n\n setProperty(el: Element, key: string, value: unknown): void {\n (el as any)[key] = value;\n },\n\n insertBefore(parent: Node, child: Node, anchor: Node | null): void {\n parent.insertBefore(child, anchor);\n },\n\n appendChild(parent: Node, child: Node): void {\n parent.appendChild(child);\n },\n\n remove(node: Node): void {\n node.parentNode?.removeChild(node);\n },\n\n setTextContent(node: Text, text: string): void {\n node.data = text;\n },\n\n addEventListener(el: Element, event: string, handler: EventListener): void {\n el.addEventListener(event, handler);\n },\n\n removeEventListener(el: Element, event: string, handler: EventListener): void {\n el.removeEventListener(event, handler);\n },\n\n parentNode(node: Node): Node | null {\n return node.parentNode;\n },\n\n nextSibling(node: Node): Node | null {\n return node.nextSibling;\n },\n};\n",
15
+ "/// <reference lib=\"dom\" />\n\n/**\n * SinwanJS Client Renderer — Event Binding\n *\n * Direct event binding (not delegation). Each handler is attached\n * directly to its target element for simplicity and easy hydration.\n *\n * Design decision: direct binding like Solid.js, not delegation like React.\n */\n\nimport { domOps } from \"./dom-ops.ts\";\nimport type { CleanupFn } from \"../reactivity/index.ts\";\n\n/**\n * Check if a prop key is an event handler (starts with \"on\").\n */\nexport function isEventProp(key: string): boolean {\n return key.length > 2 && key[0] === \"o\" && key[1] === \"n\" && key[2]! >= \"A\" && key[2]! <= \"Z\";\n}\n\n/**\n * Extract the DOM event name from a prop key.\n * e.g., \"onClick\" → \"click\", \"onMouseEnter\" → \"mouseenter\"\n */\nexport function toEventName(key: string): string {\n return key.slice(2).toLowerCase();\n}\n\n/**\n * Bind an event handler to an element.\n * Returns a cleanup function to remove the listener.\n */\nexport function bindEvent(\n el: Element,\n eventName: string,\n handler: EventListener,\n): CleanupFn {\n domOps.addEventListener(el, eventName, handler);\n return () => {\n domOps.removeEventListener(el, eventName, handler);\n };\n}\n\n/**\n * Bind all event props from an element's props object.\n * Returns an array of cleanup functions.\n */\nexport function bindEvents(\n el: Element,\n props: Record<string, unknown>,\n): CleanupFn[] {\n const cleanups: CleanupFn[] = [];\n\n for (const key of Object.keys(props)) {\n if (isEventProp(key)) {\n const handler = props[key];\n if (typeof handler === \"function\") {\n const eventName = toEventName(key);\n cleanups.push(bindEvent(el, eventName, handler as EventListener));\n }\n }\n }\n\n return cleanups;\n}\n",
16
+ "/**\n * SinwanJS Component Runtime — Instance Management\n *\n * Each component rendered on the client gets a ComponentInstance\n * that tracks its lifecycle hooks, effects, parent/child tree,\n * and provide/inject context.\n *\n * A global `currentInstance` stack lets lifecycle hooks (onMounted, etc.)\n * register themselves during setup — same pattern as Vue's getCurrentInstance.\n */\n\nimport type { SinwanComponent } from \"../types.ts\";\nimport type { MountedNode } from \"../renderer/types.ts\";\nimport type { CleanupFn } from \"../reactivity/index.ts\";\n\n// ─── ComponentInstance ─────────────────────────────────────\n\nlet uidCounter = 0;\n\nexport interface ComponentInstance {\n /** Unique identifier for this instance. */\n uid: number;\n\n /** The component definition (setup function). */\n component: SinwanComponent<any>;\n\n /** Props passed to this component. */\n props: Record<string, any>;\n\n /** The rendered DOM subtree (set after render). */\n element: MountedNode | null;\n\n /** Parent instance in the component tree. */\n parent: ComponentInstance | null;\n\n /** Child component instances. */\n children: ComponentInstance[];\n\n /** All effect dispose functions owned by this component. */\n effects: CleanupFn[];\n\n // ─── Lifecycle hook queues ────────────────────────────\n\n /** Callbacks to fire after the component is mounted to DOM. */\n _mountedHooks: (() => void)[];\n\n /** Callbacks to fire when the component is unmounted. */\n _unmountedHooks: (() => void)[];\n\n /** Callbacks to fire after any reactive update in this component. */\n _updatedHooks: (() => void)[];\n\n /** Error handler callbacks. */\n _errorHooks: ((err: Error) => void)[];\n\n // ─── Provide/Inject context ───────────────────────────\n\n /** Values provided by this instance (for inject in children). */\n provides: Record<string | symbol, unknown>;\n\n // ─── State flags ──────────────────────────────────────\n\n isMounted: boolean;\n isUnmounted: boolean;\n}\n\n/**\n * Create a fresh ComponentInstance.\n */\nexport function createComponentInstance(\n component: SinwanComponent<any>,\n props: Record<string, any>,\n parent: ComponentInstance | null,\n): ComponentInstance {\n return {\n uid: uidCounter++,\n component,\n props,\n element: null,\n parent,\n children: [],\n effects: [],\n _mountedHooks: [],\n _unmountedHooks: [],\n _updatedHooks: [],\n _errorHooks: [],\n // Inherit parent's provides (prototype chain for lookup)\n provides: parent ? Object.create(parent.provides) : Object.create(null),\n isMounted: false,\n isUnmounted: false,\n };\n}\n\n// ─── Current instance stack ────────────────────────────────\n\nlet currentInstance: ComponentInstance | null = null;\n\n/**\n * Get the currently active component instance.\n * Used by lifecycle hooks to register themselves.\n */\nexport function getCurrentInstance(): ComponentInstance | null {\n return currentInstance;\n}\n\n/**\n * Set the current instance (called by renderer before setup).\n * Returns the previous instance for restoration.\n */\nexport function setCurrentInstance(\n instance: ComponentInstance | null,\n): ComponentInstance | null {\n const prev = currentInstance;\n currentInstance = instance;\n return prev;\n}\n\n/**\n * Run a function with `instance` as the current component instance.\n * Automatically restores the previous instance when done.\n */\nexport function withInstance<T>(instance: ComponentInstance, fn: () => T): T {\n const prev = setCurrentInstance(instance);\n try {\n return fn();\n } finally {\n setCurrentInstance(prev);\n }\n}\n\n// ─── Lifecycle execution ───────────────────────────────────\n\n/**\n * Fire all onMounted hooks for an instance and its children (depth-first).\n */\nexport function fireMountedHooks(instance: ComponentInstance): void {\n // Children first (bottom-up, like Vue)\n for (const child of instance.children) {\n fireMountedHooks(child);\n }\n\n if (!instance.isMounted) {\n instance.isMounted = true;\n for (const hook of instance._mountedHooks) {\n hook();\n }\n }\n}\n\n/**\n * Fire all onUnmounted hooks and dispose all effects for an instance\n * and its children (depth-first, children first).\n */\nexport function fireUnmountedHooks(instance: ComponentInstance): void {\n // Children first\n for (const child of instance.children) {\n fireUnmountedHooks(child);\n }\n\n if (instance.isMounted && !instance.isUnmounted) {\n instance.isUnmounted = true;\n instance.isMounted = false;\n\n // Fire unmounted hooks\n for (const hook of instance._unmountedHooks) {\n hook();\n }\n\n // Dispose all effects owned by this component\n for (const dispose of instance.effects) {\n dispose();\n }\n instance.effects.length = 0;\n }\n}\n\n/**\n * Fire onUpdated hooks for the current instance.\n */\nexport function fireUpdatedHooks(instance: ComponentInstance): void {\n for (const hook of instance._updatedHooks) {\n hook();\n }\n}\n\n/**\n * Handle an error in the component tree — walks up to find an error handler.\n */\nexport function handleComponentError(\n instance: ComponentInstance,\n err: Error,\n): void {\n let current: ComponentInstance | null = instance;\n while (current) {\n if (current._errorHooks.length > 0) {\n for (const hook of current._errorHooks) {\n hook(err);\n }\n return;\n }\n current = current.parent;\n }\n // No handler found — re-throw\n console.error(\"[Sinwan] Unhandled component error:\", err);\n}\n",
17
+ "/**\n * SinwanJS Server — Hydration-Aware SSR Renderer\n *\n * Enhanced `renderToString` that injects hydration markers:\n *\n * data-sinwan-id=\"c0\" — component boundary\n * <!--sinwan-t:0-->val<!--/sinwan-t--> — reactive text boundary\n * data-sinwan-ev=\"click:0\" — event binding reference\n *\n * Usage:\n * const html = await renderToHydratableString(App, { name: \"World\" });\n * // → '<div data-sinwan-id=\"c0\"><p>Count: <!--sinwan-t:0-->5<!--/sinwan-t--></p>...</div>'\n */\n\nimport type { SinwanElement, SinwanNode, SinwanComponent } from \"../types.ts\";\nimport { HtmlEscapedString, escapeHtml } from \"../escaper.ts\";\nimport { isSignal } from \"../reactivity/signal.ts\";\nimport { isComputed } from \"../reactivity/computed.ts\";\nimport {\n compId,\n textMarkerOpen,\n textMarkerCloseStr,\n COMP_ID_ATTR,\n EVENT_ATTR,\n} from \"../hydration/markers.ts\";\nimport { isEventProp, toEventName } from \"../renderer/events.ts\";\nimport {\n createComponentInstance,\n setCurrentInstance,\n} from \"../component/instance.ts\";\n\n// ─── Hydration context ─────────────────────────────────────\n\ninterface HydrationContext {\n componentIndex: number;\n textIndex: number;\n eventIndex: number;\n}\n\nfunction createHydrationContext(): HydrationContext {\n return { componentIndex: 0, textIndex: 0, eventIndex: 0 };\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Render a component to an HTML string with hydration markers.\n */\nexport async function renderToHydratableString(\n component: SinwanComponent<any>,\n props?: Record<string, unknown>,\n): Promise<string> {\n const ctx = createHydrationContext();\n const mergedProps = props ?? {};\n\n // Create a temporary instance so lifecycle hooks register silently\n const instance = createComponentInstance(component, mergedProps, null);\n setCurrentInstance(instance);\n\n // Call the component to get the element tree\n const result = await component(mergedProps);\n\n setCurrentInstance(null);\n\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return renderElementH(result, ctx, true /* isComponentRoot */);\n }\n\n return renderNodeH(result as SinwanNode, ctx);\n}\n\n/**\n * Render a raw SinwanNode tree with hydration markers.\n */\nexport async function renderNodeToHydratableString(\n node: SinwanNode,\n): Promise<string> {\n const ctx = createHydrationContext();\n return renderNodeH(node, ctx);\n}\n\n// ─── Internal rendering ────────────────────────────────────\n\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Render a node with hydration markers.\n */\nfunction renderNodeH(node: SinwanNode, ctx: HydrationContext): string {\n if (node == null || typeof node === \"boolean\") return \"\";\n\n if (typeof node === \"string\") return escapeHtml(node);\n if (typeof node === \"number\") return String(node);\n\n if (node instanceof HtmlEscapedString) return node.value;\n\n // Signal or Computed → wrap with text markers\n if (isSignal(node) || isComputed(node)) {\n const value = (node as any).value;\n const idx = ctx.textIndex++;\n return `${textMarkerOpen(idx)}${escapeHtml(String(value))}${textMarkerCloseStr()}`;\n }\n\n if (Array.isArray(node)) {\n return node.map((child) => renderNodeH(child, ctx)).join(\"\");\n }\n\n if (node instanceof Promise) {\n // Sync-only for hydration SSR — await should be handled at top level\n return \"\";\n }\n\n if (typeof node === \"object\" && \"tag\" in node) {\n return renderElementH(node, ctx, false);\n }\n\n return escapeHtml(String(node));\n}\n\n/**\n * Render an element with hydration markers.\n */\nfunction renderElementH(\n element: SinwanElement,\n ctx: HydrationContext,\n isComponentRoot: boolean,\n): string {\n const { tag, props, children } = element;\n\n // Fragment\n if (tag === \"\") {\n return children.map((child) => renderNodeH(child, ctx)).join(\"\");\n }\n\n // Functional component\n if (typeof tag === \"function\") {\n return renderComponentH(tag, props, ctx);\n }\n\n // Intrinsic HTML element\n if (typeof tag === \"string\") {\n return renderIntrinsicH(tag, props, children, ctx, isComponentRoot);\n }\n\n return children.map((child) => renderNodeH(child, ctx)).join(\"\");\n}\n\n/**\n * Render a functional component — calls it and marks the root element.\n */\nfunction renderComponentH(\n component: Function,\n props: Record<string, unknown>,\n ctx: HydrationContext,\n): string {\n // Set a temporary instance for lifecycle hooks\n const parentInstance = (globalThis as any).__SinwanCurrentInstance;\n const instance = createComponentInstance(component as any, props, null);\n const prev = setCurrentInstance(instance);\n\n const result = component(props);\n\n setCurrentInstance(prev);\n\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return renderElementH(\n result as SinwanElement,\n ctx,\n true /* mark as component root */,\n );\n }\n\n return renderNodeH(result as SinwanNode, ctx);\n}\n\n/**\n * Render an intrinsic element with hydration markers.\n */\nfunction renderIntrinsicH(\n tag: string,\n props: Record<string, unknown>,\n children: SinwanNode[],\n ctx: HydrationContext,\n isComponentRoot: boolean,\n): string {\n let attrs = \"\";\n\n // Component boundary marker\n if (isComponentRoot) {\n attrs += ` ${COMP_ID_ATTR}=\"${compId(ctx.componentIndex++)}\"`;\n }\n\n // Event markers + regular attributes\n const eventParts: string[] = [];\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\" || key === \"dangerouslySetInnerHTML\") continue;\n\n if (isEventProp(key)) {\n // Collect event markers\n const eventName = toEventName(key);\n eventParts.push(`${eventName}:${ctx.eventIndex++}`);\n continue;\n }\n\n if (value == null || value === false) continue;\n\n // Resolve signal/computed values to their current values for SSR\n let resolvedValue = value;\n if (isSignal(value) || isComputed(value)) {\n resolvedValue = (value as any).value;\n }\n\n if (resolvedValue === true) {\n const attrName =\n key === \"className\" ? \"class\" : key === \"htmlFor\" ? \"for\" : key;\n attrs += ` ${attrName}`;\n continue;\n }\n\n const attrName =\n key === \"className\" ? \"class\" : key === \"htmlFor\" ? \"for\" : key;\n attrs += ` ${attrName}=\"${escapeHtml(String(resolvedValue))}\"`;\n }\n\n // Add event attribute\n if (eventParts.length > 0) {\n attrs += ` ${EVENT_ATTR}=\"${eventParts.join(\",\")}\"`;\n }\n\n // Void elements\n if (VOID_ELEMENTS.has(tag)) {\n return `<${tag}${attrs}>`;\n }\n\n // Dangerous inner HTML\n const dangerous = props.dangerouslySetInnerHTML as\n | { __html?: string }\n | undefined;\n if (dangerous && typeof dangerous.__html === \"string\") {\n return `<${tag}${attrs}>${dangerous.__html}</${tag}>`;\n }\n\n // Render children with markers\n const childrenHtml = children\n .map((child) => renderNodeH(child, ctx))\n .join(\"\");\n\n return `<${tag}${attrs}>${childrenHtml}</${tag}>`;\n}\n"
18
+ ],
19
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUO,IAAM,WAAW,OAAO,UAAU;AAAA;AAMlC,MAAM,0BAA0B,OAAO;AAAA,EAChB;AAAA,EAA5B,WAAW,CAAiB,OAAe;AAAA,IACzC,MAAM,KAAK;AAAA,IADe;AAAA;AAAA,EAGnB,QAAQ,GAAG;AAAA,IAClB,OAAO,KAAK;AAAA;AAEhB;AAEO,IAAM,MAAM,CAAC,QAAgB,IAAI,kBAAkB,GAAG;AAG7D,IAAM,gBAAgB,IAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKD,SAAS,iBAAiB,CAAC,UAA6B;AAAA,EACtD,IAAI,YAAY,QAAQ,OAAO,aAAa;AAAA,IAAW,OAAO,CAAC;AAAA,EAC/D,IAAI,MAAM,QAAQ,QAAQ;AAAA,IAAG,OAAO,SAAS,KAAK,QAAQ;AAAA,EAC1D,OAAO,CAAC,QAAQ;AAAA;AAOlB,SAAS,YAAY,CACnB,MACA,OACA,UACe;AAAA,EAEf,IAAI,SAAS,UAAU;AAAA,IACrB,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC,GAAG,SAAS;AAAA,EACxC;AAAA,EAGA,IAAI,OAAO,SAAS,YAAY;AAAA,IAE9B,IAAI,KAAK,oBAAoB,KAAK,aAAa;AAAA,MAC7C,MAAM,UAAS,KAAK,KAAK;AAAA,MACzB,IAAI,WAAU,OAAO,YAAW,YAAY,SAAS,SAAQ;AAAA,QAC3D,OAAO;AAAA,MACT;AAAA,MACA,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC,GAAG,UAAU,kBAAkB,OAAM,EAAE;AAAA,IACnE;AAAA,IAGA,MAAM,SAAS,KAAK,KAAK;AAAA,IACzB,IAAI,UAAU,OAAO,WAAW,YAAY,SAAS,QAAQ;AAAA,MAC3D,OAAO;AAAA,IACT;AAAA,IACA,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC,GAAG,UAAU,kBAAkB,MAAM,EAAE;AAAA,EACnE;AAAA,EAGA,IAAI,OAAO,SAAS,UAAU;AAAA,IAC5B,OAAO,EAAE,KAAK,MAAM,OAAO,SAAS,CAAC,GAAG,SAAS;AAAA,EACnD;AAAA,EAGA,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC,GAAG,SAAS;AAAA;AAOjC,SAAS,GAAG,CAAC,MAAW,OAAY,KAA0B;AAAA,EACnE,OAAO,aAAa,MAAM,OAAO,kBAAkB,OAAO,QAAQ,CAAC;AAAA;AAO9D,SAAS,IAAI,CAAC,MAAW,OAAY,KAA0B;AAAA,EACpE,MAAM,WAAW,OAAO;AAAA,EAExB,OAAO,aACL,MACA,OACA,MAAM,QAAQ,QAAQ,IAClB,SAAS,KAAK,QAAQ,IACtB,kBAAkB,QAAQ,CAChC;AAAA;AAgBK,SAAS,MAAM,CACpB,MACA,OACA,KACA,kBACA,QACA,MACe;AAAA,EACf,MAAM,WAAW,mBACb,MAAM,QAAQ,OAAO,QAAQ,IAC3B,MAAM,SAAS,KAAK,QAAQ,IAC5B,kBAAkB,OAAO,QAAQ,IACnC,kBAAkB,OAAO,QAAQ;AAAA,EAErC,MAAM,UAAU,aAAa,MAAM,OAAO,QAAQ;AAAA,EAGlD,IAAI,QAAQ;AAAA,IACT,QAAgB,WAAW;AAAA,EAC9B;AAAA,EAEA,OAAO;AAAA;;;;;;;;;;;;;;;;;;AC1IT,IAAM,OAAQ,WAAmB;AAIjC,IAAM,gBACJ,OAAO,MAAM,eAAe,aACxB,KAAK,WAAW,KAAK,IAAI,IACzB;AAIN,IAAM,iBAAiB;AACvB,IAAM,kBAA0C;AAAA,EAC9C,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEA,SAAS,cAAc,CAAC,KAAqB;AAAA,EAE3C,eAAe,YAAY;AAAA,EAC3B,IAAI,CAAC,eAAe,KAAK,GAAG;AAAA,IAAG,OAAO;AAAA,EACtC,OAAO,IAAI,QAAQ,gBAAgB,CAAC,MAAM,gBAAgB,EAAG;AAAA;AAQxD,SAAS,UAAU,CAAC,OAAwB;AAAA,EACjD,IAAI,SAAS,QAAQ,OAAO,UAAU;AAAA,IAAW,OAAO;AAAA,EACxD,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,OAAO,KAAK;AAAA,EAClD,IAAI,iBAAiB;AAAA,IAAmB,OAAO,MAAM;AAAA,EACrD,MAAM,IAAI,OAAO,KAAK;AAAA,EACtB,OAAO,gBAAgB,cAAc,CAAC,IAAI,eAAe,CAAC;AAAA;AAOrD,SAAS,QAAQ,CAAC,MAAiC;AAAA,EACxD,OAAO,IAAI,IAAI;AAAA;AAMV,SAAS,UAAU,CAAC,OAA4C;AAAA,EACrE,OAAO,iBAAiB;AAAA;;;ACnD1B,IAAM,iBAAiB,IAAI;AAG3B,IAAM,eAAe,IAAI;AAKlB,SAAS,YAAmC,CACjD,MACA,MACM;AAAA,EACN,aAAa,IAAI,MAAM,IAAI;AAAA;AAMtB,SAAS,OAA8B,CAC5C,MAC2B;AAAA,EAC3B,OAAO,aAAa,IAAI,IAAI;AAAA;AAMvB,SAAS,OAAO,CAAC,MAAuB;AAAA,EAC7C,OAAO,aAAa,IAAI,IAAI;AAAA;AAM9B,eAAsB,UAAiC,CACrD,MACA,MACiB;AAAA,EACjB,MAAM,OAAO,QAAW,IAAI;AAAA,EAC5B,IAAI,CAAC,MAAM;AAAA,IACT,MAAM,IAAI,MAAM,SAAS,6BAA6B;AAAA,EACxD;AAAA,EAEA,MAAM,UAAU,MAAM,KAAK,IAAI;AAAA,EAC/B,OAAO,eAAe,OAAO;AAAA;AAO/B,eAAsB,cAAc,CAAC,MAAmC;AAAA,EAEtE,IAAI,QAAQ,QAAQ,OAAO,SAAS,WAAW;AAAA,IAC7C,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,OAAO,SAAS,UAAU;AAAA,IAC5B,OAAO,WAAW,IAAI;AAAA,EACxB;AAAA,EAGA,IAAI,OAAO,SAAS,UAAU;AAAA,IAC5B,OAAO,OAAO,IAAI;AAAA,EACpB;AAAA,EAGA,IAAI,gBAAgB,mBAAmB;AAAA,IACrC,OAAO,KAAK;AAAA,EACd;AAAA,EAGA,IAAI,MAAM,QAAQ,IAAI,GAAG;AAAA,IACvB,MAAM,UAAU,MAAM,QAAQ,IAC5B,KAAK,IAAI,CAAC,UAAU,eAAe,KAAK,CAAC,CAC3C;AAAA,IACA,OAAO,QAAQ,KAAK,EAAE;AAAA,EACxB;AAAA,EAGA,IAAI,gBAAgB,SAAS;AAAA,IAC3B,OAAO,cAAc,MAAM,IAAI;AAAA,EACjC;AAAA,EAGA,OAAO,cAAc,IAAI;AAAA;AAM3B,eAAe,aAAa,CAAC,SAAyC;AAAA,EACpE,QAAQ,KAAK,OAAO,aAAa;AAAA,EAGjC,IAAI,OAAO,QAAQ,YAAY;AAAA,IAC7B,MAAM,SAAS,MAAM,IAAI,KAAK;AAAA,IAC9B,OAAO,eAAe,MAAM;AAAA,EAC9B;AAAA,EAGA,IAAI,OAAO,QAAQ,UAAU;AAAA,IAC3B,OAAO,uBAAuB,KAAK,OAAO,QAAQ;AAAA,EACpD;AAAA,EAGA,OAAO,eAAe,QAAQ;AAAA;AAIhC,IAAM,iBAAgB,IAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKD,eAAe,sBAAsB,CACnC,KACA,OACA,UACiB;AAAA,EACjB,MAAM,QAAQ,iBAAiB,KAAK;AAAA,EAGpC,IAAI,eAAc,IAAI,GAAG,GAAG;AAAA,IAC1B,OAAO,QAAQ,IAAI,MAAM,WAAW,IAAI;AAAA,EAC1C;AAAA,EAGA,MAAM,eAAe,MAAM,eAAe,UAAU,KAAK;AAAA,EAGzD,OAAO,QACH,IAAI,MAAM,SAAS,iBAAiB,SACpC,IAAI,OAAO,iBAAiB;AAAA;AAMlC,SAAS,gBAAgB,CAAC,OAAwC;AAAA,EAChE,IAAI,QAAQ;AAAA,EAEZ,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IAEhD,IAAI,QAAQ;AAAA,MAAY;AAAA,IAGxB,IAAI,SAAS,QAAQ,UAAU;AAAA,MAAO;AAAA,IAGtC,IAAI,UAAU,MAAM;AAAA,MAClB,SAAS,IAAI;AAAA,MACb;AAAA,IACF;AAAA,IAGA,IAAI,QAAQ,2BAA2B;AAAA,MAErC;AAAA,IACF;AAAA,IAGA,MAAM,WAAW,QAAQ,cAAc,UAAU;AAAA,IAGjD,MAAM,YAAY,aAAa,YAAY,QAAQ;AAAA,IAGnD,MAAM,YAAY,WAAW,OAAO,KAAK,CAAC;AAAA,IAC1C,SAAS,IAAI,cAAc;AAAA,EAC7B;AAAA,EAEA,OAAO;AAAA;AAMT,eAAe,cAAc,CAC3B,UACA,OACiB;AAAA,EAEjB,MAAM,YAAY,MAAM;AAAA,EAGxB,IAAI,aAAa,OAAO,UAAU,WAAW,UAAU;AAAA,IACrD,OAAO,UAAU;AAAA,EACnB;AAAA,EAEA,OAAO,eAAe,QAAQ;AAAA;AASzB,SAAS,OAAO,CAAC,UAA4C;AAAA,EAClE,OACE,YAAY,QACZ,OAAO,aAAa,YACpB,CAAC,MAAM,QAAQ,QAAQ,KACvB,EAAE,oBAAoB;AAAA;;AClO1B,IAAM,iBAAgB,IAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,SAAS,UAAiC,CAC/C,MACA,MAC4B;AAAA,EAC5B,MAAM,UAAU,IAAI;AAAA,EAEpB,OAAO,IAAI,eAAe;AAAA,SAClB,MAAK,CAAC,YAAY;AAAA,MACtB,IAAI;AAAA,QAEF,MAAM,UAAU,MAAM,KAAK,IAAI;AAAA,QAG/B,MAAM,WAAW,SAAS,YAAY,OAAO;AAAA,QAG7C,WAAW,MAAM;AAAA,QACjB,OAAO,OAAO;AAAA,QACd,WAAW,MAAM,KAAK;AAAA;AAAA;AAAA,EAG5B,CAAC;AAAA;AAMH,eAAe,UAAU,CACvB,MACA,YACA,SACe;AAAA,EAEf,IAAI,QAAQ,QAAQ,OAAO,SAAS,WAAW;AAAA,IAC7C;AAAA,EACF;AAAA,EAGA,IAAI,OAAO,SAAS,UAAU;AAAA,IAC5B,WAAW,QAAQ,QAAQ,OAAO,WAAW,IAAI,CAAC,CAAC;AAAA,IACnD;AAAA,EACF;AAAA,EAGA,IAAI,OAAO,SAAS,UAAU;AAAA,IAC5B,WAAW,QAAQ,QAAQ,OAAO,OAAO,IAAI,CAAC,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EAGA,IAAI,gBAAgB,mBAAmB;AAAA,IACrC,WAAW,QAAQ,QAAQ,OAAO,KAAK,KAAK,CAAC;AAAA,IAC7C;AAAA,EACF;AAAA,EAGA,IAAI,MAAM,QAAQ,IAAI,GAAG;AAAA,IACvB,WAAW,SAAS,MAAM;AAAA,MACxB,MAAM,WAAW,OAAO,YAAY,OAAO;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AAAA,EAGA,IAAI,gBAAgB,SAAS;AAAA,IAC3B,MAAM,WAAW,MAAM;AAAA,IACvB,MAAM,cAAc,UAAU,YAAY,OAAO;AAAA,IACjD;AAAA,EACF;AAAA,EAGA,MAAM,cAAc,MAAM,YAAY,OAAO;AAAA;AAM/C,eAAe,aAAa,CAC1B,SACA,YACA,SACe;AAAA,EACf,QAAQ,KAAK,OAAO,aAAa;AAAA,EAGjC,IAAI,OAAO,QAAQ,YAAY;AAAA,IAC7B,MAAM,SAAS,MAAM,IAAI,KAAK;AAAA,IAC9B,MAAM,WAAW,QAAQ,YAAY,OAAO;AAAA,IAC5C;AAAA,EACF;AAAA,EAGA,IAAI,OAAO,QAAQ,UAAU;AAAA,IAC3B,MAAM,uBAAuB,KAAK,OAAO,UAAU,YAAY,OAAO;AAAA,IACtE;AAAA,EACF;AAAA,EAGA,MAAM,WAAW,UAAU,YAAY,OAAO;AAAA;AAMhD,eAAe,sBAAsB,CACnC,KACA,OACA,UACA,YACA,SACe;AAAA,EACf,MAAM,QAAQ,kBAAiB,KAAK;AAAA,EAGpC,MAAM,YAAY,MAAM;AAAA,EAKxB,IAAI,eAAc,IAAI,GAAG,GAAG;AAAA,IAC1B,MAAM,OAAO,QAAQ,IAAI,MAAM,WAAW,IAAI;AAAA,IAC9C,WAAW,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACvC;AAAA,EACF;AAAA,EAGA,MAAM,UAAU,QAAQ,IAAI,MAAM,WAAW,IAAI;AAAA,EACjD,WAAW,QAAQ,QAAQ,OAAO,OAAO,CAAC;AAAA,EAG1C,IAAI,aAAa,OAAO,UAAU,WAAW,UAAU;AAAA,IACrD,WAAW,QAAQ,QAAQ,OAAO,UAAU,MAAM,CAAC;AAAA,EACrD,EAAO;AAAA,IACL,MAAM,WAAW,UAAU,YAAY,OAAO;AAAA;AAAA,EAIhD,WAAW,QAAQ,QAAQ,OAAO,KAAK,MAAM,CAAC;AAAA;AAMhD,SAAS,iBAAgB,CAAC,OAAwC;AAAA,EAChE,IAAI,QAAQ;AAAA,EAEZ,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IAChD,IAAI,QAAQ,cAAc,QAAQ;AAAA,MAA2B;AAAA,IAC7D,IAAI,SAAS,QAAQ,UAAU;AAAA,MAAO;AAAA,IAEtC,IAAI,UAAU,MAAM;AAAA,MAClB,SAAS,IAAI;AAAA,MACb;AAAA,IACF;AAAA,IAEA,MAAM,WACJ,QAAQ,cAAc,UAAU,QAAQ,YAAY,QAAQ;AAAA,IAC9D,MAAM,YAAY,WAAW,OAAO,KAAK,CAAC;AAAA,IAC1C,SAAS,IAAI,aAAa;AAAA,EAC5B;AAAA,EAEA,OAAO;AAAA;;AClLT,IAAM,iBAAiB,IAAI;AAC3B,IAAI,iBAAiB;AACrB,IAAI,aAAa;AAGjB,IAAM,mBAAmC,CAAC;AAKnC,SAAS,cAAc,CAAC,QAA0B;AAAA,EACvD,IAAI,CAAC,OAAO;AAAA,IAAQ;AAAA,EACpB,eAAe,IAAI,MAAM;AAAA,EACzB,cAAc;AAAA;AAMT,SAAS,gBAAgB,CAAC,QAA0B;AAAA,EACzD,eAAe,OAAO,MAAM;AAAA;AAM9B,SAAS,aAAa,GAAS;AAAA,EAC7B,IAAI,CAAC,gBAAgB;AAAA,IACnB,iBAAiB;AAAA,IACjB,eAAe,KAAK;AAAA,EACtB;AAAA;AAOF,SAAS,KAAK,GAAS;AAAA,EACrB,aAAa;AAAA,EAGb,MAAM,SAAS,CAAC,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;AAAA,EAC7D,eAAe,MAAM;AAAA,EAErB,WAAW,UAAU,QAAQ;AAAA,IAC3B,IAAI,OAAO,QAAQ;AAAA,MACjB,OAAO,IAAI;AAAA,IACb;AAAA,EACF;AAAA,EAIA,IAAI,SAAS;AAAA,EACb,OAAO,eAAe,OAAO,KAAK,WAAW,GAAG;AAAA,IAC9C,MAAM,OAAO,CAAC,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;AAAA,IAC3D,eAAe,MAAM;AAAA,IACrB,WAAW,UAAU,MAAM;AAAA,MACzB,IAAI,OAAO,QAAQ;AAAA,QACjB,OAAO,IAAI;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EAEA,iBAAiB;AAAA,EACjB,aAAa;AAAA,EAGb,MAAM,MAAM,iBAAiB,OAAO,CAAC;AAAA,EACrC,WAAW,MAAM,KAAK;AAAA,IACpB,GAAG;AAAA,EACL;AAAA;AAcK,SAAS,QAAQ,CAAC,IAAgC;AAAA,EACvD,OAAO,IAAI,QAAc,CAAC,YAAY;AAAA,IACpC,MAAM,WAAW,MAAM;AAAA,MACrB,KAAK;AAAA,MACL,QAAQ;AAAA;AAAA,IAEV,IAAI,kBAAkB,YAAY;AAAA,MAEhC,iBAAiB,KAAK,QAAQ;AAAA,IAChC,EAAO;AAAA,MAEL,eAAe,QAAQ;AAAA;AAAA,GAE1B;AAAA;AAOI,SAAS,SAAS,GAAS;AAAA,EAChC,IAAI,gBAAgB;AAAA,IAClB,iBAAiB;AAAA,IACjB,MAAM;AAAA,EACR;AAAA;;;AC9GF,IAAI,eAAsC;AAC1C,IAAM,cAAgC,CAAC;AACvC,IAAI,kBAAkB;AAAA;AAiBf,MAAM,eAAqC;AAAA,EAChD;AAAA,EACA,SAAS;AAAA,EAGD;AAAA,EAGA,UAA4B;AAAA,EAGpC,OAAiB,IAAI;AAAA,EAErB,WAAW,CAAC,IAAc;AAAA,IACxB,KAAK,KAAK;AAAA,IACV,KAAK,KAAK;AAAA;AAAA,EAMZ,GAAG,GAAS;AAAA,IACV,IAAI,CAAC,KAAK;AAAA,MAAQ;AAAA,IAGlB,IAAI,YAAY,SAAS,IAAI;AAAA,MAAG;AAAA,IAGhC,KAAK,YAAY;AAAA,IAGjB,IAAI,KAAK,SAAS;AAAA,MAChB,KAAK,QAAQ;AAAA,MACb,KAAK,UAAU;AAAA,IACjB;AAAA,IAGA,YAAY,KAAK,IAAI;AAAA,IACrB,MAAM,aAAa;AAAA,IACnB,eAAe;AAAA,IAEf,IAAI;AAAA,MACF,MAAM,SAAS,KAAK,GAAG;AAAA,MACvB,IAAI,OAAO,WAAW,YAAY;AAAA,QAChC,KAAK,UAAU;AAAA,MACjB;AAAA,cACA;AAAA,MACA,eAAe;AAAA,MACf,YAAY,IAAI;AAAA;AAAA;AAAA,EAOZ,WAAW,GAAS;AAAA,IAC1B,WAAW,OAAO,KAAK,MAAM;AAAA,MAC3B,IAAI,YAAY,OAAO,IAAI;AAAA,IAC7B;AAAA,IACA,KAAK,KAAK,MAAM;AAAA;AAAA,EAMlB,MAAM,GAAS;AAAA,IACb,eAAe,IAAI;AAAA;AAAA,EAMrB,OAAO,GAAS;AAAA,IACd,IAAI,CAAC,KAAK;AAAA,MAAQ;AAAA,IAClB,KAAK,SAAS;AAAA,IAGd,IAAI,KAAK,SAAS;AAAA,MAChB,KAAK,QAAQ;AAAA,MACb,KAAK,UAAU;AAAA,IACjB;AAAA,IAEA,KAAK,YAAY;AAAA,IACjB,iBAAiB,IAAI;AAAA;AAEzB;AAuBO,SAAS,MAAM,CAAC,IAAyB;AAAA,EAC9C,MAAM,IAAI,IAAI,eAAe,EAAE;AAAA,EAE/B,EAAE,IAAI;AAAA,EACN,OAAO,MAAM,EAAE,QAAQ;AAAA;AASlB,SAAS,KAAK,CAAC,KAAgB;AAAA,EACpC,IAAI,cAAc;AAAA,IAChB,IAAI,YAAY,IAAI,YAAY;AAAA,IAChC,aAAa,KAAK,IAAI,GAAG;AAAA,EAC3B;AAAA;AAOK,SAAS,OAAO,CAAC,KAAgB;AAAA,EAEtC,MAAM,UAAU,CAAC,GAAG,IAAI,WAAW;AAAA,EACnC,WAAW,WAAU,SAAS;AAAA,IAC5B,QAAO,OAAO;AAAA,EAChB;AAAA;;;AC9IF,IAAM,eAAe,OAAO,eAAe;AAAA;AAI3C,MAAM,WAAwC;AAAA,GAC3C,gBAAgB;AAAA,EAEjB,cAAc,IAAI;AAAA,EACV;AAAA,EACA,cAAc,IAAI;AAAA,EAE1B,WAAW,CAAC,SAAY;AAAA,IACtB,KAAK,SAAS;AAAA;AAAA,MAGZ,KAAK,GAAM;AAAA,IACb,MAAM,IAAI;AAAA,IACV,OAAO,KAAK;AAAA;AAAA,MAGV,KAAK,CAAC,UAAa;AAAA,IACrB,IAAI,OAAO,GAAG,KAAK,QAAQ,QAAQ;AAAA,MAAG;AAAA,IACtC,KAAK,SAAS;AAAA,IACd,QAAQ,IAAI;AAAA,IAGZ,WAAW,MAAM,KAAK,aAAa;AAAA,MACjC,GAAG,QAAQ;AAAA,IACb;AAAA;AAAA,EAGF,IAAI,GAAM;AAAA,IACR,OAAO,KAAK;AAAA;AAAA,EAGd,SAAS,CAAC,IAAoC;AAAA,IAC5C,KAAK,YAAY,IAAI,EAAE;AAAA,IACvB,OAAO,MAAM;AAAA,MACX,KAAK,YAAY,OAAO,EAAE;AAAA;AAAA;AAAA,EAO9B,QAAQ,GAAW;AAAA,IACjB,OAAO,OAAO,KAAK,KAAK;AAAA;AAAA,EAM1B,OAAO,GAAM;AAAA,IACX,OAAO,KAAK;AAAA;AAEhB;AAiBO,SAAS,MAAS,CAAC,SAAuB;AAAA,EAC/C,OAAO,IAAI,WAAW,OAAO;AAAA;AAMxB,SAAS,QAAQ,CAAC,OAA0C;AAAA,EACjE,OACE,SAAS,QAAQ,OAAO,UAAU,YAAY,gBAAiB;AAAA;;;AC/EnE,IAAM,iBAAiB,OAAO,iBAAiB;AAAA;AAI/C,MAAM,aAA4C;AAAA,GAC/C,kBAAkB;AAAA,EAEnB,cAAc,IAAI;AAAA,EAElB;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EAEA,WAAW,CAAC,QAAiB;AAAA,IAC3B,MAAM,OAAO;AAAA,IAIb,KAAK,UAAU,IAAI,eAAe,MAAM;AAAA,MACtC,KAAK,SAAS,OAAO;AAAA,KACtB;AAAA,IAID,KAAK,QAAQ,SAAS,QAAS,GAAG;AAAA,MAChC,IAAI,CAAC,KAAK,QAAQ;AAAA,QAChB,KAAK,SAAS;AAAA,QACd,QAAQ,IAAI;AAAA,MACd;AAAA;AAAA,IAIF,KAAK,QAAQ,IAAI;AAAA,IACjB,KAAK,SAAS;AAAA;AAAA,MAGZ,KAAK,GAAM;AAAA,IACb,MAAM,IAAI;AAAA,IAEV,IAAI,KAAK,QAAQ;AAAA,MACf,KAAK,QAAQ,IAAI;AAAA,MACjB,KAAK,SAAS;AAAA,IAChB;AAAA,IAEA,OAAO,KAAK;AAAA;AAAA,EAGd,IAAI,GAAM;AAAA,IACR,IAAI,KAAK,QAAQ;AAAA,MACf,KAAK,QAAQ,IAAI;AAAA,MACjB,KAAK,SAAS;AAAA,IAChB;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,EAMd,QAAQ,GAAW;AAAA,IACjB,OAAO,OAAO,KAAK,KAAK;AAAA;AAAA,EAM1B,OAAO,GAAM;AAAA,IACX,OAAO,KAAK;AAAA;AAEhB;AAmBO,SAAS,QAAW,CAAC,QAA8B;AAAA,EACxD,OAAO,IAAI,aAAa,MAAM;AAAA;AAMzB,SAAS,UAAU,CAAC,OAA4C;AAAA,EACrE,OACE,SAAS,QACT,OAAO,UAAU,YACjB,kBAAmB;AAAA;;;AC/GhB,IAAM,eAAe;AAGrB,IAAM,iBAAiB;AAGvB,IAAM,mBAAmB;AAGzB,IAAM,oBAAoB;AAG1B,IAAM,aAAa;AAKnB,SAAS,MAAM,CAAC,OAAuB;AAAA,EAC5C,OAAO,GAAG,iBAAiB;AAAA;AAItB,SAAS,cAAc,CAAC,OAAuB;AAAA,EACpD,OAAO,OAAO,mBAAmB;AAAA;AAI5B,SAAS,kBAAkB,GAAW;AAAA,EAC3C,OAAO,OAAO;AAAA;AAcT,SAAS,mBAAmB,CAAC,MAAuB;AAAA,EACzD,MAAM,OAAO,KAAK;AAAA,EAClB,IAAI,KAAK,WAAW,gBAAgB,GAAG;AAAA,IACrC,MAAM,MAAM,SAAS,KAAK,MAAM,iBAAiB,MAAM,GAAG,EAAE;AAAA,IAC5D,OAAO,OAAO,MAAM,GAAG,IAAI,KAAK;AAAA,EAClC;AAAA,EACA,OAAO;AAAA;AAMF,SAAS,iBAAiB,CAAC,MAAwB;AAAA,EACxD,OAAO,KAAK,SAAS;AAAA;;;ACzChB,IAAM,SAAiB;AAAA,EAC5B,aAAa,CAAC,KAAsB;AAAA,IAClC,OAAO,SAAS,cAAc,GAAG;AAAA;AAAA,EAGnC,cAAc,CAAC,MAAoB;AAAA,IACjC,OAAO,SAAS,eAAe,IAAI;AAAA;AAAA,EAGrC,aAAa,CAAC,MAAuB;AAAA,IACnC,OAAO,SAAS,cAAc,IAAI;AAAA;AAAA,EAGpC,YAAY,CAAC,IAAa,KAAa,OAAqB;AAAA,IAC1D,GAAG,aAAa,KAAK,KAAK;AAAA;AAAA,EAG5B,eAAe,CAAC,IAAa,KAAmB;AAAA,IAC9C,GAAG,gBAAgB,GAAG;AAAA;AAAA,EAGxB,WAAW,CAAC,IAAa,KAAa,OAAsB;AAAA,IACzD,GAAW,OAAO;AAAA;AAAA,EAGrB,YAAY,CAAC,QAAc,OAAa,QAA2B;AAAA,IACjE,OAAO,aAAa,OAAO,MAAM;AAAA;AAAA,EAGnC,WAAW,CAAC,QAAc,OAAmB;AAAA,IAC3C,OAAO,YAAY,KAAK;AAAA;AAAA,EAG1B,MAAM,CAAC,MAAkB;AAAA,IACvB,KAAK,YAAY,YAAY,IAAI;AAAA;AAAA,EAGnC,cAAc,CAAC,MAAY,MAAoB;AAAA,IAC7C,KAAK,OAAO;AAAA;AAAA,EAGd,gBAAgB,CAAC,IAAa,OAAe,SAA8B;AAAA,IACzE,GAAG,iBAAiB,OAAO,OAAO;AAAA;AAAA,EAGpC,mBAAmB,CAAC,IAAa,OAAe,SAA8B;AAAA,IAC5E,GAAG,oBAAoB,OAAO,OAAO;AAAA;AAAA,EAGvC,UAAU,CAAC,MAAyB;AAAA,IAClC,OAAO,KAAK;AAAA;AAAA,EAGd,WAAW,CAAC,MAAyB;AAAA,IACnC,OAAO,KAAK;AAAA;AAEhB;;;ACpEO,SAAS,WAAW,CAAC,KAAsB;AAAA,EAChD,OAAO,IAAI,SAAS,KAAK,IAAI,OAAO,OAAO,IAAI,OAAO,OAAO,IAAI,MAAO,OAAO,IAAI,MAAO;AAAA;AAOrF,SAAS,WAAW,CAAC,KAAqB;AAAA,EAC/C,OAAO,IAAI,MAAM,CAAC,EAAE,YAAY;AAAA;AAO3B,SAAS,SAAS,CACvB,IACA,WACA,SACW;AAAA,EACX,OAAO,iBAAiB,IAAI,WAAW,OAAO;AAAA,EAC9C,OAAO,MAAM;AAAA,IACX,OAAO,oBAAoB,IAAI,WAAW,OAAO;AAAA;AAAA;AAQ9C,SAAS,UAAU,CACxB,IACA,OACa;AAAA,EACb,MAAM,WAAwB,CAAC;AAAA,EAE/B,WAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AAAA,IACpC,IAAI,YAAY,GAAG,GAAG;AAAA,MACpB,MAAM,UAAU,MAAM;AAAA,MACtB,IAAI,OAAO,YAAY,YAAY;AAAA,QACjC,MAAM,YAAY,YAAY,GAAG;AAAA,QACjC,SAAS,KAAK,UAAU,IAAI,WAAW,OAAwB,CAAC;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;;;AC/CT,IAAI,aAAa;AAoDV,SAAS,uBAAuB,CACrC,WACA,OACA,QACmB;AAAA,EACnB,OAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,UAAU,CAAC;AAAA,IACX,SAAS,CAAC;AAAA,IACV,eAAe,CAAC;AAAA,IAChB,iBAAiB,CAAC;AAAA,IAClB,eAAe,CAAC;AAAA,IAChB,aAAa,CAAC;AAAA,IAEd,UAAU,SAAS,OAAO,OAAO,OAAO,QAAQ,IAAI,OAAO,OAAO,IAAI;AAAA,IACtE,WAAW;AAAA,IACX,aAAa;AAAA,EACf;AAAA;AAKF,IAAI,kBAA4C;AAMzC,SAAS,kBAAkB,GAA6B;AAAA,EAC7D,OAAO;AAAA;AAOF,SAAS,kBAAkB,CAChC,UAC0B;AAAA,EAC1B,MAAM,OAAO;AAAA,EACb,kBAAkB;AAAA,EAClB,OAAO;AAAA;AAqBF,SAAS,gBAAgB,CAAC,UAAmC;AAAA,EAElE,WAAW,SAAS,SAAS,UAAU;AAAA,IACrC,iBAAiB,KAAK;AAAA,EACxB;AAAA,EAEA,IAAI,CAAC,SAAS,WAAW;AAAA,IACvB,SAAS,YAAY;AAAA,IACrB,WAAW,QAAQ,SAAS,eAAe;AAAA,MACzC,KAAK;AAAA,IACP;AAAA,EACF;AAAA;AAOK,SAAS,kBAAkB,CAAC,UAAmC;AAAA,EAEpE,WAAW,SAAS,SAAS,UAAU;AAAA,IACrC,mBAAmB,KAAK;AAAA,EAC1B;AAAA,EAEA,IAAI,SAAS,aAAa,CAAC,SAAS,aAAa;AAAA,IAC/C,SAAS,cAAc;AAAA,IACvB,SAAS,YAAY;AAAA,IAGrB,WAAW,QAAQ,SAAS,iBAAiB;AAAA,MAC3C,KAAK;AAAA,IACP;AAAA,IAGA,WAAW,WAAW,SAAS,SAAS;AAAA,MACtC,QAAQ;AAAA,IACV;AAAA,IACA,SAAS,QAAQ,SAAS;AAAA,EAC5B;AAAA;AAeK,SAAS,oBAAoB,CAClC,UACA,KACM;AAAA,EACN,IAAI,UAAoC;AAAA,EACxC,OAAO,SAAS;AAAA,IACd,IAAI,QAAQ,YAAY,SAAS,GAAG;AAAA,MAClC,WAAW,QAAQ,QAAQ,aAAa;AAAA,QACtC,KAAK,GAAG;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,QAAQ;AAAA,EACpB;AAAA,EAEA,QAAQ,MAAM,uCAAuC,GAAG;AAAA;;;ACpK1D,SAAS,sBAAsB,GAAqB;AAAA,EAClD,OAAO,EAAE,gBAAgB,GAAG,WAAW,GAAG,YAAY,EAAE;AAAA;AAQ1D,eAAsB,wBAAwB,CAC5C,WACA,OACiB;AAAA,EACjB,MAAM,MAAM,uBAAuB;AAAA,EACnC,MAAM,cAAc,SAAS,CAAC;AAAA,EAG9B,MAAM,WAAW,wBAAwB,WAAW,aAAa,IAAI;AAAA,EACrE,mBAAmB,QAAQ;AAAA,EAG3B,MAAM,SAAS,MAAM,UAAU,WAAW;AAAA,EAE1C,mBAAmB,IAAI;AAAA,EAEvB,IAAI,UAAU,OAAO,WAAW,YAAY,SAAS,QAAQ;AAAA,IAC3D,OAAO,eAAe,QAAQ,KAAK,IAA0B;AAAA,EAC/D;AAAA,EAEA,OAAO,YAAY,QAAsB,GAAG;AAAA;AAM9C,eAAsB,4BAA4B,CAChD,MACiB;AAAA,EACjB,MAAM,MAAM,uBAAuB;AAAA,EACnC,OAAO,YAAY,MAAM,GAAG;AAAA;AAK9B,IAAM,iBAAgB,IAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKD,SAAS,WAAW,CAAC,MAAkB,KAA+B;AAAA,EACpE,IAAI,QAAQ,QAAQ,OAAO,SAAS;AAAA,IAAW,OAAO;AAAA,EAEtD,IAAI,OAAO,SAAS;AAAA,IAAU,OAAO,WAAW,IAAI;AAAA,EACpD,IAAI,OAAO,SAAS;AAAA,IAAU,OAAO,OAAO,IAAI;AAAA,EAEhD,IAAI,gBAAgB;AAAA,IAAmB,OAAO,KAAK;AAAA,EAGnD,IAAI,SAAS,IAAI,KAAK,WAAW,IAAI,GAAG;AAAA,IACtC,MAAM,QAAS,KAAa;AAAA,IAC5B,MAAM,MAAM,IAAI;AAAA,IAChB,OAAO,GAAG,eAAe,GAAG,IAAI,WAAW,OAAO,KAAK,CAAC,IAAI,mBAAmB;AAAA,EACjF;AAAA,EAEA,IAAI,MAAM,QAAQ,IAAI,GAAG;AAAA,IACvB,OAAO,KAAK,IAAI,CAAC,UAAU,YAAY,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE;AAAA,EAC7D;AAAA,EAEA,IAAI,gBAAgB,SAAS;AAAA,IAE3B,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAAA,IAC7C,OAAO,eAAe,MAAM,KAAK,KAAK;AAAA,EACxC;AAAA,EAEA,OAAO,WAAW,OAAO,IAAI,CAAC;AAAA;AAMhC,SAAS,cAAc,CACrB,SACA,KACA,iBACQ;AAAA,EACR,QAAQ,KAAK,OAAO,aAAa;AAAA,EAGjC,IAAI,QAAQ,IAAI;AAAA,IACd,OAAO,SAAS,IAAI,CAAC,UAAU,YAAY,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE;AAAA,EACjE;AAAA,EAGA,IAAI,OAAO,QAAQ,YAAY;AAAA,IAC7B,OAAO,iBAAiB,KAAK,OAAO,GAAG;AAAA,EACzC;AAAA,EAGA,IAAI,OAAO,QAAQ,UAAU;AAAA,IAC3B,OAAO,iBAAiB,KAAK,OAAO,UAAU,KAAK,eAAe;AAAA,EACpE;AAAA,EAEA,OAAO,SAAS,IAAI,CAAC,UAAU,YAAY,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE;AAAA;AAMjE,SAAS,gBAAgB,CACvB,WACA,OACA,KACQ;AAAA,EAER,MAAM,iBAAkB,WAAmB;AAAA,EAC3C,MAAM,WAAW,wBAAwB,WAAkB,OAAO,IAAI;AAAA,EACtE,MAAM,OAAO,mBAAmB,QAAQ;AAAA,EAExC,MAAM,SAAS,UAAU,KAAK;AAAA,EAE9B,mBAAmB,IAAI;AAAA,EAEvB,IAAI,UAAU,OAAO,WAAW,YAAY,SAAS,QAAQ;AAAA,IAC3D,OAAO,eACL,QACA,KACA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,YAAY,QAAsB,GAAG;AAAA;AAM9C,SAAS,gBAAgB,CACvB,KACA,OACA,UACA,KACA,iBACQ;AAAA,EACR,IAAI,QAAQ;AAAA,EAGZ,IAAI,iBAAiB;AAAA,IACnB,SAAS,IAAI,iBAAiB,OAAO,IAAI,gBAAgB;AAAA,EAC3D;AAAA,EAGA,MAAM,aAAuB,CAAC;AAAA,EAE9B,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IAChD,IAAI,QAAQ,cAAc,QAAQ;AAAA,MAA2B;AAAA,IAE7D,IAAI,YAAY,GAAG,GAAG;AAAA,MAEpB,MAAM,YAAY,YAAY,GAAG;AAAA,MACjC,WAAW,KAAK,GAAG,aAAa,IAAI,cAAc;AAAA,MAClD;AAAA,IACF;AAAA,IAEA,IAAI,SAAS,QAAQ,UAAU;AAAA,MAAO;AAAA,IAGtC,IAAI,gBAAgB;AAAA,IACpB,IAAI,SAAS,KAAK,KAAK,WAAW,KAAK,GAAG;AAAA,MACxC,gBAAiB,MAAc;AAAA,IACjC;AAAA,IAEA,IAAI,kBAAkB,MAAM;AAAA,MAC1B,MAAM,YACJ,QAAQ,cAAc,UAAU,QAAQ,YAAY,QAAQ;AAAA,MAC9D,SAAS,IAAI;AAAA,MACb;AAAA,IACF;AAAA,IAEA,MAAM,WACJ,QAAQ,cAAc,UAAU,QAAQ,YAAY,QAAQ;AAAA,IAC9D,SAAS,IAAI,aAAa,WAAW,OAAO,aAAa,CAAC;AAAA,EAC5D;AAAA,EAGA,IAAI,WAAW,SAAS,GAAG;AAAA,IACzB,SAAS,IAAI,eAAe,WAAW,KAAK,GAAG;AAAA,EACjD;AAAA,EAGA,IAAI,eAAc,IAAI,GAAG,GAAG;AAAA,IAC1B,OAAO,IAAI,MAAM;AAAA,EACnB;AAAA,EAGA,MAAM,YAAY,MAAM;AAAA,EAGxB,IAAI,aAAa,OAAO,UAAU,WAAW,UAAU;AAAA,IACrD,OAAO,IAAI,MAAM,SAAS,UAAU,WAAW;AAAA,EACjD;AAAA,EAGA,MAAM,eAAe,SAClB,IAAI,CAAC,UAAU,YAAY,OAAO,GAAG,CAAC,EACtC,KAAK,EAAE;AAAA,EAEV,OAAO,IAAI,MAAM,SAAS,iBAAiB;AAAA;",
20
+ "debugId": "76A0C66C8E5A5C3C64756E2164756E21",
21
+ "names": []
22
+ }
@@ -0,0 +1,3 @@
1
+ var{defineProperty:b,getOwnPropertyNames:Lq,getOwnPropertyDescriptor:Pq}=Object,Dq=Object.prototype.hasOwnProperty;function Vq(q){return this[q]}var s=(q)=>{var J=(p??=new WeakMap).get(q),K;if(J)return J;if(J=b({},"__esModule",{value:!0}),q&&typeof q==="object"||typeof q==="function"){for(var Q of Lq(q))if(!Dq.call(J,Q))b(J,Q,{get:Vq.bind(q,Q),enumerable:!(K=Pq(q,Q))||K.enumerable})}return p.set(q,J),J},p;var Aq=(q)=>q;function Mq(q,J){this[q]=Aq.bind(null,J)}var c=(q,J)=>{for(var K in J)b(q,K,{get:J[K],enumerable:!0,configurable:!0,set:Mq.bind(J,K)})};var Rq={};c(Rq,{raw:()=>R,jsxs:()=>_q,jsxDEV:()=>bq,jsx:()=>Tq,HtmlEscapedString:()=>Z,Fragment:()=>d});module.exports=s(Rq);var d=Symbol("Fragment");class Z extends String{value;constructor(q){super(q);this.value=q}toString(){return this.value}}var R=(q)=>new Z(q);function O(q){if(q==null||typeof q==="boolean")return[];if(Array.isArray(q))return q.flat(1/0);return[q]}function I(q,J,K){if(q===d)return{tag:"",props:{},children:K};if(typeof q==="function"){if(q._SinwanComponent||q._SinwanPage){let W=q(J);if(W&&typeof W==="object"&&"tag"in W)return W;return{tag:"",props:{},children:O(W)}}let Q=q(J);if(Q&&typeof Q==="object"&&"tag"in Q)return Q;return{tag:"",props:{},children:O(Q)}}if(typeof q==="string")return{tag:q,props:J||{},children:K};return{tag:"",props:{},children:K}}function Tq(q,J,K){return I(q,J,O(J?.children))}function _q(q,J,K){let Q=J?.children;return I(q,J,Array.isArray(Q)?Q.flat(1/0):O(Q))}function bq(q,J,K,Q,W,X){let Y=Q?Array.isArray(J?.children)?J.children.flat(1/0):O(J?.children):O(J?.children),j=I(q,J,Y);if(W)j.__source=W;return j}var cq={};c(cq,{streamPage:()=>qq,renderToString:()=>U,renderToHydratableString:()=>Oq,renderPage:()=>t,renderNodeToHydratableString:()=>wq,registerPage:()=>o,isSlots:()=>n,hasPage:()=>r,getPage:()=>C});module.exports=s(cq);var N=globalThis.Bun,l=typeof N?.escapeHTML==="function"?N.escapeHTML.bind(N):void 0,S=/[&<>"']/g,Iq={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function Nq(q){if(S.lastIndex=0,!S.test(q))return q;return q.replace(S,(J)=>Iq[J])}function G(q){if(q==null||typeof q==="boolean")return"";if(typeof q==="number")return String(q);if(q instanceof Z)return q.value;let J=String(q);return l?l(J):Nq(J)}function oq(q){return R(q)}function rq(q){return q instanceof Z}var H=new Map;function o(q,J){H.set(q,J)}function C(q){return H.get(q)}function r(q){return H.has(q)}async function t(q,J){let K=C(q);if(!K)throw Error(`Page "${q}" not found in registry`);let Q=await K(J);return U(Q)}async function U(q){if(q==null||typeof q==="boolean")return"";if(typeof q==="string")return G(q);if(typeof q==="number")return String(q);if(q instanceof Z)return q.value;if(Array.isArray(q))return(await Promise.all(q.map((K)=>U(K)))).join("");if(q instanceof Promise)return a(await q);return a(q)}async function a(q){let{tag:J,props:K,children:Q}=q;if(typeof J==="function"){let W=await J(K);return U(W)}if(typeof J==="string")return Hq(J,K,Q);return U(Q)}var Sq=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);async function Hq(q,J,K){let Q=Cq(J);if(Sq.has(q))return Q?`<${q}${Q}>`:`<${q}>`;let W=await xq(K,J);return Q?`<${q}${Q}>${W}</${q}>`:`<${q}>${W}</${q}>`}function Cq(q){let J="";for(let[K,Q]of Object.entries(q)){if(K==="children")continue;if(Q==null||Q===!1)continue;if(Q===!0){J+=` ${K}`;continue}if(K==="dangerouslySetInnerHTML")continue;let W=K==="className"?"class":K,X=W==="htmlFor"?"for":W,Y=G(String(Q));J+=` ${X}="${Y}"`}return J}async function xq(q,J){let K=J.dangerouslySetInnerHTML;if(K&&typeof K.__html==="string")return K.__html;return U(q)}function n(q){return q!=null&&typeof q==="object"&&!Array.isArray(q)&&!(q instanceof Z)}var kq=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function qq(q,J){let K=new TextEncoder;return new ReadableStream({async start(Q){try{let W=await q(J);await P(W,Q,K),Q.close()}catch(W){Q.error(W)}}})}async function P(q,J,K){if(q==null||typeof q==="boolean")return;if(typeof q==="string"){J.enqueue(K.encode(G(q)));return}if(typeof q==="number"){J.enqueue(K.encode(String(q)));return}if(q instanceof Z){J.enqueue(K.encode(q.value));return}if(Array.isArray(q)){for(let Q of q)await P(Q,J,K);return}if(q instanceof Promise){let Q=await q;await e(Q,J,K);return}await e(q,J,K)}async function e(q,J,K){let{tag:Q,props:W,children:X}=q;if(typeof Q==="function"){let Y=await Q(W);await P(Y,J,K);return}if(typeof Q==="string"){await Eq(Q,W,X,J,K);return}await P(X,J,K)}async function Eq(q,J,K,Q,W){let X=yq(J),Y=J.dangerouslySetInnerHTML;if(kq.has(q)){let T=X?`<${q}${X}>`:`<${q}>`;Q.enqueue(W.encode(T));return}let j=X?`<${q}${X}>`:`<${q}>`;if(Q.enqueue(W.encode(j)),Y&&typeof Y.__html==="string")Q.enqueue(W.encode(Y.__html));else await P(K,Q,W);Q.enqueue(W.encode(`</${q}>`))}function yq(q){let J="";for(let[K,Q]of Object.entries(q)){if(K==="children"||K==="dangerouslySetInnerHTML")continue;if(Q==null||Q===!1)continue;if(Q===!0){J+=` ${K}`;continue}let W=K==="className"?"class":K==="htmlFor"?"for":K,X=G(String(Q));J+=` ${W}="${X}"`}return J}var B=new Set,w=!1,x=!1,Jq=[];function Kq(q){if(!q.active)return;B.add(q),vq()}function Qq(q){B.delete(q)}function vq(){if(!w)w=!0,queueMicrotask(Wq)}function Wq(){x=!0;let q=[...B].sort((Q,W)=>Q.id-W.id);B.clear();for(let Q of q)if(Q.active)Q.run();let J=10;while(B.size>0&&J-- >0){let Q=[...B].sort((W,X)=>W.id-X.id);B.clear();for(let W of Q)if(W.active)W.run()}w=!1,x=!1;let K=Jq.splice(0);for(let Q of K)Q()}function KJ(q){return new Promise((J)=>{let K=()=>{q?.(),J()};if(w||x)Jq.push(K);else queueMicrotask(K)})}function QJ(){if(w)w=!1,Wq()}var L=null,k=[],gq=0;class V{id;active=!0;fn;cleanup=void 0;deps=new Set;constructor(q){this.id=gq++,this.fn=q}run(){if(!this.active)return;if(k.includes(this))return;if(this.cleanupDeps(),this.cleanup)this.cleanup(),this.cleanup=void 0;k.push(this);let q=L;L=this;try{let J=this.fn();if(typeof J==="function")this.cleanup=J}finally{L=q,k.pop()}}cleanupDeps(){for(let q of this.deps)q.subscribers.delete(this);this.deps.clear()}notify(){Kq(this)}dispose(){if(!this.active)return;if(this.active=!1,this.cleanup)this.cleanup(),this.cleanup=void 0;this.cleanupDeps(),Qq(this)}}function YJ(q){let J=new V(q);return J.run(),()=>J.dispose()}function A(q){if(L)q.subscribers.add(L),L.deps.add(q)}function M(q){let J=[...q.subscribers];for(let K of J)K.notify()}var Xq=Symbol("Sinwan:signal");class Yq{[Xq]=!0;subscribers=new Set;_value;_manualSubs=new Set;constructor(q){this._value=q}get value(){return A(this),this._value}set value(q){if(Object.is(this._value,q))return;this._value=q,M(this);for(let J of this._manualSubs)J(q)}peek(){return this._value}subscribe(q){return this._manualSubs.add(q),()=>{this._manualSubs.delete(q)}}toString(){return String(this.value)}valueOf(){return this.value}}function GJ(q){return new Yq(q)}function E(q){return q!=null&&typeof q==="object"&&Xq in q}var Zq=Symbol("Sinwan:computed");class $q{[Zq]=!0;subscribers=new Set;_value;_dirty=!0;_effect;constructor(q){let J=this;this._effect=new V(()=>{J._value=q()}),this._effect.notify=function(){if(!J._dirty)J._dirty=!0,M(J)},this._effect.run(),this._dirty=!1}get value(){if(A(this),this._dirty)this._effect.run(),this._dirty=!1;return this._value}peek(){if(this._dirty)this._effect.run(),this._dirty=!1;return this._value}toString(){return String(this.value)}valueOf(){return this.value}}function BJ(q){return new $q(q)}function y(q){return q!=null&&typeof q==="object"&&Zq in q}var Gq="data-sinwan-id";var jq="data-sinwan-ev";function Uq(q){return`c${q}`}function Bq(q){return`<!--sinwan-t:${q}-->`}function zq(){return"<!--/sinwan-t-->"}function FJ(q){let J=q.data;if(J.startsWith("sinwan-t:")){let K=parseInt(J.slice(9),10);return Number.isNaN(K)?-1:K}return-1}function OJ(q){return q.data==="/sinwan-t"}var v={createElement(q){return document.createElement(q)},createTextNode(q){return document.createTextNode(q)},createComment(q){return document.createComment(q)},setAttribute(q,J,K){q.setAttribute(J,K)},removeAttribute(q,J){q.removeAttribute(J)},setProperty(q,J,K){q[J]=K},insertBefore(q,J,K){q.insertBefore(J,K)},appendChild(q,J){q.appendChild(J)},remove(q){q.parentNode?.removeChild(q)},setTextContent(q,J){q.data=J},addEventListener(q,J,K){q.addEventListener(J,K)},removeEventListener(q,J,K){q.removeEventListener(J,K)},parentNode(q){return q.parentNode},nextSibling(q){return q.nextSibling}};function g(q){return q.length>2&&q[0]==="o"&&q[1]==="n"&&q[2]>="A"&&q[2]<="Z"}function f(q){return q.slice(2).toLowerCase()}function fq(q,J,K){return v.addEventListener(q,J,K),()=>{v.removeEventListener(q,J,K)}}function DJ(q,J){let K=[];for(let Q of Object.keys(J))if(g(Q)){let W=J[Q];if(typeof W==="function"){let X=f(Q);K.push(fq(q,X,W))}}return K}var mq=0;function h(q,J,K){return{uid:mq++,component:q,props:J,element:null,parent:K,children:[],effects:[],_mountedHooks:[],_unmountedHooks:[],_updatedHooks:[],_errorHooks:[],provides:K?Object.create(K.provides):Object.create(null),isMounted:!1,isUnmounted:!1}}var m=null;function AJ(){return m}function D(q){let J=m;return m=q,J}function hq(q){for(let J of q.children)hq(J);if(!q.isMounted){q.isMounted=!0;for(let J of q._mountedHooks)J()}}function uq(q){for(let J of q.children)uq(J);if(q.isMounted&&!q.isUnmounted){q.isUnmounted=!0,q.isMounted=!1;for(let J of q._unmountedHooks)J();for(let J of q.effects)J();q.effects.length=0}}function MJ(q,J){let K=q;while(K){if(K._errorHooks.length>0){for(let Q of K._errorHooks)Q(J);return}K=K.parent}console.error("[Sinwan] Unhandled component error:",J)}function Fq(){return{componentIndex:0,textIndex:0,eventIndex:0}}async function Oq(q,J){let K=Fq(),Q=J??{},W=h(q,Q,null);D(W);let X=await q(Q);if(D(null),X&&typeof X==="object"&&"tag"in X)return u(X,K,!0);return z(X,K)}async function wq(q){let J=Fq();return z(q,J)}var iq=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function z(q,J){if(q==null||typeof q==="boolean")return"";if(typeof q==="string")return G(q);if(typeof q==="number")return String(q);if(q instanceof Z)return q.value;if(E(q)||y(q)){let K=q.value,Q=J.textIndex++;return`${Bq(Q)}${G(String(K))}${zq()}`}if(Array.isArray(q))return q.map((K)=>z(K,J)).join("");if(q instanceof Promise)return"";if(typeof q==="object"&&"tag"in q)return u(q,J,!1);return G(String(q))}function u(q,J,K){let{tag:Q,props:W,children:X}=q;if(Q==="")return X.map((Y)=>z(Y,J)).join("");if(typeof Q==="function")return pq(Q,W,J);if(typeof Q==="string")return sq(Q,W,X,J,K);return X.map((Y)=>z(Y,J)).join("")}function pq(q,J,K){let Q=globalThis.__SinwanCurrentInstance,W=h(q,J,null),X=D(W),Y=q(J);if(D(X),Y&&typeof Y==="object"&&"tag"in Y)return u(Y,K,!0);return z(Y,K)}function sq(q,J,K,Q,W){let X="";if(W)X+=` ${Gq}="${Uq(Q.componentIndex++)}"`;let Y=[];for(let[$,F]of Object.entries(J)){if($==="children"||$==="dangerouslySetInnerHTML")continue;if(g($)){let i=f($);Y.push(`${i}:${Q.eventIndex++}`);continue}if(F==null||F===!1)continue;let _=F;if(E(F)||y(F))_=F.value;if(_===!0){X+=` ${$==="className"?"class":$==="htmlFor"?"for":$}`;continue}X+=` ${$==="className"?"class":$==="htmlFor"?"for":$}="${G(String(_))}"`}if(Y.length>0)X+=` ${jq}="${Y.join(",")}"`;if(iq.has(q))return`<${q}${X}>`;let j=J.dangerouslySetInnerHTML;if(j&&typeof j.__html==="string")return`<${q}${X}>${j.__html}</${q}>`;let T=K.map(($)=>z($,Q)).join("");return`<${q}${X}>${T}</${q}>`}
2
+
3
+ //# debugId=C8441168D05E406D64756E2164756E21
@@ -0,0 +1,22 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/jsx/jsx-runtime.ts", "../../src/escaper.ts", "../../src/server/renderer.ts", "../../src/server/stream.ts", "../../src/reactivity/scheduler.ts", "../../src/reactivity/effect.ts", "../../src/reactivity/signal.ts", "../../src/reactivity/computed.ts", "../../src/hydration/markers.ts", "../../src/renderer/dom-ops.ts", "../../src/renderer/events.ts", "../../src/component/instance.ts", "../../src/server/hydration-markers.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * SinwanJS View Module — JSX Runtime\n *\n * JSX factory that returns SinwanElement structures for the view renderer.\n * Imported automatically when using JSX syntax.\n */\n\nimport type { SinwanElement, SinwanNode } from \"../types.ts\";\nimport type { SinwanIntrinsicElements } from \"./jsx-types\";\n\nexport const Fragment = Symbol(\"Fragment\");\n\n/**\n * A string that has been marked as safe HTML (already escaped).\n * Used for raw HTML injection with explicit trust marking.\n */\nexport class HtmlEscapedString extends String {\n constructor(public readonly value: string) {\n super(value);\n }\n override toString() {\n return this.value;\n }\n}\n\nexport const raw = (str: string) => new HtmlEscapedString(str);\n\n// Fast path for intrinsic elements\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Normalize children into an array of SinwanNode.\n */\nfunction normalizeChildren(children: any): SinwanNode[] {\n if (children == null || typeof children === \"boolean\") return [];\n if (Array.isArray(children)) return children.flat(Infinity);\n return [children];\n}\n\n/**\n * Build an SinwanElement from a component/tag invocation.\n * Shared logic for jsx, jsxs, and jsxDEV.\n */\nfunction buildElement(\n type: any,\n props: any,\n children: SinwanNode[],\n): SinwanElement {\n // Handle Fragment\n if (type === Fragment) {\n return { tag: \"\", props: {}, children };\n }\n\n // Handle functional components\n if (typeof type === \"function\") {\n // Sinwan-tagged component — call it directly\n if (type._SinwanComponent || type._SinwanPage) {\n const result = type(props);\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return result as SinwanElement;\n }\n return { tag: \"\", props: {}, children: normalizeChildren(result) };\n }\n\n // Regular function component\n const result = type(props);\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return result as SinwanElement;\n }\n return { tag: \"\", props: {}, children: normalizeChildren(result) };\n }\n\n // Handle intrinsic HTML elements\n if (typeof type === \"string\") {\n return { tag: type, props: props || {}, children };\n }\n\n // Fallback\n return { tag: \"\", props: {}, children };\n}\n\n/**\n * JSX factory — called for elements with 0 or 1 child.\n * TypeScript auto-imports this in production mode (`react-jsx`).\n */\nexport function jsx(type: any, props: any, key?: any): SinwanElement {\n return buildElement(type, props, normalizeChildren(props?.children));\n}\n\n/**\n * JSX static factory — called for elements with 2+ children.\n * `props.children` is **already an array**, so we skip normalizeChildren.\n */\nexport function jsxs(type: any, props: any, key?: any): SinwanElement {\n const children = props?.children;\n // Children is guaranteed to be an array by the compiler\n return buildElement(\n type,\n props,\n Array.isArray(children)\n ? children.flat(Infinity)\n : normalizeChildren(children),\n );\n}\n\n/**\n * Source location metadata attached by the compiler in dev mode.\n */\nexport interface JSXSource {\n fileName: string;\n lineNumber: number;\n columnNumber: number;\n}\n\n/**\n * JSX dev factory — called in dev mode (`react-jsxdev`).\n * Receives extra source/debug info for better error messages.\n */\nexport function jsxDEV(\n type: any,\n props: any,\n key: any,\n isStaticChildren: boolean,\n source?: JSXSource,\n self?: unknown,\n): SinwanElement {\n const children = isStaticChildren\n ? Array.isArray(props?.children)\n ? props.children.flat(Infinity)\n : normalizeChildren(props?.children)\n : normalizeChildren(props?.children);\n\n const element = buildElement(type, props, children);\n\n // Attach debug metadata (useful for dev-tools / error traces)\n if (source) {\n (element as any).__source = source;\n }\n\n return element;\n}\n\nexport namespace JSX {\n export type Element = SinwanElement | Promise<SinwanElement>;\n export interface IntrinsicAttributes {\n key?: string | number;\n }\n export interface ElementChildrenAttribute {\n children: {};\n }\n export interface IntrinsicElements extends SinwanIntrinsicElements {}\n}\n",
6
+ "/**\n * Sinwan — HTML Escaping\n *\n * Security utilities for sanitizing interpolated values.\n * Runtime-agnostic: prefers `Bun.escapeHTML` when running on Bun (native\n * speed), and falls back to a portable implementation everywhere else\n * (Node, Deno, Cloudflare Workers, browsers).\n */\n\nimport { HtmlEscapedString, raw } from \"./jsx/jsx-runtime\";\n\nexport { HtmlEscapedString, raw };\n\n// ─── Native fast-path detection ─────────────────────────────\n// `Bun` is only defined inside the Bun runtime. We probe it via globalThis\n// so module evaluation never throws on other runtimes.\nconst _bun = (globalThis as any).Bun as\n | { escapeHTML?: (s: string) => string }\n | undefined;\n\nconst _nativeEscape: ((s: string) => string) | undefined =\n typeof _bun?.escapeHTML === \"function\"\n ? _bun.escapeHTML.bind(_bun)\n : undefined;\n\n// ─── Portable fallback ──────────────────────────────────────\n// Covers the five characters that matter inside HTML text and attributes.\nconst HTML_ESCAPE_RE = /[&<>\"']/g;\nconst HTML_ESCAPE_MAP: Record<string, string> = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#39;\",\n};\n\nfunction portableEscape(str: string): string {\n // Avoid a regex pass when nothing to escape (very common case).\n HTML_ESCAPE_RE.lastIndex = 0;\n if (!HTML_ESCAPE_RE.test(str)) return str;\n return str.replace(HTML_ESCAPE_RE, (c) => HTML_ESCAPE_MAP[c]!);\n}\n\n/**\n * Escape HTML entities in any value.\n * Returns \"\" for null/undefined/boolean and pass-through for numbers.\n * Pre-escaped strings (`HtmlEscapedString`) are returned untouched.\n */\nexport function escapeHtml(value: unknown): string {\n if (value == null || typeof value === \"boolean\") return \"\";\n if (typeof value === \"number\") return String(value);\n if (value instanceof HtmlEscapedString) return value.value;\n const s = String(value);\n return _nativeEscape ? _nativeEscape(s) : portableEscape(s);\n}\n\n/**\n * Mark a string as safe HTML (pre-escaped).\n * USE WITH CAUTION - only for trusted content!\n */\nexport function safeHtml(html: string): HtmlEscapedString {\n return raw(html);\n}\n\n/**\n * Check if a value is already escaped HTML.\n */\nexport function isSafeHtml(value: unknown): value is HtmlEscapedString {\n return value instanceof HtmlEscapedString;\n}\n",
7
+ "/**\n * SinwanJS View Module — Renderer & Component Registry\n *\n * Renders Sinwan component trees to HTML strings.\n * Supports async components, caching, and streaming.\n */\n\nimport type {\n SinwanNode,\n SinwanElement,\n SinwanComponent,\n SinwanPage,\n SinwanSlots,\n} from \"../types.ts\";\nimport { HtmlEscapedString, escapeHtml } from \"../escaper.ts\";\n\n// Component cache - maps component identity to render function\nconst componentCache = new WeakMap<SinwanComponent<any>, boolean>();\n\n// Page registry\nconst pageRegistry = new Map<string, SinwanPage<any>>();\n\n/**\n * Register a page renderer by name.\n */\nexport function registerPage<D extends object = {}>(\n name: string,\n page: SinwanPage<D>,\n): void {\n pageRegistry.set(name, page);\n}\n\n/**\n * Get a registered page by name.\n */\nexport function getPage<D extends object = {}>(\n name: string,\n): SinwanPage<D> | undefined {\n return pageRegistry.get(name);\n}\n\n/**\n * Check if a page is registered.\n */\nexport function hasPage(name: string): boolean {\n return pageRegistry.has(name);\n}\n\n/**\n * Render a registered page to an HTML string.\n */\nexport async function renderPage<D extends object = {}>(\n name: string,\n data: D,\n): Promise<string> {\n const page = getPage<D>(name);\n if (!page) {\n throw new Error(`Page \"${name}\" not found in registry`);\n }\n\n const element = await page(data);\n return renderToString(element);\n}\n\n/**\n * Render a node tree to an HTML string.\n * Handles primitives, elements, components, and arrays.\n */\nexport async function renderToString(node: SinwanNode): Promise<string> {\n // Handle null/undefined/boolean\n if (node == null || typeof node === \"boolean\") {\n return \"\";\n }\n\n // Handle strings (escape them)\n if (typeof node === \"string\") {\n return escapeHtml(node);\n }\n\n // Handle numbers\n if (typeof node === \"number\") {\n return String(node);\n }\n\n // Handle pre-escaped HTML\n if (node instanceof HtmlEscapedString) {\n return node.value;\n }\n\n // Handle arrays - render each child and concatenate\n if (Array.isArray(node)) {\n const results = await Promise.all(\n node.map((child) => renderToString(child)),\n );\n return results.join(\"\");\n }\n\n // Handle promises (async components)\n if (node instanceof Promise) {\n return renderElement(await node);\n }\n\n // Handle elements\n return renderElement(node);\n}\n\n/**\n * Render an element to HTML string.\n */\nasync function renderElement(element: SinwanElement): Promise<string> {\n const { tag, props, children } = element;\n\n // Handle functional components\n if (typeof tag === \"function\") {\n const result = await tag(props);\n return renderToString(result);\n }\n\n // Handle intrinsic HTML elements\n if (typeof tag === \"string\") {\n return renderIntrinsicElement(tag, props, children);\n }\n\n // Fallback - shouldn't happen with valid JSX\n return renderToString(children);\n}\n\n// Void elements that don't have closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Render an intrinsic HTML element.\n */\nasync function renderIntrinsicElement(\n tag: string,\n props: Record<string, unknown>,\n children: SinwanNode[],\n): Promise<string> {\n const attrs = renderAttributes(props);\n\n // Void elements have no children and no closing tag\n if (VOID_ELEMENTS.has(tag)) {\n return attrs ? `<${tag}${attrs}>` : `<${tag}>`;\n }\n\n // Render children (handles dangerouslySetInnerHTML)\n const childrenHtml = await renderChildren(children, props);\n\n // Build element\n return attrs\n ? `<${tag}${attrs}>${childrenHtml}</${tag}>`\n : `<${tag}>${childrenHtml}</${tag}>`;\n}\n\n/**\n * Render HTML attributes from props.\n */\nfunction renderAttributes(props: Record<string, unknown>): string {\n let attrs = \"\";\n\n for (const [key, value] of Object.entries(props)) {\n // Skip children and special props\n if (key === \"children\") continue;\n\n // Skip null/undefined/false values\n if (value == null || value === false) continue;\n\n // Handle boolean true (just the attribute name)\n if (value === true) {\n attrs += ` ${key}`;\n continue;\n }\n\n // Handle dangerous HTML (trusted only)\n if (key === \"dangerouslySetInnerHTML\") {\n // This is handled during children rendering, not as an attribute\n continue;\n }\n\n // Handle className -> class\n const attrName = key === \"className\" ? \"class\" : key;\n\n // Handle htmlFor -> for\n const finalName = attrName === \"htmlFor\" ? \"for\" : attrName;\n\n // Escape the attribute value\n const attrValue = escapeHtml(String(value));\n attrs += ` ${finalName}=\"${attrValue}\"`;\n }\n\n return attrs;\n}\n\n/**\n * Render children, with special handling for dangerouslySetInnerHTML.\n */\nasync function renderChildren(\n children: SinwanNode[],\n props: Record<string, unknown>,\n): Promise<string> {\n // Check for dangerous inner HTML\n const dangerous = props.dangerouslySetInnerHTML as\n | { __html?: string }\n | undefined;\n if (dangerous && typeof dangerous.__html === \"string\") {\n return dangerous.__html; // Trust the HTML (user explicitly marked safe)\n }\n\n return renderToString(children);\n}\n\n// Wire up dangerouslySetInnerHTML handling by patching renderIntrinsicElement\nconst originalRenderIntrinsic = renderIntrinsicElement;\n\n/**\n * Check if children is a slots object (named slots).\n */\nexport function isSlots(children: unknown): children is SinwanSlots {\n return (\n children != null &&\n typeof children === \"object\" &&\n !Array.isArray(children) &&\n !(children instanceof HtmlEscapedString)\n );\n}\n",
8
+ "/**\n * SinwanJS View Module — Streaming SSR\n *\n * Progressive HTML streaming using Bun's native ReadableStream.\n * Streams chunks as they resolve without waiting for full tree.\n */\n\nimport type { SinwanNode, SinwanElement, SinwanPage } from \"../types.ts\";\nimport { HtmlEscapedString, escapeHtml } from \"../escaper.ts\";\n\n// Void elements that don't have closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Stream a page to a ReadableStream.\n */\nexport function streamPage<D extends object = {}>(\n page: SinwanPage<D>,\n data: D,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n // Resolve the page component\n const element = await page(data);\n\n // Stream the element tree\n await streamNode(element, controller, encoder);\n\n // Close the stream\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n\n/**\n * Stream a node tree to a controller.\n */\nasync function streamNode(\n node: SinwanNode,\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n): Promise<void> {\n // Handle null/undefined/boolean\n if (node == null || typeof node === \"boolean\") {\n return;\n }\n\n // Handle strings (escape them)\n if (typeof node === \"string\") {\n controller.enqueue(encoder.encode(escapeHtml(node)));\n return;\n }\n\n // Handle numbers\n if (typeof node === \"number\") {\n controller.enqueue(encoder.encode(String(node)));\n return;\n }\n\n // Handle pre-escaped HTML\n if (node instanceof HtmlEscapedString) {\n controller.enqueue(encoder.encode(node.value));\n return;\n }\n\n // Handle arrays - stream each child\n if (Array.isArray(node)) {\n for (const child of node) {\n await streamNode(child, controller, encoder);\n }\n return;\n }\n\n // Handle async elements (Promise<SinwanElement>)\n if (node instanceof Promise) {\n const resolved = await node;\n await streamElement(resolved, controller, encoder);\n return;\n }\n\n // Handle elements\n await streamElement(node, controller, encoder);\n}\n\n/**\n * Stream an element to the controller.\n */\nasync function streamElement(\n element: SinwanElement,\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n): Promise<void> {\n const { tag, props, children } = element;\n\n // Handle functional components\n if (typeof tag === \"function\") {\n const result = await tag(props);\n await streamNode(result, controller, encoder);\n return;\n }\n\n // Handle intrinsic HTML elements\n if (typeof tag === \"string\") {\n await streamIntrinsicElement(tag, props, children, controller, encoder);\n return;\n }\n\n // Fallback\n await streamNode(children, controller, encoder);\n}\n\n/**\n * Stream an intrinsic HTML element.\n */\nasync function streamIntrinsicElement(\n tag: string,\n props: Record<string, unknown>,\n children: SinwanNode[],\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n): Promise<void> {\n const attrs = renderAttributes(props);\n\n // Check for dangerous inner HTML\n const dangerous = props.dangerouslySetInnerHTML as\n | { __html?: string }\n | undefined;\n\n // Void elements have no children and no closing tag\n if (VOID_ELEMENTS.has(tag)) {\n const html = attrs ? `<${tag}${attrs}>` : `<${tag}>`;\n controller.enqueue(encoder.encode(html));\n return;\n }\n\n // Opening tag\n const openTag = attrs ? `<${tag}${attrs}>` : `<${tag}>`;\n controller.enqueue(encoder.encode(openTag));\n\n // Children or dangerous HTML\n if (dangerous && typeof dangerous.__html === \"string\") {\n controller.enqueue(encoder.encode(dangerous.__html));\n } else {\n await streamNode(children, controller, encoder);\n }\n\n // Closing tag\n controller.enqueue(encoder.encode(`</${tag}>`));\n}\n\n/**\n * Render HTML attributes from props.\n */\nfunction renderAttributes(props: Record<string, unknown>): string {\n let attrs = \"\";\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\" || key === \"dangerouslySetInnerHTML\") continue;\n if (value == null || value === false) continue;\n\n if (value === true) {\n attrs += ` ${key}`;\n continue;\n }\n\n const attrName =\n key === \"className\" ? \"class\" : key === \"htmlFor\" ? \"for\" : key;\n const attrValue = escapeHtml(String(value));\n attrs += ` ${attrName}=\"${attrValue}\"`;\n }\n\n return attrs;\n}\n",
9
+ "/**\n * SinwanJS Reactivity — Scheduler\n *\n * Microtask-based flush queue for batching reactive updates.\n * Effects are NOT run synchronously on signal write — they are\n * queued and flushed in a microtask (like Vue's nextTick).\n */\n\nexport interface EffectNode {\n id: number;\n run(): void;\n active: boolean;\n}\n\nconst pendingEffects = new Set<EffectNode>();\nlet flushScheduled = false;\nlet isFlushing = false;\n\n// Pending nextTick callbacks\nconst pendingCallbacks: (() => void)[] = [];\n\n/**\n * Schedule an effect for the next microtask flush.\n */\nexport function scheduleEffect(effect: EffectNode): void {\n if (!effect.active) return;\n pendingEffects.add(effect);\n scheduleFlush();\n}\n\n/**\n * Remove a scheduled effect (e.g. when disposed before flush).\n */\nexport function unscheduleEffect(effect: EffectNode): void {\n pendingEffects.delete(effect);\n}\n\n/**\n * Schedule the microtask flush if not already scheduled.\n */\nfunction scheduleFlush(): void {\n if (!flushScheduled) {\n flushScheduled = true;\n queueMicrotask(flush);\n }\n}\n\n/**\n * Flush all pending effects. Effects added during flush are\n * processed in the same pass (convergence loop with a safety limit).\n */\nfunction flush(): void {\n isFlushing = true;\n\n // Sort by id to guarantee parent-before-child execution order\n const sorted = [...pendingEffects].sort((a, b) => a.id - b.id);\n pendingEffects.clear();\n\n for (const effect of sorted) {\n if (effect.active) {\n effect.run();\n }\n }\n\n // If new effects were queued during the flush, drain them too\n // (safety limit to prevent infinite loops)\n let safety = 10;\n while (pendingEffects.size > 0 && safety-- > 0) {\n const next = [...pendingEffects].sort((a, b) => a.id - b.id);\n pendingEffects.clear();\n for (const effect of next) {\n if (effect.active) {\n effect.run();\n }\n }\n }\n\n flushScheduled = false;\n isFlushing = false;\n\n // Run nextTick callbacks after all effects\n const cbs = pendingCallbacks.splice(0);\n for (const cb of cbs) {\n cb();\n }\n}\n\n/**\n * Returns true if the scheduler is currently flushing effects.\n */\nexport function isFlushingEffects(): boolean {\n return isFlushing;\n}\n\n/**\n * Queue a callback that runs after the next reactive flush completes.\n * Similar to Vue's nextTick().\n */\nexport function nextTick(fn?: () => void): Promise<void> {\n return new Promise<void>((resolve) => {\n const callback = () => {\n fn?.();\n resolve();\n };\n if (flushScheduled || isFlushing) {\n // Effects are pending — run after they flush\n pendingCallbacks.push(callback);\n } else {\n // No pending effects — run on next microtask\n queueMicrotask(callback);\n }\n });\n}\n\n/**\n * Force synchronous flush of all pending effects.\n * Primarily for testing and batch().\n */\nexport function flushSync(): void {\n if (flushScheduled) {\n flushScheduled = false;\n flush();\n }\n}\n",
10
+ "/**\n * SinwanJS Reactivity — Effect\n *\n * Fine-grained effect system with automatic dependency tracking.\n * When an effect runs, any signal reads are tracked as dependencies.\n * When those signals change, the effect is re-scheduled.\n */\n\nimport { type EffectNode, scheduleEffect, unscheduleEffect } from \"./scheduler.ts\";\n\n// ─── Global tracking state ─────────────────────────────────\n\nlet activeEffect: ReactiveEffect | null = null;\nconst effectStack: ReactiveEffect[] = [];\nlet effectIdCounter = 0;\n\n// ─── Subscription interface ────────────────────────────────\n\n/**\n * A Dep is any object that can track subscribers.\n * Signals and computeds implement this internally.\n */\nexport interface Dep {\n subscribers: Set<ReactiveEffect>;\n}\n\n// ─── ReactiveEffect ────────────────────────────────────────\n\nexport type CleanupFn = () => void;\nexport type EffectFn = () => CleanupFn | void;\n\nexport class ReactiveEffect implements EffectNode {\n id: number;\n active = true;\n\n /** The user-supplied function */\n private fn: EffectFn;\n\n /** Cleanup returned from the last run */\n private cleanup: CleanupFn | void = undefined;\n\n /** All deps this effect is subscribed to (for bidirectional cleanup) */\n deps: Set<Dep> = new Set();\n\n constructor(fn: EffectFn) {\n this.id = effectIdCounter++;\n this.fn = fn;\n }\n\n /**\n * Execute the effect function while tracking dependencies.\n */\n run(): void {\n if (!this.active) return;\n\n // Prevent infinite re-entry\n if (effectStack.includes(this)) return;\n\n // Clean up previous dependencies\n this.cleanupDeps();\n\n // Run user cleanup from previous execution\n if (this.cleanup) {\n this.cleanup();\n this.cleanup = undefined;\n }\n\n // Push onto the tracking stack\n effectStack.push(this);\n const prevEffect = activeEffect;\n activeEffect = this;\n\n try {\n const result = this.fn();\n if (typeof result === \"function\") {\n this.cleanup = result;\n }\n } finally {\n activeEffect = prevEffect;\n effectStack.pop();\n }\n }\n\n /**\n * Unsubscribe from all current deps so stale deps don't trigger this effect.\n */\n private cleanupDeps(): void {\n for (const dep of this.deps) {\n dep.subscribers.delete(this);\n }\n this.deps.clear();\n }\n\n /**\n * Notify the scheduler that this effect should re-run.\n */\n notify(): void {\n scheduleEffect(this);\n }\n\n /**\n * Permanently dispose this effect — stop tracking & unsubscribe.\n */\n dispose(): void {\n if (!this.active) return;\n this.active = false;\n\n // Run user cleanup\n if (this.cleanup) {\n this.cleanup();\n this.cleanup = undefined;\n }\n\n this.cleanupDeps();\n unscheduleEffect(this);\n }\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Create a reactive effect.\n *\n * The effect function runs immediately to establish initial dependencies.\n * It re-runs whenever any tracked signal changes.\n * Returns a dispose function to stop the effect.\n *\n * @example\n * const count = signal(0);\n * const dispose = effect(() => {\n * console.log(\"count is\", count.value);\n * });\n * // logs \"count is 0\" immediately\n *\n * count.value = 1;\n * // logs \"count is 1\" on next microtask\n *\n * dispose(); // stops tracking\n */\nexport function effect(fn: EffectFn): CleanupFn {\n const e = new ReactiveEffect(fn);\n // Run immediately (synchronous first run for initial tracking)\n e.run();\n return () => e.dispose();\n}\n\n// ─── Tracking helpers (used by signals/computed) ───────────\n\n/**\n * Track a dependency from the currently active effect.\n * Called by signal.value getters.\n */\nexport function track(dep: Dep): void {\n if (activeEffect) {\n dep.subscribers.add(activeEffect);\n activeEffect.deps.add(dep);\n }\n}\n\n/**\n * Trigger all subscribers of a dependency.\n * Called by signal.value setters.\n */\nexport function trigger(dep: Dep): void {\n // Copy to avoid modification during iteration\n const effects = [...dep.subscribers];\n for (const effect of effects) {\n effect.notify();\n }\n}\n\n/**\n * Returns the currently active effect (for advanced usage).\n */\nexport function getActiveEffect(): ReactiveEffect | null {\n return activeEffect;\n}\n",
11
+ "/**\n * SinwanJS Reactivity — Signal\n *\n * A signal is a reactive container for a single value.\n * Reading `.value` tracks the current effect as a subscriber.\n * Writing `.value` notifies all subscribers.\n *\n * Inspired by Vue 3 ref(), Solid signals, Preact signals.\n */\n\nimport { type Dep, track, trigger } from \"./effect.ts\";\n\n// ─── Signal interface ──────────────────────────────────────\n\nexport interface Signal<T> {\n /** Get or set the reactive value. Reading tracks; writing notifies. */\n value: T;\n\n /** Read the value without tracking dependencies. */\n peek(): T;\n\n /** Manually subscribe to changes. Returns an unsubscribe function. */\n subscribe(fn: (value: T) => void): () => void;\n}\n\n// Brand for type-checking\nconst SIGNAL_BRAND = Symbol(\"Sinwan:signal\");\n\n// ─── Implementation ────────────────────────────────────────\n\nclass SignalImpl<T> implements Signal<T>, Dep {\n [SIGNAL_BRAND] = true;\n\n subscribers = new Set<import(\"./effect.ts\").ReactiveEffect>();\n private _value: T;\n private _manualSubs = new Set<(value: T) => void>();\n\n constructor(initial: T) {\n this._value = initial;\n }\n\n get value(): T {\n track(this);\n return this._value;\n }\n\n set value(newValue: T) {\n if (Object.is(this._value, newValue)) return;\n this._value = newValue;\n trigger(this);\n\n // Notify manual subscribers\n for (const fn of this._manualSubs) {\n fn(newValue);\n }\n }\n\n peek(): T {\n return this._value;\n }\n\n subscribe(fn: (value: T) => void): () => void {\n this._manualSubs.add(fn);\n return () => {\n this._manualSubs.delete(fn);\n };\n }\n\n /**\n * toString() for interpolation in templates.\n */\n toString(): string {\n return String(this.value);\n }\n\n /**\n * valueOf() for numeric operations.\n */\n valueOf(): T {\n return this.value;\n }\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Create a reactive signal.\n *\n * @example\n * const count = signal(0);\n * console.log(count.value); // 0\n *\n * effect(() => {\n * console.log(count.value); // re-runs when count changes\n * });\n *\n * count.value = 5; // triggers the effect\n */\nexport function signal<T>(initial: T): Signal<T> {\n return new SignalImpl(initial);\n}\n\n/**\n * Type guard: check if a value is a Signal.\n */\nexport function isSignal(value: unknown): value is Signal<unknown> {\n return (\n value != null && typeof value === \"object\" && SIGNAL_BRAND in (value as any)\n );\n}\n",
12
+ "/**\n * SinwanJS Reactivity — Computed\n *\n * A computed is a derived reactive value that lazily re-evaluates\n * when its dependencies change. It caches the result and only\n * recomputes when actually read after a dependency has changed.\n *\n * Design: The computed does NOT use the scheduler for its own\n * re-evaluation. When a dependency changes, it marks itself dirty\n * and triggers downstream subscribers (which ARE scheduled).\n * The actual re-evaluation happens lazily on `.value` access.\n *\n * Inspired by Vue 3 computed(), Solid createMemo().\n */\n\nimport { type Dep, track, trigger, ReactiveEffect } from \"./effect.ts\";\n\n// ─── Computed interface ────────────────────────────────────\n\nexport interface Computed<T> {\n /** Read the computed value (lazy evaluation, cached). */\n readonly value: T;\n\n /** Read without tracking. */\n peek(): T;\n}\n\n// Brand for type-checking\nconst COMPUTED_BRAND = Symbol(\"Sinwan:computed\");\n\n// ─── Implementation ────────────────────────────────────────\n\nclass ComputedImpl<T> implements Computed<T>, Dep {\n [COMPUTED_BRAND] = true;\n\n subscribers = new Set<ReactiveEffect>();\n\n _value!: T;\n _dirty = true;\n _effect: ReactiveEffect;\n\n constructor(getter: () => T) {\n const self = this;\n\n // Internal effect solely for dependency tracking.\n // The fn wraps the getter — it writes to self._value as a side effect.\n this._effect = new ReactiveEffect(() => {\n self._value = getter();\n });\n\n // Override notify: don't schedule this effect via the scheduler.\n // Instead mark dirty and propagate to our own subscribers.\n this._effect.notify = function () {\n if (!self._dirty) {\n self._dirty = true;\n trigger(self);\n }\n };\n\n // Run once synchronously to establish deps and cache initial value\n this._effect.run();\n this._dirty = false;\n }\n\n get value(): T {\n track(this);\n\n if (this._dirty) {\n this._effect.run();\n this._dirty = false;\n }\n\n return this._value;\n }\n\n peek(): T {\n if (this._dirty) {\n this._effect.run();\n this._dirty = false;\n }\n return this._value;\n }\n\n /**\n * toString() for template interpolation.\n */\n toString(): string {\n return String(this.value);\n }\n\n /**\n * valueOf() for numeric operations.\n */\n valueOf(): T {\n return this.value;\n }\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Create a computed reactive value.\n *\n * The getter function is tracked — when any signal it reads changes,\n * the computed is marked dirty and will re-evaluate on next `.value` read.\n *\n * @example\n * const count = signal(2);\n * const doubled = computed(() => count.value * 2);\n *\n * console.log(doubled.value); // 4\n *\n * count.value = 5;\n * console.log(doubled.value); // 10\n */\nexport function computed<T>(getter: () => T): Computed<T> {\n return new ComputedImpl(getter);\n}\n\n/**\n * Type guard: check if a value is a Computed.\n */\nexport function isComputed(value: unknown): value is Computed<unknown> {\n return (\n value != null &&\n typeof value === \"object\" &&\n COMPUTED_BRAND in (value as any)\n );\n}\n",
13
+ "/// <reference lib=\"dom\" />\n\n/**\n * SinwanJS Hydration — Marker Protocol\n *\n * Constants and helpers for the hydration marker format:\n *\n * data-sinwan-id=\"c0\" — component boundary\n * <!--sinwan-t:0-->val<!--/sinwan-t--> — reactive text boundary\n * data-sinwan-ev=\"click:0\" — event binding reference\n */\n\n// ─── Constants ─────────────────────────────────────────────\n\n/** Attribute on the root element of each component instance. */\nexport const COMP_ID_ATTR = \"data-sinwan-id\";\n\n/** Prefix for component IDs. */\nexport const COMP_ID_PREFIX = \"c\";\n\n/** Opening comment prefix for reactive text slots: `Sinwan-t:N` */\nexport const TEXT_MARKER_OPEN = \"sinwan-t:\";\n\n/** Closing comment for reactive text slots. */\nexport const TEXT_MARKER_CLOSE = \"/sinwan-t\";\n\n/** Attribute for event binding references. */\nexport const EVENT_ATTR = \"data-sinwan-ev\";\n\n// ─── Server-side marker generation ────────────────────────\n\n/** Build a component ID string, e.g. `\"c0\"`. */\nexport function compId(index: number): string {\n return `${COMP_ID_PREFIX}${index}`;\n}\n\n/** Build an opening text marker comment string. */\nexport function textMarkerOpen(index: number): string {\n return `<!--${TEXT_MARKER_OPEN}${index}-->`;\n}\n\n/** Build a closing text marker comment string. */\nexport function textMarkerCloseStr(): string {\n return `<!--${TEXT_MARKER_CLOSE}-->`;\n}\n\n/** Build an event attribute value, e.g. `\"click:0\"`. */\nexport function eventAttrValue(event: string, index: number): string {\n return `${event}:${index}`;\n}\n\n// ─── Client-side marker parsing ───────────────────────────\n\n/**\n * Check if a comment node is a reactive text opening marker.\n * Returns the slot index, or -1 if not a marker.\n */\nexport function parseTextOpenMarker(node: Comment): number {\n const data = node.data;\n if (data.startsWith(TEXT_MARKER_OPEN)) {\n const idx = parseInt(data.slice(TEXT_MARKER_OPEN.length), 10);\n return Number.isNaN(idx) ? -1 : idx;\n }\n return -1;\n}\n\n/**\n * Check if a comment node is a reactive text closing marker.\n */\nexport function isTextCloseMarker(node: Comment): boolean {\n return node.data === TEXT_MARKER_CLOSE;\n}\n\n/**\n * Parse `data-sinwan-ev` attribute value into event entries.\n * Format: `\"click:0\"` or `\"click:0,input:1\"` for multiple.\n * Returns array of `[eventName, handlerIndex]` tuples.\n */\nexport function parseEventAttr(value: string): [string, number][] {\n return value.split(\",\").map((pair) => {\n const [event, idx] = pair.split(\":\");\n return [event!, parseInt(idx!, 10)];\n });\n}\n\n/**\n * Parse `data-sinwan-id` into the component index.\n * e.g., `\"c3\"` → `3`\n */\nexport function parseCompId(value: string): number {\n return parseInt(value.slice(COMP_ID_PREFIX.length), 10);\n}\n",
14
+ "/// <reference lib=\"dom\" />\n\n/**\n * SinwanJS Client Renderer — DOM Operations\n *\n * Thin abstraction over native DOM APIs for testability\n * and potential future server-side DOM (e.g., happy-dom, linkedom).\n */\n\nexport interface DOMOps {\n createElement(tag: string): Element;\n createTextNode(text: string): Text;\n createComment(text: string): Comment;\n setAttribute(el: Element, key: string, value: string): void;\n removeAttribute(el: Element, key: string): void;\n setProperty(el: Element, key: string, value: unknown): void;\n insertBefore(parent: Node, child: Node, anchor: Node | null): void;\n appendChild(parent: Node, child: Node): void;\n remove(node: Node): void;\n setTextContent(node: Text, text: string): void;\n addEventListener(el: Element, event: string, handler: EventListener): void;\n removeEventListener(el: Element, event: string, handler: EventListener): void;\n parentNode(node: Node): Node | null;\n nextSibling(node: Node): Node | null;\n}\n\n/**\n * Default DOM operations using native browser APIs.\n */\nexport const domOps: DOMOps = {\n createElement(tag: string): Element {\n return document.createElement(tag);\n },\n\n createTextNode(text: string): Text {\n return document.createTextNode(text);\n },\n\n createComment(text: string): Comment {\n return document.createComment(text);\n },\n\n setAttribute(el: Element, key: string, value: string): void {\n el.setAttribute(key, value);\n },\n\n removeAttribute(el: Element, key: string): void {\n el.removeAttribute(key);\n },\n\n setProperty(el: Element, key: string, value: unknown): void {\n (el as any)[key] = value;\n },\n\n insertBefore(parent: Node, child: Node, anchor: Node | null): void {\n parent.insertBefore(child, anchor);\n },\n\n appendChild(parent: Node, child: Node): void {\n parent.appendChild(child);\n },\n\n remove(node: Node): void {\n node.parentNode?.removeChild(node);\n },\n\n setTextContent(node: Text, text: string): void {\n node.data = text;\n },\n\n addEventListener(el: Element, event: string, handler: EventListener): void {\n el.addEventListener(event, handler);\n },\n\n removeEventListener(el: Element, event: string, handler: EventListener): void {\n el.removeEventListener(event, handler);\n },\n\n parentNode(node: Node): Node | null {\n return node.parentNode;\n },\n\n nextSibling(node: Node): Node | null {\n return node.nextSibling;\n },\n};\n",
15
+ "/// <reference lib=\"dom\" />\n\n/**\n * SinwanJS Client Renderer — Event Binding\n *\n * Direct event binding (not delegation). Each handler is attached\n * directly to its target element for simplicity and easy hydration.\n *\n * Design decision: direct binding like Solid.js, not delegation like React.\n */\n\nimport { domOps } from \"./dom-ops.ts\";\nimport type { CleanupFn } from \"../reactivity/index.ts\";\n\n/**\n * Check if a prop key is an event handler (starts with \"on\").\n */\nexport function isEventProp(key: string): boolean {\n return key.length > 2 && key[0] === \"o\" && key[1] === \"n\" && key[2]! >= \"A\" && key[2]! <= \"Z\";\n}\n\n/**\n * Extract the DOM event name from a prop key.\n * e.g., \"onClick\" → \"click\", \"onMouseEnter\" → \"mouseenter\"\n */\nexport function toEventName(key: string): string {\n return key.slice(2).toLowerCase();\n}\n\n/**\n * Bind an event handler to an element.\n * Returns a cleanup function to remove the listener.\n */\nexport function bindEvent(\n el: Element,\n eventName: string,\n handler: EventListener,\n): CleanupFn {\n domOps.addEventListener(el, eventName, handler);\n return () => {\n domOps.removeEventListener(el, eventName, handler);\n };\n}\n\n/**\n * Bind all event props from an element's props object.\n * Returns an array of cleanup functions.\n */\nexport function bindEvents(\n el: Element,\n props: Record<string, unknown>,\n): CleanupFn[] {\n const cleanups: CleanupFn[] = [];\n\n for (const key of Object.keys(props)) {\n if (isEventProp(key)) {\n const handler = props[key];\n if (typeof handler === \"function\") {\n const eventName = toEventName(key);\n cleanups.push(bindEvent(el, eventName, handler as EventListener));\n }\n }\n }\n\n return cleanups;\n}\n",
16
+ "/**\n * SinwanJS Component Runtime — Instance Management\n *\n * Each component rendered on the client gets a ComponentInstance\n * that tracks its lifecycle hooks, effects, parent/child tree,\n * and provide/inject context.\n *\n * A global `currentInstance` stack lets lifecycle hooks (onMounted, etc.)\n * register themselves during setup — same pattern as Vue's getCurrentInstance.\n */\n\nimport type { SinwanComponent } from \"../types.ts\";\nimport type { MountedNode } from \"../renderer/types.ts\";\nimport type { CleanupFn } from \"../reactivity/index.ts\";\n\n// ─── ComponentInstance ─────────────────────────────────────\n\nlet uidCounter = 0;\n\nexport interface ComponentInstance {\n /** Unique identifier for this instance. */\n uid: number;\n\n /** The component definition (setup function). */\n component: SinwanComponent<any>;\n\n /** Props passed to this component. */\n props: Record<string, any>;\n\n /** The rendered DOM subtree (set after render). */\n element: MountedNode | null;\n\n /** Parent instance in the component tree. */\n parent: ComponentInstance | null;\n\n /** Child component instances. */\n children: ComponentInstance[];\n\n /** All effect dispose functions owned by this component. */\n effects: CleanupFn[];\n\n // ─── Lifecycle hook queues ────────────────────────────\n\n /** Callbacks to fire after the component is mounted to DOM. */\n _mountedHooks: (() => void)[];\n\n /** Callbacks to fire when the component is unmounted. */\n _unmountedHooks: (() => void)[];\n\n /** Callbacks to fire after any reactive update in this component. */\n _updatedHooks: (() => void)[];\n\n /** Error handler callbacks. */\n _errorHooks: ((err: Error) => void)[];\n\n // ─── Provide/Inject context ───────────────────────────\n\n /** Values provided by this instance (for inject in children). */\n provides: Record<string | symbol, unknown>;\n\n // ─── State flags ──────────────────────────────────────\n\n isMounted: boolean;\n isUnmounted: boolean;\n}\n\n/**\n * Create a fresh ComponentInstance.\n */\nexport function createComponentInstance(\n component: SinwanComponent<any>,\n props: Record<string, any>,\n parent: ComponentInstance | null,\n): ComponentInstance {\n return {\n uid: uidCounter++,\n component,\n props,\n element: null,\n parent,\n children: [],\n effects: [],\n _mountedHooks: [],\n _unmountedHooks: [],\n _updatedHooks: [],\n _errorHooks: [],\n // Inherit parent's provides (prototype chain for lookup)\n provides: parent ? Object.create(parent.provides) : Object.create(null),\n isMounted: false,\n isUnmounted: false,\n };\n}\n\n// ─── Current instance stack ────────────────────────────────\n\nlet currentInstance: ComponentInstance | null = null;\n\n/**\n * Get the currently active component instance.\n * Used by lifecycle hooks to register themselves.\n */\nexport function getCurrentInstance(): ComponentInstance | null {\n return currentInstance;\n}\n\n/**\n * Set the current instance (called by renderer before setup).\n * Returns the previous instance for restoration.\n */\nexport function setCurrentInstance(\n instance: ComponentInstance | null,\n): ComponentInstance | null {\n const prev = currentInstance;\n currentInstance = instance;\n return prev;\n}\n\n/**\n * Run a function with `instance` as the current component instance.\n * Automatically restores the previous instance when done.\n */\nexport function withInstance<T>(instance: ComponentInstance, fn: () => T): T {\n const prev = setCurrentInstance(instance);\n try {\n return fn();\n } finally {\n setCurrentInstance(prev);\n }\n}\n\n// ─── Lifecycle execution ───────────────────────────────────\n\n/**\n * Fire all onMounted hooks for an instance and its children (depth-first).\n */\nexport function fireMountedHooks(instance: ComponentInstance): void {\n // Children first (bottom-up, like Vue)\n for (const child of instance.children) {\n fireMountedHooks(child);\n }\n\n if (!instance.isMounted) {\n instance.isMounted = true;\n for (const hook of instance._mountedHooks) {\n hook();\n }\n }\n}\n\n/**\n * Fire all onUnmounted hooks and dispose all effects for an instance\n * and its children (depth-first, children first).\n */\nexport function fireUnmountedHooks(instance: ComponentInstance): void {\n // Children first\n for (const child of instance.children) {\n fireUnmountedHooks(child);\n }\n\n if (instance.isMounted && !instance.isUnmounted) {\n instance.isUnmounted = true;\n instance.isMounted = false;\n\n // Fire unmounted hooks\n for (const hook of instance._unmountedHooks) {\n hook();\n }\n\n // Dispose all effects owned by this component\n for (const dispose of instance.effects) {\n dispose();\n }\n instance.effects.length = 0;\n }\n}\n\n/**\n * Fire onUpdated hooks for the current instance.\n */\nexport function fireUpdatedHooks(instance: ComponentInstance): void {\n for (const hook of instance._updatedHooks) {\n hook();\n }\n}\n\n/**\n * Handle an error in the component tree — walks up to find an error handler.\n */\nexport function handleComponentError(\n instance: ComponentInstance,\n err: Error,\n): void {\n let current: ComponentInstance | null = instance;\n while (current) {\n if (current._errorHooks.length > 0) {\n for (const hook of current._errorHooks) {\n hook(err);\n }\n return;\n }\n current = current.parent;\n }\n // No handler found — re-throw\n console.error(\"[Sinwan] Unhandled component error:\", err);\n}\n",
17
+ "/**\n * SinwanJS Server — Hydration-Aware SSR Renderer\n *\n * Enhanced `renderToString` that injects hydration markers:\n *\n * data-sinwan-id=\"c0\" — component boundary\n * <!--sinwan-t:0-->val<!--/sinwan-t--> — reactive text boundary\n * data-sinwan-ev=\"click:0\" — event binding reference\n *\n * Usage:\n * const html = await renderToHydratableString(App, { name: \"World\" });\n * // → '<div data-sinwan-id=\"c0\"><p>Count: <!--sinwan-t:0-->5<!--/sinwan-t--></p>...</div>'\n */\n\nimport type { SinwanElement, SinwanNode, SinwanComponent } from \"../types.ts\";\nimport { HtmlEscapedString, escapeHtml } from \"../escaper.ts\";\nimport { isSignal } from \"../reactivity/signal.ts\";\nimport { isComputed } from \"../reactivity/computed.ts\";\nimport {\n compId,\n textMarkerOpen,\n textMarkerCloseStr,\n COMP_ID_ATTR,\n EVENT_ATTR,\n} from \"../hydration/markers.ts\";\nimport { isEventProp, toEventName } from \"../renderer/events.ts\";\nimport {\n createComponentInstance,\n setCurrentInstance,\n} from \"../component/instance.ts\";\n\n// ─── Hydration context ─────────────────────────────────────\n\ninterface HydrationContext {\n componentIndex: number;\n textIndex: number;\n eventIndex: number;\n}\n\nfunction createHydrationContext(): HydrationContext {\n return { componentIndex: 0, textIndex: 0, eventIndex: 0 };\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Render a component to an HTML string with hydration markers.\n */\nexport async function renderToHydratableString(\n component: SinwanComponent<any>,\n props?: Record<string, unknown>,\n): Promise<string> {\n const ctx = createHydrationContext();\n const mergedProps = props ?? {};\n\n // Create a temporary instance so lifecycle hooks register silently\n const instance = createComponentInstance(component, mergedProps, null);\n setCurrentInstance(instance);\n\n // Call the component to get the element tree\n const result = await component(mergedProps);\n\n setCurrentInstance(null);\n\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return renderElementH(result, ctx, true /* isComponentRoot */);\n }\n\n return renderNodeH(result as SinwanNode, ctx);\n}\n\n/**\n * Render a raw SinwanNode tree with hydration markers.\n */\nexport async function renderNodeToHydratableString(\n node: SinwanNode,\n): Promise<string> {\n const ctx = createHydrationContext();\n return renderNodeH(node, ctx);\n}\n\n// ─── Internal rendering ────────────────────────────────────\n\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Render a node with hydration markers.\n */\nfunction renderNodeH(node: SinwanNode, ctx: HydrationContext): string {\n if (node == null || typeof node === \"boolean\") return \"\";\n\n if (typeof node === \"string\") return escapeHtml(node);\n if (typeof node === \"number\") return String(node);\n\n if (node instanceof HtmlEscapedString) return node.value;\n\n // Signal or Computed → wrap with text markers\n if (isSignal(node) || isComputed(node)) {\n const value = (node as any).value;\n const idx = ctx.textIndex++;\n return `${textMarkerOpen(idx)}${escapeHtml(String(value))}${textMarkerCloseStr()}`;\n }\n\n if (Array.isArray(node)) {\n return node.map((child) => renderNodeH(child, ctx)).join(\"\");\n }\n\n if (node instanceof Promise) {\n // Sync-only for hydration SSR — await should be handled at top level\n return \"\";\n }\n\n if (typeof node === \"object\" && \"tag\" in node) {\n return renderElementH(node, ctx, false);\n }\n\n return escapeHtml(String(node));\n}\n\n/**\n * Render an element with hydration markers.\n */\nfunction renderElementH(\n element: SinwanElement,\n ctx: HydrationContext,\n isComponentRoot: boolean,\n): string {\n const { tag, props, children } = element;\n\n // Fragment\n if (tag === \"\") {\n return children.map((child) => renderNodeH(child, ctx)).join(\"\");\n }\n\n // Functional component\n if (typeof tag === \"function\") {\n return renderComponentH(tag, props, ctx);\n }\n\n // Intrinsic HTML element\n if (typeof tag === \"string\") {\n return renderIntrinsicH(tag, props, children, ctx, isComponentRoot);\n }\n\n return children.map((child) => renderNodeH(child, ctx)).join(\"\");\n}\n\n/**\n * Render a functional component — calls it and marks the root element.\n */\nfunction renderComponentH(\n component: Function,\n props: Record<string, unknown>,\n ctx: HydrationContext,\n): string {\n // Set a temporary instance for lifecycle hooks\n const parentInstance = (globalThis as any).__SinwanCurrentInstance;\n const instance = createComponentInstance(component as any, props, null);\n const prev = setCurrentInstance(instance);\n\n const result = component(props);\n\n setCurrentInstance(prev);\n\n if (result && typeof result === \"object\" && \"tag\" in result) {\n return renderElementH(\n result as SinwanElement,\n ctx,\n true /* mark as component root */,\n );\n }\n\n return renderNodeH(result as SinwanNode, ctx);\n}\n\n/**\n * Render an intrinsic element with hydration markers.\n */\nfunction renderIntrinsicH(\n tag: string,\n props: Record<string, unknown>,\n children: SinwanNode[],\n ctx: HydrationContext,\n isComponentRoot: boolean,\n): string {\n let attrs = \"\";\n\n // Component boundary marker\n if (isComponentRoot) {\n attrs += ` ${COMP_ID_ATTR}=\"${compId(ctx.componentIndex++)}\"`;\n }\n\n // Event markers + regular attributes\n const eventParts: string[] = [];\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\" || key === \"dangerouslySetInnerHTML\") continue;\n\n if (isEventProp(key)) {\n // Collect event markers\n const eventName = toEventName(key);\n eventParts.push(`${eventName}:${ctx.eventIndex++}`);\n continue;\n }\n\n if (value == null || value === false) continue;\n\n // Resolve signal/computed values to their current values for SSR\n let resolvedValue = value;\n if (isSignal(value) || isComputed(value)) {\n resolvedValue = (value as any).value;\n }\n\n if (resolvedValue === true) {\n const attrName =\n key === \"className\" ? \"class\" : key === \"htmlFor\" ? \"for\" : key;\n attrs += ` ${attrName}`;\n continue;\n }\n\n const attrName =\n key === \"className\" ? \"class\" : key === \"htmlFor\" ? \"for\" : key;\n attrs += ` ${attrName}=\"${escapeHtml(String(resolvedValue))}\"`;\n }\n\n // Add event attribute\n if (eventParts.length > 0) {\n attrs += ` ${EVENT_ATTR}=\"${eventParts.join(\",\")}\"`;\n }\n\n // Void elements\n if (VOID_ELEMENTS.has(tag)) {\n return `<${tag}${attrs}>`;\n }\n\n // Dangerous inner HTML\n const dangerous = props.dangerouslySetInnerHTML as\n | { __html?: string }\n | undefined;\n if (dangerous && typeof dangerous.__html === \"string\") {\n return `<${tag}${attrs}>${dangerous.__html}</${tag}>`;\n }\n\n // Render children with markers\n const childrenHtml = children\n .map((child) => renderNodeH(child, ctx))\n .join(\"\");\n\n return `<${tag}${attrs}>${childrenHtml}</${tag}>`;\n}\n"
18
+ ],
19
+ "mappings": "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",
20
+ "debugId": "C8441168D05E406D64756E2164756E21",
21
+ "names": []
22
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * SinwanJS View Module — Component Factories
3
+ *
4
+ * createComponent and createPage factories for defining
5
+ * typed components and pages with full TypeScript inference.
6
+ */
7
+ import type { SinwanComponent, SinwanPage, SinwanNode, SinwanSlots } from "../types.ts";
8
+ /**
9
+ * Create a typed Sinwan component.
10
+ *
11
+ * Mirrors React.FC<P> exactly - single props object with children injected.
12
+ * Children can be a single SinwanNode or a SinwanSlots object for named slots.
13
+ *
14
+ * @example
15
+ * interface CardProps {
16
+ * title: string;
17
+ * }
18
+ * const Card = createComponent<CardProps>(({ title, children }) => (
19
+ * <div class="card">
20
+ * <h2>{title}</h2>
21
+ * <div class="content">{children}</div>
22
+ * </div>
23
+ * ));
24
+ */
25
+ export declare function createComponent<P extends object = {}>(fn: (props: P & {
26
+ children?: SinwanNode | SinwanSlots;
27
+ }) => ReturnType<SinwanComponent<P>>): SinwanComponent<P>;
28
+ /**
29
+ * Create a typed Sinwan page.
30
+ *
31
+ * Pages receive a plain data object and return a renderable element tree.
32
+ * Pages are registered with the app and rendered via `c.render("name", data)`.
33
+ *
34
+ * @example
35
+ * interface HomeData {
36
+ * title: string;
37
+ * posts: { id: number; title: string }[];
38
+ * }
39
+ * const HomePage = createPage<HomeData>(({ title, posts }) => (
40
+ * <Layout title={title}>
41
+ * <h1>{title}</h1>
42
+ * <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
43
+ * </Layout>
44
+ * ));
45
+ *
46
+ * app.setRenderer("home", HomePage);
47
+ * app.get("/", (c) => c.render("home", { title: "Home", posts: [] }));
48
+ */
49
+ export declare function createPage<D extends object = {}>(fn: (data: D) => ReturnType<SinwanPage<D>>): SinwanPage<D>;
50
+ /**
51
+ * Create a layout component.
52
+ *
53
+ * Layouts are just components that accept children. They typically render
54
+ * the HTML document structure, head metadata, and shared UI elements.
55
+ *
56
+ * @example
57
+ * interface LayoutProps {
58
+ * title?: string;
59
+ * lang?: string;
60
+ * }
61
+ * const Layout = createLayout<LayoutProps>(({ title = "App", lang = "en", children }) => (
62
+ * <html lang={lang}>
63
+ * <head><title>{title}</title></head>
64
+ * <body>{children}</body>
65
+ * </html>
66
+ * ));
67
+ */
68
+ export declare function createLayout<P extends object = {}>(fn: (props: P & {
69
+ children: SinwanNode;
70
+ }) => ReturnType<SinwanComponent<P & {
71
+ children: SinwanNode;
72
+ }>>): SinwanComponent<P & {
73
+ children: SinwanNode;
74
+ }>;
75
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/component/create.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,EACnD,EAAE,EAAE,CACF,KAAK,EAAE,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,UAAU,GAAG,WAAW,CAAA;CAAE,KAC/C,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAClC,eAAe,CAAC,CAAC,CAAC,CAKpB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,EAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GACzC,UAAU,CAAC,CAAC,CAAC,CAKf;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,EAChD,EAAE,EAAE,CACF,KAAK,EAAE,CAAC,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAA;CAAE,KAChC,UAAU,CAAC,eAAe,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC,GAC7D,eAAe,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAA;CAAE,CAAC,CAE/C"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * SinwanJS Component Runtime — Public API
3
+ */
4
+ export { getCurrentInstance, setCurrentInstance, withInstance, createComponentInstance, fireMountedHooks, fireUnmountedHooks, fireUpdatedHooks, handleComponentError, } from "./instance.ts";
5
+ export type { ComponentInstance } from "./instance.ts";
6
+ export { onMounted, onUnmounted, onUpdated, onError } from "./lifecycle.ts";
7
+ export { createComponent, createPage, createLayout } from "./create.ts";
8
+ export { provide, inject } from "./provide-inject.ts";
9
+ export type { InjectionKey } from "./provide-inject.ts";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/component/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG5E,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGxE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * SinwanJS Component Runtime — Instance Management
3
+ *
4
+ * Each component rendered on the client gets a ComponentInstance
5
+ * that tracks its lifecycle hooks, effects, parent/child tree,
6
+ * and provide/inject context.
7
+ *
8
+ * A global `currentInstance` stack lets lifecycle hooks (onMounted, etc.)
9
+ * register themselves during setup — same pattern as Vue's getCurrentInstance.
10
+ */
11
+ import type { SinwanComponent } from "../types.ts";
12
+ import type { MountedNode } from "../renderer/types.ts";
13
+ import type { CleanupFn } from "../reactivity/index.ts";
14
+ export interface ComponentInstance {
15
+ /** Unique identifier for this instance. */
16
+ uid: number;
17
+ /** The component definition (setup function). */
18
+ component: SinwanComponent<any>;
19
+ /** Props passed to this component. */
20
+ props: Record<string, any>;
21
+ /** The rendered DOM subtree (set after render). */
22
+ element: MountedNode | null;
23
+ /** Parent instance in the component tree. */
24
+ parent: ComponentInstance | null;
25
+ /** Child component instances. */
26
+ children: ComponentInstance[];
27
+ /** All effect dispose functions owned by this component. */
28
+ effects: CleanupFn[];
29
+ /** Callbacks to fire after the component is mounted to DOM. */
30
+ _mountedHooks: (() => void)[];
31
+ /** Callbacks to fire when the component is unmounted. */
32
+ _unmountedHooks: (() => void)[];
33
+ /** Callbacks to fire after any reactive update in this component. */
34
+ _updatedHooks: (() => void)[];
35
+ /** Error handler callbacks. */
36
+ _errorHooks: ((err: Error) => void)[];
37
+ /** Values provided by this instance (for inject in children). */
38
+ provides: Record<string | symbol, unknown>;
39
+ isMounted: boolean;
40
+ isUnmounted: boolean;
41
+ }
42
+ /**
43
+ * Create a fresh ComponentInstance.
44
+ */
45
+ export declare function createComponentInstance(component: SinwanComponent<any>, props: Record<string, any>, parent: ComponentInstance | null): ComponentInstance;
46
+ /**
47
+ * Get the currently active component instance.
48
+ * Used by lifecycle hooks to register themselves.
49
+ */
50
+ export declare function getCurrentInstance(): ComponentInstance | null;
51
+ /**
52
+ * Set the current instance (called by renderer before setup).
53
+ * Returns the previous instance for restoration.
54
+ */
55
+ export declare function setCurrentInstance(instance: ComponentInstance | null): ComponentInstance | null;
56
+ /**
57
+ * Run a function with `instance` as the current component instance.
58
+ * Automatically restores the previous instance when done.
59
+ */
60
+ export declare function withInstance<T>(instance: ComponentInstance, fn: () => T): T;
61
+ /**
62
+ * Fire all onMounted hooks for an instance and its children (depth-first).
63
+ */
64
+ export declare function fireMountedHooks(instance: ComponentInstance): void;
65
+ /**
66
+ * Fire all onUnmounted hooks and dispose all effects for an instance
67
+ * and its children (depth-first, children first).
68
+ */
69
+ export declare function fireUnmountedHooks(instance: ComponentInstance): void;
70
+ /**
71
+ * Fire onUpdated hooks for the current instance.
72
+ */
73
+ export declare function fireUpdatedHooks(instance: ComponentInstance): void;
74
+ /**
75
+ * Handle an error in the component tree — walks up to find an error handler.
76
+ */
77
+ export declare function handleComponentError(instance: ComponentInstance, err: Error): void;
78
+ //# sourceMappingURL=instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/component/instance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAMxD,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IAEZ,iDAAiD;IACjD,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;IAEhC,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE3B,mDAAmD;IACnD,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAE5B,6CAA6C;IAC7C,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEjC,iCAAiC;IACjC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAE9B,4DAA4D;IAC5D,OAAO,EAAE,SAAS,EAAE,CAAC;IAIrB,+DAA+D;IAC/D,aAAa,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAE9B,yDAAyD;IACzD,eAAe,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAEhC,qEAAqE;IACrE,aAAa,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAE9B,+BAA+B;IAC/B,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;IAItC,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;IAI3C,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAC/B,iBAAiB,CAkBnB;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,iBAAiB,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GACjC,iBAAiB,GAAG,IAAI,CAI1B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAO3E;AAID;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAYlE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAqBpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAIlE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,EAAE,KAAK,GACT,IAAI,CAaN"}