Changelog
Changelog
v2.0.0 (2026-10-25)
A rewrite in strict TypeScript, on peer-data 4. The migration guide maps every v1 call to its v2 form.
Added
peer-cdn/vite, a Vite plugin. It serves and builds the service worker as one classic script, and runs the signaling server on Vite’s dev and preview servers.SocketChannelandBroadcastChannelSignaling, peer-data’s signaling, are exports of peer-cdn, so pages import everything from it.peerPlugin.fetch(url)asks the connected visitors for a URL yourself.peerPlugin.peersand theonPeersoption tell how many are connected, andpeerPlugin.close()leaves them.- The
maxSizeoption: the largest body PeerPlugin sends to or takes from a peer, 2 MiB by default. A page tells a peer it lacks a larger one. peer-cdn/serverchecks that each socket speaks only for the peer ids it joined with, 16 at most, and routes an offer only into the room its id joined. A page that reconnects gets its id back once the server notices its old socket is gone. It takes an HTTP or HTTPS server.- Types for the whole API, including
Strategy,MiddlewareandMiddlewareFactoryfor writing your own. - A runnable example site in
examples/, and a documentation site with a live demo.
Changed
- peer-cdn is an ES module with types. The UMD build and the
PeerCDNglobal are gone: bundle the worker. orderedandfastestare imports instead ofPeerCDN.strategies, andcdn.GETreturns the router, so calls chain.new CachePlugin({ cacheName })replacesversionandnames. The cache is calledpeer-cdnby default.new DelegatePlugin({ timeout })replacestimeoutAfter.new PeerPlugin({ signaling })takes peer-data signaling, such as aSocketChannelover your own socket.io client, instead of creating one.configurationreplacesservers, andconstraintsis gone.- PeerPlugin answers the worker by itself, and joins one room for every request instead of one per request.
- The signaling server is
attachSignalingfrompeer-cdn/server, on socket.io 4. - A route covers the paths below it, and a
:segment matches any one segment. Of the routes that match, the most specific answers. - Requests that no middleware answers go to the network. Requests off the routes, to other origins, or other than GET are left to the browser, and so are page loads, frames, embedded objects, workers, worklets and XSLT stylesheets on any route: nothing could check what a visitor sent for them.
- Errors in the worker are reported as uncaught, and a middleware that throws counts as a miss.
Fixed
- Peers share responses. v1 sent
Responseobjects over the data channel and throughpostMessage, neither of which can carry one. A page sends each peer one body at a time, and four at most in all, and asks a peer for the next only once the last has arrived. - Peers share only same-origin 200 responses not marked
privateorno-store. DelegatePlugin asks them for images, fonts, audio, video and text tracks, and for scripts, stylesheets and other files only when the request has Subresource Integrity metadata. It drops a response that doesn’t match it, and CachePlugin deletes a cached one that doesn’t, and gives what a peer sent for an image or the like to no other request. fastestanswers with the first response instead of the first middleware to settle, a miss included.- Middleware that missed get their own copy of the response, and the worker answers before they finish storing it.
- CachePlugin answers from its own cache only, and keeps only whole 200 responses not marked
no-store. Options without aversionno longer name its cachepeerfetch-cache-vundefined. - Range requests: a range past the end is cut at the end, a suffix longer than the body gets the whole body, and a range that starts past the end gets 416.
- DelegatePlugin asks another open page when the request’s own page has closed.
Removed
cachePlugin.clearOldCaches(),CachePlugin.peerFetchandcachePlugin.names.- Regular expressions in routes.
peerPlugin.getMiddleware().- The signaling server’s
callbackargument.