Skip to content

Commit 5d0737f

Browse files
add status & is[Status] variables on the framework hooks (#233)
Co-authored-by: Kyle Mathews <mathews.kyle@gmail.com>
1 parent 1c9e867 commit 5d0737f

9 files changed

Lines changed: 868 additions & 8 deletions

File tree

packages/db/src/collection.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ export class CollectionImpl<
237237
Array<CollectionStatus>
238238
> = {
239239
idle: [`loading`, `error`, `cleaned-up`],
240-
loading: [`ready`, `error`, `cleaned-up`],
240+
loading: [`initialCommit`, `error`, `cleaned-up`],
241+
initialCommit: [`ready`, `error`, `cleaned-up`],
241242
ready: [`cleaned-up`, `error`],
242243
error: [`cleaned-up`, `idle`],
243244
"cleaned-up": [`loading`, `error`],
@@ -382,14 +383,18 @@ export class CollectionImpl<
382383

383384
pendingTransaction.committed = true
384385

385-
// Update status to ready
386-
// We do this before committing as we want the events from the changes to
387-
// be from a "ready" state.
386+
// Update status to initialCommit when transitioning from loading
387+
// This indicates we're in the process of committing the first transaction
388388
if (this._status === `loading`) {
389-
this.setStatus(`ready`)
389+
this.setStatus(`initialCommit`)
390390
}
391391

392392
this.commitPendingTransactions()
393+
394+
// Transition from initialCommit to ready after the first commit is complete
395+
if (this._status === `initialCommit`) {
396+
this.setStatus(`ready`)
397+
}
393398
},
394399
})
395400

packages/db/src/query/live-query-collection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ export function liveQueryCollectionOptions<
162162

163163
const allCollectionsReady = () => {
164164
return Object.values(collections).every(
165-
(collection) => collection.status === `ready`
165+
(collection) =>
166+
collection.status === `ready` || collection.status === `initialCommit`
166167
)
167168
}
168169

packages/db/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ export type CollectionStatus =
244244
| `idle`
245245
/** Sync has started but hasn't received the first commit yet */
246246
| `loading`
247+
/** Collection is in the process of committing its first transaction */
248+
| `initialCommit`
247249
/** Collection has received at least one commit and is ready for use */
248250
| `ready`
249251
/** An error occurred during sync initialization */

packages/db/tests/collection-errors.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ describe(`Collection Error Handling`, () => {
360360

361361
// Valid transitions from loading
362362
expect(() =>
363-
collectionImpl.validateStatusTransition(`loading`, `ready`)
363+
collectionImpl.validateStatusTransition(`loading`, `initialCommit`)
364364
).not.toThrow()
365365
expect(() =>
366366
collectionImpl.validateStatusTransition(`loading`, `error`)
@@ -369,6 +369,17 @@ describe(`Collection Error Handling`, () => {
369369
collectionImpl.validateStatusTransition(`loading`, `cleaned-up`)
370370
).not.toThrow()
371371

372+
// Valid transitions from initialCommit
373+
expect(() =>
374+
collectionImpl.validateStatusTransition(`initialCommit`, `ready`)
375+
).not.toThrow()
376+
expect(() =>
377+
collectionImpl.validateStatusTransition(`initialCommit`, `error`)
378+
).not.toThrow()
379+
expect(() =>
380+
collectionImpl.validateStatusTransition(`initialCommit`, `cleaned-up`)
381+
).not.toThrow()
382+
372383
// Valid transitions from ready
373384
expect(() =>
374385
collectionImpl.validateStatusTransition(`ready`, `cleaned-up`)
@@ -397,6 +408,12 @@ describe(`Collection Error Handling`, () => {
397408
expect(() =>
398409
collectionImpl.validateStatusTransition(`idle`, `idle`)
399410
).not.toThrow()
411+
expect(() =>
412+
collectionImpl.validateStatusTransition(
413+
`initialCommit`,
414+
`initialCommit`
415+
)
416+
).not.toThrow()
400417
expect(() =>
401418
collectionImpl.validateStatusTransition(`ready`, `ready`)
402419
).not.toThrow()

packages/react-db/src/useLiveQuery.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useRef, useSyncExternalStore } from "react"
22
import { createLiveQueryCollection } from "@tanstack/db"
33
import type {
44
Collection,
5+
CollectionStatus,
56
Context,
67
GetResult,
78
InitialQueryBuilder,
@@ -17,6 +18,12 @@ export function useLiveQuery<TContext extends Context>(
1718
state: Map<string | number, GetResult<TContext>>
1819
data: Array<GetResult<TContext>>
1920
collection: Collection<GetResult<TContext>, string | number, {}>
21+
status: CollectionStatus
22+
isLoading: boolean
23+
isReady: boolean
24+
isIdle: boolean
25+
isError: boolean
26+
isCleanedUp: boolean
2027
}
2128

2229
// Overload 2: Accept config object
@@ -27,6 +34,12 @@ export function useLiveQuery<TContext extends Context>(
2734
state: Map<string | number, GetResult<TContext>>
2835
data: Array<GetResult<TContext>>
2936
collection: Collection<GetResult<TContext>, string | number, {}>
37+
status: CollectionStatus
38+
isLoading: boolean
39+
isReady: boolean
40+
isIdle: boolean
41+
isError: boolean
42+
isCleanedUp: boolean
3043
}
3144

3245
// Overload 3: Accept pre-created live query collection
@@ -40,6 +53,12 @@ export function useLiveQuery<
4053
state: Map<TKey, TResult>
4154
data: Array<TResult>
4255
collection: Collection<TResult, TKey, TUtils>
56+
status: CollectionStatus
57+
isLoading: boolean
58+
isReady: boolean
59+
isIdle: boolean
60+
isError: boolean
61+
isCleanedUp: boolean
4362
}
4463

4564
// Implementation - use function overloads to infer the actual collection type
@@ -171,5 +190,13 @@ export function useLiveQuery(
171190
state: snapshot.state,
172191
data: snapshot.data,
173192
collection: snapshot.collection,
193+
status: snapshot.collection.status,
194+
isLoading:
195+
snapshot.collection.status === `loading` ||
196+
snapshot.collection.status === `initialCommit`,
197+
isReady: snapshot.collection.status === `ready`,
198+
isIdle: snapshot.collection.status === `idle`,
199+
isError: snapshot.collection.status === `error`,
200+
isCleanedUp: snapshot.collection.status === `cleaned-up`,
174201
}
175202
}

0 commit comments

Comments
 (0)