diff --git a/.changeset/solid-id-rendering.md b/.changeset/solid-id-rendering.md new file mode 100644 index 000000000..d81875bcc --- /dev/null +++ b/.changeset/solid-id-rendering.md @@ -0,0 +1,5 @@ +--- +'@tanstack/solid-db': patch +--- + +Fix reconcile usage in useLiveQuery by setting the key field to "$key" so that items are matched correctly during reconciliation. Fixes #1524. diff --git a/packages/solid-db/src/useLiveQuery.ts b/packages/solid-db/src/useLiveQuery.ts index 5380bae00..278484109 100644 --- a/packages/solid-db/src/useLiveQuery.ts +++ b/packages/solid-db/src/useLiveQuery.ts @@ -346,7 +346,9 @@ export function useLiveQuery( currentCollection: Collection, ) => { setData((prev) => - reconcile(Array.from(currentCollection.values()))(prev).filter(Boolean), + reconcile(Array.from(currentCollection.values()), { key: '$key' })( + prev, + ).filter(Boolean), ) } diff --git a/packages/solid-db/tests/useLiveQuery.test.tsx b/packages/solid-db/tests/useLiveQuery.test.tsx index 378c2a0fc..5c2198398 100644 --- a/packages/solid-db/tests/useLiveQuery.test.tsx +++ b/packages/solid-db/tests/useLiveQuery.test.tsx @@ -2587,4 +2587,58 @@ describe(`Query Collections`, () => { expect(rendered.result()).toBeUndefined() }) }) + describe(`custom id field`, () => { + it(`should keep all existing items when using a custom id field and reordering`, async () => { + type Item = { + _id: string + name: string + } + + const collection = createCollection( + mockSyncCollectionOptions({ + id: `custom-key-reorder-test`, + getKey: (item) => item._id, + initialData: [ + { _id: `bob1`, name: `Bob` }, + { _id: `kevin1`, name: `Kevin` }, + { _id: `stuart1`, name: `Stuart` }, + ], + }), + ) + + const rendered = renderHook(() => + useLiveQuery((q) => + q + .from({ items: collection }) + .orderBy(({ items }) => items.name, `asc`), + ), + ) + + await waitFor(() => { + expect(rendered.result.isReady).toBe(true) + }) + + expect(Array.from(rendered.result()).map((item) => item.name)).toEqual([ + `Bob`, + `Kevin`, + `Stuart`, + ]) + + collection.utils.begin() + collection.utils.write({ + type: `update`, + value: { + _id: `stuart1`, + name: `Alvin`, + }, + }) + collection.utils.commit() + + expect(Array.from(rendered.result()).map((item) => item.name)).toEqual([ + `Alvin`, + `Bob`, + `Kevin`, + ]) + }) + }) })