@livestore/adapter-node 0.3.2-dev.0 → 0.3.2-dev.5
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 +3 -3
- package/dist/client-session/adapter.d.ts.map +1 -1
- package/dist/client-session/adapter.js +14 -22
- package/dist/client-session/adapter.js.map +1 -1
- package/dist/devtools/devtools-server.d.ts +1 -1
- package/dist/devtools/devtools-server.d.ts.map +1 -1
- package/dist/devtools/devtools-server.js +6 -4
- package/dist/devtools/devtools-server.js.map +1 -1
- package/dist/devtools/mod.d.ts +3 -3
- package/dist/devtools/mod.d.ts.map +1 -1
- package/dist/devtools/mod.js +2 -2
- package/dist/devtools/mod.js.map +1 -1
- package/dist/devtools/vite-dev-server.d.ts +1 -1
- package/dist/devtools/vite-dev-server.d.ts.map +1 -1
- package/dist/devtools/vite-dev-server.js +4 -1
- package/dist/devtools/vite-dev-server.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/leader-thread-lazy.js +1 -1
- package/dist/leader-thread-shared.d.ts +2 -2
- package/dist/leader-thread-shared.d.ts.map +1 -1
- package/dist/leader-thread-shared.js +2 -2
- package/dist/make-leader-worker.d.ts +2 -2
- package/dist/make-leader-worker.d.ts.map +1 -1
- package/dist/make-leader-worker.js +10 -6
- package/dist/make-leader-worker.js.map +1 -1
- package/dist/shutdown-channel.js +1 -1
- package/dist/webchannel.d.ts.map +1 -1
- package/dist/webchannel.js +0 -1
- package/dist/webchannel.js.map +1 -1
- package/dist/worker-schema.d.ts +163 -168
- package/dist/worker-schema.d.ts.map +1 -1
- package/dist/worker-schema.js +99 -118
- package/dist/worker-schema.js.map +1 -1
- package/package.json +7 -6
- package/src/client-session/adapter.ts +22 -37
- package/src/devtools/devtools-server.ts +7 -5
- package/src/devtools/mod.ts +3 -3
- package/src/devtools/vite-dev-server.ts +5 -2
- package/src/index.ts +1 -1
- package/src/leader-thread-lazy.ts +1 -1
- package/src/leader-thread-shared.ts +5 -5
- package/src/make-leader-worker.ts +12 -7
- package/src/shutdown-channel.ts +1 -1
- package/src/webchannel.ts +0 -1
- package/src/worker-schema.ts +85 -62
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/adapter-node",
|
|
3
|
-
"version": "0.3.2-dev.
|
|
3
|
+
"version": "0.3.2-dev.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
|
+
"bun": "./src/index.ts",
|
|
9
10
|
"default": "./dist/index.js"
|
|
10
11
|
},
|
|
11
12
|
"./devtools": {
|
|
@@ -26,13 +27,13 @@
|
|
|
26
27
|
}
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"@livestore/devtools-vite": "0.3.2-dev.
|
|
30
|
+
"@livestore/devtools-vite": "0.3.2-dev.5",
|
|
30
31
|
"@opentelemetry/api": "1.9.0",
|
|
31
32
|
"vite": "7.0.0",
|
|
32
|
-
"@livestore/common": "0.3.2-dev.
|
|
33
|
-
"@livestore/sqlite-wasm": "0.3.2-dev.
|
|
34
|
-
"@livestore/
|
|
35
|
-
"@livestore/
|
|
33
|
+
"@livestore/common": "0.3.2-dev.5",
|
|
34
|
+
"@livestore/sqlite-wasm": "0.3.2-dev.5",
|
|
35
|
+
"@livestore/utils": "0.3.2-dev.5",
|
|
36
|
+
"@livestore/webmesh": "0.3.2-dev.5"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@rollup/plugin-commonjs": "^28.0.3",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { hostname } from 'node:os'
|
|
2
2
|
import * as WT from 'node:worker_threads'
|
|
3
|
-
|
|
4
3
|
import {
|
|
5
4
|
type Adapter,
|
|
6
5
|
type BootStatus,
|
|
@@ -8,9 +7,10 @@ import {
|
|
|
8
7
|
type IntentionalShutdownCause,
|
|
9
8
|
type LockStatus,
|
|
10
9
|
type MakeSqliteDb,
|
|
10
|
+
makeClientSession,
|
|
11
11
|
type SyncOptions,
|
|
12
|
+
UnexpectedError,
|
|
12
13
|
} from '@livestore/common'
|
|
13
|
-
import { makeClientSession, UnexpectedError } from '@livestore/common'
|
|
14
14
|
import { Eventlog, LeaderThreadCtx } from '@livestore/common/leader-thread'
|
|
15
15
|
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
16
16
|
import { LiveStoreEvent } from '@livestore/common/schema'
|
|
@@ -33,10 +33,10 @@ import {
|
|
|
33
33
|
import { PlatformNode } from '@livestore/utils/node'
|
|
34
34
|
import * as Webmesh from '@livestore/webmesh'
|
|
35
35
|
|
|
36
|
-
import type { TestingOverrides } from '../leader-thread-shared.
|
|
37
|
-
import { makeLeaderThread } from '../leader-thread-shared.
|
|
38
|
-
import { makeShutdownChannel } from '../shutdown-channel.
|
|
39
|
-
import * as WorkerSchema from '../worker-schema.
|
|
36
|
+
import type { TestingOverrides } from '../leader-thread-shared.ts'
|
|
37
|
+
import { makeLeaderThread } from '../leader-thread-shared.ts'
|
|
38
|
+
import { makeShutdownChannel } from '../shutdown-channel.ts'
|
|
39
|
+
import * as WorkerSchema from '../worker-schema.ts'
|
|
40
40
|
|
|
41
41
|
export interface NodeAdapterOptions {
|
|
42
42
|
storage: WorkerSchema.StorageType
|
|
@@ -90,7 +90,7 @@ export const makeWorkerAdapter = ({
|
|
|
90
90
|
...options
|
|
91
91
|
}: NodeAdapterOptions & {
|
|
92
92
|
/**
|
|
93
|
-
* Example: `new URL('./livestore.worker.
|
|
93
|
+
* Example: `new URL('./livestore.worker.ts', import.meta.url)`
|
|
94
94
|
*/
|
|
95
95
|
workerUrl: URL
|
|
96
96
|
}): Adapter => makeAdapterImpl({ ...options, leaderThread: { _tag: 'multi-threaded', workerUrl } })
|
|
@@ -147,7 +147,7 @@ const makeAdapterImpl = ({
|
|
|
147
147
|
// TODO actually implement this multi-session support
|
|
148
148
|
const lockStatus = yield* SubscriptionRef.make<LockStatus>('has-lock')
|
|
149
149
|
|
|
150
|
-
const devtoolsOptions: WorkerSchema.
|
|
150
|
+
const devtoolsOptions: WorkerSchema.LeaderWorkerInnerInitialMessage['devtools'] =
|
|
151
151
|
devtoolsEnabled && devtoolsOptionsInput !== undefined
|
|
152
152
|
? {
|
|
153
153
|
enabled: true,
|
|
@@ -215,7 +215,6 @@ const makeAdapterImpl = ({
|
|
|
215
215
|
return clientSession
|
|
216
216
|
}).pipe(
|
|
217
217
|
Effect.withSpan('@livestore/adapter-node:adapter'),
|
|
218
|
-
Effect.parallelFinalizers,
|
|
219
218
|
Effect.provide(PlatformNode.NodeFileSystem.layer),
|
|
220
219
|
Effect.provide(FetchHttpClient.layer),
|
|
221
220
|
)) satisfies Adapter
|
|
@@ -238,7 +237,7 @@ const makeLocalLeaderThread = ({
|
|
|
238
237
|
syncOptions: SyncOptions | undefined
|
|
239
238
|
storage: WorkerSchema.StorageType
|
|
240
239
|
syncPayload: Schema.JsonValue | undefined
|
|
241
|
-
devtools: WorkerSchema.
|
|
240
|
+
devtools: WorkerSchema.LeaderWorkerInnerInitialMessage['devtools']
|
|
242
241
|
testing?: {
|
|
243
242
|
overrides?: TestingOverrides
|
|
244
243
|
}
|
|
@@ -306,7 +305,7 @@ const makeWorkerLeaderThread = ({
|
|
|
306
305
|
sessionId: string
|
|
307
306
|
workerUrl: URL
|
|
308
307
|
storage: WorkerSchema.StorageType
|
|
309
|
-
devtools: WorkerSchema.
|
|
308
|
+
devtools: WorkerSchema.LeaderWorkerInnerInitialMessage['devtools']
|
|
310
309
|
bootStatusQueue: Queue.Queue<BootStatus>
|
|
311
310
|
syncPayload: Schema.JsonValue | undefined
|
|
312
311
|
testing?: {
|
|
@@ -320,11 +319,11 @@ const makeWorkerLeaderThread = ({
|
|
|
320
319
|
})
|
|
321
320
|
const nodeWorkerLayer = yield* Layer.build(PlatformNode.NodeWorker.layer(() => nodeWorker))
|
|
322
321
|
|
|
323
|
-
const worker = yield* Worker.makePoolSerialized<typeof WorkerSchema.
|
|
322
|
+
const worker = yield* Worker.makePoolSerialized<typeof WorkerSchema.LeaderWorkerInnerRequest.Type>({
|
|
324
323
|
size: 1,
|
|
325
324
|
concurrency: 100,
|
|
326
325
|
initialMessage: () =>
|
|
327
|
-
new WorkerSchema.
|
|
326
|
+
new WorkerSchema.LeaderWorkerInnerInitialMessage({
|
|
328
327
|
storeId,
|
|
329
328
|
clientId,
|
|
330
329
|
storage,
|
|
@@ -338,21 +337,7 @@ const makeWorkerLeaderThread = ({
|
|
|
338
337
|
Effect.withSpan('@livestore/adapter-node:adapter:setupLeaderThread'),
|
|
339
338
|
)
|
|
340
339
|
|
|
341
|
-
|
|
342
|
-
Effect.gen(function* () {
|
|
343
|
-
// We first try to gracefully shutdown the leader worker and then forcefully terminate it
|
|
344
|
-
yield* Effect.raceFirst(
|
|
345
|
-
runInWorker(new WorkerSchema.LeaderWorkerInner.Shutdown()).pipe(Effect.andThen(() => nodeWorker.terminate())),
|
|
346
|
-
|
|
347
|
-
Effect.sync(() => {
|
|
348
|
-
console.warn('[@livestore/adapter-node:adapter] Worker did not gracefully shutdown in time, terminating it')
|
|
349
|
-
nodeWorker.terminate()
|
|
350
|
-
}).pipe(Effect.delay(1000)),
|
|
351
|
-
).pipe(Effect.exit) // The disconnect is to prevent the interrupt to bubble out
|
|
352
|
-
}).pipe(Effect.withSpan('@livestore/adapter-node:adapter:shutdown'), Effect.tapCauseLogPretty, Effect.orDie),
|
|
353
|
-
)
|
|
354
|
-
|
|
355
|
-
const runInWorker = <TReq extends typeof WorkerSchema.LeaderWorkerInner.Request.Type>(
|
|
340
|
+
const runInWorker = <TReq extends typeof WorkerSchema.LeaderWorkerInnerRequest.Type>(
|
|
356
341
|
req: TReq,
|
|
357
342
|
): TReq extends Schema.WithResult<infer A, infer _I, infer _E, infer _EI, infer R>
|
|
358
343
|
? Effect.Effect<A, UnexpectedError, R>
|
|
@@ -373,7 +358,7 @@ const makeWorkerLeaderThread = ({
|
|
|
373
358
|
Effect.catchAllDefect((cause) => new UnexpectedError({ cause })),
|
|
374
359
|
) as any
|
|
375
360
|
|
|
376
|
-
const runInWorkerStream = <TReq extends typeof WorkerSchema.
|
|
361
|
+
const runInWorkerStream = <TReq extends typeof WorkerSchema.LeaderWorkerInnerRequest.Type>(
|
|
377
362
|
req: TReq,
|
|
378
363
|
): TReq extends Schema.WithResult<infer A, infer _I, infer _E, infer _EI, infer R>
|
|
379
364
|
? Stream.Stream<A, UnexpectedError, R>
|
|
@@ -389,7 +374,7 @@ const makeWorkerLeaderThread = ({
|
|
|
389
374
|
Stream.withSpan(`@livestore/adapter-node:client-session:runInWorkerStream:${req._tag}`),
|
|
390
375
|
) as any
|
|
391
376
|
|
|
392
|
-
const bootStatusFiber = yield* runInWorkerStream(new WorkerSchema.
|
|
377
|
+
const bootStatusFiber = yield* runInWorkerStream(new WorkerSchema.LeaderWorkerInnerBootStatusStream()).pipe(
|
|
393
378
|
Stream.tap((bootStatus) => Queue.offer(bootStatusQueue, bootStatus)),
|
|
394
379
|
Stream.runDrain,
|
|
395
380
|
Effect.tapErrorCause((cause) => (Cause.isInterruptedOnly(cause) ? Effect.void : shutdown(cause))),
|
|
@@ -404,9 +389,9 @@ const makeWorkerLeaderThread = ({
|
|
|
404
389
|
Effect.forkScoped,
|
|
405
390
|
)
|
|
406
391
|
|
|
407
|
-
const initialLeaderHead = yield* runInWorker(new WorkerSchema.
|
|
392
|
+
const initialLeaderHead = yield* runInWorker(new WorkerSchema.LeaderWorkerInnerGetLeaderHead())
|
|
408
393
|
|
|
409
|
-
const bootResult = yield* runInWorker(new WorkerSchema.
|
|
394
|
+
const bootResult = yield* runInWorker(new WorkerSchema.LeaderWorkerInnerGetRecreateSnapshot()).pipe(
|
|
410
395
|
Effect.timeout(10_000),
|
|
411
396
|
UnexpectedError.mapToUnexpectedError,
|
|
412
397
|
Effect.withSpan('@livestore/adapter-node:client-session:export'),
|
|
@@ -416,9 +401,9 @@ const makeWorkerLeaderThread = ({
|
|
|
416
401
|
{
|
|
417
402
|
events: {
|
|
418
403
|
pull: ({ cursor }) =>
|
|
419
|
-
runInWorkerStream(new WorkerSchema.
|
|
404
|
+
runInWorkerStream(new WorkerSchema.LeaderWorkerInnerPullStream({ cursor })).pipe(Stream.orDie),
|
|
420
405
|
push: (batch) =>
|
|
421
|
-
runInWorker(new WorkerSchema.
|
|
406
|
+
runInWorker(new WorkerSchema.LeaderWorkerInnerPushToLeader({ batch })).pipe(
|
|
422
407
|
Effect.withSpan('@livestore/adapter-node:client-session:pushToLeader', {
|
|
423
408
|
attributes: { batchSize: batch.length },
|
|
424
409
|
}),
|
|
@@ -428,18 +413,18 @@ const makeWorkerLeaderThread = ({
|
|
|
428
413
|
leaderHead: initialLeaderHead,
|
|
429
414
|
migrationsReport: bootResult.migrationsReport,
|
|
430
415
|
},
|
|
431
|
-
export: runInWorker(new WorkerSchema.
|
|
416
|
+
export: runInWorker(new WorkerSchema.LeaderWorkerInnerExport()).pipe(
|
|
432
417
|
Effect.timeout(10_000),
|
|
433
418
|
UnexpectedError.mapToUnexpectedError,
|
|
434
419
|
Effect.withSpan('@livestore/adapter-node:client-session:export'),
|
|
435
420
|
),
|
|
436
421
|
getEventlogData: Effect.dieMessage('Not implemented'),
|
|
437
|
-
getSyncState: runInWorker(new WorkerSchema.
|
|
422
|
+
getSyncState: runInWorker(new WorkerSchema.LeaderWorkerInnerGetLeaderSyncState()).pipe(
|
|
438
423
|
UnexpectedError.mapToUnexpectedError,
|
|
439
424
|
Effect.withSpan('@livestore/adapter-node:client-session:getLeaderSyncState'),
|
|
440
425
|
),
|
|
441
426
|
sendDevtoolsMessage: (message) =>
|
|
442
|
-
runInWorker(new WorkerSchema.
|
|
427
|
+
runInWorker(new WorkerSchema.LeaderWorkerInnerExtraDevtoolsMessage({ message })).pipe(
|
|
443
428
|
UnexpectedError.mapToUnexpectedError,
|
|
444
429
|
Effect.withSpan('@livestore/adapter-node:client-session:devtoolsMessageForLeader'),
|
|
445
430
|
),
|
|
@@ -2,7 +2,7 @@ import http from 'node:http'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
|
|
4
4
|
import type { Devtools } from '@livestore/common'
|
|
5
|
-
import { LS_DEV } from '@livestore/utils'
|
|
5
|
+
import { isReadonlyArray, LS_DEV } from '@livestore/utils'
|
|
6
6
|
import type { HttpClient } from '@livestore/utils/effect'
|
|
7
7
|
import {
|
|
8
8
|
Deferred,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { PlatformNode } from '@livestore/utils/node'
|
|
19
19
|
import { makeMeshNode, makeWebSocketEdge } from '@livestore/webmesh'
|
|
20
20
|
|
|
21
|
-
import { makeViteMiddleware } from './vite-dev-server.
|
|
21
|
+
import { makeViteMiddleware } from './vite-dev-server.ts'
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Starts a devtools HTTP/WS server which serves ...
|
|
@@ -31,7 +31,7 @@ export const startDevtoolsServer = ({
|
|
|
31
31
|
port,
|
|
32
32
|
host,
|
|
33
33
|
}: {
|
|
34
|
-
schemaPath: string
|
|
34
|
+
schemaPath: string | ReadonlyArray<string>
|
|
35
35
|
clientSessionInfo: Devtools.SessionInfo.SessionInfo | undefined
|
|
36
36
|
host: string
|
|
37
37
|
port: number
|
|
@@ -39,7 +39,9 @@ export const startDevtoolsServer = ({
|
|
|
39
39
|
Effect.gen(function* () {
|
|
40
40
|
const viteMiddleware = yield* makeViteMiddleware({
|
|
41
41
|
mode: { _tag: 'node', url: `http://${host}:${port}` },
|
|
42
|
-
schemaPath:
|
|
42
|
+
schemaPath: isReadonlyArray(schemaPath)
|
|
43
|
+
? schemaPath.map((schemaPath) => path.resolve(process.cwd(), schemaPath))
|
|
44
|
+
: path.resolve(process.cwd(), schemaPath),
|
|
43
45
|
viteConfig: (viteConfig) => {
|
|
44
46
|
if (LS_DEV) {
|
|
45
47
|
viteConfig.server ??= {}
|
|
@@ -85,7 +87,7 @@ export const startDevtoolsServer = ({
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
// We want to keep the websocket open until the client disconnects or the server shuts down
|
|
88
|
-
yield* Effect.never
|
|
90
|
+
return yield* Effect.never
|
|
89
91
|
}),
|
|
90
92
|
webChannel.closedDeferred,
|
|
91
93
|
)
|
package/src/devtools/mod.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type { ViteDevtoolsOptions } from './vite-dev-server.
|
|
3
|
-
export {
|
|
1
|
+
export { startDevtoolsServer } from './devtools-server.ts'
|
|
2
|
+
export type { ViteDevtoolsOptions } from './vite-dev-server.ts'
|
|
3
|
+
export { makeViteMiddleware } from './vite-dev-server.ts'
|
|
@@ -3,6 +3,7 @@ import path from 'node:path'
|
|
|
3
3
|
import type { Devtools } from '@livestore/common'
|
|
4
4
|
import { UnexpectedError } from '@livestore/common'
|
|
5
5
|
import { livestoreDevtoolsPlugin } from '@livestore/devtools-vite'
|
|
6
|
+
import { isReadonlyArray } from '@livestore/utils'
|
|
6
7
|
import { Effect } from '@livestore/utils/effect'
|
|
7
8
|
import { getFreePort } from '@livestore/utils/node'
|
|
8
9
|
import * as Vite from 'vite'
|
|
@@ -15,7 +16,7 @@ export type ViteDevtoolsOptions = {
|
|
|
15
16
|
*
|
|
16
17
|
* Example: `./src/schema.ts`
|
|
17
18
|
*/
|
|
18
|
-
schemaPath: string
|
|
19
|
+
schemaPath: string | ReadonlyArray<string>
|
|
19
20
|
/**
|
|
20
21
|
* The mode of the devtools server.
|
|
21
22
|
*
|
|
@@ -44,7 +45,9 @@ export const makeViteMiddleware = (options: ViteDevtoolsOptions): Effect.Effect<
|
|
|
44
45
|
base: '/_livestore/',
|
|
45
46
|
plugins: [
|
|
46
47
|
livestoreDevtoolsPlugin({
|
|
47
|
-
schemaPath:
|
|
48
|
+
schemaPath: isReadonlyArray(options.schemaPath)
|
|
49
|
+
? options.schemaPath.map((schemaPath) => path.resolve(cwd, schemaPath))
|
|
50
|
+
: path.resolve(cwd, options.schemaPath),
|
|
48
51
|
mode: options.mode,
|
|
49
52
|
path: '/',
|
|
50
53
|
}),
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { makeAdapter, makeWorkerAdapter } from './client-session/adapter.
|
|
1
|
+
export { makeAdapter, makeWorkerAdapter } from './client-session/adapter.ts'
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
const run = async () => {
|
|
7
7
|
const start = Date.now()
|
|
8
8
|
// @ts-expect-error todo
|
|
9
|
-
const _module = await import('./leader-thread.bundle.
|
|
9
|
+
const _module = await import('./leader-thread.bundle.ts')
|
|
10
10
|
const end = Date.now()
|
|
11
11
|
console.log(`[@livestore/adapter-node:leader] Loaded in ${end - start}ms`)
|
|
12
12
|
}
|
|
@@ -16,8 +16,8 @@ import type { FileSystem, HttpClient, Layer, Schema, Scope } from '@livestore/ut
|
|
|
16
16
|
import { Effect } from '@livestore/utils/effect'
|
|
17
17
|
import * as Webmesh from '@livestore/webmesh'
|
|
18
18
|
|
|
19
|
-
import { makeShutdownChannel } from './shutdown-channel.
|
|
20
|
-
import type * as WorkerSchema from './worker-schema.
|
|
19
|
+
import { makeShutdownChannel } from './shutdown-channel.ts'
|
|
20
|
+
import type * as WorkerSchema from './worker-schema.ts'
|
|
21
21
|
|
|
22
22
|
export type TestingOverrides = {
|
|
23
23
|
clientSession?: {
|
|
@@ -40,7 +40,7 @@ export interface MakeLeaderThreadArgs {
|
|
|
40
40
|
syncOptions: SyncOptions | undefined
|
|
41
41
|
storage: WorkerSchema.StorageType
|
|
42
42
|
makeSqliteDb: MakeNodeSqliteDb
|
|
43
|
-
devtools: WorkerSchema.
|
|
43
|
+
devtools: WorkerSchema.LeaderWorkerInnerInitialMessage['devtools']
|
|
44
44
|
schema: LiveStoreSchema
|
|
45
45
|
syncPayload: Schema.JsonValue | undefined
|
|
46
46
|
testing: TestingOverrides | undefined
|
|
@@ -131,7 +131,7 @@ const makeDevtoolsOptions = ({
|
|
|
131
131
|
dbEventlog: LeaderSqliteDb
|
|
132
132
|
storeId: string
|
|
133
133
|
clientId: string
|
|
134
|
-
devtools: WorkerSchema.
|
|
134
|
+
devtools: WorkerSchema.LeaderWorkerInnerInitialMessage['devtools']
|
|
135
135
|
}): Effect.Effect<DevtoolsOptions, UnexpectedError, Scope.Scope> =>
|
|
136
136
|
Effect.gen(function* () {
|
|
137
137
|
if (devtools.enabled === false) {
|
|
@@ -144,7 +144,7 @@ const makeDevtoolsOptions = ({
|
|
|
144
144
|
enabled: true,
|
|
145
145
|
boot: Effect.gen(function* () {
|
|
146
146
|
// Lazy import to improve startup time
|
|
147
|
-
const { startDevtoolsServer } = yield* Effect.promise(() => import('./devtools/devtools-server.
|
|
147
|
+
const { startDevtoolsServer } = yield* Effect.promise(() => import('./devtools/devtools-server.ts'))
|
|
148
148
|
|
|
149
149
|
// 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
|
|
150
150
|
if (devtools.useExistingDevtoolsServer === false) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import './thread-polyfill.
|
|
1
|
+
import './thread-polyfill.ts'
|
|
2
2
|
|
|
3
3
|
import inspector from 'node:inspector'
|
|
4
4
|
|
|
@@ -29,9 +29,9 @@ import {
|
|
|
29
29
|
import { PlatformNode } from '@livestore/utils/node'
|
|
30
30
|
import type * as otel from '@opentelemetry/api'
|
|
31
31
|
|
|
32
|
-
import type { TestingOverrides } from './leader-thread-shared.
|
|
33
|
-
import { makeLeaderThread } from './leader-thread-shared.
|
|
34
|
-
import * as WorkerSchema from './worker-schema.
|
|
32
|
+
import type { TestingOverrides } from './leader-thread-shared.ts'
|
|
33
|
+
import { makeLeaderThread } from './leader-thread-shared.ts'
|
|
34
|
+
import * as WorkerSchema from './worker-schema.ts'
|
|
35
35
|
|
|
36
36
|
export type WorkerOptions = {
|
|
37
37
|
schema: LiveStoreSchema
|
|
@@ -47,7 +47,10 @@ export type WorkerOptions = {
|
|
|
47
47
|
export const getWorkerArgs = () => Schema.decodeSync(WorkerSchema.WorkerArgv)(process.argv[2]!)
|
|
48
48
|
|
|
49
49
|
export const makeWorker = (options: WorkerOptions) => {
|
|
50
|
-
makeWorkerEffect(options).pipe(
|
|
50
|
+
makeWorkerEffect(options).pipe(
|
|
51
|
+
Effect.provide(Logger.prettyWithThread(options.otelOptions?.serviceName ?? 'livestore-node-leader-thread')),
|
|
52
|
+
PlatformNode.NodeRuntime.runMain,
|
|
53
|
+
)
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
export const makeWorkerEffect = (options: WorkerOptions) => {
|
|
@@ -57,7 +60,7 @@ export const makeWorkerEffect = (options: WorkerOptions) => {
|
|
|
57
60
|
)
|
|
58
61
|
: undefined
|
|
59
62
|
|
|
60
|
-
return WorkerRunner.layerSerialized(WorkerSchema.
|
|
63
|
+
return WorkerRunner.layerSerialized(WorkerSchema.LeaderWorkerInnerRequest, {
|
|
61
64
|
InitialMessage: (args) =>
|
|
62
65
|
Effect.gen(function* () {
|
|
63
66
|
const sqlite3 = yield* Effect.promise(() => loadSqlite3Wasm()).pipe(
|
|
@@ -153,7 +156,9 @@ export const makeWorkerEffect = (options: WorkerOptions) => {
|
|
|
153
156
|
thread: options.otelOptions?.serviceName ?? 'livestore-node-leader-thread',
|
|
154
157
|
processId: process.pid,
|
|
155
158
|
}),
|
|
156
|
-
Effect
|
|
159
|
+
// TODO bring back with Effect 4 once it's easier to work with replacing loggers.
|
|
160
|
+
// We basically only want to provide this logger if it's replacing the default logger, not if there's a custom logger already provided.
|
|
161
|
+
// Effect.provide(Logger.prettyWithThread(options.otelOptions?.serviceName ?? 'livestore-node-leader-thread')),
|
|
157
162
|
Effect.provide(FetchHttpClient.layer),
|
|
158
163
|
Effect.provide(PlatformNode.NodeFileSystem.layer),
|
|
159
164
|
TracingLive ? Effect.provide(TracingLive) : identity,
|
package/src/shutdown-channel.ts
CHANGED
package/src/webchannel.ts
CHANGED
|
@@ -37,7 +37,6 @@ export const makeBroadcastChannel = <Msg, MsgEncoded>({
|
|
|
37
37
|
const listen = Stream.asyncPush<Either.Either<Msg, ParseResult.ParseError>>((emit) =>
|
|
38
38
|
Effect.acquireRelease(
|
|
39
39
|
Effect.gen(function* () {
|
|
40
|
-
// eslint-disable-next-line unicorn/prefer-add-event-listener
|
|
41
40
|
channel.onmessage = (event: any) => {
|
|
42
41
|
return emit.single(Schema.decodeEither(schema)(event.data))
|
|
43
42
|
}
|
package/src/worker-schema.ts
CHANGED
|
@@ -42,18 +42,20 @@ export type StorageTypeEncoded = typeof StorageType.Encoded
|
|
|
42
42
|
export const SyncBackendOptions = Schema.Record({ key: Schema.String, value: Schema.JsonValue })
|
|
43
43
|
export type SyncBackendOptions = Record<string, Schema.JsonValue>
|
|
44
44
|
|
|
45
|
-
export
|
|
46
|
-
|
|
45
|
+
export class LeaderWorkerOuterInitialMessage extends Schema.TaggedRequest<LeaderWorkerOuterInitialMessage>()(
|
|
46
|
+
'InitialMessage',
|
|
47
|
+
{
|
|
47
48
|
payload: { port: Transferable.MessagePort },
|
|
48
49
|
success: Schema.Void,
|
|
49
50
|
failure: UnexpectedError,
|
|
50
|
-
}
|
|
51
|
+
},
|
|
52
|
+
) {}
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
+
export class LeaderWorkerOuterRequest extends Schema.Union(LeaderWorkerOuterInitialMessage) {}
|
|
54
55
|
|
|
55
|
-
export
|
|
56
|
-
|
|
56
|
+
export class LeaderWorkerInnerInitialMessage extends Schema.TaggedRequest<LeaderWorkerInnerInitialMessage>()(
|
|
57
|
+
'InitialMessage',
|
|
58
|
+
{
|
|
57
59
|
payload: {
|
|
58
60
|
storeId: Schema.String,
|
|
59
61
|
clientId: Schema.String,
|
|
@@ -73,91 +75,112 @@ export namespace LeaderWorkerInner {
|
|
|
73
75
|
},
|
|
74
76
|
success: Schema.Void,
|
|
75
77
|
failure: UnexpectedError,
|
|
76
|
-
}
|
|
78
|
+
},
|
|
79
|
+
) {}
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
export class LeaderWorkerInnerBootStatusStream extends Schema.TaggedRequest<LeaderWorkerInnerBootStatusStream>()(
|
|
82
|
+
'BootStatusStream',
|
|
83
|
+
{
|
|
79
84
|
payload: {},
|
|
80
85
|
success: BootStatus,
|
|
81
86
|
failure: UnexpectedError,
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
},
|
|
88
|
+
) {}
|
|
89
|
+
|
|
90
|
+
export class LeaderWorkerInnerPullStream extends Schema.TaggedRequest<LeaderWorkerInnerPullStream>()('PullStream', {
|
|
91
|
+
payload: {
|
|
92
|
+
cursor: EventSequenceNumber.EventSequenceNumber,
|
|
93
|
+
},
|
|
94
|
+
success: Schema.Struct({
|
|
95
|
+
payload: SyncState.PayloadUpstream,
|
|
96
|
+
}),
|
|
97
|
+
failure: UnexpectedError,
|
|
98
|
+
}) {}
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
export class LeaderWorkerInnerPushToLeader extends Schema.TaggedRequest<LeaderWorkerInnerPushToLeader>()(
|
|
101
|
+
'PushToLeader',
|
|
102
|
+
{
|
|
95
103
|
payload: {
|
|
96
104
|
batch: Schema.Array(LiveStoreEvent.AnyEncoded),
|
|
97
105
|
},
|
|
98
106
|
success: Schema.Void,
|
|
99
107
|
failure: Schema.Union(UnexpectedError, LeaderAheadError),
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
},
|
|
109
|
+
) {}
|
|
110
|
+
|
|
111
|
+
export class LeaderWorkerInnerExport extends Schema.TaggedRequest<LeaderWorkerInnerExport>()('Export', {
|
|
112
|
+
payload: {},
|
|
113
|
+
success: Transferable.Uint8Array,
|
|
114
|
+
failure: UnexpectedError,
|
|
115
|
+
}) {}
|
|
116
|
+
|
|
117
|
+
export class LeaderWorkerInnerGetRecreateSnapshot extends Schema.TaggedRequest<LeaderWorkerInnerGetRecreateSnapshot>()(
|
|
118
|
+
'GetRecreateSnapshot',
|
|
119
|
+
{
|
|
109
120
|
payload: {},
|
|
110
121
|
success: Schema.Struct({
|
|
111
122
|
snapshot: Transferable.Uint8Array,
|
|
112
123
|
migrationsReport: MigrationsReport,
|
|
113
124
|
}),
|
|
114
125
|
failure: UnexpectedError,
|
|
115
|
-
}
|
|
126
|
+
},
|
|
127
|
+
) {}
|
|
116
128
|
|
|
117
|
-
|
|
129
|
+
export class LeaderWorkerInnerExportEventlog extends Schema.TaggedRequest<LeaderWorkerInnerExportEventlog>()(
|
|
130
|
+
'ExportEventlog',
|
|
131
|
+
{
|
|
118
132
|
payload: {},
|
|
119
133
|
success: Transferable.Uint8Array,
|
|
120
134
|
failure: UnexpectedError,
|
|
121
|
-
}
|
|
135
|
+
},
|
|
136
|
+
) {}
|
|
122
137
|
|
|
123
|
-
|
|
138
|
+
export class LeaderWorkerInnerGetLeaderHead extends Schema.TaggedRequest<LeaderWorkerInnerGetLeaderHead>()(
|
|
139
|
+
'GetLeaderHead',
|
|
140
|
+
{
|
|
124
141
|
payload: {},
|
|
125
142
|
success: EventSequenceNumber.EventSequenceNumber,
|
|
126
143
|
failure: UnexpectedError,
|
|
127
|
-
}
|
|
144
|
+
},
|
|
145
|
+
) {}
|
|
128
146
|
|
|
129
|
-
|
|
147
|
+
export class LeaderWorkerInnerGetLeaderSyncState extends Schema.TaggedRequest<LeaderWorkerInnerGetLeaderSyncState>()(
|
|
148
|
+
'GetLeaderSyncState',
|
|
149
|
+
{
|
|
130
150
|
payload: {},
|
|
131
151
|
success: SyncState.SyncState,
|
|
132
152
|
failure: UnexpectedError,
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
},
|
|
154
|
+
) {}
|
|
155
|
+
|
|
156
|
+
export class LeaderWorkerInnerShutdown extends Schema.TaggedRequest<LeaderWorkerInnerShutdown>()('Shutdown', {
|
|
157
|
+
payload: {},
|
|
158
|
+
success: Schema.Void,
|
|
159
|
+
failure: UnexpectedError,
|
|
160
|
+
}) {}
|
|
161
|
+
|
|
162
|
+
export class LeaderWorkerInnerExtraDevtoolsMessage extends Schema.TaggedRequest<LeaderWorkerInnerExtraDevtoolsMessage>()(
|
|
163
|
+
'ExtraDevtoolsMessage',
|
|
164
|
+
{
|
|
142
165
|
payload: {
|
|
143
166
|
message: Devtools.Leader.MessageToApp,
|
|
144
167
|
},
|
|
145
168
|
success: Schema.Void,
|
|
146
169
|
failure: UnexpectedError,
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
170
|
+
},
|
|
171
|
+
) {}
|
|
172
|
+
|
|
173
|
+
export const LeaderWorkerInnerRequest = Schema.Union(
|
|
174
|
+
LeaderWorkerInnerInitialMessage,
|
|
175
|
+
LeaderWorkerInnerBootStatusStream,
|
|
176
|
+
LeaderWorkerInnerPullStream,
|
|
177
|
+
LeaderWorkerInnerPushToLeader,
|
|
178
|
+
LeaderWorkerInnerExport,
|
|
179
|
+
LeaderWorkerInnerGetRecreateSnapshot,
|
|
180
|
+
LeaderWorkerInnerExportEventlog,
|
|
181
|
+
LeaderWorkerInnerGetLeaderHead,
|
|
182
|
+
LeaderWorkerInnerGetLeaderSyncState,
|
|
183
|
+
LeaderWorkerInnerShutdown,
|
|
184
|
+
LeaderWorkerInnerExtraDevtoolsMessage,
|
|
185
|
+
)
|
|
186
|
+
export type LeaderWorkerInnerRequest = typeof LeaderWorkerInnerRequest.Type
|