@livestore/livestore 0.0.47 → 0.0.48-dev.1

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 (123) hide show
  1. package/README.md +3 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/MainDatabaseWrapper.d.ts +2 -2
  4. package/dist/MainDatabaseWrapper.d.ts.map +1 -1
  5. package/dist/MainDatabaseWrapper.js.map +1 -1
  6. package/dist/__tests__/react/fixture.d.ts +262 -158
  7. package/dist/__tests__/react/fixture.d.ts.map +1 -1
  8. package/dist/__tests__/react/fixture.js +14 -12
  9. package/dist/__tests__/react/fixture.js.map +1 -1
  10. package/dist/__tests__/react/utils/otel.d.ts +1 -1
  11. package/dist/__tests__/react/utils/otel.d.ts.map +1 -1
  12. package/dist/effect/LiveStore.d.ts +5 -5
  13. package/dist/effect/LiveStore.d.ts.map +1 -1
  14. package/dist/effect/LiveStore.js +5 -4
  15. package/dist/effect/LiveStore.js.map +1 -1
  16. package/dist/index.d.ts +3 -4
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +0 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/react/LiveStoreProvider.d.ts +4 -4
  21. package/dist/react/LiveStoreProvider.d.ts.map +1 -1
  22. package/dist/react/LiveStoreProvider.js +8 -8
  23. package/dist/react/LiveStoreProvider.js.map +1 -1
  24. package/dist/react/LiveStoreProvider.test.js +3 -4
  25. package/dist/react/LiveStoreProvider.test.js.map +1 -1
  26. package/dist/react/index.d.ts +1 -0
  27. package/dist/react/index.d.ts.map +1 -1
  28. package/dist/react/index.js +1 -0
  29. package/dist/react/index.js.map +1 -1
  30. package/dist/react/useAtom.d.ts +5 -2
  31. package/dist/react/useAtom.d.ts.map +1 -1
  32. package/dist/react/useAtom.js +20 -4
  33. package/dist/react/useAtom.js.map +1 -1
  34. package/dist/react/useLocalId.d.ts +10 -0
  35. package/dist/react/useLocalId.d.ts.map +1 -0
  36. package/dist/react/useLocalId.js +20 -0
  37. package/dist/react/useLocalId.js.map +1 -0
  38. package/dist/react/useQuery.test.js +7 -7
  39. package/dist/react/useQuery.test.js.map +1 -1
  40. package/dist/react/useRow.d.ts +3 -1
  41. package/dist/react/useRow.d.ts.map +1 -1
  42. package/dist/react/useRow.js +25 -8
  43. package/dist/react/useRow.js.map +1 -1
  44. package/dist/react/useRow.test.js +58 -29
  45. package/dist/react/useRow.test.js.map +1 -1
  46. package/dist/react/useTemporaryQuery.d.ts +1 -1
  47. package/dist/react/useTemporaryQuery.d.ts.map +1 -1
  48. package/dist/react/useTemporaryQuery.js.map +1 -1
  49. package/dist/react/useTemporaryQuery.test.js +3 -3
  50. package/dist/react/useTemporaryQuery.test.js.map +1 -1
  51. package/dist/react/utils/useStateRefWithReactiveInput.d.ts.map +1 -1
  52. package/dist/reactive.test.js +1 -1
  53. package/dist/reactive.test.js.map +1 -1
  54. package/dist/reactiveQueries/base-class.d.ts +1 -1
  55. package/dist/reactiveQueries/base-class.d.ts.map +1 -1
  56. package/dist/reactiveQueries/base-class.js.map +1 -1
  57. package/dist/reactiveQueries/graphql.d.ts +4 -4
  58. package/dist/reactiveQueries/graphql.d.ts.map +1 -1
  59. package/dist/reactiveQueries/graphql.js +2 -1
  60. package/dist/reactiveQueries/graphql.js.map +1 -1
  61. package/dist/reactiveQueries/js.d.ts +1 -1
  62. package/dist/reactiveQueries/js.d.ts.map +1 -1
  63. package/dist/reactiveQueries/js.js.map +1 -1
  64. package/dist/reactiveQueries/sql.d.ts +1 -1
  65. package/dist/reactiveQueries/sql.d.ts.map +1 -1
  66. package/dist/reactiveQueries/sql.js +2 -2
  67. package/dist/reactiveQueries/sql.js.map +1 -1
  68. package/dist/row-query.d.ts +3 -3
  69. package/dist/row-query.d.ts.map +1 -1
  70. package/dist/row-query.js +47 -34
  71. package/dist/row-query.js.map +1 -1
  72. package/dist/store.d.ts +20 -19
  73. package/dist/store.d.ts.map +1 -1
  74. package/dist/store.js +67 -41
  75. package/dist/store.js.map +1 -1
  76. package/dist/utils/bounded-collections.d.ts +1 -1
  77. package/dist/utils/bounded-collections.d.ts.map +1 -1
  78. package/dist/utils/util.d.ts +0 -1
  79. package/dist/utils/util.d.ts.map +1 -1
  80. package/dist/utils/util.js.map +1 -1
  81. package/package.json +16 -16
  82. package/src/MainDatabaseWrapper.ts +3 -3
  83. package/src/__tests__/react/fixture.tsx +32 -18
  84. package/src/effect/LiveStore.ts +9 -8
  85. package/src/index.ts +7 -5
  86. package/src/react/LiveStoreProvider.test.tsx +5 -5
  87. package/src/react/LiveStoreProvider.tsx +11 -11
  88. package/src/react/index.ts +1 -0
  89. package/src/react/useAtom.ts +31 -5
  90. package/src/react/useLocalId.ts +30 -0
  91. package/src/react/useQuery.test.tsx +8 -8
  92. package/src/react/useRow.test.tsx +60 -35
  93. package/src/react/useRow.ts +43 -12
  94. package/src/react/useTemporaryQuery.test.tsx +4 -4
  95. package/src/react/useTemporaryQuery.ts +1 -1
  96. package/src/reactive.test.ts +1 -1
  97. package/src/reactiveQueries/base-class.ts +1 -1
  98. package/src/reactiveQueries/graphql.ts +3 -2
  99. package/src/reactiveQueries/js.ts +1 -1
  100. package/src/reactiveQueries/sql.ts +3 -3
  101. package/src/row-query.ts +67 -55
  102. package/src/store.ts +89 -59
  103. package/src/utils/util.ts +0 -2
  104. package/dist/cud.d.ts +0 -28
  105. package/dist/cud.d.ts.map +0 -1
  106. package/dist/cud.js +0 -47
  107. package/dist/cud.js.map +0 -1
  108. package/dist/cud.test.d.ts +0 -2
  109. package/dist/cud.test.d.ts.map +0 -1
  110. package/dist/cud.test.js +0 -47
  111. package/dist/cud.test.js.map +0 -1
  112. package/dist/migrations.d.ts +0 -16
  113. package/dist/migrations.d.ts.map +0 -1
  114. package/dist/migrations.js +0 -98
  115. package/dist/migrations.js.map +0 -1
  116. package/dist/query-info.d.ts +0 -48
  117. package/dist/query-info.d.ts.map +0 -1
  118. package/dist/query-info.js +0 -39
  119. package/dist/query-info.js.map +0 -1
  120. package/src/cud.test.ts +0 -52
  121. package/src/cud.ts +0 -88
  122. package/src/migrations.ts +0 -151
  123. package/src/query-info.ts +0 -104
package/src/store.ts CHANGED
@@ -1,13 +1,9 @@
1
- import {
2
- type DatabaseFactory,
3
- type DatabaseImpl,
4
- getExecArgsFromMutation,
5
- type PreparedBindValues,
6
- } from '@livestore/common'
1
+ import type { BootDb, PreparedBindValues, ResetMode, StoreAdapter, StoreAdapterFactory } from '@livestore/common'
2
+ import { getExecArgsFromMutation } from '@livestore/common'
7
3
  import type { LiveStoreSchema, MutationEvent, MutationEventSchema } from '@livestore/common/schema'
8
4
  import { makeMutationEventSchema } from '@livestore/common/schema'
9
5
  import { assertNever, isPromise, makeNoopTracer, shouldNeverHappen } from '@livestore/utils'
10
- import { Schema } from '@livestore/utils/effect'
6
+ import { Effect, Schema, Stream } from '@livestore/utils/effect'
11
7
  import * as otel from '@opentelemetry/api'
12
8
  import type { GraphQLSchema } from 'graphql'
13
9
 
@@ -36,9 +32,7 @@ export type StoreOptions<
36
32
  TGraphQLContext extends BaseGraphQLContext,
37
33
  TSchema extends LiveStoreSchema = LiveStoreSchema,
38
34
  > = {
39
- db: DatabaseImpl
40
- // /** A `Proxy`d version of `db` except that it also mirrors `execute` calls to the storage */
41
- // dbProxy: InMemoryDatabase
35
+ adapter: StoreAdapter
42
36
  schema: TSchema
43
37
  graphQLOptions?: GraphQLOptions<TGraphQLContext>
44
38
  otelTracer: otel.Tracer
@@ -81,13 +75,6 @@ export type StoreOtel = {
81
75
  let storeCount = 0
82
76
  const uniqueStoreId = () => `store-${++storeCount}`
83
77
 
84
- export type BootDb = {
85
- execute(queryStr: string, bindValues?: ParamsObject): void
86
- mutate: <const TMutationArg extends ReadonlyArray<MutationEvent.Any>>(...list: TMutationArg) => void
87
- select<T>(queryStr: string, bindValues?: ParamsObject): ReadonlyArray<T>
88
- txn(callback: () => void): void
89
- }
90
-
91
78
  export class Store<
92
79
  TGraphQLContext extends BaseGraphQLContext = BaseGraphQLContext,
93
80
  TSchema extends LiveStoreSchema = LiveStoreSchema,
@@ -98,7 +85,7 @@ export class Store<
98
85
  // TODO refactor
99
86
  // _proxyDb: InMemoryDatabase
100
87
  // TODO
101
- db: DatabaseImpl
88
+ adapter: StoreAdapter
102
89
  schema: LiveStoreSchema
103
90
  graphQLSchema?: GraphQLSchema
104
91
  graphQLContext?: TGraphQLContext
@@ -109,14 +96,17 @@ export class Store<
109
96
  */
110
97
  tableRefs: { [key: string]: Ref<null, DbContext, RefreshReason> }
111
98
 
99
+ // TODO remove this temporary solution and find a better way to avoid re-processing the same mutation
100
+ __processedMutationIds = new Set<string>()
101
+ __processedMutationWithoutRefreshIds = new Set<string>()
102
+
112
103
  /** RC-based set to see which queries are currently subscribed to */
113
104
  activeQueries: ReferenceCountedSet<LiveQuery<any>>
114
105
 
115
106
  private mutationEventSchema
116
107
 
117
108
  private constructor({
118
- db,
119
- // dbProxy,
109
+ adapter,
120
110
  schema,
121
111
  graphQLOptions,
122
112
  dbGraph,
@@ -124,9 +114,8 @@ export class Store<
124
114
  otelRootSpanContext,
125
115
  mutationEventSchema,
126
116
  }: StoreOptions<TGraphQLContext, TSchema>) {
127
- this.mainDbWrapper = new MainDatabaseWrapper({ otelTracer, otelRootSpanContext, db: db.mainDb })
128
- this.db = db
129
- // this._proxyDb = dbProxy
117
+ this.mainDbWrapper = new MainDatabaseWrapper({ otelTracer, otelRootSpanContext, db: adapter.mainDb })
118
+ this.adapter = adapter
130
119
  this.schema = schema
131
120
 
132
121
  // TODO refactor
@@ -136,7 +125,6 @@ export class Store<
136
125
  // TODO generalize the `tableRefs` concept to allow finer-grained refs
137
126
  this.tableRefs = {}
138
127
  this.activeQueries = new ReferenceCountedSet()
139
- // this.storage = storage
140
128
 
141
129
  const mutationsSpan = otelTracer.startSpan('LiveStore:mutations', {}, otelRootSpanContext)
142
130
  const otelMuationsSpanContext = otel.trace.setSpan(otel.context.active(), mutationsSpan)
@@ -147,6 +135,15 @@ export class Store<
147
135
  this.graph = dbGraph
148
136
  this.graph.context = { store: this as any, otelTracer, rootOtelContext: otelQueriesSpanContext }
149
137
 
138
+ this.adapter.coordinator.syncMutations.pipe(
139
+ Stream.tapSync((mutationEventDecoded) => {
140
+ this.mutate({ wasSyncMessage: true }, mutationEventDecoded)
141
+ }),
142
+ Stream.runDrain,
143
+ Effect.tapCauseLogPretty,
144
+ Effect.runFork,
145
+ )
146
+
150
147
  this.otel = {
151
148
  tracer: otelTracer,
152
149
  mutationsSpanContext: otelMuationsSpanContext,
@@ -246,7 +243,7 @@ export class Store<
246
243
  otel.trace.getSpan(this.otel.mutationsSpanContext)!.end()
247
244
  otel.trace.getSpan(this.otel.queriesSpanContext)!.end()
248
245
 
249
- await this.db.storageDb.shutdown()
246
+ await this.adapter.coordinator.shutdown()
250
247
  }
251
248
 
252
249
  mutate: {
@@ -255,22 +252,24 @@ export class Store<
255
252
  txn: <const TMutationArg extends ReadonlyArray<MutationEvent.ForSchema<TSchema>>>(...list: TMutationArg) => void,
256
253
  ): void
257
254
  <const TMutationArg extends ReadonlyArray<MutationEvent.ForSchema<TSchema>>>(
258
- options: { label?: string; skipRefresh?: boolean },
255
+ options: { label?: string; skipRefresh?: boolean; wasSyncMessage?: boolean },
259
256
  ...list: TMutationArg
260
257
  ): void
261
258
  (
262
- options: { label?: string; skipRefresh?: boolean },
259
+ options: { label?: string; skipRefresh?: boolean; wasSyncMessage?: boolean },
263
260
  txn: <const TMutationArg extends ReadonlyArray<MutationEvent.ForSchema<TSchema>>>(...list: TMutationArg) => void,
264
261
  ): void
265
262
  } = (firstMutationOrTxnFnOrOptions: any, ...restMutations: any[]) => {
266
263
  let mutationsEvents: MutationEvent.ForSchema<TSchema>[]
267
- let options: { label?: string; skipRefresh?: boolean } | undefined
264
+ let options: { label?: string; skipRefresh?: boolean; wasSyncMessage?: boolean } | undefined
268
265
 
269
266
  if (typeof firstMutationOrTxnFnOrOptions === 'function') {
267
+ // TODO ensure that function is synchronous and isn't called in a async way (also write tests for this)
270
268
  mutationsEvents = firstMutationOrTxnFnOrOptions((arg: any) => mutationsEvents.push(arg))
271
269
  } else if (
272
270
  firstMutationOrTxnFnOrOptions?.label !== undefined ||
273
- firstMutationOrTxnFnOrOptions?.skipRefresh !== undefined
271
+ firstMutationOrTxnFnOrOptions?.skipRefresh !== undefined ||
272
+ firstMutationOrTxnFnOrOptions?.wasSyncMessage !== undefined
274
273
  ) {
275
274
  options = firstMutationOrTxnFnOrOptions
276
275
  mutationsEvents = restMutations
@@ -278,13 +277,26 @@ export class Store<
278
277
  mutationsEvents = [firstMutationOrTxnFnOrOptions, ...restMutations]
279
278
  }
280
279
 
280
+ mutationsEvents = mutationsEvents.filter((_) => !this.__processedMutationIds.has(_.id))
281
+
282
+ if (mutationsEvents.length === 0) {
283
+ return
284
+ }
285
+
286
+ for (const mutationEvent of mutationsEvents) {
287
+ this.__processedMutationIds.add(mutationEvent.id)
288
+ }
289
+
281
290
  const label = options?.label ?? 'mutate'
282
291
  const skipRefresh = options?.skipRefresh ?? false
292
+ const wasSyncMessage = options?.wasSyncMessage ?? false
283
293
 
284
294
  const mutationsSpan = otel.trace.getSpan(this.otel.mutationsSpanContext)!
285
295
  mutationsSpan.addEvent('mutate')
286
296
 
287
- // console.debug('LiveStore.mutate', { skipRefresh, events: [...events] })
297
+ // console.group('LiveStore.mutate', { skipRefresh, wasSyncMessage, label })
298
+ // mutationsEvents.forEach((_) => console.log(_.mutation, _.id, _.args))
299
+ // console.groupEnd()
288
300
 
289
301
  return this.otel.tracer.startActiveSpan(
290
302
  'LiveStore:mutate',
@@ -307,7 +319,11 @@ export class Store<
307
319
  const applyMutations = () => {
308
320
  for (const mutationEvent of mutationsEvents) {
309
321
  try {
310
- const { writeTables: writeTablesForEvent } = this.mutateWithoutRefresh(mutationEvent, otelContext)
322
+ const { writeTables: writeTablesForEvent } = this.mutateWithoutRefresh(
323
+ mutationEvent,
324
+ otelContext,
325
+ wasSyncMessage,
326
+ )
311
327
  for (const tableName of writeTablesForEvent) {
312
328
  writeTables.add(tableName)
313
329
  }
@@ -319,7 +335,7 @@ export class Store<
319
335
  }
320
336
 
321
337
  if (mutationsEvents.length > 1) {
322
- // TODO: what to do about storage transaction here?
338
+ // TODO: what to do about coordinator transaction here?
323
339
  this.mainDbWrapper.txn(applyMutations)
324
340
  } else {
325
341
  applyMutations()
@@ -383,10 +399,20 @@ export class Store<
383
399
  * This is an internal method that doesn't trigger a refresh;
384
400
  * the caller must refresh queries after calling this method.
385
401
  */
386
- private mutateWithoutRefresh = (
402
+ mutateWithoutRefresh = (
387
403
  mutationEventDecoded: MutationEvent.ForSchema<TSchema>,
388
404
  otelContext: otel.Context,
405
+ skipCoordinator: boolean = false,
389
406
  ): { writeTables: ReadonlySet<string>; durationMs: number } => {
407
+ // NOTE we also need this temporary workaround here since some code-paths use `mutateWithoutRefresh` directly
408
+ // e.g. the row-query functionality
409
+ if (this.__processedMutationWithoutRefreshIds.has(mutationEventDecoded.id)) {
410
+ // NOTE this data should never be used
411
+ return { writeTables: new Set(), durationMs: 0 }
412
+ } else {
413
+ this.__processedMutationWithoutRefreshIds.add(mutationEventDecoded.id)
414
+ }
415
+
390
416
  return this.otel.tracer.startActiveSpan(
391
417
  'LiveStore:mutatetWithoutRefresh',
392
418
  {
@@ -413,15 +439,20 @@ export class Store<
413
439
  bindValues,
414
440
  writeTables = this.mainDbWrapper.getTablesUsed(statementSql),
415
441
  } of execArgsArr) {
442
+ // TODO when the store doesn't have the lock, we need wait for the coordinator to confirm the mutation
443
+ // before executing the mutation on the main db
416
444
  const { durationMs } = this.mainDbWrapper.execute(statementSql, bindValues, writeTables, { otelContext })
417
445
 
418
446
  durationMsTotal += durationMs
419
447
  writeTables.forEach((table) => allWriteTables.add(table))
420
448
  }
421
449
 
422
- // Asynchronously apply mutation to a persistent storage (we're not awaiting this promise here)
423
450
  const mutationEventEncoded = Schema.encodeUnknownSync(this.mutationEventSchema)(mutationEventDecoded)
424
- this.db.storageDb.mutate(mutationEventEncoded, span)
451
+
452
+ if (skipCoordinator === false) {
453
+ // Asynchronously apply mutation to a persistent storage (we're not awaiting this promise here)
454
+ void this.adapter.coordinator.mutate(mutationEventEncoded, span)
455
+ }
425
456
 
426
457
  // Uncomment to print a list of queries currently registered on the store
427
458
  // console.debug(JSON.parse(JSON.stringify([...this.queries].map((q) => `${labelForKey(q.componentKey)}/${q.label}`))))
@@ -447,7 +478,7 @@ export class Store<
447
478
  this.mainDbWrapper.execute(query, prepareBindValues(params, query), writeTables, { otelContext })
448
479
 
449
480
  const parentSpan = otel.trace.getSpan(otel.context.active())
450
- this.db.storageDb.execute(query, prepareBindValues(params, query), parentSpan)
481
+ this.adapter.coordinator.execute(query, prepareBindValues(params, query), parentSpan)
451
482
  }
452
483
 
453
484
  select = (query: string, params: ParamsObject = {}) => {
@@ -467,12 +498,12 @@ export class Store<
467
498
  }
468
499
 
469
500
  __devDownloadMutationLogDb = async () => {
470
- const data = await this.db.storageDb.getMutationLogData()
501
+ const data = await this.adapter.coordinator.getMutationLogData()
471
502
  downloadBlob(data, `livestore-mutationlog-${Date.now()}.db`)
472
503
  }
473
504
 
474
505
  // TODO allow for graceful store reset without requiring a full page reload (which should also call .boot)
475
- dangerouslyResetStorage = () => this.db.storageDb.dangerouslyReset()
506
+ dangerouslyResetStorage = (mode: ResetMode) => this.adapter.coordinator.dangerouslyReset(mode)
476
507
  }
477
508
 
478
509
  /** Create a new LiveStore Store */
@@ -484,7 +515,7 @@ export const createStore = async <
484
515
  graphQLOptions,
485
516
  otelTracer = makeNoopTracer(),
486
517
  otelRootSpanContext = otel.context.active(),
487
- makeDb,
518
+ adapter: adapterFactory,
488
519
  boot,
489
520
  dbGraph = globalDbGraph,
490
521
  batchUpdates,
@@ -493,7 +524,7 @@ export const createStore = async <
493
524
  graphQLOptions?: GraphQLOptions<TGraphQLContext>
494
525
  otelTracer?: otel.Tracer
495
526
  otelRootSpanContext?: otel.Context
496
- makeDb: DatabaseFactory
527
+ adapter: StoreAdapterFactory
497
528
  boot?: (db: BootDb, parentSpan: otel.Span) => unknown | Promise<unknown>
498
529
  dbGraph?: DbGraph
499
530
  batchUpdates?: (run: () => void) => void
@@ -503,8 +534,8 @@ export const createStore = async <
503
534
  performance.mark('livestore:db-creating')
504
535
  const otelContext = otel.trace.setSpan(otel.context.active(), span)
505
536
 
506
- const dbPromise = makeDb({ otelTracer, otelContext, schema })
507
- const db = dbPromise instanceof Promise ? await dbPromise : dbPromise
537
+ const adapterPromise = adapterFactory({ otelTracer, otelContext, schema })
538
+ const adapter = adapterPromise instanceof Promise ? await adapterPromise : adapterPromise
508
539
  performance.mark('livestore:db-created')
509
540
  performance.measure('livestore:db-create', 'livestore:db-creating', 'livestore:db-created')
510
541
 
@@ -520,15 +551,15 @@ export const createStore = async <
520
551
  let txnExecuteStmnts: [string, PreparedBindValues | undefined][] = []
521
552
 
522
553
  const bootDbImpl: BootDb = {
554
+ _tag: 'BootDb',
523
555
  execute: (queryStr, bindValues) => {
524
- const stmt = db.mainDb.prepare(queryStr)
525
- const preparedBindValues = bindValues ? prepareBindValues(bindValues, queryStr) : undefined
526
- stmt.execute(preparedBindValues)
556
+ const stmt = adapter.mainDb.prepare(queryStr)
557
+ stmt.execute(bindValues)
527
558
 
528
559
  if (isInTxn === true) {
529
- txnExecuteStmnts.push([queryStr, preparedBindValues])
560
+ txnExecuteStmnts.push([queryStr, bindValues])
530
561
  } else {
531
- void db.storageDb.execute(queryStr, preparedBindValues, undefined)
562
+ void adapter.coordinator.execute(queryStr, bindValues, undefined)
532
563
  }
533
564
  },
534
565
  mutate: (...list) => {
@@ -541,34 +572,33 @@ export const createStore = async <
541
572
  // const { bindValues, statementSql } = getExecArgsFromMutation({ mutationDef, mutationEventDecoded })
542
573
 
543
574
  for (const { statementSql, bindValues } of execArgsArr) {
544
- db.mainDb.execute(statementSql, bindValues)
575
+ adapter.mainDb.execute(statementSql, bindValues)
545
576
  }
546
577
 
547
578
  const mutationEventEncoded = Schema.encodeUnknownSync(mutationEventSchema)(mutationEventDecoded)
548
- void db.storageDb.mutate(mutationEventEncoded, span)
579
+ void adapter.coordinator.mutate(mutationEventEncoded, span)
549
580
  }
550
581
  },
551
582
  select: (queryStr, bindValues) => {
552
- const stmt = db.mainDb.prepare(queryStr)
553
- const preparedBindValues = bindValues ? prepareBindValues(bindValues, queryStr) : undefined
554
- return stmt.select(preparedBindValues)
583
+ const stmt = adapter.mainDb.prepare(queryStr)
584
+ return stmt.select(bindValues)
555
585
  },
556
586
  txn: (callback) => {
557
587
  try {
558
588
  isInTxn = true
559
- db.mainDb.execute('BEGIN', undefined)
589
+ adapter.mainDb.execute('BEGIN', undefined)
560
590
 
561
591
  callback()
562
592
 
563
- db.mainDb.execute('COMMIT', undefined)
593
+ adapter.mainDb.execute('COMMIT', undefined)
564
594
 
565
- // db.storageDb.execute('BEGIN', undefined, undefined)
595
+ // adapter.coordinator.execute('BEGIN', undefined, undefined)
566
596
  for (const [queryStr, bindValues] of txnExecuteStmnts) {
567
- db.storageDb.execute(queryStr, bindValues, undefined)
597
+ adapter.coordinator.execute(queryStr, bindValues, undefined)
568
598
  }
569
- // db.storageDb.execute('COMMIT', undefined, undefined)
599
+ // adapter.coordinator.execute('COMMIT', undefined, undefined)
570
600
  } catch (e: any) {
571
- db.mainDb.execute('ROLLBACK', undefined)
601
+ adapter.mainDb.execute('ROLLBACK', undefined)
572
602
  throw e
573
603
  } finally {
574
604
  isInTxn = false
@@ -588,7 +618,7 @@ export const createStore = async <
588
618
  // Think about what to do about this case.
589
619
  // await applySchema(db, schema)
590
620
  return Store.createStore<TGraphQLContext, TSchema>(
591
- { db, schema, graphQLOptions, otelTracer, otelRootSpanContext, dbGraph, mutationEventSchema },
621
+ { adapter: adapter, schema, graphQLOptions, otelTracer, otelRootSpanContext, dbGraph, mutationEventSchema },
592
622
  span,
593
623
  )
594
624
  } finally {
package/src/utils/util.ts CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  import type { Brand } from '@livestore/utils/effect'
4
4
 
5
- export type GetValForKey<T, K> = K extends keyof T ? T[K] : never
6
-
7
5
  export type ParamsObject = Record<string, SqlValue>
8
6
  export type SqlValue = string | number | Uint8Array | null
9
7
 
package/dist/cud.d.ts DELETED
@@ -1,28 +0,0 @@
1
- import type { RawSqlMutationEvent } from '@livestore/common/schema';
2
- import { DbSchema } from '@livestore/common/schema';
3
- import type { SqliteDsl } from 'effect-db-schema';
4
- import type { RowResult } from './row-query.js';
5
- import { type GetValForKey } from './utils/util.js';
6
- export declare const makeCudMutations: <TTableDef extends DbSchema.TableDef<DbSchema.DefaultSqliteTableDefConstrained, boolean, DbSchema.TableOptions, import("@effect/schema/Schema").Schema<any, any, never>>>(tables: Iterable<TTableDef> | Record<string, TTableDef>) => CudMutations<TTableDef>;
7
- export type UpdateMutation<TTableDef extends DbSchema.TableDef> = (args: {
8
- where: Partial<RowResult<TTableDef>>;
9
- values: Partial<RowResult<TTableDef>>;
10
- }) => RawSqlMutationEvent;
11
- export type RowInsert<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true ? GetValForKey<SqliteDsl.FromColumns.InsertRowDecoded<TTableDef['sqliteDef']['columns']>, 'value'> : SqliteDsl.FromColumns.InsertRowDecoded<TTableDef['sqliteDef']['columns']>;
12
- export type InsertMutation<TTableDef extends DbSchema.TableDef> = (values: RowInsert<TTableDef>) => RawSqlMutationEvent;
13
- export type DeleteMutation<TTableDef extends DbSchema.TableDef> = (args: {
14
- where: Partial<RowResult<TTableDef>>;
15
- }) => RawSqlMutationEvent;
16
- export type CudMutation<TTableDef extends DbSchema.TableDef> = {
17
- insert: InsertMutation<TTableDef>;
18
- update: UpdateMutation<TTableDef>;
19
- delete: DeleteMutation<TTableDef>;
20
- };
21
- export type CudMutations<TTableDef extends DbSchema.TableDef> = {
22
- [TTableName in TTableDef['sqliteDef']['name']]: CudMutation<Extract<TTableDef, {
23
- sqliteDef: {
24
- name: TTableName;
25
- };
26
- }>>;
27
- };
28
- //# sourceMappingURL=cud.d.ts.map
package/dist/cud.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cud.d.ts","sourceRoot":"","sources":["../src/cud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,EAAE,QAAQ,EAAkB,MAAM,0BAA0B,CAAA;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEnD,eAAO,MAAM,gBAAgB,oLACnB,SAAS,SAAS,CAAC,GAAG,OAAO,MAAM,EAAE,SAAS,CAAC,KACtD,aAAa,SAAS,CAWxB,CAAA;AAyCD,MAAM,MAAM,cAAc,CAAC,SAAS,SAAS,QAAQ,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE;IAEvE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAA;IACpC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAA;CACtC,KAAK,mBAAmB,CAAA;AAEzB,MAAM,MAAM,SAAS,CAAC,SAAS,SAAS,QAAQ,CAAC,QAAQ,IAAI,SAAS,CAAC,gBAAgB,CAAC,SAAS,IAAI,GACjG,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,gBAAgB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,GAChG,SAAS,CAAC,WAAW,CAAC,gBAAgB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;AAE7E,MAAM,MAAM,cAAc,CAAC,SAAS,SAAS,QAAQ,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,KAAK,mBAAmB,CAAA;AAEvH,MAAM,MAAM,cAAc,CAAC,SAAS,SAAS,QAAQ,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE;IACvE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAA;CACrC,KAAK,mBAAmB,CAAA;AAEzB,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,QAAQ,CAAC,QAAQ,IAAI;IAC7D,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,CAAA;IACjC,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,CAAA;IACjC,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,YAAY,CAAC,SAAS,SAAS,QAAQ,CAAC,QAAQ,IAAI;KAC7D,UAAU,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE;QAAE,SAAS,EAAE;YAAE,IAAI,EAAE,UAAU,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;CACrH,CAAA"}
package/dist/cud.js DELETED
@@ -1,47 +0,0 @@
1
- import { DbSchema, rawSqlMutation } from '@livestore/common/schema';
2
- import { deleteRows, insertRow, updateRows } from '@livestore/common/sql-queries';
3
- import { isIterable } from '@livestore/utils';
4
- export const makeCudMutations = (tables) => {
5
- const cudMutationRecord = {};
6
- const tables_ = isIterable(tables) ? tables : Object.values(tables);
7
- for (const tableDef of tables_) {
8
- const [tableName, cudMutation] = cudMutationsForTable(tableDef);
9
- cudMutationRecord[tableName] = cudMutation;
10
- }
11
- return cudMutationRecord;
12
- };
13
- const cudMutationsForTable = (tableDef) => {
14
- const table = tableDef.sqliteDef;
15
- const writeTables = new Set([table.name]);
16
- const api = {
17
- insert: (values_) => {
18
- const values = DbSchema.getDefaultValuesDecoded(tableDef, values_);
19
- const [sql, bindValues] = insertRow({
20
- tableName: table.name,
21
- columns: table.columns,
22
- options: { orReplace: false },
23
- values: values,
24
- });
25
- return rawSqlMutation({ sql, bindValues, writeTables });
26
- },
27
- update: ({ where, values }) => {
28
- const [sql, bindValues] = updateRows({
29
- tableName: table.name,
30
- columns: table.columns,
31
- where: where,
32
- updateValues: values,
33
- });
34
- return rawSqlMutation({ sql, bindValues, writeTables });
35
- },
36
- delete: ({ where }) => {
37
- const [sql, bindValues] = deleteRows({
38
- tableName: table.name,
39
- columns: table.columns,
40
- where: where,
41
- });
42
- return rawSqlMutation({ sql, bindValues, writeTables });
43
- },
44
- };
45
- return [tableDef.sqliteDef.name, api];
46
- };
47
- //# sourceMappingURL=cud.js.map
package/dist/cud.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cud.js","sourceRoot":"","sources":["../src/cud.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAM7C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,MAAuD,EAC9B,EAAE;IAC3B,MAAM,iBAAiB,GAA4B,EAAS,CAAA;IAE5D,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAEnE,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;QAC/B,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAA;QAC/D,iBAAiB,CAAC,SAAS,CAAC,GAAG,WAAkB,CAAA;IACnD,CAAC;IAED,OAAO,iBAAiB,CAAA;AAC1B,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,CAC3B,QAAmB,EACuC,EAAE;IAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAA;IAChC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IACzC,MAAM,GAAG,GAAG;QACV,MAAM,EAAE,CAAC,OAAY,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,QAAQ,CAAC,uBAAuB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAElE,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC;gBAClC,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;gBAC7B,MAAM,EAAE,MAAa;aACtB,CAAC,CAAA;YACF,OAAO,cAAc,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAA;QACzD,CAAC;QACD,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;YAC5B,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC;gBACnC,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,KAAK,EAAE,KAAK;gBACZ,YAAY,EAAE,MAAM;aACrB,CAAC,CAAA;YACF,OAAO,cAAc,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAA;QACzD,CAAC;QACD,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;YACpB,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC;gBACnC,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,KAAK,EAAE,KAAK;aACb,CAAC,CAAA;YACF,OAAO,cAAc,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAA;QACzD,CAAC;KAC+B,CAAA;IAElC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;AACvC,CAAC,CAAA"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=cud.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cud.test.d.ts","sourceRoot":"","sources":["../src/cud.test.ts"],"names":[],"mappings":""}
package/dist/cud.test.js DELETED
@@ -1,47 +0,0 @@
1
- import { describe, expect, test } from 'vitest';
2
- import { tables } from './__tests__/react/fixture.js';
3
- import { makeCudMutations } from './cud.js';
4
- describe('cud mutations', () => {
5
- const cud = makeCudMutations(tables);
6
- test('basic', () => {
7
- expect(patchId(cud.todos.insert({ id: 't1', completed: true, text: 'Task 1' }))).toMatchInlineSnapshot(`
8
- {
9
- "args": {
10
- "bindValues": {
11
- "completed": 1,
12
- "id": "t1",
13
- "text": "Task 1",
14
- },
15
- "sql": "INSERT INTO todos (id, text, completed) VALUES ($id, $text, $completed)",
16
- "writeTables": Set {
17
- "todos",
18
- },
19
- },
20
- "id": "00000000-0000-0000-0000-000000000000",
21
- "mutation": "livestore.RawSql",
22
- }
23
- `);
24
- expect(patchId(cud.todos.update({ where: { id: 't1' }, values: { text: 'Task 1 - fixed' } })))
25
- .toMatchInlineSnapshot(`
26
- {
27
- "args": {
28
- "bindValues": {
29
- "update_text": "Task 1 - fixed",
30
- "where_id": "t1",
31
- },
32
- "sql": "UPDATE todos SET text = $update_text WHERE id = $where_id",
33
- "writeTables": Set {
34
- "todos",
35
- },
36
- },
37
- "id": "00000000-0000-0000-0000-000000000000",
38
- "mutation": "livestore.RawSql",
39
- }
40
- `);
41
- });
42
- });
43
- const patchId = (muationEvent) => {
44
- const id = `00000000-0000-0000-0000-000000000000`;
45
- return { ...muationEvent, id };
46
- };
47
- //# sourceMappingURL=cud.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cud.test.js","sourceRoot":"","sources":["../src/cud.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE/C,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAG3C,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAEpC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;QACjB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;KAgBtG,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC;aAC3F,qBAAqB,CAAC;;;;;;;;;;;;;;;OAetB,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,MAAM,OAAO,GAAG,CAAC,YAA+B,EAAE,EAAE;IAClD,MAAM,EAAE,GAAG,sCAAsC,CAAA;IACjD,OAAO,EAAE,GAAG,YAAY,EAAE,EAAE,EAAE,CAAA;AAChC,CAAC,CAAA"}
@@ -1,16 +0,0 @@
1
- import { type DatabaseImpl } from '@livestore/common';
2
- import type { LiveStoreSchema } from '@livestore/common/schema';
3
- import type * as otel from '@opentelemetry/api';
4
- import { SqliteAst } from 'effect-db-schema';
5
- export declare const migrateDb: ({ db, otelContext, schema, }: {
6
- db: DatabaseImpl;
7
- otelContext: otel.Context;
8
- schema: LiveStoreSchema;
9
- }) => void;
10
- export declare const migrateTable: ({ db, tableAst, schemaHash, }: {
11
- db: DatabaseImpl;
12
- tableAst: SqliteAst.Table;
13
- otelContext: otel.Context;
14
- schemaHash: number;
15
- }) => void;
16
- //# sourceMappingURL=migrations.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAO,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,0BAA0B,CAAA;AAG9E,OAAO,KAAK,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAa,MAAM,kBAAkB,CAAA;AAoCvD,eAAO,MAAM,SAAS;QAKhB,YAAY;iBACH,KAAK,OAAO;YACjB,eAAe;UAiCxB,CAAA;AAED,eAAO,MAAM,YAAY;QAMnB,YAAY;cACN,UAAU,KAAK;iBACZ,KAAK,OAAO;gBACb,MAAM;UAwBnB,CAAA"}
@@ -1,98 +0,0 @@
1
- import { sql } from '@livestore/common';
2
- import { SCHEMA_META_TABLE, systemTables } from '@livestore/common/schema';
3
- import { Schema as EffectSchema } from '@livestore/utils/effect';
4
- import { SqliteAst, SqliteDsl } from 'effect-db-schema';
5
- import { memoize } from 'lodash-es';
6
- import { prepareBindValues } from './utils/util.js';
7
- const getMemoizedTimestamp = memoize(() => new Date().toISOString());
8
- // TODO bring back statement caching
9
- // const cachedStmts = new Map<string, PreparedStatement>()
10
- const dbExecute = (db, queryStr, bindValues) => {
11
- // let stmt = cachedStmts.get(queryStr)
12
- // if (!stmt) {
13
- const stmt = db.mainDb.prepare(queryStr);
14
- // cachedStmts.set(queryStr, stmt)
15
- // }
16
- const preparedBindValues = bindValues ? prepareBindValues(bindValues, queryStr) : undefined;
17
- stmt.execute(preparedBindValues);
18
- void db.storageDb.execute(queryStr, preparedBindValues, undefined);
19
- };
20
- const dbSelect = (db, queryStr, bindValues) => {
21
- // let stmt = cachedStmts.get(queryStr)
22
- // if (!stmt) {
23
- const stmt = db.mainDb.prepare(queryStr);
24
- // cachedStmts.set(queryStr, stmt)
25
- // }
26
- return stmt.select(bindValues ? prepareBindValues(bindValues, queryStr) : undefined);
27
- };
28
- // TODO more graceful DB migration (e.g. backup DB before destructive migrations)
29
- export const migrateDb = ({ db, otelContext, schema, }) => {
30
- dbExecute(db,
31
- // TODO use schema migration definition from schema.ts instead
32
- sql `create table if not exists ${SCHEMA_META_TABLE} (tableName text primary key, schemaHash text, updatedAt text);`);
33
- const schemaMetaRows = dbSelect(db, sql `SELECT * FROM ${SCHEMA_META_TABLE}`);
34
- const dbSchemaHashByTable = Object.fromEntries(schemaMetaRows.map(({ tableName, schemaHash }) => [tableName, schemaHash]));
35
- const tableDefs = new Set([
36
- // NOTE it's important the `SCHEMA_META_TABLE` comes first since we're writing to it below
37
- ...systemTables,
38
- ...Array.from(schema.tables.values()).filter((_) => _.sqliteDef.name !== SCHEMA_META_TABLE),
39
- ]);
40
- for (const tableDef of tableDefs) {
41
- const tableAst = tableDef.sqliteDef.ast;
42
- const tableName = tableAst.name;
43
- const dbSchemaHash = dbSchemaHashByTable[tableName];
44
- const schemaHash = SqliteAst.hash(tableAst);
45
- if (schemaHash !== dbSchemaHash && import.meta.env.VITE_LIVESTORE_SKIP_MIGRATIONS === undefined) {
46
- console.log(`Schema hash mismatch for table '${tableName}' (DB: ${dbSchemaHash}, expected: ${schemaHash}), migrating table...`);
47
- migrateTable({ db, tableAst, otelContext, schemaHash });
48
- }
49
- }
50
- };
51
- export const migrateTable = ({ db, tableAst,
52
- // otelContext,
53
- schemaHash, }) => {
54
- console.log(`Migrating table '${tableAst.name}'...`);
55
- const tableName = tableAst.name;
56
- const columnSpec = makeColumnSpec(tableAst);
57
- // TODO need to possibly handle cascading deletes due to foreign keys
58
- dbExecute(db, sql `drop table if exists ${tableName}`);
59
- dbExecute(db, sql `create table if not exists ${tableName} (${columnSpec})`);
60
- for (const index of tableAst.indexes) {
61
- dbExecute(db, createIndexFromDefinition(tableName, index));
62
- }
63
- const updatedAt = getMemoizedTimestamp();
64
- dbExecute(db, sql `
65
- INSERT INTO ${SCHEMA_META_TABLE} (tableName, schemaHash, updatedAt) VALUES ($tableName, $schemaHash, $updatedAt)
66
- ON CONFLICT (tableName) DO UPDATE SET schemaHash = $schemaHash, updatedAt = $updatedAt;
67
- `, { tableName, schemaHash, updatedAt });
68
- };
69
- const createIndexFromDefinition = (tableName, index) => {
70
- const uniqueStr = index.unique ? 'UNIQUE' : '';
71
- return sql `create ${uniqueStr} index ${index.name} on ${tableName} (${index.columns.join(', ')})`;
72
- };
73
- const makeColumnSpec = (tableAst) => {
74
- const primaryKeys = tableAst.columns.filter((_) => _.primaryKey).map((_) => _.name);
75
- const columnDefStrs = tableAst.columns.map(toSqliteColumnSpec);
76
- if (primaryKeys.length > 0) {
77
- columnDefStrs.push(`PRIMARY KEY (${primaryKeys.join(', ')})`);
78
- }
79
- return columnDefStrs.join(', ');
80
- };
81
- /** NOTE primary keys are applied on a table level not on a column level to account for multi-column primary keys */
82
- const toSqliteColumnSpec = (column) => {
83
- const columnTypeStr = column.type._tag;
84
- const nullableStr = column.nullable === false ? 'not null' : '';
85
- const defaultValueStr = (() => {
86
- if (column.default._tag === 'None')
87
- return '';
88
- if (SqliteDsl.isSqlDefaultValue(column.default.value))
89
- return `default ${column.default.value.sql}`;
90
- const encodeValue = EffectSchema.encodeSync(column.schema);
91
- const encodedDefaultValue = encodeValue(column.default.value);
92
- if (columnTypeStr === 'text')
93
- return `default '${encodedDefaultValue}'`;
94
- return `default ${encodedDefaultValue}`;
95
- })();
96
- return `${column.name} ${columnTypeStr} ${nullableStr} ${defaultValueStr}`;
97
- };
98
- //# sourceMappingURL=migrations.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAE1D,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC1E,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAEhE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEnD,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;AAEpE,oCAAoC;AACpC,2DAA2D;AAE3D,MAAM,SAAS,GAAG,CAAC,EAAgB,EAAE,QAAgB,EAAE,UAAyB,EAAE,EAAE;IAClF,uCAAuC;IACvC,eAAe;IACf,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxC,kCAAkC;IAClC,IAAI;IAEJ,MAAM,kBAAkB,GAAG,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAE3F,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAEhC,KAAK,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAA;AACpE,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAI,EAAgB,EAAE,QAAgB,EAAE,UAAyB,EAAE,EAAE;IACpF,uCAAuC;IACvC,eAAe;IACf,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxC,kCAAkC;IAClC,IAAI;IAEJ,OAAO,IAAI,CAAC,MAAM,CAAI,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AACzF,CAAC,CAAA;AAED,iFAAiF;AACjF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EACxB,EAAE,EACF,WAAW,EACX,MAAM,GAKP,EAAE,EAAE;IACH,SAAS,CACP,EAAE;IACF,8DAA8D;IAC9D,GAAG,CAAA,8BAA8B,iBAAiB,iEAAiE,CACpH,CAAA;IAED,MAAM,cAAc,GAAG,QAAQ,CAAgB,EAAE,EAAE,GAAG,CAAA,iBAAiB,iBAAiB,EAAE,CAAC,CAAA;IAE3F,MAAM,mBAAmB,GAAG,MAAM,CAAC,WAAW,CAC5C,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAC3E,CAAA;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;QACxB,0FAA0F;QAC1F,GAAG,YAAY;QACf,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,iBAAiB,CAAC;KAC5F,CAAC,CAAA;IAEF,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAA;QACvC,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAA;QAC/B,MAAM,YAAY,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAA;QACnD,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,UAAU,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,8BAA8B,KAAK,SAAS,EAAE,CAAC;YAChG,OAAO,CAAC,GAAG,CACT,mCAAmC,SAAS,UAAU,YAAY,eAAe,UAAU,uBAAuB,CACnH,CAAA;YAED,YAAY,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAA;QACzD,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,EAAE,EACF,QAAQ;AACR,eAAe;AACf,UAAU,GAMX,EAAE,EAAE;IACH,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAA;IACpD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAA;IAC/B,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAE3C,qEAAqE;IACrE,SAAS,CAAC,EAAE,EAAE,GAAG,CAAA,wBAAwB,SAAS,EAAE,CAAC,CAAA;IACrD,SAAS,CAAC,EAAE,EAAE,GAAG,CAAA,8BAA8B,SAAS,KAAK,UAAU,GAAG,CAAC,CAAA;IAE3E,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrC,SAAS,CAAC,EAAE,EAAE,yBAAyB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,MAAM,SAAS,GAAG,oBAAoB,EAAE,CAAA;IAExC,SAAS,CACP,EAAE,EACF,GAAG,CAAA;oBACa,iBAAiB;;KAEhC,EACD,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,CACrC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,yBAAyB,GAAG,CAAC,SAAiB,EAAE,KAAsB,EAAE,EAAE;IAC9E,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9C,OAAO,GAAG,CAAA,UAAU,SAAS,UAAU,KAAK,CAAC,IAAI,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA;AACnG,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,QAAyB,EAAE,EAAE;IACnD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACnF,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IAC9D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,aAAa,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC,CAAA;AAED,oHAAoH;AACpH,MAAM,kBAAkB,GAAG,CAAC,MAAwB,EAAE,EAAE;IACtD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAA;IACtC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;IAC/D,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE;QAC5B,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,EAAE,CAAA;QAE7C,IAAI,SAAS,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,WAAW,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;QAEnG,MAAM,WAAW,GAAG,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC1D,MAAM,mBAAmB,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAE7D,IAAI,aAAa,KAAK,MAAM;YAAE,OAAO,YAAY,mBAAmB,GAAG,CAAA;QACvE,OAAO,WAAW,mBAAmB,EAAE,CAAA;IACzC,CAAC,CAAC,EAAE,CAAA;IAEJ,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,aAAa,IAAI,WAAW,IAAI,eAAe,EAAE,CAAA;AAC5E,CAAC,CAAA"}