@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.
Files changed (146) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapter-types.d.ts +23 -26
  3. package/dist/adapter-types.d.ts.map +1 -1
  4. package/dist/adapter-types.js.map +1 -1
  5. package/dist/derived-mutations.d.ts +4 -4
  6. package/dist/derived-mutations.d.ts.map +1 -1
  7. package/dist/derived-mutations.test.js.map +1 -1
  8. package/dist/devtools/devtools-bridge.d.ts +1 -2
  9. package/dist/devtools/devtools-bridge.d.ts.map +1 -1
  10. package/dist/devtools/devtools-messages.d.ts +110 -98
  11. package/dist/devtools/devtools-messages.d.ts.map +1 -1
  12. package/dist/devtools/devtools-messages.js +6 -9
  13. package/dist/devtools/devtools-messages.js.map +1 -1
  14. package/dist/index.d.ts +4 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/leader-thread/apply-mutation.d.ts +2 -5
  17. package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
  18. package/dist/leader-thread/apply-mutation.js +26 -38
  19. package/dist/leader-thread/apply-mutation.js.map +1 -1
  20. package/dist/leader-thread/leader-sync-processor.d.ts +2 -2
  21. package/dist/leader-thread/leader-sync-processor.d.ts.map +1 -1
  22. package/dist/leader-thread/leader-sync-processor.js +12 -20
  23. package/dist/leader-thread/leader-sync-processor.js.map +1 -1
  24. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  25. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  26. package/dist/leader-thread/leader-worker-devtools.js +66 -22
  27. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  28. package/dist/leader-thread/make-leader-thread-layer.d.ts +7 -8
  29. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  30. package/dist/leader-thread/make-leader-thread-layer.js +5 -11
  31. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  32. package/dist/leader-thread/mutationlog.d.ts +17 -4
  33. package/dist/leader-thread/mutationlog.d.ts.map +1 -1
  34. package/dist/leader-thread/mutationlog.js +1 -2
  35. package/dist/leader-thread/mutationlog.js.map +1 -1
  36. package/dist/leader-thread/pull-queue-set.d.ts.map +1 -1
  37. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  38. package/dist/leader-thread/recreate-db.js +3 -9
  39. package/dist/leader-thread/recreate-db.js.map +1 -1
  40. package/dist/leader-thread/types.d.ts +9 -17
  41. package/dist/leader-thread/types.d.ts.map +1 -1
  42. package/dist/leader-thread/types.js.map +1 -1
  43. package/dist/mutation.d.ts +2 -9
  44. package/dist/mutation.d.ts.map +1 -1
  45. package/dist/mutation.js +5 -5
  46. package/dist/mutation.js.map +1 -1
  47. package/dist/query-builder/impl.d.ts +1 -1
  48. package/dist/rehydrate-from-mutationlog.d.ts +2 -2
  49. package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
  50. package/dist/rehydrate-from-mutationlog.js +19 -13
  51. package/dist/rehydrate-from-mutationlog.js.map +1 -1
  52. package/dist/schema/EventId.d.ts +14 -16
  53. package/dist/schema/EventId.d.ts.map +1 -1
  54. package/dist/schema/EventId.js +7 -15
  55. package/dist/schema/EventId.js.map +1 -1
  56. package/dist/schema/MutationEvent.d.ts +80 -49
  57. package/dist/schema/MutationEvent.d.ts.map +1 -1
  58. package/dist/schema/MutationEvent.js +15 -32
  59. package/dist/schema/MutationEvent.js.map +1 -1
  60. package/dist/schema/system-tables.d.ts +26 -26
  61. package/dist/schema/system-tables.d.ts.map +1 -1
  62. package/dist/schema/system-tables.js +11 -19
  63. package/dist/schema/system-tables.js.map +1 -1
  64. package/dist/schema-management/migrations.js +6 -6
  65. package/dist/schema-management/migrations.js.map +1 -1
  66. package/dist/sync/client-session-sync-processor.d.ts +4 -4
  67. package/dist/sync/client-session-sync-processor.d.ts.map +1 -1
  68. package/dist/sync/index.d.ts +1 -1
  69. package/dist/sync/index.d.ts.map +1 -1
  70. package/dist/sync/index.js +1 -1
  71. package/dist/sync/index.js.map +1 -1
  72. package/dist/sync/next/history-dag-common.d.ts +4 -1
  73. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  74. package/dist/sync/next/history-dag-common.js +1 -1
  75. package/dist/sync/next/history-dag-common.js.map +1 -1
  76. package/dist/sync/next/rebase-events.d.ts +3 -3
  77. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  78. package/dist/sync/next/rebase-events.js +2 -3
  79. package/dist/sync/next/rebase-events.js.map +1 -1
  80. package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
  81. package/dist/sync/next/test/mutation-fixtures.js +9 -3
  82. package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
  83. package/dist/sync/sync.d.ts +11 -21
  84. package/dist/sync/sync.d.ts.map +1 -1
  85. package/dist/sync/sync.js.map +1 -1
  86. package/dist/sync/syncstate.d.ts +23 -45
  87. package/dist/sync/syncstate.d.ts.map +1 -1
  88. package/dist/sync/syncstate.js +12 -56
  89. package/dist/sync/syncstate.js.map +1 -1
  90. package/dist/sync/syncstate.test.js +69 -125
  91. package/dist/sync/syncstate.test.js.map +1 -1
  92. package/dist/sync/validate-push-payload.d.ts +2 -2
  93. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  94. package/dist/sync/validate-push-payload.js +2 -2
  95. package/dist/sync/validate-push-payload.js.map +1 -1
  96. package/dist/version.d.ts +1 -1
  97. package/dist/version.d.ts.map +1 -1
  98. package/dist/version.js +1 -1
  99. package/dist/version.js.map +1 -1
  100. package/package.json +5 -6
  101. package/src/adapter-types.ts +24 -22
  102. package/src/derived-mutations.test.ts +1 -1
  103. package/src/derived-mutations.ts +5 -9
  104. package/src/devtools/devtools-bridge.ts +1 -2
  105. package/src/devtools/devtools-messages.ts +6 -9
  106. package/src/index.ts +6 -0
  107. package/src/leader-thread/apply-mutation.ts +31 -49
  108. package/src/leader-thread/{LeaderSyncProcessor.ts → leader-sync-processor.ts} +230 -235
  109. package/src/leader-thread/leader-worker-devtools.ts +109 -30
  110. package/src/leader-thread/make-leader-thread-layer.ts +13 -24
  111. package/src/leader-thread/mutationlog.ts +5 -9
  112. package/src/leader-thread/recreate-db.ts +5 -9
  113. package/src/leader-thread/types.ts +11 -18
  114. package/src/mutation.ts +7 -17
  115. package/src/rehydrate-from-mutationlog.ts +23 -15
  116. package/src/schema/EventId.ts +9 -23
  117. package/src/schema/MutationEvent.ts +24 -46
  118. package/src/schema/system-tables.ts +11 -19
  119. package/src/schema-management/migrations.ts +6 -6
  120. package/src/sync/{ClientSessionSyncProcessor.ts → client-session-sync-processor.ts} +9 -11
  121. package/src/sync/index.ts +1 -1
  122. package/src/sync/next/history-dag-common.ts +1 -1
  123. package/src/sync/next/rebase-events.ts +7 -7
  124. package/src/sync/next/test/mutation-fixtures.ts +10 -3
  125. package/src/sync/sync.ts +6 -19
  126. package/src/sync/syncstate.test.ts +67 -127
  127. package/src/sync/syncstate.ts +19 -21
  128. package/src/sync/validate-push-payload.ts +4 -7
  129. package/src/version.ts +1 -1
  130. package/dist/leader-thread/LeaderSyncProcessor.d.ts +0 -37
  131. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +0 -1
  132. package/dist/leader-thread/LeaderSyncProcessor.js +0 -417
  133. package/dist/leader-thread/LeaderSyncProcessor.js.map +0 -1
  134. package/dist/schema/EventId.test.d.ts +0 -2
  135. package/dist/schema/EventId.test.d.ts.map +0 -1
  136. package/dist/schema/EventId.test.js +0 -11
  137. package/dist/schema/EventId.test.js.map +0 -1
  138. package/dist/schema/MutationEvent.test.d.ts +0 -2
  139. package/dist/schema/MutationEvent.test.d.ts.map +0 -1
  140. package/dist/schema/MutationEvent.test.js +0 -2
  141. package/dist/schema/MutationEvent.test.js.map +0 -1
  142. package/dist/sync/ClientSessionSyncProcessor.d.ts +0 -45
  143. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +0 -1
  144. package/dist/sync/ClientSessionSyncProcessor.js +0 -134
  145. package/dist/sync/ClientSessionSyncProcessor.js.map +0 -1
  146. 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 AnyDecoded = MutationEvent<MutationDef.Any>
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 PartialAnyDecoded = MutationEventPartial<MutationDef.Any>
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: AnyDecoded | PartialAnyDecoded,
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: 'MutationEventPartial' }) as any
108
+ ).annotations({ title: 'MutationEventSchemaPartial' }) as any
130
109
 
131
110
  export const makeMutationEventSchemaMemo = memoizeByRef(makeMutationEventSchema)
132
111
 
133
- /** Equivalent to AnyEncoded but with a meta field and some convenience methods */
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(parentId, isLocal),
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({ schema: EventId.GlobalEventId }),
51
- idLocal: SqliteDsl.integer({ schema: EventId.LocalEventId }),
52
- changeset: SqliteDsl.blob({ nullable: true }),
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, schema: EventId.GlobalEventId }),
76
- idLocal: SqliteDsl.integer({ primaryKey: true, schema: EventId.LocalEventId }),
77
- parentIdGlobal: SqliteDsl.integer({ schema: EventId.GlobalEventId }),
78
- parentIdLocal: SqliteDsl.integer({ schema: EventId.LocalEventId }),
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 '${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 `'${column.name}' ${columnTypeStr} ${nullableStr} ${defaultValueStr}`
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 { ClientSessionLeaderThreadProxy, UnexpectedError } from '../adapter-types.js'
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, updateSyncState } from './syncstate.js'
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: ClientSessionLeaderThreadProxy['mutations']['pull']
35
+ pullFromLeader: Coordinator['mutations']['pull']
35
36
  applyMutation: (
36
- mutationEventDecoded: MutationEvent.PartialAnyDecoded,
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: new SyncState({
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.PartialAnyDecoded>,
199
+ batch: ReadonlyArray<MutationEvent.PartialAny>,
202
200
  options: { otelContext: otel.Context },
203
201
  ) => {
204
202
  writeTables: Set<string>
package/src/sync/index.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export * from './sync.js'
2
2
  export * from './validate-push-payload.js'
3
- export * from './ClientSessionSyncProcessor.js'
3
+ export * from './client-session-sync-processor.js'
@@ -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 = EventId.make({ global: EventId.ROOT.global - 1, local: EventId.localDefault })
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.PartialAnyDecoded[]
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.PartialAnyDecoded[]
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
- }): ReadonlyArray<MutationEvent.AnyDecoded> => {
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: EventId.make({ global: headGlobalId + index + 1, local: EventId.localDefault }),
93
- parentId: EventId.make({ global: headGlobalId + index, local: EventId.localDefault }),
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.AnyDecoded,
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 = EventId.nextPair(currentEventId, mutationDef.options.localOnly).id
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 EventId.make({ global: globalParentId - 1, local: EventId.localDefault })
227
+ return { global: globalParentId - 1, local: 0 }
221
228
  }
222
229
 
223
- return EventId.make({ global: globalParentId, local: localParentId })
230
+ return { global: globalParentId, local: localParentId }
224
231
  }
package/src/sync/sync.ts CHANGED
@@ -1,23 +1,12 @@
1
- import type { Effect, HttpClient, Option, Scope, Stream, SubscriptionRef } from '@livestore/utils/effect'
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
- * 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
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.AnyEncodedGlobal
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.AnyEncodedGlobal>,
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
  }) {}