|
| 1 | +--- |
| 2 | +name: qwik |
| 3 | +description: Workflow and pitfall checklist for Qwik core development (packages/qwik). Use when the user mentions Qwik, packages/qwik, Signal/AsyncSignalImpl, reactive-primitives, serialization/hydration (serialize/inflate), or cursor queue; it enforces running unit tests immediately after any implementation change, following signal/async-signal patterns, and running build/E2E/API validations before finishing. |
| 4 | +--- |
| 5 | + |
| 6 | +# Qwik Core Development Guide (Skill) |
| 7 | + |
| 8 | +## Scope |
| 9 | +- Only for the Qwik core package: `packages/qwik` (especially `src/core/**`, `reactive-primitives/**`). |
| 10 | + |
| 11 | +## Mandatory workflow (must do) |
| 12 | +### 0. Run tests immediately after any implementation change |
| 13 | +- After changing any implementation file, **immediately** run the relevant unit tests (don’t wait for CI, don’t wait to be asked): |
| 14 | + |
| 15 | +```bash |
| 16 | +pnpm vitest run <test-file-path> |
| 17 | +``` |
| 18 | + |
| 19 | +- Typical example (signals): |
| 20 | + |
| 21 | +```bash |
| 22 | +pnpm vitest run packages/qwik/src/core/reactive-primitives/impl/signal.unit.tsx |
| 23 | +``` |
| 24 | + |
| 25 | +- If tests fail, fix and re-run until they pass. Only then proceed with anything else (docs/refactors/cleanup). |
| 26 | + |
| 27 | +## Implementation essentials (high-signal rules) |
| 28 | +- **Constructor parameter plumbing**: when adding params to signal/async-signal constructors, keep parent calls and parameter order stable; extract options in factories (e.g. `signal-api.ts`) before passing into constructors. |
| 29 | +- **AsyncSignal promise branches**: `.then()` and `.catch()` must be symmetric (same side-effects / scheduling). Errors should not “stop” polling. |
| 30 | +- **invalidate cleanup order**: clear timeouts/resources first, then clear cached data and call `super.invalidate()` to avoid leaks and test interference. |
| 31 | +- **SSR vs browser**: guard browser APIs (`setTimeout`, etc.) with `isBrowser`; still persist configuration on the instance for hydration. |
| 32 | +- **Subscriber checks**: async signals may have separate subscribers for `.value`, `.loading`, and `.error`; any “has subscribers” logic must consider all three sets. |
| 33 | +- **Serialization/hydration alignment**: when adding new serializable fields, array positions in `serialize.ts` and `inflate.ts` must match exactly. |
| 34 | + |
| 35 | +## Testing conventions (high-signal rules) |
| 36 | +- Prefer `$()` for QRLs; avoid manually constructing QRLs (e.g. `inlinedQrl()`). |
| 37 | +- In `$()` tests that need mutable state, use object refs (e.g. `{ count: 0 }`). Don’t capture and mutate outer-scope primitives (can trigger “Assignment to constant variable”). |
| 38 | +- First computation may “throw a promise” to trigger suspense behavior; in tests, use helpers like `retryOnPromise()` / `withContainer()` around first reads/creation. |
| 39 | + |
| 40 | +## Required validations before finishing |
| 41 | +When the task is complete / ready to ship (especially core changes), run as appropriate: |
| 42 | + |
| 43 | +```bash |
| 44 | +pnpm build --qwik --qwikrouter --dev |
| 45 | +pnpm run test.e2e.chromium |
| 46 | +pnpm api.update |
| 47 | +``` |
| 48 | + |
| 49 | +## Detailed reference |
| 50 | +- For deeper patterns, examples, pitfall tables, and full checklists, read `[AGENTS.md](AGENTS.md)` in the same folder. |
| 51 | + |
0 commit comments