@livestore/adapter-web 0.0.0-snapshot-2b8a9de3ec1a701aca891ebc2c98eb328274ae9e → 0.0.0-snapshot-2ef046b02334f52613d31dbe06af53487685edc0

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.
@@ -1,4 +1,4 @@
1
- import type { Adapter, ClientSession, LockStatus, NetworkStatus } from '@livestore/common'
1
+ import type { Adapter, ClientSession, LockStatus } from '@livestore/common'
2
2
  import { Devtools, IntentionalShutdownCause, StoreInterrupted, UnexpectedError } from '@livestore/common'
3
3
  // TODO bring back - this currently doesn't work due to https://github.com/vitejs/vite/issues/8427
4
4
  // NOTE We're using a non-relative import here for Vite to properly resolve the import during app builds
@@ -91,6 +91,15 @@ export type WebAdapterOptions = {
91
91
  * store it in `sessionStorage` and restore it for subsequent client sessions in the same tab/window.
92
92
  */
93
93
  sessionId?: string
94
+ experimental?: {
95
+ /**
96
+ * When set to `true`, the adapter will always start with a snapshot from the leader
97
+ * instead of trying to load a snapshot from storage.
98
+ *
99
+ * @default false
100
+ */
101
+ disableFastPath?: boolean
102
+ }
94
103
  }
95
104
 
96
105
  export const makePersistedAdapter =
@@ -130,7 +139,10 @@ export const makePersistedAdapter =
130
139
  // we usually speeds up the boot process by a lot.
131
140
  // We need to be extra careful though to not run into any race conditions or inconsistencies.
132
141
  // TODO also verify persisted data
133
- const dataFromFile = yield* readPersistedAppDbFromClientSession({ storageOptions, storeId, schema })
142
+ const dataFromFile =
143
+ options.experimental?.disableFastPath === true
144
+ ? undefined
145
+ : yield* readPersistedAppDbFromClientSession({ storageOptions, storeId, schema })
134
146
 
135
147
  // The same across all client sessions (i.e. tabs, windows)
136
148
  const clientId = options.clientId ?? getPersistedId(`clientId:${storeId}`, 'local')
@@ -193,7 +205,7 @@ export const makePersistedAdapter =
193
205
 
194
206
  const runLocked = Effect.gen(function* () {
195
207
  yield* Effect.logDebug(
196
- `[@livestore/adapter-web:client-session] ✅ Got lock '${LIVESTORE_TAB_LOCK}' (clientId: ${clientId}, sessionId: ${sessionId})`,
208
+ `[@livestore/adapter-web:client-session] ✅ Got lock '${LIVESTORE_TAB_LOCK}' (clientId: ${clientId}, sessionId: ${sessionId}).`,
197
209
  )
198
210
 
199
211
  yield* Effect.addFinalizer(() =>
@@ -230,29 +242,6 @@ export const makePersistedAdapter =
230
242
 
231
243
  yield* Deferred.succeed(waitForSharedWorkerInitialized, undefined)
232
244
 
233
- yield* Effect.addFinalizer(() =>
234
- Effect.gen(function* () {
235
- // console.log('[@livestore/adapter-web:client-session] Shutting down leader worker')
236
- // We first try to gracefully shutdown the leader worker and then forcefully terminate it
237
- // yield* Effect.raceFirst(
238
- // sharedWorker
239
- // .executeEffect(new WorkerSchema.LeaderWorkerInner.Shutdown({}))
240
- // .pipe(Effect.andThen(() => worker.terminate())),
241
- // Effect.sync(() => {
242
- // console.warn(
243
- // '[@livestore/adapter-web:client-session] Worker did not gracefully shutdown in time, terminating it',
244
- // )
245
- // worker.terminate()
246
- // }).pipe(
247
- // // Seems like we still need to wait a bit for the worker to terminate
248
- // // TODO improve this implementation (possibly via another weblock?)
249
- // Effect.delay(1000),
250
- // ),
251
- // )
252
- // yield* Effect.logDebug('[@livestore/adapter-web:client-session] client-session shutdown. worker terminated')
253
- }).pipe(Effect.withSpan('@livestore/adapter-web:client-session:lock:shutdown'), Effect.ignoreLogged),
254
- )
255
-
256
245
  yield* Effect.never
257
246
  }).pipe(Effect.withSpan('@livestore/adapter-web:client-session:lock'))
258
247
 
@@ -322,22 +311,6 @@ export const makePersistedAdapter =
322
311
  )
323
312
  }).pipe(Stream.unwrap) as any
324
313
 
325
- const networkStatus = yield* SubscriptionRef.make<NetworkStatus>({
326
- isConnected: false,
327
- timestampMs: Date.now(),
328
- latchClosed: false,
329
- })
330
-
331
- yield* runInWorkerStream(new WorkerSchema.LeaderWorkerInner.NetworkStatusStream()).pipe(
332
- Stream.tap((_) => SubscriptionRef.set(networkStatus, _)),
333
- Stream.runDrain,
334
- Effect.forever, // NOTE Whenever the leader changes, we need to re-start the stream
335
- Effect.tapErrorCause((cause) => Effect.sync(() => shutdown(cause))),
336
- Effect.interruptible,
337
- Effect.tapCauseLogPretty,
338
- Effect.forkScoped,
339
- )
340
-
341
314
  const bootStatusFiber = yield* runInWorkerStream(new WorkerSchema.LeaderWorkerInner.BootStatusStream()).pipe(
342
315
  Stream.tap((_) => Queue.offer(bootStatusQueue, _)),
343
316
  Stream.runDrain,
@@ -461,8 +434,6 @@ export const makePersistedAdapter =
461
434
  Effect.withSpan('@livestore/adapter-web:client-session:getLeaderSyncState'),
462
435
  ),
463
436
 
464
- networkStatus,
465
-
466
437
  sendDevtoolsMessage: (message) =>
467
438
  runInWorker(new WorkerSchema.LeaderWorkerInner.ExtraDevtoolsMessage({ message })).pipe(
468
439
  UnexpectedError.mapToUnexpectedError,
@@ -1,12 +1,4 @@
1
- import {
2
- BootStatus,
3
- Devtools,
4
- LeaderAheadError,
5
- MigrationsReport,
6
- NetworkStatus,
7
- SyncState,
8
- UnexpectedError,
9
- } from '@livestore/common'
1
+ import { BootStatus, Devtools, LeaderAheadError, MigrationsReport, SyncState, UnexpectedError } from '@livestore/common'
10
2
  import { EventId, MutationEvent } from '@livestore/common/schema'
11
3
  import * as WebmeshWorker from '@livestore/devtools-web-common/worker'
12
4
  import { Schema, Transferable } from '@livestore/utils/effect'
@@ -84,11 +76,11 @@ export namespace LeaderWorkerInner {
84
76
 
85
77
  export class PullStream extends Schema.TaggedRequest<PullStream>()('PullStream', {
86
78
  payload: {
87
- cursor: EventId.EventId,
79
+ cursor: Schema.Number,
88
80
  },
89
81
  success: Schema.Struct({
90
82
  payload: SyncState.PayloadUpstream,
91
- remaining: Schema.Number,
83
+ mergeCounter: Schema.Number,
92
84
  }),
93
85
  failure: UnexpectedError,
94
86
  }) {}
@@ -126,12 +118,6 @@ export namespace LeaderWorkerInner {
126
118
  failure: UnexpectedError,
127
119
  }) {}
128
120
 
129
- export class NetworkStatusStream extends Schema.TaggedRequest<NetworkStatusStream>()('NetworkStatusStream', {
130
- payload: {},
131
- success: NetworkStatus,
132
- failure: UnexpectedError,
133
- }) {}
134
-
135
121
  export class Shutdown extends Schema.TaggedRequest<Shutdown>()('Shutdown', {
136
122
  payload: {},
137
123
  success: Schema.Void,
@@ -156,7 +142,6 @@ export namespace LeaderWorkerInner {
156
142
  GetRecreateSnapshot,
157
143
  GetLeaderHead,
158
144
  GetLeaderSyncState,
159
- NetworkStatusStream,
160
145
  Shutdown,
161
146
  ExtraDevtoolsMessage,
162
147
  WebmeshWorker.Schema.CreateConnection,
@@ -198,7 +183,6 @@ export namespace SharedWorker {
198
183
  LeaderWorkerInner.ExportMutationlog,
199
184
  LeaderWorkerInner.GetLeaderHead,
200
185
  LeaderWorkerInner.GetLeaderSyncState,
201
- LeaderWorkerInner.NetworkStatusStream,
202
186
  LeaderWorkerInner.Shutdown,
203
187
  LeaderWorkerInner.ExtraDevtoolsMessage,
204
188
 
@@ -1,11 +1,11 @@
1
- import type { NetworkStatus, SqliteDb, SyncOptions } from '@livestore/common'
1
+ import type { SqliteDb, SyncOptions } from '@livestore/common'
2
2
  import { Devtools, UnexpectedError } from '@livestore/common'
3
3
  import type { DevtoolsOptions } from '@livestore/common/leader-thread'
4
4
  import {
5
5
  configureConnection,
6
- getClientHeadFromDb,
7
6
  LeaderThreadCtx,
8
7
  makeLeaderThreadLayer,
8
+ Mutationlog,
9
9
  } from '@livestore/common/leader-thread'
10
10
  import type { LiveStoreSchema } from '@livestore/common/schema'
11
11
  import { MutationEvent } from '@livestore/common/schema'
@@ -175,9 +175,8 @@ const makeWorkerRunnerInner = ({ schema, sync: syncOptions }: WorkerOptions) =>
175
175
  ),
176
176
  PullStream: ({ cursor }) =>
177
177
  Effect.gen(function* () {
178
- const { connectedClientSessionPullQueues } = yield* LeaderThreadCtx
179
- const pullQueue = yield* connectedClientSessionPullQueues.makeQueue(cursor)
180
- return Stream.fromQueue(pullQueue)
178
+ const { syncProcessor } = yield* LeaderThreadCtx
179
+ return syncProcessor.pull({ cursor })
181
180
  }).pipe(
182
181
  Stream.unwrapScoped,
183
182
  // For debugging purposes
@@ -206,7 +205,7 @@ const makeWorkerRunnerInner = ({ schema, sync: syncOptions }: WorkerOptions) =>
206
205
  GetLeaderHead: () =>
207
206
  Effect.gen(function* () {
208
207
  const workerCtx = yield* LeaderThreadCtx
209
- return getClientHeadFromDb(workerCtx.dbMutationLog)
208
+ return Mutationlog.getClientHeadFromDb(workerCtx.dbMutationLog)
210
209
  }).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/adapter-web:worker:GetLeaderHead')),
211
210
  GetLeaderSyncState: () =>
212
211
  Effect.gen(function* () {
@@ -216,19 +215,6 @@ const makeWorkerRunnerInner = ({ schema, sync: syncOptions }: WorkerOptions) =>
216
215
  UnexpectedError.mapToUnexpectedError,
217
216
  Effect.withSpan('@livestore/adapter-web:worker:GetLeaderSyncState'),
218
217
  ),
219
- NetworkStatusStream: () =>
220
- Effect.gen(function* (_) {
221
- const ctx = yield* LeaderThreadCtx
222
-
223
- if (ctx.syncBackend === undefined) {
224
- return Stream.make<[NetworkStatus]>({ isConnected: false, timestampMs: Date.now(), latchClosed: false })
225
- }
226
-
227
- return Stream.zipLatest(
228
- ctx.syncBackend.isConnected.changes,
229
- ctx.devtools.enabled ? ctx.devtools.syncBackendLatchState.changes : Stream.make({ latchClosed: false }),
230
- ).pipe(Stream.map(([isConnected, { latchClosed }]) => ({ isConnected, timestampMs: Date.now(), latchClosed })))
231
- }).pipe(Stream.unwrap),
232
218
  Shutdown: () =>
233
219
  Effect.gen(function* () {
234
220
  yield* Effect.logDebug('[@livestore/adapter-web:worker] Shutdown')
@@ -230,7 +230,6 @@ const makeWorkerRunner = Effect.gen(function* () {
230
230
  Setup: forwardRequest,
231
231
  GetLeaderSyncState: forwardRequest,
232
232
  GetLeaderHead: forwardRequest,
233
- NetworkStatusStream: forwardRequestStream,
234
233
  Shutdown: forwardRequest,
235
234
  ExtraDevtoolsMessage: forwardRequest,
236
235