rivetkit 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +11 -0
  2. package/dist/schemas/actor-persist/v1.ts +21 -24
  3. package/dist/schemas/client-protocol/v1.ts +6 -0
  4. package/dist/tsup/actor/errors.cjs +10 -2
  5. package/dist/tsup/actor/errors.cjs.map +1 -1
  6. package/dist/tsup/actor/errors.d.cts +17 -4
  7. package/dist/tsup/actor/errors.d.ts +17 -4
  8. package/dist/tsup/actor/errors.js +11 -3
  9. package/dist/tsup/{chunk-6PDXBYI5.js → chunk-3F2YSRJL.js} +8 -23
  10. package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
  11. package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
  12. package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
  13. package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
  14. package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
  15. package/dist/tsup/{chunk-OGAPU3UG.cjs → chunk-6LJT3QRL.cjs} +39 -25
  16. package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
  17. package/dist/tsup/{chunk-6WKQDDUD.cjs → chunk-GICQ3YCU.cjs} +143 -141
  18. package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
  19. package/dist/tsup/{chunk-FLMTTN27.js → chunk-H26RP6GD.js} +15 -8
  20. package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
  21. package/dist/tsup/chunk-HI3HWJRC.js +20 -0
  22. package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
  23. package/dist/tsup/{chunk-4NSUQZ2H.js → chunk-HLLF4B4Q.js} +116 -114
  24. package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
  25. package/dist/tsup/{chunk-FCCPJNMA.cjs → chunk-IH6CKNDW.cjs} +12 -27
  26. package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
  27. package/dist/tsup/chunk-LV2S3OU3.js +250 -0
  28. package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
  29. package/dist/tsup/{chunk-R2OPSKIV.cjs → chunk-LWNKVZG5.cjs} +20 -13
  30. package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
  31. package/dist/tsup/{chunk-INGJP237.js → chunk-NFU2BBT5.js} +102 -43
  32. package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
  33. package/dist/tsup/{chunk-3H7O2A7I.js → chunk-PQY7KKTL.js} +33 -19
  34. package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
  35. package/dist/tsup/{chunk-PO4VLDWA.js → chunk-QK72M5JB.js} +3 -5
  36. package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
  37. package/dist/tsup/{chunk-TZJKSBUQ.cjs → chunk-QNNXFOQV.cjs} +3 -5
  38. package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
  39. package/dist/tsup/{chunk-GIR3AFFI.cjs → chunk-SBHHJ6QS.cjs} +102 -43
  40. package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
  41. package/dist/tsup/chunk-TQ62L3X7.js +325 -0
  42. package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
  43. package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
  44. package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
  45. package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
  46. package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
  47. package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
  48. package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
  49. package/dist/tsup/client/mod.cjs +10 -10
  50. package/dist/tsup/client/mod.d.cts +7 -13
  51. package/dist/tsup/client/mod.d.ts +7 -13
  52. package/dist/tsup/client/mod.js +9 -9
  53. package/dist/tsup/common/log.cjs +12 -4
  54. package/dist/tsup/common/log.cjs.map +1 -1
  55. package/dist/tsup/common/log.d.cts +23 -17
  56. package/dist/tsup/common/log.d.ts +23 -17
  57. package/dist/tsup/common/log.js +15 -7
  58. package/dist/tsup/common/websocket.cjs +5 -5
  59. package/dist/tsup/common/websocket.js +4 -4
  60. package/dist/tsup/{common-CpqORuCq.d.cts → common-CXCe7s6i.d.cts} +2 -2
  61. package/dist/tsup/{common-CpqORuCq.d.ts → common-CXCe7s6i.d.ts} +2 -2
  62. package/dist/tsup/{connection-BwUMoe6n.d.ts → connection-BI-6UIBJ.d.ts} +196 -226
  63. package/dist/tsup/{connection-BR_Ve4ku.d.cts → connection-Dyd4NLGW.d.cts} +196 -226
  64. package/dist/tsup/driver-helpers/mod.cjs +6 -9
  65. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  66. package/dist/tsup/driver-helpers/mod.d.cts +5 -6
  67. package/dist/tsup/driver-helpers/mod.d.ts +5 -6
  68. package/dist/tsup/driver-helpers/mod.js +6 -9
  69. package/dist/tsup/driver-test-suite/mod.cjs +155 -1363
  70. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  71. package/dist/tsup/driver-test-suite/mod.d.cts +11 -5
  72. package/dist/tsup/driver-test-suite/mod.d.ts +11 -5
  73. package/dist/tsup/driver-test-suite/mod.js +876 -2084
  74. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  75. package/dist/tsup/inspector/mod.cjs +6 -8
  76. package/dist/tsup/inspector/mod.cjs.map +1 -1
  77. package/dist/tsup/inspector/mod.d.cts +3 -3
  78. package/dist/tsup/inspector/mod.d.ts +3 -3
  79. package/dist/tsup/inspector/mod.js +8 -10
  80. package/dist/tsup/mod.cjs +9 -15
  81. package/dist/tsup/mod.cjs.map +1 -1
  82. package/dist/tsup/mod.d.cts +47 -42
  83. package/dist/tsup/mod.d.ts +47 -42
  84. package/dist/tsup/mod.js +10 -16
  85. package/dist/tsup/{router-endpoints-DAbqVFx2.d.ts → router-endpoints-BTe_Rsdn.d.cts} +2 -3
  86. package/dist/tsup/{router-endpoints-AYkXG8Tl.d.cts → router-endpoints-CBSrKHmo.d.ts} +2 -3
  87. package/dist/tsup/test/mod.cjs +10 -14
  88. package/dist/tsup/test/mod.cjs.map +1 -1
  89. package/dist/tsup/test/mod.d.cts +4 -5
  90. package/dist/tsup/test/mod.d.ts +4 -5
  91. package/dist/tsup/test/mod.js +9 -13
  92. package/dist/tsup/{utils-CT0cv4jd.d.ts → utils-fwx3o3K9.d.cts} +1 -0
  93. package/dist/tsup/{utils-CT0cv4jd.d.cts → utils-fwx3o3K9.d.ts} +1 -0
  94. package/dist/tsup/utils.cjs +3 -3
  95. package/dist/tsup/utils.d.cts +1 -1
  96. package/dist/tsup/utils.d.ts +1 -1
  97. package/dist/tsup/utils.js +2 -2
  98. package/package.json +4 -4
  99. package/src/actor/action.ts +1 -5
  100. package/src/actor/config.ts +27 -295
  101. package/src/actor/connection.ts +9 -12
  102. package/src/actor/context.ts +1 -4
  103. package/src/actor/definition.ts +7 -11
  104. package/src/actor/errors.ts +97 -35
  105. package/src/actor/generic-conn-driver.ts +28 -16
  106. package/src/actor/instance.ts +177 -133
  107. package/src/actor/log.ts +4 -13
  108. package/src/actor/mod.ts +0 -5
  109. package/src/actor/protocol/old.ts +42 -26
  110. package/src/actor/protocol/serde.ts +1 -1
  111. package/src/actor/router-endpoints.ts +41 -38
  112. package/src/actor/router.ts +20 -18
  113. package/src/actor/unstable-react.ts +1 -1
  114. package/src/actor/utils.ts +6 -2
  115. package/src/client/actor-common.ts +1 -1
  116. package/src/client/actor-conn.ts +152 -91
  117. package/src/client/actor-handle.ts +85 -25
  118. package/src/client/actor-query.ts +65 -0
  119. package/src/client/client.ts +29 -98
  120. package/src/client/config.ts +44 -0
  121. package/src/client/errors.ts +1 -0
  122. package/src/client/log.ts +2 -4
  123. package/src/client/mod.ts +16 -12
  124. package/src/client/raw-utils.ts +82 -25
  125. package/src/client/utils.ts +5 -3
  126. package/src/common/fake-event-source.ts +10 -9
  127. package/src/common/inline-websocket-adapter2.ts +39 -30
  128. package/src/common/log.ts +176 -101
  129. package/src/common/logfmt.ts +21 -30
  130. package/src/common/router.ts +12 -19
  131. package/src/common/utils.ts +27 -13
  132. package/src/common/websocket.ts +0 -1
  133. package/src/driver-helpers/mod.ts +1 -1
  134. package/src/driver-test-suite/log.ts +1 -3
  135. package/src/driver-test-suite/mod.ts +86 -60
  136. package/src/driver-test-suite/tests/actor-handle.ts +33 -0
  137. package/src/driver-test-suite/tests/manager-driver.ts +5 -3
  138. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -226
  139. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -392
  140. package/src/driver-test-suite/tests/request-access.ts +112 -126
  141. package/src/driver-test-suite/utils.ts +13 -10
  142. package/src/drivers/default.ts +7 -4
  143. package/src/drivers/engine/actor-driver.ts +22 -13
  144. package/src/drivers/engine/config.ts +2 -10
  145. package/src/drivers/engine/kv.ts +1 -1
  146. package/src/drivers/engine/log.ts +1 -3
  147. package/src/drivers/engine/mod.ts +2 -3
  148. package/src/drivers/file-system/actor.ts +1 -1
  149. package/src/drivers/file-system/global-state.ts +33 -20
  150. package/src/drivers/file-system/log.ts +1 -3
  151. package/src/drivers/file-system/manager.ts +31 -8
  152. package/src/inspector/config.ts +9 -4
  153. package/src/inspector/log.ts +1 -1
  154. package/src/inspector/manager.ts +2 -2
  155. package/src/inspector/utils.ts +1 -1
  156. package/src/manager/driver.ts +10 -2
  157. package/src/manager/hono-websocket-adapter.ts +21 -12
  158. package/src/manager/log.ts +2 -4
  159. package/src/manager/mod.ts +1 -1
  160. package/src/manager/router.ts +277 -1657
  161. package/src/manager-api/routes/actors-create.ts +16 -0
  162. package/src/manager-api/routes/actors-delete.ts +4 -0
  163. package/src/manager-api/routes/actors-get-by-id.ts +7 -0
  164. package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
  165. package/src/manager-api/routes/actors-get.ts +7 -0
  166. package/src/manager-api/routes/common.ts +18 -0
  167. package/src/mod.ts +0 -2
  168. package/src/registry/config.ts +1 -1
  169. package/src/registry/log.ts +2 -4
  170. package/src/registry/mod.ts +57 -24
  171. package/src/registry/run-config.ts +31 -33
  172. package/src/registry/serve.ts +4 -5
  173. package/src/remote-manager-driver/actor-http-client.ts +72 -0
  174. package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
  175. package/src/remote-manager-driver/api-endpoints.ts +79 -0
  176. package/src/remote-manager-driver/api-utils.ts +43 -0
  177. package/src/remote-manager-driver/log.ts +5 -0
  178. package/src/remote-manager-driver/mod.ts +274 -0
  179. package/src/{drivers/engine → remote-manager-driver}/ws-proxy.ts +24 -14
  180. package/src/serde.ts +8 -2
  181. package/src/test/log.ts +1 -3
  182. package/src/test/mod.ts +17 -16
  183. package/dist/tsup/chunk-2CRLFV6Z.cjs +0 -202
  184. package/dist/tsup/chunk-2CRLFV6Z.cjs.map +0 -1
  185. package/dist/tsup/chunk-3H7O2A7I.js.map +0 -1
  186. package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
  187. package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
  188. package/dist/tsup/chunk-4NSUQZ2H.js.map +0 -1
  189. package/dist/tsup/chunk-6PDXBYI5.js.map +0 -1
  190. package/dist/tsup/chunk-6WKQDDUD.cjs.map +0 -1
  191. package/dist/tsup/chunk-CTBOSFUH.cjs +0 -116
  192. package/dist/tsup/chunk-CTBOSFUH.cjs.map +0 -1
  193. package/dist/tsup/chunk-EGVZZFE2.js +0 -2857
  194. package/dist/tsup/chunk-EGVZZFE2.js.map +0 -1
  195. package/dist/tsup/chunk-FCCPJNMA.cjs.map +0 -1
  196. package/dist/tsup/chunk-FLMTTN27.js.map +0 -1
  197. package/dist/tsup/chunk-GIR3AFFI.cjs.map +0 -1
  198. package/dist/tsup/chunk-INGJP237.js.map +0 -1
  199. package/dist/tsup/chunk-KJCJLKRM.js +0 -116
  200. package/dist/tsup/chunk-KJCJLKRM.js.map +0 -1
  201. package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
  202. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
  203. package/dist/tsup/chunk-O2MBYIXO.cjs +0 -2857
  204. package/dist/tsup/chunk-O2MBYIXO.cjs.map +0 -1
  205. package/dist/tsup/chunk-OGAPU3UG.cjs.map +0 -1
  206. package/dist/tsup/chunk-OV6AYD4S.js +0 -4406
  207. package/dist/tsup/chunk-OV6AYD4S.js.map +0 -1
  208. package/dist/tsup/chunk-PO4VLDWA.js.map +0 -1
  209. package/dist/tsup/chunk-R2OPSKIV.cjs.map +0 -1
  210. package/dist/tsup/chunk-TZJKSBUQ.cjs.map +0 -1
  211. package/dist/tsup/chunk-UBUC5C3G.cjs +0 -189
  212. package/dist/tsup/chunk-UBUC5C3G.cjs.map +0 -1
  213. package/dist/tsup/chunk-UIM22YJL.cjs +0 -4406
  214. package/dist/tsup/chunk-UIM22YJL.cjs.map +0 -1
  215. package/dist/tsup/chunk-URVFQMYI.cjs +0 -230
  216. package/dist/tsup/chunk-URVFQMYI.cjs.map +0 -1
  217. package/dist/tsup/chunk-UVUPOS46.js +0 -230
  218. package/dist/tsup/chunk-UVUPOS46.js.map +0 -1
  219. package/dist/tsup/chunk-VRRHBNJC.js +0 -189
  220. package/dist/tsup/chunk-VRRHBNJC.js.map +0 -1
  221. package/dist/tsup/chunk-XFSS33EQ.js +0 -202
  222. package/dist/tsup/chunk-XFSS33EQ.js.map +0 -1
  223. package/src/client/http-client-driver.ts +0 -326
  224. package/src/driver-test-suite/test-inline-client-driver.ts +0 -402
  225. package/src/driver-test-suite/tests/actor-auth.ts +0 -591
  226. package/src/drivers/engine/api-endpoints.ts +0 -128
  227. package/src/drivers/engine/api-utils.ts +0 -70
  228. package/src/drivers/engine/manager-driver.ts +0 -391
  229. package/src/inline-client-driver/log.ts +0 -7
  230. package/src/inline-client-driver/mod.ts +0 -385
  231. package/src/manager/auth.ts +0 -121
  232. /package/src/{drivers/engine → actor}/keys.test.ts +0 -0
  233. /package/src/{drivers/engine → actor}/keys.ts +0 -0
@@ -1,4406 +0,0 @@
1
- import {
2
- ActorDefinition,
3
- ActorError as ActorError2,
4
- createActorInspectorRouter,
5
- createClientWithDriver,
6
- importEventSource,
7
- lookupInRegistry,
8
- sendHttpRequest
9
- } from "./chunk-EGVZZFE2.js";
10
- import {
11
- ActorQuerySchema,
12
- ConnMessageRequestSchema,
13
- ConnectRequestSchema,
14
- ConnectWebSocketRequestSchema,
15
- CreateActorSchema,
16
- ResolveRequestSchema
17
- } from "./chunk-FLMTTN27.js";
18
- import {
19
- importWebSocket
20
- } from "./chunk-PO4VLDWA.js";
21
- import {
22
- RunConfigSchema,
23
- serializeEmptyPersistData
24
- } from "./chunk-KJCJLKRM.js";
25
- import {
26
- ALLOWED_PUBLIC_HEADERS,
27
- CONNECTION_DRIVER_HTTP,
28
- CONNECTION_DRIVER_SSE,
29
- CONNECTION_DRIVER_WEBSOCKET,
30
- EncodingSchema,
31
- HEADER_ACTOR_ID,
32
- HEADER_ACTOR_QUERY,
33
- HEADER_AUTH_DATA,
34
- HEADER_CONN_ID,
35
- HEADER_CONN_PARAMS,
36
- HEADER_CONN_TOKEN,
37
- HEADER_ENCODING,
38
- HEADER_EXPOSE_INTERNAL_ERROR,
39
- HTTP_ACTION_REQUEST_VERSIONED,
40
- HTTP_ACTION_RESPONSE_VERSIONED,
41
- HTTP_RESOLVE_RESPONSE_VERSIONED,
42
- HTTP_RESPONSE_ERROR_VERSIONED,
43
- TO_CLIENT_VERSIONED,
44
- TO_SERVER_VERSIONED,
45
- createVersionedDataHandler,
46
- encodeDataToString,
47
- generateRandomString,
48
- getRequestEncoding,
49
- getRequestExposeInternalError,
50
- getRequestQuery,
51
- handleAction,
52
- handleConnectionMessage,
53
- handleRawWebSocketHandler,
54
- handleSseConnect,
55
- handleWebSocketConnect,
56
- logger,
57
- logger2,
58
- serializeWithEncoding
59
- } from "./chunk-4NSUQZ2H.js";
60
- import {
61
- getLogger
62
- } from "./chunk-XFSS33EQ.js";
63
- import {
64
- bufferToArrayBuffer,
65
- deconstructError,
66
- getEnvUniversal,
67
- httpUserAgent,
68
- noopNext,
69
- setLongTimeout,
70
- stringifyError
71
- } from "./chunk-3H7O2A7I.js";
72
- import {
73
- ActorAlreadyExists,
74
- ActorError,
75
- ActorNotFound,
76
- Forbidden,
77
- InternalError,
78
- InvalidParams,
79
- InvalidQueryJSON,
80
- InvalidRequest,
81
- ProxyError,
82
- UserError
83
- } from "./chunk-INGJP237.js";
84
-
85
- // src/actor/config.ts
86
- import { z } from "zod";
87
- var ActorConfigSchema = z.object({
88
- onAuth: z.function().optional(),
89
- onCreate: z.function().optional(),
90
- onStart: z.function().optional(),
91
- onStop: z.function().optional(),
92
- onStateChange: z.function().optional(),
93
- onBeforeConnect: z.function().optional(),
94
- onConnect: z.function().optional(),
95
- onDisconnect: z.function().optional(),
96
- onBeforeActionResponse: z.function().optional(),
97
- onFetch: z.function().optional(),
98
- onWebSocket: z.function().optional(),
99
- actions: z.record(z.function()).default({}),
100
- state: z.any().optional(),
101
- createState: z.function().optional(),
102
- connState: z.any().optional(),
103
- createConnState: z.function().optional(),
104
- vars: z.any().optional(),
105
- db: z.any().optional(),
106
- createVars: z.function().optional(),
107
- options: z.object({
108
- createVarsTimeout: z.number().positive().default(5e3),
109
- createConnStateTimeout: z.number().positive().default(5e3),
110
- onConnectTimeout: z.number().positive().default(5e3),
111
- // This must be less than ACTOR_STOP_THRESHOLD_MS
112
- onStopTimeout: z.number().positive().default(5e3),
113
- stateSaveInterval: z.number().positive().default(1e4),
114
- actionTimeout: z.number().positive().default(6e4),
115
- // Max time to wait for waitUntil background promises during shutdown
116
- waitUntilTimeout: z.number().positive().default(15e3),
117
- connectionLivenessTimeout: z.number().positive().default(2500),
118
- connectionLivenessInterval: z.number().positive().default(5e3),
119
- noSleep: z.boolean().default(false),
120
- sleepTimeout: 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/generic-conn-driver.ts
143
- var GenericConnGlobalState = class {
144
- websockets = /* @__PURE__ */ new Map();
145
- sseStreams = /* @__PURE__ */ new Map();
146
- };
147
- function createGenericConnDrivers(globalState) {
148
- return {
149
- [CONNECTION_DRIVER_WEBSOCKET]: createGenericWebSocketDriver(globalState),
150
- [CONNECTION_DRIVER_SSE]: createGenericSseDriver(globalState),
151
- [CONNECTION_DRIVER_HTTP]: createGenericHttpDriver()
152
- };
153
- }
154
- function createGenericWebSocketDriver(globalState) {
155
- return {
156
- sendMessage: (actor2, conn, state, message) => {
157
- const ws = globalState.websockets.get(conn.id);
158
- if (!ws) {
159
- logger().warn("missing ws for sendMessage", {
160
- actorId: actor2.id,
161
- connId: conn.id,
162
- totalCount: globalState.websockets.size
163
- });
164
- return;
165
- }
166
- const serialized = message.serialize(state.encoding);
167
- logger().debug("sending websocket message", {
168
- encoding: state.encoding,
169
- dataType: typeof serialized,
170
- isUint8Array: serialized instanceof Uint8Array,
171
- isArrayBuffer: serialized instanceof ArrayBuffer,
172
- dataLength: serialized.byteLength || serialized.length
173
- });
174
- if (serialized instanceof Uint8Array) {
175
- const buffer = serialized.buffer.slice(
176
- serialized.byteOffset,
177
- serialized.byteOffset + serialized.byteLength
178
- );
179
- if (buffer instanceof SharedArrayBuffer) {
180
- const arrayBuffer = new ArrayBuffer(buffer.byteLength);
181
- new Uint8Array(arrayBuffer).set(new Uint8Array(buffer));
182
- logger().debug("converted SharedArrayBuffer to ArrayBuffer", {
183
- byteLength: arrayBuffer.byteLength
184
- });
185
- ws.send(arrayBuffer);
186
- } else {
187
- logger().debug("sending ArrayBuffer", {
188
- byteLength: buffer.byteLength
189
- });
190
- ws.send(buffer);
191
- }
192
- } else {
193
- logger().debug("sending string data", {
194
- length: serialized.length
195
- });
196
- ws.send(serialized);
197
- }
198
- },
199
- disconnect: async (actor2, conn, _state, reason) => {
200
- const ws = globalState.websockets.get(conn.id);
201
- if (!ws) {
202
- logger().warn("missing ws for disconnect", {
203
- actorId: actor2.id,
204
- connId: conn.id,
205
- totalCount: globalState.websockets.size
206
- });
207
- return;
208
- }
209
- const raw = ws.raw;
210
- if (!raw) {
211
- logger().warn("ws.raw does not exist");
212
- return;
213
- }
214
- const { promise, resolve } = Promise.withResolvers();
215
- raw.addEventListener("close", () => resolve());
216
- ws.close(1e3, reason);
217
- await promise;
218
- },
219
- getConnectionReadyState: (_actor, conn) => {
220
- const ws = globalState.websockets.get(conn.id);
221
- if (!ws) {
222
- logger().warn("missing ws for getConnectionReadyState", {
223
- connId: conn.id
224
- });
225
- return void 0;
226
- }
227
- const raw = ws.raw;
228
- return raw.readyState;
229
- }
230
- };
231
- }
232
- function createGenericSseDriver(globalState) {
233
- return {
234
- sendMessage: (_actor, conn, state, message) => {
235
- const stream = globalState.sseStreams.get(conn.id);
236
- if (!stream) {
237
- logger().warn("missing sse stream for sendMessage", {
238
- connId: conn.id
239
- });
240
- return;
241
- }
242
- stream.writeSSE({
243
- data: encodeDataToString(message.serialize(state.encoding))
244
- });
245
- },
246
- disconnect: async (_actor, conn, _state, _reason) => {
247
- const stream = globalState.sseStreams.get(conn.id);
248
- if (!stream) {
249
- logger().warn("missing sse stream for disconnect", { connId: conn.id });
250
- return;
251
- }
252
- stream.close();
253
- },
254
- getConnectionReadyState: (_actor, conn) => {
255
- const stream = globalState.sseStreams.get(conn.id);
256
- if (!stream) {
257
- logger().warn("missing sse stream for getConnectionReadyState", {
258
- connId: conn.id
259
- });
260
- return void 0;
261
- }
262
- if (stream.aborted || stream.closed) {
263
- return 3 /* CLOSED */;
264
- }
265
- return 1 /* OPEN */;
266
- }
267
- };
268
- }
269
- function createGenericHttpDriver() {
270
- return {
271
- getConnectionReadyState(_actor, _conn) {
272
- return 1 /* OPEN */;
273
- },
274
- disconnect: async () => {
275
- }
276
- };
277
- }
278
-
279
- // src/actor/router.ts
280
- import { Hono } from "hono";
281
- import invariant from "invariant";
282
-
283
- // src/common/router.ts
284
- import * as cbor from "cbor-x";
285
- function logger3() {
286
- return getLogger("router");
287
- }
288
- function loggerMiddleware(logger9) {
289
- return async (c, next) => {
290
- const method = c.req.method;
291
- const path3 = c.req.path;
292
- const startTime = Date.now();
293
- await next();
294
- const duration = Date.now() - startTime;
295
- logger9.debug("http request", {
296
- method,
297
- path: path3,
298
- status: c.res.status,
299
- dt: `${duration}ms`,
300
- reqSize: c.req.header("content-length"),
301
- resSize: c.res.headers.get("content-length"),
302
- userAgent: c.req.header("user-agent")
303
- });
304
- };
305
- }
306
- function handleRouteNotFound(c) {
307
- return c.text("Not Found (RivetKit)", 404);
308
- }
309
- function handleRouteError(opts, error, c) {
310
- const exposeInternalError = opts.enableExposeInternalError && getRequestExposeInternalError(c.req.raw);
311
- const { statusCode, code, message, metadata } = deconstructError(
312
- error,
313
- logger3(),
314
- {
315
- method: c.req.method,
316
- path: c.req.path
317
- },
318
- exposeInternalError
319
- );
320
- let encoding;
321
- try {
322
- encoding = getRequestEncoding(c.req);
323
- } catch (err) {
324
- logger3().debug("failed to extract encoding", {
325
- error: stringifyError(err)
326
- });
327
- encoding = "json";
328
- }
329
- const output = serializeWithEncoding(
330
- encoding,
331
- {
332
- code,
333
- message,
334
- metadata: bufferToArrayBuffer(cbor.encode(metadata))
335
- },
336
- HTTP_RESPONSE_ERROR_VERSIONED
337
- );
338
- return c.body(output, { status: statusCode });
339
- }
340
-
341
- // src/inspector/utils.ts
342
- import crypto2 from "crypto";
343
- import { createMiddleware } from "hono/factory";
344
-
345
- // src/inspector/log.ts
346
- function inspectorLogger() {
347
- return getLogger("inspector");
348
- }
349
-
350
- // src/inspector/utils.ts
351
- function compareSecrets(providedSecret, validSecret) {
352
- if (providedSecret.length !== validSecret.length) {
353
- return false;
354
- }
355
- const encoder = new TextEncoder();
356
- const a = encoder.encode(providedSecret);
357
- const b = encoder.encode(validSecret);
358
- if (a.byteLength !== b.byteLength) {
359
- return false;
360
- }
361
- if (!crypto2.timingSafeEqual(a, b)) {
362
- return false;
363
- }
364
- return true;
365
- }
366
- var secureInspector = (runConfig) => createMiddleware(async (c, next) => {
367
- var _a, _b, _c;
368
- if (!runConfig.inspector.enabled) {
369
- return c.text("Inspector is not enabled", 503);
370
- }
371
- const userToken = (_a = c.req.header("Authorization")) == null ? void 0 : _a.replace("Bearer ", "");
372
- if (!userToken) {
373
- return c.text("Unauthorized", 401);
374
- }
375
- const inspectorToken = (_c = (_b = runConfig.inspector).token) == null ? void 0 : _c.call(_b);
376
- if (!inspectorToken) {
377
- return c.text("Unauthorized", 401);
378
- }
379
- const isValid = compareSecrets(userToken, inspectorToken);
380
- if (!isValid) {
381
- return c.text("Unauthorized", 401);
382
- }
383
- await next();
384
- });
385
- function getInspectorUrl(runConfig) {
386
- var _a, _b, _c, _d;
387
- if (!((_a = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _a.enabled)) {
388
- return "disabled";
389
- }
390
- const accessToken = (_c = (_b = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _b.token) == null ? void 0 : _c.call(_b);
391
- if (!accessToken) {
392
- inspectorLogger().warn(
393
- "Inspector Token is not set, but Inspector is enabled. Please set it in the run configuration `inspector.token` or via `RIVETKIT_INSPECTOR_TOKEN` environment variable. Inspector will not be accessible."
394
- );
395
- return "disabled";
396
- }
397
- const url = new URL("https://studio.rivet.gg");
398
- url.searchParams.set("t", accessToken);
399
- if ((_d = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _d.defaultEndpoint) {
400
- url.searchParams.set("u", runConfig.inspector.defaultEndpoint);
401
- }
402
- return url.href;
403
- }
404
-
405
- // src/actor/router.ts
406
- var PATH_CONNECT_WEBSOCKET = "/connect/websocket";
407
- var PATH_RAW_WEBSOCKET_PREFIX = "/raw/websocket/";
408
- function createActorRouter(runConfig, actorDriver) {
409
- const router = new Hono({ strict: false });
410
- router.use("*", loggerMiddleware(logger()));
411
- router.get("/", (c) => {
412
- return c.text(
413
- "This is an RivetKit actor.\n\nLearn more at https://rivetkit.org"
414
- );
415
- });
416
- router.get("/health", (c) => {
417
- return c.text("ok");
418
- });
419
- router.get(PATH_CONNECT_WEBSOCKET, async (c) => {
420
- var _a;
421
- const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
422
- if (upgradeWebSocket) {
423
- return upgradeWebSocket(async (c2) => {
424
- const encodingRaw = c2.req.header(HEADER_ENCODING);
425
- const connParamsRaw = c2.req.header(HEADER_CONN_PARAMS);
426
- const authDataRaw = c2.req.header(HEADER_AUTH_DATA);
427
- const encoding = EncodingSchema.parse(encodingRaw);
428
- const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
429
- const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
430
- return await handleWebSocketConnect(
431
- c2.req.raw,
432
- runConfig,
433
- actorDriver,
434
- c2.env.actorId,
435
- encoding,
436
- connParams,
437
- authData
438
- );
439
- })(c, noopNext());
440
- } else {
441
- return c.text(
442
- "WebSockets are not enabled for this driver. Use SSE instead.",
443
- 400
444
- );
445
- }
446
- });
447
- router.get("/connect/sse", async (c) => {
448
- const authDataRaw = c.req.header(HEADER_AUTH_DATA);
449
- let authData;
450
- if (authDataRaw) {
451
- authData = JSON.parse(authDataRaw);
452
- }
453
- return handleSseConnect(c, runConfig, actorDriver, c.env.actorId, authData);
454
- });
455
- router.post("/action/:action", async (c) => {
456
- const actionName = c.req.param("action");
457
- const authDataRaw = c.req.header(HEADER_AUTH_DATA);
458
- let authData;
459
- if (authDataRaw) {
460
- authData = JSON.parse(authDataRaw);
461
- }
462
- return handleAction(
463
- c,
464
- runConfig,
465
- actorDriver,
466
- actionName,
467
- c.env.actorId,
468
- authData
469
- );
470
- });
471
- router.post("/connections/message", async (c) => {
472
- const connId = c.req.header(HEADER_CONN_ID);
473
- const connToken = c.req.header(HEADER_CONN_TOKEN);
474
- if (!connId || !connToken) {
475
- throw new Error("Missing required parameters");
476
- }
477
- return handleConnectionMessage(
478
- c,
479
- runConfig,
480
- actorDriver,
481
- connId,
482
- connToken,
483
- c.env.actorId
484
- );
485
- });
486
- router.all("/raw/http/*", async (c) => {
487
- const authDataRaw = c.req.header(HEADER_AUTH_DATA);
488
- let authData;
489
- if (authDataRaw) {
490
- authData = JSON.parse(authDataRaw);
491
- }
492
- const actor2 = await actorDriver.loadActor(c.env.actorId);
493
- const url = new URL(c.req.url);
494
- const originalPath = url.pathname.replace(/^\/raw\/http/, "") || "/";
495
- const correctedUrl = new URL(originalPath + url.search, url.origin);
496
- const correctedRequest = new Request(correctedUrl, {
497
- method: c.req.method,
498
- headers: c.req.raw.headers,
499
- body: c.req.raw.body
500
- });
501
- logger().debug("rewriting http url", {
502
- from: c.req.url,
503
- to: correctedRequest.url
504
- });
505
- const response = await actor2.handleFetch(correctedRequest, {
506
- auth: authData
507
- });
508
- if (!response) {
509
- throw new InternalError("handleFetch returned void unexpectedly");
510
- }
511
- return response;
512
- });
513
- router.get(`${PATH_RAW_WEBSOCKET_PREFIX}*`, async (c) => {
514
- var _a;
515
- const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
516
- if (upgradeWebSocket) {
517
- return upgradeWebSocket(async (c2) => {
518
- const encodingRaw = c2.req.header(HEADER_ENCODING);
519
- const connParamsRaw = c2.req.header(HEADER_CONN_PARAMS);
520
- const authDataRaw = c2.req.header(HEADER_AUTH_DATA);
521
- const encoding = EncodingSchema.parse(encodingRaw);
522
- const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
523
- const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
524
- const url = new URL(c2.req.url);
525
- const pathWithQuery = c2.req.path + url.search;
526
- logger().debug("actor router raw websocket", {
527
- path: c2.req.path,
528
- url: c2.req.url,
529
- search: url.search,
530
- pathWithQuery
531
- });
532
- return await handleRawWebSocketHandler(
533
- c2.req.raw,
534
- pathWithQuery,
535
- actorDriver,
536
- c2.env.actorId,
537
- authData
538
- );
539
- })(c, noopNext());
540
- } else {
541
- return c.text(
542
- "WebSockets are not enabled for this driver. Use SSE instead.",
543
- 400
544
- );
545
- }
546
- });
547
- if (runConfig.inspector.enabled) {
548
- router.route(
549
- "/inspect",
550
- new Hono().use(secureInspector(runConfig), async (c, next) => {
551
- const inspector = (await actorDriver.loadActor(c.env.actorId)).inspector;
552
- invariant(inspector, "inspector not supported on this platform");
553
- c.set("inspector", inspector);
554
- await next();
555
- }).route("/", createActorInspectorRouter())
556
- );
557
- }
558
- router.notFound(handleRouteNotFound);
559
- router.onError(
560
- handleRouteError.bind(void 0, {
561
- // All headers to this endpoint are considered secure, so we can enable the expose internal error header for requests from the internal client
562
- enableExposeInternalError: true
563
- })
564
- );
565
- return router;
566
- }
567
-
568
- // src/actor/mod.ts
569
- function actor(input) {
570
- const config2 = ActorConfigSchema.parse(input);
571
- return new ActorDefinition(config2);
572
- }
573
-
574
- // src/common/inline-websocket-adapter2.ts
575
- import { WSContext } from "hono/ws";
576
- var LOGGER_NAME = "fake-event-source2";
577
- function logger4() {
578
- return getLogger(LOGGER_NAME);
579
- }
580
- var InlineWebSocketAdapter2 = class {
581
- // WebSocket readyState values
582
- CONNECTING = 0;
583
- OPEN = 1;
584
- CLOSING = 2;
585
- CLOSED = 3;
586
- // Private properties
587
- #handler;
588
- #wsContext;
589
- #readyState = 0;
590
- // Start in CONNECTING state
591
- #queuedMessages = [];
592
- // Event buffering is needed since events can be fired
593
- // before JavaScript has a chance to add event listeners (e.g. within the same tick)
594
- #bufferedEvents = [];
595
- // Event listeners with buffering
596
- #eventListeners = /* @__PURE__ */ new Map();
597
- constructor(handler) {
598
- this.#handler = handler;
599
- this.#wsContext = new WSContext({
600
- raw: this,
601
- send: (data) => {
602
- logger4().debug("WSContext.send called");
603
- this.#handleMessage(data);
604
- },
605
- close: (code, reason) => {
606
- logger4().debug("WSContext.close called", { code, reason });
607
- this.#handleClose(code || 1e3, reason || "");
608
- },
609
- // Set readyState to 1 (OPEN) since handlers expect an open connection
610
- readyState: 1
611
- });
612
- this.#initialize();
613
- }
614
- get readyState() {
615
- return this.#readyState;
616
- }
617
- get binaryType() {
618
- return "arraybuffer";
619
- }
620
- set binaryType(value) {
621
- }
622
- get bufferedAmount() {
623
- return 0;
624
- }
625
- get extensions() {
626
- return "";
627
- }
628
- get protocol() {
629
- return "";
630
- }
631
- get url() {
632
- return "";
633
- }
634
- send(data) {
635
- logger4().debug("send called", { readyState: this.readyState });
636
- if (this.readyState !== this.OPEN) {
637
- const error = new Error("WebSocket is not open");
638
- logger4().warn("cannot send message, websocket not open", {
639
- readyState: this.readyState,
640
- dataType: typeof data,
641
- dataLength: typeof data === "string" ? data.length : "binary",
642
- error
643
- });
644
- this.#fireError(error);
645
- return;
646
- }
647
- this.#handler.onMessage({ data }, this.#wsContext);
648
- }
649
- /**
650
- * Closes the connection
651
- */
652
- close(code = 1e3, reason = "") {
653
- if (this.readyState === this.CLOSED || this.readyState === this.CLOSING) {
654
- return;
655
- }
656
- logger4().debug("closing fake websocket", { code, reason });
657
- this.#readyState = this.CLOSING;
658
- try {
659
- this.#handler.onClose({ code, reason, wasClean: true }, this.#wsContext);
660
- } catch (err) {
661
- logger4().error("error closing websocket", { error: err });
662
- } finally {
663
- this.#readyState = this.CLOSED;
664
- const closeEvent = {
665
- type: "close",
666
- wasClean: code === 1e3,
667
- code,
668
- reason,
669
- target: this,
670
- currentTarget: this
671
- };
672
- this.#fireClose(closeEvent);
673
- }
674
- }
675
- /**
676
- * Initialize the connection with the handler
677
- */
678
- async #initialize() {
679
- try {
680
- logger4().debug("fake websocket initializing");
681
- logger4().debug("calling handler.onOpen with WSContext");
682
- this.#handler.onOpen(void 0, this.#wsContext);
683
- this.#readyState = this.OPEN;
684
- logger4().debug("fake websocket initialized and now OPEN");
685
- this.#fireOpen();
686
- if (this.#queuedMessages.length > 0) {
687
- if (this.readyState !== this.OPEN) {
688
- logger4().warn("socket no longer open, dropping queued messages");
689
- return;
690
- }
691
- logger4().debug(
692
- `now processing ${this.#queuedMessages.length} queued messages`
693
- );
694
- const messagesToProcess = [...this.#queuedMessages];
695
- this.#queuedMessages = [];
696
- for (const message of messagesToProcess) {
697
- logger4().debug("processing queued message");
698
- this.#handleMessage(message);
699
- }
700
- }
701
- } catch (err) {
702
- logger4().error("error opening fake websocket", {
703
- error: err,
704
- errorMessage: err instanceof Error ? err.message : String(err),
705
- stack: err instanceof Error ? err.stack : void 0
706
- });
707
- this.#fireError(err);
708
- this.close(1011, "Internal error during initialization");
709
- }
710
- }
711
- /**
712
- * Handle messages received from the server via the WSContext
713
- */
714
- #handleMessage(data) {
715
- if (this.readyState !== this.OPEN) {
716
- logger4().debug("message received before socket is OPEN, queuing", {
717
- readyState: this.readyState,
718
- dataType: typeof data,
719
- dataLength: typeof data === "string" ? data.length : data instanceof ArrayBuffer ? data.byteLength : data instanceof Uint8Array ? data.byteLength : "unknown"
720
- });
721
- this.#queuedMessages.push(data);
722
- return;
723
- }
724
- logger4().debug("fake websocket received message from server", {
725
- dataType: typeof data,
726
- dataLength: typeof data === "string" ? data.length : data instanceof ArrayBuffer ? data.byteLength : data instanceof Uint8Array ? data.byteLength : "unknown"
727
- });
728
- const event = {
729
- type: "message",
730
- data,
731
- target: this,
732
- currentTarget: this
733
- };
734
- this.#dispatchEvent("message", event);
735
- }
736
- #handleClose(code, reason) {
737
- if (this.readyState === this.CLOSED) return;
738
- this.#readyState = this.CLOSED;
739
- const event = {
740
- type: "close",
741
- code,
742
- reason,
743
- wasClean: code === 1e3,
744
- target: this,
745
- currentTarget: this
746
- };
747
- this.#dispatchEvent("close", event);
748
- }
749
- addEventListener(type, listener) {
750
- if (!this.#eventListeners.has(type)) {
751
- this.#eventListeners.set(type, []);
752
- }
753
- this.#eventListeners.get(type).push(listener);
754
- this.#flushBufferedEvents(type);
755
- }
756
- removeEventListener(type, listener) {
757
- const listeners = this.#eventListeners.get(type);
758
- if (listeners) {
759
- const index = listeners.indexOf(listener);
760
- if (index !== -1) {
761
- listeners.splice(index, 1);
762
- }
763
- }
764
- }
765
- #dispatchEvent(type, event) {
766
- const listeners = this.#eventListeners.get(type);
767
- if (listeners && listeners.length > 0) {
768
- logger4().debug(
769
- `dispatching ${type} event to ${listeners.length} listeners`
770
- );
771
- for (const listener of listeners) {
772
- try {
773
- listener(event);
774
- } catch (err) {
775
- logger4().error(`error in ${type} event listener`, { error: err });
776
- }
777
- }
778
- } else {
779
- logger4().debug(`no ${type} listeners registered, buffering event`);
780
- this.#bufferedEvents.push({ type, event });
781
- }
782
- switch (type) {
783
- case "open":
784
- if (this.#onopen) {
785
- try {
786
- this.#onopen(event);
787
- } catch (error) {
788
- logger4().error("error in onopen handler", { error });
789
- }
790
- }
791
- break;
792
- case "close":
793
- if (this.#onclose) {
794
- try {
795
- this.#onclose(event);
796
- } catch (error) {
797
- logger4().error("error in onclose handler", { error });
798
- }
799
- }
800
- break;
801
- case "error":
802
- if (this.#onerror) {
803
- try {
804
- this.#onerror(event);
805
- } catch (error) {
806
- logger4().error("error in onerror handler", { error });
807
- }
808
- }
809
- break;
810
- case "message":
811
- if (this.#onmessage) {
812
- try {
813
- this.#onmessage(event);
814
- } catch (error) {
815
- logger4().error("error in onmessage handler", { error });
816
- }
817
- }
818
- break;
819
- }
820
- }
821
- dispatchEvent(event) {
822
- this.#dispatchEvent(event.type, event);
823
- return true;
824
- }
825
- #flushBufferedEvents(type) {
826
- const eventsToFlush = this.#bufferedEvents.filter(
827
- (buffered) => buffered.type === type
828
- );
829
- this.#bufferedEvents = this.#bufferedEvents.filter(
830
- (buffered) => buffered.type !== type
831
- );
832
- for (const { event } of eventsToFlush) {
833
- this.#dispatchEvent(type, event);
834
- }
835
- }
836
- #fireOpen() {
837
- try {
838
- const event = {
839
- type: "open",
840
- target: this,
841
- currentTarget: this
842
- };
843
- this.#dispatchEvent("open", event);
844
- } catch (err) {
845
- logger4().error("error in open event", { error: err });
846
- }
847
- }
848
- #fireClose(event) {
849
- try {
850
- this.#dispatchEvent("close", event);
851
- } catch (err) {
852
- logger4().error("error in close event", { error: err });
853
- }
854
- }
855
- #fireError(error) {
856
- try {
857
- const event = {
858
- type: "error",
859
- target: this,
860
- currentTarget: this,
861
- error,
862
- message: error instanceof Error ? error.message : String(error)
863
- };
864
- this.#dispatchEvent("error", event);
865
- } catch (err) {
866
- logger4().error("error in error event", { error: err });
867
- }
868
- logger4().error("websocket error", { error });
869
- }
870
- // Event handler properties with getters/setters
871
- #onopen = null;
872
- #onclose = null;
873
- #onerror = null;
874
- #onmessage = null;
875
- get onopen() {
876
- return this.#onopen;
877
- }
878
- set onopen(handler) {
879
- this.#onopen = handler;
880
- }
881
- get onclose() {
882
- return this.#onclose;
883
- }
884
- set onclose(handler) {
885
- this.#onclose = handler;
886
- }
887
- get onerror() {
888
- return this.#onerror;
889
- }
890
- set onerror(handler) {
891
- this.#onerror = handler;
892
- }
893
- get onmessage() {
894
- return this.#onmessage;
895
- }
896
- set onmessage(handler) {
897
- this.#onmessage = handler;
898
- }
899
- };
900
-
901
- // src/drivers/engine/actor-driver.ts
902
- import { Runner } from "@rivetkit/engine-runner";
903
- import * as cbor2 from "cbor-x";
904
- import { WSContext as WSContext2 } from "hono/ws";
905
- import invariant2 from "invariant";
906
-
907
- // src/drivers/engine/keys.ts
908
- var EMPTY_KEY = "/";
909
- var KEY_SEPARATOR = "/";
910
- function serializeActorKey(key) {
911
- if (key.length === 0) {
912
- return EMPTY_KEY;
913
- }
914
- const escapedParts = key.map((part) => {
915
- if (part === "") {
916
- return "\\0";
917
- }
918
- let escaped = part.replace(/\\/g, "\\\\");
919
- escaped = escaped.replace(/\//g, `\\${KEY_SEPARATOR}`);
920
- return escaped;
921
- });
922
- return escapedParts.join(KEY_SEPARATOR);
923
- }
924
- function deserializeActorKey(keyString) {
925
- if (keyString === void 0 || keyString === null || keyString === EMPTY_KEY) {
926
- return [];
927
- }
928
- const parts = [];
929
- let currentPart = "";
930
- let escaping = false;
931
- let isEmptyStringMarker = false;
932
- for (let i = 0; i < keyString.length; i++) {
933
- const char = keyString[i];
934
- if (escaping) {
935
- if (char === "0") {
936
- isEmptyStringMarker = true;
937
- } else {
938
- currentPart += char;
939
- }
940
- escaping = false;
941
- } else if (char === "\\") {
942
- escaping = true;
943
- } else if (char === KEY_SEPARATOR) {
944
- if (isEmptyStringMarker) {
945
- parts.push("");
946
- isEmptyStringMarker = false;
947
- } else {
948
- parts.push(currentPart);
949
- }
950
- currentPart = "";
951
- } else {
952
- currentPart += char;
953
- }
954
- }
955
- if (escaping) {
956
- parts.push(currentPart + "\\");
957
- } else if (isEmptyStringMarker) {
958
- parts.push("");
959
- } else if (currentPart !== "" || parts.length > 0) {
960
- parts.push(currentPart);
961
- }
962
- return parts;
963
- }
964
-
965
- // src/drivers/engine/kv.ts
966
- var KEYS = {
967
- PERSIST_DATA: Uint8Array.from([1, 1])
968
- };
969
-
970
- // src/drivers/engine/log.ts
971
- var LOGGER_NAME2 = "driver-engine";
972
- function logger5() {
973
- return getLogger(LOGGER_NAME2);
974
- }
975
-
976
- // src/drivers/engine/actor-driver.ts
977
- var EngineActorDriver = class {
978
- #registryConfig;
979
- #runConfig;
980
- #managerDriver;
981
- #inlineClient;
982
- #config;
983
- #runner;
984
- #actors = /* @__PURE__ */ new Map();
985
- #actorRouter;
986
- #version = 1;
987
- // Version for the runner protocol
988
- constructor(registryConfig, runConfig, managerDriver, inlineClient, config2) {
989
- this.#registryConfig = registryConfig;
990
- this.#runConfig = runConfig;
991
- this.#managerDriver = managerDriver;
992
- this.#inlineClient = inlineClient;
993
- this.#config = config2;
994
- this.#actorRouter = createActorRouter(runConfig, this);
995
- let hasDisconnected = false;
996
- const runnerConfig = {
997
- version: this.#version,
998
- endpoint: config2.endpoint,
999
- pegboardEndpoint: config2.pegboardEndpoint,
1000
- namespace: config2.namespace,
1001
- totalSlots: config2.totalSlots,
1002
- runnerName: config2.runnerName,
1003
- runnerKey: config2.runnerKey,
1004
- metadata: {
1005
- inspectorToken: this.#runConfig.inspector.token()
1006
- },
1007
- prepopulateActorNames: Object.fromEntries(
1008
- Object.keys(this.#registryConfig.use).map((name) => [
1009
- name,
1010
- { metadata: {} }
1011
- ])
1012
- ),
1013
- onConnected: () => {
1014
- if (hasDisconnected) {
1015
- logger5().info("runner reconnected", {
1016
- namespace: this.#config.namespace,
1017
- runnerName: this.#config.runnerName
1018
- });
1019
- } else {
1020
- logger5().debug("runner connected", {
1021
- namespace: this.#config.namespace,
1022
- runnerName: this.#config.runnerName
1023
- });
1024
- }
1025
- },
1026
- onDisconnected: () => {
1027
- logger5().warn("runner disconnected", {
1028
- namespace: this.#config.namespace,
1029
- runnerName: this.#config.runnerName
1030
- });
1031
- hasDisconnected = true;
1032
- },
1033
- fetch: this.#runnerFetch.bind(this),
1034
- websocket: this.#runnerWebSocket.bind(this),
1035
- onActorStart: this.#runnerOnActorStart.bind(this),
1036
- onActorStop: this.#runnerOnActorStop.bind(this)
1037
- };
1038
- this.#runner = new Runner(runnerConfig);
1039
- this.#runner.start();
1040
- logger5().debug("engine runner started", {
1041
- endpoint: config2.endpoint,
1042
- namespace: config2.namespace,
1043
- runnerName: config2.runnerName
1044
- });
1045
- }
1046
- async #loadActorHandler(actorId) {
1047
- const handler = this.#actors.get(actorId);
1048
- if (!handler) throw new Error(`Actor handler does not exist ${actorId}`);
1049
- if (handler.actorStartPromise) await handler.actorStartPromise.promise;
1050
- if (!handler.actor) throw new Error("Actor should be loaded");
1051
- return handler;
1052
- }
1053
- async loadActor(actorId) {
1054
- const handler = await this.#loadActorHandler(actorId);
1055
- if (!handler.actor) throw new Error(`Actor ${actorId} failed to load`);
1056
- return handler.actor;
1057
- }
1058
- getGenericConnGlobalState(actorId) {
1059
- const handler = this.#actors.get(actorId);
1060
- if (!handler) {
1061
- throw new Error(`Actor ${actorId} not loaded`);
1062
- }
1063
- return handler.genericConnGlobalState;
1064
- }
1065
- getContext(actorId) {
1066
- return {};
1067
- }
1068
- async readPersistedData(actorId) {
1069
- const handler = this.#actors.get(actorId);
1070
- if (!handler) throw new Error(`Actor ${actorId} not loaded`);
1071
- if (handler.persistedData) return handler.persistedData;
1072
- const [value] = await this.#runner.kvGet(actorId, [KEYS.PERSIST_DATA]);
1073
- if (value !== null) {
1074
- handler.persistedData = value;
1075
- return value;
1076
- } else {
1077
- return void 0;
1078
- }
1079
- }
1080
- async writePersistedData(actorId, data) {
1081
- const handler = this.#actors.get(actorId);
1082
- if (!handler) throw new Error(`Actor ${actorId} not loaded`);
1083
- handler.persistedData = data;
1084
- await this.#runner.kvPut(actorId, [[KEYS.PERSIST_DATA, data]]);
1085
- }
1086
- async setAlarm(actor2, timestamp) {
1087
- }
1088
- async getDatabase(_actorId) {
1089
- return void 0;
1090
- }
1091
- // Runner lifecycle callbacks
1092
- async #runnerOnActorStart(actorId, generation, config2) {
1093
- var _a;
1094
- logger5().debug("runner actor starting", {
1095
- actorId,
1096
- name: config2.name,
1097
- key: config2.key,
1098
- generation
1099
- });
1100
- let input;
1101
- if (config2.input) {
1102
- input = cbor2.decode(config2.input);
1103
- }
1104
- let handler = this.#actors.get(actorId);
1105
- if (!handler) {
1106
- handler = {
1107
- genericConnGlobalState: new GenericConnGlobalState(),
1108
- actorStartPromise: Promise.withResolvers(),
1109
- persistedData: serializeEmptyPersistData(input)
1110
- };
1111
- this.#actors.set(actorId, handler);
1112
- }
1113
- const name = config2.name;
1114
- invariant2(config2.key, "actor should have a key");
1115
- const key = deserializeActorKey(config2.key);
1116
- const definition = lookupInRegistry(
1117
- this.#registryConfig,
1118
- config2.name
1119
- // TODO: Remove cast
1120
- );
1121
- handler.actor = definition.instantiate();
1122
- const connDrivers = createGenericConnDrivers(
1123
- handler.genericConnGlobalState
1124
- );
1125
- await handler.actor.start(
1126
- connDrivers,
1127
- this,
1128
- this.#inlineClient,
1129
- actorId,
1130
- name,
1131
- key,
1132
- "unknown"
1133
- // TODO: Add regions
1134
- );
1135
- (_a = handler.actorStartPromise) == null ? void 0 : _a.resolve();
1136
- handler.actorStartPromise = void 0;
1137
- logger5().debug("runner actor started", { actorId, name, key });
1138
- }
1139
- async #runnerOnActorStop(actorId, generation) {
1140
- logger5().debug("runner actor stopping", { actorId, generation });
1141
- const handler = this.#actors.get(actorId);
1142
- if (handler == null ? void 0 : handler.actor) {
1143
- await handler.actor._stop();
1144
- this.#actors.delete(actorId);
1145
- }
1146
- logger5().debug("runner actor stopped", { actorId });
1147
- }
1148
- async #runnerFetch(actorId, request) {
1149
- logger5().debug("runner fetch", {
1150
- actorId,
1151
- url: request.url,
1152
- method: request.method
1153
- });
1154
- return await this.#actorRouter.fetch(request, { actorId });
1155
- }
1156
- async #runnerWebSocket(actorId, websocketRaw, request) {
1157
- const websocket = websocketRaw;
1158
- logger5().debug("runner websocket", { actorId, url: request.url });
1159
- const url = new URL(request.url);
1160
- const encodingRaw = request.headers.get(HEADER_ENCODING);
1161
- const connParamsRaw = request.headers.get(HEADER_CONN_PARAMS);
1162
- const authDataRaw = request.headers.get(HEADER_AUTH_DATA);
1163
- const encoding = EncodingSchema.parse(encodingRaw);
1164
- const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
1165
- const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
1166
- let wsHandlerPromise;
1167
- if (url.pathname === PATH_CONNECT_WEBSOCKET) {
1168
- wsHandlerPromise = handleWebSocketConnect(
1169
- request,
1170
- this.#runConfig,
1171
- this,
1172
- actorId,
1173
- encoding,
1174
- connParams,
1175
- authData
1176
- );
1177
- } else if (url.pathname.startsWith(PATH_RAW_WEBSOCKET_PREFIX)) {
1178
- wsHandlerPromise = handleRawWebSocketHandler(
1179
- request,
1180
- url.pathname + url.search,
1181
- this,
1182
- actorId,
1183
- authData
1184
- );
1185
- } else {
1186
- throw new Error(`Unreachable path: ${url.pathname}`);
1187
- }
1188
- const wsContext = new WSContext2(websocket);
1189
- wsHandlerPromise.catch((err) => {
1190
- logger5().error("building websocket handlers errored", { err });
1191
- wsContext.close(1011, `${err}`);
1192
- });
1193
- if (websocket.readyState === 1) {
1194
- wsHandlerPromise.then((x) => {
1195
- var _a;
1196
- return (_a = x.onOpen) == null ? void 0 : _a.call(x, new Event("open"), wsContext);
1197
- });
1198
- } else {
1199
- websocket.addEventListener("open", (event) => {
1200
- wsHandlerPromise.then((x) => {
1201
- var _a;
1202
- return (_a = x.onOpen) == null ? void 0 : _a.call(x, event, wsContext);
1203
- });
1204
- });
1205
- }
1206
- websocket.addEventListener("message", (event) => {
1207
- wsHandlerPromise.then((x) => {
1208
- var _a;
1209
- return (_a = x.onMessage) == null ? void 0 : _a.call(x, event, wsContext);
1210
- });
1211
- });
1212
- websocket.addEventListener("close", (event) => {
1213
- wsHandlerPromise.then((x) => {
1214
- var _a;
1215
- return (_a = x.onClose) == null ? void 0 : _a.call(x, event, wsContext);
1216
- });
1217
- });
1218
- websocket.addEventListener("error", (event) => {
1219
- wsHandlerPromise.then((x) => {
1220
- var _a;
1221
- return (_a = x.onError) == null ? void 0 : _a.call(x, event, wsContext);
1222
- });
1223
- });
1224
- }
1225
- async sleep(actorId) {
1226
- this.#runner.sleepActor(actorId);
1227
- }
1228
- async shutdown(immediate) {
1229
- logger5().info("stopping engine actor driver");
1230
- await this.#runner.shutdown(immediate);
1231
- }
1232
- };
1233
-
1234
- // src/drivers/engine/config.ts
1235
- import { z as z2 } from "zod";
1236
- var ConfigSchema = z2.object({
1237
- app: z2.custom().optional(),
1238
- endpoint: z2.string().default(
1239
- () => getEnvUniversal("RIVET_ENGINE") ?? "http://localhost:7080"
1240
- ),
1241
- pegboardEndpoint: z2.string().optional(),
1242
- namespace: z2.string().default(() => getEnvUniversal("RIVET_NAMESPACE") ?? "default"),
1243
- runnerName: z2.string().default(() => getEnvUniversal("RIVET_RUNNER") ?? "rivetkit"),
1244
- // TODO: Automatically attempt ot determine key by common env vars (e.g. k8s pod name)
1245
- runnerKey: z2.string().default(
1246
- () => getEnvUniversal("RIVET_RUNNER_KEY") ?? crypto.randomUUID()
1247
- ),
1248
- totalSlots: z2.number().default(1e5),
1249
- addresses: z2.record(
1250
- z2.object({
1251
- host: z2.string(),
1252
- port: z2.number()
1253
- })
1254
- ).default({ main: { host: "127.0.0.1", port: 5051 } })
1255
- }).default({});
1256
-
1257
- // src/drivers/engine/manager-driver.ts
1258
- import * as cbor3 from "cbor-x";
1259
- import invariant3 from "invariant";
1260
-
1261
- // src/drivers/engine/api-utils.ts
1262
- var EngineApiError = class extends Error {
1263
- constructor(group, code, message) {
1264
- super(message || `Engine API error: ${group}/${code}`);
1265
- this.group = group;
1266
- this.code = code;
1267
- this.name = "EngineApiError";
1268
- }
1269
- };
1270
- async function apiCall(endpoint, namespace, method, path3, body) {
1271
- const url = `${endpoint}${path3}${path3.includes("?") ? "&" : "?"}namespace=${encodeURIComponent(namespace)}`;
1272
- const options = {
1273
- method,
1274
- headers: {
1275
- "Content-Type": "application/json"
1276
- }
1277
- };
1278
- if (body !== void 0 && method !== "GET") {
1279
- options.body = JSON.stringify(body);
1280
- }
1281
- logger5().debug("making api call", { method, url });
1282
- const response = await fetch(url, options);
1283
- if (!response.ok) {
1284
- const errorText = await response.text();
1285
- logger5().error("api call failed", {
1286
- status: response.status,
1287
- statusText: response.statusText,
1288
- error: errorText,
1289
- method,
1290
- path: path3
1291
- });
1292
- try {
1293
- const errorData = JSON.parse(errorText);
1294
- if (errorData.kind === "error" && errorData.group && errorData.code) {
1295
- throw new EngineApiError(
1296
- errorData.group,
1297
- errorData.code,
1298
- errorData.message
1299
- );
1300
- }
1301
- } catch (parseError) {
1302
- }
1303
- throw new Error(
1304
- `API call failed: ${response.status} ${response.statusText}`
1305
- );
1306
- }
1307
- return response.json();
1308
- }
1309
-
1310
- // src/drivers/engine/api-endpoints.ts
1311
- async function getActor(config2, actorId) {
1312
- return apiCall(
1313
- config2.endpoint,
1314
- config2.namespace,
1315
- "GET",
1316
- `/actors/${encodeURIComponent(actorId)}`
1317
- );
1318
- }
1319
- async function getActorById(config2, name, key) {
1320
- const serializedKey = serializeActorKey(key);
1321
- return apiCall(
1322
- config2.endpoint,
1323
- config2.namespace,
1324
- "GET",
1325
- `/actors/by-id?name=${encodeURIComponent(name)}&key=${encodeURIComponent(serializedKey)}`
1326
- );
1327
- }
1328
- async function getOrCreateActorById(config2, request) {
1329
- return apiCall(
1330
- config2.endpoint,
1331
- config2.namespace,
1332
- "PUT",
1333
- `/actors/by-id`,
1334
- request
1335
- );
1336
- }
1337
- async function createActor(config2, request) {
1338
- return apiCall(
1339
- config2.endpoint,
1340
- config2.namespace,
1341
- "POST",
1342
- `/actors`,
1343
- request
1344
- );
1345
- }
1346
- async function destroyActor(config2, actorId) {
1347
- return apiCall(
1348
- config2.endpoint,
1349
- config2.namespace,
1350
- "DELETE",
1351
- `/actors/${encodeURIComponent(actorId)}`
1352
- );
1353
- }
1354
-
1355
- // src/drivers/engine/ws-proxy.ts
1356
- async function createWebSocketProxy(c, targetUrl, headers) {
1357
- const WebSocket2 = await importWebSocket();
1358
- for (const [k, v] of c.req.raw.headers.entries()) {
1359
- if (!k.startsWith("sec-") && k !== "connection" && k !== "upgrade") {
1360
- headers[k] = v;
1361
- }
1362
- }
1363
- const state = {};
1364
- return {
1365
- onOpen: async (event, clientWs) => {
1366
- logger5().debug("client websocket connected", { targetUrl });
1367
- if (clientWs.readyState !== 1) {
1368
- logger5().warn("client websocket not open on connection", {
1369
- targetUrl,
1370
- readyState: clientWs.readyState
1371
- });
1372
- return;
1373
- }
1374
- const targetWs = new WebSocket2(targetUrl, { headers });
1375
- state.targetWs = targetWs;
1376
- state.connectPromise = new Promise((resolve, reject) => {
1377
- targetWs.addEventListener("open", () => {
1378
- logger5().debug("target websocket connected", { targetUrl });
1379
- if (clientWs.readyState !== 1) {
1380
- logger5().warn("client websocket closed before target connected", {
1381
- targetUrl,
1382
- clientReadyState: clientWs.readyState
1383
- });
1384
- targetWs.close(1001, "Client disconnected");
1385
- reject(new Error("Client disconnected"));
1386
- return;
1387
- }
1388
- resolve();
1389
- });
1390
- targetWs.addEventListener("error", (error) => {
1391
- logger5().warn("target websocket error during connection", {
1392
- targetUrl
1393
- });
1394
- reject(error);
1395
- });
1396
- });
1397
- state.targetWs.addEventListener("message", (event2) => {
1398
- if (typeof event2.data === "string" || event2.data instanceof ArrayBuffer) {
1399
- clientWs.send(event2.data);
1400
- } else if (event2.data instanceof Blob) {
1401
- event2.data.arrayBuffer().then((buffer) => {
1402
- clientWs.send(buffer);
1403
- });
1404
- }
1405
- });
1406
- state.targetWs.addEventListener("close", (event2) => {
1407
- logger5().debug("target websocket closed", {
1408
- targetUrl,
1409
- code: event2.code,
1410
- reason: event2.reason
1411
- });
1412
- closeWebSocketIfOpen(clientWs, event2.code, event2.reason);
1413
- });
1414
- state.targetWs.addEventListener("error", (error) => {
1415
- logger5().error("target websocket error", { targetUrl, error });
1416
- closeWebSocketIfOpen(clientWs, 1011, "Target WebSocket error");
1417
- });
1418
- },
1419
- onMessage: async (event, clientWs) => {
1420
- if (!state.targetWs || !state.connectPromise) {
1421
- logger5().error("websocket state not initialized", { targetUrl });
1422
- return;
1423
- }
1424
- try {
1425
- await state.connectPromise;
1426
- if (state.targetWs.readyState === WebSocket2.OPEN) {
1427
- state.targetWs.send(event.data);
1428
- } else {
1429
- logger5().warn("target websocket not open", {
1430
- targetUrl,
1431
- readyState: state.targetWs.readyState
1432
- });
1433
- }
1434
- } catch (error) {
1435
- logger5().error("failed to connect to target websocket", {
1436
- targetUrl,
1437
- error
1438
- });
1439
- closeWebSocketIfOpen(clientWs, 1011, "Failed to connect to target");
1440
- }
1441
- },
1442
- onClose: (event, clientWs) => {
1443
- logger5().debug("client websocket closed", {
1444
- targetUrl,
1445
- code: event.code,
1446
- reason: event.reason,
1447
- wasClean: event.wasClean
1448
- });
1449
- if (state.targetWs) {
1450
- if (state.targetWs.readyState === WebSocket2.OPEN || state.targetWs.readyState === WebSocket2.CONNECTING) {
1451
- state.targetWs.close(1e3, event.reason || "Client disconnected");
1452
- }
1453
- }
1454
- },
1455
- onError: (event, clientWs) => {
1456
- logger5().error("client websocket error", { targetUrl, event });
1457
- if (state.targetWs) {
1458
- if (state.targetWs.readyState === WebSocket2.OPEN) {
1459
- state.targetWs.close(1011, "Client WebSocket error");
1460
- } else if (state.targetWs.readyState === WebSocket2.CONNECTING) {
1461
- state.targetWs.close();
1462
- }
1463
- }
1464
- }
1465
- };
1466
- }
1467
- function closeWebSocketIfOpen(ws, code, reason) {
1468
- if (ws.readyState === 1) {
1469
- ws.close(code, reason);
1470
- } else if ("close" in ws && ws.readyState === WebSocket.OPEN) {
1471
- ws.close(code, reason);
1472
- }
1473
- }
1474
-
1475
- // src/drivers/engine/manager-driver.ts
1476
- var EngineManagerDriver = class {
1477
- #config;
1478
- #runConfig;
1479
- #importWebSocketPromise;
1480
- constructor(config2, runConfig) {
1481
- this.#config = config2;
1482
- this.#runConfig = runConfig;
1483
- if (!this.#runConfig.inspector.token()) {
1484
- const token = generateRandomString();
1485
- this.#runConfig.inspector.token = () => token;
1486
- }
1487
- this.#importWebSocketPromise = importWebSocket();
1488
- }
1489
- async sendRequest(actorId, actorRequest) {
1490
- logger5().debug("sending request to actor via guard", {
1491
- actorId,
1492
- method: actorRequest.method,
1493
- url: actorRequest.url
1494
- });
1495
- return this.#forwardHttpRequest(actorRequest, actorId);
1496
- }
1497
- async openWebSocket(path3, actorId, encoding, params) {
1498
- const WebSocket2 = await this.#importWebSocketPromise;
1499
- const guardUrl = `${this.#config.endpoint}${path3}`;
1500
- logger5().debug("opening websocket to actor via guard", {
1501
- actorId,
1502
- path: path3,
1503
- guardUrl
1504
- });
1505
- const ws = new WebSocket2(guardUrl, {
1506
- headers: buildGuardHeadersForWebSocket(actorId, encoding, params)
1507
- });
1508
- logger5().debug("websocket connection opened", { actorId });
1509
- return ws;
1510
- }
1511
- async proxyRequest(_c, actorRequest, actorId) {
1512
- logger5().debug("forwarding request to actor via guard", {
1513
- actorId,
1514
- method: actorRequest.method,
1515
- url: actorRequest.url,
1516
- hasBody: !!actorRequest.body
1517
- });
1518
- return this.#forwardHttpRequest(actorRequest, actorId);
1519
- }
1520
- async proxyWebSocket(c, path3, actorId, encoding, params, authData) {
1521
- var _a, _b;
1522
- const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
1523
- invariant3(upgradeWebSocket, "missing getUpgradeWebSocket");
1524
- const guardUrl = `${this.#config.endpoint}${path3}`;
1525
- const wsGuardUrl = guardUrl.replace("http://", "ws://");
1526
- logger5().debug("forwarding websocket to actor via guard", {
1527
- actorId,
1528
- path: path3,
1529
- guardUrl
1530
- });
1531
- const headers = buildGuardHeadersForWebSocket(
1532
- actorId,
1533
- encoding,
1534
- params,
1535
- authData
1536
- );
1537
- const args = await createWebSocketProxy(c, wsGuardUrl, headers);
1538
- return await upgradeWebSocket(() => args)(c, noopNext());
1539
- }
1540
- extraStartupLog() {
1541
- return {
1542
- engine: this.#config.endpoint,
1543
- namespace: this.#config.namespace,
1544
- runner: this.#config.runnerName,
1545
- address: Object.values(this.#config.addresses).map((v) => `${v.host}:${v.port}`).join(", ")
1546
- };
1547
- }
1548
- async getForId({
1549
- c,
1550
- name,
1551
- actorId
1552
- }) {
1553
- try {
1554
- const response = await getActor(this.#config, actorId);
1555
- if (response.actor.name !== name) {
1556
- logger5().debug("actor name mismatch from api", {
1557
- actorId,
1558
- apiName: response.actor.name,
1559
- requestedName: name
1560
- });
1561
- return void 0;
1562
- }
1563
- const keyRaw = response.actor.key;
1564
- invariant3(keyRaw, `actor ${actorId} should have key`);
1565
- const key = deserializeActorKey(keyRaw);
1566
- return {
1567
- actorId,
1568
- name,
1569
- key
1570
- };
1571
- } catch (error) {
1572
- if (error instanceof EngineApiError && error.group === "actor" && error.code === "not_found") {
1573
- return void 0;
1574
- }
1575
- throw error;
1576
- }
1577
- }
1578
- async getWithKey({
1579
- c,
1580
- name,
1581
- key
1582
- }) {
1583
- logger5().debug("getWithKey: searching for actor", { name, key });
1584
- try {
1585
- const response = await getActorById(this.#config, name, key);
1586
- if (!response.actor_id) {
1587
- return void 0;
1588
- }
1589
- const actorId = response.actor_id;
1590
- logger5().debug("getWithKey: found actor via api", {
1591
- actorId,
1592
- name,
1593
- key
1594
- });
1595
- return {
1596
- actorId,
1597
- name,
1598
- key
1599
- };
1600
- } catch (error) {
1601
- if (error instanceof EngineApiError && error.group === "actor" && error.code === "not_found") {
1602
- return void 0;
1603
- }
1604
- throw error;
1605
- }
1606
- }
1607
- async getOrCreateWithKey(input) {
1608
- const { c, name, key, input: actorInput, region } = input;
1609
- logger5().info(
1610
- "getOrCreateWithKey: getting or creating actor via engine api",
1611
- {
1612
- name,
1613
- key
1614
- }
1615
- );
1616
- const response = await getOrCreateActorById(this.#config, {
1617
- name,
1618
- key: serializeActorKey(key),
1619
- runner_name_selector: this.#config.runnerName,
1620
- input: input ? cbor3.encode(actorInput).toString("base64") : void 0,
1621
- crash_policy: "sleep"
1622
- });
1623
- const actorId = response.actor_id;
1624
- logger5().info("getOrCreateWithKey: actor ready", {
1625
- actorId,
1626
- name,
1627
- key,
1628
- created: response.created
1629
- });
1630
- return {
1631
- actorId,
1632
- name,
1633
- key
1634
- };
1635
- }
1636
- async createActor({
1637
- c,
1638
- name,
1639
- key,
1640
- input
1641
- }) {
1642
- const existingActor = await this.getWithKey({ c, name, key });
1643
- if (existingActor) {
1644
- throw new ActorAlreadyExists(name, key);
1645
- }
1646
- logger5().info("creating actor via engine api", { name, key });
1647
- const result = await createActor(this.#config, {
1648
- name,
1649
- runner_name_selector: this.#config.runnerName,
1650
- key: serializeActorKey(key),
1651
- input: input ? cbor3.encode(input).toString("base64") : null,
1652
- crash_policy: "sleep"
1653
- });
1654
- const actorId = result.actor.actor_id;
1655
- logger5().info("actor created", { actorId, name, key });
1656
- return {
1657
- actorId,
1658
- name,
1659
- key
1660
- };
1661
- }
1662
- async destroyActor(actorId) {
1663
- logger5().info("destroying actor via engine api", { actorId });
1664
- await destroyActor(this.#config, actorId);
1665
- logger5().info("actor destroyed", { actorId });
1666
- }
1667
- async #forwardHttpRequest(actorRequest, actorId) {
1668
- const url = new URL(actorRequest.url);
1669
- const guardUrl = `${this.#config.endpoint}${url.pathname}${url.search}`;
1670
- let bodyToSend = null;
1671
- const guardHeaders = buildGuardHeadersForHttp(actorRequest, actorId);
1672
- if (actorRequest.body && actorRequest.method !== "GET" && actorRequest.method !== "HEAD") {
1673
- if (actorRequest.bodyUsed) {
1674
- throw new Error("Request body has already been consumed");
1675
- }
1676
- const clonedRequest = actorRequest.clone();
1677
- bodyToSend = await clonedRequest.arrayBuffer();
1678
- guardHeaders.delete("transfer-encoding");
1679
- guardHeaders.set(
1680
- "content-length",
1681
- String(bodyToSend.byteLength)
1682
- );
1683
- }
1684
- const guardRequest = new Request(guardUrl, {
1685
- method: actorRequest.method,
1686
- headers: guardHeaders,
1687
- body: bodyToSend
1688
- });
1689
- return mutableResponse(await fetch(guardRequest));
1690
- }
1691
- };
1692
- function mutableResponse(fetchRes) {
1693
- return new Response(fetchRes.body, fetchRes);
1694
- }
1695
- function buildGuardHeadersForHttp(actorRequest, actorId) {
1696
- const headers = new Headers();
1697
- for (const [key, value] of actorRequest.headers.entries()) {
1698
- headers.set(key, value);
1699
- }
1700
- headers.set("x-rivet-target", "actor");
1701
- headers.set("x-rivet-actor", actorId);
1702
- headers.set("x-rivet-port", "main");
1703
- return headers;
1704
- }
1705
- function buildGuardHeadersForWebSocket(actorId, encoding, params, authData) {
1706
- const headers = {};
1707
- headers["x-rivet-target"] = "actor";
1708
- headers["x-rivet-actor"] = actorId;
1709
- headers["x-rivet-port"] = "main";
1710
- headers[HEADER_EXPOSE_INTERNAL_ERROR] = "true";
1711
- headers[HEADER_ENCODING] = encoding;
1712
- if (params) {
1713
- headers[HEADER_CONN_PARAMS] = JSON.stringify(params);
1714
- }
1715
- if (authData) {
1716
- headers[HEADER_AUTH_DATA] = JSON.stringify(authData);
1717
- }
1718
- return headers;
1719
- }
1720
-
1721
- // src/drivers/engine/mod.ts
1722
- function createEngineDriver(inputConfig) {
1723
- const config2 = ConfigSchema.parse(inputConfig);
1724
- return {
1725
- name: "engine",
1726
- manager: (_registryConfig, runConfig) => {
1727
- return new EngineManagerDriver(config2, runConfig);
1728
- },
1729
- actor: (registryConfig, runConfig, managerDriver, inlineClient) => {
1730
- return new EngineActorDriver(
1731
- registryConfig,
1732
- runConfig,
1733
- managerDriver,
1734
- inlineClient,
1735
- config2
1736
- );
1737
- }
1738
- };
1739
- }
1740
-
1741
- // src/drivers/file-system/actor.ts
1742
- var FileSystemActorDriver = class {
1743
- #registryConfig;
1744
- #runConfig;
1745
- #managerDriver;
1746
- #inlineClient;
1747
- #state;
1748
- constructor(registryConfig, runConfig, managerDriver, inlineClient, state) {
1749
- this.#registryConfig = registryConfig;
1750
- this.#runConfig = runConfig;
1751
- this.#managerDriver = managerDriver;
1752
- this.#inlineClient = inlineClient;
1753
- this.#state = state;
1754
- }
1755
- async loadActor(actorId) {
1756
- return this.#state.startActor(
1757
- this.#registryConfig,
1758
- this.#runConfig,
1759
- this.#inlineClient,
1760
- this,
1761
- actorId
1762
- );
1763
- }
1764
- getGenericConnGlobalState(actorId) {
1765
- return this.#state.getActorOrError(actorId).genericConnGlobalState;
1766
- }
1767
- /**
1768
- * Get the current storage directory path
1769
- */
1770
- get storagePath() {
1771
- return this.#state.storagePath;
1772
- }
1773
- getContext(_actorId) {
1774
- return {};
1775
- }
1776
- async readPersistedData(actorId) {
1777
- return new Uint8Array(
1778
- (await this.#state.loadActorStateOrError(actorId)).persistedData
1779
- );
1780
- }
1781
- async writePersistedData(actorId, data) {
1782
- const state = await this.#state.loadActorStateOrError(actorId);
1783
- await this.#state.writeActor(actorId, {
1784
- ...state,
1785
- persistedData: bufferToArrayBuffer(data)
1786
- });
1787
- }
1788
- async setAlarm(actor2, timestamp) {
1789
- await this.#state.setActorAlarm(actor2.id, timestamp);
1790
- }
1791
- getDatabase(actorId) {
1792
- return this.#state.createDatabase(actorId);
1793
- }
1794
- sleep(actorId) {
1795
- return this.#state.sleepActor(actorId);
1796
- }
1797
- };
1798
-
1799
- // src/drivers/file-system/global-state.ts
1800
- import * as crypto4 from "crypto";
1801
- import * as fsSync2 from "fs";
1802
- import * as fs2 from "fs/promises";
1803
- import * as path2 from "path";
1804
- import invariant4 from "invariant";
1805
-
1806
- // dist/schemas/file-system-driver/v1.ts
1807
- import * as bare from "@bare-ts/lib";
1808
- var config = /* @__PURE__ */ bare.Config({});
1809
- function read0(bc) {
1810
- const len = bare.readUintSafe(bc);
1811
- if (len === 0) {
1812
- return [];
1813
- }
1814
- const result = [bare.readString(bc)];
1815
- for (let i = 1; i < len; i++) {
1816
- result[i] = bare.readString(bc);
1817
- }
1818
- return result;
1819
- }
1820
- function write0(bc, x) {
1821
- bare.writeUintSafe(bc, x.length);
1822
- for (let i = 0; i < x.length; i++) {
1823
- bare.writeString(bc, x[i]);
1824
- }
1825
- }
1826
- function readActorState(bc) {
1827
- return {
1828
- actorId: bare.readString(bc),
1829
- name: bare.readString(bc),
1830
- key: read0(bc),
1831
- persistedData: bare.readData(bc),
1832
- createdAt: bare.readU64(bc)
1833
- };
1834
- }
1835
- function writeActorState(bc, x) {
1836
- bare.writeString(bc, x.actorId);
1837
- bare.writeString(bc, x.name);
1838
- write0(bc, x.key);
1839
- bare.writeData(bc, x.persistedData);
1840
- bare.writeU64(bc, x.createdAt);
1841
- }
1842
- function encodeActorState(x) {
1843
- const bc = new bare.ByteCursor(
1844
- new Uint8Array(config.initialBufferLength),
1845
- config
1846
- );
1847
- writeActorState(bc, x);
1848
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
1849
- }
1850
- function decodeActorState(bytes) {
1851
- const bc = new bare.ByteCursor(bytes, config);
1852
- const result = readActorState(bc);
1853
- if (bc.offset < bc.view.byteLength) {
1854
- throw new bare.BareError(bc.offset, "remaining bytes");
1855
- }
1856
- return result;
1857
- }
1858
- function readActorAlarm(bc) {
1859
- return {
1860
- actorId: bare.readString(bc),
1861
- timestamp: bare.readUint(bc)
1862
- };
1863
- }
1864
- function writeActorAlarm(bc, x) {
1865
- bare.writeString(bc, x.actorId);
1866
- bare.writeUint(bc, x.timestamp);
1867
- }
1868
- function encodeActorAlarm(x) {
1869
- const bc = new bare.ByteCursor(
1870
- new Uint8Array(config.initialBufferLength),
1871
- config
1872
- );
1873
- writeActorAlarm(bc, x);
1874
- return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
1875
- }
1876
- function decodeActorAlarm(bytes) {
1877
- const bc = new bare.ByteCursor(bytes, config);
1878
- const result = readActorAlarm(bc);
1879
- if (bc.offset < bc.view.byteLength) {
1880
- throw new bare.BareError(bc.offset, "remaining bytes");
1881
- }
1882
- return result;
1883
- }
1884
-
1885
- // src/schemas/file-system-driver/versioned.ts
1886
- var CURRENT_VERSION = 1;
1887
- var migrations = /* @__PURE__ */ new Map();
1888
- var ACTOR_STATE_VERSIONED = createVersionedDataHandler({
1889
- currentVersion: CURRENT_VERSION,
1890
- migrations,
1891
- serializeVersion: (data) => encodeActorState(data),
1892
- deserializeVersion: (bytes) => decodeActorState(bytes)
1893
- });
1894
- var ACTOR_ALARM_VERSIONED = createVersionedDataHandler({
1895
- currentVersion: CURRENT_VERSION,
1896
- migrations,
1897
- serializeVersion: (data) => encodeActorAlarm(data),
1898
- deserializeVersion: (bytes) => decodeActorAlarm(bytes)
1899
- });
1900
-
1901
- // src/drivers/file-system/log.ts
1902
- var LOGGER_NAME3 = "driver-fs";
1903
- function logger6() {
1904
- return getLogger(LOGGER_NAME3);
1905
- }
1906
-
1907
- // src/drivers/file-system/utils.ts
1908
- import * as crypto3 from "crypto";
1909
- import * as fsSync from "fs";
1910
- import * as fs from "fs/promises";
1911
- import * as os from "os";
1912
- import * as path from "path";
1913
- function generateActorId(name, key) {
1914
- const jsonString = JSON.stringify([name, key]);
1915
- const hash = crypto3.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
1916
- return hash;
1917
- }
1918
- function createHashForPath(dirPath) {
1919
- const normalizedPath = path.normalize(dirPath);
1920
- const lastComponent = path.basename(normalizedPath);
1921
- const hash = crypto3.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
1922
- return `${lastComponent}-${hash}`;
1923
- }
1924
- function getStoragePath(customPath) {
1925
- const dataPath = getDataPath("rivetkit");
1926
- const pathToHash = customPath || process.cwd();
1927
- const dirHash = createHashForPath(pathToHash);
1928
- return path.join(dataPath, dirHash);
1929
- }
1930
- async function pathExists(path3) {
1931
- try {
1932
- await fs.access(path3);
1933
- return true;
1934
- } catch {
1935
- return false;
1936
- }
1937
- }
1938
- async function ensureDirectoryExists(directoryPath) {
1939
- if (!await pathExists(directoryPath)) {
1940
- await fs.mkdir(directoryPath, { recursive: true });
1941
- }
1942
- }
1943
- function ensureDirectoryExistsSync(directoryPath) {
1944
- if (!fsSync.existsSync(directoryPath)) {
1945
- fsSync.mkdirSync(directoryPath, { recursive: true });
1946
- }
1947
- }
1948
- function getDataPath(appName) {
1949
- const platform = process.platform;
1950
- const homeDir = os.homedir();
1951
- switch (platform) {
1952
- case "win32":
1953
- return path.join(
1954
- process.env.APPDATA || path.join(homeDir, "AppData", "Roaming"),
1955
- appName
1956
- );
1957
- case "darwin":
1958
- return path.join(homeDir, "Library", "Application Support", appName);
1959
- default:
1960
- return path.join(
1961
- process.env.XDG_DATA_HOME || path.join(homeDir, ".local", "share"),
1962
- appName
1963
- );
1964
- }
1965
- }
1966
-
1967
- // src/drivers/file-system/global-state.ts
1968
- var FileSystemGlobalState = class {
1969
- #storagePath;
1970
- #stateDir;
1971
- #dbsDir;
1972
- #alarmsDir;
1973
- #persist;
1974
- #actors = /* @__PURE__ */ new Map();
1975
- #actorCountOnStartup = 0;
1976
- #runnerParams;
1977
- get storagePath() {
1978
- return this.#storagePath;
1979
- }
1980
- get actorCountOnStartup() {
1981
- return this.#actorCountOnStartup;
1982
- }
1983
- constructor(persist = true, customPath) {
1984
- this.#persist = persist;
1985
- this.#storagePath = persist ? getStoragePath(customPath) : "/tmp";
1986
- this.#stateDir = path2.join(this.#storagePath, "state");
1987
- this.#dbsDir = path2.join(this.#storagePath, "databases");
1988
- this.#alarmsDir = path2.join(this.#storagePath, "alarms");
1989
- if (this.#persist) {
1990
- ensureDirectoryExistsSync(this.#stateDir);
1991
- ensureDirectoryExistsSync(this.#dbsDir);
1992
- ensureDirectoryExistsSync(this.#alarmsDir);
1993
- try {
1994
- const actorIds = fsSync2.readdirSync(this.#stateDir);
1995
- this.#actorCountOnStartup = actorIds.length;
1996
- } catch (error) {
1997
- logger6().error("failed to count actors", { error });
1998
- }
1999
- logger6().debug("file system driver ready", {
2000
- dir: this.#storagePath,
2001
- actorCount: this.#actorCountOnStartup
2002
- });
2003
- try {
2004
- this.#cleanupTempFilesSync();
2005
- } catch (err) {
2006
- logger6().error("failed to cleanup temp files", { error: err });
2007
- }
2008
- } else {
2009
- logger6().debug("memory driver ready");
2010
- }
2011
- }
2012
- getActorStatePath(actorId) {
2013
- return path2.join(this.#stateDir, actorId);
2014
- }
2015
- getActorDbPath(actorId) {
2016
- return path2.join(this.#dbsDir, `${actorId}.db`);
2017
- }
2018
- getActorAlarmPath(actorId) {
2019
- return path2.join(this.#alarmsDir, actorId);
2020
- }
2021
- async *getActorsIterator(params) {
2022
- let actorIds = Array.from(this.#actors.keys()).sort();
2023
- if (fsSync2.existsSync(this.#stateDir)) {
2024
- actorIds = fsSync2.readdirSync(this.#stateDir).filter((id) => !id.includes(".tmp")).sort();
2025
- }
2026
- const startIndex = params.cursor ? actorIds.indexOf(params.cursor) + 1 : 0;
2027
- for (let i = startIndex; i < actorIds.length; i++) {
2028
- const actorId = actorIds[i];
2029
- if (!actorId) {
2030
- continue;
2031
- }
2032
- try {
2033
- const state = await this.loadActorStateOrError(actorId);
2034
- yield state;
2035
- } catch (error) {
2036
- logger6().error("failed to load actor state", { actorId, error });
2037
- }
2038
- }
2039
- }
2040
- /**
2041
- * Ensures an entry exists for this actor.
2042
- *
2043
- * Used for #createActor and #loadActor.
2044
- */
2045
- #upsertEntry(actorId) {
2046
- let entry = this.#actors.get(actorId);
2047
- if (entry) {
2048
- return entry;
2049
- }
2050
- entry = {
2051
- id: actorId,
2052
- genericConnGlobalState: new GenericConnGlobalState(),
2053
- removed: false
2054
- };
2055
- this.#actors.set(actorId, entry);
2056
- return entry;
2057
- }
2058
- /**
2059
- * Creates a new actor and writes to file system.
2060
- */
2061
- async createActor(actorId, name, key, input) {
2062
- if (this.#actors.has(actorId)) {
2063
- throw new ActorAlreadyExists(name, key);
2064
- }
2065
- const entry = this.#upsertEntry(actorId);
2066
- entry.state = {
2067
- actorId,
2068
- name,
2069
- key,
2070
- createdAt: BigInt(Date.now()),
2071
- persistedData: bufferToArrayBuffer(serializeEmptyPersistData(input))
2072
- };
2073
- await this.writeActor(actorId, entry.state);
2074
- return entry;
2075
- }
2076
- /**
2077
- * Loads the actor from disk or returns the existing actor entry. This will return an entry even if the actor does not actually exist.
2078
- */
2079
- async loadActor(actorId) {
2080
- const entry = this.#upsertEntry(actorId);
2081
- if (entry.state) {
2082
- return entry;
2083
- }
2084
- if (!this.#persist) {
2085
- return entry;
2086
- }
2087
- if (entry.loadPromise) {
2088
- await entry.loadPromise;
2089
- return entry;
2090
- }
2091
- entry.loadPromise = this.loadActorState(entry);
2092
- return entry.loadPromise;
2093
- }
2094
- async loadActorState(entry) {
2095
- const stateFilePath = this.getActorStatePath(entry.id);
2096
- try {
2097
- const stateData = await fs2.readFile(stateFilePath);
2098
- entry.state = ACTOR_STATE_VERSIONED.deserializeWithEmbeddedVersion(
2099
- new Uint8Array(stateData)
2100
- );
2101
- return entry;
2102
- } catch (innerError) {
2103
- if (innerError.code === "ENOENT") {
2104
- entry.loadPromise = void 0;
2105
- return entry;
2106
- }
2107
- const error = new Error(`Failed to load actor state: ${innerError}`);
2108
- throw error;
2109
- }
2110
- }
2111
- async loadOrCreateActor(actorId, name, key, input) {
2112
- const entry = await this.loadActor(actorId);
2113
- if (!entry.state) {
2114
- entry.state = {
2115
- actorId,
2116
- name,
2117
- key,
2118
- createdAt: BigInt(Date.now()),
2119
- persistedData: bufferToArrayBuffer(serializeEmptyPersistData(input))
2120
- };
2121
- await this.writeActor(actorId, entry.state);
2122
- }
2123
- return entry;
2124
- }
2125
- async sleepActor(actorId) {
2126
- var _a;
2127
- invariant4(
2128
- this.#persist,
2129
- "cannot sleep actor with memory driver, must use file system driver"
2130
- );
2131
- const actor2 = this.#actors.get(actorId);
2132
- invariant4(actor2, `tried to sleep ${actorId}, does not exist`);
2133
- if (actor2.loadPromise) await actor2.loadPromise.catch();
2134
- if ((_a = actor2.startPromise) == null ? void 0 : _a.promise) await actor2.startPromise.promise.catch();
2135
- actor2.removed = true;
2136
- invariant4(actor2.actor, "actor should be loaded");
2137
- await actor2.actor._stop();
2138
- this.#actors.delete(actorId);
2139
- }
2140
- /**
2141
- * Save actor state to disk.
2142
- */
2143
- async writeActor(actorId, state) {
2144
- if (!this.#persist) {
2145
- return;
2146
- }
2147
- const entry = this.#actors.get(actorId);
2148
- invariant4(entry, "actor entry does not exist");
2149
- await this.#performWrite(actorId, state);
2150
- }
2151
- async setActorAlarm(actorId, timestamp) {
2152
- const entry = this.#actors.get(actorId);
2153
- invariant4(entry, "actor entry does not exist");
2154
- if (this.#persist) {
2155
- const alarmPath = this.getActorAlarmPath(actorId);
2156
- const tempPath = `${alarmPath}.tmp.${crypto4.randomUUID()}`;
2157
- try {
2158
- await ensureDirectoryExists(path2.dirname(alarmPath));
2159
- const alarmData = {
2160
- actorId,
2161
- timestamp: BigInt(timestamp)
2162
- };
2163
- const data = ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(alarmData);
2164
- await fs2.writeFile(tempPath, data);
2165
- await fs2.rename(tempPath, alarmPath);
2166
- } catch (error) {
2167
- try {
2168
- await fs2.unlink(tempPath);
2169
- } catch {
2170
- }
2171
- logger6().error("failed to write alarm", { actorId, error });
2172
- throw new Error(`Failed to write alarm: ${error}`);
2173
- }
2174
- }
2175
- this.#scheduleAlarmTimeout(actorId, timestamp);
2176
- }
2177
- /**
2178
- * Perform the actual write operation with atomic writes
2179
- */
2180
- async #performWrite(actorId, state) {
2181
- const dataPath = this.getActorStatePath(actorId);
2182
- const tempPath = `${dataPath}.tmp.${crypto4.randomUUID()}`;
2183
- try {
2184
- await ensureDirectoryExists(path2.dirname(dataPath));
2185
- const bareState = {
2186
- actorId: state.actorId,
2187
- name: state.name,
2188
- key: state.key,
2189
- createdAt: state.createdAt,
2190
- persistedData: state.persistedData
2191
- };
2192
- const serializedState = ACTOR_STATE_VERSIONED.serializeWithEmbeddedVersion(bareState);
2193
- await fs2.writeFile(tempPath, serializedState);
2194
- await fs2.rename(tempPath, dataPath);
2195
- } catch (error) {
2196
- try {
2197
- await fs2.unlink(tempPath);
2198
- } catch {
2199
- }
2200
- logger6().error("failed to save actor state", { actorId, error });
2201
- throw new Error(`Failed to save actor state: ${error}`);
2202
- }
2203
- }
2204
- /**
2205
- * Call this method after the actor driver has been initiated.
2206
- *
2207
- * This will trigger all initial alarms from the file system.
2208
- *
2209
- * This needs to be sync since DriverConfig.actor is sync
2210
- */
2211
- onRunnerStart(registryConfig, runConfig, inlineClient, actorDriver) {
2212
- if (this.#runnerParams) {
2213
- logger6().warn("already called onRunnerStart");
2214
- return;
2215
- }
2216
- this.#runnerParams = {
2217
- registryConfig,
2218
- runConfig,
2219
- inlineClient,
2220
- actorDriver
2221
- };
2222
- try {
2223
- this.#loadAlarmsSync();
2224
- } catch (err) {
2225
- logger6().error("failed to load alarms on startup", { error: err });
2226
- }
2227
- }
2228
- async startActor(registryConfig, runConfig, inlineClient, actorDriver, actorId) {
2229
- var _a;
2230
- const entry = await this.loadActor(actorId);
2231
- if (!entry.state) {
2232
- throw new Error(`Actor does exist and cannot be started: ${actorId}`);
2233
- }
2234
- if (entry.startPromise) {
2235
- await entry.startPromise.promise;
2236
- invariant4(entry.actor, "actor should have loaded");
2237
- return entry.actor;
2238
- }
2239
- if (entry.actor) {
2240
- return entry.actor;
2241
- }
2242
- entry.startPromise = Promise.withResolvers();
2243
- try {
2244
- const definition = lookupInRegistry(registryConfig, entry.state.name);
2245
- entry.actor = definition.instantiate();
2246
- const connDrivers = createGenericConnDrivers(
2247
- entry.genericConnGlobalState
2248
- );
2249
- await entry.actor.start(
2250
- connDrivers,
2251
- actorDriver,
2252
- inlineClient,
2253
- actorId,
2254
- entry.state.name,
2255
- entry.state.key,
2256
- "unknown"
2257
- );
2258
- entry.startPromise.resolve();
2259
- entry.startPromise = void 0;
2260
- return entry.actor;
2261
- } catch (innerError) {
2262
- const error = new Error(
2263
- `Failed to start actor ${actorId}: ${innerError}`,
2264
- { cause: innerError }
2265
- );
2266
- (_a = entry.startPromise) == null ? void 0 : _a.reject(error);
2267
- entry.startPromise = void 0;
2268
- throw error;
2269
- }
2270
- }
2271
- async loadActorStateOrError(actorId) {
2272
- const state = (await this.loadActor(actorId)).state;
2273
- if (!state) throw new Error(`Actor does not exist: ${actorId}`);
2274
- return state;
2275
- }
2276
- getActorOrError(actorId) {
2277
- const entry = this.#actors.get(actorId);
2278
- if (!entry) throw new Error(`No entry for actor: ${actorId}`);
2279
- return entry;
2280
- }
2281
- async createDatabase(actorId) {
2282
- return this.getActorDbPath(actorId);
2283
- }
2284
- /**
2285
- * Load all persisted alarms from disk and schedule their timers.
2286
- */
2287
- #loadAlarmsSync() {
2288
- try {
2289
- const files = fsSync2.existsSync(this.#alarmsDir) ? fsSync2.readdirSync(this.#alarmsDir) : [];
2290
- for (const file of files) {
2291
- if (file.includes(".tmp.")) continue;
2292
- const fullPath = path2.join(this.#alarmsDir, file);
2293
- try {
2294
- const buf = fsSync2.readFileSync(fullPath);
2295
- const alarmData = ACTOR_ALARM_VERSIONED.deserializeWithEmbeddedVersion(
2296
- new Uint8Array(buf)
2297
- );
2298
- const timestamp = Number(alarmData.timestamp);
2299
- if (Number.isFinite(timestamp)) {
2300
- this.#scheduleAlarmTimeout(alarmData.actorId, timestamp);
2301
- } else {
2302
- logger6().debug("invalid alarm file contents", { file });
2303
- }
2304
- } catch (err) {
2305
- logger6().error("failed to read alarm file", {
2306
- file,
2307
- error: stringifyError(err)
2308
- });
2309
- }
2310
- }
2311
- } catch (err) {
2312
- logger6().error("failed to list alarms directory", { error: err });
2313
- }
2314
- }
2315
- /**
2316
- * Schedule an alarm timer for an actor without writing to disk.
2317
- */
2318
- #scheduleAlarmTimeout(actorId, timestamp) {
2319
- var _a;
2320
- const entry = this.#upsertEntry(actorId);
2321
- if (entry.alarmTimestamp !== void 0 && timestamp >= entry.alarmTimestamp) {
2322
- logger6().debug("skipping alarm schedule (later than existing)", {
2323
- actorId,
2324
- timestamp,
2325
- current: entry.alarmTimestamp
2326
- });
2327
- return;
2328
- }
2329
- logger6().debug("scheduling alarm", { actorId, timestamp });
2330
- (_a = entry.alarmTimeout) == null ? void 0 : _a.abort();
2331
- entry.alarmTimestamp = timestamp;
2332
- const delay = Math.max(0, timestamp - Date.now());
2333
- entry.alarmTimeout = setLongTimeout(async () => {
2334
- entry.alarmTimestamp = void 0;
2335
- if (this.#persist) {
2336
- try {
2337
- await fs2.unlink(this.getActorAlarmPath(actorId));
2338
- } catch (err) {
2339
- if ((err == null ? void 0 : err.code) !== "ENOENT") {
2340
- logger6().debug("failed to remove alarm file", {
2341
- actorId,
2342
- error: stringifyError(err)
2343
- });
2344
- }
2345
- }
2346
- }
2347
- try {
2348
- logger6().debug("triggering alarm", { actorId, timestamp });
2349
- const loaded = await this.loadActor(actorId);
2350
- if (!loaded.state) throw new Error(`Actor does not exist: ${actorId}`);
2351
- const runnerParams = this.#runnerParams;
2352
- invariant4(runnerParams, "missing runner params");
2353
- if (!loaded.actor) {
2354
- await this.startActor(
2355
- runnerParams.registryConfig,
2356
- runnerParams.runConfig,
2357
- runnerParams.inlineClient,
2358
- runnerParams.actorDriver,
2359
- actorId
2360
- );
2361
- }
2362
- invariant4(loaded.actor, "actor should be loaded after wake");
2363
- await loaded.actor._onAlarm();
2364
- } catch (err) {
2365
- logger6().error("failed to handle alarm", {
2366
- actorId,
2367
- error: stringifyError(err)
2368
- });
2369
- }
2370
- }, delay);
2371
- }
2372
- getOrCreateInspectorAccessToken() {
2373
- const tokenPath = path2.join(this.#storagePath, "inspector-token");
2374
- if (fsSync2.existsSync(tokenPath)) {
2375
- return fsSync2.readFileSync(tokenPath, "utf-8");
2376
- }
2377
- const newToken = generateRandomString();
2378
- fsSync2.writeFileSync(tokenPath, newToken);
2379
- return newToken;
2380
- }
2381
- /**
2382
- * Cleanup stale temp files on startup (synchronous)
2383
- */
2384
- #cleanupTempFilesSync() {
2385
- try {
2386
- const files = fsSync2.readdirSync(this.#stateDir);
2387
- const tempFiles = files.filter((f) => f.includes(".tmp."));
2388
- const oneHourAgo = Date.now() - 36e5;
2389
- for (const tempFile of tempFiles) {
2390
- try {
2391
- const fullPath = path2.join(this.#stateDir, tempFile);
2392
- const stat = fsSync2.statSync(fullPath);
2393
- if (stat.mtimeMs < oneHourAgo) {
2394
- fsSync2.unlinkSync(fullPath);
2395
- logger6().info("cleaned up stale temp file", { file: tempFile });
2396
- }
2397
- } catch (err) {
2398
- logger6().debug("failed to cleanup temp file", {
2399
- file: tempFile,
2400
- error: err
2401
- });
2402
- }
2403
- }
2404
- } catch (err) {
2405
- logger6().error("failed to read actors directory for cleanup", {
2406
- error: err
2407
- });
2408
- }
2409
- }
2410
- };
2411
-
2412
- // src/drivers/file-system/manager.ts
2413
- import invariant6 from "invariant";
2414
-
2415
- // src/inline-client-driver/mod.ts
2416
- import * as cbor4 from "cbor-x";
2417
- import invariant5 from "invariant";
2418
- import onChange from "on-change";
2419
-
2420
- // src/inline-client-driver/log.ts
2421
- var LOGGER_NAME4 = "inline-client-driver";
2422
- function logger7() {
2423
- return getLogger(LOGGER_NAME4);
2424
- }
2425
-
2426
- // src/inline-client-driver/mod.ts
2427
- function createInlineClientDriver(managerDriver) {
2428
- const driver = {
2429
- action: async (c, actorQuery, encoding, params, actionName, args, opts) => {
2430
- try {
2431
- const { actorId } = await queryActor(c, actorQuery, managerDriver);
2432
- logger7().debug("found actor for action", { actorId });
2433
- invariant5(actorId, "Missing actor ID");
2434
- logger7().debug("handling action", { actionName, encoding });
2435
- const responseData = await sendHttpRequest({
2436
- url: `http://actor/action/${encodeURIComponent(actionName)}`,
2437
- method: "POST",
2438
- headers: {
2439
- [HEADER_ENCODING]: encoding,
2440
- ...params !== void 0 ? { [HEADER_CONN_PARAMS]: JSON.stringify(params) } : {},
2441
- [HEADER_EXPOSE_INTERNAL_ERROR]: "true"
2442
- },
2443
- body: {
2444
- args: bufferToArrayBuffer(cbor4.encode(args))
2445
- },
2446
- encoding,
2447
- customFetch: managerDriver.sendRequest.bind(managerDriver, actorId),
2448
- signal: opts == null ? void 0 : opts.signal,
2449
- requestVersionedDataHandler: HTTP_ACTION_REQUEST_VERSIONED,
2450
- responseVersionedDataHandler: HTTP_ACTION_RESPONSE_VERSIONED
2451
- });
2452
- return cbor4.decode(new Uint8Array(responseData.output));
2453
- } catch (err) {
2454
- const { code, message, metadata } = deconstructError(
2455
- err,
2456
- logger7(),
2457
- {},
2458
- true
2459
- );
2460
- const x = new ActorError2(code, message, metadata);
2461
- throw new ActorError2(code, message, metadata);
2462
- }
2463
- },
2464
- resolveActorId: async (c, actorQuery, _encodingKind) => {
2465
- const { actorId } = await queryActor(c, actorQuery, managerDriver);
2466
- logger7().debug("resolved actor", { actorId });
2467
- invariant5(actorId, "missing actor ID");
2468
- return actorId;
2469
- },
2470
- connectWebSocket: async (c, actorQuery, encodingKind, params) => {
2471
- const { actorId } = await queryActor(c, actorQuery, managerDriver);
2472
- logger7().debug("found actor for action", { actorId });
2473
- invariant5(actorId, "Missing actor ID");
2474
- logger7().debug("opening websocket", { actorId, encoding: encodingKind });
2475
- const ws = await managerDriver.openWebSocket(
2476
- PATH_CONNECT_WEBSOCKET,
2477
- actorId,
2478
- encodingKind,
2479
- params
2480
- );
2481
- return ws;
2482
- },
2483
- connectSse: async (c, actorQuery, encodingKind, params) => {
2484
- const { actorId } = await queryActor(c, actorQuery, managerDriver);
2485
- logger7().debug("found actor for sse connection", { actorId });
2486
- invariant5(actorId, "Missing actor ID");
2487
- logger7().debug("opening sse connection", {
2488
- actorId,
2489
- encoding: encodingKind
2490
- });
2491
- const EventSourceClass = await importEventSource();
2492
- const eventSource = new EventSourceClass("http://actor/connect/sse", {
2493
- fetch: (input, init) => {
2494
- return fetch(input, {
2495
- ...init,
2496
- headers: {
2497
- ...init == null ? void 0 : init.headers,
2498
- "User-Agent": httpUserAgent(),
2499
- [HEADER_ENCODING]: encodingKind,
2500
- ...params !== void 0 ? { [HEADER_CONN_PARAMS]: JSON.stringify(params) } : {},
2501
- [HEADER_EXPOSE_INTERNAL_ERROR]: "true"
2502
- }
2503
- });
2504
- }
2505
- });
2506
- return eventSource;
2507
- },
2508
- sendHttpMessage: async (c, actorId, encoding, connectionId, connectionToken, message) => {
2509
- logger7().debug("sending http message", { actorId, connectionId });
2510
- await sendHttpRequest({
2511
- url: "http://actor/connections/message",
2512
- method: "POST",
2513
- headers: {
2514
- [HEADER_ENCODING]: encoding,
2515
- [HEADER_CONN_ID]: connectionId,
2516
- [HEADER_CONN_TOKEN]: connectionToken,
2517
- [HEADER_EXPOSE_INTERNAL_ERROR]: "true"
2518
- },
2519
- body: message,
2520
- encoding,
2521
- skipParseResponse: true,
2522
- customFetch: managerDriver.sendRequest.bind(managerDriver, actorId),
2523
- requestVersionedDataHandler: TO_SERVER_VERSIONED,
2524
- responseVersionedDataHandler: TO_CLIENT_VERSIONED
2525
- });
2526
- },
2527
- rawHttpRequest: async (c, actorQuery, encoding, params, path3, init) => {
2528
- try {
2529
- const { actorId } = await queryActor(c, actorQuery, managerDriver);
2530
- logger7().debug("found actor for raw http", { actorId });
2531
- invariant5(actorId, "Missing actor ID");
2532
- const normalizedPath = path3.startsWith("/") ? path3.slice(1) : path3;
2533
- const url = new URL(`http://actor/raw/http/${normalizedPath}`);
2534
- const proxyRequestHeaders = new Headers(init.headers);
2535
- if (params) {
2536
- proxyRequestHeaders.set(HEADER_CONN_PARAMS, JSON.stringify(params));
2537
- }
2538
- const proxyRequest = new Request(url, {
2539
- ...init,
2540
- headers: proxyRequestHeaders
2541
- });
2542
- return await managerDriver.sendRequest(actorId, proxyRequest);
2543
- } catch (err) {
2544
- const { code, message, metadata } = deconstructError(
2545
- err,
2546
- logger7(),
2547
- {},
2548
- true
2549
- );
2550
- throw new ActorError2(code, message, metadata);
2551
- }
2552
- },
2553
- rawWebSocket: async (c, actorQuery, encoding, params, path3, protocols) => {
2554
- const { actorId } = await queryActor(c, actorQuery, managerDriver);
2555
- logger7().debug("found actor for action", { actorId });
2556
- invariant5(actorId, "Missing actor ID");
2557
- const normalizedPath = path3.startsWith("/") ? path3.slice(1) : path3;
2558
- logger7().debug("opening websocket", {
2559
- actorId,
2560
- encoding,
2561
- path: normalizedPath
2562
- });
2563
- const ws = await managerDriver.openWebSocket(
2564
- `${PATH_RAW_WEBSOCKET_PREFIX}${normalizedPath}`,
2565
- actorId,
2566
- encoding,
2567
- params
2568
- );
2569
- return ws;
2570
- }
2571
- };
2572
- return driver;
2573
- }
2574
- async function queryActor(c, query, driver) {
2575
- logger7().debug("querying actor", { query });
2576
- let actorOutput;
2577
- if ("getForId" in query) {
2578
- const output = await driver.getForId({
2579
- c,
2580
- name: query.getForId.name,
2581
- actorId: query.getForId.actorId
2582
- });
2583
- if (!output) throw new ActorNotFound(query.getForId.actorId);
2584
- actorOutput = output;
2585
- } else if ("getForKey" in query) {
2586
- const existingActor = await driver.getWithKey({
2587
- c,
2588
- name: query.getForKey.name,
2589
- key: query.getForKey.key
2590
- });
2591
- if (!existingActor) {
2592
- throw new ActorNotFound(
2593
- `${query.getForKey.name}:${JSON.stringify(query.getForKey.key)}`
2594
- );
2595
- }
2596
- actorOutput = existingActor;
2597
- } else if ("getOrCreateForKey" in query) {
2598
- const getOrCreateOutput = await driver.getOrCreateWithKey({
2599
- c,
2600
- name: query.getOrCreateForKey.name,
2601
- key: query.getOrCreateForKey.key,
2602
- input: query.getOrCreateForKey.input,
2603
- region: query.getOrCreateForKey.region
2604
- });
2605
- actorOutput = {
2606
- actorId: getOrCreateOutput.actorId
2607
- };
2608
- } else if ("create" in query) {
2609
- const createOutput = await driver.createActor({
2610
- c,
2611
- name: query.create.name,
2612
- key: query.create.key,
2613
- input: query.create.input,
2614
- region: query.create.region
2615
- });
2616
- actorOutput = {
2617
- actorId: createOutput.actorId
2618
- };
2619
- } else {
2620
- throw new InvalidRequest("Invalid query format");
2621
- }
2622
- logger7().debug("actor query result", {
2623
- actorId: actorOutput.actorId
2624
- });
2625
- return { actorId: actorOutput.actorId };
2626
- }
2627
-
2628
- // src/inspector/manager.ts
2629
- import { sValidator } from "@hono/standard-validator";
2630
- import { Hono as Hono2 } from "hono";
2631
- function createManagerInspectorRouter() {
2632
- return new Hono2().get("/ping", (c) => {
2633
- return c.json({ message: "pong" }, 200);
2634
- }).get("/actors", async (c) => {
2635
- const limit = Number.parseInt(c.req.query("limit") ?? "") || void 0;
2636
- const cursor = c.req.query("cursor") || void 0;
2637
- if (!limit || limit && limit <= 0) {
2638
- return c.json("Invalid limit", 400);
2639
- }
2640
- try {
2641
- const actors = await c.var.inspector.accessors.getAllActors({
2642
- limit,
2643
- cursor
2644
- });
2645
- return c.json(actors, 200);
2646
- } catch (error) {
2647
- inspectorLogger().error("Failed to fetch actors", error);
2648
- return c.json("Failed to fetch actors", 500);
2649
- }
2650
- }).post("/actors", sValidator("json", CreateActorSchema), async (c) => {
2651
- const actor2 = await c.var.inspector.accessors.createActor(
2652
- c.req.valid("json")
2653
- );
2654
- return c.json(actor2, 201);
2655
- }).get("/builds", async (c) => {
2656
- const builds = await c.var.inspector.accessors.getBuilds();
2657
- return c.json(builds, 200);
2658
- }).get("/actor/:id", async (c) => {
2659
- const id = c.req.param("id");
2660
- const actor2 = await c.var.inspector.accessors.getActorById(id);
2661
- if (!actor2) {
2662
- return c.json({ error: "Actor not found" }, 404);
2663
- }
2664
- return c.json(actor2, 200);
2665
- }).get("/bootstrap", async (c) => {
2666
- const actors = await c.var.inspector.accessors.getAllActors({
2667
- limit: 10
2668
- });
2669
- return c.json({ actors }, 200);
2670
- });
2671
- }
2672
- var ManagerInspector = class {
2673
- accessors;
2674
- constructor(accessors) {
2675
- this.accessors = accessors();
2676
- inspectorLogger().debug("Manager Inspector enabled and ready");
2677
- }
2678
- };
2679
-
2680
- // src/drivers/file-system/manager.ts
2681
- var FileSystemManagerDriver = class {
2682
- #registryConfig;
2683
- #runConfig;
2684
- #state;
2685
- #driverConfig;
2686
- #actorDriver;
2687
- #actorRouter;
2688
- inspector;
2689
- constructor(registryConfig, runConfig, state, driverConfig) {
2690
- this.#registryConfig = registryConfig;
2691
- this.#runConfig = runConfig;
2692
- this.#state = state;
2693
- this.#driverConfig = driverConfig;
2694
- if (runConfig.inspector.enabled) {
2695
- let transformActor2 = function(actorState) {
2696
- return {
2697
- id: actorState.actorId,
2698
- name: actorState.name,
2699
- key: actorState.key,
2700
- startedAt,
2701
- createdAt: new Date(Number(actorState.createdAt)).toISOString(),
2702
- features: [
2703
- "state" /* State */,
2704
- "connections" /* Connections */,
2705
- "console" /* Console */,
2706
- "events-monitoring" /* EventsMonitoring */,
2707
- "database" /* Database */
2708
- ]
2709
- };
2710
- };
2711
- var transformActor = transformActor2;
2712
- if (!this.#runConfig.inspector.token()) {
2713
- this.#runConfig.inspector.token = () => this.#state.getOrCreateInspectorAccessToken();
2714
- }
2715
- const startedAt = (/* @__PURE__ */ new Date()).toISOString();
2716
- this.inspector = new ManagerInspector(() => {
2717
- return {
2718
- getAllActors: async ({ cursor, limit }) => {
2719
- const itr = this.#state.getActorsIterator({ cursor });
2720
- const actors = [];
2721
- for await (const actor2 of itr) {
2722
- actors.push(transformActor2(actor2));
2723
- if (limit && actors.length >= limit) {
2724
- break;
2725
- }
2726
- }
2727
- return actors;
2728
- },
2729
- getActorById: async (id) => {
2730
- try {
2731
- const result = await this.#state.loadActorStateOrError(id);
2732
- return transformActor2(result);
2733
- } catch {
2734
- return null;
2735
- }
2736
- },
2737
- getBuilds: async () => {
2738
- return Object.keys(this.#registryConfig.use).map((name) => ({
2739
- name
2740
- }));
2741
- },
2742
- createActor: async (input) => {
2743
- const { actorId } = await this.createActor(input);
2744
- try {
2745
- const result = await this.#state.loadActorStateOrError(actorId);
2746
- return transformActor2(result);
2747
- } catch {
2748
- return null;
2749
- }
2750
- }
2751
- };
2752
- });
2753
- }
2754
- const inlineClient = createClientWithDriver(createInlineClientDriver(this));
2755
- this.#actorDriver = this.#driverConfig.actor(
2756
- registryConfig,
2757
- runConfig,
2758
- this,
2759
- inlineClient
2760
- );
2761
- this.#actorRouter = createActorRouter(this.#runConfig, this.#actorDriver);
2762
- }
2763
- async sendRequest(actorId, actorRequest) {
2764
- return await this.#actorRouter.fetch(actorRequest, {
2765
- actorId
2766
- });
2767
- }
2768
- async openWebSocket(path3, actorId, encoding, params) {
2769
- if (path3 === PATH_CONNECT_WEBSOCKET) {
2770
- const wsHandler = await handleWebSocketConnect(
2771
- void 0,
2772
- this.#runConfig,
2773
- this.#actorDriver,
2774
- actorId,
2775
- encoding,
2776
- params,
2777
- void 0
2778
- );
2779
- return new InlineWebSocketAdapter2(wsHandler);
2780
- } else if (path3.startsWith(PATH_RAW_WEBSOCKET_PREFIX)) {
2781
- const wsHandler = await handleRawWebSocketHandler(
2782
- void 0,
2783
- path3,
2784
- this.#actorDriver,
2785
- actorId,
2786
- void 0
2787
- );
2788
- return new InlineWebSocketAdapter2(wsHandler);
2789
- } else {
2790
- throw new Error(`Unreachable path: ${path3}`);
2791
- }
2792
- }
2793
- async proxyRequest(c, actorRequest, actorId) {
2794
- return await this.#actorRouter.fetch(actorRequest, {
2795
- actorId
2796
- });
2797
- }
2798
- async proxyWebSocket(c, path3, actorId, encoding, connParams, authData) {
2799
- var _a, _b;
2800
- const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
2801
- invariant6(upgradeWebSocket, "missing getUpgradeWebSocket");
2802
- if (path3 === PATH_CONNECT_WEBSOCKET) {
2803
- const wsHandler = await handleWebSocketConnect(
2804
- c.req.raw,
2805
- this.#runConfig,
2806
- this.#actorDriver,
2807
- actorId,
2808
- encoding,
2809
- connParams,
2810
- authData
2811
- );
2812
- return upgradeWebSocket(() => wsHandler)(c, noopNext());
2813
- } else if (path3.startsWith(PATH_RAW_WEBSOCKET_PREFIX)) {
2814
- const wsHandler = await handleRawWebSocketHandler(
2815
- c.req.raw,
2816
- path3,
2817
- this.#actorDriver,
2818
- actorId,
2819
- authData
2820
- );
2821
- return upgradeWebSocket(() => wsHandler)(c, noopNext());
2822
- } else {
2823
- throw new Error(`Unreachable path: ${path3}`);
2824
- }
2825
- }
2826
- async getForId({ actorId }) {
2827
- const actor2 = await this.#state.loadActor(actorId);
2828
- if (!actor2.state) {
2829
- return void 0;
2830
- }
2831
- try {
2832
- return {
2833
- actorId,
2834
- name: actor2.state.name,
2835
- key: actor2.state.key
2836
- };
2837
- } catch (error) {
2838
- logger6().error("failed to read actor state", { actorId, error });
2839
- return void 0;
2840
- }
2841
- }
2842
- async getWithKey({
2843
- name,
2844
- key
2845
- }) {
2846
- const actorId = generateActorId(name, key);
2847
- const actor2 = await this.#state.loadActor(actorId);
2848
- if (actor2.state) {
2849
- return {
2850
- actorId,
2851
- name,
2852
- key
2853
- };
2854
- }
2855
- return void 0;
2856
- }
2857
- async getOrCreateWithKey(input) {
2858
- const actorId = generateActorId(input.name, input.key);
2859
- const actorEntry = await this.#state.loadOrCreateActor(
2860
- actorId,
2861
- input.name,
2862
- input.key,
2863
- input.input
2864
- );
2865
- invariant6(actorEntry.state, "must have state");
2866
- return {
2867
- actorId: actorEntry.state.actorId,
2868
- name: actorEntry.state.name,
2869
- key: actorEntry.state.key
2870
- };
2871
- }
2872
- async createActor({ name, key, input }) {
2873
- const actorId = generateActorId(name, key);
2874
- await this.#state.createActor(actorId, name, key, input);
2875
- return {
2876
- actorId,
2877
- name,
2878
- key
2879
- };
2880
- }
2881
- extraStartupLog() {
2882
- return {
2883
- instances: this.#state.actorCountOnStartup,
2884
- data: this.#state.storagePath
2885
- };
2886
- }
2887
- };
2888
-
2889
- // src/drivers/file-system/mod.ts
2890
- function createFileSystemOrMemoryDriver(persist = true, customPath) {
2891
- const state = new FileSystemGlobalState(persist, customPath);
2892
- const driverConfig = {
2893
- name: persist ? "file-system" : "memory",
2894
- manager: (registryConfig, runConfig) => new FileSystemManagerDriver(
2895
- registryConfig,
2896
- runConfig,
2897
- state,
2898
- driverConfig
2899
- ),
2900
- actor: (registryConfig, runConfig, managerDriver, inlineClient) => {
2901
- const actorDriver = new FileSystemActorDriver(
2902
- registryConfig,
2903
- runConfig,
2904
- managerDriver,
2905
- inlineClient,
2906
- state
2907
- );
2908
- state.onRunnerStart(registryConfig, runConfig, inlineClient, actorDriver);
2909
- return actorDriver;
2910
- }
2911
- };
2912
- return driverConfig;
2913
- }
2914
- function createFileSystemDriver(opts) {
2915
- return createFileSystemOrMemoryDriver(true, opts == null ? void 0 : opts.path);
2916
- }
2917
- function createMemoryDriver() {
2918
- return createFileSystemOrMemoryDriver(false);
2919
- }
2920
-
2921
- // src/drivers/default.ts
2922
- function chooseDefaultDriver(runConfig) {
2923
- const engineEndpoint = runConfig.engine || getEnvUniversal("RIVET_ENGINE");
2924
- if (engineEndpoint && runConfig.driver) {
2925
- throw new UserError(
2926
- "Cannot specify both 'engine' and 'driver' in configuration"
2927
- );
2928
- }
2929
- if (runConfig.driver) {
2930
- return runConfig.driver;
2931
- }
2932
- if (engineEndpoint) {
2933
- logger().debug("using rivet engine driver", { endpoint: engineEndpoint });
2934
- return createEngineDriver({ endpoint: engineEndpoint });
2935
- }
2936
- logger().debug("using default file system driver");
2937
- return createFileSystemOrMemoryDriver(true);
2938
- }
2939
-
2940
- // src/manager/router.ts
2941
- import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
2942
- import * as cbor5 from "cbor-x";
2943
- import {
2944
- Hono as Hono3
2945
- } from "hono";
2946
- import { cors } from "hono/cors";
2947
- import { streamSSE } from "hono/streaming";
2948
- import invariant7 from "invariant";
2949
- import { z as z3 } from "zod";
2950
-
2951
- // src/manager/auth.ts
2952
- function getIntentsFromQuery(query) {
2953
- const intents = /* @__PURE__ */ new Set();
2954
- if ("getForId" in query) {
2955
- intents.add("get");
2956
- } else if ("getForKey" in query) {
2957
- intents.add("get");
2958
- } else if ("getOrCreateForKey" in query) {
2959
- intents.add("get");
2960
- intents.add("create");
2961
- } else if ("create" in query) {
2962
- intents.add("create");
2963
- }
2964
- return intents;
2965
- }
2966
- async function getActorNameFromQuery(c, driver, query) {
2967
- if ("getForId" in query) {
2968
- const output = await driver.getForId({
2969
- c,
2970
- name: query.getForId.name,
2971
- actorId: query.getForId.actorId
2972
- });
2973
- if (!output) throw new ActorNotFound(query.getForId.actorId);
2974
- return output.name;
2975
- } else if ("getForKey" in query) {
2976
- return query.getForKey.name;
2977
- } else if ("getOrCreateForKey" in query) {
2978
- return query.getOrCreateForKey.name;
2979
- } else if ("create" in query) {
2980
- return query.create.name;
2981
- } else {
2982
- throw new InvalidRequest("Invalid query format");
2983
- }
2984
- }
2985
- async function authenticateRequest(c, actorDefinition, intents, params) {
2986
- if (!("onAuth" in actorDefinition.config)) {
2987
- throw new Forbidden(
2988
- "Actor requires authentication but no onAuth handler is defined (https://rivet.gg/docs/actors/authentication/). Provide an empty handler to disable auth: `onAuth: () => {}`"
2989
- );
2990
- }
2991
- try {
2992
- const dataOrPromise = actorDefinition.config.onAuth(
2993
- {
2994
- request: c.req.raw,
2995
- intents
2996
- },
2997
- params
2998
- );
2999
- if (dataOrPromise instanceof Promise) {
3000
- return await dataOrPromise;
3001
- } else {
3002
- return dataOrPromise;
3003
- }
3004
- } catch (error) {
3005
- logger2().info("authentication error", { error: stringifyError(error) });
3006
- throw error;
3007
- }
3008
- }
3009
- async function authenticateEndpoint(c, driver, registryConfig, query, additionalIntents, params) {
3010
- const intents = getIntentsFromQuery(query);
3011
- for (const intent of additionalIntents) {
3012
- intents.add(intent);
3013
- }
3014
- const actorName = await getActorNameFromQuery(c, driver, query);
3015
- const actorDefinition = registryConfig.use[actorName];
3016
- if (!actorDefinition) {
3017
- throw new ActorNotFound(actorName);
3018
- }
3019
- return await authenticateRequest(c, actorDefinition, intents, params);
3020
- }
3021
-
3022
- // src/manager/router.ts
3023
- function parseWebSocketProtocols(protocols) {
3024
- let queryRaw;
3025
- let encodingRaw;
3026
- let connParamsRaw;
3027
- if (protocols) {
3028
- const protocolList = protocols.split(",").map((p) => p.trim());
3029
- for (const protocol of protocolList) {
3030
- if (protocol.startsWith("query.")) {
3031
- queryRaw = decodeURIComponent(protocol.substring("query.".length));
3032
- } else if (protocol.startsWith("encoding.")) {
3033
- encodingRaw = protocol.substring("encoding.".length);
3034
- } else if (protocol.startsWith("conn_params.")) {
3035
- connParamsRaw = decodeURIComponent(
3036
- protocol.substring("conn_params.".length)
3037
- );
3038
- }
3039
- }
3040
- }
3041
- return { queryRaw, encodingRaw, connParamsRaw };
3042
- }
3043
- var OPENAPI_ENCODING = z3.string().openapi({
3044
- description: "The encoding format to use for the response (json, cbor)",
3045
- example: "json"
3046
- });
3047
- var OPENAPI_ACTOR_QUERY = z3.string().openapi({
3048
- description: "Actor query information"
3049
- });
3050
- var OPENAPI_CONN_PARAMS = z3.string().openapi({
3051
- description: "Connection parameters"
3052
- });
3053
- var OPENAPI_ACTOR_ID = z3.string().openapi({
3054
- description: "Actor ID (used in some endpoints)",
3055
- example: "actor-123456"
3056
- });
3057
- var OPENAPI_CONN_ID = z3.string().openapi({
3058
- description: "Connection ID",
3059
- example: "conn-123456"
3060
- });
3061
- var OPENAPI_CONN_TOKEN = z3.string().openapi({
3062
- description: "Connection token"
3063
- });
3064
- function buildOpenApiResponses(schema, validateBody) {
3065
- return {
3066
- 200: {
3067
- description: "Success",
3068
- content: validateBody ? {
3069
- "application/json": {
3070
- schema
3071
- }
3072
- } : {}
3073
- },
3074
- 400: {
3075
- description: "User error"
3076
- },
3077
- 500: {
3078
- description: "Internal error"
3079
- }
3080
- };
3081
- }
3082
- function createManagerRouter(registryConfig, runConfig, inlineClientDriver, managerDriver, validateBody) {
3083
- var _a, _b, _c;
3084
- const router = new OpenAPIHono({ strict: false }).basePath(
3085
- runConfig.basePath
3086
- );
3087
- router.use("*", loggerMiddleware(logger2()));
3088
- if (runConfig.cors || ((_a = runConfig.inspector) == null ? void 0 : _a.cors)) {
3089
- router.use("*", async (c, next) => {
3090
- var _a2, _b2, _c2, _d, _e, _f, _g;
3091
- const path3 = c.req.path;
3092
- if (path3.endsWith("/actors/connect/websocket") || path3.includes("/actors/raw/websocket/") || // inspectors implement their own CORS handling
3093
- path3.endsWith("/inspect") || path3.endsWith("/actors/inspect")) {
3094
- return next();
3095
- }
3096
- return cors({
3097
- ...runConfig.cors ?? {},
3098
- ...((_a2 = runConfig.inspector) == null ? void 0 : _a2.cors) ?? {},
3099
- origin: (origin, c2) => {
3100
- var _a3, _b3, _c3;
3101
- const inspectorOrigin = (_b3 = (_a3 = runConfig.inspector) == null ? void 0 : _a3.cors) == null ? void 0 : _b3.origin;
3102
- if (inspectorOrigin !== void 0) {
3103
- if (typeof inspectorOrigin === "function") {
3104
- const allowed = inspectorOrigin(origin, c2);
3105
- if (allowed) return allowed;
3106
- } else if (Array.isArray(inspectorOrigin)) {
3107
- return inspectorOrigin.includes(origin) ? origin : void 0;
3108
- } else {
3109
- return inspectorOrigin;
3110
- }
3111
- }
3112
- if (((_c3 = runConfig.cors) == null ? void 0 : _c3.origin) !== void 0) {
3113
- if (typeof runConfig.cors.origin === "function") {
3114
- const allowed = runConfig.cors.origin(origin, c2);
3115
- if (allowed) return allowed;
3116
- } else {
3117
- return runConfig.cors.origin;
3118
- }
3119
- }
3120
- return null;
3121
- },
3122
- allowMethods: (origin, c2) => {
3123
- var _a3, _b3, _c3;
3124
- const inspectorMethods = (_b3 = (_a3 = runConfig.inspector) == null ? void 0 : _a3.cors) == null ? void 0 : _b3.allowMethods;
3125
- if (inspectorMethods) {
3126
- if (typeof inspectorMethods === "function") {
3127
- return inspectorMethods(origin, c2);
3128
- }
3129
- return inspectorMethods;
3130
- }
3131
- if ((_c3 = runConfig.cors) == null ? void 0 : _c3.allowMethods) {
3132
- if (typeof runConfig.cors.allowMethods === "function") {
3133
- return runConfig.cors.allowMethods(origin, c2);
3134
- }
3135
- return runConfig.cors.allowMethods;
3136
- }
3137
- return [];
3138
- },
3139
- allowHeaders: [
3140
- ...((_b2 = runConfig.cors) == null ? void 0 : _b2.allowHeaders) ?? [],
3141
- ...((_d = (_c2 = runConfig.inspector) == null ? void 0 : _c2.cors) == null ? void 0 : _d.allowHeaders) ?? [],
3142
- ...ALLOWED_PUBLIC_HEADERS,
3143
- "Content-Type",
3144
- "User-Agent"
3145
- ],
3146
- credentials: ((_e = runConfig.cors) == null ? void 0 : _e.credentials) ?? ((_g = (_f = runConfig.inspector) == null ? void 0 : _f.cors) == null ? void 0 : _g.credentials) ?? true
3147
- })(c, next);
3148
- });
3149
- }
3150
- router.get("/", (c) => {
3151
- return c.text(
3152
- "This is an RivetKit registry.\n\nLearn more at https://rivetkit.org"
3153
- );
3154
- });
3155
- {
3156
- const ResolveQuerySchema = z3.object({
3157
- query: z3.any().openapi({
3158
- example: { getForId: { actorId: "actor-123" } }
3159
- })
3160
- }).openapi("ResolveQuery");
3161
- const ResolveResponseSchema = z3.object({
3162
- i: z3.string().openapi({
3163
- example: "actor-123"
3164
- })
3165
- }).openapi("ResolveResponse");
3166
- const resolveRoute = createRoute({
3167
- method: "post",
3168
- path: "/actors/resolve",
3169
- request: {
3170
- body: {
3171
- content: validateBody ? {
3172
- "application/json": {
3173
- schema: ResolveQuerySchema
3174
- }
3175
- } : {}
3176
- },
3177
- headers: z3.object({
3178
- [HEADER_ACTOR_QUERY]: OPENAPI_ACTOR_QUERY
3179
- })
3180
- },
3181
- responses: buildOpenApiResponses(ResolveResponseSchema, validateBody)
3182
- });
3183
- router.openapi(
3184
- resolveRoute,
3185
- (c) => handleResolveRequest(c, registryConfig, managerDriver)
3186
- );
3187
- }
3188
- {
3189
- router.use("*", (c, next) => {
3190
- if (c.req.path.endsWith("/actors/connect/websocket")) {
3191
- return handleWebSocketConnectRequest(
3192
- c,
3193
- registryConfig,
3194
- runConfig,
3195
- managerDriver
3196
- );
3197
- }
3198
- return next();
3199
- });
3200
- const wsRoute = createRoute({
3201
- method: "get",
3202
- path: "/actors/connect/websocket",
3203
- responses: {
3204
- 101: {
3205
- description: "WebSocket upgrade"
3206
- }
3207
- }
3208
- });
3209
- router.openapi(wsRoute, () => {
3210
- throw new Error("Should be unreachable");
3211
- });
3212
- }
3213
- {
3214
- const sseRoute = createRoute({
3215
- method: "get",
3216
- path: "/actors/connect/sse",
3217
- request: {
3218
- headers: z3.object({
3219
- [HEADER_ENCODING]: OPENAPI_ENCODING,
3220
- [HEADER_ACTOR_QUERY]: OPENAPI_ACTOR_QUERY,
3221
- [HEADER_CONN_PARAMS]: OPENAPI_CONN_PARAMS.optional()
3222
- })
3223
- },
3224
- responses: {
3225
- 200: {
3226
- description: "SSE stream",
3227
- content: {
3228
- "text/event-stream": {
3229
- schema: z3.unknown()
3230
- }
3231
- }
3232
- }
3233
- }
3234
- });
3235
- router.openapi(
3236
- sseRoute,
3237
- (c) => handleSseConnectRequest(c, registryConfig, runConfig, managerDriver)
3238
- );
3239
- }
3240
- {
3241
- const ActionParamsSchema = z3.object({
3242
- action: z3.string().openapi({
3243
- param: {
3244
- name: "action",
3245
- in: "path"
3246
- },
3247
- example: "myAction"
3248
- })
3249
- }).openapi("ActionParams");
3250
- const ActionRequestSchema = z3.object({
3251
- query: z3.any().openapi({
3252
- example: { getForId: { actorId: "actor-123" } }
3253
- }),
3254
- body: z3.any().optional().openapi({
3255
- example: { param1: "value1", param2: 123 }
3256
- })
3257
- }).openapi("ActionRequest");
3258
- const ActionResponseSchema = z3.any().openapi("ActionResponse");
3259
- const actionRoute = createRoute({
3260
- method: "post",
3261
- path: "/actors/actions/{action}",
3262
- request: {
3263
- params: ActionParamsSchema,
3264
- body: {
3265
- content: validateBody ? {
3266
- "application/json": {
3267
- schema: ActionRequestSchema
3268
- }
3269
- } : {}
3270
- },
3271
- headers: z3.object({
3272
- [HEADER_ENCODING]: OPENAPI_ENCODING,
3273
- [HEADER_CONN_PARAMS]: OPENAPI_CONN_PARAMS.optional()
3274
- })
3275
- },
3276
- responses: buildOpenApiResponses(ActionResponseSchema, validateBody)
3277
- });
3278
- router.openapi(
3279
- actionRoute,
3280
- (c) => handleActionRequest(c, registryConfig, runConfig, managerDriver)
3281
- );
3282
- }
3283
- {
3284
- const ConnectionMessageRequestSchema = z3.object({
3285
- message: z3.any().openapi({
3286
- example: { type: "message", content: "Hello, actor!" }
3287
- })
3288
- }).openapi("ConnectionMessageRequest");
3289
- const ConnectionMessageResponseSchema = z3.any().openapi("ConnectionMessageResponse");
3290
- const messageRoute = createRoute({
3291
- method: "post",
3292
- path: "/actors/message",
3293
- request: {
3294
- body: {
3295
- content: validateBody ? {
3296
- "application/json": {
3297
- schema: ConnectionMessageRequestSchema
3298
- }
3299
- } : {}
3300
- },
3301
- headers: z3.object({
3302
- [HEADER_ACTOR_ID]: OPENAPI_ACTOR_ID,
3303
- [HEADER_CONN_ID]: OPENAPI_CONN_ID,
3304
- [HEADER_ENCODING]: OPENAPI_ENCODING,
3305
- [HEADER_CONN_TOKEN]: OPENAPI_CONN_TOKEN
3306
- })
3307
- },
3308
- responses: buildOpenApiResponses(
3309
- ConnectionMessageResponseSchema,
3310
- validateBody
3311
- )
3312
- });
3313
- router.openapi(
3314
- messageRoute,
3315
- (c) => handleMessageRequest(c, registryConfig, runConfig, managerDriver)
3316
- );
3317
- }
3318
- {
3319
- const RawHttpRequestBodySchema = z3.any().optional().openapi({
3320
- description: "Raw request body (can be any content type)"
3321
- });
3322
- const RawHttpResponseSchema = z3.any().openapi({
3323
- description: "Raw response from actor's onFetch handler"
3324
- });
3325
- const rawHttpRouteConfig = {
3326
- path: "/actors/raw/http/*",
3327
- request: {
3328
- headers: z3.object({
3329
- [HEADER_ACTOR_QUERY]: OPENAPI_ACTOR_QUERY.optional(),
3330
- [HEADER_CONN_PARAMS]: OPENAPI_CONN_PARAMS.optional()
3331
- }),
3332
- body: {
3333
- content: {
3334
- "*/*": {
3335
- schema: RawHttpRequestBodySchema
3336
- }
3337
- }
3338
- }
3339
- },
3340
- responses: {
3341
- 200: {
3342
- description: "Success - response from actor's onFetch handler",
3343
- content: {
3344
- "*/*": {
3345
- schema: RawHttpResponseSchema
3346
- }
3347
- }
3348
- },
3349
- 404: {
3350
- description: "Actor does not have an onFetch handler"
3351
- },
3352
- 500: {
3353
- description: "Internal server error or invalid response from actor"
3354
- }
3355
- }
3356
- };
3357
- const httpMethods = [
3358
- "get",
3359
- "post",
3360
- "put",
3361
- "delete",
3362
- "patch",
3363
- "head",
3364
- "options"
3365
- ];
3366
- for (const method of httpMethods) {
3367
- const route = createRoute({
3368
- method,
3369
- ...rawHttpRouteConfig
3370
- });
3371
- router.openapi(route, async (c) => {
3372
- return handleRawHttpRequest(
3373
- c,
3374
- registryConfig,
3375
- runConfig,
3376
- managerDriver
3377
- );
3378
- });
3379
- }
3380
- }
3381
- {
3382
- router.use("*", async (c, next) => {
3383
- if (c.req.path.includes("/raw/websocket/")) {
3384
- return handleRawWebSocketRequest(
3385
- c,
3386
- registryConfig,
3387
- runConfig,
3388
- managerDriver
3389
- );
3390
- }
3391
- return next();
3392
- });
3393
- const rawWebSocketRoute = createRoute({
3394
- method: "get",
3395
- path: "/actors/raw/websocket/*",
3396
- request: {},
3397
- responses: {
3398
- 101: {
3399
- description: "WebSocket upgrade successful"
3400
- },
3401
- 400: {
3402
- description: "WebSockets not enabled or invalid request"
3403
- },
3404
- 404: {
3405
- description: "Actor does not have an onWebSocket handler"
3406
- }
3407
- }
3408
- });
3409
- router.openapi(rawWebSocketRoute, () => {
3410
- throw new Error("Should be unreachable");
3411
- });
3412
- }
3413
- if ((_b = runConfig.inspector) == null ? void 0 : _b.enabled) {
3414
- router.route(
3415
- "/actors/inspect",
3416
- new Hono3().use(
3417
- cors(runConfig.inspector.cors),
3418
- secureInspector(runConfig),
3419
- universalActorProxy({
3420
- registryConfig,
3421
- runConfig,
3422
- driver: managerDriver
3423
- })
3424
- ).all(
3425
- "/",
3426
- (c) => (
3427
- // this should be handled by the actor proxy, but just in case
3428
- c.text("Unreachable.", 404)
3429
- )
3430
- )
3431
- );
3432
- router.route(
3433
- "/inspect",
3434
- new Hono3().use(
3435
- cors(runConfig.inspector.cors),
3436
- secureInspector(runConfig),
3437
- async (c, next) => {
3438
- const inspector = managerDriver.inspector;
3439
- invariant7(inspector, "inspector not supported on this platform");
3440
- c.set("inspector", inspector);
3441
- await next();
3442
- }
3443
- ).route("/", createManagerInspectorRouter())
3444
- );
3445
- }
3446
- if (registryConfig.test.enabled) {
3447
- router.post(".test/inline-driver/call", async (c) => {
3448
- const buffer = await c.req.arrayBuffer();
3449
- const { encoding, transport, method, args } = cbor5.decode(new Uint8Array(buffer));
3450
- logger2().debug("received inline request", {
3451
- encoding,
3452
- transport,
3453
- method,
3454
- args
3455
- });
3456
- let response;
3457
- try {
3458
- const output = await inlineClientDriver[method](
3459
- ...args
3460
- );
3461
- response = { ok: output };
3462
- } catch (rawErr) {
3463
- const err = deconstructError(rawErr, logger2(), {}, true);
3464
- response = { err };
3465
- }
3466
- return c.body(cbor5.encode(response));
3467
- });
3468
- router.get(".test/inline-driver/connect-websocket", async (c) => {
3469
- var _a2;
3470
- const upgradeWebSocket = (_a2 = runConfig.getUpgradeWebSocket) == null ? void 0 : _a2.call(runConfig);
3471
- invariant7(upgradeWebSocket, "websockets not supported on this platform");
3472
- return upgradeWebSocket(async (c2) => {
3473
- const {
3474
- actorQuery: actorQueryRaw,
3475
- params: paramsRaw,
3476
- encodingKind
3477
- } = c2.req.query();
3478
- const actorQuery = JSON.parse(actorQueryRaw);
3479
- const params = paramsRaw !== void 0 ? JSON.parse(paramsRaw) : void 0;
3480
- logger2().debug("received test inline driver websocket", {
3481
- actorQuery,
3482
- params,
3483
- encodingKind
3484
- });
3485
- const clientWsPromise = inlineClientDriver.connectWebSocket(
3486
- void 0,
3487
- actorQuery,
3488
- encodingKind,
3489
- params,
3490
- void 0
3491
- );
3492
- return await createTestWebSocketProxy(clientWsPromise, "standard");
3493
- })(c, noopNext());
3494
- });
3495
- router.get(".test/inline-driver/raw-websocket", async (c) => {
3496
- var _a2;
3497
- const upgradeWebSocket = (_a2 = runConfig.getUpgradeWebSocket) == null ? void 0 : _a2.call(runConfig);
3498
- invariant7(upgradeWebSocket, "websockets not supported on this platform");
3499
- return upgradeWebSocket(async (c2) => {
3500
- const {
3501
- actorQuery: actorQueryRaw,
3502
- params: paramsRaw,
3503
- encodingKind,
3504
- path: path3,
3505
- protocols: protocolsRaw
3506
- } = c2.req.query();
3507
- const actorQuery = JSON.parse(actorQueryRaw);
3508
- const params = paramsRaw !== void 0 ? JSON.parse(paramsRaw) : void 0;
3509
- const protocols = protocolsRaw !== void 0 ? JSON.parse(protocolsRaw) : void 0;
3510
- logger2().debug("received test inline driver raw websocket", {
3511
- actorQuery,
3512
- params,
3513
- encodingKind,
3514
- path: path3,
3515
- protocols
3516
- });
3517
- logger2().debug("calling inlineClientDriver.rawWebSocket");
3518
- const clientWsPromise = inlineClientDriver.rawWebSocket(
3519
- void 0,
3520
- actorQuery,
3521
- encodingKind,
3522
- params,
3523
- path3,
3524
- protocols,
3525
- void 0
3526
- );
3527
- logger2().debug("calling createTestWebSocketProxy");
3528
- return await createTestWebSocketProxy(clientWsPromise, "raw");
3529
- })(c, noopNext());
3530
- });
3531
- router.all(".test/inline-driver/raw-http/*", async (c) => {
3532
- const actorQueryHeader = c.req.header(HEADER_ACTOR_QUERY);
3533
- const paramsHeader = c.req.header(HEADER_CONN_PARAMS);
3534
- const encodingHeader = c.req.header(HEADER_ENCODING);
3535
- if (!actorQueryHeader || !encodingHeader) {
3536
- return c.text("Missing required headers", 400);
3537
- }
3538
- const actorQuery = JSON.parse(actorQueryHeader);
3539
- const params = paramsHeader ? JSON.parse(paramsHeader) : void 0;
3540
- const encoding = encodingHeader;
3541
- const fullPath = c.req.path;
3542
- const pathOnly = fullPath.split("/.test/inline-driver/raw-http/")[1] || "";
3543
- const url = new URL(c.req.url);
3544
- const pathWithQuery = pathOnly + url.search;
3545
- logger2().debug("received test inline driver raw http", {
3546
- actorQuery,
3547
- params,
3548
- encoding,
3549
- path: pathWithQuery,
3550
- method: c.req.method
3551
- });
3552
- try {
3553
- const response = await inlineClientDriver.rawHttpRequest(
3554
- void 0,
3555
- actorQuery,
3556
- encoding,
3557
- params,
3558
- pathWithQuery,
3559
- {
3560
- method: c.req.method,
3561
- headers: c.req.raw.headers,
3562
- body: c.req.raw.body
3563
- },
3564
- void 0
3565
- );
3566
- return response;
3567
- } catch (error) {
3568
- logger2().error("error in test inline raw http", {
3569
- error: stringifyError(error)
3570
- });
3571
- const err = deconstructError(error, logger2(), {}, true);
3572
- return c.json(
3573
- {
3574
- error: {
3575
- code: err.code,
3576
- message: err.message,
3577
- metadata: err.metadata
3578
- }
3579
- },
3580
- err.statusCode
3581
- );
3582
- }
3583
- });
3584
- }
3585
- (_c = managerDriver.modifyManagerRouter) == null ? void 0 : _c.call(
3586
- managerDriver,
3587
- registryConfig,
3588
- router
3589
- );
3590
- const mountedRouter = new Hono3();
3591
- mountedRouter.route("/", router);
3592
- mountedRouter.route("/registry", router);
3593
- mountedRouter.notFound(handleRouteNotFound);
3594
- mountedRouter.onError(handleRouteError.bind(void 0, {}));
3595
- return { router: mountedRouter, openapi: router };
3596
- }
3597
- async function queryActor2(c, query, driver) {
3598
- logger2().debug("querying actor", { query });
3599
- let actorOutput;
3600
- if ("getForId" in query) {
3601
- const output = await driver.getForId({
3602
- c,
3603
- name: query.getForId.name,
3604
- actorId: query.getForId.actorId
3605
- });
3606
- if (!output) throw new ActorNotFound(query.getForId.actorId);
3607
- actorOutput = output;
3608
- } else if ("getForKey" in query) {
3609
- const existingActor = await driver.getWithKey({
3610
- c,
3611
- name: query.getForKey.name,
3612
- key: query.getForKey.key
3613
- });
3614
- if (!existingActor) {
3615
- throw new ActorNotFound(
3616
- `${query.getForKey.name}:${JSON.stringify(query.getForKey.key)}`
3617
- );
3618
- }
3619
- actorOutput = existingActor;
3620
- } else if ("getOrCreateForKey" in query) {
3621
- const getOrCreateOutput = await driver.getOrCreateWithKey({
3622
- c,
3623
- name: query.getOrCreateForKey.name,
3624
- key: query.getOrCreateForKey.key,
3625
- input: query.getOrCreateForKey.input,
3626
- region: query.getOrCreateForKey.region
3627
- });
3628
- actorOutput = {
3629
- actorId: getOrCreateOutput.actorId
3630
- };
3631
- } else if ("create" in query) {
3632
- const createOutput = await driver.createActor({
3633
- c,
3634
- name: query.create.name,
3635
- key: query.create.key,
3636
- input: query.create.input,
3637
- region: query.create.region
3638
- });
3639
- actorOutput = {
3640
- actorId: createOutput.actorId
3641
- };
3642
- } else {
3643
- throw new InvalidRequest("Invalid query format");
3644
- }
3645
- logger2().debug("actor query result", {
3646
- actorId: actorOutput.actorId
3647
- });
3648
- return { actorId: actorOutput.actorId };
3649
- }
3650
- async function createTestWebSocketProxy(clientWsPromise, connectionType) {
3651
- let clientWs = null;
3652
- try {
3653
- logger2().debug("awaiting client websocket promise");
3654
- const ws = await clientWsPromise;
3655
- clientWs = ws;
3656
- logger2().debug("client websocket promise resolved", {
3657
- constructor: ws == null ? void 0 : ws.constructor.name
3658
- });
3659
- await new Promise((resolve, reject) => {
3660
- const onOpen = () => {
3661
- logger2().debug("test websocket connection opened");
3662
- resolve();
3663
- };
3664
- const onError = (error) => {
3665
- logger2().error("test websocket connection failed", { error });
3666
- reject(
3667
- new Error(`Failed to open WebSocket: ${error.message || error}`)
3668
- );
3669
- };
3670
- ws.addEventListener("open", onOpen);
3671
- ws.addEventListener("error", onError);
3672
- });
3673
- } catch (error) {
3674
- logger2().error(
3675
- `failed to establish client ${connectionType} websocket connection`,
3676
- { error }
3677
- );
3678
- return {
3679
- onOpen: (_evt, serverWs) => {
3680
- serverWs.close(1011, "Failed to establish connection");
3681
- },
3682
- onMessage: () => {
3683
- },
3684
- onError: () => {
3685
- },
3686
- onClose: () => {
3687
- }
3688
- };
3689
- }
3690
- return {
3691
- onOpen: (_evt, serverWs) => {
3692
- logger2().debug(`test ${connectionType} websocket connection opened`);
3693
- logger2().debug("clientWs info", {
3694
- constructor: clientWs.constructor.name,
3695
- hasAddEventListener: typeof clientWs.addEventListener === "function",
3696
- readyState: clientWs.readyState
3697
- });
3698
- clientWs.addEventListener("message", (clientEvt) => {
3699
- var _a, _b;
3700
- logger2().debug(
3701
- `test ${connectionType} websocket connection message from client`,
3702
- {
3703
- dataType: typeof clientEvt.data,
3704
- isBlob: clientEvt.data instanceof Blob,
3705
- isArrayBuffer: clientEvt.data instanceof ArrayBuffer,
3706
- dataConstructor: (_b = (_a = clientEvt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
3707
- dataStr: typeof clientEvt.data === "string" ? clientEvt.data.substring(0, 100) : void 0
3708
- }
3709
- );
3710
- if (serverWs.readyState === 1) {
3711
- if (clientEvt.data instanceof Blob) {
3712
- clientEvt.data.arrayBuffer().then((buffer) => {
3713
- logger2().debug(
3714
- "converted client blob to arraybuffer, sending to server",
3715
- {
3716
- bufferSize: buffer.byteLength
3717
- }
3718
- );
3719
- serverWs.send(buffer);
3720
- }).catch((error) => {
3721
- logger2().error("failed to convert blob to arraybuffer", {
3722
- error
3723
- });
3724
- });
3725
- } else {
3726
- logger2().debug("sending client data directly to server", {
3727
- dataType: typeof clientEvt.data,
3728
- dataLength: typeof clientEvt.data === "string" ? clientEvt.data.length : void 0
3729
- });
3730
- serverWs.send(clientEvt.data);
3731
- }
3732
- }
3733
- });
3734
- clientWs.addEventListener("close", (clientEvt) => {
3735
- logger2().debug(`test ${connectionType} websocket connection closed`);
3736
- if (serverWs.readyState !== 3) {
3737
- serverWs.close(clientEvt.code, clientEvt.reason);
3738
- }
3739
- });
3740
- clientWs.addEventListener("error", () => {
3741
- logger2().debug(`test ${connectionType} websocket connection error`);
3742
- if (serverWs.readyState !== 3) {
3743
- serverWs.close(1011, "Error in client websocket");
3744
- }
3745
- });
3746
- },
3747
- onMessage: (evt) => {
3748
- var _a, _b;
3749
- logger2().debug("received message from server", {
3750
- dataType: typeof evt.data,
3751
- isBlob: evt.data instanceof Blob,
3752
- isArrayBuffer: evt.data instanceof ArrayBuffer,
3753
- dataConstructor: (_b = (_a = evt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
3754
- dataStr: typeof evt.data === "string" ? evt.data.substring(0, 100) : void 0
3755
- });
3756
- if (clientWs.readyState === 1) {
3757
- if (evt.data instanceof Blob) {
3758
- evt.data.arrayBuffer().then((buffer) => {
3759
- logger2().debug("converted blob to arraybuffer, sending", {
3760
- bufferSize: buffer.byteLength
3761
- });
3762
- clientWs.send(buffer);
3763
- }).catch((error) => {
3764
- logger2().error("failed to convert blob to arraybuffer", {
3765
- error
3766
- });
3767
- });
3768
- } else {
3769
- logger2().debug("sending data directly", {
3770
- dataType: typeof evt.data,
3771
- dataLength: typeof evt.data === "string" ? evt.data.length : void 0
3772
- });
3773
- clientWs.send(evt.data);
3774
- }
3775
- }
3776
- },
3777
- onClose: (event, serverWs) => {
3778
- logger2().debug(`server ${connectionType} websocket closed`, {
3779
- wasClean: event.wasClean,
3780
- code: event.code,
3781
- reason: event.reason
3782
- });
3783
- serverWs.close(1e3, "hack_force_close");
3784
- if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
3785
- clientWs.close(1e3, event.reason);
3786
- }
3787
- },
3788
- onError: (error) => {
3789
- logger2().error(`error in server ${connectionType} websocket`, { error });
3790
- if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
3791
- clientWs.close(1011, "Error in server websocket");
3792
- }
3793
- }
3794
- };
3795
- }
3796
- async function handleSseConnectRequest(c, registryConfig, _runConfig, driver) {
3797
- let encoding;
3798
- try {
3799
- encoding = getRequestEncoding(c.req);
3800
- logger2().debug("sse connection request received", { encoding });
3801
- const params = ConnectRequestSchema.safeParse({
3802
- query: getRequestQuery(c),
3803
- encoding: c.req.header(HEADER_ENCODING),
3804
- connParams: c.req.header(HEADER_CONN_PARAMS)
3805
- });
3806
- if (!params.success) {
3807
- logger2().error("invalid connection parameters", {
3808
- error: params.error
3809
- });
3810
- throw new InvalidRequest(params.error);
3811
- }
3812
- const query = params.data.query;
3813
- const connParams = params.data.connParams ? JSON.parse(params.data.connParams) : void 0;
3814
- const authData = await authenticateEndpoint(
3815
- c,
3816
- driver,
3817
- registryConfig,
3818
- query,
3819
- ["connect"],
3820
- connParams
3821
- );
3822
- const { actorId } = await queryActor2(c, query, driver);
3823
- invariant7(actorId, "Missing actor ID");
3824
- logger2().debug("sse connection to actor", { actorId });
3825
- logger2().debug("using custom proxy mode for sse connection");
3826
- const url = new URL("http://actor/connect/sse");
3827
- const proxyRequestHeaderes = new Headers();
3828
- proxyRequestHeaderes.set(HEADER_ENCODING, params.data.encoding);
3829
- if (params.data.connParams) {
3830
- proxyRequestHeaderes.set(HEADER_CONN_PARAMS, params.data.connParams);
3831
- }
3832
- if (authData) {
3833
- proxyRequestHeaderes.set(HEADER_AUTH_DATA, JSON.stringify(authData));
3834
- }
3835
- const proxyRequest = new Request(url, { headers: proxyRequestHeaderes });
3836
- return await driver.proxyRequest(c, proxyRequest, actorId);
3837
- } catch (error) {
3838
- const { code, message, metadata } = deconstructError(error, logger2(), {
3839
- sseEvent: "setup"
3840
- });
3841
- return streamSSE(c, async (stream) => {
3842
- try {
3843
- if (encoding) {
3844
- const errorMsg = {
3845
- body: {
3846
- tag: "Error",
3847
- val: {
3848
- code,
3849
- message,
3850
- metadata: bufferToArrayBuffer(cbor5.encode(metadata)),
3851
- actionId: null
3852
- }
3853
- }
3854
- };
3855
- const serialized = serializeWithEncoding(
3856
- encoding,
3857
- errorMsg,
3858
- TO_CLIENT_VERSIONED
3859
- );
3860
- await stream.writeSSE({
3861
- data: typeof serialized === "string" ? serialized : Buffer.from(serialized).toString("base64")
3862
- });
3863
- } else {
3864
- await stream.writeSSE({
3865
- data: code,
3866
- event: "error"
3867
- });
3868
- }
3869
- } catch (serializeError) {
3870
- logger2().error("failed to send error to sse client", {
3871
- error: serializeError
3872
- });
3873
- await stream.writeSSE({
3874
- data: "internal error during error handling",
3875
- event: "error"
3876
- });
3877
- }
3878
- });
3879
- }
3880
- }
3881
- async function handleWebSocketConnectRequest(c, registryConfig, runConfig, driver) {
3882
- var _a;
3883
- const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
3884
- if (!upgradeWebSocket) {
3885
- return c.text(
3886
- "WebSockets are not enabled for this driver. Use SSE instead.",
3887
- 400
3888
- );
3889
- }
3890
- let encoding;
3891
- try {
3892
- logger2().debug("websocket connection request received");
3893
- const protocols = c.req.header("sec-websocket-protocol");
3894
- const { queryRaw, encodingRaw, connParamsRaw } = parseWebSocketProtocols(protocols);
3895
- let queryUnvalidated;
3896
- try {
3897
- queryUnvalidated = JSON.parse(queryRaw);
3898
- } catch (error) {
3899
- logger2().error("invalid query json", { error });
3900
- throw new InvalidQueryJSON(error);
3901
- }
3902
- let connParamsUnvalidated = null;
3903
- try {
3904
- if (connParamsRaw) {
3905
- connParamsUnvalidated = JSON.parse(connParamsRaw);
3906
- }
3907
- } catch (error) {
3908
- logger2().error("invalid conn params", { error });
3909
- throw new InvalidParams(
3910
- `Invalid params JSON: ${stringifyError(error)}`
3911
- );
3912
- }
3913
- const params = ConnectWebSocketRequestSchema.safeParse({
3914
- query: queryUnvalidated,
3915
- encoding: encodingRaw,
3916
- connParams: connParamsUnvalidated
3917
- });
3918
- if (!params.success) {
3919
- logger2().error("invalid connection parameters", {
3920
- error: params.error
3921
- });
3922
- throw new InvalidRequest(params.error);
3923
- }
3924
- encoding = params.data.encoding;
3925
- const authData = await authenticateEndpoint(
3926
- c,
3927
- driver,
3928
- registryConfig,
3929
- params.data.query,
3930
- ["connect"],
3931
- connParamsRaw
3932
- );
3933
- const { actorId } = await queryActor2(c, params.data.query, driver);
3934
- logger2().debug("found actor for websocket connection", {
3935
- actorId
3936
- });
3937
- invariant7(actorId, "missing actor id");
3938
- return await driver.proxyWebSocket(
3939
- c,
3940
- PATH_CONNECT_WEBSOCKET,
3941
- actorId,
3942
- params.data.encoding,
3943
- params.data.connParams,
3944
- authData
3945
- );
3946
- } catch (error) {
3947
- const { code, message, metadata } = deconstructError(error, logger2(), {
3948
- wsEvent: "setup"
3949
- });
3950
- return await upgradeWebSocket(() => ({
3951
- onOpen: (_evt, ws) => {
3952
- if (encoding) {
3953
- try {
3954
- const errorMsg = {
3955
- body: {
3956
- tag: "Error",
3957
- val: {
3958
- code,
3959
- message,
3960
- metadata: bufferToArrayBuffer(cbor5.encode(metadata)),
3961
- actionId: null
3962
- }
3963
- }
3964
- };
3965
- const serialized = serializeWithEncoding(
3966
- encoding,
3967
- errorMsg,
3968
- TO_CLIENT_VERSIONED
3969
- );
3970
- ws.send(serialized);
3971
- ws.close(1011, code);
3972
- } catch (serializeError) {
3973
- logger2().error("failed to send error to websocket client", {
3974
- error: serializeError
3975
- });
3976
- ws.close(1011, "internal error during error handling");
3977
- }
3978
- } else {
3979
- ws.close(1011, code);
3980
- }
3981
- }
3982
- }))(c, noopNext());
3983
- }
3984
- }
3985
- async function handleMessageRequest(c, _registryConfig, _runConfig, driver) {
3986
- logger2().debug("connection message request received");
3987
- try {
3988
- const params = ConnMessageRequestSchema.safeParse({
3989
- actorId: c.req.header(HEADER_ACTOR_ID),
3990
- connId: c.req.header(HEADER_CONN_ID),
3991
- encoding: c.req.header(HEADER_ENCODING),
3992
- connToken: c.req.header(HEADER_CONN_TOKEN)
3993
- });
3994
- if (!params.success) {
3995
- logger2().error("invalid connection parameters", {
3996
- error: params.error
3997
- });
3998
- throw new InvalidRequest(params.error);
3999
- }
4000
- const { actorId, connId, encoding, connToken } = params.data;
4001
- const url = new URL("http://actor/connections/message");
4002
- const proxyRequestHeaders = new Headers();
4003
- proxyRequestHeaders.set(HEADER_ENCODING, encoding);
4004
- proxyRequestHeaders.set(HEADER_CONN_ID, connId);
4005
- proxyRequestHeaders.set(HEADER_CONN_TOKEN, connToken);
4006
- const proxyRequest = new Request(url, {
4007
- method: "POST",
4008
- body: c.req.raw.body,
4009
- duplex: "half",
4010
- headers: proxyRequestHeaders
4011
- });
4012
- return await driver.proxyRequest(c, proxyRequest, actorId);
4013
- } catch (error) {
4014
- logger2().error("error proxying connection message", { error });
4015
- if (!ActorError.isActorError(error)) {
4016
- throw new ProxyError("connection message", error);
4017
- } else {
4018
- throw error;
4019
- }
4020
- }
4021
- }
4022
- async function handleActionRequest(c, registryConfig, _runConfig, driver) {
4023
- try {
4024
- const actionName = c.req.param("action");
4025
- logger2().debug("action call received", { actionName });
4026
- const params = ConnectRequestSchema.safeParse({
4027
- query: getRequestQuery(c),
4028
- encoding: c.req.header(HEADER_ENCODING),
4029
- connParams: c.req.header(HEADER_CONN_PARAMS)
4030
- });
4031
- if (!params.success) {
4032
- logger2().error("invalid connection parameters", {
4033
- error: params.error
4034
- });
4035
- throw new InvalidRequest(params.error);
4036
- }
4037
- const connParams = params.data.connParams ? JSON.parse(params.data.connParams) : void 0;
4038
- const authData = await authenticateEndpoint(
4039
- c,
4040
- driver,
4041
- registryConfig,
4042
- params.data.query,
4043
- ["action"],
4044
- connParams
4045
- );
4046
- const { actorId } = await queryActor2(c, params.data.query, driver);
4047
- logger2().debug("found actor for action", { actorId });
4048
- invariant7(actorId, "Missing actor ID");
4049
- const url = new URL(
4050
- `http://actor/action/${encodeURIComponent(actionName)}`
4051
- );
4052
- const proxyRequestHeaders = new Headers();
4053
- proxyRequestHeaders.set(HEADER_ENCODING, params.data.encoding);
4054
- if (params.data.connParams) {
4055
- proxyRequestHeaders.set(HEADER_CONN_PARAMS, params.data.connParams);
4056
- }
4057
- if (authData) {
4058
- proxyRequestHeaders.set(HEADER_AUTH_DATA, JSON.stringify(authData));
4059
- }
4060
- const proxyRequest = new Request(url, {
4061
- method: "POST",
4062
- body: c.req.raw.body,
4063
- headers: proxyRequestHeaders
4064
- });
4065
- return await driver.proxyRequest(c, proxyRequest, actorId);
4066
- } catch (error) {
4067
- logger2().error("error in action handler", { error: stringifyError(error) });
4068
- if (!ActorError.isActorError(error)) {
4069
- throw new ProxyError("Action call", error);
4070
- } else {
4071
- throw error;
4072
- }
4073
- }
4074
- }
4075
- async function handleResolveRequest(c, registryConfig, driver) {
4076
- const encoding = getRequestEncoding(c.req);
4077
- logger2().debug("resolve request encoding", { encoding });
4078
- const params = ResolveRequestSchema.safeParse({
4079
- query: getRequestQuery(c),
4080
- connParams: c.req.header(HEADER_CONN_PARAMS)
4081
- });
4082
- if (!params.success) {
4083
- logger2().error("invalid connection parameters", {
4084
- error: params.error
4085
- });
4086
- throw new InvalidRequest(params.error);
4087
- }
4088
- const connParams = params.data.connParams ? JSON.parse(params.data.connParams) : void 0;
4089
- const query = params.data.query;
4090
- await authenticateEndpoint(c, driver, registryConfig, query, [], connParams);
4091
- const { actorId } = await queryActor2(c, query, driver);
4092
- logger2().debug("resolved actor", { actorId });
4093
- invariant7(actorId, "Missing actor ID");
4094
- const response = {
4095
- actorId
4096
- };
4097
- const serialized = serializeWithEncoding(
4098
- encoding,
4099
- response,
4100
- HTTP_RESOLVE_RESPONSE_VERSIONED
4101
- );
4102
- return c.body(serialized);
4103
- }
4104
- async function handleRawHttpRequest(c, registryConfig, _runConfig, driver) {
4105
- try {
4106
- const subpath = c.req.path.split("/raw/http/")[1] || "";
4107
- logger2().debug("raw http request received", { subpath });
4108
- const queryHeader = c.req.header(HEADER_ACTOR_QUERY);
4109
- if (!queryHeader) {
4110
- throw new InvalidRequest("Missing actor query header");
4111
- }
4112
- const query = JSON.parse(queryHeader);
4113
- const connParamsHeader = c.req.header(HEADER_CONN_PARAMS);
4114
- const connParams = connParamsHeader ? JSON.parse(connParamsHeader) : void 0;
4115
- const authData = await authenticateEndpoint(
4116
- c,
4117
- driver,
4118
- registryConfig,
4119
- query,
4120
- ["action"],
4121
- connParams
4122
- );
4123
- const { actorId } = await queryActor2(c, query, driver);
4124
- logger2().debug("found actor for raw http", { actorId });
4125
- invariant7(actorId, "Missing actor ID");
4126
- const originalUrl = new URL(c.req.url);
4127
- const url = new URL(
4128
- `http://actor/raw/http/${subpath}${originalUrl.search}`
4129
- );
4130
- logger2().debug("rewriting http url", {
4131
- from: c.req.url,
4132
- to: url
4133
- });
4134
- const proxyRequestHeaders = new Headers(c.req.raw.headers);
4135
- if (connParams) {
4136
- proxyRequestHeaders.set(HEADER_CONN_PARAMS, JSON.stringify(connParams));
4137
- }
4138
- if (authData) {
4139
- proxyRequestHeaders.set(HEADER_AUTH_DATA, JSON.stringify(authData));
4140
- }
4141
- const proxyRequest = new Request(url, {
4142
- method: c.req.method,
4143
- headers: proxyRequestHeaders,
4144
- body: c.req.raw.body
4145
- });
4146
- return await driver.proxyRequest(c, proxyRequest, actorId);
4147
- } catch (error) {
4148
- logger2().error("error in raw http handler", {
4149
- error: stringifyError(error)
4150
- });
4151
- if (!ActorError.isActorError(error)) {
4152
- throw new ProxyError("Raw HTTP request", error);
4153
- } else {
4154
- throw error;
4155
- }
4156
- }
4157
- }
4158
- async function handleRawWebSocketRequest(c, registryConfig, runConfig, driver) {
4159
- var _a;
4160
- const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
4161
- if (!upgradeWebSocket) {
4162
- return c.text("WebSockets are not enabled for this driver.", 400);
4163
- }
4164
- try {
4165
- const subpath = c.req.path.split("/raw/websocket/")[1] || "";
4166
- logger2().debug("raw websocket request received", { subpath });
4167
- const protocols = c.req.header("sec-websocket-protocol");
4168
- const {
4169
- queryRaw: queryFromProtocol,
4170
- connParamsRaw: connParamsFromProtocol
4171
- } = parseWebSocketProtocols(protocols);
4172
- if (!queryFromProtocol) {
4173
- throw new InvalidRequest("Missing query in WebSocket protocol");
4174
- }
4175
- const query = JSON.parse(queryFromProtocol);
4176
- let connParams;
4177
- if (connParamsFromProtocol) {
4178
- connParams = JSON.parse(connParamsFromProtocol);
4179
- }
4180
- const authData = await authenticateEndpoint(
4181
- c,
4182
- driver,
4183
- registryConfig,
4184
- query,
4185
- ["action"],
4186
- connParams
4187
- );
4188
- const { actorId } = await queryActor2(c, query, driver);
4189
- logger2().debug("found actor for raw websocket", { actorId });
4190
- invariant7(actorId, "Missing actor ID");
4191
- logger2().debug("using custom proxy mode for raw websocket");
4192
- const originalUrl = new URL(c.req.url);
4193
- const proxyPath = `${PATH_RAW_WEBSOCKET_PREFIX}${subpath}${originalUrl.search}`;
4194
- logger2().debug("manager router proxyWebSocket", {
4195
- originalUrl: c.req.url,
4196
- subpath,
4197
- search: originalUrl.search,
4198
- proxyPath
4199
- });
4200
- return await driver.proxyWebSocket(
4201
- c,
4202
- proxyPath,
4203
- actorId,
4204
- "json",
4205
- // Default encoding for raw WebSocket
4206
- connParams,
4207
- authData
4208
- );
4209
- } catch (error) {
4210
- const { code } = deconstructError(error, logger2(), {
4211
- wsEvent: "setup"
4212
- });
4213
- return await upgradeWebSocket(() => ({
4214
- onOpen: (_evt, ws) => {
4215
- ws.close(1011, code);
4216
- }
4217
- }))(c, noopNext());
4218
- }
4219
- }
4220
- function universalActorProxy({
4221
- registryConfig,
4222
- runConfig,
4223
- driver
4224
- }) {
4225
- return async (c, _next) => {
4226
- if (c.req.header("upgrade") === "websocket") {
4227
- return handleRawWebSocketRequest(c, registryConfig, runConfig, driver);
4228
- } else {
4229
- const queryHeader = c.req.header(HEADER_ACTOR_QUERY);
4230
- if (!queryHeader) {
4231
- throw new InvalidRequest("Missing actor query header");
4232
- }
4233
- const query = ActorQuerySchema.parse(JSON.parse(queryHeader));
4234
- const { actorId } = await queryActor2(c, query, driver);
4235
- const url = new URL(c.req.url);
4236
- url.hostname = "actor";
4237
- url.pathname = url.pathname.replace(new RegExp(`^${runConfig.basePath}`, ""), "").replace(/^\/?registry\/actors/, "").replace(/^\/?actors/, "");
4238
- const proxyRequest = new Request(url, {
4239
- method: c.req.method,
4240
- headers: c.req.raw.headers,
4241
- body: c.req.raw.body
4242
- });
4243
- return await driver.proxyRequest(c, proxyRequest, actorId);
4244
- }
4245
- };
4246
- }
4247
-
4248
- // src/registry/config.ts
4249
- import { z as z4 } from "zod";
4250
- var ActorsSchema = z4.record(
4251
- z4.string(),
4252
- z4.custom()
4253
- );
4254
- var TestConfigSchema = z4.object({ enabled: z4.boolean() });
4255
- var RegistryConfigSchema = z4.object({
4256
- use: z4.record(z4.string(), z4.custom()),
4257
- // TODO: Find a better way of passing around the test config
4258
- /**
4259
- * Test configuration.
4260
- *
4261
- * DO NOT MANUALLY ENABLE. THIS IS USED INTERNALLY.
4262
- * @internal
4263
- **/
4264
- test: TestConfigSchema.optional().default({ enabled: false })
4265
- });
4266
-
4267
- // src/registry/log.ts
4268
- var LOGGER_NAME5 = "registry";
4269
- function logger8() {
4270
- return getLogger(LOGGER_NAME5);
4271
- }
4272
-
4273
- // src/registry/serve.ts
4274
- import { Hono as Hono4 } from "hono";
4275
- async function crossPlatformServe(rivetKitRouter, userRouter) {
4276
- const app = userRouter ?? new Hono4();
4277
- let serve;
4278
- try {
4279
- const dep = await import("@hono/node-server");
4280
- serve = dep.serve;
4281
- } catch (err) {
4282
- logger8().error(
4283
- "failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'"
4284
- );
4285
- process.exit(1);
4286
- }
4287
- app.route("/registry", rivetKitRouter);
4288
- let createNodeWebSocket;
4289
- try {
4290
- const dep = await import("@hono/node-ws");
4291
- createNodeWebSocket = dep.createNodeWebSocket;
4292
- } catch (err) {
4293
- logger8().error(
4294
- "failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'"
4295
- );
4296
- process.exit(1);
4297
- }
4298
- const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
4299
- app
4300
- });
4301
- const port = Number.parseInt(
4302
- getEnvUniversal("PORT") ?? getEnvUniversal("PORT_HTTP") ?? "8080"
4303
- );
4304
- const server = serve(
4305
- { fetch: app.fetch, port },
4306
- () => logger8().info("server listening", { port })
4307
- );
4308
- injectWebSocket(server);
4309
- return { upgradeWebSocket };
4310
- }
4311
-
4312
- // src/registry/mod.ts
4313
- var Registry = class {
4314
- #config;
4315
- get config() {
4316
- return this.#config;
4317
- }
4318
- constructor(config2) {
4319
- this.#config = config2;
4320
- }
4321
- /**
4322
- * Runs the registry for a server.
4323
- */
4324
- createServer(inputConfig) {
4325
- var _a, _b;
4326
- const config2 = RunConfigSchema.parse(inputConfig);
4327
- const driver = chooseDefaultDriver(config2);
4328
- let upgradeWebSocket;
4329
- if (!config2.getUpgradeWebSocket) {
4330
- config2.getUpgradeWebSocket = () => upgradeWebSocket;
4331
- }
4332
- const managerDriver = driver.manager(this.#config, config2);
4333
- const clientDriver = createInlineClientDriver(managerDriver);
4334
- const { router: hono } = createManagerRouter(
4335
- this.#config,
4336
- config2,
4337
- clientDriver,
4338
- managerDriver,
4339
- false
4340
- );
4341
- const client = createClientWithDriver(clientDriver);
4342
- const driverLog = ((_a = managerDriver.extraStartupLog) == null ? void 0 : _a.call(managerDriver)) ?? {};
4343
- logger8().info("rivetkit ready", {
4344
- driver: driver.name,
4345
- definitions: Object.keys(this.#config.use).length,
4346
- ...driverLog
4347
- });
4348
- if ((_b = config2.inspector) == null ? void 0 : _b.enabled) {
4349
- logger8().info("inspector ready", {
4350
- url: getInspectorUrl(config2)
4351
- });
4352
- }
4353
- if (config2.role === "all" || config2.role === "runner") {
4354
- const inlineClient = createClientWithDriver(
4355
- createInlineClientDriver(managerDriver)
4356
- );
4357
- const _actorDriver = driver.actor(
4358
- this.#config,
4359
- config2,
4360
- managerDriver,
4361
- inlineClient
4362
- );
4363
- }
4364
- return {
4365
- client,
4366
- hono,
4367
- handler: async (req) => await hono.fetch(req),
4368
- serve: async (app) => {
4369
- const out = await crossPlatformServe(hono, app);
4370
- upgradeWebSocket = out.upgradeWebSocket;
4371
- }
4372
- };
4373
- }
4374
- /**
4375
- * Runs the registry as a standalone server.
4376
- */
4377
- async runServer(inputConfig) {
4378
- const { serve } = this.createServer(inputConfig);
4379
- serve();
4380
- }
4381
- };
4382
- function setup(input) {
4383
- const config2 = RegistryConfigSchema.parse(input);
4384
- return new Registry(config2);
4385
- }
4386
-
4387
- export {
4388
- GenericConnGlobalState,
4389
- createGenericConnDrivers,
4390
- PATH_CONNECT_WEBSOCKET,
4391
- PATH_RAW_WEBSOCKET_PREFIX,
4392
- createActorRouter,
4393
- actor,
4394
- InlineWebSocketAdapter2,
4395
- createEngineDriver,
4396
- createInlineClientDriver,
4397
- createFileSystemOrMemoryDriver,
4398
- createFileSystemDriver,
4399
- createMemoryDriver,
4400
- createManagerRouter,
4401
- RegistryConfigSchema,
4402
- Registry,
4403
- setup
4404
- };
4405
- //! These configs configs hold anything that's not platform-specific about running actors.
4406
- //# sourceMappingURL=chunk-OV6AYD4S.js.map