rivetkit 2.0.1 → 2.0.3

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 (253) hide show
  1. package/dist/schemas/actor-persist/v1.ts +228 -0
  2. package/dist/schemas/client-protocol/v1.ts +429 -0
  3. package/dist/schemas/file-system-driver/v1.ts +102 -0
  4. package/dist/tsup/actor/errors.cjs +69 -0
  5. package/dist/tsup/actor/errors.cjs.map +1 -0
  6. package/dist/tsup/actor/errors.d.cts +143 -0
  7. package/dist/tsup/actor/errors.d.ts +143 -0
  8. package/dist/tsup/actor/errors.js +69 -0
  9. package/dist/tsup/actor/errors.js.map +1 -0
  10. package/dist/tsup/chunk-2CRLFV6Z.cjs +202 -0
  11. package/dist/tsup/chunk-2CRLFV6Z.cjs.map +1 -0
  12. package/dist/tsup/chunk-3H7O2A7I.js +525 -0
  13. package/dist/tsup/chunk-3H7O2A7I.js.map +1 -0
  14. package/dist/tsup/chunk-42I3OZ3Q.js +15 -0
  15. package/dist/tsup/chunk-42I3OZ3Q.js.map +1 -0
  16. package/dist/tsup/chunk-4NSUQZ2H.js +1790 -0
  17. package/dist/tsup/chunk-4NSUQZ2H.js.map +1 -0
  18. package/dist/tsup/chunk-6PDXBYI5.js +132 -0
  19. package/dist/tsup/chunk-6PDXBYI5.js.map +1 -0
  20. package/dist/tsup/chunk-6WKQDDUD.cjs +1790 -0
  21. package/dist/tsup/chunk-6WKQDDUD.cjs.map +1 -0
  22. package/dist/tsup/chunk-CTBOSFUH.cjs +116 -0
  23. package/dist/tsup/chunk-CTBOSFUH.cjs.map +1 -0
  24. package/dist/tsup/chunk-EGVZZFE2.js +2857 -0
  25. package/dist/tsup/chunk-EGVZZFE2.js.map +1 -0
  26. package/dist/tsup/chunk-FCCPJNMA.cjs +132 -0
  27. package/dist/tsup/chunk-FCCPJNMA.cjs.map +1 -0
  28. package/dist/tsup/chunk-FLMTTN27.js +244 -0
  29. package/dist/tsup/chunk-FLMTTN27.js.map +1 -0
  30. package/dist/tsup/chunk-GIR3AFFI.cjs +315 -0
  31. package/dist/tsup/chunk-GIR3AFFI.cjs.map +1 -0
  32. package/dist/tsup/chunk-INGJP237.js +315 -0
  33. package/dist/tsup/chunk-INGJP237.js.map +1 -0
  34. package/dist/tsup/chunk-KJCJLKRM.js +116 -0
  35. package/dist/tsup/chunk-KJCJLKRM.js.map +1 -0
  36. package/dist/tsup/chunk-KUPQZYUQ.cjs +15 -0
  37. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +1 -0
  38. package/dist/tsup/chunk-O2MBYIXO.cjs +2857 -0
  39. package/dist/tsup/chunk-O2MBYIXO.cjs.map +1 -0
  40. package/dist/tsup/chunk-OGAPU3UG.cjs +525 -0
  41. package/dist/tsup/chunk-OGAPU3UG.cjs.map +1 -0
  42. package/dist/tsup/chunk-OV6AYD4S.js +4406 -0
  43. package/dist/tsup/chunk-OV6AYD4S.js.map +1 -0
  44. package/dist/tsup/chunk-PO4VLDWA.js +47 -0
  45. package/dist/tsup/chunk-PO4VLDWA.js.map +1 -0
  46. package/dist/tsup/chunk-R2OPSKIV.cjs +244 -0
  47. package/dist/tsup/chunk-R2OPSKIV.cjs.map +1 -0
  48. package/dist/tsup/chunk-TZJKSBUQ.cjs +47 -0
  49. package/dist/tsup/chunk-TZJKSBUQ.cjs.map +1 -0
  50. package/dist/tsup/chunk-UBUC5C3G.cjs +189 -0
  51. package/dist/tsup/chunk-UBUC5C3G.cjs.map +1 -0
  52. package/dist/tsup/chunk-UIM22YJL.cjs +4406 -0
  53. package/dist/tsup/chunk-UIM22YJL.cjs.map +1 -0
  54. package/dist/tsup/chunk-URVFQMYI.cjs +230 -0
  55. package/dist/tsup/chunk-URVFQMYI.cjs.map +1 -0
  56. package/dist/tsup/chunk-UVUPOS46.js +230 -0
  57. package/dist/tsup/chunk-UVUPOS46.js.map +1 -0
  58. package/dist/tsup/chunk-VRRHBNJC.js +189 -0
  59. package/dist/tsup/chunk-VRRHBNJC.js.map +1 -0
  60. package/dist/tsup/chunk-XFSS33EQ.js +202 -0
  61. package/dist/tsup/chunk-XFSS33EQ.js.map +1 -0
  62. package/dist/tsup/client/mod.cjs +32 -0
  63. package/dist/tsup/client/mod.cjs.map +1 -0
  64. package/dist/tsup/client/mod.d.cts +26 -0
  65. package/dist/tsup/client/mod.d.ts +26 -0
  66. package/dist/tsup/client/mod.js +32 -0
  67. package/dist/tsup/client/mod.js.map +1 -0
  68. package/dist/tsup/common/log.cjs +13 -0
  69. package/dist/tsup/common/log.cjs.map +1 -0
  70. package/dist/tsup/common/log.d.cts +20 -0
  71. package/dist/tsup/common/log.d.ts +20 -0
  72. package/dist/tsup/common/log.js +13 -0
  73. package/dist/tsup/common/log.js.map +1 -0
  74. package/dist/tsup/common/websocket.cjs +10 -0
  75. package/dist/tsup/common/websocket.cjs.map +1 -0
  76. package/dist/tsup/common/websocket.d.cts +3 -0
  77. package/dist/tsup/common/websocket.d.ts +3 -0
  78. package/dist/tsup/common/websocket.js +10 -0
  79. package/dist/tsup/common/websocket.js.map +1 -0
  80. package/dist/tsup/common-CpqORuCq.d.cts +218 -0
  81. package/dist/tsup/common-CpqORuCq.d.ts +218 -0
  82. package/dist/tsup/connection-BR_Ve4ku.d.cts +2117 -0
  83. package/dist/tsup/connection-BwUMoe6n.d.ts +2117 -0
  84. package/dist/tsup/driver-helpers/mod.cjs +33 -0
  85. package/dist/tsup/driver-helpers/mod.cjs.map +1 -0
  86. package/dist/tsup/driver-helpers/mod.d.cts +18 -0
  87. package/dist/tsup/driver-helpers/mod.d.ts +18 -0
  88. package/dist/tsup/driver-helpers/mod.js +33 -0
  89. package/dist/tsup/driver-helpers/mod.js.map +1 -0
  90. package/dist/tsup/driver-test-suite/mod.cjs +4619 -0
  91. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -0
  92. package/dist/tsup/driver-test-suite/mod.d.cts +57 -0
  93. package/dist/tsup/driver-test-suite/mod.d.ts +57 -0
  94. package/dist/tsup/driver-test-suite/mod.js +4619 -0
  95. package/dist/tsup/driver-test-suite/mod.js.map +1 -0
  96. package/dist/tsup/inspector/mod.cjs +53 -0
  97. package/dist/tsup/inspector/mod.cjs.map +1 -0
  98. package/dist/tsup/inspector/mod.d.cts +408 -0
  99. package/dist/tsup/inspector/mod.d.ts +408 -0
  100. package/dist/tsup/inspector/mod.js +53 -0
  101. package/dist/tsup/inspector/mod.js.map +1 -0
  102. package/dist/tsup/mod.cjs +73 -0
  103. package/dist/tsup/mod.cjs.map +1 -0
  104. package/dist/tsup/mod.d.cts +100 -0
  105. package/dist/tsup/mod.d.ts +100 -0
  106. package/dist/tsup/mod.js +73 -0
  107. package/dist/tsup/mod.js.map +1 -0
  108. package/dist/tsup/router-endpoints-AYkXG8Tl.d.cts +66 -0
  109. package/dist/tsup/router-endpoints-DAbqVFx2.d.ts +66 -0
  110. package/dist/tsup/test/mod.cjs +21 -0
  111. package/dist/tsup/test/mod.cjs.map +1 -0
  112. package/dist/tsup/test/mod.d.cts +27 -0
  113. package/dist/tsup/test/mod.d.ts +27 -0
  114. package/dist/tsup/test/mod.js +21 -0
  115. package/dist/tsup/test/mod.js.map +1 -0
  116. package/dist/tsup/utils-CT0cv4jd.d.cts +17 -0
  117. package/dist/tsup/utils-CT0cv4jd.d.ts +17 -0
  118. package/dist/tsup/utils.cjs +26 -0
  119. package/dist/tsup/utils.cjs.map +1 -0
  120. package/dist/tsup/utils.d.cts +36 -0
  121. package/dist/tsup/utils.d.ts +36 -0
  122. package/dist/tsup/utils.js +26 -0
  123. package/dist/tsup/utils.js.map +1 -0
  124. package/package.json +208 -5
  125. package/src/actor/action.ts +182 -0
  126. package/src/actor/config.ts +765 -0
  127. package/src/actor/connection.ts +260 -0
  128. package/src/actor/context.ts +171 -0
  129. package/src/actor/database.ts +23 -0
  130. package/src/actor/definition.ts +86 -0
  131. package/src/actor/driver.ts +84 -0
  132. package/src/actor/errors.ts +360 -0
  133. package/src/actor/generic-conn-driver.ts +234 -0
  134. package/src/actor/instance.ts +1800 -0
  135. package/src/actor/log.ts +15 -0
  136. package/src/actor/mod.ts +113 -0
  137. package/src/actor/persisted.ts +42 -0
  138. package/src/actor/protocol/old.ts +281 -0
  139. package/src/actor/protocol/serde.ts +131 -0
  140. package/src/actor/router-endpoints.ts +685 -0
  141. package/src/actor/router.ts +263 -0
  142. package/src/actor/schedule.ts +17 -0
  143. package/src/actor/unstable-react.ts +110 -0
  144. package/src/actor/utils.ts +98 -0
  145. package/src/client/actor-common.ts +30 -0
  146. package/src/client/actor-conn.ts +804 -0
  147. package/src/client/actor-handle.ts +208 -0
  148. package/src/client/client.ts +623 -0
  149. package/src/client/errors.ts +41 -0
  150. package/src/client/http-client-driver.ts +326 -0
  151. package/src/client/log.ts +7 -0
  152. package/src/client/mod.ts +56 -0
  153. package/src/client/raw-utils.ts +92 -0
  154. package/src/client/test.ts +44 -0
  155. package/src/client/utils.ts +150 -0
  156. package/src/common/eventsource-interface.ts +47 -0
  157. package/src/common/eventsource.ts +80 -0
  158. package/src/common/fake-event-source.ts +266 -0
  159. package/src/common/inline-websocket-adapter2.ts +445 -0
  160. package/src/common/log-levels.ts +27 -0
  161. package/src/common/log.ts +139 -0
  162. package/src/common/logfmt.ts +228 -0
  163. package/src/common/network.ts +2 -0
  164. package/src/common/router.ts +87 -0
  165. package/src/common/utils.ts +322 -0
  166. package/src/common/versioned-data.ts +95 -0
  167. package/src/common/websocket-interface.ts +49 -0
  168. package/src/common/websocket.ts +43 -0
  169. package/src/driver-helpers/mod.ts +22 -0
  170. package/src/driver-helpers/utils.ts +17 -0
  171. package/src/driver-test-suite/log.ts +7 -0
  172. package/src/driver-test-suite/mod.ts +213 -0
  173. package/src/driver-test-suite/test-inline-client-driver.ts +402 -0
  174. package/src/driver-test-suite/tests/action-features.ts +136 -0
  175. package/src/driver-test-suite/tests/actor-auth.ts +591 -0
  176. package/src/driver-test-suite/tests/actor-conn-state.ts +249 -0
  177. package/src/driver-test-suite/tests/actor-conn.ts +349 -0
  178. package/src/driver-test-suite/tests/actor-driver.ts +25 -0
  179. package/src/driver-test-suite/tests/actor-error-handling.ts +158 -0
  180. package/src/driver-test-suite/tests/actor-handle.ts +259 -0
  181. package/src/driver-test-suite/tests/actor-inline-client.ts +152 -0
  182. package/src/driver-test-suite/tests/actor-inspector.ts +570 -0
  183. package/src/driver-test-suite/tests/actor-metadata.ts +116 -0
  184. package/src/driver-test-suite/tests/actor-onstatechange.ts +95 -0
  185. package/src/driver-test-suite/tests/actor-schedule.ts +108 -0
  186. package/src/driver-test-suite/tests/actor-sleep.ts +413 -0
  187. package/src/driver-test-suite/tests/actor-state.ts +54 -0
  188. package/src/driver-test-suite/tests/actor-vars.ts +93 -0
  189. package/src/driver-test-suite/tests/manager-driver.ts +365 -0
  190. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +226 -0
  191. package/src/driver-test-suite/tests/raw-http-request-properties.ts +414 -0
  192. package/src/driver-test-suite/tests/raw-http.ts +347 -0
  193. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +392 -0
  194. package/src/driver-test-suite/tests/raw-websocket.ts +484 -0
  195. package/src/driver-test-suite/tests/request-access.ts +244 -0
  196. package/src/driver-test-suite/utils.ts +68 -0
  197. package/src/drivers/default.ts +31 -0
  198. package/src/drivers/engine/actor-driver.ts +360 -0
  199. package/src/drivers/engine/api-endpoints.ts +128 -0
  200. package/src/drivers/engine/api-utils.ts +70 -0
  201. package/src/drivers/engine/config.ts +39 -0
  202. package/src/drivers/engine/keys.test.ts +266 -0
  203. package/src/drivers/engine/keys.ts +89 -0
  204. package/src/drivers/engine/kv.ts +3 -0
  205. package/src/drivers/engine/log.ts +7 -0
  206. package/src/drivers/engine/manager-driver.ts +391 -0
  207. package/src/drivers/engine/mod.ts +36 -0
  208. package/src/drivers/engine/ws-proxy.ts +170 -0
  209. package/src/drivers/file-system/actor.ts +91 -0
  210. package/src/drivers/file-system/global-state.ts +673 -0
  211. package/src/drivers/file-system/log.ts +7 -0
  212. package/src/drivers/file-system/manager.ts +306 -0
  213. package/src/drivers/file-system/mod.ts +48 -0
  214. package/src/drivers/file-system/utils.ts +109 -0
  215. package/src/globals.d.ts +6 -0
  216. package/src/inline-client-driver/log.ts +7 -0
  217. package/src/inline-client-driver/mod.ts +385 -0
  218. package/src/inspector/actor.ts +298 -0
  219. package/src/inspector/config.ts +83 -0
  220. package/src/inspector/log.ts +5 -0
  221. package/src/inspector/manager.ts +86 -0
  222. package/src/inspector/mod.ts +2 -0
  223. package/src/inspector/protocol/actor.ts +10 -0
  224. package/src/inspector/protocol/common.ts +196 -0
  225. package/src/inspector/protocol/manager.ts +10 -0
  226. package/src/inspector/protocol/mod.ts +2 -0
  227. package/src/inspector/utils.ts +76 -0
  228. package/src/manager/auth.ts +121 -0
  229. package/src/manager/driver.ts +80 -0
  230. package/src/manager/hono-websocket-adapter.ts +333 -0
  231. package/src/manager/log.ts +7 -0
  232. package/src/manager/mod.ts +2 -0
  233. package/src/manager/protocol/mod.ts +24 -0
  234. package/src/manager/protocol/query.ts +89 -0
  235. package/src/manager/router.ts +1792 -0
  236. package/src/mod.ts +20 -0
  237. package/src/registry/config.ts +32 -0
  238. package/src/registry/log.ts +7 -0
  239. package/src/registry/mod.ts +124 -0
  240. package/src/registry/run-config.ts +54 -0
  241. package/src/registry/serve.ts +53 -0
  242. package/src/schemas/actor-persist/mod.ts +1 -0
  243. package/src/schemas/actor-persist/versioned.ts +25 -0
  244. package/src/schemas/client-protocol/mod.ts +1 -0
  245. package/src/schemas/client-protocol/versioned.ts +63 -0
  246. package/src/schemas/file-system-driver/mod.ts +1 -0
  247. package/src/schemas/file-system-driver/versioned.ts +28 -0
  248. package/src/serde.ts +84 -0
  249. package/src/test/config.ts +16 -0
  250. package/src/test/log.ts +7 -0
  251. package/src/test/mod.ts +153 -0
  252. package/src/utils.ts +172 -0
  253. package/README.md +0 -13
@@ -0,0 +1,158 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import {
3
+ INTERNAL_ERROR_CODE,
4
+ INTERNAL_ERROR_DESCRIPTION,
5
+ } from "@/actor/errors";
6
+ import { assertUnreachable } from "@/actor/utils";
7
+ import type { DriverTestConfig } from "../mod";
8
+ import { setupDriverTest } from "../utils";
9
+
10
+ export function runActorErrorHandlingTests(driverTestConfig: DriverTestConfig) {
11
+ describe("Actor Error Handling Tests", () => {
12
+ describe("UserError Handling", () => {
13
+ test("should handle simple UserError with message", async (c) => {
14
+ const { client } = await setupDriverTest(c, driverTestConfig);
15
+
16
+ // Try to call an action that throws a simple UserError
17
+ const handle = client.errorHandlingActor.getOrCreate();
18
+
19
+ try {
20
+ await handle.throwSimpleError();
21
+ // If we get here, the test should fail
22
+ expect(true).toBe(false); // This should not be reached
23
+ } catch (error: any) {
24
+ // Verify the error properties
25
+ expect(error.message).toBe("Simple error message");
26
+ // Default code is "user_error" when not specified
27
+ expect(error.code).toBe("user_error");
28
+ // No metadata by default
29
+ expect(error.metadata).toBeUndefined();
30
+ }
31
+ });
32
+
33
+ test("should handle detailed UserError with code and metadata", async (c) => {
34
+ const { client } = await setupDriverTest(c, driverTestConfig);
35
+
36
+ // Try to call an action that throws a detailed UserError
37
+ const handle = client.errorHandlingActor.getOrCreate();
38
+
39
+ try {
40
+ await handle.throwDetailedError();
41
+ // If we get here, the test should fail
42
+ expect(true).toBe(false); // This should not be reached
43
+ } catch (error: any) {
44
+ // Verify the error properties
45
+ expect(error.message).toBe("Detailed error message");
46
+ expect(error.code).toBe("detailed_error");
47
+ expect(error.metadata).toBeDefined();
48
+ expect(error.metadata.reason).toBe("test");
49
+ expect(error.metadata.timestamp).toBeDefined();
50
+ }
51
+ });
52
+ });
53
+
54
+ describe("Internal Error Handling", () => {
55
+ test("should convert internal errors to safe format", async (c) => {
56
+ const { client } = await setupDriverTest(c, driverTestConfig);
57
+
58
+ // Try to call an action that throws an internal error
59
+ const handle = client.errorHandlingActor.getOrCreate();
60
+
61
+ try {
62
+ await handle.throwInternalError();
63
+ // If we get here, the test should fail
64
+ expect(true).toBe(false); // This should not be reached
65
+ } catch (error: any) {
66
+ if (driverTestConfig.clientType === "http") {
67
+ // Verify the error is converted to a safe format
68
+ expect(error.code).toBe(INTERNAL_ERROR_CODE);
69
+ // Original error details should not be exposed
70
+ expect(error.message).toBe(INTERNAL_ERROR_DESCRIPTION);
71
+ } else if (driverTestConfig.clientType === "inline") {
72
+ // Verify that original error is preserved
73
+ expect(error.code).toBe(INTERNAL_ERROR_CODE);
74
+ expect(error.message).toBe("This is an internal error");
75
+ } else {
76
+ assertUnreachable(driverTestConfig.clientType);
77
+ }
78
+ }
79
+ });
80
+ });
81
+
82
+ // TODO: Does not work with fake timers
83
+ describe.skip("Action Timeout", () => {
84
+ test("should handle action timeouts with custom duration", async (c) => {
85
+ const { client } = await setupDriverTest(c, driverTestConfig);
86
+
87
+ // Call an action that should time out
88
+ const handle = client.errorHandlingActor.getOrCreate();
89
+
90
+ // This should throw a timeout error because errorHandlingActor has
91
+ // a 500ms timeout and this action tries to run for much longer
92
+ const timeoutPromise = handle.timeoutAction();
93
+
94
+ try {
95
+ await timeoutPromise;
96
+ // If we get here, the test failed - timeout didn't occur
97
+ expect(true).toBe(false); // This should not be reached
98
+ } catch (error: any) {
99
+ // Verify it's a timeout error
100
+ expect(error.message).toMatch(/timed out/i);
101
+ }
102
+ });
103
+
104
+ test("should successfully run actions within timeout", async (c) => {
105
+ const { client } = await setupDriverTest(c, driverTestConfig);
106
+
107
+ // Call an action with a delay shorter than the timeout
108
+ const handle = client.errorHandlingActor.getOrCreate();
109
+
110
+ // This should succeed because 200ms < 500ms timeout
111
+ const result = await handle.delayedAction(200);
112
+ expect(result).toBe("Completed after 200ms");
113
+ });
114
+
115
+ test("should respect different timeouts for different actors", async (c) => {
116
+ const { client } = await setupDriverTest(c, driverTestConfig);
117
+
118
+ // The following actors have different timeout settings:
119
+ // customTimeoutActor: 200ms timeout
120
+ // standardTimeoutActor: default timeout (much longer)
121
+
122
+ // This should fail - 300ms delay with 200ms timeout
123
+ try {
124
+ await client.customTimeoutActor.getOrCreate().slowAction();
125
+ // Should not reach here
126
+ expect(true).toBe(false);
127
+ } catch (error: any) {
128
+ expect(error.message).toMatch(/timed out/i);
129
+ }
130
+
131
+ // This should succeed - 50ms delay with 200ms timeout
132
+ const quickResult = await client.customTimeoutActor
133
+ .getOrCreate()
134
+ .quickAction();
135
+ expect(quickResult).toBe("Quick action completed");
136
+ });
137
+ });
138
+
139
+ describe("Error Recovery", () => {
140
+ test("should continue working after errors", async (c) => {
141
+ const { client } = await setupDriverTest(c, driverTestConfig);
142
+
143
+ const handle = client.errorHandlingActor.getOrCreate();
144
+
145
+ // Trigger an error
146
+ try {
147
+ await handle.throwSimpleError();
148
+ } catch (error) {
149
+ // Ignore error
150
+ }
151
+
152
+ // Actor should still work after error
153
+ const result = await handle.successfulAction();
154
+ expect(result).toBe("success");
155
+ });
156
+ });
157
+ });
158
+ }
@@ -0,0 +1,259 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import type { DriverTestConfig } from "../mod";
3
+ import { setupDriverTest } from "../utils";
4
+
5
+ export function runActorHandleTests(driverTestConfig: DriverTestConfig) {
6
+ describe("Actor Handle Tests", () => {
7
+ describe("Access Methods", () => {
8
+ test("should use .get() to access a actor", async (c) => {
9
+ const { client } = await setupDriverTest(c, driverTestConfig);
10
+
11
+ // Create actor first
12
+ await client.counter.create(["test-get-handle"]);
13
+
14
+ // Access using get
15
+ const handle = client.counter.get(["test-get-handle"]);
16
+
17
+ // Verify Action works
18
+ const count = await handle.increment(5);
19
+ expect(count).toBe(5);
20
+
21
+ const retrievedCount = await handle.getCount();
22
+ expect(retrievedCount).toBe(5);
23
+ });
24
+
25
+ test("should use .getForId() to access a actor by ID", async (c) => {
26
+ const { client } = await setupDriverTest(c, driverTestConfig);
27
+
28
+ // Create a actor first to get its ID
29
+ const handle = client.counter.getOrCreate(["test-get-for-id-handle"]);
30
+ await handle.increment(3);
31
+ const actorId = await handle.resolve();
32
+
33
+ // Access using getForId
34
+ const idHandle = client.counter.getForId(actorId);
35
+
36
+ // Verify Action works and state is preserved
37
+ const count = await idHandle.getCount();
38
+ expect(count).toBe(3);
39
+
40
+ const newCount = await idHandle.increment(4);
41
+ expect(newCount).toBe(7);
42
+ });
43
+
44
+ test("should use .getOrCreate() to access or create a actor", async (c) => {
45
+ const { client } = await setupDriverTest(c, driverTestConfig);
46
+
47
+ // Access using getOrCreate - should create the actor
48
+ const handle = client.counter.getOrCreate([
49
+ "test-get-or-create-handle",
50
+ ]);
51
+
52
+ // Verify Action works
53
+ const count = await handle.increment(7);
54
+ expect(count).toBe(7);
55
+
56
+ // Get the same actor again - should retrieve existing actor
57
+ const sameHandle = client.counter.getOrCreate([
58
+ "test-get-or-create-handle",
59
+ ]);
60
+ const retrievedCount = await sameHandle.getCount();
61
+ expect(retrievedCount).toBe(7);
62
+ });
63
+
64
+ test("should use (await create()) to create and return a handle", async (c) => {
65
+ const { client } = await setupDriverTest(c, driverTestConfig);
66
+
67
+ // Create actor and get handle
68
+ const handle = await client.counter.create(["test-create-handle"]);
69
+
70
+ // Verify Action works
71
+ const count = await handle.increment(9);
72
+ expect(count).toBe(9);
73
+
74
+ const retrievedCount = await handle.getCount();
75
+ expect(retrievedCount).toBe(9);
76
+ });
77
+ });
78
+
79
+ describe("Action Functionality", () => {
80
+ test("should call actions directly on the handle", async (c) => {
81
+ const { client } = await setupDriverTest(c, driverTestConfig);
82
+
83
+ const handle = client.counter.getOrCreate(["test-action-handle"]);
84
+
85
+ // Call multiple actions in sequence
86
+ const count1 = await handle.increment(3);
87
+ expect(count1).toBe(3);
88
+
89
+ const count2 = await handle.increment(5);
90
+ expect(count2).toBe(8);
91
+
92
+ const retrievedCount = await handle.getCount();
93
+ expect(retrievedCount).toBe(8);
94
+ });
95
+
96
+ test("should handle independent handles to the same actor", async (c) => {
97
+ const { client } = await setupDriverTest(c, driverTestConfig);
98
+
99
+ // Create two handles to the same actor
100
+ const handle1 = client.counter.getOrCreate(["test-multiple-handles"]);
101
+ const handle2 = client.counter.get(["test-multiple-handles"]);
102
+
103
+ // Call actions on both handles
104
+ await handle1.increment(3);
105
+ const count = await handle2.getCount();
106
+
107
+ // Verify both handles access the same state
108
+ expect(count).toBe(3);
109
+
110
+ const finalCount = await handle2.increment(4);
111
+ expect(finalCount).toBe(7);
112
+
113
+ const checkCount = await handle1.getCount();
114
+ expect(checkCount).toBe(7);
115
+ });
116
+
117
+ test("should resolve a actor's ID", async (c) => {
118
+ const { client } = await setupDriverTest(c, driverTestConfig);
119
+
120
+ const handle = client.counter.getOrCreate(["test-resolve-id"]);
121
+
122
+ // Call an action to ensure actor exists
123
+ await handle.increment(1);
124
+
125
+ // Resolve the ID
126
+ const actorId = await handle.resolve();
127
+
128
+ // Verify we got a valid ID (string)
129
+ expect(typeof actorId).toBe("string");
130
+ expect(actorId).not.toBe("");
131
+
132
+ // Verify we can use this ID to get the actor
133
+ const idHandle = client.counter.getForId(actorId);
134
+ const count = await idHandle.getCount();
135
+ expect(count).toBe(1);
136
+ });
137
+ });
138
+
139
+ describe("Lifecycle Hooks", () => {
140
+ test("should trigger lifecycle hooks on actor creation", async (c) => {
141
+ const { client } = await setupDriverTest(c, driverTestConfig);
142
+
143
+ // Get or create a new actor - this should trigger onStart
144
+ const handle = client.counterWithLifecycle.getOrCreate([
145
+ "test-lifecycle-handle",
146
+ ]);
147
+
148
+ // Verify onStart was triggered
149
+ const initialEvents = await handle.getEvents();
150
+ expect(initialEvents).toContain("onStart");
151
+
152
+ // Create a separate handle to the same actor
153
+ const sameHandle = client.counterWithLifecycle.getOrCreate([
154
+ "test-lifecycle-handle",
155
+ ]);
156
+
157
+ // Verify events still include onStart but don't duplicate it
158
+ // (onStart should only be called once when the actor is first created)
159
+ const events = await sameHandle.getEvents();
160
+ expect(events).toContain("onStart");
161
+ expect(events.filter((e) => e === "onStart").length).toBe(1);
162
+ });
163
+
164
+ test("should trigger lifecycle hooks for each Action call", async (c) => {
165
+ const { client } = await setupDriverTest(c, driverTestConfig);
166
+
167
+ // Create a normal handle to view events
168
+ const viewHandle = client.counterWithLifecycle.getOrCreate([
169
+ "test-lifecycle-action",
170
+ ]);
171
+
172
+ // Initial state should only have onStart
173
+ const initialEvents = await viewHandle.getEvents();
174
+ expect(initialEvents).toContain("onStart");
175
+ expect(initialEvents).not.toContain("onBeforeConnect");
176
+ expect(initialEvents).not.toContain("onConnect");
177
+ expect(initialEvents).not.toContain("onDisconnect");
178
+
179
+ // Create a handle with trackLifecycle enabled for testing Action calls
180
+ const trackingHandle = client.counterWithLifecycle.getOrCreate(
181
+ ["test-lifecycle-action"],
182
+ { params: { trackLifecycle: true } },
183
+ );
184
+
185
+ // Make an Action call
186
+ await trackingHandle.increment(5);
187
+
188
+ // Check that it triggered the lifecycle hooks
189
+ const eventsAfterAction = await viewHandle.getEvents();
190
+
191
+ // Should have onBeforeConnect, onConnect, and onDisconnect for the Action call
192
+ expect(eventsAfterAction).toContain("onBeforeConnect");
193
+ expect(eventsAfterAction).toContain("onConnect");
194
+ expect(eventsAfterAction).toContain("onDisconnect");
195
+
196
+ // Each should have count 1
197
+ expect(
198
+ eventsAfterAction.filter((e) => e === "onBeforeConnect").length,
199
+ ).toBe(1);
200
+ expect(eventsAfterAction.filter((e) => e === "onConnect").length).toBe(
201
+ 1,
202
+ );
203
+ expect(
204
+ eventsAfterAction.filter((e) => e === "onDisconnect").length,
205
+ ).toBe(1);
206
+
207
+ // Make another Action call
208
+ await trackingHandle.increment(10);
209
+
210
+ // Check that it triggered another set of lifecycle hooks
211
+ const eventsAfterSecondAction = await viewHandle.getEvents();
212
+
213
+ // Each hook should now have count 2
214
+ expect(
215
+ eventsAfterSecondAction.filter((e) => e === "onBeforeConnect").length,
216
+ ).toBe(2);
217
+ expect(
218
+ eventsAfterSecondAction.filter((e) => e === "onConnect").length,
219
+ ).toBe(2);
220
+ expect(
221
+ eventsAfterSecondAction.filter((e) => e === "onDisconnect").length,
222
+ ).toBe(2);
223
+ });
224
+
225
+ test("should trigger lifecycle hooks for each Action call across multiple handles", async (c) => {
226
+ const { client } = await setupDriverTest(c, driverTestConfig);
227
+
228
+ // Create a normal handle to view events
229
+ const viewHandle = client.counterWithLifecycle.getOrCreate([
230
+ "test-lifecycle-multi-handle",
231
+ ]);
232
+
233
+ // Create two tracking handles to the same actor
234
+ const trackingHandle1 = client.counterWithLifecycle.getOrCreate(
235
+ ["test-lifecycle-multi-handle"],
236
+ { params: { trackLifecycle: true } },
237
+ );
238
+
239
+ const trackingHandle2 = client.counterWithLifecycle.getOrCreate(
240
+ ["test-lifecycle-multi-handle"],
241
+ { params: { trackLifecycle: true } },
242
+ );
243
+
244
+ // Make Action calls on both handles
245
+ await trackingHandle1.increment(5);
246
+ await trackingHandle2.increment(10);
247
+
248
+ // Check lifecycle hooks
249
+ const events = await viewHandle.getEvents();
250
+
251
+ // Should have 1 onStart, 2 each of onBeforeConnect, onConnect, and onDisconnect
252
+ expect(events.filter((e) => e === "onStart").length).toBe(1);
253
+ expect(events.filter((e) => e === "onBeforeConnect").length).toBe(2);
254
+ expect(events.filter((e) => e === "onConnect").length).toBe(2);
255
+ expect(events.filter((e) => e === "onDisconnect").length).toBe(2);
256
+ });
257
+ });
258
+ });
259
+ }
@@ -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
+ }