@voidhash/mimic-effect 0.0.8 → 1.0.0-beta.1

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 (176) hide show
  1. package/.turbo/turbo-build.log +93 -89
  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 +193 -82
  11. package/dist/DocumentManager.d.cts +33 -19
  12. package/dist/DocumentManager.d.cts.map +1 -1
  13. package/dist/DocumentManager.d.mts +33 -19
  14. package/dist/DocumentManager.d.mts.map +1 -1
  15. package/dist/DocumentManager.mjs +189 -67
  16. package/dist/DocumentManager.mjs.map +1 -1
  17. package/dist/Errors.cjs +45 -0
  18. package/dist/Errors.d.cts +81 -0
  19. package/dist/Errors.d.cts.map +1 -0
  20. package/dist/Errors.d.mts +81 -0
  21. package/dist/Errors.d.mts.map +1 -0
  22. package/dist/Errors.mjs +40 -0
  23. package/dist/Errors.mjs.map +1 -0
  24. package/dist/HotStorage.cjs +77 -0
  25. package/dist/HotStorage.d.cts +54 -0
  26. package/dist/HotStorage.d.cts.map +1 -0
  27. package/dist/HotStorage.d.mts +54 -0
  28. package/dist/HotStorage.d.mts.map +1 -0
  29. package/dist/HotStorage.mjs +77 -0
  30. package/dist/HotStorage.mjs.map +1 -0
  31. package/dist/Metrics.cjs +121 -0
  32. package/dist/Metrics.d.cts +27 -0
  33. package/dist/Metrics.d.cts.map +1 -0
  34. package/dist/Metrics.d.mts +27 -0
  35. package/dist/Metrics.d.mts.map +1 -0
  36. package/dist/Metrics.mjs +106 -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 +443 -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 +445 -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 +75 -0
  61. package/dist/MimicServerEngine.d.cts.map +1 -0
  62. package/dist/MimicServerEngine.d.mts +75 -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/package.json +14 -6
  91. package/src/ColdStorage.ts +136 -0
  92. package/src/DocumentManager.ts +445 -193
  93. package/src/Errors.ts +100 -0
  94. package/src/HotStorage.ts +165 -0
  95. package/src/Metrics.ts +163 -0
  96. package/src/MimicAuthService.ts +126 -64
  97. package/src/MimicClusterServerEngine.ts +824 -0
  98. package/src/MimicServer.ts +448 -195
  99. package/src/MimicServerEngine.ts +272 -0
  100. package/src/PresenceManager.ts +169 -240
  101. package/src/Protocol.ts +350 -0
  102. package/src/Types.ts +231 -0
  103. package/src/index.ts +57 -23
  104. package/tests/ColdStorage.test.ts +136 -0
  105. package/tests/DocumentManager.test.ts +158 -287
  106. package/tests/HotStorage.test.ts +143 -0
  107. package/tests/MimicAuthService.test.ts +102 -134
  108. package/tests/MimicClusterServerEngine.test.ts +587 -0
  109. package/tests/MimicServer.test.ts +90 -226
  110. package/tests/MimicServerEngine.test.ts +521 -0
  111. package/tests/PresenceManager.test.ts +22 -63
  112. package/tests/Protocol.test.ts +190 -0
  113. package/tsconfig.json +1 -1
  114. package/dist/DocumentProtocol.cjs +0 -94
  115. package/dist/DocumentProtocol.d.cts +0 -113
  116. package/dist/DocumentProtocol.d.cts.map +0 -1
  117. package/dist/DocumentProtocol.d.mts +0 -113
  118. package/dist/DocumentProtocol.d.mts.map +0 -1
  119. package/dist/DocumentProtocol.mjs +0 -89
  120. package/dist/DocumentProtocol.mjs.map +0 -1
  121. package/dist/MimicConfig.cjs +0 -60
  122. package/dist/MimicConfig.d.cts +0 -141
  123. package/dist/MimicConfig.d.cts.map +0 -1
  124. package/dist/MimicConfig.d.mts +0 -141
  125. package/dist/MimicConfig.d.mts.map +0 -1
  126. package/dist/MimicConfig.mjs +0 -50
  127. package/dist/MimicConfig.mjs.map +0 -1
  128. package/dist/MimicDataStorage.cjs +0 -83
  129. package/dist/MimicDataStorage.d.cts +0 -113
  130. package/dist/MimicDataStorage.d.cts.map +0 -1
  131. package/dist/MimicDataStorage.d.mts +0 -113
  132. package/dist/MimicDataStorage.d.mts.map +0 -1
  133. package/dist/MimicDataStorage.mjs +0 -74
  134. package/dist/MimicDataStorage.mjs.map +0 -1
  135. package/dist/WebSocketHandler.cjs +0 -365
  136. package/dist/WebSocketHandler.d.cts +0 -34
  137. package/dist/WebSocketHandler.d.cts.map +0 -1
  138. package/dist/WebSocketHandler.d.mts +0 -34
  139. package/dist/WebSocketHandler.d.mts.map +0 -1
  140. package/dist/WebSocketHandler.mjs +0 -355
  141. package/dist/WebSocketHandler.mjs.map +0 -1
  142. package/dist/auth/NoAuth.cjs +0 -43
  143. package/dist/auth/NoAuth.d.cts +0 -22
  144. package/dist/auth/NoAuth.d.cts.map +0 -1
  145. package/dist/auth/NoAuth.d.mts +0 -22
  146. package/dist/auth/NoAuth.d.mts.map +0 -1
  147. package/dist/auth/NoAuth.mjs +0 -36
  148. package/dist/auth/NoAuth.mjs.map +0 -1
  149. package/dist/errors.cjs +0 -74
  150. package/dist/errors.d.cts +0 -89
  151. package/dist/errors.d.cts.map +0 -1
  152. package/dist/errors.d.mts +0 -89
  153. package/dist/errors.d.mts.map +0 -1
  154. package/dist/errors.mjs +0 -67
  155. package/dist/errors.mjs.map +0 -1
  156. package/dist/storage/InMemoryDataStorage.cjs +0 -57
  157. package/dist/storage/InMemoryDataStorage.d.cts +0 -19
  158. package/dist/storage/InMemoryDataStorage.d.cts.map +0 -1
  159. package/dist/storage/InMemoryDataStorage.d.mts +0 -19
  160. package/dist/storage/InMemoryDataStorage.d.mts.map +0 -1
  161. package/dist/storage/InMemoryDataStorage.mjs +0 -48
  162. package/dist/storage/InMemoryDataStorage.mjs.map +0 -1
  163. package/src/DocumentProtocol.ts +0 -112
  164. package/src/MimicConfig.ts +0 -211
  165. package/src/MimicDataStorage.ts +0 -157
  166. package/src/WebSocketHandler.ts +0 -735
  167. package/src/auth/NoAuth.ts +0 -46
  168. package/src/errors.ts +0 -113
  169. package/src/storage/InMemoryDataStorage.ts +0 -66
  170. package/tests/DocumentProtocol.test.ts +0 -113
  171. package/tests/InMemoryDataStorage.test.ts +0 -190
  172. package/tests/MimicConfig.test.ts +0 -290
  173. package/tests/MimicDataStorage.test.ts +0 -190
  174. package/tests/NoAuth.test.ts +0 -94
  175. package/tests/WebSocketHandler.test.ts +0 -321
  176. package/tests/errors.test.ts +0 -77
@@ -0,0 +1,272 @@
1
+ /**
2
+ * @voidhash/mimic-effect - MimicServerEngine
3
+ *
4
+ * Core document management service for Mimic real-time collaboration.
5
+ * Handles document lifecycle, storage, presence, and transaction processing.
6
+ *
7
+ * This is the engine layer - for WebSocket routes, use MimicServer.layerHttpLayerRouter().
8
+ */
9
+ import {
10
+ Context,
11
+ Duration,
12
+ Effect,
13
+ Layer,
14
+ Scope,
15
+ Stream,
16
+ } from "effect";
17
+ import type { Presence, Primitive, Transaction } from "@voidhash/mimic";
18
+ import type {
19
+ MimicServerEngineConfig,
20
+ PresenceEntry,
21
+ PresenceEvent,
22
+ PresenceSnapshot,
23
+ ResolvedConfig,
24
+ } from "./Types";
25
+ import type * as Protocol from "./Protocol";
26
+ import { ColdStorageTag } from "./ColdStorage";
27
+ import { HotStorageTag } from "./HotStorage";
28
+ import { MimicAuthServiceTag } from "./MimicAuthService";
29
+ import {
30
+ DocumentManagerTag,
31
+ DocumentManagerConfigTag,
32
+ layer as documentManagerLayer,
33
+ type SubmitResult,
34
+ } from "./DocumentManager";
35
+ import {
36
+ PresenceManagerTag,
37
+ layer as presenceManagerLayer,
38
+ } from "./PresenceManager";
39
+
40
+ // =============================================================================
41
+ // MimicServerEngine Interface
42
+ // =============================================================================
43
+
44
+ /**
45
+ * MimicServerEngine service interface.
46
+ *
47
+ * Provides document management operations for Mimic collaboration.
48
+ * Use MimicServer.layerHttpLayerRouter() to create WebSocket routes.
49
+ */
50
+ export interface MimicServerEngine {
51
+ /**
52
+ * Submit a transaction to a document.
53
+ * Authorization is checked against the auth service.
54
+ */
55
+ readonly submit: (
56
+ documentId: string,
57
+ transaction: Transaction.Transaction
58
+ ) => Effect.Effect<SubmitResult, never>;
59
+
60
+ /**
61
+ * Get document snapshot (current state and version).
62
+ */
63
+ readonly getSnapshot: (
64
+ documentId: string
65
+ ) => Effect.Effect<{ state: unknown; version: number }, never>;
66
+
67
+ /**
68
+ * Subscribe to document broadcasts (transactions).
69
+ * Returns a stream of server messages.
70
+ * Requires a Scope for cleanup when the subscription ends.
71
+ */
72
+ readonly subscribe: (
73
+ documentId: string
74
+ ) => Effect.Effect<Stream.Stream<Protocol.ServerMessage, never, never>, never, Scope.Scope>;
75
+
76
+ /**
77
+ * Touch document to prevent idle garbage collection.
78
+ */
79
+ readonly touch: (documentId: string) => Effect.Effect<void, never>;
80
+
81
+ /**
82
+ * Get presence snapshot for a document.
83
+ */
84
+ readonly getPresenceSnapshot: (
85
+ documentId: string
86
+ ) => Effect.Effect<PresenceSnapshot, never>;
87
+
88
+ /**
89
+ * Set presence for a connection.
90
+ */
91
+ readonly setPresence: (
92
+ documentId: string,
93
+ connectionId: string,
94
+ entry: PresenceEntry
95
+ ) => Effect.Effect<void, never>;
96
+
97
+ /**
98
+ * Remove presence for a connection.
99
+ */
100
+ readonly removePresence: (
101
+ documentId: string,
102
+ connectionId: string
103
+ ) => Effect.Effect<void, never>;
104
+
105
+ /**
106
+ * Subscribe to presence events for a document.
107
+ * Requires a Scope for cleanup when the subscription ends.
108
+ */
109
+ readonly subscribePresence: (
110
+ documentId: string
111
+ ) => Effect.Effect<Stream.Stream<PresenceEvent, never, never>, never, Scope.Scope>;
112
+
113
+ /**
114
+ * Resolved engine configuration.
115
+ * Used by route layer to access schema, presence config, etc.
116
+ */
117
+ readonly config: ResolvedConfig<Primitive.AnyPrimitive>;
118
+ }
119
+
120
+ // =============================================================================
121
+ // Context Tag
122
+ // =============================================================================
123
+
124
+ /**
125
+ * Context tag for MimicServerEngine
126
+ */
127
+ export class MimicServerEngineTag extends Context.Tag(
128
+ "@voidhash/mimic-effect/MimicServerEngine"
129
+ )<MimicServerEngineTag, MimicServerEngine>() {}
130
+
131
+ // =============================================================================
132
+ // Default Configuration
133
+ // =============================================================================
134
+
135
+ const DEFAULT_MAX_IDLE_TIME = Duration.minutes(5);
136
+ const DEFAULT_MAX_TRANSACTION_HISTORY = 1000;
137
+ const DEFAULT_SNAPSHOT_INTERVAL = Duration.minutes(5);
138
+ const DEFAULT_SNAPSHOT_THRESHOLD = 100;
139
+
140
+ /**
141
+ * Resolve configuration with defaults
142
+ */
143
+ const resolveConfig = <TSchema extends Primitive.AnyPrimitive>(
144
+ config: MimicServerEngineConfig<TSchema>
145
+ ): ResolvedConfig<TSchema> => ({
146
+ schema: config.schema,
147
+ initial: config.initial,
148
+ presence: config.presence,
149
+ maxIdleTime: config.maxIdleTime
150
+ ? Duration.decode(config.maxIdleTime)
151
+ : DEFAULT_MAX_IDLE_TIME,
152
+ maxTransactionHistory:
153
+ config.maxTransactionHistory ?? DEFAULT_MAX_TRANSACTION_HISTORY,
154
+ snapshot: {
155
+ interval: config.snapshot?.interval
156
+ ? Duration.decode(config.snapshot.interval)
157
+ : DEFAULT_SNAPSHOT_INTERVAL,
158
+ transactionThreshold:
159
+ config.snapshot?.transactionThreshold ?? DEFAULT_SNAPSHOT_THRESHOLD,
160
+ },
161
+ });
162
+
163
+ // =============================================================================
164
+ // Factory
165
+ // =============================================================================
166
+
167
+ /**
168
+ * Create a MimicServerEngine layer.
169
+ *
170
+ * This creates the core document management service. To expose it via WebSocket,
171
+ * use MimicServer.layerHttpLayerRouter().
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * // 1. Create the engine
176
+ * const Engine = MimicServerEngine.make({
177
+ * schema: DocSchema,
178
+ * initial: { title: "Untitled" },
179
+ * presence: CursorPresence,
180
+ * maxIdleTime: "5 minutes",
181
+ * snapshot: { interval: "5 minutes", transactionThreshold: 100 },
182
+ * })
183
+ *
184
+ * // 2. Create the WebSocket route
185
+ * const MimicRoute = MimicServer.layerHttpLayerRouter({
186
+ * path: "/mimic",
187
+ * })
188
+ *
189
+ * // 3. Wire together
190
+ * const MimicLive = MimicRoute.pipe(
191
+ * Layer.provide(Engine),
192
+ * Layer.provide(ColdStorage.InMemory.make()),
193
+ * Layer.provide(HotStorage.InMemory.make()),
194
+ * Layer.provide(MimicAuthService.NoAuth.make()),
195
+ * )
196
+ * ```
197
+ */
198
+ export const make = <TSchema extends Primitive.AnyPrimitive>(
199
+ config: MimicServerEngineConfig<TSchema>
200
+ ): Layer.Layer<
201
+ MimicServerEngineTag,
202
+ never,
203
+ ColdStorageTag | HotStorageTag | MimicAuthServiceTag
204
+ > => {
205
+ const resolvedConfig = resolveConfig(config);
206
+
207
+ // Create config layer for DocumentManager
208
+ const configLayer = Layer.succeed(
209
+ DocumentManagerConfigTag,
210
+ resolvedConfig as ResolvedConfig<Primitive.AnyPrimitive>
211
+ );
212
+
213
+ // Create internal layers
214
+ const internalLayers = Layer.mergeAll(
215
+ documentManagerLayer.pipe(Layer.provide(configLayer)),
216
+ presenceManagerLayer
217
+ );
218
+
219
+ return Layer.scoped(
220
+ MimicServerEngineTag,
221
+ Effect.gen(function* () {
222
+ const documentManager = yield* DocumentManagerTag;
223
+ const presenceManager = yield* PresenceManagerTag;
224
+
225
+ const engine: MimicServerEngine = {
226
+ submit: (documentId, transaction) =>
227
+ documentManager.submit(documentId, transaction),
228
+
229
+ getSnapshot: (documentId) => documentManager.getSnapshot(documentId),
230
+
231
+ subscribe: (documentId) =>
232
+ documentManager.subscribe(documentId) as Effect.Effect<
233
+ Stream.Stream<Protocol.ServerMessage, never, never>,
234
+ never
235
+ >,
236
+
237
+ touch: (documentId) => documentManager.touch(documentId),
238
+
239
+ getPresenceSnapshot: (documentId) =>
240
+ presenceManager.getSnapshot(documentId),
241
+
242
+ setPresence: (documentId, connectionId, entry) =>
243
+ presenceManager.set(documentId, connectionId, entry),
244
+
245
+ removePresence: (documentId, connectionId) =>
246
+ presenceManager.remove(documentId, connectionId),
247
+
248
+ subscribePresence: (documentId) =>
249
+ presenceManager.subscribe(documentId),
250
+
251
+ config: resolvedConfig as ResolvedConfig<Primitive.AnyPrimitive>,
252
+ };
253
+
254
+ return engine;
255
+ })
256
+ ).pipe(Layer.provide(internalLayers));
257
+ };
258
+
259
+ // =============================================================================
260
+ // Re-export namespace
261
+ // =============================================================================
262
+
263
+ export const MimicServerEngine = {
264
+ Tag: MimicServerEngineTag,
265
+ make,
266
+ };
267
+
268
+ // =============================================================================
269
+ // Re-export SubmitResult type
270
+ // =============================================================================
271
+
272
+ export type { SubmitResult };