@unsetsoft/ryunixjs 1.1.38 → 1.2.0-canary.0
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 +128 -33
- package/dist/Ryunix.min.js +1 -1
- package/package.json +1 -1
package/dist/Ryunix.js
CHANGED
|
@@ -714,16 +714,18 @@
|
|
|
714
714
|
};
|
|
715
715
|
|
|
716
716
|
/**
|
|
717
|
-
*
|
|
718
|
-
* @param effect -
|
|
719
|
-
*
|
|
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.
|
|
717
|
+
* useEffect seguro para SSR/SSG: no ejecuta efectos en el servidor.
|
|
718
|
+
* @param effect - Función de efecto.
|
|
719
|
+
* @param deps - Dependencias.
|
|
724
720
|
*/
|
|
725
721
|
|
|
726
722
|
const useEffect = (callback, deps) => {
|
|
723
|
+
// No ejecutar efectos en SSR/SSG
|
|
724
|
+
if (typeof window === 'undefined') {
|
|
725
|
+
vars.hookIndex++;
|
|
726
|
+
return
|
|
727
|
+
}
|
|
728
|
+
|
|
727
729
|
const oldHook =
|
|
728
730
|
vars.wipFiber.alternate &&
|
|
729
731
|
vars.wipFiber.alternate.hooks &&
|
|
@@ -856,7 +858,9 @@
|
|
|
856
858
|
}
|
|
857
859
|
};
|
|
858
860
|
|
|
861
|
+
// Proteger hooks que usan window/document
|
|
859
862
|
const useQuery = () => {
|
|
863
|
+
if (typeof window === 'undefined') return {}
|
|
860
864
|
const searchParams = new URLSearchParams(window.location.search);
|
|
861
865
|
const query = {};
|
|
862
866
|
for (let [key, value] of searchParams.entries()) {
|
|
@@ -866,6 +870,7 @@
|
|
|
866
870
|
};
|
|
867
871
|
|
|
868
872
|
const useHash = () => {
|
|
873
|
+
if (typeof window === 'undefined') return ''
|
|
869
874
|
const [hash, setHash] = useStore(window.location.hash);
|
|
870
875
|
useEffect(() => {
|
|
871
876
|
const onHashChange = () => {
|
|
@@ -933,31 +938,46 @@
|
|
|
933
938
|
return notFound
|
|
934
939
|
};
|
|
935
940
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
941
|
+
/**
|
|
942
|
+
* RouterProvider universal: acepta contexto externo (SSR/SSG) o usa window.location (SPA).
|
|
943
|
+
* @param {Object} props - { routes, children, ssrContext }
|
|
944
|
+
* @example
|
|
945
|
+
* // SSR/SSG:
|
|
946
|
+
* <RouterProvider routes={routes} ssrContext={{ location: '/about', query: { q: 'x' } }}>
|
|
947
|
+
* ...
|
|
948
|
+
* </RouterProvider>
|
|
949
|
+
*/
|
|
950
|
+
const RouterProvider = ({ routes, children, ssrContext }) => {
|
|
951
|
+
// Si hay contexto externo (SSR/SSG), úsalo
|
|
952
|
+
const isSSR = typeof window === 'undefined' || !!ssrContext;
|
|
953
|
+
const location = isSSR
|
|
954
|
+
? (ssrContext && ssrContext.location) || '/'
|
|
955
|
+
: window.location.pathname;
|
|
956
|
+
const [loc, setLoc] = useStore(location);
|
|
957
|
+
|
|
958
|
+
// SPA: escucha cambios de ruta
|
|
939
959
|
useEffect(() => {
|
|
940
|
-
|
|
941
|
-
|
|
960
|
+
if (isSSR) return
|
|
961
|
+
const update = () => setLoc(window.location.pathname);
|
|
942
962
|
window.addEventListener('popstate', update);
|
|
943
963
|
window.addEventListener('hashchange', update);
|
|
944
964
|
return () => {
|
|
945
965
|
window.removeEventListener('popstate', update);
|
|
946
966
|
window.removeEventListener('hashchange', update);
|
|
947
967
|
}
|
|
948
|
-
}, [
|
|
968
|
+
}, [loc]);
|
|
949
969
|
|
|
950
970
|
const navigate = (path) => {
|
|
971
|
+
if (isSSR) return
|
|
951
972
|
window.history.pushState({}, '', path);
|
|
952
|
-
|
|
973
|
+
setLoc(path);
|
|
953
974
|
};
|
|
954
975
|
|
|
955
|
-
const currentRouteData = findRoute(routes,
|
|
956
|
-
|
|
957
|
-
const query = useQuery();
|
|
976
|
+
const currentRouteData = findRoute(routes, loc) || {};
|
|
977
|
+
const query = isSSR ? (ssrContext && ssrContext.query) || {} : useQuery();
|
|
958
978
|
|
|
959
979
|
const contextValue = {
|
|
960
|
-
location,
|
|
980
|
+
location: loc,
|
|
961
981
|
params: currentRouteData.params || {},
|
|
962
982
|
query,
|
|
963
983
|
navigate,
|
|
@@ -967,12 +987,16 @@
|
|
|
967
987
|
return createElement(
|
|
968
988
|
RouterContext.Provider,
|
|
969
989
|
{ value: contextValue },
|
|
970
|
-
Fragment({
|
|
971
|
-
children: children,
|
|
972
|
-
}),
|
|
990
|
+
Fragment({ children }),
|
|
973
991
|
)
|
|
974
992
|
};
|
|
975
993
|
|
|
994
|
+
/**
|
|
995
|
+
* Universal useRouter: obtiene el contexto de ruta, compatible con SSR/SSG y SPA.
|
|
996
|
+
* @returns {Object} { location, params, query, navigate, route }
|
|
997
|
+
* @example
|
|
998
|
+
* const { location, params, query } = useRouter();
|
|
999
|
+
*/
|
|
976
1000
|
const useRouter = () => {
|
|
977
1001
|
return RouterContext.useContext('ryunix.navigation')
|
|
978
1002
|
};
|
|
@@ -1036,17 +1060,93 @@
|
|
|
1036
1060
|
};
|
|
1037
1061
|
|
|
1038
1062
|
/**
|
|
1039
|
-
* useMetadata: Hook
|
|
1040
|
-
*
|
|
1041
|
-
*
|
|
1042
|
-
* @param {Object}
|
|
1043
|
-
|
|
1063
|
+
* useMetadata: Hook para gestionar dinámicamente metadatos SEO y recursos en <head>.
|
|
1064
|
+
* Ahora soporta title, meta, link, script, style y bloques personalizados en SSR/SSG.
|
|
1065
|
+
*
|
|
1066
|
+
* @param {Object} tags - Metadatos y recursos a insertar/actualizar.
|
|
1067
|
+
* Soporta: title, canonical, meta, og:*, twitter:*, script, style, custom.
|
|
1068
|
+
* - script/style/custom pueden ser string o array de strings (contenido o etiquetas completas).
|
|
1069
|
+
* @param {Object} options - Opcional. Permite definir template y default para el título.
|
|
1070
|
+
*
|
|
1071
|
+
* Ejemplo avanzado SSR/SSG:
|
|
1072
|
+
* useMetadata({
|
|
1073
|
+
* title: 'Mi página',
|
|
1074
|
+
* description: 'Desc',
|
|
1075
|
+
* script: [
|
|
1076
|
+
* '<script src="/analytics.js"></script>',
|
|
1077
|
+
* '<script>console.log("hi")</script>'
|
|
1078
|
+
* ],
|
|
1079
|
+
* style: '<style>body{background:#000}</style>',
|
|
1080
|
+
* custom: '<!-- Bloque personalizado -->'
|
|
1081
|
+
* })
|
|
1044
1082
|
*/
|
|
1045
|
-
|
|
1046
1083
|
const useMetadata = (tags = {}, options = {}) => {
|
|
1084
|
+
// SSR/SSG: collect metadata in global context if available
|
|
1085
|
+
const ssrContext =
|
|
1086
|
+
typeof globalThis !== 'undefined' && globalThis.__RYUNIX_SSR_CONTEXT__;
|
|
1087
|
+
if (ssrContext) {
|
|
1088
|
+
let finalTitle = '';
|
|
1089
|
+
let template = undefined;
|
|
1090
|
+
let defaultTitle = 'Ryunix App';
|
|
1091
|
+
if (options.title && typeof options.title === 'object') {
|
|
1092
|
+
template = options.title.template;
|
|
1093
|
+
if (typeof options.title.prefix === 'string') {
|
|
1094
|
+
defaultTitle = options.title.prefix;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
let pageTitle = tags.pageTitle || tags.title;
|
|
1098
|
+
if (typeof pageTitle === 'string') {
|
|
1099
|
+
if (pageTitle.trim() === '') {
|
|
1100
|
+
finalTitle = defaultTitle;
|
|
1101
|
+
} else if (template && template.includes('%s')) {
|
|
1102
|
+
finalTitle = template.replace('%s', pageTitle);
|
|
1103
|
+
} else {
|
|
1104
|
+
finalTitle = pageTitle;
|
|
1105
|
+
}
|
|
1106
|
+
} else if (typeof pageTitle === 'object' && pageTitle !== null) {
|
|
1107
|
+
finalTitle = defaultTitle;
|
|
1108
|
+
} else if (!pageTitle) {
|
|
1109
|
+
finalTitle = defaultTitle;
|
|
1110
|
+
}
|
|
1111
|
+
if (finalTitle) {
|
|
1112
|
+
ssrContext.head.push(`<title>${finalTitle}</title>`);
|
|
1113
|
+
}
|
|
1114
|
+
if (tags.canonical) {
|
|
1115
|
+
ssrContext.head.push(`<link rel="canonical" href="${tags.canonical}" />`);
|
|
1116
|
+
}
|
|
1117
|
+
Object.entries(tags).forEach(([key, value]) => {
|
|
1118
|
+
if (key === 'title' || key === 'pageTitle' || key === 'canonical') return
|
|
1119
|
+
if (key.startsWith('og:') || key.startsWith('twitter:')) {
|
|
1120
|
+
ssrContext.head.push(`<meta property="${key}" content="${value}" />`);
|
|
1121
|
+
} else {
|
|
1122
|
+
ssrContext.head.push(`<meta name="${key}" content="${value}" />`);
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
// Soporte para script/style/custom
|
|
1126
|
+
if (tags.script) {
|
|
1127
|
+
(Array.isArray(tags.script) ? tags.script : [tags.script]).forEach(
|
|
1128
|
+
(s) => {
|
|
1129
|
+
ssrContext.head.push(s);
|
|
1130
|
+
},
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
if (tags.style) {
|
|
1134
|
+
(Array.isArray(tags.style) ? tags.style : [tags.style]).forEach((s) => {
|
|
1135
|
+
ssrContext.head.push(s);
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
if (tags.custom) {
|
|
1139
|
+
(Array.isArray(tags.custom) ? tags.custom : [tags.custom]).forEach(
|
|
1140
|
+
(c) => {
|
|
1141
|
+
ssrContext.head.push(c);
|
|
1142
|
+
},
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1145
|
+
return
|
|
1146
|
+
}
|
|
1147
|
+
// SPA: fallback to DOM logic
|
|
1047
1148
|
useEffect(() => {
|
|
1048
1149
|
if (typeof document === 'undefined') return // SSR safe
|
|
1049
|
-
|
|
1050
1150
|
let finalTitle = '';
|
|
1051
1151
|
let template = undefined;
|
|
1052
1152
|
let defaultTitle = 'Ryunix App';
|
|
@@ -1056,10 +1156,7 @@
|
|
|
1056
1156
|
defaultTitle = options.title.prefix;
|
|
1057
1157
|
}
|
|
1058
1158
|
}
|
|
1059
|
-
|
|
1060
|
-
// pageTitle tiene prioridad sobre title
|
|
1061
1159
|
let pageTitle = tags.pageTitle || tags.title;
|
|
1062
|
-
|
|
1063
1160
|
if (typeof pageTitle === 'string') {
|
|
1064
1161
|
if (pageTitle.trim() === '') {
|
|
1065
1162
|
finalTitle = defaultTitle;
|
|
@@ -1074,7 +1171,6 @@
|
|
|
1074
1171
|
finalTitle = defaultTitle;
|
|
1075
1172
|
}
|
|
1076
1173
|
document.title = finalTitle;
|
|
1077
|
-
// Canonical
|
|
1078
1174
|
if (tags.canonical) {
|
|
1079
1175
|
let link = document.querySelector('link[rel="canonical"]');
|
|
1080
1176
|
if (!link) {
|
|
@@ -1084,7 +1180,6 @@
|
|
|
1084
1180
|
}
|
|
1085
1181
|
link.setAttribute('href', tags.canonical);
|
|
1086
1182
|
}
|
|
1087
|
-
// Meta tags
|
|
1088
1183
|
Object.entries(tags).forEach(([key, value]) => {
|
|
1089
1184
|
if (key === 'title' || key === 'pageTitle' || key === 'canonical') return
|
|
1090
1185
|
let selector = `meta[name='${key}']`;
|
package/dist/Ryunix.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("lodash")):"function"==typeof define&&define.amd?define(["exports","lodash"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Ryunix={},e.lodash)}(this,function(e,t){"use strict";let o={containerRoot:null,nextUnitOfWork:null,currentRoot:null,wipRoot:null,deletions:null,wipFiber:null,hookIndex:null,effects:null};const n=/[A-Z]/g,r=Object.freeze({TEXT_ELEMENT:Symbol("text.element").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),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})});
|