Skip to content

Commit a69bce6

Browse files
committed
chore: progressive AGENTS.md disclosure
1 parent f03d1be commit a69bce6

File tree

7 files changed

+930
-290
lines changed

7 files changed

+930
-290
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Adapter Development
2+
3+
Guide for adding framework adapters to nuqs.
4+
5+
## Overview
6+
7+
Adapters wrap the app root and provide the minimal translation layer between nuqs and framework routing APIs.
8+
9+
- **Next.js app router:** `nuqs/adapters/next/app`
10+
- **Next.js pages router:** `nuqs/adapters/next/pages`
11+
- **React SPA:** `nuqs/adapters/react`
12+
- **Remix:** `nuqs/adapters/remix`
13+
- **React Router v6:** `nuqs/adapters/react-router/v6`
14+
- **React Router v7:** `nuqs/adapters/react-router/v7`
15+
- **TanStack Router:** `nuqs/adapters/tanstack-router`
16+
- **Testing:** `nuqs/adapters/testing`
17+
18+
## Adding a New Framework Adapter
19+
20+
### Checklist
21+
22+
1. **Mirror existing adapter API surface**
23+
- Ensure the exported provider component matches established patterns
24+
- Use consistent naming and parameter shapes
25+
26+
2. **Implement minimal feature parity**
27+
- Read/query: Parse current search params
28+
- Push/replace history: Update URL without full reload
29+
- Batching: Support merging multiple updates per tick
30+
31+
3. **Create e2e bench**
32+
- Add test application under `packages/e2e/<framework>`
33+
- Cover both App Router and Pages Router if applicable
34+
35+
4. **Documentation**
36+
- Update README Adapters section
37+
- Add docs content page explaining adapter setup
38+
39+
5. **Test coverage**
40+
- Unit tests for adapter integration
41+
- E2E tests for framework-specific behaviors
42+
43+
### Key Requirements
44+
45+
- Adapter must support `shallow` option semantics (when applicable to framework)
46+
- Handle history `push` vs `replace` operations correctly
47+
- Ensure batch queue integrity (updates per key merged while preserving final state)
48+
- No memory leaks (listeners removed on unmount)
49+
50+
### Server-Side Utilities
51+
52+
When adding adapter support, consider server utilities:
53+
54+
- **Loader:** `createLoader(parsers[, { urlKeys }])` for one-off parsing
55+
- **Cache:** `createSearchParamsCache(parsers)` for nested Server Components (Next.js app router)
56+
- **Serializer:** `createSerializer(parsers[, { urlKeys }])` for canonical URLs / links
57+
- Import server helpers from `'nuqs/server'` (avoids the `"use client"` directive)
58+
59+
These should work identically across adapters where applicable.
60+
61+
## Options Semantics
62+
63+
When implementing adapter support:
64+
65+
- **`history`:** `'replace'` (default) or `'push'`
66+
- **`shallow`** (Next.js only): Default true (client-first). Set false to trigger RSC / SSR invalidation
67+
- **`throttleMs`:** ≥50ms (ignored if lower). Only URL & server notification are throttled, not in-memory state
68+
- **`startTransition`:** Pass from `React.useTransition` when using `shallow: false` for loading states
69+
70+
Override per-update via second argument to setter: `setValue(v, { history, shallow, throttleMs })`
71+
72+
## Architectural Flow
73+
74+
1. Hook reads initial value from current `window.location.search`
75+
2. Local React state mirrors parsed value
76+
3. Setter enqueues mutation intent (key → serialized value | delete)
77+
4. Batch flush (throttled) applies merged changes to History API (push/replace)
78+
5. Promise resolves with updated `URLSearchParams`
79+
6. If `shallow: false`: uses router APIs to trigger server-side rendering / data fetching
80+
81+
## Extensibility
82+
83+
- Prefer composition (wrapping adapter) over modifying core adapter
84+
- Keep adapter interfaces thin (translate framework navigation to common history operations)
85+
- Avoid duplicating logic across adapters (prefer shared utility)

.agents/docs/api-design.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# API Design & Architecture
2+
3+
Guide for maintaining API stability, designing extensions, and understanding the architecture.
4+
5+
## Core Architecture
6+
7+
### Flow
8+
9+
1. **Initialization:** Hook reads initial value from current `window.location.search`
10+
2. **Local State:** React state mirrors parsed value
11+
3. **Mutation Enqueue:** Setter enqueues mutation intent (key → serialized value | delete)
12+
4. **Batch & Throttle:** Multiple `setState` calls in one tick are merged
13+
5. **Flush to URL:** Batch flush (throttled ≥50ms) applies merged changes to History API (push/replace)
14+
6. **Promise Resolution:** Returns when URL update flushes; cache per batch
15+
7. **Server Trigger:** If `shallow: false`, uses router APIs to trigger server-side rendering / data fetching
16+
17+
### Batch Queue Integrity
18+
19+
- **Key merging:** Updates for the same key within one tick are coalesced (final state wins)
20+
- **Final value preservation:** Last write for each key determines the output
21+
- **No reordering:** Order of keys in URL is stable
22+
23+
## Design Principles
24+
25+
### 1. URL as Single Source of Truth
26+
27+
- URL shape defines state shape
28+
- Parsing must be deterministic
29+
- Serialization must be lossless
30+
31+
### 2. Type Safety
32+
33+
- Hooks return typed values matching parser output
34+
- Builder chaining preserves types
35+
- Type exports are part of public API
36+
37+
### 3. Zero Dependencies & Bundle Size
38+
39+
- No external dependencies
40+
- Avoid side effects in module top-level (affects tree shaking)
41+
- Keep parse/serialize fast and lightweight
42+
- Throwing in parsers has bundle cost (return `null` instead)
43+
44+
### 4. Backward Compatibility
45+
46+
Before modifying core logic in `packages/nuqs`:
47+
48+
1. **Assess API surface impact**
49+
- Type exports
50+
- Builder chaining
51+
- Hook signatures
52+
53+
2. **Maintain backward compatibility** unless intentional breaking change
54+
- Breaking changes require justification
55+
- Provide migration notes in PR body
56+
57+
3. **Validate types** with `pnpm test --filter nuqs` (includes TS type tests)
58+
59+
## Performance & Reliability
60+
61+
### Batch Efficiency
62+
63+
- Merging updates per key while preserving final state
64+
- Single URL write per flush cycle
65+
- No synchronous expensive operations inside parse/serialize
66+
67+
### Memory Management
68+
69+
- Ensure no memory leaks
70+
- Remove listeners on unmount
71+
- Clear event handler references
72+
73+
### URL Determinism
74+
75+
- Keep serialization deterministic
76+
- Use stable ordering for multiple keys
77+
- Consistent formatting
78+
79+
## Extensibility Guidelines
80+
81+
When extending nuqs:
82+
83+
### Composition Over Modification
84+
85+
- Prefer wrapping parsers over modifying core hook
86+
- Create adapters for new frameworks instead of baking support in core
87+
- Use builder pattern for optional behaviors
88+
89+
### Code Organization
90+
91+
- Add generic utilities under internal helpers module if reused ≥2 places
92+
- Keep adapter interfaces thin
93+
- Translate framework navigation to common history operations
94+
95+
### Builder Pattern
96+
97+
- Use `.withDefault()` for defaults
98+
- Use `.withOptions()` for behavior customization
99+
- Keep chaining lightweight
100+
101+
## Safety Checklist for Core Changes
102+
103+
Do not:
104+
105+
- Introduce side effects in module top-level (tree shaking impact)
106+
- Use non-standard browser APIs without guards
107+
- Increase bundle size significantly (maintain zero dependencies)
108+
- Export internal implementation details
109+
- Break existing type signatures
110+
111+
Do:
112+
113+
- Test types with type-level tests (`.test-d.ts`)
114+
- Provide type exports alongside implementation
115+
- Document API changes in README
116+
- Validate with full test suite

.agents/docs/git-workflow.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Release & Git Workflow
2+
3+
Guide for versioning, commits, pull requests, and release process.
4+
5+
## Conventional Commits
6+
7+
All commits follow the Conventional Commits specification. This is enforced by review.
8+
9+
### Format
10+
11+
```
12+
<type>(<scope>): <subject>
13+
14+
<body>
15+
16+
<footer>
17+
```
18+
19+
### Commit Types
20+
21+
- **`feat:`** New feature
22+
- **`fix:`** Bug fix
23+
- **`perf:`** Performance improvement
24+
- **`docs:`** Documentation only
25+
- **`refactor:`** Code restructuring (no feature change)
26+
- **`test:`** Test addition or update
27+
- **`chore:`** Tooling, dependencies, config
28+
29+
### Breaking Changes
30+
31+
For breaking changes:
32+
33+
1. Use `feat!:` or `fix!:` prefix
34+
2. Add footer: `BREAKING CHANGE: <description>`
35+
36+
Example:
37+
38+
```
39+
feat!: change parser return type
40+
41+
BREAKING CHANGE: parseAsInteger now throws on invalid input instead of returning null
42+
```
43+
44+
## Semantic Versioning
45+
46+
Version bumping is **automated by `semantic-release`**:
47+
48+
- **Patch** (v1.2.3 → v1.2.4) — `fix:` commits
49+
- **Minor** (v1.2.0 → v1.3.0) — `feat:` commits
50+
- **Major** (v1.0.0 → v2.0.0) — `feat!:` or `fix!:` (breaking changes)
51+
52+
**Do not manually bump versions** — The automation handles this.
53+
54+
## Release Branch
55+
56+
- **Release branch:** `next`
57+
- Commits to `next` trigger `semantic-release`
58+
- Publishing to NPM is automatic
59+
- Check [GitHub Releases](../../releases) for version history
60+
61+
## Pull Request Standards
62+
63+
### Before Opening a PR
64+
65+
1. Ensure commit messages follow Conventional Commits
66+
2. Run local tests: `pnpm test`
67+
3. Verify types with type-level tests
68+
4. Update documentation if applicable
69+
5. Consider if breaking change justification is needed
70+
71+
### PR Description
72+
73+
Include:
74+
75+
- **Summary** — What is this PR doing and why?
76+
- **Type** — Is this a feature, fix, refactor, or doc update?
77+
- **Changes** — High-level list of modified areas
78+
- **Testing** — What test coverage was added?
79+
- **Breaking Changes** — If applicable, describe migration path
80+
81+
### PR Title
82+
83+
PR title should match the first commit message (Conventional Commit format):
84+
85+
- `feat: add new parser type`
86+
- `fix: handle edge case in batching`
87+
- `docs: update adapter setup guide`
88+
89+
### PR Checklist
90+
91+
Before marking ready for review:
92+
93+
- [ ] `pnpm test` passes locally
94+
- [ ] Tests added/updated for new behavior
95+
- [ ] All new exports documented
96+
- [ ] Docs content updated if applicable
97+
- [ ] README updated if user-facing change
98+
- [ ] No unintended bundle size growth
99+
- [ ] Conventional Commit message
100+
- [ ] No unresolved TODOs introduced
101+
- [ ] No stray console logs (except controlled debug)
102+
103+
## Documentation Updates
104+
105+
Update documentation when:
106+
107+
- **Public API surface changes** (new exports, hook signature)
108+
- **Parser behavior changes** (parsing rules, serialization)
109+
- **Adapter requirements change** (new options, breaking changes)
110+
111+
### What to Update
112+
113+
1. **README.md**
114+
- Examples section
115+
- API reference
116+
- Adapter list
117+
118+
2. **MDX docs** under `packages/docs/content`
119+
- Mirror relevant README sections
120+
- Add detailed examples
121+
- Document configuration options
122+
123+
### Documentation Best Practices
124+
125+
- Keep examples concise
126+
- Link to existing demos instead of duplicating code
127+
- Maintain consistency with existing documentation style
128+
- Add examples that show common use cases
129+
- Update table of contents if adding new sections
130+
131+
## Decision Log
132+
133+
When making non-trivial architectural changes:
134+
135+
1. Add a short note to AGENTS.md Decision Log section
136+
2. Format: `YYYY-MM-DD - <Title> - Rationale / Impact / Migration (if any)`
137+
3. Examples:
138+
- `2025-01-15 - Add batching optimization - Reduces URL updates by 40% when multiple state changes occur in same tick. No migration needed.`
139+
- `2025-01-20 - Parser requires eq method - Enables custom equality checks for complex types. Existing parsers automatically compatible.`
140+
141+
## Automation & Tools
142+
143+
The team uses the following automation:
144+
145+
- **Conventional Commits:** Enforced by commit linting
146+
- **Type checking:** Part of `pnpm test`
147+
- **semantic-release:** Automatic versioning and publishing from `next` branch
148+
- **PR checks:** Linting, testing, type checking run automatically
149+
150+
**Agents may:**
151+
152+
- Generate parser boilerplate
153+
- Update Adapters section in documentation
154+
- Append PR checklist results
155+
- Run local tests & lint before proposing changes
156+
157+
**Agents must not:**
158+
159+
- Auto-commit version bumps (handled by release automation)
160+
- Force push to main/master
161+
- Modify git configuration
162+
- Skip git hooks

0 commit comments

Comments
 (0)