literaljs 8.0.3 → 8.0.5

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/README.md CHANGED
@@ -1,49 +1,55 @@
1
1
  <p align="center">
2
- <img src="literalJS.png" alt="LiteralJS Logo">
2
+ <img src="literalJS.png" alt="LiteralJS Logo" width="400">
3
3
  </p>
4
4
 
5
- ---
6
-
7
- # LiteralJS
8
-
9
- ### A small, fast JavaScript library for building reactive user interfaces.
5
+ <p align="center">
6
+ <strong>A small, fast JavaScript library for building reactive user interfaces.</strong><br>
7
+ Zero dependencies. 4.5 kB gzipped. Modern browsers.
8
+ </p>
10
9
 
11
- **v8.0.0** — Zero runtime dependencies. Modern browser targets (Chrome 90+, Firefox 90+, Safari 14+).
10
+ <p align="center">
11
+ <a href="#quick-start">Quick Start</a> · <a href="#component-api">Components</a> · <a href="#state-management">State</a> · <a href="#architecture">Architecture</a> · <a href="https://literaljs.com">Website</a>
12
+ </p>
12
13
 
13
14
  ---
14
15
 
15
16
  ## Quick Start
16
17
 
17
- ### npm
18
+ ### Install
18
19
 
19
20
  ```bash
20
21
  npm install literaljs
21
22
  ```
22
23
 
23
- ```js
24
+ ### Hello World
25
+
26
+ ```jsx
24
27
  /** @jsx h */
25
28
  import { h, component, App } from 'literaljs';
26
29
 
27
- const Hello = component({
28
- name: 'Hello',
30
+ const Counter = component({
31
+ name: 'Counter',
29
32
  state: { count: 0 },
33
+ methods() {
34
+ return {
35
+ increment() {
36
+ this.setState({ count: this.getState().count + 1 });
37
+ }
38
+ };
39
+ },
30
40
  render() {
31
- const { count } = this.getState();
32
41
  return (
33
- <div>
34
- <p>Count: {count}</p>
35
- <button events={{ click: () => this.setState({ count: count + 1 }) }}>
36
- Increment
37
- </button>
38
- </div>
42
+ <button events={{ click: () => this.increment() }}>
43
+ Count: {this.getState().count}
44
+ </button>
39
45
  );
40
46
  }
41
47
  });
42
48
 
43
- new App(Hello, {}).mount('app');
49
+ new App(Counter, {}).mount('app');
44
50
  ```
45
51
 
46
- > **JSX setup**: Configure your build tool to use `h` as the JSX pragma. Babel example:
52
+ > **JSX setup**: Configure your build tool to use `h` as the pragma:
47
53
  > ```json
48
54
  > { "plugins": [["@babel/plugin-transform-react-jsx", { "pragma": "h" }]] }
49
55
  > ```
@@ -51,10 +57,10 @@ new App(Hello, {}).mount('app');
51
57
  ### CDN (UMD)
52
58
 
53
59
  ```html
54
- <script src="https://unpkg.com/literaljs/build/index.umd.js"></script>
60
+ <script src="https://unpkg.com/literaljs@8/build/index.umd.js"></script>
55
61
  <script>
56
62
  const { h, component, App } = LiteralJS;
57
- // ...same as above
63
+ // same as above
58
64
  </script>
59
65
  ```
60
66
 
@@ -64,188 +70,340 @@ new App(Hello, {}).mount('app');
64
70
 
65
71
  | Export | Purpose |
66
72
  |--------|---------|
67
- | `h(tag, attrs, ...children)` | Create VNode (Hyperscript/Object syntax, or JSX pragma) |
68
- | `component(config)` | Define a component with state, methods, lifecycle |
69
- | `new App(rootComponent, initialStore)` | Create an app instance |
70
- | `app.mount(domId)` | Mount to a DOM element |
71
- | `app.unmount()` | Remove from DOM and clean up |
72
- | `app.setStore(updates)` | Update global store |
73
+ | `h(tag, attrs, ...children)` | Create a VNode (use as JSX pragma, Hyperscript, or plain object) |
74
+ | `component(config)` | Define a component with state, methods, and lifecycle |
75
+ | `new App(rootComponent, initialStore)` | Create an isolated app instance |
76
+ | `app.mount(domId)` | Mount to a DOM element by ID |
77
+ | `app.unmount()` | Remove from DOM, clean up events and state |
78
+ | `app.update()` | Force a re-render |
79
+ | `app.setStore(updater)` | Update the global store |
80
+ | `app.getStore()` | Read the global store |
73
81
  | `render(rootComponent, domId, store)` | Legacy one-liner (backward-compatible) |
82
+ | `StateManager` | Standalone state manager (for testing) |
83
+ | `generateUUID` | UUID generator |
84
+ | `advanceRenderCycle` | Advance the render cycle counter (testing) |
74
85
 
75
86
  ---
76
87
 
77
- ## Architecture Highlights
88
+ ## Component API
78
89
 
79
- ### v8 Performance Features
90
+ ```jsx
91
+ const MyComponent = component({
92
+ name: 'MyComponent', // Component name (for debugging and state keys)
93
+ state: { count: 0 }, // Initial component state
94
+ methods() { // Bound methods available as this.methodName
95
+ return {
96
+ increment() {
97
+ this.setState({ count: this.getState().count + 1 });
98
+ }
99
+ };
100
+ },
101
+ mounted() { // Called after first render
102
+ console.log('Mounted!');
103
+ },
104
+ updated() { // Called after re-render
105
+ console.log('Updated!');
106
+ },
107
+ unmounted() { // Called when removed from DOM
108
+ console.log('Cleaned up!');
109
+ },
110
+ render() { // Returns a VNode tree
111
+ const { count } = this.getState();
112
+ return (
113
+ <div>
114
+ <p>Count: {count}</p>
115
+ <button events={{ click: () => this.increment() }}>
116
+ Increment
117
+ </button>
118
+ </div>
119
+ );
120
+ }
121
+ });
122
+ ```
123
+
124
+ ### Props
125
+
126
+ Pass data down from parent to child:
127
+
128
+ ```jsx
129
+ // Parent
130
+ <MyComponent key="unique" title="Hello" count={5} />
131
+
132
+ // Child
133
+ render() {
134
+ return <h1>{this.props.title} — {this.props.count}</h1>;
135
+ }
136
+ ```
137
+
138
+ ### Sibling Components (Auto-Keyed)
139
+
140
+ **You don't need explicit `key` props for sibling components.** LiteralJS automatically assigns stable, position-based instance keys so each sibling gets isolated state:
141
+
142
+ ```jsx
143
+ const Counter = component({
144
+ name: 'Counter',
145
+ state: { count: 0 },
146
+ methods() {
147
+ return {
148
+ increment() { this.setState({ count: this.getState().count + 1 }); }
149
+ };
150
+ },
151
+ render() {
152
+ return <span>{this.getState().count}</span>;
153
+ }
154
+ });
155
+
156
+ const App = component({
157
+ name: 'App',
158
+ render() {
159
+ // Each Counter has its own independent state — no key prop needed
160
+ return (
161
+ <div>
162
+ <Counter /> {/* auto-key: __auto_0__ */}
163
+ <Counter /> {/* auto-key: __auto_1__ */}
164
+ <Counter /> {/* auto-key: __auto_2__ */}
165
+ </div>
166
+ );
167
+ }
168
+ });
169
+ ```
170
+
171
+ > **How it works**: Each render cycle, component factories reset a position counter. The first keyless sibling gets `__auto_0__`, the second `__auto_1__`, etc. Because the counter resets each render, the same position always maps to the same key — so state persists across re-renders while remaining isolated between siblings.
172
+
173
+ You can still use explicit `key` props when you need semantic identity (e.g., for list items that reorder):
174
+
175
+ ```jsx
176
+ {items.map(item => (
177
+ <ListItem key={item.id} item={item} />
178
+ ))}
179
+ ```
180
+
181
+ ### Lifecycle Hooks
182
+
183
+ | Hook | Called When | Use Case |
184
+ |------|------------|----------|
185
+ | `mounted()` | After first DOM render | Initialize third-party libs, DOM queries |
186
+ | `updated()` | After re-render | React to prop changes, DOM measurements |
187
+ | `unmounted()` | Before DOM removal | Clean up timers, event listeners, subscriptions |
188
+
189
+ ### Component Instance Methods
190
+
191
+ | Method | Description |
192
+ |--------|-------------|
193
+ | `this.getState()` | Shallow copy of component state |
194
+ | `this.setState(updater)` | Update state and trigger re-render |
195
+ | `this.getStore()` | Shallow copy of global store |
196
+ | `this.setStore(updater)` | Update global store and trigger re-render |
197
+ | `this.props` | Current component props |
198
+
199
+ ---
200
+
201
+ ## State Management
80
202
 
81
- - **Keyed reconciliation** `key` attribute preserves DOM identity across reordering
82
- - **WeakMap event delegation** — Fast path skips ancestor walk when no handlers exist
83
- - **Component render memoization** Shallow props comparison skips re-execution when props unchanged
84
- - **Text node fast path** — Updates `textContent` in-place instead of `replaceChild`
85
- - **Reference-equality short-circuits** — Skips diffing for unchanged VNodes, children, and attributes
86
- - **Deferred patching** DOM mutations complete before content patches for consistent state
203
+ ### Component State (private, isolated)
204
+
205
+ Each component instance has its own private state. Sibling instances do not share state:
206
+
207
+ ```js
208
+ this.getState(); // Read current state (shallow copy)
209
+ this.setState({ count: 5 }); // Update and re-render
210
+ ```
211
+
212
+ ### Global Store (shared across components)
213
+
214
+ ```js
215
+ // Write
216
+ this.setStore({ theme: 'dark' });
217
+
218
+ // Read
219
+ const theme = this.getStore().theme;
220
+ ```
221
+
222
+ Initialize the store when creating the app:
223
+
224
+ ```js
225
+ new App(RootComponent, { theme: 'light', user: null }).mount('app');
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Keys and Reconciliation
231
+
232
+ ### Auto-Keys (v8.0.4+)
233
+
234
+ LiteralJS automatically assigns position-based keys to sibling components. You don't need to add `key` props unless you need semantic identity for reordering.
235
+
236
+ ### Explicit Keys
237
+
238
+ Use explicit `key` props when:
239
+ - List items can be reordered (keyed reconciliation tracks DOM identity)
240
+ - You want to force a component to remount when data changes
241
+
242
+ ```jsx
243
+ {items.map(item => (
244
+ <TodoItem key={item.id} item={item} />
245
+ ))}
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Architecture
251
+
252
+ ### Design Principles
253
+
254
+ - **Zero runtime dependencies** — only dev dependencies for builds and tests
255
+ - **Small surface area** — 9 exports, one component pattern, one state model
256
+ - **Plain functions** — no classes, no hooks, no decorators, no magic
257
+ - **Isolated instances** — multiple `App` instances on one page, zero globals
87
258
 
88
259
  ### Module Structure
89
260
 
90
261
  ```
91
262
  App (container)
92
- ├── StateManager — global store + component state
93
- ├── EventManager — WeakMap delegation + event cache
94
- ├── Renderer — DOM creation + virtual DOM diff/patch
95
- ├── LifecycleQueue — mounted/updated/unmounted hooks
96
- ├── DiffEngine — keyed + non-keyed child reconciliation
97
- └── MountOrchestrator tree generation + render cycle
263
+ ├── StateManager — global store + component state with subscriptions
264
+ ├── EventManager — WeakMap delegation + event cache
265
+ ├── Renderer — DOM creation + virtual DOM diff/patch
266
+ ├── LifecycleQueue — mounted/updated/unmounted lifecycle hooks
267
+ ├── DiffEngine — keyed + non-keyed child reconciliation
268
+ ├── MountOrchestrator render cycle coordination + tree generation
269
+ ├── UpdateLoop — microtask batched scheduler
270
+ ├── ComponentInstance — per-instance state, methods, and lifecycle
271
+ └── VNode — lightweight virtual DOM representation
98
272
  ```
99
273
 
274
+ ### v8 Performance Features
275
+
276
+ | Feature | Benefit |
277
+ |---------|---------|
278
+ | Keyed reconciliation | Preserves DOM identity across reordering |
279
+ | WeakMap event delegation | Skips ancestor walk when no handlers exist |
280
+ | Component memoization | Shallow props comparison skips re-render |
281
+ | Text node fast path | `textContent` update instead of `replaceChild` |
282
+ | Reference-equality shortcuts | Skips diffing for unchanged VNodes, children, attrs |
283
+ | Auto-instance keys | Sibling components isolated without manual `key` props |
284
+ | Microtask batching | Multiple `setState` calls collapse to one render |
285
+
100
286
  ---
101
287
 
102
288
  ## Bundle Size
103
289
 
104
- | Format | Size | Gzipped | Brotli |
105
- |--------|------|---------|--------|
106
- | ESM (modern) | 13.86 kB | 4.25 kB | 3.91 kB |
107
- | UMD | 14.06 kB | 4.34 kB | 3.96 kB |
108
- | CJS | 14.19 kB | 4.35 kB | 3.93 kB |
290
+ | Format | Minified | Gzipped |
291
+ |--------|----------|---------|
292
+ | ESM (modern) | 14.3 kB | **4.4 kB** |
293
+ | CJS | 14.4 kB | 4.4 kB |
294
+ | UMD | 14.5 kB | 4.5 kB |
109
295
 
110
- Build target: Chrome 90+, Firefox 90+, Safari 14+ (ES2018). No `Object.assign` polyfill.
296
+ Target: Chrome 90+, Firefox 90+, Safari 14+ (ES2018). No `Object.assign` polyfill needed.
111
297
 
112
298
  ---
113
299
 
114
- ## Performance (JSDOM, local benchmarks)
300
+ ## Performance
115
301
 
116
- | Benchmark | v7 Baseline | v8 Optimized | Change |
117
- |-----------|-------------|--------------|--------|
302
+ Benchmarks measured in JSDOM. Real Chrome results are significantly faster.
303
+
304
+ | Benchmark | v7 | v8 | Change |
305
+ |-----------|----|----|--------|
118
306
  | create 1k rows | ~45ms | ~47ms | stable |
119
307
  | replace 1k rows | ~65ms | ~6ms | **-91%** |
120
308
  | partial update | ~186ms | ~100ms | **-46%** |
121
309
  | select row | ~22ms | ~0.05ms | **-99.8%** |
122
- | swap rows | — | ~123ms* | *JSDOM artifact; real Chrome near-instant |
123
310
  | remove row | ~74ms | ~5ms | **-93%** |
124
311
  | clear rows | ~3ms | ~0.01ms | **-99.7%** |
125
312
 
126
- *All benchmarks on JSDOM. Real Chrome results for `swap` are expected to be ~1ms (pointer swap).*
127
-
128
313
  ---
129
314
 
130
- ## Features
315
+ ## Event Handling
316
+
317
+ LiteralJS uses event delegation. Define handlers via the `events` attribute:
318
+
319
+ ```jsx
320
+ <button events={{ click: () => this.increment() }}>
321
+ Click me
322
+ </button>
323
+ ```
131
324
 
132
- - **Small** ~4.25 kB gzipped, zero dependencies
133
- - **Fast** — Keyed diffing, WeakMap event delegation, render memoization
134
- - **Simple** — Plain functions + structured components. No classes, no hooks, no magic.
135
- - **Virtual DOM** — Diffed updates only on state change
136
- - **Flexible Syntax** — JSX (with `h` pragma), Hyperscript, or Object syntax
137
- - **Lifecycle Methods** — `mounted`, `updated`, `unmounted`
138
- - **Global + Component State** — Built-in store; no Redux needed
139
- - **Event Delegation** — Most events delegated to root for performance
140
- - **Isolated Instances** — Multiple `App` instances on one page, no globals
325
+ Supported events: `click`, `input`, `change`, `submit`, `keyup`, `keydown`, `focus`, `blur`, `mouseenter`, `mouseleave`, `touchstart`, `touchend`, and more.
141
326
 
142
327
  ---
143
328
 
144
- ## Component API
329
+ ## Syntax Options
145
330
 
146
- ```js
331
+ ### JSX (recommended)
332
+
333
+ ```jsx
147
334
  /** @jsx h */
148
335
  import { h, component, App } from 'literaljs';
149
336
 
150
- const MyComponent = component({
151
- name: 'MyComponent', // Required, for debugging
152
- state: { count: 0 }, // Initial component state
153
- methods() { // Bound functions available as `this.methodName`
154
- return {
155
- increment() { this.setState({ count: this.getState().count + 1 }); }
156
- };
157
- },
158
- mounted() { console.log('mounted'); },
159
- updated() { console.log('updated'); },
160
- unmounted() { console.log('unmounted'); },
337
+ const View = component({
338
+ name: 'View',
161
339
  render() {
162
- const { count } = this.getState();
163
- return (
164
- <div>
165
- <p>Count: {count}</p>
166
- <button events={{ click: () => this.increment() }}>Add</button>
167
- </div>
168
- );
340
+ return <div class="app"><h1>Hello</h1></div>;
169
341
  }
170
342
  });
171
-
172
- new App(MyComponent, {}).mount('app');
173
343
  ```
174
344
 
175
- ### Props
345
+ ### Hyperscript
176
346
 
177
347
  ```js
178
- /** @jsx h */
179
- // Parent passes props
180
- <MyComponent key="unique" title="Hello" />
181
-
182
- // Child accesses via this.props
183
- render() {
184
- return <h1>{this.props.title}</h1>;
185
- }
348
+ const View = component({
349
+ name: 'View',
350
+ render() {
351
+ return h('div', { class: 'app' }, h('h1', {}, 'Hello'));
352
+ }
353
+ });
186
354
  ```
187
355
 
188
- ### Keys
189
-
190
- Use `key` for list items to enable DOM identity preservation:
356
+ ### Object syntax
191
357
 
192
358
  ```js
193
- /** @jsx h */
194
- <ul>
195
- {items.map(item => (
196
- <li key={item.id}>{item.name}</li>
197
- ))}
198
- </ul>
359
+ const View = component({
360
+ name: 'View',
361
+ render() {
362
+ return { e: 'div', a: { class: 'app' }, c: [{ e: 'h1', a: {}, c: ['Hello'] }] };
363
+ }
364
+ });
199
365
  ```
200
366
 
201
367
  ---
202
368
 
203
- ## State Management
369
+ ## Style Handling
204
370
 
205
- ### Component State (private)
371
+ Pass styles as objects (not strings). String styles cause a `TypeError` because LiteralJS iterates over style keys:
206
372
 
207
- ```js
208
- this.getState(); // Read current state
209
- this.setState({ count: 5 }); // Update and trigger re-render
210
- ```
373
+ ```jsx
374
+ // Correct
375
+ <div style={{ position: 'fixed', top: '0', left: '0' }}>
211
376
 
212
- ### Global Store (shared)
213
-
214
- ```js
215
- // In any component
216
- this.setStore({ theme: 'dark' }); // Update global store
217
-
218
- // Access in render
219
- render() {
220
- const theme = this.getStore().theme;
221
- return <div class={theme}>...</div>;
222
- }
377
+ // Wrong — causes TypeError
378
+ <div style="position:fixed;top:0;left:0">
223
379
  ```
224
380
 
225
381
  ---
226
382
 
227
- ## Documentation
383
+ ## Changelog
228
384
 
229
- - **Full docs**: https://literaljs.com
230
- - **Architecture decisions**: `docs/ADR/`
231
- - **Phase plans**: `docs/v8-*-plan.md`
385
+ ### [8.0.4] - 2026-05-19
232
386
 
233
- ---
387
+ **Fixed**: Sibling components without explicit `key` props now have isolated state.
234
388
 
235
- ## js-framework-benchmark
389
+ - Replaced `__default__` singleton key with auto-incrementing position keys (`__auto_0__`, `__auto_1__`, etc.)
390
+ - Added render-cycle counter (`advanceRenderCycle`) for stable keys across re-renders
391
+ - `MountOrchestrator` calls `advanceRenderCycle()` before each render pass
392
+ - Exported `advanceRenderCycle` for testing
393
+ - Updated tree.js (simplified, removed `_resetPosition` from VNode walk)
236
394
 
237
- A keyed benchmark entry is included in `js-framework-benchmark-entry/`.
395
+ ### [8.0.3] - 2026-05-18
238
396
 
239
- ```bash
240
- cd js-framework-benchmark-entry
241
- npm install
242
- npm run build-prod
243
- ```
397
+ **Fixed**: Null/undefined guard in `generateTree` before `typeof` check.
244
398
 
245
- Copy to [krausest/js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) `frameworks/keyed/literaljs/` and run `npm run bench`.
399
+ ### [8.0.2] - 2026-05-18
246
400
 
247
- ---
401
+ **Fixed**: Tree direct-props fix — two code paths for backward compat (`newC.a.props`) and modern JSX (`{ ...newC.a }`).
402
+
403
+ ### [8.0.1] - 2026-05-18
404
+
405
+ **Fixed**: WeakMap event delegation. Component render memoization. Keyed reconciliation.
248
406
 
249
- ## License
407
+ ### [8.0.0] - 2026-05-18
250
408
 
251
- MIT
409
+ **Initial v8 release**. Full architecture refactor from monolith to 12 modules.
package/build/index.js CHANGED
@@ -1 +1 @@
1
- class e{constructor(e,t,n){void 0===t&&(t={}),void 0===n&&(n=[]),this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function t(e,n){for(let s=0,i=n.length;s<i;s++)Array.isArray(n[s])?t(e,n[s]):e.push(n[s]);return e}function n(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class s{constructor(e,t,n,s,i,o){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=o,this._config=i,o.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const r=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=r();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}function i(e,t){for(let n in t)e[n]=t[n];return e}class o{constructor(e){void 0===e&&(e={}),this.store={...e},this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return{...this.store}}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=i(i({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]={...t})}getState(e){return{...this.componentStates[e]}}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=i(i({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class r{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,o;for(let r=s.length;r--;)if(o=t.a[s[r]],i=n.a[s[r]],"style"===s[r]){if(this._stylesAreEqual(o,i))continue;e.removeAttribute(s[r]),this._addStyles(o,e)}else if("events"===s[r])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,o);else{if("key"===s[r])continue;"value"===s[r]&&o!==i?e.value=o:void 0!==i&&o===i||e.setAttribute(s[r],o)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),o=Object.keys(t);if(i.length!==o.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class h{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const d=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],c="eid";class u{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new h(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+c);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const s=n();e.setAttribute("data-"+c,s),this.cache[s]=t,this._elementToUUID.set(e,s);const i=Object.keys(t);for(let t=i.length;t--;)d.includes(i[t])?e.addEventListener(i[t],this.cache[s][i[t]]):this.eventBus.attach(this.rootNode,i[t]);return s}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)d.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+c)}addEvents(e,t,n){n.setAttribute("data-"+c,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)d.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)d.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class a{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function l(t,n){if(null==t)return t;if("function"==typeof t.e){let e;e=t.a&&t.a.props?{...t.a.props}:t.a?{...t.a}:{},delete(t={e:t.e,a:{...t.a},c:t.c}).a.props,t=t.e(e)}if(t&&"function"==typeof t.bind){const s=t.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof e)i.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=i;else if("object"==typeof i&&null!==i){const n=new e(i.e,i.a,i.c);n.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=n}else t=i}if(t&&Array.isArray(t.c))for(let e=0,s=t.c.length;e<s;e++)t.c[e]=l(t.c[e],n);return t}class f{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=e.childNodes;for(let r=0;r<i;r++)s.patch(e,o[r]||null,t[r],n?n[r]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,o=t.length;if(0===o){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(r[s]=i,h[s]=n[t])}const d=new Array(o),c=new Array(o);for(let e=0;e<o;e++){const n=t[e].a?t[e].a.key:null;null!=n&&r[n]?(d[e]=r[n],c[e]=h[n],delete r[n]):(d[e]=null,c[e]=null)}for(const t in r){const n=r[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let u=e.firstChild;for(let n=0;n<o;n++){const i=d[n];if(i&&i===u)u=u.nextSibling;else if(i)e.insertBefore(i,u);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,u)}}for(;u;){const e=u.nextSibling;u.remove(),u=e}for(let n=0;n<o;n++)c[n]&&s.patch(e,e.childNodes[n],t[n],c[n]);return o}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let o=i;o-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[o]),n.remove())}}}class p{constructor(e,t,n){this.generateTree=e||l,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class y{constructor(e,t){void 0===t&&(t="microtask"),this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class m{constructor(e,t){void 0===t&&(t={}),this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new o(t),this.lifecycleQueue=new a,this.eventManager=new u,this.renderer=new r(this.eventManager,this.lifecycleQueue,new f),this.mountOrchestrator=new p(l,this.renderer,this.lifecycleQueue),this.updateLoop=new y(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}exports.App=m,exports.EventManager=u,exports.LifecycleQueue=a,exports.Renderer=r,exports.StateManager=o,exports.component=function(e){let t=void 0===e?{}:e,i=t.name,o=void 0===i?"":i,r=t.state,h=void 0===r?{}:r,d=t.mounted,c=void 0===d?function(){}:d,u=t.updated,a=void 0===u?function(){}:u,l=t.unmounted,f=void 0===l?function(){}:l,p=t.methods,y=void 0===p?function(){}:p,m=t.render,_=void 0===m?function(){}:m;const g=n(),v=new Map;return function(e){void 0===e&&(e={});const t=e.key||"__default__";if(!v.has(t)){const i=n(),r=o+(e.key?"_"+e.key:"");v.set(t,{definitionId:g,instanceId:i,key:`${g}_${i}_${r}`,_props:null,_cachedRender:null,bind(e){const t=new s(g,i,r,this._props,{state:h,mounted:c,updated:a,unmounted:f,methods:y,render:_},e);return t.bindMethods(y),t}})}const i=v.get(t);return i._props=e,i}},exports.createApp=function(e,t,n){const s=new m(e,n);return s.mount(t),s},exports.flatten=t,exports.generateTree=l,exports.generateUUID=n,exports.h=function(n,s){const i={};for(let e in s)i[e]=s[e];return new e(n,i,t([],[].slice.call(arguments,2)))},exports.isVNode=function(t){return t instanceof e||null!==t&&"object"==typeof t&&"e"in t},exports.render=function(e,t,n){void 0===n&&(n={});const s=new m(e,n);return s.mount(t),s};
1
+ class e{constructor(e,t,n){void 0===t&&(t={}),void 0===n&&(n=[]),this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function t(e,n){for(let s=0,i=n.length;s<i;s++)Array.isArray(n[s])?t(e,n[s]):null!=n[s]&&"boolean"!=typeof n[s]&&e.push(n[s]);return e}function n(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class s{constructor(e,t,n,s,i,o){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=o,this._config=i,o.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const r=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=r();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}let i=0;function o(){i++}function r(e,t){for(let n in t)e[n]=t[n];return e}class h{constructor(e){void 0===e&&(e={}),this.store={...e},this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return{...this.store}}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=r(r({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]={...t})}getState(e){return{...this.componentStates[e]}}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=r(r({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class d{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,o;for(let r=s.length;r--;)if(o=t.a[s[r]],i=n.a[s[r]],"style"===s[r]){if(this._stylesAreEqual(o,i))continue;e.removeAttribute(s[r]),this._addStyles(o,e)}else if("events"===s[r])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,o);else{if("key"===s[r])continue;"value"===s[r]&&o!==i?e.value=o:void 0!==i&&o===i||e.setAttribute(s[r],o)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),o=Object.keys(t);if(i.length!==o.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class c{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const u=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],a="eid";class l{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new c(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+a);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const s=n();e.setAttribute("data-"+a,s),this.cache[s]=t,this._elementToUUID.set(e,s);const i=Object.keys(t);for(let t=i.length;t--;)u.includes(i[t])?e.addEventListener(i[t],this.cache[s][i[t]]):this.eventBus.attach(this.rootNode,i[t]);return s}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)u.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+a)}addEvents(e,t,n){n.setAttribute("data-"+a,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)u.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)u.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class f{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function p(t,n){if(null==t)return t;if("function"==typeof t.e){let e;e=t.a&&t.a.props?{...t.a.props}:t.a?{...t.a}:{},delete(t={e:t.e,a:{...t.a},c:t.c}).a.props,t=t.e(e)}if(t&&"function"==typeof t.bind){const s=t.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof e)i.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=i;else if("object"==typeof i&&null!==i){const n=new e(i.e,i.a,i.c);n.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=n}else t=i}if(t&&Array.isArray(t.c))for(let e=0,s=t.c.length;e<s;e++)t.c[e]=p(t.c[e],n);return t}class y{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e&&t&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=e.childNodes;for(let r=0;r<i;r++)s.patch(e,o[r]||null,t[r],n?n[r]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,o=t.length;if(0===o){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(r[s]=i,h[s]=n[t])}const d=new Array(o),c=new Array(o);for(let e=0;e<o;e++){const n=t[e].a?t[e].a.key:null;null!=n&&r[n]?(d[e]=r[n],c[e]=h[n],delete r[n]):(d[e]=null,c[e]=null)}for(const t in r){const n=r[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let u=e.firstChild;for(let n=0;n<o;n++){const i=d[n];if(i&&i===u)u=u.nextSibling;else if(i)e.insertBefore(i,u);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,u)}}for(;u;){const e=u.nextSibling;u.remove(),u=e}for(let n=0;n<o;n++)c[n]&&s.patch(e,e.childNodes[n],t[n],c[n]);return o}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let o=i;o-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[o]),n.remove())}}}class m{constructor(e,t,n){this.generateTree=e||p,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){o();const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){o();const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class _{constructor(e,t){void 0===t&&(t="microtask"),this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class g{constructor(e,t){void 0===t&&(t={}),this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new h(t),this.lifecycleQueue=new f,this.eventManager=new l,this.renderer=new d(this.eventManager,this.lifecycleQueue,new y),this.mountOrchestrator=new m(p,this.renderer,this.lifecycleQueue),this.updateLoop=new _(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}exports.App=g,exports.EventManager=l,exports.LifecycleQueue=f,exports.Renderer=d,exports.StateManager=h,exports.advanceRenderCycle=o,exports.component=function(e){let t=void 0===e?{}:e,o=t.name,r=void 0===o?"":o,h=t.state,d=void 0===h?{}:h,c=t.mounted,u=void 0===c?function(){}:c,a=t.updated,l=void 0===a?function(){}:a,f=t.unmounted,p=void 0===f?function(){}:f,y=t.methods,m=void 0===y?function(){}:y,_=t.render,g=void 0===_?function(){}:_;const v=n(),b=new Map;let N=0,S=-1;return function(e){void 0===e&&(e={}),S!==i&&(N=0,S=i);const t=null!=e.key?String(e.key):`__auto_${N++}__`;if(!b.has(t)){const i=n(),o=r+(null!=e.key?"_"+String(e.key):"");b.set(t,{definitionId:v,instanceId:i,key:`${v}_${i}_${o}`,_props:null,_cachedRender:null,bind(e){const t=new s(v,i,o,this._props,{state:d,mounted:u,updated:l,unmounted:p,methods:m,render:g},e);return t.bindMethods(m),t}})}const o=b.get(t);return o._props=e,o}},exports.createApp=function(e,t,n){const s=new g(e,n);return s.mount(t),s},exports.flatten=t,exports.generateTree=p,exports.generateUUID=n,exports.h=function(n,s){const i={};for(let e in s)i[e]=s[e];return new e(n,i,t([],[].slice.call(arguments,2)))},exports.isVNode=function(t){return t instanceof e||null!==t&&"object"==typeof t&&"e"in t},exports.render=function(e,t,n){void 0===n&&(n={});const s=new g(e,n);return s.mount(t),s};
package/build/index.m.js CHANGED
@@ -1 +1 @@
1
- class e{constructor(e,t,n){void 0===t&&(t={}),void 0===n&&(n=[]),this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function t(e,n){for(let s=0,i=n.length;s<i;s++)Array.isArray(n[s])?t(e,n[s]):e.push(n[s]);return e}function n(n,s){const i={};for(let e in s)i[e]=s[e];return new e(n,i,t([],[].slice.call(arguments,2)))}function s(t){return t instanceof e||null!==t&&"object"==typeof t&&"e"in t}function i(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class o{constructor(e,t,n,s,i,o){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=o,this._config=i,o.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const r=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=r();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}function r(e){let t=void 0===e?{}:e,n=t.name,s=void 0===n?"":n,r=t.state,h=void 0===r?{}:r,d=t.mounted,c=void 0===d?function(){}:d,u=t.updated,a=void 0===u?function(){}:u,l=t.unmounted,f=void 0===l?function(){}:l,p=t.methods,y=void 0===p?function(){}:p,m=t.render,_=void 0===m?function(){}:m;const g=i(),v=new Map;return function(e){void 0===e&&(e={});const t=e.key||"__default__";if(!v.has(t)){const n=i(),r=s+(e.key?"_"+e.key:"");v.set(t,{definitionId:g,instanceId:n,key:`${g}_${n}_${r}`,_props:null,_cachedRender:null,bind(e){const t=new o(g,n,r,this._props,{state:h,mounted:c,updated:a,unmounted:f,methods:y,render:_},e);return t.bindMethods(y),t}})}const n=v.get(t);return n._props=e,n}}function h(e,t){for(let n in t)e[n]=t[n];return e}class d{constructor(e){void 0===e&&(e={}),this.store={...e},this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return{...this.store}}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=h(h({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]={...t})}getState(e){return{...this.componentStates[e]}}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=h(h({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class c{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,o;for(let r=s.length;r--;)if(o=t.a[s[r]],i=n.a[s[r]],"style"===s[r]){if(this._stylesAreEqual(o,i))continue;e.removeAttribute(s[r]),this._addStyles(o,e)}else if("events"===s[r])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,o);else{if("key"===s[r])continue;"value"===s[r]&&o!==i?e.value=o:void 0!==i&&o===i||e.setAttribute(s[r],o)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),o=Object.keys(t);if(i.length!==o.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class u{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const a=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],l="eid";class f{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new u(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+l);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const n=i();e.setAttribute("data-"+l,n),this.cache[n]=t,this._elementToUUID.set(e,n);const s=Object.keys(t);for(let t=s.length;t--;)a.includes(s[t])?e.addEventListener(s[t],this.cache[n][s[t]]):this.eventBus.attach(this.rootNode,s[t]);return n}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)a.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+l)}addEvents(e,t,n){n.setAttribute("data-"+l,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)a.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)a.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class p{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function y(t,n){if(null==t)return t;if("function"==typeof t.e){let e;e=t.a&&t.a.props?{...t.a.props}:t.a?{...t.a}:{},delete(t={e:t.e,a:{...t.a},c:t.c}).a.props,t=t.e(e)}if(t&&"function"==typeof t.bind){const s=t.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof e)i.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=i;else if("object"==typeof i&&null!==i){const n=new e(i.e,i.a,i.c);n.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=n}else t=i}if(t&&Array.isArray(t.c))for(let e=0,s=t.c.length;e<s;e++)t.c[e]=y(t.c[e],n);return t}class m{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=e.childNodes;for(let r=0;r<i;r++)s.patch(e,o[r]||null,t[r],n?n[r]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,o=t.length;if(0===o){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(r[s]=i,h[s]=n[t])}const d=new Array(o),c=new Array(o);for(let e=0;e<o;e++){const n=t[e].a?t[e].a.key:null;null!=n&&r[n]?(d[e]=r[n],c[e]=h[n],delete r[n]):(d[e]=null,c[e]=null)}for(const t in r){const n=r[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let u=e.firstChild;for(let n=0;n<o;n++){const i=d[n];if(i&&i===u)u=u.nextSibling;else if(i)e.insertBefore(i,u);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,u)}}for(;u;){const e=u.nextSibling;u.remove(),u=e}for(let n=0;n<o;n++)c[n]&&s.patch(e,e.childNodes[n],t[n],c[n]);return o}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let o=i;o-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[o]),n.remove())}}}class _{constructor(e,t,n){this.generateTree=e||y,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class g{constructor(e,t){void 0===t&&(t="microtask"),this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class v{constructor(e,t){void 0===t&&(t={}),this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new d(t),this.lifecycleQueue=new p,this.eventManager=new f,this.renderer=new c(this.eventManager,this.lifecycleQueue,new m),this.mountOrchestrator=new _(y,this.renderer,this.lifecycleQueue),this.updateLoop=new g(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}function b(e,t,n){const s=new v(e,n);return s.mount(t),s}function N(e,t,n){void 0===n&&(n={});const s=new v(e,n);return s.mount(t),s}export{v as App,f as EventManager,p as LifecycleQueue,c as Renderer,d as StateManager,r as component,b as createApp,t as flatten,y as generateTree,i as generateUUID,n as h,s as isVNode,N as render};
1
+ class e{constructor(e,t,n){void 0===t&&(t={}),void 0===n&&(n=[]),this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function t(e,n){for(let s=0,i=n.length;s<i;s++)Array.isArray(n[s])?t(e,n[s]):null!=n[s]&&"boolean"!=typeof n[s]&&e.push(n[s]);return e}function n(n,s){const i={};for(let e in s)i[e]=s[e];return new e(n,i,t([],[].slice.call(arguments,2)))}function s(t){return t instanceof e||null!==t&&"object"==typeof t&&"e"in t}function i(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class o{constructor(e,t,n,s,i,o){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=o,this._config=i,o.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const r=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=r();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}let r=0;function h(){r++}function d(e){let t=void 0===e?{}:e,n=t.name,s=void 0===n?"":n,h=t.state,d=void 0===h?{}:h,u=t.mounted,c=void 0===u?function(){}:u,a=t.updated,l=void 0===a?function(){}:a,f=t.unmounted,p=void 0===f?function(){}:f,y=t.methods,m=void 0===y?function(){}:y,_=t.render,g=void 0===_?function(){}:_;const v=i(),b=new Map;let N=0,S=-1;return function(e){void 0===e&&(e={}),S!==r&&(N=0,S=r);const t=null!=e.key?String(e.key):`__auto_${N++}__`;if(!b.has(t)){const n=i(),r=s+(null!=e.key?"_"+String(e.key):"");b.set(t,{definitionId:v,instanceId:n,key:`${v}_${n}_${r}`,_props:null,_cachedRender:null,bind(e){const t=new o(v,n,r,this._props,{state:d,mounted:c,updated:l,unmounted:p,methods:m,render:g},e);return t.bindMethods(m),t}})}const n=b.get(t);return n._props=e,n}}function u(e,t){for(let n in t)e[n]=t[n];return e}class c{constructor(e){void 0===e&&(e={}),this.store={...e},this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return{...this.store}}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=u(u({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]={...t})}getState(e){return{...this.componentStates[e]}}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=u(u({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class a{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,o;for(let r=s.length;r--;)if(o=t.a[s[r]],i=n.a[s[r]],"style"===s[r]){if(this._stylesAreEqual(o,i))continue;e.removeAttribute(s[r]),this._addStyles(o,e)}else if("events"===s[r])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,o);else{if("key"===s[r])continue;"value"===s[r]&&o!==i?e.value=o:void 0!==i&&o===i||e.setAttribute(s[r],o)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),o=Object.keys(t);if(i.length!==o.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class l{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const f=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],p="eid";class y{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new l(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+p);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const n=i();e.setAttribute("data-"+p,n),this.cache[n]=t,this._elementToUUID.set(e,n);const s=Object.keys(t);for(let t=s.length;t--;)f.includes(s[t])?e.addEventListener(s[t],this.cache[n][s[t]]):this.eventBus.attach(this.rootNode,s[t]);return n}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)f.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+p)}addEvents(e,t,n){n.setAttribute("data-"+p,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)f.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)f.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class m{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function _(t,n){if(null==t)return t;if("function"==typeof t.e){let e;e=t.a&&t.a.props?{...t.a.props}:t.a?{...t.a}:{},delete(t={e:t.e,a:{...t.a},c:t.c}).a.props,t=t.e(e)}if(t&&"function"==typeof t.bind){const s=t.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof e)i.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=i;else if("object"==typeof i&&null!==i){const n=new e(i.e,i.a,i.c);n.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=n}else t=i}if(t&&Array.isArray(t.c))for(let e=0,s=t.c.length;e<s;e++)t.c[e]=_(t.c[e],n);return t}class g{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e&&t&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=e.childNodes;for(let r=0;r<i;r++)s.patch(e,o[r]||null,t[r],n?n[r]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,o=t.length;if(0===o){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(r[s]=i,h[s]=n[t])}const d=new Array(o),u=new Array(o);for(let e=0;e<o;e++){const n=t[e].a?t[e].a.key:null;null!=n&&r[n]?(d[e]=r[n],u[e]=h[n],delete r[n]):(d[e]=null,u[e]=null)}for(const t in r){const n=r[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let c=e.firstChild;for(let n=0;n<o;n++){const i=d[n];if(i&&i===c)c=c.nextSibling;else if(i)e.insertBefore(i,c);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,c)}}for(;c;){const e=c.nextSibling;c.remove(),c=e}for(let n=0;n<o;n++)u[n]&&s.patch(e,e.childNodes[n],t[n],u[n]);return o}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let o=i;o-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[o]),n.remove())}}}class v{constructor(e,t,n){this.generateTree=e||_,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){h();const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){h();const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class b{constructor(e,t){void 0===t&&(t="microtask"),this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class N{constructor(e,t){void 0===t&&(t={}),this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new c(t),this.lifecycleQueue=new m,this.eventManager=new y,this.renderer=new a(this.eventManager,this.lifecycleQueue,new g),this.mountOrchestrator=new v(_,this.renderer,this.lifecycleQueue),this.updateLoop=new b(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}function S(e,t,n){const s=new N(e,n);return s.mount(t),s}function E(e,t,n){void 0===n&&(n={});const s=new N(e,n);return s.mount(t),s}export{N as App,y as EventManager,m as LifecycleQueue,a as Renderer,c as StateManager,h as advanceRenderCycle,d as component,S as createApp,t as flatten,_ as generateTree,i as generateUUID,n as h,s as isVNode,E as render};
@@ -1 +1 @@
1
- class e{constructor(e,t={},n=[]){this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function t(e,n){for(let s=0,i=n.length;s<i;s++)Array.isArray(n[s])?t(e,n[s]):e.push(n[s]);return e}function n(n,s,...i){const r={};for(let e in s)r[e]=s[e];return new e(n,r,t([],i))}function s(t){return t instanceof e||null!==t&&"object"==typeof t&&"e"in t}function i(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class r{constructor(e,t,n,s,i,r){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=r,this._config=i,r.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const o=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=o();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}function o({name:e="",state:t={},mounted:n=function(){},updated:s=function(){},unmounted:o=function(){},methods:h=function(){},render:u=function(){}}={}){const c=i(),d=new Map;return function(a={}){const l=a.key||"__default__";if(!d.has(l)){const f=i(),p=e+(a.key?"_"+a.key:"");d.set(l,{definitionId:c,instanceId:f,key:`${c}_${f}_${p}`,_props:null,_cachedRender:null,bind(e){const i=new r(c,f,p,this._props,{state:t,mounted:n,updated:s,unmounted:o,methods:h,render:u},e);return i.bindMethods(h),i}})}const f=d.get(l);return f._props=a,f}}function h(){return h=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var s in n)({}).hasOwnProperty.call(n,s)&&(e[s]=n[s])}return e},h.apply(null,arguments)}function u(e,t){for(let n in t)e[n]=t[n];return e}class c{constructor(e={}){this.store=h({},e),this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return h({},this.store)}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=u(u({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]=h({},t))}getState(e){return h({},this.componentStates[e])}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=u(u({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class d{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,r;for(let o=s.length;o--;)if(r=t.a[s[o]],i=n.a[s[o]],"style"===s[o]){if(this._stylesAreEqual(r,i))continue;e.removeAttribute(s[o]),this._addStyles(r,e)}else if("events"===s[o])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,r);else{if("key"===s[o])continue;"value"===s[o]&&r!==i?e.value=r:void 0!==i&&r===i||e.setAttribute(s[o],r)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),r=Object.keys(t);if(i.length!==r.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class a{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const l=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],f="eid";class p{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new a(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+f);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const n=i();e.setAttribute("data-"+f,n),this.cache[n]=t,this._elementToUUID.set(e,n);const s=Object.keys(t);for(let t=s.length;t--;)l.includes(s[t])?e.addEventListener(s[t],this.cache[n][s[t]]):this.eventBus.attach(this.rootNode,s[t]);return n}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)l.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+f)}addEvents(e,t,n){n.setAttribute("data-"+f,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)l.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)l.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class y{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function m(t,n){if(null==t)return t;if("function"==typeof t.e){let e;e=t.a&&t.a.props?h({},t.a.props):t.a?h({},t.a):{},delete(t={e:t.e,a:h({},t.a),c:t.c}).a.props,t=t.e(e)}if(t&&"function"==typeof t.bind){const s=t.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof e)i.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=i;else if("object"==typeof i&&null!==i){const n=new e(i.e,i.a,i.c);n.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=n}else t=i}if(t&&Array.isArray(t.c))for(let e=0,s=t.c.length;e<s;e++)t.c[e]=m(t.c[e],n);return t}class _{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=e.childNodes;for(let o=0;o<i;o++)s.patch(e,r[o]||null,t[o],n?n[o]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,r=t.length;if(0===r){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(o[s]=i,h[s]=n[t])}const u=new Array(r),c=new Array(r);for(let e=0;e<r;e++){const n=t[e].a?t[e].a.key:null;null!=n&&o[n]?(u[e]=o[n],c[e]=h[n],delete o[n]):(u[e]=null,c[e]=null)}for(const t in o){const n=o[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let d=e.firstChild;for(let n=0;n<r;n++){const i=u[n];if(i&&i===d)d=d.nextSibling;else if(i)e.insertBefore(i,d);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,d)}}for(;d;){const e=d.nextSibling;d.remove(),d=e}for(let n=0;n<r;n++)c[n]&&s.patch(e,e.childNodes[n],t[n],c[n]);return r}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let r=i;r-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[r]),n.remove())}}}class g{constructor(e,t,n){this.generateTree=e||m,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class v{constructor(e,t="microtask"){this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class b{constructor(e,t={}){this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new c(t),this.lifecycleQueue=new y,this.eventManager=new p,this.renderer=new d(this.eventManager,this.lifecycleQueue,new _),this.mountOrchestrator=new g(m,this.renderer,this.lifecycleQueue),this.updateLoop=new v(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}function N(e,t,n){const s=new b(e,n);return s.mount(t),s}function S(e,t,n={}){const s=new b(e,n);return s.mount(t),s}export{b as App,p as EventManager,y as LifecycleQueue,d as Renderer,c as StateManager,o as component,N as createApp,t as flatten,m as generateTree,i as generateUUID,n as h,s as isVNode,S as render};
1
+ class e{constructor(e,t={},n=[]){this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function t(e,n){for(let s=0,i=n.length;s<i;s++)Array.isArray(n[s])?t(e,n[s]):null!=n[s]&&"boolean"!=typeof n[s]&&e.push(n[s]);return e}function n(n,s,...i){const r={};for(let e in s)r[e]=s[e];return new e(n,r,t([],i))}function s(t){return t instanceof e||null!==t&&"object"==typeof t&&"e"in t}function i(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class r{constructor(e,t,n,s,i,r){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=r,this._config=i,r.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const o=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=o();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}let o=0;function h(){o++}function u({name:e="",state:t={},mounted:n=function(){},updated:s=function(){},unmounted:h=function(){},methods:u=function(){},render:c=function(){}}={}){const d=i(),a=new Map;let l=0,f=-1;return function(p={}){f!==o&&(l=0,f=o);const y=null!=p.key?String(p.key):`__auto_${l++}__`;if(!a.has(y)){const o=i(),l=e+(null!=p.key?"_"+String(p.key):"");a.set(y,{definitionId:d,instanceId:o,key:`${d}_${o}_${l}`,_props:null,_cachedRender:null,bind(e){const i=new r(d,o,l,this._props,{state:t,mounted:n,updated:s,unmounted:h,methods:u,render:c},e);return i.bindMethods(u),i}})}const m=a.get(y);return m._props=p,m}}function c(){return c=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var s in n)({}).hasOwnProperty.call(n,s)&&(e[s]=n[s])}return e},c.apply(null,arguments)}function d(e,t){for(let n in t)e[n]=t[n];return e}class a{constructor(e={}){this.store=c({},e),this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return c({},this.store)}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=d(d({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]=c({},t))}getState(e){return c({},this.componentStates[e])}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=d(d({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class l{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,r;for(let o=s.length;o--;)if(r=t.a[s[o]],i=n.a[s[o]],"style"===s[o]){if(this._stylesAreEqual(r,i))continue;e.removeAttribute(s[o]),this._addStyles(r,e)}else if("events"===s[o])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,r);else{if("key"===s[o])continue;"value"===s[o]&&r!==i?e.value=r:void 0!==i&&r===i||e.setAttribute(s[o],r)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),r=Object.keys(t);if(i.length!==r.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class f{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const p=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],y="eid";class m{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new f(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+y);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const n=i();e.setAttribute("data-"+y,n),this.cache[n]=t,this._elementToUUID.set(e,n);const s=Object.keys(t);for(let t=s.length;t--;)p.includes(s[t])?e.addEventListener(s[t],this.cache[n][s[t]]):this.eventBus.attach(this.rootNode,s[t]);return n}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)p.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+y)}addEvents(e,t,n){n.setAttribute("data-"+y,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)p.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)p.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class _{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function g(t,n){if(null==t)return t;if("function"==typeof t.e){let e;e=t.a&&t.a.props?c({},t.a.props):t.a?c({},t.a):{},delete(t={e:t.e,a:c({},t.a),c:t.c}).a.props,t=t.e(e)}if(t&&"function"==typeof t.bind){const s=t.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof e)i.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=i;else if("object"==typeof i&&null!==i){const n=new e(i.e,i.a,i.c);n.withIdentity(t.definitionId||s.definitionId,t.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),t=n}else t=i}if(t&&Array.isArray(t.c))for(let e=0,s=t.c.length;e<s;e++)t.c[e]=g(t.c[e],n);return t}class b{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e&&t&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=e.childNodes;for(let o=0;o<i;o++)s.patch(e,r[o]||null,t[o],n?n[o]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,r=t.length;if(0===r){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(o[s]=i,h[s]=n[t])}const u=new Array(r),c=new Array(r);for(let e=0;e<r;e++){const n=t[e].a?t[e].a.key:null;null!=n&&o[n]?(u[e]=o[n],c[e]=h[n],delete o[n]):(u[e]=null,c[e]=null)}for(const t in o){const n=o[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let d=e.firstChild;for(let n=0;n<r;n++){const i=u[n];if(i&&i===d)d=d.nextSibling;else if(i)e.insertBefore(i,d);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,d)}}for(;d;){const e=d.nextSibling;d.remove(),d=e}for(let n=0;n<r;n++)c[n]&&s.patch(e,e.childNodes[n],t[n],c[n]);return r}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let r=i;r-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[r]),n.remove())}}}class v{constructor(e,t,n){this.generateTree=e||g,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){h();const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){h();const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class N{constructor(e,t="microtask"){this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class S{constructor(e,t={}){this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new a(t),this.lifecycleQueue=new _,this.eventManager=new m,this.renderer=new l(this.eventManager,this.lifecycleQueue,new b),this.mountOrchestrator=new v(g,this.renderer,this.lifecycleQueue),this.updateLoop=new N(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}function E(e,t,n){const s=new S(e,n);return s.mount(t),s}function A(e,t,n={}){const s=new S(e,n);return s.mount(t),s}export{S as App,m as EventManager,_ as LifecycleQueue,l as Renderer,a as StateManager,h as advanceRenderCycle,u as component,E as createApp,t as flatten,g as generateTree,i as generateUUID,n as h,s as isVNode,A as render};
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e||self).literaljs={})}(this,function(e){class t{constructor(e,t,n){void 0===t&&(t={}),void 0===n&&(n=[]),this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function n(e,t){for(let s=0,i=t.length;s<i;s++)Array.isArray(t[s])?n(e,t[s]):e.push(t[s]);return e}function s(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class i{constructor(e,t,n,s,i,o){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=o,this._config=i,o.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const r=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=r();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}function o(e,t){for(let n in t)e[n]=t[n];return e}class r{constructor(e){void 0===e&&(e={}),this.store={...e},this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return{...this.store}}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=o(o({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]={...t})}getState(e){return{...this.componentStates[e]}}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=o(o({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class h{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,o;for(let r=s.length;r--;)if(o=t.a[s[r]],i=n.a[s[r]],"style"===s[r]){if(this._stylesAreEqual(o,i))continue;e.removeAttribute(s[r]),this._addStyles(o,e)}else if("events"===s[r])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,o);else{if("key"===s[r])continue;"value"===s[r]&&o!==i?e.value=o:void 0!==i&&o===i||e.setAttribute(s[r],o)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),o=Object.keys(t);if(i.length!==o.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class d{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const c=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],u="eid";class a{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new d(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+u);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const n=s();e.setAttribute("data-"+u,n),this.cache[n]=t,this._elementToUUID.set(e,n);const i=Object.keys(t);for(let t=i.length;t--;)c.includes(i[t])?e.addEventListener(i[t],this.cache[n][i[t]]):this.eventBus.attach(this.rootNode,i[t]);return n}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)c.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+u)}addEvents(e,t,n){n.setAttribute("data-"+u,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)c.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)c.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class l{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function f(e,n){if(null==e)return e;if("function"==typeof e.e){let t;t=e.a&&e.a.props?{...e.a.props}:e.a?{...e.a}:{},delete(e={e:e.e,a:{...e.a},c:e.c}).a.props,e=e.e(t)}if(e&&"function"==typeof e.bind){const s=e.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof t)i.withIdentity(e.definitionId||s.definitionId,e.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),e=i;else if("object"==typeof i&&null!==i){const n=new t(i.e,i.a,i.c);n.withIdentity(e.definitionId||s.definitionId,e.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),e=n}else e=i}if(e&&Array.isArray(e.c))for(let t=0,s=e.c.length;t<s;t++)e.c[t]=f(e.c[t],n);return e}class p{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=e.childNodes;for(let r=0;r<i;r++)s.patch(e,o[r]||null,t[r],n?n[r]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,o=t.length;if(0===o){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(r[s]=i,h[s]=n[t])}const d=new Array(o),c=new Array(o);for(let e=0;e<o;e++){const n=t[e].a?t[e].a.key:null;null!=n&&r[n]?(d[e]=r[n],c[e]=h[n],delete r[n]):(d[e]=null,c[e]=null)}for(const t in r){const n=r[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let u=e.firstChild;for(let n=0;n<o;n++){const i=d[n];if(i&&i===u)u=u.nextSibling;else if(i)e.insertBefore(i,u);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,u)}}for(;u;){const e=u.nextSibling;u.remove(),u=e}for(let n=0;n<o;n++)c[n]&&s.patch(e,e.childNodes[n],t[n],c[n]);return o}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let o=i;o-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[o]),n.remove())}}}class y{constructor(e,t,n){this.generateTree=e||f,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class m{constructor(e,t){void 0===t&&(t="microtask"),this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class _{constructor(e,t){void 0===t&&(t={}),this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new r(t),this.lifecycleQueue=new l,this.eventManager=new a,this.renderer=new h(this.eventManager,this.lifecycleQueue,new p),this.mountOrchestrator=new y(f,this.renderer,this.lifecycleQueue),this.updateLoop=new m(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}e.App=_,e.EventManager=a,e.LifecycleQueue=l,e.Renderer=h,e.StateManager=r,e.component=function(e){let t=void 0===e?{}:e,n=t.name,o=void 0===n?"":n,r=t.state,h=void 0===r?{}:r,d=t.mounted,c=void 0===d?function(){}:d,u=t.updated,a=void 0===u?function(){}:u,l=t.unmounted,f=void 0===l?function(){}:l,p=t.methods,y=void 0===p?function(){}:p,m=t.render,_=void 0===m?function(){}:m;const g=s(),v=new Map;return function(e){void 0===e&&(e={});const t=e.key||"__default__";if(!v.has(t)){const n=s(),r=o+(e.key?"_"+e.key:"");v.set(t,{definitionId:g,instanceId:n,key:`${g}_${n}_${r}`,_props:null,_cachedRender:null,bind(e){const t=new i(g,n,r,this._props,{state:h,mounted:c,updated:a,unmounted:f,methods:y,render:_},e);return t.bindMethods(y),t}})}const n=v.get(t);return n._props=e,n}},e.createApp=function(e,t,n){const s=new _(e,n);return s.mount(t),s},e.flatten=n,e.generateTree=f,e.generateUUID=s,e.h=function(e,s){const i={};for(let e in s)i[e]=s[e];return new t(e,i,n([],[].slice.call(arguments,2)))},e.isVNode=function(e){return e instanceof t||null!==e&&"object"==typeof e&&"e"in e},e.render=function(e,t,n){void 0===n&&(n={});const s=new _(e,n);return s.mount(t),s}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e||self).literaljs={})}(this,function(e){class t{constructor(e,t,n){void 0===t&&(t={}),void 0===n&&(n=[]),this.e=e,this.a=t,this.c=n}withLifecycle(e){return e.mounted&&(this.m=e.mounted),e.updated&&(this.up=e.updated),e.unmounted&&(this.un=e.unmounted),e.deleteState&&(this.d=e.deleteState),this}withIdentity(e,t){return this.definitionId=e,this.instanceId=t,this.id=e+"_"+t,this}}function n(e,t){for(let s=0,i=t.length;s<i;s++)Array.isArray(t[s])?n(e,t[s]):null!=t[s]&&"boolean"!=typeof t[s]&&e.push(t[s]);return e}function s(){return Math.random().toString(36).substring(2)+(new Date).getTime().toString(36)}class i{constructor(e,t,n,s,i,o){this.definitionId=e,this.instanceId=t,this.name=n,this.key=`${e}_${t}_${n}`,this.props=s,this._stateManager=o,this._config=i,o.createState(this.key,i.state),this.mounted=i.mounted.bind(this),this.updated=i.updated.bind(this),this.unmounted=i.unmounted.bind(this),this.deleteState=()=>{this._stateManager.deleteState(this.key)},this._renderedVNode=null,this._previousProps=null;const r=i.render.bind(this);this.render=()=>{if(!this.shouldUpdate())return this._renderedVNode;const e=r();return this._renderedVNode=e,this._previousProps=this.props,e}}getStore(){return this._stateManager.getStore()}setStore(e,t){this._stateManager.setStore(e,t)}getState(){return this._stateManager.getState(this.key)}setState(e,t){this._stateManager.setState(this.key,e,t)}createState(){this._stateManager.createState(this.key,this._config.state)}deleteState(){this._stateManager.deleteState(this.key)}shouldUpdate(){return!this._previousProps||!function(e,t){if(e===t)return!0;if(!e||!t||"object"!=typeof e||"object"!=typeof t)return!1;const n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(let s=0;s<n.length;s++)if(e[n[s]]!==t[n[s]])return!1;return!0}(this.props,this._previousProps)}bindMethods(e){"function"==typeof e&&(e=e.bind(this)());for(let t in e)this[t]=e[t].bind(this)}}let o=0;function r(){o++}function h(e,t){for(let n in t)e[n]=t[n];return e}class d{constructor(e){void 0===e&&(e={}),this.store={...e},this.componentStates={},this.listeners=[]}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}_notify(){for(let e=0;e<this.listeners.length;e++)this.listeners[e]()}getStore(){return{...this.store}}setStore(e,t){"function"==typeof e&&(e=e(this.store)),this.store=h(h({},this.store),e),this._notify(),"function"==typeof t&&t()}createState(e,t){e in this.componentStates||(this.componentStates[e]={...t})}getState(e){return{...this.componentStates[e]}}setState(e,t,n){"function"==typeof t&&(t=t(this.componentStates[e])),this.componentStates[e]=h(h({},this.componentStates[e]),t),this._notify(),"function"==typeof n&&n()}deleteState(e){delete this.componentStates[e]}reset(){this.store={},this.componentStates={},this.listeners=[]}}class u{constructor(e,t,n){this.eventManager=e,this.lifecycleQueue=t,this.diffEngine=n}mount(e,t){const n=this.createElement(t);n&&e.appendChild(n)}createElement(e){if(null==e)return document.createTextNode("");const t=typeof e;return"string"===t||"number"===t?document.createTextNode(e):"boolean"===t||"undefined"===t?document.createTextNode(""):"object"===t&&e.e?this._createElementNode(e):null}_createElementNode(e){const t=document.createElement(e.e);if("object"==typeof e.a){const n=Object.keys(e.a);for(let s=n.length;s--;)if("events"===n[s])e.eid=this.eventManager.bindEvents(t,e.a[n[s]]);else if("style"===n[s])this._addStyles(e.a[n[s]],t);else{if("key"===n[s])continue;t.setAttribute(n[s],e.a[n[s]])}}if(this.lifecycleQueue.mounted(e),Array.isArray(e.c))for(let n=0,s=e.c.length;n<s;n++){const s=this.createElement(e.c[n]);s&&t.appendChild(s)}return t}_addStyles(e,t){if(void 0===e)return;const n=Object.keys(e);for(let s=n.length;s--;)t.style[n[s]]=e[n[s]]}patch(e,t,n,s){const i=typeof n;if(void 0===s)this._appendChild(e,n);else if("undefined"===i)this._unmountNodeAndChildren(s),t&&t.remove();else if(this.diffEngine.areNodesEqual(n,s)){if("object"===i&&n.e){if(n===s)return;if(this._updateNodes(t,n,s),n.c!==s.c)if(this.diffEngine._hasKeys(n.c)||this.diffEngine._hasKeys(s.c))this.diffEngine.reconcileChildren(t,n.c,s.c,this);else{let e;for(let i=s.c?s.c.length:0;i--&&void 0===n.c[i];)e=t.lastChild,e&&(this._unmountNodeAndChildren(s.c[i]),e.remove());if(Array.isArray(n.c))for(let e=0,i=n.c.length;e<i;e++)this.patch(t,t.childNodes[e]||null,n.c[e],s.c?s.c[e]:void 0)}}}else if(!t||3!==t.nodeType||"string"!==i&&"number"!==i)this._unmountNodeAndChildren(s),t&&e.replaceChild(this.createElement(n),t);else{const e=String(n);t.textContent!==e&&(t.textContent=e)}}_appendChild(e,t){const n=this.createElement(t);n&&e.appendChild(n)}_updateNodes(e,t,n){if(this.lifecycleQueue.updated(t),t.a===n.a)return;if(!t.a||!n.a)return;const s=Object.keys(t.a);let i,o;for(let r=s.length;r--;)if(o=t.a[s[r]],i=n.a[s[r]],"style"===s[r]){if(this._stylesAreEqual(o,i))continue;e.removeAttribute(s[r]),this._addStyles(o,e)}else if("events"===s[r])this.eventManager.unbindEvents(e,n.eid),t.eid=this.eventManager.bindEvents(e,o);else{if("key"===s[r])continue;"value"===s[r]&&o!==i?e.value=o:void 0!==i&&o===i||e.setAttribute(s[r],o)}}_stylesAreEqual(e,t){if(e===t)return!0;const n=typeof e,s=typeof t;if("undefined"===n&&"undefined"===s)return!0;if("object"!==n||"object"!==s)return!1;const i=Object.keys(e),o=Object.keys(t);if(i.length!==o.length)return!1;for(let n=i.length;n--;)if(e[i[n]]!==t[i[n]])return!1;return!0}_unmountNodeAndChildren(e){if(null!=e&&(this.lifecycleQueue.unmounted(e),this.lifecycleQueue.deleteState(e),this.eventManager.deleteCachedEvent(e.eid),Array.isArray(e.c)))for(let t=e.c.length;t--;)this._unmountNodeAndChildren(e.c[t])}unmount(e,t){this._unmountNodeAndChildren(t),e&&(e.innerHTML="")}}class c{constructor(e,t,n){this._getCache=e,this._resolveUUID=t,this._elementToUUID=n,this._attachedTypes=new Set,this._rootNode=null}attach(e,t){this._attachedTypes.has(t)||(this._attachedTypes.add(t),this._rootNode=e,e._literaljs_hasEvents=!0,e.addEventListener(t,e=>this._handle(e)))}_handle(e){if(!this._rootNode||!this._rootNode._literaljs_hasEvents)return;let t=e.target;for(;t&&t!==this._rootNode;){let n;if(this._elementToUUID&&(n=this._elementToUUID.get(t))){const t=this._getCache(n);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}const s=this._resolveUUID(t);if("string"==typeof s){const t=this._getCache(s);if(t&&"function"==typeof t[e.type])return void t[e.type](e)}t=t.parentNode}}reset(){this._attachedTypes.clear()}}const a=["abort","blur","error","focus","load","mouseenter","mouseleave","resize","scroll","unload"],l="eid";class f{constructor(){this.cache={},this.rootNode=null,this._elementToUUID=new WeakMap,this.eventBus=new c(e=>this.cache[e],e=>this.getEventUUID(e),this._elementToUUID)}setRootNode(e){this.rootNode=e}getEventUUID(e){if(!e||!e.parentNode)return;if("#document"===e.parentNode.nodeName)return;const t=e.getAttribute("data-"+l);return"string"==typeof t?t:this.getEventUUID(e.parentNode)}bindEvents(e,t){const n=s();e.setAttribute("data-"+l,n),this.cache[n]=t,this._elementToUUID.set(e,n);const i=Object.keys(t);for(let t=i.length;t--;)a.includes(i[t])?e.addEventListener(i[t],this.cache[n][i[t]]):this.eventBus.attach(this.rootNode,i[t]);return n}unbindEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)a.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]]);this.deleteCachedEvent(t),this._elementToUUID.delete(e),e.removeAttribute("data-"+l)}addEvents(e,t,n){n.setAttribute("data-"+l,e),this.cache[e]=t,this._elementToUUID.set(n,e);const s=Object.keys(t);for(let t=s.length;t--;)a.includes(s[t])?n.addEventListener(s[t],this.cache[e][s[t]]):this.eventBus.attach(this.rootNode,s[t])}removeIndividualEvents(e,t){if(!this.cache[t])return;const n=Object.keys(this.cache[t]);for(let s=n.length;s--;)a.includes(n[s])&&e.removeEventListener(n[s],this.cache[t][n[s]])}deleteCachedEvent(e){"string"==typeof e&&delete this.cache[e]}destroy(){this.rootNode&&(this.rootNode._literaljs_hasEvents=!1),this.cache={},this.rootNode=null,this.eventBus.reset()}}class p{constructor(){this.queue=[]}mounted(e){"object"==typeof e&&"function"==typeof e.m&&this.queue.push(e.m)}updated(e){"object"==typeof e&&"function"==typeof e.up&&this.queue.push(e.up)}unmounted(e){"object"==typeof e&&"function"==typeof e.un&&this.queue.push(e.un)}deleteState(e){"object"==typeof e&&"function"==typeof e.d&&this.queue.push(e.d)}flush(){let e;for(;e=this.queue.shift();)e()}clear(){this.queue=[]}}function y(e,n){if(null==e)return e;if("function"==typeof e.e){let t;t=e.a&&e.a.props?{...e.a.props}:e.a?{...e.a}:{},delete(e={e:e.e,a:{...e.a},c:e.c}).a.props,e=e.e(t)}if(e&&"function"==typeof e.bind){const s=e.bind(n);let i;try{i=s.render()}catch(e){console.error("Component render error:",e),i={e:"div",a:{class:"error-boundary"},c:[`${e.name}: ${e.message}`]}}if("object"==typeof i&&null!==i&&i instanceof t)i.withIdentity(e.definitionId||s.definitionId,e.instanceId||s.instanceId),i.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),e=i;else if("object"==typeof i&&null!==i){const n=new t(i.e,i.a,i.c);n.withIdentity(e.definitionId||s.definitionId,e.instanceId||s.instanceId),n.withLifecycle({mounted:s.mounted,updated:s.updated,unmounted:s.unmounted,deleteState:s.deleteState}),e=n}else e=i}if(e&&Array.isArray(e.c))for(let t=0,s=e.c.length;t<s;t++)e.c[t]=y(e.c[t],n);return e}class m{areNodesEqual(e,t){const n=typeof e;return n===typeof t&&("object"===n&&e&&t&&e.e===t.e&&e.id===t.id||("string"===n||"number"===n)&&e===t)}reconcileChildren(e,t,n,s){return Array.isArray(t)?this._hasKeys(t)||this._hasKeys(n)?this._reconcileKeyed(e,t,n,s):this._reconcileNonKeyed(e,t,n,s):0}_reconcileNonKeyed(e,t,n,s){const i=t.length;if(0===i){if(n)for(let e=0;e<n.length;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const o=e.childNodes;for(let r=0;r<i;r++)s.patch(e,o[r]||null,t[r],n?n[r]:void 0);return i}_hasKeys(e){if(!Array.isArray(e))return!1;for(let t=0,n=e.length;t<n;t++)if(e[t]&&e[t].a&&null!=e[t].a.key)return!0;return!1}_reconcileKeyed(e,t,n,s){const i=n?n.length:0,o=t.length;if(0===o){for(let e=0;e<i;e++)s._unmountNodeAndChildren(n[e]);return e.innerHTML="",0}const r=Object.create(null),h=Object.create(null);for(let t=0;t<i;t++){const s=n[t].a?n[t].a.key:null,i=e.childNodes[t];null!=s&&i&&(r[s]=i,h[s]=n[t])}const d=new Array(o),u=new Array(o);for(let e=0;e<o;e++){const n=t[e].a?t[e].a.key:null;null!=n&&r[n]?(d[e]=r[n],u[e]=h[n],delete r[n]):(d[e]=null,u[e]=null)}for(const t in r){const n=r[t];n&&(s.patch(e,n,void 0,h[t]),n.remove())}let c=e.firstChild;for(let n=0;n<o;n++){const i=d[n];if(i&&i===c)c=c.nextSibling;else if(i)e.insertBefore(i,c);else{const i=s.createElement(t[n]);i&&e.insertBefore(i,c)}}for(;c;){const e=c.nextSibling;c.remove(),c=e}for(let n=0;n<o;n++)u[n]&&s.patch(e,e.childNodes[n],t[n],u[n]);return o}removeExtraChildren(e,t,n,s){const i=t.c?t.c.length:0;if(!(i<=n))for(let o=i;o-- >n;){const n=e.lastChild;n&&(s._unmountNodeAndChildren(t.c[o]),n.remove())}}}class _{constructor(e,t,n){this.generateTree=e||y,this.renderer=t,this.lifecycleQueue=n}mount(e,t,n){r();const s=this.generateTree(t(),n);return this.renderer.mount(e,s),this.lifecycleQueue.flush(),s}update(e,t,n,s){r();const i=this.generateTree(t(),n);return this.renderer.patch(e,e.firstChild,i,s),this.lifecycleQueue.flush(),i}unmount(e,t){t&&(this.renderer.unmount(e,t),this.lifecycleQueue.flush())}}class g{constructor(e,t){void 0===t&&(t="microtask"),this._renderFn=e,this._scheduler=t,this._scheduled=!1}schedule(){this._scheduled||(this._scheduled=!0,"microtask"===this._scheduler?Promise.resolve().then(()=>this._execute()):"sync"===this._scheduler&&this._execute())}_execute(){this._scheduled=!1,this._renderFn()}}class v{constructor(e,t){void 0===t&&(t={}),this.rootComponent=e,this.savedTree=e,this.currentTree=null,this.rootNode=null,this.stateManager=new d(t),this.lifecycleQueue=new p,this.eventManager=new f,this.renderer=new u(this.eventManager,this.lifecycleQueue,new m),this.mountOrchestrator=new _(y,this.renderer,this.lifecycleQueue),this.updateLoop=new g(()=>this.update(),"microtask"),this._boundSchedule=()=>this.updateLoop.schedule(),this.stateManager.subscribe(this._boundSchedule)}mount(e){if(this.rootNode=document.getElementById(e),!this.rootNode)throw new Error(`Cannot mount app: element with id "${e}" not found`);return this.eventManager.setRootNode(this.rootNode),this.currentTree=this.mountOrchestrator.mount(this.rootNode,this.savedTree,this.stateManager),this}unmount(){this.mountOrchestrator.unmount(this.rootNode,this.currentTree),this.eventManager.destroy(),this.stateManager.unsubscribe(()=>this.updateLoop.schedule()),this.rootNode&&(this.rootNode.innerHTML=""),this.currentTree=null,this.rootNode=null}scheduleUpdate(){this.updateLoop.schedule()}update(){this.rootNode&&this.savedTree&&(this.currentTree=this.mountOrchestrator.update(this.rootNode,this.savedTree,this.stateManager,this.currentTree))}getStore(){return this.stateManager.getStore()}setStore(e,t){this.stateManager.setStore(e,t)}}e.App=v,e.EventManager=f,e.LifecycleQueue=p,e.Renderer=u,e.StateManager=d,e.advanceRenderCycle=r,e.component=function(e){let t=void 0===e?{}:e,n=t.name,r=void 0===n?"":n,h=t.state,d=void 0===h?{}:h,u=t.mounted,c=void 0===u?function(){}:u,a=t.updated,l=void 0===a?function(){}:a,f=t.unmounted,p=void 0===f?function(){}:f,y=t.methods,m=void 0===y?function(){}:y,_=t.render,g=void 0===_?function(){}:_;const v=s(),b=new Map;let N=0,S=-1;return function(e){void 0===e&&(e={}),S!==o&&(N=0,S=o);const t=null!=e.key?String(e.key):`__auto_${N++}__`;if(!b.has(t)){const n=s(),o=r+(null!=e.key?"_"+String(e.key):"");b.set(t,{definitionId:v,instanceId:n,key:`${v}_${n}_${o}`,_props:null,_cachedRender:null,bind(e){const t=new i(v,n,o,this._props,{state:d,mounted:c,updated:l,unmounted:p,methods:m,render:g},e);return t.bindMethods(m),t}})}const n=b.get(t);return n._props=e,n}},e.createApp=function(e,t,n){const s=new v(e,n);return s.mount(t),s},e.flatten=n,e.generateTree=y,e.generateUUID=s,e.h=function(e,s){const i={};for(let e in s)i[e]=s[e];return new t(e,i,n([],[].slice.call(arguments,2)))},e.isVNode=function(e){return e instanceof t||null!==e&&"object"==typeof e&&"e"in e},e.render=function(e,t,n){void 0===n&&(n={});const s=new v(e,n);return s.mount(t),s}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "literaljs",
3
- "version": "8.0.3",
3
+ "version": "8.0.5",
4
4
  "description": "A small JavaScript library for building reactive user interfaces.",
5
5
  "main": "build/index.js",
6
6
  "module": "build/index.m.js",