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,3726 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class; var _class2;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkG4ABMAQYcjs = require('./chunk-G4ABMAQY.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
var _chunk5ZOHIKWGcjs = require('./chunk-5ZOHIKWG.cjs');
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
var _chunkB3TLRM4Qcjs = require('./chunk-B3TLRM4Q.cjs');
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
var _chunkDFS77KAAcjs = require('./chunk-DFS77KAA.cjs');
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
var _chunkSAZCNSVYcjs = require('./chunk-SAZCNSVY.cjs');
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
var _chunk3MBP4WNCcjs = require('./chunk-3MBP4WNC.cjs');
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
var _chunk6EUWRXLTcjs = require('./chunk-6EUWRXLT.cjs');
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
var _chunk5QGQK44Lcjs = require('./chunk-5QGQK44L.cjs');
|
|
85
|
+
|
|
86
|
+
// src/actor/config.ts
|
|
87
|
+
var _zod = require('zod');
|
|
88
|
+
var ActorConfigSchema = _zod.z.object({
|
|
89
|
+
onCreate: _zod.z.function().optional(),
|
|
90
|
+
onStart: _zod.z.function().optional(),
|
|
91
|
+
onStop: _zod.z.function().optional(),
|
|
92
|
+
onStateChange: _zod.z.function().optional(),
|
|
93
|
+
onBeforeConnect: _zod.z.function().optional(),
|
|
94
|
+
onConnect: _zod.z.function().optional(),
|
|
95
|
+
onDisconnect: _zod.z.function().optional(),
|
|
96
|
+
onBeforeActionResponse: _zod.z.function().optional(),
|
|
97
|
+
onFetch: _zod.z.function().optional(),
|
|
98
|
+
onWebSocket: _zod.z.function().optional(),
|
|
99
|
+
actions: _zod.z.record(_zod.z.function()).default({}),
|
|
100
|
+
state: _zod.z.any().optional(),
|
|
101
|
+
createState: _zod.z.function().optional(),
|
|
102
|
+
connState: _zod.z.any().optional(),
|
|
103
|
+
createConnState: _zod.z.function().optional(),
|
|
104
|
+
vars: _zod.z.any().optional(),
|
|
105
|
+
db: _zod.z.any().optional(),
|
|
106
|
+
createVars: _zod.z.function().optional(),
|
|
107
|
+
options: _zod.z.object({
|
|
108
|
+
createVarsTimeout: _zod.z.number().positive().default(5e3),
|
|
109
|
+
createConnStateTimeout: _zod.z.number().positive().default(5e3),
|
|
110
|
+
onConnectTimeout: _zod.z.number().positive().default(5e3),
|
|
111
|
+
// This must be less than ACTOR_STOP_THRESHOLD_MS
|
|
112
|
+
onStopTimeout: _zod.z.number().positive().default(5e3),
|
|
113
|
+
stateSaveInterval: _zod.z.number().positive().default(1e4),
|
|
114
|
+
actionTimeout: _zod.z.number().positive().default(6e4),
|
|
115
|
+
// Max time to wait for waitUntil background promises during shutdown
|
|
116
|
+
waitUntilTimeout: _zod.z.number().positive().default(15e3),
|
|
117
|
+
connectionLivenessTimeout: _zod.z.number().positive().default(2500),
|
|
118
|
+
connectionLivenessInterval: _zod.z.number().positive().default(5e3),
|
|
119
|
+
noSleep: _zod.z.boolean().default(false),
|
|
120
|
+
sleepTimeout: _zod.z.number().positive().default(3e4)
|
|
121
|
+
}).strict().default({})
|
|
122
|
+
}).strict().refine(
|
|
123
|
+
(data) => !(data.state !== void 0 && data.createState !== void 0),
|
|
124
|
+
{
|
|
125
|
+
message: "Cannot define both 'state' and 'createState'",
|
|
126
|
+
path: ["state"]
|
|
127
|
+
}
|
|
128
|
+
).refine(
|
|
129
|
+
(data) => !(data.connState !== void 0 && data.createConnState !== void 0),
|
|
130
|
+
{
|
|
131
|
+
message: "Cannot define both 'connState' and 'createConnState'",
|
|
132
|
+
path: ["connState"]
|
|
133
|
+
}
|
|
134
|
+
).refine(
|
|
135
|
+
(data) => !(data.vars !== void 0 && data.createVars !== void 0),
|
|
136
|
+
{
|
|
137
|
+
message: "Cannot define both 'vars' and 'createVars'",
|
|
138
|
+
path: ["vars"]
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
// src/actor/router.ts
|
|
143
|
+
var _hono = require('hono');
|
|
144
|
+
var _cors = require('hono/cors');
|
|
145
|
+
var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant);
|
|
146
|
+
|
|
147
|
+
// src/actor/router-endpoints.ts
|
|
148
|
+
var _cborx = require('cbor-x'); var cbor = _interopRequireWildcard(_cborx); var cbor2 = _interopRequireWildcard(_cborx); var cbor3 = _interopRequireWildcard(_cborx); var cbor4 = _interopRequireWildcard(_cborx);
|
|
149
|
+
var _streaming = require('hono/streaming');
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
// src/manager/log.ts
|
|
153
|
+
function logger() {
|
|
154
|
+
return _chunk3MBP4WNCcjs.getLogger.call(void 0, "actor-manager");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/manager/hono-websocket-adapter.ts
|
|
158
|
+
var HonoWebSocketAdapter = (_class = class {
|
|
159
|
+
// WebSocket readyState values
|
|
160
|
+
__init() {this.CONNECTING = 0}
|
|
161
|
+
__init2() {this.OPEN = 1}
|
|
162
|
+
__init3() {this.CLOSING = 2}
|
|
163
|
+
__init4() {this.CLOSED = 3}
|
|
164
|
+
#ws;
|
|
165
|
+
#readyState = 1;
|
|
166
|
+
// Start as OPEN since WSContext is already connected
|
|
167
|
+
#eventListeners = /* @__PURE__ */ new Map();
|
|
168
|
+
#closeCode;
|
|
169
|
+
#closeReason;
|
|
170
|
+
constructor(ws) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);
|
|
171
|
+
this.#ws = ws;
|
|
172
|
+
this.#readyState = this.OPEN;
|
|
173
|
+
setTimeout(() => {
|
|
174
|
+
this.#fireEvent("open", { type: "open", target: this });
|
|
175
|
+
}, 0);
|
|
176
|
+
}
|
|
177
|
+
get readyState() {
|
|
178
|
+
return this.#readyState;
|
|
179
|
+
}
|
|
180
|
+
get binaryType() {
|
|
181
|
+
return "arraybuffer";
|
|
182
|
+
}
|
|
183
|
+
set binaryType(value) {
|
|
184
|
+
}
|
|
185
|
+
get bufferedAmount() {
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
get extensions() {
|
|
189
|
+
return "";
|
|
190
|
+
}
|
|
191
|
+
get protocol() {
|
|
192
|
+
return "";
|
|
193
|
+
}
|
|
194
|
+
get url() {
|
|
195
|
+
return "";
|
|
196
|
+
}
|
|
197
|
+
send(data) {
|
|
198
|
+
if (this.readyState !== this.OPEN) {
|
|
199
|
+
throw new Error("WebSocket is not open");
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
logger().debug({
|
|
203
|
+
msg: "bridge sending data",
|
|
204
|
+
dataType: typeof data,
|
|
205
|
+
isString: typeof data === "string",
|
|
206
|
+
isArrayBuffer: data instanceof ArrayBuffer,
|
|
207
|
+
dataStr: typeof data === "string" ? data.substring(0, 100) : "<non-string>"
|
|
208
|
+
});
|
|
209
|
+
if (typeof data === "string") {
|
|
210
|
+
this.#ws.send(data);
|
|
211
|
+
} else if (data instanceof ArrayBuffer) {
|
|
212
|
+
this.#ws.send(data);
|
|
213
|
+
} else if (ArrayBuffer.isView(data)) {
|
|
214
|
+
const buffer = data.buffer.slice(
|
|
215
|
+
data.byteOffset,
|
|
216
|
+
data.byteOffset + data.byteLength
|
|
217
|
+
);
|
|
218
|
+
if (buffer instanceof SharedArrayBuffer) {
|
|
219
|
+
const arrayBuffer = new ArrayBuffer(buffer.byteLength);
|
|
220
|
+
new Uint8Array(arrayBuffer).set(new Uint8Array(buffer));
|
|
221
|
+
this.#ws.send(arrayBuffer);
|
|
222
|
+
} else {
|
|
223
|
+
this.#ws.send(buffer);
|
|
224
|
+
}
|
|
225
|
+
} else if (data instanceof Blob) {
|
|
226
|
+
data.arrayBuffer().then((buffer) => {
|
|
227
|
+
this.#ws.send(buffer);
|
|
228
|
+
}).catch((error) => {
|
|
229
|
+
logger().error({
|
|
230
|
+
msg: "failed to convert blob to arraybuffer",
|
|
231
|
+
error
|
|
232
|
+
});
|
|
233
|
+
this.#fireEvent("error", { type: "error", target: this, error });
|
|
234
|
+
});
|
|
235
|
+
} else {
|
|
236
|
+
logger().warn({
|
|
237
|
+
msg: "unsupported data type, converting to string",
|
|
238
|
+
dataType: typeof data,
|
|
239
|
+
data
|
|
240
|
+
});
|
|
241
|
+
this.#ws.send(String(data));
|
|
242
|
+
}
|
|
243
|
+
} catch (error) {
|
|
244
|
+
logger().error({ msg: "error sending websocket data", error });
|
|
245
|
+
this.#fireEvent("error", { type: "error", target: this, error });
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
close(code = 1e3, reason = "") {
|
|
250
|
+
if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
this.#readyState = this.CLOSING;
|
|
254
|
+
this.#closeCode = code;
|
|
255
|
+
this.#closeReason = reason;
|
|
256
|
+
try {
|
|
257
|
+
this.#ws.close(code, reason);
|
|
258
|
+
this.#readyState = this.CLOSED;
|
|
259
|
+
this.#fireEvent("close", {
|
|
260
|
+
type: "close",
|
|
261
|
+
target: this,
|
|
262
|
+
code,
|
|
263
|
+
reason,
|
|
264
|
+
wasClean: code === 1e3
|
|
265
|
+
});
|
|
266
|
+
} catch (error) {
|
|
267
|
+
logger().error({ msg: "error closing websocket", error });
|
|
268
|
+
this.#readyState = this.CLOSED;
|
|
269
|
+
this.#fireEvent("close", {
|
|
270
|
+
type: "close",
|
|
271
|
+
target: this,
|
|
272
|
+
code: 1006,
|
|
273
|
+
reason: "Abnormal closure",
|
|
274
|
+
wasClean: false
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
addEventListener(type, listener) {
|
|
279
|
+
if (!this.#eventListeners.has(type)) {
|
|
280
|
+
this.#eventListeners.set(type, /* @__PURE__ */ new Set());
|
|
281
|
+
}
|
|
282
|
+
this.#eventListeners.get(type).add(listener);
|
|
283
|
+
}
|
|
284
|
+
removeEventListener(type, listener) {
|
|
285
|
+
const listeners = this.#eventListeners.get(type);
|
|
286
|
+
if (listeners) {
|
|
287
|
+
listeners.delete(listener);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
dispatchEvent(event) {
|
|
291
|
+
const listeners = this.#eventListeners.get(event.type);
|
|
292
|
+
if (listeners) {
|
|
293
|
+
for (const listener of listeners) {
|
|
294
|
+
try {
|
|
295
|
+
listener(event);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
logger().error({
|
|
298
|
+
msg: `error in ${event.type} event listener`,
|
|
299
|
+
error
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
// Internal method to handle incoming messages from WSContext
|
|
307
|
+
_handleMessage(data) {
|
|
308
|
+
let messageData;
|
|
309
|
+
if (typeof data === "string") {
|
|
310
|
+
messageData = data;
|
|
311
|
+
} else if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
|
312
|
+
messageData = data;
|
|
313
|
+
} else if (data && typeof data === "object" && "data" in data) {
|
|
314
|
+
messageData = data.data;
|
|
315
|
+
} else {
|
|
316
|
+
messageData = String(data);
|
|
317
|
+
}
|
|
318
|
+
logger().debug({
|
|
319
|
+
msg: "bridge handling message",
|
|
320
|
+
dataType: typeof messageData,
|
|
321
|
+
isArrayBuffer: messageData instanceof ArrayBuffer,
|
|
322
|
+
dataStr: typeof messageData === "string" ? messageData : "<binary>"
|
|
323
|
+
});
|
|
324
|
+
this.#fireEvent("message", {
|
|
325
|
+
type: "message",
|
|
326
|
+
target: this,
|
|
327
|
+
data: messageData
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
// Internal method to handle close from WSContext
|
|
331
|
+
_handleClose(code, reason) {
|
|
332
|
+
this.#ws.close(1e3, "hack_force_close");
|
|
333
|
+
if (this.readyState === this.CLOSED) return;
|
|
334
|
+
this.#readyState = this.CLOSED;
|
|
335
|
+
this.#closeCode = code;
|
|
336
|
+
this.#closeReason = reason;
|
|
337
|
+
this.#fireEvent("close", {
|
|
338
|
+
type: "close",
|
|
339
|
+
target: this,
|
|
340
|
+
code,
|
|
341
|
+
reason,
|
|
342
|
+
wasClean: code === 1e3
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
// Internal method to handle errors from WSContext
|
|
346
|
+
_handleError(error) {
|
|
347
|
+
this.#fireEvent("error", {
|
|
348
|
+
type: "error",
|
|
349
|
+
target: this,
|
|
350
|
+
error
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
#fireEvent(type, event) {
|
|
354
|
+
const listeners = this.#eventListeners.get(type);
|
|
355
|
+
if (listeners) {
|
|
356
|
+
for (const listener of listeners) {
|
|
357
|
+
try {
|
|
358
|
+
listener(event);
|
|
359
|
+
} catch (error) {
|
|
360
|
+
logger().error({ msg: `error in ${type} event listener`, error });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
switch (type) {
|
|
365
|
+
case "open":
|
|
366
|
+
if (this.#onopen) {
|
|
367
|
+
try {
|
|
368
|
+
this.#onopen(event);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
logger().error({ msg: "error in onopen handler", error });
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
break;
|
|
374
|
+
case "close":
|
|
375
|
+
if (this.#onclose) {
|
|
376
|
+
try {
|
|
377
|
+
this.#onclose(event);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
logger().error({ msg: "error in onclose handler", error });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
383
|
+
case "error":
|
|
384
|
+
if (this.#onerror) {
|
|
385
|
+
try {
|
|
386
|
+
this.#onerror(event);
|
|
387
|
+
} catch (error) {
|
|
388
|
+
logger().error({ msg: "error in onerror handler", error });
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
break;
|
|
392
|
+
case "message":
|
|
393
|
+
if (this.#onmessage) {
|
|
394
|
+
try {
|
|
395
|
+
this.#onmessage(event);
|
|
396
|
+
} catch (error) {
|
|
397
|
+
logger().error({ msg: "error in onmessage handler", error });
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Event handler properties with getters/setters
|
|
404
|
+
#onopen = null;
|
|
405
|
+
#onclose = null;
|
|
406
|
+
#onerror = null;
|
|
407
|
+
#onmessage = null;
|
|
408
|
+
get onopen() {
|
|
409
|
+
return this.#onopen;
|
|
410
|
+
}
|
|
411
|
+
set onopen(handler) {
|
|
412
|
+
this.#onopen = handler;
|
|
413
|
+
}
|
|
414
|
+
get onclose() {
|
|
415
|
+
return this.#onclose;
|
|
416
|
+
}
|
|
417
|
+
set onclose(handler) {
|
|
418
|
+
this.#onclose = handler;
|
|
419
|
+
}
|
|
420
|
+
get onerror() {
|
|
421
|
+
return this.#onerror;
|
|
422
|
+
}
|
|
423
|
+
set onerror(handler) {
|
|
424
|
+
this.#onerror = handler;
|
|
425
|
+
}
|
|
426
|
+
get onmessage() {
|
|
427
|
+
return this.#onmessage;
|
|
428
|
+
}
|
|
429
|
+
set onmessage(handler) {
|
|
430
|
+
this.#onmessage = handler;
|
|
431
|
+
}
|
|
432
|
+
}, _class);
|
|
433
|
+
|
|
434
|
+
// src/actor/router-endpoints.ts
|
|
435
|
+
var SSE_PING_INTERVAL = 1e3;
|
|
436
|
+
async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, encoding, parameters, connId, connToken) {
|
|
437
|
+
const exposeInternalError = req ? getRequestExposeInternalError(req) : false;
|
|
438
|
+
const {
|
|
439
|
+
promise: handlersPromise,
|
|
440
|
+
resolve: handlersResolve,
|
|
441
|
+
reject: handlersReject
|
|
442
|
+
} = _chunk6EUWRXLTcjs.promiseWithResolvers.call(void 0, );
|
|
443
|
+
let actor2;
|
|
444
|
+
try {
|
|
445
|
+
actor2 = await actorDriver.loadActor(actorId);
|
|
446
|
+
} catch (error) {
|
|
447
|
+
return {
|
|
448
|
+
onOpen: (_evt, ws) => {
|
|
449
|
+
const { code } = _chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
450
|
+
error,
|
|
451
|
+
actor2.rLog,
|
|
452
|
+
{
|
|
453
|
+
wsEvent: "open"
|
|
454
|
+
},
|
|
455
|
+
exposeInternalError
|
|
456
|
+
);
|
|
457
|
+
ws.close(1011, code);
|
|
458
|
+
},
|
|
459
|
+
onMessage: (_evt, ws) => {
|
|
460
|
+
ws.close(1011, "Actor not loaded");
|
|
461
|
+
},
|
|
462
|
+
onClose: (_event, _ws) => {
|
|
463
|
+
},
|
|
464
|
+
onError: (_error) => {
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
const closePromise = _chunk6EUWRXLTcjs.promiseWithResolvers.call(void 0, );
|
|
469
|
+
const socketId = _chunk5ZOHIKWGcjs.generateConnSocketId.call(void 0, );
|
|
470
|
+
return {
|
|
471
|
+
onOpen: (_evt, ws) => {
|
|
472
|
+
actor2.rLog.debug("actor websocket open");
|
|
473
|
+
(async () => {
|
|
474
|
+
try {
|
|
475
|
+
let conn;
|
|
476
|
+
actor2.rLog.debug({
|
|
477
|
+
msg: connId ? "websocket reconnection attempt" : "new websocket connection",
|
|
478
|
+
connId,
|
|
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
|
+
},
|
|
492
|
+
parameters,
|
|
493
|
+
req,
|
|
494
|
+
connId,
|
|
495
|
+
connToken
|
|
496
|
+
);
|
|
497
|
+
handlersResolve({ conn, actor: actor2, connId: conn.id });
|
|
498
|
+
} catch (error) {
|
|
499
|
+
handlersReject(error);
|
|
500
|
+
const { code } = _chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
501
|
+
error,
|
|
502
|
+
actor2.rLog,
|
|
503
|
+
{
|
|
504
|
+
wsEvent: "open"
|
|
505
|
+
},
|
|
506
|
+
exposeInternalError
|
|
507
|
+
);
|
|
508
|
+
ws.close(1011, code);
|
|
509
|
+
}
|
|
510
|
+
})();
|
|
511
|
+
},
|
|
512
|
+
onMessage: (evt, ws) => {
|
|
513
|
+
handlersPromise.then(({ conn, actor: actor3 }) => {
|
|
514
|
+
actor3.rLog.debug({ msg: "received message" });
|
|
515
|
+
const value = evt.data.valueOf();
|
|
516
|
+
_chunkDFS77KAAcjs.parseMessage.call(void 0, value, {
|
|
517
|
+
encoding,
|
|
518
|
+
maxIncomingMessageSize: runConfig.maxIncomingMessageSize
|
|
519
|
+
}).then((message) => {
|
|
520
|
+
actor3.processMessage(message, conn).catch((error) => {
|
|
521
|
+
const { code } = _chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
522
|
+
error,
|
|
523
|
+
actor3.rLog,
|
|
524
|
+
{
|
|
525
|
+
wsEvent: "message"
|
|
526
|
+
},
|
|
527
|
+
exposeInternalError
|
|
528
|
+
);
|
|
529
|
+
ws.close(1011, code);
|
|
530
|
+
});
|
|
531
|
+
}).catch((error) => {
|
|
532
|
+
const { code } = _chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
533
|
+
error,
|
|
534
|
+
actor3.rLog,
|
|
535
|
+
{
|
|
536
|
+
wsEvent: "message"
|
|
537
|
+
},
|
|
538
|
+
exposeInternalError
|
|
539
|
+
);
|
|
540
|
+
ws.close(1011, code);
|
|
541
|
+
});
|
|
542
|
+
}).catch((error) => {
|
|
543
|
+
const { code } = _chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
544
|
+
error,
|
|
545
|
+
actor2.rLog,
|
|
546
|
+
{
|
|
547
|
+
wsEvent: "message"
|
|
548
|
+
},
|
|
549
|
+
exposeInternalError
|
|
550
|
+
);
|
|
551
|
+
ws.close(1011, code);
|
|
552
|
+
});
|
|
553
|
+
},
|
|
554
|
+
onClose: (event, ws) => {
|
|
555
|
+
handlersReject(`WebSocket closed (${event.code}): ${event.reason}`);
|
|
556
|
+
closePromise.resolve();
|
|
557
|
+
if (event.wasClean) {
|
|
558
|
+
actor2.rLog.info({
|
|
559
|
+
msg: "websocket closed",
|
|
560
|
+
code: event.code,
|
|
561
|
+
reason: event.reason,
|
|
562
|
+
wasClean: event.wasClean
|
|
563
|
+
});
|
|
564
|
+
} else {
|
|
565
|
+
actor2.rLog.warn({
|
|
566
|
+
msg: "websocket closed",
|
|
567
|
+
code: event.code,
|
|
568
|
+
reason: event.reason,
|
|
569
|
+
wasClean: event.wasClean
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
ws.close(1e3, "hack_force_close");
|
|
573
|
+
handlersPromise.then(({ conn, actor: actor3 }) => {
|
|
574
|
+
actor3.__connDisconnected(conn, event.wasClean, socketId);
|
|
575
|
+
}).catch((error) => {
|
|
576
|
+
_chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
577
|
+
error,
|
|
578
|
+
actor2.rLog,
|
|
579
|
+
{ wsEvent: "close" },
|
|
580
|
+
exposeInternalError
|
|
581
|
+
);
|
|
582
|
+
});
|
|
583
|
+
},
|
|
584
|
+
onError: (_error) => {
|
|
585
|
+
try {
|
|
586
|
+
actor2.rLog.warn({ msg: "websocket error" });
|
|
587
|
+
} catch (error) {
|
|
588
|
+
_chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
589
|
+
error,
|
|
590
|
+
actor2.rLog,
|
|
591
|
+
{ wsEvent: "error" },
|
|
592
|
+
exposeInternalError
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
async function handleSseConnect(c, _runConfig, actorDriver, actorId) {
|
|
599
|
+
c.header("Content-Encoding", "Identity");
|
|
600
|
+
const encoding = getRequestEncoding(c.req);
|
|
601
|
+
const parameters = getRequestConnParams(c.req);
|
|
602
|
+
const socketId = _chunk5ZOHIKWGcjs.generateConnSocketId.call(void 0, );
|
|
603
|
+
const connId = c.req.header(_chunkSAZCNSVYcjs.HEADER_CONN_ID);
|
|
604
|
+
const connToken = c.req.header(_chunkSAZCNSVYcjs.HEADER_CONN_TOKEN);
|
|
605
|
+
return _streaming.streamSSE.call(void 0, c, async (stream) => {
|
|
606
|
+
let actor2;
|
|
607
|
+
let conn;
|
|
608
|
+
try {
|
|
609
|
+
actor2 = await actorDriver.loadActor(actorId);
|
|
610
|
+
actor2.rLog.debug({
|
|
611
|
+
msg: connId ? "sse reconnection attempt" : "sse open",
|
|
612
|
+
connId
|
|
613
|
+
});
|
|
614
|
+
conn = await actor2.createConn(
|
|
615
|
+
{
|
|
616
|
+
socketId,
|
|
617
|
+
driverState: {
|
|
618
|
+
[1 /* SSE */]: {
|
|
619
|
+
encoding,
|
|
620
|
+
stream
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
parameters,
|
|
625
|
+
c.req.raw,
|
|
626
|
+
connId,
|
|
627
|
+
connToken
|
|
628
|
+
);
|
|
629
|
+
const abortResolver = _chunk6EUWRXLTcjs.promiseWithResolvers.call(void 0, );
|
|
630
|
+
stream.onAbort(() => {
|
|
631
|
+
});
|
|
632
|
+
c.req.raw.signal.addEventListener("abort", async () => {
|
|
633
|
+
_invariant2.default.call(void 0, actor2, "actor should exist");
|
|
634
|
+
const rLog = _nullishCoalesce(actor2.rLog, () => ( _chunkSAZCNSVYcjs.loggerWithoutContext.call(void 0, )));
|
|
635
|
+
try {
|
|
636
|
+
rLog.debug("sse stream aborted");
|
|
637
|
+
if (conn) {
|
|
638
|
+
actor2.__connDisconnected(conn, false, socketId);
|
|
639
|
+
}
|
|
640
|
+
abortResolver.resolve(void 0);
|
|
641
|
+
} catch (error) {
|
|
642
|
+
rLog.error({ msg: "error closing sse connection", error });
|
|
643
|
+
abortResolver.resolve(void 0);
|
|
644
|
+
}
|
|
645
|
+
});
|
|
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);
|
|
657
|
+
}
|
|
658
|
+
} catch (error) {
|
|
659
|
+
_chunkSAZCNSVYcjs.loggerWithoutContext.call(void 0, ).error({ msg: "error in sse connection", error });
|
|
660
|
+
if (conn && actor2 !== void 0) {
|
|
661
|
+
actor2.__connDisconnected(conn, false, socketId);
|
|
662
|
+
}
|
|
663
|
+
stream.close();
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
async function handleAction(c, _runConfig, actorDriver, actionName, actorId) {
|
|
668
|
+
const encoding = getRequestEncoding(c.req);
|
|
669
|
+
const parameters = getRequestConnParams(c.req);
|
|
670
|
+
const arrayBuffer = await c.req.arrayBuffer();
|
|
671
|
+
const request = _chunkSAZCNSVYcjs.deserializeWithEncoding.call(void 0,
|
|
672
|
+
encoding,
|
|
673
|
+
new Uint8Array(arrayBuffer),
|
|
674
|
+
_chunkDFS77KAAcjs.HTTP_ACTION_REQUEST_VERSIONED
|
|
675
|
+
);
|
|
676
|
+
const actionArgs = cbor.decode(new Uint8Array(request.args));
|
|
677
|
+
const socketId = _chunk5ZOHIKWGcjs.generateConnSocketId.call(void 0, );
|
|
678
|
+
let actor2;
|
|
679
|
+
let conn;
|
|
680
|
+
let output;
|
|
681
|
+
try {
|
|
682
|
+
actor2 = await actorDriver.loadActor(actorId);
|
|
683
|
+
actor2.rLog.debug({ msg: "handling action", actionName, encoding });
|
|
684
|
+
conn = await actor2.createConn(
|
|
685
|
+
{
|
|
686
|
+
socketId,
|
|
687
|
+
driverState: { [2 /* HTTP */]: {} }
|
|
688
|
+
},
|
|
689
|
+
parameters,
|
|
690
|
+
c.req.raw
|
|
691
|
+
);
|
|
692
|
+
const ctx = new (0, _chunkDFS77KAAcjs.ActionContext)(actor2.actorContext, conn);
|
|
693
|
+
output = await actor2.executeAction(ctx, actionName, actionArgs);
|
|
694
|
+
} finally {
|
|
695
|
+
if (conn) {
|
|
696
|
+
actor2 == null ? void 0 : actor2.__connDisconnected(conn, true, socketId);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
const responseData = {
|
|
700
|
+
output: _chunk6EUWRXLTcjs.bufferToArrayBuffer.call(void 0, cbor.encode(output))
|
|
701
|
+
};
|
|
702
|
+
const serialized = _chunkSAZCNSVYcjs.serializeWithEncoding.call(void 0,
|
|
703
|
+
encoding,
|
|
704
|
+
responseData,
|
|
705
|
+
_chunkDFS77KAAcjs.HTTP_ACTION_RESPONSE_VERSIONED
|
|
706
|
+
);
|
|
707
|
+
return c.body(serialized, 200, {
|
|
708
|
+
"Content-Type": _chunkSAZCNSVYcjs.contentTypeForEncoding.call(void 0, encoding)
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
async function handleConnectionMessage(c, _runConfig, actorDriver, connId, connToken, actorId) {
|
|
712
|
+
const encoding = getRequestEncoding(c.req);
|
|
713
|
+
const arrayBuffer = await c.req.arrayBuffer();
|
|
714
|
+
const message = _chunkSAZCNSVYcjs.deserializeWithEncoding.call(void 0,
|
|
715
|
+
encoding,
|
|
716
|
+
new Uint8Array(arrayBuffer),
|
|
717
|
+
_chunkDFS77KAAcjs.TO_SERVER_VERSIONED
|
|
718
|
+
);
|
|
719
|
+
const actor2 = await actorDriver.loadActor(actorId);
|
|
720
|
+
const conn = actor2.conns.get(connId);
|
|
721
|
+
if (!conn) {
|
|
722
|
+
throw new (0, _chunk5QGQK44Lcjs.ConnNotFound)(connId);
|
|
723
|
+
}
|
|
724
|
+
if (conn._token !== connToken) {
|
|
725
|
+
throw new (0, _chunk5QGQK44Lcjs.IncorrectConnToken)();
|
|
726
|
+
}
|
|
727
|
+
await actor2.processMessage(message, conn);
|
|
728
|
+
return c.json({});
|
|
729
|
+
}
|
|
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 (0, _chunk5QGQK44Lcjs.ConnNotFound)(connId);
|
|
736
|
+
}
|
|
737
|
+
if (conn._token !== connToken) {
|
|
738
|
+
throw new (0, _chunk5QGQK44Lcjs.IncorrectConnToken)();
|
|
739
|
+
}
|
|
740
|
+
if (!((_a = conn.__socket) == null ? void 0 : _a.driverState) || !(1 /* SSE */ in conn.__socket.driverState)) {
|
|
741
|
+
throw new (0, _chunk5QGQK44Lcjs.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) {
|
|
749
|
+
const actor2 = await actorDriver.loadActor(actorId);
|
|
750
|
+
return {
|
|
751
|
+
onOpen: (_evt, ws) => {
|
|
752
|
+
const adapter = new HonoWebSocketAdapter(ws);
|
|
753
|
+
ws.__adapter = adapter;
|
|
754
|
+
const url = new URL(path3, "http://actor");
|
|
755
|
+
const pathname = url.pathname.replace(/^\/raw\/websocket\/?/, "") || "/";
|
|
756
|
+
const normalizedPath = (pathname.startsWith("/") ? pathname : "/" + pathname) + url.search;
|
|
757
|
+
let newRequest;
|
|
758
|
+
if (req) {
|
|
759
|
+
newRequest = new Request(`http://actor${normalizedPath}`, req);
|
|
760
|
+
} else {
|
|
761
|
+
newRequest = new Request(`http://actor${normalizedPath}`, {
|
|
762
|
+
method: "GET"
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
actor2.rLog.debug({
|
|
766
|
+
msg: "rewriting websocket url",
|
|
767
|
+
from: path3,
|
|
768
|
+
to: newRequest.url,
|
|
769
|
+
pathname: url.pathname,
|
|
770
|
+
search: url.search,
|
|
771
|
+
normalizedPath
|
|
772
|
+
});
|
|
773
|
+
actor2.handleWebSocket(adapter, {
|
|
774
|
+
request: newRequest
|
|
775
|
+
});
|
|
776
|
+
},
|
|
777
|
+
onMessage: (event, ws) => {
|
|
778
|
+
const adapter = ws.__adapter;
|
|
779
|
+
if (adapter) {
|
|
780
|
+
adapter._handleMessage(event);
|
|
781
|
+
}
|
|
782
|
+
},
|
|
783
|
+
onClose: (evt, ws) => {
|
|
784
|
+
const adapter = ws.__adapter;
|
|
785
|
+
if (adapter) {
|
|
786
|
+
adapter._handleClose((evt == null ? void 0 : evt.code) || 1006, (evt == null ? void 0 : evt.reason) || "");
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
onError: (error, ws) => {
|
|
790
|
+
const adapter = ws.__adapter;
|
|
791
|
+
if (adapter) {
|
|
792
|
+
adapter._handleError(error);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
function getRequestEncoding(req) {
|
|
798
|
+
const encodingParam = req.header(_chunkSAZCNSVYcjs.HEADER_ENCODING);
|
|
799
|
+
if (!encodingParam) {
|
|
800
|
+
throw new (0, _chunk5QGQK44Lcjs.InvalidEncoding)("undefined");
|
|
801
|
+
}
|
|
802
|
+
const result = _chunkSAZCNSVYcjs.EncodingSchema.safeParse(encodingParam);
|
|
803
|
+
if (!result.success) {
|
|
804
|
+
throw new (0, _chunk5QGQK44Lcjs.InvalidEncoding)(encodingParam);
|
|
805
|
+
}
|
|
806
|
+
return result.data;
|
|
807
|
+
}
|
|
808
|
+
function getRequestExposeInternalError(_req) {
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
function getRequestConnParams(req) {
|
|
812
|
+
const paramsParam = req.header(_chunkSAZCNSVYcjs.HEADER_CONN_PARAMS);
|
|
813
|
+
if (!paramsParam) {
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
try {
|
|
817
|
+
return JSON.parse(paramsParam);
|
|
818
|
+
} catch (err) {
|
|
819
|
+
throw new (0, _chunk5QGQK44Lcjs.InvalidParams)(
|
|
820
|
+
`Invalid params JSON: ${_chunk6EUWRXLTcjs.stringifyError.call(void 0, err)}`
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// src/common/router.ts
|
|
826
|
+
|
|
827
|
+
function logger2() {
|
|
828
|
+
return _chunk3MBP4WNCcjs.getLogger.call(void 0, "router");
|
|
829
|
+
}
|
|
830
|
+
function loggerMiddleware(logger7) {
|
|
831
|
+
return async (c, next) => {
|
|
832
|
+
const method = c.req.method;
|
|
833
|
+
const path3 = c.req.path;
|
|
834
|
+
const startTime = Date.now();
|
|
835
|
+
await next();
|
|
836
|
+
const duration = Date.now() - startTime;
|
|
837
|
+
logger7.debug({
|
|
838
|
+
msg: "http request",
|
|
839
|
+
method,
|
|
840
|
+
path: path3,
|
|
841
|
+
status: c.res.status,
|
|
842
|
+
dt: `${duration}ms`,
|
|
843
|
+
reqSize: c.req.header("content-length"),
|
|
844
|
+
resSize: c.res.headers.get("content-length"),
|
|
845
|
+
userAgent: c.req.header("user-agent")
|
|
846
|
+
});
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
function handleRouteNotFound(c) {
|
|
850
|
+
return c.text("Not Found (RivetKit)", 404);
|
|
851
|
+
}
|
|
852
|
+
function handleRouteError(error, c) {
|
|
853
|
+
const exposeInternalError = getRequestExposeInternalError(c.req.raw);
|
|
854
|
+
const { statusCode, group, code, message, metadata } = _chunk6EUWRXLTcjs.deconstructError.call(void 0,
|
|
855
|
+
error,
|
|
856
|
+
logger2(),
|
|
857
|
+
{
|
|
858
|
+
method: c.req.method,
|
|
859
|
+
path: c.req.path
|
|
860
|
+
},
|
|
861
|
+
exposeInternalError
|
|
862
|
+
);
|
|
863
|
+
let encoding;
|
|
864
|
+
try {
|
|
865
|
+
encoding = getRequestEncoding(c.req);
|
|
866
|
+
} catch (_) {
|
|
867
|
+
encoding = "json";
|
|
868
|
+
}
|
|
869
|
+
const output = _chunkSAZCNSVYcjs.serializeWithEncoding.call(void 0,
|
|
870
|
+
encoding,
|
|
871
|
+
{
|
|
872
|
+
group,
|
|
873
|
+
code,
|
|
874
|
+
message,
|
|
875
|
+
// TODO: Cannot serialize non-binary meta since it requires ArrayBuffer atm
|
|
876
|
+
metadata: _chunkSAZCNSVYcjs.encodingIsBinary.call(void 0, encoding) ? _chunk6EUWRXLTcjs.bufferToArrayBuffer.call(void 0, cbor2.encode(metadata)) : null
|
|
877
|
+
},
|
|
878
|
+
_chunkDFS77KAAcjs.HTTP_RESPONSE_ERROR_VERSIONED
|
|
879
|
+
);
|
|
880
|
+
return c.body(output, { status: statusCode });
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// src/actor/router.ts
|
|
884
|
+
function createActorRouter(runConfig, actorDriver) {
|
|
885
|
+
const router = new (0, _hono.Hono)({ strict: false });
|
|
886
|
+
router.use("*", loggerMiddleware(_chunkSAZCNSVYcjs.loggerWithoutContext.call(void 0, )));
|
|
887
|
+
router.get("/", (c) => {
|
|
888
|
+
return c.text(
|
|
889
|
+
"This is an RivetKit actor.\n\nLearn more at https://rivetkit.org"
|
|
890
|
+
);
|
|
891
|
+
});
|
|
892
|
+
router.get("/health", (c) => {
|
|
893
|
+
return c.text("ok");
|
|
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
|
+
});
|
|
915
|
+
router.get(_chunkSAZCNSVYcjs.PATH_CONNECT_WEBSOCKET, async (c) => {
|
|
916
|
+
var _a;
|
|
917
|
+
const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
|
|
918
|
+
if (upgradeWebSocket) {
|
|
919
|
+
return upgradeWebSocket(async (c2) => {
|
|
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(_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING)) {
|
|
929
|
+
encodingRaw = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING.length);
|
|
930
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS)) {
|
|
931
|
+
connParamsRaw = decodeURIComponent(
|
|
932
|
+
protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS.length)
|
|
933
|
+
);
|
|
934
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_ID)) {
|
|
935
|
+
connIdRaw = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_ID.length);
|
|
936
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_TOKEN)) {
|
|
937
|
+
connTokenRaw = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_TOKEN.length);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
const encoding = _chunkSAZCNSVYcjs.EncodingSchema.parse(encodingRaw);
|
|
942
|
+
const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
|
|
943
|
+
return await handleWebSocketConnect(
|
|
944
|
+
c2.req.raw,
|
|
945
|
+
runConfig,
|
|
946
|
+
actorDriver,
|
|
947
|
+
c2.env.actorId,
|
|
948
|
+
encoding,
|
|
949
|
+
connParams,
|
|
950
|
+
connIdRaw,
|
|
951
|
+
connTokenRaw
|
|
952
|
+
);
|
|
953
|
+
})(c, _chunk6EUWRXLTcjs.noopNext.call(void 0, ));
|
|
954
|
+
} else {
|
|
955
|
+
return c.text(
|
|
956
|
+
"WebSockets are not enabled for this driver. Use SSE instead.",
|
|
957
|
+
400
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
router.get("/connect/sse", async (c) => {
|
|
962
|
+
return handleSseConnect(c, runConfig, actorDriver, c.env.actorId);
|
|
963
|
+
});
|
|
964
|
+
router.post("/action/:action", async (c) => {
|
|
965
|
+
const actionName = c.req.param("action");
|
|
966
|
+
return handleAction(c, runConfig, actorDriver, actionName, c.env.actorId);
|
|
967
|
+
});
|
|
968
|
+
router.post("/connections/message", async (c) => {
|
|
969
|
+
const connId = c.req.header(_chunkSAZCNSVYcjs.HEADER_CONN_ID);
|
|
970
|
+
const connToken = c.req.header(_chunkSAZCNSVYcjs.HEADER_CONN_TOKEN);
|
|
971
|
+
if (!connId || !connToken) {
|
|
972
|
+
throw new Error("Missing required parameters");
|
|
973
|
+
}
|
|
974
|
+
return handleConnectionMessage(
|
|
975
|
+
c,
|
|
976
|
+
runConfig,
|
|
977
|
+
actorDriver,
|
|
978
|
+
connId,
|
|
979
|
+
connToken,
|
|
980
|
+
c.env.actorId
|
|
981
|
+
);
|
|
982
|
+
});
|
|
983
|
+
router.post("/connections/close", async (c) => {
|
|
984
|
+
const connId = c.req.header(_chunkSAZCNSVYcjs.HEADER_CONN_ID);
|
|
985
|
+
const connToken = c.req.header(_chunkSAZCNSVYcjs.HEADER_CONN_TOKEN);
|
|
986
|
+
if (!connId || !connToken) {
|
|
987
|
+
throw new Error("Missing required parameters");
|
|
988
|
+
}
|
|
989
|
+
return handleConnectionClose(
|
|
990
|
+
c,
|
|
991
|
+
runConfig,
|
|
992
|
+
actorDriver,
|
|
993
|
+
connId,
|
|
994
|
+
connToken,
|
|
995
|
+
c.env.actorId
|
|
996
|
+
);
|
|
997
|
+
});
|
|
998
|
+
router.all("/raw/http/*", async (c) => {
|
|
999
|
+
const actor2 = await actorDriver.loadActor(c.env.actorId);
|
|
1000
|
+
const url = new URL(c.req.url);
|
|
1001
|
+
const originalPath = url.pathname.replace(/^\/raw\/http/, "") || "/";
|
|
1002
|
+
const correctedUrl = new URL(originalPath + url.search, url.origin);
|
|
1003
|
+
const correctedRequest = new Request(correctedUrl, {
|
|
1004
|
+
method: c.req.method,
|
|
1005
|
+
headers: c.req.raw.headers,
|
|
1006
|
+
body: c.req.raw.body,
|
|
1007
|
+
duplex: "half"
|
|
1008
|
+
});
|
|
1009
|
+
_chunkSAZCNSVYcjs.loggerWithoutContext.call(void 0, ).debug({
|
|
1010
|
+
msg: "rewriting http url",
|
|
1011
|
+
from: c.req.url,
|
|
1012
|
+
to: correctedRequest.url
|
|
1013
|
+
});
|
|
1014
|
+
const response = await actor2.handleFetch(correctedRequest, {});
|
|
1015
|
+
if (!response) {
|
|
1016
|
+
throw new (0, _chunk5QGQK44Lcjs.InternalError)("handleFetch returned void unexpectedly");
|
|
1017
|
+
}
|
|
1018
|
+
return response;
|
|
1019
|
+
});
|
|
1020
|
+
router.get(`${_chunkSAZCNSVYcjs.PATH_RAW_WEBSOCKET_PREFIX}*`, async (c) => {
|
|
1021
|
+
var _a;
|
|
1022
|
+
const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
|
|
1023
|
+
if (upgradeWebSocket) {
|
|
1024
|
+
return upgradeWebSocket(async (c2) => {
|
|
1025
|
+
const url = new URL(c2.req.url);
|
|
1026
|
+
const pathWithQuery = c2.req.path + url.search;
|
|
1027
|
+
_chunkSAZCNSVYcjs.loggerWithoutContext.call(void 0, ).debug({
|
|
1028
|
+
msg: "actor router raw websocket",
|
|
1029
|
+
path: c2.req.path,
|
|
1030
|
+
url: c2.req.url,
|
|
1031
|
+
search: url.search,
|
|
1032
|
+
pathWithQuery
|
|
1033
|
+
});
|
|
1034
|
+
return await handleRawWebSocketHandler(
|
|
1035
|
+
c2.req.raw,
|
|
1036
|
+
pathWithQuery,
|
|
1037
|
+
actorDriver,
|
|
1038
|
+
c2.env.actorId
|
|
1039
|
+
);
|
|
1040
|
+
})(c, _chunk6EUWRXLTcjs.noopNext.call(void 0, ));
|
|
1041
|
+
} else {
|
|
1042
|
+
return c.text(
|
|
1043
|
+
"WebSockets are not enabled for this driver. Use SSE instead.",
|
|
1044
|
+
400
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
1048
|
+
if (_chunkG4ABMAQYcjs.isInspectorEnabled.call(void 0, runConfig, "actor")) {
|
|
1049
|
+
router.route(
|
|
1050
|
+
"/inspect",
|
|
1051
|
+
new (0, _hono.Hono)().use(
|
|
1052
|
+
_cors.cors.call(void 0, runConfig.inspector.cors),
|
|
1053
|
+
_chunkG4ABMAQYcjs.secureInspector.call(void 0, runConfig),
|
|
1054
|
+
async (c, next) => {
|
|
1055
|
+
const inspector = (await actorDriver.loadActor(c.env.actorId)).inspector;
|
|
1056
|
+
_invariant2.default.call(void 0, inspector, "inspector not supported on this platform");
|
|
1057
|
+
c.set("inspector", inspector);
|
|
1058
|
+
return next();
|
|
1059
|
+
}
|
|
1060
|
+
).route("/", _chunk5ZOHIKWGcjs.createActorInspectorRouter.call(void 0, ))
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
router.notFound(handleRouteNotFound);
|
|
1064
|
+
router.onError(handleRouteError);
|
|
1065
|
+
return router;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// src/actor/mod.ts
|
|
1069
|
+
function actor(input) {
|
|
1070
|
+
const config2 = ActorConfigSchema.parse(input);
|
|
1071
|
+
return new (0, _chunk5ZOHIKWGcjs.ActorDefinition)(config2);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// src/common/inline-websocket-adapter2.ts
|
|
1075
|
+
var _ws2 = require('hono/ws');
|
|
1076
|
+
function logger3() {
|
|
1077
|
+
return _chunk3MBP4WNCcjs.getLogger.call(void 0, "fake-event-source2");
|
|
1078
|
+
}
|
|
1079
|
+
var InlineWebSocketAdapter2 = (_class2 = class {
|
|
1080
|
+
// WebSocket readyState values
|
|
1081
|
+
__init5() {this.CONNECTING = 0}
|
|
1082
|
+
__init6() {this.OPEN = 1}
|
|
1083
|
+
__init7() {this.CLOSING = 2}
|
|
1084
|
+
__init8() {this.CLOSED = 3}
|
|
1085
|
+
// Private properties
|
|
1086
|
+
#handler;
|
|
1087
|
+
#wsContext;
|
|
1088
|
+
#readyState = 0;
|
|
1089
|
+
// Start in CONNECTING state
|
|
1090
|
+
#queuedMessages = [];
|
|
1091
|
+
// Event buffering is needed since events can be fired
|
|
1092
|
+
// before JavaScript has a chance to add event listeners (e.g. within the same tick)
|
|
1093
|
+
#bufferedEvents = [];
|
|
1094
|
+
// Event listeners with buffering
|
|
1095
|
+
#eventListeners = /* @__PURE__ */ new Map();
|
|
1096
|
+
constructor(handler) {;_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);
|
|
1097
|
+
this.#handler = handler;
|
|
1098
|
+
this.#wsContext = new (0, _ws2.WSContext)({
|
|
1099
|
+
raw: this,
|
|
1100
|
+
send: (data) => {
|
|
1101
|
+
logger3().debug({ msg: "WSContext.send called" });
|
|
1102
|
+
this.#handleMessage(data);
|
|
1103
|
+
},
|
|
1104
|
+
close: (code, reason) => {
|
|
1105
|
+
logger3().debug({ msg: "WSContext.close called", code, reason });
|
|
1106
|
+
this.#handleClose(code || 1e3, reason || "");
|
|
1107
|
+
},
|
|
1108
|
+
// Set readyState to 1 (OPEN) since handlers expect an open connection
|
|
1109
|
+
readyState: 1
|
|
1110
|
+
});
|
|
1111
|
+
this.#initialize();
|
|
1112
|
+
}
|
|
1113
|
+
get readyState() {
|
|
1114
|
+
return this.#readyState;
|
|
1115
|
+
}
|
|
1116
|
+
get binaryType() {
|
|
1117
|
+
return "arraybuffer";
|
|
1118
|
+
}
|
|
1119
|
+
set binaryType(value) {
|
|
1120
|
+
}
|
|
1121
|
+
get bufferedAmount() {
|
|
1122
|
+
return 0;
|
|
1123
|
+
}
|
|
1124
|
+
get extensions() {
|
|
1125
|
+
return "";
|
|
1126
|
+
}
|
|
1127
|
+
get protocol() {
|
|
1128
|
+
return "";
|
|
1129
|
+
}
|
|
1130
|
+
get url() {
|
|
1131
|
+
return "";
|
|
1132
|
+
}
|
|
1133
|
+
send(data) {
|
|
1134
|
+
logger3().debug({ msg: "send called", readyState: this.readyState });
|
|
1135
|
+
if (this.readyState !== this.OPEN) {
|
|
1136
|
+
const error = new Error("WebSocket is not open");
|
|
1137
|
+
logger3().warn({
|
|
1138
|
+
msg: "cannot send message, websocket not open",
|
|
1139
|
+
readyState: this.readyState,
|
|
1140
|
+
dataType: typeof data,
|
|
1141
|
+
dataLength: typeof data === "string" ? data.length : "binary",
|
|
1142
|
+
error
|
|
1143
|
+
});
|
|
1144
|
+
this.#fireError(error);
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
this.#handler.onMessage({ data }, this.#wsContext);
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Closes the connection
|
|
1151
|
+
*/
|
|
1152
|
+
close(code = 1e3, reason = "") {
|
|
1153
|
+
if (this.readyState === this.CLOSED || this.readyState === this.CLOSING) {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
logger3().debug({ msg: "closing fake websocket", code, reason });
|
|
1157
|
+
this.#readyState = this.CLOSING;
|
|
1158
|
+
try {
|
|
1159
|
+
this.#handler.onClose({ code, reason, wasClean: true }, this.#wsContext);
|
|
1160
|
+
} catch (err) {
|
|
1161
|
+
logger3().error({ msg: "error closing websocket", error: err });
|
|
1162
|
+
} finally {
|
|
1163
|
+
this.#readyState = this.CLOSED;
|
|
1164
|
+
const closeEvent = {
|
|
1165
|
+
type: "close",
|
|
1166
|
+
wasClean: code === 1e3,
|
|
1167
|
+
code,
|
|
1168
|
+
reason,
|
|
1169
|
+
target: this,
|
|
1170
|
+
currentTarget: this
|
|
1171
|
+
};
|
|
1172
|
+
this.#fireClose(closeEvent);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Initialize the connection with the handler
|
|
1177
|
+
*/
|
|
1178
|
+
async #initialize() {
|
|
1179
|
+
try {
|
|
1180
|
+
logger3().debug({ msg: "fake websocket initializing" });
|
|
1181
|
+
logger3().debug({ msg: "calling handler.onOpen with WSContext" });
|
|
1182
|
+
this.#handler.onOpen(void 0, this.#wsContext);
|
|
1183
|
+
this.#readyState = this.OPEN;
|
|
1184
|
+
logger3().debug({ msg: "fake websocket initialized and now OPEN" });
|
|
1185
|
+
this.#fireOpen();
|
|
1186
|
+
if (this.#queuedMessages.length > 0) {
|
|
1187
|
+
if (this.readyState !== this.OPEN) {
|
|
1188
|
+
logger3().warn({
|
|
1189
|
+
msg: "socket no longer open, dropping queued messages"
|
|
1190
|
+
});
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
logger3().debug({
|
|
1194
|
+
msg: `now processing ${this.#queuedMessages.length} queued messages`
|
|
1195
|
+
});
|
|
1196
|
+
const messagesToProcess = [...this.#queuedMessages];
|
|
1197
|
+
this.#queuedMessages = [];
|
|
1198
|
+
for (const message of messagesToProcess) {
|
|
1199
|
+
logger3().debug({ msg: "processing queued message" });
|
|
1200
|
+
this.#handleMessage(message);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
} catch (err) {
|
|
1204
|
+
logger3().error({
|
|
1205
|
+
msg: "error opening fake websocket",
|
|
1206
|
+
error: err,
|
|
1207
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
1208
|
+
stack: err instanceof Error ? err.stack : void 0
|
|
1209
|
+
});
|
|
1210
|
+
this.#fireError(err);
|
|
1211
|
+
this.close(1011, "Internal error during initialization");
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
/**
|
|
1215
|
+
* Handle messages received from the server via the WSContext
|
|
1216
|
+
*/
|
|
1217
|
+
#handleMessage(data) {
|
|
1218
|
+
if (this.readyState !== this.OPEN) {
|
|
1219
|
+
logger3().debug({
|
|
1220
|
+
msg: "message received before socket is OPEN, queuing",
|
|
1221
|
+
readyState: this.readyState,
|
|
1222
|
+
dataType: typeof data,
|
|
1223
|
+
dataLength: typeof data === "string" ? data.length : data instanceof ArrayBuffer ? data.byteLength : data instanceof Uint8Array ? data.byteLength : "unknown"
|
|
1224
|
+
});
|
|
1225
|
+
this.#queuedMessages.push(data);
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
logger3().debug({
|
|
1229
|
+
msg: "fake websocket received message from server",
|
|
1230
|
+
dataType: typeof data,
|
|
1231
|
+
dataLength: typeof data === "string" ? data.length : data instanceof ArrayBuffer ? data.byteLength : data instanceof Uint8Array ? data.byteLength : "unknown"
|
|
1232
|
+
});
|
|
1233
|
+
const event = {
|
|
1234
|
+
type: "message",
|
|
1235
|
+
data,
|
|
1236
|
+
target: this,
|
|
1237
|
+
currentTarget: this
|
|
1238
|
+
};
|
|
1239
|
+
this.#dispatchEvent("message", event);
|
|
1240
|
+
}
|
|
1241
|
+
#handleClose(code, reason) {
|
|
1242
|
+
if (this.readyState === this.CLOSED) return;
|
|
1243
|
+
this.#readyState = this.CLOSED;
|
|
1244
|
+
const event = {
|
|
1245
|
+
type: "close",
|
|
1246
|
+
code,
|
|
1247
|
+
reason,
|
|
1248
|
+
wasClean: code === 1e3,
|
|
1249
|
+
target: this,
|
|
1250
|
+
currentTarget: this
|
|
1251
|
+
};
|
|
1252
|
+
this.#dispatchEvent("close", event);
|
|
1253
|
+
}
|
|
1254
|
+
addEventListener(type, listener) {
|
|
1255
|
+
if (!this.#eventListeners.has(type)) {
|
|
1256
|
+
this.#eventListeners.set(type, []);
|
|
1257
|
+
}
|
|
1258
|
+
this.#eventListeners.get(type).push(listener);
|
|
1259
|
+
this.#flushBufferedEvents(type);
|
|
1260
|
+
}
|
|
1261
|
+
removeEventListener(type, listener) {
|
|
1262
|
+
const listeners = this.#eventListeners.get(type);
|
|
1263
|
+
if (listeners) {
|
|
1264
|
+
const index = listeners.indexOf(listener);
|
|
1265
|
+
if (index !== -1) {
|
|
1266
|
+
listeners.splice(index, 1);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
#dispatchEvent(type, event) {
|
|
1271
|
+
const listeners = this.#eventListeners.get(type);
|
|
1272
|
+
if (listeners && listeners.length > 0) {
|
|
1273
|
+
logger3().debug(
|
|
1274
|
+
`dispatching ${type} event to ${listeners.length} listeners`
|
|
1275
|
+
);
|
|
1276
|
+
for (const listener of listeners) {
|
|
1277
|
+
try {
|
|
1278
|
+
listener(event);
|
|
1279
|
+
} catch (err) {
|
|
1280
|
+
logger3().error({
|
|
1281
|
+
msg: `error in ${type} event listener`,
|
|
1282
|
+
error: err
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
} else {
|
|
1287
|
+
logger3().debug({
|
|
1288
|
+
msg: `no ${type} listeners registered, buffering event`
|
|
1289
|
+
});
|
|
1290
|
+
this.#bufferedEvents.push({ type, event });
|
|
1291
|
+
}
|
|
1292
|
+
switch (type) {
|
|
1293
|
+
case "open":
|
|
1294
|
+
if (this.#onopen) {
|
|
1295
|
+
try {
|
|
1296
|
+
this.#onopen(event);
|
|
1297
|
+
} catch (error) {
|
|
1298
|
+
logger3().error({ msg: "error in onopen handler", error });
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
break;
|
|
1302
|
+
case "close":
|
|
1303
|
+
if (this.#onclose) {
|
|
1304
|
+
try {
|
|
1305
|
+
this.#onclose(event);
|
|
1306
|
+
} catch (error) {
|
|
1307
|
+
logger3().error({ msg: "error in onclose handler", error });
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
break;
|
|
1311
|
+
case "error":
|
|
1312
|
+
if (this.#onerror) {
|
|
1313
|
+
try {
|
|
1314
|
+
this.#onerror(event);
|
|
1315
|
+
} catch (error) {
|
|
1316
|
+
logger3().error({ msg: "error in onerror handler", error });
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
break;
|
|
1320
|
+
case "message":
|
|
1321
|
+
if (this.#onmessage) {
|
|
1322
|
+
try {
|
|
1323
|
+
this.#onmessage(event);
|
|
1324
|
+
} catch (error) {
|
|
1325
|
+
logger3().error({ msg: "error in onmessage handler", error });
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
break;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
dispatchEvent(event) {
|
|
1332
|
+
this.#dispatchEvent(event.type, event);
|
|
1333
|
+
return true;
|
|
1334
|
+
}
|
|
1335
|
+
#flushBufferedEvents(type) {
|
|
1336
|
+
const eventsToFlush = this.#bufferedEvents.filter(
|
|
1337
|
+
(buffered) => buffered.type === type
|
|
1338
|
+
);
|
|
1339
|
+
this.#bufferedEvents = this.#bufferedEvents.filter(
|
|
1340
|
+
(buffered) => buffered.type !== type
|
|
1341
|
+
);
|
|
1342
|
+
for (const { event } of eventsToFlush) {
|
|
1343
|
+
this.#dispatchEvent(type, event);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
#fireOpen() {
|
|
1347
|
+
try {
|
|
1348
|
+
const event = {
|
|
1349
|
+
type: "open",
|
|
1350
|
+
target: this,
|
|
1351
|
+
currentTarget: this
|
|
1352
|
+
};
|
|
1353
|
+
this.#dispatchEvent("open", event);
|
|
1354
|
+
} catch (err) {
|
|
1355
|
+
logger3().error({ msg: "error in open event", error: err });
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
#fireClose(event) {
|
|
1359
|
+
try {
|
|
1360
|
+
this.#dispatchEvent("close", event);
|
|
1361
|
+
} catch (err) {
|
|
1362
|
+
logger3().error({ msg: "error in close event", error: err });
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
#fireError(error) {
|
|
1366
|
+
try {
|
|
1367
|
+
const event = {
|
|
1368
|
+
type: "error",
|
|
1369
|
+
target: this,
|
|
1370
|
+
currentTarget: this,
|
|
1371
|
+
error,
|
|
1372
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1373
|
+
};
|
|
1374
|
+
this.#dispatchEvent("error", event);
|
|
1375
|
+
} catch (err) {
|
|
1376
|
+
logger3().error({ msg: "error in error event", error: err });
|
|
1377
|
+
}
|
|
1378
|
+
logger3().error({ msg: "websocket error", error });
|
|
1379
|
+
}
|
|
1380
|
+
// Event handler properties with getters/setters
|
|
1381
|
+
#onopen = null;
|
|
1382
|
+
#onclose = null;
|
|
1383
|
+
#onerror = null;
|
|
1384
|
+
#onmessage = null;
|
|
1385
|
+
get onopen() {
|
|
1386
|
+
return this.#onopen;
|
|
1387
|
+
}
|
|
1388
|
+
set onopen(handler) {
|
|
1389
|
+
this.#onopen = handler;
|
|
1390
|
+
}
|
|
1391
|
+
get onclose() {
|
|
1392
|
+
return this.#onclose;
|
|
1393
|
+
}
|
|
1394
|
+
set onclose(handler) {
|
|
1395
|
+
this.#onclose = handler;
|
|
1396
|
+
}
|
|
1397
|
+
get onerror() {
|
|
1398
|
+
return this.#onerror;
|
|
1399
|
+
}
|
|
1400
|
+
set onerror(handler) {
|
|
1401
|
+
this.#onerror = handler;
|
|
1402
|
+
}
|
|
1403
|
+
get onmessage() {
|
|
1404
|
+
return this.#onmessage;
|
|
1405
|
+
}
|
|
1406
|
+
set onmessage(handler) {
|
|
1407
|
+
this.#onmessage = handler;
|
|
1408
|
+
}
|
|
1409
|
+
}, _class2);
|
|
1410
|
+
|
|
1411
|
+
// src/drivers/engine/actor-driver.ts
|
|
1412
|
+
var _enginerunner = require('@rivetkit/engine-runner');
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
// src/drivers/engine/kv.ts
|
|
1419
|
+
var KEYS = {
|
|
1420
|
+
PERSIST_DATA: Uint8Array.from([1])
|
|
1421
|
+
};
|
|
1422
|
+
|
|
1423
|
+
// src/drivers/engine/log.ts
|
|
1424
|
+
function logger4() {
|
|
1425
|
+
return _chunk3MBP4WNCcjs.getLogger.call(void 0, "driver-engine");
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
// src/drivers/engine/actor-driver.ts
|
|
1429
|
+
var EngineActorDriver = class {
|
|
1430
|
+
#registryConfig;
|
|
1431
|
+
#runConfig;
|
|
1432
|
+
#managerDriver;
|
|
1433
|
+
#inlineClient;
|
|
1434
|
+
#config;
|
|
1435
|
+
#runner;
|
|
1436
|
+
#actors = /* @__PURE__ */ new Map();
|
|
1437
|
+
#actorRouter;
|
|
1438
|
+
#version = 1;
|
|
1439
|
+
// Version for the runner protocol
|
|
1440
|
+
#runnerStarted = Promise.withResolvers();
|
|
1441
|
+
#runnerStopped = Promise.withResolvers();
|
|
1442
|
+
constructor(registryConfig, runConfig, managerDriver, inlineClient, config2) {
|
|
1443
|
+
this.#registryConfig = registryConfig;
|
|
1444
|
+
this.#runConfig = runConfig;
|
|
1445
|
+
this.#managerDriver = managerDriver;
|
|
1446
|
+
this.#inlineClient = inlineClient;
|
|
1447
|
+
this.#config = config2;
|
|
1448
|
+
this.#actorRouter = createActorRouter(runConfig, this);
|
|
1449
|
+
let hasDisconnected = false;
|
|
1450
|
+
const runnerConfig = {
|
|
1451
|
+
version: this.#version,
|
|
1452
|
+
endpoint: config2.endpoint,
|
|
1453
|
+
token: config2.token,
|
|
1454
|
+
pegboardEndpoint: config2.pegboardEndpoint,
|
|
1455
|
+
namespace: config2.namespace,
|
|
1456
|
+
totalSlots: config2.totalSlots,
|
|
1457
|
+
runnerName: config2.runnerName,
|
|
1458
|
+
runnerKey: config2.runnerKey,
|
|
1459
|
+
metadata: {
|
|
1460
|
+
inspectorToken: this.#runConfig.inspector.token()
|
|
1461
|
+
},
|
|
1462
|
+
prepopulateActorNames: Object.fromEntries(
|
|
1463
|
+
Object.keys(this.#registryConfig.use).map((name) => [
|
|
1464
|
+
name,
|
|
1465
|
+
{ metadata: {} }
|
|
1466
|
+
])
|
|
1467
|
+
),
|
|
1468
|
+
onConnected: () => {
|
|
1469
|
+
if (hasDisconnected) {
|
|
1470
|
+
logger4().info({
|
|
1471
|
+
msg: "runner reconnected",
|
|
1472
|
+
namespace: this.#config.namespace,
|
|
1473
|
+
runnerName: this.#config.runnerName
|
|
1474
|
+
});
|
|
1475
|
+
} else {
|
|
1476
|
+
logger4().debug({
|
|
1477
|
+
msg: "runner connected",
|
|
1478
|
+
namespace: this.#config.namespace,
|
|
1479
|
+
runnerName: this.#config.runnerName
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
this.#runnerStarted.resolve(void 0);
|
|
1483
|
+
},
|
|
1484
|
+
onDisconnected: () => {
|
|
1485
|
+
logger4().warn({
|
|
1486
|
+
msg: "runner disconnected",
|
|
1487
|
+
namespace: this.#config.namespace,
|
|
1488
|
+
runnerName: this.#config.runnerName
|
|
1489
|
+
});
|
|
1490
|
+
hasDisconnected = true;
|
|
1491
|
+
},
|
|
1492
|
+
onShutdown: () => {
|
|
1493
|
+
this.#runnerStopped.resolve(void 0);
|
|
1494
|
+
},
|
|
1495
|
+
fetch: this.#runnerFetch.bind(this),
|
|
1496
|
+
websocket: this.#runnerWebSocket.bind(this),
|
|
1497
|
+
onActorStart: this.#runnerOnActorStart.bind(this),
|
|
1498
|
+
onActorStop: this.#runnerOnActorStop.bind(this),
|
|
1499
|
+
logger: _chunk3MBP4WNCcjs.getLogger.call(void 0, "engine-runner")
|
|
1500
|
+
};
|
|
1501
|
+
this.#runner = new (0, _enginerunner.Runner)(runnerConfig);
|
|
1502
|
+
this.#runner.start();
|
|
1503
|
+
logger4().debug({
|
|
1504
|
+
msg: "engine runner started",
|
|
1505
|
+
endpoint: config2.endpoint,
|
|
1506
|
+
namespace: config2.namespace,
|
|
1507
|
+
runnerName: config2.runnerName
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
async #loadActorHandler(actorId) {
|
|
1511
|
+
const handler = this.#actors.get(actorId);
|
|
1512
|
+
if (!handler) throw new Error(`Actor handler does not exist ${actorId}`);
|
|
1513
|
+
if (handler.actorStartPromise) await handler.actorStartPromise.promise;
|
|
1514
|
+
if (!handler.actor) throw new Error("Actor should be loaded");
|
|
1515
|
+
return handler;
|
|
1516
|
+
}
|
|
1517
|
+
async loadActor(actorId) {
|
|
1518
|
+
const handler = await this.#loadActorHandler(actorId);
|
|
1519
|
+
if (!handler.actor) throw new Error(`Actor ${actorId} failed to load`);
|
|
1520
|
+
return handler.actor;
|
|
1521
|
+
}
|
|
1522
|
+
getContext(actorId) {
|
|
1523
|
+
return {};
|
|
1524
|
+
}
|
|
1525
|
+
async readPersistedData(actorId) {
|
|
1526
|
+
const handler = this.#actors.get(actorId);
|
|
1527
|
+
if (!handler) throw new Error(`Actor ${actorId} not loaded`);
|
|
1528
|
+
if (handler.persistedData) return handler.persistedData;
|
|
1529
|
+
const [value] = await this.#runner.kvGet(actorId, [KEYS.PERSIST_DATA]);
|
|
1530
|
+
if (value !== null) {
|
|
1531
|
+
handler.persistedData = value;
|
|
1532
|
+
return value;
|
|
1533
|
+
} else {
|
|
1534
|
+
return void 0;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
async writePersistedData(actorId, data) {
|
|
1538
|
+
const handler = this.#actors.get(actorId);
|
|
1539
|
+
if (!handler) throw new Error(`Actor ${actorId} not loaded`);
|
|
1540
|
+
handler.persistedData = data;
|
|
1541
|
+
await this.#runner.kvPut(actorId, [[KEYS.PERSIST_DATA, data]]);
|
|
1542
|
+
}
|
|
1543
|
+
async setAlarm(actor2, timestamp) {
|
|
1544
|
+
}
|
|
1545
|
+
async getDatabase(_actorId) {
|
|
1546
|
+
return void 0;
|
|
1547
|
+
}
|
|
1548
|
+
// Runner lifecycle callbacks
|
|
1549
|
+
async #runnerOnActorStart(actorId, generation, config2) {
|
|
1550
|
+
var _a;
|
|
1551
|
+
logger4().debug({
|
|
1552
|
+
msg: "runner actor starting",
|
|
1553
|
+
actorId,
|
|
1554
|
+
name: config2.name,
|
|
1555
|
+
key: config2.key,
|
|
1556
|
+
generation
|
|
1557
|
+
});
|
|
1558
|
+
let input;
|
|
1559
|
+
if (config2.input) {
|
|
1560
|
+
input = cbor3.decode(config2.input);
|
|
1561
|
+
}
|
|
1562
|
+
let handler = this.#actors.get(actorId);
|
|
1563
|
+
if (!handler) {
|
|
1564
|
+
handler = {
|
|
1565
|
+
actorStartPromise: _chunk6EUWRXLTcjs.promiseWithResolvers.call(void 0, ),
|
|
1566
|
+
persistedData: _chunkDFS77KAAcjs.serializeEmptyPersistData.call(void 0, input)
|
|
1567
|
+
};
|
|
1568
|
+
this.#actors.set(actorId, handler);
|
|
1569
|
+
}
|
|
1570
|
+
const name = config2.name;
|
|
1571
|
+
_invariant2.default.call(void 0, config2.key, "actor should have a key");
|
|
1572
|
+
const key = _chunk5ZOHIKWGcjs.deserializeActorKey.call(void 0, config2.key);
|
|
1573
|
+
const definition = _chunk5ZOHIKWGcjs.lookupInRegistry.call(void 0,
|
|
1574
|
+
this.#registryConfig,
|
|
1575
|
+
config2.name
|
|
1576
|
+
// TODO: Remove cast
|
|
1577
|
+
);
|
|
1578
|
+
handler.actor = definition.instantiate();
|
|
1579
|
+
await handler.actor.start(
|
|
1580
|
+
this,
|
|
1581
|
+
this.#inlineClient,
|
|
1582
|
+
actorId,
|
|
1583
|
+
name,
|
|
1584
|
+
key,
|
|
1585
|
+
"unknown"
|
|
1586
|
+
// TODO: Add regions
|
|
1587
|
+
);
|
|
1588
|
+
(_a = handler.actorStartPromise) == null ? void 0 : _a.resolve();
|
|
1589
|
+
handler.actorStartPromise = void 0;
|
|
1590
|
+
logger4().debug({ msg: "runner actor started", actorId, name, key });
|
|
1591
|
+
}
|
|
1592
|
+
async #runnerOnActorStop(actorId, generation) {
|
|
1593
|
+
logger4().debug({ msg: "runner actor stopping", actorId, generation });
|
|
1594
|
+
const handler = this.#actors.get(actorId);
|
|
1595
|
+
if (handler == null ? void 0 : handler.actor) {
|
|
1596
|
+
await handler.actor._stop();
|
|
1597
|
+
this.#actors.delete(actorId);
|
|
1598
|
+
}
|
|
1599
|
+
logger4().debug({ msg: "runner actor stopped", actorId });
|
|
1600
|
+
}
|
|
1601
|
+
async #runnerFetch(actorId, request) {
|
|
1602
|
+
logger4().debug({
|
|
1603
|
+
msg: "runner fetch",
|
|
1604
|
+
actorId,
|
|
1605
|
+
url: request.url,
|
|
1606
|
+
method: request.method
|
|
1607
|
+
});
|
|
1608
|
+
return await this.#actorRouter.fetch(request, { actorId });
|
|
1609
|
+
}
|
|
1610
|
+
async #runnerWebSocket(actorId, websocketRaw, request) {
|
|
1611
|
+
const websocket = websocketRaw;
|
|
1612
|
+
logger4().debug({ msg: "runner websocket", actorId, url: request.url });
|
|
1613
|
+
const url = new URL(request.url);
|
|
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(_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING)) {
|
|
1623
|
+
encodingRaw = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING.length);
|
|
1624
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS)) {
|
|
1625
|
+
connParamsRaw = decodeURIComponent(
|
|
1626
|
+
protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS.length)
|
|
1627
|
+
);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
const encoding = _chunkSAZCNSVYcjs.EncodingSchema.parse(encodingRaw);
|
|
1632
|
+
const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
|
|
1633
|
+
let wsHandlerPromise;
|
|
1634
|
+
if (url.pathname === _chunkSAZCNSVYcjs.PATH_CONNECT_WEBSOCKET) {
|
|
1635
|
+
wsHandlerPromise = handleWebSocketConnect(
|
|
1636
|
+
request,
|
|
1637
|
+
this.#runConfig,
|
|
1638
|
+
this,
|
|
1639
|
+
actorId,
|
|
1640
|
+
encoding,
|
|
1641
|
+
connParams,
|
|
1642
|
+
// Extract connId and connToken from protocols if needed
|
|
1643
|
+
void 0,
|
|
1644
|
+
void 0
|
|
1645
|
+
);
|
|
1646
|
+
} else if (url.pathname.startsWith(_chunkSAZCNSVYcjs.PATH_RAW_WEBSOCKET_PREFIX)) {
|
|
1647
|
+
wsHandlerPromise = handleRawWebSocketHandler(
|
|
1648
|
+
request,
|
|
1649
|
+
url.pathname + url.search,
|
|
1650
|
+
this,
|
|
1651
|
+
actorId
|
|
1652
|
+
);
|
|
1653
|
+
} else {
|
|
1654
|
+
throw new Error(`Unreachable path: ${url.pathname}`);
|
|
1655
|
+
}
|
|
1656
|
+
const wsContext = new (0, _ws2.WSContext)(websocket);
|
|
1657
|
+
wsHandlerPromise.catch((err) => {
|
|
1658
|
+
logger4().error({ msg: "building websocket handlers errored", err });
|
|
1659
|
+
wsContext.close(1011, `${err}`);
|
|
1660
|
+
});
|
|
1661
|
+
if (websocket.readyState === 1) {
|
|
1662
|
+
wsHandlerPromise.then((x) => {
|
|
1663
|
+
var _a;
|
|
1664
|
+
return (_a = x.onOpen) == null ? void 0 : _a.call(x, new Event("open"), wsContext);
|
|
1665
|
+
});
|
|
1666
|
+
} else {
|
|
1667
|
+
websocket.addEventListener("open", (event) => {
|
|
1668
|
+
wsHandlerPromise.then((x) => {
|
|
1669
|
+
var _a;
|
|
1670
|
+
return (_a = x.onOpen) == null ? void 0 : _a.call(x, event, wsContext);
|
|
1671
|
+
});
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
websocket.addEventListener("message", (event) => {
|
|
1675
|
+
wsHandlerPromise.then((x) => {
|
|
1676
|
+
var _a;
|
|
1677
|
+
return (_a = x.onMessage) == null ? void 0 : _a.call(x, event, wsContext);
|
|
1678
|
+
});
|
|
1679
|
+
});
|
|
1680
|
+
websocket.addEventListener("close", (event) => {
|
|
1681
|
+
wsHandlerPromise.then((x) => {
|
|
1682
|
+
var _a;
|
|
1683
|
+
return (_a = x.onClose) == null ? void 0 : _a.call(x, event, wsContext);
|
|
1684
|
+
});
|
|
1685
|
+
});
|
|
1686
|
+
websocket.addEventListener("error", (event) => {
|
|
1687
|
+
wsHandlerPromise.then((x) => {
|
|
1688
|
+
var _a;
|
|
1689
|
+
return (_a = x.onError) == null ? void 0 : _a.call(x, event, wsContext);
|
|
1690
|
+
});
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
async sleep(actorId) {
|
|
1694
|
+
this.#runner.sleepActor(actorId);
|
|
1695
|
+
}
|
|
1696
|
+
async shutdown(immediate) {
|
|
1697
|
+
logger4().info({ msg: "stopping engine actor driver" });
|
|
1698
|
+
await this.#runner.shutdown(immediate);
|
|
1699
|
+
}
|
|
1700
|
+
async serverlessHandleStart(c) {
|
|
1701
|
+
await this.#runnerStarted.promise;
|
|
1702
|
+
return _streaming.streamSSE.call(void 0, c, async (stream) => {
|
|
1703
|
+
const runnerId = this.#runner.runnerId;
|
|
1704
|
+
_invariant2.default.call(void 0, runnerId, "runnerId not set");
|
|
1705
|
+
stream.writeSSE({ data: runnerId });
|
|
1706
|
+
return this.#runnerStopped.promise;
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1709
|
+
};
|
|
1710
|
+
|
|
1711
|
+
// src/drivers/engine/config.ts
|
|
1712
|
+
|
|
1713
|
+
var ConfigSchema = _zod.z.object({
|
|
1714
|
+
app: _zod.z.custom().optional(),
|
|
1715
|
+
endpoint: _zod.z.string().default(
|
|
1716
|
+
() => _nullishCoalesce(_chunk6EUWRXLTcjs.getEnvUniversal.call(void 0, "RIVET_ENGINE"), () => ( "http://localhost:6420"))
|
|
1717
|
+
),
|
|
1718
|
+
token: _zod.z.string().optional().transform((val) => _nullishCoalesce(val, () => ( _chunk6EUWRXLTcjs.getEnvUniversal.call(void 0, "RIVET_TOKEN")))),
|
|
1719
|
+
pegboardEndpoint: _zod.z.string().optional(),
|
|
1720
|
+
namespace: _zod.z.string().default(() => _nullishCoalesce(_chunk6EUWRXLTcjs.getEnvUniversal.call(void 0, "RIVET_NAMESPACE"), () => ( "default"))),
|
|
1721
|
+
runnerName: _zod.z.string().default(() => _nullishCoalesce(_chunk6EUWRXLTcjs.getEnvUniversal.call(void 0, "RIVET_RUNNER"), () => ( "rivetkit"))),
|
|
1722
|
+
// TODO: Automatically attempt to determine key by common env vars (e.g. k8s pod name)
|
|
1723
|
+
runnerKey: _zod.z.string().default(
|
|
1724
|
+
() => _nullishCoalesce(_chunk6EUWRXLTcjs.getEnvUniversal.call(void 0, "RIVET_RUNNER_KEY"), () => ( crypto.randomUUID()))
|
|
1725
|
+
),
|
|
1726
|
+
totalSlots: _zod.z.number().default(1e5)
|
|
1727
|
+
}).default({});
|
|
1728
|
+
|
|
1729
|
+
// src/drivers/engine/mod.ts
|
|
1730
|
+
function createEngineDriver(inputConfig) {
|
|
1731
|
+
const config2 = ConfigSchema.parse(inputConfig);
|
|
1732
|
+
return {
|
|
1733
|
+
name: "engine",
|
|
1734
|
+
manager: (_registryConfig, runConfig) => {
|
|
1735
|
+
return new (0, _chunk5ZOHIKWGcjs.RemoteManagerDriver)(runConfig);
|
|
1736
|
+
},
|
|
1737
|
+
actor: (registryConfig, runConfig, managerDriver, inlineClient) => {
|
|
1738
|
+
return new EngineActorDriver(
|
|
1739
|
+
registryConfig,
|
|
1740
|
+
runConfig,
|
|
1741
|
+
managerDriver,
|
|
1742
|
+
inlineClient,
|
|
1743
|
+
config2
|
|
1744
|
+
);
|
|
1745
|
+
}
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
// src/drivers/file-system/actor.ts
|
|
1750
|
+
var FileSystemActorDriver = class {
|
|
1751
|
+
#registryConfig;
|
|
1752
|
+
#runConfig;
|
|
1753
|
+
#managerDriver;
|
|
1754
|
+
#inlineClient;
|
|
1755
|
+
#state;
|
|
1756
|
+
constructor(registryConfig, runConfig, managerDriver, inlineClient, state) {
|
|
1757
|
+
this.#registryConfig = registryConfig;
|
|
1758
|
+
this.#runConfig = runConfig;
|
|
1759
|
+
this.#managerDriver = managerDriver;
|
|
1760
|
+
this.#inlineClient = inlineClient;
|
|
1761
|
+
this.#state = state;
|
|
1762
|
+
}
|
|
1763
|
+
async loadActor(actorId) {
|
|
1764
|
+
return this.#state.startActor(
|
|
1765
|
+
this.#registryConfig,
|
|
1766
|
+
this.#runConfig,
|
|
1767
|
+
this.#inlineClient,
|
|
1768
|
+
this,
|
|
1769
|
+
actorId
|
|
1770
|
+
);
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Get the current storage directory path
|
|
1774
|
+
*/
|
|
1775
|
+
get storagePath() {
|
|
1776
|
+
return this.#state.storagePath;
|
|
1777
|
+
}
|
|
1778
|
+
getContext(_actorId) {
|
|
1779
|
+
return {};
|
|
1780
|
+
}
|
|
1781
|
+
async readPersistedData(actorId) {
|
|
1782
|
+
return new Uint8Array(
|
|
1783
|
+
(await this.#state.loadActorStateOrError(actorId)).persistedData
|
|
1784
|
+
);
|
|
1785
|
+
}
|
|
1786
|
+
async writePersistedData(actorId, data) {
|
|
1787
|
+
const state = await this.#state.loadActorStateOrError(actorId);
|
|
1788
|
+
await this.#state.writeActor(actorId, {
|
|
1789
|
+
...state,
|
|
1790
|
+
persistedData: _chunk6EUWRXLTcjs.bufferToArrayBuffer.call(void 0, data)
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
async setAlarm(actor2, timestamp) {
|
|
1794
|
+
await this.#state.setActorAlarm(actor2.id, timestamp);
|
|
1795
|
+
}
|
|
1796
|
+
getDatabase(actorId) {
|
|
1797
|
+
return this.#state.createDatabase(actorId);
|
|
1798
|
+
}
|
|
1799
|
+
sleep(actorId) {
|
|
1800
|
+
return this.#state.sleepActor(actorId);
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
|
|
1804
|
+
// src/drivers/file-system/global-state.ts
|
|
1805
|
+
var _crypto = require('crypto'); var crypto3 = _interopRequireWildcard(_crypto); var crypto2 = _interopRequireWildcard(_crypto);
|
|
1806
|
+
var _fs = require('fs'); var fsSync2 = _interopRequireWildcard(_fs); var fsSync = _interopRequireWildcard(_fs);
|
|
1807
|
+
var _promises = require('fs/promises'); var fs2 = _interopRequireWildcard(_promises); var fs = _interopRequireWildcard(_promises);
|
|
1808
|
+
var _path = require('path'); var path2 = _interopRequireWildcard(_path); var path = _interopRequireWildcard(_path);
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
// dist/schemas/file-system-driver/v1.ts
|
|
1812
|
+
var _lib = require('@bare-ts/lib'); var bare = _interopRequireWildcard(_lib);
|
|
1813
|
+
var config = /* @__PURE__ */ bare.Config({});
|
|
1814
|
+
function read0(bc) {
|
|
1815
|
+
const len = bare.readUintSafe(bc);
|
|
1816
|
+
if (len === 0) {
|
|
1817
|
+
return [];
|
|
1818
|
+
}
|
|
1819
|
+
const result = [bare.readString(bc)];
|
|
1820
|
+
for (let i = 1; i < len; i++) {
|
|
1821
|
+
result[i] = bare.readString(bc);
|
|
1822
|
+
}
|
|
1823
|
+
return result;
|
|
1824
|
+
}
|
|
1825
|
+
function write0(bc, x) {
|
|
1826
|
+
bare.writeUintSafe(bc, x.length);
|
|
1827
|
+
for (let i = 0; i < x.length; i++) {
|
|
1828
|
+
bare.writeString(bc, x[i]);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
function readActorState(bc) {
|
|
1832
|
+
return {
|
|
1833
|
+
actorId: bare.readString(bc),
|
|
1834
|
+
name: bare.readString(bc),
|
|
1835
|
+
key: read0(bc),
|
|
1836
|
+
persistedData: bare.readData(bc),
|
|
1837
|
+
createdAt: bare.readU64(bc)
|
|
1838
|
+
};
|
|
1839
|
+
}
|
|
1840
|
+
function writeActorState(bc, x) {
|
|
1841
|
+
bare.writeString(bc, x.actorId);
|
|
1842
|
+
bare.writeString(bc, x.name);
|
|
1843
|
+
write0(bc, x.key);
|
|
1844
|
+
bare.writeData(bc, x.persistedData);
|
|
1845
|
+
bare.writeU64(bc, x.createdAt);
|
|
1846
|
+
}
|
|
1847
|
+
function encodeActorState(x) {
|
|
1848
|
+
const bc = new bare.ByteCursor(
|
|
1849
|
+
new Uint8Array(config.initialBufferLength),
|
|
1850
|
+
config
|
|
1851
|
+
);
|
|
1852
|
+
writeActorState(bc, x);
|
|
1853
|
+
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
1854
|
+
}
|
|
1855
|
+
function decodeActorState(bytes) {
|
|
1856
|
+
const bc = new bare.ByteCursor(bytes, config);
|
|
1857
|
+
const result = readActorState(bc);
|
|
1858
|
+
if (bc.offset < bc.view.byteLength) {
|
|
1859
|
+
throw new bare.BareError(bc.offset, "remaining bytes");
|
|
1860
|
+
}
|
|
1861
|
+
return result;
|
|
1862
|
+
}
|
|
1863
|
+
function readActorAlarm(bc) {
|
|
1864
|
+
return {
|
|
1865
|
+
actorId: bare.readString(bc),
|
|
1866
|
+
timestamp: bare.readUint(bc)
|
|
1867
|
+
};
|
|
1868
|
+
}
|
|
1869
|
+
function writeActorAlarm(bc, x) {
|
|
1870
|
+
bare.writeString(bc, x.actorId);
|
|
1871
|
+
bare.writeUint(bc, x.timestamp);
|
|
1872
|
+
}
|
|
1873
|
+
function encodeActorAlarm(x) {
|
|
1874
|
+
const bc = new bare.ByteCursor(
|
|
1875
|
+
new Uint8Array(config.initialBufferLength),
|
|
1876
|
+
config
|
|
1877
|
+
);
|
|
1878
|
+
writeActorAlarm(bc, x);
|
|
1879
|
+
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
1880
|
+
}
|
|
1881
|
+
function decodeActorAlarm(bytes) {
|
|
1882
|
+
const bc = new bare.ByteCursor(bytes, config);
|
|
1883
|
+
const result = readActorAlarm(bc);
|
|
1884
|
+
if (bc.offset < bc.view.byteLength) {
|
|
1885
|
+
throw new bare.BareError(bc.offset, "remaining bytes");
|
|
1886
|
+
}
|
|
1887
|
+
return result;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
// src/schemas/file-system-driver/versioned.ts
|
|
1891
|
+
var CURRENT_VERSION = 1;
|
|
1892
|
+
var migrations = /* @__PURE__ */ new Map();
|
|
1893
|
+
var ACTOR_STATE_VERSIONED = _chunkDFS77KAAcjs.createVersionedDataHandler.call(void 0, {
|
|
1894
|
+
currentVersion: CURRENT_VERSION,
|
|
1895
|
+
migrations,
|
|
1896
|
+
serializeVersion: (data) => encodeActorState(data),
|
|
1897
|
+
deserializeVersion: (bytes) => decodeActorState(bytes)
|
|
1898
|
+
});
|
|
1899
|
+
var ACTOR_ALARM_VERSIONED = _chunkDFS77KAAcjs.createVersionedDataHandler.call(void 0, {
|
|
1900
|
+
currentVersion: CURRENT_VERSION,
|
|
1901
|
+
migrations,
|
|
1902
|
+
serializeVersion: (data) => encodeActorAlarm(data),
|
|
1903
|
+
deserializeVersion: (bytes) => decodeActorAlarm(bytes)
|
|
1904
|
+
});
|
|
1905
|
+
|
|
1906
|
+
// src/drivers/file-system/log.ts
|
|
1907
|
+
function logger5() {
|
|
1908
|
+
return _chunk3MBP4WNCcjs.getLogger.call(void 0, "driver-fs");
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
// src/drivers/file-system/utils.ts
|
|
1912
|
+
|
|
1913
|
+
|
|
1914
|
+
|
|
1915
|
+
var _os = require('os'); var os = _interopRequireWildcard(_os);
|
|
1916
|
+
|
|
1917
|
+
function generateActorId(name, key) {
|
|
1918
|
+
const jsonString = JSON.stringify([name, key]);
|
|
1919
|
+
const hash = crypto2.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
|
|
1920
|
+
return hash;
|
|
1921
|
+
}
|
|
1922
|
+
function createHashForPath(dirPath) {
|
|
1923
|
+
const normalizedPath = path.normalize(dirPath);
|
|
1924
|
+
const lastComponent = path.basename(normalizedPath);
|
|
1925
|
+
const hash = crypto2.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
|
|
1926
|
+
return `${lastComponent}-${hash}`;
|
|
1927
|
+
}
|
|
1928
|
+
function getStoragePath(customPath) {
|
|
1929
|
+
const dataPath = getDataPath("rivetkit");
|
|
1930
|
+
const pathToHash = customPath || process.cwd();
|
|
1931
|
+
const dirHash = createHashForPath(pathToHash);
|
|
1932
|
+
return path.join(dataPath, dirHash);
|
|
1933
|
+
}
|
|
1934
|
+
async function pathExists(path3) {
|
|
1935
|
+
try {
|
|
1936
|
+
await fs.access(path3);
|
|
1937
|
+
return true;
|
|
1938
|
+
} catch (e) {
|
|
1939
|
+
return false;
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
async function ensureDirectoryExists(directoryPath) {
|
|
1943
|
+
if (!await pathExists(directoryPath)) {
|
|
1944
|
+
await fs.mkdir(directoryPath, { recursive: true });
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
function ensureDirectoryExistsSync(directoryPath) {
|
|
1948
|
+
if (!fsSync.existsSync(directoryPath)) {
|
|
1949
|
+
fsSync.mkdirSync(directoryPath, { recursive: true });
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
function getDataPath(appName) {
|
|
1953
|
+
const platform = process.platform;
|
|
1954
|
+
const homeDir = os.homedir();
|
|
1955
|
+
switch (platform) {
|
|
1956
|
+
case "win32":
|
|
1957
|
+
return path.join(
|
|
1958
|
+
process.env.APPDATA || path.join(homeDir, "AppData", "Roaming"),
|
|
1959
|
+
appName
|
|
1960
|
+
);
|
|
1961
|
+
case "darwin":
|
|
1962
|
+
return path.join(homeDir, "Library", "Application Support", appName);
|
|
1963
|
+
default:
|
|
1964
|
+
return path.join(
|
|
1965
|
+
process.env.XDG_DATA_HOME || path.join(homeDir, ".local", "share"),
|
|
1966
|
+
appName
|
|
1967
|
+
);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// src/drivers/file-system/global-state.ts
|
|
1972
|
+
var FileSystemGlobalState = class {
|
|
1973
|
+
#storagePath;
|
|
1974
|
+
#stateDir;
|
|
1975
|
+
#dbsDir;
|
|
1976
|
+
#alarmsDir;
|
|
1977
|
+
#persist;
|
|
1978
|
+
#actors = /* @__PURE__ */ new Map();
|
|
1979
|
+
#actorCountOnStartup = 0;
|
|
1980
|
+
#runnerParams;
|
|
1981
|
+
get persist() {
|
|
1982
|
+
return this.#persist;
|
|
1983
|
+
}
|
|
1984
|
+
get storagePath() {
|
|
1985
|
+
return this.#storagePath;
|
|
1986
|
+
}
|
|
1987
|
+
get actorCountOnStartup() {
|
|
1988
|
+
return this.#actorCountOnStartup;
|
|
1989
|
+
}
|
|
1990
|
+
constructor(persist = true, customPath) {
|
|
1991
|
+
this.#persist = persist;
|
|
1992
|
+
this.#storagePath = persist ? getStoragePath(customPath) : "/tmp";
|
|
1993
|
+
this.#stateDir = path2.join(this.#storagePath, "state");
|
|
1994
|
+
this.#dbsDir = path2.join(this.#storagePath, "databases");
|
|
1995
|
+
this.#alarmsDir = path2.join(this.#storagePath, "alarms");
|
|
1996
|
+
if (this.#persist) {
|
|
1997
|
+
ensureDirectoryExistsSync(this.#stateDir);
|
|
1998
|
+
ensureDirectoryExistsSync(this.#dbsDir);
|
|
1999
|
+
ensureDirectoryExistsSync(this.#alarmsDir);
|
|
2000
|
+
try {
|
|
2001
|
+
const actorIds = fsSync2.readdirSync(this.#stateDir);
|
|
2002
|
+
this.#actorCountOnStartup = actorIds.length;
|
|
2003
|
+
} catch (error) {
|
|
2004
|
+
logger5().error({ msg: "failed to count actors", error });
|
|
2005
|
+
}
|
|
2006
|
+
logger5().debug({
|
|
2007
|
+
msg: "file system driver ready",
|
|
2008
|
+
dir: this.#storagePath,
|
|
2009
|
+
actorCount: this.#actorCountOnStartup
|
|
2010
|
+
});
|
|
2011
|
+
try {
|
|
2012
|
+
this.#cleanupTempFilesSync();
|
|
2013
|
+
} catch (err) {
|
|
2014
|
+
logger5().error({ msg: "failed to cleanup temp files", error: err });
|
|
2015
|
+
}
|
|
2016
|
+
} else {
|
|
2017
|
+
logger5().debug({ msg: "memory driver ready" });
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
getActorStatePath(actorId) {
|
|
2021
|
+
return path2.join(this.#stateDir, actorId);
|
|
2022
|
+
}
|
|
2023
|
+
getActorDbPath(actorId) {
|
|
2024
|
+
return path2.join(this.#dbsDir, `${actorId}.db`);
|
|
2025
|
+
}
|
|
2026
|
+
getActorAlarmPath(actorId) {
|
|
2027
|
+
return path2.join(this.#alarmsDir, actorId);
|
|
2028
|
+
}
|
|
2029
|
+
async *getActorsIterator(params) {
|
|
2030
|
+
let actorIds = Array.from(this.#actors.keys()).sort();
|
|
2031
|
+
if (fsSync2.existsSync(this.#stateDir)) {
|
|
2032
|
+
actorIds = fsSync2.readdirSync(this.#stateDir).filter((id) => !id.includes(".tmp")).sort();
|
|
2033
|
+
}
|
|
2034
|
+
const startIndex = params.cursor ? actorIds.indexOf(params.cursor) + 1 : 0;
|
|
2035
|
+
for (let i = startIndex; i < actorIds.length; i++) {
|
|
2036
|
+
const actorId = actorIds[i];
|
|
2037
|
+
if (!actorId) {
|
|
2038
|
+
continue;
|
|
2039
|
+
}
|
|
2040
|
+
try {
|
|
2041
|
+
const state = await this.loadActorStateOrError(actorId);
|
|
2042
|
+
yield state;
|
|
2043
|
+
} catch (error) {
|
|
2044
|
+
logger5().error({ msg: "failed to load actor state", actorId, error });
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
/**
|
|
2049
|
+
* Ensures an entry exists for this actor.
|
|
2050
|
+
*
|
|
2051
|
+
* Used for #createActor and #loadActor.
|
|
2052
|
+
*/
|
|
2053
|
+
#upsertEntry(actorId) {
|
|
2054
|
+
let entry = this.#actors.get(actorId);
|
|
2055
|
+
if (entry) {
|
|
2056
|
+
return entry;
|
|
2057
|
+
}
|
|
2058
|
+
entry = {
|
|
2059
|
+
id: actorId,
|
|
2060
|
+
removed: false
|
|
2061
|
+
};
|
|
2062
|
+
this.#actors.set(actorId, entry);
|
|
2063
|
+
return entry;
|
|
2064
|
+
}
|
|
2065
|
+
/**
|
|
2066
|
+
* Creates a new actor and writes to file system.
|
|
2067
|
+
*/
|
|
2068
|
+
async createActor(actorId, name, key, input) {
|
|
2069
|
+
if (this.#actors.has(actorId)) {
|
|
2070
|
+
throw new (0, _chunk5QGQK44Lcjs.ActorAlreadyExists)(name, key);
|
|
2071
|
+
}
|
|
2072
|
+
const entry = this.#upsertEntry(actorId);
|
|
2073
|
+
entry.state = {
|
|
2074
|
+
actorId,
|
|
2075
|
+
name,
|
|
2076
|
+
key,
|
|
2077
|
+
createdAt: BigInt(Date.now()),
|
|
2078
|
+
persistedData: _chunk6EUWRXLTcjs.bufferToArrayBuffer.call(void 0, _chunkDFS77KAAcjs.serializeEmptyPersistData.call(void 0, input))
|
|
2079
|
+
};
|
|
2080
|
+
await this.writeActor(actorId, entry.state);
|
|
2081
|
+
return entry;
|
|
2082
|
+
}
|
|
2083
|
+
/**
|
|
2084
|
+
* Loads the actor from disk or returns the existing actor entry. This will return an entry even if the actor does not actually exist.
|
|
2085
|
+
*/
|
|
2086
|
+
async loadActor(actorId) {
|
|
2087
|
+
const entry = this.#upsertEntry(actorId);
|
|
2088
|
+
if (entry.state) {
|
|
2089
|
+
return entry;
|
|
2090
|
+
}
|
|
2091
|
+
if (!this.#persist) {
|
|
2092
|
+
return entry;
|
|
2093
|
+
}
|
|
2094
|
+
if (entry.loadPromise) {
|
|
2095
|
+
await entry.loadPromise;
|
|
2096
|
+
return entry;
|
|
2097
|
+
}
|
|
2098
|
+
entry.loadPromise = this.loadActorState(entry);
|
|
2099
|
+
return entry.loadPromise;
|
|
2100
|
+
}
|
|
2101
|
+
async loadActorState(entry) {
|
|
2102
|
+
const stateFilePath = this.getActorStatePath(entry.id);
|
|
2103
|
+
try {
|
|
2104
|
+
const stateData = await fs2.readFile(stateFilePath);
|
|
2105
|
+
entry.state = ACTOR_STATE_VERSIONED.deserializeWithEmbeddedVersion(
|
|
2106
|
+
new Uint8Array(stateData)
|
|
2107
|
+
);
|
|
2108
|
+
return entry;
|
|
2109
|
+
} catch (innerError) {
|
|
2110
|
+
if (innerError.code === "ENOENT") {
|
|
2111
|
+
entry.loadPromise = void 0;
|
|
2112
|
+
return entry;
|
|
2113
|
+
}
|
|
2114
|
+
const error = new Error(`Failed to load actor state: ${innerError}`);
|
|
2115
|
+
throw error;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
async loadOrCreateActor(actorId, name, key, input) {
|
|
2119
|
+
const entry = await this.loadActor(actorId);
|
|
2120
|
+
if (!entry.state) {
|
|
2121
|
+
entry.state = {
|
|
2122
|
+
actorId,
|
|
2123
|
+
name,
|
|
2124
|
+
key,
|
|
2125
|
+
createdAt: BigInt(Date.now()),
|
|
2126
|
+
persistedData: _chunk6EUWRXLTcjs.bufferToArrayBuffer.call(void 0, _chunkDFS77KAAcjs.serializeEmptyPersistData.call(void 0, input))
|
|
2127
|
+
};
|
|
2128
|
+
await this.writeActor(actorId, entry.state);
|
|
2129
|
+
}
|
|
2130
|
+
return entry;
|
|
2131
|
+
}
|
|
2132
|
+
async sleepActor(actorId) {
|
|
2133
|
+
var _a;
|
|
2134
|
+
_invariant2.default.call(void 0,
|
|
2135
|
+
this.#persist,
|
|
2136
|
+
"cannot sleep actor with memory driver, must use file system driver"
|
|
2137
|
+
);
|
|
2138
|
+
const actor2 = this.#actors.get(actorId);
|
|
2139
|
+
_invariant2.default.call(void 0, actor2, `tried to sleep ${actorId}, does not exist`);
|
|
2140
|
+
if (actor2.loadPromise) await actor2.loadPromise.catch();
|
|
2141
|
+
if ((_a = actor2.startPromise) == null ? void 0 : _a.promise) await actor2.startPromise.promise.catch();
|
|
2142
|
+
actor2.removed = true;
|
|
2143
|
+
_invariant2.default.call(void 0, actor2.actor, "actor should be loaded");
|
|
2144
|
+
await actor2.actor._stop();
|
|
2145
|
+
this.#actors.delete(actorId);
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Save actor state to disk.
|
|
2149
|
+
*/
|
|
2150
|
+
async writeActor(actorId, state) {
|
|
2151
|
+
if (!this.#persist) {
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
const entry = this.#actors.get(actorId);
|
|
2155
|
+
_invariant2.default.call(void 0, entry, "actor entry does not exist");
|
|
2156
|
+
await this.#performWrite(actorId, state);
|
|
2157
|
+
}
|
|
2158
|
+
async setActorAlarm(actorId, timestamp) {
|
|
2159
|
+
const entry = this.#actors.get(actorId);
|
|
2160
|
+
_invariant2.default.call(void 0, entry, "actor entry does not exist");
|
|
2161
|
+
if (this.#persist) {
|
|
2162
|
+
const alarmPath = this.getActorAlarmPath(actorId);
|
|
2163
|
+
const tempPath = `${alarmPath}.tmp.${crypto3.randomUUID()}`;
|
|
2164
|
+
try {
|
|
2165
|
+
await ensureDirectoryExists(path2.dirname(alarmPath));
|
|
2166
|
+
const alarmData = {
|
|
2167
|
+
actorId,
|
|
2168
|
+
timestamp: BigInt(timestamp)
|
|
2169
|
+
};
|
|
2170
|
+
const data = ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(alarmData);
|
|
2171
|
+
await fs2.writeFile(tempPath, data);
|
|
2172
|
+
await fs2.rename(tempPath, alarmPath);
|
|
2173
|
+
} catch (error) {
|
|
2174
|
+
try {
|
|
2175
|
+
await fs2.unlink(tempPath);
|
|
2176
|
+
} catch (e2) {
|
|
2177
|
+
}
|
|
2178
|
+
logger5().error({ msg: "failed to write alarm", actorId, error });
|
|
2179
|
+
throw new Error(`Failed to write alarm: ${error}`);
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
this.#scheduleAlarmTimeout(actorId, timestamp);
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Perform the actual write operation with atomic writes
|
|
2186
|
+
*/
|
|
2187
|
+
async #performWrite(actorId, state) {
|
|
2188
|
+
const dataPath = this.getActorStatePath(actorId);
|
|
2189
|
+
const tempPath = `${dataPath}.tmp.${crypto3.randomUUID()}`;
|
|
2190
|
+
try {
|
|
2191
|
+
await ensureDirectoryExists(path2.dirname(dataPath));
|
|
2192
|
+
const bareState = {
|
|
2193
|
+
actorId: state.actorId,
|
|
2194
|
+
name: state.name,
|
|
2195
|
+
key: state.key,
|
|
2196
|
+
createdAt: state.createdAt,
|
|
2197
|
+
persistedData: state.persistedData
|
|
2198
|
+
};
|
|
2199
|
+
const serializedState = ACTOR_STATE_VERSIONED.serializeWithEmbeddedVersion(bareState);
|
|
2200
|
+
await fs2.writeFile(tempPath, serializedState);
|
|
2201
|
+
await fs2.rename(tempPath, dataPath);
|
|
2202
|
+
} catch (error) {
|
|
2203
|
+
try {
|
|
2204
|
+
await fs2.unlink(tempPath);
|
|
2205
|
+
} catch (e3) {
|
|
2206
|
+
}
|
|
2207
|
+
logger5().error({ msg: "failed to save actor state", actorId, error });
|
|
2208
|
+
throw new Error(`Failed to save actor state: ${error}`);
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Call this method after the actor driver has been initiated.
|
|
2213
|
+
*
|
|
2214
|
+
* This will trigger all initial alarms from the file system.
|
|
2215
|
+
*
|
|
2216
|
+
* This needs to be sync since DriverConfig.actor is sync
|
|
2217
|
+
*/
|
|
2218
|
+
onRunnerStart(registryConfig, runConfig, inlineClient, actorDriver) {
|
|
2219
|
+
if (this.#runnerParams) {
|
|
2220
|
+
return;
|
|
2221
|
+
}
|
|
2222
|
+
this.#runnerParams = {
|
|
2223
|
+
registryConfig,
|
|
2224
|
+
runConfig,
|
|
2225
|
+
inlineClient,
|
|
2226
|
+
actorDriver
|
|
2227
|
+
};
|
|
2228
|
+
try {
|
|
2229
|
+
this.#loadAlarmsSync();
|
|
2230
|
+
} catch (err) {
|
|
2231
|
+
logger5().error({ msg: "failed to load alarms on startup", error: err });
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
async startActor(registryConfig, runConfig, inlineClient, actorDriver, actorId) {
|
|
2235
|
+
var _a;
|
|
2236
|
+
const entry = await this.loadActor(actorId);
|
|
2237
|
+
if (!entry.state) {
|
|
2238
|
+
throw new Error(
|
|
2239
|
+
`Actor does not exist and cannot be started: "${actorId}"`
|
|
2240
|
+
);
|
|
2241
|
+
}
|
|
2242
|
+
if (entry.startPromise) {
|
|
2243
|
+
await entry.startPromise.promise;
|
|
2244
|
+
_invariant2.default.call(void 0, entry.actor, "actor should have loaded");
|
|
2245
|
+
return entry.actor;
|
|
2246
|
+
}
|
|
2247
|
+
if (entry.actor) {
|
|
2248
|
+
return entry.actor;
|
|
2249
|
+
}
|
|
2250
|
+
entry.startPromise = _chunk6EUWRXLTcjs.promiseWithResolvers.call(void 0, );
|
|
2251
|
+
try {
|
|
2252
|
+
const definition = _chunk5ZOHIKWGcjs.lookupInRegistry.call(void 0, registryConfig, entry.state.name);
|
|
2253
|
+
entry.actor = definition.instantiate();
|
|
2254
|
+
await entry.actor.start(
|
|
2255
|
+
actorDriver,
|
|
2256
|
+
inlineClient,
|
|
2257
|
+
actorId,
|
|
2258
|
+
entry.state.name,
|
|
2259
|
+
entry.state.key,
|
|
2260
|
+
"unknown"
|
|
2261
|
+
);
|
|
2262
|
+
entry.startPromise.resolve();
|
|
2263
|
+
entry.startPromise = void 0;
|
|
2264
|
+
return entry.actor;
|
|
2265
|
+
} catch (innerError) {
|
|
2266
|
+
const error = new Error(
|
|
2267
|
+
`Failed to start actor ${actorId}: ${innerError}`,
|
|
2268
|
+
{ cause: innerError }
|
|
2269
|
+
);
|
|
2270
|
+
(_a = entry.startPromise) == null ? void 0 : _a.reject(error);
|
|
2271
|
+
entry.startPromise = void 0;
|
|
2272
|
+
throw error;
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
async loadActorStateOrError(actorId) {
|
|
2276
|
+
const state = (await this.loadActor(actorId)).state;
|
|
2277
|
+
if (!state) throw new Error(`Actor does not exist: ${actorId}`);
|
|
2278
|
+
return state;
|
|
2279
|
+
}
|
|
2280
|
+
getActorOrError(actorId) {
|
|
2281
|
+
const entry = this.#actors.get(actorId);
|
|
2282
|
+
if (!entry) throw new Error(`No entry for actor: ${actorId}`);
|
|
2283
|
+
return entry;
|
|
2284
|
+
}
|
|
2285
|
+
async createDatabase(actorId) {
|
|
2286
|
+
return this.getActorDbPath(actorId);
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Load all persisted alarms from disk and schedule their timers.
|
|
2290
|
+
*/
|
|
2291
|
+
#loadAlarmsSync() {
|
|
2292
|
+
try {
|
|
2293
|
+
const files = fsSync2.existsSync(this.#alarmsDir) ? fsSync2.readdirSync(this.#alarmsDir) : [];
|
|
2294
|
+
for (const file of files) {
|
|
2295
|
+
if (file.includes(".tmp.")) continue;
|
|
2296
|
+
const fullPath = path2.join(this.#alarmsDir, file);
|
|
2297
|
+
try {
|
|
2298
|
+
const buf = fsSync2.readFileSync(fullPath);
|
|
2299
|
+
const alarmData = ACTOR_ALARM_VERSIONED.deserializeWithEmbeddedVersion(
|
|
2300
|
+
new Uint8Array(buf)
|
|
2301
|
+
);
|
|
2302
|
+
const timestamp = Number(alarmData.timestamp);
|
|
2303
|
+
if (Number.isFinite(timestamp)) {
|
|
2304
|
+
this.#scheduleAlarmTimeout(alarmData.actorId, timestamp);
|
|
2305
|
+
} else {
|
|
2306
|
+
logger5().debug({ msg: "invalid alarm file contents", file });
|
|
2307
|
+
}
|
|
2308
|
+
} catch (err) {
|
|
2309
|
+
logger5().error({
|
|
2310
|
+
msg: "failed to read alarm file",
|
|
2311
|
+
file,
|
|
2312
|
+
error: _chunk6EUWRXLTcjs.stringifyError.call(void 0, err)
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
} catch (err) {
|
|
2317
|
+
logger5().error({ msg: "failed to list alarms directory", error: err });
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
/**
|
|
2321
|
+
* Schedule an alarm timer for an actor without writing to disk.
|
|
2322
|
+
*/
|
|
2323
|
+
#scheduleAlarmTimeout(actorId, timestamp) {
|
|
2324
|
+
var _a;
|
|
2325
|
+
const entry = this.#upsertEntry(actorId);
|
|
2326
|
+
if (entry.alarmTimestamp !== void 0 && timestamp >= entry.alarmTimestamp) {
|
|
2327
|
+
logger5().debug({
|
|
2328
|
+
msg: "skipping alarm schedule (later than existing)",
|
|
2329
|
+
actorId,
|
|
2330
|
+
timestamp,
|
|
2331
|
+
current: entry.alarmTimestamp
|
|
2332
|
+
});
|
|
2333
|
+
return;
|
|
2334
|
+
}
|
|
2335
|
+
logger5().debug({ msg: "scheduling alarm", actorId, timestamp });
|
|
2336
|
+
(_a = entry.alarmTimeout) == null ? void 0 : _a.abort();
|
|
2337
|
+
entry.alarmTimestamp = timestamp;
|
|
2338
|
+
const delay = Math.max(0, timestamp - Date.now());
|
|
2339
|
+
entry.alarmTimeout = _chunk6EUWRXLTcjs.setLongTimeout.call(void 0, async () => {
|
|
2340
|
+
entry.alarmTimestamp = void 0;
|
|
2341
|
+
if (this.#persist) {
|
|
2342
|
+
try {
|
|
2343
|
+
await fs2.unlink(this.getActorAlarmPath(actorId));
|
|
2344
|
+
} catch (err) {
|
|
2345
|
+
if ((err == null ? void 0 : err.code) !== "ENOENT") {
|
|
2346
|
+
logger5().debug({
|
|
2347
|
+
msg: "failed to remove alarm file",
|
|
2348
|
+
actorId,
|
|
2349
|
+
error: _chunk6EUWRXLTcjs.stringifyError.call(void 0, err)
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
try {
|
|
2355
|
+
logger5().debug({ msg: "triggering alarm", actorId, timestamp });
|
|
2356
|
+
const loaded = await this.loadActor(actorId);
|
|
2357
|
+
if (!loaded.state) throw new Error(`Actor does not exist: ${actorId}`);
|
|
2358
|
+
const runnerParams = this.#runnerParams;
|
|
2359
|
+
_invariant2.default.call(void 0, runnerParams, "missing runner params");
|
|
2360
|
+
if (!loaded.actor) {
|
|
2361
|
+
await this.startActor(
|
|
2362
|
+
runnerParams.registryConfig,
|
|
2363
|
+
runnerParams.runConfig,
|
|
2364
|
+
runnerParams.inlineClient,
|
|
2365
|
+
runnerParams.actorDriver,
|
|
2366
|
+
actorId
|
|
2367
|
+
);
|
|
2368
|
+
}
|
|
2369
|
+
_invariant2.default.call(void 0, loaded.actor, "actor should be loaded after wake");
|
|
2370
|
+
await loaded.actor._onAlarm();
|
|
2371
|
+
} catch (err) {
|
|
2372
|
+
logger5().error({
|
|
2373
|
+
msg: "failed to handle alarm",
|
|
2374
|
+
actorId,
|
|
2375
|
+
error: _chunk6EUWRXLTcjs.stringifyError.call(void 0, err)
|
|
2376
|
+
});
|
|
2377
|
+
}
|
|
2378
|
+
}, delay);
|
|
2379
|
+
}
|
|
2380
|
+
getOrCreateInspectorAccessToken() {
|
|
2381
|
+
const tokenPath = path2.join(this.#storagePath, "inspector-token");
|
|
2382
|
+
if (fsSync2.existsSync(tokenPath)) {
|
|
2383
|
+
return fsSync2.readFileSync(tokenPath, "utf-8");
|
|
2384
|
+
}
|
|
2385
|
+
const newToken = _chunkSAZCNSVYcjs.generateRandomString.call(void 0, );
|
|
2386
|
+
fsSync2.writeFileSync(tokenPath, newToken);
|
|
2387
|
+
return newToken;
|
|
2388
|
+
}
|
|
2389
|
+
/**
|
|
2390
|
+
* Cleanup stale temp files on startup (synchronous)
|
|
2391
|
+
*/
|
|
2392
|
+
#cleanupTempFilesSync() {
|
|
2393
|
+
try {
|
|
2394
|
+
const files = fsSync2.readdirSync(this.#stateDir);
|
|
2395
|
+
const tempFiles = files.filter((f) => f.includes(".tmp."));
|
|
2396
|
+
const oneHourAgo = Date.now() - 36e5;
|
|
2397
|
+
for (const tempFile of tempFiles) {
|
|
2398
|
+
try {
|
|
2399
|
+
const fullPath = path2.join(this.#stateDir, tempFile);
|
|
2400
|
+
const stat = fsSync2.statSync(fullPath);
|
|
2401
|
+
if (stat.mtimeMs < oneHourAgo) {
|
|
2402
|
+
fsSync2.unlinkSync(fullPath);
|
|
2403
|
+
logger5().info({
|
|
2404
|
+
msg: "cleaned up stale temp file",
|
|
2405
|
+
file: tempFile
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2408
|
+
} catch (err) {
|
|
2409
|
+
logger5().debug({
|
|
2410
|
+
msg: "failed to cleanup temp file",
|
|
2411
|
+
file: tempFile,
|
|
2412
|
+
error: err
|
|
2413
|
+
});
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
} catch (err) {
|
|
2417
|
+
logger5().error({
|
|
2418
|
+
msg: "failed to read actors directory for cleanup",
|
|
2419
|
+
error: err
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
};
|
|
2424
|
+
|
|
2425
|
+
// src/drivers/file-system/manager.ts
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
// src/inspector/manager.ts
|
|
2429
|
+
var _standardvalidator = require('@hono/standard-validator');
|
|
2430
|
+
|
|
2431
|
+
function createManagerInspectorRouter() {
|
|
2432
|
+
return new (0, _hono.Hono)().get("/ping", (c) => {
|
|
2433
|
+
return c.json({ message: "pong" }, 200);
|
|
2434
|
+
}).get("/actors", async (c) => {
|
|
2435
|
+
const limit = Number.parseInt(_nullishCoalesce(c.req.query("limit"), () => ( ""))) || void 0;
|
|
2436
|
+
const cursor = c.req.query("cursor") || void 0;
|
|
2437
|
+
if (!limit || limit && limit <= 0) {
|
|
2438
|
+
return c.json("Invalid limit", 400);
|
|
2439
|
+
}
|
|
2440
|
+
try {
|
|
2441
|
+
const actors = await c.var.inspector.accessors.getAllActors({
|
|
2442
|
+
limit,
|
|
2443
|
+
cursor
|
|
2444
|
+
});
|
|
2445
|
+
return c.json(actors, 200);
|
|
2446
|
+
} catch (error) {
|
|
2447
|
+
_chunkG4ABMAQYcjs.inspectorLogger.call(void 0, ).error({ msg: "Failed to fetch actors", error });
|
|
2448
|
+
return c.json("Failed to fetch actors", 500);
|
|
2449
|
+
}
|
|
2450
|
+
}).post("/actors", _standardvalidator.sValidator.call(void 0, "json", _chunkB3TLRM4Qcjs.CreateActorSchema), async (c) => {
|
|
2451
|
+
const actor2 = await c.var.inspector.accessors.createActor(
|
|
2452
|
+
c.req.valid("json")
|
|
2453
|
+
);
|
|
2454
|
+
return c.json(actor2, 201);
|
|
2455
|
+
}).get("/builds", async (c) => {
|
|
2456
|
+
const builds = await c.var.inspector.accessors.getBuilds();
|
|
2457
|
+
return c.json(builds, 200);
|
|
2458
|
+
}).get("/actor/:id", async (c) => {
|
|
2459
|
+
const id = c.req.param("id");
|
|
2460
|
+
const actor2 = await c.var.inspector.accessors.getActorById(id);
|
|
2461
|
+
if (!actor2) {
|
|
2462
|
+
return c.json({ error: "Actor not found" }, 404);
|
|
2463
|
+
}
|
|
2464
|
+
return c.json(actor2, 200);
|
|
2465
|
+
}).get("/bootstrap", async (c) => {
|
|
2466
|
+
const actors = await c.var.inspector.accessors.getAllActors({
|
|
2467
|
+
limit: 10
|
|
2468
|
+
});
|
|
2469
|
+
return c.json({ actors }, 200);
|
|
2470
|
+
});
|
|
2471
|
+
}
|
|
2472
|
+
var ManagerInspector = class {
|
|
2473
|
+
|
|
2474
|
+
constructor(accessors) {
|
|
2475
|
+
this.accessors = accessors();
|
|
2476
|
+
_chunkG4ABMAQYcjs.inspectorLogger.call(void 0, ).debug({ msg: "Manager Inspector enabled and ready" });
|
|
2477
|
+
}
|
|
2478
|
+
};
|
|
2479
|
+
|
|
2480
|
+
// src/drivers/file-system/manager.ts
|
|
2481
|
+
var FileSystemManagerDriver = class {
|
|
2482
|
+
#registryConfig;
|
|
2483
|
+
#runConfig;
|
|
2484
|
+
#state;
|
|
2485
|
+
#driverConfig;
|
|
2486
|
+
#actorDriver;
|
|
2487
|
+
#actorRouter;
|
|
2488
|
+
|
|
2489
|
+
constructor(registryConfig, runConfig, state, driverConfig) {
|
|
2490
|
+
this.#registryConfig = registryConfig;
|
|
2491
|
+
this.#runConfig = runConfig;
|
|
2492
|
+
this.#state = state;
|
|
2493
|
+
this.#driverConfig = driverConfig;
|
|
2494
|
+
if (runConfig.inspector.enabled) {
|
|
2495
|
+
let transformActor2 = function(actorState) {
|
|
2496
|
+
return {
|
|
2497
|
+
id: actorState.actorId,
|
|
2498
|
+
name: actorState.name,
|
|
2499
|
+
key: actorState.key,
|
|
2500
|
+
startedAt,
|
|
2501
|
+
createdAt: new Date(Number(actorState.createdAt)).toISOString(),
|
|
2502
|
+
features: [
|
|
2503
|
+
"state" /* State */,
|
|
2504
|
+
"connections" /* Connections */,
|
|
2505
|
+
"console" /* Console */,
|
|
2506
|
+
"events-monitoring" /* EventsMonitoring */,
|
|
2507
|
+
"database" /* Database */
|
|
2508
|
+
]
|
|
2509
|
+
};
|
|
2510
|
+
};
|
|
2511
|
+
var transformActor = transformActor2;
|
|
2512
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2513
|
+
this.inspector = new ManagerInspector(() => {
|
|
2514
|
+
return {
|
|
2515
|
+
getAllActors: async ({ cursor, limit }) => {
|
|
2516
|
+
const itr = this.#state.getActorsIterator({ cursor });
|
|
2517
|
+
const actors = [];
|
|
2518
|
+
for await (const actor2 of itr) {
|
|
2519
|
+
actors.push(transformActor2(actor2));
|
|
2520
|
+
if (limit && actors.length >= limit) {
|
|
2521
|
+
break;
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
return actors;
|
|
2525
|
+
},
|
|
2526
|
+
getActorById: async (id) => {
|
|
2527
|
+
try {
|
|
2528
|
+
const result = await this.#state.loadActorStateOrError(id);
|
|
2529
|
+
return transformActor2(result);
|
|
2530
|
+
} catch (e4) {
|
|
2531
|
+
return null;
|
|
2532
|
+
}
|
|
2533
|
+
},
|
|
2534
|
+
getBuilds: async () => {
|
|
2535
|
+
return Object.keys(this.#registryConfig.use).map((name) => ({
|
|
2536
|
+
name
|
|
2537
|
+
}));
|
|
2538
|
+
},
|
|
2539
|
+
createActor: async (input) => {
|
|
2540
|
+
const { actorId } = await this.createActor(input);
|
|
2541
|
+
try {
|
|
2542
|
+
const result = await this.#state.loadActorStateOrError(actorId);
|
|
2543
|
+
return transformActor2(result);
|
|
2544
|
+
} catch (e5) {
|
|
2545
|
+
return null;
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
};
|
|
2549
|
+
});
|
|
2550
|
+
}
|
|
2551
|
+
const inlineClient = _chunk5ZOHIKWGcjs.createClientWithDriver.call(void 0, this);
|
|
2552
|
+
this.#actorDriver = this.#driverConfig.actor(
|
|
2553
|
+
registryConfig,
|
|
2554
|
+
runConfig,
|
|
2555
|
+
this,
|
|
2556
|
+
inlineClient
|
|
2557
|
+
);
|
|
2558
|
+
this.#actorRouter = createActorRouter(this.#runConfig, this.#actorDriver);
|
|
2559
|
+
}
|
|
2560
|
+
async sendRequest(actorId, actorRequest) {
|
|
2561
|
+
return await this.#actorRouter.fetch(actorRequest, {
|
|
2562
|
+
actorId
|
|
2563
|
+
});
|
|
2564
|
+
}
|
|
2565
|
+
async openWebSocket(path3, actorId, encoding, params, connId, connToken) {
|
|
2566
|
+
const pathOnly = path3.split("?")[0];
|
|
2567
|
+
const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
|
|
2568
|
+
if (normalizedPath === _chunkSAZCNSVYcjs.PATH_CONNECT_WEBSOCKET) {
|
|
2569
|
+
const wsHandler = await handleWebSocketConnect(
|
|
2570
|
+
void 0,
|
|
2571
|
+
this.#runConfig,
|
|
2572
|
+
this.#actorDriver,
|
|
2573
|
+
actorId,
|
|
2574
|
+
encoding,
|
|
2575
|
+
params,
|
|
2576
|
+
connId,
|
|
2577
|
+
connToken
|
|
2578
|
+
);
|
|
2579
|
+
return new InlineWebSocketAdapter2(wsHandler);
|
|
2580
|
+
} else if (normalizedPath.startsWith(_chunkSAZCNSVYcjs.PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
|
|
2581
|
+
const wsHandler = await handleRawWebSocketHandler(
|
|
2582
|
+
void 0,
|
|
2583
|
+
path3,
|
|
2584
|
+
this.#actorDriver,
|
|
2585
|
+
actorId
|
|
2586
|
+
);
|
|
2587
|
+
return new InlineWebSocketAdapter2(wsHandler);
|
|
2588
|
+
} else {
|
|
2589
|
+
throw new Error(`Unreachable path: ${path3}`);
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
async proxyRequest(c, actorRequest, actorId) {
|
|
2593
|
+
return await this.#actorRouter.fetch(actorRequest, {
|
|
2594
|
+
actorId
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
async proxyWebSocket(c, path3, actorId, encoding, connParams, connId, connToken) {
|
|
2598
|
+
var _a, _b;
|
|
2599
|
+
const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
|
|
2600
|
+
_invariant2.default.call(void 0, upgradeWebSocket, "missing getUpgradeWebSocket");
|
|
2601
|
+
const pathOnly = path3.split("?")[0];
|
|
2602
|
+
const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
|
|
2603
|
+
if (normalizedPath === _chunkSAZCNSVYcjs.PATH_CONNECT_WEBSOCKET) {
|
|
2604
|
+
const wsHandler = await handleWebSocketConnect(
|
|
2605
|
+
c.req.raw,
|
|
2606
|
+
this.#runConfig,
|
|
2607
|
+
this.#actorDriver,
|
|
2608
|
+
actorId,
|
|
2609
|
+
encoding,
|
|
2610
|
+
connParams,
|
|
2611
|
+
connId,
|
|
2612
|
+
connToken
|
|
2613
|
+
);
|
|
2614
|
+
return upgradeWebSocket(() => wsHandler)(c, _chunk6EUWRXLTcjs.noopNext.call(void 0, ));
|
|
2615
|
+
} else if (normalizedPath.startsWith(_chunkSAZCNSVYcjs.PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
|
|
2616
|
+
const wsHandler = await handleRawWebSocketHandler(
|
|
2617
|
+
c.req.raw,
|
|
2618
|
+
path3,
|
|
2619
|
+
this.#actorDriver,
|
|
2620
|
+
actorId
|
|
2621
|
+
);
|
|
2622
|
+
return upgradeWebSocket(() => wsHandler)(c, _chunk6EUWRXLTcjs.noopNext.call(void 0, ));
|
|
2623
|
+
} else {
|
|
2624
|
+
throw new Error(`Unreachable path: ${path3}`);
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
async getForId({ actorId }) {
|
|
2628
|
+
const actor2 = await this.#state.loadActor(actorId);
|
|
2629
|
+
if (!actor2.state) {
|
|
2630
|
+
return void 0;
|
|
2631
|
+
}
|
|
2632
|
+
try {
|
|
2633
|
+
return {
|
|
2634
|
+
actorId,
|
|
2635
|
+
name: actor2.state.name,
|
|
2636
|
+
key: actor2.state.key
|
|
2637
|
+
};
|
|
2638
|
+
} catch (error) {
|
|
2639
|
+
logger5().error({ msg: "failed to read actor state", actorId, error });
|
|
2640
|
+
return void 0;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
async getWithKey({
|
|
2644
|
+
name,
|
|
2645
|
+
key
|
|
2646
|
+
}) {
|
|
2647
|
+
const actorId = generateActorId(name, key);
|
|
2648
|
+
const actor2 = await this.#state.loadActor(actorId);
|
|
2649
|
+
if (actor2.state) {
|
|
2650
|
+
return {
|
|
2651
|
+
actorId,
|
|
2652
|
+
name,
|
|
2653
|
+
key
|
|
2654
|
+
};
|
|
2655
|
+
}
|
|
2656
|
+
return void 0;
|
|
2657
|
+
}
|
|
2658
|
+
async getOrCreateWithKey(input) {
|
|
2659
|
+
const actorId = generateActorId(input.name, input.key);
|
|
2660
|
+
const actorEntry = await this.#state.loadOrCreateActor(
|
|
2661
|
+
actorId,
|
|
2662
|
+
input.name,
|
|
2663
|
+
input.key,
|
|
2664
|
+
input.input
|
|
2665
|
+
);
|
|
2666
|
+
_invariant2.default.call(void 0, actorEntry.state, "must have state");
|
|
2667
|
+
return {
|
|
2668
|
+
actorId: actorEntry.state.actorId,
|
|
2669
|
+
name: actorEntry.state.name,
|
|
2670
|
+
key: actorEntry.state.key
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
async createActor({ name, key, input }) {
|
|
2674
|
+
const actorId = generateActorId(name, key);
|
|
2675
|
+
await this.#state.createActor(actorId, name, key, input);
|
|
2676
|
+
return {
|
|
2677
|
+
actorId,
|
|
2678
|
+
name,
|
|
2679
|
+
key
|
|
2680
|
+
};
|
|
2681
|
+
}
|
|
2682
|
+
displayInformation() {
|
|
2683
|
+
return {
|
|
2684
|
+
name: this.#state.persist ? "File System" : "Memory",
|
|
2685
|
+
properties: {
|
|
2686
|
+
...this.#state.persist ? { Data: this.#state.storagePath } : {},
|
|
2687
|
+
Instances: this.#state.actorCountOnStartup.toString()
|
|
2688
|
+
}
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2691
|
+
extraStartupLog() {
|
|
2692
|
+
return {
|
|
2693
|
+
instances: this.#state.actorCountOnStartup,
|
|
2694
|
+
data: this.#state.storagePath
|
|
2695
|
+
};
|
|
2696
|
+
}
|
|
2697
|
+
getOrCreateInspectorAccessToken() {
|
|
2698
|
+
return this.#state.getOrCreateInspectorAccessToken();
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
// src/drivers/file-system/mod.ts
|
|
2703
|
+
function createFileSystemOrMemoryDriver(persist = true, customPath) {
|
|
2704
|
+
const state = new FileSystemGlobalState(persist, customPath);
|
|
2705
|
+
const driverConfig = {
|
|
2706
|
+
name: persist ? "file-system" : "memory",
|
|
2707
|
+
manager: (registryConfig, runConfig) => new FileSystemManagerDriver(
|
|
2708
|
+
registryConfig,
|
|
2709
|
+
runConfig,
|
|
2710
|
+
state,
|
|
2711
|
+
driverConfig
|
|
2712
|
+
),
|
|
2713
|
+
actor: (registryConfig, runConfig, managerDriver, inlineClient) => {
|
|
2714
|
+
const actorDriver = new FileSystemActorDriver(
|
|
2715
|
+
registryConfig,
|
|
2716
|
+
runConfig,
|
|
2717
|
+
managerDriver,
|
|
2718
|
+
inlineClient,
|
|
2719
|
+
state
|
|
2720
|
+
);
|
|
2721
|
+
state.onRunnerStart(registryConfig, runConfig, inlineClient, actorDriver);
|
|
2722
|
+
return actorDriver;
|
|
2723
|
+
}
|
|
2724
|
+
};
|
|
2725
|
+
return driverConfig;
|
|
2726
|
+
}
|
|
2727
|
+
function createFileSystemDriver(opts) {
|
|
2728
|
+
return createFileSystemOrMemoryDriver(true, opts == null ? void 0 : opts.path);
|
|
2729
|
+
}
|
|
2730
|
+
function createMemoryDriver() {
|
|
2731
|
+
return createFileSystemOrMemoryDriver(false);
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
// src/drivers/default.ts
|
|
2735
|
+
function chooseDefaultDriver(runConfig) {
|
|
2736
|
+
if (runConfig.endpoint && runConfig.driver) {
|
|
2737
|
+
throw new (0, _chunk5QGQK44Lcjs.UserError)(
|
|
2738
|
+
"Cannot specify both 'engine' and 'driver' in configuration"
|
|
2739
|
+
);
|
|
2740
|
+
}
|
|
2741
|
+
if (runConfig.driver) {
|
|
2742
|
+
return runConfig.driver;
|
|
2743
|
+
}
|
|
2744
|
+
if (runConfig.endpoint) {
|
|
2745
|
+
_chunkSAZCNSVYcjs.loggerWithoutContext.call(void 0, ).debug({
|
|
2746
|
+
msg: "using rivet engine driver",
|
|
2747
|
+
endpoint: runConfig.endpoint
|
|
2748
|
+
});
|
|
2749
|
+
return createEngineDriver({
|
|
2750
|
+
endpoint: runConfig.endpoint,
|
|
2751
|
+
token: runConfig.token
|
|
2752
|
+
});
|
|
2753
|
+
}
|
|
2754
|
+
_chunkSAZCNSVYcjs.loggerWithoutContext.call(void 0, ).debug({ msg: "using default file system driver" });
|
|
2755
|
+
return createFileSystemOrMemoryDriver(true);
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
// src/manager/router.ts
|
|
2759
|
+
var _zodopenapi = require('@hono/zod-openapi');
|
|
2760
|
+
|
|
2761
|
+
|
|
2762
|
+
|
|
2763
|
+
|
|
2764
|
+
|
|
2765
|
+
var _factory = require('hono/factory');
|
|
2766
|
+
|
|
2767
|
+
|
|
2768
|
+
|
|
2769
|
+
// src/manager-api/actors.ts
|
|
2770
|
+
|
|
2771
|
+
|
|
2772
|
+
// src/manager-api/common.ts
|
|
2773
|
+
|
|
2774
|
+
var RivetIdSchema = _zod.z.string();
|
|
2775
|
+
|
|
2776
|
+
// src/manager-api/actors.ts
|
|
2777
|
+
var ActorSchema = _zod.z.object({
|
|
2778
|
+
actor_id: RivetIdSchema,
|
|
2779
|
+
name: _zod.z.string(),
|
|
2780
|
+
key: _zod.z.string(),
|
|
2781
|
+
namespace_id: RivetIdSchema,
|
|
2782
|
+
runner_name_selector: _zod.z.string(),
|
|
2783
|
+
create_ts: _zod.z.number(),
|
|
2784
|
+
connectable_ts: _zod.z.number().nullable().optional(),
|
|
2785
|
+
destroy_ts: _zod.z.number().nullable().optional(),
|
|
2786
|
+
sleep_ts: _zod.z.number().nullable().optional(),
|
|
2787
|
+
start_ts: _zod.z.number().nullable().optional()
|
|
2788
|
+
});
|
|
2789
|
+
var ActorsListResponseSchema = _zod.z.object({
|
|
2790
|
+
actors: _zod.z.array(ActorSchema)
|
|
2791
|
+
});
|
|
2792
|
+
var ActorsCreateRequestSchema = _zod.z.object({
|
|
2793
|
+
name: _zod.z.string(),
|
|
2794
|
+
runner_name_selector: _zod.z.string(),
|
|
2795
|
+
crash_policy: _zod.z.string(),
|
|
2796
|
+
key: _zod.z.string().nullable().optional(),
|
|
2797
|
+
input: _zod.z.string().nullable().optional()
|
|
2798
|
+
});
|
|
2799
|
+
var ActorsCreateResponseSchema = _zod.z.object({
|
|
2800
|
+
actor: ActorSchema
|
|
2801
|
+
});
|
|
2802
|
+
var ActorsGetOrCreateRequestSchema = _zod.z.object({
|
|
2803
|
+
name: _zod.z.string(),
|
|
2804
|
+
key: _zod.z.string(),
|
|
2805
|
+
runner_name_selector: _zod.z.string(),
|
|
2806
|
+
crash_policy: _zod.z.string(),
|
|
2807
|
+
input: _zod.z.string().nullable().optional()
|
|
2808
|
+
});
|
|
2809
|
+
var ActorsGetOrCreateResponseSchema = _zod.z.object({
|
|
2810
|
+
actor: ActorSchema,
|
|
2811
|
+
created: _zod.z.boolean()
|
|
2812
|
+
});
|
|
2813
|
+
var ActorsDeleteResponseSchema = _zod.z.object({});
|
|
2814
|
+
|
|
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);
|
|
2824
|
+
}
|
|
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 (0, _chunk5QGQK44Lcjs.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(_chunkSAZCNSVYcjs.WS_PROTOCOL_TARGET)) {
|
|
2842
|
+
target = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_TARGET.length);
|
|
2843
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_ACTOR)) {
|
|
2844
|
+
actorId = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_ACTOR.length);
|
|
2845
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING)) {
|
|
2846
|
+
encodingRaw = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING.length);
|
|
2847
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS)) {
|
|
2848
|
+
connParamsRaw = decodeURIComponent(
|
|
2849
|
+
protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS.length)
|
|
2850
|
+
);
|
|
2851
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_ID)) {
|
|
2852
|
+
connIdRaw = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_ID.length);
|
|
2853
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_TOKEN)) {
|
|
2854
|
+
connTokenRaw = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_TOKEN.length);
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
if (target !== "actor") {
|
|
2859
|
+
return c.text("WebSocket upgrade requires target.actor protocol", 400);
|
|
2860
|
+
}
|
|
2861
|
+
if (!actorId) {
|
|
2862
|
+
throw new (0, _chunk5QGQK44Lcjs.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(_chunkSAZCNSVYcjs.HEADER_RIVET_TARGET);
|
|
2886
|
+
const actorId = c.req.header(_chunkSAZCNSVYcjs.HEADER_RIVET_ACTOR);
|
|
2887
|
+
if (target !== "actor") {
|
|
2888
|
+
return next();
|
|
2889
|
+
}
|
|
2890
|
+
if (!actorId) {
|
|
2891
|
+
throw new (0, _chunk5QGQK44Lcjs.MissingActorHeader)();
|
|
2892
|
+
}
|
|
2893
|
+
logger().debug({
|
|
2894
|
+
msg: "proxying request to actor",
|
|
2895
|
+
actorId,
|
|
2896
|
+
path: c.req.path,
|
|
2897
|
+
method: c.req.method
|
|
2898
|
+
});
|
|
2899
|
+
const proxyHeaders = new Headers(c.req.raw.headers);
|
|
2900
|
+
proxyHeaders.delete(_chunkSAZCNSVYcjs.HEADER_RIVET_TARGET);
|
|
2901
|
+
proxyHeaders.delete(_chunkSAZCNSVYcjs.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
|
|
2909
|
+
});
|
|
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
|
+
} = _chunk6EUWRXLTcjs.promiseWithResolvers.call(void 0, );
|
|
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 (0, _zodopenapi.OpenAPIHono)({ strict: false }).basePath(
|
|
3105
|
+
runConfig.basePath
|
|
3106
|
+
);
|
|
3107
|
+
router.use("*", loggerMiddleware(logger()));
|
|
3108
|
+
const cors2 = runConfig.cors ? _cors.cors.call(void 0, runConfig.cors) : _factory.createMiddleware.call(void 0, (_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
|
+
_invariant2.default.call(void 0,
|
|
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 = _zodopenapi.createRoute.call(void 0, {
|
|
3146
|
+
middleware: [cors2],
|
|
3147
|
+
method: "get",
|
|
3148
|
+
path: "/actors",
|
|
3149
|
+
request: {
|
|
3150
|
+
query: _zod.z.object({
|
|
3151
|
+
name: _zod.z.string(),
|
|
3152
|
+
actor_ids: _zod.z.string().optional(),
|
|
3153
|
+
key: _zod.z.string().optional()
|
|
3154
|
+
})
|
|
3155
|
+
},
|
|
3156
|
+
responses: buildOpenApiResponses(ActorsListResponseSchema)
|
|
3157
|
+
});
|
|
3158
|
+
router.openapi(route, async (c) => {
|
|
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
|
+
}
|
|
3199
|
+
return c.json({
|
|
3200
|
+
actors: actors.map(createApiActor)
|
|
3201
|
+
});
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3204
|
+
{
|
|
3205
|
+
const route = _zodopenapi.createRoute.call(void 0, {
|
|
3206
|
+
middleware: [cors2],
|
|
3207
|
+
method: "put",
|
|
3208
|
+
path: "/actors",
|
|
3209
|
+
request: {
|
|
3210
|
+
body: {
|
|
3211
|
+
content: {
|
|
3212
|
+
"application/json": {
|
|
3213
|
+
schema: ActorsGetOrCreateRequestSchema
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
},
|
|
3218
|
+
responses: buildOpenApiResponses(ActorsGetOrCreateResponseSchema)
|
|
3219
|
+
});
|
|
3220
|
+
router.openapi(route, async (c) => {
|
|
3221
|
+
const body = c.req.valid("json");
|
|
3222
|
+
const existingActor = await managerDriver.getWithKey({
|
|
3223
|
+
c,
|
|
3224
|
+
name: body.name,
|
|
3225
|
+
key: [body.key]
|
|
3226
|
+
// Convert string to ActorKey array
|
|
3227
|
+
});
|
|
3228
|
+
if (existingActor) {
|
|
3229
|
+
return c.json({
|
|
3230
|
+
actor: createApiActor(existingActor),
|
|
3231
|
+
created: false
|
|
3232
|
+
});
|
|
3233
|
+
}
|
|
3234
|
+
const newActor = await managerDriver.getOrCreateWithKey({
|
|
3235
|
+
c,
|
|
3236
|
+
name: body.name,
|
|
3237
|
+
key: [body.key],
|
|
3238
|
+
// Convert string to ActorKey array
|
|
3239
|
+
input: body.input ? cbor4.decode(Buffer.from(body.input, "base64")) : void 0,
|
|
3240
|
+
region: void 0
|
|
3241
|
+
// Not provided in the request schema
|
|
3242
|
+
});
|
|
3243
|
+
return c.json({
|
|
3244
|
+
actor: createApiActor(newActor),
|
|
3245
|
+
created: true
|
|
3246
|
+
});
|
|
3247
|
+
});
|
|
3248
|
+
}
|
|
3249
|
+
{
|
|
3250
|
+
const route = _zodopenapi.createRoute.call(void 0, {
|
|
3251
|
+
middleware: [cors2],
|
|
3252
|
+
method: "post",
|
|
3253
|
+
path: "/actors",
|
|
3254
|
+
request: {
|
|
3255
|
+
body: {
|
|
3256
|
+
content: {
|
|
3257
|
+
"application/json": {
|
|
3258
|
+
schema: ActorsCreateRequestSchema
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
},
|
|
3263
|
+
responses: buildOpenApiResponses(ActorsCreateResponseSchema)
|
|
3264
|
+
});
|
|
3265
|
+
router.openapi(route, async (c) => {
|
|
3266
|
+
const body = c.req.valid("json");
|
|
3267
|
+
const actorOutput = await managerDriver.createActor({
|
|
3268
|
+
c,
|
|
3269
|
+
name: body.name,
|
|
3270
|
+
key: [body.key || crypto.randomUUID()],
|
|
3271
|
+
// Generate key if not provided, convert to ActorKey array
|
|
3272
|
+
input: body.input ? cbor4.decode(Buffer.from(body.input, "base64")) : void 0,
|
|
3273
|
+
region: void 0
|
|
3274
|
+
// Not provided in the request schema
|
|
3275
|
+
});
|
|
3276
|
+
const actor2 = createApiActor(actorOutput);
|
|
3277
|
+
return c.json({ actor: actor2 });
|
|
3278
|
+
});
|
|
3279
|
+
}
|
|
3280
|
+
if (registryConfig.test.enabled) {
|
|
3281
|
+
router.post(".test/inline-driver/call", async (c) => {
|
|
3282
|
+
const buffer = await c.req.arrayBuffer();
|
|
3283
|
+
const { encoding, transport, method, args } = cbor4.decode(new Uint8Array(buffer));
|
|
3284
|
+
logger().debug({
|
|
3285
|
+
msg: "received inline request",
|
|
3286
|
+
encoding,
|
|
3287
|
+
transport,
|
|
3288
|
+
method,
|
|
3289
|
+
args
|
|
3290
|
+
});
|
|
3291
|
+
let response;
|
|
3292
|
+
try {
|
|
3293
|
+
const output = await managerDriver[method](...args);
|
|
3294
|
+
response = { ok: output };
|
|
3295
|
+
} catch (rawErr) {
|
|
3296
|
+
const err = _chunk6EUWRXLTcjs.deconstructError.call(void 0, rawErr, logger(), {}, true);
|
|
3297
|
+
response = { err };
|
|
3298
|
+
}
|
|
3299
|
+
return c.body(cbor4.encode(response));
|
|
3300
|
+
});
|
|
3301
|
+
router.get(".test/inline-driver/connect-websocket/*", async (c) => {
|
|
3302
|
+
var _a2;
|
|
3303
|
+
const upgradeWebSocket = (_a2 = runConfig.getUpgradeWebSocket) == null ? void 0 : _a2.call(runConfig);
|
|
3304
|
+
_invariant2.default.call(void 0, upgradeWebSocket, "websockets not supported on this platform");
|
|
3305
|
+
return upgradeWebSocket(async (c2) => {
|
|
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(_chunkSAZCNSVYcjs.WS_PROTOCOL_ACTOR)) {
|
|
3317
|
+
actorId = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_ACTOR.length);
|
|
3318
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING)) {
|
|
3319
|
+
encoding = protocol.substring(
|
|
3320
|
+
_chunkSAZCNSVYcjs.WS_PROTOCOL_ENCODING.length
|
|
3321
|
+
);
|
|
3322
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_TRANSPORT)) {
|
|
3323
|
+
transport = protocol.substring(
|
|
3324
|
+
_chunkSAZCNSVYcjs.WS_PROTOCOL_TRANSPORT.length
|
|
3325
|
+
);
|
|
3326
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_PATH)) {
|
|
3327
|
+
path3 = decodeURIComponent(
|
|
3328
|
+
protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_PATH.length)
|
|
3329
|
+
);
|
|
3330
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS)) {
|
|
3331
|
+
const paramsRaw = decodeURIComponent(
|
|
3332
|
+
protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_PARAMS.length)
|
|
3333
|
+
);
|
|
3334
|
+
params = JSON.parse(paramsRaw);
|
|
3335
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_ID)) {
|
|
3336
|
+
connId = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_ID.length);
|
|
3337
|
+
} else if (protocol.startsWith(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_TOKEN)) {
|
|
3338
|
+
connToken = protocol.substring(_chunkSAZCNSVYcjs.WS_PROTOCOL_CONN_TOKEN.length);
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
logger().debug({
|
|
3342
|
+
msg: "received test inline driver websocket",
|
|
3343
|
+
actorId,
|
|
3344
|
+
params,
|
|
3345
|
+
encodingKind: encoding,
|
|
3346
|
+
transport,
|
|
3347
|
+
path: path3
|
|
3348
|
+
});
|
|
3349
|
+
const clientWsPromise = managerDriver.openWebSocket(
|
|
3350
|
+
path3,
|
|
3351
|
+
actorId,
|
|
3352
|
+
encoding,
|
|
3353
|
+
params,
|
|
3354
|
+
connId,
|
|
3355
|
+
connToken
|
|
3356
|
+
);
|
|
3357
|
+
return await createTestWebSocketProxy(clientWsPromise);
|
|
3358
|
+
})(c, _chunk6EUWRXLTcjs.noopNext.call(void 0, ));
|
|
3359
|
+
});
|
|
3360
|
+
router.all(".test/inline-driver/send-request/*", async (c) => {
|
|
3361
|
+
const actorId = c.req.header(_chunkSAZCNSVYcjs.HEADER_ACTOR_ID);
|
|
3362
|
+
if (!actorId) {
|
|
3363
|
+
return c.text("Missing required headers", 400);
|
|
3364
|
+
}
|
|
3365
|
+
const pathOnly = c.req.path.split("/.test/inline-driver/send-request/")[1] || "";
|
|
3366
|
+
const url = new URL(c.req.url);
|
|
3367
|
+
const pathWithQuery = pathOnly + url.search;
|
|
3368
|
+
logger().debug({
|
|
3369
|
+
msg: "received test inline driver raw http",
|
|
3370
|
+
actorId,
|
|
3371
|
+
path: pathWithQuery,
|
|
3372
|
+
method: c.req.method
|
|
3373
|
+
});
|
|
3374
|
+
try {
|
|
3375
|
+
const response = await managerDriver.sendRequest(
|
|
3376
|
+
actorId,
|
|
3377
|
+
new Request(`http://actor/${pathWithQuery}`, {
|
|
3378
|
+
method: c.req.method,
|
|
3379
|
+
headers: c.req.raw.headers,
|
|
3380
|
+
body: c.req.raw.body,
|
|
3381
|
+
duplex: "half"
|
|
3382
|
+
})
|
|
3383
|
+
);
|
|
3384
|
+
return response;
|
|
3385
|
+
} catch (error) {
|
|
3386
|
+
logger().error({
|
|
3387
|
+
msg: "error in test inline raw http",
|
|
3388
|
+
error: _chunk6EUWRXLTcjs.stringifyError.call(void 0, error)
|
|
3389
|
+
});
|
|
3390
|
+
const err = _chunk6EUWRXLTcjs.deconstructError.call(void 0, error, logger(), {}, true);
|
|
3391
|
+
return c.json(
|
|
3392
|
+
{
|
|
3393
|
+
error: {
|
|
3394
|
+
code: err.code,
|
|
3395
|
+
message: err.message,
|
|
3396
|
+
metadata: err.metadata
|
|
3397
|
+
}
|
|
3398
|
+
},
|
|
3399
|
+
err.statusCode
|
|
3400
|
+
);
|
|
3401
|
+
}
|
|
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: _chunk6EUWRXLTcjs.stringifyError.call(void 0, error)
|
|
3433
|
+
});
|
|
3434
|
+
return c.text(`Error: ${error}`, 500);
|
|
3435
|
+
}
|
|
3436
|
+
});
|
|
3437
|
+
}
|
|
3438
|
+
router.get("/health", cors2, (c) => {
|
|
3439
|
+
return c.text("ok");
|
|
3440
|
+
});
|
|
3441
|
+
(_a = managerDriver.modifyManagerRouter) == null ? void 0 : _a.call(
|
|
3442
|
+
managerDriver,
|
|
3443
|
+
registryConfig,
|
|
3444
|
+
router
|
|
3445
|
+
);
|
|
3446
|
+
if (_chunkG4ABMAQYcjs.isInspectorEnabled.call(void 0, runConfig, "manager")) {
|
|
3447
|
+
if (!managerDriver.inspector) {
|
|
3448
|
+
throw new (0, _chunk5QGQK44Lcjs.Unsupported)("inspector");
|
|
3449
|
+
}
|
|
3450
|
+
router.route(
|
|
3451
|
+
"/inspect",
|
|
3452
|
+
new (0, _hono.Hono)().use(_cors.cors.call(void 0, runConfig.inspector.cors)).use(_chunkG4ABMAQYcjs.secureInspector.call(void 0, runConfig)).use((c, next) => {
|
|
3453
|
+
c.set("inspector", managerDriver.inspector);
|
|
3454
|
+
return next();
|
|
3455
|
+
}).route("/", createManagerInspectorRouter())
|
|
3456
|
+
);
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3459
|
+
function createApiActor(actor2) {
|
|
3460
|
+
return {
|
|
3461
|
+
actor_id: actor2.actorId,
|
|
3462
|
+
name: actor2.name,
|
|
3463
|
+
key: _chunk5ZOHIKWGcjs.serializeActorKey.call(void 0, 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
|
|
3473
|
+
};
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
// src/registry/config.ts
|
|
3477
|
+
|
|
3478
|
+
var ActorsSchema = _zod.z.record(
|
|
3479
|
+
_zod.z.string(),
|
|
3480
|
+
_zod.z.custom()
|
|
3481
|
+
);
|
|
3482
|
+
var TestConfigSchema = _zod.z.object({ enabled: _zod.z.boolean() });
|
|
3483
|
+
var RegistryConfigSchema = _zod.z.object({
|
|
3484
|
+
use: _zod.z.record(_zod.z.string(), _zod.z.custom()),
|
|
3485
|
+
// TODO: Find a better way of passing around the test config
|
|
3486
|
+
/**
|
|
3487
|
+
* Test configuration.
|
|
3488
|
+
*
|
|
3489
|
+
* DO NOT MANUALLY ENABLE. THIS IS USED INTERNALLY.
|
|
3490
|
+
* @internal
|
|
3491
|
+
**/
|
|
3492
|
+
test: TestConfigSchema.optional().default({ enabled: false })
|
|
3493
|
+
});
|
|
3494
|
+
|
|
3495
|
+
// src/registry/log.ts
|
|
3496
|
+
function logger6() {
|
|
3497
|
+
return _chunk3MBP4WNCcjs.getLogger.call(void 0, "registry");
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
// src/registry/serve.ts
|
|
3501
|
+
|
|
3502
|
+
async function crossPlatformServe(rivetKitRouter, userRouter) {
|
|
3503
|
+
const app = _nullishCoalesce(userRouter, () => ( new (0, _hono.Hono)()));
|
|
3504
|
+
let serve;
|
|
3505
|
+
try {
|
|
3506
|
+
const dep = await Promise.resolve().then(() => _interopRequireWildcard(require(
|
|
3507
|
+
/* webpackIgnore: true */
|
|
3508
|
+
"@hono/node-server"
|
|
3509
|
+
)));
|
|
3510
|
+
serve = dep.serve;
|
|
3511
|
+
} catch (err) {
|
|
3512
|
+
logger6().error(
|
|
3513
|
+
"failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'"
|
|
3514
|
+
);
|
|
3515
|
+
process.exit(1);
|
|
3516
|
+
}
|
|
3517
|
+
app.route("/", rivetKitRouter);
|
|
3518
|
+
let createNodeWebSocket;
|
|
3519
|
+
try {
|
|
3520
|
+
const dep = await Promise.resolve().then(() => _interopRequireWildcard(require(
|
|
3521
|
+
/* webpackIgnore: true */
|
|
3522
|
+
"@hono/node-ws"
|
|
3523
|
+
)));
|
|
3524
|
+
createNodeWebSocket = dep.createNodeWebSocket;
|
|
3525
|
+
} catch (err) {
|
|
3526
|
+
logger6().error(
|
|
3527
|
+
"failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'"
|
|
3528
|
+
);
|
|
3529
|
+
process.exit(1);
|
|
3530
|
+
}
|
|
3531
|
+
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
|
|
3532
|
+
app
|
|
3533
|
+
});
|
|
3534
|
+
const port = 6420;
|
|
3535
|
+
const server = serve(
|
|
3536
|
+
{ fetch: app.fetch, port },
|
|
3537
|
+
() => logger6().info({ msg: "server listening", port })
|
|
3538
|
+
);
|
|
3539
|
+
injectWebSocket(server);
|
|
3540
|
+
return { upgradeWebSocket };
|
|
3541
|
+
}
|
|
3542
|
+
|
|
3543
|
+
// src/registry/mod.ts
|
|
3544
|
+
var Registry = class {
|
|
3545
|
+
#config;
|
|
3546
|
+
get config() {
|
|
3547
|
+
return this.#config;
|
|
3548
|
+
}
|
|
3549
|
+
constructor(config2) {
|
|
3550
|
+
this.#config = config2;
|
|
3551
|
+
}
|
|
3552
|
+
/**
|
|
3553
|
+
* Runs the registry for a server.
|
|
3554
|
+
*/
|
|
3555
|
+
start(inputConfig) {
|
|
3556
|
+
var _a, _b, _c;
|
|
3557
|
+
const config2 = _chunkDFS77KAAcjs.RunConfigSchema.parse(inputConfig);
|
|
3558
|
+
if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
|
|
3559
|
+
_chunk3MBP4WNCcjs.configureBaseLogger.call(void 0, config2.logging.baseLogger);
|
|
3560
|
+
} else {
|
|
3561
|
+
_chunk3MBP4WNCcjs.configureDefaultLogger.call(void 0, (_b = config2.logging) == null ? void 0 : _b.level);
|
|
3562
|
+
}
|
|
3563
|
+
const driver = chooseDefaultDriver(config2);
|
|
3564
|
+
if (driver.name === "engine") {
|
|
3565
|
+
config2.inspector.enabled = { manager: false, actor: true };
|
|
3566
|
+
config2.disableServer = true;
|
|
3567
|
+
}
|
|
3568
|
+
if (driver.name === "cloudflare-workers") {
|
|
3569
|
+
config2.inspector.enabled = { manager: false, actor: true };
|
|
3570
|
+
config2.disableServer = true;
|
|
3571
|
+
config2.disableActorDriver = true;
|
|
3572
|
+
config2.noWelcome = true;
|
|
3573
|
+
}
|
|
3574
|
+
let upgradeWebSocket;
|
|
3575
|
+
if (!config2.getUpgradeWebSocket) {
|
|
3576
|
+
config2.getUpgradeWebSocket = () => upgradeWebSocket;
|
|
3577
|
+
}
|
|
3578
|
+
const managerDriver = driver.manager(this.#config, config2);
|
|
3579
|
+
_chunkG4ABMAQYcjs.configureInspectorAccessToken.call(void 0, config2, managerDriver);
|
|
3580
|
+
const client = _chunk5ZOHIKWGcjs.createClientWithDriver.call(void 0, managerDriver, config2);
|
|
3581
|
+
const driverLog = _nullishCoalesce(((_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 (_chunkG4ABMAQYcjs.isInspectorEnabled.call(void 0, config2, "manager") && managerDriver.inspector) {
|
|
3589
|
+
logger6().info({ msg: "inspector ready", url: _chunkG4ABMAQYcjs.getInspectorUrl.call(void 0, config2) });
|
|
3590
|
+
}
|
|
3591
|
+
if (!config2.noWelcome) {
|
|
3592
|
+
const displayInfo = managerDriver.displayInformation();
|
|
3593
|
+
console.log();
|
|
3594
|
+
console.log(` RivetKit ${_chunk6EUWRXLTcjs.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 (_chunkG4ABMAQYcjs.isInspectorEnabled.call(void 0, config2, "manager") && managerDriver.inspector) {
|
|
3601
|
+
console.log(` - Inspector: ${_chunkG4ABMAQYcjs.getInspectorUrl.call(void 0, 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
|
+
}
|
|
3613
|
+
const { router: hono } = createManagerRouter(
|
|
3614
|
+
this.#config,
|
|
3615
|
+
config2,
|
|
3616
|
+
managerDriver,
|
|
3617
|
+
void 0
|
|
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 = _chunkDFS77KAAcjs.RunConfigSchema.parse(inputConfig);
|
|
3633
|
+
if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
|
|
3634
|
+
_chunk3MBP4WNCcjs.configureBaseLogger.call(void 0, config2.logging.baseLogger);
|
|
3635
|
+
} else {
|
|
3636
|
+
_chunk3MBP4WNCcjs.configureDefaultLogger.call(void 0, (_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);
|
|
3655
|
+
const client = _chunk5ZOHIKWGcjs.createClientWithDriver.call(void 0, managerDriver, config2);
|
|
3656
|
+
const driverLog = _nullishCoalesce(((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)), () => ( {}));
|
|
3657
|
+
logger6().info({
|
|
3658
|
+
msg: "rivetkit ready",
|
|
3659
|
+
driver: driver.name,
|
|
3660
|
+
definitions: Object.keys(this.#config.use).length,
|
|
3661
|
+
...driverLog
|
|
3662
|
+
});
|
|
3663
|
+
if (((_d = config2.inspector) == null ? void 0 : _d.enabled) && managerDriver.inspector) {
|
|
3664
|
+
logger6().info({ msg: "inspector ready", url: _chunkG4ABMAQYcjs.getInspectorUrl.call(void 0, config2) });
|
|
3665
|
+
}
|
|
3666
|
+
if (!config2.noWelcome) {
|
|
3667
|
+
const displayInfo = managerDriver.displayInformation();
|
|
3668
|
+
console.log();
|
|
3669
|
+
console.log(` RivetKit ${_chunk6EUWRXLTcjs.package_default.version} (${displayInfo.name})`);
|
|
3670
|
+
console.log(` - Endpoint: http://127.0.0.1:6420`);
|
|
3671
|
+
for (const [k, v] of Object.entries(displayInfo.properties)) {
|
|
3672
|
+
const padding = " ".repeat(Math.max(0, 13 - k.length));
|
|
3673
|
+
console.log(` - ${k}:${padding}${v}`);
|
|
3674
|
+
}
|
|
3675
|
+
if (((_e = config2.inspector) == null ? void 0 : _e.enabled) && managerDriver.inspector) {
|
|
3676
|
+
console.log(` - Inspector: ${_chunkG4ABMAQYcjs.getInspectorUrl.call(void 0, config2)}`);
|
|
3677
|
+
}
|
|
3678
|
+
console.log();
|
|
3679
|
+
}
|
|
3680
|
+
let serverlessActorDriverBuilder = () => {
|
|
3681
|
+
return driver.actor(this.#config, config2, managerDriver, client);
|
|
3682
|
+
};
|
|
3683
|
+
if (!config2.disableActorDriver) {
|
|
3684
|
+
const _actorDriver = serverlessActorDriverBuilder();
|
|
3685
|
+
serverlessActorDriverBuilder = void 0;
|
|
3686
|
+
}
|
|
3687
|
+
const { router: hono } = createManagerRouter(
|
|
3688
|
+
this.#config,
|
|
3689
|
+
config2,
|
|
3690
|
+
managerDriver,
|
|
3691
|
+
serverlessActorDriverBuilder
|
|
3692
|
+
);
|
|
3693
|
+
if (!config2.disableServer) {
|
|
3694
|
+
(async () => {
|
|
3695
|
+
const out = await crossPlatformServe(hono, void 0);
|
|
3696
|
+
upgradeWebSocket = out.upgradeWebSocket;
|
|
3697
|
+
})();
|
|
3698
|
+
}
|
|
3699
|
+
return {
|
|
3700
|
+
client,
|
|
3701
|
+
fetch: hono.fetch.bind(hono)
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
};
|
|
3705
|
+
function setup(input) {
|
|
3706
|
+
const config2 = RegistryConfigSchema.parse(input);
|
|
3707
|
+
return new Registry(config2);
|
|
3708
|
+
}
|
|
3709
|
+
|
|
3710
|
+
|
|
3711
|
+
|
|
3712
|
+
|
|
3713
|
+
|
|
3714
|
+
|
|
3715
|
+
|
|
3716
|
+
|
|
3717
|
+
|
|
3718
|
+
|
|
3719
|
+
|
|
3720
|
+
|
|
3721
|
+
|
|
3722
|
+
|
|
3723
|
+
|
|
3724
|
+
exports.handleWebSocketConnect = handleWebSocketConnect; exports.handleRawWebSocketHandler = handleRawWebSocketHandler; exports.createActorRouter = createActorRouter; exports.actor = actor; exports.InlineWebSocketAdapter2 = InlineWebSocketAdapter2; exports.createEngineDriver = createEngineDriver; exports.createFileSystemOrMemoryDriver = createFileSystemOrMemoryDriver; exports.createFileSystemDriver = createFileSystemDriver; exports.createMemoryDriver = createMemoryDriver; exports.createManagerRouter = createManagerRouter; exports.RegistryConfigSchema = RegistryConfigSchema; exports.Registry = Registry; exports.setup = setup;
|
|
3725
|
+
//! These configs configs hold anything that's not platform-specific about running actors.
|
|
3726
|
+
//# sourceMappingURL=chunk-3Y45CIF4.cjs.map
|