@sigx/server-renderer 0.1.6 → 0.1.7

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 (60) hide show
  1. package/dist/builtin-ssr-directives.d.ts +8 -0
  2. package/dist/builtin-ssr-directives.d.ts.map +1 -0
  3. package/dist/client/hydrate-component.d.ts +32 -0
  4. package/dist/client/hydrate-component.d.ts.map +1 -0
  5. package/dist/client/hydrate-context.d.ts +54 -0
  6. package/dist/client/hydrate-context.d.ts.map +1 -0
  7. package/dist/client/hydrate-core.d.ts +33 -0
  8. package/dist/client/hydrate-core.d.ts.map +1 -0
  9. package/dist/client/index.d.ts +8 -4
  10. package/dist/client/index.d.ts.map +1 -1
  11. package/dist/client/index.js +2 -2
  12. package/dist/client-directives.d.ts +3 -36
  13. package/dist/client-directives.d.ts.map +1 -1
  14. package/dist/client-ggDL-Wx2.js +309 -0
  15. package/dist/client-ggDL-Wx2.js.map +1 -0
  16. package/dist/directive-ssr-types.d.ts +23 -0
  17. package/dist/directive-ssr-types.d.ts.map +1 -0
  18. package/dist/head.d.ts +97 -0
  19. package/dist/head.d.ts.map +1 -0
  20. package/dist/index.d.ts +22 -18
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +7 -3
  23. package/dist/index.js.map +1 -0
  24. package/dist/plugin.d.ts +124 -0
  25. package/dist/plugin.d.ts.map +1 -0
  26. package/dist/server/context.d.ts +52 -59
  27. package/dist/server/context.d.ts.map +1 -1
  28. package/dist/server/index.d.ts +9 -4
  29. package/dist/server/index.d.ts.map +1 -1
  30. package/dist/server/index.js +3 -2
  31. package/dist/server/render-api.d.ts +64 -0
  32. package/dist/server/render-api.d.ts.map +1 -0
  33. package/dist/server/render-core.d.ts +46 -0
  34. package/dist/server/render-core.d.ts.map +1 -0
  35. package/dist/server/streaming.d.ts +24 -0
  36. package/dist/server/streaming.d.ts.map +1 -0
  37. package/dist/server/types.d.ts +40 -0
  38. package/dist/server/types.d.ts.map +1 -0
  39. package/dist/server-UBcHtkm-.js +829 -0
  40. package/dist/server-UBcHtkm-.js.map +1 -0
  41. package/dist/ssr.d.ts +38 -0
  42. package/dist/ssr.d.ts.map +1 -0
  43. package/dist/types-B4Rf1Xot.js +6 -0
  44. package/dist/types-B4Rf1Xot.js.map +1 -0
  45. package/package.json +5 -10
  46. package/dist/client/hydrate.d.ts +0 -24
  47. package/dist/client/hydrate.d.ts.map +0 -1
  48. package/dist/client/registry.d.ts +0 -54
  49. package/dist/client/registry.d.ts.map +0 -1
  50. package/dist/client/types.d.ts +0 -23
  51. package/dist/client/types.d.ts.map +0 -1
  52. package/dist/client-DiLwBAD-.js +0 -541
  53. package/dist/client-DiLwBAD-.js.map +0 -1
  54. package/dist/server/stream.d.ts +0 -62
  55. package/dist/server/stream.d.ts.map +0 -1
  56. package/dist/server-BCOJt2Bi.js +0 -459
  57. package/dist/server-BCOJt2Bi.js.map +0 -1
  58. package/dist/shared/utils.d.ts +0 -9
  59. package/dist/shared/utils.d.ts.map +0 -1
  60. package/src/jsx.d.ts +0 -62
@@ -0,0 +1,829 @@
1
+ import { resolveBuiltInDirective, show } from "@sigx/runtime-dom";
2
+ import { Fragment, Text, createPropsAccessor, getCurrentInstance, isComponent, isDirective, provideAppContext, setCurrentInstance, signal } from "sigx";
3
+ var _initialized = false;
4
+ function initShowForSSR() {
5
+ show.getSSRProps = ({ value }) => {
6
+ if (!value) return { style: { display: "none" } };
7
+ };
8
+ }
9
+ function initDirectivesForSSR() {
10
+ if (_initialized) return;
11
+ _initialized = true;
12
+ initShowForSSR();
13
+ }
14
+ function createSSRContext(options = {}) {
15
+ let componentId = 0;
16
+ const componentStack = [];
17
+ const head = [];
18
+ const pluginData = /* @__PURE__ */ new Map();
19
+ return {
20
+ _componentId: componentId,
21
+ _componentStack: componentStack,
22
+ _head: head,
23
+ _pluginData: pluginData,
24
+ _onComponentError: options.onComponentError,
25
+ _streaming: false,
26
+ _pendingAsync: [],
27
+ nextId() {
28
+ return ++componentId;
29
+ },
30
+ pushComponent(id) {
31
+ componentStack.push(id);
32
+ },
33
+ popComponent() {
34
+ return componentStack.pop();
35
+ },
36
+ addHead(html) {
37
+ head.push(html);
38
+ },
39
+ getHead() {
40
+ return head.join("\n");
41
+ },
42
+ getPluginData(pluginName) {
43
+ return pluginData.get(pluginName);
44
+ },
45
+ setPluginData(pluginName, data) {
46
+ pluginData.set(pluginName, data);
47
+ }
48
+ };
49
+ }
50
+ var ESCAPE = {
51
+ "&": "&",
52
+ "<": "&lt;",
53
+ ">": "&gt;",
54
+ "\"": "&quot;",
55
+ "'": "&#39;"
56
+ };
57
+ function escapeHtml$1(s) {
58
+ return s.replace(/[&<>"']/g, (c) => ESCAPE[c]);
59
+ }
60
+ var kebabCache = {};
61
+ var VOID_ELEMENTS = new Set([
62
+ "area",
63
+ "base",
64
+ "br",
65
+ "col",
66
+ "embed",
67
+ "hr",
68
+ "img",
69
+ "input",
70
+ "link",
71
+ "meta",
72
+ "param",
73
+ "source",
74
+ "track",
75
+ "wbr"
76
+ ]);
77
+ function camelToKebab(str) {
78
+ if (str.startsWith("--")) return str;
79
+ return kebabCache[str] ||= str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
80
+ }
81
+ var listDelimiterRE = /;(?![^(]*\))/g;
82
+ var propertyDelimiterRE = /:([^]+)/;
83
+ var styleCommentRE = /\/\*[^]*?\*\//g;
84
+ function parseStringStyle(cssText) {
85
+ const ret = {};
86
+ cssText.replace(styleCommentRE, "").split(listDelimiterRE).forEach((item) => {
87
+ if (item) {
88
+ const tmp = item.split(propertyDelimiterRE);
89
+ if (tmp.length > 1) ret[tmp[0].trim()] = tmp[1].trim();
90
+ }
91
+ });
92
+ return ret;
93
+ }
94
+ function stringifyStyle(style) {
95
+ let ret = "";
96
+ for (const key in style) {
97
+ const value = style[key];
98
+ if (value != null && value !== "") ret += `${camelToKebab(key)}:${value};`;
99
+ }
100
+ return ret;
101
+ }
102
+ function isTextContent(element) {
103
+ if (element == null || element === false || element === true) return false;
104
+ if (typeof element === "string" || typeof element === "number") return true;
105
+ return element.type === Text;
106
+ }
107
+ function mergeSSRStyles(elementStyle, directiveStyle) {
108
+ if (!elementStyle) return directiveStyle;
109
+ if (!directiveStyle) return elementStyle;
110
+ const a = typeof elementStyle === "string" ? parseStringStyle(elementStyle) : typeof elementStyle === "object" ? elementStyle : {};
111
+ const b = typeof directiveStyle === "string" ? parseStringStyle(directiveStyle) : typeof directiveStyle === "object" ? directiveStyle : {};
112
+ return {
113
+ ...a,
114
+ ...b
115
+ };
116
+ }
117
+ async function* renderToChunks(element, ctx, parentCtx = null, appContext = null) {
118
+ if (element == null || element === false || element === true) return;
119
+ if (typeof element === "string" || typeof element === "number") {
120
+ yield escapeHtml$1(String(element));
121
+ return;
122
+ }
123
+ const vnode = element;
124
+ if (vnode.type === Text) {
125
+ yield escapeHtml$1(String(vnode.text));
126
+ return;
127
+ }
128
+ if (vnode.type === Fragment) {
129
+ for (const child of vnode.children) yield* renderToChunks(child, ctx, parentCtx, appContext);
130
+ return;
131
+ }
132
+ if (isComponent(vnode.type)) {
133
+ const setup = vnode.type.__setup;
134
+ const componentName = vnode.type.__name || "Anonymous";
135
+ const { children, slots: slotsFromProps, $models: modelsData, ...propsData } = vnode.props || {};
136
+ const id = ctx.nextId();
137
+ ctx.pushComponent(id);
138
+ const slots = {
139
+ default: () => children ? Array.isArray(children) ? children : [children] : [],
140
+ ...slotsFromProps
141
+ };
142
+ const ssrLoads = [];
143
+ let componentCtx = {
144
+ el: null,
145
+ signal,
146
+ props: createPropsAccessor(propsData),
147
+ slots,
148
+ emit: () => {},
149
+ parent: parentCtx,
150
+ onMounted: () => {},
151
+ onUnmounted: () => {},
152
+ onCreated: () => {},
153
+ onUpdated: () => {},
154
+ expose: () => {},
155
+ renderFn: null,
156
+ update: () => {},
157
+ ssr: {
158
+ load(fn) {
159
+ ssrLoads.push(fn());
160
+ },
161
+ isServer: true,
162
+ isHydrating: false
163
+ },
164
+ _ssrLoads: ssrLoads
165
+ };
166
+ if (ctx._plugins) for (const plugin of ctx._plugins) {
167
+ const transformed = plugin.server?.transformComponentContext?.(ctx, vnode, componentCtx);
168
+ if (transformed) componentCtx = transformed;
169
+ }
170
+ if (!parentCtx && appContext) provideAppContext(componentCtx, appContext);
171
+ const prev = setCurrentInstance(componentCtx);
172
+ try {
173
+ let renderFn = setup(componentCtx);
174
+ if (renderFn && typeof renderFn.then === "function") renderFn = await renderFn;
175
+ if (ssrLoads.length > 0) {
176
+ let asyncMode = ctx._streaming ? "stream" : "block";
177
+ let asyncPlaceholder;
178
+ let pluginHandled = false;
179
+ if (ctx._plugins) for (const plugin of ctx._plugins) {
180
+ const result = plugin.server?.handleAsyncSetup?.(id, ssrLoads, renderFn, ctx);
181
+ if (result) {
182
+ asyncMode = result.mode;
183
+ asyncPlaceholder = result.placeholder;
184
+ pluginHandled = true;
185
+ break;
186
+ }
187
+ }
188
+ if (asyncMode === "stream") {
189
+ yield asyncPlaceholder || `<div data-async-placeholder="${id}" style="display:contents;">`;
190
+ if (renderFn) {
191
+ const result = renderFn();
192
+ if (result) if (Array.isArray(result)) for (const item of result) yield* renderToChunks(item, ctx, componentCtx, appContext);
193
+ else yield* renderToChunks(result, ctx, componentCtx, appContext);
194
+ }
195
+ yield `</div>`;
196
+ if (!pluginHandled) {
197
+ const capturedRenderFn = renderFn;
198
+ const capturedCtx = ctx;
199
+ const capturedAppContext = appContext;
200
+ const deferredRender = (async () => {
201
+ await Promise.all(ssrLoads);
202
+ let html = "";
203
+ if (capturedRenderFn) {
204
+ const result = capturedRenderFn();
205
+ if (result) html = await renderVNodeToString(result, capturedCtx, capturedAppContext);
206
+ }
207
+ return html;
208
+ })();
209
+ ctx._pendingAsync.push({
210
+ id,
211
+ promise: deferredRender
212
+ });
213
+ }
214
+ } else if (asyncMode === "skip") {} else {
215
+ await Promise.all(ssrLoads);
216
+ if (renderFn) {
217
+ const result = renderFn();
218
+ if (result) if (Array.isArray(result)) for (const item of result) yield* renderToChunks(item, ctx, componentCtx, appContext);
219
+ else yield* renderToChunks(result, ctx, componentCtx, appContext);
220
+ }
221
+ }
222
+ } else if (renderFn) {
223
+ const result = renderFn();
224
+ if (result) if (Array.isArray(result)) for (const item of result) yield* renderToChunks(item, ctx, componentCtx, appContext);
225
+ else yield* renderToChunks(result, ctx, componentCtx, appContext);
226
+ }
227
+ } catch (e) {
228
+ const error = e instanceof Error ? e : new Error(String(e));
229
+ let fallbackHtml = null;
230
+ if (ctx._onComponentError) fallbackHtml = ctx._onComponentError(error, componentName, id);
231
+ if (fallbackHtml === null || fallbackHtml === void 0) fallbackHtml = `<!--ssr-error:${id}-->`;
232
+ if (fallbackHtml) yield fallbackHtml;
233
+ if (process.env.NODE_ENV !== "production") console.error(`Error rendering component ${componentName}:`, e);
234
+ } finally {
235
+ setCurrentInstance(prev || null);
236
+ }
237
+ if (ctx._plugins) for (const plugin of ctx._plugins) {
238
+ const transformed = plugin.server?.afterRenderComponent?.(id, vnode, "", ctx);
239
+ if (transformed) yield transformed;
240
+ }
241
+ yield `<!--$c:${id}-->`;
242
+ ctx.popComponent();
243
+ return;
244
+ }
245
+ if (typeof vnode.type === "string") {
246
+ const tagName = vnode.type;
247
+ let props = "";
248
+ let directiveSSRProps = null;
249
+ if (vnode.props) {
250
+ for (const key in vnode.props) if (key.startsWith("use:")) {
251
+ const propValue = vnode.props[key];
252
+ let def;
253
+ let value;
254
+ if (isDirective(propValue)) {
255
+ def = propValue;
256
+ value = void 0;
257
+ } else if (Array.isArray(propValue) && propValue.length >= 1 && isDirective(propValue[0])) {
258
+ def = propValue[0];
259
+ value = propValue[1];
260
+ } else {
261
+ const builtIn = resolveBuiltInDirective(key.slice(4));
262
+ if (builtIn) {
263
+ def = builtIn;
264
+ value = propValue;
265
+ } else {
266
+ const custom = appContext?.directives.get(key.slice(4));
267
+ if (custom) {
268
+ def = custom;
269
+ value = propValue;
270
+ }
271
+ }
272
+ }
273
+ if (def?.getSSRProps) {
274
+ const ssrProps = def.getSSRProps({ value });
275
+ if (ssrProps) {
276
+ if (!directiveSSRProps) directiveSSRProps = {};
277
+ for (const k in ssrProps) if (k === "style" && directiveSSRProps.style) directiveSSRProps.style = {
278
+ ...directiveSSRProps.style,
279
+ ...ssrProps.style
280
+ };
281
+ else if (k === "class" && directiveSSRProps.class) directiveSSRProps.class = directiveSSRProps.class + " " + ssrProps.class;
282
+ else directiveSSRProps[k] = ssrProps[k];
283
+ }
284
+ }
285
+ }
286
+ }
287
+ const allProps = directiveSSRProps ? {
288
+ ...vnode.props,
289
+ ...directiveSSRProps,
290
+ style: mergeSSRStyles(vnode.props?.style, directiveSSRProps?.style)
291
+ } : vnode.props;
292
+ for (const key in allProps) {
293
+ const value = allProps[key];
294
+ if (key === "children" || key === "key" || key === "ref") continue;
295
+ if (key.startsWith("client:")) continue;
296
+ if (key.startsWith("use:")) continue;
297
+ if (key === "style") {
298
+ const styleString = typeof value === "object" ? stringifyStyle(value) : String(value);
299
+ props += ` style="${escapeHtml$1(styleString)}"`;
300
+ } else if (key === "className") props += ` class="${escapeHtml$1(String(value))}"`;
301
+ else if (key.startsWith("on")) {} else if (value === true) props += ` ${key}`;
302
+ else if (value !== false && value != null) props += ` ${key}="${escapeHtml$1(String(value))}"`;
303
+ }
304
+ if (VOID_ELEMENTS.has(tagName)) {
305
+ yield `<${tagName}${props}>`;
306
+ return;
307
+ }
308
+ yield `<${tagName}${props}>`;
309
+ let prevWasText = false;
310
+ for (const child of vnode.children) {
311
+ const isText = isTextContent(child);
312
+ if (isText && prevWasText) yield "<!--t-->";
313
+ yield* renderToChunks(child, ctx, parentCtx, appContext);
314
+ prevWasText = isText;
315
+ }
316
+ yield `</${tagName}>`;
317
+ }
318
+ }
319
+ async function renderVNodeToString(element, ctx, appContext = null) {
320
+ let result = "";
321
+ for await (const chunk of renderToChunks(element, ctx, null, appContext)) result += chunk;
322
+ return result;
323
+ }
324
+ function renderToStringSync(element, ctx, parentCtx, appContext, buf) {
325
+ if (element == null || element === false || element === true) return true;
326
+ if (typeof element === "string" || typeof element === "number") {
327
+ buf.push(escapeHtml$1(String(element)));
328
+ return true;
329
+ }
330
+ const vnode = element;
331
+ if (vnode.type === Text) {
332
+ buf.push(escapeHtml$1(String(vnode.text)));
333
+ return true;
334
+ }
335
+ if (vnode.type === Fragment) {
336
+ for (const child of vnode.children) if (!renderToStringSync(child, ctx, parentCtx, appContext, buf)) return false;
337
+ return true;
338
+ }
339
+ if (isComponent(vnode.type)) {
340
+ const setup = vnode.type.__setup;
341
+ const componentName = vnode.type.__name || "Anonymous";
342
+ const { children, slots: slotsFromProps, $models: modelsData, ...propsData } = vnode.props || {};
343
+ const id = ctx.nextId();
344
+ ctx.pushComponent(id);
345
+ const slots = {
346
+ default: () => children ? Array.isArray(children) ? children : [children] : [],
347
+ ...slotsFromProps
348
+ };
349
+ const ssrLoads = [];
350
+ let componentCtx = {
351
+ el: null,
352
+ signal,
353
+ props: createPropsAccessor(propsData),
354
+ slots,
355
+ emit: () => {},
356
+ parent: parentCtx,
357
+ onMounted: () => {},
358
+ onUnmounted: () => {},
359
+ onCreated: () => {},
360
+ onUpdated: () => {},
361
+ expose: () => {},
362
+ renderFn: null,
363
+ update: () => {},
364
+ ssr: {
365
+ load(fn) {
366
+ ssrLoads.push(fn());
367
+ },
368
+ isServer: true,
369
+ isHydrating: false
370
+ },
371
+ _ssrLoads: ssrLoads
372
+ };
373
+ if (ctx._plugins) for (const plugin of ctx._plugins) {
374
+ const transformed = plugin.server?.transformComponentContext?.(ctx, vnode, componentCtx);
375
+ if (transformed) componentCtx = transformed;
376
+ }
377
+ if (!parentCtx && appContext) provideAppContext(componentCtx, appContext);
378
+ const prev = setCurrentInstance(componentCtx);
379
+ try {
380
+ let renderFn = setup(componentCtx);
381
+ if (renderFn && typeof renderFn.then === "function") {
382
+ for (const p of ssrLoads) p.catch(() => {});
383
+ setCurrentInstance(prev || null);
384
+ ctx.popComponent();
385
+ return false;
386
+ }
387
+ if (ssrLoads.length > 0) {
388
+ for (const p of ssrLoads) p.catch(() => {});
389
+ setCurrentInstance(prev || null);
390
+ ctx.popComponent();
391
+ return false;
392
+ }
393
+ if (renderFn) {
394
+ const result = renderFn();
395
+ if (result) {
396
+ if (Array.isArray(result)) {
397
+ for (const item of result) if (!renderToStringSync(item, ctx, componentCtx, appContext, buf)) {
398
+ setCurrentInstance(prev || null);
399
+ ctx.popComponent();
400
+ return false;
401
+ }
402
+ } else if (!renderToStringSync(result, ctx, componentCtx, appContext, buf)) {
403
+ setCurrentInstance(prev || null);
404
+ ctx.popComponent();
405
+ return false;
406
+ }
407
+ }
408
+ }
409
+ } catch (e) {
410
+ const error = e instanceof Error ? e : new Error(String(e));
411
+ let fallbackHtml = null;
412
+ if (ctx._onComponentError) fallbackHtml = ctx._onComponentError(error, componentName, id);
413
+ if (fallbackHtml === null || fallbackHtml === void 0) fallbackHtml = `<!--ssr-error:${id}-->`;
414
+ if (fallbackHtml) buf.push(fallbackHtml);
415
+ } finally {
416
+ setCurrentInstance(prev || null);
417
+ }
418
+ if (ctx._plugins) for (const plugin of ctx._plugins) {
419
+ const transformed = plugin.server?.afterRenderComponent?.(id, vnode, "", ctx);
420
+ if (transformed) buf.push(transformed);
421
+ }
422
+ buf.push(`<!--$c:${id}-->`);
423
+ ctx.popComponent();
424
+ return true;
425
+ }
426
+ if (typeof vnode.type === "string") {
427
+ const tagName = vnode.type;
428
+ let props = "";
429
+ let directiveSSRProps = null;
430
+ if (vnode.props) {
431
+ for (const key in vnode.props) if (key.startsWith("use:")) {
432
+ const propValue = vnode.props[key];
433
+ let def;
434
+ let value;
435
+ if (isDirective(propValue)) {
436
+ def = propValue;
437
+ value = void 0;
438
+ } else if (Array.isArray(propValue) && propValue.length >= 1 && isDirective(propValue[0])) {
439
+ def = propValue[0];
440
+ value = propValue[1];
441
+ } else {
442
+ const builtIn = resolveBuiltInDirective(key.slice(4));
443
+ if (builtIn) {
444
+ def = builtIn;
445
+ value = propValue;
446
+ } else {
447
+ const custom = appContext?.directives.get(key.slice(4));
448
+ if (custom) {
449
+ def = custom;
450
+ value = propValue;
451
+ }
452
+ }
453
+ }
454
+ if (def?.getSSRProps) {
455
+ const ssrProps = def.getSSRProps({ value });
456
+ if (ssrProps) {
457
+ if (!directiveSSRProps) directiveSSRProps = {};
458
+ for (const k in ssrProps) if (k === "style" && directiveSSRProps.style) directiveSSRProps.style = {
459
+ ...directiveSSRProps.style,
460
+ ...ssrProps.style
461
+ };
462
+ else if (k === "class" && directiveSSRProps.class) directiveSSRProps.class = directiveSSRProps.class + " " + ssrProps.class;
463
+ else directiveSSRProps[k] = ssrProps[k];
464
+ }
465
+ }
466
+ }
467
+ }
468
+ const allProps = directiveSSRProps ? {
469
+ ...vnode.props,
470
+ ...directiveSSRProps,
471
+ style: mergeSSRStyles(vnode.props?.style, directiveSSRProps?.style)
472
+ } : vnode.props;
473
+ for (const key in allProps) {
474
+ const value = allProps[key];
475
+ if (key === "children" || key === "key" || key === "ref") continue;
476
+ if (key.startsWith("client:")) continue;
477
+ if (key.startsWith("use:")) continue;
478
+ if (key === "style") {
479
+ const styleString = typeof value === "object" ? stringifyStyle(value) : String(value);
480
+ props += ` style="${escapeHtml$1(styleString)}"`;
481
+ } else if (key === "className") props += ` class="${escapeHtml$1(String(value))}"`;
482
+ else if (key.startsWith("on")) {} else if (value === true) props += ` ${key}`;
483
+ else if (value !== false && value != null) props += ` ${key}="${escapeHtml$1(String(value))}"`;
484
+ }
485
+ if (VOID_ELEMENTS.has(tagName)) {
486
+ buf.push(`<${tagName}${props}>`);
487
+ return true;
488
+ }
489
+ buf.push(`<${tagName}${props}>`);
490
+ let prevWasText = false;
491
+ for (const child of vnode.children) {
492
+ const isText = isTextContent(child);
493
+ if (isText && prevWasText) buf.push("<!--t-->");
494
+ if (!renderToStringSync(child, ctx, parentCtx, appContext, buf)) return false;
495
+ prevWasText = isText;
496
+ }
497
+ buf.push(`</${tagName}>`);
498
+ return true;
499
+ }
500
+ return true;
501
+ }
502
+ function escapeJsonForScript(json) {
503
+ return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
504
+ }
505
+ function generateStreamingScript() {
506
+ return `
507
+ <script>
508
+ window.$SIGX_REPLACE = function(id, html) {
509
+ var placeholder = document.querySelector('[data-async-placeholder="' + id + '"]');
510
+ if (placeholder) {
511
+ var template = document.createElement('template');
512
+ template.innerHTML = html;
513
+ placeholder.innerHTML = '';
514
+ while (template.content.firstChild) {
515
+ placeholder.appendChild(template.content.firstChild);
516
+ }
517
+ placeholder.dispatchEvent(new CustomEvent('sigx:async-ready', { bubbles: true, detail: { id: id } }));
518
+ }
519
+ };
520
+ <\/script>`;
521
+ }
522
+ function generateReplacementScript(id, html, extraScript) {
523
+ let script = `<script>$SIGX_REPLACE(${id}, ${escapeJsonForScript(JSON.stringify(html))});`;
524
+ if (extraScript) script += extraScript;
525
+ script += `<\/script>`;
526
+ return script;
527
+ }
528
+ var _ssrHeadConfigs = [];
529
+ var _isSSR = false;
530
+ function enableSSRHead() {
531
+ _isSSR = true;
532
+ _ssrHeadConfigs = [];
533
+ }
534
+ function collectSSRHead() {
535
+ _isSSR = false;
536
+ const configs = _ssrHeadConfigs;
537
+ _ssrHeadConfigs = [];
538
+ return configs;
539
+ }
540
+ function renderHeadToString(configs) {
541
+ const parts = [];
542
+ const seenMeta = /* @__PURE__ */ new Map();
543
+ let finalTitle;
544
+ let titleTemplate;
545
+ for (const config of configs) {
546
+ if (config.titleTemplate) titleTemplate = config.titleTemplate;
547
+ if (config.title) finalTitle = config.title;
548
+ if (config.meta) for (const meta of config.meta) {
549
+ const key = meta.name ? `name:${meta.name}` : meta.property ? `property:${meta.property}` : meta["http-equiv"] ? `http-equiv:${meta["http-equiv"]}` : meta.charset ? "charset" : null;
550
+ const tag = `<meta ${Object.entries(meta).filter(([, v]) => v !== void 0).map(([k, v]) => `${escapeAttr(k)}="${escapeAttr(String(v))}"`).join(" ")}>`;
551
+ if (key) seenMeta.set(key, tag);
552
+ else parts.push(tag);
553
+ }
554
+ if (config.link) for (const link of config.link) {
555
+ const attrs = Object.entries(link).filter(([, v]) => v !== void 0).map(([k, v]) => `${escapeAttr(k)}="${escapeAttr(String(v))}"`).join(" ");
556
+ parts.push(`<link ${attrs}>`);
557
+ }
558
+ if (config.script) for (const script of config.script) {
559
+ const { innerHTML, ...rest } = script;
560
+ const attrs = Object.entries(rest).filter(([, v]) => v !== void 0 && v !== false).map(([k, v]) => v === true ? escapeAttr(k) : `${escapeAttr(k)}="${escapeAttr(String(v))}"`).join(" ");
561
+ if (innerHTML) parts.push(`<script ${attrs}>${innerHTML}<\/script>`);
562
+ else parts.push(`<script ${attrs}><\/script>`);
563
+ }
564
+ }
565
+ const result = [];
566
+ if (finalTitle) {
567
+ const title = titleTemplate ? titleTemplate.replace("%s", finalTitle) : finalTitle;
568
+ result.push(`<title>${escapeHtml(title)}</title>`);
569
+ }
570
+ for (const tag of seenMeta.values()) result.push(tag);
571
+ result.push(...parts);
572
+ return result.join("\n");
573
+ }
574
+ var _headToken = 0;
575
+ function applyHeadClient(config) {
576
+ const managed = [];
577
+ const token = ++_headToken;
578
+ if (config.title) {
579
+ const title = config.titleTemplate ? config.titleTemplate.replace("%s", config.title) : config.title;
580
+ document.title = title;
581
+ }
582
+ if (config.meta) for (const meta of config.meta) {
583
+ const selector = meta.name ? `meta[name="${meta.name}"]` : meta.property ? `meta[property="${meta.property}"]` : meta["http-equiv"] ? `meta[http-equiv="${meta["http-equiv"]}"]` : null;
584
+ if (selector) {
585
+ const existing = document.querySelector(selector);
586
+ if (existing) existing.remove();
587
+ }
588
+ const el = document.createElement("meta");
589
+ for (const [k, v] of Object.entries(meta)) if (v !== void 0) el.setAttribute(k, v);
590
+ el.setAttribute("data-sigx-head", String(token));
591
+ document.head.appendChild(el);
592
+ managed.push(el);
593
+ }
594
+ if (config.link) for (const link of config.link) {
595
+ const el = document.createElement("link");
596
+ for (const [k, v] of Object.entries(link)) if (v !== void 0) el.setAttribute(k, v);
597
+ el.setAttribute("data-sigx-head", String(token));
598
+ document.head.appendChild(el);
599
+ managed.push(el);
600
+ }
601
+ if (config.script) for (const script of config.script) {
602
+ const { innerHTML, ...rest } = script;
603
+ const el = document.createElement("script");
604
+ for (const [k, v] of Object.entries(rest)) if (v === true) el.setAttribute(k, "");
605
+ else if (v !== void 0 && v !== false) el.setAttribute(k, String(v));
606
+ if (innerHTML) el.textContent = innerHTML;
607
+ el.setAttribute("data-sigx-head", String(token));
608
+ document.head.appendChild(el);
609
+ managed.push(el);
610
+ }
611
+ if (config.htmlAttrs) {
612
+ for (const [k, v] of Object.entries(config.htmlAttrs)) if (v !== void 0) document.documentElement.setAttribute(k, v);
613
+ }
614
+ if (config.bodyAttrs) {
615
+ for (const [k, v] of Object.entries(config.bodyAttrs)) if (v !== void 0) document.body.setAttribute(k, v);
616
+ }
617
+ return () => {
618
+ for (const el of managed) el.remove();
619
+ };
620
+ }
621
+ function useHead(config) {
622
+ if (_isSSR) {
623
+ _ssrHeadConfigs.push(config);
624
+ return;
625
+ }
626
+ const cleanup = applyHeadClient(config);
627
+ const instance = getCurrentInstance();
628
+ if (instance) instance.onUnmounted(() => cleanup());
629
+ }
630
+ function escapeHtml(s) {
631
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
632
+ }
633
+ function escapeAttr(s) {
634
+ return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
635
+ }
636
+ function isApp(input) {
637
+ return input && typeof input === "object" && "_rootComponent" in input && "_context" in input;
638
+ }
639
+ function extractInput(input) {
640
+ if (isApp(input)) return {
641
+ element: input._rootComponent,
642
+ appContext: input._context
643
+ };
644
+ return {
645
+ element: input,
646
+ appContext: null
647
+ };
648
+ }
649
+ async function* streamAllAsyncChunks(ctx, plugins) {
650
+ const hasCoreAsync = ctx._pendingAsync.length > 0;
651
+ const pluginGenerators = [];
652
+ for (const plugin of plugins) {
653
+ const chunks = plugin.server?.getStreamingChunks?.(ctx);
654
+ if (chunks) pluginGenerators.push(chunks);
655
+ }
656
+ const hasPluginStreaming = pluginGenerators.length > 0;
657
+ if (!hasCoreAsync && !hasPluginStreaming) return;
658
+ if (hasCoreAsync) yield generateStreamingScript();
659
+ const corePromises = ctx._pendingAsync.map((pending, index) => pending.promise.then((html) => {
660
+ let finalHtml = html;
661
+ let extraScript = "";
662
+ for (const plugin of plugins) {
663
+ const result = plugin.server?.onAsyncComponentResolved?.(pending.id, finalHtml, ctx);
664
+ if (result) {
665
+ if (result.html !== void 0) finalHtml = result.html;
666
+ if (result.script) extraScript += result.script;
667
+ }
668
+ }
669
+ return {
670
+ index,
671
+ script: generateReplacementScript(pending.id, finalHtml, extraScript || void 0)
672
+ };
673
+ }).catch((error) => {
674
+ if (process.env.NODE_ENV !== "production") console.error(`Error streaming async component ${pending.id}:`, error);
675
+ return {
676
+ index,
677
+ script: generateReplacementScript(pending.id, `<div style="color:red;">Error loading component</div>`)
678
+ };
679
+ }));
680
+ const totalCore = corePromises.length;
681
+ const pumps = pluginGenerators.map((g) => ({
682
+ generator: g,
683
+ done: false
684
+ }));
685
+ const activePumps = /* @__PURE__ */ new Map();
686
+ function pumpNext(pumpIdx) {
687
+ const slotIndex = totalCore + pumpIdx;
688
+ return pumps[pumpIdx].generator.next().then(({ value, done }) => {
689
+ if (done) {
690
+ pumps[pumpIdx].done = true;
691
+ activePumps.delete(slotIndex);
692
+ return {
693
+ index: slotIndex,
694
+ script: ""
695
+ };
696
+ }
697
+ const nextP = pumpNext(pumpIdx);
698
+ activePumps.set(slotIndex, nextP);
699
+ return {
700
+ index: slotIndex,
701
+ script: value || ""
702
+ };
703
+ });
704
+ }
705
+ for (let i = 0; i < pumps.length; i++) {
706
+ const slotIndex = totalCore + i;
707
+ const p = pumpNext(i);
708
+ activePumps.set(slotIndex, p);
709
+ }
710
+ const resolvedCore = /* @__PURE__ */ new Set();
711
+ function getRaceablePromises() {
712
+ const promises = [];
713
+ for (let i = 0; i < totalCore; i++) if (!resolvedCore.has(i)) promises.push(corePromises[i]);
714
+ for (const [, p] of activePumps) promises.push(p);
715
+ return promises;
716
+ }
717
+ while (true) {
718
+ const raceable = getRaceablePromises();
719
+ if (raceable.length === 0) break;
720
+ const winner = await Promise.race(raceable);
721
+ if (winner.script) yield winner.script;
722
+ if (winner.index < totalCore) resolvedCore.add(winner.index);
723
+ }
724
+ }
725
+ function createSSR() {
726
+ const plugins = [];
727
+ function makeContext(options) {
728
+ const ctx = options && "_componentId" in options ? options : createSSRContext(options);
729
+ ctx._plugins = plugins;
730
+ for (const plugin of plugins) plugin.server?.setup?.(ctx);
731
+ return ctx;
732
+ }
733
+ return {
734
+ use(plugin) {
735
+ plugins.push(plugin);
736
+ return this;
737
+ },
738
+ async render(input, options) {
739
+ const { element, appContext } = extractInput(input);
740
+ enableSSRHead();
741
+ let result = "";
742
+ let ctx;
743
+ const syncCtx = makeContext(options);
744
+ const buf = [];
745
+ if (renderToStringSync(element, syncCtx, null, appContext, buf)) {
746
+ result = buf.join("");
747
+ ctx = syncCtx;
748
+ } else {
749
+ ctx = makeContext(options);
750
+ for await (const chunk of renderToChunks(element, ctx, null, appContext)) result += chunk;
751
+ }
752
+ for (const plugin of plugins) {
753
+ const injected = plugin.server?.getInjectedHTML?.(ctx);
754
+ if (injected) result += typeof injected === "string" ? injected : await injected;
755
+ }
756
+ for (const plugin of plugins) {
757
+ const chunks = plugin.server?.getStreamingChunks?.(ctx);
758
+ if (chunks) for await (const chunk of chunks) result += chunk;
759
+ }
760
+ const headConfigs = collectSSRHead();
761
+ if (headConfigs.length > 0) ctx.addHead(renderHeadToString(headConfigs));
762
+ return result;
763
+ },
764
+ renderStream(input, options) {
765
+ const ctx = makeContext(options);
766
+ ctx._streaming = true;
767
+ const { element, appContext } = extractInput(input);
768
+ return new ReadableStream({ async start(controller) {
769
+ try {
770
+ enableSSRHead();
771
+ for await (const chunk of renderToChunks(element, ctx, null, appContext)) controller.enqueue(chunk);
772
+ const headConfigs = collectSSRHead();
773
+ if (headConfigs.length > 0) ctx.addHead(renderHeadToString(headConfigs));
774
+ for (const plugin of plugins) {
775
+ const injected = plugin.server?.getInjectedHTML?.(ctx);
776
+ if (injected) {
777
+ const html = typeof injected === "string" ? injected : await injected;
778
+ if (html) controller.enqueue(html);
779
+ }
780
+ }
781
+ for await (const chunk of streamAllAsyncChunks(ctx, plugins)) controller.enqueue(chunk);
782
+ controller.enqueue(`<script>window.__SIGX_STREAMING_COMPLETE__=true;window.dispatchEvent(new Event('sigx:ready'));<\/script>`);
783
+ controller.close();
784
+ } catch (error) {
785
+ controller.error(error);
786
+ }
787
+ } });
788
+ },
789
+ async renderStreamWithCallbacks(input, callbacks, options) {
790
+ const ctx = makeContext(options);
791
+ ctx._streaming = true;
792
+ const { element, appContext } = extractInput(input);
793
+ try {
794
+ enableSSRHead();
795
+ let shellHtml = "";
796
+ for await (const chunk of renderToChunks(element, ctx, null, appContext)) shellHtml += chunk;
797
+ const headConfigs = collectSSRHead();
798
+ if (headConfigs.length > 0) ctx.addHead(renderHeadToString(headConfigs));
799
+ for (const plugin of plugins) {
800
+ const injected = plugin.server?.getInjectedHTML?.(ctx);
801
+ if (injected) shellHtml += typeof injected === "string" ? injected : await injected;
802
+ }
803
+ shellHtml += `<script>window.__SIGX_STREAMING_COMPLETE__=true;window.dispatchEvent(new Event('sigx:ready'));<\/script>`;
804
+ callbacks.onShellReady(shellHtml);
805
+ for await (const chunk of streamAllAsyncChunks(ctx, plugins)) callbacks.onAsyncChunk(chunk);
806
+ callbacks.onComplete();
807
+ } catch (error) {
808
+ callbacks.onError(error);
809
+ }
810
+ },
811
+ createContext(options) {
812
+ return makeContext(options);
813
+ }
814
+ };
815
+ }
816
+ var _defaultSSR = createSSR();
817
+ function renderToStream(input, context) {
818
+ return _defaultSSR.renderStream(input, context);
819
+ }
820
+ async function renderToStreamWithCallbacks(input, callbacks, context) {
821
+ return _defaultSSR.renderStreamWithCallbacks(input, callbacks, context);
822
+ }
823
+ async function renderToString(input, context) {
824
+ return _defaultSSR.render(input, context);
825
+ }
826
+ initDirectivesForSSR();
827
+ export { collectSSRHead as a, useHead as c, generateStreamingScript as d, renderVNodeToString as f, createSSR as i, escapeJsonForScript as l, initDirectivesForSSR as m, renderToStreamWithCallbacks as n, enableSSRHead as o, createSSRContext as p, renderToString as r, renderHeadToString as s, renderToStream as t, generateReplacementScript as u };
828
+
829
+ //# sourceMappingURL=server-UBcHtkm-.js.map