lopata 0.18.3 → 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.
- package/dist/types/api/dispatch.d.ts +2 -2
- package/dist/types/api/handlers/workflows.d.ts +2 -2
- package/dist/types/bindings/container-cleanup.d.ts +43 -0
- package/dist/types/bindings/container-docker.d.ts +24 -0
- package/dist/types/bindings/container.d.ts +4 -2
- package/dist/types/bindings/do-executor-worker.d.ts +73 -89
- package/dist/types/bindings/do-executor.d.ts +22 -1
- package/dist/types/bindings/do-worker-env.d.ts +16 -7
- package/dist/types/bindings/durable-object.d.ts +66 -4
- package/dist/types/bindings/queue.d.ts +4 -1
- package/dist/types/bindings/rpc-stub.d.ts +23 -1
- package/dist/types/bindings/scheduled.d.ts +13 -3
- package/dist/types/bindings/service-binding.d.ts +13 -4
- package/dist/types/bindings/static-assets.d.ts +1 -1
- package/dist/types/bindings/websocket-pair.d.ts +12 -3
- package/dist/types/bindings/workflow.d.ts +29 -0
- package/dist/types/config.d.ts +2 -0
- package/dist/types/env.d.ts +6 -0
- package/dist/types/error-page-render.d.ts +6 -0
- package/dist/types/execution-context.d.ts +8 -0
- package/dist/types/generation-manager.d.ts +21 -2
- package/dist/types/generation.d.ts +16 -21
- package/dist/types/import-graph.d.ts +28 -0
- package/dist/types/lopata-config.d.ts +3 -3
- package/dist/types/plugin.d.ts +4 -1
- package/dist/types/rpc-validate.d.ts +9 -0
- package/dist/types/setup-globals.d.ts +5 -1
- package/dist/types/tracing/context.d.ts +21 -0
- package/dist/types/tracing/span.d.ts +21 -3
- package/dist/types/tracing/store.d.ts +17 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/vite-plugin/index.d.ts +8 -1
- package/dist/types/worker-registry.d.ts +11 -4
- package/dist/types/worker-thread/do-protocol.d.ts +256 -0
- package/dist/types/worker-thread/entry.d.ts +2 -0
- package/dist/types/worker-thread/execution-context.d.ts +22 -0
- package/dist/types/worker-thread/executor.d.ts +123 -0
- package/dist/types/worker-thread/protocol.d.ts +553 -0
- package/dist/types/worker-thread/remote-trace-store.d.ts +27 -0
- package/dist/types/worker-thread/rpc-client.d.ts +4 -0
- package/dist/types/worker-thread/rpc-shared.d.ts +138 -0
- package/dist/types/worker-thread/serialize.d.ts +12 -0
- package/dist/types/worker-thread/stream-shared.d.ts +147 -0
- package/dist/types/worker-thread/thread-env.d.ts +42 -0
- package/dist/types/worker-thread/wire-handlers.d.ts +16 -0
- package/dist/types/worker-thread/ws-bridge-shared.d.ts +163 -0
- package/package.json +1 -1
- package/src/api/handlers/containers.ts +2 -1
- package/src/api/handlers/workflows.ts +39 -34
- package/src/bindings/container-cleanup.ts +125 -0
- package/src/bindings/container-docker.ts +49 -34
- package/src/bindings/container.ts +24 -9
- package/src/bindings/do-executor-inprocess.ts +9 -5
- package/src/bindings/do-executor-worker.ts +386 -158
- package/src/bindings/do-executor.ts +23 -1
- package/src/bindings/do-worker-entry.ts +242 -60
- package/src/bindings/do-worker-env.ts +296 -11
- package/src/bindings/durable-object.ts +231 -27
- package/src/bindings/email.ts +6 -0
- package/src/bindings/queue.ts +11 -1
- package/src/bindings/rpc-stub.ts +79 -10
- package/src/bindings/scheduled.ts +37 -30
- package/src/bindings/service-binding.ts +96 -35
- package/src/bindings/static-assets.ts +3 -2
- package/src/bindings/websocket-pair.ts +19 -3
- package/src/bindings/workflow.ts +91 -0
- package/src/cli/dev.ts +106 -41
- package/src/config.ts +6 -3
- package/src/db.ts +1 -0
- package/src/env.ts +40 -21
- package/src/error-page-render.ts +21 -0
- package/src/execution-context.ts +13 -3
- package/src/generation-manager.ts +144 -143
- package/src/generation.ts +150 -306
- package/src/import-graph.ts +140 -0
- package/src/lopata-config.ts +3 -3
- package/src/plugin.ts +7 -0
- package/src/rpc-validate.ts +29 -0
- package/src/setup-globals.ts +6 -17
- package/src/testing/durable-object.ts +5 -3
- package/src/testing/index.ts +8 -4
- package/src/tracing/context.ts +28 -0
- package/src/tracing/span.ts +88 -56
- package/src/tracing/store.ts +41 -3
- package/src/virtual-modules.ts +2 -0
- package/src/vite-plugin/dev-server-plugin.ts +4 -0
- package/src/vite-plugin/index.ts +8 -1
- package/src/worker-registry.ts +15 -2
- package/src/worker-thread/do-protocol.ts +237 -0
- package/src/worker-thread/entry.ts +453 -0
- package/src/worker-thread/execution-context.ts +53 -0
- package/src/worker-thread/executor.ts +595 -0
- package/src/worker-thread/protocol.ts +552 -0
- package/src/worker-thread/remote-trace-store.ts +90 -0
- package/src/worker-thread/rpc-client.ts +5 -0
- package/src/worker-thread/rpc-shared.ts +503 -0
- package/src/worker-thread/serialize.ts +37 -0
- package/src/worker-thread/stream-shared.ts +414 -0
- package/src/worker-thread/thread-env.ts +350 -0
- package/src/worker-thread/wire-handlers.ts +80 -0
- package/src/worker-thread/ws-bridge-shared.ts +482 -0
- package/dist/types/bindings/do-websocket-bridge.d.ts +0 -60
- package/dist/types/module-cache.d.ts +0 -23
- package/src/bindings/do-websocket-bridge.ts +0 -79
- package/src/module-cache.ts +0 -58
- 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 {};
|