rivetkit 2.0.2 → 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 (246) hide show
  1. package/README.md +3 -5
  2. package/dist/schemas/actor-persist/v1.ts +225 -0
  3. package/dist/schemas/client-protocol/v1.ts +435 -0
  4. package/dist/schemas/file-system-driver/v1.ts +102 -0
  5. package/dist/tsup/actor/errors.cjs +77 -0
  6. package/dist/tsup/actor/errors.cjs.map +1 -0
  7. package/dist/tsup/actor/errors.d.cts +156 -0
  8. package/dist/tsup/actor/errors.d.ts +156 -0
  9. package/dist/tsup/actor/errors.js +77 -0
  10. package/dist/tsup/actor/errors.js.map +1 -0
  11. package/dist/tsup/chunk-3F2YSRJL.js +117 -0
  12. package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
  13. package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
  14. package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
  15. package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
  16. package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
  17. package/dist/tsup/chunk-6LJT3QRL.cjs +539 -0
  18. package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
  19. package/dist/tsup/chunk-GICQ3YCU.cjs +1792 -0
  20. package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
  21. package/dist/tsup/chunk-H26RP6GD.js +251 -0
  22. package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
  23. package/dist/tsup/chunk-HI3HWJRC.js +20 -0
  24. package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
  25. package/dist/tsup/chunk-HLLF4B4Q.js +1792 -0
  26. package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
  27. package/dist/tsup/chunk-IH6CKNDW.cjs +117 -0
  28. package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
  29. package/dist/tsup/chunk-LV2S3OU3.js +250 -0
  30. package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
  31. package/dist/tsup/chunk-LWNKVZG5.cjs +251 -0
  32. package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
  33. package/dist/tsup/chunk-NFU2BBT5.js +374 -0
  34. package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
  35. package/dist/tsup/chunk-PQY7KKTL.js +539 -0
  36. package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
  37. package/dist/tsup/chunk-QK72M5JB.js +45 -0
  38. package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
  39. package/dist/tsup/chunk-QNNXFOQV.cjs +45 -0
  40. package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
  41. package/dist/tsup/chunk-SBHHJ6QS.cjs +374 -0
  42. package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
  43. package/dist/tsup/chunk-TQ62L3X7.js +325 -0
  44. package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
  45. package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
  46. package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
  47. package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
  48. package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
  49. package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
  50. package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
  51. package/dist/tsup/client/mod.cjs +32 -0
  52. package/dist/tsup/client/mod.cjs.map +1 -0
  53. package/dist/tsup/client/mod.d.cts +20 -0
  54. package/dist/tsup/client/mod.d.ts +20 -0
  55. package/dist/tsup/client/mod.js +32 -0
  56. package/dist/tsup/client/mod.js.map +1 -0
  57. package/dist/tsup/common/log.cjs +21 -0
  58. package/dist/tsup/common/log.cjs.map +1 -0
  59. package/dist/tsup/common/log.d.cts +26 -0
  60. package/dist/tsup/common/log.d.ts +26 -0
  61. package/dist/tsup/common/log.js +21 -0
  62. package/dist/tsup/common/log.js.map +1 -0
  63. package/dist/tsup/common/websocket.cjs +10 -0
  64. package/dist/tsup/common/websocket.cjs.map +1 -0
  65. package/dist/tsup/common/websocket.d.cts +3 -0
  66. package/dist/tsup/common/websocket.d.ts +3 -0
  67. package/dist/tsup/common/websocket.js +10 -0
  68. package/dist/tsup/common/websocket.js.map +1 -0
  69. package/dist/tsup/common-CXCe7s6i.d.cts +218 -0
  70. package/dist/tsup/common-CXCe7s6i.d.ts +218 -0
  71. package/dist/tsup/connection-BI-6UIBJ.d.ts +2087 -0
  72. package/dist/tsup/connection-Dyd4NLGW.d.cts +2087 -0
  73. package/dist/tsup/driver-helpers/mod.cjs +30 -0
  74. package/dist/tsup/driver-helpers/mod.cjs.map +1 -0
  75. package/dist/tsup/driver-helpers/mod.d.cts +17 -0
  76. package/dist/tsup/driver-helpers/mod.d.ts +17 -0
  77. package/dist/tsup/driver-helpers/mod.js +30 -0
  78. package/dist/tsup/driver-helpers/mod.js.map +1 -0
  79. package/dist/tsup/driver-test-suite/mod.cjs +3411 -0
  80. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -0
  81. package/dist/tsup/driver-test-suite/mod.d.cts +63 -0
  82. package/dist/tsup/driver-test-suite/mod.d.ts +63 -0
  83. package/dist/tsup/driver-test-suite/mod.js +3411 -0
  84. package/dist/tsup/driver-test-suite/mod.js.map +1 -0
  85. package/dist/tsup/inspector/mod.cjs +51 -0
  86. package/dist/tsup/inspector/mod.cjs.map +1 -0
  87. package/dist/tsup/inspector/mod.d.cts +408 -0
  88. package/dist/tsup/inspector/mod.d.ts +408 -0
  89. package/dist/tsup/inspector/mod.js +51 -0
  90. package/dist/tsup/inspector/mod.js.map +1 -0
  91. package/dist/tsup/mod.cjs +67 -0
  92. package/dist/tsup/mod.cjs.map +1 -0
  93. package/dist/tsup/mod.d.cts +105 -0
  94. package/dist/tsup/mod.d.ts +105 -0
  95. package/dist/tsup/mod.js +67 -0
  96. package/dist/tsup/mod.js.map +1 -0
  97. package/dist/tsup/router-endpoints-BTe_Rsdn.d.cts +65 -0
  98. package/dist/tsup/router-endpoints-CBSrKHmo.d.ts +65 -0
  99. package/dist/tsup/test/mod.cjs +17 -0
  100. package/dist/tsup/test/mod.cjs.map +1 -0
  101. package/dist/tsup/test/mod.d.cts +26 -0
  102. package/dist/tsup/test/mod.d.ts +26 -0
  103. package/dist/tsup/test/mod.js +17 -0
  104. package/dist/tsup/test/mod.js.map +1 -0
  105. package/dist/tsup/utils-fwx3o3K9.d.cts +18 -0
  106. package/dist/tsup/utils-fwx3o3K9.d.ts +18 -0
  107. package/dist/tsup/utils.cjs +26 -0
  108. package/dist/tsup/utils.cjs.map +1 -0
  109. package/dist/tsup/utils.d.cts +36 -0
  110. package/dist/tsup/utils.d.ts +36 -0
  111. package/dist/tsup/utils.js +26 -0
  112. package/dist/tsup/utils.js.map +1 -0
  113. package/package.json +208 -5
  114. package/src/actor/action.ts +178 -0
  115. package/src/actor/config.ts +497 -0
  116. package/src/actor/connection.ts +257 -0
  117. package/src/actor/context.ts +168 -0
  118. package/src/actor/database.ts +23 -0
  119. package/src/actor/definition.ts +82 -0
  120. package/src/actor/driver.ts +84 -0
  121. package/src/actor/errors.ts +422 -0
  122. package/src/actor/generic-conn-driver.ts +246 -0
  123. package/src/actor/instance.ts +1844 -0
  124. package/src/actor/keys.test.ts +266 -0
  125. package/src/actor/keys.ts +89 -0
  126. package/src/actor/log.ts +6 -0
  127. package/src/actor/mod.ts +108 -0
  128. package/src/actor/persisted.ts +42 -0
  129. package/src/actor/protocol/old.ts +297 -0
  130. package/src/actor/protocol/serde.ts +131 -0
  131. package/src/actor/router-endpoints.ts +688 -0
  132. package/src/actor/router.ts +265 -0
  133. package/src/actor/schedule.ts +17 -0
  134. package/src/actor/unstable-react.ts +110 -0
  135. package/src/actor/utils.ts +102 -0
  136. package/src/client/actor-common.ts +30 -0
  137. package/src/client/actor-conn.ts +865 -0
  138. package/src/client/actor-handle.ts +268 -0
  139. package/src/client/actor-query.ts +65 -0
  140. package/src/client/client.ts +554 -0
  141. package/src/client/config.ts +44 -0
  142. package/src/client/errors.ts +42 -0
  143. package/src/client/log.ts +5 -0
  144. package/src/client/mod.ts +60 -0
  145. package/src/client/raw-utils.ts +149 -0
  146. package/src/client/test.ts +44 -0
  147. package/src/client/utils.ts +152 -0
  148. package/src/common/eventsource-interface.ts +47 -0
  149. package/src/common/eventsource.ts +80 -0
  150. package/src/common/fake-event-source.ts +267 -0
  151. package/src/common/inline-websocket-adapter2.ts +454 -0
  152. package/src/common/log-levels.ts +27 -0
  153. package/src/common/log.ts +214 -0
  154. package/src/common/logfmt.ts +219 -0
  155. package/src/common/network.ts +2 -0
  156. package/src/common/router.ts +80 -0
  157. package/src/common/utils.ts +336 -0
  158. package/src/common/versioned-data.ts +95 -0
  159. package/src/common/websocket-interface.ts +49 -0
  160. package/src/common/websocket.ts +42 -0
  161. package/src/driver-helpers/mod.ts +22 -0
  162. package/src/driver-helpers/utils.ts +17 -0
  163. package/src/driver-test-suite/log.ts +5 -0
  164. package/src/driver-test-suite/mod.ts +239 -0
  165. package/src/driver-test-suite/tests/action-features.ts +136 -0
  166. package/src/driver-test-suite/tests/actor-conn-state.ts +249 -0
  167. package/src/driver-test-suite/tests/actor-conn.ts +349 -0
  168. package/src/driver-test-suite/tests/actor-driver.ts +25 -0
  169. package/src/driver-test-suite/tests/actor-error-handling.ts +158 -0
  170. package/src/driver-test-suite/tests/actor-handle.ts +292 -0
  171. package/src/driver-test-suite/tests/actor-inline-client.ts +152 -0
  172. package/src/driver-test-suite/tests/actor-inspector.ts +570 -0
  173. package/src/driver-test-suite/tests/actor-metadata.ts +116 -0
  174. package/src/driver-test-suite/tests/actor-onstatechange.ts +95 -0
  175. package/src/driver-test-suite/tests/actor-schedule.ts +108 -0
  176. package/src/driver-test-suite/tests/actor-sleep.ts +413 -0
  177. package/src/driver-test-suite/tests/actor-state.ts +54 -0
  178. package/src/driver-test-suite/tests/actor-vars.ts +93 -0
  179. package/src/driver-test-suite/tests/manager-driver.ts +367 -0
  180. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -0
  181. package/src/driver-test-suite/tests/raw-http-request-properties.ts +414 -0
  182. package/src/driver-test-suite/tests/raw-http.ts +347 -0
  183. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -0
  184. package/src/driver-test-suite/tests/raw-websocket.ts +484 -0
  185. package/src/driver-test-suite/tests/request-access.ts +230 -0
  186. package/src/driver-test-suite/utils.ts +71 -0
  187. package/src/drivers/default.ts +34 -0
  188. package/src/drivers/engine/actor-driver.ts +369 -0
  189. package/src/drivers/engine/config.ts +31 -0
  190. package/src/drivers/engine/kv.ts +3 -0
  191. package/src/drivers/engine/log.ts +5 -0
  192. package/src/drivers/engine/mod.ts +35 -0
  193. package/src/drivers/file-system/actor.ts +91 -0
  194. package/src/drivers/file-system/global-state.ts +686 -0
  195. package/src/drivers/file-system/log.ts +5 -0
  196. package/src/drivers/file-system/manager.ts +329 -0
  197. package/src/drivers/file-system/mod.ts +48 -0
  198. package/src/drivers/file-system/utils.ts +109 -0
  199. package/src/globals.d.ts +6 -0
  200. package/src/inspector/actor.ts +298 -0
  201. package/src/inspector/config.ts +88 -0
  202. package/src/inspector/log.ts +5 -0
  203. package/src/inspector/manager.ts +86 -0
  204. package/src/inspector/mod.ts +2 -0
  205. package/src/inspector/protocol/actor.ts +10 -0
  206. package/src/inspector/protocol/common.ts +196 -0
  207. package/src/inspector/protocol/manager.ts +10 -0
  208. package/src/inspector/protocol/mod.ts +2 -0
  209. package/src/inspector/utils.ts +76 -0
  210. package/src/manager/driver.ts +88 -0
  211. package/src/manager/hono-websocket-adapter.ts +342 -0
  212. package/src/manager/log.ts +5 -0
  213. package/src/manager/mod.ts +2 -0
  214. package/src/manager/protocol/mod.ts +24 -0
  215. package/src/manager/protocol/query.ts +89 -0
  216. package/src/manager/router.ts +412 -0
  217. package/src/manager-api/routes/actors-create.ts +16 -0
  218. package/src/manager-api/routes/actors-delete.ts +4 -0
  219. package/src/manager-api/routes/actors-get-by-id.ts +7 -0
  220. package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
  221. package/src/manager-api/routes/actors-get.ts +7 -0
  222. package/src/manager-api/routes/common.ts +18 -0
  223. package/src/mod.ts +18 -0
  224. package/src/registry/config.ts +32 -0
  225. package/src/registry/log.ts +5 -0
  226. package/src/registry/mod.ts +157 -0
  227. package/src/registry/run-config.ts +52 -0
  228. package/src/registry/serve.ts +52 -0
  229. package/src/remote-manager-driver/actor-http-client.ts +72 -0
  230. package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
  231. package/src/remote-manager-driver/api-endpoints.ts +79 -0
  232. package/src/remote-manager-driver/api-utils.ts +43 -0
  233. package/src/remote-manager-driver/log.ts +5 -0
  234. package/src/remote-manager-driver/mod.ts +274 -0
  235. package/src/remote-manager-driver/ws-proxy.ts +180 -0
  236. package/src/schemas/actor-persist/mod.ts +1 -0
  237. package/src/schemas/actor-persist/versioned.ts +25 -0
  238. package/src/schemas/client-protocol/mod.ts +1 -0
  239. package/src/schemas/client-protocol/versioned.ts +63 -0
  240. package/src/schemas/file-system-driver/mod.ts +1 -0
  241. package/src/schemas/file-system-driver/versioned.ts +28 -0
  242. package/src/serde.ts +90 -0
  243. package/src/test/config.ts +16 -0
  244. package/src/test/log.ts +5 -0
  245. package/src/test/mod.ts +154 -0
  246. package/src/utils.ts +172 -0
@@ -0,0 +1,93 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import type { DriverTestConfig } from "../mod";
3
+ import { setupDriverTest } from "../utils";
4
+
5
+ export function runActorVarsTests(driverTestConfig: DriverTestConfig) {
6
+ describe("Actor Variables", () => {
7
+ describe("Static vars", () => {
8
+ test("should provide access to static vars", async (c) => {
9
+ const { client } = await setupDriverTest(c, driverTestConfig);
10
+
11
+ const instance = client.staticVarActor.getOrCreate();
12
+
13
+ // Test accessing vars
14
+ const result = await instance.getVars();
15
+ expect(result).toEqual({ counter: 42, name: "test-actor" });
16
+
17
+ // Test accessing specific var property
18
+ const name = await instance.getName();
19
+ expect(name).toBe("test-actor");
20
+ });
21
+ });
22
+
23
+ describe("Deep cloning of static vars", () => {
24
+ test("should deep clone static vars between actor instances", async (c) => {
25
+ const { client } = await setupDriverTest(c, driverTestConfig);
26
+
27
+ // Create two separate instances
28
+ const instance1 = client.nestedVarActor.getOrCreate(["instance1"]);
29
+ const instance2 = client.nestedVarActor.getOrCreate(["instance2"]);
30
+
31
+ // Modify vars in the first instance
32
+ const modifiedVars = await instance1.modifyNested();
33
+ expect(modifiedVars.nested.value).toBe("modified");
34
+ expect(modifiedVars.nested.array).toContain(4);
35
+ expect(modifiedVars.nested.obj.key).toBe("new-value");
36
+
37
+ // Check that the second instance still has the original values
38
+ const instance2Vars = await instance2.getVars();
39
+ expect(instance2Vars.nested.value).toBe("original");
40
+ expect(instance2Vars.nested.array).toEqual([1, 2, 3]);
41
+ expect(instance2Vars.nested.obj.key).toBe("value");
42
+ });
43
+ });
44
+
45
+ describe("createVars", () => {
46
+ test("should support dynamic vars creation", async (c) => {
47
+ const { client } = await setupDriverTest(c, driverTestConfig);
48
+
49
+ // Create an instance
50
+ const instance = client.dynamicVarActor.getOrCreate();
51
+
52
+ // Test accessing dynamically created vars
53
+ const vars = await instance.getVars();
54
+ expect(vars).toHaveProperty("random");
55
+ expect(vars).toHaveProperty("computed");
56
+ expect(typeof vars.random).toBe("number");
57
+ expect(typeof vars.computed).toBe("string");
58
+ expect(vars.computed).toMatch(/^Actor-\d+$/);
59
+ });
60
+
61
+ test("should create different vars for different instances", async (c) => {
62
+ const { client } = await setupDriverTest(c, driverTestConfig);
63
+
64
+ // Create two separate instances
65
+ const instance1 = client.uniqueVarActor.getOrCreate(["test1"]);
66
+ const instance2 = client.uniqueVarActor.getOrCreate(["test2"]);
67
+
68
+ // Get vars from both instances
69
+ const vars1 = await instance1.getVars();
70
+ const vars2 = await instance2.getVars();
71
+
72
+ // Verify they have different values
73
+ expect(vars1.id).not.toBe(vars2.id);
74
+ });
75
+ });
76
+
77
+ describe("Driver Context", () => {
78
+ test("should provide access to driver context", async (c) => {
79
+ const { client } = await setupDriverTest(c, driverTestConfig);
80
+
81
+ // Create an instance
82
+ const instance = client.driverCtxActor.getOrCreate();
83
+
84
+ // Test accessing driver context through vars
85
+ const vars = await instance.getVars();
86
+
87
+ // Driver context might or might not be available depending on the driver
88
+ // But the test should run without errors
89
+ expect(vars).toHaveProperty("hasDriverCtx");
90
+ });
91
+ });
92
+ });
93
+ }
@@ -0,0 +1,367 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import type { ActorError } from "@/client/mod";
3
+ import type { DriverTestConfig } from "../mod";
4
+ import { setupDriverTest } from "../utils";
5
+
6
+ export function runManagerDriverTests(driverTestConfig: DriverTestConfig) {
7
+ describe("Manager Driver Tests", () => {
8
+ describe("Client Connection Methods", () => {
9
+ test("connect() - finds or creates a actor", async (c) => {
10
+ const { client } = await setupDriverTest(c, driverTestConfig);
11
+
12
+ // Basic connect() with no parameters creates a default actor
13
+ const counterA = client.counter.getOrCreate();
14
+ await counterA.increment(5);
15
+
16
+ // Get the same actor again to verify state persisted
17
+ const counterAAgain = client.counter.getOrCreate();
18
+ const count = await counterAAgain.increment(0);
19
+ expect(count).toBe(5);
20
+
21
+ // Connect with key creates a new actor with specific parameters
22
+ const counterB = client.counter.getOrCreate(["counter-b", "testing"]);
23
+
24
+ await counterB.increment(10);
25
+ const countB = await counterB.increment(0);
26
+ expect(countB).toBe(10);
27
+ });
28
+
29
+ test("throws ActorAlreadyExists when creating duplicate actors", async (c) => {
30
+ const { client } = await setupDriverTest(c, driverTestConfig);
31
+
32
+ // Create a unique actor with specific key
33
+ const uniqueKey = ["duplicate-actor-test", crypto.randomUUID()];
34
+ const counter = client.counter.getOrCreate(uniqueKey);
35
+ await counter.increment(5);
36
+
37
+ // Expect duplicate actor
38
+ try {
39
+ await client.counter.create(uniqueKey);
40
+ expect.fail("did not error on duplicate create");
41
+ } catch (err) {
42
+ expect((err as ActorError).group).toBe("actor");
43
+ expect((err as ActorError).code).toBe("already_exists");
44
+ }
45
+
46
+ // Verify the original actor still works and has its state
47
+ const count = await counter.increment(0);
48
+ expect(count).toBe(5);
49
+ });
50
+ });
51
+
52
+ describe("Connection Options", () => {
53
+ test("get without create prevents actor creation", async (c) => {
54
+ const { client } = await setupDriverTest(c, driverTestConfig);
55
+
56
+ // Try to get a nonexistent actor with no create
57
+ const nonexistentId = `nonexistent-${crypto.randomUUID()}`;
58
+
59
+ // Should fail when actor doesn't exist
60
+ try {
61
+ await client.counter.get([nonexistentId]).resolve();
62
+ expect.fail("did not error for get");
63
+ } catch (err) {
64
+ expect((err as ActorError).group).toBe("actor");
65
+ expect((err as ActorError).code).toBe("not_found");
66
+ }
67
+
68
+ // Create the actor
69
+ const createdCounter = client.counter.getOrCreate(nonexistentId);
70
+ await createdCounter.increment(3);
71
+
72
+ // Now no create should work since the actor exists
73
+ const retrievedCounter = client.counter.get(nonexistentId);
74
+
75
+ const count = await retrievedCounter.increment(0);
76
+ expect(count).toBe(3);
77
+ });
78
+
79
+ test("connection params are passed to actors", async (c) => {
80
+ const { client } = await setupDriverTest(c, driverTestConfig);
81
+
82
+ // Create a actor with connection params
83
+ // Note: In a real test we'd verify these are received by the actor,
84
+ // but our simple counter actor doesn't use connection params.
85
+ // This test just ensures the params are accepted by the driver.
86
+ const counter = client.counter.getOrCreate(undefined, {
87
+ params: {
88
+ userId: "user-123",
89
+ authToken: "token-abc",
90
+ settings: { increment: 5 },
91
+ },
92
+ });
93
+
94
+ await counter.increment(1);
95
+ const count = await counter.increment(0);
96
+ expect(count).toBe(1);
97
+ });
98
+ });
99
+
100
+ describe("Actor Creation & Retrieval", () => {
101
+ test("creates and retrieves actors by ID", async (c) => {
102
+ const { client } = await setupDriverTest(c, driverTestConfig);
103
+
104
+ // Create a unique ID for this test
105
+ const uniqueId = `test-counter-${crypto.randomUUID()}`;
106
+
107
+ // Create actor with specific ID
108
+ const counter = client.counter.getOrCreate([uniqueId]);
109
+ await counter.increment(10);
110
+
111
+ // Retrieve the same actor by ID and verify state
112
+ const retrievedCounter = client.counter.getOrCreate([uniqueId]);
113
+ const count = await retrievedCounter.increment(0); // Get current value
114
+ expect(count).toBe(10);
115
+ });
116
+
117
+ test("passes input to actor during creation", async (c) => {
118
+ const { client } = await setupDriverTest(c, driverTestConfig);
119
+
120
+ // Test data to pass as input
121
+ const testInput = {
122
+ name: "test-actor",
123
+ value: 42,
124
+ nested: { foo: "bar" },
125
+ };
126
+
127
+ // Create actor with input
128
+ const actor = await client.inputActor.create(undefined, {
129
+ input: testInput,
130
+ });
131
+
132
+ // Verify both createState and onCreate received the input
133
+ const inputs = await actor.getInputs();
134
+
135
+ // Input should be available in createState
136
+ expect(inputs.initialInput).toEqual(testInput);
137
+
138
+ // Input should also be available in onCreate lifecycle hook
139
+ expect(inputs.onCreateInput).toEqual(testInput);
140
+ });
141
+
142
+ test("input is undefined when not provided", async (c) => {
143
+ const { client } = await setupDriverTest(c, driverTestConfig);
144
+
145
+ // Create actor without providing input
146
+ const actor = await client.inputActor.create();
147
+
148
+ // Get inputs and verify they're undefined
149
+ const inputs = await actor.getInputs();
150
+
151
+ // Should be undefined in createState
152
+ expect(inputs.initialInput).toBeUndefined();
153
+
154
+ // Should be undefined in onCreate lifecycle hook too
155
+ expect(inputs.onCreateInput).toBeUndefined();
156
+ });
157
+
158
+ test("getOrCreate passes input to actor during creation", async (c) => {
159
+ const { client } = await setupDriverTest(c, driverTestConfig);
160
+
161
+ // Create a unique key for this test
162
+ const uniqueKey = [`input-test-${crypto.randomUUID()}`];
163
+
164
+ // Test data to pass as input
165
+ const testInput = {
166
+ name: "getorcreate-test",
167
+ value: 100,
168
+ nested: { baz: "qux" },
169
+ };
170
+
171
+ // Use getOrCreate with input
172
+ const actor = client.inputActor.getOrCreate(uniqueKey, {
173
+ createWithInput: testInput,
174
+ });
175
+
176
+ // Verify both createState and onCreate received the input
177
+ const inputs = await actor.getInputs();
178
+
179
+ // Input should be available in createState
180
+ expect(inputs.initialInput).toEqual(testInput);
181
+
182
+ // Input should also be available in onCreate lifecycle hook
183
+ expect(inputs.onCreateInput).toEqual(testInput);
184
+
185
+ // Verify that calling getOrCreate again with the same key
186
+ // returns the existing actor and doesn't create a new one
187
+ const existingActor = client.inputActor.getOrCreate(uniqueKey);
188
+ const existingInputs = await existingActor.getInputs();
189
+
190
+ // Should still have the original inputs
191
+ expect(existingInputs.initialInput).toEqual(testInput);
192
+ expect(existingInputs.onCreateInput).toEqual(testInput);
193
+ });
194
+
195
+ // TODO: Correctly test region for each provider
196
+ //test("creates and retrieves actors with region", async (c) => {
197
+ // const { client } = await setupDriverTest(c,
198
+ // driverTestConfig,
199
+ // COUNTER_APP_PATH
200
+ // );
201
+ //
202
+ // // Create actor with a specific region
203
+ // const counter = client.counter.getOrCreate({
204
+ // create: {
205
+ // key: ["metadata-test", "testing"],
206
+ // region: "test-region",
207
+ // },
208
+ // });
209
+ //
210
+ // // Set state to identify this specific instance
211
+ // await counter.increment(42);
212
+ //
213
+ // // Retrieve by ID (since metadata is not used for retrieval)
214
+ // const retrievedCounter = client.counter.getOrCreate(["metadata-test"]);
215
+ //
216
+ // // Verify it's the same instance
217
+ // const count = await retrievedCounter.increment(0);
218
+ // expect(count).toBe(42);
219
+ //});
220
+ });
221
+
222
+ describe("Key Matching", () => {
223
+ test("matches actors only with exactly the same keys", async (c) => {
224
+ const { client } = await setupDriverTest(c, driverTestConfig);
225
+
226
+ // Create actor with multiple keys
227
+ const originalCounter = client.counter.getOrCreate([
228
+ "counter-match",
229
+ "test",
230
+ "us-east",
231
+ ]);
232
+ await originalCounter.increment(10);
233
+
234
+ // Should match with exact same keys
235
+ const exactMatchCounter = client.counter.getOrCreate([
236
+ "counter-match",
237
+ "test",
238
+ "us-east",
239
+ ]);
240
+ const exactMatchCount = await exactMatchCounter.increment(0);
241
+ expect(exactMatchCount).toBe(10);
242
+
243
+ // Should NOT match with subset of keys - should create new actor
244
+ const subsetMatchCounter = client.counter.getOrCreate([
245
+ "counter-match",
246
+ "test",
247
+ ]);
248
+ const subsetMatchCount = await subsetMatchCounter.increment(0);
249
+ expect(subsetMatchCount).toBe(0); // Should be a new counter with 0
250
+
251
+ // Should NOT match with just one key - should create new actor
252
+ const singleKeyCounter = client.counter.getOrCreate(["counter-match"]);
253
+ const singleKeyCount = await singleKeyCounter.increment(0);
254
+ expect(singleKeyCount).toBe(0); // Should be a new counter with 0
255
+ });
256
+
257
+ test("string key matches array with single string key", async (c) => {
258
+ const { client } = await setupDriverTest(c, driverTestConfig);
259
+
260
+ // Create actor with string key
261
+ const stringKeyCounter = client.counter.getOrCreate("string-key-test");
262
+ await stringKeyCounter.increment(7);
263
+
264
+ // Should match with equivalent array key
265
+ const arrayKeyCounter = client.counter.getOrCreate(["string-key-test"]);
266
+ const count = await arrayKeyCounter.increment(0);
267
+ expect(count).toBe(7);
268
+ });
269
+
270
+ test("undefined key matches empty array key and no key", async (c) => {
271
+ const { client } = await setupDriverTest(c, driverTestConfig);
272
+
273
+ // Create actor with undefined key
274
+ const undefinedKeyCounter = client.counter.getOrCreate(undefined);
275
+ await undefinedKeyCounter.increment(12);
276
+
277
+ // Should match with empty array key
278
+ const emptyArrayKeyCounter = client.counter.getOrCreate([]);
279
+ const emptyArrayCount = await emptyArrayKeyCounter.increment(0);
280
+ expect(emptyArrayCount).toBe(12);
281
+
282
+ // Should match with no key
283
+ const noKeyCounter = client.counter.getOrCreate();
284
+ const noKeyCount = await noKeyCounter.increment(0);
285
+ expect(noKeyCount).toBe(12);
286
+ });
287
+
288
+ test("no keys does not match actors with keys", async (c) => {
289
+ const { client } = await setupDriverTest(c, driverTestConfig);
290
+
291
+ // Create counter with keys
292
+ const keyedCounter = client.counter.getOrCreate([
293
+ "counter-with-keys",
294
+ "special",
295
+ ]);
296
+ await keyedCounter.increment(15);
297
+
298
+ // Should not match when searching with no keys
299
+ const noKeysCounter = client.counter.getOrCreate();
300
+ const count = await noKeysCounter.increment(10);
301
+ expect(count).toBe(10);
302
+ });
303
+
304
+ test("actors with keys match actors with no keys", async (c) => {
305
+ const { client } = await setupDriverTest(c, driverTestConfig);
306
+
307
+ // Create a counter with no keys
308
+ const noKeysCounter = client.counter.getOrCreate();
309
+ await noKeysCounter.increment(25);
310
+
311
+ // Get counter with keys - should create a new one
312
+ const keyedCounter = client.counter.getOrCreate([
313
+ "new-counter",
314
+ "prod",
315
+ ]);
316
+ const keyedCount = await keyedCounter.increment(0);
317
+
318
+ // Should be a new counter, not the one created above
319
+ expect(keyedCount).toBe(0);
320
+ });
321
+ });
322
+
323
+ describe("Multiple Actor Instances", () => {
324
+ // TODO: This test is flakey https://github.com/rivet-dev/rivetkit/issues/873
325
+ test("creates multiple actor instances of the same type", async (c) => {
326
+ const { client } = await setupDriverTest(c, driverTestConfig);
327
+
328
+ // Create multiple instances with different IDs
329
+ const instance1 = client.counter.getOrCreate(["multi-1"]);
330
+ const instance2 = client.counter.getOrCreate(["multi-2"]);
331
+ const instance3 = client.counter.getOrCreate(["multi-3"]);
332
+
333
+ // Set different states
334
+ await instance1.increment(1);
335
+ await instance2.increment(2);
336
+ await instance3.increment(3);
337
+
338
+ // Retrieve all instances again
339
+ const retrieved1 = client.counter.getOrCreate(["multi-1"]);
340
+ const retrieved2 = client.counter.getOrCreate(["multi-2"]);
341
+ const retrieved3 = client.counter.getOrCreate(["multi-3"]);
342
+
343
+ // Verify separate state
344
+ expect(await retrieved1.increment(0)).toBe(1);
345
+ expect(await retrieved2.increment(0)).toBe(2);
346
+ expect(await retrieved3.increment(0)).toBe(3);
347
+ });
348
+
349
+ test("handles default instance with no explicit ID", async (c) => {
350
+ const { client } = await setupDriverTest(c, driverTestConfig);
351
+
352
+ // Get default instance (no ID specified)
353
+ const defaultCounter = client.counter.getOrCreate();
354
+
355
+ // Set state
356
+ await defaultCounter.increment(5);
357
+
358
+ // Get default instance again
359
+ const sameDefaultCounter = client.counter.getOrCreate();
360
+
361
+ // Verify state is maintained
362
+ const count = await sameDefaultCounter.increment(0);
363
+ expect(count).toBe(5);
364
+ });
365
+ });
366
+ });
367
+ }
@@ -0,0 +1,227 @@
1
+ // TODO: re-expose this once we can have actor queries on the gateway
2
+ // import { describe, expect, test } from "vitest";
3
+ // import {
4
+ // HEADER_ACTOR_QUERY,
5
+ // HEADER_CONN_PARAMS,
6
+ // } from "@/actor/router-endpoints";
7
+ // import type { ActorQuery } from "@/manager/protocol/query";
8
+ // import type { DriverTestConfig } from "../mod";
9
+ // import { setupDriverTest } from "../utils";
10
+ //
11
+ // export function runRawHttpDirectRegistryTests(
12
+ // driverTestConfig: DriverTestConfig,
13
+ // ) {
14
+ // describe("raw http - direct registry access", () => {
15
+ // test("should handle direct fetch requests to registry with proper headers", async (c) => {
16
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
17
+ //
18
+ // // Build the actor query
19
+ // const actorQuery: ActorQuery = {
20
+ // getOrCreateForKey: {
21
+ // name: "rawHttpActor",
22
+ // key: ["direct-test"],
23
+ // },
24
+ // };
25
+ //
26
+ // // Make a direct fetch request to the registry
27
+ // const response = await fetch(
28
+ // `${endpoint}/registry/actors/raw/http/api/hello`,
29
+ // {
30
+ // method: "GET",
31
+ // headers: {
32
+ // [HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
33
+ // },
34
+ // },
35
+ // );
36
+ //
37
+ // expect(response.ok).toBe(true);
38
+ // expect(response.status).toBe(200);
39
+ // const data = await response.json();
40
+ // expect(data).toEqual({ message: "Hello from actor!" });
41
+ // });
42
+ //
43
+ // test("should handle POST requests with body to registry", async (c) => {
44
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
45
+ //
46
+ // const actorQuery: ActorQuery = {
47
+ // getOrCreateForKey: {
48
+ // name: "rawHttpActor",
49
+ // key: ["direct-post-test"],
50
+ // },
51
+ // };
52
+ //
53
+ // const testData = { test: "direct", number: 456 };
54
+ // const response = await fetch(
55
+ // `${endpoint}/registry/actors/raw/http/api/echo`,
56
+ // {
57
+ // method: "POST",
58
+ // headers: {
59
+ // [HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
60
+ // "Content-Type": "application/json",
61
+ // },
62
+ // body: JSON.stringify(testData),
63
+ // },
64
+ // );
65
+ //
66
+ // expect(response.ok).toBe(true);
67
+ // expect(response.status).toBe(200);
68
+ // const data = await response.json();
69
+ // expect(data).toEqual(testData);
70
+ // });
71
+ //
72
+ // test("should pass custom headers through to actor", async (c) => {
73
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
74
+ //
75
+ // const actorQuery: ActorQuery = {
76
+ // getOrCreateForKey: {
77
+ // name: "rawHttpActor",
78
+ // key: ["direct-headers-test"],
79
+ // },
80
+ // };
81
+ //
82
+ // const customHeaders = {
83
+ // "X-Custom-Header": "direct-test-value",
84
+ // "X-Another-Header": "another-direct-value",
85
+ // };
86
+ //
87
+ // const response = await fetch(
88
+ // `${endpoint}/registry/actors/raw/http/api/headers`,
89
+ // {
90
+ // method: "GET",
91
+ // headers: {
92
+ // [HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
93
+ // ...customHeaders,
94
+ // },
95
+ // },
96
+ // );
97
+ //
98
+ // expect(response.ok).toBe(true);
99
+ // const headers = (await response.json()) as Record<string, string>;
100
+ // expect(headers["x-custom-header"]).toBe("direct-test-value");
101
+ // expect(headers["x-another-header"]).toBe("another-direct-value");
102
+ // });
103
+ //
104
+ // test("should handle connection parameters for authentication", async (c) => {
105
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
106
+ //
107
+ // const actorQuery: ActorQuery = {
108
+ // getOrCreateForKey: {
109
+ // name: "rawHttpActor",
110
+ // key: ["direct-auth-test"],
111
+ // },
112
+ // };
113
+ //
114
+ // const connParams = { token: "test-auth-token", userId: "user123" };
115
+ //
116
+ // const response = await fetch(
117
+ // `${endpoint}/registry/actors/raw/http/api/hello`,
118
+ // {
119
+ // method: "GET",
120
+ // headers: {
121
+ // [HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
122
+ // [HEADER_CONN_PARAMS]: JSON.stringify(connParams),
123
+ // },
124
+ // },
125
+ // );
126
+ //
127
+ // expect(response.ok).toBe(true);
128
+ // const data = await response.json();
129
+ // expect(data).toEqual({ message: "Hello from actor!" });
130
+ // });
131
+ //
132
+ // test("should return 404 for actors without onFetch handler", async (c) => {
133
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
134
+ //
135
+ // const actorQuery: ActorQuery = {
136
+ // getOrCreateForKey: {
137
+ // name: "rawHttpNoHandlerActor",
138
+ // key: ["direct-no-handler"],
139
+ // },
140
+ // };
141
+ //
142
+ // const response = await fetch(
143
+ // `${endpoint}/registry/actors/raw/http/api/anything`,
144
+ // {
145
+ // method: "GET",
146
+ // headers: {
147
+ // [HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
148
+ // },
149
+ // },
150
+ // );
151
+ //
152
+ // expect(response.ok).toBe(false);
153
+ // expect(response.status).toBe(404);
154
+ // });
155
+ //
156
+ // test("should handle different HTTP methods", async (c) => {
157
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
158
+ //
159
+ // const actorQuery: ActorQuery = {
160
+ // getOrCreateForKey: {
161
+ // name: "rawHttpActor",
162
+ // key: ["direct-methods-test"],
163
+ // },
164
+ // };
165
+ //
166
+ // // Test various HTTP methods
167
+ // const methods = ["GET", "POST", "PUT", "DELETE", "PATCH"] as const;
168
+ //
169
+ // for (const method of methods) {
170
+ // const response = await fetch(
171
+ // `${endpoint}/registry/actors/raw/http/api/echo`,
172
+ // {
173
+ // method,
174
+ // headers: {
175
+ // [HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
176
+ // ...(method !== "GET"
177
+ // ? { "Content-Type": "application/json" }
178
+ // : {}),
179
+ // },
180
+ // body: ["POST", "PUT", "PATCH"].includes(method)
181
+ // ? JSON.stringify({ method })
182
+ // : undefined,
183
+ // },
184
+ // );
185
+ //
186
+ // // Echo endpoint only handles POST, others should fall through to 404
187
+ // if (method === "POST") {
188
+ // expect(response.ok).toBe(true);
189
+ // const data = await response.json();
190
+ // expect(data).toEqual({ method });
191
+ // } else {
192
+ // expect(response.status).toBe(404);
193
+ // }
194
+ // }
195
+ // });
196
+ //
197
+ // test("should handle binary data", async (c) => {
198
+ // const { endpoint } = await setupDriverTest(c, driverTestConfig);
199
+ //
200
+ // const actorQuery: ActorQuery = {
201
+ // getOrCreateForKey: {
202
+ // name: "rawHttpActor",
203
+ // key: ["direct-binary-test"],
204
+ // },
205
+ // };
206
+ //
207
+ // // Send binary data
208
+ // const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
209
+ // const response = await fetch(
210
+ // `${endpoint}/registry/actors/raw/http/api/echo`,
211
+ // {
212
+ // method: "POST",
213
+ // headers: {
214
+ // [HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
215
+ // "Content-Type": "application/octet-stream",
216
+ // },
217
+ // body: binaryData,
218
+ // },
219
+ // );
220
+ //
221
+ // expect(response.ok).toBe(true);
222
+ // const responseBuffer = await response.arrayBuffer();
223
+ // const responseArray = new Uint8Array(responseBuffer);
224
+ // expect(Array.from(responseArray)).toEqual([1, 2, 3, 4, 5]);
225
+ // });
226
+ // });
227
+ // }