@unsetsoft/ryunixjs 1.1.19 → 1.1.20-canary.2

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
@@ -111,6 +111,11 @@
111
111
  const isProperty = (key) => key !== STRINGS.children && !isEvent(key);
112
112
  const isNew = (prev, next) => (key) => prev[key] !== next[key];
113
113
  const isGone = (next) => (key) => !(key in next);
114
+ const hasDepsChanged = (prevDeps, nextDeps) =>
115
+ !prevDeps ||
116
+ !nextDeps ||
117
+ prevDeps.length !== nextDeps.length ||
118
+ prevDeps.some((dep, index) => dep !== nextDeps[index]);
114
119
 
115
120
  /**
116
121
  * The function cancels all effect hooks in a given fiber.
@@ -120,15 +125,46 @@
120
125
  * "cancelEffects" is likely intended
121
126
  */
122
127
  const cancelEffects = (fiber) => {
123
- if (fiber.hooks) {
128
+ if (fiber.hooks && fiber.hooks.length > 0) {
124
129
  fiber.hooks
125
- .filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.cancel)
130
+ .filter((hook) => hook.type === RYUNIX_TYPES.RYUNIX_EFFECT && hook.cancel)
126
131
  .forEach((effectHook) => {
127
132
  effectHook.cancel();
128
133
  });
129
134
  }
130
135
  };
131
136
 
137
+ /**
138
+ * The function `cancelEffectsDeep` recursively cancels effects in a fiber tree by running cleanup
139
+ * functions for each effect hook.
140
+ * @param fiber - The `fiber` parameter in the `cancelEffectsDeep` function seems to be an object
141
+ * representing a fiber node in a data structure. The function recursively traverses the fiber tree to
142
+ * find hooks with effects and cancels them by calling their `cancel` function if it exists. It also
143
+ * logs a message
144
+ * @returns The `cancelEffectsDeep` function does not explicitly return a value. It is a recursive
145
+ * function that traverses a fiber tree structure and cancels effects for hooks that have a `cancel`
146
+ * function defined. The function performs cleanup operations by calling the `cancel` function for each
147
+ * applicable hook.
148
+ */
149
+ const cancelEffectsDeep = (fiber) => {
150
+ if (!fiber) return
151
+
152
+ if (fiber.hooks && fiber.hooks.length > 0) {
153
+ fiber.hooks
154
+ .filter(
155
+ (hook) =>
156
+ hook.type === RYUNIX_TYPES.RYUNIX_EFFECT &&
157
+ typeof hook.cancel === STRINGS.function,
158
+ )
159
+ .forEach((hook) => {
160
+ hook.cancel();
161
+ });
162
+ }
163
+
164
+ if (fiber.child) cancelEffectsDeep(fiber.child);
165
+ if (fiber.sibling) cancelEffectsDeep(fiber.sibling);
166
+ };
167
+
132
168
  /**
133
169
  * The function runs all effect hooks in a given fiber.
134
170
  * @param fiber - The "fiber" parameter is likely referring to a data structure used in the
@@ -137,12 +173,27 @@
137
173
  * contains information about a component and its children, as
138
174
  */
139
175
  const runEffects = (fiber) => {
140
- if (fiber.hooks) {
141
- fiber.hooks
142
- .filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.effect)
143
- .forEach((effectHook) => {
144
- effectHook.cancel = effectHook.effect();
145
- });
176
+ if (!fiber.hooks || fiber.hooks.length === 0) return
177
+
178
+ for (let i = 0; i < fiber.hooks.length; i++) {
179
+ const hook = fiber.hooks[i];
180
+ if (
181
+ hook.type === RYUNIX_TYPES.RYUNIX_EFFECT &&
182
+ typeof hook.effect === STRINGS.function &&
183
+ hook.effect !== null
184
+ ) {
185
+ if (typeof hook.cancel === STRINGS.function) {
186
+ hook.cancel();
187
+ }
188
+
189
+ const cleanup = hook.effect();
190
+
191
+ if (typeof cleanup === 'function') {
192
+ hook.cancel = cleanup;
193
+ } else {
194
+ hook.cancel = undefined;
195
+ }
196
+ }
146
197
  }
147
198
  };
148
199
 
@@ -287,7 +338,7 @@
287
338
  }
288
339
  runEffects(fiber);
289
340
  } else if (fiber.effectTag === EFFECT_TAGS.DELETION) {
290
- cancelEffects(fiber);
341
+ cancelEffectsDeep(fiber);
291
342
  commitDeletion(fiber, domParent);
292
343
  return
293
344
  }
@@ -343,6 +394,7 @@
343
394
  parent: wipFiber,
344
395
  alternate: oldFiber,
345
396
  effectTag: EFFECT_TAGS.UPDATE,
397
+ hooks: oldFiber.hooks,
346
398
  };
347
399
  }
348
400
  if (element && !sameType) {
@@ -601,6 +653,22 @@
601
653
  return useReducer(reducer, initialState, init)
602
654
  };
603
655
 
656
+ /**
657
+ * The `useReducer` function in JavaScript is used to manage state updates based on actions dispatched
658
+ * to a reducer function.
659
+ * @param reducer - The `reducer` parameter in the `useReducer` function is a function that takes the
660
+ * current state and an action as arguments, and returns the new state based on the action. It is used
661
+ * to update the state in response to different actions dispatched by the `dispatch` function.
662
+ * @param initialState - The `initialState` parameter in the `useReducer` function represents the
663
+ * initial state of the reducer. It is the state that will be used when the reducer is first
664
+ * initialized or reset. This initial state can be any value or object that the reducer will operate on
665
+ * and update based on the dispatched actions
666
+ * @param init - The `init` parameter in the `useReducer` function is an optional function that can be
667
+ * used to initialize the state. If provided, it will be called with the `initialState` as its argument
668
+ * and the return value will be used as the initial state value. If `init` is not
669
+ * @returns The `useReducer` function is returning an array with two elements: the current state and a
670
+ * dispatch function.
671
+ */
604
672
  const useReducer = (reducer, initialState, init) => {
605
673
  const oldHook =
606
674
  vars.wipFiber.alternate &&
@@ -608,6 +676,8 @@
608
676
  vars.wipFiber.alternate.hooks[vars.hookIndex];
609
677
 
610
678
  const hook = {
679
+ hookID: vars.hookIndex,
680
+ type: RYUNIX_TYPES.RYUNIX_STORE,
611
681
  state: oldHook ? oldHook.state : init ? init(initialState) : initialState,
612
682
  queue: oldHook && Array.isArray(oldHook.queue) ? oldHook.queue.slice() : [],
613
683
  };
@@ -659,29 +729,16 @@
659
729
  vars.wipFiber.alternate.hooks &&
660
730
  vars.wipFiber.alternate.hooks[vars.hookIndex];
661
731
 
732
+ const hasChanged = hasDepsChanged(oldHook?.deps, deps);
733
+
662
734
  const hook = {
735
+ hookID: vars.hookIndex,
663
736
  type: RYUNIX_TYPES.RYUNIX_EFFECT,
664
737
  deps,
665
- cleanup: oldHook?.cleanup,
738
+ effect: hasChanged ? callback : null,
739
+ cancel: oldHook?.cancel,
666
740
  };
667
741
 
668
- const hasChanged = !oldHook || !lodash.isEqual(oldHook.deps, deps);
669
-
670
- if (hasChanged) {
671
- vars.effects.push(() => {
672
- // Llama al cleanup anterior si existe
673
- if (typeof hook.cleanup === 'function') {
674
- hook.cleanup();
675
- }
676
-
677
- // Ejecuta el nuevo efecto y guarda el nuevo cleanup
678
- const result = callback();
679
- if (typeof result === 'function') {
680
- hook.cleanup = result;
681
- }
682
- });
683
- }
684
-
685
742
  vars.wipFiber.hooks[vars.hookIndex] = hook;
686
743
  vars.hookIndex++;
687
744
  };
@@ -825,6 +882,7 @@
825
882
  params: {},
826
883
  query: {},
827
884
  navigate: (path) => {},
885
+ replace: (path) => {},
828
886
  route: null,
829
887
  });
830
888
 
@@ -869,6 +927,11 @@
869
927
  return acc
870
928
  }, {});
871
929
 
930
+ // TODO: ADDED REDIRECT
931
+ if (route?.redirectTo) {
932
+ return { redirect: route.redirectTo }
933
+ }
934
+
872
935
  return { route, params }
873
936
  }
874
937
  }
@@ -892,10 +955,22 @@
892
955
 
893
956
  const navigate = (path) => {
894
957
  window.history.pushState({}, '', path);
895
- setLocation(window.location.pathname);
958
+ setLocation(path);
896
959
  };
897
960
 
898
- const currentRouteData = findRoute(routes, window.location.pathname) || {};
961
+ // TODO: ADDED REPLACE
962
+ const replace = (path) => {
963
+ window.history.replaceState({}, '', path);
964
+ setLocation(path);
965
+ };
966
+
967
+ const currentRouteData = findRoute(routes, location) || {};
968
+
969
+ // TODO: ADDED PROCESS THE REDIRECT WITH REPLACE
970
+ if (currentRouteData?.redirect) {
971
+ replace(routeData.redirect);
972
+ return null
973
+ }
899
974
  const query = useQuery();
900
975
 
901
976
  const contextValue = {
@@ -903,6 +978,7 @@
903
978
  params: currentRouteData.params || {},
904
979
  query,
905
980
  navigate,
981
+ replace, // TODO: IMPLEMENTED REPLACE INSIDE CONTEXT NAVIGATION
906
982
  route: currentRouteData.route,
907
983
  };
908
984
 
@@ -941,21 +1017,48 @@
941
1017
  };
942
1018
 
943
1019
  // Componente NavLink para navegación interna
944
- const NavLink = ({ to, ...props }) => {
945
- const { navigate } = useRouter();
1020
+ const NavLink = ({ to, exact = false, ...props }) => {
1021
+ const { location, navigate } = useRouter();
1022
+
1023
+ const isActive = exact ? location === to : location.startsWith(to);
1024
+
1025
+ const resolveClass = (cls) =>
1026
+ typeof cls === 'function' ? cls({ isActive }) : cls || '';
946
1027
 
947
1028
  const handleClick = (e) => {
948
1029
  e.preventDefault();
949
1030
  navigate(to);
950
1031
  };
951
1032
 
1033
+ console.log(props);
1034
+
1035
+ const classAttrName = props['ryunix-class'] ? 'ryunix-class' : 'className';
1036
+
1037
+ const classAttrValue = resolveClass(props['ryunix-class'] || className);
1038
+
952
1039
  return createElement(
953
1040
  'a',
954
- { href: to, onClick: handleClick, ...props },
1041
+ {
1042
+ href: to,
1043
+ onClick: handleClick,
1044
+ [classAttrName]: classAttrValue,
1045
+ ...props,
1046
+ },
955
1047
  props.children,
956
1048
  )
957
1049
  };
958
1050
 
1051
+ // TODO: ADDED IS-ACTIVE FOR NavLink
1052
+ const useIsActive = (exact = false) => {
1053
+ const { location } = useRouter();
1054
+ return exact
1055
+ ? location === window.location.pathname
1056
+ : location.startsWith(window.location.pathname)
1057
+ };
1058
+
1059
+ useIsActive('/home');
1060
+ useIsActive('/test');
1061
+
959
1062
  var Hooks = /*#__PURE__*/Object.freeze({
960
1063
  __proto__: null,
961
1064
  Children: Children,
@@ -965,6 +1068,7 @@
965
1068
  useCallback: useCallback,
966
1069
  useEffect: useEffect,
967
1070
  useHash: useHash,
1071
+ useIsActive: useIsActive,
968
1072
  useMemo: useMemo,
969
1073
  useQuery: useQuery,
970
1074
  useRef: useRef,
@@ -991,6 +1095,7 @@
991
1095
  exports.useCallback = useCallback;
992
1096
  exports.useEffect = useEffect;
993
1097
  exports.useHash = useHash;
1098
+ exports.useIsActive = useIsActive;
994
1099
  exports.useMemo = useMemo;
995
1100
  exports.useQuery = useQuery;
996
1101
  exports.useRef = useRef;
@@ -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").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"}),a=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()}),l=(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 l(r.RYUNIX_FRAGMENT,{},...t)},p=e=>e.startsWith("on"),d=e=>e!==i.children&&!p(e),h=(e,t)=>o=>e[o]!==t[o],f=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()}))},w=(e,t,o)=>{Object.keys(t).filter(p).filter((e=>f(o)(e)||h(t,o)(e))).forEach((o=>{const n=o.toLowerCase().substring(2);e.removeEventListener(n,t[o])})),Object.keys(t).filter(d).filter(f(o)).forEach((t=>{e[t]=""})),Object.keys(o).filter(d).filter(h(t,o)).forEach((n=>{if(n===i.style)E(e,o["ryunix-style"]);else if(n===s.style)E(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+/).filter(Boolean)||[]),e.classList.add(...o["ryunix-class"].split(/\s+/).filter(Boolean))}else if(n===s.className){if(""===o.className)throw new Error("className cannot be empty.");t.className&&e.classList.remove(...t.className.split(/\s+/).filter(Boolean)||[]),e.classList.add(...o.className.split(/\s+/).filter(Boolean))}else e[n]=o[n]})),Object.keys(o).filter(p).filter(h(t,o)).forEach((t=>{const n=t.toLowerCase().substring(2);e.addEventListener(n,o[t])}))},E=(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===a.PLACEMENT)null!=e.dom&&o.appendChild(e.dom),m(e);else if(e.effectTag===a.UPDATE)y(e),null!=e.dom&&w(e.dom,e.alternate.props,e.props),m(e);else if(e.effectTag===a.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}},g=(e,t)=>{let n,r=0,i=e.alternate&&e.alternate.child;for(;r<t.length||null!=i;){const s=t[r];let l;const c=i&&s&&s.type==i.type;c&&(l={type:i.type,props:s.props,dom:i.dom,parent:e,alternate:i,effectTag:a.UPDATE}),s&&!c&&(l={type:s.type,props:s.props,dom:null,parent:e,alternate:null,effectTag:a.PLACEMENT}),i&&!c&&(i.effectTag=a.DELETION,o.deletions.push(i)),i&&(i=i.sibling),0===r?e.child=l:s&&(n.sibling=l),n=l,r++}},R=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 w(t,{},e.props),t})(e)),g(e,t)},k=({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("height",t.height),t.quality&&o.set("quality",t.quality);const r=t.extension?`@${t.extension}`:"";return n?(()=>{const{hostname:e}=window.location;return"localhost"===e||"127.0.0.1"===e})()?(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()}`},N=e=>{let t=!1;for(;o.nextUnitOfWork&&!t;)o.nextUnitOfWork=I(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(N)};requestIdleCallback(N);const I=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),g(e,t)})(e):R(e),e.child)return e.child;let t=e;for(;t;){if(t.sibling)return t.sibling;t=t.parent}},v=e=>{o.nextUnitOfWork=e,o.wipRoot=e,o.deletions=[],o.hookIndex=0,o.effects=[],requestIdleCallback(N)},F=(e,t)=>(o.wipRoot={dom:t,props:{children:[e]},alternate:o.currentRoot},o.nextUnitOfWork=o.wipRoot,o.deletions=[],v(o.wipRoot),o.wipRoot),T=(e,t)=>_(((e,t)=>"function"==typeof t?t(e):t),e,t),_=(e,t,n)=>{const r=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],s={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=>{s.state=e(s.state,t)}));return s.queue.forEach((t=>{s.state=e(s.state,t)})),o.wipFiber.hooks[o.hookIndex]=s,o.hookIndex++,[s.state,e=>{s.queue.push(typeof e===i.function?e:t=>e),o.wipRoot={dom:o.currentRoot.dom,props:o.currentRoot.props,alternate:o.currentRoot},o.deletions=[],o.hookIndex=0,v(o.wipRoot)}]},S=(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++},U=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},L=(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)=>L((()=>e),t),O=(e=r.RYUNIX_CONTEXT,t={})=>{const n=({children:e})=>u({children:e});n._contextId=e;return{Provider:n,useContext:(e=r.RYUNIX_CONTEXT)=>{let n=o.wipFiber;for(;n;){if(n.type&&n.type._contextId===e)return n.props&&"value"in n.props?n.props.value:void 0;n=n.parent}return t}}},X=()=>{const e=new URLSearchParams(window.location.search),t={};for(let[o,n]of e.entries())t[o]=n;return t},q=()=>{const[e,t]=T(window.location.hash);return S((()=>{const e=()=>{t(window.location.hash)};return window.addEventListener("hashchange",e),()=>window.removeEventListener("hashchange",e)}),[]),e},A=O("ryunix.navigation",{location:"/",params:{},query:{},navigate:e=>{},route:null}),Y=(e,t)=>{const o=t.split("?")[0].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=Y(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);S((()=>{const e=()=>n(window.location.pathname);return window.addEventListener("popstate",e),window.addEventListener("hashchange",e),()=>{window.removeEventListener("popstate",e),window.removeEventListener("hashchange",e)}}),[]);const r=Y(e,window.location.pathname)||{},i=X(),s={location:o,params:r.params||{},query:i,navigate:e=>{window.history.pushState({},"",e),n(window.location.pathname)},route:r.route};return l(A.Provider,{value:s},u({children:t}))},j=()=>A.useContext("ryunix.navigation"),P=()=>{const{route:e,params:t,query:o,location:n}=j();if(!e||!e.component)return null;const r=q();return S((()=>{if(r){const e=r.slice(1),t=document.getElementById(e);t&&t.scrollIntoView({block:"start",behavior:"smooth"})}}),[r]),l(e.component,{key:n,params:t,query:o,hash:r})},W=({to:e,...t})=>{const{navigate:o}=j();return l("a",{href:e,onClick:t=>{t.preventDefault(),o(e)},...t},t.children)};var $={createElement:l,render:F,init:(e,t="__ryunix")=>{o.containerRoot=document.getElementById(t);return F(e,o.containerRoot)},Fragment:u,Hooks:Object.freeze({__proto__:null,Children:P,NavLink:W,RouterProvider:M,createContext:O,useCallback:C,useEffect:S,useHash:q,useMemo:L,useQuery:X,useRef:U,useRouter:j,useStore:T})};window.Ryunix=$,e.Children=P,e.Image=({src:e,...t})=>{const o={src:"true"===t.optimization?k({src:e,props:t}):e,...t};return l("img",o,null)},e.NavLink=W,e.RouterProvider=M,e.createContext=O,e.default=$,e.useCallback=C,e.useEffect=S,e.useHash=q,e.useMemo=L,e.useQuery=X,e.useRef=U,e.useRouter=j,e.useStore=T,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=>{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),h=(e,t)=>o=>e[o]!==t[o],f=e=>t=>!(t in e),y=e=>{e&&(e.hooks&&e.hooks.length>0&&e.hooks.filter((e=>e.type===r.RYUNIX_EFFECT&&typeof e.cancel===i.function)).forEach((e=>{e.cancel()})),e.child&&y(e.child),e.sibling&&y(e.sibling))},m=e=>{if(e.hooks&&0!==e.hooks.length)for(let t=0;t<e.hooks.length;t++){const o=e.hooks[t];if(o.type===r.RYUNIX_EFFECT&&typeof o.effect===i.function&&null!==o.effect){typeof o.cancel===i.function&&o.cancel();const e=o.effect();o.cancel="function"==typeof e?e:void 0}}},w=(e,t,o)=>{Object.keys(t).filter(p).filter((e=>f(o)(e)||h(t,o)(e))).forEach((o=>{const n=o.toLowerCase().substring(2);e.removeEventListener(n,t[o])})),Object.keys(t).filter(d).filter(f(o)).forEach((t=>{e[t]=""})),Object.keys(o).filter(d).filter(h(t,o)).forEach((n=>{if(n===i.style)E(e,o["ryunix-style"]);else if(n===s.style)E(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+/).filter(Boolean)||[]),e.classList.add(...o["ryunix-class"].split(/\s+/).filter(Boolean))}else if(n===s.className){if(""===o.className)throw new Error("className cannot be empty.");t.className&&e.classList.remove(...t.className.split(/\s+/).filter(Boolean)||[]),e.classList.add(...o.className.split(/\s+/).filter(Boolean))}else e[n]=o[n]})),Object.keys(o).filter(p).filter(h(t,o)).forEach((t=>{const n=t.toLowerCase().substring(2);e.addEventListener(n,o[t])}))},E=(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)(e=>{e.hooks&&e.hooks.length>0&&e.hooks.filter((e=>e.type===r.RYUNIX_EFFECT&&e.cancel)).forEach((e=>{e.cancel()}))})(e),null!=e.dom&&w(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}},g=(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,hooks:i.hooks}),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++}},k=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 w(t,{},e.props),t})(e)),g(e,t)},R=({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("height",t.height),t.quality&&o.set("quality",t.quality);const r=t.extension?`@${t.extension}`:"";return n?(()=>{const{hostname:e}=window.location;return"localhost"===e||"127.0.0.1"===e})()?(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()}`},I=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(I)};requestIdleCallback(I);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),g(e,t)})(e):k(e),e.child)return e.child;let t=e;for(;t;){if(t.sibling)return t.sibling;t=t.parent}},v=e=>{o.nextUnitOfWork=e,o.wipRoot=e,o.deletions=[],o.hookIndex=0,o.effects=[],requestIdleCallback(I)},T=(e,t)=>(o.wipRoot={dom:t,props:{children:[e]},alternate:o.currentRoot},o.nextUnitOfWork=o.wipRoot,o.deletions=[],v(o.wipRoot),o.wipRoot),F=(e,t)=>_(((e,t)=>"function"==typeof t?t(e):t),e,t),_=(e,t,n)=>{const s=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],l={hookID:o.hookIndex,type:r.RYUNIX_STORE,state:s?s.state:n?n(t):t,queue:s&&Array.isArray(s.queue)?s.queue.slice():[]};s&&Array.isArray(s.queue)&&s.queue.forEach((t=>{l.state=e(l.state,t)}));return l.queue.forEach((t=>{l.state=e(l.state,t)})),o.wipFiber.hooks[o.hookIndex]=l,o.hookIndex++,[l.state,e=>{l.queue.push(typeof e===i.function?e:t=>e),o.wipRoot={dom:o.currentRoot.dom,props:o.currentRoot.props,alternate:o.currentRoot},o.deletions=[],o.hookIndex=0,v(o.wipRoot)}]},S=(e,t)=>{const n=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],i=(s=n?.deps,l=t,!s||!l||s.length!==l.length||s.some(((e,t)=>e!==l[t])));var s,l;const a={hookID:o.hookIndex,type:r.RYUNIX_EFFECT,deps:t,effect:i?e:null,cancel:n?.cancel};o.wipFiber.hooks[o.hookIndex]=a,o.hookIndex++},U=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},C=(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},L=(e,t)=>C((()=>e),t),O=(e=r.RYUNIX_CONTEXT,t={})=>{const n=({children:e})=>u({children:e});n._contextId=e;return{Provider:n,useContext:(e=r.RYUNIX_CONTEXT)=>{let n=o.wipFiber;for(;n;){if(n.type&&n.type._contextId===e)return n.props&&"value"in n.props?n.props.value:void 0;n=n.parent}return t}}},X=()=>{const e=new URLSearchParams(window.location.search),t={};for(let[o,n]of e.entries())t[o]=n;return t},A=()=>{const[e,t]=F(window.location.hash);return S((()=>{const e=()=>{t(window.location.hash)};return window.addEventListener("hashchange",e),()=>window.removeEventListener("hashchange",e)}),[]),e},Y=O("ryunix.navigation",{location:"/",params:{},query:{},navigate:e=>{},replace:e=>{},route:null}),q=(e,t)=>{const o=t.split("?")[0].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){const t=e.reduce(((e,t,o)=>(e[t]=s[o+1],e)),{});return n?.redirectTo?{redirect:n.redirectTo}:{route:n,params:t}}}return r},M=({routes:e,children:t})=>{const[o,n]=F(window.location.pathname);S((()=>{const e=()=>n(window.location.pathname);return window.addEventListener("popstate",e),window.addEventListener("hashchange",e),()=>{window.removeEventListener("popstate",e),window.removeEventListener("hashchange",e)}}),[]);const r=e=>{window.history.replaceState({},"",e),n(e)},i=q(e,o)||{};if(i?.redirect)return r(routeData.redirect),null;const s=X(),l={location:o,params:i.params||{},query:s,navigate:e=>{window.history.pushState({},"",e),n(e)},replace:r,route:i.route};return a(Y.Provider,{value:l},u({children:t}))},j=()=>Y.useContext("ryunix.navigation"),P=()=>{const{route:e,params:t,query:o,location:n}=j();if(!e||!e.component)return null;const r=A();return S((()=>{if(r){const e=r.slice(1),t=document.getElementById(e);t&&t.scrollIntoView({block:"start",behavior:"smooth"})}}),[r]),a(e.component,{key:n,params:t,query:o,hash:r})},W=({to:e,exact:t=!1,...o})=>{const{location:n,navigate:r}=j(),i=t?n===e:n.startsWith(e);console.log(o);const s=o["ryunix-class"]?"ryunix-class":"className",l="function"==typeof(c=o["ryunix-class"]||className)?c({isActive:i}):c||"";var c;return a("a",{href:e,onClick:t=>{t.preventDefault(),r(e)},[s]:l,...o},o.children)},D=(e=!1)=>{const{location:t}=j();return e?t===window.location.pathname:t.startsWith(window.location.pathname)};D("/home"),D("/test");var $={createElement:a,render:T,init:(e,t="__ryunix")=>{o.containerRoot=document.getElementById(t);return T(e,o.containerRoot)},Fragment:u,Hooks:Object.freeze({__proto__:null,Children:P,NavLink:W,RouterProvider:M,createContext:O,useCallback:L,useEffect:S,useHash:A,useIsActive:D,useMemo:C,useQuery:X,useRef:U,useRouter:j,useStore:F})};window.Ryunix=$,e.Children=P,e.Image=({src:e,...t})=>{const o={src:"true"===t.optimization?R({src:e,props:t}):e,...t};return a("img",o,null)},e.NavLink=W,e.RouterProvider=M,e.createContext=O,e.default=$,e.useCallback=L,e.useEffect=S,e.useHash=A,e.useIsActive=D,e.useMemo=C,e.useQuery=X,e.useRef=U,e.useRouter=j,e.useStore=F,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.19",
3
+ "version": "1.1.20-canary.2",
4
4
  "license": "MIT",
5
5
  "main": "./dist/Ryunix.min.js",
6
6
  "types": "./dist/Ryunix.d.ts",
@@ -12,7 +12,6 @@
12
12
  "build:js": "rollup ./src/main.js --file ./dist/Ryunix.min.js --format umd --name Ryunix --plugin @rollup/plugin-terser",
13
13
  "build": "rollup ./src/main.js --file ./dist/Ryunix.js --format umd --name Ryunix",
14
14
  "prepublishOnly": "npm run build:js | npm run build",
15
- "nightly:release": "npm publish --tag nightly",
16
15
  "canary:release": "npm publish --tag canary",
17
16
  "release": "npm publish",
18
17
  "lint": "eslint . --ext .ts --fix --max-warnings=0 --config .eslintrc.js --no-eslintrc",