@livestore/common 0.3.0-dev.10 → 0.3.0-dev.2
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 +23 -26
- 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/devtools-bridge.d.ts +1 -2
- package/dist/devtools/devtools-bridge.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.d.ts +110 -98
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +6 -9
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.d.ts +2 -5
- package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.js +26 -38
- package/dist/leader-thread/apply-mutation.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 +12 -20
- 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 +66 -22
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +7 -8
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +5 -11
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mutationlog.d.ts +17 -4
- package/dist/leader-thread/mutationlog.d.ts.map +1 -1
- package/dist/leader-thread/mutationlog.js +1 -2
- 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 +3 -9
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/types.d.ts +9 -17
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/mutation.d.ts +2 -9
- 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 +2 -2
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +19 -13
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +14 -16
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +7 -15
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/MutationEvent.d.ts +80 -49
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +15 -32
- package/dist/schema/MutationEvent.js.map +1 -1
- 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 +11 -19
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema-management/migrations.js +6 -6
- package/dist/schema-management/migrations.js.map +1 -1
- 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 +4 -1
- 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 +2 -3
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.js +9 -3
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +11 -21
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +23 -45
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +12 -56
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +69 -125
- 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 +5 -6
- package/src/adapter-types.ts +24 -22
- package/src/derived-mutations.test.ts +1 -1
- package/src/derived-mutations.ts +5 -9
- package/src/devtools/devtools-bridge.ts +1 -2
- package/src/devtools/devtools-messages.ts +6 -9
- package/src/index.ts +6 -0
- package/src/leader-thread/apply-mutation.ts +31 -49
- package/src/leader-thread/{LeaderSyncProcessor.ts → leader-sync-processor.ts} +230 -235
- package/src/leader-thread/leader-worker-devtools.ts +109 -30
- package/src/leader-thread/make-leader-thread-layer.ts +13 -24
- package/src/leader-thread/mutationlog.ts +5 -9
- package/src/leader-thread/recreate-db.ts +5 -9
- package/src/leader-thread/types.ts +11 -18
- package/src/mutation.ts +7 -17
- package/src/rehydrate-from-mutationlog.ts +23 -15
- package/src/schema/EventId.ts +9 -23
- package/src/schema/MutationEvent.ts +24 -46
- package/src/schema/system-tables.ts +11 -19
- package/src/schema-management/migrations.ts +6 -6
- package/src/sync/{ClientSessionSyncProcessor.ts → client-session-sync-processor.ts} +9 -11
- 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 +10 -3
- package/src/sync/sync.ts +6 -19
- package/src/sync/syncstate.test.ts +67 -127
- package/src/sync/syncstate.ts +19 -21
- package/src/sync/validate-push-payload.ts +4 -7
- package/src/version.ts +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +0 -37
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +0 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +0 -417
- package/dist/leader-thread/LeaderSyncProcessor.js.map +0 -1
- package/dist/schema/EventId.test.d.ts +0 -2
- package/dist/schema/EventId.test.d.ts.map +0 -1
- package/dist/schema/EventId.test.js +0 -11
- package/dist/schema/EventId.test.js.map +0 -1
- package/dist/schema/MutationEvent.test.d.ts +0 -2
- package/dist/schema/MutationEvent.test.d.ts.map +0 -1
- package/dist/schema/MutationEvent.test.js +0 -2
- package/dist/schema/MutationEvent.test.js.map +0 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +0 -45
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +0 -1
- package/dist/sync/ClientSessionSyncProcessor.js +0 -134
- package/dist/sync/ClientSessionSyncProcessor.js.map +0 -1
- package/src/schema/EventId.test.ts +0 -12
@@ -1,4 +1,5 @@
|
|
1
1
|
import { memoizeByRef } from '@livestore/utils'
|
2
|
+
import type { Deferred } from '@livestore/utils/effect'
|
2
3
|
import { Schema } from '@livestore/utils/effect'
|
3
4
|
|
4
5
|
import * as EventId from './EventId.js'
|
@@ -29,31 +30,10 @@ export type MutationEventEncoded<TMutationsDef extends MutationDef.Any> = {
|
|
29
30
|
parentId: EventId.EventId
|
30
31
|
}
|
31
32
|
|
32
|
-
export type
|
33
|
-
export const AnyDecoded = Schema.Struct({
|
34
|
-
mutation: Schema.String,
|
35
|
-
args: Schema.Any,
|
36
|
-
id: EventId.EventId,
|
37
|
-
parentId: EventId.EventId,
|
38
|
-
}).annotations({ title: 'MutationEvent.AnyDecoded' })
|
39
|
-
|
33
|
+
export type Any = MutationEvent<MutationDef.Any>
|
40
34
|
export type AnyEncoded = MutationEventEncoded<MutationDef.Any>
|
41
|
-
export const AnyEncoded = Schema.Struct({
|
42
|
-
mutation: Schema.String,
|
43
|
-
args: Schema.Any,
|
44
|
-
id: EventId.EventId,
|
45
|
-
parentId: EventId.EventId,
|
46
|
-
}).annotations({ title: 'MutationEvent.AnyEncoded' })
|
47
|
-
|
48
|
-
export const AnyEncodedGlobal = Schema.Struct({
|
49
|
-
mutation: Schema.String,
|
50
|
-
args: Schema.Any,
|
51
|
-
id: EventId.GlobalEventId,
|
52
|
-
parentId: EventId.GlobalEventId,
|
53
|
-
}).annotations({ title: 'MutationEvent.AnyEncodedGlobal' })
|
54
|
-
export type AnyEncodedGlobal = typeof AnyEncodedGlobal.Type
|
55
35
|
|
56
|
-
export type
|
36
|
+
export type PartialAny = MutationEventPartial<MutationDef.Any>
|
57
37
|
export type PartialAnyEncoded = MutationEventPartialEncoded<MutationDef.Any>
|
58
38
|
|
59
39
|
export type PartialForSchema<TSchema extends LiveStoreSchema> = {
|
@@ -64,9 +44,8 @@ export type ForSchema<TSchema extends LiveStoreSchema> = {
|
|
64
44
|
[K in keyof TSchema['_MutationDefMapType']]: MutationEvent<TSchema['_MutationDefMapType'][K]>
|
65
45
|
}[keyof TSchema['_MutationDefMapType']]
|
66
46
|
|
67
|
-
export const isPartialMutationEvent = (
|
68
|
-
mutationEvent
|
69
|
-
): mutationEvent is PartialAnyDecoded => 'id' in mutationEvent === false && 'parentId' in mutationEvent === false
|
47
|
+
export const isPartialMutationEvent = (mutationEvent: Any | PartialAny): mutationEvent is PartialAny =>
|
48
|
+
'id' in mutationEvent === false && 'parentId' in mutationEvent === false
|
70
49
|
|
71
50
|
export type ForMutationDefRecord<TMutationsDefRecord extends MutationDefRecord> = Schema.Schema<
|
72
51
|
{
|
@@ -126,21 +105,33 @@ export const makeMutationEventPartialSchema = <TSchema extends LiveStoreSchema>(
|
|
126
105
|
args: def.schema,
|
127
106
|
}),
|
128
107
|
),
|
129
|
-
).annotations({ title: '
|
108
|
+
).annotations({ title: 'MutationEventSchemaPartial' }) as any
|
130
109
|
|
131
110
|
export const makeMutationEventSchemaMemo = memoizeByRef(makeMutationEventSchema)
|
132
111
|
|
133
|
-
|
112
|
+
export const Any = Schema.Struct({
|
113
|
+
mutation: Schema.String,
|
114
|
+
args: Schema.Any,
|
115
|
+
id: EventId.EventId,
|
116
|
+
parentId: EventId.EventId,
|
117
|
+
}).annotations({ title: 'MutationEvent.Any' })
|
118
|
+
|
119
|
+
export const DecodedAny = Schema.typeSchema(Any).annotations({
|
120
|
+
title: 'MutationEvent.DecodedAny',
|
121
|
+
})
|
122
|
+
|
123
|
+
export const EncodedAny = Schema.encodedSchema(Any).annotations({
|
124
|
+
title: 'MutationEvent.EncodedAny',
|
125
|
+
})
|
126
|
+
|
127
|
+
/** Equivalent to EncodedAny but with a meta field and some convenience methods */
|
134
128
|
export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('MutationEvent.EncodedWithMeta')({
|
135
129
|
mutation: Schema.String,
|
136
130
|
args: Schema.Any,
|
137
131
|
id: EventId.EventId,
|
138
132
|
parentId: EventId.EventId,
|
139
|
-
// TODO get rid of `meta` again by cleaning up the usage implementations
|
140
133
|
meta: Schema.optionalWith(
|
141
|
-
Schema.Any as Schema.Schema<{
|
142
|
-
sessionChangeset?: Uint8Array
|
143
|
-
}>,
|
134
|
+
Schema.Any as Schema.Schema<{ deferred?: Deferred.Deferred<void>; sessionChangeset?: Uint8Array }>,
|
144
135
|
{ default: () => ({}) },
|
145
136
|
),
|
146
137
|
}) {
|
@@ -158,21 +149,8 @@ export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('MutationEven
|
|
158
149
|
rebase = (parentId: EventId.EventId, isLocal: boolean) =>
|
159
150
|
new EncodedWithMeta({
|
160
151
|
...this,
|
161
|
-
...EventId.nextPair(
|
152
|
+
...EventId.nextPair(this.id, isLocal),
|
162
153
|
})
|
163
|
-
|
164
|
-
static fromGlobal = (mutationEvent: AnyEncodedGlobal) =>
|
165
|
-
new EncodedWithMeta({
|
166
|
-
...mutationEvent,
|
167
|
-
id: { global: mutationEvent.id, local: EventId.localDefault },
|
168
|
-
parentId: { global: mutationEvent.parentId, local: EventId.localDefault },
|
169
|
-
})
|
170
|
-
|
171
|
-
toGlobal = (): AnyEncodedGlobal => ({
|
172
|
-
...this,
|
173
|
-
id: this.id.global,
|
174
|
-
parentId: this.parentId.global,
|
175
|
-
})
|
176
154
|
}
|
177
155
|
|
178
156
|
export const isEqualEncoded = (a: AnyEncoded, b: AnyEncoded) =>
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import { type SqliteAst as __SqliteAst, SqliteDsl } from '@livestore/db-schema'
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
3
3
|
|
4
|
-
import * as EventId from './EventId.js'
|
5
4
|
import type { FromTable } from './table-def.js'
|
6
5
|
import { table } from './table-def.js'
|
7
6
|
|
@@ -47,15 +46,14 @@ export const sessionChangesetMetaTable = table(
|
|
47
46
|
SESSION_CHANGESET_META_TABLE,
|
48
47
|
{
|
49
48
|
// TODO bring back primary key
|
50
|
-
idGlobal: SqliteDsl.integer({
|
51
|
-
idLocal: SqliteDsl.integer({
|
52
|
-
|
49
|
+
idGlobal: SqliteDsl.integer({}),
|
50
|
+
idLocal: SqliteDsl.integer({}),
|
51
|
+
// idGlobal: SqliteDsl.integer({ primaryKey: true }),
|
52
|
+
// idLocal: SqliteDsl.integer({ primaryKey: true }),
|
53
|
+
changeset: SqliteDsl.blob({}),
|
53
54
|
debug: SqliteDsl.json({ nullable: true }),
|
54
55
|
},
|
55
|
-
{
|
56
|
-
disableAutomaticIdColumn: true,
|
57
|
-
indexes: [{ columns: ['idGlobal', 'idLocal'], name: 'idx_session_changeset_id' }],
|
58
|
-
},
|
56
|
+
{ disableAutomaticIdColumn: true },
|
59
57
|
)
|
60
58
|
|
61
59
|
export type SessionChangesetMetaRow = FromTable.RowDecoded<typeof sessionChangesetMetaTable>
|
@@ -72,22 +70,16 @@ export const MUTATION_LOG_META_TABLE = 'mutation_log'
|
|
72
70
|
export const mutationLogMetaTable = table(
|
73
71
|
MUTATION_LOG_META_TABLE,
|
74
72
|
{
|
75
|
-
idGlobal: SqliteDsl.integer({ primaryKey: true
|
76
|
-
idLocal: SqliteDsl.integer({ primaryKey: true
|
77
|
-
parentIdGlobal: SqliteDsl.integer({
|
78
|
-
parentIdLocal: SqliteDsl.integer({
|
73
|
+
idGlobal: SqliteDsl.integer({ primaryKey: true }),
|
74
|
+
idLocal: SqliteDsl.integer({ primaryKey: true }),
|
75
|
+
parentIdGlobal: SqliteDsl.integer({}),
|
76
|
+
parentIdLocal: SqliteDsl.integer({}),
|
79
77
|
mutation: SqliteDsl.text({}),
|
80
78
|
argsJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Any) }),
|
81
79
|
schemaHash: SqliteDsl.integer({}),
|
82
80
|
syncMetadataJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Option(Schema.JsonValue)) }),
|
83
81
|
},
|
84
|
-
{
|
85
|
-
disableAutomaticIdColumn: true,
|
86
|
-
indexes: [
|
87
|
-
{ columns: ['idGlobal'], name: 'idx_idGlobal' },
|
88
|
-
{ columns: ['idGlobal', 'idLocal'], name: 'idx_mutationlog_id' },
|
89
|
-
],
|
90
|
-
},
|
82
|
+
{ disableAutomaticIdColumn: true, indexes: [] },
|
91
83
|
)
|
92
84
|
|
93
85
|
export type MutationLogMetaRow = FromTable.RowDecoded<typeof mutationLogMetaTable>
|
@@ -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
|
133
|
-
dbExecute(db, sql`create table if not exists
|
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
|
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
|
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((_) =>
|
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
|
}
|
@@ -3,11 +3,12 @@ import type { 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 { Coordinator, 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 { SyncState
|
10
|
+
import type { SyncState } from './syncstate.js'
|
11
|
+
import { updateSyncState } from './syncstate.js'
|
11
12
|
|
12
13
|
/**
|
13
14
|
* Rebase behaviour:
|
@@ -31,9 +32,9 @@ export const makeClientSessionSyncProcessor = ({
|
|
31
32
|
schema: LiveStoreSchema
|
32
33
|
initialLeaderHead: EventId.EventId
|
33
34
|
pushToLeader: (batch: ReadonlyArray<MutationEvent.AnyEncoded>) => void
|
34
|
-
pullFromLeader:
|
35
|
+
pullFromLeader: Coordinator['mutations']['pull']
|
35
36
|
applyMutation: (
|
36
|
-
mutationEventDecoded: MutationEvent.
|
37
|
+
mutationEventDecoded: MutationEvent.PartialAny,
|
37
38
|
options: { otelContext: otel.Context; withChangeset: boolean },
|
38
39
|
) => {
|
39
40
|
writeTables: Set<string>
|
@@ -41,18 +42,19 @@ export const makeClientSessionSyncProcessor = ({
|
|
41
42
|
}
|
42
43
|
rollback: (changeset: Uint8Array) => void
|
43
44
|
refreshTables: (tables: Set<string>) => void
|
45
|
+
// rebaseBehaviour: 'auto-rebase' | 'manual-rebase'
|
44
46
|
span: otel.Span
|
45
47
|
}): ClientSessionSyncProcessor => {
|
46
48
|
const mutationEventSchema = MutationEvent.makeMutationEventSchemaMemo(schema)
|
47
49
|
|
48
50
|
const syncStateRef = {
|
49
|
-
current:
|
51
|
+
current: {
|
50
52
|
localHead: initialLeaderHead,
|
51
53
|
upstreamHead: initialLeaderHead,
|
52
54
|
pending: [],
|
53
55
|
// TODO init rollbackTail from leader to be ready for backend rebasing
|
54
56
|
rollbackTail: [],
|
55
|
-
}
|
57
|
+
} as SyncState,
|
56
58
|
}
|
57
59
|
|
58
60
|
const isLocalEvent = (mutationEventEncoded: MutationEvent.EncodedWithMeta) => {
|
@@ -102,7 +104,6 @@ export const makeClientSessionSyncProcessor = ({
|
|
102
104
|
mutationEvent.meta.sessionChangeset = res.sessionChangeset
|
103
105
|
}
|
104
106
|
|
105
|
-
// console.debug('pushToLeader', encodedMutationEvents.length, ...encodedMutationEvents.map((_) => _.toJSON()))
|
106
107
|
pushToLeader(encodedMutationEvents)
|
107
108
|
|
108
109
|
return { writeTables }
|
@@ -154,8 +155,6 @@ export const makeClientSessionSyncProcessor = ({
|
|
154
155
|
event.meta.sessionChangeset = undefined
|
155
156
|
}
|
156
157
|
}
|
157
|
-
|
158
|
-
pushToLeader(updateResult.newSyncState.pending)
|
159
158
|
} else {
|
160
159
|
span.addEvent('pull:advance', {
|
161
160
|
payloadTag: payload._tag,
|
@@ -183,7 +182,6 @@ export const makeClientSessionSyncProcessor = ({
|
|
183
182
|
}),
|
184
183
|
),
|
185
184
|
Stream.runDrain,
|
186
|
-
Effect.forever, // NOTE Whenever the leader changes, we need to re-start the stream
|
187
185
|
Effect.tapCauseLogPretty,
|
188
186
|
Effect.forkScoped,
|
189
187
|
)
|
@@ -198,7 +196,7 @@ export const makeClientSessionSyncProcessor = ({
|
|
198
196
|
|
199
197
|
export interface ClientSessionSyncProcessor {
|
200
198
|
push: (
|
201
|
-
batch: ReadonlyArray<MutationEvent.
|
199
|
+
batch: ReadonlyArray<MutationEvent.PartialAny>,
|
202
200
|
options: { otelContext: otel.Context },
|
203
201
|
) => {
|
204
202
|
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 =
|
23
|
+
export const rootParentId = { global: EventId.ROOT.global - 1, local: 0 } satisfies EventId.EventId
|
24
24
|
|
25
25
|
export type HistoryDagNode = {
|
26
26
|
id: EventId.EventId
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import * as EventId from '../../schema/EventId.js'
|
1
|
+
import type * 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.PartialAny[]
|
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.PartialAny[]
|
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
|
-
}):
|
51
|
+
}): MutationEvent.Any[] => {
|
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:
|
93
|
-
parentId:
|
92
|
+
id: { global: headGlobalId + index + 1, local: 0 } satisfies EventId.EventId,
|
93
|
+
parentId: { global: headGlobalId + index, local: 0 } satisfies EventId.EventId,
|
94
94
|
mutation: event.mutation,
|
95
95
|
args: event.args,
|
96
|
-
}) satisfies MutationEvent.
|
96
|
+
}) satisfies MutationEvent.Any,
|
97
97
|
)
|
98
98
|
}
|
@@ -140,9 +140,16 @@ 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
|
+
|
143
150
|
const eventNodes = partialEvents.map((partialEvent) => {
|
144
151
|
const mutationDef = mutationDefs[partialEvent.mutation]!
|
145
|
-
const eventId =
|
152
|
+
const eventId = getNextEventId(mutationDef)
|
146
153
|
currentEventId = eventId
|
147
154
|
|
148
155
|
const factsSnapshot = factsSnapshotForDag(historyDagFromNodes(nodesAcc, { skipFactsCheck: true }), undefined)
|
@@ -217,8 +224,8 @@ const getParentId = (eventId: EventId.EventId): EventId.EventId => {
|
|
217
224
|
const localParentId = eventId.local - 1
|
218
225
|
|
219
226
|
if (localParentId < 0) {
|
220
|
-
return
|
227
|
+
return { global: globalParentId - 1, local: 0 }
|
221
228
|
}
|
222
229
|
|
223
|
-
return
|
230
|
+
return { global: globalParentId, local: localParentId }
|
224
231
|
}
|
package/src/sync/sync.ts
CHANGED
@@ -1,23 +1,12 @@
|
|
1
|
-
import type { Effect, HttpClient, Option,
|
1
|
+
import type { Effect, HttpClient, Option, 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'
|
6
4
|
import * as EventId from '../schema/EventId.js'
|
7
5
|
import type * as MutationEvent from '../schema/MutationEvent.js'
|
8
6
|
|
9
|
-
|
10
|
-
|
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
|
7
|
+
export interface SyncBackendOptionsBase {
|
8
|
+
type: string
|
9
|
+
[key: string]: Schema.JsonValue
|
21
10
|
}
|
22
11
|
|
23
12
|
export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
@@ -29,7 +18,7 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
29
18
|
) => Stream.Stream<
|
30
19
|
{
|
31
20
|
batch: ReadonlyArray<{
|
32
|
-
mutationEventEncoded: MutationEvent.
|
21
|
+
mutationEventEncoded: MutationEvent.AnyEncoded
|
33
22
|
metadata: Option.Option<TSyncMetadata>
|
34
23
|
}>
|
35
24
|
remaining: number
|
@@ -44,7 +33,7 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
44
33
|
* - Number of events: 1-100
|
45
34
|
* - event ids must be in ascending order
|
46
35
|
* */
|
47
|
-
batch: ReadonlyArray<MutationEvent.
|
36
|
+
batch: ReadonlyArray<MutationEvent.AnyEncoded>,
|
48
37
|
) => Effect.Effect<
|
49
38
|
{
|
50
39
|
/** Indexes are relative to `batch` */
|
@@ -57,7 +46,6 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
57
46
|
}
|
58
47
|
|
59
48
|
export class IsOfflineError extends Schema.TaggedError<IsOfflineError>()('IsOfflineError', {}) {}
|
60
|
-
|
61
49
|
export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('InvalidPushError', {
|
62
50
|
reason: Schema.Union(
|
63
51
|
Schema.TaggedStruct('Unexpected', {
|
@@ -73,7 +61,6 @@ export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('In
|
|
73
61
|
}),
|
74
62
|
),
|
75
63
|
}) {}
|
76
|
-
|
77
64
|
export class InvalidPullError extends Schema.TaggedError<InvalidPullError>()('InvalidPullError', {
|
78
65
|
message: Schema.String,
|
79
66
|
}) {}
|