3.4 KiB
register-service-worker
Purpose
register-service-worker.ts collects four lifecycle helpers exposed via
the /utils subpath: registerPackedResourceServiceWorker,
unregisterPackedResourceServiceWorker, clearServiceWorkerCache, and
getServiceWorkerCacheStatus. They wrap the
navigator.serviceWorker API with typed errors, injectable container
support (for tests), and AbortSignal honoured at every yield. Every
boundary error uses MessageResolver-keyed messages rather than
hard-coded English literals.
Features
- Injectable
container: ServiceWorkerContainerLike— tests pass an in-memory implementation; production defaults tonavigator.serviceWorker. AbortSignalhonoured pre-call (synchronous reject withPackerBrowserError(ABORTED)) and mid-call (channel teardown + reject) on bothclearServiceWorkerCacheandgetServiceWorkerCacheStatus.getServiceWorkerCacheStatusincludes a hard 5-second timeout so a hung controller cannot leak a pending Promise.- Boundary errors:
SW_REGISTRATION_FAILED(no SW support, register rejected, no controller attached),LOAD_FAILED(timeout / negative reply),ABORTED(signal fires). - Returns typed shapes:
ServiceWorkerRegistration,boolean,void,CacheStatusReply.
Usage: Basic
import {
clearServiceWorkerCache,
getServiceWorkerCacheStatus,
registerPackedResourceServiceWorker,
} from "@suaveplan/packer-browser/utils";
await registerPackedResourceServiceWorker();
const status = await getServiceWorkerCacheStatus();
console.log(status.cacheSize, status.urls);
await clearServiceWorkerCache();
Usage: Advanced
import type { ServiceWorkerContainerLike } from "@suaveplan/packer-browser/utils";
const ac = new AbortController();
const recorded: string[] = [];
const container: ServiceWorkerContainerLike = {
controller: createMockController(recorded),
register: async () => fakeRegistration(),
getRegistrations: async () => [],
ready: Promise.resolve(fakeRegistration()),
};
await registerPackedResourceServiceWorker({
container,
scriptUrl: "/custom.js",
signal: ac.signal,
});
API Reference
registerPackedResourceServiceWorker(opts?: RegisterOptions): Promise<ServiceWorkerRegistration>—- throws
SW_REGISTRATION_FAILEDfor no SW support / rejectedregister(). - throws
ABORTEDon a pre-aborted signal.
- throws
unregisterPackedResourceServiceWorker(opts?): Promise<boolean>— resolvesfalsewhen no container is available.clearServiceWorkerCache(opts?): Promise<void>— throwsSW_REGISTRATION_FAILEDif no controller is attached; throwsABORTEDif the signal fires.getServiceWorkerCacheStatus(opts?): Promise<CacheStatusReply>— throwsLOAD_FAILEDon 5 s timeout; throwsABORTEDon signal.ServiceWorkerContainerLike/RegisterOptions/ServiceWorkerLifecycleOptions— type-only injection points.
Implementation Notes
The helpers route every controller.postMessage through a
MessageChannel and listen on port1 for the reply. The
AbortSignal integration closes port1 before rejecting so the
underlying SW does not see a half-open channel. The 5-second
getServiceWorkerCacheStatus timeout is hard-coded because the
upstream form had the same value; Cluster B will widen this once the
SW gains range-request support and a single status query can take
arbitrarily long under load.