lightweight-router 1.0.8 → 1.0.10

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.
@@ -1 +1 @@
1
- (()=>{let l={},o=!1,c=(...e)=>o&&console.log("🚦 Router:",...e),r=async()=>{c("Navigation triggered to:",globalThis.location.pathname),document.body.classList.add("loading");var e=globalThis.location.pathname,t=document.querySelector("router");let n=t.querySelector(`route[path="${e}"]`);if(n||(c("Creating new route element for:",e),(n=document.createElement("route")).setAttribute("path",e),t.appendChild(n)),!n.innerHTML){c("Fetching content for:",globalThis.location.href);let e=l[globalThis.location.href];e||(e=await u(globalThis.location.href),l[globalThis.location.href]=e);var o,r=(new DOMParser).parseFromString(e,"text/html"),a=r.querySelector("title"),a=(a&&(c("Updating page title to:",a.textContent),document.title=a.textContent),n.innerHTML=r.body.innerHTML,Array.from(n.querySelectorAll("script")));c("Executing",a.length,"scripts from fetched content");for(o of a){var i=document.createElement("script");o.src?i.src=o.src:i.textContent=o.textContent,o.parentNode.replaceChild(i,o)}}t.querySelectorAll("route").forEach(e=>e.style.display="none"),n.style.display="contents",document.body.classList.remove("loading"),window.scrollTo(0,0),h&&h(e),c("Route change completed")},a=async e=>{l[e.href]||(c("Prefetching content for:",e.href),l[e.href]=await u(e.href))},i=(e,t)=>{e.forEach(e=>{e.isIntersecting&&(e=e.target,l[e.href]||(a(e),t.unobserve(e)))})},s=e=>{var t=e.target.closest("A");t&&t.href&&d(t.href)&&t.origin===location.origin?(c("Internal link clicked:",t.href),e.preventDefault(),globalThis.history.pushState(null,null,t.href),globalThis.dispatchEvent(new Event("popstate"))):c("Invalid link click:",t?.href)};function d(e){if(e&&!e.startsWith("#")&&!e.startsWith("javascript:")){if(e.startsWith("/"))return 1;try{var t=new URL(e,window.location.origin),n=new URL(window.location.href);return n.hostname.replace(/^www\./,"")===t.hostname.replace(/^www\./,"")?n.pathname!==t.pathname||!t.hash:void 0}catch{}}}let h,u=async e=>{e=await t(e);return e.ok?e.text():"Couldn't fetch the route - HTTP error! status: "+e.status},t=async e=>{if(!f){var t=await fetch(e,{method:"POST",body:"onlyRoute"});if(t.ok)return t}return fetch(e)},f=!1,e=(e={})=>{var{onRouteChange:t,debug:n}=e,e=(o=n,c("Router starting...",e),t&&(n=t,h=n),document.createElement("style")),t=(e.textContent=".loading{animation:pulse 1s infinite alternate}@keyframes pulse{from{opacity:.6}to{opacity:.1}}route{content-visibility:auto}",document.head.appendChild(e),document.querySelector("router")),n=globalThis.location.pathname,n=(t||(c("Creating new router element"),t=document.createElement("router"),(e=document.createElement("route")).setAttribute("path",n),e.innerHTML=document.body.innerHTML,t.appendChild(e),document.body.innerHTML="",document.body.appendChild(t),f=!0),globalThis.addEventListener("popstate",r),document.addEventListener("click",s),document.body.addEventListener("mouseover",e=>{"A"===e.target.tagName&&"onHover"===e.target.getAttribute("prefetch")&&(async e=>{e=e.target;!l[e.href]&&d(e.href)&&await a(e)})(e)}),new IntersectionObserver(i,{root:null,threshold:.5}));(t=>{let n=navigator.connection&&navigator.connection.saveData;document.querySelectorAll("a").forEach(e=>{"onHover"===e.getAttribute("prefetch")||n||d(e.href)||t.observe(e)})})(n)};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>e()):e()})();
1
+ (()=>{let l={},n=!1,c=(...e)=>n&&console.log("🚦 Router:",...e),o=async()=>{c("Navigation triggered to:",globalThis.location.pathname),document.body.classList.add("loading");var e=globalThis.location.pathname.replace(/\/$/,""),t=document.querySelector("router");let r=t.querySelector(`route[path="${e}"]`);if(r||(c("Creating new route element for:",e),(r=document.createElement("route")).setAttribute("path",e),t.appendChild(r)),!r.innerHTML){c("Fetching content for:",globalThis.location.href);let e=l[globalThis.location.href];e||(e=await u(globalThis.location.href),l[globalThis.location.href]=e);var n,o=(new DOMParser).parseFromString(e,"text/html"),a=o.querySelector("title"),a=(a&&(c("Updating page title to:",a.textContent),document.title=a.textContent),r.innerHTML=o.body.innerHTML,Array.from(r.querySelectorAll("script")));c("Executing",a.length,"scripts from fetched content");for(n of a){var i=document.createElement("script");n.src?i.src=n.src:i.textContent=n.textContent,n.parentNode.replaceChild(i,n)}}t.querySelectorAll("route").forEach(e=>e.style.contentVisibility="hidden"),r.style.contentVisibility="visible",document.body.classList.remove("loading"),window.scrollTo(0,0),d&&d(e),c("Route change completed")},a=async e=>{l[e.href]||(c("Prefetching content for:",e.href),l[e.href]=await u(e.href))},i=(e,r)=>{c("🔍 Intersection Observer triggered for",e.length,"entries"),e.forEach(e=>{var t=e.target;c(`🎯 Link ${t.href} intersection:`,{isIntersecting:e.isIntersecting,intersectionRatio:e.intersectionRatio,alreadyCached:!!l[t.href]}),e.isIntersecting&&(l[t.href]?c("📦 Content already cached for:",t.href):(a(t),c("👁️ Unobserving link after prefetch initiated:",t.href),r.unobserve(t)))})},s=e=>{var t=e.target.closest("A");t&&t.href&&h(t.href)&&t.origin===location.origin?(c("Internal link clicked:",t.href),e.preventDefault(),globalThis.history.pushState(null,null,t.href),globalThis.dispatchEvent(new Event("popstate"))):c("Invalid link click:",t?.href)};function h(e){if(!e||e.startsWith("#")||e.startsWith("javascript:"))return!1;if(e.startsWith("/"))return!0;try{var t=new URL(e,window.location.origin),r=new URL(window.location.href);return r.hostname.replace(/^www\./,"")!==t.hostname.replace(/^www\./,"")?!1:r.pathname!==t.pathname||!t.hash}catch{return!1}}let d,u=async e=>{e=await t(e);return e.ok?e.text():"Couldn't fetch the route - HTTP error! status: "+e.status},t=async e=>{if(!f){var t=await fetch(e,{method:"POST",body:"onlyRoute"});if(t.ok)return t}return fetch(e)},f=!1,e=(e={})=>{var{onRouteChange:t,debug:r}=e,e=(n=r,c("Router starting...",e),t&&(r=t,d=r),document.createElement("style")),t=(e.textContent=".loading{animation:pulse 1s infinite alternate}@keyframes pulse{from{opacity:.6}to{opacity:.1}}route{content-visibility:auto}",document.head.appendChild(e),document.querySelector("router")),r=globalThis.location.pathname,r=(t||(c("Creating new router element"),t=document.createElement("router"),(e=document.createElement("route")).setAttribute("path",r),e.innerHTML=document.body.innerHTML,t.appendChild(e),document.body.innerHTML="",document.body.appendChild(t),f=!0),globalThis.addEventListener("popstate",o),document.addEventListener("click",s),document.body.addEventListener("mouseover",e=>{"A"===e.target.tagName&&"onHover"===e.target.getAttribute("prefetch")&&(async e=>{e=e.target;!l[e.href]&&h(e.href)&&await a(e)})(e)}),new IntersectionObserver(i,{root:null,threshold:.5}));c("🎭 Created Intersection Observer with config:",{root:"viewport",threshold:.5}),(r=>{let n=navigator.connection&&navigator.connection.saveData;var e=document.querySelectorAll("a");c("🔄 Starting link observation...",{totalLinks:e.length,saveDataMode:n}),e.forEach(e=>{var t="onHover"!==e.getAttribute("prefetch")&&!n&&h(e.href);c("🔗 Link evaluation:",{href:e.href,prefetchAttr:e.getAttribute("prefetch"),isInternal:h(e.href),willObserve:t}),t&&(r.observe(e),c("👀 Now observing link:",e.href))})})(r)};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>e()):e()})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lightweight-router",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "main": "src/router.js",
5
5
  "scripts": {
6
6
  "dev": "npx http-server src -o",
package/src/router.js CHANGED
@@ -55,8 +55,8 @@ const handlePopState = async () => {
55
55
  }
56
56
 
57
57
  // Display only the current route
58
- router.querySelectorAll("route").forEach(route => (route.style.display = "none"));
59
- currentRoute.style.display = "contents";
58
+ router.querySelectorAll("route").forEach(route => (route.style.contentVisibility = "hidden"));
59
+ currentRoute.style.contentVisibility = "visible";
60
60
 
61
61
  document.body.classList.remove("loading");
62
62
  window.scrollTo(0, 0);
@@ -76,12 +76,22 @@ const fetchAndSaveContent = async link => {
76
76
  };
77
77
 
78
78
  const handleLinkIntersection = (entries, observer) => {
79
+ log("🔍 Intersection Observer triggered for", entries.length, "entries");
79
80
  entries.forEach(entry => {
81
+ const link = entry.target;
82
+ log(`🎯 Link ${link.href} intersection:`, {
83
+ isIntersecting: entry.isIntersecting,
84
+ intersectionRatio: entry.intersectionRatio,
85
+ alreadyCached: !!linkData[link.href],
86
+ });
87
+
80
88
  if (entry.isIntersecting) {
81
- const link = entry.target;
82
89
  if (!linkData[link.href]) {
83
90
  fetchAndSaveContent(link);
91
+ log("👁️ Unobserving link after prefetch initiated:", link.href);
84
92
  observer.unobserve(link);
93
+ } else {
94
+ log("📦 Content already cached for:", link.href);
85
95
  }
86
96
  }
87
97
  });
@@ -110,8 +120,25 @@ const observeLinks = observer => {
110
120
  const saveDataOn = navigator.connection && navigator.connection.saveData;
111
121
  const links = document.querySelectorAll("a");
112
122
 
123
+ log("🔄 Starting link observation...", {
124
+ totalLinks: links.length,
125
+ saveDataMode: saveDataOn,
126
+ });
127
+
113
128
  links.forEach(link => {
114
- if (link.getAttribute("prefetch") !== "onHover" && !saveDataOn && !isInternalLink(link.href)) observer.observe(link);
129
+ const shouldObserve = link.getAttribute("prefetch") !== "onHover" && !saveDataOn && isInternalLink(link.href);
130
+
131
+ log("🔗 Link evaluation:", {
132
+ href: link.href,
133
+ prefetchAttr: link.getAttribute("prefetch"),
134
+ isInternal: isInternalLink(link.href),
135
+ willObserve: shouldObserve,
136
+ });
137
+
138
+ if (shouldObserve) {
139
+ observer.observe(link);
140
+ log("👀 Now observing link:", link.href);
141
+ }
115
142
  });
116
143
  };
117
144
 
@@ -207,7 +234,15 @@ const startRouter = (options = {}) => {
207
234
  }
208
235
  });
209
236
 
210
- const observer = new IntersectionObserver(handleLinkIntersection, { root: null, threshold: 0.5 });
237
+ const observer = new IntersectionObserver(handleLinkIntersection, {
238
+ root: null,
239
+ threshold: 0.5,
240
+ });
241
+ log("🎭 Created Intersection Observer with config:", {
242
+ root: "viewport",
243
+ threshold: 0.5,
244
+ });
245
+
211
246
  observeLinks(observer);
212
247
  };
213
248