mirror of
https://github.com/langgenius/dify.git
synced 2026-05-09 12:59:18 +08:00
add skill
This commit is contained in:
parent
48a96739d4
commit
396c349cdd
39
.agents/skills/tkdodo-react-query/SKILL.md
Normal file
39
.agents/skills/tkdodo-react-query/SKILL.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
name: tkdodo-react-query
|
||||
description: TanStack Query / React Query implementation and review guidance distilled from TkDodo's 32-part Practical React Query series. Use when working on query keys, queryOptions factories, queryFn context, selectors, data transformations, status checks, loading/error UX, mutations, invalidation, optimistic updates, infinite queries, forms, React Router loaders/actions, cache seeding, WebSockets, offline behavior, testing, TypeScript inference, or deciding whether React Query is the right abstraction.
|
||||
---
|
||||
|
||||
# TkDodo React Query
|
||||
|
||||
## Intent
|
||||
|
||||
Use this skill to apply TkDodo's React Query guidance without loading the full blog series into context.
|
||||
|
||||
For Dify frontend work, combine this skill with `frontend-query-mutation`: let `frontend-query-mutation` govern local oRPC, contract, service-layer, and invalidation conventions; use this skill for general TanStack Query design judgment.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Identify the React Query concern.
|
||||
- Read `references/practice-guide.md` for implementation and review rules.
|
||||
- Read `references/series-index.md` when you need the original article mapping, source links, or deeper topic selection.
|
||||
2. Preserve TypeScript inference.
|
||||
- Prefer `queryOptions()` and colocated query factories over wrapper types that erase inference.
|
||||
- Avoid manually passing `useQuery` generics unless inference cannot express the intended result.
|
||||
3. Treat query keys as dependencies.
|
||||
- Include every queryFn input in the key.
|
||||
- Use stable array or object keys that support broad and targeted invalidation.
|
||||
4. Choose the least surprising cache update strategy.
|
||||
- Prefer invalidation after mutations.
|
||||
- Use direct cache writes when the mutation response is the complete replacement for the cached entity.
|
||||
- Use optimistic updates only when the UX benefit justifies duplicating server logic.
|
||||
5. Review UX states deliberately.
|
||||
- Keep previously available data visible during background refetches where possible.
|
||||
- Do not replace good data with a full-page error for a background failure unless the product explicitly wants that.
|
||||
6. Cite original sources when documenting rationale.
|
||||
- Do not copy full article text into code comments or docs.
|
||||
- Link to the relevant article from `references/series-index.md` for non-obvious decisions.
|
||||
|
||||
## References
|
||||
|
||||
- `references/practice-guide.md`: concise applied rules for implementation and code review.
|
||||
- `references/series-index.md`: all 32 series entries, source URLs, and topic map.
|
||||
4
.agents/skills/tkdodo-react-query/agents/openai.yaml
Normal file
4
.agents/skills/tkdodo-react-query/agents/openai.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "TkDodo React Query"
|
||||
short_description: "TanStack Query guidance distilled from TkDodo series"
|
||||
default_prompt: "Use this skill when implementing or reviewing TanStack Query / React Query code, especially query keys, queryOptions, mutations, invalidation, selectors, optimistic updates, forms, testing, and TypeScript inference."
|
||||
185
.agents/skills/tkdodo-react-query/references/practice-guide.md
Normal file
185
.agents/skills/tkdodo-react-query/references/practice-guide.md
Normal file
@ -0,0 +1,185 @@
|
||||
# TkDodo React Query Practice Guide
|
||||
|
||||
This is an applied, paraphrased digest of TkDodo's Practical React Query series. It is not a copy of the articles. Use `series-index.md` for source links.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- Mental model
|
||||
- Query keys
|
||||
- Query options and abstractions
|
||||
- Data transformation and selectors
|
||||
- Status, loading, and error UX
|
||||
- TypeScript and type safety
|
||||
- Mutations and invalidation
|
||||
- Optimistic updates
|
||||
- Forms
|
||||
- Router loaders and cache seeding
|
||||
- Infinite queries
|
||||
- Real-time and offline behavior
|
||||
- Testing
|
||||
- Review checklist
|
||||
|
||||
## Mental Model
|
||||
|
||||
- Treat React Query as an async state manager and data synchronization tool, not a normalized client database.
|
||||
- Keep server state and client state separate. Do not copy query data into local state unless you intentionally take a snapshot, such as initial form values.
|
||||
- Tune `staleTime` before reaching for manual refetching. Most freshness surprises are stale/fresh decisions, not cache lifetime decisions.
|
||||
- Rarely change `gcTime` unless memory pressure or cache retention behavior is the actual problem.
|
||||
- Prefer declarative data dependencies over imperative refetch chains.
|
||||
|
||||
## Query Keys
|
||||
|
||||
- Put every queryFn input in the query key. If a value changes the request, it belongs in the key.
|
||||
- Query keys should be arrays or structured objects that allow partial matching.
|
||||
- Do not reuse one key shape for finite and infinite queries. Infinite queries store pages and page params; finite queries store a different shape.
|
||||
- Colocate query keys and query options with the feature that owns the data access.
|
||||
- Use factories when multiple call sites need the same key/options or when invalidation depends on consistent prefixes.
|
||||
|
||||
```ts
|
||||
import { queryOptions } from '@tanstack/react-query'
|
||||
|
||||
type ProjectListInput = {
|
||||
workspaceId: string
|
||||
keyword?: string
|
||||
}
|
||||
|
||||
export const projectQueries = {
|
||||
all: () => ['projects'] as const,
|
||||
lists: () => [...projectQueries.all(), 'list'] as const,
|
||||
list: (input: ProjectListInput) =>
|
||||
queryOptions({
|
||||
queryKey: [...projectQueries.lists(), input] as const,
|
||||
queryFn: ({ signal }) => fetchProjects(input, { signal }),
|
||||
}),
|
||||
}
|
||||
```
|
||||
|
||||
## Query Options and Abstractions
|
||||
|
||||
- Prefer `queryOptions()` for reusable options. It preserves the relationship between key, queryFn, and result type.
|
||||
- Avoid broad wrapper hooks that accept most of `UseQueryOptions`; those abstractions often weaken inference and hide important behavior.
|
||||
- If a custom hook is useful, make it narrow and domain-specific.
|
||||
- Let call sites compose options that are truly local, such as `enabled`, `select`, or component-specific `staleTime`.
|
||||
- In reusable libraries, accept options only after deciding which fields are safe to override. Avoid exposing overrides that can break cache identity or fetch behavior.
|
||||
|
||||
```ts
|
||||
export const useProjectList = (input: ProjectListInput) => {
|
||||
return useQuery(projectQueries.list(input))
|
||||
}
|
||||
|
||||
export const useProjectNames = (input: ProjectListInput) => {
|
||||
return useQuery({
|
||||
...projectQueries.list(input),
|
||||
select: projects => projects.map(project => project.name),
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
## Data Transformation and Selectors
|
||||
|
||||
- Prefer backend/API transformation when it is the real contract shape.
|
||||
- Transform in the `queryFn` when every consumer should see the transformed data and devtools should show the transformed shape.
|
||||
- Use `select` for observer-specific projections and fine-grained subscriptions.
|
||||
- Keep `select` stable if it is expensive or if it is passed through abstractions. Extract named functions or memoize carefully.
|
||||
- Structural sharing helps avoid re-renders when data is equal by structure. Do not defeat it with unnecessary deep cloning.
|
||||
|
||||
## Status, Loading, and Error UX
|
||||
|
||||
- Distinguish first load from background refetch. `isPending` or lack of data usually means no usable result yet; `isFetching` can also mean background refresh.
|
||||
- Prefer rendering stale data with a subtle refresh indicator over replacing it with a spinner.
|
||||
- Check for available data before showing a hard error when background refetches can fail.
|
||||
- Use Error Boundaries for renderable query errors when a full fallback is appropriate.
|
||||
- Use global cache callbacks for cross-cutting notifications. Avoid duplicate toast logic at every observer.
|
||||
- Remember that callbacks tied to an observer may not run if the observer unmounts before the mutation settles.
|
||||
|
||||
## TypeScript and Type Safety
|
||||
|
||||
- Prefer inference from typed API functions. Type the fetcher response, not every `useQuery` generic.
|
||||
- Avoid "lying" angle brackets: specifying a generic does not validate runtime data.
|
||||
- Validate untrusted API responses in the queryFn when runtime shape matters, for example with a schema library.
|
||||
- Use narrowing from query state instead of destructuring in ways that lose correlation between `status`, `data`, and `error`.
|
||||
- With dependent queries, use `enabled` for runtime gating, but still make the queryFn type-safe for unavailable inputs.
|
||||
- Use `queryOptions()` so helpers like `getQueryData` can infer associated data types from the key where supported.
|
||||
|
||||
## Mutations and Invalidation
|
||||
|
||||
- Mutations are imperative server side effects. Queries are declarative subscriptions to server state.
|
||||
- Prefer invalidating related queries after successful mutations. It is simple and robust when the server owns final truth.
|
||||
- Await invalidation if the UI must stay pending until the refetch completes; otherwise let it happen in the background.
|
||||
- Use direct `setQueryData` when the mutation response is the authoritative new cached value.
|
||||
- Use global `MutationCache` callbacks when automatic invalidation should apply across the app.
|
||||
- Use `mutationKey` or `meta` to connect mutations to invalidation scopes.
|
||||
- Prefer `mutate` for UI event handlers. Use `mutateAsync` only when Promise composition is genuinely needed.
|
||||
- Pass mutation variables as a single object to keep room for growth.
|
||||
|
||||
```ts
|
||||
const updateProject = useMutation({
|
||||
mutationKey: ['projects', 'update'],
|
||||
mutationFn: (input: UpdateProjectInput) => api.updateProject(input),
|
||||
onSuccess: (project) => {
|
||||
queryClient.setQueryData(projectQueries.detail(project.id).queryKey, project)
|
||||
return queryClient.invalidateQueries({ queryKey: projectQueries.lists() })
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Optimistic Updates
|
||||
|
||||
- Use optimistic updates for interactions where latency would be visibly harmful.
|
||||
- Cancel in-flight queries that might overwrite the optimistic value.
|
||||
- Snapshot previous cache state and return it from `onMutate` for rollback.
|
||||
- Scope invalidation so concurrent optimistic mutations do not repeatedly overwrite each other.
|
||||
- Avoid optimistic updates when the client would need to reimplement complex server logic, permissions, filtering, ranking, or derived fields.
|
||||
|
||||
## Forms
|
||||
|
||||
- A form usually starts from server state but becomes client state once the user edits it.
|
||||
- The simple pattern is to load query data, initialize the form, and avoid background updates with an appropriate `staleTime`.
|
||||
- If collaborative or long-lived forms need background updates, derive displayed values from server data plus dirty client fields rather than copying the whole query result.
|
||||
- Disable double submits through mutation pending state.
|
||||
- After successful mutation, invalidate affected queries and reset form state deliberately.
|
||||
|
||||
## Router Loaders and Cache Seeding
|
||||
|
||||
- React Router loaders are good for fetching early; React Query is better as the cache and synchronization layer.
|
||||
- In loaders, prefer `getQueryData(...) ?? fetchQuery(...)` or `ensureQueryData(...)` so navigation can reuse cached data.
|
||||
- In actions, invalidate the same query scopes the mutation would invalidate.
|
||||
- Use cache seeding from list data to detail data when it avoids waterfalls and the list item is sufficient as initial detail data.
|
||||
- Prefer pull seeding (`initialData` from an existing cache entry) when the detail query can derive from an already cached list.
|
||||
- Prefer push seeding (`setQueryData` while fetching a list) only when you are comfortable writing multiple cache entries up front.
|
||||
|
||||
## Infinite Queries
|
||||
|
||||
- Infinite queries are one query with pages, not many independent page queries.
|
||||
- The key identifies the whole infinite list; page params are managed separately.
|
||||
- Refetching may need to replay pages to preserve cursor correctness.
|
||||
- Keep `getNextPageParam` and `initialPageParam` explicit.
|
||||
- Do not manually write page data unless you preserve `{ pages, pageParams }` shape.
|
||||
|
||||
## Real-Time and Offline Behavior
|
||||
|
||||
- For WebSockets, use messages as invalidation or partial cache update signals. Keep React Query as the cache owner.
|
||||
- Prefer invalidating entity/list scopes from events unless the event payload contains enough data for a safe direct update.
|
||||
- With push-driven updates, consider longer `staleTime` because the socket becomes the freshness trigger.
|
||||
- Understand network mode before building offline behavior: some queries should pause offline, while others can read from local persistence or service worker caches.
|
||||
|
||||
## Testing
|
||||
|
||||
- Use a fresh `QueryClient` per test to avoid cache leakage.
|
||||
- Wrap tested hooks/components in `QueryClientProvider`.
|
||||
- Turn retries off in tests unless retry behavior is under test.
|
||||
- Mock network at the boundary. MSW-style request mocks usually age better than mocking React Query itself.
|
||||
- Await query results through UI or hook state, not arbitrary timers.
|
||||
- Silence expected network errors in test output only when assertions cover the error path.
|
||||
|
||||
## Review Checklist
|
||||
|
||||
- Does every request input appear in the query key?
|
||||
- Are finite and infinite query keys distinct?
|
||||
- Is data kept in query cache instead of copied into local state without reason?
|
||||
- Are loading and background fetching states handled separately?
|
||||
- Are background errors displayed without destroying useful stale data?
|
||||
- Does the abstraction preserve inference and avoid broad `UseQueryOptions` plumbing?
|
||||
- Is invalidation scoped clearly after mutations?
|
||||
- Is optimistic logic simpler than the server logic it approximates?
|
||||
- Are tests isolated with a fresh `QueryClient` and retries disabled?
|
||||
161
.agents/skills/tkdodo-react-query/references/series-index.md
Normal file
161
.agents/skills/tkdodo-react-query/references/series-index.md
Normal file
@ -0,0 +1,161 @@
|
||||
# Practical React Query Series Index
|
||||
|
||||
Fetched and summarized on 2026-04-30 from TkDodo's blog index: <https://tkdodo.eu/blog/practical-react-query>. The source index listed 32 parts. This file is a paraphrased lookup guide with links; it intentionally does not mirror the copyrighted article bodies.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- Article lookup
|
||||
- Topic map
|
||||
- Source handling
|
||||
|
||||
## Article Lookup
|
||||
|
||||
1. [Practical React Query](https://tkdodo.eu/blog/practical-react-query)
|
||||
- Use for the core mental model: server state vs. client state, defaults, `staleTime` vs. `gcTime`, query keys as dependencies, `enabled`, and custom hooks.
|
||||
- Prefer React Query cache for server state, not as a local state store.
|
||||
|
||||
2. [React Query Data Transformations](https://tkdodo.eu/blog/react-query-data-transformations)
|
||||
- Use when deciding where to reshape API data: backend, `queryFn`, render, or `select`.
|
||||
- Pick the transformation layer based on whether every consumer or only one observer needs the shape.
|
||||
|
||||
3. [React Query Render Optimizations](https://tkdodo.eu/blog/react-query-render-optimizations)
|
||||
- Use for re-render concerns, tracked properties, `notifyOnChangeProps`, and structural sharing.
|
||||
- Optimize after identifying a real render problem; keep structural sharing intact.
|
||||
|
||||
4. [Status Checks in React Query](https://tkdodo.eu/blog/status-checks-in-react-query)
|
||||
- Use when reviewing `isPending`, `isLoading`, `isError`, `isFetching`, and background error UX.
|
||||
- Prefer showing existing data over replacing the screen with an error for a background failure.
|
||||
|
||||
5. [Testing React Query](https://tkdodo.eu/blog/testing-react-query)
|
||||
- Use for hook/component testing setup with `QueryClientProvider`, isolated clients, disabled retries, and awaited assertions.
|
||||
- Mock network calls rather than mocking React Query internals.
|
||||
|
||||
6. [React Query and TypeScript](https://tkdodo.eu/blog/react-query-and-type-script)
|
||||
- Use for generics, inference, error typing, dependent queries, optimistic updates, infinite query typing, and default query functions.
|
||||
- Prefer typed fetchers and inference over manual `useQuery` generic arguments.
|
||||
|
||||
7. [Using WebSockets with React Query](https://tkdodo.eu/blog/using-web-sockets-with-react-query)
|
||||
- Use when real-time messages should invalidate or update cached data.
|
||||
- Consider longer `staleTime` when server push becomes the freshness source.
|
||||
|
||||
8. [Effective React Query Keys](https://tkdodo.eu/blog/effective-react-query-keys)
|
||||
- Use for key structure, colocated key factories, array keys, cache identity, and invalidation scopes.
|
||||
- Never share keys between finite and infinite queries.
|
||||
|
||||
9. [Leveraging the Query Function Context](https://tkdodo.eu/blog/leveraging-the-query-function-context)
|
||||
- Use when query keys and query functions drift apart.
|
||||
- Read request variables from `QueryFunctionContext` where it improves type safety and keeps dependencies explicit.
|
||||
|
||||
10. [Placeholder and Initial Data in React Query](https://tkdodo.eu/blog/placeholder-and-initial-data-in-react-query)
|
||||
- Use when avoiding loading flashes with `placeholderData` or `initialData`.
|
||||
- Remember that initial data affects cache-level state, while placeholder data is observer-level.
|
||||
|
||||
11. [React Query as a State Manager](https://tkdodo.eu/blog/react-query-as-a-state-manager)
|
||||
- Use for explaining React Query as an async state manager and stale-while-revalidate tool.
|
||||
- Tune `staleTime` for the product's freshness expectations instead of forcing manual sync.
|
||||
|
||||
12. [React Query Error Handling](https://tkdodo.eu/blog/react-query-error-handling)
|
||||
- Use for Error Boundaries, global query cache callbacks, toast notifications, and error propagation.
|
||||
- Prefer global callbacks for cross-cutting notifications to avoid duplicate observer side effects.
|
||||
|
||||
13. [Mastering Mutations in React Query](https://tkdodo.eu/blog/mastering-mutations-in-react-query)
|
||||
- Use for mutation lifecycle, invalidation, direct updates, optimistic updates, `mutate` vs. `mutateAsync`, callback behavior, and mutation variables.
|
||||
- Prefer invalidation unless the mutation response is sufficient for a precise cache write.
|
||||
|
||||
14. [Offline React Query](https://tkdodo.eu/blog/offline-react-query)
|
||||
- Use for network mode decisions and offline semantics.
|
||||
- Decide whether a query requires the network, can run always, or should behave offline-first.
|
||||
|
||||
15. [React Query and Forms](https://tkdodo.eu/blog/react-query-and-forms)
|
||||
- Use when server state initializes editable form state.
|
||||
- Choose between snapshotting initial data and keeping background updates with derived dirty fields.
|
||||
|
||||
16. [React Query FAQs](https://tkdodo.eu/blog/react-query-fa-qs)
|
||||
- Use for common debugging questions: refetch parameters, loading states, updates not showing, unstable clients, fetch API errors, and queryFns not running.
|
||||
- Most cache-update bugs come from mismatched query keys or an unstable `QueryClient`.
|
||||
|
||||
17. [React Query meets React Router](https://tkdodo.eu/blog/react-query-meets-react-router)
|
||||
- Use when integrating loaders/actions with React Query.
|
||||
- Fetch early in loaders, cache through React Query, and invalidate in actions.
|
||||
|
||||
18. [Seeding the Query Cache](https://tkdodo.eu/blog/seeding-the-query-cache)
|
||||
- Use for avoiding fetch waterfalls, especially list-to-detail transitions and Suspense.
|
||||
- Seed detail queries from list data only when the list item is good enough as initial detail data.
|
||||
|
||||
19. [Inside React Query](https://tkdodo.eu/blog/inside-react-query)
|
||||
- Use for internal architecture: `QueryClient`, `QueryCache`, `Query`, `QueryObserver`, active and inactive queries.
|
||||
- Helpful when debugging observer behavior or cache lifecycle.
|
||||
|
||||
20. [Type-safe React Query](https://tkdodo.eu/blog/type-safe-react-query)
|
||||
- Use for the difference between having TypeScript annotations and validating real API data.
|
||||
- Add runtime validation in the queryFn when API trust is not enough.
|
||||
|
||||
21. [You Might Not Need React Query](https://tkdodo.eu/blog/you-might-not-need-react-query)
|
||||
- Use when deciding whether React Query is appropriate.
|
||||
- React Query is most useful for client-owned data synchronization concerns; route/framework data APIs can cover simpler cases.
|
||||
|
||||
22. [Thinking in React Query](https://tkdodo.eu/blog/thinking-in-react-query)
|
||||
- Use for a high-level mindset talk: declarative dependencies, freshness, cache ownership, and server-state thinking.
|
||||
- Useful when code is written as imperative fetch orchestration.
|
||||
|
||||
23. [React Query and React Context](https://tkdodo.eu/blog/react-query-and-react-context)
|
||||
- Use when Context is used to pass implicit query parameters or synchronize query data.
|
||||
- Prefer explicit dependencies; beware request waterfalls and hidden coupling.
|
||||
|
||||
24. [Why You Want React Query](https://tkdodo.eu/blog/why-you-want-react-query)
|
||||
- Use to justify a data-fetching library over hand-written effects.
|
||||
- Covers race conditions, loading/empty state handling, StrictMode double effects, cancellation, and error handling.
|
||||
|
||||
25. [The Query Options API](https://tkdodo.eu/blog/the-query-options-api)
|
||||
- Use for v5 `queryOptions`, type inference, data tags, and query factories.
|
||||
- Prefer options factories to preserve type links between keys, fetchers, and cached data.
|
||||
|
||||
26. [Automatic Query Invalidation after Mutations](https://tkdodo.eu/blog/automatic-query-invalidation-after-mutations)
|
||||
- Use for app-level invalidation with global mutation cache callbacks.
|
||||
- Scope automatic invalidation with `mutationKey`, `meta`, `staleTime`, and awaited vs. background invalidation choices.
|
||||
|
||||
27. [How Infinite Queries work](https://tkdodo.eu/blog/how-infinite-queries-work)
|
||||
- Use for infinite query internals, `QueryBehavior`, retry behavior, and page refetch architecture.
|
||||
- Preserve `{ pages, pageParams }` shape and cursor correctness.
|
||||
|
||||
28. [React Query API Design - Lessons Learned](https://tkdodo.eu/blog/react-query-api-design-lessons-learned)
|
||||
- Use for API design tradeoffs: overloads, object syntax, naming, DX, migration, and maintainability.
|
||||
- Useful when designing local abstractions over React Query.
|
||||
|
||||
29. [React Query - The Bad Parts](https://tkdodo.eu/blog/react-query-the-bad-parts)
|
||||
- Use for tradeoff analysis and cases where React Query can be too much.
|
||||
- Good review prompt for bundle cost, abstraction cost, mental-model complexity, and alternative framework data APIs.
|
||||
|
||||
30. [Concurrent Optimistic Updates in React Query](https://tkdodo.eu/blog/concurrent-optimistic-updates-in-react-query)
|
||||
- Use for race-resistant optimistic UI when multiple mutations affect the same cached entity or list.
|
||||
- Cancel conflicting queries and prevent over-invalidation windows.
|
||||
|
||||
31. [React Query Selectors, Supercharged](https://tkdodo.eu/blog/react-query-selectors-supercharged)
|
||||
- Use for `select`, fine-grained subscriptions, query hash behavior, memoization, and selector typing.
|
||||
- Stabilize expensive selectors and preserve result inference.
|
||||
|
||||
32. [Creating Query Abstractions](https://tkdodo.eu/blog/creating-query-abstractions)
|
||||
- Use for building reusable abstractions around inference-heavy APIs.
|
||||
- Prefer `queryOptions()` composition over passing broad `UseQueryOptions` through custom hooks.
|
||||
|
||||
## Topic Map
|
||||
|
||||
- Core mindset: 1, 11, 21, 22, 24, 29
|
||||
- Keys and query function inputs: 1, 8, 9, 16, 25
|
||||
- TypeScript and inference: 6, 20, 25, 31, 32
|
||||
- Data shape and render performance: 2, 3, 31
|
||||
- Loading, status, and errors: 4, 10, 12, 16
|
||||
- Mutations and invalidation: 13, 26, 30
|
||||
- Optimistic updates: 6, 13, 30
|
||||
- Forms: 15
|
||||
- Router integration and cache seeding: 17, 18, 23
|
||||
- Infinite queries: 6, 27
|
||||
- Real-time and offline: 7, 14
|
||||
- Testing: 5
|
||||
- Internals and API design: 19, 27, 28
|
||||
|
||||
## Source Handling
|
||||
|
||||
- Link to the original article when adding durable rationale to project docs or comments.
|
||||
- Quote at most a short phrase if needed; otherwise paraphrase.
|
||||
- Re-check the source index if the user asks for the latest series contents.
|
||||
Loading…
Reference in New Issue
Block a user