@livestore/adapter-web 0.3.0-dev.36 → 0.3.0-dev.38
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/web-worker/client-session/client-session-devtools.d.ts +3 -3
- package/dist/web-worker/client-session/client-session-devtools.d.ts.map +1 -1
- package/dist/web-worker/client-session/client-session-devtools.js +2 -2
- package/dist/web-worker/client-session/client-session-devtools.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 +50 -78
- package/dist/web-worker/client-session/persisted-adapter.js.map +1 -1
- package/dist/web-worker/leader-worker/make-leader-worker.d.ts.map +1 -1
- package/dist/web-worker/leader-worker/make-leader-worker.js +6 -13
- 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 +10 -4
- package/dist/web-worker/shared-worker/make-shared-worker.js.map +1 -1
- package/package.json +6 -6
- package/src/web-worker/client-session/client-session-devtools.ts +5 -4
- package/src/web-worker/client-session/persisted-adapter.ts +96 -135
- package/src/web-worker/leader-worker/make-leader-worker.ts +10 -13
- package/src/web-worker/shared-worker/make-shared-worker.ts +11 -7
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { Adapter, ClientSession, LockStatus } from '@livestore/common'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Devtools,
|
|
4
|
+
IntentionalShutdownCause,
|
|
5
|
+
makeClientSession,
|
|
6
|
+
StoreInterrupted,
|
|
7
|
+
UnexpectedError,
|
|
8
|
+
} from '@livestore/common'
|
|
3
9
|
// TODO bring back - this currently doesn't work due to https://github.com/vitejs/vite/issues/8427
|
|
4
10
|
// NOTE We're using a non-relative import here for Vite to properly resolve the import during app builds
|
|
5
11
|
// import LiveStoreSharedWorker from '@livestore/adapter-web/internal-shared-worker?sharedworker'
|
|
6
12
|
import { EventId, SystemTables } from '@livestore/common/schema'
|
|
7
|
-
import
|
|
8
|
-
ClientSessionRequestContentscriptMain,
|
|
9
|
-
connectViaWorker,
|
|
10
|
-
makeChannelForConnectedMeshNode,
|
|
11
|
-
makeSessionsChannel,
|
|
12
|
-
} from '@livestore/devtools-web-common/web-channel'
|
|
13
|
+
import * as DevtoolsWeb from '@livestore/devtools-web-common/web-channel'
|
|
13
14
|
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser'
|
|
14
15
|
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
15
16
|
import { isDevEnv, shouldNeverHappen, tryAsFunctionAndNew } from '@livestore/utils'
|
|
@@ -104,17 +105,10 @@ export type WebAdapterOptions = {
|
|
|
104
105
|
|
|
105
106
|
export const makePersistedAdapter =
|
|
106
107
|
(options: WebAdapterOptions): Adapter =>
|
|
107
|
-
(
|
|
108
|
-
schema,
|
|
109
|
-
storeId,
|
|
110
|
-
devtoolsEnabled,
|
|
111
|
-
debugInstanceId,
|
|
112
|
-
bootStatusQueue,
|
|
113
|
-
shutdown,
|
|
114
|
-
connectDevtoolsToStore,
|
|
115
|
-
syncPayload,
|
|
116
|
-
}) =>
|
|
108
|
+
(adapterArgs) =>
|
|
117
109
|
Effect.gen(function* () {
|
|
110
|
+
const { schema, storeId, devtoolsEnabled, debugInstanceId, bootStatusQueue, shutdown, syncPayload } = adapterArgs
|
|
111
|
+
|
|
118
112
|
yield* ensureBrowserRequirements
|
|
119
113
|
|
|
120
114
|
yield* Queue.offer(bootStatusQueue, { stage: 'loading' })
|
|
@@ -392,135 +386,102 @@ export const makePersistedAdapter =
|
|
|
392
386
|
}).pipe(Effect.tapCauseLogPretty, Effect.orDie),
|
|
393
387
|
)
|
|
394
388
|
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
devtools,
|
|
402
|
-
lockStatus,
|
|
403
|
-
clientId,
|
|
404
|
-
sessionId,
|
|
405
|
-
|
|
406
|
-
leaderThread: {
|
|
407
|
-
export: runInWorker(new WorkerSchema.LeaderWorkerInner.Export()).pipe(
|
|
408
|
-
Effect.timeout(10_000),
|
|
409
|
-
UnexpectedError.mapToUnexpectedError,
|
|
410
|
-
Effect.withSpan('@livestore/adapter-web:client-session:export'),
|
|
411
|
-
),
|
|
412
|
-
|
|
413
|
-
events: {
|
|
414
|
-
pull: ({ cursor }) =>
|
|
415
|
-
runInWorkerStream(new WorkerSchema.LeaderWorkerInner.PullStream({ cursor })).pipe(Stream.orDie),
|
|
416
|
-
push: (batch) =>
|
|
417
|
-
runInWorker(new WorkerSchema.LeaderWorkerInner.PushToLeader({ batch })).pipe(
|
|
418
|
-
Effect.withSpan('@livestore/adapter-web:client-session:pushToLeader', {
|
|
419
|
-
attributes: { batchSize: batch.length },
|
|
420
|
-
}),
|
|
421
|
-
),
|
|
422
|
-
},
|
|
423
|
-
|
|
424
|
-
initialState: { leaderHead: initialLeaderHead, migrationsReport },
|
|
425
|
-
|
|
426
|
-
getEventlogData: runInWorker(new WorkerSchema.LeaderWorkerInner.ExportEventlog()).pipe(
|
|
427
|
-
Effect.timeout(10_000),
|
|
428
|
-
UnexpectedError.mapToUnexpectedError,
|
|
429
|
-
Effect.withSpan('@livestore/adapter-web:client-session:getEventlogData'),
|
|
430
|
-
),
|
|
431
|
-
|
|
432
|
-
getSyncState: runInWorker(new WorkerSchema.LeaderWorkerInner.GetLeaderSyncState()).pipe(
|
|
433
|
-
UnexpectedError.mapToUnexpectedError,
|
|
434
|
-
Effect.withSpan('@livestore/adapter-web:client-session:getLeaderSyncState'),
|
|
435
|
-
),
|
|
389
|
+
const leaderThread: ClientSession['leaderThread'] = {
|
|
390
|
+
export: runInWorker(new WorkerSchema.LeaderWorkerInner.Export()).pipe(
|
|
391
|
+
Effect.timeout(10_000),
|
|
392
|
+
UnexpectedError.mapToUnexpectedError,
|
|
393
|
+
Effect.withSpan('@livestore/adapter-web:client-session:export'),
|
|
394
|
+
),
|
|
436
395
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
396
|
+
events: {
|
|
397
|
+
pull: ({ cursor }) =>
|
|
398
|
+
runInWorkerStream(new WorkerSchema.LeaderWorkerInner.PullStream({ cursor })).pipe(Stream.orDie),
|
|
399
|
+
push: (batch) =>
|
|
400
|
+
runInWorker(new WorkerSchema.LeaderWorkerInner.PushToLeader({ batch })).pipe(
|
|
401
|
+
Effect.withSpan('@livestore/adapter-web:client-session:pushToLeader', {
|
|
402
|
+
attributes: { batchSize: batch.length },
|
|
403
|
+
}),
|
|
441
404
|
),
|
|
442
405
|
},
|
|
443
406
|
|
|
444
|
-
|
|
445
|
-
} satisfies ClientSession
|
|
446
|
-
|
|
447
|
-
if (devtoolsEnabled) {
|
|
448
|
-
yield* Effect.gen(function* () {
|
|
449
|
-
const sharedWorker = yield* Fiber.join(sharedWorkerFiber)
|
|
450
|
-
|
|
451
|
-
const webmeshNode = yield* Webmesh.makeMeshNode(`client-session-${storeId}-${clientId}-${sessionId}`)
|
|
452
|
-
globalThis.__debugWebmeshNode = webmeshNode
|
|
453
|
-
|
|
454
|
-
yield* logDevtoolsUrl({ clientSession, schema, storeId })
|
|
455
|
-
|
|
456
|
-
const sessionsChannel = yield* makeSessionsChannel
|
|
457
|
-
const sessionInfoMessage = Devtools.SessionInfo.SessionInfo.make({
|
|
458
|
-
storeId,
|
|
459
|
-
clientId,
|
|
460
|
-
sessionId,
|
|
461
|
-
schemaAlias: schema.devtools.alias,
|
|
462
|
-
})
|
|
463
|
-
|
|
464
|
-
yield* Devtools.SessionInfo.provideSessionInfo({
|
|
465
|
-
webChannel: sessionsChannel,
|
|
466
|
-
sessionInfo: sessionInfoMessage,
|
|
467
|
-
}).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
|
|
468
|
-
|
|
469
|
-
yield* Effect.gen(function* () {
|
|
470
|
-
const clientSessionStaticChannel = yield* WebChannel.windowChannel2({
|
|
471
|
-
listenWindow: window,
|
|
472
|
-
sendWindow: window,
|
|
473
|
-
schema: { listen: Schema.Void, send: ClientSessionRequestContentscriptMain },
|
|
474
|
-
ids: { own: 'client-session-static', other: 'contentscript-main-static' },
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
yield* clientSessionStaticChannel.send(
|
|
478
|
-
ClientSessionRequestContentscriptMain.make({ clientId, sessionId, storeId }),
|
|
479
|
-
)
|
|
407
|
+
initialState: { leaderHead: initialLeaderHead, migrationsReport },
|
|
480
408
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
schema: Webmesh.WebmeshSchema.Packet,
|
|
487
|
-
ids: { own: webmeshNode.nodeName, other: contentscriptMainNodeName },
|
|
488
|
-
})
|
|
409
|
+
getEventlogData: runInWorker(new WorkerSchema.LeaderWorkerInner.ExportEventlog()).pipe(
|
|
410
|
+
Effect.timeout(10_000),
|
|
411
|
+
UnexpectedError.mapToUnexpectedError,
|
|
412
|
+
Effect.withSpan('@livestore/adapter-web:client-session:getEventlogData'),
|
|
413
|
+
),
|
|
489
414
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
// yield* Effect.logDebug(
|
|
495
|
-
// `[@livestore/adapter-web:client-session] initiated connection: ${webmeshNode.nodeName} → contentscript-main`,
|
|
496
|
-
// )
|
|
415
|
+
getSyncState: runInWorker(new WorkerSchema.LeaderWorkerInner.GetLeaderSyncState()).pipe(
|
|
416
|
+
UnexpectedError.mapToUnexpectedError,
|
|
417
|
+
Effect.withSpan('@livestore/adapter-web:client-session:getLeaderSyncState'),
|
|
418
|
+
),
|
|
497
419
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
420
|
+
sendDevtoolsMessage: (message) =>
|
|
421
|
+
runInWorker(new WorkerSchema.LeaderWorkerInner.ExtraDevtoolsMessage({ message })).pipe(
|
|
422
|
+
UnexpectedError.mapToUnexpectedError,
|
|
423
|
+
Effect.withSpan('@livestore/adapter-web:client-session:devtoolsMessageForLeader'),
|
|
424
|
+
),
|
|
425
|
+
}
|
|
502
426
|
|
|
427
|
+
const clientSession = yield* makeClientSession({
|
|
428
|
+
...adapterArgs,
|
|
429
|
+
sqliteDb,
|
|
430
|
+
lockStatus,
|
|
431
|
+
clientId,
|
|
432
|
+
sessionId,
|
|
433
|
+
leaderThread,
|
|
434
|
+
webmeshMode: 'direct',
|
|
435
|
+
connectWebmeshNode: Effect.fn(function* ({ webmeshNode, sessionInfo }) {
|
|
436
|
+
if (devtoolsEnabled) {
|
|
437
|
+
yield* logDevtoolsUrl({ clientId, sessionId, schema, storeId })
|
|
438
|
+
|
|
439
|
+
// This additional sessioninfo broadcast channel is needed since we can't use the shared worker
|
|
440
|
+
// as it's currently storeId-specific
|
|
503
441
|
yield* Devtools.SessionInfo.provideSessionInfo({
|
|
504
|
-
webChannel:
|
|
505
|
-
sessionInfo
|
|
506
|
-
})
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
442
|
+
webChannel: yield* DevtoolsWeb.makeSessionInfoBroadcastChannel,
|
|
443
|
+
sessionInfo,
|
|
444
|
+
}).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
|
|
445
|
+
|
|
446
|
+
yield* Effect.gen(function* () {
|
|
447
|
+
const clientSessionStaticChannel = yield* DevtoolsWeb.makeStaticClientSessionChannel.clientSession
|
|
448
|
+
|
|
449
|
+
yield* clientSessionStaticChannel.send(
|
|
450
|
+
DevtoolsWeb.ClientSessionContentscriptMainReq.make({ clientId, sessionId, storeId }),
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
const { tabId } = yield* clientSessionStaticChannel.listen.pipe(
|
|
454
|
+
Stream.flatten(),
|
|
455
|
+
Stream.runHead,
|
|
456
|
+
Effect.flatten,
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
const contentscriptMainNodeName = DevtoolsWeb.makeNodeName.browserExtension.contentscriptMain(tabId)
|
|
460
|
+
|
|
461
|
+
const contentscriptMainChannel = yield* WebChannel.windowChannel({
|
|
462
|
+
listenWindow: window,
|
|
463
|
+
sendWindow: window,
|
|
464
|
+
schema: Webmesh.WebmeshSchema.Packet,
|
|
465
|
+
ids: { own: webmeshNode.nodeName, other: contentscriptMainNodeName },
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
yield* webmeshNode.addEdge({ target: contentscriptMainNodeName, edgeChannel: contentscriptMainChannel })
|
|
469
|
+
}).pipe(
|
|
470
|
+
Effect.withSpan('@livestore/adapter-web:client-session:devtools:browser-extension'),
|
|
471
|
+
Effect.tapCauseLogPretty,
|
|
472
|
+
Effect.forkScoped,
|
|
473
|
+
)
|
|
510
474
|
|
|
511
|
-
|
|
512
|
-
node: webmeshNode,
|
|
513
|
-
target: `devtools`,
|
|
514
|
-
schema: { listen: Devtools.ClientSession.MessageToApp, send: Devtools.ClientSession.MessageFromApp },
|
|
515
|
-
})
|
|
475
|
+
const sharedWorker = yield* Fiber.join(sharedWorkerFiber)
|
|
516
476
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
477
|
+
yield* DevtoolsWeb.connectViaWorker({
|
|
478
|
+
node: webmeshNode,
|
|
479
|
+
target: DevtoolsWeb.makeNodeName.sharedWorker({ storeId }),
|
|
480
|
+
worker: sharedWorker,
|
|
481
|
+
})
|
|
482
|
+
}
|
|
483
|
+
}),
|
|
484
|
+
})
|
|
524
485
|
|
|
525
486
|
return clientSession
|
|
526
487
|
}).pipe(UnexpectedError.mapToUnexpectedError)
|
|
@@ -4,7 +4,6 @@ import type { DevtoolsOptions } from '@livestore/common/leader-thread'
|
|
|
4
4
|
import { configureConnection, Eventlog, LeaderThreadCtx, makeLeaderThreadLayer } from '@livestore/common/leader-thread'
|
|
5
5
|
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
6
6
|
import { LiveStoreEvent } from '@livestore/common/schema'
|
|
7
|
-
import { makeChannelForConnectedMeshNode } from '@livestore/devtools-web-common/web-channel'
|
|
8
7
|
import * as WebmeshWorker from '@livestore/devtools-web-common/worker'
|
|
9
8
|
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser'
|
|
10
9
|
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
@@ -92,7 +91,9 @@ const makeWorkerRunnerOuter = (
|
|
|
92
91
|
Effect.scoped,
|
|
93
92
|
Effect.withSpan('@livestore/adapter-web:worker:wrapper:InitialMessage:innerFiber'),
|
|
94
93
|
Effect.tapCauseLogPretty,
|
|
95
|
-
Effect.provide(
|
|
94
|
+
Effect.provide(
|
|
95
|
+
WebmeshWorker.CacheService.layer({ nodeName: Devtools.makeNodeName.client.leader({ storeId, clientId }) }),
|
|
96
|
+
),
|
|
96
97
|
Effect.forkScoped,
|
|
97
98
|
)
|
|
98
99
|
|
|
@@ -239,22 +240,18 @@ const makeDevtoolsOptions = ({
|
|
|
239
240
|
if (devtoolsEnabled === false) {
|
|
240
241
|
return { enabled: false }
|
|
241
242
|
}
|
|
243
|
+
|
|
242
244
|
const { node } = yield* WebmeshWorker.CacheService
|
|
243
245
|
|
|
244
246
|
return {
|
|
245
247
|
enabled: true,
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
target: `devtools`,
|
|
251
|
-
schema: { listen: Devtools.Leader.MessageToApp, send: Devtools.Leader.MessageFromApp },
|
|
252
|
-
}),
|
|
253
|
-
persistenceInfo: {
|
|
254
|
-
state: dbState.metadata.persistenceInfo,
|
|
255
|
-
eventlog: dbEventlog.metadata.persistenceInfo,
|
|
256
|
-
},
|
|
248
|
+
boot: Effect.gen(function* () {
|
|
249
|
+
const persistenceInfo = {
|
|
250
|
+
state: dbState.metadata.persistenceInfo,
|
|
251
|
+
eventlog: dbEventlog.metadata.persistenceInfo,
|
|
257
252
|
}
|
|
253
|
+
|
|
254
|
+
return { node, persistenceInfo, mode: 'direct' }
|
|
258
255
|
}),
|
|
259
256
|
}
|
|
260
257
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { UnexpectedError } from '@livestore/common'
|
|
2
|
-
import
|
|
1
|
+
import { Devtools, UnexpectedError } from '@livestore/common'
|
|
2
|
+
import * as DevtoolsWeb from '@livestore/devtools-web-common/web-channel'
|
|
3
3
|
import * as WebmeshWorker from '@livestore/devtools-web-common/worker'
|
|
4
4
|
import { isDevEnv, isNotUndefined, LS_DEV } from '@livestore/utils'
|
|
5
5
|
import {
|
|
@@ -207,10 +207,11 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
207
207
|
const { node } = yield* WebmeshWorker.CacheService
|
|
208
208
|
const { storeId, clientId } = initialMessagePayload.initialMessage
|
|
209
209
|
|
|
210
|
-
yield* connectViaWorker({
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
yield* DevtoolsWeb.connectViaWorker({
|
|
211
|
+
node,
|
|
212
|
+
worker,
|
|
213
|
+
target: Devtools.makeNodeName.client.leader({ storeId, clientId }),
|
|
214
|
+
}).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
|
|
214
215
|
|
|
215
216
|
yield* SubscriptionRef.set(leaderWorkerContextSubRef, { worker, scope })
|
|
216
217
|
}).pipe(Effect.tapCauseLogPretty, Scope.extend(scope), Effect.forkIn(scope))
|
|
@@ -239,6 +240,9 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
239
240
|
}).pipe(Layer.unwrapScoped)
|
|
240
241
|
|
|
241
242
|
export const makeWorker = () => {
|
|
243
|
+
// Extract from `livestore-shared-worker-${storeId}`
|
|
244
|
+
const storeId = self.name.replace('livestore-shared-worker-', '')
|
|
245
|
+
|
|
242
246
|
makeWorkerRunner.pipe(
|
|
243
247
|
Layer.provide(BrowserWorkerRunner.layer),
|
|
244
248
|
// WorkerRunner.launch,
|
|
@@ -248,7 +252,7 @@ export const makeWorker = () => {
|
|
|
248
252
|
Effect.annotateLogs({ thread: self.name }),
|
|
249
253
|
Effect.provide(Logger.prettyWithThread(self.name)),
|
|
250
254
|
Effect.provide(FetchHttpClient.layer),
|
|
251
|
-
Effect.provide(WebmeshWorker.CacheService.layer({ nodeName:
|
|
255
|
+
Effect.provide(WebmeshWorker.CacheService.layer({ nodeName: DevtoolsWeb.makeNodeName.sharedWorker({ storeId }) })),
|
|
252
256
|
LS_DEV ? TaskTracing.withAsyncTaggingTracing((name) => (console as any).createTask(name)) : identity,
|
|
253
257
|
// TODO remove type-cast (currently needed to silence a tsc bug)
|
|
254
258
|
(_) => _ as any as Effect.Effect<void, any>,
|