olova 2.0.1 → 2.0.3

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/dist/olova.js CHANGED
@@ -1,1139 +1,291 @@
1
- /**
2
- * @license
3
- * Olova Framework v2.0.0
4
- * (c) 2025 Olova
5
- * This source code is licensed under the MIT license
6
- *
7
- * Author: Nazmul Hossain
8
- * Made in Bangladesh
9
- */
10
-
11
- /** @jsx Olova.createElement */
12
-
13
- const Olova = {};
14
- let currentComponent = null,
15
- currentHook = 0;
16
- const states = new WeakMap(),
17
- effects = new WeakMap(),
18
- memos = new WeakMap(),
19
- refs = new WeakMap();
20
- let isBatchingUpdates = !1;
21
- const effectComponentIds = new Set(),
22
- customHookComponentIds = new Set();
23
- Olova.createHook = (e) => {
24
- if ("function" != typeof e)
25
- throw new Error("createHook: Hook implementation must be a function");
26
- return (...t) => {
27
- if (!currentComponent)
28
- throw new Error(
29
- "Custom hooks can only be called inside component render"
30
- );
31
- const o = currentHook++,
32
- r = currentComponent;
33
- customHooks.has(r) ||
34
- (customHooks.set(r, new Map()), customHookComponentIds.add(r));
35
- const n = customHooks.get(r);
36
- n.has(o) || n.set(o, { state: void 0, cleanup: void 0 });
37
- const a = {
38
- useState: Olova.State,
39
- useEffect: Olova.Effect,
40
- useMemo: Olova.Memo,
41
- useRef: Olova.Ref,
42
- getHookState: () => n.get(o).state,
43
- setHookState: (e) => {
44
- n.get(o).state = e;
45
- },
46
- setCleanup: (e) => {
47
- "function" == typeof e && (n.get(o).cleanup = e);
48
- },
49
- };
50
- return e(a, ...t);
51
- };
52
- };
53
- const customHooks = new WeakMap();
54
- Olova.State = (e) => {
55
- const t = currentComponent,
56
- o = currentHook++;
57
- states.has(t) || states.set(t, []);
58
- const r = states.get(t);
59
- void 0 === r[o] && (r[o] = e);
60
- return [
61
- r[o],
62
- (e) => {
63
- const t = "function" == typeof e ? e(r[o]) : e;
64
- queueUpdate(() => {
65
- (r[o] = t), rerender();
66
- });
67
- },
68
- ];
69
- };
70
- const flattenChildren = (e) =>
71
- e.reduce(
72
- (e, t) =>
73
- null == t || "boolean" == typeof t
74
- ? e
75
- : Array.isArray(t)
76
- ? e.concat(flattenChildren(t))
77
- : e.concat("object" == typeof t ? t : createTextElement(t)),
78
- []
79
- );
80
- Olova.createElement = (e, t, ...o) =>
81
- e === Olova.Fragment
82
- ? { type: "FRAGMENT", props: { children: flattenChildren(o) } }
83
- : { type: e, props: { ...t, children: flattenChildren(o) } };
84
- const createTextElement = (e) => ({
85
- type: "TEXT_ELEMENT",
86
- props: { nodeValue: e, children: [] },
87
- }),
88
- createDom = (e) => {
89
- const t =
90
- "TEXT_ELEMENT" === e.type
91
- ? document.createTextNode("")
92
- : document.createElement(e.type),
93
- o = sanitizeProps(e.props);
94
- return updateDom(t, {}, o), t;
95
- },
96
- updateDom = (e, t, o) => {
97
- t.style &&
98
- Object.keys(t.style).forEach((r) => {
99
- (o.style && t.style[r] === o.style[r]) || (e.style[r] = "");
100
- });
101
- const r = new Map();
102
- Object.keys(t || {}).forEach((e) => {
103
- "children" === e || e in o || r.set(e, null);
104
- }),
105
- Object.keys(o || {}).forEach((e) => {
106
- "children" !== e && t[e] !== o[e] && r.set(e, o[e]);
107
- }),
108
- r.forEach((o, r) => {
109
- if (r.startsWith("on")) {
110
- const n = r.slice(2).toLowerCase();
111
- t[r] && e.removeEventListener(n, t[r]), o && e.addEventListener(n, o);
112
- } else
113
- "style" === r && "object" == typeof o
114
- ? Object.assign(e.style, o)
115
- : "className" === r
116
- ? e.setAttribute("class", o || "")
117
- : "boolean" == typeof o
118
- ? o
119
- ? e.setAttribute(r, "")
120
- : e.removeAttribute(r)
121
- : (e[r] = o ?? "");
122
- });
123
- };
124
- let rootElement = null,
125
- currentRoot = null;
126
- Olova.render = (e, t) => {
127
- (rootElement = t),
128
- (currentRoot = { dom: t, props: { children: [e] } }),
129
- rerender();
130
- };
131
- const rerender = () => {
132
- if (rootElement && currentRoot) {
133
- for (
134
- effectComponentIds.forEach((e) => {
135
- const t = effects.get(e);
136
- t &&
137
- t.forEach((e) => {
138
- e && e.cleanup && e.cleanup();
139
- });
140
- }),
141
- customHookComponentIds.forEach((e) => {
142
- const t = customHooks.get(e);
143
- t &&
144
- t.forEach((e) => {
145
- e.cleanup && e.cleanup();
146
- });
147
- });
148
- rootElement.firstChild;
149
-
150
- )
151
- rootElement.removeChild(rootElement.firstChild);
152
- renderElement(currentRoot.props.children[0], rootElement);
153
- }
154
- },
155
- cleanupEffects = () => {
156
- effects.forEach((e, t) => {
157
- e.forEach((e) => {
158
- e && e.cleanup && e.cleanup();
159
- });
160
- });
161
- },
162
- cleanupCustomHooks = () => {
163
- customHooks.forEach((e, t) => {
164
- e.forEach((e) => {
165
- e.cleanup && e.cleanup();
166
- });
167
- });
168
- },
169
- contexts = new Map();
170
- let contextIndex = 0;
171
- (Olova.createContext = (e) => {
172
- const t = contextIndex++;
173
- return (
174
- contexts.set(t, { defaultValue: e, value: e }),
175
- {
176
- Provider: ({ value: e, children: o }) => (
177
- (contexts.get(t).value = e), o[0]
178
- ),
179
- Consumer: ({ children: e }) => e[0](contexts.get(t).value),
180
- _contextId: t,
181
- }
182
- );
183
- }),
184
- (Olova.Context = (e) => {
185
- if (!e || "number" != typeof e._contextId)
186
- throw new Error(
187
- "Context: Invalid context object. Make sure you're passing a context created by createContext()"
188
- );
189
- return currentHook++, contexts.get(e._contextId).value;
190
- });
191
- const renderElement = (e, t) => {
192
- if (!t || !(t instanceof Element || t instanceof DocumentFragment))
193
- throw new Error("Invalid container element provided to render");
194
- if (!e && 0 !== e && "" !== e) return;
195
- if ("FRAGMENT" === e.type) {
196
- const o = document.createDocumentFragment();
197
- return (
198
- e.props.children.forEach((e) => renderElement(e, o)),
199
- void t.appendChild(o)
200
- );
201
- }
202
- if ("object" == typeof e.type && e.type.Consumer) {
203
- const o = contexts.get(e.type._contextId).value,
204
- r = e.props.children[0](o);
205
- return void renderElement(r, t);
206
- }
207
- if ("object" == typeof e.type && e.type.Provider) {
208
- const o = e.props.children[0];
209
- return void renderElement(o, t);
210
- }
211
- if ("function" == typeof e.type) {
212
- (currentComponent = e.type), (currentHook = 0);
213
- const o = e.type(e.props);
214
- return void renderElement(o, t);
215
- }
216
- const o = createDom(e);
217
- e.props.children.forEach((e) => renderElement(e, o)), t.appendChild(o);
218
- };
219
- (Olova.Effect = (e, t) => {
220
- if ("function" != typeof e)
221
- throw new Error("Effect: First argument must be a function");
222
- if (void 0 !== t && !Array.isArray(t))
223
- throw new Error("Effect: Second argument must be an array or undefined");
224
- const o = currentComponent,
225
- r = currentHook++;
226
- effects.has(o) || (effects.set(o, []), effectComponentIds.add(o));
227
- const n = effects.get(o),
228
- a = n[r];
229
- if (!a || !t || t.some((e, t) => !Object.is(e, a.deps[t]))) {
230
- a && a.cleanup && a.cleanup();
231
- const o = e();
232
- n[r] = { deps: t, cleanup: "function" == typeof o ? o : void 0 };
233
- }
234
- }),
235
- (Olova.Reducer = (e, t, o) => {
236
- const r = currentComponent,
237
- n = currentHook++;
238
- states.has(r) || states.set(r, []);
239
- const a = states.get(r);
240
- void 0 === a[n] && (a[n] = o ? o(t) : t);
241
- return [
242
- a[n],
243
- (t) => {
244
- (a[n] = e(a[n], t)), rerender();
245
- },
246
- ];
247
- }),
248
- (Olova.Callback = (e, t) => Olova.Memo(() => e, t)),
249
- (Olova.Memo = (e, t) => {
250
- const o = currentComponent,
251
- r = currentHook++;
252
- memos.has(o) || memos.set(o, []);
253
- const n = memos.get(o),
254
- a = n[r];
255
- if (
256
- !a ||
257
- !t ||
258
- t.length !== a.deps.length ||
259
- t.some(
260
- (e, t) =>
261
- !Object.is(e, a.deps[t]) &&
262
- ("object" != typeof e ||
263
- null === e ||
264
- JSON.stringify(e) !== JSON.stringify(a.deps[t]))
265
- )
266
- ) {
267
- const o = e();
268
- return (n[r] = { value: o, deps: t }), o;
269
- }
270
- return a.value;
271
- }),
272
- (Olova.Ref = (e) => {
273
- const t = currentComponent,
274
- o = currentHook++;
275
- refs.has(t) || refs.set(t, []);
276
- const r = refs.get(t);
277
- return void 0 === r[o] && (r[o] = { current: e }), r[o];
278
- }),
279
- (Olova.LayoutEffect = (e, t) => {
280
- Olova.Effect(e, t);
281
- }),
282
- (Olova.ImperativeHandle = (e, t, o) => {
283
- Olova.LayoutEffect(() => {
284
- e && (e.current = t());
285
- }, o);
286
- }),
287
- (Olova.Fragment = Symbol("Fragment"));
288
- let nextUnitOfWork = null,
289
- wipRoot = null;
290
- function createFiber(e, t, o = null) {
291
- return {
292
- type: e,
293
- props: t,
294
- key: o,
295
- dom: null,
296
- parent: null,
297
- child: null,
298
- sibling: null,
299
- alternate: null,
300
- effectTag: null,
301
- lastProps: null,
302
- shouldUpdate: !0,
303
- dependencies: new Set(),
304
- memoizedState: null,
305
- };
306
- }
307
- const schedulerPriorities = {
308
- ImmediatePriority: 1,
309
- UserBlockingPriority: 2,
310
- NormalPriority: 3,
311
- LowPriority: 4,
312
- IdlePriority: 5,
313
- },
314
- objectPool = {
315
- fibers: [],
316
- effects: [],
317
- acquireFiber() {
318
- return this.fibers.pop() || createFiber();
319
- },
320
- releaseFiber(e) {
321
- Object.keys(e).forEach((t) => {
322
- e[t] = null;
323
- }),
324
- this.fibers.push(e);
325
- },
326
- },
327
- workLoop = (e) => {
328
- let t = !1;
329
- for (; nextUnitOfWork && !t; ) {
330
- const o = nextUnitOfWork;
331
- if (
332
- (o.priorityLevel || schedulerPriorities.NormalPriority) >
333
- schedulerPriorities.ImmediatePriority &&
334
- e.timeRemaining() < 500
335
- ) {
336
- t = !0;
337
- break;
338
- }
339
- nextUnitOfWork = performUnitOfWork(o);
340
- }
341
- !nextUnitOfWork && wipRoot && commitRoot(), requestIdleCallback(workLoop);
342
- };
343
- function performUnitOfWork(e) {
344
- if (
345
- ("function" == typeof e.type
346
- ? updateFunctionComponent(e)
347
- : updateHostComponent(e),
348
- e.child)
349
- )
350
- return e.child;
351
- let t = e;
352
- for (; t; ) {
353
- if (t.sibling) return t.sibling;
354
- t = t.parent;
355
- }
356
- }
357
- function updateFunctionComponent(e) {
358
- (currentComponent = e), (currentHook = 0), (e.hooks = []);
359
- try {
360
- const t = [e.type(e.props)];
361
- reconcileChildren(e, t);
362
- } catch (t) {
363
- handleWorkInProgressError(e, t);
364
- }
365
- }
366
- function updateHostComponent(e) {
367
- e.dom || (e.dom = createDom(e)), reconcileChildren(e, e.props.children);
368
- }
369
- function reconcileChildren(e, t, o) {
370
- let r = null,
371
- n = null;
372
- const a = new Map();
373
- let s = t;
374
- for (; s; ) {
375
- const e = s.key || s.index;
376
- a.set(e, s), (s = s.sibling);
377
- }
378
- for (let t = 0; t < o.length; t++) {
379
- const s = o[t],
380
- c = s.key || t,
381
- l = a.get(c);
382
- l && l.type === s.type
383
- ? (n = {
384
- ...l,
385
- props: s.props,
386
- alternate: l,
387
- effectTag: "UPDATE",
388
- shouldUpdate: !shallowEqual(l.props, s.props),
389
- })
390
- : ((n = createFiber(s.type, s.props, c)),
391
- (n.effectTag = "PLACEMENT"),
392
- (n.shouldUpdate = !0),
393
- l && ((l.effectTag = "DELETION"), deletions.push(l))),
394
- null === r ? (e.child = n) : (r.sibling = n),
395
- (r = n),
396
- a.delete(c);
397
- }
398
- a.forEach((e) => {
399
- (e.effectTag = "DELETION"), deletions.push(e);
400
- });
401
- }
402
- function shallowEqual(e, t) {
403
- if (Object.is(e, t)) return !0;
404
- if (!e || !t) return !1;
405
- const o = Object.keys(e),
406
- r = Object.keys(t);
407
- if (o.length !== r.length) return !1;
408
- for (let r = 0; r < o.length; r++) {
409
- const n = o[r];
410
- if ("children" !== n && !Object.is(e[n], t[n])) return !1;
411
- }
412
- return !0;
413
- }
414
- function handleWorkInProgressError(e, t) {
415
- let o = null,
416
- r = e;
417
- for (; r; ) {
418
- if (r.type?.prototype instanceof Olova.ErrorBoundary) {
419
- o = r;
420
- break;
421
- }
422
- r = r.parent;
423
- }
424
- if (!o) throw t;
425
- {
426
- const r = {
427
- componentStack: getComponentStack(e),
428
- error: t,
429
- errorBoundary: o,
430
- };
431
- (o.updateQueue = o.updateQueue || []),
432
- o.updateQueue.push({ action: "ERROR", error: r }),
433
- scheduleWork(o, schedulerPriorities.ImmediatePriority);
434
- }
435
- }
436
- function commitRoot() {
437
- deletions.forEach(commitWork),
438
- commitWork(wipRoot.child),
439
- (currentRoot = wipRoot),
440
- (wipRoot = null);
441
- }
442
- const commitWork = (e) => {
443
- if (e) {
444
- if (e.shouldUpdate)
445
- switch (e.effectTag) {
446
- case "PLACEMENT":
447
- if (e.dom) {
448
- const t = getParentFiber(e);
449
- t && t.dom.appendChild(e.dom);
450
- }
451
- break;
452
- case "UPDATE":
453
- e.dom && updateDom(e.dom, e.alternate.props, e.props);
454
- break;
455
- case "DELETION":
456
- commitDeletion(e);
457
- }
458
- commitWork(e.child), commitWork(e.sibling);
459
- }
460
- };
461
- function getParentFiber(e) {
462
- let t = e.parent;
463
- for (; t && !t.dom; ) t = t.parent;
464
- return t;
465
- }
466
- (Olova.createStore = (e, t) => {
467
- if ("function" != typeof e)
468
- throw new Error("createStore: Reducer must be a function");
469
- let o = t,
470
- r = new Set();
471
- const n = (t) => {
472
- (o = e(o, t)), r.forEach((e) => e());
473
- };
474
- return (
475
- n({ type: "@@INIT" }),
476
- {
477
- getState: () => o,
478
- dispatch: n,
479
- subscribe: (e) => (r.add(e), () => r.delete(e)),
480
- }
481
- );
482
- }),
483
- (Olova.Provider = ({ store: e, children: t }) => {
484
- if (
485
- !e ||
486
- "function" != typeof e.getState ||
487
- "function" != typeof e.dispatch
488
- )
489
- throw new Error(
490
- "Provider: Invalid store object. Make sure you're passing a store created by createStore()"
491
- );
492
- if (!t) throw new Error("Provider: Must include children elements");
493
- const o = Olova.createContext(null),
494
- r = () => o.Provider({ value: e, children: [t] });
495
- return (r.Context = o), r();
496
- }),
497
- (Olova.Selector = (e) => {
498
- if ("function" != typeof e)
499
- throw new Error("Selector: Selector must be a function");
500
- const t = Olova.Context(Olova.Provider.Context);
501
- if (!t) throw new Error("Selector must be used within a Provider");
502
- const [, o] = Olova.State({});
503
- Olova.Effect(
504
- () =>
505
- t.subscribe(() => {
506
- const n = e(t.getState());
507
- r !== n && o({});
508
- }),
509
- [t, e]
510
- );
511
- const r = e(t.getState());
512
- return r;
513
- }),
514
- (Olova.Dispatch = () => {
515
- const e = Olova.Context(Olova.Provider.Context);
516
- if (!e) throw new Error("Dispatch must be used within a Provider");
517
- return e.dispatch;
518
- }),
519
- (Olova.combineReducers =
520
- (e) =>
521
- (t = {}, o) => {
522
- const r = {};
523
- let n = !1;
524
- return (
525
- Object.entries(e).forEach(([e, a]) => {
526
- const s = t[e],
527
- c = a(s, o);
528
- (r[e] = c), (n = n || c !== s);
529
- }),
530
- n ? r : t
531
- );
532
- }),
533
- (Olova.createAction = (e) => {
534
- const t = (t) => ({ type: e, payload: t });
535
- return (t.toString = () => e), t;
536
- }),
537
- (Olova.applyMiddleware =
538
- (...e) =>
539
- (t) =>
540
- (o, r) => {
541
- const n = t(o, r);
542
- let a = n.dispatch;
543
- const s = { getState: n.getState, dispatch: (e) => a(e) },
544
- c = e.map((e) => e(s));
545
- return (a = c.reduce((e, t) => t(e))(n.dispatch)), { ...n, dispatch: a };
546
- }),
547
- (Olova.Suspense = ({ fallback: e, children: t }) => {
548
- const [o, r] = Olova.State(!1),
549
- [n, a] = Olova.State(null);
550
- try {
551
- return Olova.createElement(
552
- SuspenseProvider,
553
- { value: { isPending: o, setPending: r, setError: a } },
554
- t
555
- );
556
- } catch (t) {
557
- if (t instanceof Promise) return t.then(() => r(!1)), r(!0), e;
558
- throw t;
559
- }
560
- }),
561
- (Olova.ErrorBoundary = class {
562
- constructor(e) {
563
- (this.state = { hasError: !1, error: null }),
564
- (this.fallback = e.fallback);
565
- }
566
- static getDerivedStateFromError(e) {
567
- return { hasError: !0, error: e };
568
- }
569
- componentDidCatch(e, t) {
570
- console.error("Error caught by ErrorBoundary:", e, t),
571
- this.props.onError && this.props.onError(e, t);
572
- }
573
- render() {
574
- return this.state.hasError
575
- ? "function" == typeof this.fallback
576
- ? this.fallback(this.state.error)
577
- : this.fallback
578
- : this.props.children;
579
- }
580
- });
581
- const createVirtualDom = (e) => ({
582
- type: e.type,
583
- key: e.key || null,
584
- ref: e.ref || null,
585
- props: {
586
- ...e.props,
587
- children: Array.isArray(e.props.children)
588
- ? e.props.children.map((e) =>
589
- "object" == typeof e ? createVirtualDom(e) : e
590
- )
591
- : e.props.children,
592
- },
593
- _owner: currentComponent,
594
- _store: { validated: !1 },
595
- _self: null,
596
- _source:
597
- "production" !== process.env.NODE_ENV
598
- ? {
599
- fileName: e._source?.fileName || "unknown",
600
- lineNumber: e._source?.lineNumber || 0,
601
- }
602
- : null,
603
- }),
604
- reconcileChildrenArray = (e, t, o) => {
605
- let r = t,
606
- n = null,
607
- a = null,
608
- s = 0,
609
- c = null;
610
- const l = new Map();
611
- let i = t;
612
- for (; i; ) {
613
- const e = i.key || s;
614
- l.set(e, i), (i = i.sibling);
615
- }
616
- for (; r && s < o.length; s++) {
617
- c = r.sibling;
618
- const t = o[s],
619
- l = t.key || s;
620
- if (l !== (r.key || s)) {
621
- r = c;
622
- break;
623
- }
624
- (a = {
625
- type: t.type,
626
- key: l,
627
- props: t.props,
628
- dom: r.dom,
629
- parent: e,
630
- alternate: r,
631
- effectTag: "UPDATE",
632
- lanes: 0,
633
- childLanes: 0,
634
- }),
635
- null === n ? (e.child = a) : (n.sibling = a),
636
- (n = a),
637
- (r = c);
638
- }
639
- for (; s < o.length; ) {
640
- const t = o[s];
641
- (a = {
642
- type: t.type,
643
- key: t.key || s,
644
- props: t.props,
645
- dom: null,
646
- parent: e,
647
- alternate: null,
648
- effectTag: "PLACEMENT",
649
- lanes: 0,
650
- childLanes: 0,
651
- }),
652
- null === n ? (e.child = a) : (n.sibling = a),
653
- (n = a),
654
- s++;
655
- }
656
- for (; r; ) (r.effectTag = "DELETION"), deletions.push(r), (r = r.sibling);
657
- return e.child;
658
- },
659
- memoizedDiff = (() => {
660
- const e = new WeakMap();
661
- return (t, o) => {
662
- const r = `${t?.type}-${o?.type}`;
663
- e.has(t) || e.set(t, new Map());
664
- const n = e.get(t);
665
- if (n.has(r)) return n.get(r);
666
- const a = [];
667
- if (t?.type !== o?.type)
668
- return a.push({ type: "REPLACE", newNode: o }), n.set(r, a), a;
669
- if ("object" != typeof o)
670
- return t !== o && a.push({ type: "TEXT", content: o }), n.set(r, a), a;
671
- const s = diffProps(t.props, o.props);
672
- return (
673
- s && a.push({ type: "PROPS", patches: s }),
674
- o.props.skipChildrenDiff ||
675
- diffChildren(t.props.children, o.props.children, a),
676
- n.set(r, a),
677
- a
678
- );
679
- };
680
- })(),
681
- diffProps = (e, t) => {
682
- const o = {};
683
- let r = !1;
684
- for (const n in e) "children" === n || n in t || ((r = !0), (o[n] = null));
685
- for (const n in t)
686
- "children" !== n && e[n] !== t[n] && ((r = !0), (o[n] = t[n]));
687
- return r ? o : null;
688
- },
689
- diffChildren = (e, t, o) => {
690
- const r = Array.isArray(e) ? e : [e],
691
- n = Array.isArray(t) ? t : [t],
692
- a = new Map();
693
- r.forEach((e, t) => {
694
- const o = e?.key || `index:${t}`;
695
- a.set(o, { child: e, index: t });
696
- });
697
- const s = [];
698
- let c = 0;
699
- n.forEach((e, t) => {
700
- const o = e?.key || `index:${t}`,
701
- r = a.get(o);
702
- if (r) {
703
- const t = r.child,
704
- n = r.index;
705
- n !== c && s.push({ type: "REORDER", from: n, to: c });
706
- const l = memoizedDiff(t, e);
707
- l.length > 0 && s.push({ type: "UPDATE", index: c, patches: l }),
708
- a.delete(o);
709
- } else s.push({ type: "INSERT", index: c, node: e });
710
- c++;
711
- }),
712
- a.forEach(({ index: e }) => {
713
- s.push({ type: "REMOVE", index: e });
714
- }),
715
- s.length > 0 && o.push({ type: "CHILDREN", patches: s });
716
- },
717
- applyPatches = (e, t) => {
718
- t.forEach((t) => {
719
- switch (t.type) {
720
- case "REPLACE":
721
- const o = createDom(t.newNode);
722
- e.parentNode.replaceChild(o, e);
723
- break;
724
- case "TEXT":
725
- e.textContent = t.content;
726
- break;
727
- case "PROPS":
728
- updateDomProperties(e, t.patches);
729
- break;
730
- case "CHILDREN":
731
- applyChildrenPatches(e, t.patches);
732
- }
733
- });
734
- },
735
- updateDomProperties = (e, t) => {
736
- Object.entries(t).forEach(([t, o]) => {
737
- if (t.startsWith("on")) {
738
- const r = t.toLowerCase().substring(2);
739
- e._listeners &&
740
- e._listeners[r] &&
741
- e.removeEventListener(r, e._listeners[r]),
742
- o &&
743
- (e._listeners || (e._listeners = {}),
744
- (e._listeners[r] = o),
745
- e.addEventListener(r, o));
746
- } else
747
- "style" === t && "object" == typeof o
748
- ? Object.assign(e.style, o)
749
- : "className" === t
750
- ? e.setAttribute("class", o)
751
- : "boolean" == typeof o
752
- ? o
753
- ? e.setAttribute(t, "")
754
- : e.removeAttribute(t)
755
- : null === o
756
- ? e.removeAttribute(t)
757
- : e.setAttribute(t, o);
758
- });
759
- },
760
- applyChildrenPatches = (e, t) => {
761
- const o = Array.from(e.childNodes),
762
- r = [];
763
- t.forEach((e) => {
764
- switch (e.type) {
765
- case "REORDER":
766
- r.push({ type: "MOVE", from: e.from, to: e.to, node: o[e.from] });
767
- break;
768
- case "REMOVE":
769
- r.push({ type: "REMOVE", index: e.index, node: o[e.index] });
770
- break;
771
- case "INSERT":
772
- r.push({ type: "INSERT", index: e.index, node: createDom(e.node) });
773
- break;
774
- case "UPDATE":
775
- applyPatches(o[e.index], e.patches);
776
- }
777
- }),
778
- r
779
- .sort((e, t) =>
780
- "REMOVE" === e.type ? -1 : "REMOVE" === t.type ? 1 : e.index - t.index
781
- )
782
- .forEach((t) => {
783
- switch (t.type) {
784
- case "MOVE":
785
- e.insertBefore(t.node, e.childNodes[t.to] || null);
786
- break;
787
- case "REMOVE":
788
- e.removeChild(t.node);
789
- break;
790
- case "INSERT":
791
- e.insertBefore(t.node, e.childNodes[t.index] || null);
792
- }
793
- });
794
- },
795
- priorityLevels = {
796
- IMMEDIATE: 1,
797
- USER_BLOCKING: 2,
798
- NORMAL: 3,
799
- LOW: 4,
800
- IDLE: 5,
801
- },
802
- scheduleWork = (e, t) => {
803
- new Map().set(t, e);
804
- };
805
- let batchQueue = new Set(),
806
- isProcessingBatch = !1;
807
- const batchedUpdates = (e) => {
808
- const t = isBatchingUpdates;
809
- isBatchingUpdates = !0;
810
- try {
811
- return e();
812
- } finally {
813
- (isBatchingUpdates = t), isBatchingUpdates || flushBatchQueue();
814
- }
815
- },
816
- flushBatchQueue = () => {
817
- if (!isProcessingBatch) {
818
- isProcessingBatch = !0;
819
- try {
820
- batchQueue.forEach((e) => {
821
- e();
822
- });
823
- } finally {
824
- (isProcessingBatch = !1), batchQueue.clear();
825
- }
826
- performSyncWork();
827
- }
828
- },
829
- queueUpdate = (e) => {
830
- batchQueue.add(e), isBatchingUpdates || flushBatchQueue();
831
- },
832
- performSyncWork = () => {
833
- rerender();
834
- };
835
- (Olova.Transition = () => {
836
- const [e, t] = Olova.State(!1);
837
- return [
838
- e,
839
- Olova.Callback((e) => {
840
- t(!0),
841
- queueMicrotask(() => {
842
- try {
843
- e();
844
- } finally {
845
- t(!1);
846
- }
847
- });
848
- }, []),
849
- ];
850
- }),
851
- (Olova.DeferredValue = (e, t) => {
852
- const [o, r] = Olova.State(e);
853
- return (
854
- Olova.Effect(() => {
855
- const o = setTimeout(() => {
856
- r(e);
857
- }, t?.timeoutMs || 2e3);
858
- return () => clearTimeout(o);
859
- }, [e, t?.timeoutMs]),
860
- o
861
- );
862
- }),
863
- (Olova.renderToString = (e) => {
864
- let t = "";
865
- var o;
866
- return "string" != typeof (o = e) || (t += o), t;
867
- });
868
- const SyntheticEvent = {
869
- preventDefault() {},
870
- stopPropagation() {},
871
- persist() {},
872
- isPersistent() {},
873
- nativeEvent: null,
874
- target: null,
875
- currentTarget: null,
876
- type: null,
877
- };
878
- Olova.lazy = (e) => {
879
- let t = null,
880
- o = null;
881
- return (r) => {
882
- if (
883
- (t ||
884
- o ||
885
- (o = e()
886
- .then((e) => {
887
- t = e.default || e;
888
- })
889
- .catch((e) => {
890
- throw e;
891
- })),
892
- t)
893
- )
894
- return Olova.createElement(t, r);
895
- throw o;
896
- };
897
- };
898
- export const {
899
- State: State,
900
- createContext: createContext,
901
- Context: Context,
902
- Effect: Effect,
903
- Reducer: Reducer,
904
- Callback: Callback,
905
- Memo: Memo,
906
- Ref: Ref,
907
- LayoutEffect: LayoutEffect,
908
- ImperativeHandle: ImperativeHandle,
909
- Fragment: Fragment,
910
- createStore: createStore,
911
- Provider: Provider,
912
- Selector: Selector,
913
- Dispatch: Dispatch,
914
- combineReducers: combineReducers,
915
- createAction: createAction,
916
- applyMiddleware: applyMiddleware,
917
- Suspense: Suspense,
918
- ErrorBoundary: ErrorBoundary,
919
- Transition: Transition,
920
- DeferredValue: DeferredValue,
921
- renderToString: renderToString,
922
- lazy: lazy,
923
- StrictMode: StrictMode,
924
- Profiler: Profiler,
925
- DebugValue: DebugValue,
926
- Id: Id,
927
- InsertionEffect: InsertionEffect,
928
- Optimistic: Optimistic,
929
- SyncExternalStore: SyncExternalStore,
930
- ActionState: ActionState,
931
- } = Olova;
932
- export default Olova;
933
- (Olova.StrictMode = ({ children: e }) => {
934
- const t = (e) => {
935
- if ("function" == typeof e.type) {
936
- Object.getOwnPropertyNames(e.type.prototype).forEach((t) => {
937
- t.startsWith("UNSAFE_") &&
938
- console.warn(
939
- `StrictMode: Detected deprecated method ${t} in component ${e.type.name}`
940
- );
941
- }),
942
- e.props && e.props.children && e.props.children.forEach(t);
943
- }
944
- };
945
- return e.forEach(t), e[0];
946
- }),
947
- (Olova.Profiler = ({ id: e, onRender: t, children: o }) => {
948
- if ("function" != typeof t)
949
- return console.warn("Profiler requires an onRender callback"), o;
950
- const r = performance.now();
951
- return (
952
- Olova.Effect(() => {
953
- const o = performance.now(),
954
- n = o - r;
955
- t({
956
- id: e,
957
- actualDuration: n,
958
- baseDuration: n,
959
- startTime: r,
960
- commitTime: o,
961
- interactions: new Set(),
962
- phase: "mount",
963
- });
964
- }, []),
965
- o
966
- );
967
- }),
968
- "production" !== process.env.NODE_ENV &&
969
- (Olova.__DEV__ = {
970
- componentStack: [],
971
- markComponentRender: (e) => {
972
- Olova.__DEV__.componentStack.push(e),
973
- console.log(`Component rendered: ${e.name || "Anonymous"}`);
974
- },
975
- clearComponentStack: () => {
976
- Olova.__DEV__.componentStack = [];
977
- },
978
- });
979
- const handleError = (e, t) => {
980
- console.error("Error in Olova application:", e),
981
- console.error("Component stack:", t);
982
- let o = null,
983
- r = t[t.length - 1];
984
- for (; r && !o; )
985
- r.type && r.type.prototype instanceof Olova.ErrorBoundary && (o = r),
986
- (r = r.parent);
987
- if (!o) throw e;
988
- o.setState({ hasError: !0, error: e });
989
- },
990
- cleanupComponent = (e) => {
991
- effects.has(e) &&
992
- (effects.get(e).forEach((e) => {
993
- e.cleanup && e.cleanup();
994
- }),
995
- effects.delete(e)),
996
- states.has(e) && states.delete(e),
997
- memos.has(e) && memos.delete(e),
998
- refs.has(e) && refs.delete(e);
999
- },
1000
- sanitizeProps = (e) => {
1001
- if (e.dangerouslySetInnerHTML) {
1002
- const t = e.dangerouslySetInnerHTML.__html.replace(
1003
- /<script[^>]*>([\S\s]*?)<\/script>/gi,
1004
- ""
1005
- );
1006
- e.dangerouslySetInnerHTML.__html = t;
1007
- }
1008
- return e;
1009
- };
1010
- (Olova.DebugValue = (e, t) => {
1011
- if ("production" !== process.env.NODE_ENV) {
1012
- const o = t ? t(e) : e;
1013
- console.log("Debug value:", o);
1014
- }
1015
- }),
1016
- (Olova.Id = () => {
1017
- const [e] = Olova.State(
1018
- () => `olova-${Math.random().toString(36).slice(2)}`
1019
- );
1020
- return e;
1021
- }),
1022
- (Olova.InsertionEffect = (e, t) => {
1023
- Olova.LayoutEffect(e, t);
1024
- }),
1025
- (Olova.SyncExternalStore = (e, t, o) => {
1026
- const [r, n] = Olova.State(t);
1027
- return (
1028
- Olova.Effect(
1029
- () => (
1030
- n(t()),
1031
- e(() => {
1032
- n(t());
1033
- })
1034
- ),
1035
- [e, t]
1036
- ),
1037
- r
1038
- );
1039
- }),
1040
- (Olova.Optimistic = (e, t) => {
1041
- const [o, r] = Olova.State(e),
1042
- [n, a] = Olova.Transition();
1043
- return [
1044
- o,
1045
- (e) => {
1046
- a(() => {
1047
- const n = t(o, e);
1048
- r(n);
1049
- });
1050
- },
1051
- ];
1052
- }),
1053
- (Olova.ActionState = (e, t) => {
1054
- const [o, r] = Olova.State(e),
1055
- [n, a] = Olova.State(null),
1056
- [s, c] = Olova.State(null);
1057
- return [
1058
- o,
1059
- async (e) => {
1060
- try {
1061
- a(o);
1062
- const n = await t(o, e);
1063
- r(n), a(null), c(null);
1064
- } catch (e) {
1065
- c(e), a(null);
1066
- }
1067
- },
1068
- { pending: n, error: s },
1069
- ];
1070
- });
1071
- const diffCache = new WeakMap(),
1072
- memoizedCreateVirtualDom = (e) => {
1073
- if (diffCache.has(e)) return diffCache.get(e);
1074
- const t = createVirtualDom(e);
1075
- return diffCache.set(e, t), t;
1076
- };
1077
- class UpdateQueue {
1078
- constructor() {
1079
- this.updates = new Map();
1080
- }
1081
- enqueue(e, t) {
1082
- this.updates.has(e) || this.updates.set(e, new Set()),
1083
- this.updates.get(e).add(t);
1084
- }
1085
- dequeue() {
1086
- const e = Array.from(this.updates.keys()).sort();
1087
- for (const t of e) {
1088
- const e = this.updates.get(t);
1089
- if (e.size > 0) {
1090
- const o = e.values().next().value;
1091
- return e.delete(o), 0 === e.size && this.updates.delete(t), o;
1092
- }
1093
- }
1094
- return null;
1095
- }
1096
- }
1097
- const updateQueue = new UpdateQueue(),
1098
- componentCache = new WeakMap(),
1099
- getCachedComponent = (e, t) => {
1100
- const o = JSON.stringify(t);
1101
- componentCache.has(e) || componentCache.set(e, new Map());
1102
- const r = componentCache.get(e);
1103
- return r.has(o) || r.set(o, new e(t)), r.get(o);
1104
- },
1105
- batchDomOperations = (e) => {
1106
- const t = document.createDocumentFragment();
1107
- return (
1108
- e.forEach((e) => {
1109
- if ("INSERT" === e.type) t.appendChild(e.node);
1110
- }),
1111
- t
1112
- );
1113
- },
1114
- eventDelegator = {
1115
- handlers: new Map(),
1116
- delegate(e, t) {
1117
- this.handlers.has(e) ||
1118
- (this.handlers.set(e, new Set()),
1119
- document.addEventListener(e, this.handleEvent.bind(this))),
1120
- this.handlers.get(e).add(t);
1121
- },
1122
- handleEvent(e) {
1123
- const t = this.handlers.get(e.type);
1124
- t && t.forEach((t) => t(e));
1125
- },
1126
- },
1127
- createImmutableState = (e) => ({
1128
- value: e,
1129
- set(e) {
1130
- return !Object.is(this.value, e) && ((this.value = e), !0);
1131
- },
1132
- });
1133
- let renderThrottleTimeout = null;
1134
- const throttledRerender = () => {
1135
- renderThrottleTimeout ||
1136
- (renderThrottleTimeout = setTimeout(() => {
1137
- rerender(), (renderThrottleTimeout = null);
1138
- }, 16));
1139
- };
1
+ const memoize = (e) => {
2
+ const t = new Map();
3
+ return (...n) => {
4
+ const r = JSON.stringify(n);
5
+ return t.has(r) || t.set(r, e(...n)), t.get(r);
6
+ };
7
+ };
8
+ let currentObserver = null;
9
+ function diffProps(e = {}, t = {}, n) {
10
+ void 0 !== t.className && ((t.class = t.className), delete t.className),
11
+ void 0 !== e.className && ((e.class = e.className), delete e.className);
12
+ for (const [r, o] of Object.entries(e))
13
+ r in t ||
14
+ (r.startsWith("on")
15
+ ? n.removeEventListener(r.slice(2).toLowerCase(), o)
16
+ : "style" === r
17
+ ? (n.style.cssText = "")
18
+ : n.removeAttribute(r));
19
+ for (const [r, o] of Object.entries(t))
20
+ if (null != o && e[r] !== o)
21
+ if (r.startsWith("on")) {
22
+ const t = r.slice(2).toLowerCase();
23
+ e[r] && n.removeEventListener(t, e[r]), n.addEventListener(t, o);
24
+ } else if ("ref" === r)
25
+ o && "object" == typeof o && "current" in o
26
+ ? (o.current = n)
27
+ : "function" == typeof o && o(n);
28
+ else if ("style" === r) {
29
+ const e = n.style;
30
+ "object" == typeof o ? Object.assign(e, o) : (e.cssText = o);
31
+ } else n.setAttribute(r, o);
32
+ }
33
+ const diffChildren = memoize((e, t, n) => {
34
+ const r = Array.isArray(e) ? e.flat() : [e],
35
+ o = Array.isArray(t) ? t.flat() : [t],
36
+ s = Math.max(r.length, o.length);
37
+ for (let e = 0; e < s; e++) {
38
+ const t = r[e],
39
+ s = o[e];
40
+ if (!t || s)
41
+ if (t || !s) {
42
+ if (t instanceof Node && s instanceof Node)
43
+ t.nodeType !== s.nodeType || t.nodeName !== s.nodeName
44
+ ? n.replaceChild(s, t)
45
+ : (diffProps(t.attributes, s.attributes, t),
46
+ diffChildren(
47
+ Array.from(t.childNodes),
48
+ Array.from(s.childNodes),
49
+ t
50
+ ));
51
+ else if (t !== s) {
52
+ const t = n.childNodes[e];
53
+ t && (t.textContent = String(s));
54
+ }
55
+ } else {
56
+ const e = s instanceof Node ? s : document.createTextNode(String(s));
57
+ n.appendChild(e);
58
+ }
59
+ else t instanceof Node && n.removeChild(t);
60
+ }
61
+ });
62
+ class Signal {
63
+ constructor(e) {
64
+ (this._value = e),
65
+ (this.observers = new Map()),
66
+ (this.pending = new Set()),
67
+ (this.isBatching = !1);
68
+ }
69
+ get value() {
70
+ return (
71
+ currentObserver &&
72
+ (this.observers.has("_root") || this.observers.set("_root", new Set()),
73
+ this.observers.get("_root").add(currentObserver)),
74
+ this._value
75
+ );
76
+ }
77
+ set value(e) {
78
+ if (this._value === e) return;
79
+ const t = this._value;
80
+ if (((this._value = e), this.observers.has("_root")))
81
+ for (const e of this.observers.get("_root")) this.pending.add(e);
82
+ if ("object" == typeof t && "object" == typeof e) {
83
+ const n = new Set([...Object.keys(t), ...Object.keys(e)]);
84
+ for (const r of n)
85
+ if (t[r] !== e[r] && this.observers.has(r))
86
+ for (const e of this.observers.get(r)) this.pending.add(e);
87
+ }
88
+ this.batchUpdate();
89
+ }
90
+ batchUpdate() {
91
+ this.isBatching ||
92
+ ((this.isBatching = !0),
93
+ Promise.resolve().then(() => {
94
+ this.pending.forEach((e) => e()),
95
+ this.pending.clear(),
96
+ (this.isBatching = !1);
97
+ }));
98
+ }
99
+ observe(e, t) {
100
+ this.observers.has(e) || this.observers.set(e, new Set()),
101
+ this.observers.get(e).add(t);
102
+ }
103
+ unobserve(e, t) {
104
+ this.observers.has(e) && this.observers.get(e).delete(t);
105
+ }
106
+ }
107
+ function $signal(e) {
108
+ const t = new Signal(e),
109
+ n = () => t.value;
110
+ return (
111
+ (n.toString = () => t.value),
112
+ (n.observe = (e, n) => t.observe(e, n)),
113
+ (n.unobserve = (e, n) => t.unobserve(e, n)),
114
+ [
115
+ n,
116
+ (e) => {
117
+ t.value = "function" == typeof e ? e(t.value) : e;
118
+ },
119
+ ]
120
+ );
121
+ }
122
+ function $effect(e, t) {
123
+ let n,
124
+ r = !0,
125
+ o = null;
126
+ const s = () => {
127
+ "function" == typeof n && (n(), (n = void 0)), (currentObserver = o);
128
+ const t = e();
129
+ (currentObserver = null), "function" == typeof t && (n = t);
130
+ };
131
+ return (
132
+ (o = () => {
133
+ if (r || !t) return s(), void (r = !1);
134
+ Array.isArray(t) && 0 === t.length ? r && (s(), (r = !1)) : s();
135
+ }),
136
+ o(),
137
+ () => {
138
+ n && n();
139
+ }
140
+ );
141
+ }
142
+ function $memo(e) {
143
+ const [t, n] = $signal(e());
144
+ return $effect(() => n(e())), t;
145
+ }
146
+ function $ref(e) {
147
+ const [t, n] = $signal({
148
+ current: e,
149
+ toString() {
150
+ return this.current;
151
+ },
152
+ valueOf() {
153
+ return this.current;
154
+ },
155
+ });
156
+ return {
157
+ get current() {
158
+ return t().current;
159
+ },
160
+ set current(e) {
161
+ n((t) => (t.current === e ? t : { ...t, current: e }));
162
+ },
163
+ toString() {
164
+ return this.current.toString();
165
+ },
166
+ valueOf() {
167
+ return this.current;
168
+ },
169
+ };
170
+ }
171
+ function h(e, t, ...n) {
172
+ if (e === Fragment || Array.isArray(e)) {
173
+ const r = document.createDocumentFragment(),
174
+ o = e === Fragment ? t?.children || n : e;
175
+ return (
176
+ Array.isArray(o) &&
177
+ o.flat().forEach((e) => {
178
+ null != e &&
179
+ r.appendChild(
180
+ e instanceof Node ? e : document.createTextNode(String(e))
181
+ );
182
+ }),
183
+ r
184
+ );
185
+ }
186
+ if (!e) return null;
187
+ const r = "function" == typeof e ? e(t) : document.createElement(e);
188
+ if (("string" == typeof e && r && t && diffProps({}, t, r), n.length)) {
189
+ const e = document.createDocumentFragment(),
190
+ t = (n) => {
191
+ if (null != n)
192
+ if ("function" == typeof n) {
193
+ const t = document.createTextNode("");
194
+ $effect(() => {
195
+ const e = n();
196
+ if (Array.isArray(e)) {
197
+ const n = document.createDocumentFragment();
198
+ e.forEach((e) => {
199
+ n.appendChild(
200
+ e instanceof Node ? e : document.createTextNode(String(e))
201
+ );
202
+ }),
203
+ t.parentNode && t.parentNode.replaceChild(n, t);
204
+ } else t.textContent = String(e);
205
+ }),
206
+ e.appendChild(t);
207
+ } else
208
+ n instanceof Node
209
+ ? e.appendChild(n)
210
+ : Array.isArray(n)
211
+ ? n.flat().forEach(t)
212
+ : e.appendChild(document.createTextNode(String(n)));
213
+ };
214
+ n.forEach(t), r.appendChild(e);
215
+ }
216
+ return r;
217
+ }
218
+ const Component = (e, t) => {
219
+ if ("function" != typeof e)
220
+ throw new Error("Invalid Component: must be a function");
221
+ return e(t);
222
+ },
223
+ Fragment = (e) => e.children;
224
+ window.Fragment = Fragment;
225
+ const Olova = {
226
+ render(e, t) {
227
+ const n = "function" == typeof e ? e() : e;
228
+ return (
229
+ t.firstChild ? diffChildren([t.firstChild], [n], t) : t.appendChild(n),
230
+ n
231
+ );
232
+ },
233
+ mount(e, t) {
234
+ return this.render(e, t);
235
+ },
236
+ unmount(e) {
237
+ e.innerHTML = "";
238
+ },
239
+ Fragment: Fragment,
240
+ },
241
+ contextRegistry = new Map();
242
+ function $context(e) {
243
+ const t = Symbol("context");
244
+ return (
245
+ contextRegistry.set(t, e),
246
+ {
247
+ Provider({ value: e, children: n }) {
248
+ const r = contextRegistry.get(t);
249
+ contextRegistry.set(t, e);
250
+ const o = n;
251
+ return contextRegistry.set(t, r), o;
252
+ },
253
+ use() {
254
+ const n = contextRegistry.get(t);
255
+ if (void 0 === n && void 0 === e)
256
+ throw new Error("Context used outside of Provider");
257
+ return n ?? e;
258
+ },
259
+ }
260
+ );
261
+ }
262
+ function $callback(e, t) {
263
+ const [n, r] = $signal(() => ({
264
+ fn: e,
265
+ deps: t,
266
+ memoized: (...t) => e(...t),
267
+ }));
268
+ return (
269
+ $effect(() => {
270
+ const o = n();
271
+ t &&
272
+ ((o.deps &&
273
+ t.length === o.deps.length &&
274
+ !t.some((e, t) => e !== o.deps[t])) ||
275
+ r({ fn: e, deps: t, memoized: (...t) => e(...t) }));
276
+ }),
277
+ () => n().memoized
278
+ );
279
+ }
280
+ export {
281
+ $signal,
282
+ $effect,
283
+ $memo,
284
+ $ref,
285
+ $context,
286
+ $callback,
287
+ Component,
288
+ h,
289
+ Fragment,
290
+ };
291
+ export default Olova;