@livestore/livestore 0.1.0-dev.9 → 0.2.0-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 (112) hide show
  1. package/README.md +3 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/global-state.d.ts +1 -1
  4. package/dist/global-state.d.ts.map +1 -1
  5. package/dist/global-state.js +1 -1
  6. package/dist/global-state.js.map +1 -1
  7. package/dist/index.d.ts +6 -6
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +5 -5
  10. package/dist/index.js.map +1 -1
  11. package/dist/live-queries/base-class.d.ts +64 -0
  12. package/dist/live-queries/base-class.d.ts.map +1 -0
  13. package/dist/live-queries/base-class.js +31 -0
  14. package/dist/live-queries/base-class.js.map +1 -0
  15. package/dist/live-queries/computed.d.ts +26 -0
  16. package/dist/live-queries/computed.d.ts.map +1 -0
  17. package/dist/{reactiveQueries/js.js → live-queries/computed.js} +7 -26
  18. package/dist/live-queries/computed.js.map +1 -0
  19. package/dist/live-queries/db.d.ts +66 -0
  20. package/dist/live-queries/db.d.ts.map +1 -0
  21. package/dist/live-queries/db.js +199 -0
  22. package/dist/live-queries/db.js.map +1 -0
  23. package/dist/live-queries/db.test.d.ts +2 -0
  24. package/dist/live-queries/db.test.d.ts.map +1 -0
  25. package/dist/live-queries/db.test.js +117 -0
  26. package/dist/live-queries/db.test.js.map +1 -0
  27. package/dist/live-queries/graphql.d.ts +49 -0
  28. package/dist/live-queries/graphql.d.ts.map +1 -0
  29. package/dist/live-queries/graphql.js +122 -0
  30. package/dist/live-queries/graphql.js.map +1 -0
  31. package/dist/live-queries/sql.d.ts +62 -0
  32. package/dist/live-queries/sql.d.ts.map +1 -0
  33. package/dist/live-queries/sql.js +175 -0
  34. package/dist/live-queries/sql.js.map +1 -0
  35. package/dist/live-queries/sql.test.d.ts +2 -0
  36. package/dist/live-queries/sql.test.d.ts.map +1 -0
  37. package/{src/reactiveQueries/sql.test.ts → dist/live-queries/sql.test.js} +68 -91
  38. package/dist/live-queries/sql.test.js.map +1 -0
  39. package/dist/reactiveQueries/base-class.d.ts +6 -2
  40. package/dist/reactiveQueries/base-class.d.ts.map +1 -1
  41. package/dist/reactiveQueries/base-class.js +2 -0
  42. package/dist/reactiveQueries/base-class.js.map +1 -1
  43. package/dist/reactiveQueries/computed.d.ts +4 -13
  44. package/dist/reactiveQueries/computed.d.ts.map +1 -1
  45. package/dist/reactiveQueries/computed.js +2 -21
  46. package/dist/reactiveQueries/computed.js.map +1 -1
  47. package/dist/reactiveQueries/graphql.d.ts +4 -8
  48. package/dist/reactiveQueries/graphql.d.ts.map +1 -1
  49. package/dist/reactiveQueries/graphql.js +1 -15
  50. package/dist/reactiveQueries/graphql.js.map +1 -1
  51. package/dist/reactiveQueries/sql.d.ts +36 -23
  52. package/dist/reactiveQueries/sql.d.ts.map +1 -1
  53. package/dist/reactiveQueries/sql.js +100 -55
  54. package/dist/reactiveQueries/sql.js.map +1 -1
  55. package/dist/reactiveQueries/sql.test.js +12 -11
  56. package/dist/reactiveQueries/sql.test.js.map +1 -1
  57. package/dist/row-query-utils.d.ts +17 -0
  58. package/dist/row-query-utils.d.ts.map +1 -0
  59. package/dist/row-query-utils.js +30 -0
  60. package/dist/row-query-utils.js.map +1 -0
  61. package/dist/row-query.d.ts +10 -27
  62. package/dist/row-query.d.ts.map +1 -1
  63. package/dist/row-query.js +16 -66
  64. package/dist/row-query.js.map +1 -1
  65. package/dist/store/create-store.d.ts +1 -1
  66. package/dist/store/create-store.d.ts.map +1 -1
  67. package/dist/store/devtools.d.ts +1 -1
  68. package/dist/store/devtools.d.ts.map +1 -1
  69. package/dist/store/devtools.js.map +1 -1
  70. package/dist/store/store-types.d.ts +2 -2
  71. package/dist/store/store-types.d.ts.map +1 -1
  72. package/dist/store/store.d.ts +8 -3
  73. package/dist/store/store.d.ts.map +1 -1
  74. package/dist/store/store.js +32 -4
  75. package/dist/store/store.js.map +1 -1
  76. package/dist/utils/tests/fixture.d.ts +168 -132
  77. package/dist/utils/tests/fixture.d.ts.map +1 -1
  78. package/package.json +5 -5
  79. package/src/global-state.ts +1 -1
  80. package/src/index.ts +8 -5
  81. package/src/live-queries/__snapshots__/db.test.ts.snap +301 -0
  82. package/src/{reactiveQueries → live-queries}/base-class.ts +10 -5
  83. package/src/{reactiveQueries → live-queries}/computed.ts +5 -29
  84. package/src/live-queries/db.test.ts +153 -0
  85. package/src/live-queries/db.ts +350 -0
  86. package/src/{reactiveQueries → live-queries}/graphql.ts +6 -21
  87. package/src/row-query-utils.ts +65 -0
  88. package/src/store/create-store.ts +1 -1
  89. package/src/store/devtools.ts +1 -1
  90. package/src/store/store-types.ts +2 -2
  91. package/src/store/store.ts +44 -7
  92. package/dist/reactiveQueries/js.d.ts +0 -35
  93. package/dist/reactiveQueries/js.d.ts.map +0 -1
  94. package/dist/reactiveQueries/js.js.map +0 -1
  95. package/dist/store/store-context.d.ts +0 -26
  96. package/dist/store/store-context.d.ts.map +0 -1
  97. package/dist/store/store-context.js +0 -6
  98. package/dist/store/store-context.js.map +0 -1
  99. package/dist/store-context.d.ts +0 -26
  100. package/dist/store-context.d.ts.map +0 -1
  101. package/dist/store-context.js +0 -6
  102. package/dist/store-context.js.map +0 -1
  103. package/dist/store-devtools.d.ts +0 -19
  104. package/dist/store-devtools.d.ts.map +0 -1
  105. package/dist/store-devtools.js +0 -141
  106. package/dist/store-devtools.js.map +0 -1
  107. package/dist/store.d.ts +0 -175
  108. package/dist/store.d.ts.map +0 -1
  109. package/dist/store.js +0 -509
  110. package/dist/store.js.map +0 -1
  111. package/src/reactiveQueries/sql.ts +0 -226
  112. package/src/row-query.ts +0 -196
@@ -1,226 +0,0 @@
1
- import { type Bindable, prepareBindValues, type QueryInfo, type QueryInfoNone } from '@livestore/common'
2
- import { shouldNeverHappen } from '@livestore/utils'
3
- import { Schema, TreeFormatter } from '@livestore/utils/effect'
4
- import * as otel from '@opentelemetry/api'
5
-
6
- import { globalReactivityGraph } from '../global-state.js'
7
- import type { Thunk } from '../reactive.js'
8
- import { NOT_REFRESHED_YET } from '../reactive.js'
9
- import type { RefreshReason } from '../store/store-types.js'
10
- import { getDurationMsFromSpan } from '../utils/otel.js'
11
- import type { GetAtomResult, LiveQuery, QueryContext, ReactivityGraph } from './base-class.js'
12
- import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js'
13
-
14
- /**
15
- * NOTE `querySQL` is only supposed to read data. Don't use it to insert/update/delete data but use mutations instead.
16
- */
17
- export const querySQL = <TResultSchema, TResult = TResultSchema>(
18
- query: string | ((get: GetAtomResult) => string),
19
- options: {
20
- schema: Schema.Schema<TResultSchema, ReadonlyArray<any>>
21
- map?: (rows: TResultSchema) => TResult
22
- /**
23
- * Can be provided explicitly to slightly speed up initial query performance
24
- *
25
- * NOTE In the future we want to do this automatically at build time
26
- */
27
- queriedTables?: Set<string>
28
- bindValues?: Bindable
29
- label?: string
30
- reactivityGraph?: ReactivityGraph
31
- },
32
- ): LiveQuery<TResult, QueryInfoNone> =>
33
- new LiveStoreSQLQuery<TResultSchema, TResult, QueryInfoNone>({
34
- label: options?.label,
35
- genQueryString: query,
36
- queriedTables: options?.queriedTables,
37
- bindValues: options?.bindValues,
38
- reactivityGraph: options?.reactivityGraph,
39
- map: options?.map,
40
- schema: options.schema,
41
- queryInfo: { _tag: 'None' },
42
- })
43
-
44
- /* An object encapsulating a reactive SQL query */
45
- export class LiveStoreSQLQuery<
46
- TResultSchema,
47
- TResult = TResultSchema,
48
- TQueryInfo extends QueryInfo = QueryInfoNone,
49
- > extends LiveStoreQueryBase<TResult, TQueryInfo> {
50
- _tag: 'sql' = 'sql'
51
-
52
- /** A reactive thunk representing the query text */
53
- queryString$: Thunk<string, QueryContext, RefreshReason> | undefined
54
-
55
- /** A reactive thunk representing the query results */
56
- results$: Thunk<TResult, QueryContext, RefreshReason>
57
-
58
- label: string
59
-
60
- protected reactivityGraph
61
-
62
- /** Currently only used by `rowQuery` for lazy table migrations and eager default row insertion */
63
- private execBeforeFirstRun
64
-
65
- private mapResult: (rows: TResultSchema) => TResult
66
- private schema: Schema.Schema<TResultSchema, ReadonlyArray<any>>
67
-
68
- queryInfo: TQueryInfo
69
-
70
- constructor({
71
- genQueryString,
72
- queriedTables,
73
- bindValues,
74
- label = genQueryString.toString(),
75
- reactivityGraph,
76
- schema,
77
- map,
78
- execBeforeFirstRun,
79
- queryInfo,
80
- }: {
81
- label?: string
82
- genQueryString: string | ((get: GetAtomResult, ctx: QueryContext) => string)
83
- queriedTables?: Set<string>
84
- bindValues?: Bindable
85
- reactivityGraph?: ReactivityGraph
86
- schema: Schema.Schema<TResultSchema, ReadonlyArray<any>>
87
- map?: (rows: TResultSchema) => TResult
88
- execBeforeFirstRun?: (ctx: QueryContext) => void
89
- queryInfo?: TQueryInfo
90
- }) {
91
- super()
92
-
93
- this.label = `sql(${label})`
94
- this.reactivityGraph = reactivityGraph ?? globalReactivityGraph
95
- this.execBeforeFirstRun = execBeforeFirstRun
96
- this.queryInfo = queryInfo ?? ({ _tag: 'None' } as TQueryInfo)
97
-
98
- this.schema = schema
99
- this.mapResult = map === undefined ? (rows: any) => rows as TResult : map
100
-
101
- let queryString$OrQueryString: string | Thunk<string, QueryContext, RefreshReason>
102
- if (typeof genQueryString === 'function') {
103
- queryString$OrQueryString = this.reactivityGraph.makeThunk(
104
- (get, setDebugInfo, ctx, otelContext) => {
105
- const startMs = performance.now()
106
- const queryString = genQueryString(makeGetAtomResult(get, otelContext ?? ctx.rootOtelContext), ctx)
107
- const durationMs = performance.now() - startMs
108
- setDebugInfo({ _tag: 'computed', label: `${label}:queryString`, query: queryString, durationMs })
109
- return queryString
110
- },
111
- {
112
- label: `${label}:queryString`,
113
- meta: { liveStoreThunkType: 'sqlQueryString' },
114
- equal: (a, b) => a === b,
115
- },
116
- )
117
-
118
- this.queryString$ = queryString$OrQueryString
119
- } else {
120
- queryString$OrQueryString = genQueryString
121
- }
122
-
123
- const queryLabel = `${label}:results`
124
-
125
- const queriedTablesRef = { current: queriedTables }
126
-
127
- const schemaEqual = Schema.equivalence(schema)
128
- // TODO also support derived equality for `map` (probably will depend on having an easy way to transform a schema without an `encode` step)
129
- // This would mean dropping the `map` option
130
- const equal =
131
- map === undefined
132
- ? (a: TResult, b: TResult) =>
133
- a === NOT_REFRESHED_YET || b === NOT_REFRESHED_YET ? false : schemaEqual(a as any, b as any)
134
- : undefined
135
-
136
- const results$ = this.reactivityGraph.makeThunk<TResult>(
137
- (get, setDebugInfo, { store, otelTracer, rootOtelContext }, otelContext) =>
138
- otelTracer.startActiveSpan(
139
- 'sql:...', // NOTE span name will be overridden further down
140
- {},
141
- otelContext ?? rootOtelContext,
142
- (span) => {
143
- const otelContext = otel.trace.setSpan(otel.context.active(), span)
144
-
145
- if (this.execBeforeFirstRun !== undefined) {
146
- this.execBeforeFirstRun({ store, otelTracer, rootOtelContext, effectsWrapper: (run) => run() })
147
- this.execBeforeFirstRun = undefined
148
- }
149
-
150
- const sqlString =
151
- typeof queryString$OrQueryString === 'string'
152
- ? queryString$OrQueryString
153
- : get(queryString$OrQueryString, otelContext)
154
-
155
- if (queriedTablesRef.current === undefined) {
156
- queriedTablesRef.current = store.syncDbWrapper.getTablesUsed(sqlString)
157
- }
158
-
159
- // Establish a reactive dependency on the tables used in the query
160
- for (const tableName of queriedTablesRef.current) {
161
- const tableRef = store.tableRefs[tableName] ?? shouldNeverHappen(`No table ref found for ${tableName}`)
162
- get(tableRef, otelContext)
163
- }
164
-
165
- span.setAttribute('sql.query', sqlString)
166
- span.updateName(`sql:${sqlString.slice(0, 50)}`)
167
-
168
- const rawResults = store.syncDbWrapper.select<any>(sqlString, {
169
- queriedTables,
170
- bindValues: bindValues ? prepareBindValues(bindValues, sqlString) : undefined,
171
- otelContext,
172
- })
173
-
174
- span.setAttribute('sql.rowsCount', rawResults.length)
175
-
176
- const parsedResult = Schema.decodeEither(this.schema)(rawResults)
177
-
178
- if (parsedResult._tag === 'Left') {
179
- const parseErrorStr = TreeFormatter.formatErrorSync(parsedResult.left)
180
- const expectedSchemaStr = String(this.schema.ast)
181
- const bindValuesStr = bindValues === undefined ? '' : `\nBind values: ${JSON.stringify(bindValues)}`
182
-
183
- console.error(
184
- `\
185
- Error parsing SQL query result.
186
-
187
- Query: ${sqlString}\
188
- ${bindValuesStr}
189
-
190
- Expected schema: ${expectedSchemaStr}
191
-
192
- Error: ${parseErrorStr}
193
-
194
- Result:`,
195
- rawResults,
196
- )
197
- return shouldNeverHappen(`Error parsing SQL query result: ${parsedResult.left}`)
198
- }
199
-
200
- const result = this.mapResult(parsedResult.right)
201
-
202
- span.end()
203
-
204
- const durationMs = getDurationMsFromSpan(span)
205
-
206
- this.executionTimes.push(durationMs)
207
-
208
- setDebugInfo({ _tag: 'sql', label, query: sqlString, durationMs })
209
-
210
- return result
211
- },
212
- ),
213
- { label: queryLabel, equal },
214
- )
215
-
216
- this.results$ = results$
217
- }
218
-
219
- destroy = () => {
220
- if (this.queryString$ !== undefined) {
221
- this.reactivityGraph.destroyNode(this.queryString$)
222
- }
223
-
224
- this.reactivityGraph.destroyNode(this.results$)
225
- }
226
- }
package/src/row-query.ts DELETED
@@ -1,196 +0,0 @@
1
- import type { QueryInfoCol, QueryInfoNone, QueryInfoRow } from '@livestore/common'
2
- import { SessionIdSymbol, sql } from '@livestore/common'
3
- import { DbSchema } from '@livestore/common/schema'
4
- import type { SqliteDsl } from '@livestore/db-schema'
5
- import type { GetValForKey } from '@livestore/utils'
6
- import { shouldNeverHappen } from '@livestore/utils'
7
- import { Schema } from '@livestore/utils/effect'
8
- import type * as otel from '@opentelemetry/api'
9
-
10
- import type {
11
- GetAtomResult,
12
- LiveQuery,
13
- LiveQueryAny,
14
- QueryContext,
15
- ReactivityGraph,
16
- } from './reactiveQueries/base-class.js'
17
- import { computed } from './reactiveQueries/computed.js'
18
- import { LiveStoreSQLQuery } from './reactiveQueries/sql.js'
19
- import type { Store } from './store/store.js'
20
-
21
- export type RowQueryOptions<TTableDef extends DbSchema.TableDef, TResult = RowResult<TTableDef>> = {
22
- otelContext?: otel.Context
23
- skipInsertDefaultRow?: boolean
24
- reactivityGraph?: ReactivityGraph
25
- map?: (result: RowResult<TTableDef>) => TResult
26
- label?: string
27
- }
28
-
29
- export type RowQueryOptionsDefaulValues<TTableDef extends DbSchema.TableDef> = {
30
- defaultValues?: Partial<RowResult<TTableDef>>
31
- }
32
-
33
- export type MakeRowQuery = {
34
- <
35
- TTableDef extends DbSchema.TableDef<
36
- DbSchema.DefaultSqliteTableDef,
37
- boolean,
38
- DbSchema.TableOptions & { isSingleton: true }
39
- >,
40
- TResult = RowResult<TTableDef>,
41
- >(
42
- table: TTableDef,
43
- options?: RowQueryOptions<TTableDef, TResult>,
44
- ): LiveQuery<RowResult<TTableDef>, QueryInfoRow<TTableDef>>
45
- <
46
- TTableDef extends DbSchema.TableDef<
47
- DbSchema.DefaultSqliteTableDef,
48
- boolean,
49
- DbSchema.TableOptions & { isSingleton: false }
50
- >,
51
- TResult = RowResult<TTableDef>,
52
- >(
53
- table: TTableDef,
54
- // TODO adjust so it works with arbitrary primary keys or unique constraints
55
- id: string | SessionIdSymbol,
56
- options?: RowQueryOptions<TTableDef, TResult> & RowQueryOptionsDefaulValues<TTableDef>,
57
- ): LiveQuery<TResult, QueryInfoRow<TTableDef>>
58
- }
59
-
60
- // TODO also allow other where clauses and multiple rows
61
- export const rowQuery: MakeRowQuery = <TTableDef extends DbSchema.TableDef>(
62
- table: TTableDef,
63
- idOrOptions?: string | SessionIdSymbol | RowQueryOptions<TTableDef, any>,
64
- options_?: RowQueryOptions<TTableDef, any> & RowQueryOptionsDefaulValues<TTableDef>,
65
- ) => {
66
- const id = typeof idOrOptions === 'string' || idOrOptions === SessionIdSymbol ? idOrOptions : undefined
67
- const options = typeof idOrOptions === 'string' || idOrOptions === SessionIdSymbol ? options_ : idOrOptions
68
- const defaultValues: Partial<RowResult<TTableDef>> | undefined = (options as any)?.defaultValues ?? {}
69
-
70
- // Validate query args
71
- if (table.options.isSingleton === true && id !== undefined && id !== SessionIdSymbol) {
72
- shouldNeverHappen(`Cannot query state table ${table.sqliteDef.name} with id "${id}" as it is a singleton`)
73
- } else if (table.options.isSingleton !== true && id === undefined) {
74
- shouldNeverHappen(`Cannot query state table ${table.sqliteDef.name} without id`)
75
- }
76
-
77
- const tableSchema = table.sqliteDef
78
- const tableName = tableSchema.name
79
-
80
- const makeQueryString = (id: string | undefined) =>
81
- sql`select * from ${tableName} ${id === undefined ? '' : `where id = '${id}'`} limit 1`
82
-
83
- const genQueryString =
84
- id === SessionIdSymbol
85
- ? (_: GetAtomResult, ctx: QueryContext) => makeQueryString(ctx.store.sessionId)
86
- : makeQueryString(id)
87
-
88
- const rowSchema = table.isSingleColumn === true ? table.schema.pipe(Schema.pluck('value' as any)) : table.schema
89
-
90
- return new LiveStoreSQLQuery({
91
- label:
92
- options?.label ??
93
- `rowQuery:query:${tableSchema.name}${id === undefined ? '' : id === SessionIdSymbol ? `:sessionId` : `:${id}`}`,
94
- genQueryString,
95
- queriedTables: new Set([tableName]),
96
- reactivityGraph: options?.reactivityGraph,
97
- // While this code-path is not needed for singleton tables, it's still needed for `useRow` with non-existing rows for a given ID
98
- execBeforeFirstRun: makeExecBeforeFirstRun({
99
- otelContext: options?.otelContext,
100
- table,
101
- defaultValues,
102
- id,
103
- skipInsertDefaultRow: options?.skipInsertDefaultRow,
104
- }),
105
- schema: rowSchema.pipe(Schema.Array, Schema.headOrElse()),
106
- map: options?.map,
107
- queryInfo: { _tag: 'Row', table, id: id ?? 'singleton' },
108
- })
109
- }
110
-
111
- export type RowResult<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true
112
- ? GetValForKey<SqliteDsl.FromColumns.RowDecoded<TTableDef['sqliteDef']['columns']>, 'value'>
113
- : SqliteDsl.FromColumns.RowDecoded<TTableDef['sqliteDef']['columns']>
114
-
115
- export type RowResultEncoded<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true
116
- ? GetValForKey<SqliteDsl.FromColumns.RowEncoded<TTableDef['sqliteDef']['columns']>, 'value'>
117
- : SqliteDsl.FromColumns.RowEncoded<TTableDef['sqliteDef']['columns']>
118
-
119
- export const deriveColQuery: {
120
- <TQuery extends LiveQuery<any, QueryInfoNone>, TCol extends keyof TQuery['__result!'] & string>(
121
- query$: TQuery,
122
- colName: TCol,
123
- ): LiveQuery<TQuery['__result!'][TCol], QueryInfoNone>
124
- <TQuery extends LiveQuery<any, QueryInfoRow<any>>, TCol extends keyof TQuery['__result!'] & string>(
125
- query$: TQuery,
126
- colName: TCol,
127
- ): LiveQuery<TQuery['__result!'][TCol], QueryInfoCol<TQuery['queryInfo']['table'], TCol>>
128
- } = (query$: LiveQueryAny, colName: string) => {
129
- return computed((get) => get(query$)[colName], {
130
- label: `deriveColQuery:${query$.label}:${colName}`,
131
- queryInfo:
132
- query$.queryInfo._tag === 'Row'
133
- ? { _tag: 'Col', table: query$.queryInfo.table, column: colName, id: query$.queryInfo.id }
134
- : undefined,
135
- }) as any
136
- }
137
-
138
- const makeExecBeforeFirstRun =
139
- ({
140
- id,
141
- defaultValues,
142
- skipInsertDefaultRow,
143
- otelContext: otelContext_,
144
- table,
145
- }: {
146
- id?: string | SessionIdSymbol
147
- defaultValues?: any
148
- skipInsertDefaultRow?: boolean
149
- otelContext?: otel.Context
150
- table: DbSchema.TableDef
151
- }) =>
152
- ({ store }: QueryContext) => {
153
- const otelContext = otelContext_ ?? store.otel.queriesSpanContext
154
-
155
- if (skipInsertDefaultRow !== true && table.options.isSingleton === false) {
156
- insertRowWithDefaultValuesOrIgnore({
157
- store,
158
- id: id!,
159
- table,
160
- otelContext,
161
- explicitDefaultValues: defaultValues,
162
- })
163
- }
164
- }
165
-
166
- const insertRowWithDefaultValuesOrIgnore = ({
167
- store,
168
- id,
169
- table,
170
- otelContext,
171
- explicitDefaultValues,
172
- }: {
173
- store: Store
174
- id: string | SessionIdSymbol
175
- table: DbSchema.TableDef
176
- otelContext: otel.Context
177
- explicitDefaultValues: Partial<RowResult<DbSchema.TableDef>> | undefined
178
- }) => {
179
- const idStr = id === SessionIdSymbol ? store.sessionId : id
180
- const rowExists =
181
- store.syncDbWrapper.select(`select 1 from ${table.sqliteDef.name} where id = '${idStr}'`).length === 1
182
-
183
- if (rowExists) return
184
-
185
- // const mutationDef = deriveCreateMutationDef(table)
186
- if (DbSchema.tableHasDerivedMutations(table) === false) {
187
- return shouldNeverHappen(
188
- `Cannot insert row for table "${table.sqliteDef.name}" which does not have 'deriveMutations: true' set`,
189
- )
190
- }
191
- // NOTE It's important that we only mutate and don't refresh here, as this function is called during a render
192
- store.mutateWithoutRefresh(table.insert({ id, ...explicitDefaultValues }), {
193
- otelContext,
194
- coordinatorMode: 'default',
195
- })
196
- }