@livestore/livestore 0.3.0-dev.50 → 0.3.0-dev.51
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/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 +31 -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,17 @@ export const depsToString = (deps: DepKey): string => {
|
|
60
69
|
return deps.filter(isNotNil).join(',')
|
61
70
|
}
|
62
71
|
|
63
|
-
|
64
|
-
|
72
|
+
// TODO we should refactor/clean up how LiveQueryDef / SignalDef / LiveQuery / ISignal are defined (particularly on the type-level)
|
73
|
+
export interface LiveQueryDef<TResult, TTag extends string = 'def'> {
|
74
|
+
_tag: TTag
|
65
75
|
/** Creates a new LiveQuery instance bound to a specific store/reactivityGraph */
|
66
|
-
make: (ctx: ReactivityGraphContext, otelContext?: otel.Context) => RcRef<LiveQuery<TResult>>
|
76
|
+
make: (ctx: ReactivityGraphContext, otelContext?: otel.Context) => RcRef<LiveQuery<TResult> | ISignal<TResult>>
|
67
77
|
label: string
|
68
78
|
hash: string
|
69
79
|
}
|
70
80
|
|
71
81
|
export namespace LiveQueryDef {
|
72
|
-
export type Any = LiveQueryDef<any>
|
82
|
+
export type Any = LiveQueryDef<any, 'def' | 'signal-def'>
|
73
83
|
}
|
74
84
|
|
75
85
|
/**
|
@@ -77,7 +87,7 @@ export namespace LiveQueryDef {
|
|
77
87
|
*/
|
78
88
|
export interface LiveQuery<TResult> {
|
79
89
|
id: number
|
80
|
-
_tag: 'computed' | 'db' | 'graphql'
|
90
|
+
_tag: 'computed' | 'db' | 'graphql' | 'signal'
|
81
91
|
[TypeId]: TypeId
|
82
92
|
|
83
93
|
// reactivityGraph: ReactivityGraph
|
@@ -86,7 +96,7 @@ export interface LiveQuery<TResult> {
|
|
86
96
|
'__result!': TResult
|
87
97
|
|
88
98
|
/** A reactive thunk representing the query results */
|
89
|
-
results$: RG.
|
99
|
+
results$: RG.Atom<TResult, ReactivityGraphContext, RefreshReason>
|
90
100
|
|
91
101
|
label: string
|
92
102
|
|
@@ -106,7 +116,7 @@ export interface LiveQuery<TResult> {
|
|
106
116
|
runs: number
|
107
117
|
|
108
118
|
executionTimes: number[]
|
109
|
-
def: LiveQueryDef<TResult>
|
119
|
+
def: LiveQueryDef<TResult> | SignalDef<TResult>
|
110
120
|
}
|
111
121
|
|
112
122
|
export namespace LiveQuery {
|
@@ -117,21 +127,24 @@ export abstract class LiveStoreQueryBase<TResult> implements LiveQuery<TResult>
|
|
117
127
|
'__result!'!: TResult
|
118
128
|
id = queryIdCounter++;
|
119
129
|
[TypeId]: TypeId = TypeId
|
120
|
-
abstract _tag: 'computed' | 'db' | 'graphql'
|
130
|
+
abstract _tag: 'computed' | 'db' | 'graphql' | 'signal'
|
121
131
|
|
122
132
|
/** Human-readable label for the query for debugging */
|
123
133
|
abstract label: string
|
124
134
|
|
125
|
-
abstract def: LiveQueryDef<TResult>
|
135
|
+
abstract def: LiveQueryDef<TResult> | SignalDef<TResult>
|
126
136
|
|
127
|
-
abstract results$: RG.
|
137
|
+
abstract results$: RG.Atom<TResult, ReactivityGraphContext, RefreshReason>
|
128
138
|
|
129
139
|
activeSubscriptions: Set<StackInfo> = new Set()
|
130
140
|
|
131
141
|
abstract readonly reactivityGraph: ReactivityGraph
|
132
142
|
|
133
143
|
get runs() {
|
134
|
-
|
144
|
+
if (this.results$._tag === 'thunk') {
|
145
|
+
return this.results$.recomputations
|
146
|
+
}
|
147
|
+
return 0
|
135
148
|
}
|
136
149
|
|
137
150
|
executionTimes: number[] = []
|
@@ -183,7 +196,9 @@ export const makeGetAtomResult = (
|
|
183
196
|
}
|
184
197
|
|
185
198
|
// Signal case
|
186
|
-
if (atom._tag === 'signal'
|
199
|
+
if (atom._tag === 'signal' && Predicate.hasProperty(atom, 'ref')) {
|
200
|
+
return get(atom.ref, otelContext, debugRefreshReason)
|
201
|
+
}
|
187
202
|
|
188
203
|
// LiveQuery case
|
189
204
|
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
|