-
-
Notifications
You must be signed in to change notification settings - Fork 6
Add react implementation of state management #124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: ui-controller
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a React adapter for the @ethnolib/state-management-core library, enabling React applications to use the framework-agnostic state management system. The implementation follows the pattern established by the existing Svelte adapter, providing a useField hook that binds Field objects to React state.
Key Changes
- Created new
@ethnolib/state-management-reactpackage with theuseFieldhook - Added build configuration (Vite, TypeScript, Vitest) following the existing pattern
- Included comprehensive README documentation explaining usage patterns
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| package-lock.json | Added dependencies for the new React state management package and updated Svelte package references |
| components/state-management/state-management-react/package.json | Package manifest defining the React adapter with build scripts and dev dependencies |
| components/state-management/state-management-react/index.ts | Main entry point exporting the useField hook |
| components/state-management/state-management-react/src/use-field.ts | Core implementation of the React hook for binding Field objects to React state |
| components/state-management/state-management-react/vite.config.ts | Vite build configuration for library mode |
| components/state-management/state-management-react/vitest.config.ts | Vitest test configuration |
| components/state-management/state-management-react/tsconfig.json | Base TypeScript configuration with React JSX support |
| components/state-management/state-management-react/tsconfig.lib.json | Library-specific TypeScript configuration for build output |
| components/state-management/state-management-react/README.md | Documentation explaining the state management system and usage patterns |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "@vitejs/plugin-react-swc": "^3.8.0", | ||
| "tsx": "^4.19.2", | ||
| "typescript": "^5.2.2" | ||
| }, |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing peerDependencies for "react" (and optionally "react-dom"). Since this package is a React adapter that imports from "react", it should declare React as a peer dependency to ensure consumers have it installed. Consider adding:
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0"
}| }, | |
| }, | |
| "peerDependencies": { | |
| "react": "^17.0.0 || ^18.0.0" | |
| }, |
| _setFieldValue(value); | ||
| } | ||
|
|
||
| field.updateUI = (value) => _setFieldValue(value); |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field.updateUI assignment on every render can cause issues. If the component re-renders (e.g., due to parent state changes), this assignment will overwrite the callback, potentially breaking synchronization. Consider using useEffect to set this up once:
useEffect(() => {
field.updateUI = (value) => _setFieldValue(value);
return () => {
field.updateUI = null; // cleanup
};
}, [field]);| export function useField<T>(field: Field<T>): [T, (value: T) => void] { | ||
| const [fieldValue, _setFieldValue] = useState(field.value); | ||
|
|
||
| function setFieldValue(value: T) { | ||
| field.requestUpdate(value); | ||
| _setFieldValue(value); | ||
| } | ||
|
|
||
| field.updateUI = (value) => _setFieldValue(value); | ||
|
|
||
| return [fieldValue, setFieldValue]; | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The useField hook lacks test coverage. The sibling package state-management-svelte has tests (e.g., transform-view-model.test.ts) for similar functionality. Consider adding tests to verify:
- Initial state matches field value
- Updates through setFieldValue call field.requestUpdate
- Updates through field.updateUI update React state
- Cleanup of field.updateUI on unmount
| @@ -0,0 +1,108 @@ | |||
| # State Management Core | |||
|
|
|||
| This package provides a simple interface for working with multiple reactive framworks. | |||
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "framworks" should be "frameworks"
| This package provides a simple interface for working with multiple reactive framworks. | |
| This package provides a simple interface for working with multiple reactive frameworks. |
| const person = usePersonViewModel(); | ||
|
|
||
| // Replace `defineReactiveState` with your framework's mechanism | ||
| const reactiveName = defineReactiveSate(); |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "defineReactiveSate" should be "defineReactiveState"
| const reactiveName = defineReactiveSate(); | |
| const reactiveName = defineReactiveState(); |
| export default defineConfig({ | ||
| root: __dirname, | ||
| cacheDir: | ||
| "../../../node_modules/.vite/components/state-management/state-management-core", |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cacheDir path references "state-management-core" but should reference "state-management-react" to match the actual package being built.
| "../../../node_modules/.vite/components/state-management/state-management-core", | |
| "../../../node_modules/.vite/components/state-management/state-management-react", |
| }, | ||
| lib: { | ||
| entry: "./index.ts", | ||
| name: "@ethnolib/find-language", |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The library name is incorrectly set to "@ethnolib/find-language". It should be "@ethnolib/state-management-react" to match the package name.
| name: "@ethnolib/find-language", | |
| name: "@ethnolib/state-management-react", |
| "declarationMap": true | ||
| }, | ||
| "exclude": [ | ||
| "langtagProcessing.ts", |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exclude pattern references "langtagProcessing.ts" which doesn't exist in this package. This appears to be a leftover from a template and should be removed.
| "langtagProcessing.ts", |
This change is