@unsetsoft/ryunixjs 1.2.0-canary.0 → 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.
@@ -1224,6 +1352,10 @@
1224
1352
  init,
1225
1353
  Fragment,
1226
1354
  Hooks,
1355
+ hydrate,
1356
+ renderToString,
1357
+ withSSRData,
1358
+ withSSGData,
1227
1359
  };
1228
1360
 
1229
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"}),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&&(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)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(h(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===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 g(e,o);b(e.child),b(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 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++}},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(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),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}},T=e=>{o.nextUnitOfWork=e,o.wipRoot=e,o.deletions=[],o.hookIndex=0,o.effects=[],requestIdleCallback(N)},v=(e,t)=>(o.wipRoot={dom:t,props:{children:[e]},alternate:o.currentRoot},o.nextUnitOfWork=o.wipRoot,o.deletions=[],T(o.wipRoot),o.wipRoot),_=(e,t)=>F((e,t)=>"function"==typeof t?t(e):t,e,t),F=(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,T(o.wipRoot)}]},S=(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},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),A=(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}}},L=()=>{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},X=()=>{if("undefined"==typeof window)return"";const[e,t]=_(window.location.hash);return S(()=>{const e=()=>{t(window.location.hash)};return window.addEventListener("hashchange",e),()=>window.removeEventListener("hashchange",e)},[]),e},q=A("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},j=({routes:e,children:t,ssrContext:o})=>{const n="undefined"==typeof window||!!o,r=n?o&&o.location||"/":window.location.pathname,[i,s]=_(r);S(()=>{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||{}:L(),p={location:i,params:a.params||{},query:c,navigate:e=>{n||(window.history.pushState({},"",e),s(e))},route:a.route};return l(q.Provider,{value:p},u({children:t}))},M=()=>q.useContext("ryunix.navigation"),$=()=>{const{route:e,params:t,query:o,location:n}=M();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]),l(e.component,{key:n,params:t,query:o,hash:r})},W=({to:e,exact:t=!1,...o})=>{const{location:n,navigate:r}=M(),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)},P=(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)}))}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:l,render:v,init:(e,t="__ryunix")=>{o.containerRoot=document.getElementById(t);return v(e,o.containerRoot)},Fragment:u,Hooks:Object.freeze({__proto__:null,Children:$,NavLink:W,RouterProvider:j,createContext:A,useCallback:O,useEffect:S,useHash:X,useMemo:C,useMetadata:P,useQuery:L,useRef:U,useRouter:M,useStore:_})};window.Ryunix=D,e.Children=$,e.Image=({src:e,...t})=>{const o={src:"true"===t.optimization?R({src:e,props:t}):e,...t};return l("img",o,null)},e.NavLink=W,e.RouterProvider=j,e.createContext=A,e.default=D,e.useCallback=O,e.useEffect=S,e.useHash=X,e.useMemo=C,e.useMetadata=P,e.useQuery=L,e.useRef=U,e.useRouter=M,e.useStore=_,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.2.0-canary.0",
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",