@unsetsoft/ryunixjs 1.1.7-canary.8 → 1.1.7-canary.80

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/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,16 +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
55
  /**
61
56
  * The function creates a new element with the given type, props, and children.
62
57
  * @param type - The type of the element to be created, such as "div", "span", "h1", etc.
@@ -75,16 +70,10 @@
75
70
  */
76
71
 
77
72
  const createElement = (type, props, ...children) => {
78
- const key =
79
- props && props.key
80
- ? generateHash(props.key)
81
- : generateHash(RYUNIX_TYPES.Ryunix_ELEMENT.toString());
82
-
83
73
  return {
84
74
  type,
85
75
  props: {
86
76
  ...props,
87
- key,
88
77
  children: children
89
78
  .flat()
90
79
  .map((child) =>
@@ -111,6 +100,9 @@
111
100
  }
112
101
  };
113
102
 
103
+ const Fragment = (props) =>
104
+ createElement(RYUNIX_TYPES.RYUNIX_FRAGMENT, {}, ...props.children);
105
+
114
106
  const isEvent = (key) => key.startsWith('on');
115
107
  const isProperty = (key) => key !== STRINGS.children && !isEvent(key);
116
108
  const isNew = (prev, next) => (key) => prev[key] !== next[key];
@@ -247,18 +239,8 @@
247
239
  */
248
240
  const commitRoot = () => {
249
241
  vars.deletions.forEach(commitWork);
250
- if (vars.wipRoot && vars.wipRoot.child) {
251
- commitWork(vars.wipRoot.child);
252
- vars.currentRoot = vars.wipRoot;
253
- }
254
- vars.effects.forEach((effect) => {
255
- try {
256
- effect();
257
- } catch (err) {
258
- console.error('Error in effect:', err);
259
- }
260
- });
261
- vars.effects = [];
242
+ commitWork(vars.wipRoot.child);
243
+ vars.currentRoot = vars.wipRoot;
262
244
  vars.wipRoot = null;
263
245
  };
264
246
 
@@ -270,7 +252,9 @@
270
252
  * @returns The function does not return anything, it performs side effects by manipulating the DOM.
271
253
  */
272
254
  const commitWork = (fiber) => {
273
- if (!fiber) return
255
+ if (!fiber) {
256
+ return
257
+ }
274
258
 
275
259
  let domParentFiber = fiber.parent;
276
260
  while (!domParentFiber.dom) {
@@ -278,20 +262,23 @@
278
262
  }
279
263
  const domParent = domParentFiber.dom;
280
264
 
281
- if (fiber.effectTag === EFFECT_TAGS.PLACEMENT && fiber.dom != null) {
282
- domParent.appendChild(fiber.dom);
265
+ if (fiber.effectTag === EFFECT_TAGS.PLACEMENT) {
266
+ if (fiber.dom != null) {
267
+ domParent.appendChild(fiber.dom);
268
+ }
283
269
  runEffects(fiber);
284
- } else if (fiber.effectTag === EFFECT_TAGS.UPDATE && fiber.dom != null) {
270
+ } else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
285
271
  cancelEffects(fiber);
286
- updateDom(fiber.dom, fiber.alternate.props, fiber.props);
272
+ if (fiber.dom != null) {
273
+ updateDom(fiber.dom, fiber.alternate.props, fiber.props);
274
+ }
287
275
  runEffects(fiber);
288
276
  } else if (fiber.effectTag === EFFECT_TAGS.DELETION) {
289
- commitDeletion(fiber, domParent);
290
277
  cancelEffects(fiber);
278
+ commitDeletion(fiber, domParent);
291
279
  return
292
280
  }
293
281
 
294
- // Recorre los "fibers" hijos y hermanos
295
282
  commitWork(fiber.child);
296
283
  commitWork(fiber.sibling);
297
284
  };
@@ -320,38 +307,18 @@
320
307
  * @param elements - an array of elements representing the new children to be rendered in the current
321
308
  * fiber's subtree
322
309
  */
323
- const shouldComponentUpdate = (oldProps, newProps) => {
324
- // Comparar las propiedades antiguas y nuevas
325
- return (
326
- !oldProps ||
327
- !newProps ||
328
- Object.keys(oldProps).length !== Object.keys(newProps).length ||
329
- Object.keys(newProps).some((key) => oldProps[key] !== newProps[key])
330
- )
331
- };
332
-
333
310
  const reconcileChildren = (wipFiber, elements) => {
334
311
  let index = 0;
335
312
  let oldFiber = wipFiber.alternate && wipFiber.alternate.child;
336
- let prevSibling = null;
313
+ let prevSibling;
337
314
 
338
- const oldFibersMap = new Map();
339
-
340
- while (oldFiber) {
341
- const oldKey = oldFiber.props.key || oldFiber.type;
342
- oldFibersMap.set(oldKey, oldFiber);
343
- oldFiber = oldFiber.sibling;
344
- }
345
-
346
- while (index < elements.length) {
315
+ while (index < elements.length || oldFiber != null) {
347
316
  const element = elements[index];
348
- const key = element.props.key || element.type;
349
- const oldFiber = oldFibersMap.get(key);
350
317
  let newFiber;
351
318
 
352
319
  const sameType = oldFiber && element && element.type == oldFiber.type;
353
320
 
354
- if (sameType && !shouldComponentUpdate(oldFiber.props, element.props)) {
321
+ if (sameType) {
355
322
  newFiber = {
356
323
  type: oldFiber.type,
357
324
  props: element.props,
@@ -371,10 +338,8 @@
371
338
  effectTag: EFFECT_TAGS.PLACEMENT,
372
339
  };
373
340
  }
374
-
375
341
  if (oldFiber && !sameType) {
376
342
  oldFiber.effectTag = EFFECT_TAGS.DELETION;
377
- wipFiber.effects = wipFiber.effects || [];
378
343
  vars.deletions.push(oldFiber);
379
344
  }
380
345
 
@@ -391,11 +356,6 @@
391
356
  prevSibling = newFiber;
392
357
  index++;
393
358
  }
394
-
395
- oldFibersMap.forEach((oldFiber) => {
396
- oldFiber.effectTag = EFFECT_TAGS.DELETION;
397
- vars.deletions.push(oldFiber);
398
- });
399
359
  };
400
360
 
401
361
  /**
@@ -409,11 +369,15 @@
409
369
  vars.wipFiber = fiber;
410
370
  vars.hookIndex = 0;
411
371
  vars.wipFiber.hooks = [];
372
+ const children = [fiber.type(fiber.props)];
412
373
 
413
- const children = fiber.type(fiber.props);
414
- let childArr = Array.isArray(children) ? children : [children];
374
+ // Aquí detectamos si es Provider para guardar contexto y valor en fiber
375
+ if (fiber.type._contextId && fiber.props.value !== undefined) {
376
+ fiber._contextId = fiber.type._contextId;
377
+ fiber._contextValue = fiber.props.value;
378
+ }
415
379
 
416
- reconcileChildren(fiber, childArr);
380
+ reconcileChildren(fiber, children);
417
381
  };
418
382
 
419
383
  /**
@@ -423,10 +387,14 @@
423
387
  * fibers in the tree.
424
388
  */
425
389
  const updateHostComponent = (fiber) => {
426
- if (!fiber.dom) {
427
- fiber.dom = createDom(fiber);
390
+ if (fiber.type === RYUNIX_TYPES.RYUNIX_FRAGMENT) {
391
+ reconcileChildren(fiber, fiber.props.children.flat());
392
+ } else {
393
+ if (!fiber.dom) {
394
+ fiber.dom = createDom(fiber);
395
+ }
396
+ reconcileChildren(fiber, fiber.props.children.flat());
428
397
  }
429
- reconcileChildren(fiber, fiber.props.children);
430
398
  };
431
399
 
432
400
  /* Internal components*/
@@ -515,7 +483,7 @@
515
483
  requestIdleCallback(workLoop);
516
484
  };
517
485
 
518
- //requestIdleCallback(workLoop)
486
+ requestIdleCallback(workLoop);
519
487
 
520
488
  /**
521
489
  * The function performs a unit of work by updating either a function component or a host component and
@@ -527,7 +495,7 @@
527
495
  * @returns The function `performUnitOfWork` returns the next fiber to be processed. If the current
528
496
  * fiber has a child, it returns the child. Otherwise, it looks for the next sibling of the current
529
497
  * fiber. If there are no more siblings, it goes up the tree to the parent and looks for the next
530
- * sibling of the parent. The function returns `undefined` if there are no more fibers to process.
498
+ * sibling of the parent. The function returns `null` if there are no more fibers to process.
531
499
  */
532
500
  const performUnitOfWork = (fiber) => {
533
501
  const isFunctionComponent = fiber.type instanceof Function;
@@ -604,37 +572,51 @@
604
572
  * @returns The `useStore` function returns an array with two elements: the current state value and a
605
573
  * `setState` function that can be used to update the state.
606
574
  */
607
- const useStore = (initial) => {
575
+ const useStore = (initialState, init) => {
576
+ const reducer = (state, action) =>
577
+ typeof action === 'function' ? action(state) : action;
578
+
579
+ return useReducer(reducer, initialState, init)
580
+ };
581
+
582
+ const useReducer = (reducer, initialState, init) => {
608
583
  const oldHook =
609
584
  vars.wipFiber.alternate &&
610
585
  vars.wipFiber.alternate.hooks &&
611
586
  vars.wipFiber.alternate.hooks[vars.hookIndex];
612
587
 
613
588
  const hook = {
614
- state: oldHook ? oldHook.state : initial,
615
- queue: [],
589
+ state: oldHook ? oldHook.state : init ? init(initialState) : initialState,
590
+ queue: oldHook && Array.isArray(oldHook.queue) ? oldHook.queue.slice() : [],
616
591
  };
617
592
 
618
- const actions = oldHook ? oldHook.queue : [];
619
- actions.forEach((action) => {
620
- hook.state =
621
- typeof action === STRINGS.function ? action(hook.state) : action;
622
- });
593
+ if (oldHook && Array.isArray(oldHook.queue)) {
594
+ oldHook.queue.forEach((action) => {
595
+ hook.state = reducer(hook.state, action);
596
+ });
597
+ }
623
598
 
624
- const setState = (action) => {
599
+ const dispatch = (action) => {
625
600
  hook.queue.push(action);
601
+
626
602
  vars.wipRoot = {
627
603
  dom: vars.currentRoot.dom,
628
604
  props: vars.currentRoot.props,
629
605
  alternate: vars.currentRoot,
630
606
  };
631
- vars.nextUnitOfWork = vars.wipRoot;
632
607
  vars.deletions = [];
608
+ vars.hookIndex = 0;
609
+ scheduleWork(vars.wipRoot);
633
610
  };
634
611
 
635
- vars.wipFiber.hooks.push(hook);
612
+ hook.queue.forEach((action) => {
613
+ hook.state = reducer(hook.state, action);
614
+ });
615
+
616
+ vars.wipFiber.hooks[vars.hookIndex] = hook;
636
617
  vars.hookIndex++;
637
- return [hook.state, setState]
618
+
619
+ return [hook.state, dispatch]
638
620
  };
639
621
 
640
622
  /**
@@ -680,6 +662,15 @@
680
662
  vars.hookIndex++;
681
663
  };
682
664
 
665
+ /**
666
+ * The useRef function in JavaScript is used to create a reference object that persists between renders
667
+ * in a functional component.
668
+ * @param initial - The `initial` parameter in the `useRef` function represents the initial value that
669
+ * will be assigned to the `current` property of the reference object. This initial value will be used
670
+ * if there is no previous value stored in the hook.
671
+ * @returns The `useRef` function is returning the `current` property of the `hook.value` object. This
672
+ * property contains the current value of the reference being managed by the `useRef` hook.
673
+ */
683
674
  const useRef = (initial) => {
684
675
  const oldHook =
685
676
  vars.wipFiber.alternate &&
@@ -697,6 +688,19 @@
697
688
  return hook.value
698
689
  };
699
690
 
691
+ /**
692
+ * The useMemo function in JavaScript is used to memoize the result of a computation based on the
693
+ * dependencies provided.
694
+ * @param comp - The `comp` parameter in the `useMemo` function is a function that represents the
695
+ * computation that needs to be memoized. This function will be executed to calculate the memoized
696
+ * value based on the dependencies provided.
697
+ * @param deps - The `deps` parameter in the `useMemo` function stands for dependencies. It is an array
698
+ * of values that the function depends on. The `useMemo` function will only recompute the memoized
699
+ * value when one of the dependencies has changed.
700
+ * @returns The `useMemo` function returns the `value` property of the `hook` object, which is either
701
+ * the memoized value from the previous render if the dependencies have not changed, or the result of
702
+ * calling the `comp` function if the dependencies have changed.
703
+ */
700
704
  const useMemo = (comp, deps) => {
701
705
  const oldHook =
702
706
  vars.wipFiber.alternate &&
@@ -725,6 +729,16 @@
725
729
  return hook.value
726
730
  };
727
731
 
732
+ /**
733
+ * The useCallback function in JavaScript returns a memoized version of the callback function that only
734
+ * changes if one of the dependencies has changed.
735
+ * @param callback - The `callback` parameter is a function that you want to memoize using
736
+ * `useCallback`. This function will only be re-created if any of the dependencies specified in the
737
+ * `deps` array change.
738
+ * @param deps - Dependencies array that the callback function depends on.
739
+ * @returns The useCallback function is returning a memoized version of the callback function. It is
740
+ * using the useMemo hook to memoize the callback function based on the provided dependencies (deps).
741
+ */
728
742
  const useCallback = (callback, deps) => {
729
743
  return useMemo(() => callback, deps)
730
744
  };
@@ -743,6 +757,37 @@
743
757
  return query
744
758
  };
745
759
 
760
+ const createContext = (defaultValue) => {
761
+ const contextId = RYUNIX_TYPES.RYUNIX_CONTEXT;
762
+
763
+ const Provider = ({ value, children }) => {
764
+ return Fragment({
765
+ children: children,
766
+ })
767
+ };
768
+
769
+ Provider._contextId = contextId;
770
+
771
+ const useContext = () => {
772
+ let fiber = vars.wipFiber;
773
+ while (fiber) {
774
+ if (fiber.type && fiber.type._contextId === contextId) {
775
+ if (fiber.props && 'value' in fiber.props) {
776
+ return fiber.props.value
777
+ }
778
+ return undefined
779
+ }
780
+ fiber = fiber.parent;
781
+ }
782
+ return defaultValue
783
+ };
784
+
785
+ return {
786
+ Provider,
787
+ useContext,
788
+ }
789
+ };
790
+
746
791
  /**
747
792
  * `useRouter` is a routing function to manage navigation, nested routes, and route pre-loading.
748
793
  *
@@ -798,115 +843,247 @@
798
843
  * </>
799
844
  * );
800
845
  */
801
- const useRouter = (routes) => {
802
- const [location, setLocation] = useStore(window.location.pathname);
846
+ // const useRouter = (routes) => {
847
+ // const [location, setLocation] = useStore(window.location.pathname)
848
+
849
+ // const findRoute = (routes, path) => {
850
+ // const pathname = path.split('?')[0]
851
+
852
+ // const notFoundRoute = routes.find((route) => route.NotFound)
853
+ // const notFound = notFoundRoute
854
+ // ? { route: { component: notFoundRoute.NotFound }, params: {} }
855
+ // : { route: { component: null }, params: {} }
856
+
857
+ // for (const route of routes) {
858
+ // if (route.subRoutes) {
859
+ // const childRoute = findRoute(route.subRoutes, path)
860
+ // if (childRoute) return childRoute
861
+ // }
862
+
863
+ // if (route.path === '*') {
864
+ // return notFound
865
+ // }
866
+
867
+ // if (!route.path || typeof route.path !== 'string') {
868
+ // console.warn('Invalid route detected:', route)
869
+ // console.info(
870
+ // "if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }",
871
+ // )
872
+ // continue
873
+ // }
874
+
875
+ // const keys = []
876
+ // const pattern = new RegExp(
877
+ // `^${route.path.replace(/:\w+/g, (match) => {
878
+ // keys.push(match.substring(1))
879
+ // return '([^/]+)'
880
+ // })}$`,
881
+ // )
882
+
883
+ // const match = pathname.match(pattern)
884
+ // if (match) {
885
+ // const params = keys.reduce((acc, key, index) => {
886
+ // acc[key] = match[index + 1]
887
+ // return acc
888
+ // }, {})
889
+
890
+ // return { route, params }
891
+ // }
892
+ // }
893
+
894
+ // return notFound
895
+ // }
896
+
897
+ // const navigate = (path) => {
898
+ // window.history.pushState({}, '', path)
899
+
900
+ // updateRoute(path)
901
+ // }
902
+
903
+ // const updateRoute = (path) => {
904
+ // const cleanedPath = path.split('?')[0]
905
+ // setLocation(cleanedPath)
906
+ // }
907
+
908
+ // useEffect(() => {
909
+ // const onPopState = () => updateRoute(window.location.pathname)
910
+ // window.addEventListener('popstate', onPopState)
911
+
912
+ // return () => window.removeEventListener('popstate', onPopState)
913
+ // }, [])
914
+
915
+ // const currentRouteData = findRoute(routes, location) || {}
916
+
917
+ // const Children = () => {
918
+ // const query = useQuery()
919
+ // const { route } = currentRouteData
920
+
921
+ // if (
922
+ // !route ||
923
+ // !route.component ||
924
+ // typeof route.component !== STRINGS.function
925
+ // ) {
926
+ // console.error(
927
+ // 'Component not found for current path or the component is not a valid function:',
928
+ // currentRouteData,
929
+ // )
930
+ // return null
931
+ // }
932
+
933
+ // const WrappedComponent = () =>
934
+ // createElement(route.component, {
935
+ // key: location,
936
+ // params: currentRouteData.params || {},
937
+ // query,
938
+ // })
939
+
940
+ // return createElement(WrappedComponent)
941
+ // }
942
+
943
+ // const NavLink = ({ to, ...props }) => {
944
+ // const handleClick = (e) => {
945
+ // e.preventDefault()
946
+ // navigate(to)
947
+ // }
948
+ // return createElement(
949
+ // 'a',
950
+ // { href: to, onClick: handleClick, ...props },
951
+ // props.children,
952
+ // )
953
+ // }
954
+
955
+ // return { Children, NavLink, navigate }
956
+ // }
957
+
958
+ // Crear contexto para Router
959
+ const RouterContext = createContext({
960
+ location: '/',
961
+ params: {},
962
+ query: {},
963
+ navigate: (path) => {},
964
+ route: null,
965
+ });
803
966
 
804
- const findRoute = (routes, path) => {
805
- const pathname = path.split('?')[0];
967
+ const findRoute = (routes, path) => {
968
+ const pathname = path.split('?')[0];
806
969
 
807
- const notFoundRoute = routes.find((route) => route.NotFound);
808
- const notFound = notFoundRoute
809
- ? { route: { component: notFoundRoute.NotFound }, params: {} }
810
- : { route: { component: null }, params: {} };
970
+ const notFoundRoute = routes.find((route) => route.NotFound);
971
+ const notFound = notFoundRoute
972
+ ? { route: { component: notFoundRoute.NotFound }, params: {} }
973
+ : { route: { component: null }, params: {} };
811
974
 
812
- for (const route of routes) {
813
- if (route.subRoutes) {
814
- const childRoute = findRoute(route.subRoutes, path);
815
- if (childRoute) return childRoute
816
- }
817
-
818
- if (route.path === '*') {
819
- return notFound
820
- }
975
+ for (const route of routes) {
976
+ if (route.subRoutes) {
977
+ const childRoute = findRoute(route.subRoutes, path);
978
+ if (childRoute) return childRoute
979
+ }
821
980
 
822
- if (!route.path || typeof route.path !== 'string') {
823
- console.warn('Invalid route detected:', route);
824
- console.info(
825
- "if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }",
826
- );
827
- continue
828
- }
981
+ if (route.path === '*') {
982
+ return notFound
983
+ }
829
984
 
830
- const keys = [];
831
- const pattern = new RegExp(
832
- `^${route.path.replace(/:\w+/g, (match) => {
833
- keys.push(match.substring(1));
834
- return '([^/]+)'
835
- })}$`,
985
+ if (!route.path || typeof route.path !== 'string') {
986
+ console.warn('Invalid route detected:', route);
987
+ console.info(
988
+ "if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }",
836
989
  );
990
+ continue
991
+ }
837
992
 
838
- const match = pathname.match(pattern);
839
- if (match) {
840
- const params = keys.reduce((acc, key, index) => {
841
- acc[key] = match[index + 1];
842
- return acc
843
- }, {});
844
-
845
- return { route, params }
846
- }
993
+ const keys = [];
994
+ const pattern = new RegExp(
995
+ `^${route.path.replace(/:\w+/g, (match) => {
996
+ keys.push(match.substring(1));
997
+ return '([^/]+)'
998
+ })}$`,
999
+ );
1000
+
1001
+ const match = pathname.match(pattern);
1002
+ if (match) {
1003
+ const params = keys.reduce((acc, key, index) => {
1004
+ acc[key] = match[index + 1];
1005
+ return acc
1006
+ }, {});
1007
+
1008
+ return { route, params }
847
1009
  }
1010
+ }
848
1011
 
849
- return notFound
850
- };
1012
+ return notFound
1013
+ };
1014
+
1015
+ const RouterProvider = ({ routes, children }) => {
1016
+ const [location, setLocation] = useStore(window.location.pathname);
1017
+
1018
+ useEffect(() => {
1019
+ const onPopState = () => setLocation(window.location.pathname);
1020
+ window.addEventListener('popstate', onPopState);
1021
+ return () => window.removeEventListener('popstate', onPopState)
1022
+ }, []);
851
1023
 
852
1024
  const navigate = (path) => {
853
1025
  window.history.pushState({}, '', path);
854
- updateRoute(path);
1026
+ setLocation(path);
855
1027
  };
856
1028
 
857
- const updateRoute = (path) => {
858
- const cleanedPath = path.split('?')[0];
859
- setLocation(cleanedPath);
1029
+ const currentRouteData = findRoute(routes, location) || {};
1030
+ const query = useQuery();
1031
+
1032
+ const contextValue = {
1033
+ location,
1034
+ params: currentRouteData.params || {},
1035
+ query,
1036
+ navigate,
1037
+ route: currentRouteData.route,
860
1038
  };
861
1039
 
862
- useEffect(() => {
863
- const onPopState = () => updateRoute(window.location.pathname);
864
- window.addEventListener('popstate', onPopState);
1040
+ return createElement(
1041
+ RouterContext.Provider,
1042
+ { value: contextValue },
1043
+ Fragment({
1044
+ children: children,
1045
+ }),
1046
+ )
1047
+ };
865
1048
 
866
- return () => window.removeEventListener('popstate', onPopState)
867
- }, []);
1049
+ const useRouter = () => {
1050
+ return RouterContext.useContext()
1051
+ };
868
1052
 
869
- const currentRouteData = findRoute(routes, location) || {};
1053
+ const Children = () => {
1054
+ const { route, params, query, location } = useRouter();
870
1055
 
871
- const Children = () => {
872
- const query = useQuery();
873
- const { route } = currentRouteData;
874
-
875
- if (
876
- !route ||
877
- !route.component ||
878
- typeof route.component !== STRINGS.function
879
- ) {
880
- console.error(
881
- 'Component not found for current path or the component is not a valid function:',
882
- currentRouteData,
883
- );
884
- return null
885
- }
1056
+ if (!route || !route.component) return null
886
1057
 
887
- return route.component({
888
- params: currentRouteData.params || {},
889
- query,
890
- })
891
- };
1058
+ return createElement(
1059
+ RYUNIX_TYPES.RYUNIX_FRAGMENT,
1060
+ {},
1061
+ createElement(route.component, { key: location, params, query }),
1062
+ )
1063
+ };
892
1064
 
893
- const NavLink = ({ to, ...props }) => {
894
- const handleClick = (e) => {
895
- e.preventDefault();
896
- navigate(to);
897
- };
898
- return createElement(
899
- 'a',
900
- { href: to, onClick: handleClick, ...props },
901
- props.children,
902
- )
1065
+ // Componente NavLink para navegación interna
1066
+ const NavLink = ({ to, ...props }) => {
1067
+ const { navigate } = useRouter();
1068
+
1069
+ const handleClick = (e) => {
1070
+ e.preventDefault();
1071
+ navigate(to);
903
1072
  };
904
1073
 
905
- return { Children, NavLink, navigate }
1074
+ return createElement(
1075
+ 'a',
1076
+ { href: to, onClick: handleClick, ...props },
1077
+ props.children,
1078
+ )
906
1079
  };
907
1080
 
908
1081
  var Hooks = /*#__PURE__*/Object.freeze({
909
1082
  __proto__: null,
1083
+ Children: Children,
1084
+ NavLink: NavLink,
1085
+ RouterProvider: RouterProvider,
1086
+ createContext: createContext,
910
1087
  useCallback: useCallback,
911
1088
  useEffect: useEffect,
912
1089
  useMemo: useMemo,
@@ -926,7 +1103,11 @@
926
1103
 
927
1104
  window.Ryunix = Ryunix;
928
1105
 
1106
+ exports.Children = Children;
929
1107
  exports.Image = Image;
1108
+ exports.NavLink = NavLink;
1109
+ exports.RouterProvider = RouterProvider;
1110
+ exports.createContext = createContext;
930
1111
  exports.default = Ryunix;
931
1112
  exports.useCallback = useCallback;
932
1113
  exports.useEffect = useEffect;
@@ -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")}),s=Object.freeze({object:"object",function:"function",style:"ryunix-style",className:"ryunix-class",children:"children",boolean:"boolean",string:"string"}),i=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()}),a=e=>`${e}-${Math.random().toString(36).substring(2,9)}`,c=(e,t,...o)=>{const n=t&&t.key?a(t.key):a(r.Ryunix_ELEMENT.toString());return{type:e,props:{...t,key:n,children:o.flat().map((e=>typeof e===s.object?e:u(e)))}}},u=e=>({type:r.TEXT_ELEMENT,props:{nodeValue:e,children:[]}}),p=e=>e.startsWith("on"),f=e=>e!==s.children&&!p(e),d=(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)||d(t,o)(e))).forEach((o=>{const n=o.toLowerCase().substring(2);e.removeEventListener(n,t[o])})),Object.keys(t).filter(f).filter(h(o)).forEach((t=>{e[t]=""})),Object.keys(o).filter(f).filter(d(t,o)).forEach((n=>{if(n===s.style)w(e,o["ryunix-style"]);else if(n===i.style)w(e,o.style);else if(n===s.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===i.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(d(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&&null!=e.dom)y(e),E(e.dom,e.alternate.props,e.props),m(e);else if(e.effectTag===l.DELETION)return k(e,o),void y(e);b(e.child),b(e.sibling)},k=(e,t)=>{e.dom?t.removeChild(e.dom):k(e.child,t)},R=(e,t)=>!e||!t||Object.keys(e).length!==Object.keys(t).length||Object.keys(t).some((o=>e[o]!==t[o])),g=(e,t)=>{let n=0,r=e.alternate&&e.alternate.child,s=null;const i=new Map;for(;r;){const e=r.props.key||r.type;i.set(e,r),r=r.sibling}for(;n<t.length;){const r=t[n],a=r.props.key||r.type,c=i.get(a);let u;const p=c&&r&&r.type==c.type;p&&!R(c.props,r.props)&&(u={type:c.type,props:r.props,dom:c.dom,parent:e,alternate:c,effectTag:l.UPDATE}),r&&!p&&(u={type:r.type,props:r.props,dom:null,parent:e,alternate:null,effectTag:l.PLACEMENT}),c&&!p&&(c.effectTag=l.DELETION,e.effects=e.effects||[],o.deletions.push(c)),c&&(c=c.sibling),0===n?e.child=u:r&&(s.sibling=u),s=u,n++}i.forEach((e=>{e.effectTag=l.DELETION,o.deletions.push(e)}))},x=e=>{e.dom||(e.dom=(e=>{const t=e.type==r.TEXT_ELEMENT?document.createTextNode(""):document.createElement(e.type);return E(t,{},e.props),t})(e)),g(e,e.props.children)},N=e=>{let t=!1;for(;o.nextUnitOfWork&&!t;)o.nextUnitOfWork=F(o.nextUnitOfWork),t=e.timeRemaining()<1;!o.nextUnitOfWork&&o.wipRoot&&(o.deletions.forEach(b),o.wipRoot&&o.wipRoot.child&&(b(o.wipRoot.child),o.currentRoot=o.wipRoot),o.effects.forEach((e=>{try{e()}catch(e){console.error("Error in effect:",e)}})),o.effects=[],o.wipRoot=null),requestIdleCallback(N)},F=e=>{if(e.type instanceof Function?(e=>{o.wipFiber=e,o.hookIndex=0,o.wipFiber.hooks=[];const t=e.type(e.props);let n=Array.isArray(t)?t:[t];g(e,n)})(e):x(e),e.child)return e.child;let t=e;for(;t;){if(t.sibling)return t.sibling;t=t.parent}},T=(e,t)=>{var n;return o.wipRoot={dom:t,props:{children:[e]},alternate:o.currentRoot},o.nextUnitOfWork=o.wipRoot,o.deletions=[],n=o.wipRoot,o.nextUnitOfWork=n,o.wipRoot=n,o.deletions=[],o.hookIndex=0,o.effects=[],requestIdleCallback(N),o.wipRoot},I=e=>{const t=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],n={state:t?t.state:e,queue:[]};(t?t.queue:[]).forEach((e=>{n.state=typeof e===s.function?e(n.state):e}));return o.wipFiber.hooks.push(n),o.hookIndex++,[n.state,e=>{n.queue.push(e),o.wipRoot={dom:o.currentRoot.dom,props:o.currentRoot.props,alternate:o.currentRoot},o.nextUnitOfWork=o.wipRoot,o.deletions=[]}]},O=(e,n)=>{const s=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],i={type:r.RYUNIX_EFFECT,deps:n,cleanup:s?.cleanup};(!s||!t.isEqual(s.deps,n))&&o.effects.push((()=>{"function"==typeof i.cleanup&&i.cleanup();const t=e();"function"==typeof t&&(i.cleanup=t)})),o.wipFiber.hooks[o.hookIndex]=i,o.hookIndex++},L=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 s=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],i={type:r.RYUNIX_MEMO,value:null,deps:n};return s&&t.isEqual(s.deps,i.deps)?i.value=s.value:i.value=e(),o.wipFiber.hooks[o.hookIndex]=i,o.hookIndex++,i.value},v=(e,t)=>U((()=>e),t),_=()=>{const e=new URLSearchParams(window.location.search),t={};for(let[o,n]of e.entries())t[o]=n;return t},S=e=>{const[t,o]=I(window.location.pathname),n=(e,t)=>{const o=t.split("?")[0],r=e.find((e=>e.NotFound)),s=r?{route:{component:r.NotFound},params:{}}:{route:{component:null},params:{}};for(const r of e){if(r.subRoutes){const e=n(r.subRoutes,t);if(e)return e}if("*"===r.path)return s;if(!r.path||"string"!=typeof r.path){console.warn("Invalid route detected:",r),console.info("if you are using { NotFound: NotFound } please add { path: '*', NotFound: NotFound }");continue}const e=[],i=new RegExp(`^${r.path.replace(/:\w+/g,(t=>(e.push(t.substring(1)),"([^/]+)")))}$`),l=o.match(i);if(l){return{route:r,params:e.reduce(((e,t,o)=>(e[t]=l[o+1],e)),{})}}}return s},r=e=>{window.history.pushState({},"",e),i(e)},i=e=>{const t=e.split("?")[0];o(t)};O((()=>{const e=()=>i(window.location.pathname);return window.addEventListener("popstate",e),()=>window.removeEventListener("popstate",e)}),[]);const l=n(e,t)||{};return{Children:()=>{const e=_(),{route:t}=l;return t&&t.component&&typeof t.component===s.function?t.component({params:l.params||{},query:e}):(console.error("Component not found for current path or the component is not a valid function:",l),null)},NavLink:({to:e,...t})=>c("a",{href:e,onClick:t=>{t.preventDefault(),r(e)},...t},t.children),navigate:r}};var C={createElement:c,render:T,init:(e,t="__ryunix")=>{o.containerRoot=document.getElementById(t);return T(e,o.containerRoot)},Fragment:e=>e.children,Hooks:Object.freeze({__proto__:null,useCallback:v,useEffect:O,useMemo:U,useQuery:_,useRef:L,useRouter:S,useStore:I})};window.Ryunix=C,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}`:"",s="http://localhost:3000"===window.location.origin||"http://localhost:5173"===window.location.origin||"http://localhost:4173"===window.location.origin;return n?s?(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 c("img",{src:o,props:t},null)},e.default=C,e.useCallback=v,e.useEffect=O,e.useMemo=U,e.useQuery=_,e.useRef=L,e.useRouter=S,e.useStore=I,Object.defineProperty(e,"__esModule",{value:!0})}));
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=>a(r.RYUNIX_FRAGMENT,{},...e.children),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)=>{e.dom?t.removeChild(e.dom):x(e.child,t)},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=>{e.type===r.RYUNIX_FRAGMENT||e.dom||(e.dom=(e=>{const t=e.type==r.TEXT_ELEMENT?document.createTextNode(""):document.createElement(e.type);return E(t,{},e.props),t})(e)),R(e,e.props.children.flat())},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},M=({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}))},Y=()=>X.useContext(),j=()=>{const{route:e,params:t,query:o,location:n}=Y();return e&&e.component?a(r.RYUNIX_FRAGMENT,{},a(e.component,{key:n,params:t,query:o})):null},A=({to:e,...t})=>{const{navigate:o}=Y();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:j,NavLink:A,RouterProvider:M,createContext:L,useCallback:C,useEffect:_,useMemo:U,useQuery:O,useRef:S,useRouter:Y,useStore:T})};window.Ryunix=P,e.Children=j,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=A,e.RouterProvider=M,e.createContext=L,e.default=P,e.useCallback=C,e.useEffect=_,e.useMemo=U,e.useQuery=O,e.useRef=S,e.useRouter=Y,e.useStore=T,Object.defineProperty(e,"__esModule",{value:!0})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unsetsoft/ryunixjs",
3
- "version": "1.1.7-canary.8",
3
+ "version": "1.1.7-canary.80",
4
4
  "license": "MIT",
5
5
  "main": "./dist/Ryunix.min.js",
6
6
  "types": "./dist/Ryunix.d.ts",