rivetkit 2.0.2 → 2.0.4
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 +3 -5
- package/dist/schemas/actor-persist/v1.ts +225 -0
- package/dist/schemas/client-protocol/v1.ts +435 -0
- package/dist/schemas/file-system-driver/v1.ts +102 -0
- package/dist/tsup/actor/errors.cjs +77 -0
- package/dist/tsup/actor/errors.cjs.map +1 -0
- package/dist/tsup/actor/errors.d.cts +156 -0
- package/dist/tsup/actor/errors.d.ts +156 -0
- package/dist/tsup/actor/errors.js +77 -0
- package/dist/tsup/actor/errors.js.map +1 -0
- package/dist/tsup/chunk-3F2YSRJL.js +117 -0
- package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
- package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
- package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
- package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
- package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
- package/dist/tsup/chunk-6LJT3QRL.cjs +539 -0
- package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
- package/dist/tsup/chunk-GICQ3YCU.cjs +1792 -0
- package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
- package/dist/tsup/chunk-H26RP6GD.js +251 -0
- package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
- package/dist/tsup/chunk-HI3HWJRC.js +20 -0
- package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
- package/dist/tsup/chunk-HLLF4B4Q.js +1792 -0
- package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
- package/dist/tsup/chunk-IH6CKNDW.cjs +117 -0
- package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
- package/dist/tsup/chunk-LV2S3OU3.js +250 -0
- package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
- package/dist/tsup/chunk-LWNKVZG5.cjs +251 -0
- package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
- package/dist/tsup/chunk-NFU2BBT5.js +374 -0
- package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
- package/dist/tsup/chunk-PQY7KKTL.js +539 -0
- package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
- package/dist/tsup/chunk-QK72M5JB.js +45 -0
- package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
- package/dist/tsup/chunk-QNNXFOQV.cjs +45 -0
- package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
- package/dist/tsup/chunk-SBHHJ6QS.cjs +374 -0
- package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
- package/dist/tsup/chunk-TQ62L3X7.js +325 -0
- package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
- package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
- package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
- package/dist/tsup/client/mod.cjs +32 -0
- package/dist/tsup/client/mod.cjs.map +1 -0
- package/dist/tsup/client/mod.d.cts +20 -0
- package/dist/tsup/client/mod.d.ts +20 -0
- package/dist/tsup/client/mod.js +32 -0
- package/dist/tsup/client/mod.js.map +1 -0
- package/dist/tsup/common/log.cjs +21 -0
- package/dist/tsup/common/log.cjs.map +1 -0
- package/dist/tsup/common/log.d.cts +26 -0
- package/dist/tsup/common/log.d.ts +26 -0
- package/dist/tsup/common/log.js +21 -0
- package/dist/tsup/common/log.js.map +1 -0
- package/dist/tsup/common/websocket.cjs +10 -0
- package/dist/tsup/common/websocket.cjs.map +1 -0
- package/dist/tsup/common/websocket.d.cts +3 -0
- package/dist/tsup/common/websocket.d.ts +3 -0
- package/dist/tsup/common/websocket.js +10 -0
- package/dist/tsup/common/websocket.js.map +1 -0
- package/dist/tsup/common-CXCe7s6i.d.cts +218 -0
- package/dist/tsup/common-CXCe7s6i.d.ts +218 -0
- package/dist/tsup/connection-BI-6UIBJ.d.ts +2087 -0
- package/dist/tsup/connection-Dyd4NLGW.d.cts +2087 -0
- package/dist/tsup/driver-helpers/mod.cjs +30 -0
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -0
- package/dist/tsup/driver-helpers/mod.d.cts +17 -0
- package/dist/tsup/driver-helpers/mod.d.ts +17 -0
- package/dist/tsup/driver-helpers/mod.js +30 -0
- package/dist/tsup/driver-helpers/mod.js.map +1 -0
- package/dist/tsup/driver-test-suite/mod.cjs +3411 -0
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -0
- package/dist/tsup/driver-test-suite/mod.d.cts +63 -0
- package/dist/tsup/driver-test-suite/mod.d.ts +63 -0
- package/dist/tsup/driver-test-suite/mod.js +3411 -0
- package/dist/tsup/driver-test-suite/mod.js.map +1 -0
- package/dist/tsup/inspector/mod.cjs +51 -0
- package/dist/tsup/inspector/mod.cjs.map +1 -0
- package/dist/tsup/inspector/mod.d.cts +408 -0
- package/dist/tsup/inspector/mod.d.ts +408 -0
- package/dist/tsup/inspector/mod.js +51 -0
- package/dist/tsup/inspector/mod.js.map +1 -0
- package/dist/tsup/mod.cjs +67 -0
- package/dist/tsup/mod.cjs.map +1 -0
- package/dist/tsup/mod.d.cts +105 -0
- package/dist/tsup/mod.d.ts +105 -0
- package/dist/tsup/mod.js +67 -0
- package/dist/tsup/mod.js.map +1 -0
- package/dist/tsup/router-endpoints-BTe_Rsdn.d.cts +65 -0
- package/dist/tsup/router-endpoints-CBSrKHmo.d.ts +65 -0
- package/dist/tsup/test/mod.cjs +17 -0
- package/dist/tsup/test/mod.cjs.map +1 -0
- package/dist/tsup/test/mod.d.cts +26 -0
- package/dist/tsup/test/mod.d.ts +26 -0
- package/dist/tsup/test/mod.js +17 -0
- package/dist/tsup/test/mod.js.map +1 -0
- package/dist/tsup/utils-fwx3o3K9.d.cts +18 -0
- package/dist/tsup/utils-fwx3o3K9.d.ts +18 -0
- package/dist/tsup/utils.cjs +26 -0
- package/dist/tsup/utils.cjs.map +1 -0
- package/dist/tsup/utils.d.cts +36 -0
- package/dist/tsup/utils.d.ts +36 -0
- package/dist/tsup/utils.js +26 -0
- package/dist/tsup/utils.js.map +1 -0
- package/package.json +208 -5
- package/src/actor/action.ts +178 -0
- package/src/actor/config.ts +497 -0
- package/src/actor/connection.ts +257 -0
- package/src/actor/context.ts +168 -0
- package/src/actor/database.ts +23 -0
- package/src/actor/definition.ts +82 -0
- package/src/actor/driver.ts +84 -0
- package/src/actor/errors.ts +422 -0
- package/src/actor/generic-conn-driver.ts +246 -0
- package/src/actor/instance.ts +1844 -0
- package/src/actor/keys.test.ts +266 -0
- package/src/actor/keys.ts +89 -0
- package/src/actor/log.ts +6 -0
- package/src/actor/mod.ts +108 -0
- package/src/actor/persisted.ts +42 -0
- package/src/actor/protocol/old.ts +297 -0
- package/src/actor/protocol/serde.ts +131 -0
- package/src/actor/router-endpoints.ts +688 -0
- package/src/actor/router.ts +265 -0
- package/src/actor/schedule.ts +17 -0
- package/src/actor/unstable-react.ts +110 -0
- package/src/actor/utils.ts +102 -0
- package/src/client/actor-common.ts +30 -0
- package/src/client/actor-conn.ts +865 -0
- package/src/client/actor-handle.ts +268 -0
- package/src/client/actor-query.ts +65 -0
- package/src/client/client.ts +554 -0
- package/src/client/config.ts +44 -0
- package/src/client/errors.ts +42 -0
- package/src/client/log.ts +5 -0
- package/src/client/mod.ts +60 -0
- package/src/client/raw-utils.ts +149 -0
- package/src/client/test.ts +44 -0
- package/src/client/utils.ts +152 -0
- package/src/common/eventsource-interface.ts +47 -0
- package/src/common/eventsource.ts +80 -0
- package/src/common/fake-event-source.ts +267 -0
- package/src/common/inline-websocket-adapter2.ts +454 -0
- package/src/common/log-levels.ts +27 -0
- package/src/common/log.ts +214 -0
- package/src/common/logfmt.ts +219 -0
- package/src/common/network.ts +2 -0
- package/src/common/router.ts +80 -0
- package/src/common/utils.ts +336 -0
- package/src/common/versioned-data.ts +95 -0
- package/src/common/websocket-interface.ts +49 -0
- package/src/common/websocket.ts +42 -0
- package/src/driver-helpers/mod.ts +22 -0
- package/src/driver-helpers/utils.ts +17 -0
- package/src/driver-test-suite/log.ts +5 -0
- package/src/driver-test-suite/mod.ts +239 -0
- package/src/driver-test-suite/tests/action-features.ts +136 -0
- package/src/driver-test-suite/tests/actor-conn-state.ts +249 -0
- package/src/driver-test-suite/tests/actor-conn.ts +349 -0
- package/src/driver-test-suite/tests/actor-driver.ts +25 -0
- package/src/driver-test-suite/tests/actor-error-handling.ts +158 -0
- package/src/driver-test-suite/tests/actor-handle.ts +292 -0
- package/src/driver-test-suite/tests/actor-inline-client.ts +152 -0
- package/src/driver-test-suite/tests/actor-inspector.ts +570 -0
- package/src/driver-test-suite/tests/actor-metadata.ts +116 -0
- package/src/driver-test-suite/tests/actor-onstatechange.ts +95 -0
- package/src/driver-test-suite/tests/actor-schedule.ts +108 -0
- package/src/driver-test-suite/tests/actor-sleep.ts +413 -0
- package/src/driver-test-suite/tests/actor-state.ts +54 -0
- package/src/driver-test-suite/tests/actor-vars.ts +93 -0
- package/src/driver-test-suite/tests/manager-driver.ts +367 -0
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -0
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +414 -0
- package/src/driver-test-suite/tests/raw-http.ts +347 -0
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -0
- package/src/driver-test-suite/tests/raw-websocket.ts +484 -0
- package/src/driver-test-suite/tests/request-access.ts +230 -0
- package/src/driver-test-suite/utils.ts +71 -0
- package/src/drivers/default.ts +34 -0
- package/src/drivers/engine/actor-driver.ts +369 -0
- package/src/drivers/engine/config.ts +31 -0
- package/src/drivers/engine/kv.ts +3 -0
- package/src/drivers/engine/log.ts +5 -0
- package/src/drivers/engine/mod.ts +35 -0
- package/src/drivers/file-system/actor.ts +91 -0
- package/src/drivers/file-system/global-state.ts +686 -0
- package/src/drivers/file-system/log.ts +5 -0
- package/src/drivers/file-system/manager.ts +329 -0
- package/src/drivers/file-system/mod.ts +48 -0
- package/src/drivers/file-system/utils.ts +109 -0
- package/src/globals.d.ts +6 -0
- package/src/inspector/actor.ts +298 -0
- package/src/inspector/config.ts +88 -0
- package/src/inspector/log.ts +5 -0
- package/src/inspector/manager.ts +86 -0
- package/src/inspector/mod.ts +2 -0
- package/src/inspector/protocol/actor.ts +10 -0
- package/src/inspector/protocol/common.ts +196 -0
- package/src/inspector/protocol/manager.ts +10 -0
- package/src/inspector/protocol/mod.ts +2 -0
- package/src/inspector/utils.ts +76 -0
- package/src/manager/driver.ts +88 -0
- package/src/manager/hono-websocket-adapter.ts +342 -0
- package/src/manager/log.ts +5 -0
- package/src/manager/mod.ts +2 -0
- package/src/manager/protocol/mod.ts +24 -0
- package/src/manager/protocol/query.ts +89 -0
- package/src/manager/router.ts +412 -0
- 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 +18 -0
- package/src/registry/config.ts +32 -0
- package/src/registry/log.ts +5 -0
- package/src/registry/mod.ts +157 -0
- package/src/registry/run-config.ts +52 -0
- package/src/registry/serve.ts +52 -0
- package/src/remote-manager-driver/actor-http-client.ts +72 -0
- package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
- package/src/remote-manager-driver/api-endpoints.ts +79 -0
- package/src/remote-manager-driver/api-utils.ts +43 -0
- package/src/remote-manager-driver/log.ts +5 -0
- package/src/remote-manager-driver/mod.ts +274 -0
- package/src/remote-manager-driver/ws-proxy.ts +180 -0
- package/src/schemas/actor-persist/mod.ts +1 -0
- package/src/schemas/actor-persist/versioned.ts +25 -0
- package/src/schemas/client-protocol/mod.ts +1 -0
- package/src/schemas/client-protocol/versioned.ts +63 -0
- package/src/schemas/file-system-driver/mod.ts +1 -0
- package/src/schemas/file-system-driver/versioned.ts +28 -0
- package/src/serde.ts +90 -0
- package/src/test/config.ts +16 -0
- package/src/test/log.ts +5 -0
- package/src/test/mod.ts +154 -0
- package/src/utils.ts +172 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import type { Hono } from "hono";
|
|
2
|
+
import { type Client, createClientWithDriver } from "@/client/client";
|
|
3
|
+
import { configureBaseLogger, configureDefaultLogger } from "@/common/log";
|
|
4
|
+
import { chooseDefaultDriver } from "@/drivers/default";
|
|
5
|
+
import { getInspectorUrl } from "@/inspector/utils";
|
|
6
|
+
import { createManagerRouter } from "@/manager/router";
|
|
7
|
+
import pkg from "../../package.json" with { type: "json" };
|
|
8
|
+
import {
|
|
9
|
+
type RegistryActors,
|
|
10
|
+
type RegistryConfig,
|
|
11
|
+
type RegistryConfigInput,
|
|
12
|
+
RegistryConfigSchema,
|
|
13
|
+
} from "./config";
|
|
14
|
+
import { logger } from "./log";
|
|
15
|
+
import {
|
|
16
|
+
type DriverConfig,
|
|
17
|
+
type RunConfig,
|
|
18
|
+
type RunConfigInput,
|
|
19
|
+
RunConfigSchema,
|
|
20
|
+
} from "./run-config";
|
|
21
|
+
import { crossPlatformServe } from "./serve";
|
|
22
|
+
|
|
23
|
+
interface ServerOutput<A extends Registry<any>> {
|
|
24
|
+
config: RunConfig;
|
|
25
|
+
driver: DriverConfig;
|
|
26
|
+
client: Client<A>;
|
|
27
|
+
hono: Hono;
|
|
28
|
+
handler: (req: Request) => Promise<Response>;
|
|
29
|
+
serve: (hono?: Hono) => void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class Registry<A extends RegistryActors> {
|
|
33
|
+
#config: RegistryConfig;
|
|
34
|
+
|
|
35
|
+
public get config(): RegistryConfig {
|
|
36
|
+
return this.#config;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
constructor(config: RegistryConfig) {
|
|
40
|
+
this.#config = config;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Runs the registry for a server.
|
|
45
|
+
*/
|
|
46
|
+
public createServer(inputConfig?: RunConfigInput): ServerOutput<this> {
|
|
47
|
+
const config = RunConfigSchema.parse(inputConfig);
|
|
48
|
+
|
|
49
|
+
// Configure logger
|
|
50
|
+
if (config.logging?.baseLogger) {
|
|
51
|
+
// Use provided base logger
|
|
52
|
+
configureBaseLogger(config.logging.baseLogger);
|
|
53
|
+
} else {
|
|
54
|
+
// Configure default logger with log level from config
|
|
55
|
+
// getPinoLevel will handle env variable priority
|
|
56
|
+
configureDefaultLogger(config.logging?.level);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Choose the driver based on configuration
|
|
60
|
+
const driver = chooseDefaultDriver(config);
|
|
61
|
+
|
|
62
|
+
// TODO: Find cleaner way of disabling by default
|
|
63
|
+
if (driver.name === "engine") {
|
|
64
|
+
config.inspector.enabled = false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Configure getUpgradeWebSocket lazily so we can assign it in crossPlatformServe
|
|
68
|
+
let upgradeWebSocket: any;
|
|
69
|
+
if (!config.getUpgradeWebSocket) {
|
|
70
|
+
config.getUpgradeWebSocket = () => upgradeWebSocket!;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Create router
|
|
74
|
+
const managerDriver = driver.manager(this.#config, config);
|
|
75
|
+
const { router: hono } = createManagerRouter(
|
|
76
|
+
this.#config,
|
|
77
|
+
config,
|
|
78
|
+
managerDriver,
|
|
79
|
+
false,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// Create client
|
|
83
|
+
const client = createClientWithDriver<this>(managerDriver, config);
|
|
84
|
+
|
|
85
|
+
const driverLog = managerDriver.extraStartupLog?.() ?? {};
|
|
86
|
+
logger().info({
|
|
87
|
+
msg: "rivetkit ready",
|
|
88
|
+
driver: driver.name,
|
|
89
|
+
definitions: Object.keys(this.#config.use).length,
|
|
90
|
+
...driverLog,
|
|
91
|
+
});
|
|
92
|
+
if (config.inspector?.enabled && managerDriver.inspector) {
|
|
93
|
+
logger().info({ msg: "inspector ready", url: getInspectorUrl(config) });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Print welcome information
|
|
97
|
+
if (!config.noWelcome) {
|
|
98
|
+
const displayInfo = managerDriver.displayInformation();
|
|
99
|
+
console.log();
|
|
100
|
+
console.log(` RivetKit ${pkg.version} (${displayInfo.name})`);
|
|
101
|
+
console.log(` - Endpoint: http://127.0.0.1:6420`);
|
|
102
|
+
for (const [k, v] of Object.entries(displayInfo.properties)) {
|
|
103
|
+
const padding = " ".repeat(Math.max(0, 13 - k.length));
|
|
104
|
+
console.log(` - ${k}:${padding}${v}`);
|
|
105
|
+
}
|
|
106
|
+
if (config.inspector?.enabled && managerDriver.inspector) {
|
|
107
|
+
console.log(` - Inspector: ${getInspectorUrl(config)}`);
|
|
108
|
+
}
|
|
109
|
+
console.log();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Create runner
|
|
113
|
+
//
|
|
114
|
+
// Even though we do not use the return value, this is required to start the code that will handle incoming actors
|
|
115
|
+
const _actorDriver = driver.actor(
|
|
116
|
+
this.#config,
|
|
117
|
+
config,
|
|
118
|
+
managerDriver,
|
|
119
|
+
client,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
config,
|
|
124
|
+
driver,
|
|
125
|
+
client,
|
|
126
|
+
hono,
|
|
127
|
+
handler: async (req: Request) => await hono.fetch(req),
|
|
128
|
+
serve: async (app) => {
|
|
129
|
+
const out = await crossPlatformServe(hono, app);
|
|
130
|
+
upgradeWebSocket = out.upgradeWebSocket;
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Runs the registry as a standalone server.
|
|
137
|
+
*/
|
|
138
|
+
public async runServer(inputConfig?: RunConfigInput) {
|
|
139
|
+
const { driver, serve } = this.createServer(inputConfig);
|
|
140
|
+
|
|
141
|
+
// TODO: FInd better way of doing this
|
|
142
|
+
// Don't run server by default
|
|
143
|
+
if (driver.name !== "engine") {
|
|
144
|
+
serve();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function setup<A extends RegistryActors>(
|
|
150
|
+
input: RegistryConfigInput<A>,
|
|
151
|
+
): Registry<A> {
|
|
152
|
+
const config = RegistryConfigSchema.parse(input);
|
|
153
|
+
return new Registry(config);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export type { RegistryConfig, RegistryActors, RunConfig, DriverConfig };
|
|
157
|
+
export { RegistryConfigSchema };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { cors } from "hono/cors";
|
|
2
|
+
import type { Logger } from "pino";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import type { ActorDriverBuilder } from "@/actor/driver";
|
|
5
|
+
import { ClientConfigSchema } from "@/client/config";
|
|
6
|
+
import { LogLevelSchema } from "@/common/log";
|
|
7
|
+
import { InspectorConfigSchema } from "@/inspector/config";
|
|
8
|
+
import type { ManagerDriverBuilder } from "@/manager/driver";
|
|
9
|
+
|
|
10
|
+
type CorsOptions = NonNullable<Parameters<typeof cors>[0]>;
|
|
11
|
+
|
|
12
|
+
export const DriverConfigSchema = z.object({
|
|
13
|
+
/** Machine-readable name to identify this driver by. */
|
|
14
|
+
name: z.string(),
|
|
15
|
+
manager: z.custom<ManagerDriverBuilder>(),
|
|
16
|
+
actor: z.custom<ActorDriverBuilder>(),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export type DriverConfig = z.infer<typeof DriverConfigSchema>;
|
|
20
|
+
|
|
21
|
+
/** Base config used for the actor config across all platforms. */
|
|
22
|
+
export const RunConfigSchema = ClientConfigSchema.extend({
|
|
23
|
+
driver: DriverConfigSchema.optional(),
|
|
24
|
+
|
|
25
|
+
/** CORS configuration for the router. Uses Hono's CORS middleware options. */
|
|
26
|
+
cors: z.custom<CorsOptions>().optional(),
|
|
27
|
+
|
|
28
|
+
maxIncomingMessageSize: z.number().optional().default(65_536),
|
|
29
|
+
|
|
30
|
+
inspector: InspectorConfigSchema,
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Base path for the router. This is used to prefix all routes.
|
|
34
|
+
* For example, if the base path is `/api`, then the route `/actors` will be
|
|
35
|
+
* available at `/api/actors`.
|
|
36
|
+
*/
|
|
37
|
+
basePath: z.string().optional().default("/"),
|
|
38
|
+
|
|
39
|
+
/** Disable welcome message. */
|
|
40
|
+
noWelcome: z.boolean().optional().default(false),
|
|
41
|
+
|
|
42
|
+
logging: z
|
|
43
|
+
.object({
|
|
44
|
+
baseLogger: z.custom<Logger>().optional(),
|
|
45
|
+
level: LogLevelSchema.optional(),
|
|
46
|
+
})
|
|
47
|
+
.optional()
|
|
48
|
+
.default({}),
|
|
49
|
+
}).default({});
|
|
50
|
+
|
|
51
|
+
export type RunConfig = z.infer<typeof RunConfigSchema>;
|
|
52
|
+
export type RunConfigInput = z.input<typeof RunConfigSchema>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { getEnvUniversal } from "@/utils";
|
|
3
|
+
import { logger } from "./log";
|
|
4
|
+
|
|
5
|
+
export async function crossPlatformServe(
|
|
6
|
+
rivetKitRouter: Hono<any>,
|
|
7
|
+
userRouter: Hono | undefined,
|
|
8
|
+
) {
|
|
9
|
+
const app = userRouter ?? new Hono();
|
|
10
|
+
|
|
11
|
+
// Import @hono/node-server
|
|
12
|
+
let serve: any;
|
|
13
|
+
try {
|
|
14
|
+
const dep = await import("@hono/node-server");
|
|
15
|
+
serve = dep.serve;
|
|
16
|
+
} catch (err) {
|
|
17
|
+
logger().error(
|
|
18
|
+
"failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'",
|
|
19
|
+
);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Mount registry
|
|
24
|
+
// app.route("/registry", rivetKitRouter);
|
|
25
|
+
app.route("/", rivetKitRouter);
|
|
26
|
+
|
|
27
|
+
// Import @hono/node-ws
|
|
28
|
+
let createNodeWebSocket: any;
|
|
29
|
+
try {
|
|
30
|
+
const dep = await import("@hono/node-ws");
|
|
31
|
+
createNodeWebSocket = dep.createNodeWebSocket;
|
|
32
|
+
} catch (err) {
|
|
33
|
+
logger().error(
|
|
34
|
+
"failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'",
|
|
35
|
+
);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Inject WS
|
|
40
|
+
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
|
|
41
|
+
app,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Start server
|
|
45
|
+
const port = 6420;
|
|
46
|
+
const server = serve({ fetch: app.fetch, port }, () =>
|
|
47
|
+
logger().info({ msg: "server listening", port }),
|
|
48
|
+
);
|
|
49
|
+
injectWebSocket(server);
|
|
50
|
+
|
|
51
|
+
return { upgradeWebSocket };
|
|
52
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ClientConfig } from "@/client/config";
|
|
2
|
+
import { getEndpoint } from "./api-utils";
|
|
3
|
+
|
|
4
|
+
export async function sendHttpRequestToActor(
|
|
5
|
+
runConfig: ClientConfig,
|
|
6
|
+
actorId: string,
|
|
7
|
+
actorRequest: Request,
|
|
8
|
+
): Promise<Response> {
|
|
9
|
+
// Route through guard port
|
|
10
|
+
const url = new URL(actorRequest.url);
|
|
11
|
+
const endpoint = getEndpoint(runConfig);
|
|
12
|
+
const guardUrl = `${endpoint}${url.pathname}${url.search}`;
|
|
13
|
+
|
|
14
|
+
// Handle body properly based on method and presence
|
|
15
|
+
let bodyToSend: ArrayBuffer | null = null;
|
|
16
|
+
const guardHeaders = buildGuardHeadersForHttp(actorRequest, actorId);
|
|
17
|
+
|
|
18
|
+
if (
|
|
19
|
+
actorRequest.body &&
|
|
20
|
+
actorRequest.method !== "GET" &&
|
|
21
|
+
actorRequest.method !== "HEAD"
|
|
22
|
+
) {
|
|
23
|
+
if (actorRequest.bodyUsed) {
|
|
24
|
+
throw new Error("Request body has already been consumed");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// TODO: This buffers the entire request in memory every time. We
|
|
28
|
+
// need to properly implement streaming bodies.
|
|
29
|
+
// Clone and read the body to ensure it can be sent
|
|
30
|
+
const clonedRequest = actorRequest.clone();
|
|
31
|
+
bodyToSend = await clonedRequest.arrayBuffer();
|
|
32
|
+
|
|
33
|
+
// If this is a streaming request, we need to convert the headers
|
|
34
|
+
// for the basic array buffer
|
|
35
|
+
guardHeaders.delete("transfer-encoding");
|
|
36
|
+
guardHeaders.set(
|
|
37
|
+
"content-length",
|
|
38
|
+
String((bodyToSend as ArrayBuffer).byteLength),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const guardRequest = new Request(guardUrl, {
|
|
43
|
+
method: actorRequest.method,
|
|
44
|
+
headers: guardHeaders,
|
|
45
|
+
body: bodyToSend,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return mutableResponse(await fetch(guardRequest));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function mutableResponse(fetchRes: Response): Response {
|
|
52
|
+
// We cannot return the raw response from `fetch` since the response type is not mutable.
|
|
53
|
+
//
|
|
54
|
+
// In order for middleware to be able to mutate the response, we need to build a new Response object that is mutable.
|
|
55
|
+
return new Response(fetchRes.body, fetchRes);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function buildGuardHeadersForHttp(
|
|
59
|
+
actorRequest: Request,
|
|
60
|
+
actorId: string,
|
|
61
|
+
): Headers {
|
|
62
|
+
const headers = new Headers();
|
|
63
|
+
// Copy all headers from the original request
|
|
64
|
+
for (const [key, value] of actorRequest.headers.entries()) {
|
|
65
|
+
headers.set(key, value);
|
|
66
|
+
}
|
|
67
|
+
// Add guard-specific headers
|
|
68
|
+
headers.set("x-rivet-target", "actor");
|
|
69
|
+
headers.set("x-rivet-actor", actorId);
|
|
70
|
+
headers.set("x-rivet-port", "main");
|
|
71
|
+
return headers;
|
|
72
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HEADER_AUTH_DATA,
|
|
3
|
+
HEADER_CONN_PARAMS,
|
|
4
|
+
HEADER_ENCODING,
|
|
5
|
+
} from "@/actor/router-endpoints";
|
|
6
|
+
import type { ClientConfig } from "@/client/config";
|
|
7
|
+
import { importWebSocket } from "@/common/websocket";
|
|
8
|
+
import type { Encoding, UniversalWebSocket } from "@/mod";
|
|
9
|
+
import { getEndpoint } from "./api-utils";
|
|
10
|
+
import { logger } from "./log";
|
|
11
|
+
|
|
12
|
+
export async function openWebSocketToActor(
|
|
13
|
+
runConfig: ClientConfig,
|
|
14
|
+
path: string,
|
|
15
|
+
actorId: string,
|
|
16
|
+
encoding: Encoding,
|
|
17
|
+
params: unknown,
|
|
18
|
+
): Promise<UniversalWebSocket> {
|
|
19
|
+
const WebSocket = await importWebSocket();
|
|
20
|
+
|
|
21
|
+
// WebSocket connections go through guard
|
|
22
|
+
const endpoint = getEndpoint(runConfig);
|
|
23
|
+
const guardUrl = `${endpoint}${path}`;
|
|
24
|
+
|
|
25
|
+
logger().debug({
|
|
26
|
+
msg: "opening websocket to actor via guard",
|
|
27
|
+
actorId,
|
|
28
|
+
path,
|
|
29
|
+
guardUrl,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Create WebSocket connection
|
|
33
|
+
const ws = new WebSocket(guardUrl, {
|
|
34
|
+
headers: buildGuardHeadersForWebSocket(actorId, encoding, params),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Set binary type to arraybuffer for proper encoding support
|
|
38
|
+
ws.binaryType = "arraybuffer";
|
|
39
|
+
|
|
40
|
+
logger().debug({ msg: "websocket connection opened", actorId });
|
|
41
|
+
|
|
42
|
+
return ws as UniversalWebSocket;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function buildGuardHeadersForWebSocket(
|
|
46
|
+
actorId: string,
|
|
47
|
+
encoding: Encoding,
|
|
48
|
+
params?: unknown,
|
|
49
|
+
authData?: unknown,
|
|
50
|
+
): Record<string, string> {
|
|
51
|
+
const headers: Record<string, string> = {};
|
|
52
|
+
headers["x-rivet-target"] = "actor";
|
|
53
|
+
headers["x-rivet-actor"] = actorId;
|
|
54
|
+
headers["x-rivet-port"] = "main";
|
|
55
|
+
headers[HEADER_ENCODING] = encoding;
|
|
56
|
+
if (params) {
|
|
57
|
+
headers[HEADER_CONN_PARAMS] = JSON.stringify(params);
|
|
58
|
+
}
|
|
59
|
+
if (authData) {
|
|
60
|
+
headers[HEADER_AUTH_DATA] = JSON.stringify(authData);
|
|
61
|
+
}
|
|
62
|
+
return headers;
|
|
63
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { serializeActorKey } from "@/actor/keys";
|
|
2
|
+
import type { ClientConfig } from "@/client/client";
|
|
3
|
+
import type {
|
|
4
|
+
ActorsCreateRequest,
|
|
5
|
+
ActorsCreateResponse,
|
|
6
|
+
} from "@/manager-api/routes/actors-create";
|
|
7
|
+
import type { ActorsDeleteResponse } from "@/manager-api/routes/actors-delete";
|
|
8
|
+
import type { ActorsGetResponse } from "@/manager-api/routes/actors-get";
|
|
9
|
+
import type { ActorsGetByIdResponse } from "@/manager-api/routes/actors-get-by-id";
|
|
10
|
+
import type {
|
|
11
|
+
ActorsGetOrCreateByIdRequest,
|
|
12
|
+
ActorsGetOrCreateByIdResponse,
|
|
13
|
+
} from "@/manager-api/routes/actors-get-or-create-by-id";
|
|
14
|
+
import type { RivetId } from "@/manager-api/routes/common";
|
|
15
|
+
import { apiCall } from "./api-utils";
|
|
16
|
+
|
|
17
|
+
// MARK: Get actor
|
|
18
|
+
export async function getActor(
|
|
19
|
+
config: ClientConfig,
|
|
20
|
+
actorId: RivetId,
|
|
21
|
+
): Promise<ActorsGetResponse> {
|
|
22
|
+
return apiCall<never, ActorsGetResponse>(
|
|
23
|
+
config,
|
|
24
|
+
"GET",
|
|
25
|
+
`/actors/${encodeURIComponent(actorId)}`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// MARK: Get actor by id
|
|
30
|
+
export async function getActorById(
|
|
31
|
+
config: ClientConfig,
|
|
32
|
+
name: string,
|
|
33
|
+
key: string[],
|
|
34
|
+
): Promise<ActorsGetByIdResponse> {
|
|
35
|
+
const serializedKey = serializeActorKey(key);
|
|
36
|
+
return apiCall<never, ActorsGetByIdResponse>(
|
|
37
|
+
config,
|
|
38
|
+
"GET",
|
|
39
|
+
`/actors/by-id?name=${encodeURIComponent(name)}&key=${encodeURIComponent(serializedKey)}`,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// MARK: Get or create actor by id
|
|
44
|
+
export async function getOrCreateActorById(
|
|
45
|
+
config: ClientConfig,
|
|
46
|
+
request: ActorsGetOrCreateByIdRequest,
|
|
47
|
+
): Promise<ActorsGetOrCreateByIdResponse> {
|
|
48
|
+
return apiCall<ActorsGetOrCreateByIdRequest, ActorsGetOrCreateByIdResponse>(
|
|
49
|
+
config,
|
|
50
|
+
"PUT",
|
|
51
|
+
`/actors/by-id`,
|
|
52
|
+
request,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// MARK: Create actor
|
|
57
|
+
export async function createActor(
|
|
58
|
+
config: ClientConfig,
|
|
59
|
+
request: ActorsCreateRequest,
|
|
60
|
+
): Promise<ActorsCreateResponse> {
|
|
61
|
+
return apiCall<ActorsCreateRequest, ActorsCreateResponse>(
|
|
62
|
+
config,
|
|
63
|
+
"POST",
|
|
64
|
+
`/actors`,
|
|
65
|
+
request,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// MARK: Destroy actor
|
|
70
|
+
export async function destroyActor(
|
|
71
|
+
config: ClientConfig,
|
|
72
|
+
actorId: RivetId,
|
|
73
|
+
): Promise<ActorsDeleteResponse> {
|
|
74
|
+
return apiCall<never, ActorsDeleteResponse>(
|
|
75
|
+
config,
|
|
76
|
+
"DELETE",
|
|
77
|
+
`/actors/${encodeURIComponent(actorId)}`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ClientConfig } from "@/client/config";
|
|
2
|
+
import { sendHttpRequest } from "@/client/utils";
|
|
3
|
+
import { logger } from "./log";
|
|
4
|
+
|
|
5
|
+
// Error class for Engine API errors
|
|
6
|
+
export class EngineApiError extends Error {
|
|
7
|
+
constructor(
|
|
8
|
+
public readonly group: string,
|
|
9
|
+
public readonly code: string,
|
|
10
|
+
message?: string,
|
|
11
|
+
) {
|
|
12
|
+
super(message || `Engine API error: ${group}/${code}`);
|
|
13
|
+
this.name = "EngineApiError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function getEndpoint(config: ClientConfig) {
|
|
18
|
+
return config.endpoint ?? "http://127.0.0.1:6420";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Helper function for making API calls
|
|
22
|
+
export async function apiCall<TInput = unknown, TOutput = unknown>(
|
|
23
|
+
config: ClientConfig,
|
|
24
|
+
method: "GET" | "POST" | "PUT" | "DELETE",
|
|
25
|
+
path: string,
|
|
26
|
+
body?: TInput,
|
|
27
|
+
): Promise<TOutput> {
|
|
28
|
+
const endpoint = getEndpoint(config);
|
|
29
|
+
const url = `${endpoint}${path}${path.includes("?") ? "&" : "?"}namespace=${encodeURIComponent(config.namespace)}`;
|
|
30
|
+
|
|
31
|
+
logger().debug({ msg: "making api call", method, url });
|
|
32
|
+
|
|
33
|
+
return await sendHttpRequest<TInput, TOutput>({
|
|
34
|
+
method,
|
|
35
|
+
url,
|
|
36
|
+
headers: {},
|
|
37
|
+
body,
|
|
38
|
+
encoding: "json",
|
|
39
|
+
skipParseResponse: false,
|
|
40
|
+
requestVersionedDataHandler: undefined,
|
|
41
|
+
responseVersionedDataHandler: undefined,
|
|
42
|
+
});
|
|
43
|
+
}
|