@livestore/livestore 0.0.54-dev.22 → 0.0.54-dev.24
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/__tests__/react/fixture.d.ts +0 -8
- package/dist/__tests__/react/fixture.d.ts.map +1 -1
- package/dist/__tests__/react/fixture.js +1 -1
- package/dist/__tests__/react/fixture.js.map +1 -1
- package/dist/effect/LiveStore.d.ts +1 -0
- package/dist/effect/LiveStore.d.ts.map +1 -1
- package/dist/effect/LiveStore.js +1 -1
- package/dist/effect/LiveStore.js.map +1 -1
- package/dist/global-state.d.ts +0 -2
- package/dist/global-state.d.ts.map +1 -1
- package/dist/global-state.js +0 -1
- package/dist/global-state.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react/LiveStoreContext.d.ts.map +1 -1
- package/dist/react/LiveStoreContext.js +3 -0
- package/dist/react/LiveStoreContext.js.map +1 -1
- package/dist/react/LiveStoreProvider.d.ts +3 -3
- package/dist/react/LiveStoreProvider.d.ts.map +1 -1
- package/dist/react/LiveStoreProvider.js +16 -8
- package/dist/react/LiveStoreProvider.js.map +1 -1
- package/dist/react/LiveStoreProvider.test.js +6 -4
- package/dist/react/LiveStoreProvider.test.js.map +1 -1
- package/dist/row-query.d.ts.map +1 -1
- package/dist/row-query.js +4 -38
- package/dist/row-query.js.map +1 -1
- package/dist/store.d.ts +7 -4
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +231 -96
- package/dist/store.js.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/react/fixture.tsx +1 -1
- package/src/effect/LiveStore.ts +2 -1
- package/src/global-state.ts +0 -4
- package/src/index.ts +2 -1
- package/src/react/LiveStoreContext.ts +4 -0
- package/src/react/LiveStoreProvider.test.tsx +9 -4
- package/src/react/LiveStoreProvider.tsx +17 -10
- package/src/row-query.ts +5 -51
- package/src/store.ts +315 -128
package/src/global-state.ts
CHANGED
|
@@ -11,10 +11,6 @@
|
|
|
11
11
|
*
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type { DbSchema } from '@livestore/common/schema'
|
|
15
|
-
|
|
16
14
|
import { makeReactivityGraph } from './reactiveQueries/base-class.js'
|
|
17
15
|
|
|
18
16
|
export const globalReactivityGraph = makeReactivityGraph()
|
|
19
|
-
|
|
20
|
-
export const dynamicallyRegisteredTables: Map<string, DbSchema.TableDef> = new Map()
|
package/src/index.ts
CHANGED
|
@@ -27,7 +27,7 @@ export {
|
|
|
27
27
|
type LiveQuery,
|
|
28
28
|
} from './reactiveQueries/base-class.js'
|
|
29
29
|
|
|
30
|
-
export { globalReactivityGraph
|
|
30
|
+
export { globalReactivityGraph } from './global-state.js'
|
|
31
31
|
|
|
32
32
|
export { type RowResult, type RowResultEncoded, rowQuery, deriveColQuery } from './row-query.js'
|
|
33
33
|
|
|
@@ -35,6 +35,7 @@ export * from '@livestore/common/schema'
|
|
|
35
35
|
export {
|
|
36
36
|
sql,
|
|
37
37
|
type BootDb,
|
|
38
|
+
type BootStatus,
|
|
38
39
|
type InMemoryDatabase,
|
|
39
40
|
type DebugInfo,
|
|
40
41
|
type MutableDebugInfo,
|
|
@@ -11,5 +11,9 @@ export const useStore = (): LiveStoreContext_ => {
|
|
|
11
11
|
throw new Error(`useStore can only be used inside StoreContext.Provider`)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
if (storeContext.stage !== 'running') {
|
|
15
|
+
throw new Error(`useStore can only be used after the store is running`)
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
return storeContext
|
|
15
19
|
}
|
|
@@ -37,7 +37,12 @@ describe('LiveStoreProvider', () => {
|
|
|
37
37
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
38
|
const adapterMemo = React.useMemo(() => makeInMemoryAdapter(), [forceUpdate])
|
|
39
39
|
return (
|
|
40
|
-
<LiveStoreProvider
|
|
40
|
+
<LiveStoreProvider
|
|
41
|
+
schema={schema}
|
|
42
|
+
renderLoading={(status) => <div>Loading LiveStore: {status.stage}</div>}
|
|
43
|
+
adapter={adapterMemo}
|
|
44
|
+
boot={bootCb}
|
|
45
|
+
>
|
|
41
46
|
<App />
|
|
42
47
|
</LiveStoreProvider>
|
|
43
48
|
)
|
|
@@ -47,14 +52,14 @@ describe('LiveStoreProvider', () => {
|
|
|
47
52
|
|
|
48
53
|
expect(renderCount).toBe(0)
|
|
49
54
|
|
|
50
|
-
await waitForElementToBeRemoved(() => screen.getByText('Loading LiveStore'))
|
|
55
|
+
await waitForElementToBeRemoved(() => screen.getByText((_) => _.startsWith('Loading LiveStore')))
|
|
51
56
|
|
|
52
57
|
expect(renderCount).toBe(1)
|
|
53
58
|
|
|
54
59
|
rerender(<Root forceUpdate={2} />)
|
|
55
60
|
|
|
56
|
-
await waitFor(() => screen.getByText('Loading LiveStore'))
|
|
57
|
-
await waitForElementToBeRemoved(() => screen.getByText('Loading LiveStore'))
|
|
61
|
+
await waitFor(() => screen.getByText('Loading LiveStore: loading'))
|
|
62
|
+
await waitForElementToBeRemoved(() => screen.getByText((_) => _.startsWith('Loading LiveStore')))
|
|
58
63
|
|
|
59
64
|
expect(renderCount).toBe(2)
|
|
60
65
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BootDb, StoreAdapterFactory } from '@livestore/common'
|
|
1
|
+
import type { BootDb, BootStatus, StoreAdapterFactory } from '@livestore/common'
|
|
2
2
|
import type { LiveStoreSchema } from '@livestore/common/schema'
|
|
3
3
|
import { shouldNeverHappen } from '@livestore/utils'
|
|
4
4
|
import type * as otel from '@opentelemetry/api'
|
|
@@ -16,14 +16,14 @@ interface LiveStoreProviderProps<GraphQLContext> {
|
|
|
16
16
|
boot?: (db: BootDb, parentSpan: otel.Span) => unknown | Promise<unknown>
|
|
17
17
|
graphQLOptions?: GraphQLOptions<GraphQLContext>
|
|
18
18
|
otelOptions?: OtelOptions
|
|
19
|
-
|
|
19
|
+
renderLoading: (status: BootStatus) => ReactElement
|
|
20
20
|
adapter: StoreAdapterFactory
|
|
21
21
|
batchUpdates?: (run: () => void) => void
|
|
22
22
|
disableDevtools?: boolean
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export const LiveStoreProvider = <GraphQLContext extends BaseGraphQLContext>({
|
|
26
|
-
|
|
26
|
+
renderLoading,
|
|
27
27
|
graphQLOptions,
|
|
28
28
|
otelOptions,
|
|
29
29
|
children,
|
|
@@ -43,8 +43,8 @@ export const LiveStoreProvider = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
43
43
|
disableDevtools,
|
|
44
44
|
})
|
|
45
45
|
|
|
46
|
-
if (storeCtx
|
|
47
|
-
return
|
|
46
|
+
if (storeCtx.stage !== 'running') {
|
|
47
|
+
return <div>{renderLoading(storeCtx)}</div>
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
window.__debugLiveStore = storeCtx.store
|
|
@@ -62,7 +62,7 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
62
62
|
disableDevtools,
|
|
63
63
|
}: LiveStoreCreateStoreOptions<GraphQLContext>) => {
|
|
64
64
|
const [_, rerender] = React.useState(0)
|
|
65
|
-
const ctxValueRef = React.useRef<StoreContext_ |
|
|
65
|
+
const ctxValueRef = React.useRef<StoreContext_ | BootStatus>({ stage: 'loading' })
|
|
66
66
|
const inputPropsCacheRef = React.useRef({
|
|
67
67
|
schema,
|
|
68
68
|
graphQLOptions,
|
|
@@ -89,9 +89,11 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
89
89
|
adapter,
|
|
90
90
|
batchUpdates,
|
|
91
91
|
}
|
|
92
|
-
ctxValueRef.current
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
if (ctxValueRef.current.stage === 'running') {
|
|
93
|
+
ctxValueRef.current.store.destroy()
|
|
94
|
+
oldStoreAlreadyDestroyedRef.current = true
|
|
95
|
+
ctxValueRef.current = { stage: 'loading' }
|
|
96
|
+
}
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
React.useEffect(() => {
|
|
@@ -107,8 +109,13 @@ const useCreateStore = <GraphQLContext extends BaseGraphQLContext>({
|
|
|
107
109
|
adapter,
|
|
108
110
|
batchUpdates,
|
|
109
111
|
disableDevtools,
|
|
112
|
+
onBootStatus: (status) => {
|
|
113
|
+
if (ctxValueRef.current.stage === 'running') return
|
|
114
|
+
ctxValueRef.current = status
|
|
115
|
+
rerender((c) => c + 1)
|
|
116
|
+
},
|
|
110
117
|
})
|
|
111
|
-
ctxValueRef.current = { store }
|
|
118
|
+
ctxValueRef.current = { stage: 'running', store }
|
|
112
119
|
oldStoreAlreadyDestroyedRef.current = false
|
|
113
120
|
rerender((c) => c + 1)
|
|
114
121
|
} catch (e) {
|
package/src/row-query.ts
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import { DbSchema
|
|
1
|
+
import type { QueryInfoCol, QueryInfoNone, QueryInfoRow } from '@livestore/common'
|
|
2
|
+
import { sql } from '@livestore/common'
|
|
3
|
+
import { DbSchema } from '@livestore/common/schema'
|
|
4
4
|
import type { GetValForKey } from '@livestore/utils'
|
|
5
5
|
import { shouldNeverHappen } from '@livestore/utils'
|
|
6
|
-
import {
|
|
6
|
+
import { Schema, TreeFormatter } from '@livestore/utils/effect'
|
|
7
7
|
import type * as otel from '@opentelemetry/api'
|
|
8
8
|
import type { SqliteDsl } from 'effect-db-schema'
|
|
9
|
-
import { SqliteAst } from 'effect-db-schema'
|
|
10
9
|
|
|
11
|
-
import type { Ref } from './reactive.js'
|
|
12
10
|
import type { LiveQuery, LiveQueryAny, QueryContext, ReactivityGraph } from './reactiveQueries/base-class.js'
|
|
13
11
|
import { computed } from './reactiveQueries/js.js'
|
|
14
12
|
import { LiveStoreSQLQuery } from './reactiveQueries/sql.js'
|
|
15
|
-
import type {
|
|
13
|
+
import type { Store } from './store.js'
|
|
16
14
|
|
|
17
15
|
export type RowQueryOptions = {
|
|
18
16
|
otelContext?: otel.Context
|
|
@@ -81,7 +79,6 @@ export const rowQuery: MakeRowQuery = <TTableDef extends DbSchema.TableDef>(
|
|
|
81
79
|
execBeforeFirstRun: makeExecBeforeFirstRun({
|
|
82
80
|
otelContext: options?.otelContext,
|
|
83
81
|
table,
|
|
84
|
-
tableName,
|
|
85
82
|
defaultValues,
|
|
86
83
|
id,
|
|
87
84
|
skipInsertDefaultRow: options?.skipInsertDefaultRow,
|
|
@@ -136,59 +133,16 @@ const makeExecBeforeFirstRun =
|
|
|
136
133
|
skipInsertDefaultRow,
|
|
137
134
|
otelContext: otelContext_,
|
|
138
135
|
table,
|
|
139
|
-
tableName,
|
|
140
136
|
}: {
|
|
141
137
|
id?: string
|
|
142
138
|
defaultValues?: any
|
|
143
139
|
skipInsertDefaultRow?: boolean
|
|
144
140
|
otelContext?: otel.Context
|
|
145
|
-
tableName: string
|
|
146
141
|
table: DbSchema.TableDef
|
|
147
142
|
}) =>
|
|
148
143
|
({ store }: QueryContext) => {
|
|
149
144
|
const otelContext = otelContext_ ?? store.otel.queriesSpanContext
|
|
150
145
|
|
|
151
|
-
// TODO we can remove this codepath again when Devtools v2 has landed
|
|
152
|
-
if (store.tableRefs[tableName] === undefined) {
|
|
153
|
-
const schemaHash = SqliteAst.hash(table.sqliteDef.ast)
|
|
154
|
-
const res = store.mainDbWrapper.select<{ schemaHash: number }>(
|
|
155
|
-
sql`SELECT schemaHash FROM ${SCHEMA_META_TABLE} WHERE tableName = '${tableName}'`,
|
|
156
|
-
)
|
|
157
|
-
if (res.length === 0 || res[0]!.schemaHash !== schemaHash) {
|
|
158
|
-
const db = {
|
|
159
|
-
...store.adapter.mainDb,
|
|
160
|
-
prepare: (query) => {
|
|
161
|
-
const mainStmt = store.adapter.mainDb.prepare(query)
|
|
162
|
-
return {
|
|
163
|
-
...mainStmt,
|
|
164
|
-
execute: (bindValues) => {
|
|
165
|
-
const getRowsChanged = mainStmt.execute(bindValues)
|
|
166
|
-
store.adapter.coordinator.execute(query, bindValues).pipe(Effect.tapCauseLogPretty, Effect.runFork)
|
|
167
|
-
return getRowsChanged
|
|
168
|
-
},
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
} satisfies InMemoryDatabase
|
|
172
|
-
|
|
173
|
-
migrateTable({
|
|
174
|
-
db,
|
|
175
|
-
tableAst: table.sqliteDef.ast,
|
|
176
|
-
otelContext,
|
|
177
|
-
schemaHash,
|
|
178
|
-
behaviour: 'create-if-not-exists',
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const label = `tableRef:${tableName}`
|
|
183
|
-
|
|
184
|
-
// TODO find a better implementation for this
|
|
185
|
-
const existingTableRefFromGraph = Array.from(store.reactivityGraph.atoms.values()).find(
|
|
186
|
-
(_) => _._tag === 'ref' && _.label === label,
|
|
187
|
-
) as Ref<null, QueryContext, RefreshReason> | undefined
|
|
188
|
-
|
|
189
|
-
store.tableRefs[tableName] = existingTableRefFromGraph ?? store.makeTableRef(tableName)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
146
|
if (skipInsertDefaultRow !== true && table.options.isSingleton === false) {
|
|
193
147
|
insertRowWithDefaultValuesOrIgnore({
|
|
194
148
|
store,
|