@livestore/react 0.4.0-dev.20 → 0.4.0-dev.22
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/StoreRegistryContext.d.ts +56 -0
- package/dist/StoreRegistryContext.d.ts.map +1 -0
- package/dist/StoreRegistryContext.js +61 -0
- package/dist/StoreRegistryContext.js.map +1 -0
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +1 -6
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/experimental/components/LiveList.d.ts +4 -2
- package/dist/experimental/components/LiveList.d.ts.map +1 -1
- package/dist/experimental/components/LiveList.js +6 -5
- package/dist/experimental/components/LiveList.js.map +1 -1
- package/dist/experimental/mod.d.ts +0 -1
- package/dist/experimental/mod.d.ts.map +1 -1
- package/dist/experimental/mod.js +0 -1
- package/dist/experimental/mod.js.map +1 -1
- package/dist/mod.d.ts +4 -3
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +3 -2
- package/dist/mod.js.map +1 -1
- package/dist/useClientDocument.d.ts +33 -0
- package/dist/useClientDocument.d.ts.map +1 -1
- package/dist/useClientDocument.js +1 -4
- package/dist/useClientDocument.js.map +1 -1
- package/dist/useQuery.d.ts +1 -1
- package/dist/useQuery.d.ts.map +1 -1
- package/dist/useQuery.js +2 -5
- package/dist/useQuery.js.map +1 -1
- package/dist/useStore.d.ts +62 -7
- package/dist/useStore.d.ts.map +1 -1
- package/dist/useStore.js +73 -15
- package/dist/useStore.js.map +1 -1
- package/dist/useStore.test.d.ts.map +1 -0
- package/dist/useStore.test.js +196 -0
- package/dist/useStore.test.js.map +1 -0
- package/package.json +7 -7
- package/src/StoreRegistryContext.tsx +69 -0
- package/src/__tests__/fixture.tsx +1 -13
- package/src/experimental/components/LiveList.tsx +13 -4
- package/src/experimental/mod.ts +0 -1
- package/src/mod.ts +4 -3
- package/src/useClientDocument.ts +36 -5
- package/src/useQuery.ts +2 -6
- package/src/useStore.test.tsx +271 -0
- package/src/useStore.ts +102 -23
- package/dist/LiveStoreContext.d.ts +0 -13
- package/dist/LiveStoreContext.d.ts.map +0 -1
- package/dist/LiveStoreContext.js +0 -3
- package/dist/LiveStoreContext.js.map +0 -1
- package/dist/LiveStoreProvider.d.ts +0 -66
- package/dist/LiveStoreProvider.d.ts.map +0 -1
- package/dist/LiveStoreProvider.js +0 -232
- package/dist/LiveStoreProvider.js.map +0 -1
- package/dist/LiveStoreProvider.test.d.ts +0 -2
- package/dist/LiveStoreProvider.test.d.ts.map +0 -1
- package/dist/LiveStoreProvider.test.js +0 -117
- package/dist/LiveStoreProvider.test.js.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.d.ts +0 -61
- package/dist/experimental/multi-store/StoreRegistry.d.ts.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.js +0 -275
- package/dist/experimental/multi-store/StoreRegistry.js.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.test.d.ts +0 -2
- package/dist/experimental/multi-store/StoreRegistry.test.d.ts.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.test.js +0 -464
- package/dist/experimental/multi-store/StoreRegistry.test.js.map +0 -1
- package/dist/experimental/multi-store/StoreRegistryContext.d.ts +0 -10
- package/dist/experimental/multi-store/StoreRegistryContext.d.ts.map +0 -1
- package/dist/experimental/multi-store/StoreRegistryContext.js +0 -15
- package/dist/experimental/multi-store/StoreRegistryContext.js.map +0 -1
- package/dist/experimental/multi-store/mod.d.ts +0 -6
- package/dist/experimental/multi-store/mod.d.ts.map +0 -1
- package/dist/experimental/multi-store/mod.js +0 -6
- package/dist/experimental/multi-store/mod.js.map +0 -1
- package/dist/experimental/multi-store/storeOptions.d.ts +0 -4
- package/dist/experimental/multi-store/storeOptions.d.ts.map +0 -1
- package/dist/experimental/multi-store/storeOptions.js +0 -4
- package/dist/experimental/multi-store/storeOptions.js.map +0 -1
- package/dist/experimental/multi-store/types.d.ts +0 -44
- package/dist/experimental/multi-store/types.d.ts.map +0 -1
- package/dist/experimental/multi-store/types.js +0 -2
- package/dist/experimental/multi-store/types.js.map +0 -1
- package/dist/experimental/multi-store/useStore.d.ts +0 -11
- package/dist/experimental/multi-store/useStore.d.ts.map +0 -1
- package/dist/experimental/multi-store/useStore.js +0 -21
- package/dist/experimental/multi-store/useStore.js.map +0 -1
- package/dist/experimental/multi-store/useStore.test.d.ts.map +0 -1
- package/dist/experimental/multi-store/useStore.test.js +0 -144
- package/dist/experimental/multi-store/useStore.test.js.map +0 -1
- package/src/LiveStoreContext.ts +0 -14
- package/src/LiveStoreProvider.test.tsx +0 -248
- package/src/LiveStoreProvider.tsx +0 -421
- package/src/experimental/multi-store/StoreRegistry.test.ts +0 -631
- package/src/experimental/multi-store/StoreRegistry.ts +0 -347
- package/src/experimental/multi-store/StoreRegistryContext.tsx +0 -23
- package/src/experimental/multi-store/mod.ts +0 -5
- package/src/experimental/multi-store/storeOptions.ts +0 -8
- package/src/experimental/multi-store/types.ts +0 -55
- package/src/experimental/multi-store/useStore.test.tsx +0 -197
- package/src/experimental/multi-store/useStore.ts +0 -34
- /package/dist/{experimental/multi-store/useStore.test.d.ts → useStore.test.d.ts} +0 -0
|
@@ -1,421 +0,0 @@
|
|
|
1
|
-
import type { Adapter, BootStatus, IntentionalShutdownCause, MigrationsReport, SyncError } from '@livestore/common'
|
|
2
|
-
import { LogConfig, provideOtel, UnknownError } from '@livestore/common'
|
|
3
|
-
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
4
|
-
import type {
|
|
5
|
-
CreateStoreOptions,
|
|
6
|
-
OtelOptions,
|
|
7
|
-
ShutdownDeferred,
|
|
8
|
-
Store,
|
|
9
|
-
LiveStoreContext as StoreContext_,
|
|
10
|
-
} from '@livestore/livestore'
|
|
11
|
-
import { createStore, makeShutdownDeferred, StoreInterrupted } from '@livestore/livestore'
|
|
12
|
-
import { errorToString, IS_REACT_NATIVE, LS_DEV, omitUndefineds } from '@livestore/utils'
|
|
13
|
-
import type { OtelTracer } from '@livestore/utils/effect'
|
|
14
|
-
import { Cause, Deferred, Effect, Exit, identity, Schema, Scope, TaskTracing } from '@livestore/utils/effect'
|
|
15
|
-
import type * as otel from '@opentelemetry/api'
|
|
16
|
-
import React from 'react'
|
|
17
|
-
|
|
18
|
-
import { LiveStoreContext } from './LiveStoreContext.ts'
|
|
19
|
-
|
|
20
|
-
export interface LiveStoreProviderProps<TSyncPayloadSchema extends Schema.Schema<any> = typeof Schema.JsonValue>
|
|
21
|
-
extends LogConfig.WithLoggerOptions {
|
|
22
|
-
schema: LiveStoreSchema
|
|
23
|
-
/**
|
|
24
|
-
* The `storeId` can be used to isolate multiple stores from each other.
|
|
25
|
-
* So it can be useful for multi-tenancy scenarios.
|
|
26
|
-
*
|
|
27
|
-
* The `storeId` is also used for persistence.
|
|
28
|
-
*
|
|
29
|
-
* Make sure to also configure `storeId` in LiveStore Devtools (e.g. in Vite plugin).
|
|
30
|
-
*
|
|
31
|
-
* @default 'default'
|
|
32
|
-
*/
|
|
33
|
-
storeId?: string
|
|
34
|
-
boot?: (
|
|
35
|
-
store: Store<LiveStoreSchema>,
|
|
36
|
-
ctx: { migrationsReport: MigrationsReport; parentSpan: otel.Span },
|
|
37
|
-
) => void | Promise<void> | Effect.Effect<void, unknown, OtelTracer.OtelTracer>
|
|
38
|
-
otelOptions?: Partial<OtelOptions>
|
|
39
|
-
renderLoading?: (status: BootStatus) => React.ReactNode
|
|
40
|
-
renderError?: (error: UnknownError | unknown) => React.ReactNode
|
|
41
|
-
renderShutdown?: (cause: IntentionalShutdownCause | StoreInterrupted | SyncError) => React.ReactNode
|
|
42
|
-
adapter: Adapter
|
|
43
|
-
/**
|
|
44
|
-
* In order for LiveStore to apply multiple events in a single render,
|
|
45
|
-
* you need to pass the `batchUpdates` function from either `react-dom` or `react-native`.
|
|
46
|
-
*
|
|
47
|
-
* ```ts
|
|
48
|
-
* // With React DOM
|
|
49
|
-
* import { unstable_batchedUpdates as batchUpdates } from 'react-dom'
|
|
50
|
-
*
|
|
51
|
-
* // With React Native
|
|
52
|
-
* import { unstable_batchedUpdates as batchUpdates } from 'react-native'
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
batchUpdates: (run: () => void) => void
|
|
56
|
-
disableDevtools?: boolean
|
|
57
|
-
signal?: AbortSignal
|
|
58
|
-
/**
|
|
59
|
-
* Currently only used in the web adapter:
|
|
60
|
-
* If true, registers a beforeunload event listener to confirm unsaved changes.
|
|
61
|
-
*
|
|
62
|
-
* @default true
|
|
63
|
-
*/
|
|
64
|
-
confirmUnsavedChanges?: boolean
|
|
65
|
-
/**
|
|
66
|
-
* Payload that will be passed to the sync backend when connecting
|
|
67
|
-
*
|
|
68
|
-
* @default undefined
|
|
69
|
-
*/
|
|
70
|
-
syncPayloadSchema?: TSyncPayloadSchema
|
|
71
|
-
syncPayload?: Schema.Schema.Type<TSyncPayloadSchema>
|
|
72
|
-
debug?: {
|
|
73
|
-
instanceId?: string
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const defaultRenderError = (error: UnknownError | unknown) =>
|
|
78
|
-
IS_REACT_NATIVE ? null : Schema.is(UnknownError)(error) ? error.toString() : errorToString(error)
|
|
79
|
-
|
|
80
|
-
const defaultRenderShutdown = (cause: IntentionalShutdownCause | StoreInterrupted | SyncError) => {
|
|
81
|
-
const reason =
|
|
82
|
-
cause._tag === 'LiveStore.StoreInterrupted'
|
|
83
|
-
? `interrupted due to: ${cause.reason}`
|
|
84
|
-
: cause._tag === 'InvalidPushError' || cause._tag === 'InvalidPullError'
|
|
85
|
-
? `sync error: ${cause.cause}`
|
|
86
|
-
: cause.reason === 'devtools-import'
|
|
87
|
-
? 'devtools import'
|
|
88
|
-
: cause.reason === 'devtools-reset'
|
|
89
|
-
? 'devtools reset'
|
|
90
|
-
: cause.reason === 'adapter-reset'
|
|
91
|
-
? 'adapter reset'
|
|
92
|
-
: cause.reason === 'manual'
|
|
93
|
-
? 'manual shutdown'
|
|
94
|
-
: 'unknown reason'
|
|
95
|
-
|
|
96
|
-
return IS_REACT_NATIVE ? null : <>LiveStore Shutdown due to {reason}</>
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const defaultRenderLoading = (status: BootStatus) =>
|
|
100
|
-
IS_REACT_NATIVE ? null : <>LiveStore is loading ({status.stage})...</>
|
|
101
|
-
|
|
102
|
-
export const LiveStoreProvider = <TSyncPayloadSchema extends Schema.Schema<any> = typeof Schema.JsonValue>({
|
|
103
|
-
renderLoading = defaultRenderLoading,
|
|
104
|
-
renderError = defaultRenderError,
|
|
105
|
-
renderShutdown = defaultRenderShutdown,
|
|
106
|
-
otelOptions,
|
|
107
|
-
children,
|
|
108
|
-
schema,
|
|
109
|
-
storeId = 'default',
|
|
110
|
-
boot,
|
|
111
|
-
adapter,
|
|
112
|
-
batchUpdates,
|
|
113
|
-
disableDevtools,
|
|
114
|
-
signal,
|
|
115
|
-
confirmUnsavedChanges = true,
|
|
116
|
-
syncPayload,
|
|
117
|
-
syncPayloadSchema,
|
|
118
|
-
debug,
|
|
119
|
-
logger,
|
|
120
|
-
logLevel,
|
|
121
|
-
}: LiveStoreProviderProps<TSyncPayloadSchema> & React.PropsWithChildren): React.ReactNode => {
|
|
122
|
-
const storeCtx = useCreateStore({
|
|
123
|
-
storeId,
|
|
124
|
-
schema,
|
|
125
|
-
adapter,
|
|
126
|
-
batchUpdates,
|
|
127
|
-
confirmUnsavedChanges,
|
|
128
|
-
...omitUndefineds({
|
|
129
|
-
otelOptions,
|
|
130
|
-
boot,
|
|
131
|
-
disableDevtools,
|
|
132
|
-
signal,
|
|
133
|
-
syncPayload,
|
|
134
|
-
syncPayloadSchema,
|
|
135
|
-
debug,
|
|
136
|
-
}),
|
|
137
|
-
logger,
|
|
138
|
-
logLevel,
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
if (storeCtx.stage === 'error') {
|
|
142
|
-
return renderError(storeCtx.error)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (storeCtx.stage === 'shutdown') {
|
|
146
|
-
return renderShutdown(storeCtx.cause)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (storeCtx.stage !== 'running') {
|
|
150
|
-
return renderLoading(storeCtx)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
globalThis.__debugLiveStore ??= {}
|
|
154
|
-
if (Object.keys(globalThis.__debugLiveStore).length === 0) {
|
|
155
|
-
globalThis.__debugLiveStore._ = storeCtx.store
|
|
156
|
-
}
|
|
157
|
-
globalThis.__debugLiveStore[debug?.instanceId ?? storeId] = storeCtx.store
|
|
158
|
-
|
|
159
|
-
return <LiveStoreContext.Provider value={storeCtx as TODO}>{children}</LiveStoreContext.Provider>
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const useCreateStore = ({
|
|
163
|
-
schema,
|
|
164
|
-
storeId,
|
|
165
|
-
otelOptions,
|
|
166
|
-
boot,
|
|
167
|
-
adapter,
|
|
168
|
-
batchUpdates,
|
|
169
|
-
disableDevtools,
|
|
170
|
-
signal,
|
|
171
|
-
context,
|
|
172
|
-
params,
|
|
173
|
-
confirmUnsavedChanges,
|
|
174
|
-
syncPayload,
|
|
175
|
-
syncPayloadSchema,
|
|
176
|
-
debug,
|
|
177
|
-
logger,
|
|
178
|
-
logLevel,
|
|
179
|
-
}: CreateStoreOptions<LiveStoreSchema> &
|
|
180
|
-
LogConfig.WithLoggerOptions & {
|
|
181
|
-
signal?: AbortSignal
|
|
182
|
-
otelOptions?: Partial<OtelOptions>
|
|
183
|
-
}) => {
|
|
184
|
-
const [_, rerender] = React.useState(0)
|
|
185
|
-
const ctxValueRef = React.useRef<{
|
|
186
|
-
value: StoreContext_ | BootStatus
|
|
187
|
-
componentScope: Scope.CloseableScope | undefined
|
|
188
|
-
shutdownDeferred: ShutdownDeferred | undefined
|
|
189
|
-
/** Used to wait for the previous shutdown deferred to fully complete before creating a new one */
|
|
190
|
-
previousShutdownDeferred: ShutdownDeferred | undefined
|
|
191
|
-
counter: number
|
|
192
|
-
}>({
|
|
193
|
-
value: { stage: 'loading' },
|
|
194
|
-
componentScope: undefined,
|
|
195
|
-
shutdownDeferred: undefined,
|
|
196
|
-
previousShutdownDeferred: undefined,
|
|
197
|
-
counter: 0,
|
|
198
|
-
})
|
|
199
|
-
const debugInstanceId = debug?.instanceId
|
|
200
|
-
|
|
201
|
-
// console.debug(`useCreateStore (${ctxValueRef.current.counter})`, ctxValueRef.current.value.stage)
|
|
202
|
-
|
|
203
|
-
const inputPropsCacheRef = React.useRef({
|
|
204
|
-
schema,
|
|
205
|
-
otelOptions,
|
|
206
|
-
boot,
|
|
207
|
-
adapter,
|
|
208
|
-
batchUpdates,
|
|
209
|
-
disableDevtools,
|
|
210
|
-
signal,
|
|
211
|
-
context,
|
|
212
|
-
params,
|
|
213
|
-
confirmUnsavedChanges,
|
|
214
|
-
syncPayload,
|
|
215
|
-
syncPayloadSchema,
|
|
216
|
-
debugInstanceId,
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
const interrupt = React.useCallback(
|
|
220
|
-
(componentScope: Scope.CloseableScope, shutdownDeferred: ShutdownDeferred, error: StoreInterrupted) =>
|
|
221
|
-
Effect.gen(function* () {
|
|
222
|
-
// console.log('[@livestore/livestore/react] interupting', error)
|
|
223
|
-
yield* Scope.close(componentScope, Exit.fail(error))
|
|
224
|
-
yield* Deferred.fail(shutdownDeferred, error)
|
|
225
|
-
}).pipe(
|
|
226
|
-
Effect.tapErrorCause((cause) => Effect.logDebug('[@livestore/livestore/react] interupting', cause)),
|
|
227
|
-
Effect.runFork,
|
|
228
|
-
),
|
|
229
|
-
[],
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
const inputPropChanges = {
|
|
233
|
-
schema: inputPropsCacheRef.current.schema !== schema,
|
|
234
|
-
otelOptions: inputPropsCacheRef.current.otelOptions !== otelOptions,
|
|
235
|
-
boot: inputPropsCacheRef.current.boot !== boot,
|
|
236
|
-
adapter: inputPropsCacheRef.current.adapter !== adapter,
|
|
237
|
-
batchUpdates: inputPropsCacheRef.current.batchUpdates !== batchUpdates,
|
|
238
|
-
disableDevtools: inputPropsCacheRef.current.disableDevtools !== disableDevtools,
|
|
239
|
-
signal: inputPropsCacheRef.current.signal !== signal,
|
|
240
|
-
context: inputPropsCacheRef.current.context !== context,
|
|
241
|
-
params: inputPropsCacheRef.current.params !== params,
|
|
242
|
-
confirmUnsavedChanges: inputPropsCacheRef.current.confirmUnsavedChanges !== confirmUnsavedChanges,
|
|
243
|
-
syncPayload: inputPropsCacheRef.current.syncPayload !== syncPayload,
|
|
244
|
-
syncPayloadSchema: inputPropsCacheRef.current.syncPayloadSchema !== syncPayloadSchema,
|
|
245
|
-
debugInstanceId: inputPropsCacheRef.current.debugInstanceId !== debugInstanceId,
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (
|
|
249
|
-
inputPropChanges.schema ||
|
|
250
|
-
inputPropChanges.otelOptions ||
|
|
251
|
-
inputPropChanges.boot ||
|
|
252
|
-
inputPropChanges.adapter ||
|
|
253
|
-
inputPropChanges.batchUpdates ||
|
|
254
|
-
inputPropChanges.disableDevtools ||
|
|
255
|
-
inputPropChanges.signal ||
|
|
256
|
-
inputPropChanges.context ||
|
|
257
|
-
inputPropChanges.params ||
|
|
258
|
-
inputPropChanges.confirmUnsavedChanges ||
|
|
259
|
-
inputPropChanges.syncPayload ||
|
|
260
|
-
inputPropChanges.syncPayloadSchema
|
|
261
|
-
) {
|
|
262
|
-
inputPropsCacheRef.current = {
|
|
263
|
-
schema,
|
|
264
|
-
otelOptions,
|
|
265
|
-
boot,
|
|
266
|
-
adapter,
|
|
267
|
-
batchUpdates,
|
|
268
|
-
disableDevtools,
|
|
269
|
-
signal,
|
|
270
|
-
context,
|
|
271
|
-
params,
|
|
272
|
-
confirmUnsavedChanges,
|
|
273
|
-
syncPayload,
|
|
274
|
-
syncPayloadSchema,
|
|
275
|
-
debugInstanceId,
|
|
276
|
-
}
|
|
277
|
-
if (ctxValueRef.current.componentScope !== undefined && ctxValueRef.current.shutdownDeferred !== undefined) {
|
|
278
|
-
const changedInputProps = Object.keys(inputPropChanges).filter(
|
|
279
|
-
(key) => inputPropChanges[key as keyof typeof inputPropChanges],
|
|
280
|
-
)
|
|
281
|
-
|
|
282
|
-
interrupt(
|
|
283
|
-
ctxValueRef.current.componentScope,
|
|
284
|
-
ctxValueRef.current.shutdownDeferred,
|
|
285
|
-
new StoreInterrupted({ reason: `re-rendering due to changed input props: ${changedInputProps.join(', ')}` }),
|
|
286
|
-
)
|
|
287
|
-
ctxValueRef.current.componentScope = undefined
|
|
288
|
-
ctxValueRef.current.shutdownDeferred = undefined
|
|
289
|
-
}
|
|
290
|
-
ctxValueRef.current = {
|
|
291
|
-
value: { stage: 'loading' },
|
|
292
|
-
componentScope: undefined,
|
|
293
|
-
shutdownDeferred: undefined,
|
|
294
|
-
previousShutdownDeferred: ctxValueRef.current.shutdownDeferred,
|
|
295
|
-
counter: ctxValueRef.current.counter + 1,
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
React.useEffect(() => {
|
|
300
|
-
const counter = ctxValueRef.current.counter
|
|
301
|
-
|
|
302
|
-
const setContextValue = (value: StoreContext_ | BootStatus) => {
|
|
303
|
-
if (ctxValueRef.current.counter !== counter) return
|
|
304
|
-
ctxValueRef.current.value = value
|
|
305
|
-
rerender((c) => c + 1)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
signal?.addEventListener('abort', () => {
|
|
309
|
-
if (
|
|
310
|
-
ctxValueRef.current.componentScope !== undefined &&
|
|
311
|
-
ctxValueRef.current.shutdownDeferred !== undefined &&
|
|
312
|
-
ctxValueRef.current.counter === counter
|
|
313
|
-
) {
|
|
314
|
-
interrupt(
|
|
315
|
-
ctxValueRef.current.componentScope,
|
|
316
|
-
ctxValueRef.current.shutdownDeferred,
|
|
317
|
-
new StoreInterrupted({ reason: 'Aborted via provided AbortController' }),
|
|
318
|
-
)
|
|
319
|
-
ctxValueRef.current.componentScope = undefined
|
|
320
|
-
ctxValueRef.current.shutdownDeferred = undefined
|
|
321
|
-
}
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
const cancel = Effect.gen(function* () {
|
|
325
|
-
// Wait for the previous store to fully shutdown before creating a new one
|
|
326
|
-
if (ctxValueRef.current.previousShutdownDeferred) {
|
|
327
|
-
yield* Deferred.await(ctxValueRef.current.previousShutdownDeferred)
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const componentScope = yield* Scope.make().pipe(Effect.acquireRelease(Scope.close))
|
|
331
|
-
const shutdownDeferred = yield* makeShutdownDeferred
|
|
332
|
-
|
|
333
|
-
ctxValueRef.current.componentScope = componentScope
|
|
334
|
-
ctxValueRef.current.shutdownDeferred = shutdownDeferred
|
|
335
|
-
|
|
336
|
-
yield* Effect.gen(function* () {
|
|
337
|
-
const store = yield* createStore({
|
|
338
|
-
schema,
|
|
339
|
-
storeId,
|
|
340
|
-
adapter,
|
|
341
|
-
shutdownDeferred,
|
|
342
|
-
...omitUndefineds({
|
|
343
|
-
boot,
|
|
344
|
-
batchUpdates,
|
|
345
|
-
disableDevtools,
|
|
346
|
-
context,
|
|
347
|
-
params,
|
|
348
|
-
confirmUnsavedChanges,
|
|
349
|
-
syncPayload,
|
|
350
|
-
syncPayloadSchema,
|
|
351
|
-
}),
|
|
352
|
-
onBootStatus: (status) => {
|
|
353
|
-
if (ctxValueRef.current.value.stage === 'running' || ctxValueRef.current.value.stage === 'error') return
|
|
354
|
-
// NOTE sometimes when status come in in rapid succession, only the last value will be rendered by React
|
|
355
|
-
setContextValue(status)
|
|
356
|
-
},
|
|
357
|
-
debug: { ...omitUndefineds({ instanceId: debugInstanceId }) },
|
|
358
|
-
}).pipe(Effect.tapErrorCause((cause) => Deferred.failCause(shutdownDeferred, cause)))
|
|
359
|
-
|
|
360
|
-
setContextValue({ stage: 'running', store })
|
|
361
|
-
}).pipe(Scope.extend(componentScope), Effect.forkIn(componentScope))
|
|
362
|
-
|
|
363
|
-
const shutdownContext = (cause: IntentionalShutdownCause | StoreInterrupted | SyncError) =>
|
|
364
|
-
Effect.sync(() => setContextValue({ stage: 'shutdown', cause }))
|
|
365
|
-
|
|
366
|
-
yield* Deferred.await(shutdownDeferred).pipe(
|
|
367
|
-
Effect.tapErrorCause((cause) => Effect.logDebug('[@livestore/livestore/react] shutdown', Cause.pretty(cause))),
|
|
368
|
-
Effect.tap((intentionalShutdown) => shutdownContext(intentionalShutdown)),
|
|
369
|
-
Effect.catchTag('InvalidPushError', (cause) => shutdownContext(cause)),
|
|
370
|
-
Effect.catchTag('InvalidPullError', (cause) => shutdownContext(cause)),
|
|
371
|
-
Effect.catchTag('LiveStore.StoreInterrupted', (cause) => shutdownContext(cause)),
|
|
372
|
-
Effect.tapError((error) => Effect.sync(() => setContextValue({ stage: 'error', error }))),
|
|
373
|
-
Effect.tapDefect((defect) => Effect.sync(() => setContextValue({ stage: 'error', error: defect }))),
|
|
374
|
-
Effect.exit,
|
|
375
|
-
)
|
|
376
|
-
}).pipe(
|
|
377
|
-
Effect.scoped,
|
|
378
|
-
Effect.withSpan('@livestore/react:useCreateStore'),
|
|
379
|
-
LS_DEV ? TaskTracing.withAsyncTaggingTracing((name: string) => (console as any).createTask(name)) : identity,
|
|
380
|
-
provideOtel(omitUndefineds({ parentSpanContext: otelOptions?.rootSpanContext, otelTracer: otelOptions?.tracer })),
|
|
381
|
-
Effect.tapCauseLogPretty,
|
|
382
|
-
Effect.annotateLogs({ thread: 'window' }),
|
|
383
|
-
LogConfig.withLoggerConfig({ logger, logLevel }, { threadName: 'window' }),
|
|
384
|
-
Effect.runCallback,
|
|
385
|
-
)
|
|
386
|
-
|
|
387
|
-
return () => {
|
|
388
|
-
cancel()
|
|
389
|
-
|
|
390
|
-
if (ctxValueRef.current.componentScope !== undefined && ctxValueRef.current.shutdownDeferred !== undefined) {
|
|
391
|
-
interrupt(
|
|
392
|
-
ctxValueRef.current.componentScope,
|
|
393
|
-
ctxValueRef.current.shutdownDeferred,
|
|
394
|
-
new StoreInterrupted({ reason: 'unmounting component' }),
|
|
395
|
-
)
|
|
396
|
-
ctxValueRef.current.componentScope = undefined
|
|
397
|
-
ctxValueRef.current.shutdownDeferred = undefined
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}, [
|
|
401
|
-
schema,
|
|
402
|
-
otelOptions,
|
|
403
|
-
boot,
|
|
404
|
-
adapter,
|
|
405
|
-
batchUpdates,
|
|
406
|
-
disableDevtools,
|
|
407
|
-
signal,
|
|
408
|
-
storeId,
|
|
409
|
-
context,
|
|
410
|
-
params,
|
|
411
|
-
confirmUnsavedChanges,
|
|
412
|
-
syncPayload,
|
|
413
|
-
syncPayloadSchema,
|
|
414
|
-
debugInstanceId,
|
|
415
|
-
interrupt,
|
|
416
|
-
logger,
|
|
417
|
-
logLevel,
|
|
418
|
-
])
|
|
419
|
-
|
|
420
|
-
return ctxValueRef.current.value
|
|
421
|
-
}
|