@livestore/adapter-web 0.0.0-snapshot-04bc235dd721238cb10c060705672376b6e06dd3 → 0.0.0-snapshot-f695fd72a038f4deb7b452e82cb37999b5cc30b9
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 +45 -3
- package/dist/in-memory/in-memory-adapter.d.ts.map +1 -1
- package/dist/in-memory/in-memory-adapter.js +139 -36
- package/dist/in-memory/in-memory-adapter.js.map +1 -1
- package/dist/web-worker/client-session/client-session-devtools.d.ts +11 -0
- package/dist/web-worker/client-session/client-session-devtools.d.ts.map +1 -1
- package/dist/web-worker/client-session/client-session-devtools.js +34 -1
- 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 +28 -43
- package/dist/web-worker/client-session/persisted-adapter.js.map +1 -1
- package/dist/web-worker/common/worker-schema.d.ts +12 -11
- package/dist/web-worker/common/worker-schema.d.ts.map +1 -1
- package/dist/web-worker/common/worker-schema.js +6 -3
- package/dist/web-worker/common/worker-schema.js.map +1 -1
- package/package.json +7 -7
- package/src/in-memory/in-memory-adapter.ts +251 -39
- package/src/web-worker/client-session/client-session-devtools.ts +62 -1
- package/src/web-worker/client-session/persisted-adapter.ts +32 -69
- package/src/web-worker/common/worker-schema.ts +6 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Adapter, ClientSession, LockStatus } from '@livestore/common'
|
|
2
2
|
import {
|
|
3
|
-
Devtools,
|
|
4
3
|
IntentionalShutdownCause,
|
|
4
|
+
liveStoreVersion,
|
|
5
5
|
makeClientSession,
|
|
6
6
|
StoreInterrupted,
|
|
7
7
|
UnexpectedError,
|
|
@@ -9,8 +9,7 @@ import {
|
|
|
9
9
|
// TODO bring back - this currently doesn't work due to https://github.com/vitejs/vite/issues/8427
|
|
10
10
|
// NOTE We're using a non-relative import here for Vite to properly resolve the import during app builds
|
|
11
11
|
// import LiveStoreSharedWorker from '@livestore/adapter-web/internal-shared-worker?sharedworker'
|
|
12
|
-
import {
|
|
13
|
-
import * as DevtoolsWeb from '@livestore/devtools-web-common/web-channel'
|
|
12
|
+
import { EventSequenceNumber, SystemTables } from '@livestore/common/schema'
|
|
14
13
|
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser'
|
|
15
14
|
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
16
15
|
import { isDevEnv, shouldNeverHappen, tryAsFunctionAndNew } from '@livestore/utils'
|
|
@@ -26,20 +25,18 @@ import {
|
|
|
26
25
|
Schema,
|
|
27
26
|
Stream,
|
|
28
27
|
SubscriptionRef,
|
|
29
|
-
WebChannel,
|
|
30
28
|
WebLock,
|
|
31
29
|
Worker,
|
|
32
30
|
WorkerError,
|
|
33
31
|
} from '@livestore/utils/effect'
|
|
34
32
|
import { nanoid } from '@livestore/utils/nanoid'
|
|
35
|
-
import * as Webmesh from '@livestore/webmesh'
|
|
36
33
|
|
|
37
34
|
import * as OpfsUtils from '../../opfs-utils.js'
|
|
38
35
|
import { readPersistedAppDbFromClientSession, resetPersistedDataFromClientSession } from '../common/persisted-sqlite.js'
|
|
39
36
|
import { makeShutdownChannel } from '../common/shutdown-channel.js'
|
|
40
37
|
import { DedicatedWorkerDisconnectBroadcast, makeWorkerDisconnectChannel } from '../common/worker-disconnect-channel.js'
|
|
41
38
|
import * as WorkerSchema from '../common/worker-schema.js'
|
|
42
|
-
import {
|
|
39
|
+
import { connectWebmeshNodeClientSession } from './client-session-devtools.js'
|
|
43
40
|
|
|
44
41
|
// NOTE we're starting to initialize the sqlite wasm binary here to speed things up
|
|
45
42
|
const sqlite3Promise = loadSqlite3Wasm()
|
|
@@ -147,7 +144,7 @@ export const makePersistedAdapter =
|
|
|
147
144
|
|
|
148
145
|
yield* shutdownChannel.listen.pipe(
|
|
149
146
|
Stream.flatten(),
|
|
150
|
-
Stream.tap((error) =>
|
|
147
|
+
Stream.tap((error) => shutdown(Cause.fail(error))),
|
|
151
148
|
Stream.runDrain,
|
|
152
149
|
Effect.interruptible,
|
|
153
150
|
Effect.tapCauseLogPretty,
|
|
@@ -161,6 +158,7 @@ export const makePersistedAdapter =
|
|
|
161
158
|
concurrency: 100,
|
|
162
159
|
initialMessage: () =>
|
|
163
160
|
new WorkerSchema.SharedWorker.InitialMessage({
|
|
161
|
+
liveStoreVersion,
|
|
164
162
|
payload: {
|
|
165
163
|
_tag: 'FromClientSession',
|
|
166
164
|
initialMessage: new WorkerSchema.LeaderWorkerInner.InitialMessage({
|
|
@@ -177,7 +175,7 @@ export const makePersistedAdapter =
|
|
|
177
175
|
Effect.provide(BrowserWorker.layer(() => sharedWebWorker)),
|
|
178
176
|
Effect.tapCauseLogPretty,
|
|
179
177
|
UnexpectedError.mapToUnexpectedError,
|
|
180
|
-
Effect.tapErrorCause(
|
|
178
|
+
Effect.tapErrorCause(shutdown),
|
|
181
179
|
Effect.withSpan('@livestore/adapter-web:client-session:setupSharedWorker'),
|
|
182
180
|
Effect.forkScoped,
|
|
183
181
|
)
|
|
@@ -220,7 +218,7 @@ export const makePersistedAdapter =
|
|
|
220
218
|
}).pipe(
|
|
221
219
|
Effect.provide(BrowserWorker.layer(() => worker)),
|
|
222
220
|
UnexpectedError.mapToUnexpectedError,
|
|
223
|
-
Effect.tapErrorCause(
|
|
221
|
+
Effect.tapErrorCause(shutdown),
|
|
224
222
|
Effect.withSpan('@livestore/adapter-web:client-session:setupDedicatedWorker'),
|
|
225
223
|
Effect.tapCauseLogPretty,
|
|
226
224
|
Effect.forkScoped,
|
|
@@ -229,10 +227,9 @@ export const makePersistedAdapter =
|
|
|
229
227
|
yield* workerDisconnectChannel.send(DedicatedWorkerDisconnectBroadcast.make({}))
|
|
230
228
|
|
|
231
229
|
const sharedWorker = yield* Fiber.join(sharedWorkerFiber)
|
|
232
|
-
yield* sharedWorker
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
)
|
|
230
|
+
yield* sharedWorker
|
|
231
|
+
.executeEffect(new WorkerSchema.SharedWorker.UpdateMessagePort({ port: mc.port2 }))
|
|
232
|
+
.pipe(UnexpectedError.mapToUnexpectedError, Effect.tapErrorCause(shutdown))
|
|
236
233
|
|
|
237
234
|
yield* Deferred.succeed(waitForSharedWorkerInitialized, undefined)
|
|
238
235
|
|
|
@@ -308,9 +305,7 @@ export const makePersistedAdapter =
|
|
|
308
305
|
const bootStatusFiber = yield* runInWorkerStream(new WorkerSchema.LeaderWorkerInner.BootStatusStream()).pipe(
|
|
309
306
|
Stream.tap((_) => Queue.offer(bootStatusQueue, _)),
|
|
310
307
|
Stream.runDrain,
|
|
311
|
-
Effect.tapErrorCause((cause) =>
|
|
312
|
-
Cause.isInterruptedOnly(cause) ? Effect.void : Effect.sync(() => shutdown(cause)),
|
|
313
|
-
),
|
|
308
|
+
Effect.tapErrorCause((cause) => (Cause.isInterruptedOnly(cause) ? Effect.void : shutdown(cause))),
|
|
314
309
|
Effect.interruptible,
|
|
315
310
|
Effect.tapCauseLogPretty,
|
|
316
311
|
Effect.forkScoped,
|
|
@@ -355,15 +350,18 @@ export const makePersistedAdapter =
|
|
|
355
350
|
// We're restoring the leader head from the SESSION_CHANGESET_META_TABLE, not from the eventlog db/table
|
|
356
351
|
// in order to avoid exporting/transferring the eventlog db/table, which is important to speed up the fast path.
|
|
357
352
|
const initialLeaderHeadRes = sqliteDb.select<{
|
|
358
|
-
|
|
359
|
-
|
|
353
|
+
seqNumGlobal: EventSequenceNumber.GlobalEventSequenceNumber
|
|
354
|
+
seqNumClient: EventSequenceNumber.ClientEventSequenceNumber
|
|
360
355
|
}>(
|
|
361
|
-
`select
|
|
356
|
+
`select seqNumGlobal, seqNumClient from ${SystemTables.SESSION_CHANGESET_META_TABLE} order by seqNumGlobal desc, seqNumClient desc limit 1`,
|
|
362
357
|
)[0]
|
|
363
358
|
|
|
364
359
|
const initialLeaderHead = initialLeaderHeadRes
|
|
365
|
-
?
|
|
366
|
-
|
|
360
|
+
? EventSequenceNumber.make({
|
|
361
|
+
global: initialLeaderHeadRes.seqNumGlobal,
|
|
362
|
+
client: initialLeaderHeadRes.seqNumClient,
|
|
363
|
+
})
|
|
364
|
+
: EventSequenceNumber.ROOT
|
|
367
365
|
|
|
368
366
|
// console.debug('[@livestore/adapter-web:client-session] initialLeaderHead', initialLeaderHead)
|
|
369
367
|
|
|
@@ -424,63 +422,28 @@ export const makePersistedAdapter =
|
|
|
424
422
|
),
|
|
425
423
|
}
|
|
426
424
|
|
|
425
|
+
const sharedWorker = yield* Fiber.join(sharedWorkerFiber)
|
|
426
|
+
|
|
427
427
|
const clientSession = yield* makeClientSession({
|
|
428
428
|
...adapterArgs,
|
|
429
429
|
sqliteDb,
|
|
430
430
|
lockStatus,
|
|
431
431
|
clientId,
|
|
432
432
|
sessionId,
|
|
433
|
+
// isLeader: gotLocky, // TODO update when leader is changing
|
|
434
|
+
isLeader: true,
|
|
433
435
|
leaderThread,
|
|
434
436
|
webmeshMode: 'direct',
|
|
435
|
-
connectWebmeshNode:
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
yield* Devtools.SessionInfo.provideSessionInfo({
|
|
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
|
-
)
|
|
474
|
-
|
|
475
|
-
const sharedWorker = yield* Fiber.join(sharedWorkerFiber)
|
|
476
|
-
|
|
477
|
-
yield* DevtoolsWeb.connectViaWorker({
|
|
478
|
-
node: webmeshNode,
|
|
479
|
-
target: DevtoolsWeb.makeNodeName.sharedWorker({ storeId }),
|
|
480
|
-
worker: sharedWorker,
|
|
481
|
-
})
|
|
437
|
+
connectWebmeshNode: ({ sessionInfo, webmeshNode }) =>
|
|
438
|
+
connectWebmeshNodeClientSession({ webmeshNode, sessionInfo, sharedWorker, devtoolsEnabled, schema }),
|
|
439
|
+
registerBeforeUnload: (onBeforeUnload) => {
|
|
440
|
+
if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
|
|
441
|
+
window.addEventListener('beforeunload', onBeforeUnload)
|
|
442
|
+
return () => window.removeEventListener('beforeunload', onBeforeUnload)
|
|
482
443
|
}
|
|
483
|
-
|
|
444
|
+
|
|
445
|
+
return () => {}
|
|
446
|
+
},
|
|
484
447
|
})
|
|
485
448
|
|
|
486
449
|
return clientSession
|
|
@@ -3,11 +3,12 @@ import {
|
|
|
3
3
|
Devtools,
|
|
4
4
|
LeaderAheadError,
|
|
5
5
|
LeaderPullCursor,
|
|
6
|
+
liveStoreVersion,
|
|
6
7
|
MigrationsReport,
|
|
7
8
|
SyncState,
|
|
8
9
|
UnexpectedError,
|
|
9
10
|
} from '@livestore/common'
|
|
10
|
-
import {
|
|
11
|
+
import { EventSequenceNumber, LiveStoreEvent } from '@livestore/common/schema'
|
|
11
12
|
import * as WebmeshWorker from '@livestore/devtools-web-common/worker'
|
|
12
13
|
import { Schema, Transferable } from '@livestore/utils/effect'
|
|
13
14
|
|
|
@@ -116,7 +117,7 @@ export namespace LeaderWorkerInner {
|
|
|
116
117
|
|
|
117
118
|
export class GetLeaderHead extends Schema.TaggedRequest<GetLeaderHead>()('GetLeaderHead', {
|
|
118
119
|
payload: {},
|
|
119
|
-
success:
|
|
120
|
+
success: EventSequenceNumber.EventSequenceNumber,
|
|
120
121
|
failure: UnexpectedError,
|
|
121
122
|
}) {}
|
|
122
123
|
|
|
@@ -165,6 +166,9 @@ export namespace SharedWorker {
|
|
|
165
166
|
export class InitialMessage extends Schema.TaggedRequest<InitialMessage>()('InitialMessage', {
|
|
166
167
|
payload: {
|
|
167
168
|
payload: Schema.Union(InitialMessagePayloadFromClientSession, Schema.TaggedStruct('FromWebBridge', {})),
|
|
169
|
+
// To guard against scenarios where a client session is already running a newer version of LiveStore
|
|
170
|
+
// We should probably find a better way to handle those cases once they become more common.
|
|
171
|
+
liveStoreVersion: Schema.Literal(liveStoreVersion),
|
|
168
172
|
},
|
|
169
173
|
success: Schema.Void,
|
|
170
174
|
failure: UnexpectedError,
|