From 876d1492eb4fcef38c03cca696890051571fe319 Mon Sep 17 00:00:00 2001 From: Gerben Mulder Date: Tue, 7 Jul 2026 14:40:47 +0200 Subject: [PATCH] fix: include query format in view key --- src/query.test.ts | 79 +++++++++++++++++++++++++++++++++++++++++++++++ src/query.ts | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/query.test.ts b/src/query.test.ts index e99d9b4..0d3f8e4 100644 --- a/src/query.test.ts +++ b/src/query.test.ts @@ -7,10 +7,12 @@ import { defineQueriesWithType, defineQuery, number, + relationships, string, table, Zero, } from '@rocicorp/zero' +import { asQueryInternals } from '@rocicorp/zero/bindings' import { describe, expect, it, onTestFinished, vi } from 'vitest' import { nextTick, ref, watchEffect } from 'vue' import z from 'zod' @@ -276,6 +278,83 @@ describe('useQuery', () => { // expect(resultDetailsLog).toEqual(["complete"]); }) + it('re-materializes when query format changes', async () => { + const { zero, useQuery } = await setupTestEnvironment() + const zql = createBuilder(schema) + const pluralQuery = zql.table.where('a', 1).limit(1) + const singularQuery = zql.table.where('a', 1).one() + expect(asQueryInternals(pluralQuery).hash()).toBe(asQueryInternals(singularQuery).hash()) + + const singular = ref(false) + const materializeSpy = vi.spyOn(zero.value, 'materialize') + const query = () => singular.value + ? singularQuery + : pluralQuery + + useQuery(query as Parameters[0]) + + expect(materializeSpy).toHaveBeenCalledTimes(1) + + singular.value = true + await nextTick() + + expect(materializeSpy).toHaveBeenCalledTimes(2) + }) + + it('re-materializes when nested query format changes', async () => { + const issue = table('issue') + .columns({ id: string() }) + .primaryKey('id') + const comment = table('comment') + .columns({ id: string(), issueID: string() }) + .primaryKey('id') + const nestedSchema = createSchema({ + tables: [issue, comment], + relationships: [ + relationships(issue, ({ many }) => ({ + comments: many({ + sourceField: ['id'], + destField: ['issueID'], + destSchema: comment, + }), + })), + ], + }) + const zero = new Zero({ + userID: 'test-user', + server: null, + schema: nestedSchema, + kvStore: 'mem' as const, + }) + const zql = createBuilder(nestedSchema) + const pluralQuery = zql.issue + .where('id', 'i1') + .related('comments', q => q.limit(1)) + const singularQuery = zql.issue + .where('id', 'i1') + .related('comments', q => q.one()) + expect(asQueryInternals(pluralQuery).hash()).toBe(asQueryInternals(singularQuery).hash()) + + onTestFinished(async () => { + await zero.close() + }) + + const singular = ref(false) + const materializeSpy = vi.spyOn(zero, 'materialize') + const query = () => singular.value + ? singularQuery + : pluralQuery + + useQuery(zero, query as never) + + expect(materializeSpy).toHaveBeenCalledTimes(1) + + singular.value = true + await nextTick() + + expect(materializeSpy).toHaveBeenCalledTimes(2) + }) + it('useQuery deps change watchEffect', async () => { const { zero, queries, mutators, useQuery } = await setupTestEnvironment() const a = ref(1) diff --git a/src/query.ts b/src/query.ts index 0ee3343..a47ef7c 100644 --- a/src/query.ts +++ b/src/query.ts @@ -104,7 +104,7 @@ export function useQuery< ) const qi = computed(() => q.value ? asQueryInternals(q.value) : undefined) - const hash = computed(() => qi.value?.hash()) + const hash = computed(() => qi.value ? qi.value.hash() + JSON.stringify(qi.value.format) : undefined) watch( [