open-standards/aac/aac-rs/crates/aac-web/static/sw.js
Transaction Science ba1212361f Add aac, map, sandbox standards; catalog the standards family
Commit the previously-untracked standard directories and catalog them in the
root README alongside proof:

- aac/    — communication cargo class: portable boards + a ten-level
            offline-first cascade (Apache-2.0 code / CC-BY-4.0 spec).
- map/    — geospatial cargo class: range-requestable signed tilesets +
            an F0–F4 fidelity cascade (Apache-2.0 code / CC-BY-4.0 spec).
- sandbox/— isolated, metered, attested execution across the heterogeneous
            compute fabric (Apache-2.0 code / CC-BY-4.0 spec).
- jouleclaw-otel-authz, jouleclaw-trust — new jouleclaw reference crates.

Root README now lists aac, map, sandbox, and proof in the catalog, the tree,
and the contribution guide.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-07 17:04:36 -04:00

92 lines
2.7 KiB
JavaScript

// Service Worker for aac.transaction.science — offline-first AAC.
//
// AAC must NEVER fail because of network. This service worker
// caches everything needed for full offline communication.
// Only AI prediction (L3+) requires network, and it's optional.
const CACHE_NAME = 'aac-v1';
const OFFLINE_URL = '/';
// Core assets that must be cached for offline AAC to work.
// Names match the cargo-leptos output (output-name = "aac-web").
const CORE_ASSETS = [
'/',
'/manifest.json',
'/pkg/aac-web.js',
'/pkg/aac-web.wasm',
'/pkg/aac-web.css',
];
// Install: cache core assets
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(CORE_ASSETS))
.then(() => self.skipWaiting())
);
});
// Activate: clean old caches
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys()
.then((keys) => Promise.all(
keys
.filter((key) => key !== CACHE_NAME)
.map((key) => caches.delete(key))
))
.then(() => self.clients.claim())
);
});
// Fetch: cache-first for assets, network-first for API
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
// API calls (prediction, sync) — network first, fall back to cache
if (url.pathname.startsWith('/api/')) {
event.respondWith(
fetch(event.request)
.then((response) => {
const clone = response.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone));
return response;
})
.catch(() => caches.match(event.request))
);
return;
}
// Everything else — cache first (core AAC functionality)
event.respondWith(
caches.match(event.request)
.then((cached) => {
if (cached) {
// Return cache, update in background
fetch(event.request)
.then((response) => {
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, response));
})
.catch(() => {});
return cached;
}
// Not cached — fetch and cache
return fetch(event.request)
.then((response) => {
if (response.status === 200) {
const clone = response.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone));
}
return response;
})
.catch(() => {
// Offline and not cached — return the app shell
if (event.request.mode === 'navigate') {
return caches.match(OFFLINE_URL);
}
return new Response('Offline', { status: 503 });
});
})
);
});