@voidhash/mimic-effect 0.0.2 → 0.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 (99) hide show
  1. package/.turbo/turbo-build.log +99 -14
  2. package/dist/DocumentManager.cjs +118 -0
  3. package/dist/DocumentManager.d.cts +45 -0
  4. package/dist/DocumentManager.d.cts.map +1 -0
  5. package/dist/DocumentManager.d.mts +45 -0
  6. package/dist/DocumentManager.d.mts.map +1 -0
  7. package/dist/DocumentManager.mjs +105 -0
  8. package/dist/DocumentManager.mjs.map +1 -0
  9. package/dist/DocumentProtocol.cjs +94 -0
  10. package/dist/DocumentProtocol.d.cts +113 -0
  11. package/dist/DocumentProtocol.d.cts.map +1 -0
  12. package/dist/DocumentProtocol.d.mts +113 -0
  13. package/dist/DocumentProtocol.d.mts.map +1 -0
  14. package/dist/DocumentProtocol.mjs +89 -0
  15. package/dist/DocumentProtocol.mjs.map +1 -0
  16. package/dist/MimicAuthService.cjs +55 -0
  17. package/dist/MimicAuthService.d.cts +65 -0
  18. package/dist/MimicAuthService.d.cts.map +1 -0
  19. package/dist/MimicAuthService.d.mts +65 -0
  20. package/dist/MimicAuthService.d.mts.map +1 -0
  21. package/dist/MimicAuthService.mjs +47 -0
  22. package/dist/MimicAuthService.mjs.map +1 -0
  23. package/dist/MimicConfig.cjs +50 -0
  24. package/dist/MimicConfig.d.cts +99 -0
  25. package/dist/MimicConfig.d.cts.map +1 -0
  26. package/dist/MimicConfig.d.mts +99 -0
  27. package/dist/MimicConfig.d.mts.map +1 -0
  28. package/dist/MimicConfig.mjs +41 -0
  29. package/dist/MimicConfig.mjs.map +1 -0
  30. package/dist/MimicDataStorage.cjs +83 -0
  31. package/dist/MimicDataStorage.d.cts +113 -0
  32. package/dist/MimicDataStorage.d.cts.map +1 -0
  33. package/dist/MimicDataStorage.d.mts +113 -0
  34. package/dist/MimicDataStorage.d.mts.map +1 -0
  35. package/dist/MimicDataStorage.mjs +74 -0
  36. package/dist/MimicDataStorage.mjs.map +1 -0
  37. package/dist/MimicServer.cjs +230 -0
  38. package/dist/MimicServer.d.cts +192 -0
  39. package/dist/MimicServer.d.cts.map +1 -0
  40. package/dist/MimicServer.d.mts +192 -0
  41. package/dist/MimicServer.d.mts.map +1 -0
  42. package/dist/MimicServer.mjs +223 -0
  43. package/dist/MimicServer.mjs.map +1 -0
  44. package/dist/PresenceManager.cjs +108 -0
  45. package/dist/PresenceManager.d.cts +91 -0
  46. package/dist/PresenceManager.d.cts.map +1 -0
  47. package/dist/PresenceManager.d.mts +91 -0
  48. package/dist/PresenceManager.d.mts.map +1 -0
  49. package/dist/PresenceManager.mjs +95 -0
  50. package/dist/PresenceManager.mjs.map +1 -0
  51. package/dist/WebSocketHandler.cjs +366 -0
  52. package/dist/WebSocketHandler.d.cts +34 -0
  53. package/dist/WebSocketHandler.d.cts.map +1 -0
  54. package/dist/WebSocketHandler.d.mts +34 -0
  55. package/dist/WebSocketHandler.d.mts.map +1 -0
  56. package/dist/WebSocketHandler.mjs +355 -0
  57. package/dist/WebSocketHandler.mjs.map +1 -0
  58. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/defineProperty.cjs +14 -0
  59. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/defineProperty.mjs +14 -0
  60. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.cjs +27 -0
  61. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.mjs +27 -0
  62. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPrimitive.cjs +16 -0
  63. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPrimitive.mjs +16 -0
  64. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPropertyKey.cjs +11 -0
  65. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/toPropertyKey.mjs +11 -0
  66. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/typeof.cjs +18 -0
  67. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/typeof.mjs +12 -0
  68. package/dist/_virtual/rolldown_runtime.cjs +43 -0
  69. package/dist/{chunk-C6wwvPpM.mjs → _virtual/rolldown_runtime.mjs} +1 -1
  70. package/dist/auth/NoAuth.cjs +43 -0
  71. package/dist/auth/NoAuth.d.cts +22 -0
  72. package/dist/auth/NoAuth.d.cts.map +1 -0
  73. package/dist/auth/NoAuth.d.mts +22 -0
  74. package/dist/auth/NoAuth.d.mts.map +1 -0
  75. package/dist/auth/NoAuth.mjs +36 -0
  76. package/dist/auth/NoAuth.mjs.map +1 -0
  77. package/dist/errors.cjs +74 -0
  78. package/dist/errors.d.cts +89 -0
  79. package/dist/errors.d.cts.map +1 -0
  80. package/dist/errors.d.mts +89 -0
  81. package/dist/errors.d.mts.map +1 -0
  82. package/dist/errors.mjs +67 -0
  83. package/dist/errors.mjs.map +1 -0
  84. package/dist/index.cjs +29 -1227
  85. package/dist/index.d.cts +12 -795
  86. package/dist/index.d.mts +12 -795
  87. package/dist/index.mjs +13 -1162
  88. package/dist/storage/InMemoryDataStorage.cjs +57 -0
  89. package/dist/storage/InMemoryDataStorage.d.cts +19 -0
  90. package/dist/storage/InMemoryDataStorage.d.cts.map +1 -0
  91. package/dist/storage/InMemoryDataStorage.d.mts +19 -0
  92. package/dist/storage/InMemoryDataStorage.d.mts.map +1 -0
  93. package/dist/storage/InMemoryDataStorage.mjs +48 -0
  94. package/dist/storage/InMemoryDataStorage.mjs.map +1 -0
  95. package/package.json +3 -3
  96. package/tsdown.config.ts +1 -1
  97. package/dist/index.d.cts.map +0 -1
  98. package/dist/index.d.mts.map +0 -1
  99. package/dist/index.mjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,1277 +1,79 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (all, symbols) => {
9
- let target = {};
10
- for (var name in all) {
11
- __defProp(target, name, {
12
- get: all[name],
13
- enumerable: true
14
- });
15
- }
16
- if (symbols) {
17
- __defProp(target, Symbol.toStringTag, { value: "Module" });
18
- }
19
- return target;
20
- };
21
- var __copyProps = (to, from, except, desc) => {
22
- if (from && typeof from === "object" || typeof from === "function") {
23
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
24
- key = keys[i];
25
- if (!__hasOwnProp.call(to, key) && key !== except) {
26
- __defProp(to, key, {
27
- get: ((k) => from[k]).bind(null, key),
28
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
29
- });
30
- }
31
- }
32
- }
33
- return to;
34
- };
35
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
36
- value: mod,
37
- enumerable: true
38
- }) : target, mod));
39
-
40
- //#endregion
41
- let effect_Effect = require("effect/Effect");
42
- effect_Effect = __toESM(effect_Effect);
43
- let effect_Layer = require("effect/Layer");
44
- effect_Layer = __toESM(effect_Layer);
45
- let effect_Context = require("effect/Context");
46
- effect_Context = __toESM(effect_Context);
47
- let _effect_platform_SocketServer = require("@effect/platform/SocketServer");
48
- let effect_PubSub = require("effect/PubSub");
49
- effect_PubSub = __toESM(effect_PubSub);
50
- let effect_Ref = require("effect/Ref");
51
- effect_Ref = __toESM(effect_Ref);
52
- let effect_HashMap = require("effect/HashMap");
53
- effect_HashMap = __toESM(effect_HashMap);
54
- let effect_Stream = require("effect/Stream");
55
- effect_Stream = __toESM(effect_Stream);
56
- let _voidhash_mimic_server = require("@voidhash/mimic/server");
57
- let effect_Duration = require("effect/Duration");
58
- effect_Duration = __toESM(effect_Duration);
59
- let effect_Data = require("effect/Data");
60
- effect_Data = __toESM(effect_Data);
61
- let effect_Fiber = require("effect/Fiber");
62
- effect_Fiber = __toESM(effect_Fiber);
63
- let _voidhash_mimic = require("@voidhash/mimic");
64
- let _effect_platform = require("@effect/platform");
65
- let effect_Schema = require("effect/Schema");
66
- effect_Schema = __toESM(effect_Schema);
67
-
68
- //#region src/MimicConfig.ts
69
- /**
70
- * @since 0.0.1
71
- * Configuration types for the Mimic server.
72
- */
73
- var MimicConfig_exports = /* @__PURE__ */ __export({
74
- MimicServerConfigTag: () => MimicServerConfigTag,
75
- layer: () => layer$7,
76
- make: () => make$2
77
- });
78
- /**
79
- * Create a MimicServerConfig from options.
80
- */
81
- const make$2 = (options) => {
82
- var _options$maxIdleTime, _options$maxTransacti, _options$heartbeatInt, _options$heartbeatTim;
83
- return {
84
- schema: options.schema,
85
- maxIdleTime: effect_Duration.decode((_options$maxIdleTime = options.maxIdleTime) !== null && _options$maxIdleTime !== void 0 ? _options$maxIdleTime : "5 minutes"),
86
- maxTransactionHistory: (_options$maxTransacti = options.maxTransactionHistory) !== null && _options$maxTransacti !== void 0 ? _options$maxTransacti : 1e3,
87
- heartbeatInterval: effect_Duration.decode((_options$heartbeatInt = options.heartbeatInterval) !== null && _options$heartbeatInt !== void 0 ? _options$heartbeatInt : "30 seconds"),
88
- heartbeatTimeout: effect_Duration.decode((_options$heartbeatTim = options.heartbeatTimeout) !== null && _options$heartbeatTim !== void 0 ? _options$heartbeatTim : "10 seconds"),
89
- presence: options.presence
90
- };
91
- };
92
- /**
93
- * Context tag for MimicServerConfig.
94
- */
95
- var MimicServerConfigTag = class extends effect_Context.Tag("@voidhash/mimic-server-effect/MimicServerConfig")() {};
96
- /**
97
- * Create a Layer that provides MimicServerConfig.
98
- */
99
- const layer$7 = (options) => effect_Layer.succeed(MimicServerConfigTag, make$2(options));
100
-
101
- //#endregion
102
- //#region src/MimicDataStorage.ts
103
- /**
104
- * @since 0.0.1
105
- * Data storage service interface for Mimic documents.
106
- * Provides pluggable storage adapters with load/save hooks for data transformation.
107
- */
108
- var MimicDataStorage_exports = /* @__PURE__ */ __export({
109
- MimicDataStorageTag: () => MimicDataStorageTag,
110
- StorageDeleteError: () => StorageDeleteError,
111
- StorageLoadError: () => StorageLoadError,
112
- StorageSaveError: () => StorageSaveError,
113
- layer: () => layer$6,
114
- layerEffect: () => layerEffect$1,
115
- make: () => make$1
116
- });
117
- /**
118
- * Error when loading a document from storage fails.
119
- */
120
- var StorageLoadError = class extends effect_Data.TaggedError("StorageLoadError") {
121
- get message() {
122
- return `Failed to load document ${this.documentId}: ${String(this.cause)}`;
123
- }
124
- };
125
- /**
126
- * Error when saving a document to storage fails.
127
- */
128
- var StorageSaveError = class extends effect_Data.TaggedError("StorageSaveError") {
129
- get message() {
130
- return `Failed to save document ${this.documentId}: ${String(this.cause)}`;
131
- }
132
- };
133
- /**
134
- * Error when deleting a document from storage fails.
135
- */
136
- var StorageDeleteError = class extends effect_Data.TaggedError("StorageDeleteError") {
137
- get message() {
138
- return `Failed to delete document ${this.documentId}: ${String(this.cause)}`;
139
- }
140
- };
141
- /**
142
- * Context tag for MimicDataStorage service.
143
- */
144
- var MimicDataStorageTag = class extends effect_Context.Tag("@voidhash/mimic-server-effect/MimicDataStorage")() {};
145
- /**
146
- * Create a MimicDataStorage layer from a storage implementation.
147
- */
148
- const layer$6 = (storage) => effect_Layer.succeed(MimicDataStorageTag, storage);
149
- /**
150
- * Create a MimicDataStorage layer from an Effect that produces a storage implementation.
151
- */
152
- const layerEffect$1 = (effect) => effect_Layer.effect(MimicDataStorageTag, effect);
153
- /**
154
- * Create a simple storage implementation with minimal configuration.
155
- */
156
- const make$1 = (options) => {
157
- var _options$delete, _options$onLoad, _options$onSave;
158
- return {
159
- load: options.load,
160
- save: options.save,
161
- delete: (_options$delete = options.delete) !== null && _options$delete !== void 0 ? _options$delete : (() => effect_Effect.void),
162
- onLoad: (_options$onLoad = options.onLoad) !== null && _options$onLoad !== void 0 ? _options$onLoad : ((state) => effect_Effect.succeed(state)),
163
- onSave: (_options$onSave = options.onSave) !== null && _options$onSave !== void 0 ? _options$onSave : ((state) => effect_Effect.succeed(state))
164
- };
165
- };
166
-
167
- //#endregion
168
- //#region src/DocumentManager.ts
169
- /**
170
- * @since 0.0.1
171
- * Document manager that handles multiple document instances.
172
- */
173
- var DocumentManager_exports = /* @__PURE__ */ __export({
174
- DocumentManagerTag: () => DocumentManagerTag,
175
- layer: () => layer$5
176
- });
177
- /**
178
- * Context tag for DocumentManager.
179
- */
180
- var DocumentManagerTag = class extends effect_Context.Tag("@voidhash/mimic-server-effect/DocumentManager")() {};
181
- /**
182
- * Create the DocumentManager service.
183
- */
184
- const makeDocumentManager = effect_Effect.gen(function* () {
185
- const config = yield* MimicServerConfigTag;
186
- const storage = yield* MimicDataStorageTag;
187
- const documents = yield* effect_Ref.make(effect_HashMap.empty());
188
- const getOrCreateDocument = (documentId) => effect_Effect.gen(function* () {
189
- const current = yield* effect_Ref.get(documents);
190
- const existing = effect_HashMap.get(current, documentId);
191
- if (existing._tag === "Some") {
192
- yield* effect_Ref.update(existing.value.refCount, (n) => n + 1);
193
- return existing.value;
194
- }
195
- const rawState = yield* effect_Effect.catchAll(storage.load(documentId), () => effect_Effect.succeed(void 0));
196
- const initialState = rawState !== void 0 ? yield* storage.onLoad(rawState) : void 0;
197
- const pubsub = yield* effect_PubSub.unbounded();
198
- const serverDocument = _voidhash_mimic_server.ServerDocument.make({
199
- schema: config.schema,
200
- initialState,
201
- maxTransactionHistory: config.maxTransactionHistory,
202
- onBroadcast: (transactionMessage) => {
203
- const currentState = serverDocument.get();
204
- effect_Effect.runFork(effect_Effect.gen(function* () {
205
- if (currentState !== void 0) {
206
- const transformedState = yield* storage.onSave(currentState);
207
- yield* effect_Effect.catchAll(storage.save(documentId, transformedState), (error) => effect_Effect.logError("Failed to save document", error));
208
- }
209
- }));
210
- effect_Effect.runSync(effect_PubSub.publish(pubsub, {
211
- type: "transaction",
212
- transaction: transactionMessage.transaction,
213
- version: transactionMessage.version
214
- }));
215
- },
216
- onRejection: (transactionId, reason) => {
217
- effect_Effect.runSync(effect_PubSub.publish(pubsub, {
218
- type: "error",
219
- transactionId,
220
- reason
221
- }));
222
- }
223
- });
224
- const instance = {
225
- document: serverDocument,
226
- pubsub,
227
- refCount: yield* effect_Ref.make(1)
228
- };
229
- yield* effect_Ref.update(documents, (map) => effect_HashMap.set(map, documentId, instance));
230
- return instance;
231
- });
232
- const submit = (documentId, transaction) => effect_Effect.gen(function* () {
233
- return (yield* getOrCreateDocument(documentId)).document.submit(transaction);
234
- });
235
- const getSnapshot = (documentId) => effect_Effect.gen(function* () {
236
- return (yield* getOrCreateDocument(documentId)).document.getSnapshot();
237
- });
238
- const subscribe = (documentId) => effect_Effect.gen(function* () {
239
- const instance = yield* getOrCreateDocument(documentId);
240
- const queue = yield* effect_PubSub.subscribe(instance.pubsub);
241
- yield* effect_Effect.addFinalizer(() => effect_Effect.gen(function* () {
242
- yield* effect_Ref.updateAndGet(instance.refCount, (n) => n - 1);
243
- }));
244
- return effect_Stream.fromQueue(queue);
245
- });
246
- return {
247
- submit,
248
- getSnapshot,
249
- subscribe
250
- };
251
- });
252
- /**
253
- * Layer that provides DocumentManager.
254
- * Requires MimicServerConfigTag and MimicDataStorageTag.
255
- */
256
- const layer$5 = effect_Layer.effect(DocumentManagerTag, makeDocumentManager);
257
-
258
- //#endregion
259
- //#region src/MimicAuthService.ts
260
- /**
261
- * @since 0.0.1
262
- * Authentication service interface for Mimic connections.
263
- * Provides pluggable authentication adapters.
264
- */
265
- var MimicAuthService_exports = /* @__PURE__ */ __export({
266
- MimicAuthServiceTag: () => MimicAuthServiceTag,
267
- layer: () => layer$4,
268
- layerEffect: () => layerEffect,
269
- layerService: () => layerService,
270
- make: () => make,
271
- makeEffect: () => makeEffect
272
- });
273
- /**
274
- * Context tag for MimicAuthService service.
275
- */
276
- var MimicAuthServiceTag = class extends effect_Context.Tag("@voidhash/mimic-server-effect/MimicAuthService")() {};
277
- /**
278
- * Create a MimicAuthService layer from an auth handler function.
279
- */
280
- const layer$4 = (options) => effect_Layer.succeed(MimicAuthServiceTag, { authenticate: (token) => effect_Effect.promise(() => Promise.resolve(options.authHandler(token))) });
281
- /**
282
- * Create a MimicAuthService layer from an auth service implementation.
283
- */
284
- const layerService = (service) => effect_Layer.succeed(MimicAuthServiceTag, service);
285
- /**
286
- * Create a MimicAuthService layer from an Effect that produces an auth service.
287
- */
288
- const layerEffect = (effect) => effect_Layer.effect(MimicAuthServiceTag, effect);
289
- /**
290
- * Create an auth service from an auth handler function.
291
- */
292
- const make = (authHandler) => ({ authenticate: (token) => effect_Effect.promise(() => Promise.resolve(authHandler(token))) });
293
- /**
294
- * Create an auth service from an Effect-based authenticate function.
295
- */
296
- const makeEffect = (authenticate) => ({ authenticate });
297
-
298
- //#endregion
299
- //#region src/PresenceManager.ts
300
- /**
301
- * @since 0.0.1
302
- * Presence manager for ephemeral per-connection state.
303
- * Handles in-memory storage and broadcasting of presence updates.
304
- */
305
- var PresenceManager_exports = /* @__PURE__ */ __export({
306
- PresenceManagerTag: () => PresenceManagerTag,
307
- layer: () => layer$3,
308
- layerDefault: () => layerDefault$2
309
- });
310
- /**
311
- * Context tag for PresenceManager.
312
- */
313
- var PresenceManagerTag = class extends effect_Context.Tag("@voidhash/mimic-server-effect/PresenceManager")() {};
314
- /**
315
- * Create the PresenceManager service.
316
- */
317
- const makePresenceManager = effect_Effect.gen(function* () {
318
- const documents = yield* effect_Ref.make(effect_HashMap.empty());
319
- const getOrCreateDocument = (documentId) => effect_Effect.gen(function* () {
320
- const current = yield* effect_Ref.get(documents);
321
- const existing = effect_HashMap.get(current, documentId);
322
- if (existing._tag === "Some") return existing.value;
323
- const docPresence = {
324
- entries: yield* effect_Ref.make(effect_HashMap.empty()),
325
- pubsub: yield* effect_PubSub.unbounded()
326
- };
327
- yield* effect_Ref.update(documents, (map) => effect_HashMap.set(map, documentId, docPresence));
328
- return docPresence;
329
- });
330
- const getSnapshot = (documentId) => effect_Effect.gen(function* () {
331
- const docPresence = yield* getOrCreateDocument(documentId);
332
- const entriesMap = yield* effect_Ref.get(docPresence.entries);
333
- const presences = {};
334
- for (const [id, entry] of entriesMap) presences[id] = entry;
335
- return { presences };
336
- });
337
- const set = (documentId, connectionId, entry) => effect_Effect.gen(function* () {
338
- const docPresence = yield* getOrCreateDocument(documentId);
339
- yield* effect_Ref.update(docPresence.entries, (map) => effect_HashMap.set(map, connectionId, entry));
340
- yield* effect_PubSub.publish(docPresence.pubsub, {
341
- type: "presence_update",
342
- id: connectionId,
343
- data: entry.data,
344
- userId: entry.userId
345
- });
346
- });
347
- const remove = (documentId, connectionId) => effect_Effect.gen(function* () {
348
- const current = yield* effect_Ref.get(documents);
349
- const existing = effect_HashMap.get(current, documentId);
350
- if (existing._tag === "None") return;
351
- const docPresence = existing.value;
352
- const entries = yield* effect_Ref.get(docPresence.entries);
353
- if (!effect_HashMap.has(entries, connectionId)) return;
354
- yield* effect_Ref.update(docPresence.entries, (map) => effect_HashMap.remove(map, connectionId));
355
- yield* effect_PubSub.publish(docPresence.pubsub, {
356
- type: "presence_remove",
357
- id: connectionId
358
- });
359
- });
360
- const subscribe = (documentId) => effect_Effect.gen(function* () {
361
- const docPresence = yield* getOrCreateDocument(documentId);
362
- const queue = yield* effect_PubSub.subscribe(docPresence.pubsub);
363
- return effect_Stream.fromQueue(queue);
364
- });
365
- return {
366
- getSnapshot,
367
- set,
368
- remove,
369
- subscribe
370
- };
371
- });
372
- /**
373
- * Layer that provides PresenceManager.
374
- */
375
- const layer$3 = effect_Layer.effect(PresenceManagerTag, makePresenceManager);
376
- /**
377
- * Default layer that provides PresenceManager.
378
- * Uses the default priority for layer composition.
379
- */
380
- const layerDefault$2 = effect_Layer.effectDiscard(effect_Effect.succeed(void 0)).pipe(effect_Layer.provideMerge(layer$3));
381
-
382
- //#endregion
383
- //#region src/errors.ts
384
- /**
385
- * @since 0.0.1
386
- * Error types for the Mimic server.
387
- */
388
- /**
389
- * Error when a document type is not found in the schema registry.
390
- */
391
- var DocumentTypeNotFoundError = class extends effect_Data.TaggedError("DocumentTypeNotFoundError") {
392
- get message() {
393
- return `Document type not found: ${this.documentType}`;
394
- }
395
- };
396
- /**
397
- * Error when a document is not found.
398
- */
399
- var DocumentNotFoundError = class extends effect_Data.TaggedError("DocumentNotFoundError") {
400
- get message() {
401
- return `Document not found: ${this.documentId}`;
402
- }
403
- };
404
- /**
405
- * Error when authentication fails.
406
- */
407
- var AuthenticationError = class extends effect_Data.TaggedError("AuthenticationError") {
408
- get message() {
409
- return `Authentication failed: ${this.reason}`;
410
- }
411
- };
412
- /**
413
- * Error when a transaction is rejected.
414
- */
415
- var TransactionRejectedError = class extends effect_Data.TaggedError("TransactionRejectedError") {
416
- get message() {
417
- return `Transaction ${this.transactionId} rejected: ${this.reason}`;
418
- }
419
- };
420
- /**
421
- * Error when parsing a client message fails.
422
- */
423
- var MessageParseError = class extends effect_Data.TaggedError("MessageParseError") {
424
- get message() {
425
- return `Failed to parse message: ${String(this.cause)}`;
426
- }
427
- };
428
- /**
429
- * Error when the WebSocket connection is invalid.
430
- */
431
- var InvalidConnectionError = class extends effect_Data.TaggedError("InvalidConnectionError") {
432
- get message() {
433
- return `Invalid connection: ${this.reason}`;
434
- }
435
- };
436
- /**
437
- * Error when the document ID is missing from the URL path.
438
- */
439
- var MissingDocumentIdError = class extends effect_Data.TaggedError("MissingDocumentIdError") {
440
- get message() {
441
- return this.path ? `Document ID is required in the URL path: ${this.path}` : "Document ID is required in the URL path";
442
- }
443
- };
444
-
445
- //#endregion
446
- //#region \0@oxc-project+runtime@0.103.0/helpers/typeof.js
447
- function _typeof(o) {
448
- "@babel/helpers - typeof";
449
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
450
- return typeof o$1;
451
- } : function(o$1) {
452
- return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
453
- }, _typeof(o);
454
- }
455
-
456
- //#endregion
457
- //#region \0@oxc-project+runtime@0.103.0/helpers/toPrimitive.js
458
- function toPrimitive(t, r) {
459
- if ("object" != _typeof(t) || !t) return t;
460
- var e = t[Symbol.toPrimitive];
461
- if (void 0 !== e) {
462
- var i = e.call(t, r || "default");
463
- if ("object" != _typeof(i)) return i;
464
- throw new TypeError("@@toPrimitive must return a primitive value.");
465
- }
466
- return ("string" === r ? String : Number)(t);
467
- }
468
-
469
- //#endregion
470
- //#region \0@oxc-project+runtime@0.103.0/helpers/toPropertyKey.js
471
- function toPropertyKey(t) {
472
- var i = toPrimitive(t, "string");
473
- return "symbol" == _typeof(i) ? i : i + "";
474
- }
475
-
476
- //#endregion
477
- //#region \0@oxc-project+runtime@0.103.0/helpers/defineProperty.js
478
- function _defineProperty(e, r, t) {
479
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
480
- value: t,
481
- enumerable: !0,
482
- configurable: !0,
483
- writable: !0
484
- }) : e[r] = t, e;
485
- }
486
-
487
- //#endregion
488
- //#region \0@oxc-project+runtime@0.103.0/helpers/objectSpread2.js
489
- function ownKeys(e, r) {
490
- var t = Object.keys(e);
491
- if (Object.getOwnPropertySymbols) {
492
- var o = Object.getOwnPropertySymbols(e);
493
- r && (o = o.filter(function(r$1) {
494
- return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
495
- })), t.push.apply(t, o);
496
- }
497
- return t;
498
- }
499
- function _objectSpread2(e) {
500
- for (var r = 1; r < arguments.length; r++) {
501
- var t = null != arguments[r] ? arguments[r] : {};
502
- r % 2 ? ownKeys(Object(t), !0).forEach(function(r$1) {
503
- _defineProperty(e, r$1, t[r$1]);
504
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) {
505
- Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
506
- });
507
- }
508
- return e;
509
- }
510
-
511
- //#endregion
512
- //#region src/WebSocketHandler.ts
513
- /**
514
- * @since 0.0.1
515
- * WebSocket connection handler using Effect Platform Socket API.
516
- */
517
- var WebSocketHandler_exports = /* @__PURE__ */ __export({
518
- extractDocumentId: () => extractDocumentId,
519
- handleConnection: () => handleConnection,
520
- makeHandler: () => makeHandler
521
- });
522
- /**
523
- * Extract document ID from URL path.
524
- * Expected format: /doc/{documentId}
525
- */
526
- const extractDocumentId = (path) => {
527
- const parts = path.replace(/^\/+/, "").split("/");
528
- const docIndex = parts.lastIndexOf("doc");
529
- const part = parts[docIndex + 1];
530
- if (docIndex !== -1 && part) return effect_Effect.succeed(decodeURIComponent(part));
531
- return effect_Effect.fail(new MissingDocumentIdError({}));
532
- };
533
- /**
534
- * Decodes an encoded client message from the wire format.
535
- */
536
- const decodeClientMessage = (encoded) => {
537
- if (encoded.type === "submit") return {
538
- type: "submit",
539
- transaction: _voidhash_mimic.Transaction.decode(encoded.transaction)
540
- };
541
- return encoded;
542
- };
543
- /**
544
- * Encodes a server message for the wire format.
545
- */
546
- const encodeServerMessageForWire = (message) => {
547
- if (message.type === "transaction") return {
548
- type: "transaction",
549
- transaction: _voidhash_mimic.Transaction.encode(message.transaction),
550
- version: message.version
551
- };
552
- return message;
553
- };
554
- const parseClientMessage = (data) => effect_Effect.try({
555
- try: () => {
556
- const text = typeof data === "string" ? data : new TextDecoder().decode(data);
557
- return decodeClientMessage(JSON.parse(text));
558
- },
559
- catch: (cause) => new MessageParseError({ cause })
560
- });
561
- const encodeServerMessage = (message) => JSON.stringify(encodeServerMessageForWire(message));
562
- /**
563
- * Handle a WebSocket connection for a document.
564
- *
565
- * @param socket - The Effect Platform Socket
566
- * @param path - The URL path (e.g., "/doc/my-document-id")
567
- * @returns An Effect that handles the connection lifecycle
568
- */
569
- const handleConnection = (socket, path) => effect_Effect.gen(function* () {
570
- const config = yield* MimicServerConfigTag;
571
- const authService = yield* MimicAuthServiceTag;
572
- const documentManager = yield* DocumentManagerTag;
573
- const presenceManager = yield* PresenceManagerTag;
574
- const documentId = yield* extractDocumentId(path);
575
- const connectionId = crypto.randomUUID();
576
- let state = {
577
- documentId,
578
- connectionId,
579
- authenticated: false
580
- };
581
- let hasPresence = false;
582
- const write = yield* socket.writer;
583
- const sendMessage = (message) => write(encodeServerMessage(message));
584
- const sendPresenceSnapshot = effect_Effect.gen(function* () {
585
- if (!config.presence) return;
586
- yield* sendMessage({
587
- type: "presence_snapshot",
588
- selfId: connectionId,
589
- presences: (yield* presenceManager.getSnapshot(documentId)).presences
590
- });
591
- });
592
- const handleAuth = (token) => effect_Effect.gen(function* () {
593
- const result = yield* authService.authenticate(token);
594
- if (result.success) {
595
- state = _objectSpread2(_objectSpread2({}, state), {}, {
596
- authenticated: true,
597
- userId: result.userId
598
- });
599
- yield* sendMessage({
600
- type: "auth_result",
601
- success: true
602
- });
603
- yield* sendPresenceSnapshot;
604
- } else yield* sendMessage({
605
- type: "auth_result",
606
- success: false,
607
- error: result.error
608
- });
609
- });
610
- const handlePresenceSet = (data) => effect_Effect.gen(function* () {
611
- if (!state.authenticated) return;
612
- if (!config.presence) return;
613
- const validated = _voidhash_mimic.Presence.validateSafe(config.presence, data);
614
- if (validated === void 0) {
615
- yield* effect_Effect.logWarning("Invalid presence data received", {
616
- connectionId,
617
- data
618
- });
619
- return;
620
- }
621
- yield* presenceManager.set(documentId, connectionId, {
622
- data: validated,
623
- userId: state.userId
624
- });
625
- hasPresence = true;
626
- });
627
- const handlePresenceClear = effect_Effect.gen(function* () {
628
- if (!state.authenticated) return;
629
- if (!config.presence) return;
630
- yield* presenceManager.remove(documentId, connectionId);
631
- hasPresence = false;
632
- });
633
- const handleMessage = (message) => effect_Effect.gen(function* () {
634
- switch (message.type) {
635
- case "auth":
636
- yield* handleAuth(message.token);
637
- break;
638
- case "ping":
639
- yield* sendMessage({ type: "pong" });
640
- break;
641
- case "submit":
642
- if (!state.authenticated) {
643
- yield* sendMessage({
644
- type: "error",
645
- transactionId: message.transaction.id,
646
- reason: "Not authenticated"
647
- });
648
- return;
649
- }
650
- const submitResult = yield* documentManager.submit(documentId, message.transaction);
651
- if (!submitResult.success) yield* sendMessage({
652
- type: "error",
653
- transactionId: message.transaction.id,
654
- reason: submitResult.reason
655
- });
656
- break;
657
- case "request_snapshot":
658
- if (!state.authenticated) return;
659
- yield* sendMessage(yield* effect_Effect.catchAll(documentManager.getSnapshot(documentId), () => effect_Effect.succeed({
660
- type: "snapshot",
661
- state: null,
662
- version: 0
663
- })));
664
- break;
665
- case "presence_set":
666
- yield* handlePresenceSet(message.data);
667
- break;
668
- case "presence_clear":
669
- yield* handlePresenceClear;
670
- break;
671
- }
672
- });
673
- const subscribeFiber = yield* effect_Effect.fork(effect_Effect.gen(function* () {
674
- while (!state.authenticated) yield* effect_Effect.sleep(effect_Duration.millis(100));
675
- const broadcastStream = yield* effect_Effect.catchAll(documentManager.subscribe(documentId), () => effect_Effect.succeed(effect_Stream.empty));
676
- yield* effect_Stream.runForEach(broadcastStream, (broadcast) => sendMessage(broadcast));
677
- }).pipe(effect_Effect.scoped));
678
- const presenceFiber = yield* effect_Effect.fork(effect_Effect.gen(function* () {
679
- if (!config.presence) return;
680
- while (!state.authenticated) yield* effect_Effect.sleep(effect_Duration.millis(100));
681
- const presenceStream = yield* presenceManager.subscribe(documentId);
682
- yield* effect_Stream.runForEach(presenceStream, (event) => effect_Effect.gen(function* () {
683
- if (event.id === connectionId) return;
684
- if (event.type === "presence_update") yield* sendMessage({
685
- type: "presence_update",
686
- id: event.id,
687
- data: event.data,
688
- userId: event.userId
689
- });
690
- else if (event.type === "presence_remove") yield* sendMessage({
691
- type: "presence_remove",
692
- id: event.id
693
- });
694
- }));
695
- }).pipe(effect_Effect.scoped));
696
- yield* effect_Effect.addFinalizer(() => effect_Effect.gen(function* () {
697
- yield* effect_Fiber.interrupt(subscribeFiber);
698
- yield* effect_Fiber.interrupt(presenceFiber);
699
- if (hasPresence && config.presence) yield* presenceManager.remove(documentId, connectionId);
700
- }));
701
- yield* socket.runRaw((data) => effect_Effect.gen(function* () {
702
- yield* handleMessage(yield* parseClientMessage(data));
703
- }).pipe(effect_Effect.catchAll((error) => effect_Effect.logError("Message handling error", error))));
704
- });
705
- /**
706
- * Create a handler function for the WebSocket server.
707
- * Returns a function that takes a socket and document ID.
708
- */
709
- const makeHandler = effect_Effect.gen(function* () {
710
- const config = yield* MimicServerConfigTag;
711
- const authService = yield* MimicAuthServiceTag;
712
- const documentManager = yield* DocumentManagerTag;
713
- const presenceManager = yield* PresenceManagerTag;
714
- return (socket, documentId) => handleConnectionWithDocumentId(socket, documentId).pipe(effect_Effect.provideService(MimicServerConfigTag, config), effect_Effect.provideService(MimicAuthServiceTag, authService), effect_Effect.provideService(DocumentManagerTag, documentManager), effect_Effect.provideService(PresenceManagerTag, presenceManager), effect_Effect.scoped);
715
- });
716
- /**
717
- * Handle a WebSocket connection for a document (using document ID directly).
718
- */
719
- const handleConnectionWithDocumentId = (socket, documentId) => effect_Effect.gen(function* () {
720
- const config = yield* MimicServerConfigTag;
721
- const authService = yield* MimicAuthServiceTag;
722
- const documentManager = yield* DocumentManagerTag;
723
- const presenceManager = yield* PresenceManagerTag;
724
- const connectionId = crypto.randomUUID();
725
- let state = {
726
- documentId,
727
- connectionId,
728
- authenticated: false
729
- };
730
- let hasPresence = false;
731
- const write = yield* socket.writer;
732
- const sendMessage = (message) => write(encodeServerMessage(message));
733
- const sendPresenceSnapshot = effect_Effect.gen(function* () {
734
- if (!config.presence) return;
735
- yield* sendMessage({
736
- type: "presence_snapshot",
737
- selfId: connectionId,
738
- presences: (yield* presenceManager.getSnapshot(documentId)).presences
739
- });
740
- });
741
- const handleAuth = (token) => effect_Effect.gen(function* () {
742
- const result = yield* authService.authenticate(token);
743
- if (result.success) {
744
- state = _objectSpread2(_objectSpread2({}, state), {}, {
745
- authenticated: true,
746
- userId: result.userId
747
- });
748
- yield* sendMessage({
749
- type: "auth_result",
750
- success: true
751
- });
752
- yield* sendPresenceSnapshot;
753
- } else yield* sendMessage({
754
- type: "auth_result",
755
- success: false,
756
- error: result.error
757
- });
758
- });
759
- const handlePresenceSet = (data) => effect_Effect.gen(function* () {
760
- if (!state.authenticated) return;
761
- if (!config.presence) return;
762
- const validated = _voidhash_mimic.Presence.validateSafe(config.presence, data);
763
- if (validated === void 0) {
764
- yield* effect_Effect.logWarning("Invalid presence data received", {
765
- connectionId,
766
- data
767
- });
768
- return;
769
- }
770
- yield* presenceManager.set(documentId, connectionId, {
771
- data: validated,
772
- userId: state.userId
773
- });
774
- hasPresence = true;
775
- });
776
- const handlePresenceClear = effect_Effect.gen(function* () {
777
- if (!state.authenticated) return;
778
- if (!config.presence) return;
779
- yield* presenceManager.remove(documentId, connectionId);
780
- hasPresence = false;
781
- });
782
- const handleMessage = (message) => effect_Effect.gen(function* () {
783
- switch (message.type) {
784
- case "auth":
785
- yield* handleAuth(message.token);
786
- break;
787
- case "ping":
788
- yield* sendMessage({ type: "pong" });
789
- break;
790
- case "submit":
791
- if (!state.authenticated) {
792
- yield* sendMessage({
793
- type: "error",
794
- transactionId: message.transaction.id,
795
- reason: "Not authenticated"
796
- });
797
- return;
798
- }
799
- const submitResult = yield* documentManager.submit(documentId, message.transaction);
800
- if (!submitResult.success) yield* sendMessage({
801
- type: "error",
802
- transactionId: message.transaction.id,
803
- reason: submitResult.reason
804
- });
805
- break;
806
- case "request_snapshot":
807
- if (!state.authenticated) return;
808
- yield* sendMessage(yield* documentManager.getSnapshot(documentId));
809
- break;
810
- case "presence_set":
811
- yield* handlePresenceSet(message.data);
812
- break;
813
- case "presence_clear":
814
- yield* handlePresenceClear;
815
- break;
816
- }
817
- });
818
- const subscribeFiber = yield* effect_Effect.fork(effect_Effect.gen(function* () {
819
- while (!state.authenticated) yield* effect_Effect.sleep(effect_Duration.millis(100));
820
- const broadcastStream = yield* documentManager.subscribe(documentId);
821
- yield* effect_Stream.runForEach(broadcastStream, (broadcast) => sendMessage(broadcast));
822
- }).pipe(effect_Effect.scoped));
823
- const presenceFiber = yield* effect_Effect.fork(effect_Effect.gen(function* () {
824
- if (!config.presence) return;
825
- while (!state.authenticated) yield* effect_Effect.sleep(effect_Duration.millis(100));
826
- const presenceStream = yield* presenceManager.subscribe(documentId);
827
- yield* effect_Stream.runForEach(presenceStream, (event) => effect_Effect.gen(function* () {
828
- if (event.id === connectionId) return;
829
- if (event.type === "presence_update") yield* sendMessage({
830
- type: "presence_update",
831
- id: event.id,
832
- data: event.data,
833
- userId: event.userId
834
- });
835
- else if (event.type === "presence_remove") yield* sendMessage({
836
- type: "presence_remove",
837
- id: event.id
838
- });
839
- }));
840
- }).pipe(effect_Effect.scoped));
841
- yield* effect_Effect.addFinalizer(() => effect_Effect.gen(function* () {
842
- yield* effect_Fiber.interrupt(subscribeFiber);
843
- yield* effect_Fiber.interrupt(presenceFiber);
844
- if (hasPresence && config.presence) yield* presenceManager.remove(documentId, connectionId);
845
- }));
846
- yield* socket.runRaw((data) => effect_Effect.gen(function* () {
847
- yield* handleMessage(yield* parseClientMessage(data));
848
- }).pipe(effect_Effect.catchAll((error) => effect_Effect.logError("Message handling error", error))));
849
- });
850
-
851
- //#endregion
852
- //#region src/storage/InMemoryDataStorage.ts
853
- /**
854
- * @since 0.0.1
855
- * In-memory data storage implementation for Mimic documents.
856
- * Provides ephemeral storage - data is lost when the server restarts.
857
- */
858
- var InMemoryDataStorage_exports = /* @__PURE__ */ __export({
859
- layer: () => layer$2,
860
- layerDefault: () => layerDefault$1
861
- });
862
- /**
863
- * Create an in-memory storage service.
864
- * Uses a HashMap to store documents in memory.
865
- */
866
- const makeInMemoryStorage = effect_Effect.gen(function* () {
867
- const store = yield* effect_Ref.make(effect_HashMap.empty());
868
- return {
869
- load: (documentId) => effect_Effect.gen(function* () {
870
- const current = yield* effect_Ref.get(store);
871
- const result = effect_HashMap.get(current, documentId);
872
- return result._tag === "Some" ? result.value : void 0;
873
- }),
874
- save: (documentId, state) => effect_Ref.update(store, (map) => effect_HashMap.set(map, documentId, state)),
875
- delete: (documentId) => effect_Ref.update(store, (map) => effect_HashMap.remove(map, documentId)),
876
- onLoad: (state) => effect_Effect.succeed(state),
877
- onSave: (state) => effect_Effect.succeed(state)
878
- };
879
- });
880
- /**
881
- * Layer that provides in-memory data storage.
882
- * This is the default storage implementation - ephemeral and non-persistent.
883
- */
884
- const layer$2 = effect_Layer.effect(MimicDataStorageTag, makeInMemoryStorage);
885
- /**
886
- * Default layer alias for convenience.
887
- */
888
- const layerDefault$1 = layer$2;
889
-
890
- //#endregion
891
- //#region src/auth/NoAuth.ts
892
- /**
893
- * @since 0.0.1
894
- * No authentication implementation for Mimic connections.
895
- * All connections are automatically authenticated (open access).
896
- */
897
- var NoAuth_exports = /* @__PURE__ */ __export({
898
- layer: () => layer$1,
899
- layerDefault: () => layerDefault
900
- });
901
- /**
902
- * Authentication service that auto-succeeds all authentication requests.
903
- * Use this for development or when authentication is handled externally.
904
- */
905
- const noAuthService = { authenticate: (_token) => effect_Effect.succeed({ success: true }) };
906
- /**
907
- * Layer that provides no authentication (open access).
908
- * All connections are automatically authenticated.
909
- *
910
- * WARNING: Only use this for development or when authentication
911
- * is handled at a different layer (e.g., API gateway, reverse proxy).
912
- */
913
- const layer$1 = effect_Layer.succeed(MimicAuthServiceTag, noAuthService);
914
- /**
915
- * Default layer alias for convenience.
916
- */
917
- const layerDefault = layer$1;
918
-
919
- //#endregion
920
- //#region src/MimicServer.ts
921
- /**
922
- * @since 0.0.1
923
- * Mimic server layer composition.
924
- */
925
- var MimicServer_exports = /* @__PURE__ */ __export({
926
- MimicWebSocketHandler: () => MimicWebSocketHandler,
927
- documentManagerLayer: () => documentManagerLayer,
928
- handlerLayer: () => handlerLayer,
929
- layer: () => layer,
930
- layerHttpLayerRouter: () => layerHttpLayerRouter,
931
- run: () => run
932
- });
933
- /**
934
- * Tag for the WebSocket handler function.
935
- */
936
- var MimicWebSocketHandler = class extends effect_Context.Tag("@voidhash/mimic-server-effect/MimicWebSocketHandler")() {};
937
- /**
938
- * Create a Mimic WebSocket handler layer.
939
- *
940
- * This layer provides a handler function that can be used with any WebSocket server
941
- * implementation. The handler takes a socket and document ID and manages the
942
- * document synchronization.
943
- *
944
- * By default, uses in-memory storage and no authentication.
945
- * Override these by providing MimicDataStorage and MimicAuthService layers.
946
- *
947
- * @example
948
- * ```typescript
949
- * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
950
- * import { Primitive } from "@voidhash/mimic";
951
- *
952
- * const TodoSchema = Primitive.Struct({
953
- * title: Primitive.String(),
954
- * completed: Primitive.Boolean(),
955
- * });
956
- *
957
- * // Create the handler layer with defaults
958
- * const HandlerLayer = MimicServer.layer({
959
- * basePath: "/mimic/todo",
960
- * schema: TodoSchema
961
- * });
962
- *
963
- * // Or with custom auth
964
- * const HandlerLayerWithAuth = MimicServer.layer({
965
- * basePath: "/mimic/todo",
966
- * schema: TodoSchema
967
- * }).pipe(
968
- * Layer.provideMerge(MimicAuthService.layer({
969
- * authHandler: (token) => ({ success: true, userId: "user-123" })
970
- * }))
971
- * );
972
- * ```
973
- */
974
- const layer = (options) => {
975
- const configLayer = layer$7({
976
- schema: options.schema,
977
- maxTransactionHistory: options.maxTransactionHistory,
978
- presence: options.presence
979
- });
980
- return effect_Layer.merge(effect_Layer.effect(MimicWebSocketHandler, makeHandler).pipe(effect_Layer.provide(layer$5), effect_Layer.provide(layer$3), effect_Layer.provide(configLayer)), layer$5.pipe(effect_Layer.provide(configLayer))).pipe(effect_Layer.provide(layerDefault$1), effect_Layer.provide(layerDefault));
981
- };
982
- /**
983
- * Create the Mimic server handler layer.
984
- * This layer provides the WebSocket handler that can be used with any WebSocket server.
985
- *
986
- * @example
987
- * ```typescript
988
- * import { MimicServer } from "@voidhash/mimic-server-effect";
989
- * import { SocketServer } from "@effect/platform/SocketServer";
990
- * import { Primitive } from "@voidhash/mimic";
991
- *
992
- * // Define your document schema
993
- * const TodoSchema = Primitive.Struct({
994
- * title: Primitive.String(),
995
- * completed: Primitive.Boolean(),
996
- * });
997
- *
998
- * // Create the server layer
999
- * const serverLayer = MimicServer.handlerLayer({
1000
- * schema: TodoSchema,
1001
- * });
1002
- *
1003
- * // Run with your socket server
1004
- * Effect.gen(function* () {
1005
- * const handler = yield* MimicServer.MimicWebSocketHandler;
1006
- * const server = yield* SocketServer;
1007
- *
1008
- * yield* server.run((socket) =>
1009
- * // Extract document ID from request and call handler
1010
- * handler(socket, "my-document-id")
1011
- * );
1012
- * }).pipe(
1013
- * Effect.provide(serverLayer),
1014
- * Effect.provide(YourSocketServerLayer),
1015
- * );
1016
- * ```
1017
- */
1018
- const handlerLayer = (options) => effect_Layer.effect(MimicWebSocketHandler, makeHandler).pipe(effect_Layer.provide(layer$5), effect_Layer.provide(layer$3), effect_Layer.provide(layer$7(options)), effect_Layer.provide(layerDefault$1), effect_Layer.provide(layerDefault));
1019
- /**
1020
- * Create the document manager layer.
1021
- */
1022
- const documentManagerLayer = (options) => layer$5.pipe(effect_Layer.provide(layer$7(options)), effect_Layer.provide(layerDefault$1), effect_Layer.provide(layerDefault));
1023
- /**
1024
- * Run a Mimic WebSocket server with the provided handler.
1025
- *
1026
- * This is a helper that:
1027
- * 1. Gets the WebSocket handler from context
1028
- * 2. Runs the socket server with the handler
1029
- *
1030
- * Note: The document ID extraction from socket is implementation-specific.
1031
- * You may need to customize this based on your socket server.
1032
- */
1033
- const run = (extractDocumentId$1) => effect_Effect.gen(function* () {
1034
- const handler = yield* MimicWebSocketHandler;
1035
- yield* (yield* _effect_platform_SocketServer.SocketServer).run((socket) => effect_Effect.gen(function* () {
1036
- yield* handler(socket, yield* extractDocumentId$1(socket));
1037
- }).pipe(effect_Effect.catchAll((error) => effect_Effect.logError("Connection error", error))));
1038
- });
1039
- /**
1040
- * Create the HTTP handler effect for WebSocket upgrade.
1041
- * This handler:
1042
- * 1. Extracts the document ID from the URL path
1043
- * 2. Upgrades the HTTP connection to WebSocket
1044
- * 3. Delegates to the WebSocketHandler for document sync
1045
- */
1046
- const makeMimicHandler = effect_Effect.gen(function* () {
1047
- const config = yield* MimicServerConfigTag;
1048
- const authService = yield* MimicAuthServiceTag;
1049
- const documentManager = yield* DocumentManagerTag;
1050
- const presenceManager = yield* PresenceManagerTag;
1051
- return effect_Effect.gen(function* () {
1052
- const request = yield* _effect_platform.HttpServerRequest.HttpServerRequest;
1053
- yield* extractDocumentId(request.url);
1054
- const socket = yield* request.upgrade;
1055
- yield* handleConnection(socket, request.url).pipe(effect_Effect.provideService(MimicServerConfigTag, config), effect_Effect.provideService(MimicAuthServiceTag, authService), effect_Effect.provideService(DocumentManagerTag, documentManager), effect_Effect.provideService(PresenceManagerTag, presenceManager), effect_Effect.scoped, effect_Effect.catchAll((error) => effect_Effect.logError("WebSocket connection error", error)));
1056
- return _effect_platform.HttpServerResponse.empty();
1057
- }).pipe(effect_Effect.catchAll((error) => effect_Effect.gen(function* () {
1058
- yield* effect_Effect.logWarning("WebSocket upgrade failed", error);
1059
- return _effect_platform.HttpServerResponse.text("WebSocket upgrade failed", { status: 400 });
1060
- })));
1061
- });
1062
- /**
1063
- * Create a Mimic server layer that integrates with HttpLayerRouter.
1064
- *
1065
- * This function creates a layer that:
1066
- * 1. Registers a WebSocket route at the specified base path
1067
- * 2. Handles WebSocket upgrades for document sync
1068
- * 3. Provides all required dependencies (config, auth, storage, document manager)
1069
- *
1070
- * By default, uses in-memory storage and no authentication.
1071
- * To override these defaults, provide custom layers before the defaults:
1072
- *
1073
- * @example
1074
- * ```typescript
1075
- * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
1076
- * import { HttpLayerRouter } from "@effect/platform";
1077
- * import { Primitive } from "@voidhash/mimic";
1078
- *
1079
- * const TodoSchema = Primitive.Struct({
1080
- * title: Primitive.String(),
1081
- * completed: Primitive.Boolean(),
1082
- * });
1083
- *
1084
- * // Create the Mimic route layer with defaults
1085
- * const MimicRoute = MimicServer.layerHttpLayerRouter({
1086
- * basePath: "/mimic/todo",
1087
- * schema: TodoSchema
1088
- * });
1089
- *
1090
- * // Or with custom auth - use Layer.provide to inject before defaults
1091
- * const MimicRouteWithAuth = MimicServer.layerHttpLayerRouter({
1092
- * basePath: "/mimic/todo",
1093
- * schema: TodoSchema,
1094
- * authLayer: MimicAuthService.layer({
1095
- * authHandler: (token) => ({ success: true, userId: token })
1096
- * })
1097
- * });
1098
- *
1099
- * // Merge with other routes and serve
1100
- * const AllRoutes = Layer.mergeAll(MimicRoute, OtherRoutes);
1101
- * HttpLayerRouter.serve(AllRoutes).pipe(
1102
- * Layer.provide(BunHttpServer.layer({ port: 3000 })),
1103
- * Layer.launch,
1104
- * BunRuntime.runMain
1105
- * );
1106
- * ```
1107
- */
1108
- const layerHttpLayerRouter = (options) => {
1109
- var _options$basePath, _options$authLayer, _options$storageLayer;
1110
- const wsPath = `${(_options$basePath = options.basePath) !== null && _options$basePath !== void 0 ? _options$basePath : "/mimic"}/doc/*`;
1111
- const configLayer = layer$7({
1112
- schema: options.schema,
1113
- maxTransactionHistory: options.maxTransactionHistory,
1114
- presence: options.presence
1115
- });
1116
- const authLayer = (_options$authLayer = options.authLayer) !== null && _options$authLayer !== void 0 ? _options$authLayer : layerDefault;
1117
- const storageLayer = (_options$storageLayer = options.storageLayer) !== null && _options$storageLayer !== void 0 ? _options$storageLayer : layerDefault$1;
1118
- const registerRoute = effect_Effect.gen(function* () {
1119
- const router = yield* _effect_platform.HttpLayerRouter.HttpRouter;
1120
- const handler = yield* makeMimicHandler;
1121
- yield* router.add("GET", wsPath, handler);
1122
- });
1123
- return effect_Layer.scopedDiscard(registerRoute).pipe(effect_Layer.provide(layer$5), effect_Layer.provide(layer$3), effect_Layer.provide(configLayer), effect_Layer.provide(storageLayer), effect_Layer.provide(authLayer));
1124
- };
1125
-
1126
- //#endregion
1127
- //#region src/DocumentProtocol.ts
1128
- /**
1129
- * @since 0.0.1
1130
- * Protocol and schema definitions for document communication.
1131
- */
1132
- var DocumentProtocol_exports = /* @__PURE__ */ __export({
1133
- AuthResultMessageSchema: () => AuthResultMessageSchema,
1134
- ErrorMessageSchema: () => ErrorMessageSchema,
1135
- OperationSchema: () => OperationSchema,
1136
- PongMessageSchema: () => PongMessageSchema,
1137
- ServerBroadcastSchema: () => ServerBroadcastSchema,
1138
- SnapshotMessageSchema: () => SnapshotMessageSchema,
1139
- SubmitResultSchema: () => SubmitResultSchema,
1140
- TransactionMessageSchema: () => TransactionMessageSchema,
1141
- TransactionSchema: () => TransactionSchema
1142
- });
1143
- /**
1144
- * Schema for a transaction operation.
1145
- */
1146
- const OperationSchema = effect_Schema.Struct({
1147
- kind: effect_Schema.String,
1148
- path: effect_Schema.Unknown,
1149
- payload: effect_Schema.Unknown
1150
- });
1151
- /**
1152
- * Schema for a transaction.
1153
- */
1154
- const TransactionSchema = effect_Schema.Struct({
1155
- id: effect_Schema.String,
1156
- ops: effect_Schema.Array(OperationSchema),
1157
- timestamp: effect_Schema.Number
1158
- });
1159
- /**
1160
- * Schema for a server message that broadcasts a committed transaction.
1161
- */
1162
- const TransactionMessageSchema = effect_Schema.Struct({
1163
- type: effect_Schema.Literal("transaction"),
1164
- transaction: TransactionSchema,
1165
- version: effect_Schema.Number
1166
- });
1167
- /**
1168
- * Schema for a server message containing a snapshot.
1169
- */
1170
- const SnapshotMessageSchema = effect_Schema.Struct({
1171
- type: effect_Schema.Literal("snapshot"),
1172
- state: effect_Schema.Unknown,
1173
- version: effect_Schema.Number
1174
- });
1175
- /**
1176
- * Schema for a server error message.
1177
- */
1178
- const ErrorMessageSchema = effect_Schema.Struct({
1179
- type: effect_Schema.Literal("error"),
1180
- transactionId: effect_Schema.String,
1181
- reason: effect_Schema.String
1182
- });
1183
- /**
1184
- * Schema for a pong message.
1185
- */
1186
- const PongMessageSchema = effect_Schema.Struct({ type: effect_Schema.Literal("pong") });
1187
- /**
1188
- * Schema for authentication result message.
1189
- */
1190
- const AuthResultMessageSchema = effect_Schema.Struct({
1191
- type: effect_Schema.Literal("auth_result"),
1192
- success: effect_Schema.Boolean,
1193
- error: effect_Schema.optional(effect_Schema.String)
1194
- });
1195
- /**
1196
- * Union of all server broadcast messages.
1197
- */
1198
- const ServerBroadcastSchema = effect_Schema.Union(TransactionMessageSchema, ErrorMessageSchema);
1199
- /**
1200
- * Result of submitting a transaction.
1201
- */
1202
- const SubmitResultSchema = effect_Schema.Union(effect_Schema.Struct({
1203
- success: effect_Schema.Literal(true),
1204
- version: effect_Schema.Number
1205
- }), effect_Schema.Struct({
1206
- success: effect_Schema.Literal(false),
1207
- reason: effect_Schema.String
1208
- }));
1209
-
1210
- //#endregion
1211
- exports.AuthenticationError = AuthenticationError;
1
+ const require_MimicConfig = require('./MimicConfig.cjs');
2
+ const require_MimicDataStorage = require('./MimicDataStorage.cjs');
3
+ const require_DocumentManager = require('./DocumentManager.cjs');
4
+ const require_MimicAuthService = require('./MimicAuthService.cjs');
5
+ const require_PresenceManager = require('./PresenceManager.cjs');
6
+ const require_errors = require('./errors.cjs');
7
+ const require_WebSocketHandler = require('./WebSocketHandler.cjs');
8
+ const require_InMemoryDataStorage = require('./storage/InMemoryDataStorage.cjs');
9
+ const require_NoAuth = require('./auth/NoAuth.cjs');
10
+ const require_MimicServer = require('./MimicServer.cjs');
11
+ const require_DocumentProtocol = require('./DocumentProtocol.cjs');
12
+
13
+ exports.AuthenticationError = require_errors.AuthenticationError;
1212
14
  Object.defineProperty(exports, 'DocumentManager', {
1213
15
  enumerable: true,
1214
16
  get: function () {
1215
- return DocumentManager_exports;
17
+ return require_DocumentManager.DocumentManager_exports;
1216
18
  }
1217
19
  });
1218
- exports.DocumentNotFoundError = DocumentNotFoundError;
20
+ exports.DocumentNotFoundError = require_errors.DocumentNotFoundError;
1219
21
  Object.defineProperty(exports, 'DocumentProtocol', {
1220
22
  enumerable: true,
1221
23
  get: function () {
1222
- return DocumentProtocol_exports;
24
+ return require_DocumentProtocol.DocumentProtocol_exports;
1223
25
  }
1224
26
  });
1225
- exports.DocumentTypeNotFoundError = DocumentTypeNotFoundError;
1226
- exports.InvalidConnectionError = InvalidConnectionError;
1227
- exports.MessageParseError = MessageParseError;
27
+ exports.DocumentTypeNotFoundError = require_errors.DocumentTypeNotFoundError;
28
+ exports.InvalidConnectionError = require_errors.InvalidConnectionError;
29
+ exports.MessageParseError = require_errors.MessageParseError;
1228
30
  Object.defineProperty(exports, 'MimicAuthService', {
1229
31
  enumerable: true,
1230
32
  get: function () {
1231
- return MimicAuthService_exports;
33
+ return require_MimicAuthService.MimicAuthService_exports;
1232
34
  }
1233
35
  });
1234
36
  Object.defineProperty(exports, 'MimicConfig', {
1235
37
  enumerable: true,
1236
38
  get: function () {
1237
- return MimicConfig_exports;
39
+ return require_MimicConfig.MimicConfig_exports;
1238
40
  }
1239
41
  });
1240
42
  Object.defineProperty(exports, 'MimicDataStorage', {
1241
43
  enumerable: true,
1242
44
  get: function () {
1243
- return MimicDataStorage_exports;
45
+ return require_MimicDataStorage.MimicDataStorage_exports;
1244
46
  }
1245
47
  });
1246
48
  Object.defineProperty(exports, 'MimicInMemoryDataStorage', {
1247
49
  enumerable: true,
1248
50
  get: function () {
1249
- return InMemoryDataStorage_exports;
51
+ return require_InMemoryDataStorage.InMemoryDataStorage_exports;
1250
52
  }
1251
53
  });
1252
54
  Object.defineProperty(exports, 'MimicNoAuth', {
1253
55
  enumerable: true,
1254
56
  get: function () {
1255
- return NoAuth_exports;
57
+ return require_NoAuth.NoAuth_exports;
1256
58
  }
1257
59
  });
1258
60
  Object.defineProperty(exports, 'MimicServer', {
1259
61
  enumerable: true,
1260
62
  get: function () {
1261
- return MimicServer_exports;
63
+ return require_MimicServer.MimicServer_exports;
1262
64
  }
1263
65
  });
1264
- exports.MissingDocumentIdError = MissingDocumentIdError;
66
+ exports.MissingDocumentIdError = require_errors.MissingDocumentIdError;
1265
67
  Object.defineProperty(exports, 'PresenceManager', {
1266
68
  enumerable: true,
1267
69
  get: function () {
1268
- return PresenceManager_exports;
70
+ return require_PresenceManager.PresenceManager_exports;
1269
71
  }
1270
72
  });
1271
- exports.TransactionRejectedError = TransactionRejectedError;
73
+ exports.TransactionRejectedError = require_errors.TransactionRejectedError;
1272
74
  Object.defineProperty(exports, 'WebSocketHandler', {
1273
75
  enumerable: true,
1274
76
  get: function () {
1275
- return WebSocketHandler_exports;
77
+ return require_WebSocketHandler.WebSocketHandler_exports;
1276
78
  }
1277
79
  });