Routes in your worker
Send requests for a path through middleware, asked in order or all at once: the cache, the other visitors, the network, or your own.
A service worker answers requests for your assets from this browser's cache, then from the other visitors on your site over WebRTC, and only then from your server. Every visitor who has a file can send it to the next.
npm install peer-cdnconst cache = new CachePlugin();const peers = new DelegatePlugin();const network = new NetworkPlugin();
// This browser's cache, then the other visitors,// then your server, caching what comes backnew PeerCDN() .GET('/assets', ordered, cache.getMiddleware, peers.getMiddleware, network.getMiddleware) .register();// Finds files among the other visitors for the// worker, and shares this browser's cachenew PeerPlugin({ signaling: new SocketChannel(io()), onPeers: (count) => console.log(count, 'visitors'),});
await navigator.serviceWorker.register('/sw.js');import { defineConfig } from 'vite';import { peerCDN } from 'peer-cdn/vite';
// Serves and builds src/sw.ts as /sw.js, and runs// the signaling server on Vite's own serverexport default defineConfig({ plugins: [peerCDN({ worker: 'src/sw.ts' })],});Features
Routes in your worker
Send requests for a path through middleware, asked in order or all at once: the cache, the other visitors, the network, or your own.
Visitors share their cache
Each open page shares what its worker cached, and finds files among the other visitors for its worker, over peer-data data channels.
Careful with what it shares
Only same-origin 200 responses not marked private or no-store. Scripts and stylesheets come from a peer
only when they match the request’s Subresource Integrity metadata.
The network as a fallback
What no cache or visitor has comes from your server. Requests you don’t route are left to the browser.
Vite plugin
peer-cdn/vite bundles your worker into one script for every browser, and runs the signaling server on
Vite’s own server while you develop.
Small and typed
ES modules in strict TypeScript. The worker side has no dependencies; WebRTC stays in the pages.
Try it
Each visitor below has a cache of its own, as a visitor in another browser has. Load the pictures as
Visitor 1 and they come from the server. Load them as Visitor 2 and they come from Visitor 1,
over WebRTC. The visitors found each other through BroadcastChannel, with no signaling server.
Your server has sent 0 pictures.
Looking for other visitors…
Looking for other visitors…
Upgrading
The router, the strategies and the plugins keep their shape. Import them instead of loading a global, bundle the worker, and let PeerPlugin answer the worker by itself.
self.importScripts('/peer-cdn/index.js');const { CachePlugin, NetworkPlugin } = PeerCDN;const { ordered } = PeerCDN.strategies;
const cachePlugin = new CachePlugin({ version: 1 });const networkPlugin = new NetworkPlugin();
const cdn = new PeerCDN();cdn.GET('/css/main.css', ordered, cachePlugin.getMiddleware, networkPlugin.getMiddleware);cdn.register();import { CachePlugin, NetworkPlugin, PeerCDN, ordered } from 'peer-cdn';
const cache = new CachePlugin();const network = new NetworkPlugin();
new PeerCDN() .GET('/css', ordered, cache.getMiddleware, network.getMiddleware) .register();Add a worker, a line to each page and a signaling server. With Vite, the plugin sets up the worker and the server for you.