feat: add removable reference feature vertical slice

This commit is contained in:
donghyeon-ka
2026-07-26 14:56:34 +09:00
parent 980981bc86
commit c11be43f20
87 changed files with 1881 additions and 1114 deletions
+16 -7
View File
@@ -5,18 +5,27 @@ import {
createQueryCacheAdapter,
createQueryClient,
} from "../../src/adapters/query-cache/tanstack-query-cache.js";
import { queryKeys } from "../../src/contracts/query-keys.js";
import { canonicalize } from "../../src/contracts/query-keys.js";
const queryKeys = Object.freeze({
all: () => Object.freeze(["entity", 1]),
list: (filters = {}) =>
Object.freeze(["entity", 1, "list", canonicalize(filters)]),
/** @param {string} entityId */
detail: (entityId) =>
Object.freeze(["entity", 1, "detail", String(entityId)]),
});
describe("query key registry", () => {
it("canonicalizes filter order into the same stable key", () => {
expect(queryKeys.resource.list({ page: 1, status: "open" })).toEqual(
queryKeys.resource.list({ status: "open", page: 1 }),
expect(queryKeys.list({ page: 1, status: "open" })).toEqual(
queryKeys.list({ status: "open", page: 1 }),
);
});
it("contains no raw URL or token material", () => {
expect(JSON.stringify(queryKeys.resource.detail("resource-1"))).toBe(
'["resource",1,"detail","resource-1"]',
expect(JSON.stringify(queryKeys.detail("entity-1"))).toBe(
'["entity",1,"detail","entity-1"]',
);
});
});
@@ -25,7 +34,7 @@ describe("TanStack QueryCachePort adapter", () => {
it("reads, writes, and invalidates only the declared namespace", async () => {
const client = createQueryClient();
const adapter = createQueryCacheAdapter(client);
const listKey = queryKeys.resource.list({ page: 1 });
const listKey = queryKeys.list({ page: 1 });
const otherKey = ["other", 1];
expect(adapter.write(listKey, [{ id: "resource-1" }])).toEqual({ ok: true });
@@ -35,7 +44,7 @@ describe("TanStack QueryCachePort adapter", () => {
value: [{ id: "resource-1" }],
});
await adapter.invalidate(queryKeys.resource.all());
await adapter.invalidate(queryKeys.all());
expect(client.getQueryState(listKey)?.isInvalidated).toBe(true);
expect(client.getQueryState(otherKey)?.isInvalidated).toBe(false);
});