@livestore/adapter-web 0.4.0-dev.10 → 0.4.0-dev.11
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/in-memory/in-memory-adapter.d.ts.map +1 -1
- package/dist/in-memory/in-memory-adapter.js +3 -5
- package/dist/in-memory/in-memory-adapter.js.map +1 -1
- package/dist/web-worker/client-session/persisted-adapter.d.ts.map +1 -1
- package/dist/web-worker/client-session/persisted-adapter.js +6 -5
- package/dist/web-worker/client-session/persisted-adapter.js.map +1 -1
- package/dist/web-worker/client-session/sqlite-loader.d.ts +2 -0
- package/dist/web-worker/client-session/sqlite-loader.d.ts.map +1 -0
- package/dist/web-worker/client-session/sqlite-loader.js +16 -0
- package/dist/web-worker/client-session/sqlite-loader.js.map +1 -0
- package/dist/web-worker/common/worker-schema.d.ts +11 -6
- package/dist/web-worker/common/worker-schema.d.ts.map +1 -1
- package/dist/web-worker/common/worker-schema.js +8 -2
- package/dist/web-worker/common/worker-schema.js.map +1 -1
- package/dist/web-worker/leader-worker/make-leader-worker.js +4 -0
- package/dist/web-worker/leader-worker/make-leader-worker.js.map +1 -1
- package/dist/web-worker/shared-worker/make-shared-worker.d.ts.map +1 -1
- package/dist/web-worker/shared-worker/make-shared-worker.js +6 -2
- package/dist/web-worker/shared-worker/make-shared-worker.js.map +1 -1
- package/package.json +6 -6
- package/src/in-memory/in-memory-adapter.ts +3 -6
- package/src/web-worker/ambient.d.ts +7 -4
- package/src/web-worker/client-session/persisted-adapter.ts +9 -9
- package/src/web-worker/client-session/sqlite-loader.ts +19 -0
- package/src/web-worker/common/worker-schema.ts +11 -0
- package/src/web-worker/leader-worker/make-leader-worker.ts +5 -0
- package/src/web-worker/shared-worker/make-shared-worker.ts +31 -13
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
// import LiveStoreSharedWorker from '@livestore/adapter-web/internal-shared-worker?sharedworker'
|
|
13
13
|
import { EventSequenceNumber } from '@livestore/common/schema'
|
|
14
14
|
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser'
|
|
15
|
-
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
16
15
|
import { isDevEnv, shouldNeverHappen, tryAsFunctionAndNew } from '@livestore/utils'
|
|
17
16
|
import {
|
|
18
17
|
BrowserWorker,
|
|
@@ -40,9 +39,7 @@ import { makeShutdownChannel } from '../common/shutdown-channel.ts'
|
|
|
40
39
|
import { DedicatedWorkerDisconnectBroadcast, makeWorkerDisconnectChannel } from '../common/worker-disconnect-channel.ts'
|
|
41
40
|
import * as WorkerSchema from '../common/worker-schema.ts'
|
|
42
41
|
import { connectWebmeshNodeClientSession } from './client-session-devtools.ts'
|
|
43
|
-
|
|
44
|
-
// NOTE we're starting to initialize the sqlite wasm binary here to speed things up
|
|
45
|
-
const sqlite3Promise = loadSqlite3Wasm()
|
|
42
|
+
import { loadSqlite3 } from './sqlite-loader.ts'
|
|
46
43
|
|
|
47
44
|
if (isDevEnv()) {
|
|
48
45
|
globalThis.__debugLiveStoreUtils = {
|
|
@@ -147,7 +144,7 @@ export const makePersistedAdapter =
|
|
|
147
144
|
|
|
148
145
|
yield* Queue.offer(bootStatusQueue, { stage: 'loading' })
|
|
149
146
|
|
|
150
|
-
const sqlite3 = yield* Effect.promise(() =>
|
|
147
|
+
const sqlite3 = yield* Effect.promise(() => loadSqlite3())
|
|
151
148
|
|
|
152
149
|
const LIVESTORE_TAB_LOCK = `livestore-tab-lock-${storeId}`
|
|
153
150
|
const LIVESTORE_SHARED_WORKER_TERMINATION_LOCK = `livestore-shared-worker-termination-lock-${storeId}`
|
|
@@ -463,10 +460,13 @@ export const makePersistedAdapter =
|
|
|
463
460
|
Effect.withSpan('@livestore/adapter-web:client-session:getEventlogData'),
|
|
464
461
|
),
|
|
465
462
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
463
|
+
syncState: Subscribable.make({
|
|
464
|
+
get: runInWorker(new WorkerSchema.LeaderWorkerInnerGetLeaderSyncState()).pipe(
|
|
465
|
+
UnexpectedError.mapToUnexpectedError,
|
|
466
|
+
Effect.withSpan('@livestore/adapter-web:client-session:getLeaderSyncState'),
|
|
467
|
+
),
|
|
468
|
+
changes: runInWorkerStream(new WorkerSchema.LeaderWorkerInnerSyncStateStream()).pipe(Stream.orDie),
|
|
469
|
+
}),
|
|
470
470
|
|
|
471
471
|
sendDevtoolsMessage: (message) =>
|
|
472
472
|
runInWorker(new WorkerSchema.LeaderWorkerInnerExtraDevtoolsMessage({ message })).pipe(
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Browser sessions benefit from downloading and compiling the wasm binary as soon as
|
|
5
|
+
* possible to hide network and IO latency behind the rest of the boot process. We kick
|
|
6
|
+
* that work off eagerly on the client while still returning the shared promise.
|
|
7
|
+
*
|
|
8
|
+
* The Cloudflare / Workerd runtime has stricter rules: async fetches during module
|
|
9
|
+
* evaluation are blocked, so we defer loading until the worker asks for it.
|
|
10
|
+
*/
|
|
11
|
+
const isServerRuntime = String(import.meta.env.SSR) === 'true'
|
|
12
|
+
|
|
13
|
+
let sqlite3Promise: ReturnType<typeof loadSqlite3Wasm> | undefined
|
|
14
|
+
|
|
15
|
+
if (isServerRuntime === false) {
|
|
16
|
+
sqlite3Promise = loadSqlite3Wasm()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const loadSqlite3 = () => (isServerRuntime ? loadSqlite3Wasm() : (sqlite3Promise ?? loadSqlite3Wasm()))
|
|
@@ -147,6 +147,15 @@ export class LeaderWorkerInnerGetLeaderSyncState extends Schema.TaggedRequest<Le
|
|
|
147
147
|
},
|
|
148
148
|
) {}
|
|
149
149
|
|
|
150
|
+
export class LeaderWorkerInnerSyncStateStream extends Schema.TaggedRequest<LeaderWorkerInnerSyncStateStream>()(
|
|
151
|
+
'SyncStateStream',
|
|
152
|
+
{
|
|
153
|
+
payload: {},
|
|
154
|
+
success: SyncState.SyncState,
|
|
155
|
+
failure: UnexpectedError,
|
|
156
|
+
},
|
|
157
|
+
) {}
|
|
158
|
+
|
|
150
159
|
export class LeaderWorkerInnerGetNetworkStatus extends Schema.TaggedRequest<LeaderWorkerInnerGetNetworkStatus>()(
|
|
151
160
|
'GetNetworkStatus',
|
|
152
161
|
{
|
|
@@ -192,6 +201,7 @@ export const LeaderWorkerInnerRequest = Schema.Union(
|
|
|
192
201
|
LeaderWorkerInnerGetRecreateSnapshot,
|
|
193
202
|
LeaderWorkerInnerGetLeaderHead,
|
|
194
203
|
LeaderWorkerInnerGetLeaderSyncState,
|
|
204
|
+
LeaderWorkerInnerSyncStateStream,
|
|
195
205
|
LeaderWorkerInnerGetNetworkStatus,
|
|
196
206
|
LeaderWorkerInnerNetworkStatusStream,
|
|
197
207
|
LeaderWorkerInnerShutdown,
|
|
@@ -239,6 +249,7 @@ export class SharedWorkerRequest extends Schema.Union(
|
|
|
239
249
|
LeaderWorkerInnerExportEventlog,
|
|
240
250
|
LeaderWorkerInnerGetLeaderHead,
|
|
241
251
|
LeaderWorkerInnerGetLeaderSyncState,
|
|
252
|
+
LeaderWorkerInnerSyncStateStream,
|
|
242
253
|
LeaderWorkerInnerGetNetworkStatus,
|
|
243
254
|
LeaderWorkerInnerNetworkStatusStream,
|
|
244
255
|
LeaderWorkerInnerShutdown,
|
|
@@ -222,6 +222,11 @@ const makeWorkerRunnerInner = ({ schema, sync: syncOptions }: WorkerOptions) =>
|
|
|
222
222
|
UnexpectedError.mapToUnexpectedError,
|
|
223
223
|
Effect.withSpan('@livestore/adapter-web:worker:GetLeaderSyncState'),
|
|
224
224
|
),
|
|
225
|
+
SyncStateStream: () =>
|
|
226
|
+
Effect.gen(function* () {
|
|
227
|
+
const workerCtx = yield* LeaderThreadCtx
|
|
228
|
+
return workerCtx.syncProcessor.syncState.changes
|
|
229
|
+
}).pipe(Stream.unwrapScoped),
|
|
225
230
|
GetNetworkStatus: () =>
|
|
226
231
|
Effect.gen(function* () {
|
|
227
232
|
const workerCtx = yield* LeaderThreadCtx
|
|
@@ -70,12 +70,15 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
70
70
|
|
|
71
71
|
const forwardRequest = <TReq extends WorkerSchema.LeaderWorkerInnerRequest>(
|
|
72
72
|
req: TReq,
|
|
73
|
-
):
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
): Effect.Effect<
|
|
74
|
+
Schema.WithResult.Success<TReq>,
|
|
75
|
+
UnexpectedError | Schema.WithResult.Failure<TReq>,
|
|
76
|
+
Schema.WithResult.Context<TReq>
|
|
77
|
+
> =>
|
|
78
|
+
// Forward the request to the active worker and normalize platform errors into UnexpectedError.
|
|
76
79
|
waitForWorker.pipe(
|
|
77
80
|
// Effect.logBefore(`forwardRequest: ${req._tag}`),
|
|
78
|
-
Effect.andThen((worker) => worker.executeEffect(req) as Effect.Effect<unknown, unknown,
|
|
81
|
+
Effect.andThen((worker) => worker.executeEffect(req) as Effect.Effect<unknown, unknown, unknown>),
|
|
79
82
|
// Effect.tap((_) => Effect.log(`forwardRequest: ${req._tag}`, _)),
|
|
80
83
|
// Effect.tapError((cause) => Effect.logError(`forwardRequest err: ${req._tag}`, cause)),
|
|
81
84
|
Effect.interruptible,
|
|
@@ -92,17 +95,23 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
92
95
|
),
|
|
93
96
|
Effect.catchAllDefect((cause) => new UnexpectedError({ cause })),
|
|
94
97
|
Effect.tapCauseLogPretty,
|
|
95
|
-
) as
|
|
98
|
+
) as Effect.Effect<
|
|
99
|
+
Schema.WithResult.Success<TReq>,
|
|
100
|
+
UnexpectedError | Schema.WithResult.Failure<TReq>,
|
|
101
|
+
Schema.WithResult.Context<TReq>
|
|
102
|
+
>
|
|
96
103
|
|
|
97
104
|
const forwardRequestStream = <TReq extends WorkerSchema.LeaderWorkerInnerRequest>(
|
|
98
105
|
req: TReq,
|
|
99
|
-
):
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
): Stream.Stream<
|
|
107
|
+
Schema.WithResult.Success<TReq>,
|
|
108
|
+
UnexpectedError | Schema.WithResult.Failure<TReq>,
|
|
109
|
+
Schema.WithResult.Context<TReq>
|
|
110
|
+
> =>
|
|
102
111
|
Effect.gen(function* () {
|
|
103
112
|
yield* Effect.logDebug(`forwardRequestStream: ${req._tag}`)
|
|
104
113
|
const { worker, scope } = yield* SubscriptionRef.waitUntil(leaderWorkerContextSubRef, isNotUndefined)
|
|
105
|
-
const stream = worker.execute(req) as Stream.Stream<unknown, unknown,
|
|
114
|
+
const stream = worker.execute(req) as Stream.Stream<unknown, unknown, unknown>
|
|
106
115
|
|
|
107
116
|
// It seems the request stream is not automatically interrupted when the scope shuts down
|
|
108
117
|
// so we need to manually interrupt it when the scope shuts down
|
|
@@ -123,7 +132,11 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
123
132
|
Stream.unwrap,
|
|
124
133
|
Stream.ensuring(Effect.logDebug(`shutting down stream for ${req._tag}`)),
|
|
125
134
|
UnexpectedError.mapToUnexpectedErrorStream,
|
|
126
|
-
) as
|
|
135
|
+
) as Stream.Stream<
|
|
136
|
+
Schema.WithResult.Success<TReq>,
|
|
137
|
+
UnexpectedError | Schema.WithResult.Failure<TReq>,
|
|
138
|
+
Schema.WithResult.Context<TReq>
|
|
139
|
+
>
|
|
127
140
|
|
|
128
141
|
const resetCurrentWorkerCtx = Effect.gen(function* () {
|
|
129
142
|
const prevWorker = yield* SubscriptionRef.get(leaderWorkerContextSubRef)
|
|
@@ -245,6 +258,7 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
245
258
|
ExportEventlog: forwardRequest,
|
|
246
259
|
Setup: forwardRequest,
|
|
247
260
|
GetLeaderSyncState: forwardRequest,
|
|
261
|
+
SyncStateStream: forwardRequestStream,
|
|
248
262
|
GetLeaderHead: forwardRequest,
|
|
249
263
|
GetNetworkStatus: forwardRequest,
|
|
250
264
|
NetworkStatusStream: forwardRequestStream,
|
|
@@ -257,6 +271,12 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
257
271
|
}).pipe(Layer.unwrapScoped)
|
|
258
272
|
|
|
259
273
|
export const makeWorker = () => {
|
|
274
|
+
const layer = Layer.mergeAll(
|
|
275
|
+
Logger.prettyWithThread(self.name),
|
|
276
|
+
FetchHttpClient.layer,
|
|
277
|
+
WebmeshWorker.CacheService.layer({ nodeName: DevtoolsWeb.makeNodeName.sharedWorker({ storeId }) }),
|
|
278
|
+
)
|
|
279
|
+
|
|
260
280
|
makeWorkerRunner.pipe(
|
|
261
281
|
Layer.provide(BrowserWorkerRunner.layer),
|
|
262
282
|
// WorkerRunner.launch,
|
|
@@ -264,9 +284,7 @@ export const makeWorker = () => {
|
|
|
264
284
|
Effect.scoped,
|
|
265
285
|
Effect.tapCauseLogPretty,
|
|
266
286
|
Effect.annotateLogs({ thread: self.name }),
|
|
267
|
-
Effect.provide(
|
|
268
|
-
Effect.provide(FetchHttpClient.layer),
|
|
269
|
-
Effect.provide(WebmeshWorker.CacheService.layer({ nodeName: DevtoolsWeb.makeNodeName.sharedWorker({ storeId }) })),
|
|
287
|
+
Effect.provide(layer),
|
|
270
288
|
LS_DEV ? TaskTracing.withAsyncTaggingTracing((name) => (console as any).createTask(name)) : identity,
|
|
271
289
|
// TODO remove type-cast (currently needed to silence a tsc bug)
|
|
272
290
|
(_) => _ as any as Effect.Effect<void, any>,
|