@livestore/common 0.3.0-dev.22 → 0.3.0-dev.24

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 (103) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapter-types.d.ts +6 -0
  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 +8 -8
  6. package/dist/devtools/devtools-messages-client-session.d.ts +21 -21
  7. package/dist/devtools/devtools-messages-common.d.ts +6 -6
  8. package/dist/devtools/devtools-messages-leader.d.ts +25 -24
  9. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  10. package/dist/leader-thread/LeaderSyncProcessor.js +3 -1
  11. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  12. package/dist/leader-thread/apply-mutation.js +1 -1
  13. package/dist/leader-thread/apply-mutation.js.map +1 -1
  14. package/dist/leader-thread/leader-worker-devtools.js +2 -2
  15. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  16. package/dist/leader-thread/make-leader-thread-layer.d.ts +3 -2
  17. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  18. package/dist/leader-thread/make-leader-thread-layer.js +4 -2
  19. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  20. package/dist/leader-thread/mutationlog.js +1 -1
  21. package/dist/leader-thread/mutationlog.js.map +1 -1
  22. package/dist/leader-thread/pull-queue-set.d.ts.map +1 -1
  23. package/dist/leader-thread/types.d.ts +1 -1
  24. package/dist/leader-thread/types.d.ts.map +1 -1
  25. package/dist/mutation.d.ts.map +1 -1
  26. package/dist/mutation.js +13 -2
  27. package/dist/mutation.js.map +1 -1
  28. package/dist/query-builder/api.d.ts +118 -20
  29. package/dist/query-builder/api.d.ts.map +1 -1
  30. package/dist/query-builder/api.js.map +1 -1
  31. package/dist/query-builder/astToSql.d.ts +7 -0
  32. package/dist/query-builder/astToSql.d.ts.map +1 -0
  33. package/dist/query-builder/astToSql.js +168 -0
  34. package/dist/query-builder/astToSql.js.map +1 -0
  35. package/dist/query-builder/impl.d.ts +1 -5
  36. package/dist/query-builder/impl.d.ts.map +1 -1
  37. package/dist/query-builder/impl.js +130 -96
  38. package/dist/query-builder/impl.js.map +1 -1
  39. package/dist/query-builder/impl.test.js +94 -0
  40. package/dist/query-builder/impl.test.js.map +1 -1
  41. package/dist/query-builder/mod.d.ts +7 -0
  42. package/dist/query-builder/mod.d.ts.map +1 -1
  43. package/dist/query-builder/mod.js +7 -0
  44. package/dist/query-builder/mod.js.map +1 -1
  45. package/dist/query-info.d.ts +4 -1
  46. package/dist/query-info.d.ts.map +1 -1
  47. package/dist/query-info.js.map +1 -1
  48. package/dist/rehydrate-from-mutationlog.js +1 -1
  49. package/dist/rehydrate-from-mutationlog.js.map +1 -1
  50. package/dist/schema/MutationEvent.d.ts +10 -9
  51. package/dist/schema/MutationEvent.d.ts.map +1 -1
  52. package/dist/schema/MutationEvent.js +6 -6
  53. package/dist/schema/MutationEvent.js.map +1 -1
  54. package/dist/schema/db-schema/dsl/mod.d.ts +7 -5
  55. package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -1
  56. package/dist/schema/db-schema/dsl/mod.js +6 -0
  57. package/dist/schema/db-schema/dsl/mod.js.map +1 -1
  58. package/dist/schema/mutations.d.ts +12 -3
  59. package/dist/schema/mutations.d.ts.map +1 -1
  60. package/dist/schema/mutations.js.map +1 -1
  61. package/dist/schema/system-tables.d.ts +5 -5
  62. package/dist/schema/system-tables.d.ts.map +1 -1
  63. package/dist/schema/system-tables.js +1 -2
  64. package/dist/schema/system-tables.js.map +1 -1
  65. package/dist/schema/table-def.d.ts +7 -3
  66. package/dist/schema/table-def.d.ts.map +1 -1
  67. package/dist/schema/table-def.js +7 -1
  68. package/dist/schema/table-def.js.map +1 -1
  69. package/dist/sync/next/rebase-events.d.ts +1 -1
  70. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  71. package/dist/sync/sync.d.ts +10 -1
  72. package/dist/sync/sync.d.ts.map +1 -1
  73. package/dist/sync/sync.js.map +1 -1
  74. package/dist/sync/syncstate.test.js +1 -1
  75. package/dist/sync/syncstate.test.js.map +1 -1
  76. package/dist/version.d.ts +1 -1
  77. package/dist/version.js +1 -1
  78. package/package.json +2 -2
  79. package/src/adapter-types.ts +6 -0
  80. package/src/leader-thread/LeaderSyncProcessor.ts +3 -1
  81. package/src/leader-thread/apply-mutation.ts +2 -2
  82. package/src/leader-thread/leader-worker-devtools.ts +2 -2
  83. package/src/leader-thread/make-leader-thread-layer.ts +6 -2
  84. package/src/leader-thread/mutationlog.ts +1 -1
  85. package/src/leader-thread/types.ts +1 -1
  86. package/src/mutation.ts +20 -3
  87. package/src/query-builder/api.ts +192 -15
  88. package/src/query-builder/astToSql.ts +203 -0
  89. package/src/query-builder/impl.test.ts +104 -0
  90. package/src/query-builder/impl.ts +157 -113
  91. package/src/query-builder/mod.ts +7 -0
  92. package/src/query-info.ts +6 -1
  93. package/src/rehydrate-from-mutationlog.ts +1 -1
  94. package/src/schema/MutationEvent.ts +10 -10
  95. package/src/schema/db-schema/dsl/mod.ts +30 -2
  96. package/src/schema/mutations.ts +12 -1
  97. package/src/schema/system-tables.ts +1 -2
  98. package/src/schema/table-def.ts +14 -4
  99. package/src/sync/next/rebase-events.ts +1 -1
  100. package/src/sync/sync.ts +10 -1
  101. package/src/sync/syncstate.test.ts +1 -1
  102. package/src/version.ts +1 -1
  103. package/tmp/pack.tgz +0 -0
package/src/query-info.ts CHANGED
@@ -9,7 +9,7 @@ import type { DbSchema } from './schema/mod.js'
9
9
  *
10
10
  * This information is currently only used for derived mutations.
11
11
  */
12
- export type QueryInfo = QueryInfo.None | QueryInfo.Row | QueryInfo.Col | QueryInfo.ColJsonValue
12
+ export type QueryInfo = QueryInfo.None | QueryInfo.Row | QueryInfo.Col | QueryInfo.ColJsonValue | QueryInfo.Write
13
13
  // export type QueryInfo<TTableDef extends DbSchema.TableDefBase = DbSchema.TableDefBase> =
14
14
  // | QueryInfo.None
15
15
  // | QueryInfo.Row<TTableDef>
@@ -45,6 +45,11 @@ export namespace QueryInfo {
45
45
  jsonPath: string
46
46
  }
47
47
 
48
+ // NOTE Not yet used but we might want to use this in order to avoid write queries in read-only situations
49
+ export type Write = {
50
+ _tag: 'Write'
51
+ }
52
+
48
53
  // NOTE maybe we want to bring back type-params back like below
49
54
  // export type Row<TTableDef extends DbSchema.TableDefBase> = {
50
55
  // _tag: 'Row'
@@ -65,7 +65,7 @@ This likely means the schema has changed in an incompatible way.
65
65
  mutation: row.mutation,
66
66
  args,
67
67
  clientId: row.clientId,
68
- sessionId: row.sessionId ?? undefined,
68
+ sessionId: row.sessionId,
69
69
  } satisfies MutationEvent.AnyEncoded
70
70
 
71
71
  yield* applyMutation(mutationEventEncoded, { skipMutationLog: true })
@@ -21,7 +21,7 @@ export type MutationEvent<TMutationsDef extends MutationDef.Any> = {
21
21
  id: EventId.EventId
22
22
  parentId: EventId.EventId
23
23
  clientId: string
24
- sessionId: string | undefined
24
+ sessionId: string
25
25
  }
26
26
 
27
27
  export type MutationEventEncoded<TMutationsDef extends MutationDef.Any> = {
@@ -30,7 +30,7 @@ export type MutationEventEncoded<TMutationsDef extends MutationDef.Any> = {
30
30
  id: EventId.EventId
31
31
  parentId: EventId.EventId
32
32
  clientId: string
33
- sessionId: string | undefined
33
+ sessionId: string
34
34
  }
35
35
 
36
36
  export type AnyDecoded = MutationEvent<MutationDef.Any>
@@ -40,7 +40,7 @@ export const AnyDecoded = Schema.Struct({
40
40
  id: EventId.EventId,
41
41
  parentId: EventId.EventId,
42
42
  clientId: Schema.String,
43
- sessionId: Schema.UndefinedOr(Schema.String),
43
+ sessionId: Schema.String,
44
44
  }).annotations({ title: 'MutationEvent.AnyDecoded' })
45
45
 
46
46
  export type AnyEncoded = MutationEventEncoded<MutationDef.Any>
@@ -50,7 +50,7 @@ export const AnyEncoded = Schema.Struct({
50
50
  id: EventId.EventId,
51
51
  parentId: EventId.EventId,
52
52
  clientId: Schema.String,
53
- sessionId: Schema.UndefinedOr(Schema.String),
53
+ sessionId: Schema.String,
54
54
  }).annotations({ title: 'MutationEvent.AnyEncoded' })
55
55
 
56
56
  export const AnyEncodedGlobal = Schema.Struct({
@@ -59,6 +59,7 @@ export const AnyEncodedGlobal = Schema.Struct({
59
59
  id: EventId.GlobalEventId,
60
60
  parentId: EventId.GlobalEventId,
61
61
  clientId: Schema.String,
62
+ sessionId: Schema.String,
62
63
  }).annotations({ title: 'MutationEvent.AnyEncodedGlobal' })
63
64
  export type AnyEncodedGlobal = typeof AnyEncodedGlobal.Type
64
65
 
@@ -90,7 +91,7 @@ export type ForMutationDefRecord<TMutationsDefRecord extends MutationDefRecord>
90
91
  id: EventId.EventId
91
92
  parentId: EventId.EventId
92
93
  clientId: string
93
- sessionId: string | undefined
94
+ sessionId: string
94
95
  }
95
96
  }[keyof TMutationsDefRecord],
96
97
  {
@@ -100,7 +101,7 @@ export type ForMutationDefRecord<TMutationsDefRecord extends MutationDefRecord>
100
101
  id: EventId.EventId
101
102
  parentId: EventId.EventId
102
103
  clientId: string
103
- sessionId: string | undefined
104
+ sessionId: string
104
105
  }
105
106
  }[keyof TMutationsDefRecord]
106
107
  >
@@ -131,7 +132,7 @@ export const makeMutationEventSchema = <TSchema extends LiveStoreSchema>(
131
132
  id: EventId.EventId,
132
133
  parentId: EventId.EventId,
133
134
  clientId: Schema.String,
134
- sessionId: Schema.UndefinedOr(Schema.String),
135
+ sessionId: Schema.String,
135
136
  }),
136
137
  ),
137
138
  ).annotations({ title: 'MutationEvent' }) as any
@@ -157,7 +158,7 @@ export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('MutationEven
157
158
  id: EventId.EventId,
158
159
  parentId: EventId.EventId,
159
160
  clientId: Schema.String,
160
- sessionId: Schema.UndefinedOr(Schema.String),
161
+ sessionId: Schema.String,
161
162
  // TODO get rid of `meta` again by cleaning up the usage implementations
162
163
  meta: Schema.optionalWith(
163
164
  Schema.Any as Schema.Schema<{
@@ -188,7 +189,6 @@ export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('MutationEven
188
189
  ...mutationEvent,
189
190
  id: { global: mutationEvent.id, client: EventId.clientDefault },
190
191
  parentId: { global: mutationEvent.parentId, client: EventId.clientDefault },
191
- sessionId: undefined,
192
192
  })
193
193
 
194
194
  toGlobal = (): AnyEncodedGlobal => ({
@@ -203,6 +203,6 @@ export const isEqualEncoded = (a: AnyEncoded, b: AnyEncoded) =>
203
203
  a.id.client === b.id.client &&
204
204
  a.mutation === b.mutation &&
205
205
  a.clientId === b.clientId &&
206
- // a.sessionId === b.sessionId &&
206
+ a.sessionId === b.sessionId &&
207
207
  // TODO use schema equality here
208
208
  JSON.stringify(a.args) === JSON.stringify(b.args)
@@ -52,8 +52,13 @@ export type AnyIfConstained<In, Out> = '__constrained' extends keyof In ? any :
52
52
  export type EmptyObjIfConstained<In> = '__constrained' extends keyof In ? {} : In
53
53
 
54
54
  export type StructSchemaForColumns<TCols extends ConstraintColumns> = Schema.Schema<
55
- AnyIfConstained<TCols, { readonly [K in keyof TCols]: TCols[K]['schema']['Type'] }>,
56
- AnyIfConstained<TCols, { readonly [K in keyof TCols]: TCols[K]['schema']['Encoded'] }>
55
+ AnyIfConstained<TCols, FromColumns.RowDecoded<TCols>>,
56
+ AnyIfConstained<TCols, FromColumns.RowEncoded<TCols>>
57
+ >
58
+
59
+ export type InsertStructSchemaForColumns<TCols extends ConstraintColumns> = Schema.Schema<
60
+ AnyIfConstained<TCols, FromColumns.InsertRowDecoded<TCols>>,
61
+ AnyIfConstained<TCols, FromColumns.InsertRowEncoded<TCols>>
57
62
  >
58
63
 
59
64
  export const structSchemaForTable = <TTableDefinition extends TableDefinition<any, any>>(
@@ -63,6 +68,20 @@ export const structSchemaForTable = <TTableDefinition extends TableDefinition<an
63
68
  title: tableDef.name,
64
69
  }) as any
65
70
 
71
+ export const insertStructSchemaForTable = <TTableDefinition extends TableDefinition<any, any>>(
72
+ tableDef: TTableDefinition,
73
+ ): InsertStructSchemaForColumns<TTableDefinition['columns']> =>
74
+ Schema.Struct(
75
+ Object.fromEntries(
76
+ tableDef.ast.columns.map((column) => [
77
+ column.name,
78
+ column.nullable === true || column.default._tag === 'Some' ? Schema.optional(column.schema) : column.schema,
79
+ ]),
80
+ ),
81
+ ).annotations({
82
+ title: tableDef.name,
83
+ }) as any
84
+
66
85
  const columsToAst = (columns: Columns): ReadonlyArray<SqliteAst.Column> => {
67
86
  return Object.entries(columns).map(([name, column]) => {
68
87
  return {
@@ -161,6 +180,10 @@ export namespace FromColumns {
161
180
  readonly [K in keyof TColumns]: Schema.Schema.Type<TColumns[K]['schema']>
162
181
  }
163
182
 
183
+ export type RowEncodedAll<TColumns extends Columns> = {
184
+ readonly [K in keyof TColumns]: Schema.Schema.Encoded<TColumns[K]['schema']>
185
+ }
186
+
164
187
  export type RowEncoded<TColumns extends Columns> = Types.Simplify<
165
188
  Nullable<Pick<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>> &
166
189
  Omit<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>
@@ -192,4 +215,9 @@ export namespace FromColumns {
192
215
  Pick<RowDecodedAll<TColumns>, RequiredInsertColumnNames<TColumns>> &
193
216
  Partial<Omit<RowDecodedAll<TColumns>, RequiredInsertColumnNames<TColumns>>>
194
217
  >
218
+
219
+ export type InsertRowEncoded<TColumns extends Columns> = Types.Simplify<
220
+ Pick<RowEncodedAll<TColumns>, RequiredInsertColumnNames<TColumns>> &
221
+ Partial<Omit<RowEncodedAll<TColumns>, RequiredInsertColumnNames<TColumns>>>
222
+ >
195
223
  }
@@ -1,5 +1,6 @@
1
1
  import { Schema } from '@livestore/utils/effect'
2
2
 
3
+ import type { QueryBuilder } from '../query-builder/mod.js'
3
4
  import type { BindValues } from '../sql-queries/sql-queries.js'
4
5
 
5
6
  export type MutationDefMap = {
@@ -20,7 +21,10 @@ export type InternalMutationSchema<TRecord extends MutationDefRecord = MutationD
20
21
 
21
22
  export type MutationDefSqlResult<TTo> =
22
23
  | SingleOrReadonlyArray<string>
23
- | ((args: TTo) => SingleOrReadonlyArray<
24
+ | ((
25
+ args: TTo,
26
+ context: { currentFacts: MutationEventFacts; clientOnly: boolean },
27
+ ) => SingleOrReadonlyArray<
24
28
  | string
25
29
  | {
26
30
  sql: string
@@ -28,8 +32,15 @@ export type MutationDefSqlResult<TTo> =
28
32
  bindValues: BindValues
29
33
  writeTables?: ReadonlySet<string>
30
34
  }
35
+ | QueryBuilder.Any
31
36
  >)
32
37
 
38
+ export type MutationHandlerResult = {
39
+ sql: string
40
+ bindValues: BindValues
41
+ writeTables?: ReadonlySet<string>
42
+ }
43
+
33
44
  export type SingleOrReadonlyArray<T> = T | ReadonlyArray<T>
34
45
 
35
46
  export type MutationDef<TName extends string, TFrom, TTo> = {
@@ -79,8 +79,7 @@ export const mutationLogMetaTable = table(
79
79
  mutation: SqliteDsl.text({}),
80
80
  argsJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Any) }),
81
81
  clientId: SqliteDsl.text({}),
82
- /** Only available for mutations which were executed in this client */
83
- sessionId: SqliteDsl.text({ nullable: true }),
82
+ sessionId: SqliteDsl.text({}),
84
83
  schemaHash: SqliteDsl.integer({}),
85
84
  syncMetadataJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Option(Schema.JsonValue)) }),
86
85
  },
@@ -19,12 +19,12 @@ export type DefaultSqliteTableDefConstrained = SqliteDsl.TableDefinition<string,
19
19
  export type TableDefBase<
20
20
  TSqliteDef extends DefaultSqliteTableDef = DefaultSqliteTableDefConstrained,
21
21
  TOptions extends TableOptions = TableOptions,
22
- TSchema = SqliteDsl.StructSchemaForColumns<TSqliteDef['columns']>,
23
22
  > = {
24
23
  sqliteDef: TSqliteDef
25
24
  options: TOptions
26
25
  // Derived from `sqliteDef`, so only exposed for convenience
27
- schema: TSchema
26
+ schema: SqliteDsl.StructSchemaForColumns<TSqliteDef['columns']>
27
+ insertSchema: SqliteDsl.InsertStructSchemaForColumns<TSqliteDef['columns']>
28
28
  }
29
29
 
30
30
  export type TableDef<
@@ -47,7 +47,10 @@ export type TableDef<
47
47
  options: TOptions
48
48
  // Derived from `sqliteDef`, so only exposed for convenience
49
49
  schema: TSchema
50
- query: QueryBuilder<ReadonlyArray<Schema.Schema.Type<TSchema>>, TableDef<TSqliteDef & {}, TOptions>>
50
+ insertSchema: SqliteDsl.InsertStructSchemaForColumns<TSqliteDef['columns']>
51
+ query: QueryBuilder<ReadonlyArray<Schema.Schema.Type<TSchema>>, TableDefBase<TSqliteDef & {}, TOptions>>
52
+ readonly Type: Schema.Schema.Type<TSchema>
53
+ readonly Encoded: Schema.Schema.Encoded<TSchema>
51
54
  } & (TOptions['deriveMutations']['enabled'] extends true
52
55
  ? DerivedMutationHelperFns<TSqliteDef['columns'], TOptions>
53
56
  : {})
@@ -195,7 +198,14 @@ export const table = <
195
198
  const isSingleColumn = SqliteDsl.isColumnDefinition(columnOrColumns) === true
196
199
 
197
200
  const schema = SqliteDsl.structSchemaForTable(sqliteDef)
198
- const tableDef = { sqliteDef, options: options_, schema } satisfies TableDefBase
201
+ const insertSchema = SqliteDsl.insertStructSchemaForTable(sqliteDef)
202
+ const tableDef = {
203
+ sqliteDef,
204
+ options: options_,
205
+ schema,
206
+ insertSchema,
207
+ } satisfies TableDefBase
208
+
199
209
  const query = makeQueryBuilder(tableDef)
200
210
  // const tableDef = { ...tableDefBase, query } satisfies TableDef
201
211
 
@@ -51,7 +51,7 @@ export const rebaseEvents = ({
51
51
  rebaseFn: RebaseFn
52
52
  currentFactsSnapshot: MutationEventFactsSnapshot
53
53
  clientId: string
54
- sessionId: string | undefined
54
+ sessionId: string
55
55
  }): ReadonlyArray<MutationEvent.AnyDecoded> => {
56
56
  const initialSnapshot = new Map(currentFactsSnapshot)
57
57
  applyFactGroups(
package/src/sync/sync.ts CHANGED
@@ -12,14 +12,19 @@ import type * as MutationEvent from '../schema/MutationEvent.js'
12
12
  export type MakeBackendArgs = {
13
13
  storeId: string
14
14
  clientId: string
15
+ payload: Schema.JsonValue | undefined
15
16
  }
16
17
 
17
18
  export type SyncOptions = {
18
- makeBackend?: (args: MakeBackendArgs) => Effect.Effect<SyncBackend<any>, UnexpectedError, Scope.Scope>
19
+ backend?: SyncBackendConstructor<any>
19
20
  /** @default { _tag: 'Skip' } */
20
21
  initialSyncOptions?: InitialSyncOptions
21
22
  }
22
23
 
24
+ export type SyncBackendConstructor<TSyncMetadata = Schema.JsonValue> = (
25
+ args: MakeBackendArgs,
26
+ ) => Effect.Effect<SyncBackend<TSyncMetadata>, UnexpectedError, Scope.Scope | HttpClient.HttpClient>
27
+
23
28
  export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
24
29
  pull: (
25
30
  args: Option.Option<{
@@ -54,6 +59,10 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
54
59
  HttpClient.HttpClient
55
60
  >
56
61
  isConnected: SubscriptionRef.SubscriptionRef<boolean>
62
+ /**
63
+ * Metadata describing the sync backend.
64
+ */
65
+ metadata: { name: string; description: string } & Record<string, Schema.JsonValue>
57
66
  }
58
67
 
59
68
  export class IsOfflineError extends Schema.TaggedError<IsOfflineError>()('IsOfflineError', {}) {}
@@ -19,7 +19,7 @@ class TestEvent extends MutationEvent.EncodedWithMeta {
19
19
  args: payload,
20
20
 
21
21
  clientId: 'static-local-id',
22
- sessionId: undefined,
22
+ sessionId: 'static-session-id',
23
23
  })
24
24
  }
25
25
 
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.0-dev.22' as const
5
+ export const liveStoreVersion = '0.3.0-dev.24' as const
6
6
 
7
7
  /**
8
8
  * This version number is incremented whenever the internal storage format changes in a breaking way.
package/tmp/pack.tgz CHANGED
Binary file