@triggery/codemod
Codemods that mechanically migrate React / Redux side-effect code to Triggery’s event → conditions → actions model. Powered by ts-morph so the output is real TypeScript — JSX, types, and imports preserved.
Install
Section titled “Install”pnpm add -D @triggery/codemod npm install --save-dev @triggery/codemod yarn add --save-dev @triggery/codemod bun add -D @triggery/codemod What’s inside
Section titled “What’s inside”| Command / Export | Purpose |
|---|---|
triggery-codemod extract-trigger --name <event> <file> | Pull a useEffect(() => { ... }, []) block out of a component into a sibling <name>.trigger.ts. |
triggery-codemod migrate-from-listener-middleware <file> | Generate one trigger per RTK startListening({ actionCreator, effect }) call. |
extractTrigger, migrateFromListenerMiddleware | Programmatic API for the two codemods. |
Add --dry-run to preview without writing.
Quick example
Section titled “Quick example”# Pull a useEffect block out of a component into a *.trigger.ts file.
npx triggery-codemod extract-trigger --name new-message src/Chat.tsx
# Generate one trigger per RTK listenerMiddleware effect.
npx triggery-codemod migrate-from-listener-middleware src/store/middleware.tsProgrammatic API:
import { extractTrigger, migrateFromListenerMiddleware } from '@triggery/codemod';
extractTrigger({ file: 'src/Chat.tsx', name: 'new-message' });
migrateFromListenerMiddleware({ file: 'src/store/middleware.ts' });What each codemod does
Section titled “What each codemod does”extract-trigger
Section titled “extract-trigger”Reads the first useEffect(() => { ... }, []) in the file and writes a sibling <name>.trigger.ts containing a stub createTrigger({...}). The component is rewritten to call useEvent(<name>Trigger, '<event-name>') instead.
The codemod intentionally does not:
- Infer the
events/conditions/actionsschema generic — you write it. - Move closure-captured state into typed conditions — refactor by hand.
- Touch cleanup functions or effects with conditional deps — handle manually.
migrate-from-listener-middleware
Section titled “migrate-from-listener-middleware”For each startListening({ actionCreator, effect }) call in the file, generates one <event-name>.trigger.ts. The effect body is dropped verbatim into the new trigger’s handler with a // TODO: refactor dispatch/getState into actions/conditions marker.
Other listenerMiddleware shapes (matcher, predicate, type) are detected but skipped — they need human review.