@livestore/livestore 0.0.24 → 0.0.27
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/dist/.tsbuildinfo +1 -1
- package/dist/QueryCache.d.ts +3 -3
- package/dist/QueryCache.d.ts.map +1 -1
- package/dist/QueryCache.js +50 -60
- package/dist/QueryCache.js.map +1 -1
- package/dist/__tests__/react/fixture.d.ts +22 -7
- package/dist/__tests__/react/fixture.d.ts.map +1 -1
- package/dist/__tests__/react/fixture.js +14 -15
- package/dist/__tests__/react/fixture.js.map +1 -1
- package/dist/__tests__/react/useQuery.test.js +37 -12
- package/dist/__tests__/react/useQuery.test.js.map +1 -1
- package/dist/__tests__/react/useRow.test.d.ts +2 -0
- package/dist/__tests__/react/useRow.test.d.ts.map +1 -0
- package/dist/__tests__/react/useRow.test.js +131 -0
- package/dist/__tests__/react/useRow.test.js.map +1 -0
- package/dist/__tests__/react/utils/stack-info.test.js +32 -0
- package/dist/__tests__/react/utils/stack-info.test.js.map +1 -1
- package/dist/__tests__/reactive.test.js +51 -0
- package/dist/__tests__/reactive.test.js.map +1 -1
- package/dist/__tests__/reactiveQueries/sql.test.js +6 -13
- package/dist/__tests__/reactiveQueries/sql.test.js.map +1 -1
- package/dist/effect/LiveStore.d.ts +3 -3
- package/dist/effect/LiveStore.d.ts.map +1 -1
- package/dist/effect/LiveStore.js +2 -2
- package/dist/effect/LiveStore.js.map +1 -1
- package/dist/global-state.d.ts +19 -0
- package/dist/global-state.d.ts.map +1 -0
- package/dist/global-state.js +20 -0
- package/dist/global-state.js.map +1 -0
- package/dist/inMemoryDatabase.d.ts +6 -6
- package/dist/inMemoryDatabase.d.ts.map +1 -1
- package/dist/inMemoryDatabase.js +16 -10
- package/dist/inMemoryDatabase.js.map +1 -1
- package/dist/index.d.ts +9 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -8
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts +4 -4
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +34 -28
- package/dist/migrations.js.map +1 -1
- package/dist/react/LiveStoreContext.js.map +1 -1
- package/dist/react/LiveStoreProvider.d.ts +2 -2
- package/dist/react/LiveStoreProvider.d.ts.map +1 -1
- package/dist/react/LiveStoreProvider.js.map +1 -1
- package/dist/react/index.d.ts +1 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/useQuery.d.ts +3 -0
- package/dist/react/useQuery.d.ts.map +1 -1
- package/dist/react/useQuery.js +7 -6
- package/dist/react/useQuery.js.map +1 -1
- package/dist/react/useRow.d.ts +33 -0
- package/dist/react/useRow.d.ts.map +1 -0
- package/dist/react/useRow.js +136 -0
- package/dist/react/useRow.js.map +1 -0
- package/dist/react/useTemporaryQuery.d.ts +2 -0
- package/dist/react/useTemporaryQuery.d.ts.map +1 -1
- package/dist/react/useTemporaryQuery.js +28 -11
- package/dist/react/useTemporaryQuery.js.map +1 -1
- package/dist/react/utils/stack-info.d.ts.map +1 -1
- package/dist/react/utils/stack-info.js +3 -3
- package/dist/react/utils/stack-info.js.map +1 -1
- package/dist/react/utils/useStateRefWithReactiveInput.js.map +1 -1
- package/dist/reactive.d.ts +38 -29
- package/dist/reactive.d.ts.map +1 -1
- package/dist/reactive.js +73 -45
- package/dist/reactive.js.map +1 -1
- package/dist/reactiveQueries/base-class.d.ts +10 -6
- package/dist/reactiveQueries/base-class.d.ts.map +1 -1
- package/dist/reactiveQueries/base-class.js +11 -12
- package/dist/reactiveQueries/base-class.js.map +1 -1
- package/dist/reactiveQueries/graphql.d.ts +2 -2
- package/dist/reactiveQueries/graphql.d.ts.map +1 -1
- package/dist/reactiveQueries/graphql.js +56 -50
- package/dist/reactiveQueries/graphql.js.map +1 -1
- package/dist/reactiveQueries/js.d.ts +7 -3
- package/dist/reactiveQueries/js.d.ts.map +1 -1
- package/dist/reactiveQueries/js.js +25 -15
- package/dist/reactiveQueries/js.js.map +1 -1
- package/dist/reactiveQueries/sql.d.ts +5 -5
- package/dist/reactiveQueries/sql.d.ts.map +1 -1
- package/dist/reactiveQueries/sql.js +39 -34
- package/dist/reactiveQueries/sql.js.map +1 -1
- package/dist/row-query.d.ts +21 -0
- package/dist/row-query.d.ts.map +1 -0
- package/dist/row-query.js +77 -0
- package/dist/row-query.js.map +1 -0
- package/dist/schema/action.d.ts +30 -0
- package/dist/schema/action.d.ts.map +1 -0
- package/dist/schema/action.js +3 -0
- package/dist/schema/action.js.map +1 -0
- package/dist/schema/index.d.ts +28 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +26 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/system-tables.d.ts +24 -0
- package/dist/schema/system-tables.d.ts.map +1 -0
- package/dist/schema/system-tables.js +11 -0
- package/dist/schema/system-tables.js.map +1 -0
- package/dist/schema/table-def.d.ts +161 -0
- package/dist/schema/table-def.d.ts.map +1 -0
- package/dist/schema/table-def.js +53 -0
- package/dist/schema/table-def.js.map +1 -0
- package/dist/storage/in-memory/index.d.ts +1 -1
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/in-memory/index.js +6 -7
- package/dist/storage/in-memory/index.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/tauri/index.d.ts +1 -1
- package/dist/storage/tauri/index.d.ts.map +1 -1
- package/dist/storage/tauri/index.js +25 -23
- package/dist/storage/tauri/index.js.map +1 -1
- package/dist/storage/utils/idb.js +3 -1
- package/dist/storage/utils/idb.js.map +1 -1
- package/dist/storage/web-worker/index.d.ts +1 -1
- package/dist/storage/web-worker/index.d.ts.map +1 -1
- package/dist/storage/web-worker/index.js +38 -34
- package/dist/storage/web-worker/index.js.map +1 -1
- package/dist/storage/web-worker/worker.d.ts +1 -1
- package/dist/storage/web-worker/worker.d.ts.map +1 -1
- package/dist/storage/web-worker/worker.js +1 -1
- package/dist/storage/web-worker/worker.js.map +1 -1
- package/dist/store.d.ts +11 -21
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +284 -272
- package/dist/store.js.map +1 -1
- package/dist/utils/bounded-collections.d.ts.map +1 -0
- package/dist/utils/bounded-collections.js +90 -0
- package/dist/utils/bounded-collections.js.map +1 -0
- package/dist/utils/otel.d.ts.map +1 -0
- package/dist/{otel.js → utils/otel.js} +1 -1
- package/dist/utils/otel.js.map +1 -0
- package/dist/utils/util.d.ts.map +1 -0
- package/dist/utils/util.js.map +1 -0
- package/package.json +21 -18
- package/src/QueryCache.ts +4 -4
- package/src/__tests__/react/fixture.tsx +17 -17
- package/src/__tests__/react/useQuery.test.tsx +56 -14
- package/src/__tests__/react/useRow.test.tsx +205 -0
- package/src/__tests__/react/utils/stack-info.test.ts +34 -0
- package/src/__tests__/reactive.test.ts +71 -0
- package/src/__tests__/reactiveQueries/sql.test.ts +6 -13
- package/src/effect/LiveStore.ts +7 -7
- package/src/global-state.ts +26 -0
- package/src/inMemoryDatabase.ts +14 -12
- package/src/index.ts +22 -29
- package/src/migrations.ts +41 -35
- package/src/react/LiveStoreProvider.tsx +2 -2
- package/src/react/index.ts +7 -9
- package/src/react/useQuery.ts +12 -6
- package/src/react/useRow.ts +221 -0
- package/src/react/useTemporaryQuery.ts +43 -11
- package/src/react/utils/stack-info.ts +4 -3
- package/src/reactive.ts +81 -65
- package/src/reactiveQueries/base-class.ts +14 -10
- package/src/reactiveQueries/graphql.ts +4 -3
- package/src/reactiveQueries/js.ts +9 -5
- package/src/reactiveQueries/sql.ts +9 -9
- package/src/row-query.ts +142 -0
- package/src/schema/action.ts +41 -0
- package/src/schema/index.ts +63 -0
- package/src/schema/system-tables.ts +21 -0
- package/src/schema/table-def.ts +199 -0
- package/src/storage/in-memory/index.ts +1 -1
- package/src/storage/index.ts +2 -1
- package/src/storage/tauri/index.ts +2 -2
- package/src/storage/web-worker/index.ts +1 -1
- package/src/storage/web-worker/worker.ts +2 -2
- package/src/store.ts +51 -51
- package/dist/__tests__/react/useComponentState.test.d.ts +0 -2
- package/dist/__tests__/react/useComponentState.test.d.ts.map +0 -1
- package/dist/__tests__/react/useComponentState.test.js +0 -68
- package/dist/__tests__/react/useComponentState.test.js.map +0 -1
- package/dist/__tests__/react/useLQuery.test.d.ts +0 -2
- package/dist/__tests__/react/useLQuery.test.d.ts.map +0 -1
- package/dist/__tests__/react/useLQuery.test.js +0 -38
- package/dist/__tests__/react/useLQuery.test.js.map +0 -1
- package/dist/__tests__/react/useLiveStoreComponent.test.d.ts +0 -2
- package/dist/__tests__/react/useLiveStoreComponent.test.d.ts.map +0 -1
- package/dist/__tests__/react/useLiveStoreComponent.test.js +0 -73
- package/dist/__tests__/react/useLiveStoreComponent.test.js.map +0 -1
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.d.ts +0 -2
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.d.ts.map +0 -1
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.js +0 -38
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.js.map +0 -1
- package/dist/bounded-collections.d.ts.map +0 -1
- package/dist/bounded-collections.js +0 -103
- package/dist/bounded-collections.js.map +0 -1
- package/dist/componentKey.d.ts +0 -20
- package/dist/componentKey.d.ts.map +0 -1
- package/dist/componentKey.js +0 -3
- package/dist/componentKey.js.map +0 -1
- package/dist/otel.d.ts.map +0 -1
- package/dist/otel.js.map +0 -1
- package/dist/react/useComponentState.d.ts +0 -50
- package/dist/react/useComponentState.d.ts.map +0 -1
- package/dist/react/useComponentState.js +0 -240
- package/dist/react/useComponentState.js.map +0 -1
- package/dist/react/useGlobalQuery.d.ts +0 -3
- package/dist/react/useGlobalQuery.d.ts.map +0 -1
- package/dist/react/useGlobalQuery.js +0 -26
- package/dist/react/useGlobalQuery.js.map +0 -1
- package/dist/react/useGraphQL.d.ts +0 -13
- package/dist/react/useGraphQL.d.ts.map +0 -1
- package/dist/react/useGraphQL.js +0 -87
- package/dist/react/useGraphQL.js.map +0 -1
- package/dist/react/useLiveStoreComponent.d.ts +0 -75
- package/dist/react/useLiveStoreComponent.d.ts.map +0 -1
- package/dist/react/useLiveStoreComponent.js +0 -361
- package/dist/react/useLiveStoreComponent.js.map +0 -1
- package/dist/react/utils/extractNamesFromStackTrace.d.ts +0 -3
- package/dist/react/utils/extractNamesFromStackTrace.d.ts.map +0 -1
- package/dist/react/utils/extractNamesFromStackTrace.js +0 -40
- package/dist/react/utils/extractNamesFromStackTrace.js.map +0 -1
- package/dist/react/utils/extractStackInfoFromStackTrace.d.ts +0 -7
- package/dist/react/utils/extractStackInfoFromStackTrace.d.ts.map +0 -1
- package/dist/react/utils/extractStackInfoFromStackTrace.js +0 -40
- package/dist/react/utils/extractStackInfoFromStackTrace.js.map +0 -1
- package/dist/reactiveQueries/graph.d.ts +0 -10
- package/dist/reactiveQueries/graph.d.ts.map +0 -1
- package/dist/reactiveQueries/graph.js +0 -6
- package/dist/reactiveQueries/graph.js.map +0 -1
- package/dist/schema.d.ts +0 -81
- package/dist/schema.d.ts.map +0 -1
- package/dist/schema.js +0 -46
- package/dist/schema.js.map +0 -1
- package/dist/util.d.ts.map +0 -1
- package/dist/util.js.map +0 -1
- package/src/__tests__/react/useComponentState.test.tsx +0 -100
- package/src/componentKey.ts +0 -9
- package/src/react/useComponentState.ts +0 -404
- package/src/reactiveQueries/graph.ts +0 -15
- package/src/schema.ts +0 -143
- /package/dist/{bounded-collections.d.ts → utils/bounded-collections.d.ts} +0 -0
- /package/dist/{otel.d.ts → utils/otel.d.ts} +0 -0
- /package/dist/{util.d.ts → utils/util.d.ts} +0 -0
- /package/dist/{util.js → utils/util.js} +0 -0
- /package/src/{bounded-collections.ts → utils/bounded-collections.ts} +0 -0
- /package/src/{otel.ts → utils/otel.ts} +0 -0
- /package/src/{util.ts → utils/util.ts} +0 -0
|
@@ -3,11 +3,12 @@ import { assertNever, shouldNeverHappen } from '@livestore/utils'
|
|
|
3
3
|
import * as otel from '@opentelemetry/api'
|
|
4
4
|
import * as graphql from 'graphql'
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { dbGraph } from '../global-state.js'
|
|
7
7
|
import type { Thunk } from '../reactive.js'
|
|
8
8
|
import type { BaseGraphQLContext, RefreshReason, Store } from '../store.js'
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { getDurationMsFromSpan } from '../utils/otel.js'
|
|
10
|
+
import type { DbContext, GetAtomResult } from './base-class.js'
|
|
11
|
+
import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js'
|
|
11
12
|
import { LiveStoreJSQuery } from './js.js'
|
|
12
13
|
|
|
13
14
|
export const queryGraphQL = <TResult extends Record<string, any>, TVariableValues extends Record<string, any>>(
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as otel from '@opentelemetry/api'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { dbGraph } from '../global-state.js'
|
|
4
4
|
import type { Thunk } from '../reactive.js'
|
|
5
5
|
import type { RefreshReason } from '../store.js'
|
|
6
|
-
import {
|
|
7
|
-
import type
|
|
8
|
-
import { dbGraph } from './graph.js'
|
|
6
|
+
import { getDurationMsFromSpan } from '../utils/otel.js'
|
|
7
|
+
import { type DbContext, type GetAtomResult, LiveStoreQueryBase, makeGetAtomResult } from './base-class.js'
|
|
9
8
|
|
|
10
9
|
export const queryJS = <TResult>(fn: (get: GetAtomResult) => TResult, options: { label: string }) =>
|
|
11
10
|
new LiveStoreJSQuery<TResult>({ fn, label: options.label })
|
|
@@ -18,7 +17,12 @@ export class LiveStoreJSQuery<TResult> extends LiveStoreQueryBase<TResult> {
|
|
|
18
17
|
|
|
19
18
|
label: string
|
|
20
19
|
|
|
21
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Currently only used for "nested destruction" of piped queries
|
|
22
|
+
*
|
|
23
|
+
* i.e. when doing something like `const q = querySQL(...).pipe(...)`
|
|
24
|
+
* we need to also destory the SQL query when the JS query `q` is destroyed
|
|
25
|
+
*/
|
|
22
26
|
private onDestroy: (() => void) | undefined
|
|
23
27
|
|
|
24
28
|
constructor({
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { shouldNeverHappen } from '@livestore/utils'
|
|
2
2
|
import * as otel from '@opentelemetry/api'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { dbGraph } from '../global-state.js'
|
|
5
5
|
import type { Thunk } from '../reactive.js'
|
|
6
6
|
import type { RefreshReason } from '../store.js'
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import type { DbContext } from './
|
|
11
|
-
import {
|
|
7
|
+
import { getDurationMsFromSpan } from '../utils/otel.js'
|
|
8
|
+
import type { Bindable } from '../utils/util.js'
|
|
9
|
+
import { prepareBindValues } from '../utils/util.js'
|
|
10
|
+
import type { DbContext, GetAtomResult } from './base-class.js'
|
|
11
|
+
import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js'
|
|
12
12
|
import { LiveStoreJSQuery } from './js.js'
|
|
13
13
|
|
|
14
14
|
export const querySQL = <Row>(
|
|
@@ -19,7 +19,7 @@ export const querySQL = <Row>(
|
|
|
19
19
|
*
|
|
20
20
|
* NOTE In the future we want to do this automatically at build time
|
|
21
21
|
*/
|
|
22
|
-
queriedTables?:
|
|
22
|
+
queriedTables?: Set<string>
|
|
23
23
|
bindValues?: Bindable
|
|
24
24
|
label?: string
|
|
25
25
|
},
|
|
@@ -51,7 +51,7 @@ export class LiveStoreSQLQuery<Row> extends LiveStoreQueryBase<ReadonlyArray<Row
|
|
|
51
51
|
}: {
|
|
52
52
|
label?: string
|
|
53
53
|
genQueryString: string | ((get: GetAtomResult) => string)
|
|
54
|
-
queriedTables?:
|
|
54
|
+
queriedTables?: Set<string>
|
|
55
55
|
bindValues?: Bindable
|
|
56
56
|
}) {
|
|
57
57
|
super()
|
|
@@ -150,7 +150,7 @@ export class LiveStoreSQLQuery<Row> extends LiveStoreQueryBase<ReadonlyArray<Row
|
|
|
150
150
|
if (results.length === 0 && args?.defaultValue === undefined) {
|
|
151
151
|
// const queryLabel = this._tag === 'sql' ? this.queryString$!.computeResult(otelContext) : this.label
|
|
152
152
|
const queryLabel = this.label
|
|
153
|
-
|
|
153
|
+
return shouldNeverHappen(`Expected query ${queryLabel} to return at least one result`)
|
|
154
154
|
}
|
|
155
155
|
return results[0] ?? args!.defaultValue!
|
|
156
156
|
},
|
package/src/row-query.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { shouldNeverHappen } from '@livestore/utils'
|
|
2
|
+
import { pipe, ReadonlyRecord, Schema, TreeFormatter } from '@livestore/utils/effect'
|
|
3
|
+
import type * as otel from '@opentelemetry/api'
|
|
4
|
+
import { SqliteAst, SqliteDsl } from 'effect-db-schema'
|
|
5
|
+
|
|
6
|
+
import type { InMemoryDatabase } from './inMemoryDatabase.js'
|
|
7
|
+
import { migrateTable } from './migrations.js'
|
|
8
|
+
import type { LiveStoreJSQuery } from './reactiveQueries/js.js'
|
|
9
|
+
import { LiveStoreSQLQuery } from './reactiveQueries/sql.js'
|
|
10
|
+
import { SCHEMA_META_TABLE } from './schema/index.js'
|
|
11
|
+
import type { TableDef } from './schema/table-def.js'
|
|
12
|
+
import type { Store } from './store.js'
|
|
13
|
+
import { prepareBindValues, sql } from './utils/util.js'
|
|
14
|
+
|
|
15
|
+
export type RowQueryArgs<TTableDef extends TableDef> = TTableDef['options']['isSingleton'] extends true
|
|
16
|
+
? {
|
|
17
|
+
table: TTableDef
|
|
18
|
+
store: Store
|
|
19
|
+
otelContext?: otel.Context
|
|
20
|
+
}
|
|
21
|
+
: {
|
|
22
|
+
table: TTableDef
|
|
23
|
+
store: Store
|
|
24
|
+
otelContext?: otel.Context
|
|
25
|
+
id: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// TODO also allow other where clauses and multiple rows
|
|
29
|
+
export const rowQuery = <TTableDef extends TableDef>(
|
|
30
|
+
args: RowQueryArgs<TTableDef>,
|
|
31
|
+
): LiveStoreJSQuery<RowResult<TTableDef>> => {
|
|
32
|
+
const { table, store } = args
|
|
33
|
+
const otelContext = args.otelContext ?? store.otel.queriesSpanContext
|
|
34
|
+
const id: string | undefined = (args as any).id
|
|
35
|
+
|
|
36
|
+
// Validate query args
|
|
37
|
+
if (table.options.isSingleton === true && id !== undefined) {
|
|
38
|
+
shouldNeverHappen(`Cannot query state table ${table.schema.name} with id "${id}" as it is a singleton`)
|
|
39
|
+
} else if (table.options.isSingleton !== true && id === undefined) {
|
|
40
|
+
shouldNeverHappen(`Cannot query state table ${table.schema.name} without id`)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const stateSchema = table.schema
|
|
44
|
+
const componentTableName = stateSchema.name
|
|
45
|
+
|
|
46
|
+
type TComponentState = SqliteDsl.FromColumns.RowDecoded<TTableDef['schema']['columns']>
|
|
47
|
+
|
|
48
|
+
// TODO find a better solution for this
|
|
49
|
+
if (store.tableRefs[componentTableName] === undefined) {
|
|
50
|
+
const schemaHash = SqliteAst.hash(stateSchema.ast)
|
|
51
|
+
const res = store.inMemoryDB.select<{ schemaHash: number }>(
|
|
52
|
+
sql`SELECT schemaHash FROM ${SCHEMA_META_TABLE} WHERE tableName = '${componentTableName}'`,
|
|
53
|
+
)
|
|
54
|
+
if (res.length === 0 || res[0]!.schemaHash !== schemaHash) {
|
|
55
|
+
migrateTable({
|
|
56
|
+
db: store._proxyDb,
|
|
57
|
+
tableAst: stateSchema.ast,
|
|
58
|
+
otelContext,
|
|
59
|
+
schemaHash,
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
store.tableRefs[componentTableName] = store.graph.makeRef(null, {
|
|
64
|
+
equal: () => false,
|
|
65
|
+
label: componentTableName,
|
|
66
|
+
meta: { liveStoreRefType: 'table' },
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// TODO find a way to only do this if necessary
|
|
71
|
+
insertRowWithDefaultValuesOrIgnore({
|
|
72
|
+
db: store._proxyDb,
|
|
73
|
+
id: id ?? 'singleton',
|
|
74
|
+
stateSchema,
|
|
75
|
+
otelContext,
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const whereClause = id === undefined ? '' : `where id = '${id}'`
|
|
79
|
+
const queryStr = sql`select * from ${componentTableName} ${whereClause} limit 1`
|
|
80
|
+
|
|
81
|
+
return new LiveStoreSQLQuery({
|
|
82
|
+
label: `localState:query:${stateSchema.name}${id === undefined ? '' : `:${id}`}`,
|
|
83
|
+
genQueryString: queryStr,
|
|
84
|
+
queriedTables: new Set([componentTableName]),
|
|
85
|
+
}).pipe<TComponentState>((results) => {
|
|
86
|
+
if (results.length === 0) return shouldNeverHappen(`No results for query ${queryStr}`)
|
|
87
|
+
|
|
88
|
+
const componentStateEffectSchema = SqliteDsl.structSchemaForTable(stateSchema)
|
|
89
|
+
const parseResult = Schema.parseEither(componentStateEffectSchema)(results[0]!)
|
|
90
|
+
|
|
91
|
+
if (parseResult._tag === 'Left') {
|
|
92
|
+
console.error('decode error', TreeFormatter.formatErrors(parseResult.left.errors), 'results', results)
|
|
93
|
+
return shouldNeverHappen(`Error decoding query result for ${queryStr}`)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return table.isSingleColumn === true ? parseResult.right.value : parseResult.right
|
|
97
|
+
}) as unknown as LiveStoreJSQuery<RowResult<TTableDef>>
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
type GetValForKey<T, K> = K extends keyof T ? T[K] : never
|
|
101
|
+
|
|
102
|
+
export type RowResult<TTableDef extends TableDef> = TTableDef['isSingleColumn'] extends true
|
|
103
|
+
? GetValForKey<SqliteDsl.FromColumns.RowDecoded<TTableDef['schema']['columns']>, 'value'>
|
|
104
|
+
: SqliteDsl.FromColumns.RowDecoded<TTableDef['schema']['columns']>
|
|
105
|
+
|
|
106
|
+
export type RowResultEncoded<TTableDef extends TableDef> = TTableDef['isSingleColumn'] extends true
|
|
107
|
+
? GetValForKey<SqliteDsl.FromColumns.RowEncoded<TTableDef['schema']['columns']>, 'value'>
|
|
108
|
+
: SqliteDsl.FromColumns.RowEncoded<TTableDef['schema']['columns']>
|
|
109
|
+
|
|
110
|
+
const insertRowWithDefaultValuesOrIgnore = ({
|
|
111
|
+
db,
|
|
112
|
+
id,
|
|
113
|
+
stateSchema,
|
|
114
|
+
otelContext,
|
|
115
|
+
}: {
|
|
116
|
+
db: InMemoryDatabase
|
|
117
|
+
id: string
|
|
118
|
+
stateSchema: SqliteDsl.TableDefinition<string, SqliteDsl.Columns>
|
|
119
|
+
otelContext: otel.Context
|
|
120
|
+
}) => {
|
|
121
|
+
const columnNames = Object.keys(stateSchema.columns)
|
|
122
|
+
const columnValues = columnNames.map((name) => `$${name}`).join(', ')
|
|
123
|
+
|
|
124
|
+
const tableName = stateSchema.name
|
|
125
|
+
const insertQuery = sql`insert into ${tableName} (${columnNames.join(
|
|
126
|
+
', ',
|
|
127
|
+
)}) select ${columnValues} where not exists(select 1 from ${tableName} where id = '${id}')`
|
|
128
|
+
|
|
129
|
+
const defaultValues = pipe(
|
|
130
|
+
stateSchema.columns,
|
|
131
|
+
ReadonlyRecord.filter((_, key) => key !== 'id'),
|
|
132
|
+
ReadonlyRecord.map((column, columnName) =>
|
|
133
|
+
column.default === undefined
|
|
134
|
+
? column.nullable === true
|
|
135
|
+
? null
|
|
136
|
+
: shouldNeverHappen(`Column ${columnName} has no default value and is not nullable`)
|
|
137
|
+
: Schema.encodeSync(column.type.codec)(column.default ?? null),
|
|
138
|
+
),
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
void db.execute(insertQuery, prepareBindValues({ ...defaultValues, id }, insertQuery), [tableName], { otelContext })
|
|
142
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type SQLWriteStatement = {
|
|
2
|
+
sql: string
|
|
3
|
+
|
|
4
|
+
/** Tables written by the statement */
|
|
5
|
+
writeTables: ReadonlyArray<string>
|
|
6
|
+
// TODO refactor this
|
|
7
|
+
argsAlreadyBound?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ActionDefinition<TArgs = any> = {
|
|
11
|
+
statement: SQLWriteStatement | ((args: TArgs) => SQLWriteStatement)
|
|
12
|
+
prepareBindValues?: (args: TArgs) => any
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type ActionDefinitions<TArgsMap extends Record<string, any>> = {
|
|
16
|
+
[key in keyof TArgsMap]: ActionDefinition<TArgsMap[key]>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const defineActions = <A extends ActionDefinitions<any>>(actions: A) => actions
|
|
20
|
+
export const defineAction = <TArgs extends Record<string, any>>(
|
|
21
|
+
action: ActionDefinition<TArgs>,
|
|
22
|
+
): ActionDefinition<TArgs> => action
|
|
23
|
+
|
|
24
|
+
export type GetApplyEventArgs<TActionDefinitionsMap> = RecordValues<{
|
|
25
|
+
[eventType in keyof TActionDefinitionsMap]: {
|
|
26
|
+
eventType: eventType
|
|
27
|
+
args: GetActionArgs<TActionDefinitionsMap[eventType]>
|
|
28
|
+
}
|
|
29
|
+
}>
|
|
30
|
+
|
|
31
|
+
type RecordValues<T> = T extends Record<string, infer V> ? V : never
|
|
32
|
+
|
|
33
|
+
export type GetActionArgs<A> = A extends ActionDefinition<infer TArgs> ? TArgs : never
|
|
34
|
+
|
|
35
|
+
// TODO get rid of this
|
|
36
|
+
declare global {
|
|
37
|
+
// NOTE Can be extended
|
|
38
|
+
interface LiveStoreActionDefinitionsTypes {
|
|
39
|
+
[key: string]: ActionDefinition
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { SqliteDsl } from 'effect-db-schema'
|
|
2
|
+
|
|
3
|
+
import type { ActionDefinitions } from './action.js'
|
|
4
|
+
import { systemTables } from './system-tables.js'
|
|
5
|
+
import type { TableDef } from './table-def.js'
|
|
6
|
+
|
|
7
|
+
export * from './action.js'
|
|
8
|
+
export * from './system-tables.js'
|
|
9
|
+
export * as DbSchema from './table-def.js'
|
|
10
|
+
|
|
11
|
+
// export { SqliteDsl as DbSchema } from 'effect-db-schema'
|
|
12
|
+
|
|
13
|
+
export type LiveStoreSchema<TDbSchema extends SqliteDsl.DbSchema = SqliteDsl.DbSchema> = {
|
|
14
|
+
/** Only used on type-level */
|
|
15
|
+
readonly _DbSchemaType: TDbSchema
|
|
16
|
+
|
|
17
|
+
readonly tables: Map<string, TableDef>
|
|
18
|
+
readonly actions: ActionDefinitions<any>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type InputSchema = {
|
|
22
|
+
tables: Record<string, TableDef> | ReadonlyArray<TableDef>
|
|
23
|
+
actions: ActionDefinitions<any>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const makeSchema = <TInputSchema extends InputSchema>(
|
|
27
|
+
/** Note when using the object-notation for tables, the object keys are ignored and not used as table names */
|
|
28
|
+
schema: TInputSchema,
|
|
29
|
+
): LiveStoreSchema<DbSchemaFromInputSchemaTables<TInputSchema['tables']>> => {
|
|
30
|
+
const inputTables: ReadonlyArray<TableDef> = Array.isArray(schema.tables)
|
|
31
|
+
? schema.tables
|
|
32
|
+
: // TODO validate that table names are unique in this case
|
|
33
|
+
Object.values(schema.tables)
|
|
34
|
+
|
|
35
|
+
const tables = new Map<string, TableDef>()
|
|
36
|
+
|
|
37
|
+
for (const tableDef of inputTables) {
|
|
38
|
+
// TODO validate tables (e.g. index names are unique)
|
|
39
|
+
tables.set(tableDef.schema.ast.name, tableDef)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const tableDef of systemTables) {
|
|
43
|
+
tables.set(tableDef.schema.name, tableDef)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
_DbSchemaType: Symbol('livestore.DbSchemaType') as any,
|
|
48
|
+
tables,
|
|
49
|
+
actions: schema.actions,
|
|
50
|
+
} satisfies LiveStoreSchema
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* In case of ...
|
|
55
|
+
* - array: we use the table name of each array item (= table definition) as the object key
|
|
56
|
+
* - object: we discard the keys of the input object and use the table name of each object value (= table definition) as the new object key
|
|
57
|
+
*/
|
|
58
|
+
export type DbSchemaFromInputSchemaTables<TTables extends InputSchema['tables']> =
|
|
59
|
+
TTables extends ReadonlyArray<TableDef>
|
|
60
|
+
? { [K in TTables[number] as K['schema']['name']]: K['schema'] }
|
|
61
|
+
: TTables extends Record<string, TableDef>
|
|
62
|
+
? { [K in keyof TTables as TTables[K]['schema']['name']]: TTables[K]['schema'] }
|
|
63
|
+
: never
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SqliteAst as __SqliteAst, SqliteDsl } from 'effect-db-schema'
|
|
2
|
+
|
|
3
|
+
import type { FromTable } from './table-def.js'
|
|
4
|
+
import { table } from './table-def.js'
|
|
5
|
+
|
|
6
|
+
export const SCHEMA_META_TABLE = '__livestore_schema'
|
|
7
|
+
|
|
8
|
+
const schemaMetaTable = table(
|
|
9
|
+
SCHEMA_META_TABLE,
|
|
10
|
+
{
|
|
11
|
+
tableName: SqliteDsl.text({ primaryKey: true }),
|
|
12
|
+
schemaHash: SqliteDsl.integer({ nullable: false }),
|
|
13
|
+
/** ISO date format */
|
|
14
|
+
updatedAt: SqliteDsl.text({ nullable: false }),
|
|
15
|
+
},
|
|
16
|
+
{ disableAutomaticIdColumn: true },
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
export type SchemaMetaRow = FromTable.RowDecoded<typeof schemaMetaTable>
|
|
20
|
+
|
|
21
|
+
export const systemTables = [schemaMetaTable]
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { shouldNeverHappen } from '@livestore/utils'
|
|
2
|
+
import { Schema } from '@livestore/utils/effect'
|
|
3
|
+
import type { Nullable, PrettifyFlat } from 'effect-db-schema'
|
|
4
|
+
import { SqliteAst, SqliteDsl } from 'effect-db-schema'
|
|
5
|
+
|
|
6
|
+
export const {
|
|
7
|
+
blob,
|
|
8
|
+
blobWithSchema,
|
|
9
|
+
boolean,
|
|
10
|
+
column,
|
|
11
|
+
datetime,
|
|
12
|
+
integer,
|
|
13
|
+
isColumnDefinition,
|
|
14
|
+
json,
|
|
15
|
+
real,
|
|
16
|
+
text,
|
|
17
|
+
textWithSchema,
|
|
18
|
+
} = SqliteDsl
|
|
19
|
+
|
|
20
|
+
export { SqliteDsl as __SqliteDsl } from 'effect-db-schema'
|
|
21
|
+
|
|
22
|
+
import { dynamicallyRegisteredTables } from '../global-state.js'
|
|
23
|
+
|
|
24
|
+
export type StateType = 'singleton' | 'dynamic'
|
|
25
|
+
|
|
26
|
+
export type DefaultSqliteTableDef = SqliteDsl.TableDefinition<string, SqliteDsl.Columns>
|
|
27
|
+
|
|
28
|
+
export type TableDef<
|
|
29
|
+
TTableDef extends DefaultSqliteTableDef = DefaultSqliteTableDef,
|
|
30
|
+
TIsSingleColumn extends boolean = boolean,
|
|
31
|
+
TOptions extends TableOptions = TableOptions,
|
|
32
|
+
> = {
|
|
33
|
+
schema: TTableDef
|
|
34
|
+
isSingleColumn: TIsSingleColumn
|
|
35
|
+
options: TOptions
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type TableOptionsInput = Partial<TableOptions & { indexes: SqliteDsl.Index[] }>
|
|
39
|
+
|
|
40
|
+
export type TableOptions = {
|
|
41
|
+
/**
|
|
42
|
+
* Setting this to true will have the following consequences:
|
|
43
|
+
* - An `id` column will be added with `primaryKey: true` and `"singleton"` as default value and only allowed value
|
|
44
|
+
* - LiveStore will automatically create the singleton row when the table is created
|
|
45
|
+
* - LiveStore will fail if there is already a column defined with `primaryKey: true`
|
|
46
|
+
*
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
49
|
+
isSingleton: boolean
|
|
50
|
+
// TODO
|
|
51
|
+
dynamicRegistration: boolean
|
|
52
|
+
disableAutomaticIdColumn: boolean
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const table = <
|
|
56
|
+
TName extends string,
|
|
57
|
+
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
|
58
|
+
const TOptionsInput extends TableOptionsInput = TableOptionsInput,
|
|
59
|
+
>(
|
|
60
|
+
name: TName,
|
|
61
|
+
columnOrColumns: TColumns,
|
|
62
|
+
// type?: TStateType,
|
|
63
|
+
options?: TOptionsInput,
|
|
64
|
+
): TableDef<
|
|
65
|
+
SqliteDsl.TableDefinition<
|
|
66
|
+
TName,
|
|
67
|
+
PrettifyFlat<
|
|
68
|
+
WithId<TColumns extends SqliteDsl.Columns ? TColumns : { value: TColumns }, WithDefaults<TOptionsInput>>
|
|
69
|
+
>
|
|
70
|
+
>,
|
|
71
|
+
TColumns extends SqliteDsl.ColumnDefinition<any, any> ? true : false,
|
|
72
|
+
WithDefaults<TOptionsInput>
|
|
73
|
+
> => {
|
|
74
|
+
const tablePath = name
|
|
75
|
+
|
|
76
|
+
const options_: TableOptions = {
|
|
77
|
+
isSingleton: options?.isSingleton ?? false,
|
|
78
|
+
dynamicRegistration: options?.dynamicRegistration ?? false,
|
|
79
|
+
disableAutomaticIdColumn: options?.disableAutomaticIdColumn ?? false,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const columns = (
|
|
83
|
+
SqliteDsl.isColumnDefinition(columnOrColumns) ? { value: columnOrColumns } : columnOrColumns
|
|
84
|
+
) as SqliteDsl.Columns
|
|
85
|
+
|
|
86
|
+
if (options_.disableAutomaticIdColumn === true) {
|
|
87
|
+
if (columns.id === undefined && options_.isSingleton === true) {
|
|
88
|
+
shouldNeverHappen(
|
|
89
|
+
`Cannot create table ${name} with "isSingleton: true" because there is no column with name "id" and "disableAutomaticIdColumn: true" is set`,
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
if (columns.id === undefined) {
|
|
94
|
+
if (options_.isSingleton) {
|
|
95
|
+
columns.id = SqliteDsl.textWithSchema(Schema.literal('singleton'), { primaryKey: true, default: 'singleton' })
|
|
96
|
+
} else {
|
|
97
|
+
columns.id = SqliteDsl.text({ primaryKey: true })
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const schema = SqliteDsl.table(tablePath, columns, options?.indexes ?? [])
|
|
103
|
+
|
|
104
|
+
if (options_.isSingleton) {
|
|
105
|
+
for (const column of schema.ast.columns) {
|
|
106
|
+
if (column.nullable === false && column.default === undefined) {
|
|
107
|
+
shouldNeverHappen(
|
|
108
|
+
`When creating a singleton table, each column must be either nullable or have a default value. Column '${column.name}' is neither.`,
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const isSingleColumn = SqliteDsl.isColumnDefinition(columnOrColumns) === true
|
|
115
|
+
|
|
116
|
+
const tableDef = { schema, isSingleColumn, options: options_ }
|
|
117
|
+
|
|
118
|
+
if (dynamicallyRegisteredTables.has(tablePath)) {
|
|
119
|
+
if (SqliteAst.hash(dynamicallyRegisteredTables.get(tablePath)!.schema.ast) !== SqliteAst.hash(schema.ast)) {
|
|
120
|
+
console.error('previous tableDef', dynamicallyRegisteredTables.get(tablePath), 'new tableDef', schema.ast)
|
|
121
|
+
shouldNeverHappen(`Table with name "${name}" was already previously defined with a different definition`)
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
dynamicallyRegisteredTables.set(tablePath, tableDef)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return tableDef as any
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
type WithId<TColumns extends SqliteDsl.Columns, TOptions extends TableOptions> = TColumns &
|
|
131
|
+
(TOptions['disableAutomaticIdColumn'] extends true
|
|
132
|
+
? {}
|
|
133
|
+
: TOptions['isSingleton'] extends true
|
|
134
|
+
? {
|
|
135
|
+
id: SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeText<'singleton', 'singleton'>, false>
|
|
136
|
+
}
|
|
137
|
+
: {
|
|
138
|
+
id: SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeText<string, string>, false>
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
type WithDefaults<TOptionsInput extends TableOptionsInput> = {
|
|
142
|
+
isSingleton: TOptionsInput['isSingleton'] extends true ? true : false
|
|
143
|
+
dynamicRegistration: TOptionsInput['dynamicRegistration'] extends true ? true : false
|
|
144
|
+
disableAutomaticIdColumn: TOptionsInput['disableAutomaticIdColumn'] extends true ? true : false
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export namespace FromTable {
|
|
148
|
+
// TODO this sometimes doesn't preserve the order of columns
|
|
149
|
+
export type RowDecoded<TTableDef extends TableDef> = PrettifyFlat<
|
|
150
|
+
Nullable<Pick<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>> &
|
|
151
|
+
Omit<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>
|
|
152
|
+
>
|
|
153
|
+
|
|
154
|
+
export type NullableColumnNames<TTableDef extends TableDef> = FromColumns.NullableColumnNames<
|
|
155
|
+
TTableDef['schema']['columns']
|
|
156
|
+
>
|
|
157
|
+
|
|
158
|
+
export type Columns<TTableDef extends TableDef> = {
|
|
159
|
+
[K in keyof TTableDef['schema']['columns']]: TTableDef['schema']['columns'][K]['type']['columnType']
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export type RowEncodeNonNullable<TTableDef extends TableDef> = {
|
|
163
|
+
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.From<TTableDef['schema']['columns'][K]['type']['codec']>
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export type RowEncoded<TTableDef extends TableDef> = PrettifyFlat<
|
|
167
|
+
Nullable<Pick<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>> &
|
|
168
|
+
Omit<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>
|
|
169
|
+
>
|
|
170
|
+
|
|
171
|
+
export type RowDecodedAll<TTableDef extends TableDef> = {
|
|
172
|
+
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.To<TTableDef['schema']['columns'][K]['type']['codec']>
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export namespace FromColumns {
|
|
177
|
+
// TODO this sometimes doesn't preserve the order of columns
|
|
178
|
+
export type RowDecoded<TColumns extends SqliteDsl.Columns> = PrettifyFlat<
|
|
179
|
+
Nullable<Pick<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>> &
|
|
180
|
+
Omit<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>
|
|
181
|
+
>
|
|
182
|
+
|
|
183
|
+
export type RowDecodedAll<TColumns extends SqliteDsl.Columns> = {
|
|
184
|
+
[K in keyof TColumns]: Schema.Schema.To<TColumns[K]['type']['codec']>
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export type RowEncoded<TColumns extends SqliteDsl.Columns> = PrettifyFlat<
|
|
188
|
+
Nullable<Pick<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>> &
|
|
189
|
+
Omit<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>
|
|
190
|
+
>
|
|
191
|
+
|
|
192
|
+
export type RowEncodeNonNullable<TColumns extends SqliteDsl.Columns> = {
|
|
193
|
+
[K in keyof TColumns]: Schema.Schema.From<TColumns[K]['type']['codec']>
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export type NullableColumnNames<TColumns extends SqliteDsl.Columns> = keyof {
|
|
197
|
+
[K in keyof TColumns as TColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as otel from '@opentelemetry/api'
|
|
2
2
|
|
|
3
|
-
import type { PreparedBindValues } from '../../util.js'
|
|
3
|
+
import type { PreparedBindValues } from '../../utils/util.js'
|
|
4
4
|
import type { Storage, StorageOtelProps } from '../index.js'
|
|
5
5
|
|
|
6
6
|
export type StorageOptionsWebInMemory = {
|
package/src/storage/index.ts
CHANGED
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
import type * as otel from '@opentelemetry/api'
|
|
10
10
|
|
|
11
|
-
import type { PreparedBindValues } from '../util.js'
|
|
11
|
+
import type { PreparedBindValues } from '../utils/util.js'
|
|
12
12
|
|
|
13
13
|
export type StorageInit = (otelProps: StorageOtelProps) => Promise<Storage> | Storage
|
|
14
14
|
|
|
15
15
|
export interface Storage {
|
|
16
|
+
// TODO consider transferables for `bindValues` (e.g. Uint8Array values)
|
|
16
17
|
execute(query: string, bindValues?: PreparedBindValues, parentSpan?: otel.Span): void
|
|
17
18
|
|
|
18
19
|
/** Return a snapshot of persisted data from the storage */
|
|
@@ -2,8 +2,8 @@ import { getTraceParentHeader } from '@livestore/utils'
|
|
|
2
2
|
import type * as otel from '@opentelemetry/api'
|
|
3
3
|
import { invoke } from '@tauri-apps/api'
|
|
4
4
|
|
|
5
|
-
import type { PreparedBindValues } from '../../util.js'
|
|
6
|
-
import { prepareBindValues } from '../../util.js'
|
|
5
|
+
import type { PreparedBindValues } from '../../utils/util.js'
|
|
6
|
+
import { prepareBindValues } from '../../utils/util.js'
|
|
7
7
|
import type { Storage, StorageOtelProps } from '../index.js'
|
|
8
8
|
|
|
9
9
|
export type StorageOptionsTauri = {
|
|
@@ -2,7 +2,7 @@ import { casesHandled } from '@livestore/utils'
|
|
|
2
2
|
import type * as otel from '@opentelemetry/api'
|
|
3
3
|
import * as Comlink from 'comlink'
|
|
4
4
|
|
|
5
|
-
import type { PreparedBindValues } from '../../util.js'
|
|
5
|
+
import type { PreparedBindValues } from '../../utils/util.js'
|
|
6
6
|
import type { Storage, StorageOtelProps } from '../index.js'
|
|
7
7
|
import { IDB } from '../utils/idb.js'
|
|
8
8
|
import type { WrappedWorker } from './worker.js'
|
|
@@ -8,8 +8,8 @@ import type * as SqliteWasm from 'sqlite-esm'
|
|
|
8
8
|
import sqlite3InitModule from 'sqlite-esm'
|
|
9
9
|
|
|
10
10
|
// import { v4 as uuid } from 'uuid'
|
|
11
|
-
import type { Bindable } from '../../util.js'
|
|
12
|
-
import { casesHandled, sql } from '../../util.js'
|
|
11
|
+
import type { Bindable } from '../../utils/util.js'
|
|
12
|
+
import { casesHandled, sql } from '../../utils/util.js'
|
|
13
13
|
import { IDB } from '../utils/idb.js'
|
|
14
14
|
import type { StorageOptionsWeb } from './index.js'
|
|
15
15
|
|