@livestore/adapter-web 0.0.0-snapshot-a953343ad2d7468c6573bcb5e26f0eab4302078f
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/.eslintrc.cjs +6 -0
- package/README.md +12 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/common/connection.d.ts +7 -0
- package/dist/common/connection.d.ts.map +1 -0
- package/dist/common/connection.js +25 -0
- package/dist/common/connection.js.map +1 -0
- package/dist/devtools-bridge/background-browser-channel.d.ts +9 -0
- package/dist/devtools-bridge/background-browser-channel.d.ts.map +1 -0
- package/dist/devtools-bridge/background-browser-channel.js +31 -0
- package/dist/devtools-bridge/background-browser-channel.js.map +1 -0
- package/dist/devtools-bridge/background-message.d.ts +75 -0
- package/dist/devtools-bridge/background-message.d.ts.map +1 -0
- package/dist/devtools-bridge/background-message.js +53 -0
- package/dist/devtools-bridge/background-message.js.map +1 -0
- package/dist/devtools-bridge/bridge-shared.d.ts +14 -0
- package/dist/devtools-bridge/bridge-shared.d.ts.map +1 -0
- package/dist/devtools-bridge/bridge-shared.js +67 -0
- package/dist/devtools-bridge/bridge-shared.js.map +1 -0
- package/dist/devtools-bridge/browser-extension-bridge.d.ts +3 -0
- package/dist/devtools-bridge/browser-extension-bridge.d.ts.map +1 -0
- package/dist/devtools-bridge/browser-extension-bridge.js +59 -0
- package/dist/devtools-bridge/browser-extension-bridge.js.map +1 -0
- package/dist/devtools-bridge/iframe-message.d.ts +16 -0
- package/dist/devtools-bridge/iframe-message.d.ts.map +1 -0
- package/dist/devtools-bridge/iframe-message.js +11 -0
- package/dist/devtools-bridge/iframe-message.js.map +1 -0
- package/dist/devtools-bridge/index.d.ts +6 -0
- package/dist/devtools-bridge/index.d.ts.map +1 -0
- package/dist/devtools-bridge/index.js +5 -0
- package/dist/devtools-bridge/index.js.map +1 -0
- package/dist/devtools-bridge/web-bridge.d.ts +31 -0
- package/dist/devtools-bridge/web-bridge.d.ts.map +1 -0
- package/dist/devtools-bridge/web-bridge.js +131 -0
- package/dist/devtools-bridge/web-bridge.js.map +1 -0
- package/dist/in-memory/index.d.ts +4 -0
- package/dist/in-memory/index.d.ts.map +1 -0
- package/dist/in-memory/index.js +50 -0
- package/dist/in-memory/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/opfs-utils.d.ts +5 -0
- package/dist/opfs-utils.d.ts.map +1 -0
- package/dist/opfs-utils.js +43 -0
- package/dist/opfs-utils.js.map +1 -0
- package/dist/web-worker/client-session/client-session-devtools.d.ts +7 -0
- package/dist/web-worker/client-session/client-session-devtools.d.ts.map +1 -0
- package/dist/web-worker/client-session/client-session-devtools.js +107 -0
- package/dist/web-worker/client-session/client-session-devtools.js.map +1 -0
- package/dist/web-worker/client-session/index.d.ts +41 -0
- package/dist/web-worker/client-session/index.d.ts.map +1 -0
- package/dist/web-worker/client-session/index.js +299 -0
- package/dist/web-worker/client-session/index.js.map +1 -0
- package/dist/web-worker/client-session/trim-batch.d.ts +4 -0
- package/dist/web-worker/client-session/trim-batch.d.ts.map +1 -0
- package/dist/web-worker/client-session/trim-batch.js +13 -0
- package/dist/web-worker/client-session/trim-batch.js.map +1 -0
- package/dist/web-worker/client-session/trim-batch.test.d.ts +2 -0
- package/dist/web-worker/client-session/trim-batch.test.d.ts.map +1 -0
- package/dist/web-worker/client-session/trim-batch.test.js +38 -0
- package/dist/web-worker/client-session/trim-batch.test.js.map +1 -0
- package/dist/web-worker/common/persisted-sqlite.d.ts +23 -0
- package/dist/web-worker/common/persisted-sqlite.d.ts.map +1 -0
- package/dist/web-worker/common/persisted-sqlite.js +92 -0
- package/dist/web-worker/common/persisted-sqlite.js.map +1 -0
- package/dist/web-worker/common/shutdown-channel.d.ts +7 -0
- package/dist/web-worker/common/shutdown-channel.d.ts.map +1 -0
- package/dist/web-worker/common/shutdown-channel.js +7 -0
- package/dist/web-worker/common/shutdown-channel.js.map +1 -0
- package/dist/web-worker/common/worker-schema.d.ts +226 -0
- package/dist/web-worker/common/worker-schema.d.ts.map +1 -0
- package/dist/web-worker/common/worker-schema.js +176 -0
- package/dist/web-worker/common/worker-schema.js.map +1 -0
- package/dist/web-worker/leader-worker/make-leader-worker.d.ts +15 -0
- package/dist/web-worker/leader-worker/make-leader-worker.d.ts.map +1 -0
- package/dist/web-worker/leader-worker/make-leader-worker.js +144 -0
- package/dist/web-worker/leader-worker/make-leader-worker.js.map +1 -0
- package/dist/web-worker/shared-worker/make-shared-worker.d.ts +2 -0
- package/dist/web-worker/shared-worker/make-shared-worker.d.ts.map +1 -0
- package/dist/web-worker/shared-worker/make-shared-worker.js +160 -0
- package/dist/web-worker/shared-worker/make-shared-worker.js.map +1 -0
- package/dist/web-worker/vite-dev-polyfill.d.ts +2 -0
- package/dist/web-worker/vite-dev-polyfill.d.ts.map +1 -0
- package/dist/web-worker/vite-dev-polyfill.js +37 -0
- package/dist/web-worker/vite-dev-polyfill.js.map +1 -0
- package/package.json +78 -0
- package/src/common/connection.ts +32 -0
- package/src/devtools-bridge/background-browser-channel.ts +57 -0
- package/src/devtools-bridge/background-message.ts +42 -0
- package/src/devtools-bridge/bridge-shared.ts +97 -0
- package/src/devtools-bridge/browser-extension-bridge.ts +64 -0
- package/src/devtools-bridge/iframe-message.ts +9 -0
- package/src/devtools-bridge/index.ts +9 -0
- package/src/devtools-bridge/web-bridge.ts +169 -0
- package/src/in-memory/index.ts +66 -0
- package/src/index.ts +3 -0
- package/src/opfs-utils.ts +61 -0
- package/src/web-worker/ambient.d.ts +37 -0
- package/src/web-worker/client-session/client-session-devtools.ts +167 -0
- package/src/web-worker/client-session/index.ts +537 -0
- package/src/web-worker/client-session/trim-batch.test.ts +48 -0
- package/src/web-worker/client-session/trim-batch.ts +15 -0
- package/src/web-worker/common/persisted-sqlite.ts +136 -0
- package/src/web-worker/common/shutdown-channel.ts +8 -0
- package/src/web-worker/common/worker-schema.ts +206 -0
- package/src/web-worker/leader-worker/make-leader-worker.ts +276 -0
- package/src/web-worker/shared-worker/make-shared-worker.ts +300 -0
- package/src/web-worker/vite-dev-polyfill.ts +36 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { Devtools, IntentionalShutdownCause, UnexpectedError } from '@livestore/common';
|
|
2
|
+
// TODO bring back - this currently doesn't work due to https://github.com/vitejs/vite/issues/8427
|
|
3
|
+
// NOTE We're using a non-relative import here for Vite to properly resolve the import during app builds
|
|
4
|
+
// import LiveStoreSharedWorker from '@livestore/adapter-web/internal-shared-worker?sharedworker'
|
|
5
|
+
import { ShutdownChannel } from '@livestore/common/leader-thread';
|
|
6
|
+
import { EventId, SESSION_CHANGESET_META_TABLE } from '@livestore/common/schema';
|
|
7
|
+
import { makeWebDevtoolsChannel } from '@livestore/devtools-web-common/web-channel';
|
|
8
|
+
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser';
|
|
9
|
+
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm';
|
|
10
|
+
import { isDevEnv, shouldNeverHappen, tryAsFunctionAndNew } from '@livestore/utils';
|
|
11
|
+
import { BrowserWorker, BucketQueue, Cause, Deferred, Effect, Exit, Fiber, ParseResult, Queue, Schema, Stream, SubscriptionRef, WebLock, Worker, WorkerError, } from '@livestore/utils/effect';
|
|
12
|
+
import { nanoid } from '@livestore/utils/nanoid';
|
|
13
|
+
import * as OpfsUtils from '../../opfs-utils.js';
|
|
14
|
+
import { readPersistedAppDbFromClientSession, resetPersistedDataFromClientSession } from '../common/persisted-sqlite.js';
|
|
15
|
+
import { makeShutdownChannel } from '../common/shutdown-channel.js';
|
|
16
|
+
import * as WorkerSchema from '../common/worker-schema.js';
|
|
17
|
+
import { bootDevtools } from './client-session-devtools.js';
|
|
18
|
+
import { trimPushBatch } from './trim-batch.js';
|
|
19
|
+
// NOTE we're starting to initialize the sqlite wasm binary here to speed things up
|
|
20
|
+
const sqlite3Promise = loadSqlite3Wasm();
|
|
21
|
+
if (isDevEnv()) {
|
|
22
|
+
globalThis.__debugLiveStoreUtils = {
|
|
23
|
+
opfs: OpfsUtils,
|
|
24
|
+
runSync: (effect) => Effect.runSync(effect),
|
|
25
|
+
runFork: (effect) => Effect.runFork(effect),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export const makeAdapter = (options) => ({ schema, storeId, devtoolsEnabled, debugInstanceId, bootStatusQueue, shutdown, connectDevtoolsToStore }) => Effect.gen(function* () {
|
|
29
|
+
yield* ensureBrowserRequirements;
|
|
30
|
+
yield* Queue.offer(bootStatusQueue, { stage: 'loading' });
|
|
31
|
+
const sqlite3 = yield* Effect.promise(() => sqlite3Promise);
|
|
32
|
+
const LIVESTORE_TAB_LOCK = `livestore-tab-lock-${storeId}`;
|
|
33
|
+
const storageOptions = yield* Schema.decode(WorkerSchema.StorageType)(options.storage);
|
|
34
|
+
if (options.resetPersistence === true) {
|
|
35
|
+
yield* resetPersistedDataFromClientSession({ storageOptions, storeId });
|
|
36
|
+
}
|
|
37
|
+
// Note on fast-path booting:
|
|
38
|
+
// Instead of waiting for the leader worker to boot and then get a database snapshot from it,
|
|
39
|
+
// we're here trying to get the snapshot directly from storage
|
|
40
|
+
// we usually speeds up the boot process by a lot.
|
|
41
|
+
// We need to be extra careful though to not run into any race conditions or inconsistencies.
|
|
42
|
+
// TODO also verify persisted data
|
|
43
|
+
const dataFromFile = yield* readPersistedAppDbFromClientSession({ storageOptions, storeId, schema });
|
|
44
|
+
// The same across all client sessions (i.e. tabs, windows)
|
|
45
|
+
const clientId = getPersistedId(`clientId:${storeId}`, 'local');
|
|
46
|
+
// Unique per client session (i.e. tab, window)
|
|
47
|
+
const sessionId = getPersistedId(`sessionId:${storeId}`, 'session');
|
|
48
|
+
const shutdownChannel = yield* makeShutdownChannel(storeId);
|
|
49
|
+
yield* shutdownChannel.listen.pipe(Stream.flatten(), Stream.filter(Schema.is(IntentionalShutdownCause)), Stream.tap((msg) => shutdown(Cause.fail(msg))), Stream.runDrain, Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
50
|
+
const sharedWebWorker = tryAsFunctionAndNew(options.sharedWorker, { name: `livestore-shared-worker-${storeId}` });
|
|
51
|
+
const sharedWorkerFiber = yield* Worker.makePoolSerialized({
|
|
52
|
+
size: 1,
|
|
53
|
+
concurrency: 100,
|
|
54
|
+
initialMessage: () => new WorkerSchema.SharedWorker.InitialMessage({
|
|
55
|
+
payload: {
|
|
56
|
+
_tag: 'FromClientSession',
|
|
57
|
+
initialMessage: new WorkerSchema.LeaderWorkerInner.InitialMessage({
|
|
58
|
+
storageOptions,
|
|
59
|
+
storeId,
|
|
60
|
+
clientId,
|
|
61
|
+
devtoolsEnabled,
|
|
62
|
+
debugInstanceId,
|
|
63
|
+
}),
|
|
64
|
+
},
|
|
65
|
+
}),
|
|
66
|
+
}).pipe(Effect.provide(BrowserWorker.layer(() => sharedWebWorker)), Effect.tapCauseLogPretty, UnexpectedError.mapToUnexpectedError, Effect.tapErrorCause(shutdown), Effect.withSpan('@livestore/adapter-web:client-session:setupSharedWorker'), Effect.forkScoped);
|
|
67
|
+
const lockDeferred = yield* Deferred.make();
|
|
68
|
+
// It's important that we resolve the leader election in a blocking way, so there's always a leader.
|
|
69
|
+
// Otherwise mutations could end up being dropped.
|
|
70
|
+
//
|
|
71
|
+
// Sorry for this pun ...
|
|
72
|
+
let gotLocky = yield* WebLock.tryGetDeferredLock(lockDeferred, LIVESTORE_TAB_LOCK);
|
|
73
|
+
const lockStatus = yield* SubscriptionRef.make(gotLocky ? 'has-lock' : 'no-lock');
|
|
74
|
+
// Ideally we can come up with a simpler implementation that doesn't require this
|
|
75
|
+
const waitForSharedWorkerInitialized = yield* Deferred.make();
|
|
76
|
+
if (gotLocky === false) {
|
|
77
|
+
// Don't need to wait if we're not the leader
|
|
78
|
+
yield* Deferred.succeed(waitForSharedWorkerInitialized, undefined);
|
|
79
|
+
}
|
|
80
|
+
const runLocked = Effect.gen(function* () {
|
|
81
|
+
yield* Effect.logDebug(`[@livestore/adapter-web:client-session] ✅ Got lock '${LIVESTORE_TAB_LOCK}' (sessionId: ${sessionId})`);
|
|
82
|
+
yield* Effect.addFinalizer(() => Effect.logDebug(`[@livestore/adapter-web:client-session] Releasing lock for '${LIVESTORE_TAB_LOCK}'`));
|
|
83
|
+
yield* SubscriptionRef.set(lockStatus, 'has-lock');
|
|
84
|
+
const mc = new MessageChannel();
|
|
85
|
+
// NOTE we're adding the `storeId` to the worker name to make it unique
|
|
86
|
+
// and adding the `sessionId` to make it easier to debug which session a worker belongs to in logs
|
|
87
|
+
const worker = tryAsFunctionAndNew(options.worker, { name: `livestore-worker-${storeId}-${sessionId}` });
|
|
88
|
+
yield* Worker.makeSerialized({
|
|
89
|
+
initialMessage: () => new WorkerSchema.LeaderWorkerOuter.InitialMessage({ port: mc.port1, storeId, clientId }),
|
|
90
|
+
}).pipe(Effect.provide(BrowserWorker.layer(() => worker)), UnexpectedError.mapToUnexpectedError, Effect.tapErrorCause(shutdown), Effect.withSpan('@livestore/adapter-web:client-session:setupDedicatedWorker'), Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
91
|
+
yield* shutdownChannel.send(ShutdownChannel.DedicatedWorkerDisconnectBroadcast.make({}));
|
|
92
|
+
const sharedWorker = yield* Fiber.join(sharedWorkerFiber);
|
|
93
|
+
yield* sharedWorker
|
|
94
|
+
.executeEffect(new WorkerSchema.SharedWorker.UpdateMessagePort({ port: mc.port2 }))
|
|
95
|
+
.pipe(UnexpectedError.mapToUnexpectedError, Effect.tapErrorCause(shutdown));
|
|
96
|
+
yield* Deferred.succeed(waitForSharedWorkerInitialized, undefined);
|
|
97
|
+
yield* Effect.addFinalizer(() => Effect.gen(function* () {
|
|
98
|
+
// console.log('[@livestore/adapter-web:client-session] Shutting down leader worker')
|
|
99
|
+
// We first try to gracefully shutdown the leader worker and then forcefully terminate it
|
|
100
|
+
// yield* Effect.raceFirst(
|
|
101
|
+
// sharedWorker
|
|
102
|
+
// .executeEffect(new WorkerSchema.LeaderWorkerInner.Shutdown({}))
|
|
103
|
+
// .pipe(Effect.andThen(() => worker.terminate())),
|
|
104
|
+
// Effect.sync(() => {
|
|
105
|
+
// console.warn(
|
|
106
|
+
// '[@livestore/adapter-web:client-session] Worker did not gracefully shutdown in time, terminating it',
|
|
107
|
+
// )
|
|
108
|
+
// worker.terminate()
|
|
109
|
+
// }).pipe(
|
|
110
|
+
// // Seems like we still need to wait a bit for the worker to terminate
|
|
111
|
+
// // TODO improve this implementation (possibly via another weblock?)
|
|
112
|
+
// Effect.delay(1000),
|
|
113
|
+
// ),
|
|
114
|
+
// )
|
|
115
|
+
// yield* Effect.logDebug('[@livestore/adapter-web:client-session] client-session shutdown. worker terminated')
|
|
116
|
+
}).pipe(Effect.withSpan('@livestore/adapter-web:client-session:lock:shutdown'), Effect.ignoreLogged));
|
|
117
|
+
yield* Effect.never;
|
|
118
|
+
}).pipe(Effect.withSpan('@livestore/adapter-web:client-session:lock'));
|
|
119
|
+
// TODO take/give up lock when tab becomes active/passive
|
|
120
|
+
if (gotLocky === false) {
|
|
121
|
+
yield* Effect.logDebug(`[@livestore/adapter-web:client-session] ⏳ Waiting for lock '${LIVESTORE_TAB_LOCK}' (sessionId: ${sessionId})`);
|
|
122
|
+
// TODO find a cleaner implementation for the lock handling as we don't make use of the deferred properly right now
|
|
123
|
+
yield* WebLock.waitForDeferredLock(lockDeferred, LIVESTORE_TAB_LOCK).pipe(Effect.andThen(() => {
|
|
124
|
+
gotLocky = true;
|
|
125
|
+
return runLocked;
|
|
126
|
+
}), Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
yield* runLocked.pipe(Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
130
|
+
}
|
|
131
|
+
const runInWorker = (req) => Fiber.join(sharedWorkerFiber).pipe(
|
|
132
|
+
// NOTE we need to wait for the shared worker to be initialized before we can send requests to it
|
|
133
|
+
Effect.tap(() => waitForSharedWorkerInitialized), Effect.flatMap((worker) => worker.executeEffect(req)),
|
|
134
|
+
// NOTE we want to treat worker requests as atomic and therefore not allow them to be interrupted
|
|
135
|
+
// Interruption usually only happens during leader re-election or store shutdown
|
|
136
|
+
// Effect.uninterruptible,
|
|
137
|
+
Effect.logWarnIfTakesLongerThan({
|
|
138
|
+
label: `@livestore/adapter-web:client-session:runInWorker:${req._tag}`,
|
|
139
|
+
duration: 2000,
|
|
140
|
+
}), Effect.withSpan(`@livestore/adapter-web:client-session:runInWorker:${req._tag}`), Effect.mapError((cause) => Schema.is(UnexpectedError)(cause)
|
|
141
|
+
? cause
|
|
142
|
+
: ParseResult.isParseError(cause) || Schema.is(WorkerError.WorkerError)(cause)
|
|
143
|
+
? new UnexpectedError({ cause })
|
|
144
|
+
: cause), Effect.catchAllDefect((cause) => new UnexpectedError({ cause })));
|
|
145
|
+
const runInWorkerStream = (req) => Effect.gen(function* () {
|
|
146
|
+
const sharedWorker = yield* Fiber.join(sharedWorkerFiber);
|
|
147
|
+
return sharedWorker.execute(req).pipe(Stream.mapError((cause) => Schema.is(UnexpectedError)(cause)
|
|
148
|
+
? cause
|
|
149
|
+
: ParseResult.isParseError(cause) || Schema.is(WorkerError.WorkerError)(cause)
|
|
150
|
+
? new UnexpectedError({ cause })
|
|
151
|
+
: cause), Stream.withSpan(`@livestore/adapter-web:client-session:runInWorkerStream:${req._tag}`));
|
|
152
|
+
}).pipe(Stream.unwrap);
|
|
153
|
+
const networkStatus = yield* SubscriptionRef.make({
|
|
154
|
+
isConnected: false,
|
|
155
|
+
timestampMs: Date.now(),
|
|
156
|
+
latchClosed: false,
|
|
157
|
+
});
|
|
158
|
+
yield* runInWorkerStream(new WorkerSchema.LeaderWorkerInner.NetworkStatusStream()).pipe(Stream.tap((_) => SubscriptionRef.set(networkStatus, _)), Stream.runDrain, Effect.forever, // NOTE Whenever the leader changes, we need to re-start the stream
|
|
159
|
+
Effect.tapErrorCause(shutdown), Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
160
|
+
const bootStatusFiber = yield* runInWorkerStream(new WorkerSchema.LeaderWorkerInner.BootStatusStream()).pipe(Stream.tap((_) => Queue.offer(bootStatusQueue, _)), Stream.runDrain, Effect.tapErrorCause((cause) => (Cause.isInterruptedOnly(cause) ? Effect.void : shutdown(cause))), Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
161
|
+
yield* Queue.awaitShutdown(bootStatusQueue).pipe(Effect.andThen(Fiber.interrupt(bootStatusFiber)), Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
162
|
+
// TODO maybe bring back transfering the initially created in-memory db snapshot instead of
|
|
163
|
+
// re-exporting the db
|
|
164
|
+
const initialResult = dataFromFile === undefined
|
|
165
|
+
? yield* runInWorker(new WorkerSchema.LeaderWorkerInner.GetRecreateSnapshot()).pipe(Effect.map(({ snapshot, migrationsReport }) => ({
|
|
166
|
+
_tag: 'from-leader-worker',
|
|
167
|
+
snapshot,
|
|
168
|
+
migrationsReport,
|
|
169
|
+
})))
|
|
170
|
+
: { _tag: 'fast-path', snapshot: dataFromFile };
|
|
171
|
+
const migrationsReport = initialResult._tag === 'from-leader-worker' ? initialResult.migrationsReport : { migrations: [] };
|
|
172
|
+
const makeSqliteDb = sqliteDbFactory({ sqlite3 });
|
|
173
|
+
const sqliteDb = yield* makeSqliteDb({ _tag: 'in-memory' });
|
|
174
|
+
sqliteDb.import(initialResult.snapshot);
|
|
175
|
+
const numberOfTables = sqliteDb.select(`select count(*) as count from sqlite_master`)[0]?.count ?? 0;
|
|
176
|
+
if (numberOfTables === 0) {
|
|
177
|
+
yield* UnexpectedError.make({
|
|
178
|
+
cause: `Encountered empty or corrupted database`,
|
|
179
|
+
payload: { snapshotByteLength: initialResult.snapshot.byteLength, storageOptions: options.storage },
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// We're restoring the leader head from the SESSION_CHANGESET_META_TABLE, not from the mutationlog db/table
|
|
183
|
+
// in order to avoid exporting/transferring the mutationlog db/table, which is important to speed up the fast path.
|
|
184
|
+
const initialLeaderHeadRes = sqliteDb.select(`select idGlobal, idClient from ${SESSION_CHANGESET_META_TABLE} order by idGlobal desc, idClient desc limit 1`)[0];
|
|
185
|
+
const initialLeaderHead = initialLeaderHeadRes
|
|
186
|
+
? EventId.make({ global: initialLeaderHeadRes.idGlobal, client: initialLeaderHeadRes.idClient })
|
|
187
|
+
: EventId.ROOT;
|
|
188
|
+
// console.debug('[@livestore/adapter-web:client-session] initialLeaderHead', initialLeaderHead)
|
|
189
|
+
yield* Effect.addFinalizer((ex) => Effect.gen(function* () {
|
|
190
|
+
if (Exit.isFailure(ex) &&
|
|
191
|
+
Exit.isInterrupted(ex) === false &&
|
|
192
|
+
Schema.is(IntentionalShutdownCause)(Cause.squash(ex.cause)) === false) {
|
|
193
|
+
yield* Effect.logError('[@livestore/adapter-web:client-session] client-session shutdown', ex.cause);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
yield* Effect.logDebug('[@livestore/adapter-web:client-session] client-session shutdown', gotLocky, ex);
|
|
197
|
+
}
|
|
198
|
+
if (gotLocky) {
|
|
199
|
+
yield* Deferred.succeed(lockDeferred, undefined);
|
|
200
|
+
}
|
|
201
|
+
}).pipe(Effect.tapCauseLogPretty, Effect.orDie));
|
|
202
|
+
const pushQueue = yield* BucketQueue.make();
|
|
203
|
+
yield* Effect.gen(function* () {
|
|
204
|
+
const batch = yield* BucketQueue.takeBetween(pushQueue, 1, 100);
|
|
205
|
+
// We need to trim "old batches" which can happen during client session rebasing
|
|
206
|
+
const trimmedBatch = trimPushBatch(batch);
|
|
207
|
+
yield* runInWorker(new WorkerSchema.LeaderWorkerInner.PushToLeader({ batch: trimmedBatch })).pipe(Effect.withSpan('@livestore/adapter-web:client-session:pushToLeader', {
|
|
208
|
+
attributes: { batchSize: batch.length },
|
|
209
|
+
}),
|
|
210
|
+
// We can ignore the error here because the ClientSessionSyncProcessor will retry after rebasing
|
|
211
|
+
Effect.ignoreLogged);
|
|
212
|
+
}).pipe(Effect.forever, Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
213
|
+
const devtools = devtoolsEnabled
|
|
214
|
+
? { enabled: true, pullLatch: yield* Effect.makeLatch(true), pushLatch: yield* Effect.makeLatch(true) }
|
|
215
|
+
: { enabled: false };
|
|
216
|
+
const clientSession = {
|
|
217
|
+
sqliteDb,
|
|
218
|
+
devtools,
|
|
219
|
+
lockStatus,
|
|
220
|
+
clientId,
|
|
221
|
+
sessionId,
|
|
222
|
+
leaderThread: {
|
|
223
|
+
export: runInWorker(new WorkerSchema.LeaderWorkerInner.Export()).pipe(Effect.timeout(10_000), UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/adapter-web:client-session:export')),
|
|
224
|
+
mutations: {
|
|
225
|
+
pull: runInWorkerStream(new WorkerSchema.LeaderWorkerInner.PullStream({ cursor: initialLeaderHead })).pipe(Stream.orDie),
|
|
226
|
+
// NOTE instead of sending the worker message right away, we're batching the events in order to
|
|
227
|
+
// - maintain a consistent order of events
|
|
228
|
+
// - improve efficiency by reducing the number of messages
|
|
229
|
+
push: (batch) => BucketQueue.offerAll(pushQueue, batch),
|
|
230
|
+
},
|
|
231
|
+
initialState: { leaderHead: initialLeaderHead, migrationsReport },
|
|
232
|
+
getMutationLogData: runInWorker(new WorkerSchema.LeaderWorkerInner.ExportMutationlog()).pipe(Effect.timeout(10_000), UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/adapter-web:client-session:getMutationLogData')),
|
|
233
|
+
getSyncState: runInWorker(new WorkerSchema.LeaderWorkerInner.GetLeaderSyncState()).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/adapter-web:client-session:getLeaderSyncState')),
|
|
234
|
+
networkStatus,
|
|
235
|
+
sendDevtoolsMessage: (message) => runInWorker(new WorkerSchema.LeaderWorkerInner.ExtraDevtoolsMessage({ message })).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/adapter-web:client-session:devtoolsMessageForLeader')),
|
|
236
|
+
},
|
|
237
|
+
shutdown,
|
|
238
|
+
};
|
|
239
|
+
if (devtoolsEnabled) {
|
|
240
|
+
// yield* bootDevtools({ client-session, waitForDevtoolsWebBridgePort, connectToDevtools, storeId })
|
|
241
|
+
yield* Effect.gen(function* () {
|
|
242
|
+
const sharedWorker = yield* Fiber.join(sharedWorkerFiber);
|
|
243
|
+
yield* bootDevtools({ clientSession, storeId });
|
|
244
|
+
// TODO re-enable browser extension as well
|
|
245
|
+
const storeDevtoolsChannel = yield* makeWebDevtoolsChannel({
|
|
246
|
+
nodeName: `client-session-${storeId}-${clientId}-${sessionId}`,
|
|
247
|
+
target: `devtools`,
|
|
248
|
+
schema: {
|
|
249
|
+
listen: Devtools.ClientSession.MessageToApp,
|
|
250
|
+
send: Devtools.ClientSession.MessageFromApp,
|
|
251
|
+
},
|
|
252
|
+
worker: sharedWorker,
|
|
253
|
+
workerTargetName: 'shared-worker',
|
|
254
|
+
});
|
|
255
|
+
yield* connectDevtoolsToStore(storeDevtoolsChannel);
|
|
256
|
+
}).pipe(Effect.withSpan('@livestore/adapter-web:client-session:devtools'), Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
257
|
+
}
|
|
258
|
+
return clientSession;
|
|
259
|
+
}).pipe(UnexpectedError.mapToUnexpectedError);
|
|
260
|
+
// NOTE for `local` storage we could also use the mutationlog db to store the data
|
|
261
|
+
const getPersistedId = (key, storageType) => {
|
|
262
|
+
const makeId = () => nanoid(5);
|
|
263
|
+
const storage = typeof window === 'undefined'
|
|
264
|
+
? undefined
|
|
265
|
+
: storageType === 'session'
|
|
266
|
+
? sessionStorage
|
|
267
|
+
: storageType === 'local'
|
|
268
|
+
? localStorage
|
|
269
|
+
: shouldNeverHappen(`[@livestore/adapter-web] Invalid storage type: ${storageType}`);
|
|
270
|
+
// in case of a worker, we need the id of the parent window, to keep the id consistent
|
|
271
|
+
// we also need to handle the case where there are multiple workers being spawned by the same window
|
|
272
|
+
if (storage === undefined) {
|
|
273
|
+
return makeId();
|
|
274
|
+
}
|
|
275
|
+
const fullKey = `livestore:${key}`;
|
|
276
|
+
const storedKey = storage.getItem(fullKey);
|
|
277
|
+
if (storedKey)
|
|
278
|
+
return storedKey;
|
|
279
|
+
const newKey = makeId();
|
|
280
|
+
storage.setItem(fullKey, newKey);
|
|
281
|
+
return newKey;
|
|
282
|
+
};
|
|
283
|
+
const ensureBrowserRequirements = Effect.gen(function* () {
|
|
284
|
+
const validate = (condition, label) => Effect.gen(function* () {
|
|
285
|
+
if (condition) {
|
|
286
|
+
yield* UnexpectedError.make({
|
|
287
|
+
cause: `[@livestore/adapter-web] Browser not supported. The LiveStore web adapter needs '${label}' to work properly`,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
yield* Effect.all([
|
|
292
|
+
validate(typeof navigator === 'undefined', 'navigator'),
|
|
293
|
+
validate(navigator.locks === undefined, 'navigator.locks'),
|
|
294
|
+
validate(navigator.storage === undefined, 'navigator.storage'),
|
|
295
|
+
validate(typeof window === 'undefined', 'window'),
|
|
296
|
+
validate(typeof sessionStorage === 'undefined', 'sessionStorage'),
|
|
297
|
+
]);
|
|
298
|
+
});
|
|
299
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web-worker/client-session/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MutationEvent } from '@livestore/common/schema';
|
|
2
|
+
/** [(0,1), (0,2), (1,0), (0,1), (0,2), (1,0), (1,1)] -> [(0,1), (0,2), (1,0), (1,1)] */
|
|
3
|
+
export declare const trimPushBatch: (batch: ReadonlyArray<MutationEvent.AnyEncoded>) => readonly MutationEvent.AnyEncoded[];
|
|
4
|
+
//# sourceMappingURL=trim-batch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trim-batch.d.ts","sourceRoot":"","sources":["../../../src/web-worker/client-session/trim-batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAG7D,wFAAwF;AACxF,eAAO,MAAM,aAAa,UAAW,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,wCAU3E,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EventId } from '@livestore/common/schema';
|
|
2
|
+
/** [(0,1), (0,2), (1,0), (0,1), (0,2), (1,0), (1,1)] -> [(0,1), (0,2), (1,0), (1,1)] */
|
|
3
|
+
export const trimPushBatch = (batch) => {
|
|
4
|
+
// Iterate over batch from the end and stop once we encounter an event with a larger id than the previous event
|
|
5
|
+
// Then return the slice of the batch up to and including that event
|
|
6
|
+
for (let i = batch.length - 2; i >= 0; i--) {
|
|
7
|
+
if (EventId.isGreaterThanOrEqual(batch[i].id, batch[i + 1].id)) {
|
|
8
|
+
return batch.slice(i + 1);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return batch;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=trim-batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trim-batch.js","sourceRoot":"","sources":["../../../src/web-worker/client-session/trim-batch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAElD,wFAAwF;AACxF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAA8C,EAAE,EAAE;IAC9E,+GAA+G;IAC/G,oEAAoE;IACpE,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,OAAO,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACjE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trim-batch.test.d.ts","sourceRoot":"","sources":["../../../src/web-worker/client-session/trim-batch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { EventId } from '@livestore/common/schema';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { trimPushBatch } from './trim-batch.js';
|
|
4
|
+
describe('trimPushBatch', () => {
|
|
5
|
+
it('should return same batch', () => {
|
|
6
|
+
const batch = [
|
|
7
|
+
{ id: EventId.make({ global: 0, client: 1 }), parentId: EventId.make({ global: 0, client: 0 }) },
|
|
8
|
+
{ id: EventId.make({ global: 0, client: 2 }), parentId: EventId.make({ global: 0, client: 1 }) },
|
|
9
|
+
{ id: EventId.make({ global: 1, client: 0 }), parentId: EventId.make({ global: 0, client: 0 }) },
|
|
10
|
+
{ id: EventId.make({ global: 1, client: 1 }), parentId: EventId.make({ global: 1, client: 0 }) },
|
|
11
|
+
];
|
|
12
|
+
const trimmed = trimPushBatch(batch);
|
|
13
|
+
expect(trimmed).toEqual(batch);
|
|
14
|
+
});
|
|
15
|
+
it('should trim the batch', () => {
|
|
16
|
+
const batch = [
|
|
17
|
+
{ id: EventId.make({ global: 0, client: 1 }), parentId: EventId.make({ global: 0, client: 0 }) },
|
|
18
|
+
{ id: EventId.make({ global: 0, client: 2 }), parentId: EventId.make({ global: 0, client: 1 }) },
|
|
19
|
+
// should trim above
|
|
20
|
+
{ id: EventId.make({ global: 0, client: 1 }), parentId: EventId.make({ global: 0, client: 0 }) },
|
|
21
|
+
{ id: EventId.make({ global: 0, client: 2 }), parentId: EventId.make({ global: 0, client: 1 }) },
|
|
22
|
+
{ id: EventId.make({ global: 1, client: 0 }), parentId: EventId.make({ global: 0, client: 0 }) },
|
|
23
|
+
{ id: EventId.make({ global: 1, client: 1 }), parentId: EventId.make({ global: 1, client: 0 }) },
|
|
24
|
+
];
|
|
25
|
+
const trimmed = trimPushBatch(batch);
|
|
26
|
+
expect(trimmed).toEqual(batch.slice(2));
|
|
27
|
+
});
|
|
28
|
+
it('should trim the batch', () => {
|
|
29
|
+
const batch = [
|
|
30
|
+
{ id: EventId.make({ global: 0, client: 1 }), parentId: EventId.make({ global: 0, client: 0 }) },
|
|
31
|
+
// should trim above
|
|
32
|
+
{ id: EventId.make({ global: 0, client: 1 }), parentId: EventId.make({ global: 0, client: 0 }) },
|
|
33
|
+
];
|
|
34
|
+
const trimmed = trimPushBatch(batch);
|
|
35
|
+
expect(trimmed).toEqual(batch.slice(1));
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=trim-batch.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trim-batch.test.js","sourceRoot":"","sources":["../../../src/web-worker/client-session/trim-batch.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { LiveStoreSchema } from '@livestore/common/schema';
|
|
2
|
+
import { Effect, Schema } from '@livestore/utils/effect';
|
|
3
|
+
import type * as WorkerSchema from './worker-schema.js';
|
|
4
|
+
declare const PersistedSqliteError_base: Schema.TaggedErrorClass<PersistedSqliteError, "PersistedSqliteError", {
|
|
5
|
+
readonly _tag: Schema.tag<"PersistedSqliteError">;
|
|
6
|
+
} & {
|
|
7
|
+
cause: Schema.Defect;
|
|
8
|
+
}>;
|
|
9
|
+
export declare class PersistedSqliteError extends PersistedSqliteError_base {
|
|
10
|
+
}
|
|
11
|
+
export declare const readPersistedAppDbFromClientSession: ({ storageOptions, storeId, schema, }: {
|
|
12
|
+
storageOptions: WorkerSchema.StorageType;
|
|
13
|
+
storeId: string;
|
|
14
|
+
schema: LiveStoreSchema;
|
|
15
|
+
}) => Effect.Effect<Uint8Array<ArrayBuffer> | undefined, never, never>;
|
|
16
|
+
export declare const resetPersistedDataFromClientSession: ({ storageOptions, storeId, }: {
|
|
17
|
+
storageOptions: WorkerSchema.StorageType;
|
|
18
|
+
storeId: string;
|
|
19
|
+
}) => Effect.Effect<void, never, never>;
|
|
20
|
+
export declare const sanitizeOpfsDir: (directory: string | undefined, storeId: string) => string;
|
|
21
|
+
export declare const getAppDbFileName: (schema: LiveStoreSchema) => string;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=persisted-sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persisted-sqlite.d.ts","sourceRoot":"","sources":["../../../src/web-worker/common/persisted-sqlite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAGxD,OAAO,KAAK,KAAK,YAAY,MAAM,oBAAoB,CAAA;;;;;;AAEvD,qBAAa,oBAAqB,SAAQ,yBAExC;CAAG;AAEL,eAAO,MAAM,mCAAmC,yCAI7C;IACD,cAAc,EAAE,YAAY,CAAC,WAAW,CAAA;IACxC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,eAAe,CAAA;CACxB,qEAyDE,CAAA;AAEH,eAAO,MAAM,mCAAmC,iCAG7C;IACD,cAAc,EAAE,YAAY,CAAC,WAAW,CAAA;IACxC,OAAO,EAAE,MAAM,CAAA;CAChB,sCAIuF,CAAA;AA6BxF,eAAO,MAAM,eAAe,cAAe,MAAM,GAAG,SAAS,WAAW,MAAM,WAY7E,CAAA;AAED,eAAO,MAAM,gBAAgB,WAAY,eAAe,WAGvD,CAAA"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { liveStoreStorageFormatVersion } from '@livestore/common';
|
|
2
|
+
import { decodeSAHPoolFilename, HEADER_OFFSET_DATA } from '@livestore/sqlite-wasm/browser';
|
|
3
|
+
import { Effect, Schema } from '@livestore/utils/effect';
|
|
4
|
+
import * as OpfsUtils from '../../opfs-utils.js';
|
|
5
|
+
export class PersistedSqliteError extends Schema.TaggedError()('PersistedSqliteError', {
|
|
6
|
+
cause: Schema.Defect,
|
|
7
|
+
}) {
|
|
8
|
+
}
|
|
9
|
+
export const readPersistedAppDbFromClientSession = ({ storageOptions, storeId, schema, }) => Effect.gen(function* () {
|
|
10
|
+
return yield* Effect.promise(async () => {
|
|
11
|
+
const directory = sanitizeOpfsDir(storageOptions.directory, storeId);
|
|
12
|
+
const sahPoolOpaqueDir = await OpfsUtils.getDirHandle(directory).catch(() => undefined);
|
|
13
|
+
if (sahPoolOpaqueDir === undefined) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const tryGetDbFile = async (fileHandle) => {
|
|
17
|
+
const file = await fileHandle.getFile();
|
|
18
|
+
const fileName = await decodeSAHPoolFilename(file);
|
|
19
|
+
return fileName ? { fileName, file } : undefined;
|
|
20
|
+
};
|
|
21
|
+
const getAllFiles = async (asyncIterator) => {
|
|
22
|
+
const results = [];
|
|
23
|
+
for await (const value of asyncIterator) {
|
|
24
|
+
if (value.kind === 'file') {
|
|
25
|
+
results.push(value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return results;
|
|
29
|
+
};
|
|
30
|
+
const files = await getAllFiles(sahPoolOpaqueDir.values());
|
|
31
|
+
const fileResults = await Promise.all(files.map(tryGetDbFile));
|
|
32
|
+
const appDbFileName = '/' + getAppDbFileName(schema);
|
|
33
|
+
const dbFileRes = fileResults.find((_) => _?.fileName === appDbFileName);
|
|
34
|
+
// console.debug('fileResults', fileResults, 'dbFileRes', dbFileRes)
|
|
35
|
+
if (dbFileRes !== undefined) {
|
|
36
|
+
const data = await dbFileRes.file.slice(HEADER_OFFSET_DATA).arrayBuffer();
|
|
37
|
+
// console.debug('readPersistedAppDbFromClientSession', data.byteLength, data)
|
|
38
|
+
// Given the SAH pool always eagerly creates files with empty non-header data,
|
|
39
|
+
// we want to return undefined if the file exists but is empty
|
|
40
|
+
if (data.byteLength === 0) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
return new Uint8Array(data);
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
});
|
|
47
|
+
}).pipe(Effect.logWarnIfTakesLongerThan({
|
|
48
|
+
duration: 1000,
|
|
49
|
+
label: '@livestore/adapter-web:readPersistedAppDbFromClientSession',
|
|
50
|
+
}), Effect.withPerformanceMeasure('@livestore/adapter-web:readPersistedAppDbFromClientSession'), Effect.withSpan('@livestore/adapter-web:readPersistedAppDbFromClientSession'));
|
|
51
|
+
export const resetPersistedDataFromClientSession = ({ storageOptions, storeId, }) => Effect.gen(function* () {
|
|
52
|
+
const directory = sanitizeOpfsDir(storageOptions.directory, storeId);
|
|
53
|
+
yield* opfsDeleteAbs(directory);
|
|
54
|
+
}).pipe(Effect.withSpan('@livestore/adapter-web:resetPersistedDataFromClientSession'));
|
|
55
|
+
const opfsDeleteAbs = (absPath) => Effect.promise(async () => {
|
|
56
|
+
// Get the root directory handle
|
|
57
|
+
const root = await OpfsUtils.rootHandlePromise;
|
|
58
|
+
// Split the absolute path to traverse directories
|
|
59
|
+
const pathParts = absPath.split('/').filter((part) => part.length);
|
|
60
|
+
try {
|
|
61
|
+
// Traverse to the target file handle
|
|
62
|
+
let currentDir = root;
|
|
63
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
64
|
+
currentDir = await currentDir.getDirectoryHandle(pathParts[i]);
|
|
65
|
+
}
|
|
66
|
+
// Delete the file
|
|
67
|
+
await currentDir.removeEntry(pathParts.at(-1), { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof DOMException && error.name === 'NotFoundError') {
|
|
71
|
+
// Can ignore as it's already been deleted or not there in the first place
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}).pipe(Effect.withSpan('@livestore/adapter-web:worker:opfsDeleteFile', { attributes: { absFilePath: absPath } }));
|
|
79
|
+
export const sanitizeOpfsDir = (directory, storeId) => {
|
|
80
|
+
// Root dir should be `''` not `/`
|
|
81
|
+
if (directory === undefined || directory === '' || directory === '/')
|
|
82
|
+
return `livestore-${storeId}@${liveStoreStorageFormatVersion}`;
|
|
83
|
+
if (directory.includes('/')) {
|
|
84
|
+
throw new Error(`@livestore/adapter-web:worker:sanitizeOpfsDir: Nested directories are not yet supported ('${directory}')`);
|
|
85
|
+
}
|
|
86
|
+
return `${directory}@${liveStoreStorageFormatVersion}`;
|
|
87
|
+
};
|
|
88
|
+
export const getAppDbFileName = (schema) => {
|
|
89
|
+
const schemaHashSuffix = schema.migrationOptions.strategy === 'manual' ? 'fixed' : schema.hash.toString();
|
|
90
|
+
return `app${schemaHashSuffix}.db`;
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=persisted-sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persisted-sqlite.js","sourceRoot":"","sources":["../../../src/web-worker/common/persisted-sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { WebChannel } from '@livestore/utils/effect';
|
|
2
|
+
export declare const makeShutdownChannel: (storeId: string) => import("effect/Effect").Effect<WebChannel.WebChannel<import("@livestore/common/dist/adapter-types.js").IntentionalShutdownCause | {
|
|
3
|
+
readonly _tag: "DedicatedWorkerDisconnectBroadcast";
|
|
4
|
+
}, import("@livestore/common/dist/adapter-types.js").IntentionalShutdownCause | {
|
|
5
|
+
readonly _tag: "DedicatedWorkerDisconnectBroadcast";
|
|
6
|
+
}, never>, never, import("effect/Scope").Scope>;
|
|
7
|
+
//# sourceMappingURL=shutdown-channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown-channel.d.ts","sourceRoot":"","sources":["../../../src/web-worker/common/shutdown-channel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpD,eAAO,MAAM,mBAAmB,YAAa,MAAM;;;;+CAI/C,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ShutdownChannel } from '@livestore/common/leader-thread';
|
|
2
|
+
import { WebChannel } from '@livestore/utils/effect';
|
|
3
|
+
export const makeShutdownChannel = (storeId) => WebChannel.broadcastChannel({
|
|
4
|
+
channelName: `livestore.shutdown.${storeId}`,
|
|
5
|
+
schema: ShutdownChannel.All,
|
|
6
|
+
});
|
|
7
|
+
//# sourceMappingURL=shutdown-channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown-channel.js","sourceRoot":"","sources":["../../../src/web-worker/common/shutdown-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,EAAE,CACrD,UAAU,CAAC,gBAAgB,CAAC;IAC1B,WAAW,EAAE,sBAAsB,OAAO,EAAE;IAC5C,MAAM,EAAE,eAAe,CAAC,GAAG;CAC5B,CAAC,CAAA"}
|