rivetkit 2.3.0-rc.6 → 2.3.0-rc.7
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/browser/client.d.ts +37 -8
- package/dist/browser/client.js +64 -34
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +4 -3
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/actor/errors.cjs +2 -2
- package/dist/tsup/actor/errors.js +1 -1
- package/dist/tsup/agent-os/index.cjs +7 -5
- package/dist/tsup/agent-os/index.cjs.map +1 -1
- package/dist/tsup/agent-os/index.d.cts +26 -5
- package/dist/tsup/agent-os/index.d.ts +26 -5
- package/dist/tsup/agent-os/index.js +7 -5
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-2G64KSZQ.cjs → chunk-2H4ISA4Y.cjs} +10 -10
- package/dist/tsup/chunk-2H4ISA4Y.cjs.map +1 -0
- package/dist/tsup/{chunk-ZI5QJMKO.js → chunk-4DJMFOSU.js} +2 -2
- package/dist/tsup/{chunk-RTC2AZGB.js → chunk-4LTY5TOO.js} +132 -4
- package/dist/tsup/chunk-4LTY5TOO.js.map +1 -0
- package/dist/tsup/{chunk-DEO7MMWQ.js → chunk-52TPEKEC.js} +2 -2
- package/dist/tsup/{chunk-HTR4YLNT.cjs → chunk-55E7IR6D.cjs} +4 -4
- package/dist/tsup/{chunk-HTR4YLNT.cjs.map → chunk-55E7IR6D.cjs.map} +1 -1
- package/dist/tsup/{chunk-QAZLM4WT.cjs → chunk-63WNTDRC.cjs} +3 -3
- package/dist/tsup/{chunk-QAZLM4WT.cjs.map → chunk-63WNTDRC.cjs.map} +1 -1
- package/dist/tsup/{chunk-EMO6E3PJ.js → chunk-CMV6N5OX.js} +3 -3
- package/dist/tsup/{chunk-T6YVRM4K.js → chunk-D5G75T7J.js} +3 -1
- package/dist/tsup/chunk-D5G75T7J.js.map +1 -0
- package/dist/tsup/{chunk-LIXXFXVR.cjs → chunk-FEOG44WH.cjs} +137 -9
- package/dist/tsup/chunk-FEOG44WH.cjs.map +1 -0
- package/dist/tsup/{chunk-M5C7YNI5.cjs → chunk-G5HUSWP4.cjs} +8 -8
- package/dist/tsup/{chunk-M5C7YNI5.cjs.map → chunk-G5HUSWP4.cjs.map} +1 -1
- package/dist/tsup/{chunk-6S25NVAP.js → chunk-HERL2VQ2.js} +7 -5
- package/dist/tsup/chunk-HERL2VQ2.js.map +1 -0
- package/dist/tsup/{chunk-JALSAX7Z.cjs → chunk-SJLPZEA3.cjs} +3 -3
- package/dist/tsup/{chunk-JALSAX7Z.cjs.map → chunk-SJLPZEA3.cjs.map} +1 -1
- package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-SRNOPUC6.cjs} +4 -2
- package/dist/tsup/chunk-SRNOPUC6.cjs.map +1 -0
- package/dist/tsup/{chunk-KIWH5H3K.js → chunk-TMLOKTRB.js} +3 -3
- package/dist/tsup/chunk-TMLOKTRB.js.map +1 -0
- package/dist/tsup/{chunk-CAF6JDJE.js → chunk-VFIY6GWO.js} +4 -4
- package/dist/tsup/chunk-VFIY6GWO.js.map +1 -0
- package/dist/tsup/{chunk-FLODVLYW.js → chunk-VJ4Y4WBT.js} +10 -34
- package/dist/tsup/chunk-VJ4Y4WBT.js.map +1 -0
- package/dist/tsup/{chunk-K5BA2LEO.cjs → chunk-X6HIFXNK.cjs} +14 -12
- package/dist/tsup/chunk-X6HIFXNK.cjs.map +1 -0
- package/dist/tsup/{chunk-ENK7C66G.cjs → chunk-ZGPX6KAH.cjs} +169 -193
- package/dist/tsup/chunk-ZGPX6KAH.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +7 -7
- package/dist/tsup/client/mod.d.cts +2 -2
- package/dist/tsup/client/mod.d.ts +2 -2
- package/dist/tsup/client/mod.js +6 -6
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{config-0Ta55UV0.d.ts → config-Ak1lv4gF.d.ts} +27 -6
- package/dist/tsup/{config-Ca8dN4cS.d.cts → config-DU_xj4qZ.d.cts} +27 -6
- package/dist/tsup/{context-B_IWbWne.d.ts → context-DAAp4Lpg.d.ts} +1 -1
- package/dist/tsup/{context-CUrQ9MHc.d.cts → context-Dt_L55q8.d.cts} +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +470 -316
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +3 -3
- package/dist/tsup/mod.d.ts +3 -3
- package/dist/tsup/mod.js +391 -237
- package/dist/tsup/mod.js.map +1 -1
- package/dist/tsup/process-metrics-NW754INA.js +118 -0
- package/dist/tsup/process-metrics-NW754INA.js.map +1 -0
- package/dist/tsup/process-metrics-TYAGKCEJ.cjs +118 -0
- package/dist/tsup/process-metrics-TYAGKCEJ.cjs.map +1 -0
- package/dist/tsup/test/mod.cjs +10 -10
- package/dist/tsup/test/mod.d.cts +1 -1
- package/dist/tsup/test/mod.d.ts +1 -1
- package/dist/tsup/test/mod.js +6 -6
- package/dist/tsup/utils.cjs +3 -3
- package/dist/tsup/utils.js +2 -2
- package/dist/tsup/workflow/mod.cjs +41 -16
- package/dist/tsup/workflow/mod.cjs.map +1 -1
- package/dist/tsup/workflow/mod.d.cts +3 -3
- package/dist/tsup/workflow/mod.d.ts +3 -3
- package/dist/tsup/workflow/mod.js +35 -10
- package/dist/tsup/workflow/mod.js.map +1 -1
- package/package.json +11 -10
- package/src/actor/config.ts +3 -0
- package/src/actor/errors.ts +2 -2
- package/src/agent-os/actor/session.ts +2 -2
- package/src/client/actor-conn.ts +6 -34
- package/src/client/actor-handle.ts +2 -1
- package/src/client/queue.ts +2 -1
- package/src/client/utils.ts +0 -1
- package/src/common/encoding.ts +243 -5
- package/src/common/inline-websocket-adapter.ts +12 -12
- package/src/common/log.ts +1 -0
- package/src/common/router.ts +2 -2
- package/src/common/utils.ts +0 -148
- package/src/drivers/engine/actor-driver.ts +11 -11
- package/src/engine-client/actor-websocket-client.ts +2 -1
- package/src/engine-client/mod.ts +3 -2
- package/src/registry/index.ts +46 -109
- package/src/registry/napi-runtime.ts +11 -34
- package/src/registry/native.ts +193 -104
- package/src/registry/process-metrics.ts +183 -0
- package/src/registry/runtime.ts +5 -12
- package/src/registry/wasm-runtime.ts +2 -13
- package/src/registry/write-through-proxy.ts +40 -0
- package/src/serde.ts +2 -2
- package/src/workflow/context.ts +32 -5
- package/src/workflow/inspector.ts +2 -1
- package/dist/tsup/chunk-2G64KSZQ.cjs.map +0 -1
- package/dist/tsup/chunk-6S25NVAP.js.map +0 -1
- package/dist/tsup/chunk-CAF6JDJE.js.map +0 -1
- package/dist/tsup/chunk-ENK7C66G.cjs.map +0 -1
- package/dist/tsup/chunk-FLODVLYW.js.map +0 -1
- package/dist/tsup/chunk-K5BA2LEO.cjs.map +0 -1
- package/dist/tsup/chunk-KIWH5H3K.js.map +0 -1
- package/dist/tsup/chunk-LIXXFXVR.cjs.map +0 -1
- package/dist/tsup/chunk-RTC2AZGB.js.map +0 -1
- package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
- package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
- /package/dist/tsup/{chunk-ZI5QJMKO.js.map → chunk-4DJMFOSU.js.map} +0 -0
- /package/dist/tsup/{chunk-DEO7MMWQ.js.map → chunk-52TPEKEC.js.map} +0 -0
- /package/dist/tsup/{chunk-EMO6E3PJ.js.map → chunk-CMV6N5OX.js.map} +0 -0
package/src/common/encoding.ts
CHANGED
|
@@ -13,6 +13,171 @@ const JSON_COMPAT_BIGINT = "$BigInt";
|
|
|
13
13
|
const JSON_COMPAT_ARRAY_BUFFER = "$ArrayBuffer";
|
|
14
14
|
const JSON_COMPAT_UINT8_ARRAY = "$Uint8Array";
|
|
15
15
|
const JSON_COMPAT_UNDEFINED = "$Undefined";
|
|
16
|
+
const JSON_COMPAT_SET = "$Set";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Types that cbor-x encodes natively without any compat transforms.
|
|
20
|
+
*/
|
|
21
|
+
export type CborSerializable =
|
|
22
|
+
| string
|
|
23
|
+
| number
|
|
24
|
+
| boolean
|
|
25
|
+
| null
|
|
26
|
+
| undefined
|
|
27
|
+
| bigint
|
|
28
|
+
| Date
|
|
29
|
+
| RegExp
|
|
30
|
+
| Error
|
|
31
|
+
| ArrayBuffer
|
|
32
|
+
| Uint8Array
|
|
33
|
+
| Uint8ClampedArray
|
|
34
|
+
| Uint16Array
|
|
35
|
+
| Uint32Array
|
|
36
|
+
| BigUint64Array
|
|
37
|
+
| Int8Array
|
|
38
|
+
| Int16Array
|
|
39
|
+
| Int32Array
|
|
40
|
+
| BigInt64Array
|
|
41
|
+
| Float32Array
|
|
42
|
+
| Float64Array
|
|
43
|
+
| CborSerializable[]
|
|
44
|
+
| Map<CborSerializable, CborSerializable>
|
|
45
|
+
| { [key: string]: CborSerializable };
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* User-facing serializable type. Extends CborSerializable with Set (encoded
|
|
49
|
+
* as a `$Set` tagged array by the JSON compat layer).
|
|
50
|
+
*/
|
|
51
|
+
export type JsonCompatValue =
|
|
52
|
+
| CborSerializable
|
|
53
|
+
| Set<JsonCompatValue>
|
|
54
|
+
| JsonCompatValue[]
|
|
55
|
+
| Map<JsonCompatValue, JsonCompatValue>
|
|
56
|
+
| { [key: string]: JsonCompatValue };
|
|
57
|
+
|
|
58
|
+
function isTypedArray(value: unknown): boolean {
|
|
59
|
+
return (
|
|
60
|
+
value instanceof Uint8ClampedArray ||
|
|
61
|
+
value instanceof Uint16Array ||
|
|
62
|
+
value instanceof Uint32Array ||
|
|
63
|
+
value instanceof BigUint64Array ||
|
|
64
|
+
value instanceof Int8Array ||
|
|
65
|
+
value instanceof Int16Array ||
|
|
66
|
+
value instanceof Int32Array ||
|
|
67
|
+
value instanceof BigInt64Array ||
|
|
68
|
+
value instanceof Float32Array ||
|
|
69
|
+
value instanceof Float64Array
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Recursively validates that a value is CBOR serializable. Throws TypeError
|
|
75
|
+
* with a descriptive message for non-serializable values.
|
|
76
|
+
*/
|
|
77
|
+
export function assertJsonCompatValue(
|
|
78
|
+
value: unknown,
|
|
79
|
+
path = "",
|
|
80
|
+
): asserts value is JsonCompatValue {
|
|
81
|
+
if (
|
|
82
|
+
value === null ||
|
|
83
|
+
value === undefined ||
|
|
84
|
+
typeof value === "string" ||
|
|
85
|
+
typeof value === "number" ||
|
|
86
|
+
typeof value === "boolean" ||
|
|
87
|
+
typeof value === "bigint"
|
|
88
|
+
) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (typeof value === "function") {
|
|
93
|
+
throw new TypeError(
|
|
94
|
+
`Value at ${path || "root"} is a function and is not CBOR serializable`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (typeof value === "symbol") {
|
|
99
|
+
throw new TypeError(
|
|
100
|
+
`Value at ${path || "root"} is a symbol and is not CBOR serializable`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (
|
|
105
|
+
value instanceof Date ||
|
|
106
|
+
value instanceof RegExp ||
|
|
107
|
+
value instanceof Error ||
|
|
108
|
+
value instanceof ArrayBuffer ||
|
|
109
|
+
value instanceof Uint8Array ||
|
|
110
|
+
isTypedArray(value)
|
|
111
|
+
) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (value instanceof WeakMap) {
|
|
116
|
+
throw new TypeError(
|
|
117
|
+
`Value at ${path || "root"} is a WeakMap and is not CBOR serializable`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (value instanceof WeakSet) {
|
|
122
|
+
throw new TypeError(
|
|
123
|
+
`Value at ${path || "root"} is a WeakSet and is not CBOR serializable`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (value instanceof WeakRef) {
|
|
128
|
+
throw new TypeError(
|
|
129
|
+
`Value at ${path || "root"} is a WeakRef and is not CBOR serializable`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (value instanceof Promise) {
|
|
134
|
+
throw new TypeError(
|
|
135
|
+
`Value at ${path || "root"} is a Promise and is not CBOR serializable`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (value instanceof Map) {
|
|
140
|
+
for (const [k, v] of value.entries()) {
|
|
141
|
+
assertJsonCompatValue(k, `${path || "root"}.key(${String(k)})`);
|
|
142
|
+
assertJsonCompatValue(v, `${path || "root"}.value(${String(k)})`);
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (value instanceof Set) {
|
|
148
|
+
let index = 0;
|
|
149
|
+
for (const item of value.values()) {
|
|
150
|
+
assertJsonCompatValue(item, `${path || "root"}.set[${index}]`);
|
|
151
|
+
index++;
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (Array.isArray(value)) {
|
|
157
|
+
for (let i = 0; i < value.length; i++) {
|
|
158
|
+
assertJsonCompatValue(value[i], `${path || "root"}[${i}]`);
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (isPlainObject(value)) {
|
|
164
|
+
for (const key in value) {
|
|
165
|
+
assertJsonCompatValue(
|
|
166
|
+
value[key as keyof typeof value],
|
|
167
|
+
path ? `${path}.${key}` : key,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const typeName =
|
|
174
|
+
typeof value === "object" && value !== null
|
|
175
|
+
? value.constructor?.name ?? typeof value
|
|
176
|
+
: typeof value;
|
|
177
|
+
throw new TypeError(
|
|
178
|
+
`Value at ${path || "root"} of type "${typeName}" is not CBOR serializable`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
16
181
|
|
|
17
182
|
export const EncodingSchema = z.enum(["json", "cbor", "bare"]);
|
|
18
183
|
|
|
@@ -112,38 +277,95 @@ function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
|
112
277
|
return proto === Object.prototype || proto === null;
|
|
113
278
|
}
|
|
114
279
|
|
|
115
|
-
export function encodeJsonCompatValue(input:
|
|
280
|
+
export function encodeJsonCompatValue(input: JsonCompatValue): unknown {
|
|
281
|
+
// Primitives
|
|
282
|
+
if (input === null) {
|
|
283
|
+
return input;
|
|
284
|
+
}
|
|
116
285
|
if (input === undefined) {
|
|
117
286
|
return [JSON_COMPAT_UNDEFINED, 0];
|
|
118
287
|
}
|
|
288
|
+
if (
|
|
289
|
+
typeof input === "string" ||
|
|
290
|
+
typeof input === "number" ||
|
|
291
|
+
typeof input === "boolean"
|
|
292
|
+
) {
|
|
293
|
+
return input;
|
|
294
|
+
}
|
|
119
295
|
if (typeof input === "bigint") {
|
|
120
296
|
return [JSON_COMPAT_BIGINT, input.toString()];
|
|
121
297
|
}
|
|
298
|
+
|
|
299
|
+
// Binary types with custom encoding
|
|
122
300
|
if (input instanceof ArrayBuffer) {
|
|
123
301
|
return [JSON_COMPAT_ARRAY_BUFFER, base64EncodeArrayBuffer(input)];
|
|
124
302
|
}
|
|
125
303
|
if (input instanceof Uint8Array) {
|
|
126
304
|
return [JSON_COMPAT_UINT8_ARRAY, base64EncodeUint8Array(input)];
|
|
127
305
|
}
|
|
306
|
+
|
|
307
|
+
// TypedArrays pass through for cbor-x native handling
|
|
308
|
+
if (isTypedArray(input)) {
|
|
309
|
+
return input;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Date, RegExp, and Error pass through for cbor-x native handling
|
|
313
|
+
if (input instanceof Date || input instanceof RegExp || input instanceof Error) {
|
|
314
|
+
return input;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Set uses custom tag encoding
|
|
318
|
+
if (input instanceof Set) {
|
|
319
|
+
const encoded = [...input.values()].map((v) =>
|
|
320
|
+
encodeJsonCompatValue(v as JsonCompatValue),
|
|
321
|
+
);
|
|
322
|
+
return [JSON_COMPAT_SET, encoded];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Map recurses into keys and values
|
|
326
|
+
if (input instanceof Map) {
|
|
327
|
+
const encoded = new Map<unknown, unknown>();
|
|
328
|
+
for (const [k, v] of input.entries()) {
|
|
329
|
+
encoded.set(
|
|
330
|
+
encodeJsonCompatValue(k as JsonCompatValue),
|
|
331
|
+
encodeJsonCompatValue(v as JsonCompatValue),
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
return encoded;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Arrays
|
|
128
338
|
if (Array.isArray(input)) {
|
|
129
|
-
const encoded = input.map((value) =>
|
|
339
|
+
const encoded = input.map((value) =>
|
|
340
|
+
encodeJsonCompatValue(value as JsonCompatValue),
|
|
341
|
+
);
|
|
130
342
|
if (
|
|
131
343
|
encoded.length === 2 &&
|
|
132
344
|
typeof encoded[0] === "string" &&
|
|
133
|
-
encoded[0].startsWith("$")
|
|
345
|
+
(encoded[0] as string).startsWith("$")
|
|
134
346
|
) {
|
|
135
347
|
return ["$" + encoded[0], encoded[1]];
|
|
136
348
|
}
|
|
137
349
|
return encoded;
|
|
138
350
|
}
|
|
351
|
+
|
|
352
|
+
// Plain objects
|
|
139
353
|
if (isPlainObject(input)) {
|
|
140
354
|
const encoded: Record<string, unknown> = {};
|
|
141
355
|
for (const [key, value] of Object.entries(input)) {
|
|
142
|
-
encoded[key] = encodeJsonCompatValue(value);
|
|
356
|
+
encoded[key] = encodeJsonCompatValue(value as JsonCompatValue);
|
|
143
357
|
}
|
|
144
358
|
return encoded;
|
|
145
359
|
}
|
|
146
|
-
|
|
360
|
+
|
|
361
|
+
// Not serializable
|
|
362
|
+
const typeName =
|
|
363
|
+
typeof input === "object" && input !== null
|
|
364
|
+
? (input as object).constructor?.name ?? typeof input
|
|
365
|
+
: typeof input;
|
|
366
|
+
throw new TypeError(
|
|
367
|
+
`Value of type "${typeName}" is not CBOR serializable`,
|
|
368
|
+
);
|
|
147
369
|
}
|
|
148
370
|
|
|
149
371
|
export interface JsonCompatReviveOptions {
|
|
@@ -164,6 +386,16 @@ export function reviveJsonCompatValue(
|
|
|
164
386
|
}
|
|
165
387
|
return input;
|
|
166
388
|
}
|
|
389
|
+
if (input instanceof Map) {
|
|
390
|
+
const revived = new Map();
|
|
391
|
+
for (const [k, v] of input.entries()) {
|
|
392
|
+
revived.set(
|
|
393
|
+
reviveJsonCompatValue(k, options),
|
|
394
|
+
reviveJsonCompatValue(v, options),
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
return revived;
|
|
398
|
+
}
|
|
167
399
|
if (Array.isArray(input)) {
|
|
168
400
|
if (
|
|
169
401
|
input.length === 2 &&
|
|
@@ -182,6 +414,12 @@ export function reviveJsonCompatValue(
|
|
|
182
414
|
if (input[0] === JSON_COMPAT_UNDEFINED) {
|
|
183
415
|
return undefined;
|
|
184
416
|
}
|
|
417
|
+
if (input[0] === JSON_COMPAT_SET) {
|
|
418
|
+
const items = (input[1] as unknown[]).map((v) =>
|
|
419
|
+
reviveJsonCompatValue(v, options),
|
|
420
|
+
);
|
|
421
|
+
return new Set(items);
|
|
422
|
+
}
|
|
185
423
|
if (input[0].startsWith("$$")) {
|
|
186
424
|
return [
|
|
187
425
|
input[0].substring(1),
|
|
@@ -161,28 +161,28 @@ export class InlineWebSocketAdapter {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
#handleError(
|
|
165
|
-
console.error("INLINE_WEBSOCKET_ADAPTER_ERROR",
|
|
164
|
+
#handleError(error: unknown): void {
|
|
165
|
+
console.error("INLINE_WEBSOCKET_ADAPTER_ERROR", error);
|
|
166
166
|
logger().error({
|
|
167
167
|
msg: "error in websocket",
|
|
168
|
-
error
|
|
169
|
-
errorMessage:
|
|
170
|
-
stack:
|
|
168
|
+
error,
|
|
169
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
170
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
// Call handler.onError
|
|
174
174
|
try {
|
|
175
|
-
this.#handler.onError(
|
|
176
|
-
} catch (
|
|
175
|
+
this.#handler.onError(error, this.#wsContext);
|
|
176
|
+
} catch (error) {
|
|
177
177
|
logger().error({
|
|
178
178
|
msg: "error in onError handler",
|
|
179
|
-
error
|
|
179
|
+
error,
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
// Fire error event to both sides
|
|
184
|
-
this.#clientWs.triggerError(
|
|
185
|
-
this.#actorWs.triggerError(
|
|
184
|
+
this.#clientWs.triggerError(error);
|
|
185
|
+
this.#actorWs.triggerError(error);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
#close(code: number, reason: string): void {
|
|
@@ -199,8 +199,8 @@ export class InlineWebSocketAdapter {
|
|
|
199
199
|
{ code, reason, wasClean: true },
|
|
200
200
|
this.#wsContext,
|
|
201
201
|
);
|
|
202
|
-
} catch (
|
|
203
|
-
logger().error({ msg: "error closing websocket", error
|
|
202
|
+
} catch (error) {
|
|
203
|
+
logger().error({ msg: "error closing websocket", error });
|
|
204
204
|
} finally {
|
|
205
205
|
this.#readyState = 3; // CLOSED
|
|
206
206
|
|
package/src/common/log.ts
CHANGED
|
@@ -76,6 +76,7 @@ export function configureDefaultLogger(logLevel?: LogLevel) {
|
|
|
76
76
|
messageKey: "msg",
|
|
77
77
|
// Do not include pid/hostname in output
|
|
78
78
|
base: {},
|
|
79
|
+
errorKey: "error",
|
|
79
80
|
// Keep the numeric level so the logfmt sink can match Pino's levels.
|
|
80
81
|
formatters: {
|
|
81
82
|
level(_label: string, number: number) {
|
package/src/common/router.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
HEADER_ACTOR_ID,
|
|
7
7
|
HEADER_ACTOR_KEY,
|
|
8
8
|
} from "@/common/actor-router-consts";
|
|
9
|
-
import type { Encoding } from "@/common/encoding";
|
|
9
|
+
import type { JsonCompatValue, Encoding } from "@/common/encoding";
|
|
10
10
|
import {
|
|
11
11
|
getRequestEncoding,
|
|
12
12
|
getRequestExposeInternalError,
|
|
@@ -111,7 +111,7 @@ export function handleRouteError(error: unknown, c: HonoContext) {
|
|
|
111
111
|
code: value.code,
|
|
112
112
|
message: value.message,
|
|
113
113
|
metadata: value.metadata
|
|
114
|
-
? bufferToArrayBuffer(encodeCborCompat(value.metadata))
|
|
114
|
+
? bufferToArrayBuffer(encodeCborCompat(value.metadata as JsonCompatValue))
|
|
115
115
|
: null,
|
|
116
116
|
actor: value.actor
|
|
117
117
|
? {
|
package/src/common/utils.ts
CHANGED
|
@@ -36,154 +36,6 @@ export function safeStringify(obj: unknown, maxSize: number) {
|
|
|
36
36
|
return JSON.stringify(obj, replacer);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
// TODO: Instead of doing this, use a temp var for state and attempt to write
|
|
40
|
-
// it. Roll back state if fails to serialize.
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Check if a value is CBOR serializable.
|
|
44
|
-
* Optionally pass an onInvalid callback to receive the path to invalid values.
|
|
45
|
-
*
|
|
46
|
-
* For a complete list of supported CBOR tags, see:
|
|
47
|
-
* https://github.com/kriszyp/cbor-x/blob/cc1cf9df8ba72288c7842af1dd374d73e34cdbc1/README.md#list-of-supported-tags-for-decoding
|
|
48
|
-
*/
|
|
49
|
-
export function isCborSerializable(
|
|
50
|
-
value: unknown,
|
|
51
|
-
onInvalid?: (path: string) => void,
|
|
52
|
-
currentPath = "",
|
|
53
|
-
): boolean {
|
|
54
|
-
// Handle primitive types directly
|
|
55
|
-
if (value === null || value === undefined) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (typeof value === "number") {
|
|
60
|
-
if (!Number.isFinite(value)) {
|
|
61
|
-
onInvalid?.(currentPath);
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (typeof value === "boolean" || typeof value === "string") {
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Handle BigInt (CBOR tags 2 and 3)
|
|
72
|
-
if (typeof value === "bigint") {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Handle Date objects (CBOR tags 0 and 1)
|
|
77
|
-
if (value instanceof Date) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Handle typed arrays (CBOR tags 64-82)
|
|
82
|
-
if (
|
|
83
|
-
value instanceof Uint8Array ||
|
|
84
|
-
value instanceof Uint8ClampedArray ||
|
|
85
|
-
value instanceof Uint16Array ||
|
|
86
|
-
value instanceof Uint32Array ||
|
|
87
|
-
value instanceof BigUint64Array ||
|
|
88
|
-
value instanceof Int8Array ||
|
|
89
|
-
value instanceof Int16Array ||
|
|
90
|
-
value instanceof Int32Array ||
|
|
91
|
-
value instanceof BigInt64Array ||
|
|
92
|
-
value instanceof Float32Array ||
|
|
93
|
-
value instanceof Float64Array
|
|
94
|
-
) {
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Handle Map (CBOR tag 259)
|
|
99
|
-
if (value instanceof Map) {
|
|
100
|
-
for (const [key, val] of value.entries()) {
|
|
101
|
-
const keyPath = currentPath
|
|
102
|
-
? `${currentPath}.key(${String(key)})`
|
|
103
|
-
: `key(${String(key)})`;
|
|
104
|
-
const valPath = currentPath
|
|
105
|
-
? `${currentPath}.value(${String(key)})`
|
|
106
|
-
: `value(${String(key)})`;
|
|
107
|
-
if (
|
|
108
|
-
!isCborSerializable(key, onInvalid, keyPath) ||
|
|
109
|
-
!isCborSerializable(val, onInvalid, valPath)
|
|
110
|
-
) {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Handle Set (CBOR tag 258)
|
|
118
|
-
if (value instanceof Set) {
|
|
119
|
-
let index = 0;
|
|
120
|
-
for (const item of value.values()) {
|
|
121
|
-
const itemPath = currentPath
|
|
122
|
-
? `${currentPath}.set[${index}]`
|
|
123
|
-
: `set[${index}]`;
|
|
124
|
-
if (!isCborSerializable(item, onInvalid, itemPath)) {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
index++;
|
|
128
|
-
}
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Handle RegExp (CBOR tag 27)
|
|
133
|
-
if (value instanceof RegExp) {
|
|
134
|
-
return true;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Handle Error objects (CBOR tag 27)
|
|
138
|
-
if (value instanceof Error) {
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Handle arrays
|
|
143
|
-
if (Array.isArray(value)) {
|
|
144
|
-
for (let i = 0; i < value.length; i++) {
|
|
145
|
-
const itemPath = currentPath ? `${currentPath}[${i}]` : `[${i}]`;
|
|
146
|
-
if (!isCborSerializable(value[i], onInvalid, itemPath)) {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Handle plain objects and records (CBOR tags 105, 51, 57344-57599)
|
|
154
|
-
if (typeof value === "object") {
|
|
155
|
-
// Allow plain objects and objects with prototypes (for records and named objects)
|
|
156
|
-
const proto = Object.getPrototypeOf(value);
|
|
157
|
-
if (proto !== null && proto !== Object.prototype) {
|
|
158
|
-
// Check if it's a known serializable object type
|
|
159
|
-
const protoConstructor = value.constructor;
|
|
160
|
-
if (protoConstructor && typeof protoConstructor.name === "string") {
|
|
161
|
-
// Allow objects with named constructors (records, named objects)
|
|
162
|
-
// This includes user-defined classes and built-in objects
|
|
163
|
-
// that CBOR can serialize with tag 27 or record tags
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Check all properties recursively
|
|
168
|
-
for (const key in value) {
|
|
169
|
-
const propPath = currentPath ? `${currentPath}.${key}` : key;
|
|
170
|
-
if (
|
|
171
|
-
!isCborSerializable(
|
|
172
|
-
value[key as keyof typeof value],
|
|
173
|
-
onInvalid,
|
|
174
|
-
propPath,
|
|
175
|
-
)
|
|
176
|
-
) {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return true;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Not serializable
|
|
184
|
-
onInvalid?.(currentPath);
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
39
|
|
|
188
40
|
export interface DeconstructedError {
|
|
189
41
|
__type: "ActorError";
|
|
@@ -284,7 +284,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
284
284
|
logger().debug({
|
|
285
285
|
msg: "actor crash cleanup errored",
|
|
286
286
|
actorId,
|
|
287
|
-
|
|
287
|
+
error: stringifyError(err),
|
|
288
288
|
});
|
|
289
289
|
}
|
|
290
290
|
}
|
|
@@ -1357,7 +1357,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1357
1357
|
logger().warn({
|
|
1358
1358
|
msg: "failed to rebind dynamic hibernatable runner websocket",
|
|
1359
1359
|
actorId,
|
|
1360
|
-
|
|
1360
|
+
error: stringifyError(result.reason),
|
|
1361
1361
|
});
|
|
1362
1362
|
}
|
|
1363
1363
|
}
|
|
@@ -1380,7 +1380,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1380
1380
|
logger().warn({
|
|
1381
1381
|
msg: "failed to rebind hibernatable connect socket",
|
|
1382
1382
|
actorId,
|
|
1383
|
-
|
|
1383
|
+
error: stringifyError(result.reason),
|
|
1384
1384
|
});
|
|
1385
1385
|
}
|
|
1386
1386
|
}
|
|
@@ -1640,7 +1640,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1640
1640
|
logger().warn({
|
|
1641
1641
|
msg: "failed to restore dynamic hibernating requests after actor start",
|
|
1642
1642
|
actorId,
|
|
1643
|
-
|
|
1643
|
+
error: stringifyError(error),
|
|
1644
1644
|
});
|
|
1645
1645
|
}
|
|
1646
1646
|
} else if (isStaticActorDefinition(definition)) {
|
|
@@ -1707,7 +1707,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1707
1707
|
logger().debug({
|
|
1708
1708
|
msg: "failed to dispose dynamic runtime after actor start failure",
|
|
1709
1709
|
actorId,
|
|
1710
|
-
|
|
1710
|
+
error: stringifyError(disposeError),
|
|
1711
1711
|
});
|
|
1712
1712
|
}
|
|
1713
1713
|
this.#dynamicRuntimes.delete(actorId);
|
|
@@ -1730,7 +1730,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1730
1730
|
actorId,
|
|
1731
1731
|
name,
|
|
1732
1732
|
key,
|
|
1733
|
-
|
|
1733
|
+
error: stringifyError(error),
|
|
1734
1734
|
});
|
|
1735
1735
|
|
|
1736
1736
|
try {
|
|
@@ -1739,7 +1739,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1739
1739
|
logger().debug({
|
|
1740
1740
|
msg: "failed to stop actor after start failure",
|
|
1741
1741
|
actorId,
|
|
1742
|
-
|
|
1742
|
+
error: stringifyError(stopError),
|
|
1743
1743
|
});
|
|
1744
1744
|
}
|
|
1745
1745
|
}
|
|
@@ -1786,7 +1786,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1786
1786
|
logger().debug({
|
|
1787
1787
|
msg: "actor start failed during stop, cleaning up handler",
|
|
1788
1788
|
actorId,
|
|
1789
|
-
|
|
1789
|
+
error: stringifyError(err),
|
|
1790
1790
|
});
|
|
1791
1791
|
}
|
|
1792
1792
|
}
|
|
@@ -1804,7 +1804,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1804
1804
|
} catch (err) {
|
|
1805
1805
|
logger().error({
|
|
1806
1806
|
msg: "error in onStop, proceeding with removing actor",
|
|
1807
|
-
|
|
1807
|
+
error: stringifyError(err),
|
|
1808
1808
|
});
|
|
1809
1809
|
}
|
|
1810
1810
|
}
|
|
@@ -1989,8 +1989,8 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
1989
1989
|
isHibernatable,
|
|
1990
1990
|
isRestoringHibernatable,
|
|
1991
1991
|
);
|
|
1992
|
-
} catch (
|
|
1993
|
-
logger().error({ msg: "building websocket handlers errored",
|
|
1992
|
+
} catch (error) {
|
|
1993
|
+
logger().error({ msg: "building websocket handlers errored", error });
|
|
1994
1994
|
websocketRaw.close(1011, "ws.route_error");
|
|
1995
1995
|
return;
|
|
1996
1996
|
}
|
|
@@ -16,6 +16,7 @@ import { importWebSocket } from "@/common/websocket";
|
|
|
16
16
|
import { setRemoteHibernatableWebSocketAckTestHooks } from "@/common/websocket-test-hooks";
|
|
17
17
|
import type { ActorGatewayQuery, CrashPolicy } from "@/client/query";
|
|
18
18
|
import type { Encoding, UniversalWebSocket } from "@/mod";
|
|
19
|
+
import type { JsonCompatValue } from "@/common/encoding";
|
|
19
20
|
import { encodeCborCompat, uint8ArrayToBase64 } from "@/serde";
|
|
20
21
|
import { combineUrlPath } from "@/utils";
|
|
21
22
|
import { shouldSkipReadyWait, type GatewayRequestOptions } from "./driver";
|
|
@@ -302,7 +303,7 @@ function pushInputQueryParam(
|
|
|
302
303
|
return;
|
|
303
304
|
}
|
|
304
305
|
|
|
305
|
-
const encodedInput = encodeCborCompat(input);
|
|
306
|
+
const encodedInput = encodeCborCompat(input as JsonCompatValue);
|
|
306
307
|
if (encodedInput.byteLength > maxInputSize) {
|
|
307
308
|
throw new Error(
|
|
308
309
|
`Actor query input exceeds maxInputSize (${encodedInput.byteLength} > ${maxInputSize} bytes). Increase client maxInputSize to allow larger query payloads.`,
|
package/src/engine-client/mod.ts
CHANGED
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
RuntimeDisplayInformation,
|
|
24
24
|
} from "@/engine-client/driver";
|
|
25
25
|
import type { Encoding, UniversalWebSocket } from "@/mod";
|
|
26
|
+
import type { JsonCompatValue } from "@/common/encoding";
|
|
26
27
|
import { encodeCborCompat, uint8ArrayToBase64 } from "@/serde";
|
|
27
28
|
import { combineUrlPath, type GetUpgradeWebSocket } from "@/utils";
|
|
28
29
|
import { getNextPhase } from "@/utils/env-vars";
|
|
@@ -181,7 +182,7 @@ export class RemoteEngineControlClient implements EngineControlClient {
|
|
|
181
182
|
key: serializeActorKey(key),
|
|
182
183
|
runner_name_selector: this.#config.poolName,
|
|
183
184
|
input: actorInput
|
|
184
|
-
? uint8ArrayToBase64(encodeCborCompat(actorInput))
|
|
185
|
+
? uint8ArrayToBase64(encodeCborCompat(actorInput as JsonCompatValue))
|
|
185
186
|
: undefined,
|
|
186
187
|
crash_policy: crashPolicy ?? "sleep",
|
|
187
188
|
});
|
|
@@ -215,7 +216,7 @@ export class RemoteEngineControlClient implements EngineControlClient {
|
|
|
215
216
|
runner_name_selector: this.#config.poolName,
|
|
216
217
|
key: serializeActorKey(key),
|
|
217
218
|
input: input
|
|
218
|
-
? uint8ArrayToBase64(encodeCborCompat(input))
|
|
219
|
+
? uint8ArrayToBase64(encodeCborCompat(input as JsonCompatValue))
|
|
219
220
|
: undefined,
|
|
220
221
|
crash_policy: crashPolicy ?? "sleep",
|
|
221
222
|
});
|