@livestore/common 0.3.0-dev.2 → 0.3.0-dev.21
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/__tests__/fixture.d.ts +21 -21
- package/dist/adapter-types.d.ts +97 -53
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +17 -0
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/derived-mutations.d.ts +5 -5
- package/dist/derived-mutations.d.ts.map +1 -1
- package/dist/derived-mutations.js +3 -3
- package/dist/derived-mutations.js.map +1 -1
- package/dist/derived-mutations.test.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +96 -0
- package/dist/devtools/devtools-messages-client-session.js.map +1 -0
- package/dist/devtools/devtools-messages-common.d.ts +61 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-common.js +54 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -0
- package/dist/devtools/devtools-messages-leader.d.ts +393 -0
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-leader.js +148 -0
- package/dist/devtools/devtools-messages-leader.js.map +1 -0
- package/dist/devtools/devtools-messages.d.ts +3 -592
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +3 -171
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
- package/dist/devtools/devtools-sessioninfo.js +34 -0
- package/dist/devtools/devtools-sessioninfo.js.map +1 -0
- package/dist/devtools/devtools-sessions-channel.d.ts +28 -0
- package/dist/devtools/devtools-sessions-channel.d.ts.map +1 -0
- package/dist/devtools/devtools-sessions-channel.js +34 -0
- package/dist/devtools/devtools-sessions-channel.js.map +1 -0
- package/dist/devtools/index.d.ts +35 -38
- package/dist/devtools/index.d.ts.map +1 -1
- package/dist/devtools/index.js +20 -45
- package/dist/devtools/index.js.map +1 -1
- package/dist/devtools/mod.d.ts +39 -0
- package/dist/devtools/mod.d.ts.map +1 -0
- package/dist/devtools/mod.js +27 -0
- package/dist/devtools/mod.js.map +1 -0
- package/dist/index.d.ts +2 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/init-singleton-tables.d.ts +2 -2
- package/dist/init-singleton-tables.d.ts.map +1 -1
- package/dist/init-singleton-tables.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +39 -0
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
- package/dist/leader-thread/LeaderSyncProcessor.js +527 -0
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
- package/dist/leader-thread/apply-mutation.d.ts +5 -2
- package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.js +55 -35
- package/dist/leader-thread/apply-mutation.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +34 -6
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +22 -7
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +147 -124
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +12 -11
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +55 -18
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mutationlog.d.ts +6 -19
- package/dist/leader-thread/mutationlog.d.ts.map +1 -1
- package/dist/leader-thread/mutationlog.js +12 -9
- package/dist/leader-thread/mutationlog.js.map +1 -1
- package/dist/leader-thread/pull-queue-set.d.ts +3 -3
- package/dist/leader-thread/pull-queue-set.d.ts.map +1 -1
- package/dist/leader-thread/pull-queue-set.js +9 -0
- package/dist/leader-thread/pull-queue-set.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +4 -2
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +32 -21
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -5
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -4
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/types.d.ts +58 -26
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +1 -3
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/mutation.d.ts +9 -2
- package/dist/mutation.d.ts.map +1 -1
- package/dist/mutation.js +5 -5
- package/dist/mutation.js.map +1 -1
- package/dist/otel.d.ts +2 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +5 -0
- package/dist/otel.js.map +1 -1
- package/dist/query-builder/api.d.ts +3 -3
- package/dist/query-builder/api.d.ts.map +1 -1
- package/dist/query-builder/impl.d.ts +4 -4
- package/dist/query-builder/impl.d.ts.map +1 -1
- package/dist/query-builder/impl.js.map +1 -1
- package/dist/query-builder/impl.test.js +16 -1
- package/dist/query-builder/impl.test.js.map +1 -1
- package/dist/query-info.d.ts +3 -3
- package/dist/query-info.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts +5 -5
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +23 -27
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +27 -16
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +36 -11
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/EventId.test.d.ts +2 -0
- package/dist/schema/EventId.test.d.ts.map +1 -0
- package/dist/schema/EventId.test.js +11 -0
- package/dist/schema/EventId.test.js.map +1 -0
- package/dist/schema/MutationEvent.d.ts +76 -82
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +53 -20
- package/dist/schema/MutationEvent.js.map +1 -1
- package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/sqlite.js +71 -0
- package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
- package/dist/schema/db-schema/ast/validate.d.ts +3 -0
- package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/validate.js +12 -0
- package/dist/schema/db-schema/ast/validate.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.js +87 -0
- package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/schema/db-schema/dsl/mod.d.ts +88 -0
- package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/mod.js +35 -0
- package/dist/schema/db-schema/dsl/mod.js.map +1 -0
- package/dist/schema/db-schema/hash.d.ts +2 -0
- package/dist/schema/db-schema/hash.d.ts.map +1 -0
- package/dist/schema/db-schema/hash.js +14 -0
- package/dist/schema/db-schema/hash.js.map +1 -0
- package/dist/schema/db-schema/mod.d.ts +3 -0
- package/dist/schema/db-schema/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/mod.js +3 -0
- package/dist/schema/db-schema/mod.js.map +1 -0
- package/dist/schema/mod.d.ts +1 -0
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +1 -0
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/mutations.d.ts +8 -9
- package/dist/schema/mutations.d.ts.map +1 -1
- package/dist/schema/mutations.js +2 -2
- package/dist/schema/mutations.js.map +1 -1
- package/dist/schema/schema-helpers.d.ts.map +1 -1
- package/dist/schema/schema-helpers.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/schema.d.ts +5 -2
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +20 -9
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/system-tables.d.ts +65 -47
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +24 -13
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +18 -24
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +3 -4
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema-management/common.d.ts +3 -3
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +6 -6
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +13 -8
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
- package/dist/schema-management/validate-mutation-defs.js +2 -2
- package/dist/schema-management/validate-mutation-defs.js.map +1 -1
- package/dist/sql-queries/misc.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sql-queries/types.d.ts +2 -1
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sql-queries/types.js.map +1 -1
- package/dist/sync/{client-session-sync-processor.d.ts → ClientSessionSyncProcessor.d.ts} +25 -14
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.js +199 -0
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +1 -1
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +3 -4
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +3 -1
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/history-dag.d.ts.map +1 -1
- package/dist/sync/next/history-dag.js +1 -1
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +6 -4
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +6 -3
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +12 -12
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +43 -43
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts +4 -4
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.js +12 -16
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +31 -16
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +7 -3
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +177 -44
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +188 -56
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +162 -92
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/validate-push-payload.d.ts +2 -2
- package/dist/sync/validate-push-payload.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js +2 -2
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -6
- package/src/adapter-types.ts +80 -56
- package/src/derived-mutations.test.ts +1 -1
- package/src/derived-mutations.ts +13 -9
- package/src/devtools/devtools-messages-client-session.ts +141 -0
- package/src/devtools/devtools-messages-common.ts +106 -0
- package/src/devtools/devtools-messages-leader.ts +192 -0
- package/src/devtools/devtools-messages.ts +3 -243
- package/src/devtools/devtools-sessioninfo.ts +99 -0
- package/src/devtools/mod.ts +36 -0
- package/src/index.ts +2 -8
- package/src/init-singleton-tables.ts +2 -2
- package/src/leader-thread/LeaderSyncProcessor.ts +833 -0
- package/src/leader-thread/apply-mutation.ts +87 -43
- package/src/leader-thread/connection.ts +54 -9
- package/src/leader-thread/leader-worker-devtools.ts +199 -174
- package/src/leader-thread/make-leader-thread-layer.ts +89 -35
- package/src/leader-thread/mutationlog.ts +20 -14
- package/src/leader-thread/pull-queue-set.ts +10 -1
- package/src/leader-thread/recreate-db.ts +38 -25
- package/src/leader-thread/shutdown-channel.ts +2 -4
- package/src/leader-thread/types.ts +68 -34
- package/src/mutation.ts +17 -7
- package/src/otel.ts +8 -0
- package/src/query-builder/api.ts +4 -4
- package/src/query-builder/impl.test.ts +22 -1
- package/src/query-builder/impl.ts +2 -2
- package/src/query-info.ts +3 -3
- package/src/rehydrate-from-mutationlog.ts +28 -34
- package/src/schema/EventId.test.ts +12 -0
- package/src/schema/EventId.ts +49 -15
- package/src/schema/MutationEvent.ts +78 -31
- package/src/schema/db-schema/ast/sqlite.ts +142 -0
- package/src/schema/db-schema/ast/validate.ts +13 -0
- package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
- package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
- package/src/schema/db-schema/dsl/field-defs.ts +242 -0
- package/src/schema/db-schema/dsl/mod.ts +195 -0
- package/src/schema/db-schema/hash.ts +14 -0
- package/src/schema/db-schema/mod.ts +2 -0
- package/src/schema/mod.ts +1 -0
- package/src/schema/mutations.ts +10 -20
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/schema.ts +22 -10
- package/src/schema/system-tables.ts +24 -13
- package/src/schema/table-def.ts +17 -17
- package/src/schema-management/common.ts +3 -3
- package/src/schema-management/migrations.ts +19 -15
- package/src/schema-management/validate-mutation-defs.ts +2 -2
- package/src/sql-queries/sql-queries.ts +1 -1
- package/src/sql-queries/sql-query-builder.ts +1 -2
- package/src/sql-queries/types.ts +3 -1
- package/src/sync/ClientSessionSyncProcessor.ts +313 -0
- package/src/sync/index.ts +1 -1
- package/src/sync/next/facts.ts +1 -1
- package/src/sync/next/history-dag-common.ts +5 -1
- package/src/sync/next/history-dag.ts +1 -1
- package/src/sync/next/rebase-events.ts +13 -7
- package/src/sync/next/test/compact-events.calculator.test.ts +12 -12
- package/src/sync/next/test/compact-events.test.ts +43 -43
- package/src/sync/next/test/mutation-fixtures.ts +16 -19
- package/src/sync/sync.ts +26 -10
- package/src/sync/syncstate.test.ts +178 -98
- package/src/sync/syncstate.ts +170 -83
- package/src/sync/validate-push-payload.ts +7 -4
- package/src/version.ts +1 -1
- package/tmp/pack.tgz +0 -0
- package/tsconfig.json +1 -1
- package/dist/devtools/devtools-bridge.d.ts +0 -12
- package/dist/devtools/devtools-bridge.d.ts.map +0 -1
- package/dist/devtools/devtools-bridge.js +0 -2
- package/dist/devtools/devtools-bridge.js.map +0 -1
- package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
- package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
- package/dist/leader-thread/leader-sync-processor.js +0 -422
- package/dist/leader-thread/leader-sync-processor.js.map +0 -1
- package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
- package/dist/sync/client-session-sync-processor.js +0 -131
- package/dist/sync/client-session-sync-processor.js.map +0 -1
- package/src/devtools/devtools-bridge.ts +0 -13
- package/src/devtools/index.ts +0 -48
- package/src/leader-thread/leader-sync-processor.ts +0 -666
- package/src/sync/client-session-sync-processor.ts +0 -207
@@ -1,68 +1,104 @@
|
|
1
|
-
import type { HttpClient, Scope
|
2
|
-
import { Deferred, Effect,
|
1
|
+
import type { HttpClient, Scope } from '@livestore/utils/effect'
|
2
|
+
import { Deferred, Effect, Layer, Queue, SubscriptionRef } from '@livestore/utils/effect'
|
3
3
|
|
4
|
-
import type { BootStatus,
|
4
|
+
import type { BootStatus, MakeSqliteDb, MigrationsReport, SqliteError } from '../adapter-types.js'
|
5
5
|
import { UnexpectedError } from '../adapter-types.js'
|
6
|
+
import type * as Devtools from '../devtools/mod.js'
|
6
7
|
import type { LiveStoreSchema } from '../schema/mod.js'
|
7
8
|
import { EventId, MutationEvent, mutationLogMetaTable, SYNC_STATUS_TABLE, syncStatusTable } from '../schema/mod.js'
|
8
9
|
import { migrateTable } from '../schema-management/migrations.js'
|
9
|
-
import type { InvalidPullError, IsOfflineError,
|
10
|
+
import type { InvalidPullError, IsOfflineError, SyncOptions } from '../sync/sync.js'
|
10
11
|
import { sql } from '../util.js'
|
11
12
|
import { execSql } from './connection.js'
|
12
|
-
import { makeLeaderSyncProcessor } from './leader-sync-processor.js'
|
13
13
|
import { bootDevtools } from './leader-worker-devtools.js'
|
14
|
+
import { makeLeaderSyncProcessor } from './LeaderSyncProcessor.js'
|
14
15
|
import { makePullQueueSet } from './pull-queue-set.js'
|
15
16
|
import { recreateDb } from './recreate-db.js'
|
16
|
-
import type {
|
17
|
+
import type { ShutdownChannel } from './shutdown-channel.js'
|
18
|
+
import type {
|
19
|
+
DevtoolsOptions,
|
20
|
+
InitialBlockingSyncContext,
|
21
|
+
InitialSyncOptions,
|
22
|
+
LeaderSqliteDb,
|
23
|
+
ShutdownState,
|
24
|
+
} from './types.js'
|
17
25
|
import { LeaderThreadCtx } from './types.js'
|
18
26
|
|
19
27
|
export const makeLeaderThreadLayer = ({
|
20
28
|
schema,
|
21
29
|
storeId,
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
clientId,
|
31
|
+
makeSqliteDb,
|
32
|
+
syncOptions,
|
33
|
+
dbReadModel,
|
34
|
+
dbMutationLog,
|
27
35
|
devtoolsOptions,
|
28
|
-
|
36
|
+
shutdownChannel,
|
29
37
|
}: {
|
30
38
|
storeId: string
|
31
|
-
|
39
|
+
clientId: string
|
32
40
|
schema: LiveStoreSchema
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
makeSqliteDb: MakeSqliteDb
|
42
|
+
syncOptions: SyncOptions | undefined
|
43
|
+
dbReadModel: LeaderSqliteDb
|
44
|
+
dbMutationLog: LeaderSqliteDb
|
37
45
|
devtoolsOptions: DevtoolsOptions
|
38
|
-
|
46
|
+
shutdownChannel: ShutdownChannel
|
39
47
|
}): Layer.Layer<LeaderThreadCtx, UnexpectedError, Scope.Scope | HttpClient.HttpClient> =>
|
40
48
|
Effect.gen(function* () {
|
41
49
|
const bootStatusQueue = yield* Queue.unbounded<BootStatus>().pipe(Effect.acquireRelease(Queue.shutdown))
|
42
50
|
|
43
51
|
// TODO do more validation here than just checking the count of tables
|
44
52
|
// Either happens on initial boot or if schema changes
|
45
|
-
const dbMissing =
|
53
|
+
const dbMissing =
|
54
|
+
dbReadModel.select<{ count: number }>(sql`select count(*) as count from sqlite_master`)[0]!.count === 0
|
46
55
|
|
47
|
-
const syncBackend =
|
56
|
+
const syncBackend =
|
57
|
+
syncOptions?.makeBackend === undefined ? undefined : yield* syncOptions.makeBackend({ storeId, clientId })
|
48
58
|
|
49
|
-
const initialBlockingSyncContext = yield* makeInitialBlockingSyncContext({
|
59
|
+
const initialBlockingSyncContext = yield* makeInitialBlockingSyncContext({
|
60
|
+
initialSyncOptions: syncOptions?.initialSyncOptions ?? { _tag: 'Skip' },
|
61
|
+
bootStatusQueue,
|
62
|
+
})
|
50
63
|
|
51
|
-
const syncProcessor = yield* makeLeaderSyncProcessor({
|
64
|
+
const syncProcessor = yield* makeLeaderSyncProcessor({
|
65
|
+
schema,
|
66
|
+
dbMissing,
|
67
|
+
dbMutationLog,
|
68
|
+
initialBlockingSyncContext,
|
69
|
+
clientId,
|
70
|
+
})
|
71
|
+
|
72
|
+
const extraIncomingMessagesQueue = yield* Queue.unbounded<Devtools.Leader.MessageToApp>().pipe(
|
73
|
+
Effect.acquireRelease(Queue.shutdown),
|
74
|
+
)
|
75
|
+
|
76
|
+
const devtoolsContext = devtoolsOptions.enabled
|
77
|
+
? {
|
78
|
+
enabled: true as const,
|
79
|
+
syncBackendLatch: yield* Effect.makeLatch(true),
|
80
|
+
syncBackendLatchState: yield* SubscriptionRef.make<{ latchClosed: boolean }>({ latchClosed: false }),
|
81
|
+
}
|
82
|
+
: { enabled: false as const }
|
52
83
|
|
53
84
|
const ctx = {
|
54
85
|
schema,
|
55
86
|
bootStatusQueue,
|
56
87
|
storeId,
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
88
|
+
clientId,
|
89
|
+
dbReadModel,
|
90
|
+
dbMutationLog,
|
91
|
+
makeSqliteDb,
|
61
92
|
mutationEventSchema: MutationEvent.makeMutationEventSchema(schema),
|
62
93
|
shutdownStateSubRef: yield* SubscriptionRef.make<ShutdownState>('running'),
|
94
|
+
shutdownChannel,
|
63
95
|
syncBackend,
|
64
96
|
syncProcessor,
|
65
97
|
connectedClientSessionPullQueues: yield* makePullQueueSet,
|
98
|
+
extraIncomingMessagesQueue,
|
99
|
+
devtools: devtoolsContext,
|
100
|
+
// State will be set during `bootLeaderThread`
|
101
|
+
initialState: {} as any as LeaderThreadCtx['Type']['initialState'],
|
66
102
|
} satisfies typeof LeaderThreadCtx.Service
|
67
103
|
|
68
104
|
// @ts-expect-error For debugging purposes
|
@@ -70,7 +106,11 @@ export const makeLeaderThreadLayer = ({
|
|
70
106
|
|
71
107
|
const layer = Layer.succeed(LeaderThreadCtx, ctx)
|
72
108
|
|
73
|
-
yield* bootLeaderThread({
|
109
|
+
ctx.initialState = yield* bootLeaderThread({
|
110
|
+
dbMissing,
|
111
|
+
initialBlockingSyncContext,
|
112
|
+
devtoolsOptions,
|
113
|
+
}).pipe(Effect.provide(layer))
|
74
114
|
|
75
115
|
return layer
|
76
116
|
}).pipe(
|
@@ -140,22 +180,22 @@ const bootLeaderThread = ({
|
|
140
180
|
initialBlockingSyncContext: InitialBlockingSyncContext
|
141
181
|
devtoolsOptions: DevtoolsOptions
|
142
182
|
}): Effect.Effect<
|
143
|
-
|
183
|
+
LeaderThreadCtx['Type']['initialState'],
|
144
184
|
UnexpectedError | SqliteError | IsOfflineError | InvalidPullError,
|
145
185
|
LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
|
146
186
|
> =>
|
147
187
|
Effect.gen(function* () {
|
148
|
-
const {
|
188
|
+
const { dbMutationLog, bootStatusQueue, syncProcessor } = yield* LeaderThreadCtx
|
149
189
|
|
150
190
|
yield* migrateTable({
|
151
|
-
db:
|
191
|
+
db: dbMutationLog,
|
152
192
|
behaviour: 'create-if-not-exists',
|
153
193
|
tableAst: mutationLogMetaTable.sqliteDef.ast,
|
154
194
|
skipMetaTable: true,
|
155
195
|
})
|
156
196
|
|
157
197
|
yield* migrateTable({
|
158
|
-
db:
|
198
|
+
db: dbMutationLog,
|
159
199
|
behaviour: 'create-if-not-exists',
|
160
200
|
tableAst: syncStatusTable.sqliteDef.ast,
|
161
201
|
skipMetaTable: true,
|
@@ -163,7 +203,7 @@ const bootLeaderThread = ({
|
|
163
203
|
|
164
204
|
// Create sync status row if it doesn't exist
|
165
205
|
yield* execSql(
|
166
|
-
|
206
|
+
dbMutationLog,
|
167
207
|
sql`INSERT INTO ${SYNC_STATUS_TABLE} (head)
|
168
208
|
SELECT ${EventId.ROOT.global}
|
169
209
|
WHERE NOT EXISTS (SELECT 1 FROM ${SYNC_STATUS_TABLE})`,
|
@@ -174,19 +214,33 @@ const bootLeaderThread = ({
|
|
174
214
|
|
175
215
|
// We're already starting pulling from the sync backend concurrently but wait until the db is ready before
|
176
216
|
// processing any incoming mutations
|
177
|
-
yield* syncProcessor.boot({ dbReady })
|
217
|
+
const { initialLeaderHead } = yield* syncProcessor.boot({ dbReady })
|
178
218
|
|
219
|
+
let migrationsReport: MigrationsReport
|
179
220
|
if (dbMissing) {
|
180
|
-
yield* recreateDb
|
221
|
+
const recreateResult = yield* recreateDb
|
222
|
+
migrationsReport = recreateResult.migrationsReport
|
223
|
+
} else {
|
224
|
+
migrationsReport = { migrations: [] }
|
181
225
|
}
|
182
226
|
|
183
227
|
yield* Deferred.succeed(dbReady, void 0)
|
184
228
|
|
185
229
|
if (initialBlockingSyncContext.blockingDeferred !== undefined) {
|
186
|
-
|
230
|
+
// Provides a syncing status right away before the first pull response comes in
|
231
|
+
yield* Queue.offer(bootStatusQueue, {
|
232
|
+
stage: 'syncing',
|
233
|
+
progress: { done: 0, total: -1 },
|
234
|
+
})
|
235
|
+
|
236
|
+
yield* initialBlockingSyncContext.blockingDeferred.pipe(
|
237
|
+
Effect.withSpan('@livestore/common:leader-thread:initial-sync-blocking'),
|
238
|
+
)
|
187
239
|
}
|
188
240
|
|
189
241
|
yield* Queue.offer(bootStatusQueue, { stage: 'done' })
|
190
242
|
|
191
243
|
yield* bootDevtools(devtoolsOptions).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
|
244
|
+
|
245
|
+
return { migrationsReport, leaderHead: initialLeaderHead }
|
192
246
|
})
|
@@ -1,17 +1,20 @@
|
|
1
1
|
import { Effect, Schema } from '@livestore/utils/effect'
|
2
2
|
|
3
|
-
import type {
|
3
|
+
import type { SqliteDb } from '../adapter-types.js'
|
4
4
|
import * as EventId from '../schema/EventId.js'
|
5
|
+
import type * as MutationEvent from '../schema/MutationEvent.js'
|
5
6
|
import { MUTATION_LOG_META_TABLE, mutationLogMetaTable, SYNC_STATUS_TABLE } from '../schema/system-tables.js'
|
6
7
|
import { prepareBindValues, sql } from '../util.js'
|
7
8
|
import { LeaderThreadCtx } from './types.js'
|
8
9
|
|
9
|
-
export const getMutationEventsSince = (
|
10
|
+
export const getMutationEventsSince = (
|
11
|
+
since: EventId.EventId,
|
12
|
+
): Effect.Effect<ReadonlyArray<MutationEvent.AnyEncoded>, never, LeaderThreadCtx> =>
|
10
13
|
Effect.gen(function* () {
|
11
|
-
const {
|
14
|
+
const { dbMutationLog } = yield* LeaderThreadCtx
|
12
15
|
|
13
16
|
const query = mutationLogMetaTable.query.where('idGlobal', '>=', since.global).asSql()
|
14
|
-
const pendingMutationEventsRaw =
|
17
|
+
const pendingMutationEventsRaw = dbMutationLog.select(query.query, prepareBindValues(query.bindValues, query.query))
|
15
18
|
const pendingMutationEvents = Schema.decodeUnknownSync(mutationLogMetaTable.schema.pipe(Schema.Array))(
|
16
19
|
pendingMutationEventsRaw,
|
17
20
|
)
|
@@ -20,23 +23,26 @@ export const getMutationEventsSince = (since: EventId.EventId) =>
|
|
20
23
|
.map((_) => ({
|
21
24
|
mutation: _.mutation,
|
22
25
|
args: _.argsJson,
|
23
|
-
id: { global: _.idGlobal,
|
24
|
-
parentId: { global: _.parentIdGlobal,
|
26
|
+
id: { global: _.idGlobal, client: _.idClient },
|
27
|
+
parentId: { global: _.parentIdGlobal, client: _.parentIdClient },
|
28
|
+
clientId: _.clientId,
|
29
|
+
sessionId: _.sessionId ?? undefined,
|
25
30
|
}))
|
26
31
|
.filter((_) => EventId.compare(_.id, since) > 0)
|
27
32
|
})
|
28
33
|
|
29
|
-
export const
|
30
|
-
const res =
|
31
|
-
sql`select idGlobal,
|
34
|
+
export const getClientHeadFromDb = (dbMutationLog: SqliteDb): EventId.EventId => {
|
35
|
+
const res = dbMutationLog.select<{ idGlobal: EventId.GlobalEventId; idClient: EventId.ClientEventId }>(
|
36
|
+
sql`select idGlobal, idClient from ${MUTATION_LOG_META_TABLE} order by idGlobal DESC, idClient DESC limit 1`,
|
32
37
|
)[0]
|
33
38
|
|
34
|
-
return res ? { global: res.idGlobal,
|
39
|
+
return res ? { global: res.idGlobal, client: res.idClient } : EventId.ROOT
|
35
40
|
}
|
36
41
|
|
37
|
-
export const getBackendHeadFromDb = (
|
38
|
-
|
42
|
+
export const getBackendHeadFromDb = (dbMutationLog: SqliteDb): EventId.GlobalEventId =>
|
43
|
+
dbMutationLog.select<{ head: EventId.GlobalEventId }>(sql`select head from ${SYNC_STATUS_TABLE}`)[0]?.head ??
|
44
|
+
EventId.ROOT.global
|
39
45
|
|
40
46
|
// TODO use prepared statements
|
41
|
-
export const updateBackendHead = (
|
42
|
-
|
47
|
+
export const updateBackendHead = (dbMutationLog: SqliteDb, head: EventId.EventId) =>
|
48
|
+
dbMutationLog.execute(sql`UPDATE ${SYNC_STATUS_TABLE} SET head = ${head.global}`)
|
@@ -2,7 +2,7 @@ import { Effect, Queue } from '@livestore/utils/effect'
|
|
2
2
|
|
3
3
|
import * as MutationEvent from '../schema/MutationEvent.js'
|
4
4
|
import { getMutationEventsSince } from './mutationlog.js'
|
5
|
-
import { type PullQueueItem, type PullQueueSet } from './types.js'
|
5
|
+
import { LeaderThreadCtx, type PullQueueItem, type PullQueueSet } from './types.js'
|
6
6
|
|
7
7
|
export const makePullQueueSet = Effect.gen(function* () {
|
8
8
|
const set = new Set<Queue.Queue<PullQueueItem>>()
|
@@ -46,6 +46,15 @@ export const makePullQueueSet = Effect.gen(function* () {
|
|
46
46
|
return
|
47
47
|
}
|
48
48
|
|
49
|
+
const { clientId } = yield* LeaderThreadCtx
|
50
|
+
if (clientId === 'client-b') {
|
51
|
+
// console.log(
|
52
|
+
// 'offer',
|
53
|
+
// item.payload._tag,
|
54
|
+
// item.payload.newEvents.map((_) => _.toJSON()),
|
55
|
+
// )
|
56
|
+
}
|
57
|
+
|
49
58
|
for (const queue of set) {
|
50
59
|
yield* Queue.offer(queue, item)
|
51
60
|
}
|
@@ -2,85 +2,94 @@ import { casesHandled } from '@livestore/utils'
|
|
2
2
|
import type { HttpClient } from '@livestore/utils/effect'
|
3
3
|
import { Effect, Queue } from '@livestore/utils/effect'
|
4
4
|
|
5
|
-
import type { InvalidPullError, IsOfflineError, MigrationHooks, SqliteError } from '../index.js'
|
5
|
+
import type { InvalidPullError, IsOfflineError, MigrationHooks, MigrationsReport, SqliteError } from '../index.js'
|
6
6
|
import { initializeSingletonTables, migrateDb, rehydrateFromMutationLog, UnexpectedError } from '../index.js'
|
7
7
|
import { configureConnection } from './connection.js'
|
8
8
|
import { LeaderThreadCtx } from './types.js'
|
9
9
|
|
10
10
|
export const recreateDb: Effect.Effect<
|
11
|
-
|
11
|
+
{ migrationsReport: MigrationsReport },
|
12
12
|
UnexpectedError | SqliteError | IsOfflineError | InvalidPullError,
|
13
13
|
LeaderThreadCtx | HttpClient.HttpClient
|
14
14
|
> = Effect.gen(function* () {
|
15
|
-
const {
|
15
|
+
const { dbReadModel, dbMutationLog, schema, bootStatusQueue } = yield* LeaderThreadCtx
|
16
16
|
|
17
17
|
const migrationOptions = schema.migrationOptions
|
18
|
+
let migrationsReport: MigrationsReport
|
18
19
|
|
19
20
|
yield* Effect.addFinalizer(
|
20
21
|
Effect.fn('recreateDb:finalizer')(function* (ex) {
|
21
|
-
if (ex._tag === 'Failure')
|
22
|
+
if (ex._tag === 'Failure') dbReadModel.destroy()
|
22
23
|
}),
|
23
24
|
)
|
24
25
|
|
25
26
|
// NOTE to speed up the operations below, we're creating a temporary in-memory database
|
26
27
|
// and later we'll overwrite the persisted database with the new data
|
27
|
-
|
28
|
-
yield*
|
28
|
+
// TODO bring back this optimization
|
29
|
+
// const tmpDb = yield* makeSqliteDb({ _tag: 'in-memory' })
|
30
|
+
const tmpDb = dbReadModel
|
31
|
+
yield* configureConnection(tmpDb, { foreignKeys: true })
|
29
32
|
|
30
33
|
const initDb = (hooks: Partial<MigrationHooks> | undefined) =>
|
31
34
|
Effect.gen(function* () {
|
32
|
-
yield* Effect.tryAll(() => hooks?.init?.(
|
35
|
+
yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
33
36
|
|
34
|
-
yield* migrateDb({
|
35
|
-
db:
|
37
|
+
const migrationsReport = yield* migrateDb({
|
38
|
+
db: tmpDb,
|
36
39
|
schema,
|
37
40
|
onProgress: ({ done, total }) =>
|
38
41
|
Queue.offer(bootStatusQueue, { stage: 'migrating', progress: { done, total } }),
|
39
42
|
})
|
40
43
|
|
41
|
-
initializeSingletonTables(schema,
|
44
|
+
initializeSingletonTables(schema, tmpDb)
|
42
45
|
|
43
|
-
yield* Effect.tryAll(() => hooks?.pre?.(
|
46
|
+
yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
44
47
|
|
45
|
-
return
|
48
|
+
return { migrationsReport, tmpDb }
|
46
49
|
})
|
47
50
|
|
48
51
|
switch (migrationOptions.strategy) {
|
49
52
|
case 'from-mutation-log': {
|
50
53
|
const hooks = migrationOptions.hooks
|
51
|
-
const
|
54
|
+
const initResult = yield* initDb(hooks)
|
55
|
+
|
56
|
+
migrationsReport = initResult.migrationsReport
|
52
57
|
|
53
58
|
yield* rehydrateFromMutationLog({
|
54
|
-
db:
|
55
|
-
logDb:
|
59
|
+
db: initResult.tmpDb,
|
60
|
+
logDb: dbMutationLog,
|
56
61
|
schema,
|
57
62
|
migrationOptions,
|
58
63
|
onProgress: ({ done, total }) =>
|
59
64
|
Queue.offer(bootStatusQueue, { stage: 'rehydrating', progress: { done, total } }),
|
60
65
|
})
|
61
66
|
|
62
|
-
yield* Effect.tryAll(() => hooks?.post?.(
|
67
|
+
yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
63
68
|
|
64
69
|
break
|
65
70
|
}
|
66
71
|
case 'hard-reset': {
|
67
72
|
const hooks = migrationOptions.hooks
|
68
|
-
const
|
73
|
+
const initResult = yield* initDb(hooks)
|
74
|
+
|
75
|
+
migrationsReport = initResult.migrationsReport
|
69
76
|
|
70
77
|
// The database is migrated but empty now, so nothing else to do
|
71
78
|
|
72
|
-
yield* Effect.tryAll(() => hooks?.post?.(
|
79
|
+
yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
73
80
|
|
74
81
|
break
|
75
82
|
}
|
76
83
|
case 'manual': {
|
77
|
-
const oldDbData =
|
84
|
+
const oldDbData = dbReadModel.export()
|
85
|
+
|
86
|
+
migrationsReport = { migrations: [] }
|
78
87
|
|
79
88
|
const newDbData = yield* Effect.tryAll(() => migrationOptions.migrate(oldDbData)).pipe(
|
80
89
|
UnexpectedError.mapToUnexpectedError,
|
81
90
|
)
|
82
91
|
|
83
|
-
|
92
|
+
tmpDb.import(newDbData)
|
84
93
|
|
85
94
|
// TODO validate schema
|
86
95
|
|
@@ -91,17 +100,21 @@ export const recreateDb: Effect.Effect<
|
|
91
100
|
}
|
92
101
|
}
|
93
102
|
|
103
|
+
// TODO bring back
|
94
104
|
// Import the temporary in-memory database into the persistent database
|
95
|
-
yield* Effect.sync(() => db.import(
|
96
|
-
|
97
|
-
)
|
105
|
+
// yield* Effect.sync(() => db.import(tmpDb)).pipe(
|
106
|
+
// Effect.withSpan('@livestore/common:leader-thread:recreateDb:import'),
|
107
|
+
// )
|
98
108
|
|
99
109
|
// TODO maybe bring back re-using this initial snapshot to avoid calling `.export()` again
|
100
110
|
// We've disabled this for now as it made the code too complex, as we often run syncing right after
|
101
111
|
// so the snapshot is no longer up to date
|
102
|
-
// const snapshotFromTmpDb =
|
112
|
+
// const snapshotFromTmpDb = tmpDb.export()
|
113
|
+
|
114
|
+
// TODO bring back
|
115
|
+
// tmpDb.close()
|
103
116
|
|
104
|
-
|
117
|
+
return { migrationsReport }
|
105
118
|
}).pipe(
|
106
119
|
Effect.scoped, // NOTE we're closing the scope here so finalizers are called when the effect is done
|
107
120
|
Effect.withSpan('@livestore/common:leader-thread:recreateDb'),
|
@@ -1,11 +1,9 @@
|
|
1
1
|
import type { WebChannel } from '@livestore/utils/effect'
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
3
3
|
|
4
|
-
import { IntentionalShutdownCause } from '../index.js'
|
4
|
+
import { IntentionalShutdownCause, UnexpectedError } from '../index.js'
|
5
5
|
|
6
|
-
export class
|
7
|
-
|
8
|
-
export class All extends Schema.Union(IntentionalShutdownCause, DedicatedWorkerDisconnectBroadcast) {}
|
6
|
+
export class All extends Schema.Union(IntentionalShutdownCause, UnexpectedError) {}
|
9
7
|
|
10
8
|
/**
|
11
9
|
* Used internally by an adapter to shutdown gracefully.
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import type {
|
2
2
|
Deferred,
|
3
3
|
Effect,
|
4
|
-
Fiber,
|
5
4
|
HttpClient,
|
6
5
|
Option,
|
7
6
|
Queue,
|
8
7
|
Scope,
|
8
|
+
Subscribable,
|
9
9
|
SubscriptionRef,
|
10
10
|
WebChannel,
|
11
11
|
} from '@livestore/utils/effect'
|
@@ -14,31 +14,25 @@ import { Context, Schema } from '@livestore/utils/effect'
|
|
14
14
|
import type {
|
15
15
|
BootStatus,
|
16
16
|
Devtools,
|
17
|
-
|
18
|
-
|
17
|
+
LeaderAheadError,
|
18
|
+
MakeSqliteDb,
|
19
|
+
MigrationsReport,
|
19
20
|
PersistenceInfo,
|
21
|
+
SqliteDb,
|
20
22
|
SyncBackend,
|
21
|
-
SynchronousDatabase,
|
22
23
|
UnexpectedError,
|
23
24
|
} from '../index.js'
|
24
25
|
import type { EventId, LiveStoreSchema, MutationEvent } from '../schema/mod.js'
|
25
|
-
import type
|
26
|
+
import type * as SyncState from '../sync/syncstate.js'
|
26
27
|
import type { ShutdownChannel } from './shutdown-channel.js'
|
27
28
|
|
28
29
|
export type ShutdownState = 'running' | 'shutting-down'
|
29
30
|
|
30
|
-
export class OuterWorkerCtx extends Context.Tag('OuterWorkerCtx')<
|
31
|
-
OuterWorkerCtx,
|
32
|
-
{
|
33
|
-
innerFiber: Fiber.RuntimeFiber<any, any>
|
34
|
-
}
|
35
|
-
>() {}
|
36
|
-
|
37
31
|
export const InitialSyncOptionsSkip = Schema.TaggedStruct('Skip', {})
|
38
32
|
export type InitialSyncOptionsSkip = typeof InitialSyncOptionsSkip.Type
|
39
33
|
|
40
34
|
export const InitialSyncOptionsBlocking = Schema.TaggedStruct('Blocking', {
|
41
|
-
timeout: Schema.DurationFromMillis,
|
35
|
+
timeout: Schema.Union(Schema.DurationFromMillis, Schema.Number),
|
42
36
|
})
|
43
37
|
|
44
38
|
export type InitialSyncOptionsBlocking = typeof InitialSyncOptionsBlocking.Type
|
@@ -55,8 +49,8 @@ export type InitialSyncInfo = Option.Option<{
|
|
55
49
|
// | { _tag: 'Recreate'; snapshotRef: Ref.Ref<Uint8Array | undefined>; syncInfo: InitialSyncInfo }
|
56
50
|
// | { _tag: 'Reuse'; syncInfo: InitialSyncInfo }
|
57
51
|
|
58
|
-
export type
|
59
|
-
export type PersistenceInfoPair = {
|
52
|
+
export type LeaderSqliteDb = SqliteDb<{ dbPointer: number; persistenceInfo: PersistenceInfo }>
|
53
|
+
export type PersistenceInfoPair = { readModel: PersistenceInfo; mutationLog: PersistenceInfo }
|
60
54
|
|
61
55
|
export type DevtoolsOptions =
|
62
56
|
| {
|
@@ -64,10 +58,9 @@ export type DevtoolsOptions =
|
|
64
58
|
}
|
65
59
|
| {
|
66
60
|
enabled: true
|
67
|
-
|
61
|
+
makeBootContext: Effect.Effect<
|
68
62
|
{
|
69
|
-
devtoolsWebChannel: WebChannel.WebChannel<Devtools.
|
70
|
-
shutdownChannel: ShutdownChannel
|
63
|
+
devtoolsWebChannel: WebChannel.WebChannel<Devtools.Leader.MessageToApp, Devtools.Leader.MessageFromApp>
|
71
64
|
persistenceInfo: PersistenceInfoPair
|
72
65
|
},
|
73
66
|
UnexpectedError,
|
@@ -75,23 +68,46 @@ export type DevtoolsOptions =
|
|
75
68
|
>
|
76
69
|
}
|
77
70
|
|
71
|
+
export type DevtoolsContext =
|
72
|
+
| {
|
73
|
+
enabled: true
|
74
|
+
// syncBackendPullLatch: Effect.Latch
|
75
|
+
// syncBackendPushLatch: Effect.Latch
|
76
|
+
syncBackendLatch: Effect.Latch
|
77
|
+
syncBackendLatchState: SubscriptionRef.SubscriptionRef<{ latchClosed: boolean }>
|
78
|
+
}
|
79
|
+
| {
|
80
|
+
enabled: false
|
81
|
+
}
|
82
|
+
|
78
83
|
export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
|
79
84
|
LeaderThreadCtx,
|
80
85
|
{
|
81
86
|
schema: LiveStoreSchema
|
82
87
|
storeId: string
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
clientId: string
|
89
|
+
makeSqliteDb: MakeSqliteDb
|
90
|
+
dbReadModel: LeaderSqliteDb
|
91
|
+
dbMutationLog: LeaderSqliteDb
|
87
92
|
bootStatusQueue: Queue.Queue<BootStatus>
|
88
93
|
// TODO we should find a more elegant way to handle cases which need this ref for their implementation
|
89
94
|
shutdownStateSubRef: SubscriptionRef.SubscriptionRef<ShutdownState>
|
95
|
+
shutdownChannel: ShutdownChannel
|
90
96
|
mutationEventSchema: MutationEvent.ForMutationDefRecord<any>
|
91
|
-
|
97
|
+
devtools: DevtoolsContext
|
92
98
|
syncBackend: SyncBackend | undefined
|
93
|
-
syncProcessor:
|
99
|
+
syncProcessor: LeaderSyncProcessor
|
94
100
|
connectedClientSessionPullQueues: PullQueueSet
|
101
|
+
initialState: {
|
102
|
+
leaderHead: EventId.EventId
|
103
|
+
migrationsReport: MigrationsReport
|
104
|
+
}
|
105
|
+
/**
|
106
|
+
* e.g. used for `store._dev` APIs
|
107
|
+
*
|
108
|
+
* This is currently separated from `.devtools` as it also needs to work when devtools are disabled
|
109
|
+
*/
|
110
|
+
extraIncomingMessagesQueue: Queue.Queue<Devtools.Leader.MessageToApp>
|
95
111
|
}
|
96
112
|
>() {}
|
97
113
|
|
@@ -101,24 +117,42 @@ export type InitialBlockingSyncContext = {
|
|
101
117
|
}
|
102
118
|
|
103
119
|
export type PullQueueItem = {
|
104
|
-
|
105
|
-
// backendHead: number
|
106
|
-
payload: PayloadUpstream
|
107
|
-
// TODO move `remaining` into `PayloadUpstream`
|
120
|
+
payload: SyncState.PayloadUpstream
|
108
121
|
remaining: number
|
109
122
|
}
|
110
123
|
|
111
|
-
export interface
|
124
|
+
export interface LeaderSyncProcessor {
|
112
125
|
push: (
|
113
126
|
/** `batch` needs to follow the same rules as `batch` in `SyncBackend.push` */
|
114
127
|
batch: ReadonlyArray<MutationEvent.EncodedWithMeta>,
|
115
|
-
|
116
|
-
|
117
|
-
|
128
|
+
options?: {
|
129
|
+
/**
|
130
|
+
* This generation number is used to automatically reject subsequent pushes
|
131
|
+
* of a previously rejected push from a client session. This might occur in
|
132
|
+
* certain concurrent scenarios.
|
133
|
+
*/
|
134
|
+
// generation: number
|
135
|
+
/**
|
136
|
+
* If true, the effect will only finish when the local push has been processed (i.e. succeeded or was rejected).
|
137
|
+
* @default false
|
138
|
+
*/
|
139
|
+
waitForProcessing?: boolean
|
140
|
+
},
|
141
|
+
) => Effect.Effect<void, LeaderAheadError>
|
142
|
+
|
143
|
+
pushPartial: (args: {
|
144
|
+
mutationEvent: MutationEvent.PartialAnyEncoded
|
145
|
+
clientId: string
|
146
|
+
sessionId: string | undefined
|
147
|
+
}) => Effect.Effect<void, UnexpectedError, LeaderThreadCtx>
|
118
148
|
boot: (args: {
|
119
149
|
dbReady: Deferred.Deferred<void>
|
120
|
-
}) => Effect.Effect<
|
121
|
-
|
150
|
+
}) => Effect.Effect<
|
151
|
+
{ initialLeaderHead: EventId.EventId },
|
152
|
+
UnexpectedError,
|
153
|
+
LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
|
154
|
+
>
|
155
|
+
syncState: Subscribable.Subscribable<SyncState.SyncState>
|
122
156
|
}
|
123
157
|
|
124
158
|
export interface PullQueueSet {
|