rivetkit 2.0.24-rc.1 → 2.0.25-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/schemas/actor-persist/v1.ts +6 -0
  2. package/dist/schemas/actor-persist/v2.ts +9 -3
  3. package/dist/schemas/actor-persist/v3.ts +280 -0
  4. package/dist/schemas/client-protocol/v1.ts +6 -0
  5. package/dist/schemas/client-protocol/v2.ts +438 -0
  6. package/dist/schemas/file-system-driver/v1.ts +6 -0
  7. package/dist/schemas/file-system-driver/v2.ts +142 -0
  8. package/dist/tsup/actor/errors.cjs +2 -4
  9. package/dist/tsup/actor/errors.cjs.map +1 -1
  10. package/dist/tsup/actor/errors.d.cts +7 -10
  11. package/dist/tsup/actor/errors.d.ts +7 -10
  12. package/dist/tsup/actor/errors.js +9 -11
  13. package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.cts → actor-router-consts-DzI2szci.d.cts} +5 -9
  14. package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.ts → actor-router-consts-DzI2szci.d.ts} +5 -9
  15. package/dist/tsup/{chunk-ZTH3KYFH.cjs → chunk-3FG5OJ3G.cjs} +3 -3
  16. package/dist/tsup/{chunk-ZTH3KYFH.cjs.map → chunk-3FG5OJ3G.cjs.map} +1 -1
  17. package/dist/tsup/{chunk-BLK27ES3.js → chunk-6JN6W6G3.js} +44 -56
  18. package/dist/tsup/chunk-6JN6W6G3.js.map +1 -0
  19. package/dist/tsup/chunk-7IBNNGQ2.js +514 -0
  20. package/dist/tsup/chunk-7IBNNGQ2.js.map +1 -0
  21. package/dist/tsup/{chunk-36JJ4IQB.cjs → chunk-AZATXPR4.cjs} +4 -8
  22. package/dist/tsup/chunk-AZATXPR4.cjs.map +1 -0
  23. package/dist/tsup/chunk-B7MENRD5.cjs +5694 -0
  24. package/dist/tsup/chunk-B7MENRD5.cjs.map +1 -0
  25. package/dist/tsup/{chunk-BOMZS2TJ.js → chunk-BBVFDEYD.js} +9 -9
  26. package/dist/tsup/chunk-BBVFDEYD.js.map +1 -0
  27. package/dist/tsup/{chunk-KSRXX3Z4.cjs → chunk-D6762AOA.cjs} +20 -25
  28. package/dist/tsup/chunk-D6762AOA.cjs.map +1 -0
  29. package/dist/tsup/{chunk-2JYPS5YM.cjs → chunk-E63WZNMR.cjs} +6 -6
  30. package/dist/tsup/chunk-E63WZNMR.cjs.map +1 -0
  31. package/dist/tsup/{chunk-YBG6R7LX.js → chunk-EDGN4OC7.js} +3 -7
  32. package/dist/tsup/chunk-EDGN4OC7.js.map +1 -0
  33. package/dist/tsup/{chunk-BYMKMOBS.js → chunk-FLOQ3UWM.js} +1844 -1681
  34. package/dist/tsup/chunk-FLOQ3UWM.js.map +1 -0
  35. package/dist/tsup/{chunk-7L65NNWP.cjs → chunk-H7GV5DIW.cjs} +187 -185
  36. package/dist/tsup/chunk-H7GV5DIW.cjs.map +1 -0
  37. package/dist/tsup/{chunk-227FEWMB.js → chunk-HZYZ7JSF.js} +3322 -2251
  38. package/dist/tsup/chunk-HZYZ7JSF.js.map +1 -0
  39. package/dist/tsup/{chunk-FX7TWFQR.js → chunk-IDJK7ILQ.js} +2 -6
  40. package/dist/tsup/chunk-IDJK7ILQ.js.map +1 -0
  41. package/dist/tsup/{chunk-VHGY7PU5.cjs → chunk-ILFXA4AL.cjs} +1900 -1737
  42. package/dist/tsup/chunk-ILFXA4AL.cjs.map +1 -0
  43. package/dist/tsup/chunk-MV6M3FDL.cjs +514 -0
  44. package/dist/tsup/chunk-MV6M3FDL.cjs.map +1 -0
  45. package/dist/tsup/{chunk-PLUN2NQT.js → chunk-NWBKMCWC.js} +189 -187
  46. package/dist/tsup/chunk-NWBKMCWC.js.map +1 -0
  47. package/dist/tsup/{chunk-CD33GT6Z.js → chunk-QIHBDXTO.js} +2 -2
  48. package/dist/tsup/{chunk-G64QUEDJ.js → chunk-W6RDS6NW.js} +23 -28
  49. package/dist/tsup/chunk-W6RDS6NW.js.map +1 -0
  50. package/dist/tsup/{chunk-INNFK746.cjs → chunk-WQU4M4ZC.cjs} +10 -14
  51. package/dist/tsup/chunk-WQU4M4ZC.cjs.map +1 -0
  52. package/dist/tsup/{chunk-SHVX2QUR.cjs → chunk-XKZA47XS.cjs} +17 -17
  53. package/dist/tsup/chunk-XKZA47XS.cjs.map +1 -0
  54. package/dist/tsup/{chunk-HHFKKVLR.cjs → chunk-YHWIOWVA.cjs} +45 -57
  55. package/dist/tsup/chunk-YHWIOWVA.cjs.map +1 -0
  56. package/dist/tsup/{chunk-YBHYXIP6.js → chunk-YVL6IRUM.js} +3 -3
  57. package/dist/tsup/chunk-YVL6IRUM.js.map +1 -0
  58. package/dist/tsup/client/mod.cjs +9 -9
  59. package/dist/tsup/client/mod.d.cts +5 -7
  60. package/dist/tsup/client/mod.d.ts +5 -7
  61. package/dist/tsup/client/mod.js +8 -8
  62. package/dist/tsup/common/log.cjs +3 -3
  63. package/dist/tsup/common/log.js +2 -2
  64. package/dist/tsup/common/websocket.cjs +4 -4
  65. package/dist/tsup/common/websocket.js +3 -3
  66. package/dist/tsup/{conn-B3Vhbgnd.d.ts → config-BRDYDraU.d.cts} +1119 -1047
  67. package/dist/tsup/{conn-DJWL3nGx.d.cts → config-Bo-blHpJ.d.ts} +1119 -1047
  68. package/dist/tsup/driver-helpers/mod.cjs +5 -13
  69. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  70. package/dist/tsup/driver-helpers/mod.d.cts +11 -9
  71. package/dist/tsup/driver-helpers/mod.d.ts +11 -9
  72. package/dist/tsup/driver-helpers/mod.js +14 -22
  73. package/dist/tsup/driver-test-suite/mod.cjs +474 -303
  74. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  75. package/dist/tsup/driver-test-suite/mod.d.cts +6 -9
  76. package/dist/tsup/driver-test-suite/mod.d.ts +6 -9
  77. package/dist/tsup/driver-test-suite/mod.js +1085 -914
  78. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  79. package/dist/tsup/inspector/mod.cjs +6 -6
  80. package/dist/tsup/inspector/mod.d.cts +5 -7
  81. package/dist/tsup/inspector/mod.d.ts +5 -7
  82. package/dist/tsup/inspector/mod.js +5 -5
  83. package/dist/tsup/mod.cjs +10 -16
  84. package/dist/tsup/mod.cjs.map +1 -1
  85. package/dist/tsup/mod.d.cts +23 -25
  86. package/dist/tsup/mod.d.ts +23 -25
  87. package/dist/tsup/mod.js +17 -23
  88. package/dist/tsup/test/mod.cjs +11 -11
  89. package/dist/tsup/test/mod.d.cts +4 -6
  90. package/dist/tsup/test/mod.d.ts +4 -6
  91. package/dist/tsup/test/mod.js +10 -10
  92. package/dist/tsup/utils.cjs +3 -5
  93. package/dist/tsup/utils.cjs.map +1 -1
  94. package/dist/tsup/utils.d.cts +1 -2
  95. package/dist/tsup/utils.d.ts +1 -2
  96. package/dist/tsup/utils.js +2 -4
  97. package/package.json +13 -6
  98. package/src/actor/config.ts +56 -44
  99. package/src/actor/conn/driver.ts +61 -0
  100. package/src/actor/conn/drivers/http.ts +17 -0
  101. package/src/actor/conn/drivers/raw-request.ts +24 -0
  102. package/src/actor/conn/drivers/raw-websocket.ts +65 -0
  103. package/src/actor/conn/drivers/websocket.ts +129 -0
  104. package/src/actor/conn/mod.ts +232 -0
  105. package/src/actor/conn/persisted.ts +81 -0
  106. package/src/actor/conn/state-manager.ts +196 -0
  107. package/src/actor/contexts/action.ts +23 -0
  108. package/src/actor/{context.ts → contexts/actor.ts} +19 -8
  109. package/src/actor/contexts/conn-init.ts +31 -0
  110. package/src/actor/contexts/conn.ts +48 -0
  111. package/src/actor/contexts/create-conn-state.ts +13 -0
  112. package/src/actor/contexts/on-before-connect.ts +13 -0
  113. package/src/actor/contexts/on-connect.ts +22 -0
  114. package/src/actor/contexts/request.ts +48 -0
  115. package/src/actor/contexts/websocket.ts +48 -0
  116. package/src/actor/definition.ts +3 -3
  117. package/src/actor/driver.ts +36 -5
  118. package/src/actor/errors.ts +19 -24
  119. package/src/actor/instance/connection-manager.ts +465 -0
  120. package/src/actor/instance/event-manager.ts +292 -0
  121. package/src/actor/instance/kv.ts +15 -0
  122. package/src/actor/instance/mod.ts +1107 -0
  123. package/src/actor/instance/persisted.ts +67 -0
  124. package/src/actor/instance/schedule-manager.ts +349 -0
  125. package/src/actor/instance/state-manager.ts +502 -0
  126. package/src/actor/mod.ts +13 -16
  127. package/src/actor/protocol/old.ts +131 -43
  128. package/src/actor/protocol/serde.ts +19 -4
  129. package/src/actor/router-endpoints.ts +61 -586
  130. package/src/actor/router-websocket-endpoints.ts +408 -0
  131. package/src/actor/router.ts +63 -197
  132. package/src/actor/schedule.ts +1 -1
  133. package/src/client/actor-conn.ts +183 -249
  134. package/src/client/actor-handle.ts +29 -6
  135. package/src/client/client.ts +0 -4
  136. package/src/client/config.ts +1 -4
  137. package/src/client/mod.ts +0 -1
  138. package/src/client/raw-utils.ts +3 -3
  139. package/src/client/utils.ts +85 -39
  140. package/src/common/actor-router-consts.ts +5 -12
  141. package/src/common/{inline-websocket-adapter2.ts → inline-websocket-adapter.ts} +26 -48
  142. package/src/common/log.ts +1 -1
  143. package/src/common/router.ts +28 -17
  144. package/src/common/utils.ts +2 -0
  145. package/src/driver-helpers/mod.ts +7 -10
  146. package/src/driver-helpers/utils.ts +18 -9
  147. package/src/driver-test-suite/mod.ts +26 -50
  148. package/src/driver-test-suite/test-inline-client-driver.ts +27 -51
  149. package/src/driver-test-suite/tests/actor-conn-hibernation.ts +150 -0
  150. package/src/driver-test-suite/tests/actor-conn-state.ts +1 -4
  151. package/src/driver-test-suite/tests/actor-conn.ts +5 -9
  152. package/src/driver-test-suite/tests/actor-destroy.ts +294 -0
  153. package/src/driver-test-suite/tests/actor-driver.ts +0 -7
  154. package/src/driver-test-suite/tests/actor-handle.ts +12 -12
  155. package/src/driver-test-suite/tests/actor-metadata.ts +1 -1
  156. package/src/driver-test-suite/tests/manager-driver.ts +1 -1
  157. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +8 -8
  158. package/src/driver-test-suite/tests/raw-http-request-properties.ts +6 -5
  159. package/src/driver-test-suite/tests/raw-http.ts +5 -5
  160. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +7 -7
  161. package/src/driver-test-suite/tests/request-access.ts +4 -4
  162. package/src/driver-test-suite/utils.ts +6 -10
  163. package/src/drivers/engine/actor-driver.ts +614 -424
  164. package/src/drivers/engine/mod.ts +0 -1
  165. package/src/drivers/file-system/actor.ts +24 -12
  166. package/src/drivers/file-system/global-state.ts +427 -37
  167. package/src/drivers/file-system/manager.ts +71 -83
  168. package/src/drivers/file-system/mod.ts +3 -0
  169. package/src/drivers/file-system/utils.ts +18 -8
  170. package/src/engine-process/mod.ts +38 -38
  171. package/src/inspector/utils.ts +7 -5
  172. package/src/manager/driver.ts +11 -4
  173. package/src/manager/gateway.ts +4 -29
  174. package/src/manager/protocol/mod.ts +0 -2
  175. package/src/manager/protocol/query.ts +0 -4
  176. package/src/manager/router.ts +67 -64
  177. package/src/manager-api/actors.ts +13 -0
  178. package/src/mod.ts +1 -3
  179. package/src/registry/mod.ts +20 -20
  180. package/src/registry/serve.ts +9 -14
  181. package/src/remote-manager-driver/actor-websocket-client.ts +1 -16
  182. package/src/remote-manager-driver/api-endpoints.ts +13 -1
  183. package/src/remote-manager-driver/api-utils.ts +8 -0
  184. package/src/remote-manager-driver/metadata.ts +58 -0
  185. package/src/remote-manager-driver/mod.ts +47 -62
  186. package/src/remote-manager-driver/ws-proxy.ts +1 -1
  187. package/src/schemas/actor-persist/mod.ts +1 -1
  188. package/src/schemas/actor-persist/versioned.ts +56 -31
  189. package/src/schemas/client-protocol/mod.ts +1 -1
  190. package/src/schemas/client-protocol/versioned.ts +41 -21
  191. package/src/schemas/client-protocol-zod/mod.ts +103 -0
  192. package/src/schemas/file-system-driver/mod.ts +1 -1
  193. package/src/schemas/file-system-driver/versioned.ts +42 -19
  194. package/src/serde.ts +33 -11
  195. package/src/test/mod.ts +7 -3
  196. package/src/utils/node.ts +173 -0
  197. package/src/utils.ts +0 -4
  198. package/dist/tsup/chunk-227FEWMB.js.map +0 -1
  199. package/dist/tsup/chunk-2JYPS5YM.cjs.map +0 -1
  200. package/dist/tsup/chunk-36JJ4IQB.cjs.map +0 -1
  201. package/dist/tsup/chunk-7L65NNWP.cjs.map +0 -1
  202. package/dist/tsup/chunk-BLK27ES3.js.map +0 -1
  203. package/dist/tsup/chunk-BOMZS2TJ.js.map +0 -1
  204. package/dist/tsup/chunk-BYMKMOBS.js.map +0 -1
  205. package/dist/tsup/chunk-FX7TWFQR.js.map +0 -1
  206. package/dist/tsup/chunk-G64QUEDJ.js.map +0 -1
  207. package/dist/tsup/chunk-HHFKKVLR.cjs.map +0 -1
  208. package/dist/tsup/chunk-INNFK746.cjs.map +0 -1
  209. package/dist/tsup/chunk-KSRXX3Z4.cjs.map +0 -1
  210. package/dist/tsup/chunk-O44LFKSB.cjs +0 -4623
  211. package/dist/tsup/chunk-O44LFKSB.cjs.map +0 -1
  212. package/dist/tsup/chunk-PLUN2NQT.js.map +0 -1
  213. package/dist/tsup/chunk-S4UJG7ZE.js +0 -1119
  214. package/dist/tsup/chunk-S4UJG7ZE.js.map +0 -1
  215. package/dist/tsup/chunk-SHVX2QUR.cjs.map +0 -1
  216. package/dist/tsup/chunk-VFB23BYZ.cjs +0 -1119
  217. package/dist/tsup/chunk-VFB23BYZ.cjs.map +0 -1
  218. package/dist/tsup/chunk-VHGY7PU5.cjs.map +0 -1
  219. package/dist/tsup/chunk-YBG6R7LX.js.map +0 -1
  220. package/dist/tsup/chunk-YBHYXIP6.js.map +0 -1
  221. package/src/actor/action.ts +0 -178
  222. package/src/actor/conn-drivers.ts +0 -216
  223. package/src/actor/conn-socket.ts +0 -8
  224. package/src/actor/conn.ts +0 -272
  225. package/src/actor/instance.ts +0 -2336
  226. package/src/actor/persisted.ts +0 -49
  227. package/src/actor/unstable-react.ts +0 -110
  228. package/src/driver-test-suite/tests/actor-reconnect.ts +0 -170
  229. package/src/drivers/engine/kv.ts +0 -3
  230. package/src/manager/hono-websocket-adapter.ts +0 -393
  231. /package/dist/tsup/{chunk-CD33GT6Z.js.map → chunk-QIHBDXTO.js.map} +0 -0
@@ -1,4623 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class; var _class2; var _class3; var _class4;
2
-
3
-
4
-
5
-
6
- var _chunkINNFK746cjs = require('./chunk-INNFK746.cjs');
7
-
8
-
9
-
10
- var _chunkZTH3KYFHcjs = require('./chunk-ZTH3KYFH.cjs');
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
- var _chunkVFB23BYZcjs = require('./chunk-VFB23BYZ.cjs');
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
- var _chunkHHFKKVLRcjs = require('./chunk-HHFKKVLR.cjs');
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
- var _chunk7L65NNWPcjs = require('./chunk-7L65NNWP.cjs');
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
- var _chunkKSRXX3Z4cjs = require('./chunk-KSRXX3Z4.cjs');
85
-
86
- // src/actor/conn.ts
87
- var _cborx = require('cbor-x'); var cbor2 = _interopRequireWildcard(_cborx); var cbor = _interopRequireWildcard(_cborx); var cbor5 = _interopRequireWildcard(_cborx); var cbor4 = _interopRequireWildcard(_cborx); var cbor3 = _interopRequireWildcard(_cborx); var cbor6 = _interopRequireWildcard(_cborx);
88
-
89
- // src/actor/conn-drivers.ts
90
- var WEBSOCKET_DRIVER = {
91
- sendMessage: (actor, conn, state, message) => {
92
- if (state.websocket.readyState !== 1 /* OPEN */) {
93
- actor.rLog.warn({
94
- msg: "attempting to send message to closed websocket, this is likely a bug in RivetKit",
95
- connId: conn.id,
96
- wsReadyState: state.websocket.readyState
97
- });
98
- return;
99
- }
100
- const serialized = message.serialize(state.encoding);
101
- actor.rLog.debug({
102
- msg: "sending websocket message",
103
- encoding: state.encoding,
104
- dataType: typeof serialized,
105
- isUint8Array: serialized instanceof Uint8Array,
106
- isArrayBuffer: serialized instanceof ArrayBuffer,
107
- dataLength: serialized.byteLength || serialized.length
108
- });
109
- if (serialized instanceof Uint8Array) {
110
- const buffer = serialized.buffer.slice(
111
- serialized.byteOffset,
112
- serialized.byteOffset + serialized.byteLength
113
- );
114
- if (buffer instanceof SharedArrayBuffer) {
115
- const arrayBuffer = new ArrayBuffer(buffer.byteLength);
116
- new Uint8Array(arrayBuffer).set(new Uint8Array(buffer));
117
- actor.rLog.debug({
118
- msg: "converted SharedArrayBuffer to ArrayBuffer",
119
- byteLength: arrayBuffer.byteLength
120
- });
121
- state.websocket.send(arrayBuffer);
122
- } else {
123
- actor.rLog.debug({
124
- msg: "sending ArrayBuffer",
125
- byteLength: buffer.byteLength
126
- });
127
- state.websocket.send(buffer);
128
- }
129
- } else {
130
- actor.rLog.debug({
131
- msg: "sending string data",
132
- length: serialized.length
133
- });
134
- state.websocket.send(serialized);
135
- }
136
- },
137
- disconnect: async (_actor, _conn, state, reason) => {
138
- state.websocket.close(1e3, reason);
139
- await state.closePromise.promise;
140
- },
141
- getConnectionReadyState: (_actor, _conn, state) => {
142
- return state.websocket.readyState;
143
- }
144
- };
145
- var SSE_DRIVER = {
146
- sendMessage: (_actor, _conn, state, message) => {
147
- state.stream.writeSSE({
148
- data: _chunkHHFKKVLRcjs.encodeDataToString.call(void 0, message.serialize(state.encoding))
149
- });
150
- },
151
- disconnect: async (_actor, _conn, state, _reason) => {
152
- state.stream.close();
153
- },
154
- getConnectionReadyState: (_actor, _conn, state) => {
155
- if (state.stream.aborted || state.stream.closed) {
156
- return 3 /* CLOSED */;
157
- }
158
- return 1 /* OPEN */;
159
- }
160
- };
161
- var HTTP_DRIVER = {
162
- getConnectionReadyState(_actor, _conn) {
163
- return 1 /* OPEN */;
164
- },
165
- disconnect: async () => {
166
- }
167
- };
168
- var CONN_DRIVERS = {
169
- [0 /* WEBSOCKET */]: WEBSOCKET_DRIVER,
170
- [1 /* SSE */]: SSE_DRIVER,
171
- [2 /* HTTP */]: HTTP_DRIVER
172
- };
173
- function getConnDriverKindFromState(state) {
174
- if (0 /* WEBSOCKET */ in state) return 0 /* WEBSOCKET */;
175
- else if (1 /* SSE */ in state) return 1 /* SSE */;
176
- else if (2 /* HTTP */ in state) return 2 /* HTTP */;
177
- else _chunk7L65NNWPcjs.assertUnreachable.call(void 0, state);
178
- }
179
-
180
- // src/actor/instance.ts
181
-
182
- var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant);
183
- var _onchange = require('on-change'); var _onchange2 = _interopRequireDefault(_onchange);
184
-
185
- // src/inspector/actor.ts
186
- var _standardvalidator = require('@hono/standard-validator');
187
- var _fastjsonpatch = require('@rivetkit/fast-json-patch'); var _fastjsonpatch2 = _interopRequireDefault(_fastjsonpatch);
188
- var _hono = require('hono');
189
- var _streaming = require('hono/streaming');
190
- var _nanoevents = require('nanoevents');
191
- var _v4 = require('zod/v4'); var _v42 = _interopRequireDefault(_v4);
192
- function createActorInspectorRouter() {
193
- return new (0, _hono.Hono)().get("/ping", (c) => {
194
- return c.json({ message: "pong" }, 200);
195
- }).get("/state", async (c) => {
196
- if (await c.var.inspector.accessors.isStateEnabled()) {
197
- return c.json(
198
- {
199
- enabled: true,
200
- state: await c.var.inspector.accessors.getState()
201
- },
202
- 200
203
- );
204
- }
205
- return c.json({ enabled: false, state: null }, 200);
206
- }).patch(
207
- "/state",
208
- _standardvalidator.sValidator.call(void 0,
209
- "json",
210
- _v42.default.object({ patch: _chunkINNFK746cjs.PatchSchema }).or(_v42.default.object({ replace: _v42.default.any() }))
211
- ),
212
- async (c) => {
213
- if (!await c.var.inspector.accessors.isStateEnabled()) {
214
- return c.json({ enabled: false }, 200);
215
- }
216
- const body = c.req.valid("json");
217
- if ("replace" in body) {
218
- await c.var.inspector.accessors.setState(body.replace);
219
- return c.json(
220
- {
221
- enabled: true,
222
- state: await c.var.inspector.accessors.getState()
223
- },
224
- 200
225
- );
226
- }
227
- const state = await c.var.inspector.accessors.getState();
228
- const { newDocument: newState } = _fastjsonpatch2.default.applyPatch(
229
- state,
230
- body.patch
231
- );
232
- await c.var.inspector.accessors.setState(newState);
233
- return c.json(
234
- {
235
- enabled: true,
236
- state: await c.var.inspector.accessors.getState()
237
- },
238
- 200
239
- );
240
- }
241
- ).get("/state/stream", async (c) => {
242
- if (!await c.var.inspector.accessors.isStateEnabled()) {
243
- return c.json({ enabled: false }, 200);
244
- }
245
- let id = 0;
246
- let unsub;
247
- return _streaming.streamSSE.call(void 0,
248
- c,
249
- async (stream) => {
250
- unsub = c.var.inspector.emitter.on(
251
- "stateUpdated",
252
- async (state) => {
253
- stream.writeSSE({
254
- data: JSON.stringify(state) || "",
255
- event: "state-update",
256
- id: String(id++)
257
- });
258
- }
259
- );
260
- const { promise } = _chunk7L65NNWPcjs.promiseWithResolvers.call(void 0, );
261
- return promise;
262
- },
263
- async () => {
264
- unsub == null ? void 0 : unsub();
265
- }
266
- );
267
- }).get("/connections", async (c) => {
268
- const connections = await c.var.inspector.accessors.getConnections();
269
- return c.json({ connections }, 200);
270
- }).get("/connections/stream", async (c) => {
271
- let id = 0;
272
- let unsub;
273
- return _streaming.streamSSE.call(void 0,
274
- c,
275
- async (stream) => {
276
- unsub = c.var.inspector.emitter.on(
277
- "connectionUpdated",
278
- async () => {
279
- stream.writeSSE({
280
- data: JSON.stringify(
281
- await c.var.inspector.accessors.getConnections()
282
- ),
283
- event: "connection-update",
284
- id: String(id++)
285
- });
286
- }
287
- );
288
- const { promise } = _chunk7L65NNWPcjs.promiseWithResolvers.call(void 0, );
289
- return promise;
290
- },
291
- async () => {
292
- unsub == null ? void 0 : unsub();
293
- }
294
- );
295
- }).get("/events", async (c) => {
296
- const events = c.var.inspector.lastRealtimeEvents;
297
- return c.json({ events }, 200);
298
- }).post("/events/clear", async (c) => {
299
- c.var.inspector.lastRealtimeEvents.length = 0;
300
- return c.json({ message: "Events cleared" }, 200);
301
- }).get("/events/stream", async (c) => {
302
- let id = 0;
303
- let unsub;
304
- return _streaming.streamSSE.call(void 0,
305
- c,
306
- async (stream) => {
307
- unsub = c.var.inspector.emitter.on("eventFired", () => {
308
- stream.writeSSE({
309
- data: JSON.stringify(
310
- c.var.inspector.lastRealtimeEvents
311
- ),
312
- event: "realtime-event",
313
- id: String(id++)
314
- });
315
- });
316
- const { promise } = _chunk7L65NNWPcjs.promiseWithResolvers.call(void 0, );
317
- return promise;
318
- },
319
- async () => {
320
- unsub == null ? void 0 : unsub();
321
- }
322
- );
323
- }).get("/rpcs", async (c) => {
324
- const rpcs = await c.var.inspector.accessors.getRpcs();
325
- return c.json({ rpcs }, 200);
326
- }).get("/db", async (c) => {
327
- if (!await c.var.inspector.accessors.isDbEnabled()) {
328
- return c.json({ enabled: false, db: null }, 200);
329
- }
330
- const db = await c.var.inspector.accessors.getDb();
331
- const rows = await db.execute(`PRAGMA table_list`);
332
- const tables = _chunkINNFK746cjs.TablesSchema.parse(rows).filter(
333
- (table) => table.schema !== "temp" && !table.name.startsWith("sqlite_")
334
- );
335
- const tablesInfo = await Promise.all(
336
- tables.map(
337
- (table) => db.execute(`PRAGMA table_info(${table.name})`)
338
- )
339
- );
340
- const columns = tablesInfo.map((def) => _chunkINNFK746cjs.ColumnsSchema.parse(def));
341
- const foreignKeysList = await Promise.all(
342
- tables.map(
343
- (table) => db.execute(`PRAGMA foreign_key_list(${table.name})`)
344
- )
345
- );
346
- const foreignKeys = foreignKeysList.map(
347
- (def) => _chunkINNFK746cjs.ForeignKeysSchema.parse(def)
348
- );
349
- const countInfo = await Promise.all(
350
- tables.map(
351
- (table) => db.execute(`SELECT COUNT(*) as count FROM ${table.name}`)
352
- )
353
- );
354
- const counts = countInfo.map((def) => {
355
- return def[0].count || 0;
356
- });
357
- return c.json(
358
- {
359
- enabled: true,
360
- db: tablesInfo.map((_, index) => {
361
- return {
362
- table: tables[index],
363
- columns: columns[index],
364
- foreignKeys: foreignKeys[index],
365
- records: counts[index]
366
- };
367
- })
368
- },
369
- 200
370
- );
371
- }).post(
372
- "/db",
373
- _standardvalidator.sValidator.call(void 0,
374
- "json",
375
- _v42.default.object({
376
- query: _v42.default.string(),
377
- params: _v42.default.array(_v42.default.any()).optional()
378
- })
379
- ),
380
- async (c) => {
381
- if (!await c.var.inspector.accessors.isDbEnabled()) {
382
- return c.json({ enabled: false }, 200);
383
- }
384
- const db = await c.var.inspector.accessors.getDb();
385
- try {
386
- const result = await db.execute(
387
- c.req.valid("json").query,
388
- ...c.req.valid("json").params || []
389
- );
390
- return c.json({ result }, 200);
391
- } catch (error) {
392
- c;
393
- return c.json({ error: error.message }, 500);
394
- }
395
- }
396
- ).post(
397
- "/action",
398
- _standardvalidator.sValidator.call(void 0,
399
- "json",
400
- _v42.default.object({
401
- name: _v42.default.string(),
402
- params: _v42.default.array(_v42.default.any()).optional()
403
- })
404
- ),
405
- async (c) => {
406
- const { name, params } = c.req.valid("json");
407
- const result = await c.var.inspector.accessors.executeAction(
408
- name,
409
- params
410
- );
411
- return c.json({ result }, 200);
412
- }
413
- );
414
- }
415
- var ActorInspector = (_class = class {
416
-
417
- __init() {this.emitter = _nanoevents.createNanoEvents.call(void 0, )}
418
- #lastRealtimeEvents = [];
419
- get lastRealtimeEvents() {
420
- return this.#lastRealtimeEvents;
421
- }
422
- constructor(accessors) {;_class.prototype.__init.call(this);
423
- this.accessors = accessors();
424
- this.emitter.on("eventFired", (event) => {
425
- this.#lastRealtimeEvents.push({
426
- id: crypto.randomUUID(),
427
- timestamp: Date.now(),
428
- ...event
429
- });
430
- if (this.#lastRealtimeEvents.length > 100) {
431
- this.#lastRealtimeEvents = this.#lastRealtimeEvents.slice(-100);
432
- }
433
- });
434
- }
435
- }, _class);
436
-
437
- // src/actor/context.ts
438
- var ActorContext = class {
439
- #actor;
440
- constructor(actor) {
441
- this.#actor = actor;
442
- }
443
- /**
444
- * Get the actor state
445
- */
446
- get state() {
447
- return this.#actor.state;
448
- }
449
- /**
450
- * Get the actor variables
451
- */
452
- get vars() {
453
- return this.#actor.vars;
454
- }
455
- /**
456
- * Broadcasts an event to all connected clients.
457
- * @param name - The name of the event.
458
- * @param args - The arguments to send with the event.
459
- */
460
- broadcast(name, ...args) {
461
- this.#actor._broadcast(name, ...args);
462
- return;
463
- }
464
- /**
465
- * Gets the logger instance.
466
- */
467
- get log() {
468
- return this.#actor.log;
469
- }
470
- /**
471
- * Gets actor ID.
472
- */
473
- get actorId() {
474
- return this.#actor.id;
475
- }
476
- /**
477
- * Gets the actor name.
478
- */
479
- get name() {
480
- return this.#actor.name;
481
- }
482
- /**
483
- * Gets the actor key.
484
- */
485
- get key() {
486
- return this.#actor.key;
487
- }
488
- /**
489
- * Gets the region.
490
- */
491
- get region() {
492
- return this.#actor.region;
493
- }
494
- /**
495
- * Gets the scheduler.
496
- */
497
- get schedule() {
498
- return this.#actor.schedule;
499
- }
500
- /**
501
- * Gets the map of connections.
502
- */
503
- get conns() {
504
- return this.#actor.conns;
505
- }
506
- /**
507
- * Returns the client for the given registry.
508
- */
509
- client() {
510
- return this.#actor.inlineClient;
511
- }
512
- /**
513
- * Gets the database.
514
- * @experimental
515
- * @throws {DatabaseNotEnabled} If the database is not enabled.
516
- */
517
- get db() {
518
- return this.#actor.db;
519
- }
520
- /**
521
- * Forces the state to get saved.
522
- *
523
- * @param opts - Options for saving the state.
524
- */
525
- async saveState(opts) {
526
- return this.#actor.saveState(opts);
527
- }
528
- /**
529
- * Prevents the actor from sleeping until promise is complete.
530
- */
531
- waitUntil(promise) {
532
- this.#actor._waitUntil(promise);
533
- }
534
- /**
535
- * AbortSignal that fires when the actor is stopping.
536
- */
537
- get abortSignal() {
538
- return this.#actor.abortSignal;
539
- }
540
- /**
541
- * Forces the actor to sleep.
542
- *
543
- * Not supported on all drivers.
544
- *
545
- * @experimental
546
- */
547
- sleep() {
548
- this.#actor._startSleep();
549
- }
550
- };
551
-
552
- // src/actor/keys.ts
553
- var EMPTY_KEY = "/";
554
- var KEY_SEPARATOR = "/";
555
- function serializeActorKey(key) {
556
- if (key.length === 0) {
557
- return EMPTY_KEY;
558
- }
559
- const escapedParts = key.map((part) => {
560
- if (part === "") {
561
- return "\\0";
562
- }
563
- let escaped = part.replace(/\\/g, "\\\\");
564
- escaped = escaped.replace(/\//g, `\\${KEY_SEPARATOR}`);
565
- return escaped;
566
- });
567
- return escapedParts.join(KEY_SEPARATOR);
568
- }
569
- function deserializeActorKey(keyString) {
570
- if (keyString === void 0 || keyString === null || keyString === EMPTY_KEY) {
571
- return [];
572
- }
573
- const parts = [];
574
- let currentPart = "";
575
- let escaping = false;
576
- let isEmptyStringMarker = false;
577
- for (let i = 0; i < keyString.length; i++) {
578
- const char = keyString[i];
579
- if (escaping) {
580
- if (char === "0") {
581
- isEmptyStringMarker = true;
582
- } else {
583
- currentPart += char;
584
- }
585
- escaping = false;
586
- } else if (char === "\\") {
587
- escaping = true;
588
- } else if (char === KEY_SEPARATOR) {
589
- if (isEmptyStringMarker) {
590
- parts.push("");
591
- isEmptyStringMarker = false;
592
- } else {
593
- parts.push(currentPart);
594
- }
595
- currentPart = "";
596
- } else {
597
- currentPart += char;
598
- }
599
- }
600
- if (escaping) {
601
- parts.push(currentPart + "\\");
602
- } else if (isEmptyStringMarker) {
603
- parts.push("");
604
- } else if (currentPart !== "" || parts.length > 0) {
605
- parts.push(currentPart);
606
- }
607
- return parts;
608
- }
609
-
610
- // src/actor/schedule.ts
611
- var Schedule = class {
612
- #actor;
613
- constructor(actor) {
614
- this.#actor = actor;
615
- }
616
- async after(duration, fn, ...args) {
617
- await this.#actor.scheduleEvent(Date.now() + duration, fn, args);
618
- }
619
- async at(timestamp, fn, ...args) {
620
- await this.#actor.scheduleEvent(timestamp, fn, args);
621
- }
622
- };
623
-
624
- // src/actor/instance.ts
625
- var PERSIST_SYMBOL = Symbol("persist");
626
- var CanSleep = /* @__PURE__ */ ((CanSleep2) => {
627
- CanSleep2[CanSleep2["Yes"] = 0] = "Yes";
628
- CanSleep2[CanSleep2["NotReady"] = 1] = "NotReady";
629
- CanSleep2[CanSleep2["ActiveConns"] = 2] = "ActiveConns";
630
- CanSleep2[CanSleep2["ActiveHonoHttpRequests"] = 3] = "ActiveHonoHttpRequests";
631
- CanSleep2[CanSleep2["ActiveRawWebSockets"] = 4] = "ActiveRawWebSockets";
632
- return CanSleep2;
633
- })(CanSleep || {});
634
- var ActorInstance = class {
635
- // Shared actor context for this instance
636
-
637
- /** Actor log, intended for the user to call */
638
- #log;
639
- /** Runtime log, intended for internal actor logs */
640
- #rLog;
641
- #sleepCalled = false;
642
- #stopCalled = false;
643
- get isStopping() {
644
- return this.#stopCalled;
645
- }
646
- #persistChanged = false;
647
- #isInOnStateChange = false;
648
- /**
649
- * The proxied state that notifies of changes automatically.
650
- *
651
- * Any data that should be stored indefinitely should be held within this object.
652
- */
653
- #persist;
654
- get [PERSIST_SYMBOL]() {
655
- return this.#persist;
656
- }
657
- /** Raw state without the proxy wrapper */
658
- #persistRaw;
659
- #persistWriteQueue = new (0, _chunk7L65NNWPcjs.SinglePromiseQueue)();
660
- #alarmWriteQueue = new (0, _chunk7L65NNWPcjs.SinglePromiseQueue)();
661
- #lastSaveTime = 0;
662
- #pendingSaveTimeout;
663
- #vars;
664
- #backgroundPromises = [];
665
- #abortController = new AbortController();
666
- #config;
667
- #actorDriver;
668
- #inlineClient;
669
- #actorId;
670
- #name;
671
- #key;
672
- #region;
673
- #ready = false;
674
- #connections = /* @__PURE__ */ new Map();
675
- #subscriptionIndex = /* @__PURE__ */ new Map();
676
- #checkConnLivenessInterval;
677
- #sleepTimeout;
678
- /**
679
- * Track active HTTP requests through Hono router so sleep logic can
680
- * account for them. Does not include WebSockets.
681
- **/
682
- #activeHonoHttpRequests = 0;
683
- #activeRawWebSockets = /* @__PURE__ */ new Set();
684
- #schedule;
685
- #db;
686
- #inspector = new ActorInspector(() => {
687
- return {
688
- isDbEnabled: async () => {
689
- return this.#db !== void 0;
690
- },
691
- getDb: async () => {
692
- return this.db;
693
- },
694
- isStateEnabled: async () => {
695
- return this.stateEnabled;
696
- },
697
- getState: async () => {
698
- this.#validateStateEnabled();
699
- return this.#persistRaw.state;
700
- },
701
- getRpcs: async () => {
702
- return Object.keys(this.#config.actions);
703
- },
704
- getConnections: async () => {
705
- return Array.from(this.#connections.entries()).map(
706
- ([id, conn]) => ({
707
- id,
708
- params: conn.params,
709
- state: conn.__stateEnabled ? conn.state : void 0,
710
- status: conn.status,
711
- subscriptions: conn.subscriptions.size,
712
- lastSeen: conn.lastSeen,
713
- stateEnabled: conn.__stateEnabled,
714
- isHibernatable: conn.isHibernatable,
715
- hibernatableRequestId: conn.__persist.hibernatableRequestId ? _chunk7L65NNWPcjs.idToStr.call(void 0, conn.__persist.hibernatableRequestId) : void 0,
716
- driver: conn.__driverState ? getConnDriverKindFromState(conn.__driverState) : void 0
717
- })
718
- );
719
- },
720
- setState: async (state) => {
721
- this.#validateStateEnabled();
722
- this.#persist.state = { ...state };
723
- await this.saveState({ immediate: true });
724
- },
725
- executeAction: async (name, params) => {
726
- const requestId = generateConnRequestId();
727
- const conn = await this.createConn(
728
- {
729
- requestId,
730
- hibernatable: false,
731
- driverState: { [2 /* HTTP */]: {} }
732
- },
733
- void 0,
734
- void 0
735
- );
736
- try {
737
- return await this.executeAction(
738
- new (0, _chunkVFB23BYZcjs.ActionContext)(this.actorContext, conn),
739
- name,
740
- params || []
741
- );
742
- } finally {
743
- this.__connDisconnected(conn, true, requestId);
744
- }
745
- }
746
- };
747
- });
748
- get id() {
749
- return this.#actorId;
750
- }
751
- get inlineClient() {
752
- return this.#inlineClient;
753
- }
754
- get inspector() {
755
- return this.#inspector;
756
- }
757
- get #sleepingSupported() {
758
- return this.#actorDriver.startSleep !== void 0;
759
- }
760
- /**
761
- * This constructor should never be used directly.
762
- *
763
- * Constructed in {@link ActorInstance.start}.
764
- *
765
- * @private
766
- */
767
- constructor(config) {
768
- this.#config = config;
769
- this.actorContext = new ActorContext(this);
770
- }
771
- async start(actorDriver, inlineClient, actorId, name, key, region) {
772
- var _a, _b, _c;
773
- const logParams = {
774
- actor: name,
775
- key: serializeActorKey(key),
776
- actorId
777
- };
778
- const extraLogParams = (_a = actorDriver.getExtraActorLogParams) == null ? void 0 : _a.call(actorDriver);
779
- if (extraLogParams) Object.assign(logParams, extraLogParams);
780
- this.#log = _chunk7L65NNWPcjs.getBaseLogger.call(void 0, ).child(
781
- Object.assign(
782
- _chunk7L65NNWPcjs.getIncludeTarget.call(void 0, ) ? { target: "actor" } : {},
783
- logParams
784
- )
785
- );
786
- this.#rLog = _chunk7L65NNWPcjs.getBaseLogger.call(void 0, ).child(
787
- Object.assign(
788
- _chunk7L65NNWPcjs.getIncludeTarget.call(void 0, ) ? { target: "actor-runtime" } : {},
789
- logParams
790
- )
791
- );
792
- this.#actorDriver = actorDriver;
793
- this.#inlineClient = inlineClient;
794
- this.#actorId = actorId;
795
- this.#name = name;
796
- this.#key = key;
797
- this.#region = region;
798
- this.#schedule = new Schedule(this);
799
- await this.#initialize();
800
- if (this.#varsEnabled) {
801
- let vars;
802
- if ("createVars" in this.#config) {
803
- const dataOrPromise = this.#config.createVars(
804
- this.actorContext,
805
- this.#actorDriver.getContext(this.#actorId)
806
- );
807
- if (dataOrPromise instanceof Promise) {
808
- vars = await _chunkHHFKKVLRcjs.deadline.call(void 0,
809
- dataOrPromise,
810
- this.#config.options.createVarsTimeout
811
- );
812
- } else {
813
- vars = dataOrPromise;
814
- }
815
- } else if ("vars" in this.#config) {
816
- vars = structuredClone(this.#config.vars);
817
- } else {
818
- throw new Error(
819
- "Could not variables from 'createVars' or 'vars'"
820
- );
821
- }
822
- this.#vars = vars;
823
- }
824
- this.#rLog.info({ msg: "actor starting" });
825
- if (this.#config.onStart) {
826
- const result = this.#config.onStart(this.actorContext);
827
- if (result instanceof Promise) {
828
- await result;
829
- }
830
- }
831
- if ("db" in this.#config && this.#config.db) {
832
- const client = await this.#config.db.createClient({
833
- getDatabase: () => actorDriver.getDatabase(this.#actorId)
834
- });
835
- this.#rLog.info({ msg: "database migration starting" });
836
- await ((_c = (_b = this.#config.db).onMigrate) == null ? void 0 : _c.call(_b, client));
837
- this.#rLog.info({ msg: "database migration complete" });
838
- this.#db = client;
839
- }
840
- if (this.#persist.scheduledEvents.length > 0) {
841
- await this.#queueSetAlarm(
842
- this.#persist.scheduledEvents[0].timestamp
843
- );
844
- }
845
- this.#rLog.info({ msg: "actor ready" });
846
- this.#ready = true;
847
- this.#resetSleepTimer();
848
- this.#checkConnLivenessInterval = setInterval(
849
- this.#checkConnectionsLiveness.bind(this),
850
- this.#config.options.connectionLivenessInterval
851
- );
852
- this.#checkConnectionsLiveness();
853
- await this._onAlarm();
854
- }
855
- async #scheduleEventInner(newEvent) {
856
- this.actorContext.log.info({ msg: "scheduling event", ...newEvent });
857
- const insertIndex = this.#persist.scheduledEvents.findIndex(
858
- (x) => x.timestamp > newEvent.timestamp
859
- );
860
- if (insertIndex === -1) {
861
- this.#persist.scheduledEvents.push(newEvent);
862
- } else {
863
- this.#persist.scheduledEvents.splice(insertIndex, 0, newEvent);
864
- }
865
- if (insertIndex === 0 || this.#persist.scheduledEvents.length === 1) {
866
- this.actorContext.log.info({
867
- msg: "setting alarm",
868
- timestamp: newEvent.timestamp,
869
- eventCount: this.#persist.scheduledEvents.length
870
- });
871
- await this.#queueSetAlarm(newEvent.timestamp);
872
- }
873
- }
874
- /**
875
- * Triggers any pending alarms.
876
- *
877
- * This method is idempotent. It's called automatically when the actor wakes
878
- * in order to trigger any pending alarms.
879
- */
880
- async _onAlarm() {
881
- const now = Date.now();
882
- this.actorContext.log.debug({
883
- msg: "alarm triggered",
884
- now,
885
- events: this.#persist.scheduledEvents.length
886
- });
887
- this.#resetSleepTimer();
888
- const runIndex = this.#persist.scheduledEvents.findIndex(
889
- (x) => x.timestamp <= now
890
- );
891
- if (runIndex === -1) {
892
- this.#rLog.debug({ msg: "no events are due yet" });
893
- if (this.#persist.scheduledEvents.length > 0) {
894
- const nextTs = this.#persist.scheduledEvents[0].timestamp;
895
- this.actorContext.log.debug({
896
- msg: "alarm fired early, rescheduling for next event",
897
- now,
898
- nextTs,
899
- delta: nextTs - now
900
- });
901
- await this.#queueSetAlarm(nextTs);
902
- }
903
- this.actorContext.log.debug({ msg: "no events to run", now });
904
- return;
905
- }
906
- const scheduleEvents = this.#persist.scheduledEvents.splice(
907
- 0,
908
- runIndex + 1
909
- );
910
- this.actorContext.log.debug({
911
- msg: "running events",
912
- count: scheduleEvents.length
913
- });
914
- if (this.#persist.scheduledEvents.length > 0) {
915
- const nextTs = this.#persist.scheduledEvents[0].timestamp;
916
- this.actorContext.log.info({
917
- msg: "setting next alarm",
918
- nextTs,
919
- remainingEvents: this.#persist.scheduledEvents.length
920
- });
921
- await this.#queueSetAlarm(nextTs);
922
- }
923
- for (const event of scheduleEvents) {
924
- try {
925
- this.actorContext.log.info({
926
- msg: "running action for event",
927
- event: event.eventId,
928
- timestamp: event.timestamp,
929
- action: event.kind.generic.actionName
930
- });
931
- const fn = this.#config.actions[event.kind.generic.actionName];
932
- if (!fn)
933
- throw new Error(
934
- `Missing action for alarm ${event.kind.generic.actionName}`
935
- );
936
- if (typeof fn !== "function")
937
- throw new Error(
938
- `Alarm function lookup for ${event.kind.generic.actionName} returned ${typeof fn}`
939
- );
940
- try {
941
- const args = event.kind.generic.args ? cbor.decode(new Uint8Array(event.kind.generic.args)) : [];
942
- await fn.call(void 0, this.actorContext, ...args);
943
- } catch (error) {
944
- this.actorContext.log.error({
945
- msg: "error while running event",
946
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error),
947
- event: event.eventId,
948
- timestamp: event.timestamp,
949
- action: event.kind.generic.actionName
950
- });
951
- }
952
- } catch (error) {
953
- this.actorContext.log.error({
954
- msg: "internal error while running event",
955
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error),
956
- ...event
957
- });
958
- }
959
- }
960
- }
961
- async scheduleEvent(timestamp, action, args) {
962
- return this.#scheduleEventInner({
963
- eventId: crypto.randomUUID(),
964
- timestamp,
965
- kind: {
966
- generic: {
967
- actionName: action,
968
- args: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor.encode(args))
969
- }
970
- }
971
- });
972
- }
973
- get stateEnabled() {
974
- return "createState" in this.#config || "state" in this.#config;
975
- }
976
- #validateStateEnabled() {
977
- if (!this.stateEnabled) {
978
- throw new (0, _chunkKSRXX3Z4cjs.StateNotEnabled)();
979
- }
980
- }
981
- get connStateEnabled() {
982
- return "createConnState" in this.#config || "connState" in this.#config;
983
- }
984
- get #varsEnabled() {
985
- return "createVars" in this.#config || "vars" in this.#config;
986
- }
987
- #validateVarsEnabled() {
988
- if (!this.#varsEnabled) {
989
- throw new (0, _chunkKSRXX3Z4cjs.VarsNotEnabled)();
990
- }
991
- }
992
- /** Promise used to wait for a save to complete. This is required since you cannot await `#saveStateThrottled`. */
993
- #onPersistSavedPromise;
994
- /** Throttled save state method. Used to write to KV at a reasonable cadence. */
995
- #savePersistThrottled() {
996
- const now = Date.now();
997
- const timeSinceLastSave = now - this.#lastSaveTime;
998
- const saveInterval = this.#config.options.stateSaveInterval;
999
- if (timeSinceLastSave < saveInterval) {
1000
- if (this.#pendingSaveTimeout === void 0) {
1001
- this.#pendingSaveTimeout = setTimeout(() => {
1002
- this.#pendingSaveTimeout = void 0;
1003
- this.#savePersistInner();
1004
- }, saveInterval - timeSinceLastSave);
1005
- }
1006
- } else {
1007
- this.#savePersistInner();
1008
- }
1009
- }
1010
- /** Saves the state to KV. You probably want to use #saveStateThrottled instead except for a few edge cases. */
1011
- async #savePersistInner() {
1012
- var _a, _b;
1013
- try {
1014
- this.#lastSaveTime = Date.now();
1015
- if (this.#persistChanged) {
1016
- const finished = this.#persistWriteQueue.enqueue(async () => {
1017
- this.#rLog.debug({ msg: "saving persist" });
1018
- this.#persistChanged = false;
1019
- const bareData = this.#convertToBarePersisted(
1020
- this.#persistRaw
1021
- );
1022
- await this.#actorDriver.writePersistedData(
1023
- this.#actorId,
1024
- _chunkVFB23BYZcjs.PERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(
1025
- bareData
1026
- )
1027
- );
1028
- this.#rLog.debug({ msg: "persist saved" });
1029
- });
1030
- await finished;
1031
- }
1032
- (_a = this.#onPersistSavedPromise) == null ? void 0 : _a.resolve();
1033
- } catch (error) {
1034
- this.#rLog.error({
1035
- msg: "error saving persist",
1036
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1037
- });
1038
- (_b = this.#onPersistSavedPromise) == null ? void 0 : _b.reject(error);
1039
- throw error;
1040
- }
1041
- }
1042
- async #queueSetAlarm(timestamp) {
1043
- await this.#alarmWriteQueue.enqueue(async () => {
1044
- await this.#actorDriver.setAlarm(this, timestamp);
1045
- });
1046
- }
1047
- /**
1048
- * Creates proxy for `#persist` that handles automatically flagging when state needs to be updated.
1049
- */
1050
- #setPersist(target) {
1051
- this.#persistRaw = target;
1052
- if (target === null || typeof target !== "object") {
1053
- let invalidPath = "";
1054
- if (!_chunk7L65NNWPcjs.isCborSerializable.call(void 0,
1055
- target,
1056
- (path) => {
1057
- invalidPath = path;
1058
- },
1059
- ""
1060
- )) {
1061
- throw new (0, _chunkKSRXX3Z4cjs.InvalidStateType)({ path: invalidPath });
1062
- }
1063
- return target;
1064
- }
1065
- if (this.#persist) {
1066
- _onchange2.default.unsubscribe(this.#persist);
1067
- }
1068
- this.#persist = _onchange2.default.call(void 0,
1069
- target,
1070
- // biome-ignore lint/suspicious/noExplicitAny: Don't know types in proxy
1071
- (path, value, _previousValue, _applyData) => {
1072
- const actorStatePath = _chunkHHFKKVLRcjs.isStatePath.call(void 0, path);
1073
- const connStatePath = _chunkHHFKKVLRcjs.isConnStatePath.call(void 0, path);
1074
- if (actorStatePath || connStatePath) {
1075
- let invalidPath = "";
1076
- if (!_chunk7L65NNWPcjs.isCborSerializable.call(void 0,
1077
- value,
1078
- (invalidPathPart) => {
1079
- invalidPath = invalidPathPart;
1080
- },
1081
- ""
1082
- )) {
1083
- throw new (0, _chunkKSRXX3Z4cjs.InvalidStateType)({
1084
- path: path + (invalidPath ? `.${invalidPath}` : "")
1085
- });
1086
- }
1087
- }
1088
- this.#rLog.debug({
1089
- msg: "onChange triggered, setting persistChanged=true",
1090
- path
1091
- });
1092
- this.#persistChanged = true;
1093
- if (actorStatePath) {
1094
- this.inspector.emitter.emit(
1095
- "stateUpdated",
1096
- this.#persist.state
1097
- );
1098
- }
1099
- if (actorStatePath && this.#config.onStateChange && this.#ready && !this.#isInOnStateChange) {
1100
- try {
1101
- this.#isInOnStateChange = true;
1102
- this.#config.onStateChange(
1103
- this.actorContext,
1104
- this.#persistRaw.state
1105
- );
1106
- } catch (error) {
1107
- this.#rLog.error({
1108
- msg: "error in `_onStateChange`",
1109
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1110
- });
1111
- } finally {
1112
- this.#isInOnStateChange = false;
1113
- }
1114
- }
1115
- },
1116
- { ignoreDetached: true }
1117
- );
1118
- }
1119
- async #initialize() {
1120
- const persistDataBuffer = await this.#actorDriver.readPersistedData(
1121
- this.#actorId
1122
- );
1123
- _invariant2.default.call(void 0,
1124
- persistDataBuffer !== void 0,
1125
- "persist data has not been set, it should be set when initialized"
1126
- );
1127
- const bareData = _chunkVFB23BYZcjs.PERSISTED_ACTOR_VERSIONED.deserializeWithEmbeddedVersion(
1128
- persistDataBuffer
1129
- );
1130
- const persistData = this.#convertFromBarePersisted(bareData);
1131
- if (persistData.hasInitiated) {
1132
- this.#rLog.info({
1133
- msg: "actor restoring",
1134
- connections: persistData.connections.length,
1135
- hibernatableWebSockets: persistData.hibernatableWebSocket.length
1136
- });
1137
- this.#setPersist(persistData);
1138
- for (const connPersist of this.#persist.connections) {
1139
- const conn = new Conn(this, connPersist);
1140
- this.#connections.set(conn.id, conn);
1141
- for (const sub of connPersist.subscriptions) {
1142
- this.#addSubscription(sub.eventName, conn, true);
1143
- }
1144
- }
1145
- } else {
1146
- this.#rLog.info({ msg: "actor creating" });
1147
- let stateData;
1148
- if (this.stateEnabled) {
1149
- this.#rLog.info({ msg: "actor state initializing" });
1150
- if ("createState" in this.#config) {
1151
- this.#config.createState;
1152
- stateData = await this.#config.createState(
1153
- this.actorContext,
1154
- persistData.input
1155
- );
1156
- } else if ("state" in this.#config) {
1157
- stateData = structuredClone(this.#config.state);
1158
- } else {
1159
- throw new Error(
1160
- "Both 'createState' or 'state' were not defined"
1161
- );
1162
- }
1163
- } else {
1164
- this.#rLog.debug({ msg: "state not enabled" });
1165
- }
1166
- persistData.state = stateData;
1167
- persistData.hasInitiated = true;
1168
- this.#rLog.debug({ msg: "writing state" });
1169
- const bareData2 = this.#convertToBarePersisted(persistData);
1170
- await this.#actorDriver.writePersistedData(
1171
- this.#actorId,
1172
- _chunkVFB23BYZcjs.PERSISTED_ACTOR_VERSIONED.serializeWithEmbeddedVersion(
1173
- bareData2
1174
- )
1175
- );
1176
- this.#setPersist(persistData);
1177
- if (this.#config.onCreate) {
1178
- await this.#config.onCreate(
1179
- this.actorContext,
1180
- persistData.input
1181
- );
1182
- }
1183
- }
1184
- }
1185
- __getConnForId(id) {
1186
- return this.#connections.get(id);
1187
- }
1188
- /**
1189
- * Call when conn is disconnected. Used by transports.
1190
- *
1191
- * If a clean diconnect, will be removed immediately.
1192
- *
1193
- * If not a clean disconnect, will keep the connection alive for a given interval to wait for reconnect.
1194
- */
1195
- __connDisconnected(conn, wasClean, requestId) {
1196
- if (requestId && conn.__socket && requestId !== conn.__socket.requestId) {
1197
- this.#rLog.debug({
1198
- msg: "ignoring stale disconnect event",
1199
- connId: conn.id,
1200
- eventRequestId: requestId,
1201
- currentRequestId: conn.__socket.requestId
1202
- });
1203
- return;
1204
- }
1205
- if (wasClean) {
1206
- this.#removeConn(conn);
1207
- } else {
1208
- if (!conn.__driverState) {
1209
- this.rLog.warn("called conn disconnected without driver state");
1210
- }
1211
- conn.__persist.lastSeen = Date.now();
1212
- conn.__socket = void 0;
1213
- this.#resetSleepTimer();
1214
- }
1215
- }
1216
- /**
1217
- * Removes a connection and cleans up its resources.
1218
- */
1219
- #removeConn(conn) {
1220
- const connIdx = this.#persist.connections.findIndex(
1221
- (c) => c.connId === conn.id
1222
- );
1223
- if (connIdx !== -1) {
1224
- this.#persist.connections.splice(connIdx, 1);
1225
- this.saveState({ immediate: true, allowStoppingState: true });
1226
- } else {
1227
- this.#rLog.warn({
1228
- msg: "could not find persisted connection to remove",
1229
- connId: conn.id
1230
- });
1231
- }
1232
- this.#connections.delete(conn.id);
1233
- this.#rLog.debug({ msg: "removed conn", connId: conn.id });
1234
- for (const eventName of [...conn.subscriptions.values()]) {
1235
- this.#removeSubscription(eventName, conn, true);
1236
- }
1237
- this.inspector.emitter.emit("connectionUpdated");
1238
- if (this.#config.onDisconnect) {
1239
- try {
1240
- const result = this.#config.onDisconnect(
1241
- this.actorContext,
1242
- conn
1243
- );
1244
- if (result instanceof Promise) {
1245
- result.catch((error) => {
1246
- this.#rLog.error({
1247
- msg: "error in `onDisconnect`",
1248
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1249
- });
1250
- });
1251
- }
1252
- } catch (error) {
1253
- this.#rLog.error({
1254
- msg: "error in `onDisconnect`",
1255
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1256
- });
1257
- }
1258
- }
1259
- this.#resetSleepTimer();
1260
- }
1261
- /**
1262
- * Called to create a new connection or reconnect an existing one.
1263
- */
1264
- async createConn(socket, params, request, connectionId, connectionToken) {
1265
- this.#assertReady();
1266
- if (socket.requestIdBuf && socket.hibernatable) {
1267
- this.rLog.debug({
1268
- msg: "checking for hibernatable websocket connection",
1269
- requestId: socket.requestId,
1270
- existingConnectionsCount: this.#connections.size
1271
- });
1272
- const existingConn = Array.from(this.#connections.values()).find(
1273
- (conn2) => conn2.__persist.hibernatableRequestId && _chunk7L65NNWPcjs.arrayBuffersEqual.call(void 0,
1274
- conn2.__persist.hibernatableRequestId,
1275
- socket.requestIdBuf
1276
- )
1277
- );
1278
- if (existingConn) {
1279
- this.rLog.debug({
1280
- msg: "reconnecting hibernatable websocket connection",
1281
- connectionId: existingConn.id,
1282
- requestId: socket.requestId
1283
- });
1284
- if (existingConn.__driverState) {
1285
- this.#rLog.warn({
1286
- msg: "found existing driver state on hibernatable websocket",
1287
- connectionId: existingConn.id,
1288
- requestId: socket.requestId
1289
- });
1290
- const driverKind = getConnDriverKindFromState(
1291
- existingConn.__driverState
1292
- );
1293
- const driver = CONN_DRIVERS[driverKind];
1294
- if (driver.disconnect) {
1295
- driver.disconnect(
1296
- this,
1297
- existingConn,
1298
- existingConn.__driverState[driverKind],
1299
- "Reconnecting hibernatable websocket with new driver state"
1300
- );
1301
- }
1302
- }
1303
- existingConn.__socket = socket;
1304
- existingConn.__persist.lastSeen = Date.now();
1305
- this.#resetSleepTimer();
1306
- this.inspector.emitter.emit("connectionUpdated");
1307
- return existingConn;
1308
- } else {
1309
- this.rLog.debug({
1310
- msg: "no existing hibernatable connection found, creating new connection",
1311
- requestId: socket.requestId
1312
- });
1313
- }
1314
- }
1315
- if (connectionId && connectionToken) {
1316
- this.rLog.debug({
1317
- msg: "checking for existing connection",
1318
- connectionId
1319
- });
1320
- const existingConn = this.#connections.get(connectionId);
1321
- if (existingConn && existingConn._token === connectionToken) {
1322
- this.rLog.debug({
1323
- msg: "reconnecting existing connection",
1324
- connectionId
1325
- });
1326
- if (existingConn.__driverState) {
1327
- const driverKind = getConnDriverKindFromState(
1328
- existingConn.__driverState
1329
- );
1330
- const driver = CONN_DRIVERS[driverKind];
1331
- if (driver.disconnect) {
1332
- driver.disconnect(
1333
- this,
1334
- existingConn,
1335
- existingConn.__driverState[driverKind],
1336
- "Reconnecting with new driver state"
1337
- );
1338
- }
1339
- }
1340
- existingConn.__socket = socket;
1341
- existingConn.__persist.lastSeen = Date.now();
1342
- this.#resetSleepTimer();
1343
- this.inspector.emitter.emit("connectionUpdated");
1344
- existingConn._sendMessage(
1345
- new (0, _chunkHHFKKVLRcjs.CachedSerializer)(
1346
- {
1347
- body: {
1348
- tag: "Init",
1349
- val: {
1350
- actorId: this.id,
1351
- connectionId: existingConn.id,
1352
- connectionToken: existingConn._token
1353
- }
1354
- }
1355
- },
1356
- _chunkVFB23BYZcjs.TO_CLIENT_VERSIONED
1357
- )
1358
- );
1359
- return existingConn;
1360
- } else {
1361
- this.rLog.debug({
1362
- msg: "connection not found or token mismatch, creating new connection",
1363
- connectionId
1364
- });
1365
- }
1366
- }
1367
- const newConnId = generateConnId();
1368
- const newConnToken = generateConnToken();
1369
- if (this.#connections.has(newConnId)) {
1370
- throw new Error(`Connection already exists: ${newConnId}`);
1371
- }
1372
- let connState;
1373
- const onBeforeConnectOpts = {
1374
- request
1375
- };
1376
- if (this.#config.onBeforeConnect) {
1377
- await this.#config.onBeforeConnect(
1378
- this.actorContext,
1379
- onBeforeConnectOpts,
1380
- params
1381
- );
1382
- }
1383
- if (this.connStateEnabled) {
1384
- if ("createConnState" in this.#config) {
1385
- const dataOrPromise = this.#config.createConnState(
1386
- this.actorContext,
1387
- onBeforeConnectOpts,
1388
- params
1389
- );
1390
- if (dataOrPromise instanceof Promise) {
1391
- connState = await _chunkHHFKKVLRcjs.deadline.call(void 0,
1392
- dataOrPromise,
1393
- this.#config.options.createConnStateTimeout
1394
- );
1395
- } else {
1396
- connState = dataOrPromise;
1397
- }
1398
- } else if ("connState" in this.#config) {
1399
- connState = structuredClone(this.#config.connState);
1400
- } else {
1401
- throw new Error(
1402
- "Could not create connection state from 'createConnState' or 'connState'"
1403
- );
1404
- }
1405
- }
1406
- const persist = {
1407
- connId: newConnId,
1408
- token: newConnToken,
1409
- params,
1410
- state: connState,
1411
- lastSeen: Date.now(),
1412
- subscriptions: []
1413
- };
1414
- if (socket.requestIdBuf) {
1415
- const isHibernatable = this.#persist.hibernatableWebSocket.findIndex(
1416
- (ws) => _chunk7L65NNWPcjs.arrayBuffersEqual.call(void 0, ws.requestId, socket.requestIdBuf)
1417
- ) !== -1;
1418
- if (isHibernatable) {
1419
- persist.hibernatableRequestId = socket.requestIdBuf;
1420
- }
1421
- }
1422
- const conn = new Conn(this, persist);
1423
- conn.__socket = socket;
1424
- this.#connections.set(conn.id, conn);
1425
- this.#resetSleepTimer();
1426
- this.#persist.connections.push(persist);
1427
- this.saveState({ immediate: true });
1428
- if (this.#config.onConnect) {
1429
- try {
1430
- const result = this.#config.onConnect(this.actorContext, conn);
1431
- if (result instanceof Promise) {
1432
- _chunkHHFKKVLRcjs.deadline.call(void 0,
1433
- result,
1434
- this.#config.options.onConnectTimeout
1435
- ).catch((error) => {
1436
- this.#rLog.error({
1437
- msg: "error in `onConnect`, closing socket",
1438
- error
1439
- });
1440
- conn == null ? void 0 : conn.disconnect("`onConnect` failed");
1441
- });
1442
- }
1443
- } catch (error) {
1444
- this.#rLog.error({
1445
- msg: "error in `onConnect`",
1446
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1447
- });
1448
- conn == null ? void 0 : conn.disconnect("`onConnect` failed");
1449
- }
1450
- }
1451
- this.inspector.emitter.emit("connectionUpdated");
1452
- conn._sendMessage(
1453
- new (0, _chunkHHFKKVLRcjs.CachedSerializer)(
1454
- {
1455
- body: {
1456
- tag: "Init",
1457
- val: {
1458
- actorId: this.id,
1459
- connectionId: conn.id,
1460
- connectionToken: conn._token
1461
- }
1462
- }
1463
- },
1464
- _chunkVFB23BYZcjs.TO_CLIENT_VERSIONED
1465
- )
1466
- );
1467
- return conn;
1468
- }
1469
- // MARK: Messages
1470
- async processMessage(message, conn) {
1471
- await _chunkVFB23BYZcjs.processMessage.call(void 0, message, this, conn, {
1472
- onExecuteAction: async (ctx, name, args) => {
1473
- this.inspector.emitter.emit("eventFired", {
1474
- type: "action",
1475
- name,
1476
- args,
1477
- connId: conn.id
1478
- });
1479
- return await this.executeAction(ctx, name, args);
1480
- },
1481
- onSubscribe: async (eventName, conn2) => {
1482
- this.inspector.emitter.emit("eventFired", {
1483
- type: "subscribe",
1484
- eventName,
1485
- connId: conn2.id
1486
- });
1487
- this.#addSubscription(eventName, conn2, false);
1488
- },
1489
- onUnsubscribe: async (eventName, conn2) => {
1490
- this.inspector.emitter.emit("eventFired", {
1491
- type: "unsubscribe",
1492
- eventName,
1493
- connId: conn2.id
1494
- });
1495
- this.#removeSubscription(eventName, conn2, false);
1496
- }
1497
- });
1498
- }
1499
- // MARK: Events
1500
- #addSubscription(eventName, connection, fromPersist) {
1501
- if (connection.subscriptions.has(eventName)) {
1502
- this.#rLog.debug({
1503
- msg: "connection already has subscription",
1504
- eventName
1505
- });
1506
- return;
1507
- }
1508
- if (!fromPersist) {
1509
- connection.__persist.subscriptions.push({ eventName });
1510
- this.saveState({ immediate: true });
1511
- }
1512
- connection.subscriptions.add(eventName);
1513
- let subscribers = this.#subscriptionIndex.get(eventName);
1514
- if (!subscribers) {
1515
- subscribers = /* @__PURE__ */ new Set();
1516
- this.#subscriptionIndex.set(eventName, subscribers);
1517
- }
1518
- subscribers.add(connection);
1519
- }
1520
- #removeSubscription(eventName, connection, fromRemoveConn) {
1521
- if (!connection.subscriptions.has(eventName)) {
1522
- this.#rLog.warn({
1523
- msg: "connection does not have subscription",
1524
- eventName
1525
- });
1526
- return;
1527
- }
1528
- if (!fromRemoveConn) {
1529
- connection.subscriptions.delete(eventName);
1530
- const subIdx = connection.__persist.subscriptions.findIndex(
1531
- (s) => s.eventName === eventName
1532
- );
1533
- if (subIdx !== -1) {
1534
- connection.__persist.subscriptions.splice(subIdx, 1);
1535
- } else {
1536
- this.#rLog.warn({
1537
- msg: "subscription does not exist with name",
1538
- eventName
1539
- });
1540
- }
1541
- this.saveState({ immediate: true });
1542
- }
1543
- const subscribers = this.#subscriptionIndex.get(eventName);
1544
- if (subscribers) {
1545
- subscribers.delete(connection);
1546
- if (subscribers.size === 0) {
1547
- this.#subscriptionIndex.delete(eventName);
1548
- }
1549
- }
1550
- }
1551
- #assertReady(allowStoppingState = false) {
1552
- if (!this.#ready) throw new (0, _chunkKSRXX3Z4cjs.InternalError)("Actor not ready");
1553
- if (!allowStoppingState && this.#stopCalled)
1554
- throw new (0, _chunkKSRXX3Z4cjs.InternalError)("Actor is stopping");
1555
- }
1556
- /**
1557
- * Check the liveness of all connections.
1558
- * Sets up a recurring check based on the configured interval.
1559
- */
1560
- #checkConnectionsLiveness() {
1561
- this.#rLog.debug({ msg: "checking connections liveness" });
1562
- let connected = 0;
1563
- let reconnecting = 0;
1564
- let removed = 0;
1565
- for (const conn of this.#connections.values()) {
1566
- if (conn.__status === "connected") {
1567
- connected += 1;
1568
- this.#rLog.debug({
1569
- msg: "connection is alive",
1570
- connId: conn.id
1571
- });
1572
- } else {
1573
- reconnecting += 1;
1574
- const lastSeen = conn.__persist.lastSeen;
1575
- const sinceLastSeen = Date.now() - lastSeen;
1576
- if (sinceLastSeen < this.#config.options.connectionLivenessTimeout) {
1577
- this.#rLog.debug({
1578
- msg: "connection might be alive, will check later",
1579
- connId: conn.id,
1580
- lastSeen,
1581
- sinceLastSeen
1582
- });
1583
- continue;
1584
- }
1585
- this.#rLog.info({
1586
- msg: "connection is dead, removing",
1587
- connId: conn.id,
1588
- lastSeen
1589
- });
1590
- removed += 1;
1591
- this.#removeConn(conn);
1592
- }
1593
- }
1594
- this.#rLog.debug({
1595
- msg: "checked connection liveness",
1596
- total: connected + reconnecting,
1597
- connected,
1598
- reconnecting,
1599
- removed
1600
- });
1601
- }
1602
- /**
1603
- * Check if the actor is ready to handle requests.
1604
- */
1605
- isReady() {
1606
- return this.#ready;
1607
- }
1608
- /**
1609
- * Execute an action call from a client.
1610
- *
1611
- * This method handles:
1612
- * 1. Validating the action name
1613
- * 2. Executing the action function
1614
- * 3. Processing the result through onBeforeActionResponse (if configured)
1615
- * 4. Handling timeouts and errors
1616
- * 5. Saving state changes
1617
- *
1618
- * @param ctx The action context
1619
- * @param actionName The name of the action being called
1620
- * @param args The arguments passed to the action
1621
- * @returns The result of the action call
1622
- * @throws {ActionNotFound} If the action doesn't exist
1623
- * @throws {ActionTimedOut} If the action times out
1624
- * @internal
1625
- */
1626
- async executeAction(ctx, actionName, args) {
1627
- _invariant2.default.call(void 0, this.#ready, "executing action before ready");
1628
- if (!(actionName in this.#config.actions)) {
1629
- this.#rLog.warn({ msg: "action does not exist", actionName });
1630
- throw new (0, _chunkKSRXX3Z4cjs.ActionNotFound)(actionName);
1631
- }
1632
- const actionFunction = this.#config.actions[actionName];
1633
- if (typeof actionFunction !== "function") {
1634
- this.#rLog.warn({
1635
- msg: "action is not a function",
1636
- actionName,
1637
- type: typeof actionFunction
1638
- });
1639
- throw new (0, _chunkKSRXX3Z4cjs.ActionNotFound)(actionName);
1640
- }
1641
- try {
1642
- this.#rLog.debug({
1643
- msg: "executing action",
1644
- actionName,
1645
- args
1646
- });
1647
- const outputOrPromise = actionFunction.call(
1648
- void 0,
1649
- ctx,
1650
- ...args
1651
- );
1652
- let output;
1653
- if (outputOrPromise instanceof Promise) {
1654
- this.#rLog.debug({
1655
- msg: "awaiting async action",
1656
- actionName
1657
- });
1658
- output = await _chunkHHFKKVLRcjs.deadline.call(void 0,
1659
- outputOrPromise,
1660
- this.#config.options.actionTimeout
1661
- );
1662
- this.#rLog.debug({
1663
- msg: "async action completed",
1664
- actionName
1665
- });
1666
- } else {
1667
- output = outputOrPromise;
1668
- }
1669
- if (this.#config.onBeforeActionResponse) {
1670
- try {
1671
- const processedOutput = this.#config.onBeforeActionResponse(
1672
- this.actorContext,
1673
- actionName,
1674
- args,
1675
- output
1676
- );
1677
- if (processedOutput instanceof Promise) {
1678
- this.#rLog.debug({
1679
- msg: "awaiting onBeforeActionResponse",
1680
- actionName
1681
- });
1682
- output = await processedOutput;
1683
- this.#rLog.debug({
1684
- msg: "onBeforeActionResponse completed",
1685
- actionName
1686
- });
1687
- } else {
1688
- output = processedOutput;
1689
- }
1690
- } catch (error) {
1691
- this.#rLog.error({
1692
- msg: "error in `onBeforeActionResponse`",
1693
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1694
- });
1695
- }
1696
- }
1697
- this.#rLog.debug({
1698
- msg: "action completed",
1699
- actionName,
1700
- outputType: typeof output,
1701
- isPromise: output instanceof Promise
1702
- });
1703
- return output;
1704
- } catch (error) {
1705
- if (error instanceof _chunkHHFKKVLRcjs.DeadlineError) {
1706
- throw new (0, _chunkKSRXX3Z4cjs.ActionTimedOut)();
1707
- }
1708
- this.#rLog.error({
1709
- msg: "action error",
1710
- actionName,
1711
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1712
- });
1713
- throw error;
1714
- } finally {
1715
- this.#savePersistThrottled();
1716
- }
1717
- }
1718
- /**
1719
- * Returns a list of action methods available on this actor.
1720
- */
1721
- get actions() {
1722
- return Object.keys(this.#config.actions);
1723
- }
1724
- /**
1725
- * Handles raw HTTP requests to the actor.
1726
- */
1727
- async handleFetch(request, opts) {
1728
- this.#assertReady();
1729
- if (!this.#config.onFetch) {
1730
- throw new (0, _chunkKSRXX3Z4cjs.FetchHandlerNotDefined)();
1731
- }
1732
- try {
1733
- const response = await this.#config.onFetch(
1734
- this.actorContext,
1735
- request,
1736
- opts
1737
- );
1738
- if (!response) {
1739
- throw new (0, _chunkKSRXX3Z4cjs.InvalidFetchResponse)();
1740
- }
1741
- return response;
1742
- } catch (error) {
1743
- this.#rLog.error({
1744
- msg: "onFetch error",
1745
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1746
- });
1747
- throw error;
1748
- } finally {
1749
- this.#savePersistThrottled();
1750
- }
1751
- }
1752
- /**
1753
- * Handles raw WebSocket connections to the actor.
1754
- */
1755
- async handleWebSocket(websocket, opts) {
1756
- this.#assertReady();
1757
- if (!this.#config.onWebSocket) {
1758
- throw new (0, _chunkKSRXX3Z4cjs.InternalError)("onWebSocket handler not defined");
1759
- }
1760
- try {
1761
- const stateBeforeHandler = this.#persistChanged;
1762
- this.#activeRawWebSockets.add(websocket);
1763
- this.#resetSleepTimer();
1764
- let rivetRequestId;
1765
- let persistedHibernatableWebSocket;
1766
- const onSocketOpened = (event) => {
1767
- rivetRequestId = event == null ? void 0 : event.rivetRequestId;
1768
- if (rivetRequestId) {
1769
- const rivetRequestIdLocal = rivetRequestId;
1770
- persistedHibernatableWebSocket = this.#persist.hibernatableWebSocket.find(
1771
- (ws) => _chunk7L65NNWPcjs.arrayBuffersEqual.call(void 0,
1772
- ws.requestId,
1773
- rivetRequestIdLocal
1774
- )
1775
- );
1776
- if (persistedHibernatableWebSocket) {
1777
- persistedHibernatableWebSocket.lastSeenTimestamp = BigInt(Date.now());
1778
- }
1779
- }
1780
- this.#rLog.debug({
1781
- msg: "actor instance onSocketOpened",
1782
- rivetRequestId,
1783
- isHibernatable: !!persistedHibernatableWebSocket,
1784
- hibernationMsgIndex: persistedHibernatableWebSocket == null ? void 0 : persistedHibernatableWebSocket.msgIndex
1785
- });
1786
- };
1787
- const onSocketMessage = (event) => {
1788
- if (persistedHibernatableWebSocket) {
1789
- persistedHibernatableWebSocket.lastSeenTimestamp = BigInt(
1790
- Date.now()
1791
- );
1792
- persistedHibernatableWebSocket.msgIndex = BigInt(
1793
- event.rivetMessageIndex
1794
- );
1795
- }
1796
- this.#rLog.debug({
1797
- msg: "actor instance onSocketMessage",
1798
- rivetRequestId,
1799
- isHibernatable: !!persistedHibernatableWebSocket,
1800
- hibernationMsgIndex: persistedHibernatableWebSocket == null ? void 0 : persistedHibernatableWebSocket.msgIndex
1801
- });
1802
- };
1803
- const onSocketClosed = (_event) => {
1804
- if (rivetRequestId) {
1805
- const rivetRequestIdLocal = rivetRequestId;
1806
- const wsIndex = this.#persist.hibernatableWebSocket.findIndex(
1807
- (ws) => _chunk7L65NNWPcjs.arrayBuffersEqual.call(void 0,
1808
- ws.requestId,
1809
- rivetRequestIdLocal
1810
- )
1811
- );
1812
- const removed = this.#persist.hibernatableWebSocket.splice(
1813
- wsIndex,
1814
- 1
1815
- );
1816
- if (removed.length > 0) {
1817
- this.#rLog.debug({
1818
- msg: "removed hibernatable websocket",
1819
- rivetRequestId,
1820
- hibernationMsgIndex: persistedHibernatableWebSocket == null ? void 0 : persistedHibernatableWebSocket.msgIndex
1821
- });
1822
- } else {
1823
- this.#rLog.warn({
1824
- msg: "could not find hibernatable websocket to remove",
1825
- rivetRequestId,
1826
- hibernationMsgIndex: persistedHibernatableWebSocket == null ? void 0 : persistedHibernatableWebSocket.msgIndex
1827
- });
1828
- }
1829
- }
1830
- this.#rLog.debug({
1831
- msg: "actor instance onSocketMessage",
1832
- rivetRequestId,
1833
- isHibernatable: !!persistedHibernatableWebSocket,
1834
- hibernatableWebSocketCount: this.#persist.hibernatableWebSocket.length
1835
- });
1836
- try {
1837
- websocket.removeEventListener("open", onSocketOpened);
1838
- websocket.removeEventListener("message", onSocketMessage);
1839
- websocket.removeEventListener("close", onSocketClosed);
1840
- websocket.removeEventListener("error", onSocketClosed);
1841
- } catch (e) {
1842
- }
1843
- this.#activeRawWebSockets.delete(websocket);
1844
- this.#resetSleepTimer();
1845
- };
1846
- try {
1847
- websocket.addEventListener("open", onSocketOpened);
1848
- websocket.addEventListener("message", onSocketMessage);
1849
- websocket.addEventListener("close", onSocketClosed);
1850
- websocket.addEventListener("error", onSocketClosed);
1851
- } catch (e2) {
1852
- }
1853
- await this.#config.onWebSocket(this.actorContext, websocket, opts);
1854
- if (this.#persistChanged && !stateBeforeHandler) {
1855
- await this.saveState({ immediate: true });
1856
- }
1857
- } catch (error) {
1858
- this.#rLog.error({
1859
- msg: "onWebSocket error",
1860
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1861
- });
1862
- throw error;
1863
- } finally {
1864
- this.#savePersistThrottled();
1865
- }
1866
- }
1867
- // MARK: Lifecycle hooks
1868
- // MARK: Exposed methods
1869
- get log() {
1870
- _invariant2.default.call(void 0, this.#log, "log not configured");
1871
- return this.#log;
1872
- }
1873
- get rLog() {
1874
- _invariant2.default.call(void 0, this.#rLog, "log not configured");
1875
- return this.#rLog;
1876
- }
1877
- /**
1878
- * Gets the name.
1879
- */
1880
- get name() {
1881
- return this.#name;
1882
- }
1883
- /**
1884
- * Gets the key.
1885
- */
1886
- get key() {
1887
- return this.#key;
1888
- }
1889
- /**
1890
- * Gets the region.
1891
- */
1892
- get region() {
1893
- return this.#region;
1894
- }
1895
- /**
1896
- * Gets the scheduler.
1897
- */
1898
- get schedule() {
1899
- return this.#schedule;
1900
- }
1901
- /**
1902
- * Gets the map of connections.
1903
- */
1904
- get conns() {
1905
- return this.#connections;
1906
- }
1907
- /**
1908
- * Gets the current state.
1909
- *
1910
- * Changing properties of this value will automatically be persisted.
1911
- */
1912
- get state() {
1913
- this.#validateStateEnabled();
1914
- return this.#persist.state;
1915
- }
1916
- /**
1917
- * Gets the database.
1918
- * @experimental
1919
- * @throws {DatabaseNotEnabled} If the database is not enabled.
1920
- */
1921
- get db() {
1922
- if (!this.#db) {
1923
- throw new (0, _chunkKSRXX3Z4cjs.DatabaseNotEnabled)();
1924
- }
1925
- return this.#db;
1926
- }
1927
- /**
1928
- * Sets the current state.
1929
- *
1930
- * This property will automatically be persisted.
1931
- */
1932
- set state(value) {
1933
- this.#validateStateEnabled();
1934
- this.#persist.state = value;
1935
- }
1936
- get vars() {
1937
- this.#validateVarsEnabled();
1938
- _invariant2.default.call(void 0, this.#vars !== void 0, "vars not enabled");
1939
- return this.#vars;
1940
- }
1941
- /**
1942
- * Broadcasts an event to all connected clients.
1943
- * @param name - The name of the event.
1944
- * @param args - The arguments to send with the event.
1945
- */
1946
- _broadcast(name, ...args) {
1947
- this.#assertReady();
1948
- this.inspector.emitter.emit("eventFired", {
1949
- type: "broadcast",
1950
- eventName: name,
1951
- args
1952
- });
1953
- const subscriptions = this.#subscriptionIndex.get(name);
1954
- if (!subscriptions) return;
1955
- const toClientSerializer = new (0, _chunkHHFKKVLRcjs.CachedSerializer)(
1956
- {
1957
- body: {
1958
- tag: "Event",
1959
- val: {
1960
- name,
1961
- args: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor.encode(args))
1962
- }
1963
- }
1964
- },
1965
- _chunkVFB23BYZcjs.TO_CLIENT_VERSIONED
1966
- );
1967
- for (const connection of subscriptions) {
1968
- connection._sendMessage(toClientSerializer);
1969
- }
1970
- }
1971
- /**
1972
- * Prevents the actor from sleeping until promise is complete.
1973
- *
1974
- * This allows the actor runtime to ensure that a promise completes while
1975
- * returning from an action request early.
1976
- *
1977
- * @param promise - The promise to run in the background.
1978
- */
1979
- _waitUntil(promise) {
1980
- this.#assertReady();
1981
- const nonfailablePromise = promise.then(() => {
1982
- this.#rLog.debug({ msg: "wait until promise complete" });
1983
- }).catch((error) => {
1984
- this.#rLog.error({
1985
- msg: "wait until promise failed",
1986
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
1987
- });
1988
- });
1989
- this.#backgroundPromises.push(nonfailablePromise);
1990
- }
1991
- /**
1992
- * Forces the state to get saved.
1993
- *
1994
- * This is helpful if running a long task that may fail later or when
1995
- * running a background job that updates the state.
1996
- *
1997
- * @param opts - Options for saving the state.
1998
- */
1999
- async saveState(opts) {
2000
- this.#assertReady(opts.allowStoppingState);
2001
- this.#rLog.debug({
2002
- msg: "saveState called",
2003
- persistChanged: this.#persistChanged,
2004
- allowStoppingState: opts.allowStoppingState,
2005
- immediate: opts.immediate
2006
- });
2007
- if (this.#persistChanged) {
2008
- if (opts.immediate) {
2009
- await this.#savePersistInner();
2010
- } else {
2011
- if (!this.#onPersistSavedPromise) {
2012
- this.#onPersistSavedPromise = _chunk7L65NNWPcjs.promiseWithResolvers.call(void 0, );
2013
- }
2014
- this.#savePersistThrottled();
2015
- await this.#onPersistSavedPromise.promise;
2016
- }
2017
- }
2018
- }
2019
- /**
2020
- * Called by router middleware when an HTTP request begins.
2021
- */
2022
- __beginHonoHttpRequest() {
2023
- this.#activeHonoHttpRequests++;
2024
- this.#resetSleepTimer();
2025
- }
2026
- /**
2027
- * Called by router middleware when an HTTP request ends.
2028
- */
2029
- __endHonoHttpRequest() {
2030
- this.#activeHonoHttpRequests--;
2031
- if (this.#activeHonoHttpRequests < 0) {
2032
- this.#activeHonoHttpRequests = 0;
2033
- this.#rLog.warn({
2034
- msg: "active hono requests went below 0, this is a RivetKit bug",
2035
- ..._chunk7L65NNWPcjs.EXTRA_ERROR_LOG
2036
- });
2037
- }
2038
- this.#resetSleepTimer();
2039
- }
2040
- // MARK: Sleep
2041
- /**
2042
- * Reset timer from the last actor interaction that allows it to be put to sleep.
2043
- *
2044
- * This should be called any time a sleep-related event happens:
2045
- * - Connection opens (will clear timer)
2046
- * - Connection closes (will schedule timer if there are no open connections)
2047
- * - Alarm triggers (will reset timer)
2048
- *
2049
- * We don't need to call this on events like individual action calls, since there will always be a connection open for these.
2050
- **/
2051
- #resetSleepTimer() {
2052
- if (this.#config.options.noSleep || !this.#sleepingSupported) return;
2053
- if (this.#stopCalled) return;
2054
- const canSleep = this.#canSleep();
2055
- this.#rLog.debug({
2056
- msg: "resetting sleep timer",
2057
- canSleep: CanSleep[canSleep],
2058
- existingTimeout: !!this.#sleepTimeout,
2059
- timeout: this.#config.options.sleepTimeout
2060
- });
2061
- if (this.#sleepTimeout) {
2062
- clearTimeout(this.#sleepTimeout);
2063
- this.#sleepTimeout = void 0;
2064
- }
2065
- if (this.#sleepCalled) return;
2066
- if (canSleep === 0 /* Yes */) {
2067
- this.#sleepTimeout = setTimeout(() => {
2068
- this._startSleep();
2069
- }, this.#config.options.sleepTimeout);
2070
- }
2071
- }
2072
- /** If this actor can be put in a sleeping state. */
2073
- #canSleep() {
2074
- if (!this.#ready) return 1 /* NotReady */;
2075
- if (this.#activeHonoHttpRequests > 0)
2076
- return 3 /* ActiveHonoHttpRequests */;
2077
- if (this.#activeRawWebSockets.size > 0)
2078
- return 4 /* ActiveRawWebSockets */;
2079
- for (const conn of this.#connections.values()) {
2080
- if (conn.status === "connected") return 2 /* ActiveConns */;
2081
- }
2082
- return 0 /* Yes */;
2083
- }
2084
- /**
2085
- * Puts an actor to sleep. This should just start the sleep sequence, most shutdown logic should be in _stop (which is called by the ActorDriver when sleeping).
2086
- *
2087
- * For the engine, this will:
2088
- * 1. Publish EventActorIntent with ActorIntentSleep (via driver.startSleep)
2089
- * 2. Engine runner will wait for CommandStopActor
2090
- * 3. Engine runner will call _onStop and wait for it to finish
2091
- * 4. Engine runner will publish EventActorStateUpdate with ActorStateSTop
2092
- **/
2093
- _startSleep() {
2094
- var _a;
2095
- if (this.#stopCalled) {
2096
- this.#rLog.debug({
2097
- msg: "cannot call _startSleep if actor already stopping"
2098
- });
2099
- return;
2100
- }
2101
- if (this.#sleepCalled) {
2102
- this.#rLog.warn({
2103
- msg: "cannot call _startSleep twice, actor already sleeping"
2104
- });
2105
- return;
2106
- }
2107
- this.#sleepCalled = true;
2108
- const sleep = (_a = this.#actorDriver.startSleep) == null ? void 0 : _a.bind(
2109
- this.#actorDriver,
2110
- this.#actorId
2111
- );
2112
- _invariant2.default.call(void 0, this.#sleepingSupported, "sleeping not supported");
2113
- _invariant2.default.call(void 0, sleep, "no sleep on driver");
2114
- this.#rLog.info({ msg: "actor sleeping" });
2115
- setImmediate(() => {
2116
- sleep();
2117
- });
2118
- }
2119
- // MARK: Stop
2120
- /**
2121
- * For the engine:
2122
- * 1. Engine runner receives CommandStopActor
2123
- * 2. Engine runner calls _onStop and waits for it to finish
2124
- * 3. Engine runner publishes EventActorStateUpdate with ActorStateSTop
2125
- */
2126
- async _onStop() {
2127
- if (this.#stopCalled) {
2128
- this.#rLog.warn({ msg: "already stopping actor" });
2129
- return;
2130
- }
2131
- this.#stopCalled = true;
2132
- this.#rLog.info({ msg: "actor stopping" });
2133
- if (this.#sleepTimeout) {
2134
- clearTimeout(this.#sleepTimeout);
2135
- this.#sleepTimeout = void 0;
2136
- }
2137
- try {
2138
- this.#abortController.abort();
2139
- } catch (e3) {
2140
- }
2141
- if (this.#config.onStop) {
2142
- try {
2143
- this.#rLog.debug({ msg: "calling onStop" });
2144
- const result = this.#config.onStop(this.actorContext);
2145
- if (result instanceof Promise) {
2146
- await _chunkHHFKKVLRcjs.deadline.call(void 0, result, this.#config.options.onStopTimeout);
2147
- }
2148
- this.#rLog.debug({ msg: "onStop completed" });
2149
- } catch (error) {
2150
- if (error instanceof _chunkHHFKKVLRcjs.DeadlineError) {
2151
- this.#rLog.error({ msg: "onStop timed out" });
2152
- } else {
2153
- this.#rLog.error({
2154
- msg: "error in onStop",
2155
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
2156
- });
2157
- }
2158
- }
2159
- }
2160
- const promises = [];
2161
- for (const connection of this.#connections.values()) {
2162
- if (!connection.isHibernatable) {
2163
- this.#rLog.debug({
2164
- msg: "disconnecting non-hibernatable connection on actor stop",
2165
- connId: connection.id
2166
- });
2167
- promises.push(connection.disconnect());
2168
- }
2169
- }
2170
- await this.#waitBackgroundPromises(
2171
- this.#config.options.waitUntilTimeout
2172
- );
2173
- if (this.#pendingSaveTimeout) clearTimeout(this.#pendingSaveTimeout);
2174
- if (this.#checkConnLivenessInterval)
2175
- clearInterval(this.#checkConnLivenessInterval);
2176
- await this.saveState({ immediate: true, allowStoppingState: true });
2177
- const res = Promise.race([
2178
- Promise.all(promises).then(() => false),
2179
- new Promise(
2180
- (res2) => globalThis.setTimeout(() => res2(true), 1500)
2181
- )
2182
- ]);
2183
- if (await res) {
2184
- this.#rLog.warn({
2185
- msg: "timed out waiting for connections to close, shutting down anyway"
2186
- });
2187
- }
2188
- if (this.#persistWriteQueue.runningDrainLoop)
2189
- await this.#persistWriteQueue.runningDrainLoop;
2190
- if (this.#alarmWriteQueue.runningDrainLoop)
2191
- await this.#alarmWriteQueue.runningDrainLoop;
2192
- }
2193
- /** Abort signal that fires when the actor is stopping. */
2194
- get abortSignal() {
2195
- return this.#abortController.signal;
2196
- }
2197
- /** Wait for background waitUntil promises with a timeout. */
2198
- async #waitBackgroundPromises(timeoutMs) {
2199
- const pending = this.#backgroundPromises;
2200
- if (pending.length === 0) {
2201
- this.#rLog.debug({ msg: "no background promises" });
2202
- return;
2203
- }
2204
- const timedOut = await Promise.race([
2205
- Promise.allSettled(pending).then(() => false),
2206
- new Promise(
2207
- (resolve) => setTimeout(() => resolve(true), timeoutMs)
2208
- )
2209
- ]);
2210
- if (timedOut) {
2211
- this.#rLog.error({
2212
- msg: "timed out waiting for background tasks, background promises may have leaked",
2213
- count: pending.length,
2214
- timeoutMs
2215
- });
2216
- } else {
2217
- this.#rLog.debug({ msg: "background promises finished" });
2218
- }
2219
- }
2220
- // MARK: BARE Conversion Helpers
2221
- #convertToBarePersisted(persist) {
2222
- return {
2223
- input: persist.input !== void 0 ? _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor.encode(persist.input)) : null,
2224
- hasInitialized: persist.hasInitiated,
2225
- state: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor.encode(persist.state)),
2226
- connections: persist.connections.map((conn) => ({
2227
- id: conn.connId,
2228
- token: conn.token,
2229
- parameters: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor.encode(conn.params || {})),
2230
- state: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor.encode(conn.state || {})),
2231
- subscriptions: conn.subscriptions.map((sub) => ({
2232
- eventName: sub.eventName
2233
- })),
2234
- lastSeen: BigInt(conn.lastSeen),
2235
- hibernatableRequestId: _nullishCoalesce(conn.hibernatableRequestId, () => ( null))
2236
- })),
2237
- scheduledEvents: persist.scheduledEvents.map((event) => ({
2238
- eventId: event.eventId,
2239
- timestamp: BigInt(event.timestamp),
2240
- kind: {
2241
- tag: "GenericPersistedScheduleEvent",
2242
- val: {
2243
- action: event.kind.generic.actionName,
2244
- args: _nullishCoalesce(event.kind.generic.args, () => ( null))
2245
- }
2246
- }
2247
- })),
2248
- hibernatableWebSocket: persist.hibernatableWebSocket.map((ws) => ({
2249
- requestId: ws.requestId,
2250
- lastSeenTimestamp: ws.lastSeenTimestamp,
2251
- msgIndex: ws.msgIndex
2252
- }))
2253
- };
2254
- }
2255
- #convertFromBarePersisted(bareData) {
2256
- return {
2257
- input: bareData.input ? cbor.decode(new Uint8Array(bareData.input)) : void 0,
2258
- hasInitiated: bareData.hasInitialized,
2259
- state: cbor.decode(new Uint8Array(bareData.state)),
2260
- connections: bareData.connections.map((conn) => ({
2261
- connId: conn.id,
2262
- token: conn.token,
2263
- params: cbor.decode(new Uint8Array(conn.parameters)),
2264
- state: cbor.decode(new Uint8Array(conn.state)),
2265
- subscriptions: conn.subscriptions.map((sub) => ({
2266
- eventName: sub.eventName
2267
- })),
2268
- lastSeen: Number(conn.lastSeen),
2269
- hibernatableRequestId: _nullishCoalesce(conn.hibernatableRequestId, () => ( void 0))
2270
- })),
2271
- scheduledEvents: bareData.scheduledEvents.map((event) => ({
2272
- eventId: event.eventId,
2273
- timestamp: Number(event.timestamp),
2274
- kind: {
2275
- generic: {
2276
- actionName: event.kind.val.action,
2277
- args: event.kind.val.args
2278
- }
2279
- }
2280
- })),
2281
- hibernatableWebSocket: bareData.hibernatableWebSocket.map((ws) => ({
2282
- requestId: ws.requestId,
2283
- lastSeenTimestamp: ws.lastSeenTimestamp,
2284
- msgIndex: ws.msgIndex
2285
- }))
2286
- };
2287
- }
2288
- };
2289
-
2290
- // src/actor/conn.ts
2291
- function generateConnId() {
2292
- return crypto.randomUUID();
2293
- }
2294
- function generateConnToken() {
2295
- return _chunkHHFKKVLRcjs.generateSecureToken.call(void 0, 32);
2296
- }
2297
- function generateConnRequestId() {
2298
- return crypto.randomUUID();
2299
- }
2300
- var Conn = (_class2 = class {
2301
- __init2() {this.subscriptions = /* @__PURE__ */ new Set()}
2302
- // TODO: Remove this cyclical reference
2303
- #actor;
2304
- /**
2305
- * The proxied state that notifies of changes automatically.
2306
- *
2307
- * Any data that should be stored indefinitely should be held within this object.
2308
- */
2309
-
2310
- get __driverState() {
2311
- var _a;
2312
- return (_a = this.__socket) == null ? void 0 : _a.driverState;
2313
- }
2314
- /**
2315
- * Socket connected to this connection.
2316
- *
2317
- * If undefined, then nothing is connected to this.
2318
- */
2319
-
2320
- get __status() {
2321
- if (this.__socket || this.isHibernatable) {
2322
- return "connected";
2323
- } else {
2324
- return "reconnecting";
2325
- }
2326
- }
2327
- get params() {
2328
- return this.__persist.params;
2329
- }
2330
- get __stateEnabled() {
2331
- return this.#actor.connStateEnabled;
2332
- }
2333
- /**
2334
- * Gets the current state of the connection.
2335
- *
2336
- * Throws an error if the state is not enabled.
2337
- */
2338
- get state() {
2339
- this.#validateStateEnabled();
2340
- if (!this.__persist.state) throw new Error("state should exists");
2341
- return this.__persist.state;
2342
- }
2343
- /**
2344
- * Sets the state of the connection.
2345
- *
2346
- * Throws an error if the state is not enabled.
2347
- */
2348
- set state(value) {
2349
- this.#validateStateEnabled();
2350
- this.__persist.state = value;
2351
- }
2352
- /**
2353
- * Unique identifier for the connection.
2354
- */
2355
- get id() {
2356
- return this.__persist.connId;
2357
- }
2358
- /**
2359
- * Token used to authenticate this request.
2360
- */
2361
- get _token() {
2362
- return this.__persist.token;
2363
- }
2364
- /**
2365
- * Status of the connection.
2366
- */
2367
- get status() {
2368
- return this.__status;
2369
- }
2370
- /**
2371
- * @experimental
2372
- *
2373
- * If the underlying connection can hibernate.
2374
- */
2375
- get isHibernatable() {
2376
- if (!this.__persist.hibernatableRequestId) {
2377
- return false;
2378
- }
2379
- return this.#actor[PERSIST_SYMBOL].hibernatableWebSocket.findIndex(
2380
- (x) => _chunk7L65NNWPcjs.arrayBuffersEqual.call(void 0,
2381
- x.requestId,
2382
- this.__persist.hibernatableRequestId
2383
- )
2384
- ) > -1;
2385
- }
2386
- /**
2387
- * Timestamp of the last time the connection was seen, i.e. the last time the connection was active and checked for liveness.
2388
- */
2389
- get lastSeen() {
2390
- return this.__persist.lastSeen;
2391
- }
2392
- /**
2393
- * Initializes a new instance of the Connection class.
2394
- *
2395
- * This should only be constructed by {@link Actor}.
2396
- *
2397
- * @protected
2398
- */
2399
- constructor(actor, persist) {;_class2.prototype.__init2.call(this);
2400
- this.#actor = actor;
2401
- this.__persist = persist;
2402
- }
2403
- #validateStateEnabled() {
2404
- if (!this.__stateEnabled) {
2405
- throw new (0, _chunkKSRXX3Z4cjs.ConnStateNotEnabled)();
2406
- }
2407
- }
2408
- /**
2409
- * Sends a WebSocket message to the client.
2410
- *
2411
- * @param message - The message to send.
2412
- *
2413
- * @protected
2414
- */
2415
- _sendMessage(message) {
2416
- if (this.__driverState) {
2417
- const driverKind = getConnDriverKindFromState(this.__driverState);
2418
- const driver = CONN_DRIVERS[driverKind];
2419
- if (driver.sendMessage) {
2420
- driver.sendMessage(
2421
- this.#actor,
2422
- this,
2423
- this.__driverState[driverKind],
2424
- message
2425
- );
2426
- } else {
2427
- this.#actor.rLog.debug({
2428
- msg: "conn driver does not support sending messages",
2429
- conn: this.id
2430
- });
2431
- }
2432
- } else {
2433
- this.#actor.rLog.warn({
2434
- msg: "missing connection driver state for send message",
2435
- conn: this.id
2436
- });
2437
- }
2438
- }
2439
- /**
2440
- * Sends an event with arguments to the client.
2441
- *
2442
- * @param eventName - The name of the event.
2443
- * @param args - The arguments for the event.
2444
- * @see {@link https://rivet.dev/docs/events|Events Documentation}
2445
- */
2446
- send(eventName, ...args) {
2447
- this.#actor.inspector.emitter.emit("eventFired", {
2448
- type: "event",
2449
- eventName,
2450
- args,
2451
- connId: this.id
2452
- });
2453
- this._sendMessage(
2454
- new (0, _chunkHHFKKVLRcjs.CachedSerializer)(
2455
- {
2456
- body: {
2457
- tag: "Event",
2458
- val: {
2459
- name: eventName,
2460
- args: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor2.encode(args))
2461
- }
2462
- }
2463
- },
2464
- _chunkVFB23BYZcjs.TO_CLIENT_VERSIONED
2465
- )
2466
- );
2467
- }
2468
- /**
2469
- * Disconnects the client with an optional reason.
2470
- *
2471
- * @param reason - The reason for disconnection.
2472
- */
2473
- async disconnect(reason) {
2474
- if (this.__socket && this.__driverState) {
2475
- const driverKind = getConnDriverKindFromState(this.__driverState);
2476
- const driver = CONN_DRIVERS[driverKind];
2477
- if (driver.disconnect) {
2478
- driver.disconnect(
2479
- this.#actor,
2480
- this,
2481
- this.__driverState[driverKind],
2482
- reason
2483
- );
2484
- } else {
2485
- this.#actor.rLog.debug({
2486
- msg: "no disconnect handler for conn driver",
2487
- conn: this.id
2488
- });
2489
- }
2490
- this.#actor.__connDisconnected(this, true, this.__socket.requestId);
2491
- } else {
2492
- this.#actor.rLog.warn({
2493
- msg: "missing connection driver state for disconnect",
2494
- conn: this.id
2495
- });
2496
- }
2497
- this.__socket = void 0;
2498
- }
2499
- }, _class2);
2500
-
2501
- // src/actor/definition.ts
2502
- var ActorDefinition = class {
2503
- #config;
2504
- constructor(config) {
2505
- this.#config = config;
2506
- }
2507
- get config() {
2508
- return this.#config;
2509
- }
2510
- instantiate() {
2511
- return new ActorInstance(this.#config);
2512
- }
2513
- };
2514
- function lookupInRegistry(registryConfig, name) {
2515
- const definition = registryConfig.use[name];
2516
- if (!definition) throw new Error(`no actor in registry for name ${name}`);
2517
- return definition;
2518
- }
2519
-
2520
- // src/client/errors.ts
2521
- var ActorClientError = class extends Error {
2522
- };
2523
- var InternalError2 = class extends ActorClientError {
2524
- };
2525
- var ManagerError = class extends ActorClientError {
2526
- constructor(error, opts) {
2527
- super(`Manager error: ${error}`, opts);
2528
- }
2529
- };
2530
- var MalformedResponseMessage = class extends ActorClientError {
2531
- constructor(cause) {
2532
- super(`Malformed response message: ${cause}`, { cause });
2533
- }
2534
- };
2535
- var ActorError = (_class3 = class extends ActorClientError {
2536
- constructor(group, code, message, metadata) {
2537
- super(message);_class3.prototype.__init3.call(this);;
2538
- this.group = group;
2539
- this.code = code;
2540
- this.metadata = metadata;
2541
- }
2542
- __init3() {this.__type = "ActorError"}
2543
- }, _class3);
2544
- var HttpRequestError = class extends ActorClientError {
2545
- constructor(message, opts) {
2546
- super(`HTTP request error: ${message}`, { cause: opts == null ? void 0 : opts.cause });
2547
- }
2548
- };
2549
- var ActorConnDisposed = class extends ActorClientError {
2550
- constructor() {
2551
- super("Attempting to interact with a disposed actor connection.");
2552
- }
2553
- };
2554
-
2555
- // src/client/actor-conn.ts
2556
-
2557
-
2558
- var _pretry = require('p-retry'); var _pretry2 = _interopRequireDefault(_pretry);
2559
-
2560
- // src/common/eventsource.ts
2561
- var eventSourcePromise = null;
2562
- async function importEventSource() {
2563
- if (eventSourcePromise !== null) {
2564
- return eventSourcePromise;
2565
- }
2566
- eventSourcePromise = (async () => {
2567
- let _EventSource;
2568
- try {
2569
- const moduleName = "eventsource";
2570
- const es = await Promise.resolve().then(() => _interopRequireWildcard(require(
2571
- /* webpackIgnore: true */
2572
- moduleName
2573
- )));
2574
- _EventSource = es.EventSource;
2575
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug("using eventsource from npm");
2576
- } catch (err) {
2577
- _EventSource = class MockEventSource {
2578
- constructor() {
2579
- throw new Error(
2580
- 'EventSource support requires installing the "eventsource" peer dependency.'
2581
- );
2582
- }
2583
- };
2584
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug("using mock eventsource");
2585
- }
2586
- return _EventSource;
2587
- })();
2588
- return eventSourcePromise;
2589
- }
2590
-
2591
- // src/client/actor-query.ts
2592
- async function queryActor(c, query, managerDriver) {
2593
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "querying actor", query: JSON.stringify(query) });
2594
- let actorOutput;
2595
- if ("getForId" in query) {
2596
- const output = await managerDriver.getForId({
2597
- c,
2598
- name: query.getForId.name,
2599
- actorId: query.getForId.actorId
2600
- });
2601
- if (!output) throw new (0, _chunkKSRXX3Z4cjs.ActorNotFound)(query.getForId.actorId);
2602
- actorOutput = output;
2603
- } else if ("getForKey" in query) {
2604
- const existingActor = await managerDriver.getWithKey({
2605
- c,
2606
- name: query.getForKey.name,
2607
- key: query.getForKey.key
2608
- });
2609
- if (!existingActor) {
2610
- throw new (0, _chunkKSRXX3Z4cjs.ActorNotFound)(
2611
- `${query.getForKey.name}:${JSON.stringify(query.getForKey.key)}`
2612
- );
2613
- }
2614
- actorOutput = existingActor;
2615
- } else if ("getOrCreateForKey" in query) {
2616
- const getOrCreateOutput = await managerDriver.getOrCreateWithKey({
2617
- c,
2618
- name: query.getOrCreateForKey.name,
2619
- key: query.getOrCreateForKey.key,
2620
- input: query.getOrCreateForKey.input,
2621
- region: query.getOrCreateForKey.region
2622
- });
2623
- actorOutput = {
2624
- actorId: getOrCreateOutput.actorId
2625
- };
2626
- } else if ("create" in query) {
2627
- const createOutput = await managerDriver.createActor({
2628
- c,
2629
- name: query.create.name,
2630
- key: query.create.key,
2631
- input: query.create.input,
2632
- region: query.create.region
2633
- });
2634
- actorOutput = {
2635
- actorId: createOutput.actorId
2636
- };
2637
- } else {
2638
- throw new (0, _chunkKSRXX3Z4cjs.InvalidRequest)("Invalid query format");
2639
- }
2640
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "actor query result", actorId: actorOutput.actorId });
2641
- return { actorId: actorOutput.actorId };
2642
- }
2643
-
2644
- // src/client/actor-handle.ts
2645
-
2646
-
2647
-
2648
- // src/client/raw-utils.ts
2649
-
2650
- async function rawHttpFetch(driver, actorQuery, params, input, init) {
2651
- let path;
2652
- let mergedInit = init || {};
2653
- if (typeof input === "string") {
2654
- path = input;
2655
- } else if (input instanceof URL) {
2656
- path = input.pathname + input.search;
2657
- } else if (input instanceof Request) {
2658
- const url = new URL(input.url);
2659
- path = url.pathname + url.search;
2660
- const requestHeaders = new Headers(input.headers);
2661
- const initHeaders = new Headers((init == null ? void 0 : init.headers) || {});
2662
- const mergedHeaders = new Headers(requestHeaders);
2663
- for (const [key, value] of initHeaders) {
2664
- mergedHeaders.set(key, value);
2665
- }
2666
- mergedInit = {
2667
- method: input.method,
2668
- body: input.body,
2669
- mode: input.mode,
2670
- credentials: input.credentials,
2671
- redirect: input.redirect,
2672
- referrer: input.referrer,
2673
- referrerPolicy: input.referrerPolicy,
2674
- integrity: input.integrity,
2675
- keepalive: input.keepalive,
2676
- signal: input.signal,
2677
- ...mergedInit,
2678
- // init overrides Request properties
2679
- headers: mergedHeaders
2680
- // headers must be set after spread to ensure proper merge
2681
- };
2682
- if (mergedInit.body) {
2683
- mergedInit.duplex = "half";
2684
- }
2685
- } else {
2686
- throw new TypeError("Invalid input type for fetch");
2687
- }
2688
- try {
2689
- const { actorId } = await queryActor(void 0, actorQuery, driver);
2690
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "found actor for raw http", actorId });
2691
- _invariant2.default.call(void 0, actorId, "Missing actor ID");
2692
- const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
2693
- const url = new URL(`http://actor/raw/http/${normalizedPath}`);
2694
- const proxyRequestHeaders = new Headers(mergedInit.headers);
2695
- if (params) {
2696
- proxyRequestHeaders.set(_chunkHHFKKVLRcjs.HEADER_CONN_PARAMS, JSON.stringify(params));
2697
- }
2698
- const proxyRequest = new Request(url, {
2699
- ...mergedInit,
2700
- headers: proxyRequestHeaders
2701
- });
2702
- return driver.sendRequest(actorId, proxyRequest);
2703
- } catch (err) {
2704
- const { group, code, message, metadata } = _chunk7L65NNWPcjs.deconstructError.call(void 0,
2705
- err,
2706
- _chunkZTH3KYFHcjs.logger.call(void 0, ),
2707
- {},
2708
- true
2709
- );
2710
- throw new ActorError(group, code, message, metadata);
2711
- }
2712
- }
2713
- async function rawWebSocket(driver, actorQuery, params, path, protocols) {
2714
- const encoding = "bare";
2715
- const { actorId } = await queryActor(void 0, actorQuery, driver);
2716
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "found actor for action", actorId });
2717
- _invariant2.default.call(void 0, actorId, "Missing actor ID");
2718
- let pathPortion = "";
2719
- let queryPortion = "";
2720
- if (path) {
2721
- const queryIndex = path.indexOf("?");
2722
- if (queryIndex !== -1) {
2723
- pathPortion = path.substring(0, queryIndex);
2724
- queryPortion = path.substring(queryIndex);
2725
- } else {
2726
- pathPortion = path;
2727
- }
2728
- if (pathPortion.startsWith("/")) {
2729
- pathPortion = pathPortion.slice(1);
2730
- }
2731
- }
2732
- const fullPath = `${_chunkHHFKKVLRcjs.PATH_RAW_WEBSOCKET_PREFIX}${pathPortion}${queryPortion}`;
2733
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
2734
- msg: "opening websocket",
2735
- actorId,
2736
- encoding,
2737
- path: fullPath
2738
- });
2739
- const ws = await driver.openWebSocket(fullPath, actorId, encoding, params);
2740
- return ws;
2741
- }
2742
-
2743
- // src/client/utils.ts
2744
-
2745
-
2746
- function messageLength(message) {
2747
- if (message instanceof Blob) {
2748
- return message.size;
2749
- }
2750
- if (message instanceof ArrayBuffer) {
2751
- return message.byteLength;
2752
- }
2753
- if (message instanceof Uint8Array) {
2754
- return message.byteLength;
2755
- }
2756
- if (typeof message === "string") {
2757
- return message.length;
2758
- }
2759
- _chunk7L65NNWPcjs.assertUnreachable.call(void 0, message);
2760
- }
2761
- async function sendHttpRequest(opts) {
2762
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
2763
- msg: "sending http request",
2764
- url: opts.url,
2765
- encoding: opts.encoding
2766
- });
2767
- let contentType;
2768
- let bodyData;
2769
- if (opts.method === "POST" || opts.method === "PUT") {
2770
- _invariant2.default.call(void 0, opts.body !== void 0, "missing body");
2771
- contentType = _chunkHHFKKVLRcjs.contentTypeForEncoding.call(void 0, opts.encoding);
2772
- bodyData = _chunkHHFKKVLRcjs.serializeWithEncoding.call(void 0,
2773
- opts.encoding,
2774
- opts.body,
2775
- opts.requestVersionedDataHandler
2776
- );
2777
- }
2778
- let response;
2779
- try {
2780
- response = await (_nullishCoalesce(opts.customFetch, () => ( fetch)))(
2781
- new Request(opts.url, {
2782
- method: opts.method,
2783
- headers: {
2784
- ...opts.headers,
2785
- ...contentType ? {
2786
- "Content-Type": contentType
2787
- } : {},
2788
- "User-Agent": _chunk7L65NNWPcjs.httpUserAgent.call(void 0, )
2789
- },
2790
- body: bodyData,
2791
- credentials: "include",
2792
- signal: opts.signal
2793
- })
2794
- );
2795
- } catch (error) {
2796
- throw new HttpRequestError(`Request failed: ${error}`, {
2797
- cause: error
2798
- });
2799
- }
2800
- if (!response.ok) {
2801
- const bufferResponse = await response.arrayBuffer();
2802
- let responseData;
2803
- try {
2804
- responseData = _chunkHHFKKVLRcjs.deserializeWithEncoding.call(void 0,
2805
- opts.encoding,
2806
- new Uint8Array(bufferResponse),
2807
- _chunkVFB23BYZcjs.HTTP_RESPONSE_ERROR_VERSIONED
2808
- );
2809
- } catch (error) {
2810
- const textResponse = new TextDecoder("utf-8", {
2811
- fatal: false
2812
- }).decode(bufferResponse);
2813
- const rayId = response.headers.get("x-rivet-ray-id");
2814
- if (rayId) {
2815
- throw new HttpRequestError(
2816
- `${response.statusText} (${response.status}) (Ray ID: ${rayId}):
2817
- ${textResponse}`
2818
- );
2819
- } else {
2820
- throw new HttpRequestError(
2821
- `${response.statusText} (${response.status}):
2822
- ${textResponse}`
2823
- );
2824
- }
2825
- }
2826
- let decodedMetadata;
2827
- if (responseData.metadata && _chunkHHFKKVLRcjs.encodingIsBinary.call(void 0, opts.encoding)) {
2828
- decodedMetadata = cbor3.decode(
2829
- new Uint8Array(responseData.metadata)
2830
- );
2831
- }
2832
- throw new ActorError(
2833
- responseData.group,
2834
- responseData.code,
2835
- responseData.message,
2836
- decodedMetadata
2837
- );
2838
- }
2839
- if (opts.skipParseResponse) {
2840
- return void 0;
2841
- }
2842
- try {
2843
- const buffer = new Uint8Array(await response.arrayBuffer());
2844
- return _chunkHHFKKVLRcjs.deserializeWithEncoding.call(void 0,
2845
- opts.encoding,
2846
- buffer,
2847
- opts.responseVersionedDataHandler
2848
- );
2849
- } catch (error) {
2850
- throw new HttpRequestError(`Failed to parse response: ${error}`, {
2851
- cause: error
2852
- });
2853
- }
2854
- }
2855
-
2856
- // src/client/actor-handle.ts
2857
- var ActorHandleRaw = class {
2858
- #client;
2859
- #driver;
2860
- #encoding;
2861
- #actorQuery;
2862
- #params;
2863
- /**
2864
- * Do not call this directly.
2865
- *
2866
- * Creates an instance of ActorHandleRaw.
2867
- *
2868
- * @protected
2869
- */
2870
- constructor(client, driver, params, encoding, actorQuery) {
2871
- this.#client = client;
2872
- this.#driver = driver;
2873
- this.#encoding = encoding;
2874
- this.#actorQuery = actorQuery;
2875
- this.#params = params;
2876
- }
2877
- /**
2878
- * Call a raw action. This method sends an HTTP request to invoke the named action.
2879
- *
2880
- * @see {@link ActorHandle}
2881
- * @template Args - The type of arguments to pass to the action function.
2882
- * @template Response - The type of the response returned by the action function.
2883
- */
2884
- async action(opts) {
2885
- try {
2886
- const { actorId } = await queryActor(
2887
- void 0,
2888
- this.#actorQuery,
2889
- this.#driver
2890
- );
2891
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "found actor for action", actorId });
2892
- _invariant2.default.call(void 0, actorId, "Missing actor ID");
2893
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
2894
- msg: "handling action",
2895
- name: opts.name,
2896
- encoding: this.#encoding
2897
- });
2898
- const responseData = await sendHttpRequest({
2899
- url: `http://actor/action/${encodeURIComponent(opts.name)}`,
2900
- method: "POST",
2901
- headers: {
2902
- [_chunkHHFKKVLRcjs.HEADER_ENCODING]: this.#encoding,
2903
- ...this.#params !== void 0 ? { [_chunkHHFKKVLRcjs.HEADER_CONN_PARAMS]: JSON.stringify(this.#params) } : {}
2904
- },
2905
- body: {
2906
- args: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor4.encode(opts.args))
2907
- },
2908
- encoding: this.#encoding,
2909
- customFetch: this.#driver.sendRequest.bind(
2910
- this.#driver,
2911
- actorId
2912
- ),
2913
- signal: opts == null ? void 0 : opts.signal,
2914
- requestVersionedDataHandler: _chunkVFB23BYZcjs.HTTP_ACTION_REQUEST_VERSIONED,
2915
- responseVersionedDataHandler: _chunkVFB23BYZcjs.HTTP_ACTION_RESPONSE_VERSIONED
2916
- });
2917
- return cbor4.decode(new Uint8Array(responseData.output));
2918
- } catch (err) {
2919
- const { group, code, message, metadata } = _chunk7L65NNWPcjs.deconstructError.call(void 0,
2920
- err,
2921
- _chunkZTH3KYFHcjs.logger.call(void 0, ),
2922
- {},
2923
- true
2924
- );
2925
- throw new ActorError(group, code, message, metadata);
2926
- }
2927
- }
2928
- /**
2929
- * Establishes a persistent connection to the actor.
2930
- *
2931
- * @template AD The actor class that this connection is for.
2932
- * @returns {ActorConn<AD>} A connection to the actor.
2933
- */
2934
- connect() {
2935
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
2936
- msg: "establishing connection from handle",
2937
- query: this.#actorQuery
2938
- });
2939
- const conn = new ActorConnRaw(
2940
- this.#client,
2941
- this.#driver,
2942
- this.#params,
2943
- this.#encoding,
2944
- this.#actorQuery
2945
- );
2946
- return this.#client[CREATE_ACTOR_CONN_PROXY](
2947
- conn
2948
- );
2949
- }
2950
- /**
2951
- * Makes a raw HTTP request to the actor.
2952
- *
2953
- * @param input - The URL, path, or Request object
2954
- * @param init - Standard fetch RequestInit options
2955
- * @returns Promise<Response> - The raw HTTP response
2956
- */
2957
- async fetch(input, init) {
2958
- return rawHttpFetch(
2959
- this.#driver,
2960
- this.#actorQuery,
2961
- this.#params,
2962
- input,
2963
- init
2964
- );
2965
- }
2966
- /**
2967
- * Creates a raw WebSocket connection to the actor.
2968
- *
2969
- * @param path - The path for the WebSocket connection (e.g., "stream")
2970
- * @param protocols - Optional WebSocket subprotocols
2971
- * @returns WebSocket - A raw WebSocket connection
2972
- */
2973
- async websocket(path, protocols) {
2974
- return rawWebSocket(
2975
- this.#driver,
2976
- this.#actorQuery,
2977
- this.#params,
2978
- path,
2979
- protocols
2980
- );
2981
- }
2982
- /**
2983
- * Resolves the actor to get its unique actor ID
2984
- *
2985
- * @returns {Promise<string>} - A promise that resolves to the actor's ID
2986
- */
2987
- async resolve({ signal } = {}) {
2988
- if ("getForKey" in this.#actorQuery || "getOrCreateForKey" in this.#actorQuery) {
2989
- let name;
2990
- if ("getForKey" in this.#actorQuery) {
2991
- name = this.#actorQuery.getForKey.name;
2992
- } else if ("getOrCreateForKey" in this.#actorQuery) {
2993
- name = this.#actorQuery.getOrCreateForKey.name;
2994
- } else {
2995
- _chunkHHFKKVLRcjs.assertUnreachable.call(void 0, this.#actorQuery);
2996
- }
2997
- const { actorId } = await queryActor(
2998
- void 0,
2999
- this.#actorQuery,
3000
- this.#driver
3001
- );
3002
- this.#actorQuery = { getForId: { actorId, name } };
3003
- return actorId;
3004
- } else if ("getForId" in this.#actorQuery) {
3005
- return this.#actorQuery.getForId.actorId;
3006
- } else if ("create" in this.#actorQuery) {
3007
- _invariant2.default.call(void 0, false, "actorQuery cannot be create");
3008
- } else {
3009
- _chunkHHFKKVLRcjs.assertUnreachable.call(void 0, this.#actorQuery);
3010
- }
3011
- }
3012
- };
3013
-
3014
- // src/client/client.ts
3015
- var ACTOR_CONNS_SYMBOL = Symbol("actorConns");
3016
- var CREATE_ACTOR_CONN_PROXY = Symbol("createActorConnProxy");
3017
- var TRANSPORT_SYMBOL = Symbol("transport");
3018
- var ClientRaw = (_class4 = class {
3019
- #disposed = false;
3020
- __init4() {this[ACTOR_CONNS_SYMBOL] = /* @__PURE__ */ new Set()}
3021
- #driver;
3022
- #encodingKind;
3023
-
3024
- /**
3025
- * Creates an instance of Client.
3026
- */
3027
- constructor(driver, config) {;_class4.prototype.__init4.call(this);
3028
- this.#driver = driver;
3029
- this.#encodingKind = _nullishCoalesce(config.encoding, () => ( "bare"));
3030
- this[TRANSPORT_SYMBOL] = _nullishCoalesce(config.transport, () => ( "websocket"));
3031
- }
3032
- /**
3033
- * Gets a stateless handle to a actor by its ID.
3034
- *
3035
- * @template AD The actor class that this handle is for.
3036
- * @param {string} name - The name of the actor.
3037
- * @param {string} actorId - The ID of the actor.
3038
- * @param {GetWithIdOptions} [opts] - Options for getting the actor.
3039
- * @returns {ActorHandle<AD>} - A handle to the actor.
3040
- */
3041
- getForId(name, actorId, opts) {
3042
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3043
- msg: "get handle to actor with id",
3044
- name,
3045
- actorId,
3046
- params: opts == null ? void 0 : opts.params
3047
- });
3048
- const actorQuery = {
3049
- getForId: {
3050
- name,
3051
- actorId
3052
- }
3053
- };
3054
- const handle = this.#createHandle(opts == null ? void 0 : opts.params, actorQuery);
3055
- return createActorProxy(handle);
3056
- }
3057
- /**
3058
- * Gets a stateless handle to a actor by its key, but does not create the actor if it doesn't exist.
3059
- *
3060
- * @template AD The actor class that this handle is for.
3061
- * @param {string} name - The name of the actor.
3062
- * @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.
3063
- * @param {GetWithIdOptions} [opts] - Options for getting the actor.
3064
- * @returns {ActorHandle<AD>} - A handle to the actor.
3065
- */
3066
- get(name, key, opts) {
3067
- const keyArray = typeof key === "string" ? [key] : key || [];
3068
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3069
- msg: "get handle to actor",
3070
- name,
3071
- key: keyArray,
3072
- parameters: opts == null ? void 0 : opts.params
3073
- });
3074
- const actorQuery = {
3075
- getForKey: {
3076
- name,
3077
- key: keyArray
3078
- }
3079
- };
3080
- const handle = this.#createHandle(opts == null ? void 0 : opts.params, actorQuery);
3081
- return createActorProxy(handle);
3082
- }
3083
- /**
3084
- * Gets a stateless handle to a actor by its key, creating it if necessary.
3085
- *
3086
- * @template AD The actor class that this handle is for.
3087
- * @param {string} name - The name of the actor.
3088
- * @param {string | string[]} [key=[]] - The key to identify the actor. Can be a single string or an array of strings.
3089
- * @param {GetOptions} [opts] - Options for getting the actor.
3090
- * @returns {ActorHandle<AD>} - A handle to the actor.
3091
- */
3092
- getOrCreate(name, key, opts) {
3093
- const keyArray = typeof key === "string" ? [key] : key || [];
3094
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3095
- msg: "get or create handle to actor",
3096
- name,
3097
- key: keyArray,
3098
- parameters: opts == null ? void 0 : opts.params,
3099
- createInRegion: opts == null ? void 0 : opts.createInRegion
3100
- });
3101
- const actorQuery = {
3102
- getOrCreateForKey: {
3103
- name,
3104
- key: keyArray,
3105
- input: opts == null ? void 0 : opts.createWithInput,
3106
- region: opts == null ? void 0 : opts.createInRegion
3107
- }
3108
- };
3109
- const handle = this.#createHandle(opts == null ? void 0 : opts.params, actorQuery);
3110
- return createActorProxy(handle);
3111
- }
3112
- /**
3113
- * Creates a new actor with the provided key and returns a stateless handle to it.
3114
- * Resolves the actor ID and returns a handle with getForId query.
3115
- *
3116
- * @template AD The actor class that this handle is for.
3117
- * @param {string} name - The name of the actor.
3118
- * @param {string | string[]} key - The key to identify the actor. Can be a single string or an array of strings.
3119
- * @param {CreateOptions} [opts] - Options for creating the actor (excluding name and key).
3120
- * @returns {Promise<ActorHandle<AD>>} - A promise that resolves to a handle to the actor.
3121
- */
3122
- async create(name, key, opts) {
3123
- const keyArray = typeof key === "string" ? [key] : key || [];
3124
- const createQuery = {
3125
- create: {
3126
- ...opts,
3127
- // Do these last to override `opts`
3128
- name,
3129
- key: keyArray
3130
- }
3131
- };
3132
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3133
- msg: "create actor handle",
3134
- name,
3135
- key: keyArray,
3136
- parameters: opts == null ? void 0 : opts.params,
3137
- create: createQuery.create
3138
- });
3139
- const { actorId } = await queryActor(
3140
- void 0,
3141
- createQuery,
3142
- this.#driver
3143
- );
3144
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3145
- msg: "created actor with ID",
3146
- name,
3147
- key: keyArray,
3148
- actorId
3149
- });
3150
- const getForIdQuery = {
3151
- getForId: {
3152
- name,
3153
- actorId
3154
- }
3155
- };
3156
- const handle = this.#createHandle(opts == null ? void 0 : opts.params, getForIdQuery);
3157
- const proxy = createActorProxy(handle);
3158
- return proxy;
3159
- }
3160
- #createHandle(params, actorQuery) {
3161
- return new ActorHandleRaw(
3162
- this,
3163
- this.#driver,
3164
- params,
3165
- this.#encodingKind,
3166
- actorQuery
3167
- );
3168
- }
3169
- [CREATE_ACTOR_CONN_PROXY](conn) {
3170
- this[ACTOR_CONNS_SYMBOL].add(conn);
3171
- conn[CONNECT_SYMBOL]();
3172
- return createActorProxy(conn);
3173
- }
3174
- /**
3175
- * Disconnects from all actors.
3176
- *
3177
- * @returns {Promise<void>} A promise that resolves when all connections are closed.
3178
- */
3179
- async dispose() {
3180
- if (this.#disposed) {
3181
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({ msg: "client already disconnected" });
3182
- return;
3183
- }
3184
- this.#disposed = true;
3185
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "disposing client" });
3186
- const disposePromises = [];
3187
- for (const conn of this[ACTOR_CONNS_SYMBOL].values()) {
3188
- disposePromises.push(conn.dispose());
3189
- }
3190
- await Promise.all(disposePromises);
3191
- }
3192
- }, _class4);
3193
- function createClientWithDriver(driver, config) {
3194
- const client = new ClientRaw(driver, config);
3195
- return new Proxy(client, {
3196
- get: (target, prop, receiver) => {
3197
- if (typeof prop === "symbol" || prop in target) {
3198
- const value = Reflect.get(target, prop, receiver);
3199
- if (typeof value === "function") {
3200
- return value.bind(target);
3201
- }
3202
- return value;
3203
- }
3204
- if (typeof prop === "string") {
3205
- return {
3206
- // Handle methods (stateless action)
3207
- get: (key, opts) => {
3208
- return target.get(prop, key, opts);
3209
- },
3210
- getOrCreate: (key, opts) => {
3211
- return target.getOrCreate(prop, key, opts);
3212
- },
3213
- getForId: (actorId, opts) => {
3214
- return target.getForId(prop, actorId, opts);
3215
- },
3216
- create: async (key, opts = {}) => {
3217
- return await target.create(prop, key, opts);
3218
- }
3219
- };
3220
- }
3221
- return void 0;
3222
- }
3223
- });
3224
- }
3225
- function createActorProxy(handle) {
3226
- const methodCache = /* @__PURE__ */ new Map();
3227
- return new Proxy(handle, {
3228
- get(target, prop, receiver) {
3229
- if (typeof prop === "symbol") {
3230
- return Reflect.get(target, prop, receiver);
3231
- }
3232
- if (prop === "constructor" || prop in target) {
3233
- const value = Reflect.get(target, prop, target);
3234
- if (typeof value === "function") {
3235
- return value.bind(target);
3236
- }
3237
- return value;
3238
- }
3239
- if (typeof prop === "string") {
3240
- if (prop === "then") return void 0;
3241
- let method = methodCache.get(prop);
3242
- if (!method) {
3243
- method = (...args) => target.action({ name: prop, args });
3244
- methodCache.set(prop, method);
3245
- }
3246
- return method;
3247
- }
3248
- },
3249
- // Support for 'in' operator
3250
- has(target, prop) {
3251
- if (typeof prop === "string") {
3252
- return true;
3253
- }
3254
- return Reflect.has(target, prop);
3255
- },
3256
- // Support instanceof checks
3257
- getPrototypeOf(target) {
3258
- return Reflect.getPrototypeOf(target);
3259
- },
3260
- // Prevent property enumeration of non-existent action methods
3261
- ownKeys(target) {
3262
- return Reflect.ownKeys(target);
3263
- },
3264
- // Support proper property descriptors
3265
- getOwnPropertyDescriptor(target, prop) {
3266
- const targetDescriptor = Reflect.getOwnPropertyDescriptor(
3267
- target,
3268
- prop
3269
- );
3270
- if (targetDescriptor) {
3271
- return targetDescriptor;
3272
- }
3273
- if (typeof prop === "string") {
3274
- return {
3275
- configurable: true,
3276
- enumerable: false,
3277
- writable: false,
3278
- value: (...args) => target.action({ name: prop, args })
3279
- };
3280
- }
3281
- return void 0;
3282
- }
3283
- });
3284
- }
3285
-
3286
- // src/client/actor-conn.ts
3287
- var CONNECT_SYMBOL = Symbol("connect");
3288
- var ActorConnRaw = class {
3289
- #disposed = false;
3290
- /* Will be aborted on dispose. */
3291
- #abortController = new AbortController();
3292
- /** If attempting to connect. Helpful for knowing if in a retry loop when reconnecting. */
3293
- #connecting = false;
3294
- // Connection info, used for reconnection and HTTP requests
3295
- #actorId;
3296
- #connectionId;
3297
- #connectionToken;
3298
- #transport;
3299
- #messageQueue = [];
3300
- #actionsInFlight = /* @__PURE__ */ new Map();
3301
- // biome-ignore lint/suspicious/noExplicitAny: Unknown subscription type
3302
- #eventSubscriptions = /* @__PURE__ */ new Map();
3303
- #errorHandlers = /* @__PURE__ */ new Set();
3304
- #actionIdCounter = 0;
3305
- /**
3306
- * Interval that keeps the NodeJS process alive if this is the only thing running.
3307
- *
3308
- * See ttps://github.com/nodejs/node/issues/22088
3309
- */
3310
- #keepNodeAliveInterval;
3311
- /** Promise used to indicate the socket has connected successfully. This will be rejected if the connection fails. */
3312
- #onOpenPromise;
3313
- #client;
3314
- #driver;
3315
- #params;
3316
- #encoding;
3317
- #actorQuery;
3318
- // TODO: ws message queue
3319
- /**
3320
- * Do not call this directly.
3321
- *
3322
- * Creates an instance of ActorConnRaw.
3323
- *
3324
- * @protected
3325
- */
3326
- constructor(client, driver, params, encoding, actorQuery) {
3327
- this.#client = client;
3328
- this.#driver = driver;
3329
- this.#params = params;
3330
- this.#encoding = encoding;
3331
- this.#actorQuery = actorQuery;
3332
- this.#keepNodeAliveInterval = setInterval(() => 6e4);
3333
- }
3334
- /**
3335
- * Call a raw action connection. See {@link ActorConn} for type-safe action calls.
3336
- *
3337
- * @see {@link ActorConn}
3338
- * @template Args - The type of arguments to pass to the action function.
3339
- * @template Response - The type of the response returned by the action function.
3340
- * @param {string} name - The name of the action function to call.
3341
- * @param {...Args} args - The arguments to pass to the action function.
3342
- * @returns {Promise<Response>} - A promise that resolves to the response of the action function.
3343
- */
3344
- async action(opts) {
3345
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "action", name: opts.name, args: opts.args });
3346
- const actionId = this.#actionIdCounter;
3347
- this.#actionIdCounter += 1;
3348
- const { promise, resolve, reject } = _chunk7L65NNWPcjs.promiseWithResolvers.call(void 0, );
3349
- this.#actionsInFlight.set(actionId, {
3350
- name: opts.name,
3351
- resolve,
3352
- reject
3353
- });
3354
- this.#sendMessage({
3355
- body: {
3356
- tag: "ActionRequest",
3357
- val: {
3358
- id: BigInt(actionId),
3359
- name: opts.name,
3360
- args: _chunk7L65NNWPcjs.bufferToArrayBuffer.call(void 0, cbor5.encode(opts.args))
3361
- }
3362
- }
3363
- });
3364
- const { id: responseId, output } = await promise;
3365
- if (responseId !== BigInt(actionId))
3366
- throw new Error(
3367
- `Request ID ${actionId} does not match response ID ${responseId}`
3368
- );
3369
- return cbor5.decode(new Uint8Array(output));
3370
- }
3371
- /**
3372
- * Do not call this directly.
3373
- enc
3374
- * Establishes a connection to the server using the specified endpoint & encoding & driver.
3375
- *
3376
- * @protected
3377
- */
3378
- [CONNECT_SYMBOL]() {
3379
- this.#connectWithRetry();
3380
- }
3381
- async #connectWithRetry() {
3382
- this.#connecting = true;
3383
- try {
3384
- await _pretry2.default.call(void 0, this.#connectAndWait.bind(this), {
3385
- forever: true,
3386
- minTimeout: 250,
3387
- maxTimeout: 3e4,
3388
- onFailedAttempt: (error) => {
3389
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({
3390
- msg: "failed to reconnect",
3391
- attempt: error.attemptNumber,
3392
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
3393
- });
3394
- },
3395
- // Cancel retry if aborted
3396
- signal: this.#abortController.signal
3397
- });
3398
- } catch (err) {
3399
- if (err.name === "AbortError") {
3400
- _chunkZTH3KYFHcjs.logger.call(void 0, ).info({ msg: "connection retry aborted" });
3401
- return;
3402
- } else {
3403
- throw err;
3404
- }
3405
- }
3406
- this.#connecting = false;
3407
- }
3408
- async #connectAndWait() {
3409
- try {
3410
- if (this.#onOpenPromise)
3411
- throw new Error("#onOpenPromise already defined");
3412
- this.#onOpenPromise = _chunk7L65NNWPcjs.promiseWithResolvers.call(void 0, );
3413
- if (this.#client[TRANSPORT_SYMBOL] === "websocket") {
3414
- await this.#connectWebSocket();
3415
- } else if (this.#client[TRANSPORT_SYMBOL] === "sse") {
3416
- await this.#connectSse();
3417
- } else {
3418
- _chunk7L65NNWPcjs.assertUnreachable.call(void 0, this.#client[TRANSPORT_SYMBOL]);
3419
- }
3420
- await this.#onOpenPromise.promise;
3421
- } finally {
3422
- this.#onOpenPromise = void 0;
3423
- }
3424
- }
3425
- async #connectWebSocket() {
3426
- const { actorId } = await queryActor(
3427
- void 0,
3428
- this.#actorQuery,
3429
- this.#driver
3430
- );
3431
- const isReconnection = this.#connectionId && this.#connectionToken;
3432
- if (isReconnection) {
3433
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3434
- msg: "attempting websocket reconnection",
3435
- connectionId: this.#connectionId
3436
- });
3437
- }
3438
- const ws = await this.#driver.openWebSocket(
3439
- _chunkHHFKKVLRcjs.PATH_CONNECT_WEBSOCKET,
3440
- actorId,
3441
- this.#encoding,
3442
- this.#params,
3443
- // Pass connection ID and token for reconnection if available
3444
- isReconnection ? this.#connectionId : void 0,
3445
- isReconnection ? this.#connectionToken : void 0
3446
- );
3447
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3448
- msg: "transport set to new websocket",
3449
- connectionId: this.#connectionId,
3450
- readyState: ws.readyState,
3451
- messageQueueLength: this.#messageQueue.length
3452
- });
3453
- this.#transport = { websocket: ws };
3454
- ws.addEventListener("open", () => {
3455
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3456
- msg: "client websocket open",
3457
- connectionId: this.#connectionId
3458
- });
3459
- });
3460
- ws.addEventListener("message", async (ev) => {
3461
- try {
3462
- await this.#handleOnMessage(ev.data);
3463
- } catch (err) {
3464
- _chunkZTH3KYFHcjs.logger.call(void 0, ).error({
3465
- msg: "error in websocket message handler",
3466
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, err)
3467
- });
3468
- }
3469
- });
3470
- ws.addEventListener("close", (ev) => {
3471
- try {
3472
- this.#handleOnClose(ev);
3473
- } catch (err) {
3474
- _chunkZTH3KYFHcjs.logger.call(void 0, ).error({
3475
- msg: "error in websocket close handler",
3476
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, err)
3477
- });
3478
- }
3479
- });
3480
- ws.addEventListener("error", (_ev) => {
3481
- try {
3482
- this.#handleOnError();
3483
- } catch (err) {
3484
- _chunkZTH3KYFHcjs.logger.call(void 0, ).error({
3485
- msg: "error in websocket error handler",
3486
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, err)
3487
- });
3488
- }
3489
- });
3490
- }
3491
- async #connectSse() {
3492
- const EventSource = await importEventSource();
3493
- const { actorId } = await queryActor(
3494
- void 0,
3495
- this.#actorQuery,
3496
- this.#driver
3497
- );
3498
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "found actor for sse connection", actorId });
3499
- _invariant2.default.call(void 0, actorId, "Missing actor ID");
3500
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3501
- msg: "opening sse connection",
3502
- actorId,
3503
- encoding: this.#encoding
3504
- });
3505
- const isReconnection = this.#connectionId && this.#connectionToken;
3506
- const eventSource = new EventSource("http://actor/connect/sse", {
3507
- fetch: (input, init) => {
3508
- return this.#driver.sendRequest(
3509
- actorId,
3510
- new Request(input, {
3511
- ...init,
3512
- headers: {
3513
- ...init == null ? void 0 : init.headers,
3514
- "User-Agent": _chunk7L65NNWPcjs.httpUserAgent.call(void 0, ),
3515
- [_chunkHHFKKVLRcjs.HEADER_ENCODING]: this.#encoding,
3516
- ...this.#params !== void 0 ? {
3517
- [_chunkHHFKKVLRcjs.HEADER_CONN_PARAMS]: JSON.stringify(
3518
- this.#params
3519
- )
3520
- } : {},
3521
- ...isReconnection ? {
3522
- [_chunkHHFKKVLRcjs.HEADER_CONN_ID]: this.#connectionId,
3523
- [_chunkHHFKKVLRcjs.HEADER_CONN_TOKEN]: this.#connectionToken
3524
- } : {}
3525
- }
3526
- })
3527
- );
3528
- }
3529
- });
3530
- this.#transport = { sse: eventSource };
3531
- eventSource.addEventListener("message", (ev) => {
3532
- if (ev.type === "ping") return;
3533
- this.#handleOnMessage(ev.data);
3534
- });
3535
- eventSource.addEventListener("error", (ev) => {
3536
- this.#handleOnError();
3537
- });
3538
- }
3539
- /** Called by the onopen event from drivers. */
3540
- #handleOnOpen() {
3541
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3542
- msg: "socket open",
3543
- messageQueueLength: this.#messageQueue.length,
3544
- connectionId: this.#connectionId
3545
- });
3546
- if (this.#onOpenPromise) {
3547
- this.#onOpenPromise.resolve(void 0);
3548
- } else {
3549
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({ msg: "#onOpenPromise is undefined" });
3550
- }
3551
- for (const eventName of this.#eventSubscriptions.keys()) {
3552
- this.#sendSubscription(eventName, true);
3553
- }
3554
- const queue = this.#messageQueue;
3555
- this.#messageQueue = [];
3556
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3557
- msg: "flushing message queue",
3558
- queueLength: queue.length
3559
- });
3560
- for (const msg of queue) {
3561
- this.#sendMessage(msg);
3562
- }
3563
- }
3564
- /** Called by the onmessage event from drivers. */
3565
- async #handleOnMessage(data) {
3566
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace({
3567
- msg: "received message",
3568
- dataType: typeof data,
3569
- isBlob: data instanceof Blob,
3570
- isArrayBuffer: data instanceof ArrayBuffer
3571
- });
3572
- const response = await this.#parseMessage(data);
3573
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace(
3574
- _chunk7L65NNWPcjs.getEnvUniversal.call(void 0, "_RIVETKIT_LOG_MESSAGE") ? {
3575
- msg: "parsed message",
3576
- message: _chunkHHFKKVLRcjs.jsonStringifyCompat.call(void 0, response).substring(0, 100) + "..."
3577
- } : { msg: "parsed message" }
3578
- );
3579
- if (response.body.tag === "Init") {
3580
- this.#actorId = response.body.val.actorId;
3581
- this.#connectionId = response.body.val.connectionId;
3582
- this.#connectionToken = response.body.val.connectionToken;
3583
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace({
3584
- msg: "received init message",
3585
- actorId: this.#actorId,
3586
- connectionId: this.#connectionId
3587
- });
3588
- this.#handleOnOpen();
3589
- } else if (response.body.tag === "Error") {
3590
- const { group, code, message, metadata, actionId } = response.body.val;
3591
- if (actionId) {
3592
- const inFlight = this.#takeActionInFlight(Number(actionId));
3593
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({
3594
- msg: "action error",
3595
- actionId,
3596
- actionName: inFlight == null ? void 0 : inFlight.name,
3597
- group,
3598
- code,
3599
- message,
3600
- metadata
3601
- });
3602
- inFlight.reject(
3603
- new ActorError(group, code, message, metadata)
3604
- );
3605
- } else {
3606
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({
3607
- msg: "connection error",
3608
- group,
3609
- code,
3610
- message,
3611
- metadata
3612
- });
3613
- const actorError = new ActorError(
3614
- group,
3615
- code,
3616
- message,
3617
- metadata
3618
- );
3619
- if (this.#onOpenPromise) {
3620
- this.#onOpenPromise.reject(actorError);
3621
- }
3622
- for (const [id, inFlight] of this.#actionsInFlight.entries()) {
3623
- inFlight.reject(actorError);
3624
- this.#actionsInFlight.delete(id);
3625
- }
3626
- this.#dispatchActorError(actorError);
3627
- }
3628
- } else if (response.body.tag === "ActionResponse") {
3629
- const { id: actionId } = response.body.val;
3630
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace({
3631
- msg: "received action response",
3632
- actionId
3633
- });
3634
- const inFlight = this.#takeActionInFlight(Number(actionId));
3635
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace({
3636
- msg: "resolving action promise",
3637
- actionId,
3638
- actionName: inFlight == null ? void 0 : inFlight.name
3639
- });
3640
- inFlight.resolve(response.body.val);
3641
- } else if (response.body.tag === "Event") {
3642
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace({
3643
- msg: "received event",
3644
- name: response.body.val.name
3645
- });
3646
- this.#dispatchEvent(response.body.val);
3647
- } else {
3648
- _chunk7L65NNWPcjs.assertUnreachable.call(void 0, response.body);
3649
- }
3650
- }
3651
- /** Called by the onclose event from drivers. */
3652
- #handleOnClose(event) {
3653
- const closeEvent = event;
3654
- const wasClean = closeEvent.wasClean;
3655
- if (this.#onOpenPromise) {
3656
- this.#onOpenPromise.reject(
3657
- new Error(
3658
- `websocket closed with code ${closeEvent.code}: ${closeEvent.reason}`
3659
- )
3660
- );
3661
- }
3662
- _chunkZTH3KYFHcjs.logger.call(void 0, ).info({
3663
- msg: "socket closed",
3664
- code: closeEvent.code,
3665
- reason: closeEvent.reason,
3666
- wasClean,
3667
- connectionId: this.#connectionId,
3668
- messageQueueLength: this.#messageQueue.length,
3669
- actionsInFlight: this.#actionsInFlight.size
3670
- });
3671
- if (this.#actionsInFlight.size > 0) {
3672
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3673
- msg: "rejecting in-flight actions after disconnect",
3674
- count: this.#actionsInFlight.size,
3675
- connectionId: this.#connectionId,
3676
- wasClean
3677
- });
3678
- const disconnectError = new Error(
3679
- wasClean ? "Connection closed" : "Connection lost"
3680
- );
3681
- for (const actionInfo of this.#actionsInFlight.values()) {
3682
- actionInfo.reject(disconnectError);
3683
- }
3684
- this.#actionsInFlight.clear();
3685
- }
3686
- this.#transport = void 0;
3687
- if (!this.#disposed && !this.#connecting) {
3688
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3689
- msg: "triggering reconnect",
3690
- connectionId: this.#connectionId,
3691
- messageQueueLength: this.#messageQueue.length
3692
- });
3693
- this.#connectWithRetry();
3694
- }
3695
- }
3696
- /** Called by the onerror event from drivers. */
3697
- #handleOnError() {
3698
- if (this.#disposed) return;
3699
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn("socket error");
3700
- }
3701
- #takeActionInFlight(id) {
3702
- const inFlight = this.#actionsInFlight.get(id);
3703
- if (!inFlight) {
3704
- throw new InternalError2(`No in flight response for ${id}`);
3705
- }
3706
- this.#actionsInFlight.delete(id);
3707
- return inFlight;
3708
- }
3709
- #dispatchEvent(event) {
3710
- const { name, args: argsRaw } = event;
3711
- const args = cbor5.decode(new Uint8Array(argsRaw));
3712
- const listeners = this.#eventSubscriptions.get(name);
3713
- if (!listeners) return;
3714
- for (const listener of [...listeners]) {
3715
- listener.callback(...args);
3716
- if (listener.once) {
3717
- listeners.delete(listener);
3718
- }
3719
- }
3720
- if (listeners.size === 0) {
3721
- this.#eventSubscriptions.delete(name);
3722
- }
3723
- }
3724
- #dispatchActorError(error) {
3725
- for (const handler of [...this.#errorHandlers]) {
3726
- try {
3727
- handler(error);
3728
- } catch (err) {
3729
- _chunkZTH3KYFHcjs.logger.call(void 0, ).error({
3730
- msg: "error in connection error handler",
3731
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, err)
3732
- });
3733
- }
3734
- }
3735
- }
3736
- #addEventSubscription(eventName, callback, once) {
3737
- const listener = {
3738
- callback,
3739
- once
3740
- };
3741
- let subscriptionSet = this.#eventSubscriptions.get(eventName);
3742
- if (subscriptionSet === void 0) {
3743
- subscriptionSet = /* @__PURE__ */ new Set();
3744
- this.#eventSubscriptions.set(eventName, subscriptionSet);
3745
- this.#sendSubscription(eventName, true);
3746
- }
3747
- subscriptionSet.add(listener);
3748
- return () => {
3749
- const listeners = this.#eventSubscriptions.get(eventName);
3750
- if (listeners) {
3751
- listeners.delete(listener);
3752
- if (listeners.size === 0) {
3753
- this.#eventSubscriptions.delete(eventName);
3754
- this.#sendSubscription(eventName, false);
3755
- }
3756
- }
3757
- };
3758
- }
3759
- /**
3760
- * Subscribes to an event that will happen repeatedly.
3761
- *
3762
- * @template Args - The type of arguments the event callback will receive.
3763
- * @param {string} eventName - The name of the event to subscribe to.
3764
- * @param {(...args: Args) => void} callback - The callback function to execute when the event is triggered.
3765
- * @returns {EventUnsubscribe} - A function to unsubscribe from the event.
3766
- * @see {@link https://rivet.dev/docs/events|Events Documentation}
3767
- */
3768
- on(eventName, callback) {
3769
- return this.#addEventSubscription(eventName, callback, false);
3770
- }
3771
- /**
3772
- * Subscribes to an event that will be triggered only once.
3773
- *
3774
- * @template Args - The type of arguments the event callback will receive.
3775
- * @param {string} eventName - The name of the event to subscribe to.
3776
- * @param {(...args: Args) => void} callback - The callback function to execute when the event is triggered.
3777
- * @returns {EventUnsubscribe} - A function to unsubscribe from the event.
3778
- * @see {@link https://rivet.dev/docs/events|Events Documentation}
3779
- */
3780
- once(eventName, callback) {
3781
- return this.#addEventSubscription(eventName, callback, true);
3782
- }
3783
- /**
3784
- * Subscribes to connection errors.
3785
- *
3786
- * @param {ActorErrorCallback} callback - The callback function to execute when a connection error occurs.
3787
- * @returns {() => void} - A function to unsubscribe from the error handler.
3788
- */
3789
- onError(callback) {
3790
- this.#errorHandlers.add(callback);
3791
- return () => {
3792
- this.#errorHandlers.delete(callback);
3793
- };
3794
- }
3795
- #sendMessage(message, opts) {
3796
- var _a, _b;
3797
- if (this.#disposed) {
3798
- throw new ActorConnDisposed();
3799
- }
3800
- let queueMessage = false;
3801
- if (!this.#transport) {
3802
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "no transport, queueing message" });
3803
- queueMessage = true;
3804
- } else if ("websocket" in this.#transport) {
3805
- const readyState = this.#transport.websocket.readyState;
3806
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3807
- msg: "websocket send attempt",
3808
- readyState,
3809
- readyStateString: readyState === 0 ? "CONNECTING" : readyState === 1 ? "OPEN" : readyState === 2 ? "CLOSING" : "CLOSED",
3810
- connectionId: this.#connectionId,
3811
- messageType: message.body.tag,
3812
- actionName: (_a = message.body.val) == null ? void 0 : _a.name
3813
- });
3814
- if (readyState === 1) {
3815
- try {
3816
- const messageSerialized = _chunkHHFKKVLRcjs.serializeWithEncoding.call(void 0,
3817
- this.#encoding,
3818
- message,
3819
- _chunkVFB23BYZcjs.TO_SERVER_VERSIONED
3820
- );
3821
- this.#transport.websocket.send(messageSerialized);
3822
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace({
3823
- msg: "sent websocket message",
3824
- len: messageLength(messageSerialized)
3825
- });
3826
- } catch (error) {
3827
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({
3828
- msg: "failed to send message, added to queue",
3829
- error,
3830
- connectionId: this.#connectionId
3831
- });
3832
- queueMessage = true;
3833
- }
3834
- } else {
3835
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3836
- msg: "websocket not open, queueing message",
3837
- readyState
3838
- });
3839
- queueMessage = true;
3840
- }
3841
- } else if ("sse" in this.#transport) {
3842
- if (this.#transport.sse.readyState === 1) {
3843
- this.#sendHttpMessage(message, opts);
3844
- } else {
3845
- queueMessage = true;
3846
- }
3847
- } else {
3848
- _chunk7L65NNWPcjs.assertUnreachable.call(void 0, this.#transport);
3849
- }
3850
- if (!(opts == null ? void 0 : opts.ephemeral) && queueMessage) {
3851
- this.#messageQueue.push(message);
3852
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3853
- msg: "queued connection message",
3854
- queueLength: this.#messageQueue.length,
3855
- connectionId: this.#connectionId,
3856
- messageType: message.body.tag,
3857
- actionName: (_b = message.body.val) == null ? void 0 : _b.name
3858
- });
3859
- }
3860
- }
3861
- async #sendHttpMessage(message, opts) {
3862
- try {
3863
- if (!this.#actorId || !this.#connectionId || !this.#connectionToken)
3864
- throw new InternalError2(
3865
- "Missing connection ID or token."
3866
- );
3867
- _chunkZTH3KYFHcjs.logger.call(void 0, ).trace(
3868
- _chunk7L65NNWPcjs.getEnvUniversal.call(void 0, "_RIVETKIT_LOG_MESSAGE") ? {
3869
- msg: "sent http message",
3870
- message: `${_chunkHHFKKVLRcjs.jsonStringifyCompat.call(void 0, message).substring(0, 100)}...`
3871
- } : { msg: "sent http message" }
3872
- );
3873
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({
3874
- msg: "sending http message",
3875
- actorId: this.#actorId,
3876
- connectionId: this.#connectionId
3877
- });
3878
- await sendHttpRequest({
3879
- url: "http://actor/connections/message",
3880
- method: "POST",
3881
- headers: {
3882
- [_chunkHHFKKVLRcjs.HEADER_ENCODING]: this.#encoding,
3883
- [_chunkHHFKKVLRcjs.HEADER_CONN_ID]: this.#connectionId,
3884
- [_chunkHHFKKVLRcjs.HEADER_CONN_TOKEN]: this.#connectionToken
3885
- },
3886
- body: message,
3887
- encoding: this.#encoding,
3888
- skipParseResponse: true,
3889
- customFetch: this.#driver.sendRequest.bind(
3890
- this.#driver,
3891
- this.#actorId
3892
- ),
3893
- requestVersionedDataHandler: _chunkVFB23BYZcjs.TO_SERVER_VERSIONED,
3894
- responseVersionedDataHandler: _chunkVFB23BYZcjs.TO_CLIENT_VERSIONED
3895
- });
3896
- } catch (error) {
3897
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({
3898
- msg: "failed to send message, added to queue",
3899
- error
3900
- });
3901
- if (!(opts == null ? void 0 : opts.ephemeral)) {
3902
- this.#messageQueue.unshift(message);
3903
- }
3904
- }
3905
- }
3906
- async #parseMessage(data) {
3907
- _invariant2.default.call(void 0, this.#transport, "transport must be defined");
3908
- if (_chunkHHFKKVLRcjs.encodingIsBinary.call(void 0, this.#encoding) && "sse" in this.#transport) {
3909
- if (typeof data === "string") {
3910
- const binaryString = atob(data);
3911
- data = new Uint8Array(
3912
- [...binaryString].map((char) => char.charCodeAt(0))
3913
- );
3914
- } else {
3915
- throw new InternalError2(
3916
- `Expected data to be a string for SSE, got ${data}.`
3917
- );
3918
- }
3919
- }
3920
- const buffer = await _chunkVFB23BYZcjs.inputDataToBuffer.call(void 0, data);
3921
- return _chunkHHFKKVLRcjs.deserializeWithEncoding.call(void 0,
3922
- this.#encoding,
3923
- buffer,
3924
- _chunkVFB23BYZcjs.TO_CLIENT_VERSIONED
3925
- );
3926
- }
3927
- /**
3928
- * Get the actor ID (for testing purposes).
3929
- * @internal
3930
- */
3931
- get actorId() {
3932
- return this.#actorId;
3933
- }
3934
- /**
3935
- * Get the connection ID (for testing purposes).
3936
- * @internal
3937
- */
3938
- get connectionId() {
3939
- return this.#connectionId;
3940
- }
3941
- /**
3942
- * Disconnects from the actor.
3943
- *
3944
- * @returns {Promise<void>} A promise that resolves when the socket is gracefully closed.
3945
- */
3946
- async dispose() {
3947
- if (this.#disposed) {
3948
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({ msg: "connection already disconnected" });
3949
- return;
3950
- }
3951
- this.#disposed = true;
3952
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "disposing actor conn" });
3953
- clearInterval(this.#keepNodeAliveInterval);
3954
- this.#abortController.abort();
3955
- this.#client[ACTOR_CONNS_SYMBOL].delete(this);
3956
- if (!this.#transport) {
3957
- } else if ("websocket" in this.#transport) {
3958
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug("closing ws");
3959
- const ws = this.#transport.websocket;
3960
- if (ws.readyState === 2 || ws.readyState === 3) {
3961
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "ws already closed or closing" });
3962
- } else {
3963
- const { promise, resolve } = _chunk7L65NNWPcjs.promiseWithResolvers.call(void 0, );
3964
- ws.addEventListener("close", () => {
3965
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug({ msg: "ws closed" });
3966
- resolve(void 0);
3967
- });
3968
- ws.close(1e3, "Normal closure");
3969
- await promise;
3970
- }
3971
- } else if ("sse" in this.#transport) {
3972
- _chunkZTH3KYFHcjs.logger.call(void 0, ).debug("closing sse");
3973
- if (this.#connectionId && this.#connectionToken) {
3974
- try {
3975
- await sendHttpRequest({
3976
- url: "http://actor/connections/close",
3977
- method: "POST",
3978
- headers: {
3979
- [_chunkHHFKKVLRcjs.HEADER_CONN_ID]: this.#connectionId,
3980
- [_chunkHHFKKVLRcjs.HEADER_CONN_TOKEN]: this.#connectionToken
3981
- },
3982
- encoding: this.#encoding,
3983
- skipParseResponse: true,
3984
- customFetch: this.#driver.sendRequest.bind(
3985
- this.#driver,
3986
- this.#actorId
3987
- ),
3988
- requestVersionedDataHandler: _chunkVFB23BYZcjs.TO_SERVER_VERSIONED,
3989
- responseVersionedDataHandler: _chunkVFB23BYZcjs.TO_CLIENT_VERSIONED
3990
- });
3991
- } catch (error) {
3992
- _chunkZTH3KYFHcjs.logger.call(void 0, ).warn({
3993
- msg: "failed to send close request",
3994
- error
3995
- });
3996
- }
3997
- }
3998
- this.#transport.sse.close();
3999
- } else {
4000
- _chunk7L65NNWPcjs.assertUnreachable.call(void 0, this.#transport);
4001
- }
4002
- this.#transport = void 0;
4003
- }
4004
- #sendSubscription(eventName, subscribe) {
4005
- this.#sendMessage(
4006
- {
4007
- body: {
4008
- tag: "SubscriptionRequest",
4009
- val: {
4010
- eventName,
4011
- subscribe
4012
- }
4013
- }
4014
- },
4015
- { ephemeral: true }
4016
- );
4017
- }
4018
- };
4019
-
4020
- // src/remote-manager-driver/mod.ts
4021
-
4022
-
4023
-
4024
- // src/remote-manager-driver/log.ts
4025
- function logger2() {
4026
- return _chunk7L65NNWPcjs.getLogger.call(void 0, "remote-manager-driver");
4027
- }
4028
-
4029
- // src/remote-manager-driver/api-utils.ts
4030
- var EngineApiError = class extends Error {
4031
- constructor(group, code, message) {
4032
- super(message || `Engine API error: ${group}/${code}`);
4033
- this.group = group;
4034
- this.code = code;
4035
- this.name = "EngineApiError";
4036
- }
4037
- };
4038
- function getEndpoint(config) {
4039
- return _nullishCoalesce(config.endpoint, () => ( "http://127.0.0.1:6420"));
4040
- }
4041
- async function apiCall(config, method, path, body) {
4042
- const endpoint = getEndpoint(config);
4043
- const url = _chunk7L65NNWPcjs.combineUrlPath.call(void 0, endpoint, path, {
4044
- namespace: config.namespace
4045
- });
4046
- logger2().debug({ msg: "making api call", method, url });
4047
- const headers = {
4048
- ...config.headers
4049
- };
4050
- if (config.token) {
4051
- headers.Authorization = `Bearer ${config.token}`;
4052
- }
4053
- return await sendHttpRequest({
4054
- method,
4055
- url,
4056
- headers,
4057
- body,
4058
- encoding: "json",
4059
- skipParseResponse: false,
4060
- requestVersionedDataHandler: void 0,
4061
- responseVersionedDataHandler: void 0
4062
- });
4063
- }
4064
-
4065
- // src/remote-manager-driver/actor-http-client.ts
4066
- async function sendHttpRequestToActor(runConfig, actorId, actorRequest) {
4067
- const url = new URL(actorRequest.url);
4068
- const endpoint = getEndpoint(runConfig);
4069
- const guardUrl = _chunk7L65NNWPcjs.combineUrlPath.call(void 0,
4070
- endpoint,
4071
- `/gateway/${actorId}${url.pathname}${url.search}`
4072
- );
4073
- let bodyToSend = null;
4074
- const guardHeaders = buildGuardHeadersForHttp(
4075
- runConfig,
4076
- actorRequest,
4077
- actorId
4078
- );
4079
- if (actorRequest.method !== "GET" && actorRequest.method !== "HEAD") {
4080
- if (actorRequest.bodyUsed) {
4081
- throw new Error("Request body has already been consumed");
4082
- }
4083
- const reqBody = await actorRequest.arrayBuffer();
4084
- if (reqBody.byteLength !== 0) {
4085
- bodyToSend = reqBody;
4086
- guardHeaders.delete("transfer-encoding");
4087
- guardHeaders.set("content-length", String(bodyToSend.byteLength));
4088
- }
4089
- }
4090
- const guardRequest = new Request(guardUrl, {
4091
- method: actorRequest.method,
4092
- headers: guardHeaders,
4093
- body: bodyToSend,
4094
- signal: actorRequest.signal
4095
- });
4096
- return mutableResponse(await fetch(guardRequest));
4097
- }
4098
- function mutableResponse(fetchRes) {
4099
- return new Response(fetchRes.body, fetchRes);
4100
- }
4101
- function buildGuardHeadersForHttp(runConfig, actorRequest, actorId) {
4102
- const headers = new Headers();
4103
- for (const [key, value] of actorRequest.headers.entries()) {
4104
- headers.set(key, value);
4105
- }
4106
- for (const [key, value] of Object.entries(runConfig.headers)) {
4107
- headers.set(key, value);
4108
- }
4109
- if (runConfig.token) {
4110
- headers.set(_chunkHHFKKVLRcjs.HEADER_RIVET_TOKEN, runConfig.token);
4111
- }
4112
- return headers;
4113
- }
4114
-
4115
- // src/remote-manager-driver/actor-websocket-client.ts
4116
- async function openWebSocketToActor(runConfig, path, actorId, encoding, params, connId, connToken) {
4117
- const WebSocket2 = await _chunkZTH3KYFHcjs.importWebSocket.call(void 0, );
4118
- const endpoint = getEndpoint(runConfig);
4119
- const guardUrl = _chunk7L65NNWPcjs.combineUrlPath.call(void 0, endpoint, `/gateway/${actorId}${path}`);
4120
- logger2().debug({
4121
- msg: "opening websocket to actor via guard",
4122
- actorId,
4123
- path,
4124
- guardUrl
4125
- });
4126
- const ws = new WebSocket2(
4127
- guardUrl,
4128
- buildWebSocketProtocols(runConfig, encoding, params, connId, connToken)
4129
- );
4130
- ws.binaryType = "arraybuffer";
4131
- logger2().debug({ msg: "websocket connection opened", actorId });
4132
- return ws;
4133
- }
4134
- function buildWebSocketProtocols(runConfig, encoding, params, connId, connToken) {
4135
- const protocols = [];
4136
- protocols.push(_chunkHHFKKVLRcjs.WS_PROTOCOL_STANDARD);
4137
- protocols.push(`${_chunkHHFKKVLRcjs.WS_PROTOCOL_ENCODING}${encoding}`);
4138
- if (runConfig.token) {
4139
- protocols.push(`${_chunkHHFKKVLRcjs.WS_PROTOCOL_TOKEN}${runConfig.token}`);
4140
- }
4141
- if (params) {
4142
- protocols.push(
4143
- `${_chunkHHFKKVLRcjs.WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`
4144
- );
4145
- }
4146
- if (connId) {
4147
- protocols.push(`${_chunkHHFKKVLRcjs.WS_PROTOCOL_CONN_ID}${connId}`);
4148
- }
4149
- if (connToken) {
4150
- protocols.push(`${_chunkHHFKKVLRcjs.WS_PROTOCOL_CONN_TOKEN}${connToken}`);
4151
- }
4152
- return protocols;
4153
- }
4154
-
4155
- // src/remote-manager-driver/api-endpoints.ts
4156
- async function getActor(config, _, actorId) {
4157
- return apiCall(
4158
- config,
4159
- "GET",
4160
- `/actors?actor_ids=${encodeURIComponent(actorId)}`
4161
- );
4162
- }
4163
- async function getActorByKey(config, name, key) {
4164
- const serializedKey = serializeActorKey(key);
4165
- return apiCall(
4166
- config,
4167
- "GET",
4168
- `/actors?name=${encodeURIComponent(name)}&key=${encodeURIComponent(serializedKey)}`
4169
- );
4170
- }
4171
- async function getOrCreateActor(config, request) {
4172
- return apiCall(
4173
- config,
4174
- "PUT",
4175
- `/actors`,
4176
- request
4177
- );
4178
- }
4179
- async function createActor(config, request) {
4180
- return apiCall(
4181
- config,
4182
- "POST",
4183
- `/actors`,
4184
- request
4185
- );
4186
- }
4187
- async function destroyActor(config, actorId) {
4188
- return apiCall(
4189
- config,
4190
- "DELETE",
4191
- `/actors/${encodeURIComponent(actorId)}`
4192
- );
4193
- }
4194
- async function getMetadata(config) {
4195
- return apiCall(config, "GET", `/metadata`);
4196
- }
4197
- async function getDatacenters(config) {
4198
- return apiCall(config, "GET", `/datacenters`);
4199
- }
4200
- async function updateRunnerConfig(config, runnerName, request) {
4201
- return apiCall(
4202
- config,
4203
- "PUT",
4204
- `/runner-configs/${runnerName}`,
4205
- request
4206
- );
4207
- }
4208
-
4209
- // src/remote-manager-driver/ws-proxy.ts
4210
- async function createWebSocketProxy(c, targetUrl, protocols) {
4211
- const WebSocket2 = await _chunkZTH3KYFHcjs.importWebSocket.call(void 0, );
4212
- const state = {};
4213
- return {
4214
- onOpen: async (event, clientWs) => {
4215
- logger2().debug({ msg: "client websocket connected", targetUrl });
4216
- if (clientWs.readyState !== 1) {
4217
- logger2().warn({
4218
- msg: "client websocket not open on connection",
4219
- targetUrl,
4220
- readyState: clientWs.readyState
4221
- });
4222
- return;
4223
- }
4224
- const targetWs = new WebSocket2(targetUrl, protocols);
4225
- state.targetWs = targetWs;
4226
- state.connectPromise = new Promise((resolve, reject) => {
4227
- targetWs.addEventListener("open", () => {
4228
- logger2().debug({
4229
- msg: "target websocket connected",
4230
- targetUrl
4231
- });
4232
- if (clientWs.readyState !== 1) {
4233
- logger2().warn({
4234
- msg: "client websocket closed before target connected",
4235
- targetUrl,
4236
- clientReadyState: clientWs.readyState
4237
- });
4238
- targetWs.close(1001, "Client disconnected");
4239
- reject(new Error("Client disconnected"));
4240
- return;
4241
- }
4242
- resolve();
4243
- });
4244
- targetWs.addEventListener("error", (error) => {
4245
- logger2().warn({
4246
- msg: "target websocket error during connection",
4247
- targetUrl
4248
- });
4249
- reject(error);
4250
- });
4251
- });
4252
- state.targetWs.addEventListener("message", (event2) => {
4253
- if (typeof event2.data === "string" || event2.data instanceof ArrayBuffer) {
4254
- clientWs.send(event2.data);
4255
- } else if (event2.data instanceof Blob) {
4256
- event2.data.arrayBuffer().then((buffer) => {
4257
- clientWs.send(buffer);
4258
- });
4259
- }
4260
- });
4261
- state.targetWs.addEventListener("close", (event2) => {
4262
- logger2().debug({
4263
- msg: "target websocket closed",
4264
- targetUrl,
4265
- code: event2.code,
4266
- reason: event2.reason
4267
- });
4268
- closeWebSocketIfOpen(clientWs, event2.code, event2.reason);
4269
- });
4270
- state.targetWs.addEventListener("error", (error) => {
4271
- logger2().error({
4272
- msg: "target websocket error",
4273
- targetUrl,
4274
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
4275
- });
4276
- closeWebSocketIfOpen(clientWs, 1011, "Target WebSocket error");
4277
- });
4278
- },
4279
- onMessage: async (event, clientWs) => {
4280
- if (!state.targetWs || !state.connectPromise) {
4281
- logger2().error({
4282
- msg: "websocket state not initialized",
4283
- targetUrl
4284
- });
4285
- return;
4286
- }
4287
- try {
4288
- await state.connectPromise;
4289
- if (state.targetWs.readyState === WebSocket2.OPEN) {
4290
- state.targetWs.send(event.data);
4291
- } else {
4292
- logger2().warn({
4293
- msg: "target websocket not open",
4294
- targetUrl,
4295
- readyState: state.targetWs.readyState
4296
- });
4297
- }
4298
- } catch (error) {
4299
- logger2().error({
4300
- msg: "failed to connect to target websocket",
4301
- targetUrl,
4302
- error
4303
- });
4304
- closeWebSocketIfOpen(
4305
- clientWs,
4306
- 1011,
4307
- "Failed to connect to target"
4308
- );
4309
- }
4310
- },
4311
- onClose: (event, clientWs) => {
4312
- logger2().debug({
4313
- msg: "client websocket closed",
4314
- targetUrl,
4315
- code: event.code,
4316
- reason: event.reason,
4317
- wasClean: event.wasClean
4318
- });
4319
- if (state.targetWs) {
4320
- if (state.targetWs.readyState === WebSocket2.OPEN || state.targetWs.readyState === WebSocket2.CONNECTING) {
4321
- state.targetWs.close(
4322
- 1e3,
4323
- event.reason || "Client disconnected"
4324
- );
4325
- }
4326
- }
4327
- },
4328
- onError: (event, clientWs) => {
4329
- logger2().error({ msg: "client websocket error", targetUrl, event });
4330
- if (state.targetWs) {
4331
- if (state.targetWs.readyState === WebSocket2.OPEN) {
4332
- state.targetWs.close(1011, "Client WebSocket error");
4333
- } else if (state.targetWs.readyState === WebSocket2.CONNECTING) {
4334
- state.targetWs.close();
4335
- }
4336
- }
4337
- }
4338
- };
4339
- }
4340
- function closeWebSocketIfOpen(ws, code, reason) {
4341
- if (ws.readyState === 1) {
4342
- ws.close(code, reason);
4343
- } else if ("close" in ws && ws.readyState === WebSocket.OPEN) {
4344
- ws.close(code, reason);
4345
- }
4346
- }
4347
-
4348
- // src/remote-manager-driver/mod.ts
4349
- var metadataCheckCache = /* @__PURE__ */ new Map();
4350
- var RemoteManagerDriver = class {
4351
- #config;
4352
- #metadataPromise;
4353
- constructor(runConfig) {
4354
- if (_chunk7L65NNWPcjs.getEnvUniversal.call(void 0, "NEXT_PHASE") === "phase-production-build") {
4355
- logger2().info(
4356
- "detected next.js build phase, disabling health check"
4357
- );
4358
- runConfig.disableHealthCheck = true;
4359
- }
4360
- this.#config = runConfig;
4361
- if (!runConfig.disableHealthCheck) {
4362
- this.#metadataPromise = this.#performMetadataCheck(runConfig);
4363
- this.#metadataPromise.catch((error) => {
4364
- logger2().error({
4365
- msg: "metadata check failed",
4366
- error: error instanceof Error ? error.message : String(error)
4367
- });
4368
- });
4369
- }
4370
- }
4371
- async #performMetadataCheck(config) {
4372
- const endpoint = getEndpoint(config);
4373
- const existingPromise = metadataCheckCache.get(endpoint);
4374
- if (existingPromise) {
4375
- return existingPromise;
4376
- }
4377
- const metadataCheckPromise = (async () => {
4378
- try {
4379
- const metadataData = await getMetadata(config);
4380
- if (metadataData.clientEndpoint) {
4381
- logger2().info({
4382
- msg: "received new client endpoint from metadata",
4383
- endpoint: metadataData.clientEndpoint
4384
- });
4385
- this.#config.endpoint = metadataData.clientEndpoint;
4386
- }
4387
- logger2().info({
4388
- msg: "connected to rivetkit manager",
4389
- runtime: metadataData.runtime,
4390
- version: metadataData.version,
4391
- runner: metadataData.runner
4392
- });
4393
- } catch (error) {
4394
- logger2().error({
4395
- msg: "health check failed, validate the Rivet endpoint is configured correctly",
4396
- endpoint,
4397
- error: _chunk7L65NNWPcjs.stringifyError.call(void 0, error)
4398
- });
4399
- }
4400
- })();
4401
- metadataCheckCache.set(endpoint, metadataCheckPromise);
4402
- return metadataCheckPromise;
4403
- }
4404
- async getForId({
4405
- c,
4406
- name,
4407
- actorId
4408
- }) {
4409
- if (this.#metadataPromise) {
4410
- await this.#metadataPromise;
4411
- }
4412
- const response = await getActor(this.#config, name, actorId);
4413
- const actor = response.actors[0];
4414
- if (!actor) return void 0;
4415
- if (actor.name !== name) {
4416
- logger2().debug({
4417
- msg: "actor name mismatch from api",
4418
- actorId,
4419
- apiName: actor.name,
4420
- requestedName: name
4421
- });
4422
- return void 0;
4423
- }
4424
- const keyRaw = actor.key;
4425
- _invariant2.default.call(void 0, keyRaw, `actor ${actorId} should have key`);
4426
- const key = deserializeActorKey(keyRaw);
4427
- return {
4428
- actorId,
4429
- name,
4430
- key
4431
- };
4432
- }
4433
- async getWithKey({
4434
- c,
4435
- name,
4436
- key
4437
- }) {
4438
- if (this.#metadataPromise) {
4439
- await this.#metadataPromise;
4440
- }
4441
- logger2().debug({ msg: "getWithKey: searching for actor", name, key });
4442
- try {
4443
- const response = await getActorByKey(this.#config, name, key);
4444
- const actor = response.actors[0];
4445
- if (!actor) return void 0;
4446
- const actorId = actor.actor_id;
4447
- logger2().debug({
4448
- msg: "getWithKey: found actor via api",
4449
- actorId,
4450
- name,
4451
- key
4452
- });
4453
- return {
4454
- actorId,
4455
- name,
4456
- key
4457
- };
4458
- } catch (error) {
4459
- if (error instanceof EngineApiError && error.group === "actor" && error.code === "not_found") {
4460
- return void 0;
4461
- }
4462
- throw error;
4463
- }
4464
- }
4465
- async getOrCreateWithKey(input) {
4466
- if (this.#metadataPromise) {
4467
- await this.#metadataPromise;
4468
- }
4469
- const { c, name, key, input: actorInput, region } = input;
4470
- logger2().info({
4471
- msg: "getOrCreateWithKey: getting or creating actor via engine api",
4472
- name,
4473
- key
4474
- });
4475
- const { actor, created } = await getOrCreateActor(this.#config, {
4476
- datacenter: region,
4477
- name,
4478
- key: serializeActorKey(key),
4479
- runner_name_selector: this.#config.runnerName,
4480
- input: actorInput ? _chunkHHFKKVLRcjs.uint8ArrayToBase64.call(void 0, cbor6.encode(actorInput)) : void 0,
4481
- crash_policy: "sleep"
4482
- });
4483
- const actorId = actor.actor_id;
4484
- logger2().info({
4485
- msg: "getOrCreateWithKey: actor ready",
4486
- actorId,
4487
- name,
4488
- key,
4489
- created
4490
- });
4491
- return {
4492
- actorId,
4493
- name,
4494
- key
4495
- };
4496
- }
4497
- async createActor({
4498
- c,
4499
- name,
4500
- key,
4501
- input,
4502
- region
4503
- }) {
4504
- if (this.#metadataPromise) {
4505
- await this.#metadataPromise;
4506
- }
4507
- logger2().info({ msg: "creating actor via engine api", name, key });
4508
- const result = await createActor(this.#config, {
4509
- datacenter: region,
4510
- name,
4511
- runner_name_selector: this.#config.runnerName,
4512
- key: serializeActorKey(key),
4513
- input: input ? _chunkHHFKKVLRcjs.uint8ArrayToBase64.call(void 0, cbor6.encode(input)) : void 0,
4514
- crash_policy: "sleep"
4515
- });
4516
- const actorId = result.actor.actor_id;
4517
- logger2().info({ msg: "actor created", actorId, name, key });
4518
- return {
4519
- actorId,
4520
- name,
4521
- key
4522
- };
4523
- }
4524
- async destroyActor(actorId) {
4525
- if (this.#metadataPromise) {
4526
- await this.#metadataPromise;
4527
- }
4528
- logger2().info({ msg: "destroying actor via engine api", actorId });
4529
- await destroyActor(this.#config, actorId);
4530
- logger2().info({ msg: "actor destroyed", actorId });
4531
- }
4532
- async sendRequest(actorId, actorRequest) {
4533
- if (this.#metadataPromise) {
4534
- await this.#metadataPromise;
4535
- }
4536
- return await sendHttpRequestToActor(
4537
- this.#config,
4538
- actorId,
4539
- actorRequest
4540
- );
4541
- }
4542
- async openWebSocket(path, actorId, encoding, params, connId, connToken) {
4543
- if (this.#metadataPromise) {
4544
- await this.#metadataPromise;
4545
- }
4546
- return await openWebSocketToActor(
4547
- this.#config,
4548
- path,
4549
- actorId,
4550
- encoding,
4551
- params,
4552
- connId,
4553
- connToken
4554
- );
4555
- }
4556
- async proxyRequest(_c, actorRequest, actorId) {
4557
- if (this.#metadataPromise) {
4558
- await this.#metadataPromise;
4559
- }
4560
- return await sendHttpRequestToActor(
4561
- this.#config,
4562
- actorId,
4563
- actorRequest
4564
- );
4565
- }
4566
- async proxyWebSocket(c, path, actorId, encoding, params, connId, connToken) {
4567
- var _a, _b;
4568
- if (this.#metadataPromise) {
4569
- await this.#metadataPromise;
4570
- }
4571
- const upgradeWebSocket = (_b = (_a = this.#config).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
4572
- _invariant2.default.call(void 0, upgradeWebSocket, "missing getUpgradeWebSocket");
4573
- const endpoint = getEndpoint(this.#config);
4574
- const guardUrl = _chunk7L65NNWPcjs.combineUrlPath.call(void 0, endpoint, path);
4575
- const wsGuardUrl = guardUrl.replace("http://", "ws://");
4576
- logger2().debug({
4577
- msg: "forwarding websocket to actor via guard",
4578
- actorId,
4579
- path,
4580
- guardUrl
4581
- });
4582
- const protocols = buildWebSocketProtocols(
4583
- this.#config,
4584
- encoding,
4585
- params,
4586
- connId,
4587
- connToken
4588
- );
4589
- const args = await createWebSocketProxy(c, wsGuardUrl, protocols);
4590
- return await upgradeWebSocket(() => args)(c, _chunk7L65NNWPcjs.noopNext.call(void 0, ));
4591
- }
4592
- displayInformation() {
4593
- return { name: "Remote", properties: {} };
4594
- }
4595
- getOrCreateInspectorAccessToken() {
4596
- return _chunkHHFKKVLRcjs.generateRandomString.call(void 0, );
4597
- }
4598
- };
4599
-
4600
-
4601
-
4602
-
4603
-
4604
-
4605
-
4606
-
4607
-
4608
-
4609
-
4610
-
4611
-
4612
-
4613
-
4614
-
4615
-
4616
-
4617
-
4618
-
4619
-
4620
-
4621
-
4622
- exports.createActorInspectorRouter = createActorInspectorRouter; exports.serializeActorKey = serializeActorKey; exports.deserializeActorKey = deserializeActorKey; exports.PERSIST_SYMBOL = PERSIST_SYMBOL; exports.generateConnId = generateConnId; exports.generateConnToken = generateConnToken; exports.generateConnRequestId = generateConnRequestId; exports.ActorDefinition = ActorDefinition; exports.lookupInRegistry = lookupInRegistry; exports.ActorClientError = ActorClientError; exports.InternalError = InternalError2; exports.ManagerError = ManagerError; exports.MalformedResponseMessage = MalformedResponseMessage; exports.ActorError = ActorError; exports.getEndpoint = getEndpoint; exports.ActorConnRaw = ActorConnRaw; exports.ActorHandleRaw = ActorHandleRaw; exports.createClientWithDriver = createClientWithDriver; exports.getDatacenters = getDatacenters; exports.updateRunnerConfig = updateRunnerConfig; exports.RemoteManagerDriver = RemoteManagerDriver;
4623
- //# sourceMappingURL=chunk-O44LFKSB.cjs.map