-
Notifications
You must be signed in to change notification settings - Fork 8
J/template hyperapp #380
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
Merged
Merged
J/template hyperapp #380
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
5f02314
add hyperapp skeleton to templates
jurij-jukic bfc0a22
Format Rust code using rustfmt
github-actions[bot] 8babfa7
template
jurij-jukic 8556e3b
Merge remote-tracking branch 'origin/j/template-hyperapp' into j/temp…
jurij-jukic 77c513f
add resources
jurij-jukic 01129a8
rename hyperapp-skeleton to hyperapp
jurij-jukic e684a9f
remove pkg/ui and add to gitignore
jurij-jukic b8fdf40
remove garbage from example-apps/id/id
jurij-jukic 6292efb
rename back from hyperapp to hyperapp-skeleton
jurij-jukic 097c3d4
remove machine generated api folder
jurij-jukic c8ed6bb
fix icon
jurij-jukic 08af650
remove obsolete comments.
jurij-jukic 1a61992
remove api.ts and wire backend calls correctly
jurij-jukic fdc9304
wit_world fix
jurij-jukic afcbb0f
remove useless request_body args
jurij-jukic 61d5dd7
remove file explorer
jurij-jukic a969490
update file explorer
jurij-jukic 03ca3c7
gitignore cleanup
jurij-jukic 01289dc
remove pkg/ui from file explorer
jurij-jukic 6206ce7
clean up cargo tomls in hyperapp skeleton
jurij-jukic 65597a2
remove types/skeleton.ts
jurij-jukic 3a0ba89
remove CHANGES_MADE.md
jurij-jukic f10ac75
remove expand-sign-old.txt
jurij-jukic 9b15386
remove caller utils from file explorer example
jurij-jukic f459a67
Revert "remove types/skeleton.ts"
jurij-jukic 5bc7535
remove api stuff from types/skeleton.ts and some readme updates
jurij-jukic 12bb808
update readme re file explorer api
jurij-jukic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| [profile.release] | ||
| lto = true | ||
| opt-level = "s" | ||
| panic = "abort" | ||
|
|
||
| [workspace] | ||
| members = [ | ||
| "skeleton-app", | ||
| "target/hyperapp-skeleton-caller-util?", | ||
| ] | ||
| resolver = "2" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,249 @@ | ||
| # Hyperware Skeleton App | ||
|
|
||
| A minimal, well-commented skeleton application for the Hyperware platform using the Hyperapp framework. | ||
| This skeleton provides a starting point for building Hyperware applications with a React/TypeScript frontend and Rust backend. | ||
|
|
||
| Either prompt your favorite LLM directly with instructions on how to build your app or add them to `instructions.md`! | ||
|
|
||
| Recommended usage: | ||
| - Create a skeleton repo using a kit template: | ||
| ```bash | ||
| kit new foo --template hyperapp-skeleton --ui | ||
| cd foo | ||
| ``` | ||
| - Write a detailed document describing what you want your app to do. | ||
| Save this in `instructions.md`. | ||
| - Prompt your LLM agent (i.e. Claude Code) with something like: | ||
| ``` | ||
| ## GOAL | ||
|
|
||
| <One-sentence description of app here> | ||
|
|
||
| ## Instructions | ||
|
|
||
| Read the README.md and follow the Instructions > Create an implementation plan | ||
| ``` | ||
|
|
||
| - After creating an implementation plan, clear your LLM agent's context and then prompt it again with something like: | ||
|
|
||
| ``` | ||
| ## GOAL | ||
|
|
||
| <One-sentence description of app here> | ||
|
|
||
| ## Instructions | ||
|
|
||
| Read the README.md and follow the Instructions > Implement the plan | ||
| ``` | ||
|
|
||
| The rest of this document is aimed at *LLMs* not *humans*. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| - Hyperware development environment (`kit` command) | ||
| - Rust toolchain | ||
| - Node.js and npm | ||
|
|
||
| ### Building | ||
|
|
||
| Always build with | ||
| ```bash | ||
| kit build --hyperapp | ||
| ``` | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ``` | ||
| hyperapp-skeleton/ | ||
| ├── Cargo.toml # Workspace configuration | ||
| ├── metadata.json # App metadata | ||
| ├── skeleton-app/ # Main Rust process | ||
| │ ├── Cargo.toml # Process dependencies | ||
| │ └── src/ | ||
| │ ├── lib.rs # Main app logic (well-commented) | ||
| │ └── icon # App icon file | ||
| ├── ui/ # Frontend application | ||
| │ ├── package.json # Node dependencies | ||
| │ ├── index.html # Entry point (includes /our.js) | ||
| │ ├── vite.config.ts # Build configuration | ||
| │ └── src/ | ||
| │ ├── App.tsx # Main React component | ||
| │ ├── store/ # Zustand state management | ||
| │ ├── types/ # TypeScript type definitions | ||
| │ └── utils/ # API utilities | ||
| ├── api/ # Generated WIT files (after build) | ||
| └── pkg/ # The final build product, including manifest.json, scripts.json and built package output | ||
| ``` | ||
|
|
||
| ## Key Concepts | ||
|
|
||
| ### 1. The Hyperprocess Macro | ||
|
|
||
| The `#[hyperprocess]` macro is the core of the Hyperapp framework. It provides: | ||
| - Async/await support without tokio | ||
| - Automatic WIT generation | ||
| - State persistence | ||
| - HTTP/WebSocket endpoint configuration | ||
|
|
||
| ### 2. Required Patterns | ||
|
|
||
| #### HTTP Endpoints | ||
| ALL HTTP endpoints MUST be tagged with `#[http]`: | ||
| ```rust | ||
| #[http] | ||
| async fn my_endpoint(&self) -> String { | ||
| // Implementation | ||
| } | ||
| ``` | ||
|
|
||
| #### Frontend API Calls | ||
| Parameters must be sent as tuples for multi-parameter methods: | ||
| ```typescript | ||
| // Single parameter | ||
| { "MethodName": value } | ||
|
|
||
| // Multiple parameters | ||
| { "MethodName": [param1, param2] } | ||
| ``` | ||
|
|
||
| #### The /our.js Script | ||
| MUST be included in index.html: | ||
| ```html | ||
| <script src="/our.js"></script> | ||
| ``` | ||
|
|
||
| ### 3. State Persistence | ||
|
|
||
| Your app's state is automatically persisted based on the `save_config` option: | ||
| - `OnDiff`: Save when state changes (strongly recommended) | ||
| - `Never`: No automatic saves | ||
| - `EveryMessage`: Save after each message (safest; slowest) | ||
| - `EveeyNMessage(u64)`: Save every N messages received | ||
| - `EveeyNSeconds(u64)`: Save every N seconds | ||
|
|
||
| ## Customization Guide | ||
|
|
||
| ### 1. Modify App State | ||
|
|
||
| Edit `AppState` in `skeleton-app/src/lib.rs`: | ||
| ```rust | ||
| #[derive(Default, Serialize, Deserialize)] | ||
| pub struct AppState { | ||
| // Add your fields here | ||
| my_data: Vec<MyType>, | ||
| } | ||
| ``` | ||
|
|
||
| ### 2. Add HTTP Endpoints | ||
|
|
||
| For UI interaction: | ||
| ```rust | ||
| #[http] | ||
| async fn my_method(&mut self) -> Result<String, String> { | ||
| // Parse request, update state, return response | ||
| } | ||
| ``` | ||
|
|
||
| ### 3. Add Capabilities | ||
|
|
||
| Add system permissions in `pkg/manifest.json`: | ||
| ```json | ||
| "request_capabilities": [ | ||
| "homepage:homepage:sys", | ||
| "http-server:distro:sys", | ||
| "vfs:distro:sys" // Add as needed | ||
| ] | ||
| ``` | ||
|
|
||
| These are required to message other local processes. | ||
| They can also be granted so other local processes can message us. | ||
| There is also a `request_networking` field that must be true to send messages over the network p2p. | ||
|
|
||
| ### 4. Update Frontend | ||
|
|
||
| 1. Add types in `ui/src/types/skeleton.ts` | ||
| 2. Update store in `ui/src/store/skeleton.ts` | ||
| 3. Modify UI in `ui/src/App.tsx` | ||
|
|
||
| ### 5. Rename as appropriate | ||
|
|
||
| Change names throughout from `hyperapp-skeleton` (and variants) as appropriate if user describes app name. | ||
|
|
||
| ## Common Issues and Solutions | ||
|
|
||
| ### "Failed to deserialize HTTP request" | ||
| - Check parameter format (tuple vs object) | ||
|
|
||
| ### "Node not connected" | ||
| - Verify `/our.js` is included in index.html | ||
| - Check that the app is running in Hyperware environment | ||
|
|
||
| ### WIT Generation Errors | ||
| - Use simple types or return JSON strings | ||
| - No HashMap (use Vec<(K,V)>) | ||
| - No fixed arrays (use Vec<T>) | ||
| - Add #[derive(PartialEq)] to structs | ||
|
|
||
| ### Import Errors | ||
| - Don't add `hyperware_process_lib` to Cargo.toml | ||
| - Use imports from `hyperprocess_macro` | ||
|
|
||
| ## Testing Your App | ||
|
|
||
| 1. Deploy app to a Hyperware node (after building, if requested): | ||
| ```bash | ||
| kit start-packages | ||
| ``` | ||
| 2. Your app will be automatically installed and available at `http://localhost:8080` | ||
| 3. Check the Hyperware homepage for your app icon | ||
|
|
||
| ## Instructions | ||
|
|
||
| ### Create an implementation plan | ||
|
|
||
| Carefully read the prompt; look carefully at `instructions.md` (if it exists) and in the resources/ directory. | ||
| In particular, note the example applications `resources/example-apps/sign/`, `resources/example-apps/id/`, and `resources/example-apps/file-explorer`. Note that `file-explorer` example contains an `api`, which is generated by the compiler, and not human or LLM written. | ||
| `sign` and `id` demonstrate local messaging. | ||
| `file-explorer` demonstrates VFS interactions. | ||
|
|
||
| Expand the prompt and/or `instructions.md` into a detailed implementation plan. | ||
| The implementor will be starting from this existing template that exists at `skeleton-app/` and `ui/`. | ||
|
|
||
| Note in particular that bindings for the UI will be generated when the app is built with `kit build --hyperapp`. | ||
| As such, first design and implement the backend; the interface will be generated from the backend; finally design and implement the frontend to consume the interface. | ||
| Subsequent changes to the interface must follow this pattern as well: start in backend, generate interface, finish in frontend | ||
|
|
||
| Do NOT create the API. | ||
| The API is machine generated. | ||
| You create types that end up in the API by defining and using them in functions in the Rust backend "hyperapp" | ||
|
|
||
| Do NOT write code: just create a detailed `IMPLEMENTATION_PLAN.md` that will be used by the implementor. | ||
| The implementor will have access to `resources/` but will be working from `IMPLEMENTATION_PLAN.md`, so include all relevant context in the PLAN. | ||
| You can refer the implementor to `resources/` but do not assume the implementor has read them unless you refer them there. | ||
|
|
||
| ### Implement the plan | ||
|
|
||
| Look carefully at `IMPLEMENTATION_PLAN.md` and in the `resources/` directory, if relevant. | ||
| In particular, note the example applications `resources/example-apps/sign/`, `resources/example-apps/id/`, and `resources/example-apps/file-explorer`. | ||
| Use them if useful. | ||
|
|
||
| Work from the existing template that exists at `skeleton-app/` and `ui/`. | ||
|
|
||
| Note in particular that bindings for the UI will be generated when the app is built with `kit build --hyperapp`. | ||
| As such, first design and implement the backend; the interface will be generated from the backend; finally design and implement the frontend to consume the interface. | ||
| Subsequent changes to the interface must follow this pattern as well: start in backend, generate interface, finish in frontend | ||
|
|
||
| Do NOT create the API. | ||
| The API is machine generated. | ||
| You create types that end up in the API by defining and using them in functions in the Rust backend "hyperapp" | ||
|
|
||
| Do not worry about serialization/deserialization when using `send` and `send_rmp` functions for p2p communication. | ||
| Notice that this all happens within those functions: just take the rust types as args and return rust types as return values. | ||
|
|
||
| If you create a GUI for the app you MUST use target/ui/caller-utils.ts for HTTP requests to the backend. | ||
| Do NOT edit this file: it is machine generated. | ||
| Do NOT do `fetch` or other HTTP requests manually to the backend: use the functions in this machine generated interface. | ||
|
|
||
| Implement the application described in the `IMPLEMENTATION_PLAN.md`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "name": "SkeletonApp", | ||
| "description": "A minimal skeleton app for the Hyperware platform using the Hyperapp framework - demonstrates basic state management and HTTP endpoints", | ||
| "image": "", | ||
| "properties": { | ||
| "package_name": "skeleton-app", | ||
| "current_version": "0.1.0", | ||
| "publisher": "skeleton.os", | ||
| "mirrors": [], | ||
| "code_hashes": { | ||
| "0.1.0": "" | ||
| }, | ||
| "wit_version": 1, | ||
| "dependencies": [] | ||
| }, | ||
| "external_url": "", | ||
| "animation_url": "" | ||
| } |
19 changes: 19 additions & 0 deletions
19
src/new/templates/rust/ui/hyperapp-skeleton/pkg/manifest.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| [ | ||
| { | ||
| "process_name": "skeleton-app", | ||
| "process_wasm_path": "/skeleton-app.wasm", | ||
| "on_exit": "Restart", | ||
| "request_networking": false, | ||
| "request_capabilities": [ | ||
| "homepage:homepage:sys", | ||
| "http-server:distro:sys", | ||
| "vfs:distro:sys" | ||
| ], | ||
| "grant_capabilities": [ | ||
| "homepage:homepage:sys", | ||
| "http-server:distro:sys", | ||
| "vfs:distro:sys" | ||
| ], | ||
| "public": false | ||
| } | ||
| ] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.