diff --git a/src/studio-builder.js b/src/studio-builder.js index b690a2d..6837b83 100644 --- a/src/studio-builder.js +++ b/src/studio-builder.js @@ -123,7 +123,7 @@ function generateShopDappConf(shopName, products) { desc = products[0] ? products[0].description || products[0].name : 'miniMerch shop'; } return JSON.stringify({ - name: shopName || 'miniMerch', + name: safeName(shopName) || 'miniMerch', version: '1.1.0', headline: headline, description: desc, @@ -222,7 +222,7 @@ async function build(products, imagePaths, slippage, shopName, distDir) { if (file === 'dapp.conf') { fs.writeFileSync(dest, generateInboxDappConf()); } else if (file === 'config.js') { - fs.writeFileSync(dest, `const INBOX_CONFIG = { obfuscatedVendorAddress: "${cfg.obfuscated}", appName: "miniMerchInbox", version: "1.0.0" };`); + fs.writeFileSync(dest, `const INBOX_CONFIG = { obfuscatedVendorAddress: "${cfg.obfuscated}", appName: "miniMerchInbox", version: "1.1.0" };`); } else { copyFile(src, dest); } diff --git a/template/shop/sw.js b/template/shop/sw.js index cbbd8eb..7a85b34 100644 --- a/template/shop/sw.js +++ b/template/shop/sw.js @@ -1,33 +1,37 @@ /** * @file Service Worker for miniMerch PWA - * @version 2.0.0 + * @version 2.1.0 */ const CACHE_NAME = 'minimerch-v2'; +// Resolve paths relative to the SW's own location so cache keys match +// the full URLs that Minima serves (e.g. /minidapps/0x1a2b.../style.css). +const BASE = new URL('./', self.location).href; + // Assets to precache — excludes config.js and products.js which are // regenerated on every build and must always be fetched from the network. const PRECACHE_ASSETS = [ - '/', - '/index.html', - '/style.css', - '/app.js', - '/db.js', - '/cart.js', - '/messaging.js', - '/price.js', - '/i18n.js', - '/ui.js', - '/mds.js', - '/icon.svg', - '/favicon.ico', - '/minima_logo.png', - '/minima_logo_bw.svg', - '/usdt_icon.svg' -]; + '', + 'index.html', + 'style.css', + 'app.js', + 'db.js', + 'cart.js', + 'messaging.js', + 'price.js', + 'i18n.js', + 'ui.js', + 'mds.js', + 'icon.svg', + 'favicon.ico', + 'minima_logo.png', + 'minima_logo_bw.svg', + 'usdt_icon.svg', +].map(a => BASE + a); // Files that change on every build — always fetch from network, never cache. -const NETWORK_ONLY = ['/config.js', '/products.js']; +const NETWORK_ONLY_FILES = ['config.js', 'products.js']; // Install event - cache static assets, then skip waiting only after cache is ready self.addEventListener('install', (event) => { @@ -74,10 +78,10 @@ self.addEventListener('fetch', (event) => { if (event.request.method !== 'GET') return; if (event.request.url.includes('/api/')) return; - const url = new URL(event.request.url); + const filename = event.request.url.split('/').pop().split('?')[0]; // Network-only: config.js and products.js are regenerated on every build - if (NETWORK_ONLY.some(p => url.pathname.endsWith(p))) { + if (NETWORK_ONLY_FILES.includes(filename)) { event.respondWith( fetch(event.request).catch(() => new Response('', { status: 503, statusText: 'Service Unavailable' }) @@ -105,7 +109,7 @@ self.addEventListener('fetch', (event) => { }) .catch(() => { if (event.request.headers.get('accept')?.includes('text/html')) { - return caches.match('/index.html'); + return caches.match(BASE + 'index.html'); } return new Response('', { status: 503, statusText: 'Service Unavailable' }); });