@fluixi/dom 1.0.0-alpha.82 → 1.0.0-alpha.84

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 (183) hide show
  1. package/dist/cdn/dom-client.cjs +1427 -1
  2. package/dist/cdn/dom-client.d.ts +2 -2
  3. package/dist/cdn/dom-client.global.js +2 -1
  4. package/dist/cdn/dom-client.js +3 -3
  5. package/dist/cdn/dom-client.mjs +1430 -1
  6. package/dist/cdn/dom.cjs +3127 -1
  7. package/dist/cdn/dom.d.ts +2 -2
  8. package/dist/cdn/dom.global.js +2 -1
  9. package/dist/cdn/dom.js +4 -4
  10. package/dist/cdn/dom.mjs +3133 -1
  11. package/dist/index.cjs +3155 -1
  12. package/dist/index.js +2 -2
  13. package/dist/index.mjs +3149 -1
  14. package/dist/lib/component/index.cjs +128 -1
  15. package/dist/lib/component/index.mjs +105 -1
  16. package/dist/lib/component/modifiers.cjs +126 -1
  17. package/dist/lib/component/modifiers.d.ts +12 -0
  18. package/dist/lib/component/modifiers.d.ts.map +1 -1
  19. package/dist/lib/component/modifiers.js +12 -84
  20. package/dist/lib/component/modifiers.mjs +105 -1
  21. package/dist/lib/dom/delegate.cjs +60 -1
  22. package/dist/lib/dom/delegate.js +1 -1
  23. package/dist/lib/dom/delegate.mjs +39 -1
  24. package/dist/lib/dom/dynamic-element.cjs +949 -1
  25. package/dist/lib/dom/dynamic-element.d.ts +3 -3
  26. package/dist/lib/dom/dynamic-element.js +3 -3
  27. package/dist/lib/dom/dynamic-element.mjs +928 -1
  28. package/dist/lib/dom/hydration-state.cjs +93 -1
  29. package/dist/lib/dom/hydration-state.d.ts +1 -1
  30. package/dist/lib/dom/hydration-state.js +1 -1
  31. package/dist/lib/dom/hydration-state.mjs +72 -1
  32. package/dist/lib/dom/hydration.cjs +685 -1
  33. package/dist/lib/dom/hydration.js +8 -8
  34. package/dist/lib/dom/hydration.mjs +664 -1
  35. package/dist/lib/dom/index.cjs +2040 -1
  36. package/dist/lib/dom/index.js +1 -1
  37. package/dist/lib/dom/index.mjs +2020 -1
  38. package/dist/lib/dom/integration.cjs +71 -1
  39. package/dist/lib/dom/integration.d.ts.map +1 -1
  40. package/dist/lib/dom/integration.js +15 -6
  41. package/dist/lib/dom/integration.mjs +51 -1
  42. package/dist/lib/dom/island.cjs +790 -1
  43. package/dist/lib/dom/island.d.ts +1 -1
  44. package/dist/lib/dom/island.js +12 -12
  45. package/dist/lib/dom/island.mjs +769 -1
  46. package/dist/lib/dom/runtime.cjs +1432 -1
  47. package/dist/lib/dom/runtime.d.ts +71 -19
  48. package/dist/lib/dom/runtime.d.ts.map +1 -1
  49. package/dist/lib/dom/runtime.js +261 -100
  50. package/dist/lib/dom/runtime.mjs +1414 -1
  51. package/dist/lib/dom/server/fx-data.cjs +53 -1
  52. package/dist/lib/dom/server/fx-data.d.ts +5 -5
  53. package/dist/lib/dom/server/fx-data.js +6 -6
  54. package/dist/lib/dom/server/fx-data.mjs +32 -1
  55. package/dist/lib/dom/server/host.cjs +66 -1
  56. package/dist/lib/dom/server/host.d.ts +14 -2
  57. package/dist/lib/dom/server/host.d.ts.map +1 -1
  58. package/dist/lib/dom/server/host.js +38 -10
  59. package/dist/lib/dom/server/host.mjs +45 -1
  60. package/dist/lib/dom/server/index.cjs +759 -1
  61. package/dist/lib/dom/server/index.d.ts +1 -1
  62. package/dist/lib/dom/server/index.js +1 -1
  63. package/dist/lib/dom/server/index.mjs +743 -1
  64. package/dist/lib/dom/server/nodes.cjs +302 -1
  65. package/dist/lib/dom/server/nodes.d.ts +2 -2
  66. package/dist/lib/dom/server/nodes.d.ts.map +1 -1
  67. package/dist/lib/dom/server/nodes.js +4 -4
  68. package/dist/lib/dom/server/nodes.mjs +279 -1
  69. package/dist/lib/dom/server/parse-template.cjs +395 -1
  70. package/dist/lib/dom/server/parse-template.d.ts +1 -1
  71. package/dist/lib/dom/server/parse-template.js +4 -4
  72. package/dist/lib/dom/server/parse-template.mjs +372 -1
  73. package/dist/lib/dom/server/render.cjs +691 -1
  74. package/dist/lib/dom/server/render.d.ts +9 -1
  75. package/dist/lib/dom/server/render.d.ts.map +1 -1
  76. package/dist/lib/dom/server/render.js +25 -17
  77. package/dist/lib/dom/server/render.mjs +677 -1
  78. package/dist/lib/dom/server/request-context.cjs +110 -1
  79. package/dist/lib/dom/server/request-context.d.ts +29 -9
  80. package/dist/lib/dom/server/request-context.d.ts.map +1 -1
  81. package/dist/lib/dom/server/request-context.js +28 -8
  82. package/dist/lib/dom/server/request-context.mjs +89 -1
  83. package/dist/lib/dom/server/serialize.cjs +187 -1
  84. package/dist/lib/dom/server/serialize.js +3 -3
  85. package/dist/lib/dom/server/serialize.mjs +164 -1
  86. package/dist/lib/dom/server-renderer.cjs +760 -1
  87. package/dist/lib/dom/server-renderer.js +1 -1
  88. package/dist/lib/dom/server-renderer.mjs +745 -1
  89. package/dist/lib/dom/types.cjs +18 -1
  90. package/dist/lib/dom/utils.cjs +381 -1
  91. package/dist/lib/dom/utils.d.ts +1 -88
  92. package/dist/lib/dom/utils.d.ts.map +1 -1
  93. package/dist/lib/dom/utils.js +2 -99
  94. package/dist/lib/dom/utils.mjs +361 -1
  95. package/dist/lib/dom/versions.cjs +60 -1
  96. package/dist/lib/dom/versions.d.ts +3 -3
  97. package/dist/lib/dom/versions.d.ts.map +1 -1
  98. package/dist/lib/dom/versions.js +17 -5
  99. package/dist/lib/dom/versions.mjs +37 -1
  100. package/dist/lib/element/attributes.cjs +19 -1
  101. package/dist/lib/element/attributes.d.ts +7 -7
  102. package/dist/lib/element/attributes.js +1 -1
  103. package/dist/lib/element/attributes.mjs +1 -0
  104. package/dist/lib/element/index.cjs +19 -1
  105. package/dist/lib/element/index.mjs +1 -0
  106. package/dist/lib/element/types.cjs +18 -1
  107. package/dist/lib/element/types.d.ts +4 -5
  108. package/dist/lib/element/types.d.ts.map +1 -1
  109. package/dist/lib/element/types.js +0 -1
  110. package/dist/lib/flow/class-map.cjs +38 -1
  111. package/dist/lib/flow/class-map.d.ts +3 -3
  112. package/dist/lib/flow/class-map.js +3 -3
  113. package/dist/lib/flow/class-map.mjs +17 -1
  114. package/dist/lib/flow/client-only.cjs +57 -1
  115. package/dist/lib/flow/client-only.d.ts +4 -4
  116. package/dist/lib/flow/client-only.js +4 -4
  117. package/dist/lib/flow/client-only.mjs +36 -1
  118. package/dist/lib/flow/dynamic.cjs +53 -1
  119. package/dist/lib/flow/dynamic.d.ts +2 -2
  120. package/dist/lib/flow/dynamic.js +4 -4
  121. package/dist/lib/flow/dynamic.mjs +32 -1
  122. package/dist/lib/flow/error-boundary.cjs +43 -1
  123. package/dist/lib/flow/error-boundary.d.ts +2 -2
  124. package/dist/lib/flow/error-boundary.js +4 -4
  125. package/dist/lib/flow/error-boundary.mjs +22 -1
  126. package/dist/lib/flow/for.cjs +66 -1
  127. package/dist/lib/flow/for.d.ts +9 -9
  128. package/dist/lib/flow/for.d.ts.map +1 -1
  129. package/dist/lib/flow/for.js +2 -2
  130. package/dist/lib/flow/for.mjs +45 -1
  131. package/dist/lib/flow/index-flow.cjs +67 -1
  132. package/dist/lib/flow/index-flow.d.ts +5 -5
  133. package/dist/lib/flow/index-flow.js +4 -4
  134. package/dist/lib/flow/index-flow.mjs +46 -1
  135. package/dist/lib/flow/index.cjs +805 -1
  136. package/dist/lib/flow/index.mjs +792 -1
  137. package/dist/lib/flow/portal.cjs +538 -1
  138. package/dist/lib/flow/portal.mjs +519 -1
  139. package/dist/lib/flow/show.cjs +81 -1
  140. package/dist/lib/flow/show.d.ts +1 -1
  141. package/dist/lib/flow/show.d.ts.map +1 -1
  142. package/dist/lib/flow/show.js +12 -118
  143. package/dist/lib/flow/show.mjs +67 -1
  144. package/dist/lib/flow/style-map.cjs +43 -1
  145. package/dist/lib/flow/style-map.d.ts +3 -3
  146. package/dist/lib/flow/style-map.js +4 -4
  147. package/dist/lib/flow/style-map.mjs +22 -1
  148. package/dist/lib/flow/switch.cjs +91 -1
  149. package/dist/lib/flow/switch.d.ts +3 -3
  150. package/dist/lib/flow/switch.d.ts.map +1 -1
  151. package/dist/lib/flow/switch.js +7 -7
  152. package/dist/lib/flow/switch.mjs +70 -1
  153. package/dist/lib/flow/utils.cjs +44 -1
  154. package/dist/lib/flow/utils.d.ts +1 -1
  155. package/dist/lib/flow/utils.js +1 -1
  156. package/dist/lib/flow/utils.mjs +23 -1
  157. package/dist/lib/html.cjs +32 -1
  158. package/dist/lib/html.d.ts +6 -6
  159. package/dist/lib/html.js +5 -5
  160. package/dist/lib/html.mjs +11 -1
  161. package/dist/lib/index.cjs +3104 -1
  162. package/dist/lib/index.d.ts +0 -1
  163. package/dist/lib/index.d.ts.map +1 -1
  164. package/dist/lib/index.js +2 -3
  165. package/dist/lib/index.mjs +3097 -1
  166. package/dist/lib/shared/types.cjs +18 -1
  167. package/dist/lib/shared/types.d.ts +8 -8
  168. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  169. package/dist/version.generated.cjs +26 -1
  170. package/dist/version.generated.d.ts +1 -1
  171. package/dist/version.generated.js +2 -2
  172. package/dist/version.generated.mjs +5 -1
  173. package/package.json +7 -6
  174. package/dist/lib/jsx/control-flow/flow.cjs +0 -1
  175. package/dist/lib/jsx/control-flow/flow.d.ts +0 -2
  176. package/dist/lib/jsx/control-flow/flow.d.ts.map +0 -1
  177. package/dist/lib/jsx/control-flow/flow.js +0 -627
  178. package/dist/lib/jsx/control-flow/flow.mjs +0 -0
  179. package/dist/lib/jsx/control-flow/for-flow.cjs +0 -1
  180. package/dist/lib/jsx/control-flow/for-flow.d.ts +0 -2
  181. package/dist/lib/jsx/control-flow/for-flow.d.ts.map +0 -1
  182. package/dist/lib/jsx/control-flow/for-flow.js +0 -1
  183. package/dist/lib/jsx/control-flow/for-flow.mjs +0 -0
@@ -1 +1,110 @@
1
- "use strict";var a=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var k=(e,t)=>{for(var r in t)a(e,r,{get:t[r],enumerable:!0})},C=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of w(t))!S.call(e,s)&&s!==r&&a(e,s,{get:()=>t[s],enumerable:!(n=f(t,s))||n.enumerable});return e};var M=e=>C(a({},"__esModule",{value:!0}),e);var b={};k(b,{createRequestContext:()=>L,getLocals:()=>y,getRequestContext:()=>q,getRequestEvent:()=>x,getRequestLocals:()=>g,runWithRequestContext:()=>v,setRequestStore:()=>T});module.exports=M(b);var c,p={getStore:()=>c,run(e,t){let r=c;c=e;try{return t()}finally{c=r}}},i=p;function T(e){i=e??p}function L(e={}){e.locals||(e.locals=e.request?g(e.request):{});let t=0,r=0,n=null,s=new Map,l=new Map;return{event:e,routeData:new Map,matchedRoute:new Map,nextId:()=>`s${t++}`,nextResourceId:()=>{if(n===null)return`r${r++}`;let o=s.get(n)??0;return s.set(n,o+1),`${n}:r${o}`},nextIslandNamespace:o=>{let u=l.get(o)??0;return l.set(o,u+1),`${o}#${u}`},withResourceScope(o,u){let d=n;n=o;try{return u()}finally{n=d}},pending:new Set,data:new Map}}function v(e,t){return i.run(e,t)}function q(){return i.getStore()}function x(){return q()?.event}function y(){let e=x();return e?(e.locals||(e.locals={}),e.locals):{}}var R=new WeakMap;function g(e){let t=R.get(e);return t||(t={},R.set(e,t)),t}
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/dom/server/request-context.ts
21
+ var request_context_exports = {};
22
+ __export(request_context_exports, {
23
+ createRequestContext: () => createRequestContext,
24
+ getLocals: () => getLocals,
25
+ getRequestContext: () => getRequestContext,
26
+ getRequestEvent: () => getRequestEvent,
27
+ getRequestLocals: () => getRequestLocals,
28
+ runWithRequestContext: () => runWithRequestContext,
29
+ setRequestStore: () => setRequestStore
30
+ });
31
+ module.exports = __toCommonJS(request_context_exports);
32
+ var _current;
33
+ var syncStore = {
34
+ getStore: () => _current,
35
+ run(ctx, fn) {
36
+ const prev = _current;
37
+ _current = ctx;
38
+ try {
39
+ return fn();
40
+ } finally {
41
+ _current = prev;
42
+ }
43
+ }
44
+ };
45
+ var _store = syncStore;
46
+ function setRequestStore(store) {
47
+ _store = store ?? syncStore;
48
+ }
49
+ function createRequestContext(event = {}) {
50
+ if (!event.locals) {
51
+ event.locals = event.request ? getRequestLocals(event.request) : {};
52
+ }
53
+ let id = 0;
54
+ let rid = 0;
55
+ let scope = null;
56
+ const scopeCounters = /* @__PURE__ */ new Map();
57
+ const islandCounts = /* @__PURE__ */ new Map();
58
+ return {
59
+ event,
60
+ routeData: /* @__PURE__ */ new Map(),
61
+ matchedRoute: /* @__PURE__ */ new Map(),
62
+ nextId: () => `s${id++}`,
63
+ nextResourceId: () => {
64
+ if (scope === null) return `r${rid++}`;
65
+ const n = scopeCounters.get(scope) ?? 0;
66
+ scopeCounters.set(scope, n + 1);
67
+ return `${scope}:r${n}`;
68
+ },
69
+ nextIslandNamespace: (name) => {
70
+ const n = islandCounts.get(name) ?? 0;
71
+ islandCounts.set(name, n + 1);
72
+ return `${name}#${n}`;
73
+ },
74
+ withResourceScope(ns, fn) {
75
+ const prev = scope;
76
+ scope = ns;
77
+ try {
78
+ return fn();
79
+ } finally {
80
+ scope = prev;
81
+ }
82
+ },
83
+ pending: /* @__PURE__ */ new Set(),
84
+ data: /* @__PURE__ */ new Map()
85
+ };
86
+ }
87
+ function runWithRequestContext(ctx, fn) {
88
+ return _store.run(ctx, fn);
89
+ }
90
+ function getRequestContext() {
91
+ return _store.getStore();
92
+ }
93
+ function getRequestEvent() {
94
+ return getRequestContext()?.event;
95
+ }
96
+ function getLocals() {
97
+ const event = getRequestEvent();
98
+ if (!event) return {};
99
+ if (!event.locals) event.locals = {};
100
+ return event.locals;
101
+ }
102
+ var _requestLocals = /* @__PURE__ */ new WeakMap();
103
+ function getRequestLocals(request) {
104
+ let bag = _requestLocals.get(request);
105
+ if (!bag) {
106
+ bag = {};
107
+ _requestLocals.set(request, bag);
108
+ }
109
+ return bag;
110
+ }
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Per-request SSR context the request-scoping that fixes the "P0 #4"
3
- * module-global concurrency hazard. State that must NOT be shared across
2
+ * Per-request SSR context, the request-scoping that fixes the "P0 #4"
3
+ * module-global concurrency hazard. State that must not be shared across
4
4
  * concurrent server renders (route data, the matched-route map, the hydration
5
5
  * id counter, the request event) lives here, keyed by an injectable store.
6
6
  *
@@ -8,7 +8,7 @@
8
8
  * (`run(store, cb)` + `getStore()`), so a real ALS can be injected verbatim by
9
9
  * the Node-only @fluixi/server package (and by tests). @fluixi/dom itself stays
10
10
  * environment-agnostic: it never imports `node:async_hooks`, so browser bundles
11
- * don't pull it in. The default store is a synchronous module-global correct
11
+ * don't pull it in. The default store is a synchronous module-global: correct
12
12
  * for a single sync render; concurrency isolation comes from the injected ALS.
13
13
  */
14
14
  /**
@@ -42,9 +42,9 @@ export interface RequestContext {
42
42
  /** monotonic per-request id source for hydration markers (was module-global ssrMarkerId) */
43
43
  nextId(): string;
44
44
  /**
45
- * Per-request resource id (creation order) matched on the client. Outside an island
46
- * the id is global creation order (`r0`, `r1`, ). Inside an island scope it is namespaced
47
- * and counted PER island (`Counter#0:r0`, ) so the client, which hydrates each island
45
+ * Per-request resource id (creation order): matched on the client. Outside an island
46
+ * the id is global creation order (`r0`, `r1`, ...). Inside an island scope it is namespaced
47
+ * and counted PER island (`Counter#0:r0`, ...) so the client, which hydrates each island
48
48
  * independently and restarts its local counter, reproduces the same ids and seeds each
49
49
  * island's resources from `__FX_DATA__` without a global render.
50
50
  */
@@ -58,26 +58,46 @@ export interface RequestContext {
58
58
  /** resolved resource data to serialize for client hydration, keyed by resource id */
59
59
  data: Map<string, unknown>;
60
60
  }
61
- /** Matches AsyncLocalStorage<RequestContext> inject one for real isolation. */
61
+ /** Matches AsyncLocalStorage<RequestContext>: inject one for real isolation. */
62
62
  export interface RequestStore {
63
63
  getStore(): RequestContext | undefined;
64
64
  run<T>(ctx: RequestContext, fn: () => T): T;
65
65
  }
66
66
  /** Inject an AsyncLocalStorage-shaped store (Node @fluixi/server / tests). */
67
67
  export declare function setRequestStore(store: RequestStore | null): void;
68
+ /**
69
+ * A per-request context: the event, its locals, and the data bag hydration reads.
70
+ *
71
+ * `locals` is adopted from the platform request when there is one, so anything
72
+ * middleware wrote is the same object the render sees. Without a request it starts
73
+ * empty.
74
+ */
68
75
  export declare function createRequestContext(event?: RequestEvent): RequestContext;
76
+ /**
77
+ * Run `fn` with `ctx` as the current request.
78
+ *
79
+ * Backed by `AsyncLocalStorage` where the host provides one, which is what keeps two
80
+ * concurrent renders from reading each other's request. A synchronous fallback covers
81
+ * hosts without it.
82
+ */
69
83
  export declare function runWithRequestContext<T>(ctx: RequestContext, fn: () => T): T;
70
84
  export declare function getRequestContext(): RequestContext | undefined;
85
+ /**
86
+ * The request being rendered, or undefined outside a server render.
87
+ *
88
+ * Undefined rather than throwing, because the same component code runs on the client
89
+ * where there is no request to have.
90
+ */
71
91
  export declare function getRequestEvent(): RequestEvent | undefined;
72
92
  /**
73
93
  * The current request's mutable `locals` bag (created if absent). Returns a fresh empty
74
94
  * object when called outside a request context, so reads never throw. This is the seam
75
- * middleware writes (e.g. `getLocals().auth = …`) and loaders / server functions read.
95
+ * middleware writes (e.g. `getLocals().auth = ...`) and loaders / server functions read.
76
96
  */
77
97
  export declare function getLocals(): RequestLocals;
78
98
  /**
79
99
  * The mutable `locals` bag for a platform request object (created on first access).
80
- * Middleware writes here (e.g. `getRequestLocals(request).auth = …`) before calling
100
+ * Middleware writes here (e.g. `getRequestLocals(request).auth = ...`) before calling
81
101
  * `next()`; the render then reads the same object via `getLocals()`. Pairs with the app
82
102
  * entry forwarding `request` on the render event (`renderRequestAsync(App, { url, request })`).
83
103
  */
@@ -1 +1 @@
1
- {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../../../src/lib/dom/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,qFAAqF;IACrF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,CAAC;IACpB,qFAAqF;IACrF,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,4EAA4E;IAC5E,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACpC,4FAA4F;IAC5F,MAAM,IAAI,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,cAAc,IAAI,MAAM,CAAC;IACzB,2FAA2F;IAC3F,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,4FAA4F;IAC5F,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACjD,mEAAmE;IACnE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/B,qFAAqF;IACrF,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5B;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,QAAQ,IAAI,cAAc,GAAG,SAAS,CAAC;IACvC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;CAC7C;AAqBD,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAEhE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,GAAE,YAAiB,GAAG,cAAc,CA0C7E;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE5E;AAED,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED,wBAAgB,eAAe,IAAI,YAAY,GAAG,SAAS,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,aAAa,CAKzC;AASD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAO/D"}
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../../../src/lib/dom/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,qFAAqF;IACrF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,CAAC;IACpB,qFAAqF;IACrF,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,4EAA4E;IAC5E,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACpC,4FAA4F;IAC5F,MAAM,IAAI,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,cAAc,IAAI,MAAM,CAAC;IACzB,2FAA2F;IAC3F,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,4FAA4F;IAC5F,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACjD,mEAAmE;IACnE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/B,qFAAqF;IACrF,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5B;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,QAAQ,IAAI,cAAc,GAAG,SAAS,CAAC;IACvC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;CAC7C;AAqBD,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAEhE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,GAAE,YAAiB,GAAG,cAAc,CA0C7E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE5E;AAED,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,YAAY,GAAG,SAAS,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,aAAa,CAKzC;AASD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAO/D"}
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Per-request SSR context the request-scoping that fixes the "P0 #4"
3
- * module-global concurrency hazard. State that must NOT be shared across
2
+ * Per-request SSR context, the request-scoping that fixes the "P0 #4"
3
+ * module-global concurrency hazard. State that must not be shared across
4
4
  * concurrent server renders (route data, the matched-route map, the hydration
5
5
  * id counter, the request event) lives here, keyed by an injectable store.
6
6
  *
@@ -8,7 +8,7 @@
8
8
  * (`run(store, cb)` + `getStore()`), so a real ALS can be injected verbatim by
9
9
  * the Node-only @fluixi/server package (and by tests). @fluixi/dom itself stays
10
10
  * environment-agnostic: it never imports `node:async_hooks`, so browser bundles
11
- * don't pull it in. The default store is a synchronous module-global correct
11
+ * don't pull it in. The default store is a synchronous module-global: correct
12
12
  * for a single sync render; concurrency isolation comes from the injected ALS.
13
13
  */
14
14
  // Default synchronous store. A single sync render runs start-to-finish without
@@ -33,9 +33,16 @@ let _store = syncStore;
33
33
  export function setRequestStore(store) {
34
34
  _store = store ?? syncStore;
35
35
  }
36
+ /**
37
+ * A per-request context: the event, its locals, and the data bag hydration reads.
38
+ *
39
+ * `locals` is adopted from the platform request when there is one, so anything
40
+ * middleware wrote is the same object the render sees. Without a request it starts
41
+ * empty.
42
+ */
36
43
  export function createRequestContext(event = {}) {
37
- // Seed the locals bag: if the event carries the platform request, ADOPT the bag that
38
- // middleware wrote via getRequestLocals(request) (the middlewarerender bridge); else
44
+ // Seed the locals bag, if the event carries the platform request, ADOPT the bag that
45
+ // middleware wrote via getRequestLocals(request) (the middleware -> render bridge); else
39
46
  // start a fresh empty one. Either way the render's getLocals() sees the right object.
40
47
  if (!event.locals) {
41
48
  event.locals = event.request ? getRequestLocals(event.request) : {};
@@ -78,19 +85,32 @@ export function createRequestContext(event = {}) {
78
85
  data: new Map(),
79
86
  };
80
87
  }
88
+ /**
89
+ * Run `fn` with `ctx` as the current request.
90
+ *
91
+ * Backed by `AsyncLocalStorage` where the host provides one, which is what keeps two
92
+ * concurrent renders from reading each other's request. A synchronous fallback covers
93
+ * hosts without it.
94
+ */
81
95
  export function runWithRequestContext(ctx, fn) {
82
96
  return _store.run(ctx, fn);
83
97
  }
84
98
  export function getRequestContext() {
85
99
  return _store.getStore();
86
100
  }
101
+ /**
102
+ * The request being rendered, or undefined outside a server render.
103
+ *
104
+ * Undefined rather than throwing, because the same component code runs on the client
105
+ * where there is no request to have.
106
+ */
87
107
  export function getRequestEvent() {
88
108
  return getRequestContext()?.event;
89
109
  }
90
110
  /**
91
111
  * The current request's mutable `locals` bag (created if absent). Returns a fresh empty
92
112
  * object when called outside a request context, so reads never throw. This is the seam
93
- * middleware writes (e.g. `getLocals().auth = …`) and loaders / server functions read.
113
+ * middleware writes (e.g. `getLocals().auth = ...`) and loaders / server functions read.
94
114
  */
95
115
  export function getLocals() {
96
116
  const event = getRequestEvent();
@@ -100,7 +120,7 @@ export function getLocals() {
100
120
  event.locals = {};
101
121
  return event.locals;
102
122
  }
103
- // ─── middleware render bridge ─────────────────────────────────────────────────
123
+ // ─── middleware -> render bridge ─────────────────────────────────────────────────
104
124
  // Middleware runs on the raw platform request, OUTSIDE the render's request context.
105
125
  // This WeakMap associates a per-request locals bag with that request object; the render
106
126
  // adopts it in createRequestContext when the app forwards `request` on the event. Keyed
@@ -108,7 +128,7 @@ export function getLocals() {
108
128
  const _requestLocals = new WeakMap();
109
129
  /**
110
130
  * The mutable `locals` bag for a platform request object (created on first access).
111
- * Middleware writes here (e.g. `getRequestLocals(request).auth = …`) before calling
131
+ * Middleware writes here (e.g. `getRequestLocals(request).auth = ...`) before calling
112
132
  * `next()`; the render then reads the same object via `getLocals()`. Pairs with the app
113
133
  * entry forwarding `request` on the render event (`renderRequestAsync(App, { url, request })`).
114
134
  */
@@ -1 +1,89 @@
1
- var o,R={getStore:()=>o,run(e,t){let u=o;o=e;try{return t()}finally{o=u}}},c=R;function d(e){c=e??R}function f(e={}){e.locals||(e.locals=e.request?g(e.request):{});let t=0,u=0,r=null,a=new Map,i=new Map;return{event:e,routeData:new Map,matchedRoute:new Map,nextId:()=>`s${t++}`,nextResourceId:()=>{if(r===null)return`r${u++}`;let n=a.get(r)??0;return a.set(r,n+1),`${r}:r${n}`},nextIslandNamespace:n=>{let s=i.get(n)??0;return i.set(n,s+1),`${n}#${s}`},withResourceScope(n,s){let p=r;r=n;try{return s()}finally{r=p}},pending:new Set,data:new Map}}function w(e,t){return c.run(e,t)}function q(){return c.getStore()}function x(){return q()?.event}function S(){let e=x();return e?(e.locals||(e.locals={}),e.locals):{}}var l=new WeakMap;function g(e){let t=l.get(e);return t||(t={},l.set(e,t)),t}export{f as createRequestContext,S as getLocals,q as getRequestContext,x as getRequestEvent,g as getRequestLocals,w as runWithRequestContext,d as setRequestStore};
1
+ // src/lib/dom/server/request-context.ts
2
+ var _current;
3
+ var syncStore = {
4
+ getStore: () => _current,
5
+ run(ctx, fn) {
6
+ const prev = _current;
7
+ _current = ctx;
8
+ try {
9
+ return fn();
10
+ } finally {
11
+ _current = prev;
12
+ }
13
+ }
14
+ };
15
+ var _store = syncStore;
16
+ function setRequestStore(store) {
17
+ _store = store ?? syncStore;
18
+ }
19
+ function createRequestContext(event = {}) {
20
+ if (!event.locals) {
21
+ event.locals = event.request ? getRequestLocals(event.request) : {};
22
+ }
23
+ let id = 0;
24
+ let rid = 0;
25
+ let scope = null;
26
+ const scopeCounters = /* @__PURE__ */ new Map();
27
+ const islandCounts = /* @__PURE__ */ new Map();
28
+ return {
29
+ event,
30
+ routeData: /* @__PURE__ */ new Map(),
31
+ matchedRoute: /* @__PURE__ */ new Map(),
32
+ nextId: () => `s${id++}`,
33
+ nextResourceId: () => {
34
+ if (scope === null) return `r${rid++}`;
35
+ const n = scopeCounters.get(scope) ?? 0;
36
+ scopeCounters.set(scope, n + 1);
37
+ return `${scope}:r${n}`;
38
+ },
39
+ nextIslandNamespace: (name) => {
40
+ const n = islandCounts.get(name) ?? 0;
41
+ islandCounts.set(name, n + 1);
42
+ return `${name}#${n}`;
43
+ },
44
+ withResourceScope(ns, fn) {
45
+ const prev = scope;
46
+ scope = ns;
47
+ try {
48
+ return fn();
49
+ } finally {
50
+ scope = prev;
51
+ }
52
+ },
53
+ pending: /* @__PURE__ */ new Set(),
54
+ data: /* @__PURE__ */ new Map()
55
+ };
56
+ }
57
+ function runWithRequestContext(ctx, fn) {
58
+ return _store.run(ctx, fn);
59
+ }
60
+ function getRequestContext() {
61
+ return _store.getStore();
62
+ }
63
+ function getRequestEvent() {
64
+ return getRequestContext()?.event;
65
+ }
66
+ function getLocals() {
67
+ const event = getRequestEvent();
68
+ if (!event) return {};
69
+ if (!event.locals) event.locals = {};
70
+ return event.locals;
71
+ }
72
+ var _requestLocals = /* @__PURE__ */ new WeakMap();
73
+ function getRequestLocals(request) {
74
+ let bag = _requestLocals.get(request);
75
+ if (!bag) {
76
+ bag = {};
77
+ _requestLocals.set(request, bag);
78
+ }
79
+ return bag;
80
+ }
81
+ export {
82
+ createRequestContext,
83
+ getLocals,
84
+ getRequestContext,
85
+ getRequestEvent,
86
+ getRequestLocals,
87
+ runWithRequestContext,
88
+ setRequestStore
89
+ };
@@ -1 +1,187 @@
1
- "use strict";var o=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var b=(t,e)=>{for(var r in e)o(t,r,{get:e[r],enumerable:!0})},x=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of T(e))!y.call(t,s)&&s!==r&&o(t,s,{get:()=>e[s],enumerable:!(n=v(e,s))||n.enumerable});return t};var S=t=>x(o({},"__esModule",{value:!0}),t);var O={};b(O,{serializeNode:()=>i});module.exports=S(O);var a=Symbol.for("fluixi.server-node");var c=1,h=3,p=8,d;d=a;var u=class{constructor(){this[d]=!0;this.parentNode=null;this.childNodes=[]}get firstChild(){return this.childNodes[0]??null}get lastChild(){return this.childNodes[this.childNodes.length-1]??null}get nextSibling(){let e=this.parentNode;if(!e)return null;let r=e.childNodes.indexOf(this);return r>=0?e.childNodes[r+1]??null:null}get previousSibling(){let e=this.parentNode;if(!e)return null;let r=e.childNodes.indexOf(this);return r>0?e.childNodes[r-1]??null:null}get parentElement(){return this.parentNode}appendChild(e){return e.parentNode&&e.parentNode.removeChild(e),e.parentNode=this,this.childNodes.push(e),e}insertBefore(e,r){if(r==null)return this.appendChild(e);e.parentNode&&e.parentNode.removeChild(e);let n=this.childNodes.indexOf(r);return e.parentNode=this,n<0?this.childNodes.push(e):this.childNodes.splice(n,0,e),e}removeChild(e){let r=this.childNodes.indexOf(e);return r>=0&&this.childNodes.splice(r,1),e.parentNode=null,e}replaceChild(e,r){let n=this.childNodes.indexOf(r);return n>=0&&(e.parentNode&&e.parentNode.removeChild(e),e.parentNode=this,this.childNodes[n]=e,r.parentNode=null),r}addEventListener(){}removeEventListener(){}};var w=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),f=/&/g,N=/</g,m=/>/g,E=/"/g;function l(t){return t.replace(f,"&amp;").replace(N,"&lt;").replace(m,"&gt;")}function g(t){return t.replace(f,"&amp;").replace(E,"&quot;").replace(N,"&lt;").replace(m,"&gt;")}function A(t){return t.startsWith("--")?t:t.replace(/[A-Z]/g,e=>"-"+e.toLowerCase())}function M(t){if(!t)return"";let e=[];t.cssText&&e.push(t.cssText.trim().replace(/;\s*$/,""));for(let r of Object.keys(t)){if(r==="cssText")continue;let n=t[r];n==null||n===""||e.push(`${A(r)}: ${n}`)}return e.join("; ")}function C(t){let e="",r=M(t.style);for(let[n,s]of t.attributes)n==="style"&&r||(e+=` ${n}="${g(s)}"`);if(r){let n=t.attributes.get("style"),s=n?`${n.replace(/;\s*$/,"")}; ${r}`:r;e+=` style="${g(s)}"`}return e}function i(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string")return l(t);if(typeof t=="number")return l(String(t));if(typeof t=="function")return i(t());if(Array.isArray(t))return t.map(i).join("");if(typeof t.rawOuterHTML=="string")return t.rawOuterHTML;switch(t.nodeType){case h:return l(t.data??"");case p:return`<!--${t.data??""}-->`;case c:{let e=t.localName,r=`<${e}${C(t)}>`;if(w.has(e))return r;let n=t.rawHTML!=null?t.rawHTML:(t.childNodes??[]).map(i).join("");return`${r}${n}</${e}>`}}return Array.isArray(t.childNodes)?t.childNodes.map(i).join(""):""}
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/dom/server/serialize.ts
21
+ var serialize_exports = {};
22
+ __export(serialize_exports, {
23
+ serializeNode: () => serializeNode
24
+ });
25
+ module.exports = __toCommonJS(serialize_exports);
26
+
27
+ // src/lib/dom/server/host.ts
28
+ var SERVER_NODE = /* @__PURE__ */ Symbol.for("fluixi.server-node");
29
+ var STATE = /* @__PURE__ */ Symbol.for("fluixi.dom.server-host");
30
+ var realm = globalThis;
31
+ var state = realm[STATE] ??= {
32
+ server: typeof document === "undefined",
33
+ nodes: null
34
+ };
35
+
36
+ // src/lib/dom/server/nodes.ts
37
+ var NODE_ELEMENT = 1;
38
+ var NODE_TEXT = 3;
39
+ var NODE_COMMENT = 8;
40
+ var _a;
41
+ _a = SERVER_NODE;
42
+ var ServerNode = class {
43
+ constructor() {
44
+ // Brand the host.ts guards check for (lets them skip an instanceof on these classes).
45
+ this[_a] = true;
46
+ this.parentNode = null;
47
+ this.childNodes = [];
48
+ }
49
+ get firstChild() {
50
+ return this.childNodes[0] ?? null;
51
+ }
52
+ get lastChild() {
53
+ return this.childNodes[this.childNodes.length - 1] ?? null;
54
+ }
55
+ get nextSibling() {
56
+ const p = this.parentNode;
57
+ if (!p) return null;
58
+ const i = p.childNodes.indexOf(this);
59
+ return i >= 0 ? p.childNodes[i + 1] ?? null : null;
60
+ }
61
+ get previousSibling() {
62
+ const p = this.parentNode;
63
+ if (!p) return null;
64
+ const i = p.childNodes.indexOf(this);
65
+ return i > 0 ? p.childNodes[i - 1] ?? null : null;
66
+ }
67
+ get parentElement() {
68
+ return this.parentNode;
69
+ }
70
+ appendChild(child) {
71
+ if (child.parentNode) child.parentNode.removeChild(child);
72
+ child.parentNode = this;
73
+ this.childNodes.push(child);
74
+ return child;
75
+ }
76
+ insertBefore(child, ref) {
77
+ if (ref == null) return this.appendChild(child);
78
+ if (child.parentNode) child.parentNode.removeChild(child);
79
+ const i = this.childNodes.indexOf(ref);
80
+ child.parentNode = this;
81
+ if (i < 0) this.childNodes.push(child);
82
+ else this.childNodes.splice(i, 0, child);
83
+ return child;
84
+ }
85
+ removeChild(child) {
86
+ const i = this.childNodes.indexOf(child);
87
+ if (i >= 0) this.childNodes.splice(i, 1);
88
+ child.parentNode = null;
89
+ return child;
90
+ }
91
+ replaceChild(next, old) {
92
+ const i = this.childNodes.indexOf(old);
93
+ if (i >= 0) {
94
+ if (next.parentNode) next.parentNode.removeChild(next);
95
+ next.parentNode = this;
96
+ this.childNodes[i] = next;
97
+ old.parentNode = null;
98
+ }
99
+ return old;
100
+ }
101
+ // Event listeners are inert on the server.
102
+ addEventListener() {
103
+ }
104
+ removeEventListener() {
105
+ }
106
+ };
107
+
108
+ // src/lib/dom/server/serialize.ts
109
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
110
+ "area",
111
+ "base",
112
+ "br",
113
+ "col",
114
+ "embed",
115
+ "hr",
116
+ "img",
117
+ "input",
118
+ "link",
119
+ "meta",
120
+ "param",
121
+ "source",
122
+ "track",
123
+ "wbr"
124
+ ]);
125
+ var AMP = /&/g;
126
+ var LT = /</g;
127
+ var GT = />/g;
128
+ var QUOT = /"/g;
129
+ function escapeText(s) {
130
+ return s.replace(AMP, "&amp;").replace(LT, "&lt;").replace(GT, "&gt;");
131
+ }
132
+ function escapeAttr(s) {
133
+ return s.replace(AMP, "&amp;").replace(QUOT, "&quot;").replace(LT, "&lt;").replace(GT, "&gt;");
134
+ }
135
+ function camelToKebab(k) {
136
+ if (k.startsWith("--")) return k;
137
+ return k.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
138
+ }
139
+ function serializeStyle(style) {
140
+ if (!style) return "";
141
+ const parts = [];
142
+ if (style.cssText) parts.push(style.cssText.trim().replace(/;\s*$/, ""));
143
+ for (const key of Object.keys(style)) {
144
+ if (key === "cssText") continue;
145
+ const v = style[key];
146
+ if (v == null || v === "") continue;
147
+ parts.push(`${camelToKebab(key)}: ${v}`);
148
+ }
149
+ return parts.join("; ");
150
+ }
151
+ function serializeAttrs(el) {
152
+ let out = "";
153
+ const inlineStyle = serializeStyle(el.style);
154
+ for (const [name, value] of el.attributes) {
155
+ if (name === "style" && inlineStyle) continue;
156
+ out += ` ${name}="${escapeAttr(value)}"`;
157
+ }
158
+ if (inlineStyle) {
159
+ const attrStyle = el.attributes.get("style");
160
+ const merged = attrStyle ? `${attrStyle.replace(/;\s*$/, "")}; ${inlineStyle}` : inlineStyle;
161
+ out += ` style="${escapeAttr(merged)}"`;
162
+ }
163
+ return out;
164
+ }
165
+ function serializeNode(node) {
166
+ if (node == null || node === false || node === true) return "";
167
+ if (typeof node === "string") return escapeText(node);
168
+ if (typeof node === "number") return escapeText(String(node));
169
+ if (typeof node === "function") return serializeNode(node());
170
+ if (Array.isArray(node)) return node.map(serializeNode).join("");
171
+ if (typeof node.rawOuterHTML === "string") return node.rawOuterHTML;
172
+ switch (node.nodeType) {
173
+ case NODE_TEXT:
174
+ return escapeText(node.data ?? "");
175
+ case NODE_COMMENT:
176
+ return `<!--${node.data ?? ""}-->`;
177
+ case NODE_ELEMENT: {
178
+ const tag = node.localName;
179
+ const open = `<${tag}${serializeAttrs(node)}>`;
180
+ if (VOID_ELEMENTS.has(tag)) return open;
181
+ const inner = node.rawHTML != null ? node.rawHTML : (node.childNodes ?? []).map(serializeNode).join("");
182
+ return `${open}${inner}</${tag}>`;
183
+ }
184
+ }
185
+ if (Array.isArray(node.childNodes)) return node.childNodes.map(serializeNode).join("");
186
+ return "";
187
+ }
@@ -50,7 +50,7 @@ function serializeStyle(style) {
50
50
  function serializeAttrs(el) {
51
51
  let out = '';
52
52
  // style comes from the style object, not the attribute map, unless set as a
53
- // plain attribute string (setStyle uses cssText; spread style="..." cssText).
53
+ // plain attribute string (setStyle uses cssText; spread style="..." -> cssText).
54
54
  const inlineStyle = serializeStyle(el.style);
55
55
  for (const [name, value] of el.attributes) {
56
56
  if (name === 'style' && inlineStyle)
@@ -78,7 +78,7 @@ export function serializeNode(node) {
78
78
  return serializeNode(node());
79
79
  if (Array.isArray(node))
80
80
  return node.map(serializeNode).join('');
81
- // A template subtree carried as text written out untouched.
81
+ // A template subtree carried as text: written out untouched.
82
82
  if (typeof node.rawOuterHTML === 'string')
83
83
  return node.rawOuterHTML;
84
84
  // Duck-type on nodeType rather than `instanceof`: a node can come from a
@@ -103,6 +103,6 @@ export function serializeNode(node) {
103
103
  // Any other node-like value with children (fragments etc.).
104
104
  if (Array.isArray(node.childNodes))
105
105
  return node.childNodes.map(serializeNode).join('');
106
- // Unknown value (e.g. a stray object) render nothing rather than [object].
106
+ // Unknown value (e.g. a stray object): render nothing rather than [object].
107
107
  return '';
108
108
  }