@atolljs/core 0.1.6 → 0.1.8
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 +1 -1
- package/dist/contract/memoryDevtools.d.ts +30 -0
- package/dist/contract/sharedMemory.d.ts +6 -2
- package/dist/contract/types.d.ts +13 -0
- package/dist/devtools.d.ts +346 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +19 -16
- package/dist/index10.js +28 -184
- package/dist/index11.js +18 -48
- package/dist/index12.js +29 -63
- package/dist/index13.js +49 -24
- package/dist/index14.js +57 -59
- package/dist/index15.js +335 -45
- package/dist/index16.js +242 -47
- package/dist/index17.js +57 -38
- package/dist/index18.js +9 -86
- package/dist/index19.js +58 -48
- package/dist/index20.js +24 -56
- package/dist/index21.js +61 -0
- package/dist/index22.js +48 -0
- package/dist/index23.js +68 -0
- package/dist/index24.js +41 -0
- package/dist/index25.js +46 -0
- package/dist/index26.js +113 -0
- package/dist/index27.js +60 -0
- package/dist/index28.js +57 -0
- package/dist/index5.js +227 -35
- package/dist/index6.js +143 -471
- package/dist/index7.js +51 -20
- package/dist/index8.js +507 -27
- package/dist/index9.js +19 -18
- package/dist/pool/dedicatedWorker.d.ts +63 -0
- package/dist/pool/devtoolsCommands.d.ts +54 -0
- package/dist/pool/subWorkerClient.d.ts +50 -0
- package/dist/pool/workerChannel.d.ts +44 -0
- package/dist/pool/workerClient.d.ts +38 -8
- package/dist/pool/workerPool.d.ts +13 -0
- package/dist/reactive.d.ts +15 -0
- package/dist/reactiveGraph.d.ts +9 -0
- package/dist/userTiming.d.ts +27 -0
- package/package.json +2 -1
- package/src/contract/memoryDevtools.ts +249 -0
- package/src/contract/sharedMemory.ts +39 -9
- package/src/contract/types.ts +13 -0
- package/src/devtools.ts +735 -0
- package/src/index.ts +27 -1
- package/src/log.ts +22 -0
- package/src/observable.ts +16 -3
- package/src/pool/dedicatedWorker.ts +332 -0
- package/src/pool/devtoolsCommands.ts +165 -0
- package/src/pool/subWorkerClient.ts +70 -0
- package/src/pool/workerChannel.ts +99 -0
- package/src/pool/workerClient.ts +64 -15
- package/src/pool/workerPool.ts +115 -36
- package/src/reactive.ts +87 -12
- package/src/reactiveGraph.ts +91 -0
- package/src/testing/inProcessWorker.ts +4 -3
- package/src/userTiming.ts +71 -0
- package/src/worker/workerBootstrap.ts +29 -3
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ export const counter = connectWorker<CounterWorker>({
|
|
|
68
68
|
// Inline new Worker(new URL(..., import.meta.url)) — every bundler's
|
|
69
69
|
// worker transform can see the entry point this way.
|
|
70
70
|
worker: () => new Worker(new URL('./counter.worker.ts', import.meta.url), { type: 'module' }),
|
|
71
|
-
|
|
71
|
+
workers: 'auto', // navigator.hardwareConcurrency; default 1 (one worker, no pool)
|
|
72
72
|
});
|
|
73
73
|
// counter.increment(1) → Promise<number>. The pool spawns on first call
|
|
74
74
|
// (SSR-safe to import); counter.terminate() tears it down.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Connector, SharedMemory } from './sharedMemory.js';
|
|
2
|
+
export type WatchRule = {
|
|
3
|
+
text: string;
|
|
4
|
+
test: (value: unknown) => boolean;
|
|
5
|
+
};
|
|
6
|
+
interface WatchState {
|
|
7
|
+
rule: WatchRule;
|
|
8
|
+
/** Per contract: last version checked and last value preview ('change'). */
|
|
9
|
+
seen: WeakMap<SharedMemory<any>, {
|
|
10
|
+
version: number;
|
|
11
|
+
preview: string;
|
|
12
|
+
}>;
|
|
13
|
+
stop: () => void;
|
|
14
|
+
hits: number;
|
|
15
|
+
}
|
|
16
|
+
/** path → watch. Read by the write path — keep `.size` the only hot check. */
|
|
17
|
+
export declare const memoryWatches: Map<string, WatchState>;
|
|
18
|
+
/** Bounded preview of a field's current value — lists/typed arrays read only a head. */
|
|
19
|
+
export declare const fieldPreview: (connector: Connector<any>) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Parse a watch rule: 'change' | '> n' | '< n' | '>= n' | '<= n' | '== v' |
|
|
22
|
+
* '!= v'. `v` is JSON when it parses ('"down"', 'true', '3'), else a bare
|
|
23
|
+
* string. Numeric comparisons only match number/bigint fields.
|
|
24
|
+
*/
|
|
25
|
+
export declare const parseWatchRule: (raw: string) => WatchRule;
|
|
26
|
+
/** Write-path hook — only called when `memoryWatches.size > 0`. */
|
|
27
|
+
export declare const checkWatchOnWrite: (memory: SharedMemory<any>, path: string, version: number) => void;
|
|
28
|
+
/** Register the `memory.*` commands once; `contracts` lists every defined contract. */
|
|
29
|
+
export declare const ensureMemoryCommands: (contracts: () => readonly SharedMemory<any>[]) => void;
|
|
30
|
+
export {};
|
|
@@ -49,6 +49,8 @@ export interface ConnectorContext {
|
|
|
49
49
|
view: Int32Array;
|
|
50
50
|
index: number;
|
|
51
51
|
};
|
|
52
|
+
/** The field's contract path — for devtools write events on granular commits. */
|
|
53
|
+
path?: string;
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
54
56
|
* A connector factory builds a connector for one field kind over a region of
|
|
@@ -79,6 +81,8 @@ export interface Connector<T> {
|
|
|
79
81
|
view: Int32Array;
|
|
80
82
|
index: number;
|
|
81
83
|
};
|
|
84
|
+
/** Internal: the field's contract path — devtools node labels. */
|
|
85
|
+
readonly _path?: string;
|
|
82
86
|
}
|
|
83
87
|
export type ScalarKind = 'i8' | 'u8' | 'i16' | 'u16' | 'i32' | 'u32' | 'f32' | 'f64' | 'i64' | 'u64';
|
|
84
88
|
/** A fixed-layout member spec: a scalar kind, `{ string: n }` for an inline UTF-8 field of n bytes, or `{ bool: true }` for a flag byte. */
|
|
@@ -316,8 +320,8 @@ export declare class SharedMemory<S extends SharedSpec = SharedSpec> {
|
|
|
316
320
|
byteLength: number;
|
|
317
321
|
}[];
|
|
318
322
|
/**
|
|
319
|
-
* Fires when the contract is bound on this thread —
|
|
320
|
-
* bound. Returns an unsubscribe function.
|
|
323
|
+
* Fires when the contract is bound on this thread — on every bind, and
|
|
324
|
+
* immediately if already bound. Returns an unsubscribe function.
|
|
321
325
|
*/
|
|
322
326
|
onBound(cb: () => void): () => void;
|
|
323
327
|
/** Typed lookup for flat (ungrouped) field keys. */
|
package/dist/contract/types.d.ts
CHANGED
|
@@ -52,6 +52,17 @@ export interface WorkerPoolConfig<S extends SharedSpec = SharedSpec, T extends T
|
|
|
52
52
|
* skipped and workers receive a plain `{ type: 'INIT' }` handshake.
|
|
53
53
|
*/
|
|
54
54
|
sharedMemory?: SharedMemory<S> & Prettify<SharedAccess<S>>;
|
|
55
|
+
/**
|
|
56
|
+
* Hand an existing SharedArrayBuffer to every spawned worker instead of
|
|
57
|
+
* allocating a fresh `WebAssembly.Memory` — the worker-shell case: a worker
|
|
58
|
+
* already bound to a contract spawns sub-workers on the SAME buffer
|
|
59
|
+
* (`sharedBuffer: contract.buffer`), or a second pool shares the first
|
|
60
|
+
* pool's `pool.sharedBuffer`. A thunk is resolved once, when the pool
|
|
61
|
+
* constructs. With `sharedMemory` the contract binds locally to this
|
|
62
|
+
* buffer; without it the buffer still ships via INIT_MEMORY and the
|
|
63
|
+
* workers bind their own defined contracts.
|
|
64
|
+
*/
|
|
65
|
+
sharedBuffer?: SharedArrayBuffer | (() => SharedArrayBuffer | undefined);
|
|
55
66
|
/**
|
|
56
67
|
* Persistence adapter for `sharedMemory` — invoked with the contract right
|
|
57
68
|
* after the pool binds it, and its `stop()` runs on `terminate()`.
|
|
@@ -60,6 +71,8 @@ export interface WorkerPoolConfig<S extends SharedSpec = SharedSpec, T extends T
|
|
|
60
71
|
persistence?: (memory: SharedMemory<S>) => MemoryPersistence | undefined;
|
|
61
72
|
/** Worker count — a number, or 'auto' (the default) for navigator.hardwareConcurrency ?? 4. */
|
|
62
73
|
poolSize?: number | 'auto';
|
|
74
|
+
/** Display label for devtools/dashboards — falls back to a generated id. */
|
|
75
|
+
name?: string;
|
|
63
76
|
memory?: MemoryConfig;
|
|
64
77
|
/** Max in-flight tasks per worker (default 1); excess tasks queue FIFO. */
|
|
65
78
|
concurrency?: number;
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured instrumentation events for the devtools/dashboard tooling.
|
|
3
|
+
* Same zero-cost contract as `log.ts` and islands' `proxyMetrics`: when no
|
|
4
|
+
* sink is installed, emit() is a single branch — production pays nothing.
|
|
5
|
+
*
|
|
6
|
+
* Events are emitted on whichever thread they occur on. Worker-side events
|
|
7
|
+
* reach the main thread's sink by postMessage forwarding (`ATOLL_DEVTOOLS`
|
|
8
|
+
* on the task channel — the pool re-emits them), so one sink sees the whole
|
|
9
|
+
* app. See docs/plans/devtools-dashboard.md.
|
|
10
|
+
*/
|
|
11
|
+
export type DevtoolsThread = 'main' | 'worker';
|
|
12
|
+
export type TaskSettleOutcome = 'ok' | 'error' | 'aborted' | 'timeout' | 'queue-full' | 'crashed';
|
|
13
|
+
export type DevtoolsEvent = {
|
|
14
|
+
type: 'pool:init';
|
|
15
|
+
poolId: string;
|
|
16
|
+
/** Config `name`, when supplied — a display label, not the id. */
|
|
17
|
+
label?: string;
|
|
18
|
+
poolSize: number;
|
|
19
|
+
/** Per-worker in-flight cap; 0 for a dedicated worker (no queue, uncapped). */
|
|
20
|
+
concurrency: number;
|
|
21
|
+
memoryBytes?: number;
|
|
22
|
+
/**
|
|
23
|
+
* True for a single dedicated worker (`connectWorker({ workers: 1 })`,
|
|
24
|
+
* island clients): no pool, no queue. Same event vocabulary otherwise.
|
|
25
|
+
*/
|
|
26
|
+
dedicated?: boolean;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'pool:terminate';
|
|
29
|
+
poolId: string;
|
|
30
|
+
} | {
|
|
31
|
+
type: 'worker:spawn';
|
|
32
|
+
poolId: string;
|
|
33
|
+
slot: number;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'worker:error';
|
|
36
|
+
poolId: string;
|
|
37
|
+
slot: number;
|
|
38
|
+
message: string;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'worker:respawn';
|
|
41
|
+
poolId: string;
|
|
42
|
+
slot: number;
|
|
43
|
+
} | {
|
|
44
|
+
type: 'task:enqueue';
|
|
45
|
+
poolId: string;
|
|
46
|
+
callId: number;
|
|
47
|
+
taskId: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: 'task:dispatch';
|
|
50
|
+
poolId: string;
|
|
51
|
+
callId: number;
|
|
52
|
+
taskId: string;
|
|
53
|
+
slot: number;
|
|
54
|
+
waitMs: number;
|
|
55
|
+
/** Estimated structured-clone size of the task args (`estimateCloneBytes`). */
|
|
56
|
+
argBytes?: number;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'task:settle';
|
|
59
|
+
poolId: string;
|
|
60
|
+
callId: number;
|
|
61
|
+
taskId: string;
|
|
62
|
+
outcome: TaskSettleOutcome;
|
|
63
|
+
/** dispatch→reply; absent for calls that never ran. */
|
|
64
|
+
runMs?: number;
|
|
65
|
+
error?: string;
|
|
66
|
+
/** Estimated structured-clone size of the result (`estimateCloneBytes`). */
|
|
67
|
+
resultBytes?: number;
|
|
68
|
+
} | {
|
|
69
|
+
type: 'memory:bind';
|
|
70
|
+
/** Version-counter index → field path, for pairing memory:write. */
|
|
71
|
+
fields: [index: number, path: string][];
|
|
72
|
+
totalBytes: number;
|
|
73
|
+
} | {
|
|
74
|
+
type: 'memory:write';
|
|
75
|
+
path: string;
|
|
76
|
+
version: number;
|
|
77
|
+
} | {
|
|
78
|
+
/** A dashboard-set watchpoint matched on write (`memory.watch` command). */
|
|
79
|
+
type: 'memory:watch-hit';
|
|
80
|
+
path: string;
|
|
81
|
+
version: number;
|
|
82
|
+
/** Preview of the written value (`previewValue`). */
|
|
83
|
+
value: string;
|
|
84
|
+
/** The watch rule as set, e.g. '> 100', 'change', '== "down"'. */
|
|
85
|
+
rule: string;
|
|
86
|
+
} | {
|
|
87
|
+
type: 'island:mount';
|
|
88
|
+
instance: string;
|
|
89
|
+
app: string;
|
|
90
|
+
pid: string;
|
|
91
|
+
/** The client pool driving this island — links the island to its worker. */
|
|
92
|
+
poolId?: string;
|
|
93
|
+
/** Renderer/framework tag supplied by the mounter — observability only. */
|
|
94
|
+
framework?: string;
|
|
95
|
+
} | {
|
|
96
|
+
type: 'island:unmount';
|
|
97
|
+
instance: string;
|
|
98
|
+
} | {
|
|
99
|
+
type: 'island:event';
|
|
100
|
+
instance: string;
|
|
101
|
+
name: string;
|
|
102
|
+
/** Preview of the emitted payload (`previewValue`). */
|
|
103
|
+
payload?: string;
|
|
104
|
+
} | {
|
|
105
|
+
/** The props an island currently holds: sent on mount and every updateProps. */
|
|
106
|
+
type: 'island:props';
|
|
107
|
+
instance: string;
|
|
108
|
+
/** Preview of the props object (`previewValue`); callbacks show as '[fn]'. */
|
|
109
|
+
props: string;
|
|
110
|
+
} | {
|
|
111
|
+
type: 'island:task';
|
|
112
|
+
instance: string;
|
|
113
|
+
/** The client call behind the round-trip — the island's "request". */
|
|
114
|
+
method: 'mount' | 'whoami' | 'dispatch' | 'setSize' | 'updateProps' | 'flush' | 'unmount';
|
|
115
|
+
/** Round-trip ms: call → ops returned (worker render + transport). */
|
|
116
|
+
ms: number;
|
|
117
|
+
/** Op count in the returned batch (response size in ops). */
|
|
118
|
+
ops?: number;
|
|
119
|
+
error?: string;
|
|
120
|
+
} | {
|
|
121
|
+
type: 'island:ops';
|
|
122
|
+
instance: string;
|
|
123
|
+
/** The client call that produced the batch. */
|
|
124
|
+
via: 'mount' | 'updateProps' | 'dispatch' | 'setSize' | 'flush' | 'unmount';
|
|
125
|
+
count: number;
|
|
126
|
+
/** Main-thread replay time; worker-side render time rides call timings. */
|
|
127
|
+
replayMs?: number;
|
|
128
|
+
/** Estimated structured-clone size of the op batch (`estimateCloneBytes`). */
|
|
129
|
+
bytes?: number;
|
|
130
|
+
} | {
|
|
131
|
+
type: 'net:fetch';
|
|
132
|
+
/** Per-context sequence — correlates the net:fetch-detail follow-up. */
|
|
133
|
+
id: number;
|
|
134
|
+
url: string;
|
|
135
|
+
method: string;
|
|
136
|
+
/** HTTP status — absent when the request failed before a response. */
|
|
137
|
+
status?: number;
|
|
138
|
+
/** Time from dispatch to response headers (error: to failure). */
|
|
139
|
+
ms: number;
|
|
140
|
+
/** Response Content-Length when advertised. */
|
|
141
|
+
bytes?: number;
|
|
142
|
+
error?: string;
|
|
143
|
+
reqHeaders?: [string, string][];
|
|
144
|
+
/** Capped preview; non-text bodies are described, not dumped. */
|
|
145
|
+
reqBody?: string;
|
|
146
|
+
} | {
|
|
147
|
+
/**
|
|
148
|
+
* Detail follow-up to net:fetch (same id) — emitted after the response
|
|
149
|
+
* settles so it can carry headers, a capped body preview, and the
|
|
150
|
+
* Resource Timing stage breakdown once the entry exists.
|
|
151
|
+
*/
|
|
152
|
+
type: 'net:fetch-detail';
|
|
153
|
+
id: number;
|
|
154
|
+
/** Present when the body was only readable async (Request objects). */
|
|
155
|
+
reqBody?: string;
|
|
156
|
+
resHeaders?: [string, string][];
|
|
157
|
+
resBody?: string;
|
|
158
|
+
/**
|
|
159
|
+
* Stage ms from PerformanceResourceTiming: queue (stalled → fetch
|
|
160
|
+
* start), dns, tcp, tls, wait (request → first byte), download.
|
|
161
|
+
* Absent for cross-origin responses without Timing-Allow-Origin.
|
|
162
|
+
*/
|
|
163
|
+
timing?: {
|
|
164
|
+
queue: number;
|
|
165
|
+
dns: number;
|
|
166
|
+
tcp: number;
|
|
167
|
+
tls: number;
|
|
168
|
+
wait: number;
|
|
169
|
+
download: number;
|
|
170
|
+
};
|
|
171
|
+
transferSize?: number;
|
|
172
|
+
encodedSize?: number;
|
|
173
|
+
decodedSize?: number;
|
|
174
|
+
} | {
|
|
175
|
+
type: 'runtime:memory';
|
|
176
|
+
/**
|
|
177
|
+
* measureUserAgentSpecificMemory: cluster total.
|
|
178
|
+
* performance.memory / process.memoryUsage fallback: this context's
|
|
179
|
+
* usedJSHeapSize / heapUsed.
|
|
180
|
+
*/
|
|
181
|
+
heapBytes: number;
|
|
182
|
+
heapLimitBytes?: number;
|
|
183
|
+
/** Resident set size — present on the Node memoryUsage() path. */
|
|
184
|
+
rssBytes?: number;
|
|
185
|
+
/**
|
|
186
|
+
* Per-execution-context attribution from
|
|
187
|
+
* `performance.measureUserAgentSpecificMemory` — emitted on the main
|
|
188
|
+
* thread only (workers can't self-identify among same-URL contexts).
|
|
189
|
+
* Worker contexts are identified by their script URL.
|
|
190
|
+
*/
|
|
191
|
+
contexts?: {
|
|
192
|
+
bytes: number;
|
|
193
|
+
scope?: string;
|
|
194
|
+
url?: string;
|
|
195
|
+
}[];
|
|
196
|
+
} | {
|
|
197
|
+
/**
|
|
198
|
+
* A main-thread frame that blocked rendering: Long Animation Frame
|
|
199
|
+
* entries where supported, `longtask` entries as the fallback.
|
|
200
|
+
*/
|
|
201
|
+
type: 'runtime:longframe';
|
|
202
|
+
/** Frame (or long task) duration. */
|
|
203
|
+
ms: number;
|
|
204
|
+
/** Time past the 50ms budget that blocked input/render. */
|
|
205
|
+
blockingMs: number;
|
|
206
|
+
/** LoAF script attribution, longest first (capped). */
|
|
207
|
+
scripts?: {
|
|
208
|
+
src?: string;
|
|
209
|
+
fn?: string;
|
|
210
|
+
ms: number;
|
|
211
|
+
}[];
|
|
212
|
+
/**
|
|
213
|
+
* Page was hidden: frame duration is throttling, not work, so only
|
|
214
|
+
* frames with substantial script time are reported. Excluded from
|
|
215
|
+
* foreground jank metrics.
|
|
216
|
+
*/
|
|
217
|
+
hidden?: boolean;
|
|
218
|
+
} | {
|
|
219
|
+
/** Main-thread frame rate, sampled once a second via rAF while devtools is on. */
|
|
220
|
+
type: 'runtime:frames';
|
|
221
|
+
fps: number;
|
|
222
|
+
/** Frames over ~2× the display interval in that second. */
|
|
223
|
+
dropped: number;
|
|
224
|
+
} | {
|
|
225
|
+
/** A `src/log.ts` entry, mirrored into the stream (worker logs forward too). */
|
|
226
|
+
type: 'log';
|
|
227
|
+
level: 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
228
|
+
scope: string;
|
|
229
|
+
message: string;
|
|
230
|
+
/** Preview of the structured data (`previewValue`). */
|
|
231
|
+
data?: string;
|
|
232
|
+
} | {
|
|
233
|
+
/**
|
|
234
|
+
* Cross-thread reactivity edge/node update for the dependency graph.
|
|
235
|
+
* `id` names a reactive source or subscriber; `deps` are the ids it reads.
|
|
236
|
+
*/
|
|
237
|
+
type: 'reactive:node';
|
|
238
|
+
id: string;
|
|
239
|
+
kind: 'source' | 'derived' | 'effect' | 'bridge';
|
|
240
|
+
label?: string;
|
|
241
|
+
deps?: string[];
|
|
242
|
+
/** Thread-qualified owner, e.g. a pool id or island instance. */
|
|
243
|
+
owner?: string;
|
|
244
|
+
/** Set when the node is disposed. */
|
|
245
|
+
disposed?: boolean;
|
|
246
|
+
};
|
|
247
|
+
export type EmittedDevtoolsEvent = DevtoolsEvent & {
|
|
248
|
+
/** performance.now() on the emitting thread. */
|
|
249
|
+
at: number;
|
|
250
|
+
/** Which side of the boundary emitted the event. */
|
|
251
|
+
thread: DevtoolsThread;
|
|
252
|
+
/**
|
|
253
|
+
* Stamped by the pool when re-emitting a worker-forwarded event —
|
|
254
|
+
* attributes worker-side events (memory writes, fetches, heap samples)
|
|
255
|
+
* to the specific pool slot that produced them.
|
|
256
|
+
*/
|
|
257
|
+
worker?: {
|
|
258
|
+
poolId: string;
|
|
259
|
+
slot: number;
|
|
260
|
+
};
|
|
261
|
+
};
|
|
262
|
+
export type DevtoolsSink = (event: EmittedDevtoolsEvent) => void;
|
|
263
|
+
/**
|
|
264
|
+
* Install the transport sink (devtools transports hook here); null removes
|
|
265
|
+
* it. Additive sinks (`addDevtoolsSink`) are unaffected.
|
|
266
|
+
*/
|
|
267
|
+
export declare const setDevtoolsSink: (custom: DevtoolsSink | null) => void;
|
|
268
|
+
/**
|
|
269
|
+
* Add a listener alongside the transport sink (exporters like OTLP);
|
|
270
|
+
* returns its remover. Any installed listener turns `devtoolsEnabled()` on,
|
|
271
|
+
* so pools spawned afterwards enable worker forwarding the same way.
|
|
272
|
+
*/
|
|
273
|
+
export declare const addDevtoolsSink: (listener: DevtoolsSink) => (() => void);
|
|
274
|
+
/** Emit a structured event — one branch when no sink is installed. */
|
|
275
|
+
export declare const emitDevtools: (event: DevtoolsEvent) => void;
|
|
276
|
+
/**
|
|
277
|
+
* Re-emit an already-stamped event — for forwarding worker-side events that
|
|
278
|
+
* arrived over postMessage without re-stamping their timing/thread.
|
|
279
|
+
*/
|
|
280
|
+
export declare const forwardDevtools: (event: EmittedDevtoolsEvent) => void;
|
|
281
|
+
/** True when a devtools sink (transport or additive listener) is installed on this thread. */
|
|
282
|
+
export declare const devtoolsEnabled: () => boolean;
|
|
283
|
+
/**
|
|
284
|
+
* Compact, bounded preview of any value for event payloads: JSON-ish,
|
|
285
|
+
* functions as '[fn]', typed arrays/buffers described by size, cycles cut,
|
|
286
|
+
* capped at `max` chars. Call only behind `devtoolsEnabled()`.
|
|
287
|
+
*/
|
|
288
|
+
export declare const previewValue: (value: unknown, max?: number) => string;
|
|
289
|
+
/**
|
|
290
|
+
* Rough structured-clone size in bytes: strings 2B/char, numbers 8B,
|
|
291
|
+
* typed arrays/buffers by byteLength, plus small per-key overhead. A cost
|
|
292
|
+
* signal for the dashboard ("is this message big?"), not an exact count.
|
|
293
|
+
* Walks at most `budget` nodes. Call only behind `devtoolsEnabled()`.
|
|
294
|
+
*/
|
|
295
|
+
export declare const estimateCloneBytes: (value: unknown, budget?: number) => number;
|
|
296
|
+
/**
|
|
297
|
+
* A command the dashboard can invoke on this app (`control` frames on the
|
|
298
|
+
* devtools transport). Args and result must be structured-cloneable and
|
|
299
|
+
* JSON-safe (the WebSocket path stringifies them).
|
|
300
|
+
*/
|
|
301
|
+
export type DevtoolsCommandHandler = (args: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
302
|
+
/**
|
|
303
|
+
* Register a dashboard-invocable command; returns an unregister function.
|
|
304
|
+
* Names are dotted by area: 'island.tree', 'worker.kill', 'memory.read'.
|
|
305
|
+
* A later registration under the same name replaces the earlier one.
|
|
306
|
+
*/
|
|
307
|
+
export declare const registerDevtoolsCommand: (name: string, handler: DevtoolsCommandHandler) => (() => void);
|
|
308
|
+
/** Names of the registered commands — the dashboard enables controls from this. */
|
|
309
|
+
export declare const listDevtoolsCommands: () => string[];
|
|
310
|
+
/** Run a registered command (transports call this for inbound `control` frames). */
|
|
311
|
+
export declare const runDevtoolsCommand: (name: string, args?: Record<string, unknown>) => Promise<unknown>;
|
|
312
|
+
/**
|
|
313
|
+
* Worker side: route emitted events to the main thread over the task
|
|
314
|
+
* channel (`ATOLL_DEVTOOLS` messages — the pool re-emits them into its
|
|
315
|
+
* sink). Switched on by the pool's INIT handshake when the pool has a
|
|
316
|
+
* sink installed, so workers only forward when someone is listening.
|
|
317
|
+
*/
|
|
318
|
+
export declare const enableWorkerDevtoolsForwarding: () => void;
|
|
319
|
+
/**
|
|
320
|
+
* Wrap `scope.fetch` to emit `net:fetch` (+ a `net:fetch-detail` follow-up
|
|
321
|
+
* with headers/body previews and stage timings) for every request — covers
|
|
322
|
+
* main thread (installed by connectDevtools) and workers (installed by the
|
|
323
|
+
* INIT handshake's forwarding flag). Idempotent; restores nothing (the
|
|
324
|
+
* wrapper delegates to the captured original). XHR is not covered.
|
|
325
|
+
*/
|
|
326
|
+
export declare const installFetchProbe: (scope: {
|
|
327
|
+
fetch?: typeof fetch;
|
|
328
|
+
}) => void;
|
|
329
|
+
/**
|
|
330
|
+
* Emit `runtime:memory` periodically — JS heap usage. On the main thread,
|
|
331
|
+
* prefers `performance.measureUserAgentSpecificMemory()`, which reports a
|
|
332
|
+
* per-execution-context breakdown (windows + workers identified by script
|
|
333
|
+
* URL) for the whole agent cluster; falls back to `performance.memory`,
|
|
334
|
+
* which also covers the worker-side install on engines that expose it
|
|
335
|
+
* there, then `process.memoryUsage()` on Node (heapUsed + rss — works
|
|
336
|
+
* inside worker_threads too). No-ops with none of the three.
|
|
337
|
+
*/
|
|
338
|
+
export declare const installMemoryProbe: (scope: object, intervalMs?: number) => void;
|
|
339
|
+
/**
|
|
340
|
+
* Process-unique ids for runners. Unnamed: 'pool-1', 'worker-2', … Named:
|
|
341
|
+
* the slugged name plus a kind suffix, '-p' for a pool and '-w' for a
|
|
342
|
+
* dedicated worker ('regions-p', 'ops-inline-w'); a repeated name gets a
|
|
343
|
+
* counter ('regions-w', 'regions-w2'). Slugs never contain '#', '~' or
|
|
344
|
+
* '|', which the dashboard uses to qualify forwarded ids.
|
|
345
|
+
*/
|
|
346
|
+
export declare const nextDevtoolsId: (prefix: string, name?: string) => string;
|
package/dist/index.d.ts
CHANGED
|
@@ -11,8 +11,12 @@ export { MemoryManager } from './pool/memory.js';
|
|
|
11
11
|
export { WorkerPool } from './pool/workerPool.js';
|
|
12
12
|
export type { PoolStats, RunOptions } from './pool/workerPool.js';
|
|
13
13
|
export { PoolQueueFullError, TaskAbortedError, TaskTimeoutError, WorkerCrashedError, } from './pool/errors.js';
|
|
14
|
-
export {
|
|
15
|
-
export type {
|
|
14
|
+
export { DedicatedWorker } from './pool/dedicatedWorker.js';
|
|
15
|
+
export type { DedicatedWorkerConfig } from './pool/dedicatedWorker.js';
|
|
16
|
+
export { connectWorker, resolveWorkerCount, workerClient } from './pool/workerClient.js';
|
|
17
|
+
export type { ClientMethods, ConnectWorkerConfig, WorkerClient, WorkerMethods, WorkerRunner, } from './pool/workerClient.js';
|
|
18
|
+
export { connectSubWorker } from './pool/subWorkerClient.js';
|
|
19
|
+
export type { ConnectSubWorkerConfig } from './pool/subWorkerClient.js';
|
|
16
20
|
export { connectSharedWorker } from './shared/sharedWorkerClient.js';
|
|
17
21
|
export type { SharedWorkerClient } from './shared/sharedWorkerClient.js';
|
|
18
22
|
export { sharedWorkerHost } from './shared/sharedWorkerHost.js';
|
|
@@ -29,3 +33,5 @@ export { defineTask, isAsyncTask, toTask } from './task.js';
|
|
|
29
33
|
export type { AsyncTask, TaskSnapshot } from './task.js';
|
|
30
34
|
export { getLogLevel, log, scoped, setLogLevel, setLogSink } from './log.js';
|
|
31
35
|
export type { LogEntry, LogLevel, LogSink } from './log.js';
|
|
36
|
+
export { addDevtoolsSink, devtoolsEnabled, emitDevtools, estimateCloneBytes, installFetchProbe, installMemoryProbe, listDevtoolsCommands, previewValue, registerDevtoolsCommand, runDevtoolsCommand, setDevtoolsSink, } from './devtools.js';
|
|
37
|
+
export type { DevtoolsCommandHandler, DevtoolsEvent, DevtoolsSink, DevtoolsThread, EmittedDevtoolsEvent, TaskSettleOutcome, } from './devtools.js';
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { msgpackrCodec as e } from "./index2.js";
|
|
2
2
|
import { SchemaError as t, z as n } from "./index3.js";
|
|
3
3
|
import { listSchema as r } from "./index4.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
4
|
+
import { addDevtoolsSink as i, devtoolsEnabled as a, emitDevtools as o, estimateCloneBytes as s, installFetchProbe as c, installMemoryProbe as l, listDevtoolsCommands as u, previewValue as d, registerDevtoolsCommand as f, runDevtoolsCommand as p, setDevtoolsSink as m } from "./index5.js";
|
|
5
|
+
import { getLogLevel as h, log as g, scoped as _, setLogLevel as v, setLogSink as y } from "./index7.js";
|
|
6
|
+
import { bindSharedMemories as b, defineSharedMemory as x, field as S, getDefinedSharedMemoryCount as C, jsonCodec as w, registerConnectorFactory as T } from "./index8.js";
|
|
7
|
+
import { reef as E } from "./index9.js";
|
|
8
|
+
import { MemoryManager as D } from "./index10.js";
|
|
9
|
+
import { PoolQueueFullError as O, TaskAbortedError as k, TaskTimeoutError as A, WorkerCrashedError as j } from "./index11.js";
|
|
10
|
+
import { WorkerPool as M } from "./index15.js";
|
|
11
|
+
import { DedicatedWorker as N } from "./index16.js";
|
|
12
|
+
import { connectWorker as P, resolveWorkerCount as F, workerClient as I } from "./index17.js";
|
|
13
|
+
import { connectSubWorker as L } from "./index18.js";
|
|
14
|
+
import { connectSharedWorker as R } from "./index19.js";
|
|
15
|
+
import { TaskRegistry as z } from "./index20.js";
|
|
16
|
+
import { sharedWorkerHost as B } from "./index21.js";
|
|
17
|
+
import { createClient as V, defineService as H, implementService as U, rpc as W, serviceMethod as G } from "./index22.js";
|
|
18
|
+
import { RESERVED_CLIENT_KEYS as K, defineWorker as q } from "./index24.js";
|
|
19
|
+
import { reactive as J, shallowEqual as Y, watch as X } from "./index26.js";
|
|
20
|
+
import { observe as Z } from "./index27.js";
|
|
21
|
+
import { defineTask as Q, isAsyncTask as $, toTask as ee } from "./index28.js";
|
|
22
|
+
export { N as DedicatedWorker, D as MemoryManager, O as PoolQueueFullError, K as RESERVED_CLIENT_KEYS, t as SchemaError, k as TaskAbortedError, z as TaskRegistry, A as TaskTimeoutError, j as WorkerCrashedError, M as WorkerPool, i as addDevtoolsSink, b as bindSharedMemories, R as connectSharedWorker, L as connectSubWorker, P as connectWorker, V as createClient, H as defineService, x as defineSharedMemory, Q as defineTask, q as defineWorker, a as devtoolsEnabled, o as emitDevtools, s as estimateCloneBytes, S as field, C as getDefinedSharedMemoryCount, h as getLogLevel, U as implementService, c as installFetchProbe, l as installMemoryProbe, $ as isAsyncTask, w as jsonCodec, u as listDevtoolsCommands, r as listSchema, g as log, e as msgpackrCodec, Z as observe, d as previewValue, J as reactive, E as reef, T as registerConnectorFactory, f as registerDevtoolsCommand, F as resolveWorkerCount, W as rpc, p as runDevtoolsCommand, _ as scoped, G as serviceMethod, m as setDevtoolsSink, v as setLogLevel, y as setLogSink, Y as shallowEqual, B as sharedWorkerHost, ee as toTask, X as watch, I as workerClient, n as z };
|