@livestore/common 0.3.2-dev.10 → 0.3.2-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.
Files changed (87) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapter-types.d.ts +3 -3
  3. package/dist/adapter-types.d.ts.map +1 -1
  4. package/dist/devtools/devtools-messages-client-session.d.ts +21 -21
  5. package/dist/devtools/devtools-messages-common.d.ts +6 -6
  6. package/dist/devtools/devtools-messages-leader.d.ts +24 -24
  7. package/dist/leader-thread/LeaderSyncProcessor.js +3 -1
  8. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  9. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  10. package/dist/leader-thread/make-leader-thread-layer.js +21 -4
  11. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  12. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  13. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  14. package/dist/leader-thread/shutdown-channel.js +2 -2
  15. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  16. package/dist/materializer-helper.d.ts +3 -3
  17. package/dist/materializer-helper.d.ts.map +1 -1
  18. package/dist/materializer-helper.js +2 -2
  19. package/dist/materializer-helper.js.map +1 -1
  20. package/dist/rematerialize-from-eventlog.js +1 -1
  21. package/dist/rematerialize-from-eventlog.js.map +1 -1
  22. package/dist/schema/EventDef.d.ts +104 -178
  23. package/dist/schema/EventSequenceNumber.d.ts +5 -0
  24. package/dist/schema/EventSequenceNumber.d.ts.map +1 -1
  25. package/dist/schema/EventSequenceNumber.js +7 -2
  26. package/dist/schema/EventSequenceNumber.js.map +1 -1
  27. package/dist/schema/EventSequenceNumber.test.js +2 -2
  28. package/dist/schema/LiveStoreEvent.d.ts +1 -0
  29. package/dist/schema/LiveStoreEvent.d.ts.map +1 -1
  30. package/dist/schema/LiveStoreEvent.js +5 -0
  31. package/dist/schema/LiveStoreEvent.js.map +1 -1
  32. package/dist/schema/schema.d.ts +3 -0
  33. package/dist/schema/schema.d.ts.map +1 -1
  34. package/dist/schema/schema.js.map +1 -1
  35. package/dist/schema/state/sqlite/client-document-def.d.ts +1 -0
  36. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  37. package/dist/schema/state/sqlite/client-document-def.js +4 -2
  38. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  39. package/dist/schema/state/sqlite/client-document-def.test.js +76 -1
  40. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  41. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +65 -165
  42. package/dist/schema/state/sqlite/query-builder/api.d.ts +309 -560
  43. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  44. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts +1 -0
  45. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  46. package/dist/schema/state/sqlite/query-builder/astToSql.js +8 -6
  47. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  48. package/dist/schema/state/sqlite/table-def.d.ts +70 -152
  49. package/dist/schema-management/common.d.ts +1 -1
  50. package/dist/schema-management/common.d.ts.map +1 -1
  51. package/dist/schema-management/common.js +11 -2
  52. package/dist/schema-management/common.js.map +1 -1
  53. package/dist/schema-management/migrations.js +1 -1
  54. package/dist/schema-management/migrations.js.map +1 -1
  55. package/dist/schema-management/migrations.test.d.ts +2 -0
  56. package/dist/schema-management/migrations.test.d.ts.map +1 -0
  57. package/dist/schema-management/migrations.test.js +52 -0
  58. package/dist/schema-management/migrations.test.js.map +1 -0
  59. package/dist/sql-queries/types.d.ts +37 -133
  60. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  61. package/dist/sync/ClientSessionSyncProcessor.js +8 -7
  62. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  63. package/dist/sync/sync.d.ts.map +1 -1
  64. package/dist/sync/sync.js.map +1 -1
  65. package/dist/version.d.ts +1 -1
  66. package/dist/version.js +1 -1
  67. package/package.json +4 -4
  68. package/src/adapter-types.ts +3 -3
  69. package/src/leader-thread/LeaderSyncProcessor.ts +3 -1
  70. package/src/leader-thread/make-leader-thread-layer.ts +26 -7
  71. package/src/leader-thread/shutdown-channel.ts +2 -2
  72. package/src/materializer-helper.ts +5 -11
  73. package/src/rematerialize-from-eventlog.ts +2 -2
  74. package/src/schema/EventSequenceNumber.test.ts +2 -2
  75. package/src/schema/EventSequenceNumber.ts +8 -2
  76. package/src/schema/LiveStoreEvent.ts +6 -0
  77. package/src/schema/schema.ts +4 -0
  78. package/src/schema/state/sqlite/client-document-def.test.ts +89 -1
  79. package/src/schema/state/sqlite/client-document-def.ts +5 -2
  80. package/src/schema/state/sqlite/query-builder/api.ts +4 -3
  81. package/src/schema/state/sqlite/query-builder/astToSql.ts +9 -7
  82. package/src/schema-management/common.ts +10 -3
  83. package/src/schema-management/migrations.test.ts +65 -0
  84. package/src/schema-management/migrations.ts +1 -1
  85. package/src/sync/ClientSessionSyncProcessor.ts +8 -6
  86. package/src/sync/sync.ts +2 -0
  87. package/src/version.ts +1 -1
@@ -3,7 +3,7 @@ import { describe, expect, test } from 'vitest'
3
3
 
4
4
  import { tables } from '../../../__tests__/fixture.ts'
5
5
  import type * as LiveStoreEvent from '../../LiveStoreEvent.ts'
6
- import { ClientDocumentTableDefSymbol, clientDocument } from './client-document-def.ts'
6
+ import { ClientDocumentTableDefSymbol, clientDocument, mergeDefaultValues } from './client-document-def.ts'
7
7
 
8
8
  describe('client document table', () => {
9
9
  test('set event', () => {
@@ -238,3 +238,91 @@ const patchId = (muationEvent: LiveStoreEvent.PartialAnyDecoded) => {
238
238
  const id = `00000000-0000-0000-0000-000000000000`
239
239
  return { ...muationEvent, id }
240
240
  }
241
+
242
+ describe('mergeDefaultValues', () => {
243
+ test('merges values from both objects', () => {
244
+ const defaults = { a: 1, b: 2 }
245
+ const explicit = { a: 10, b: 20 }
246
+ const result = mergeDefaultValues(defaults, explicit)
247
+
248
+ expect(result).toEqual({ a: 10, b: 20 })
249
+ })
250
+
251
+ test('uses default values when explicit values are undefined', () => {
252
+ const defaults = { a: 1, b: 2 }
253
+ const explicit = { a: undefined, b: 20 } as any
254
+ const result = mergeDefaultValues(defaults, explicit)
255
+
256
+ expect(result).toEqual({ a: 1, b: 20 })
257
+ })
258
+
259
+ test('should preserve properties that are not in default values', () => {
260
+ const defaults = { a: 1, b: 2 }
261
+ const explicit = { a: 10, b: 20, c: 30 }
262
+ const result = mergeDefaultValues(defaults, explicit)
263
+
264
+ // Should include ALL properties from explicit, not just those in defaults
265
+ expect(result).toEqual({ a: 10, b: 20, c: 30 })
266
+ expect('c' in result).toBe(true)
267
+ })
268
+
269
+ test('issue #487 - should preserve optional fields not in defaults', () => {
270
+ const defaults = {
271
+ newTodoText: '',
272
+ filter: 'all' as const,
273
+ }
274
+ const userSet = {
275
+ newTodoText: '',
276
+ description: 'First attempt', // Optional field not in defaults
277
+ filter: 'all' as const,
278
+ }
279
+ const result = mergeDefaultValues(defaults, userSet)
280
+
281
+ // Should include the description field even though it's not in defaults
282
+ expect(result).toEqual({
283
+ newTodoText: '',
284
+ description: 'First attempt',
285
+ filter: 'all',
286
+ })
287
+ expect('description' in result).toBe(true)
288
+ })
289
+
290
+ test('handles non-object values', () => {
291
+ expect(mergeDefaultValues('default', 'explicit')).toBe('explicit')
292
+ expect(mergeDefaultValues(42, 100)).toBe(100)
293
+ expect(mergeDefaultValues(null, { a: 1 })).toEqual({ a: 1 })
294
+ expect(mergeDefaultValues({ a: 1 }, null)).toBe(null)
295
+ })
296
+
297
+ test('handles nested objects (current implementation does not deep merge)', () => {
298
+ const defaults = { a: { x: 1, y: 2 }, b: 3 }
299
+ const explicit = { a: { x: 10 }, b: 30 } as any
300
+ const result = mergeDefaultValues(defaults, explicit)
301
+
302
+ // Current implementation replaces entire nested object
303
+ expect(result).toEqual({ a: { x: 10 }, b: 30 })
304
+ // Note: 'y' is lost because the entire 'a' object is replaced
305
+ })
306
+
307
+ test('should handle mix of default and new properties', () => {
308
+ const defaults = {
309
+ required1: 'default1',
310
+ required2: 'default2',
311
+ }
312
+ const userSet = {
313
+ required1: 'user1', // Override default
314
+ required2: 'default2', // Keep default
315
+ optional1: 'new1', // New field
316
+ optional2: 'new2', // New field
317
+ }
318
+ const result = mergeDefaultValues(defaults, userSet)
319
+
320
+ expect(result).toEqual({
321
+ required1: 'user1',
322
+ required2: 'default2',
323
+ optional1: 'new1',
324
+ optional2: 'new2',
325
+ })
326
+ expect(Object.keys(result).sort()).toEqual(['optional1', 'optional2', 'required1', 'required2'])
327
+ })
328
+ })
@@ -121,7 +121,7 @@ export const clientDocument = <
121
121
  return clientDocumentTableDef
122
122
  }
123
123
 
124
- const mergeDefaultValues = <T>(defaultValues: T, explicitDefaultValues: T): T => {
124
+ export const mergeDefaultValues = <T>(defaultValues: T, explicitDefaultValues: T): T => {
125
125
  if (
126
126
  typeof defaultValues !== 'object' ||
127
127
  typeof explicitDefaultValues !== 'object' ||
@@ -131,7 +131,10 @@ const mergeDefaultValues = <T>(defaultValues: T, explicitDefaultValues: T): T =>
131
131
  return explicitDefaultValues
132
132
  }
133
133
 
134
- return Object.keys(defaultValues as any).reduce((acc, key) => {
134
+ // Get all unique keys from both objects
135
+ const allKeys = new Set([...Object.keys(defaultValues as any), ...Object.keys(explicitDefaultValues as any)])
136
+
137
+ return Array.from(allKeys).reduce((acc, key) => {
135
138
  acc[key] = (explicitDefaultValues as any)[key] ?? (defaultValues as any)[key]
136
139
  return acc
137
140
  }, {} as any)
@@ -122,7 +122,7 @@ export type QueryBuilder<
122
122
  readonly [QueryBuilderTypeId]: QueryBuilderTypeId
123
123
  readonly [QueryBuilderAstSymbol]: QueryBuilderAst
124
124
  readonly ResultType: TResult
125
- readonly asSql: () => { query: string; bindValues: SqlValue[] }
125
+ readonly asSql: () => { query: string; bindValues: SqlValue[]; usedTables: Set<string> }
126
126
  readonly toString: () => string
127
127
  } & Omit<QueryBuilder.ApiFull<TResult, TTableDef, TWithout>, TWithout>
128
128
 
@@ -264,14 +264,15 @@ export namespace QueryBuilder {
264
264
  * Example:
265
265
  * ```ts
266
266
  * db.todos.orderBy('createdAt', 'desc')
267
+ * db.todos.orderBy([{ col: 'createdAt', direction: 'desc' }])
267
268
  * ```
268
269
  */
269
270
  readonly orderBy: {
270
- <TColName extends keyof TTableDef['sqliteDef']['columns'] & string>(
271
+ <const TColName extends keyof TTableDef['sqliteDef']['columns'] & string>(
271
272
  col: TColName,
272
273
  direction: 'asc' | 'desc',
273
274
  ): QueryBuilder<TResult, TTableDef, TWithout | 'returning' | 'onConflict'>
274
- <TParams extends QueryBuilder.OrderByParams<TTableDef>>(
275
+ <const TParams extends QueryBuilder.OrderByParams<TTableDef>>(
275
276
  params: TParams,
276
277
  ): QueryBuilder<TResult, TTableDef, TWithout | 'returning' | 'onConflict'>
277
278
  }
@@ -65,8 +65,9 @@ const formatReturningClause = (returning?: string[]): string => {
65
65
  return ` RETURNING ${returning.join(', ')}`
66
66
  }
67
67
 
68
- export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: SqlValue[] } => {
68
+ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: SqlValue[]; usedTables: Set<string> } => {
69
69
  const bindValues: SqlValue[] = []
70
+ const usedTables = new Set<string>([ast.tableDef.sqliteDef.name])
70
71
 
71
72
  // INSERT query
72
73
  if (ast._tag === 'InsertQuery') {
@@ -134,7 +135,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
134
135
  query += conflictClause
135
136
 
136
137
  query += formatReturningClause(ast.returning)
137
- return { query, bindValues }
138
+ return { query, bindValues, usedTables }
138
139
  }
139
140
 
140
141
  // UPDATE query
@@ -145,7 +146,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
145
146
  console.warn(
146
147
  `UPDATE query requires at least one column to set (for table ${ast.tableDef.sqliteDef.name}). Running no-op query instead to skip this update query.`,
147
148
  )
148
- return { query: 'SELECT 1', bindValues: [] }
149
+ return { query: 'SELECT 1', bindValues: [], usedTables }
149
150
  // return shouldNeverHappen('UPDATE query requires at least one column to set.')
150
151
  }
151
152
 
@@ -162,7 +163,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
162
163
  if (whereClause) query += ` ${whereClause}`
163
164
 
164
165
  query += formatReturningClause(ast.returning)
165
- return { query, bindValues }
166
+ return { query, bindValues, usedTables }
166
167
  }
167
168
 
168
169
  // DELETE query
@@ -173,7 +174,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
173
174
  if (whereClause) query += ` ${whereClause}`
174
175
 
175
176
  query += formatReturningClause(ast.returning)
176
- return { query, bindValues }
177
+ return { query, bindValues, usedTables }
177
178
  }
178
179
 
179
180
  // COUNT query
@@ -185,7 +186,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
185
186
  .filter((clause) => clause.length > 0)
186
187
  .join(' ')
187
188
 
188
- return { query, bindValues }
189
+ return { query, bindValues, usedTables }
189
190
  }
190
191
 
191
192
  // ROW query
@@ -202,6 +203,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
202
203
  return {
203
204
  query: `SELECT * FROM '${ast.tableDef.sqliteDef.name}' WHERE id = ?`,
204
205
  bindValues: [encodedId as SqlValue],
206
+ usedTables,
205
207
  }
206
208
  }
207
209
 
@@ -228,5 +230,5 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
228
230
  .filter((clause) => clause.length > 0)
229
231
  .join(' ')
230
232
 
231
- return { query, bindValues }
233
+ return { query, bindValues, usedTables }
232
234
  }
@@ -1,4 +1,4 @@
1
- import type { SqliteDb } from '../adapter-types.ts'
1
+ import { type SqliteDb, SqliteError } from '../adapter-types.ts'
2
2
  import type { ParamsObject } from '../util.ts'
3
3
  import { prepareBindValues } from '../util.ts'
4
4
 
@@ -15,9 +15,16 @@ export const dbExecute = (db: SqliteDb, queryStr: string, bindValues?: ParamsObj
15
15
 
16
16
  const preparedBindValues = bindValues ? prepareBindValues(bindValues, queryStr) : undefined
17
17
 
18
- stmt.execute(preparedBindValues)
18
+ try {
19
+ stmt.execute(preparedBindValues)
19
20
 
20
- stmt.finalize()
21
+ stmt.finalize()
22
+ } catch (cause) {
23
+ throw new SqliteError({
24
+ cause,
25
+ query: { sql: queryStr, bindValues: preparedBindValues ?? {} },
26
+ })
27
+ }
21
28
  }
22
29
 
23
30
  export const dbSelect = <T>(db: SqliteDb, queryStr: string, bindValues?: ParamsObject) => {
@@ -0,0 +1,65 @@
1
+ import { Option, Schema } from '@livestore/utils/effect'
2
+ import { describe, expect, it } from 'vitest'
3
+ import type { SqliteAst } from '../schema/state/sqlite/db-schema/mod.ts'
4
+ import { makeColumnSpec } from './migrations.js'
5
+
6
+ const createColumn = (
7
+ name: string,
8
+ type: 'text' | 'integer',
9
+ options: { nullable?: boolean; primaryKey?: boolean } = {},
10
+ ) => ({
11
+ _tag: 'column' as const,
12
+ name,
13
+ type: { _tag: type },
14
+ nullable: options.nullable ?? true,
15
+ primaryKey: options.primaryKey ?? false,
16
+ default: Option.none(),
17
+ schema: type === 'text' ? Schema.String : Schema.Number,
18
+ })
19
+
20
+ describe('makeColumnSpec', () => {
21
+ it('should quote column names properly for reserved keywords', () => {
22
+ const table: SqliteAst.Table = {
23
+ _tag: 'table',
24
+ name: 'blocks',
25
+ columns: [createColumn('order', 'integer', { nullable: false }), createColumn('group', 'text')],
26
+ indexes: [],
27
+ }
28
+
29
+ const result = makeColumnSpec(table)
30
+ expect(result).toMatchInlineSnapshot(`"'order' integer not null , 'group' text "`)
31
+ expect(result).toContain("'order'")
32
+ expect(result).toContain("'group'")
33
+ })
34
+
35
+ it('should handle basic columns with primary keys', () => {
36
+ const table: SqliteAst.Table = {
37
+ _tag: 'table',
38
+ name: 'users',
39
+ columns: [createColumn('id', 'text', { nullable: false, primaryKey: true }), createColumn('name', 'text')],
40
+ indexes: [],
41
+ }
42
+
43
+ const result = makeColumnSpec(table)
44
+ expect(result).toMatchInlineSnapshot(`"'id' text not null , 'name' text , PRIMARY KEY ('id')"`)
45
+ expect(result).toContain("PRIMARY KEY ('id')")
46
+ })
47
+
48
+ it('should handle multi-column primary keys', () => {
49
+ const table: SqliteAst.Table = {
50
+ _tag: 'table',
51
+ name: 'composite',
52
+ columns: [
53
+ createColumn('tenant_id', 'text', { nullable: false, primaryKey: true }),
54
+ createColumn('user_id', 'text', { nullable: false, primaryKey: true }),
55
+ ],
56
+ indexes: [],
57
+ }
58
+
59
+ const result = makeColumnSpec(table)
60
+ expect(result).toMatchInlineSnapshot(
61
+ `"'tenant_id' text not null , 'user_id' text not null , PRIMARY KEY ('tenant_id', 'user_id')"`,
62
+ )
63
+ expect(result).toContain("PRIMARY KEY ('tenant_id', 'user_id')")
64
+ })
65
+ })
@@ -169,7 +169,7 @@ export const migrateTable = ({
169
169
 
170
170
  const createIndexFromDefinition = (tableName: string, index: SqliteAst.Index) => {
171
171
  const uniqueStr = index.unique ? 'UNIQUE' : ''
172
- return sql`create ${uniqueStr} index if not exists '${index.name}' on '${tableName}' (${index.columns.join(', ')})`
172
+ return sql`create ${uniqueStr} index if not exists '${index.name}' on '${tableName}' (${index.columns.map((col) => `'${col}'`).join(', ')})`
173
173
  }
174
174
 
175
175
  export const makeColumnSpec = (tableAst: SqliteAst.Table) => {
@@ -3,6 +3,7 @@ import { LS_DEV, shouldNeverHappen, TRACE_VERBOSE } from '@livestore/utils'
3
3
  import {
4
4
  BucketQueue,
5
5
  Effect,
6
+ Exit,
6
7
  FiberHandle,
7
8
  Option,
8
9
  Queue,
@@ -316,7 +317,7 @@ export const makeClientSessionSyncProcessor = ({
316
317
  refreshTables(writeTables)
317
318
  }).pipe(
318
319
  Effect.tapCauseLogPretty,
319
- Effect.catchAllCause((cause) => clientSession.shutdown(cause)),
320
+ Effect.catchAllCause((cause) => clientSession.shutdown(Exit.failCause(cause))),
320
321
  ),
321
322
  ),
322
323
  Stream.runDrain,
@@ -381,13 +382,14 @@ export interface ClientSessionSyncProcessor {
381
382
  // TODO turn this into a build-time "macro" so all simulation snippets are removed for production builds
382
383
  const SIMULATION_ENABLED = true
383
384
 
385
+ // Warning: High values for the simulation params can lead to very long test runs since those get multiplied with the number of events
384
386
  export const ClientSessionSyncProcessorSimulationParams = Schema.Struct({
385
387
  pull: Schema.Struct({
386
- '1_before_leader_push_fiber_interrupt': Schema.Int.pipe(Schema.between(0, 1000)),
387
- '2_before_leader_push_queue_clear': Schema.Int.pipe(Schema.between(0, 1000)),
388
- '3_before_rebase_rollback': Schema.Int.pipe(Schema.between(0, 1000)),
389
- '4_before_leader_push_queue_offer': Schema.Int.pipe(Schema.between(0, 1000)),
390
- '5_before_leader_push_fiber_run': Schema.Int.pipe(Schema.between(0, 1000)),
388
+ '1_before_leader_push_fiber_interrupt': Schema.Int.pipe(Schema.between(0, 25)),
389
+ '2_before_leader_push_queue_clear': Schema.Int.pipe(Schema.between(0, 25)),
390
+ '3_before_rebase_rollback': Schema.Int.pipe(Schema.between(0, 25)),
391
+ '4_before_leader_push_queue_offer': Schema.Int.pipe(Schema.between(0, 25)),
392
+ '5_before_leader_push_fiber_run': Schema.Int.pipe(Schema.between(0, 25)),
391
393
  }),
392
394
  })
393
395
  type ClientSessionSyncProcessorSimulationParams = typeof ClientSessionSyncProcessorSimulationParams.Type
package/src/sync/sync.ts CHANGED
@@ -31,6 +31,7 @@ export type SyncOptions = {
31
31
  onSyncError?: 'shutdown' | 'ignore'
32
32
  }
33
33
 
34
+ // TODO rename to `SyncProviderClientConstructor`
34
35
  export type SyncBackendConstructor<TSyncMetadata = Schema.JsonValue> = (
35
36
  args: MakeBackendArgs,
36
37
  ) => Effect.Effect<SyncBackend<TSyncMetadata>, UnexpectedError, Scope.Scope | HttpClient.HttpClient>
@@ -41,6 +42,7 @@ export type SyncBackendConstructor<TSyncMetadata = Schema.JsonValue> = (
41
42
  // - dynamic sync backend data;
42
43
  // - data center location (e.g. colo on CF workers)
43
44
 
45
+ // TODO rename to `SyncProviderClient`
44
46
  export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
45
47
  /**
46
48
  * Can be implemented to prepare a connection to the sync backend to speed up the first pull/push.
package/src/version.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // import packageJson from '../package.json' with { type: 'json' }
3
3
  // export const liveStoreVersion = packageJson.version
4
4
 
5
- export const liveStoreVersion = '0.3.2-dev.10' as const
5
+ export const liveStoreVersion = '0.3.2-dev.11' as const
6
6
 
7
7
  /**
8
8
  * This version number is incremented whenever the internal storage format changes in a breaking way.