ai-infrastructure-hugg…
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
Service Worker lifecycle, caching strategies, offline patterns, update handling, precaching, runtime caching
$ npx -y skills add agents-inc/skills --skill web-pwa-service-workers --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/web-pwa-service-workersContext preview
The summary Claude sees to decide when to auto-load this skill.
Service Worker lifecycle, caching strategies, offline patterns, update handling, precaching, runtime caching
name: web-pwa-service-workers description: Service Worker lifecycle, caching strategies, offline patterns, update handling, precaching, runtime caching
> **Quick Guide:** A service worker is a programmable network proxy with its own lifecycle: > install precaches, activate cleans up, fetch intercepts. Match the caching strategy to the > content — cache-first for hashed assets, network-first for HTML, stale-while-revalidate for > non-critical API reads. Two details cause most bugs: a response body can be read once, so > `cache.put(request, response.clone())`, and a new worker waits until every tab using the old one > closes, so updates need explicit detection and a user-triggered `skipWaiting`.
**Detailed Resources:**
---
it cache-first, and skip navigation preload; there is nothing to preload.
network-first with a timeout and an offline fallback, and enable navigation preload so the request starts before the worker boots. Follow [examples/caching.md](examples/caching.md) Pattern 8.
---
<critical_requirements>
**Wrap every async lifecycle task in `event.waitUntil()`.** It keeps the worker alive until the promise settles; without it the browser is free to terminate mid-precache.
**Put a version in every cache name and delete the non-current ones during activate.** That is what makes an upgrade clean and keeps storage from growing without bound.
**Clone before caching — `cache.put(request, response.clone())`.** A response body can be consumed once, so caching the original leaves the client with an empty response.
**Let the client decide when a waiting worker takes over.** Detect the waiting worker, tell the user, and call `skipWaiting()` in response to their message, so behaviour never changes underneath an open session.
**Give every fetch path a fallback.** A precached `offline.html` for navigations and a constructed `Response` as the last resort turn a network failure into a page you wrote.
</critical_requirements>
---
**Auto-detection:** navigator.serviceWorker, serviceWorker.register, ServiceWorkerGlobalScope, sw.js, sw.ts, self.skipWaiting, clients.claim, event.waitUntil, event.respondWith, event.preloadResponse, caches.open, caches.match, cache.addAll, CacheStorage, navigationPreload, updateViaCache, controllerchange, updatefound, precache
**Applies to:**
**Handled elsewhere:**
server said, which is a different lifetime from records a user edits offline
and what to show is a product decision
---
<philosophy>
A service worker is a proxy, not a plugin: once installed it sees every request in its scope, and anything it fails to answer, it breaks.
The lifecycle exists to stop two versions running at once. A new worker installs immediately but **waits** until every client controlled by the old one has gone, so one page never runs half the old assets and half the new ones.
Registration → Download → Install → Waiting → Activate → Fetch
↓ ↓
(skipWaiting) (claim)`skipWaiting()` and `clients.claim()` are the two escapes from that guarantee, and both are opt-in for a reason. Reach for them when the user has asked for the update, or when a fix is urgent enough to be worth a mid-session change.
</philosophy>
---
<patterns>
Register with feature detection, check for updates periodically, and track the waiting worker so the UI can offer the update.
const registration = await navigator.serviceWorker.register("/sw.js", {
scope: "/",
updateViaCache: "none", // ask the server for the worker script every time
});
setInterval(() => registration.update(), UPDATE_CHECK_INTERVAL_MS);
registration.addEventListener("updatefound", () => {
const installing = registration.installing;
installing?.addEventListener("statechange", () => {
const isWaiting =
installing.state === "installed" && navigator.serviceWorker.controller;
if (isWaiting) notifyUpdateAvailable();
});
});Full code: [examples/core.md](examples/core.md)
Precache in install, delete superseded caches in activate, and take `skipWaiting` as a message rather than calling it unconditionally.
self.addEventListener("install", (event: ExtendableEvent) => {
event.waitUntil(
caches.open(CACHES.static).then((cache) => cache.addAll(PRECACHE_URLS)),
);
});
self.addEventListener("activate", (event: ExtendableEvent) => {
event.waitUntil(
(async () => {
consThe official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Repo: agents-inc/skills
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production…
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and…
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation,…