@unsetsoft/ryunixjs 1.1.7 → 1.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/Ryunix.js +361 -197
- package/dist/Ryunix.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<img src="https://raw.githubusercontent.com/UnSetSoft/Ryunixjs/
|
|
1
|
+
<img src="https://raw.githubusercontent.com/UnSetSoft/Ryunixjs/canary/assets/logo.png" width="200" height="200" style="
|
|
2
2
|
display: block;
|
|
3
3
|
margin: 0 auto;" />
|
|
4
4
|
|
|
@@ -14,4 +14,6 @@ Like React, NextJS, Preact, Vite. Ryunix allows you to build static websites fro
|
|
|
14
14
|
|
|
15
15
|
### Do you want to contribute?
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
You can make any change as long as it does not affect the `canary` branches. Make changes that are important, necessary or to add something new if you see it necessary, include your proposal before in an issue and then create a PR referencing that issue.
|
|
18
|
+
|
|
19
|
+
To be able to work more comfortably you should create a branch with this name `gh/[user]/[branch name]`, all changes should always go to the canary version. Once the changes are applied and no problems are detected, they will become part of the nightly version for further testing and finally the final version will be released. make each change with a simple descriptive message, and remember not to change the version of the mono repo or packages, such changes are made manually when a new update is about to be made.
|
package/dist/Ryunix.js
CHANGED
|
@@ -18,14 +18,16 @@
|
|
|
18
18
|
const reg = /[A-Z]/g;
|
|
19
19
|
|
|
20
20
|
const RYUNIX_TYPES = Object.freeze({
|
|
21
|
-
TEXT_ELEMENT: Symbol('text.element'),
|
|
22
|
-
Ryunix_ELEMENT: Symbol('ryunix.element'),
|
|
23
|
-
RYUNIX_EFFECT: Symbol('ryunix.effect'),
|
|
24
|
-
RYUNIX_MEMO: Symbol('ryunix.memo'),
|
|
25
|
-
RYUNIX_URL_QUERY: Symbol('ryunix.urlQuery'),
|
|
26
|
-
RYUNIX_REF: Symbol('ryunix.ref'),
|
|
27
|
-
RYUNIX_STORE: Symbol('ryunix.store'),
|
|
28
|
-
RYUNIX_REDUCE: Symbol('ryunix.reduce'),
|
|
21
|
+
TEXT_ELEMENT: Symbol('text.element').toString(),
|
|
22
|
+
Ryunix_ELEMENT: Symbol('ryunix.element').toString(),
|
|
23
|
+
RYUNIX_EFFECT: Symbol('ryunix.effect').toString(),
|
|
24
|
+
RYUNIX_MEMO: Symbol('ryunix.memo').toString(),
|
|
25
|
+
RYUNIX_URL_QUERY: Symbol('ryunix.urlQuery').toString(),
|
|
26
|
+
RYUNIX_REF: Symbol('ryunix.ref').toString(),
|
|
27
|
+
RYUNIX_STORE: Symbol('ryunix.store').toString(),
|
|
28
|
+
RYUNIX_REDUCE: Symbol('ryunix.reduce').toString(),
|
|
29
|
+
RYUNIX_FRAGMENT: Symbol('ryunix.fragment').toString(),
|
|
30
|
+
RYUNIX_CONTEXT: Symbol('ryunix.context').toString(),
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
const STRINGS = Object.freeze({
|
|
@@ -47,28 +49,9 @@
|
|
|
47
49
|
PLACEMENT: Symbol('ryunix.reconciler.status.placement').toString(),
|
|
48
50
|
UPDATE: Symbol('ryunix.reconciler.status.update').toString(),
|
|
49
51
|
DELETION: Symbol('ryunix.reconciler.status.deletion').toString(),
|
|
52
|
+
NO_EFFECT: Symbol('ryunix.reconciler.status.no_efect').toString(),
|
|
50
53
|
});
|
|
51
54
|
|
|
52
|
-
const generateHash = (prefix) => {
|
|
53
|
-
return `${prefix}-${Math.random().toString(36).substring(2, 9)}`
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const Fragment = (props) => {
|
|
57
|
-
return props.children
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const childArray = (children, out) => {
|
|
61
|
-
out = out || [];
|
|
62
|
-
if (children == undefined || typeof children == STRINGS.boolean) ; else if (Array.isArray(children)) {
|
|
63
|
-
children.some((child) => {
|
|
64
|
-
childArray(child, out);
|
|
65
|
-
});
|
|
66
|
-
} else {
|
|
67
|
-
out.push(children);
|
|
68
|
-
}
|
|
69
|
-
return out
|
|
70
|
-
};
|
|
71
|
-
|
|
72
55
|
/**
|
|
73
56
|
* The function creates a new element with the given type, props, and children.
|
|
74
57
|
* @param type - The type of the element to be created, such as "div", "span", "h1", etc.
|
|
@@ -87,20 +70,15 @@
|
|
|
87
70
|
*/
|
|
88
71
|
|
|
89
72
|
const createElement = (type, props, ...children) => {
|
|
90
|
-
children = childArray(children, []);
|
|
91
|
-
const key =
|
|
92
|
-
props && props.key
|
|
93
|
-
? generateHash(props.key)
|
|
94
|
-
: generateHash(RYUNIX_TYPES.Ryunix_ELEMENT.toString());
|
|
95
|
-
|
|
96
73
|
return {
|
|
97
74
|
type,
|
|
98
75
|
props: {
|
|
99
76
|
...props,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
77
|
+
children: children
|
|
78
|
+
.flat()
|
|
79
|
+
.map((child) =>
|
|
80
|
+
typeof child === STRINGS.object ? child : createTextElement(child),
|
|
81
|
+
),
|
|
104
82
|
},
|
|
105
83
|
}
|
|
106
84
|
};
|
|
@@ -122,6 +100,13 @@
|
|
|
122
100
|
}
|
|
123
101
|
};
|
|
124
102
|
|
|
103
|
+
const Fragment = (props) => {
|
|
104
|
+
const children = Array.isArray(props.children)
|
|
105
|
+
? props.children
|
|
106
|
+
: [props.children];
|
|
107
|
+
return createElement(RYUNIX_TYPES.RYUNIX_FRAGMENT, {}, ...children)
|
|
108
|
+
};
|
|
109
|
+
|
|
125
110
|
const isEvent = (key) => key.startsWith('on');
|
|
126
111
|
const isProperty = (key) => key !== STRINGS.children && !isEvent(key);
|
|
127
112
|
const isNew = (prev, next) => (key) => prev[key] !== next[key];
|
|
@@ -172,6 +157,9 @@
|
|
|
172
157
|
* properties of the newly created
|
|
173
158
|
*/
|
|
174
159
|
const createDom = (fiber) => {
|
|
160
|
+
if (fiber.type === RYUNIX_TYPES.RYUNIX_FRAGMENT) {
|
|
161
|
+
return null // Los fragmentos no crean nodos DOM reales
|
|
162
|
+
}
|
|
175
163
|
const dom =
|
|
176
164
|
fiber.type == RYUNIX_TYPES.TEXT_ELEMENT
|
|
177
165
|
? document.createTextNode('')
|
|
@@ -258,18 +246,8 @@
|
|
|
258
246
|
*/
|
|
259
247
|
const commitRoot = () => {
|
|
260
248
|
vars.deletions.forEach(commitWork);
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
vars.currentRoot = vars.wipRoot;
|
|
264
|
-
}
|
|
265
|
-
vars.effects.forEach((effect) => {
|
|
266
|
-
try {
|
|
267
|
-
effect();
|
|
268
|
-
} catch (err) {
|
|
269
|
-
console.error('Error in effect:', err);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
vars.effects = [];
|
|
249
|
+
commitWork(vars.wipRoot.child);
|
|
250
|
+
vars.currentRoot = vars.wipRoot;
|
|
273
251
|
vars.wipRoot = null;
|
|
274
252
|
};
|
|
275
253
|
|
|
@@ -281,7 +259,9 @@
|
|
|
281
259
|
* @returns The function does not return anything, it performs side effects by manipulating the DOM.
|
|
282
260
|
*/
|
|
283
261
|
const commitWork = (fiber) => {
|
|
284
|
-
if (!fiber)
|
|
262
|
+
if (!fiber) {
|
|
263
|
+
return
|
|
264
|
+
}
|
|
285
265
|
|
|
286
266
|
let domParentFiber = fiber.parent;
|
|
287
267
|
while (!domParentFiber.dom) {
|
|
@@ -289,20 +269,23 @@
|
|
|
289
269
|
}
|
|
290
270
|
const domParent = domParentFiber.dom;
|
|
291
271
|
|
|
292
|
-
if (fiber.effectTag === EFFECT_TAGS.PLACEMENT
|
|
293
|
-
|
|
272
|
+
if (fiber.effectTag === EFFECT_TAGS.PLACEMENT) {
|
|
273
|
+
if (fiber.dom != null) {
|
|
274
|
+
domParent.appendChild(fiber.dom);
|
|
275
|
+
}
|
|
294
276
|
runEffects(fiber);
|
|
295
|
-
} else if (fiber.effectTag === EFFECT_TAGS.UPDATE
|
|
277
|
+
} else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
|
|
296
278
|
cancelEffects(fiber);
|
|
297
|
-
|
|
279
|
+
if (fiber.dom != null) {
|
|
280
|
+
updateDom(fiber.dom, fiber.alternate.props, fiber.props);
|
|
281
|
+
}
|
|
298
282
|
runEffects(fiber);
|
|
299
283
|
} else if (fiber.effectTag === EFFECT_TAGS.DELETION) {
|
|
300
|
-
commitDeletion(fiber, domParent);
|
|
301
284
|
cancelEffects(fiber);
|
|
285
|
+
commitDeletion(fiber, domParent);
|
|
302
286
|
return
|
|
303
287
|
}
|
|
304
288
|
|
|
305
|
-
// Recorre los "fibers" hijos y hermanos
|
|
306
289
|
commitWork(fiber.child);
|
|
307
290
|
commitWork(fiber.sibling);
|
|
308
291
|
};
|
|
@@ -318,7 +301,11 @@
|
|
|
318
301
|
if (fiber.dom) {
|
|
319
302
|
domParent.removeChild(fiber.dom);
|
|
320
303
|
} else {
|
|
321
|
-
|
|
304
|
+
let child = fiber.child;
|
|
305
|
+
while (child) {
|
|
306
|
+
commitDeletion(child, domParent);
|
|
307
|
+
child = child.sibling;
|
|
308
|
+
}
|
|
322
309
|
}
|
|
323
310
|
};
|
|
324
311
|
|
|
@@ -331,53 +318,28 @@
|
|
|
331
318
|
* @param elements - an array of elements representing the new children to be rendered in the current
|
|
332
319
|
* fiber's subtree
|
|
333
320
|
*/
|
|
334
|
-
const shouldComponentUpdate = (oldProps, newProps) => {
|
|
335
|
-
// Comparar las propiedades antiguas y nuevas
|
|
336
|
-
return (
|
|
337
|
-
!oldProps ||
|
|
338
|
-
!newProps ||
|
|
339
|
-
Object.keys(oldProps).length !== Object.keys(newProps).length ||
|
|
340
|
-
Object.keys(newProps).some((key) => oldProps[key] !== newProps[key])
|
|
341
|
-
)
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
const recycleFiber = (oldFiber, newProps) => {
|
|
345
|
-
return {
|
|
346
|
-
...oldFiber,
|
|
347
|
-
props: newProps,
|
|
348
|
-
alternate: oldFiber,
|
|
349
|
-
effectTag: EFFECT_TAGS.UPDATE,
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
|
|
353
321
|
const reconcileChildren = (wipFiber, elements) => {
|
|
354
322
|
let index = 0;
|
|
355
323
|
let oldFiber = wipFiber.alternate && wipFiber.alternate.child;
|
|
356
|
-
let prevSibling
|
|
357
|
-
|
|
358
|
-
const oldFibersMap = new Map();
|
|
359
|
-
while (oldFiber) {
|
|
360
|
-
const oldKey = oldFiber.props.key || oldFiber.type;
|
|
361
|
-
oldFibersMap.set(oldKey, oldFiber);
|
|
362
|
-
oldFiber = oldFiber.sibling;
|
|
363
|
-
}
|
|
324
|
+
let prevSibling;
|
|
364
325
|
|
|
365
|
-
while (index < elements.length) {
|
|
326
|
+
while (index < elements.length || oldFiber != null) {
|
|
366
327
|
const element = elements[index];
|
|
367
|
-
const key = element.props.key || element.type;
|
|
368
|
-
const oldFiber = oldFibersMap.get(key);
|
|
369
|
-
|
|
370
328
|
let newFiber;
|
|
371
|
-
const sameType = oldFiber && element && element.type === oldFiber.type;
|
|
372
329
|
|
|
373
|
-
|
|
374
|
-
// Reutilizar fibra existente si no hay cambios
|
|
375
|
-
newFiber = recycleFiber(oldFiber, element.props);
|
|
376
|
-
oldFibersMap.delete(key);
|
|
377
|
-
}
|
|
330
|
+
const sameType = oldFiber && element && element.type == oldFiber.type;
|
|
378
331
|
|
|
332
|
+
if (sameType) {
|
|
333
|
+
newFiber = {
|
|
334
|
+
type: oldFiber.type,
|
|
335
|
+
props: element.props,
|
|
336
|
+
dom: oldFiber.dom,
|
|
337
|
+
parent: wipFiber,
|
|
338
|
+
alternate: oldFiber,
|
|
339
|
+
effectTag: EFFECT_TAGS.UPDATE,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
379
342
|
if (element && !sameType) {
|
|
380
|
-
// Crear nueva fibra
|
|
381
343
|
newFiber = {
|
|
382
344
|
type: element.type,
|
|
383
345
|
props: element.props,
|
|
@@ -387,28 +349,24 @@
|
|
|
387
349
|
effectTag: EFFECT_TAGS.PLACEMENT,
|
|
388
350
|
};
|
|
389
351
|
}
|
|
390
|
-
|
|
391
352
|
if (oldFiber && !sameType) {
|
|
392
353
|
oldFiber.effectTag = EFFECT_TAGS.DELETION;
|
|
393
|
-
|
|
394
|
-
|
|
354
|
+
vars.deletions.push(oldFiber);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (oldFiber) {
|
|
358
|
+
oldFiber = oldFiber.sibling;
|
|
395
359
|
}
|
|
396
360
|
|
|
397
361
|
if (index === 0) {
|
|
398
362
|
wipFiber.child = newFiber;
|
|
399
|
-
} else if (
|
|
363
|
+
} else if (element) {
|
|
400
364
|
prevSibling.sibling = newFiber;
|
|
401
365
|
}
|
|
402
366
|
|
|
403
367
|
prevSibling = newFiber;
|
|
404
|
-
|
|
405
368
|
index++;
|
|
406
369
|
}
|
|
407
|
-
|
|
408
|
-
oldFibersMap.forEach((oldFiber) => {
|
|
409
|
-
oldFiber.effectTag = EFFECT_TAGS.DELETION;
|
|
410
|
-
vars.deletions.push(oldFiber);
|
|
411
|
-
});
|
|
412
370
|
};
|
|
413
371
|
|
|
414
372
|
/**
|
|
@@ -422,11 +380,15 @@
|
|
|
422
380
|
vars.wipFiber = fiber;
|
|
423
381
|
vars.hookIndex = 0;
|
|
424
382
|
vars.wipFiber.hooks = [];
|
|
383
|
+
const children = [fiber.type(fiber.props)];
|
|
425
384
|
|
|
426
|
-
|
|
427
|
-
|
|
385
|
+
// Aquí detectamos si es Provider para guardar contexto y valor en fiber
|
|
386
|
+
if (fiber.type._contextId && fiber.props.value !== undefined) {
|
|
387
|
+
fiber._contextId = fiber.type._contextId;
|
|
388
|
+
fiber._contextValue = fiber.props.value;
|
|
389
|
+
}
|
|
428
390
|
|
|
429
|
-
reconcileChildren(fiber,
|
|
391
|
+
reconcileChildren(fiber, children);
|
|
430
392
|
};
|
|
431
393
|
|
|
432
394
|
/**
|
|
@@ -436,10 +398,18 @@
|
|
|
436
398
|
* fibers in the tree.
|
|
437
399
|
*/
|
|
438
400
|
const updateHostComponent = (fiber) => {
|
|
439
|
-
|
|
440
|
-
fiber.
|
|
401
|
+
const children = Array.isArray(fiber.props.children)
|
|
402
|
+
? fiber.props.children.flat()
|
|
403
|
+
: [fiber.props.children];
|
|
404
|
+
|
|
405
|
+
if (fiber.type === RYUNIX_TYPES.RYUNIX_FRAGMENT) {
|
|
406
|
+
reconcileChildren(fiber, children);
|
|
407
|
+
} else {
|
|
408
|
+
if (!fiber.dom) {
|
|
409
|
+
fiber.dom = createDom(fiber);
|
|
410
|
+
}
|
|
411
|
+
reconcileChildren(fiber, children);
|
|
441
412
|
}
|
|
442
|
-
reconcileChildren(fiber, fiber.props.children);
|
|
443
413
|
};
|
|
444
414
|
|
|
445
415
|
/* Internal components*/
|
|
@@ -528,7 +498,7 @@
|
|
|
528
498
|
requestIdleCallback(workLoop);
|
|
529
499
|
};
|
|
530
500
|
|
|
531
|
-
|
|
501
|
+
requestIdleCallback(workLoop);
|
|
532
502
|
|
|
533
503
|
/**
|
|
534
504
|
* The function performs a unit of work by updating either a function component or a host component and
|
|
@@ -540,7 +510,7 @@
|
|
|
540
510
|
* @returns The function `performUnitOfWork` returns the next fiber to be processed. If the current
|
|
541
511
|
* fiber has a child, it returns the child. Otherwise, it looks for the next sibling of the current
|
|
542
512
|
* fiber. If there are no more siblings, it goes up the tree to the parent and looks for the next
|
|
543
|
-
* sibling of the parent. The function returns `
|
|
513
|
+
* sibling of the parent. The function returns `null` if there are no more fibers to process.
|
|
544
514
|
*/
|
|
545
515
|
const performUnitOfWork = (fiber) => {
|
|
546
516
|
const isFunctionComponent = fiber.type instanceof Function;
|
|
@@ -559,7 +529,6 @@
|
|
|
559
529
|
}
|
|
560
530
|
nextFiber = nextFiber.parent;
|
|
561
531
|
}
|
|
562
|
-
return undefined
|
|
563
532
|
};
|
|
564
533
|
|
|
565
534
|
const scheduleWork = (root) => {
|
|
@@ -708,6 +677,15 @@
|
|
|
708
677
|
vars.hookIndex++;
|
|
709
678
|
};
|
|
710
679
|
|
|
680
|
+
/**
|
|
681
|
+
* The useRef function in JavaScript is used to create a reference object that persists between renders
|
|
682
|
+
* in a functional component.
|
|
683
|
+
* @param initial - The `initial` parameter in the `useRef` function represents the initial value that
|
|
684
|
+
* will be assigned to the `current` property of the reference object. This initial value will be used
|
|
685
|
+
* if there is no previous value stored in the hook.
|
|
686
|
+
* @returns The `useRef` function is returning the `current` property of the `hook.value` object. This
|
|
687
|
+
* property contains the current value of the reference being managed by the `useRef` hook.
|
|
688
|
+
*/
|
|
711
689
|
const useRef = (initial) => {
|
|
712
690
|
const oldHook =
|
|
713
691
|
vars.wipFiber.alternate &&
|
|
@@ -725,6 +703,19 @@
|
|
|
725
703
|
return hook.value
|
|
726
704
|
};
|
|
727
705
|
|
|
706
|
+
/**
|
|
707
|
+
* The useMemo function in JavaScript is used to memoize the result of a computation based on the
|
|
708
|
+
* dependencies provided.
|
|
709
|
+
* @param comp - The `comp` parameter in the `useMemo` function is a function that represents the
|
|
710
|
+
* computation that needs to be memoized. This function will be executed to calculate the memoized
|
|
711
|
+
* value based on the dependencies provided.
|
|
712
|
+
* @param deps - The `deps` parameter in the `useMemo` function stands for dependencies. It is an array
|
|
713
|
+
* of values that the function depends on. The `useMemo` function will only recompute the memoized
|
|
714
|
+
* value when one of the dependencies has changed.
|
|
715
|
+
* @returns The `useMemo` function returns the `value` property of the `hook` object, which is either
|
|
716
|
+
* the memoized value from the previous render if the dependencies have not changed, or the result of
|
|
717
|
+
* calling the `comp` function if the dependencies have changed.
|
|
718
|
+
*/
|
|
728
719
|
const useMemo = (comp, deps) => {
|
|
729
720
|
const oldHook =
|
|
730
721
|
vars.wipFiber.alternate &&
|
|
@@ -753,6 +744,16 @@
|
|
|
753
744
|
return hook.value
|
|
754
745
|
};
|
|
755
746
|
|
|
747
|
+
/**
|
|
748
|
+
* The useCallback function in JavaScript returns a memoized version of the callback function that only
|
|
749
|
+
* changes if one of the dependencies has changed.
|
|
750
|
+
* @param callback - The `callback` parameter is a function that you want to memoize using
|
|
751
|
+
* `useCallback`. This function will only be re-created if any of the dependencies specified in the
|
|
752
|
+
* `deps` array change.
|
|
753
|
+
* @param deps - Dependencies array that the callback function depends on.
|
|
754
|
+
* @returns The useCallback function is returning a memoized version of the callback function. It is
|
|
755
|
+
* using the useMemo hook to memoize the callback function based on the provided dependencies (deps).
|
|
756
|
+
*/
|
|
756
757
|
const useCallback = (callback, deps) => {
|
|
757
758
|
return useMemo(() => callback, deps)
|
|
758
759
|
};
|
|
@@ -771,6 +772,37 @@
|
|
|
771
772
|
return query
|
|
772
773
|
};
|
|
773
774
|
|
|
775
|
+
const createContext = (defaultValue) => {
|
|
776
|
+
const contextId = RYUNIX_TYPES.RYUNIX_CONTEXT;
|
|
777
|
+
|
|
778
|
+
const Provider = ({ value, children }) => {
|
|
779
|
+
return Fragment({
|
|
780
|
+
children: children,
|
|
781
|
+
})
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
Provider._contextId = contextId;
|
|
785
|
+
|
|
786
|
+
const useContext = () => {
|
|
787
|
+
let fiber = vars.wipFiber;
|
|
788
|
+
while (fiber) {
|
|
789
|
+
if (fiber.type && fiber.type._contextId === contextId) {
|
|
790
|
+
if (fiber.props && 'value' in fiber.props) {
|
|
791
|
+
return fiber.props.value
|
|
792
|
+
}
|
|
793
|
+
return undefined
|
|
794
|
+
}
|
|
795
|
+
fiber = fiber.parent;
|
|
796
|
+
}
|
|
797
|
+
return defaultValue
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
return {
|
|
801
|
+
Provider,
|
|
802
|
+
useContext,
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
|
|
774
806
|
/**
|
|
775
807
|
* `useRouter` is a routing function to manage navigation, nested routes, and route pre-loading.
|
|
776
808
|
*
|
|
@@ -826,115 +858,243 @@
|
|
|
826
858
|
* </>
|
|
827
859
|
* );
|
|
828
860
|
*/
|
|
829
|
-
const useRouter = (routes) => {
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
861
|
+
// const useRouter = (routes) => {
|
|
862
|
+
// const [location, setLocation] = useStore(window.location.pathname)
|
|
863
|
+
|
|
864
|
+
// const findRoute = (routes, path) => {
|
|
865
|
+
// const pathname = path.split('?')[0]
|
|
866
|
+
|
|
867
|
+
// const notFoundRoute = routes.find((route) => route.NotFound)
|
|
868
|
+
// const notFound = notFoundRoute
|
|
869
|
+
// ? { route: { component: notFoundRoute.NotFound }, params: {} }
|
|
870
|
+
// : { route: { component: null }, params: {} }
|
|
871
|
+
|
|
872
|
+
// for (const route of routes) {
|
|
873
|
+
// if (route.subRoutes) {
|
|
874
|
+
// const childRoute = findRoute(route.subRoutes, path)
|
|
875
|
+
// if (childRoute) return childRoute
|
|
876
|
+
// }
|
|
877
|
+
|
|
878
|
+
// if (route.path === '*') {
|
|
879
|
+
// return notFound
|
|
880
|
+
// }
|
|
881
|
+
|
|
882
|
+
// if (!route.path || typeof route.path !== 'string') {
|
|
883
|
+
// console.warn('Invalid route detected:', route)
|
|
884
|
+
// console.info(
|
|
885
|
+
// "if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }",
|
|
886
|
+
// )
|
|
887
|
+
// continue
|
|
888
|
+
// }
|
|
889
|
+
|
|
890
|
+
// const keys = []
|
|
891
|
+
// const pattern = new RegExp(
|
|
892
|
+
// `^${route.path.replace(/:\w+/g, (match) => {
|
|
893
|
+
// keys.push(match.substring(1))
|
|
894
|
+
// return '([^/]+)'
|
|
895
|
+
// })}$`,
|
|
896
|
+
// )
|
|
897
|
+
|
|
898
|
+
// const match = pathname.match(pattern)
|
|
899
|
+
// if (match) {
|
|
900
|
+
// const params = keys.reduce((acc, key, index) => {
|
|
901
|
+
// acc[key] = match[index + 1]
|
|
902
|
+
// return acc
|
|
903
|
+
// }, {})
|
|
904
|
+
|
|
905
|
+
// return { route, params }
|
|
906
|
+
// }
|
|
907
|
+
// }
|
|
908
|
+
|
|
909
|
+
// return notFound
|
|
910
|
+
// }
|
|
911
|
+
|
|
912
|
+
// const navigate = (path) => {
|
|
913
|
+
// window.history.pushState({}, '', path)
|
|
914
|
+
|
|
915
|
+
// updateRoute(path)
|
|
916
|
+
// }
|
|
917
|
+
|
|
918
|
+
// const updateRoute = (path) => {
|
|
919
|
+
// const cleanedPath = path.split('?')[0]
|
|
920
|
+
// setLocation(cleanedPath)
|
|
921
|
+
// }
|
|
922
|
+
|
|
923
|
+
// useEffect(() => {
|
|
924
|
+
// const onPopState = () => updateRoute(window.location.pathname)
|
|
925
|
+
// window.addEventListener('popstate', onPopState)
|
|
926
|
+
|
|
927
|
+
// return () => window.removeEventListener('popstate', onPopState)
|
|
928
|
+
// }, [])
|
|
929
|
+
|
|
930
|
+
// const currentRouteData = findRoute(routes, location) || {}
|
|
931
|
+
|
|
932
|
+
// const Children = () => {
|
|
933
|
+
// const query = useQuery()
|
|
934
|
+
// const { route } = currentRouteData
|
|
935
|
+
|
|
936
|
+
// if (
|
|
937
|
+
// !route ||
|
|
938
|
+
// !route.component ||
|
|
939
|
+
// typeof route.component !== STRINGS.function
|
|
940
|
+
// ) {
|
|
941
|
+
// console.error(
|
|
942
|
+
// 'Component not found for current path or the component is not a valid function:',
|
|
943
|
+
// currentRouteData,
|
|
944
|
+
// )
|
|
945
|
+
// return null
|
|
946
|
+
// }
|
|
947
|
+
|
|
948
|
+
// const WrappedComponent = () =>
|
|
949
|
+
// createElement(route.component, {
|
|
950
|
+
// key: location,
|
|
951
|
+
// params: currentRouteData.params || {},
|
|
952
|
+
// query,
|
|
953
|
+
// })
|
|
954
|
+
|
|
955
|
+
// return createElement(WrappedComponent)
|
|
956
|
+
// }
|
|
957
|
+
|
|
958
|
+
// const NavLink = ({ to, ...props }) => {
|
|
959
|
+
// const handleClick = (e) => {
|
|
960
|
+
// e.preventDefault()
|
|
961
|
+
// navigate(to)
|
|
962
|
+
// }
|
|
963
|
+
// return createElement(
|
|
964
|
+
// 'a',
|
|
965
|
+
// { href: to, onClick: handleClick, ...props },
|
|
966
|
+
// props.children,
|
|
967
|
+
// )
|
|
968
|
+
// }
|
|
969
|
+
|
|
970
|
+
// return { Children, NavLink, navigate }
|
|
971
|
+
// }
|
|
972
|
+
|
|
973
|
+
// Crear contexto para Router
|
|
974
|
+
const RouterContext = createContext({
|
|
975
|
+
location: '/',
|
|
976
|
+
params: {},
|
|
977
|
+
query: {},
|
|
978
|
+
navigate: (path) => {},
|
|
979
|
+
route: null,
|
|
980
|
+
});
|
|
834
981
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
? { route: { component: notFoundRoute.NotFound }, params: {} }
|
|
838
|
-
: { route: { component: null }, params: {} };
|
|
982
|
+
const findRoute = (routes, path) => {
|
|
983
|
+
const pathname = path.split('?')[0];
|
|
839
984
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
}
|
|
985
|
+
const notFoundRoute = routes.find((route) => route.NotFound);
|
|
986
|
+
const notFound = notFoundRoute
|
|
987
|
+
? { route: { component: notFoundRoute.NotFound }, params: {} }
|
|
988
|
+
: { route: { component: null }, params: {} };
|
|
845
989
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
990
|
+
for (const route of routes) {
|
|
991
|
+
if (route.subRoutes) {
|
|
992
|
+
const childRoute = findRoute(route.subRoutes, path);
|
|
993
|
+
if (childRoute) return childRoute
|
|
994
|
+
}
|
|
849
995
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
"if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }",
|
|
854
|
-
);
|
|
855
|
-
continue
|
|
856
|
-
}
|
|
996
|
+
if (route.path === '*') {
|
|
997
|
+
return notFound
|
|
998
|
+
}
|
|
857
999
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
return '([^/]+)'
|
|
863
|
-
})}$`,
|
|
1000
|
+
if (!route.path || typeof route.path !== 'string') {
|
|
1001
|
+
console.warn('Invalid route detected:', route);
|
|
1002
|
+
console.info(
|
|
1003
|
+
"if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }",
|
|
864
1004
|
);
|
|
1005
|
+
continue
|
|
1006
|
+
}
|
|
865
1007
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1008
|
+
const keys = [];
|
|
1009
|
+
const pattern = new RegExp(
|
|
1010
|
+
`^${route.path.replace(/:\w+/g, (match) => {
|
|
1011
|
+
keys.push(match.substring(1));
|
|
1012
|
+
return '([^/]+)'
|
|
1013
|
+
})}$`,
|
|
1014
|
+
);
|
|
1015
|
+
|
|
1016
|
+
const match = pathname.match(pattern);
|
|
1017
|
+
if (match) {
|
|
1018
|
+
const params = keys.reduce((acc, key, index) => {
|
|
1019
|
+
acc[key] = match[index + 1];
|
|
1020
|
+
return acc
|
|
1021
|
+
}, {});
|
|
1022
|
+
|
|
1023
|
+
return { route, params }
|
|
875
1024
|
}
|
|
1025
|
+
}
|
|
876
1026
|
|
|
877
|
-
|
|
878
|
-
|
|
1027
|
+
return notFound
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
const RouterProvider = ({ routes, children }) => {
|
|
1031
|
+
const [location, setLocation] = useStore(window.location.pathname);
|
|
1032
|
+
|
|
1033
|
+
useEffect(() => {
|
|
1034
|
+
const onPopState = () => setLocation(window.location.pathname);
|
|
1035
|
+
window.addEventListener('popstate', onPopState);
|
|
1036
|
+
return () => window.removeEventListener('popstate', onPopState)
|
|
1037
|
+
}, []);
|
|
879
1038
|
|
|
880
1039
|
const navigate = (path) => {
|
|
881
1040
|
window.history.pushState({}, '', path);
|
|
882
|
-
|
|
1041
|
+
setLocation(path);
|
|
883
1042
|
};
|
|
884
1043
|
|
|
885
|
-
const
|
|
886
|
-
|
|
887
|
-
|
|
1044
|
+
const currentRouteData = findRoute(routes, location) || {};
|
|
1045
|
+
const query = useQuery();
|
|
1046
|
+
|
|
1047
|
+
const contextValue = {
|
|
1048
|
+
location,
|
|
1049
|
+
params: currentRouteData.params || {},
|
|
1050
|
+
query,
|
|
1051
|
+
navigate,
|
|
1052
|
+
route: currentRouteData.route,
|
|
888
1053
|
};
|
|
889
1054
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1055
|
+
return createElement(
|
|
1056
|
+
RouterContext.Provider,
|
|
1057
|
+
{ value: contextValue },
|
|
1058
|
+
Fragment({
|
|
1059
|
+
children: children,
|
|
1060
|
+
}),
|
|
1061
|
+
)
|
|
1062
|
+
};
|
|
893
1063
|
|
|
894
|
-
|
|
895
|
-
|
|
1064
|
+
const useRouter = () => {
|
|
1065
|
+
return RouterContext.useContext()
|
|
1066
|
+
};
|
|
896
1067
|
|
|
897
|
-
|
|
1068
|
+
const Children = () => {
|
|
1069
|
+
const { route, params, query, location } = useRouter();
|
|
898
1070
|
|
|
899
|
-
|
|
900
|
-
const query = useQuery();
|
|
901
|
-
const { route } = currentRouteData;
|
|
902
|
-
|
|
903
|
-
if (
|
|
904
|
-
!route ||
|
|
905
|
-
!route.component ||
|
|
906
|
-
typeof route.component !== STRINGS.function
|
|
907
|
-
) {
|
|
908
|
-
console.error(
|
|
909
|
-
'Component not found for current path or the component is not a valid function:',
|
|
910
|
-
currentRouteData,
|
|
911
|
-
);
|
|
912
|
-
return null
|
|
913
|
-
}
|
|
1071
|
+
if (!route || !route.component) return null
|
|
914
1072
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
query,
|
|
918
|
-
})
|
|
919
|
-
};
|
|
1073
|
+
return createElement(route.component, { key: location, params, query })
|
|
1074
|
+
};
|
|
920
1075
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
{ href: to, onClick: handleClick, ...props },
|
|
929
|
-
props.children,
|
|
930
|
-
)
|
|
1076
|
+
// Componente NavLink para navegación interna
|
|
1077
|
+
const NavLink = ({ to, ...props }) => {
|
|
1078
|
+
const { navigate } = useRouter();
|
|
1079
|
+
|
|
1080
|
+
const handleClick = (e) => {
|
|
1081
|
+
e.preventDefault();
|
|
1082
|
+
navigate(to);
|
|
931
1083
|
};
|
|
932
1084
|
|
|
933
|
-
return
|
|
1085
|
+
return createElement(
|
|
1086
|
+
'a',
|
|
1087
|
+
{ href: to, onClick: handleClick, ...props },
|
|
1088
|
+
props.children,
|
|
1089
|
+
)
|
|
934
1090
|
};
|
|
935
1091
|
|
|
936
1092
|
var Hooks = /*#__PURE__*/Object.freeze({
|
|
937
1093
|
__proto__: null,
|
|
1094
|
+
Children: Children,
|
|
1095
|
+
NavLink: NavLink,
|
|
1096
|
+
RouterProvider: RouterProvider,
|
|
1097
|
+
createContext: createContext,
|
|
938
1098
|
useCallback: useCallback,
|
|
939
1099
|
useEffect: useEffect,
|
|
940
1100
|
useMemo: useMemo,
|
|
@@ -954,7 +1114,11 @@
|
|
|
954
1114
|
|
|
955
1115
|
window.Ryunix = Ryunix;
|
|
956
1116
|
|
|
1117
|
+
exports.Children = Children;
|
|
957
1118
|
exports.Image = Image;
|
|
1119
|
+
exports.NavLink = NavLink;
|
|
1120
|
+
exports.RouterProvider = RouterProvider;
|
|
1121
|
+
exports.createContext = createContext;
|
|
958
1122
|
exports.default = Ryunix;
|
|
959
1123
|
exports.useCallback = useCallback;
|
|
960
1124
|
exports.useEffect = useEffect;
|
package/dist/Ryunix.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("lodash")):"function"==typeof define&&define.amd?define(["exports","lodash"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Ryunix={},e.lodash)}(this,(function(e,t){"use strict";let o={containerRoot:null,nextUnitOfWork:null,currentRoot:null,wipRoot:null,deletions:null,wipFiber:null,hookIndex:null,effects:null};const n=/[A-Z]/g,r=Object.freeze({TEXT_ELEMENT:Symbol("text.element"),Ryunix_ELEMENT:Symbol("ryunix.element"),RYUNIX_EFFECT:Symbol("ryunix.effect"),RYUNIX_MEMO:Symbol("ryunix.memo"),RYUNIX_URL_QUERY:Symbol("ryunix.urlQuery"),RYUNIX_REF:Symbol("ryunix.ref"),RYUNIX_STORE:Symbol("ryunix.store"),RYUNIX_REDUCE:Symbol("ryunix.reduce")}),
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("lodash")):"function"==typeof define&&define.amd?define(["exports","lodash"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Ryunix={},e.lodash)}(this,(function(e,t){"use strict";let o={containerRoot:null,nextUnitOfWork:null,currentRoot:null,wipRoot:null,deletions:null,wipFiber:null,hookIndex:null,effects:null};const n=/[A-Z]/g,r=Object.freeze({TEXT_ELEMENT:Symbol("text.element").toString(),Ryunix_ELEMENT:Symbol("ryunix.element").toString(),RYUNIX_EFFECT:Symbol("ryunix.effect").toString(),RYUNIX_MEMO:Symbol("ryunix.memo").toString(),RYUNIX_URL_QUERY:Symbol("ryunix.urlQuery").toString(),RYUNIX_REF:Symbol("ryunix.ref").toString(),RYUNIX_STORE:Symbol("ryunix.store").toString(),RYUNIX_REDUCE:Symbol("ryunix.reduce").toString(),RYUNIX_FRAGMENT:Symbol("ryunix.fragment").toString(),RYUNIX_CONTEXT:Symbol("ryunix.context").toString()}),i=Object.freeze({object:"object",function:"function",style:"ryunix-style",className:"ryunix-class",children:"children",boolean:"boolean",string:"string"}),s=Object.freeze({style:"style",className:"className"}),l=Object.freeze({PLACEMENT:Symbol("ryunix.reconciler.status.placement").toString(),UPDATE:Symbol("ryunix.reconciler.status.update").toString(),DELETION:Symbol("ryunix.reconciler.status.deletion").toString(),NO_EFFECT:Symbol("ryunix.reconciler.status.no_efect").toString()}),a=(e,t,...o)=>({type:e,props:{...t,children:o.flat().map((e=>typeof e===i.object?e:c(e)))}}),c=e=>({type:r.TEXT_ELEMENT,props:{nodeValue:e,children:[]}}),u=e=>{const t=Array.isArray(e.children)?e.children:[e.children];return a(r.RYUNIX_FRAGMENT,{},...t)},p=e=>e.startsWith("on"),d=e=>e!==i.children&&!p(e),f=(e,t)=>o=>e[o]!==t[o],h=e=>t=>!(t in e),y=e=>{e.hooks&&e.hooks.filter((e=>e.tag===r.RYUNIX_EFFECT&&e.cancel)).forEach((e=>{e.cancel()}))},m=e=>{e.hooks&&e.hooks.filter((e=>e.tag===r.RYUNIX_EFFECT&&e.effect)).forEach((e=>{e.cancel=e.effect()}))},E=(e,t,o)=>{Object.keys(t).filter(p).filter((e=>h(o)(e)||f(t,o)(e))).forEach((o=>{const n=o.toLowerCase().substring(2);e.removeEventListener(n,t[o])})),Object.keys(t).filter(d).filter(h(o)).forEach((t=>{e[t]=""})),Object.keys(o).filter(d).filter(f(t,o)).forEach((n=>{if(n===i.style)w(e,o["ryunix-style"]);else if(n===s.style)w(e,o.style);else if(n===i.className){if(""===o["ryunix-class"])throw new Error("data-class cannot be empty.");t["ryunix-class"]&&e.classList.remove(...t["ryunix-class"].split(/\s+/)),e.classList.add(...o["ryunix-class"].split(/\s+/))}else if(n===s.className){if(""===o.className)throw new Error("className cannot be empty.");t.className&&e.classList.remove(...t.className.split(/\s+/)),e.classList.add(...o.className.split(/\s+/))}else e[n]=o[n]})),Object.keys(o).filter(p).filter(f(t,o)).forEach((t=>{const n=t.toLowerCase().substring(2);e.addEventListener(n,o[t])}))},w=(e,t)=>{e.style=Object.keys(t).reduce(((e,o)=>e+=`${o.replace(n,(function(e){return"-"+e.toLowerCase()}))}: ${t[o]};`),"")},b=e=>{if(!e)return;let t=e.parent;for(;!t.dom;)t=t.parent;const o=t.dom;if(e.effectTag===l.PLACEMENT)null!=e.dom&&o.appendChild(e.dom),m(e);else if(e.effectTag===l.UPDATE)y(e),null!=e.dom&&E(e.dom,e.alternate.props,e.props),m(e);else if(e.effectTag===l.DELETION)return y(e),void x(e,o);b(e.child),b(e.sibling)},x=(e,t)=>{if(e.dom)t.removeChild(e.dom);else{let o=e.child;for(;o;)x(o,t),o=o.sibling}},R=(e,t)=>{let n,r=0,i=e.alternate&&e.alternate.child;for(;r<t.length||null!=i;){const s=t[r];let a;const c=i&&s&&s.type==i.type;c&&(a={type:i.type,props:s.props,dom:i.dom,parent:e,alternate:i,effectTag:l.UPDATE}),s&&!c&&(a={type:s.type,props:s.props,dom:null,parent:e,alternate:null,effectTag:l.PLACEMENT}),i&&!c&&(i.effectTag=l.DELETION,o.deletions.push(i)),i&&(i=i.sibling),0===r?e.child=a:s&&(n.sibling=a),n=a,r++}},g=e=>{const t=Array.isArray(e.props.children)?e.props.children.flat():[e.props.children];e.type===r.RYUNIX_FRAGMENT||e.dom||(e.dom=(e=>{if(e.type===r.RYUNIX_FRAGMENT)return null;const t=e.type==r.TEXT_ELEMENT?document.createTextNode(""):document.createElement(e.type);return E(t,{},e.props),t})(e)),R(e,t)},k=e=>{let t=!1;for(;o.nextUnitOfWork&&!t;)o.nextUnitOfWork=N(o.nextUnitOfWork),t=e.timeRemaining()<1;!o.nextUnitOfWork&&o.wipRoot&&(o.deletions.forEach(b),b(o.wipRoot.child),o.currentRoot=o.wipRoot,o.wipRoot=null),requestIdleCallback(k)};requestIdleCallback(k);const N=e=>{if(e.type instanceof Function?(e=>{o.wipFiber=e,o.hookIndex=0,o.wipFiber.hooks=[];const t=[e.type(e.props)];e.type._contextId&&void 0!==e.props.value&&(e._contextId=e.type._contextId,e._contextValue=e.props.value),R(e,t)})(e):g(e),e.child)return e.child;let t=e;for(;t;){if(t.sibling)return t.sibling;t=t.parent}},I=e=>{o.nextUnitOfWork=e,o.wipRoot=e,o.deletions=[],o.hookIndex=0,o.effects=[],requestIdleCallback(k)},F=(e,t)=>(o.wipRoot={dom:t,props:{children:[e]},alternate:o.currentRoot},o.nextUnitOfWork=o.wipRoot,o.deletions=[],I(o.wipRoot),o.wipRoot),T=(e,t)=>v(((e,t)=>"function"==typeof t?t(e):t),e,t),v=(e,t,n)=>{const r=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],i={state:r?r.state:n?n(t):t,queue:r&&Array.isArray(r.queue)?r.queue.slice():[]};r&&Array.isArray(r.queue)&&r.queue.forEach((t=>{i.state=e(i.state,t)}));return i.queue.forEach((t=>{i.state=e(i.state,t)})),o.wipFiber.hooks[o.hookIndex]=i,o.hookIndex++,[i.state,e=>{i.queue.push(e),o.wipRoot={dom:o.currentRoot.dom,props:o.currentRoot.props,alternate:o.currentRoot},o.deletions=[],o.hookIndex=0,I(o.wipRoot)}]},_=(e,n)=>{const i=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],s={type:r.RYUNIX_EFFECT,deps:n,cleanup:i?.cleanup};(!i||!t.isEqual(i.deps,n))&&o.effects.push((()=>{"function"==typeof s.cleanup&&s.cleanup();const t=e();"function"==typeof t&&(s.cleanup=t)})),o.wipFiber.hooks[o.hookIndex]=s,o.hookIndex++},S=e=>{const t=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],n={type:r.RYUNIX_REF,value:t?t.value:{current:e}};return o.wipFiber.hooks[o.hookIndex]=n,o.hookIndex++,n.value},U=(e,n)=>{const i=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],s={type:r.RYUNIX_MEMO,value:null,deps:n};return i&&t.isEqual(i.deps,s.deps)?s.value=i.value:s.value=e(),o.wipFiber.hooks[o.hookIndex]=s,o.hookIndex++,s.value},C=(e,t)=>U((()=>e),t),O=()=>{const e=new URLSearchParams(window.location.search),t={};for(let[o,n]of e.entries())t[o]=n;return t},L=e=>{const t=r.RYUNIX_CONTEXT,n=({value:e,children:t})=>u({children:t});n._contextId=t;return{Provider:n,useContext:()=>{let n=o.wipFiber;for(;n;){if(n.type&&n.type._contextId===t)return n.props&&"value"in n.props?n.props.value:void 0;n=n.parent}return e}}},X=L({location:"/",params:{},query:{},navigate:e=>{},route:null}),q=(e,t)=>{const o=t.split("?")[0],n=e.find((e=>e.NotFound)),r=n?{route:{component:n.NotFound},params:{}}:{route:{component:null},params:{}};for(const n of e){if(n.subRoutes){const e=q(n.subRoutes,t);if(e)return e}if("*"===n.path)return r;if(!n.path||"string"!=typeof n.path){console.warn("Invalid route detected:",n),console.info("if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }");continue}const e=[],i=new RegExp(`^${n.path.replace(/:\w+/g,(t=>(e.push(t.substring(1)),"([^/]+)")))}$`),s=o.match(i);if(s){return{route:n,params:e.reduce(((e,t,o)=>(e[t]=s[o+1],e)),{})}}}return r},A=({routes:e,children:t})=>{const[o,n]=T(window.location.pathname);_((()=>{const e=()=>n(window.location.pathname);return window.addEventListener("popstate",e),()=>window.removeEventListener("popstate",e)}),[]);const r=q(e,o)||{},i=O(),s={location:o,params:r.params||{},query:i,navigate:e=>{window.history.pushState({},"",e),n(e)},route:r.route};return a(X.Provider,{value:s},u({children:t}))},M=()=>X.useContext(),Y=()=>{const{route:e,params:t,query:o,location:n}=M();return e&&e.component?a(e.component,{key:n,params:t,query:o}):null},j=({to:e,...t})=>{const{navigate:o}=M();return a("a",{href:e,onClick:t=>{t.preventDefault(),o(e)},...t},t.children)};var P={createElement:a,render:F,init:(e,t="__ryunix")=>{o.containerRoot=document.getElementById(t);return F(e,o.containerRoot)},Fragment:u,Hooks:Object.freeze({__proto__:null,Children:Y,NavLink:j,RouterProvider:A,createContext:L,useCallback:C,useEffect:_,useMemo:U,useQuery:O,useRef:S,useRouter:M,useStore:T})};window.Ryunix=P,e.Children=Y,e.Image=({src:e,...t})=>{const o="true"===t.optimization?(({src:e,props:t})=>{const o=new URLSearchParams,n=!e.startsWith("http")||!e.startsWith("https");t.width&&o.set("width",t.width),t.height&&o.set("width",t.height),t.quality&&o.set("quality",t.quality);const r=t.extension?`@${t.extension}`:"",i="http://localhost:3000"===window.location.origin||"http://localhost:5173"===window.location.origin||"http://localhost:4173"===window.location.origin;return n?i?(console.warn("Image optimizations only work with full links and must not contain localhost."),e):`${window.location.origin}/${e}`:`https://image.unsetsoft.com/image/${e}${r}?${o.toString()}`})({src:e,props:t}):e;return a("img",{src:o,props:t},null)},e.NavLink=j,e.RouterProvider=A,e.createContext=L,e.default=P,e.useCallback=C,e.useEffect=_,e.useMemo=U,e.useQuery=O,e.useRef=S,e.useRouter=M,e.useStore=T,Object.defineProperty(e,"__esModule",{value:!0})}));
|