diff options
Diffstat (limited to 'js/seed/README.md')
-rw-r--r-- | js/seed/README.md | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/js/seed/README.md b/js/seed/README.md new file mode 100644 index 0000000..8159cb3 --- /dev/null +++ b/js/seed/README.md @@ -0,0 +1,91 @@ +# Seed: Minimal FRP/TEA Web App Starter Kit + +This is an opinionated, minimal starting point for browser-native web apps using a functional, Elm-style architecture (FRP/TEA) and only browser APIs. No frameworks, no build step, just ES modules. + +## Architecture +- **state.js**: App state definition and helpers +- **update.js**: Pure update function (handles actions/messages) +- **view.js**: Pure view functions (renders HTML as string) +- **api.js**: API fetch logic +- **app.js**: Entrypoint, main loop, event delegation + +## Pattern +- **State**: Single immutable state object +- **Update**: Pure function `(state, action) => newState` +- **View**: Pure function `(state) => html` +- **Entrypoint**: Handles events, dispatches actions, triggers re-render + +## Why? +- Simple, testable, and maintainable +- No dependencies +- Encourages functional, declarative code + +## How to Extend and Use This Template + +This template is designed to be a flexible, opinionated starting point for any browser-native app. + +### Key Files to Extend +- **src/state.js**: Define the app's state shape and any helper functions for cloning or initializing state. +- **src/update.js**: Add new action/message types and update logic. This is where you handle all state transitions. +- **src/view.js**: Build your UI as a pure function of state. Add new components or views here. +- **src/api.js**: Add or replace API calls as needed for your app's data fetching. +- **src/app.js**: Wire up events, use the generalized `render` function, and add any app-specific logic (e.g., focus management, custom event handling). + +### Using the Generalized `render` Function +The `render` function in `app.js` is designed to be reusable for any app. It takes a config object: + +```js +render({ + root, // DOM element to render into + state, // Current app state + view, // View function: (state) => html + events: [ // Array of event bindings + { selector, event, handler }, + // ... + ], + postRender // Optional: function({ root, state }) for custom logic (e.g., focus) +}); +``` + +#### Example: Adding a New Feature +Suppose you want to add a button that increments a counter: + +1. **state.js**: Add `count` to your state. +2. **update.js**: Handle an `INCREMENT` action. +3. **view.js**: Add a button and display the count. +4. **app.js**: + - Add an event handler for the button: + ```js + function handleIncrement() { + dispatch({ type: 'INCREMENT' }); + } + ``` + - Add to the `events` array: + ```js + events: [ + { selector: '#increment-btn', event: 'click', handler: handleIncrement }, + // ...other events + ] + ``` + +### Tips +- Keep all state transitions in `update.js` for predictability. +- Keep all DOM rendering in `view.js` for clarity. +- Use the `postRender` hook for accessibility or focus management. +- Add new features by extending state, update, view, and wiring up events in `app.js`. + +--- + +Inspired by the [Elm Architecture](https://guide.elm-lang.org/architecture/), but using only browser APIs and ES modules. + +--- + +## MIT License + +Copyright 2025 eli_oat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file |