UNPKG

0x1

Version:

0x1: Lightning-fast web framework for JavaScript/TypeScript with zero overhead and maximum performance, powered by Bun

318 lines (284 loc) 20.4 kB
var{existsSync:N}=(()=>({}));var{create:Q,defineProperty:B,getOwnPropertyDescriptor:U,getOwnPropertyNames:X,getPrototypeOf:Y}=Object,Z=Object.prototype.hasOwnProperty,$=(u,s)=>()=>(s||u((s={exports:{}}).exports,s),s.exports),M=(u,s,d,m)=>{if(s&&typeof s=="object"||typeof s=="function")for(let x of X(s))!Z.call(u,x)&&x!==d&&B(u,x,{get:()=>s[x],enumerable:!(m=U(s,x))||m.enumerable});return u},W=(u,s,d)=>(d=u!=null?Q(Y(u)):{},M(s||!u||!u.__esModule?B(d,"default",{value:u,enumerable:!0}):d,u)),a=$((u,s)=>{function d(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function m(e,t){for(var r="",b=0,h=-1,l=0,A,v=0;v<=e.length;++v){if(v<e.length)A=e.charCodeAt(v);else{if(A===47)break;A=47}if(A===47){if(!(h===v-1||l===1))if(h!==v-1&&l===2){if(r.length<2||b!==2||r.charCodeAt(r.length-1)!==46||r.charCodeAt(r.length-2)!==46){if(r.length>2){var z=r.lastIndexOf("/");if(z!==r.length-1){z===-1?(r="",b=0):(r=r.slice(0,z),b=r.length-1-r.lastIndexOf("/")),h=v,l=0;continue}}else if(r.length===2||r.length===1){r="",b=0,h=v,l=0;continue}}t&&(r.length>0?r+="/..":r="..",b=2)}else r.length>0?r+="/"+e.slice(h+1,v):r=e.slice(h+1,v),b=v-h-1;h=v,l=0}else A===46&&l!==-1?++l:l=-1}return r}function x(e,t){var r=t.dir||t.root,b=t.base||(t.name||"")+(t.ext||"");return r?r===t.root?r+b:r+e+b:b}var y={resolve:function(){for(var e="",t=!1,r,b=arguments.length-1;b>=-1&&!t;b--){var h;b>=0?h=arguments[b]:(r===void 0&&(r=process.cwd()),h=r),d(h),h.length!==0&&(e=h+"/"+e,t=h.charCodeAt(0)===47)}return e=m(e,!t),t?e.length>0?"/"+e:"/":e.length>0?e:"."},normalize:function(e){if(d(e),e.length===0)return".";var t=e.charCodeAt(0)===47,r=e.charCodeAt(e.length-1)===47;return e=m(e,!t),e.length===0&&!t&&(e="."),e.length>0&&r&&(e+="/"),t?"/"+e:e},isAbsolute:function(e){return d(e),e.length>0&&e.charCodeAt(0)===47},join:function(){if(arguments.length===0)return".";for(var e,t=0;t<arguments.length;++t){var r=arguments[t];d(r),r.length>0&&(e===void 0?e=r:e+="/"+r)}return e===void 0?".":y.normalize(e)},relative:function(e,t){if(d(e),d(t),e===t||(e=y.resolve(e),t=y.resolve(t),e===t))return"";for(var r=1;r<e.length&&e.charCodeAt(r)===47;++r);for(var b=e.length,h=b-r,l=1;l<t.length&&t.charCodeAt(l)===47;++l);for(var A=t.length,v=A-l,z=h<v?h:v,_=-1,O=0;O<=z;++O){if(O===z){if(v>z){if(t.charCodeAt(l+O)===47)return t.slice(l+O+1);if(O===0)return t.slice(l+O)}else h>z&&(e.charCodeAt(r+O)===47?_=O:O===0&&(_=0));break}var D=e.charCodeAt(r+O),K=t.charCodeAt(l+O);if(D!==K)break;D===47&&(_=O)}var T="";for(O=r+_+1;O<=b;++O)(O===b||e.charCodeAt(O)===47)&&(T.length===0?T+="..":T+="/..");return T.length>0?T+t.slice(l+_):(l+=_,t.charCodeAt(l)===47&&++l,t.slice(l))},_makeLong:function(e){return e},dirname:function(e){if(d(e),e.length===0)return".";for(var t=e.charCodeAt(0),r=t===47,b=-1,h=!0,l=e.length-1;l>=1;--l)if(t=e.charCodeAt(l),t===47){if(!h){b=l;break}}else h=!1;return b===-1?r?"/":".":r&&b===1?"//":e.slice(0,b)},basename:function(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');d(e);var r=0,b=-1,h=!0,l;if(t!==void 0&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var A=t.length-1,v=-1;for(l=e.length-1;l>=0;--l){var z=e.charCodeAt(l);if(z===47){if(!h){r=l+1;break}}else v===-1&&(h=!1,v=l+1),A>=0&&(z===t.charCodeAt(A)?--A===-1&&(b=l):(A=-1,b=v))}return r===b?b=v:b===-1&&(b=e.length),e.slice(r,b)}else{for(l=e.length-1;l>=0;--l)if(e.charCodeAt(l)===47){if(!h){r=l+1;break}}else b===-1&&(h=!1,b=l+1);return b===-1?"":e.slice(r,b)}},extname:function(e){d(e);for(var t=-1,r=0,b=-1,h=!0,l=0,A=e.length-1;A>=0;--A){var v=e.charCodeAt(A);if(v===47){if(!h){r=A+1;break}continue}b===-1&&(h=!1,b=A+1),v===46?t===-1?t=A:l!==1&&(l=1):t!==-1&&(l=-1)}return t===-1||b===-1||l===0||l===1&&t===b-1&&t===r+1?"":e.slice(t,b)},format:function(e){if(e===null||typeof e!="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return x("/",e)},parse:function(e){d(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(e.length===0)return t;var r=e.charCodeAt(0),b=r===47,h;b?(t.root="/",h=1):h=0;for(var l=-1,A=0,v=-1,z=!0,_=e.length-1,O=0;_>=h;--_){if(r=e.charCodeAt(_),r===47){if(!z){A=_+1;break}continue}v===-1&&(z=!1,v=_+1),r===46?l===-1?l=_:O!==1&&(O=1):l!==-1&&(O=-1)}return l===-1||v===-1||O===0||O===1&&l===v-1&&l===A+1?v!==-1&&(A===0&&b?t.base=t.name=e.slice(1,v):t.base=t.name=e.slice(A,v)):(A===0&&b?(t.name=e.slice(1,l),t.base=e.slice(1,v)):(t.name=e.slice(A,l),t.base=e.slice(A,v)),t.ext=e.slice(l,v)),A>0?t.dir=e.slice(0,A-1):b&&(t.dir="/"),t},sep:"/",delimiter:":",win32:null,posix:null};y.posix=y,s.exports=y}),G=W(a()),k=G,L=G,J=function(u){return u},H=function(){throw new Error("Not implemented")};k.parse??=H;L.parse??=H;var R={resolve:k.resolve.bind(k),normalize:k.normalize.bind(k),isAbsolute:k.isAbsolute.bind(k),join:k.join.bind(k),relative:k.relative.bind(k),toNamespacedPath:J,dirname:k.dirname.bind(k),basename:k.basename.bind(k),extname:k.extname.bind(k),format:k.format.bind(k),parse:k.parse.bind(k),sep:"/",delimiter:":",win32:void 0,posix:void 0,_makeLong:J},q={sep:"\\",delimiter:";",win32:void 0,...R,posix:R};R.win32=q.win32=q;R.posix=R;var{resolve:F,normalize:C,isAbsolute:n,join:E,relative:i,toNamespacedPath:P,dirname:p,basename:f,extname:g,format:c,parse:o,sep:ee,delimiter:re}=R;function j(u){try{let s=u.app?.pwa||{},d=u.pwa||{},m=u.app||{};if(!(d.enabled!==!1&&(s.name||m.name||d.enabled===!0)))return null;return{name:s.name||m.name||m.title||"0x1 App",shortName:s.shortName||V(s.name||m.name||m.title||"0x1"),description:s.description||m.description||"Built with 0x1 - the ultra-minimal framework",themeColor:s.themeColor||"#7c3aed",backgroundColor:s.backgroundColor||"#ffffff",display:s.display||"standalone",statusBarStyle:s.statusBarStyle||"default",startUrl:s.startUrl||"/",orientation:s.orientation||"any",scope:s.scope||"/",iconsPath:s.iconsPath||"/icons",generateIcons:s.generateIcons!==!1,offlineSupport:s.offlineSupport!==!1,cacheStrategy:s.cacheStrategy||"stale-while-revalidate",cacheName:s.cacheName||I(m.name||"0x1-app"),precacheResources:S(s.precacheResources,["/","/index.html","/styles.css","/app.js","/icons/favicon.svg"]),enabled:d.enabled!==!1,manifest:d.manifest||"/manifest.json",workbox:d.workbox,icons:d.icons}}catch(s){return console.warn(`[PWA Config Parser] Error parsing complex config: ${s}`),null}}function V(u){let s=u.split(/[^a-zA-Z0-9]/).filter(Boolean);if(s.length>1)return s.slice(0,4).map((d)=>d.charAt(0).toUpperCase()).join("");else return u.substring(0,Math.min(8,u.length))}function I(u){return`${u.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}-cache-v1`}function S(u,s){let d=[...u||[],...s||[]];return[...new Set(d)]}async function le(u){let s=[u,"0x1.config.ts","0x1.config.js","ox1.config.ts","ox1.config.js"].filter(Boolean);for(let d of s)try{if(!await Bun.file(d).exists())continue;let x=await Bun.file(d).text(),y=w(x);if(y){let e=j(y);if(e)return e}}catch(m){console.warn(`[PWA] Could not load config from ${d}: ${m}`);continue}return null}function w(u){try{let d=u.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"").replace(/import\s+.*?from\s+.*?;/g,"").replace(/export\s+type\s+.*?;/g,"").match(/export\s+default\s+(\{[\s\S]*?\});?\s*$/m);if(!d)return console.warn("[PWA Config Parser] No default export found"),null;let m=d[1];return m=m.replace(/process\.env\.(\w+)/g,(e,t)=>{let r=process.env[t];return r?`"${r}"`:"undefined"}).replace(/process\.env\.(\w+)\s*===\s*["']([^"']+)["']/g,(e,t,r)=>{return process.env[t]===r?"true":"false"}),new Function("console",` // Provide safe console object const process = { env: ${JSON.stringify(process.env)} }; // Return the config object return ${m}; `)(console)}catch(s){return console.warn(`[PWA Config Parser] Failed to parse config: ${s}`),null}}var be={name:"0x1 App",shortName:"0x1",description:"Built with 0x1 - the ultra-minimal framework",themeColor:"#7c3aed",backgroundColor:"#ffffff",display:"standalone",startUrl:"/",orientation:"any",iconsPath:"/icons",generateIcons:!0,offlineSupport:!0,cacheStrategy:"stale-while-revalidate",cacheName:"0x1-cache-v1",statusBarStyle:"default",precacheResources:["/","/index.html","/styles.css","/app.js"]};function de(u,s){let d=u.iconsPath||"/icons",m=[{size:"48x48",purpose:"any"},{size:"72x72",purpose:"any"},{size:"96x96",purpose:"any"},{size:"144x144",purpose:"any"},{size:"192x192",purpose:"any"},{size:"512x512",purpose:"any"},{size:"192x192",purpose:"maskable"},{size:"512x512",purpose:"maskable"}],x=[],y=(r)=>{if(!s)return u.generateIcons!==!1;return[E(s,"public","icons",r),E(s,"icons",r),E(s,"assets","icons",r),E(s,"static","icons",r),E(s,"dist","icons",r),E(s,"build","icons",r)].some((h)=>N(h))};for(let r of m){let b=r.purpose==="maskable"?`maskable-icon-${r.size}.png`:`icon-${r.size}.png`;if(y(b))x.push({src:`${d}/${b}`,sizes:r.size,type:"image/png",purpose:r.purpose})}let e=["icon.svg","icon-512x512.svg"];for(let r of e)if(y(r))x.push({src:`${d}/${r}`,sizes:r==="icon.svg"?"any":"512x512",type:"image/svg+xml",purpose:"any"});if(x.length===0&&u.generateIcons!==!1){let r=[{src:`${d}/icon-192x192.png`,sizes:"192x192",type:"image/png",purpose:"any"},{src:`${d}/icon-512x512.png`,sizes:"512x512",type:"image/png",purpose:"any"}];x.push(...r)}let t={name:u.name,short_name:u.shortName,description:u.description,start_url:u.startUrl||"/",display:u.display,background_color:u.backgroundColor,theme_color:u.themeColor,orientation:u.orientation||"any",icons:x,screenshots:[],id:u.name.toLowerCase().replace(/\s+/g,"-"),dir:"ltr",lang:"en-US",categories:["productivity"],scope:u.scope||"/",prefer_related_applications:!1,shortcuts:[{name:"Home",url:"/",description:"Go to the home page",icons:x.length>0?[{src:`${d}/icon-192x192.png`,sizes:"192x192",type:"image/png"}]:[]}],file_handlers:[],handle_links:"preferred",launch_handler:{client_mode:["navigate-existing","auto"]},display_override:["window-controls-overlay",u.display||"standalone"]};return JSON.stringify(t,null,2)}function he(u){let s=u.cacheName||"0x1-cache-v1",d=JSON.stringify(u.precacheResources||[]),m=u.cacheStrategy||"stale-while-revalidate",x;switch(m){case"cache-first":x=` async function fetchResource(request) { // Try cache first, then network const cachedResponse = await caches.match(request); if (cachedResponse) return cachedResponse; // If not in cache, fetch from network try { const networkResponse = await fetch(request); if (networkResponse.ok) { const cache = await caches.open(CACHE_NAME); cache.put(request, networkResponse.clone()); } return networkResponse; } catch (error) { return new Response('Network error', { status: 408 }); } }`;break;case"network-first":x=` async function fetchResource(request) { // Try network first, then cache try { const networkResponse = await fetch(request); if (networkResponse.ok) { const cache = await caches.open(CACHE_NAME); cache.put(request, networkResponse.clone()); } return networkResponse; } catch (error) { // If network fails, use cache const cachedResponse = await caches.match(request); return cachedResponse || new Response('Network error', { status: 408 }); } }`;break;case"stale-while-revalidate":default:x=` async function fetchResource(request) { // Return cached version immediately (if available) const cache = await caches.open(CACHE_NAME); const cachedResponse = await caches.match(request); // Update cache in background const fetchPromise = fetch(request).then(networkResponse => { if (networkResponse.ok) { cache.put(request, networkResponse.clone()); } return networkResponse; }).catch(() => null); // Return cached version or wait for network return cachedResponse || fetchPromise; }`;break}return`// 0x1 Service Worker // Generated on ${new Date().toISOString()} const CACHE_NAME = '${s}'; const OFFLINE_URL = '/offline.html'; const PRECACHE_RESOURCES = ${d}; // CRITICAL FIX: Validate resources before caching to prevent addAll failures async function validateAndCacheResources(cache, resources) { const validResources = []; for (const url of resources) { try { const response = await fetch(url); if (response.ok) { validResources.push(url); await cache.put(url, response); /* console.log removed */ } else { console.warn('[SW] Resource not found, skipping cache:', url, response.status); } } catch (error) { console.warn('[SW] Failed to fetch resource, skipping cache:', url, error.message); } } /* console.log removed */ return validResources; } // Install event - precache resources with validation self.addEventListener('install', (event) => { event.waitUntil( (async () => { try { const cache = await caches.open(CACHE_NAME); // CRITICAL FIX: Validate resources before attempting to cache them await validateAndCacheResources(cache, PRECACHE_RESOURCES); await self.skipWaiting(); /* console.log removed */ } catch (error) { console.error('[SW] Installation failed:', error); // Still complete installation even if caching fails await self.skipWaiting(); } })() ); }); // Activate event - clean up old caches self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames.filter((name) => { return name !== CACHE_NAME; }).map((name) => { return caches.delete(name); }) ); }).then(() => { return self.clients.claim(); }) ); }); // Fetch event - respond with cache or network ${x} self.addEventListener('fetch', (event) => { // Skip cross-origin requests if (!event.request.url.startsWith(self.location.origin)) { return; } // Handle navigation requests if (event.request.mode === 'navigate') { event.respondWith( fetch(event.request).catch(() => { return caches.match(OFFLINE_URL) || caches.match('/') || new Response('You are offline', { headers: { 'Content-Type': 'text/html' }}); }) ); return; } // Handle other requests with chosen strategy event.respondWith(fetchResource(event.request)); }); // Handle push notifications self.addEventListener('push', (event) => { if (!event.data) return; const data = event.data.json(); const options = { body: data.body, icon: '${u.iconsPath||"/icons"}/icon-192x192.png', badge: '${u.iconsPath||"/icons"}/badge-96x96.png', vibrate: [100, 50, 100], data: { url: data.url || '/' } }; event.waitUntil( self.registration.showNotification(data.title, options) ); }); // Handle notification clicks self.addEventListener('notificationclick', (event) => { event.notification.close(); event.waitUntil( clients.matchAll({type: 'window'}).then((clientList) => { for (const client of clientList) { if ('focus' in client) return client.focus(); } if (clients.openWindow) { return clients.openWindow(event.notification.data.url); } }) ); }); // Periodic sync for background updates self.addEventListener('periodicsync', (event) => { if (event.tag === 'content-sync') { event.waitUntil(syncContent()); } }); async function syncContent() { // Sync content in background when online if (navigator.onLine) { try { const cache = await caches.open(CACHE_NAME); // Update precached resources with validation await validateAndCacheResources(cache, PRECACHE_RESOURCES); } catch (error) { console.error('Background sync failed:', error); } } } `}function ve(){return`// Service Worker Registration if ('serviceWorker' in navigator) { window.addEventListener('load', async () => { try { const registration = await navigator.serviceWorker.register('/service-worker.js', { scope: '/' }); /* console.log removed */ // Setup periodic background sync if supported if ('periodicSync' in registration) { try { await registration.periodicSync.register('content-sync', { minInterval: 24 * 60 * 60 * 1000 // Once per day }); } catch (error) { /* console.log removed */ } } // Register for push notifications if ('PushManager' in window) { // The pushManager property interface allows you to receive notifications from third-party servers const subscribed = await registration.pushManager.getSubscription(); if (!subscribed) { /* console.log removed */ } } } catch (error) { console.error('ServiceWorker registration failed:', error); } }); }`}function Ae(u){return`<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> <title>Offline | ${u.name}</title> <meta name="theme-color" content="${u.themeColor}"> <link rel="manifest" href="/manifest.json"> <link rel="icon" href="/favicon.svg" type="image/svg+xml"> <style> * { box-sizing: border-box; margin: 0; padding: 0; } html, body { height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background-color: ${u.backgroundColor}; color: #333; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 1rem; text-align: center; } .offline-container { max-width: 500px; padding: 2rem; background-color: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } h1 { margin-bottom: 1rem; color: ${u.themeColor}; } p { margin-bottom: 1.5rem; line-height: 1.6; } .icon { margin-bottom: 2rem; width: 80px; height: 80px; } .btn { display: inline-block; padding: 0.75rem 1.5rem; background-color: ${u.themeColor}; color: white; text-decoration: none; border-radius: 4px; font-weight: 500; } </style> </head> <body> <div class="offline-container"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="${u.themeColor}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="1" y1="1" x2="23" y2="23"></line> <path d="M16.72 11.06A10.94 10.94 0 0 1 19 12.55"></path> <path d="M5 12.55a10.94 10.94 0 0 1 5.17-2.39"></path> <path d="M10.71 5.05A16 16 0 0 1 22.58 9"></path> <path d="M1.42 9a15.91 15.91 0 0 1 4.7-2.88"></path> <path d="M8.53 16.11a6 6 0 0 1 6.95 0"></path> <line x1="12" y1="20" x2="12.01" y2="20"></line> </svg> <h1>You're Offline</h1> <p>It looks like you're currently offline. Please check your internet connection and try again.</p> <button class="btn" onclick="window.location.reload()">Retry</button> </div> </body> </html>`}function me(u){}function Oe(u){return{title:u.name,description:u.description,themeColor:u.themeColor,manifest:"/manifest.json",viewport:{width:"device-width",initialScale:1,themeColor:u.themeColor},appleWebApp:{capable:!0,title:u.shortName||u.name,statusBarStyle:u.statusBarStyle||"default"},icons:{icon:[{url:"/icons/icon-192x192.png",sizes:"192x192",type:"image/png"},{url:"/icons/icon-512x512.png",sizes:"512x512",type:"image/png"}],apple:[{url:"/icons/apple-touch-icon.png",sizes:"180x180",type:"image/png"}]}}}export{me as registerPWA,Oe as pwaConfigToMetadata,j as parseComplexPWAConfig,le as loadPWAConfig,ve as generateServiceWorkerRegistration,he as generateServiceWorker,Ae as generateOfflinePage,de as generateManifest,be as DEFAULT_PWA_CONFIG};