@livestore/common 0.3.0-dev.11 → 0.3.0-dev.13
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 +41 -18
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +12 -0
- package/dist/adapter-types.js.map +1 -1
- package/dist/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/db-schema/ast/sqlite.js +71 -0
- package/dist/db-schema/ast/sqlite.js.map +1 -0
- package/dist/db-schema/ast/validate.d.ts +3 -0
- package/dist/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/db-schema/ast/validate.js +12 -0
- package/dist/db-schema/ast/validate.js.map +1 -0
- package/dist/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/db-schema/dsl/field-defs.js +87 -0
- package/dist/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/db-schema/dsl/index.d.ts +88 -0
- package/dist/db-schema/dsl/index.d.ts.map +1 -0
- package/dist/db-schema/dsl/index.js +35 -0
- package/dist/db-schema/dsl/index.js.map +1 -0
- package/dist/db-schema/dsl/mod.d.ts +90 -0
- package/dist/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/db-schema/dsl/mod.js +35 -0
- package/dist/db-schema/dsl/mod.js.map +1 -0
- package/dist/db-schema/dsl/sqlite/field-defs.d.ts +90 -0
- package/dist/db-schema/dsl/sqlite/field-defs.d.ts.map +1 -0
- package/dist/db-schema/dsl/sqlite/field-defs.js +86 -0
- package/dist/db-schema/dsl/sqlite/field-defs.js.map +1 -0
- package/dist/db-schema/dsl/sqlite/field-defs.test.d.ts +2 -0
- package/dist/db-schema/dsl/sqlite/field-defs.test.d.ts.map +1 -0
- package/dist/db-schema/dsl/sqlite/field-defs.test.js +29 -0
- package/dist/db-schema/dsl/sqlite/field-defs.test.js.map +1 -0
- package/dist/db-schema/dsl/sqlite/index.d.ts +88 -0
- package/dist/db-schema/dsl/sqlite/index.d.ts.map +1 -0
- package/dist/db-schema/dsl/sqlite/index.js +35 -0
- package/dist/db-schema/dsl/sqlite/index.js.map +1 -0
- package/dist/db-schema/hash.d.ts +2 -0
- package/dist/db-schema/hash.d.ts.map +1 -0
- package/dist/db-schema/hash.js +14 -0
- package/dist/db-schema/hash.js.map +1 -0
- package/dist/db-schema/index.d.ts +4 -0
- package/dist/db-schema/index.d.ts.map +1 -0
- package/dist/db-schema/index.js +6 -0
- package/dist/db-schema/index.js.map +1 -0
- package/dist/db-schema/mod.d.ts +3 -0
- package/dist/db-schema/mod.d.ts.map +1 -0
- package/dist/db-schema/mod.js +3 -0
- package/dist/db-schema/mod.js.map +1 -0
- package/dist/derived-mutations.d.ts +1 -1
- 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/devtools/devtools-bridge.d.ts +10 -7
- package/dist/devtools/devtools-bridge.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +101 -28
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-client-session.js +19 -3
- package/dist/devtools/devtools-messages-client-session.js.map +1 -1
- package/dist/devtools/devtools-messages-common.d.ts +24 -32
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.js +19 -10
- package/dist/devtools/devtools-messages-common.js.map +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +220 -56
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.js +57 -9
- package/dist/devtools/devtools-messages-leader.js.map +1 -1
- package/dist/devtools/devtools-messages.d.ts +2 -2
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +2 -2
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +50 -35
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.js +8 -6
- package/dist/leader-thread/apply-mutation.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +31 -3
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +18 -3
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +56 -31
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +23 -6
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mutationlog.d.ts +1 -1
- package/dist/leader-thread/mutationlog.d.ts.map +1 -1
- package/dist/leader-thread/mutationlog.js +7 -5
- package/dist/leader-thread/mutationlog.js.map +1 -1
- package/dist/leader-thread/pull-queue-set.d.ts.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 +13 -8
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/types.d.ts +22 -15
- 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/query-builder/api.d.ts +3 -3
- package/dist/query-builder/api.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.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +8 -6
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +10 -9
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +14 -11
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/EventId.test.js +3 -3
- package/dist/schema/EventId.test.js.map +1 -1
- package/dist/schema/MutationEvent.d.ts +37 -12
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +20 -4
- 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 +4 -8
- 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.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/schema.d.ts +1 -1
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +1 -1
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/system-tables.d.ts +47 -29
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +10 -7
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +18 -14
- 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/migrations.d.ts +3 -3
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +7 -2
- package/dist/schema-management/migrations.js.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/ClientSessionSyncProcessor.d.ts +3 -5
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +38 -12
- package/dist/sync/ClientSessionSyncProcessor.js.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 +2 -0
- 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 +3 -1
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +5 -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 +11 -11
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.js +12 -10
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +2 -2
- package/dist/sync/syncstate.d.ts +9 -9
- package/dist/sync/syncstate.js +6 -6
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +18 -16
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -3
- package/src/adapter-types.ts +35 -17
- package/src/derived-mutations.ts +4 -4
- package/src/devtools/devtools-bridge.ts +10 -7
- package/src/devtools/devtools-messages-client-session.ts +26 -10
- package/src/devtools/devtools-messages-common.ts +37 -8
- package/src/devtools/devtools-messages-leader.ts +78 -16
- package/src/devtools/devtools-messages.ts +2 -2
- package/src/index.ts +1 -1
- package/src/leader-thread/LeaderSyncProcessor.ts +59 -38
- package/src/leader-thread/apply-mutation.ts +15 -5
- package/src/leader-thread/connection.ts +48 -3
- package/src/leader-thread/leader-worker-devtools.ts +85 -35
- package/src/leader-thread/make-leader-thread-layer.ts +29 -9
- package/src/leader-thread/mutationlog.ts +8 -6
- package/src/leader-thread/recreate-db.ts +19 -10
- package/src/leader-thread/types.ts +22 -15
- 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 +8 -6
- package/src/schema/EventId.test.ts +3 -3
- package/src/schema/EventId.ts +20 -16
- package/src/schema/MutationEvent.ts +31 -6
- 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 +6 -19
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/schema.ts +2 -2
- package/src/schema/system-tables.ts +10 -7
- package/src/schema/table-def.ts +17 -16
- package/src/schema-management/migrations.ts +10 -6
- 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 +44 -14
- 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 +8 -2
- 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 -12
- package/src/sync/syncstate.test.ts +19 -17
- package/src/sync/syncstate.ts +6 -6
- package/src/version.ts +1 -1
- package/tsconfig.json +1 -1
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { HttpClient, Scope } from '@livestore/utils/effect'
|
2
2
|
import { Deferred, Effect, Layer, Queue, SubscriptionRef } from '@livestore/utils/effect'
|
3
3
|
|
4
|
-
import type { BootStatus, MakeSqliteDb, SqliteError } from '../adapter-types.js'
|
4
|
+
import type { BootStatus, MakeSqliteDb, MigrationsReport, SqliteError } from '../adapter-types.js'
|
5
5
|
import { UnexpectedError } from '../adapter-types.js'
|
6
6
|
import type * as Devtools from '../devtools/index.js'
|
7
7
|
import type { LiveStoreSchema } from '../schema/mod.js'
|
@@ -67,15 +67,15 @@ export const makeLeaderThreadLayer = ({
|
|
67
67
|
initialBlockingSyncContext,
|
68
68
|
})
|
69
69
|
|
70
|
-
const extraIncomingMessagesQueue = yield* Queue.unbounded<Devtools.
|
70
|
+
const extraIncomingMessagesQueue = yield* Queue.unbounded<Devtools.Leader.MessageToApp>().pipe(
|
71
71
|
Effect.acquireRelease(Queue.shutdown),
|
72
72
|
)
|
73
73
|
|
74
74
|
const devtoolsContext = devtoolsOptions.enabled
|
75
75
|
? {
|
76
76
|
enabled: true as const,
|
77
|
-
|
78
|
-
|
77
|
+
syncBackendLatch: yield* Effect.makeLatch(true),
|
78
|
+
syncBackendLatchState: yield* SubscriptionRef.make<{ latchClosed: boolean }>({ latchClosed: false }),
|
79
79
|
}
|
80
80
|
: { enabled: false as const }
|
81
81
|
|
@@ -95,6 +95,8 @@ export const makeLeaderThreadLayer = ({
|
|
95
95
|
connectedClientSessionPullQueues: yield* makePullQueueSet,
|
96
96
|
extraIncomingMessagesQueue,
|
97
97
|
devtools: devtoolsContext,
|
98
|
+
// State will be set during `bootLeaderThread`
|
99
|
+
initialState: {} as any as LeaderThreadCtx['Type']['initialState'],
|
98
100
|
} satisfies typeof LeaderThreadCtx.Service
|
99
101
|
|
100
102
|
// @ts-expect-error For debugging purposes
|
@@ -102,7 +104,11 @@ export const makeLeaderThreadLayer = ({
|
|
102
104
|
|
103
105
|
const layer = Layer.succeed(LeaderThreadCtx, ctx)
|
104
106
|
|
105
|
-
yield* bootLeaderThread({
|
107
|
+
ctx.initialState = yield* bootLeaderThread({
|
108
|
+
dbMissing,
|
109
|
+
initialBlockingSyncContext,
|
110
|
+
devtoolsOptions,
|
111
|
+
}).pipe(Effect.provide(layer))
|
106
112
|
|
107
113
|
return layer
|
108
114
|
}).pipe(
|
@@ -172,7 +178,7 @@ const bootLeaderThread = ({
|
|
172
178
|
initialBlockingSyncContext: InitialBlockingSyncContext
|
173
179
|
devtoolsOptions: DevtoolsOptions
|
174
180
|
}): Effect.Effect<
|
175
|
-
|
181
|
+
LeaderThreadCtx['Type']['initialState'],
|
176
182
|
UnexpectedError | SqliteError | IsOfflineError | InvalidPullError,
|
177
183
|
LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
|
178
184
|
> =>
|
@@ -206,19 +212,33 @@ const bootLeaderThread = ({
|
|
206
212
|
|
207
213
|
// We're already starting pulling from the sync backend concurrently but wait until the db is ready before
|
208
214
|
// processing any incoming mutations
|
209
|
-
yield* syncProcessor.boot({ dbReady })
|
215
|
+
const { initialLeaderHead } = yield* syncProcessor.boot({ dbReady })
|
210
216
|
|
217
|
+
let migrationsReport: MigrationsReport
|
211
218
|
if (dbMissing) {
|
212
|
-
yield* recreateDb
|
219
|
+
const recreateResult = yield* recreateDb
|
220
|
+
migrationsReport = recreateResult.migrationsReport
|
221
|
+
} else {
|
222
|
+
migrationsReport = { migrations: [] }
|
213
223
|
}
|
214
224
|
|
215
225
|
yield* Deferred.succeed(dbReady, void 0)
|
216
226
|
|
217
227
|
if (initialBlockingSyncContext.blockingDeferred !== undefined) {
|
218
|
-
|
228
|
+
// Provides a syncing status right away before the first pull response comes in
|
229
|
+
yield* Queue.offer(bootStatusQueue, {
|
230
|
+
stage: 'syncing',
|
231
|
+
progress: { done: 0, total: -1 },
|
232
|
+
})
|
233
|
+
|
234
|
+
yield* initialBlockingSyncContext.blockingDeferred.pipe(
|
235
|
+
Effect.withSpan('@livestore/common:leader-thread:initial-sync-blocking'),
|
236
|
+
)
|
219
237
|
}
|
220
238
|
|
221
239
|
yield* Queue.offer(bootStatusQueue, { stage: 'done' })
|
222
240
|
|
223
241
|
yield* bootDevtools(devtoolsOptions).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
|
242
|
+
|
243
|
+
return { migrationsReport, leaderHead: initialLeaderHead }
|
224
244
|
})
|
@@ -23,18 +23,20 @@ export const getMutationEventsSince = (
|
|
23
23
|
.map((_) => ({
|
24
24
|
mutation: _.mutation,
|
25
25
|
args: _.argsJson,
|
26
|
-
id: { global: _.idGlobal,
|
27
|
-
parentId: { global: _.parentIdGlobal,
|
26
|
+
id: { global: _.idGlobal, client: _.idClient },
|
27
|
+
parentId: { global: _.parentIdGlobal, client: _.parentIdClient },
|
28
|
+
clientId: _.clientId,
|
29
|
+
sessionId: _.sessionId ?? undefined,
|
28
30
|
}))
|
29
31
|
.filter((_) => EventId.compare(_.id, since) > 0)
|
30
32
|
})
|
31
33
|
|
32
|
-
export const
|
33
|
-
const res = dbMutationLog.select<{ idGlobal: EventId.GlobalEventId;
|
34
|
-
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`,
|
35
37
|
)[0]
|
36
38
|
|
37
|
-
return res ? { global: res.idGlobal,
|
39
|
+
return res ? { global: res.idGlobal, client: res.idClient } : EventId.ROOT
|
38
40
|
}
|
39
41
|
|
40
42
|
export const getBackendHeadFromDb = (dbMutationLog: SqliteDb): EventId.GlobalEventId =>
|
@@ -2,19 +2,20 @@ 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
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) {
|
@@ -27,13 +28,13 @@ export const recreateDb: Effect.Effect<
|
|
27
28
|
// TODO bring back this optimization
|
28
29
|
// const tmpDb = yield* makeSqliteDb({ _tag: 'in-memory' })
|
29
30
|
const tmpDb = dbReadModel
|
30
|
-
yield* configureConnection(tmpDb, {
|
31
|
+
yield* configureConnection(tmpDb, { foreignKeys: true })
|
31
32
|
|
32
33
|
const initDb = (hooks: Partial<MigrationHooks> | undefined) =>
|
33
34
|
Effect.gen(function* () {
|
34
35
|
yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
35
36
|
|
36
|
-
yield* migrateDb({
|
37
|
+
const migrationsReport = yield* migrateDb({
|
37
38
|
db: tmpDb,
|
38
39
|
schema,
|
39
40
|
onProgress: ({ done, total }) =>
|
@@ -44,16 +45,18 @@ export const recreateDb: Effect.Effect<
|
|
44
45
|
|
45
46
|
yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
46
47
|
|
47
|
-
return tmpDb
|
48
|
+
return { migrationsReport, tmpDb }
|
48
49
|
})
|
49
50
|
|
50
51
|
switch (migrationOptions.strategy) {
|
51
52
|
case 'from-mutation-log': {
|
52
53
|
const hooks = migrationOptions.hooks
|
53
|
-
const
|
54
|
+
const initResult = yield* initDb(hooks)
|
55
|
+
|
56
|
+
migrationsReport = initResult.migrationsReport
|
54
57
|
|
55
58
|
yield* rehydrateFromMutationLog({
|
56
|
-
db: tmpDb,
|
59
|
+
db: initResult.tmpDb,
|
57
60
|
logDb: dbMutationLog,
|
58
61
|
schema,
|
59
62
|
migrationOptions,
|
@@ -61,23 +64,27 @@ export const recreateDb: Effect.Effect<
|
|
61
64
|
Queue.offer(bootStatusQueue, { stage: 'rehydrating', progress: { done, total } }),
|
62
65
|
})
|
63
66
|
|
64
|
-
yield* Effect.tryAll(() => hooks?.post?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
67
|
+
yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
65
68
|
|
66
69
|
break
|
67
70
|
}
|
68
71
|
case 'hard-reset': {
|
69
72
|
const hooks = migrationOptions.hooks
|
70
|
-
const
|
73
|
+
const initResult = yield* initDb(hooks)
|
74
|
+
|
75
|
+
migrationsReport = initResult.migrationsReport
|
71
76
|
|
72
77
|
// The database is migrated but empty now, so nothing else to do
|
73
78
|
|
74
|
-
yield* Effect.tryAll(() => hooks?.post?.(
|
79
|
+
yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
|
75
80
|
|
76
81
|
break
|
77
82
|
}
|
78
83
|
case 'manual': {
|
79
84
|
const oldDbData = dbReadModel.export()
|
80
85
|
|
86
|
+
migrationsReport = { migrations: [] }
|
87
|
+
|
81
88
|
const newDbData = yield* Effect.tryAll(() => migrationOptions.migrate(oldDbData)).pipe(
|
82
89
|
UnexpectedError.mapToUnexpectedError,
|
83
90
|
)
|
@@ -106,6 +113,8 @@ export const recreateDb: Effect.Effect<
|
|
106
113
|
|
107
114
|
// TODO bring back
|
108
115
|
// tmpDb.close()
|
116
|
+
|
117
|
+
return { migrationsReport }
|
109
118
|
}).pipe(
|
110
119
|
Effect.scoped, // NOTE we're closing the scope here so finalizers are called when the effect is done
|
111
120
|
Effect.withSpan('@livestore/common:leader-thread:recreateDb'),
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import type {
|
2
2
|
Deferred,
|
3
3
|
Effect,
|
4
|
-
Fiber,
|
5
4
|
HttpClient,
|
6
5
|
Option,
|
7
6
|
Queue,
|
@@ -17,6 +16,7 @@ import type {
|
|
17
16
|
Devtools,
|
18
17
|
InvalidPushError,
|
19
18
|
MakeSqliteDb,
|
19
|
+
MigrationsReport,
|
20
20
|
PersistenceInfo,
|
21
21
|
SqliteDb,
|
22
22
|
SyncBackend,
|
@@ -28,18 +28,11 @@ import type { ShutdownChannel } from './shutdown-channel.js'
|
|
28
28
|
|
29
29
|
export type ShutdownState = 'running' | 'shutting-down'
|
30
30
|
|
31
|
-
export class OuterWorkerCtx extends Context.Tag('OuterWorkerCtx')<
|
32
|
-
OuterWorkerCtx,
|
33
|
-
{
|
34
|
-
innerFiber: Fiber.RuntimeFiber<any, any>
|
35
|
-
}
|
36
|
-
>() {}
|
37
|
-
|
38
31
|
export const InitialSyncOptionsSkip = Schema.TaggedStruct('Skip', {})
|
39
32
|
export type InitialSyncOptionsSkip = typeof InitialSyncOptionsSkip.Type
|
40
33
|
|
41
34
|
export const InitialSyncOptionsBlocking = Schema.TaggedStruct('Blocking', {
|
42
|
-
timeout: Schema.DurationFromMillis,
|
35
|
+
timeout: Schema.Union(Schema.DurationFromMillis, Schema.Number),
|
43
36
|
})
|
44
37
|
|
45
38
|
export type InitialSyncOptionsBlocking = typeof InitialSyncOptionsBlocking.Type
|
@@ -67,7 +60,7 @@ export type DevtoolsOptions =
|
|
67
60
|
enabled: true
|
68
61
|
makeBootContext: Effect.Effect<
|
69
62
|
{
|
70
|
-
devtoolsWebChannel: WebChannel.WebChannel<Devtools.
|
63
|
+
devtoolsWebChannel: WebChannel.WebChannel<Devtools.Leader.MessageToApp, Devtools.Leader.MessageFromApp>
|
71
64
|
persistenceInfo: PersistenceInfoPair
|
72
65
|
},
|
73
66
|
UnexpectedError,
|
@@ -78,8 +71,10 @@ export type DevtoolsOptions =
|
|
78
71
|
export type DevtoolsContext =
|
79
72
|
| {
|
80
73
|
enabled: true
|
81
|
-
syncBackendPullLatch: Effect.Latch
|
82
|
-
syncBackendPushLatch: Effect.Latch
|
74
|
+
// syncBackendPullLatch: Effect.Latch
|
75
|
+
// syncBackendPushLatch: Effect.Latch
|
76
|
+
syncBackendLatch: Effect.Latch
|
77
|
+
syncBackendLatchState: SubscriptionRef.SubscriptionRef<{ latchClosed: boolean }>
|
83
78
|
}
|
84
79
|
| {
|
85
80
|
enabled: false
|
@@ -103,12 +98,16 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
|
|
103
98
|
syncBackend: SyncBackend | undefined
|
104
99
|
syncProcessor: LeaderSyncProcessor
|
105
100
|
connectedClientSessionPullQueues: PullQueueSet
|
101
|
+
initialState: {
|
102
|
+
leaderHead: EventId.EventId
|
103
|
+
migrationsReport: MigrationsReport
|
104
|
+
}
|
106
105
|
/**
|
107
106
|
* e.g. used for `store._dev` APIs
|
108
107
|
*
|
109
108
|
* This is currently separated from `.devtools` as it also needs to work when devtools are disabled
|
110
109
|
*/
|
111
|
-
extraIncomingMessagesQueue: Queue.Queue<Devtools.
|
110
|
+
extraIncomingMessagesQueue: Queue.Queue<Devtools.Leader.MessageToApp>
|
112
111
|
}
|
113
112
|
>() {}
|
114
113
|
|
@@ -135,10 +134,18 @@ export interface LeaderSyncProcessor {
|
|
135
134
|
},
|
136
135
|
) => Effect.Effect<void, InvalidPushError>
|
137
136
|
|
138
|
-
pushPartial: (
|
137
|
+
pushPartial: (args: {
|
138
|
+
mutationEvent: MutationEvent.PartialAnyEncoded
|
139
|
+
clientId: string
|
140
|
+
sessionId: string | undefined
|
141
|
+
}) => Effect.Effect<void, UnexpectedError, LeaderThreadCtx>
|
139
142
|
boot: (args: {
|
140
143
|
dbReady: Deferred.Deferred<void>
|
141
|
-
}) => Effect.Effect<
|
144
|
+
}) => Effect.Effect<
|
145
|
+
{ initialLeaderHead: EventId.EventId },
|
146
|
+
UnexpectedError,
|
147
|
+
LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
|
148
|
+
>
|
142
149
|
syncState: Subscribable.Subscribable<SyncState.SyncState>
|
143
150
|
}
|
144
151
|
|
package/src/query-builder/api.ts
CHANGED
@@ -3,8 +3,8 @@ import { type Option, Predicate, type Schema } from '@livestore/utils/effect'
|
|
3
3
|
|
4
4
|
import type { SessionIdSymbol } from '../adapter-types.js'
|
5
5
|
import type { QueryInfo } from '../query-info.js'
|
6
|
+
import type { SqliteDsl } from '../schema/db-schema/mod.js'
|
6
7
|
import type { DbSchema } from '../schema/mod.js'
|
7
|
-
import type { SqliteDsl } from '../schema/table-def.js'
|
8
8
|
import type { SqlValue } from '../util.js'
|
9
9
|
|
10
10
|
export type QueryBuilderAst = QueryBuilderAst.SelectQuery | QueryBuilderAst.CountQuery | QueryBuilderAst.RowQuery
|
@@ -35,7 +35,7 @@ export namespace QueryBuilderAst {
|
|
35
35
|
export type RowQuery = {
|
36
36
|
readonly _tag: 'RowQuery'
|
37
37
|
readonly tableDef: DbSchema.TableDefBase
|
38
|
-
readonly id: string | SessionIdSymbol
|
38
|
+
readonly id: string | SessionIdSymbol | number
|
39
39
|
readonly insertValues: Record<string, unknown>
|
40
40
|
}
|
41
41
|
|
@@ -252,10 +252,10 @@ export namespace QueryBuilder {
|
|
252
252
|
? (_: 'Error: Need to enable deriveMutations to use row()') => any
|
253
253
|
: TTableDef['options']['requiredInsertColumnNames'] extends never
|
254
254
|
? (
|
255
|
-
id: string | SessionIdSymbol,
|
255
|
+
id: string | SessionIdSymbol | number,
|
256
256
|
) => QueryBuilder<RowQuery.Result<TTableDef>, TTableDef, QueryBuilder.ApiFeature, QueryInfo.Row>
|
257
257
|
: <TOptions extends RowQuery.RequiredColumnsOptions<TTableDef>>(
|
258
|
-
id: string | SessionIdSymbol,
|
258
|
+
id: string | SessionIdSymbol | number,
|
259
259
|
opts: TOptions,
|
260
260
|
) => QueryBuilder<RowQuery.Result<TTableDef>, TTableDef, QueryBuilder.ApiFeature, QueryInfo.Row>
|
261
261
|
}
|
@@ -18,13 +18,23 @@ const todos = DbSchema.table(
|
|
18
18
|
{ deriveMutations: true },
|
19
19
|
)
|
20
20
|
|
21
|
+
const todosWithIntId = DbSchema.table(
|
22
|
+
'todos_with_int_id',
|
23
|
+
{
|
24
|
+
id: DbSchema.integer({ primaryKey: true }),
|
25
|
+
text: DbSchema.text({ default: '', nullable: false }),
|
26
|
+
status: DbSchema.text({ schema: Schema.Literal('active', 'completed') }),
|
27
|
+
},
|
28
|
+
{ deriveMutations: true },
|
29
|
+
)
|
30
|
+
|
21
31
|
const comments = DbSchema.table('comments', {
|
22
32
|
id: DbSchema.text({ primaryKey: true }),
|
23
33
|
text: DbSchema.text({ default: '', nullable: false }),
|
24
34
|
todoId: DbSchema.text({}),
|
25
35
|
})
|
26
36
|
|
27
|
-
const db = { todos: todos.query, comments: comments.query }
|
37
|
+
const db = { todos: todos.query, todosWithIntId: todosWithIntId.query, comments: comments.query }
|
28
38
|
|
29
39
|
describe('query builder', () => {
|
30
40
|
describe('result schema', () => {
|
@@ -204,6 +214,17 @@ describe('query builder', () => {
|
|
204
214
|
}
|
205
215
|
`)
|
206
216
|
})
|
217
|
+
|
218
|
+
it('should handle row queries with numbers', () => {
|
219
|
+
expect(db.todosWithIntId.row(123, { insertValues: { status: 'active' } }).asSql()).toMatchInlineSnapshot(`
|
220
|
+
{
|
221
|
+
"bindValues": [
|
222
|
+
123,
|
223
|
+
],
|
224
|
+
"query": "SELECT * FROM 'todos_with_int_id' WHERE id = ?",
|
225
|
+
}
|
226
|
+
`)
|
227
|
+
})
|
207
228
|
})
|
208
229
|
})
|
209
230
|
|
@@ -128,12 +128,12 @@ export const makeQueryBuilder = <TResult, TTableDef extends DbSchema.TableDefBas
|
|
128
128
|
// eslint-disable-next-line prefer-rest-params
|
129
129
|
const params = [...arguments]
|
130
130
|
|
131
|
-
let id: string
|
131
|
+
let id: string | number
|
132
132
|
|
133
133
|
if (tableDef.options.isSingleton) {
|
134
134
|
id = tableDef.sqliteDef.columns.id!.default.pipe(Option.getOrThrow)
|
135
135
|
} else {
|
136
|
-
id = params[0] as string
|
136
|
+
id = params[0] as string | number
|
137
137
|
if (id === undefined) {
|
138
138
|
invalidQueryBuilder(`Id missing for row query on non-singleton table ${tableDef.sqliteDef.name}`)
|
139
139
|
}
|
package/src/query-info.ts
CHANGED
@@ -24,20 +24,20 @@ export namespace QueryInfo {
|
|
24
24
|
export type Row = {
|
25
25
|
_tag: 'Row'
|
26
26
|
table: DbSchema.TableDefBase
|
27
|
-
id: string | SessionIdSymbol
|
27
|
+
id: string | SessionIdSymbol | number
|
28
28
|
}
|
29
29
|
|
30
30
|
export type Col = {
|
31
31
|
_tag: 'Col'
|
32
32
|
table: DbSchema.TableDefBase
|
33
|
-
id: string | SessionIdSymbol
|
33
|
+
id: string | SessionIdSymbol | number
|
34
34
|
column: string
|
35
35
|
}
|
36
36
|
|
37
37
|
export type ColJsonValue = {
|
38
38
|
_tag: 'ColJsonValue'
|
39
39
|
table: DbSchema.TableDefBase
|
40
|
-
id: string | SessionIdSymbol
|
40
|
+
id: string | SessionIdSymbol | number
|
41
41
|
column: string
|
42
42
|
/**
|
43
43
|
* example: `$.tabs[3].items[2]` (`$` referring to the column value)
|
@@ -60,10 +60,12 @@ This likely means the schema has changed in an incompatible way.
|
|
60
60
|
)
|
61
61
|
|
62
62
|
const mutationEventEncoded = {
|
63
|
-
id: { global: row.idGlobal,
|
64
|
-
parentId: { global: row.parentIdGlobal,
|
63
|
+
id: { global: row.idGlobal, client: row.idClient },
|
64
|
+
parentId: { global: row.parentIdGlobal, client: row.parentIdClient },
|
65
65
|
mutation: row.mutation,
|
66
66
|
args,
|
67
|
+
clientId: row.clientId,
|
68
|
+
sessionId: row.sessionId ?? undefined,
|
67
69
|
} satisfies MutationEvent.AnyEncoded
|
68
70
|
|
69
71
|
yield* applyMutation(mutationEventEncoded, { skipMutationLog: true })
|
@@ -73,8 +75,8 @@ This likely means the schema has changed in an incompatible way.
|
|
73
75
|
|
74
76
|
const stmt = logDb.prepare(sql`\
|
75
77
|
SELECT * FROM ${MUTATION_LOG_META_TABLE}
|
76
|
-
WHERE idGlobal > $idGlobal OR (idGlobal = $idGlobal AND
|
77
|
-
ORDER BY idGlobal ASC,
|
78
|
+
WHERE idGlobal > $idGlobal OR (idGlobal = $idGlobal AND idClient > $idClient)
|
79
|
+
ORDER BY idGlobal ASC, idClient ASC
|
78
80
|
LIMIT ${CHUNK_SIZE}
|
79
81
|
`)
|
80
82
|
|
@@ -88,14 +90,14 @@ LIMIT ${CHUNK_SIZE}
|
|
88
90
|
|
89
91
|
const lastId = Chunk.isChunk(item)
|
90
92
|
? Chunk.last(item).pipe(
|
91
|
-
Option.map((_) => ({ global: _.idGlobal,
|
93
|
+
Option.map((_) => ({ global: _.idGlobal, client: _.idClient })),
|
92
94
|
Option.getOrElse(() => EventId.ROOT),
|
93
95
|
)
|
94
96
|
: EventId.ROOT
|
95
97
|
const nextItem = Chunk.fromIterable(
|
96
98
|
stmt.select<MutationLogMetaRow>({
|
97
99
|
$idGlobal: lastId?.global,
|
98
|
-
$
|
100
|
+
$idClient: lastId?.client,
|
99
101
|
} as any as PreparedBindValues),
|
100
102
|
)
|
101
103
|
const prevItem = Chunk.isChunk(item) ? item : Chunk.empty()
|
@@ -5,8 +5,8 @@ import { EventId } from './mod.js'
|
|
5
5
|
|
6
6
|
Vitest.describe('EventId', () => {
|
7
7
|
Vitest.test('nextPair', () => {
|
8
|
-
const e_0_0 = EventId.make({ global: 0,
|
9
|
-
expect(EventId.nextPair(e_0_0, false).id).toStrictEqual({ global: 1,
|
10
|
-
expect(EventId.nextPair(e_0_0, true).id).toStrictEqual({ global: 0,
|
8
|
+
const e_0_0 = EventId.make({ global: 0, client: 0 })
|
9
|
+
expect(EventId.nextPair(e_0_0, false).id).toStrictEqual({ global: 1, client: 0 })
|
10
|
+
expect(EventId.nextPair(e_0_0, true).id).toStrictEqual({ global: 0, client: 1 })
|
11
11
|
})
|
12
12
|
})
|
package/src/schema/EventId.ts
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
import { Brand, Schema } from '@livestore/utils/effect'
|
2
2
|
|
3
|
-
export type
|
4
|
-
export const localEventId = Brand.nominal<
|
5
|
-
export const
|
3
|
+
export type ClientEventId = Brand.Branded<number, 'ClientEventId'>
|
4
|
+
export const localEventId = Brand.nominal<ClientEventId>()
|
5
|
+
export const ClientEventId = Schema.fromBrand(localEventId)(Schema.Int)
|
6
6
|
|
7
7
|
export type GlobalEventId = Brand.Branded<number, 'GlobalEventId'>
|
8
8
|
export const globalEventId = Brand.nominal<GlobalEventId>()
|
9
9
|
export const GlobalEventId = Schema.fromBrand(globalEventId)(Schema.Int)
|
10
10
|
|
11
|
-
export const
|
11
|
+
export const clientDefault = 0 as any as ClientEventId
|
12
12
|
|
13
13
|
/**
|
14
14
|
* LiveStore event id value consisting of a globally unique event sequence number
|
15
|
-
* and a
|
15
|
+
* and a client sequence number.
|
16
16
|
*
|
17
|
-
* The
|
17
|
+
* The client sequence number is only used for clientOnly mutations and starts from 0 for each global sequence number.
|
18
18
|
*/
|
19
|
-
export type EventId = { global: GlobalEventId;
|
19
|
+
export type EventId = { global: GlobalEventId; client: ClientEventId }
|
20
20
|
|
21
21
|
export const EventId = Schema.Struct({
|
22
22
|
global: GlobalEventId,
|
23
|
-
|
23
|
+
client: ClientEventId,
|
24
24
|
}).annotations({ title: 'LiveStore.EventId' })
|
25
25
|
|
26
26
|
/**
|
@@ -30,17 +30,21 @@ export const compare = (a: EventId, b: EventId) => {
|
|
30
30
|
if (a.global !== b.global) {
|
31
31
|
return a.global - b.global
|
32
32
|
}
|
33
|
-
return a.
|
33
|
+
return a.client - b.client
|
34
34
|
}
|
35
35
|
|
36
|
-
export const isEqual = (a: EventId, b: EventId) => a.global === b.global && a.
|
36
|
+
export const isEqual = (a: EventId, b: EventId) => a.global === b.global && a.client === b.client
|
37
37
|
|
38
38
|
export type EventIdPair = { id: EventId; parentId: EventId }
|
39
39
|
|
40
|
-
export const ROOT = { global: -1 as any as GlobalEventId,
|
40
|
+
export const ROOT = { global: -1 as any as GlobalEventId, client: clientDefault } satisfies EventId
|
41
41
|
|
42
42
|
export const isGreaterThan = (a: EventId, b: EventId) => {
|
43
|
-
return a.global > b.global || (a.global === b.global && a.
|
43
|
+
return a.global > b.global || (a.global === b.global && a.client > b.client)
|
44
|
+
}
|
45
|
+
|
46
|
+
export const isGreaterThanOrEqual = (a: EventId, b: EventId) => {
|
47
|
+
return a.global > b.global || (a.global === b.global && a.client >= b.client)
|
44
48
|
}
|
45
49
|
|
46
50
|
export const make = (id: EventId | typeof EventId.Encoded): EventId => {
|
@@ -49,12 +53,12 @@ export const make = (id: EventId | typeof EventId.Encoded): EventId => {
|
|
49
53
|
|
50
54
|
export const nextPair = (id: EventId, isLocal: boolean): EventIdPair => {
|
51
55
|
if (isLocal) {
|
52
|
-
return { id: { global: id.global,
|
56
|
+
return { id: { global: id.global, client: (id.client + 1) as any as ClientEventId }, parentId: id }
|
53
57
|
}
|
54
58
|
|
55
59
|
return {
|
56
|
-
id: { global: (id.global + 1) as any as GlobalEventId,
|
57
|
-
// NOTE we always point to `
|
58
|
-
parentId: { global: id.global,
|
60
|
+
id: { global: (id.global + 1) as any as GlobalEventId, client: clientDefault },
|
61
|
+
// NOTE we always point to `client: 0` for non-clientOnly mutations
|
62
|
+
parentId: { global: id.global, client: clientDefault },
|
59
63
|
}
|
60
64
|
}
|