rivetkit 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +11 -0
  2. package/dist/schemas/actor-persist/v1.ts +21 -24
  3. package/dist/schemas/client-protocol/v1.ts +6 -0
  4. package/dist/tsup/actor/errors.cjs +10 -2
  5. package/dist/tsup/actor/errors.cjs.map +1 -1
  6. package/dist/tsup/actor/errors.d.cts +17 -4
  7. package/dist/tsup/actor/errors.d.ts +17 -4
  8. package/dist/tsup/actor/errors.js +11 -3
  9. package/dist/tsup/{chunk-6PDXBYI5.js → chunk-3F2YSRJL.js} +8 -23
  10. package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
  11. package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
  12. package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
  13. package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
  14. package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
  15. package/dist/tsup/{chunk-OGAPU3UG.cjs → chunk-6LJT3QRL.cjs} +39 -25
  16. package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
  17. package/dist/tsup/{chunk-6WKQDDUD.cjs → chunk-GICQ3YCU.cjs} +143 -141
  18. package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
  19. package/dist/tsup/{chunk-FLMTTN27.js → chunk-H26RP6GD.js} +15 -8
  20. package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
  21. package/dist/tsup/chunk-HI3HWJRC.js +20 -0
  22. package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
  23. package/dist/tsup/{chunk-4NSUQZ2H.js → chunk-HLLF4B4Q.js} +116 -114
  24. package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
  25. package/dist/tsup/{chunk-FCCPJNMA.cjs → chunk-IH6CKNDW.cjs} +12 -27
  26. package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
  27. package/dist/tsup/chunk-LV2S3OU3.js +250 -0
  28. package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
  29. package/dist/tsup/{chunk-R2OPSKIV.cjs → chunk-LWNKVZG5.cjs} +20 -13
  30. package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
  31. package/dist/tsup/{chunk-INGJP237.js → chunk-NFU2BBT5.js} +102 -43
  32. package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
  33. package/dist/tsup/{chunk-3H7O2A7I.js → chunk-PQY7KKTL.js} +33 -19
  34. package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
  35. package/dist/tsup/{chunk-PO4VLDWA.js → chunk-QK72M5JB.js} +3 -5
  36. package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
  37. package/dist/tsup/{chunk-TZJKSBUQ.cjs → chunk-QNNXFOQV.cjs} +3 -5
  38. package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
  39. package/dist/tsup/{chunk-GIR3AFFI.cjs → chunk-SBHHJ6QS.cjs} +102 -43
  40. package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
  41. package/dist/tsup/chunk-TQ62L3X7.js +325 -0
  42. package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
  43. package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
  44. package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
  45. package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
  46. package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
  47. package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
  48. package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
  49. package/dist/tsup/client/mod.cjs +10 -10
  50. package/dist/tsup/client/mod.d.cts +7 -13
  51. package/dist/tsup/client/mod.d.ts +7 -13
  52. package/dist/tsup/client/mod.js +9 -9
  53. package/dist/tsup/common/log.cjs +12 -4
  54. package/dist/tsup/common/log.cjs.map +1 -1
  55. package/dist/tsup/common/log.d.cts +23 -17
  56. package/dist/tsup/common/log.d.ts +23 -17
  57. package/dist/tsup/common/log.js +15 -7
  58. package/dist/tsup/common/websocket.cjs +5 -5
  59. package/dist/tsup/common/websocket.js +4 -4
  60. package/dist/tsup/{common-CpqORuCq.d.cts → common-CXCe7s6i.d.cts} +2 -2
  61. package/dist/tsup/{common-CpqORuCq.d.ts → common-CXCe7s6i.d.ts} +2 -2
  62. package/dist/tsup/{connection-BwUMoe6n.d.ts → connection-BI-6UIBJ.d.ts} +196 -226
  63. package/dist/tsup/{connection-BR_Ve4ku.d.cts → connection-Dyd4NLGW.d.cts} +196 -226
  64. package/dist/tsup/driver-helpers/mod.cjs +6 -9
  65. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  66. package/dist/tsup/driver-helpers/mod.d.cts +5 -6
  67. package/dist/tsup/driver-helpers/mod.d.ts +5 -6
  68. package/dist/tsup/driver-helpers/mod.js +6 -9
  69. package/dist/tsup/driver-test-suite/mod.cjs +155 -1363
  70. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  71. package/dist/tsup/driver-test-suite/mod.d.cts +11 -5
  72. package/dist/tsup/driver-test-suite/mod.d.ts +11 -5
  73. package/dist/tsup/driver-test-suite/mod.js +876 -2084
  74. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  75. package/dist/tsup/inspector/mod.cjs +6 -8
  76. package/dist/tsup/inspector/mod.cjs.map +1 -1
  77. package/dist/tsup/inspector/mod.d.cts +3 -3
  78. package/dist/tsup/inspector/mod.d.ts +3 -3
  79. package/dist/tsup/inspector/mod.js +8 -10
  80. package/dist/tsup/mod.cjs +9 -15
  81. package/dist/tsup/mod.cjs.map +1 -1
  82. package/dist/tsup/mod.d.cts +47 -42
  83. package/dist/tsup/mod.d.ts +47 -42
  84. package/dist/tsup/mod.js +10 -16
  85. package/dist/tsup/{router-endpoints-DAbqVFx2.d.ts → router-endpoints-BTe_Rsdn.d.cts} +2 -3
  86. package/dist/tsup/{router-endpoints-AYkXG8Tl.d.cts → router-endpoints-CBSrKHmo.d.ts} +2 -3
  87. package/dist/tsup/test/mod.cjs +10 -14
  88. package/dist/tsup/test/mod.cjs.map +1 -1
  89. package/dist/tsup/test/mod.d.cts +4 -5
  90. package/dist/tsup/test/mod.d.ts +4 -5
  91. package/dist/tsup/test/mod.js +9 -13
  92. package/dist/tsup/{utils-CT0cv4jd.d.ts → utils-fwx3o3K9.d.cts} +1 -0
  93. package/dist/tsup/{utils-CT0cv4jd.d.cts → utils-fwx3o3K9.d.ts} +1 -0
  94. package/dist/tsup/utils.cjs +3 -3
  95. package/dist/tsup/utils.d.cts +1 -1
  96. package/dist/tsup/utils.d.ts +1 -1
  97. package/dist/tsup/utils.js +2 -2
  98. package/package.json +4 -4
  99. package/src/actor/action.ts +1 -5
  100. package/src/actor/config.ts +27 -295
  101. package/src/actor/connection.ts +9 -12
  102. package/src/actor/context.ts +1 -4
  103. package/src/actor/definition.ts +7 -11
  104. package/src/actor/errors.ts +97 -35
  105. package/src/actor/generic-conn-driver.ts +28 -16
  106. package/src/actor/instance.ts +177 -133
  107. package/src/actor/log.ts +4 -13
  108. package/src/actor/mod.ts +0 -5
  109. package/src/actor/protocol/old.ts +42 -26
  110. package/src/actor/protocol/serde.ts +1 -1
  111. package/src/actor/router-endpoints.ts +41 -38
  112. package/src/actor/router.ts +20 -18
  113. package/src/actor/unstable-react.ts +1 -1
  114. package/src/actor/utils.ts +6 -2
  115. package/src/client/actor-common.ts +1 -1
  116. package/src/client/actor-conn.ts +152 -91
  117. package/src/client/actor-handle.ts +85 -25
  118. package/src/client/actor-query.ts +65 -0
  119. package/src/client/client.ts +29 -98
  120. package/src/client/config.ts +44 -0
  121. package/src/client/errors.ts +1 -0
  122. package/src/client/log.ts +2 -4
  123. package/src/client/mod.ts +16 -12
  124. package/src/client/raw-utils.ts +82 -25
  125. package/src/client/utils.ts +5 -3
  126. package/src/common/fake-event-source.ts +10 -9
  127. package/src/common/inline-websocket-adapter2.ts +39 -30
  128. package/src/common/log.ts +176 -101
  129. package/src/common/logfmt.ts +21 -30
  130. package/src/common/router.ts +12 -19
  131. package/src/common/utils.ts +27 -13
  132. package/src/common/websocket.ts +0 -1
  133. package/src/driver-helpers/mod.ts +1 -1
  134. package/src/driver-test-suite/log.ts +1 -3
  135. package/src/driver-test-suite/mod.ts +86 -60
  136. package/src/driver-test-suite/tests/actor-handle.ts +33 -0
  137. package/src/driver-test-suite/tests/manager-driver.ts +5 -3
  138. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -226
  139. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -392
  140. package/src/driver-test-suite/tests/request-access.ts +112 -126
  141. package/src/driver-test-suite/utils.ts +13 -10
  142. package/src/drivers/default.ts +7 -4
  143. package/src/drivers/engine/actor-driver.ts +22 -13
  144. package/src/drivers/engine/config.ts +2 -10
  145. package/src/drivers/engine/kv.ts +1 -1
  146. package/src/drivers/engine/log.ts +1 -3
  147. package/src/drivers/engine/mod.ts +2 -3
  148. package/src/drivers/file-system/actor.ts +1 -1
  149. package/src/drivers/file-system/global-state.ts +33 -20
  150. package/src/drivers/file-system/log.ts +1 -3
  151. package/src/drivers/file-system/manager.ts +31 -8
  152. package/src/inspector/config.ts +9 -4
  153. package/src/inspector/log.ts +1 -1
  154. package/src/inspector/manager.ts +2 -2
  155. package/src/inspector/utils.ts +1 -1
  156. package/src/manager/driver.ts +10 -2
  157. package/src/manager/hono-websocket-adapter.ts +21 -12
  158. package/src/manager/log.ts +2 -4
  159. package/src/manager/mod.ts +1 -1
  160. package/src/manager/router.ts +277 -1657
  161. package/src/manager-api/routes/actors-create.ts +16 -0
  162. package/src/manager-api/routes/actors-delete.ts +4 -0
  163. package/src/manager-api/routes/actors-get-by-id.ts +7 -0
  164. package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
  165. package/src/manager-api/routes/actors-get.ts +7 -0
  166. package/src/manager-api/routes/common.ts +18 -0
  167. package/src/mod.ts +0 -2
  168. package/src/registry/config.ts +1 -1
  169. package/src/registry/log.ts +2 -4
  170. package/src/registry/mod.ts +57 -24
  171. package/src/registry/run-config.ts +31 -33
  172. package/src/registry/serve.ts +4 -5
  173. package/src/remote-manager-driver/actor-http-client.ts +72 -0
  174. package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
  175. package/src/remote-manager-driver/api-endpoints.ts +79 -0
  176. package/src/remote-manager-driver/api-utils.ts +43 -0
  177. package/src/remote-manager-driver/log.ts +5 -0
  178. package/src/remote-manager-driver/mod.ts +274 -0
  179. package/src/{drivers/engine → remote-manager-driver}/ws-proxy.ts +24 -14
  180. package/src/serde.ts +8 -2
  181. package/src/test/log.ts +1 -3
  182. package/src/test/mod.ts +17 -16
  183. package/dist/tsup/chunk-2CRLFV6Z.cjs +0 -202
  184. package/dist/tsup/chunk-2CRLFV6Z.cjs.map +0 -1
  185. package/dist/tsup/chunk-3H7O2A7I.js.map +0 -1
  186. package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
  187. package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
  188. package/dist/tsup/chunk-4NSUQZ2H.js.map +0 -1
  189. package/dist/tsup/chunk-6PDXBYI5.js.map +0 -1
  190. package/dist/tsup/chunk-6WKQDDUD.cjs.map +0 -1
  191. package/dist/tsup/chunk-CTBOSFUH.cjs +0 -116
  192. package/dist/tsup/chunk-CTBOSFUH.cjs.map +0 -1
  193. package/dist/tsup/chunk-EGVZZFE2.js +0 -2857
  194. package/dist/tsup/chunk-EGVZZFE2.js.map +0 -1
  195. package/dist/tsup/chunk-FCCPJNMA.cjs.map +0 -1
  196. package/dist/tsup/chunk-FLMTTN27.js.map +0 -1
  197. package/dist/tsup/chunk-GIR3AFFI.cjs.map +0 -1
  198. package/dist/tsup/chunk-INGJP237.js.map +0 -1
  199. package/dist/tsup/chunk-KJCJLKRM.js +0 -116
  200. package/dist/tsup/chunk-KJCJLKRM.js.map +0 -1
  201. package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
  202. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
  203. package/dist/tsup/chunk-O2MBYIXO.cjs +0 -2857
  204. package/dist/tsup/chunk-O2MBYIXO.cjs.map +0 -1
  205. package/dist/tsup/chunk-OGAPU3UG.cjs.map +0 -1
  206. package/dist/tsup/chunk-OV6AYD4S.js +0 -4406
  207. package/dist/tsup/chunk-OV6AYD4S.js.map +0 -1
  208. package/dist/tsup/chunk-PO4VLDWA.js.map +0 -1
  209. package/dist/tsup/chunk-R2OPSKIV.cjs.map +0 -1
  210. package/dist/tsup/chunk-TZJKSBUQ.cjs.map +0 -1
  211. package/dist/tsup/chunk-UBUC5C3G.cjs +0 -189
  212. package/dist/tsup/chunk-UBUC5C3G.cjs.map +0 -1
  213. package/dist/tsup/chunk-UIM22YJL.cjs +0 -4406
  214. package/dist/tsup/chunk-UIM22YJL.cjs.map +0 -1
  215. package/dist/tsup/chunk-URVFQMYI.cjs +0 -230
  216. package/dist/tsup/chunk-URVFQMYI.cjs.map +0 -1
  217. package/dist/tsup/chunk-UVUPOS46.js +0 -230
  218. package/dist/tsup/chunk-UVUPOS46.js.map +0 -1
  219. package/dist/tsup/chunk-VRRHBNJC.js +0 -189
  220. package/dist/tsup/chunk-VRRHBNJC.js.map +0 -1
  221. package/dist/tsup/chunk-XFSS33EQ.js +0 -202
  222. package/dist/tsup/chunk-XFSS33EQ.js.map +0 -1
  223. package/src/client/http-client-driver.ts +0 -326
  224. package/src/driver-test-suite/test-inline-client-driver.ts +0 -402
  225. package/src/driver-test-suite/tests/actor-auth.ts +0 -591
  226. package/src/drivers/engine/api-endpoints.ts +0 -128
  227. package/src/drivers/engine/api-utils.ts +0 -70
  228. package/src/drivers/engine/manager-driver.ts +0 -391
  229. package/src/inline-client-driver/log.ts +0 -7
  230. package/src/inline-client-driver/mod.ts +0 -385
  231. package/src/manager/auth.ts +0 -121
  232. /package/src/{drivers/engine → actor}/keys.test.ts +0 -0
  233. /package/src/{drivers/engine → actor}/keys.ts +0 -0
@@ -1,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
+ // }