apprun 4.0.0 → 6.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +235 -12
- package/LICENSE +1 -1
- package/README.md +225 -110
- package/apprun.d.ts +240 -34
- package/cli/app.js +29 -0
- package/cli/colors.js +69 -0
- package/cli/index.html +13 -0
- package/cli/index.js +96 -0
- package/dist/apprun-code.js +2 -0
- package/dist/apprun-code.js.map +1 -0
- package/dist/apprun-dev-tools.js +1 -1
- package/dist/apprun-dev-tools.js.map +1 -1
- package/dist/apprun-html.esm.js +34 -0
- package/dist/apprun-html.esm.js.map +1 -0
- package/dist/apprun-html.js +2 -1
- package/dist/apprun-html.js.LICENSE.txt +11 -0
- package/dist/apprun-html.js.map +1 -1
- package/dist/apprun-play.js +2 -0
- package/dist/apprun-play.js.map +1 -0
- package/dist/apprun.esm.js +2 -0
- package/dist/apprun.esm.js.map +1 -0
- package/dist/apprun.js +1 -1
- package/dist/apprun.js.map +1 -1
- package/dist/createState.js +2 -0
- package/dist/createState.js.map +1 -0
- package/esm/add-components.js +90 -0
- package/esm/add-components.js.map +1 -0
- package/esm/app.js +209 -0
- package/esm/app.js.map +1 -0
- package/esm/apprun-code.js +170 -0
- package/esm/apprun-code.js.map +1 -0
- package/esm/apprun-dev-tools-tests.js +95 -0
- package/esm/apprun-dev-tools-tests.js.map +1 -0
- package/esm/apprun-dev-tools.js +281 -0
- package/esm/apprun-dev-tools.js.map +1 -0
- package/esm/apprun-html.js +24 -0
- package/esm/apprun-html.js.map +1 -0
- package/esm/apprun-play.js +248 -0
- package/esm/apprun-play.js.map +1 -0
- package/esm/apprun.js +220 -0
- package/esm/apprun.js.map +1 -0
- package/esm/component.js +413 -0
- package/esm/component.js.map +1 -0
- package/esm/createState.js +9 -0
- package/esm/createState.js.map +1 -0
- package/esm/decorator.js +88 -0
- package/esm/decorator.js.map +1 -0
- package/esm/directive.js +306 -0
- package/esm/directive.js.map +1 -0
- package/esm/router.js +345 -0
- package/esm/router.js.map +1 -0
- package/esm/type-utils.js +90 -0
- package/esm/type-utils.js.map +1 -0
- package/esm/types.js +58 -0
- package/esm/types.js.map +1 -0
- package/esm/vdom-lit-html.js +65 -0
- package/esm/vdom-lit-html.js.map +1 -0
- package/esm/vdom-my-prop-attr.js +227 -0
- package/esm/vdom-my-prop-attr.js.map +1 -0
- package/esm/vdom-my.js +293 -0
- package/esm/vdom-my.js.map +1 -0
- package/esm/vdom-to-html.js +54 -0
- package/esm/vdom-to-html.js.map +1 -0
- package/esm/vdom.js +28 -0
- package/esm/vdom.js.map +1 -0
- package/esm/version.js +15 -0
- package/esm/version.js.map +1 -0
- package/esm/web-component.js +155 -0
- package/esm/web-component.js.map +1 -0
- package/jsx-runtime.js +2 -0
- package/jsx-runtime.js.map +1 -0
- package/package.json +90 -41
- package/.travis.yml +0 -10
- package/.vscode/launch.json +0 -19
- package/BACKERS.md +0 -3
- package/apprun-cli.js +0 -177
- package/cli-templates/_gitignore +0 -6
- package/cli-templates/component.ts_ +0 -16
- package/cli-templates/index.html +0 -11
- package/cli-templates/karma.conf.js +0 -24
- package/cli-templates/main.ts_ +0 -13
- package/cli-templates/readme.md +0 -7
- package/cli-templates/spa_index.html +0 -14
- package/cli-templates/spa_main.ts_ +0 -47
- package/cli-templates/spec.ts_ +0 -11
- package/cli-templates/tsconfig.json +0 -12
- package/cli-templates/webpack.config.js +0 -23
- package/demo-html/app.js +0 -2
- package/demo-html/app.js.map +0 -1
- package/demo-html/counter-c.html +0 -29
- package/demo-html/counter-wc-event.html +0 -29
- package/demo-html/counter-wc.html +0 -29
- package/demo-html/counter.html +0 -26
- package/demo-html/index.html +0 -14
- package/demo-html/main.tsx +0 -31
- package/docs/README.md +0 -326
- package/docs/index.html +0 -23
- package/index.html +0 -85
- package/logo.png +0 -0
- package/src/app.ts +0 -69
- package/src/apprun-dev-tools.tsx +0 -67
- package/src/apprun-html.ts +0 -13
- package/src/apprun.ts +0 -53
- package/src/component.ts +0 -189
- package/src/createComponent.tsx +0 -38
- package/src/decorator.ts +0 -36
- package/src/router.ts +0 -19
- package/src/types.ts +0 -9
- package/src/vdom-html.ts +0 -17
- package/src/vdom-my.ts +0 -191
- package/src/vdom-to-html.tsx +0 -45
- package/src/vdom.ts +0 -7
- package/src/web-component.ts +0 -29
- package/tests/app-rx.spec_ +0 -41
- package/tests/app.spec.ts +0 -122
- package/tests/application.spec.tsx +0 -23
- package/tests/component.spec.tsx +0 -296
- package/tests/custom-element.spec.tsx +0 -19
- package/tests/data-attr.spec.tsx +0 -42
- package/tests/decorator.spec.tsx +0 -104
- package/tests/fragment.spec.tsx +0 -79
- package/tests/hyperscript.spec.ts +0 -43
- package/tests/node-test.js +0 -7
- package/tests/router.spec.ts +0 -69
- package/tests/stateful-component.spec.tsx +0 -248
- package/tests/typed.spec.tsx +0 -63
- package/tests/vdom-html.spec.ts +0 -35
- package/tests/vdom-jsx.spec.tsx +0 -131
- package/tests/vdom-my.spec.tsx +0 -195
- package/tests/view-engine.spec.js +0 -59
- package/tsconfig.json +0 -11
- package/tslint.json +0 -124
- package/typescriptreact.json +0 -87
- package/viewEngine.js +0 -54
- package/webpack.config.js +0 -30
package/CHANGELOG.md
CHANGED
|
@@ -1,26 +1,249 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
* apprun@latet: 1.x, stable, es5
|
|
5
|
-
* apprun@beta: 2.x, stable, es2015, web component
|
|
6
|
-
* apprun@next: 3.x, development, es5
|
|
7
|
-
* apprun@es6: 4.x, development, es2015, web component
|
|
3
|
+
## V6.0.0
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
* Kept AppRun script-tag globals; removed legacy `React` and `_React` browser aliases
|
|
6
|
+
* Removed `_html:` string-prefix rendering; use `trustedHTML()` for caller-owned trusted markup
|
|
7
|
+
* Deprecated misleading `safeHTML()` naming in favor of `trustedHTML()`
|
|
8
|
+
* Removed `query()` in favor of `runAsync()`
|
|
9
|
+
* Added router support for `:param` and `*` patterns
|
|
10
|
+
* Hardened package exports, package contents, side-effect metadata, and generated artifact hygiene
|
|
11
|
+
* Made `immer` an optional peer dependency for `createState`
|
|
12
|
+
* Added CI checks for lint and package dry-run validation
|
|
13
|
+
|
|
14
|
+
## V3.38.0
|
|
15
|
+
|
|
16
|
+
* Support for binding to nested objects and arrays with `$bind`
|
|
17
|
+
* Support for type safe props and children in components
|
|
18
|
+
* Use `unknown` instead of `any` for generic defaults
|
|
19
|
+
|
|
20
|
+
## V3.37.3
|
|
21
|
+
|
|
22
|
+
* Updated skip logic for - removed `value` property
|
|
23
|
+
|
|
24
|
+
## V3.37.2
|
|
25
|
+
|
|
26
|
+
* Include rule / prompt files for AI Coding Agent
|
|
27
|
+
* Improved type definitions for better TypeScript support
|
|
28
|
+
- Support async function and async generator in `Action<T>` that is used in `Update<T, E>`
|
|
29
|
+
- Added `State` type to allow the initial state to be a function or an async function
|
|
30
|
+
* Fixed routing basePath initialization issue - not to set basePath to location.pathname by default
|
|
31
|
+
|
|
32
|
+
## V3.37.1
|
|
33
|
+
|
|
34
|
+
* Make `immer` and `property-information` as dependencies
|
|
35
|
+
|
|
36
|
+
## V3.37.0
|
|
37
|
+
|
|
38
|
+
* Introduced `createState` helper for simplified immutable state updates using Immer [create-state-immer](#docs/done/blog-create-state-immer.md)
|
|
39
|
+
* Added `addComponents` function for adding components to routes [add-components](#docs/done/blog-addcomponents-feature.md)
|
|
40
|
+
* Moved the component to dev-tools
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## 3.36.1
|
|
44
|
+
|
|
45
|
+
* Continue code review with AI
|
|
46
|
+
* Use property-information to improve property and attribute handling
|
|
47
|
+
* Performance improvements in virtual DOM handling, see [analysis reports](#docs/done/framework-reordering-comparison.md)
|
|
48
|
+
* New hierarchical matching behavior, see [hierarchical routing requirements](#docs/requirements/req-hierarchical-routing.md)
|
|
49
|
+
|
|
50
|
+
## 3.36.0
|
|
51
|
+
|
|
52
|
+
* Code review by using Copilot and Claude Sonnet 4, see [plan-apprun-bugfixes.md](#docs/plan/plan-apprun-bugfixes.md) for details.
|
|
53
|
+
* Enhanced type definitions (apprun.d.ts) for better TypeScript support
|
|
54
|
+
* Fixed minor bugs and edge cases in virtual DOM handling
|
|
55
|
+
* Fixed bugs in router initialization logic
|
|
56
|
+
|
|
57
|
+
## 3.35.0
|
|
58
|
+
|
|
59
|
+
* Support auto use router for pretty links
|
|
60
|
+
* AppRun now supports pretty links with components subscribing to route events like '/about'
|
|
61
|
+
* Routing component events with pretty links
|
|
62
|
+
* Fallback to hash-based routing when components subscribe to '#' or '#/'
|
|
63
|
+
|
|
64
|
+
## 3.33.10
|
|
65
|
+
|
|
66
|
+
* Support async generator for event handlers
|
|
67
|
+
* Async generator functions can return multiple values rendered in order
|
|
68
|
+
* Use lit-html V3 for apprun-html.js
|
|
69
|
+
* Standalone version of AppRun using lit-html for rendering without JSX
|
|
70
|
+
|
|
71
|
+
## 3.30.0
|
|
72
|
+
|
|
73
|
+
* Add React-safe apprun-play-html
|
|
74
|
+
* Add no-init-route flag
|
|
75
|
+
* Save Rect in app in case it needs to be used in the future
|
|
76
|
+
* Create custom element that extends HTMLDivElement
|
|
77
|
+
* Allow require from node
|
|
78
|
+
|
|
79
|
+
## 3.29.0
|
|
80
|
+
|
|
81
|
+
* Resolve async state before running the event
|
|
82
|
+
|
|
83
|
+
## 3.28.15
|
|
84
|
+
|
|
85
|
+
* Support css selector in _mount_, _start_, and _app.render_
|
|
86
|
+
|
|
87
|
+
## 3.28.12
|
|
88
|
+
|
|
89
|
+
* Export safeHTML funciton
|
|
90
|
+
|
|
91
|
+
## 3.28.11
|
|
92
|
+
|
|
93
|
+
* Make the package type module
|
|
94
|
+
|
|
95
|
+
## 3.28.10
|
|
96
|
+
|
|
97
|
+
* Apply directive to _app.render_
|
|
98
|
+
|
|
99
|
+
## 3.28.9
|
|
100
|
+
|
|
101
|
+
* retire CLI
|
|
102
|
+
|
|
103
|
+
## 3.28.8
|
|
104
|
+
|
|
105
|
+
* Use lit-html@2
|
|
106
|
+
|
|
107
|
+
## 3.28.3 merged into master
|
|
108
|
+
|
|
109
|
+
* Replaced _morphdom_ with _lit-html_
|
|
110
|
+
|
|
111
|
+
## 1.28/ 2.28 / 3.28
|
|
112
|
+
|
|
113
|
+
* New app.query function that returns the returned values of all then event handlers
|
|
114
|
+
```ts
|
|
115
|
+
app.query(name: string, ...args): Promise<any[]>;
|
|
116
|
+
```
|
|
117
|
+
* Event pattern matching
|
|
118
|
+
```ts
|
|
119
|
+
app.on('ws:*', _ => 0); // handles all events that have name start with ws:
|
|
120
|
+
```
|
|
121
|
+
* Event context
|
|
122
|
+
```ts
|
|
123
|
+
@on('event', {c:1}) // define the context
|
|
124
|
+
fn = ({c}) => {...}; // get the context in the handler
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 1.27/ 2.27 / 3.27
|
|
129
|
+
|
|
130
|
+
* BREAKING CHANGES: New logic for creating stateful components
|
|
131
|
+
* BREAKING CHANGES: remove props from the view function call
|
|
132
|
+
* Support _as_ prop for naming the root element of components
|
|
133
|
+
* Support prop _apprun-no-init_ in _body_ to skip the init route call
|
|
134
|
+
* CLI: -e, --esbuild option to use esbuild instead of webpack
|
|
135
|
+
* CLI: -o, --story option to generate stories for a component
|
|
136
|
+
|
|
137
|
+
## 1.26/ 2.26 / 3.26
|
|
138
|
+
|
|
139
|
+
* Support initial state as a function or an async function
|
|
140
|
+
* Support promise returned from the _mounted_ function
|
|
141
|
+
* Wait for all promises before set new state
|
|
142
|
+
* Dev Tools: save debugging flag to local storage
|
|
143
|
+
* Dev Tools: handle messages from redux dev tools
|
|
144
|
+
* Dev Tools: improve debugging event content
|
|
145
|
+
* Dev Tools: publish two debugging events for each event
|
|
146
|
+
* CLI: Support the unbundled development experiences with [esm-server](https://github.com/yysun/apprun-esm-server)
|
|
147
|
+
* CLI: add -e option for adding ESLint
|
|
148
|
+
* CLI: use Jest preset: ts-jest
|
|
149
|
+
* CLI: use jsxFactory to app.h
|
|
150
|
+
|
|
151
|
+
## 1.24 / 2.25 / 3.25
|
|
152
|
+
|
|
153
|
+
* Support the list attribute
|
|
154
|
+
* Support webpack 5
|
|
155
|
+
* Set jsxFactory to app.h for TypeScript 4
|
|
156
|
+
|
|
157
|
+
## 1.24 / 2.24 / 3.24
|
|
158
|
+
|
|
159
|
+
* Support the list attribute
|
|
160
|
+
|
|
161
|
+
## 1.23 / 2.23 / 3.23
|
|
162
|
+
|
|
163
|
+
* Support style attribute using string
|
|
164
|
+
* Support element event handler using string
|
|
165
|
+
* Support xlink:href in SVG
|
|
166
|
+
* Add -patch-vdom-on flag on component for patching vdom before rendering
|
|
167
|
+
* Add _route_ to mount options
|
|
168
|
+
* Add app start options type
|
|
169
|
+
* PR #90 - observable properties on web-component, thanks to @spurreiter
|
|
170
|
+
* Add @on and @customElement to window
|
|
171
|
+
* Export Fragment and app.h
|
|
172
|
+
* Add more examples to play-ground
|
|
173
|
+
* CLI installs ES2015 by default
|
|
174
|
+
* fix vdom update for child svg, remove console.assert
|
|
175
|
+
* Fix bug: view function called twice in create component
|
|
176
|
+
|
|
177
|
+
## 1.22 / 2.22 / 3.22
|
|
178
|
+
|
|
179
|
+
* Call ref attribute in JSX as a function
|
|
180
|
+
* Allow event to be turned or off inside a run call
|
|
181
|
+
* Allow mounted life cycle function to return state and Promise of state
|
|
182
|
+
* Pass _state_ to mounted function
|
|
183
|
+
* Merge dev-tools into one file: apprun-dev-tools.js
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
## 1.21 / 2.21 / 3.21
|
|
187
|
+
|
|
188
|
+
* Allow embedding elements in JSX
|
|
189
|
+
* Use app['debug'] to turn on/off debug events and component cache
|
|
190
|
+
|
|
191
|
+
## 1.20 / 2.20 / 3.20
|
|
192
|
+
|
|
193
|
+
* Add . event to Component,a.k.s the refresh event
|
|
194
|
+
* Add ES6 module build: apprun.esm.js (2.20+)
|
|
195
|
+
* Add @customElement decorator (2.20+)
|
|
196
|
+
* Store _AppRunVersions in global
|
|
197
|
+
* New docs
|
|
198
|
+
|
|
199
|
+
## 1.19 / 2.19
|
|
200
|
+
|
|
201
|
+
* $on directive use tuple for event parameters
|
|
202
|
+
* Add event type to app, component and decorators
|
|
203
|
+
* Support _Update_ as array of tuple to enforce the event type
|
|
204
|
+
* Set window['React']=app for using babel in browser
|
|
205
|
+
* $bind to function and tuple
|
|
206
|
+
|
|
207
|
+
## 1.18 / 2.18
|
|
208
|
+
|
|
209
|
+
* Support JSX directives $on and $bind
|
|
210
|
+
* Add $ event for custom directives
|
|
211
|
+
* Change the component wrapper element from <div> to <section>
|
|
212
|
+
* Fixed #57, #58
|
|
213
|
+
|
|
214
|
+
## 1.17 / 2.17
|
|
215
|
+
|
|
216
|
+
* Pull requests: #48, #49, #50, #52, #53, #54, #55 thanks to @phBalance, @Sebring
|
|
217
|
+
* Added lifecycle function: unload (beta)
|
|
218
|
+
* Add props to the wrapper div of stateful component, #57, thanks to @bo-kh
|
|
219
|
+
* Pass props to view, children to mounted functions of the stateful component
|
|
220
|
+
|
|
221
|
+
## 1.16 / 2.16
|
|
222
|
+
|
|
223
|
+
* Support class attribute in JSX
|
|
224
|
+
* Support class and className attribute for SVG
|
|
225
|
+
* Support custom attribute (with kebab case/snake case)
|
|
226
|
+
* Export app (non-default)
|
|
227
|
+
* CLI: use src and dist folder, es6 flag
|
|
228
|
+
* Fix CLI error: #45, thanks to @srlopez
|
|
229
|
+
|
|
230
|
+
## 1.15
|
|
231
|
+
|
|
232
|
+
* Support SVG
|
|
233
|
+
* Convert kebab-case to camelCase for data- attributes
|
|
234
|
+
|
|
235
|
+
## 1.14
|
|
10
236
|
|
|
11
237
|
* New logic for creating stateful component
|
|
12
238
|
* Add unmount function
|
|
239
|
+
* Add app.off function
|
|
13
240
|
* Server-side rendering
|
|
14
241
|
* Don't render vnode of false
|
|
15
242
|
* Add dev-tools (dist/apprun-dev-tools.js)
|
|
16
243
|
|
|
17
|
-
## 2.0 beta
|
|
18
|
-
|
|
19
|
-
* Make AppRun component web component
|
|
20
|
-
|
|
21
244
|
## 1.13
|
|
22
245
|
|
|
23
|
-
* Add
|
|
246
|
+
* Add lifecycle method: mounted
|
|
24
247
|
* Add event 'get-components' to retrieve the stateful component cache
|
|
25
248
|
|
|
26
249
|
## 1.12
|
|
@@ -128,4 +351,4 @@
|
|
|
128
351
|
* Event pubsub
|
|
129
352
|
* Used virtual-dom, virtual-dom-html
|
|
130
353
|
* Three versions: zero, jsx and html
|
|
131
|
-
* Demo apps
|
|
354
|
+
* Demo apps
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,144 +1,238 @@
|
|
|
1
|
-
# AppRun
|
|
1
|
+
# AppRun
|
|
2
2
|
|
|
3
|
+
[](https://apprun.js.org/docs)
|
|
4
|
+
[](https://apprun.js.org/#play)
|
|
5
|
+
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][downloads-url] [![License][license-image]][license-url] [![twitter][twitter-badge]][twitter] [![Discord Chat][discord-image]][discord-invite]
|
|
3
6
|
|
|
4
|
-
AppRun is a 3K library for building applications using the [Elm inspired Architecture](https://yysun.github.io/apprun/docs/#/?id=architecture), [event pub-sub](https://yysun.github.io/apprun/docs/#/?id=event-pubsubs) and [components](https://yysun.github.io/apprun/docs/#/?id=component).
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
⭐ NEW Agent Skills for AppRun: We have developed a set of AI Agent Skills to assist with AppRun development. These skills cover various aspects of building applications with AppRun, including component design, state management, routing, and testing.
|
|
7
9
|
|
|
8
|
-
## Architecture Concept
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
You can install the AppRun Skills for your AI agents with the following command:
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npx skills add yysun/apprun
|
|
15
|
+
```
|
|
15
16
|
|
|
16
|
-
AppRun ties the three parts together and drives the applications using [event pub-sub](https://yysun.github.io/apprun/docs/#/?id=event-pubsubs).
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
🚀 July 2025, We have started to improve the codebase using AI - the spec-driven flow. The requirements, implementation plan and final results are stored in the `docs` folder.
|
|
19
19
|
|
|
20
|
+
## Introduction
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
AppRun is a lightweight framework for building web apps. It has a [unique architecture](https://apprun.js.org/docs/architecture/) inspired by the Elm architecture that can help you manage states, routing, and other essential aspects of your web application, leveraging the power of the [event publish-subscribe](https://apprun.js.org/docs/event-pubsub/) pattern.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
24
|
+
## AppRun Benefits
|
|
25
|
+
|
|
26
|
+
* Clean architecture that needs minimal setup and boilerplate code.
|
|
27
|
+
* Decoupled architecture that is test friendly.
|
|
28
|
+
* No proprietary syntax to learn (no hooks, no reducers, no signals)
|
|
29
|
+
* State management and routing included
|
|
30
|
+
* Use directly in the browser or with a compiler/bundler
|
|
31
|
+
* Advanced features: JSX, Web Components, Dev Tools, SSR, etc.
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
Let's use a _Counter_ as an example to demonstrate the AppRun architecture:
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
// define the initial state
|
|
39
|
+
const state = 0;
|
|
40
|
+
|
|
41
|
+
// view is a function to display the state (JSX)
|
|
42
|
+
const view = state => <div>
|
|
43
|
+
<h1>{state}</h1>
|
|
44
|
+
<button onclick="app.run('-1')">-1</button>
|
|
45
|
+
<button onclick="app.run('+1')">+1</button>
|
|
46
|
+
</div>;
|
|
47
|
+
|
|
48
|
+
// update is a collection of event handlers
|
|
49
|
+
const update = {
|
|
50
|
+
'+1': state => state + 1,
|
|
51
|
+
'-1': state => state - 1
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// start the app
|
|
55
|
+
app.start(document.body, state, view, update);
|
|
50
56
|
```
|
|
57
|
+
<apprun-code></apprun-code>
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
With [directives](https://apprun.js.org/docs/directives/) syntax sugar you can write more concise code:
|
|
53
60
|
|
|
54
|
-
|
|
61
|
+
```js
|
|
62
|
+
// define the initial state
|
|
63
|
+
const state = 0;
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
<
|
|
58
|
-
<
|
|
59
|
-
<
|
|
60
|
-
<
|
|
61
|
-
</
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<h1>${state}</h1>
|
|
72
|
-
<button onclick='counter.run("-1")'>-1</button>
|
|
73
|
-
<button onclick='counter.run("+1")'>+1</button>
|
|
74
|
-
</div>`;
|
|
75
|
-
this.update = {
|
|
76
|
-
'+1': state => state + 1,
|
|
77
|
-
'-1': state => state - 1
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
app.webComponent('my-app', Counter);
|
|
82
|
-
</script>
|
|
83
|
-
</body>
|
|
84
|
-
</html>
|
|
65
|
+
// view is a function to display the state (JSX)
|
|
66
|
+
const view = state => <div>
|
|
67
|
+
<h1>{state}</h1>
|
|
68
|
+
<button $onclick="-1">-1</button>
|
|
69
|
+
<button $onclick="+1">+1</button>
|
|
70
|
+
</div>;
|
|
71
|
+
|
|
72
|
+
// update is a collection of event handlers
|
|
73
|
+
const update = {
|
|
74
|
+
'+1': state => state + 1,
|
|
75
|
+
'-1': state => state - 1
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// start the app
|
|
79
|
+
app.start(document.body, state, view, update);
|
|
85
80
|
```
|
|
81
|
+
<apprun-code></apprun-code>
|
|
82
|
+
|
|
83
|
+
Alternatively, you can invoke state update functions without events for local state updates:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
// define the initial state
|
|
87
|
+
const state = 0;
|
|
86
88
|
|
|
87
|
-
|
|
89
|
+
// state update function
|
|
90
|
+
const add = (state, value) => state + value;
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<
|
|
92
|
+
// view is a function to display the state (JSX)
|
|
93
|
+
const view = state => <div>
|
|
94
|
+
<h1>{state}</h1>
|
|
95
|
+
<button $onclick={[add, -1]}>-1</button>
|
|
96
|
+
<button $onclick={[add, 1]}>+1</button>
|
|
97
|
+
</div>;
|
|
98
|
+
|
|
99
|
+
// start the app
|
|
100
|
+
app.start(document.body, state, view);
|
|
101
|
+
```
|
|
102
|
+
<apprun-code></apprun-code>
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
One cool feature of AppRun is that you can use async generator functions for event handlers to return multiple values. AppRun will render each value in the order they are generated.
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
const state = {};
|
|
109
|
+
const view = state => html`
|
|
110
|
+
<div><button @click=${run(getComic)}>fetch ...</button></div>
|
|
111
|
+
${state.loading && html`<div>loading ... </div>`}
|
|
112
|
+
${state.comic && html`<img src=${state.comic.img} />`}
|
|
113
|
+
`;
|
|
114
|
+
async function* getComic() { // async generator function returns loading flag and then the comic object
|
|
115
|
+
yield { loading: true };
|
|
116
|
+
const response = await fetch('https://xkcd-api.netlify.app');
|
|
117
|
+
const comic = await response.json();
|
|
118
|
+
yield { comic };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
app.start(document.body, state, view);
|
|
92
122
|
```
|
|
93
|
-
|
|
123
|
+
<apprun-code></apprun-code>
|
|
124
|
+
|
|
125
|
+
And, of course, you can use Components to encapsulate the logic blocks, e.g., SPA pages. Each component can have its own state, view, and update functions. Each component has its own handlers to handle the routing events. AppRun routes `/<path>`, `#<path>`, and `#/<path>` URLs to components. AppRun also does this with [hierarchical routing](docs/requirements/req-hierarchical-routing.md).
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
class Home extends Component {
|
|
129
|
+
view = () => <div>Home</div>;
|
|
130
|
+
update = {'/, /home': state => state };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
class Contact extends Component {
|
|
134
|
+
view = () => <div>Contact</div>;
|
|
135
|
+
update = {'/contact': state => state };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
class About extends Component {
|
|
139
|
+
view = () => <div>About</div>;
|
|
140
|
+
update = {'/about': state => state };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const App = () => <>
|
|
144
|
+
<div id="menus">
|
|
145
|
+
<a href="/home">Home</a>{' | '}
|
|
146
|
+
<a href="/contact">Contact</a>{' | '}
|
|
147
|
+
<a href="/about">About</a></div>
|
|
148
|
+
<div id="pages"></div>
|
|
149
|
+
</>
|
|
150
|
+
|
|
151
|
+
app.render(document.body, <App />);
|
|
152
|
+
[About, Contact, Home].map(C => new C().start('pages'));
|
|
153
|
+
```
|
|
154
|
+
<apprun-code></apprun-code>
|
|
94
155
|
|
|
95
156
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
157
|
+
Finally, you can use AppRun with [React](https://reactjs.org/). The `app.use_react` function allows you to use React for rendering the view.
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
import React from 'react'
|
|
161
|
+
import ReactDOM from 'react-dom/client'
|
|
162
|
+
import { app } from 'apprun';
|
|
163
|
+
app.use_react(React, ReactDOM);
|
|
100
164
|
```
|
|
101
165
|
|
|
102
|
-
|
|
166
|
+
The `app.use_render` function allows you to use a other render library for rendering the view. Enjoy the rich ecosystem of React.
|
|
103
167
|
|
|
104
|
-
|
|
168
|
+
```js
|
|
169
|
+
import { render } from 'preact'
|
|
170
|
+
import { app } from 'apprun';
|
|
171
|
+
app.use_render(render);
|
|
172
|
+
```
|
|
105
173
|
|
|
106
|
-
|
|
174
|
+
There are many more examples and interactive demos available in [the AppRun Playground](https://apprun.js.org/#play).
|
|
107
175
|
|
|
108
|
-
* [Architecture](https://yysun.github.io/apprun/docs/#/?id=architecture)
|
|
109
|
-
* [Event Pub and Sub](https://yysun.github.io/apprun/docs/#/?id=event-pubsubs)
|
|
110
|
-
* [State Management](https://yysun.github.io/apprun/docs/#/?id=state-management)
|
|
111
|
-
* [Virtual DOM](https://yysun.github.io/apprun/docs/#/?id=virtual-dom)
|
|
112
|
-
* [Component](https://yysun.github.io/apprun/docs/#/?id=component)
|
|
113
|
-
* [Routing](https://yysun.github.io/apprun/docs/#/?id=routing)
|
|
114
|
-
* [CLI](https://yysun.github.io/apprun/docs/#/?id=cli)
|
|
115
176
|
|
|
116
|
-
##
|
|
177
|
+
## Getting Started
|
|
117
178
|
|
|
118
|
-
|
|
119
|
-
* [Building Applications with AppRun, Part 2 - Components](https://www.youtube.com/watch?v=qkP6HvZmhtY)
|
|
179
|
+
AppRun is distributed on npm. To get it, run:
|
|
120
180
|
|
|
121
|
-
|
|
181
|
+
```sh
|
|
182
|
+
npm install apprun
|
|
183
|
+
```
|
|
122
184
|
|
|
123
|
-
|
|
124
|
-
* [Deep Dive into AppRun State](https://medium.com/@yiyisun/deep-dive-into-apprun-state-3d6fb58b1521)
|
|
125
|
-
* [Deep Dive into AppRun Events](https://medium.com/@yiyisun/deep-dive-into-apprun-events-1650dc7811ea)
|
|
185
|
+
When you want to do a rapid prototyping or demo, you can use AppRun directly in the browser without JSX or any build step. The `app`, `Component`, `on`, `customElement`, `trustedHTML`, `safeHTML`, `html`, `run`, and `svg` APIs are available globally in the script-tag build. The `html` and `svg` functions are lit templates. The `run` function is equivalent to the `$on` directive and invokes state update functions.
|
|
126
186
|
|
|
187
|
+
```js
|
|
188
|
+
<html>
|
|
189
|
+
<body>
|
|
190
|
+
<script src="https://unpkg.com/apprun/dist/apprun-html.js"></script>
|
|
191
|
+
<script>
|
|
192
|
+
const add = (state, delta) => state + delta;
|
|
193
|
+
const view = state => {
|
|
194
|
+
return html`<div>
|
|
195
|
+
<h1>${state}</h1>
|
|
196
|
+
<button @click=${run(add, -1)}>-1</button>
|
|
197
|
+
<button @click=${run(add, +1)}>+1</button>
|
|
198
|
+
</div>`;
|
|
199
|
+
};
|
|
200
|
+
app.start(document.body, 0, view);
|
|
201
|
+
</script>
|
|
202
|
+
</body>
|
|
203
|
+
</html>
|
|
204
|
+
```
|
|
205
|
+
<apprun-code style="height:200px"></apprun-code>
|
|
127
206
|
|
|
128
|
-
|
|
207
|
+
Or, use the ESM version:
|
|
208
|
+
```js
|
|
209
|
+
<html>
|
|
210
|
+
<body>
|
|
211
|
+
<script type="module">
|
|
212
|
+
import { app, html } from 'https://unpkg.com/apprun/dist/apprun-html.esm.js';
|
|
213
|
+
const view = state => html`<div>${state}</div>`;
|
|
214
|
+
app.start(document.body, 'hello ESM', view);
|
|
215
|
+
</script>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|
|
218
|
+
```
|
|
219
|
+
<apprun-code style="height:200px"></apprun-code>
|
|
129
220
|
|
|
130
|
-
|
|
131
|
-
* [Hacker News Reader](https://github.com/yysun/apprun-hn) - PWA hacker news reader (230 lines)
|
|
132
|
-
* [AppRun Demo App](https://yysun.github.com/apprun) - a SPA that has 8 components, including a [Todo component](https://github.com/yysun/apprun/tree/master/demo/components/todo.tsx) (90 lines)
|
|
221
|
+
In addition to run directly in the browser, you can run the `npm create apprun-app` command to create an AppRun project for using a compiler/bundler like Webpack, esbuild or Vite.
|
|
133
222
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
223
|
+
```sh
|
|
224
|
+
npm create apprun-app [my-app]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Learn More
|
|
228
|
+
|
|
229
|
+
You can read [AppRun Docs](https://apprun.js.org/docs).
|
|
230
|
+
|
|
231
|
+
### AppRun Book from Apress
|
|
232
|
+
|
|
233
|
+
[](https://www.amazon.com/Practical-Application-Development-AppRun-High-Performance/dp/1484240685/)
|
|
234
|
+
|
|
235
|
+
* [Order from Amazon](https://www.amazon.com/Practical-Application-Development-AppRun-High-Performance/dp/1484240685/)
|
|
142
236
|
|
|
143
237
|
|
|
144
238
|
## Contribute
|
|
@@ -155,18 +249,36 @@ npm test
|
|
|
155
249
|
```
|
|
156
250
|
Unit tests can serve as functional specifications.
|
|
157
251
|
|
|
158
|
-
Finally, to build
|
|
252
|
+
Finally, to build the generated package artifacts, run:
|
|
159
253
|
```sh
|
|
160
254
|
npm run build
|
|
161
255
|
```
|
|
162
256
|
|
|
257
|
+
The build writes `dist`, `esm`, `jsx-runtime.js`, and the demo bundle. They are generated artifacts and are intentionally ignored in source commits. `npm pack --dry-run` runs the same build through `prepack` and verifies the files that will be published.
|
|
258
|
+
|
|
163
259
|
Have fun and send pull requests.
|
|
164
260
|
|
|
261
|
+
## Contributors
|
|
262
|
+
[](https://github.com/yysun/apprun/graphs/contributors)
|
|
263
|
+
|
|
264
|
+
## Support
|
|
265
|
+
|
|
266
|
+
AppRun is an MIT-licensed open-source project. Please consider [supporting the project on Patreon](https://www.patreon.com/apprun). 👍❤️🙏
|
|
267
|
+
|
|
268
|
+
### Thank you for your support
|
|
269
|
+
|
|
270
|
+
* Athkahden Asura
|
|
271
|
+
* Alfred Nerstu
|
|
272
|
+
* Gyuri Lajos
|
|
273
|
+
* Lorenz Glißmann
|
|
274
|
+
* Kevin Shi
|
|
275
|
+
* Chancy Kennedy
|
|
276
|
+
|
|
165
277
|
## License
|
|
166
278
|
|
|
167
279
|
MIT
|
|
168
280
|
|
|
169
|
-
Copyright (c) 2015-
|
|
281
|
+
Copyright (c) 2015-2025 Yiyi Sun
|
|
170
282
|
|
|
171
283
|
|
|
172
284
|
[travis-image]: https://travis-ci.org/yysun/apprun.svg?branch=master
|
|
@@ -175,8 +287,11 @@ Copyright (c) 2015-2018 Yiyi Sun
|
|
|
175
287
|
[npm-url]: https://npmjs.org/package/apprun
|
|
176
288
|
[license-image]: https://img.shields.io/:license-mit-blue.svg
|
|
177
289
|
[license-url]: LICENSE.md
|
|
178
|
-
[downloads-image]:
|
|
290
|
+
[downloads-image]: https://img.shields.io/npm/dm/apprun.svg
|
|
179
291
|
[downloads-url]: https://npmjs.org/package/apprun
|
|
180
292
|
|
|
181
293
|
[twitter]: https://twitter.com/intent/tweet?text=Check%20out%20AppRun%20by%20%40yysun%20https%3A%2F%2Fgithub.com%2Fyysun%2Fapprun%20%F0%9F%91%8D%20%40apprunjs
|
|
182
294
|
[twitter-badge]: https://img.shields.io/twitter/url/https/github.com/yysun/apprun.svg?style=social
|
|
295
|
+
|
|
296
|
+
[discord-image]: https://img.shields.io/discord/476903999023480842.svg
|
|
297
|
+
[discord-invite]: https://discord.gg/CETyUdx
|