rivetkit 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/README.md +11 -0
  2. package/dist/schemas/actor-persist/v1.ts +21 -24
  3. package/dist/schemas/client-protocol/v1.ts +6 -0
  4. package/dist/tsup/actor/errors.cjs +10 -2
  5. package/dist/tsup/actor/errors.cjs.map +1 -1
  6. package/dist/tsup/actor/errors.d.cts +17 -4
  7. package/dist/tsup/actor/errors.d.ts +17 -4
  8. package/dist/tsup/actor/errors.js +11 -3
  9. package/dist/tsup/{chunk-4NSUQZ2H.js → chunk-2MD57QF4.js} +119 -115
  10. package/dist/tsup/chunk-2MD57QF4.js.map +1 -0
  11. package/dist/tsup/{chunk-GIR3AFFI.cjs → chunk-5QGQK44L.cjs} +103 -44
  12. package/dist/tsup/chunk-5QGQK44L.cjs.map +1 -0
  13. package/dist/tsup/chunk-5YTI25C3.cjs +250 -0
  14. package/dist/tsup/chunk-5YTI25C3.cjs.map +1 -0
  15. package/dist/tsup/chunk-B2QGJGZQ.js +338 -0
  16. package/dist/tsup/chunk-B2QGJGZQ.js.map +1 -0
  17. package/dist/tsup/{chunk-3H7O2A7I.js → chunk-CFFKMUYH.js} +61 -22
  18. package/dist/tsup/chunk-CFFKMUYH.js.map +1 -0
  19. package/dist/tsup/{chunk-FLMTTN27.js → chunk-CKA54YQN.js} +15 -8
  20. package/dist/tsup/chunk-CKA54YQN.js.map +1 -0
  21. package/dist/tsup/chunk-D7NWUCRK.cjs +20 -0
  22. package/dist/tsup/chunk-D7NWUCRK.cjs.map +1 -0
  23. package/dist/tsup/{chunk-FCCPJNMA.cjs → chunk-FGFT4FVX.cjs} +12 -27
  24. package/dist/tsup/chunk-FGFT4FVX.cjs.map +1 -0
  25. package/dist/tsup/chunk-I5VTWPHW.js +20 -0
  26. package/dist/tsup/chunk-I5VTWPHW.js.map +1 -0
  27. package/dist/tsup/{chunk-6WKQDDUD.cjs → chunk-IRMBWX36.cjs} +146 -142
  28. package/dist/tsup/chunk-IRMBWX36.cjs.map +1 -0
  29. package/dist/tsup/chunk-L7QRXNWP.js +6562 -0
  30. package/dist/tsup/chunk-L7QRXNWP.js.map +1 -0
  31. package/dist/tsup/{chunk-R2OPSKIV.cjs → chunk-LZIBTLEY.cjs} +20 -13
  32. package/dist/tsup/chunk-LZIBTLEY.cjs.map +1 -0
  33. package/dist/tsup/chunk-MRZS2J4X.cjs +6562 -0
  34. package/dist/tsup/chunk-MRZS2J4X.cjs.map +1 -0
  35. package/dist/tsup/{chunk-PO4VLDWA.js → chunk-PG3K2LI7.js} +3 -5
  36. package/dist/tsup/chunk-PG3K2LI7.js.map +1 -0
  37. package/dist/tsup/{chunk-TZJKSBUQ.cjs → chunk-PHSQJ6QI.cjs} +3 -5
  38. package/dist/tsup/chunk-PHSQJ6QI.cjs.map +1 -0
  39. package/dist/tsup/chunk-RM2SVURR.cjs +338 -0
  40. package/dist/tsup/chunk-RM2SVURR.cjs.map +1 -0
  41. package/dist/tsup/{chunk-OGAPU3UG.cjs → chunk-WADSS5X4.cjs} +66 -27
  42. package/dist/tsup/chunk-WADSS5X4.cjs.map +1 -0
  43. package/dist/tsup/chunk-WNGOBAA7.js +250 -0
  44. package/dist/tsup/chunk-WNGOBAA7.js.map +1 -0
  45. package/dist/tsup/{chunk-INGJP237.js → chunk-YPZFLUO6.js} +103 -44
  46. package/dist/tsup/chunk-YPZFLUO6.js.map +1 -0
  47. package/dist/tsup/{chunk-6PDXBYI5.js → chunk-YW6Y6VNE.js} +8 -23
  48. package/dist/tsup/chunk-YW6Y6VNE.js.map +1 -0
  49. package/dist/tsup/client/mod.cjs +10 -10
  50. package/dist/tsup/client/mod.d.cts +7 -13
  51. package/dist/tsup/client/mod.d.ts +7 -13
  52. package/dist/tsup/client/mod.js +9 -9
  53. package/dist/tsup/common/log.cjs +12 -4
  54. package/dist/tsup/common/log.cjs.map +1 -1
  55. package/dist/tsup/common/log.d.cts +23 -17
  56. package/dist/tsup/common/log.d.ts +23 -17
  57. package/dist/tsup/common/log.js +15 -7
  58. package/dist/tsup/common/websocket.cjs +5 -5
  59. package/dist/tsup/common/websocket.js +4 -4
  60. package/dist/tsup/{common-CpqORuCq.d.cts → common-CXCe7s6i.d.cts} +2 -2
  61. package/dist/tsup/{common-CpqORuCq.d.ts → common-CXCe7s6i.d.ts} +2 -2
  62. package/dist/tsup/{connection-BwUMoe6n.d.ts → connection-BvE-Oq7t.d.ts} +215 -234
  63. package/dist/tsup/{connection-BR_Ve4ku.d.cts → connection-DTzmWwU5.d.cts} +215 -234
  64. package/dist/tsup/driver-helpers/mod.cjs +6 -9
  65. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  66. package/dist/tsup/driver-helpers/mod.d.cts +5 -6
  67. package/dist/tsup/driver-helpers/mod.d.ts +5 -6
  68. package/dist/tsup/driver-helpers/mod.js +6 -9
  69. package/dist/tsup/driver-test-suite/mod.cjs +615 -1357
  70. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  71. package/dist/tsup/driver-test-suite/mod.d.cts +12 -6
  72. package/dist/tsup/driver-test-suite/mod.d.ts +12 -6
  73. package/dist/tsup/driver-test-suite/mod.js +1334 -2076
  74. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  75. package/dist/tsup/inspector/mod.cjs +6 -8
  76. package/dist/tsup/inspector/mod.cjs.map +1 -1
  77. package/dist/tsup/inspector/mod.d.cts +3 -3
  78. package/dist/tsup/inspector/mod.d.ts +3 -3
  79. package/dist/tsup/inspector/mod.js +8 -10
  80. package/dist/tsup/mod.cjs +9 -15
  81. package/dist/tsup/mod.cjs.map +1 -1
  82. package/dist/tsup/mod.d.cts +47 -42
  83. package/dist/tsup/mod.d.ts +47 -42
  84. package/dist/tsup/mod.js +10 -16
  85. package/dist/tsup/{router-endpoints-DAbqVFx2.d.ts → router-endpoints-CctffZNL.d.cts} +2 -3
  86. package/dist/tsup/{router-endpoints-AYkXG8Tl.d.cts → router-endpoints-DFm1BglJ.d.ts} +2 -3
  87. package/dist/tsup/test/mod.cjs +10 -14
  88. package/dist/tsup/test/mod.cjs.map +1 -1
  89. package/dist/tsup/test/mod.d.cts +4 -5
  90. package/dist/tsup/test/mod.d.ts +4 -5
  91. package/dist/tsup/test/mod.js +9 -13
  92. package/dist/tsup/{utils-CT0cv4jd.d.ts → utils-fwx3o3K9.d.cts} +1 -0
  93. package/dist/tsup/{utils-CT0cv4jd.d.cts → utils-fwx3o3K9.d.ts} +1 -0
  94. package/dist/tsup/utils.cjs +5 -3
  95. package/dist/tsup/utils.cjs.map +1 -1
  96. package/dist/tsup/utils.d.cts +19 -2
  97. package/dist/tsup/utils.d.ts +19 -2
  98. package/dist/tsup/utils.js +4 -2
  99. package/package.json +6 -6
  100. package/src/actor/action.ts +1 -5
  101. package/src/actor/config.ts +27 -295
  102. package/src/actor/connection.ts +9 -12
  103. package/src/actor/context.ts +1 -4
  104. package/src/actor/definition.ts +7 -11
  105. package/src/actor/errors.ts +98 -36
  106. package/src/actor/generic-conn-driver.ts +28 -16
  107. package/src/actor/instance.ts +177 -133
  108. package/src/actor/log.ts +4 -13
  109. package/src/actor/mod.ts +0 -5
  110. package/src/actor/protocol/old.ts +42 -26
  111. package/src/actor/protocol/serde.ts +1 -1
  112. package/src/actor/router-endpoints.ts +47 -39
  113. package/src/actor/router.ts +22 -19
  114. package/src/actor/unstable-react.ts +1 -1
  115. package/src/actor/utils.ts +6 -2
  116. package/src/client/actor-common.ts +1 -1
  117. package/src/client/actor-conn.ts +152 -91
  118. package/src/client/actor-handle.ts +85 -25
  119. package/src/client/actor-query.ts +65 -0
  120. package/src/client/client.ts +29 -98
  121. package/src/client/config.ts +44 -0
  122. package/src/client/errors.ts +1 -0
  123. package/src/client/log.ts +2 -4
  124. package/src/client/mod.ts +16 -12
  125. package/src/client/raw-utils.ts +82 -25
  126. package/src/client/utils.ts +5 -3
  127. package/src/common/fake-event-source.ts +10 -9
  128. package/src/common/inline-websocket-adapter2.ts +39 -30
  129. package/src/common/log.ts +176 -101
  130. package/src/common/logfmt.ts +21 -30
  131. package/src/common/router.ts +12 -19
  132. package/src/common/utils.ts +27 -13
  133. package/src/common/websocket.ts +0 -1
  134. package/src/driver-helpers/mod.ts +1 -1
  135. package/src/driver-test-suite/log.ts +1 -3
  136. package/src/driver-test-suite/mod.ts +87 -61
  137. package/src/driver-test-suite/test-inline-client-driver.ts +441 -255
  138. package/src/driver-test-suite/tests/actor-error-handling.ts +4 -12
  139. package/src/driver-test-suite/tests/actor-handle.ts +33 -0
  140. package/src/driver-test-suite/tests/actor-inspector.ts +2 -1
  141. package/src/driver-test-suite/tests/manager-driver.ts +5 -3
  142. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -226
  143. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -392
  144. package/src/driver-test-suite/tests/request-access.ts +112 -126
  145. package/src/driver-test-suite/utils.ts +10 -6
  146. package/src/drivers/default.ts +7 -4
  147. package/src/drivers/engine/actor-driver.ts +22 -13
  148. package/src/drivers/engine/config.ts +2 -10
  149. package/src/drivers/engine/kv.ts +1 -1
  150. package/src/drivers/engine/log.ts +1 -3
  151. package/src/drivers/engine/mod.ts +2 -3
  152. package/src/drivers/file-system/actor.ts +1 -1
  153. package/src/drivers/file-system/global-state.ts +36 -21
  154. package/src/drivers/file-system/log.ts +1 -3
  155. package/src/drivers/file-system/manager.ts +33 -15
  156. package/src/inspector/config.ts +9 -4
  157. package/src/inspector/log.ts +1 -1
  158. package/src/inspector/manager.ts +2 -2
  159. package/src/inspector/utils.ts +1 -1
  160. package/src/manager/driver.ts +10 -2
  161. package/src/manager/hono-websocket-adapter.ts +21 -12
  162. package/src/manager/log.ts +2 -4
  163. package/src/manager/mod.ts +1 -1
  164. package/src/manager/router.ts +378 -1390
  165. package/src/manager-api/routes/actors-create.ts +16 -0
  166. package/src/manager-api/routes/actors-delete.ts +4 -0
  167. package/src/manager-api/routes/actors-get-by-id.ts +7 -0
  168. package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
  169. package/src/manager-api/routes/actors-get.ts +7 -0
  170. package/src/manager-api/routes/common.ts +18 -0
  171. package/src/mod.ts +0 -2
  172. package/src/registry/config.ts +1 -1
  173. package/src/registry/log.ts +2 -4
  174. package/src/registry/mod.ts +63 -34
  175. package/src/registry/run-config.ts +39 -26
  176. package/src/registry/serve.ts +4 -5
  177. package/src/remote-manager-driver/actor-http-client.ts +74 -0
  178. package/src/remote-manager-driver/actor-websocket-client.ts +64 -0
  179. package/src/remote-manager-driver/api-endpoints.ts +79 -0
  180. package/src/remote-manager-driver/api-utils.ts +46 -0
  181. package/src/remote-manager-driver/log.ts +5 -0
  182. package/src/remote-manager-driver/mod.ts +275 -0
  183. package/src/{drivers/engine → remote-manager-driver}/ws-proxy.ts +24 -14
  184. package/src/serde.ts +8 -2
  185. package/src/test/log.ts +1 -3
  186. package/src/test/mod.ts +17 -16
  187. package/src/utils.ts +53 -0
  188. package/dist/tsup/chunk-2CRLFV6Z.cjs +0 -202
  189. package/dist/tsup/chunk-2CRLFV6Z.cjs.map +0 -1
  190. package/dist/tsup/chunk-3H7O2A7I.js.map +0 -1
  191. package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
  192. package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
  193. package/dist/tsup/chunk-4NSUQZ2H.js.map +0 -1
  194. package/dist/tsup/chunk-6PDXBYI5.js.map +0 -1
  195. package/dist/tsup/chunk-6WKQDDUD.cjs.map +0 -1
  196. package/dist/tsup/chunk-CTBOSFUH.cjs +0 -116
  197. package/dist/tsup/chunk-CTBOSFUH.cjs.map +0 -1
  198. package/dist/tsup/chunk-EGVZZFE2.js +0 -2857
  199. package/dist/tsup/chunk-EGVZZFE2.js.map +0 -1
  200. package/dist/tsup/chunk-FCCPJNMA.cjs.map +0 -1
  201. package/dist/tsup/chunk-FLMTTN27.js.map +0 -1
  202. package/dist/tsup/chunk-GIR3AFFI.cjs.map +0 -1
  203. package/dist/tsup/chunk-INGJP237.js.map +0 -1
  204. package/dist/tsup/chunk-KJCJLKRM.js +0 -116
  205. package/dist/tsup/chunk-KJCJLKRM.js.map +0 -1
  206. package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
  207. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
  208. package/dist/tsup/chunk-O2MBYIXO.cjs +0 -2857
  209. package/dist/tsup/chunk-O2MBYIXO.cjs.map +0 -1
  210. package/dist/tsup/chunk-OGAPU3UG.cjs.map +0 -1
  211. package/dist/tsup/chunk-OV6AYD4S.js +0 -4406
  212. package/dist/tsup/chunk-OV6AYD4S.js.map +0 -1
  213. package/dist/tsup/chunk-PO4VLDWA.js.map +0 -1
  214. package/dist/tsup/chunk-R2OPSKIV.cjs.map +0 -1
  215. package/dist/tsup/chunk-TZJKSBUQ.cjs.map +0 -1
  216. package/dist/tsup/chunk-UBUC5C3G.cjs +0 -189
  217. package/dist/tsup/chunk-UBUC5C3G.cjs.map +0 -1
  218. package/dist/tsup/chunk-UIM22YJL.cjs +0 -4406
  219. package/dist/tsup/chunk-UIM22YJL.cjs.map +0 -1
  220. package/dist/tsup/chunk-URVFQMYI.cjs +0 -230
  221. package/dist/tsup/chunk-URVFQMYI.cjs.map +0 -1
  222. package/dist/tsup/chunk-UVUPOS46.js +0 -230
  223. package/dist/tsup/chunk-UVUPOS46.js.map +0 -1
  224. package/dist/tsup/chunk-VRRHBNJC.js +0 -189
  225. package/dist/tsup/chunk-VRRHBNJC.js.map +0 -1
  226. package/dist/tsup/chunk-XFSS33EQ.js +0 -202
  227. package/dist/tsup/chunk-XFSS33EQ.js.map +0 -1
  228. package/src/client/http-client-driver.ts +0 -326
  229. package/src/driver-test-suite/tests/actor-auth.ts +0 -591
  230. package/src/drivers/engine/api-endpoints.ts +0 -128
  231. package/src/drivers/engine/api-utils.ts +0 -70
  232. package/src/drivers/engine/manager-driver.ts +0 -391
  233. package/src/inline-client-driver/log.ts +0 -7
  234. package/src/inline-client-driver/mod.ts +0 -385
  235. package/src/manager/auth.ts +0 -121
  236. /package/src/{drivers/engine → actor}/keys.test.ts +0 -0
  237. /package/src/{drivers/engine → actor}/keys.ts +0 -0
@@ -1,392 +1,393 @@
1
- import { describe, expect, test } from "vitest";
2
- import { importWebSocket } from "@/common/websocket";
3
- import type { ActorQuery } from "@/manager/protocol/query";
4
- import type { DriverTestConfig } from "../mod";
5
- import { setupDriverTest } from "../utils";
6
-
7
- export function runRawWebSocketDirectRegistryTests(
8
- driverTestConfig: DriverTestConfig,
9
- ) {
10
- describe("raw websocket - direct registry access", () => {
11
- test("should establish vanilla WebSocket connection with proper subprotocols", async (c) => {
12
- const { endpoint } = await setupDriverTest(c, driverTestConfig);
13
- const WebSocket = await importWebSocket();
14
-
15
- // Build the actor query
16
- const actorQuery: ActorQuery = {
17
- getOrCreateForKey: {
18
- name: "rawWebSocketActor",
19
- key: ["vanilla-test"],
20
- },
21
- };
22
-
23
- // Encode query as WebSocket subprotocol
24
- const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
25
-
26
- // Build WebSocket URL (convert http to ws)
27
- const wsEndpoint = endpoint
28
- .replace(/^http:/, "ws:")
29
- .replace(/^https:/, "wss:");
30
- const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
31
-
32
- // Create WebSocket connection with subprotocol
33
- const ws = new WebSocket(wsUrl, [
34
- queryProtocol,
35
- // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
36
- "rivetkit",
37
- ]) as any;
38
-
39
- await new Promise<void>((resolve, reject) => {
40
- ws.addEventListener("open", () => {
41
- resolve();
42
- });
43
- ws.addEventListener("error", reject);
44
- ws.addEventListener("close", reject);
45
- });
46
-
47
- // Should receive welcome message
48
- const welcomeMessage = await new Promise<any>((resolve, reject) => {
49
- ws.addEventListener(
50
- "message",
51
- (event: any) => {
52
- resolve(JSON.parse(event.data as string));
53
- },
54
- { once: true },
55
- );
56
- ws.addEventListener("close", reject);
57
- });
58
-
59
- expect(welcomeMessage.type).toBe("welcome");
60
- expect(welcomeMessage.connectionCount).toBe(1);
61
-
62
- ws.close();
63
- });
64
-
65
- test("should echo messages with vanilla WebSocket", async (c) => {
66
- const { endpoint } = await setupDriverTest(c, driverTestConfig);
67
- const WebSocket = await importWebSocket();
68
-
69
- const actorQuery: ActorQuery = {
70
- getOrCreateForKey: {
71
- name: "rawWebSocketActor",
72
- key: ["vanilla-echo"],
73
- },
74
- };
75
-
76
- const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
77
-
78
- const wsEndpoint = endpoint
79
- .replace(/^http:/, "ws:")
80
- .replace(/^https:/, "wss:");
81
- const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
82
-
83
- const ws = new WebSocket(wsUrl, [
84
- queryProtocol,
85
- // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
86
- "rivetkit",
87
- ]) as any;
88
-
89
- await new Promise<void>((resolve, reject) => {
90
- ws.addEventListener("open", () => resolve(), { once: true });
91
- ws.addEventListener("close", reject);
92
- });
93
-
94
- // Skip welcome message
95
- await new Promise<void>((resolve, reject) => {
96
- ws.addEventListener("message", () => resolve(), { once: true });
97
- ws.addEventListener("close", reject);
98
- });
99
-
100
- // Send and receive echo
101
- const testMessage = { test: "vanilla", timestamp: Date.now() };
102
- ws.send(JSON.stringify(testMessage));
103
-
104
- const echoMessage = await new Promise<any>((resolve, reject) => {
105
- ws.addEventListener(
106
- "message",
107
- (event: any) => {
108
- resolve(JSON.parse(event.data as string));
109
- },
110
- { once: true },
111
- );
112
- ws.addEventListener("close", reject);
113
- });
114
-
115
- expect(echoMessage).toEqual(testMessage);
116
-
117
- ws.close();
118
- });
119
-
120
- test("should handle connection parameters for authentication", async (c) => {
121
- const { endpoint } = await setupDriverTest(c, driverTestConfig);
122
- const WebSocket = await importWebSocket();
123
-
124
- const actorQuery: ActorQuery = {
125
- getOrCreateForKey: {
126
- name: "rawWebSocketActor",
127
- key: ["vanilla-auth"],
128
- },
129
- };
130
-
131
- const connParams = { token: "ws-auth-token", userId: "ws-user123" };
132
-
133
- // Encode both query and connection params as subprotocols
134
- const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
135
- const connParamsProtocol = `conn_params.${encodeURIComponent(JSON.stringify(connParams))}`;
136
-
137
- const wsEndpoint = endpoint
138
- .replace(/^http:/, "ws:")
139
- .replace(/^https:/, "wss:");
140
- const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
141
-
142
- const ws = new WebSocket(wsUrl, [
143
- queryProtocol,
144
- connParamsProtocol,
145
- // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
146
- "rivetkit",
147
- ]) as any;
148
-
149
- await new Promise<void>((resolve, reject) => {
150
- ws.addEventListener("open", () => {
151
- resolve();
152
- });
153
- ws.addEventListener("error", reject);
154
- ws.addEventListener("close", reject);
155
- });
156
-
157
- // Connection should succeed with auth params
158
- const welcomeMessage = await new Promise<any>((resolve, reject) => {
159
- ws.addEventListener(
160
- "message",
161
- (event: any) => {
162
- resolve(JSON.parse(event.data as string));
163
- },
164
- { once: true },
165
- );
166
- ws.addEventListener("close", reject);
167
- });
168
-
169
- expect(welcomeMessage.type).toBe("welcome");
170
-
171
- ws.close();
172
- });
173
-
174
- test("should handle custom user protocols alongside rivetkit protocols", async (c) => {
175
- const { endpoint } = await setupDriverTest(c, driverTestConfig);
176
- const WebSocket = await importWebSocket();
177
-
178
- const actorQuery: ActorQuery = {
179
- getOrCreateForKey: {
180
- name: "rawWebSocketActor",
181
- key: ["vanilla-protocols"],
182
- },
183
- };
184
-
185
- // Include user-defined protocols
186
- const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
187
- const userProtocol1 = "chat-v1";
188
- const userProtocol2 = "custom-protocol";
189
-
190
- const wsEndpoint = endpoint
191
- .replace(/^http:/, "ws:")
192
- .replace(/^https:/, "wss:");
193
- const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
194
-
195
- const ws = new WebSocket(wsUrl, [
196
- queryProtocol,
197
- userProtocol1,
198
- userProtocol2,
199
- // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
200
- "rivetkit",
201
- ]) as any;
202
-
203
- await new Promise<void>((resolve, reject) => {
204
- ws.addEventListener("open", () => {
205
- resolve();
206
- });
207
- ws.addEventListener("error", reject);
208
- ws.addEventListener("close", reject);
209
- });
210
-
211
- // Should connect successfully with custom protocols
212
- const welcomeMessage = await new Promise<any>((resolve, reject) => {
213
- ws.addEventListener(
214
- "message",
215
- (event: any) => {
216
- resolve(JSON.parse(event.data as string));
217
- },
218
- { once: true },
219
- );
220
- ws.addEventListener("close", reject);
221
- });
222
-
223
- expect(welcomeMessage.type).toBe("welcome");
224
-
225
- ws.close();
226
- });
227
-
228
- test("should handle different paths for WebSocket routes", async (c) => {
229
- const { endpoint } = await setupDriverTest(c, driverTestConfig);
230
- const WebSocket = await importWebSocket();
231
-
232
- const actorQuery: ActorQuery = {
233
- getOrCreateForKey: {
234
- name: "rawWebSocketActor",
235
- key: ["vanilla-paths"],
236
- },
237
- };
238
-
239
- const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
240
-
241
- const wsEndpoint = endpoint
242
- .replace(/^http:/, "ws:")
243
- .replace(/^https:/, "wss:");
244
-
245
- // Test different paths
246
- const paths = ["chat/room1", "updates/feed", "stream/events"];
247
-
248
- for (const path of paths) {
249
- const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/${path}`;
250
- const ws = new WebSocket(wsUrl, [
251
- queryProtocol,
252
- // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
253
- "rivetkit",
254
- ]) as any;
255
-
256
- await new Promise<void>((resolve, reject) => {
257
- ws.addEventListener("open", () => {
258
- resolve();
259
- });
260
- ws.addEventListener("error", reject);
261
- });
262
-
263
- // Should receive welcome message with the path
264
- const welcomeMessage = await new Promise<any>((resolve, reject) => {
265
- ws.addEventListener(
266
- "message",
267
- (event: any) => {
268
- resolve(JSON.parse(event.data as string));
269
- },
270
- { once: true },
271
- );
272
- ws.addEventListener("close", reject);
273
- });
274
-
275
- expect(welcomeMessage.type).toBe("welcome");
276
-
277
- ws.close();
278
- }
279
- });
280
-
281
- test("should return error for actors without onWebSocket handler", async (c) => {
282
- const { endpoint } = await setupDriverTest(c, driverTestConfig);
283
- const WebSocket = await importWebSocket();
284
-
285
- const actorQuery: ActorQuery = {
286
- getOrCreateForKey: {
287
- name: "rawWebSocketNoHandlerActor",
288
- key: ["vanilla-no-handler"],
289
- },
290
- };
291
-
292
- const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
293
-
294
- const wsEndpoint = endpoint
295
- .replace(/^http:/, "ws:")
296
- .replace(/^https:/, "wss:");
297
- const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
298
-
299
- const ws = new WebSocket(wsUrl, [
300
- queryProtocol,
301
-
302
- // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
303
- "rivetkit",
304
- ]) as any;
305
-
306
- // Should fail to connect
307
- await new Promise<void>((resolve) => {
308
- ws.addEventListener("error", () => resolve(), { once: true });
309
- ws.addEventListener("close", () => resolve(), { once: true });
310
- });
311
-
312
- expect(ws.readyState).toBe(ws.CLOSED || 3); // WebSocket.CLOSED
313
- });
314
-
315
- test("should handle binary data over vanilla WebSocket", async (c) => {
316
- const { endpoint } = await setupDriverTest(c, driverTestConfig);
317
- const WebSocket = await importWebSocket();
318
-
319
- const actorQuery: ActorQuery = {
320
- getOrCreateForKey: {
321
- name: "rawWebSocketActor",
322
- key: ["vanilla-binary"],
323
- },
324
- };
325
-
326
- const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
327
-
328
- const wsEndpoint = endpoint
329
- .replace(/^http:/, "ws:")
330
- .replace(/^https:/, "wss:");
331
- const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
332
-
333
- const ws = new WebSocket(wsUrl, [
334
- queryProtocol,
335
- // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
336
- "rivetkit",
337
- ]) as any;
338
- ws.binaryType = "arraybuffer";
339
-
340
- await new Promise<void>((resolve, reject) => {
341
- ws.addEventListener("open", () => resolve(), { once: true });
342
- ws.addEventListener("close", reject);
343
- });
344
-
345
- // Skip welcome message
346
- await new Promise<void>((resolve, reject) => {
347
- ws.addEventListener("message", () => resolve(), { once: true });
348
- ws.addEventListener("close", reject);
349
- });
350
-
351
- // Send binary data
352
- const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
353
- ws.send(binaryData.buffer);
354
-
355
- // Receive echoed binary data
356
- const echoedData = await new Promise<ArrayBuffer>((resolve, reject) => {
357
- ws.addEventListener(
358
- "message",
359
- (event: any) => {
360
- // The actor echoes binary data back as-is
361
- resolve(event.data as ArrayBuffer);
362
- },
363
- { once: true },
364
- );
365
- ws.addEventListener("close", reject);
366
- });
367
-
368
- // Verify the echoed data matches what we sent
369
- const echoedArray = new Uint8Array(echoedData);
370
- expect(Array.from(echoedArray)).toEqual([1, 2, 3, 4, 5]);
371
-
372
- // Now test JSON echo
373
- ws.send(JSON.stringify({ type: "binary-test", size: binaryData.length }));
374
-
375
- const echoMessage = await new Promise<any>((resolve, reject) => {
376
- ws.addEventListener(
377
- "message",
378
- (event: any) => {
379
- resolve(JSON.parse(event.data as string));
380
- },
381
- { once: true },
382
- );
383
- ws.addEventListener("close", reject);
384
- });
385
-
386
- expect(echoMessage.type).toBe("binary-test");
387
- expect(echoMessage.size).toBe(5);
388
-
389
- ws.close();
390
- });
391
- });
392
- }
1
+ // TODO: re-expose this once we can have actor queries on the gateway
2
+ // import { describe, expect, test } from "vitest";
3
+ // import { importWebSocket } from "@/common/websocket";
4
+ // import type { ActorQuery } from "@/manager/protocol/query";
5
+ // import type { DriverTestConfig } from "../mod";
6
+ // import { setupDriverTest } from "../utils";
7
+ //
8
+ // export function runRawWebSocketDirectRegistryTests(
9
+ // driverTestConfig: DriverTestConfig,
10
+ // ) {
11
+ // describe("raw websocket - direct registry access", () => {
12
+ // test("should establish vanilla WebSocket connection with proper subprotocols", async (c) => {
13
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
14
+ // const WebSocket = await importWebSocket();
15
+ //
16
+ // // Build the actor query
17
+ // const actorQuery: ActorQuery = {
18
+ // getOrCreateForKey: {
19
+ // name: "rawWebSocketActor",
20
+ // key: ["vanilla-test"],
21
+ // },
22
+ // };
23
+ //
24
+ // // Encode query as WebSocket subprotocol
25
+ // const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
26
+ //
27
+ // // Build WebSocket URL (convert http to ws)
28
+ // const wsEndpoint = endpoint
29
+ // .replace(/^http:/, "ws:")
30
+ // .replace(/^https:/, "wss:");
31
+ // const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
32
+ //
33
+ // // Create WebSocket connection with subprotocol
34
+ // const ws = new WebSocket(wsUrl, [
35
+ // queryProtocol,
36
+ // // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
37
+ // "rivetkit",
38
+ // ]) as any;
39
+ //
40
+ // await new Promise<void>((resolve, reject) => {
41
+ // ws.addEventListener("open", () => {
42
+ // resolve();
43
+ // });
44
+ // ws.addEventListener("error", reject);
45
+ // ws.addEventListener("close", reject);
46
+ // });
47
+ //
48
+ // // Should receive welcome message
49
+ // const welcomeMessage = await new Promise<any>((resolve, reject) => {
50
+ // ws.addEventListener(
51
+ // "message",
52
+ // (event: any) => {
53
+ // resolve(JSON.parse(event.data as string));
54
+ // },
55
+ // { once: true },
56
+ // );
57
+ // ws.addEventListener("close", reject);
58
+ // });
59
+ //
60
+ // expect(welcomeMessage.type).toBe("welcome");
61
+ // expect(welcomeMessage.connectionCount).toBe(1);
62
+ //
63
+ // ws.close();
64
+ // });
65
+ //
66
+ // test("should echo messages with vanilla WebSocket", async (c) => {
67
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
68
+ // const WebSocket = await importWebSocket();
69
+ //
70
+ // const actorQuery: ActorQuery = {
71
+ // getOrCreateForKey: {
72
+ // name: "rawWebSocketActor",
73
+ // key: ["vanilla-echo"],
74
+ // },
75
+ // };
76
+ //
77
+ // const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
78
+ //
79
+ // const wsEndpoint = endpoint
80
+ // .replace(/^http:/, "ws:")
81
+ // .replace(/^https:/, "wss:");
82
+ // const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
83
+ //
84
+ // const ws = new WebSocket(wsUrl, [
85
+ // queryProtocol,
86
+ // // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
87
+ // "rivetkit",
88
+ // ]) as any;
89
+ //
90
+ // await new Promise<void>((resolve, reject) => {
91
+ // ws.addEventListener("open", () => resolve(), { once: true });
92
+ // ws.addEventListener("close", reject);
93
+ // });
94
+ //
95
+ // // Skip welcome message
96
+ // await new Promise<void>((resolve, reject) => {
97
+ // ws.addEventListener("message", () => resolve(), { once: true });
98
+ // ws.addEventListener("close", reject);
99
+ // });
100
+ //
101
+ // // Send and receive echo
102
+ // const testMessage = { test: "vanilla", timestamp: Date.now() };
103
+ // ws.send(JSON.stringify(testMessage));
104
+ //
105
+ // const echoMessage = await new Promise<any>((resolve, reject) => {
106
+ // ws.addEventListener(
107
+ // "message",
108
+ // (event: any) => {
109
+ // resolve(JSON.parse(event.data as string));
110
+ // },
111
+ // { once: true },
112
+ // );
113
+ // ws.addEventListener("close", reject);
114
+ // });
115
+ //
116
+ // expect(echoMessage).toEqual(testMessage);
117
+ //
118
+ // ws.close();
119
+ // });
120
+ //
121
+ // test("should handle connection parameters for authentication", async (c) => {
122
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
123
+ // const WebSocket = await importWebSocket();
124
+ //
125
+ // const actorQuery: ActorQuery = {
126
+ // getOrCreateForKey: {
127
+ // name: "rawWebSocketActor",
128
+ // key: ["vanilla-auth"],
129
+ // },
130
+ // };
131
+ //
132
+ // const connParams = { token: "ws-auth-token", userId: "ws-user123" };
133
+ //
134
+ // // Encode both query and connection params as subprotocols
135
+ // const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
136
+ // const connParamsProtocol = `conn_params.${encodeURIComponent(JSON.stringify(connParams))}`;
137
+ //
138
+ // const wsEndpoint = endpoint
139
+ // .replace(/^http:/, "ws:")
140
+ // .replace(/^https:/, "wss:");
141
+ // const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
142
+ //
143
+ // const ws = new WebSocket(wsUrl, [
144
+ // queryProtocol,
145
+ // connParamsProtocol,
146
+ // // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
147
+ // "rivetkit",
148
+ // ]) as any;
149
+ //
150
+ // await new Promise<void>((resolve, reject) => {
151
+ // ws.addEventListener("open", () => {
152
+ // resolve();
153
+ // });
154
+ // ws.addEventListener("error", reject);
155
+ // ws.addEventListener("close", reject);
156
+ // });
157
+ //
158
+ // // Connection should succeed with auth params
159
+ // const welcomeMessage = await new Promise<any>((resolve, reject) => {
160
+ // ws.addEventListener(
161
+ // "message",
162
+ // (event: any) => {
163
+ // resolve(JSON.parse(event.data as string));
164
+ // },
165
+ // { once: true },
166
+ // );
167
+ // ws.addEventListener("close", reject);
168
+ // });
169
+ //
170
+ // expect(welcomeMessage.type).toBe("welcome");
171
+ //
172
+ // ws.close();
173
+ // });
174
+ //
175
+ // test("should handle custom user protocols alongside rivetkit protocols", async (c) => {
176
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
177
+ // const WebSocket = await importWebSocket();
178
+ //
179
+ // const actorQuery: ActorQuery = {
180
+ // getOrCreateForKey: {
181
+ // name: "rawWebSocketActor",
182
+ // key: ["vanilla-protocols"],
183
+ // },
184
+ // };
185
+ //
186
+ // // Include user-defined protocols
187
+ // const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
188
+ // const userProtocol1 = "chat-v1";
189
+ // const userProtocol2 = "custom-protocol";
190
+ //
191
+ // const wsEndpoint = endpoint
192
+ // .replace(/^http:/, "ws:")
193
+ // .replace(/^https:/, "wss:");
194
+ // const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
195
+ //
196
+ // const ws = new WebSocket(wsUrl, [
197
+ // queryProtocol,
198
+ // userProtocol1,
199
+ // userProtocol2,
200
+ // // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
201
+ // "rivetkit",
202
+ // ]) as any;
203
+ //
204
+ // await new Promise<void>((resolve, reject) => {
205
+ // ws.addEventListener("open", () => {
206
+ // resolve();
207
+ // });
208
+ // ws.addEventListener("error", reject);
209
+ // ws.addEventListener("close", reject);
210
+ // });
211
+ //
212
+ // // Should connect successfully with custom protocols
213
+ // const welcomeMessage = await new Promise<any>((resolve, reject) => {
214
+ // ws.addEventListener(
215
+ // "message",
216
+ // (event: any) => {
217
+ // resolve(JSON.parse(event.data as string));
218
+ // },
219
+ // { once: true },
220
+ // );
221
+ // ws.addEventListener("close", reject);
222
+ // });
223
+ //
224
+ // expect(welcomeMessage.type).toBe("welcome");
225
+ //
226
+ // ws.close();
227
+ // });
228
+ //
229
+ // test("should handle different paths for WebSocket routes", async (c) => {
230
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
231
+ // const WebSocket = await importWebSocket();
232
+ //
233
+ // const actorQuery: ActorQuery = {
234
+ // getOrCreateForKey: {
235
+ // name: "rawWebSocketActor",
236
+ // key: ["vanilla-paths"],
237
+ // },
238
+ // };
239
+ //
240
+ // const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
241
+ //
242
+ // const wsEndpoint = endpoint
243
+ // .replace(/^http:/, "ws:")
244
+ // .replace(/^https:/, "wss:");
245
+ //
246
+ // // Test different paths
247
+ // const paths = ["chat/room1", "updates/feed", "stream/events"];
248
+ //
249
+ // for (const path of paths) {
250
+ // const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/${path}`;
251
+ // const ws = new WebSocket(wsUrl, [
252
+ // queryProtocol,
253
+ // // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
254
+ // "rivetkit",
255
+ // ]) as any;
256
+ //
257
+ // await new Promise<void>((resolve, reject) => {
258
+ // ws.addEventListener("open", () => {
259
+ // resolve();
260
+ // });
261
+ // ws.addEventListener("error", reject);
262
+ // });
263
+ //
264
+ // // Should receive welcome message with the path
265
+ // const welcomeMessage = await new Promise<any>((resolve, reject) => {
266
+ // ws.addEventListener(
267
+ // "message",
268
+ // (event: any) => {
269
+ // resolve(JSON.parse(event.data as string));
270
+ // },
271
+ // { once: true },
272
+ // );
273
+ // ws.addEventListener("close", reject);
274
+ // });
275
+ //
276
+ // expect(welcomeMessage.type).toBe("welcome");
277
+ //
278
+ // ws.close();
279
+ // }
280
+ // });
281
+ //
282
+ // test("should return error for actors without onWebSocket handler", async (c) => {
283
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
284
+ // const WebSocket = await importWebSocket();
285
+ //
286
+ // const actorQuery: ActorQuery = {
287
+ // getOrCreateForKey: {
288
+ // name: "rawWebSocketNoHandlerActor",
289
+ // key: ["vanilla-no-handler"],
290
+ // },
291
+ // };
292
+ //
293
+ // const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
294
+ //
295
+ // const wsEndpoint = endpoint
296
+ // .replace(/^http:/, "ws:")
297
+ // .replace(/^https:/, "wss:");
298
+ // const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
299
+ //
300
+ // const ws = new WebSocket(wsUrl, [
301
+ // queryProtocol,
302
+ //
303
+ // // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
304
+ // "rivetkit",
305
+ // ]) as any;
306
+ //
307
+ // // Should fail to connect
308
+ // await new Promise<void>((resolve) => {
309
+ // ws.addEventListener("error", () => resolve(), { once: true });
310
+ // ws.addEventListener("close", () => resolve(), { once: true });
311
+ // });
312
+ //
313
+ // expect(ws.readyState).toBe(ws.CLOSED || 3); // WebSocket.CLOSED
314
+ // });
315
+ //
316
+ // test("should handle binary data over vanilla WebSocket", async (c) => {
317
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
318
+ // const WebSocket = await importWebSocket();
319
+ //
320
+ // const actorQuery: ActorQuery = {
321
+ // getOrCreateForKey: {
322
+ // name: "rawWebSocketActor",
323
+ // key: ["vanilla-binary"],
324
+ // },
325
+ // };
326
+ //
327
+ // const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
328
+ //
329
+ // const wsEndpoint = endpoint
330
+ // .replace(/^http:/, "ws:")
331
+ // .replace(/^https:/, "wss:");
332
+ // const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
333
+ //
334
+ // const ws = new WebSocket(wsUrl, [
335
+ // queryProtocol,
336
+ // // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
337
+ // "rivetkit",
338
+ // ]) as any;
339
+ // ws.binaryType = "arraybuffer";
340
+ //
341
+ // await new Promise<void>((resolve, reject) => {
342
+ // ws.addEventListener("open", () => resolve(), { once: true });
343
+ // ws.addEventListener("close", reject);
344
+ // });
345
+ //
346
+ // // Skip welcome message
347
+ // await new Promise<void>((resolve, reject) => {
348
+ // ws.addEventListener("message", () => resolve(), { once: true });
349
+ // ws.addEventListener("close", reject);
350
+ // });
351
+ //
352
+ // // Send binary data
353
+ // const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
354
+ // ws.send(binaryData.buffer);
355
+ //
356
+ // // Receive echoed binary data
357
+ // const echoedData = await new Promise<ArrayBuffer>((resolve, reject) => {
358
+ // ws.addEventListener(
359
+ // "message",
360
+ // (event: any) => {
361
+ // // The actor echoes binary data back as-is
362
+ // resolve(event.data as ArrayBuffer);
363
+ // },
364
+ // { once: true },
365
+ // );
366
+ // ws.addEventListener("close", reject);
367
+ // });
368
+ //
369
+ // // Verify the echoed data matches what we sent
370
+ // const echoedArray = new Uint8Array(echoedData);
371
+ // expect(Array.from(echoedArray)).toEqual([1, 2, 3, 4, 5]);
372
+ //
373
+ // // Now test JSON echo
374
+ // ws.send(JSON.stringify({ type: "binary-test", size: binaryData.length }));
375
+ //
376
+ // const echoMessage = await new Promise<any>((resolve, reject) => {
377
+ // ws.addEventListener(
378
+ // "message",
379
+ // (event: any) => {
380
+ // resolve(JSON.parse(event.data as string));
381
+ // },
382
+ // { once: true },
383
+ // );
384
+ // ws.addEventListener("close", reject);
385
+ // });
386
+ //
387
+ // expect(echoMessage.type).toBe("binary-test");
388
+ // expect(echoMessage.size).toBe(5);
389
+ //
390
+ // ws.close();
391
+ // });
392
+ // });
393
+ // }