@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.
- package/README.md +3 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/MainDatabaseWrapper.d.ts +2 -2
- package/dist/MainDatabaseWrapper.d.ts.map +1 -1
- package/dist/MainDatabaseWrapper.js.map +1 -1
- package/dist/__tests__/react/fixture.d.ts +262 -158
- package/dist/__tests__/react/fixture.d.ts.map +1 -1
- package/dist/__tests__/react/fixture.js +14 -12
- package/dist/__tests__/react/fixture.js.map +1 -1
- package/dist/__tests__/react/utils/otel.d.ts +1 -1
- package/dist/__tests__/react/utils/otel.d.ts.map +1 -1
- package/dist/effect/LiveStore.d.ts +5 -5
- package/dist/effect/LiveStore.d.ts.map +1 -1
- package/dist/effect/LiveStore.js +5 -4
- package/dist/effect/LiveStore.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/react/LiveStoreProvider.d.ts +4 -4
- package/dist/react/LiveStoreProvider.d.ts.map +1 -1
- package/dist/react/LiveStoreProvider.js +8 -8
- package/dist/react/LiveStoreProvider.js.map +1 -1
- package/dist/react/LiveStoreProvider.test.js +3 -4
- package/dist/react/LiveStoreProvider.test.js.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/useAtom.d.ts +5 -2
- package/dist/react/useAtom.d.ts.map +1 -1
- package/dist/react/useAtom.js +20 -4
- package/dist/react/useAtom.js.map +1 -1
- package/dist/react/useLocalId.d.ts +10 -0
- package/dist/react/useLocalId.d.ts.map +1 -0
- package/dist/react/useLocalId.js +20 -0
- package/dist/react/useLocalId.js.map +1 -0
- package/dist/react/useQuery.test.js +7 -7
- package/dist/react/useQuery.test.js.map +1 -1
- package/dist/react/useRow.d.ts +3 -1
- package/dist/react/useRow.d.ts.map +1 -1
- package/dist/react/useRow.js +25 -8
- package/dist/react/useRow.js.map +1 -1
- package/dist/react/useRow.test.js +58 -29
- package/dist/react/useRow.test.js.map +1 -1
- package/dist/react/useTemporaryQuery.d.ts +1 -1
- package/dist/react/useTemporaryQuery.d.ts.map +1 -1
- package/dist/react/useTemporaryQuery.js.map +1 -1
- package/dist/react/useTemporaryQuery.test.js +3 -3
- package/dist/react/useTemporaryQuery.test.js.map +1 -1
- package/dist/react/utils/useStateRefWithReactiveInput.d.ts.map +1 -1
- package/dist/reactive.test.js +1 -1
- package/dist/reactive.test.js.map +1 -1
- package/dist/reactiveQueries/base-class.d.ts +1 -1
- package/dist/reactiveQueries/base-class.d.ts.map +1 -1
- package/dist/reactiveQueries/base-class.js.map +1 -1
- package/dist/reactiveQueries/graphql.d.ts +4 -4
- package/dist/reactiveQueries/graphql.d.ts.map +1 -1
- package/dist/reactiveQueries/graphql.js +2 -1
- package/dist/reactiveQueries/graphql.js.map +1 -1
- package/dist/reactiveQueries/js.d.ts +1 -1
- package/dist/reactiveQueries/js.d.ts.map +1 -1
- package/dist/reactiveQueries/js.js.map +1 -1
- package/dist/reactiveQueries/sql.d.ts +1 -1
- package/dist/reactiveQueries/sql.d.ts.map +1 -1
- package/dist/reactiveQueries/sql.js +2 -2
- package/dist/reactiveQueries/sql.js.map +1 -1
- package/dist/row-query.d.ts +3 -3
- package/dist/row-query.d.ts.map +1 -1
- package/dist/row-query.js +47 -34
- package/dist/row-query.js.map +1 -1
- package/dist/store.d.ts +20 -19
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +67 -41
- package/dist/store.js.map +1 -1
- package/dist/utils/bounded-collections.d.ts +1 -1
- package/dist/utils/bounded-collections.d.ts.map +1 -1
- package/dist/utils/util.d.ts +0 -1
- package/dist/utils/util.d.ts.map +1 -1
- package/dist/utils/util.js.map +1 -1
- package/package.json +16 -16
- package/src/MainDatabaseWrapper.ts +3 -3
- package/src/__tests__/react/fixture.tsx +32 -18
- package/src/effect/LiveStore.ts +9 -8
- package/src/index.ts +7 -5
- package/src/react/LiveStoreProvider.test.tsx +5 -5
- package/src/react/LiveStoreProvider.tsx +11 -11
- package/src/react/index.ts +1 -0
- package/src/react/useAtom.ts +31 -5
- package/src/react/useLocalId.ts +30 -0
- package/src/react/useQuery.test.tsx +8 -8
- package/src/react/useRow.test.tsx +60 -35
- package/src/react/useRow.ts +43 -12
- package/src/react/useTemporaryQuery.test.tsx +4 -4
- package/src/react/useTemporaryQuery.ts +1 -1
- package/src/reactive.test.ts +1 -1
- package/src/reactiveQueries/base-class.ts +1 -1
- package/src/reactiveQueries/graphql.ts +3 -2
- package/src/reactiveQueries/js.ts +1 -1
- package/src/reactiveQueries/sql.ts +3 -3
- package/src/row-query.ts +67 -55
- package/src/store.ts +89 -59
- package/src/utils/util.ts +0 -2
- package/dist/cud.d.ts +0 -28
- package/dist/cud.d.ts.map +0 -1
- package/dist/cud.js +0 -47
- package/dist/cud.js.map +0 -1
- package/dist/cud.test.d.ts +0 -2
- package/dist/cud.test.d.ts.map +0 -1
- package/dist/cud.test.js +0 -47
- package/dist/cud.test.js.map +0 -1
- package/dist/migrations.d.ts +0 -16
- package/dist/migrations.d.ts.map +0 -1
- package/dist/migrations.js +0 -98
- package/dist/migrations.js.map +0 -1
- package/dist/query-info.d.ts +0 -48
- package/dist/query-info.d.ts.map +0 -1
- package/dist/query-info.js +0 -39
- package/dist/query-info.js.map +0 -1
- package/src/cud.test.ts +0 -52
- package/src/cud.ts +0 -88
- package/src/migrations.ts +0 -151
- 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,
|
|
11
|
+
const { wrapper, store, makeRenderCount } = await makeTodoMvc()
|
|
12
12
|
|
|
13
13
|
const renderCount = makeRenderCount()
|
|
14
14
|
|
|
15
15
|
store.mutate(
|
|
16
|
-
|
|
17
|
-
|
|
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'
|
package/src/reactive.test.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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 {
|
|
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 {
|
|
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
|
|
71
|
-
const
|
|
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 ${
|
|
73
|
+
const queryStr = sql`select * from ${tableName} ${whereClause} limit 1`
|
|
75
74
|
|
|
76
75
|
return new LiveStoreSQLQuery({
|
|
77
|
-
label: `rowQuery:query:${
|
|
76
|
+
label: `rowQuery:query:${tableSchema.name}${id === undefined ? '' : `:${id}`}`,
|
|
78
77
|
genQueryString: queryStr,
|
|
79
|
-
queriedTables: new Set([
|
|
78
|
+
queriedTables: new Set([tableName]),
|
|
80
79
|
dbGraph: options?.dbGraph,
|
|
81
|
-
//
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
139
|
+
tableName,
|
|
170
140
|
}: {
|
|
171
141
|
id?: string
|
|
172
142
|
defaultValues?: any
|
|
173
143
|
skipInsertDefaultRow?: boolean
|
|
174
144
|
otelContext?: otel.Context
|
|
175
|
-
|
|
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
|
|
182
|
-
if (store.tableRefs[
|
|
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 = '${
|
|
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
|
|
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:${
|
|
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[
|
|
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
|
|
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
|
+
}
|