@fluixi/core 1.0.0-alpha.53

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 (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +611 -0
  3. package/dist/cdn/core.global.js +3 -0
  4. package/dist/cli/generate.cjs +1814 -0
  5. package/dist/cli/generate.d.ts +7 -0
  6. package/dist/cli/generate.d.ts.map +1 -0
  7. package/dist/cli/generate.js +2580 -0
  8. package/dist/cli/generate.mjs +1814 -0
  9. package/dist/cli/index.cjs +1814 -0
  10. package/dist/cli/index.d.ts +7 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +2580 -0
  13. package/dist/cli/index.mjs +1814 -0
  14. package/dist/cli/run.cjs +2 -0
  15. package/dist/cli/run.d.ts +3 -0
  16. package/dist/cli/run.d.ts.map +1 -0
  17. package/dist/cli/run.js +62 -0
  18. package/dist/cli/run.mjs +2 -0
  19. package/dist/fluixi.d.ts +5 -0
  20. package/dist/src/cdn/chunk-PFM5O5UE.mjs +1 -0
  21. package/dist/src/cdn/core.cjs +1 -0
  22. package/dist/src/cdn/core.d.ts +16 -0
  23. package/dist/src/cdn/core.d.ts.map +1 -0
  24. package/dist/src/cdn/core.js +15 -0
  25. package/dist/src/cdn/core.mjs +1 -0
  26. package/dist/src/cdn/router-next-WNWCFVC2.mjs +1 -0
  27. package/dist/src/index.cjs +1 -0
  28. package/dist/src/index.d.ts +7 -0
  29. package/dist/src/index.d.ts.map +1 -0
  30. package/dist/src/index.js +26 -0
  31. package/dist/src/index.mjs +1 -0
  32. package/dist/src/jsx-dev-runtime.cjs +1 -0
  33. package/dist/src/jsx-dev-runtime.d.ts +2 -0
  34. package/dist/src/jsx-dev-runtime.d.ts.map +1 -0
  35. package/dist/src/jsx-dev-runtime.js +1 -0
  36. package/dist/src/jsx-dev-runtime.mjs +1 -0
  37. package/dist/src/jsx-runtime.cjs +1 -0
  38. package/dist/src/jsx-runtime.d.ts +7 -0
  39. package/dist/src/jsx-runtime.d.ts.map +1 -0
  40. package/dist/src/jsx-runtime.js +17 -0
  41. package/dist/src/jsx-runtime.mjs +1 -0
  42. package/dist/src/lib/client/chunk-D3VTWVNJ.mjs +1 -0
  43. package/dist/src/lib/client/index.cjs +1 -0
  44. package/dist/src/lib/client/index.d.ts +54 -0
  45. package/dist/src/lib/client/index.d.ts.map +1 -0
  46. package/dist/src/lib/client/index.js +142 -0
  47. package/dist/src/lib/client/index.mjs +1 -0
  48. package/dist/src/lib/client/router-next-UYIYMRJL.mjs +1 -0
  49. package/dist/src/lib/context/context.cjs +1 -0
  50. package/dist/src/lib/context/context.d.ts +337 -0
  51. package/dist/src/lib/context/context.d.ts.map +1 -0
  52. package/dist/src/lib/context/context.js +462 -0
  53. package/dist/src/lib/context/context.mjs +1 -0
  54. package/dist/src/lib/context/index.cjs +1 -0
  55. package/dist/src/lib/context/index.d.ts +3 -0
  56. package/dist/src/lib/context/index.d.ts.map +1 -0
  57. package/dist/src/lib/context/index.js +5 -0
  58. package/dist/src/lib/context/index.mjs +1 -0
  59. package/dist/src/lib/control-flow.cjs +1 -0
  60. package/dist/src/lib/control-flow.d.ts +4 -0
  61. package/dist/src/lib/control-flow.d.ts.map +1 -0
  62. package/dist/src/lib/control-flow.js +1 -0
  63. package/dist/src/lib/control-flow.mjs +1 -0
  64. package/dist/src/lib/core.cjs +1 -0
  65. package/dist/src/lib/core.d.ts +90 -0
  66. package/dist/src/lib/core.d.ts.map +1 -0
  67. package/dist/src/lib/core.js +181 -0
  68. package/dist/src/lib/core.mjs +1 -0
  69. package/dist/src/lib/directives/lit.cjs +1 -0
  70. package/dist/src/lib/directives/lit.d.ts +2 -0
  71. package/dist/src/lib/directives/lit.d.ts.map +1 -0
  72. package/dist/src/lib/directives/lit.js +31 -0
  73. package/dist/src/lib/directives/lit.mjs +0 -0
  74. package/dist/src/lib/env/index.cjs +1 -0
  75. package/dist/src/lib/env/index.d.ts +39 -0
  76. package/dist/src/lib/env/index.d.ts.map +1 -0
  77. package/dist/src/lib/env/index.js +50 -0
  78. package/dist/src/lib/env/index.mjs +1 -0
  79. package/dist/src/lib/i18n/index.cjs +1 -0
  80. package/dist/src/lib/i18n/index.d.ts +79 -0
  81. package/dist/src/lib/i18n/index.d.ts.map +1 -0
  82. package/dist/src/lib/i18n/index.js +127 -0
  83. package/dist/src/lib/i18n/index.mjs +1 -0
  84. package/dist/src/lib/index.cjs +1 -0
  85. package/dist/src/lib/index.d.ts +83 -0
  86. package/dist/src/lib/index.d.ts.map +1 -0
  87. package/dist/src/lib/index.js +147 -0
  88. package/dist/src/lib/index.mjs +1 -0
  89. package/dist/src/lib/isomorphic.cjs +1 -0
  90. package/dist/src/lib/isomorphic.d.ts +69 -0
  91. package/dist/src/lib/isomorphic.d.ts.map +1 -0
  92. package/dist/src/lib/isomorphic.js +92 -0
  93. package/dist/src/lib/isomorphic.mjs +1 -0
  94. package/dist/src/lib/jsx-runtime/index.cjs +1 -0
  95. package/dist/src/lib/jsx-runtime/index.d.ts +13 -0
  96. package/dist/src/lib/jsx-runtime/index.d.ts.map +1 -0
  97. package/dist/src/lib/jsx-runtime/index.js +23 -0
  98. package/dist/src/lib/jsx-runtime/index.mjs +1 -0
  99. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -0
  100. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts +2 -0
  101. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts.map +1 -0
  102. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.js +1 -0
  103. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -0
  104. package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +13 -0
  105. package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +21 -0
  106. package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -0
  107. package/dist/src/lib/plugins/fluixi-routes-plugin.js +102 -0
  108. package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +13 -0
  109. package/dist/src/lib/plugins/index.cjs +13 -0
  110. package/dist/src/lib/plugins/index.d.ts +4 -0
  111. package/dist/src/lib/plugins/index.d.ts.map +1 -0
  112. package/dist/src/lib/plugins/index.js +3 -0
  113. package/dist/src/lib/plugins/index.mjs +13 -0
  114. package/dist/src/lib/plugins/route-codegen.cjs +8 -0
  115. package/dist/src/lib/plugins/route-codegen.d.ts +13 -0
  116. package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -0
  117. package/dist/src/lib/plugins/route-codegen.js +81 -0
  118. package/dist/src/lib/plugins/route-codegen.mjs +8 -0
  119. package/dist/src/lib/plugins/route-scanner.cjs +1 -0
  120. package/dist/src/lib/plugins/route-scanner.d.ts +39 -0
  121. package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -0
  122. package/dist/src/lib/plugins/route-scanner.js +216 -0
  123. package/dist/src/lib/plugins/route-scanner.mjs +1 -0
  124. package/dist/src/lib/plugins/vite.cjs +1 -0
  125. package/dist/src/lib/plugins/vite.d.ts +3 -0
  126. package/dist/src/lib/plugins/vite.d.ts.map +1 -0
  127. package/dist/src/lib/plugins/vite.js +1 -0
  128. package/dist/src/lib/plugins/vite.mjs +1 -0
  129. package/dist/src/lib/render/component.cjs +1 -0
  130. package/dist/src/lib/render/component.d.ts +328 -0
  131. package/dist/src/lib/render/component.d.ts.map +1 -0
  132. package/dist/src/lib/render/component.js +520 -0
  133. package/dist/src/lib/render/component.mjs +1 -0
  134. package/dist/src/lib/render/index.cjs +1 -0
  135. package/dist/src/lib/render/index.d.ts +113 -0
  136. package/dist/src/lib/render/index.d.ts.map +1 -0
  137. package/dist/src/lib/render/index.js +201 -0
  138. package/dist/src/lib/render/index.mjs +1 -0
  139. package/dist/src/lib/render/lazy.cjs +1 -0
  140. package/dist/src/lib/render/lazy.d.ts +28 -0
  141. package/dist/src/lib/render/lazy.d.ts.map +1 -0
  142. package/dist/src/lib/render/lazy.js +62 -0
  143. package/dist/src/lib/render/lazy.mjs +1 -0
  144. package/dist/src/lib/render/suspense.cjs +1 -0
  145. package/dist/src/lib/render/suspense.d.ts +25 -0
  146. package/dist/src/lib/render/suspense.d.ts.map +1 -0
  147. package/dist/src/lib/render/suspense.js +139 -0
  148. package/dist/src/lib/render/suspense.mjs +1 -0
  149. package/dist/src/lib/router-next/data.cjs +1 -0
  150. package/dist/src/lib/router-next/data.d.ts +101 -0
  151. package/dist/src/lib/router-next/data.d.ts.map +1 -0
  152. package/dist/src/lib/router-next/data.js +179 -0
  153. package/dist/src/lib/router-next/data.mjs +1 -0
  154. package/dist/src/lib/router-next/index.cjs +1 -0
  155. package/dist/src/lib/router-next/index.d.ts +156 -0
  156. package/dist/src/lib/router-next/index.d.ts.map +1 -0
  157. package/dist/src/lib/router-next/index.js +464 -0
  158. package/dist/src/lib/router-next/index.mjs +1 -0
  159. package/dist/src/lib/server/hydration.cjs +1 -0
  160. package/dist/src/lib/server/hydration.d.ts +238 -0
  161. package/dist/src/lib/server/hydration.d.ts.map +1 -0
  162. package/dist/src/lib/server/hydration.js +384 -0
  163. package/dist/src/lib/server/hydration.mjs +1 -0
  164. package/dist/src/lib/server/index.cjs +16 -0
  165. package/dist/src/lib/server/index.d.ts +91 -0
  166. package/dist/src/lib/server/index.d.ts.map +1 -0
  167. package/dist/src/lib/server/index.js +141 -0
  168. package/dist/src/lib/server/index.mjs +16 -0
  169. package/dist/src/lib/server/reactive.cjs +1 -0
  170. package/dist/src/lib/server/reactive.d.ts +298 -0
  171. package/dist/src/lib/server/reactive.d.ts.map +1 -0
  172. package/dist/src/lib/server/reactive.js +472 -0
  173. package/dist/src/lib/server/reactive.mjs +1 -0
  174. package/dist/src/lib/theme/index.cjs +1 -0
  175. package/dist/src/lib/theme/index.d.ts +51 -0
  176. package/dist/src/lib/theme/index.d.ts.map +1 -0
  177. package/dist/src/lib/theme/index.js +79 -0
  178. package/dist/src/lib/theme/index.mjs +1 -0
  179. package/dist/src/lib/utils/index.cjs +1 -0
  180. package/dist/src/lib/utils/index.d.ts +379 -0
  181. package/dist/src/lib/utils/index.d.ts.map +1 -0
  182. package/dist/src/lib/utils/index.js +527 -0
  183. package/dist/src/lib/utils/index.mjs +1 -0
  184. package/dist/src/rx.cjs +1 -0
  185. package/dist/src/rx.d.ts +2 -0
  186. package/dist/src/rx.d.ts.map +1 -0
  187. package/dist/src/rx.js +101 -0
  188. package/dist/src/rx.mjs +0 -0
  189. package/dist/src/server.cjs +16 -0
  190. package/dist/src/server.d.ts +64 -0
  191. package/dist/src/server.d.ts.map +1 -0
  192. package/dist/src/server.js +63 -0
  193. package/dist/src/server.mjs +16 -0
  194. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  195. package/package.json +128 -0
  196. package/src/index.ts +31 -0
  197. package/types/fluixi.d.ts +5 -0
  198. package/types/vinxi.d.ts +50 -0
@@ -0,0 +1,238 @@
1
+ /**
2
+ * @fileoverview Hydration utilities for Fluixi
3
+ * @module @fluixi/core/server/hydration
4
+ *
5
+ * Hydration:
6
+ * - DOM reused (no recreation)
7
+ * - No component execution (components ran on server)
8
+ * - Bindings reattached
9
+ * - Structural markers required
10
+ */
11
+ /**
12
+ * Hydration data structure
13
+ */
14
+ export interface HydrationData {
15
+ [key: string]: any;
16
+ }
17
+ /**
18
+ * Check if currently hydrating
19
+ *
20
+ * Section 11: During hydration, DOM is reused, not recreated
21
+ *
22
+ * @returns {boolean} True if hydrating
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { isHydrating } from '@fluixi/core/server';
27
+ *
28
+ * if (isHydrating()) {
29
+ * // Reuse existing DOM
30
+ * }
31
+ * ```
32
+ */
33
+ export declare function isHydrating(): boolean;
34
+ /**
35
+ * Set hydration state
36
+ *
37
+ * @param {boolean} state - Hydration state
38
+ * @internal
39
+ */
40
+ export declare function setHydrating(state: boolean): void;
41
+ /**
42
+ * Store data for hydration
43
+ *
44
+ * Section 11: On server, store data to serialize into HTML
45
+ * On client during hydration, this data is reused
46
+ *
47
+ * @param {string} key - Unique key
48
+ * @param {any} data - Data to store
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { setHydrationData } from '@fluixi/core/server';
53
+ *
54
+ * // On server
55
+ * setHydrationData('user', { id: 1, name: 'Alice' });
56
+ * ```
57
+ */
58
+ export declare function setHydrationData(key: string, data: any): void;
59
+ /**
60
+ * Get hydration data
61
+ *
62
+ * Section 11: On client, retrieve data stored on server
63
+ *
64
+ * @param {string} key - Unique key
65
+ * @returns {any} Data or undefined
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * import { getHydrationData } from '@fluixi/core/server';
70
+ *
71
+ * // On client
72
+ * const user = getHydrationData('user');
73
+ * ```
74
+ */
75
+ export declare function getHydrationData(key: string): any;
76
+ /**
77
+ * Check if hydration data exists
78
+ *
79
+ * @param {string} key - Unique key
80
+ * @returns {boolean} True if exists
81
+ */
82
+ export declare function hasHydrationData(key: string): boolean;
83
+ /**
84
+ * Clear all hydration data
85
+ *
86
+ * @internal
87
+ */
88
+ export declare function clearHydrationData(): void;
89
+ /**
90
+ * Clear specific hydration data
91
+ *
92
+ * @param {string} key - Key to clear
93
+ */
94
+ export declare function clearHydrationDataKey(key: string): void;
95
+ /**
96
+ * Serialize hydration data to script tag
97
+ *
98
+ * Section 11: Embed data in HTML for client hydration
99
+ *
100
+ * @returns {string} Script tag with JSON data
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * import { serializeHydrationData } from '@fluixi/core/server';
105
+ *
106
+ * const html = await renderToString(() => App());
107
+ * const script = serializeHydrationData();
108
+ * return html + script;
109
+ * ```
110
+ */
111
+ export declare function serializeHydrationData(): string;
112
+ /**
113
+ * Deserialize hydration data from DOM
114
+ *
115
+ * Section 11: On client, load data from script tag
116
+ *
117
+ * @returns {boolean} True if data was loaded
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * import { deserializeHydrationData } from '@fluixi/core/server';
122
+ *
123
+ * // On client startup
124
+ * if (deserializeHydrationData()) {
125
+ * console.log('Hydration data loaded');
126
+ * }
127
+ * ```
128
+ */
129
+ export declare function deserializeHydrationData(): boolean;
130
+ /**
131
+ * Generate unique hydration marker ID
132
+ *
133
+ * @returns {string} Unique marker ID
134
+ * @internal
135
+ */
136
+ export declare function generateMarkerID(): string;
137
+ /**
138
+ * Create hydration marker
139
+ *
140
+ * Section 11: Structural markers required for hydration points
141
+ *
142
+ * @param {string} id - Marker ID
143
+ * @returns {string} HTML comment marker
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * import { hydrationMarker } from '@fluixi/core/server';
148
+ *
149
+ * const marker = hydrationMarker('component-1');
150
+ * // Returns: <!--h:component-1-->
151
+ * ```
152
+ */
153
+ export declare function hydrationMarker(id: string): string;
154
+ /**
155
+ * Create start hydration marker
156
+ *
157
+ * @param {string} id - Marker ID
158
+ * @returns {string} Start marker
159
+ */
160
+ export declare function hydrationMarkerStart(id: string): string;
161
+ /**
162
+ * Create end hydration marker
163
+ *
164
+ * @param {string} id - Marker ID
165
+ * @returns {string} End marker
166
+ */
167
+ export declare function hydrationMarkerEnd(id: string): string;
168
+ /**
169
+ * Create hydration-friendly resource
170
+ *
171
+ * Section 11: Resources loaded on server are serialized
172
+ * On client, reused during hydration (no re-fetch)
173
+ *
174
+ * @template T
175
+ * @param {string} key - Unique resource key
176
+ * @param {() => Promise<T>} fetcher - Resource fetcher
177
+ * @returns {() => Promise<T>} Hydration-aware fetcher
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * import { createHydratableResource } from '@fluixi/core/server';
182
+ *
183
+ * const loadUser = createHydratableResource('user', async () => {
184
+ * const res = await fetch('/api/user');
185
+ * return res.json();
186
+ * });
187
+ * ```
188
+ */
189
+ export declare function createHydratableResource<T>(key: string, fetcher: () => Promise<T>): () => Promise<T>;
190
+ /**
191
+ * Use hydration data in component
192
+ *
193
+ * Section 11: Components use hydration data to restore state
194
+ * without re-execution
195
+ *
196
+ * @template T
197
+ * @param {string} key - Data key
198
+ * @param {T | (() => T)} value - Value or getter
199
+ * @returns {T} Value
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * import { useHydrationData } from '@fluixi/core/server';
204
+ *
205
+ * const MyComponent = () => {
206
+ * const data = useHydrationData('my-data', { initial: true });
207
+ * return html`<div>${JSON.stringify(data)}</div>`;
208
+ * };
209
+ * ```
210
+ */
211
+ export declare function useHydrationData<T>(key: string, value: T | (() => T)): T;
212
+ /**
213
+ * Cleanup hydration artifacts from DOM
214
+ *
215
+ * Section 11: After hydration, remove markers and serialized data
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * import { cleanupHydration } from '@fluixi/core/server';
220
+ *
221
+ * // After hydration completes
222
+ * cleanupHydration();
223
+ * ```
224
+ */
225
+ export declare function cleanupHydration(): void;
226
+ /**
227
+ * Check if on server
228
+ *
229
+ * @returns {boolean} True if server
230
+ */
231
+ export declare function isServerEnvironment(): boolean;
232
+ /**
233
+ * Check if on client
234
+ *
235
+ * @returns {boolean} True if client
236
+ */
237
+ export declare function isClientEnvironment(): boolean;
238
+ //# sourceMappingURL=hydration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydration.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/hydration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AA2BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEjD;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,CAE7D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAEjD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvD;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAS/C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAuBlD;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAErD;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EACxC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACxB,MAAM,OAAO,CAAC,CAAC,CAAC,CAoBlB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAiBxE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAiCvC;AAgBD;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C"}
@@ -0,0 +1,384 @@
1
+ /**
2
+ * @fileoverview Hydration utilities for Fluixi
3
+ * @module @fluixi/core/server/hydration
4
+ *
5
+ * Hydration:
6
+ * - DOM reused (no recreation)
7
+ * - No component execution (components ran on server)
8
+ * - Bindings reattached
9
+ * - Structural markers required
10
+ */
11
+ // ============================================================================
12
+ // STATE
13
+ // ============================================================================
14
+ /**
15
+ * Global hydration flag
16
+ * Section 11: Indicates if we're currently hydrating
17
+ */
18
+ let hydrating = false;
19
+ /**
20
+ * Hydration data registry
21
+ * Stores data serialized on server and consumed on client
22
+ */
23
+ const hydrationDataMap = new Map();
24
+ /**
25
+ * Hydration marker counter for unique IDs
26
+ */
27
+ let markerCounter = 0;
28
+ // ============================================================================
29
+ // HYDRATION STATE
30
+ // ============================================================================
31
+ /**
32
+ * Check if currently hydrating
33
+ *
34
+ * Section 11: During hydration, DOM is reused, not recreated
35
+ *
36
+ * @returns {boolean} True if hydrating
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * import { isHydrating } from '@fluixi/core/server';
41
+ *
42
+ * if (isHydrating()) {
43
+ * // Reuse existing DOM
44
+ * }
45
+ * ```
46
+ */
47
+ export function isHydrating() {
48
+ return hydrating;
49
+ }
50
+ /**
51
+ * Set hydration state
52
+ *
53
+ * @param {boolean} state - Hydration state
54
+ * @internal
55
+ */
56
+ export function setHydrating(state) {
57
+ hydrating = state;
58
+ }
59
+ // ============================================================================
60
+ // HYDRATION DATA MANAGEMENT
61
+ // ============================================================================
62
+ /**
63
+ * Store data for hydration
64
+ *
65
+ * Section 11: On server, store data to serialize into HTML
66
+ * On client during hydration, this data is reused
67
+ *
68
+ * @param {string} key - Unique key
69
+ * @param {any} data - Data to store
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * import { setHydrationData } from '@fluixi/core/server';
74
+ *
75
+ * // On server
76
+ * setHydrationData('user', { id: 1, name: 'Alice' });
77
+ * ```
78
+ */
79
+ export function setHydrationData(key, data) {
80
+ hydrationDataMap.set(key, data);
81
+ }
82
+ /**
83
+ * Get hydration data
84
+ *
85
+ * Section 11: On client, retrieve data stored on server
86
+ *
87
+ * @param {string} key - Unique key
88
+ * @returns {any} Data or undefined
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { getHydrationData } from '@fluixi/core/server';
93
+ *
94
+ * // On client
95
+ * const user = getHydrationData('user');
96
+ * ```
97
+ */
98
+ export function getHydrationData(key) {
99
+ return hydrationDataMap.get(key);
100
+ }
101
+ /**
102
+ * Check if hydration data exists
103
+ *
104
+ * @param {string} key - Unique key
105
+ * @returns {boolean} True if exists
106
+ */
107
+ export function hasHydrationData(key) {
108
+ return hydrationDataMap.has(key);
109
+ }
110
+ /**
111
+ * Clear all hydration data
112
+ *
113
+ * @internal
114
+ */
115
+ export function clearHydrationData() {
116
+ hydrationDataMap.clear();
117
+ }
118
+ /**
119
+ * Clear specific hydration data
120
+ *
121
+ * @param {string} key - Key to clear
122
+ */
123
+ export function clearHydrationDataKey(key) {
124
+ hydrationDataMap.delete(key);
125
+ }
126
+ // ============================================================================
127
+ // SERIALIZATION
128
+ // ============================================================================
129
+ /**
130
+ * Serialize hydration data to script tag
131
+ *
132
+ * Section 11: Embed data in HTML for client hydration
133
+ *
134
+ * @returns {string} Script tag with JSON data
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * import { serializeHydrationData } from '@fluixi/core/server';
139
+ *
140
+ * const html = await renderToString(() => App());
141
+ * const script = serializeHydrationData();
142
+ * return html + script;
143
+ * ```
144
+ */
145
+ export function serializeHydrationData() {
146
+ if (hydrationDataMap.size === 0) {
147
+ return '';
148
+ }
149
+ const data = Object.fromEntries(hydrationDataMap);
150
+ const json = JSON.stringify(data);
151
+ return `<script type="application/json" id="__FLUIXI_HYDRATION__">${json}</script>`;
152
+ }
153
+ /**
154
+ * Deserialize hydration data from DOM
155
+ *
156
+ * Section 11: On client, load data from script tag
157
+ *
158
+ * @returns {boolean} True if data was loaded
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * import { deserializeHydrationData } from '@fluixi/core/server';
163
+ *
164
+ * // On client startup
165
+ * if (deserializeHydrationData()) {
166
+ * console.log('Hydration data loaded');
167
+ * }
168
+ * ```
169
+ */
170
+ export function deserializeHydrationData() {
171
+ if (typeof window === 'undefined') {
172
+ return false;
173
+ }
174
+ const script = document.getElementById('__FLUIXI_HYDRATION__');
175
+ if (!script || script.getAttribute('type') !== 'application/json') {
176
+ return false;
177
+ }
178
+ try {
179
+ const json = script.textContent || '{}';
180
+ const data = JSON.parse(json);
181
+ for (const [key, value] of Object.entries(data)) {
182
+ hydrationDataMap.set(key, value);
183
+ }
184
+ return true;
185
+ }
186
+ catch (error) {
187
+ console.error('Failed to deserialize hydration data:', error);
188
+ return false;
189
+ }
190
+ }
191
+ // ============================================================================
192
+ // HYDRATION MARKERS
193
+ // ============================================================================
194
+ /**
195
+ * Generate unique hydration marker ID
196
+ *
197
+ * @returns {string} Unique marker ID
198
+ * @internal
199
+ */
200
+ export function generateMarkerID() {
201
+ return `h${markerCounter++}`;
202
+ }
203
+ /**
204
+ * Create hydration marker
205
+ *
206
+ * Section 11: Structural markers required for hydration points
207
+ *
208
+ * @param {string} id - Marker ID
209
+ * @returns {string} HTML comment marker
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * import { hydrationMarker } from '@fluixi/core/server';
214
+ *
215
+ * const marker = hydrationMarker('component-1');
216
+ * // Returns: <!--h:component-1-->
217
+ * ```
218
+ */
219
+ export function hydrationMarker(id) {
220
+ return `<!--#${id}-->`;
221
+ }
222
+ /**
223
+ * Create start hydration marker
224
+ *
225
+ * @param {string} id - Marker ID
226
+ * @returns {string} Start marker
227
+ */
228
+ export function hydrationMarkerStart(id) {
229
+ return `<!--#${id}-->`;
230
+ }
231
+ /**
232
+ * Create end hydration marker
233
+ *
234
+ * @param {string} id - Marker ID
235
+ * @returns {string} End marker
236
+ */
237
+ export function hydrationMarkerEnd(id) {
238
+ return `<!--/${id}-->`;
239
+ }
240
+ // ============================================================================
241
+ // RESOURCE HYDRATION
242
+ // ============================================================================
243
+ /**
244
+ * Create hydration-friendly resource
245
+ *
246
+ * Section 11: Resources loaded on server are serialized
247
+ * On client, reused during hydration (no re-fetch)
248
+ *
249
+ * @template T
250
+ * @param {string} key - Unique resource key
251
+ * @param {() => Promise<T>} fetcher - Resource fetcher
252
+ * @returns {() => Promise<T>} Hydration-aware fetcher
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * import { createHydratableResource } from '@fluixi/core/server';
257
+ *
258
+ * const loadUser = createHydratableResource('user', async () => {
259
+ * const res = await fetch('/api/user');
260
+ * return res.json();
261
+ * });
262
+ * ```
263
+ */
264
+ export function createHydratableResource(key, fetcher) {
265
+ return async () => {
266
+ // Section 11: During hydration or on client, check for cached data
267
+ if (isHydrating() || typeof window !== 'undefined') {
268
+ const cached = getHydrationData(key);
269
+ if (cached !== undefined) {
270
+ return cached;
271
+ }
272
+ }
273
+ // Server or no cache: fetch data
274
+ const data = await fetcher();
275
+ // Section 11: On server, store for serialization
276
+ if (typeof window === 'undefined') {
277
+ setHydrationData(key, data);
278
+ }
279
+ return data;
280
+ };
281
+ }
282
+ /**
283
+ * Use hydration data in component
284
+ *
285
+ * Section 11: Components use hydration data to restore state
286
+ * without re-execution
287
+ *
288
+ * @template T
289
+ * @param {string} key - Data key
290
+ * @param {T | (() => T)} value - Value or getter
291
+ * @returns {T} Value
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * import { useHydrationData } from '@fluixi/core/server';
296
+ *
297
+ * const MyComponent = () => {
298
+ * const data = useHydrationData('my-data', { initial: true });
299
+ * return html`<div>${JSON.stringify(data)}</div>`;
300
+ * };
301
+ * ```
302
+ */
303
+ export function useHydrationData(key, value) {
304
+ // Section 11: Check for hydration data first
305
+ const hydrationData = getHydrationData(key);
306
+ if (hydrationData !== undefined) {
307
+ return hydrationData;
308
+ }
309
+ // Compute or use provided value
310
+ const computedValue = typeof value === 'function' ? value() : value;
311
+ // Section 11: On server, store for serialization
312
+ if (typeof window === 'undefined') {
313
+ setHydrationData(key, computedValue);
314
+ }
315
+ return computedValue;
316
+ }
317
+ // ============================================================================
318
+ // CLEANUP
319
+ // ============================================================================
320
+ /**
321
+ * Cleanup hydration artifacts from DOM
322
+ *
323
+ * Section 11: After hydration, remove markers and serialized data
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * import { cleanupHydration } from '@fluixi/core/server';
328
+ *
329
+ * // After hydration completes
330
+ * cleanupHydration();
331
+ * ```
332
+ */
333
+ export function cleanupHydration() {
334
+ if (typeof window === 'undefined') {
335
+ return;
336
+ }
337
+ // Remove hydration data script
338
+ const script = document.getElementById('__FLUIXI_HYDRATION__');
339
+ if (script) {
340
+ script.remove();
341
+ }
342
+ // Remove hydration markers (comments)
343
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_COMMENT, null);
344
+ const comments = [];
345
+ let node;
346
+ while ((node = walker.nextNode())) {
347
+ const comment = node;
348
+ const text = comment.nodeValue || '';
349
+ if (text.startsWith('#') || text.startsWith('/')) {
350
+ comments.push(comment);
351
+ }
352
+ }
353
+ comments.forEach((comment) => comment.remove());
354
+ // Clear hydration data from memory
355
+ clearHydrationData();
356
+ }
357
+ /**
358
+ * Auto-cleanup hydration on page load (client-side)
359
+ */
360
+ if (typeof window !== 'undefined') {
361
+ window.addEventListener('load', () => {
362
+ // Delay cleanup to ensure hydration is complete
363
+ setTimeout(cleanupHydration, 100);
364
+ });
365
+ }
366
+ // ============================================================================
367
+ // ENVIRONMENT HELPERS
368
+ // ============================================================================
369
+ /**
370
+ * Check if on server
371
+ *
372
+ * @returns {boolean} True if server
373
+ */
374
+ export function isServerEnvironment() {
375
+ return typeof window === 'undefined';
376
+ }
377
+ /**
378
+ * Check if on client
379
+ *
380
+ * @returns {boolean} True if client
381
+ */
382
+ export function isClientEnvironment() {
383
+ return typeof window !== 'undefined';
384
+ }
@@ -0,0 +1 @@
1
+ var d=!1,o=new Map,c=0;function f(){return d}function l(t){d=t}function s(t,n){o.set(t,n)}function u(t){return o.get(t)}function g(t){return o.has(t)}function p(){o.clear()}function m(t){o.delete(t)}function w(){if(o.size===0)return"";let t=Object.fromEntries(o);return`<script type="application/json" id="__FLUIXI_HYDRATION__">${JSON.stringify(t)}<\/script>`}function x(){if(typeof window>"u")return!1;let t=document.getElementById("__FLUIXI_HYDRATION__");if(!t||t.getAttribute("type")!=="application/json")return!1;try{let n=t.textContent||"{}",e=JSON.parse(n);for(let[r,i]of Object.entries(e))o.set(r,i);return!0}catch(n){return console.error("Failed to deserialize hydration data:",n),!1}}function h(){return`h${c++}`}function H(t){return`<!--#${t}-->`}function T(t){return`<!--#${t}-->`}function _(t){return`<!--/${t}-->`}function D(t,n){return async()=>{if(f()||typeof window<"u"){let r=u(t);if(r!==void 0)return r}let e=await n();return typeof window>"u"&&s(t,e),e}}function I(t,n){let e=u(t);if(e!==void 0)return e;let r=typeof n=="function"?n():n;return typeof window>"u"&&s(t,r),r}function y(){if(typeof window>"u")return;let t=document.getElementById("__FLUIXI_HYDRATION__");t&&t.remove();let n=document.createTreeWalker(document.body,NodeFilter.SHOW_COMMENT,null),e=[],r;for(;r=n.nextNode();){let i=r,a=i.nodeValue||"";(a.startsWith("#")||a.startsWith("/"))&&e.push(i)}e.forEach(i=>i.remove()),p()}typeof window<"u"&&window.addEventListener("load",()=>{setTimeout(y,100)});function b(){return typeof window>"u"}function v(){return typeof window<"u"}export{y as cleanupHydration,p as clearHydrationData,m as clearHydrationDataKey,D as createHydratableResource,x as deserializeHydrationData,h as generateMarkerID,u as getHydrationData,g as hasHydrationData,H as hydrationMarker,_ as hydrationMarkerEnd,T as hydrationMarkerStart,v as isClientEnvironment,f as isHydrating,b as isServerEnvironment,w as serializeHydrationData,l as setHydrating,s as setHydrationData,I as useHydrationData};
@@ -0,0 +1,16 @@
1
+ "use strict";var T=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var ct=Object.getOwnPropertyNames;var ut=Object.prototype.hasOwnProperty;var dt=(t,e)=>{for(var n in e)T(t,n,{get:e[n],enumerable:!0})},lt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of ct(e))!ut.call(t,o)&&o!==n&&T(t,o,{get:()=>e[o],enumerable:!(r=st(e,o))||r.enumerable});return t};var pt=t=>lt(T({},"__esModule",{value:!0}),t);var mt={};dt(mt,{batch:()=>I,cleanupHydration:()=>S,clearHydrationData:()=>g,clearHydrationDataKey:()=>H,createComputed:()=>P,createContext:()=>U,createDeferred:()=>X,createEffect:()=>f,createHtmlDocument:()=>tt,createHydratableResource:()=>k,createMemo:()=>m,createRenderEffect:()=>V,createResource:()=>J,createRoot:()=>F,createSelector:()=>B,createSignal:()=>K,deserializeHydrationData:()=>b,getHydrationData:()=>d,getOwner:()=>W,getSSRContext:()=>ft,hasHydrationData:()=>R,hydrationMarker:()=>O,hydrationMarkerEnd:()=>A,hydrationMarkerStart:()=>E,isClient:()=>nt,isClientEnvironment:()=>M,isClientReactive:()=>Q,isHydrating:()=>x,isServer:()=>et,isServerEnvironment:()=>j,isServerReactive:()=>G,onCleanup:()=>z,onClient:()=>gt,onServer:()=>xt,renderToPage:()=>Z,renderToStream:()=>rt,renderToString:()=>h,runWithOwner:()=>L,serializeHydrationData:()=>l,setHydrating:()=>D,setHydrationData:()=>u,setSSRContext:()=>yt,startServer:()=>St,startTransition:()=>q,untrack:()=>N,useContext:()=>Y,useHydrationData:()=>_,withSSRContext:()=>Tt});module.exports=pt(mt);var C=!1,a=new Map;function x(){return C}function D(t){C=t}function u(t,e){a.set(t,e)}function d(t){return a.get(t)}function R(t){return a.has(t)}function g(){a.clear()}function H(t){a.delete(t)}function l(){if(a.size===0)return"";let t=Object.fromEntries(a);return`<script type="application/json" id="__FLUIXI_HYDRATION__">${JSON.stringify(t)}<\/script>`}function b(){if(typeof window>"u")return!1;let t=document.getElementById("__FLUIXI_HYDRATION__");if(!t||t.getAttribute("type")!=="application/json")return!1;try{let e=t.textContent||"{}",n=JSON.parse(e);for(let[r,o]of Object.entries(n))a.set(r,o);return!0}catch(e){return console.error("Failed to deserialize hydration data:",e),!1}}function O(t){return`<!--#${t}-->`}function E(t){return`<!--#${t}-->`}function A(t){return`<!--/${t}-->`}function k(t,e){return async()=>{if(x()||typeof window<"u"){let r=d(t);if(r!==void 0)return r}let n=await e();return typeof window>"u"&&u(t,n),n}}function _(t,e){let n=d(t);if(n!==void 0)return n;let r=typeof e=="function"?e():e;return typeof window>"u"&&u(t,r),r}function S(){if(typeof window>"u")return;let t=document.getElementById("__FLUIXI_HYDRATION__");t&&t.remove();let e=document.createTreeWalker(document.body,NodeFilter.SHOW_COMMENT,null),n=[],r;for(;r=e.nextNode();){let o=r,i=o.nodeValue||"";(i.startsWith("#")||i.startsWith("/"))&&n.push(o)}n.forEach(o=>o.remove()),g()}typeof window<"u"&&window.addEventListener("load",()=>{setTimeout(S,100)});function j(){return typeof window>"u"}function M(){return typeof window<"u"}var v=require("@fluixi/server");function K(t,e){let n=t;return[(()=>n),i=>(typeof i=="function"?n=i(n):n=i,n)]}function f(t,e,n){try{t(e)}catch(r){console.error("[Fluixi Server] Effect error:",r)}return{dispose:()=>{}}}function m(t,e,n){let r=t(e);return(()=>r)}function F(t){let e=[],n=()=>{e.forEach(r=>{try{r()}catch(o){console.error("[Fluixi Server] Cleanup error:",o)}}),e.length=0};try{return t(n)}catch(r){throw n(),r}}function I(t){return t()}function N(t){return t()}var $=null;function z(t){$&&$.push(t)}var p=null;function W(){return p}function L(t,e){let n=p;p=t;try{return e()}finally{p=n}}var s=new Map;function U(t){let e=Symbol("context");return{id:e,Provider:r=>{let o=s.get(e);s.set(e,r.value);try{return r.children}finally{o!==void 0?s.set(e,o):s.delete(e)}},defaultValue:t}}function Y(t){let e=s.get(t.id);return e!==void 0?e:t.defaultValue}function P(t){return f(t)}function V(t){return f(t)}function X(t){return m(t)}function B(t){let e=t();return n=>n===e}function J(t,e,n){return[()=>{},{mutate:r=>r,refetch:()=>{}}]}function q(t){t()}var G=!0,Q=!1;var c=null;function ft(){return c}function yt(t){c=t}function Tt(t,e){let n=c;c=t;try{return e()}finally{c=n}}async function Z(t,e={}){let n=await h(t);return tt(n,e)}function tt(t,e={}){let{title:n="Fluixi App",lang:r="en",stylesheets:o=[],scripts:i=[],head:ot="",bodyAttributes:w=""}=e,it=o.map(y=>`<link rel="stylesheet" href="${y}">`).join(`
2
+ `),at=i.map(y=>`<script type="module" src="${y}"><\/script>`).join(`
3
+ `);return`<!DOCTYPE html>
4
+ <html lang="${r}">
5
+ <head>
6
+ <meta charset="UTF-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <title>${n}</title>
9
+ ${it}
10
+ ${ot}
11
+ </head>
12
+ <body${w?" "+w:""}>
13
+ ${t}
14
+ ${at}
15
+ </body>
16
+ </html>`}function et(){return typeof window>"u"}function nt(){return typeof window<"u"}function xt(t,e){return et()?t():e}function gt(t,e){return nt()?t():e}async function h(t){let e=await(0,v.renderToString)(t),n=l();return e+n}async function rt(t){let e=await(0,v.renderToString)(t),n=l();return e+n}function St(t){return{render:e=>h(()=>t({url:e})),stream:e=>rt(()=>t({url:e})),page:(e,n)=>Z(()=>t({url:e}),n)}}