eleva 1.0.0-rc.1 → 1.0.0-rc.10
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 +384 -16
- package/dist/eleva-plugins.cjs.js +3397 -0
- package/dist/eleva-plugins.cjs.js.map +1 -0
- package/dist/eleva-plugins.esm.js +3392 -0
- package/dist/eleva-plugins.esm.js.map +1 -0
- package/dist/eleva-plugins.umd.js +3403 -0
- package/dist/eleva-plugins.umd.js.map +1 -0
- package/dist/eleva-plugins.umd.min.js +3 -0
- package/dist/eleva-plugins.umd.min.js.map +1 -0
- package/dist/eleva.cjs.js +593 -117
- package/dist/eleva.cjs.js.map +1 -1
- package/dist/eleva.d.ts +612 -75
- package/dist/eleva.esm.js +593 -117
- package/dist/eleva.esm.js.map +1 -1
- package/dist/eleva.umd.js +593 -117
- package/dist/eleva.umd.js.map +1 -1
- package/dist/eleva.umd.min.js +2 -2
- package/dist/eleva.umd.min.js.map +1 -1
- package/dist/plugins/attr.umd.js +231 -0
- package/dist/plugins/attr.umd.js.map +1 -0
- package/dist/plugins/attr.umd.min.js +3 -0
- package/dist/plugins/attr.umd.min.js.map +1 -0
- package/dist/plugins/props.umd.js +711 -0
- package/dist/plugins/props.umd.js.map +1 -0
- package/dist/plugins/props.umd.min.js +3 -0
- package/dist/plugins/props.umd.min.js.map +1 -0
- package/dist/plugins/router.umd.js +1807 -0
- package/dist/plugins/router.umd.js.map +1 -0
- package/dist/plugins/router.umd.min.js +3 -0
- package/dist/plugins/router.umd.min.js.map +1 -0
- package/dist/plugins/store.umd.js +684 -0
- package/dist/plugins/store.umd.js.map +1 -0
- package/dist/plugins/store.umd.min.js +3 -0
- package/dist/plugins/store.umd.min.js.map +1 -0
- package/package.json +77 -25
- package/src/core/Eleva.js +226 -62
- package/src/modules/Emitter.js +98 -8
- package/src/modules/Renderer.js +66 -36
- package/src/modules/Signal.js +85 -8
- package/src/modules/TemplateEngine.js +121 -13
- package/src/plugins/Attr.js +252 -0
- package/src/plugins/Props.js +590 -0
- package/src/plugins/Router.js +1919 -0
- package/src/plugins/Store.js +741 -0
- package/src/plugins/index.js +40 -0
- package/types/core/Eleva.d.ts +217 -50
- package/types/core/Eleva.d.ts.map +1 -1
- package/types/modules/Emitter.d.ts +111 -12
- package/types/modules/Emitter.d.ts.map +1 -1
- package/types/modules/Renderer.d.ts +68 -3
- package/types/modules/Renderer.d.ts.map +1 -1
- package/types/modules/Signal.d.ts +92 -10
- package/types/modules/Signal.d.ts.map +1 -1
- package/types/modules/TemplateEngine.d.ts +131 -15
- package/types/modules/TemplateEngine.d.ts.map +1 -1
- package/types/plugins/Attr.d.ts +28 -0
- package/types/plugins/Attr.d.ts.map +1 -0
- package/types/plugins/Props.d.ts +48 -0
- package/types/plugins/Props.d.ts.map +1 -0
- package/types/plugins/Router.d.ts +1000 -0
- package/types/plugins/Router.d.ts.map +1 -0
- package/types/plugins/Store.d.ts +86 -0
- package/types/plugins/Store.d.ts.map +1 -0
- package/types/plugins/index.d.ts +5 -0
- package/types/plugins/index.d.ts.map +1 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# eleva.js 🚀
|
|
2
2
|
|
|
3
|
+
> **Version:** 1.0.0-rc.10 | **Size:** ~6KB min (~2KB gzip) | **Dependencies:** Zero | **TypeScript:** Yes
|
|
4
|
+
|
|
3
5
|
Pure JavaScript, Pure Performance, Simply Elegant.
|
|
4
6
|
|
|
5
7
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -10,7 +12,7 @@ Pure JavaScript, Pure Performance, Simply Elegant.
|
|
|
10
12
|
[](https://codecov.io/gh/TarekRaafat/eleva)
|
|
11
13
|
[](https://bundlephobia.com/package/eleva@latest)
|
|
12
14
|
[](https://bundlephobia.com/package/eleva@latest)
|
|
13
|
-
[](https://www.jsdelivr.com/package/npm/eleva)
|
|
15
|
+
[](https://www.jsdelivr.com/package/npm/eleva)
|
|
14
16
|
[](https://canonical.com)
|
|
15
17
|
|
|
16
18
|
<br>
|
|
@@ -38,11 +40,11 @@ Pure JavaScript, Pure Performance, Simply Elegant.
|
|
|
38
40
|
<br>
|
|
39
41
|
|
|
40
42
|
**A minimalist, lightweight, pure vanilla JavaScript frontend runtime framework.**
|
|
41
|
-
_Built with love for native JavaScript-because sometimes, less really is more!_ 😊
|
|
43
|
+
_Built with love for native JavaScript and designed with a minimal core that can be extended through a powerful plugin system-because sometimes, less really is more!_ 😊
|
|
42
44
|
|
|
43
|
-
> **Stability Notice**: This is `v1.0.0-rc.
|
|
45
|
+
> **Stability Notice**: This is `v1.0.0-rc.10` - The core functionality is stable. Seeking community feedback before the final v1.0.0 release.
|
|
44
46
|
|
|
45
|
-
**Version:** `1.0.0-rc.
|
|
47
|
+
**Version:** `1.0.0-rc.10`
|
|
46
48
|
|
|
47
49
|
|
|
48
50
|
|
|
@@ -54,6 +56,7 @@ Welcome to Eleva! This is my humble, experimental playground for a fresh approac
|
|
|
54
56
|
|
|
55
57
|
- [eleva.js 🚀](#elevajs-)
|
|
56
58
|
- [Table of Contents](#table-of-contents)
|
|
59
|
+
- [Quick Reference](#quick-reference)
|
|
57
60
|
- [Introduction](#introduction)
|
|
58
61
|
- [Design Philosophy](#design-philosophy)
|
|
59
62
|
- [Handcrafted \& Developer-Centric Design](#handcrafted--developer-centric-design)
|
|
@@ -74,6 +77,12 @@ Welcome to Eleva! This is my humble, experimental playground for a fresh approac
|
|
|
74
77
|
- [Emitter](#emitter)
|
|
75
78
|
- [Renderer](#renderer)
|
|
76
79
|
- [Eleva (Core)](#eleva-core)
|
|
80
|
+
- [Plugins](#plugins)
|
|
81
|
+
- [Core Framework Only (Lightweight)](#core-framework-only-lightweight)
|
|
82
|
+
- [AttrPlugin](#attrplugin)
|
|
83
|
+
- [RouterPlugin](#routerplugin)
|
|
84
|
+
- [PropsPlugin](#propsplugin)
|
|
85
|
+
- [StorePlugin](#storeplugin)
|
|
77
86
|
- [Development](#development)
|
|
78
87
|
- [Testing](#testing)
|
|
79
88
|
- [Contributing](#contributing)
|
|
@@ -82,17 +91,56 @@ Welcome to Eleva! This is my humble, experimental playground for a fresh approac
|
|
|
82
91
|
|
|
83
92
|
---
|
|
84
93
|
|
|
94
|
+
## Quick Reference
|
|
95
|
+
|
|
96
|
+
### Minimal Setup (30 seconds)
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
import Eleva from "eleva";
|
|
100
|
+
|
|
101
|
+
const app = new Eleva("MyApp");
|
|
102
|
+
|
|
103
|
+
app.component("Counter", {
|
|
104
|
+
setup: ({ signal }) => ({ count: signal(0) }),
|
|
105
|
+
template: (ctx) => `<button @click="() => count.value++">${ctx.count.value}</button>`
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
app.mount(document.getElementById("app"), "Counter");
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### API at a Glance
|
|
112
|
+
|
|
113
|
+
| Method | Purpose |
|
|
114
|
+
|--------|---------|
|
|
115
|
+
| `new Eleva(name)` | Create app |
|
|
116
|
+
| `app.component(name, def)` | Register component |
|
|
117
|
+
| `app.mount(el, name)` | Mount to DOM |
|
|
118
|
+
| `app.use(plugin)` | Add plugin |
|
|
119
|
+
| `signal(value)` | Reactive state |
|
|
120
|
+
| `emitter.on/emit` | Events |
|
|
121
|
+
|
|
122
|
+
### Template Syntax
|
|
123
|
+
|
|
124
|
+
| Syntax | Use |
|
|
125
|
+
|--------|-----|
|
|
126
|
+
| `${expr}` | Static value |
|
|
127
|
+
| `{{ expr }}` | Reactive value |
|
|
128
|
+
| `@click` | Event handler |
|
|
129
|
+
| `:prop` | Pass to child |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
85
133
|
## Introduction
|
|
86
134
|
|
|
87
|
-
Eleva is a lightweight, no-nonsense runtime framework for frontend applications. Built with love for **pure vanilla JavaScript**, Eleva lets you create highly modular and scalable applications without the overhead of large frameworks. I built Eleva to prove that you don't need heavy frameworks or libraries to build amazing user interfaces-sometimes, the simplest approach is the most powerful.
|
|
135
|
+
Eleva is a lightweight, no-nonsense runtime framework for frontend applications. Built with love for **pure vanilla JavaScript**, Eleva features a minimal core with essential functionality that can be extended through a powerful plugin system. This approach lets you create highly modular and scalable applications without the overhead of large frameworks. I built Eleva to prove that you don't need heavy frameworks or libraries to build amazing user interfaces-sometimes, the simplest approach is the most powerful.
|
|
88
136
|
|
|
89
137
|
**My Inspiration:**
|
|
90
138
|
The idea behind Eleva comes from a deep appreciation for native JavaScript. I wanted to create a tool that stays true to the language without introducing new syntax or complexity, making it easy to integrate into your projects.
|
|
91
139
|
|
|
92
140
|
**Core Principles:**
|
|
93
141
|
|
|
94
|
-
- **🌱 Minimalism:** Only the
|
|
95
|
-
- **🔌 Extensibility:**
|
|
142
|
+
- **🌱 Minimalism:** Only essential features in the core, keeping the framework lean and focused.
|
|
143
|
+
- **🔌 Extensibility:** Extend functionality by plugging in your own ideas, such as custom state management, routing, and more.
|
|
96
144
|
- **🚀 Performance:** Fast, efficient, and designed with modern browsers in mind.
|
|
97
145
|
- **🍦 Pure Vanilla:** No dependencies, no magic-just plain JavaScript.
|
|
98
146
|
|
|
@@ -100,9 +148,9 @@ The idea behind Eleva comes from a deep appreciation for native JavaScript. I wa
|
|
|
100
148
|
|
|
101
149
|
## Design Philosophy
|
|
102
150
|
|
|
103
|
-
**Eleva is an unopinionated framework.**
|
|
151
|
+
**Eleva is an unopinionated framework with a minimal core philosophy.**
|
|
104
152
|
|
|
105
|
-
Unlike
|
|
153
|
+
Unlike monolithic frameworks that include everything out-of-the-box, Eleva intentionally provides only essential features in its core, relying on a powerful plugin system for extensibility. This architectural choice means:
|
|
106
154
|
|
|
107
155
|
- **🔄 Flexibility:** Architect your application your way-no rigid structure required.
|
|
108
156
|
- **🎯 Native JavaScript:** Built using pure vanilla JavaScript, Eleva integrates seamlessly with your existing code without unfamiliar syntax.
|
|
@@ -136,6 +184,7 @@ This unique, developer-first approach makes Eleva a standout choice for building
|
|
|
136
184
|
- **🔄 Lifecycle Hooks:** Complete lifecycle management with before/after mount and update hooks
|
|
137
185
|
- **🧹 Automatic Cleanup:** Proper cleanup of resources, watchers, and child components on unmount
|
|
138
186
|
- **🔌 Plugin System:** Extensible architecture with a simple plugin API
|
|
187
|
+
- **🎯 Built-in Plugins:** AttrPlugin for advanced attributes, PropsPlugin for complex data handling, RouterPlugin for client-side routing, and StorePlugin for reactive state management
|
|
139
188
|
- **📦 UMD & ES Module Builds:** Supports modern build tools and browser environments
|
|
140
189
|
- **🤝 Friendly API:** A gentle learning curve for both beginners and seasoned developers
|
|
141
190
|
- **💎 Tiny Footprint & TypeScript Support:** Approximately ~6 KB minified with built-in TypeScript declarations
|
|
@@ -152,6 +201,9 @@ Eleva is ideal for developers seeking a lightweight, flexible, and high-performa
|
|
|
152
201
|
- **🎯 Developer-Friendly:** Stick to pure vanilla JavaScript with familiar syntax and built-in TypeScript support.
|
|
153
202
|
- **🧪 Rapid Prototyping:** Quickly prototype ideas with a minimal and extendable framework.
|
|
154
203
|
- **🔌 Extensible:** Easily add features like routing or state management through plugins.
|
|
204
|
+
- **🚀 Built-in Routing:** Advanced client-side routing with navigation guards and reactive state via RouterPlugin.
|
|
205
|
+
- **🎯 Advanced Attributes:** Sophisticated attribute handling with ARIA support via AttrPlugin.
|
|
206
|
+
- **🏪 Reactive State Management:** Centralized, reactive data store with persistence and namespacing via StorePlugin.
|
|
155
207
|
- **📦 Module Format Flexibility:** Choose from ESM, CommonJS, or UMD formats based on your project's needs.
|
|
156
208
|
|
|
157
209
|
---
|
|
@@ -160,9 +212,8 @@ Eleva is ideal for developers seeking a lightweight, flexible, and high-performa
|
|
|
160
212
|
|
|
161
213
|
I believe in clear versioning that reflects the maturity of the project:
|
|
162
214
|
|
|
163
|
-
- **Pre-release Versions (
|
|
215
|
+
- **Pre-release Versions (RC):** Release candidate versions like `1.0.0-rc.10` indicate the API is stable but still gathering community feedback before the final release.
|
|
164
216
|
- **Semantic Versioning:** Once stable, I'll follow semantic versioning strictly to clearly communicate any breaking changes.
|
|
165
|
-
- **Fresh Start:** This release (`1.2.0-alpha`) marks a significant update with enhanced inline documentation, improved JSDoc annotations, and a refined mounting context that now includes an `emitter` property.
|
|
166
217
|
|
|
167
218
|
---
|
|
168
219
|
|
|
@@ -196,10 +247,10 @@ Preliminary benchmarks illustrate Eleva's efficiency compared to popular framewo
|
|
|
196
247
|
|
|
197
248
|
| **Framework** | **Bundle Size** (KB) | **Initial Load Time** (ms) | **DOM Update Speed** (s) | **Peak Memory Usage** (KB) | **Overall Performance Score** (lower is better) |
|
|
198
249
|
| ----------------------------- | -------------------- | -------------------------- | ------------------------ | -------------------------- | ----------------------------------------------- |
|
|
199
|
-
| **Eleva** (Direct DOM) | **2**
|
|
200
|
-
| **React** (Virtual DOM) | 4.1
|
|
201
|
-
| **Vue** (Reactive State) | 45 | 4.72
|
|
202
|
-
| **Angular** (Two-way Binding) | 62 | 5.26
|
|
250
|
+
| **Eleva** (Direct DOM) | **2** | **0.05** | **0.002** | **0.25** | **0.58 (Best)** |
|
|
251
|
+
| **React** (Virtual DOM) | 4.1 | 5.34 | 0.020 | 0.25 | 9.71 |
|
|
252
|
+
| **Vue** (Reactive State) | 45 | 4.72 | 0.021 | 3.10 | 13.21 |
|
|
253
|
+
| **Angular** (Two-way Binding) | 62 | 5.26 | 0.021 | 0.25 | 16.88 (Slowest) |
|
|
203
254
|
|
|
204
255
|
Detailed [Benchmark Metrics Report](BENCHMARK.md)
|
|
205
256
|
|
|
@@ -373,6 +424,323 @@ Interactive Demo: [CodePen](https://codepen.io/tarekraafat/pen/jEOyzYN?editors=1
|
|
|
373
424
|
- **`.mount(container, compName, props)`**
|
|
374
425
|
Mount a component to the DOM.
|
|
375
426
|
|
|
427
|
+
### Plugins
|
|
428
|
+
|
|
429
|
+
Eleva's plugin system allows you to extend functionality as needed. Plugins are **separately bundled** from the core framework, ensuring optimal tree-shaking and minimal bundle sizes.
|
|
430
|
+
|
|
431
|
+
#### Core Framework Only (Lightweight)
|
|
432
|
+
|
|
433
|
+
```javascript
|
|
434
|
+
import Eleva from 'eleva';
|
|
435
|
+
|
|
436
|
+
const app = new Eleva("myApp");
|
|
437
|
+
// Core framework only - ~6KB minified
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
#### AttrPlugin
|
|
441
|
+
|
|
442
|
+
Advanced attribute handling for ARIA, data attributes, boolean properties, and dynamic property detection:
|
|
443
|
+
|
|
444
|
+
```javascript
|
|
445
|
+
import Eleva from 'eleva';
|
|
446
|
+
import { Attr } from 'eleva/plugins';
|
|
447
|
+
|
|
448
|
+
const app = new Eleva("myApp");
|
|
449
|
+
app.use(Attr, {
|
|
450
|
+
enableAria: true, // ARIA attribute handling
|
|
451
|
+
enableData: true, // Data attribute management
|
|
452
|
+
enableBoolean: true, // Boolean attribute processing
|
|
453
|
+
enableDynamic: true // Dynamic property detection
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Use advanced attributes in components
|
|
457
|
+
app.component("myComponent", {
|
|
458
|
+
template: (ctx) => `
|
|
459
|
+
<button
|
|
460
|
+
aria-expanded="${ctx.isExpanded.value}"
|
|
461
|
+
data-user-id="${ctx.userId.value}"
|
|
462
|
+
disabled="${ctx.isLoading.value}"
|
|
463
|
+
class="btn ${ctx.variant.value}"
|
|
464
|
+
>
|
|
465
|
+
${ctx.text.value}
|
|
466
|
+
</button>
|
|
467
|
+
`
|
|
468
|
+
});
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
📚 **[Full Attr Documentation →](docs/plugins/attr.md)** - Comprehensive guide with ARIA attributes, data attributes, boolean handling, and dynamic properties.
|
|
472
|
+
|
|
473
|
+
#### RouterPlugin
|
|
474
|
+
|
|
475
|
+
🚀 **Advanced client-side routing** with multiple modes, navigation guards, reactive state, and component resolution:
|
|
476
|
+
|
|
477
|
+
```javascript
|
|
478
|
+
import Eleva from 'eleva';
|
|
479
|
+
import { Router } from 'eleva/plugins';
|
|
480
|
+
|
|
481
|
+
const app = new Eleva("myApp");
|
|
482
|
+
|
|
483
|
+
// Define components
|
|
484
|
+
const HomePage = { template: () => `<h1>Home</h1>` };
|
|
485
|
+
const AboutPage = { template: () => `<h1>About</h1>` };
|
|
486
|
+
const UserPage = {
|
|
487
|
+
template: (ctx) => `<h1>User: ${ctx.router.params.id}</h1>`
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// Install router with advanced configuration
|
|
491
|
+
const router = app.use(Router, {
|
|
492
|
+
mount: '#app', // Mount element selector
|
|
493
|
+
mode: 'hash', // 'hash', 'history', or 'query'
|
|
494
|
+
routes: [
|
|
495
|
+
{
|
|
496
|
+
path: '/',
|
|
497
|
+
component: HomePage,
|
|
498
|
+
meta: { title: 'Home' }
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
path: '/about',
|
|
502
|
+
component: AboutPage,
|
|
503
|
+
beforeEnter: (to, from) => {
|
|
504
|
+
// Navigation guard
|
|
505
|
+
return true;
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
path: '/users/:id',
|
|
510
|
+
component: UserPage,
|
|
511
|
+
afterEnter: (to, from) => {
|
|
512
|
+
// Lifecycle hook
|
|
513
|
+
console.log('User page entered');
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
],
|
|
517
|
+
onBeforeEach: (to, from) => {
|
|
518
|
+
// Global navigation guard
|
|
519
|
+
return true;
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
// Access reactive router state
|
|
524
|
+
router.currentRoute.subscribe(route => {
|
|
525
|
+
console.log('Route changed:', route);
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
// Programmatic navigation
|
|
529
|
+
router.navigate('/users/123', { replace: true });
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
📚 **[Full Router Documentation →](docs/plugins/router.md)** - Comprehensive guide with 13 events, 7 reactive signals, navigation guards, scroll management, and more.
|
|
533
|
+
|
|
534
|
+
#### PropsPlugin
|
|
535
|
+
|
|
536
|
+
🎯 **Advanced props handling** with automatic type detection, parsing, and reactivity for complex data structures:
|
|
537
|
+
|
|
538
|
+
```javascript
|
|
539
|
+
import Eleva from 'eleva';
|
|
540
|
+
import { Props } from 'eleva/plugins';
|
|
541
|
+
|
|
542
|
+
const app = new Eleva("myApp");
|
|
543
|
+
app.use(Props, {
|
|
544
|
+
enableAutoParsing: true, // Enable automatic type detection
|
|
545
|
+
enableReactivity: true, // Enable reactive prop updates
|
|
546
|
+
onError: (error, value) => {
|
|
547
|
+
console.error('Props parsing error:', error, value);
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
// Use complex props in components
|
|
552
|
+
app.component("UserCard", {
|
|
553
|
+
template: (ctx) => `
|
|
554
|
+
<div class="user-container"
|
|
555
|
+
:user='${JSON.stringify(ctx.user.value)}'
|
|
556
|
+
:permissions='${JSON.stringify(ctx.permissions.value)}'>
|
|
557
|
+
</div>
|
|
558
|
+
`,
|
|
559
|
+
children: {
|
|
560
|
+
'.user-container': 'UserInfo'
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
app.component("UserInfo", {
|
|
565
|
+
setup({ props }) {
|
|
566
|
+
return {
|
|
567
|
+
user: props.user, // Automatically parsed object
|
|
568
|
+
permissions: props.permissions // Automatically parsed array
|
|
569
|
+
};
|
|
570
|
+
},
|
|
571
|
+
template: (ctx) => `
|
|
572
|
+
<div class="user-info">
|
|
573
|
+
<h3>${ctx.user.value.name}</h3>
|
|
574
|
+
<p>Role: ${ctx.user.value.role}</p>
|
|
575
|
+
</div>
|
|
576
|
+
`
|
|
577
|
+
});
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
📚 **[Full Props Documentation →](docs/plugins/props.md)** - Comprehensive guide with type parsing, reactive props, signal linking, complex data structures, and error handling.
|
|
581
|
+
|
|
582
|
+
#### StorePlugin
|
|
583
|
+
|
|
584
|
+
🏪 **Reactive state management** with centralized data store, persistence, namespacing, and cross-component reactive updates:
|
|
585
|
+
|
|
586
|
+
```javascript
|
|
587
|
+
import Eleva from 'eleva';
|
|
588
|
+
import { Store } from 'eleva/plugins';
|
|
589
|
+
|
|
590
|
+
const app = new Eleva("myApp");
|
|
591
|
+
|
|
592
|
+
// Install store with configuration
|
|
593
|
+
app.use(Store, {
|
|
594
|
+
state: {
|
|
595
|
+
theme: "light",
|
|
596
|
+
counter: 0,
|
|
597
|
+
user: {
|
|
598
|
+
name: "John Doe",
|
|
599
|
+
email: "john@example.com"
|
|
600
|
+
}
|
|
601
|
+
},
|
|
602
|
+
actions: {
|
|
603
|
+
increment: (state) => state.counter.value++,
|
|
604
|
+
decrement: (state) => state.counter.value--,
|
|
605
|
+
toggleTheme: (state) => {
|
|
606
|
+
state.theme.value = state.theme.value === "light" ? "dark" : "light";
|
|
607
|
+
},
|
|
608
|
+
updateUser: (state, updates) => {
|
|
609
|
+
state.user.value = { ...state.user.value, ...updates };
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
// Optional: Namespaced modules
|
|
613
|
+
namespaces: {
|
|
614
|
+
auth: {
|
|
615
|
+
state: { token: null, isLoggedIn: false },
|
|
616
|
+
actions: {
|
|
617
|
+
login: (state, token) => {
|
|
618
|
+
state.auth.token.value = token;
|
|
619
|
+
state.auth.isLoggedIn.value = true;
|
|
620
|
+
},
|
|
621
|
+
logout: (state) => {
|
|
622
|
+
state.auth.token.value = null;
|
|
623
|
+
state.auth.isLoggedIn.value = false;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
// Optional: State persistence
|
|
629
|
+
persistence: {
|
|
630
|
+
enabled: true,
|
|
631
|
+
key: "myApp-store",
|
|
632
|
+
storage: "localStorage", // or "sessionStorage"
|
|
633
|
+
include: ["theme", "user"] // Only persist specific keys
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
// Use store in components
|
|
638
|
+
app.component("Counter", {
|
|
639
|
+
setup({ store }) {
|
|
640
|
+
return {
|
|
641
|
+
count: store.state.counter,
|
|
642
|
+
theme: store.state.theme,
|
|
643
|
+
increment: () => store.dispatch("increment"),
|
|
644
|
+
decrement: () => store.dispatch("decrement")
|
|
645
|
+
};
|
|
646
|
+
},
|
|
647
|
+
template: (ctx) => `
|
|
648
|
+
<div class="${ctx.theme.value}">
|
|
649
|
+
<h3>Counter: ${ctx.count.value}</h3>
|
|
650
|
+
<button @click="decrement">-</button>
|
|
651
|
+
<button @click="increment">+</button>
|
|
652
|
+
</div>
|
|
653
|
+
`
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
// Create state and actions at runtime
|
|
657
|
+
app.component("TodoManager", {
|
|
658
|
+
setup({ store }) {
|
|
659
|
+
// Register new module dynamically
|
|
660
|
+
store.registerModule("todos", {
|
|
661
|
+
state: { items: [], filter: "all" },
|
|
662
|
+
actions: {
|
|
663
|
+
addTodo: (state, text) => {
|
|
664
|
+
state.todos.items.value.push({
|
|
665
|
+
id: Date.now(),
|
|
666
|
+
text,
|
|
667
|
+
completed: false
|
|
668
|
+
});
|
|
669
|
+
},
|
|
670
|
+
toggleTodo: (state, id) => {
|
|
671
|
+
const todo = state.todos.items.value.find(t => t.id === id);
|
|
672
|
+
if (todo) todo.completed = !todo.completed;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
// Create individual state properties
|
|
678
|
+
const notification = store.createState("notification", null);
|
|
679
|
+
|
|
680
|
+
// Create individual actions
|
|
681
|
+
store.createAction("showNotification", (state, message) => {
|
|
682
|
+
state.notification.value = message;
|
|
683
|
+
setTimeout(() => state.notification.value = null, 3000);
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
return {
|
|
687
|
+
todos: store.state.todos.items,
|
|
688
|
+
notification,
|
|
689
|
+
addTodo: (text) => store.dispatch("todos.addTodo", text),
|
|
690
|
+
notify: (msg) => store.dispatch("showNotification", msg)
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
// Subscribe to store changes
|
|
696
|
+
const unsubscribe = app.store.subscribe((mutation, state) => {
|
|
697
|
+
console.log('Store updated:', mutation.type, state);
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
// Access store globally
|
|
701
|
+
console.log(app.store.getState()); // Get current state values
|
|
702
|
+
app.dispatch("increment"); // Dispatch actions globally
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
📚 **[Full Store Documentation →](docs/plugins/store.md)** - Comprehensive guide with 10 API methods, persistence options, namespaces, subscriptions, and migration guides.
|
|
706
|
+
|
|
707
|
+
**Bundle Sizes:**
|
|
708
|
+
- Core framework only: ~6KB (minified)
|
|
709
|
+
- Core + AttrPlugin: ~8KB (minified)
|
|
710
|
+
- Core + PropsPlugin: ~10KB (minified)
|
|
711
|
+
- Core + RouterPlugin: ~19KB (minified)
|
|
712
|
+
- Core + StorePlugin: ~12KB (minified)
|
|
713
|
+
- Core + All plugins: ~25KB (minified)
|
|
714
|
+
|
|
715
|
+
**Individual Plugin Sizes:**
|
|
716
|
+
- AttrPlugin: ~2.4KB (minified)
|
|
717
|
+
- PropsPlugin: ~4.2KB (minified)
|
|
718
|
+
- RouterPlugin: ~13KB (minified)
|
|
719
|
+
- StorePlugin: ~6KB (minified)
|
|
720
|
+
|
|
721
|
+
**Available Plugin Formats:**
|
|
722
|
+
|
|
723
|
+
**For Bundlers (Tree-Shaking Supported):**
|
|
724
|
+
- ESM: `import { Attr, Props, Router, Store } from 'eleva/plugins'`
|
|
725
|
+
- CJS: `const { Attr, Props, Router, Store } = require('eleva/plugins')`
|
|
726
|
+
|
|
727
|
+
**For CDN (Individual Plugins - Smaller Bundle Size):**
|
|
728
|
+
- UMD: `<script src="https://unpkg.com/eleva@latest/dist/eleva.umd.min.js"></script>`
|
|
729
|
+
- UMD: `<script src="https://unpkg.com/eleva@latest/dist/plugins/attr.umd.min.js"></script>`
|
|
730
|
+
- UMD: `<script src="https://unpkg.com/eleva@latest/dist/plugins/props.umd.min.js"></script>`
|
|
731
|
+
- UMD: `<script src="https://unpkg.com/eleva@latest/dist/plugins/router.umd.min.js"></script>`
|
|
732
|
+
- UMD: `<script src="https://unpkg.com/eleva@latest/dist/plugins/store.umd.min.js"></script>`
|
|
733
|
+
|
|
734
|
+
**Individual Plugin Imports (Best for Tree-Shaking):**
|
|
735
|
+
- ESM: `import { Attr } from 'eleva/plugins/attr'`
|
|
736
|
+
- ESM: `import { Props } from 'eleva/plugins/props'`
|
|
737
|
+
- ESM: `import { Router } from 'eleva/plugins/router'`
|
|
738
|
+
- ESM: `import { Store } from 'eleva/plugins/store'`
|
|
739
|
+
- CJS: `const { Attr } = require('eleva/plugins/attr')`
|
|
740
|
+
- CJS: `const { Props } = require('eleva/plugins/props')`
|
|
741
|
+
- CJS: `const { Router } = require('eleva/plugins/router')`
|
|
742
|
+
- CJS: `const { Store } = require('eleva/plugins/store')`
|
|
743
|
+
|
|
376
744
|
For detailed API documentation, please check the [docs](docs/index.md) folder.
|
|
377
745
|
|
|
378
746
|
---
|
|
@@ -453,7 +821,7 @@ Eleva is open-source and available under the [MIT License](LICENSE).
|
|
|
453
821
|
|
|
454
822
|
---
|
|
455
823
|
|
|
456
|
-
**Note:** This is a
|
|
824
|
+
**Note:** This is a release candidate (RC). The core functionality is stable and suitable for production use. Your feedback and contributions will help shape Eleva into something truly amazing. Let's build something great together! 💪✨
|
|
457
825
|
|
|
458
826
|
---
|
|
459
827
|
|