diff --git a/packages/evolu/src/DbWorker.ts b/packages/evolu/src/DbWorker.ts index b80902b67..c23653297 100644 --- a/packages/evolu/src/DbWorker.ts +++ b/packages/evolu/src/DbWorker.ts @@ -32,7 +32,6 @@ import { merkleTreeToString, unsafeMerkleTreeFromString, } from "./MerkleTree.js"; -import { Message, NewMessage } from "./Message.js"; import { CastableForMutate, Id, SqliteDate, cast } from "./Model.js"; import { OnCompleteId } from "./OnCompletes.js"; import { RowsCacheRef, RowsCacheRefLive } from "./RowsCache.js"; @@ -47,6 +46,8 @@ import { } from "./Sql.js"; import { Query, Sqlite, Value, queryObjectFromQuery } from "./Sqlite.js"; import { + Message, + NewMessage, SyncState, SyncWorker, SyncWorkerOutputSyncResponse, diff --git a/packages/evolu/src/DbWorker.worker.ts b/packages/evolu/src/DbWorker.worker.ts index 924915045..615687fb8 100644 --- a/packages/evolu/src/DbWorker.worker.ts +++ b/packages/evolu/src/DbWorker.worker.ts @@ -7,7 +7,9 @@ const dbWorker = DbWorker.pipe( Effect.runSync, ); -dbWorker.onMessage = (output): void => postMessage(output); +dbWorker.onMessage = (output): void => { + postMessage(output); +}; onmessage = (e: MessageEvent): void => { dbWorker.postMessage(e.data); diff --git a/packages/evolu/src/DbWorkerLive.web.ts b/packages/evolu/src/DbWorkerLive.web.ts index fec4a7027..cae45f92e 100644 --- a/packages/evolu/src/DbWorkerLive.web.ts +++ b/packages/evolu/src/DbWorkerLive.web.ts @@ -1,4 +1,4 @@ -import { Layer } from "effect"; +import { Effect, Function, Layer } from "effect"; import { Slip21Live } from "./Crypto.js"; import { Bip39Live, @@ -8,7 +8,27 @@ import { } from "./CryptoLive.web.js"; import { DbWorkerLive } from "./DbWorker.js"; import { SqliteLive } from "./SqliteLive.web.js"; -import { SyncWorkerLive } from "./SyncWorkerLive.web.js"; +import { SyncWorker, SyncWorkerOutput } from "./SyncWorker.js"; + +const SyncWorkerLive = Layer.effect( + SyncWorker, + Effect.sync(() => { + const worker = new Worker( + new URL("SyncWorker.worker.js", import.meta.url), + { type: "module" }, + ); + worker.onmessage = (e: MessageEvent): void => { + syncWorker.onMessage(e.data); + }; + const syncWorker: SyncWorker = { + postMessage: (input) => { + worker.postMessage(input); + }, + onMessage: Function.constVoid, + }; + return syncWorker; + }), +); // It's a separate file because it's imported dynamically or by WebWorker. export const dbWorkerLive = Layer.mergeAll( diff --git a/packages/evolu/src/Message.ts b/packages/evolu/src/Message.ts deleted file mode 100644 index 958621c2e..000000000 --- a/packages/evolu/src/Message.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Id } from "./Model.js"; -import { Value } from "./Sqlite.js"; -import { TimestampString } from "./Timestamp.js"; - -export interface NewMessage { - readonly table: string; - readonly row: Id; - readonly column: string; - readonly value: Value; -} - -export interface Message extends NewMessage { - readonly timestamp: TimestampString; -} diff --git a/packages/evolu/src/SyncWorker.ts b/packages/evolu/src/SyncWorker.ts index 4c7fbe10e..9850c381c 100644 --- a/packages/evolu/src/SyncWorker.ts +++ b/packages/evolu/src/SyncWorker.ts @@ -9,7 +9,6 @@ import { merkleTreeToString, unsafeMerkleTreeFromString, } from "./MerkleTree.js"; -import { Message } from "./Message.js"; import { Id } from "./Model.js"; import { Fetch, SyncLock } from "./Platform.js"; import { FetchLive } from "./Platform.web.js"; @@ -49,6 +48,17 @@ interface SyncWorkerInputSync { readonly syncLoopCount: number; } +export interface NewMessage { + readonly table: string; + readonly row: Id; + readonly column: string; + readonly value: Value; +} + +export interface Message extends NewMessage { + readonly timestamp: TimestampString; +} + interface SyncWorkerInputSyncCompleted { readonly _tag: "syncCompleted"; } diff --git a/packages/evolu/src/SyncWorkerLive.web.worker.ts b/packages/evolu/src/SyncWorker.worker.ts similarity index 50% rename from packages/evolu/src/SyncWorkerLive.web.worker.ts rename to packages/evolu/src/SyncWorker.worker.ts index 05e20dfd8..eae1acf11 100644 --- a/packages/evolu/src/SyncWorkerLive.web.worker.ts +++ b/packages/evolu/src/SyncWorker.worker.ts @@ -1,16 +1,16 @@ import { Effect, Layer } from "effect"; -import { SyncWorker, SyncWorkerInput, SyncWorkerLive } from "./SyncWorker.js"; import { SyncLockLive } from "./Platform.web.js"; +import { SyncWorker, SyncWorkerInput, SyncWorkerLive } from "./SyncWorker.js"; -Effect.gen(function* (_) { - const syncWorker = yield* _(SyncWorker); - syncWorker.onMessage = (output): void => { - postMessage(output); - }; - onmessage = (e: MessageEvent): void => { - syncWorker.postMessage(e.data); - }; -}).pipe( +const syncWorker = SyncWorker.pipe( Effect.provideLayer(SyncLockLive.pipe(Layer.provide(SyncWorkerLive))), Effect.runSync, ); + +syncWorker.onMessage = (output): void => { + postMessage(output); +}; + +onmessage = (e: MessageEvent): void => { + syncWorker.postMessage(e.data); +}; diff --git a/packages/evolu/src/SyncWorkerLive.web.ts b/packages/evolu/src/SyncWorkerLive.web.ts deleted file mode 100644 index fd88fd0ce..000000000 --- a/packages/evolu/src/SyncWorkerLive.web.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Effect, Function, Layer } from "effect"; -import { SyncWorker, SyncWorkerOutput } from "./SyncWorker.js"; - -export const SyncWorkerLive = Layer.effect( - SyncWorker, - Effect.sync(() => { - const worker = new Worker( - new URL("SyncWorkerLive.web.worker.js", import.meta.url), - { type: "module" }, - ); - - worker.onmessage = (e: MessageEvent): void => { - syncWorker.onMessage(e.data); - }; - - const syncWorker: SyncWorker = { - postMessage: (input) => { - worker.postMessage(input); - }, - onMessage: Function.constVoid, - }; - - return syncWorker; - }), -); diff --git a/packages/evolu/src/index.ts b/packages/evolu/src/index.ts index 53c5b050b..50be85372 100644 --- a/packages/evolu/src/index.ts +++ b/packages/evolu/src/index.ts @@ -19,63 +19,57 @@ import { SubscribedQueriesLive } from "./SubscribedQueries.js"; import { TimeLive } from "./Timestamp.js"; export * from "./exports.js"; -const NoOpDbWorker = Effect.sync(() => - DbWorker.of({ - postMessage: Function.constVoid, - onMessage: Function.constVoid, - }), -); - -const OpfsDbWorker = Effect.sync(() => { - const worker = new Worker(new URL("DbWorker.worker.js", import.meta.url), { - type: "module", - }); - worker.onmessage = (e: MessageEvent): void => { - dbWorker.onMessage(e.data); - }; - const dbWorker: DbWorker = { - postMessage: (input) => { - worker.postMessage(input); - }, - onMessage: Function.constVoid, - }; - return dbWorker; -}); - -const LocalStorageDbWorker = Effect.sync(() => { - const promise = Effect.promise(() => import("./DbWorkerLive.web.js")).pipe( - Effect.map((a) => { - const importedDbWorker = DbWorker.pipe( - Effect.provideLayer(a.dbWorkerLive), - Effect.runSync, - ); - importedDbWorker.onMessage = dbWorker.onMessage; - return importedDbWorker.postMessage; - }), - Effect.runPromise, - ); - const dbWorker: DbWorker = { - postMessage: (input) => { - void promise.then((postMessage) => { - postMessage(input); - }); - }, - onMessage: Function.constVoid, - }; - return dbWorker; -}); - const DbWorkerLive = Layer.effect( DbWorker, Effect.gen(function* (_) { const platform = yield* _(Platform); - return yield* _( - platform.name === "server" - ? NoOpDbWorker - : platform.name === "web-with-opfs" - ? OpfsDbWorker - : LocalStorageDbWorker, - ); + + if (platform.name === "web-with-opfs") { + const worker = new Worker( + new URL("DbWorker.worker.js", import.meta.url), + { type: "module" }, + ); + worker.onmessage = (e: MessageEvent): void => { + dbWorker.onMessage(e.data); + }; + const dbWorker: DbWorker = { + postMessage: (input) => { + worker.postMessage(input); + }, + onMessage: Function.constVoid, + }; + return dbWorker; + } + + if (platform.name === "web-without-opfs") { + const promise = Effect.promise( + () => import("./DbWorkerLive.web.js"), + ).pipe( + Effect.map((a) => { + const importedDbWorker = DbWorker.pipe( + Effect.provideLayer(a.dbWorkerLive), + Effect.runSync, + ); + importedDbWorker.onMessage = dbWorker.onMessage; + return importedDbWorker.postMessage; + }), + Effect.runPromise, + ); + const dbWorker: DbWorker = { + postMessage: (input) => { + void promise.then((postMessage) => { + postMessage(input); + }); + }, + onMessage: Function.constVoid, + }; + return dbWorker; + } + + return DbWorker.of({ + postMessage: Function.constVoid, + onMessage: Function.constVoid, + }); }), );