@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
@@ -1,20 +1,20 @@
1
1
  import { renderHook } from '@testing-library/react'
2
2
  import { describe, expect, it } from 'vitest'
3
3
 
4
- import { makeTodoMvc, parseTodos } from '../__tests__/react/fixture.js'
4
+ import { makeTodoMvc, parseTodos, todos } from '../__tests__/react/fixture.js'
5
5
  import type * as LiveStore from '../index.js'
6
6
  import { querySQL } from '../reactiveQueries/sql.js'
7
7
  import * as LiveStoreReact from './index.js'
8
8
 
9
9
  describe('useTemporaryQuery', () => {
10
10
  it('simple', async () => {
11
- const { wrapper, store, cud, makeRenderCount } = await makeTodoMvc()
11
+ const { wrapper, store, makeRenderCount } = await makeTodoMvc()
12
12
 
13
13
  const renderCount = makeRenderCount()
14
14
 
15
15
  store.mutate(
16
- cud.todos.insert({ id: 't1', text: 'buy milk', completed: false }),
17
- cud.todos.insert({ id: 't2', text: 'buy bread', completed: false }),
16
+ todos.insert({ id: 't1', text: 'buy milk', completed: false }),
17
+ todos.insert({ id: 't2', text: 'buy bread', completed: false }),
18
18
  )
19
19
 
20
20
  const queryMap = new Map<string, LiveStore.LiveQuery<any>>()
@@ -1,7 +1,7 @@
1
+ import type { QueryInfo } from '@livestore/common'
1
2
  import * as otel from '@opentelemetry/api'
2
3
  import React from 'react'
3
4
 
4
- import type { QueryInfo } from '../query-info.js'
5
5
  import type { LiveQuery } from '../reactiveQueries/base-class.js'
6
6
  import { useStore } from './LiveStoreContext.js'
7
7
  import { useQueryRef } from './useQuery.js'
@@ -245,7 +245,7 @@ describe('a trivial graph', () => {
245
245
  expect(e.isDirty).toBe(true)
246
246
 
247
247
  expect(() => c.computeResult()).toThrowErrorMatchingInlineSnapshot(
248
- `[Error: This should never happen LiveStore Error: Attempted to compute destroyed ref (node-58): b]`,
248
+ `[Error: This should never happen: LiveStore Error: Attempted to compute destroyed ref (node-58): b]`,
249
249
  )
250
250
  })
251
251
  })
@@ -1,7 +1,7 @@
1
+ import type { QueryInfo, QueryInfoNone } from '@livestore/common'
1
2
  import type * as otel from '@opentelemetry/api'
2
3
  import ReactDOM from 'react-dom'
3
4
 
4
- import type { QueryInfo, QueryInfoNone } from '../query-info.js'
5
5
  import type { StackInfo } from '../react/utils/stack-info.js'
6
6
  import { type Atom, type GetAtom, ReactiveGraph, throwContextNotSetError, type Thunk } from '../reactive.js'
7
7
  import type { QueryDebugInfo, RefreshReason, Store } from '../store.js'
@@ -1,11 +1,11 @@
1
1
  import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'
2
+ import type { QueryInfoNone } from '@livestore/common'
2
3
  import { shouldNeverHappen } from '@livestore/utils'
3
4
  import { Schema, TreeFormatter } from '@livestore/utils/effect'
4
5
  import * as otel from '@opentelemetry/api'
5
6
  import * as graphql from 'graphql'
6
7
 
7
8
  import { globalDbGraph } from '../global-state.js'
8
- import type { QueryInfoNone } from '../query-info.js'
9
9
  import { isThunk, type Thunk } from '../reactive.js'
10
10
  import type { BaseGraphQLContext, RefreshReason, Store } from '../store.js'
11
11
  import { getDurationMsFromSpan } from '../utils/otel.js'
@@ -78,7 +78,7 @@ export class LiveStoreGraphQLQuery<
78
78
  ? (res: TResult) => {
79
79
  const parseResult = Schema.decodeEither(map as Schema.Schema<TResultMapped, TResult>)(res)
80
80
  if (parseResult._tag === 'Left') {
81
- console.error(`Error parsing GraphQL query result: ${TreeFormatter.formatError(parseResult.left)}`)
81
+ console.error(`Error parsing GraphQL query result: ${TreeFormatter.formatErrorSync(parseResult.left)}`)
82
82
  return shouldNeverHappen(`Error parsing SQL query result: ${parseResult.left}`)
83
83
  } else {
84
84
  return parseResult.right as TResultMapped
@@ -196,6 +196,7 @@ export class LiveStoreGraphQLQuery<
196
196
  console.error(error)
197
197
  }
198
198
  debugger
199
+ shouldNeverHappen(`GraphQL error: ${res.errors.join('\n')}`)
199
200
  }
200
201
 
201
202
  span.end()
@@ -1,7 +1,7 @@
1
+ import type { QueryInfo, QueryInfoNone } from '@livestore/common'
1
2
  import * as otel from '@opentelemetry/api'
2
3
 
3
4
  import { globalDbGraph } from '../global-state.js'
4
- import type { QueryInfo, QueryInfoNone } from '../query-info.js'
5
5
  import type { Thunk } from '../reactive.js'
6
6
  import type { RefreshReason } from '../store.js'
7
7
  import { getDurationMsFromSpan } from '../utils/otel.js'
@@ -1,9 +1,9 @@
1
+ import type { QueryInfo, QueryInfoNone } from '@livestore/common'
1
2
  import { shouldNeverHappen } from '@livestore/utils'
2
3
  import { Schema, TreeFormatter } from '@livestore/utils/effect'
3
4
  import * as otel from '@opentelemetry/api'
4
5
 
5
6
  import { globalDbGraph } from '../global-state.js'
6
- import type { QueryInfo, QueryInfoNone } from '../query-info.js'
7
7
  import type { Thunk } from '../reactive.js'
8
8
  import type { RefreshReason } from '../store.js'
9
9
  import { getDurationMsFromSpan } from '../utils/otel.js'
@@ -98,7 +98,7 @@ export class LiveStoreSQLQuery<TResult, TQueryInfo extends QueryInfo = QueryInfo
98
98
  ? (rows: any, opts: { sqlString: string }) => {
99
99
  const parseResult = Schema.decodeEither(map as Schema.Schema<TResult, ReadonlyArray<any>>)(rows)
100
100
  if (parseResult._tag === 'Left') {
101
- const parseErrorStr = TreeFormatter.formatError(parseResult.left)
101
+ const parseErrorStr = TreeFormatter.formatErrorSync(parseResult.left)
102
102
  const expectedSchemaStr = String(map.ast)
103
103
  const bindValuesStr = bindValues === undefined ? '' : `\nBind values: ${JSON.stringify(bindValues)}`
104
104
 
@@ -116,7 +116,7 @@ Error: ${parseErrorStr}
116
116
  Result:`,
117
117
  rows,
118
118
  )
119
- // console.error(`Error parsing SQL query result: ${TreeFormatter.formatError(parseResult.left)}`)
119
+ // console.error(`Error parsing SQL query result: ${TreeFormatter.formatErrorSync(parseResult.left)}`)
120
120
  return shouldNeverHappen(`Error parsing SQL query result: ${parseResult.left}`)
121
121
  } else {
122
122
  return parseResult.right as TResult
package/src/row-query.ts CHANGED
@@ -1,19 +1,18 @@
1
- import { sql } from '@livestore/common'
1
+ import type { InMemoryDatabase, QueryInfoCol, QueryInfoNone, QueryInfoRow } from '@livestore/common'
2
+ import { migrateTable, sql } from '@livestore/common'
2
3
  import { DbSchema, SCHEMA_META_TABLE } from '@livestore/common/schema'
4
+ import type { GetValForKey } from '@livestore/utils'
3
5
  import { shouldNeverHappen } from '@livestore/utils'
4
6
  import { Schema, TreeFormatter } from '@livestore/utils/effect'
5
7
  import type * as otel from '@opentelemetry/api'
6
- import { SqliteAst, SqliteDsl } from 'effect-db-schema'
8
+ import type { SqliteDsl } from 'effect-db-schema'
9
+ import { SqliteAst } from 'effect-db-schema'
7
10
 
8
- import { migrateTable } from './migrations.js'
9
- import type { QueryInfoCol, QueryInfoNone, QueryInfoRow } from './query-info.js'
10
11
  import type { Ref } from './reactive.js'
11
12
  import type { DbContext, DbGraph, LiveQuery, LiveQueryAny } from './reactiveQueries/base-class.js'
12
13
  import { computed } from './reactiveQueries/js.js'
13
- // import type { LiveStoreJSQuery } from './reactiveQueries/js.js'
14
14
  import { LiveStoreSQLQuery } from './reactiveQueries/sql.js'
15
15
  import type { RefreshReason, Store } from './store.js'
16
- import type { GetValForKey } from './utils/util.js'
17
16
 
18
17
  export type RowQueryOptions = {
19
18
  otelContext?: otel.Context
@@ -67,24 +66,22 @@ export const rowQuery: MakeRowQuery = <TTableDef extends DbSchema.TableDef>(
67
66
  shouldNeverHappen(`Cannot query state table ${table.sqliteDef.name} without id`)
68
67
  }
69
68
 
70
- const stateSchema = table.sqliteDef
71
- const componentTableName = stateSchema.name
69
+ const tableSchema = table.sqliteDef
70
+ const tableName = tableSchema.name
72
71
 
73
72
  const whereClause = id === undefined ? '' : `where id = '${id}'`
74
- const queryStr = sql`select * from ${componentTableName} ${whereClause} limit 1`
73
+ const queryStr = sql`select * from ${tableName} ${whereClause} limit 1`
75
74
 
76
75
  return new LiveStoreSQLQuery({
77
- label: `rowQuery:query:${stateSchema.name}${id === undefined ? '' : `:${id}`}`,
76
+ label: `rowQuery:query:${tableSchema.name}${id === undefined ? '' : `:${id}`}`,
78
77
  genQueryString: queryStr,
79
- queriedTables: new Set([componentTableName]),
78
+ queriedTables: new Set([tableName]),
80
79
  dbGraph: options?.dbGraph,
81
- // TODO remove this once the LiveStore Devtools are no longer relying on it
82
- // as the defaults rows are now already being inserted during store initialization
83
- // and the tables need to be registered during initialization
80
+ // While this code-path is not needed for singleton tables, it's still needed for `useRow` with non-existing rows for a given ID
84
81
  execBeforeFirstRun: makeExecBeforeFirstRun({
85
82
  otelContext: options?.otelContext,
86
83
  table,
87
- componentTableName,
84
+ tableName,
88
85
  defaultValues,
89
86
  id,
90
87
  skipInsertDefaultRow: options?.skipInsertDefaultRow,
@@ -92,11 +89,10 @@ export const rowQuery: MakeRowQuery = <TTableDef extends DbSchema.TableDef>(
92
89
  map: (results): RowResult<TTableDef> => {
93
90
  if (results.length === 0) return shouldNeverHappen(`No results for query ${queryStr}`)
94
91
 
95
- const componentStateEffectSchema = SqliteDsl.structSchemaForTable(stateSchema)
96
- const parseResult = Schema.decodeEither(componentStateEffectSchema)(results[0]!)
92
+ const parseResult = Schema.decodeEither(table.schema)(results[0]!)
97
93
 
98
94
  if (parseResult._tag === 'Left') {
99
- console.error('decode error', TreeFormatter.formatError(parseResult.left), 'results', results)
95
+ console.error('decode error', TreeFormatter.formatErrorSync(parseResult.left), 'results', results)
100
96
  return shouldNeverHappen(`Error decoding query result for ${queryStr}`)
101
97
  }
102
98
 
@@ -133,32 +129,6 @@ export const deriveColQuery: {
133
129
  }) as any
134
130
  }
135
131
 
136
- const insertRowWithDefaultValuesOrIgnore = ({
137
- store,
138
- id,
139
- table,
140
- otelContext,
141
- defaultValues: explicitDefaultValues,
142
- }: {
143
- store: Store
144
- id: string
145
- table: DbSchema.TableDef
146
- otelContext: otel.Context
147
- defaultValues: Partial<RowResult<DbSchema.TableDef>> | undefined
148
- }) => {
149
- const defaultValues = DbSchema.getDefaultValuesEncoded(table, explicitDefaultValues)
150
-
151
- const defaultColumnNames = [...Object.keys(defaultValues), 'id']
152
- const columnValues = defaultColumnNames.map((name) => `$${name}`).join(', ')
153
-
154
- const tableName = table.sqliteDef.name
155
- const insertQuery = sql`insert into ${tableName} (${defaultColumnNames.join(
156
- ', ',
157
- )}) select ${columnValues} where not exists(select 1 from ${tableName} where id = '${id}')`
158
-
159
- store.execute(insertQuery, { ...defaultValues, id }, new Set([tableName]), otelContext)
160
- }
161
-
162
132
  const makeExecBeforeFirstRun =
163
133
  ({
164
134
  id,
@@ -166,50 +136,92 @@ const makeExecBeforeFirstRun =
166
136
  skipInsertDefaultRow,
167
137
  otelContext: otelContext_,
168
138
  table,
169
- componentTableName,
139
+ tableName,
170
140
  }: {
171
141
  id?: string
172
142
  defaultValues?: any
173
143
  skipInsertDefaultRow?: boolean
174
144
  otelContext?: otel.Context
175
- componentTableName: string
145
+ tableName: string
176
146
  table: DbSchema.TableDef
177
147
  }) =>
178
148
  ({ store }: DbContext) => {
179
149
  const otelContext = otelContext_ ?? store.otel.queriesSpanContext
180
150
 
181
- // TODO find a better solution for this
182
- if (store.tableRefs[componentTableName] === undefined) {
151
+ // TODO we can remove this codepath again when Devtools v2 has landed
152
+ if (store.tableRefs[tableName] === undefined) {
183
153
  const schemaHash = SqliteAst.hash(table.sqliteDef.ast)
184
154
  const res = store.mainDbWrapper.select<{ schemaHash: number }>(
185
- sql`SELECT schemaHash FROM ${SCHEMA_META_TABLE} WHERE tableName = '${componentTableName}'`,
155
+ sql`SELECT schemaHash FROM ${SCHEMA_META_TABLE} WHERE tableName = '${tableName}'`,
186
156
  )
187
157
  if (res.length === 0 || res[0]!.schemaHash !== schemaHash) {
158
+ const db = {
159
+ ...store.adapter.mainDb,
160
+ prepare: (query) => {
161
+ const mainStmt = store.adapter.mainDb.prepare(query)
162
+ return {
163
+ ...mainStmt,
164
+ execute: (bindValues) => {
165
+ const getRowsChanged = mainStmt.execute(bindValues)
166
+ store.adapter.coordinator.execute(query, bindValues, undefined)
167
+ return getRowsChanged
168
+ },
169
+ }
170
+ },
171
+ } satisfies InMemoryDatabase
172
+
188
173
  migrateTable({
189
- db: store.db,
174
+ db,
190
175
  tableAst: table.sqliteDef.ast,
191
176
  otelContext,
192
177
  schemaHash,
178
+ behaviour: 'create-if-not-exists',
193
179
  })
194
180
  }
195
181
 
196
- const label = `tableRef:${componentTableName}`
182
+ const label = `tableRef:${tableName}`
197
183
 
198
184
  // TODO find a better implementation for this
199
185
  const existingTableRefFromGraph = Array.from(store.graph.atoms.values()).find(
200
186
  (_) => _._tag === 'ref' && _.label === label,
201
187
  ) as Ref<null, DbContext, RefreshReason> | undefined
202
188
 
203
- store.tableRefs[componentTableName] = existingTableRefFromGraph ?? store.makeTableRef(componentTableName)
189
+ store.tableRefs[tableName] = existingTableRefFromGraph ?? store.makeTableRef(tableName)
204
190
  }
205
191
 
206
- if (skipInsertDefaultRow !== true) {
192
+ if (skipInsertDefaultRow !== true && table.options.isSingleton === false) {
207
193
  insertRowWithDefaultValuesOrIgnore({
208
194
  store,
209
- id: id ?? 'singleton',
195
+ id: id!,
210
196
  table,
211
197
  otelContext,
212
- defaultValues,
198
+ explicitDefaultValues: defaultValues,
213
199
  })
214
200
  }
215
201
  }
202
+
203
+ const insertRowWithDefaultValuesOrIgnore = ({
204
+ store,
205
+ id,
206
+ table,
207
+ otelContext,
208
+ explicitDefaultValues,
209
+ }: {
210
+ store: Store
211
+ id: string
212
+ table: DbSchema.TableDef
213
+ otelContext: otel.Context
214
+ explicitDefaultValues: Partial<RowResult<DbSchema.TableDef>> | undefined
215
+ }) => {
216
+ const rowExists = store.mainDbWrapper.select(`select 1 from ${table.sqliteDef.name} where id = '${id}'`).length === 1
217
+ if (rowExists) return
218
+
219
+ // const mutationDef = deriveCreateMutationDef(table)
220
+ if (DbSchema.tableHasDerivedMutations(table) === false) {
221
+ return shouldNeverHappen(
222
+ `Cannot insert row for table "${table.sqliteDef.name}" which does not have 'deriveMutations: true' set`,
223
+ )
224
+ }
225
+ // NOTE It's important that we only mutate and don't refresh here, as this function is called during a render
226
+ store.mutateWithoutRefresh(table.insert({ id, ...explicitDefaultValues }), otelContext)
227
+ }