eleva 1.0.0-alpha → 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/LICENSE +1 -1
- package/README.md +554 -137
- 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 +1448 -0
- package/dist/eleva.cjs.js.map +1 -0
- package/dist/eleva.d.ts +1057 -80
- package/dist/eleva.esm.js +1230 -274
- package/dist/eleva.esm.js.map +1 -1
- package/dist/eleva.umd.js +1230 -274
- package/dist/eleva.umd.js.map +1 -1
- package/dist/eleva.umd.min.js +3 -0
- package/dist/eleva.umd.min.js.map +1 -0
- 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 +240 -62
- package/src/core/Eleva.js +552 -145
- package/src/modules/Emitter.js +154 -18
- package/src/modules/Renderer.js +288 -86
- package/src/modules/Signal.js +132 -13
- package/src/modules/TemplateEngine.js +153 -27
- 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 +482 -48
- package/types/core/Eleva.d.ts.map +1 -1
- package/types/modules/Emitter.d.ts +151 -20
- package/types/modules/Emitter.d.ts.map +1 -1
- package/types/modules/Renderer.d.ts +151 -12
- package/types/modules/Renderer.d.ts.map +1 -1
- package/types/modules/Signal.d.ts +130 -16
- package/types/modules/Signal.d.ts.map +1 -1
- package/types/modules/TemplateEngine.d.ts +154 -14
- 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/dist/eleva.min.js +0 -2
- package/dist/eleva.min.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,25 +1,62 @@
|
|
|
1
|
-
#
|
|
1
|
+
# eleva.js 🚀
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
|
|
3
|
+
> **Version:** 1.0.0-rc.10 | **Size:** ~6KB min (~2KB gzip) | **Dependencies:** Zero | **TypeScript:** Yes
|
|
4
|
+
|
|
5
|
+
Pure JavaScript, Pure Performance, Simply Elegant.
|
|
5
6
|
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://github.com/TarekRaafat/eleva)
|
|
6
9
|
[](https://www.npmjs.com/package/eleva)
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+

|
|
11
|
+

|
|
12
|
+
[](https://codecov.io/gh/TarekRaafat/eleva)
|
|
13
|
+
[](https://bundlephobia.com/package/eleva@latest)
|
|
14
|
+
[](https://bundlephobia.com/package/eleva@latest)
|
|
15
|
+
[](https://www.jsdelivr.com/package/npm/eleva)
|
|
16
|
+
[](https://canonical.com)
|
|
17
|
+
|
|
18
|
+
<br>
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<a href="https://tarekraafat.github.io/eleva/"><img src="./docs/imgs/eleva.js Full Logo.png" alt="eleva.js Full Logo" width="50%"></a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
<a href="https://canonical.com" target="_blank" rel="noopener">
|
|
26
|
+
<img src="https://raw.githubusercontent.com/SebastJava/Ubuntu-logo/649d55eca403302fb06281d9dd94798bb0568e8d/logo-v2025-plain-450x708.svg" alt="Canonical Logo" width="80"/>
|
|
27
|
+
</a>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<em>Eleva.js is proudly supported by Canonical - the company behind Ubuntu.</em>
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<a href="https://www.producthunt.com/posts/eleva?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-eleva" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=938663&theme=light&t=1741247713068" alt="eleva.js - A minimalist, pure vanilla javascript frontend framework. | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<br>
|
|
39
|
+
<br>
|
|
40
|
+
<br>
|
|
41
|
+
|
|
42
|
+
**A minimalist, lightweight, pure vanilla JavaScript frontend runtime framework.**
|
|
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!_ 😊
|
|
9
44
|
|
|
10
|
-
> **Stability Notice**: This is `v1.0.0-
|
|
11
|
-
> Not recommended for production use yet. Follow the [versioning guide](#versioning) for updates.
|
|
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.
|
|
12
46
|
|
|
13
|
-
**Version:** `1.0.0-
|
|
47
|
+
**Version:** `1.0.0-rc.10`
|
|
14
48
|
|
|
15
|
-
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
Welcome to Eleva! This is my humble, experimental playground for a fresh approach to frontend development. Eleva was born out of my genuine passion for pure vanilla JavaScript-no frameworks, no bloat, just the power of native code. I hope you'll have fun exploring, testing, and contributing to make Eleva even better. 🚀
|
|
16
52
|
|
|
17
53
|
---
|
|
18
54
|
|
|
19
55
|
## Table of Contents
|
|
20
56
|
|
|
21
|
-
- [
|
|
57
|
+
- [eleva.js 🚀](#elevajs-)
|
|
22
58
|
- [Table of Contents](#table-of-contents)
|
|
59
|
+
- [Quick Reference](#quick-reference)
|
|
23
60
|
- [Introduction](#introduction)
|
|
24
61
|
- [Design Philosophy](#design-philosophy)
|
|
25
62
|
- [Handcrafted \& Developer-Centric Design](#handcrafted--developer-centric-design)
|
|
@@ -40,6 +77,12 @@ Welcome to Eleva! This is my humble, experimental playground for a fresh approac
|
|
|
40
77
|
- [Emitter](#emitter)
|
|
41
78
|
- [Renderer](#renderer)
|
|
42
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)
|
|
43
86
|
- [Development](#development)
|
|
44
87
|
- [Testing](#testing)
|
|
45
88
|
- [Contributing](#contributing)
|
|
@@ -48,52 +91,84 @@ Welcome to Eleva! This is my humble, experimental playground for a fresh approac
|
|
|
48
91
|
|
|
49
92
|
---
|
|
50
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
|
+
|
|
51
133
|
## Introduction
|
|
52
134
|
|
|
53
|
-
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
|
|
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.
|
|
54
136
|
|
|
55
137
|
**My Inspiration:**
|
|
56
|
-
The idea
|
|
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.
|
|
57
139
|
|
|
58
140
|
**Core Principles:**
|
|
59
141
|
|
|
60
|
-
- **🌱 Minimalism:** Only the
|
|
61
|
-
- **🔌 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.
|
|
62
144
|
- **🚀 Performance:** Fast, efficient, and designed with modern browsers in mind.
|
|
63
|
-
- **🍦 Pure Vanilla:** No dependencies, no magic
|
|
145
|
+
- **🍦 Pure Vanilla:** No dependencies, no magic-just plain JavaScript.
|
|
64
146
|
|
|
65
147
|
---
|
|
66
148
|
|
|
67
149
|
## Design Philosophy
|
|
68
150
|
|
|
69
|
-
**Eleva is an unopinionated
|
|
151
|
+
**Eleva is an unopinionated framework with a minimal core philosophy.**
|
|
70
152
|
|
|
71
|
-
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:
|
|
72
154
|
|
|
73
|
-
- **🔄 Flexibility:**
|
|
74
|
-
- **🎯 Native JavaScript:**
|
|
75
|
-
- **⚙️ Configurability:**
|
|
76
|
-
- **🆓 Freedom:**
|
|
155
|
+
- **🔄 Flexibility:** Architect your application your way-no rigid structure required.
|
|
156
|
+
- **🎯 Native JavaScript:** Built using pure vanilla JavaScript, Eleva integrates seamlessly with your existing code without unfamiliar syntax.
|
|
157
|
+
- **⚙️ Configurability:** Extend Eleva's functionality with a simple API and optional plugins.
|
|
158
|
+
- **🆓 Freedom:** Decide the best way to implement features without unnecessary constraints.
|
|
77
159
|
|
|
78
|
-
This unopinionated approach makes Eleva versatile and ideal for developers who
|
|
160
|
+
This unopinionated approach makes Eleva versatile and ideal for developers who want full control over their application's design.
|
|
79
161
|
|
|
80
162
|
---
|
|
81
163
|
|
|
82
164
|
## Handcrafted & Developer-Centric Design
|
|
83
165
|
|
|
84
|
-
Eleva is built with
|
|
85
|
-
|
|
86
|
-
- **🎨 Craftsmanship:**
|
|
87
|
-
Every line of code in Eleva is written with care, ensuring that the library remains lightweight, efficient, and easy to understand.
|
|
166
|
+
Eleva is built with meticulous attention to detail and a deep passion for pure vanilla JavaScript. Every aspect of its design and architecture is handcrafted with the developer in mind. This makes Eleva not only innovative but also a solid foundation for your projects.
|
|
88
167
|
|
|
89
|
-
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
By sticking to pure vanilla JavaScript and avoiding unnecessary abstractions, Eleva offers a refreshing alternative to the complex and opinionated frameworks out there.
|
|
94
|
-
|
|
95
|
-
- **🏗️ Solid & Reliable:**
|
|
96
|
-
With a focus on performance and modularity, Eleva provides a robust yet flexible platform that scales with your project's needs.
|
|
168
|
+
- **🎨 Craftsmanship:** Every line of code is written with care, keeping the framework lightweight, efficient, and easy to understand.
|
|
169
|
+
- **🛠️ Developer-Centric:** Its intuitive API and minimal core mean you spend less time wrestling with the framework and more time building your application.
|
|
170
|
+
- **🌟 Innovative & Fresh:** Stick to pure vanilla JavaScript and avoid unnecessary abstractions.
|
|
171
|
+
- **🏗️ Solid & Reliable:** Focused on performance and modularity, Eleva scales with your project's needs.
|
|
97
172
|
|
|
98
173
|
This unique, developer-first approach makes Eleva a standout choice for building high-performance frontend applications without compromising on simplicity or control.
|
|
99
174
|
|
|
@@ -101,40 +176,35 @@ This unique, developer-first approach makes Eleva a standout choice for building
|
|
|
101
176
|
|
|
102
177
|
## Features
|
|
103
178
|
|
|
104
|
-
- **🧩 Component-Based Architecture:** Create reusable UI components
|
|
105
|
-
- **⚡ Signal-Based Reactivity:** Fine-grained reactivity that updates only what
|
|
106
|
-
- **🔔 Event Handling:** Built-in event emitter for robust inter-component communication
|
|
107
|
-
- **📝 Template Parsing:** Secure and dynamic interpolation with a custom TemplateEngine
|
|
108
|
-
- **🔄 DOM Diffing & Patching:** High-performance updates without a virtual DOM
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
179
|
+
- **🧩 Component-Based Architecture:** Create reusable UI components with a rich context API
|
|
180
|
+
- **⚡ Signal-Based Reactivity:** Fine-grained reactivity that updates only what's needed
|
|
181
|
+
- **🔔 Event Handling:** Built-in event emitter for robust inter-component communication
|
|
182
|
+
- **📝 Template Parsing:** Secure and dynamic interpolation with a custom TemplateEngine
|
|
183
|
+
- **🔄 DOM Diffing & Patching:** High-performance updates without a virtual DOM
|
|
184
|
+
- **🔄 Lifecycle Hooks:** Complete lifecycle management with before/after mount and update hooks
|
|
185
|
+
- **🧹 Automatic Cleanup:** Proper cleanup of resources, watchers, and child components on unmount
|
|
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
|
|
188
|
+
- **📦 UMD & ES Module Builds:** Supports modern build tools and browser environments
|
|
189
|
+
- **🤝 Friendly API:** A gentle learning curve for both beginners and seasoned developers
|
|
190
|
+
- **💎 Tiny Footprint & TypeScript Support:** Approximately ~6 KB minified with built-in TypeScript declarations
|
|
112
191
|
|
|
113
192
|
---
|
|
114
193
|
|
|
115
194
|
## When to Use Eleva
|
|
116
195
|
|
|
117
|
-
Eleva is
|
|
118
|
-
|
|
119
|
-
- **🚀 Small to Medium Projects:**
|
|
120
|
-
If you're building a web app or website that doesn't require the overhead of a full-fledged framework, Eleva’s minimal footprint (~4 KB minified) keeps your project fast and efficient.
|
|
196
|
+
Eleva is ideal for developers seeking a lightweight, flexible, and high-performance solution for building frontend applications. Here are some scenarios where Eleva shines:
|
|
121
197
|
|
|
122
|
-
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
-
|
|
132
|
-
Eleva's simplicity and ease of integration make it a great choice for prototyping ideas quickly. Its modular architecture means you can start small and extend the functionality as your project evolves.
|
|
133
|
-
|
|
134
|
-
- **🔌 Extensibility through Plugins:**
|
|
135
|
-
With a robust plugin system, Eleva can be easily extended to include features like routing, state management, or custom behaviors, making it suitable for both simple and complex applications.
|
|
136
|
-
|
|
137
|
-
In short, if you're looking for a solid, developer-centric framework that provides high performance, simplicity, and the freedom to build your application your way, Eleva is an excellent choice.
|
|
198
|
+
- **🚀 Small to Medium Projects:** Perfect for web apps or websites that don't require the overhead of a full-fledged framework.
|
|
199
|
+
- **⚡ Performance-Critical Applications:** Optimized reactivity and DOM diffing ensure smooth performance without bloat.
|
|
200
|
+
- **🔄 Unopinionated & Flexible:** Architect your application your way with a straightforward API and plugin system.
|
|
201
|
+
- **🎯 Developer-Friendly:** Stick to pure vanilla JavaScript with familiar syntax and built-in TypeScript support.
|
|
202
|
+
- **🧪 Rapid Prototyping:** Quickly prototype ideas with a minimal and extendable framework.
|
|
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.
|
|
207
|
+
- **📦 Module Format Flexibility:** Choose from ESM, CommonJS, or UMD formats based on your project's needs.
|
|
138
208
|
|
|
139
209
|
---
|
|
140
210
|
|
|
@@ -142,80 +212,85 @@ In short, if you're looking for a solid, developer-centric framework that provid
|
|
|
142
212
|
|
|
143
213
|
I believe in clear versioning that reflects the maturity of the project:
|
|
144
214
|
|
|
145
|
-
- **Pre-release Versions (
|
|
146
|
-
- **Semantic Versioning:** Once
|
|
147
|
-
- **Fresh Start:** Since this is a complete overhaul and a fresh start, `1.0.0-alpha` represents my first major step forward.
|
|
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.
|
|
216
|
+
- **Semantic Versioning:** Once stable, I'll follow semantic versioning strictly to clearly communicate any breaking changes.
|
|
148
217
|
|
|
149
218
|
---
|
|
150
219
|
|
|
151
220
|
## Version Guide
|
|
152
221
|
|
|
153
|
-
I follow [Semantic Versioning (SemVer)](https://semver.org/)
|
|
154
|
-
|
|
155
|
-
- **🔢 Major Version:**
|
|
156
|
-
A change in the first digit (e.g., from `1.0.0` to `2.0.0`) indicates breaking changes or a major overhaul of the framework.
|
|
157
|
-
- **🔢 Minor Version:**
|
|
158
|
-
A change in the second digit (e.g., from `1.0.0` to `1.1.0`) signifies the addition of new features in a backward-compatible manner.
|
|
159
|
-
- **🔢 Patch Version:**
|
|
160
|
-
A change in the third digit (e.g., from `1.0.0` to `1.0.1`) reflects backward-compatible bug fixes and minor improvements.
|
|
161
|
-
- **📌 Pre-release Identifiers:**
|
|
162
|
-
Suffixes like `-alpha`, `-beta`, or `-rc` indicate that the release is not yet stable. For example, `1.0.0-alpha` means this is an experimental version of the upcoming stable `1.0.0` release.
|
|
222
|
+
I follow [Semantic Versioning (SemVer)](https://semver.org/):
|
|
163
223
|
|
|
164
|
-
|
|
224
|
+
- **🔢 Major Version:** Breaking changes or major overhauls (e.g., from `1.0.0` to `2.0.0`).
|
|
225
|
+
- **🔢 Minor Version:** New features in a backward-compatible manner (e.g., from `1.1.0` to `1.2.0`).
|
|
226
|
+
- **🔢 Patch Version:** Backward-compatible bug fixes and minor improvements (e.g., `1.0.1`).
|
|
227
|
+
- **📌 Pre-release Identifiers:** Suffixes like `-alpha`, `-beta`, or `-rc` denote unstable releases (e.g., `1.2.0-alpha`).
|
|
165
228
|
|
|
166
229
|
---
|
|
167
230
|
|
|
168
231
|
## Performance
|
|
169
232
|
|
|
170
|
-
Eleva is crafted
|
|
233
|
+
Eleva is crafted for performance:
|
|
171
234
|
|
|
172
|
-
- **Lightweight:**
|
|
173
|
-
- **Efficient Reactivity:** Signal-based updates ensure only
|
|
174
|
-
- **Optimized Diffing:**
|
|
175
|
-
- **No Bloat:** Pure vanilla JavaScript
|
|
235
|
+
- **Lightweight:** Approximately ~6 KB minified and ~2 KB gzipped.
|
|
236
|
+
- **Efficient Reactivity:** Signal-based updates ensure only necessary DOM parts are updated.
|
|
237
|
+
- **Optimized Diffing:** Renderer efficiently patches changes without the overhead of a virtual DOM.
|
|
238
|
+
- **No Bloat:** Pure vanilla JavaScript with zero dependencies keeps your project nimble.
|
|
239
|
+
- **Tree-Shakable:** ESM format allows bundlers to eliminate unused code.
|
|
240
|
+
- **Format-Specific Optimizations:** Each module format is optimized for its target environment.
|
|
176
241
|
|
|
177
242
|
---
|
|
178
243
|
|
|
179
244
|
## Performance Benchmarks
|
|
180
245
|
|
|
181
|
-
|
|
246
|
+
Preliminary benchmarks illustrate Eleva's efficiency compared to popular frameworks:
|
|
247
|
+
|
|
248
|
+
| **Framework** | **Bundle Size** (KB) | **Initial Load Time** (ms) | **DOM Update Speed** (s) | **Peak Memory Usage** (KB) | **Overall Performance Score** (lower is better) |
|
|
249
|
+
| ----------------------------- | -------------------- | -------------------------- | ------------------------ | -------------------------- | ----------------------------------------------- |
|
|
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) |
|
|
182
254
|
|
|
183
|
-
|
|
184
|
-
| --------- | ---------------------- | ----------------- | ---------------- |
|
|
185
|
-
| **Eleva** | ~4 KB | ~35 ms | ~2 ms |
|
|
186
|
-
| React | ~110 KB | ~100 ms | ~4 ms |
|
|
187
|
-
| Vue | ~80 KB | ~80 ms | ~3 ms |
|
|
188
|
-
| Angular | ~500 KB | ~250 ms | ~6 ms |
|
|
255
|
+
Detailed [Benchmark Metrics Report](BENCHMARK.md)
|
|
189
256
|
|
|
190
|
-
> ⚠️ **Disclaimer:**
|
|
257
|
+
> ⚠️ **Disclaimer:** Benchmarks are based on internal tests and may vary by project and environment.
|
|
191
258
|
|
|
192
259
|
---
|
|
193
260
|
|
|
194
261
|
## Eleva vs. Popular Frameworks
|
|
195
262
|
|
|
196
|
-
|
|
263
|
+
Eleva offers a refreshing alternative to frameworks like React, Vue, and Angular:
|
|
197
264
|
|
|
198
|
-
- **Simplicity:** No virtual DOM,
|
|
199
|
-
- **Modularity:** Easily extend
|
|
200
|
-
- **Size:**
|
|
201
|
-
- **Learning Curve:**
|
|
265
|
+
- **Simplicity:** No virtual DOM, JSX, or complex state management-just plain JavaScript.
|
|
266
|
+
- **Modularity:** Easily extend via plugins to suit your project's needs.
|
|
267
|
+
- **Size:** A fraction of the size of mainstream frameworks.
|
|
268
|
+
- **Learning Curve:** Familiar syntax and a clear API make it accessible to all developers.
|
|
202
269
|
|
|
203
|
-
|
|
270
|
+
_Note:_ Eleva isn't trying to replace these giants but provides a lightweight option when you want simplicity and speed. 🌟
|
|
204
271
|
|
|
205
272
|
---
|
|
206
273
|
|
|
207
274
|
## Installation
|
|
208
275
|
|
|
209
|
-
Eleva is available on npm.
|
|
276
|
+
Eleva is available on npm. Try it out and share your thoughts!
|
|
210
277
|
|
|
211
278
|
```bash
|
|
212
279
|
npm install eleva
|
|
213
280
|
```
|
|
214
281
|
|
|
215
|
-
Or include it directly
|
|
282
|
+
Or include it directly via CDN:
|
|
216
283
|
|
|
217
284
|
```html
|
|
218
|
-
|
|
285
|
+
<!-- jsDelivr (Recommended) -->
|
|
286
|
+
<script src="https://cdn.jsdelivr.net/npm/eleva"></script>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
or
|
|
290
|
+
|
|
291
|
+
```html
|
|
292
|
+
<!-- unpkg -->
|
|
293
|
+
<script src="https://unpkg.com/eleva"></script>
|
|
219
294
|
```
|
|
220
295
|
|
|
221
296
|
---
|
|
@@ -226,33 +301,46 @@ Or include it directly in your HTML via CDN:
|
|
|
226
301
|
|
|
227
302
|
```js
|
|
228
303
|
// Import Eleva (using ES modules)
|
|
229
|
-
import
|
|
304
|
+
import Eleva from "eleva";
|
|
230
305
|
|
|
231
306
|
// Create a new Eleva instance
|
|
232
307
|
const app = new Eleva("MyApp");
|
|
233
308
|
|
|
234
309
|
// Define a component
|
|
235
310
|
app.component("HelloWorld", {
|
|
311
|
+
// The setup method is optional; if omitted, an empty state is used.
|
|
236
312
|
setup({ signal }) {
|
|
237
313
|
const count = signal(0);
|
|
238
|
-
return {
|
|
314
|
+
return {
|
|
315
|
+
count,
|
|
316
|
+
onMount: ({ container, context }) => {
|
|
317
|
+
console.log('Component mounted!');
|
|
318
|
+
}
|
|
319
|
+
};
|
|
239
320
|
},
|
|
240
321
|
template: ({ count }) => `
|
|
241
322
|
<div>
|
|
242
323
|
<h1>Hello, Eleva! 👋</h1>
|
|
243
|
-
<p>Count: ${count}</p>
|
|
244
|
-
<button @click="() => count++">Increment</button>
|
|
324
|
+
<p>Count: ${count.value}</p>
|
|
325
|
+
<button @click="() => count.value++">Increment</button>
|
|
245
326
|
</div>
|
|
246
|
-
|
|
327
|
+
`
|
|
247
328
|
});
|
|
248
329
|
|
|
249
|
-
// Mount the component
|
|
250
|
-
app.mount("
|
|
330
|
+
// Mount the component and handle the Promise
|
|
331
|
+
app.mount(document.getElementById("app"), "HelloWorld")
|
|
332
|
+
.then(instance => {
|
|
333
|
+
console.log("Component mounted:", instance);
|
|
334
|
+
// Later...
|
|
335
|
+
// instance.unmount();
|
|
336
|
+
});
|
|
251
337
|
```
|
|
252
338
|
|
|
339
|
+
Interactive Demo: [CodePen](https://codepen.io/tarekraafat/pen/GgRrxdY?editors=1010)
|
|
340
|
+
|
|
253
341
|
### UMD Example
|
|
254
342
|
|
|
255
|
-
Include Eleva via a script tag
|
|
343
|
+
Include Eleva via a script tag and use the global variable:
|
|
256
344
|
|
|
257
345
|
```html
|
|
258
346
|
<!DOCTYPE html>
|
|
@@ -263,7 +351,7 @@ Include Eleva via a script tag, and it will be available as a global variable:
|
|
|
263
351
|
</head>
|
|
264
352
|
<body>
|
|
265
353
|
<div id="app"></div>
|
|
266
|
-
<script src="https://
|
|
354
|
+
<script src="https://cdn.jsdelivr.net/npm/eleva"></script>
|
|
267
355
|
<script>
|
|
268
356
|
const app = new Eleva("MyApp");
|
|
269
357
|
app.component("HelloWorld", {
|
|
@@ -272,56 +360,58 @@ Include Eleva via a script tag, and it will be available as a global variable:
|
|
|
272
360
|
return { count };
|
|
273
361
|
},
|
|
274
362
|
template: ({ count }) => `
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
363
|
+
<div>
|
|
364
|
+
<h1>Hello, Eleva! 👋</h1>
|
|
365
|
+
<p>Count: ${count.value}</p>
|
|
366
|
+
<button @click="() => count.value++">Increment</button>
|
|
367
|
+
</div>
|
|
368
|
+
`,
|
|
281
369
|
});
|
|
282
|
-
app.mount("
|
|
370
|
+
app.mount(document.getElementById("app"), "HelloWorld");
|
|
283
371
|
</script>
|
|
284
372
|
</body>
|
|
285
373
|
</html>
|
|
286
374
|
```
|
|
287
375
|
|
|
376
|
+
Interactive Demo: [CodePen](https://codepen.io/tarekraafat/pen/jEOyzYN?editors=1010)
|
|
377
|
+
|
|
288
378
|
---
|
|
289
379
|
|
|
290
380
|
## API Reference
|
|
291
381
|
|
|
292
382
|
### TemplateEngine
|
|
293
383
|
|
|
294
|
-
- **`TemplateEngine.parse(template, data)`**
|
|
384
|
+
- **`TemplateEngine.parse(template, data)`**
|
|
295
385
|
Replaces `{{ expression }}` patterns in the template with evaluated values.
|
|
296
|
-
- **`TemplateEngine.evaluate(expr, data)`**
|
|
386
|
+
- **`TemplateEngine.evaluate(expr, data)`**
|
|
297
387
|
Safely evaluates JavaScript expressions within a given context.
|
|
298
388
|
|
|
299
389
|
### Signal
|
|
300
390
|
|
|
301
|
-
- **`new Signal(
|
|
391
|
+
- **`new Signal(initialValue)`**
|
|
302
392
|
Creates a reactive data holder.
|
|
303
|
-
- **`.value` (getter/setter)**
|
|
393
|
+
- **`.value` (getter/setter)**
|
|
304
394
|
Get or update the current value and trigger watchers.
|
|
305
|
-
- **`.watch(
|
|
395
|
+
- **`.watch(callback)`**
|
|
306
396
|
Registers a function to run when the value updates.
|
|
307
397
|
|
|
308
398
|
### Emitter
|
|
309
399
|
|
|
310
|
-
-
|
|
400
|
+
- **`new Emitter()`**
|
|
401
|
+
Creates an Emitter instance.
|
|
402
|
+
- **`.on(event, handler)`**
|
|
311
403
|
Listen to events.
|
|
312
|
-
- **`.off(event, handler)`**
|
|
404
|
+
- **`.off(event, handler)`**
|
|
313
405
|
Remove event listeners.
|
|
314
|
-
- **`.emit(event, ...args)`**
|
|
406
|
+
- **`.emit(event, ...args)`**
|
|
315
407
|
Trigger events with additional arguments.
|
|
316
408
|
|
|
317
409
|
### Renderer
|
|
318
410
|
|
|
319
|
-
- **`
|
|
320
|
-
|
|
321
|
-
-
|
|
322
|
-
|
|
323
|
-
- **`updateAttributes(oldEl, newEl)`**
|
|
324
|
-
Sync element attributes.
|
|
411
|
+
- **`new Renderer()`**
|
|
412
|
+
Creates a Renderer instance.
|
|
413
|
+
- **`.patchDOM(container, newHtml)`**:
|
|
414
|
+
Updates container content with the new HTML.
|
|
325
415
|
|
|
326
416
|
### Eleva (Core)
|
|
327
417
|
|
|
@@ -331,16 +421,333 @@ Include Eleva via a script tag, and it will be available as a global variable:
|
|
|
331
421
|
Install plugins.
|
|
332
422
|
- **`.component(name, definition)`**
|
|
333
423
|
Register a component.
|
|
334
|
-
- **`.mount(
|
|
424
|
+
- **`.mount(container, compName, props)`**
|
|
335
425
|
Mount a component to the DOM.
|
|
336
426
|
|
|
337
|
-
|
|
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
|
+
|
|
744
|
+
For detailed API documentation, please check the [docs](docs/index.md) folder.
|
|
338
745
|
|
|
339
746
|
---
|
|
340
747
|
|
|
341
748
|
## Development
|
|
342
749
|
|
|
343
|
-
I welcome developers to dive in and
|
|
750
|
+
I welcome developers to dive in and experiment with Eleva! Here's how to get started locally:
|
|
344
751
|
|
|
345
752
|
1. **Clone the Repository:**
|
|
346
753
|
|
|
@@ -361,7 +768,7 @@ I welcome developers to dive in and play around with Eleva! Here's how you can g
|
|
|
361
768
|
npm run dev
|
|
362
769
|
```
|
|
363
770
|
|
|
364
|
-
4. **Build for Production:**
|
|
771
|
+
4. **Build for Production without TypeScript Declarations:**
|
|
365
772
|
|
|
366
773
|
```bash
|
|
367
774
|
npm run build
|
|
@@ -374,23 +781,29 @@ I welcome developers to dive in and play around with Eleva! Here's how you can g
|
|
|
374
781
|
npm run build:types:bundle
|
|
375
782
|
```
|
|
376
783
|
|
|
784
|
+
6. **Build for Production with TypeScript Declarations:**
|
|
785
|
+
|
|
786
|
+
```bash
|
|
787
|
+
npm run build:all
|
|
788
|
+
```
|
|
789
|
+
|
|
377
790
|
---
|
|
378
791
|
|
|
379
792
|
## Testing
|
|
380
793
|
|
|
381
|
-
I use Jest for
|
|
794
|
+
I use Jest for testing. Run the test suite with:
|
|
382
795
|
|
|
383
796
|
```bash
|
|
384
797
|
npm test
|
|
385
798
|
```
|
|
386
799
|
|
|
387
|
-
|
|
800
|
+
Contributions to tests are very welcome! 🧪
|
|
388
801
|
|
|
389
802
|
---
|
|
390
803
|
|
|
391
804
|
## Contributing
|
|
392
805
|
|
|
393
|
-
I
|
|
806
|
+
I'd love to have you onboard as a contributor! Whether you're adding new features, squashing bugs, or sharing ideas, your input is invaluable. Please check out [CONTRIBUTING](CONTRIBUTING.md) for guidelines on getting started.
|
|
394
807
|
|
|
395
808
|
---
|
|
396
809
|
|
|
@@ -408,11 +821,15 @@ Eleva is open-source and available under the [MIT License](LICENSE).
|
|
|
408
821
|
|
|
409
822
|
---
|
|
410
823
|
|
|
411
|
-
**Note:** This is
|
|
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! 💪✨
|
|
825
|
+
|
|
826
|
+
---
|
|
827
|
+
|
|
828
|
+
[](https://nodei.co/npm/eleva/)
|
|
412
829
|
|
|
413
830
|
---
|
|
414
831
|
|
|
415
832
|
[Documentation](/docs/index.md) |
|
|
416
833
|
[Examples](/examples) |
|
|
417
|
-
[Changelog](
|
|
834
|
+
[Changelog](/CHANGELOG.md) |
|
|
418
835
|
[GitHub Discussions](https://github.com/TarekRaafat/eleva/discussions)
|