mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 08:04:45 +00:00
Static-site / SPA nApplets & nSites (Vite/nsyte/CRA/webpack output) rendered as a blank page, then — once that was fixed — as a fast reload-loop blink. Three layered causes, each found on-device via logcat: 1. Sub-path serving. The applet loaded under https://napplet.local/app/, but bundlers emit absolute asset URLs (/assets/app.js, /fonts/…) that resolve against the origin ROOT, so every script/style/font 404'd. nSites are defined to be hosted at the domain root; serve there. 2. Opaque-origin storage. The applet ran in an `allow-scripts`-only iframe, so its origin was opaque ("null"): module scripts + asset fetches were CORS-blocked, and reading localStorage/IndexedDB/serviceWorker threw SecurityError — which crash-loops every SPA (gruuv: "cache version 0 < 23 → reset → reload", forever, because IndexedDB never worked so the version never persisted). Fix: give each applet its OWN real, persistent, isolated origin — a per-applet subdomain https://<id>.napplet.local (id = sha256(author:identifier)), framed by the shell with `allow-scripts allow-same-origin`. A real origin restores localStorage/IndexedDB/SW and makes the applet's own assets same-origin (no CORS). Isolation is preserved because the origin is DISTINCT from the shell's: the native bridge stays origin-restricted to the shell (napplet.local), so the cross-origin applet still can't reach it or read the shell DOM, and per-applet subdomains keep applets' storage isolated from each other. The shell HTML's iframe src + CSP frame-src are bound to the specific applet origin at serve time. Also add an in-memory localStorage/sessionStorage polyfill to the injected shim as belt-and-suspenders for any context where DOM storage is still unavailable. By-design sandbox enforcement is unchanged and correctly blocks the rest (external CDN scripts, direct relay WebSockets via connect-src 'none', external images) — apps must go through the napplet SDK for those. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>