Refactor Firestore CRUD to use Effect atoms and React hooks#45
Conversation
Introduce REACT.md and reference implementation in example/app for using effect-firebase repositories from React: a RuntimeProvider that binds a Firestore Layer to a ManagedRuntime, plus useEffectQuery, useEffectStream, and useEffectMutation hooks that surface a Result- shaped state and handle fiber cleanup. Refactor the /firestore route to use the hooks together with @tanstack/react-form and effect/Schema (via toStandardSchemaV1) for validated CRUD. Add a Vitest setup with @testing-library/react and a demo test that swaps in @effect-firebase/mock at the provider boundary. The hook surface intentionally mirrors @effect-atom/atom-react idioms so a future migration is mechanical once atom-react supports Effect v4. Also remove a duplicate deleteRecursive key in the mock service that blocked the package build. https://claude.ai/code/session_01R1D97BwwWVdGzARJY8iWeB
Replace the hand-rolled RuntimeProvider + useEffectQuery/Stream/Mutation
hooks with the upstream Effect-TS React binding now that
@effect/atom-react has shipped for Effect v4.
Repository operations live in example/app/src/lib/atoms.ts as atoms
keyed by a swappable firestoreLayerAtom: postByIdAtom, postByIdLiveAtom,
latestPostsAtom, and addPost/updatePost/deletePostAtom mutations. The
firestore route reads via useAtomValue + AsyncResult.builder and writes
via useAtomSet({ mode: 'promise' }). RegistryProvider replaces the
custom provider; tests swap the layer via initialValues. REACT.md is
rewritten to document the atom-based patterns.
https://claude.ai/code/session_01R1D97BwwWVdGzARJY8iWeB
|
View your CI Pipeline Execution ↗ for commit 30d85ef
☁️ Nx Cloud last updated this comment at |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Refactored the Firestore CRUD example to use
@effect/atom-reactfor state management and reactive data fetching, replacing manual Effect/Stream management with declarative atom-based patterns. This demonstrates production-ready patterns for integrating Effect-TS repositories with React.Key Changes
Atom-based architecture: Introduced
atoms.tswith repository atoms for reads (latestPostsAtom,postByIdAtom) and mutations (addPostAtom,updatePostAtom,deletePostAtom), enabling shared subscriptions and automatic cleanup.Runtime setup: Created a
firestoreLayerAtomindirection layer that makes the Firestore service swappable at the registry boundary, enabling seamless testing with mock layers without changing component code.Component refactoring:
PostFormcomponent using@tanstack/react-formwith Effect Schema validationPostListcomponent usingAsyncResult.builderfor exhaustive state handlingRouteComponentto coordinate form and list stateApp-level integration: Wrapped the app in
RegistryProviderwith memoized layer initialization to ensure stable runtime identity across renders.Testing support: Added
MockFirestoreServiceintegration and example test demonstrating how to override the layer atom for unit tests without modifying components.Documentation: Added comprehensive
REACT.mdguide covering runtime setup, repository atoms, reading data, mutations, form validation, and testing patterns.Notable Implementation Details
Atom.family) memoize atoms by argument, ensuring multiple components subscribed to the same resource share a single Firestore subscription.clientRuntime.atom(effect)andclientRuntime.atom(stream)automatically wrap results inAsyncResult<A, E>for consistent loading/success/failure handling.useAtomSet(atom, { mode: 'promise' })enables fire-and-forget or promise-based mutations with automatic state tracking.editing?.idensures fresh defaults load when switching between create and edit modes.https://claude.ai/code/session_01R1D97BwwWVdGzARJY8iWeB