rivetkit 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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-7OUKNSTU.js → chunk-2NL3KGJ7.js} +17 -14
- package/dist/tsup/chunk-2NL3KGJ7.js.map +1 -0
- package/dist/tsup/{chunk-6P6RA47N.cjs → chunk-3ALZ7EGX.cjs} +14 -10
- package/dist/tsup/chunk-3ALZ7EGX.cjs.map +1 -0
- package/dist/tsup/chunk-4EXJ4ITR.cjs +102 -0
- package/dist/tsup/chunk-4EXJ4ITR.cjs.map +1 -0
- package/dist/tsup/{chunk-ZYLTS2EM.js → chunk-54MAHBLL.js} +2 -2
- package/dist/tsup/{chunk-NTCUGYSD.cjs → chunk-7OOBMCQI.cjs} +34 -31
- package/dist/tsup/chunk-7OOBMCQI.cjs.map +1 -0
- package/dist/tsup/{chunk-VCEHU56K.js → chunk-B6N6VM37.js} +2 -2
- package/dist/tsup/{chunk-VPV4MWXR.js → chunk-DIHKN7NM.js} +3 -3
- package/dist/tsup/{chunk-MRRT2CZD.cjs → chunk-ETDWYT2P.cjs} +7 -7
- package/dist/tsup/{chunk-MRRT2CZD.cjs.map → chunk-ETDWYT2P.cjs.map} +1 -1
- package/dist/tsup/{chunk-TWGATZ3X.cjs → chunk-F7YL5G7Q.cjs} +922 -872
- package/dist/tsup/chunk-F7YL5G7Q.cjs.map +1 -0
- package/dist/tsup/{chunk-UTI5NCES.cjs → chunk-GWJTWY3G.cjs} +6 -6
- package/dist/tsup/{chunk-UTI5NCES.cjs.map → chunk-GWJTWY3G.cjs.map} +1 -1
- package/dist/tsup/{chunk-W6LN7AF5.js → chunk-KHRZPP5T.js} +866 -816
- package/dist/tsup/chunk-KHRZPP5T.js.map +1 -0
- package/dist/tsup/{chunk-5JBFVV4C.cjs → chunk-LXAVET4A.cjs} +21 -7
- package/dist/tsup/chunk-LXAVET4A.cjs.map +1 -0
- package/dist/tsup/{chunk-TCUI5JFE.cjs → chunk-NDCVQZBS.cjs} +45 -18
- package/dist/tsup/chunk-NDCVQZBS.cjs.map +1 -0
- package/dist/tsup/{chunk-4CKHQRXG.js → chunk-NII4KKHD.js} +515 -240
- package/dist/tsup/chunk-NII4KKHD.js.map +1 -0
- package/dist/tsup/{chunk-2K3JMDAN.js → chunk-NRELKXIX.js} +40 -13
- package/dist/tsup/chunk-NRELKXIX.js.map +1 -0
- package/dist/tsup/{chunk-UFWAK3X2.cjs → chunk-NUA6LOOJ.cjs} +660 -385
- package/dist/tsup/chunk-NUA6LOOJ.cjs.map +1 -0
- package/dist/tsup/{chunk-DIAYNQTE.cjs → chunk-OSK2VSJF.cjs} +12 -12
- package/dist/tsup/{chunk-DIAYNQTE.cjs.map → chunk-OSK2VSJF.cjs.map} +1 -1
- package/dist/tsup/chunk-PD6HCAJE.js +102 -0
- package/dist/tsup/chunk-PD6HCAJE.js.map +1 -0
- package/dist/tsup/{chunk-RGQR2J7S.js → chunk-RLBM6D4L.js} +20 -6
- package/dist/tsup/chunk-RLBM6D4L.js.map +1 -0
- package/dist/tsup/{chunk-KG3C7MKR.cjs → chunk-VAF63BEI.cjs} +3 -3
- package/dist/tsup/{chunk-KG3C7MKR.cjs.map → chunk-VAF63BEI.cjs.map} +1 -1
- package/dist/tsup/{chunk-G75SVQON.js → chunk-WAT5AE7S.js} +9 -5
- package/dist/tsup/chunk-WAT5AE7S.js.map +1 -0
- package/dist/tsup/{chunk-WC2PSJWN.js → chunk-YL4VZMMT.js} +2 -2
- 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-BLemxi4f.d.ts → conn-DCSQgIlw.d.ts} +1605 -1353
- package/dist/tsup/{connection-CpDIydXf.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 +317 -222
- 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 +582 -487
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +16 -6
- 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 +17 -7
- package/dist/tsup/mod.cjs +10 -20
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +9 -7
- package/dist/tsup/mod.d.ts +9 -7
- package/dist/tsup/mod.js +9 -19
- package/dist/tsup/test/mod.cjs +11 -11
- 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 -10
- 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 +1 -11
- package/src/actor/persisted.ts +2 -5
- package/src/actor/protocol/old.ts +1 -1
- package/src/actor/router-endpoints.ts +142 -106
- package/src/actor/router.ts +81 -45
- package/src/actor/utils.ts +5 -1
- package/src/client/actor-conn.ts +154 -23
- package/src/client/client.ts +1 -1
- package/src/client/config.ts +7 -0
- package/src/common/actor-router-consts.ts +29 -8
- package/src/common/router.ts +2 -1
- package/src/common/versioned-data.ts +5 -5
- package/src/driver-helpers/mod.ts +14 -1
- package/src/driver-test-suite/mod.ts +11 -2
- package/src/driver-test-suite/test-inline-client-driver.ts +36 -18
- 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 +3 -3
- package/src/drivers/default.ts +8 -7
- package/src/drivers/engine/actor-driver.ts +53 -31
- 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 +11 -1
- package/src/manager/gateway.ts +407 -0
- 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 +119 -10
- package/src/remote-manager-driver/actor-http-client.ts +30 -19
- package/src/remote-manager-driver/actor-websocket-client.ts +43 -16
- 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 +51 -48
- 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/actor-router-consts-BK6arfy8.d.cts +0 -17
- package/dist/tsup/actor-router-consts-BK6arfy8.d.ts +0 -17
- package/dist/tsup/chunk-2K3JMDAN.js.map +0 -1
- package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
- package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
- package/dist/tsup/chunk-4CKHQRXG.js.map +0 -1
- package/dist/tsup/chunk-5JBFVV4C.cjs.map +0 -1
- package/dist/tsup/chunk-6P6RA47N.cjs.map +0 -1
- package/dist/tsup/chunk-7OUKNSTU.js.map +0 -1
- package/dist/tsup/chunk-G75SVQON.js.map +0 -1
- package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
- package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
- package/dist/tsup/chunk-NTCUGYSD.cjs.map +0 -1
- package/dist/tsup/chunk-RGQR2J7S.js.map +0 -1
- package/dist/tsup/chunk-TCUI5JFE.cjs.map +0 -1
- package/dist/tsup/chunk-TWGATZ3X.cjs.map +0 -1
- package/dist/tsup/chunk-UFWAK3X2.cjs.map +0 -1
- package/dist/tsup/chunk-W6LN7AF5.js.map +0 -1
- package/dist/tsup/common-CXCe7s6i.d.cts +0 -218
- package/dist/tsup/common-CXCe7s6i.d.ts +0 -218
- 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-ZYLTS2EM.js.map → chunk-54MAHBLL.js.map} +0 -0
- /package/dist/tsup/{chunk-VCEHU56K.js.map → chunk-B6N6VM37.js.map} +0 -0
- /package/dist/tsup/{chunk-VPV4MWXR.js.map → chunk-DIHKN7NM.js.map} +0 -0
- /package/dist/tsup/{chunk-WC2PSJWN.js.map → chunk-YL4VZMMT.js.map} +0 -0
|
@@ -1,19 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
configureInspectorAccessToken,
|
|
3
|
+
getInspectorUrl,
|
|
4
|
+
inspectorLogger,
|
|
5
|
+
isInspectorEnabled,
|
|
6
|
+
secureInspector
|
|
7
|
+
} from "./chunk-PD6HCAJE.js";
|
|
1
8
|
import {
|
|
2
9
|
ActorDefinition,
|
|
3
|
-
CONNECTION_DRIVER_HTTP,
|
|
4
|
-
CONNECTION_DRIVER_SSE,
|
|
5
|
-
CONNECTION_DRIVER_WEBSOCKET,
|
|
6
10
|
RemoteManagerDriver,
|
|
7
11
|
createActorInspectorRouter,
|
|
8
12
|
createClientWithDriver,
|
|
9
13
|
deserializeActorKey,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
generateConnSocketId,
|
|
15
|
+
lookupInRegistry,
|
|
16
|
+
serializeActorKey
|
|
17
|
+
} from "./chunk-NII4KKHD.js";
|
|
14
18
|
import {
|
|
15
19
|
CreateActorSchema
|
|
16
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-54MAHBLL.js";
|
|
17
21
|
import {
|
|
18
22
|
ActionContext,
|
|
19
23
|
HTTP_ACTION_REQUEST_VERSIONED,
|
|
@@ -24,42 +28,50 @@ import {
|
|
|
24
28
|
createVersionedDataHandler,
|
|
25
29
|
parseMessage,
|
|
26
30
|
serializeEmptyPersistData
|
|
27
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-2NL3KGJ7.js";
|
|
28
32
|
import {
|
|
29
33
|
EncodingSchema,
|
|
30
34
|
HEADER_ACTOR_ID,
|
|
31
|
-
HEADER_AUTH_DATA,
|
|
32
35
|
HEADER_CONN_ID,
|
|
33
36
|
HEADER_CONN_PARAMS,
|
|
34
37
|
HEADER_CONN_TOKEN,
|
|
35
38
|
HEADER_ENCODING,
|
|
39
|
+
HEADER_RIVET_ACTOR,
|
|
40
|
+
HEADER_RIVET_TARGET,
|
|
36
41
|
PATH_CONNECT_WEBSOCKET,
|
|
37
42
|
PATH_RAW_WEBSOCKET_PREFIX,
|
|
43
|
+
WS_PROTOCOL_ACTOR,
|
|
44
|
+
WS_PROTOCOL_CONN_ID,
|
|
45
|
+
WS_PROTOCOL_CONN_PARAMS,
|
|
46
|
+
WS_PROTOCOL_CONN_TOKEN,
|
|
47
|
+
WS_PROTOCOL_ENCODING,
|
|
48
|
+
WS_PROTOCOL_PATH,
|
|
49
|
+
WS_PROTOCOL_TARGET,
|
|
50
|
+
WS_PROTOCOL_TRANSPORT,
|
|
38
51
|
contentTypeForEncoding,
|
|
39
52
|
deserializeWithEncoding,
|
|
40
|
-
encodeDataToString,
|
|
41
53
|
encodingIsBinary,
|
|
42
54
|
generateRandomString,
|
|
43
55
|
loggerWithoutContext,
|
|
44
56
|
serializeWithEncoding
|
|
45
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-NRELKXIX.js";
|
|
46
58
|
import {
|
|
47
59
|
configureBaseLogger,
|
|
48
60
|
configureDefaultLogger,
|
|
49
61
|
getLogger
|
|
50
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-YL4VZMMT.js";
|
|
51
63
|
import {
|
|
52
64
|
bufferToArrayBuffer,
|
|
53
65
|
deconstructError,
|
|
54
66
|
getEnvUniversal,
|
|
55
67
|
noopNext,
|
|
56
68
|
package_default,
|
|
69
|
+
promiseWithResolvers,
|
|
57
70
|
setLongTimeout,
|
|
58
71
|
stringifyError
|
|
59
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-RLBM6D4L.js";
|
|
60
73
|
import {
|
|
61
74
|
ActorAlreadyExists,
|
|
62
|
-
ActorNotFound,
|
|
63
75
|
ConnNotFound,
|
|
64
76
|
IncorrectConnToken,
|
|
65
77
|
InternalError,
|
|
@@ -127,163 +139,15 @@ var ActorConfigSchema = z.object({
|
|
|
127
139
|
}
|
|
128
140
|
);
|
|
129
141
|
|
|
130
|
-
// src/actor/generic-conn-driver.ts
|
|
131
|
-
var GenericConnGlobalState = class {
|
|
132
|
-
websockets = /* @__PURE__ */ new Map();
|
|
133
|
-
sseStreams = /* @__PURE__ */ new Map();
|
|
134
|
-
};
|
|
135
|
-
function createGenericConnDrivers(globalState) {
|
|
136
|
-
return {
|
|
137
|
-
[CONNECTION_DRIVER_WEBSOCKET]: createGenericWebSocketDriver(globalState),
|
|
138
|
-
[CONNECTION_DRIVER_SSE]: createGenericSseDriver(globalState),
|
|
139
|
-
[CONNECTION_DRIVER_HTTP]: createGenericHttpDriver()
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
function createGenericWebSocketDriver(globalState) {
|
|
143
|
-
return {
|
|
144
|
-
sendMessage: (actor2, conn, state, message) => {
|
|
145
|
-
const ws = globalState.websockets.get(conn.id);
|
|
146
|
-
if (!ws) {
|
|
147
|
-
actor2.rLog.warn({
|
|
148
|
-
msg: "missing ws for sendMessage",
|
|
149
|
-
actorId: actor2.id,
|
|
150
|
-
connId: conn.id,
|
|
151
|
-
totalCount: globalState.websockets.size
|
|
152
|
-
});
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const serialized = message.serialize(state.encoding);
|
|
156
|
-
actor2.rLog.debug({
|
|
157
|
-
msg: "sending websocket message",
|
|
158
|
-
encoding: state.encoding,
|
|
159
|
-
dataType: typeof serialized,
|
|
160
|
-
isUint8Array: serialized instanceof Uint8Array,
|
|
161
|
-
isArrayBuffer: serialized instanceof ArrayBuffer,
|
|
162
|
-
dataLength: serialized.byteLength || serialized.length
|
|
163
|
-
});
|
|
164
|
-
if (serialized instanceof Uint8Array) {
|
|
165
|
-
const buffer = serialized.buffer.slice(
|
|
166
|
-
serialized.byteOffset,
|
|
167
|
-
serialized.byteOffset + serialized.byteLength
|
|
168
|
-
);
|
|
169
|
-
if (buffer instanceof SharedArrayBuffer) {
|
|
170
|
-
const arrayBuffer = new ArrayBuffer(buffer.byteLength);
|
|
171
|
-
new Uint8Array(arrayBuffer).set(new Uint8Array(buffer));
|
|
172
|
-
actor2.rLog.debug({
|
|
173
|
-
msg: "converted SharedArrayBuffer to ArrayBuffer",
|
|
174
|
-
byteLength: arrayBuffer.byteLength
|
|
175
|
-
});
|
|
176
|
-
ws.send(arrayBuffer);
|
|
177
|
-
} else {
|
|
178
|
-
actor2.rLog.debug({
|
|
179
|
-
msg: "sending ArrayBuffer",
|
|
180
|
-
byteLength: buffer.byteLength
|
|
181
|
-
});
|
|
182
|
-
ws.send(buffer);
|
|
183
|
-
}
|
|
184
|
-
} else {
|
|
185
|
-
actor2.rLog.debug({
|
|
186
|
-
msg: "sending string data",
|
|
187
|
-
length: serialized.length
|
|
188
|
-
});
|
|
189
|
-
ws.send(serialized);
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
disconnect: async (actor2, conn, _state, reason) => {
|
|
193
|
-
const ws = globalState.websockets.get(conn.id);
|
|
194
|
-
if (!ws) {
|
|
195
|
-
actor2.rLog.warn({
|
|
196
|
-
msg: "missing ws for disconnect",
|
|
197
|
-
actorId: actor2.id,
|
|
198
|
-
connId: conn.id,
|
|
199
|
-
totalCount: globalState.websockets.size
|
|
200
|
-
});
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const raw = ws.raw;
|
|
204
|
-
if (!raw) {
|
|
205
|
-
actor2.rLog.warn({ msg: "ws.raw does not exist" });
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const { promise, resolve } = Promise.withResolvers();
|
|
209
|
-
raw.addEventListener("close", () => resolve());
|
|
210
|
-
ws.close(1e3, reason);
|
|
211
|
-
await promise;
|
|
212
|
-
},
|
|
213
|
-
getConnectionReadyState: (actor2, conn) => {
|
|
214
|
-
const ws = globalState.websockets.get(conn.id);
|
|
215
|
-
if (!ws) {
|
|
216
|
-
actor2.rLog.warn({
|
|
217
|
-
msg: "missing ws for getConnectionReadyState",
|
|
218
|
-
connId: conn.id
|
|
219
|
-
});
|
|
220
|
-
return void 0;
|
|
221
|
-
}
|
|
222
|
-
const raw = ws.raw;
|
|
223
|
-
return raw.readyState;
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
function createGenericSseDriver(globalState) {
|
|
228
|
-
return {
|
|
229
|
-
sendMessage: (actor2, conn, state, message) => {
|
|
230
|
-
const stream = globalState.sseStreams.get(conn.id);
|
|
231
|
-
if (!stream) {
|
|
232
|
-
actor2.rLog.warn({
|
|
233
|
-
msg: "missing sse stream for sendMessage",
|
|
234
|
-
connId: conn.id
|
|
235
|
-
});
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
stream.writeSSE({
|
|
239
|
-
data: encodeDataToString(message.serialize(state.encoding))
|
|
240
|
-
});
|
|
241
|
-
},
|
|
242
|
-
disconnect: async (actor2, conn, _state, _reason) => {
|
|
243
|
-
const stream = globalState.sseStreams.get(conn.id);
|
|
244
|
-
if (!stream) {
|
|
245
|
-
actor2.rLog.warn({
|
|
246
|
-
msg: "missing sse stream for disconnect",
|
|
247
|
-
connId: conn.id
|
|
248
|
-
});
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
stream.close();
|
|
252
|
-
},
|
|
253
|
-
getConnectionReadyState: (actor2, conn) => {
|
|
254
|
-
const stream = globalState.sseStreams.get(conn.id);
|
|
255
|
-
if (!stream) {
|
|
256
|
-
actor2.rLog.warn({
|
|
257
|
-
msg: "missing sse stream for getConnectionReadyState",
|
|
258
|
-
connId: conn.id
|
|
259
|
-
});
|
|
260
|
-
return void 0;
|
|
261
|
-
}
|
|
262
|
-
if (stream.aborted || stream.closed) {
|
|
263
|
-
return 3 /* CLOSED */;
|
|
264
|
-
}
|
|
265
|
-
return 1 /* OPEN */;
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
function createGenericHttpDriver() {
|
|
270
|
-
return {
|
|
271
|
-
getConnectionReadyState(_actor, _conn) {
|
|
272
|
-
return 1 /* OPEN */;
|
|
273
|
-
},
|
|
274
|
-
disconnect: async () => {
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
|
|
279
142
|
// src/actor/router.ts
|
|
280
143
|
import { Hono } from "hono";
|
|
281
144
|
import { cors } from "hono/cors";
|
|
282
|
-
import
|
|
145
|
+
import invariant2 from "invariant";
|
|
283
146
|
|
|
284
147
|
// src/actor/router-endpoints.ts
|
|
285
148
|
import * as cbor from "cbor-x";
|
|
286
149
|
import { streamSSE } from "hono/streaming";
|
|
150
|
+
import invariant from "invariant";
|
|
287
151
|
|
|
288
152
|
// src/manager/log.ts
|
|
289
153
|
function logger() {
|
|
@@ -568,13 +432,14 @@ var HonoWebSocketAdapter = class {
|
|
|
568
432
|
};
|
|
569
433
|
|
|
570
434
|
// src/actor/router-endpoints.ts
|
|
571
|
-
|
|
435
|
+
var SSE_PING_INTERVAL = 1e3;
|
|
436
|
+
async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, encoding, parameters, connId, connToken) {
|
|
572
437
|
const exposeInternalError = req ? getRequestExposeInternalError(req) : false;
|
|
573
438
|
const {
|
|
574
439
|
promise: handlersPromise,
|
|
575
440
|
resolve: handlersResolve,
|
|
576
441
|
reject: handlersReject
|
|
577
|
-
} =
|
|
442
|
+
} = promiseWithResolvers();
|
|
578
443
|
let actor2;
|
|
579
444
|
try {
|
|
580
445
|
actor2 = await actorDriver.loadActor(actorId);
|
|
@@ -600,31 +465,36 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
|
|
|
600
465
|
}
|
|
601
466
|
};
|
|
602
467
|
}
|
|
468
|
+
const closePromise = promiseWithResolvers();
|
|
469
|
+
const socketId = generateConnSocketId();
|
|
603
470
|
return {
|
|
604
471
|
onOpen: (_evt, ws) => {
|
|
605
|
-
actor2.rLog.debug("websocket open");
|
|
472
|
+
actor2.rLog.debug("actor websocket open");
|
|
606
473
|
(async () => {
|
|
607
474
|
try {
|
|
608
|
-
|
|
609
|
-
const connToken = generateConnToken();
|
|
610
|
-
const connState = await actor2.prepareConn(parameters, req);
|
|
611
|
-
const connGlobalState = actorDriver.getGenericConnGlobalState(actorId);
|
|
612
|
-
connGlobalState.websockets.set(connId, ws);
|
|
475
|
+
let conn;
|
|
613
476
|
actor2.rLog.debug({
|
|
614
|
-
msg: "
|
|
615
|
-
actorId,
|
|
616
|
-
totalCount: connGlobalState.websockets.size
|
|
617
|
-
});
|
|
618
|
-
const conn = await actor2.createConn(
|
|
477
|
+
msg: connId ? "websocket reconnection attempt" : "new websocket connection",
|
|
619
478
|
connId,
|
|
620
|
-
|
|
479
|
+
actorId
|
|
480
|
+
});
|
|
481
|
+
conn = await actor2.createConn(
|
|
482
|
+
{
|
|
483
|
+
socketId,
|
|
484
|
+
driverState: {
|
|
485
|
+
[0 /* WEBSOCKET */]: {
|
|
486
|
+
encoding,
|
|
487
|
+
websocket: ws,
|
|
488
|
+
closePromise
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
},
|
|
621
492
|
parameters,
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
authData
|
|
493
|
+
req,
|
|
494
|
+
connId,
|
|
495
|
+
connToken
|
|
626
496
|
);
|
|
627
|
-
handlersResolve({ conn, actor: actor2, connId });
|
|
497
|
+
handlersResolve({ conn, actor: actor2, connId: conn.id });
|
|
628
498
|
} catch (error) {
|
|
629
499
|
handlersReject(error);
|
|
630
500
|
const { code } = deconstructError(
|
|
@@ -682,6 +552,8 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
|
|
|
682
552
|
});
|
|
683
553
|
},
|
|
684
554
|
onClose: (event, ws) => {
|
|
555
|
+
handlersReject(`WebSocket closed (${event.code}): ${event.reason}`);
|
|
556
|
+
closePromise.resolve();
|
|
685
557
|
if (event.wasClean) {
|
|
686
558
|
actor2.rLog.info({
|
|
687
559
|
msg: "websocket closed",
|
|
@@ -698,22 +570,8 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
|
|
|
698
570
|
});
|
|
699
571
|
}
|
|
700
572
|
ws.close(1e3, "hack_force_close");
|
|
701
|
-
handlersPromise.then(({ conn, actor: actor3
|
|
702
|
-
|
|
703
|
-
const didDelete = connGlobalState.websockets.delete(connId);
|
|
704
|
-
if (didDelete) {
|
|
705
|
-
actor3.rLog.info({
|
|
706
|
-
msg: "removing websocket for conn",
|
|
707
|
-
totalCount: connGlobalState.websockets.size
|
|
708
|
-
});
|
|
709
|
-
} else {
|
|
710
|
-
actor3.rLog.warn({
|
|
711
|
-
msg: "websocket does not exist for conn",
|
|
712
|
-
actorId,
|
|
713
|
-
totalCount: connGlobalState.websockets.size
|
|
714
|
-
});
|
|
715
|
-
}
|
|
716
|
-
actor3.__removeConn(conn);
|
|
573
|
+
handlersPromise.then(({ conn, actor: actor3 }) => {
|
|
574
|
+
actor3.__connDisconnected(conn, event.wasClean, socketId);
|
|
717
575
|
}).catch((error) => {
|
|
718
576
|
deconstructError(
|
|
719
577
|
error,
|
|
@@ -737,43 +595,47 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
|
|
|
737
595
|
}
|
|
738
596
|
};
|
|
739
597
|
}
|
|
740
|
-
async function handleSseConnect(c, _runConfig, actorDriver, actorId
|
|
598
|
+
async function handleSseConnect(c, _runConfig, actorDriver, actorId) {
|
|
599
|
+
c.header("Content-Encoding", "Identity");
|
|
741
600
|
const encoding = getRequestEncoding(c.req);
|
|
742
601
|
const parameters = getRequestConnParams(c.req);
|
|
602
|
+
const socketId = generateConnSocketId();
|
|
603
|
+
const connId = c.req.header(HEADER_CONN_ID);
|
|
604
|
+
const connToken = c.req.header(HEADER_CONN_TOKEN);
|
|
743
605
|
return streamSSE(c, async (stream) => {
|
|
744
606
|
let actor2;
|
|
745
|
-
let connId;
|
|
746
|
-
let connToken;
|
|
747
|
-
let connState;
|
|
748
607
|
let conn;
|
|
749
608
|
try {
|
|
750
609
|
actor2 = await actorDriver.loadActor(actorId);
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
actorDriver.getGenericConnGlobalState(actorId).sseStreams.set(connId, stream);
|
|
610
|
+
actor2.rLog.debug({
|
|
611
|
+
msg: connId ? "sse reconnection attempt" : "sse open",
|
|
612
|
+
connId
|
|
613
|
+
});
|
|
756
614
|
conn = await actor2.createConn(
|
|
757
|
-
|
|
758
|
-
|
|
615
|
+
{
|
|
616
|
+
socketId,
|
|
617
|
+
driverState: {
|
|
618
|
+
[1 /* SSE */]: {
|
|
619
|
+
encoding,
|
|
620
|
+
stream
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
},
|
|
759
624
|
parameters,
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
authData
|
|
625
|
+
c.req.raw,
|
|
626
|
+
connId,
|
|
627
|
+
connToken
|
|
764
628
|
);
|
|
765
|
-
const abortResolver =
|
|
629
|
+
const abortResolver = promiseWithResolvers();
|
|
766
630
|
stream.onAbort(() => {
|
|
767
631
|
});
|
|
768
632
|
c.req.raw.signal.addEventListener("abort", async () => {
|
|
769
|
-
|
|
633
|
+
invariant(actor2, "actor should exist");
|
|
634
|
+
const rLog = actor2.rLog ?? loggerWithoutContext();
|
|
770
635
|
try {
|
|
771
636
|
rLog.debug("sse stream aborted");
|
|
772
|
-
if (
|
|
773
|
-
|
|
774
|
-
}
|
|
775
|
-
if (conn && actor2) {
|
|
776
|
-
actor2.__removeConn(conn);
|
|
637
|
+
if (conn) {
|
|
638
|
+
actor2.__connDisconnected(conn, false, socketId);
|
|
777
639
|
}
|
|
778
640
|
abortResolver.resolve(void 0);
|
|
779
641
|
} catch (error) {
|
|
@@ -781,24 +643,28 @@ async function handleSseConnect(c, _runConfig, actorDriver, actorId, authData) {
|
|
|
781
643
|
abortResolver.resolve(void 0);
|
|
782
644
|
}
|
|
783
645
|
});
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
646
|
+
while (true) {
|
|
647
|
+
if (stream.closed || stream.aborted) {
|
|
648
|
+
actor2 == null ? void 0 : actor2.rLog.debug({
|
|
649
|
+
msg: "sse stream closed",
|
|
650
|
+
closed: stream.closed,
|
|
651
|
+
aborted: stream.aborted
|
|
652
|
+
});
|
|
653
|
+
break;
|
|
654
|
+
}
|
|
655
|
+
await stream.writeSSE({ event: "ping", data: "" });
|
|
656
|
+
await stream.sleep(SSE_PING_INTERVAL);
|
|
787
657
|
}
|
|
788
|
-
await abortResolver.promise;
|
|
789
658
|
} catch (error) {
|
|
790
659
|
loggerWithoutContext().error({ msg: "error in sse connection", error });
|
|
791
|
-
if (connId !== void 0) {
|
|
792
|
-
actorDriver.getGenericConnGlobalState(actorId).sseStreams.delete(connId);
|
|
793
|
-
}
|
|
794
660
|
if (conn && actor2 !== void 0) {
|
|
795
|
-
actor2.
|
|
661
|
+
actor2.__connDisconnected(conn, false, socketId);
|
|
796
662
|
}
|
|
797
663
|
stream.close();
|
|
798
664
|
}
|
|
799
665
|
});
|
|
800
666
|
}
|
|
801
|
-
async function handleAction(c, _runConfig, actorDriver, actionName, actorId
|
|
667
|
+
async function handleAction(c, _runConfig, actorDriver, actionName, actorId) {
|
|
802
668
|
const encoding = getRequestEncoding(c.req);
|
|
803
669
|
const parameters = getRequestConnParams(c.req);
|
|
804
670
|
const arrayBuffer = await c.req.arrayBuffer();
|
|
@@ -808,27 +674,26 @@ async function handleAction(c, _runConfig, actorDriver, actionName, actorId, aut
|
|
|
808
674
|
HTTP_ACTION_REQUEST_VERSIONED
|
|
809
675
|
);
|
|
810
676
|
const actionArgs = cbor.decode(new Uint8Array(request.args));
|
|
677
|
+
const socketId = generateConnSocketId();
|
|
811
678
|
let actor2;
|
|
812
679
|
let conn;
|
|
813
680
|
let output;
|
|
814
681
|
try {
|
|
815
682
|
actor2 = await actorDriver.loadActor(actorId);
|
|
816
683
|
actor2.rLog.debug({ msg: "handling action", actionName, encoding });
|
|
817
|
-
const connState = await actor2.prepareConn(parameters, c.req.raw);
|
|
818
684
|
conn = await actor2.createConn(
|
|
819
|
-
|
|
820
|
-
|
|
685
|
+
{
|
|
686
|
+
socketId,
|
|
687
|
+
driverState: { [2 /* HTTP */]: {} }
|
|
688
|
+
},
|
|
821
689
|
parameters,
|
|
822
|
-
|
|
823
|
-
CONNECTION_DRIVER_HTTP,
|
|
824
|
-
{},
|
|
825
|
-
authData
|
|
690
|
+
c.req.raw
|
|
826
691
|
);
|
|
827
692
|
const ctx = new ActionContext(actor2.actorContext, conn);
|
|
828
693
|
output = await actor2.executeAction(ctx, actionName, actionArgs);
|
|
829
694
|
} finally {
|
|
830
695
|
if (conn) {
|
|
831
|
-
actor2 == null ? void 0 : actor2.
|
|
696
|
+
actor2 == null ? void 0 : actor2.__connDisconnected(conn, true, socketId);
|
|
832
697
|
}
|
|
833
698
|
}
|
|
834
699
|
const responseData = {
|
|
@@ -862,7 +727,25 @@ async function handleConnectionMessage(c, _runConfig, actorDriver, connId, connT
|
|
|
862
727
|
await actor2.processMessage(message, conn);
|
|
863
728
|
return c.json({});
|
|
864
729
|
}
|
|
865
|
-
async function
|
|
730
|
+
async function handleConnectionClose(c, _runConfig, actorDriver, connId, connToken, actorId) {
|
|
731
|
+
var _a;
|
|
732
|
+
const actor2 = await actorDriver.loadActor(actorId);
|
|
733
|
+
const conn = actor2.conns.get(connId);
|
|
734
|
+
if (!conn) {
|
|
735
|
+
throw new ConnNotFound(connId);
|
|
736
|
+
}
|
|
737
|
+
if (conn._token !== connToken) {
|
|
738
|
+
throw new IncorrectConnToken();
|
|
739
|
+
}
|
|
740
|
+
if (!((_a = conn.__socket) == null ? void 0 : _a.driverState) || !(1 /* SSE */ in conn.__socket.driverState)) {
|
|
741
|
+
throw new UserError(
|
|
742
|
+
"Connection close is only supported for SSE connections"
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
await conn.disconnect("Connection closed by client request");
|
|
746
|
+
return c.json({});
|
|
747
|
+
}
|
|
748
|
+
async function handleRawWebSocketHandler(req, path3, actorDriver, actorId) {
|
|
866
749
|
const actor2 = await actorDriver.loadActor(actorId);
|
|
867
750
|
return {
|
|
868
751
|
onOpen: (_evt, ws) => {
|
|
@@ -997,70 +880,6 @@ function handleRouteError(error, c) {
|
|
|
997
880
|
return c.body(output, { status: statusCode });
|
|
998
881
|
}
|
|
999
882
|
|
|
1000
|
-
// src/inspector/utils.ts
|
|
1001
|
-
import crypto2 from "crypto";
|
|
1002
|
-
import { createMiddleware } from "hono/factory";
|
|
1003
|
-
|
|
1004
|
-
// src/inspector/log.ts
|
|
1005
|
-
function inspectorLogger() {
|
|
1006
|
-
return getLogger("inspector");
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
// src/inspector/utils.ts
|
|
1010
|
-
function compareSecrets(providedSecret, validSecret) {
|
|
1011
|
-
if (providedSecret.length !== validSecret.length) {
|
|
1012
|
-
return false;
|
|
1013
|
-
}
|
|
1014
|
-
const encoder = new TextEncoder();
|
|
1015
|
-
const a = encoder.encode(providedSecret);
|
|
1016
|
-
const b = encoder.encode(validSecret);
|
|
1017
|
-
if (a.byteLength !== b.byteLength) {
|
|
1018
|
-
return false;
|
|
1019
|
-
}
|
|
1020
|
-
if (!crypto2.timingSafeEqual(a, b)) {
|
|
1021
|
-
return false;
|
|
1022
|
-
}
|
|
1023
|
-
return true;
|
|
1024
|
-
}
|
|
1025
|
-
var secureInspector = (runConfig) => createMiddleware(async (c, next) => {
|
|
1026
|
-
var _a, _b, _c;
|
|
1027
|
-
if (!runConfig.inspector.enabled) {
|
|
1028
|
-
return c.text("Inspector is not enabled", 503);
|
|
1029
|
-
}
|
|
1030
|
-
const userToken = (_a = c.req.header("Authorization")) == null ? void 0 : _a.replace("Bearer ", "");
|
|
1031
|
-
if (!userToken) {
|
|
1032
|
-
return c.text("Unauthorized", 401);
|
|
1033
|
-
}
|
|
1034
|
-
const inspectorToken = (_c = (_b = runConfig.inspector).token) == null ? void 0 : _c.call(_b);
|
|
1035
|
-
if (!inspectorToken) {
|
|
1036
|
-
return c.text("Unauthorized", 401);
|
|
1037
|
-
}
|
|
1038
|
-
const isValid = compareSecrets(userToken, inspectorToken);
|
|
1039
|
-
if (!isValid) {
|
|
1040
|
-
return c.text("Unauthorized", 401);
|
|
1041
|
-
}
|
|
1042
|
-
await next();
|
|
1043
|
-
});
|
|
1044
|
-
function getInspectorUrl(runConfig) {
|
|
1045
|
-
var _a, _b, _c, _d;
|
|
1046
|
-
if (!((_a = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _a.enabled)) {
|
|
1047
|
-
return "disabled";
|
|
1048
|
-
}
|
|
1049
|
-
const accessToken = (_c = (_b = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _b.token) == null ? void 0 : _c.call(_b);
|
|
1050
|
-
if (!accessToken) {
|
|
1051
|
-
inspectorLogger().warn(
|
|
1052
|
-
"Inspector Token is not set, but Inspector is enabled. Please set it in the run configuration `inspector.token` or via `RIVETKIT_INSPECTOR_TOKEN` environment variable. Inspector will not be accessible."
|
|
1053
|
-
);
|
|
1054
|
-
return "disabled";
|
|
1055
|
-
}
|
|
1056
|
-
const url = new URL("https://inspect.rivet.dev");
|
|
1057
|
-
url.searchParams.set("t", accessToken);
|
|
1058
|
-
if ((_d = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _d.defaultEndpoint) {
|
|
1059
|
-
url.searchParams.set("u", runConfig.inspector.defaultEndpoint);
|
|
1060
|
-
}
|
|
1061
|
-
return url.href;
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
883
|
// src/actor/router.ts
|
|
1065
884
|
function createActorRouter(runConfig, actorDriver) {
|
|
1066
885
|
const router = new Hono({ strict: false });
|
|
@@ -1073,17 +892,54 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1073
892
|
router.get("/health", (c) => {
|
|
1074
893
|
return c.text("ok");
|
|
1075
894
|
});
|
|
895
|
+
router.post("/.test/force-disconnect", async (c) => {
|
|
896
|
+
const connId = c.req.query("conn");
|
|
897
|
+
if (!connId) {
|
|
898
|
+
return c.text("Missing conn query parameter", 400);
|
|
899
|
+
}
|
|
900
|
+
const actor2 = await actorDriver.loadActor(c.env.actorId);
|
|
901
|
+
const conn = actor2.__getConnForId(connId);
|
|
902
|
+
if (!conn) {
|
|
903
|
+
return c.text(`Connection not found: ${connId}`, 404);
|
|
904
|
+
}
|
|
905
|
+
const driverState = conn.__driverState;
|
|
906
|
+
if (driverState && 0 /* WEBSOCKET */ in driverState) {
|
|
907
|
+
const ws = driverState[0 /* WEBSOCKET */].websocket;
|
|
908
|
+
ws.raw.terminate();
|
|
909
|
+
} else if (driverState && 1 /* SSE */ in driverState) {
|
|
910
|
+
const stream = driverState[1 /* SSE */].stream;
|
|
911
|
+
stream.abort();
|
|
912
|
+
}
|
|
913
|
+
return c.json({ success: true });
|
|
914
|
+
});
|
|
1076
915
|
router.get(PATH_CONNECT_WEBSOCKET, async (c) => {
|
|
1077
916
|
var _a;
|
|
1078
917
|
const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
|
|
1079
918
|
if (upgradeWebSocket) {
|
|
1080
919
|
return upgradeWebSocket(async (c2) => {
|
|
1081
|
-
const
|
|
1082
|
-
|
|
1083
|
-
|
|
920
|
+
const protocols = c2.req.header("sec-websocket-protocol");
|
|
921
|
+
let encodingRaw;
|
|
922
|
+
let connParamsRaw;
|
|
923
|
+
let connIdRaw;
|
|
924
|
+
let connTokenRaw;
|
|
925
|
+
if (protocols) {
|
|
926
|
+
const protocolList = protocols.split(",").map((p) => p.trim());
|
|
927
|
+
for (const protocol of protocolList) {
|
|
928
|
+
if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
|
|
929
|
+
encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
|
|
930
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
|
|
931
|
+
connParamsRaw = decodeURIComponent(
|
|
932
|
+
protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
|
|
933
|
+
);
|
|
934
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
|
|
935
|
+
connIdRaw = protocol.substring(WS_PROTOCOL_CONN_ID.length);
|
|
936
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
|
|
937
|
+
connTokenRaw = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
1084
941
|
const encoding = EncodingSchema.parse(encodingRaw);
|
|
1085
942
|
const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
|
|
1086
|
-
const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
|
|
1087
943
|
return await handleWebSocketConnect(
|
|
1088
944
|
c2.req.raw,
|
|
1089
945
|
runConfig,
|
|
@@ -1091,7 +947,8 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1091
947
|
c2.env.actorId,
|
|
1092
948
|
encoding,
|
|
1093
949
|
connParams,
|
|
1094
|
-
|
|
950
|
+
connIdRaw,
|
|
951
|
+
connTokenRaw
|
|
1095
952
|
);
|
|
1096
953
|
})(c, noopNext());
|
|
1097
954
|
} else {
|
|
@@ -1102,36 +959,34 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1102
959
|
}
|
|
1103
960
|
});
|
|
1104
961
|
router.get("/connect/sse", async (c) => {
|
|
1105
|
-
|
|
1106
|
-
let authData;
|
|
1107
|
-
if (authDataRaw) {
|
|
1108
|
-
authData = JSON.parse(authDataRaw);
|
|
1109
|
-
}
|
|
1110
|
-
return handleSseConnect(c, runConfig, actorDriver, c.env.actorId, authData);
|
|
962
|
+
return handleSseConnect(c, runConfig, actorDriver, c.env.actorId);
|
|
1111
963
|
});
|
|
1112
964
|
router.post("/action/:action", async (c) => {
|
|
1113
965
|
const actionName = c.req.param("action");
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
966
|
+
return handleAction(c, runConfig, actorDriver, actionName, c.env.actorId);
|
|
967
|
+
});
|
|
968
|
+
router.post("/connections/message", async (c) => {
|
|
969
|
+
const connId = c.req.header(HEADER_CONN_ID);
|
|
970
|
+
const connToken = c.req.header(HEADER_CONN_TOKEN);
|
|
971
|
+
if (!connId || !connToken) {
|
|
972
|
+
throw new Error("Missing required parameters");
|
|
1118
973
|
}
|
|
1119
|
-
return
|
|
974
|
+
return handleConnectionMessage(
|
|
1120
975
|
c,
|
|
1121
976
|
runConfig,
|
|
1122
977
|
actorDriver,
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
978
|
+
connId,
|
|
979
|
+
connToken,
|
|
980
|
+
c.env.actorId
|
|
1126
981
|
);
|
|
1127
982
|
});
|
|
1128
|
-
router.post("/connections/
|
|
983
|
+
router.post("/connections/close", async (c) => {
|
|
1129
984
|
const connId = c.req.header(HEADER_CONN_ID);
|
|
1130
985
|
const connToken = c.req.header(HEADER_CONN_TOKEN);
|
|
1131
986
|
if (!connId || !connToken) {
|
|
1132
987
|
throw new Error("Missing required parameters");
|
|
1133
988
|
}
|
|
1134
|
-
return
|
|
989
|
+
return handleConnectionClose(
|
|
1135
990
|
c,
|
|
1136
991
|
runConfig,
|
|
1137
992
|
actorDriver,
|
|
@@ -1141,11 +996,6 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1141
996
|
);
|
|
1142
997
|
});
|
|
1143
998
|
router.all("/raw/http/*", async (c) => {
|
|
1144
|
-
const authDataRaw = c.req.header(HEADER_AUTH_DATA);
|
|
1145
|
-
let authData;
|
|
1146
|
-
if (authDataRaw) {
|
|
1147
|
-
authData = JSON.parse(authDataRaw);
|
|
1148
|
-
}
|
|
1149
999
|
const actor2 = await actorDriver.loadActor(c.env.actorId);
|
|
1150
1000
|
const url = new URL(c.req.url);
|
|
1151
1001
|
const originalPath = url.pathname.replace(/^\/raw\/http/, "") || "/";
|
|
@@ -1161,9 +1011,7 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1161
1011
|
from: c.req.url,
|
|
1162
1012
|
to: correctedRequest.url
|
|
1163
1013
|
});
|
|
1164
|
-
const response = await actor2.handleFetch(correctedRequest, {
|
|
1165
|
-
auth: authData
|
|
1166
|
-
});
|
|
1014
|
+
const response = await actor2.handleFetch(correctedRequest, {});
|
|
1167
1015
|
if (!response) {
|
|
1168
1016
|
throw new InternalError("handleFetch returned void unexpectedly");
|
|
1169
1017
|
}
|
|
@@ -1174,12 +1022,6 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1174
1022
|
const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
|
|
1175
1023
|
if (upgradeWebSocket) {
|
|
1176
1024
|
return upgradeWebSocket(async (c2) => {
|
|
1177
|
-
const encodingRaw = c2.req.header(HEADER_ENCODING);
|
|
1178
|
-
const connParamsRaw = c2.req.header(HEADER_CONN_PARAMS);
|
|
1179
|
-
const authDataRaw = c2.req.header(HEADER_AUTH_DATA);
|
|
1180
|
-
const encoding = EncodingSchema.parse(encodingRaw);
|
|
1181
|
-
const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
|
|
1182
|
-
const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
|
|
1183
1025
|
const url = new URL(c2.req.url);
|
|
1184
1026
|
const pathWithQuery = c2.req.path + url.search;
|
|
1185
1027
|
loggerWithoutContext().debug({
|
|
@@ -1193,8 +1035,7 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1193
1035
|
c2.req.raw,
|
|
1194
1036
|
pathWithQuery,
|
|
1195
1037
|
actorDriver,
|
|
1196
|
-
c2.env.actorId
|
|
1197
|
-
authData
|
|
1038
|
+
c2.env.actorId
|
|
1198
1039
|
);
|
|
1199
1040
|
})(c, noopNext());
|
|
1200
1041
|
} else {
|
|
@@ -1204,7 +1045,7 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1204
1045
|
);
|
|
1205
1046
|
}
|
|
1206
1047
|
});
|
|
1207
|
-
if (runConfig
|
|
1048
|
+
if (isInspectorEnabled(runConfig, "actor")) {
|
|
1208
1049
|
router.route(
|
|
1209
1050
|
"/inspect",
|
|
1210
1051
|
new Hono().use(
|
|
@@ -1212,7 +1053,7 @@ function createActorRouter(runConfig, actorDriver) {
|
|
|
1212
1053
|
secureInspector(runConfig),
|
|
1213
1054
|
async (c, next) => {
|
|
1214
1055
|
const inspector = (await actorDriver.loadActor(c.env.actorId)).inspector;
|
|
1215
|
-
|
|
1056
|
+
invariant2(inspector, "inspector not supported on this platform");
|
|
1216
1057
|
c.set("inspector", inspector);
|
|
1217
1058
|
return next();
|
|
1218
1059
|
}
|
|
@@ -1570,8 +1411,9 @@ var InlineWebSocketAdapter2 = class {
|
|
|
1570
1411
|
// src/drivers/engine/actor-driver.ts
|
|
1571
1412
|
import { Runner } from "@rivetkit/engine-runner";
|
|
1572
1413
|
import * as cbor3 from "cbor-x";
|
|
1414
|
+
import { streamSSE as streamSSE2 } from "hono/streaming";
|
|
1573
1415
|
import { WSContext as WSContext2 } from "hono/ws";
|
|
1574
|
-
import
|
|
1416
|
+
import invariant3 from "invariant";
|
|
1575
1417
|
|
|
1576
1418
|
// src/drivers/engine/kv.ts
|
|
1577
1419
|
var KEYS = {
|
|
@@ -1595,6 +1437,8 @@ var EngineActorDriver = class {
|
|
|
1595
1437
|
#actorRouter;
|
|
1596
1438
|
#version = 1;
|
|
1597
1439
|
// Version for the runner protocol
|
|
1440
|
+
#runnerStarted = Promise.withResolvers();
|
|
1441
|
+
#runnerStopped = Promise.withResolvers();
|
|
1598
1442
|
constructor(registryConfig, runConfig, managerDriver, inlineClient, config2) {
|
|
1599
1443
|
this.#registryConfig = registryConfig;
|
|
1600
1444
|
this.#runConfig = runConfig;
|
|
@@ -1606,6 +1450,7 @@ var EngineActorDriver = class {
|
|
|
1606
1450
|
const runnerConfig = {
|
|
1607
1451
|
version: this.#version,
|
|
1608
1452
|
endpoint: config2.endpoint,
|
|
1453
|
+
token: config2.token,
|
|
1609
1454
|
pegboardEndpoint: config2.pegboardEndpoint,
|
|
1610
1455
|
namespace: config2.namespace,
|
|
1611
1456
|
totalSlots: config2.totalSlots,
|
|
@@ -1634,6 +1479,7 @@ var EngineActorDriver = class {
|
|
|
1634
1479
|
runnerName: this.#config.runnerName
|
|
1635
1480
|
});
|
|
1636
1481
|
}
|
|
1482
|
+
this.#runnerStarted.resolve(void 0);
|
|
1637
1483
|
},
|
|
1638
1484
|
onDisconnected: () => {
|
|
1639
1485
|
logger4().warn({
|
|
@@ -1644,6 +1490,7 @@ var EngineActorDriver = class {
|
|
|
1644
1490
|
hasDisconnected = true;
|
|
1645
1491
|
},
|
|
1646
1492
|
onShutdown: () => {
|
|
1493
|
+
this.#runnerStopped.resolve(void 0);
|
|
1647
1494
|
},
|
|
1648
1495
|
fetch: this.#runnerFetch.bind(this),
|
|
1649
1496
|
websocket: this.#runnerWebSocket.bind(this),
|
|
@@ -1672,13 +1519,6 @@ var EngineActorDriver = class {
|
|
|
1672
1519
|
if (!handler.actor) throw new Error(`Actor ${actorId} failed to load`);
|
|
1673
1520
|
return handler.actor;
|
|
1674
1521
|
}
|
|
1675
|
-
getGenericConnGlobalState(actorId) {
|
|
1676
|
-
const handler = this.#actors.get(actorId);
|
|
1677
|
-
if (!handler) {
|
|
1678
|
-
throw new Error(`Actor ${actorId} not loaded`);
|
|
1679
|
-
}
|
|
1680
|
-
return handler.genericConnGlobalState;
|
|
1681
|
-
}
|
|
1682
1522
|
getContext(actorId) {
|
|
1683
1523
|
return {};
|
|
1684
1524
|
}
|
|
@@ -1722,14 +1562,13 @@ var EngineActorDriver = class {
|
|
|
1722
1562
|
let handler = this.#actors.get(actorId);
|
|
1723
1563
|
if (!handler) {
|
|
1724
1564
|
handler = {
|
|
1725
|
-
|
|
1726
|
-
actorStartPromise: Promise.withResolvers(),
|
|
1565
|
+
actorStartPromise: promiseWithResolvers(),
|
|
1727
1566
|
persistedData: serializeEmptyPersistData(input)
|
|
1728
1567
|
};
|
|
1729
1568
|
this.#actors.set(actorId, handler);
|
|
1730
1569
|
}
|
|
1731
1570
|
const name = config2.name;
|
|
1732
|
-
|
|
1571
|
+
invariant3(config2.key, "actor should have a key");
|
|
1733
1572
|
const key = deserializeActorKey(config2.key);
|
|
1734
1573
|
const definition = lookupInRegistry(
|
|
1735
1574
|
this.#registryConfig,
|
|
@@ -1737,11 +1576,7 @@ var EngineActorDriver = class {
|
|
|
1737
1576
|
// TODO: Remove cast
|
|
1738
1577
|
);
|
|
1739
1578
|
handler.actor = definition.instantiate();
|
|
1740
|
-
const connDrivers = createGenericConnDrivers(
|
|
1741
|
-
handler.genericConnGlobalState
|
|
1742
|
-
);
|
|
1743
1579
|
await handler.actor.start(
|
|
1744
|
-
connDrivers,
|
|
1745
1580
|
this,
|
|
1746
1581
|
this.#inlineClient,
|
|
1747
1582
|
actorId,
|
|
@@ -1776,12 +1611,25 @@ var EngineActorDriver = class {
|
|
|
1776
1611
|
const websocket = websocketRaw;
|
|
1777
1612
|
logger4().debug({ msg: "runner websocket", actorId, url: request.url });
|
|
1778
1613
|
const url = new URL(request.url);
|
|
1779
|
-
const
|
|
1780
|
-
|
|
1781
|
-
|
|
1614
|
+
const protocols = request.headers.get("sec-websocket-protocol");
|
|
1615
|
+
if (protocols === null)
|
|
1616
|
+
throw new Error(`Missing sec-websocket-protocol header`);
|
|
1617
|
+
let encodingRaw;
|
|
1618
|
+
let connParamsRaw;
|
|
1619
|
+
if (protocols) {
|
|
1620
|
+
const protocolList = protocols.split(",").map((p) => p.trim());
|
|
1621
|
+
for (const protocol of protocolList) {
|
|
1622
|
+
if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
|
|
1623
|
+
encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
|
|
1624
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
|
|
1625
|
+
connParamsRaw = decodeURIComponent(
|
|
1626
|
+
protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
|
|
1627
|
+
);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1782
1631
|
const encoding = EncodingSchema.parse(encodingRaw);
|
|
1783
1632
|
const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
|
|
1784
|
-
const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
|
|
1785
1633
|
let wsHandlerPromise;
|
|
1786
1634
|
if (url.pathname === PATH_CONNECT_WEBSOCKET) {
|
|
1787
1635
|
wsHandlerPromise = handleWebSocketConnect(
|
|
@@ -1791,15 +1639,16 @@ var EngineActorDriver = class {
|
|
|
1791
1639
|
actorId,
|
|
1792
1640
|
encoding,
|
|
1793
1641
|
connParams,
|
|
1794
|
-
|
|
1642
|
+
// Extract connId and connToken from protocols if needed
|
|
1643
|
+
void 0,
|
|
1644
|
+
void 0
|
|
1795
1645
|
);
|
|
1796
1646
|
} else if (url.pathname.startsWith(PATH_RAW_WEBSOCKET_PREFIX)) {
|
|
1797
1647
|
wsHandlerPromise = handleRawWebSocketHandler(
|
|
1798
1648
|
request,
|
|
1799
1649
|
url.pathname + url.search,
|
|
1800
1650
|
this,
|
|
1801
|
-
actorId
|
|
1802
|
-
authData
|
|
1651
|
+
actorId
|
|
1803
1652
|
);
|
|
1804
1653
|
} else {
|
|
1805
1654
|
throw new Error(`Unreachable path: ${url.pathname}`);
|
|
@@ -1848,6 +1697,15 @@ var EngineActorDriver = class {
|
|
|
1848
1697
|
logger4().info({ msg: "stopping engine actor driver" });
|
|
1849
1698
|
await this.#runner.shutdown(immediate);
|
|
1850
1699
|
}
|
|
1700
|
+
async serverlessHandleStart(c) {
|
|
1701
|
+
await this.#runnerStarted.promise;
|
|
1702
|
+
return streamSSE2(c, async (stream) => {
|
|
1703
|
+
const runnerId = this.#runner.runnerId;
|
|
1704
|
+
invariant3(runnerId, "runnerId not set");
|
|
1705
|
+
stream.writeSSE({ data: runnerId });
|
|
1706
|
+
return this.#runnerStopped.promise;
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1851
1709
|
};
|
|
1852
1710
|
|
|
1853
1711
|
// src/drivers/engine/config.ts
|
|
@@ -1857,6 +1715,7 @@ var ConfigSchema = z2.object({
|
|
|
1857
1715
|
endpoint: z2.string().default(
|
|
1858
1716
|
() => getEnvUniversal("RIVET_ENGINE") ?? "http://localhost:6420"
|
|
1859
1717
|
),
|
|
1718
|
+
token: z2.string().optional().transform((val) => val ?? getEnvUniversal("RIVET_TOKEN")),
|
|
1860
1719
|
pegboardEndpoint: z2.string().optional(),
|
|
1861
1720
|
namespace: z2.string().default(() => getEnvUniversal("RIVET_NAMESPACE") ?? "default"),
|
|
1862
1721
|
runnerName: z2.string().default(() => getEnvUniversal("RIVET_RUNNER") ?? "rivetkit"),
|
|
@@ -1910,9 +1769,6 @@ var FileSystemActorDriver = class {
|
|
|
1910
1769
|
actorId
|
|
1911
1770
|
);
|
|
1912
1771
|
}
|
|
1913
|
-
getGenericConnGlobalState(actorId) {
|
|
1914
|
-
return this.#state.getActorOrError(actorId).genericConnGlobalState;
|
|
1915
|
-
}
|
|
1916
1772
|
/**
|
|
1917
1773
|
* Get the current storage directory path
|
|
1918
1774
|
*/
|
|
@@ -1946,11 +1802,11 @@ var FileSystemActorDriver = class {
|
|
|
1946
1802
|
};
|
|
1947
1803
|
|
|
1948
1804
|
// src/drivers/file-system/global-state.ts
|
|
1949
|
-
import * as
|
|
1805
|
+
import * as crypto3 from "crypto";
|
|
1950
1806
|
import * as fsSync2 from "fs";
|
|
1951
1807
|
import * as fs2 from "fs/promises";
|
|
1952
1808
|
import * as path2 from "path";
|
|
1953
|
-
import
|
|
1809
|
+
import invariant4 from "invariant";
|
|
1954
1810
|
|
|
1955
1811
|
// dist/schemas/file-system-driver/v1.ts
|
|
1956
1812
|
import * as bare from "@bare-ts/lib";
|
|
@@ -2053,20 +1909,20 @@ function logger5() {
|
|
|
2053
1909
|
}
|
|
2054
1910
|
|
|
2055
1911
|
// src/drivers/file-system/utils.ts
|
|
2056
|
-
import * as
|
|
1912
|
+
import * as crypto2 from "crypto";
|
|
2057
1913
|
import * as fsSync from "fs";
|
|
2058
1914
|
import * as fs from "fs/promises";
|
|
2059
1915
|
import * as os from "os";
|
|
2060
1916
|
import * as path from "path";
|
|
2061
1917
|
function generateActorId(name, key) {
|
|
2062
1918
|
const jsonString = JSON.stringify([name, key]);
|
|
2063
|
-
const hash =
|
|
1919
|
+
const hash = crypto2.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
|
|
2064
1920
|
return hash;
|
|
2065
1921
|
}
|
|
2066
1922
|
function createHashForPath(dirPath) {
|
|
2067
1923
|
const normalizedPath = path.normalize(dirPath);
|
|
2068
1924
|
const lastComponent = path.basename(normalizedPath);
|
|
2069
|
-
const hash =
|
|
1925
|
+
const hash = crypto2.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
|
|
2070
1926
|
return `${lastComponent}-${hash}`;
|
|
2071
1927
|
}
|
|
2072
1928
|
function getStoragePath(customPath) {
|
|
@@ -2201,7 +2057,6 @@ var FileSystemGlobalState = class {
|
|
|
2201
2057
|
}
|
|
2202
2058
|
entry = {
|
|
2203
2059
|
id: actorId,
|
|
2204
|
-
genericConnGlobalState: new GenericConnGlobalState(),
|
|
2205
2060
|
removed: false
|
|
2206
2061
|
};
|
|
2207
2062
|
this.#actors.set(actorId, entry);
|
|
@@ -2276,16 +2131,16 @@ var FileSystemGlobalState = class {
|
|
|
2276
2131
|
}
|
|
2277
2132
|
async sleepActor(actorId) {
|
|
2278
2133
|
var _a;
|
|
2279
|
-
|
|
2134
|
+
invariant4(
|
|
2280
2135
|
this.#persist,
|
|
2281
2136
|
"cannot sleep actor with memory driver, must use file system driver"
|
|
2282
2137
|
);
|
|
2283
2138
|
const actor2 = this.#actors.get(actorId);
|
|
2284
|
-
|
|
2139
|
+
invariant4(actor2, `tried to sleep ${actorId}, does not exist`);
|
|
2285
2140
|
if (actor2.loadPromise) await actor2.loadPromise.catch();
|
|
2286
2141
|
if ((_a = actor2.startPromise) == null ? void 0 : _a.promise) await actor2.startPromise.promise.catch();
|
|
2287
2142
|
actor2.removed = true;
|
|
2288
|
-
|
|
2143
|
+
invariant4(actor2.actor, "actor should be loaded");
|
|
2289
2144
|
await actor2.actor._stop();
|
|
2290
2145
|
this.#actors.delete(actorId);
|
|
2291
2146
|
}
|
|
@@ -2297,15 +2152,15 @@ var FileSystemGlobalState = class {
|
|
|
2297
2152
|
return;
|
|
2298
2153
|
}
|
|
2299
2154
|
const entry = this.#actors.get(actorId);
|
|
2300
|
-
|
|
2155
|
+
invariant4(entry, "actor entry does not exist");
|
|
2301
2156
|
await this.#performWrite(actorId, state);
|
|
2302
2157
|
}
|
|
2303
2158
|
async setActorAlarm(actorId, timestamp) {
|
|
2304
2159
|
const entry = this.#actors.get(actorId);
|
|
2305
|
-
|
|
2160
|
+
invariant4(entry, "actor entry does not exist");
|
|
2306
2161
|
if (this.#persist) {
|
|
2307
2162
|
const alarmPath = this.getActorAlarmPath(actorId);
|
|
2308
|
-
const tempPath = `${alarmPath}.tmp.${
|
|
2163
|
+
const tempPath = `${alarmPath}.tmp.${crypto3.randomUUID()}`;
|
|
2309
2164
|
try {
|
|
2310
2165
|
await ensureDirectoryExists(path2.dirname(alarmPath));
|
|
2311
2166
|
const alarmData = {
|
|
@@ -2331,7 +2186,7 @@ var FileSystemGlobalState = class {
|
|
|
2331
2186
|
*/
|
|
2332
2187
|
async #performWrite(actorId, state) {
|
|
2333
2188
|
const dataPath = this.getActorStatePath(actorId);
|
|
2334
|
-
const tempPath = `${dataPath}.tmp.${
|
|
2189
|
+
const tempPath = `${dataPath}.tmp.${crypto3.randomUUID()}`;
|
|
2335
2190
|
try {
|
|
2336
2191
|
await ensureDirectoryExists(path2.dirname(dataPath));
|
|
2337
2192
|
const bareState = {
|
|
@@ -2386,21 +2241,17 @@ var FileSystemGlobalState = class {
|
|
|
2386
2241
|
}
|
|
2387
2242
|
if (entry.startPromise) {
|
|
2388
2243
|
await entry.startPromise.promise;
|
|
2389
|
-
|
|
2244
|
+
invariant4(entry.actor, "actor should have loaded");
|
|
2390
2245
|
return entry.actor;
|
|
2391
2246
|
}
|
|
2392
2247
|
if (entry.actor) {
|
|
2393
2248
|
return entry.actor;
|
|
2394
2249
|
}
|
|
2395
|
-
entry.startPromise =
|
|
2250
|
+
entry.startPromise = promiseWithResolvers();
|
|
2396
2251
|
try {
|
|
2397
2252
|
const definition = lookupInRegistry(registryConfig, entry.state.name);
|
|
2398
2253
|
entry.actor = definition.instantiate();
|
|
2399
|
-
const connDrivers = createGenericConnDrivers(
|
|
2400
|
-
entry.genericConnGlobalState
|
|
2401
|
-
);
|
|
2402
2254
|
await entry.actor.start(
|
|
2403
|
-
connDrivers,
|
|
2404
2255
|
actorDriver,
|
|
2405
2256
|
inlineClient,
|
|
2406
2257
|
actorId,
|
|
@@ -2505,7 +2356,7 @@ var FileSystemGlobalState = class {
|
|
|
2505
2356
|
const loaded = await this.loadActor(actorId);
|
|
2506
2357
|
if (!loaded.state) throw new Error(`Actor does not exist: ${actorId}`);
|
|
2507
2358
|
const runnerParams = this.#runnerParams;
|
|
2508
|
-
|
|
2359
|
+
invariant4(runnerParams, "missing runner params");
|
|
2509
2360
|
if (!loaded.actor) {
|
|
2510
2361
|
await this.startActor(
|
|
2511
2362
|
runnerParams.registryConfig,
|
|
@@ -2515,7 +2366,7 @@ var FileSystemGlobalState = class {
|
|
|
2515
2366
|
actorId
|
|
2516
2367
|
);
|
|
2517
2368
|
}
|
|
2518
|
-
|
|
2369
|
+
invariant4(loaded.actor, "actor should be loaded after wake");
|
|
2519
2370
|
await loaded.actor._onAlarm();
|
|
2520
2371
|
} catch (err) {
|
|
2521
2372
|
logger5().error({
|
|
@@ -2572,7 +2423,7 @@ var FileSystemGlobalState = class {
|
|
|
2572
2423
|
};
|
|
2573
2424
|
|
|
2574
2425
|
// src/drivers/file-system/manager.ts
|
|
2575
|
-
import
|
|
2426
|
+
import invariant5 from "invariant";
|
|
2576
2427
|
|
|
2577
2428
|
// src/inspector/manager.ts
|
|
2578
2429
|
import { sValidator } from "@hono/standard-validator";
|
|
@@ -2658,9 +2509,6 @@ var FileSystemManagerDriver = class {
|
|
|
2658
2509
|
};
|
|
2659
2510
|
};
|
|
2660
2511
|
var transformActor = transformActor2;
|
|
2661
|
-
if (!this.#runConfig.inspector.token()) {
|
|
2662
|
-
this.#runConfig.inspector.token = () => this.#state.getOrCreateInspectorAccessToken();
|
|
2663
|
-
}
|
|
2664
2512
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2665
2513
|
this.inspector = new ManagerInspector(() => {
|
|
2666
2514
|
return {
|
|
@@ -2714,7 +2562,7 @@ var FileSystemManagerDriver = class {
|
|
|
2714
2562
|
actorId
|
|
2715
2563
|
});
|
|
2716
2564
|
}
|
|
2717
|
-
async openWebSocket(path3, actorId, encoding, params) {
|
|
2565
|
+
async openWebSocket(path3, actorId, encoding, params, connId, connToken) {
|
|
2718
2566
|
const pathOnly = path3.split("?")[0];
|
|
2719
2567
|
const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
|
|
2720
2568
|
if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
|
|
@@ -2725,7 +2573,8 @@ var FileSystemManagerDriver = class {
|
|
|
2725
2573
|
actorId,
|
|
2726
2574
|
encoding,
|
|
2727
2575
|
params,
|
|
2728
|
-
|
|
2576
|
+
connId,
|
|
2577
|
+
connToken
|
|
2729
2578
|
);
|
|
2730
2579
|
return new InlineWebSocketAdapter2(wsHandler);
|
|
2731
2580
|
} else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
|
|
@@ -2733,8 +2582,7 @@ var FileSystemManagerDriver = class {
|
|
|
2733
2582
|
void 0,
|
|
2734
2583
|
path3,
|
|
2735
2584
|
this.#actorDriver,
|
|
2736
|
-
actorId
|
|
2737
|
-
void 0
|
|
2585
|
+
actorId
|
|
2738
2586
|
);
|
|
2739
2587
|
return new InlineWebSocketAdapter2(wsHandler);
|
|
2740
2588
|
} else {
|
|
@@ -2746,10 +2594,10 @@ var FileSystemManagerDriver = class {
|
|
|
2746
2594
|
actorId
|
|
2747
2595
|
});
|
|
2748
2596
|
}
|
|
2749
|
-
async proxyWebSocket(c, path3, actorId, encoding, connParams) {
|
|
2597
|
+
async proxyWebSocket(c, path3, actorId, encoding, connParams, connId, connToken) {
|
|
2750
2598
|
var _a, _b;
|
|
2751
2599
|
const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
|
|
2752
|
-
|
|
2600
|
+
invariant5(upgradeWebSocket, "missing getUpgradeWebSocket");
|
|
2753
2601
|
const pathOnly = path3.split("?")[0];
|
|
2754
2602
|
const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
|
|
2755
2603
|
if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
|
|
@@ -2760,7 +2608,8 @@ var FileSystemManagerDriver = class {
|
|
|
2760
2608
|
actorId,
|
|
2761
2609
|
encoding,
|
|
2762
2610
|
connParams,
|
|
2763
|
-
|
|
2611
|
+
connId,
|
|
2612
|
+
connToken
|
|
2764
2613
|
);
|
|
2765
2614
|
return upgradeWebSocket(() => wsHandler)(c, noopNext());
|
|
2766
2615
|
} else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
|
|
@@ -2768,8 +2617,7 @@ var FileSystemManagerDriver = class {
|
|
|
2768
2617
|
c.req.raw,
|
|
2769
2618
|
path3,
|
|
2770
2619
|
this.#actorDriver,
|
|
2771
|
-
actorId
|
|
2772
|
-
void 0
|
|
2620
|
+
actorId
|
|
2773
2621
|
);
|
|
2774
2622
|
return upgradeWebSocket(() => wsHandler)(c, noopNext());
|
|
2775
2623
|
} else {
|
|
@@ -2815,7 +2663,7 @@ var FileSystemManagerDriver = class {
|
|
|
2815
2663
|
input.key,
|
|
2816
2664
|
input.input
|
|
2817
2665
|
);
|
|
2818
|
-
|
|
2666
|
+
invariant5(actorEntry.state, "must have state");
|
|
2819
2667
|
return {
|
|
2820
2668
|
actorId: actorEntry.state.actorId,
|
|
2821
2669
|
name: actorEntry.state.name,
|
|
@@ -2846,6 +2694,9 @@ var FileSystemManagerDriver = class {
|
|
|
2846
2694
|
data: this.#state.storagePath
|
|
2847
2695
|
};
|
|
2848
2696
|
}
|
|
2697
|
+
getOrCreateInspectorAccessToken() {
|
|
2698
|
+
return this.#state.getOrCreateInspectorAccessToken();
|
|
2699
|
+
}
|
|
2849
2700
|
};
|
|
2850
2701
|
|
|
2851
2702
|
// src/drivers/file-system/mod.ts
|
|
@@ -2882,8 +2733,7 @@ function createMemoryDriver() {
|
|
|
2882
2733
|
|
|
2883
2734
|
// src/drivers/default.ts
|
|
2884
2735
|
function chooseDefaultDriver(runConfig) {
|
|
2885
|
-
|
|
2886
|
-
if (engineEndpoint && runConfig.driver) {
|
|
2736
|
+
if (runConfig.endpoint && runConfig.driver) {
|
|
2887
2737
|
throw new UserError(
|
|
2888
2738
|
"Cannot specify both 'engine' and 'driver' in configuration"
|
|
2889
2739
|
);
|
|
@@ -2891,12 +2741,15 @@ function chooseDefaultDriver(runConfig) {
|
|
|
2891
2741
|
if (runConfig.driver) {
|
|
2892
2742
|
return runConfig.driver;
|
|
2893
2743
|
}
|
|
2894
|
-
if (
|
|
2744
|
+
if (runConfig.endpoint) {
|
|
2895
2745
|
loggerWithoutContext().debug({
|
|
2896
2746
|
msg: "using rivet engine driver",
|
|
2897
|
-
endpoint:
|
|
2747
|
+
endpoint: runConfig.endpoint
|
|
2748
|
+
});
|
|
2749
|
+
return createEngineDriver({
|
|
2750
|
+
endpoint: runConfig.endpoint,
|
|
2751
|
+
token: runConfig.token
|
|
2898
2752
|
});
|
|
2899
|
-
return createEngineDriver({ endpoint: engineEndpoint });
|
|
2900
2753
|
}
|
|
2901
2754
|
loggerWithoutContext().debug({ msg: "using default file system driver" });
|
|
2902
2755
|
return createFileSystemOrMemoryDriver(true);
|
|
@@ -2905,32 +2758,37 @@ function chooseDefaultDriver(runConfig) {
|
|
|
2905
2758
|
// src/manager/router.ts
|
|
2906
2759
|
import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
|
|
2907
2760
|
import * as cbor4 from "cbor-x";
|
|
2908
|
-
import {
|
|
2761
|
+
import {
|
|
2762
|
+
Hono as Hono3
|
|
2763
|
+
} from "hono";
|
|
2909
2764
|
import { cors as corsMiddleware } from "hono/cors";
|
|
2910
|
-
import { createMiddleware
|
|
2911
|
-
import
|
|
2912
|
-
import { z as
|
|
2765
|
+
import { createMiddleware } from "hono/factory";
|
|
2766
|
+
import invariant6 from "invariant";
|
|
2767
|
+
import { z as z5 } from "zod";
|
|
2913
2768
|
|
|
2914
|
-
// src/manager-api/
|
|
2769
|
+
// src/manager-api/actors.ts
|
|
2915
2770
|
import { z as z4 } from "zod";
|
|
2916
2771
|
|
|
2917
|
-
// src/manager-api/
|
|
2772
|
+
// src/manager-api/common.ts
|
|
2918
2773
|
import { z as z3 } from "zod";
|
|
2919
2774
|
var RivetIdSchema = z3.string();
|
|
2920
|
-
|
|
2775
|
+
|
|
2776
|
+
// src/manager-api/actors.ts
|
|
2777
|
+
var ActorSchema = z4.object({
|
|
2921
2778
|
actor_id: RivetIdSchema,
|
|
2922
|
-
name:
|
|
2923
|
-
key:
|
|
2779
|
+
name: z4.string(),
|
|
2780
|
+
key: z4.string(),
|
|
2924
2781
|
namespace_id: RivetIdSchema,
|
|
2925
|
-
runner_name_selector:
|
|
2926
|
-
create_ts:
|
|
2927
|
-
connectable_ts:
|
|
2928
|
-
destroy_ts:
|
|
2929
|
-
sleep_ts:
|
|
2930
|
-
start_ts:
|
|
2782
|
+
runner_name_selector: z4.string(),
|
|
2783
|
+
create_ts: z4.number(),
|
|
2784
|
+
connectable_ts: z4.number().nullable().optional(),
|
|
2785
|
+
destroy_ts: z4.number().nullable().optional(),
|
|
2786
|
+
sleep_ts: z4.number().nullable().optional(),
|
|
2787
|
+
start_ts: z4.number().nullable().optional()
|
|
2788
|
+
});
|
|
2789
|
+
var ActorsListResponseSchema = z4.object({
|
|
2790
|
+
actors: z4.array(ActorSchema)
|
|
2931
2791
|
});
|
|
2932
|
-
|
|
2933
|
-
// src/manager-api/routes/actors-create.ts
|
|
2934
2792
|
var ActorsCreateRequestSchema = z4.object({
|
|
2935
2793
|
name: z4.string(),
|
|
2936
2794
|
runner_name_selector: z4.string(),
|
|
@@ -2941,169 +2799,426 @@ var ActorsCreateRequestSchema = z4.object({
|
|
|
2941
2799
|
var ActorsCreateResponseSchema = z4.object({
|
|
2942
2800
|
actor: ActorSchema
|
|
2943
2801
|
});
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
// src/manager-api/routes/actors-get-by-id.ts
|
|
2952
|
-
import { z as z6 } from "zod";
|
|
2953
|
-
var ActorsGetByIdResponseSchema = z6.object({
|
|
2954
|
-
actor_id: RivetIdSchema.nullable().optional()
|
|
2802
|
+
var ActorsGetOrCreateRequestSchema = z4.object({
|
|
2803
|
+
name: z4.string(),
|
|
2804
|
+
key: z4.string(),
|
|
2805
|
+
runner_name_selector: z4.string(),
|
|
2806
|
+
crash_policy: z4.string(),
|
|
2807
|
+
input: z4.string().nullable().optional()
|
|
2955
2808
|
});
|
|
2956
|
-
|
|
2957
|
-
// src/manager-api/routes/actors-get-or-create-by-id.ts
|
|
2958
|
-
import { z as z7 } from "zod";
|
|
2959
|
-
var ActorsGetOrCreateResponseSchema = z7.object({
|
|
2809
|
+
var ActorsGetOrCreateResponseSchema = z4.object({
|
|
2960
2810
|
actor: ActorSchema,
|
|
2961
|
-
created:
|
|
2962
|
-
});
|
|
2963
|
-
var ActorsGetOrCreateByIdResponseSchema = z7.object({
|
|
2964
|
-
actor_id: RivetIdSchema,
|
|
2965
|
-
created: z7.boolean()
|
|
2966
|
-
});
|
|
2967
|
-
var ActorsGetOrCreateByIdRequestSchema = z7.object({
|
|
2968
|
-
name: z7.string(),
|
|
2969
|
-
key: z7.string(),
|
|
2970
|
-
runner_name_selector: z7.string(),
|
|
2971
|
-
crash_policy: z7.string(),
|
|
2972
|
-
input: z7.string().nullable().optional()
|
|
2811
|
+
created: z4.boolean()
|
|
2973
2812
|
});
|
|
2813
|
+
var ActorsDeleteResponseSchema = z4.object({});
|
|
2974
2814
|
|
|
2975
|
-
// src/manager/
|
|
2976
|
-
function
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
} : {}
|
|
2985
|
-
},
|
|
2986
|
-
400: {
|
|
2987
|
-
description: "User error"
|
|
2988
|
-
},
|
|
2989
|
-
500: {
|
|
2990
|
-
description: "Internal error"
|
|
2991
|
-
}
|
|
2992
|
-
};
|
|
2815
|
+
// src/manager/gateway.ts
|
|
2816
|
+
async function actorGateway(runConfig, managerDriver, c, next) {
|
|
2817
|
+
if (c.req.path.startsWith("/.test/")) {
|
|
2818
|
+
return next();
|
|
2819
|
+
}
|
|
2820
|
+
if (c.req.header("upgrade") === "websocket") {
|
|
2821
|
+
return await handleWebSocketGateway(runConfig, managerDriver, c);
|
|
2822
|
+
}
|
|
2823
|
+
return await handleHttpGateway(managerDriver, c, next);
|
|
2993
2824
|
}
|
|
2994
|
-
function
|
|
2995
|
-
var _a
|
|
2996
|
-
const
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
const
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
})
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
}
|
|
3020
|
-
const encoding = c.req.header("X-RivetKit-Encoding") || c.req.header("x-rivet-encoding") || "json";
|
|
3021
|
-
const connParams = c.req.header("X-RivetKit-Conn-Params") || c.req.header("x-rivet-conn-params");
|
|
3022
|
-
const authData = c.req.header("X-RivetKit-Auth-Data") || c.req.header("x-rivet-auth-data");
|
|
3023
|
-
const pathWithQuery = c.req.url.includes("?") ? c.req.path + c.req.url.substring(c.req.url.indexOf("?")) : c.req.path;
|
|
3024
|
-
return await managerDriver.proxyWebSocket(
|
|
3025
|
-
c,
|
|
3026
|
-
pathWithQuery,
|
|
3027
|
-
actorId,
|
|
3028
|
-
encoding,
|
|
3029
|
-
// Will be validated by driver
|
|
3030
|
-
connParams ? JSON.parse(connParams) : void 0,
|
|
3031
|
-
authData ? JSON.parse(authData) : void 0
|
|
2825
|
+
async function handleWebSocketGateway(runConfig, managerDriver, c) {
|
|
2826
|
+
var _a;
|
|
2827
|
+
const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
|
|
2828
|
+
if (!upgradeWebSocket) {
|
|
2829
|
+
throw new WebSocketsNotEnabled();
|
|
2830
|
+
}
|
|
2831
|
+
const protocols = c.req.header("sec-websocket-protocol");
|
|
2832
|
+
let target;
|
|
2833
|
+
let actorId;
|
|
2834
|
+
let encodingRaw;
|
|
2835
|
+
let connParamsRaw;
|
|
2836
|
+
let connIdRaw;
|
|
2837
|
+
let connTokenRaw;
|
|
2838
|
+
if (protocols) {
|
|
2839
|
+
const protocolList = protocols.split(",").map((p) => p.trim());
|
|
2840
|
+
for (const protocol of protocolList) {
|
|
2841
|
+
if (protocol.startsWith(WS_PROTOCOL_TARGET)) {
|
|
2842
|
+
target = protocol.substring(WS_PROTOCOL_TARGET.length);
|
|
2843
|
+
} else if (protocol.startsWith(WS_PROTOCOL_ACTOR)) {
|
|
2844
|
+
actorId = protocol.substring(WS_PROTOCOL_ACTOR.length);
|
|
2845
|
+
} else if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
|
|
2846
|
+
encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
|
|
2847
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
|
|
2848
|
+
connParamsRaw = decodeURIComponent(
|
|
2849
|
+
protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
|
|
3032
2850
|
);
|
|
2851
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
|
|
2852
|
+
connIdRaw = protocol.substring(WS_PROTOCOL_CONN_ID.length);
|
|
2853
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
|
|
2854
|
+
connTokenRaw = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
|
|
3033
2855
|
}
|
|
3034
|
-
const proxyHeaders = new Headers(c.req.raw.headers);
|
|
3035
|
-
proxyHeaders.delete("x-rivet-target");
|
|
3036
|
-
proxyHeaders.delete("x-rivet-actor");
|
|
3037
|
-
const url = new URL(c.req.url);
|
|
3038
|
-
const proxyUrl = new URL(`http://actor${url.pathname}${url.search}`);
|
|
3039
|
-
const proxyRequest = new Request(proxyUrl, {
|
|
3040
|
-
method: c.req.raw.method,
|
|
3041
|
-
headers: proxyHeaders,
|
|
3042
|
-
body: c.req.raw.body,
|
|
3043
|
-
signal: c.req.raw.signal
|
|
3044
|
-
});
|
|
3045
|
-
return await managerDriver.proxyRequest(c, proxyRequest, actorId);
|
|
3046
2856
|
}
|
|
2857
|
+
}
|
|
2858
|
+
if (target !== "actor") {
|
|
2859
|
+
return c.text("WebSocket upgrade requires target.actor protocol", 400);
|
|
2860
|
+
}
|
|
2861
|
+
if (!actorId) {
|
|
2862
|
+
throw new MissingActorHeader();
|
|
2863
|
+
}
|
|
2864
|
+
logger().debug({
|
|
2865
|
+
msg: "proxying websocket to actor",
|
|
2866
|
+
actorId,
|
|
2867
|
+
path: c.req.path,
|
|
2868
|
+
encoding: encodingRaw
|
|
2869
|
+
});
|
|
2870
|
+
const encoding = encodingRaw || "json";
|
|
2871
|
+
const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
|
|
2872
|
+
const pathWithQuery = c.req.url.includes("?") ? c.req.path + c.req.url.substring(c.req.url.indexOf("?")) : c.req.path;
|
|
2873
|
+
return await managerDriver.proxyWebSocket(
|
|
2874
|
+
c,
|
|
2875
|
+
pathWithQuery,
|
|
2876
|
+
actorId,
|
|
2877
|
+
encoding,
|
|
2878
|
+
// Will be validated by driver
|
|
2879
|
+
connParams,
|
|
2880
|
+
connIdRaw,
|
|
2881
|
+
connTokenRaw
|
|
2882
|
+
);
|
|
2883
|
+
}
|
|
2884
|
+
async function handleHttpGateway(managerDriver, c, next) {
|
|
2885
|
+
const target = c.req.header(HEADER_RIVET_TARGET);
|
|
2886
|
+
const actorId = c.req.header(HEADER_RIVET_ACTOR);
|
|
2887
|
+
if (target !== "actor") {
|
|
3047
2888
|
return next();
|
|
2889
|
+
}
|
|
2890
|
+
if (!actorId) {
|
|
2891
|
+
throw new MissingActorHeader();
|
|
2892
|
+
}
|
|
2893
|
+
logger().debug({
|
|
2894
|
+
msg: "proxying request to actor",
|
|
2895
|
+
actorId,
|
|
2896
|
+
path: c.req.path,
|
|
2897
|
+
method: c.req.method
|
|
3048
2898
|
});
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
2899
|
+
const proxyHeaders = new Headers(c.req.raw.headers);
|
|
2900
|
+
proxyHeaders.delete(HEADER_RIVET_TARGET);
|
|
2901
|
+
proxyHeaders.delete(HEADER_RIVET_ACTOR);
|
|
2902
|
+
const url = new URL(c.req.url);
|
|
2903
|
+
const proxyUrl = new URL(`http://actor${url.pathname}${url.search}`);
|
|
2904
|
+
const proxyRequest = new Request(proxyUrl, {
|
|
2905
|
+
method: c.req.raw.method,
|
|
2906
|
+
headers: proxyHeaders,
|
|
2907
|
+
body: c.req.raw.body,
|
|
2908
|
+
signal: c.req.raw.signal
|
|
3053
2909
|
});
|
|
3054
|
-
|
|
3055
|
-
|
|
2910
|
+
return await managerDriver.proxyRequest(c, proxyRequest, actorId);
|
|
2911
|
+
}
|
|
2912
|
+
async function createTestWebSocketProxy(clientWsPromise) {
|
|
2913
|
+
let clientWs = null;
|
|
2914
|
+
const {
|
|
2915
|
+
promise: serverWsPromise,
|
|
2916
|
+
resolve: serverWsResolve,
|
|
2917
|
+
reject: serverWsReject
|
|
2918
|
+
} = promiseWithResolvers();
|
|
2919
|
+
try {
|
|
2920
|
+
logger().debug({ msg: "awaiting client websocket promise" });
|
|
2921
|
+
const ws = await clientWsPromise;
|
|
2922
|
+
clientWs = ws;
|
|
2923
|
+
logger().debug({
|
|
2924
|
+
msg: "client websocket promise resolved",
|
|
2925
|
+
constructor: ws == null ? void 0 : ws.constructor.name
|
|
2926
|
+
});
|
|
2927
|
+
await new Promise((resolve, reject) => {
|
|
2928
|
+
const onOpen = () => {
|
|
2929
|
+
logger().debug({ msg: "test websocket connection to actor opened" });
|
|
2930
|
+
resolve();
|
|
2931
|
+
};
|
|
2932
|
+
const onError = (error) => {
|
|
2933
|
+
logger().error({ msg: "test websocket connection failed", error });
|
|
2934
|
+
reject(
|
|
2935
|
+
new Error(`Failed to open WebSocket: ${error.message || error}`)
|
|
2936
|
+
);
|
|
2937
|
+
serverWsReject();
|
|
2938
|
+
};
|
|
2939
|
+
ws.addEventListener("open", onOpen);
|
|
2940
|
+
ws.addEventListener("error", onError);
|
|
2941
|
+
ws.addEventListener("message", async (clientEvt) => {
|
|
2942
|
+
var _a, _b;
|
|
2943
|
+
const serverWs = await serverWsPromise;
|
|
2944
|
+
logger().debug({
|
|
2945
|
+
msg: `test websocket connection message from client`,
|
|
2946
|
+
dataType: typeof clientEvt.data,
|
|
2947
|
+
isBlob: clientEvt.data instanceof Blob,
|
|
2948
|
+
isArrayBuffer: clientEvt.data instanceof ArrayBuffer,
|
|
2949
|
+
dataConstructor: (_b = (_a = clientEvt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
|
|
2950
|
+
dataStr: typeof clientEvt.data === "string" ? clientEvt.data.substring(0, 100) : void 0
|
|
2951
|
+
});
|
|
2952
|
+
if (serverWs.readyState === 1) {
|
|
2953
|
+
if (clientEvt.data instanceof Blob) {
|
|
2954
|
+
clientEvt.data.arrayBuffer().then((buffer) => {
|
|
2955
|
+
logger().debug({
|
|
2956
|
+
msg: "converted client blob to arraybuffer, sending to server",
|
|
2957
|
+
bufferSize: buffer.byteLength
|
|
2958
|
+
});
|
|
2959
|
+
serverWs.send(buffer);
|
|
2960
|
+
}).catch((error) => {
|
|
2961
|
+
logger().error({
|
|
2962
|
+
msg: "failed to convert blob to arraybuffer",
|
|
2963
|
+
error
|
|
2964
|
+
});
|
|
2965
|
+
});
|
|
2966
|
+
} else {
|
|
2967
|
+
logger().debug({
|
|
2968
|
+
msg: "sending client data directly to server",
|
|
2969
|
+
dataType: typeof clientEvt.data,
|
|
2970
|
+
dataLength: typeof clientEvt.data === "string" ? clientEvt.data.length : void 0
|
|
2971
|
+
});
|
|
2972
|
+
serverWs.send(clientEvt.data);
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
});
|
|
2976
|
+
ws.addEventListener("close", async (clientEvt) => {
|
|
2977
|
+
const serverWs = await serverWsPromise;
|
|
2978
|
+
logger().debug({
|
|
2979
|
+
msg: `test websocket connection closed`
|
|
2980
|
+
});
|
|
2981
|
+
if (serverWs.readyState !== 3) {
|
|
2982
|
+
serverWs.close(clientEvt.code, clientEvt.reason);
|
|
2983
|
+
}
|
|
2984
|
+
});
|
|
2985
|
+
ws.addEventListener("error", async () => {
|
|
2986
|
+
const serverWs = await serverWsPromise;
|
|
2987
|
+
logger().debug({
|
|
2988
|
+
msg: `test websocket connection error`
|
|
2989
|
+
});
|
|
2990
|
+
if (serverWs.readyState !== 3) {
|
|
2991
|
+
serverWs.close(1011, "Error in client websocket");
|
|
2992
|
+
}
|
|
2993
|
+
});
|
|
2994
|
+
});
|
|
2995
|
+
} catch (error) {
|
|
2996
|
+
logger().error({
|
|
2997
|
+
msg: `failed to establish client websocket connection`,
|
|
2998
|
+
error
|
|
2999
|
+
});
|
|
3000
|
+
return {
|
|
3001
|
+
onOpen: (_evt, serverWs) => {
|
|
3002
|
+
serverWs.close(1011, "Failed to establish connection");
|
|
3003
|
+
},
|
|
3004
|
+
onMessage: () => {
|
|
3005
|
+
},
|
|
3006
|
+
onError: () => {
|
|
3007
|
+
},
|
|
3008
|
+
onClose: () => {
|
|
3009
|
+
}
|
|
3010
|
+
};
|
|
3011
|
+
}
|
|
3012
|
+
return {
|
|
3013
|
+
onOpen: (_evt, serverWs) => {
|
|
3014
|
+
logger().debug({
|
|
3015
|
+
msg: `test websocket connection from client opened`
|
|
3016
|
+
});
|
|
3017
|
+
logger().debug({
|
|
3018
|
+
msg: "clientWs info",
|
|
3019
|
+
constructor: clientWs.constructor.name,
|
|
3020
|
+
hasAddEventListener: typeof clientWs.addEventListener === "function",
|
|
3021
|
+
readyState: clientWs.readyState
|
|
3022
|
+
});
|
|
3023
|
+
serverWsResolve(serverWs);
|
|
3024
|
+
},
|
|
3025
|
+
onMessage: (evt) => {
|
|
3026
|
+
var _a, _b;
|
|
3027
|
+
logger().debug({
|
|
3028
|
+
msg: "received message from server",
|
|
3029
|
+
dataType: typeof evt.data,
|
|
3030
|
+
isBlob: evt.data instanceof Blob,
|
|
3031
|
+
isArrayBuffer: evt.data instanceof ArrayBuffer,
|
|
3032
|
+
dataConstructor: (_b = (_a = evt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
|
|
3033
|
+
dataStr: typeof evt.data === "string" ? evt.data.substring(0, 100) : void 0
|
|
3034
|
+
});
|
|
3035
|
+
if (clientWs.readyState === 1) {
|
|
3036
|
+
if (evt.data instanceof Blob) {
|
|
3037
|
+
evt.data.arrayBuffer().then((buffer) => {
|
|
3038
|
+
logger().debug({
|
|
3039
|
+
msg: "converted blob to arraybuffer, sending",
|
|
3040
|
+
bufferSize: buffer.byteLength
|
|
3041
|
+
});
|
|
3042
|
+
clientWs.send(buffer);
|
|
3043
|
+
}).catch((error) => {
|
|
3044
|
+
logger().error({
|
|
3045
|
+
msg: "failed to convert blob to arraybuffer",
|
|
3046
|
+
error
|
|
3047
|
+
});
|
|
3048
|
+
});
|
|
3049
|
+
} else {
|
|
3050
|
+
logger().debug({
|
|
3051
|
+
msg: "sending data directly",
|
|
3052
|
+
dataType: typeof evt.data,
|
|
3053
|
+
dataLength: typeof evt.data === "string" ? evt.data.length : void 0
|
|
3054
|
+
});
|
|
3055
|
+
clientWs.send(evt.data);
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
},
|
|
3059
|
+
onClose: (event, serverWs) => {
|
|
3060
|
+
logger().debug({
|
|
3061
|
+
msg: `server websocket closed`,
|
|
3062
|
+
wasClean: event.wasClean,
|
|
3063
|
+
code: event.code,
|
|
3064
|
+
reason: event.reason
|
|
3065
|
+
});
|
|
3066
|
+
serverWs.close(1e3, "hack_force_close");
|
|
3067
|
+
if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
|
|
3068
|
+
clientWs.close(1e3, event.reason);
|
|
3069
|
+
}
|
|
3070
|
+
},
|
|
3071
|
+
onError: (error) => {
|
|
3072
|
+
logger().error({
|
|
3073
|
+
msg: `error in server websocket`,
|
|
3074
|
+
error
|
|
3075
|
+
});
|
|
3076
|
+
if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
|
|
3077
|
+
clientWs.close(1011, "Error in server websocket");
|
|
3078
|
+
}
|
|
3079
|
+
serverWsReject();
|
|
3080
|
+
}
|
|
3081
|
+
};
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
// src/manager/router.ts
|
|
3085
|
+
function buildOpenApiResponses(schema) {
|
|
3086
|
+
return {
|
|
3087
|
+
200: {
|
|
3088
|
+
description: "Success",
|
|
3089
|
+
content: {
|
|
3090
|
+
"application/json": {
|
|
3091
|
+
schema
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
},
|
|
3095
|
+
400: {
|
|
3096
|
+
description: "User error"
|
|
3097
|
+
},
|
|
3098
|
+
500: {
|
|
3099
|
+
description: "Internal error"
|
|
3100
|
+
}
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
function createManagerRouter(registryConfig, runConfig, managerDriver, serverlessActorDriverBuilder) {
|
|
3104
|
+
const router = new OpenAPIHono({ strict: false }).basePath(
|
|
3105
|
+
runConfig.basePath
|
|
3106
|
+
);
|
|
3107
|
+
router.use("*", loggerMiddleware(logger()));
|
|
3108
|
+
const cors2 = runConfig.cors ? corsMiddleware(runConfig.cors) : createMiddleware((_c, next) => next());
|
|
3109
|
+
if (serverlessActorDriverBuilder) {
|
|
3110
|
+
addServerlessRoutes(serverlessActorDriverBuilder, router, cors2);
|
|
3111
|
+
} else {
|
|
3112
|
+
addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors2);
|
|
3113
|
+
}
|
|
3114
|
+
router.notFound(handleRouteNotFound);
|
|
3115
|
+
router.onError(handleRouteError);
|
|
3116
|
+
return { router, openapi: router, cors: cors2 };
|
|
3117
|
+
}
|
|
3118
|
+
function addServerlessRoutes(serverlessActorDriverBuilder, router, cors2) {
|
|
3119
|
+
router.get("/", cors2, (c) => {
|
|
3120
|
+
return c.text(
|
|
3121
|
+
"This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
|
|
3122
|
+
);
|
|
3123
|
+
});
|
|
3124
|
+
router.get("/start", cors2, async (c) => {
|
|
3125
|
+
const actorDriver = serverlessActorDriverBuilder();
|
|
3126
|
+
invariant6(
|
|
3127
|
+
actorDriver.serverlessHandleStart,
|
|
3128
|
+
"missing serverlessHandleStart on ActorDriver"
|
|
3129
|
+
);
|
|
3130
|
+
return await actorDriver.serverlessHandleStart(c);
|
|
3131
|
+
});
|
|
3132
|
+
router.get("/health", cors2, (c) => {
|
|
3133
|
+
return c.text("ok");
|
|
3134
|
+
});
|
|
3135
|
+
}
|
|
3136
|
+
function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors2) {
|
|
3137
|
+
var _a;
|
|
3138
|
+
router.use("*", cors2, actorGateway.bind(void 0, runConfig, managerDriver));
|
|
3139
|
+
router.get("/", cors2, (c) => {
|
|
3140
|
+
return c.text(
|
|
3141
|
+
"This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
|
|
3142
|
+
);
|
|
3143
|
+
});
|
|
3144
|
+
{
|
|
3145
|
+
const route = createRoute({
|
|
3056
3146
|
middleware: [cors2],
|
|
3057
3147
|
method: "get",
|
|
3058
|
-
path: "/actors
|
|
3148
|
+
path: "/actors",
|
|
3059
3149
|
request: {
|
|
3060
|
-
query:
|
|
3061
|
-
name:
|
|
3062
|
-
|
|
3150
|
+
query: z5.object({
|
|
3151
|
+
name: z5.string(),
|
|
3152
|
+
actor_ids: z5.string().optional(),
|
|
3153
|
+
key: z5.string().optional()
|
|
3063
3154
|
})
|
|
3064
3155
|
},
|
|
3065
|
-
responses: buildOpenApiResponses(
|
|
3066
|
-
ActorsGetByIdResponseSchema,
|
|
3067
|
-
validateBody
|
|
3068
|
-
)
|
|
3156
|
+
responses: buildOpenApiResponses(ActorsListResponseSchema)
|
|
3069
3157
|
});
|
|
3070
3158
|
router.openapi(route, async (c) => {
|
|
3071
|
-
const { name, key } = c.req.valid("query");
|
|
3072
|
-
const
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3159
|
+
const { name, actor_ids, key } = c.req.valid("query");
|
|
3160
|
+
const actorIdsParsed = actor_ids ? actor_ids.split(",").map((id) => id.trim()).filter((id) => id.length > 0) : void 0;
|
|
3161
|
+
const actors = [];
|
|
3162
|
+
if (actorIdsParsed) {
|
|
3163
|
+
if (actorIdsParsed.length > 32) {
|
|
3164
|
+
return c.json(
|
|
3165
|
+
{
|
|
3166
|
+
error: `Too many actor IDs. Maximum is 32, got ${actorIdsParsed.length}.`
|
|
3167
|
+
},
|
|
3168
|
+
400
|
|
3169
|
+
);
|
|
3170
|
+
}
|
|
3171
|
+
if (actorIdsParsed.length === 0) {
|
|
3172
|
+
return c.json({
|
|
3173
|
+
actors: []
|
|
3174
|
+
});
|
|
3175
|
+
}
|
|
3176
|
+
for (const actorId of actorIdsParsed) {
|
|
3177
|
+
if (name) {
|
|
3178
|
+
const actorOutput = await managerDriver.getForId({
|
|
3179
|
+
c,
|
|
3180
|
+
name,
|
|
3181
|
+
actorId
|
|
3182
|
+
});
|
|
3183
|
+
if (actorOutput) {
|
|
3184
|
+
actors.push(actorOutput);
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
} else if (key) {
|
|
3189
|
+
const actorOutput = await managerDriver.getWithKey({
|
|
3190
|
+
c,
|
|
3191
|
+
name,
|
|
3192
|
+
key: [key]
|
|
3193
|
+
// Convert string to ActorKey array
|
|
3194
|
+
});
|
|
3195
|
+
if (actorOutput) {
|
|
3196
|
+
actors.push(actorOutput);
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3078
3199
|
return c.json({
|
|
3079
|
-
|
|
3200
|
+
actors: actors.map(createApiActor)
|
|
3080
3201
|
});
|
|
3081
3202
|
});
|
|
3082
3203
|
}
|
|
3083
3204
|
{
|
|
3084
3205
|
const route = createRoute({
|
|
3085
|
-
|
|
3206
|
+
middleware: [cors2],
|
|
3086
3207
|
method: "put",
|
|
3087
|
-
path: "/actors
|
|
3208
|
+
path: "/actors",
|
|
3088
3209
|
request: {
|
|
3089
3210
|
body: {
|
|
3090
|
-
content:
|
|
3211
|
+
content: {
|
|
3091
3212
|
"application/json": {
|
|
3092
|
-
schema:
|
|
3213
|
+
schema: ActorsGetOrCreateRequestSchema
|
|
3093
3214
|
}
|
|
3094
|
-
}
|
|
3215
|
+
}
|
|
3095
3216
|
}
|
|
3096
3217
|
},
|
|
3097
|
-
responses: buildOpenApiResponses(
|
|
3098
|
-
ActorsGetOrCreateByIdResponseSchema,
|
|
3099
|
-
validateBody
|
|
3100
|
-
)
|
|
3218
|
+
responses: buildOpenApiResponses(ActorsGetOrCreateResponseSchema)
|
|
3101
3219
|
});
|
|
3102
3220
|
router.openapi(route, async (c) => {
|
|
3103
|
-
const body =
|
|
3104
|
-
if (validateBody) {
|
|
3105
|
-
ActorsGetOrCreateByIdRequestSchema.parse(body);
|
|
3106
|
-
}
|
|
3221
|
+
const body = c.req.valid("json");
|
|
3107
3222
|
const existingActor = await managerDriver.getWithKey({
|
|
3108
3223
|
c,
|
|
3109
3224
|
name: body.name,
|
|
@@ -3112,7 +3227,7 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3112
3227
|
});
|
|
3113
3228
|
if (existingActor) {
|
|
3114
3229
|
return c.json({
|
|
3115
|
-
|
|
3230
|
+
actor: createApiActor(existingActor),
|
|
3116
3231
|
created: false
|
|
3117
3232
|
});
|
|
3118
3233
|
}
|
|
@@ -3126,52 +3241,11 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3126
3241
|
// Not provided in the request schema
|
|
3127
3242
|
});
|
|
3128
3243
|
return c.json({
|
|
3129
|
-
|
|
3244
|
+
actor: createApiActor(newActor),
|
|
3130
3245
|
created: true
|
|
3131
3246
|
});
|
|
3132
3247
|
});
|
|
3133
3248
|
}
|
|
3134
|
-
{
|
|
3135
|
-
const route = createRoute({
|
|
3136
|
-
middleware: [cors2],
|
|
3137
|
-
method: "get",
|
|
3138
|
-
path: "/actors/{actor_id}",
|
|
3139
|
-
request: {
|
|
3140
|
-
params: z8.object({
|
|
3141
|
-
actor_id: RivetIdSchema
|
|
3142
|
-
})
|
|
3143
|
-
},
|
|
3144
|
-
responses: buildOpenApiResponses(ActorsGetResponseSchema, validateBody)
|
|
3145
|
-
});
|
|
3146
|
-
router.openapi(route, async (c) => {
|
|
3147
|
-
const { actor_id } = c.req.valid("param");
|
|
3148
|
-
const actorOutput = await managerDriver.getForId({
|
|
3149
|
-
c,
|
|
3150
|
-
name: "",
|
|
3151
|
-
// TODO: The API doesn't provide the name, this may need to be resolved
|
|
3152
|
-
actorId: actor_id
|
|
3153
|
-
});
|
|
3154
|
-
if (!actorOutput) {
|
|
3155
|
-
throw new ActorNotFound(actor_id);
|
|
3156
|
-
}
|
|
3157
|
-
const actor2 = {
|
|
3158
|
-
actor_id: actorOutput.actorId,
|
|
3159
|
-
name: actorOutput.name,
|
|
3160
|
-
key: actorOutput.key,
|
|
3161
|
-
namespace_id: "default",
|
|
3162
|
-
// Assert default namespace
|
|
3163
|
-
runner_name_selector: "rivetkit",
|
|
3164
|
-
// Assert rivetkit runner
|
|
3165
|
-
create_ts: Date.now(),
|
|
3166
|
-
// Not available from driver
|
|
3167
|
-
connectable_ts: null,
|
|
3168
|
-
destroy_ts: null,
|
|
3169
|
-
sleep_ts: null,
|
|
3170
|
-
start_ts: null
|
|
3171
|
-
};
|
|
3172
|
-
return c.json({ actor: actor2 });
|
|
3173
|
-
});
|
|
3174
|
-
}
|
|
3175
3249
|
{
|
|
3176
3250
|
const route = createRoute({
|
|
3177
3251
|
middleware: [cors2],
|
|
@@ -3179,23 +3253,17 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3179
3253
|
path: "/actors",
|
|
3180
3254
|
request: {
|
|
3181
3255
|
body: {
|
|
3182
|
-
content:
|
|
3256
|
+
content: {
|
|
3183
3257
|
"application/json": {
|
|
3184
3258
|
schema: ActorsCreateRequestSchema
|
|
3185
3259
|
}
|
|
3186
|
-
}
|
|
3260
|
+
}
|
|
3187
3261
|
}
|
|
3188
3262
|
},
|
|
3189
|
-
responses: buildOpenApiResponses(
|
|
3190
|
-
ActorsCreateResponseSchema,
|
|
3191
|
-
validateBody
|
|
3192
|
-
)
|
|
3263
|
+
responses: buildOpenApiResponses(ActorsCreateResponseSchema)
|
|
3193
3264
|
});
|
|
3194
3265
|
router.openapi(route, async (c) => {
|
|
3195
|
-
const body =
|
|
3196
|
-
if (validateBody) {
|
|
3197
|
-
ActorsCreateRequestSchema.parse(body);
|
|
3198
|
-
}
|
|
3266
|
+
const body = c.req.valid("json");
|
|
3199
3267
|
const actorOutput = await managerDriver.createActor({
|
|
3200
3268
|
c,
|
|
3201
3269
|
name: body.name,
|
|
@@ -3205,20 +3273,7 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3205
3273
|
region: void 0
|
|
3206
3274
|
// Not provided in the request schema
|
|
3207
3275
|
});
|
|
3208
|
-
const actor2 =
|
|
3209
|
-
actor_id: actorOutput.actorId,
|
|
3210
|
-
name: actorOutput.name,
|
|
3211
|
-
key: actorOutput.key,
|
|
3212
|
-
namespace_id: "default",
|
|
3213
|
-
// Assert default namespace
|
|
3214
|
-
runner_name_selector: "rivetkit",
|
|
3215
|
-
// Assert rivetkit runner
|
|
3216
|
-
create_ts: Date.now(),
|
|
3217
|
-
connectable_ts: null,
|
|
3218
|
-
destroy_ts: null,
|
|
3219
|
-
sleep_ts: null,
|
|
3220
|
-
start_ts: null
|
|
3221
|
-
};
|
|
3276
|
+
const actor2 = createApiActor(actorOutput);
|
|
3222
3277
|
return c.json({ actor: actor2 });
|
|
3223
3278
|
});
|
|
3224
3279
|
}
|
|
@@ -3246,29 +3301,60 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3246
3301
|
router.get(".test/inline-driver/connect-websocket/*", async (c) => {
|
|
3247
3302
|
var _a2;
|
|
3248
3303
|
const upgradeWebSocket = (_a2 = runConfig.getUpgradeWebSocket) == null ? void 0 : _a2.call(runConfig);
|
|
3249
|
-
|
|
3304
|
+
invariant6(upgradeWebSocket, "websockets not supported on this platform");
|
|
3250
3305
|
return upgradeWebSocket(async (c2) => {
|
|
3251
|
-
const
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3306
|
+
const protocolHeader = c2.req.header("sec-websocket-protocol") || "";
|
|
3307
|
+
const protocols = protocolHeader.split(/,\s*/);
|
|
3308
|
+
let actorId = "";
|
|
3309
|
+
let encoding = "bare";
|
|
3310
|
+
let transport = "websocket";
|
|
3311
|
+
let path3 = "";
|
|
3312
|
+
let params;
|
|
3313
|
+
let connId;
|
|
3314
|
+
let connToken;
|
|
3315
|
+
for (const protocol of protocols) {
|
|
3316
|
+
if (protocol.startsWith(WS_PROTOCOL_ACTOR)) {
|
|
3317
|
+
actorId = protocol.substring(WS_PROTOCOL_ACTOR.length);
|
|
3318
|
+
} else if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
|
|
3319
|
+
encoding = protocol.substring(
|
|
3320
|
+
WS_PROTOCOL_ENCODING.length
|
|
3321
|
+
);
|
|
3322
|
+
} else if (protocol.startsWith(WS_PROTOCOL_TRANSPORT)) {
|
|
3323
|
+
transport = protocol.substring(
|
|
3324
|
+
WS_PROTOCOL_TRANSPORT.length
|
|
3325
|
+
);
|
|
3326
|
+
} else if (protocol.startsWith(WS_PROTOCOL_PATH)) {
|
|
3327
|
+
path3 = decodeURIComponent(
|
|
3328
|
+
protocol.substring(WS_PROTOCOL_PATH.length)
|
|
3329
|
+
);
|
|
3330
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
|
|
3331
|
+
const paramsRaw = decodeURIComponent(
|
|
3332
|
+
protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
|
|
3333
|
+
);
|
|
3334
|
+
params = JSON.parse(paramsRaw);
|
|
3335
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
|
|
3336
|
+
connId = protocol.substring(WS_PROTOCOL_CONN_ID.length);
|
|
3337
|
+
} else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
|
|
3338
|
+
connToken = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3258
3341
|
logger().debug({
|
|
3259
3342
|
msg: "received test inline driver websocket",
|
|
3260
3343
|
actorId,
|
|
3261
3344
|
params,
|
|
3262
|
-
encodingKind,
|
|
3345
|
+
encodingKind: encoding,
|
|
3346
|
+
transport,
|
|
3263
3347
|
path: path3
|
|
3264
3348
|
});
|
|
3265
3349
|
const clientWsPromise = managerDriver.openWebSocket(
|
|
3266
3350
|
path3,
|
|
3267
3351
|
actorId,
|
|
3268
|
-
|
|
3269
|
-
params
|
|
3352
|
+
encoding,
|
|
3353
|
+
params,
|
|
3354
|
+
connId,
|
|
3355
|
+
connToken
|
|
3270
3356
|
);
|
|
3271
|
-
return await createTestWebSocketProxy(clientWsPromise
|
|
3357
|
+
return await createTestWebSocketProxy(clientWsPromise);
|
|
3272
3358
|
})(c, noopNext());
|
|
3273
3359
|
});
|
|
3274
3360
|
router.all(".test/inline-driver/send-request/*", async (c) => {
|
|
@@ -3291,7 +3377,8 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3291
3377
|
new Request(`http://actor/${pathWithQuery}`, {
|
|
3292
3378
|
method: c.req.method,
|
|
3293
3379
|
headers: c.req.raw.headers,
|
|
3294
|
-
body: c.req.raw.body
|
|
3380
|
+
body: c.req.raw.body,
|
|
3381
|
+
duplex: "half"
|
|
3295
3382
|
})
|
|
3296
3383
|
);
|
|
3297
3384
|
return response;
|
|
@@ -3313,13 +3400,50 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3313
3400
|
);
|
|
3314
3401
|
}
|
|
3315
3402
|
});
|
|
3403
|
+
router.post("/.test/force-disconnect", async (c) => {
|
|
3404
|
+
const actorId = c.req.query("actor");
|
|
3405
|
+
const connId = c.req.query("conn");
|
|
3406
|
+
if (!actorId || !connId) {
|
|
3407
|
+
return c.text("Missing actor or conn query parameters", 400);
|
|
3408
|
+
}
|
|
3409
|
+
logger().debug({
|
|
3410
|
+
msg: "forcing unclean disconnect",
|
|
3411
|
+
actorId,
|
|
3412
|
+
connId
|
|
3413
|
+
});
|
|
3414
|
+
try {
|
|
3415
|
+
const response = await managerDriver.sendRequest(
|
|
3416
|
+
actorId,
|
|
3417
|
+
new Request(`http://actor/.test/force-disconnect?conn=${connId}`, {
|
|
3418
|
+
method: "POST"
|
|
3419
|
+
})
|
|
3420
|
+
);
|
|
3421
|
+
if (!response.ok) {
|
|
3422
|
+
const text = await response.text();
|
|
3423
|
+
return c.text(
|
|
3424
|
+
`Failed to force disconnect: ${text}`,
|
|
3425
|
+
response.status
|
|
3426
|
+
);
|
|
3427
|
+
}
|
|
3428
|
+
return c.json({ success: true });
|
|
3429
|
+
} catch (error) {
|
|
3430
|
+
logger().error({
|
|
3431
|
+
msg: "error forcing disconnect",
|
|
3432
|
+
error: stringifyError(error)
|
|
3433
|
+
});
|
|
3434
|
+
return c.text(`Error: ${error}`, 500);
|
|
3435
|
+
}
|
|
3436
|
+
});
|
|
3316
3437
|
}
|
|
3438
|
+
router.get("/health", cors2, (c) => {
|
|
3439
|
+
return c.text("ok");
|
|
3440
|
+
});
|
|
3317
3441
|
(_a = managerDriver.modifyManagerRouter) == null ? void 0 : _a.call(
|
|
3318
3442
|
managerDriver,
|
|
3319
3443
|
registryConfig,
|
|
3320
3444
|
router
|
|
3321
3445
|
);
|
|
3322
|
-
if ((
|
|
3446
|
+
if (isInspectorEnabled(runConfig, "manager")) {
|
|
3323
3447
|
if (!managerDriver.inspector) {
|
|
3324
3448
|
throw new Unsupported("inspector");
|
|
3325
3449
|
}
|
|
@@ -3331,180 +3455,33 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
|
|
|
3331
3455
|
}).route("/", createManagerInspectorRouter())
|
|
3332
3456
|
);
|
|
3333
3457
|
}
|
|
3334
|
-
router.notFound(handleRouteNotFound);
|
|
3335
|
-
router.onError(handleRouteError);
|
|
3336
|
-
return { router, openapi: router };
|
|
3337
3458
|
}
|
|
3338
|
-
|
|
3339
|
-
let clientWs = null;
|
|
3340
|
-
try {
|
|
3341
|
-
logger().debug({ msg: "awaiting client websocket promise" });
|
|
3342
|
-
const ws = await clientWsPromise;
|
|
3343
|
-
clientWs = ws;
|
|
3344
|
-
logger().debug({
|
|
3345
|
-
msg: "client websocket promise resolved",
|
|
3346
|
-
constructor: ws == null ? void 0 : ws.constructor.name
|
|
3347
|
-
});
|
|
3348
|
-
await new Promise((resolve, reject) => {
|
|
3349
|
-
const onOpen = () => {
|
|
3350
|
-
logger().debug({ msg: "test websocket connection opened" });
|
|
3351
|
-
resolve();
|
|
3352
|
-
};
|
|
3353
|
-
const onError = (error) => {
|
|
3354
|
-
logger().error({ msg: "test websocket connection failed", error });
|
|
3355
|
-
reject(
|
|
3356
|
-
new Error(`Failed to open WebSocket: ${error.message || error}`)
|
|
3357
|
-
);
|
|
3358
|
-
};
|
|
3359
|
-
ws.addEventListener("open", onOpen);
|
|
3360
|
-
ws.addEventListener("error", onError);
|
|
3361
|
-
});
|
|
3362
|
-
} catch (error) {
|
|
3363
|
-
logger().error({
|
|
3364
|
-
msg: `failed to establish client ${connectionType} websocket connection`,
|
|
3365
|
-
error
|
|
3366
|
-
});
|
|
3367
|
-
return {
|
|
3368
|
-
onOpen: (_evt, serverWs) => {
|
|
3369
|
-
serverWs.close(1011, "Failed to establish connection");
|
|
3370
|
-
},
|
|
3371
|
-
onMessage: () => {
|
|
3372
|
-
},
|
|
3373
|
-
onError: () => {
|
|
3374
|
-
},
|
|
3375
|
-
onClose: () => {
|
|
3376
|
-
}
|
|
3377
|
-
};
|
|
3378
|
-
}
|
|
3459
|
+
function createApiActor(actor2) {
|
|
3379
3460
|
return {
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
logger().debug({
|
|
3393
|
-
msg: `test ${connectionType} websocket connection message from client`,
|
|
3394
|
-
dataType: typeof clientEvt.data,
|
|
3395
|
-
isBlob: clientEvt.data instanceof Blob,
|
|
3396
|
-
isArrayBuffer: clientEvt.data instanceof ArrayBuffer,
|
|
3397
|
-
dataConstructor: (_b = (_a = clientEvt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
|
|
3398
|
-
dataStr: typeof clientEvt.data === "string" ? clientEvt.data.substring(0, 100) : void 0
|
|
3399
|
-
});
|
|
3400
|
-
if (serverWs.readyState === 1) {
|
|
3401
|
-
if (clientEvt.data instanceof Blob) {
|
|
3402
|
-
clientEvt.data.arrayBuffer().then((buffer) => {
|
|
3403
|
-
logger().debug({
|
|
3404
|
-
msg: "converted client blob to arraybuffer, sending to server",
|
|
3405
|
-
bufferSize: buffer.byteLength
|
|
3406
|
-
});
|
|
3407
|
-
serverWs.send(buffer);
|
|
3408
|
-
}).catch((error) => {
|
|
3409
|
-
logger().error({
|
|
3410
|
-
msg: "failed to convert blob to arraybuffer",
|
|
3411
|
-
error
|
|
3412
|
-
});
|
|
3413
|
-
});
|
|
3414
|
-
} else {
|
|
3415
|
-
logger().debug({
|
|
3416
|
-
msg: "sending client data directly to server",
|
|
3417
|
-
dataType: typeof clientEvt.data,
|
|
3418
|
-
dataLength: typeof clientEvt.data === "string" ? clientEvt.data.length : void 0
|
|
3419
|
-
});
|
|
3420
|
-
serverWs.send(clientEvt.data);
|
|
3421
|
-
}
|
|
3422
|
-
}
|
|
3423
|
-
});
|
|
3424
|
-
clientWs.addEventListener("close", (clientEvt) => {
|
|
3425
|
-
logger().debug({
|
|
3426
|
-
msg: `test ${connectionType} websocket connection closed`
|
|
3427
|
-
});
|
|
3428
|
-
if (serverWs.readyState !== 3) {
|
|
3429
|
-
serverWs.close(clientEvt.code, clientEvt.reason);
|
|
3430
|
-
}
|
|
3431
|
-
});
|
|
3432
|
-
clientWs.addEventListener("error", () => {
|
|
3433
|
-
logger().debug({
|
|
3434
|
-
msg: `test ${connectionType} websocket connection error`
|
|
3435
|
-
});
|
|
3436
|
-
if (serverWs.readyState !== 3) {
|
|
3437
|
-
serverWs.close(1011, "Error in client websocket");
|
|
3438
|
-
}
|
|
3439
|
-
});
|
|
3440
|
-
},
|
|
3441
|
-
onMessage: (evt) => {
|
|
3442
|
-
var _a, _b;
|
|
3443
|
-
logger().debug({
|
|
3444
|
-
msg: "received message from server",
|
|
3445
|
-
dataType: typeof evt.data,
|
|
3446
|
-
isBlob: evt.data instanceof Blob,
|
|
3447
|
-
isArrayBuffer: evt.data instanceof ArrayBuffer,
|
|
3448
|
-
dataConstructor: (_b = (_a = evt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
|
|
3449
|
-
dataStr: typeof evt.data === "string" ? evt.data.substring(0, 100) : void 0
|
|
3450
|
-
});
|
|
3451
|
-
if (clientWs.readyState === 1) {
|
|
3452
|
-
if (evt.data instanceof Blob) {
|
|
3453
|
-
evt.data.arrayBuffer().then((buffer) => {
|
|
3454
|
-
logger().debug({
|
|
3455
|
-
msg: "converted blob to arraybuffer, sending",
|
|
3456
|
-
bufferSize: buffer.byteLength
|
|
3457
|
-
});
|
|
3458
|
-
clientWs.send(buffer);
|
|
3459
|
-
}).catch((error) => {
|
|
3460
|
-
logger().error({
|
|
3461
|
-
msg: "failed to convert blob to arraybuffer",
|
|
3462
|
-
error
|
|
3463
|
-
});
|
|
3464
|
-
});
|
|
3465
|
-
} else {
|
|
3466
|
-
logger().debug({
|
|
3467
|
-
msg: "sending data directly",
|
|
3468
|
-
dataType: typeof evt.data,
|
|
3469
|
-
dataLength: typeof evt.data === "string" ? evt.data.length : void 0
|
|
3470
|
-
});
|
|
3471
|
-
clientWs.send(evt.data);
|
|
3472
|
-
}
|
|
3473
|
-
}
|
|
3474
|
-
},
|
|
3475
|
-
onClose: (event, serverWs) => {
|
|
3476
|
-
logger().debug({
|
|
3477
|
-
msg: `server ${connectionType} websocket closed`,
|
|
3478
|
-
wasClean: event.wasClean,
|
|
3479
|
-
code: event.code,
|
|
3480
|
-
reason: event.reason
|
|
3481
|
-
});
|
|
3482
|
-
serverWs.close(1e3, "hack_force_close");
|
|
3483
|
-
if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
|
|
3484
|
-
clientWs.close(1e3, event.reason);
|
|
3485
|
-
}
|
|
3486
|
-
},
|
|
3487
|
-
onError: (error) => {
|
|
3488
|
-
logger().error({
|
|
3489
|
-
msg: `error in server ${connectionType} websocket`,
|
|
3490
|
-
error
|
|
3491
|
-
});
|
|
3492
|
-
if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
|
|
3493
|
-
clientWs.close(1011, "Error in server websocket");
|
|
3494
|
-
}
|
|
3495
|
-
}
|
|
3461
|
+
actor_id: actor2.actorId,
|
|
3462
|
+
name: actor2.name,
|
|
3463
|
+
key: serializeActorKey(actor2.key),
|
|
3464
|
+
namespace_id: "default",
|
|
3465
|
+
// Assert default namespace
|
|
3466
|
+
runner_name_selector: "rivetkit",
|
|
3467
|
+
// Assert rivetkit runner
|
|
3468
|
+
create_ts: Date.now(),
|
|
3469
|
+
connectable_ts: null,
|
|
3470
|
+
destroy_ts: null,
|
|
3471
|
+
sleep_ts: null,
|
|
3472
|
+
start_ts: null
|
|
3496
3473
|
};
|
|
3497
3474
|
}
|
|
3498
3475
|
|
|
3499
3476
|
// src/registry/config.ts
|
|
3500
|
-
import { z as
|
|
3501
|
-
var ActorsSchema =
|
|
3502
|
-
|
|
3503
|
-
|
|
3477
|
+
import { z as z6 } from "zod";
|
|
3478
|
+
var ActorsSchema = z6.record(
|
|
3479
|
+
z6.string(),
|
|
3480
|
+
z6.custom()
|
|
3504
3481
|
);
|
|
3505
|
-
var TestConfigSchema =
|
|
3506
|
-
var RegistryConfigSchema =
|
|
3507
|
-
use:
|
|
3482
|
+
var TestConfigSchema = z6.object({ enabled: z6.boolean() });
|
|
3483
|
+
var RegistryConfigSchema = z6.object({
|
|
3484
|
+
use: z6.record(z6.string(), z6.custom()),
|
|
3508
3485
|
// TODO: Find a better way of passing around the test config
|
|
3509
3486
|
/**
|
|
3510
3487
|
* Test configuration.
|
|
@@ -3576,7 +3553,7 @@ var Registry = class {
|
|
|
3576
3553
|
* Runs the registry for a server.
|
|
3577
3554
|
*/
|
|
3578
3555
|
start(inputConfig) {
|
|
3579
|
-
var _a, _b, _c
|
|
3556
|
+
var _a, _b, _c;
|
|
3580
3557
|
const config2 = RunConfigSchema.parse(inputConfig);
|
|
3581
3558
|
if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
|
|
3582
3559
|
configureBaseLogger(config2.logging.baseLogger);
|
|
@@ -3585,11 +3562,11 @@ var Registry = class {
|
|
|
3585
3562
|
}
|
|
3586
3563
|
const driver = chooseDefaultDriver(config2);
|
|
3587
3564
|
if (driver.name === "engine") {
|
|
3588
|
-
config2.inspector.enabled = false;
|
|
3565
|
+
config2.inspector.enabled = { manager: false, actor: true };
|
|
3589
3566
|
config2.disableServer = true;
|
|
3590
3567
|
}
|
|
3591
3568
|
if (driver.name === "cloudflare-workers") {
|
|
3592
|
-
config2.inspector.enabled = false;
|
|
3569
|
+
config2.inspector.enabled = { manager: false, actor: true };
|
|
3593
3570
|
config2.disableServer = true;
|
|
3594
3571
|
config2.disableActorDriver = true;
|
|
3595
3572
|
config2.noWelcome = true;
|
|
@@ -3599,12 +3576,82 @@ var Registry = class {
|
|
|
3599
3576
|
config2.getUpgradeWebSocket = () => upgradeWebSocket;
|
|
3600
3577
|
}
|
|
3601
3578
|
const managerDriver = driver.manager(this.#config, config2);
|
|
3579
|
+
configureInspectorAccessToken(config2, managerDriver);
|
|
3580
|
+
const client = createClientWithDriver(managerDriver, config2);
|
|
3581
|
+
const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
|
|
3582
|
+
logger6().info({
|
|
3583
|
+
msg: "rivetkit ready",
|
|
3584
|
+
driver: driver.name,
|
|
3585
|
+
definitions: Object.keys(this.#config.use).length,
|
|
3586
|
+
...driverLog
|
|
3587
|
+
});
|
|
3588
|
+
if (isInspectorEnabled(config2, "manager") && managerDriver.inspector) {
|
|
3589
|
+
logger6().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
|
|
3590
|
+
}
|
|
3591
|
+
if (!config2.noWelcome) {
|
|
3592
|
+
const displayInfo = managerDriver.displayInformation();
|
|
3593
|
+
console.log();
|
|
3594
|
+
console.log(` RivetKit ${package_default.version} (${displayInfo.name})`);
|
|
3595
|
+
console.log(` - Endpoint: http://127.0.0.1:6420`);
|
|
3596
|
+
for (const [k, v] of Object.entries(displayInfo.properties)) {
|
|
3597
|
+
const padding = " ".repeat(Math.max(0, 13 - k.length));
|
|
3598
|
+
console.log(` - ${k}:${padding}${v}`);
|
|
3599
|
+
}
|
|
3600
|
+
if (isInspectorEnabled(config2, "manager") && managerDriver.inspector) {
|
|
3601
|
+
console.log(` - Inspector: ${getInspectorUrl(config2)}`);
|
|
3602
|
+
}
|
|
3603
|
+
console.log();
|
|
3604
|
+
}
|
|
3605
|
+
if (!config2.disableActorDriver) {
|
|
3606
|
+
const _actorDriver = driver.actor(
|
|
3607
|
+
this.#config,
|
|
3608
|
+
config2,
|
|
3609
|
+
managerDriver,
|
|
3610
|
+
client
|
|
3611
|
+
);
|
|
3612
|
+
}
|
|
3602
3613
|
const { router: hono } = createManagerRouter(
|
|
3603
3614
|
this.#config,
|
|
3604
3615
|
config2,
|
|
3605
3616
|
managerDriver,
|
|
3606
|
-
|
|
3617
|
+
void 0
|
|
3607
3618
|
);
|
|
3619
|
+
if (!config2.disableServer) {
|
|
3620
|
+
(async () => {
|
|
3621
|
+
const out = await crossPlatformServe(hono, void 0);
|
|
3622
|
+
upgradeWebSocket = out.upgradeWebSocket;
|
|
3623
|
+
})();
|
|
3624
|
+
}
|
|
3625
|
+
return {
|
|
3626
|
+
client,
|
|
3627
|
+
fetch: hono.fetch.bind(hono)
|
|
3628
|
+
};
|
|
3629
|
+
}
|
|
3630
|
+
startServerless(inputConfig) {
|
|
3631
|
+
var _a, _b, _c, _d, _e;
|
|
3632
|
+
const config2 = RunConfigSchema.parse(inputConfig);
|
|
3633
|
+
if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
|
|
3634
|
+
configureBaseLogger(config2.logging.baseLogger);
|
|
3635
|
+
} else {
|
|
3636
|
+
configureDefaultLogger((_b = config2.logging) == null ? void 0 : _b.level);
|
|
3637
|
+
}
|
|
3638
|
+
const driver = chooseDefaultDriver(config2);
|
|
3639
|
+
if (driver.name === "engine") {
|
|
3640
|
+
config2.inspector.enabled = false;
|
|
3641
|
+
config2.disableServer = true;
|
|
3642
|
+
config2.disableActorDriver = true;
|
|
3643
|
+
}
|
|
3644
|
+
if (driver.name === "cloudflare-workers") {
|
|
3645
|
+
config2.inspector.enabled = false;
|
|
3646
|
+
config2.disableServer = true;
|
|
3647
|
+
config2.disableActorDriver = true;
|
|
3648
|
+
config2.noWelcome = true;
|
|
3649
|
+
}
|
|
3650
|
+
let upgradeWebSocket;
|
|
3651
|
+
if (!config2.getUpgradeWebSocket) {
|
|
3652
|
+
config2.getUpgradeWebSocket = () => upgradeWebSocket;
|
|
3653
|
+
}
|
|
3654
|
+
const managerDriver = driver.manager(this.#config, config2);
|
|
3608
3655
|
const client = createClientWithDriver(managerDriver, config2);
|
|
3609
3656
|
const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
|
|
3610
3657
|
logger6().info({
|
|
@@ -3630,14 +3677,19 @@ var Registry = class {
|
|
|
3630
3677
|
}
|
|
3631
3678
|
console.log();
|
|
3632
3679
|
}
|
|
3680
|
+
let serverlessActorDriverBuilder = () => {
|
|
3681
|
+
return driver.actor(this.#config, config2, managerDriver, client);
|
|
3682
|
+
};
|
|
3633
3683
|
if (!config2.disableActorDriver) {
|
|
3634
|
-
const _actorDriver =
|
|
3635
|
-
|
|
3636
|
-
config2,
|
|
3637
|
-
managerDriver,
|
|
3638
|
-
client
|
|
3639
|
-
);
|
|
3684
|
+
const _actorDriver = serverlessActorDriverBuilder();
|
|
3685
|
+
serverlessActorDriverBuilder = void 0;
|
|
3640
3686
|
}
|
|
3687
|
+
const { router: hono } = createManagerRouter(
|
|
3688
|
+
this.#config,
|
|
3689
|
+
config2,
|
|
3690
|
+
managerDriver,
|
|
3691
|
+
serverlessActorDriverBuilder
|
|
3692
|
+
);
|
|
3641
3693
|
if (!config2.disableServer) {
|
|
3642
3694
|
(async () => {
|
|
3643
3695
|
const out = await crossPlatformServe(hono, void 0);
|
|
@@ -3656,8 +3708,6 @@ function setup(input) {
|
|
|
3656
3708
|
}
|
|
3657
3709
|
|
|
3658
3710
|
export {
|
|
3659
|
-
GenericConnGlobalState,
|
|
3660
|
-
createGenericConnDrivers,
|
|
3661
3711
|
handleWebSocketConnect,
|
|
3662
3712
|
handleRawWebSocketHandler,
|
|
3663
3713
|
createActorRouter,
|
|
@@ -3673,4 +3723,4 @@ export {
|
|
|
3673
3723
|
setup
|
|
3674
3724
|
};
|
|
3675
3725
|
//! These configs configs hold anything that's not platform-specific about running actors.
|
|
3676
|
-
//# sourceMappingURL=chunk-
|
|
3726
|
+
//# sourceMappingURL=chunk-KHRZPP5T.js.map
|