@elurjs/core 3.6.2 → 3.7.0-beta.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 (211) hide show
  1. package/dist/lib/async.cjs +1 -1
  2. package/dist/lib/async.js +1 -1
  3. package/dist/lib/component.cjs +1 -2
  4. package/dist/lib/component.js +2 -66
  5. package/dist/lib/context.cjs +1 -1
  6. package/dist/lib/context.js +35 -23
  7. package/dist/lib/devtools.cjs +1 -1
  8. package/dist/lib/devtools.js +1 -1
  9. package/dist/lib/elur/async.cjs +1 -1
  10. package/dist/lib/elur/async.cjs.map +1 -1
  11. package/dist/lib/elur/async.js +1 -1
  12. package/dist/lib/elur/component.cjs +1 -2
  13. package/dist/lib/elur/component.d.cts +1 -17
  14. package/dist/lib/elur/component.d.ts +1 -17
  15. package/dist/lib/elur/component.js +2 -66
  16. package/dist/lib/elur/context.cjs +1 -1
  17. package/dist/lib/elur/context.cjs.map +1 -1
  18. package/dist/lib/elur/context.d.cts +5 -0
  19. package/dist/lib/elur/context.d.ts +5 -0
  20. package/dist/lib/elur/context.js +35 -23
  21. package/dist/lib/elur/context.js.map +1 -1
  22. package/dist/lib/elur/devtools.cjs +1 -1
  23. package/dist/lib/elur/devtools.cjs.map +1 -1
  24. package/dist/lib/elur/devtools.js +1 -1
  25. package/dist/lib/elur/form.cjs +1 -1
  26. package/dist/lib/elur/form.cjs.map +1 -1
  27. package/dist/lib/elur/form.js +1 -1
  28. package/dist/lib/elur/hydrate/index.cjs +1 -2
  29. package/dist/lib/elur/hydrate/index.d.cts +1 -13
  30. package/dist/lib/elur/hydrate/index.d.ts +1 -13
  31. package/dist/lib/elur/hydrate/index.js +2 -410
  32. package/dist/lib/elur/lifecycle.cjs +1 -1
  33. package/dist/lib/elur/lifecycle.cjs.map +1 -1
  34. package/dist/lib/elur/lifecycle.d.cts +27 -0
  35. package/dist/lib/elur/lifecycle.d.ts +27 -0
  36. package/dist/lib/elur/lifecycle.js +4 -0
  37. package/dist/lib/elur/lifecycle.js.map +1 -1
  38. package/dist/lib/elur/next/component.d.cts +281 -0
  39. package/dist/lib/elur/next/component.d.ts +281 -0
  40. package/dist/lib/elur/next/dom-write.d.cts +18 -0
  41. package/dist/lib/elur/next/dom-write.d.ts +18 -0
  42. package/dist/lib/elur/next/hydrate.d.cts +14 -0
  43. package/dist/lib/elur/next/hydrate.d.ts +14 -0
  44. package/dist/lib/elur/next/keyed-diff.d.cts +46 -0
  45. package/dist/lib/elur/next/keyed-diff.d.ts +46 -0
  46. package/dist/lib/elur/next/mount-helpers.d.cts +25 -0
  47. package/dist/lib/elur/next/mount-helpers.d.ts +25 -0
  48. package/dist/lib/elur/next/mount.d.cts +29 -0
  49. package/dist/lib/elur/next/mount.d.ts +29 -0
  50. package/dist/lib/elur/next/node-binding.d.cts +6 -0
  51. package/dist/lib/elur/next/node-binding.d.ts +6 -0
  52. package/dist/lib/elur/next/reactivity.d.cts +193 -0
  53. package/dist/lib/elur/next/reactivity.d.ts +193 -0
  54. package/dist/lib/elur/next-2/component.cjs +2 -0
  55. package/dist/lib/elur/next-2/component.cjs.map +1 -0
  56. package/dist/lib/elur/next-2/component.d.cts +283 -0
  57. package/dist/lib/elur/next-2/component.d.ts +283 -0
  58. package/dist/lib/elur/next-2/component.js +340 -0
  59. package/dist/lib/elur/next-2/component.js.map +1 -0
  60. package/dist/lib/elur/next-2/dom-write.cjs +2 -0
  61. package/dist/lib/elur/next-2/dom-write.cjs.map +1 -0
  62. package/dist/lib/elur/next-2/dom-write.d.cts +18 -0
  63. package/dist/lib/elur/next-2/dom-write.d.ts +18 -0
  64. package/dist/lib/elur/next-2/dom-write.js +31 -0
  65. package/dist/lib/elur/next-2/dom-write.js.map +1 -0
  66. package/dist/lib/elur/next-2/hydrate.cjs +2 -0
  67. package/dist/lib/elur/next-2/hydrate.cjs.map +1 -0
  68. package/dist/lib/elur/next-2/hydrate.d.cts +30 -0
  69. package/dist/lib/elur/next-2/hydrate.d.ts +30 -0
  70. package/dist/lib/elur/next-2/hydrate.js +449 -0
  71. package/dist/lib/elur/next-2/hydrate.js.map +1 -0
  72. package/dist/lib/elur/next-2/keyed-diff.cjs +2 -0
  73. package/dist/lib/elur/next-2/keyed-diff.cjs.map +1 -0
  74. package/dist/lib/elur/next-2/keyed-diff.d.cts +79 -0
  75. package/dist/lib/elur/next-2/keyed-diff.d.ts +79 -0
  76. package/dist/lib/elur/next-2/keyed-diff.js +208 -0
  77. package/dist/lib/elur/next-2/keyed-diff.js.map +1 -0
  78. package/dist/lib/elur/next-2/mount-helpers.cjs +2 -0
  79. package/dist/lib/elur/next-2/mount-helpers.cjs.map +1 -0
  80. package/dist/lib/elur/next-2/mount-helpers.d.cts +25 -0
  81. package/dist/lib/elur/next-2/mount-helpers.d.ts +25 -0
  82. package/dist/lib/elur/next-2/mount-helpers.js +87 -0
  83. package/dist/lib/elur/next-2/mount-helpers.js.map +1 -0
  84. package/dist/lib/elur/next-2/mount.cjs +2 -0
  85. package/dist/lib/elur/next-2/mount.cjs.map +1 -0
  86. package/dist/lib/elur/next-2/mount.d.cts +29 -0
  87. package/dist/lib/elur/next-2/mount.d.ts +29 -0
  88. package/dist/lib/elur/next-2/mount.js +34 -0
  89. package/dist/lib/elur/next-2/mount.js.map +1 -0
  90. package/dist/lib/elur/next-2/node-binding.cjs +2 -0
  91. package/dist/lib/elur/next-2/node-binding.cjs.map +1 -0
  92. package/dist/lib/elur/next-2/node-binding.d.cts +6 -0
  93. package/dist/lib/elur/next-2/node-binding.d.ts +6 -0
  94. package/dist/lib/elur/next-2/node-binding.js +130 -0
  95. package/dist/lib/elur/next-2/node-binding.js.map +1 -0
  96. package/dist/lib/elur/next-2/reactivity.cjs +2 -0
  97. package/dist/lib/elur/next-2/reactivity.cjs.map +1 -0
  98. package/dist/lib/elur/next-2/reactivity.d.cts +220 -0
  99. package/dist/lib/elur/next-2/reactivity.d.ts +220 -0
  100. package/dist/lib/elur/next-2/reactivity.js +614 -0
  101. package/dist/lib/elur/next-2/reactivity.js.map +1 -0
  102. package/dist/lib/elur/next-2/scheduler.cjs +2 -0
  103. package/dist/lib/elur/next-2/scheduler.cjs.map +1 -0
  104. package/dist/lib/elur/next-2/scheduler.d.cts +23 -0
  105. package/dist/lib/elur/next-2/scheduler.d.ts +23 -0
  106. package/dist/lib/elur/next-2/scheduler.js +26 -0
  107. package/dist/lib/elur/next-2/scheduler.js.map +1 -0
  108. package/dist/lib/elur/plugins.cjs +1 -1
  109. package/dist/lib/elur/plugins.cjs.map +1 -1
  110. package/dist/lib/elur/plugins.js +1 -1
  111. package/dist/lib/elur/reactivity.cjs +1 -2
  112. package/dist/lib/elur/reactivity.d.cts +1 -67
  113. package/dist/lib/elur/reactivity.d.ts +1 -67
  114. package/dist/lib/elur/reactivity.js +2 -218
  115. package/dist/lib/elur/router.cjs +1 -1
  116. package/dist/lib/elur/router.cjs.map +1 -1
  117. package/dist/lib/elur/router.js +1 -1
  118. package/dist/lib/elur/server/index.cjs +1 -1
  119. package/dist/lib/elur/server/index.cjs.map +1 -1
  120. package/dist/lib/elur/server/index.js +175 -107
  121. package/dist/lib/elur/server/index.js.map +1 -1
  122. package/dist/lib/elur/store.cjs +1 -1
  123. package/dist/lib/elur/store.cjs.map +1 -1
  124. package/dist/lib/elur/store.js +1 -1
  125. package/dist/lib/elur/template/bindings.cjs +1 -1
  126. package/dist/lib/elur/template/bindings.cjs.map +1 -1
  127. package/dist/lib/elur/template/bindings.js +98 -84
  128. package/dist/lib/elur/template/bindings.js.map +1 -1
  129. package/dist/lib/elur/template/dom-write.d.cts +1 -5
  130. package/dist/lib/elur/template/dom-write.d.ts +1 -5
  131. package/dist/lib/elur/template/error-boundary.cjs +1 -1
  132. package/dist/lib/elur/template/error-boundary.cjs.map +1 -1
  133. package/dist/lib/elur/template/error-boundary.js +56 -50
  134. package/dist/lib/elur/template/error-boundary.js.map +1 -1
  135. package/dist/lib/elur/template/html.cjs +1 -1
  136. package/dist/lib/elur/template/html.cjs.map +1 -1
  137. package/dist/lib/elur/template/html.js +40 -37
  138. package/dist/lib/elur/template/html.js.map +1 -1
  139. package/dist/lib/elur/template/index.cjs +1 -1
  140. package/dist/lib/elur/template/index.d.cts +2 -1
  141. package/dist/lib/elur/template/index.d.ts +2 -1
  142. package/dist/lib/elur/template/index.js +13 -12
  143. package/dist/lib/elur/template/keyed-diff.d.cts +1 -32
  144. package/dist/lib/elur/template/keyed-diff.d.ts +1 -32
  145. package/dist/lib/elur/template/keyed.cjs +1 -1
  146. package/dist/lib/elur/template/keyed.cjs.map +1 -1
  147. package/dist/lib/elur/template/keyed.d.cts +10 -2
  148. package/dist/lib/elur/template/keyed.d.ts +10 -2
  149. package/dist/lib/elur/template/keyed.js +12 -1
  150. package/dist/lib/elur/template/keyed.js.map +1 -1
  151. package/dist/lib/elur/template/mount-helpers.d.cts +1 -29
  152. package/dist/lib/elur/template/mount-helpers.d.ts +1 -29
  153. package/dist/lib/elur/template/node-binding.d.cts +1 -6
  154. package/dist/lib/elur/template/node-binding.d.ts +1 -6
  155. package/dist/lib/elur/template/portal.cjs +1 -1
  156. package/dist/lib/elur/template/portal.cjs.map +1 -1
  157. package/dist/lib/elur/template/portal.js +1 -1
  158. package/dist/lib/elur/template/transitions.cjs +1 -1
  159. package/dist/lib/elur/template/transitions.cjs.map +1 -1
  160. package/dist/lib/elur/template/transitions.js +2 -2
  161. package/dist/lib/elur/template/types.cjs +1 -1
  162. package/dist/lib/elur/template/types.cjs.map +1 -1
  163. package/dist/lib/elur/template/types.d.cts +55 -0
  164. package/dist/lib/elur/template/types.d.ts +55 -0
  165. package/dist/lib/elur/template/types.js +5 -1
  166. package/dist/lib/elur/template/types.js.map +1 -1
  167. package/dist/lib/elur.cjs +1 -1
  168. package/dist/lib/elur.js +2 -2
  169. package/dist/lib/form.cjs +1 -1
  170. package/dist/lib/form.js +1 -1
  171. package/dist/lib/hydrate.cjs +1 -2
  172. package/dist/lib/hydrate.js +2 -410
  173. package/dist/lib/index.cjs +1 -1
  174. package/dist/lib/index.js +2 -2
  175. package/dist/lib/lifecycle.cjs +1 -1
  176. package/dist/lib/lifecycle.js +4 -0
  177. package/dist/lib/plugins.cjs +1 -1
  178. package/dist/lib/plugins.js +1 -1
  179. package/dist/lib/router.cjs +1 -1
  180. package/dist/lib/router.js +1 -1
  181. package/dist/lib/server.cjs +1 -1
  182. package/dist/lib/server.js +175 -107
  183. package/dist/lib/signals.cjs +1 -2
  184. package/dist/lib/signals.js +2 -218
  185. package/dist/lib/store.cjs +1 -1
  186. package/dist/lib/store.js +1 -1
  187. package/dist/lib/template.cjs +1 -1
  188. package/dist/lib/template.js +13 -12
  189. package/package.json +7 -9
  190. package/dist/lib/elur/component.cjs.map +0 -1
  191. package/dist/lib/elur/component.js.map +0 -1
  192. package/dist/lib/elur/hydrate/index.cjs.map +0 -1
  193. package/dist/lib/elur/hydrate/index.js.map +0 -1
  194. package/dist/lib/elur/reactivity.cjs.map +0 -1
  195. package/dist/lib/elur/reactivity.js.map +0 -1
  196. package/dist/lib/elur/template/dom-write.cjs +0 -2
  197. package/dist/lib/elur/template/dom-write.cjs.map +0 -1
  198. package/dist/lib/elur/template/dom-write.js +0 -16
  199. package/dist/lib/elur/template/dom-write.js.map +0 -1
  200. package/dist/lib/elur/template/keyed-diff.cjs +0 -2
  201. package/dist/lib/elur/template/keyed-diff.cjs.map +0 -1
  202. package/dist/lib/elur/template/keyed-diff.js +0 -100
  203. package/dist/lib/elur/template/keyed-diff.js.map +0 -1
  204. package/dist/lib/elur/template/mount-helpers.cjs +0 -2
  205. package/dist/lib/elur/template/mount-helpers.cjs.map +0 -1
  206. package/dist/lib/elur/template/mount-helpers.js +0 -132
  207. package/dist/lib/elur/template/mount-helpers.js.map +0 -1
  208. package/dist/lib/elur/template/node-binding.cjs +0 -2
  209. package/dist/lib/elur/template/node-binding.cjs.map +0 -1
  210. package/dist/lib/elur/template/node-binding.js +0 -95
  211. package/dist/lib/elur/template/node-binding.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"server.cjs","names":[],"sources":["../../src/elur/server/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { _popComponentContext, _pushComponentContext, _setContextScopeResolver } from \"../context.js\";\nimport { isElurComponent, type ElurComponent } from \"../lifecycle.js\";\nimport {\n isKeyedList,\n isElurTemplate,\n ELUR_RENDER_PROTOCOL,\n ELUR_TEMPLATE_DESCRIPTOR,\n type ServerRenderProtocolContext,\n type TemplateBindingContext,\n type TemplateDescriptor,\n} from \"../template/types.js\";\nimport { sanitizeUrl } from \"../template/sanitize.js\";\nimport { normalizeRepeatKey, serializeRepeatKey } from \"../template/keyed.js\";\n\n// Local guards avoid sharing the same minified import binding name with\n// callback parameters in the same module (esbuild bug with shared chunks).\nconst isTemplate = isElurTemplate;\nconst isKeyed = isKeyedList;\n\nexport interface RenderErrorInfo {\n /** Binding index inside the descriptor (or -1 for root/component errors). */\n index: number;\n /** Binding context where the error occurred. */\n context: \"node\" | \"attribute\" | \"event\" | \"root\" | \"component\";\n /** The original error. */\n cause: unknown;\n /** Debug name of the component when the error happened inside one. */\n component?: string;\n}\n\nexport interface ServerRenderOptions {\n markers?: \"none\" | \"hydration\";\n signal?: AbortSignal;\n context?: unknown;\n onError?: (error: unknown, info: RenderErrorInfo) => void;\n}\n\n/** A fragment of the rendered markup, streamed incrementally by `renderToChunks`. */\nexport interface RenderChunk {\n type: \"markup\" | \"boundary-start\" | \"boundary-end\" | \"error\" | \"done\";\n value: string;\n index: number;\n}\n\ninterface RenderState {\n markers: boolean;\n signal?: AbortSignal;\n context?: unknown;\n onError?: (error: unknown, info: RenderErrorInfo) => void;\n}\n\nconst renderContext = new AsyncLocalStorage<Map<unknown, unknown>[]>();\n_setContextScopeResolver(() => renderContext.getStore());\n\nexport interface ServerRenderScope {\n /** Abort signal that cancels all renders created through this scope. */\n readonly signal: AbortSignal;\n /** Renders a value to a full string, sharing this scope's context isolation. */\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n /** Streams a value as incremental chunks, sharing this scope's context isolation. */\n renderToChunks(value: unknown, options?: { markers?: boolean }): AsyncIterable<RenderChunk>;\n /** Aborts every render running inside this scope. */\n abort(reason?: unknown): void;\n}\n\n/**\n * Creates an explicit server render scope: a per-render isolation unit that\n * keeps component context, markers and abort state private. Concurrent renders\n * created from the same scope never share `provide`/`inject` state.\n */\nexport function createServerRenderScope(options: Omit<ServerRenderOptions, \"signal\"> = {}): ServerRenderScope {\n const controller = new AbortController();\n const state: RenderState = {\n markers: options.markers === \"hydration\",\n context: options.context,\n onError: options.onError,\n };\n const run = <T>(fn: () => Promise<T> | T): Promise<T> => Promise.resolve(renderContext.run([], fn));\n return {\n signal: controller.signal,\n async render(value, opts): Promise<string> {\n const scoped: RenderState = { ...state, markers: opts?.markers ?? state.markers, signal: controller.signal };\n let out = \"\";\n await run(() => {\n return (async () => {\n for await (const chunk of renderValueChunks(value, scoped)) {\n out += chunk.value;\n }\n })();\n });\n return out;\n },\n renderToChunks(value, opts): AsyncIterable<RenderChunk> {\n const scoped: RenderState = { ...state, markers: opts?.markers ?? state.markers, signal: controller.signal };\n return streamChunks(value, scoped);\n },\n abort(reason?: unknown): void {\n controller.abort(reason);\n },\n };\n}\n\n/**\n * Streams chunks produced inside an AsyncLocalStorage scope, preserving\n * per-render context isolation while yielding incrementally.\n */\nfunction streamChunks(value: unknown, state: RenderState): AsyncIterable<RenderChunk> {\n return {\n async *[Symbol.asyncIterator]() {\n const queue: RenderChunk[] = [];\n const waiters: Array<() => void> = [];\n let producerDone = false;\n let producerError: unknown;\n const wake = () => {\n const waiter = waiters.shift();\n waiter?.();\n };\n\n const task = renderContext.run([], async () => {\n try {\n for await (const chunk of renderValueChunks(value, state)) {\n queue.push(chunk);\n wake();\n }\n } catch (error) {\n producerError = error;\n } finally {\n producerDone = true;\n wake();\n }\n });\n\n while (true) {\n while (queue.length === 0) {\n if (producerDone) break;\n await new Promise<void>((resolve) => waiters.push(resolve));\n }\n if (queue.length === 0) break;\n const chunk = queue.shift()!;\n if (chunk) yield chunk;\n }\n if (producerError) {\n yield { type: \"error\", value: producerError instanceof Error ? producerError.message : String(producerError), index: -1 };\n throw producerError;\n }\n yield { type: \"done\", value: \"\", index: -1 };\n await task;\n },\n };\n}\n\nexport async function renderToString(value: unknown, options: ServerRenderOptions = {}): Promise<string> {\n const state: RenderState = {\n markers: options.markers === \"hydration\",\n signal: options.signal,\n context: options.context,\n onError: options.onError,\n };\n let out = \"\";\n await Promise.resolve(\n renderContext.run([], async () => {\n for await (const chunk of renderValueChunks(value, state)) {\n out += chunk.value;\n }\n }),\n );\n return out;\n}\n\nexport function renderToChunks(\n value: unknown,\n options: ServerRenderOptions = {},\n): AsyncIterable<RenderChunk> {\n const state: RenderState = {\n markers: options.markers === \"hydration\",\n signal: options.signal,\n context: options.context,\n onError: options.onError,\n };\n return streamChunks(value, state);\n}\n\nasync function* renderValueChunks(value: unknown, state: RenderState): AsyncGenerator<RenderChunk> {\n checkAbort(state);\n if (value instanceof Promise) {\n yield* renderValueChunks(await value, state);\n return;\n }\n if (value === null || value === undefined || value === false || value === true) return;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"bigint\") {\n yield { type: \"markup\", value: escapeText(String(value)), index: -1 };\n return;\n }\n if (Array.isArray(value)) {\n const resolved = await Promise.all(value.map((item) => resolveBindingValue(item)));\n checkAbort(state);\n for (const item of resolved) {\n if (state.markers) yield { type: \"markup\", value: \"<!--elur-ai-->\", index: -1 };\n yield* renderValueChunks(item, state);\n if (state.markers) yield { type: \"markup\", value: \"<!--elur-aiend-->\", index: -1 };\n }\n return;\n }\n if ((typeof value === \"object\" || typeof value === \"function\") && value !== null) {\n const protocol = (value as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] as\n | { renderServer?: (context: ServerRenderProtocolContext) => string | Promise<string> }\n | undefined;\n if (protocol?.renderServer) {\n const output = await protocol.renderServer({\n markers: state.markers,\n signal: state.signal,\n context: state.context,\n render: (nested, options) => renderValue(nested, {\n ...state,\n markers: options?.markers ?? state.markers,\n }),\n });\n checkAbort(state);\n yield { type: \"markup\", value: output, index: -1 };\n return;\n }\n }\n if (isElurComponent(value)) {\n yield* renderComponentChunks(value, state);\n return;\n }\n if (isKeyed(value)) {\n if (!state.markers) {\n const rendered = await Promise.all(\n value.items.map((item, index) => renderValue(value.renderFn(item, index), state)),\n );\n yield { type: \"markup\", value: rendered.join(\"\"), index: -1 };\n return;\n }\n const seen = new Set<string>();\n for (let index = 0; index < value.items.length; index++) {\n const item = value.items[index];\n const key = normalizeRepeatKey(value.keyFn(item, index), index);\n const serialized = serializeRepeatKey(key);\n if (seen.has(serialized)) {\n console.warn(\n `[elur] repeat(): duplicate key \"${key}\" during server render. ` +\n \"Keys must be unique; entries after the first will leak during hydration.\",\n );\n }\n seen.add(serialized);\n yield { type: \"markup\", value: `<!--elur-ki:${serialized}-->`, index: -1 };\n yield* renderValueChunks(value.renderFn(item, index), state);\n yield { type: \"markup\", value: \"<!--elur-ke-->\", index: -1 };\n }\n return;\n }\n if (isTemplate(value)) {\n const descriptor = value[ELUR_TEMPLATE_DESCRIPTOR];\n if (!descriptor) throw new TypeError(\"[elur] Template does not support server rendering\");\n yield* renderDescriptorChunks(descriptor, state);\n return;\n }\n yield { type: \"markup\", value: escapeText(String(value)), index: -1 };\n}\n\nasync function* renderComponentChunks(component: ElurComponent, state: RenderState): AsyncGenerator<RenderChunk> {\n _pushComponentContext();\n const info: RenderErrorInfo = {\n index: -1,\n context: \"component\",\n cause: undefined,\n component: component._debugName,\n };\n try {\n try {\n component.onInit?.();\n component.onServerRender?.();\n } catch (error) {\n if (component.onError) component.onError(error);\n else throw error;\n }\n try {\n yield* renderValueChunks(component.render(), state);\n } catch (error) {\n if (component.onError) {\n component.onError(error);\n return;\n }\n throw error;\n }\n } catch (error) {\n state.onError?.(error, { ...info, cause: error });\n throw error;\n } finally {\n _popComponentContext();\n }\n}\n\nasync function* renderDescriptorChunks(descriptor: TemplateDescriptor, state: RenderState): AsyncGenerator<RenderChunk> {\n const skipLeading = new Uint8Array(descriptor.strings.length);\n\n for (let index = 0; index < descriptor.strings.length; index++) {\n if (state.signal?.aborted) throw state.signal.reason ?? new DOMException(\"Render aborted\", \"AbortError\");\n let staticPart = descriptor.strings[index];\n if (skipLeading[index] === 1 && (staticPart[0] === '\"' || staticPart[0] === \"'\")) {\n staticPart = staticPart.slice(1);\n }\n if (index >= descriptor.contexts.length) {\n yield { type: \"markup\", value: staticPart, index };\n continue;\n }\n\n const context = descriptor.contexts[index];\n const value = descriptor.values[index];\n if (context.type === \"node\") {\n yield { type: \"markup\", value: staticPart, index };\n if (state.markers) yield { type: \"boundary-start\", value: `<!--elur-${index}-->`, index };\n try {\n const resolved = await resolveBindingValue(value);\n checkAbort(state);\n yield* renderValueChunks(resolved, state);\n } catch (error) {\n state.onError?.(error, { index, context: \"node\", cause: error });\n throw error;\n }\n if (state.markers) yield { type: \"boundary-end\", value: `<!--elur-end-${index}-->`, index };\n continue;\n }\n\n const cut = bindingCut(context);\n const prefix = staticPart.slice(0, -cut);\n if (context.hadOpenQuote) skipLeading[index + 1] = 1;\n if (context.type === \"event\") {\n if (state.markers) {\n const separator = /\\s$/.test(prefix) ? \"\" : \" \";\n yield { type: \"markup\", value: `${prefix}${separator}data-elur-e-${index}=\"${escapeAttribute(context.eventName)}\"`, index };\n } else {\n yield { type: \"markup\", value: prefix.replace(/\\s+$/, \"\"), index };\n }\n continue;\n }\n\n yield { type: \"markup\", value: prefix, index };\n const resolved = await resolveBindingValue(value);\n checkAbort(state);\n if (context.attrName !== \"ref\" && resolved !== null && resolved !== undefined && resolved !== false) {\n const serialized = context.url ? sanitizeUrl(String(resolved)) : String(resolved);\n const separator = /\\s$/.test(prefix) ? \"\" : \" \";\n yield { type: \"markup\", value: `${separator}${context.attrName}=\"${escapeAttribute(serialized)}\"`, index };\n }\n if (state.markers) yield { type: \"markup\", value: ` data-elur-a-${index}=\"${escapeAttribute(context.attrName)}\"`, index };\n }\n}\n\nasync function renderValue(value: unknown, state: RenderState): Promise<string> {\n let out = \"\";\n for await (const chunk of renderValueChunks(value, state)) {\n out += chunk.value;\n }\n return out;\n}\n\nfunction checkAbort(state: RenderState): void {\n if (state.signal?.aborted) throw state.signal.reason ?? new DOMException(\"Render aborted\", \"AbortError\");\n}\n\nasync function resolveBindingValue(value: unknown): Promise<unknown> {\n const resolved = typeof value === \"function\" ? (value as () => unknown)() : value;\n return resolved instanceof Promise ? await resolved : resolved;\n}\n\nfunction bindingCut(context: Exclude<TemplateBindingContext, { type: \"node\" }>): number {\n if (context.type === \"event\") {\n const full = context.modifiers.length\n ? `${context.eventName}.${context.modifiers.join(\".\")}`\n : context.eventName;\n return `@${full}=`.length + (context.hadOpenQuote ? 1 : 0);\n }\n return `${context.attrName}=`.length + (context.hadOpenQuote ? 1 : 0);\n}\n\nfunction escapeText(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttribute(value: string): string {\n return escapeText(value).replace(/\"/g, \"&quot;\");\n}"],"mappings":"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"}
1
+ {"version":3,"file":"server.cjs","names":[],"sources":["../../src/elur/server/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { _popComponentContext, _pushComponentContext, _setContextScopeResolver } from \"../context.js\";\nimport { isElurComponent, type ElurComponent } from \"../lifecycle.js\";\nimport {\n isKeyedList,\n isElurTemplate,\n ELUR_RENDER_PROTOCOL,\n ELUR_TEMPLATE_DESCRIPTOR,\n type ServerRenderProtocolContext,\n type SsrEmit,\n type TemplateBindingContext,\n type TemplateDescriptor,\n} from \"../template/types.js\";\nimport { sanitizeUrl } from \"../template/sanitize.js\";\nimport { normalizeRepeatKey, serializeRepeatKey } from \"../template/keyed.js\";\nimport { Signal, untrack } from \"../reactivity.js\";\nimport { isDerivedBinding } from \"../template/types.js\";\n\n// Local guards avoid sharing the same minified import binding name with\n// callback parameters in the same module (esbuild bug with shared chunks).\nconst isTemplate = isElurTemplate;\nconst isKeyed = isKeyedList;\n\nexport interface RenderErrorInfo {\n /** Binding index inside the descriptor (or -1 for root/component errors). */\n index: number;\n /** Binding context where the error occurred. */\n context: \"node\" | \"attribute\" | \"event\" | \"root\" | \"component\";\n /** The original error. */\n cause: unknown;\n /** Debug name of the component when the error happened inside one. */\n component?: string;\n}\n\nexport interface ServerRenderOptions {\n markers?: \"none\" | \"hydration\";\n signal?: AbortSignal;\n context?: unknown;\n onError?: (error: unknown, info: RenderErrorInfo) => void;\n}\n\n/** A fragment of the rendered markup, streamed incrementally by `renderToChunks`. */\nexport interface RenderChunk {\n type: \"markup\" | \"boundary-start\" | \"boundary-end\" | \"error\" | \"done\";\n value: string;\n index: number;\n}\n\ninterface RenderState {\n markers: boolean;\n signal?: AbortSignal;\n context?: unknown;\n onError?: (error: unknown, info: RenderErrorInfo) => void;\n}\n\nconst renderContext = new AsyncLocalStorage<Map<unknown, unknown>[]>();\n_setContextScopeResolver(() => renderContext.getStore());\n\nexport interface ServerRenderScope {\n /** Abort signal that cancels all renders created through this scope. */\n readonly signal: AbortSignal;\n /** Renders a value to a full string, sharing this scope's context isolation. */\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n /** Streams a value as incremental chunks, sharing this scope's context isolation. */\n renderToChunks(value: unknown, options?: { markers?: boolean }): AsyncIterable<RenderChunk>;\n /** Aborts every render running inside this scope. */\n abort(reason?: unknown): void;\n}\n\n/**\n * Creates an explicit server render scope: a per-render isolation unit that\n * keeps component context, markers and abort state private. Concurrent renders\n * created from the same scope never share `provide`/`inject` state.\n */\nexport function createServerRenderScope(options: Omit<ServerRenderOptions, \"signal\"> = {}): ServerRenderScope {\n const controller = new AbortController();\n const state: RenderState = {\n markers: options.markers === \"hydration\",\n context: options.context,\n onError: options.onError,\n };\n const run = <T>(fn: () => Promise<T> | T): Promise<T> => Promise.resolve(renderContext.run([], fn));\n return {\n signal: controller.signal,\n async render(value, opts): Promise<string> {\n const scoped: RenderState = { ...state, markers: opts?.markers ?? state.markers, signal: controller.signal };\n let out = \"\";\n await run(() => {\n return (async () => {\n for await (const chunk of renderValueChunks(value, scoped)) {\n out += chunk.value;\n }\n })();\n });\n return out;\n },\n renderToChunks(value, opts): AsyncIterable<RenderChunk> {\n const scoped: RenderState = { ...state, markers: opts?.markers ?? state.markers, signal: controller.signal };\n return streamChunks(value, scoped);\n },\n abort(reason?: unknown): void {\n controller.abort(reason);\n },\n };\n}\n\n/**\n * Streams chunks produced inside an AsyncLocalStorage scope, preserving\n * per-render context isolation while yielding incrementally.\n */\nfunction streamChunks(value: unknown, state: RenderState): AsyncIterable<RenderChunk> {\n return {\n async *[Symbol.asyncIterator]() {\n const queue: RenderChunk[] = [];\n const waiters: Array<() => void> = [];\n let producerDone = false;\n let producerError: unknown;\n const wake = () => {\n const waiter = waiters.shift();\n waiter?.();\n };\n\n const task = renderContext.run([], async () => {\n try {\n for await (const chunk of renderValueChunks(value, state)) {\n queue.push(chunk);\n wake();\n }\n } catch (error) {\n producerError = error;\n } finally {\n producerDone = true;\n wake();\n }\n });\n\n while (true) {\n while (queue.length === 0) {\n if (producerDone) break;\n await new Promise<void>((resolve) => waiters.push(resolve));\n }\n if (queue.length === 0) break;\n const chunk = queue.shift()!;\n if (chunk) yield chunk;\n }\n if (producerError) {\n yield { type: \"error\", value: producerError instanceof Error ? producerError.message : String(producerError), index: -1 };\n throw producerError;\n }\n yield { type: \"done\", value: \"\", index: -1 };\n await task;\n },\n };\n}\n\nexport async function renderToString(value: unknown, options: ServerRenderOptions = {}): Promise<string> {\n const state: RenderState = {\n markers: options.markers === \"hydration\",\n signal: options.signal,\n context: options.context,\n onError: options.onError,\n };\n let out = \"\";\n await Promise.resolve(\n renderContext.run([], async () => {\n for await (const chunk of renderValueChunks(value, state)) {\n out += chunk.value;\n }\n }),\n );\n return out;\n}\n\nexport function renderToChunks(\n value: unknown,\n options: ServerRenderOptions = {},\n): AsyncIterable<RenderChunk> {\n const state: RenderState = {\n markers: options.markers === \"hydration\",\n signal: options.signal,\n context: options.context,\n onError: options.onError,\n };\n return streamChunks(value, state);\n}\n\nasync function* renderValueChunks(value: unknown, state: RenderState): AsyncGenerator<RenderChunk> {\n checkAbort(state);\n if (value instanceof Promise) {\n yield* renderValueChunks(await value, state);\n return;\n }\n if (value === null || value === undefined || value === false || value === true) return;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"bigint\") {\n yield { type: \"markup\", value: escapeText(String(value)), index: -1 };\n return;\n }\n if (Array.isArray(value)) {\n const resolved = await Promise.all(value.map((item) => resolveBindingValue(item)));\n checkAbort(state);\n for (const item of resolved) {\n if (state.markers) yield { type: \"markup\", value: \"<!--elur-ai-->\", index: -1 };\n yield* renderValueChunks(item, state);\n if (state.markers) yield { type: \"markup\", value: \"<!--elur-aiend-->\", index: -1 };\n }\n return;\n }\n if ((typeof value === \"object\" || typeof value === \"function\") && value !== null) {\n const protocol = (value as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] as\n | { renderServer?: (context: ServerRenderProtocolContext) => string | Promise<string> }\n | undefined;\n if (protocol?.renderServer) {\n const output = await protocol.renderServer({\n markers: state.markers,\n signal: state.signal,\n context: state.context,\n render: (nested, options) => renderValue(nested, {\n ...state,\n markers: options?.markers ?? state.markers,\n }),\n });\n checkAbort(state);\n yield { type: \"markup\", value: output, index: -1 };\n return;\n }\n }\n if (isElurComponent(value)) {\n yield* renderComponentChunks(value, state);\n return;\n }\n if (isKeyed(value)) {\n if (!state.markers) {\n const rendered = await Promise.all(\n value.items.map((item, index) => renderValue(value.renderFn(item, index), state)),\n );\n yield { type: \"markup\", value: rendered.join(\"\"), index: -1 };\n return;\n }\n const seen = new Set<string>();\n for (let index = 0; index < value.items.length; index++) {\n const item = value.items[index];\n const key = normalizeRepeatKey(value.keyFn(item, index), index);\n const serialized = serializeRepeatKey(key);\n if (seen.has(serialized)) {\n console.warn(\n `[elur] repeat(): duplicate key \"${key}\" during server render. ` +\n \"Keys must be unique; entries after the first will leak during hydration.\",\n );\n }\n seen.add(serialized);\n yield { type: \"markup\", value: `<!--elur-ki:${serialized}-->`, index: -1 };\n yield* renderValueChunks(value.renderFn(item, index), state);\n yield { type: \"markup\", value: \"<!--elur-ke-->\", index: -1 };\n }\n return;\n }\n if (isTemplate(value)) {\n const descriptor = value[ELUR_TEMPLATE_DESCRIPTOR];\n if (!descriptor) throw new TypeError(\"[elur] Template does not support server rendering\");\n yield* renderDescriptorChunks(descriptor, state);\n return;\n }\n yield { type: \"markup\", value: escapeText(String(value)), index: -1 };\n}\n\nasync function* renderComponentChunks(component: ElurComponent, state: RenderState): AsyncGenerator<RenderChunk> {\n _pushComponentContext();\n const info: RenderErrorInfo = {\n index: -1,\n context: \"component\",\n cause: undefined,\n component: component._debugName,\n };\n try {\n try {\n component.onInit?.();\n component.onServerRender?.();\n } catch (error) {\n if (component.onError) component.onError(error);\n else throw error;\n }\n try {\n yield* renderValueChunks(component.render(), state);\n } catch (error) {\n if (component.onError) {\n component.onError(error);\n return;\n }\n throw error;\n }\n } catch (error) {\n state.onError?.(error, { ...info, cause: error });\n throw error;\n } finally {\n _popComponentContext();\n }\n}\n\n// C.12 fase 2: emit ops para el renderer SSR especializado (descriptor.ssr).\n// Replican exactamente la semántica del intérprete genérico — los strings\n// llegan pre-cortados desde el codegen (bindingCut/skipLeading en build).\nfunction makeSsrEmit(state: RenderState, compiledHydrate: boolean): SsrEmit {\n return {\n m: (value) => ({ type: \"markup\", value, index: -1 }),\n node: async function* (index, value) {\n if (state.markers) yield { type: \"boundary-start\", value: `<!--elur-${index}-->`, index };\n try {\n const resolved = await resolveBindingValue(value);\n checkAbort(state);\n yield* renderValueChunks(resolved, state);\n } catch (error) {\n state.onError?.(error, { index, context: \"node\", cause: error });\n throw error;\n }\n if (state.markers) yield { type: \"boundary-end\", value: `<!--elur-end-${index}-->`, index };\n },\n attr: async (prefix, index, attrName, url, _executable, value) => {\n const chunks: RenderChunk[] = [{ type: \"markup\", value: prefix, index }];\n const resolved = await resolveBindingValue(value);\n checkAbort(state);\n if (attrName !== \"ref\" && resolved !== null && resolved !== undefined && resolved !== false) {\n const serialized = url ? sanitizeUrl(String(resolved)) : String(resolved);\n const separator = /\\s$/.test(prefix) ? \"\" : \" \";\n chunks.push({ type: \"markup\", value: `${separator}${attrName}=\"${escapeAttribute(serialized)}\"`, index });\n }\n if (state.markers && !compiledHydrate) {\n chunks.push({ type: \"markup\", value: ` data-elur-a-${index}=\"${escapeAttribute(attrName)}\"`, index });\n }\n return chunks;\n },\n event: (index, prefix, eventName) => {\n if (state.markers && !compiledHydrate) {\n const separator = /\\s$/.test(prefix) ? \"\" : \" \";\n return { type: \"markup\", value: `${prefix}${separator}data-elur-e-${index}=\"${escapeAttribute(eventName)}\"`, index };\n }\n return { type: \"markup\", value: prefix.replace(/\\s+$/, \"\"), index };\n },\n };\n}\n\nasync function* renderDescriptorChunks(descriptor: TemplateDescriptor, state: RenderState): AsyncGenerator<RenderChunk> {\n // C.13: templates con hidratación compilada no necesitan `data-elur-*`\n // en el HTML — el cliente localiza los elementos por access paths.\n // Los `<!--elur-N-->` siguen emitiéndose (boundaries dinámicas).\n const compiledHydrate = descriptor.hydrate !== undefined;\n // C.12 fase 2: el artefacto compilado trae su propio renderer SSR —\n // mismo HTML, secuencia especializada en vez del loop intérprete.\n if (descriptor.ssr) {\n yield* descriptor.ssr(makeSsrEmit(state, compiledHydrate), descriptor.values);\n return;\n }\n const skipLeading = new Uint8Array(descriptor.strings.length);\n\n for (let index = 0; index < descriptor.strings.length; index++) {\n if (state.signal?.aborted) throw state.signal.reason ?? new DOMException(\"Render aborted\", \"AbortError\");\n let staticPart = descriptor.strings[index];\n if (skipLeading[index] === 1 && (staticPart[0] === '\"' || staticPart[0] === \"'\")) {\n staticPart = staticPart.slice(1);\n }\n if (index >= descriptor.contexts.length) {\n yield { type: \"markup\", value: staticPart, index };\n continue;\n }\n\n const context = descriptor.contexts[index];\n const value = descriptor.values[index];\n if (context.type === \"node\") {\n yield { type: \"markup\", value: staticPart, index };\n if (state.markers) yield { type: \"boundary-start\", value: `<!--elur-${index}-->`, index };\n try {\n const resolved = await resolveBindingValue(value);\n checkAbort(state);\n yield* renderValueChunks(resolved, state);\n } catch (error) {\n state.onError?.(error, { index, context: \"node\", cause: error });\n throw error;\n }\n if (state.markers) yield { type: \"boundary-end\", value: `<!--elur-end-${index}-->`, index };\n continue;\n }\n\n const cut = bindingCut(context);\n const prefix = staticPart.slice(0, -cut);\n if (context.hadOpenQuote) skipLeading[index + 1] = 1;\n if (context.type === \"event\") {\n if (state.markers && !compiledHydrate) {\n const separator = /\\s$/.test(prefix) ? \"\" : \" \";\n yield { type: \"markup\", value: `${prefix}${separator}data-elur-e-${index}=\"${escapeAttribute(context.eventName)}\"`, index };\n } else {\n yield { type: \"markup\", value: prefix.replace(/\\s+$/, \"\"), index };\n }\n continue;\n }\n\n yield { type: \"markup\", value: prefix, index };\n const resolved = await resolveBindingValue(value);\n checkAbort(state);\n if (context.attrName !== \"ref\" && resolved !== null && resolved !== undefined && resolved !== false) {\n const serialized = context.url ? sanitizeUrl(String(resolved)) : String(resolved);\n const separator = /\\s$/.test(prefix) ? \"\" : \" \";\n yield { type: \"markup\", value: `${separator}${context.attrName}=\"${escapeAttribute(serialized)}\"`, index };\n }\n if (state.markers && !compiledHydrate) yield { type: \"markup\", value: ` data-elur-a-${index}=\"${escapeAttribute(context.attrName)}\"`, index };\n }\n}\n\nasync function renderValue(value: unknown, state: RenderState): Promise<string> {\n let out = \"\";\n for await (const chunk of renderValueChunks(value, state)) {\n out += chunk.value;\n }\n return out;\n}\n\nfunction checkAbort(state: RenderState): void {\n if (state.signal?.aborted) throw state.signal.reason ?? new DOMException(\"Render aborted\", \"AbortError\");\n}\n\nasync function resolveBindingValue(value: unknown): Promise<unknown> {\n // C.6 T1: la señal viaja como valor — SSR la resuelve a su lectura actual.\n if (value instanceof Signal) return value.peek();\n // C.7 T2: el pack derivado se resuelve evaluando el getter untracked —\n // SSR no crea suscripciones y no debe contaminar un consumidor activo.\n if (isDerivedBinding(value)) return untrack(value.get);\n const resolved = typeof value === \"function\" ? (value as () => unknown)() : value;\n return resolved instanceof Promise ? await resolved : resolved;\n}\n\nfunction bindingCut(context: Exclude<TemplateBindingContext, { type: \"node\" }>): number {\n if (context.type === \"event\") {\n const full = context.modifiers.length\n ? `${context.eventName}.${context.modifiers.join(\".\")}`\n : context.eventName;\n return `@${full}=`.length + (context.hadOpenQuote ? 1 : 0);\n }\n return `${context.attrName}=`.length + (context.hadOpenQuote ? 1 : 0);\n}\n\nfunction escapeText(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttribute(value: string): string {\n return escapeText(value).replace(/\"/g, \"&quot;\");\n}"],"mappings":"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"}
@@ -1,18 +1,19 @@
1
- import { ELUR_RENDER_PROTOCOL as e, ELUR_TEMPLATE_DESCRIPTOR as t, isElurTemplate as n, isKeyedList as r } from "./elur/template/types.js";
2
- import { isElurComponent as i } from "./lifecycle.js";
3
- import { _popComponentContext as a, _pushComponentContext as o, _setContextScopeResolver as s } from "./context.js";
4
- import { normalizeRepeatKey as c, serializeRepeatKey as l } from "./elur/template/keyed.js";
5
- import { sanitizeUrl as u } from "./elur/template/sanitize.js";
6
- import { AsyncLocalStorage as d } from "node:async_hooks";
1
+ import { Signal as e, untrack as t } from "./elur/next-2/reactivity.js";
2
+ import { ELUR_RENDER_PROTOCOL as n, ELUR_TEMPLATE_DESCRIPTOR as r, isDerivedBinding as i, isElurTemplate as a, isKeyedList as o } from "./elur/template/types.js";
3
+ import { isElurComponent as s } from "./lifecycle.js";
4
+ import { _popComponentContext as c, _pushComponentContext as l, _setContextScopeResolver as u } from "./context.js";
5
+ import { normalizeRepeatKey as d, serializeRepeatKey as f } from "./elur/template/keyed.js";
6
+ import { sanitizeUrl as p } from "./elur/template/sanitize.js";
7
+ import { AsyncLocalStorage as m } from "node:async_hooks";
7
8
  //#region src/elur/server/index.ts
8
- var f = n, p = r, m = new d();
9
- s(() => m.getStore());
10
- function h(e = {}) {
9
+ var h = a, g = o, _ = new m();
10
+ u(() => _.getStore());
11
+ function v(e = {}) {
11
12
  let t = new AbortController(), n = {
12
13
  markers: e.markers === "hydration",
13
14
  context: e.context,
14
15
  onError: e.onError
15
- }, r = (e) => Promise.resolve(m.run([], e));
16
+ }, r = (e) => Promise.resolve(_.run([], e));
16
17
  return {
17
18
  signal: t.signal,
18
19
  async render(e, i) {
@@ -22,11 +23,11 @@ function h(e = {}) {
22
23
  signal: t.signal
23
24
  }, o = "";
24
25
  return await r(() => (async () => {
25
- for await (let t of y(e, a)) o += t.value;
26
+ for await (let t of S(e, a)) o += t.value;
26
27
  })()), o;
27
28
  },
28
29
  renderToChunks(e, r) {
29
- return g(e, {
30
+ return y(e, {
30
31
  ...n,
31
32
  markers: r?.markers ?? n.markers,
32
33
  signal: t.signal
@@ -37,13 +38,13 @@ function h(e = {}) {
37
38
  }
38
39
  };
39
40
  }
40
- function g(e, t) {
41
+ function y(e, t) {
41
42
  return { async *[Symbol.asyncIterator]() {
42
43
  let n = [], r = [], i = !1, a, o = () => {
43
44
  r.shift()?.();
44
- }, s = m.run([], async () => {
45
+ }, s = _.run([], async () => {
45
46
  try {
46
- for await (let r of y(e, t)) n.push(r), o();
47
+ for await (let r of S(e, t)) n.push(r), o();
47
48
  } catch (e) {
48
49
  a = e;
49
50
  } finally {
@@ -68,66 +69,66 @@ function g(e, t) {
68
69
  }, await s;
69
70
  } };
70
71
  }
71
- async function _(e, t = {}) {
72
+ async function b(e, t = {}) {
72
73
  let n = {
73
74
  markers: t.markers === "hydration",
74
75
  signal: t.signal,
75
76
  context: t.context,
76
77
  onError: t.onError
77
78
  }, r = "";
78
- return await Promise.resolve(m.run([], async () => {
79
- for await (let t of y(e, n)) r += t.value;
79
+ return await Promise.resolve(_.run([], async () => {
80
+ for await (let t of S(e, n)) r += t.value;
80
81
  })), r;
81
82
  }
82
- function v(e, t = {}) {
83
- return g(e, {
83
+ function x(e, t = {}) {
84
+ return y(e, {
84
85
  markers: t.markers === "hydration",
85
86
  signal: t.signal,
86
87
  context: t.context,
87
88
  onError: t.onError
88
89
  });
89
90
  }
90
- async function* y(n, r) {
91
- if (C(r), n instanceof Promise) {
92
- yield* y(await n, r);
91
+ async function* S(e, t) {
92
+ if (D(t), e instanceof Promise) {
93
+ yield* S(await e, t);
93
94
  return;
94
95
  }
95
- if (!(n == null || n === !1 || n === !0)) {
96
- if (typeof n == "string" || typeof n == "number" || typeof n == "bigint") {
96
+ if (!(e == null || e === !1 || e === !0)) {
97
+ if (typeof e == "string" || typeof e == "number" || typeof e == "bigint") {
97
98
  yield {
98
99
  type: "markup",
99
- value: E(String(n)),
100
+ value: A(String(e)),
100
101
  index: -1
101
102
  };
102
103
  return;
103
104
  }
104
- if (Array.isArray(n)) {
105
- let e = await Promise.all(n.map((e) => w(e)));
106
- C(r);
107
- for (let t of e) r.markers && (yield {
105
+ if (Array.isArray(e)) {
106
+ let n = await Promise.all(e.map((e) => O(e)));
107
+ D(t);
108
+ for (let e of n) t.markers && (yield {
108
109
  type: "markup",
109
110
  value: "<!--elur-ai-->",
110
111
  index: -1
111
- }), yield* y(t, r), r.markers && (yield {
112
+ }), yield* S(e, t), t.markers && (yield {
112
113
  type: "markup",
113
114
  value: "<!--elur-aiend-->",
114
115
  index: -1
115
116
  });
116
117
  return;
117
118
  }
118
- if ((typeof n == "object" || typeof n == "function") && n !== null) {
119
- let t = n[e];
120
- if (t?.renderServer) {
121
- let e = await t.renderServer({
122
- markers: r.markers,
123
- signal: r.signal,
124
- context: r.context,
125
- render: (e, t) => S(e, {
126
- ...r,
127
- markers: t?.markers ?? r.markers
119
+ if ((typeof e == "object" || typeof e == "function") && e !== null) {
120
+ let r = e[n];
121
+ if (r?.renderServer) {
122
+ let e = await r.renderServer({
123
+ markers: t.markers,
124
+ signal: t.signal,
125
+ context: t.context,
126
+ render: (e, n) => E(e, {
127
+ ...t,
128
+ markers: n?.markers ?? t.markers
128
129
  })
129
130
  });
130
- C(r), yield {
131
+ D(t), yield {
131
132
  type: "markup",
132
133
  value: e,
133
134
  index: -1
@@ -135,27 +136,27 @@ async function* y(n, r) {
135
136
  return;
136
137
  }
137
138
  }
138
- if (i(n)) {
139
- yield* b(n, r);
139
+ if (s(e)) {
140
+ yield* C(e, t);
140
141
  return;
141
142
  }
142
- if (p(n)) {
143
- if (!r.markers) {
143
+ if (g(e)) {
144
+ if (!t.markers) {
144
145
  yield {
145
146
  type: "markup",
146
- value: (await Promise.all(n.items.map((e, t) => S(n.renderFn(e, t), r)))).join(""),
147
+ value: (await Promise.all(e.items.map((n, r) => E(e.renderFn(n, r), t)))).join(""),
147
148
  index: -1
148
149
  };
149
150
  return;
150
151
  }
151
- let e = /* @__PURE__ */ new Set();
152
- for (let t = 0; t < n.items.length; t++) {
153
- let i = n.items[t], a = c(n.keyFn(i, t), t), o = l(a);
154
- e.has(o) && console.warn(`[elur] repeat(): duplicate key "${a}" during server render. Keys must be unique; entries after the first will leak during hydration.`), e.add(o), yield {
152
+ let n = /* @__PURE__ */ new Set();
153
+ for (let r = 0; r < e.items.length; r++) {
154
+ let i = e.items[r], a = d(e.keyFn(i, r), r), o = f(a);
155
+ n.has(o) && console.warn(`[elur] repeat(): duplicate key "${a}" during server render. Keys must be unique; entries after the first will leak during hydration.`), n.add(o), yield {
155
156
  type: "markup",
156
157
  value: `<!--elur-ki:${o}-->`,
157
158
  index: -1
158
- }, yield* y(n.renderFn(i, t), r), yield {
159
+ }, yield* S(e.renderFn(i, r), t), yield {
159
160
  type: "markup",
160
161
  value: "<!--elur-ke-->",
161
162
  index: -1
@@ -163,21 +164,21 @@ async function* y(n, r) {
163
164
  }
164
165
  return;
165
166
  }
166
- if (f(n)) {
167
- let e = n[t];
168
- if (!e) throw TypeError("[elur] Template does not support server rendering");
169
- yield* x(e, r);
167
+ if (h(e)) {
168
+ let n = e[r];
169
+ if (!n) throw TypeError("[elur] Template does not support server rendering");
170
+ yield* T(n, t);
170
171
  return;
171
172
  }
172
173
  yield {
173
174
  type: "markup",
174
- value: E(String(n)),
175
+ value: A(String(e)),
175
176
  index: -1
176
177
  };
177
178
  }
178
179
  }
179
- async function* b(e, t) {
180
- o();
180
+ async function* C(e, t) {
181
+ l();
181
182
  let n = {
182
183
  index: -1,
183
184
  context: "component",
@@ -192,7 +193,7 @@ async function* b(e, t) {
192
193
  else throw t;
193
194
  }
194
195
  try {
195
- yield* y(e.render(), t);
196
+ yield* S(e.render(), t);
196
197
  } catch (t) {
197
198
  if (e.onError) {
198
199
  e.onError(t);
@@ -206,106 +207,173 @@ async function* b(e, t) {
206
207
  cause: e
207
208
  }), e;
208
209
  } finally {
209
- a();
210
+ c();
210
211
  }
211
212
  }
212
- async function* x(e, t) {
213
- let n = new Uint8Array(e.strings.length);
214
- for (let r = 0; r < e.strings.length; r++) {
213
+ function w(e, t) {
214
+ return {
215
+ m: (e) => ({
216
+ type: "markup",
217
+ value: e,
218
+ index: -1
219
+ }),
220
+ node: async function* (t, n) {
221
+ e.markers && (yield {
222
+ type: "boundary-start",
223
+ value: `<!--elur-${t}-->`,
224
+ index: t
225
+ });
226
+ try {
227
+ let t = await O(n);
228
+ D(e), yield* S(t, e);
229
+ } catch (n) {
230
+ throw e.onError?.(n, {
231
+ index: t,
232
+ context: "node",
233
+ cause: n
234
+ }), n;
235
+ }
236
+ e.markers && (yield {
237
+ type: "boundary-end",
238
+ value: `<!--elur-end-${t}-->`,
239
+ index: t
240
+ });
241
+ },
242
+ attr: async (n, r, i, a, o, s) => {
243
+ let c = [{
244
+ type: "markup",
245
+ value: n,
246
+ index: r
247
+ }], l = await O(s);
248
+ if (D(e), i !== "ref" && l != null && l !== !1) {
249
+ let e = a ? p(String(l)) : String(l), t = /\s$/.test(n) ? "" : " ";
250
+ c.push({
251
+ type: "markup",
252
+ value: `${t}${i}="${j(e)}"`,
253
+ index: r
254
+ });
255
+ }
256
+ return e.markers && !t && c.push({
257
+ type: "markup",
258
+ value: ` data-elur-a-${r}="${j(i)}"`,
259
+ index: r
260
+ }), c;
261
+ },
262
+ event: (n, r, i) => e.markers && !t ? {
263
+ type: "markup",
264
+ value: `${r}${/\s$/.test(r) ? "" : " "}data-elur-e-${n}="${j(i)}"`,
265
+ index: n
266
+ } : {
267
+ type: "markup",
268
+ value: r.replace(/\s+$/, ""),
269
+ index: n
270
+ }
271
+ };
272
+ }
273
+ async function* T(e, t) {
274
+ let n = e.hydrate !== void 0;
275
+ if (e.ssr) {
276
+ yield* e.ssr(w(t, n), e.values);
277
+ return;
278
+ }
279
+ let r = new Uint8Array(e.strings.length);
280
+ for (let i = 0; i < e.strings.length; i++) {
215
281
  if (t.signal?.aborted) throw t.signal.reason ?? new DOMException("Render aborted", "AbortError");
216
- let i = e.strings[r];
217
- if (n[r] === 1 && (i[0] === "\"" || i[0] === "'") && (i = i.slice(1)), r >= e.contexts.length) {
282
+ let a = e.strings[i];
283
+ if (r[i] === 1 && (a[0] === "\"" || a[0] === "'") && (a = a.slice(1)), i >= e.contexts.length) {
218
284
  yield {
219
285
  type: "markup",
220
- value: i,
221
- index: r
286
+ value: a,
287
+ index: i
222
288
  };
223
289
  continue;
224
290
  }
225
- let a = e.contexts[r], o = e.values[r];
226
- if (a.type === "node") {
291
+ let o = e.contexts[i], s = e.values[i];
292
+ if (o.type === "node") {
227
293
  yield {
228
294
  type: "markup",
229
- value: i,
230
- index: r
295
+ value: a,
296
+ index: i
231
297
  }, t.markers && (yield {
232
298
  type: "boundary-start",
233
- value: `<!--elur-${r}-->`,
234
- index: r
299
+ value: `<!--elur-${i}-->`,
300
+ index: i
235
301
  });
236
302
  try {
237
- let e = await w(o);
238
- C(t), yield* y(e, t);
303
+ let e = await O(s);
304
+ D(t), yield* S(e, t);
239
305
  } catch (e) {
240
306
  throw t.onError?.(e, {
241
- index: r,
307
+ index: i,
242
308
  context: "node",
243
309
  cause: e
244
310
  }), e;
245
311
  }
246
312
  t.markers && (yield {
247
313
  type: "boundary-end",
248
- value: `<!--elur-end-${r}-->`,
249
- index: r
314
+ value: `<!--elur-end-${i}-->`,
315
+ index: i
250
316
  });
251
317
  continue;
252
318
  }
253
- let s = T(a), c = i.slice(0, -s);
254
- if (a.hadOpenQuote && (n[r + 1] = 1), a.type === "event") {
255
- t.markers ? yield {
319
+ let c = k(o), l = a.slice(0, -c);
320
+ if (o.hadOpenQuote && (r[i + 1] = 1), o.type === "event") {
321
+ t.markers && !n ? yield {
256
322
  type: "markup",
257
- value: `${c}${/\s$/.test(c) ? "" : " "}data-elur-e-${r}="${D(a.eventName)}"`,
258
- index: r
323
+ value: `${l}${/\s$/.test(l) ? "" : " "}data-elur-e-${i}="${j(o.eventName)}"`,
324
+ index: i
259
325
  } : yield {
260
326
  type: "markup",
261
- value: c.replace(/\s+$/, ""),
262
- index: r
327
+ value: l.replace(/\s+$/, ""),
328
+ index: i
263
329
  };
264
330
  continue;
265
331
  }
266
332
  yield {
267
333
  type: "markup",
268
- value: c,
269
- index: r
334
+ value: l,
335
+ index: i
270
336
  };
271
- let l = await w(o);
272
- if (C(t), a.attrName !== "ref" && l != null && l !== !1) {
273
- let e = a.url ? u(String(l)) : String(l);
337
+ let u = await O(s);
338
+ if (D(t), o.attrName !== "ref" && u != null && u !== !1) {
339
+ let e = o.url ? p(String(u)) : String(u);
274
340
  yield {
275
341
  type: "markup",
276
- value: `${/\s$/.test(c) ? "" : " "}${a.attrName}="${D(e)}"`,
277
- index: r
342
+ value: `${/\s$/.test(l) ? "" : " "}${o.attrName}="${j(e)}"`,
343
+ index: i
278
344
  };
279
345
  }
280
- t.markers && (yield {
346
+ t.markers && !n && (yield {
281
347
  type: "markup",
282
- value: ` data-elur-a-${r}="${D(a.attrName)}"`,
283
- index: r
348
+ value: ` data-elur-a-${i}="${j(o.attrName)}"`,
349
+ index: i
284
350
  });
285
351
  }
286
352
  }
287
- async function S(e, t) {
353
+ async function E(e, t) {
288
354
  let n = "";
289
- for await (let r of y(e, t)) n += r.value;
355
+ for await (let r of S(e, t)) n += r.value;
290
356
  return n;
291
357
  }
292
- function C(e) {
358
+ function D(e) {
293
359
  if (e.signal?.aborted) throw e.signal.reason ?? new DOMException("Render aborted", "AbortError");
294
360
  }
295
- async function w(e) {
296
- let t = typeof e == "function" ? e() : e;
297
- return t instanceof Promise ? await t : t;
361
+ async function O(n) {
362
+ if (n instanceof e) return n.peek();
363
+ if (i(n)) return t(n.get);
364
+ let r = typeof n == "function" ? n() : n;
365
+ return r instanceof Promise ? await r : r;
298
366
  }
299
- function T(e) {
367
+ function k(e) {
300
368
  return e.type === "event" ? `@${e.modifiers.length ? `${e.eventName}.${e.modifiers.join(".")}` : e.eventName}=`.length + +!!e.hadOpenQuote : `${e.attrName}=`.length + +!!e.hadOpenQuote;
301
369
  }
302
- function E(e) {
370
+ function A(e) {
303
371
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
304
372
  }
305
- function D(e) {
306
- return E(e).replace(/"/g, "&quot;");
373
+ function j(e) {
374
+ return A(e).replace(/"/g, "&quot;");
307
375
  }
308
376
  //#endregion
309
- export { h as createServerRenderScope, v as renderToChunks, _ as renderToString };
377
+ export { v as createServerRenderScope, x as renderToChunks, b as renderToString };
310
378
 
311
379
  //# sourceMappingURL=server.js.map