@livestore/react 0.0.0-snapshot-2411da6706c12365b5aa4533b551b9b6554d4617 → 0.0.0-snapshot-97ca7eac46b6a583b22d40189126d06a377ec1b0

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.
@@ -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, StoreAbort, StoreInterrupted } from '@livestore/livestore'
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 { Deferred, Effect, Exit, identity, Logger, LogLevel, Schema, Scope, TaskTracing } from '@livestore/utils/effect'
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<GraphQLContext extends BaseGraphQLContext> {
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<GraphQLContext, LiveStoreSchema>,
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 | StoreAbort) => ReactElement
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 | StoreAbort) => {
74
+ const defaultRenderShutdown = (cause: IntentionalShutdownCause | StoreInterrupted) => {
67
75
  const reason =
68
- cause._tag === 'LiveStore.StoreAbort'
69
- ? 'abort signal'
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 = <GraphQLContext extends BaseGraphQLContext>({
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<GraphQLContext> & { children?: ReactNode }): React.ReactElement => {
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 = <GraphQLContext extends BaseGraphQLContext>({
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<GraphQLContext, LiveStoreSchema> & {
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: StoreAbort | StoreInterrupted,
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(ctxValueRef.current.componentScope, ctxValueRef.current.shutdownDeferred, new StoreInterrupted())
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(ctxValueRef.current.componentScope, ctxValueRef.current.shutdownDeferred, new StoreAbort())
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 | StoreAbort | StoreInterrupted
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 | StoreAbort) =>
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.StoreAbort', (cause) => shutdownContext(cause)),
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(ctxValueRef.current.componentScope, ctxValueRef.current.shutdownDeferred, new StoreInterrupted())
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, graphQLOptions, otelOptions, boot, adapter, batchUpdates, disableDevtools, signal, storeId])
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 { GetResult, LiveQueryDef, Store } from '@livestore/livestore'
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
- ): [value: GetResult<TQuery>, setValue: Dispatch<SetStateAction<Partial<GetResult<TQuery>>>>] => {
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 { GetResult, LiveQuery, LiveQueryDef, LiveQueryDefAny, RcRef, Store } from '@livestore/livestore'
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 LiveQueryDefAny>(
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 LiveQueryDefAny> =
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 LiveQueryDefAny>(
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