Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Security research & red team persistence
- Offline-first web apps
- Fast-loading precompiled assets
- Secure local caching
- Web apps with live updates
- Browser-based CDNs
- function createResolvablePromise() {
- let resolveFunction, rejectFunction;
- const promise = new Promise((resolve, reject) => {
- resolveFunction = resolve;
- rejectFunction = reject;
- });
- return { promise, resolve: resolveFunction, reject: rejectFunction };
- }
- const DB_NAME = '__v0';
- const DB_VERSION = 1;
- const COMPILED_CACHE_NAME = '/__v0_compiled';
- let compiled = null;
- const { promise: compiledPromise, reject: rejectCompiled, resolve: resolveCompiled } = createResolvablePromise();
- async function getDB() {
- return new Promise((resolve, reject) => {
- const request = indexedDB.open(DB_NAME, DB_VERSION);
- request.onupgradeneeded = event => {
- event.target.result.createObjectStore('data');
- };
- request.onsuccess = event => resolve(event.target.result);
- request.onerror = () => reject(request.error);
- });
- }
- // Load cached data from IndexedDB
- getDB().then(db => {
- const tx = db.transaction('data', 'readonly');
- const store = tx.objectStore('data');
- const request = store.get(COMPILED_CACHE_NAME);
- request.onsuccess = event => {
- compiled = event.target.result;
- if (compiled) resolveCompiled();
- };
- });
- self.addEventListener('install', () => self.skipWaiting());
- self.addEventListener('activate', () => self.clients.claim());
- self.addEventListener('fetch', async event => {
- event.respondWith(fetchHandler(event));
- });
- let port2 = null;
- self.addEventListener('message', async event => {
- if (!event.data) return;
- if (event.data.type === 'v0_init') {
- compiled = event.data.compiled;
- if (compiled) resolveCompiled();
- port2 = event.ports[0];
- const db = await getDB();
- const tx = db.transaction('data', 'readwrite');
- const store = tx.objectStore('data');
- store.put(compiled, COMPILED_CACHE_NAME);
- }
- });
- const currentOrigin = self.location.origin;
- async function fetchHandler(event) {
- await compiledPromise;
- if (!compiled || !compiled.staticFiles) return fetch(event.request);
- const url = new URL(event.request.url);
- if (url.origin !== currentOrigin) return fetch(event.request);
- return handleStaticFile(event, url) || fetch(event.request);
- }
- function handleStaticFile(event, url) {
- let resourcePath = url.pathname;
- let maybeResource = compiled.staticFiles[resourcePath] || compiled.staticFiles[resourcePath + '.html'];
- if (!maybeResource) return null;
- if (typeof maybeResource === 'string' || maybeResource.type === 'raw') {
- return new Response(maybeResource.content || maybeResource, {
- headers: { 'Content-Type': getMimeType(resourcePath) },
- });
- }
- if (maybeResource.type === 'url') {
- return fetch(maybeResource.content);
- }
- return null;
- }
- function getMimeType(path) {
- const ext = path.toLowerCase().split('.').pop();
- const mimeTypes = {
- html: 'text/html',
- js: 'text/javascript',
- css: 'text/css',
- json: 'application/json',
- svg: 'image/svg+xml',
- xml: 'application/xml',
- txt: 'text/plain',
- md: 'text/markdown',
- csv: 'text/csv',
- };
- return mimeTypes[ext] || 'text/plain';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement