@livestore/common 0.3.0-dev.1 → 0.3.0-dev.11
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/adapter-types.d.ts +47 -35
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js.map +1 -1
- package/dist/derived-mutations.d.ts +4 -4
- package/dist/derived-mutations.d.ts.map +1 -1
- package/dist/derived-mutations.test.js.map +1 -1
- package/dist/devtools/devtool-message-leader.d.ts +2 -0
- package/dist/devtools/devtool-message-leader.d.ts.map +1 -0
- package/dist/devtools/devtool-message-leader.js +2 -0
- package/dist/devtools/devtool-message-leader.js.map +1 -0
- package/dist/devtools/devtools-bridge.d.ts +2 -1
- package/dist/devtools/devtools-bridge.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +297 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +61 -0
- package/dist/devtools/devtools-messages-client-session.js.map +1 -0
- package/dist/devtools/devtools-messages-common.d.ts +65 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-common.js +35 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -0
- package/dist/devtools/devtools-messages-leader.d.ts +261 -0
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-leader.js +85 -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/index.d.ts +0 -4
- package/dist/index.d.ts.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 +37 -0
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
- package/dist/leader-thread/LeaderSyncProcessor.js +432 -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 +41 -29
- package/dist/leader-thread/apply-mutation.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +4 -4
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +5 -5
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/leader-sync-processor.d.ts +2 -2
- package/dist/leader-thread/leader-sync-processor.d.ts.map +1 -1
- package/dist/leader-thread/leader-sync-processor.js +20 -12
- package/dist/leader-thread/leader-sync-processor.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 +37 -81
- 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 +33 -14
- 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 +7 -6
- 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.map +1 -1
- package/dist/leader-thread/recreate-db.js +24 -18
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/types.d.ts +36 -16
- package/dist/leader-thread/types.d.ts.map +1 -1
- 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/query-builder/impl.d.ts +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 +13 -19
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +16 -14
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +15 -7
- 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 +49 -80
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +32 -15
- package/dist/schema/MutationEvent.js.map +1 -1
- package/dist/schema/MutationEvent.test.d.ts +2 -0
- package/dist/schema/MutationEvent.test.d.ts.map +1 -0
- package/dist/schema/MutationEvent.test.js +2 -0
- package/dist/schema/MutationEvent.test.js.map +1 -0
- package/dist/schema/system-tables.d.ts +26 -26
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +19 -11
- package/dist/schema/system-tables.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 +4 -4
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +6 -6
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +43 -0
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.js +141 -0
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
- package/dist/sync/client-session-sync-processor.d.ts +4 -4
- package/dist/sync/client-session-sync-processor.d.ts.map +1 -1
- 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/history-dag-common.d.ts +1 -4
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +1 -1
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +3 -3
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +3 -2
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts +7 -7
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.js +3 -9
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +21 -11
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +45 -23
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +56 -12
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +125 -69
- 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/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 -5
- package/src/adapter-types.ts +39 -40
- package/src/derived-mutations.test.ts +1 -1
- package/src/derived-mutations.ts +9 -5
- package/src/devtools/devtools-bridge.ts +2 -1
- package/src/devtools/devtools-messages-client-session.ts +109 -0
- package/src/devtools/devtools-messages-common.ts +52 -0
- package/src/devtools/devtools-messages-leader.ts +115 -0
- package/src/devtools/devtools-messages.ts +3 -243
- package/src/index.ts +0 -6
- package/src/init-singleton-tables.ts +2 -2
- package/src/leader-thread/{leader-sync-processor.ts → LeaderSyncProcessor.ts} +306 -268
- package/src/leader-thread/apply-mutation.ts +53 -35
- package/src/leader-thread/connection.ts +7 -7
- package/src/leader-thread/leader-worker-devtools.ts +52 -124
- package/src/leader-thread/make-leader-thread-layer.ts +62 -30
- package/src/leader-thread/mutationlog.ts +14 -10
- package/src/leader-thread/recreate-db.ts +24 -20
- package/src/leader-thread/types.ts +41 -20
- package/src/mutation.ts +17 -7
- package/src/rehydrate-from-mutationlog.ts +18 -26
- package/src/schema/EventId.test.ts +12 -0
- package/src/schema/EventId.ts +23 -9
- package/src/schema/MutationEvent.ts +46 -24
- package/src/schema/system-tables.ts +19 -11
- package/src/schema-management/common.ts +3 -3
- package/src/schema-management/migrations.ts +10 -10
- package/src/sync/{client-session-sync-processor.ts → ClientSessionSyncProcessor.ts} +26 -19
- package/src/sync/index.ts +1 -1
- package/src/sync/next/history-dag-common.ts +1 -1
- package/src/sync/next/rebase-events.ts +7 -7
- package/src/sync/next/test/mutation-fixtures.ts +3 -10
- package/src/sync/sync.ts +19 -6
- package/src/sync/syncstate.test.ts +127 -67
- package/src/sync/syncstate.ts +21 -19
- package/src/sync/validate-push-payload.ts +7 -4
- package/src/version.ts +1 -1
@@ -1,4 +1,4 @@
|
|
1
|
-
import type {
|
1
|
+
import type { SqliteDb } from '../adapter-types.js'
|
2
2
|
import type { ParamsObject } from '../util.js'
|
3
3
|
import { prepareBindValues } from '../util.js'
|
4
4
|
|
@@ -6,7 +6,7 @@ import { prepareBindValues } from '../util.js'
|
|
6
6
|
// will require proper scope-aware cleanup etc (for testing and apps with multiple LiveStore instances)
|
7
7
|
// const cachedStmts = new Map<string, PreparedStatement>()
|
8
8
|
|
9
|
-
export const dbExecute = (db:
|
9
|
+
export const dbExecute = (db: SqliteDb, queryStr: string, bindValues?: ParamsObject) => {
|
10
10
|
// let stmt = cachedStmts.get(queryStr)
|
11
11
|
// if (!stmt) {
|
12
12
|
const stmt = db.prepare(queryStr)
|
@@ -20,7 +20,7 @@ export const dbExecute = (db: SynchronousDatabase, queryStr: string, bindValues?
|
|
20
20
|
stmt.finalize()
|
21
21
|
}
|
22
22
|
|
23
|
-
export const dbSelect = <T>(db:
|
23
|
+
export const dbSelect = <T>(db: SqliteDb, queryStr: string, bindValues?: ParamsObject) => {
|
24
24
|
// let stmt = cachedStmts.get(queryStr)
|
25
25
|
// if (!stmt) {
|
26
26
|
const stmt = db.prepare(queryStr)
|
@@ -2,7 +2,7 @@ import { SqliteAst, SqliteDsl } from '@livestore/db-schema'
|
|
2
2
|
import { memoizeByStringifyArgs } from '@livestore/utils'
|
3
3
|
import { Effect, Schema as EffectSchema } from '@livestore/utils/effect'
|
4
4
|
|
5
|
-
import type {
|
5
|
+
import type { SqliteDb } from '../adapter-types.js'
|
6
6
|
import type { LiveStoreSchema } from '../schema/mod.js'
|
7
7
|
import type { SchemaMetaRow, SchemaMutationsMetaRow } from '../schema/system-tables.js'
|
8
8
|
import {
|
@@ -19,7 +19,7 @@ import { validateSchema } from './validate-mutation-defs.js'
|
|
19
19
|
|
20
20
|
const getMemoizedTimestamp = memoizeByStringifyArgs(() => new Date().toISOString())
|
21
21
|
|
22
|
-
export const makeSchemaManager = (db:
|
22
|
+
export const makeSchemaManager = (db: SqliteDb): Effect.Effect<SchemaManager> =>
|
23
23
|
Effect.gen(function* () {
|
24
24
|
yield* migrateTable({
|
25
25
|
db,
|
@@ -51,7 +51,7 @@ export const migrateDb = ({
|
|
51
51
|
schema,
|
52
52
|
onProgress,
|
53
53
|
}: {
|
54
|
-
db:
|
54
|
+
db: SqliteDb
|
55
55
|
schema: LiveStoreSchema
|
56
56
|
onProgress?: (opts: { done: number; total: number }) => Effect.Effect<void>
|
57
57
|
}) =>
|
@@ -116,7 +116,7 @@ export const migrateTable = ({
|
|
116
116
|
behaviour,
|
117
117
|
skipMetaTable = false,
|
118
118
|
}: {
|
119
|
-
db:
|
119
|
+
db: SqliteDb
|
120
120
|
tableAst: SqliteAst.Table
|
121
121
|
schemaHash?: number
|
122
122
|
behaviour: 'drop-and-recreate' | 'create-if-not-exists'
|
@@ -129,10 +129,10 @@ export const migrateTable = ({
|
|
129
129
|
|
130
130
|
if (behaviour === 'drop-and-recreate') {
|
131
131
|
// TODO need to possibly handle cascading deletes due to foreign keys
|
132
|
-
dbExecute(db, sql`drop table if exists ${tableName}`)
|
133
|
-
dbExecute(db, sql`create table if not exists ${tableName} (${columnSpec}) strict`)
|
132
|
+
dbExecute(db, sql`drop table if exists '${tableName}'`)
|
133
|
+
dbExecute(db, sql`create table if not exists '${tableName}' (${columnSpec}) strict`)
|
134
134
|
} else if (behaviour === 'create-if-not-exists') {
|
135
|
-
dbExecute(db, sql`create table if not exists ${tableName} (${columnSpec}) strict`)
|
135
|
+
dbExecute(db, sql`create table if not exists '${tableName}' (${columnSpec}) strict`)
|
136
136
|
}
|
137
137
|
|
138
138
|
for (const index of tableAst.indexes) {
|
@@ -162,11 +162,11 @@ export const migrateTable = ({
|
|
162
162
|
|
163
163
|
const createIndexFromDefinition = (tableName: string, index: SqliteAst.Index) => {
|
164
164
|
const uniqueStr = index.unique ? 'UNIQUE' : ''
|
165
|
-
return sql`create ${uniqueStr} index if not exists ${index.name} on ${tableName} (${index.columns.join(', ')})`
|
165
|
+
return sql`create ${uniqueStr} index if not exists '${index.name}' on '${tableName}' (${index.columns.join(', ')})`
|
166
166
|
}
|
167
167
|
|
168
168
|
export const makeColumnSpec = (tableAst: SqliteAst.Table) => {
|
169
|
-
const primaryKeys = tableAst.columns.filter((_) => _.primaryKey).map((_) => _.name)
|
169
|
+
const primaryKeys = tableAst.columns.filter((_) => _.primaryKey).map((_) => `'${_.name}'`)
|
170
170
|
const columnDefStrs = tableAst.columns.map(toSqliteColumnSpec)
|
171
171
|
if (primaryKeys.length > 0) {
|
172
172
|
columnDefStrs.push(`PRIMARY KEY (${primaryKeys.join(', ')})`)
|
@@ -191,5 +191,5 @@ const toSqliteColumnSpec = (column: SqliteAst.Column) => {
|
|
191
191
|
return `default ${encodedDefaultValue}`
|
192
192
|
})()
|
193
193
|
|
194
|
-
return
|
194
|
+
return `'${column.name}' ${columnTypeStr} ${nullableStr} ${defaultValueStr}`
|
195
195
|
}
|
@@ -1,14 +1,13 @@
|
|
1
1
|
import { LS_DEV, shouldNeverHappen, TRACE_VERBOSE } from '@livestore/utils'
|
2
|
-
import type { Scope } from '@livestore/utils/effect'
|
2
|
+
import type { Runtime, Scope } from '@livestore/utils/effect'
|
3
3
|
import { Effect, Schema, Stream } from '@livestore/utils/effect'
|
4
4
|
import * as otel from '@opentelemetry/api'
|
5
5
|
|
6
|
-
import type {
|
6
|
+
import type { ClientSession, UnexpectedError } from '../adapter-types.js'
|
7
7
|
import * as EventId from '../schema/EventId.js'
|
8
8
|
import { type LiveStoreSchema } from '../schema/mod.js'
|
9
9
|
import * as MutationEvent from '../schema/MutationEvent.js'
|
10
|
-
import
|
11
|
-
import { updateSyncState } from './syncstate.js'
|
10
|
+
import { SyncState, updateSyncState } from './syncstate.js'
|
12
11
|
|
13
12
|
/**
|
14
13
|
* Rebase behaviour:
|
@@ -21,20 +20,18 @@ import { updateSyncState } from './syncstate.js'
|
|
21
20
|
*/
|
22
21
|
export const makeClientSessionSyncProcessor = ({
|
23
22
|
schema,
|
24
|
-
|
25
|
-
|
26
|
-
pullFromLeader,
|
23
|
+
clientSession,
|
24
|
+
runtime,
|
27
25
|
applyMutation,
|
28
26
|
rollback,
|
29
27
|
refreshTables,
|
30
28
|
span,
|
31
29
|
}: {
|
32
30
|
schema: LiveStoreSchema
|
33
|
-
|
34
|
-
|
35
|
-
pullFromLeader: Coordinator['mutations']['pull']
|
31
|
+
clientSession: ClientSession
|
32
|
+
runtime: Runtime.Runtime<Scope.Scope>
|
36
33
|
applyMutation: (
|
37
|
-
mutationEventDecoded: MutationEvent.
|
34
|
+
mutationEventDecoded: MutationEvent.PartialAnyDecoded,
|
38
35
|
options: { otelContext: otel.Context; withChangeset: boolean },
|
39
36
|
) => {
|
40
37
|
writeTables: Set<string>
|
@@ -42,19 +39,18 @@ export const makeClientSessionSyncProcessor = ({
|
|
42
39
|
}
|
43
40
|
rollback: (changeset: Uint8Array) => void
|
44
41
|
refreshTables: (tables: Set<string>) => void
|
45
|
-
// rebaseBehaviour: 'auto-rebase' | 'manual-rebase'
|
46
42
|
span: otel.Span
|
47
43
|
}): ClientSessionSyncProcessor => {
|
48
44
|
const mutationEventSchema = MutationEvent.makeMutationEventSchemaMemo(schema)
|
49
45
|
|
50
46
|
const syncStateRef = {
|
51
|
-
current: {
|
52
|
-
localHead:
|
53
|
-
upstreamHead:
|
47
|
+
current: new SyncState({
|
48
|
+
localHead: clientSession.leaderThread.mutations.initialMutationEventId,
|
49
|
+
upstreamHead: clientSession.leaderThread.mutations.initialMutationEventId,
|
54
50
|
pending: [],
|
55
51
|
// TODO init rollbackTail from leader to be ready for backend rebasing
|
56
52
|
rollbackTail: [],
|
57
|
-
}
|
53
|
+
}),
|
58
54
|
}
|
59
55
|
|
60
56
|
const isLocalEvent = (mutationEventEncoded: MutationEvent.EncodedWithMeta) => {
|
@@ -104,7 +100,10 @@ export const makeClientSessionSyncProcessor = ({
|
|
104
100
|
mutationEvent.meta.sessionChangeset = res.sessionChangeset
|
105
101
|
}
|
106
102
|
|
107
|
-
pushToLeader(
|
103
|
+
// console.debug('pushToLeader', encodedMutationEvents.length, ...encodedMutationEvents.map((_) => _.toJSON()))
|
104
|
+
clientSession.leaderThread.mutations
|
105
|
+
.push(encodedMutationEvents)
|
106
|
+
.pipe(Effect.tapCauseLogPretty, Effect.provide(runtime), Effect.runFork)
|
108
107
|
|
109
108
|
return { writeTables }
|
110
109
|
}
|
@@ -112,10 +111,13 @@ export const makeClientSessionSyncProcessor = ({
|
|
112
111
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
113
112
|
|
114
113
|
const boot: ClientSessionSyncProcessor['boot'] = Effect.gen(function* () {
|
115
|
-
yield*
|
114
|
+
yield* clientSession.leaderThread.mutations.pull.pipe(
|
116
115
|
Stream.tap(({ payload, remaining }) =>
|
117
116
|
Effect.gen(function* () {
|
118
117
|
// console.log('pulled payload from leader', { payload, remaining })
|
118
|
+
if (clientSession.devtools.enabled) {
|
119
|
+
yield* clientSession.devtools.pullLatch.await
|
120
|
+
}
|
119
121
|
|
120
122
|
const updateResult = updateSyncState({
|
121
123
|
syncState: syncStateRef.current,
|
@@ -155,6 +157,10 @@ export const makeClientSessionSyncProcessor = ({
|
|
155
157
|
event.meta.sessionChangeset = undefined
|
156
158
|
}
|
157
159
|
}
|
160
|
+
|
161
|
+
clientSession.leaderThread.mutations
|
162
|
+
.push(updateResult.newSyncState.pending)
|
163
|
+
.pipe(Effect.tapCauseLogPretty, Effect.provide(runtime), Effect.runFork)
|
158
164
|
} else {
|
159
165
|
span.addEvent('pull:advance', {
|
160
166
|
payloadTag: payload._tag,
|
@@ -182,6 +188,7 @@ export const makeClientSessionSyncProcessor = ({
|
|
182
188
|
}),
|
183
189
|
),
|
184
190
|
Stream.runDrain,
|
191
|
+
Effect.forever, // NOTE Whenever the leader changes, we need to re-start the stream
|
185
192
|
Effect.tapCauseLogPretty,
|
186
193
|
Effect.forkScoped,
|
187
194
|
)
|
@@ -196,7 +203,7 @@ export const makeClientSessionSyncProcessor = ({
|
|
196
203
|
|
197
204
|
export interface ClientSessionSyncProcessor {
|
198
205
|
push: (
|
199
|
-
batch: ReadonlyArray<MutationEvent.
|
206
|
+
batch: ReadonlyArray<MutationEvent.PartialAnyDecoded>,
|
200
207
|
options: { otelContext: otel.Context },
|
201
208
|
) => {
|
202
209
|
writeTables: Set<string>
|
package/src/sync/index.ts
CHANGED
@@ -20,7 +20,7 @@ export const emptyHistoryDag = (): HistoryDag =>
|
|
20
20
|
})
|
21
21
|
|
22
22
|
// TODO consider making `ROOT_ID` parent to itself
|
23
|
-
export const rootParentId = { global: EventId.ROOT.global - 1, local:
|
23
|
+
export const rootParentId = EventId.make({ global: EventId.ROOT.global - 1, local: EventId.localDefault })
|
24
24
|
|
25
25
|
export type HistoryDagNode = {
|
26
26
|
id: EventId.EventId
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import * as EventId from '../../schema/EventId.js'
|
2
2
|
import type * as MutationEvent from '../../schema/MutationEvent.js'
|
3
3
|
import type { MutationDef, MutationEventFactsSnapshot } from '../../schema/mutations.js'
|
4
4
|
import {
|
@@ -19,13 +19,13 @@ export type RebaseInput = {
|
|
19
19
|
newRemoteEvents: RebaseEventWithConflict[]
|
20
20
|
pendingLocalEvents: RebaseEventWithConflict[]
|
21
21
|
validate: (args: {
|
22
|
-
rebasedLocalEvents: MutationEvent.
|
22
|
+
rebasedLocalEvents: MutationEvent.PartialAnyDecoded[]
|
23
23
|
mutationDefs: Record<string, MutationDef.Any>
|
24
24
|
}) => FactValidationResult
|
25
25
|
}
|
26
26
|
|
27
27
|
export type RebaseOutput = {
|
28
|
-
rebasedLocalEvents: MutationEvent.
|
28
|
+
rebasedLocalEvents: MutationEvent.PartialAnyDecoded[]
|
29
29
|
}
|
30
30
|
|
31
31
|
export type RebaseFn = (input: RebaseInput) => RebaseOutput
|
@@ -48,7 +48,7 @@ export const rebaseEvents = ({
|
|
48
48
|
newRemoteEvents: HistoryDagNode[]
|
49
49
|
rebaseFn: RebaseFn
|
50
50
|
currentFactsSnapshot: MutationEventFactsSnapshot
|
51
|
-
}): MutationEvent.
|
51
|
+
}): ReadonlyArray<MutationEvent.AnyDecoded> => {
|
52
52
|
const initialSnapshot = new Map(currentFactsSnapshot)
|
53
53
|
applyFactGroups(
|
54
54
|
newRemoteEvents.map((event) => event.factsGroup),
|
@@ -89,10 +89,10 @@ export const rebaseEvents = ({
|
|
89
89
|
return rebasedLocalEvents.map(
|
90
90
|
(event, index) =>
|
91
91
|
({
|
92
|
-
id: { global: headGlobalId + index + 1, local:
|
93
|
-
parentId: { global: headGlobalId + index, local:
|
92
|
+
id: EventId.make({ global: headGlobalId + index + 1, local: EventId.localDefault }),
|
93
|
+
parentId: EventId.make({ global: headGlobalId + index, local: EventId.localDefault }),
|
94
94
|
mutation: event.mutation,
|
95
95
|
args: event.args,
|
96
|
-
}) satisfies MutationEvent.
|
96
|
+
}) satisfies MutationEvent.AnyDecoded,
|
97
97
|
)
|
98
98
|
}
|
@@ -140,16 +140,9 @@ export const toEventNodes = (
|
|
140
140
|
|
141
141
|
let currentEventId: EventId.EventId = EventId.ROOT
|
142
142
|
|
143
|
-
const getNextEventId = (mutationDef: MutationDef.Any): EventId.EventId => {
|
144
|
-
if (mutationDef.options.localOnly) {
|
145
|
-
return { global: currentEventId.global, local: currentEventId.local + 1 }
|
146
|
-
}
|
147
|
-
return { global: currentEventId.global + 1, local: 0 }
|
148
|
-
}
|
149
|
-
|
150
143
|
const eventNodes = partialEvents.map((partialEvent) => {
|
151
144
|
const mutationDef = mutationDefs[partialEvent.mutation]!
|
152
|
-
const eventId =
|
145
|
+
const eventId = EventId.nextPair(currentEventId, mutationDef.options.localOnly).id
|
153
146
|
currentEventId = eventId
|
154
147
|
|
155
148
|
const factsSnapshot = factsSnapshotForDag(historyDagFromNodes(nodesAcc, { skipFactsCheck: true }), undefined)
|
@@ -224,8 +217,8 @@ const getParentId = (eventId: EventId.EventId): EventId.EventId => {
|
|
224
217
|
const localParentId = eventId.local - 1
|
225
218
|
|
226
219
|
if (localParentId < 0) {
|
227
|
-
return { global: globalParentId - 1, local:
|
220
|
+
return EventId.make({ global: globalParentId - 1, local: EventId.localDefault })
|
228
221
|
}
|
229
222
|
|
230
|
-
return { global: globalParentId, local: localParentId }
|
223
|
+
return EventId.make({ global: globalParentId, local: localParentId })
|
231
224
|
}
|
package/src/sync/sync.ts
CHANGED
@@ -1,12 +1,23 @@
|
|
1
|
-
import type { Effect, HttpClient, Option, Stream, SubscriptionRef } from '@livestore/utils/effect'
|
1
|
+
import type { Effect, HttpClient, Option, Scope, Stream, SubscriptionRef } from '@livestore/utils/effect'
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
3
3
|
|
4
|
+
import type { UnexpectedError } from '../adapter-types.js'
|
5
|
+
import type { InitialSyncOptions } from '../leader-thread/types.js'
|
4
6
|
import * as EventId from '../schema/EventId.js'
|
5
7
|
import type * as MutationEvent from '../schema/MutationEvent.js'
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
/**
|
10
|
+
* Those arguments can be used to implement multi-tenancy etc and are passed in from the store.
|
11
|
+
*/
|
12
|
+
export type MakeBackendArgs = {
|
13
|
+
storeId: string
|
14
|
+
clientId: string
|
15
|
+
}
|
16
|
+
|
17
|
+
export type SyncOptions = {
|
18
|
+
makeBackend: (args: MakeBackendArgs) => Effect.Effect<SyncBackend<any>, UnexpectedError, Scope.Scope>
|
19
|
+
/** @default { _tag: 'Skip' } */
|
20
|
+
initialSyncOptions?: InitialSyncOptions
|
10
21
|
}
|
11
22
|
|
12
23
|
export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
@@ -18,7 +29,7 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
18
29
|
) => Stream.Stream<
|
19
30
|
{
|
20
31
|
batch: ReadonlyArray<{
|
21
|
-
mutationEventEncoded: MutationEvent.
|
32
|
+
mutationEventEncoded: MutationEvent.AnyEncodedGlobal
|
22
33
|
metadata: Option.Option<TSyncMetadata>
|
23
34
|
}>
|
24
35
|
remaining: number
|
@@ -33,7 +44,7 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
33
44
|
* - Number of events: 1-100
|
34
45
|
* - event ids must be in ascending order
|
35
46
|
* */
|
36
|
-
batch: ReadonlyArray<MutationEvent.
|
47
|
+
batch: ReadonlyArray<MutationEvent.AnyEncodedGlobal>,
|
37
48
|
) => Effect.Effect<
|
38
49
|
{
|
39
50
|
/** Indexes are relative to `batch` */
|
@@ -46,6 +57,7 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
46
57
|
}
|
47
58
|
|
48
59
|
export class IsOfflineError extends Schema.TaggedError<IsOfflineError>()('IsOfflineError', {}) {}
|
60
|
+
|
49
61
|
export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('InvalidPushError', {
|
50
62
|
reason: Schema.Union(
|
51
63
|
Schema.TaggedStruct('Unexpected', {
|
@@ -61,6 +73,7 @@ export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('In
|
|
61
73
|
}),
|
62
74
|
),
|
63
75
|
}) {}
|
76
|
+
|
64
77
|
export class InvalidPullError extends Schema.TaggedError<InvalidPullError>()('InvalidPullError', {
|
65
78
|
message: Schema.String,
|
66
79
|
}) {}
|