@voidhash/mimic-effect 0.0.9 → 1.0.0-beta.2

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 (227) hide show
  1. package/.turbo/turbo-build.log +136 -90
  2. package/README.md +385 -0
  3. package/dist/ColdStorage.cjs +60 -0
  4. package/dist/ColdStorage.d.cts +53 -0
  5. package/dist/ColdStorage.d.cts.map +1 -0
  6. package/dist/ColdStorage.d.mts +53 -0
  7. package/dist/ColdStorage.d.mts.map +1 -0
  8. package/dist/ColdStorage.mjs +60 -0
  9. package/dist/ColdStorage.mjs.map +1 -0
  10. package/dist/DocumentManager.cjs +263 -82
  11. package/dist/DocumentManager.d.cts +44 -22
  12. package/dist/DocumentManager.d.cts.map +1 -1
  13. package/dist/DocumentManager.d.mts +44 -22
  14. package/dist/DocumentManager.d.mts.map +1 -1
  15. package/dist/DocumentManager.mjs +259 -67
  16. package/dist/DocumentManager.mjs.map +1 -1
  17. package/dist/Errors.cjs +54 -0
  18. package/dist/Errors.d.cts +96 -0
  19. package/dist/Errors.d.cts.map +1 -0
  20. package/dist/Errors.d.mts +96 -0
  21. package/dist/Errors.d.mts.map +1 -0
  22. package/dist/Errors.mjs +48 -0
  23. package/dist/Errors.mjs.map +1 -0
  24. package/dist/HotStorage.cjs +100 -0
  25. package/dist/HotStorage.d.cts +70 -0
  26. package/dist/HotStorage.d.cts.map +1 -0
  27. package/dist/HotStorage.d.mts +70 -0
  28. package/dist/HotStorage.d.mts.map +1 -0
  29. package/dist/HotStorage.mjs +100 -0
  30. package/dist/HotStorage.mjs.map +1 -0
  31. package/dist/Metrics.cjs +143 -0
  32. package/dist/Metrics.d.cts +31 -0
  33. package/dist/Metrics.d.cts.map +1 -0
  34. package/dist/Metrics.d.mts +31 -0
  35. package/dist/Metrics.d.mts.map +1 -0
  36. package/dist/Metrics.mjs +126 -0
  37. package/dist/Metrics.mjs.map +1 -0
  38. package/dist/MimicAuthService.cjs +61 -45
  39. package/dist/MimicAuthService.d.cts +61 -48
  40. package/dist/MimicAuthService.d.cts.map +1 -1
  41. package/dist/MimicAuthService.d.mts +61 -48
  42. package/dist/MimicAuthService.d.mts.map +1 -1
  43. package/dist/MimicAuthService.mjs +60 -36
  44. package/dist/MimicAuthService.mjs.map +1 -1
  45. package/dist/MimicClusterServerEngine.cjs +521 -0
  46. package/dist/MimicClusterServerEngine.d.cts +17 -0
  47. package/dist/MimicClusterServerEngine.d.cts.map +1 -0
  48. package/dist/MimicClusterServerEngine.d.mts +17 -0
  49. package/dist/MimicClusterServerEngine.d.mts.map +1 -0
  50. package/dist/MimicClusterServerEngine.mjs +523 -0
  51. package/dist/MimicClusterServerEngine.mjs.map +1 -0
  52. package/dist/MimicServer.cjs +205 -96
  53. package/dist/MimicServer.d.cts +9 -110
  54. package/dist/MimicServer.d.cts.map +1 -1
  55. package/dist/MimicServer.d.mts +9 -110
  56. package/dist/MimicServer.d.mts.map +1 -1
  57. package/dist/MimicServer.mjs +206 -90
  58. package/dist/MimicServer.mjs.map +1 -1
  59. package/dist/MimicServerEngine.cjs +97 -0
  60. package/dist/MimicServerEngine.d.cts +78 -0
  61. package/dist/MimicServerEngine.d.cts.map +1 -0
  62. package/dist/MimicServerEngine.d.mts +78 -0
  63. package/dist/MimicServerEngine.d.mts.map +1 -0
  64. package/dist/MimicServerEngine.mjs +97 -0
  65. package/dist/MimicServerEngine.mjs.map +1 -0
  66. package/dist/PresenceManager.cjs +75 -91
  67. package/dist/PresenceManager.d.cts +17 -66
  68. package/dist/PresenceManager.d.cts.map +1 -1
  69. package/dist/PresenceManager.d.mts +17 -66
  70. package/dist/PresenceManager.d.mts.map +1 -1
  71. package/dist/PresenceManager.mjs +74 -78
  72. package/dist/PresenceManager.mjs.map +1 -1
  73. package/dist/Protocol.cjs +146 -0
  74. package/dist/Protocol.d.cts +203 -0
  75. package/dist/Protocol.d.cts.map +1 -0
  76. package/dist/Protocol.d.mts +203 -0
  77. package/dist/Protocol.d.mts.map +1 -0
  78. package/dist/Protocol.mjs +132 -0
  79. package/dist/Protocol.mjs.map +1 -0
  80. package/dist/Types.d.cts +172 -0
  81. package/dist/Types.d.cts.map +1 -0
  82. package/dist/Types.d.mts +172 -0
  83. package/dist/Types.d.mts.map +1 -0
  84. package/dist/_virtual/rolldown_runtime.cjs +1 -25
  85. package/dist/_virtual/rolldown_runtime.mjs +4 -1
  86. package/dist/index.cjs +37 -75
  87. package/dist/index.d.cts +13 -12
  88. package/dist/index.d.mts +13 -12
  89. package/dist/index.mjs +12 -12
  90. package/dist/testing/ColdStorageTestSuite.cjs +508 -0
  91. package/dist/testing/ColdStorageTestSuite.d.cts +36 -0
  92. package/dist/testing/ColdStorageTestSuite.d.cts.map +1 -0
  93. package/dist/testing/ColdStorageTestSuite.d.mts +36 -0
  94. package/dist/testing/ColdStorageTestSuite.d.mts.map +1 -0
  95. package/dist/testing/ColdStorageTestSuite.mjs +508 -0
  96. package/dist/testing/ColdStorageTestSuite.mjs.map +1 -0
  97. package/dist/testing/FailingStorage.cjs +135 -0
  98. package/dist/testing/FailingStorage.d.cts +43 -0
  99. package/dist/testing/FailingStorage.d.cts.map +1 -0
  100. package/dist/testing/FailingStorage.d.mts +43 -0
  101. package/dist/testing/FailingStorage.d.mts.map +1 -0
  102. package/dist/testing/FailingStorage.mjs +136 -0
  103. package/dist/testing/FailingStorage.mjs.map +1 -0
  104. package/dist/testing/HotStorageTestSuite.cjs +585 -0
  105. package/dist/testing/HotStorageTestSuite.d.cts +40 -0
  106. package/dist/testing/HotStorageTestSuite.d.cts.map +1 -0
  107. package/dist/testing/HotStorageTestSuite.d.mts +40 -0
  108. package/dist/testing/HotStorageTestSuite.d.mts.map +1 -0
  109. package/dist/testing/HotStorageTestSuite.mjs +585 -0
  110. package/dist/testing/HotStorageTestSuite.mjs.map +1 -0
  111. package/dist/testing/StorageIntegrationTestSuite.cjs +349 -0
  112. package/dist/testing/StorageIntegrationTestSuite.d.cts +35 -0
  113. package/dist/testing/StorageIntegrationTestSuite.d.cts.map +1 -0
  114. package/dist/testing/StorageIntegrationTestSuite.d.mts +35 -0
  115. package/dist/testing/StorageIntegrationTestSuite.d.mts.map +1 -0
  116. package/dist/testing/StorageIntegrationTestSuite.mjs +349 -0
  117. package/dist/testing/StorageIntegrationTestSuite.mjs.map +1 -0
  118. package/dist/testing/assertions.cjs +114 -0
  119. package/dist/testing/assertions.mjs +109 -0
  120. package/dist/testing/assertions.mjs.map +1 -0
  121. package/dist/testing/index.cjs +14 -0
  122. package/dist/testing/index.d.cts +6 -0
  123. package/dist/testing/index.d.mts +6 -0
  124. package/dist/testing/index.mjs +7 -0
  125. package/dist/testing/types.cjs +15 -0
  126. package/dist/testing/types.d.cts +90 -0
  127. package/dist/testing/types.d.cts.map +1 -0
  128. package/dist/testing/types.d.mts +90 -0
  129. package/dist/testing/types.d.mts.map +1 -0
  130. package/dist/testing/types.mjs +16 -0
  131. package/dist/testing/types.mjs.map +1 -0
  132. package/package.json +18 -3
  133. package/src/ColdStorage.ts +136 -0
  134. package/src/DocumentManager.ts +550 -190
  135. package/src/Errors.ts +114 -0
  136. package/src/HotStorage.ts +239 -0
  137. package/src/Metrics.ts +187 -0
  138. package/src/MimicAuthService.ts +126 -64
  139. package/src/MimicClusterServerEngine.ts +946 -0
  140. package/src/MimicServer.ts +448 -195
  141. package/src/MimicServerEngine.ts +276 -0
  142. package/src/PresenceManager.ts +169 -240
  143. package/src/Protocol.ts +350 -0
  144. package/src/Types.ts +231 -0
  145. package/src/index.ts +57 -23
  146. package/src/testing/ColdStorageTestSuite.ts +589 -0
  147. package/src/testing/FailingStorage.ts +286 -0
  148. package/src/testing/HotStorageTestSuite.ts +762 -0
  149. package/src/testing/StorageIntegrationTestSuite.ts +504 -0
  150. package/src/testing/assertions.ts +181 -0
  151. package/src/testing/index.ts +83 -0
  152. package/src/testing/types.ts +100 -0
  153. package/tests/ColdStorage.test.ts +24 -0
  154. package/tests/DocumentManager.test.ts +158 -287
  155. package/tests/HotStorage.test.ts +24 -0
  156. package/tests/MimicAuthService.test.ts +102 -134
  157. package/tests/MimicClusterServerEngine.test.ts +587 -0
  158. package/tests/MimicServer.test.ts +90 -226
  159. package/tests/MimicServerEngine.test.ts +521 -0
  160. package/tests/PresenceManager.test.ts +22 -63
  161. package/tests/Protocol.test.ts +190 -0
  162. package/tests/StorageIntegration.test.ts +259 -0
  163. package/tsconfig.json +1 -1
  164. package/tsdown.config.ts +1 -1
  165. package/dist/DocumentProtocol.cjs +0 -94
  166. package/dist/DocumentProtocol.d.cts +0 -113
  167. package/dist/DocumentProtocol.d.cts.map +0 -1
  168. package/dist/DocumentProtocol.d.mts +0 -113
  169. package/dist/DocumentProtocol.d.mts.map +0 -1
  170. package/dist/DocumentProtocol.mjs +0 -89
  171. package/dist/DocumentProtocol.mjs.map +0 -1
  172. package/dist/MimicConfig.cjs +0 -60
  173. package/dist/MimicConfig.d.cts +0 -141
  174. package/dist/MimicConfig.d.cts.map +0 -1
  175. package/dist/MimicConfig.d.mts +0 -141
  176. package/dist/MimicConfig.d.mts.map +0 -1
  177. package/dist/MimicConfig.mjs +0 -50
  178. package/dist/MimicConfig.mjs.map +0 -1
  179. package/dist/MimicDataStorage.cjs +0 -83
  180. package/dist/MimicDataStorage.d.cts +0 -113
  181. package/dist/MimicDataStorage.d.cts.map +0 -1
  182. package/dist/MimicDataStorage.d.mts +0 -113
  183. package/dist/MimicDataStorage.d.mts.map +0 -1
  184. package/dist/MimicDataStorage.mjs +0 -74
  185. package/dist/MimicDataStorage.mjs.map +0 -1
  186. package/dist/WebSocketHandler.cjs +0 -365
  187. package/dist/WebSocketHandler.d.cts +0 -34
  188. package/dist/WebSocketHandler.d.cts.map +0 -1
  189. package/dist/WebSocketHandler.d.mts +0 -34
  190. package/dist/WebSocketHandler.d.mts.map +0 -1
  191. package/dist/WebSocketHandler.mjs +0 -355
  192. package/dist/WebSocketHandler.mjs.map +0 -1
  193. package/dist/auth/NoAuth.cjs +0 -43
  194. package/dist/auth/NoAuth.d.cts +0 -22
  195. package/dist/auth/NoAuth.d.cts.map +0 -1
  196. package/dist/auth/NoAuth.d.mts +0 -22
  197. package/dist/auth/NoAuth.d.mts.map +0 -1
  198. package/dist/auth/NoAuth.mjs +0 -36
  199. package/dist/auth/NoAuth.mjs.map +0 -1
  200. package/dist/errors.cjs +0 -74
  201. package/dist/errors.d.cts +0 -89
  202. package/dist/errors.d.cts.map +0 -1
  203. package/dist/errors.d.mts +0 -89
  204. package/dist/errors.d.mts.map +0 -1
  205. package/dist/errors.mjs +0 -67
  206. package/dist/errors.mjs.map +0 -1
  207. package/dist/storage/InMemoryDataStorage.cjs +0 -57
  208. package/dist/storage/InMemoryDataStorage.d.cts +0 -19
  209. package/dist/storage/InMemoryDataStorage.d.cts.map +0 -1
  210. package/dist/storage/InMemoryDataStorage.d.mts +0 -19
  211. package/dist/storage/InMemoryDataStorage.d.mts.map +0 -1
  212. package/dist/storage/InMemoryDataStorage.mjs +0 -48
  213. package/dist/storage/InMemoryDataStorage.mjs.map +0 -1
  214. package/src/DocumentProtocol.ts +0 -112
  215. package/src/MimicConfig.ts +0 -211
  216. package/src/MimicDataStorage.ts +0 -157
  217. package/src/WebSocketHandler.ts +0 -735
  218. package/src/auth/NoAuth.ts +0 -46
  219. package/src/errors.ts +0 -113
  220. package/src/storage/InMemoryDataStorage.ts +0 -66
  221. package/tests/DocumentProtocol.test.ts +0 -113
  222. package/tests/InMemoryDataStorage.test.ts +0 -190
  223. package/tests/MimicConfig.test.ts +0 -290
  224. package/tests/MimicDataStorage.test.ts +0 -190
  225. package/tests/NoAuth.test.ts +0 -94
  226. package/tests/WebSocketHandler.test.ts +0 -321
  227. package/tests/errors.test.ts +0 -77
@@ -1,290 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import * as Effect from "effect/Effect";
3
- import * as Duration from "effect/Duration";
4
- import * as Schema from "effect/Schema";
5
- import { Primitive, Presence } from "@voidhash/mimic";
6
- import * as MimicConfig from "../src/MimicConfig";
7
-
8
- // =============================================================================
9
- // Test Schema
10
- // =============================================================================
11
-
12
- const TestSchema = Primitive.Struct({
13
- title: Primitive.String().default(""),
14
- count: Primitive.Number().default(0),
15
- });
16
-
17
- // =============================================================================
18
- // MimicConfig Tests
19
- // =============================================================================
20
-
21
- describe("MimicConfig", () => {
22
- describe("make", () => {
23
- it("should create config with default values", () => {
24
- const config = MimicConfig.make({
25
- schema: TestSchema,
26
- });
27
-
28
- expect(config.schema).toBe(TestSchema);
29
- expect(Duration.toMillis(config.maxIdleTime)).toBe(5 * 60 * 1000); // 5 minutes
30
- expect(config.maxTransactionHistory).toBe(1000);
31
- expect(Duration.toMillis(config.heartbeatInterval)).toBe(30 * 1000); // 30 seconds
32
- expect(Duration.toMillis(config.heartbeatTimeout)).toBe(10 * 1000); // 10 seconds
33
- });
34
-
35
- it("should accept custom maxIdleTime", () => {
36
- const config = MimicConfig.make({
37
- schema: TestSchema,
38
- maxIdleTime: "10 minutes",
39
- });
40
-
41
- expect(Duration.toMillis(config.maxIdleTime)).toBe(10 * 60 * 1000);
42
- });
43
-
44
- it("should accept custom maxTransactionHistory", () => {
45
- const config = MimicConfig.make({
46
- schema: TestSchema,
47
- maxTransactionHistory: 500,
48
- });
49
-
50
- expect(config.maxTransactionHistory).toBe(500);
51
- });
52
-
53
- it("should accept custom heartbeatInterval", () => {
54
- const config = MimicConfig.make({
55
- schema: TestSchema,
56
- heartbeatInterval: "1 minute",
57
- });
58
-
59
- expect(Duration.toMillis(config.heartbeatInterval)).toBe(60 * 1000);
60
- });
61
-
62
- it("should accept custom heartbeatTimeout", () => {
63
- const config = MimicConfig.make({
64
- schema: TestSchema,
65
- heartbeatTimeout: "30 seconds",
66
- });
67
-
68
- expect(Duration.toMillis(config.heartbeatTimeout)).toBe(30 * 1000);
69
- });
70
-
71
- it("should accept all custom values", () => {
72
- const config = MimicConfig.make({
73
- schema: TestSchema,
74
- maxIdleTime: "15 minutes",
75
- maxTransactionHistory: 2000,
76
- heartbeatInterval: "45 seconds",
77
- heartbeatTimeout: "15 seconds",
78
- });
79
-
80
- expect(config.schema).toBe(TestSchema);
81
- expect(Duration.toMillis(config.maxIdleTime)).toBe(15 * 60 * 1000);
82
- expect(config.maxTransactionHistory).toBe(2000);
83
- expect(Duration.toMillis(config.heartbeatInterval)).toBe(45 * 1000);
84
- expect(Duration.toMillis(config.heartbeatTimeout)).toBe(15 * 1000);
85
- });
86
- });
87
-
88
- describe("layer", () => {
89
- it("should create a layer that provides MimicServerConfigTag", async () => {
90
- const testLayer = MimicConfig.layer({
91
- schema: TestSchema,
92
- maxTransactionHistory: 100,
93
- });
94
-
95
- const result = await Effect.runPromise(
96
- Effect.gen(function* () {
97
- const config = yield* MimicConfig.MimicServerConfigTag;
98
- return config;
99
- }).pipe(Effect.provide(testLayer))
100
- );
101
-
102
- expect(result.schema).toBe(TestSchema);
103
- expect(result.maxTransactionHistory).toBe(100);
104
- });
105
- });
106
-
107
- describe("MimicServerConfigTag", () => {
108
- it("should have the correct tag identifier", () => {
109
- expect(MimicConfig.MimicServerConfigTag.key).toBe(
110
- "@voidhash/mimic-server-effect/MimicServerConfig"
111
- );
112
- });
113
- });
114
-
115
- describe("presence configuration", () => {
116
- const CursorPresence = Presence.make({
117
- schema: Schema.Struct({
118
- x: Schema.Number,
119
- y: Schema.Number,
120
- name: Schema.optional(Schema.String),
121
- }),
122
- });
123
-
124
- it("should have undefined presence by default", () => {
125
- const config = MimicConfig.make({
126
- schema: TestSchema,
127
- });
128
-
129
- expect(config.presence).toBeUndefined();
130
- });
131
-
132
- it("should accept presence schema option", () => {
133
- const config = MimicConfig.make({
134
- schema: TestSchema,
135
- presence: CursorPresence,
136
- });
137
-
138
- expect(config.presence).toBe(CursorPresence);
139
- });
140
-
141
- it("should provide presence through layer", async () => {
142
- const testLayer = MimicConfig.layer({
143
- schema: TestSchema,
144
- presence: CursorPresence,
145
- });
146
-
147
- const result = await Effect.runPromise(
148
- Effect.gen(function* () {
149
- const config = yield* MimicConfig.MimicServerConfigTag;
150
- return config.presence;
151
- }).pipe(Effect.provide(testLayer))
152
- );
153
-
154
- expect(result).toBe(CursorPresence);
155
- });
156
-
157
- it("should work with all options including presence", () => {
158
- const config = MimicConfig.make({
159
- schema: TestSchema,
160
- maxIdleTime: "10 minutes",
161
- maxTransactionHistory: 500,
162
- heartbeatInterval: "1 minute",
163
- heartbeatTimeout: "20 seconds",
164
- presence: CursorPresence,
165
- });
166
-
167
- expect(config.schema).toBe(TestSchema);
168
- expect(Duration.toMillis(config.maxIdleTime)).toBe(10 * 60 * 1000);
169
- expect(config.maxTransactionHistory).toBe(500);
170
- expect(Duration.toMillis(config.heartbeatInterval)).toBe(60 * 1000);
171
- expect(Duration.toMillis(config.heartbeatTimeout)).toBe(20 * 1000);
172
- expect(config.presence).toBe(CursorPresence);
173
- });
174
- });
175
-
176
- describe("initial state configuration", () => {
177
- it("should have undefined initial state by default", () => {
178
- const config = MimicConfig.make({
179
- schema: TestSchema,
180
- });
181
-
182
- expect(config.initial).toBeUndefined();
183
- });
184
-
185
- it("should accept initial state object and convert to function", async () => {
186
- const config = MimicConfig.make({
187
- schema: TestSchema,
188
- initial: { title: "My Document", count: 42 },
189
- });
190
-
191
- expect(typeof config.initial).toBe("function");
192
- // The function should return the initial state when called
193
- const result = await Effect.runPromise(config.initial!({ documentId: "test-doc" }));
194
- expect(result).toEqual({ title: "My Document", count: 42 });
195
- });
196
-
197
- it("should apply defaults for omitted fields in initial state object", async () => {
198
- const config = MimicConfig.make({
199
- schema: TestSchema,
200
- initial: { title: "My Document" }, // count has default of 0
201
- });
202
-
203
- const result = await Effect.runPromise(config.initial!({ documentId: "test-doc" }));
204
- expect(result).toEqual({ title: "My Document", count: 0 });
205
- });
206
-
207
- it("should accept initial state function", async () => {
208
- const config = MimicConfig.make({
209
- schema: TestSchema,
210
- initial: ({ documentId }) => Effect.succeed({ title: `Doc ${documentId}`, count: 123 }),
211
- });
212
-
213
- expect(typeof config.initial).toBe("function");
214
- const result = await Effect.runPromise(config.initial!({ documentId: "my-doc-id" }));
215
- expect(result).toEqual({ title: "Doc my-doc-id", count: 123 });
216
- });
217
-
218
- it("should apply defaults to initial state function result", async () => {
219
- const config = MimicConfig.make({
220
- schema: TestSchema,
221
- initial: ({ documentId }) => Effect.succeed({ title: documentId }), // count omitted
222
- });
223
-
224
- const result = await Effect.runPromise(config.initial!({ documentId: "test" }));
225
- expect(result).toEqual({ title: "test", count: 0 });
226
- });
227
-
228
- it("should provide initial function through layer", async () => {
229
- const testLayer = MimicConfig.layer({
230
- schema: TestSchema,
231
- initial: { title: "From Layer", count: 100 },
232
- });
233
-
234
- const result = await Effect.runPromise(
235
- Effect.gen(function* () {
236
- const config = yield* MimicConfig.MimicServerConfigTag;
237
- return yield* config.initial!({ documentId: "layer-doc" });
238
- }).pipe(Effect.provide(testLayer))
239
- );
240
-
241
- expect(result).toEqual({ title: "From Layer", count: 100 });
242
- });
243
-
244
- it("should work with schema that has required fields without defaults", async () => {
245
- const SchemaWithRequired = Primitive.Struct({
246
- name: Primitive.String().required(),
247
- optional: Primitive.String().default("default"),
248
- });
249
-
250
- const config = MimicConfig.make({
251
- schema: SchemaWithRequired,
252
- initial: { name: "Required Name" },
253
- });
254
-
255
- const result = await Effect.runPromise(config.initial!({ documentId: "test" }));
256
- expect(result).toEqual({ name: "Required Name", optional: "default" });
257
- });
258
-
259
- it("should work with all options including initial object", async () => {
260
- const config = MimicConfig.make({
261
- schema: TestSchema,
262
- maxIdleTime: "10 minutes",
263
- maxTransactionHistory: 500,
264
- initial: { title: "Full Options", count: 999 },
265
- });
266
-
267
- expect(config.schema).toBe(TestSchema);
268
- expect(Duration.toMillis(config.maxIdleTime)).toBe(10 * 60 * 1000);
269
- expect(config.maxTransactionHistory).toBe(500);
270
- const result = await Effect.runPromise(config.initial!({ documentId: "test" }));
271
- expect(result).toEqual({ title: "Full Options", count: 999 });
272
- });
273
-
274
- it("should work with initial function that uses documentId", async () => {
275
- const config = MimicConfig.make({
276
- schema: TestSchema,
277
- initial: ({ documentId }) => Effect.succeed({
278
- title: `Document: ${documentId}`,
279
- count: documentId.length,
280
- }),
281
- });
282
-
283
- const result1 = await Effect.runPromise(config.initial!({ documentId: "short" }));
284
- expect(result1).toEqual({ title: "Document: short", count: 5 });
285
-
286
- const result2 = await Effect.runPromise(config.initial!({ documentId: "longer-id" }));
287
- expect(result2).toEqual({ title: "Document: longer-id", count: 9 });
288
- });
289
- });
290
- });
@@ -1,190 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import * as Effect from "effect/Effect";
3
- import * as MimicDataStorage from "../src/MimicDataStorage";
4
-
5
- // =============================================================================
6
- // Error Tests
7
- // =============================================================================
8
-
9
- describe("MimicDataStorage", () => {
10
- describe("StorageLoadError", () => {
11
- it("should have correct message", () => {
12
- const error = new MimicDataStorage.StorageLoadError({
13
- documentId: "doc-123",
14
- cause: new Error("Connection failed"),
15
- });
16
- expect(error.message).toBe(
17
- "Failed to load document doc-123: Error: Connection failed"
18
- );
19
- expect(error._tag).toBe("StorageLoadError");
20
- expect(error.documentId).toBe("doc-123");
21
- });
22
- });
23
-
24
- describe("StorageSaveError", () => {
25
- it("should have correct message", () => {
26
- const error = new MimicDataStorage.StorageSaveError({
27
- documentId: "doc-456",
28
- cause: new Error("Disk full"),
29
- });
30
- expect(error.message).toBe(
31
- "Failed to save document doc-456: Error: Disk full"
32
- );
33
- expect(error._tag).toBe("StorageSaveError");
34
- expect(error.documentId).toBe("doc-456");
35
- });
36
- });
37
-
38
- describe("StorageDeleteError", () => {
39
- it("should have correct message", () => {
40
- const error = new MimicDataStorage.StorageDeleteError({
41
- documentId: "doc-789",
42
- cause: new Error("Permission denied"),
43
- });
44
- expect(error.message).toBe(
45
- "Failed to delete document doc-789: Error: Permission denied"
46
- );
47
- expect(error._tag).toBe("StorageDeleteError");
48
- expect(error.documentId).toBe("doc-789");
49
- });
50
- });
51
-
52
- describe("make", () => {
53
- it("should create storage with required functions", async () => {
54
- const storage = MimicDataStorage.make({
55
- load: (documentId) => Effect.succeed({ id: documentId, data: "test" }),
56
- save: (_documentId, _state) => Effect.void,
57
- });
58
-
59
- const loaded = await Effect.runPromise(storage.load("doc-1"));
60
- expect(loaded).toEqual({ id: "doc-1", data: "test" });
61
-
62
- await Effect.runPromise(storage.save("doc-1", { data: "new" }));
63
- });
64
-
65
- it("should provide default delete implementation", async () => {
66
- const storage = MimicDataStorage.make({
67
- load: (_documentId) => Effect.succeed(undefined),
68
- save: (_documentId, _state) => Effect.void,
69
- });
70
-
71
- // Default delete should be a no-op
72
- await Effect.runPromise(storage.delete("doc-1"));
73
- });
74
-
75
- it("should provide default onLoad implementation (pass-through)", async () => {
76
- const storage = MimicDataStorage.make({
77
- load: (_documentId) => Effect.succeed(undefined),
78
- save: (_documentId, _state) => Effect.void,
79
- });
80
-
81
- const state = { title: "Test" };
82
- const result = await Effect.runPromise(storage.onLoad(state));
83
- expect(result).toBe(state);
84
- });
85
-
86
- it("should provide default onSave implementation (pass-through)", async () => {
87
- const storage = MimicDataStorage.make({
88
- load: (_documentId) => Effect.succeed(undefined),
89
- save: (_documentId, _state) => Effect.void,
90
- });
91
-
92
- const state = { title: "Test" };
93
- const result = await Effect.runPromise(storage.onSave(state));
94
- expect(result).toBe(state);
95
- });
96
-
97
- it("should accept custom delete implementation", async () => {
98
- let deletedId: string | null = null;
99
- const storage = MimicDataStorage.make({
100
- load: (_documentId) => Effect.succeed(undefined),
101
- save: (_documentId, _state) => Effect.void,
102
- delete: (documentId) => {
103
- deletedId = documentId;
104
- return Effect.void;
105
- },
106
- });
107
-
108
- await Effect.runPromise(storage.delete("doc-to-delete"));
109
- expect(deletedId).toBe("doc-to-delete");
110
- });
111
-
112
- it("should accept custom onLoad implementation", async () => {
113
- const storage = MimicDataStorage.make({
114
- load: (_documentId) => Effect.succeed(undefined),
115
- save: (_documentId, _state) => Effect.void,
116
- onLoad: (state) =>
117
- Effect.succeed({ ...(state as object), loaded: true }),
118
- });
119
-
120
- const result = await Effect.runPromise(
121
- storage.onLoad({ title: "Test" })
122
- );
123
- expect(result).toEqual({ title: "Test", loaded: true });
124
- });
125
-
126
- it("should accept custom onSave implementation", async () => {
127
- const storage = MimicDataStorage.make({
128
- load: (_documentId) => Effect.succeed(undefined),
129
- save: (_documentId, _state) => Effect.void,
130
- onSave: (state) =>
131
- Effect.succeed({ ...(state as object), savedAt: "now" }),
132
- });
133
-
134
- const result = await Effect.runPromise(
135
- storage.onSave({ title: "Test" })
136
- );
137
- expect(result).toEqual({ title: "Test", savedAt: "now" });
138
- });
139
- });
140
-
141
- describe("layer", () => {
142
- it("should create a layer that provides MimicDataStorageTag", async () => {
143
- const testStorage = MimicDataStorage.make({
144
- load: (_documentId) => Effect.succeed({ test: true }),
145
- save: (_documentId, _state) => Effect.void,
146
- });
147
-
148
- const testLayer = MimicDataStorage.layer(testStorage);
149
-
150
- const result = await Effect.runPromise(
151
- Effect.gen(function* () {
152
- const storage = yield* MimicDataStorage.MimicDataStorageTag;
153
- return yield* storage.load("doc-1");
154
- }).pipe(Effect.provide(testLayer))
155
- );
156
-
157
- expect(result).toEqual({ test: true });
158
- });
159
- });
160
-
161
- describe("layerEffect", () => {
162
- it("should create a layer from an Effect", async () => {
163
- const testLayer = MimicDataStorage.layerEffect(
164
- Effect.succeed(
165
- MimicDataStorage.make({
166
- load: (_documentId) => Effect.succeed({ fromEffect: true }),
167
- save: (_documentId, _state) => Effect.void,
168
- })
169
- )
170
- );
171
-
172
- const result = await Effect.runPromise(
173
- Effect.gen(function* () {
174
- const storage = yield* MimicDataStorage.MimicDataStorageTag;
175
- return yield* storage.load("doc-1");
176
- }).pipe(Effect.provide(testLayer))
177
- );
178
-
179
- expect(result).toEqual({ fromEffect: true });
180
- });
181
- });
182
-
183
- describe("MimicDataStorageTag", () => {
184
- it("should have the correct tag identifier", () => {
185
- expect(MimicDataStorage.MimicDataStorageTag.key).toBe(
186
- "@voidhash/mimic-server-effect/MimicDataStorage"
187
- );
188
- });
189
- });
190
- });
@@ -1,94 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import * as Effect from "effect/Effect";
3
- import * as NoAuth from "../src/auth/NoAuth";
4
- import { MimicAuthServiceTag } from "../src/MimicAuthService";
5
-
6
- // =============================================================================
7
- // NoAuth Tests
8
- // =============================================================================
9
-
10
- describe("NoAuth", () => {
11
- describe("authenticate", () => {
12
- it("should always return success: true", async () => {
13
- const result = await Effect.runPromise(
14
- Effect.gen(function* () {
15
- const authService = yield* MimicAuthServiceTag;
16
- return yield* authService.authenticate("any-token");
17
- }).pipe(Effect.provide(NoAuth.layer))
18
- );
19
-
20
- expect(result).toEqual({ success: true });
21
- });
22
-
23
- it("should succeed with empty token", async () => {
24
- const result = await Effect.runPromise(
25
- Effect.gen(function* () {
26
- const authService = yield* MimicAuthServiceTag;
27
- return yield* authService.authenticate("");
28
- }).pipe(Effect.provide(NoAuth.layer))
29
- );
30
-
31
- expect(result.success).toBe(true);
32
- });
33
-
34
- it("should succeed with any arbitrary token", async () => {
35
- const tokens = [
36
- "valid-token-123",
37
- "invalid-token",
38
- "abc123xyz",
39
- "special!@#$%^&*()",
40
- "very-long-token-" + "x".repeat(1000),
41
- ];
42
-
43
- for (const token of tokens) {
44
- const result = await Effect.runPromise(
45
- Effect.gen(function* () {
46
- const authService = yield* MimicAuthServiceTag;
47
- return yield* authService.authenticate(token);
48
- }).pipe(Effect.provide(NoAuth.layer))
49
- );
50
-
51
- expect(result.success).toBe(true);
52
- }
53
- });
54
-
55
- it("should not include userId in result", async () => {
56
- const result = await Effect.runPromise(
57
- Effect.gen(function* () {
58
- const authService = yield* MimicAuthServiceTag;
59
- return yield* authService.authenticate("test-token");
60
- }).pipe(Effect.provide(NoAuth.layer))
61
- );
62
-
63
- expect(result.success).toBe(true);
64
- if (result.success) {
65
- expect(result.userId).toBeUndefined();
66
- }
67
- });
68
- });
69
-
70
- describe("layer aliases", () => {
71
- it("should have layerDefault as an alias for layer", () => {
72
- expect(NoAuth.layerDefault).toBe(NoAuth.layer);
73
- });
74
- });
75
-
76
- describe("multiple authentications", () => {
77
- it("should handle multiple sequential authentications", async () => {
78
- const results = await Effect.runPromise(
79
- Effect.gen(function* () {
80
- const authService = yield* MimicAuthServiceTag;
81
- const result1 = yield* authService.authenticate("token-1");
82
- const result2 = yield* authService.authenticate("token-2");
83
- const result3 = yield* authService.authenticate("token-3");
84
- return [result1, result2, result3];
85
- }).pipe(Effect.provide(NoAuth.layer))
86
- );
87
-
88
- expect(results).toHaveLength(3);
89
- for (const result of results) {
90
- expect(result.success).toBe(true);
91
- }
92
- });
93
- });
94
- });