@livestore/common 0.0.58-dev.1 → 0.0.58-dev.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/adapter-types.d.ts +48 -6
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +16 -1
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.js.map +1 -1
- package/dist/derived-mutations.d.ts +5 -5
- package/dist/derived-mutations.d.ts.map +1 -1
- package/dist/derived-mutations.js +4 -2
- package/dist/derived-mutations.js.map +1 -1
- package/dist/derived-mutations.test.js +1 -0
- package/dist/derived-mutations.test.js.map +1 -1
- package/dist/devtools/devtools-bridge.d.ts +1 -1
- package/dist/devtools/devtools-bridge.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.d.ts +91 -13
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +13 -4
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/index.d.ts +1 -0
- package/dist/devtools/index.d.ts.map +1 -1
- package/dist/devtools/index.js +2 -0
- package/dist/devtools/index.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +11 -5
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/mutations.d.ts +137 -17
- package/dist/schema/mutations.d.ts.map +1 -1
- package/dist/schema/mutations.js +42 -16
- package/dist/schema/mutations.js.map +1 -1
- package/dist/schema/schema-helpers.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/system-tables.d.ts +119 -6
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +22 -9
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +3 -3
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +1 -1
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +1 -1
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +2 -2
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +10 -3
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js +8 -7
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/types.d.ts +2 -2
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sync/next/compact-events.d.ts +15 -0
- package/dist/sync/next/compact-events.d.ts.map +1 -0
- package/dist/sync/next/compact-events.js +176 -0
- package/dist/sync/next/compact-events.js.map +1 -0
- package/dist/sync/next/facts.d.ts +37 -0
- package/dist/sync/next/facts.d.ts.map +1 -0
- package/dist/sync/next/facts.js +156 -0
- package/dist/sync/next/facts.js.map +1 -0
- package/dist/sync/next/graphology.d.ts +8 -0
- package/dist/sync/next/graphology.d.ts.map +1 -0
- package/dist/sync/next/graphology.js +36 -0
- package/dist/sync/next/graphology.js.map +1 -0
- package/dist/sync/next/graphology_.d.ts +3 -0
- package/dist/sync/next/graphology_.d.ts.map +1 -0
- package/dist/sync/next/graphology_.js +3 -0
- package/dist/sync/next/graphology_.js.map +1 -0
- package/dist/sync/next/history-dag.d.ts +30 -0
- package/dist/sync/next/history-dag.d.ts.map +1 -0
- package/dist/sync/next/history-dag.js +69 -0
- package/dist/sync/next/history-dag.js.map +1 -0
- package/dist/sync/next/mod.d.ts +5 -0
- package/dist/sync/next/mod.d.ts.map +1 -0
- package/dist/sync/next/mod.js +5 -0
- package/dist/sync/next/mod.js.map +1 -0
- package/dist/sync/next/rebase-events.d.ts +27 -0
- package/dist/sync/next/rebase-events.d.ts.map +1 -0
- package/dist/sync/next/rebase-events.js +41 -0
- package/dist/sync/next/rebase-events.js.map +1 -0
- package/dist/sync/next/test/compact-events.calculator.test.d.ts +2 -0
- package/dist/sync/next/test/compact-events.calculator.test.d.ts.map +1 -0
- package/dist/sync/next/test/compact-events.calculator.test.js +101 -0
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -0
- package/dist/sync/next/test/compact-events.test.d.ts +2 -0
- package/dist/sync/next/test/compact-events.test.d.ts.map +1 -0
- package/dist/sync/next/test/compact-events.test.js +201 -0
- package/dist/sync/next/test/compact-events.test.js.map +1 -0
- package/dist/sync/next/test/mod.d.ts +2 -0
- package/dist/sync/next/test/mod.d.ts.map +1 -0
- package/dist/sync/next/test/mod.js +2 -0
- package/dist/sync/next/test/mod.js.map +1 -0
- package/dist/sync/next/test/mutation-fixtures.d.ts +73 -0
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -0
- package/dist/sync/next/test/mutation-fixtures.js +161 -0
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -0
- package/dist/sync/sync.d.ts +19 -6
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/version.d.ts +8 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -1
- package/package.json +21 -4
- package/src/adapter-types.ts +46 -7
- package/src/bounded-collections.ts +1 -1
- package/src/derived-mutations.test.ts +2 -1
- package/src/derived-mutations.ts +10 -10
- package/src/devtools/devtools-bridge.ts +1 -1
- package/src/devtools/devtools-messages.ts +12 -2
- package/src/devtools/index.ts +2 -0
- package/src/index.ts +6 -0
- package/src/rehydrate-from-mutationlog.ts +16 -7
- package/src/schema/index.ts +4 -3
- package/src/schema/mutations.ts +175 -30
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/system-tables.ts +30 -9
- package/src/schema/table-def.ts +3 -3
- package/src/schema-management/migrations.ts +2 -2
- package/src/sql-queries/sql-queries.ts +21 -10
- package/src/sql-queries/sql-query-builder.ts +1 -1
- package/src/sql-queries/types.ts +2 -2
- package/src/sync/next/ambient.d.ts +3 -0
- package/src/sync/next/compact-events.ts +218 -0
- package/src/sync/next/facts.ts +229 -0
- package/src/sync/next/graphology.ts +49 -0
- package/src/sync/next/graphology_.ts +2 -0
- package/src/sync/next/history-dag.ts +109 -0
- package/src/sync/next/mod.ts +4 -0
- package/src/sync/next/rebase-events.ts +97 -0
- package/src/sync/next/test/compact-events.calculator.test.ts +121 -0
- package/src/sync/next/test/compact-events.test.ts +232 -0
- package/src/sync/next/test/mod.ts +1 -0
- package/src/sync/next/test/mutation-fixtures.ts +230 -0
- package/src/sync/sync.ts +30 -6
- package/src/version.ts +10 -0
- package/tsconfig.json +1 -1
package/src/schema/index.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
import type { SqliteDsl } from '@livestore/db-schema'
|
2
|
+
import { SqliteAst } from '@livestore/db-schema'
|
1
3
|
import { isReadonlyArray, shouldNeverHappen } from '@livestore/utils'
|
2
|
-
import type { SqliteDsl } from 'effect-db-schema'
|
3
|
-
import { SqliteAst } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import type { MigrationOptions } from '../adapter-types.js'
|
6
6
|
import { makeDerivedMutationDefsForTable } from '../derived-mutations.js'
|
@@ -46,6 +46,7 @@ export type InputSchema = {
|
|
46
46
|
/**
|
47
47
|
* Can be used to isolate multiple LiveStore apps running in the same origin
|
48
48
|
*/
|
49
|
+
// TODO remove this in favour of storeId
|
49
50
|
readonly key?: string
|
50
51
|
}
|
51
52
|
|
@@ -116,7 +117,7 @@ export const makeSchema = <TInputSchema extends InputSchema>(
|
|
116
117
|
} satisfies LiveStoreSchema
|
117
118
|
}
|
118
119
|
|
119
|
-
namespace FromInputSchema {
|
120
|
+
export namespace FromInputSchema {
|
120
121
|
export type DeriveSchema<TInputSchema extends InputSchema> = LiveStoreSchema<
|
121
122
|
DbSchemaFromInputSchemaTables<TInputSchema['tables']>,
|
122
123
|
MutationDefRecordFromInputSchemaMutations<TInputSchema['mutations']>
|
package/src/schema/mutations.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { memoizeByRef } from '@livestore/utils'
|
2
|
-
import { cuid } from '@livestore/utils/cuid'
|
3
2
|
import { Schema } from '@livestore/utils/effect'
|
4
3
|
|
4
|
+
import { EventId } from '../adapter-types.js'
|
5
5
|
import type { BindValues } from '../sql-queries/sql-queries.js'
|
6
6
|
import type { LiveStoreSchema } from './index.js'
|
7
7
|
|
@@ -35,42 +35,131 @@ export type SingleOrReadonlyArray<T> = T | ReadonlyArray<T>
|
|
35
35
|
export type MutationDef<TName extends string, TFrom, TTo> = {
|
36
36
|
name: TName
|
37
37
|
schema: Schema.Schema<TTo, TFrom>
|
38
|
-
sql: MutationDefSqlResult<TTo
|
38
|
+
sql: MutationDefSqlResult<NoInfer<TTo>>
|
39
39
|
options: {
|
40
|
+
/** Warning: This feature is not fully implemented yet */
|
41
|
+
historyId: string
|
40
42
|
/**
|
41
43
|
* When set to true, the mutation won't be synced over the network
|
42
44
|
*/
|
43
45
|
localOnly: boolean
|
46
|
+
/** Warning: This feature is not fully implemented yet */
|
47
|
+
facts: FactsCallback<TTo> | undefined
|
44
48
|
}
|
45
49
|
|
46
|
-
/** Helper function to construct mutation event */
|
47
|
-
(
|
50
|
+
/** Helper function to construct a partial mutation event */
|
51
|
+
(
|
52
|
+
args: TTo,
|
53
|
+
options?: {
|
54
|
+
id?: number
|
55
|
+
},
|
56
|
+
): {
|
57
|
+
mutation: TName
|
58
|
+
args: TTo
|
59
|
+
// TODO remove/clean up after sync-next is fully implemented
|
60
|
+
id?: EventId
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
export type FactsCallback<TTo> = (
|
65
|
+
args: TTo,
|
66
|
+
currentFacts: MutationEventFacts,
|
67
|
+
) => {
|
68
|
+
modify: {
|
69
|
+
set: Iterable<MutationEventFactInput>
|
70
|
+
unset: Iterable<MutationEventFactInput>
|
71
|
+
}
|
72
|
+
require: Iterable<MutationEventFactInput>
|
48
73
|
}
|
49
74
|
|
50
75
|
export namespace MutationDef {
|
51
76
|
export type Any = MutationDef<string, any, any>
|
52
77
|
}
|
53
78
|
|
79
|
+
export type MutationEventKey = string
|
80
|
+
export type MutationEventFact = string
|
81
|
+
export type MutationEventFacts = ReadonlyMap<string, any>
|
82
|
+
|
83
|
+
export type MutationEventFactsGroup = {
|
84
|
+
modifySet: MutationEventFacts
|
85
|
+
modifyUnset: MutationEventFacts
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Events on independent "dependency" branches are commutative which can facilitate more prioritized syncing
|
89
|
+
*/
|
90
|
+
depRequire: MutationEventFacts
|
91
|
+
depRead: MutationEventFacts
|
92
|
+
}
|
93
|
+
|
94
|
+
export type MutationEventFactsSnapshot = Map<string, any>
|
95
|
+
|
96
|
+
export type MutationEventFactInput = string | readonly [string, any]
|
97
|
+
|
98
|
+
export const defineFacts = <
|
99
|
+
TRecord extends Record<string, MutationEventFactInput | ((...args: any[]) => MutationEventFactInput)>,
|
100
|
+
>(
|
101
|
+
record: TRecord,
|
102
|
+
): TRecord => record
|
103
|
+
|
104
|
+
export type DefineMutationOptions<TTo> = {
|
105
|
+
historyId?: string
|
106
|
+
/** Warning: This feature is not fully implemented yet */
|
107
|
+
facts?: (
|
108
|
+
args: TTo,
|
109
|
+
currentFacts: MutationEventFacts,
|
110
|
+
) => {
|
111
|
+
modify?: {
|
112
|
+
set?: Iterable<MutationEventFactInput>
|
113
|
+
unset?: Iterable<MutationEventFactInput>
|
114
|
+
}
|
115
|
+
/**
|
116
|
+
* Two purposes: constrain history and constrain compaction
|
117
|
+
*/
|
118
|
+
require?: Iterable<MutationEventFactInput>
|
119
|
+
}
|
120
|
+
/**
|
121
|
+
* When set to true, the mutation won't be synced over the network
|
122
|
+
*/
|
123
|
+
localOnly?: boolean
|
124
|
+
}
|
125
|
+
|
54
126
|
// TODO possibly also allow for mutation event subsumption behaviour
|
55
127
|
export const defineMutation = <TName extends string, TFrom, TTo>(
|
56
128
|
name: TName,
|
57
129
|
schema: Schema.Schema<TTo, TFrom>,
|
58
|
-
sql: MutationDefSqlResult<TTo
|
59
|
-
options?:
|
60
|
-
/**
|
61
|
-
* When set to true, the mutation won't be synced over the network
|
62
|
-
*/
|
63
|
-
localOnly?: boolean
|
64
|
-
},
|
130
|
+
sql: MutationDefSqlResult<NoInfer<TTo>>,
|
131
|
+
options?: DefineMutationOptions<TTo>,
|
65
132
|
): MutationDef<TName, TFrom, TTo> => {
|
66
|
-
const
|
133
|
+
const makePartialEvent = (
|
134
|
+
args: TTo,
|
135
|
+
options?: {
|
136
|
+
id?: EventId
|
137
|
+
},
|
138
|
+
) => ({ mutation: name, args, ...options })
|
67
139
|
|
68
|
-
Object.defineProperty(
|
69
|
-
Object.defineProperty(
|
70
|
-
Object.defineProperty(
|
71
|
-
Object.defineProperty(
|
140
|
+
Object.defineProperty(makePartialEvent, 'name', { value: name })
|
141
|
+
Object.defineProperty(makePartialEvent, 'schema', { value: schema })
|
142
|
+
Object.defineProperty(makePartialEvent, 'sql', { value: sql })
|
143
|
+
Object.defineProperty(makePartialEvent, 'options', {
|
144
|
+
value: {
|
145
|
+
historyId: options?.historyId ?? 'main',
|
146
|
+
localOnly: options?.localOnly ?? false,
|
147
|
+
facts: options?.facts
|
148
|
+
? (args, currentFacts) => {
|
149
|
+
const res = options.facts!(args, currentFacts)
|
150
|
+
return {
|
151
|
+
modify: {
|
152
|
+
set: res.modify?.set ? new Set(res.modify.set) : new Set(),
|
153
|
+
unset: res.modify?.unset ? new Set(res.modify.unset) : new Set(),
|
154
|
+
},
|
155
|
+
require: res.require ? new Set(res.require) : new Set(),
|
156
|
+
}
|
157
|
+
}
|
158
|
+
: undefined,
|
159
|
+
} satisfies MutationDef.Any['options'],
|
160
|
+
})
|
72
161
|
|
73
|
-
return
|
162
|
+
return makePartialEvent as MutationDef<TName, TFrom, TTo>
|
74
163
|
}
|
75
164
|
|
76
165
|
export const makeMutationDefRecord = <TInputRecord extends Record<string, MutationDef.Any>>(
|
@@ -102,40 +191,80 @@ export const rawSqlMutation = defineMutation(
|
|
102
191
|
export type RawSqlMutation = typeof rawSqlMutation
|
103
192
|
export type RawSqlMutationEvent = ReturnType<typeof rawSqlMutation>
|
104
193
|
|
194
|
+
export type MutationEventPartial<TMutationsDef extends MutationDef.Any> = {
|
195
|
+
mutation: TMutationsDef['name']
|
196
|
+
args: Schema.Schema.Type<TMutationsDef['schema']>
|
197
|
+
}
|
198
|
+
|
199
|
+
export type MutationEventPartialEncoded<TMutationsDef extends MutationDef.Any> = {
|
200
|
+
mutation: TMutationsDef['name']
|
201
|
+
args: Schema.Schema.Encoded<TMutationsDef['schema']>
|
202
|
+
}
|
203
|
+
|
105
204
|
export type MutationEvent<TMutationsDef extends MutationDef.Any> = {
|
106
205
|
mutation: TMutationsDef['name']
|
107
206
|
args: Schema.Schema.Type<TMutationsDef['schema']>
|
108
|
-
id:
|
207
|
+
id: EventId
|
208
|
+
parentId: EventId
|
109
209
|
}
|
110
210
|
|
111
211
|
export type MutationEventEncoded<TMutationsDef extends MutationDef.Any> = {
|
112
212
|
mutation: TMutationsDef['name']
|
113
213
|
args: Schema.Schema.Encoded<TMutationsDef['schema']>
|
114
|
-
id:
|
214
|
+
id: EventId
|
215
|
+
parentId: EventId
|
115
216
|
}
|
116
217
|
|
117
218
|
export namespace MutationEvent {
|
118
219
|
export type Any = MutationEvent<MutationDef.Any>
|
119
220
|
export type AnyEncoded = MutationEventEncoded<MutationDef.Any>
|
120
221
|
|
222
|
+
export type PartialAny = MutationEventPartial<MutationDef.Any>
|
223
|
+
export type PartialAnyEncoded = MutationEventPartialEncoded<MutationDef.Any>
|
224
|
+
|
225
|
+
export type PartialForSchema<TSchema extends LiveStoreSchema> = {
|
226
|
+
[K in keyof TSchema['_MutationDefMapType']]: MutationEventPartial<TSchema['_MutationDefMapType'][K]>
|
227
|
+
}[keyof TSchema['_MutationDefMapType']]
|
228
|
+
|
121
229
|
export type ForSchema<TSchema extends LiveStoreSchema> = {
|
122
230
|
[K in keyof TSchema['_MutationDefMapType']]: MutationEvent<TSchema['_MutationDefMapType'][K]>
|
123
231
|
}[keyof TSchema['_MutationDefMapType']]
|
124
232
|
}
|
125
233
|
|
234
|
+
export const isPartialMutationEvent = (
|
235
|
+
mutationEvent: MutationEvent.Any | MutationEvent.PartialAny,
|
236
|
+
): mutationEvent is MutationEvent.PartialAny => 'id' in mutationEvent === false && 'parentId' in mutationEvent === false
|
237
|
+
|
126
238
|
export type MutationEventSchema<TMutationsDefRecord extends MutationDefRecord> = Schema.Schema<
|
127
239
|
{
|
128
240
|
[K in keyof TMutationsDefRecord]: {
|
129
241
|
mutation: K
|
130
242
|
args: Schema.Schema.Type<TMutationsDefRecord[K]['schema']>
|
131
|
-
id:
|
243
|
+
id: EventId
|
244
|
+
parentId: EventId
|
245
|
+
}
|
246
|
+
}[keyof TMutationsDefRecord],
|
247
|
+
{
|
248
|
+
[K in keyof TMutationsDefRecord]: {
|
249
|
+
mutation: K
|
250
|
+
args: Schema.Schema.Encoded<TMutationsDefRecord[K]['schema']>
|
251
|
+
id: EventId
|
252
|
+
parentId: EventId
|
253
|
+
}
|
254
|
+
}[keyof TMutationsDefRecord]
|
255
|
+
>
|
256
|
+
|
257
|
+
export type MutationEventPartialSchema<TMutationsDefRecord extends MutationDefRecord> = Schema.Schema<
|
258
|
+
{
|
259
|
+
[K in keyof TMutationsDefRecord]: {
|
260
|
+
mutation: K
|
261
|
+
args: Schema.Schema.Type<TMutationsDefRecord[K]['schema']>
|
132
262
|
}
|
133
263
|
}[keyof TMutationsDefRecord],
|
134
264
|
{
|
135
265
|
[K in keyof TMutationsDefRecord]: {
|
136
266
|
mutation: K
|
137
267
|
args: Schema.Schema.Encoded<TMutationsDefRecord[K]['schema']>
|
138
|
-
id: string
|
139
268
|
}
|
140
269
|
}[keyof TMutationsDefRecord]
|
141
270
|
>
|
@@ -148,21 +277,37 @@ export const makeMutationEventSchema = <TSchema extends LiveStoreSchema>(
|
|
148
277
|
Schema.Struct({
|
149
278
|
mutation: Schema.Literal(def.name),
|
150
279
|
args: def.schema,
|
151
|
-
id:
|
280
|
+
id: EventId,
|
281
|
+
parentId: EventId,
|
152
282
|
}),
|
153
283
|
),
|
154
284
|
).annotations({ title: 'MutationEventSchema' }) as any
|
155
285
|
|
286
|
+
export const makeMutationEventPartialSchema = <TSchema extends LiveStoreSchema>(
|
287
|
+
schema: TSchema,
|
288
|
+
): MutationEventPartialSchema<TSchema['_MutationDefMapType']> =>
|
289
|
+
Schema.Union(
|
290
|
+
...[...schema.mutations.values()].map((def) =>
|
291
|
+
Schema.Struct({
|
292
|
+
mutation: Schema.Literal(def.name),
|
293
|
+
args: def.schema,
|
294
|
+
}),
|
295
|
+
),
|
296
|
+
).annotations({ title: 'MutationEventSchemaPartial' }) as any
|
297
|
+
|
156
298
|
export const makeMutationEventSchemaMemo = memoizeByRef(makeMutationEventSchema)
|
157
299
|
|
158
|
-
export const
|
300
|
+
export const mutationEventSchemaAny = Schema.Struct({
|
159
301
|
mutation: Schema.String,
|
160
302
|
args: Schema.Any,
|
161
|
-
id:
|
162
|
-
|
303
|
+
id: EventId,
|
304
|
+
parentId: EventId,
|
305
|
+
}).annotations({ title: 'MutationEventSchema.Any' })
|
163
306
|
|
164
|
-
export const
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
307
|
+
export const mutationEventSchemaDecodedAny = Schema.typeSchema(mutationEventSchemaAny).annotations({
|
308
|
+
title: 'MutationEventSchema.DecodedAny',
|
309
|
+
})
|
310
|
+
|
311
|
+
export const mutationEventSchemaEncodedAny = Schema.encodedSchema(mutationEventSchemaAny).annotations({
|
312
|
+
title: 'MutationEventSchema.EncodedAny',
|
313
|
+
})
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { shouldNeverHappen } from '@livestore/utils'
|
2
3
|
import { pipe, ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
3
|
-
import { SqliteDsl } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import type { TableDef } from './table-def.js'
|
6
6
|
|
@@ -1,5 +1,5 @@
|
|
1
|
+
import { type SqliteAst as __SqliteAst, SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { Schema } from '@livestore/utils/effect'
|
2
|
-
import { type SqliteAst as __SqliteAst, SqliteDsl } from 'effect-db-schema'
|
3
3
|
|
4
4
|
import type { FromTable } from './table-def.js'
|
5
5
|
import { table } from './table-def.js'
|
@@ -36,7 +36,25 @@ export const schemaMutationsMetaTable = table(
|
|
36
36
|
|
37
37
|
export type SchemaMutationsMetaRow = FromTable.RowDecoded<typeof schemaMutationsMetaTable>
|
38
38
|
|
39
|
-
|
39
|
+
/**
|
40
|
+
* Table which stores SQLite changeset blobs which is used for rolling back
|
41
|
+
* read-model state during rebasing.
|
42
|
+
*/
|
43
|
+
export const SESSION_CHANGESET_META_TABLE = '__livestore_session_changeset'
|
44
|
+
|
45
|
+
export const sessionChangesetMetaTable = table(
|
46
|
+
SESSION_CHANGESET_META_TABLE,
|
47
|
+
{
|
48
|
+
idGlobal: SqliteDsl.integer({ primaryKey: true }),
|
49
|
+
idLocal: SqliteDsl.integer({ primaryKey: true }),
|
50
|
+
changeset: SqliteDsl.blob({}),
|
51
|
+
},
|
52
|
+
{ disableAutomaticIdColumn: true },
|
53
|
+
)
|
54
|
+
|
55
|
+
export type SessionChangesetMetaRow = FromTable.RowDecoded<typeof sessionChangesetMetaTable>
|
56
|
+
|
57
|
+
export const systemTables = [schemaMetaTable, schemaMutationsMetaTable, sessionChangesetMetaTable]
|
40
58
|
|
41
59
|
/// Mutation log DB
|
42
60
|
|
@@ -48,16 +66,19 @@ export const MUTATION_LOG_META_TABLE = 'mutation_log'
|
|
48
66
|
export const mutationLogMetaTable = table(
|
49
67
|
MUTATION_LOG_META_TABLE,
|
50
68
|
{
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
69
|
+
idGlobal: SqliteDsl.integer({ primaryKey: true }),
|
70
|
+
idLocal: SqliteDsl.integer({ primaryKey: true }),
|
71
|
+
parentIdGlobal: SqliteDsl.integer({}),
|
72
|
+
parentIdLocal: SqliteDsl.integer({}),
|
73
|
+
mutation: SqliteDsl.text({}),
|
74
|
+
argsJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Any) }),
|
75
|
+
schemaHash: SqliteDsl.integer({}),
|
56
76
|
/** ISO date format */
|
57
|
-
createdAt: SqliteDsl.text({
|
77
|
+
createdAt: SqliteDsl.text({}),
|
58
78
|
syncStatus: SqliteDsl.text({ schema: SyncStatus }),
|
79
|
+
syncMetadataJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Option(Schema.JsonValue)) }),
|
59
80
|
},
|
60
|
-
{ disableAutomaticIdColumn: true },
|
81
|
+
{ disableAutomaticIdColumn: true, indexes: [] },
|
61
82
|
)
|
62
83
|
|
63
84
|
export type MutationLogMetaRow = FromTable.RowDecoded<typeof mutationLogMetaTable>
|
package/src/schema/table-def.ts
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
+
import type { Nullable, PrettifyFlat } from '@livestore/db-schema'
|
2
|
+
import { SqliteDsl } from '@livestore/db-schema'
|
1
3
|
import { shouldNeverHappen } from '@livestore/utils'
|
2
4
|
import { ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
3
|
-
import type { Nullable, PrettifyFlat } from 'effect-db-schema'
|
4
|
-
import { SqliteDsl } from 'effect-db-schema'
|
5
5
|
|
6
6
|
import type { DerivedMutationHelperFns } from '../derived-mutations.js'
|
7
7
|
import { makeDerivedMutationDefsForTable } from '../derived-mutations.js'
|
8
8
|
|
9
9
|
export const { blob, boolean, column, datetime, integer, isColumnDefinition, json, real, text } = SqliteDsl
|
10
10
|
|
11
|
-
export { type SqliteDsl } from '
|
11
|
+
export { type SqliteDsl } from '@livestore/db-schema'
|
12
12
|
|
13
13
|
export type StateType = 'singleton' | 'dynamic'
|
14
14
|
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { SqliteAst, SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { memoizeByStringifyArgs } from '@livestore/utils'
|
2
3
|
import { Effect, Schema as EffectSchema } from '@livestore/utils/effect'
|
3
|
-
import { SqliteAst, SqliteDsl } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import type { SynchronousDatabase } from '../adapter-types.js'
|
6
6
|
import type { LiveStoreSchema } from '../schema/index.js'
|
@@ -155,7 +155,7 @@ export const migrateTable = ({
|
|
155
155
|
|
156
156
|
const createIndexFromDefinition = (tableName: string, index: SqliteAst.Index) => {
|
157
157
|
const uniqueStr = index.unique ? 'UNIQUE' : ''
|
158
|
-
return sql`create ${uniqueStr} index ${index.name} on ${tableName} (${index.columns.join(', ')})`
|
158
|
+
return sql`create ${uniqueStr} index if not exists ${index.name} on ${tableName} (${index.columns.join(', ')})`
|
159
159
|
}
|
160
160
|
|
161
161
|
export const makeColumnSpec = (tableAst: SqliteAst.Table) => {
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import type { SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { shouldNeverHappen } from '@livestore/utils'
|
2
3
|
import { pipe, ReadonlyArray, Schema, TreeFormatter } from '@livestore/utils/effect'
|
3
|
-
import type { SqliteDsl } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import { sql } from '../util.js'
|
6
6
|
import { objectEntries } from './misc.js'
|
@@ -58,15 +58,26 @@ export const insertRow = <TColumns extends SqliteDsl.Columns>({
|
|
58
58
|
values: ClientTypes.DecodedValuesForColumns<TColumns>
|
59
59
|
options?: { orReplace: boolean }
|
60
60
|
}): [string, BindValues] => {
|
61
|
-
const
|
62
|
-
|
63
|
-
|
61
|
+
const stmt = insertRowPrepared({ tableName, columns, options })
|
62
|
+
|
63
|
+
return [stmt, makeBindValues({ columns, values })]
|
64
|
+
}
|
65
|
+
|
66
|
+
export const insertRowPrepared = <TColumns extends SqliteDsl.Columns>({
|
67
|
+
tableName,
|
68
|
+
columns,
|
69
|
+
options = { orReplace: false },
|
70
|
+
}: {
|
71
|
+
tableName: string
|
72
|
+
columns: TColumns
|
73
|
+
options?: { orReplace: boolean }
|
74
|
+
}): string => {
|
75
|
+
const keysStr = Object.keys(columns).join(', ')
|
76
|
+
const valuesStr = Object.keys(columns)
|
77
|
+
.map((key) => `$${key}`)
|
64
78
|
.join(', ')
|
65
79
|
|
66
|
-
return
|
67
|
-
sql`INSERT ${options.orReplace ? 'OR REPLACE ' : ''}INTO ${tableName} (${keysStr}) VALUES (${valuesStr})`,
|
68
|
-
makeBindValues({ columns, values }),
|
69
|
-
]
|
80
|
+
return sql`INSERT ${options.orReplace ? 'OR REPLACE ' : ''}INTO ${tableName} (${keysStr}) VALUES (${valuesStr})`
|
70
81
|
}
|
71
82
|
|
72
83
|
export const insertRows = <TColumns extends SqliteDsl.Columns>({
|
@@ -243,14 +254,14 @@ export const createTable = ({
|
|
243
254
|
return sql`CREATE TABLE ${tableName} (${columnDefStrs.join(', ')});`
|
244
255
|
}
|
245
256
|
|
246
|
-
export const makeBindValues = <TColumns extends SqliteDsl.Columns, TKeys extends
|
257
|
+
export const makeBindValues = <TColumns extends SqliteDsl.Columns, TKeys extends keyof TColumns>({
|
247
258
|
columns,
|
248
259
|
values,
|
249
260
|
variablePrefix = '',
|
250
261
|
skipNil,
|
251
262
|
}: {
|
252
263
|
columns: TColumns
|
253
|
-
values: Record<TKeys, any
|
264
|
+
values: Partial<Record<TKeys, any>>
|
254
265
|
variablePrefix?: string
|
255
266
|
/** So far only used to prepare `where` statements */
|
256
267
|
skipNil?: boolean
|
package/src/sql-queries/types.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
import type { Prettify, SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import type { Schema } from '@livestore/utils/effect'
|
2
|
-
import type { Prettify, SqliteDsl } from 'effect-db-schema'
|
3
3
|
|
4
4
|
export type DecodedValuesForTableAll<TSchema extends SqliteDsl.DbSchema, TTableName extends keyof TSchema> = {
|
5
5
|
[K in keyof GetColumns<TSchema, TTableName>]: Schema.Schema.Type<GetColumn<TSchema, TTableName, K>['schema']>
|
@@ -89,7 +89,7 @@ export type WhereValuesForColumns<TColumns extends SqliteDsl.Columns> = PartialO
|
|
89
89
|
}>
|
90
90
|
|
91
91
|
export type GetNullableColumnNames<TColumns extends SqliteDsl.Columns> = keyof {
|
92
|
-
[K in keyof TColumns as TColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]:
|
92
|
+
[K in keyof TColumns as TColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: unknown
|
93
93
|
}
|
94
94
|
|
95
95
|
export type PartialOrNull<T> = { [P in keyof T]?: T[P] | null }
|