@livestore/livestore 0.0.19 → 0.0.21
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 +18 -21
- package/dist/.tsbuildinfo +1 -1
- package/dist/QueryCache.d.ts +1 -1
- package/dist/QueryCache.d.ts.map +1 -1
- package/dist/QueryCache.js.map +1 -1
- package/dist/__tests__/react/fixture.d.ts +5 -4
- package/dist/__tests__/react/fixture.d.ts.map +1 -1
- package/dist/__tests__/react/fixture.js +5 -5
- package/dist/__tests__/react/fixture.js.map +1 -1
- package/dist/__tests__/react/useComponentState.test.d.ts +2 -0
- package/dist/__tests__/react/useComponentState.test.d.ts.map +1 -0
- package/dist/__tests__/react/useComponentState.test.js +68 -0
- package/dist/__tests__/react/useComponentState.test.js.map +1 -0
- package/dist/__tests__/react/useLQuery.test.d.ts +2 -0
- package/dist/__tests__/react/useLQuery.test.d.ts.map +1 -0
- package/dist/__tests__/react/useLQuery.test.js +38 -0
- package/dist/__tests__/react/useLQuery.test.js.map +1 -0
- package/dist/__tests__/react/useLiveStoreComponent.test.js +4 -9
- package/dist/__tests__/react/useLiveStoreComponent.test.js.map +1 -1
- package/dist/__tests__/react/useQuery.test.d.ts +2 -0
- package/dist/__tests__/react/useQuery.test.d.ts.map +1 -0
- package/dist/__tests__/react/useQuery.test.js +33 -0
- package/dist/__tests__/react/useQuery.test.js.map +1 -0
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.d.ts +2 -0
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.d.ts.map +1 -0
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.js +38 -0
- package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.js.map +1 -0
- package/dist/__tests__/reactive.test.js +167 -93
- package/dist/__tests__/reactive.test.js.map +1 -1
- package/dist/__tests__/reactiveQueries/sql.test.d.ts +2 -0
- package/dist/__tests__/reactiveQueries/sql.test.d.ts.map +1 -0
- package/dist/__tests__/reactiveQueries/sql.test.js +337 -0
- package/dist/__tests__/reactiveQueries/sql.test.js.map +1 -0
- package/dist/inMemoryDatabase.d.ts +2 -2
- package/dist/inMemoryDatabase.d.ts.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/useComponentState.d.ts +50 -0
- package/dist/react/useComponentState.d.ts.map +1 -0
- package/dist/react/useComponentState.js +248 -0
- package/dist/react/useComponentState.js.map +1 -0
- package/dist/react/useGlobalQuery.d.ts +3 -0
- package/dist/react/useGlobalQuery.d.ts.map +1 -0
- package/dist/react/useGlobalQuery.js +26 -0
- package/dist/react/useGlobalQuery.js.map +1 -0
- package/dist/react/useGraphQL.d.ts +3 -3
- package/dist/react/useGraphQL.d.ts.map +1 -1
- package/dist/react/useGraphQL.js +10 -8
- package/dist/react/useGraphQL.js.map +1 -1
- package/dist/react/useLiveStoreComponent.d.ts +6 -6
- package/dist/react/useLiveStoreComponent.d.ts.map +1 -1
- package/dist/react/useLiveStoreComponent.js +143 -99
- package/dist/react/useLiveStoreComponent.js.map +1 -1
- package/dist/react/useQuery.d.ts +2 -2
- package/dist/react/useQuery.d.ts.map +1 -1
- package/dist/react/useQuery.js +26 -22
- package/dist/react/useQuery.js.map +1 -1
- package/dist/react/useTemporaryQuery.d.ts +8 -0
- package/dist/react/useTemporaryQuery.d.ts.map +1 -0
- package/dist/react/useTemporaryQuery.js +17 -0
- package/dist/react/useTemporaryQuery.js.map +1 -0
- package/dist/react/utils/extractNamesFromStackTrace.d.ts +3 -0
- package/dist/react/utils/extractNamesFromStackTrace.d.ts.map +1 -0
- package/dist/react/utils/extractNamesFromStackTrace.js +40 -0
- package/dist/react/utils/extractNamesFromStackTrace.js.map +1 -0
- package/dist/react/utils/extractStackInfoFromStackTrace.d.ts +7 -0
- package/dist/react/utils/extractStackInfoFromStackTrace.d.ts.map +1 -0
- package/dist/react/utils/extractStackInfoFromStackTrace.js +40 -0
- package/dist/react/utils/extractStackInfoFromStackTrace.js.map +1 -0
- package/dist/reactive.d.ts +42 -48
- package/dist/reactive.d.ts.map +1 -1
- package/dist/reactive.js +293 -186
- package/dist/reactive.js.map +1 -1
- package/dist/reactiveQueries/base-class.d.ts +28 -23
- package/dist/reactiveQueries/base-class.d.ts.map +1 -1
- package/dist/reactiveQueries/base-class.js +25 -18
- package/dist/reactiveQueries/base-class.js.map +1 -1
- package/dist/reactiveQueries/graph.d.ts +10 -0
- package/dist/reactiveQueries/graph.d.ts.map +1 -0
- package/dist/reactiveQueries/graph.js +6 -0
- package/dist/reactiveQueries/graph.js.map +1 -0
- package/dist/reactiveQueries/graphql.d.ts +34 -17
- package/dist/reactiveQueries/graphql.d.ts.map +1 -1
- package/dist/reactiveQueries/graphql.js +91 -10
- package/dist/reactiveQueries/graphql.js.map +1 -1
- package/dist/reactiveQueries/js.d.ts +16 -12
- package/dist/reactiveQueries/js.d.ts.map +1 -1
- package/dist/reactiveQueries/js.js +31 -8
- package/dist/reactiveQueries/js.js.map +1 -1
- package/dist/reactiveQueries/sql.d.ts +22 -18
- package/dist/reactiveQueries/sql.d.ts.map +1 -1
- package/dist/reactiveQueries/sql.js +82 -16
- package/dist/reactiveQueries/sql.js.map +1 -1
- package/dist/store.d.ts +12 -52
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +283 -264
- package/dist/store.js.map +1 -1
- package/package.json +4 -3
- package/src/QueryCache.ts +1 -1
- package/src/__tests__/react/fixture.tsx +12 -7
- package/src/__tests__/react/{useLiveStoreComponent.test.tsx → useComponentState.test.tsx} +9 -20
- package/src/__tests__/react/useQuery.test.tsx +48 -0
- package/src/__tests__/react/utils/extractStackInfoFromStackTrace.test.ts +40 -0
- package/src/__tests__/reactive.test.ts +193 -140
- package/src/__tests__/reactiveQueries/sql.test.ts +372 -0
- package/src/inMemoryDatabase.ts +2 -2
- package/src/index.ts +7 -11
- package/src/react/index.ts +3 -7
- package/src/react/{useLiveStoreComponent.ts → useComponentState.ts} +89 -247
- package/src/react/useQuery.ts +29 -27
- package/src/react/useTemporaryQuery.ts +21 -0
- package/src/react/utils/extractStackInfoFromStackTrace.ts +47 -0
- package/src/reactive.ts +385 -268
- package/src/reactiveQueries/base-class.ts +60 -44
- package/src/reactiveQueries/graph.ts +15 -0
- package/src/reactiveQueries/graphql.ts +145 -29
- package/src/reactiveQueries/js.ts +53 -20
- package/src/reactiveQueries/sql.ts +129 -36
- package/src/store.ts +338 -408
- package/src/react/useGraphQL.ts +0 -138
package/src/react/useGraphQL.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'
|
|
2
|
-
import * as otel from '@opentelemetry/api'
|
|
3
|
-
import { isEqual } from 'lodash-es'
|
|
4
|
-
import React from 'react'
|
|
5
|
-
|
|
6
|
-
import { labelForKey } from '../componentKey.js'
|
|
7
|
-
import { useStore } from './LiveStoreContext.js'
|
|
8
|
-
import { type ComponentKeyConfig, useComponentKey } from './useLiveStoreComponent.js'
|
|
9
|
-
import { useStateRefWithReactiveInput } from './utils/useStateRefWithReactiveInput.js'
|
|
10
|
-
|
|
11
|
-
export type UseLiveStoreComponentProps<TResult extends Record<string, any>, TVariables extends Record<string, any>> = {
|
|
12
|
-
query: DocumentNode<TResult, TVariables>
|
|
13
|
-
variables: TVariables
|
|
14
|
-
componentKey: ComponentKeyConfig
|
|
15
|
-
reactDeps?: React.DependencyList
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
type Variables = Record<string, any>
|
|
19
|
-
|
|
20
|
-
// TODO get rid of the query cache in favour of the new side-effect-free query definition approach https://www.notion.so/schickling/New-query-definition-approach-1097a78ef0e9495bac25f90417374756?pvs=4
|
|
21
|
-
// NOTE we're using a nested map here since we need to resolve 2 levels of object identities (query + variables)
|
|
22
|
-
// const queryCache = new Map<DocumentNode<any, any>, Map<Variables, LiveStoreGraphQLQuery<any, any, any>>>()
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* This is needed because the `React.useMemo` call below, can sometimes be called multiple times 🤷,
|
|
26
|
-
* so we need to "cache" the fact that we've already started a span for this component.
|
|
27
|
-
* The map entry is being removed again in the `React.useEffect` call below.
|
|
28
|
-
*/
|
|
29
|
-
const spanAlreadyStartedCache = new Map<string, { span: otel.Span; otelContext: otel.Context }>()
|
|
30
|
-
|
|
31
|
-
// TODO 1) figure out a way to make `variables` optional if the query doesn't have any variables (probably requires positional args)
|
|
32
|
-
// TODO 2) allow `.pipe` on the resulting query (possibly as a separate optional prop)
|
|
33
|
-
export const useGraphQL = <TResult extends Record<string, any>, TVariables extends Variables = {}>({
|
|
34
|
-
query,
|
|
35
|
-
variables,
|
|
36
|
-
componentKey: componentKeyConfig,
|
|
37
|
-
reactDeps = [],
|
|
38
|
-
}: UseLiveStoreComponentProps<TResult, TVariables>): Readonly<TResult> => {
|
|
39
|
-
const componentKey = useComponentKey(componentKeyConfig, reactDeps)
|
|
40
|
-
const { store } = useStore()
|
|
41
|
-
|
|
42
|
-
const componentKeyLabel = React.useMemo(() => labelForKey(componentKey), [componentKey])
|
|
43
|
-
|
|
44
|
-
// The following `React.useMemo` and `React.useEffect` calls are used to start and end a span for the lifetime of this component.
|
|
45
|
-
const { span, otelContext } = React.useMemo(() => {
|
|
46
|
-
const existingSpan = spanAlreadyStartedCache.get(componentKeyLabel)
|
|
47
|
-
if (existingSpan !== undefined) return existingSpan
|
|
48
|
-
|
|
49
|
-
const span = store.otel.tracer.startSpan(
|
|
50
|
-
`LiveStore:useGraphQL:${componentKeyLabel}`,
|
|
51
|
-
{},
|
|
52
|
-
store.otel.queriesSpanContext,
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
56
|
-
|
|
57
|
-
spanAlreadyStartedCache.set(componentKeyLabel, { span, otelContext })
|
|
58
|
-
|
|
59
|
-
return { span, otelContext }
|
|
60
|
-
}, [componentKeyLabel, store.otel.queriesSpanContext, store.otel.tracer])
|
|
61
|
-
|
|
62
|
-
React.useEffect(
|
|
63
|
-
() => () => {
|
|
64
|
-
spanAlreadyStartedCache.delete(componentKeyLabel)
|
|
65
|
-
span.end()
|
|
66
|
-
},
|
|
67
|
-
[componentKeyLabel, span],
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
const makeLiveStoreQuery = React.useCallback(
|
|
71
|
-
() => {
|
|
72
|
-
return store.queryGraphQL(query, () => variables ?? ({} as TVariables), { componentKey, otelContext })
|
|
73
|
-
|
|
74
|
-
// NOTE I had to disable the caching below as still led to many problems
|
|
75
|
-
// We should just implement the new query definition approach instead
|
|
76
|
-
|
|
77
|
-
// const queryCacheForQuery = queryCache.get(query)
|
|
78
|
-
// if (queryCacheForQuery && queryCacheForQuery.has(variables)) {
|
|
79
|
-
// return queryCacheForQuery.get(variables)!
|
|
80
|
-
// }
|
|
81
|
-
|
|
82
|
-
// const newQuery = store.queryGraphQL(query, () => variables ?? ({} as TVariables), { componentKey, otelContext })
|
|
83
|
-
|
|
84
|
-
// if (queryCacheForQuery) {
|
|
85
|
-
// queryCacheForQuery.set(variables, newQuery)
|
|
86
|
-
// } else {
|
|
87
|
-
// queryCache.set(query, new Map([[variables, newQuery]]))
|
|
88
|
-
// }
|
|
89
|
-
|
|
90
|
-
// return newQuery
|
|
91
|
-
},
|
|
92
|
-
// NOTE: we don't include the queries function passed in by the user here;
|
|
93
|
-
// the reason is that we don't want to force them to memoize that function.
|
|
94
|
-
// Instead, we just assume that the function always has the same contents.
|
|
95
|
-
// This makes sense for LiveStore because the component config should be static.
|
|
96
|
-
// TODO: document this and consider whether it's the right API surface.
|
|
97
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
98
|
-
[componentKey, store],
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
// TODO get rid of the temporary query workaround
|
|
102
|
-
const initialQueryResults = React.useMemo(
|
|
103
|
-
() => store.inTempQueryContext(() => makeLiveStoreQuery().results$.result),
|
|
104
|
-
[makeLiveStoreQuery, store],
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
const [queryResultsRef, setQueryResults_] = useStateRefWithReactiveInput<TResult>(initialQueryResults)
|
|
108
|
-
|
|
109
|
-
React.useEffect(() => {
|
|
110
|
-
const liveStoreQuery = makeLiveStoreQuery()
|
|
111
|
-
const unsubscribe = store.subscribe(
|
|
112
|
-
liveStoreQuery,
|
|
113
|
-
(results) => {
|
|
114
|
-
if (isEqual(results, queryResultsRef.current) === false) {
|
|
115
|
-
setQueryResults_(results)
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
undefined,
|
|
119
|
-
{ label: `useGraphQL:query:subscribe:${liveStoreQuery.label}` },
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
return () => {
|
|
123
|
-
unsubscribe()
|
|
124
|
-
}
|
|
125
|
-
// NOTE `setQueryResults_` from the deps array as it seems to cause an infinite loop
|
|
126
|
-
// This should probably be improved
|
|
127
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
128
|
-
}, [
|
|
129
|
-
makeLiveStoreQuery,
|
|
130
|
-
// setQueryResults_,
|
|
131
|
-
store,
|
|
132
|
-
])
|
|
133
|
-
|
|
134
|
-
// Very important: remove any queries / other resources associated w/ this component
|
|
135
|
-
React.useEffect(() => () => store.unmountComponent(componentKey), [store, componentKey])
|
|
136
|
-
|
|
137
|
-
return queryResultsRef.current
|
|
138
|
-
}
|