@livestore/livestore 0.0.41-dev.2 → 0.0.42-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{inMemoryDatabase.d.ts → MainDatabaseWrapper.d.ts} +11 -18
  3. package/dist/MainDatabaseWrapper.d.ts.map +1 -0
  4. package/dist/{inMemoryDatabase.js → MainDatabaseWrapper.js} +26 -72
  5. package/dist/MainDatabaseWrapper.js.map +1 -0
  6. package/dist/__tests__/react/fixture.d.ts +41 -40
  7. package/dist/__tests__/react/fixture.d.ts.map +1 -1
  8. package/dist/__tests__/react/fixture.js +2 -8
  9. package/dist/__tests__/react/fixture.js.map +1 -1
  10. package/dist/cud.d.ts +9 -9
  11. package/dist/cud.d.ts.map +1 -1
  12. package/dist/cud.js +7 -8
  13. package/dist/cud.js.map +1 -1
  14. package/dist/effect/LiveStore.d.ts +10 -10
  15. package/dist/effect/LiveStore.d.ts.map +1 -1
  16. package/dist/effect/LiveStore.js +2 -11
  17. package/dist/effect/LiveStore.js.map +1 -1
  18. package/dist/global-state.d.ts +2 -2
  19. package/dist/global-state.d.ts.map +1 -1
  20. package/dist/global-state.js.map +1 -1
  21. package/dist/index.d.ts +6 -6
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +4 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/migrations.d.ts +5 -5
  26. package/dist/migrations.d.ts.map +1 -1
  27. package/dist/migrations.js +37 -21
  28. package/dist/migrations.js.map +1 -1
  29. package/dist/query-info.d.ts +8 -9
  30. package/dist/query-info.d.ts.map +1 -1
  31. package/dist/query-info.js +1 -1
  32. package/dist/query-info.js.map +1 -1
  33. package/dist/react/LiveStoreProvider.d.ts +7 -7
  34. package/dist/react/LiveStoreProvider.d.ts.map +1 -1
  35. package/dist/react/LiveStoreProvider.js +11 -19
  36. package/dist/react/LiveStoreProvider.js.map +1 -1
  37. package/dist/react/useRow.d.ts +6 -6
  38. package/dist/react/useRow.d.ts.map +1 -1
  39. package/dist/react/useRow.js +2 -2
  40. package/dist/react/useRow.js.map +1 -1
  41. package/dist/reactiveQueries/sql.js +2 -2
  42. package/dist/reactiveQueries/sql.js.map +1 -1
  43. package/dist/reactiveQueries/sql.test.js +12 -31
  44. package/dist/reactiveQueries/sql.test.js.map +1 -1
  45. package/dist/row-query.d.ts +6 -6
  46. package/dist/row-query.d.ts.map +1 -1
  47. package/dist/row-query.js +9 -12
  48. package/dist/row-query.js.map +1 -1
  49. package/dist/store.d.ts +18 -18
  50. package/dist/store.d.ts.map +1 -1
  51. package/dist/store.js +80 -86
  52. package/dist/store.js.map +1 -1
  53. package/dist/utils/bounded-collections.d.ts +1 -1
  54. package/dist/utils/bounded-collections.d.ts.map +1 -1
  55. package/dist/utils/bounded-collections.js +2 -1
  56. package/dist/utils/bounded-collections.js.map +1 -1
  57. package/dist/utils/util.d.ts +0 -16
  58. package/dist/utils/util.d.ts.map +1 -1
  59. package/dist/utils/util.js +0 -38
  60. package/dist/utils/util.js.map +1 -1
  61. package/package.json +8 -44
  62. package/src/{inMemoryDatabase.ts → MainDatabaseWrapper.ts} +40 -94
  63. package/src/__tests__/react/fixture.tsx +3 -9
  64. package/src/cud.ts +17 -16
  65. package/src/effect/LiveStore.ts +12 -24
  66. package/src/global-state.ts +3 -2
  67. package/src/index.ts +7 -23
  68. package/src/migrations.ts +51 -34
  69. package/src/query-info.ts +10 -9
  70. package/src/react/LiveStoreProvider.tsx +19 -27
  71. package/src/react/useRow.ts +24 -12
  72. package/src/reactiveQueries/sql.test.ts +12 -31
  73. package/src/reactiveQueries/sql.ts +2 -2
  74. package/src/row-query.ts +32 -29
  75. package/src/store.ts +98 -103
  76. package/src/utils/bounded-collections.ts +3 -2
  77. package/src/utils/util.ts +0 -44
  78. package/tsconfig.json +1 -1
  79. package/vitest.config.js +4 -0
  80. package/dist/inMemoryDatabase.d.ts.map +0 -1
  81. package/dist/inMemoryDatabase.js.map +0 -1
  82. package/dist/schema/index.d.ts +0 -42
  83. package/dist/schema/index.d.ts.map +0 -1
  84. package/dist/schema/index.js +0 -42
  85. package/dist/schema/index.js.map +0 -1
  86. package/dist/schema/mutations.d.ts +0 -81
  87. package/dist/schema/mutations.d.ts.map +0 -1
  88. package/dist/schema/mutations.js +0 -29
  89. package/dist/schema/mutations.js.map +0 -1
  90. package/dist/schema/parse-utils.d.ts +0 -6
  91. package/dist/schema/parse-utils.d.ts.map +0 -1
  92. package/dist/schema/parse-utils.js +0 -22
  93. package/dist/schema/parse-utils.js.map +0 -1
  94. package/dist/schema/system-tables.d.ts +0 -76
  95. package/dist/schema/system-tables.d.ts.map +0 -1
  96. package/dist/schema/system-tables.js +0 -11
  97. package/dist/schema/system-tables.js.map +0 -1
  98. package/dist/schema/table-def.d.ts +0 -100
  99. package/dist/schema/table-def.d.ts.map +0 -1
  100. package/dist/schema/table-def.js +0 -70
  101. package/dist/schema/table-def.js.map +0 -1
  102. package/dist/storage/in-memory/index.d.ts +0 -19
  103. package/dist/storage/in-memory/index.d.ts.map +0 -1
  104. package/dist/storage/in-memory/index.js +0 -16
  105. package/dist/storage/in-memory/index.js.map +0 -1
  106. package/dist/storage/index.d.ts +0 -18
  107. package/dist/storage/index.d.ts.map +0 -1
  108. package/dist/storage/index.js +0 -9
  109. package/dist/storage/index.js.map +0 -1
  110. package/dist/storage/tauri/index.d.ts +0 -23
  111. package/dist/storage/tauri/index.d.ts.map +0 -1
  112. package/dist/storage/tauri/index.js +0 -46
  113. package/dist/storage/tauri/index.js.map +0 -1
  114. package/dist/storage/utils/idb.d.ts +0 -11
  115. package/dist/storage/utils/idb.d.ts.map +0 -1
  116. package/dist/storage/utils/idb.js +0 -71
  117. package/dist/storage/utils/idb.js.map +0 -1
  118. package/dist/storage/web-worker/common.d.ts +0 -11
  119. package/dist/storage/web-worker/common.d.ts.map +0 -1
  120. package/dist/storage/web-worker/common.js +0 -2
  121. package/dist/storage/web-worker/common.js.map +0 -1
  122. package/dist/storage/web-worker/index.d.ts +0 -34
  123. package/dist/storage/web-worker/index.d.ts.map +0 -1
  124. package/dist/storage/web-worker/index.js +0 -134
  125. package/dist/storage/web-worker/index.js.map +0 -1
  126. package/dist/storage/web-worker/make-worker.d.ts +0 -20
  127. package/dist/storage/web-worker/make-worker.d.ts.map +0 -1
  128. package/dist/storage/web-worker/make-worker.js +0 -155
  129. package/dist/storage/web-worker/make-worker.js.map +0 -1
  130. package/dist/storage/web-worker/vite-dev-polyfill.d.ts +0 -2
  131. package/dist/storage/web-worker/vite-dev-polyfill.d.ts.map +0 -1
  132. package/dist/storage/web-worker/vite-dev-polyfill.js +0 -35
  133. package/dist/storage/web-worker/vite-dev-polyfill.js.map +0 -1
  134. package/src/schema/index.ts +0 -100
  135. package/src/schema/mutations.ts +0 -128
  136. package/src/schema/parse-utils.ts +0 -42
  137. package/src/schema/system-tables.ts +0 -21
  138. package/src/schema/table-def.ts +0 -270
  139. package/src/storage/in-memory/index.ts +0 -28
  140. package/src/storage/index.ts +0 -36
  141. package/src/storage/tauri/index.ts +0 -66
  142. package/src/storage/utils/idb.ts +0 -85
  143. package/src/storage/web-worker/common.ts +0 -6
  144. package/src/storage/web-worker/index.ts +0 -185
  145. package/src/storage/web-worker/make-worker.ts +0 -214
  146. package/src/storage/web-worker/vite-dev-polyfill.ts +0 -33
package/src/query-info.ts CHANGED
@@ -1,16 +1,14 @@
1
+ import { type DbSchema, rawSqlMutation, type RawSqlMutationEvent } from '@livestore/common/schema'
1
2
  import { notYetImplemented, shouldNeverHappen } from '@livestore/utils'
2
3
  import { Schema } from '@livestore/utils/effect'
3
4
 
4
- import { rawSqlMutation, type RawSqlMutationEvent } from './schema/mutations.js'
5
- import type { FromTable, TableDef } from './schema/table-def.js'
6
-
7
5
  /**
8
6
  * Semantic information about a query with supported cases being:
9
7
  * - a whole row
10
8
  * - a single column value
11
9
  * - a sub value in a JSON column
12
10
  */
13
- export type QueryInfo<TTableDef extends TableDef = TableDef> =
11
+ export type QueryInfo<TTableDef extends DbSchema.TableDef = DbSchema.TableDef> =
14
12
  | QueryInfoNone
15
13
  | QueryInfoRow<TTableDef>
16
14
  | QueryInfoColJsonValue<TTableDef, GetJsonColumn<TTableDef>>
@@ -20,20 +18,23 @@ export type QueryInfoNone = {
20
18
  _tag: 'None'
21
19
  }
22
20
 
23
- export type QueryInfoRow<TTableDef extends TableDef> = {
21
+ export type QueryInfoRow<TTableDef extends DbSchema.TableDef> = {
24
22
  _tag: 'Row'
25
23
  table: TTableDef
26
24
  id: string
27
25
  }
28
26
 
29
- export type QueryInfoCol<TTableDef extends TableDef, TColName extends keyof TTableDef['sqliteDef']['columns']> = {
27
+ export type QueryInfoCol<
28
+ TTableDef extends DbSchema.TableDef,
29
+ TColName extends keyof TTableDef['sqliteDef']['columns'],
30
+ > = {
30
31
  _tag: 'Col'
31
32
  table: TTableDef
32
33
  id: string
33
34
  column: TColName
34
35
  }
35
36
 
36
- export type QueryInfoColJsonValue<TTableDef extends TableDef, TColName extends GetJsonColumn<TTableDef>> = {
37
+ export type QueryInfoColJsonValue<TTableDef extends DbSchema.TableDef, TColName extends GetJsonColumn<TTableDef>> = {
37
38
  _tag: 'ColJsonValue'
38
39
  table: TTableDef
39
40
  id: string
@@ -44,14 +45,14 @@ export type QueryInfoColJsonValue<TTableDef extends TableDef, TColName extends G
44
45
  jsonPath: string
45
46
  }
46
47
 
47
- type GetJsonColumn<TTableDef extends TableDef> = keyof {
48
+ type GetJsonColumn<TTableDef extends DbSchema.TableDef> = keyof {
48
49
  [ColName in keyof TTableDef['sqliteDef']['columns'] as TTableDef['sqliteDef']['columns'][ColName]['columnType'] extends 'text'
49
50
  ? ColName
50
51
  : never]: {}
51
52
  }
52
53
 
53
54
  export type UpdateValueForPath<TPath extends QueryInfo> = TPath extends { _tag: 'Row' }
54
- ? Partial<FromTable.RowDecodedAll<TPath['table']>>
55
+ ? Partial<DbSchema.FromTable.RowDecodedAll<TPath['table']>>
55
56
  : TPath extends { _tag: 'Col' }
56
57
  ? Schema.Schema.To<TPath['table']['sqliteDef']['columns'][TPath['column']]['schema']>
57
58
  : TPath extends { _tag: 'ColJsonValue' }
@@ -1,70 +1,65 @@
1
+ import type { DatabaseFactory } from '@livestore/common'
2
+ import type { LiveStoreSchema } from '@livestore/common/schema'
1
3
  import { shouldNeverHappen } from '@livestore/utils'
2
4
  import type * as otel from '@opentelemetry/api'
3
5
  import type { ReactElement, ReactNode } from 'react'
4
6
  import React from 'react'
5
- import initSqlite3Wasm from 'sqlite-esm'
6
7
 
7
8
  // TODO refactor so the `react` module doesn't depend on `effect` module
8
9
  import type { LiveStoreContext as StoreContext_, LiveStoreCreateStoreOptions } from '../effect/LiveStore.js'
9
- import type { InMemoryDatabase } from '../inMemoryDatabase.js'
10
- import type { LiveStoreSchema } from '../schema/index.js'
11
- import type { StorageInit } from '../storage/index.js'
12
- import type { BaseGraphQLContext, GraphQLOptions, Store } from '../store.js'
10
+ import type { BaseGraphQLContext, BootDb, GraphQLOptions, Store } from '../store.js'
13
11
  import { createStore } from '../store.js'
14
12
  import { LiveStoreContext } from './LiveStoreContext.js'
15
13
 
16
- // NOTE we're starting to initialize the sqlite wasm binary here (already before calling `createStore`),
17
- // so that it's ready when we need it
18
- const sqlite3Promise = initSqlite3Wasm({
19
- print: (message) => console.log(`[livestore sqlite] ${message}`),
20
- printErr: (message) => console.error(`[livestore sqlite] ${message}`),
21
- })
22
-
23
14
  interface LiveStoreProviderProps<GraphQLContext> {
24
15
  schema: LiveStoreSchema
25
- loadStorage: () => StorageInit | Promise<StorageInit>
26
- boot?: (db: InMemoryDatabase, parentSpan: otel.Span) => unknown | Promise<unknown>
16
+ boot?: (db: BootDb, parentSpan: otel.Span) => unknown | Promise<unknown>
27
17
  graphQLOptions?: GraphQLOptions<GraphQLContext>
28
18
  otelTracer?: otel.Tracer
29
19
  otelRootSpanContext?: otel.Context
30
20
  fallback: ReactElement
21
+ makeDb: DatabaseFactory
22
+ batchUpdates?: (run: () => void) => void
31
23
  }
32
24
 
33
25
  export const LiveStoreProvider = <GraphQLContext extends BaseGraphQLContext>({
34
26
  fallback,
35
- loadStorage,
36
27
  graphQLOptions,
37
28
  otelTracer,
38
29
  otelRootSpanContext,
39
30
  children,
40
31
  schema,
41
32
  boot,
33
+ makeDb,
34
+ batchUpdates,
42
35
  }: LiveStoreProviderProps<GraphQLContext> & { children?: ReactNode }): JSX.Element => {
43
- const store = useCreateStore({
36
+ const storeCtx = useCreateStore({
44
37
  schema,
45
- loadStorage,
46
38
  graphQLOptions,
47
39
  otelTracer,
48
40
  otelRootSpanContext,
49
41
  boot,
42
+ makeDb,
43
+ batchUpdates,
50
44
  })
51
45
 
52
- if (store === undefined) {
46
+ if (storeCtx === undefined) {
53
47
  return fallback
54
48
  }
55
49
 
56
- window.__debugLiveStore = store.store
50
+ window.__debugLiveStore = storeCtx.store
57
51
 
58
- return <LiveStoreContext.Provider value={store}>{children}</LiveStoreContext.Provider>
52
+ return <LiveStoreContext.Provider value={storeCtx}>{children}</LiveStoreContext.Provider>
59
53
  }
60
54
 
61
55
  const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
62
56
  schema,
63
- loadStorage,
64
57
  graphQLOptions,
65
58
  otelTracer,
66
59
  otelRootSpanContext,
67
60
  boot,
61
+ makeDb,
62
+ batchUpdates,
68
63
  }: LiveStoreCreateStoreOptions<GraphQLContext>) => {
69
64
  const [ctxValue, setCtxValue] = React.useState<StoreContext_ | undefined>()
70
65
 
@@ -76,15 +71,14 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
76
71
 
77
72
  void (async () => {
78
73
  try {
79
- const sqlite3 = await sqlite3Promise
80
74
  store = await createStore({
81
75
  schema,
82
- loadStorage,
83
76
  graphQLOptions,
84
77
  otelTracer,
85
78
  otelRootSpanContext,
86
79
  boot,
87
- sqlite3,
80
+ makeDb,
81
+ batchUpdates,
88
82
  })
89
83
  setCtxValue({ store })
90
84
  } catch (e) {
@@ -95,9 +89,7 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
95
89
  return () => {
96
90
  store?.destroy()
97
91
  }
98
-
99
- // TODO: do we need to return any cleanup function here?
100
- }, [schema, loadStorage, graphQLOptions, otelTracer, otelRootSpanContext, boot])
92
+ }, [schema, graphQLOptions, otelTracer, otelRootSpanContext, boot, makeDb, batchUpdates])
101
93
 
102
94
  return ctxValue
103
95
  }
@@ -1,3 +1,4 @@
1
+ import { DbSchema } from '@livestore/common/schema'
1
2
  import * as otel from '@opentelemetry/api'
2
3
  import type { SqliteDsl } from 'effect-db-schema'
3
4
  import { mapValues } from 'lodash-es'
@@ -8,18 +9,17 @@ import type { QueryInfo } from '../query-info.js'
8
9
  import { mutationForQueryInfo } from '../query-info.js'
9
10
  import type { RowResult } from '../row-query.js'
10
11
  import { rowQuery } from '../row-query.js'
11
- import { type DefaultSqliteTableDef, type TableDef, tableIsSingleton, type TableOptions } from '../schema/table-def.js'
12
12
  import { useStore } from './LiveStoreContext.js'
13
13
  import { useQueryRef } from './useQuery.js'
14
14
  import { useCleanup } from './utils/useCleanup.js'
15
15
 
16
- export type UseRowResult<TTableDef extends TableDef> = [
16
+ export type UseRowResult<TTableDef extends DbSchema.TableDef> = [
17
17
  row: RowResult<TTableDef>,
18
18
  setRow: StateSetters<TTableDef>,
19
19
  query$: LiveQuery<RowResult<TTableDef>, QueryInfo>,
20
20
  ]
21
21
 
22
- export type UseRowOptionsDefaulValues<TTableDef extends TableDef> = {
22
+ export type UseRowOptionsDefaulValues<TTableDef extends DbSchema.TableDef> = {
23
23
  defaultValues?: Partial<RowResult<TTableDef>>
24
24
  }
25
25
 
@@ -37,17 +37,29 @@ export type UseRowOptionsBase = {
37
37
  * If the table is a singleton table, `useRow` can be called without an `id` argument. Otherwise, the `id` argument is required.
38
38
  */
39
39
  export const useRow: {
40
- <TTableDef extends TableDef<DefaultSqliteTableDef, boolean, TableOptions & { isSingleton: true }>>(
40
+ <
41
+ TTableDef extends DbSchema.TableDef<
42
+ DbSchema.DefaultSqliteTableDef,
43
+ boolean,
44
+ DbSchema.TableOptions & { isSingleton: true }
45
+ >,
46
+ >(
41
47
  table: TTableDef,
42
48
  options?: UseRowOptionsBase,
43
49
  ): UseRowResult<TTableDef>
44
- <TTableDef extends TableDef<DefaultSqliteTableDef, boolean, TableOptions & { isSingleton: false }>>(
50
+ <
51
+ TTableDef extends DbSchema.TableDef<
52
+ DbSchema.DefaultSqliteTableDef,
53
+ boolean,
54
+ DbSchema.TableOptions & { isSingleton: false }
55
+ >,
56
+ >(
45
57
  table: TTableDef,
46
58
  // TODO adjust so it works with arbitrary primary keys or unique constraints
47
59
  id: string,
48
60
  options?: UseRowOptionsBase & UseRowOptionsDefaulValues<TTableDef>,
49
61
  ): UseRowResult<TTableDef>
50
- } = <TTableDef extends TableDef>(
62
+ } = <TTableDef extends DbSchema.TableDef>(
51
63
  table: TTableDef,
52
64
  idOrOptions?: string | UseRowOptionsBase,
53
65
  options_?: UseRowOptionsBase & UseRowOptionsDefaulValues<TTableDef>,
@@ -83,7 +95,7 @@ export const useRow: {
83
95
 
84
96
  const otelContext = otel.trace.setSpan(otel.context.active(), span)
85
97
 
86
- const query$ = tableIsSingleton(table)
98
+ const query$ = DbSchema.tableIsSingleton(table)
87
99
  ? (rowQuery(table, { otelContext, dbGraph }) as LiveQuery<RowResult<TTableDef>, QueryInfo>)
88
100
  : (rowQuery(table as TTableDef & { options: { isSingleton: false } }, id!, {
89
101
  otelContext,
@@ -160,7 +172,7 @@ export const useRow: {
160
172
  export type Dispatch<A> = (action: A) => void
161
173
  export type SetStateAction<S> = S | ((previousValue: S) => S)
162
174
 
163
- export type StateSetters<TTableDef extends TableDef> = TTableDef['isSingleColumn'] extends true
175
+ export type StateSetters<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true
164
176
  ? Dispatch<SetStateAction<RowResult<TTableDef>>>
165
177
  : {
166
178
  [K in keyof RowResult<TTableDef>]: Dispatch<SetStateAction<RowResult<TTableDef>[K]>>
@@ -171,7 +183,7 @@ export type StateSetters<TTableDef extends TableDef> = TTableDef['isSingleColumn
171
183
  /** Reference counted cache for `query$` and otel context */
172
184
  class RCCache {
173
185
  private readonly cache = new Map<
174
- TableDef,
186
+ DbSchema.TableDef,
175
187
  Map<
176
188
  string,
177
189
  {
@@ -182,16 +194,16 @@ class RCCache {
182
194
  }
183
195
  >
184
196
  >()
185
- private reverseCache = new Map<LiveQuery<any, any>, [TableDef, string]>()
197
+ private reverseCache = new Map<LiveQuery<any, any>, [DbSchema.TableDef, string]>()
186
198
 
187
- get = (table: TableDef, id: string) => {
199
+ get = (table: DbSchema.TableDef, id: string) => {
188
200
  const queries = this.cache.get(table)
189
201
  if (queries === undefined) return undefined
190
202
  return queries.get(id)
191
203
  }
192
204
 
193
205
  set = (
194
- table: TableDef,
206
+ table: DbSchema.TableDef,
195
207
  id: string,
196
208
  query$: LiveQuery<any, any>,
197
209
  reactId: string,
@@ -31,11 +31,19 @@ describe('otel', () => {
31
31
 
32
32
  const { store } = await makeTodoMvc({ otelTracer: tracer, otelContext })
33
33
 
34
- return { store, tracer, exporter, span, provider }
34
+ return {
35
+ [Symbol.dispose]: () => store.destroy(),
36
+ store,
37
+ tracer,
38
+ exporter,
39
+ span,
40
+ provider,
41
+ }
35
42
  }
36
43
 
37
44
  it('otel', async () => {
38
- const { store, exporter, span } = await makeQuery()
45
+ using inputs = await makeQuery()
46
+ const { store, exporter, span } = inputs
39
47
 
40
48
  const query = querySQL(`select * from todos`, { queriedTables: new Set(['todos']) })
41
49
  expect(query.run()).toMatchInlineSnapshot('[]')
@@ -73,20 +81,6 @@ describe('otel', () => {
73
81
  ",
74
82
  },
75
83
  },
76
- {
77
- "_name": "sql-in-memory-select",
78
- "attributes": {
79
- "sql.cached": false,
80
- "sql.query": "SELECT * FROM __livestore_schema",
81
- "sql.rowsCount": 0,
82
- },
83
- },
84
- {
85
- "_name": "livestore.in-memory-db:execute",
86
- "attributes": {
87
- "sql.query": "INSERT OR IGNORE INTO app (id, newTodoText, filter) VALUES ('static', '', 'all');",
88
- },
89
- },
90
84
  {
91
85
  "_name": "LiveStore:mutations",
92
86
  "children": [
@@ -170,7 +164,8 @@ describe('otel', () => {
170
164
  })
171
165
 
172
166
  it('with thunks', async () => {
173
- const { store, exporter, span } = await makeQuery()
167
+ using inputs = await makeQuery()
168
+ const { store, exporter, span } = inputs
174
169
 
175
170
  const defaultTodo = { id: '', text: '', completed: false }
176
171
 
@@ -219,20 +214,6 @@ describe('otel', () => {
219
214
  ",
220
215
  },
221
216
  },
222
- {
223
- "_name": "sql-in-memory-select",
224
- "attributes": {
225
- "sql.cached": false,
226
- "sql.query": "SELECT * FROM __livestore_schema",
227
- "sql.rowsCount": 0,
228
- },
229
- },
230
- {
231
- "_name": "livestore.in-memory-db:execute",
232
- "attributes": {
233
- "sql.query": "INSERT OR IGNORE INTO app (id, newTodoText, filter) VALUES ('static', '', 'all');",
234
- },
235
- },
236
217
  {
237
218
  "_name": "LiveStore:mutations",
238
219
  "children": [
@@ -147,7 +147,7 @@ export class LiveStoreSQLQuery<TResult, TQueryInfo extends QueryInfo = QueryInfo
147
147
  const sqlString = get(queryString$, otelContext)
148
148
 
149
149
  if (queriedTablesRef.current === undefined) {
150
- queriedTablesRef.current = store.inMemoryDB.getTablesUsed(sqlString)
150
+ queriedTablesRef.current = store.mainDbWrapper.getTablesUsed(sqlString)
151
151
  }
152
152
 
153
153
  // Establish a reactive dependency on the tables used in the query
@@ -159,7 +159,7 @@ export class LiveStoreSQLQuery<TResult, TQueryInfo extends QueryInfo = QueryInfo
159
159
  span.setAttribute('sql.query', sqlString)
160
160
  span.updateName(`sql:${sqlString.slice(0, 50)}`)
161
161
 
162
- const rawResults = store.inMemoryDB.select<any>(sqlString, {
162
+ const rawResults = store.mainDbWrapper.select<any>(sqlString, {
163
163
  queriedTables,
164
164
  bindValues: bindValues ? prepareBindValues(bindValues, sqlString) : undefined,
165
165
  otelContext,
package/src/row-query.ts CHANGED
@@ -1,26 +1,19 @@
1
+ import { sql } from '@livestore/common'
2
+ import { DbSchema, SCHEMA_META_TABLE } from '@livestore/common/schema'
1
3
  import { shouldNeverHappen } from '@livestore/utils'
2
4
  import { Schema, TreeFormatter } from '@livestore/utils/effect'
3
5
  import type * as otel from '@opentelemetry/api'
4
6
  import { SqliteAst, SqliteDsl } from 'effect-db-schema'
5
7
 
6
- import { computed } from './index.js'
7
- import type { InMemoryDatabase } from './inMemoryDatabase.js'
8
8
  import { migrateTable } from './migrations.js'
9
9
  import type { QueryInfoCol, QueryInfoNone, QueryInfoRow } from './query-info.js'
10
10
  import type { Ref } from './reactive.js'
11
11
  import type { DbContext, DbGraph, LiveQuery, LiveQueryAny } from './reactiveQueries/base-class.js'
12
+ import { computed } from './reactiveQueries/js.js'
12
13
  // import type { LiveStoreJSQuery } from './reactiveQueries/js.js'
13
14
  import { LiveStoreSQLQuery } from './reactiveQueries/sql.js'
14
- import { SCHEMA_META_TABLE } from './schema/index.js'
15
- import {
16
- type DefaultSqliteTableDef,
17
- getDefaultValuesEncoded,
18
- type TableDef,
19
- type TableOptions,
20
- } from './schema/table-def.js'
21
- import type { RefreshReason } from './store.js'
15
+ import type { RefreshReason, Store } from './store.js'
22
16
  import type { GetValForKey } from './utils/util.js'
23
- import { prepareBindValues, sql } from './utils/util.js'
24
17
 
25
18
  export type RowQueryOptions = {
26
19
  otelContext?: otel.Context
@@ -28,16 +21,28 @@ export type RowQueryOptions = {
28
21
  dbGraph?: DbGraph
29
22
  }
30
23
 
31
- export type RowQueryOptionsDefaulValues<TTableDef extends TableDef> = {
24
+ export type RowQueryOptionsDefaulValues<TTableDef extends DbSchema.TableDef> = {
32
25
  defaultValues: Partial<RowResult<TTableDef>>
33
26
  }
34
27
 
35
28
  export type MakeRowQuery = {
36
- <TTableDef extends TableDef<DefaultSqliteTableDef, boolean, TableOptions & { isSingleton: true }>>(
29
+ <
30
+ TTableDef extends DbSchema.TableDef<
31
+ DbSchema.DefaultSqliteTableDef,
32
+ boolean,
33
+ DbSchema.TableOptions & { isSingleton: true }
34
+ >,
35
+ >(
37
36
  table: TTableDef,
38
37
  options?: RowQueryOptions,
39
38
  ): LiveQuery<RowResult<TTableDef>, QueryInfoRow<TTableDef>>
40
- <TTableDef extends TableDef<DefaultSqliteTableDef, boolean, TableOptions & { isSingleton: false }>>(
39
+ <
40
+ TTableDef extends DbSchema.TableDef<
41
+ DbSchema.DefaultSqliteTableDef,
42
+ boolean,
43
+ DbSchema.TableOptions & { isSingleton: false }
44
+ >,
45
+ >(
41
46
  table: TTableDef,
42
47
  // TODO adjust so it works with arbitrary primary keys or unique constraints
43
48
  id: string,
@@ -46,7 +51,7 @@ export type MakeRowQuery = {
46
51
  }
47
52
 
48
53
  // TODO also allow other where clauses and multiple rows
49
- export const rowQuery: MakeRowQuery = <TTableDef extends TableDef>(
54
+ export const rowQuery: MakeRowQuery = <TTableDef extends DbSchema.TableDef>(
50
55
  table: TTableDef,
51
56
  idOrOptions?: string | RowQueryOptions,
52
57
  options_?: RowQueryOptions & RowQueryOptionsDefaulValues<TTableDef>,
@@ -98,11 +103,11 @@ export const rowQuery: MakeRowQuery = <TTableDef extends TableDef>(
98
103
  })
99
104
  }
100
105
 
101
- export type RowResult<TTableDef extends TableDef> = TTableDef['isSingleColumn'] extends true
106
+ export type RowResult<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true
102
107
  ? GetValForKey<SqliteDsl.FromColumns.RowDecoded<TTableDef['sqliteDef']['columns']>, 'value'>
103
108
  : SqliteDsl.FromColumns.RowDecoded<TTableDef['sqliteDef']['columns']>
104
109
 
105
- export type RowResultEncoded<TTableDef extends TableDef> = TTableDef['isSingleColumn'] extends true
110
+ export type RowResultEncoded<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true
106
111
  ? GetValForKey<SqliteDsl.FromColumns.RowEncoded<TTableDef['sqliteDef']['columns']>, 'value'>
107
112
  : SqliteDsl.FromColumns.RowEncoded<TTableDef['sqliteDef']['columns']>
108
113
 
@@ -126,19 +131,19 @@ export const deriveColQuery: {
126
131
  }
127
132
 
128
133
  const insertRowWithDefaultValuesOrIgnore = ({
129
- db,
134
+ store,
130
135
  id,
131
136
  table,
132
137
  otelContext,
133
138
  defaultValues: explicitDefaultValues,
134
139
  }: {
135
- db: InMemoryDatabase
140
+ store: Store
136
141
  id: string
137
- table: TableDef
142
+ table: DbSchema.TableDef
138
143
  otelContext: otel.Context
139
- defaultValues: Partial<RowResult<TableDef>> | undefined
144
+ defaultValues: Partial<RowResult<DbSchema.TableDef>> | undefined
140
145
  }) => {
141
- const defaultValues = getDefaultValuesEncoded(table, explicitDefaultValues)
146
+ const defaultValues = DbSchema.getDefaultValuesEncoded(table, explicitDefaultValues)
142
147
 
143
148
  const defaultColumnNames = [...Object.keys(defaultValues), 'id']
144
149
  const columnValues = defaultColumnNames.map((name) => `$${name}`).join(', ')
@@ -148,9 +153,7 @@ const insertRowWithDefaultValuesOrIgnore = ({
148
153
  ', ',
149
154
  )}) select ${columnValues} where not exists(select 1 from ${tableName} where id = '${id}')`
150
155
 
151
- db.execute(insertQuery, prepareBindValues({ ...defaultValues, id }, insertQuery), new Set([tableName]), {
152
- otelContext,
153
- })
156
+ store.execute(insertQuery, { ...defaultValues, id }, new Set([tableName]), otelContext)
154
157
  }
155
158
 
156
159
  const makeExecBeforeFirstRun =
@@ -167,7 +170,7 @@ const makeExecBeforeFirstRun =
167
170
  skipInsertDefaultRow?: boolean
168
171
  otelContext?: otel.Context
169
172
  componentTableName: string
170
- table: TableDef
173
+ table: DbSchema.TableDef
171
174
  }) =>
172
175
  ({ store }: DbContext) => {
173
176
  const otelContext = otelContext_ ?? store.otel.queriesSpanContext
@@ -175,12 +178,12 @@ const makeExecBeforeFirstRun =
175
178
  // TODO find a better solution for this
176
179
  if (store.tableRefs[componentTableName] === undefined) {
177
180
  const schemaHash = SqliteAst.hash(table.sqliteDef.ast)
178
- const res = store.inMemoryDB.select<{ schemaHash: number }>(
181
+ const res = store.mainDbWrapper.select<{ schemaHash: number }>(
179
182
  sql`SELECT schemaHash FROM ${SCHEMA_META_TABLE} WHERE tableName = '${componentTableName}'`,
180
183
  )
181
184
  if (res.length === 0 || res[0]!.schemaHash !== schemaHash) {
182
185
  migrateTable({
183
- db: store._proxyDb,
186
+ db: store.db,
184
187
  tableAst: table.sqliteDef.ast,
185
188
  otelContext,
186
189
  schemaHash,
@@ -200,7 +203,7 @@ const makeExecBeforeFirstRun =
200
203
  if (skipInsertDefaultRow !== true) {
201
204
  // TODO find a way to only do this if necessary
202
205
  insertRowWithDefaultValuesOrIgnore({
203
- db: store._proxyDb,
206
+ store,
204
207
  id: id ?? 'singleton',
205
208
  table,
206
209
  otelContext,