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,292 @@
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 runActorHandleTests(driverTestConfig: DriverTestConfig) {
7
+ describe("Actor Handle Tests", () => {
8
+ describe("Access Methods", () => {
9
+ test("should use .get() to access a actor", async (c) => {
10
+ const { client } = await setupDriverTest(c, driverTestConfig);
11
+
12
+ // Create actor first
13
+ await client.counter.create(["test-get-handle"]);
14
+
15
+ // Access using get
16
+ const handle = client.counter.get(["test-get-handle"]);
17
+
18
+ // Verify Action works
19
+ const count = await handle.increment(5);
20
+ expect(count).toBe(5);
21
+
22
+ const retrievedCount = await handle.getCount();
23
+ expect(retrievedCount).toBe(5);
24
+ });
25
+
26
+ test("should use .getForId() to access a actor by ID", async (c) => {
27
+ const { client } = await setupDriverTest(c, driverTestConfig);
28
+
29
+ // Create a actor first to get its ID
30
+ const handle = client.counter.getOrCreate(["test-get-for-id-handle"]);
31
+ await handle.increment(3);
32
+ const actorId = await handle.resolve();
33
+
34
+ // Access using getForId
35
+ const idHandle = client.counter.getForId(actorId);
36
+
37
+ // Verify Action works and state is preserved
38
+ const count = await idHandle.getCount();
39
+ expect(count).toBe(3);
40
+
41
+ const newCount = await idHandle.increment(4);
42
+ expect(newCount).toBe(7);
43
+ });
44
+
45
+ test("should use .getOrCreate() to access or create a actor", async (c) => {
46
+ const { client } = await setupDriverTest(c, driverTestConfig);
47
+
48
+ // Access using getOrCreate - should create the actor
49
+ const handle = client.counter.getOrCreate([
50
+ "test-get-or-create-handle",
51
+ ]);
52
+
53
+ // Verify Action works
54
+ const count = await handle.increment(7);
55
+ expect(count).toBe(7);
56
+
57
+ // Get the same actor again - should retrieve existing actor
58
+ const sameHandle = client.counter.getOrCreate([
59
+ "test-get-or-create-handle",
60
+ ]);
61
+ const retrievedCount = await sameHandle.getCount();
62
+ expect(retrievedCount).toBe(7);
63
+ });
64
+
65
+ test("should use (await create()) to create and return a handle", async (c) => {
66
+ const { client } = await setupDriverTest(c, driverTestConfig);
67
+
68
+ // Create actor and get handle
69
+ const handle = await client.counter.create(["test-create-handle"]);
70
+
71
+ // Verify Action works
72
+ const count = await handle.increment(9);
73
+ expect(count).toBe(9);
74
+
75
+ const retrievedCount = await handle.getCount();
76
+ expect(retrievedCount).toBe(9);
77
+ });
78
+
79
+ test("errors when calling create twice with the same key", async (c) => {
80
+ const { client } = await setupDriverTest(c, driverTestConfig);
81
+
82
+ const key = ["duplicate-create-handle", crypto.randomUUID()];
83
+
84
+ // First create should succeed
85
+ await client.counter.create(key);
86
+
87
+ // Second create with same key should throw ActorAlreadyExists
88
+ try {
89
+ await client.counter.create(key);
90
+ expect.fail("did not error on duplicate create");
91
+ } catch (err) {
92
+ expect((err as ActorError).group).toBe("actor");
93
+ expect((err as ActorError).code).toBe("already_exists");
94
+ }
95
+ });
96
+
97
+ test(".get().resolve() errors for non-existent actor", async (c) => {
98
+ const { client } = await setupDriverTest(c, driverTestConfig);
99
+
100
+ const missingId = `nonexistent-${crypto.randomUUID()}`;
101
+
102
+ try {
103
+ await client.counter.get([missingId]).resolve();
104
+ expect.fail("did not error for get().resolve() on missing actor");
105
+ } catch (err) {
106
+ expect((err as ActorError).group).toBe("actor");
107
+ expect((err as ActorError).code).toBe("not_found");
108
+ }
109
+ });
110
+ });
111
+
112
+ describe("Action Functionality", () => {
113
+ test("should call actions directly on the handle", async (c) => {
114
+ const { client } = await setupDriverTest(c, driverTestConfig);
115
+
116
+ const handle = client.counter.getOrCreate(["test-action-handle"]);
117
+
118
+ // Call multiple actions in sequence
119
+ const count1 = await handle.increment(3);
120
+ expect(count1).toBe(3);
121
+
122
+ const count2 = await handle.increment(5);
123
+ expect(count2).toBe(8);
124
+
125
+ const retrievedCount = await handle.getCount();
126
+ expect(retrievedCount).toBe(8);
127
+ });
128
+
129
+ test("should handle independent handles to the same actor", async (c) => {
130
+ const { client } = await setupDriverTest(c, driverTestConfig);
131
+
132
+ // Create two handles to the same actor
133
+ const handle1 = client.counter.getOrCreate(["test-multiple-handles"]);
134
+ const handle2 = client.counter.get(["test-multiple-handles"]);
135
+
136
+ // Call actions on both handles
137
+ await handle1.increment(3);
138
+ const count = await handle2.getCount();
139
+
140
+ // Verify both handles access the same state
141
+ expect(count).toBe(3);
142
+
143
+ const finalCount = await handle2.increment(4);
144
+ expect(finalCount).toBe(7);
145
+
146
+ const checkCount = await handle1.getCount();
147
+ expect(checkCount).toBe(7);
148
+ });
149
+
150
+ test("should resolve a actor's ID", async (c) => {
151
+ const { client } = await setupDriverTest(c, driverTestConfig);
152
+
153
+ const handle = client.counter.getOrCreate(["test-resolve-id"]);
154
+
155
+ // Call an action to ensure actor exists
156
+ await handle.increment(1);
157
+
158
+ // Resolve the ID
159
+ const actorId = await handle.resolve();
160
+
161
+ // Verify we got a valid ID (string)
162
+ expect(typeof actorId).toBe("string");
163
+ expect(actorId).not.toBe("");
164
+
165
+ // Verify we can use this ID to get the actor
166
+ const idHandle = client.counter.getForId(actorId);
167
+ const count = await idHandle.getCount();
168
+ expect(count).toBe(1);
169
+ });
170
+ });
171
+
172
+ describe("Lifecycle Hooks", () => {
173
+ test("should trigger lifecycle hooks on actor creation", async (c) => {
174
+ const { client } = await setupDriverTest(c, driverTestConfig);
175
+
176
+ // Get or create a new actor - this should trigger onStart
177
+ const handle = client.counterWithLifecycle.getOrCreate([
178
+ "test-lifecycle-handle",
179
+ ]);
180
+
181
+ // Verify onStart was triggered
182
+ const initialEvents = await handle.getEvents();
183
+ expect(initialEvents).toContain("onStart");
184
+
185
+ // Create a separate handle to the same actor
186
+ const sameHandle = client.counterWithLifecycle.getOrCreate([
187
+ "test-lifecycle-handle",
188
+ ]);
189
+
190
+ // Verify events still include onStart but don't duplicate it
191
+ // (onStart should only be called once when the actor is first created)
192
+ const events = await sameHandle.getEvents();
193
+ expect(events).toContain("onStart");
194
+ expect(events.filter((e) => e === "onStart").length).toBe(1);
195
+ });
196
+
197
+ test("should trigger lifecycle hooks for each Action call", async (c) => {
198
+ const { client } = await setupDriverTest(c, driverTestConfig);
199
+
200
+ // Create a normal handle to view events
201
+ const viewHandle = client.counterWithLifecycle.getOrCreate([
202
+ "test-lifecycle-action",
203
+ ]);
204
+
205
+ // Initial state should only have onStart
206
+ const initialEvents = await viewHandle.getEvents();
207
+ expect(initialEvents).toContain("onStart");
208
+ expect(initialEvents).not.toContain("onBeforeConnect");
209
+ expect(initialEvents).not.toContain("onConnect");
210
+ expect(initialEvents).not.toContain("onDisconnect");
211
+
212
+ // Create a handle with trackLifecycle enabled for testing Action calls
213
+ const trackingHandle = client.counterWithLifecycle.getOrCreate(
214
+ ["test-lifecycle-action"],
215
+ { params: { trackLifecycle: true } },
216
+ );
217
+
218
+ // Make an Action call
219
+ await trackingHandle.increment(5);
220
+
221
+ // Check that it triggered the lifecycle hooks
222
+ const eventsAfterAction = await viewHandle.getEvents();
223
+
224
+ // Should have onBeforeConnect, onConnect, and onDisconnect for the Action call
225
+ expect(eventsAfterAction).toContain("onBeforeConnect");
226
+ expect(eventsAfterAction).toContain("onConnect");
227
+ expect(eventsAfterAction).toContain("onDisconnect");
228
+
229
+ // Each should have count 1
230
+ expect(
231
+ eventsAfterAction.filter((e) => e === "onBeforeConnect").length,
232
+ ).toBe(1);
233
+ expect(eventsAfterAction.filter((e) => e === "onConnect").length).toBe(
234
+ 1,
235
+ );
236
+ expect(
237
+ eventsAfterAction.filter((e) => e === "onDisconnect").length,
238
+ ).toBe(1);
239
+
240
+ // Make another Action call
241
+ await trackingHandle.increment(10);
242
+
243
+ // Check that it triggered another set of lifecycle hooks
244
+ const eventsAfterSecondAction = await viewHandle.getEvents();
245
+
246
+ // Each hook should now have count 2
247
+ expect(
248
+ eventsAfterSecondAction.filter((e) => e === "onBeforeConnect").length,
249
+ ).toBe(2);
250
+ expect(
251
+ eventsAfterSecondAction.filter((e) => e === "onConnect").length,
252
+ ).toBe(2);
253
+ expect(
254
+ eventsAfterSecondAction.filter((e) => e === "onDisconnect").length,
255
+ ).toBe(2);
256
+ });
257
+
258
+ test("should trigger lifecycle hooks for each Action call across multiple handles", async (c) => {
259
+ const { client } = await setupDriverTest(c, driverTestConfig);
260
+
261
+ // Create a normal handle to view events
262
+ const viewHandle = client.counterWithLifecycle.getOrCreate([
263
+ "test-lifecycle-multi-handle",
264
+ ]);
265
+
266
+ // Create two tracking handles to the same actor
267
+ const trackingHandle1 = client.counterWithLifecycle.getOrCreate(
268
+ ["test-lifecycle-multi-handle"],
269
+ { params: { trackLifecycle: true } },
270
+ );
271
+
272
+ const trackingHandle2 = client.counterWithLifecycle.getOrCreate(
273
+ ["test-lifecycle-multi-handle"],
274
+ { params: { trackLifecycle: true } },
275
+ );
276
+
277
+ // Make Action calls on both handles
278
+ await trackingHandle1.increment(5);
279
+ await trackingHandle2.increment(10);
280
+
281
+ // Check lifecycle hooks
282
+ const events = await viewHandle.getEvents();
283
+
284
+ // Should have 1 onStart, 2 each of onBeforeConnect, onConnect, and onDisconnect
285
+ expect(events.filter((e) => e === "onStart").length).toBe(1);
286
+ expect(events.filter((e) => e === "onBeforeConnect").length).toBe(2);
287
+ expect(events.filter((e) => e === "onConnect").length).toBe(2);
288
+ expect(events.filter((e) => e === "onDisconnect").length).toBe(2);
289
+ });
290
+ });
291
+ });
292
+ }
@@ -0,0 +1,152 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import type { DriverTestConfig } from "../mod";
3
+ import { setupDriverTest } from "../utils";
4
+
5
+ export function runActorInlineClientTests(driverTestConfig: DriverTestConfig) {
6
+ describe("Actor Inline Client Tests", () => {
7
+ describe("Stateless Client Calls", () => {
8
+ test("should make stateless calls to other actors", async (c) => {
9
+ const { client } = await setupDriverTest(c, driverTestConfig);
10
+
11
+ // Create the inline client actor
12
+ const inlineClientHandle = client.inlineClientActor.getOrCreate([
13
+ "inline-client-test",
14
+ ]);
15
+
16
+ // Test calling counter.increment via inline client
17
+ const result = await inlineClientHandle.callCounterIncrement(5);
18
+ expect(result).toBe(5);
19
+
20
+ // Verify the counter state was actually updated
21
+ const counterState = await inlineClientHandle.getCounterState();
22
+ expect(counterState).toBe(5);
23
+
24
+ // Check that messages were logged
25
+ const messages = await inlineClientHandle.getMessages();
26
+ expect(messages).toHaveLength(2);
27
+ expect(messages[0]).toContain("Called counter.increment(5), result: 5");
28
+ expect(messages[1]).toContain("Got counter state: 5");
29
+ });
30
+
31
+ test("should handle multiple stateless calls", async (c) => {
32
+ const { client } = await setupDriverTest(c, driverTestConfig);
33
+
34
+ // Create the inline client actor
35
+ const inlineClientHandle = client.inlineClientActor.getOrCreate([
36
+ "inline-client-multi",
37
+ ]);
38
+
39
+ // Clear any existing messages
40
+ await inlineClientHandle.clearMessages();
41
+
42
+ // Make multiple calls
43
+ const result1 = await inlineClientHandle.callCounterIncrement(3);
44
+ const result2 = await inlineClientHandle.callCounterIncrement(7);
45
+ const finalState = await inlineClientHandle.getCounterState();
46
+
47
+ expect(result1).toBe(3);
48
+ expect(result2).toBe(10); // 3 + 7
49
+ expect(finalState).toBe(10);
50
+
51
+ // Check messages
52
+ const messages = await inlineClientHandle.getMessages();
53
+ expect(messages).toHaveLength(3);
54
+ expect(messages[0]).toContain("Called counter.increment(3), result: 3");
55
+ expect(messages[1]).toContain(
56
+ "Called counter.increment(7), result: 10",
57
+ );
58
+ expect(messages[2]).toContain("Got counter state: 10");
59
+ });
60
+ });
61
+
62
+ describe("Stateful Client Calls", () => {
63
+ test("should connect to other actors and receive events", async (c) => {
64
+ const { client } = await setupDriverTest(c, driverTestConfig);
65
+
66
+ // Create the inline client actor
67
+ const inlineClientHandle = client.inlineClientActor.getOrCreate([
68
+ "inline-client-stateful",
69
+ ]);
70
+
71
+ // Clear any existing messages
72
+ await inlineClientHandle.clearMessages();
73
+
74
+ // Test stateful connection with events
75
+ const result = await inlineClientHandle.connectToCounterAndIncrement(4);
76
+
77
+ expect(result.result1).toBe(4);
78
+ expect(result.result2).toBe(12); // 4 + 8
79
+ expect(result.events).toEqual([4, 12]); // Should have received both events
80
+
81
+ // Check that message was logged
82
+ const messages = await inlineClientHandle.getMessages();
83
+ expect(messages).toHaveLength(1);
84
+ expect(messages[0]).toContain(
85
+ "Connected to counter, incremented by 4 and 8",
86
+ );
87
+ expect(messages[0]).toContain("results: 4, 12");
88
+ expect(messages[0]).toContain("events: [4,12]");
89
+ });
90
+
91
+ test("should handle stateful connection independently", async (c) => {
92
+ const { client } = await setupDriverTest(c, driverTestConfig);
93
+
94
+ // Create the inline client actor
95
+ const inlineClientHandle = client.inlineClientActor.getOrCreate([
96
+ "inline-client-independent",
97
+ ]);
98
+
99
+ // Clear any existing messages
100
+ await inlineClientHandle.clearMessages();
101
+
102
+ // Test with different increment values
103
+ const result = await inlineClientHandle.connectToCounterAndIncrement(2);
104
+
105
+ expect(result.result1).toBe(2);
106
+ expect(result.result2).toBe(6); // 2 + 4
107
+ expect(result.events).toEqual([2, 6]);
108
+
109
+ // Verify the state is independent from previous tests
110
+ const messages = await inlineClientHandle.getMessages();
111
+ expect(messages).toHaveLength(1);
112
+ expect(messages[0]).toContain(
113
+ "Connected to counter, incremented by 2 and 4",
114
+ );
115
+ });
116
+ });
117
+
118
+ describe("Mixed Client Usage", () => {
119
+ test("should handle both stateless and stateful calls", async (c) => {
120
+ const { client } = await setupDriverTest(c, driverTestConfig);
121
+
122
+ // Create the inline client actor
123
+ const inlineClientHandle = client.inlineClientActor.getOrCreate([
124
+ "inline-client-mixed",
125
+ ]);
126
+
127
+ // Clear any existing messages
128
+ await inlineClientHandle.clearMessages();
129
+
130
+ // Start with stateless calls
131
+ await inlineClientHandle.callCounterIncrement(1);
132
+ const statelessResult = await inlineClientHandle.getCounterState();
133
+ expect(statelessResult).toBe(1);
134
+
135
+ // Then do stateful call
136
+ const statefulResult =
137
+ await inlineClientHandle.connectToCounterAndIncrement(3);
138
+ expect(statefulResult.result1).toBe(3);
139
+ expect(statefulResult.result2).toBe(9); // 3 + 6
140
+
141
+ // Check all messages were logged
142
+ const messages = await inlineClientHandle.getMessages();
143
+ expect(messages).toHaveLength(3);
144
+ expect(messages[0]).toContain("Called counter.increment(1), result: 1");
145
+ expect(messages[1]).toContain("Got counter state: 1");
146
+ expect(messages[2]).toContain(
147
+ "Connected to counter, incremented by 3 and 6",
148
+ );
149
+ });
150
+ });
151
+ });
152
+ }