pulse-js-framework 1.7.32 → 1.7.37

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.
package/types/ssr.d.ts ADDED
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Pulse Framework - SSR (Server-Side Rendering) Type Definitions
3
+ * @module pulse-js-framework/runtime/ssr
4
+ */
5
+
6
+ // ============================================================================
7
+ // Options and Result Interfaces
8
+ // ============================================================================
9
+
10
+ /**
11
+ * Options for renderToString
12
+ */
13
+ export interface RenderToStringOptions {
14
+ /** Wait for async operations before rendering (default: true) */
15
+ waitForAsync?: boolean;
16
+
17
+ /** Timeout for async operations in ms (default: 5000) */
18
+ timeout?: number;
19
+
20
+ /** Include state in result (default: true) */
21
+ serializeState?: boolean;
22
+ }
23
+
24
+ /**
25
+ * Result returned by renderToString
26
+ */
27
+ export interface RenderResult {
28
+ /** Rendered HTML string */
29
+ html: string;
30
+
31
+ /** Serialized state (null if serializeState is false) */
32
+ state: Record<string, unknown> | null;
33
+ }
34
+
35
+ /**
36
+ * Options for hydrate
37
+ */
38
+ export interface HydrateOptions {
39
+ /** Server state to restore */
40
+ state?: unknown;
41
+
42
+ /**
43
+ * Callback when hydration mismatch detected.
44
+ * @param expected - What was expected in the DOM
45
+ * @param actual - What was found in the DOM
46
+ */
47
+ onMismatch?: (expected: string, actual: string) => void;
48
+ }
49
+
50
+ // ============================================================================
51
+ // SSR Mode
52
+ // ============================================================================
53
+
54
+ /**
55
+ * Check if currently in SSR mode.
56
+ * Use this to conditionally skip browser-only code.
57
+ *
58
+ * @returns True if running in SSR mode
59
+ *
60
+ * @example
61
+ * import { isSSR } from 'pulse-js-framework/runtime/ssr';
62
+ *
63
+ * effect(() => {
64
+ * if (isSSR()) return; // Skip on server
65
+ * window.addEventListener('resize', handleResize);
66
+ * return () => window.removeEventListener('resize', handleResize);
67
+ * });
68
+ */
69
+ export declare function isSSR(): boolean;
70
+
71
+ /**
72
+ * Set SSR mode (internal use).
73
+ * @param enabled - Whether to enable SSR mode
74
+ * @internal
75
+ */
76
+ export declare function setSSRMode(enabled: boolean): void;
77
+
78
+ // ============================================================================
79
+ // Server-Side Rendering
80
+ // ============================================================================
81
+
82
+ /**
83
+ * Render a component tree to an HTML string.
84
+ *
85
+ * Creates an isolated reactive context and renders the component using
86
+ * MockDOMAdapter, then serializes the result to HTML.
87
+ *
88
+ * @param componentFactory - Function that returns the root component
89
+ * @param options - Rendering options
90
+ * @returns Rendered HTML and optional state
91
+ *
92
+ * @example
93
+ * // Basic rendering
94
+ * const { html } = await renderToString(() => App());
95
+ *
96
+ * @example
97
+ * // With async data fetching
98
+ * const { html, state } = await renderToString(() => App(), {
99
+ * waitForAsync: true,
100
+ * timeout: 10000,
101
+ * serializeState: true
102
+ * });
103
+ */
104
+ export declare function renderToString(
105
+ componentFactory: () => unknown,
106
+ options?: RenderToStringOptions
107
+ ): Promise<RenderResult>;
108
+
109
+ /**
110
+ * Render to string synchronously (no async data waiting).
111
+ * Use this when you don't need to wait for async operations.
112
+ *
113
+ * @param componentFactory - Function that returns the root component
114
+ * @returns Rendered HTML string
115
+ *
116
+ * @example
117
+ * const html = renderToStringSync(() => StaticPage());
118
+ */
119
+ export declare function renderToStringSync(
120
+ componentFactory: () => unknown
121
+ ): string;
122
+
123
+ // ============================================================================
124
+ // Client-Side Hydration
125
+ // ============================================================================
126
+
127
+ /**
128
+ * Hydrate server-rendered HTML by attaching event listeners and
129
+ * connecting to the reactive system.
130
+ *
131
+ * @param target - CSS selector or DOM element
132
+ * @param componentFactory - Function that returns the root component
133
+ * @param options - Hydration options
134
+ * @returns Cleanup function to dispose hydration
135
+ *
136
+ * @example
137
+ * // Basic hydration
138
+ * const dispose = hydrate('#app', () => App());
139
+ *
140
+ * // Later, if needed:
141
+ * dispose();
142
+ *
143
+ * @example
144
+ * // With state restoration
145
+ * hydrate('#app', () => App(), {
146
+ * state: window.__PULSE_STATE__,
147
+ * onMismatch: (expected, actual) => {
148
+ * console.warn('Hydration mismatch:', expected, actual);
149
+ * }
150
+ * });
151
+ */
152
+ export declare function hydrate(
153
+ target: string | Element,
154
+ componentFactory: () => unknown,
155
+ options?: HydrateOptions
156
+ ): () => void;
157
+
158
+ // ============================================================================
159
+ // State Serialization
160
+ // ============================================================================
161
+
162
+ /**
163
+ * Serialize state for safe transfer from server to client.
164
+ * Handles special types like Date and undefined.
165
+ * Escapes HTML entities to prevent XSS when embedded in script tags.
166
+ *
167
+ * @param state - State to serialize
168
+ * @returns JSON string safe for embedding in HTML
169
+ *
170
+ * @example
171
+ * const json = serializeState({ date: new Date(), name: 'Test' });
172
+ * // Can be safely embedded in <script> tag
173
+ */
174
+ export declare function serializeState(state: unknown): string;
175
+
176
+ /**
177
+ * Deserialize state received from server.
178
+ * Restores special types like Date.
179
+ *
180
+ * @param data - Serialized state (string or already parsed object)
181
+ * @returns Deserialized state
182
+ *
183
+ * @example
184
+ * const state = deserializeState(window.__PULSE_STATE__);
185
+ */
186
+ export declare function deserializeState(data: string | object): unknown;
187
+
188
+ /**
189
+ * Restore serialized state into the application.
190
+ * Stores the deserialized state in module scope and globalThis for access
191
+ * by components via getSSRState().
192
+ *
193
+ * @param state - Serialized or deserialized state object
194
+ *
195
+ * @example
196
+ * restoreState(window.__PULSE_STATE__);
197
+ */
198
+ export declare function restoreState(state: unknown): void;
199
+
200
+ /**
201
+ * Get restored SSR state.
202
+ * Use this in components to access server-fetched data.
203
+ *
204
+ * @param key - Optional key to get specific value
205
+ * @returns Full state object or specific value if key is provided
206
+ *
207
+ * @example
208
+ * const userData = getSSRState('user');
209
+ * const allState = getSSRState();
210
+ */
211
+ export declare function getSSRState(key?: string): unknown;
212
+
213
+ /**
214
+ * Clear the SSR state.
215
+ * Use in tests or when cleaning up SSR context.
216
+ */
217
+ export declare function clearSSRState(): void;
218
+
219
+ // ============================================================================
220
+ // Re-exports from ssr-hydrator.js
221
+ // ============================================================================
222
+
223
+ /**
224
+ * Check if currently in hydration mode.
225
+ * @returns True if hydrating server-rendered HTML
226
+ */
227
+ export declare function isHydratingMode(): boolean;
228
+
229
+ /**
230
+ * Get the current hydration context.
231
+ * @returns Hydration context or null if not hydrating
232
+ */
233
+ export declare function getHydrationContext(): unknown;
234
+
235
+ // ============================================================================
236
+ // Re-exports from ssr-async.js
237
+ // ============================================================================
238
+
239
+ /**
240
+ * Get the current SSR async context.
241
+ * Returns null if not in SSR mode.
242
+ * @returns SSR async context or null
243
+ */
244
+ export declare function getSSRAsyncContext(): unknown;
245
+
246
+ // ============================================================================
247
+ // Default Export
248
+ // ============================================================================
249
+
250
+ declare const _default: {
251
+ renderToString: typeof renderToString;
252
+ renderToStringSync: typeof renderToStringSync;
253
+ hydrate: typeof hydrate;
254
+ serializeState: typeof serializeState;
255
+ deserializeState: typeof deserializeState;
256
+ restoreState: typeof restoreState;
257
+ getSSRState: typeof getSSRState;
258
+ clearSSRState: typeof clearSSRState;
259
+ isSSR: typeof isSSR;
260
+ isHydratingMode: typeof isHydratingMode;
261
+ };
262
+
263
+ export default _default;
package/types/utils.d.ts CHANGED
@@ -235,6 +235,91 @@ export declare function throttle<T extends (...args: unknown[]) => unknown>(
235
235
  interval: number
236
236
  ): CancellableFunction<T>;
237
237
 
238
+ // =============================================================================
239
+ // CSS Sanitization
240
+ // =============================================================================
241
+
242
+ /**
243
+ * Check if a string is a valid CSS property name
244
+ */
245
+ export declare function isValidCSSProperty(prop: string): boolean;
246
+
247
+ /** Result of CSS value sanitization */
248
+ export interface SanitizeCSSResult {
249
+ safe: boolean;
250
+ value: string;
251
+ blocked?: string;
252
+ }
253
+
254
+ /**
255
+ * Sanitize a CSS value to prevent CSS injection
256
+ */
257
+ export declare function sanitizeCSSValue(
258
+ value: string,
259
+ options?: { allowUrl?: boolean }
260
+ ): SanitizeCSSResult;
261
+
262
+ /**
263
+ * Safely set an inline style on an element
264
+ */
265
+ export declare function safeSetStyle(
266
+ element: HTMLElement,
267
+ prop: string,
268
+ value: string,
269
+ options?: { allowUrl?: boolean }
270
+ ): boolean;
271
+
272
+ // =============================================================================
273
+ // Environment Utilities
274
+ // =============================================================================
275
+
276
+ /**
277
+ * Check if running in a browser environment
278
+ */
279
+ export declare function isBrowser(): boolean;
280
+
281
+ /**
282
+ * Listen to a window event with cleanup support
283
+ */
284
+ export declare function onWindowEvent(
285
+ event: string,
286
+ handler: (e: Event) => void,
287
+ onCleanup?: (cleanup: () => void) => void,
288
+ options?: AddEventListenerOptions
289
+ ): () => void;
290
+
291
+ /**
292
+ * Listen to window focus events
293
+ */
294
+ export declare function onWindowFocus(
295
+ handler: () => void,
296
+ onCleanup?: (cleanup: () => void) => void
297
+ ): () => void;
298
+
299
+ /**
300
+ * Listen to online events
301
+ */
302
+ export declare function onWindowOnline(
303
+ handler: () => void,
304
+ onCleanup?: (cleanup: () => void) => void
305
+ ): () => void;
306
+
307
+ /**
308
+ * Listen to offline events
309
+ */
310
+ export declare function onWindowOffline(
311
+ handler: () => void,
312
+ onCleanup?: (cleanup: () => void) => void
313
+ ): () => void;
314
+
315
+ /**
316
+ * Listen to network change events
317
+ */
318
+ export declare function onNetworkChange(
319
+ handlers: { online?: () => void; offline?: () => void },
320
+ onCleanup?: (cleanup: () => void) => void
321
+ ): () => void;
322
+
238
323
  // =============================================================================
239
324
  // Default Export
240
325
  // =============================================================================