@livestore/adapter-web 0.4.0-dev.13 → 0.4.0-dev.15
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 +13 -3
- package/dist/in-memory/in-memory-adapter.d.ts.map +1 -1
- package/dist/in-memory/in-memory-adapter.js +19 -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 +10 -2
- package/dist/web-worker/client-session/persisted-adapter.js.map +1 -1
- package/dist/web-worker/client-session/sqlite-loader.js +1 -1
- package/dist/web-worker/client-session/sqlite-loader.js.map +1 -1
- package/dist/web-worker/common/worker-schema.d.ts +5 -5
- package/dist/web-worker/common/worker-schema.js +1 -1
- package/dist/web-worker/common/worker-schema.js.map +1 -1
- package/dist/web-worker/leader-worker/make-leader-worker.d.ts +2 -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 +4 -3
- package/dist/web-worker/leader-worker/make-leader-worker.js.map +1 -1
- package/dist/web-worker/shared-worker/make-shared-worker.js +3 -3
- 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 +32 -7
- package/src/web-worker/client-session/persisted-adapter.ts +20 -2
- package/src/web-worker/client-session/sqlite-loader.ts +1 -1
- package/src/web-worker/common/worker-schema.ts +1 -1
- package/src/web-worker/leader-worker/make-leader-worker.ts +6 -3
- package/src/web-worker/shared-worker/make-shared-worker.ts +3 -3
|
@@ -17,8 +17,17 @@ import type * as WebmeshWorker from '@livestore/devtools-web-common/worker'
|
|
|
17
17
|
import type { MakeWebSqliteDb } from '@livestore/sqlite-wasm/browser'
|
|
18
18
|
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser'
|
|
19
19
|
import { tryAsFunctionAndNew } from '@livestore/utils'
|
|
20
|
-
import type {
|
|
21
|
-
import {
|
|
20
|
+
import type { Scope } from '@livestore/utils/effect'
|
|
21
|
+
import {
|
|
22
|
+
BrowserWorker,
|
|
23
|
+
Effect,
|
|
24
|
+
FetchHttpClient,
|
|
25
|
+
Fiber,
|
|
26
|
+
Layer,
|
|
27
|
+
type Schema,
|
|
28
|
+
SubscriptionRef,
|
|
29
|
+
Worker,
|
|
30
|
+
} from '@livestore/utils/effect'
|
|
22
31
|
import { nanoid } from '@livestore/utils/nanoid'
|
|
23
32
|
import * as Webmesh from '@livestore/webmesh'
|
|
24
33
|
|
|
@@ -52,11 +61,21 @@ export interface InMemoryAdapterOptions {
|
|
|
52
61
|
}
|
|
53
62
|
}
|
|
54
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Create a web-only in-memory LiveStore adapter.
|
|
66
|
+
*
|
|
67
|
+
* - Runs entirely in memory: fast, zero I/O, great for tests, sandboxes, or ephemeral sessions.
|
|
68
|
+
* - Works across browser execution contexts: Window, WebWorker, SharedWorker, and ServiceWorker.
|
|
69
|
+
* - DevTools: to inspect this adapter from the browser DevTools, provide a `sharedWorker` in `options.devtools`.
|
|
70
|
+
* (The shared worker is used to bridge the DevTools UI to the running session.)
|
|
71
|
+
* - No persistence support: nothing is written to OPFS/IndexedDB/localStorage. `importSnapshot`
|
|
72
|
+
* can bootstrap initial state only; subsequent changes are not persisted anywhere.
|
|
73
|
+
*/
|
|
55
74
|
export const makeInMemoryAdapter =
|
|
56
75
|
(options: InMemoryAdapterOptions = {}): Adapter =>
|
|
57
76
|
(adapterArgs) =>
|
|
58
77
|
Effect.gen(function* () {
|
|
59
|
-
const { schema, shutdown,
|
|
78
|
+
const { schema, shutdown, syncPayloadEncoded, syncPayloadSchema, storeId, devtoolsEnabled } = adapterArgs
|
|
60
79
|
const sqlite3 = yield* Effect.promise(() => loadSqlite3())
|
|
61
80
|
|
|
62
81
|
const sqliteDb = yield* sqliteDbFactory({ sqlite3 })({ _tag: 'in-memory' })
|
|
@@ -88,7 +107,8 @@ export const makeInMemoryAdapter =
|
|
|
88
107
|
clientId,
|
|
89
108
|
makeSqliteDb: sqliteDbFactory({ sqlite3 }),
|
|
90
109
|
syncOptions: options.sync,
|
|
91
|
-
|
|
110
|
+
syncPayloadEncoded,
|
|
111
|
+
syncPayloadSchema,
|
|
92
112
|
importSnapshot: options.importSnapshot,
|
|
93
113
|
devtoolsEnabled,
|
|
94
114
|
sharedWorkerFiber,
|
|
@@ -108,6 +128,8 @@ export const makeInMemoryAdapter =
|
|
|
108
128
|
lockStatus,
|
|
109
129
|
shutdown,
|
|
110
130
|
webmeshMode: 'direct',
|
|
131
|
+
// Can be undefined in Node.js
|
|
132
|
+
origin: globalThis.location?.origin,
|
|
111
133
|
connectWebmeshNode: ({ sessionInfo, webmeshNode }) =>
|
|
112
134
|
Effect.gen(function* () {
|
|
113
135
|
if (sharedWorkerFiber === undefined || devtoolsEnabled === false) {
|
|
@@ -137,7 +159,8 @@ export interface MakeLeaderThreadArgs {
|
|
|
137
159
|
clientId: string
|
|
138
160
|
makeSqliteDb: MakeWebSqliteDb
|
|
139
161
|
syncOptions: SyncOptions | undefined
|
|
140
|
-
|
|
162
|
+
syncPayloadEncoded: Schema.JsonValue | undefined
|
|
163
|
+
syncPayloadSchema: Schema.Schema<any> | undefined
|
|
141
164
|
importSnapshot: Uint8Array<ArrayBuffer> | undefined
|
|
142
165
|
devtoolsEnabled: boolean
|
|
143
166
|
sharedWorkerFiber: SharedWorkerFiber | undefined
|
|
@@ -149,7 +172,8 @@ const makeLeaderThread = ({
|
|
|
149
172
|
clientId,
|
|
150
173
|
makeSqliteDb,
|
|
151
174
|
syncOptions,
|
|
152
|
-
|
|
175
|
+
syncPayloadEncoded,
|
|
176
|
+
syncPayloadSchema,
|
|
153
177
|
importSnapshot,
|
|
154
178
|
devtoolsEnabled,
|
|
155
179
|
sharedWorkerFiber,
|
|
@@ -196,7 +220,8 @@ const makeLeaderThread = ({
|
|
|
196
220
|
dbEventlog,
|
|
197
221
|
devtoolsOptions,
|
|
198
222
|
shutdownChannel,
|
|
199
|
-
|
|
223
|
+
syncPayloadEncoded,
|
|
224
|
+
syncPayloadSchema,
|
|
200
225
|
}),
|
|
201
226
|
)
|
|
202
227
|
|
|
@@ -138,7 +138,23 @@ export const makePersistedAdapter =
|
|
|
138
138
|
(options: WebAdapterOptions): Adapter =>
|
|
139
139
|
(adapterArgs) =>
|
|
140
140
|
Effect.gen(function* () {
|
|
141
|
-
const {
|
|
141
|
+
const {
|
|
142
|
+
schema,
|
|
143
|
+
storeId,
|
|
144
|
+
devtoolsEnabled,
|
|
145
|
+
debugInstanceId,
|
|
146
|
+
bootStatusQueue,
|
|
147
|
+
shutdown,
|
|
148
|
+
syncPayloadSchema: _syncPayloadSchema,
|
|
149
|
+
syncPayloadEncoded,
|
|
150
|
+
} = adapterArgs
|
|
151
|
+
|
|
152
|
+
// NOTE: The schema travels with the worker bundle (developers call
|
|
153
|
+
// `makeWorker({ schema, syncPayloadSchema })`). We only keep the
|
|
154
|
+
// destructured value here to document availability on the client session
|
|
155
|
+
// side—structured cloning the Effect schema into the worker is not
|
|
156
|
+
// possible, so we intentionally do not forward it.
|
|
157
|
+
void _syncPayloadSchema
|
|
142
158
|
|
|
143
159
|
yield* ensureBrowserRequirements
|
|
144
160
|
|
|
@@ -266,7 +282,7 @@ export const makePersistedAdapter =
|
|
|
266
282
|
clientId,
|
|
267
283
|
devtoolsEnabled,
|
|
268
284
|
debugInstanceId,
|
|
269
|
-
|
|
285
|
+
syncPayloadEncoded,
|
|
270
286
|
}),
|
|
271
287
|
}),
|
|
272
288
|
)
|
|
@@ -490,6 +506,8 @@ export const makePersistedAdapter =
|
|
|
490
506
|
isLeader: gotLocky,
|
|
491
507
|
leaderThread,
|
|
492
508
|
webmeshMode: 'direct',
|
|
509
|
+
// Can be undefined in Node.js
|
|
510
|
+
origin: globalThis.location?.origin,
|
|
493
511
|
connectWebmeshNode: ({ sessionInfo, webmeshNode }) =>
|
|
494
512
|
connectWebmeshNodeClientSession({ webmeshNode, sessionInfo, sharedWorker, devtoolsEnabled, schema }),
|
|
495
513
|
registerBeforeUnload: (onBeforeUnload) => {
|
|
@@ -8,7 +8,7 @@ import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
|
8
8
|
* The Cloudflare / Workerd runtime has stricter rules: async fetches during module
|
|
9
9
|
* evaluation are blocked, so we defer loading until the worker asks for it.
|
|
10
10
|
*/
|
|
11
|
-
const isServerRuntime = String(import.meta.env
|
|
11
|
+
const isServerRuntime = String(import.meta.env?.SSR) === 'true' || typeof window === 'undefined'
|
|
12
12
|
|
|
13
13
|
let sqlite3Promise: ReturnType<typeof loadSqlite3Wasm> | undefined
|
|
14
14
|
|
|
@@ -65,7 +65,7 @@ export class LeaderWorkerInnerInitialMessage extends Schema.TaggedRequest<Leader
|
|
|
65
65
|
storeId: Schema.String,
|
|
66
66
|
clientId: Schema.String,
|
|
67
67
|
debugInstanceId: Schema.String,
|
|
68
|
-
|
|
68
|
+
syncPayloadEncoded: Schema.UndefinedOr(Schema.JsonValue),
|
|
69
69
|
},
|
|
70
70
|
success: Schema.Void,
|
|
71
71
|
failure: UnexpectedError,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
LogLevel,
|
|
20
20
|
OtelTracer,
|
|
21
21
|
Scheduler,
|
|
22
|
+
type Schema,
|
|
22
23
|
Stream,
|
|
23
24
|
TaskTracing,
|
|
24
25
|
WorkerRunner,
|
|
@@ -33,6 +34,7 @@ import * as WorkerSchema from '../common/worker-schema.ts'
|
|
|
33
34
|
export type WorkerOptions = {
|
|
34
35
|
schema: LiveStoreSchema
|
|
35
36
|
sync?: SyncOptions
|
|
37
|
+
syncPayloadSchema?: Schema.Schema<any>
|
|
36
38
|
otelOptions?: {
|
|
37
39
|
tracer?: otel.Tracer
|
|
38
40
|
}
|
|
@@ -102,9 +104,9 @@ const makeWorkerRunnerOuter = (
|
|
|
102
104
|
}).pipe(Effect.withSpan('@livestore/adapter-web:worker:wrapper:InitialMessage'), Layer.unwrapScoped),
|
|
103
105
|
})
|
|
104
106
|
|
|
105
|
-
const makeWorkerRunnerInner = ({ schema, sync: syncOptions }: WorkerOptions) =>
|
|
107
|
+
const makeWorkerRunnerInner = ({ schema, sync: syncOptions, syncPayloadSchema }: WorkerOptions) =>
|
|
106
108
|
WorkerRunner.layerSerialized(WorkerSchema.LeaderWorkerInnerRequest, {
|
|
107
|
-
InitialMessage: ({ storageOptions, storeId, clientId, devtoolsEnabled, debugInstanceId,
|
|
109
|
+
InitialMessage: ({ storageOptions, storeId, clientId, devtoolsEnabled, debugInstanceId, syncPayloadEncoded }) =>
|
|
108
110
|
Effect.gen(function* () {
|
|
109
111
|
const sqlite3 = yield* Effect.promise(() => loadSqlite3Wasm())
|
|
110
112
|
const makeSqliteDb = sqliteDbFactory({ sqlite3 })
|
|
@@ -154,7 +156,8 @@ const makeWorkerRunnerInner = ({ schema, sync: syncOptions }: WorkerOptions) =>
|
|
|
154
156
|
dbEventlog,
|
|
155
157
|
devtoolsOptions,
|
|
156
158
|
shutdownChannel,
|
|
157
|
-
|
|
159
|
+
syncPayloadEncoded,
|
|
160
|
+
syncPayloadSchema,
|
|
158
161
|
})
|
|
159
162
|
}).pipe(
|
|
160
163
|
Effect.tapCauseLogPretty,
|
|
@@ -163,7 +163,7 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
163
163
|
const InvariantsSchema = Schema.Struct({
|
|
164
164
|
storeId: Schema.String,
|
|
165
165
|
storageOptions: WorkerSchema.StorageType,
|
|
166
|
-
|
|
166
|
+
syncPayloadEncoded: Schema.UndefinedOr(Schema.JsonValue),
|
|
167
167
|
liveStoreVersion: Schema.Literal(liveStoreVersion),
|
|
168
168
|
devtoolsEnabled: Schema.Boolean,
|
|
169
169
|
})
|
|
@@ -176,11 +176,11 @@ const makeWorkerRunner = Effect.gen(function* () {
|
|
|
176
176
|
// sends a new MessagePort to the shared worker which proxies messages to the new leader thread.
|
|
177
177
|
UpdateMessagePort: ({ port, initial, liveStoreVersion: clientLiveStoreVersion }) =>
|
|
178
178
|
Effect.gen(function* () {
|
|
179
|
-
// Enforce invariants: storeId, storageOptions,
|
|
179
|
+
// Enforce invariants: storeId, storageOptions, syncPayloadEncoded, liveStoreVersion must remain stable
|
|
180
180
|
const invariants: Invariants = {
|
|
181
181
|
storeId: initial.storeId,
|
|
182
182
|
storageOptions: initial.storageOptions,
|
|
183
|
-
|
|
183
|
+
syncPayloadEncoded: initial.syncPayloadEncoded,
|
|
184
184
|
liveStoreVersion: clientLiveStoreVersion,
|
|
185
185
|
devtoolsEnabled: initial.devtoolsEnabled,
|
|
186
186
|
}
|