rivetkit 2.0.19 → 2.0.21
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/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/{chunk-UGLCR467.js → chunk-2POQCWMA.js} +481 -100
- package/dist/tsup/chunk-2POQCWMA.js.map +1 -0
- package/dist/tsup/{chunk-GBVUP7IH.js → chunk-3UIGKLZW.js} +6 -6
- package/dist/tsup/chunk-3UIGKLZW.js.map +1 -0
- package/dist/tsup/{chunk-NCVKAD3U.js → chunk-4OINFQBR.js} +3 -3
- package/dist/tsup/{chunk-2N5T57W5.cjs → chunk-65SAIRRY.cjs} +12 -12
- package/dist/tsup/chunk-65SAIRRY.cjs.map +1 -0
- package/dist/tsup/{chunk-SO6CSZPF.js → chunk-6G76WIWL.js} +2 -2
- package/dist/tsup/{chunk-SO6CSZPF.js.map → chunk-6G76WIWL.js.map} +1 -1
- package/dist/tsup/{chunk-UBS2ARYU.js → chunk-D2LS4X6E.js} +11 -5
- package/dist/tsup/chunk-D2LS4X6E.js.map +1 -0
- package/dist/tsup/{chunk-FO4Q36GQ.js → chunk-DYA34FHW.js} +2 -2
- package/dist/tsup/{chunk-7RKGZXDH.cjs → chunk-ELDFBXDV.cjs} +8 -4
- package/dist/tsup/chunk-ELDFBXDV.cjs.map +1 -0
- package/dist/tsup/{chunk-F4PHLUIT.cjs → chunk-FDJ3AVNB.cjs} +32 -26
- package/dist/tsup/chunk-FDJ3AVNB.cjs.map +1 -0
- package/dist/tsup/{chunk-U3PO7PEY.js → chunk-FUX6U6TL.js} +2 -2
- package/dist/tsup/chunk-FUX6U6TL.js.map +1 -0
- package/dist/tsup/{chunk-AYNDGM4A.cjs → chunk-HN7UXCYQ.cjs} +7 -7
- package/dist/tsup/chunk-HN7UXCYQ.cjs.map +1 -0
- package/dist/tsup/{chunk-6MI3RWWC.js → chunk-HUGSRAGL.js} +8 -4
- package/dist/tsup/chunk-HUGSRAGL.js.map +1 -0
- package/dist/tsup/{chunk-7BTAYSZC.cjs → chunk-JKOUXDK6.cjs} +16 -10
- package/dist/tsup/chunk-JKOUXDK6.cjs.map +1 -0
- package/dist/tsup/{chunk-EXP6CQEI.cjs → chunk-JTIBPF7N.cjs} +14 -14
- package/dist/tsup/chunk-JTIBPF7N.cjs.map +1 -0
- package/dist/tsup/chunk-KSRXX3Z4.cjs.map +1 -1
- package/dist/tsup/{chunk-RIK4JNIG.cjs → chunk-LMJHBF26.cjs} +454 -288
- package/dist/tsup/chunk-LMJHBF26.cjs.map +1 -0
- package/dist/tsup/{chunk-DGXMPCNI.cjs → chunk-LWGCMELP.cjs} +3 -3
- package/dist/tsup/chunk-LWGCMELP.cjs.map +1 -0
- package/dist/tsup/{chunk-ZB3DP5IR.cjs → chunk-M5BHNJHB.cjs} +630 -249
- package/dist/tsup/chunk-M5BHNJHB.cjs.map +1 -0
- package/dist/tsup/{chunk-J5PFJTK3.cjs → chunk-O4GUKGK4.cjs} +6 -6
- package/dist/tsup/chunk-O4GUKGK4.cjs.map +1 -0
- package/dist/tsup/{chunk-LWQDW6VP.js → chunk-RZZDFDB6.js} +13 -7
- package/dist/tsup/chunk-RZZDFDB6.js.map +1 -0
- package/dist/tsup/{chunk-DAZ2YBCM.js → chunk-VLR3TDHT.js} +2 -2
- package/dist/tsup/{chunk-DAAQFFK3.js → chunk-Y2QONT7B.js} +262 -96
- package/dist/tsup/chunk-Y2QONT7B.js.map +1 -0
- package/dist/tsup/{chunk-AXQWQIUS.cjs → chunk-ZNWE3XBT.cjs} +3 -3
- package/dist/tsup/chunk-ZNWE3XBT.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.cjs.map +1 -1
- package/dist/tsup/client/mod.d.cts +2 -2
- package/dist/tsup/client/mod.d.ts +2 -2
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.cjs.map +1 -1
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.cjs.map +1 -1
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{conn-DAXlyhVg.d.ts → conn-Clu655RU.d.ts} +1 -0
- package/dist/tsup/{conn--6rFdSfD.d.cts → conn-lUvFLo_q.d.cts} +1 -0
- package/dist/tsup/driver-helpers/mod.cjs +5 -5
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +1 -1
- package/dist/tsup/driver-helpers/mod.d.ts +1 -1
- package/dist/tsup/driver-helpers/mod.js +4 -4
- package/dist/tsup/driver-test-suite/mod.cjs +603 -294
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +1 -1
- package/dist/tsup/driver-test-suite/mod.d.ts +1 -1
- package/dist/tsup/driver-test-suite/mod.js +574 -265
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +68 -7
- package/dist/tsup/inspector/mod.d.ts +68 -7
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +10 -10
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +2 -2
- package/dist/tsup/mod.d.ts +2 -2
- package/dist/tsup/mod.js +9 -9
- package/dist/tsup/test/mod.cjs +11 -11
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +1 -1
- package/dist/tsup/test/mod.d.ts +1 -1
- package/dist/tsup/test/mod.js +10 -10
- package/dist/tsup/utils.cjs +2 -2
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.js +1 -1
- package/package.json +4 -3
- package/src/actor/config.ts +108 -15
- package/src/actor/conn-drivers.ts +2 -1
- package/src/actor/instance.ts +119 -35
- package/src/actor/keys.test.ts +13 -4
- package/src/actor/protocol/old.ts +10 -3
- package/src/actor/router-endpoints.ts +26 -16
- package/src/actor/router.ts +41 -13
- package/src/actor/unstable-react.ts +1 -1
- package/src/client/actor-common.ts +3 -1
- package/src/client/actor-conn.ts +44 -12
- package/src/client/actor-handle.ts +4 -1
- package/src/client/client.ts +32 -18
- package/src/client/utils.ts +21 -8
- package/src/common/actor-router-consts.ts +2 -0
- package/src/common/inline-websocket-adapter2.ts +24 -6
- package/src/common/log.ts +6 -2
- package/src/common/logfmt.ts +3 -1
- package/src/common/router.ts +3 -1
- package/src/common/utils.ts +6 -2
- package/src/driver-helpers/utils.ts +4 -1
- package/src/driver-test-suite/mod.ts +15 -4
- package/src/driver-test-suite/test-inline-client-driver.ts +35 -13
- package/src/driver-test-suite/tests/action-features.ts +6 -2
- package/src/driver-test-suite/tests/actor-conn-state.ts +18 -8
- package/src/driver-test-suite/tests/actor-conn.ts +35 -13
- package/src/driver-test-suite/tests/actor-handle.ts +35 -15
- package/src/driver-test-suite/tests/actor-inline-client.ts +34 -23
- package/src/driver-test-suite/tests/actor-inspector.ts +241 -131
- package/src/driver-test-suite/tests/actor-reconnect.ts +14 -4
- package/src/driver-test-suite/tests/actor-schedule.ts +12 -3
- package/src/driver-test-suite/tests/actor-sleep.ts +6 -3
- package/src/driver-test-suite/tests/actor-vars.ts +6 -2
- package/src/driver-test-suite/tests/manager-driver.ts +16 -6
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +64 -25
- package/src/driver-test-suite/tests/raw-http.ts +17 -5
- package/src/driver-test-suite/tests/raw-websocket.ts +36 -12
- package/src/driver-test-suite/tests/request-access.ts +18 -8
- package/src/drivers/engine/actor-driver.ts +46 -25
- package/src/drivers/engine/config.ts +2 -1
- package/src/drivers/file-system/global-state.ts +58 -16
- package/src/drivers/file-system/manager.ts +35 -12
- package/src/drivers/file-system/mod.ts +6 -1
- package/src/drivers/file-system/utils.ts +8 -2
- package/src/engine-process/mod.ts +15 -4
- package/src/inspector/actor.ts +63 -23
- package/src/inspector/config.ts +2 -1
- package/src/inspector/manager.ts +10 -3
- package/src/inspector/utils.ts +2 -1
- package/src/manager/driver.ts +4 -1
- package/src/manager/gateway.ts +278 -8
- package/src/manager/hono-websocket-adapter.ts +33 -10
- package/src/manager/router-schema.ts +4 -2
- package/src/manager/router.ts +78 -12
- package/src/manager-api/actors.ts +2 -0
- package/src/registry/mod.ts +31 -9
- package/src/registry/run-config.ts +3 -1
- package/src/remote-manager-driver/api-endpoints.ts +2 -2
- package/src/remote-manager-driver/mod.ts +22 -5
- package/src/remote-manager-driver/ws-proxy.ts +21 -5
- package/src/serde.ts +6 -2
- package/src/test/mod.ts +2 -1
- package/src/utils.ts +6 -2
- package/dist/tsup/chunk-2N5T57W5.cjs.map +0 -1
- package/dist/tsup/chunk-6MI3RWWC.js.map +0 -1
- package/dist/tsup/chunk-7BTAYSZC.cjs.map +0 -1
- package/dist/tsup/chunk-7RKGZXDH.cjs.map +0 -1
- package/dist/tsup/chunk-AXQWQIUS.cjs.map +0 -1
- package/dist/tsup/chunk-AYNDGM4A.cjs.map +0 -1
- package/dist/tsup/chunk-DAAQFFK3.js.map +0 -1
- package/dist/tsup/chunk-DGXMPCNI.cjs.map +0 -1
- package/dist/tsup/chunk-EXP6CQEI.cjs.map +0 -1
- package/dist/tsup/chunk-F4PHLUIT.cjs.map +0 -1
- package/dist/tsup/chunk-GBVUP7IH.js.map +0 -1
- package/dist/tsup/chunk-J5PFJTK3.cjs.map +0 -1
- package/dist/tsup/chunk-LWQDW6VP.js.map +0 -1
- package/dist/tsup/chunk-RIK4JNIG.cjs.map +0 -1
- package/dist/tsup/chunk-U3PO7PEY.js.map +0 -1
- package/dist/tsup/chunk-UBS2ARYU.js.map +0 -1
- package/dist/tsup/chunk-UGLCR467.js.map +0 -1
- package/dist/tsup/chunk-ZB3DP5IR.cjs.map +0 -1
- /package/dist/tsup/{chunk-NCVKAD3U.js.map → chunk-4OINFQBR.js.map} +0 -0
- /package/dist/tsup/{chunk-FO4Q36GQ.js.map → chunk-DYA34FHW.js.map} +0 -0
- /package/dist/tsup/{chunk-DAZ2YBCM.js.map → chunk-VLR3TDHT.js.map} +0 -0
package/src/actor/config.ts
CHANGED
|
@@ -84,7 +84,10 @@ export const ActorConfigSchema = z
|
|
|
84
84
|
)
|
|
85
85
|
.refine(
|
|
86
86
|
(data) =>
|
|
87
|
-
!(
|
|
87
|
+
!(
|
|
88
|
+
data.connState !== undefined &&
|
|
89
|
+
data.createConnState !== undefined
|
|
90
|
+
),
|
|
88
91
|
{
|
|
89
92
|
message: "Cannot define both 'connState' and 'createConnState'",
|
|
90
93
|
path: ["connState"],
|
|
@@ -115,7 +118,10 @@ export interface OnConnectOptions {
|
|
|
115
118
|
type CreateState<TState, TConnParams, TConnState, TVars, TInput, TDatabase> =
|
|
116
119
|
| { state: TState }
|
|
117
120
|
| {
|
|
118
|
-
createState: (
|
|
121
|
+
createState: (
|
|
122
|
+
c: InitContext,
|
|
123
|
+
input: TInput,
|
|
124
|
+
) => TState | Promise<TState>;
|
|
119
125
|
}
|
|
120
126
|
| Record<never, never>;
|
|
121
127
|
|
|
@@ -159,7 +165,10 @@ type CreateVars<TState, TConnParams, TConnState, TVars, TInput, TDatabase> =
|
|
|
159
165
|
/**
|
|
160
166
|
* @experimental
|
|
161
167
|
*/
|
|
162
|
-
createVars: (
|
|
168
|
+
createVars: (
|
|
169
|
+
c: InitContext,
|
|
170
|
+
driverCtx: any,
|
|
171
|
+
) => TVars | Promise<TVars>;
|
|
163
172
|
}
|
|
164
173
|
| Record<never, never>;
|
|
165
174
|
|
|
@@ -172,7 +181,14 @@ export interface Actions<
|
|
|
172
181
|
TDatabase extends AnyDatabaseProvider,
|
|
173
182
|
> {
|
|
174
183
|
[Action: string]: (
|
|
175
|
-
c: ActionContext<
|
|
184
|
+
c: ActionContext<
|
|
185
|
+
TState,
|
|
186
|
+
TConnParams,
|
|
187
|
+
TConnState,
|
|
188
|
+
TVars,
|
|
189
|
+
TInput,
|
|
190
|
+
TDatabase
|
|
191
|
+
>,
|
|
176
192
|
...args: any[]
|
|
177
193
|
) => any;
|
|
178
194
|
}
|
|
@@ -210,7 +226,14 @@ interface BaseActorConfig<
|
|
|
210
226
|
* This is called before any other lifecycle hooks.
|
|
211
227
|
*/
|
|
212
228
|
onCreate?: (
|
|
213
|
-
c: ActorContext<
|
|
229
|
+
c: ActorContext<
|
|
230
|
+
TState,
|
|
231
|
+
TConnParams,
|
|
232
|
+
TConnState,
|
|
233
|
+
TVars,
|
|
234
|
+
TInput,
|
|
235
|
+
TDatabase
|
|
236
|
+
>,
|
|
214
237
|
input: TInput,
|
|
215
238
|
) => void | Promise<void>;
|
|
216
239
|
|
|
@@ -223,7 +246,14 @@ interface BaseActorConfig<
|
|
|
223
246
|
* @returns Void or a Promise that resolves when startup is complete
|
|
224
247
|
*/
|
|
225
248
|
onStart?: (
|
|
226
|
-
c: ActorContext<
|
|
249
|
+
c: ActorContext<
|
|
250
|
+
TState,
|
|
251
|
+
TConnParams,
|
|
252
|
+
TConnState,
|
|
253
|
+
TVars,
|
|
254
|
+
TInput,
|
|
255
|
+
TDatabase
|
|
256
|
+
>,
|
|
227
257
|
) => void | Promise<void>;
|
|
228
258
|
|
|
229
259
|
/**
|
|
@@ -237,7 +267,14 @@ interface BaseActorConfig<
|
|
|
237
267
|
* @returns Void or a Promise that resolves when shutdown is complete
|
|
238
268
|
*/
|
|
239
269
|
onStop?: (
|
|
240
|
-
c: ActorContext<
|
|
270
|
+
c: ActorContext<
|
|
271
|
+
TState,
|
|
272
|
+
TConnParams,
|
|
273
|
+
TConnState,
|
|
274
|
+
TVars,
|
|
275
|
+
TInput,
|
|
276
|
+
TDatabase
|
|
277
|
+
>,
|
|
241
278
|
) => void | Promise<void>;
|
|
242
279
|
|
|
243
280
|
/**
|
|
@@ -252,7 +289,14 @@ interface BaseActorConfig<
|
|
|
252
289
|
* @param newState The updated state
|
|
253
290
|
*/
|
|
254
291
|
onStateChange?: (
|
|
255
|
-
c: ActorContext<
|
|
292
|
+
c: ActorContext<
|
|
293
|
+
TState,
|
|
294
|
+
TConnParams,
|
|
295
|
+
TConnState,
|
|
296
|
+
TVars,
|
|
297
|
+
TInput,
|
|
298
|
+
TDatabase
|
|
299
|
+
>,
|
|
256
300
|
newState: TState,
|
|
257
301
|
) => void;
|
|
258
302
|
|
|
@@ -267,7 +311,14 @@ interface BaseActorConfig<
|
|
|
267
311
|
* @throws Throw an error to reject the connection
|
|
268
312
|
*/
|
|
269
313
|
onBeforeConnect?: (
|
|
270
|
-
c: ActorContext<
|
|
314
|
+
c: ActorContext<
|
|
315
|
+
TState,
|
|
316
|
+
TConnParams,
|
|
317
|
+
TConnState,
|
|
318
|
+
TVars,
|
|
319
|
+
TInput,
|
|
320
|
+
TDatabase
|
|
321
|
+
>,
|
|
271
322
|
opts: OnConnectOptions,
|
|
272
323
|
params: TConnParams,
|
|
273
324
|
) => void | Promise<void>;
|
|
@@ -282,7 +333,14 @@ interface BaseActorConfig<
|
|
|
282
333
|
* @returns Void or a Promise that resolves when connection handling is complete
|
|
283
334
|
*/
|
|
284
335
|
onConnect?: (
|
|
285
|
-
c: ActorContext<
|
|
336
|
+
c: ActorContext<
|
|
337
|
+
TState,
|
|
338
|
+
TConnParams,
|
|
339
|
+
TConnState,
|
|
340
|
+
TVars,
|
|
341
|
+
TInput,
|
|
342
|
+
TDatabase
|
|
343
|
+
>,
|
|
286
344
|
conn: Conn<TState, TConnParams, TConnState, TVars, TInput, TDatabase>,
|
|
287
345
|
) => void | Promise<void>;
|
|
288
346
|
|
|
@@ -296,7 +354,14 @@ interface BaseActorConfig<
|
|
|
296
354
|
* @returns Void or a Promise that resolves when disconnect handling is complete
|
|
297
355
|
*/
|
|
298
356
|
onDisconnect?: (
|
|
299
|
-
c: ActorContext<
|
|
357
|
+
c: ActorContext<
|
|
358
|
+
TState,
|
|
359
|
+
TConnParams,
|
|
360
|
+
TConnState,
|
|
361
|
+
TVars,
|
|
362
|
+
TInput,
|
|
363
|
+
TDatabase
|
|
364
|
+
>,
|
|
300
365
|
conn: Conn<TState, TConnParams, TConnState, TVars, TInput, TDatabase>,
|
|
301
366
|
) => void | Promise<void>;
|
|
302
367
|
|
|
@@ -313,7 +378,14 @@ interface BaseActorConfig<
|
|
|
313
378
|
* @returns The modified output to send to the client
|
|
314
379
|
*/
|
|
315
380
|
onBeforeActionResponse?: <Out>(
|
|
316
|
-
c: ActorContext<
|
|
381
|
+
c: ActorContext<
|
|
382
|
+
TState,
|
|
383
|
+
TConnParams,
|
|
384
|
+
TConnState,
|
|
385
|
+
TVars,
|
|
386
|
+
TInput,
|
|
387
|
+
TDatabase
|
|
388
|
+
>,
|
|
317
389
|
name: string,
|
|
318
390
|
args: unknown[],
|
|
319
391
|
output: Out,
|
|
@@ -329,7 +401,14 @@ interface BaseActorConfig<
|
|
|
329
401
|
* @returns A Response object to send back, or void to continue with default routing
|
|
330
402
|
*/
|
|
331
403
|
onFetch?: (
|
|
332
|
-
c: ActorContext<
|
|
404
|
+
c: ActorContext<
|
|
405
|
+
TState,
|
|
406
|
+
TConnParams,
|
|
407
|
+
TConnState,
|
|
408
|
+
TVars,
|
|
409
|
+
TInput,
|
|
410
|
+
TDatabase
|
|
411
|
+
>,
|
|
333
412
|
request: Request,
|
|
334
413
|
opts: {},
|
|
335
414
|
) => Response | Promise<Response>;
|
|
@@ -344,7 +423,14 @@ interface BaseActorConfig<
|
|
|
344
423
|
* @param request The original HTTP upgrade request
|
|
345
424
|
*/
|
|
346
425
|
onWebSocket?: (
|
|
347
|
-
c: ActorContext<
|
|
426
|
+
c: ActorContext<
|
|
427
|
+
TState,
|
|
428
|
+
TConnParams,
|
|
429
|
+
TConnState,
|
|
430
|
+
TVars,
|
|
431
|
+
TInput,
|
|
432
|
+
TDatabase
|
|
433
|
+
>,
|
|
348
434
|
websocket: UniversalWebSocket,
|
|
349
435
|
opts: { request: Request },
|
|
350
436
|
) => void | Promise<void>;
|
|
@@ -422,7 +508,14 @@ export type ActorConfigInput<
|
|
|
422
508
|
TDatabase
|
|
423
509
|
> = Record<never, never>,
|
|
424
510
|
> = {
|
|
425
|
-
types?: ActorTypes<
|
|
511
|
+
types?: ActorTypes<
|
|
512
|
+
TState,
|
|
513
|
+
TConnParams,
|
|
514
|
+
TConnState,
|
|
515
|
+
TVars,
|
|
516
|
+
TInput,
|
|
517
|
+
TDatabase
|
|
518
|
+
>;
|
|
426
519
|
} & Omit<
|
|
427
520
|
z.input<typeof ActorConfigSchema>,
|
|
428
521
|
| "actions"
|
|
@@ -85,7 +85,8 @@ const WEBSOCKET_DRIVER: ConnDriver<ConnDriverWebSocketState> = {
|
|
|
85
85
|
dataType: typeof serialized,
|
|
86
86
|
isUint8Array: serialized instanceof Uint8Array,
|
|
87
87
|
isArrayBuffer: serialized instanceof ArrayBuffer,
|
|
88
|
-
dataLength:
|
|
88
|
+
dataLength:
|
|
89
|
+
(serialized as any).byteLength || (serialized as any).length,
|
|
89
90
|
});
|
|
90
91
|
|
|
91
92
|
// Convert Uint8Array to ArrayBuffer for proper transmission
|
package/src/actor/instance.ts
CHANGED
|
@@ -20,12 +20,19 @@ import {
|
|
|
20
20
|
promiseWithResolvers,
|
|
21
21
|
SinglePromiseQueue,
|
|
22
22
|
} from "@/utils";
|
|
23
|
-
import
|
|
23
|
+
import { ActionContext } from "./action";
|
|
24
24
|
import type { ActorConfig, OnConnectOptions } from "./config";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
Conn,
|
|
27
|
+
type ConnId,
|
|
28
|
+
generateConnId,
|
|
29
|
+
generateConnSocketId,
|
|
30
|
+
generateConnToken,
|
|
31
|
+
} from "./conn";
|
|
26
32
|
import {
|
|
27
33
|
CONN_DRIVERS,
|
|
28
34
|
type ConnDriver,
|
|
35
|
+
ConnDriverKind,
|
|
29
36
|
type ConnDriverState,
|
|
30
37
|
getConnDriverKindFromState,
|
|
31
38
|
} from "./conn-drivers";
|
|
@@ -207,12 +214,14 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
207
214
|
return Object.keys(this.#config.actions);
|
|
208
215
|
},
|
|
209
216
|
getConnections: async () => {
|
|
210
|
-
return Array.from(this.#connections.entries()).map(
|
|
211
|
-
id,
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
217
|
+
return Array.from(this.#connections.entries()).map(
|
|
218
|
+
([id, conn]) => ({
|
|
219
|
+
id,
|
|
220
|
+
stateEnabled: conn.__stateEnabled,
|
|
221
|
+
params: conn.params as any,
|
|
222
|
+
state: conn.__stateEnabled ? conn.state : undefined,
|
|
223
|
+
}),
|
|
224
|
+
);
|
|
216
225
|
},
|
|
217
226
|
setState: async (state: unknown) => {
|
|
218
227
|
this.#validateStateEnabled();
|
|
@@ -225,6 +234,27 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
225
234
|
this.#persist.state = { ...(state as S) };
|
|
226
235
|
await this.saveState({ immediate: true });
|
|
227
236
|
},
|
|
237
|
+
executeAction: async (name, params) => {
|
|
238
|
+
const socketId = generateConnSocketId();
|
|
239
|
+
const conn = await this.createConn(
|
|
240
|
+
{
|
|
241
|
+
socketId,
|
|
242
|
+
driverState: { [ConnDriverKind.HTTP]: {} },
|
|
243
|
+
},
|
|
244
|
+
undefined,
|
|
245
|
+
undefined,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
return await this.executeAction(
|
|
250
|
+
new ActionContext(this.actorContext, conn),
|
|
251
|
+
name,
|
|
252
|
+
params || [],
|
|
253
|
+
);
|
|
254
|
+
} finally {
|
|
255
|
+
this.__connDisconnected(conn, true, socketId);
|
|
256
|
+
}
|
|
257
|
+
},
|
|
228
258
|
};
|
|
229
259
|
});
|
|
230
260
|
|
|
@@ -271,7 +301,10 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
271
301
|
};
|
|
272
302
|
|
|
273
303
|
this.#log = getBaseLogger().child(
|
|
274
|
-
Object.assign(
|
|
304
|
+
Object.assign(
|
|
305
|
+
getIncludeTarget() ? { target: "actor" } : {},
|
|
306
|
+
logParams,
|
|
307
|
+
),
|
|
275
308
|
);
|
|
276
309
|
this.#rLog = getBaseLogger().child(
|
|
277
310
|
Object.assign(
|
|
@@ -319,7 +352,9 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
319
352
|
} else if ("vars" in this.#config) {
|
|
320
353
|
vars = structuredClone(this.#config.vars);
|
|
321
354
|
} else {
|
|
322
|
-
throw new Error(
|
|
355
|
+
throw new Error(
|
|
356
|
+
"Could not variables from 'createVars' or 'vars'",
|
|
357
|
+
);
|
|
323
358
|
}
|
|
324
359
|
this.#vars = vars;
|
|
325
360
|
}
|
|
@@ -346,7 +381,9 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
346
381
|
|
|
347
382
|
// Set alarm for next scheduled event if any exist after finishing initiation sequence
|
|
348
383
|
if (this.#persist.scheduledEvents.length > 0) {
|
|
349
|
-
await this.#queueSetAlarm(
|
|
384
|
+
await this.#queueSetAlarm(
|
|
385
|
+
this.#persist.scheduledEvents[0].timestamp,
|
|
386
|
+
);
|
|
350
387
|
}
|
|
351
388
|
|
|
352
389
|
this.#rLog.info({ msg: "actor ready" });
|
|
@@ -475,7 +512,8 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
475
512
|
});
|
|
476
513
|
|
|
477
514
|
// Look up function
|
|
478
|
-
const fn: unknown =
|
|
515
|
+
const fn: unknown =
|
|
516
|
+
this.#config.actions[event.kind.generic.actionName];
|
|
479
517
|
|
|
480
518
|
if (!fn)
|
|
481
519
|
throw new Error(
|
|
@@ -589,10 +627,14 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
589
627
|
this.#persistChanged = false;
|
|
590
628
|
|
|
591
629
|
// Convert to BARE types and write to KV
|
|
592
|
-
const bareData = this.#convertToBarePersisted(
|
|
630
|
+
const bareData = this.#convertToBarePersisted(
|
|
631
|
+
this.#persistRaw,
|
|
632
|
+
);
|
|
593
633
|
await this.#actorDriver.writePersistedData(
|
|
594
634
|
this.#actorId,
|
|
595
|
-
PERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(
|
|
635
|
+
PERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(
|
|
636
|
+
bareData,
|
|
637
|
+
),
|
|
596
638
|
);
|
|
597
639
|
|
|
598
640
|
this.#rLog.debug({ msg: "persist saved" });
|
|
@@ -649,7 +691,12 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
649
691
|
this.#persist = onChange(
|
|
650
692
|
target,
|
|
651
693
|
// biome-ignore lint/suspicious/noExplicitAny: Don't know types in proxy
|
|
652
|
-
(
|
|
694
|
+
(
|
|
695
|
+
path: string,
|
|
696
|
+
value: any,
|
|
697
|
+
_previousValue: any,
|
|
698
|
+
_applyData: any,
|
|
699
|
+
) => {
|
|
653
700
|
if (path !== "state" && !path.startsWith("state.")) {
|
|
654
701
|
return;
|
|
655
702
|
}
|
|
@@ -671,7 +718,10 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
671
718
|
this.#persistChanged = true;
|
|
672
719
|
|
|
673
720
|
// Inform the inspector about state changes
|
|
674
|
-
this.inspector.emitter.emit(
|
|
721
|
+
this.inspector.emitter.emit(
|
|
722
|
+
"stateUpdated",
|
|
723
|
+
this.#persist.state,
|
|
724
|
+
);
|
|
675
725
|
|
|
676
726
|
// Call onStateChange if it exists
|
|
677
727
|
// Skip if we're already inside onStateChange to prevent infinite recursion
|
|
@@ -763,7 +813,9 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
763
813
|
} else if ("state" in this.#config) {
|
|
764
814
|
stateData = structuredClone(this.#config.state);
|
|
765
815
|
} else {
|
|
766
|
-
throw new Error(
|
|
816
|
+
throw new Error(
|
|
817
|
+
"Both 'createState' or 'state' were not defined",
|
|
818
|
+
);
|
|
767
819
|
}
|
|
768
820
|
} else {
|
|
769
821
|
this.#rLog.debug({ msg: "state not enabled" });
|
|
@@ -778,14 +830,19 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
778
830
|
const bareData = this.#convertToBarePersisted(persistData);
|
|
779
831
|
await this.#actorDriver.writePersistedData(
|
|
780
832
|
this.#actorId,
|
|
781
|
-
PERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(
|
|
833
|
+
PERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(
|
|
834
|
+
bareData,
|
|
835
|
+
),
|
|
782
836
|
);
|
|
783
837
|
|
|
784
838
|
this.#setPersist(persistData);
|
|
785
839
|
|
|
786
840
|
// Notify creation
|
|
787
841
|
if (this.#config.onCreate) {
|
|
788
|
-
await this.#config.onCreate(
|
|
842
|
+
await this.#config.onCreate(
|
|
843
|
+
this.actorContext,
|
|
844
|
+
persistData.input!,
|
|
845
|
+
);
|
|
789
846
|
}
|
|
790
847
|
}
|
|
791
848
|
}
|
|
@@ -870,7 +927,10 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
870
927
|
this.inspector.emitter.emit("connectionUpdated");
|
|
871
928
|
if (this.#config.onDisconnect) {
|
|
872
929
|
try {
|
|
873
|
-
const result = this.#config.onDisconnect(
|
|
930
|
+
const result = this.#config.onDisconnect(
|
|
931
|
+
this.actorContext,
|
|
932
|
+
conn,
|
|
933
|
+
);
|
|
874
934
|
if (result instanceof Promise) {
|
|
875
935
|
// Handle promise but don't await it to prevent blocking
|
|
876
936
|
result.catch((error) => {
|
|
@@ -1054,15 +1114,16 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
1054
1114
|
try {
|
|
1055
1115
|
const result = this.#config.onConnect(this.actorContext, conn);
|
|
1056
1116
|
if (result instanceof Promise) {
|
|
1057
|
-
deadline(
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1117
|
+
deadline(
|
|
1118
|
+
result,
|
|
1119
|
+
this.#config.options.onConnectTimeout,
|
|
1120
|
+
).catch((error) => {
|
|
1121
|
+
this.#rLog.error({
|
|
1122
|
+
msg: "error in `onConnect`, closing socket",
|
|
1123
|
+
error,
|
|
1124
|
+
});
|
|
1125
|
+
conn?.disconnect("`onConnect` failed");
|
|
1126
|
+
});
|
|
1066
1127
|
}
|
|
1067
1128
|
} catch (error) {
|
|
1068
1129
|
this.#rLog.error({
|
|
@@ -1224,11 +1285,17 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
1224
1285
|
|
|
1225
1286
|
for (const conn of this.#connections.values()) {
|
|
1226
1287
|
if (conn.__status === "connected") {
|
|
1227
|
-
this.#rLog.debug({
|
|
1288
|
+
this.#rLog.debug({
|
|
1289
|
+
msg: "connection is alive",
|
|
1290
|
+
connId: conn.id,
|
|
1291
|
+
});
|
|
1228
1292
|
} else {
|
|
1229
1293
|
const lastSeen = conn.__persist.lastSeen;
|
|
1230
1294
|
const sinceLastSeen = Date.now() - lastSeen;
|
|
1231
|
-
if (
|
|
1295
|
+
if (
|
|
1296
|
+
sinceLastSeen <
|
|
1297
|
+
this.#config.options.connectionLivenessTimeout
|
|
1298
|
+
) {
|
|
1232
1299
|
this.#rLog.debug({
|
|
1233
1300
|
msg: "connection might be alive, will check later",
|
|
1234
1301
|
connId: conn.id,
|
|
@@ -1311,7 +1378,11 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
1311
1378
|
args,
|
|
1312
1379
|
});
|
|
1313
1380
|
|
|
1314
|
-
const outputOrPromise = actionFunction.call(
|
|
1381
|
+
const outputOrPromise = actionFunction.call(
|
|
1382
|
+
undefined,
|
|
1383
|
+
ctx,
|
|
1384
|
+
...args,
|
|
1385
|
+
);
|
|
1315
1386
|
let output: unknown;
|
|
1316
1387
|
if (outputOrPromise instanceof Promise) {
|
|
1317
1388
|
// Log that we're waiting for an async action
|
|
@@ -1426,11 +1497,17 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
1426
1497
|
}
|
|
1427
1498
|
return response;
|
|
1428
1499
|
} catch (error) {
|
|
1429
|
-
this.#rLog.error({
|
|
1500
|
+
this.#rLog.error({
|
|
1501
|
+
msg: "onFetch error",
|
|
1502
|
+
error: stringifyError(error),
|
|
1503
|
+
});
|
|
1430
1504
|
throw error;
|
|
1431
1505
|
} finally {
|
|
1432
1506
|
// Decrement active raw fetch counter and re-evaluate sleep
|
|
1433
|
-
this.#activeRawFetchCount = Math.max(
|
|
1507
|
+
this.#activeRawFetchCount = Math.max(
|
|
1508
|
+
0,
|
|
1509
|
+
this.#activeRawFetchCount - 1,
|
|
1510
|
+
);
|
|
1434
1511
|
this.#resetSleepTimer();
|
|
1435
1512
|
this.#savePersistThrottled();
|
|
1436
1513
|
}
|
|
@@ -1765,6 +1842,11 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
1765
1842
|
|
|
1766
1843
|
this.#rLog.info({ msg: "actor stopping" });
|
|
1767
1844
|
|
|
1845
|
+
if (this.#sleepTimeout) {
|
|
1846
|
+
clearTimeout(this.#sleepTimeout);
|
|
1847
|
+
this.#sleepTimeout = undefined;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1768
1850
|
// Abort any listeners waiting for shutdown
|
|
1769
1851
|
try {
|
|
1770
1852
|
this.#abortController.abort();
|
|
@@ -1800,7 +1882,9 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
|
1800
1882
|
}
|
|
1801
1883
|
|
|
1802
1884
|
// Wait for any background tasks to finish, with timeout
|
|
1803
|
-
await this.#waitBackgroundPromises(
|
|
1885
|
+
await this.#waitBackgroundPromises(
|
|
1886
|
+
this.#config.options.waitUntilTimeout,
|
|
1887
|
+
);
|
|
1804
1888
|
|
|
1805
1889
|
// Clear timeouts
|
|
1806
1890
|
if (this.#pendingSaveTimeout) clearTimeout(this.#pendingSaveTimeout);
|
package/src/actor/keys.test.ts
CHANGED
|
@@ -25,7 +25,9 @@ describe("Key serialization and deserialization", () => {
|
|
|
25
25
|
|
|
26
26
|
test("escapes forward slashes in keys", () => {
|
|
27
27
|
expect(serializeActorKey(["a/b"])).toBe("a\\/b");
|
|
28
|
-
expect(serializeActorKey(["a/b", "c"])).toBe(
|
|
28
|
+
expect(serializeActorKey(["a/b", "c"])).toBe(
|
|
29
|
+
`a\\/b${KEY_SEPARATOR}c`,
|
|
30
|
+
);
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
test("escapes empty key marker in keys", () => {
|
|
@@ -46,7 +48,9 @@ describe("Key serialization and deserialization", () => {
|
|
|
46
48
|
});
|
|
47
49
|
|
|
48
50
|
test("deserializes undefined/null", () => {
|
|
49
|
-
expect(deserializeActorKey(undefined as unknown as string)).toEqual(
|
|
51
|
+
expect(deserializeActorKey(undefined as unknown as string)).toEqual(
|
|
52
|
+
[],
|
|
53
|
+
);
|
|
50
54
|
expect(deserializeActorKey(null as unknown as string)).toEqual([]);
|
|
51
55
|
});
|
|
52
56
|
|
|
@@ -127,7 +131,9 @@ describe("Key serialization and deserialization", () => {
|
|
|
127
131
|
expect(serialized2).toBe("\\0"); // Empty string becomes \0 marker
|
|
128
132
|
|
|
129
133
|
expect(deserializeActorKey(serialized1)).toEqual(emptyArray);
|
|
130
|
-
expect(deserializeActorKey(serialized2)).toEqual(
|
|
134
|
+
expect(deserializeActorKey(serialized2)).toEqual(
|
|
135
|
+
arrayWithEmptyString,
|
|
136
|
+
);
|
|
131
137
|
});
|
|
132
138
|
|
|
133
139
|
test("handles mix of empty strings and forward slash (EMPTY_KEY)", () => {
|
|
@@ -194,7 +200,10 @@ describe("Key serialization and deserialization", () => {
|
|
|
194
200
|
const testCases: Array<[string[], string]> = [
|
|
195
201
|
[["path\\to\\file/dir"], "path\\\\to\\\\file\\/dir"],
|
|
196
202
|
[["file\\with/slash"], "file\\\\with\\/slash"],
|
|
197
|
-
[
|
|
203
|
+
[
|
|
204
|
+
["path\\to\\file", "with/slash"],
|
|
205
|
+
"path\\\\to\\\\file/with\\/slash",
|
|
206
|
+
],
|
|
198
207
|
];
|
|
199
208
|
|
|
200
209
|
for (const [key, expectedSerialized] of testCases) {
|
|
@@ -57,7 +57,10 @@ export async function inputDataToBuffer(
|
|
|
57
57
|
return new Uint8Array(arrayBuffer);
|
|
58
58
|
} else if (data instanceof Uint8Array) {
|
|
59
59
|
return data;
|
|
60
|
-
} else if (
|
|
60
|
+
} else if (
|
|
61
|
+
data instanceof ArrayBuffer ||
|
|
62
|
+
data instanceof SharedArrayBuffer
|
|
63
|
+
) {
|
|
61
64
|
return new Uint8Array(data);
|
|
62
65
|
} else {
|
|
63
66
|
throw new errors.MalformedMessage();
|
|
@@ -171,7 +174,9 @@ export async function processMessage<
|
|
|
171
174
|
tag: "ActionResponse",
|
|
172
175
|
val: {
|
|
173
176
|
id: id,
|
|
174
|
-
output: bufferToArrayBuffer(
|
|
177
|
+
output: bufferToArrayBuffer(
|
|
178
|
+
cbor.encode(output),
|
|
179
|
+
),
|
|
175
180
|
},
|
|
176
181
|
},
|
|
177
182
|
},
|
|
@@ -240,7 +245,9 @@ export async function processMessage<
|
|
|
240
245
|
group,
|
|
241
246
|
code,
|
|
242
247
|
message,
|
|
243
|
-
metadata: bufferToArrayBuffer(
|
|
248
|
+
metadata: bufferToArrayBuffer(
|
|
249
|
+
cbor.encode(metadata),
|
|
250
|
+
),
|
|
244
251
|
actionId: actionId ?? null,
|
|
245
252
|
},
|
|
246
253
|
},
|
|
@@ -114,7 +114,9 @@ export async function handleWebSocketConnect(
|
|
|
114
114
|
connId?: string,
|
|
115
115
|
connToken?: string,
|
|
116
116
|
): Promise<UpgradeWebSocketArgs> {
|
|
117
|
-
const exposeInternalError = req
|
|
117
|
+
const exposeInternalError = req
|
|
118
|
+
? getRequestExposeInternalError(req)
|
|
119
|
+
: false;
|
|
118
120
|
|
|
119
121
|
// Setup promise for the init handlers since all other behavior depends on this
|
|
120
122
|
const {
|
|
@@ -218,20 +220,23 @@ export async function handleWebSocketConnect(
|
|
|
218
220
|
const value = evt.data.valueOf() as InputData;
|
|
219
221
|
parseMessage(value, {
|
|
220
222
|
encoding: encoding,
|
|
221
|
-
maxIncomingMessageSize:
|
|
223
|
+
maxIncomingMessageSize:
|
|
224
|
+
runConfig.maxIncomingMessageSize,
|
|
222
225
|
})
|
|
223
226
|
.then((message) => {
|
|
224
|
-
actor
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
227
|
+
actor
|
|
228
|
+
.processMessage(message, conn)
|
|
229
|
+
.catch((error) => {
|
|
230
|
+
const { code } = deconstructError(
|
|
231
|
+
error,
|
|
232
|
+
actor.rLog,
|
|
233
|
+
{
|
|
234
|
+
wsEvent: "message",
|
|
235
|
+
},
|
|
236
|
+
exposeInternalError,
|
|
237
|
+
);
|
|
238
|
+
ws.close(1011, code);
|
|
239
|
+
});
|
|
235
240
|
})
|
|
236
241
|
.catch((error) => {
|
|
237
242
|
const { code } = deconstructError(
|
|
@@ -419,7 +424,10 @@ export async function handleSseConnect(
|
|
|
419
424
|
await stream.sleep(SSE_PING_INTERVAL);
|
|
420
425
|
}
|
|
421
426
|
} catch (error) {
|
|
422
|
-
loggerWithoutContext().error({
|
|
427
|
+
loggerWithoutContext().error({
|
|
428
|
+
msg: "error in sse connection",
|
|
429
|
+
error,
|
|
430
|
+
});
|
|
423
431
|
|
|
424
432
|
// Cleanup on error
|
|
425
433
|
if (conn && actor !== undefined) {
|
|
@@ -597,9 +605,11 @@ export async function handleRawWebSocketHandler(
|
|
|
597
605
|
// Extract the path after prefix and preserve query parameters
|
|
598
606
|
// Use URL API for cleaner parsing
|
|
599
607
|
const url = new URL(path, "http://actor");
|
|
600
|
-
const pathname =
|
|
608
|
+
const pathname =
|
|
609
|
+
url.pathname.replace(/^\/raw\/websocket\/?/, "") || "/";
|
|
601
610
|
const normalizedPath =
|
|
602
|
-
(pathname.startsWith("/") ? pathname : "/" + pathname) +
|
|
611
|
+
(pathname.startsWith("/") ? pathname : "/" + pathname) +
|
|
612
|
+
url.search;
|
|
603
613
|
|
|
604
614
|
let newRequest: Request;
|
|
605
615
|
if (req) {
|