rivetkit 2.0.24-rc.1 → 2.0.24
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/schemas/actor-persist/v2.ts +3 -3
- package/dist/schemas/actor-persist/v3.ts +274 -0
- package/dist/schemas/client-protocol/v2.ts +432 -0
- package/dist/schemas/file-system-driver/v2.ts +136 -0
- package/dist/tsup/actor/errors.cjs +2 -4
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +7 -10
- package/dist/tsup/actor/errors.d.ts +7 -10
- package/dist/tsup/actor/errors.js +9 -11
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.cts → actor-router-consts-DzI2szci.d.cts} +5 -9
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.ts → actor-router-consts-DzI2szci.d.ts} +5 -9
- package/dist/tsup/{chunk-HHFKKVLR.cjs → chunk-3543NCSN.cjs} +45 -57
- package/dist/tsup/chunk-3543NCSN.cjs.map +1 -0
- package/dist/tsup/chunk-4SHILYS5.cjs +5694 -0
- package/dist/tsup/chunk-4SHILYS5.cjs.map +1 -0
- package/dist/tsup/{chunk-ZTH3KYFH.cjs → chunk-5BZO5XPS.cjs} +3 -3
- package/dist/tsup/{chunk-ZTH3KYFH.cjs.map → chunk-5BZO5XPS.cjs.map} +1 -1
- package/dist/tsup/{chunk-PLUN2NQT.js → chunk-BAIGSF64.js} +189 -187
- package/dist/tsup/chunk-BAIGSF64.js.map +1 -0
- package/dist/tsup/{chunk-SHVX2QUR.cjs → chunk-CHLZBSI2.cjs} +17 -17
- package/dist/tsup/chunk-CHLZBSI2.cjs.map +1 -0
- package/dist/tsup/chunk-D3SLADUD.cjs +512 -0
- package/dist/tsup/chunk-D3SLADUD.cjs.map +1 -0
- package/dist/tsup/{chunk-KSRXX3Z4.cjs → chunk-D6762AOA.cjs} +20 -25
- package/dist/tsup/chunk-D6762AOA.cjs.map +1 -0
- package/dist/tsup/{chunk-7L65NNWP.cjs → chunk-DLK5YCTN.cjs} +187 -185
- package/dist/tsup/chunk-DLK5YCTN.cjs.map +1 -0
- package/dist/tsup/{chunk-YBG6R7LX.js → chunk-DUJQWGYD.js} +3 -7
- package/dist/tsup/chunk-DUJQWGYD.js.map +1 -0
- package/dist/tsup/{chunk-CD33GT6Z.js → chunk-EIPANQMF.js} +2 -2
- package/dist/tsup/{chunk-2JYPS5YM.cjs → chunk-ESMTDP7G.cjs} +6 -6
- package/dist/tsup/chunk-ESMTDP7G.cjs.map +1 -0
- package/dist/tsup/{chunk-VHGY7PU5.cjs → chunk-FVAKREFB.cjs} +1900 -1737
- package/dist/tsup/chunk-FVAKREFB.cjs.map +1 -0
- package/dist/tsup/{chunk-BLK27ES3.js → chunk-I3XT7WOF.js} +44 -56
- package/dist/tsup/chunk-I3XT7WOF.js.map +1 -0
- package/dist/tsup/{chunk-YBHYXIP6.js → chunk-IMDS5T42.js} +3 -3
- package/dist/tsup/chunk-IMDS5T42.js.map +1 -0
- package/dist/tsup/{chunk-INNFK746.cjs → chunk-J3HZJF2P.cjs} +10 -14
- package/dist/tsup/chunk-J3HZJF2P.cjs.map +1 -0
- package/dist/tsup/{chunk-BYMKMOBS.js → chunk-MBBJUHSP.js} +1844 -1681
- package/dist/tsup/chunk-MBBJUHSP.js.map +1 -0
- package/dist/tsup/{chunk-BOMZS2TJ.js → chunk-MO5CB6MD.js} +9 -9
- package/dist/tsup/chunk-MO5CB6MD.js.map +1 -0
- package/dist/tsup/chunk-OFOTPKAH.js +512 -0
- package/dist/tsup/chunk-OFOTPKAH.js.map +1 -0
- package/dist/tsup/{chunk-G64QUEDJ.js → chunk-W6RDS6NW.js} +23 -28
- package/dist/tsup/chunk-W6RDS6NW.js.map +1 -0
- package/dist/tsup/{chunk-36JJ4IQB.cjs → chunk-YC5DUHPM.cjs} +4 -8
- package/dist/tsup/chunk-YC5DUHPM.cjs.map +1 -0
- package/dist/tsup/{chunk-FX7TWFQR.js → chunk-YC7YPM2T.js} +2 -6
- package/dist/tsup/chunk-YC7YPM2T.js.map +1 -0
- package/dist/tsup/{chunk-227FEWMB.js → chunk-ZSPU5R4C.js} +3322 -2251
- package/dist/tsup/chunk-ZSPU5R4C.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +5 -7
- package/dist/tsup/client/mod.d.ts +5 -7
- package/dist/tsup/client/mod.js +8 -8
- 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/{conn-B3Vhbgnd.d.ts → config-BRDYDraU.d.cts} +1119 -1047
- package/dist/tsup/{conn-DJWL3nGx.d.cts → config-Bo-blHpJ.d.ts} +1119 -1047
- package/dist/tsup/driver-helpers/mod.cjs +5 -13
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +11 -9
- package/dist/tsup/driver-helpers/mod.d.ts +11 -9
- package/dist/tsup/driver-helpers/mod.js +14 -22
- package/dist/tsup/driver-test-suite/mod.cjs +474 -303
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +6 -9
- package/dist/tsup/driver-test-suite/mod.d.ts +6 -9
- package/dist/tsup/driver-test-suite/mod.js +1085 -914
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.d.cts +5 -7
- package/dist/tsup/inspector/mod.d.ts +5 -7
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +10 -16
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +23 -25
- package/dist/tsup/mod.d.ts +23 -25
- package/dist/tsup/mod.js +17 -23
- package/dist/tsup/test/mod.cjs +11 -11
- package/dist/tsup/test/mod.d.cts +4 -6
- package/dist/tsup/test/mod.d.ts +4 -6
- package/dist/tsup/test/mod.js +10 -10
- package/dist/tsup/utils.cjs +3 -5
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +1 -2
- package/dist/tsup/utils.d.ts +1 -2
- package/dist/tsup/utils.js +2 -4
- package/package.json +13 -6
- package/src/actor/config.ts +56 -44
- package/src/actor/conn/driver.ts +61 -0
- package/src/actor/conn/drivers/http.ts +17 -0
- package/src/actor/conn/drivers/raw-request.ts +24 -0
- package/src/actor/conn/drivers/raw-websocket.ts +65 -0
- package/src/actor/conn/drivers/websocket.ts +129 -0
- package/src/actor/conn/mod.ts +232 -0
- package/src/actor/conn/persisted.ts +81 -0
- package/src/actor/conn/state-manager.ts +196 -0
- package/src/actor/contexts/action.ts +23 -0
- package/src/actor/{context.ts → contexts/actor.ts} +19 -8
- package/src/actor/contexts/conn-init.ts +31 -0
- package/src/actor/contexts/conn.ts +48 -0
- package/src/actor/contexts/create-conn-state.ts +13 -0
- package/src/actor/contexts/on-before-connect.ts +13 -0
- package/src/actor/contexts/on-connect.ts +22 -0
- package/src/actor/contexts/request.ts +48 -0
- package/src/actor/contexts/websocket.ts +48 -0
- package/src/actor/definition.ts +3 -3
- package/src/actor/driver.ts +36 -5
- package/src/actor/errors.ts +19 -24
- package/src/actor/instance/connection-manager.ts +465 -0
- package/src/actor/instance/event-manager.ts +292 -0
- package/src/actor/instance/kv.ts +15 -0
- package/src/actor/instance/mod.ts +1107 -0
- package/src/actor/instance/persisted.ts +67 -0
- package/src/actor/instance/schedule-manager.ts +349 -0
- package/src/actor/instance/state-manager.ts +502 -0
- package/src/actor/mod.ts +13 -16
- package/src/actor/protocol/old.ts +131 -43
- package/src/actor/protocol/serde.ts +19 -4
- package/src/actor/router-endpoints.ts +61 -586
- package/src/actor/router-websocket-endpoints.ts +408 -0
- package/src/actor/router.ts +63 -197
- package/src/actor/schedule.ts +1 -1
- package/src/client/actor-conn.ts +183 -249
- package/src/client/actor-handle.ts +29 -6
- package/src/client/client.ts +0 -4
- package/src/client/config.ts +1 -4
- package/src/client/mod.ts +0 -1
- package/src/client/raw-utils.ts +3 -3
- package/src/client/utils.ts +85 -39
- package/src/common/actor-router-consts.ts +5 -12
- package/src/common/{inline-websocket-adapter2.ts → inline-websocket-adapter.ts} +26 -48
- package/src/common/log.ts +1 -1
- package/src/common/router.ts +28 -17
- package/src/common/utils.ts +2 -0
- package/src/driver-helpers/mod.ts +7 -10
- package/src/driver-helpers/utils.ts +18 -9
- package/src/driver-test-suite/mod.ts +26 -50
- package/src/driver-test-suite/test-inline-client-driver.ts +27 -51
- package/src/driver-test-suite/tests/actor-conn-hibernation.ts +150 -0
- package/src/driver-test-suite/tests/actor-conn-state.ts +1 -4
- package/src/driver-test-suite/tests/actor-conn.ts +5 -9
- package/src/driver-test-suite/tests/actor-destroy.ts +294 -0
- package/src/driver-test-suite/tests/actor-driver.ts +0 -7
- package/src/driver-test-suite/tests/actor-handle.ts +12 -12
- package/src/driver-test-suite/tests/actor-metadata.ts +1 -1
- package/src/driver-test-suite/tests/manager-driver.ts +1 -1
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +8 -8
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +6 -5
- package/src/driver-test-suite/tests/raw-http.ts +5 -5
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +7 -7
- package/src/driver-test-suite/tests/request-access.ts +4 -4
- package/src/driver-test-suite/utils.ts +6 -10
- package/src/drivers/engine/actor-driver.ts +614 -424
- package/src/drivers/engine/mod.ts +0 -1
- package/src/drivers/file-system/actor.ts +24 -12
- package/src/drivers/file-system/global-state.ts +427 -37
- package/src/drivers/file-system/manager.ts +71 -83
- package/src/drivers/file-system/mod.ts +3 -0
- package/src/drivers/file-system/utils.ts +18 -8
- package/src/engine-process/mod.ts +38 -38
- package/src/inspector/utils.ts +7 -5
- package/src/manager/driver.ts +11 -4
- package/src/manager/gateway.ts +4 -29
- package/src/manager/protocol/mod.ts +0 -2
- package/src/manager/protocol/query.ts +0 -4
- package/src/manager/router.ts +67 -64
- package/src/manager-api/actors.ts +13 -0
- package/src/mod.ts +1 -3
- package/src/registry/mod.ts +20 -20
- package/src/registry/serve.ts +9 -14
- package/src/remote-manager-driver/actor-websocket-client.ts +1 -16
- package/src/remote-manager-driver/api-endpoints.ts +13 -1
- package/src/remote-manager-driver/api-utils.ts +8 -0
- package/src/remote-manager-driver/metadata.ts +58 -0
- package/src/remote-manager-driver/mod.ts +47 -62
- package/src/remote-manager-driver/ws-proxy.ts +1 -1
- package/src/schemas/actor-persist/mod.ts +1 -1
- package/src/schemas/actor-persist/versioned.ts +56 -31
- package/src/schemas/client-protocol/mod.ts +1 -1
- package/src/schemas/client-protocol/versioned.ts +41 -21
- package/src/schemas/client-protocol-zod/mod.ts +103 -0
- package/src/schemas/file-system-driver/mod.ts +1 -1
- package/src/schemas/file-system-driver/versioned.ts +42 -19
- package/src/serde.ts +33 -11
- package/src/test/mod.ts +7 -3
- package/src/utils/node.ts +173 -0
- package/src/utils.ts +0 -4
- package/dist/tsup/chunk-227FEWMB.js.map +0 -1
- package/dist/tsup/chunk-2JYPS5YM.cjs.map +0 -1
- package/dist/tsup/chunk-36JJ4IQB.cjs.map +0 -1
- package/dist/tsup/chunk-7L65NNWP.cjs.map +0 -1
- package/dist/tsup/chunk-BLK27ES3.js.map +0 -1
- package/dist/tsup/chunk-BOMZS2TJ.js.map +0 -1
- package/dist/tsup/chunk-BYMKMOBS.js.map +0 -1
- package/dist/tsup/chunk-FX7TWFQR.js.map +0 -1
- package/dist/tsup/chunk-G64QUEDJ.js.map +0 -1
- package/dist/tsup/chunk-HHFKKVLR.cjs.map +0 -1
- package/dist/tsup/chunk-INNFK746.cjs.map +0 -1
- package/dist/tsup/chunk-KSRXX3Z4.cjs.map +0 -1
- package/dist/tsup/chunk-O44LFKSB.cjs +0 -4623
- package/dist/tsup/chunk-O44LFKSB.cjs.map +0 -1
- package/dist/tsup/chunk-PLUN2NQT.js.map +0 -1
- package/dist/tsup/chunk-S4UJG7ZE.js +0 -1119
- package/dist/tsup/chunk-S4UJG7ZE.js.map +0 -1
- package/dist/tsup/chunk-SHVX2QUR.cjs.map +0 -1
- package/dist/tsup/chunk-VFB23BYZ.cjs +0 -1119
- package/dist/tsup/chunk-VFB23BYZ.cjs.map +0 -1
- package/dist/tsup/chunk-VHGY7PU5.cjs.map +0 -1
- package/dist/tsup/chunk-YBG6R7LX.js.map +0 -1
- package/dist/tsup/chunk-YBHYXIP6.js.map +0 -1
- package/src/actor/action.ts +0 -178
- package/src/actor/conn-drivers.ts +0 -216
- package/src/actor/conn-socket.ts +0 -8
- package/src/actor/conn.ts +0 -272
- package/src/actor/instance.ts +0 -2336
- package/src/actor/persisted.ts +0 -49
- package/src/actor/unstable-react.ts +0 -110
- package/src/driver-test-suite/tests/actor-reconnect.ts +0 -170
- package/src/drivers/engine/kv.ts +0 -3
- package/src/manager/hono-websocket-adapter.ts +0 -393
- /package/dist/tsup/{chunk-CD33GT6Z.js.map → chunk-EIPANQMF.js.map} +0 -0
package/src/client/actor-conn.ts
CHANGED
|
@@ -6,11 +6,9 @@ import type { AnyActorDefinition } from "@/actor/definition";
|
|
|
6
6
|
import { inputDataToBuffer } from "@/actor/protocol/old";
|
|
7
7
|
import { type Encoding, jsonStringifyCompat } from "@/actor/protocol/serde";
|
|
8
8
|
import {
|
|
9
|
-
HEADER_CONN_ID,
|
|
10
9
|
HEADER_CONN_PARAMS,
|
|
11
|
-
HEADER_CONN_TOKEN,
|
|
12
10
|
HEADER_ENCODING,
|
|
13
|
-
|
|
11
|
+
PATH_CONNECT,
|
|
14
12
|
} from "@/common/actor-router-consts";
|
|
15
13
|
import { importEventSource } from "@/common/eventsource";
|
|
16
14
|
import type {
|
|
@@ -27,6 +25,12 @@ import {
|
|
|
27
25
|
TO_CLIENT_VERSIONED,
|
|
28
26
|
TO_SERVER_VERSIONED,
|
|
29
27
|
} from "@/schemas/client-protocol/versioned";
|
|
28
|
+
import {
|
|
29
|
+
type ToClient as ToClientJson,
|
|
30
|
+
ToClientSchema,
|
|
31
|
+
type ToServer as ToServerJson,
|
|
32
|
+
ToServerSchema,
|
|
33
|
+
} from "@/schemas/client-protocol-zod/mod";
|
|
30
34
|
import {
|
|
31
35
|
deserializeWithEncoding,
|
|
32
36
|
encodingIsBinary,
|
|
@@ -40,7 +44,7 @@ import {
|
|
|
40
44
|
} from "@/utils";
|
|
41
45
|
import type { ActorDefinitionActions } from "./actor-common";
|
|
42
46
|
import { queryActor } from "./actor-query";
|
|
43
|
-
import { ACTOR_CONNS_SYMBOL, type ClientRaw
|
|
47
|
+
import { ACTOR_CONNS_SYMBOL, type ClientRaw } from "./client";
|
|
44
48
|
import * as errors from "./errors";
|
|
45
49
|
import { logger } from "./log";
|
|
46
50
|
import {
|
|
@@ -51,7 +55,7 @@ import {
|
|
|
51
55
|
|
|
52
56
|
interface ActionInFlight {
|
|
53
57
|
name: string;
|
|
54
|
-
resolve: (response:
|
|
58
|
+
resolve: (response: { id: bigint; output: unknown }) => void;
|
|
55
59
|
reject: (error: Error) => void;
|
|
56
60
|
}
|
|
57
61
|
|
|
@@ -79,10 +83,6 @@ export interface SendHttpMessageOpts {
|
|
|
79
83
|
signal?: AbortSignal;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
export type ConnTransport =
|
|
83
|
-
| { websocket: UniversalWebSocket }
|
|
84
|
-
| { sse: UniversalEventSource };
|
|
85
|
-
|
|
86
86
|
export const CONNECT_SYMBOL = Symbol("connect");
|
|
87
87
|
|
|
88
88
|
/**
|
|
@@ -96,17 +96,22 @@ export class ActorConnRaw {
|
|
|
96
96
|
/* Will be aborted on dispose. */
|
|
97
97
|
#abortController = new AbortController();
|
|
98
98
|
|
|
99
|
-
/** If attempting to connect. Helpful for knowing if in a retry loop when reconnecting. */
|
|
100
99
|
#connecting = false;
|
|
101
100
|
|
|
102
|
-
// Connection info, used for reconnection and HTTP requests
|
|
103
101
|
#actorId?: string;
|
|
104
102
|
#connectionId?: string;
|
|
105
|
-
#connectionToken?: string;
|
|
106
|
-
|
|
107
|
-
#transport?: ConnTransport;
|
|
108
103
|
|
|
109
|
-
#messageQueue:
|
|
104
|
+
#messageQueue: Array<{
|
|
105
|
+
body:
|
|
106
|
+
| {
|
|
107
|
+
tag: "ActionRequest";
|
|
108
|
+
val: { id: bigint; name: string; args: unknown };
|
|
109
|
+
}
|
|
110
|
+
| {
|
|
111
|
+
tag: "SubscriptionRequest";
|
|
112
|
+
val: { eventName: string; subscribe: boolean };
|
|
113
|
+
};
|
|
114
|
+
}> = [];
|
|
110
115
|
#actionsInFlight = new Map<number, ActionInFlight>();
|
|
111
116
|
|
|
112
117
|
// biome-ignore lint/suspicious/noExplicitAny: Unknown subscription type
|
|
@@ -126,6 +131,8 @@ export class ActorConnRaw {
|
|
|
126
131
|
/** Promise used to indicate the socket has connected successfully. This will be rejected if the connection fails. */
|
|
127
132
|
#onOpenPromise?: ReturnType<typeof promiseWithResolvers<undefined>>;
|
|
128
133
|
|
|
134
|
+
#websocket?: UniversalWebSocket;
|
|
135
|
+
|
|
129
136
|
#client: ClientRaw;
|
|
130
137
|
#driver: ManagerDriver;
|
|
131
138
|
#params: unknown;
|
|
@@ -181,13 +188,21 @@ export class ActorConnRaw {
|
|
|
181
188
|
const actionId = this.#actionIdCounter;
|
|
182
189
|
this.#actionIdCounter += 1;
|
|
183
190
|
|
|
184
|
-
const { promise, resolve, reject } =
|
|
185
|
-
|
|
191
|
+
const { promise, resolve, reject } = promiseWithResolvers<{
|
|
192
|
+
id: bigint;
|
|
193
|
+
output: unknown;
|
|
194
|
+
}>();
|
|
186
195
|
this.#actionsInFlight.set(actionId, {
|
|
187
196
|
name: opts.name,
|
|
188
197
|
resolve,
|
|
189
198
|
reject,
|
|
190
199
|
});
|
|
200
|
+
logger().debug({
|
|
201
|
+
msg: "added action to in-flight map",
|
|
202
|
+
actionId,
|
|
203
|
+
actionName: opts.name,
|
|
204
|
+
inFlightCount: this.#actionsInFlight.size,
|
|
205
|
+
});
|
|
191
206
|
|
|
192
207
|
this.#sendMessage({
|
|
193
208
|
body: {
|
|
@@ -195,10 +210,10 @@ export class ActorConnRaw {
|
|
|
195
210
|
val: {
|
|
196
211
|
id: BigInt(actionId),
|
|
197
212
|
name: opts.name,
|
|
198
|
-
args:
|
|
213
|
+
args: opts.args,
|
|
199
214
|
},
|
|
200
215
|
},
|
|
201
|
-
}
|
|
216
|
+
});
|
|
202
217
|
|
|
203
218
|
// TODO: Throw error if disconnect is called
|
|
204
219
|
|
|
@@ -208,7 +223,7 @@ export class ActorConnRaw {
|
|
|
208
223
|
`Request ID ${actionId} does not match response ID ${responseId}`,
|
|
209
224
|
);
|
|
210
225
|
|
|
211
|
-
return
|
|
226
|
+
return output as Response;
|
|
212
227
|
}
|
|
213
228
|
|
|
214
229
|
/**
|
|
@@ -264,14 +279,7 @@ enc
|
|
|
264
279
|
throw new Error("#onOpenPromise already defined");
|
|
265
280
|
this.#onOpenPromise = promiseWithResolvers();
|
|
266
281
|
|
|
267
|
-
|
|
268
|
-
if (this.#client[TRANSPORT_SYMBOL] === "websocket") {
|
|
269
|
-
await this.#connectWebSocket();
|
|
270
|
-
} else if (this.#client[TRANSPORT_SYMBOL] === "sse") {
|
|
271
|
-
await this.#connectSse();
|
|
272
|
-
} else {
|
|
273
|
-
assertUnreachable(this.#client[TRANSPORT_SYMBOL]);
|
|
274
|
-
}
|
|
282
|
+
await this.#connectWebSocket();
|
|
275
283
|
|
|
276
284
|
// Wait for result
|
|
277
285
|
await this.#onOpenPromise.promise;
|
|
@@ -287,31 +295,19 @@ enc
|
|
|
287
295
|
this.#driver,
|
|
288
296
|
);
|
|
289
297
|
|
|
290
|
-
// Check if we have connection info for reconnection
|
|
291
|
-
const isReconnection = this.#connectionId && this.#connectionToken;
|
|
292
|
-
if (isReconnection) {
|
|
293
|
-
logger().debug({
|
|
294
|
-
msg: "attempting websocket reconnection",
|
|
295
|
-
connectionId: this.#connectionId,
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
|
|
299
298
|
const ws = await this.#driver.openWebSocket(
|
|
300
|
-
|
|
299
|
+
PATH_CONNECT,
|
|
301
300
|
actorId,
|
|
302
301
|
this.#encoding,
|
|
303
302
|
this.#params,
|
|
304
|
-
// Pass connection ID and token for reconnection if available
|
|
305
|
-
isReconnection ? this.#connectionId : undefined,
|
|
306
|
-
isReconnection ? this.#connectionToken : undefined,
|
|
307
303
|
);
|
|
308
304
|
logger().debug({
|
|
309
|
-
msg: "
|
|
305
|
+
msg: "opened websocket",
|
|
310
306
|
connectionId: this.#connectionId,
|
|
311
307
|
readyState: ws.readyState,
|
|
312
308
|
messageQueueLength: this.#messageQueue.length,
|
|
313
309
|
});
|
|
314
|
-
this.#
|
|
310
|
+
this.#websocket = ws;
|
|
315
311
|
ws.addEventListener("open", () => {
|
|
316
312
|
logger().debug({
|
|
317
313
|
msg: "client websocket open",
|
|
@@ -350,70 +346,6 @@ enc
|
|
|
350
346
|
});
|
|
351
347
|
}
|
|
352
348
|
|
|
353
|
-
async #connectSse() {
|
|
354
|
-
const EventSource = await importEventSource();
|
|
355
|
-
|
|
356
|
-
// Get the actor ID
|
|
357
|
-
const { actorId } = await queryActor(
|
|
358
|
-
undefined,
|
|
359
|
-
this.#actorQuery,
|
|
360
|
-
this.#driver,
|
|
361
|
-
);
|
|
362
|
-
logger().debug({ msg: "found actor for sse connection", actorId });
|
|
363
|
-
invariant(actorId, "Missing actor ID");
|
|
364
|
-
|
|
365
|
-
logger().debug({
|
|
366
|
-
msg: "opening sse connection",
|
|
367
|
-
actorId,
|
|
368
|
-
encoding: this.#encoding,
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
const isReconnection = this.#connectionId && this.#connectionToken;
|
|
372
|
-
|
|
373
|
-
const eventSource = new EventSource("http://actor/connect/sse", {
|
|
374
|
-
fetch: (input, init) => {
|
|
375
|
-
return this.#driver.sendRequest(
|
|
376
|
-
actorId,
|
|
377
|
-
new Request(input, {
|
|
378
|
-
...init,
|
|
379
|
-
headers: {
|
|
380
|
-
...init?.headers,
|
|
381
|
-
"User-Agent": httpUserAgent(),
|
|
382
|
-
[HEADER_ENCODING]: this.#encoding,
|
|
383
|
-
...(this.#params !== undefined
|
|
384
|
-
? {
|
|
385
|
-
[HEADER_CONN_PARAMS]: JSON.stringify(
|
|
386
|
-
this.#params,
|
|
387
|
-
),
|
|
388
|
-
}
|
|
389
|
-
: {}),
|
|
390
|
-
...(isReconnection
|
|
391
|
-
? {
|
|
392
|
-
[HEADER_CONN_ID]: this.#connectionId,
|
|
393
|
-
[HEADER_CONN_TOKEN]:
|
|
394
|
-
this.#connectionToken,
|
|
395
|
-
}
|
|
396
|
-
: {}),
|
|
397
|
-
},
|
|
398
|
-
}),
|
|
399
|
-
);
|
|
400
|
-
},
|
|
401
|
-
}) as UniversalEventSource;
|
|
402
|
-
|
|
403
|
-
this.#transport = { sse: eventSource };
|
|
404
|
-
|
|
405
|
-
eventSource.addEventListener("message", (ev: UniversalMessageEvent) => {
|
|
406
|
-
// Ignore pings
|
|
407
|
-
if (ev.type === "ping") return;
|
|
408
|
-
|
|
409
|
-
this.#handleOnMessage(ev.data);
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
eventSource.addEventListener("error", (ev: UniversalErrorEvent) => {
|
|
413
|
-
this.#handleOnError();
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
|
|
417
349
|
/** Called by the onopen event from drivers. */
|
|
418
350
|
#handleOnOpen() {
|
|
419
351
|
logger().debug({
|
|
@@ -470,10 +402,9 @@ enc
|
|
|
470
402
|
);
|
|
471
403
|
|
|
472
404
|
if (response.body.tag === "Init") {
|
|
473
|
-
// Store connection info
|
|
405
|
+
// Store connection info
|
|
474
406
|
this.#actorId = response.body.val.actorId;
|
|
475
407
|
this.#connectionId = response.body.val.connectionId;
|
|
476
|
-
this.#connectionToken = response.body.val.connectionToken;
|
|
477
408
|
logger().trace({
|
|
478
409
|
msg: "received init message",
|
|
479
410
|
actorId: this.#actorId,
|
|
@@ -535,9 +466,11 @@ enc
|
|
|
535
466
|
} else if (response.body.tag === "ActionResponse") {
|
|
536
467
|
// Action response OK
|
|
537
468
|
const { id: actionId } = response.body.val;
|
|
538
|
-
logger().
|
|
469
|
+
logger().debug({
|
|
539
470
|
msg: "received action response",
|
|
540
|
-
actionId,
|
|
471
|
+
actionId: Number(actionId),
|
|
472
|
+
inFlightCount: this.#actionsInFlight.size,
|
|
473
|
+
inFlightIds: Array.from(this.#actionsInFlight.keys()),
|
|
541
474
|
});
|
|
542
475
|
|
|
543
476
|
const inFlight = this.#takeActionInFlight(Number(actionId));
|
|
@@ -598,7 +531,7 @@ enc
|
|
|
598
531
|
});
|
|
599
532
|
|
|
600
533
|
const disconnectError = new Error(
|
|
601
|
-
wasClean ? "Connection closed" : "Connection lost",
|
|
534
|
+
`${wasClean ? "Connection closed" : "Connection lost"} (code: ${closeEvent.code}, reason: ${closeEvent.reason})`,
|
|
602
535
|
);
|
|
603
536
|
|
|
604
537
|
for (const actionInfo of this.#actionsInFlight.values()) {
|
|
@@ -607,7 +540,7 @@ enc
|
|
|
607
540
|
this.#actionsInFlight.clear();
|
|
608
541
|
}
|
|
609
542
|
|
|
610
|
-
this.#
|
|
543
|
+
this.#websocket = undefined;
|
|
611
544
|
|
|
612
545
|
// Automatically reconnect. Skip if already attempting to connect.
|
|
613
546
|
if (!this.#disposed && !this.#connecting) {
|
|
@@ -636,22 +569,39 @@ enc
|
|
|
636
569
|
#takeActionInFlight(id: number): ActionInFlight {
|
|
637
570
|
const inFlight = this.#actionsInFlight.get(id);
|
|
638
571
|
if (!inFlight) {
|
|
572
|
+
logger().error({
|
|
573
|
+
msg: "action not found in in-flight map",
|
|
574
|
+
lookupId: id,
|
|
575
|
+
inFlightCount: this.#actionsInFlight.size,
|
|
576
|
+
inFlightIds: Array.from(this.#actionsInFlight.keys()),
|
|
577
|
+
inFlightActions: Array.from(
|
|
578
|
+
this.#actionsInFlight.entries(),
|
|
579
|
+
).map(([id, action]) => ({
|
|
580
|
+
id,
|
|
581
|
+
name: action.name,
|
|
582
|
+
})),
|
|
583
|
+
});
|
|
639
584
|
throw new errors.InternalError(`No in flight response for ${id}`);
|
|
640
585
|
}
|
|
641
586
|
this.#actionsInFlight.delete(id);
|
|
587
|
+
logger().debug({
|
|
588
|
+
msg: "removed action from in-flight map",
|
|
589
|
+
actionId: id,
|
|
590
|
+
actionName: inFlight.name,
|
|
591
|
+
inFlightCount: this.#actionsInFlight.size,
|
|
592
|
+
});
|
|
642
593
|
return inFlight;
|
|
643
594
|
}
|
|
644
595
|
|
|
645
|
-
#dispatchEvent(event:
|
|
646
|
-
const { name, args
|
|
647
|
-
const args = cbor.decode(new Uint8Array(argsRaw));
|
|
596
|
+
#dispatchEvent(event: { name: string; args: unknown }) {
|
|
597
|
+
const { name, args } = event;
|
|
648
598
|
|
|
649
599
|
const listeners = this.#eventSubscriptions.get(name);
|
|
650
600
|
if (!listeners) return;
|
|
651
601
|
|
|
652
602
|
// Create a new array to avoid issues with listeners being removed during iteration
|
|
653
603
|
for (const listener of [...listeners]) {
|
|
654
|
-
listener.callback(...args);
|
|
604
|
+
listener.callback(...(args as unknown[]));
|
|
655
605
|
|
|
656
606
|
// Remove if this was a one-time listener
|
|
657
607
|
if (listener.once) {
|
|
@@ -757,18 +707,27 @@ enc
|
|
|
757
707
|
};
|
|
758
708
|
}
|
|
759
709
|
|
|
760
|
-
#sendMessage(
|
|
710
|
+
#sendMessage(
|
|
711
|
+
message: {
|
|
712
|
+
body:
|
|
713
|
+
| {
|
|
714
|
+
tag: "ActionRequest";
|
|
715
|
+
val: { id: bigint; name: string; args: unknown };
|
|
716
|
+
}
|
|
717
|
+
| {
|
|
718
|
+
tag: "SubscriptionRequest";
|
|
719
|
+
val: { eventName: string; subscribe: boolean };
|
|
720
|
+
};
|
|
721
|
+
},
|
|
722
|
+
opts?: SendHttpMessageOpts,
|
|
723
|
+
) {
|
|
761
724
|
if (this.#disposed) {
|
|
762
725
|
throw new errors.ActorConnDisposed();
|
|
763
726
|
}
|
|
764
727
|
|
|
765
728
|
let queueMessage = false;
|
|
766
|
-
if (
|
|
767
|
-
|
|
768
|
-
logger().debug({ msg: "no transport, queueing message" });
|
|
769
|
-
queueMessage = true;
|
|
770
|
-
} else if ("websocket" in this.#transport) {
|
|
771
|
-
const readyState = this.#transport.websocket.readyState;
|
|
729
|
+
if (this.#websocket) {
|
|
730
|
+
const readyState = this.#websocket.readyState;
|
|
772
731
|
logger().debug({
|
|
773
732
|
msg: "websocket send attempt",
|
|
774
733
|
readyState,
|
|
@@ -790,8 +749,30 @@ enc
|
|
|
790
749
|
this.#encoding,
|
|
791
750
|
message,
|
|
792
751
|
TO_SERVER_VERSIONED,
|
|
752
|
+
ToServerSchema,
|
|
753
|
+
// JSON: args is the raw value
|
|
754
|
+
(msg): ToServerJson => msg as ToServerJson,
|
|
755
|
+
// BARE: args needs to be CBOR-encoded to ArrayBuffer
|
|
756
|
+
(msg): protocol.ToServer => {
|
|
757
|
+
if (msg.body.tag === "ActionRequest") {
|
|
758
|
+
return {
|
|
759
|
+
body: {
|
|
760
|
+
tag: "ActionRequest",
|
|
761
|
+
val: {
|
|
762
|
+
id: msg.body.val.id,
|
|
763
|
+
name: msg.body.val.name,
|
|
764
|
+
args: bufferToArrayBuffer(
|
|
765
|
+
cbor.encode(msg.body.val.args),
|
|
766
|
+
),
|
|
767
|
+
},
|
|
768
|
+
},
|
|
769
|
+
};
|
|
770
|
+
} else {
|
|
771
|
+
return msg as protocol.ToServer;
|
|
772
|
+
}
|
|
773
|
+
},
|
|
793
774
|
);
|
|
794
|
-
this.#
|
|
775
|
+
this.#websocket.send(messageSerialized);
|
|
795
776
|
logger().trace({
|
|
796
777
|
msg: "sent websocket message",
|
|
797
778
|
len: messageLength(messageSerialized),
|
|
@@ -813,15 +794,10 @@ enc
|
|
|
813
794
|
});
|
|
814
795
|
queueMessage = true;
|
|
815
796
|
}
|
|
816
|
-
} else if ("sse" in this.#transport) {
|
|
817
|
-
if (this.#transport.sse.readyState === 1) {
|
|
818
|
-
// Spawn in background since #sendMessage cannot be async
|
|
819
|
-
this.#sendHttpMessage(message, opts);
|
|
820
|
-
} else {
|
|
821
|
-
queueMessage = true;
|
|
822
|
-
}
|
|
823
797
|
} else {
|
|
824
|
-
|
|
798
|
+
// No websocket connected yet
|
|
799
|
+
logger().debug({ msg: "no websocket, queueing message" });
|
|
800
|
+
queueMessage = true;
|
|
825
801
|
}
|
|
826
802
|
|
|
827
803
|
if (!opts?.ephemeral && queueMessage) {
|
|
@@ -836,83 +812,23 @@ enc
|
|
|
836
812
|
}
|
|
837
813
|
}
|
|
838
814
|
|
|
839
|
-
async #
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
);
|
|
857
|
-
|
|
858
|
-
logger().debug({
|
|
859
|
-
msg: "sending http message",
|
|
860
|
-
actorId: this.#actorId,
|
|
861
|
-
connectionId: this.#connectionId,
|
|
862
|
-
});
|
|
863
|
-
|
|
864
|
-
// Send an HTTP request to the connections endpoint
|
|
865
|
-
await sendHttpRequest({
|
|
866
|
-
url: "http://actor/connections/message",
|
|
867
|
-
method: "POST",
|
|
868
|
-
headers: {
|
|
869
|
-
[HEADER_ENCODING]: this.#encoding,
|
|
870
|
-
[HEADER_CONN_ID]: this.#connectionId,
|
|
871
|
-
[HEADER_CONN_TOKEN]: this.#connectionToken,
|
|
872
|
-
},
|
|
873
|
-
body: message,
|
|
874
|
-
encoding: this.#encoding,
|
|
875
|
-
skipParseResponse: true,
|
|
876
|
-
customFetch: this.#driver.sendRequest.bind(
|
|
877
|
-
this.#driver,
|
|
878
|
-
this.#actorId,
|
|
879
|
-
),
|
|
880
|
-
requestVersionedDataHandler: TO_SERVER_VERSIONED,
|
|
881
|
-
responseVersionedDataHandler: TO_CLIENT_VERSIONED,
|
|
882
|
-
});
|
|
883
|
-
} catch (error) {
|
|
884
|
-
// TODO: This will not automatically trigger a re-broadcast of HTTP events since SSE is separate from the HTTP action
|
|
885
|
-
|
|
886
|
-
logger().warn({
|
|
887
|
-
msg: "failed to send message, added to queue",
|
|
888
|
-
error,
|
|
889
|
-
});
|
|
890
|
-
|
|
891
|
-
// Assuming the socket is disconnected and will be reconnected soon
|
|
892
|
-
//
|
|
893
|
-
// Will attempt to resend soon
|
|
894
|
-
if (!opts?.ephemeral) {
|
|
895
|
-
this.#messageQueue.unshift(message);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
async #parseMessage(data: ConnMessage): Promise<protocol.ToClient> {
|
|
901
|
-
invariant(this.#transport, "transport must be defined");
|
|
902
|
-
|
|
903
|
-
// Decode base64 since SSE sends raw strings
|
|
904
|
-
if (encodingIsBinary(this.#encoding) && "sse" in this.#transport) {
|
|
905
|
-
if (typeof data === "string") {
|
|
906
|
-
const binaryString = atob(data);
|
|
907
|
-
data = new Uint8Array(
|
|
908
|
-
[...binaryString].map((char) => char.charCodeAt(0)),
|
|
909
|
-
);
|
|
910
|
-
} else {
|
|
911
|
-
throw new errors.InternalError(
|
|
912
|
-
`Expected data to be a string for SSE, got ${data}.`,
|
|
913
|
-
);
|
|
914
|
-
}
|
|
915
|
-
}
|
|
815
|
+
async #parseMessage(data: ConnMessage): Promise<{
|
|
816
|
+
body:
|
|
817
|
+
| { tag: "Init"; val: { actorId: string; connectionId: string } }
|
|
818
|
+
| {
|
|
819
|
+
tag: "Error";
|
|
820
|
+
val: {
|
|
821
|
+
group: string;
|
|
822
|
+
code: string;
|
|
823
|
+
message: string;
|
|
824
|
+
metadata: unknown;
|
|
825
|
+
actionId: bigint | null;
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
| { tag: "ActionResponse"; val: { id: bigint; output: unknown } }
|
|
829
|
+
| { tag: "Event"; val: { name: string; args: unknown } };
|
|
830
|
+
}> {
|
|
831
|
+
invariant(this.#websocket, "websocket must be defined");
|
|
916
832
|
|
|
917
833
|
const buffer = await inputDataToBuffer(data);
|
|
918
834
|
|
|
@@ -920,6 +836,59 @@ enc
|
|
|
920
836
|
this.#encoding,
|
|
921
837
|
buffer,
|
|
922
838
|
TO_CLIENT_VERSIONED,
|
|
839
|
+
ToClientSchema,
|
|
840
|
+
// JSON: values are already the correct type
|
|
841
|
+
(msg): ToClientJson => msg as ToClientJson,
|
|
842
|
+
// BARE: need to decode ArrayBuffer fields back to unknown
|
|
843
|
+
(msg): any => {
|
|
844
|
+
if (msg.body.tag === "Error") {
|
|
845
|
+
return {
|
|
846
|
+
body: {
|
|
847
|
+
tag: "Error",
|
|
848
|
+
val: {
|
|
849
|
+
group: msg.body.val.group,
|
|
850
|
+
code: msg.body.val.code,
|
|
851
|
+
message: msg.body.val.message,
|
|
852
|
+
metadata: msg.body.val.metadata
|
|
853
|
+
? cbor.decode(
|
|
854
|
+
new Uint8Array(
|
|
855
|
+
msg.body.val.metadata,
|
|
856
|
+
),
|
|
857
|
+
)
|
|
858
|
+
: null,
|
|
859
|
+
actionId: msg.body.val.actionId,
|
|
860
|
+
},
|
|
861
|
+
},
|
|
862
|
+
};
|
|
863
|
+
} else if (msg.body.tag === "ActionResponse") {
|
|
864
|
+
return {
|
|
865
|
+
body: {
|
|
866
|
+
tag: "ActionResponse",
|
|
867
|
+
val: {
|
|
868
|
+
id: msg.body.val.id,
|
|
869
|
+
output: cbor.decode(
|
|
870
|
+
new Uint8Array(msg.body.val.output),
|
|
871
|
+
),
|
|
872
|
+
},
|
|
873
|
+
},
|
|
874
|
+
};
|
|
875
|
+
} else if (msg.body.tag === "Event") {
|
|
876
|
+
return {
|
|
877
|
+
body: {
|
|
878
|
+
tag: "Event",
|
|
879
|
+
val: {
|
|
880
|
+
name: msg.body.val.name,
|
|
881
|
+
args: cbor.decode(
|
|
882
|
+
new Uint8Array(msg.body.val.args),
|
|
883
|
+
),
|
|
884
|
+
},
|
|
885
|
+
},
|
|
886
|
+
};
|
|
887
|
+
} else {
|
|
888
|
+
// Init has no ArrayBuffer fields
|
|
889
|
+
return msg;
|
|
890
|
+
}
|
|
891
|
+
},
|
|
923
892
|
);
|
|
924
893
|
}
|
|
925
894
|
|
|
@@ -964,13 +933,11 @@ enc
|
|
|
964
933
|
// Remove from registry
|
|
965
934
|
this.#client[ACTOR_CONNS_SYMBOL].delete(this);
|
|
966
935
|
|
|
967
|
-
// Disconnect
|
|
968
|
-
if (
|
|
969
|
-
// Nothing to do
|
|
970
|
-
} else if ("websocket" in this.#transport) {
|
|
936
|
+
// Disconnect websocket cleanly
|
|
937
|
+
if (this.#websocket) {
|
|
971
938
|
logger().debug("closing ws");
|
|
972
939
|
|
|
973
|
-
const ws = this.#
|
|
940
|
+
const ws = this.#websocket;
|
|
974
941
|
// Check if WebSocket is already closed or closing
|
|
975
942
|
if (
|
|
976
943
|
ws.readyState === 2 /* CLOSING */ ||
|
|
@@ -986,41 +953,8 @@ enc
|
|
|
986
953
|
ws.close(1000, "Normal closure");
|
|
987
954
|
await promise;
|
|
988
955
|
}
|
|
989
|
-
} else if ("sse" in this.#transport) {
|
|
990
|
-
logger().debug("closing sse");
|
|
991
|
-
|
|
992
|
-
// Send close request to server for SSE connections
|
|
993
|
-
if (this.#connectionId && this.#connectionToken) {
|
|
994
|
-
try {
|
|
995
|
-
await sendHttpRequest({
|
|
996
|
-
url: "http://actor/connections/close",
|
|
997
|
-
method: "POST",
|
|
998
|
-
headers: {
|
|
999
|
-
[HEADER_CONN_ID]: this.#connectionId,
|
|
1000
|
-
[HEADER_CONN_TOKEN]: this.#connectionToken,
|
|
1001
|
-
},
|
|
1002
|
-
encoding: this.#encoding,
|
|
1003
|
-
skipParseResponse: true,
|
|
1004
|
-
customFetch: this.#driver.sendRequest.bind(
|
|
1005
|
-
this.#driver,
|
|
1006
|
-
this.#actorId!,
|
|
1007
|
-
),
|
|
1008
|
-
requestVersionedDataHandler: TO_SERVER_VERSIONED,
|
|
1009
|
-
responseVersionedDataHandler: TO_CLIENT_VERSIONED,
|
|
1010
|
-
});
|
|
1011
|
-
} catch (error) {
|
|
1012
|
-
// Ignore errors when closing - connection may already be closed
|
|
1013
|
-
logger().warn({
|
|
1014
|
-
msg: "failed to send close request",
|
|
1015
|
-
error,
|
|
1016
|
-
});
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
this.#transport.sse.close();
|
|
1020
|
-
} else {
|
|
1021
|
-
assertUnreachable(this.#transport);
|
|
1022
956
|
}
|
|
1023
|
-
this.#
|
|
957
|
+
this.#websocket = undefined;
|
|
1024
958
|
}
|
|
1025
959
|
|
|
1026
960
|
#sendSubscription(eventName: string, subscribe: boolean) {
|
|
@@ -15,6 +15,12 @@ import {
|
|
|
15
15
|
HTTP_ACTION_REQUEST_VERSIONED,
|
|
16
16
|
HTTP_ACTION_RESPONSE_VERSIONED,
|
|
17
17
|
} from "@/schemas/client-protocol/versioned";
|
|
18
|
+
import {
|
|
19
|
+
type HttpActionRequest as HttpActionRequestJson,
|
|
20
|
+
HttpActionRequestSchema,
|
|
21
|
+
type HttpActionResponse as HttpActionResponseJson,
|
|
22
|
+
HttpActionResponseSchema,
|
|
23
|
+
} from "@/schemas/client-protocol-zod/mod";
|
|
18
24
|
import { bufferToArrayBuffer } from "@/utils";
|
|
19
25
|
import type { ActorDefinitionActions } from "./actor-common";
|
|
20
26
|
import { type ActorConn, ActorConnRaw } from "./actor-conn";
|
|
@@ -100,8 +106,12 @@ export class ActorHandleRaw {
|
|
|
100
106
|
encoding: this.#encoding,
|
|
101
107
|
});
|
|
102
108
|
const responseData = await sendHttpRequest<
|
|
103
|
-
protocol.HttpActionRequest,
|
|
104
|
-
protocol.HttpActionResponse
|
|
109
|
+
protocol.HttpActionRequest, // Bare type
|
|
110
|
+
protocol.HttpActionResponse, // Bare type
|
|
111
|
+
HttpActionRequestJson, // Json type
|
|
112
|
+
HttpActionResponseJson, // Json type
|
|
113
|
+
unknown[], // Request type (the args array)
|
|
114
|
+
Response // Response type (the output value)
|
|
105
115
|
>({
|
|
106
116
|
url: `http://actor/action/${encodeURIComponent(opts.name)}`,
|
|
107
117
|
method: "POST",
|
|
@@ -111,9 +121,7 @@ export class ActorHandleRaw {
|
|
|
111
121
|
? { [HEADER_CONN_PARAMS]: JSON.stringify(this.#params) }
|
|
112
122
|
: {}),
|
|
113
123
|
},
|
|
114
|
-
body:
|
|
115
|
-
args: bufferToArrayBuffer(cbor.encode(opts.args)),
|
|
116
|
-
} satisfies protocol.HttpActionRequest,
|
|
124
|
+
body: opts.args,
|
|
117
125
|
encoding: this.#encoding,
|
|
118
126
|
customFetch: this.#driver.sendRequest.bind(
|
|
119
127
|
this.#driver,
|
|
@@ -122,9 +130,24 @@ export class ActorHandleRaw {
|
|
|
122
130
|
signal: opts?.signal,
|
|
123
131
|
requestVersionedDataHandler: HTTP_ACTION_REQUEST_VERSIONED,
|
|
124
132
|
responseVersionedDataHandler: HTTP_ACTION_RESPONSE_VERSIONED,
|
|
133
|
+
requestZodSchema: HttpActionRequestSchema,
|
|
134
|
+
responseZodSchema: HttpActionResponseSchema,
|
|
135
|
+
// JSON Request: args is the raw value
|
|
136
|
+
requestToJson: (args): HttpActionRequestJson => ({
|
|
137
|
+
args,
|
|
138
|
+
}),
|
|
139
|
+
// BARE Request: args needs to be CBOR-encoded
|
|
140
|
+
requestToBare: (args): protocol.HttpActionRequest => ({
|
|
141
|
+
args: bufferToArrayBuffer(cbor.encode(args)),
|
|
142
|
+
}),
|
|
143
|
+
// JSON Response: output is the raw value
|
|
144
|
+
responseFromJson: (json): Response => json.output as Response,
|
|
145
|
+
// BARE Response: output is ArrayBuffer that needs CBOR-decoding
|
|
146
|
+
responseFromBare: (bare): Response =>
|
|
147
|
+
cbor.decode(new Uint8Array(bare.output)) as Response,
|
|
125
148
|
});
|
|
126
149
|
|
|
127
|
-
return
|
|
150
|
+
return responseData;
|
|
128
151
|
} catch (err) {
|
|
129
152
|
// Standardize to ClientActorError instead of the native backend error
|
|
130
153
|
const { group, code, message, metadata } = deconstructError(
|