@coherent.js/client 1.1.1 → 2.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -66
- package/dist/chunk-EAOAAY2X.js +1550 -0
- package/dist/chunk-EAOAAY2X.js.map +7 -0
- package/dist/{chunk-N36BSMJU.js → chunk-UYL3RRRC.js} +134 -32
- package/dist/chunk-UYL3RRRC.js.map +7 -0
- package/dist/events/index.js +1 -1
- package/dist/hmr.js +34 -4
- package/dist/hmr.js.map +3 -3
- package/dist/index.js +598 -1732
- package/dist/index.js.map +4 -4
- package/dist/router.js +209 -31
- package/dist/router.js.map +2 -2
- package/package.json +4 -1
- package/types/hmr.d.ts +32 -1
- package/types/index.d.ts +258 -701
- package/types/router.d.ts +34 -11
- package/dist/chunk-N36BSMJU.js.map +0 -7
package/types/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Coherent.js Client Types
|
|
3
|
-
* TypeScript definitions for client
|
|
3
|
+
* TypeScript definitions for @coherent.js/client: hydration, event
|
|
4
|
+
* delegation, state serialization, mismatch detection and HMR.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
+
* The router is the `@coherent.js/client/router` entry point; its types are
|
|
7
|
+
* re-exported here.
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
10
|
// Import core types for component integration
|
|
@@ -28,39 +30,45 @@ export type {
|
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
// ============================================================================
|
|
31
|
-
//
|
|
32
|
-
// ============================================================================
|
|
33
|
-
|
|
34
|
-
/** HTML element with Coherent.js data attributes */
|
|
35
|
-
export interface CoherentHTMLElement extends HTMLElement {
|
|
36
|
-
'data-coherent-state'?: string;
|
|
37
|
-
'data-coherent-component'?: string;
|
|
38
|
-
'data-coherent-id'?: string;
|
|
39
|
-
'data-action'?: string;
|
|
40
|
-
'data-event'?: string;
|
|
41
|
-
'data-count'?: string;
|
|
42
|
-
'data-step'?: string;
|
|
43
|
-
'data-active'?: string;
|
|
44
|
-
'data-loading'?: string;
|
|
45
|
-
'data-disabled'?: string;
|
|
46
|
-
'data-selected'?: string;
|
|
47
|
-
'data-expanded'?: string;
|
|
48
|
-
'data-visible'?: string;
|
|
49
|
-
__coherentInstance?: HydratedInstance;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// ============================================================================
|
|
53
|
-
// Event Handler Types - Specific DOM Events
|
|
33
|
+
// Events
|
|
54
34
|
// ============================================================================
|
|
55
35
|
|
|
56
36
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
37
|
+
* What a delegated handler (an `on*` prop bound by `hydrate()`) receives: the
|
|
38
|
+
* native event plus the component it belongs to.
|
|
59
39
|
*/
|
|
60
|
-
export
|
|
61
|
-
event
|
|
62
|
-
|
|
63
|
-
|
|
40
|
+
export interface CoherentEvent<S = any, E extends Event = Event> {
|
|
41
|
+
/** The native DOM event */
|
|
42
|
+
originalEvent: E;
|
|
43
|
+
/** The event type, e.g. `'click'` */
|
|
44
|
+
type: string;
|
|
45
|
+
/** The element whose handler runs (the one carrying the handler) */
|
|
46
|
+
target: Element;
|
|
47
|
+
/** Same as `target` */
|
|
48
|
+
currentTarget: Element;
|
|
49
|
+
/** Whether the default action was prevented */
|
|
50
|
+
readonly defaultPrevented: boolean;
|
|
51
|
+
/** Whether a handler stopped propagation to ancestor handlers */
|
|
52
|
+
propagationStopped: boolean;
|
|
53
|
+
/** Prevent the default action (all delegated types but touch/wheel/scroll) */
|
|
54
|
+
preventDefault(): void;
|
|
55
|
+
/** Stop ancestor handlers and native propagation */
|
|
56
|
+
stopPropagation(): void;
|
|
57
|
+
/** Like stopPropagation(), also for other native listeners */
|
|
58
|
+
stopImmediatePropagation(): void;
|
|
59
|
+
/** The hydrated component function */
|
|
60
|
+
component: ((props?: any) => CoherentNode) | null;
|
|
61
|
+
/** The component's state when the event fired */
|
|
62
|
+
state: S | null;
|
|
63
|
+
/** Merge state and re-render the component */
|
|
64
|
+
setState: ((newState: Partial<S> | ((prev: S) => Partial<S>)) => void) | null;
|
|
65
|
+
/** The props the component last rendered with (state included) */
|
|
66
|
+
props: Record<string, any> | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** A delegated event handler. */
|
|
70
|
+
export type EventHandler<E extends Event = Event, S = any> = (
|
|
71
|
+
event: CoherentEvent<S, E>
|
|
64
72
|
) => void | Promise<void>;
|
|
65
73
|
|
|
66
74
|
/** Click event handler (MouseEvent) */
|
|
@@ -96,14 +104,9 @@ export type TouchHandler = EventHandler<TouchEvent>;
|
|
|
96
104
|
/** Wheel event handler (WheelEvent) */
|
|
97
105
|
export type WheelHandler = EventHandler<WheelEvent>;
|
|
98
106
|
|
|
99
|
-
/**
|
|
100
|
-
* State-aware event handler used in components.
|
|
101
|
-
* Receives event, current state, and setState function.
|
|
102
|
-
*/
|
|
107
|
+
/** A delegated handler typed by the component's state. */
|
|
103
108
|
export type StateAwareHandler<S = any, E extends Event = Event> = (
|
|
104
|
-
event: E
|
|
105
|
-
state: S,
|
|
106
|
-
setState: (newState: Partial<S> | ((prev: S) => Partial<S>)) => void
|
|
109
|
+
event: CoherentEvent<S, E>
|
|
107
110
|
) => void | Promise<void>;
|
|
108
111
|
|
|
109
112
|
// ============================================================================
|
|
@@ -130,98 +133,46 @@ export interface SerializableState {
|
|
|
130
133
|
// Hydration Types
|
|
131
134
|
// ============================================================================
|
|
132
135
|
|
|
133
|
-
/**
|
|
136
|
+
/** Options for {@link hydrate} */
|
|
134
137
|
export interface HydrationOptions {
|
|
138
|
+
/** State to hydrate with; defaults to the container's `data-state` */
|
|
135
139
|
initialState?: SerializableState;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
timeout?: number;
|
|
142
|
-
onError?: (error: Error, element?: HTMLElement) => void;
|
|
143
|
-
onSuccess?: (element: HTMLElement, state: SerializableState) => void;
|
|
144
|
-
transforms?: StateTransforms;
|
|
145
|
-
validators?: StateValidators;
|
|
146
|
-
/** Enable mismatch detection (dev mode default: true) */
|
|
140
|
+
/**
|
|
141
|
+
* Compare the server DOM with the component's output. Defaults to on when
|
|
142
|
+
* `strict` or `onMismatch` is given or `process.env.NODE_ENV` is
|
|
143
|
+
* `'development'`, off otherwise.
|
|
144
|
+
*/
|
|
147
145
|
detectMismatch?: boolean;
|
|
148
146
|
/** Throw on mismatch instead of warning */
|
|
149
147
|
strict?: boolean;
|
|
150
|
-
/**
|
|
148
|
+
/** Receive mismatches instead of the console warning */
|
|
151
149
|
onMismatch?: (mismatches: HydrationMismatch[]) => void;
|
|
152
150
|
/** Additional props to pass to component */
|
|
153
151
|
props?: Record<string, any>;
|
|
154
152
|
}
|
|
155
153
|
|
|
156
|
-
/**
|
|
157
|
-
export interface StateTransforms {
|
|
158
|
-
[key: string]: (value: any) => any;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/** State validation functions */
|
|
162
|
-
export interface StateValidators {
|
|
163
|
-
[key: string]: (value: any) => boolean;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/** Hydration mismatch information */
|
|
154
|
+
/** One difference between the server DOM and the component's output */
|
|
167
155
|
export interface HydrationMismatch {
|
|
156
|
+
/** Position in the virtual tree, e.g. `children[1].@class` */
|
|
168
157
|
path: string;
|
|
169
|
-
type:
|
|
158
|
+
type:
|
|
159
|
+
| 'text'
|
|
160
|
+
| 'tagName'
|
|
161
|
+
| 'attribute'
|
|
162
|
+
| 'children_count'
|
|
163
|
+
| 'missing_dom_child'
|
|
164
|
+
| 'extra_dom_child';
|
|
170
165
|
expected: any;
|
|
171
166
|
actual: any;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
/** Component hydration result */
|
|
175
|
-
export interface HydrationResult {
|
|
176
|
-
success: boolean;
|
|
177
|
-
element: HTMLElement;
|
|
178
|
-
state: SerializableState;
|
|
179
|
-
component?: ClientComponent;
|
|
180
|
-
error?: Error;
|
|
181
|
-
duration?: number;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/** Batch hydration result */
|
|
185
|
-
export interface BatchHydrationResult {
|
|
186
|
-
total: number;
|
|
187
|
-
successful: number;
|
|
188
|
-
failed: number;
|
|
189
|
-
results: HydrationResult[];
|
|
190
|
-
errors: Array<{ element: HTMLElement; error: Error }>;
|
|
191
|
-
duration: number;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Hydrated component instance returned by hydrate().
|
|
196
|
-
* Provides control methods for state management and lifecycle.
|
|
197
|
-
*/
|
|
198
|
-
export interface HydratedInstance {
|
|
199
|
-
/** The DOM element being hydrated */
|
|
200
|
-
element: HTMLElement;
|
|
201
|
-
/** The component function */
|
|
202
|
-
component: CoherentComponent;
|
|
203
|
-
/** Current props */
|
|
204
|
-
props: Record<string, any>;
|
|
205
|
-
/** Current state */
|
|
206
|
-
state: SerializableState;
|
|
207
|
-
/** Whether hydration is complete */
|
|
208
|
-
isHydrated: boolean;
|
|
209
|
-
|
|
210
|
-
/** Update props and re-render */
|
|
211
|
-
update(newProps?: Record<string, any>): HydratedInstance;
|
|
212
|
-
/** Re-render with current state */
|
|
213
|
-
rerender(): void;
|
|
214
|
-
/** Destroy the instance and clean up */
|
|
215
|
-
destroy(): void;
|
|
216
|
-
/** Set state and trigger re-render */
|
|
217
|
-
setState(newState: Partial<SerializableState> | ((prev: SerializableState) => Partial<SerializableState>)): void;
|
|
167
|
+
/** CSS-like path of the DOM element, for debugging */
|
|
168
|
+
domPath: string;
|
|
218
169
|
}
|
|
219
170
|
|
|
220
171
|
/**
|
|
221
172
|
* Control object returned by the clean hydrate() API.
|
|
222
173
|
*/
|
|
223
174
|
export interface HydrateControl {
|
|
224
|
-
/** Unmount the component and clean up event handlers */
|
|
175
|
+
/** Unmount the component and clean up event handlers; terminal */
|
|
225
176
|
unmount(): void;
|
|
226
177
|
/** Re-render with optional new props */
|
|
227
178
|
rerender(newProps?: Record<string, any>): void;
|
|
@@ -231,90 +182,15 @@ export interface HydrateControl {
|
|
|
231
182
|
setState(newState: Partial<SerializableState> | ((prev: SerializableState) => Partial<SerializableState>)): void;
|
|
232
183
|
}
|
|
233
184
|
|
|
234
|
-
export interface MakeHydratableOptions {
|
|
235
|
-
componentName?: string;
|
|
236
|
-
initialState?: SerializableState;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// ============================================================================
|
|
240
|
-
// Client Component Types
|
|
241
|
-
// ============================================================================
|
|
242
|
-
|
|
243
|
-
/** Client-side component interface */
|
|
244
|
-
export interface ClientComponent {
|
|
245
|
-
readonly element: HTMLElement;
|
|
246
|
-
readonly state: SerializableState;
|
|
247
|
-
readonly isHydrated: boolean;
|
|
248
|
-
readonly id: string;
|
|
249
|
-
|
|
250
|
-
setState(newState: Partial<SerializableState>): void;
|
|
251
|
-
updateState(updater: (state: SerializableState) => Partial<SerializableState>): void;
|
|
252
|
-
getState(): SerializableState;
|
|
253
|
-
resetState(): void;
|
|
254
|
-
|
|
255
|
-
render(): void;
|
|
256
|
-
destroy(): void;
|
|
257
|
-
refresh(): void;
|
|
258
|
-
|
|
259
|
-
addEventListener(event: string, handler: EventHandler): void;
|
|
260
|
-
removeEventListener(event: string, handler: EventHandler): void;
|
|
261
|
-
trigger(event: string, data?: any): void;
|
|
262
|
-
|
|
263
|
-
serialize(): string;
|
|
264
|
-
toJSON(): SerializableState;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/** Component factory function */
|
|
268
|
-
export type ComponentFactory = (element: HTMLElement, initialState?: SerializableState) => ClientComponent;
|
|
269
|
-
|
|
270
|
-
/** Component registry entry */
|
|
271
|
-
export interface ComponentRegistryEntry {
|
|
272
|
-
name: string;
|
|
273
|
-
factory: ComponentFactory;
|
|
274
|
-
selector?: string;
|
|
275
|
-
autoHydrate?: boolean;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
185
|
// ============================================================================
|
|
279
|
-
// Event
|
|
186
|
+
// Event Delegation Types
|
|
280
187
|
// ============================================================================
|
|
281
188
|
|
|
282
|
-
/**
|
|
283
|
-
export interface EventBinding {
|
|
284
|
-
event: string;
|
|
285
|
-
selector?: string;
|
|
286
|
-
handler: EventHandler;
|
|
287
|
-
options?: EventListenerOptions | boolean;
|
|
288
|
-
delegate?: boolean;
|
|
289
|
-
once?: boolean;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/** Event manager interface */
|
|
293
|
-
export interface EventManager {
|
|
294
|
-
bind(element: HTMLElement, bindings: EventBinding[]): void;
|
|
295
|
-
unbind(element: HTMLElement, event?: string): void;
|
|
296
|
-
trigger(element: HTMLElement, event: string, data?: any): void;
|
|
297
|
-
delegate(container: HTMLElement, selector: string, event: string, handler: EventHandler): void;
|
|
298
|
-
undelegate(container: HTMLElement, selector?: string, event?: string): void;
|
|
299
|
-
once(element: HTMLElement, event: string, handler: EventHandler): void;
|
|
300
|
-
debounce(handler: EventHandler, delay: number): EventHandler;
|
|
301
|
-
throttle(handler: EventHandler, limit: number): EventHandler;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/** Custom event data */
|
|
305
|
-
export interface CustomEventData {
|
|
306
|
-
detail: any;
|
|
307
|
-
bubbles?: boolean;
|
|
308
|
-
cancelable?: boolean;
|
|
309
|
-
composed?: boolean;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// ============================================================================
|
|
313
|
-
// Event Delegation Types (Plan 02-01)
|
|
314
|
-
// ============================================================================
|
|
315
|
-
|
|
316
|
-
/** A component whose state a delegated handler may read and write */
|
|
189
|
+
/** The component a delegated handler belongs to */
|
|
317
190
|
export interface HandlerComponentRef {
|
|
191
|
+
component?: (props?: any) => CoherentNode;
|
|
192
|
+
state?: any;
|
|
193
|
+
props?: Record<string, any>;
|
|
318
194
|
getState?: () => any;
|
|
319
195
|
setState?: (state: any) => void;
|
|
320
196
|
[key: string]: any;
|
|
@@ -322,14 +198,19 @@ export interface HandlerComponentRef {
|
|
|
322
198
|
|
|
323
199
|
/** A registered handler and the component it belongs to */
|
|
324
200
|
export interface RegisteredHandler {
|
|
325
|
-
handler: StateAwareHandler
|
|
201
|
+
handler: StateAwareHandler<any, any>;
|
|
326
202
|
componentRef: HandlerComponentRef | null;
|
|
327
203
|
}
|
|
328
204
|
|
|
329
205
|
/**
|
|
330
206
|
* Routes document-level events to handlers registered by id.
|
|
331
207
|
*
|
|
332
|
-
*
|
|
208
|
+
* Listeners are non-passive, so handlers can call `preventDefault()`, except
|
|
209
|
+
* for scroll-blocking types (touchstart, touchmove, wheel, scroll). Handlers
|
|
210
|
+
* run from the target's nearest `data-coherent-{type}` element outwards, like
|
|
211
|
+
* bubbling, until one stops propagation. Focus and blur are captured, since
|
|
212
|
+
* they do not bubble natively; other non-bubbling events (mouseenter, load,
|
|
213
|
+
* ...) only reach a handler on the target itself.
|
|
333
214
|
*/
|
|
334
215
|
export class EventDelegation {
|
|
335
216
|
constructor(registry?: HandlerRegistry);
|
|
@@ -343,10 +224,16 @@ export class EventDelegation {
|
|
|
343
224
|
/** Attach listeners to `root`; idempotent, and a no-op without a document */
|
|
344
225
|
initialize(root?: Document | Element | null): void;
|
|
345
226
|
|
|
346
|
-
/**
|
|
227
|
+
/**
|
|
228
|
+
* Delegate `eventType` too. hydrate() calls this for every event type a
|
|
229
|
+
* component handles, so any DOM event works, not only the defaults.
|
|
230
|
+
*/
|
|
231
|
+
listen(eventType: string): void;
|
|
232
|
+
|
|
233
|
+
/** Dispatch one delegated event to its registered handlers */
|
|
347
234
|
handleEvent(event: Event, eventType: string): void;
|
|
348
235
|
|
|
349
|
-
/** Remove every listener attached by `initialize()` */
|
|
236
|
+
/** Remove every listener attached by `initialize()` and `listen()` */
|
|
350
237
|
destroy(): void;
|
|
351
238
|
|
|
352
239
|
isInitialized(): boolean;
|
|
@@ -361,7 +248,7 @@ export class HandlerRegistry {
|
|
|
361
248
|
/** Register a handler, optionally bound to a component */
|
|
362
249
|
register(
|
|
363
250
|
handlerId: string,
|
|
364
|
-
handler: StateAwareHandler,
|
|
251
|
+
handler: StateAwareHandler<any, any>,
|
|
365
252
|
componentRef?: HandlerComponentRef | null
|
|
366
253
|
): void;
|
|
367
254
|
|
|
@@ -380,489 +267,239 @@ export class HandlerRegistry {
|
|
|
380
267
|
}
|
|
381
268
|
|
|
382
269
|
// ============================================================================
|
|
383
|
-
//
|
|
270
|
+
// Hot Module Replacement Types
|
|
384
271
|
// ============================================================================
|
|
385
272
|
|
|
386
|
-
/**
|
|
387
|
-
export interface
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
};
|
|
418
|
-
debounce?: number;
|
|
419
|
-
validate?: (value: any) => boolean;
|
|
420
|
-
transform?: (value: any) => any;
|
|
273
|
+
/** Hot context API for a module (see {@link createHotContext}) */
|
|
274
|
+
export interface HotContext {
|
|
275
|
+
/** Data persisted across HMR updates of this module */
|
|
276
|
+
readonly data: Record<string, any>;
|
|
277
|
+
/** Accept self updates; without it an update reloads the page */
|
|
278
|
+
accept(callback?: (newModule: any) => void): void;
|
|
279
|
+
/** Accept updates of dependencies */
|
|
280
|
+
acceptDeps(deps: string | string[], callback: (modules: Record<string, any>) => void): void;
|
|
281
|
+
/** Cleanup before the module is replaced; receives `data` */
|
|
282
|
+
dispose(callback: (data: Record<string, any>) => void): void;
|
|
283
|
+
/** Called when the module is removed from the module graph */
|
|
284
|
+
prune(callback: () => void): void;
|
|
285
|
+
/** Ask the dev server to propagate the update to importers */
|
|
286
|
+
invalidate(message?: string): void;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** Tracked timers, listeners and fetches of one module */
|
|
290
|
+
export interface HMRModuleContext {
|
|
291
|
+
setTimeout(callback: (...args: any[]) => void, delay?: number, ...args: any[]): ReturnType<typeof setTimeout>;
|
|
292
|
+
setInterval(callback: (...args: any[]) => void, delay?: number, ...args: any[]): ReturnType<typeof setInterval>;
|
|
293
|
+
clearTimeout(id: ReturnType<typeof setTimeout>): void;
|
|
294
|
+
clearInterval(id: ReturnType<typeof setInterval>): void;
|
|
295
|
+
addEventListener(
|
|
296
|
+
target: EventTarget,
|
|
297
|
+
event: string,
|
|
298
|
+
handler: EventListenerOrEventListenerObject,
|
|
299
|
+
options?: AddEventListenerOptions | boolean
|
|
300
|
+
): void;
|
|
301
|
+
createAbortController(): AbortController;
|
|
302
|
+
/** fetch() aborted on module disposal and by the caller's own `signal` */
|
|
303
|
+
fetch(url: string | URL, options?: RequestInit): Promise<Response>;
|
|
421
304
|
}
|
|
422
305
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
/** HMR update information */
|
|
428
|
-
export interface HMRUpdate {
|
|
429
|
-
type: 'component' | 'style' | 'script' | 'template' | 'full-reload';
|
|
430
|
-
id: string;
|
|
431
|
-
path: string;
|
|
432
|
-
content?: string;
|
|
433
|
-
timestamp: number;
|
|
434
|
-
/** File that changed (for error display) */
|
|
306
|
+
/** An error shown by the overlay */
|
|
307
|
+
export interface HMRErrorDetails {
|
|
308
|
+
message: string;
|
|
435
309
|
file?: string;
|
|
436
|
-
/** Line number for error */
|
|
437
310
|
line?: number;
|
|
438
|
-
/** Column number for error */
|
|
439
311
|
column?: number;
|
|
312
|
+
frame?: string;
|
|
313
|
+
stack?: string;
|
|
440
314
|
}
|
|
441
315
|
|
|
442
|
-
/**
|
|
443
|
-
export
|
|
444
|
-
|
|
445
|
-
/** HMR configuration */
|
|
446
|
-
export interface HMRConfig {
|
|
447
|
-
enabled: boolean;
|
|
448
|
-
websocketUrl?: string;
|
|
449
|
-
reconnectInterval?: number;
|
|
450
|
-
maxReconnectAttempts?: number;
|
|
451
|
-
debug?: boolean;
|
|
452
|
-
onUpdate?: HMRListener;
|
|
453
|
-
onError?: (error: Error) => void;
|
|
454
|
-
onReconnect?: () => void;
|
|
455
|
-
/** Show error overlay */
|
|
456
|
-
overlay?: boolean;
|
|
457
|
-
/** Show connection indicator */
|
|
458
|
-
indicator?: boolean;
|
|
459
|
-
}
|
|
316
|
+
/** WebSocket client that applies dev-server updates */
|
|
317
|
+
export class HMRClient {
|
|
318
|
+
constructor();
|
|
460
319
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
320
|
+
socket: WebSocket | null;
|
|
321
|
+
connected: boolean;
|
|
322
|
+
reconnectAttempts: number;
|
|
323
|
+
maxReconnectAttempts: number;
|
|
324
|
+
reconnectDelay: number;
|
|
325
|
+
hadDisconnect: boolean;
|
|
326
|
+
reconnectTimeout: ReturnType<typeof setTimeout> | null;
|
|
327
|
+
initialized: boolean;
|
|
465
328
|
|
|
466
|
-
|
|
329
|
+
/** Connect once per page (no-op without `window`) */
|
|
330
|
+
initialize(): void;
|
|
331
|
+
/** Open the WebSocket, reconnecting with backoff when it closes */
|
|
332
|
+
connect(): void;
|
|
333
|
+
/** Close the socket without reconnecting */
|
|
467
334
|
disconnect(): void;
|
|
335
|
+
isConnected(): boolean;
|
|
336
|
+
scheduleReconnect(): void;
|
|
337
|
+
handleMessage(event: MessageEvent): void;
|
|
338
|
+
/** Re-import a changed module; reloads the page when it does not accept updates */
|
|
339
|
+
handleUpdate(data: { filePath?: string; webPath?: string; updateType?: string }): Promise<void>;
|
|
340
|
+
/** Import an updated module (overridable) */
|
|
341
|
+
importModule(url: string): Promise<any>;
|
|
342
|
+
/** Reload the page */
|
|
343
|
+
reload(): void;
|
|
344
|
+
handleUpdateError(error: Error, filePath: string): void;
|
|
345
|
+
showError(error: HMRErrorDetails): void;
|
|
346
|
+
hideError(): void;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** Hot contexts and update handlers by module id */
|
|
350
|
+
export class ModuleTracker {
|
|
351
|
+
constructor();
|
|
468
352
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
accept(deps: string | string[], callback?: (modules: any[]) => void): void;
|
|
484
|
-
/** Dispose callback for cleanup */
|
|
485
|
-
dispose(callback: (data: any) => void): void;
|
|
486
|
-
/** Prune callback when module is removed */
|
|
487
|
-
prune(callback: () => void): void;
|
|
488
|
-
/** Invalidate to trigger parent update */
|
|
489
|
-
invalidate(): void;
|
|
490
|
-
/** Decline to fall back to full reload */
|
|
491
|
-
decline(): void;
|
|
492
|
-
/** Data persisted across HMR updates */
|
|
493
|
-
data: Record<string, any>;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/** Module tracker for HMR boundary detection */
|
|
497
|
-
export interface ModuleTracker {
|
|
498
|
-
/** Track a module with its hot context */
|
|
499
|
-
track(moduleId: string, context: HotContext): void;
|
|
500
|
-
/** Check if module is a boundary */
|
|
501
|
-
isBoundary(moduleId: string): boolean;
|
|
502
|
-
/** Get hot context for module */
|
|
503
|
-
getContext(moduleId: string): HotContext | undefined;
|
|
504
|
-
/** Clear tracked modules */
|
|
353
|
+
modules: Map<string, any>;
|
|
354
|
+
socket: WebSocket | null;
|
|
355
|
+
|
|
356
|
+
setSocket(socket: WebSocket | null): void;
|
|
357
|
+
createHotContext(moduleId: string): HotContext;
|
|
358
|
+
canHotUpdate(moduleId: string): boolean;
|
|
359
|
+
isHmrBoundary(moduleId: string, moduleExports?: Record<string, any>): boolean;
|
|
360
|
+
extractComponentName(moduleId: string): string | null;
|
|
361
|
+
executeDispose(moduleId: string): Record<string, any> | null;
|
|
362
|
+
executeAccept(moduleId: string, newModule?: any): boolean;
|
|
363
|
+
executeAcceptDeps(moduleId: string, updatedDeps: Record<string, any>): boolean;
|
|
364
|
+
executePrune(moduleId: string): void;
|
|
365
|
+
hasModule(moduleId: string): boolean;
|
|
366
|
+
getModuleData(moduleId: string): Record<string, any> | null;
|
|
505
367
|
clear(): void;
|
|
506
368
|
}
|
|
507
369
|
|
|
508
|
-
/**
|
|
509
|
-
export
|
|
510
|
-
|
|
511
|
-
trackTimer(moduleId: string, timerId: number): void;
|
|
512
|
-
/** Track an event listener for cleanup */
|
|
513
|
-
trackListener(moduleId: string, element: EventTarget, event: string, handler: EventListener): void;
|
|
514
|
-
/** Track a fetch request for cleanup */
|
|
515
|
-
trackFetch(moduleId: string, controller: AbortController): void;
|
|
516
|
-
/** Clean up all resources for a module */
|
|
517
|
-
cleanup(moduleId: string): void;
|
|
518
|
-
/** Clear all tracked resources */
|
|
519
|
-
clearAll(): void;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/** State capturer for preserving form state during HMR */
|
|
523
|
-
export interface StateCapturer {
|
|
524
|
-
/** Capture current input values and scroll positions */
|
|
525
|
-
capture(): Record<string, any>;
|
|
526
|
-
/** Restore captured state */
|
|
527
|
-
restore(state: Record<string, any>): void;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
/** Error overlay for displaying HMR errors */
|
|
531
|
-
export interface ErrorOverlay {
|
|
532
|
-
/** Show error overlay */
|
|
533
|
-
show(error: { message: string; file?: string; line?: number; column?: number; frame?: string }): void;
|
|
534
|
-
/** Hide error overlay */
|
|
535
|
-
hide(): void;
|
|
536
|
-
/** Check if overlay is visible */
|
|
537
|
-
isVisible(): boolean;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
/** Connection indicator for WebSocket status */
|
|
541
|
-
export interface ConnectionIndicator {
|
|
542
|
-
/** Show indicator with status */
|
|
543
|
-
show(status: 'connected' | 'disconnected' | 'connecting' | 'error'): void;
|
|
544
|
-
/** Hide indicator */
|
|
545
|
-
hide(): void;
|
|
546
|
-
/** Update status */
|
|
547
|
-
setStatus(status: 'connected' | 'disconnected' | 'connecting' | 'error'): void;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// ============================================================================
|
|
551
|
-
// Performance Types
|
|
552
|
-
// ============================================================================
|
|
553
|
-
|
|
554
|
-
/** Performance metrics */
|
|
555
|
-
export interface PerformanceMetrics {
|
|
556
|
-
hydrationTime: number;
|
|
557
|
-
componentCount: number;
|
|
558
|
-
eventBindings: number;
|
|
559
|
-
memoryUsage?: number;
|
|
560
|
-
renderTime?: number;
|
|
561
|
-
stateUpdates: number;
|
|
562
|
-
}
|
|
370
|
+
/** Tracks module resources so HMR can release them */
|
|
371
|
+
export class CleanupTracker {
|
|
372
|
+
constructor();
|
|
563
373
|
|
|
564
|
-
|
|
565
|
-
export interface PerformanceMonitor {
|
|
566
|
-
start(label: string): void;
|
|
567
|
-
end(label: string): number;
|
|
568
|
-
measure(label: string, fn: () => any): any;
|
|
569
|
-
measureAsync(label: string, fn: () => Promise<any>): Promise<any>;
|
|
570
|
-
getMetrics(): PerformanceMetrics;
|
|
571
|
-
reset(): void;
|
|
572
|
-
report(): void;
|
|
573
|
-
}
|
|
374
|
+
moduleResources: Map<string, any>;
|
|
574
375
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
376
|
+
createContext(moduleId: string): HMRModuleContext;
|
|
377
|
+
cleanup(moduleId: string): void;
|
|
378
|
+
checkForLeaks(moduleId: string): void;
|
|
379
|
+
hasResources(moduleId: string): boolean;
|
|
380
|
+
getResourceCounts(moduleId: string): {
|
|
381
|
+
timers: number;
|
|
382
|
+
intervals: number;
|
|
383
|
+
listeners: number;
|
|
384
|
+
abortControllers: number;
|
|
385
|
+
} | null;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/** Preserves form input and scroll state across HMR updates */
|
|
389
|
+
export class StateCapturer {
|
|
390
|
+
constructor();
|
|
578
391
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
392
|
+
capturedInputs: Map<string, any>;
|
|
393
|
+
scrollPositions: Map<string, { top: number; left: number }>;
|
|
394
|
+
layoutSnapshot: Record<string, any> | null;
|
|
395
|
+
|
|
396
|
+
getInputKey(input: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement): string;
|
|
397
|
+
getElementPath(element: Element): string;
|
|
398
|
+
captureFormState(): Map<string, any>;
|
|
399
|
+
restoreFormState(): void;
|
|
400
|
+
findInputsByKey(key: string): HTMLElement[];
|
|
401
|
+
captureScrollPositions(): Map<string, { top: number; left: number }>;
|
|
402
|
+
getScrollableKey(element: Element): string;
|
|
403
|
+
captureLayout(): void;
|
|
404
|
+
layoutChangedSignificantly(): boolean;
|
|
405
|
+
findElementByKey(key: string): HTMLElement | null;
|
|
406
|
+
restoreScrollPositions(): void;
|
|
407
|
+
captureAll(): void;
|
|
408
|
+
restoreAll(): void;
|
|
409
|
+
clear(): void;
|
|
595
410
|
}
|
|
596
411
|
|
|
597
|
-
/**
|
|
598
|
-
export
|
|
599
|
-
|
|
600
|
-
component?: CoherentComponent;
|
|
601
|
-
meta?: Record<string, any>;
|
|
602
|
-
hash?: string;
|
|
603
|
-
query?: Record<string, string>;
|
|
604
|
-
}
|
|
412
|
+
/** Full-screen overlay for HMR errors */
|
|
413
|
+
export class ErrorOverlay {
|
|
414
|
+
constructor();
|
|
605
415
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
enter: string;
|
|
609
|
-
leave: string;
|
|
610
|
-
duration: number;
|
|
611
|
-
}
|
|
416
|
+
overlay: { host: HTMLElement; shadow: ShadowRoot } | null;
|
|
417
|
+
editor: string;
|
|
612
418
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
delay?: number;
|
|
619
|
-
savePosition?: boolean;
|
|
620
|
-
custom?: (to: Route, from: Route | null, savedPosition: { x: number; y: number } | null) => { x: number; y: number } | { el: Element };
|
|
419
|
+
createOverlay(): { host: HTMLElement; shadow: ShadowRoot };
|
|
420
|
+
show(error: HMRErrorDetails): void;
|
|
421
|
+
hide(): void;
|
|
422
|
+
openInEditor(file: string, line?: number): void;
|
|
423
|
+
setEditor(editor: string): void;
|
|
621
424
|
}
|
|
622
425
|
|
|
623
|
-
/**
|
|
624
|
-
export
|
|
625
|
-
|
|
626
|
-
base?: string;
|
|
627
|
-
prefetch?: {
|
|
628
|
-
enabled?: boolean;
|
|
629
|
-
strategy?: 'hover' | 'visible' | 'idle';
|
|
630
|
-
delay?: number;
|
|
631
|
-
maxConcurrent?: number;
|
|
632
|
-
priority?: {
|
|
633
|
-
critical?: number;
|
|
634
|
-
high?: number;
|
|
635
|
-
normal?: number;
|
|
636
|
-
low?: number;
|
|
637
|
-
};
|
|
638
|
-
};
|
|
639
|
-
transitions?: {
|
|
640
|
-
enabled?: boolean;
|
|
641
|
-
default?: RouteTransition;
|
|
642
|
-
routes?: Record<string, RouteTransition>;
|
|
643
|
-
onStart?: (from: string | null, to: string) => void;
|
|
644
|
-
onComplete?: (from: string | null, to: string) => void;
|
|
645
|
-
};
|
|
646
|
-
codeSplitting?: {
|
|
647
|
-
enabled?: boolean;
|
|
648
|
-
strategy?: 'route';
|
|
649
|
-
chunkNaming?: string;
|
|
650
|
-
preload?: string[];
|
|
651
|
-
onLoad?: (path: string, component: any, loadTime: number) => void;
|
|
652
|
-
};
|
|
653
|
-
scrollBehavior?: ScrollBehaviorConfig;
|
|
654
|
-
}
|
|
426
|
+
/** Small dot showing the HMR connection status */
|
|
427
|
+
export class ConnectionIndicator {
|
|
428
|
+
constructor();
|
|
655
429
|
|
|
656
|
-
|
|
657
|
-
export interface RouterStats {
|
|
658
|
-
navigations: number;
|
|
659
|
-
prefetches: number;
|
|
660
|
-
transitionsCompleted: number;
|
|
661
|
-
chunksLoaded: number;
|
|
662
|
-
scrollRestores: number;
|
|
663
|
-
routesRegistered: number;
|
|
664
|
-
prefetchQueueSize: number;
|
|
665
|
-
activePrefetches: number;
|
|
666
|
-
loadedChunks: number;
|
|
667
|
-
savedPositions: number;
|
|
668
|
-
historyLength: number;
|
|
669
|
-
}
|
|
430
|
+
indicator: HTMLElement | null;
|
|
670
431
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
push(path: string, options?: Partial<Route>): Promise<boolean>;
|
|
675
|
-
replace(path: string, options?: Partial<Route>): Promise<boolean>;
|
|
676
|
-
back(): void;
|
|
677
|
-
forward(): void;
|
|
678
|
-
prefetchRoute(path: string, priority?: number): Promise<void>;
|
|
679
|
-
prefetchRoutes(paths: string[], priority?: number): void;
|
|
680
|
-
setupPrefetchStrategy(element: HTMLElement, path: string): void;
|
|
681
|
-
getRoute(path: string): RouteConfig | undefined;
|
|
682
|
-
getRoutes(): RouteConfig[];
|
|
683
|
-
getCurrentRoute(): Route | null;
|
|
684
|
-
getStats(): RouterStats;
|
|
685
|
-
clearCaches(): void;
|
|
432
|
+
create(): void;
|
|
433
|
+
update(status: 'connected' | 'disconnected' | 'reconnecting' | 'error'): void;
|
|
434
|
+
destroy(): void;
|
|
686
435
|
}
|
|
687
436
|
|
|
688
437
|
// ============================================================================
|
|
689
|
-
//
|
|
438
|
+
// Router Types (the router itself is the @coherent.js/client/router entry)
|
|
690
439
|
// ============================================================================
|
|
691
440
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
/** Animation frame callback */
|
|
702
|
-
export type AnimationCallback = (timestamp: number) => void;
|
|
703
|
-
|
|
704
|
-
/** Intersection observer entry with extended data */
|
|
705
|
-
export interface ExtendedIntersectionObserverEntry extends IntersectionObserverEntry {
|
|
706
|
-
element: HTMLElement;
|
|
707
|
-
isVisible: boolean;
|
|
708
|
-
percentage: number;
|
|
709
|
-
}
|
|
441
|
+
export type {
|
|
442
|
+
RouteConfig,
|
|
443
|
+
Route,
|
|
444
|
+
RouteTransition,
|
|
445
|
+
ScrollBehaviorConfig,
|
|
446
|
+
RouterConfig,
|
|
447
|
+
RouterStats,
|
|
448
|
+
Router,
|
|
449
|
+
} from './router.js';
|
|
710
450
|
|
|
711
451
|
// ============================================================================
|
|
712
|
-
//
|
|
452
|
+
// Hydration
|
|
713
453
|
// ============================================================================
|
|
714
454
|
|
|
715
|
-
/** Extract initial state from DOM element */
|
|
716
|
-
declare function extractInitialState(
|
|
717
|
-
element: HTMLElement,
|
|
718
|
-
options?: Pick<HydrationOptions, 'initialState' | 'transforms' | 'validators'>
|
|
719
|
-
): SerializableState | null;
|
|
720
|
-
|
|
721
455
|
/**
|
|
722
456
|
* Hydrate a server-rendered component (clean API).
|
|
723
457
|
* Returns a control object with unmount, rerender, getState, and setState.
|
|
458
|
+
* Hydrating a container again replaces its previous hydration.
|
|
724
459
|
*/
|
|
725
460
|
export function hydrate(
|
|
726
|
-
component: CoherentComponent,
|
|
461
|
+
component: CoherentComponent | ((props: any) => CoherentNode),
|
|
727
462
|
container: HTMLElement,
|
|
728
463
|
options?: HydrationOptions
|
|
729
464
|
): HydrateControl;
|
|
730
465
|
|
|
731
|
-
/** Register a component for auto-hydration */
|
|
732
|
-
declare function registerComponent(
|
|
733
|
-
name: string,
|
|
734
|
-
factory: ComponentFactory,
|
|
735
|
-
options?: Partial<ComponentRegistryEntry>
|
|
736
|
-
): void;
|
|
737
|
-
|
|
738
|
-
/** Unregister a component */
|
|
739
|
-
declare function unregisterComponent(name: string): boolean;
|
|
740
|
-
|
|
741
|
-
/** Get registered component */
|
|
742
|
-
declare function getComponent(name: string): ComponentRegistryEntry | undefined;
|
|
743
|
-
|
|
744
|
-
/** Get all registered components */
|
|
745
|
-
declare function getAllComponents(): ComponentRegistryEntry[];
|
|
746
|
-
|
|
747
|
-
/** Create a client component */
|
|
748
|
-
declare function createClientComponent(
|
|
749
|
-
element: HTMLElement,
|
|
750
|
-
initialState?: SerializableState
|
|
751
|
-
): ClientComponent;
|
|
752
|
-
|
|
753
|
-
/** Wait for DOM to be ready */
|
|
754
|
-
declare function ready(callback: ReadyCallback): Promise<void>;
|
|
755
|
-
|
|
756
|
-
/** DOM query utilities */
|
|
757
|
-
declare function $(selector: Selector): HTMLElement[];
|
|
758
|
-
declare function $$(selector: string): HTMLElement | null;
|
|
759
|
-
|
|
760
|
-
/** Event utilities */
|
|
761
|
-
declare function on(
|
|
762
|
-
element: HTMLElement | string,
|
|
763
|
-
event: string,
|
|
764
|
-
handler: EventHandler,
|
|
765
|
-
options?: EventListenerOptions | boolean
|
|
766
|
-
): void;
|
|
767
|
-
|
|
768
|
-
declare function off(
|
|
769
|
-
element: HTMLElement | string,
|
|
770
|
-
event?: string,
|
|
771
|
-
handler?: EventHandler
|
|
772
|
-
): void;
|
|
773
|
-
|
|
774
|
-
declare function trigger(
|
|
775
|
-
element: HTMLElement,
|
|
776
|
-
event: string,
|
|
777
|
-
data?: CustomEventData
|
|
778
|
-
): boolean;
|
|
779
|
-
|
|
780
|
-
declare function delegate(
|
|
781
|
-
container: HTMLElement,
|
|
782
|
-
selector: string,
|
|
783
|
-
event: string,
|
|
784
|
-
handler: EventHandler
|
|
785
|
-
): void;
|
|
786
|
-
|
|
787
|
-
/** Animation utilities */
|
|
788
|
-
declare function requestAnimationFrame(callback: AnimationCallback): number;
|
|
789
|
-
declare function cancelAnimationFrame(id: number): void;
|
|
790
|
-
|
|
791
|
-
/** Debounce and throttle utilities */
|
|
792
|
-
declare function debounce<T extends (...args: any[]) => any>(
|
|
793
|
-
func: T,
|
|
794
|
-
delay: number
|
|
795
|
-
): (...args: Parameters<T>) => void;
|
|
796
|
-
|
|
797
|
-
declare function throttle<T extends (...args: any[]) => any>(
|
|
798
|
-
func: T,
|
|
799
|
-
limit: number
|
|
800
|
-
): (...args: Parameters<T>) => void;
|
|
801
|
-
|
|
802
|
-
/** State management utilities */
|
|
803
|
-
declare function createStateManager(): ClientStateManager;
|
|
804
|
-
declare function syncState(options: StateSyncOptions): void;
|
|
805
|
-
|
|
806
|
-
/** Performance utilities */
|
|
807
|
-
declare function createPerformanceMonitor(): PerformanceMonitor;
|
|
808
|
-
|
|
809
|
-
/** HMR utilities */
|
|
810
|
-
declare function createHMRClient(config?: Partial<HMRConfig>): HMRClient;
|
|
811
|
-
declare function enableHMR(config?: Partial<HMRConfig>): Promise<void>;
|
|
812
|
-
export function createHotContext(moduleId: string): HotContext;
|
|
813
|
-
|
|
814
|
-
/** Intersection observer utilities */
|
|
815
|
-
declare function observeVisibility(
|
|
816
|
-
elements: HTMLElement | HTMLElement[],
|
|
817
|
-
callback: (entries: ExtendedIntersectionObserverEntry[]) => void,
|
|
818
|
-
options?: IntersectionObserverInit
|
|
819
|
-
): IntersectionObserver;
|
|
820
|
-
|
|
821
|
-
/** Lazy loading utilities */
|
|
822
|
-
declare function lazyLoad(
|
|
823
|
-
elements: HTMLElement | HTMLElement[],
|
|
824
|
-
options?: {
|
|
825
|
-
threshold?: number;
|
|
826
|
-
rootMargin?: string;
|
|
827
|
-
attribute?: string;
|
|
828
|
-
placeholder?: string;
|
|
829
|
-
}
|
|
830
|
-
): IntersectionObserver;
|
|
831
|
-
|
|
832
466
|
// ============================================================================
|
|
833
|
-
// State Serialization
|
|
467
|
+
// State Serialization
|
|
834
468
|
// ============================================================================
|
|
835
469
|
|
|
836
|
-
/** Serialize state to base64-encoded JSON */
|
|
837
|
-
export function serializeState(state: SerializableState): string;
|
|
470
|
+
/** Serialize state to base64-encoded JSON; `null` when nothing is serializable */
|
|
471
|
+
export function serializeState(state: SerializableState): string | null;
|
|
838
472
|
|
|
839
|
-
/** Deserialize state from base64-encoded JSON */
|
|
840
|
-
export function deserializeState(encoded: string): SerializableState;
|
|
473
|
+
/** Deserialize state from base64-encoded JSON; `null` when invalid */
|
|
474
|
+
export function deserializeState(encoded: string | null | undefined): SerializableState | null;
|
|
841
475
|
|
|
842
476
|
/** Extract state from DOM element's data-state attribute */
|
|
843
477
|
export function extractState(element: HTMLElement): SerializableState | null;
|
|
844
478
|
|
|
845
479
|
/** Serialize state with size warning (10KB threshold) */
|
|
846
|
-
export function serializeStateWithWarning(state: SerializableState, componentName?: string): string;
|
|
480
|
+
export function serializeStateWithWarning(state: SerializableState, componentName?: string): string | null;
|
|
847
481
|
|
|
848
482
|
// ============================================================================
|
|
849
|
-
// Mismatch Detection
|
|
483
|
+
// Mismatch Detection
|
|
850
484
|
// ============================================================================
|
|
851
485
|
|
|
852
|
-
/**
|
|
486
|
+
/**
|
|
487
|
+
* Detect mismatches between DOM and virtual DOM. An array `vNode` is compared
|
|
488
|
+
* with the element's children.
|
|
489
|
+
*/
|
|
853
490
|
export function detectMismatch(element: HTMLElement, vNode: CoherentNode): HydrationMismatch[];
|
|
854
491
|
|
|
855
|
-
/** Report mismatches with warnings or
|
|
492
|
+
/** Report mismatches with warnings, or throw with `strict` */
|
|
856
493
|
export function reportMismatches(
|
|
857
494
|
mismatches: HydrationMismatch[],
|
|
858
495
|
options?: { componentName?: string; strict?: boolean }
|
|
859
496
|
): void;
|
|
860
497
|
|
|
861
498
|
/** Format path for mismatch reporting */
|
|
862
|
-
export function formatPath(path: (string | number)[]): string;
|
|
499
|
+
export function formatPath(path: (string | number)[] | null | undefined): string;
|
|
863
500
|
|
|
864
501
|
// ============================================================================
|
|
865
|
-
// Event Delegation
|
|
502
|
+
// Event Delegation
|
|
866
503
|
// ============================================================================
|
|
867
504
|
|
|
868
505
|
/** Event delegation singleton */
|
|
@@ -871,106 +508,26 @@ export const eventDelegation: EventDelegation;
|
|
|
871
508
|
/** Handler registry singleton */
|
|
872
509
|
export const handlerRegistry: HandlerRegistry;
|
|
873
510
|
|
|
874
|
-
/**
|
|
511
|
+
/**
|
|
512
|
+
* Wrap a native event for a delegated handler: `target` is the element the
|
|
513
|
+
* handler is registered on, `componentRef` supplies state/setState/props.
|
|
514
|
+
*/
|
|
875
515
|
export function wrapEvent<S = any, E extends Event = Event>(
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
):
|
|
516
|
+
originalEvent: E,
|
|
517
|
+
target: Element,
|
|
518
|
+
componentRef?: HandlerComponentRef | null
|
|
519
|
+
): CoherentEvent<S, E>;
|
|
880
520
|
|
|
881
521
|
// ============================================================================
|
|
882
|
-
// HMR
|
|
522
|
+
// HMR
|
|
883
523
|
// ============================================================================
|
|
884
524
|
|
|
885
|
-
export const HMRClient: new (config?: Partial<HMRConfig>) => HMRClient;
|
|
886
525
|
export const hmrClient: HMRClient;
|
|
887
|
-
export const ModuleTracker: new () => ModuleTracker;
|
|
888
526
|
export const moduleTracker: ModuleTracker;
|
|
889
|
-
export const CleanupTracker: new () => CleanupTracker;
|
|
890
527
|
export const cleanupTracker: CleanupTracker;
|
|
891
|
-
export const StateCapturer: new () => StateCapturer;
|
|
892
528
|
export const stateCapturer: StateCapturer;
|
|
893
|
-
export const ErrorOverlay: new () => ErrorOverlay;
|
|
894
529
|
export const errorOverlay: ErrorOverlay;
|
|
895
|
-
export const ConnectionIndicator: new () => ConnectionIndicator;
|
|
896
530
|
export const connectionIndicator: ConnectionIndicator;
|
|
897
531
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
// ============================================================================
|
|
901
|
-
|
|
902
|
-
/** Default hydration selector */
|
|
903
|
-
declare const DEFAULT_HYDRATION_SELECTOR: string;
|
|
904
|
-
|
|
905
|
-
/** Component registry */
|
|
906
|
-
declare const componentRegistry: Map<string, ComponentRegistryEntry>;
|
|
907
|
-
|
|
908
|
-
/** Global state manager instance */
|
|
909
|
-
declare const globalStateManager: ClientStateManager;
|
|
910
|
-
|
|
911
|
-
/** Global event manager instance */
|
|
912
|
-
declare const globalEventManager: EventManager;
|
|
913
|
-
|
|
914
|
-
/** Global performance monitor instance */
|
|
915
|
-
declare const globalPerformanceMonitor: PerformanceMonitor;
|
|
916
|
-
|
|
917
|
-
// ============================================================================
|
|
918
|
-
// Default Export
|
|
919
|
-
// ============================================================================
|
|
920
|
-
|
|
921
|
-
declare const coherentClient: {
|
|
922
|
-
// Hydration
|
|
923
|
-
extractInitialState: typeof extractInitialState;
|
|
924
|
-
hydrate: typeof hydrate;
|
|
925
|
-
|
|
926
|
-
// Component registration
|
|
927
|
-
registerComponent: typeof registerComponent;
|
|
928
|
-
unregisterComponent: typeof unregisterComponent;
|
|
929
|
-
getComponent: typeof getComponent;
|
|
930
|
-
getAllComponents: typeof getAllComponents;
|
|
931
|
-
createClientComponent: typeof createClientComponent;
|
|
932
|
-
|
|
933
|
-
// DOM utilities
|
|
934
|
-
ready: typeof ready;
|
|
935
|
-
$: typeof $;
|
|
936
|
-
$$: typeof $$;
|
|
937
|
-
|
|
938
|
-
// Event utilities
|
|
939
|
-
on: typeof on;
|
|
940
|
-
off: typeof off;
|
|
941
|
-
trigger: typeof trigger;
|
|
942
|
-
delegate: typeof delegate;
|
|
943
|
-
|
|
944
|
-
// Animation utilities
|
|
945
|
-
requestAnimationFrame: typeof requestAnimationFrame;
|
|
946
|
-
cancelAnimationFrame: typeof cancelAnimationFrame;
|
|
947
|
-
|
|
948
|
-
// Utility functions
|
|
949
|
-
debounce: typeof debounce;
|
|
950
|
-
throttle: typeof throttle;
|
|
951
|
-
|
|
952
|
-
// State management
|
|
953
|
-
createStateManager: typeof createStateManager;
|
|
954
|
-
syncState: typeof syncState;
|
|
955
|
-
globalStateManager: typeof globalStateManager;
|
|
956
|
-
|
|
957
|
-
// Performance
|
|
958
|
-
createPerformanceMonitor: typeof createPerformanceMonitor;
|
|
959
|
-
globalPerformanceMonitor: typeof globalPerformanceMonitor;
|
|
960
|
-
|
|
961
|
-
// HMR
|
|
962
|
-
createHMRClient: typeof createHMRClient;
|
|
963
|
-
enableHMR: typeof enableHMR;
|
|
964
|
-
createHotContext: typeof createHotContext;
|
|
965
|
-
|
|
966
|
-
// Intersection Observer
|
|
967
|
-
observeVisibility: typeof observeVisibility;
|
|
968
|
-
lazyLoad: typeof lazyLoad;
|
|
969
|
-
|
|
970
|
-
// Constants
|
|
971
|
-
DEFAULT_HYDRATION_SELECTOR: typeof DEFAULT_HYDRATION_SELECTOR;
|
|
972
|
-
componentRegistry: typeof componentRegistry;
|
|
973
|
-
globalEventManager: typeof globalEventManager;
|
|
974
|
-
};
|
|
975
|
-
|
|
976
|
-
declare const _unused: typeof coherentClient;
|
|
532
|
+
/** Hot context for a module: `createHotContext(import.meta.url)` */
|
|
533
|
+
export function createHotContext(moduleId: string): HotContext;
|