lopata 0.18.4 → 0.19.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.
Files changed (106) hide show
  1. package/dist/types/api/dispatch.d.ts +2 -2
  2. package/dist/types/api/handlers/workflows.d.ts +2 -2
  3. package/dist/types/bindings/container-cleanup.d.ts +43 -0
  4. package/dist/types/bindings/container-docker.d.ts +24 -0
  5. package/dist/types/bindings/container.d.ts +4 -2
  6. package/dist/types/bindings/do-executor-worker.d.ts +73 -89
  7. package/dist/types/bindings/do-executor.d.ts +22 -1
  8. package/dist/types/bindings/do-worker-env.d.ts +16 -7
  9. package/dist/types/bindings/durable-object.d.ts +66 -4
  10. package/dist/types/bindings/queue.d.ts +4 -1
  11. package/dist/types/bindings/rpc-stub.d.ts +23 -1
  12. package/dist/types/bindings/scheduled.d.ts +13 -3
  13. package/dist/types/bindings/service-binding.d.ts +13 -4
  14. package/dist/types/bindings/static-assets.d.ts +1 -1
  15. package/dist/types/bindings/websocket-pair.d.ts +12 -3
  16. package/dist/types/bindings/workflow.d.ts +29 -0
  17. package/dist/types/config.d.ts +2 -0
  18. package/dist/types/env.d.ts +6 -0
  19. package/dist/types/error-page-render.d.ts +6 -0
  20. package/dist/types/execution-context.d.ts +8 -0
  21. package/dist/types/generation-manager.d.ts +21 -2
  22. package/dist/types/generation.d.ts +16 -21
  23. package/dist/types/import-graph.d.ts +28 -0
  24. package/dist/types/lopata-config.d.ts +3 -3
  25. package/dist/types/plugin.d.ts +4 -1
  26. package/dist/types/rpc-validate.d.ts +9 -0
  27. package/dist/types/setup-globals.d.ts +5 -1
  28. package/dist/types/tracing/context.d.ts +12 -0
  29. package/dist/types/tracing/span.d.ts +21 -3
  30. package/dist/types/tracing/store.d.ts +17 -0
  31. package/dist/types/tsconfig.tsbuildinfo +1 -1
  32. package/dist/types/vite-plugin/index.d.ts +8 -1
  33. package/dist/types/worker-registry.d.ts +11 -4
  34. package/dist/types/worker-thread/do-protocol.d.ts +256 -0
  35. package/dist/types/worker-thread/entry.d.ts +2 -0
  36. package/dist/types/worker-thread/execution-context.d.ts +22 -0
  37. package/dist/types/worker-thread/executor.d.ts +123 -0
  38. package/dist/types/worker-thread/protocol.d.ts +553 -0
  39. package/dist/types/worker-thread/remote-trace-store.d.ts +27 -0
  40. package/dist/types/worker-thread/rpc-client.d.ts +4 -0
  41. package/dist/types/worker-thread/rpc-shared.d.ts +138 -0
  42. package/dist/types/worker-thread/serialize.d.ts +12 -0
  43. package/dist/types/worker-thread/stream-shared.d.ts +147 -0
  44. package/dist/types/worker-thread/thread-env.d.ts +42 -0
  45. package/dist/types/worker-thread/wire-handlers.d.ts +16 -0
  46. package/dist/types/worker-thread/ws-bridge-shared.d.ts +163 -0
  47. package/package.json +1 -1
  48. package/src/api/handlers/containers.ts +2 -1
  49. package/src/api/handlers/workflows.ts +39 -34
  50. package/src/bindings/container-cleanup.ts +125 -0
  51. package/src/bindings/container-docker.ts +49 -34
  52. package/src/bindings/container.ts +24 -9
  53. package/src/bindings/do-executor-inprocess.ts +9 -5
  54. package/src/bindings/do-executor-worker.ts +386 -158
  55. package/src/bindings/do-executor.ts +23 -1
  56. package/src/bindings/do-worker-entry.ts +242 -60
  57. package/src/bindings/do-worker-env.ts +296 -11
  58. package/src/bindings/durable-object.ts +231 -27
  59. package/src/bindings/email.ts +6 -0
  60. package/src/bindings/queue.ts +11 -1
  61. package/src/bindings/rpc-stub.ts +79 -10
  62. package/src/bindings/scheduled.ts +37 -30
  63. package/src/bindings/service-binding.ts +87 -33
  64. package/src/bindings/static-assets.ts +3 -2
  65. package/src/bindings/websocket-pair.ts +19 -3
  66. package/src/bindings/workflow.ts +91 -0
  67. package/src/cli/dev.ts +106 -41
  68. package/src/config.ts +6 -3
  69. package/src/db.ts +1 -0
  70. package/src/env.ts +40 -21
  71. package/src/error-page-render.ts +21 -0
  72. package/src/execution-context.ts +13 -3
  73. package/src/generation-manager.ts +144 -143
  74. package/src/generation.ts +150 -306
  75. package/src/import-graph.ts +140 -0
  76. package/src/lopata-config.ts +3 -3
  77. package/src/plugin.ts +7 -0
  78. package/src/rpc-validate.ts +29 -0
  79. package/src/setup-globals.ts +6 -17
  80. package/src/testing/durable-object.ts +5 -3
  81. package/src/testing/index.ts +8 -4
  82. package/src/tracing/context.ts +18 -0
  83. package/src/tracing/span.ts +83 -57
  84. package/src/tracing/store.ts +41 -3
  85. package/src/virtual-modules.ts +2 -0
  86. package/src/vite-plugin/dev-server-plugin.ts +4 -0
  87. package/src/vite-plugin/index.ts +8 -1
  88. package/src/worker-registry.ts +15 -2
  89. package/src/worker-thread/do-protocol.ts +237 -0
  90. package/src/worker-thread/entry.ts +453 -0
  91. package/src/worker-thread/execution-context.ts +53 -0
  92. package/src/worker-thread/executor.ts +595 -0
  93. package/src/worker-thread/protocol.ts +552 -0
  94. package/src/worker-thread/remote-trace-store.ts +90 -0
  95. package/src/worker-thread/rpc-client.ts +5 -0
  96. package/src/worker-thread/rpc-shared.ts +503 -0
  97. package/src/worker-thread/serialize.ts +37 -0
  98. package/src/worker-thread/stream-shared.ts +414 -0
  99. package/src/worker-thread/thread-env.ts +350 -0
  100. package/src/worker-thread/wire-handlers.ts +80 -0
  101. package/src/worker-thread/ws-bridge-shared.ts +482 -0
  102. package/dist/types/bindings/do-websocket-bridge.d.ts +0 -60
  103. package/dist/types/module-cache.d.ts +0 -23
  104. package/src/bindings/do-websocket-bridge.ts +0 -79
  105. package/src/module-cache.ts +0 -58
  106. package/src/tracing/global.d.ts +0 -50
@@ -0,0 +1,553 @@
1
+ /**
2
+ * Message protocol between main thread and worker-thread runtime.
3
+ *
4
+ * Main thread owns Bun.serve, file watcher, GenerationManager, dashboard.
5
+ * Worker thread owns the user module graph + per-thread env. Reload =
6
+ * terminate + respawn.
7
+ */
8
+ import type { WranglerConfig } from '../config';
9
+ import type { TraceStore } from '../tracing/store';
10
+ import type { SpanData, SpanEventData } from '../tracing/types';
11
+ /** Parent span context handed to the worker so its spans nest under main's server span. */
12
+ export interface ParentSpanContext {
13
+ traceId: string;
14
+ spanId: string;
15
+ }
16
+ export type TraceErrorPayload = Parameters<TraceStore['insertError']>[0];
17
+ export interface SerializedRequest {
18
+ url: string;
19
+ method: string;
20
+ headers: [string, string][];
21
+ body: ArrayBuffer | null;
22
+ /**
23
+ * When set, the body is streamed (not buffered): `body` is `null` and the
24
+ * sender pumps chunk messages keyed by this id. The channel decides which
25
+ * message family (`req-stream-*` for top-level main→worker fetch,
26
+ * `rpc-req-stream-*` for cross-thread binding fetch, `do-req-stream-*` for
27
+ * main→DO-worker fetch). Receiver reconstructs a `ReadableStream` and uses
28
+ * it as the rebuilt Request's body.
29
+ */
30
+ streamId?: number;
31
+ }
32
+ export interface SerializedResponse {
33
+ status: number;
34
+ statusText: string;
35
+ headers: [string, string][];
36
+ body: ArrayBuffer | null;
37
+ /** When set, the response carries a WebSocket upgrade — main rebuilds a
38
+ * `CFWebSocket` whose peer bridges send/close to this id on the worker. */
39
+ webSocketId?: string;
40
+ /**
41
+ * When set, the body is streamed (not buffered): `body` is `null` and the
42
+ * worker pumps `stream-chunk` / `stream-end` / `stream-error` for this id.
43
+ * Main rebuilds a `ReadableStream` so SSE / chunked / otherwise-unbounded
44
+ * responses reach the client incrementally instead of hanging on a never-
45
+ * resolving `arrayBuffer()`.
46
+ */
47
+ streamId?: number;
48
+ }
49
+ export interface SerializedError {
50
+ message: string;
51
+ stack?: string;
52
+ name?: string;
53
+ /** Recursively serialized `error.cause` chain (depth-capped). */
54
+ cause?: SerializedError;
55
+ /** Enumerable own-properties (err.code, err.status, err.data, …) that user
56
+ * or library error handling branches on. Only structured-cloneable values
57
+ * are kept (the whole SerializedError must survive postMessage). */
58
+ props?: Record<string, unknown>;
59
+ }
60
+ /**
61
+ * Serialize a thrown value for postMessage. MUST be total — it runs inside every
62
+ * worker-side catch block, so a secondary throw here (a non-stringifiable value,
63
+ * a throwing getter) would escalate a handled error into `worker.onerror` and
64
+ * tear down the whole generation. Every value read is guarded.
65
+ *
66
+ * Non-Error thrown values (`throw { status: 404 }`, `throw 'boom'`) keep their
67
+ * cloneable own-enumerable properties so `catch (e) { e.status }` survives the
68
+ * hop — class identity is lost (it always was, even in-process the wire is
69
+ * structured-clone), but the payload is preserved.
70
+ */
71
+ export declare function serializeError(e: unknown, depth?: number): SerializedError;
72
+ export declare function deserializeError(err: SerializedError): Error;
73
+ export interface WorkerInitConfig {
74
+ modulePath: string;
75
+ /** Wrangler config — already parsed, with `env.<name>` overrides applied. */
76
+ config: WranglerConfig;
77
+ baseDir: string;
78
+ /**
79
+ * Main's resolved `.lopata` data dir (`getDataDir()`). The worker thread MUST
80
+ * open the same SQLite file / r2 / d1 dirs main and the DO workers use —
81
+ * `baseDir` is per-worker (`dirname(workerDef.config)` in multi-worker mode)
82
+ * and would otherwise split state into a second db. `baseDir` is kept only for
83
+ * `.dev.vars`/`.env`/assets resolution, which IS per-worker.
84
+ */
85
+ dataDir: string;
86
+ /** Worker name from `lopata.config.ts` (or single-worker wrangler config). Used
87
+ * for span attribution + error attribution; mirrors `Generation.workerName`. */
88
+ workerName?: string;
89
+ /** Browser Rendering local dev config (Chrome wsEndpoint or executable path). */
90
+ browserConfig?: {
91
+ wsEndpoint?: string;
92
+ executablePath?: string;
93
+ headless?: boolean;
94
+ };
95
+ }
96
+ /** Names of the worker handlers we know how to invoke via RPC. */
97
+ export type WorkerHandlerName = 'fetch' | 'scheduled' | 'email' | 'queue';
98
+ /**
99
+ * Workflow control operation, routed to the *live* worker-side
100
+ * `SqliteWorkflowBinding` (which owns the real abort controllers / event
101
+ * waiters / sleep resolvers — main's binding is hollow in thread mode).
102
+ * Initiated by the dashboard AND by DO workers, whose `this.env.WF` proxy
103
+ * models create/get/instance methods as these ops. `binding` is the wrangler
104
+ * binding name; `instanceId` targets a specific instance for everything except
105
+ * `create`.
106
+ */
107
+ export type WorkflowControlOp = {
108
+ kind: 'create';
109
+ params: unknown;
110
+ id?: string;
111
+ } | {
112
+ kind: 'resumeInterrupted';
113
+ } | {
114
+ kind: 'terminate';
115
+ instanceId: string;
116
+ } | {
117
+ kind: 'pause';
118
+ instanceId: string;
119
+ } | {
120
+ kind: 'resume';
121
+ instanceId: string;
122
+ } | {
123
+ kind: 'restart';
124
+ instanceId: string;
125
+ fromStep?: string;
126
+ } | {
127
+ kind: 'skipSleep';
128
+ instanceId: string;
129
+ } | {
130
+ kind: 'sendEvent';
131
+ instanceId: string;
132
+ eventType: string;
133
+ payload?: unknown;
134
+ } | {
135
+ kind: 'isSleeping';
136
+ instanceId: string;
137
+ } | {
138
+ kind: 'waitingEventTypes';
139
+ instanceId: string;
140
+ } | {
141
+ kind: 'status';
142
+ instanceId: string;
143
+ };
144
+ /** `WorkflowInstance.status()` payload (see `SqliteWorkflowInstance.status`). */
145
+ export interface WorkflowInstanceStatus {
146
+ status: string;
147
+ output?: unknown;
148
+ error?: {
149
+ name: string;
150
+ message: string;
151
+ };
152
+ }
153
+ /** Result payload of a {@link WorkflowControlOp}. `create` reports the new id,
154
+ * the introspection reads report their value; mutating ops report nothing. */
155
+ export type WorkflowControlResult = {
156
+ kind: 'create';
157
+ id: string;
158
+ } | {
159
+ kind: 'ok';
160
+ } | {
161
+ kind: 'isSleeping';
162
+ value: boolean;
163
+ } | {
164
+ kind: 'waitingEventTypes';
165
+ value: string[];
166
+ } | {
167
+ kind: 'status';
168
+ value: WorkflowInstanceStatus;
169
+ };
170
+ export interface BindingTarget {
171
+ binding: string;
172
+ /**
173
+ * DO instance target. When set, the resolving side routes through
174
+ * `env[binding].get(instanceId)` before invoking `method` / `fetch`, so
175
+ * cross-DO and self-DO access via env-RPC lands on the right instance. Used
176
+ * by both the DO-stub proxies and the executors' `_resolveBinding`.
177
+ */
178
+ instanceId?: string;
179
+ /**
180
+ * @internal For DO instance targets created via `idFromName(name)`: the
181
+ * original name string. Main reconstructs `DurableObjectIdImpl(instanceId,
182
+ * instanceName)` before calling `binding.get()` so `ctx.id.name` is
183
+ * preserved across the thread boundary (matches the in-process path).
184
+ */
185
+ instanceName?: string;
186
+ }
187
+ /**
188
+ * Unified cross-thread RPC frame. Used in both directions:
189
+ * - user-worker → main (`WorkerThreadExecutor`): stateful binding access from the user's worker
190
+ * - DO-worker → main (`WorkerExecutor`): same, from a DO instance worker
191
+ *
192
+ * `parent` propagates trace context so spans created on the receiving side
193
+ * (including spans inside *further* nested cross-thread hops) link back to the
194
+ * caller's active span. Without it nested service-binding calls float at root.
195
+ */
196
+ export interface RpcCallRequest {
197
+ type: 'rpc-call';
198
+ id: number;
199
+ target: BindingTarget;
200
+ method: string;
201
+ args: unknown[];
202
+ parent?: ParentSpanContext;
203
+ }
204
+ export interface RpcFetchRequest {
205
+ type: 'rpc-fetch';
206
+ id: number;
207
+ target: BindingTarget;
208
+ request: SerializedRequest;
209
+ parent?: ParentSpanContext;
210
+ }
211
+ /**
212
+ * Property read on a cross-thread binding (`await env.SVC.someProp`). The
213
+ * worker-side binding proxy is callable (for method calls) AND thenable (for
214
+ * property reads); awaiting it posts this and main resolves the property on the
215
+ * main-side binding (which itself implements the thenable property-get). The
216
+ * reply reuses {@link RpcCallReply} / {@link RpcCallErrorReply}.
217
+ */
218
+ export interface RpcGetRequest {
219
+ type: 'rpc-call-get';
220
+ id: number;
221
+ target: BindingTarget;
222
+ property: string;
223
+ parent?: ParentSpanContext;
224
+ }
225
+ export interface RpcCallReply {
226
+ type: 'rpc-call-result';
227
+ id: number;
228
+ value: unknown;
229
+ }
230
+ export interface RpcCallErrorReply {
231
+ type: 'rpc-call-error';
232
+ id: number;
233
+ error: SerializedError;
234
+ }
235
+ export interface RpcFetchReply {
236
+ type: 'rpc-fetch-result';
237
+ id: number;
238
+ response: SerializedResponse;
239
+ }
240
+ export interface RpcFetchErrorReply {
241
+ type: 'rpc-fetch-error';
242
+ id: number;
243
+ error: SerializedError;
244
+ }
245
+ /**
246
+ * Reverse-direction streaming for {@link RpcFetchReply}. When main's
247
+ * `dispatchRpcFetch` resolves a response with a body, it ships headers + a
248
+ * `streamId` immediately and pumps the body via these messages so SSE / chunked
249
+ * responses returned from a service binding reach the caller incrementally
250
+ * instead of waiting for the source to finish.
251
+ *
252
+ * Direction: main → worker (mirrors `stream-chunk` / `stream-end` /
253
+ * `stream-error` which carry the worker → main top-level fetch path).
254
+ *
255
+ * Id space: independent counter inside `dispatchRpcFetch`; carried in
256
+ * {@link SerializedResponse}.streamId on the matching `rpc-fetch-result`.
257
+ */
258
+ export interface RpcStreamChunk {
259
+ type: 'rpc-stream-chunk';
260
+ streamId: number;
261
+ chunk: Uint8Array;
262
+ }
263
+ export interface RpcStreamEnd {
264
+ type: 'rpc-stream-end';
265
+ streamId: number;
266
+ }
267
+ export interface RpcStreamError {
268
+ type: 'rpc-stream-error';
269
+ streamId: number;
270
+ error: SerializedError;
271
+ }
272
+ /** worker → main: the caller cancelled the reconstructed response body
273
+ * (consumer dropped, AbortController, etc). Main stops the source reader. */
274
+ export interface RpcStreamCancel {
275
+ type: 'rpc-stream-cancel';
276
+ streamId: number;
277
+ }
278
+ /** worker → main: the caller consumed an rpc-fetch response-body chunk and
279
+ * grants the sender one more credit (see `STREAM_BACKPRESSURE_WINDOW`). */
280
+ export interface RpcStreamAck {
281
+ type: 'rpc-stream-ack';
282
+ streamId: number;
283
+ }
284
+ /**
285
+ * Forward-direction streaming for {@link RpcFetchRequest}'s body. The sender
286
+ * (worker-side `RpcClient.callFetch`) ships the request shell + a
287
+ * `requestStreamId` immediately and pumps the body via these messages so
288
+ * uploads / streaming proxies reach the binding's `fetch()` incrementally
289
+ * instead of waiting for the full body to buffer.
290
+ *
291
+ * Direction: sender → receiver of the unified RPC channel. For the
292
+ * user-worker channel that's worker → main; for the DO-worker channel that's
293
+ * DO worker → main. Both `WorkerThreadExecutor` and `WorkerExecutor` host an
294
+ * inbound request-stream receiver and route these messages into it.
295
+ *
296
+ * Id space: independent counter inside the sending `RpcClient`; carried in
297
+ * {@link SerializedRequest}.streamId on the matching `rpc-fetch`.
298
+ */
299
+ export interface RpcReqStreamChunk {
300
+ type: 'rpc-req-stream-chunk';
301
+ streamId: number;
302
+ chunk: Uint8Array;
303
+ }
304
+ export interface RpcReqStreamEnd {
305
+ type: 'rpc-req-stream-end';
306
+ streamId: number;
307
+ }
308
+ export interface RpcReqStreamError {
309
+ type: 'rpc-req-stream-error';
310
+ streamId: number;
311
+ error: SerializedError;
312
+ }
313
+ /** receiver → sender: the binding consumer cancelled the reconstructed
314
+ * request body. Sender stops the source reader. */
315
+ export interface RpcReqStreamCancel {
316
+ type: 'rpc-req-stream-cancel';
317
+ streamId: number;
318
+ }
319
+ /** receiver → sender: the binding consumer pulled a request-body chunk and
320
+ * grants the sender one more credit (cross-thread backpressure, mirrors
321
+ * {@link RpcStreamAck} on the response side). */
322
+ export interface RpcReqStreamAck {
323
+ type: 'rpc-req-stream-ack';
324
+ streamId: number;
325
+ }
326
+ export type RpcReply = RpcCallReply | RpcCallErrorReply | RpcFetchReply | RpcFetchErrorReply | RpcStreamChunk | RpcStreamEnd | RpcStreamError | RpcReqStreamCancel | RpcReqStreamAck;
327
+ /** Main → worker */
328
+ export type WorkerCommand = {
329
+ type: 'init';
330
+ config: WorkerInitConfig;
331
+ } | {
332
+ type: 'fetch';
333
+ id: number;
334
+ request: SerializedRequest;
335
+ parent?: ParentSpanContext;
336
+ props?: Record<string, unknown>;
337
+ } | {
338
+ type: 'scheduled';
339
+ id: number;
340
+ cronExpr: string;
341
+ scheduledTime: number;
342
+ parent?: ParentSpanContext;
343
+ } | {
344
+ type: 'email';
345
+ id: number;
346
+ messageId: string;
347
+ from: string;
348
+ to: string;
349
+ raw: Uint8Array;
350
+ parent?: ParentSpanContext;
351
+ } | RpcCallReply | RpcCallErrorReply | RpcFetchReply | RpcFetchErrorReply | RpcStreamChunk | RpcStreamEnd | RpcStreamError | RpcReqStreamCancel | RpcReqStreamAck | {
352
+ type: 'entrypoint-rpc';
353
+ id: number;
354
+ entrypoint: string | undefined;
355
+ method: string;
356
+ args: unknown[];
357
+ props?: Record<string, unknown>;
358
+ parent?: ParentSpanContext;
359
+ } | {
360
+ type: 'entrypoint-rpc-get';
361
+ id: number;
362
+ entrypoint: string | undefined;
363
+ property: string;
364
+ props?: Record<string, unknown>;
365
+ parent?: ParentSpanContext;
366
+ } | {
367
+ type: 'workflow-control';
368
+ id: number;
369
+ binding: string;
370
+ op: WorkflowControlOp;
371
+ parent?: ParentSpanContext;
372
+ } | {
373
+ type: 'ws-client-message';
374
+ wsId: string;
375
+ data: string | ArrayBuffer;
376
+ } | {
377
+ type: 'ws-client-close';
378
+ wsId: string;
379
+ code: number;
380
+ reason: string;
381
+ wasClean: boolean;
382
+ } | {
383
+ type: 'env-ws-incoming';
384
+ wsId: string;
385
+ data: string | ArrayBuffer;
386
+ } | {
387
+ type: 'env-ws-close-in';
388
+ wsId: string;
389
+ code: number;
390
+ reason: string;
391
+ wasClean: boolean;
392
+ } | {
393
+ type: 'stream-cancel';
394
+ id: number;
395
+ } | {
396
+ type: 'stream-ack';
397
+ id: number;
398
+ } | {
399
+ type: 'req-stream-chunk';
400
+ streamId: number;
401
+ chunk: Uint8Array;
402
+ } | {
403
+ type: 'req-stream-end';
404
+ streamId: number;
405
+ } | {
406
+ type: 'req-stream-error';
407
+ streamId: number;
408
+ error: SerializedError;
409
+ } | {
410
+ type: 'stop-queue-consumers';
411
+ } | {
412
+ type: 'fetch-abort';
413
+ id: number;
414
+ };
415
+ /** Worker → main */
416
+ export type WorkerMessage = {
417
+ type: 'need-init';
418
+ }
419
+ /**
420
+ * Sent after the user module imports successfully.
421
+ *
422
+ * `doAlarmHandlers` maps each DO/container class name declared in the
423
+ * wrangler config to whether its prototype defines an `alarm()` method. Main
424
+ * uses it to forward `_setAlarmHandlerHint` to each namespace — without this,
425
+ * thread-mode `hasAlarmHandler()` would always return `false` (the main-side
426
+ * namespace doesn't load the user module). Missing exports report `false`.
427
+ */
428
+ | {
429
+ type: 'ready';
430
+ doAlarmHandlers: Record<string, boolean>;
431
+ } | {
432
+ type: 'init-error';
433
+ error: SerializedError;
434
+ } | {
435
+ type: 'fetch-result';
436
+ id: number;
437
+ response: SerializedResponse;
438
+ } | {
439
+ type: 'fetch-error';
440
+ id: number;
441
+ error: SerializedError;
442
+ } | {
443
+ type: 'scheduled-result';
444
+ id: number;
445
+ } | {
446
+ type: 'scheduled-error';
447
+ id: number;
448
+ error: SerializedError;
449
+ noHandler?: boolean;
450
+ } | {
451
+ type: 'email-result';
452
+ id: number;
453
+ } | {
454
+ type: 'email-error';
455
+ id: number;
456
+ error: SerializedError;
457
+ noHandler?: boolean;
458
+ } | {
459
+ type: 'entrypoint-rpc-result';
460
+ id: number;
461
+ value: unknown;
462
+ } | {
463
+ type: 'entrypoint-rpc-error';
464
+ id: number;
465
+ error: SerializedError;
466
+ } | {
467
+ type: 'entrypoint-rpc-get-result';
468
+ id: number;
469
+ kind: 'value';
470
+ value: unknown;
471
+ } | {
472
+ type: 'entrypoint-rpc-get-result';
473
+ id: number;
474
+ kind: 'function';
475
+ } | {
476
+ type: 'entrypoint-rpc-get-error';
477
+ id: number;
478
+ error: SerializedError;
479
+ } | {
480
+ type: 'workflow-control-result';
481
+ id: number;
482
+ result: WorkflowControlResult;
483
+ } | {
484
+ type: 'workflow-control-error';
485
+ id: number;
486
+ error: SerializedError;
487
+ } | RpcCallRequest | RpcGetRequest | RpcFetchRequest | RpcStreamCancel | RpcStreamAck | RpcReqStreamChunk | RpcReqStreamEnd | RpcReqStreamError | {
488
+ type: 'wait-until-add';
489
+ id: number;
490
+ } | {
491
+ type: 'wait-until-settle';
492
+ id: number;
493
+ } | {
494
+ type: 'trace-span-insert';
495
+ span: SpanData;
496
+ } | {
497
+ type: 'trace-span-end';
498
+ spanId: string;
499
+ endTime: number;
500
+ status: 'ok' | 'error';
501
+ statusMessage: string | null;
502
+ } | {
503
+ type: 'trace-span-status';
504
+ spanId: string;
505
+ status: 'ok' | 'error';
506
+ statusMessage: string | null;
507
+ } | {
508
+ type: 'trace-span-attrs';
509
+ spanId: string;
510
+ attrs: Record<string, unknown>;
511
+ } | {
512
+ type: 'trace-span-event';
513
+ event: Omit<SpanEventData, 'id'>;
514
+ } | {
515
+ type: 'trace-error';
516
+ error: TraceErrorPayload;
517
+ } | {
518
+ type: 'ws-worker-send';
519
+ wsId: string;
520
+ data: string | ArrayBuffer;
521
+ } | {
522
+ type: 'ws-worker-close';
523
+ wsId: string;
524
+ code: number;
525
+ reason: string;
526
+ } | {
527
+ type: 'env-ws-outgoing';
528
+ wsId: string;
529
+ data: string | ArrayBuffer;
530
+ } | {
531
+ type: 'env-ws-close-out';
532
+ wsId: string;
533
+ code: number;
534
+ reason: string;
535
+ wasClean: boolean;
536
+ } | {
537
+ type: 'stream-chunk';
538
+ id: number;
539
+ chunk: Uint8Array;
540
+ } | {
541
+ type: 'stream-end';
542
+ id: number;
543
+ } | {
544
+ type: 'stream-error';
545
+ id: number;
546
+ error: SerializedError;
547
+ } | {
548
+ type: 'req-stream-cancel';
549
+ streamId: number;
550
+ } | {
551
+ type: 'req-stream-ack';
552
+ streamId: number;
553
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Worker-side stand-in for `TraceStore`. Each operation is forwarded to
3
+ * main via postMessage so the single persistent store + dashboard
4
+ * subscribers stay the source of truth. We keep a tiny local mirror of
5
+ * span statuses because `startSpan` reads `getSpanStatus(spanId)`
6
+ * synchronously and the bridge is async-only.
7
+ */
8
+ import type { TraceStore } from '../tracing/store';
9
+ import type { SpanData, SpanEventData } from '../tracing/types';
10
+ import type { TraceErrorPayload, WorkerMessage } from './protocol';
11
+ /** Methods of `TraceStore` actually called from worker-side code. Adding a new
12
+ * call site against the store from `span.ts` / `instrument.ts` / `setup-globals.ts`
13
+ * must extend this list (and `RemoteTraceStore` below). */
14
+ type RemotedMethods = 'insertSpan' | 'endSpan' | 'setSpanStatus' | 'getSpanStatus' | 'updateAttributes' | 'addEvent' | 'insertError';
15
+ export declare class RemoteTraceStore implements Pick<TraceStore, RemotedMethods> {
16
+ private _statuses;
17
+ private _post;
18
+ constructor(post: (msg: WorkerMessage) => void);
19
+ insertSpan(span: SpanData): void;
20
+ endSpan(spanId: string, endTime: number, status: 'ok' | 'error', statusMessage?: string): void;
21
+ setSpanStatus(spanId: string, status: 'ok' | 'error', statusMessage: string | null): void;
22
+ getSpanStatus(spanId: string): string | null;
23
+ updateAttributes(spanId: string, attrs: Record<string, unknown>): void;
24
+ addEvent(event: Omit<SpanEventData, 'id'>): void;
25
+ insertError(opts: TraceErrorPayload): void;
26
+ }
27
+ export {};
@@ -0,0 +1,4 @@
1
+ /** Re-export of the shared cross-thread RPC client. Kept as a stable import
2
+ * path for callers in `./thread-env.ts`; new code should import directly
3
+ * from `./rpc-shared`. */
4
+ export { RpcClient } from './rpc-shared';