@livestore/react 0.0.0-snapshot-2411da6706c12365b5aa4533b551b9b6554d4617 → 0.0.0-snapshot-2ba399f1522c4d89e40c6bedb64f94b6a0889a4d
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/LiveStoreContext.d.ts.map +1 -1
- package/dist/LiveStoreProvider.d.ts +6 -8
- package/dist/LiveStoreProvider.d.ts.map +1 -1
- package/dist/LiveStoreProvider.js +11 -16
- package/dist/LiveStoreProvider.js.map +1 -1
- package/dist/LiveStoreProvider.test.js +1 -1
- package/dist/LiveStoreProvider.test.js.map +1 -1
- package/dist/__tests__/fixture.d.ts +2 -2
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/experimental/components/LiveList.d.ts.map +1 -1
- package/dist/useAtom.d.ts +4 -3
- package/dist/useAtom.d.ts.map +1 -1
- package/dist/useAtom.js.map +1 -1
- package/dist/useQuery.d.ts +8 -7
- package/dist/useQuery.d.ts.map +1 -1
- package/dist/useQuery.js.map +1 -1
- package/dist/useRcResource.d.ts.map +1 -1
- package/dist/utils/useStateRefWithReactiveInput.d.ts.map +1 -1
- package/package.json +12 -11
- package/src/LiveStoreProvider.test.tsx +1 -1
- package/src/LiveStoreProvider.tsx +44 -31
- package/src/useAtom.ts +8 -4
- package/src/useQuery.ts +10 -9
|
@@ -2,25 +2,34 @@ import type { Adapter, BootStatus, IntentionalShutdownCause, MigrationsReport }
|
|
|
2
2
|
import { provideOtel, UnexpectedError } from '@livestore/common'
|
|
3
3
|
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
4
4
|
import type {
|
|
5
|
-
BaseGraphQLContext,
|
|
6
5
|
CreateStoreOptions,
|
|
7
|
-
GraphQLOptions,
|
|
8
6
|
LiveStoreContext as StoreContext_,
|
|
9
7
|
OtelOptions,
|
|
10
8
|
ShutdownDeferred,
|
|
11
9
|
Store,
|
|
12
10
|
} from '@livestore/livestore'
|
|
13
|
-
import { createStore,
|
|
11
|
+
import { createStore, StoreInterrupted } from '@livestore/livestore'
|
|
14
12
|
import { errorToString, LS_DEV } from '@livestore/utils'
|
|
15
13
|
import type { OtelTracer } from '@livestore/utils/effect'
|
|
16
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Cause,
|
|
16
|
+
Deferred,
|
|
17
|
+
Effect,
|
|
18
|
+
Exit,
|
|
19
|
+
identity,
|
|
20
|
+
Logger,
|
|
21
|
+
LogLevel,
|
|
22
|
+
Schema,
|
|
23
|
+
Scope,
|
|
24
|
+
TaskTracing,
|
|
25
|
+
} from '@livestore/utils/effect'
|
|
17
26
|
import type * as otel from '@opentelemetry/api'
|
|
18
27
|
import type { ReactElement, ReactNode } from 'react'
|
|
19
28
|
import React from 'react'
|
|
20
29
|
|
|
21
30
|
import { LiveStoreContext } from './LiveStoreContext.js'
|
|
22
31
|
|
|
23
|
-
interface LiveStoreProviderProps
|
|
32
|
+
export interface LiveStoreProviderProps {
|
|
24
33
|
schema: LiveStoreSchema
|
|
25
34
|
/**
|
|
26
35
|
* The `storeId` can be used to isolate multiple stores from each other.
|
|
@@ -34,14 +43,13 @@ interface LiveStoreProviderProps<GraphQLContext extends BaseGraphQLContext> {
|
|
|
34
43
|
*/
|
|
35
44
|
storeId?: string
|
|
36
45
|
boot?: (
|
|
37
|
-
store: Store<
|
|
46
|
+
store: Store<LiveStoreSchema>,
|
|
38
47
|
ctx: { migrationsReport: MigrationsReport; parentSpan: otel.Span },
|
|
39
48
|
) => void | Promise<void> | Effect.Effect<void, unknown, OtelTracer.OtelTracer>
|
|
40
|
-
graphQLOptions?: GraphQLOptions<GraphQLContext>
|
|
41
49
|
otelOptions?: Partial<OtelOptions>
|
|
42
50
|
renderLoading: (status: BootStatus) => ReactElement
|
|
43
51
|
renderError?: (error: UnexpectedError | unknown) => ReactElement
|
|
44
|
-
renderShutdown?: (cause: IntentionalShutdownCause |
|
|
52
|
+
renderShutdown?: (cause: IntentionalShutdownCause | StoreInterrupted) => ReactElement
|
|
45
53
|
adapter: Adapter
|
|
46
54
|
/**
|
|
47
55
|
* In order for LiveStore to apply multiple mutations in a single render,
|
|
@@ -63,10 +71,10 @@ interface LiveStoreProviderProps<GraphQLContext extends BaseGraphQLContext> {
|
|
|
63
71
|
const defaultRenderError = (error: UnexpectedError | unknown) => (
|
|
64
72
|
<>{Schema.is(UnexpectedError)(error) ? error.toString() : errorToString(error)}</>
|
|
65
73
|
)
|
|
66
|
-
const defaultRenderShutdown = (cause: IntentionalShutdownCause |
|
|
74
|
+
const defaultRenderShutdown = (cause: IntentionalShutdownCause | StoreInterrupted) => {
|
|
67
75
|
const reason =
|
|
68
|
-
cause._tag === 'LiveStore.
|
|
69
|
-
?
|
|
76
|
+
cause._tag === 'LiveStore.StoreInterrupted'
|
|
77
|
+
? `interrupted due to: ${cause.reason}`
|
|
70
78
|
: cause.reason === 'devtools-import'
|
|
71
79
|
? 'devtools import'
|
|
72
80
|
: cause.reason === 'devtools-reset'
|
|
@@ -78,11 +86,10 @@ const defaultRenderShutdown = (cause: IntentionalShutdownCause | StoreAbort) =>
|
|
|
78
86
|
return <>LiveStore Shutdown due to {reason}</>
|
|
79
87
|
}
|
|
80
88
|
|
|
81
|
-
export const LiveStoreProvider =
|
|
89
|
+
export const LiveStoreProvider = ({
|
|
82
90
|
renderLoading,
|
|
83
91
|
renderError = defaultRenderError,
|
|
84
92
|
renderShutdown = defaultRenderShutdown,
|
|
85
|
-
graphQLOptions,
|
|
86
93
|
otelOptions,
|
|
87
94
|
children,
|
|
88
95
|
schema,
|
|
@@ -92,11 +99,10 @@ export const LiveStoreProvider = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
92
99
|
batchUpdates,
|
|
93
100
|
disableDevtools,
|
|
94
101
|
signal,
|
|
95
|
-
}: LiveStoreProviderProps
|
|
102
|
+
}: LiveStoreProviderProps & { children?: ReactNode }): React.ReactElement => {
|
|
96
103
|
const storeCtx = useCreateStore({
|
|
97
104
|
storeId,
|
|
98
105
|
schema,
|
|
99
|
-
graphQLOptions,
|
|
100
106
|
otelOptions,
|
|
101
107
|
boot,
|
|
102
108
|
adapter,
|
|
@@ -138,17 +144,16 @@ const withSemaphore = (storeId: SchemaKey) => {
|
|
|
138
144
|
return semaphore.withPermits(1)
|
|
139
145
|
}
|
|
140
146
|
|
|
141
|
-
const useCreateStore =
|
|
147
|
+
const useCreateStore = ({
|
|
142
148
|
schema,
|
|
143
149
|
storeId,
|
|
144
|
-
graphQLOptions,
|
|
145
150
|
otelOptions,
|
|
146
151
|
boot,
|
|
147
152
|
adapter,
|
|
148
153
|
batchUpdates,
|
|
149
154
|
disableDevtools,
|
|
150
155
|
signal,
|
|
151
|
-
}: CreateStoreOptions<
|
|
156
|
+
}: CreateStoreOptions<LiveStoreSchema> & {
|
|
152
157
|
signal?: AbortSignal
|
|
153
158
|
otelOptions?: Partial<OtelOptions>
|
|
154
159
|
}) => {
|
|
@@ -169,7 +174,6 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
169
174
|
|
|
170
175
|
const inputPropsCacheRef = React.useRef({
|
|
171
176
|
schema,
|
|
172
|
-
graphQLOptions,
|
|
173
177
|
otelOptions,
|
|
174
178
|
boot,
|
|
175
179
|
adapter,
|
|
@@ -181,7 +185,7 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
181
185
|
const interrupt = (
|
|
182
186
|
componentScope: Scope.CloseableScope,
|
|
183
187
|
shutdownDeferred: ShutdownDeferred,
|
|
184
|
-
error:
|
|
188
|
+
error: StoreInterrupted,
|
|
185
189
|
) =>
|
|
186
190
|
Effect.gen(function* () {
|
|
187
191
|
// console.log('[@livestore/livestore/react] interupting', error)
|
|
@@ -194,7 +198,6 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
194
198
|
|
|
195
199
|
if (
|
|
196
200
|
inputPropsCacheRef.current.schema !== schema ||
|
|
197
|
-
inputPropsCacheRef.current.graphQLOptions !== graphQLOptions ||
|
|
198
201
|
inputPropsCacheRef.current.otelOptions !== otelOptions ||
|
|
199
202
|
inputPropsCacheRef.current.boot !== boot ||
|
|
200
203
|
inputPropsCacheRef.current.adapter !== adapter ||
|
|
@@ -204,7 +207,6 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
204
207
|
) {
|
|
205
208
|
inputPropsCacheRef.current = {
|
|
206
209
|
schema,
|
|
207
|
-
graphQLOptions,
|
|
208
210
|
otelOptions,
|
|
209
211
|
boot,
|
|
210
212
|
adapter,
|
|
@@ -213,7 +215,11 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
213
215
|
signal,
|
|
214
216
|
}
|
|
215
217
|
if (ctxValueRef.current.componentScope !== undefined && ctxValueRef.current.shutdownDeferred !== undefined) {
|
|
216
|
-
interrupt(
|
|
218
|
+
interrupt(
|
|
219
|
+
ctxValueRef.current.componentScope,
|
|
220
|
+
ctxValueRef.current.shutdownDeferred,
|
|
221
|
+
new StoreInterrupted({ reason: 're-rendering due to changed input props' }),
|
|
222
|
+
)
|
|
217
223
|
ctxValueRef.current.componentScope = undefined
|
|
218
224
|
ctxValueRef.current.shutdownDeferred = undefined
|
|
219
225
|
}
|
|
@@ -240,7 +246,11 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
240
246
|
ctxValueRef.current.shutdownDeferred !== undefined &&
|
|
241
247
|
ctxValueRef.current.counter === counter
|
|
242
248
|
) {
|
|
243
|
-
interrupt(
|
|
249
|
+
interrupt(
|
|
250
|
+
ctxValueRef.current.componentScope,
|
|
251
|
+
ctxValueRef.current.shutdownDeferred,
|
|
252
|
+
new StoreInterrupted({ reason: 'Aborted via provided AbortController' }),
|
|
253
|
+
)
|
|
244
254
|
ctxValueRef.current.componentScope = undefined
|
|
245
255
|
ctxValueRef.current.shutdownDeferred = undefined
|
|
246
256
|
}
|
|
@@ -250,7 +260,7 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
250
260
|
const componentScope = yield* Scope.make()
|
|
251
261
|
const shutdownDeferred = yield* Deferred.make<
|
|
252
262
|
void,
|
|
253
|
-
UnexpectedError | IntentionalShutdownCause |
|
|
263
|
+
UnexpectedError | IntentionalShutdownCause | StoreInterrupted
|
|
254
264
|
>()
|
|
255
265
|
|
|
256
266
|
ctxValueRef.current.componentScope = componentScope
|
|
@@ -260,7 +270,6 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
260
270
|
const store = yield* createStore({
|
|
261
271
|
schema,
|
|
262
272
|
storeId,
|
|
263
|
-
graphQLOptions,
|
|
264
273
|
boot,
|
|
265
274
|
adapter,
|
|
266
275
|
batchUpdates,
|
|
@@ -276,13 +285,13 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
276
285
|
setContextValue({ stage: 'running', store })
|
|
277
286
|
}).pipe(Scope.extend(componentScope), Effect.forkIn(componentScope))
|
|
278
287
|
|
|
279
|
-
const shutdownContext = (cause: IntentionalShutdownCause |
|
|
288
|
+
const shutdownContext = (cause: IntentionalShutdownCause | StoreInterrupted) =>
|
|
280
289
|
Effect.sync(() => setContextValue({ stage: 'shutdown', cause }))
|
|
281
290
|
|
|
282
291
|
yield* Deferred.await(shutdownDeferred).pipe(
|
|
283
|
-
Effect.tapErrorCause((cause) => Effect.logDebug('[@livestore/livestore/react] shutdown', cause)),
|
|
292
|
+
Effect.tapErrorCause((cause) => Effect.logDebug('[@livestore/livestore/react] shutdown', Cause.pretty(cause))),
|
|
284
293
|
Effect.catchTag('LiveStore.IntentionalShutdownCause', (cause) => shutdownContext(cause)),
|
|
285
|
-
Effect.catchTag('LiveStore.
|
|
294
|
+
Effect.catchTag('LiveStore.StoreInterrupted', (cause) => shutdownContext(cause)),
|
|
286
295
|
Effect.tapError((error) => Effect.sync(() => setContextValue({ stage: 'error', error }))),
|
|
287
296
|
Effect.tapDefect((defect) => Effect.sync(() => setContextValue({ stage: 'error', error: defect }))),
|
|
288
297
|
Effect.exit,
|
|
@@ -305,12 +314,16 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
305
314
|
|
|
306
315
|
return () => {
|
|
307
316
|
if (ctxValueRef.current.componentScope !== undefined && ctxValueRef.current.shutdownDeferred !== undefined) {
|
|
308
|
-
interrupt(
|
|
317
|
+
interrupt(
|
|
318
|
+
ctxValueRef.current.componentScope,
|
|
319
|
+
ctxValueRef.current.shutdownDeferred,
|
|
320
|
+
new StoreInterrupted({ reason: 'unmounting component' }),
|
|
321
|
+
)
|
|
309
322
|
ctxValueRef.current.componentScope = undefined
|
|
310
323
|
ctxValueRef.current.shutdownDeferred = undefined
|
|
311
324
|
}
|
|
312
325
|
}
|
|
313
|
-
}, [schema,
|
|
326
|
+
}, [schema, otelOptions, boot, adapter, batchUpdates, disableDevtools, signal, storeId])
|
|
314
327
|
|
|
315
328
|
return ctxValueRef.current.value
|
|
316
329
|
}
|
package/src/useAtom.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DerivedMutationHelperFns, QueryInfo } from '@livestore/common'
|
|
2
2
|
import type { DbSchema, SqliteDsl } from '@livestore/common/schema'
|
|
3
|
-
import type {
|
|
3
|
+
import type { Store } from '@livestore/livestore'
|
|
4
|
+
import type { LiveQueries } from '@livestore/livestore/internal'
|
|
4
5
|
import { shouldNeverHappen } from '@livestore/utils'
|
|
5
6
|
import React from 'react'
|
|
6
7
|
|
|
@@ -10,13 +11,16 @@ import type { Dispatch, SetStateAction } from './useRow.js'
|
|
|
10
11
|
|
|
11
12
|
export const useAtom = <
|
|
12
13
|
// TODO also support colJsonValue
|
|
13
|
-
TQuery extends LiveQueryDef<any, QueryInfo.Row | QueryInfo.Col>,
|
|
14
|
+
TQuery extends LiveQueries.LiveQueryDef<any, QueryInfo.Row | QueryInfo.Col>,
|
|
14
15
|
>(
|
|
15
16
|
queryDef: TQuery,
|
|
16
17
|
options?: {
|
|
17
18
|
store?: Store
|
|
18
19
|
},
|
|
19
|
-
): [
|
|
20
|
+
): [
|
|
21
|
+
value: LiveQueries.GetResult<TQuery>,
|
|
22
|
+
setValue: Dispatch<SetStateAction<Partial<LiveQueries.GetResult<TQuery>>>>,
|
|
23
|
+
] => {
|
|
20
24
|
const queryRef = useQueryRef(queryDef, { store: options?.store })
|
|
21
25
|
const query$ = queryRef.queryRcRef.value
|
|
22
26
|
|
|
@@ -28,7 +32,7 @@ export const useAtom = <
|
|
|
28
32
|
const { store } = useStore()
|
|
29
33
|
|
|
30
34
|
// TODO make API equivalent to useRow
|
|
31
|
-
const setValue = React.useMemo<Dispatch<SetStateAction<Partial<GetResult<TQuery>>>>>(
|
|
35
|
+
const setValue = React.useMemo<Dispatch<SetStateAction<Partial<LiveQueries.GetResult<TQuery>>>>>(
|
|
32
36
|
() => (newValueOrFn: any) => {
|
|
33
37
|
const newValue = typeof newValueOrFn === 'function' ? newValueOrFn(queryRef.valueRef.current) : newValueOrFn
|
|
34
38
|
const table = query$.queryInfo.table as DbSchema.TableDef &
|
package/src/useQuery.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LiveQuery, LiveQueryDef, Store } from '@livestore/livestore'
|
|
2
2
|
import { extractStackInfoFromStackTrace, stackInfoToString } from '@livestore/livestore'
|
|
3
|
+
import type { LiveQueries } from '@livestore/livestore/internal'
|
|
3
4
|
import { deepEqual, indent } from '@livestore/utils'
|
|
4
5
|
import * as otel from '@opentelemetry/api'
|
|
5
6
|
import React from 'react'
|
|
@@ -20,17 +21,17 @@ import { useStateRefWithReactiveInput } from './utils/useStateRefWithReactiveInp
|
|
|
20
21
|
* }
|
|
21
22
|
* ```
|
|
22
23
|
*/
|
|
23
|
-
export const useQuery = <TQuery extends
|
|
24
|
+
export const useQuery = <TQuery extends LiveQueryDef.Any>(
|
|
24
25
|
queryDef: TQuery,
|
|
25
26
|
options?: { store?: Store },
|
|
26
|
-
): GetResult<TQuery> => useQueryRef(queryDef, options).valueRef.current
|
|
27
|
+
): LiveQueries.GetResult<TQuery> => useQueryRef(queryDef, options).valueRef.current
|
|
27
28
|
|
|
28
|
-
type GetQueryInfo<TQuery extends
|
|
29
|
+
type GetQueryInfo<TQuery extends LiveQueryDef.Any> =
|
|
29
30
|
TQuery extends LiveQueryDef<infer _1, infer TQueryInfo> ? TQueryInfo : never
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
*/
|
|
33
|
-
export const useQueryRef = <TQuery extends
|
|
34
|
+
export const useQueryRef = <TQuery extends LiveQueryDef.Any>(
|
|
34
35
|
queryDef: TQuery,
|
|
35
36
|
options?: {
|
|
36
37
|
store?: Store
|
|
@@ -40,8 +41,8 @@ export const useQueryRef = <TQuery extends LiveQueryDefAny>(
|
|
|
40
41
|
otelSpanName?: string
|
|
41
42
|
},
|
|
42
43
|
): {
|
|
43
|
-
valueRef: React.RefObject<GetResult<TQuery>>
|
|
44
|
-
queryRcRef: RcRef<LiveQuery<GetResult<TQuery>, GetQueryInfo<TQuery>>>
|
|
44
|
+
valueRef: React.RefObject<LiveQueries.GetResult<TQuery>>
|
|
45
|
+
queryRcRef: LiveQueries.RcRef<LiveQuery<LiveQueries.GetResult<TQuery>, GetQueryInfo<TQuery>>>
|
|
45
46
|
} => {
|
|
46
47
|
const { store } = useStore({ store: options?.store })
|
|
47
48
|
|
|
@@ -76,7 +77,7 @@ export const useQueryRef = <TQuery extends LiveQueryDefAny>(
|
|
|
76
77
|
// which takes care of disposing the queryRcRef
|
|
77
78
|
() => {},
|
|
78
79
|
)
|
|
79
|
-
const query$ = queryRcRef.value as LiveQuery<GetResult<TQuery>, GetQueryInfo<TQuery>>
|
|
80
|
+
const query$ = queryRcRef.value as LiveQuery<LiveQueries.GetResult<TQuery>, GetQueryInfo<TQuery>>
|
|
80
81
|
|
|
81
82
|
React.useDebugValue(`LiveStore:useQuery:${query$.id}:${query$.label}`)
|
|
82
83
|
// console.debug(`LiveStore:useQuery:${query$.id}:${query$.label}`)
|
|
@@ -111,7 +112,7 @@ Stack trace:
|
|
|
111
112
|
}, [otelContext, query$, stackInfo])
|
|
112
113
|
|
|
113
114
|
// We know the query has a result by the time we use it; so we can synchronously populate a default state
|
|
114
|
-
const [valueRef, setValue] = useStateRefWithReactiveInput<GetResult<TQuery>>(initialResult)
|
|
115
|
+
const [valueRef, setValue] = useStateRefWithReactiveInput<LiveQueries.GetResult<TQuery>>(initialResult)
|
|
115
116
|
|
|
116
117
|
// TODO we probably need to change the order of `useEffect` calls, so we destroy the query at the end
|
|
117
118
|
// before calling the LS `onEffect` on it
|