@livestore/react 0.2.0 → 0.3.0-dev.10
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/LiveStoreProvider.d.ts +6 -4
- package/dist/LiveStoreProvider.d.ts.map +1 -1
- package/dist/LiveStoreProvider.js +45 -28
- package/dist/LiveStoreProvider.js.map +1 -1
- package/dist/LiveStoreProvider.test.js +8 -2
- package/dist/LiveStoreProvider.test.js.map +1 -1
- package/dist/__tests__/fixture.d.ts +1 -2
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +6 -10
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/useQuery.d.ts +1 -1
- package/dist/useQuery.d.ts.map +1 -1
- package/dist/useQuery.js.map +1 -1
- package/dist/useRow.js.map +1 -1
- package/dist/useRow.test.js +13 -18
- package/dist/useRow.test.js.map +1 -1
- package/dist/useScopedQuery.d.ts +1 -1
- package/dist/useScopedQuery.d.ts.map +1 -1
- package/dist/useScopedQuery.js +2 -1
- package/dist/useScopedQuery.js.map +1 -1
- package/dist/utils/useStateRefWithReactiveInput.d.ts +1 -1
- package/dist/utils/useStateRefWithReactiveInput.d.ts.map +1 -1
- package/dist/utils/useStateRefWithReactiveInput.js.map +1 -1
- package/package.json +18 -17
- package/src/LiveStoreProvider.test.tsx +13 -2
- package/src/LiveStoreProvider.tsx +68 -36
- package/src/__snapshots__/useRow.test.tsx.snap +54 -53
- package/src/__tests__/fixture.tsx +6 -11
- package/src/useQuery.ts +1 -1
- package/src/useRow.test.tsx +71 -71
- package/src/useRow.ts +1 -1
- package/src/useScopedQuery.ts +3 -2
- package/src/utils/useStateRefWithReactiveInput.ts +1 -1
- package/dist/useTemporaryQuery.d.ts +0 -22
- package/dist/useTemporaryQuery.d.ts.map +0 -1
- package/dist/useTemporaryQuery.js +0 -75
- package/dist/useTemporaryQuery.js.map +0 -1
|
@@ -9,5 +9,5 @@ import React from 'react';
|
|
|
9
9
|
* - Also see this Tweet for more potential problems: https://twitter.com/schickling/status/1677317711104278528
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
|
-
export declare const useStateRefWithReactiveInput: <T>(inputState: T) => [React.
|
|
12
|
+
export declare const useStateRefWithReactiveInput: <T>(inputState: T) => [React.RefObject<T>, (newState: T | ((prev: T) => T)) => void];
|
|
13
13
|
//# sourceMappingURL=useStateRefWithReactiveInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStateRefWithReactiveInput.d.ts","sourceRoot":"","sources":["../../src/utils/useStateRefWithReactiveInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,GAAI,CAAC,cAChC,CAAC,KACZ,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"useStateRefWithReactiveInput.d.ts","sourceRoot":"","sources":["../../src/utils/useStateRefWithReactiveInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,GAAI,CAAC,cAChC,CAAC,KACZ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAwB/D,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStateRefWithReactiveInput.js","sourceRoot":"","sources":["../../src/utils/useStateRefWithReactiveInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC1C,UAAa,
|
|
1
|
+
{"version":3,"file":"useStateRefWithReactiveInput.js","sourceRoot":"","sources":["../../src/utils/useStateRefWithReactiveInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC1C,UAAa,EACmD,EAAE;IAClE,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAEvC,MAAM,sBAAsB,GAAG,KAAK,CAAC,MAAM,CAAI,UAAU,CAAC,CAAA;IAC1D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAI,UAAU,CAAC,CAAA;IAE5C,IAAI,sBAAsB,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAClD,sBAAsB,CAAC,OAAO,GAAG,UAAU,CAAA;QAE3C,qHAAqH;QACrH,QAAQ,CAAC,OAAO,GAAG,UAAU,CAAA;IAC/B,CAAC;IAED,MAAM,mBAAmB,GAAG,KAAK,CAAC,WAAW,CAC3C,CAAC,QAA8B,EAAE,EAAE;QACjC,wEAAwE;QACxE,MAAM,GAAG,GAAG,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QAClF,QAAQ,CAAC,OAAO,GAAG,GAAG,CAAA;QACtB,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACxB,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,OAAO,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAA;AACxC,CAAC,CAAA;AAED,yGAAyG;AACzG,iFAAiF;AACjF,4GAA4G;AAC5G,yEAAyE;AAEzE,wCAAwC;AACxC,mCAAmC;AACnC,MAAM;AAEN,6CAA6C;AAC7C,IAAI"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-dev.10",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
5
6
|
"exports": {
|
|
6
7
|
".": {
|
|
7
8
|
"types": "./dist/mod.d.ts",
|
|
@@ -21,28 +22,28 @@
|
|
|
21
22
|
}
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"@opentelemetry/api": "
|
|
25
|
-
"@livestore/
|
|
26
|
-
"@livestore/
|
|
27
|
-
"@livestore/
|
|
28
|
-
"@livestore/
|
|
25
|
+
"@opentelemetry/api": "1.9.0",
|
|
26
|
+
"@livestore/common": "0.3.0-dev.10",
|
|
27
|
+
"@livestore/livestore": "0.3.0-dev.10",
|
|
28
|
+
"@livestore/utils": "0.3.0-dev.10",
|
|
29
|
+
"@livestore/db-schema": "0.3.0-dev.10"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
|
-
"@opentelemetry/sdk-trace-base": "1.
|
|
32
|
+
"@opentelemetry/sdk-trace-base": "^1.30.1",
|
|
32
33
|
"@testing-library/react": "^16.0.1",
|
|
33
|
-
"@types/react": "^
|
|
34
|
-
"@types/react-dom": "^
|
|
35
|
-
"jsdom": "^
|
|
36
|
-
"react": "^
|
|
37
|
-
"react-dom": "^
|
|
38
|
-
"react-window": "^1.8.
|
|
39
|
-
"typescript": "5.
|
|
40
|
-
"vite": "
|
|
34
|
+
"@types/react": "^19.0.8",
|
|
35
|
+
"@types/react-dom": "^19.0.3",
|
|
36
|
+
"jsdom": "^26.0.0",
|
|
37
|
+
"react": "^19.0.0",
|
|
38
|
+
"react-dom": "^19.0.0",
|
|
39
|
+
"react-window": "^1.8.11",
|
|
40
|
+
"typescript": "^5.7.2",
|
|
41
|
+
"vite": "^6.0.11",
|
|
41
42
|
"vitest": "^2.1.4",
|
|
42
|
-
"@livestore/web": "0.
|
|
43
|
+
"@livestore/web": "0.3.0-dev.10"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
|
-
"react": "
|
|
46
|
+
"react": "~19.0.0"
|
|
46
47
|
},
|
|
47
48
|
"publishConfig": {
|
|
48
49
|
"access": "public"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { sql } from '@livestore/common'
|
|
2
|
+
import { rawSqlMutation } from '@livestore/common/schema'
|
|
2
3
|
import { queryDb, type Store } from '@livestore/livestore'
|
|
3
4
|
import { Schema } from '@livestore/utils/effect'
|
|
4
5
|
import { makeInMemoryAdapter } from '@livestore/web'
|
|
@@ -30,7 +31,11 @@ describe('LiveStoreProvider', () => {
|
|
|
30
31
|
const Root = ({ forceUpdate }: { forceUpdate: number }) => {
|
|
31
32
|
const bootCb = React.useCallback(
|
|
32
33
|
(store: Store) =>
|
|
33
|
-
store.
|
|
34
|
+
store.mutate(
|
|
35
|
+
rawSqlMutation({
|
|
36
|
+
sql: sql`INSERT OR IGNORE INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)`,
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
34
39
|
[],
|
|
35
40
|
)
|
|
36
41
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -69,6 +74,8 @@ describe('LiveStoreProvider', () => {
|
|
|
69
74
|
await waitFor(() => screen.getByText('LiveStore Shutdown due to abort signal'))
|
|
70
75
|
})
|
|
71
76
|
|
|
77
|
+
// TODO test aborting during boot
|
|
78
|
+
|
|
72
79
|
it('error during boot', async () => {
|
|
73
80
|
let appRenderCount = 0
|
|
74
81
|
|
|
@@ -81,7 +88,11 @@ describe('LiveStoreProvider', () => {
|
|
|
81
88
|
const Root = ({ forceUpdate }: { forceUpdate: number }) => {
|
|
82
89
|
const bootCb = React.useCallback(
|
|
83
90
|
(store: Store) =>
|
|
84
|
-
store.
|
|
91
|
+
store.mutate(
|
|
92
|
+
rawSqlMutation({
|
|
93
|
+
sql: sql`INSERT OR IGNORE INTO todos_missing_table (id, text, completed) VALUES ('t1', 'buy milk', 0)`,
|
|
94
|
+
}),
|
|
95
|
+
),
|
|
85
96
|
[],
|
|
86
97
|
)
|
|
87
98
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Adapter, BootStatus, IntentionalShutdownCause } from '@livestore/common'
|
|
2
|
-
import { UnexpectedError } from '@livestore/common'
|
|
2
|
+
import { provideOtel, UnexpectedError } from '@livestore/common'
|
|
3
3
|
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
4
4
|
import type {
|
|
5
5
|
BaseGraphQLContext,
|
|
@@ -7,11 +7,13 @@ import type {
|
|
|
7
7
|
GraphQLOptions,
|
|
8
8
|
LiveStoreContext as StoreContext_,
|
|
9
9
|
OtelOptions,
|
|
10
|
+
ShutdownDeferred,
|
|
10
11
|
Store,
|
|
11
12
|
} from '@livestore/livestore'
|
|
12
13
|
import { createStore, StoreAbort, StoreInterrupted } from '@livestore/livestore'
|
|
13
|
-
import { errorToString } from '@livestore/utils'
|
|
14
|
-
import {
|
|
14
|
+
import { errorToString, LS_DEV } from '@livestore/utils'
|
|
15
|
+
import type { OtelTracer } from '@livestore/utils/effect'
|
|
16
|
+
import { Deferred, Effect, Exit, identity, Logger, LogLevel, Schema, Scope, TaskTracing } from '@livestore/utils/effect'
|
|
15
17
|
import type * as otel from '@opentelemetry/api'
|
|
16
18
|
import type { ReactElement, ReactNode } from 'react'
|
|
17
19
|
import React from 'react'
|
|
@@ -26,7 +28,7 @@ interface LiveStoreProviderProps<GraphQLContext extends BaseGraphQLContext> {
|
|
|
26
28
|
*
|
|
27
29
|
* The `storeId` is also used for persistence.
|
|
28
30
|
*
|
|
29
|
-
* Make sure to also
|
|
31
|
+
* Make sure to also configure `storeId` in LiveStore Devtools (e.g. in Vite plugin).
|
|
30
32
|
*
|
|
31
33
|
* @default 'default'
|
|
32
34
|
*/
|
|
@@ -34,9 +36,9 @@ interface LiveStoreProviderProps<GraphQLContext extends BaseGraphQLContext> {
|
|
|
34
36
|
boot?: (
|
|
35
37
|
store: Store<GraphQLContext, LiveStoreSchema>,
|
|
36
38
|
parentSpan: otel.Span,
|
|
37
|
-
) => void | Promise<void> | Effect.Effect<void, unknown,
|
|
39
|
+
) => void | Promise<void> | Effect.Effect<void, unknown, OtelTracer.OtelTracer>
|
|
38
40
|
graphQLOptions?: GraphQLOptions<GraphQLContext>
|
|
39
|
-
otelOptions?: OtelOptions
|
|
41
|
+
otelOptions?: Partial<OtelOptions>
|
|
40
42
|
renderLoading: (status: BootStatus) => ReactElement
|
|
41
43
|
renderError?: (error: UnexpectedError | unknown) => ReactElement
|
|
42
44
|
renderShutdown?: (cause: IntentionalShutdownCause | StoreAbort) => ReactElement
|
|
@@ -69,7 +71,9 @@ const defaultRenderShutdown = (cause: IntentionalShutdownCause | StoreAbort) =>
|
|
|
69
71
|
? 'devtools import'
|
|
70
72
|
: cause.reason === 'devtools-reset'
|
|
71
73
|
? 'devtools reset'
|
|
72
|
-
:
|
|
74
|
+
: cause.reason === 'manual'
|
|
75
|
+
? 'manual shutdown'
|
|
76
|
+
: 'unknown reason'
|
|
73
77
|
|
|
74
78
|
return <>LiveStore Shutdown due to {reason}</>
|
|
75
79
|
}
|
|
@@ -88,7 +92,7 @@ export const LiveStoreProvider = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
88
92
|
batchUpdates,
|
|
89
93
|
disableDevtools,
|
|
90
94
|
signal,
|
|
91
|
-
}: LiveStoreProviderProps<GraphQLContext> & { children?: ReactNode }):
|
|
95
|
+
}: LiveStoreProviderProps<GraphQLContext> & { children?: ReactNode }): React.ReactElement => {
|
|
92
96
|
const storeCtx = useCreateStore({
|
|
93
97
|
storeId,
|
|
94
98
|
schema,
|
|
@@ -114,6 +118,9 @@ export const LiveStoreProvider = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
globalThis.__debugLiveStore ??= {}
|
|
121
|
+
if (Object.keys(globalThis.__debugLiveStore).length === 0) {
|
|
122
|
+
globalThis.__debugLiveStore['_'] = storeCtx.store
|
|
123
|
+
}
|
|
117
124
|
globalThis.__debugLiveStore[storeId] = storeCtx.store
|
|
118
125
|
|
|
119
126
|
return <LiveStoreContext.Provider value={storeCtx}>{children}</LiveStoreContext.Provider>
|
|
@@ -142,15 +149,20 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
142
149
|
disableDevtools,
|
|
143
150
|
reactivityGraph,
|
|
144
151
|
signal,
|
|
145
|
-
}: CreateStoreOptions<GraphQLContext, LiveStoreSchema> & {
|
|
152
|
+
}: CreateStoreOptions<GraphQLContext, LiveStoreSchema> & {
|
|
153
|
+
signal?: AbortSignal
|
|
154
|
+
otelOptions?: Partial<OtelOptions>
|
|
155
|
+
}) => {
|
|
146
156
|
const [_, rerender] = React.useState(0)
|
|
147
157
|
const ctxValueRef = React.useRef<{
|
|
148
158
|
value: StoreContext_ | BootStatus
|
|
149
|
-
|
|
159
|
+
componentScope: Scope.CloseableScope | undefined
|
|
160
|
+
shutdownDeferred: ShutdownDeferred | undefined
|
|
150
161
|
counter: number
|
|
151
162
|
}>({
|
|
152
163
|
value: { stage: 'loading' },
|
|
153
|
-
|
|
164
|
+
componentScope: undefined,
|
|
165
|
+
shutdownDeferred: undefined,
|
|
154
166
|
counter: 0,
|
|
155
167
|
})
|
|
156
168
|
|
|
@@ -168,12 +180,17 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
168
180
|
signal,
|
|
169
181
|
})
|
|
170
182
|
|
|
171
|
-
const interrupt = (
|
|
183
|
+
const interrupt = (
|
|
184
|
+
componentScope: Scope.CloseableScope,
|
|
185
|
+
shutdownDeferred: ShutdownDeferred,
|
|
186
|
+
error: StoreAbort | StoreInterrupted,
|
|
187
|
+
) =>
|
|
172
188
|
Effect.gen(function* () {
|
|
173
|
-
|
|
174
|
-
yield*
|
|
189
|
+
// console.log('[@livestore/livestore/react] interupting', error)
|
|
190
|
+
yield* Scope.close(componentScope, Exit.fail(error))
|
|
191
|
+
yield* Deferred.fail(shutdownDeferred, error)
|
|
175
192
|
}).pipe(
|
|
176
|
-
Effect.tapErrorCause((cause) => Effect.logDebug(
|
|
193
|
+
Effect.tapErrorCause((cause) => Effect.logDebug('[@livestore/livestore/react] interupting', cause)),
|
|
177
194
|
Effect.runFork,
|
|
178
195
|
)
|
|
179
196
|
|
|
@@ -199,11 +216,17 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
199
216
|
reactivityGraph,
|
|
200
217
|
signal,
|
|
201
218
|
}
|
|
202
|
-
if (ctxValueRef.current.
|
|
203
|
-
interrupt(ctxValueRef.current.
|
|
204
|
-
ctxValueRef.current.
|
|
219
|
+
if (ctxValueRef.current.componentScope !== undefined && ctxValueRef.current.shutdownDeferred !== undefined) {
|
|
220
|
+
interrupt(ctxValueRef.current.componentScope, ctxValueRef.current.shutdownDeferred, new StoreInterrupted())
|
|
221
|
+
ctxValueRef.current.componentScope = undefined
|
|
222
|
+
ctxValueRef.current.shutdownDeferred = undefined
|
|
223
|
+
}
|
|
224
|
+
ctxValueRef.current = {
|
|
225
|
+
value: { stage: 'loading' },
|
|
226
|
+
componentScope: undefined,
|
|
227
|
+
shutdownDeferred: undefined,
|
|
228
|
+
counter: ctxValueRef.current.counter + 1,
|
|
205
229
|
}
|
|
206
|
-
ctxValueRef.current = { value: { stage: 'loading' }, fiberSet: undefined, counter: ctxValueRef.current.counter + 1 }
|
|
207
230
|
}
|
|
208
231
|
|
|
209
232
|
React.useEffect(() => {
|
|
@@ -216,47 +239,52 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
216
239
|
}
|
|
217
240
|
|
|
218
241
|
signal?.addEventListener('abort', () => {
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
ctxValueRef.current.
|
|
242
|
+
if (
|
|
243
|
+
ctxValueRef.current.componentScope !== undefined &&
|
|
244
|
+
ctxValueRef.current.shutdownDeferred !== undefined &&
|
|
245
|
+
ctxValueRef.current.counter === counter
|
|
246
|
+
) {
|
|
247
|
+
interrupt(ctxValueRef.current.componentScope, ctxValueRef.current.shutdownDeferred, new StoreAbort())
|
|
248
|
+
ctxValueRef.current.componentScope = undefined
|
|
249
|
+
ctxValueRef.current.shutdownDeferred = undefined
|
|
222
250
|
}
|
|
223
251
|
})
|
|
224
252
|
|
|
225
253
|
Effect.gen(function* () {
|
|
226
|
-
const
|
|
227
|
-
|
|
254
|
+
const componentScope = yield* Scope.make()
|
|
255
|
+
const shutdownDeferred = yield* Deferred.make<
|
|
256
|
+
void,
|
|
228
257
|
UnexpectedError | IntentionalShutdownCause | StoreAbort | StoreInterrupted
|
|
229
258
|
>()
|
|
230
259
|
|
|
231
|
-
ctxValueRef.current.
|
|
260
|
+
ctxValueRef.current.componentScope = componentScope
|
|
261
|
+
ctxValueRef.current.shutdownDeferred = shutdownDeferred
|
|
232
262
|
|
|
233
263
|
yield* Effect.gen(function* () {
|
|
234
264
|
const store = yield* createStore({
|
|
235
|
-
fiberSet,
|
|
236
265
|
schema,
|
|
237
266
|
storeId,
|
|
238
267
|
graphQLOptions,
|
|
239
|
-
otelOptions,
|
|
240
268
|
boot,
|
|
241
269
|
adapter,
|
|
242
270
|
reactivityGraph,
|
|
243
271
|
batchUpdates,
|
|
244
272
|
disableDevtools,
|
|
273
|
+
shutdownDeferred,
|
|
245
274
|
onBootStatus: (status) => {
|
|
246
275
|
if (ctxValueRef.current.value.stage === 'running' || ctxValueRef.current.value.stage === 'error') return
|
|
247
276
|
setContextValue(status)
|
|
248
277
|
},
|
|
249
|
-
})
|
|
278
|
+
}).pipe(Effect.tapErrorCause((cause) => Deferred.failCause(shutdownDeferred, cause)))
|
|
250
279
|
|
|
251
280
|
setContextValue({ stage: 'running', store })
|
|
252
|
-
|
|
253
|
-
yield* Effect.never
|
|
254
|
-
}).pipe(Effect.scoped, FiberSet.run(fiberSet))
|
|
281
|
+
}).pipe(Scope.extend(componentScope), Effect.forkIn(componentScope))
|
|
255
282
|
|
|
256
283
|
const shutdownContext = (cause: IntentionalShutdownCause | StoreAbort) =>
|
|
257
284
|
Effect.sync(() => setContextValue({ stage: 'shutdown', cause }))
|
|
258
285
|
|
|
259
|
-
yield*
|
|
286
|
+
yield* Deferred.await(shutdownDeferred).pipe(
|
|
287
|
+
Effect.tapErrorCause((cause) => Effect.logDebug('[@livestore/livestore/react] shutdown', cause)),
|
|
260
288
|
Effect.catchTag('LiveStore.IntentionalShutdownCause', (cause) => shutdownContext(cause)),
|
|
261
289
|
Effect.catchTag('LiveStore.StoreAbort', (cause) => shutdownContext(cause)),
|
|
262
290
|
Effect.tapError((error) => Effect.sync(() => setContextValue({ stage: 'error', error }))),
|
|
@@ -269,17 +297,21 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
269
297
|
// shutdown before a new one is created - especially when shutdown logic is async. You can't trust `React.useEffect`.
|
|
270
298
|
// Thank you to Mattia Manzati for this idea.
|
|
271
299
|
withSemaphore(storeId),
|
|
300
|
+
Effect.withSpan('@livestore/react:useCreateStore'),
|
|
301
|
+
LS_DEV ? TaskTracing.withAsyncTaggingTracing((name: string) => (console as any).createTask(name)) : identity,
|
|
302
|
+
provideOtel({ parentSpanContext: otelOptions?.rootSpanContext, otelTracer: otelOptions?.tracer }),
|
|
272
303
|
Effect.tapCauseLogPretty,
|
|
273
304
|
Effect.annotateLogs({ thread: 'window' }),
|
|
274
|
-
Effect.provide(Logger.
|
|
305
|
+
Effect.provide(Logger.prettyWithThread('window')),
|
|
275
306
|
Logger.withMinimumLogLevel(LogLevel.Debug),
|
|
276
307
|
Effect.runFork,
|
|
277
308
|
)
|
|
278
309
|
|
|
279
310
|
return () => {
|
|
280
|
-
if (ctxValueRef.current.
|
|
281
|
-
interrupt(ctxValueRef.current.
|
|
282
|
-
ctxValueRef.current.
|
|
311
|
+
if (ctxValueRef.current.componentScope !== undefined && ctxValueRef.current.shutdownDeferred !== undefined) {
|
|
312
|
+
interrupt(ctxValueRef.current.componentScope, ctxValueRef.current.shutdownDeferred, new StoreInterrupted())
|
|
313
|
+
ctxValueRef.current.componentScope = undefined
|
|
314
|
+
ctxValueRef.current.shutdownDeferred = undefined
|
|
283
315
|
}
|
|
284
316
|
}
|
|
285
317
|
}, [
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`useRow > otel > should update the data based on component key
|
|
3
|
+
exports[`useRow > otel > should update the data based on component key strictMode={ strictMode: false } 1`] = `
|
|
4
4
|
{
|
|
5
|
-
"_name": "
|
|
5
|
+
"_name": "createStore",
|
|
6
|
+
"attributes": {
|
|
7
|
+
"debugInstanceId": "test",
|
|
8
|
+
"storeId": "default",
|
|
9
|
+
},
|
|
6
10
|
"children": [
|
|
7
11
|
{
|
|
8
12
|
"_name": "livestore.in-memory-db:execute",
|
|
@@ -17,6 +21,9 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
17
21
|
",
|
|
18
22
|
},
|
|
19
23
|
},
|
|
24
|
+
{
|
|
25
|
+
"_name": "LiveStore:createStore",
|
|
26
|
+
},
|
|
20
27
|
{
|
|
21
28
|
"_name": "sql-in-memory-select",
|
|
22
29
|
"attributes": {
|
|
@@ -33,6 +40,9 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
33
40
|
"sql.rowsCount": 1,
|
|
34
41
|
},
|
|
35
42
|
},
|
|
43
|
+
{
|
|
44
|
+
"_name": "LiveStore:sync",
|
|
45
|
+
},
|
|
36
46
|
{
|
|
37
47
|
"_name": "LiveStore:mutations",
|
|
38
48
|
"children": [
|
|
@@ -43,27 +53,16 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
43
53
|
},
|
|
44
54
|
"children": [
|
|
45
55
|
{
|
|
46
|
-
"_name": "LiveStore:
|
|
56
|
+
"_name": "LiveStore:mutate:applyMutations",
|
|
47
57
|
"attributes": {
|
|
48
58
|
"livestore.mutateLabel": "mutate",
|
|
49
59
|
},
|
|
50
60
|
"children": [
|
|
51
61
|
{
|
|
52
|
-
"_name": "
|
|
62
|
+
"_name": "livestore.in-memory-db:execute",
|
|
53
63
|
"attributes": {
|
|
54
|
-
"
|
|
55
|
-
"sql": "INSERT INTO UserInfo (id, username) VALUES ('u2', 'username_u2')"
|
|
56
|
-
}",
|
|
57
|
-
"livestore.mutation": "livestore.RawSql",
|
|
64
|
+
"sql.query": "INSERT INTO UserInfo (id, username) VALUES ('u2', 'username_u2')",
|
|
58
65
|
},
|
|
59
|
-
"children": [
|
|
60
|
-
{
|
|
61
|
-
"_name": "livestore.in-memory-db:execute",
|
|
62
|
-
"attributes": {
|
|
63
|
-
"sql.query": "INSERT INTO UserInfo (id, username) VALUES ('u2', 'username_u2')",
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
66
|
},
|
|
68
67
|
],
|
|
69
68
|
},
|
|
@@ -98,19 +97,24 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
98
97
|
},
|
|
99
98
|
"children": [
|
|
100
99
|
{
|
|
101
|
-
"_name": "LiveStore:
|
|
100
|
+
"_name": "LiveStore:mutate",
|
|
102
101
|
"attributes": {
|
|
103
|
-
"livestore.
|
|
104
|
-
"id": "u1"
|
|
105
|
-
}",
|
|
106
|
-
"livestore.mutation": "_Derived_Create_UserInfo",
|
|
102
|
+
"livestore.mutateLabel": "mutate",
|
|
107
103
|
},
|
|
108
104
|
"children": [
|
|
109
105
|
{
|
|
110
|
-
"_name": "
|
|
106
|
+
"_name": "LiveStore:mutate:applyMutations",
|
|
111
107
|
"attributes": {
|
|
112
|
-
"
|
|
108
|
+
"livestore.mutateLabel": "mutate",
|
|
113
109
|
},
|
|
110
|
+
"children": [
|
|
111
|
+
{
|
|
112
|
+
"_name": "livestore.in-memory-db:execute",
|
|
113
|
+
"attributes": {
|
|
114
|
+
"sql.query": "INSERT INTO UserInfo (username, text, id) VALUES ($username, $text, $id)",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
],
|
|
114
118
|
},
|
|
115
119
|
],
|
|
116
120
|
},
|
|
@@ -196,9 +200,13 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
196
200
|
}
|
|
197
201
|
`;
|
|
198
202
|
|
|
199
|
-
exports[`useRow > otel > should update the data based on component key
|
|
203
|
+
exports[`useRow > otel > should update the data based on component key strictMode={ strictMode: true } 1`] = `
|
|
200
204
|
{
|
|
201
|
-
"_name": "
|
|
205
|
+
"_name": "createStore",
|
|
206
|
+
"attributes": {
|
|
207
|
+
"debugInstanceId": "test",
|
|
208
|
+
"storeId": "default",
|
|
209
|
+
},
|
|
202
210
|
"children": [
|
|
203
211
|
{
|
|
204
212
|
"_name": "livestore.in-memory-db:execute",
|
|
@@ -213,6 +221,9 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
213
221
|
",
|
|
214
222
|
},
|
|
215
223
|
},
|
|
224
|
+
{
|
|
225
|
+
"_name": "LiveStore:createStore",
|
|
226
|
+
},
|
|
216
227
|
{
|
|
217
228
|
"_name": "sql-in-memory-select",
|
|
218
229
|
"attributes": {
|
|
@@ -229,6 +240,9 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
229
240
|
"sql.rowsCount": 1,
|
|
230
241
|
},
|
|
231
242
|
},
|
|
243
|
+
{
|
|
244
|
+
"_name": "LiveStore:sync",
|
|
245
|
+
},
|
|
232
246
|
{
|
|
233
247
|
"_name": "LiveStore:mutations",
|
|
234
248
|
"children": [
|
|
@@ -239,27 +253,16 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
239
253
|
},
|
|
240
254
|
"children": [
|
|
241
255
|
{
|
|
242
|
-
"_name": "LiveStore:
|
|
256
|
+
"_name": "LiveStore:mutate:applyMutations",
|
|
243
257
|
"attributes": {
|
|
244
258
|
"livestore.mutateLabel": "mutate",
|
|
245
259
|
},
|
|
246
260
|
"children": [
|
|
247
261
|
{
|
|
248
|
-
"_name": "
|
|
262
|
+
"_name": "livestore.in-memory-db:execute",
|
|
249
263
|
"attributes": {
|
|
250
|
-
"
|
|
251
|
-
"sql": "INSERT INTO UserInfo (id, username) VALUES ('u2', 'username_u2')"
|
|
252
|
-
}",
|
|
253
|
-
"livestore.mutation": "livestore.RawSql",
|
|
264
|
+
"sql.query": "INSERT INTO UserInfo (id, username) VALUES ('u2', 'username_u2')",
|
|
254
265
|
},
|
|
255
|
-
"children": [
|
|
256
|
-
{
|
|
257
|
-
"_name": "livestore.in-memory-db:execute",
|
|
258
|
-
"attributes": {
|
|
259
|
-
"sql.query": "INSERT INTO UserInfo (id, username) VALUES ('u2', 'username_u2')",
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
],
|
|
263
266
|
},
|
|
264
267
|
],
|
|
265
268
|
},
|
|
@@ -294,19 +297,24 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
294
297
|
},
|
|
295
298
|
"children": [
|
|
296
299
|
{
|
|
297
|
-
"_name": "LiveStore:
|
|
300
|
+
"_name": "LiveStore:mutate",
|
|
298
301
|
"attributes": {
|
|
299
|
-
"livestore.
|
|
300
|
-
"id": "u1"
|
|
301
|
-
}",
|
|
302
|
-
"livestore.mutation": "_Derived_Create_UserInfo",
|
|
302
|
+
"livestore.mutateLabel": "mutate",
|
|
303
303
|
},
|
|
304
304
|
"children": [
|
|
305
305
|
{
|
|
306
|
-
"_name": "
|
|
306
|
+
"_name": "LiveStore:mutate:applyMutations",
|
|
307
307
|
"attributes": {
|
|
308
|
-
"
|
|
308
|
+
"livestore.mutateLabel": "mutate",
|
|
309
309
|
},
|
|
310
|
+
"children": [
|
|
311
|
+
{
|
|
312
|
+
"_name": "livestore.in-memory-db:execute",
|
|
313
|
+
"attributes": {
|
|
314
|
+
"sql.query": "INSERT INTO UserInfo (username, text, id) VALUES ($username, $text, $id)",
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
],
|
|
310
318
|
},
|
|
311
319
|
],
|
|
312
320
|
},
|
|
@@ -341,13 +349,6 @@ exports[`useRow > otel > should update the data based on component key > strictM
|
|
|
341
349
|
"queryLabel": "db(row:UserInfo:u1)",
|
|
342
350
|
},
|
|
343
351
|
},
|
|
344
|
-
{
|
|
345
|
-
"_name": "LiveStore.subscribe",
|
|
346
|
-
"attributes": {
|
|
347
|
-
"label": "db(row:UserInfo:u1)",
|
|
348
|
-
"queryLabel": "db(row:UserInfo:u1)",
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
352
|
],
|
|
352
353
|
},
|
|
353
354
|
],
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { provideOtel } from '@livestore/common'
|
|
1
2
|
import { DbSchema, makeSchema } from '@livestore/common/schema'
|
|
2
3
|
import type { LiveStoreContextRunning } from '@livestore/livestore'
|
|
3
4
|
import { createStore, globalReactivityGraph, makeReactivityGraph } from '@livestore/livestore'
|
|
4
|
-
import { Effect
|
|
5
|
+
import { Effect } from '@livestore/utils/effect'
|
|
5
6
|
import { makeInMemoryAdapter } from '@livestore/web'
|
|
6
7
|
import type * as otel from '@opentelemetry/api'
|
|
7
8
|
import React from 'react'
|
|
@@ -65,7 +66,7 @@ export const makeTodoMvcReact = ({
|
|
|
65
66
|
otelTracer,
|
|
66
67
|
otelContext,
|
|
67
68
|
useGlobalReactivityGraph = true,
|
|
68
|
-
strictMode
|
|
69
|
+
strictMode,
|
|
69
70
|
}: {
|
|
70
71
|
otelTracer?: otel.Tracer
|
|
71
72
|
otelContext?: otel.Context
|
|
@@ -90,18 +91,12 @@ export const makeTodoMvcReact = ({
|
|
|
90
91
|
|
|
91
92
|
const reactivityGraph = useGlobalReactivityGraph ? globalReactivityGraph : makeReactivityGraph()
|
|
92
93
|
|
|
93
|
-
const fiberSet = yield* FiberSet.make()
|
|
94
|
-
|
|
95
94
|
const store = yield* createStore({
|
|
96
95
|
schema,
|
|
97
96
|
storeId: 'default',
|
|
98
97
|
adapter: makeInMemoryAdapter(),
|
|
99
98
|
reactivityGraph,
|
|
100
|
-
|
|
101
|
-
tracer: otelTracer,
|
|
102
|
-
rootSpanContext: otelContext,
|
|
103
|
-
},
|
|
104
|
-
fiberSet,
|
|
99
|
+
debug: { instanceId: 'test' },
|
|
105
100
|
})
|
|
106
101
|
|
|
107
102
|
// TODO improve typing of `LiveStoreContext`
|
|
@@ -117,5 +112,5 @@ export const makeTodoMvcReact = ({
|
|
|
117
112
|
</MaybeStrictMode>
|
|
118
113
|
)
|
|
119
114
|
|
|
120
|
-
return { wrapper, store, reactivityGraph, makeRenderCount
|
|
121
|
-
})
|
|
115
|
+
return { wrapper, store, reactivityGraph, makeRenderCount }
|
|
116
|
+
}).pipe(provideOtel({ parentSpanContext: otelContext, otelTracer }))
|
package/src/useQuery.ts
CHANGED
|
@@ -28,7 +28,7 @@ export const useQuery = <TQuery extends LiveQueryAny>(query: TQuery): GetResult<
|
|
|
28
28
|
export const useQueryRef = <TQuery extends LiveQueryAny>(
|
|
29
29
|
query$: TQuery,
|
|
30
30
|
parentOtelContext?: otel.Context,
|
|
31
|
-
): React.
|
|
31
|
+
): React.RefObject<GetResult<TQuery>> => {
|
|
32
32
|
const { store } = useStore()
|
|
33
33
|
|
|
34
34
|
React.useDebugValue(`LiveStore:useQuery:${query$.id}:${query$.label}`)
|