first commit
This commit is contained in:
87
docs/foundation/data/pwa/src/caching-strategies/router.md
Normal file
87
docs/foundation/data/pwa/src/caching-strategies/router.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# `caching-strategies/router.ts`
|
||||
|
||||
## Purpose
|
||||
|
||||
`Router` evaluates incoming `Request`s against a list of registered routes
|
||||
in order and dispatches the first match to its strategy. The router is the
|
||||
glue between the SW `fetch` event and the package's caching strategies. It
|
||||
owns the default `Cache` and `fetcher` references so individual strategies
|
||||
stay free of global access — strategies receive their `StrategyContext`
|
||||
through the router and need not touch `caches`, `fetch`, or `Date.now`.
|
||||
|
||||
## Features
|
||||
|
||||
- HTTP-method filtering (`GET`, `POST`, `PUT`, …) with case-insensitive
|
||||
comparison.
|
||||
- Three pattern types: `RegExp`, substring `string`, and predicate function
|
||||
(`(Request) => boolean`).
|
||||
- Per-route cache-name override so different routes can write to isolated
|
||||
caches without re-instantiating the router.
|
||||
- Fall-through to `fetcher(request)` for unmatched requests — the router is
|
||||
always safe to `respondWith()` because every request gets a response.
|
||||
- OTel `pwa_cache_strategy_ms` histogram recording strategy latency.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
Router,
|
||||
cacheFirst,
|
||||
networkFirst,
|
||||
staleWhileRevalidate,
|
||||
} from "@suaveplan/pwa";
|
||||
|
||||
const router = new Router({ cacheName: "v1" });
|
||||
router.registerRoute({
|
||||
pattern: /\.(png|jpg|webp)$/,
|
||||
strategy: cacheFirst({ ttlMs: 86_400_000 }),
|
||||
});
|
||||
router.registerRoute({
|
||||
pattern: /\/api\/static\//,
|
||||
strategy: staleWhileRevalidate(),
|
||||
});
|
||||
router.registerRoute({
|
||||
method: "GET",
|
||||
pattern: /\/api\//,
|
||||
strategy: networkFirst({ ttlMs: 30_000 }),
|
||||
});
|
||||
self.addEventListener("fetch", (event) =>
|
||||
event.respondWith(router.handle(event.request))
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Per-route cache + predicate matching:
|
||||
|
||||
```ts
|
||||
import { Router, cacheOnly } from "@suaveplan/pwa";
|
||||
|
||||
const router = new Router();
|
||||
router.registerRoute({
|
||||
method: "GET",
|
||||
pattern: (req) => req.url.startsWith("/offline-fallback/"),
|
||||
strategy: cacheOnly(),
|
||||
cacheName: "offline-fallbacks",
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `new Router(options?: RouterOptions)`.
|
||||
- `registerRoute(route: Route): void`.
|
||||
- `handle(request: Request): Promise<Response>`.
|
||||
- `size: number`.
|
||||
- `Route` — `{ method?, pattern, strategy, cacheName? }`.
|
||||
- `RouterOptions` — `{ cacheStorage?, cacheName?, fetcher?, clock?, observability? }`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The router opens caches lazily via `cacheStorage.open()` on every `handle()`
|
||||
call. The platform `CacheStorage.open()` is idempotent and returns the same
|
||||
underlying `Cache` instance for the same name, so the per-call open is a
|
||||
trivial pointer lookup rather than a heavy initialisation. The fall-through
|
||||
path bypasses both the cache open and the strategy invocation entirely, so
|
||||
unmatched requests pay no per-request cost beyond the linear route scan.
|
||||
For applications with hundreds of routes, the scan can be optimised by the
|
||||
caller via predicate matchers that group routes by URL prefix.
|
||||
Reference in New Issue
Block a user