rivetkit 2.0.5 → 2.0.7-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/schemas/actor-persist/v1.ts +0 -6
- package/dist/tsup/actor-router-consts-B3Lu87yJ.d.cts +28 -0
- package/dist/tsup/actor-router-consts-B3Lu87yJ.d.ts +28 -0
- package/dist/tsup/{chunk-5YTI25C3.cjs → chunk-3MBP4WNC.cjs} +7 -7
- package/dist/tsup/{chunk-5YTI25C3.cjs.map → chunk-3MBP4WNC.cjs.map} +1 -1
- package/dist/tsup/chunk-3Y45CIF4.cjs +3726 -0
- package/dist/tsup/chunk-3Y45CIF4.cjs.map +1 -0
- package/dist/tsup/chunk-4GP7BZSR.js +102 -0
- package/dist/tsup/chunk-4GP7BZSR.js.map +1 -0
- package/dist/tsup/chunk-5ZOHIKWG.cjs +4071 -0
- package/dist/tsup/chunk-5ZOHIKWG.cjs.map +1 -0
- package/dist/tsup/{chunk-WADSS5X4.cjs → chunk-6EUWRXLT.cjs} +21 -7
- package/dist/tsup/chunk-6EUWRXLT.cjs.map +1 -0
- package/dist/tsup/{chunk-D7NWUCRK.cjs → chunk-6OVKCDSH.cjs} +6 -6
- package/dist/tsup/{chunk-D7NWUCRK.cjs.map → chunk-6OVKCDSH.cjs.map} +1 -1
- package/dist/tsup/{chunk-I5VTWPHW.js → chunk-7N56ZUC7.js} +3 -3
- package/dist/tsup/{chunk-LZIBTLEY.cjs → chunk-B3TLRM4Q.cjs} +13 -25
- package/dist/tsup/chunk-B3TLRM4Q.cjs.map +1 -0
- package/dist/tsup/chunk-BW5DPM6Z.js +4071 -0
- package/dist/tsup/chunk-BW5DPM6Z.js.map +1 -0
- package/dist/tsup/chunk-DFS77KAA.cjs +1046 -0
- package/dist/tsup/chunk-DFS77KAA.cjs.map +1 -0
- package/dist/tsup/{chunk-PG3K2LI7.js → chunk-E4UVJKSV.js} +2 -2
- package/dist/tsup/chunk-G4ABMAQY.cjs +102 -0
- package/dist/tsup/chunk-G4ABMAQY.cjs.map +1 -0
- package/dist/tsup/{chunk-CKA54YQN.js → chunk-GZVBFXBI.js} +3 -15
- package/dist/tsup/chunk-GZVBFXBI.js.map +1 -0
- package/dist/tsup/chunk-HPT3I7UU.js +3726 -0
- package/dist/tsup/chunk-HPT3I7UU.js.map +1 -0
- package/dist/tsup/chunk-JD54PXWP.js +1046 -0
- package/dist/tsup/chunk-JD54PXWP.js.map +1 -0
- package/dist/tsup/{chunk-PHSQJ6QI.cjs → chunk-K4ENQCC4.cjs} +3 -3
- package/dist/tsup/{chunk-PHSQJ6QI.cjs.map → chunk-K4ENQCC4.cjs.map} +1 -1
- package/dist/tsup/{chunk-WNGOBAA7.js → chunk-PUSQNDJG.js} +2 -2
- package/dist/tsup/{chunk-CFFKMUYH.js → chunk-RVP5RUSC.js} +20 -6
- package/dist/tsup/chunk-RVP5RUSC.js.map +1 -0
- package/dist/tsup/chunk-SAZCNSVY.cjs +259 -0
- package/dist/tsup/chunk-SAZCNSVY.cjs.map +1 -0
- package/dist/tsup/{chunk-YW6Y6VNE.js → chunk-SBKRVQS2.js} +9 -5
- package/dist/tsup/chunk-SBKRVQS2.js.map +1 -0
- package/dist/tsup/{chunk-FGFT4FVX.cjs → chunk-TZGUSEIJ.cjs} +14 -10
- package/dist/tsup/chunk-TZGUSEIJ.cjs.map +1 -0
- package/dist/tsup/chunk-YQ4XQYPM.js +259 -0
- package/dist/tsup/chunk-YQ4XQYPM.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +7 -8
- package/dist/tsup/client/mod.d.ts +7 -8
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{connection-BvE-Oq7t.d.ts → conn-DCSQgIlw.d.ts} +1605 -1353
- package/dist/tsup/{connection-DTzmWwU5.d.cts → conn-DdzHTm2E.d.cts} +1605 -1353
- package/dist/tsup/driver-helpers/mod.cjs +31 -5
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +7 -8
- package/dist/tsup/driver-helpers/mod.d.ts +7 -8
- package/dist/tsup/driver-helpers/mod.js +33 -7
- package/dist/tsup/driver-test-suite/mod.cjs +319 -216
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +7 -7
- package/dist/tsup/driver-test-suite/mod.d.ts +7 -7
- package/dist/tsup/driver-test-suite/mod.js +588 -485
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +17 -5
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +34 -7
- package/dist/tsup/inspector/mod.d.ts +34 -7
- package/dist/tsup/inspector/mod.js +20 -8
- package/dist/tsup/mod.cjs +10 -17
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +56 -9
- package/dist/tsup/mod.d.ts +56 -9
- package/dist/tsup/mod.js +17 -24
- package/dist/tsup/test/mod.cjs +11 -9
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +6 -7
- package/dist/tsup/test/mod.d.ts +6 -7
- package/dist/tsup/test/mod.js +10 -8
- package/dist/tsup/utils.cjs +4 -2
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +11 -1
- package/dist/tsup/utils.d.ts +11 -1
- package/dist/tsup/utils.js +3 -1
- package/package.json +8 -4
- package/src/actor/action.ts +1 -1
- package/src/actor/config.ts +1 -1
- package/src/actor/conn-drivers.ts +205 -0
- package/src/actor/conn-socket.ts +6 -0
- package/src/actor/{connection.ts → conn.ts} +78 -84
- package/src/actor/context.ts +1 -1
- package/src/actor/driver.ts +4 -43
- package/src/actor/instance.ts +162 -86
- package/src/actor/mod.ts +6 -14
- package/src/actor/persisted.ts +2 -5
- package/src/actor/protocol/old.ts +1 -1
- package/src/actor/router-endpoints.ts +147 -138
- package/src/actor/router.ts +89 -52
- package/src/actor/utils.ts +5 -1
- package/src/client/actor-conn.ts +163 -31
- package/src/client/actor-handle.ts +0 -1
- package/src/client/client.ts +2 -2
- package/src/client/config.ts +7 -0
- package/src/client/raw-utils.ts +1 -1
- package/src/client/utils.ts +1 -1
- package/src/common/actor-router-consts.ts +59 -0
- package/src/common/router.ts +2 -1
- package/src/common/versioned-data.ts +5 -5
- package/src/driver-helpers/mod.ts +15 -2
- package/src/driver-test-suite/mod.ts +11 -2
- package/src/driver-test-suite/test-inline-client-driver.ts +40 -22
- package/src/driver-test-suite/tests/actor-conn-state.ts +66 -22
- package/src/driver-test-suite/tests/actor-conn.ts +65 -126
- package/src/driver-test-suite/tests/actor-reconnect.ts +160 -0
- package/src/driver-test-suite/tests/actor-sleep.ts +0 -1
- package/src/driver-test-suite/tests/raw-websocket.ts +0 -35
- package/src/driver-test-suite/utils.ts +8 -3
- package/src/drivers/default.ts +8 -7
- package/src/drivers/engine/actor-driver.ts +67 -44
- package/src/drivers/engine/config.ts +4 -0
- package/src/drivers/file-system/actor.ts +0 -6
- package/src/drivers/file-system/global-state.ts +3 -14
- package/src/drivers/file-system/manager.ts +12 -8
- package/src/inspector/actor.ts +4 -3
- package/src/inspector/config.ts +10 -1
- package/src/inspector/mod.ts +1 -0
- package/src/inspector/utils.ts +23 -4
- package/src/manager/driver.ts +12 -2
- package/src/manager/gateway.ts +407 -0
- package/src/manager/protocol/query.ts +1 -1
- package/src/manager/router.ts +269 -468
- package/src/manager-api/actors.ts +61 -0
- package/src/manager-api/common.ts +4 -0
- package/src/mod.ts +1 -1
- package/src/registry/mod.ts +126 -12
- package/src/registry/serve.ts +8 -3
- package/src/remote-manager-driver/actor-http-client.ts +30 -19
- package/src/remote-manager-driver/actor-websocket-client.ts +45 -18
- package/src/remote-manager-driver/api-endpoints.ts +19 -21
- package/src/remote-manager-driver/api-utils.ts +10 -1
- package/src/remote-manager-driver/mod.ts +53 -53
- package/src/remote-manager-driver/ws-proxy.ts +2 -9
- package/src/test/mod.ts +6 -2
- package/src/utils.ts +21 -2
- package/dist/tsup/chunk-2MD57QF4.js +0 -1794
- package/dist/tsup/chunk-2MD57QF4.js.map +0 -1
- package/dist/tsup/chunk-B2QGJGZQ.js +0 -338
- package/dist/tsup/chunk-B2QGJGZQ.js.map +0 -1
- package/dist/tsup/chunk-CFFKMUYH.js.map +0 -1
- package/dist/tsup/chunk-CKA54YQN.js.map +0 -1
- package/dist/tsup/chunk-FGFT4FVX.cjs.map +0 -1
- package/dist/tsup/chunk-IRMBWX36.cjs +0 -1794
- package/dist/tsup/chunk-IRMBWX36.cjs.map +0 -1
- package/dist/tsup/chunk-L7QRXNWP.js +0 -6562
- package/dist/tsup/chunk-L7QRXNWP.js.map +0 -1
- package/dist/tsup/chunk-LZIBTLEY.cjs.map +0 -1
- package/dist/tsup/chunk-MRZS2J4X.cjs +0 -6562
- package/dist/tsup/chunk-MRZS2J4X.cjs.map +0 -1
- package/dist/tsup/chunk-RM2SVURR.cjs +0 -338
- package/dist/tsup/chunk-RM2SVURR.cjs.map +0 -1
- package/dist/tsup/chunk-WADSS5X4.cjs.map +0 -1
- package/dist/tsup/chunk-YW6Y6VNE.js.map +0 -1
- package/dist/tsup/common-CXCe7s6i.d.cts +0 -218
- package/dist/tsup/common-CXCe7s6i.d.ts +0 -218
- package/dist/tsup/router-endpoints-CctffZNL.d.cts +0 -65
- package/dist/tsup/router-endpoints-DFm1BglJ.d.ts +0 -65
- package/src/actor/generic-conn-driver.ts +0 -246
- package/src/common/fake-event-source.ts +0 -267
- package/src/manager-api/routes/actors-create.ts +0 -16
- package/src/manager-api/routes/actors-delete.ts +0 -4
- package/src/manager-api/routes/actors-get-by-id.ts +0 -7
- package/src/manager-api/routes/actors-get-or-create-by-id.ts +0 -29
- package/src/manager-api/routes/actors-get.ts +0 -7
- package/src/manager-api/routes/common.ts +0 -18
- /package/dist/tsup/{chunk-I5VTWPHW.js.map → chunk-7N56ZUC7.js.map} +0 -0
- /package/dist/tsup/{chunk-PG3K2LI7.js.map → chunk-E4UVJKSV.js.map} +0 -0
- /package/dist/tsup/{chunk-WNGOBAA7.js.map → chunk-PUSQNDJG.js.map} +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// NOTE: This is in a separate file from the router since it needs to be shared between the client & the server. If this was in the router file, the client would end up importing the *entire* actor router and tree shaking would not work.
|
|
2
|
+
|
|
3
|
+
// MARK: Paths
|
|
4
|
+
export const PATH_CONNECT_WEBSOCKET = "/connect/websocket";
|
|
5
|
+
export const PATH_RAW_WEBSOCKET_PREFIX = "/raw/websocket/";
|
|
6
|
+
|
|
7
|
+
// MARK: Headers
|
|
8
|
+
export const HEADER_ACTOR_QUERY = "x-rivet-query";
|
|
9
|
+
|
|
10
|
+
export const HEADER_ENCODING = "x-rivet-encoding";
|
|
11
|
+
|
|
12
|
+
// IMPORTANT: Params must be in headers or in an E2EE part of the request (i.e. NOT the URL or query string) in order to ensure that tokens can be securely passed in params.
|
|
13
|
+
export const HEADER_CONN_PARAMS = "x-rivet-conn-params";
|
|
14
|
+
|
|
15
|
+
export const HEADER_ACTOR_ID = "x-rivet-actor";
|
|
16
|
+
|
|
17
|
+
export const HEADER_CONN_ID = "x-rivet-conn";
|
|
18
|
+
|
|
19
|
+
export const HEADER_CONN_TOKEN = "x-rivet-conn-token";
|
|
20
|
+
|
|
21
|
+
export const HEADER_RIVET_TOKEN = "x-rivet-token";
|
|
22
|
+
|
|
23
|
+
// MARK: Manager Gateway Headers
|
|
24
|
+
export const HEADER_RIVET_TARGET = "x-rivet-target";
|
|
25
|
+
export const HEADER_RIVET_ACTOR = "x-rivet-actor";
|
|
26
|
+
|
|
27
|
+
// MARK: WebSocket Protocol Prefixes
|
|
28
|
+
/** Some servers (such as node-ws & Cloudflare) require explicitly match a certain WebSocket protocol. This gives us a static protocol to match against. */
|
|
29
|
+
export const WS_PROTOCOL_STANDARD = "rivet";
|
|
30
|
+
export const WS_PROTOCOL_TARGET = "rivet_target.";
|
|
31
|
+
export const WS_PROTOCOL_ACTOR = "rivet_actor.";
|
|
32
|
+
export const WS_PROTOCOL_ENCODING = "rivet_encoding.";
|
|
33
|
+
export const WS_PROTOCOL_CONN_PARAMS = "rivet_conn_params.";
|
|
34
|
+
export const WS_PROTOCOL_CONN_ID = "rivet_conn.";
|
|
35
|
+
export const WS_PROTOCOL_CONN_TOKEN = "rivet_conn_token.";
|
|
36
|
+
export const WS_PROTOCOL_TOKEN = "rivet_token.";
|
|
37
|
+
|
|
38
|
+
// MARK: WebSocket Inline Test Protocol Prefixes
|
|
39
|
+
export const WS_PROTOCOL_TRANSPORT = "test_transport.";
|
|
40
|
+
export const WS_PROTOCOL_PATH = "test_path.";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Headers that publics can send from public clients.
|
|
44
|
+
*
|
|
45
|
+
* Used for CORS.
|
|
46
|
+
**/
|
|
47
|
+
export const ALLOWED_PUBLIC_HEADERS = [
|
|
48
|
+
"Content-Type",
|
|
49
|
+
"User-Agent",
|
|
50
|
+
HEADER_ACTOR_QUERY,
|
|
51
|
+
HEADER_ENCODING,
|
|
52
|
+
HEADER_CONN_PARAMS,
|
|
53
|
+
HEADER_ACTOR_ID,
|
|
54
|
+
HEADER_CONN_ID,
|
|
55
|
+
HEADER_CONN_TOKEN,
|
|
56
|
+
HEADER_RIVET_TARGET,
|
|
57
|
+
HEADER_RIVET_ACTOR,
|
|
58
|
+
HEADER_RIVET_TOKEN,
|
|
59
|
+
];
|
package/src/common/router.ts
CHANGED
|
@@ -63,8 +63,8 @@ export class VersionedDataHandler<T> {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
private embedVersion(data: VersionedData<Uint8Array>): Uint8Array {
|
|
66
|
-
const versionBytes = new Uint8Array(
|
|
67
|
-
new DataView(versionBytes.buffer).
|
|
66
|
+
const versionBytes = new Uint8Array(2);
|
|
67
|
+
new DataView(versionBytes.buffer).setUint16(0, data.version, true);
|
|
68
68
|
|
|
69
69
|
const result = new Uint8Array(versionBytes.length + data.data.length);
|
|
70
70
|
result.set(versionBytes);
|
|
@@ -74,15 +74,15 @@ export class VersionedDataHandler<T> {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
private extractVersion(bytes: Uint8Array): VersionedData<Uint8Array> {
|
|
77
|
-
if (bytes.length <
|
|
77
|
+
if (bytes.length < 2) {
|
|
78
78
|
throw new Error("Invalid versioned data: too short");
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
const version = new DataView(bytes.buffer, bytes.byteOffset).
|
|
81
|
+
const version = new DataView(bytes.buffer, bytes.byteOffset).getUint16(
|
|
82
82
|
0,
|
|
83
83
|
true,
|
|
84
84
|
);
|
|
85
|
-
const data = bytes.slice(
|
|
85
|
+
const data = bytes.slice(2);
|
|
86
86
|
|
|
87
87
|
return { version, data };
|
|
88
88
|
}
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
export type { ActorDriver } from "@/actor/driver";
|
|
2
2
|
export type { ActorInstance, AnyActorInstance } from "@/actor/instance";
|
|
3
3
|
export {
|
|
4
|
+
ALLOWED_PUBLIC_HEADERS,
|
|
4
5
|
HEADER_ACTOR_ID,
|
|
5
6
|
HEADER_ACTOR_QUERY,
|
|
6
|
-
HEADER_AUTH_DATA,
|
|
7
7
|
HEADER_CONN_ID,
|
|
8
8
|
HEADER_CONN_PARAMS,
|
|
9
9
|
HEADER_CONN_TOKEN,
|
|
10
10
|
HEADER_ENCODING,
|
|
11
|
-
|
|
11
|
+
HEADER_RIVET_ACTOR,
|
|
12
|
+
HEADER_RIVET_TARGET,
|
|
13
|
+
PATH_CONNECT_WEBSOCKET,
|
|
14
|
+
PATH_RAW_WEBSOCKET_PREFIX,
|
|
15
|
+
WS_PROTOCOL_ACTOR,
|
|
16
|
+
WS_PROTOCOL_CONN_ID,
|
|
17
|
+
WS_PROTOCOL_CONN_PARAMS,
|
|
18
|
+
WS_PROTOCOL_CONN_TOKEN,
|
|
19
|
+
WS_PROTOCOL_ENCODING,
|
|
20
|
+
WS_PROTOCOL_PATH,
|
|
21
|
+
WS_PROTOCOL_STANDARD,
|
|
22
|
+
WS_PROTOCOL_TARGET,
|
|
23
|
+
WS_PROTOCOL_TRANSPORT,
|
|
24
|
+
} from "@/common/actor-router-consts";
|
|
12
25
|
export type {
|
|
13
26
|
ActorOutput,
|
|
14
27
|
CreateInput,
|
|
@@ -4,6 +4,7 @@ import { bundleRequire } from "bundle-require";
|
|
|
4
4
|
import invariant from "invariant";
|
|
5
5
|
import { describe } from "vitest";
|
|
6
6
|
import type { Transport } from "@/client/mod";
|
|
7
|
+
import { configureInspectorAccessToken } from "@/inspector/utils";
|
|
7
8
|
import { createManagerRouter } from "@/manager/router";
|
|
8
9
|
import type { DriverConfig, Registry, RunConfig } from "@/mod";
|
|
9
10
|
import { RunConfigSchema } from "@/registry/run-config";
|
|
@@ -22,6 +23,7 @@ import { runActorInlineClientTests } from "./tests/actor-inline-client";
|
|
|
22
23
|
import { runActorInspectorTests } from "./tests/actor-inspector";
|
|
23
24
|
import { runActorMetadataTests } from "./tests/actor-metadata";
|
|
24
25
|
import { runActorOnStateChangeTests } from "./tests/actor-onstatechange";
|
|
26
|
+
import { runActorReconnectTests } from "./tests/actor-reconnect";
|
|
25
27
|
import { runActorVarsTests } from "./tests/actor-vars";
|
|
26
28
|
import { runManagerDriverTests } from "./tests/manager-driver";
|
|
27
29
|
import { runRawHttpTests } from "./tests/raw-http";
|
|
@@ -32,6 +34,7 @@ import { runRequestAccessTests } from "./tests/request-access";
|
|
|
32
34
|
export interface SkipTests {
|
|
33
35
|
schedule?: boolean;
|
|
34
36
|
sleep?: boolean;
|
|
37
|
+
sse?: boolean;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
export interface DriverTestConfig {
|
|
@@ -86,7 +89,10 @@ export function runDriverTests(
|
|
|
86
89
|
runActorDriverTests(driverTestConfig);
|
|
87
90
|
runManagerDriverTests(driverTestConfig);
|
|
88
91
|
|
|
89
|
-
|
|
92
|
+
const transports: Transport[] = driverTestConfig.skip?.sse
|
|
93
|
+
? ["websocket"]
|
|
94
|
+
: ["websocket", "sse"];
|
|
95
|
+
for (const transport of transports) {
|
|
90
96
|
describe(`transport (${transport})`, () => {
|
|
91
97
|
runActorConnTests({
|
|
92
98
|
...driverTestConfig,
|
|
@@ -95,6 +101,8 @@ export function runDriverTests(
|
|
|
95
101
|
|
|
96
102
|
runActorConnStateTests({ ...driverTestConfig, transport });
|
|
97
103
|
|
|
104
|
+
runActorReconnectTests({ ...driverTestConfig, transport });
|
|
105
|
+
|
|
98
106
|
runRequestAccessTests({ ...driverTestConfig, transport });
|
|
99
107
|
|
|
100
108
|
runActorDriverTestsWithTransport({ ...driverTestConfig, transport });
|
|
@@ -193,11 +201,12 @@ export async function createTestRuntime(
|
|
|
193
201
|
|
|
194
202
|
// Create router
|
|
195
203
|
const managerDriver = driver.manager(registry.config, config);
|
|
204
|
+
configureInspectorAccessToken(config, managerDriver);
|
|
196
205
|
const { router } = createManagerRouter(
|
|
197
206
|
registry.config,
|
|
198
207
|
config,
|
|
199
208
|
managerDriver,
|
|
200
|
-
|
|
209
|
+
undefined,
|
|
201
210
|
);
|
|
202
211
|
|
|
203
212
|
// Inject WebSocket
|
|
@@ -3,14 +3,20 @@ import type { Context as HonoContext } from "hono";
|
|
|
3
3
|
import invariant from "invariant";
|
|
4
4
|
import type { WebSocket } from "ws";
|
|
5
5
|
import type { Encoding } from "@/actor/protocol/serde";
|
|
6
|
+
import { assertUnreachable } from "@/actor/utils";
|
|
7
|
+
import { ActorError as ClientActorError } from "@/client/errors";
|
|
8
|
+
import type { Transport } from "@/client/mod";
|
|
6
9
|
import {
|
|
7
10
|
HEADER_ACTOR_QUERY,
|
|
8
11
|
HEADER_CONN_PARAMS,
|
|
9
12
|
HEADER_ENCODING,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
WS_PROTOCOL_ACTOR,
|
|
14
|
+
WS_PROTOCOL_CONN_PARAMS,
|
|
15
|
+
WS_PROTOCOL_ENCODING,
|
|
16
|
+
WS_PROTOCOL_PATH,
|
|
17
|
+
WS_PROTOCOL_TARGET,
|
|
18
|
+
WS_PROTOCOL_TRANSPORT,
|
|
19
|
+
} from "@/common/actor-router-consts";
|
|
14
20
|
import type { UniversalEventSource } from "@/common/eventsource-interface";
|
|
15
21
|
import type { DeconstructedError } from "@/common/utils";
|
|
16
22
|
import { importWebSocket } from "@/common/websocket";
|
|
@@ -111,7 +117,8 @@ export function createTestInlineClientDriver(
|
|
|
111
117
|
headers,
|
|
112
118
|
body: actorRequest.body,
|
|
113
119
|
signal: actorRequest.signal,
|
|
114
|
-
|
|
120
|
+
duplex: "half",
|
|
121
|
+
} as RequestInit),
|
|
115
122
|
);
|
|
116
123
|
|
|
117
124
|
// Check if it's an error response from our handler
|
|
@@ -153,39 +160,48 @@ export function createTestInlineClientDriver(
|
|
|
153
160
|
actorId: string,
|
|
154
161
|
encoding: Encoding,
|
|
155
162
|
params: unknown,
|
|
163
|
+
connId?: string,
|
|
164
|
+
connToken?: string,
|
|
156
165
|
): Promise<UniversalWebSocket> {
|
|
157
166
|
const WebSocket = await importWebSocket();
|
|
158
167
|
|
|
159
168
|
// Normalize path to match other drivers
|
|
160
169
|
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
161
170
|
|
|
162
|
-
logger().debug({
|
|
163
|
-
msg: "creating websocket connection via test inline driver",
|
|
164
|
-
});
|
|
165
|
-
|
|
166
171
|
// Create WebSocket connection to the test endpoint
|
|
167
|
-
// Use a placeholder path and pass the actual path as a query param to avoid mixing user query params with internal ones
|
|
168
172
|
const wsUrl = new URL(
|
|
169
173
|
`${endpoint}/.test/inline-driver/connect-websocket/ws`,
|
|
170
174
|
);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
wsUrl.
|
|
175
|
-
|
|
175
|
+
|
|
176
|
+
logger().debug({
|
|
177
|
+
msg: "creating websocket connection via test inline driver",
|
|
178
|
+
url: wsUrl.toString(),
|
|
179
|
+
});
|
|
176
180
|
|
|
177
181
|
// Convert http/https to ws/wss
|
|
178
182
|
const wsProtocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
179
|
-
const finalWsUrl = `${wsProtocol}//${wsUrl.host}${wsUrl.pathname}
|
|
183
|
+
const finalWsUrl = `${wsProtocol}//${wsUrl.host}${wsUrl.pathname}`;
|
|
180
184
|
|
|
181
185
|
logger().debug({ msg: "connecting to websocket", url: finalWsUrl });
|
|
182
186
|
|
|
187
|
+
// Build protocols for the connection
|
|
188
|
+
const protocols: string[] = [];
|
|
189
|
+
protocols.push(`${WS_PROTOCOL_TARGET}actor`);
|
|
190
|
+
protocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);
|
|
191
|
+
protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
|
|
192
|
+
protocols.push(`${WS_PROTOCOL_TRANSPORT}${transport}`);
|
|
193
|
+
protocols.push(
|
|
194
|
+
`${WS_PROTOCOL_PATH}${encodeURIComponent(normalizedPath)}`,
|
|
195
|
+
);
|
|
196
|
+
if (params !== undefined) {
|
|
197
|
+
protocols.push(
|
|
198
|
+
`${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
183
202
|
// Create and return the WebSocket
|
|
184
203
|
// Node & browser WebSocket types are incompatible
|
|
185
|
-
const ws = new WebSocket(finalWsUrl,
|
|
186
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
187
|
-
"rivetkit",
|
|
188
|
-
]) as any;
|
|
204
|
+
const ws = new WebSocket(finalWsUrl, protocols) as any;
|
|
189
205
|
|
|
190
206
|
return ws;
|
|
191
207
|
},
|
|
@@ -202,7 +218,6 @@ export function createTestInlineClientDriver(
|
|
|
202
218
|
_actorId: string,
|
|
203
219
|
_encoding: Encoding,
|
|
204
220
|
_params: unknown,
|
|
205
|
-
_authData: unknown,
|
|
206
221
|
): Promise<Response> {
|
|
207
222
|
throw "UNIMPLEMENTED";
|
|
208
223
|
// const upgradeWebSocket = this.#runConfig.getUpgradeWebSocket?.();
|
|
@@ -214,6 +229,8 @@ export function createTestInlineClientDriver(
|
|
|
214
229
|
displayInformation(): ManagerDisplayInformation {
|
|
215
230
|
return { name: "Test Inline", properties: {} };
|
|
216
231
|
},
|
|
232
|
+
// TODO:
|
|
233
|
+
getOrCreateInspectorAccessToken: () => "",
|
|
217
234
|
|
|
218
235
|
// action: async <Args extends Array<unknown> = unknown[], Response = unknown>(
|
|
219
236
|
// _c: HonoContext | undefined,
|
|
@@ -560,7 +577,8 @@ async function makeInlineRequest<T>(
|
|
|
560
577
|
method,
|
|
561
578
|
args,
|
|
562
579
|
} satisfies TestInlineDriverCallRequest),
|
|
563
|
-
|
|
580
|
+
duplex: "half",
|
|
581
|
+
} as RequestInit);
|
|
564
582
|
|
|
565
583
|
if (!response.ok) {
|
|
566
584
|
throw new Error(`Failed to call inline ${method}: ${response.statusText}`);
|
|
@@ -145,38 +145,79 @@ export function runActorConnStateTests(driverTestConfig: DriverTestConfig) {
|
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
describe("Connection Lifecycle", () => {
|
|
148
|
-
test(
|
|
148
|
+
test.skipIf(
|
|
149
|
+
driverTestConfig.transport === "sse" &&
|
|
150
|
+
driverTestConfig.clientType === "inline",
|
|
151
|
+
)("should track connection and disconnection events", async (c) => {
|
|
149
152
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
150
153
|
|
|
154
|
+
const debugHandle = client.connStateActor.getOrCreate(undefined, {
|
|
155
|
+
params: { noCount: true },
|
|
156
|
+
});
|
|
157
|
+
|
|
151
158
|
// Create a connection
|
|
152
|
-
const
|
|
153
|
-
const conn = handle.connect();
|
|
159
|
+
const conn = client.connStateActor.getOrCreate().connect();
|
|
154
160
|
|
|
155
161
|
// Get the connection state
|
|
156
162
|
const connState = await conn.getConnectionState();
|
|
157
163
|
|
|
158
164
|
// Verify the connection is tracked
|
|
159
|
-
|
|
160
|
-
|
|
165
|
+
await vi.waitFor(async () => {
|
|
166
|
+
const connectionIds = await debugHandle.getConnectionIds();
|
|
167
|
+
expect(connectionIds).toContain(connState.id);
|
|
168
|
+
});
|
|
161
169
|
|
|
162
170
|
// Initial disconnection count
|
|
163
|
-
|
|
171
|
+
await vi.waitFor(async () => {
|
|
172
|
+
const disconnects = await debugHandle.getDisconnectionCount();
|
|
173
|
+
expect(disconnects).toBe(0);
|
|
174
|
+
});
|
|
164
175
|
|
|
165
176
|
// Dispose the connection
|
|
166
177
|
await conn.dispose();
|
|
167
178
|
|
|
179
|
+
// Validate conn count
|
|
180
|
+
await vi.waitFor(
|
|
181
|
+
async () => {
|
|
182
|
+
console.log("disconnects before");
|
|
183
|
+
const disconnects = await debugHandle.getDisconnectionCount();
|
|
184
|
+
console.log("disconnects", disconnects);
|
|
185
|
+
expect(disconnects).toBe(1);
|
|
186
|
+
},
|
|
187
|
+
// SSE takes a long time to disconnect on CF Workers
|
|
188
|
+
{
|
|
189
|
+
timeout: 10_000,
|
|
190
|
+
interval: 100,
|
|
191
|
+
},
|
|
192
|
+
);
|
|
193
|
+
|
|
168
194
|
// Create a new connection to check the disconnection count
|
|
169
|
-
const newConn =
|
|
195
|
+
const newConn = client.connStateActor.getOrCreate().connect();
|
|
170
196
|
|
|
171
|
-
// Verify
|
|
197
|
+
// Verify the connection is tracked
|
|
172
198
|
await vi.waitFor(async () => {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
expect(
|
|
199
|
+
const connectionIds = await debugHandle.getConnectionIds();
|
|
200
|
+
console.log("conn ids", connectionIds);
|
|
201
|
+
expect(connectionIds.length).toBe(1);
|
|
176
202
|
});
|
|
177
203
|
|
|
178
204
|
// Clean up
|
|
179
205
|
await newConn.dispose();
|
|
206
|
+
|
|
207
|
+
// Verify disconnection was tracked
|
|
208
|
+
await vi.waitFor(
|
|
209
|
+
async () => {
|
|
210
|
+
console.log("A");
|
|
211
|
+
const disconnects = await debugHandle.getDisconnectionCount();
|
|
212
|
+
console.log(`B ${disconnects}`);
|
|
213
|
+
expect(disconnects).toBe(2);
|
|
214
|
+
},
|
|
215
|
+
// SSE takes a long time to disconnect on CF Workers
|
|
216
|
+
{
|
|
217
|
+
timeout: 10_000,
|
|
218
|
+
interval: 100,
|
|
219
|
+
},
|
|
220
|
+
);
|
|
180
221
|
});
|
|
181
222
|
|
|
182
223
|
test("should update connection state", async (c) => {
|
|
@@ -228,17 +269,20 @@ export function runActorConnStateTests(driverTestConfig: DriverTestConfig) {
|
|
|
228
269
|
receivedMessages.push(data);
|
|
229
270
|
});
|
|
230
271
|
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
272
|
+
// TODO: SSE has race condition between subscrib eand publish message
|
|
273
|
+
await vi.waitFor(async () => {
|
|
274
|
+
// Send message from first connection to second
|
|
275
|
+
const success = await conn1.sendToConnection(
|
|
276
|
+
state2.id,
|
|
277
|
+
"Hello from conn1",
|
|
278
|
+
);
|
|
279
|
+
expect(success).toBe(true);
|
|
280
|
+
|
|
281
|
+
// Verify message was received
|
|
282
|
+
expect(receivedMessages.length).toBe(1);
|
|
283
|
+
expect(receivedMessages[0].from).toBe(state1.id);
|
|
284
|
+
expect(receivedMessages[0].message).toBe("Hello from conn1");
|
|
285
|
+
});
|
|
242
286
|
|
|
243
287
|
// Clean up
|
|
244
288
|
await conn1.dispose();
|