@livestore/livestore 0.0.0-snapshot-2cc2dcc1f7d0a534a2247a531ff3ecf6a83f0e63 → 0.0.0-snapshot-846084fc168de30ab64beedc157728bc85d858b0.2
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 +1 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/live-queries/base-class.d.ts +15 -13
- package/dist/live-queries/base-class.d.ts.map +1 -1
- package/dist/live-queries/base-class.js +7 -2
- package/dist/live-queries/base-class.js.map +1 -1
- package/dist/live-queries/computed.d.ts +1 -1
- package/dist/live-queries/computed.d.ts.map +1 -1
- package/dist/live-queries/computed.js.map +1 -1
- package/dist/live-queries/db-query.d.ts +1 -1
- package/dist/live-queries/db-query.d.ts.map +1 -1
- package/dist/live-queries/db-query.js +3 -1
- package/dist/live-queries/db-query.js.map +1 -1
- package/dist/live-queries/signal.d.ts +12 -7
- package/dist/live-queries/signal.d.ts.map +1 -1
- package/dist/live-queries/signal.js +28 -11
- package/dist/live-queries/signal.js.map +1 -1
- package/dist/mod.d.ts +1 -1
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +1 -1
- package/dist/mod.js.map +1 -1
- package/dist/store/store.d.ts +1 -1
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +4 -2
- package/dist/store/store.js.map +1 -1
- package/package.json +5 -5
- package/src/live-queries/base-class.ts +30 -16
- package/src/live-queries/computed.ts +2 -2
- package/src/live-queries/db-query.ts +6 -4
- package/src/live-queries/signal.ts +44 -10
- package/src/mod.ts +10 -1
- package/src/store/store.ts +6 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isNotNil } from '@livestore/utils'
|
|
2
|
+
import { Predicate } from '@livestore/utils/effect'
|
|
2
3
|
import type * as otel from '@opentelemetry/api'
|
|
3
4
|
|
|
4
5
|
import * as RG from '../reactive.js'
|
|
@@ -22,18 +23,26 @@ export type ReactivityGraphContext = {
|
|
|
22
23
|
effectsWrapper: (run: () => void) => void
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
export type GetResult<TQuery extends LiveQueryDef.Any | LiveQuery.Any
|
|
26
|
-
TQuery extends LiveQuery<infer TResult>
|
|
26
|
+
export type GetResult<TQuery extends LiveQueryDef.Any | LiveQuery.Any | SignalDef<any>> =
|
|
27
|
+
TQuery extends LiveQuery<infer TResult>
|
|
28
|
+
? TResult
|
|
29
|
+
: TQuery extends LiveQueryDef<infer TResult>
|
|
30
|
+
? TResult
|
|
31
|
+
: TQuery extends SignalDef<infer TResult>
|
|
32
|
+
? TResult
|
|
33
|
+
: unknown
|
|
27
34
|
|
|
28
35
|
let queryIdCounter = 0
|
|
29
36
|
|
|
30
|
-
export interface SignalDef<T> {
|
|
37
|
+
export interface SignalDef<T> extends LiveQueryDef<T, 'signal-def'> {
|
|
31
38
|
_tag: 'signal-def'
|
|
32
39
|
defaultValue: T
|
|
40
|
+
hash: string
|
|
41
|
+
label: string
|
|
33
42
|
make: (ctx: ReactivityGraphContext) => RcRef<ISignal<T>>
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
export interface ISignal<T> {
|
|
45
|
+
export interface ISignal<T> extends LiveQuery<T> {
|
|
37
46
|
_tag: 'signal'
|
|
38
47
|
reactivityGraph: ReactivityGraph
|
|
39
48
|
ref: RG.Ref<T, ReactivityGraphContext, RefreshReason>
|
|
@@ -60,16 +69,16 @@ export const depsToString = (deps: DepKey): string => {
|
|
|
60
69
|
return deps.filter(isNotNil).join(',')
|
|
61
70
|
}
|
|
62
71
|
|
|
63
|
-
export interface LiveQueryDef<TResult> {
|
|
64
|
-
_tag:
|
|
72
|
+
export interface LiveQueryDef<TResult, TTag extends string = 'def'> {
|
|
73
|
+
_tag: TTag
|
|
65
74
|
/** Creates a new LiveQuery instance bound to a specific store/reactivityGraph */
|
|
66
|
-
make: (ctx: ReactivityGraphContext, otelContext?: otel.Context) => RcRef<LiveQuery<TResult>>
|
|
75
|
+
make: (ctx: ReactivityGraphContext, otelContext?: otel.Context) => RcRef<LiveQuery<TResult> | ISignal<TResult>>
|
|
67
76
|
label: string
|
|
68
77
|
hash: string
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
export namespace LiveQueryDef {
|
|
72
|
-
export type Any = LiveQueryDef<any>
|
|
81
|
+
export type Any = LiveQueryDef<any, 'def' | 'signal-def'>
|
|
73
82
|
}
|
|
74
83
|
|
|
75
84
|
/**
|
|
@@ -77,7 +86,7 @@ export namespace LiveQueryDef {
|
|
|
77
86
|
*/
|
|
78
87
|
export interface LiveQuery<TResult> {
|
|
79
88
|
id: number
|
|
80
|
-
_tag: 'computed' | 'db' | 'graphql'
|
|
89
|
+
_tag: 'computed' | 'db' | 'graphql' | 'signal'
|
|
81
90
|
[TypeId]: TypeId
|
|
82
91
|
|
|
83
92
|
// reactivityGraph: ReactivityGraph
|
|
@@ -86,7 +95,7 @@ export interface LiveQuery<TResult> {
|
|
|
86
95
|
'__result!': TResult
|
|
87
96
|
|
|
88
97
|
/** A reactive thunk representing the query results */
|
|
89
|
-
results$: RG.
|
|
98
|
+
results$: RG.Atom<TResult, ReactivityGraphContext, RefreshReason>
|
|
90
99
|
|
|
91
100
|
label: string
|
|
92
101
|
|
|
@@ -106,7 +115,7 @@ export interface LiveQuery<TResult> {
|
|
|
106
115
|
runs: number
|
|
107
116
|
|
|
108
117
|
executionTimes: number[]
|
|
109
|
-
def: LiveQueryDef<TResult>
|
|
118
|
+
def: LiveQueryDef<TResult> | SignalDef<TResult>
|
|
110
119
|
}
|
|
111
120
|
|
|
112
121
|
export namespace LiveQuery {
|
|
@@ -117,21 +126,24 @@ export abstract class LiveStoreQueryBase<TResult> implements LiveQuery<TResult>
|
|
|
117
126
|
'__result!'!: TResult
|
|
118
127
|
id = queryIdCounter++;
|
|
119
128
|
[TypeId]: TypeId = TypeId
|
|
120
|
-
abstract _tag: 'computed' | 'db' | 'graphql'
|
|
129
|
+
abstract _tag: 'computed' | 'db' | 'graphql' | 'signal'
|
|
121
130
|
|
|
122
131
|
/** Human-readable label for the query for debugging */
|
|
123
132
|
abstract label: string
|
|
124
133
|
|
|
125
|
-
abstract def: LiveQueryDef<TResult>
|
|
134
|
+
abstract def: LiveQueryDef<TResult> | SignalDef<TResult>
|
|
126
135
|
|
|
127
|
-
abstract results$: RG.
|
|
136
|
+
abstract results$: RG.Atom<TResult, ReactivityGraphContext, RefreshReason>
|
|
128
137
|
|
|
129
138
|
activeSubscriptions: Set<StackInfo> = new Set()
|
|
130
139
|
|
|
131
140
|
abstract readonly reactivityGraph: ReactivityGraph
|
|
132
141
|
|
|
133
142
|
get runs() {
|
|
134
|
-
|
|
143
|
+
if (this.results$._tag === 'thunk') {
|
|
144
|
+
return this.results$.recomputations
|
|
145
|
+
}
|
|
146
|
+
return 0
|
|
135
147
|
}
|
|
136
148
|
|
|
137
149
|
executionTimes: number[] = []
|
|
@@ -183,7 +195,9 @@ export const makeGetAtomResult = (
|
|
|
183
195
|
}
|
|
184
196
|
|
|
185
197
|
// Signal case
|
|
186
|
-
if (atom._tag === 'signal'
|
|
198
|
+
if (atom._tag === 'signal' && Predicate.hasProperty(atom, 'ref')) {
|
|
199
|
+
return get(atom.ref, otelContext, debugRefreshReason)
|
|
200
|
+
}
|
|
187
201
|
|
|
188
202
|
// LiveQuery case
|
|
189
203
|
return get(atom.results$, otelContext, debugRefreshReason)
|
|
@@ -19,7 +19,7 @@ export const computed = <TResult>(
|
|
|
19
19
|
throw new Error(`On Expo/React Native, computed queries must provide a \`deps\` option`)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const def: LiveQueryDef
|
|
22
|
+
const def: LiveQueryDef<any> = {
|
|
23
23
|
_tag: 'def',
|
|
24
24
|
make: withRCMap(hash, (ctx, _otelContext) => {
|
|
25
25
|
// TODO onDestroy
|
|
@@ -41,7 +41,7 @@ export const computed = <TResult>(
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export class LiveStoreComputedQuery<TResult> extends LiveStoreQueryBase<TResult> {
|
|
44
|
-
_tag
|
|
44
|
+
_tag = 'computed' as const
|
|
45
45
|
|
|
46
46
|
/** A reactive thunk representing the query results */
|
|
47
47
|
results$: Thunk<TResult, ReactivityGraphContext, RefreshReason>
|
|
@@ -102,8 +102,10 @@ export const queryDb: {
|
|
|
102
102
|
} = (queryInput, options) => {
|
|
103
103
|
const { queryString, extraDeps } = getQueryStringAndExtraDeps(queryInput)
|
|
104
104
|
|
|
105
|
-
const hash =
|
|
106
|
-
|
|
105
|
+
const hash = [queryString, options?.deps ? depsToString(options.deps) : undefined, depsToString(extraDeps)]
|
|
106
|
+
.filter(Boolean)
|
|
107
|
+
.join('-')
|
|
108
|
+
|
|
107
109
|
if (isValidFunctionString(hash)._tag === 'invalid') {
|
|
108
110
|
throw new Error(`On Expo/React Native, db queries must provide a \`deps\` option`)
|
|
109
111
|
}
|
|
@@ -114,7 +116,7 @@ export const queryDb: {
|
|
|
114
116
|
|
|
115
117
|
const label = options?.label ?? queryString
|
|
116
118
|
|
|
117
|
-
const def: LiveQueryDef
|
|
119
|
+
const def: LiveQueryDef<any> = {
|
|
118
120
|
_tag: 'def',
|
|
119
121
|
make: withRCMap(hash, (ctx, otelContext) => {
|
|
120
122
|
// TODO onDestroy
|
|
@@ -165,7 +167,7 @@ const getQueryStringAndExtraDeps = (
|
|
|
165
167
|
|
|
166
168
|
/* An object encapsulating a reactive SQL query */
|
|
167
169
|
export class LiveStoreDbQuery<TResultSchema, TResult = TResultSchema> extends LiveStoreQueryBase<TResult> {
|
|
168
|
-
_tag
|
|
170
|
+
_tag = 'db' as const
|
|
169
171
|
|
|
170
172
|
/** A reactive thunk representing the query text */
|
|
171
173
|
queryInput$: Thunk<QueryInputRaw<any, any>, ReactivityGraphContext, RefreshReason> | undefined
|
|
@@ -3,7 +3,7 @@ import { nanoid } from '@livestore/utils/nanoid'
|
|
|
3
3
|
import type * as RG from '../reactive.js'
|
|
4
4
|
import type { RefreshReason } from '../store/store-types.js'
|
|
5
5
|
import type { ISignal, ReactivityGraph, ReactivityGraphContext, SignalDef } from './base-class.js'
|
|
6
|
-
import { withRCMap } from './base-class.js'
|
|
6
|
+
import { LiveStoreQueryBase, withRCMap } from './base-class.js'
|
|
7
7
|
|
|
8
8
|
export const signal = <T>(
|
|
9
9
|
defaultValue: T,
|
|
@@ -12,25 +12,59 @@ export const signal = <T>(
|
|
|
12
12
|
},
|
|
13
13
|
): SignalDef<T> => {
|
|
14
14
|
const id = nanoid()
|
|
15
|
-
|
|
15
|
+
const def: SignalDef<T> = {
|
|
16
16
|
_tag: 'signal-def',
|
|
17
17
|
defaultValue,
|
|
18
|
-
|
|
18
|
+
hash: id,
|
|
19
|
+
label: options?.label ?? 'Signal',
|
|
20
|
+
make: withRCMap(
|
|
21
|
+
id,
|
|
22
|
+
(ctx) =>
|
|
23
|
+
new Signal({
|
|
24
|
+
defaultValue,
|
|
25
|
+
reactivityGraph: ctx.reactivityGraph.deref()!,
|
|
26
|
+
label: options?.label ?? 'Signal',
|
|
27
|
+
def,
|
|
28
|
+
}),
|
|
29
|
+
),
|
|
19
30
|
}
|
|
31
|
+
|
|
32
|
+
return def
|
|
20
33
|
}
|
|
21
34
|
|
|
22
|
-
export class Signal<T> implements ISignal<T> {
|
|
35
|
+
export class Signal<T> extends LiveStoreQueryBase<T> implements ISignal<T> {
|
|
23
36
|
_tag = 'signal' as const
|
|
24
37
|
readonly ref: RG.Ref<T, ReactivityGraphContext, RefreshReason>
|
|
25
|
-
|
|
38
|
+
label: string
|
|
39
|
+
reactivityGraph: ReactivityGraph
|
|
40
|
+
results$: RG.Ref<T, ReactivityGraphContext, RefreshReason>
|
|
41
|
+
def: SignalDef<T>
|
|
26
42
|
constructor(
|
|
27
|
-
private defaultValue: T,
|
|
28
|
-
readonly reactivityGraph: ReactivityGraph,
|
|
29
|
-
private options?: {
|
|
30
|
-
|
|
43
|
+
// private defaultValue: T,
|
|
44
|
+
// readonly reactivityGraph: ReactivityGraph,
|
|
45
|
+
// private options?: {
|
|
46
|
+
// label?: string
|
|
47
|
+
// },
|
|
48
|
+
{
|
|
49
|
+
defaultValue,
|
|
50
|
+
reactivityGraph,
|
|
51
|
+
label,
|
|
52
|
+
def,
|
|
53
|
+
}: {
|
|
54
|
+
defaultValue: T
|
|
55
|
+
reactivityGraph: ReactivityGraph
|
|
56
|
+
label: string
|
|
57
|
+
def: SignalDef<T>
|
|
31
58
|
},
|
|
32
59
|
) {
|
|
33
|
-
|
|
60
|
+
super()
|
|
61
|
+
|
|
62
|
+
this.ref = reactivityGraph.makeRef(defaultValue, { label })
|
|
63
|
+
this.label = label
|
|
64
|
+
this.reactivityGraph = reactivityGraph
|
|
65
|
+
this.def = def
|
|
66
|
+
|
|
67
|
+
this.results$ = this.ref
|
|
34
68
|
}
|
|
35
69
|
|
|
36
70
|
set = (value: T) => {
|
package/src/mod.ts
CHANGED
|
@@ -13,7 +13,16 @@ export {
|
|
|
13
13
|
|
|
14
14
|
export { SqliteDbWrapper, emptyDebugInfo } from './SqliteDbWrapper.js'
|
|
15
15
|
|
|
16
|
-
export {
|
|
16
|
+
export {
|
|
17
|
+
queryDb,
|
|
18
|
+
computed,
|
|
19
|
+
signal,
|
|
20
|
+
type LiveQuery,
|
|
21
|
+
type LiveQueryDef,
|
|
22
|
+
type Signal,
|
|
23
|
+
type SignalDef,
|
|
24
|
+
type RcRef,
|
|
25
|
+
} from './live-queries/mod.js'
|
|
17
26
|
|
|
18
27
|
export * from '@livestore/common/schema'
|
|
19
28
|
export {
|
package/src/store/store.ts
CHANGED
|
@@ -135,7 +135,9 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
|
135
135
|
this.sqliteDbWrapper.execute(statementSql, bindValues, { otelContext, writeTables })
|
|
136
136
|
|
|
137
137
|
// durationMsTotal += durationMs
|
|
138
|
-
|
|
138
|
+
for (const table of writeTables) {
|
|
139
|
+
writeTablesForEvent.add(table)
|
|
140
|
+
}
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
143
|
|
|
@@ -262,7 +264,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
|
262
264
|
* ```
|
|
263
265
|
*/
|
|
264
266
|
subscribe = <TResult>(
|
|
265
|
-
query: LiveQueryDef<TResult> | LiveQuery<TResult>,
|
|
267
|
+
query: LiveQueryDef<TResult, 'def' | 'signal-def'> | LiveQuery<TResult>,
|
|
266
268
|
options: {
|
|
267
269
|
/** Called when the query result has changed */
|
|
268
270
|
onUpdate: (value: TResult) => void
|
|
@@ -289,10 +291,10 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
|
289
291
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
290
292
|
|
|
291
293
|
const queryRcRef =
|
|
292
|
-
query._tag === 'def'
|
|
294
|
+
query._tag === 'def' || query._tag === 'signal-def'
|
|
293
295
|
? query.make(this.reactivityGraph.context!)
|
|
294
296
|
: {
|
|
295
|
-
value: query
|
|
297
|
+
value: query as LiveQuery<TResult>,
|
|
296
298
|
deref: () => {},
|
|
297
299
|
}
|
|
298
300
|
const query$ = queryRcRef.value
|