@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.
- package/README.md +3 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/global-state.d.ts +1 -1
- package/dist/global-state.d.ts.map +1 -1
- package/dist/global-state.js +1 -1
- package/dist/global-state.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/live-queries/base-class.d.ts +64 -0
- package/dist/live-queries/base-class.d.ts.map +1 -0
- package/dist/live-queries/base-class.js +31 -0
- package/dist/live-queries/base-class.js.map +1 -0
- package/dist/live-queries/computed.d.ts +26 -0
- package/dist/live-queries/computed.d.ts.map +1 -0
- package/dist/{reactiveQueries/js.js → live-queries/computed.js} +7 -26
- package/dist/live-queries/computed.js.map +1 -0
- package/dist/live-queries/db.d.ts +66 -0
- package/dist/live-queries/db.d.ts.map +1 -0
- package/dist/live-queries/db.js +199 -0
- package/dist/live-queries/db.js.map +1 -0
- package/dist/live-queries/db.test.d.ts +2 -0
- package/dist/live-queries/db.test.d.ts.map +1 -0
- package/dist/live-queries/db.test.js +117 -0
- package/dist/live-queries/db.test.js.map +1 -0
- package/dist/live-queries/graphql.d.ts +49 -0
- package/dist/live-queries/graphql.d.ts.map +1 -0
- package/dist/live-queries/graphql.js +122 -0
- package/dist/live-queries/graphql.js.map +1 -0
- package/dist/live-queries/sql.d.ts +62 -0
- package/dist/live-queries/sql.d.ts.map +1 -0
- package/dist/live-queries/sql.js +175 -0
- package/dist/live-queries/sql.js.map +1 -0
- package/dist/live-queries/sql.test.d.ts +2 -0
- package/dist/live-queries/sql.test.d.ts.map +1 -0
- package/{src/reactiveQueries/sql.test.ts → dist/live-queries/sql.test.js} +68 -91
- package/dist/live-queries/sql.test.js.map +1 -0
- package/dist/reactiveQueries/base-class.d.ts +6 -2
- package/dist/reactiveQueries/base-class.d.ts.map +1 -1
- package/dist/reactiveQueries/base-class.js +2 -0
- package/dist/reactiveQueries/base-class.js.map +1 -1
- package/dist/reactiveQueries/computed.d.ts +4 -13
- package/dist/reactiveQueries/computed.d.ts.map +1 -1
- package/dist/reactiveQueries/computed.js +2 -21
- package/dist/reactiveQueries/computed.js.map +1 -1
- package/dist/reactiveQueries/graphql.d.ts +4 -8
- package/dist/reactiveQueries/graphql.d.ts.map +1 -1
- package/dist/reactiveQueries/graphql.js +1 -15
- package/dist/reactiveQueries/graphql.js.map +1 -1
- package/dist/reactiveQueries/sql.d.ts +36 -23
- package/dist/reactiveQueries/sql.d.ts.map +1 -1
- package/dist/reactiveQueries/sql.js +100 -55
- package/dist/reactiveQueries/sql.js.map +1 -1
- package/dist/reactiveQueries/sql.test.js +12 -11
- package/dist/reactiveQueries/sql.test.js.map +1 -1
- package/dist/row-query-utils.d.ts +17 -0
- package/dist/row-query-utils.d.ts.map +1 -0
- package/dist/row-query-utils.js +30 -0
- package/dist/row-query-utils.js.map +1 -0
- package/dist/row-query.d.ts +10 -27
- package/dist/row-query.d.ts.map +1 -1
- package/dist/row-query.js +16 -66
- package/dist/row-query.js.map +1 -1
- package/dist/store/create-store.d.ts +1 -1
- package/dist/store/create-store.d.ts.map +1 -1
- package/dist/store/devtools.d.ts +1 -1
- package/dist/store/devtools.d.ts.map +1 -1
- package/dist/store/devtools.js.map +1 -1
- package/dist/store/store-types.d.ts +2 -2
- package/dist/store/store-types.d.ts.map +1 -1
- package/dist/store/store.d.ts +8 -3
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +32 -4
- package/dist/store/store.js.map +1 -1
- package/dist/utils/tests/fixture.d.ts +168 -132
- package/dist/utils/tests/fixture.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/global-state.ts +1 -1
- package/src/index.ts +8 -5
- package/src/live-queries/__snapshots__/db.test.ts.snap +301 -0
- package/src/{reactiveQueries → live-queries}/base-class.ts +10 -5
- package/src/{reactiveQueries → live-queries}/computed.ts +5 -29
- package/src/live-queries/db.test.ts +153 -0
- package/src/live-queries/db.ts +350 -0
- package/src/{reactiveQueries → live-queries}/graphql.ts +6 -21
- package/src/row-query-utils.ts +65 -0
- package/src/store/create-store.ts +1 -1
- package/src/store/devtools.ts +1 -1
- package/src/store/store-types.ts +2 -2
- package/src/store/store.ts +44 -7
- package/dist/reactiveQueries/js.d.ts +0 -35
- package/dist/reactiveQueries/js.d.ts.map +0 -1
- package/dist/reactiveQueries/js.js.map +0 -1
- package/dist/store/store-context.d.ts +0 -26
- package/dist/store/store-context.d.ts.map +0 -1
- package/dist/store/store-context.js +0 -6
- package/dist/store/store-context.js.map +0 -1
- package/dist/store-context.d.ts +0 -26
- package/dist/store-context.d.ts.map +0 -1
- package/dist/store-context.js +0 -6
- package/dist/store-context.js.map +0 -1
- package/dist/store-devtools.d.ts +0 -19
- package/dist/store-devtools.d.ts.map +0 -1
- package/dist/store-devtools.js +0 -141
- package/dist/store-devtools.js.map +0 -1
- package/dist/store.d.ts +0 -175
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -509
- package/dist/store.js.map +0 -1
- package/src/reactiveQueries/sql.ts +0 -226
- package/src/row-query.ts +0 -196
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import type { Bindable, QueryBuilder, QueryInfo } from '@livestore/common'
|
|
2
|
+
import {
|
|
3
|
+
getResultSchema,
|
|
4
|
+
isQueryBuilder,
|
|
5
|
+
prepareBindValues,
|
|
6
|
+
QueryBuilderAstSymbol,
|
|
7
|
+
replaceSessionIdSymbol,
|
|
8
|
+
} from '@livestore/common'
|
|
9
|
+
import { deepEqual, shouldNeverHappen } from '@livestore/utils'
|
|
10
|
+
import { Predicate, Schema, TreeFormatter } from '@livestore/utils/effect'
|
|
11
|
+
import * as otel from '@opentelemetry/api'
|
|
12
|
+
|
|
13
|
+
import { globalReactivityGraph } from '../global-state.js'
|
|
14
|
+
import type { Thunk } from '../reactive.js'
|
|
15
|
+
import { isThunk, NOT_REFRESHED_YET } from '../reactive.js'
|
|
16
|
+
import { makeExecBeforeFirstRun, rowQueryLabel } from '../row-query-utils.js'
|
|
17
|
+
import type { RefreshReason } from '../store/store-types.js'
|
|
18
|
+
import { getDurationMsFromSpan } from '../utils/otel.js'
|
|
19
|
+
import type { GetAtomResult, LiveQuery, QueryContext, ReactivityGraph } from './base-class.js'
|
|
20
|
+
import { LiveStoreQueryBase, makeGetAtomResult } from './base-class.js'
|
|
21
|
+
|
|
22
|
+
export type QueryInputRaw<TDecoded, TEncoded, TQueryInfo extends QueryInfo> = {
|
|
23
|
+
query: string
|
|
24
|
+
schema: Schema.Schema<TDecoded, TEncoded>
|
|
25
|
+
bindValues?: Bindable
|
|
26
|
+
/**
|
|
27
|
+
* Can be provided explicitly to slightly speed up initial query performance
|
|
28
|
+
*
|
|
29
|
+
* NOTE In the future we want to do this automatically at build time
|
|
30
|
+
*/
|
|
31
|
+
queriedTables?: Set<string>
|
|
32
|
+
queryInfo?: TQueryInfo
|
|
33
|
+
execBeforeFirstRun?: (ctx: QueryContext) => void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type QueryInput<TDecoded, TEncoded, TQueryInfo extends QueryInfo> =
|
|
37
|
+
| QueryInputRaw<TDecoded, TEncoded, TQueryInfo>
|
|
38
|
+
| QueryBuilder<TDecoded, any, any, TQueryInfo>
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* NOTE `query` is only supposed to read data. Don't use it to insert/update/delete data but use mutations instead.
|
|
42
|
+
*/
|
|
43
|
+
export const queryDb: {
|
|
44
|
+
<TResultSchema, TResult = TResultSchema, TQueryInfo extends QueryInfo = QueryInfo.None>(
|
|
45
|
+
queryInput:
|
|
46
|
+
| QueryInputRaw<TResultSchema, ReadonlyArray<any>, TQueryInfo>
|
|
47
|
+
| QueryBuilder<TResultSchema, any, any, TQueryInfo>,
|
|
48
|
+
options?: {
|
|
49
|
+
map?: (rows: TResultSchema) => TResult
|
|
50
|
+
/**
|
|
51
|
+
* Used for debugging / devtools
|
|
52
|
+
*/
|
|
53
|
+
label?: string
|
|
54
|
+
reactivityGraph?: ReactivityGraph
|
|
55
|
+
otelContext?: otel.Context
|
|
56
|
+
},
|
|
57
|
+
): LiveQuery<TResult, TQueryInfo>
|
|
58
|
+
// NOTE in this "thunk case", we can't directly derive label/queryInfo from the queryInput,
|
|
59
|
+
// so the caller needs to provide them explicitly otherwise queryInfo will be set to `None`,
|
|
60
|
+
// and label will be set during the query execution
|
|
61
|
+
<TResultSchema, TResult = TResultSchema, TQueryInfo extends QueryInfo = QueryInfo.None>(
|
|
62
|
+
queryInput:
|
|
63
|
+
| ((get: GetAtomResult) => QueryInputRaw<TResultSchema, ReadonlyArray<any>, TQueryInfo>)
|
|
64
|
+
| ((get: GetAtomResult) => QueryBuilder<TResultSchema, any, any, TQueryInfo>),
|
|
65
|
+
options?: {
|
|
66
|
+
map?: (rows: TResultSchema) => TResult
|
|
67
|
+
/**
|
|
68
|
+
* Used for debugging / devtools
|
|
69
|
+
*/
|
|
70
|
+
label?: string
|
|
71
|
+
reactivityGraph?: ReactivityGraph
|
|
72
|
+
queryInfo?: TQueryInfo
|
|
73
|
+
otelContext?: otel.Context
|
|
74
|
+
},
|
|
75
|
+
): LiveQuery<TResult, TQueryInfo>
|
|
76
|
+
} = (queryInput, options) =>
|
|
77
|
+
new LiveStoreDbQuery({
|
|
78
|
+
queryInput,
|
|
79
|
+
label: options?.label,
|
|
80
|
+
reactivityGraph: options?.reactivityGraph,
|
|
81
|
+
map: options?.map,
|
|
82
|
+
queryInfo: Predicate.hasProperty(options, 'queryInfo') ? (options.queryInfo as QueryInfo) : undefined,
|
|
83
|
+
otelContext: options?.otelContext,
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
/* An object encapsulating a reactive SQL query */
|
|
87
|
+
export class LiveStoreDbQuery<
|
|
88
|
+
TResultSchema,
|
|
89
|
+
TResult = TResultSchema,
|
|
90
|
+
TQueryInfo extends QueryInfo = QueryInfo.None,
|
|
91
|
+
> extends LiveStoreQueryBase<TResult, TQueryInfo> {
|
|
92
|
+
_tag: 'db' = 'db'
|
|
93
|
+
|
|
94
|
+
/** A reactive thunk representing the query text */
|
|
95
|
+
queryInput$: Thunk<QueryInput<TResultSchema, ReadonlyArray<any>, TQueryInfo>, QueryContext, RefreshReason> | undefined
|
|
96
|
+
|
|
97
|
+
/** A reactive thunk representing the query results */
|
|
98
|
+
results$: Thunk<TResult, QueryContext, RefreshReason>
|
|
99
|
+
|
|
100
|
+
label: string
|
|
101
|
+
|
|
102
|
+
queryInfo: TQueryInfo
|
|
103
|
+
|
|
104
|
+
protected reactivityGraph
|
|
105
|
+
|
|
106
|
+
private mapResult: (rows: TResultSchema) => TResult
|
|
107
|
+
|
|
108
|
+
constructor({
|
|
109
|
+
queryInput,
|
|
110
|
+
label: inputLabel,
|
|
111
|
+
reactivityGraph,
|
|
112
|
+
map,
|
|
113
|
+
queryInfo: inputQueryInfo,
|
|
114
|
+
otelContext,
|
|
115
|
+
}: {
|
|
116
|
+
label?: string
|
|
117
|
+
queryInput:
|
|
118
|
+
| QueryInput<TResultSchema, ReadonlyArray<any>, TQueryInfo>
|
|
119
|
+
| ((get: GetAtomResult, ctx: QueryContext) => QueryInput<TResultSchema, ReadonlyArray<any>, TQueryInfo>)
|
|
120
|
+
reactivityGraph?: ReactivityGraph
|
|
121
|
+
map?: (rows: TResultSchema) => TResult
|
|
122
|
+
queryInfo?: TQueryInfo
|
|
123
|
+
otelContext?: otel.Context
|
|
124
|
+
}) {
|
|
125
|
+
super()
|
|
126
|
+
|
|
127
|
+
let label = inputLabel ?? 'db(unknown)'
|
|
128
|
+
let queryInfo = inputQueryInfo ?? ({ _tag: 'None' } as TQueryInfo)
|
|
129
|
+
this.reactivityGraph = reactivityGraph ?? globalReactivityGraph
|
|
130
|
+
|
|
131
|
+
this.mapResult = map === undefined ? (rows: any) => rows as TResult : map
|
|
132
|
+
|
|
133
|
+
const schemaRef: { current: Schema.Schema<any, any> | undefined } = {
|
|
134
|
+
current:
|
|
135
|
+
typeof queryInput === 'function' ? undefined : isQueryBuilder(queryInput) ? undefined : queryInput.schema,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const execBeforeFirstRunRef: { current: ((ctx: QueryContext, otelContext: otel.Context) => void) | undefined } = {
|
|
139
|
+
current: undefined,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
type TQueryInputRaw = QueryInputRaw<any, any, QueryInfo>
|
|
143
|
+
|
|
144
|
+
let queryInputRaw$OrQueryInputRaw: TQueryInputRaw | Thunk<TQueryInputRaw, QueryContext, RefreshReason>
|
|
145
|
+
|
|
146
|
+
const fromQueryBuilder = (qb: QueryBuilder.Any, otelContext: otel.Context | undefined) => {
|
|
147
|
+
const qbRes = qb.asSql()
|
|
148
|
+
const schema = getResultSchema(qb) as Schema.Schema<TResultSchema, ReadonlyArray<any>>
|
|
149
|
+
const ast = qb[QueryBuilderAstSymbol]
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
queryInputRaw: {
|
|
153
|
+
query: qbRes.query,
|
|
154
|
+
schema,
|
|
155
|
+
bindValues: qbRes.bindValues,
|
|
156
|
+
queriedTables: new Set([ast.tableDef.sqliteDef.name]),
|
|
157
|
+
queryInfo: ast._tag === 'RowQuery' ? { _tag: 'Row', table: ast.tableDef, id: ast.id } : { _tag: 'None' },
|
|
158
|
+
} satisfies TQueryInputRaw,
|
|
159
|
+
label: ast._tag === 'RowQuery' ? rowQueryLabel(ast.tableDef, ast.id) : qb.toString(),
|
|
160
|
+
execBeforeFirstRun:
|
|
161
|
+
ast._tag === 'RowQuery'
|
|
162
|
+
? makeExecBeforeFirstRun({
|
|
163
|
+
table: ast.tableDef,
|
|
164
|
+
insertValues: ast.insertValues,
|
|
165
|
+
id: ast.id,
|
|
166
|
+
otelContext,
|
|
167
|
+
})
|
|
168
|
+
: undefined,
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (typeof queryInput === 'function') {
|
|
173
|
+
queryInputRaw$OrQueryInputRaw = this.reactivityGraph.makeThunk(
|
|
174
|
+
(get, setDebugInfo, ctx, otelContext) => {
|
|
175
|
+
const startMs = performance.now()
|
|
176
|
+
const queryInputResult = queryInput(makeGetAtomResult(get, otelContext ?? ctx.rootOtelContext), ctx)
|
|
177
|
+
const durationMs = performance.now() - startMs
|
|
178
|
+
|
|
179
|
+
let queryInputRaw: TQueryInputRaw
|
|
180
|
+
|
|
181
|
+
if (isQueryBuilder(queryInputResult)) {
|
|
182
|
+
const res = fromQueryBuilder(queryInputResult, otelContext)
|
|
183
|
+
queryInputRaw = res.queryInputRaw
|
|
184
|
+
// setting label dynamically here
|
|
185
|
+
this.label = res.label
|
|
186
|
+
execBeforeFirstRunRef.current = res.execBeforeFirstRun
|
|
187
|
+
} else {
|
|
188
|
+
queryInputRaw = queryInputResult
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
setDebugInfo({ _tag: 'computed', label: `${this.label}:queryInput`, query: queryInputRaw.query, durationMs })
|
|
192
|
+
|
|
193
|
+
schemaRef.current = queryInputRaw.schema
|
|
194
|
+
|
|
195
|
+
if (inputQueryInfo === undefined && queryInputRaw.queryInfo !== undefined) {
|
|
196
|
+
queryInfo = queryInputRaw.queryInfo as TQueryInfo
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return queryInputRaw
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
label: `${label}:query`,
|
|
203
|
+
meta: { liveStoreThunkType: 'db.query' },
|
|
204
|
+
// NOTE we're not checking the schema here as we assume the query string to always change when the schema might change
|
|
205
|
+
equal: (a, b) => a.query === b.query && deepEqual(a.bindValues, b.bindValues),
|
|
206
|
+
},
|
|
207
|
+
)
|
|
208
|
+
} else {
|
|
209
|
+
let queryInputRaw: TQueryInputRaw
|
|
210
|
+
if (isQueryBuilder(queryInput)) {
|
|
211
|
+
const res = fromQueryBuilder(queryInput, otelContext)
|
|
212
|
+
queryInputRaw = res.queryInputRaw
|
|
213
|
+
label = res.label
|
|
214
|
+
execBeforeFirstRunRef.current = res.execBeforeFirstRun
|
|
215
|
+
} else {
|
|
216
|
+
queryInputRaw = queryInput
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
schemaRef.current = queryInputRaw.schema
|
|
220
|
+
queryInputRaw$OrQueryInputRaw = queryInputRaw
|
|
221
|
+
|
|
222
|
+
// this.label = inputLabel ? this.label : `db(${})`
|
|
223
|
+
if (inputLabel === undefined && isQueryBuilder(queryInput)) {
|
|
224
|
+
const ast = queryInput[QueryBuilderAstSymbol]
|
|
225
|
+
if (ast._tag === 'RowQuery') {
|
|
226
|
+
label = `db(${rowQueryLabel(ast.tableDef, ast.id)})`
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (inputQueryInfo === undefined && queryInputRaw.queryInfo !== undefined) {
|
|
231
|
+
queryInfo = queryInputRaw.queryInfo as TQueryInfo
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const queriedTablesRef: { current: Set<string> | undefined } = { current: undefined }
|
|
236
|
+
|
|
237
|
+
const makeResultsEqual = (resultSchema: Schema.Schema<any, any>) => (a: TResult, b: TResult) =>
|
|
238
|
+
a === NOT_REFRESHED_YET || b === NOT_REFRESHED_YET ? false : Schema.equivalence(resultSchema)(a, b)
|
|
239
|
+
|
|
240
|
+
// NOTE we try to create the equality function eagerly as it might be expensive
|
|
241
|
+
// TODO also support derived equality for `map` (probably will depend on having an easy way to transform a schema without an `encode` step)
|
|
242
|
+
// This would mean dropping the `map` option
|
|
243
|
+
const resultsEqual =
|
|
244
|
+
map === undefined
|
|
245
|
+
? schemaRef.current === undefined
|
|
246
|
+
? (a: TResult, b: TResult) => makeResultsEqual(schemaRef.current!)(a, b)
|
|
247
|
+
: makeResultsEqual(schemaRef.current)
|
|
248
|
+
: undefined
|
|
249
|
+
|
|
250
|
+
const results$ = this.reactivityGraph.makeThunk<TResult>(
|
|
251
|
+
(get, setDebugInfo, queryContext, otelContext) =>
|
|
252
|
+
queryContext.otelTracer.startActiveSpan(
|
|
253
|
+
'db:...', // NOTE span name will be overridden further down
|
|
254
|
+
{},
|
|
255
|
+
otelContext ?? queryContext.rootOtelContext,
|
|
256
|
+
(span) => {
|
|
257
|
+
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
258
|
+
const { store } = queryContext
|
|
259
|
+
|
|
260
|
+
if (execBeforeFirstRunRef.current !== undefined) {
|
|
261
|
+
execBeforeFirstRunRef.current(queryContext, otelContext)
|
|
262
|
+
execBeforeFirstRunRef.current = undefined
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const queryInputResult = isThunk(queryInputRaw$OrQueryInputRaw)
|
|
266
|
+
? (get(queryInputRaw$OrQueryInputRaw, otelContext) as TQueryInputRaw)
|
|
267
|
+
: (queryInputRaw$OrQueryInputRaw as TQueryInputRaw)
|
|
268
|
+
|
|
269
|
+
const sqlString = queryInputResult.query
|
|
270
|
+
const bindValues = queryInputResult.bindValues
|
|
271
|
+
|
|
272
|
+
if (queriedTablesRef.current === undefined) {
|
|
273
|
+
queriedTablesRef.current = store.syncDbWrapper.getTablesUsed(sqlString)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (bindValues !== undefined) {
|
|
277
|
+
replaceSessionIdSymbol(bindValues, store.clientSession.coordinator.sessionId)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Establish a reactive dependency on the tables used in the query
|
|
281
|
+
for (const tableName of queriedTablesRef.current) {
|
|
282
|
+
const tableRef = store.tableRefs[tableName] ?? shouldNeverHappen(`No table ref found for ${tableName}`)
|
|
283
|
+
get(tableRef, otelContext)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
span.setAttribute('sql.query', sqlString)
|
|
287
|
+
span.updateName(`db:${sqlString.slice(0, 50)}`)
|
|
288
|
+
|
|
289
|
+
const rawDbResults = store.syncDbWrapper.select<any>(sqlString, {
|
|
290
|
+
queriedTables: queriedTablesRef.current,
|
|
291
|
+
bindValues: bindValues ? prepareBindValues(bindValues, sqlString) : undefined,
|
|
292
|
+
otelContext,
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
span.setAttribute('sql.rowsCount', rawDbResults.length)
|
|
296
|
+
|
|
297
|
+
const parsedResult = Schema.decodeEither(schemaRef.current!)(rawDbResults)
|
|
298
|
+
|
|
299
|
+
if (parsedResult._tag === 'Left') {
|
|
300
|
+
const parseErrorStr = TreeFormatter.formatErrorSync(parsedResult.left)
|
|
301
|
+
const expectedSchemaStr = String(schemaRef.current!.ast)
|
|
302
|
+
const bindValuesStr = bindValues === undefined ? '' : `\nBind values: ${JSON.stringify(bindValues)}`
|
|
303
|
+
|
|
304
|
+
console.error(
|
|
305
|
+
`\
|
|
306
|
+
Error parsing SQL query result.
|
|
307
|
+
|
|
308
|
+
Query: ${sqlString}\
|
|
309
|
+
${bindValuesStr}
|
|
310
|
+
|
|
311
|
+
Expected schema: ${expectedSchemaStr}
|
|
312
|
+
|
|
313
|
+
Error: ${parseErrorStr}
|
|
314
|
+
|
|
315
|
+
Result:`,
|
|
316
|
+
rawDbResults,
|
|
317
|
+
)
|
|
318
|
+
return shouldNeverHappen(`Error parsing SQL query result: ${parsedResult.left}`)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const result = this.mapResult(parsedResult.right)
|
|
322
|
+
|
|
323
|
+
span.end()
|
|
324
|
+
|
|
325
|
+
const durationMs = getDurationMsFromSpan(span)
|
|
326
|
+
|
|
327
|
+
this.executionTimes.push(durationMs)
|
|
328
|
+
|
|
329
|
+
setDebugInfo({ _tag: 'db', label: `${label}:results`, query: sqlString, durationMs })
|
|
330
|
+
|
|
331
|
+
return result
|
|
332
|
+
},
|
|
333
|
+
),
|
|
334
|
+
{ label: `${label}:results`, meta: { liveStoreThunkType: 'db.results' }, equal: resultsEqual },
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
this.results$ = results$
|
|
338
|
+
|
|
339
|
+
this.label = label
|
|
340
|
+
this.queryInfo = queryInfo
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
destroy = () => {
|
|
344
|
+
if (this.queryInput$ !== undefined) {
|
|
345
|
+
this.reactivityGraph.destroyNode(this.queryInput$)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
this.reactivityGraph.destroyNode(this.results$)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'
|
|
2
|
-
import type {
|
|
2
|
+
import type { QueryInfo } from '@livestore/common'
|
|
3
3
|
import { shouldNeverHappen } from '@livestore/utils'
|
|
4
4
|
import { Schema, TreeFormatter } from '@livestore/utils/effect'
|
|
5
5
|
import * as otel from '@opentelemetry/api'
|
|
@@ -31,7 +31,7 @@ export const queryGraphQL = <
|
|
|
31
31
|
reactivityGraph?: ReactivityGraph
|
|
32
32
|
map?: MapResult<TResultMapped, TResult>
|
|
33
33
|
} = {},
|
|
34
|
-
): LiveQuery<TResultMapped,
|
|
34
|
+
): LiveQuery<TResultMapped, QueryInfo.None> =>
|
|
35
35
|
new LiveStoreGraphQLQuery({ document, genVariableValues, label, reactivityGraph, map })
|
|
36
36
|
|
|
37
37
|
export class LiveStoreGraphQLQuery<
|
|
@@ -39,7 +39,7 @@ export class LiveStoreGraphQLQuery<
|
|
|
39
39
|
TVariableValues extends Record<string, any>,
|
|
40
40
|
TContext extends BaseGraphQLContext,
|
|
41
41
|
TResultMapped extends Record<string, any> = TResult,
|
|
42
|
-
> extends LiveStoreQueryBase<TResultMapped,
|
|
42
|
+
> extends LiveStoreQueryBase<TResultMapped, QueryInfo.None> {
|
|
43
43
|
_tag: 'graphql' = 'graphql'
|
|
44
44
|
|
|
45
45
|
/** The abstract GraphQL query */
|
|
@@ -54,7 +54,7 @@ export class LiveStoreGraphQLQuery<
|
|
|
54
54
|
|
|
55
55
|
protected reactivityGraph: ReactivityGraph
|
|
56
56
|
|
|
57
|
-
queryInfo:
|
|
57
|
+
queryInfo: QueryInfo.None = { _tag: 'None' }
|
|
58
58
|
|
|
59
59
|
private mapResult
|
|
60
60
|
|
|
@@ -105,7 +105,7 @@ export class LiveStoreGraphQLQuery<
|
|
|
105
105
|
(get, _setDebugInfo, { rootOtelContext }, otelContext) => {
|
|
106
106
|
return genVariableValues(makeGetAtomResult(get, otelContext ?? rootOtelContext))
|
|
107
107
|
},
|
|
108
|
-
{ label: `${labelWithDefault}:variableValues`, meta: { liveStoreThunkType: '
|
|
108
|
+
{ label: `${labelWithDefault}:variableValues`, meta: { liveStoreThunkType: 'graphql.variables' } },
|
|
109
109
|
)
|
|
110
110
|
this.variableValues$ = variableValues$OrvariableValues
|
|
111
111
|
} else {
|
|
@@ -137,26 +137,11 @@ export class LiveStoreGraphQLQuery<
|
|
|
137
137
|
|
|
138
138
|
return result
|
|
139
139
|
},
|
|
140
|
-
{ label: resultsLabel, meta: { liveStoreThunkType: '
|
|
140
|
+
{ label: resultsLabel, meta: { liveStoreThunkType: 'graphql.results' } },
|
|
141
141
|
// otelContext,
|
|
142
142
|
)
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
/**
|
|
146
|
-
* Returns a new reactive query that contains the result of
|
|
147
|
-
* running an arbitrary JS computation on the results of this SQL query.
|
|
148
|
-
*/
|
|
149
|
-
// pipe = <U>(fn: (result: TResult, get: GetAtomResult) => U): LiveStoreJSQuery<U> =>
|
|
150
|
-
// new LiveStoreJSQuery({
|
|
151
|
-
// fn: (get) => {
|
|
152
|
-
// const results = get(this.results$)
|
|
153
|
-
// return fn(results, get)
|
|
154
|
-
// },
|
|
155
|
-
// label: `${this.label}:js`,
|
|
156
|
-
// onDestroy: () => this.destroy(),
|
|
157
|
-
// reactivityGraph: this.reactivityGraph,
|
|
158
|
-
// })
|
|
159
|
-
|
|
160
145
|
queryOnce = ({
|
|
161
146
|
document,
|
|
162
147
|
otelContext,
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { PreparedBindValues, QueryInfo } from '@livestore/common'
|
|
2
|
+
import { SessionIdSymbol } from '@livestore/common'
|
|
3
|
+
import { DbSchema } from '@livestore/common/schema'
|
|
4
|
+
import { shouldNeverHappen } from '@livestore/utils'
|
|
5
|
+
import type * as otel from '@opentelemetry/api'
|
|
6
|
+
|
|
7
|
+
import type { LiveQuery, LiveQueryAny, QueryContext } from './live-queries/base-class.js'
|
|
8
|
+
import { computed } from './live-queries/computed.js'
|
|
9
|
+
|
|
10
|
+
export const rowQueryLabel = (table: DbSchema.TableDefBase, id: string | SessionIdSymbol | undefined) =>
|
|
11
|
+
`row:${table.sqliteDef.name}${id === undefined ? '' : id === SessionIdSymbol ? `:sessionId` : `:${id}`}`
|
|
12
|
+
|
|
13
|
+
export const deriveColQuery: {
|
|
14
|
+
<TQuery extends LiveQuery<any, QueryInfo.None>, TCol extends keyof TQuery['__result!'] & string>(
|
|
15
|
+
query$: TQuery,
|
|
16
|
+
colName: TCol,
|
|
17
|
+
): LiveQuery<TQuery['__result!'][TCol], QueryInfo.None>
|
|
18
|
+
<TQuery extends LiveQuery<any, QueryInfo.Row>, TCol extends keyof TQuery['__result!'] & string>(
|
|
19
|
+
query$: TQuery,
|
|
20
|
+
colName: TCol,
|
|
21
|
+
): LiveQuery<TQuery['__result!'][TCol], QueryInfo.Col>
|
|
22
|
+
} = (query$: LiveQueryAny, colName: string) => {
|
|
23
|
+
return computed((get) => get(query$)[colName], {
|
|
24
|
+
label: `deriveColQuery:${query$.label}:${colName}`,
|
|
25
|
+
queryInfo:
|
|
26
|
+
query$.queryInfo._tag === 'Row'
|
|
27
|
+
? { _tag: 'Col', table: query$.queryInfo.table, column: colName, id: query$.queryInfo.id }
|
|
28
|
+
: undefined,
|
|
29
|
+
}) as any
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const makeExecBeforeFirstRun =
|
|
33
|
+
({
|
|
34
|
+
id,
|
|
35
|
+
insertValues,
|
|
36
|
+
table,
|
|
37
|
+
otelContext: otelContext_,
|
|
38
|
+
}: {
|
|
39
|
+
id?: string | SessionIdSymbol
|
|
40
|
+
insertValues?: any
|
|
41
|
+
table: DbSchema.TableDefBase
|
|
42
|
+
otelContext: otel.Context | undefined
|
|
43
|
+
}) =>
|
|
44
|
+
({ store }: QueryContext) => {
|
|
45
|
+
const otelContext = otelContext_ ?? store.otel.queriesSpanContext
|
|
46
|
+
|
|
47
|
+
if (table.options.isSingleton === false) {
|
|
48
|
+
const idStr = id === SessionIdSymbol ? store.sessionId : id!
|
|
49
|
+
const rowExists =
|
|
50
|
+
store.syncDbWrapper.select(`SELECT 1 FROM '${table.sqliteDef.name}' WHERE id = ?`, {
|
|
51
|
+
bindValues: [idStr] as any as PreparedBindValues,
|
|
52
|
+
}).length === 1
|
|
53
|
+
|
|
54
|
+
if (rowExists) return
|
|
55
|
+
|
|
56
|
+
if (DbSchema.tableHasDerivedMutations(table) === false) {
|
|
57
|
+
return shouldNeverHappen(
|
|
58
|
+
`Cannot insert row for table "${table.sqliteDef.name}" which does not have 'deriveMutations: true' set`,
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// NOTE It's important that we only mutate and don't refresh here, as this function is called during a render
|
|
63
|
+
store.mutateWithoutRefresh(table.insert({ id, ...insertValues }), { otelContext, coordinatorMode: 'default' })
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
import * as otel from '@opentelemetry/api'
|
|
29
29
|
|
|
30
30
|
import { globalReactivityGraph } from '../global-state.js'
|
|
31
|
-
import type { ReactivityGraph } from '../
|
|
31
|
+
import type { ReactivityGraph } from '../live-queries/base-class.js'
|
|
32
32
|
import { connectDevtoolsToStore } from './devtools.js'
|
|
33
33
|
import { Store } from './store.js'
|
|
34
34
|
import type { BaseGraphQLContext, GraphQLOptions, OtelOptions } from './store-types.js'
|
package/src/store/devtools.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { throttle } from '@livestore/utils'
|
|
|
4
4
|
import type { WebChannel } from '@livestore/utils/effect'
|
|
5
5
|
import { Effect, Stream } from '@livestore/utils/effect'
|
|
6
6
|
|
|
7
|
+
import type { LiveQuery, ReactivityGraph } from '../live-queries/base-class.js'
|
|
7
8
|
import { NOT_REFRESHED_YET } from '../reactive.js'
|
|
8
|
-
import type { LiveQuery, ReactivityGraph } from '../reactiveQueries/base-class.js'
|
|
9
9
|
import type { SynchronousDatabaseWrapper } from '../SynchronousDatabaseWrapper.js'
|
|
10
10
|
import { emptyDebugInfo as makeEmptyDebugInfo } from '../SynchronousDatabaseWrapper.js'
|
|
11
11
|
import type { ReferenceCountedSet } from '../utils/data-structures.js'
|
package/src/store/store-types.ts
CHANGED
|
@@ -5,8 +5,8 @@ import { Schema } from '@livestore/utils/effect'
|
|
|
5
5
|
import type * as otel from '@opentelemetry/api'
|
|
6
6
|
import type { GraphQLSchema } from 'graphql'
|
|
7
7
|
|
|
8
|
+
import type { ReactivityGraph } from '../live-queries/base-class.js'
|
|
8
9
|
import type { DebugRefreshReasonBase } from '../reactive.js'
|
|
9
|
-
import type { ReactivityGraph } from '../reactiveQueries/base-class.js'
|
|
10
10
|
import type { SynchronousDatabaseWrapper } from '../SynchronousDatabaseWrapper.js'
|
|
11
11
|
import type { StackInfo } from '../utils/stack-info.js'
|
|
12
12
|
import type { Store } from './store.js'
|
|
@@ -84,7 +84,7 @@ export type RefreshReason =
|
|
|
84
84
|
| { _tag: 'manual'; label?: string }
|
|
85
85
|
|
|
86
86
|
export type QueryDebugInfo = {
|
|
87
|
-
_tag: 'graphql' | '
|
|
87
|
+
_tag: 'graphql' | 'db' | 'computed' | 'unknown'
|
|
88
88
|
label: string
|
|
89
89
|
query: string
|
|
90
90
|
durationMs: number
|
package/src/store/store.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import type { ClientSession, ParamsObject } from '@livestore/common'
|
|
2
|
-
import {
|
|
1
|
+
import type { ClientSession, ParamsObject, PreparedBindValues, QueryBuilder } from '@livestore/common'
|
|
2
|
+
import {
|
|
3
|
+
getExecArgsFromMutation,
|
|
4
|
+
getResultSchema,
|
|
5
|
+
isQueryBuilder,
|
|
6
|
+
prepareBindValues,
|
|
7
|
+
QueryBuilderAstSymbol,
|
|
8
|
+
replaceSessionIdSymbol,
|
|
9
|
+
} from '@livestore/common'
|
|
3
10
|
import type { LiveStoreSchema, MutationEvent } from '@livestore/common/schema'
|
|
4
11
|
import {
|
|
5
12
|
isPartialMutationEvent,
|
|
@@ -14,8 +21,9 @@ import { Data, Effect, FiberSet, Inspectable, MutableHashMap, Runtime, Schema, S
|
|
|
14
21
|
import * as otel from '@opentelemetry/api'
|
|
15
22
|
import type { GraphQLSchema } from 'graphql'
|
|
16
23
|
|
|
24
|
+
import type { LiveQuery, QueryContext, ReactivityGraph } from '../live-queries/base-class.js'
|
|
17
25
|
import type { Ref } from '../reactive.js'
|
|
18
|
-
import
|
|
26
|
+
import { makeExecBeforeFirstRun } from '../row-query-utils.js'
|
|
19
27
|
import { SynchronousDatabaseWrapper } from '../SynchronousDatabaseWrapper.js'
|
|
20
28
|
import { ReferenceCountedSet } from '../utils/data-structures.js'
|
|
21
29
|
import { downloadBlob, exposeDebugUtils } from '../utils/dev.js'
|
|
@@ -234,6 +242,39 @@ export class Store<
|
|
|
234
242
|
},
|
|
235
243
|
)
|
|
236
244
|
|
|
245
|
+
query = <TResult>(
|
|
246
|
+
query: QueryBuilder<TResult, any, any> | LiveQuery<TResult, any> | { query: string; bindValues: ParamsObject },
|
|
247
|
+
options?: { otelContext?: otel.Context },
|
|
248
|
+
): TResult => {
|
|
249
|
+
if (typeof query === 'object' && 'query' in query && 'bindValues' in query) {
|
|
250
|
+
return this.syncDbWrapper.select(query.query, {
|
|
251
|
+
bindValues: prepareBindValues(query.bindValues, query.query),
|
|
252
|
+
otelContext: options?.otelContext,
|
|
253
|
+
}) as any
|
|
254
|
+
} else if (isQueryBuilder(query)) {
|
|
255
|
+
const ast = query[QueryBuilderAstSymbol]
|
|
256
|
+
if (ast._tag === 'RowQuery') {
|
|
257
|
+
makeExecBeforeFirstRun({
|
|
258
|
+
table: ast.tableDef,
|
|
259
|
+
id: ast.id,
|
|
260
|
+
insertValues: ast.insertValues,
|
|
261
|
+
otelContext: options?.otelContext,
|
|
262
|
+
})(this.reactivityGraph.context!)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const sqlRes = query.asSql()
|
|
266
|
+
const schema = getResultSchema(query)
|
|
267
|
+
const rawRes = this.syncDbWrapper.select(sqlRes.query, {
|
|
268
|
+
bindValues: sqlRes.bindValues as any as PreparedBindValues,
|
|
269
|
+
otelContext: options?.otelContext,
|
|
270
|
+
queriedTables: new Set([query[QueryBuilderAstSymbol].tableDef.sqliteDef.name]),
|
|
271
|
+
})
|
|
272
|
+
return Schema.decodeSync(schema)(rawRes)
|
|
273
|
+
} else {
|
|
274
|
+
return query.run(options?.otelContext)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
237
278
|
// #region mutate
|
|
238
279
|
mutate: {
|
|
239
280
|
<const TMutationArg extends ReadonlyArray<MutationEvent.PartialForSchema<TSchema>>>(...list: TMutationArg): void
|
|
@@ -518,10 +559,6 @@ export class Store<
|
|
|
518
559
|
this.clientSession.coordinator.execute(query, prepareBindValues(params, query)).pipe(this.runEffectFork)
|
|
519
560
|
}
|
|
520
561
|
|
|
521
|
-
__select = (query: string, params: ParamsObject = {}) => {
|
|
522
|
-
return this.syncDbWrapper.select(query, { bindValues: prepareBindValues(params, query) })
|
|
523
|
-
}
|
|
524
|
-
|
|
525
562
|
private makeTableRef = (tableName: string) =>
|
|
526
563
|
this.reactivityGraph.makeRef(null, {
|
|
527
564
|
equal: () => false,
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { QueryInfo, QueryInfoNone } from '@livestore/common';
|
|
2
|
-
import type { Thunk } from '../reactive.js';
|
|
3
|
-
import type { RefreshReason } from '../store.js';
|
|
4
|
-
import type { GetAtomResult, LiveQuery, QueryContext, ReactivityGraph } from './base-class.js';
|
|
5
|
-
import { LiveStoreQueryBase } from './base-class.js';
|
|
6
|
-
export declare const computed: <TResult, TQueryInfo extends QueryInfo = QueryInfoNone>(fn: (get: GetAtomResult) => TResult, options?: {
|
|
7
|
-
label: string;
|
|
8
|
-
reactivityGraph?: ReactivityGraph;
|
|
9
|
-
queryInfo?: TQueryInfo;
|
|
10
|
-
}) => LiveQuery<TResult, TQueryInfo>;
|
|
11
|
-
export declare class LiveStoreJSQuery<TResult, TQueryInfo extends QueryInfo = QueryInfoNone> extends LiveStoreQueryBase<TResult, TQueryInfo> {
|
|
12
|
-
_tag: 'js';
|
|
13
|
-
/** A reactive thunk representing the query results */
|
|
14
|
-
results$: Thunk<TResult, QueryContext, RefreshReason>;
|
|
15
|
-
label: string;
|
|
16
|
-
protected reactivityGraph: ReactivityGraph;
|
|
17
|
-
queryInfo: TQueryInfo;
|
|
18
|
-
/**
|
|
19
|
-
* Currently only used for "nested destruction" of piped queries
|
|
20
|
-
*
|
|
21
|
-
* i.e. when doing something like `const q = querySQL(...).pipe(...)`
|
|
22
|
-
* we need to also destory the SQL query when the JS query `q` is destroyed
|
|
23
|
-
*/
|
|
24
|
-
private onDestroy;
|
|
25
|
-
constructor({ fn, label, onDestroy, reactivityGraph, queryInfo, }: {
|
|
26
|
-
label: string;
|
|
27
|
-
fn: (get: GetAtomResult) => TResult;
|
|
28
|
-
/** Currently only used for "nested destruction" of piped queries */
|
|
29
|
-
onDestroy?: () => void;
|
|
30
|
-
reactivityGraph?: ReactivityGraph;
|
|
31
|
-
queryInfo?: TQueryInfo;
|
|
32
|
-
});
|
|
33
|
-
destroy: () => void;
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=js.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"js.d.ts","sourceRoot":"","sources":["../../src/reactiveQueries/js.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAIjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC9F,OAAO,EAAE,kBAAkB,EAAqB,MAAM,iBAAiB,CAAA;AAEvE,eAAO,MAAM,QAAQ,GAAI,OAAO,EAAE,UAAU,SAAS,SAAS,sBACxD,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,YACzB;IACR,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,SAAS,CAAC,EAAE,UAAU,CAAA;CACvB,KACA,SAAS,CAAC,OAAO,EAAE,UAAU,CAM5B,CAAA;AAEJ,qBAAa,gBAAgB,CAAC,OAAO,EAAE,UAAU,SAAS,SAAS,GAAG,aAAa,CAAE,SAAQ,kBAAkB,CAC7G,OAAO,EACP,UAAU,CACX;IACC,IAAI,EAAE,IAAI,CAAO;IAEjB,sDAAsD;IACtD,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,CAAC,CAAA;IAErD,KAAK,EAAE,MAAM,CAAA;IAEb,SAAS,CAAC,eAAe,EAAE,eAAe,CAAA;IAE1C,SAAS,EAAE,UAAU,CAAA;IAErB;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAA0B;gBAE/B,EACV,EAAE,EACF,KAAK,EACL,SAAS,EACT,eAAe,EACf,SAAS,GACV,EAAE;QACD,KAAK,EAAE,MAAM,CAAA;QACb,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAA;QACnC,oEAAoE;QACpE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;QACtB,eAAe,CAAC,EAAE,eAAe,CAAA;QACjC,SAAS,CAAC,EAAE,UAAU,CAAA;KACvB;IA0CD,OAAO,aAGN;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"js.js","sourceRoot":"","sources":["../../src/reactiveQueries/js.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAE1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAG1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEvE,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,EAAmC,EACnC,OAIC,EAC+B,EAAE,CAClC,IAAI,gBAAgB,CAAsB;IACxC,EAAE;IACF,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE;IACtC,eAAe,EAAE,OAAO,EAAE,eAAe;IACzC,SAAS,EAAE,OAAO,EAAE,SAAS;CAC9B,CAAC,CAAA;AAEJ,MAAM,OAAO,gBAAwE,SAAQ,kBAG5F;IACC,IAAI,GAAS,IAAI,CAAA;IAEjB,sDAAsD;IACtD,QAAQ,CAA6C;IAErD,KAAK,CAAQ;IAEH,eAAe,CAAiB;IAE1C,SAAS,CAAY;IAErB;;;;;OAKG;IACK,SAAS,CAA0B;IAE3C,YAAY,EACV,EAAE,EACF,KAAK,EACL,SAAS,EACT,eAAe,EACf,SAAS,GAQV;QACC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAElB,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,qBAAqB,CAAA;QAC/D,IAAI,CAAC,SAAS,GAAG,SAAS,IAAK,EAAE,IAAI,EAAE,MAAM,EAAiB,CAAA;QAE9D,MAAM,UAAU,GAAG,GAAG,KAAK,UAAU,CAAA;QAErC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5C,CAAC,GAAG,EAAE,YAAY,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,EAAE,WAAW,EAAE,EAAE,CAClE,UAAU,CAAC,eAAe,CAAC,MAAM,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,IAAI,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE;YACrF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;YACnE,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAA;YAEnD,IAAI,CAAC,GAAG,EAAE,CAAA;YAEV,MAAM,UAAU,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;YAE9C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAEpC,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAA;YAErE,OAAO,GAAG,CAAA;QACZ,CAAC,CAAC,EACJ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,CACjE,CAAA;IACH,CAAC;IAED,qFAAqF;IACrF,2BAA2B;IAC3B,qBAAqB;IACrB,2CAA2C;IAC3C,gCAAgC;IAChC,SAAS;IACT,iCAAiC;IACjC,uCAAuC;IACvC,6CAA6C;IAC7C,OAAO;IAEP,OAAO,GAAG,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC/C,IAAI,CAAC,SAAS,EAAE,EAAE,CAAA;IACpB,CAAC,CAAA;CACF"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { IntentionalShutdownCause, UnexpectedError } from '@livestore/common';
|
|
2
|
-
import { Schema } from '@livestore/utils/effect';
|
|
3
|
-
import type { Store } from './store.js';
|
|
4
|
-
export type LiveStoreContext = LiveStoreContextRunning | {
|
|
5
|
-
stage: 'error';
|
|
6
|
-
error: UnexpectedError | unknown;
|
|
7
|
-
} | {
|
|
8
|
-
stage: 'shutdown';
|
|
9
|
-
cause: IntentionalShutdownCause | StoreAbort;
|
|
10
|
-
};
|
|
11
|
-
declare const StoreAbort_base: Schema.TaggedErrorClass<StoreAbort, "LiveStore.StoreAbort", {
|
|
12
|
-
readonly _tag: Schema.tag<"LiveStore.StoreAbort">;
|
|
13
|
-
}>;
|
|
14
|
-
export declare class StoreAbort extends StoreAbort_base {
|
|
15
|
-
}
|
|
16
|
-
declare const StoreInterrupted_base: Schema.TaggedErrorClass<StoreInterrupted, "LiveStore.StoreInterrupted", {
|
|
17
|
-
readonly _tag: Schema.tag<"LiveStore.StoreInterrupted">;
|
|
18
|
-
}>;
|
|
19
|
-
export declare class StoreInterrupted extends StoreInterrupted_base {
|
|
20
|
-
}
|
|
21
|
-
export type LiveStoreContextRunning = {
|
|
22
|
-
stage: 'running';
|
|
23
|
-
store: Store;
|
|
24
|
-
};
|
|
25
|
-
export {};
|
|
26
|
-
//# sourceMappingURL=store-context.d.ts.map
|