@lifeart/async-dom 2.0.0-alpha.3
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/LICENSE +21 -0
- package/README.md +623 -0
- package/dist/base.d.cts +398 -0
- package/dist/base.d.cts.map +1 -0
- package/dist/base.d.ts +398 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/cli.cjs +528 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +493 -0
- package/dist/cli.js.map +1 -0
- package/dist/debug.d.cts +145 -0
- package/dist/debug.d.cts.map +1 -0
- package/dist/debug.d.ts +145 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/index.cjs +26 -0
- package/dist/index.d.cts +560 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +560 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index2.d.cts +5 -0
- package/dist/index2.d.ts +5 -0
- package/dist/index3.d.cts +882 -0
- package/dist/index3.d.cts.map +1 -0
- package/dist/index3.d.ts +882 -0
- package/dist/index3.d.ts.map +1 -0
- package/dist/main-thread.cjs +5459 -0
- package/dist/main-thread.cjs.map +1 -0
- package/dist/main-thread.js +5429 -0
- package/dist/main-thread.js.map +1 -0
- package/dist/react.cjs +116 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +91 -0
- package/dist/react.d.cts.map +1 -0
- package/dist/react.d.ts +91 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +113 -0
- package/dist/react.js.map +1 -0
- package/dist/resolve-debug.cjs +24 -0
- package/dist/resolve-debug.cjs.map +1 -0
- package/dist/resolve-debug.js +19 -0
- package/dist/resolve-debug.js.map +1 -0
- package/dist/server.cjs +250 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +127 -0
- package/dist/server.d.cts.map +1 -0
- package/dist/server.d.ts +127 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +245 -0
- package/dist/server.js.map +1 -0
- package/dist/svelte.cjs +48 -0
- package/dist/svelte.cjs.map +1 -0
- package/dist/svelte.d.cts +38 -0
- package/dist/svelte.d.cts.map +1 -0
- package/dist/svelte.d.ts +38 -0
- package/dist/svelte.d.ts.map +1 -0
- package/dist/svelte.js +47 -0
- package/dist/svelte.js.map +1 -0
- package/dist/sync-channel.cjs +532 -0
- package/dist/sync-channel.cjs.map +1 -0
- package/dist/sync-channel.js +425 -0
- package/dist/sync-channel.js.map +1 -0
- package/dist/transport.cjs +213 -0
- package/dist/transport.cjs.map +1 -0
- package/dist/transport.d.cts +79 -0
- package/dist/transport.d.cts.map +1 -0
- package/dist/transport.d.ts +79 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +202 -0
- package/dist/transport.js.map +1 -0
- package/dist/vite-plugin.cjs +112 -0
- package/dist/vite-plugin.cjs.map +1 -0
- package/dist/vite-plugin.d.cts +39 -0
- package/dist/vite-plugin.d.cts.map +1 -0
- package/dist/vite-plugin.d.ts +39 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +107 -0
- package/dist/vite-plugin.js.map +1 -0
- package/dist/vue.cjs +123 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.cts +126 -0
- package/dist/vue.d.cts.map +1 -0
- package/dist/vue.d.ts +126 -0
- package/dist/vue.d.ts.map +1 -0
- package/dist/vue.js +120 -0
- package/dist/vue.js.map +1 -0
- package/dist/worker-thread.cjs +2751 -0
- package/dist/worker-thread.cjs.map +1 -0
- package/dist/worker-thread.js +2692 -0
- package/dist/worker-thread.js.map +1 -0
- package/dist/worker-transport.cjs +136 -0
- package/dist/worker-transport.cjs.map +1 -0
- package/dist/worker-transport.d.cts +162 -0
- package/dist/worker-transport.d.cts.map +1 -0
- package/dist/worker-transport.d.ts +162 -0
- package/dist/worker-transport.d.ts.map +1 -0
- package/dist/worker-transport.js +125 -0
- package/dist/worker-transport.js.map +1 -0
- package/dist/worker.cjs +12 -0
- package/dist/worker.d.cts +2 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.js +2 -0
- package/dist/ws-server-transport.cjs +147 -0
- package/dist/ws-server-transport.cjs.map +1 -0
- package/dist/ws-server-transport.d.cts +64 -0
- package/dist/ws-server-transport.d.cts.map +1 -0
- package/dist/ws-server-transport.d.ts +64 -0
- package/dist/ws-server-transport.d.ts.map +1 -0
- package/dist/ws-server-transport.js +142 -0
- package/dist/ws-server-transport.js.map +1 -0
- package/dist/ws-transport.cjs +954 -0
- package/dist/ws-transport.cjs.map +1 -0
- package/dist/ws-transport.js +913 -0
- package/dist/ws-transport.js.map +1 -0
- package/package.json +145 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
import { _ as Priority, c as DomMutation, g as NodeId, i as AppId, p as Message, t as Transport, v as SerializedError } from "./base.cjs";
|
|
2
|
+
import { a as MutationLogEntry, l as WarningLogEntry, n as DebugOptions } from "./debug.cjs";
|
|
3
|
+
import { c as WebSocketTransportOptions } from "./worker-transport.cjs";
|
|
4
|
+
|
|
5
|
+
//#region src/core/html-sanitizer.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Lightweight HTML sanitizer for async-dom.
|
|
9
|
+
*
|
|
10
|
+
* Strips dangerous tags and attributes to prevent XSS when
|
|
11
|
+
* worker-provided HTML is injected via innerHTML or insertAdjacentHTML.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Sanitize an HTML string by removing dangerous tags and attributes.
|
|
15
|
+
*
|
|
16
|
+
* Uses the browser's DOMParser to parse the HTML, walks the resulting tree,
|
|
17
|
+
* and removes any elements/attributes that could execute scripts or load
|
|
18
|
+
* external resources in a dangerous way.
|
|
19
|
+
*/
|
|
20
|
+
declare function sanitizeHTML(html: string): string;
|
|
21
|
+
//# sourceMappingURL=html-sanitizer.d.ts.map
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/core/scheduler.d.ts
|
|
24
|
+
/** Configuration for the FrameScheduler. All fields are optional with sensible defaults. */
|
|
25
|
+
interface SchedulerConfig {
|
|
26
|
+
/** Maximum milliseconds to spend processing mutations per frame (default: 16ms for 60fps). */
|
|
27
|
+
frameBudgetMs?: number;
|
|
28
|
+
/** Whether to skip off-screen style mutations (default: true). */
|
|
29
|
+
enableViewportCulling?: boolean;
|
|
30
|
+
/** Whether to drop optional mutations under frame pressure (default: true). */
|
|
31
|
+
enablePrioritySkipping?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** Diagnostic record for a single frame, used by devtools flamechart visualization. */
|
|
34
|
+
interface FrameLogEntry {
|
|
35
|
+
/** Monotonically increasing frame counter. */
|
|
36
|
+
frameId: number;
|
|
37
|
+
/** Wall-clock time spent in this frame's tick(), in milliseconds. */
|
|
38
|
+
totalMs: number;
|
|
39
|
+
/** Number of mutations applied during this frame. */
|
|
40
|
+
actionCount: number;
|
|
41
|
+
/** Cumulative time per mutation action type (e.g., "setAttribute" -> 1.2ms). */
|
|
42
|
+
timingBreakdown: Map<string, number>;
|
|
43
|
+
/** Per-app mutation counts and deferred counts per frame (multi-app mode). */
|
|
44
|
+
perApp?: Map<string, {
|
|
45
|
+
mutations: number;
|
|
46
|
+
deferred: number;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
/** Callback that applies a single mutation to the real DOM (typically DomRenderer.apply). */
|
|
50
|
+
type MutationApplier = (mutation: DomMutation, appId: AppId, batchUid?: number) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Frame-budget scheduler that processes DOM mutations within requestAnimationFrame
|
|
53
|
+
* callbacks, respecting a configurable time budget per frame.
|
|
54
|
+
*
|
|
55
|
+
* Key features preserved from the original vm.js:
|
|
56
|
+
* - Adaptive batch sizing based on measured action execution times
|
|
57
|
+
* - Priority sorting (high > normal > low, non-optional before optional)
|
|
58
|
+
* - Viewport culling for optional style mutations
|
|
59
|
+
* - Graceful degradation: skip optional mutations under pressure
|
|
60
|
+
*/
|
|
61
|
+
declare class FrameScheduler {
|
|
62
|
+
/** Priority-sorted queue of pending mutations awaiting application. */
|
|
63
|
+
private queue;
|
|
64
|
+
/** Most recent execution time per action type, used for adaptive batch sizing. */
|
|
65
|
+
private actionTimes;
|
|
66
|
+
private frameId;
|
|
67
|
+
private running;
|
|
68
|
+
private rafId;
|
|
69
|
+
private uidCounter;
|
|
70
|
+
private timePerLastFrame;
|
|
71
|
+
private totalActionsLastFrame;
|
|
72
|
+
/** True while the user is scrolling; triggers skipping of optional mutations. */
|
|
73
|
+
private isScrolling;
|
|
74
|
+
private scrollTimer;
|
|
75
|
+
private scrollAbort;
|
|
76
|
+
private viewportHeight;
|
|
77
|
+
private viewportWidth;
|
|
78
|
+
/** Cache of element-id -> in-viewport results to avoid repeated getBoundingClientRect. */
|
|
79
|
+
private boundingRectCache;
|
|
80
|
+
/** Frame number when each viewport cache entry was last computed. */
|
|
81
|
+
private boundingRectCacheFrame;
|
|
82
|
+
private readonly frameBudgetMs;
|
|
83
|
+
private readonly enableViewportCulling;
|
|
84
|
+
private readonly enablePrioritySkipping;
|
|
85
|
+
private applier;
|
|
86
|
+
/** Number of active apps; enables per-app fairness budget splitting when > 1. */
|
|
87
|
+
private appCount;
|
|
88
|
+
/** Per-app mutation count within the current frame, reset each tick. */
|
|
89
|
+
private appBudgets;
|
|
90
|
+
private lastTickTime;
|
|
91
|
+
private healthCheckTimer;
|
|
92
|
+
private queueOverflowWarned;
|
|
93
|
+
private lastEnqueueTime;
|
|
94
|
+
/** Count of frames where processing time exceeded the frame budget. */
|
|
95
|
+
private droppedFrameCount;
|
|
96
|
+
private lastWorkerToMainLatencyMs;
|
|
97
|
+
/** Rolling log of the last MAX_FRAME_LOG frames for devtools inspection. */
|
|
98
|
+
private frameLog;
|
|
99
|
+
constructor(config?: SchedulerConfig);
|
|
100
|
+
/** Set the function that applies each mutation to the real DOM. */
|
|
101
|
+
setApplier(applier: MutationApplier): void;
|
|
102
|
+
/** Update the number of active apps for per-app fairness budgeting. */
|
|
103
|
+
setAppCount(count: number): void;
|
|
104
|
+
/**
|
|
105
|
+
* Add mutations to the scheduling queue.
|
|
106
|
+
* Mutations are not applied immediately; they wait for the next frame tick.
|
|
107
|
+
* Emits a warning if the queue exceeds 10,000 items (indicates a processing bottleneck).
|
|
108
|
+
*
|
|
109
|
+
* @param mutations - Array of DOM mutations to schedule
|
|
110
|
+
* @param appId - Owning app, used for per-app fairness
|
|
111
|
+
* @param priority - Scheduling priority (default: "normal")
|
|
112
|
+
* @param batchUid - Optional batch identifier for grouping
|
|
113
|
+
*/
|
|
114
|
+
enqueue(mutations: DomMutation[], appId: AppId, priority?: Priority, batchUid?: number): void;
|
|
115
|
+
/** Start the rAF loop. Sets up scroll detection and a 1-second health check. */
|
|
116
|
+
start(): void;
|
|
117
|
+
private scheduleFrame;
|
|
118
|
+
/** Stop the rAF loop, cancel pending frames, and tear down scroll listeners. */
|
|
119
|
+
stop(): void;
|
|
120
|
+
clearViewportCache(): void;
|
|
121
|
+
/** Synchronously apply all queued mutations, bypassing frame budget. Used for teardown. */
|
|
122
|
+
flush(): void;
|
|
123
|
+
/** Number of mutations waiting to be applied. */
|
|
124
|
+
get pendingCount(): number;
|
|
125
|
+
/** Record the cross-thread latency from a worker MutationMessage.sentAt */
|
|
126
|
+
recordWorkerLatency(sentAt: number): void;
|
|
127
|
+
/** Return a snapshot of scheduler metrics for devtools and diagnostics. */
|
|
128
|
+
getStats(): {
|
|
129
|
+
pending: number;
|
|
130
|
+
frameId: number;
|
|
131
|
+
lastFrameTimeMs: number;
|
|
132
|
+
lastFrameActions: number;
|
|
133
|
+
isRunning: boolean;
|
|
134
|
+
lastTickTime: number;
|
|
135
|
+
enqueueToApplyMs: number;
|
|
136
|
+
droppedFrameCount: number;
|
|
137
|
+
workerToMainLatencyMs: number;
|
|
138
|
+
};
|
|
139
|
+
/** Return a copy of the rolling frame log (last 30 frames). */
|
|
140
|
+
getFrameLog(): FrameLogEntry[];
|
|
141
|
+
/**
|
|
142
|
+
* Core frame loop. Processes as many queued mutations as the frame budget allows.
|
|
143
|
+
*
|
|
144
|
+
* Algorithm:
|
|
145
|
+
* 1. Sort queue by priority (high > normal > low), then optional last, then FIFO
|
|
146
|
+
* 2. Compute maxActions via getActionsForFrame() (adaptive batch sizing)
|
|
147
|
+
* 3. Iterate queue, skipping optional mutations under pressure (shouldSkip)
|
|
148
|
+
* 4. In multi-app mode, enforce per-app fairness caps (maxActions / appCount)
|
|
149
|
+
* 5. Break if elapsed time exceeds frameBudgetMs (unless queue is critically large)
|
|
150
|
+
* 6. Re-enqueue deferred items for the next frame
|
|
151
|
+
*/
|
|
152
|
+
private tick;
|
|
153
|
+
/** Schedule the next tick, delaying if the frame finished early to avoid busy-spinning. */
|
|
154
|
+
private scheduleNext;
|
|
155
|
+
/**
|
|
156
|
+
* Determine how many mutations to attempt this frame using adaptive batch sizing.
|
|
157
|
+
*
|
|
158
|
+
* Strategy (escalating by queue pressure):
|
|
159
|
+
* - Queue > 25k: emergency flush — process everything in one frame
|
|
160
|
+
* - Queue >= MAX_QUEUE_BEFORE_FLUSH (3000): process FLUSH_BATCH_SIZE (500)
|
|
161
|
+
* - Queue > CRITICAL_QUEUE_SIZE (1500): process up to CRITICAL_QUEUE_SIZE
|
|
162
|
+
* - Otherwise: use the measured average action time to estimate how many
|
|
163
|
+
* actions fit in 3x the frame budget (the 3x multiplier allows the time-
|
|
164
|
+
* based break in tick() to be the real limiter, while ensuring enough
|
|
165
|
+
* work is attempted). Falls back to 2000 when no timing data exists yet.
|
|
166
|
+
*/
|
|
167
|
+
private getActionsForFrame;
|
|
168
|
+
/**
|
|
169
|
+
* Decide whether to skip an optional mutation to preserve frame budget.
|
|
170
|
+
* Non-optional mutations are never skipped. Optional mutations are skipped when:
|
|
171
|
+
* - User is actively scrolling (visual updates would be wasted)
|
|
172
|
+
* - Queue is large (> half of CRITICAL_QUEUE_SIZE), indicating backpressure
|
|
173
|
+
* - Previous frame exceeded budget (prevent cascading frame drops)
|
|
174
|
+
*/
|
|
175
|
+
private shouldSkip;
|
|
176
|
+
/** Record the execution time for an action type. The 0.02ms bias prevents zero-time entries from skewing averages. */
|
|
177
|
+
private recordTiming;
|
|
178
|
+
private getAvgActionTime;
|
|
179
|
+
private calcViewportSize;
|
|
180
|
+
/**
|
|
181
|
+
* Check if an element is within the viewport, using a per-frame cache to
|
|
182
|
+
* avoid repeated getBoundingClientRect calls. Cache entries expire after
|
|
183
|
+
* VIEWPORT_CACHE_FRAMES (60) frames.
|
|
184
|
+
*/
|
|
185
|
+
isInViewport(elem: Element): boolean;
|
|
186
|
+
private setupScrollListener;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/core/node-cache.d.ts
|
|
191
|
+
/**
|
|
192
|
+
* Cache for mapping NodeIds to real DOM nodes on the main thread.
|
|
193
|
+
* Supports both forward (NodeId → Node) and reverse (Node → NodeId) lookups.
|
|
194
|
+
*/
|
|
195
|
+
declare class NodeCache {
|
|
196
|
+
private cache;
|
|
197
|
+
private reverseCache;
|
|
198
|
+
get(id: NodeId): Node | null;
|
|
199
|
+
/** Reverse lookup: get the NodeId for a real DOM node. */
|
|
200
|
+
getId(node: Node): NodeId | null;
|
|
201
|
+
set(id: NodeId, node: Node): void;
|
|
202
|
+
delete(id: NodeId): void;
|
|
203
|
+
clear(): void;
|
|
204
|
+
has(id: NodeId): boolean;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=node-cache.d.ts.map
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/main-thread/event-bridge.d.ts
|
|
209
|
+
/**
|
|
210
|
+
* Trace record for a single DOM event round-trip, tracking:
|
|
211
|
+
* - serializeMs: time to serialize the DOM event on the main thread
|
|
212
|
+
* - transportMs: estimated message transit time (main -> worker -> main)
|
|
213
|
+
* - dispatchMs: time the worker spent dispatching the event to handlers
|
|
214
|
+
* - mutationCount: number of mutations the event handler produced
|
|
215
|
+
*/
|
|
216
|
+
interface EventTraceEntry {
|
|
217
|
+
eventType: string;
|
|
218
|
+
listenerId: string;
|
|
219
|
+
/** Time spent serializing the DOM event to a plain object. */
|
|
220
|
+
serializeMs: number;
|
|
221
|
+
/** performance.now() when the trace was created. */
|
|
222
|
+
timestamp: number;
|
|
223
|
+
/** Date.now() when the event was sent, used to compute transportMs on response. */
|
|
224
|
+
sentAt: number;
|
|
225
|
+
/** Estimated round-trip transport time excluding worker dispatch time. */
|
|
226
|
+
transportMs?: number;
|
|
227
|
+
/** Time the worker spent in event handler dispatch. */
|
|
228
|
+
dispatchMs?: number;
|
|
229
|
+
/** Number of mutations generated by the event handler. */
|
|
230
|
+
mutationCount?: number;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Bridges real DOM events on the main thread to the worker thread.
|
|
234
|
+
* Uses AbortController for clean listener removal.
|
|
235
|
+
*/
|
|
236
|
+
declare class EventBridge {
|
|
237
|
+
/** Map of listenerId -> AbortController, used for clean listener removal. */
|
|
238
|
+
private listeners;
|
|
239
|
+
/** Per-event configuration (e.g., preventDefault) keyed by "{nodeId}_{eventName}". */
|
|
240
|
+
private eventConfig;
|
|
241
|
+
private nodeCache;
|
|
242
|
+
private transport;
|
|
243
|
+
private appId;
|
|
244
|
+
/** Rolling buffer of the last MAX_EVENT_TRACES event traces for diagnostics. */
|
|
245
|
+
private eventTraces;
|
|
246
|
+
private _onTimingResult;
|
|
247
|
+
constructor(appId: AppId, nodeCache?: NodeCache);
|
|
248
|
+
/**
|
|
249
|
+
* Set a callback that is invoked whenever a trace entry is fully
|
|
250
|
+
* populated with worker timing data. This allows callers (e.g. the
|
|
251
|
+
* devtools debug hooks) to emit EventLogEntry objects.
|
|
252
|
+
*/
|
|
253
|
+
set onTimingResult(cb: ((trace: EventTraceEntry) => void) | null);
|
|
254
|
+
setTransport(transport: Transport): void;
|
|
255
|
+
setNodeCache(nodeCache: NodeCache): void;
|
|
256
|
+
/**
|
|
257
|
+
* Configure event behavior for a specific node/event pair.
|
|
258
|
+
* If preventDefault is set on a normally-passive event (e.g., touchstart),
|
|
259
|
+
* the listener is detached and re-attached as non-passive so preventDefault works.
|
|
260
|
+
*/
|
|
261
|
+
configureEvent(nodeId: NodeId, eventName: string, config: {
|
|
262
|
+
preventDefault: boolean;
|
|
263
|
+
passive?: boolean;
|
|
264
|
+
}): void;
|
|
265
|
+
/**
|
|
266
|
+
* Attach a real DOM event listener that serializes the event and sends it to the worker.
|
|
267
|
+
* Uses AbortController for deterministic cleanup. Idempotent: re-attaching the same
|
|
268
|
+
* listenerId aborts the previous listener first.
|
|
269
|
+
*/
|
|
270
|
+
attach(nodeId: NodeId, eventName: string, listenerId: string): void;
|
|
271
|
+
/** Remove a single listener by its ID, aborting the AbortController. */
|
|
272
|
+
detach(listenerId: string): void;
|
|
273
|
+
/** Remove all listeners attached to a specific node (called when a node is removed). */
|
|
274
|
+
detachByNodeId(nodeId: NodeId): void;
|
|
275
|
+
getEventTraces(): EventTraceEntry[];
|
|
276
|
+
/**
|
|
277
|
+
* Update the most recent trace entry for a given listener with
|
|
278
|
+
* dispatch and mutation count timing from the worker.
|
|
279
|
+
* Transport time is computed on the main thread to avoid cross-origin
|
|
280
|
+
* timing issues between main thread and worker `performance.now()`.
|
|
281
|
+
*/
|
|
282
|
+
updateTraceWithWorkerTiming(listenerId: string, dispatchMs: number, mutationCount: number): void;
|
|
283
|
+
getListenersForNode(nodeId: NodeId): Array<{
|
|
284
|
+
listenerId: string;
|
|
285
|
+
eventName: string;
|
|
286
|
+
}>;
|
|
287
|
+
/** Remove all listeners across all nodes. Called during teardown. */
|
|
288
|
+
detachAll(): void;
|
|
289
|
+
private _isPassiveForListener;
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=event-bridge.d.ts.map
|
|
292
|
+
//#endregion
|
|
293
|
+
//#region src/main-thread/renderer.d.ts
|
|
294
|
+
/**
|
|
295
|
+
* Security permissions controlling which mutation types the renderer will execute.
|
|
296
|
+
* Defaults are restrictive; enable only what the app needs.
|
|
297
|
+
*/
|
|
298
|
+
interface RendererPermissions {
|
|
299
|
+
/** Allow appending nodes directly to <head> (e.g., for injecting styles). */
|
|
300
|
+
allowHeadAppend: boolean;
|
|
301
|
+
/** Allow appending nodes directly to <body>. */
|
|
302
|
+
allowBodyAppend: boolean;
|
|
303
|
+
/** Allow history.pushState/replaceState calls. */
|
|
304
|
+
allowNavigation: boolean;
|
|
305
|
+
/** Allow window.scrollTo calls. */
|
|
306
|
+
allowScroll: boolean;
|
|
307
|
+
/** Bypass HTML sanitization for innerHTML/insertAdjacentHTML. */
|
|
308
|
+
allowUnsafeHTML: boolean;
|
|
309
|
+
/** Additional DOM property names allowed for setProperty beyond the built-in list. */
|
|
310
|
+
additionalAllowedProperties?: string[];
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Root elements for the renderer's DOM mount point.
|
|
314
|
+
* Defaults to document.body/head/documentElement but can be overridden
|
|
315
|
+
* to render into a shadow DOM or iframe.
|
|
316
|
+
*/
|
|
317
|
+
interface RendererRoot {
|
|
318
|
+
/** The element or shadow root that serves as the `<body>` equivalent. */
|
|
319
|
+
body: Element | ShadowRoot;
|
|
320
|
+
/** The element or shadow root that serves as the `<head>` equivalent. */
|
|
321
|
+
head: Element | ShadowRoot;
|
|
322
|
+
/** The element that serves as the `<html>` equivalent. */
|
|
323
|
+
html: Element;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Configuration for automatic content-visibility: auto on top-level children
|
|
327
|
+
* of the mount point, enabling the browser to skip rendering off-screen subtrees.
|
|
328
|
+
*/
|
|
329
|
+
interface ContentVisibilityConfig {
|
|
330
|
+
/** Whether the optimization is active. */
|
|
331
|
+
enabled: boolean;
|
|
332
|
+
/** CSS `contain-intrinsic-size` value applied to container elements (e.g. `"auto 500px"`). */
|
|
333
|
+
intrinsicSize: string;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Applies DOM mutations from the worker thread to the real browser DOM.
|
|
337
|
+
*
|
|
338
|
+
* Maintains a NodeCache mapping worker-side NodeIds to real DOM Node references.
|
|
339
|
+
* Each mutation type is dispatched through the apply() method, which acts as
|
|
340
|
+
* the single entry point for the scheduler.
|
|
341
|
+
*
|
|
342
|
+
* Security: blocks on* attribute handlers, javascript: URIs, and restricts
|
|
343
|
+
* which DOM properties can be set via an allowlist.
|
|
344
|
+
*/
|
|
345
|
+
declare class DomRenderer {
|
|
346
|
+
/** Maps NodeId -> real DOM Node for O(1) lookup during mutation application. */
|
|
347
|
+
private nodeCache;
|
|
348
|
+
private permissions;
|
|
349
|
+
private root;
|
|
350
|
+
private _additionalAllowedProperties;
|
|
351
|
+
/** Callback invoked when a node is removed, allowing EventBridge to detach listeners. */
|
|
352
|
+
onNodeRemoved: ((id: NodeId) => void) | null;
|
|
353
|
+
private _onWarning;
|
|
354
|
+
private _onMutation;
|
|
355
|
+
private highlightEnabled;
|
|
356
|
+
private _contentVisibility;
|
|
357
|
+
setDebugHooks(hooks: {
|
|
358
|
+
onWarning?: ((e: WarningLogEntry) => void) | null;
|
|
359
|
+
onMutation?: ((e: MutationLogEntry) => void) | null;
|
|
360
|
+
}): void;
|
|
361
|
+
enableHighlightUpdates(enabled: boolean): void;
|
|
362
|
+
setContentVisibility(config: ContentVisibilityConfig | null): void;
|
|
363
|
+
private highlightNode;
|
|
364
|
+
constructor(nodeCache?: NodeCache, permissions?: Partial<RendererPermissions>, root?: RendererRoot);
|
|
365
|
+
/**
|
|
366
|
+
* Apply a single DOM mutation to the real DOM.
|
|
367
|
+
* This is the main entry point called by the FrameScheduler's applier callback.
|
|
368
|
+
* Event-related mutations (addEventListener, configureEvent, removeEventListener)
|
|
369
|
+
* are no-ops here as they are handled by EventBridge.
|
|
370
|
+
*
|
|
371
|
+
* @param mutation - The mutation to apply
|
|
372
|
+
* @param batchUid - Optional batch identifier for debug logging
|
|
373
|
+
*/
|
|
374
|
+
apply(mutation: DomMutation, batchUid?: number): void;
|
|
375
|
+
/** Look up the real DOM node for a given NodeId, or null if not cached. */
|
|
376
|
+
getNode(id: NodeId): Node | null;
|
|
377
|
+
clear(): void;
|
|
378
|
+
/**
|
|
379
|
+
* Clear the node cache but preserve structural nodes (BODY, HEAD, HTML, DOCUMENT).
|
|
380
|
+
* Used during replay to allow re-creation of dynamic nodes while keeping the
|
|
381
|
+
* root structure intact.
|
|
382
|
+
*/
|
|
383
|
+
resetNodeCache(): void;
|
|
384
|
+
getRoot(): RendererRoot;
|
|
385
|
+
/**
|
|
386
|
+
* Create a DOM element or text node and store it in the node cache.
|
|
387
|
+
* Structural tags (HTML, BODY, HEAD) are mapped to existing DOM elements rather than created.
|
|
388
|
+
* Tags starting with "#" are treated as text nodes.
|
|
389
|
+
* SVG tags are created with the SVG namespace.
|
|
390
|
+
*/
|
|
391
|
+
private createNode;
|
|
392
|
+
private createComment;
|
|
393
|
+
private appendChild;
|
|
394
|
+
private removeNode;
|
|
395
|
+
private removeChild;
|
|
396
|
+
private insertBefore;
|
|
397
|
+
private setAttribute;
|
|
398
|
+
private removeAttribute;
|
|
399
|
+
private setStyle;
|
|
400
|
+
private setProperty;
|
|
401
|
+
private setTextContent;
|
|
402
|
+
private setClassName;
|
|
403
|
+
private setHTML;
|
|
404
|
+
private insertAdjacentHTML;
|
|
405
|
+
private headAppendChild;
|
|
406
|
+
private bodyAppendChild;
|
|
407
|
+
/**
|
|
408
|
+
* Call a whitelisted method on a DOM node (e.g., focus, play, showModal).
|
|
409
|
+
* Methods not in ALLOWED_METHODS are silently blocked.
|
|
410
|
+
*/
|
|
411
|
+
private callMethod;
|
|
412
|
+
/** Inline element tags that should not receive content-visibility. */
|
|
413
|
+
private static readonly INLINE_TAGS;
|
|
414
|
+
/**
|
|
415
|
+
* Apply content-visibility: auto to top-level children of the mount point.
|
|
416
|
+
* Only applies to block-level HTMLElements that don't already have it set.
|
|
417
|
+
*/
|
|
418
|
+
private _applyContentVisibility;
|
|
419
|
+
/**
|
|
420
|
+
* Notify onNodeRemoved for a node and all its descendants.
|
|
421
|
+
* This ensures EventBridge detaches listeners on the entire subtree.
|
|
422
|
+
*/
|
|
423
|
+
private _cleanupSubtreeListeners;
|
|
424
|
+
}
|
|
425
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
426
|
+
//#endregion
|
|
427
|
+
//#region src/main-thread/thread-manager.d.ts
|
|
428
|
+
interface WorkerConfig {
|
|
429
|
+
worker: Worker;
|
|
430
|
+
transport?: Transport;
|
|
431
|
+
/** Human-readable name for this app (shown in DevTools instead of a random hash) */
|
|
432
|
+
name?: string;
|
|
433
|
+
}
|
|
434
|
+
interface RemoteConfig {
|
|
435
|
+
transport: Transport;
|
|
436
|
+
name?: string;
|
|
437
|
+
}
|
|
438
|
+
interface WebSocketConfig {
|
|
439
|
+
url: string;
|
|
440
|
+
options?: WebSocketTransportOptions;
|
|
441
|
+
/** Human-readable name for this app (shown in DevTools instead of a random hash) */
|
|
442
|
+
name?: string;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Manages multiple worker/WebSocket connections, routing messages
|
|
446
|
+
* between the main thread and isolated app threads.
|
|
447
|
+
*/
|
|
448
|
+
declare class ThreadManager {
|
|
449
|
+
private threads;
|
|
450
|
+
private messageHandlers;
|
|
451
|
+
createWorkerThread(config: WorkerConfig): AppId;
|
|
452
|
+
createRemoteThread(config: RemoteConfig): AppId;
|
|
453
|
+
createWebSocketThread(config: WebSocketConfig): AppId;
|
|
454
|
+
sendToThread(appId: AppId, message: Message): void;
|
|
455
|
+
broadcast(message: Message): void;
|
|
456
|
+
destroyThread(appId: AppId): void;
|
|
457
|
+
destroyAll(): void;
|
|
458
|
+
onMessage(handler: (appId: AppId, message: Message) => void): void;
|
|
459
|
+
getTransport(appId: AppId): Transport | null;
|
|
460
|
+
private notifyHandlers;
|
|
461
|
+
/** Generate a unique AppId, appending a suffix if the name already exists. */
|
|
462
|
+
private _uniqueAppId;
|
|
463
|
+
}
|
|
464
|
+
//# sourceMappingURL=thread-manager.d.ts.map
|
|
465
|
+
//#endregion
|
|
466
|
+
//#region src/main-thread/index.d.ts
|
|
467
|
+
/**
|
|
468
|
+
* Configuration for {@link createAsyncDom}.
|
|
469
|
+
*
|
|
470
|
+
* At minimum, provide a `target` element where worker-rendered DOM will be mounted.
|
|
471
|
+
* Optionally pass a `worker` to immediately register the first app.
|
|
472
|
+
*/
|
|
473
|
+
interface AsyncDomConfig {
|
|
474
|
+
/** The DOM element that serves as the rendering root for worker-produced mutations. */
|
|
475
|
+
target: Element;
|
|
476
|
+
/** Optional initial worker. If provided, it is registered as the first app automatically. */
|
|
477
|
+
worker?: Worker;
|
|
478
|
+
/** Frame-budget scheduler tuning options. */
|
|
479
|
+
scheduler?: SchedulerConfig;
|
|
480
|
+
/** Debug logging and devtools panel options. */
|
|
481
|
+
debug?: DebugOptions;
|
|
482
|
+
/**
|
|
483
|
+
* Enable `content-visibility: auto` on top-level container elements for off-screen
|
|
484
|
+
* rendering optimization. Pass `true` for defaults, or an object with a custom
|
|
485
|
+
* `intrinsicSize` (CSS value, default `"auto 500px"`).
|
|
486
|
+
*/
|
|
487
|
+
contentVisibility?: boolean | {
|
|
488
|
+
intrinsicSize?: string;
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Configuration for adding a worker-backed app via {@link AsyncDomInstance.addApp}.
|
|
493
|
+
*/
|
|
494
|
+
interface AppConfig {
|
|
495
|
+
/** The Web Worker instance that runs this app's UI logic. */
|
|
496
|
+
worker: Worker;
|
|
497
|
+
/** Human-readable name for this app (shown in DevTools instead of a random hash). */
|
|
498
|
+
name?: string;
|
|
499
|
+
/** CSS selector or Element where this app's DOM will be mounted. Defaults to the instance root. */
|
|
500
|
+
mountPoint?: string | Element;
|
|
501
|
+
/** Attach to a Shadow DOM root for CSS isolation. Pass `true` for `{ mode: "open" }` or a custom `ShadowRootInit`. */
|
|
502
|
+
shadow?: boolean | ShadowRootInit;
|
|
503
|
+
/** Custom transport to use instead of the default `WorkerTransport`. */
|
|
504
|
+
transport?: Transport;
|
|
505
|
+
/** Called when the worker reports an unhandled error or unhandled promise rejection. */
|
|
506
|
+
onError?: (error: SerializedError, appId: AppId) => void;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Configuration for adding a remote (non-worker) app via {@link AsyncDomInstance.addRemoteApp}.
|
|
510
|
+
*
|
|
511
|
+
* Remote apps communicate over a custom transport (e.g. WebSocket) rather than
|
|
512
|
+
* a local Web Worker.
|
|
513
|
+
*/
|
|
514
|
+
interface RemoteAppConfig {
|
|
515
|
+
/** The transport used to communicate with the remote process. */
|
|
516
|
+
transport: Transport;
|
|
517
|
+
/** Human-readable name for this app (shown in DevTools instead of a random hash). */
|
|
518
|
+
name?: string;
|
|
519
|
+
/** CSS selector or Element where this app's DOM will be mounted. Defaults to the instance root. */
|
|
520
|
+
mountPoint?: string | Element;
|
|
521
|
+
/** Attach to a Shadow DOM root for CSS isolation. Pass `true` for `{ mode: "open" }` or a custom `ShadowRootInit`. */
|
|
522
|
+
shadow?: boolean | ShadowRootInit;
|
|
523
|
+
/** Called when the remote process reports an unhandled error. */
|
|
524
|
+
onError?: (error: SerializedError, appId: AppId) => void;
|
|
525
|
+
/** Enable `SharedArrayBuffer`-based sync channel for synchronous DOM reads. Default: `false`. */
|
|
526
|
+
enableSyncChannel?: boolean;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Handle returned by {@link createAsyncDom}.
|
|
530
|
+
*
|
|
531
|
+
* Controls the lifecycle of the async-dom instance: starting/stopping the
|
|
532
|
+
* scheduler, adding/removing apps, and tearing down all resources.
|
|
533
|
+
*/
|
|
534
|
+
interface AsyncDomInstance {
|
|
535
|
+
/** Start the frame-budget scheduler. Mutations begin applying to the DOM. */
|
|
536
|
+
start(): void;
|
|
537
|
+
/** Pause the scheduler. Mutations are queued but not applied until `start()` is called. */
|
|
538
|
+
stop(): void;
|
|
539
|
+
/** Stop the scheduler, flush remaining mutations, tear down all apps, and release all resources. */
|
|
540
|
+
destroy(): void;
|
|
541
|
+
/** Register a new worker-backed app. Returns a unique `AppId` for later removal. */
|
|
542
|
+
addApp(config: AppConfig): AppId;
|
|
543
|
+
/** Register a new remote app using a custom transport. Returns a unique `AppId` for later removal. */
|
|
544
|
+
addRemoteApp(config: RemoteAppConfig): AppId;
|
|
545
|
+
/** Remove an app by its `AppId`, detaching its event listeners and clearing its rendered DOM. */
|
|
546
|
+
removeApp(appId: AppId): void;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Creates a new async-dom instance on the main thread.
|
|
550
|
+
*
|
|
551
|
+
* This is the primary entry point for using async-dom. It:
|
|
552
|
+
* - Creates a scheduler for frame-budgeted rendering
|
|
553
|
+
* - Creates per-app renderers for applying DOM mutations (isolation)
|
|
554
|
+
* - Creates an event bridge for forwarding events to workers
|
|
555
|
+
* - Manages worker threads
|
|
556
|
+
*/
|
|
557
|
+
declare function createAsyncDom(config: AsyncDomConfig): AsyncDomInstance;
|
|
558
|
+
//#endregion
|
|
559
|
+
export { sanitizeHTML as _, createAsyncDom as a, WebSocketConfig as c, DomRenderer as d, RendererPermissions as f, SchedulerConfig as g, FrameScheduler as h, RemoteAppConfig as i, WorkerConfig as l, EventBridge as m, AsyncDomConfig as n, RemoteConfig as o, RendererRoot as p, AsyncDomInstance as r, ThreadManager as s, AppConfig as t, ContentVisibilityConfig as u };
|
|
560
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/core/html-sanitizer.ts","../src/core/scheduler.ts","../src/core/node-cache.ts","../src/main-thread/event-bridge.ts","../src/main-thread/renderer.ts","../src/main-thread/thread-manager.ts","../src/main-thread/index.ts"],"sourcesContent":[],"mappings":"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"}
|