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.
Files changed (135) hide show
  1. package/CHANGELOG.md +235 -12
  2. package/LICENSE +1 -1
  3. package/README.md +225 -110
  4. package/apprun.d.ts +240 -34
  5. package/cli/app.js +29 -0
  6. package/cli/colors.js +69 -0
  7. package/cli/index.html +13 -0
  8. package/cli/index.js +96 -0
  9. package/dist/apprun-code.js +2 -0
  10. package/dist/apprun-code.js.map +1 -0
  11. package/dist/apprun-dev-tools.js +1 -1
  12. package/dist/apprun-dev-tools.js.map +1 -1
  13. package/dist/apprun-html.esm.js +34 -0
  14. package/dist/apprun-html.esm.js.map +1 -0
  15. package/dist/apprun-html.js +2 -1
  16. package/dist/apprun-html.js.LICENSE.txt +11 -0
  17. package/dist/apprun-html.js.map +1 -1
  18. package/dist/apprun-play.js +2 -0
  19. package/dist/apprun-play.js.map +1 -0
  20. package/dist/apprun.esm.js +2 -0
  21. package/dist/apprun.esm.js.map +1 -0
  22. package/dist/apprun.js +1 -1
  23. package/dist/apprun.js.map +1 -1
  24. package/dist/createState.js +2 -0
  25. package/dist/createState.js.map +1 -0
  26. package/esm/add-components.js +90 -0
  27. package/esm/add-components.js.map +1 -0
  28. package/esm/app.js +209 -0
  29. package/esm/app.js.map +1 -0
  30. package/esm/apprun-code.js +170 -0
  31. package/esm/apprun-code.js.map +1 -0
  32. package/esm/apprun-dev-tools-tests.js +95 -0
  33. package/esm/apprun-dev-tools-tests.js.map +1 -0
  34. package/esm/apprun-dev-tools.js +281 -0
  35. package/esm/apprun-dev-tools.js.map +1 -0
  36. package/esm/apprun-html.js +24 -0
  37. package/esm/apprun-html.js.map +1 -0
  38. package/esm/apprun-play.js +248 -0
  39. package/esm/apprun-play.js.map +1 -0
  40. package/esm/apprun.js +220 -0
  41. package/esm/apprun.js.map +1 -0
  42. package/esm/component.js +413 -0
  43. package/esm/component.js.map +1 -0
  44. package/esm/createState.js +9 -0
  45. package/esm/createState.js.map +1 -0
  46. package/esm/decorator.js +88 -0
  47. package/esm/decorator.js.map +1 -0
  48. package/esm/directive.js +306 -0
  49. package/esm/directive.js.map +1 -0
  50. package/esm/router.js +345 -0
  51. package/esm/router.js.map +1 -0
  52. package/esm/type-utils.js +90 -0
  53. package/esm/type-utils.js.map +1 -0
  54. package/esm/types.js +58 -0
  55. package/esm/types.js.map +1 -0
  56. package/esm/vdom-lit-html.js +65 -0
  57. package/esm/vdom-lit-html.js.map +1 -0
  58. package/esm/vdom-my-prop-attr.js +227 -0
  59. package/esm/vdom-my-prop-attr.js.map +1 -0
  60. package/esm/vdom-my.js +293 -0
  61. package/esm/vdom-my.js.map +1 -0
  62. package/esm/vdom-to-html.js +54 -0
  63. package/esm/vdom-to-html.js.map +1 -0
  64. package/esm/vdom.js +28 -0
  65. package/esm/vdom.js.map +1 -0
  66. package/esm/version.js +15 -0
  67. package/esm/version.js.map +1 -0
  68. package/esm/web-component.js +155 -0
  69. package/esm/web-component.js.map +1 -0
  70. package/jsx-runtime.js +2 -0
  71. package/jsx-runtime.js.map +1 -0
  72. package/package.json +90 -41
  73. package/.travis.yml +0 -10
  74. package/.vscode/launch.json +0 -19
  75. package/BACKERS.md +0 -3
  76. package/apprun-cli.js +0 -177
  77. package/cli-templates/_gitignore +0 -6
  78. package/cli-templates/component.ts_ +0 -16
  79. package/cli-templates/index.html +0 -11
  80. package/cli-templates/karma.conf.js +0 -24
  81. package/cli-templates/main.ts_ +0 -13
  82. package/cli-templates/readme.md +0 -7
  83. package/cli-templates/spa_index.html +0 -14
  84. package/cli-templates/spa_main.ts_ +0 -47
  85. package/cli-templates/spec.ts_ +0 -11
  86. package/cli-templates/tsconfig.json +0 -12
  87. package/cli-templates/webpack.config.js +0 -23
  88. package/demo-html/app.js +0 -2
  89. package/demo-html/app.js.map +0 -1
  90. package/demo-html/counter-c.html +0 -29
  91. package/demo-html/counter-wc-event.html +0 -29
  92. package/demo-html/counter-wc.html +0 -29
  93. package/demo-html/counter.html +0 -26
  94. package/demo-html/index.html +0 -14
  95. package/demo-html/main.tsx +0 -31
  96. package/docs/README.md +0 -326
  97. package/docs/index.html +0 -23
  98. package/index.html +0 -85
  99. package/logo.png +0 -0
  100. package/src/app.ts +0 -69
  101. package/src/apprun-dev-tools.tsx +0 -67
  102. package/src/apprun-html.ts +0 -13
  103. package/src/apprun.ts +0 -53
  104. package/src/component.ts +0 -189
  105. package/src/createComponent.tsx +0 -38
  106. package/src/decorator.ts +0 -36
  107. package/src/router.ts +0 -19
  108. package/src/types.ts +0 -9
  109. package/src/vdom-html.ts +0 -17
  110. package/src/vdom-my.ts +0 -191
  111. package/src/vdom-to-html.tsx +0 -45
  112. package/src/vdom.ts +0 -7
  113. package/src/web-component.ts +0 -29
  114. package/tests/app-rx.spec_ +0 -41
  115. package/tests/app.spec.ts +0 -122
  116. package/tests/application.spec.tsx +0 -23
  117. package/tests/component.spec.tsx +0 -296
  118. package/tests/custom-element.spec.tsx +0 -19
  119. package/tests/data-attr.spec.tsx +0 -42
  120. package/tests/decorator.spec.tsx +0 -104
  121. package/tests/fragment.spec.tsx +0 -79
  122. package/tests/hyperscript.spec.ts +0 -43
  123. package/tests/node-test.js +0 -7
  124. package/tests/router.spec.ts +0 -69
  125. package/tests/stateful-component.spec.tsx +0 -248
  126. package/tests/typed.spec.tsx +0 -63
  127. package/tests/vdom-html.spec.ts +0 -35
  128. package/tests/vdom-jsx.spec.tsx +0 -131
  129. package/tests/vdom-my.spec.tsx +0 -195
  130. package/tests/view-engine.spec.js +0 -59
  131. package/tsconfig.json +0 -11
  132. package/tslint.json +0 -124
  133. package/typescriptreact.json +0 -87
  134. package/viewEngine.js +0 -54
  135. package/webpack.config.js +0 -30
@@ -1,31 +0,0 @@
1
-
2
- import app, { Component } from '../src/apprun';
3
- declare var customElements;
4
- class MyApp extends Component {
5
- // state = 0/
6
-
7
- view = (state) => {
8
- return <div><h1>{state}</h1></div>
9
- }
10
-
11
- update = {
12
- '-1': (state) => state - 1,
13
- '+1': (state) => state + 1
14
- }
15
-
16
- children;
17
- rendered = state => {
18
- this.children.forEach(el => {
19
- this.element.firstElementChild.appendChild(el)
20
- });
21
- this.element.setAttribute('num', state);
22
- }
23
-
24
- constructor({ num, children } ) {
25
- super();
26
- this.children = children;
27
- this.state = parseInt(num);
28
- }
29
- }
30
-
31
- app.webComponent('my-app', MyApp);
package/docs/README.md DELETED
@@ -1,326 +0,0 @@
1
- # Building Applications with AppRun
2
-
3
- AppRun is a 3K library for building applications using the [elm architecture](https://guide.elm-lang.org/architecture) and event publication and subscription.
4
-
5
- ## Architecture
6
-
7
- According to the elm architecture, there are three separated parts in an application.
8
-
9
- * Model — the data model of your application state
10
- * Update — a set of functions to update the state
11
- * View — a function to display the state as HTML
12
-
13
- The 15 lines of code below is a simple counter application demonstrates the architecture using AppRun.
14
-
15
- ```
16
- const state = 0;
17
-
18
- const view = state => {
19
- return `<div>
20
- <h1>${state}</h1>
21
- <button onclick='app.run("-1")'>-1</button>
22
- <button onclick='app.run("+1")'>+1</button>
23
- </div>`;
24
- };
25
-
26
- const update = {
27
- '+1': state => state + 1,
28
- '-1': state => state - 1
29
- };
30
-
31
- app.start('my-app', state, view, update);
32
- ```
33
-
34
- ### The Model
35
-
36
- The model can be any data structure, a number, an array, or an object that reflects the state of the application. In the counter example, it is a number.
37
- ```
38
- const state = 0;
39
- ```
40
-
41
- ### The Update
42
-
43
- The update contains functions that take existing state and create new states.
44
- ```
45
- const update = {
46
- '+1': state => state + 1,
47
- '-1': state => state - 1
48
- }
49
- ```
50
-
51
- ### The View
52
-
53
- The view generates HTML based on the state. AppRun parses the HTML string into virtual dom. It then calculates the differences against the web page element and renders the changes.
54
-
55
- ```
56
- const view = state => {
57
- return `<div>
58
- <h1>${state}</h1>
59
- <button onclick='app.run("-1")'>-1</button>
60
- <button onclick='app.run("+1")'>+1</button>
61
- </div>`;
62
- };
63
- ```
64
-
65
- ### Trigger the Update
66
-
67
- AppRun exposes a global object named _app_ that is accessible globally to trigger the Update by calling _app.run_ function.
68
- ```
69
- app.run('+1');
70
- ```
71
- The web page programming is event driven. Connecting web events to AppRun events, you can trigger update functions from user input, click, navigation and etc.
72
-
73
- E.g. call _app.run_ in HTML markup directly:
74
- ```
75
- <button id="inc" onclick="app.run('+1')">+1</button>
76
- ```
77
- Or in JavaScript:
78
- ```
79
- document.getElementById('inc').addEventListener('click',
80
- () => app.run('+1'));
81
- ```
82
- Or with JSX:
83
- ```
84
- <button onclick={()=>app.run("+1")}>+1</button>
85
- ```
86
- Or even with jQuery:
87
- ```
88
- $('#inc').on('click', ()=>app.run('+1'));
89
- ```
90
-
91
- Finally, _app.start_ function from AppRun ties State, View and Update together to an element and starts the application.
92
- ```
93
- const element = document.getElementById('my-app');
94
- app.start(element, State, view, update);
95
- ```
96
-
97
- To summarize above, the two functions from AppRun (_app.run_ and _app.start_) are all you need to make an application of elm architecture.
98
-
99
- Try the counter example online: [Simple Counter](https://jsfiddle.net/ap1kgyeb/4).
100
-
101
- ## Event PubSubs
102
-
103
- At the core, AppRun is an event publication and subscription system, which is also known as event emitter. It is a commonly used pattern in JavaScript programming.
104
-
105
- AppRun has two important functions: _app.run_ and _app.on_. _app.run_ fires events.
106
- _app.on_ handles events. E.g. :
107
-
108
- Module A subscribes to an event _print_:
109
- ```
110
- import app from 'apprun';
111
- export () => app.on('print', e => console.log(e));
112
- ```
113
- Module B publishes the event _print_:
114
- ```
115
- import app from 'apprun';
116
- export () => app.run('print', {});
117
- ```
118
- Main Module:
119
- ```
120
- import a from './A';
121
- import b from './B';
122
- a();
123
- b();
124
- ```
125
- Module A and Module B only have to know the event system, not other modules, so they are only dependent on the event system, not other modules. Therefore modules are decoupled. Thus makes it easier to modify, extend and swap modules.
126
-
127
- The most significant benefit of such event system is decoupling. In traditional MVC architecture, the model, view and controller are coupled, which makes it difficult to test and maintain. In result, there are many architecture patterns have been developed to solve the coupling problem, such as Model-View-Presenter, Presentation Model, and Model-View-ViewModel. AppRun solved the coupling problem by using event publication and subscription. Model, View and Controller/Update don't know each.
128
-
129
- AppRun applications have an event cycle like below:
130
-
131
- ```
132
- Web events => AppRun Events => Update => (new state) => View => (HTML)
133
- ```
134
-
135
- Behind scene AppRun events trigger update functions; the update functions create new states; AppRun then let view function turn the new state into HTML or virtual DOM. Finally AppRun renders the HTML or virtual DOM to web page element.
136
-
137
- ## State Management
138
-
139
- During the event cycle, AppRun manages application states. It passes current state into the update functions. It takes the new state from the update functions and passes into the view function. Therefore it can maintain the history of all states, which enables the time travel / undo-redo feature.
140
-
141
- In leverage the time travel / undo-redo feature, the update functions must make sure current state immutable and always create a new state.
142
-
143
- See the multiple counter example that has undo-redo online: [Multiple counters](https://jsfiddle.net/ap1kgyeb/6)
144
-
145
-
146
- ## Virtual DOM
147
-
148
- When applications get complex, we start to think performance and build system.
149
-
150
- In the simple counter example above, the View creates HTML string out of the state.
151
- Although HTML string is easy to understand and useful for trying out ideas, it takes
152
- time to parse it into virtual dom at run time, which may cause performance issue.
153
- It also has some problems that have been documented by the Facebook React team:
154
- [Why not template literals](http://facebook.github.io/jsx/#why-not-template-literals).
155
-
156
- Using JSX, the JSX compiler compiles the JSX into functions at compile time. The View function creates virtual dom in runtime directly without parsing HTML, which gives
157
- better performance. Therefore, we recommend using JSX in production.
158
-
159
- To compile and build production code, we recommend using TypeScript and webpack. See CLI section below.
160
-
161
-
162
- ## Component
163
-
164
- Another thing to consider when applications get complex is to divide and organize code into components.
165
-
166
- A component in AppRun is a mini elm architecture, which means inside a component, there are model, view and update. Let's use _AppRun CLI_ to generate a component.
167
-
168
- ```
169
- apprun -c Counter
170
- ```
171
-
172
- It generates a Counter component:
173
- ```
174
- import app, {Component} from 'apprun';
175
-
176
- export default class CounterComponent extends Component {
177
- state = 'Counter';
178
- view = state => {
179
- return <div>
180
- <h1>{state}</h1>
181
- </div>
182
- }
183
- update = {
184
- '#Counter': state => state,
185
- }
186
- }
187
- ```
188
-
189
- To use the Counter component, create an instance of it and then mount the instance to an element.
190
-
191
- ```
192
- import Counter from './Counter';
193
- const element = document.getElementById('my-app');
194
- new Counter().mount(element);
195
- ```
196
-
197
- Notice the update has a '#Counter' function. It is a route. See Routing section below.
198
-
199
- ### Pure Function Component
200
-
201
- Pure Function Component is fully supported. Make sure the function name is capitalized.
202
-
203
- ```
204
- const Counter = ({num, idx}) => (
205
- <div>
206
- <h1>{num}</h1>
207
- <button onclick={() => app.run("-1", idx)}>-1</button>
208
- <button onclick={() => app.run("+1", idx)}>+1</button>
209
- <button onclick={() => app.run("remove-counter", idx)}>x</button>
210
- </div>
211
- );
212
-
213
- const CounterList = ({counters}) => counters.map((num, idx) =>
214
- <Counter num={num} idx={idx} />
215
- );
216
-
217
- const view = state => {
218
- console.log(state);
219
- return (
220
- <div>
221
- <div>
222
- <button onclick={() => app.run("add-counter")}>add counter</button>
223
- <button onclick={() => app.run("remove-counter", state.length-1)} disabled={state.length <= 0}>remove counter</button>
224
- </div>
225
- <br/>
226
- <CounterList counters={state} />
227
- </div>);
228
- };
229
- ```
230
-
231
- ### Child Stateful Component
232
-
233
- (Working in progress)
234
-
235
- ```
236
- class TestComponent extends Component {
237
- state = '';
238
- view = state => <div>{state}</div>
239
- update = { }
240
- constructor({ id }) {
241
- super();
242
- }
243
- }
244
-
245
- class MainComponent extends Component {
246
- view = state => {
247
- return <div>
248
- <TestComponent id = 'c1' />
249
- <TestComponent id = 'c2' />
250
- <TestComponent id = 'c3'/>
251
- </div>
252
- }
253
- }
254
-
255
- new MainComponent().start('my-app');
256
- ```
257
-
258
- ### Update function Decorator
259
-
260
- In AppRun, there are two decorators to make the update functions easier to write and read in component. _@update_ and _@on_. _@update_ is for class functions. _@on_ is for class properties.
261
-
262
- ```
263
- class TestComponent extends Component {
264
- view = state => state
265
-
266
- // function decorator
267
- @update('hi, #hi')
268
- f2(state, val) {
269
- return val;
270
- }
271
-
272
- // property decorator
273
- @on('hi2, #hi2')
274
- f2 = (state, val) => val
275
- }
276
- ```
277
-
278
- ## Routing
279
-
280
- Because AppRun can connect web page events to AppRun Event, handling routing becomes much easier. AppRun detects the hash changes in URL and calls update functions by matching the hash. E.g., when URL in the browser address bar becomes http://..../#Counter, The #Couter update function of the component will run.
281
-
282
- Each component defines its route in an update function. The URL changes trigger and run the update function. It can avoid a lot of code for registering and matching routes like in the other frameworks and libraries.
283
-
284
-
285
- ## CLI
286
-
287
- AppRun includes a cli. To install AppRun CLI:
288
-
289
- ```
290
- npm install apprun -g
291
- ```
292
-
293
- AppRun CLI can:
294
-
295
- * Initialize a TypeScript and webpack configured project
296
- * Initialize git repository
297
- * Add Jest unit test
298
- * Generate component
299
- * Generate SPA application
300
-
301
- Let's initialize a SPA project.
302
-
303
- ```
304
- apprun -i --spa
305
- ```
306
-
307
- The apprun -i command installs apprun, webpack, webpack-dev-server and typescript. It also generates files: tsconfig.json, webpack.config.js, index.html and main.tsx.
308
-
309
- The apprun --spa command generates files: index.html, main.tsx and three components: Home, About and Contact.
310
-
311
- After the command finishes execution, you can start the application and then navigate to https://localhost:8080 in a browser.
312
-
313
- ```
314
- npm start
315
- ```
316
-
317
- ## Performance
318
-
319
- AppRun itself is lightweight. It is about 3K gzipped. More important is that applications built with AppRun have less line of code, smaller js file, and better performance.
320
- See a comparison from [A Real-World Comparison of Front-End Frameworks with Benchmarks](https://medium.freecodecamp.org/a-real-world-comparison-of-front-end-frameworks-with-benchmarks-e1cb62fd526c).
321
-
322
- AppRun has also joined the [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) project. You can see its [performance results](https://rawgit.com/krausest/js-framework-benchmark/master/webdriver-ts-results/table.html) compared to other frameworks and libraries.
323
-
324
-
325
- AppRun makes your applications clean, precious, declarative and has no ceremony.
326
- Please give it a try and send pull requests.
package/docs/index.html DELETED
@@ -1,23 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
7
- <title>AppRun</title>
8
- <link rel="stylesheet" href="https://unpkg.com/docute@3/dist/docute.css">
9
- </head>
10
- <body>
11
- <div id="app"></div>
12
- <script src="https://unpkg.com/docute@3/dist/docute.js"></script>
13
- <script>
14
- docute.init({
15
- // sidebar: false,
16
- nav: [
17
- {title: 'Home', path: '/'},
18
- {title: 'Github', path: 'https://github.com/yysun/apprun'}
19
- ]
20
- })
21
- </script>
22
- </body>
23
- </html>
package/index.html DELETED
@@ -1,85 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
6
- <title>AppRun Examples</title>
7
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
8
- integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
9
- <link rel="stylesheet" type="text/css" href="demo/styles.css">
10
- </head>
11
- <body>
12
- <!-- navbar -->
13
- <nav class="navbar navbar-default">
14
- <div class="container">
15
- <div class="navbar-header">
16
- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
17
- <span class="sr-only">Toggle navigation</span>
18
- <span class="icon-bar"></span>
19
- <span class="icon-bar"></span>
20
- <span class="icon-bar"></span>
21
- </button>
22
- <a class="navbar-brand" href="#">AppRun</a>
23
- </div>
24
- <div id="navbar" class="navbar-collapse collapse">
25
- <ul class="nav navbar-nav">
26
- <!--<li class="active"><a href="#">Home</a></li>-->
27
- <li class="dropdown">
28
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">Hello
29
- <span class="caret"></span></a>
30
- <ul class="dropdown-menu">
31
- <li><a href="#hello">Hello World</a></li>
32
- <li><a href="#hello-pushstate">Hello World - Push State</a></li>
33
- <li><a href="#hello-delayed">Hello World - Delayed</a></li>
34
- <li><a href="#hello-directive">Hello World - Directive</a></li>
35
- </ul>
36
- </li>
37
- <li class="dropdown">
38
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">Counter
39
- <span class="caret"></span></a>
40
- <ul class="dropdown-menu">
41
- <li><a href="#counter">Simple Counter</a></li>
42
- <li><a href="#counters">Multiple Counters</a></li>
43
- </ul>
44
- </li>
45
- <li><a href="#blade">Blade</a></li>
46
- <li><a href="#dragdrop">Drag</a></li>
47
- <li><a href="#todo">Todo</a></li>
48
- <li><a href="#multi-selection">Type-ahead</a></li>
49
- <li><a href="#benchmark">Benchmark</a></li>
50
-
51
- <li class="dropdown">
52
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">More
53
- <span class="caret"></span></a>
54
- <ul class="dropdown-menu">
55
- <li><a href="https://yysun.github.io/apprun-hn">Hacker News Reader</a></li>
56
- <li><a href="https://github.com/gothinkster/apprun-realworld-example-app">RealWorld Example App</a></li>
57
- <li><a href="https://github.com/yysun/apprun-ssr">Server-Side Rendering</a></li>
58
- <li><a href="https://github.com/yysun/apprun-multilingual">Multilingual Example</a></li>
59
- <li><a href="https://github.com/yysun/apprun-firebase-authentication">Firebase Authentication</a></li>
60
- <li><a href="https://github.com/yysun/apprun-dynamic-components">Dynamic Module Import</a></li>
61
- <li><a href="https://github.com/yysun/apprun-hot-module-reload">Hot Module Reload with Webpack</a></li>
62
- <li><a href="https://github.com/yysun/apprun-parcel-bundler">Use Parcel</a></li>
63
- </ul>
64
- </li>
65
- </ul>
66
- <ul class="nav navbar-nav navbar-right">
67
- <li><a href="https://github.com/yysun/apprun">Github</a></li>
68
- </ul>
69
- </div><!--/.nav-collapse -->
70
- </div>
71
- </nav>
72
-
73
- <div class="container">
74
- <div id="my-app"></div>
75
- </div> <!-- /container -->
76
-
77
- <script src="https://code.jquery.com/jquery-3.1.1.min.js"
78
- integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
79
-
80
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
81
- integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
82
-
83
- <script src="demo/app.js"></script>
84
- </body>
85
- </html>
package/logo.png DELETED
Binary file
package/src/app.ts DELETED
@@ -1,69 +0,0 @@
1
- export class App {
2
-
3
- private _events: Object;
4
-
5
- public start;
6
- public createElement;
7
- public render;
8
- public Fragment;
9
- public webComponent;
10
-
11
- constructor() {
12
- this._events = {};
13
- }
14
-
15
- on(name: string, fn: (...args) => void, options: any = {}) {
16
- this._events[name] = this._events[name] || [];
17
- this._events[name].push({ fn: fn, options: options });
18
- }
19
-
20
- off(name: string, fn: (...args) => void) {
21
- let subscribers = this._events[name];
22
- if (subscribers) {
23
- subscribers = subscribers.filter((sub) => sub.fn !== fn);
24
- if (subscribers.length) this._events[name] = subscribers;
25
- else delete this._events[name]
26
- }
27
- }
28
-
29
- run(name: string, ...args) {
30
- let subscribers = this._events[name];
31
- console.assert(!!subscribers, 'No subscriber for event: ' + name);
32
- if (subscribers) {
33
- subscribers = subscribers.filter((sub) => {
34
- const { fn, options } = sub;
35
- if (options.delay) {
36
- this.delay(name, fn, args, options);
37
- } else {
38
- fn.apply(this, args);
39
- }
40
- return !sub.options.once;
41
- });
42
- if (subscribers.length) this._events[name] = subscribers;
43
- else delete this._events[name]
44
- }
45
- }
46
-
47
- once(name: string, fn, options: any = {}) {
48
- this.on(name, fn, { ...options, once: true });
49
- }
50
-
51
- private delay(name, fn, args, options) {
52
- if (options._t) clearTimeout(options._t);
53
- options._t = setTimeout(() => {
54
- clearTimeout(options._t);
55
- fn.apply(this, args);
56
- }, options.delay);
57
- }
58
- }
59
-
60
- let app: App;
61
- declare var global;
62
- const root = global || window;
63
- if (root['app'] && root['app']['start']) {
64
- app = root['app'];
65
- } else {
66
- app = new App();
67
- root['app'] = app;
68
- }
69
- export default app;
@@ -1,67 +0,0 @@
1
- import app from './app';
2
- import toHTML from './vdom-to-html';
3
-
4
- const log = p => console.log(p);
5
- let debug = false;
6
-
7
- window['_debug'] = (on) => {
8
- on ? !debug && app.on('debug', log) : debug && app.off('debug', log);
9
- debug = on;
10
- }
11
-
12
- function newWin(html) {
13
- const newWin = window.open('', '_apprun_debug', 'toolbar=0');
14
- newWin.document.write(`<html>
15
- <title>AppRun Analyzer | ${document.location.href}</title>
16
- <style>
17
- body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI" }
18
- li { margin-left: 30px; }
19
- </style>
20
- <body>
21
- <div id="main">${html}</div>
22
- </script>
23
- </body>
24
- </html>`);
25
- newWin.document.close();
26
- }
27
-
28
- const Events = ({ events }) => <ul>
29
- {events && events
30
- .sort(((a, b) => a.name > b.name ? 1 : -1))
31
- .map(event => <li>
32
- {event.name}
33
- </li>)}
34
- </ul>;
35
-
36
- const Components = ({ components }) => <ul>
37
- {components.map(component => <li>
38
- <div>{component.constructor.name}</div>
39
- <Events events={component['_actions']} />
40
- </li>)}
41
- </ul>;
42
-
43
- const view = state => <ul>
44
- {Object.keys(state).map(name =><li>
45
- <div>#{name}</div>
46
- <Components components={state[name]} />
47
- </li>)}
48
- </ul>
49
-
50
- window['_components'] = (print) => {
51
- const o = { components: {} };
52
- app.run('get-components', o);
53
- const { components } = o;
54
- if (print) {
55
- const vdom = view(components);
56
- newWin(toHTML(vdom));
57
- } else {
58
- Object.keys(components).forEach(el => {
59
- const element = typeof el === 'string' ? document.getElementById(el) : el;
60
- const comps = components[el].map(component => ({
61
- component,
62
- events: component['_actions'].sort(((a, b) => a.name > b.name ? 1 : -1)).map(e => e.name),
63
- }));
64
- console.log(element, comps);
65
- });
66
- }
67
- }
@@ -1,13 +0,0 @@
1
- import app, { Component, View, Action, Update, on, update } from './apprun'
2
- import { createElement, render, Fragment } from './vdom-html';
3
-
4
- app.createElement = createElement;
5
- app.render = render;
6
- app.Fragment = Fragment;
7
-
8
- export default app;
9
- export { Component, View, Action, Update, on, update };
10
-
11
- if (typeof window === 'object') {
12
- window['Component'] = Component;
13
- }
package/src/apprun.ts DELETED
@@ -1,53 +0,0 @@
1
- import app from './app';
2
- import { createElement, render, Fragment } from './vdom';
3
- import { Component } from './component';
4
- import { VNode, View, Action, Update } from './types';
5
- import { on, update } from './decorator';
6
- import route from './router';
7
- import webComponent from './web-component';
8
-
9
- export interface IApp {
10
- start<T>(element?: Element | string, model?: T, view?: View<T>, update?: Update<T>,
11
- options?: { history?, rendered?: (state: T) => void}): Component<T>;
12
- on(name: string, fn: (...args: any[]) => void, options?: any): void;
13
- off(name: string, fn: (...args: any[]) => void): void;
14
- run(name: string, ...args: any[]): void;
15
- createElement(tag: string | Function, props, ...children): VNode | VNode[];
16
- render(element: HTMLElement, node: VNode): void;
17
- Fragment(props, ...children): any[];
18
- webComponent(name: string, componentClass, options?): void;
19
- }
20
-
21
- app.createElement = createElement;
22
- app.render = render;
23
- app.Fragment = Fragment;
24
- app.webComponent = webComponent;
25
-
26
- app.start = <T>(element?: HTMLElement | string, model?: T, view?: View<T>, update?: Update<T>,
27
- options?: { history?, rendered?: (state: T) => void }) : Component<T> => {
28
- const opts = Object.assign(options || {}, { render: true, global_event: true });
29
- const component = new Component<T>(model, view, update);
30
- if (options && options.rendered) component.rendered = options.rendered;
31
- component.mount(element, opts);
32
- return component;
33
- };
34
-
35
- if (!app['route']) {
36
- app['route'] = route;
37
- app.on('//', _ => { });
38
- app.on('#', _ => { });
39
- app.on('route', url => route(url));
40
- if (typeof document === 'object') {
41
- document.addEventListener("DOMContentLoaded", () => {
42
- window.onpopstate = () => route(location.hash);
43
- route(location.hash);
44
- });
45
- }
46
- }
47
-
48
- export type StatelessComponent<T={}> = (args: T) => string | VNode | void;
49
- export { Component, View, Action, Update, on, update };
50
- export { update as event };
51
- export default app as IApp;
52
-
53
- app.on('debug', _ => 0);