feat(COMPT-44): README guide + changeset for v0.1.0#8
feat(COMPT-44): README guide + changeset for v0.1.0#8a-elkhiraooui-ciscode merged 1 commit intodevelopfrom
Conversation
- Rewrote README as an end-to-end usage guide for @ciscode/query-kit - createQuery: key builder, fetcher, useQuery shorthand, direct key/fn access - usePaginatedQuery: offset mode (nextPage/prevPage) and cursor mode (fetchNextPage/hasNextPage) - createMutation + invalidateQueries full lifecycle example - setQueryData typed updater example - API reference table covering all exports - Peer dep @tanstack/react-query >=5 clearly stated - Changeset: minor bump to v0.1.0 (initial public release)
There was a problem hiding this comment.
Pull request overview
This PR prepares @ciscode/query-kit for its initial public release by replacing the template README with an end-to-end usage guide and adding a Changesets entry for a 0.1.0 release.
Changes:
- Rewrites
README.mdinto a usage guide coveringcreateQuery,usePaginatedQuery,createMutation, and cache helpers. - Adds an API reference table and release flow notes to the README.
- Adds a changeset to bump
@ciscode/query-kittov0.1.0.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| README.md | New usage guide and API reference for query-kit consumers. |
| .changeset/v0-1-0-initial-release.md | Changesets entry for initial public release version bump. |
| export function UserProfile({ userId }: { userId: number }) { | ||
| const { data, isLoading, isError, error } = userQuery.useQuery({ id: userId }); | ||
|
|
||
| if (isLoading) return <p>Loading…</p>; | ||
| if (isError) return <p>Error: {error.message}</p>; | ||
|
|
||
| return ( | ||
| <div> | ||
| <h1>{data.name}</h1> | ||
| <p>{data.email}</p> | ||
| </div> |
There was a problem hiding this comment.
In this snippet, userQuery.useQuery returns UseQueryResult<User, Error> where data is User | undefined and error is Error | null. As written, error.message and data.name/data.email won’t typecheck without additional guards (e.g., check error/data or use optional chaining).
| // postsQuery is a createQuery definition whose fetcher accepts { page, pageSize } | ||
| export function PostsList() { | ||
| const { data, isLoading, page, pageSize, nextPage, prevPage } = usePaginatedQuery( | ||
| postsQuery, | ||
| { page: 1, pageSize: 10 }, |
There was a problem hiding this comment.
The example implies postsQuery’s key/fetcher take { page, pageSize }, but usePaginatedQuery already appends page and pageSize onto the generated queryKey (and also passes them into queryDef.queryKey). If the query definition’s key builder includes page/pageSize, keys will contain duplicates (e.g., ['posts', page, pageSize, page, pageSize]). Consider clarifying the expected key builder shape for paginated queries to avoid confusing/unstable keys.
| // postsQuery is a createQuery definition whose fetcher accepts { page, pageSize } | |
| export function PostsList() { | |
| const { data, isLoading, page, pageSize, nextPage, prevPage } = usePaginatedQuery( | |
| postsQuery, | |
| { page: 1, pageSize: 10 }, | |
| // For usePaginatedQuery, postsQuery should define only non-pagination params. | |
| // The hook manages page and pageSize internally for the generated query key/fetching. | |
| export function PostsList() { | |
| const { data, isLoading, page, pageSize, nextPage, prevPage } = usePaginatedQuery( | |
| postsQuery, | |
| {}, |
| // Invalidate a specific user | ||
| await invalidateQueries(queryClient, userQuery, { id: 42 }); | ||
|
|
||
| // Invalidate all queries matching the userQuery key prefix | ||
| await invalidateQueries(queryClient, userQuery); | ||
| ``` |
There was a problem hiding this comment.
The docs say calling invalidateQueries(queryClient, userQuery) invalidates all queries matching the query’s key prefix, but the current implementation calls queryDef.queryKey({} as TParams) when params are omitted. For definitions like ['users', params.id], this becomes ['users', undefined] and will not match/invalidate existing user queries. Either update the docs to require params (or explain the keyFn must handle empty params), or change the helper to invalidate by a real prefix key.
| <button type="submit" disabled={isPending}> | ||
| {isPending ? 'Saving…' : 'Save'} | ||
| </button> | ||
| {isError && <p role="alert">Error: {error.message}</p>} |
There was a problem hiding this comment.
This snippet uses error.message inside {isError && ...}, but TanStack mutation results type error as Error | null, and isError doesn’t narrow error to non-null for TypeScript. Use optional chaining or an explicit if (error) check so the example typechecks.
| {isError && <p role="alert">Error: {error.message}</p>} | |
| {isError && <p role="alert">Error: {error?.message ?? 'Unknown error'}</p>} |
| | Export | Kind | Description | | ||
| | ------------------------- | ---------- | -------------------------------------------------- | | ||
| | `createQuery` | `function` | Creates a `QueryDefinition` (key + fetcher + hook) | | ||
| | `usePaginatedQuery` | `function` | Offset or cursor pagination hook | | ||
| | `createMutation` | `function` | Creates a `MutationDefinition` (fn + hook) | | ||
| | `invalidateQueries` | `function` | Type-safe query invalidation via `QueryDefinition` | | ||
| | `setQueryData` | `function` | Type-safe cache write via `QueryDefinition` | | ||
| | `QueryDefinition` | `type` | Shape returned by `createQuery` | | ||
| | `MutationDefinition` | `type` | Shape returned by `createMutation` | | ||
| | `OffsetPaginationOptions` | `type` | Options for `usePaginatedQuery` offset mode | | ||
| | `CursorPaginationOptions` | `type` | Options for `usePaginatedQuery` cursor mode | |
There was a problem hiding this comment.
The API reference table doesn’t reflect everything that’s currently exported from the package (e.g., NoopButton, useNoop, noop, and the __*_placeholder exports are re-exported from src/index.ts). Either add these to the table or remove/stop exporting the placeholders so the README matches the actual public API.
| | Export | Kind | Description | | |
| | ------------------------- | ---------- | -------------------------------------------------- | | |
| | `createQuery` | `function` | Creates a `QueryDefinition` (key + fetcher + hook) | | |
| | `usePaginatedQuery` | `function` | Offset or cursor pagination hook | | |
| | `createMutation` | `function` | Creates a `MutationDefinition` (fn + hook) | | |
| | `invalidateQueries` | `function` | Type-safe query invalidation via `QueryDefinition` | | |
| | `setQueryData` | `function` | Type-safe cache write via `QueryDefinition` | | |
| | `QueryDefinition` | `type` | Shape returned by `createQuery` | | |
| | `MutationDefinition` | `type` | Shape returned by `createMutation` | | |
| | `OffsetPaginationOptions` | `type` | Options for `usePaginatedQuery` offset mode | | |
| | `CursorPaginationOptions` | `type` | Options for `usePaginatedQuery` cursor mode | | |
| | Export | Kind | Description | | |
| | ------------------------- | ------------------- | -------------------------------------------------- | | |
| | `createQuery` | `function` | Creates a `QueryDefinition` (key + fetcher + hook) | | |
| | `usePaginatedQuery` | `function` | Offset or cursor pagination hook | | |
| | `createMutation` | `function` | Creates a `MutationDefinition` (fn + hook) | | |
| | `invalidateQueries` | `function` | Type-safe query invalidation via `QueryDefinition` | | |
| | `setQueryData` | `function` | Type-safe cache write via `QueryDefinition` | | |
| | `noop` | `function` | No-op utility export | | |
| | `useNoop` | `function` | No-op hook export | | |
| | `NoopButton` | `component` | No-op button component export | | |
| | `__*_placeholder` | `internal export(s)`| Placeholder re-exports currently exposed publicly | | |
| | `QueryDefinition` | `type` | Shape returned by `createQuery` | | |
| | `MutationDefinition` | `type` | Shape returned by `createMutation` | | |
| | `OffsetPaginationOptions` | `type` | Options for `usePaginatedQuery` offset mode | | |
| | `CursorPaginationOptions` | `type` | Options for `usePaginatedQuery` cursor mode | |
| - Merge to `develop` | ||
| - Add a changeset for user-facing changes: `npx changeset` | ||
| - Promote `develop` → `master` | ||
| - Work on a `feat/*` branch from `develop` |
There was a problem hiding this comment.
Release flow branch naming here (feat/*) conflicts with other repo docs/workflows that mention feature/* as well (e.g., CONTRIBUTING uses feature/amazing-feature, and publish workflow mentions feat/** or feature/**). Aligning these instructions will reduce confusion for contributors.
| - Work on a `feat/*` branch from `develop` | |
| - Work on a `feature/*` branch from `develop` |
* ops: updated sonar variable * Feat/compt 40 create query factory (#3) * feat(COMPT-40): implement createQuery factory - Add createQuery(keyFn, fetcher) returning QueryDefinition<TParams, TData> - TData and TParams fully inferred from fetcher signature, zero manual annotation - queryKey returns stable readonly tuple via keyFn - useQuery shorthand hook wraps useTanstackQuery with typed params - Export from src/index.ts - Add @tanstack/react-query as peerDependency (>=5) and devDependency - Add pnpm cssstyle override to fix Node.js v22 + jsdom@28 ESM compat issue - Fix duplicate import in vitest.config.ts - 9 tests, 100% coverage on createQuery.ts, 88.6% overall Closes COMPT-40 * chore: sync package-lock.json with @tanstack/react-query addition * chore: switch from pnpm to npm, sync lockfile * chore: fix prettier formatting across all files * feat(COMPT-41): implement usePaginatedQuery offset and cursor modes (#4) - usePaginatedQuery(queryDef, params, options) supports mode: 'offset' | 'cursor' - Offset mode: page/pageSize (default 20)/nextPage/prevPage/totalPages - Cursor mode: fetchNextPage/hasNextPage/nextCursor via useInfiniteQuery - Both expose data as flat T[] array, isLoading, isFetching, isError, error - Offset uses useQuery with page in queryKey; cursor uses useInfiniteQuery - getCursor option required for cursor mode - Typed overloads: full inference, no TanStack internals exposed - 15 tests, 100% coverage on usePaginatedQuery.ts, 95.62% overall Closes COMPT-41 * feat(COMPT-42): implement createMutation and typed cache helpers (#5) * feat(COMPT-42): implement createMutation and typed cache helpers - createMutation(fn) returns MutationDefinition with mutationFn and useMutation shorthand - useMutation exposes mutate/mutateAsync/isPending/isError/error/data/reset - invalidateQueries(client, queryDef, params?) uses queryDef key — no raw strings - setQueryData typed updater — wrong shape is TypeScript compile error - All exported from src/index.ts via src/query/index.ts - 18 tests (10 mutation + 8 cache), 100% coverage on both src files, 95.94% overall Closes COMPT-42 * chore: fix prettier formatting * fix: suppress eslint no-unused-vars on intentionally unused mutation param * feat(COMPT-43): add integration test suite in src/__tests__/ (#6) - createQuery.test.tsx: queryKey shape, queryFn call, useQuery loading/success/error/enabled/rerender - usePaginatedQuery.test.tsx: offset page navigation, data shape, cursor fetchNextPage/hasNextPage/nextCursor - createMutation.test.tsx: idle state, mutate, isPending, data, isError, reset, mutateAsync - cacheHelpers.test.tsx: invalidateQueries marks stale + refetch, setQueryData direct/updater/hook reflect All 84 tests pass, 97.35% stmt coverage (target: 85%) * feat(COMPT-43): consolidate all tests into src/__tests__/ (#7) - Moved all co-located tests (src/query/*.test.tsx, src/index.test.ts) into src/__tests__/ - Merged unique tests from co-located files: definition shape, stable key, TData inference, mode assertions, initialPage, mutationFn direct call - Deleted: src/query/createQuery.test.tsx, cacheHelpers.test.tsx, createMutation.test.tsx, usePaginatedQuery.test.tsx, src/index.test.ts - 51 tests, all passing, no test files outside src/__tests__/ * feat(COMPT-44): README guide + changeset for v0.1.0 (#8) - Rewrote README as an end-to-end usage guide for @ciscode/query-kit - createQuery: key builder, fetcher, useQuery shorthand, direct key/fn access - usePaginatedQuery: offset mode (nextPage/prevPage) and cursor mode (fetchNextPage/hasNextPage) - createMutation + invalidateQueries full lifecycle example - setQueryData typed updater example - API reference table covering all exports - Peer dep @tanstack/react-query >=5 clearly stated - Changeset: minor bump to v0.1.0 (initial public release) * Feat/compt 44 readme changeset (#10) * feat(COMPT-44): README guide + changeset for v0.1.0 - Rewrote README as an end-to-end usage guide for @ciscode/query-kit - createQuery: key builder, fetcher, useQuery shorthand, direct key/fn access - usePaginatedQuery: offset mode (nextPage/prevPage) and cursor mode (fetchNextPage/hasNextPage) - createMutation + invalidateQueries full lifecycle example - setQueryData typed updater example - API reference table covering all exports - Peer dep @tanstack/react-query >=5 clearly stated - Changeset: minor bump to v0.1.0 (initial public release) * fix(ci): correct sonar.tests path from 'test' to 'src/__tests__' Tests live in src/__tests__/, not test/. Also add sonar.exclusions and sonar.test.inclusions so source files and test files are correctly separated in SonarCloud analysis. --------- Co-authored-by: Zaiidmo <zaiidmoumnii@gmail.com>
* ops: updated sonar variable * Feat/compt 40 create query factory (#3) * feat(COMPT-40): implement createQuery factory - Add createQuery(keyFn, fetcher) returning QueryDefinition<TParams, TData> - TData and TParams fully inferred from fetcher signature, zero manual annotation - queryKey returns stable readonly tuple via keyFn - useQuery shorthand hook wraps useTanstackQuery with typed params - Export from src/index.ts - Add @tanstack/react-query as peerDependency (>=5) and devDependency - Add pnpm cssstyle override to fix Node.js v22 + jsdom@28 ESM compat issue - Fix duplicate import in vitest.config.ts - 9 tests, 100% coverage on createQuery.ts, 88.6% overall Closes COMPT-40 * chore: sync package-lock.json with @tanstack/react-query addition * chore: switch from pnpm to npm, sync lockfile * chore: fix prettier formatting across all files * feat(COMPT-41): implement usePaginatedQuery offset and cursor modes (#4) - usePaginatedQuery(queryDef, params, options) supports mode: 'offset' | 'cursor' - Offset mode: page/pageSize (default 20)/nextPage/prevPage/totalPages - Cursor mode: fetchNextPage/hasNextPage/nextCursor via useInfiniteQuery - Both expose data as flat T[] array, isLoading, isFetching, isError, error - Offset uses useQuery with page in queryKey; cursor uses useInfiniteQuery - getCursor option required for cursor mode - Typed overloads: full inference, no TanStack internals exposed - 15 tests, 100% coverage on usePaginatedQuery.ts, 95.62% overall Closes COMPT-41 * feat(COMPT-42): implement createMutation and typed cache helpers (#5) * feat(COMPT-42): implement createMutation and typed cache helpers - createMutation(fn) returns MutationDefinition with mutationFn and useMutation shorthand - useMutation exposes mutate/mutateAsync/isPending/isError/error/data/reset - invalidateQueries(client, queryDef, params?) uses queryDef key — no raw strings - setQueryData typed updater — wrong shape is TypeScript compile error - All exported from src/index.ts via src/query/index.ts - 18 tests (10 mutation + 8 cache), 100% coverage on both src files, 95.94% overall Closes COMPT-42 * chore: fix prettier formatting * fix: suppress eslint no-unused-vars on intentionally unused mutation param * feat(COMPT-43): add integration test suite in src/__tests__/ (#6) - createQuery.test.tsx: queryKey shape, queryFn call, useQuery loading/success/error/enabled/rerender - usePaginatedQuery.test.tsx: offset page navigation, data shape, cursor fetchNextPage/hasNextPage/nextCursor - createMutation.test.tsx: idle state, mutate, isPending, data, isError, reset, mutateAsync - cacheHelpers.test.tsx: invalidateQueries marks stale + refetch, setQueryData direct/updater/hook reflect All 84 tests pass, 97.35% stmt coverage (target: 85%) * feat(COMPT-43): consolidate all tests into src/__tests__/ (#7) - Moved all co-located tests (src/query/*.test.tsx, src/index.test.ts) into src/__tests__/ - Merged unique tests from co-located files: definition shape, stable key, TData inference, mode assertions, initialPage, mutationFn direct call - Deleted: src/query/createQuery.test.tsx, cacheHelpers.test.tsx, createMutation.test.tsx, usePaginatedQuery.test.tsx, src/index.test.ts - 51 tests, all passing, no test files outside src/__tests__/ * feat(COMPT-44): README guide + changeset for v0.1.0 (#8) - Rewrote README as an end-to-end usage guide for @ciscode/query-kit - createQuery: key builder, fetcher, useQuery shorthand, direct key/fn access - usePaginatedQuery: offset mode (nextPage/prevPage) and cursor mode (fetchNextPage/hasNextPage) - createMutation + invalidateQueries full lifecycle example - setQueryData typed updater example - API reference table covering all exports - Peer dep @tanstack/react-query >=5 clearly stated - Changeset: minor bump to v0.1.0 (initial public release) * Feat/compt 44 readme changeset (#10) * feat(COMPT-44): README guide + changeset for v0.1.0 - Rewrote README as an end-to-end usage guide for @ciscode/query-kit - createQuery: key builder, fetcher, useQuery shorthand, direct key/fn access - usePaginatedQuery: offset mode (nextPage/prevPage) and cursor mode (fetchNextPage/hasNextPage) - createMutation + invalidateQueries full lifecycle example - setQueryData typed updater example - API reference table covering all exports - Peer dep @tanstack/react-query >=5 clearly stated - Changeset: minor bump to v0.1.0 (initial public release) * fix(ci): correct sonar.tests path from 'test' to 'src/__tests__' Tests live in src/__tests__/, not test/. Also add sonar.exclusions and sonar.test.inclusions so source files and test files are correctly separated in SonarCloud analysis. * Feat/compt 44 readme changeset (#12) * feat(COMPT-44): README guide + changeset for v0.1.0 - Rewrote README as an end-to-end usage guide for @ciscode/query-kit - createQuery: key builder, fetcher, useQuery shorthand, direct key/fn access - usePaginatedQuery: offset mode (nextPage/prevPage) and cursor mode (fetchNextPage/hasNextPage) - createMutation + invalidateQueries full lifecycle example - setQueryData typed updater example - API reference table covering all exports - Peer dep @tanstack/react-query >=5 clearly stated - Changeset: minor bump to v0.1.0 (initial public release) * fix(ci): correct sonar.tests path from 'test' to 'src/__tests__' Tests live in src/__tests__/, not test/. Also add sonar.exclusions and sonar.test.inclusions so source files and test files are correctly separated in SonarCloud analysis. * 0.0.1 --------- Co-authored-by: Zaiidmo <zaiidmoumnii@gmail.com>
Summary
Why
Checklist
npm run lintpassesnpm run typecheckpassesnpm testpassesnpm run buildpassesnpx changeset) if this affects consumersNotes