dalila 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +333 -0
  2. package/package.json +44 -0
package/README.md ADDED
@@ -0,0 +1,333 @@
1
+ # Dalila Framework
2
+
3
+ **UI driven by the DOM, not re-renders.**
4
+
5
+ Dalila is a **SPA**, **DOM-first**, **HTML natural** framework based on **signals**, created to eliminate the common pitfalls and workarounds of React.
6
+
7
+ ## โœจ Status
8
+
9
+ ### Core (runtime, stable)
10
+ - ๐Ÿš€ **Signals-based reactivity** - Automatic dependency tracking
11
+ - ๐ŸŽฏ **DOM-first rendering** - Direct DOM manipulation, no Virtual DOM
12
+ - ๐Ÿ”„ **Scope-based lifecycle** - Automatic cleanup (best effort)
13
+ - ๐Ÿ›ฃ๏ธ **SPA router** - Basic routing with loaders and AbortSignal
14
+ - ๐Ÿ“ฆ **Context system** - Reactive dependency injection
15
+ - ๐Ÿ”ง **Scheduler & batching** - Group updates into a single frame
16
+ - ๐Ÿ“š **List rendering** - `createList` for keyed lists
17
+ - ๐Ÿงฑ **Resources** - Async data helpers with AbortSignal and scope cleanup
18
+
19
+ ### Experimental
20
+ - ๐ŸŽจ **Natural HTML bindings** - Only in the example dev-server (not in core)
21
+ - ๐Ÿ“Š **Virtualization** - Virtual lists/tables are experimental
22
+ - ๐Ÿ” **DevTools (console)** - Warnings and FPS monitor only
23
+ - ๐Ÿงช **Low-level list API** - `forEach` (experimental, prefer `createList`)
24
+
25
+ ### Planned / Roadmap
26
+ - ๐Ÿงฐ **DevTools UI** - Visual inspection tooling
27
+ - ๐Ÿงฉ **HTML bindings runtime/compiler** - First-class template binding
28
+
29
+ ## ๐Ÿ“ฆ Installation
30
+
31
+ ```bash
32
+ npm install dalila
33
+ ```
34
+
35
+ ## ๐Ÿš€ Quick Start
36
+
37
+ Dalila examples use HTML bindings and a controller:
38
+
39
+ ```html
40
+ <div>
41
+ <span>{count}</span>
42
+ <button on:click={increment}>+</button>
43
+ </div>
44
+ ```
45
+
46
+ ```ts
47
+ import { signal } from 'dalila';
48
+
49
+ export function createController() {
50
+ const count = signal(0);
51
+ const increment = () => count.update(c => c + 1);
52
+
53
+ return { count, increment };
54
+ }
55
+ ```
56
+
57
+ > Note: HTML bindings in this example are provided by the example dev-server,
58
+ > not by the core runtime.
59
+
60
+ ## ๐Ÿงช Local Demo Server
61
+
62
+ Run a local server with HMR from the repo root:
63
+
64
+ ```bash
65
+ npm run serve
66
+ ```
67
+
68
+ Then open `http://localhost:3000/`.
69
+
70
+ ## ๐Ÿ“š Core Concepts
71
+
72
+ ### Signals
73
+ ```typescript
74
+ const count = signal(0);
75
+
76
+ // Read value
77
+ console.log(count()); // 0
78
+
79
+ // Set value
80
+ count.set(5);
81
+
82
+ // Update with function
83
+ count.update(c => c + 1);
84
+
85
+ // Reactive effects
86
+ effect(() => {
87
+ console.log(`Count changed to: ${count()}`);
88
+ });
89
+
90
+ // Async effects with cleanup
91
+ effectAsync(async (signal) => {
92
+ const response = await fetch('/api/data', { signal });
93
+ const data = await response.json();
94
+ console.log(data);
95
+ });
96
+ ```
97
+
98
+ ### Conditional Rendering
99
+ ```html
100
+ <p when={showTips}>This shows when true.</p>
101
+ <div match={status}>
102
+ <span case="idle">Idle</span>
103
+ <span case="active">Active</span>
104
+ </div>
105
+ ```
106
+
107
+ > Note: `when`/`match` bindings are available only in the example dev-server today.
108
+ > They are not part of the core runtime yet.
109
+
110
+ ### Context (Dependency Injection)
111
+ ```ts
112
+ const Theme = createContext<'light' | 'dark'>('theme');
113
+ provide(Theme, signal('light'));
114
+ const theme = inject(Theme);
115
+ ```
116
+
117
+ ### SPA Router
118
+ ```typescript
119
+ const router = createRouter({
120
+ routes: [
121
+ {
122
+ path: '/',
123
+ view: HomePage,
124
+ loader: async ({ signal }) => {
125
+ const res = await fetch('/api/home', { signal });
126
+ return res.json();
127
+ }
128
+ },
129
+ { path: '/users/:id', view: UserPage }
130
+ ]
131
+ });
132
+
133
+ router.mount(document.getElementById('app'));
134
+ ```
135
+
136
+ ### Batching & Scheduling
137
+ ```typescript
138
+ // Batch multiple updates into single frame
139
+ batch(() => {
140
+ count.set(1);
141
+ theme.set('dark');
142
+ // All updates happen in one frame
143
+ });
144
+
145
+ // DOM read/write discipline
146
+ const width = measure(() => element.offsetWidth);
147
+ mutate(() => {
148
+ element.style.width = `${width + 10}px`;
149
+ });
150
+ ```
151
+
152
+ ### List Rendering with Keys
153
+ ```typescript
154
+ // Primary API (stable)
155
+ createList(
156
+ todos,
157
+ (todo) => div(todo.text)
158
+ );
159
+
160
+ // Experimental low-level API
161
+ forEach(
162
+ items,
163
+ (item) => div(item.name),
164
+ (item) => item.id // Key function
165
+ );
166
+ ```
167
+
168
+ ### Resource Management
169
+ ```typescript
170
+ // Declarative data fetching
171
+ const { data, loading, error, refresh } = createResource(
172
+ async (signal) => {
173
+ const res = await fetch('/api/data', { signal });
174
+ return res.json();
175
+ }
176
+ );
177
+
178
+ // Signals
179
+ effect(() => {
180
+ console.log(data(), loading(), error());
181
+ });
182
+
183
+ // Cached resource
184
+ const cachedData = createCachedResource(
185
+ 'user-data',
186
+ async (signal) => fetchUser(signal)
187
+ );
188
+
189
+ // Auto-refresh
190
+ const liveData = createAutoRefreshResource(
191
+ fetchData,
192
+ 5000 // Refresh every 5 seconds
193
+ );
194
+ ```
195
+
196
+ ### Virtualization (experimental)
197
+ ```typescript
198
+ // Virtual list
199
+ createVirtualList(
200
+ items,
201
+ 50, // Item height
202
+ (item) => div(item.name),
203
+ { container: document.getElementById('list') }
204
+ );
205
+
206
+ // Virtual table
207
+ createVirtualTable(
208
+ data,
209
+ [
210
+ { key: 'id', header: 'ID', width: '100px' },
211
+ { key: 'name', header: 'Name', width: '200px' }
212
+ ],
213
+ (item, column) => div(item[column.key]),
214
+ document.getElementById('table')
215
+ );
216
+
217
+ // Infinite scroll
218
+ const { items, loading, refresh } = createInfiniteScroll(
219
+ (offset, limit) => fetchItems(offset, limit),
220
+ (item) => div(item.name),
221
+ document.getElementById('scroll-container')
222
+ );
223
+ ```
224
+
225
+ ### DevTools & Warnings (console-only)
226
+ ```typescript
227
+ // Enable dev tools
228
+ initDevTools();
229
+
230
+ // Inspect signals
231
+ const { value, subscribers } = inspectSignal(count);
232
+
233
+ // Get active effects
234
+ const effects = getActiveEffects();
235
+
236
+ // Performance monitoring (automatic, console warnings)
237
+ monitorPerformance();
238
+ ```
239
+
240
+ > There is no DevTools UI yet. The current tooling is lightweight console diagnostics.
241
+
242
+ ### Cleanup Utilities
243
+ ```typescript
244
+ // Event listener with auto-cleanup
245
+ useEvent(window, 'resize', handleResize);
246
+
247
+ // Interval with auto-cleanup
248
+ useInterval(() => {
249
+ console.log('Tick');
250
+ }, 1000);
251
+
252
+ // Timeout with auto-cleanup
253
+ useTimeout(() => {
254
+ console.log('Delayed');
255
+ }, 2000);
256
+
257
+ // Fetch with auto-cleanup
258
+ const { data, loading, error } = useFetch('/api/data');
259
+ ```
260
+
261
+ ## ๐Ÿ—๏ธ Architecture
262
+
263
+ Dalila is built around these core principles:
264
+
265
+ - **No JSX** - Core runtime doesn't require JSX
266
+ - **No Virtual DOM** - Direct DOM manipulation
267
+ - **No manual memoization** - Signals reduce manual memoization (goal)
268
+ - **Scope-based cleanup** - Automatic resource management (best-effort)
269
+ - **Signal-driven reactivity** - Localized updates where possible
270
+
271
+ ## ๐Ÿ“Š Performance
272
+
273
+ - **Localized updates**: Signals update only subscribed DOM nodes (goal)
274
+ - **Automatic cleanup**: Scope-based cleanup is best-effort
275
+ - **Bundle size**: Not yet measured/verified
276
+
277
+ ## ๐Ÿค” Why Dalila vs React?
278
+
279
+ | Feature | React | Dalila |
280
+ |---------|-------|--------|
281
+ | Rendering | Virtual DOM diffing | Direct DOM manipulation |
282
+ | Performance | Manual optimization | Runtime scheduling (best-effort) |
283
+ | State management | Hooks + deps arrays | Signals + automatic tracking |
284
+ | Side effects | `useEffect` + deps | `effect()` + automatic cleanup |
285
+ | Bundle size | ~40KB | Not yet measured |
286
+
287
+ ## ๐Ÿ“ Project Structure
288
+
289
+ ```
290
+ dalila/
291
+ โ”œโ”€โ”€ src/
292
+ โ”‚ โ”œโ”€โ”€ core/ # Signals, effects, scopes
293
+ โ”‚ โ”œโ”€โ”€ context/ # Dependency injection
294
+ โ”‚ โ”œโ”€โ”€ router/ # SPA routing
295
+ โ”‚ โ”œโ”€โ”€ dom/ # DOM utilities
296
+ โ”‚ โ””โ”€โ”€ index.ts # Main exports
297
+ โ”œโ”€โ”€ examples/ # Example applications
298
+ โ””โ”€โ”€ dist/ # Compiled output
299
+ ```
300
+
301
+ ## ๐Ÿ› ๏ธ Development
302
+
303
+ ```bash
304
+ # Install dependencies
305
+ npm install
306
+
307
+ # Build the framework
308
+ npm run build
309
+
310
+ # Development mode
311
+ npm run dev
312
+ ```
313
+
314
+ ## ๐Ÿ“– Examples
315
+
316
+ Check out the `examples/` directory for:
317
+ - Counter app
318
+
319
+ ## ๐Ÿค Contributing
320
+
321
+ Contributions welcome! Focus on:
322
+ - Maintaining core principles (no JSX, no VDOM, no manual optimization)
323
+ - Adding features that reduce boilerplate
324
+ - Improving performance without complexity
325
+ - Enhancing developer experience
326
+
327
+ ## ๐Ÿ“„ License
328
+
329
+ MIT
330
+
331
+ ---
332
+
333
+ **Build UI, not workarounds.**
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "dalila",
3
+ "version": "1.0.0",
4
+ "description": "DOM-first reactive framework based on signals",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "serve": "node scripts/dev-server.js",
11
+ "test": "jest",
12
+ "test:watch": "jest --watch",
13
+ "clean": "rm -rf dist"
14
+ },
15
+ "keywords": [
16
+ "framework",
17
+ "reactive",
18
+ "signals",
19
+ "dom",
20
+ "typescript",
21
+ "spa"
22
+ ],
23
+ "author": "Everton Da Silva Vieira",
24
+ "license": "MIT",
25
+ "devDependencies": {
26
+ "@types/jest": "^29.5.0",
27
+ "@types/node": "^20.0.0",
28
+ "jest": "^29.5.0",
29
+ "jest-environment-jsdom": "^29.5.0",
30
+ "typescript": "^5.0.0"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "README.md"
35
+ ],
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/evertondsvieira/dalila.git"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/evertondsvieira/dalila/issues"
42
+ },
43
+ "homepage": "https://github.com/evertondsvieira/dalila/blob/main/README.md"
44
+ }