Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ architecture for code in the browser. The key libraries are:

- Model - GraphQL
- View - [React](https://reactjs.org/)
- Controller - [React Easy State](https://github.com/RisingStack/react-easy-state)
- Controller - [The Observer Utility](https://github.com/nx-js/observer-util), the underlying library powering [React Easy State](https://github.com/RisingStack/react-easy-state)

## Example

Expand All @@ -18,7 +18,7 @@ yarn
yarn demo
```

To run with react in production mode
To run with React in production mode

```
yarn demo:production
Expand Down Expand Up @@ -46,15 +46,15 @@ There should be one "right" way code pattern so that developers don't have to th

#### Simple state management that just works

Managing state for frameworks like Redux that require immutability for performance places a lot of burden on the developer. Updating immutable structures is more complex. State management should be simple, and not require any more knowledge or methods than vanilla Javascript. This is provided through the magic of [React Easy State](https://github.com/RisingStack/react-easy-state).
Managing state for frameworks like Redux that require immutability for performance places a lot of burden on the developer. Updating immutable structures is more complex. State management should be simple, and not require any more knowledge or methods than vanilla Javascript. This is provided through the magic of [The Observer Utility](https://github.com/nx-js/observer-util).

#### Explicit model classes

Using plain old javascript objects to represent state models is error prone, and makes it hard to discover what methods can operate on which objects. Typescipt is only solution to this problem, but we believe that explicit model classes with object oriented encapsulation provides a more productive solution when the objective is to create functionality as efficiently as possible. Apollo GraphQL is included as the recommended way to achieve this, but is not strictly necessary and all of the controller benefits can be achieved with a different model implementation.
Using plain old javascript objects to represent state models is error prone, and makes it hard to discover what methods can operate on which objects. Typescipt is one solution to this problem, but we believe that explicit model classes with object oriented encapsulation provides a more productive solution when the objective is to create functionality as efficiently as possible. Apollo GraphQL is included as the recommended way to achieve this, but is not strictly necessary and all of the controller benefits can be achieved with a different model implementation.

#### Optimal React re-rendering without developer overhead

Avoiding re-rendering is critical for good React performance. In most cases the developer should not need to write explicit memoization code, or use immutable state, to get this performance. In fact if the framework handles re-render automatically it is likely to give better performance than alternatives where the developer must do it explicitly. This is also provided automatically by React Easy State.
Avoiding re-rendering is critical for good React performance. In most cases the developer should not need to write explicit memoization code, or use immutable state, to get this performance. In fact if the framework handles re-render automatically it is likely to give better performance than alternatives where the developer must do it explicitly. This is implemented similarly to [MobX](https://mobx.js.org/README.html), supporting React 18 and up.

#### Proportionality

Expand All @@ -64,4 +64,4 @@ The framework should be lightweight enough to be attractive to use for very simp

## Licensing

mvc is [MIT licensed](./LICENSE) and is Copyright 2020-2023 Aha! Labs Inc.
mvc is [MIT licensed](./LICENSE) and is Copyright 2020-2025 Aha! Labs Inc.
1 change: 0 additions & 1 deletion config/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ build({
external: [
'react',
'react-dom',
'@aha-app/react-easy-state',
'@nx-js/observer-util',
'debug',
'lodash',
Expand Down
4 changes: 2 additions & 2 deletions demo/counter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ const Counter = () => {
<h1>Simple counter</h1>
<p className='count'>{count}</p>
<p>
<button onClick={() => controller.actionIncrement()}>+</button>
<button onClick={() => controller.actionDecrement()}>-</button>
<button type="button" onClick={() => controller.actionIncrement()}>+</button>
<button type="button" onClick={() => controller.actionDecrement()}>-</button>
</p>
</div>
);
Expand Down
5 changes: 0 additions & 5 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ export default {
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
tsconfig: {
jsx: 'react',
},
},
],
},
};
18 changes: 10 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aha-app/mvc",
"version": "0.13.0",
"version": "0.15.0-beta-20250609",
"description": "Simple MVC framework using React for the view and GraphQL for the models.",
"main": "dist/index.js",
"type": "module",
Expand All @@ -23,29 +23,31 @@
"license": "UNLICENSED",
"homepage": "https://github.com/aha-app/mvc#readme",
"dependencies": {
"@aha-app/react-easy-state": "^0.0.12-development",
"@nx-js/observer-util": "^4.2.2",
"debug": "^4.1.0",
"lodash": "^4.17.21 || npm:lodash-es@^4.17.21"
},
"peerDependencies": {
"react": "^16.8.4",
"react-dom": "^16.8.4"
"react": "^18.3.1 || ^19.0.0",
"react-dom": "^18.3.1 || ^19.0.0"
},
"devDependencies": {
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.2.0",
"@testing-library/react": "^14.1.2",
"@testing-library/react": "^16.3.0",
"@testing-library/react-render-stream": "^2.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/debug": "^4.1.12",
"@types/jest": "^29.5.11",
"@types/lodash": "^4.14.202",
"@types/react": "^18.2.48",
"@types/react": "^18.3.12",
"esbuild": "^0.19.11",
"esbuild-plugin-d.ts": "^1.1.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"prettier": "^3.2.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"rimraf": "^5.0.0",
"ts-jest": "^29.1.1",
"typescript": "^5.0.4"
Expand Down
Loading