@voidhash/mimic-effect 0.0.1 → 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 (100) 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/src/MimicServer.ts +1 -1
  97. package/tsdown.config.ts +1 -1
  98. package/dist/index.d.cts.map +0 -1
  99. package/dist/index.d.mts.map +0 -1
  100. package/dist/index.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MimicDataStorage.mjs","names":[],"sources":["../src/MimicDataStorage.ts"],"sourcesContent":["/**\n * @since 0.0.1\n * Data storage service interface for Mimic documents.\n * Provides pluggable storage adapters with load/save hooks for data transformation.\n */\nimport * as Effect from \"effect/Effect\";\nimport * as Context from \"effect/Context\";\nimport * as Layer from \"effect/Layer\";\nimport * as Data from \"effect/Data\";\n\n// =============================================================================\n// Error Types\n// =============================================================================\n\n/**\n * Error when loading a document from storage fails.\n */\nexport class StorageLoadError extends Data.TaggedError(\"StorageLoadError\")<{\n readonly documentId: string;\n readonly cause: unknown;\n}> {\n override get message(): string {\n return `Failed to load document ${this.documentId}: ${String(this.cause)}`;\n }\n}\n\n/**\n * Error when saving a document to storage fails.\n */\nexport class StorageSaveError extends Data.TaggedError(\"StorageSaveError\")<{\n readonly documentId: string;\n readonly cause: unknown;\n}> {\n override get message(): string {\n return `Failed to save document ${this.documentId}: ${String(this.cause)}`;\n }\n}\n\n/**\n * Error when deleting a document from storage fails.\n */\nexport class StorageDeleteError extends Data.TaggedError(\"StorageDeleteError\")<{\n readonly documentId: string;\n readonly cause: unknown;\n}> {\n override get message(): string {\n return `Failed to delete document ${this.documentId}: ${String(this.cause)}`;\n }\n}\n\n/**\n * Union of all storage errors.\n */\nexport type StorageError = StorageLoadError | StorageSaveError | StorageDeleteError;\n\n// =============================================================================\n// Storage Service Interface\n// =============================================================================\n\n/**\n * Data storage service interface.\n * Implementations can persist documents to various backends (memory, S3, database, etc.)\n */\nexport interface MimicDataStorage {\n /**\n * Load a document's state from storage.\n * @param documentId - The unique identifier for the document\n * @returns The document state, or undefined if not found\n */\n readonly load: (\n documentId: string\n ) => Effect.Effect<unknown | undefined, StorageLoadError>;\n\n /**\n * Save a document's state to storage.\n * @param documentId - The unique identifier for the document\n * @param state - The document state to persist\n */\n readonly save: (\n documentId: string,\n state: unknown\n ) => Effect.Effect<void, StorageSaveError>;\n\n /**\n * Delete a document from storage.\n * @param documentId - The unique identifier for the document\n */\n readonly delete: (\n documentId: string\n ) => Effect.Effect<void, StorageDeleteError>;\n\n /**\n * Transform data after loading from storage.\n * Useful for migrations, decryption, decompression, etc.\n * @param state - The raw state loaded from storage\n * @returns The transformed state\n */\n readonly onLoad: (state: unknown) => Effect.Effect<unknown>;\n\n /**\n * Transform/validate data before saving to storage.\n * Useful for encryption, compression, validation, etc.\n * @param state - The state to be saved\n * @returns The transformed state\n */\n readonly onSave: (state: unknown) => Effect.Effect<unknown>;\n}\n\n// =============================================================================\n// Context Tag\n// =============================================================================\n\n/**\n * Context tag for MimicDataStorage service.\n */\nexport class MimicDataStorageTag extends Context.Tag(\n \"@voidhash/mimic-server-effect/MimicDataStorage\"\n)<MimicDataStorageTag, MimicDataStorage>() {}\n\n// =============================================================================\n// Layer Constructors\n// =============================================================================\n\n/**\n * Create a MimicDataStorage layer from a storage implementation.\n */\nexport const layer = (storage: MimicDataStorage): Layer.Layer<MimicDataStorageTag> =>\n Layer.succeed(MimicDataStorageTag, storage);\n\n/**\n * Create a MimicDataStorage layer from an Effect that produces a storage implementation.\n */\nexport const layerEffect = <E, R>(\n effect: Effect.Effect<MimicDataStorage, E, R>\n): Layer.Layer<MimicDataStorageTag, E, R> =>\n Layer.effect(MimicDataStorageTag, effect);\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Create a simple storage implementation with minimal configuration.\n */\nexport const make = (options: {\n readonly load: (documentId: string) => Effect.Effect<unknown | undefined, StorageLoadError>;\n readonly save: (documentId: string, state: unknown) => Effect.Effect<void, StorageSaveError>;\n readonly delete?: (documentId: string) => Effect.Effect<void, StorageDeleteError>;\n readonly onLoad?: (state: unknown) => Effect.Effect<unknown>;\n readonly onSave?: (state: unknown) => Effect.Effect<unknown>;\n}): MimicDataStorage => ({\n load: options.load,\n save: options.save,\n delete: options.delete ?? (() => Effect.void),\n onLoad: options.onLoad ?? ((state) => Effect.succeed(state)),\n onSave: options.onSave ?? ((state) => Effect.succeed(state)),\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAiBA,IAAa,mBAAb,cAAsC,KAAK,YAAY,mBAAmB,CAGvE;CACD,IAAa,UAAkB;AAC7B,SAAO,2BAA2B,KAAK,WAAW,IAAI,OAAO,KAAK,MAAM;;;;;;AAO5E,IAAa,mBAAb,cAAsC,KAAK,YAAY,mBAAmB,CAGvE;CACD,IAAa,UAAkB;AAC7B,SAAO,2BAA2B,KAAK,WAAW,IAAI,OAAO,KAAK,MAAM;;;;;;AAO5E,IAAa,qBAAb,cAAwC,KAAK,YAAY,qBAAqB,CAG3E;CACD,IAAa,UAAkB;AAC7B,SAAO,6BAA6B,KAAK,WAAW,IAAI,OAAO,KAAK,MAAM;;;;;;AAqE9E,IAAa,sBAAb,cAAyC,QAAQ,IAC/C,iDACD,EAAyC,CAAC;;;;AAS3C,MAAa,SAAS,YACpB,MAAM,QAAQ,qBAAqB,QAAQ;;;;AAK7C,MAAa,eACX,WAEA,MAAM,OAAO,qBAAqB,OAAO;;;;AAS3C,MAAa,QAAQ,YAMG;;QAAC;EACvB,MAAM,QAAQ;EACd,MAAM,QAAQ;EACd,2BAAQ,QAAQ,0EAAiB,OAAO;EACxC,2BAAQ,QAAQ,qEAAY,UAAU,OAAO,QAAQ,MAAM;EAC3D,2BAAQ,QAAQ,qEAAY,UAAU,OAAO,QAAQ,MAAM;EAC5D"}
@@ -0,0 +1,230 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_MimicConfig = require('./MimicConfig.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_WebSocketHandler = require('./WebSocketHandler.cjs');
7
+ const require_InMemoryDataStorage = require('./storage/InMemoryDataStorage.cjs');
8
+ const require_NoAuth = require('./auth/NoAuth.cjs');
9
+ let effect_Effect = require("effect/Effect");
10
+ effect_Effect = require_rolldown_runtime.__toESM(effect_Effect);
11
+ let effect_Layer = require("effect/Layer");
12
+ effect_Layer = require_rolldown_runtime.__toESM(effect_Layer);
13
+ let effect_Context = require("effect/Context");
14
+ effect_Context = require_rolldown_runtime.__toESM(effect_Context);
15
+ let _effect_platform_SocketServer = require("@effect/platform/SocketServer");
16
+ let _effect_platform = require("@effect/platform");
17
+
18
+ //#region src/MimicServer.ts
19
+ /**
20
+ * @since 0.0.1
21
+ * Mimic server layer composition.
22
+ */
23
+ var MimicServer_exports = /* @__PURE__ */ require_rolldown_runtime.__export({
24
+ MimicWebSocketHandler: () => MimicWebSocketHandler,
25
+ documentManagerLayer: () => documentManagerLayer,
26
+ handlerLayer: () => handlerLayer,
27
+ layer: () => layer,
28
+ layerHttpLayerRouter: () => layerHttpLayerRouter,
29
+ run: () => run
30
+ });
31
+ /**
32
+ * Tag for the WebSocket handler function.
33
+ */
34
+ var MimicWebSocketHandler = class extends effect_Context.Tag("@voidhash/mimic-server-effect/MimicWebSocketHandler")() {};
35
+ /**
36
+ * Create a Mimic WebSocket handler layer.
37
+ *
38
+ * This layer provides a handler function that can be used with any WebSocket server
39
+ * implementation. The handler takes a socket and document ID and manages the
40
+ * document synchronization.
41
+ *
42
+ * By default, uses in-memory storage and no authentication.
43
+ * Override these by providing MimicDataStorage and MimicAuthService layers.
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
48
+ * import { Primitive } from "@voidhash/mimic";
49
+ *
50
+ * const TodoSchema = Primitive.Struct({
51
+ * title: Primitive.String(),
52
+ * completed: Primitive.Boolean(),
53
+ * });
54
+ *
55
+ * // Create the handler layer with defaults
56
+ * const HandlerLayer = MimicServer.layer({
57
+ * basePath: "/mimic/todo",
58
+ * schema: TodoSchema
59
+ * });
60
+ *
61
+ * // Or with custom auth
62
+ * const HandlerLayerWithAuth = MimicServer.layer({
63
+ * basePath: "/mimic/todo",
64
+ * schema: TodoSchema
65
+ * }).pipe(
66
+ * Layer.provideMerge(MimicAuthService.layer({
67
+ * authHandler: (token) => ({ success: true, userId: "user-123" })
68
+ * }))
69
+ * );
70
+ * ```
71
+ */
72
+ const layer = (options) => {
73
+ const configLayer = require_MimicConfig.layer({
74
+ schema: options.schema,
75
+ maxTransactionHistory: options.maxTransactionHistory,
76
+ presence: options.presence
77
+ });
78
+ return effect_Layer.merge(effect_Layer.effect(MimicWebSocketHandler, require_WebSocketHandler.makeHandler).pipe(effect_Layer.provide(require_DocumentManager.layer), effect_Layer.provide(require_PresenceManager.layer), effect_Layer.provide(configLayer)), require_DocumentManager.layer.pipe(effect_Layer.provide(configLayer))).pipe(effect_Layer.provide(require_InMemoryDataStorage.layerDefault), effect_Layer.provide(require_NoAuth.layerDefault));
79
+ };
80
+ /**
81
+ * Create the Mimic server handler layer.
82
+ * This layer provides the WebSocket handler that can be used with any WebSocket server.
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * import { MimicServer } from "@voidhash/mimic-server-effect";
87
+ * import { SocketServer } from "@effect/platform/SocketServer";
88
+ * import { Primitive } from "@voidhash/mimic";
89
+ *
90
+ * // Define your document schema
91
+ * const TodoSchema = Primitive.Struct({
92
+ * title: Primitive.String(),
93
+ * completed: Primitive.Boolean(),
94
+ * });
95
+ *
96
+ * // Create the server layer
97
+ * const serverLayer = MimicServer.handlerLayer({
98
+ * schema: TodoSchema,
99
+ * });
100
+ *
101
+ * // Run with your socket server
102
+ * Effect.gen(function* () {
103
+ * const handler = yield* MimicServer.MimicWebSocketHandler;
104
+ * const server = yield* SocketServer;
105
+ *
106
+ * yield* server.run((socket) =>
107
+ * // Extract document ID from request and call handler
108
+ * handler(socket, "my-document-id")
109
+ * );
110
+ * }).pipe(
111
+ * Effect.provide(serverLayer),
112
+ * Effect.provide(YourSocketServerLayer),
113
+ * );
114
+ * ```
115
+ */
116
+ const handlerLayer = (options) => effect_Layer.effect(MimicWebSocketHandler, require_WebSocketHandler.makeHandler).pipe(effect_Layer.provide(require_DocumentManager.layer), effect_Layer.provide(require_PresenceManager.layer), effect_Layer.provide(require_MimicConfig.layer(options)), effect_Layer.provide(require_InMemoryDataStorage.layerDefault), effect_Layer.provide(require_NoAuth.layerDefault));
117
+ /**
118
+ * Create the document manager layer.
119
+ */
120
+ const documentManagerLayer = (options) => require_DocumentManager.layer.pipe(effect_Layer.provide(require_MimicConfig.layer(options)), effect_Layer.provide(require_InMemoryDataStorage.layerDefault), effect_Layer.provide(require_NoAuth.layerDefault));
121
+ /**
122
+ * Run a Mimic WebSocket server with the provided handler.
123
+ *
124
+ * This is a helper that:
125
+ * 1. Gets the WebSocket handler from context
126
+ * 2. Runs the socket server with the handler
127
+ *
128
+ * Note: The document ID extraction from socket is implementation-specific.
129
+ * You may need to customize this based on your socket server.
130
+ */
131
+ const run = (extractDocumentId$1) => effect_Effect.gen(function* () {
132
+ const handler = yield* MimicWebSocketHandler;
133
+ yield* (yield* _effect_platform_SocketServer.SocketServer).run((socket) => effect_Effect.gen(function* () {
134
+ yield* handler(socket, yield* extractDocumentId$1(socket));
135
+ }).pipe(effect_Effect.catchAll((error) => effect_Effect.logError("Connection error", error))));
136
+ });
137
+ /**
138
+ * Create the HTTP handler effect for WebSocket upgrade.
139
+ * This handler:
140
+ * 1. Extracts the document ID from the URL path
141
+ * 2. Upgrades the HTTP connection to WebSocket
142
+ * 3. Delegates to the WebSocketHandler for document sync
143
+ */
144
+ const makeMimicHandler = effect_Effect.gen(function* () {
145
+ const config = yield* require_MimicConfig.MimicServerConfigTag;
146
+ const authService = yield* require_MimicAuthService.MimicAuthServiceTag;
147
+ const documentManager = yield* require_DocumentManager.DocumentManagerTag;
148
+ const presenceManager = yield* require_PresenceManager.PresenceManagerTag;
149
+ return effect_Effect.gen(function* () {
150
+ const request = yield* _effect_platform.HttpServerRequest.HttpServerRequest;
151
+ yield* require_WebSocketHandler.extractDocumentId(request.url);
152
+ const socket = yield* request.upgrade;
153
+ yield* require_WebSocketHandler.handleConnection(socket, request.url).pipe(effect_Effect.provideService(require_MimicConfig.MimicServerConfigTag, config), effect_Effect.provideService(require_MimicAuthService.MimicAuthServiceTag, authService), effect_Effect.provideService(require_DocumentManager.DocumentManagerTag, documentManager), effect_Effect.provideService(require_PresenceManager.PresenceManagerTag, presenceManager), effect_Effect.scoped, effect_Effect.catchAll((error) => effect_Effect.logError("WebSocket connection error", error)));
154
+ return _effect_platform.HttpServerResponse.empty();
155
+ }).pipe(effect_Effect.catchAll((error) => effect_Effect.gen(function* () {
156
+ yield* effect_Effect.logWarning("WebSocket upgrade failed", error);
157
+ return _effect_platform.HttpServerResponse.text("WebSocket upgrade failed", { status: 400 });
158
+ })));
159
+ });
160
+ /**
161
+ * Create a Mimic server layer that integrates with HttpLayerRouter.
162
+ *
163
+ * This function creates a layer that:
164
+ * 1. Registers a WebSocket route at the specified base path
165
+ * 2. Handles WebSocket upgrades for document sync
166
+ * 3. Provides all required dependencies (config, auth, storage, document manager)
167
+ *
168
+ * By default, uses in-memory storage and no authentication.
169
+ * To override these defaults, provide custom layers before the defaults:
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
174
+ * import { HttpLayerRouter } from "@effect/platform";
175
+ * import { Primitive } from "@voidhash/mimic";
176
+ *
177
+ * const TodoSchema = Primitive.Struct({
178
+ * title: Primitive.String(),
179
+ * completed: Primitive.Boolean(),
180
+ * });
181
+ *
182
+ * // Create the Mimic route layer with defaults
183
+ * const MimicRoute = MimicServer.layerHttpLayerRouter({
184
+ * basePath: "/mimic/todo",
185
+ * schema: TodoSchema
186
+ * });
187
+ *
188
+ * // Or with custom auth - use Layer.provide to inject before defaults
189
+ * const MimicRouteWithAuth = MimicServer.layerHttpLayerRouter({
190
+ * basePath: "/mimic/todo",
191
+ * schema: TodoSchema,
192
+ * authLayer: MimicAuthService.layer({
193
+ * authHandler: (token) => ({ success: true, userId: token })
194
+ * })
195
+ * });
196
+ *
197
+ * // Merge with other routes and serve
198
+ * const AllRoutes = Layer.mergeAll(MimicRoute, OtherRoutes);
199
+ * HttpLayerRouter.serve(AllRoutes).pipe(
200
+ * Layer.provide(BunHttpServer.layer({ port: 3000 })),
201
+ * Layer.launch,
202
+ * BunRuntime.runMain
203
+ * );
204
+ * ```
205
+ */
206
+ const layerHttpLayerRouter = (options) => {
207
+ var _options$basePath, _options$authLayer, _options$storageLayer;
208
+ const wsPath = `${(_options$basePath = options.basePath) !== null && _options$basePath !== void 0 ? _options$basePath : "/mimic"}/doc/*`;
209
+ const configLayer = require_MimicConfig.layer({
210
+ schema: options.schema,
211
+ maxTransactionHistory: options.maxTransactionHistory,
212
+ presence: options.presence
213
+ });
214
+ const authLayer = (_options$authLayer = options.authLayer) !== null && _options$authLayer !== void 0 ? _options$authLayer : require_NoAuth.layerDefault;
215
+ const storageLayer = (_options$storageLayer = options.storageLayer) !== null && _options$storageLayer !== void 0 ? _options$storageLayer : require_InMemoryDataStorage.layerDefault;
216
+ const registerRoute = effect_Effect.gen(function* () {
217
+ const router = yield* _effect_platform.HttpLayerRouter.HttpRouter;
218
+ const handler = yield* makeMimicHandler;
219
+ yield* router.add("GET", wsPath, handler);
220
+ });
221
+ return effect_Layer.scopedDiscard(registerRoute).pipe(effect_Layer.provide(require_DocumentManager.layer), effect_Layer.provide(require_PresenceManager.layer), effect_Layer.provide(configLayer), effect_Layer.provide(storageLayer), effect_Layer.provide(authLayer));
222
+ };
223
+
224
+ //#endregion
225
+ Object.defineProperty(exports, 'MimicServer_exports', {
226
+ enumerable: true,
227
+ get: function () {
228
+ return MimicServer_exports;
229
+ }
230
+ });
@@ -0,0 +1,192 @@
1
+ import { MimicServerConfigOptions } from "./MimicConfig.cjs";
2
+ import { MimicDataStorageTag } from "./MimicDataStorage.cjs";
3
+ import { DocumentManagerTag } from "./DocumentManager.cjs";
4
+ import { MimicAuthServiceTag } from "./MimicAuthService.cjs";
5
+ import * as _effect_platform_SocketServer0 from "@effect/platform/SocketServer";
6
+ import { SocketServer } from "@effect/platform/SocketServer";
7
+ import * as Effect from "effect/Effect";
8
+ import * as Layer from "effect/Layer";
9
+ import * as Context from "effect/Context";
10
+ import * as Socket from "@effect/platform/Socket";
11
+ import { Presence, Primitive } from "@voidhash/mimic";
12
+ import { HttpLayerRouter } from "@effect/platform";
13
+ import { PathInput } from "@effect/platform/HttpRouter";
14
+
15
+ //#region src/MimicServer.d.ts
16
+ declare namespace MimicServer_d_exports {
17
+ export { MimicLayerOptions, MimicWebSocketHandler, documentManagerLayer, handlerLayer, layer, layerHttpLayerRouter, run };
18
+ }
19
+ declare const MimicWebSocketHandler_base: Context.TagClass<MimicWebSocketHandler, "@voidhash/mimic-server-effect/MimicWebSocketHandler", (socket: Socket.Socket, documentId: string) => Effect.Effect<void, unknown>>;
20
+ /**
21
+ * Tag for the WebSocket handler function.
22
+ */
23
+ declare class MimicWebSocketHandler extends MimicWebSocketHandler_base {}
24
+ /**
25
+ * Options for creating a Mimic server layer.
26
+ */
27
+ interface MimicLayerOptions<TSchema extends Primitive.AnyPrimitive> {
28
+ /**
29
+ * Base path for document routes (used for path matching).
30
+ * @example "/mimic/todo" - documents accessed at "/mimic/todo/:documentId"
31
+ */
32
+ readonly basePath?: PathInput;
33
+ /**
34
+ * The schema defining the document structure.
35
+ */
36
+ readonly schema: TSchema;
37
+ /**
38
+ * Maximum number of processed transaction IDs to track for deduplication.
39
+ * @default 1000
40
+ */
41
+ readonly maxTransactionHistory?: number;
42
+ /**
43
+ * Optional presence schema for ephemeral per-user data.
44
+ * When provided, enables presence features on WebSocket connections.
45
+ */
46
+ readonly presence?: Presence.AnyPresence;
47
+ }
48
+ /**
49
+ * Create a Mimic WebSocket handler layer.
50
+ *
51
+ * This layer provides a handler function that can be used with any WebSocket server
52
+ * implementation. The handler takes a socket and document ID and manages the
53
+ * document synchronization.
54
+ *
55
+ * By default, uses in-memory storage and no authentication.
56
+ * Override these by providing MimicDataStorage and MimicAuthService layers.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
61
+ * import { Primitive } from "@voidhash/mimic";
62
+ *
63
+ * const TodoSchema = Primitive.Struct({
64
+ * title: Primitive.String(),
65
+ * completed: Primitive.Boolean(),
66
+ * });
67
+ *
68
+ * // Create the handler layer with defaults
69
+ * const HandlerLayer = MimicServer.layer({
70
+ * basePath: "/mimic/todo",
71
+ * schema: TodoSchema
72
+ * });
73
+ *
74
+ * // Or with custom auth
75
+ * const HandlerLayerWithAuth = MimicServer.layer({
76
+ * basePath: "/mimic/todo",
77
+ * schema: TodoSchema
78
+ * }).pipe(
79
+ * Layer.provideMerge(MimicAuthService.layer({
80
+ * authHandler: (token) => ({ success: true, userId: "user-123" })
81
+ * }))
82
+ * );
83
+ * ```
84
+ */
85
+ declare const layer: <TSchema extends Primitive.AnyPrimitive>(options: MimicLayerOptions<TSchema>) => Layer.Layer<MimicWebSocketHandler | DocumentManagerTag>;
86
+ /**
87
+ * Create the Mimic server handler layer.
88
+ * This layer provides the WebSocket handler that can be used with any WebSocket server.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { MimicServer } from "@voidhash/mimic-server-effect";
93
+ * import { SocketServer } from "@effect/platform/SocketServer";
94
+ * import { Primitive } from "@voidhash/mimic";
95
+ *
96
+ * // Define your document schema
97
+ * const TodoSchema = Primitive.Struct({
98
+ * title: Primitive.String(),
99
+ * completed: Primitive.Boolean(),
100
+ * });
101
+ *
102
+ * // Create the server layer
103
+ * const serverLayer = MimicServer.handlerLayer({
104
+ * schema: TodoSchema,
105
+ * });
106
+ *
107
+ * // Run with your socket server
108
+ * Effect.gen(function* () {
109
+ * const handler = yield* MimicServer.MimicWebSocketHandler;
110
+ * const server = yield* SocketServer;
111
+ *
112
+ * yield* server.run((socket) =>
113
+ * // Extract document ID from request and call handler
114
+ * handler(socket, "my-document-id")
115
+ * );
116
+ * }).pipe(
117
+ * Effect.provide(serverLayer),
118
+ * Effect.provide(YourSocketServerLayer),
119
+ * );
120
+ * ```
121
+ */
122
+ declare const handlerLayer: <TSchema extends Primitive.AnyPrimitive>(options: MimicServerConfigOptions<TSchema>) => Layer.Layer<MimicWebSocketHandler>;
123
+ /**
124
+ * Create the document manager layer.
125
+ */
126
+ declare const documentManagerLayer: <TSchema extends Primitive.AnyPrimitive>(options: MimicServerConfigOptions<TSchema>) => Layer.Layer<DocumentManagerTag>;
127
+ /**
128
+ * Run a Mimic WebSocket server with the provided handler.
129
+ *
130
+ * This is a helper that:
131
+ * 1. Gets the WebSocket handler from context
132
+ * 2. Runs the socket server with the handler
133
+ *
134
+ * Note: The document ID extraction from socket is implementation-specific.
135
+ * You may need to customize this based on your socket server.
136
+ */
137
+ declare const run: (extractDocumentId: (socket: Socket.Socket) => Effect.Effect<string>) => Effect.Effect<void, _effect_platform_SocketServer0.SocketServerError, MimicWebSocketHandler | SocketServer>;
138
+ /**
139
+ * Create a Mimic server layer that integrates with HttpLayerRouter.
140
+ *
141
+ * This function creates a layer that:
142
+ * 1. Registers a WebSocket route at the specified base path
143
+ * 2. Handles WebSocket upgrades for document sync
144
+ * 3. Provides all required dependencies (config, auth, storage, document manager)
145
+ *
146
+ * By default, uses in-memory storage and no authentication.
147
+ * To override these defaults, provide custom layers before the defaults:
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
152
+ * import { HttpLayerRouter } from "@effect/platform";
153
+ * import { Primitive } from "@voidhash/mimic";
154
+ *
155
+ * const TodoSchema = Primitive.Struct({
156
+ * title: Primitive.String(),
157
+ * completed: Primitive.Boolean(),
158
+ * });
159
+ *
160
+ * // Create the Mimic route layer with defaults
161
+ * const MimicRoute = MimicServer.layerHttpLayerRouter({
162
+ * basePath: "/mimic/todo",
163
+ * schema: TodoSchema
164
+ * });
165
+ *
166
+ * // Or with custom auth - use Layer.provide to inject before defaults
167
+ * const MimicRouteWithAuth = MimicServer.layerHttpLayerRouter({
168
+ * basePath: "/mimic/todo",
169
+ * schema: TodoSchema,
170
+ * authLayer: MimicAuthService.layer({
171
+ * authHandler: (token) => ({ success: true, userId: token })
172
+ * })
173
+ * });
174
+ *
175
+ * // Merge with other routes and serve
176
+ * const AllRoutes = Layer.mergeAll(MimicRoute, OtherRoutes);
177
+ * HttpLayerRouter.serve(AllRoutes).pipe(
178
+ * Layer.provide(BunHttpServer.layer({ port: 3000 })),
179
+ * Layer.launch,
180
+ * BunRuntime.runMain
181
+ * );
182
+ * ```
183
+ */
184
+ declare const layerHttpLayerRouter: <TSchema extends Primitive.AnyPrimitive>(options: MimicLayerOptions<TSchema> & {
185
+ /** Custom auth layer. Defaults to NoAuth (all connections allowed). */
186
+ readonly authLayer?: Layer.Layer<MimicAuthServiceTag>;
187
+ /** Custom storage layer. Defaults to InMemoryDataStorage. */
188
+ readonly storageLayer?: Layer.Layer<MimicDataStorageTag>;
189
+ }) => Layer.Layer<never, never, HttpLayerRouter.HttpRouter>;
190
+ //#endregion
191
+ export { MimicServer_d_exports };
192
+ //# sourceMappingURL=MimicServer.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MimicServer.d.cts","names":[],"sources":["../src/MimicServer.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;cAoBwD,oIAa7C,MAAA,CAAO,+BAA+B,MAAA,CAAO;;;;cAJ3C,qBAAA,SAA8B,0BAAA;;;;AATa,UAuBvC,iBAV4D,CAAA,gBAU1B,SAAA,CAAU,YAVgB,CAAA,CAAA;;;;;sBAevD;EAnBT;AAcb;;EAKsB,SAAA,MAAA,EAIH,OAJG;EAIH;;;AAsDnB;EAAsC,SAAU,qBAAA,CAAA,EAAA,MAAA;EACnB;;;;EAC1B,SAAM,QAAA,CAAA,EA9Ca,QAAA,CAAS,WA8CtB;;AA2DT;;;;;;;AAeA;;;;;;;AAwBA;;;;;;;;AAqHA;;;;;;;;;;;;;;;cAzNa,wBAAyB,SAAA,CAAU,uBACrC,kBAAkB,aAC1B,KAAA,CAAM,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2D1B,+BAAgC,SAAA,CAAU,uBAC5C,yBAAqC,aAC7C,KAAA,CAAM,MAAM;;;;cAaF,uCAAwC,SAAA,CAAU,uBACpD,yBAAqC,aAC7C,KAAA,CAAM,MAAM;;;;;;;;;;;cAsBF,kCACiB,MAAA,CAAO,WAAW,MAAA,CAAO,mBAAc,MAAA,CAAA,aAAR,8BAAA,CAAQ,iBAAA,EAAA,wBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoHxD,uCAAwC,SAAA,CAAU,uBACpD,kBAAkB;;uBAEJ,KAAA,CAAM,MAAM;;0BAET,KAAA,CAAM,MAAM;MACrC,KAAA,CAAA,oBAAA,eAAA,CAAA"}
@@ -0,0 +1,192 @@
1
+ import { MimicServerConfigOptions } from "./MimicConfig.mjs";
2
+ import { MimicDataStorageTag } from "./MimicDataStorage.mjs";
3
+ import { DocumentManagerTag } from "./DocumentManager.mjs";
4
+ import { MimicAuthServiceTag } from "./MimicAuthService.mjs";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Layer from "effect/Layer";
7
+ import * as Context from "effect/Context";
8
+ import * as _effect_platform_SocketServer0 from "@effect/platform/SocketServer";
9
+ import { SocketServer } from "@effect/platform/SocketServer";
10
+ import { Presence, Primitive } from "@voidhash/mimic";
11
+ import { HttpLayerRouter } from "@effect/platform";
12
+ import * as Socket from "@effect/platform/Socket";
13
+ import { PathInput } from "@effect/platform/HttpRouter";
14
+
15
+ //#region src/MimicServer.d.ts
16
+ declare namespace MimicServer_d_exports {
17
+ export { MimicLayerOptions, MimicWebSocketHandler, documentManagerLayer, handlerLayer, layer, layerHttpLayerRouter, run };
18
+ }
19
+ declare const MimicWebSocketHandler_base: Context.TagClass<MimicWebSocketHandler, "@voidhash/mimic-server-effect/MimicWebSocketHandler", (socket: Socket.Socket, documentId: string) => Effect.Effect<void, unknown>>;
20
+ /**
21
+ * Tag for the WebSocket handler function.
22
+ */
23
+ declare class MimicWebSocketHandler extends MimicWebSocketHandler_base {}
24
+ /**
25
+ * Options for creating a Mimic server layer.
26
+ */
27
+ interface MimicLayerOptions<TSchema extends Primitive.AnyPrimitive> {
28
+ /**
29
+ * Base path for document routes (used for path matching).
30
+ * @example "/mimic/todo" - documents accessed at "/mimic/todo/:documentId"
31
+ */
32
+ readonly basePath?: PathInput;
33
+ /**
34
+ * The schema defining the document structure.
35
+ */
36
+ readonly schema: TSchema;
37
+ /**
38
+ * Maximum number of processed transaction IDs to track for deduplication.
39
+ * @default 1000
40
+ */
41
+ readonly maxTransactionHistory?: number;
42
+ /**
43
+ * Optional presence schema for ephemeral per-user data.
44
+ * When provided, enables presence features on WebSocket connections.
45
+ */
46
+ readonly presence?: Presence.AnyPresence;
47
+ }
48
+ /**
49
+ * Create a Mimic WebSocket handler layer.
50
+ *
51
+ * This layer provides a handler function that can be used with any WebSocket server
52
+ * implementation. The handler takes a socket and document ID and manages the
53
+ * document synchronization.
54
+ *
55
+ * By default, uses in-memory storage and no authentication.
56
+ * Override these by providing MimicDataStorage and MimicAuthService layers.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
61
+ * import { Primitive } from "@voidhash/mimic";
62
+ *
63
+ * const TodoSchema = Primitive.Struct({
64
+ * title: Primitive.String(),
65
+ * completed: Primitive.Boolean(),
66
+ * });
67
+ *
68
+ * // Create the handler layer with defaults
69
+ * const HandlerLayer = MimicServer.layer({
70
+ * basePath: "/mimic/todo",
71
+ * schema: TodoSchema
72
+ * });
73
+ *
74
+ * // Or with custom auth
75
+ * const HandlerLayerWithAuth = MimicServer.layer({
76
+ * basePath: "/mimic/todo",
77
+ * schema: TodoSchema
78
+ * }).pipe(
79
+ * Layer.provideMerge(MimicAuthService.layer({
80
+ * authHandler: (token) => ({ success: true, userId: "user-123" })
81
+ * }))
82
+ * );
83
+ * ```
84
+ */
85
+ declare const layer: <TSchema extends Primitive.AnyPrimitive>(options: MimicLayerOptions<TSchema>) => Layer.Layer<MimicWebSocketHandler | DocumentManagerTag>;
86
+ /**
87
+ * Create the Mimic server handler layer.
88
+ * This layer provides the WebSocket handler that can be used with any WebSocket server.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { MimicServer } from "@voidhash/mimic-server-effect";
93
+ * import { SocketServer } from "@effect/platform/SocketServer";
94
+ * import { Primitive } from "@voidhash/mimic";
95
+ *
96
+ * // Define your document schema
97
+ * const TodoSchema = Primitive.Struct({
98
+ * title: Primitive.String(),
99
+ * completed: Primitive.Boolean(),
100
+ * });
101
+ *
102
+ * // Create the server layer
103
+ * const serverLayer = MimicServer.handlerLayer({
104
+ * schema: TodoSchema,
105
+ * });
106
+ *
107
+ * // Run with your socket server
108
+ * Effect.gen(function* () {
109
+ * const handler = yield* MimicServer.MimicWebSocketHandler;
110
+ * const server = yield* SocketServer;
111
+ *
112
+ * yield* server.run((socket) =>
113
+ * // Extract document ID from request and call handler
114
+ * handler(socket, "my-document-id")
115
+ * );
116
+ * }).pipe(
117
+ * Effect.provide(serverLayer),
118
+ * Effect.provide(YourSocketServerLayer),
119
+ * );
120
+ * ```
121
+ */
122
+ declare const handlerLayer: <TSchema extends Primitive.AnyPrimitive>(options: MimicServerConfigOptions<TSchema>) => Layer.Layer<MimicWebSocketHandler>;
123
+ /**
124
+ * Create the document manager layer.
125
+ */
126
+ declare const documentManagerLayer: <TSchema extends Primitive.AnyPrimitive>(options: MimicServerConfigOptions<TSchema>) => Layer.Layer<DocumentManagerTag>;
127
+ /**
128
+ * Run a Mimic WebSocket server with the provided handler.
129
+ *
130
+ * This is a helper that:
131
+ * 1. Gets the WebSocket handler from context
132
+ * 2. Runs the socket server with the handler
133
+ *
134
+ * Note: The document ID extraction from socket is implementation-specific.
135
+ * You may need to customize this based on your socket server.
136
+ */
137
+ declare const run: (extractDocumentId: (socket: Socket.Socket) => Effect.Effect<string>) => Effect.Effect<void, _effect_platform_SocketServer0.SocketServerError, MimicWebSocketHandler | SocketServer>;
138
+ /**
139
+ * Create a Mimic server layer that integrates with HttpLayerRouter.
140
+ *
141
+ * This function creates a layer that:
142
+ * 1. Registers a WebSocket route at the specified base path
143
+ * 2. Handles WebSocket upgrades for document sync
144
+ * 3. Provides all required dependencies (config, auth, storage, document manager)
145
+ *
146
+ * By default, uses in-memory storage and no authentication.
147
+ * To override these defaults, provide custom layers before the defaults:
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * import { MimicServer, MimicAuthService } from "@voidhash/mimic-effect";
152
+ * import { HttpLayerRouter } from "@effect/platform";
153
+ * import { Primitive } from "@voidhash/mimic";
154
+ *
155
+ * const TodoSchema = Primitive.Struct({
156
+ * title: Primitive.String(),
157
+ * completed: Primitive.Boolean(),
158
+ * });
159
+ *
160
+ * // Create the Mimic route layer with defaults
161
+ * const MimicRoute = MimicServer.layerHttpLayerRouter({
162
+ * basePath: "/mimic/todo",
163
+ * schema: TodoSchema
164
+ * });
165
+ *
166
+ * // Or with custom auth - use Layer.provide to inject before defaults
167
+ * const MimicRouteWithAuth = MimicServer.layerHttpLayerRouter({
168
+ * basePath: "/mimic/todo",
169
+ * schema: TodoSchema,
170
+ * authLayer: MimicAuthService.layer({
171
+ * authHandler: (token) => ({ success: true, userId: token })
172
+ * })
173
+ * });
174
+ *
175
+ * // Merge with other routes and serve
176
+ * const AllRoutes = Layer.mergeAll(MimicRoute, OtherRoutes);
177
+ * HttpLayerRouter.serve(AllRoutes).pipe(
178
+ * Layer.provide(BunHttpServer.layer({ port: 3000 })),
179
+ * Layer.launch,
180
+ * BunRuntime.runMain
181
+ * );
182
+ * ```
183
+ */
184
+ declare const layerHttpLayerRouter: <TSchema extends Primitive.AnyPrimitive>(options: MimicLayerOptions<TSchema> & {
185
+ /** Custom auth layer. Defaults to NoAuth (all connections allowed). */
186
+ readonly authLayer?: Layer.Layer<MimicAuthServiceTag>;
187
+ /** Custom storage layer. Defaults to InMemoryDataStorage. */
188
+ readonly storageLayer?: Layer.Layer<MimicDataStorageTag>;
189
+ }) => Layer.Layer<never, never, HttpLayerRouter.HttpRouter>;
190
+ //#endregion
191
+ export { MimicServer_d_exports };
192
+ //# sourceMappingURL=MimicServer.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MimicServer.d.mts","names":[],"sources":["../src/MimicServer.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;cAoBwD,oIAa7C,MAAA,CAAO,+BAA+B,MAAA,CAAO;;;;cAJ3C,qBAAA,SAA8B,0BAAA;;;;AATa,UAuBvC,iBAV4D,CAAA,gBAU1B,SAAA,CAAU,YAVgB,CAAA,CAAA;;;;;sBAevD;EAnBT;AAcb;;EAKsB,SAAA,MAAA,EAIH,OAJG;EAIH;;;AAsDnB;EAAsC,SAAU,qBAAA,CAAA,EAAA,MAAA;EACnB;;;;EAC1B,SAAM,QAAA,CAAA,EA9Ca,QAAA,CAAS,WA8CtB;;AA2DT;;;;;;;AAeA;;;;;;;AAwBA;;;;;;;;AAqHA;;;;;;;;;;;;;;;cAzNa,wBAAyB,SAAA,CAAU,uBACrC,kBAAkB,aAC1B,KAAA,CAAM,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2D1B,+BAAgC,SAAA,CAAU,uBAC5C,yBAAqC,aAC7C,KAAA,CAAM,MAAM;;;;cAaF,uCAAwC,SAAA,CAAU,uBACpD,yBAAqC,aAC7C,KAAA,CAAM,MAAM;;;;;;;;;;;cAsBF,kCACiB,MAAA,CAAO,WAAW,MAAA,CAAO,mBAAc,MAAA,CAAA,aAAR,8BAAA,CAAQ,iBAAA,EAAA,wBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoHxD,uCAAwC,SAAA,CAAU,uBACpD,kBAAkB;;uBAEJ,KAAA,CAAM,MAAM;;0BAET,KAAA,CAAM,MAAM;MACrC,KAAA,CAAA,oBAAA,eAAA,CAAA"}