rivetkit 2.0.3 → 2.0.5
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/README.md +11 -0
- package/dist/schemas/actor-persist/v1.ts +21 -24
- package/dist/schemas/client-protocol/v1.ts +6 -0
- package/dist/tsup/actor/errors.cjs +10 -2
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +17 -4
- package/dist/tsup/actor/errors.d.ts +17 -4
- package/dist/tsup/actor/errors.js +11 -3
- package/dist/tsup/{chunk-4NSUQZ2H.js → chunk-2MD57QF4.js} +119 -115
- package/dist/tsup/chunk-2MD57QF4.js.map +1 -0
- package/dist/tsup/{chunk-GIR3AFFI.cjs → chunk-5QGQK44L.cjs} +103 -44
- package/dist/tsup/chunk-5QGQK44L.cjs.map +1 -0
- package/dist/tsup/chunk-5YTI25C3.cjs +250 -0
- package/dist/tsup/chunk-5YTI25C3.cjs.map +1 -0
- package/dist/tsup/chunk-B2QGJGZQ.js +338 -0
- package/dist/tsup/chunk-B2QGJGZQ.js.map +1 -0
- package/dist/tsup/{chunk-3H7O2A7I.js → chunk-CFFKMUYH.js} +61 -22
- package/dist/tsup/chunk-CFFKMUYH.js.map +1 -0
- package/dist/tsup/{chunk-FLMTTN27.js → chunk-CKA54YQN.js} +15 -8
- package/dist/tsup/chunk-CKA54YQN.js.map +1 -0
- package/dist/tsup/chunk-D7NWUCRK.cjs +20 -0
- package/dist/tsup/chunk-D7NWUCRK.cjs.map +1 -0
- package/dist/tsup/{chunk-FCCPJNMA.cjs → chunk-FGFT4FVX.cjs} +12 -27
- package/dist/tsup/chunk-FGFT4FVX.cjs.map +1 -0
- package/dist/tsup/chunk-I5VTWPHW.js +20 -0
- package/dist/tsup/chunk-I5VTWPHW.js.map +1 -0
- package/dist/tsup/{chunk-6WKQDDUD.cjs → chunk-IRMBWX36.cjs} +146 -142
- package/dist/tsup/chunk-IRMBWX36.cjs.map +1 -0
- package/dist/tsup/chunk-L7QRXNWP.js +6562 -0
- package/dist/tsup/chunk-L7QRXNWP.js.map +1 -0
- package/dist/tsup/{chunk-R2OPSKIV.cjs → chunk-LZIBTLEY.cjs} +20 -13
- package/dist/tsup/chunk-LZIBTLEY.cjs.map +1 -0
- package/dist/tsup/chunk-MRZS2J4X.cjs +6562 -0
- package/dist/tsup/chunk-MRZS2J4X.cjs.map +1 -0
- package/dist/tsup/{chunk-PO4VLDWA.js → chunk-PG3K2LI7.js} +3 -5
- package/dist/tsup/chunk-PG3K2LI7.js.map +1 -0
- package/dist/tsup/{chunk-TZJKSBUQ.cjs → chunk-PHSQJ6QI.cjs} +3 -5
- package/dist/tsup/chunk-PHSQJ6QI.cjs.map +1 -0
- package/dist/tsup/chunk-RM2SVURR.cjs +338 -0
- package/dist/tsup/chunk-RM2SVURR.cjs.map +1 -0
- package/dist/tsup/{chunk-OGAPU3UG.cjs → chunk-WADSS5X4.cjs} +66 -27
- package/dist/tsup/chunk-WADSS5X4.cjs.map +1 -0
- package/dist/tsup/chunk-WNGOBAA7.js +250 -0
- package/dist/tsup/chunk-WNGOBAA7.js.map +1 -0
- package/dist/tsup/{chunk-INGJP237.js → chunk-YPZFLUO6.js} +103 -44
- package/dist/tsup/chunk-YPZFLUO6.js.map +1 -0
- package/dist/tsup/{chunk-6PDXBYI5.js → chunk-YW6Y6VNE.js} +8 -23
- package/dist/tsup/chunk-YW6Y6VNE.js.map +1 -0
- package/dist/tsup/client/mod.cjs +10 -10
- package/dist/tsup/client/mod.d.cts +7 -13
- package/dist/tsup/client/mod.d.ts +7 -13
- package/dist/tsup/client/mod.js +9 -9
- package/dist/tsup/common/log.cjs +12 -4
- package/dist/tsup/common/log.cjs.map +1 -1
- package/dist/tsup/common/log.d.cts +23 -17
- package/dist/tsup/common/log.d.ts +23 -17
- package/dist/tsup/common/log.js +15 -7
- package/dist/tsup/common/websocket.cjs +5 -5
- package/dist/tsup/common/websocket.js +4 -4
- package/dist/tsup/{common-CpqORuCq.d.cts → common-CXCe7s6i.d.cts} +2 -2
- package/dist/tsup/{common-CpqORuCq.d.ts → common-CXCe7s6i.d.ts} +2 -2
- package/dist/tsup/{connection-BwUMoe6n.d.ts → connection-BvE-Oq7t.d.ts} +215 -234
- package/dist/tsup/{connection-BR_Ve4ku.d.cts → connection-DTzmWwU5.d.cts} +215 -234
- package/dist/tsup/driver-helpers/mod.cjs +6 -9
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +5 -6
- package/dist/tsup/driver-helpers/mod.d.ts +5 -6
- package/dist/tsup/driver-helpers/mod.js +6 -9
- package/dist/tsup/driver-test-suite/mod.cjs +615 -1357
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +12 -6
- package/dist/tsup/driver-test-suite/mod.d.ts +12 -6
- package/dist/tsup/driver-test-suite/mod.js +1334 -2076
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -8
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +3 -3
- package/dist/tsup/inspector/mod.d.ts +3 -3
- package/dist/tsup/inspector/mod.js +8 -10
- package/dist/tsup/mod.cjs +9 -15
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +47 -42
- package/dist/tsup/mod.d.ts +47 -42
- package/dist/tsup/mod.js +10 -16
- package/dist/tsup/{router-endpoints-DAbqVFx2.d.ts → router-endpoints-CctffZNL.d.cts} +2 -3
- package/dist/tsup/{router-endpoints-AYkXG8Tl.d.cts → router-endpoints-DFm1BglJ.d.ts} +2 -3
- package/dist/tsup/test/mod.cjs +10 -14
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +4 -5
- package/dist/tsup/test/mod.d.ts +4 -5
- package/dist/tsup/test/mod.js +9 -13
- package/dist/tsup/{utils-CT0cv4jd.d.ts → utils-fwx3o3K9.d.cts} +1 -0
- package/dist/tsup/{utils-CT0cv4jd.d.cts → utils-fwx3o3K9.d.ts} +1 -0
- package/dist/tsup/utils.cjs +5 -3
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +19 -2
- package/dist/tsup/utils.d.ts +19 -2
- package/dist/tsup/utils.js +4 -2
- package/package.json +6 -6
- package/src/actor/action.ts +1 -5
- package/src/actor/config.ts +27 -295
- package/src/actor/connection.ts +9 -12
- package/src/actor/context.ts +1 -4
- package/src/actor/definition.ts +7 -11
- package/src/actor/errors.ts +98 -36
- package/src/actor/generic-conn-driver.ts +28 -16
- package/src/actor/instance.ts +177 -133
- package/src/actor/log.ts +4 -13
- package/src/actor/mod.ts +0 -5
- package/src/actor/protocol/old.ts +42 -26
- package/src/actor/protocol/serde.ts +1 -1
- package/src/actor/router-endpoints.ts +47 -39
- package/src/actor/router.ts +22 -19
- package/src/actor/unstable-react.ts +1 -1
- package/src/actor/utils.ts +6 -2
- package/src/client/actor-common.ts +1 -1
- package/src/client/actor-conn.ts +152 -91
- package/src/client/actor-handle.ts +85 -25
- package/src/client/actor-query.ts +65 -0
- package/src/client/client.ts +29 -98
- package/src/client/config.ts +44 -0
- package/src/client/errors.ts +1 -0
- package/src/client/log.ts +2 -4
- package/src/client/mod.ts +16 -12
- package/src/client/raw-utils.ts +82 -25
- package/src/client/utils.ts +5 -3
- package/src/common/fake-event-source.ts +10 -9
- package/src/common/inline-websocket-adapter2.ts +39 -30
- package/src/common/log.ts +176 -101
- package/src/common/logfmt.ts +21 -30
- package/src/common/router.ts +12 -19
- package/src/common/utils.ts +27 -13
- package/src/common/websocket.ts +0 -1
- package/src/driver-helpers/mod.ts +1 -1
- package/src/driver-test-suite/log.ts +1 -3
- package/src/driver-test-suite/mod.ts +87 -61
- package/src/driver-test-suite/test-inline-client-driver.ts +441 -255
- package/src/driver-test-suite/tests/actor-error-handling.ts +4 -12
- package/src/driver-test-suite/tests/actor-handle.ts +33 -0
- package/src/driver-test-suite/tests/actor-inspector.ts +2 -1
- package/src/driver-test-suite/tests/manager-driver.ts +5 -3
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -226
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -392
- package/src/driver-test-suite/tests/request-access.ts +112 -126
- package/src/driver-test-suite/utils.ts +10 -6
- package/src/drivers/default.ts +7 -4
- package/src/drivers/engine/actor-driver.ts +22 -13
- package/src/drivers/engine/config.ts +2 -10
- package/src/drivers/engine/kv.ts +1 -1
- package/src/drivers/engine/log.ts +1 -3
- package/src/drivers/engine/mod.ts +2 -3
- package/src/drivers/file-system/actor.ts +1 -1
- package/src/drivers/file-system/global-state.ts +36 -21
- package/src/drivers/file-system/log.ts +1 -3
- package/src/drivers/file-system/manager.ts +33 -15
- package/src/inspector/config.ts +9 -4
- package/src/inspector/log.ts +1 -1
- package/src/inspector/manager.ts +2 -2
- package/src/inspector/utils.ts +1 -1
- package/src/manager/driver.ts +10 -2
- package/src/manager/hono-websocket-adapter.ts +21 -12
- package/src/manager/log.ts +2 -4
- package/src/manager/mod.ts +1 -1
- package/src/manager/router.ts +378 -1390
- package/src/manager-api/routes/actors-create.ts +16 -0
- package/src/manager-api/routes/actors-delete.ts +4 -0
- package/src/manager-api/routes/actors-get-by-id.ts +7 -0
- package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
- package/src/manager-api/routes/actors-get.ts +7 -0
- package/src/manager-api/routes/common.ts +18 -0
- package/src/mod.ts +0 -2
- package/src/registry/config.ts +1 -1
- package/src/registry/log.ts +2 -4
- package/src/registry/mod.ts +63 -34
- package/src/registry/run-config.ts +39 -26
- package/src/registry/serve.ts +4 -5
- package/src/remote-manager-driver/actor-http-client.ts +74 -0
- package/src/remote-manager-driver/actor-websocket-client.ts +64 -0
- package/src/remote-manager-driver/api-endpoints.ts +79 -0
- package/src/remote-manager-driver/api-utils.ts +46 -0
- package/src/remote-manager-driver/log.ts +5 -0
- package/src/remote-manager-driver/mod.ts +275 -0
- package/src/{drivers/engine → remote-manager-driver}/ws-proxy.ts +24 -14
- package/src/serde.ts +8 -2
- package/src/test/log.ts +1 -3
- package/src/test/mod.ts +17 -16
- package/src/utils.ts +53 -0
- package/dist/tsup/chunk-2CRLFV6Z.cjs +0 -202
- package/dist/tsup/chunk-2CRLFV6Z.cjs.map +0 -1
- package/dist/tsup/chunk-3H7O2A7I.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-4NSUQZ2H.js.map +0 -1
- package/dist/tsup/chunk-6PDXBYI5.js.map +0 -1
- package/dist/tsup/chunk-6WKQDDUD.cjs.map +0 -1
- package/dist/tsup/chunk-CTBOSFUH.cjs +0 -116
- package/dist/tsup/chunk-CTBOSFUH.cjs.map +0 -1
- package/dist/tsup/chunk-EGVZZFE2.js +0 -2857
- package/dist/tsup/chunk-EGVZZFE2.js.map +0 -1
- package/dist/tsup/chunk-FCCPJNMA.cjs.map +0 -1
- package/dist/tsup/chunk-FLMTTN27.js.map +0 -1
- package/dist/tsup/chunk-GIR3AFFI.cjs.map +0 -1
- package/dist/tsup/chunk-INGJP237.js.map +0 -1
- package/dist/tsup/chunk-KJCJLKRM.js +0 -116
- package/dist/tsup/chunk-KJCJLKRM.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-O2MBYIXO.cjs +0 -2857
- package/dist/tsup/chunk-O2MBYIXO.cjs.map +0 -1
- package/dist/tsup/chunk-OGAPU3UG.cjs.map +0 -1
- package/dist/tsup/chunk-OV6AYD4S.js +0 -4406
- package/dist/tsup/chunk-OV6AYD4S.js.map +0 -1
- package/dist/tsup/chunk-PO4VLDWA.js.map +0 -1
- package/dist/tsup/chunk-R2OPSKIV.cjs.map +0 -1
- package/dist/tsup/chunk-TZJKSBUQ.cjs.map +0 -1
- package/dist/tsup/chunk-UBUC5C3G.cjs +0 -189
- package/dist/tsup/chunk-UBUC5C3G.cjs.map +0 -1
- package/dist/tsup/chunk-UIM22YJL.cjs +0 -4406
- package/dist/tsup/chunk-UIM22YJL.cjs.map +0 -1
- package/dist/tsup/chunk-URVFQMYI.cjs +0 -230
- package/dist/tsup/chunk-URVFQMYI.cjs.map +0 -1
- package/dist/tsup/chunk-UVUPOS46.js +0 -230
- package/dist/tsup/chunk-UVUPOS46.js.map +0 -1
- package/dist/tsup/chunk-VRRHBNJC.js +0 -189
- package/dist/tsup/chunk-VRRHBNJC.js.map +0 -1
- package/dist/tsup/chunk-XFSS33EQ.js +0 -202
- package/dist/tsup/chunk-XFSS33EQ.js.map +0 -1
- package/src/client/http-client-driver.ts +0 -326
- package/src/driver-test-suite/tests/actor-auth.ts +0 -591
- package/src/drivers/engine/api-endpoints.ts +0 -128
- package/src/drivers/engine/api-utils.ts +0 -70
- package/src/drivers/engine/manager-driver.ts +0 -391
- package/src/inline-client-driver/log.ts +0 -7
- package/src/inline-client-driver/mod.ts +0 -385
- package/src/manager/auth.ts +0 -121
- /package/src/{drivers/engine → actor}/keys.test.ts +0 -0
- /package/src/{drivers/engine → actor}/keys.ts +0 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import * as cbor from "cbor-x";
|
|
2
|
+
import type { Hono, Context as HonoContext } from "hono";
|
|
3
|
+
import invariant from "invariant";
|
|
4
|
+
import { ActorAlreadyExists } from "@/actor/errors";
|
|
5
|
+
import { deserializeActorKey, serializeActorKey } from "@/actor/keys";
|
|
6
|
+
import type { ClientConfig } from "@/client/client";
|
|
7
|
+
import { noopNext } from "@/common/utils";
|
|
8
|
+
import type {
|
|
9
|
+
ActorOutput,
|
|
10
|
+
CreateInput,
|
|
11
|
+
GetForIdInput,
|
|
12
|
+
GetOrCreateWithKeyInput,
|
|
13
|
+
GetWithKeyInput,
|
|
14
|
+
ManagerDisplayInformation,
|
|
15
|
+
ManagerDriver,
|
|
16
|
+
} from "@/driver-helpers/mod";
|
|
17
|
+
import type { ManagerInspector } from "@/inspector/manager";
|
|
18
|
+
import type { Encoding, RegistryConfig, UniversalWebSocket } from "@/mod";
|
|
19
|
+
import type { RunConfig } from "@/registry/run-config";
|
|
20
|
+
import { combineUrlPath } from "@/utils";
|
|
21
|
+
import { sendHttpRequestToActor } from "./actor-http-client";
|
|
22
|
+
import {
|
|
23
|
+
buildGuardHeadersForWebSocket,
|
|
24
|
+
openWebSocketToActor,
|
|
25
|
+
} from "./actor-websocket-client";
|
|
26
|
+
import {
|
|
27
|
+
createActor,
|
|
28
|
+
destroyActor,
|
|
29
|
+
getActor,
|
|
30
|
+
getActorById,
|
|
31
|
+
getOrCreateActorById,
|
|
32
|
+
} from "./api-endpoints";
|
|
33
|
+
import { EngineApiError, getEndpoint } from "./api-utils";
|
|
34
|
+
import { logger } from "./log";
|
|
35
|
+
import { createWebSocketProxy } from "./ws-proxy";
|
|
36
|
+
|
|
37
|
+
// TODO:
|
|
38
|
+
// // Lazily import the dynamic imports so we don't have to turn `createClient` in to an async fn
|
|
39
|
+
// const dynamicImports = (async () => {
|
|
40
|
+
// // Import dynamic dependencies
|
|
41
|
+
// const [WebSocket, EventSource] = await Promise.all([
|
|
42
|
+
// importWebSocket(),
|
|
43
|
+
// importEventSource(),
|
|
44
|
+
// ]);
|
|
45
|
+
// return {
|
|
46
|
+
// WebSocket,
|
|
47
|
+
// EventSource,
|
|
48
|
+
// };
|
|
49
|
+
// })();
|
|
50
|
+
|
|
51
|
+
export class RemoteManagerDriver implements ManagerDriver {
|
|
52
|
+
#config: ClientConfig;
|
|
53
|
+
|
|
54
|
+
constructor(runConfig: ClientConfig) {
|
|
55
|
+
this.#config = runConfig;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async getForId({
|
|
59
|
+
c,
|
|
60
|
+
name,
|
|
61
|
+
actorId,
|
|
62
|
+
}: GetForIdInput): Promise<ActorOutput | undefined> {
|
|
63
|
+
// Fetch from API if not in cache
|
|
64
|
+
try {
|
|
65
|
+
const response = await getActor(this.#config, actorId);
|
|
66
|
+
|
|
67
|
+
// Validate name matches
|
|
68
|
+
if (response.actor.name !== name) {
|
|
69
|
+
logger().debug({
|
|
70
|
+
msg: "actor name mismatch from api",
|
|
71
|
+
actorId,
|
|
72
|
+
apiName: response.actor.name,
|
|
73
|
+
requestedName: name,
|
|
74
|
+
});
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const keyRaw = response.actor.key;
|
|
79
|
+
invariant(keyRaw, `actor ${actorId} should have key`);
|
|
80
|
+
const key = deserializeActorKey(keyRaw);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
actorId,
|
|
84
|
+
name,
|
|
85
|
+
key,
|
|
86
|
+
};
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (
|
|
89
|
+
error instanceof EngineApiError &&
|
|
90
|
+
(error as EngineApiError).group === "actor" &&
|
|
91
|
+
(error as EngineApiError).code === "not_found"
|
|
92
|
+
) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async getWithKey({
|
|
100
|
+
c,
|
|
101
|
+
name,
|
|
102
|
+
key,
|
|
103
|
+
}: GetWithKeyInput): Promise<ActorOutput | undefined> {
|
|
104
|
+
logger().debug({ msg: "getWithKey: searching for actor", name, key });
|
|
105
|
+
|
|
106
|
+
// If not in local cache, fetch by key from API
|
|
107
|
+
try {
|
|
108
|
+
const response = await getActorById(this.#config, name, key);
|
|
109
|
+
|
|
110
|
+
if (!response.actor_id) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const actorId = response.actor_id;
|
|
115
|
+
|
|
116
|
+
logger().debug({
|
|
117
|
+
msg: "getWithKey: found actor via api",
|
|
118
|
+
actorId,
|
|
119
|
+
name,
|
|
120
|
+
key,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
actorId,
|
|
125
|
+
name,
|
|
126
|
+
key,
|
|
127
|
+
};
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (
|
|
130
|
+
error instanceof EngineApiError &&
|
|
131
|
+
(error as EngineApiError).group === "actor" &&
|
|
132
|
+
(error as EngineApiError).code === "not_found"
|
|
133
|
+
) {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async getOrCreateWithKey(
|
|
141
|
+
input: GetOrCreateWithKeyInput,
|
|
142
|
+
): Promise<ActorOutput> {
|
|
143
|
+
const { c, name, key, input: actorInput, region } = input;
|
|
144
|
+
|
|
145
|
+
logger().info({
|
|
146
|
+
msg: "getOrCreateWithKey: getting or creating actor via engine api",
|
|
147
|
+
name,
|
|
148
|
+
key,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const response = await getOrCreateActorById(this.#config, {
|
|
152
|
+
name,
|
|
153
|
+
key: serializeActorKey(key),
|
|
154
|
+
runner_name_selector: this.#config.runnerName,
|
|
155
|
+
input: input ? cbor.encode(actorInput).toString("base64") : undefined,
|
|
156
|
+
crash_policy: "sleep",
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const actorId = response.actor_id;
|
|
160
|
+
|
|
161
|
+
logger().info({
|
|
162
|
+
msg: "getOrCreateWithKey: actor ready",
|
|
163
|
+
actorId,
|
|
164
|
+
name,
|
|
165
|
+
key,
|
|
166
|
+
created: response.created,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
actorId,
|
|
171
|
+
name,
|
|
172
|
+
key,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async createActor({
|
|
177
|
+
c,
|
|
178
|
+
name,
|
|
179
|
+
key,
|
|
180
|
+
input,
|
|
181
|
+
}: CreateInput): Promise<ActorOutput> {
|
|
182
|
+
logger().info({ msg: "creating actor via engine api", name, key });
|
|
183
|
+
|
|
184
|
+
// Create actor via engine API
|
|
185
|
+
const result = await createActor(this.#config, {
|
|
186
|
+
name,
|
|
187
|
+
runner_name_selector: this.#config.runnerName,
|
|
188
|
+
key: serializeActorKey(key),
|
|
189
|
+
input: input ? cbor.encode(input).toString("base64") : null,
|
|
190
|
+
crash_policy: "sleep",
|
|
191
|
+
});
|
|
192
|
+
const actorId = result.actor.actor_id;
|
|
193
|
+
|
|
194
|
+
logger().info({ msg: "actor created", actorId, name, key });
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
actorId,
|
|
198
|
+
name,
|
|
199
|
+
key,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async destroyActor(actorId: string): Promise<void> {
|
|
204
|
+
logger().info({ msg: "destroying actor via engine api", actorId });
|
|
205
|
+
|
|
206
|
+
await destroyActor(this.#config, actorId);
|
|
207
|
+
|
|
208
|
+
logger().info({ msg: "actor destroyed", actorId });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async sendRequest(actorId: string, actorRequest: Request): Promise<Response> {
|
|
212
|
+
return await sendHttpRequestToActor(this.#config, actorId, actorRequest);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async openWebSocket(
|
|
216
|
+
path: string,
|
|
217
|
+
actorId: string,
|
|
218
|
+
encoding: Encoding,
|
|
219
|
+
params: unknown,
|
|
220
|
+
): Promise<UniversalWebSocket> {
|
|
221
|
+
return await openWebSocketToActor(
|
|
222
|
+
this.#config,
|
|
223
|
+
path,
|
|
224
|
+
actorId,
|
|
225
|
+
encoding,
|
|
226
|
+
params,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async proxyRequest(
|
|
231
|
+
_c: HonoContext,
|
|
232
|
+
actorRequest: Request,
|
|
233
|
+
actorId: string,
|
|
234
|
+
): Promise<Response> {
|
|
235
|
+
return await sendHttpRequestToActor(this.#config, actorId, actorRequest);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async proxyWebSocket(
|
|
239
|
+
c: HonoContext,
|
|
240
|
+
path: string,
|
|
241
|
+
actorId: string,
|
|
242
|
+
encoding: Encoding,
|
|
243
|
+
params: unknown,
|
|
244
|
+
authData: unknown,
|
|
245
|
+
): Promise<Response> {
|
|
246
|
+
const upgradeWebSocket = this.#config.getUpgradeWebSocket?.();
|
|
247
|
+
invariant(upgradeWebSocket, "missing getUpgradeWebSocket");
|
|
248
|
+
|
|
249
|
+
const endpoint = getEndpoint(this.#config);
|
|
250
|
+
const guardUrl = combineUrlPath(endpoint, path);
|
|
251
|
+
const wsGuardUrl = guardUrl.replace("http://", "ws://");
|
|
252
|
+
|
|
253
|
+
logger().debug({
|
|
254
|
+
msg: "forwarding websocket to actor via guard",
|
|
255
|
+
actorId,
|
|
256
|
+
path,
|
|
257
|
+
guardUrl,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Build headers
|
|
261
|
+
const headers = buildGuardHeadersForWebSocket(
|
|
262
|
+
actorId,
|
|
263
|
+
encoding,
|
|
264
|
+
params,
|
|
265
|
+
authData,
|
|
266
|
+
);
|
|
267
|
+
const args = await createWebSocketProxy(c, wsGuardUrl, headers);
|
|
268
|
+
|
|
269
|
+
return await upgradeWebSocket(() => args)(c, noopNext());
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
displayInformation(): ManagerDisplayInformation {
|
|
273
|
+
return { name: "Remote", properties: {} };
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Context as HonoContext } from "hono";
|
|
2
2
|
import type { WSContext } from "hono/ws";
|
|
3
|
-
import
|
|
4
|
-
import type { CloseEvent } from "ws";
|
|
3
|
+
import { stringifyError } from "@/common/utils";
|
|
5
4
|
import { importWebSocket } from "@/common/websocket";
|
|
6
5
|
import type { UpgradeWebSocketArgs } from "@/mod";
|
|
7
6
|
import { logger } from "./log";
|
|
@@ -32,10 +31,11 @@ export async function createWebSocketProxy(
|
|
|
32
31
|
|
|
33
32
|
return {
|
|
34
33
|
onOpen: async (event: any, clientWs: WSContext) => {
|
|
35
|
-
logger().debug("client websocket connected",
|
|
34
|
+
logger().debug({ msg: "client websocket connected", targetUrl });
|
|
36
35
|
|
|
37
36
|
if (clientWs.readyState !== 1) {
|
|
38
|
-
logger().warn(
|
|
37
|
+
logger().warn({
|
|
38
|
+
msg: "client websocket not open on connection",
|
|
39
39
|
targetUrl,
|
|
40
40
|
readyState: clientWs.readyState,
|
|
41
41
|
});
|
|
@@ -49,10 +49,11 @@ export async function createWebSocketProxy(
|
|
|
49
49
|
// Setup connection promise
|
|
50
50
|
state.connectPromise = new Promise<void>((resolve, reject) => {
|
|
51
51
|
targetWs.addEventListener("open", () => {
|
|
52
|
-
logger().debug("target websocket connected",
|
|
52
|
+
logger().debug({ msg: "target websocket connected", targetUrl });
|
|
53
53
|
|
|
54
54
|
if (clientWs.readyState !== 1) {
|
|
55
|
-
logger().warn(
|
|
55
|
+
logger().warn({
|
|
56
|
+
msg: "client websocket closed before target connected",
|
|
56
57
|
targetUrl,
|
|
57
58
|
clientReadyState: clientWs.readyState,
|
|
58
59
|
});
|
|
@@ -64,7 +65,8 @@ export async function createWebSocketProxy(
|
|
|
64
65
|
});
|
|
65
66
|
|
|
66
67
|
targetWs.addEventListener("error", (error) => {
|
|
67
|
-
logger().warn(
|
|
68
|
+
logger().warn({
|
|
69
|
+
msg: "target websocket error during connection",
|
|
68
70
|
targetUrl,
|
|
69
71
|
});
|
|
70
72
|
reject(error);
|
|
@@ -86,7 +88,8 @@ export async function createWebSocketProxy(
|
|
|
86
88
|
});
|
|
87
89
|
|
|
88
90
|
state.targetWs.addEventListener("close", (event) => {
|
|
89
|
-
logger().debug(
|
|
91
|
+
logger().debug({
|
|
92
|
+
msg: "target websocket closed",
|
|
90
93
|
targetUrl,
|
|
91
94
|
code: event.code,
|
|
92
95
|
reason: event.reason,
|
|
@@ -95,14 +98,18 @@ export async function createWebSocketProxy(
|
|
|
95
98
|
});
|
|
96
99
|
|
|
97
100
|
state.targetWs.addEventListener("error", (error) => {
|
|
98
|
-
logger().error(
|
|
101
|
+
logger().error({
|
|
102
|
+
msg: "target websocket error",
|
|
103
|
+
targetUrl,
|
|
104
|
+
error: stringifyError(error),
|
|
105
|
+
});
|
|
99
106
|
closeWebSocketIfOpen(clientWs, 1011, "Target WebSocket error");
|
|
100
107
|
});
|
|
101
108
|
},
|
|
102
109
|
|
|
103
110
|
onMessage: async (event: any, clientWs: WSContext) => {
|
|
104
111
|
if (!state.targetWs || !state.connectPromise) {
|
|
105
|
-
logger().error("websocket state not initialized",
|
|
112
|
+
logger().error({ msg: "websocket state not initialized", targetUrl });
|
|
106
113
|
return;
|
|
107
114
|
}
|
|
108
115
|
|
|
@@ -111,13 +118,15 @@ export async function createWebSocketProxy(
|
|
|
111
118
|
if (state.targetWs.readyState === WebSocket.OPEN) {
|
|
112
119
|
state.targetWs.send(event.data);
|
|
113
120
|
} else {
|
|
114
|
-
logger().warn(
|
|
121
|
+
logger().warn({
|
|
122
|
+
msg: "target websocket not open",
|
|
115
123
|
targetUrl,
|
|
116
124
|
readyState: state.targetWs.readyState,
|
|
117
125
|
});
|
|
118
126
|
}
|
|
119
127
|
} catch (error) {
|
|
120
|
-
logger().error(
|
|
128
|
+
logger().error({
|
|
129
|
+
msg: "failed to connect to target websocket",
|
|
121
130
|
targetUrl,
|
|
122
131
|
error,
|
|
123
132
|
});
|
|
@@ -126,7 +135,8 @@ export async function createWebSocketProxy(
|
|
|
126
135
|
},
|
|
127
136
|
|
|
128
137
|
onClose: (event: any, clientWs: WSContext) => {
|
|
129
|
-
logger().debug(
|
|
138
|
+
logger().debug({
|
|
139
|
+
msg: "client websocket closed",
|
|
130
140
|
targetUrl,
|
|
131
141
|
code: event.code,
|
|
132
142
|
reason: event.reason,
|
|
@@ -144,7 +154,7 @@ export async function createWebSocketProxy(
|
|
|
144
154
|
},
|
|
145
155
|
|
|
146
156
|
onError: (event: any, clientWs: WSContext) => {
|
|
147
|
-
logger().error("client websocket error",
|
|
157
|
+
logger().error({ msg: "client websocket error", targetUrl, event });
|
|
148
158
|
|
|
149
159
|
if (state.targetWs) {
|
|
150
160
|
if (state.targetWs.readyState === WebSocket.OPEN) {
|
package/src/serde.ts
CHANGED
|
@@ -40,13 +40,16 @@ export function wsBinaryTypeForEncoding(
|
|
|
40
40
|
export function serializeWithEncoding<T>(
|
|
41
41
|
encoding: Encoding,
|
|
42
42
|
value: T,
|
|
43
|
-
versionedDataHandler: VersionedDataHandler<T
|
|
43
|
+
versionedDataHandler: VersionedDataHandler<T> | undefined,
|
|
44
44
|
): Uint8Array | string {
|
|
45
45
|
if (encoding === "json") {
|
|
46
46
|
return jsonStringifyCompat(value);
|
|
47
47
|
} else if (encoding === "cbor") {
|
|
48
48
|
return cbor.encode(value);
|
|
49
49
|
} else if (encoding === "bare") {
|
|
50
|
+
if (!versionedDataHandler) {
|
|
51
|
+
throw new Error("VersionedDataHandler is required for 'bare' encoding");
|
|
52
|
+
}
|
|
50
53
|
return versionedDataHandler.serializeWithEmbeddedVersion(value);
|
|
51
54
|
} else {
|
|
52
55
|
assertUnreachable(encoding);
|
|
@@ -56,7 +59,7 @@ export function serializeWithEncoding<T>(
|
|
|
56
59
|
export function deserializeWithEncoding<T>(
|
|
57
60
|
encoding: Encoding,
|
|
58
61
|
buffer: Uint8Array | string,
|
|
59
|
-
versionedDataHandler: VersionedDataHandler<T
|
|
62
|
+
versionedDataHandler: VersionedDataHandler<T> | undefined,
|
|
60
63
|
): T {
|
|
61
64
|
if (encoding === "json") {
|
|
62
65
|
if (typeof buffer === "string") {
|
|
@@ -77,6 +80,9 @@ export function deserializeWithEncoding<T>(
|
|
|
77
80
|
typeof buffer !== "string",
|
|
78
81
|
"buffer cannot be string for bare encoding",
|
|
79
82
|
);
|
|
83
|
+
if (!versionedDataHandler) {
|
|
84
|
+
throw new Error("VersionedDataHandler is required for 'bare' encoding");
|
|
85
|
+
}
|
|
80
86
|
return versionedDataHandler.deserializeWithEmbeddedVersion(buffer);
|
|
81
87
|
} else {
|
|
82
88
|
assertUnreachable(encoding);
|
package/src/test/log.ts
CHANGED
package/src/test/mod.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { type TestContext, vi } from "vitest";
|
|
|
5
5
|
import { type Client, createClient } from "@/client/mod";
|
|
6
6
|
import { chooseDefaultDriver } from "@/drivers/default";
|
|
7
7
|
import { createFileSystemOrMemoryDriver } from "@/drivers/file-system/mod";
|
|
8
|
-
import { createInlineClientDriver } from "@/inline-client-driver/mod";
|
|
9
8
|
import { getInspectorUrl } from "@/inspector/utils";
|
|
10
9
|
import { createManagerRouter } from "@/manager/router";
|
|
11
10
|
import type { Registry } from "@/registry/mod";
|
|
@@ -28,11 +27,9 @@ function serve(registry: Registry<any>, inputConfig?: InputConfig): ServerType {
|
|
|
28
27
|
const runConfig = RunConfigSchema.parse(inputConfig);
|
|
29
28
|
const driver = inputConfig.driver ?? createFileSystemOrMemoryDriver(false);
|
|
30
29
|
const managerDriver = driver.manager(registry.config, config);
|
|
31
|
-
const inlineClientDriver = createInlineClientDriver(managerDriver);
|
|
32
30
|
const { router } = createManagerRouter(
|
|
33
31
|
registry.config,
|
|
34
32
|
runConfig,
|
|
35
|
-
inlineClientDriver,
|
|
36
33
|
managerDriver,
|
|
37
34
|
false,
|
|
38
35
|
);
|
|
@@ -48,7 +45,8 @@ function serve(registry: Registry<any>, inputConfig?: InputConfig): ServerType {
|
|
|
48
45
|
});
|
|
49
46
|
nodeWebSocket.injectWebSocket(server);
|
|
50
47
|
|
|
51
|
-
logger().info(
|
|
48
|
+
logger().info({
|
|
49
|
+
msg: "rivetkit started",
|
|
52
50
|
hostname: config.hostname,
|
|
53
51
|
port: config.port,
|
|
54
52
|
definitions: Object.keys(registry.config.use).length,
|
|
@@ -88,18 +86,21 @@ export async function setupTest<A extends Registry<any>>(
|
|
|
88
86
|
async () => await new Promise((resolve) => server.close(() => resolve())),
|
|
89
87
|
);
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
89
|
+
throw "TODO: Fix engine port";
|
|
90
|
+
|
|
91
|
+
// // TODO: Figure out how to make this the correct endpoint
|
|
92
|
+
// // Create client
|
|
93
|
+
// const client = createClient<A>(`http://127.0.0.1:${port}`);
|
|
94
|
+
// c.onTestFinished(async () => await client.dispose());
|
|
95
|
+
//
|
|
96
|
+
// return {
|
|
97
|
+
// client,
|
|
98
|
+
// mockDriver: {
|
|
99
|
+
// actorDriver: {
|
|
100
|
+
// setCreateVarsContext: setDriverContextFn,
|
|
101
|
+
// },
|
|
102
|
+
// },
|
|
103
|
+
// };
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
export async function getPort(): Promise<number> {
|
package/src/utils.ts
CHANGED
|
@@ -170,3 +170,56 @@ export function bufferToArrayBuffer(buf: Buffer | Uint8Array): ArrayBuffer {
|
|
|
170
170
|
buf.byteOffset + buf.byteLength,
|
|
171
171
|
) as ArrayBuffer;
|
|
172
172
|
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Properly combines a base URL endpoint with a path, preserving any base path in the endpoint.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* combineUrlPath("http://localhost:8787/rivet", "/actors/action")
|
|
179
|
+
* // Returns: "http://localhost:8787/rivet/actors/action"
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* combineUrlPath("http://localhost:8787/rivet", "/actors?type=foo", { namespace: "test" })
|
|
183
|
+
* // Returns: "http://localhost:8787/rivet/actors?type=foo&namespace=test"
|
|
184
|
+
*
|
|
185
|
+
* @param endpoint The base URL endpoint that may contain a path component
|
|
186
|
+
* @param path The path to append to the endpoint (may include query parameters)
|
|
187
|
+
* @param queryParams Optional additional query parameters to append
|
|
188
|
+
* @returns The properly combined URL string
|
|
189
|
+
*/
|
|
190
|
+
export function combineUrlPath(
|
|
191
|
+
endpoint: string,
|
|
192
|
+
path: string,
|
|
193
|
+
queryParams?: Record<string, string | undefined>,
|
|
194
|
+
): string {
|
|
195
|
+
const baseUrl = new URL(endpoint);
|
|
196
|
+
|
|
197
|
+
// Extract path and query from the provided path
|
|
198
|
+
const pathParts = path.split("?");
|
|
199
|
+
const pathOnly = pathParts[0];
|
|
200
|
+
const existingQuery = pathParts[1] || "";
|
|
201
|
+
|
|
202
|
+
// Remove trailing slash from base path and ensure path starts with /
|
|
203
|
+
const basePath = baseUrl.pathname.replace(/\/$/, "");
|
|
204
|
+
const cleanPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
|
|
205
|
+
// Combine paths and remove any double slashes
|
|
206
|
+
const fullPath = (basePath + cleanPath).replace(/\/\//g, "/");
|
|
207
|
+
|
|
208
|
+
// Build query string
|
|
209
|
+
const queryParts: string[] = [];
|
|
210
|
+
if (existingQuery) {
|
|
211
|
+
queryParts.push(existingQuery);
|
|
212
|
+
}
|
|
213
|
+
if (queryParams) {
|
|
214
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
215
|
+
if (value !== undefined) {
|
|
216
|
+
queryParts.push(
|
|
217
|
+
`${encodeURIComponent(key)}=${encodeURIComponent(value)}`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const fullQuery = queryParts.length > 0 ? `?${queryParts.join("&")}` : "";
|
|
224
|
+
return `${baseUrl.protocol}//${baseUrl.host}${fullPath}${fullQuery}`;
|
|
225
|
+
}
|