rivetkit 2.0.5 → 2.0.7-rc.1
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/v1.ts +0 -6
- package/dist/tsup/actor-router-consts-B3Lu87yJ.d.cts +28 -0
- package/dist/tsup/actor-router-consts-B3Lu87yJ.d.ts +28 -0
- package/dist/tsup/{chunk-5YTI25C3.cjs → chunk-3MBP4WNC.cjs} +7 -7
- package/dist/tsup/{chunk-5YTI25C3.cjs.map → chunk-3MBP4WNC.cjs.map} +1 -1
- package/dist/tsup/chunk-3Y45CIF4.cjs +3726 -0
- package/dist/tsup/chunk-3Y45CIF4.cjs.map +1 -0
- package/dist/tsup/chunk-4GP7BZSR.js +102 -0
- package/dist/tsup/chunk-4GP7BZSR.js.map +1 -0
- package/dist/tsup/chunk-5ZOHIKWG.cjs +4071 -0
- package/dist/tsup/chunk-5ZOHIKWG.cjs.map +1 -0
- package/dist/tsup/{chunk-WADSS5X4.cjs → chunk-6EUWRXLT.cjs} +21 -7
- package/dist/tsup/chunk-6EUWRXLT.cjs.map +1 -0
- package/dist/tsup/{chunk-D7NWUCRK.cjs → chunk-6OVKCDSH.cjs} +6 -6
- package/dist/tsup/{chunk-D7NWUCRK.cjs.map → chunk-6OVKCDSH.cjs.map} +1 -1
- package/dist/tsup/{chunk-I5VTWPHW.js → chunk-7N56ZUC7.js} +3 -3
- package/dist/tsup/{chunk-LZIBTLEY.cjs → chunk-B3TLRM4Q.cjs} +13 -25
- package/dist/tsup/chunk-B3TLRM4Q.cjs.map +1 -0
- package/dist/tsup/chunk-BW5DPM6Z.js +4071 -0
- package/dist/tsup/chunk-BW5DPM6Z.js.map +1 -0
- package/dist/tsup/chunk-DFS77KAA.cjs +1046 -0
- package/dist/tsup/chunk-DFS77KAA.cjs.map +1 -0
- package/dist/tsup/{chunk-PG3K2LI7.js → chunk-E4UVJKSV.js} +2 -2
- package/dist/tsup/chunk-G4ABMAQY.cjs +102 -0
- package/dist/tsup/chunk-G4ABMAQY.cjs.map +1 -0
- package/dist/tsup/{chunk-CKA54YQN.js → chunk-GZVBFXBI.js} +3 -15
- package/dist/tsup/chunk-GZVBFXBI.js.map +1 -0
- package/dist/tsup/chunk-HPT3I7UU.js +3726 -0
- package/dist/tsup/chunk-HPT3I7UU.js.map +1 -0
- package/dist/tsup/chunk-JD54PXWP.js +1046 -0
- package/dist/tsup/chunk-JD54PXWP.js.map +1 -0
- package/dist/tsup/{chunk-PHSQJ6QI.cjs → chunk-K4ENQCC4.cjs} +3 -3
- package/dist/tsup/{chunk-PHSQJ6QI.cjs.map → chunk-K4ENQCC4.cjs.map} +1 -1
- package/dist/tsup/{chunk-WNGOBAA7.js → chunk-PUSQNDJG.js} +2 -2
- package/dist/tsup/{chunk-CFFKMUYH.js → chunk-RVP5RUSC.js} +20 -6
- package/dist/tsup/chunk-RVP5RUSC.js.map +1 -0
- package/dist/tsup/chunk-SAZCNSVY.cjs +259 -0
- package/dist/tsup/chunk-SAZCNSVY.cjs.map +1 -0
- package/dist/tsup/{chunk-YW6Y6VNE.js → chunk-SBKRVQS2.js} +9 -5
- package/dist/tsup/chunk-SBKRVQS2.js.map +1 -0
- package/dist/tsup/{chunk-FGFT4FVX.cjs → chunk-TZGUSEIJ.cjs} +14 -10
- package/dist/tsup/chunk-TZGUSEIJ.cjs.map +1 -0
- package/dist/tsup/chunk-YQ4XQYPM.js +259 -0
- package/dist/tsup/chunk-YQ4XQYPM.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +7 -8
- package/dist/tsup/client/mod.d.ts +7 -8
- 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/{connection-BvE-Oq7t.d.ts → conn-DCSQgIlw.d.ts} +1605 -1353
- package/dist/tsup/{connection-DTzmWwU5.d.cts → conn-DdzHTm2E.d.cts} +1605 -1353
- package/dist/tsup/driver-helpers/mod.cjs +31 -5
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +7 -8
- package/dist/tsup/driver-helpers/mod.d.ts +7 -8
- package/dist/tsup/driver-helpers/mod.js +33 -7
- package/dist/tsup/driver-test-suite/mod.cjs +319 -216
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +7 -7
- package/dist/tsup/driver-test-suite/mod.d.ts +7 -7
- package/dist/tsup/driver-test-suite/mod.js +588 -485
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +17 -5
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +34 -7
- package/dist/tsup/inspector/mod.d.ts +34 -7
- package/dist/tsup/inspector/mod.js +20 -8
- package/dist/tsup/mod.cjs +10 -17
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +56 -9
- package/dist/tsup/mod.d.ts +56 -9
- package/dist/tsup/mod.js +17 -24
- package/dist/tsup/test/mod.cjs +11 -9
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +6 -7
- package/dist/tsup/test/mod.d.ts +6 -7
- package/dist/tsup/test/mod.js +10 -8
- package/dist/tsup/utils.cjs +4 -2
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +11 -1
- package/dist/tsup/utils.d.ts +11 -1
- package/dist/tsup/utils.js +3 -1
- package/package.json +8 -4
- package/src/actor/action.ts +1 -1
- package/src/actor/config.ts +1 -1
- package/src/actor/conn-drivers.ts +205 -0
- package/src/actor/conn-socket.ts +6 -0
- package/src/actor/{connection.ts → conn.ts} +78 -84
- package/src/actor/context.ts +1 -1
- package/src/actor/driver.ts +4 -43
- package/src/actor/instance.ts +162 -86
- package/src/actor/mod.ts +6 -14
- package/src/actor/persisted.ts +2 -5
- package/src/actor/protocol/old.ts +1 -1
- package/src/actor/router-endpoints.ts +147 -138
- package/src/actor/router.ts +89 -52
- package/src/actor/utils.ts +5 -1
- package/src/client/actor-conn.ts +163 -31
- package/src/client/actor-handle.ts +0 -1
- package/src/client/client.ts +2 -2
- package/src/client/config.ts +7 -0
- package/src/client/raw-utils.ts +1 -1
- package/src/client/utils.ts +1 -1
- package/src/common/actor-router-consts.ts +59 -0
- package/src/common/router.ts +2 -1
- package/src/common/versioned-data.ts +5 -5
- package/src/driver-helpers/mod.ts +15 -2
- package/src/driver-test-suite/mod.ts +11 -2
- package/src/driver-test-suite/test-inline-client-driver.ts +40 -22
- package/src/driver-test-suite/tests/actor-conn-state.ts +66 -22
- package/src/driver-test-suite/tests/actor-conn.ts +65 -126
- package/src/driver-test-suite/tests/actor-reconnect.ts +160 -0
- package/src/driver-test-suite/tests/actor-sleep.ts +0 -1
- package/src/driver-test-suite/tests/raw-websocket.ts +0 -35
- package/src/driver-test-suite/utils.ts +8 -3
- package/src/drivers/default.ts +8 -7
- package/src/drivers/engine/actor-driver.ts +67 -44
- package/src/drivers/engine/config.ts +4 -0
- package/src/drivers/file-system/actor.ts +0 -6
- package/src/drivers/file-system/global-state.ts +3 -14
- package/src/drivers/file-system/manager.ts +12 -8
- package/src/inspector/actor.ts +4 -3
- package/src/inspector/config.ts +10 -1
- package/src/inspector/mod.ts +1 -0
- package/src/inspector/utils.ts +23 -4
- package/src/manager/driver.ts +12 -2
- package/src/manager/gateway.ts +407 -0
- package/src/manager/protocol/query.ts +1 -1
- package/src/manager/router.ts +269 -468
- package/src/manager-api/actors.ts +61 -0
- package/src/manager-api/common.ts +4 -0
- package/src/mod.ts +1 -1
- package/src/registry/mod.ts +126 -12
- package/src/registry/serve.ts +8 -3
- package/src/remote-manager-driver/actor-http-client.ts +30 -19
- package/src/remote-manager-driver/actor-websocket-client.ts +45 -18
- package/src/remote-manager-driver/api-endpoints.ts +19 -21
- package/src/remote-manager-driver/api-utils.ts +10 -1
- package/src/remote-manager-driver/mod.ts +53 -53
- package/src/remote-manager-driver/ws-proxy.ts +2 -9
- package/src/test/mod.ts +6 -2
- package/src/utils.ts +21 -2
- package/dist/tsup/chunk-2MD57QF4.js +0 -1794
- package/dist/tsup/chunk-2MD57QF4.js.map +0 -1
- package/dist/tsup/chunk-B2QGJGZQ.js +0 -338
- package/dist/tsup/chunk-B2QGJGZQ.js.map +0 -1
- package/dist/tsup/chunk-CFFKMUYH.js.map +0 -1
- package/dist/tsup/chunk-CKA54YQN.js.map +0 -1
- package/dist/tsup/chunk-FGFT4FVX.cjs.map +0 -1
- package/dist/tsup/chunk-IRMBWX36.cjs +0 -1794
- package/dist/tsup/chunk-IRMBWX36.cjs.map +0 -1
- package/dist/tsup/chunk-L7QRXNWP.js +0 -6562
- package/dist/tsup/chunk-L7QRXNWP.js.map +0 -1
- package/dist/tsup/chunk-LZIBTLEY.cjs.map +0 -1
- package/dist/tsup/chunk-MRZS2J4X.cjs +0 -6562
- package/dist/tsup/chunk-MRZS2J4X.cjs.map +0 -1
- package/dist/tsup/chunk-RM2SVURR.cjs +0 -338
- package/dist/tsup/chunk-RM2SVURR.cjs.map +0 -1
- package/dist/tsup/chunk-WADSS5X4.cjs.map +0 -1
- package/dist/tsup/chunk-YW6Y6VNE.js.map +0 -1
- package/dist/tsup/common-CXCe7s6i.d.cts +0 -218
- package/dist/tsup/common-CXCe7s6i.d.ts +0 -218
- package/dist/tsup/router-endpoints-CctffZNL.d.cts +0 -65
- package/dist/tsup/router-endpoints-DFm1BglJ.d.ts +0 -65
- package/src/actor/generic-conn-driver.ts +0 -246
- package/src/common/fake-event-source.ts +0 -267
- package/src/manager-api/routes/actors-create.ts +0 -16
- package/src/manager-api/routes/actors-delete.ts +0 -4
- package/src/manager-api/routes/actors-get-by-id.ts +0 -7
- package/src/manager-api/routes/actors-get-or-create-by-id.ts +0 -29
- package/src/manager-api/routes/actors-get.ts +0 -7
- package/src/manager-api/routes/common.ts +0 -18
- /package/dist/tsup/{chunk-I5VTWPHW.js.map → chunk-7N56ZUC7.js.map} +0 -0
- /package/dist/tsup/{chunk-PG3K2LI7.js.map → chunk-E4UVJKSV.js.map} +0 -0
- /package/dist/tsup/{chunk-WNGOBAA7.js.map → chunk-PUSQNDJG.js.map} +0 -0
package/src/actor/router.ts
CHANGED
|
@@ -10,17 +10,26 @@ import {
|
|
|
10
10
|
type ConnectWebSocketOpts,
|
|
11
11
|
type ConnectWebSocketOutput,
|
|
12
12
|
type ConnsMessageOpts,
|
|
13
|
-
HEADER_AUTH_DATA,
|
|
14
|
-
HEADER_CONN_ID,
|
|
15
|
-
HEADER_CONN_PARAMS,
|
|
16
|
-
HEADER_CONN_TOKEN,
|
|
17
|
-
HEADER_ENCODING,
|
|
18
13
|
handleAction,
|
|
14
|
+
handleConnectionClose,
|
|
19
15
|
handleConnectionMessage,
|
|
20
16
|
handleRawWebSocketHandler,
|
|
21
17
|
handleSseConnect,
|
|
22
18
|
handleWebSocketConnect,
|
|
23
19
|
} from "@/actor/router-endpoints";
|
|
20
|
+
import {
|
|
21
|
+
HEADER_CONN_ID,
|
|
22
|
+
HEADER_CONN_PARAMS,
|
|
23
|
+
HEADER_CONN_TOKEN,
|
|
24
|
+
HEADER_ENCODING,
|
|
25
|
+
PATH_CONNECT_WEBSOCKET,
|
|
26
|
+
PATH_RAW_WEBSOCKET_PREFIX,
|
|
27
|
+
WS_PROTOCOL_CONN_ID,
|
|
28
|
+
WS_PROTOCOL_CONN_PARAMS,
|
|
29
|
+
WS_PROTOCOL_CONN_TOKEN,
|
|
30
|
+
WS_PROTOCOL_ENCODING,
|
|
31
|
+
WS_PROTOCOL_TOKEN,
|
|
32
|
+
} from "@/common/actor-router-consts";
|
|
24
33
|
import {
|
|
25
34
|
handleRouteError,
|
|
26
35
|
handleRouteNotFound,
|
|
@@ -31,15 +40,13 @@ import {
|
|
|
31
40
|
type ActorInspectorRouterEnv,
|
|
32
41
|
createActorInspectorRouter,
|
|
33
42
|
} from "@/inspector/actor";
|
|
34
|
-
import { secureInspector } from "@/inspector/utils";
|
|
43
|
+
import { isInspectorEnabled, secureInspector } from "@/inspector/utils";
|
|
35
44
|
import type { RunConfig } from "@/registry/run-config";
|
|
45
|
+
import { ConnDriverKind } from "./conn-drivers";
|
|
36
46
|
import type { ActorDriver } from "./driver";
|
|
37
47
|
import { InternalError } from "./errors";
|
|
38
48
|
import { loggerWithoutContext } from "./log";
|
|
39
49
|
|
|
40
|
-
export const PATH_CONNECT_WEBSOCKET = "/connect/websocket";
|
|
41
|
-
export const PATH_RAW_WEBSOCKET_PREFIX = "/raw/websocket/";
|
|
42
|
-
|
|
43
50
|
export type {
|
|
44
51
|
ConnectWebSocketOpts,
|
|
45
52
|
ConnectWebSocketOutput,
|
|
@@ -77,19 +84,70 @@ export function createActorRouter(
|
|
|
77
84
|
return c.text("ok");
|
|
78
85
|
});
|
|
79
86
|
|
|
87
|
+
// Test endpoint to force disconnect a connection non-cleanly
|
|
88
|
+
router.post("/.test/force-disconnect", async (c) => {
|
|
89
|
+
const connId = c.req.query("conn");
|
|
90
|
+
|
|
91
|
+
if (!connId) {
|
|
92
|
+
return c.text("Missing conn query parameter", 400);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const actor = await actorDriver.loadActor(c.env.actorId);
|
|
96
|
+
const conn = actor.__getConnForId(connId);
|
|
97
|
+
|
|
98
|
+
if (!conn) {
|
|
99
|
+
return c.text(`Connection not found: ${connId}`, 404);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Force close the websocket/SSE connection without clean shutdown
|
|
103
|
+
const driverState = conn.__driverState;
|
|
104
|
+
if (driverState && ConnDriverKind.WEBSOCKET in driverState) {
|
|
105
|
+
const ws = driverState[ConnDriverKind.WEBSOCKET].websocket;
|
|
106
|
+
|
|
107
|
+
// Force close without sending close frame
|
|
108
|
+
(ws.raw as any).terminate();
|
|
109
|
+
} else if (driverState && ConnDriverKind.SSE in driverState) {
|
|
110
|
+
const stream = driverState[ConnDriverKind.SSE].stream;
|
|
111
|
+
|
|
112
|
+
// Force close the SSE stream
|
|
113
|
+
stream.abort();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return c.json({ success: true });
|
|
117
|
+
});
|
|
118
|
+
|
|
80
119
|
router.get(PATH_CONNECT_WEBSOCKET, async (c) => {
|
|
81
120
|
const upgradeWebSocket = runConfig.getUpgradeWebSocket?.();
|
|
82
121
|
if (upgradeWebSocket) {
|
|
83
122
|
return upgradeWebSocket(async (c) => {
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
123
|
+
// Parse configuration from Sec-WebSocket-Protocol header
|
|
124
|
+
const protocols = c.req.header("sec-websocket-protocol");
|
|
125
|
+
let encodingRaw: string | undefined;
|
|
126
|
+
let connParamsRaw: string | undefined;
|
|
127
|
+
let connIdRaw: string | undefined;
|
|
128
|
+
let connTokenRaw: string | undefined;
|
|
129
|
+
|
|
130
|
+
if (protocols) {
|
|
131
|
+
const protocolList = protocols.split(",").map((p) => p.trim());
|
|
132
|
+
for (const protocol of protocolList) {
|
|
133
|
+
if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
|
|
134
|
+
encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
|
|
135
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
|
|
136
|
+
connParamsRaw = decodeURIComponent(
|
|
137
|
+
protocol.substring(WS_PROTOCOL_CONN_PARAMS.length),
|
|
138
|
+
);
|
|
139
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
|
|
140
|
+
connIdRaw = protocol.substring(WS_PROTOCOL_CONN_ID.length);
|
|
141
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
|
|
142
|
+
connTokenRaw = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
87
146
|
|
|
88
147
|
const encoding = EncodingSchema.parse(encodingRaw);
|
|
89
148
|
const connParams = connParamsRaw
|
|
90
149
|
? JSON.parse(connParamsRaw)
|
|
91
150
|
: undefined;
|
|
92
|
-
const authData = authDataRaw ? JSON.parse(authDataRaw) : undefined;
|
|
93
151
|
|
|
94
152
|
return await handleWebSocketConnect(
|
|
95
153
|
c.req.raw,
|
|
@@ -98,7 +156,8 @@ export function createActorRouter(
|
|
|
98
156
|
c.env.actorId,
|
|
99
157
|
encoding,
|
|
100
158
|
connParams,
|
|
101
|
-
|
|
159
|
+
connIdRaw,
|
|
160
|
+
connTokenRaw,
|
|
102
161
|
);
|
|
103
162
|
})(c, noopNext());
|
|
104
163
|
} else {
|
|
@@ -110,41 +169,38 @@ export function createActorRouter(
|
|
|
110
169
|
});
|
|
111
170
|
|
|
112
171
|
router.get("/connect/sse", async (c) => {
|
|
113
|
-
|
|
114
|
-
let authData: unknown;
|
|
115
|
-
if (authDataRaw) {
|
|
116
|
-
authData = JSON.parse(authDataRaw);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return handleSseConnect(c, runConfig, actorDriver, c.env.actorId, authData);
|
|
172
|
+
return handleSseConnect(c, runConfig, actorDriver, c.env.actorId);
|
|
120
173
|
});
|
|
121
174
|
|
|
122
175
|
router.post("/action/:action", async (c) => {
|
|
123
176
|
const actionName = c.req.param("action");
|
|
124
177
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (authDataRaw) {
|
|
128
|
-
authData = JSON.parse(authDataRaw);
|
|
129
|
-
}
|
|
178
|
+
return handleAction(c, runConfig, actorDriver, actionName, c.env.actorId);
|
|
179
|
+
});
|
|
130
180
|
|
|
131
|
-
|
|
181
|
+
router.post("/connections/message", async (c) => {
|
|
182
|
+
const connId = c.req.header(HEADER_CONN_ID);
|
|
183
|
+
const connToken = c.req.header(HEADER_CONN_TOKEN);
|
|
184
|
+
if (!connId || !connToken) {
|
|
185
|
+
throw new Error("Missing required parameters");
|
|
186
|
+
}
|
|
187
|
+
return handleConnectionMessage(
|
|
132
188
|
c,
|
|
133
189
|
runConfig,
|
|
134
190
|
actorDriver,
|
|
135
|
-
|
|
191
|
+
connId,
|
|
192
|
+
connToken,
|
|
136
193
|
c.env.actorId,
|
|
137
|
-
authData,
|
|
138
194
|
);
|
|
139
195
|
});
|
|
140
196
|
|
|
141
|
-
router.post("/connections/
|
|
197
|
+
router.post("/connections/close", async (c) => {
|
|
142
198
|
const connId = c.req.header(HEADER_CONN_ID);
|
|
143
199
|
const connToken = c.req.header(HEADER_CONN_TOKEN);
|
|
144
200
|
if (!connId || !connToken) {
|
|
145
201
|
throw new Error("Missing required parameters");
|
|
146
202
|
}
|
|
147
|
-
return
|
|
203
|
+
return handleConnectionClose(
|
|
148
204
|
c,
|
|
149
205
|
runConfig,
|
|
150
206
|
actorDriver,
|
|
@@ -156,12 +212,6 @@ export function createActorRouter(
|
|
|
156
212
|
|
|
157
213
|
// Raw HTTP endpoints - /http/*
|
|
158
214
|
router.all("/raw/http/*", async (c) => {
|
|
159
|
-
const authDataRaw = c.req.header(HEADER_AUTH_DATA);
|
|
160
|
-
let authData: unknown;
|
|
161
|
-
if (authDataRaw) {
|
|
162
|
-
authData = JSON.parse(authDataRaw);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
215
|
const actor = await actorDriver.loadActor(c.env.actorId);
|
|
166
216
|
|
|
167
217
|
// TODO: This is not a clean way of doing this since `/http/` might exist mid-path
|
|
@@ -185,9 +235,7 @@ export function createActorRouter(
|
|
|
185
235
|
});
|
|
186
236
|
|
|
187
237
|
// Call the actor's onFetch handler - it will throw appropriate errors
|
|
188
|
-
const response = await actor.handleFetch(correctedRequest, {
|
|
189
|
-
auth: authData,
|
|
190
|
-
});
|
|
238
|
+
const response = await actor.handleFetch(correctedRequest, {});
|
|
191
239
|
|
|
192
240
|
// This should never happen now since handleFetch throws errors
|
|
193
241
|
if (!response) {
|
|
@@ -202,16 +250,6 @@ export function createActorRouter(
|
|
|
202
250
|
const upgradeWebSocket = runConfig.getUpgradeWebSocket?.();
|
|
203
251
|
if (upgradeWebSocket) {
|
|
204
252
|
return upgradeWebSocket(async (c) => {
|
|
205
|
-
const encodingRaw = c.req.header(HEADER_ENCODING);
|
|
206
|
-
const connParamsRaw = c.req.header(HEADER_CONN_PARAMS);
|
|
207
|
-
const authDataRaw = c.req.header(HEADER_AUTH_DATA);
|
|
208
|
-
|
|
209
|
-
const encoding = EncodingSchema.parse(encodingRaw);
|
|
210
|
-
const connParams = connParamsRaw
|
|
211
|
-
? JSON.parse(connParamsRaw)
|
|
212
|
-
: undefined;
|
|
213
|
-
const authData = authDataRaw ? JSON.parse(authDataRaw) : undefined;
|
|
214
|
-
|
|
215
253
|
const url = new URL(c.req.url);
|
|
216
254
|
const pathWithQuery = c.req.path + url.search;
|
|
217
255
|
|
|
@@ -228,7 +266,6 @@ export function createActorRouter(
|
|
|
228
266
|
pathWithQuery,
|
|
229
267
|
actorDriver,
|
|
230
268
|
c.env.actorId,
|
|
231
|
-
authData,
|
|
232
269
|
);
|
|
233
270
|
})(c, noopNext());
|
|
234
271
|
} else {
|
|
@@ -239,7 +276,7 @@ export function createActorRouter(
|
|
|
239
276
|
}
|
|
240
277
|
});
|
|
241
278
|
|
|
242
|
-
if (runConfig
|
|
279
|
+
if (isInspectorEnabled(runConfig, "actor")) {
|
|
243
280
|
router.route(
|
|
244
281
|
"/inspect",
|
|
245
282
|
new Hono<ActorInspectorRouterEnv & { Bindings: ActorRouterBindings }>()
|
package/src/actor/utils.ts
CHANGED
|
@@ -87,7 +87,11 @@ export class Lock<T> {
|
|
|
87
87
|
export function generateSecureToken(length = 32) {
|
|
88
88
|
const array = new Uint8Array(length);
|
|
89
89
|
crypto.getRandomValues(array);
|
|
90
|
-
|
|
90
|
+
// Replace base64 chars that are not URL safe with URL-safe chars and strip padding
|
|
91
|
+
return btoa(String.fromCharCode(...array))
|
|
92
|
+
.replace(/\+/g, "-")
|
|
93
|
+
.replace(/\//g, "_")
|
|
94
|
+
.replace(/=/g, "");
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
export function generateRandomString(length = 32) {
|
package/src/client/actor-conn.ts
CHANGED
|
@@ -5,6 +5,13 @@ import type { CloseEvent } from "ws";
|
|
|
5
5
|
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
|
+
import {
|
|
9
|
+
HEADER_CONN_ID,
|
|
10
|
+
HEADER_CONN_PARAMS,
|
|
11
|
+
HEADER_CONN_TOKEN,
|
|
12
|
+
HEADER_ENCODING,
|
|
13
|
+
PATH_CONNECT_WEBSOCKET,
|
|
14
|
+
} from "@/common/actor-router-consts";
|
|
8
15
|
import { importEventSource } from "@/common/eventsource";
|
|
9
16
|
import type {
|
|
10
17
|
UniversalErrorEvent,
|
|
@@ -12,15 +19,9 @@ import type {
|
|
|
12
19
|
UniversalMessageEvent,
|
|
13
20
|
} from "@/common/eventsource-interface";
|
|
14
21
|
import { assertUnreachable, stringifyError } from "@/common/utils";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
HEADER_CONN_PARAMS,
|
|
18
|
-
HEADER_CONN_TOKEN,
|
|
19
|
-
HEADER_ENCODING,
|
|
20
|
-
type ManagerDriver,
|
|
21
|
-
} from "@/driver-helpers/mod";
|
|
22
|
+
import type { UniversalWebSocket } from "@/common/websocket-interface";
|
|
23
|
+
import type { ManagerDriver } from "@/driver-helpers/mod";
|
|
22
24
|
import type { ActorQuery } from "@/manager/protocol/query";
|
|
23
|
-
import { PATH_CONNECT_WEBSOCKET, type UniversalWebSocket } from "@/mod";
|
|
24
25
|
import type * as protocol from "@/schemas/client-protocol/mod";
|
|
25
26
|
import {
|
|
26
27
|
TO_CLIENT_VERSIONED,
|
|
@@ -31,7 +32,12 @@ import {
|
|
|
31
32
|
encodingIsBinary,
|
|
32
33
|
serializeWithEncoding,
|
|
33
34
|
} from "@/serde";
|
|
34
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
bufferToArrayBuffer,
|
|
37
|
+
getEnvUniversal,
|
|
38
|
+
httpUserAgent,
|
|
39
|
+
promiseWithResolvers,
|
|
40
|
+
} from "@/utils";
|
|
35
41
|
import type { ActorDefinitionActions } from "./actor-common";
|
|
36
42
|
import { queryActor } from "./actor-query";
|
|
37
43
|
import { ACTOR_CONNS_SYMBOL, type ClientRaw, TRANSPORT_SYMBOL } from "./client";
|
|
@@ -93,7 +99,7 @@ export class ActorConnRaw {
|
|
|
93
99
|
/** If attempting to connect. Helpful for knowing if in a retry loop when reconnecting. */
|
|
94
100
|
#connecting = false;
|
|
95
101
|
|
|
96
|
-
//
|
|
102
|
+
// Connection info, used for reconnection and HTTP requests
|
|
97
103
|
#actorId?: string;
|
|
98
104
|
#connectionId?: string;
|
|
99
105
|
#connectionToken?: string;
|
|
@@ -118,7 +124,7 @@ export class ActorConnRaw {
|
|
|
118
124
|
#keepNodeAliveInterval: NodeJS.Timeout;
|
|
119
125
|
|
|
120
126
|
/** Promise used to indicate the socket has connected successfully. This will be rejected if the connection fails. */
|
|
121
|
-
#onOpenPromise?:
|
|
127
|
+
#onOpenPromise?: ReturnType<typeof promiseWithResolvers<undefined>>;
|
|
122
128
|
|
|
123
129
|
#client: ClientRaw;
|
|
124
130
|
#driver: ManagerDriver;
|
|
@@ -176,7 +182,7 @@ export class ActorConnRaw {
|
|
|
176
182
|
this.#actionIdCounter += 1;
|
|
177
183
|
|
|
178
184
|
const { promise, resolve, reject } =
|
|
179
|
-
|
|
185
|
+
promiseWithResolvers<protocol.ActionResponse>();
|
|
180
186
|
this.#actionsInFlight.set(actionId, { name: opts.name, resolve, reject });
|
|
181
187
|
|
|
182
188
|
this.#sendMessage({
|
|
@@ -252,7 +258,7 @@ enc
|
|
|
252
258
|
// Create promise for open
|
|
253
259
|
if (this.#onOpenPromise)
|
|
254
260
|
throw new Error("#onOpenPromise already defined");
|
|
255
|
-
this.#onOpenPromise =
|
|
261
|
+
this.#onOpenPromise = promiseWithResolvers();
|
|
256
262
|
|
|
257
263
|
// Connect transport
|
|
258
264
|
if (this.#client[TRANSPORT_SYMBOL] === "websocket") {
|
|
@@ -276,15 +282,37 @@ enc
|
|
|
276
282
|
this.#actorQuery,
|
|
277
283
|
this.#driver,
|
|
278
284
|
);
|
|
285
|
+
|
|
286
|
+
// Check if we have connection info for reconnection
|
|
287
|
+
const isReconnection = this.#connectionId && this.#connectionToken;
|
|
288
|
+
if (isReconnection) {
|
|
289
|
+
logger().debug({
|
|
290
|
+
msg: "attempting websocket reconnection",
|
|
291
|
+
connectionId: this.#connectionId,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
279
295
|
const ws = await this.#driver.openWebSocket(
|
|
280
296
|
PATH_CONNECT_WEBSOCKET,
|
|
281
297
|
actorId,
|
|
282
298
|
this.#encoding,
|
|
283
299
|
this.#params,
|
|
300
|
+
// Pass connection ID and token for reconnection if available
|
|
301
|
+
isReconnection ? this.#connectionId : undefined,
|
|
302
|
+
isReconnection ? this.#connectionToken : undefined,
|
|
284
303
|
);
|
|
304
|
+
logger().debug({
|
|
305
|
+
msg: "transport set to new websocket",
|
|
306
|
+
connectionId: this.#connectionId,
|
|
307
|
+
readyState: ws.readyState,
|
|
308
|
+
messageQueueLength: this.#messageQueue.length,
|
|
309
|
+
});
|
|
285
310
|
this.#transport = { websocket: ws };
|
|
286
311
|
ws.addEventListener("open", () => {
|
|
287
|
-
logger().debug({
|
|
312
|
+
logger().debug({
|
|
313
|
+
msg: "client websocket open",
|
|
314
|
+
connectionId: this.#connectionId,
|
|
315
|
+
});
|
|
288
316
|
});
|
|
289
317
|
ws.addEventListener("message", async (ev) => {
|
|
290
318
|
this.#handleOnMessage(ev.data);
|
|
@@ -315,6 +343,8 @@ enc
|
|
|
315
343
|
encoding: this.#encoding,
|
|
316
344
|
});
|
|
317
345
|
|
|
346
|
+
const isReconnection = this.#connectionId && this.#connectionToken;
|
|
347
|
+
|
|
318
348
|
const eventSource = new EventSource("http://actor/connect/sse", {
|
|
319
349
|
fetch: (input, init) => {
|
|
320
350
|
return this.#driver.sendRequest(
|
|
@@ -328,6 +358,12 @@ enc
|
|
|
328
358
|
...(this.#params !== undefined
|
|
329
359
|
? { [HEADER_CONN_PARAMS]: JSON.stringify(this.#params) }
|
|
330
360
|
: {}),
|
|
361
|
+
...(isReconnection
|
|
362
|
+
? {
|
|
363
|
+
[HEADER_CONN_ID]: this.#connectionId,
|
|
364
|
+
[HEADER_CONN_TOKEN]: this.#connectionToken,
|
|
365
|
+
}
|
|
366
|
+
: {}),
|
|
331
367
|
},
|
|
332
368
|
}),
|
|
333
369
|
);
|
|
@@ -337,6 +373,9 @@ enc
|
|
|
337
373
|
this.#transport = { sse: eventSource };
|
|
338
374
|
|
|
339
375
|
eventSource.addEventListener("message", (ev: UniversalMessageEvent) => {
|
|
376
|
+
// Ignore pings
|
|
377
|
+
if (ev.type === "ping") return;
|
|
378
|
+
|
|
340
379
|
this.#handleOnMessage(ev.data);
|
|
341
380
|
});
|
|
342
381
|
|
|
@@ -350,6 +389,7 @@ enc
|
|
|
350
389
|
logger().debug({
|
|
351
390
|
msg: "socket open",
|
|
352
391
|
messageQueueLength: this.#messageQueue.length,
|
|
392
|
+
connectionId: this.#connectionId,
|
|
353
393
|
});
|
|
354
394
|
|
|
355
395
|
// Resolve open promise
|
|
@@ -369,6 +409,10 @@ enc
|
|
|
369
409
|
// If the message fails to send, the message will be re-queued
|
|
370
410
|
const queue = this.#messageQueue;
|
|
371
411
|
this.#messageQueue = [];
|
|
412
|
+
logger().debug({
|
|
413
|
+
msg: "flushing message queue",
|
|
414
|
+
queueLength: queue.length,
|
|
415
|
+
});
|
|
372
416
|
for (const msg of queue) {
|
|
373
417
|
this.#sendMessage(msg);
|
|
374
418
|
}
|
|
@@ -394,7 +438,7 @@ enc
|
|
|
394
438
|
);
|
|
395
439
|
|
|
396
440
|
if (response.body.tag === "Init") {
|
|
397
|
-
//
|
|
441
|
+
// Store connection info for reconnection
|
|
398
442
|
this.#actorId = response.body.val.actorId;
|
|
399
443
|
this.#connectionId = response.body.val.connectionId;
|
|
400
444
|
this.#connectionToken = response.body.val.connectionToken;
|
|
@@ -490,26 +534,46 @@ enc
|
|
|
490
534
|
//
|
|
491
535
|
// These properties will be undefined
|
|
492
536
|
const closeEvent = event as CloseEvent;
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
537
|
+
const wasClean = closeEvent.wasClean;
|
|
538
|
+
|
|
539
|
+
logger().info({
|
|
540
|
+
msg: "socket closed",
|
|
541
|
+
code: closeEvent.code,
|
|
542
|
+
reason: closeEvent.reason,
|
|
543
|
+
wasClean: wasClean,
|
|
544
|
+
connectionId: this.#connectionId,
|
|
545
|
+
messageQueueLength: this.#messageQueue.length,
|
|
546
|
+
actionsInFlight: this.#actionsInFlight.size,
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
// Reject all in-flight actions
|
|
550
|
+
if (this.#actionsInFlight.size > 0) {
|
|
551
|
+
logger().debug({
|
|
552
|
+
msg: "rejecting in-flight actions after disconnect",
|
|
553
|
+
count: this.#actionsInFlight.size,
|
|
554
|
+
connectionId: this.#connectionId,
|
|
555
|
+
wasClean,
|
|
506
556
|
});
|
|
557
|
+
|
|
558
|
+
const disconnectError = new Error(
|
|
559
|
+
wasClean ? "Connection closed" : "Connection lost",
|
|
560
|
+
);
|
|
561
|
+
|
|
562
|
+
for (const actionInfo of this.#actionsInFlight.values()) {
|
|
563
|
+
actionInfo.reject(disconnectError);
|
|
564
|
+
}
|
|
565
|
+
this.#actionsInFlight.clear();
|
|
507
566
|
}
|
|
508
567
|
|
|
509
568
|
this.#transport = undefined;
|
|
510
569
|
|
|
511
570
|
// Automatically reconnect. Skip if already attempting to connect.
|
|
512
571
|
if (!this.#disposed && !this.#connecting) {
|
|
572
|
+
logger().debug({
|
|
573
|
+
msg: "triggering reconnect",
|
|
574
|
+
connectionId: this.#connectionId,
|
|
575
|
+
messageQueueLength: this.#messageQueue.length,
|
|
576
|
+
});
|
|
513
577
|
// TODO: Fetch actor to check if it's destroyed
|
|
514
578
|
// TODO: Add backoff for reconnect
|
|
515
579
|
// TODO: Add a way of preserving connection ID for connection state
|
|
@@ -659,9 +723,26 @@ enc
|
|
|
659
723
|
let queueMessage = false;
|
|
660
724
|
if (!this.#transport) {
|
|
661
725
|
// No transport connected yet
|
|
726
|
+
logger().debug({ msg: "no transport, queueing message" });
|
|
662
727
|
queueMessage = true;
|
|
663
728
|
} else if ("websocket" in this.#transport) {
|
|
664
|
-
|
|
729
|
+
const readyState = this.#transport.websocket.readyState;
|
|
730
|
+
logger().debug({
|
|
731
|
+
msg: "websocket send attempt",
|
|
732
|
+
readyState,
|
|
733
|
+
readyStateString:
|
|
734
|
+
readyState === 0
|
|
735
|
+
? "CONNECTING"
|
|
736
|
+
: readyState === 1
|
|
737
|
+
? "OPEN"
|
|
738
|
+
: readyState === 2
|
|
739
|
+
? "CLOSING"
|
|
740
|
+
: "CLOSED",
|
|
741
|
+
connectionId: this.#connectionId,
|
|
742
|
+
messageType: (message.body as any).tag,
|
|
743
|
+
actionName: (message.body as any).val?.name,
|
|
744
|
+
});
|
|
745
|
+
if (readyState === 1) {
|
|
665
746
|
try {
|
|
666
747
|
const messageSerialized = serializeWithEncoding(
|
|
667
748
|
this.#encoding,
|
|
@@ -677,12 +758,17 @@ enc
|
|
|
677
758
|
logger().warn({
|
|
678
759
|
msg: "failed to send message, added to queue",
|
|
679
760
|
error,
|
|
761
|
+
connectionId: this.#connectionId,
|
|
680
762
|
});
|
|
681
763
|
|
|
682
764
|
// Assuming the socket is disconnected and will be reconnected soon
|
|
683
765
|
queueMessage = true;
|
|
684
766
|
}
|
|
685
767
|
} else {
|
|
768
|
+
logger().debug({
|
|
769
|
+
msg: "websocket not open, queueing message",
|
|
770
|
+
readyState,
|
|
771
|
+
});
|
|
686
772
|
queueMessage = true;
|
|
687
773
|
}
|
|
688
774
|
} else if ("sse" in this.#transport) {
|
|
@@ -698,7 +784,13 @@ enc
|
|
|
698
784
|
|
|
699
785
|
if (!opts?.ephemeral && queueMessage) {
|
|
700
786
|
this.#messageQueue.push(message);
|
|
701
|
-
logger().debug({
|
|
787
|
+
logger().debug({
|
|
788
|
+
msg: "queued connection message",
|
|
789
|
+
queueLength: this.#messageQueue.length,
|
|
790
|
+
connectionId: this.#connectionId,
|
|
791
|
+
messageType: (message.body as any).tag,
|
|
792
|
+
actionName: (message.body as any).val?.name,
|
|
793
|
+
});
|
|
702
794
|
}
|
|
703
795
|
}
|
|
704
796
|
|
|
@@ -777,6 +869,22 @@ enc
|
|
|
777
869
|
return deserializeWithEncoding(this.#encoding, buffer, TO_CLIENT_VERSIONED);
|
|
778
870
|
}
|
|
779
871
|
|
|
872
|
+
/**
|
|
873
|
+
* Get the actor ID (for testing purposes).
|
|
874
|
+
* @internal
|
|
875
|
+
*/
|
|
876
|
+
get actorId(): string | undefined {
|
|
877
|
+
return this.#actorId;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* Get the connection ID (for testing purposes).
|
|
882
|
+
* @internal
|
|
883
|
+
*/
|
|
884
|
+
get connectionId(): string | undefined {
|
|
885
|
+
return this.#connectionId;
|
|
886
|
+
}
|
|
887
|
+
|
|
780
888
|
/**
|
|
781
889
|
* Disconnects from the actor.
|
|
782
890
|
*
|
|
@@ -814,7 +922,7 @@ enc
|
|
|
814
922
|
) {
|
|
815
923
|
logger().debug({ msg: "ws already closed or closing" });
|
|
816
924
|
} else {
|
|
817
|
-
const { promise, resolve } =
|
|
925
|
+
const { promise, resolve } = promiseWithResolvers();
|
|
818
926
|
ws.addEventListener("close", () => {
|
|
819
927
|
logger().debug({ msg: "ws closed" });
|
|
820
928
|
resolve(undefined);
|
|
@@ -823,6 +931,30 @@ enc
|
|
|
823
931
|
await promise;
|
|
824
932
|
}
|
|
825
933
|
} else if ("sse" in this.#transport) {
|
|
934
|
+
// Send close request to server for SSE connections
|
|
935
|
+
if (this.#connectionId && this.#connectionToken) {
|
|
936
|
+
try {
|
|
937
|
+
await sendHttpRequest({
|
|
938
|
+
url: "http://actor/connections/close",
|
|
939
|
+
method: "POST",
|
|
940
|
+
headers: {
|
|
941
|
+
[HEADER_CONN_ID]: this.#connectionId,
|
|
942
|
+
[HEADER_CONN_TOKEN]: this.#connectionToken,
|
|
943
|
+
},
|
|
944
|
+
encoding: this.#encoding,
|
|
945
|
+
skipParseResponse: true,
|
|
946
|
+
customFetch: this.#driver.sendRequest.bind(
|
|
947
|
+
this.#driver,
|
|
948
|
+
this.#actorId!,
|
|
949
|
+
),
|
|
950
|
+
requestVersionedDataHandler: TO_SERVER_VERSIONED,
|
|
951
|
+
responseVersionedDataHandler: TO_CLIENT_VERSIONED,
|
|
952
|
+
});
|
|
953
|
+
} catch (error) {
|
|
954
|
+
// Ignore errors when closing - connection may already be closed
|
|
955
|
+
logger().warn({ msg: "failed to send close request", error });
|
|
956
|
+
}
|
|
957
|
+
}
|
|
826
958
|
this.#transport.sse.close();
|
|
827
959
|
} else {
|
|
828
960
|
assertUnreachable(this.#transport);
|
|
@@ -4,7 +4,6 @@ import type { AnyActorDefinition } from "@/actor/definition";
|
|
|
4
4
|
import type { Encoding } from "@/actor/protocol/serde";
|
|
5
5
|
import { assertUnreachable } from "@/actor/utils";
|
|
6
6
|
import { deconstructError } from "@/common/utils";
|
|
7
|
-
import { importWebSocket } from "@/common/websocket";
|
|
8
7
|
import {
|
|
9
8
|
HEADER_CONN_PARAMS,
|
|
10
9
|
HEADER_ENCODING,
|
package/src/client/client.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Transport } from "@/actor/protocol/old";
|
|
|
3
3
|
import type { Encoding } from "@/actor/protocol/serde";
|
|
4
4
|
import type { ManagerDriver } from "@/driver-helpers/mod";
|
|
5
5
|
import type { ActorQuery } from "@/manager/protocol/query";
|
|
6
|
-
import type { Registry } from "@/mod";
|
|
6
|
+
import type { Registry } from "@/registry/mod";
|
|
7
7
|
import type { ActorActionFunction } from "./actor-common";
|
|
8
8
|
import {
|
|
9
9
|
type ActorConn,
|
|
@@ -491,7 +491,7 @@ function createActorProxy<AD extends AnyActorDefinition>(
|
|
|
491
491
|
|
|
492
492
|
// Handle built-in Promise methods and existing properties
|
|
493
493
|
if (prop === "constructor" || prop in target) {
|
|
494
|
-
const value = Reflect.get(target, prop,
|
|
494
|
+
const value = Reflect.get(target, prop, target);
|
|
495
495
|
// Preserve method binding
|
|
496
496
|
if (typeof value === "function") {
|
|
497
497
|
return value.bind(target);
|
package/src/client/config.ts
CHANGED
|
@@ -14,6 +14,13 @@ export const ClientConfigSchema = z.object({
|
|
|
14
14
|
})
|
|
15
15
|
.default({}),
|
|
16
16
|
|
|
17
|
+
token: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.transform((x) => x ?? getEnvUniversal("RIVET_TOKEN")),
|
|
21
|
+
|
|
22
|
+
headers: z.record(z.string()).optional().default({}),
|
|
23
|
+
|
|
17
24
|
/** Endpoint to connect to the Rivet engine. Can be configured via RIVET_ENGINE env var. */
|
|
18
25
|
endpoint: z
|
|
19
26
|
.string()
|
package/src/client/raw-utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import invariant from "invariant";
|
|
2
|
-
import { PATH_RAW_WEBSOCKET_PREFIX } from "@/actor
|
|
2
|
+
import { PATH_RAW_WEBSOCKET_PREFIX } from "@/common/actor-router-consts";
|
|
3
3
|
import { deconstructError } from "@/common/utils";
|
|
4
4
|
import { HEADER_CONN_PARAMS, type ManagerDriver } from "@/driver-helpers/mod";
|
|
5
5
|
import type { ActorQuery } from "@/manager/protocol/query";
|
package/src/client/utils.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as cbor from "cbor-x";
|
|
2
2
|
import invariant from "invariant";
|
|
3
|
+
import type { Encoding } from "@/actor/protocol/serde";
|
|
3
4
|
import { assertUnreachable } from "@/common/utils";
|
|
4
5
|
import type { VersionedDataHandler } from "@/common/versioned-data";
|
|
5
|
-
import type { Encoding } from "@/mod";
|
|
6
6
|
import type { HttpResponseError } from "@/schemas/client-protocol/mod";
|
|
7
7
|
import { HTTP_RESPONSE_ERROR_VERSIONED } from "@/schemas/client-protocol/versioned";
|
|
8
8
|
import {
|