@livestore/adapter-node 0.0.0-snapshot-54e706b7e73bd685653cd43e1e34a02c1d8054a2 → 0.0.0-snapshot-412a36a7e6c9b0e9e237b553fd0522aed285228f.1
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/client-session/adapter.d.ts +44 -0
- package/dist/client-session/adapter.d.ts.map +1 -0
- package/dist/client-session/adapter.js +199 -0
- package/dist/client-session/adapter.js.map +1 -0
- package/dist/client-session/in-memory-adapter.d.ts +145 -10
- package/dist/client-session/in-memory-adapter.d.ts.map +1 -1
- package/dist/client-session/in-memory-adapter.js +2 -3
- package/dist/client-session/in-memory-adapter.js.map +1 -1
- package/dist/client-session/persisted-adapter.d.ts +26 -14
- package/dist/client-session/persisted-adapter.d.ts.map +1 -1
- package/dist/client-session/persisted-adapter.js +81 -24
- package/dist/client-session/persisted-adapter.js.map +1 -1
- package/dist/devtools/devtools-server.d.ts.map +1 -1
- package/dist/devtools/devtools-server.js +3 -1
- package/dist/devtools/devtools-server.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/leader-shared.d.ts +29 -0
- package/dist/leader-shared.d.ts.map +1 -0
- package/dist/leader-shared.js +87 -0
- package/dist/leader-shared.js.map +1 -0
- package/dist/leader-thread-lazy.js +4 -0
- package/dist/leader-thread-lazy.js.map +1 -1
- package/dist/leader-thread-shared.d.ts +29 -0
- package/dist/leader-thread-shared.d.ts.map +1 -0
- package/dist/leader-thread-shared.js +88 -0
- package/dist/leader-thread-shared.js.map +1 -0
- package/dist/make-leader-worker.d.ts +5 -1
- package/dist/make-leader-worker.d.ts.map +1 -1
- package/dist/make-leader-worker.js +14 -81
- package/dist/make-leader-worker.js.map +1 -1
- package/dist/shutdown-channel.d.ts +1 -1
- package/dist/worker-schema.d.ts +35 -19
- package/dist/worker-schema.d.ts.map +1 -1
- package/dist/worker-schema.js +14 -19
- package/dist/worker-schema.js.map +1 -1
- package/package.json +6 -10
- package/src/client-session/{persisted-adapter.ts → adapter.ts} +190 -57
- package/src/devtools/devtools-server.ts +3 -0
- package/src/index.ts +1 -2
- package/src/leader-thread-lazy.ts +5 -0
- package/src/leader-thread-shared.ts +167 -0
- package/src/make-leader-worker.ts +20 -138
- package/src/worker-schema.ts +23 -26
- package/src/client-session/in-memory-adapter.ts +0 -169
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import './thread-polyfill.js'
|
|
2
2
|
|
|
3
3
|
import inspector from 'node:inspector'
|
|
4
|
-
import path from 'node:path'
|
|
5
4
|
|
|
6
5
|
if (process.execArgv.includes('--inspect')) {
|
|
7
6
|
inspector.open()
|
|
@@ -9,15 +8,12 @@ if (process.execArgv.includes('--inspect')) {
|
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
import type { SyncOptions } from '@livestore/common'
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import { configureConnection, Eventlog, LeaderThreadCtx, makeLeaderThreadLayer } from '@livestore/common/leader-thread'
|
|
11
|
+
import { UnexpectedError } from '@livestore/common'
|
|
12
|
+
import { Eventlog, LeaderThreadCtx } from '@livestore/common/leader-thread'
|
|
15
13
|
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
16
14
|
import { LiveStoreEvent } from '@livestore/common/schema'
|
|
17
|
-
import { makeNodeDevtoolsChannel } from '@livestore/devtools-node-common/web-channel'
|
|
18
15
|
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
19
16
|
import { sqliteDbFactory } from '@livestore/sqlite-wasm/node'
|
|
20
|
-
import type { FileSystem, HttpClient, Scope } from '@livestore/utils/effect'
|
|
21
17
|
import {
|
|
22
18
|
Effect,
|
|
23
19
|
FetchHttpClient,
|
|
@@ -33,17 +29,19 @@ import {
|
|
|
33
29
|
import { PlatformNode } from '@livestore/utils/node'
|
|
34
30
|
import type * as otel from '@opentelemetry/api'
|
|
35
31
|
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
32
|
+
import type { TestingOverrides } from './leader-thread-shared.js'
|
|
33
|
+
import { makeLeaderThread } from './leader-thread-shared.js'
|
|
38
34
|
import * as WorkerSchema from './worker-schema.js'
|
|
39
35
|
|
|
40
36
|
export type WorkerOptions = {
|
|
37
|
+
schema: LiveStoreSchema
|
|
41
38
|
sync?: SyncOptions
|
|
42
39
|
otelOptions?: {
|
|
43
40
|
tracer?: otel.Tracer
|
|
44
41
|
/** @default 'livestore-node-leader-thread' */
|
|
45
42
|
serviceName?: string
|
|
46
43
|
}
|
|
44
|
+
testing?: TestingOverrides
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
export const getWorkerArgs = () => Schema.decodeSync(WorkerSchema.WorkerArgv)(process.argv[2]!)
|
|
@@ -60,7 +58,20 @@ export const makeWorkerEffect = (options: WorkerOptions) => {
|
|
|
60
58
|
: undefined
|
|
61
59
|
|
|
62
60
|
return WorkerRunner.layerSerialized(WorkerSchema.LeaderWorkerInner.Request, {
|
|
63
|
-
InitialMessage: (args) =>
|
|
61
|
+
InitialMessage: (args) =>
|
|
62
|
+
Effect.gen(function* () {
|
|
63
|
+
const sqlite3 = yield* Effect.promise(() => loadSqlite3Wasm()).pipe(
|
|
64
|
+
Effect.withSpan('@livestore/adapter-node:leader-thread:loadSqlite3Wasm'),
|
|
65
|
+
)
|
|
66
|
+
const makeSqliteDb = yield* sqliteDbFactory({ sqlite3 })
|
|
67
|
+
return yield* makeLeaderThread({
|
|
68
|
+
...args,
|
|
69
|
+
syncOptions: options.sync,
|
|
70
|
+
schema: options.schema,
|
|
71
|
+
testing: options.testing,
|
|
72
|
+
makeSqliteDb,
|
|
73
|
+
})
|
|
74
|
+
}).pipe(Layer.unwrapScoped),
|
|
64
75
|
PushToLeader: ({ batch }) =>
|
|
65
76
|
Effect.andThen(LeaderThreadCtx, (_) =>
|
|
66
77
|
_.syncProcessor.push(
|
|
@@ -149,132 +160,3 @@ export const makeWorkerEffect = (options: WorkerOptions) => {
|
|
|
149
160
|
Logger.withMinimumLogLevel(LogLevel.Debug),
|
|
150
161
|
)
|
|
151
162
|
}
|
|
152
|
-
|
|
153
|
-
const makeLeaderThread = ({
|
|
154
|
-
storeId,
|
|
155
|
-
clientId,
|
|
156
|
-
syncOptions,
|
|
157
|
-
baseDirectory,
|
|
158
|
-
devtools,
|
|
159
|
-
schemaPath,
|
|
160
|
-
syncPayload,
|
|
161
|
-
}: WorkerSchema.LeaderWorkerInner.InitialMessage & {
|
|
162
|
-
syncOptions: SyncOptions | undefined
|
|
163
|
-
schemaPath: string
|
|
164
|
-
}): Layer.Layer<LeaderThreadCtx, UnexpectedError, Scope.Scope | HttpClient.HttpClient | FileSystem.FileSystem> =>
|
|
165
|
-
Effect.gen(function* () {
|
|
166
|
-
const schema = yield* Effect.promise(() => import(schemaPath).then((m) => m.schema as LiveStoreSchema))
|
|
167
|
-
|
|
168
|
-
const sqlite3 = yield* Effect.promise(() => loadSqlite3Wasm()).pipe(
|
|
169
|
-
Effect.withSpan('@livestore/adapter-node:leader-thread:loadSqlite3Wasm'),
|
|
170
|
-
)
|
|
171
|
-
const makeSqliteDb = yield* sqliteDbFactory({ sqlite3 })
|
|
172
|
-
const runtime = yield* Effect.runtime<never>()
|
|
173
|
-
|
|
174
|
-
const schemaHashSuffix =
|
|
175
|
-
schema.state.sqlite.migrations.strategy === 'manual' ? 'fixed' : schema.state.sqlite.hash.toString()
|
|
176
|
-
|
|
177
|
-
const makeDb = (kind: 'state' | 'eventlog') =>
|
|
178
|
-
makeSqliteDb({
|
|
179
|
-
_tag: 'fs',
|
|
180
|
-
directory: path.join(baseDirectory ?? '', storeId),
|
|
181
|
-
fileName:
|
|
182
|
-
kind === 'state' ? getStateDbFileName(schemaHashSuffix) : `eventlog@${liveStoreStorageFormatVersion}.db`,
|
|
183
|
-
// TODO enable WAL for nodejs
|
|
184
|
-
configureDb: (db) =>
|
|
185
|
-
configureConnection(db, { foreignKeys: true }).pipe(Effect.provide(runtime), Effect.runSync),
|
|
186
|
-
}).pipe(Effect.acquireRelease((db) => Effect.sync(() => db.close())))
|
|
187
|
-
|
|
188
|
-
// Might involve some async work, so we're running them concurrently
|
|
189
|
-
const [dbState, dbEventlog] = yield* Effect.all([makeDb('state'), makeDb('eventlog')], { concurrency: 2 })
|
|
190
|
-
|
|
191
|
-
const devtoolsOptions = yield* makeDevtoolsOptions({
|
|
192
|
-
devtoolsEnabled: devtools.enabled,
|
|
193
|
-
devtoolsPort: devtools.port,
|
|
194
|
-
devtoolsHost: devtools.host,
|
|
195
|
-
dbState,
|
|
196
|
-
dbEventlog,
|
|
197
|
-
storeId,
|
|
198
|
-
clientId,
|
|
199
|
-
schemaPath,
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
const shutdownChannel = yield* makeShutdownChannel(storeId)
|
|
203
|
-
|
|
204
|
-
return makeLeaderThreadLayer({
|
|
205
|
-
schema,
|
|
206
|
-
storeId,
|
|
207
|
-
clientId,
|
|
208
|
-
makeSqliteDb,
|
|
209
|
-
syncOptions,
|
|
210
|
-
dbState,
|
|
211
|
-
dbEventlog,
|
|
212
|
-
devtoolsOptions,
|
|
213
|
-
shutdownChannel,
|
|
214
|
-
syncPayload,
|
|
215
|
-
})
|
|
216
|
-
}).pipe(
|
|
217
|
-
Effect.tapCauseLogPretty,
|
|
218
|
-
UnexpectedError.mapToUnexpectedError,
|
|
219
|
-
Effect.withSpan('@livestore/adapter-node:worker:InitialMessage'),
|
|
220
|
-
Layer.unwrapScoped,
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
const getStateDbFileName = (suffix: string) => `state${suffix}@${liveStoreStorageFormatVersion}.db`
|
|
224
|
-
|
|
225
|
-
const makeDevtoolsOptions = ({
|
|
226
|
-
devtoolsEnabled,
|
|
227
|
-
dbState,
|
|
228
|
-
dbEventlog,
|
|
229
|
-
storeId,
|
|
230
|
-
clientId,
|
|
231
|
-
devtoolsPort,
|
|
232
|
-
devtoolsHost,
|
|
233
|
-
schemaPath,
|
|
234
|
-
}: {
|
|
235
|
-
devtoolsEnabled: boolean
|
|
236
|
-
dbState: LeaderSqliteDb
|
|
237
|
-
dbEventlog: LeaderSqliteDb
|
|
238
|
-
storeId: string
|
|
239
|
-
clientId: string
|
|
240
|
-
devtoolsPort: number
|
|
241
|
-
devtoolsHost: string
|
|
242
|
-
schemaPath: string
|
|
243
|
-
}): Effect.Effect<DevtoolsOptions, UnexpectedError, Scope.Scope> =>
|
|
244
|
-
Effect.gen(function* () {
|
|
245
|
-
if (devtoolsEnabled === false) {
|
|
246
|
-
return {
|
|
247
|
-
enabled: false,
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return {
|
|
252
|
-
enabled: true,
|
|
253
|
-
makeBootContext: Effect.gen(function* () {
|
|
254
|
-
// TODO instead of failing when the port is already in use, we should try to use that WS server instead of starting a new one
|
|
255
|
-
yield* startDevtoolsServer({
|
|
256
|
-
schemaPath,
|
|
257
|
-
storeId,
|
|
258
|
-
clientId,
|
|
259
|
-
sessionId: 'static', // TODO make this dynamic
|
|
260
|
-
port: devtoolsPort,
|
|
261
|
-
host: devtoolsHost,
|
|
262
|
-
}).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
|
|
263
|
-
|
|
264
|
-
const devtoolsWebChannel = yield* makeNodeDevtoolsChannel({
|
|
265
|
-
nodeName: `leader-${storeId}-${clientId}`,
|
|
266
|
-
target: `devtools-${storeId}-${clientId}-static`,
|
|
267
|
-
url: `ws://localhost:${devtoolsPort}`,
|
|
268
|
-
schema: { listen: Devtools.Leader.MessageToApp, send: Devtools.Leader.MessageFromApp },
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
return {
|
|
272
|
-
devtoolsWebChannel,
|
|
273
|
-
persistenceInfo: {
|
|
274
|
-
state: dbState.metadata.persistenceInfo,
|
|
275
|
-
eventlog: dbEventlog.metadata.persistenceInfo,
|
|
276
|
-
},
|
|
277
|
-
}
|
|
278
|
-
}).pipe(Effect.provide(FetchHttpClient.layer)),
|
|
279
|
-
}
|
|
280
|
-
})
|
package/src/worker-schema.ts
CHANGED
|
@@ -18,31 +18,25 @@ export const WorkerArgv = Schema.parseJson(
|
|
|
18
18
|
}),
|
|
19
19
|
)
|
|
20
20
|
|
|
21
|
-
export const
|
|
22
|
-
type: Schema.Literal('
|
|
21
|
+
export const StorageTypeInMemory = Schema.Struct({
|
|
22
|
+
type: Schema.Literal('in-memory'),
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
export type StorageTypeInMemory = typeof StorageTypeInMemory.Type
|
|
26
|
+
|
|
27
|
+
export const StorageTypeFs = Schema.Struct({
|
|
28
|
+
type: Schema.Literal('fs'),
|
|
23
29
|
/**
|
|
24
|
-
*
|
|
30
|
+
* Where to store the database files
|
|
25
31
|
*
|
|
26
|
-
*
|
|
27
|
-
* conflicts with other LiveStore apps.
|
|
32
|
+
* @default Current working directory
|
|
28
33
|
*/
|
|
29
|
-
|
|
34
|
+
baseDirectory: Schema.String,
|
|
30
35
|
})
|
|
31
36
|
|
|
32
|
-
export type
|
|
37
|
+
export type StorageTypeFs = typeof StorageTypeFs.Type
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
// type: Schema.Literal('indexeddb'),
|
|
36
|
-
// /** @default "livestore" */
|
|
37
|
-
// databaseName: Schema.optionalWith(Schema.String, { default: () => 'livestore' }),
|
|
38
|
-
// /** @default "livestore-" */
|
|
39
|
-
// storeNamePrefix: Schema.optionalWith(Schema.String, { default: () => 'livestore-' }),
|
|
40
|
-
// })
|
|
41
|
-
|
|
42
|
-
export const StorageType = Schema.Union(
|
|
43
|
-
StorageTypeOpfs,
|
|
44
|
-
// StorageTypeIndexeddb
|
|
45
|
-
)
|
|
39
|
+
export const StorageType = Schema.Union(StorageTypeInMemory, StorageTypeFs)
|
|
46
40
|
export type StorageType = typeof StorageType.Type
|
|
47
41
|
export type StorageTypeEncoded = typeof StorageType.Encoded
|
|
48
42
|
|
|
@@ -71,14 +65,17 @@ export namespace LeaderWorkerInner {
|
|
|
71
65
|
payload: {
|
|
72
66
|
storeId: Schema.String,
|
|
73
67
|
clientId: Schema.String,
|
|
74
|
-
|
|
75
|
-
schemaPath: Schema.String,
|
|
68
|
+
storage: StorageType,
|
|
76
69
|
syncPayload: Schema.UndefinedOr(Schema.JsonValue),
|
|
77
|
-
devtools: Schema.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
devtools: Schema.Union(
|
|
71
|
+
Schema.Struct({
|
|
72
|
+
enabled: Schema.Literal(true),
|
|
73
|
+
schemaPath: Schema.String,
|
|
74
|
+
port: Schema.Number,
|
|
75
|
+
host: Schema.String,
|
|
76
|
+
}),
|
|
77
|
+
Schema.Struct({ enabled: Schema.Literal(false) }),
|
|
78
|
+
),
|
|
82
79
|
},
|
|
83
80
|
success: Schema.Void,
|
|
84
81
|
failure: UnexpectedError,
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Adapter,
|
|
3
|
-
ClientSession,
|
|
4
|
-
ClientSessionLeaderThreadProxy,
|
|
5
|
-
LockStatus,
|
|
6
|
-
MakeSqliteDb,
|
|
7
|
-
SqliteDb,
|
|
8
|
-
SyncOptions,
|
|
9
|
-
} from '@livestore/common'
|
|
10
|
-
import { UnexpectedError } from '@livestore/common'
|
|
11
|
-
import { Eventlog, LeaderThreadCtx, makeLeaderThreadLayer } from '@livestore/common/leader-thread'
|
|
12
|
-
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
13
|
-
import { LiveStoreEvent } from '@livestore/common/schema'
|
|
14
|
-
import { sqliteDbFactory } from '@livestore/sqlite-wasm/browser'
|
|
15
|
-
import { loadSqlite3Wasm } from '@livestore/sqlite-wasm/load-wasm'
|
|
16
|
-
import type { Schema } from '@livestore/utils/effect'
|
|
17
|
-
import { Cause, Effect, FetchHttpClient, Layer, Stream, SubscriptionRef } from '@livestore/utils/effect'
|
|
18
|
-
import { nanoid } from '@livestore/utils/nanoid'
|
|
19
|
-
|
|
20
|
-
import { makeShutdownChannel } from '../shutdown-channel.js'
|
|
21
|
-
|
|
22
|
-
// TODO unify in-memory adapter with other in-memory adapter implementations
|
|
23
|
-
|
|
24
|
-
export interface InMemoryAdapterOptions {
|
|
25
|
-
sync?: SyncOptions
|
|
26
|
-
/**
|
|
27
|
-
* @default 'in-memory'
|
|
28
|
-
*/
|
|
29
|
-
clientId?: string
|
|
30
|
-
/**
|
|
31
|
-
* @default nanoid(6)
|
|
32
|
-
*/
|
|
33
|
-
sessionId?: string
|
|
34
|
-
|
|
35
|
-
/** Only used internally for testing */
|
|
36
|
-
testing?: {
|
|
37
|
-
overrides?: TestingOverrides
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export type TestingOverrides = {
|
|
42
|
-
clientSession?: {
|
|
43
|
-
leaderThreadProxy?: Partial<ClientSessionLeaderThreadProxy>
|
|
44
|
-
}
|
|
45
|
-
makeLeaderThread?: {
|
|
46
|
-
dbEventlog?: (makeSqliteDb: MakeSqliteDb) => Effect.Effect<SqliteDb, UnexpectedError>
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** NOTE: This adapter is currently only used for testing */
|
|
51
|
-
export const makeInMemoryAdapter =
|
|
52
|
-
({ sync: syncOptions, clientId = 'in-memory', sessionId = nanoid(6), testing }: InMemoryAdapterOptions): Adapter =>
|
|
53
|
-
({
|
|
54
|
-
schema,
|
|
55
|
-
storeId,
|
|
56
|
-
shutdown,
|
|
57
|
-
syncPayload,
|
|
58
|
-
// devtoolsEnabled, bootStatusQueue, shutdown, connectDevtoolsToStore
|
|
59
|
-
}) =>
|
|
60
|
-
Effect.gen(function* () {
|
|
61
|
-
const sqlite3 = yield* Effect.promise(() => loadSqlite3Wasm())
|
|
62
|
-
|
|
63
|
-
const makeSqliteDb = sqliteDbFactory({ sqlite3 })
|
|
64
|
-
const sqliteDb = yield* makeSqliteDb({ _tag: 'in-memory' })
|
|
65
|
-
|
|
66
|
-
const lockStatus = yield* SubscriptionRef.make<LockStatus>('has-lock')
|
|
67
|
-
|
|
68
|
-
const shutdownChannel = yield* makeShutdownChannel(storeId)
|
|
69
|
-
|
|
70
|
-
yield* shutdownChannel.listen.pipe(
|
|
71
|
-
Stream.flatten(),
|
|
72
|
-
Stream.tap((error) => Effect.sync(() => shutdown(Cause.fail(error)))),
|
|
73
|
-
Stream.runDrain,
|
|
74
|
-
Effect.interruptible,
|
|
75
|
-
Effect.tapCauseLogPretty,
|
|
76
|
-
Effect.forkScoped,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
const { leaderThread, initialSnapshot } = yield* makeLeaderThread({
|
|
80
|
-
storeId,
|
|
81
|
-
clientId,
|
|
82
|
-
schema,
|
|
83
|
-
makeSqliteDb,
|
|
84
|
-
syncOptions,
|
|
85
|
-
syncPayload,
|
|
86
|
-
testing,
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
sqliteDb.import(initialSnapshot)
|
|
90
|
-
|
|
91
|
-
const clientSession = {
|
|
92
|
-
sqliteDb,
|
|
93
|
-
devtools: { enabled: false },
|
|
94
|
-
clientId,
|
|
95
|
-
sessionId,
|
|
96
|
-
lockStatus,
|
|
97
|
-
leaderThread,
|
|
98
|
-
shutdown,
|
|
99
|
-
} satisfies ClientSession
|
|
100
|
-
|
|
101
|
-
return clientSession
|
|
102
|
-
}).pipe(UnexpectedError.mapToUnexpectedError)
|
|
103
|
-
|
|
104
|
-
const makeLeaderThread = ({
|
|
105
|
-
storeId,
|
|
106
|
-
clientId,
|
|
107
|
-
schema,
|
|
108
|
-
makeSqliteDb,
|
|
109
|
-
syncOptions,
|
|
110
|
-
syncPayload,
|
|
111
|
-
testing,
|
|
112
|
-
}: {
|
|
113
|
-
storeId: string
|
|
114
|
-
clientId: string
|
|
115
|
-
schema: LiveStoreSchema
|
|
116
|
-
makeSqliteDb: MakeSqliteDb
|
|
117
|
-
syncOptions: SyncOptions | undefined
|
|
118
|
-
syncPayload: Schema.JsonValue | undefined
|
|
119
|
-
testing?: {
|
|
120
|
-
overrides?: TestingOverrides
|
|
121
|
-
}
|
|
122
|
-
}) =>
|
|
123
|
-
Effect.gen(function* () {
|
|
124
|
-
const layer = yield* Layer.memoize(
|
|
125
|
-
makeLeaderThreadLayer({
|
|
126
|
-
clientId,
|
|
127
|
-
dbState: yield* makeSqliteDb({ _tag: 'in-memory' }),
|
|
128
|
-
dbEventlog: testing?.overrides?.makeLeaderThread?.dbEventlog
|
|
129
|
-
? yield* testing.overrides.makeLeaderThread.dbEventlog(makeSqliteDb)
|
|
130
|
-
: yield* makeSqliteDb({ _tag: 'in-memory' }),
|
|
131
|
-
devtoolsOptions: { enabled: false },
|
|
132
|
-
makeSqliteDb,
|
|
133
|
-
schema,
|
|
134
|
-
// NOTE we're creating a separate channel here since you can't listen to your own channel messages
|
|
135
|
-
shutdownChannel: yield* makeShutdownChannel(storeId),
|
|
136
|
-
storeId,
|
|
137
|
-
syncOptions,
|
|
138
|
-
syncPayload,
|
|
139
|
-
}).pipe(Layer.provideMerge(FetchHttpClient.layer)),
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
return yield* Effect.gen(function* () {
|
|
143
|
-
const { dbState, dbEventlog, syncProcessor, extraIncomingMessagesQueue, initialState } = yield* LeaderThreadCtx
|
|
144
|
-
|
|
145
|
-
const initialLeaderHead = Eventlog.getClientHeadFromDb(dbEventlog)
|
|
146
|
-
|
|
147
|
-
const leaderThread = {
|
|
148
|
-
events: {
|
|
149
|
-
pull:
|
|
150
|
-
testing?.overrides?.clientSession?.leaderThreadProxy?.events?.pull ??
|
|
151
|
-
(({ cursor }) => syncProcessor.pull({ cursor })),
|
|
152
|
-
push: (batch) =>
|
|
153
|
-
syncProcessor.push(
|
|
154
|
-
batch.map((item) => new LiveStoreEvent.EncodedWithMeta(item)),
|
|
155
|
-
{ waitForProcessing: true },
|
|
156
|
-
),
|
|
157
|
-
},
|
|
158
|
-
initialState: { leaderHead: initialLeaderHead, migrationsReport: initialState.migrationsReport },
|
|
159
|
-
export: Effect.sync(() => dbState.export()),
|
|
160
|
-
getEventlogData: Effect.sync(() => dbEventlog.export()),
|
|
161
|
-
getSyncState: syncProcessor.syncState,
|
|
162
|
-
sendDevtoolsMessage: (message) => extraIncomingMessagesQueue.offer(message),
|
|
163
|
-
} satisfies ClientSessionLeaderThreadProxy
|
|
164
|
-
|
|
165
|
-
const initialSnapshot = dbState.export()
|
|
166
|
-
|
|
167
|
-
return { leaderThread, initialSnapshot }
|
|
168
|
-
}).pipe(Effect.provide(layer))
|
|
169
|
-
})
|