@kaiserofthenight/human-js 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.
package/README.md ADDED
@@ -0,0 +1,545 @@
1
+ # 🦉 HumanJS Framework
2
+
3
+ **A framework built for humans, not machines.**
4
+
5
+ Simple. Readable. Easy to extend. Zero magic. No build tools required.
6
+
7
+ ---
8
+
9
+ ## 🌟 Philosophy
10
+
11
+ HumanJS prioritizes human understanding over machine optimization.
12
+
13
+ ### Core Principles
14
+
15
+ 1. **Zero Magic** - Every behavior is traceable in ~200 lines of code
16
+ 2. **Human-First API** - Read like English sentences
17
+ 3. **Minimal Abstractions** - Use native DOM APIs when possible
18
+ 4. **Easy to Extend** - Modify the source, don't fight it
19
+ 5. **No Heavy Dependencies** - Pure JavaScript (ES6+), browser APIs only
20
+
21
+ ---
22
+
23
+ ## 🚀 Quick Start
24
+
25
+ ### 1. Clone or Download
26
+
27
+ ```bash
28
+ git clone https://github.com/kaiserofthenight/humanjs.git
29
+ cd humanjs
30
+ ```
31
+
32
+ ### 2. Open in Browser
33
+
34
+ ```bash
35
+ # No build step required!
36
+ # Just open index.html in your browser
37
+ open index.html
38
+ ```
39
+
40
+ ### 3. Your First App
41
+
42
+ ```javascript
43
+ import { app, html } from './src/index.js';
44
+
45
+ app.create({
46
+ state: { count: 0 },
47
+
48
+ render: (state) => {
49
+ const element = html`
50
+ <div style="padding: 40px; text-align: center;">
51
+ <h1>Count: ${state.count}</h1>
52
+ <button id="increment">+1</button>
53
+ </div>
54
+ `;
55
+
56
+ const events = {
57
+ '#increment': {
58
+ click: () => state.count += 1
59
+ }
60
+ };
61
+
62
+ return { element, events };
63
+ }
64
+ });
65
+ ```
66
+
67
+ **That's it!** No compilation, no bundling, no configuration.
68
+
69
+ ---
70
+
71
+ ## 📚 Core Concepts
72
+
73
+ ### 1. Reactive State
74
+
75
+ ```javascript
76
+ import { createState } from './src/index.js';
77
+
78
+ const state = createState({ count: 0 }, (prop, value) => {
79
+ console.log(`${prop} changed to ${value}`);
80
+ });
81
+
82
+ state.count = 5; // Triggers callback
83
+ ```
84
+
85
+ **Advanced state features:**
86
+
87
+ ```javascript
88
+ // Watch specific properties
89
+ state.$watch('count', (newVal, oldVal) => {
90
+ console.log(`Count: ${oldVal} → ${newVal}`);
91
+ });
92
+
93
+ // Computed properties
94
+ state.$computed('double', function() {
95
+ return this.count * 2;
96
+ });
97
+
98
+ // Reset state
99
+ state.$reset({ count: 0 });
100
+
101
+ // Get raw state
102
+ const raw = state.$raw();
103
+ ```
104
+
105
+ ### 2. HTML Rendering
106
+
107
+ ```javascript
108
+ import { html } from './src/index.js';
109
+
110
+ // Simple
111
+ const greeting = html`<h1>Hello, World!</h1>`;
112
+
113
+ // With dynamic values
114
+ const count = 5;
115
+ const counter = html`<div>Count: ${count}</div>`;
116
+
117
+ // With arrays
118
+ const items = ['Apple', 'Banana', 'Orange'];
119
+ const list = html`
120
+ <ul>
121
+ ${items.map(item => html`<li>${item}</li>`)}
122
+ </ul>
123
+ `;
124
+ ```
125
+
126
+ **Conditional rendering:**
127
+
128
+ ```javascript
129
+ import { when } from './src/index.js';
130
+
131
+ when(
132
+ user.isLoggedIn,
133
+ () => html`<div>Welcome, ${user.name}!</div>`,
134
+ () => html`<div>Please log in</div>`
135
+ );
136
+ ```
137
+
138
+ **List rendering:**
139
+
140
+ ```javascript
141
+ import { each } from './src/index.js';
142
+
143
+ each(users, (user) => html`
144
+ <div class="user-card">
145
+ <h3>${user.name}</h3>
146
+ <p>${user.email}</p>
147
+ </div>
148
+ `);
149
+ ```
150
+
151
+ ### 3. Components
152
+
153
+ ```javascript
154
+ import { app, html } from './src/index.js';
155
+
156
+ app.create({
157
+ // Where to mount
158
+ root: document.getElementById('app'),
159
+
160
+ // Initial state
161
+ state: {
162
+ count: 0,
163
+ user: { name: 'John' }
164
+ },
165
+
166
+ // Render function
167
+ render: (state) => {
168
+ const element = html`<div>${state.count}</div>`;
169
+ const events = {
170
+ '#btn': { click: () => state.count++ }
171
+ };
172
+ return { element, events };
173
+ },
174
+
175
+ // Lifecycle hooks
176
+ onMount: (state) => {
177
+ console.log('Component mounted!');
178
+ },
179
+
180
+ onUpdate: (state) => {
181
+ console.log('State updated!');
182
+ },
183
+
184
+ onDestroy: (state) => {
185
+ console.log('Component destroyed!');
186
+ }
187
+ });
188
+ ```
189
+
190
+ ### 4. Event Handling
191
+
192
+ ```javascript
193
+ // Basic events
194
+ const events = {
195
+ '#button': {
196
+ click: () => console.log('Clicked!'),
197
+ mouseover: () => console.log('Hovered!')
198
+ },
199
+ '#input': {
200
+ input: (e) => state.value = e.target.value,
201
+ focus: () => console.log('Focused!')
202
+ }
203
+ };
204
+
205
+ // Form submission
206
+ '#form': {
207
+ submit: (e) => {
208
+ e.preventDefault();
209
+ const data = getFormData(e.target);
210
+ console.log(data);
211
+ }
212
+ }
213
+ ```
214
+
215
+ **Event helpers:**
216
+
217
+ ```javascript
218
+ import { on, debounce, throttle } from './src/index.js';
219
+
220
+ // Debounce search input
221
+ const handleSearch = debounce((e) => {
222
+ state.query = e.target.value;
223
+ }, 300);
224
+
225
+ // Throttle scroll events
226
+ const handleScroll = throttle(() => {
227
+ console.log('Scrolling...');
228
+ }, 100);
229
+ ```
230
+
231
+ ### 5. Routing
232
+
233
+ ```javascript
234
+ import { createRouter, Link } from './src/index.js';
235
+
236
+ const router = createRouter({
237
+ '/': () => html`<h1>Home Page</h1>`,
238
+ '/about': () => html`<h1>About Page</h1>`,
239
+ '/user/:id': (params) => html`<h1>User ${params.id}</h1>`,
240
+ '*': () => html`<h1>404 - Not Found</h1>`
241
+ }, {
242
+ beforeEach: (to, from, params) => {
243
+ console.log(`Navigating from ${from} to ${to}`);
244
+ },
245
+ afterEach: (to, from, params) => {
246
+ console.log(`Navigated to ${to}`);
247
+ }
248
+ });
249
+
250
+ // Navigate programmatically
251
+ router.navigate('/about');
252
+
253
+ // Create links
254
+ const link = Link('/about', 'About Us', 'nav-link');
255
+ ```
256
+
257
+ ---
258
+
259
+ ## 🔌 Plugins
260
+
261
+ ### Form Validation
262
+
263
+ ```javascript
264
+ import { createValidator, rules, displayErrors } from './src/plugins/validator.js';
265
+
266
+ const validator = createValidator({
267
+ email: [rules.required, rules.email],
268
+ password: [rules.required, rules.minLength(8)],
269
+ age: [rules.required, rules.number, rules.min(18)],
270
+ confirmPassword: [rules.required, rules.match('password', 'Password')]
271
+ });
272
+
273
+ const result = validator.validate(formData);
274
+
275
+ if (!result.isValid) {
276
+ displayErrors(formElement, result.errors);
277
+ } else {
278
+ // Submit form
279
+ }
280
+ ```
281
+
282
+ **Available rules:**
283
+ - `required` - Field must have a value
284
+ - `email` - Valid email format
285
+ - `minLength(n)` - Minimum length
286
+ - `maxLength(n)` - Maximum length
287
+ - `min(n)` - Minimum numeric value
288
+ - `max(n)` - Maximum numeric value
289
+ - `pattern(regex, msg)` - Custom regex
290
+ - `url` - Valid URL
291
+ - `number` - Numeric value
292
+ - `integer` - Integer value
293
+ - `match(field, name)` - Match another field
294
+ - `custom(fn, msg)` - Custom validation
295
+
296
+ ### HTTP Client
297
+
298
+ ```javascript
299
+ import { createHttp, http } from './src/plugins/http.js';
300
+
301
+ // Use default instance
302
+ const { data } = await http.get('/api/users');
303
+ await http.post('/api/users', { name: 'John' });
304
+ await http.put('/api/users/1', { name: 'Jane' });
305
+ await http.delete('/api/users/1');
306
+
307
+ // Custom instance
308
+ const api = createHttp({
309
+ baseURL: 'https://api.example.com',
310
+ headers: { 'Authorization': 'Bearer token' },
311
+ timeout: 10000,
312
+ onRequest: (config) => {
313
+ console.log('Request:', config);
314
+ },
315
+ onResponse: (response) => {
316
+ console.log('Response:', response);
317
+ },
318
+ onError: (error) => {
319
+ console.error('Error:', error);
320
+ }
321
+ });
322
+
323
+ const users = await api.get('/users');
324
+ ```
325
+
326
+ ### Storage
327
+
328
+ ```javascript
329
+ import { local, session, createNamespace } from './src/plugins/storage.js';
330
+
331
+ // LocalStorage (persists)
332
+ local.set('user', { name: 'John', age: 30 });
333
+ const user = local.get('user');
334
+ local.remove('user');
335
+ local.clear();
336
+
337
+ // SessionStorage (cleared on close)
338
+ session.set('token', 'abc123');
339
+ const token = session.get('token');
340
+
341
+ // Namespaced storage
342
+ const appStorage = createNamespace('myapp');
343
+ appStorage.local.set('settings', { theme: 'dark' });
344
+ ```
345
+
346
+ ---
347
+
348
+ ## 🛠️ Utilities
349
+
350
+ ```javascript
351
+ import { helpers } from './src/index.js';
352
+
353
+ // Generate unique ID
354
+ const id = helpers.uid('todo'); // 'todo_1234567890_abc'
355
+
356
+ // Deep clone
357
+ const copy = helpers.clone(originalObject);
358
+
359
+ // Deep merge
360
+ const merged = helpers.merge(obj1, obj2, obj3);
361
+
362
+ // Format date
363
+ const formatted = helpers.formatDate(new Date(), 'YYYY-MM-DD HH:mm');
364
+
365
+ // Sleep/delay
366
+ await helpers.sleep(1000); // Wait 1 second
367
+
368
+ // String utilities
369
+ helpers.capitalize('hello'); // 'Hello'
370
+ helpers.truncate('Long text...', 10); // 'Long text...'
371
+
372
+ // Array utilities
373
+ helpers.shuffle([1, 2, 3, 4, 5]);
374
+ helpers.unique([1, 2, 2, 3, 3]); // [1, 2, 3]
375
+ helpers.groupBy(users, 'role');
376
+
377
+ // Object utilities
378
+ helpers.get(obj, 'user.address.city', 'Unknown');
379
+ helpers.set(obj, 'user.name', 'John');
380
+ helpers.pick(obj, ['name', 'email']);
381
+ helpers.omit(obj, ['password', 'token']);
382
+
383
+ // Async utilities
384
+ await helpers.waitFor(() => element.isReady, 5000);
385
+ await helpers.retry(() => fetchData(), 3, 1000);
386
+ ```
387
+
388
+ ---
389
+
390
+ ## 📦 Project Structure
391
+
392
+ ```
393
+ humanjs-framework/
394
+ ├── index.html # Demo page
395
+ ├── README.md # This file
396
+
397
+ ├── src/ # Framework source
398
+ │ ├── core/ # Core modules
399
+ │ │ ├── state.js # Reactive state
400
+ │ │ ├── render.js # HTML rendering
401
+ │ │ ├── component.js # Components
402
+ │ │ ├── router.js # SPA routing
403
+ │ │ └── events.js # Event handling
404
+ │ │
405
+ │ ├── plugins/ # Optional plugins
406
+ │ │ ├── validator.js # Form validation
407
+ │ │ ├── http.js # HTTP client
408
+ │ │ └── storage.js # Storage wrapper
409
+ │ │
410
+ │ ├── utils/ # Utilities
411
+ │ │ └── helpers.js # Helper functions
412
+ │ │
413
+ │ └── index.js # Main entry point
414
+
415
+ └── examples/ # Example apps
416
+ ├── todo-app/
417
+ │ └── app.js
418
+ └── api-example/
419
+ └── app.js
420
+ ```
421
+
422
+ ---
423
+
424
+ ## 🎓 Examples
425
+
426
+ ### Todo App
427
+
428
+ A complete todo application with:
429
+ - Add, edit, delete todos
430
+ - Mark as complete
431
+ - Filter (all, active, completed)
432
+ - LocalStorage persistence
433
+ - Form validation
434
+
435
+ [View Source](./examples/todo-app/app.js)
436
+
437
+ ### API Integration
438
+
439
+ Demonstrates API usage with:
440
+ - Fetch users from API
441
+ - Loading states
442
+ - Error handling
443
+ - Search and filter
444
+ - Debounced input
445
+
446
+ [View Source](./examples/api-example/app.js)
447
+
448
+ ---
449
+
450
+ ## 🆚 Comparison with Other Frameworks
451
+
452
+ ### vs React
453
+
454
+ | Feature | HumanJS | React |
455
+ |---------|---------|-------|
456
+ | Learning curve | 1 day | 1-2 weeks |
457
+ | Setup | Open HTML file | Complex build setup |
458
+ | Bundle size | ~5KB | ~40KB (min) |
459
+ | Abstraction | Minimal | Heavy (JSX, virtual DOM) |
460
+ | Debugging | Trace in source | Complex stack traces |
461
+
462
+ ### vs Vue
463
+
464
+ | Feature | HumanJS | Vue |
465
+ |---------|---------|-----|
466
+ | Template syntax | Native HTML | Custom directives |
467
+ | Reactivity | Proxy (native) | Proxy + compiler |
468
+ | Components | Functions | Classes/objects |
469
+ | Build step | None | Required for SFC |
470
+
471
+ ### vs Svelte
472
+
473
+ | Feature | HumanJS | Svelte |
474
+ |---------|---------|--------|
475
+ | Compilation | None | Required |
476
+ | Runtime size | ~5KB | ~2KB |
477
+ | Learning curve | 1 day | 3-4 days |
478
+ | Debugging | Browser native | Compiled output |
479
+
480
+ ### When to use HumanJS
481
+
482
+ ✅ **Use when:**
483
+ - Building simple to medium apps
484
+ - Learning frontend concepts
485
+ - Prototyping quickly
486
+ - Want full control
487
+ - No build step desired
488
+
489
+ ❌ **Don't use when:**
490
+ - Building complex enterprise apps
491
+ - Need large ecosystem
492
+ - Team requires specific framework experience
493
+ - Need SSR or mobile apps
494
+
495
+ ---
496
+
497
+ ## 🔮 Future Improvements
498
+
499
+ ### Optional Enhancements
500
+
501
+ 1. **Virtual DOM** - For better performance
502
+ 2. **TypeScript** - Type definitions
503
+ 3. **SSR Support** - Server-side rendering
504
+ 4. **Dev Tools** - Browser extension
505
+ 5. **Plugin System** - Third-party plugins
506
+ 6. **CLI Tool** - Project scaffolding
507
+
508
+ ### How to Extend
509
+
510
+ The framework is designed to be modified:
511
+
512
+ 1. Fork the repository
513
+ 2. Modify `src/` files directly
514
+ 3. Add new plugins in `src/plugins/`
515
+ 4. Share your improvements!
516
+
517
+ ---
518
+
519
+ ## License
520
+
521
+ MIT License - do whatever you want with it!
522
+
523
+ ---
524
+
525
+ ## Contributing
526
+
527
+ Contributions welcome! Please:
528
+
529
+ 1. Keep it simple
530
+ 2. Maintain readability
531
+ 3. Add tests for new features
532
+ 4. Update documentation
533
+
534
+ ---
535
+
536
+ ## Support
537
+
538
+ - 📧 Email: abderrazzak.elouazghi@gmail.com
539
+ - 🐛 Issues: [GitHub Issues](https://github.com/kaiserofthenight/humanjs/issues)
540
+ - 💬 Discussions: [GitHub Discussions](https://github.com/kaiserofthenight/humanjs/discussions)
541
+ - ⭐ Star us on GitHub!
542
+
543
+ ---
544
+
545
+ **Remember: Frameworks are tools, not religions. Use what makes you productive!** 🚀