@unsetsoft/ryunixjs 1.1.38 → 1.2.0-canary.1

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
@@ -640,6 +640,134 @@
640
640
  return renderProcess
641
641
  };
642
642
 
643
+ /**
644
+ * Renders a Ryunix component tree to an HTML string (SSR/SSG), con soporte para obtención de datos.
645
+ * Si el componente raíz exporta una función estática `fetchSSRData` o `fetchSSGData`, esta será ejecutada antes del renderizado
646
+ * y sus datos serán inyectados como props.
647
+ *
648
+ * @param {Object} element - El elemento raíz a renderizar.
649
+ * @param {Object} [options] - Contexto opcional para SSR/SSG (ej: route, params, props).
650
+ * @returns {Promise<Object>} { html, head, data } - HTML renderizado, metadatos y datos obtenidos.
651
+ *
652
+ * Uso SSR con datos:
653
+ * App.fetchSSRData = async (ctx) => ({ user: await fetchUser(ctx.route) })
654
+ * const { html, head, data } = await renderToString(<App />, { route: '/about' })
655
+ *
656
+ * Uso SSG con datos:
657
+ * App.fetchSSGData = async (ctx) => ({ posts: await fetchPosts() })
658
+ * const { html, head, data } = await renderToString(<App />, { route: '/blog' })
659
+ */
660
+ async function renderToString(element, options = {}) {
661
+ // Soporte para obtención de datos SSR/SSG
662
+ let data = undefined;
663
+ let rootType = element && element.type;
664
+ // Si no se pasa location en ssrContext, usar '/'
665
+ if (options && !options.location) {
666
+ options.location = '/';
667
+ }
668
+ if (rootType && typeof rootType === 'function') {
669
+ if (typeof rootType.fetchSSRData === 'function' && options.ssr !== false) {
670
+ data = await rootType.fetchSSRData(options);
671
+ } else if (
672
+ typeof rootType.fetchSSGData === 'function' &&
673
+ options.ssg !== false
674
+ ) {
675
+ data = await rootType.fetchSSGData(options);
676
+ }
677
+ }
678
+ // Inyectar los datos como props
679
+ if (data) {
680
+ element = { ...element, props: { ...element.props, ...data } };
681
+ }
682
+ // Temporary global context for SSR/SSG metadata collection
683
+ const ssrContext = { head: [] };
684
+ const prevContext = globalThis.__RYUNIX_SSR_CONTEXT__;
685
+ globalThis.__RYUNIX_SSR_CONTEXT__ = ssrContext;
686
+
687
+ function renderNode(node) {
688
+ if (typeof node === 'string' || typeof node === 'number') {
689
+ return String(node)
690
+ }
691
+ if (!node || typeof node !== 'object') return ''
692
+ if (node.type === 'FRAGMENT' || node.type === undefined) {
693
+ return (Array.isArray(node.children) ? node.children : [node.children])
694
+ .map(renderNode)
695
+ .join('')
696
+ }
697
+ if (typeof node.type === 'function') {
698
+ const rendered = node.type({ ...node.props, ...options });
699
+ return renderNode(rendered)
700
+ }
701
+ let html = `<${node.type}`;
702
+ if (node.props) {
703
+ for (const [key, value] of Object.entries(node.props)) {
704
+ if (key === 'children' || value == null || typeof value === 'object')
705
+ continue
706
+ html += ` ${key}="${String(value)}"`;
707
+ }
708
+ }
709
+ html += '>';
710
+ if (node.props && node.props.children) {
711
+ html += Array.isArray(node.props.children)
712
+ ? node.props.children.map(renderNode).join('')
713
+ : renderNode(node.props.children);
714
+ }
715
+ html += `</${node.type}>`;
716
+ return html
717
+ }
718
+
719
+ const html = renderNode(element);
720
+ // Restore previous context to avoid leaking between renders
721
+ globalThis.__RYUNIX_SSR_CONTEXT__ = prevContext;
722
+ return { html, head: ssrContext.head.join('\n'), data }
723
+ }
724
+
725
+ /**
726
+ * Helper para asociar una función de obtención de datos SSR a un componente Ryunix.
727
+ * @param {Function} Component - Componente Ryunix.
728
+ * @param {Function} fetchFn - Función async (ctx) => datos.
729
+ * @returns {Function} El mismo componente, con fetchSSRData asignado.
730
+ * @example
731
+ * export default withSSRData(App, async (ctx) => ({ user: await fetchUser(ctx.route) }))
732
+ */
733
+ function withSSRData(Component, fetchFn) {
734
+ Component.fetchSSRData = fetchFn;
735
+ return Component
736
+ }
737
+
738
+ /**
739
+ * Helper para asociar una función de obtención de datos SSG a un componente Ryunix.
740
+ * @param {Function} Component - Componente Ryunix.
741
+ * @param {Function} fetchFn - Función async (ctx) => datos.
742
+ * @returns {Function} El mismo componente, con fetchSSGData asignado.
743
+ * @example
744
+ * export default withSSGData(App, async (ctx) => ({ posts: await fetchPosts() }))
745
+ */
746
+ function withSSGData(Component, fetchFn) {
747
+ Component.fetchSSGData = fetchFn;
748
+ return Component
749
+ }
750
+
751
+ /**
752
+ * Hidrata una aplicación Ryunix renderizada por SSR/SSG, enlazando eventos y estado sobre el DOM existente.
753
+ * @function hydrate
754
+ * @param {Object|HTMLElement} element - El elemento raíz a hidratar.
755
+ * @param {string|HTMLElement} [root='__ryunix'] - El contenedor raíz (id o elemento DOM).
756
+ * @description Busca el contenedor en el DOM y reutiliza el HTML existente, enlazando el árbol de componentes Ryunix.
757
+ * @example
758
+ * // En el cliente, tras recibir HTML SSR/SSG:
759
+ * import { hydrate } from 'ryunix';
760
+ * hydrate(<App />, '__ryunix');
761
+ */
762
+ function hydrate(MainElement, root = '__ryunix') {
763
+ let container =
764
+ typeof root === 'string' ? document.getElementById(root) : root;
765
+ if (!container) throw new Error('No se encontró el contenedor para hidratar')
766
+ // Reutiliza el DOM existente y conecta el árbol Ryunix
767
+ // (En este ejemplo, simplemente delegamos a render, pero en el futuro se puede optimizar para diff/hidratación real)
768
+ return render(MainElement, container)
769
+ }
770
+
643
771
  /**
644
772
  * @description The function creates a state.
645
773
  * @param initial - The initial value of the state for the hook.
@@ -714,16 +842,18 @@
714
842
  };
715
843
 
716
844
  /**
717
- * This is a function that creates a hook for managing side effects in Ryunix components.
718
- * @param effect - The effect function that will be executed after the component has rendered or when
719
- * the dependencies have changed. It can perform side effects such as fetching data, updating the DOM,
720
- * or subscribing to events.
721
- * @param deps - An array of dependencies that the effect depends on. If any of the dependencies change
722
- * between renders, the effect will be re-run. If the array is empty, the effect will only run once on
723
- * mount and never again.
845
+ * useEffect seguro para SSR/SSG: no ejecuta efectos en el servidor.
846
+ * @param effect - Función de efecto.
847
+ * @param deps - Dependencias.
724
848
  */
725
849
 
726
850
  const useEffect = (callback, deps) => {
851
+ // No ejecutar efectos en SSR/SSG
852
+ if (typeof window === 'undefined') {
853
+ vars.hookIndex++;
854
+ return
855
+ }
856
+
727
857
  const oldHook =
728
858
  vars.wipFiber.alternate &&
729
859
  vars.wipFiber.alternate.hooks &&
@@ -856,7 +986,9 @@
856
986
  }
857
987
  };
858
988
 
989
+ // Proteger hooks que usan window/document
859
990
  const useQuery = () => {
991
+ if (typeof window === 'undefined') return {}
860
992
  const searchParams = new URLSearchParams(window.location.search);
861
993
  const query = {};
862
994
  for (let [key, value] of searchParams.entries()) {
@@ -866,6 +998,7 @@
866
998
  };
867
999
 
868
1000
  const useHash = () => {
1001
+ if (typeof window === 'undefined') return ''
869
1002
  const [hash, setHash] = useStore(window.location.hash);
870
1003
  useEffect(() => {
871
1004
  const onHashChange = () => {
@@ -933,31 +1066,46 @@
933
1066
  return notFound
934
1067
  };
935
1068
 
936
- const RouterProvider = ({ routes, children }) => {
937
- const [location, setLocation] = useStore(window.location.pathname);
938
-
1069
+ /**
1070
+ * RouterProvider universal: acepta contexto externo (SSR/SSG) o usa window.location (SPA).
1071
+ * @param {Object} props - { routes, children, ssrContext }
1072
+ * @example
1073
+ * // SSR/SSG:
1074
+ * <RouterProvider routes={routes} ssrContext={{ location: '/about', query: { q: 'x' } }}>
1075
+ * ...
1076
+ * </RouterProvider>
1077
+ */
1078
+ const RouterProvider = ({ routes, children, ssrContext }) => {
1079
+ // Si hay contexto externo (SSR/SSG), úsalo
1080
+ const isSSR = typeof window === 'undefined' || !!ssrContext;
1081
+ const location = isSSR
1082
+ ? (ssrContext && ssrContext.location) || '/'
1083
+ : window.location.pathname;
1084
+ const [loc, setLoc] = useStore(location);
1085
+
1086
+ // SPA: escucha cambios de ruta
939
1087
  useEffect(() => {
940
- const update = () => setLocation(window.location.pathname);
941
-
1088
+ if (isSSR) return
1089
+ const update = () => setLoc(window.location.pathname);
942
1090
  window.addEventListener('popstate', update);
943
1091
  window.addEventListener('hashchange', update);
944
1092
  return () => {
945
1093
  window.removeEventListener('popstate', update);
946
1094
  window.removeEventListener('hashchange', update);
947
1095
  }
948
- }, [location]);
1096
+ }, [loc]);
949
1097
 
950
1098
  const navigate = (path) => {
1099
+ if (isSSR) return
951
1100
  window.history.pushState({}, '', path);
952
- setLocation(path);
1101
+ setLoc(path);
953
1102
  };
954
1103
 
955
- const currentRouteData = findRoute(routes, location) || {};
956
-
957
- const query = useQuery();
1104
+ const currentRouteData = findRoute(routes, loc) || {};
1105
+ const query = isSSR ? (ssrContext && ssrContext.query) || {} : useQuery();
958
1106
 
959
1107
  const contextValue = {
960
- location,
1108
+ location: loc,
961
1109
  params: currentRouteData.params || {},
962
1110
  query,
963
1111
  navigate,
@@ -967,12 +1115,16 @@
967
1115
  return createElement(
968
1116
  RouterContext.Provider,
969
1117
  { value: contextValue },
970
- Fragment({
971
- children: children,
972
- }),
1118
+ Fragment({ children }),
973
1119
  )
974
1120
  };
975
1121
 
1122
+ /**
1123
+ * Universal useRouter: obtiene el contexto de ruta, compatible con SSR/SSG y SPA.
1124
+ * @returns {Object} { location, params, query, navigate, route }
1125
+ * @example
1126
+ * const { location, params, query } = useRouter();
1127
+ */
976
1128
  const useRouter = () => {
977
1129
  return RouterContext.useContext('ryunix.navigation')
978
1130
  };
@@ -1036,17 +1188,93 @@
1036
1188
  };
1037
1189
 
1038
1190
  /**
1039
- * useMetadata: Hook to dynamically manage SEO metadata in the <head>.
1040
- * Supports title with template, description, robots, robots, canonical, OpenGraph, Twitter, and any standard meta.
1041
- * @param {Object} tags - Object with metatags to insert/update.
1042
- * @param {Object} options - Optional. Allows to define template and default for the title.
1043
-
1191
+ * useMetadata: Hook para gestionar dinámicamente metadatos SEO y recursos en <head>.
1192
+ * Ahora soporta title, meta, link, script, style y bloques personalizados en SSR/SSG.
1193
+ *
1194
+ * @param {Object} tags - Metadatos y recursos a insertar/actualizar.
1195
+ * Soporta: title, canonical, meta, og:*, twitter:*, script, style, custom.
1196
+ * - script/style/custom pueden ser string o array de strings (contenido o etiquetas completas).
1197
+ * @param {Object} options - Opcional. Permite definir template y default para el título.
1198
+ *
1199
+ * Ejemplo avanzado SSR/SSG:
1200
+ * useMetadata({
1201
+ * title: 'Mi página',
1202
+ * description: 'Desc',
1203
+ * script: [
1204
+ * '<script src="/analytics.js"></script>',
1205
+ * '<script>console.log("hi")</script>'
1206
+ * ],
1207
+ * style: '<style>body{background:#000}</style>',
1208
+ * custom: '<!-- Bloque personalizado -->'
1209
+ * })
1044
1210
  */
1045
-
1046
1211
  const useMetadata = (tags = {}, options = {}) => {
1212
+ // SSR/SSG: collect metadata in global context if available
1213
+ const ssrContext =
1214
+ typeof globalThis !== 'undefined' && globalThis.__RYUNIX_SSR_CONTEXT__;
1215
+ if (ssrContext) {
1216
+ let finalTitle = '';
1217
+ let template = undefined;
1218
+ let defaultTitle = 'Ryunix App';
1219
+ if (options.title && typeof options.title === 'object') {
1220
+ template = options.title.template;
1221
+ if (typeof options.title.prefix === 'string') {
1222
+ defaultTitle = options.title.prefix;
1223
+ }
1224
+ }
1225
+ let pageTitle = tags.pageTitle || tags.title;
1226
+ if (typeof pageTitle === 'string') {
1227
+ if (pageTitle.trim() === '') {
1228
+ finalTitle = defaultTitle;
1229
+ } else if (template && template.includes('%s')) {
1230
+ finalTitle = template.replace('%s', pageTitle);
1231
+ } else {
1232
+ finalTitle = pageTitle;
1233
+ }
1234
+ } else if (typeof pageTitle === 'object' && pageTitle !== null) {
1235
+ finalTitle = defaultTitle;
1236
+ } else if (!pageTitle) {
1237
+ finalTitle = defaultTitle;
1238
+ }
1239
+ if (finalTitle) {
1240
+ ssrContext.head.push(`<title>${finalTitle}</title>`);
1241
+ }
1242
+ if (tags.canonical) {
1243
+ ssrContext.head.push(`<link rel="canonical" href="${tags.canonical}" />`);
1244
+ }
1245
+ Object.entries(tags).forEach(([key, value]) => {
1246
+ if (key === 'title' || key === 'pageTitle' || key === 'canonical') return
1247
+ if (key.startsWith('og:') || key.startsWith('twitter:')) {
1248
+ ssrContext.head.push(`<meta property="${key}" content="${value}" />`);
1249
+ } else {
1250
+ ssrContext.head.push(`<meta name="${key}" content="${value}" />`);
1251
+ }
1252
+ });
1253
+ // Soporte para script/style/custom
1254
+ if (tags.script) {
1255
+ (Array.isArray(tags.script) ? tags.script : [tags.script]).forEach(
1256
+ (s) => {
1257
+ ssrContext.head.push(s);
1258
+ },
1259
+ );
1260
+ }
1261
+ if (tags.style) {
1262
+ (Array.isArray(tags.style) ? tags.style : [tags.style]).forEach((s) => {
1263
+ ssrContext.head.push(s);
1264
+ });
1265
+ }
1266
+ if (tags.custom) {
1267
+ (Array.isArray(tags.custom) ? tags.custom : [tags.custom]).forEach(
1268
+ (c) => {
1269
+ ssrContext.head.push(c);
1270
+ },
1271
+ );
1272
+ }
1273
+ return
1274
+ }
1275
+ // SPA: fallback to DOM logic
1047
1276
  useEffect(() => {
1048
1277
  if (typeof document === 'undefined') return // SSR safe
1049
-
1050
1278
  let finalTitle = '';
1051
1279
  let template = undefined;
1052
1280
  let defaultTitle = 'Ryunix App';
@@ -1056,10 +1284,7 @@
1056
1284
  defaultTitle = options.title.prefix;
1057
1285
  }
1058
1286
  }
1059
-
1060
- // pageTitle tiene prioridad sobre title
1061
1287
  let pageTitle = tags.pageTitle || tags.title;
1062
-
1063
1288
  if (typeof pageTitle === 'string') {
1064
1289
  if (pageTitle.trim() === '') {
1065
1290
  finalTitle = defaultTitle;
@@ -1074,7 +1299,6 @@
1074
1299
  finalTitle = defaultTitle;
1075
1300
  }
1076
1301
  document.title = finalTitle;
1077
- // Canonical
1078
1302
  if (tags.canonical) {
1079
1303
  let link = document.querySelector('link[rel="canonical"]');
1080
1304
  if (!link) {
@@ -1084,7 +1308,6 @@
1084
1308
  }
1085
1309
  link.setAttribute('href', tags.canonical);
1086
1310
  }
1087
- // Meta tags
1088
1311
  Object.entries(tags).forEach(([key, value]) => {
1089
1312
  if (key === 'title' || key === 'pageTitle' || key === 'canonical') return
1090
1313
  let selector = `meta[name='${key}']`;
@@ -1129,6 +1352,10 @@
1129
1352
  init,
1130
1353
  Fragment,
1131
1354
  Hooks,
1355
+ hydrate,
1356
+ renderToString,
1357
+ withSSRData,
1358
+ withSSGData,
1132
1359
  };
1133
1360
 
1134
1361
  window.Ryunix = Ryunix;
@@ -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"}),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}}},E=(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)b(e,o["ryunix-style"]);else if(n===s.style)b(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])})},b=(e,t)=>{e.style=Object.keys(t).reduce((e,o)=>e+=`${o.replace(n,function(e){return"-"+e.toLowerCase()})}: ${t[o]};`,"")},w=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&&E(e.dom,e.alternate.props,e.props),m(e);else if(e.effectTag===l.DELETION)return y(e),void g(e,o);w(e.child),w(e.sibling)},g=(e,t)=>{if(e.dom)t.removeChild(e.dom);else{let o=e.child;for(;o;)g(o,t),o=o.sibling}},x=(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 E(t,{},e.props),t})(e)),x(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()}`},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(w),w(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),x(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(N)},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},O=(e,t)=>C(()=>e,t),L=(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}}},A=()=>{const e=new URLSearchParams(window.location.search),t={};for(let[o,n]of e.entries())t[o]=n;return t},X=()=>{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},q=L("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]=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)}},[o]);const r=Y(e,o)||{},i=A(),s={location:o,params:r.params||{},query:i,navigate:e=>{window.history.pushState({},"",e),n(e)},route:r.route};return a(q.Provider,{value:s},u({children:t}))},j=()=>q.useContext("ryunix.navigation"),W=()=>{const{route:e,params:t,query:o,location:n}=j();if(!e||!e.component)return null;const r=X();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})},P=({to:e,exact:t=!1,...o})=>{const{location:n,navigate:r}=j(),i=t?n===e:n.startsWith(e),s=o["ryunix-class"]?"ryunix-class":"className",l="function"==typeof(c=o["ryunix-class"]||o.className)?c({isActive:i}):c||"";var c;const{"ryunix-class":u,className:p,...d}=o;return a("a",{href:e,onClick:t=>{t.preventDefault(),r(e)},[s]:l,...d},o.children)},$=(e={},t={})=>{S(()=>{if("undefined"==typeof document)return;let o,n="",r="Ryunix App";t.title&&"object"==typeof t.title&&(o=t.title.template,"string"==typeof t.title.prefix&&(r=t.title.prefix));let i=e.pageTitle||e.title;if("string"==typeof i?n=""===i.trim()?r:o&&o.includes("%s")?o.replace("%s",i):i:"object"==typeof i&&null!==i?n=r:i||(n=r),document.title=n,e.canonical){let t=document.querySelector('link[rel="canonical"]');t||(t=document.createElement("link"),t.setAttribute("rel","canonical"),document.head.appendChild(t)),t.setAttribute("href",e.canonical)}Object.entries(e).forEach(([e,t])=>{if("title"===e||"pageTitle"===e||"canonical"===e)return;let o=`meta[name='${e}']`;(e.startsWith("og:")||e.startsWith("twitter:"))&&(o=`meta[property='${e}']`);let n=document.head.querySelector(o);n||(n=document.createElement("meta"),e.startsWith("og:")||e.startsWith("twitter:")?n.setAttribute("property",e):n.setAttribute("name",e),document.head.appendChild(n)),n.setAttribute("content",t)})},[JSON.stringify(e),JSON.stringify(t)])};var D={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:W,NavLink:P,RouterProvider:M,createContext:L,useCallback:O,useEffect:S,useHash:X,useMemo:C,useMetadata:$,useQuery:A,useRef:U,useRouter:j,useStore:F})};window.Ryunix=D,e.Children=W,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=P,e.RouterProvider=M,e.createContext=L,e.default=D,e.useCallback=O,e.useEffect=S,e.useHash=X,e.useMemo=C,e.useMetadata=$,e.useQuery=A,e.useRef=U,e.useRouter=j,e.useStore=F,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"}),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),f=(e,t)=>o=>e[o]!==t[o],h=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}}},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+/).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(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]};`,"")},g=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)(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&&E(e.dom,e.alternate.props,e.props),m(e);else if(e.effectTag===a.DELETION)return y(e),void b(e,o);g(e.child),g(e.sibling)},b=(e,t)=>{if(e.dom)t.removeChild(e.dom);else{let o=e.child;for(;o;)b(o,t),o=o.sibling}},x=(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,hooks:i.hooks}),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 E(t,{},e.props),t})(e)),x(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=S(o.nextUnitOfWork),t=e.timeRemaining()<1;!o.nextUnitOfWork&&o.wipRoot&&(o.deletions.forEach(g),g(o.wipRoot.child),o.currentRoot=o.wipRoot,o.wipRoot=null),requestIdleCallback(N)};requestIdleCallback(N);const S=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),x(e,t)})(e):R(e),e.child)return e.child;let t=e;for(;t;){if(t.sibling)return t.sibling;t=t.parent}},_=e=>{o.nextUnitOfWork=e,o.wipRoot=e,o.deletions=[],o.hookIndex=0,o.effects=[],requestIdleCallback(N)},T=(e,t)=>(o.wipRoot={dom:t,props:{children:[e]},alternate:o.currentRoot},o.nextUnitOfWork=o.wipRoot,o.deletions=[],_(o.wipRoot),o.wipRoot);const I=(e,t)=>v((e,t)=>"function"==typeof t?t(e):t,e,t),v=(e,t,n)=>{const s=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],a={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=>{a.state=e(a.state,t)});return a.queue.forEach(t=>{a.state=e(a.state,t)}),o.wipFiber.hooks[o.hookIndex]=a,o.hookIndex++,[a.state,e=>{a.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,_(o.wipRoot)}]},F=(e,t)=>{if("undefined"==typeof window)return void o.hookIndex++;const n=o.wipFiber.alternate&&o.wipFiber.alternate.hooks&&o.wipFiber.alternate.hooks[o.hookIndex],i=(s=n?.deps,a=t,!s||!a||s.length!==a.length||s.some((e,t)=>e!==a[t]));var s,a;const l={hookID:o.hookIndex,type:r.RYUNIX_EFFECT,deps:t,effect:i?e:null,cancel:n?.cancel};o.wipFiber.hooks[o.hookIndex]=l,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},A=(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},O=(e,t)=>A(()=>e,t),C=(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=()=>{if("undefined"==typeof window)return{};const e=new URLSearchParams(window.location.search),t={};for(let[o,n]of e.entries())t[o]=n;return t},L=()=>{if("undefined"==typeof window)return"";const[e,t]=I(window.location.hash);return F(()=>{const e=()=>{t(window.location.hash)};return window.addEventListener("hashchange",e),()=>window.removeEventListener("hashchange",e)},[]),e},j=C("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},q=({routes:e,children:t,ssrContext:o})=>{const n="undefined"==typeof window||!!o,r=n?o&&o.location||"/":window.location.pathname,[i,s]=I(r);F(()=>{if(n)return;const e=()=>s(window.location.pathname);return window.addEventListener("popstate",e),window.addEventListener("hashchange",e),()=>{window.removeEventListener("popstate",e),window.removeEventListener("hashchange",e)}},[i]);const a=Y(e,i)||{},c=n?o&&o.query||{}:X(),p={location:i,params:a.params||{},query:c,navigate:e=>{n||(window.history.pushState({},"",e),s(e))},route:a.route};return l(j.Provider,{value:p},u({children:t}))},$=()=>j.useContext("ryunix.navigation"),M=()=>{const{route:e,params:t,query:o,location:n}=$();if(!e||!e.component)return null;const r=L();return F(()=>{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})},D=({to:e,exact:t=!1,...o})=>{const{location:n,navigate:r}=$(),i=t?n===e:n.startsWith(e),s=o["ryunix-class"]?"ryunix-class":"className",a="function"==typeof(c=o["ryunix-class"]||o.className)?c({isActive:i}):c||"";var c;const{"ryunix-class":u,className:p,...d}=o;return l("a",{href:e,onClick:t=>{t.preventDefault(),r(e)},[s]:a,...d},o.children)},W=(e={},t={})=>{const o="undefined"!=typeof globalThis&&globalThis.__RYUNIX_SSR_CONTEXT__;if(o){let n,r="",i="Ryunix App";t.title&&"object"==typeof t.title&&(n=t.title.template,"string"==typeof t.title.prefix&&(i=t.title.prefix));let s=e.pageTitle||e.title;return"string"==typeof s?r=""===s.trim()?i:n&&n.includes("%s")?n.replace("%s",s):s:"object"==typeof s&&null!==s?r=i:s||(r=i),r&&o.head.push(`<title>${r}</title>`),e.canonical&&o.head.push(`<link rel="canonical" href="${e.canonical}" />`),Object.entries(e).forEach(([e,t])=>{"title"!==e&&"pageTitle"!==e&&"canonical"!==e&&(e.startsWith("og:")||e.startsWith("twitter:")?o.head.push(`<meta property="${e}" content="${t}" />`):o.head.push(`<meta name="${e}" content="${t}" />`))}),e.script&&(Array.isArray(e.script)?e.script:[e.script]).forEach(e=>{o.head.push(e)}),e.style&&(Array.isArray(e.style)?e.style:[e.style]).forEach(e=>{o.head.push(e)}),void(e.custom&&(Array.isArray(e.custom)?e.custom:[e.custom]).forEach(e=>{o.head.push(e)}))}F(()=>{if("undefined"==typeof document)return;let o,n="",r="Ryunix App";t.title&&"object"==typeof t.title&&(o=t.title.template,"string"==typeof t.title.prefix&&(r=t.title.prefix));let i=e.pageTitle||e.title;if("string"==typeof i?n=""===i.trim()?r:o&&o.includes("%s")?o.replace("%s",i):i:"object"==typeof i&&null!==i?n=r:i||(n=r),document.title=n,e.canonical){let t=document.querySelector('link[rel="canonical"]');t||(t=document.createElement("link"),t.setAttribute("rel","canonical"),document.head.appendChild(t)),t.setAttribute("href",e.canonical)}Object.entries(e).forEach(([e,t])=>{if("title"===e||"pageTitle"===e||"canonical"===e)return;let o=`meta[name='${e}']`;(e.startsWith("og:")||e.startsWith("twitter:"))&&(o=`meta[property='${e}']`);let n=document.head.querySelector(o);n||(n=document.createElement("meta"),e.startsWith("og:")||e.startsWith("twitter:")?n.setAttribute("property",e):n.setAttribute("name",e),document.head.appendChild(n)),n.setAttribute("content",t)})},[JSON.stringify(e),JSON.stringify(t)])};var P={createElement:l,render:T,init:(e,t="__ryunix")=>{o.containerRoot=document.getElementById(t);return T(e,o.containerRoot)},Fragment:u,Hooks:Object.freeze({__proto__:null,Children:M,NavLink:D,RouterProvider:q,createContext:C,useCallback:O,useEffect:F,useHash:L,useMemo:A,useMetadata:W,useQuery:X,useRef:U,useRouter:$,useStore:I}),hydrate:function(e,t="__ryunix"){let o="string"==typeof t?document.getElementById(t):t;if(!o)throw new Error("No se encontró el contenedor para hidratar");return T(e,o)},renderToString:async function(e,t={}){let o,n=e&&e.type;t&&!t.location&&(t.location="/"),n&&"function"==typeof n&&("function"==typeof n.fetchSSRData&&!1!==t.ssr?o=await n.fetchSSRData(t):"function"==typeof n.fetchSSGData&&!1!==t.ssg&&(o=await n.fetchSSGData(t))),o&&(e={...e,props:{...e.props,...o}});const r={head:[]},i=globalThis.__RYUNIX_SSR_CONTEXT__;globalThis.__RYUNIX_SSR_CONTEXT__=r;const s=function e(o){if("string"==typeof o||"number"==typeof o)return String(o);if(!o||"object"!=typeof o)return"";if("FRAGMENT"===o.type||void 0===o.type)return(Array.isArray(o.children)?o.children:[o.children]).map(e).join("");if("function"==typeof o.type){return e(o.type({...o.props,...t}))}let n=`<${o.type}`;if(o.props)for(const[e,t]of Object.entries(o.props))"children"!==e&&null!=t&&"object"!=typeof t&&(n+=` ${e}="${String(t)}"`);return n+=">",o.props&&o.props.children&&(n+=Array.isArray(o.props.children)?o.props.children.map(e).join(""):e(o.props.children)),n+=`</${o.type}>`,n}(e);return globalThis.__RYUNIX_SSR_CONTEXT__=i,{html:s,head:r.head.join("\n"),data:o}},withSSRData:function(e,t){return e.fetchSSRData=t,e},withSSGData:function(e,t){return e.fetchSSGData=t,e}};window.Ryunix=P,e.Children=M,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=D,e.RouterProvider=q,e.createContext=C,e.default=P,e.useCallback=O,e.useEffect=F,e.useHash=L,e.useMemo=A,e.useMetadata=W,e.useQuery=X,e.useRef=U,e.useRouter=$,e.useStore=I,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.38",
3
+ "version": "1.2.0-canary.1",
4
4
  "license": "MIT",
5
5
  "main": "./dist/Ryunix.min.js",
6
6
  "types": "./dist/Ryunix.d.ts",