# `cross-origin` — multi-origin Service Worker registration ## Purpose `registerCrossOriginPackedResourceServiceWorker` lets an application register a packed-resource Service Worker hosted on a different origin (typically a CDN subdomain). Before any browser request is dispatched the helper validates the SW URL's origin against a caller-supplied allowlist, so attacker-controlled or misconfigured CDN origins cannot slip past. On success the helper returns both the new registration and the container's current registration list so multi-tenant apps can confirm the CDN-origin SW is actually controlling the page. ## Features - Strict allowlist validation BEFORE `register()` fires - Parses `swUrl` via the `URL` constructor — malformed URLs reject with `PACKER_BROWSER.UNAUTHORIZED_ORIGIN` - Delegates to `registerPackedResourceServiceWorker` so all the underlying contract (AbortSignal, error wrapping, message resolution) remains intact - Returns the full registration list (parity with `clients.matchAll({ includeUncontrolled: true })`) ## Usage: Basic ```ts import { registerCrossOriginPackedResourceServiceWorker } from "@suaveplan/packer-browser/utils"; await registerCrossOriginPackedResourceServiceWorker({ swUrl: "https://cdn.example.com/sw.js", scope: "/packed/", allowedOrigins: ["https://cdn.example.com"], }); ``` ## Usage: Advanced ```ts import { PACKER_BROWSER_CODES, PackerBrowserError, registerCrossOriginPackedResourceServiceWorker, } from "@suaveplan/packer-browser"; try { const { registration, registrations } = await registerCrossOriginPackedResourceServiceWorker({ swUrl: "https://cdn.example.com/sw.js", scope: "/", allowedOrigins: [ "https://cdn.example.com", "https://cdn-fallback.example.com", ], container: navigator.serviceWorker, signal: shutdownController.signal, }); console.log("registered", registration.scope, "of", registrations.length); } catch (err) { if ( err instanceof PackerBrowserError && err.code === PACKER_BROWSER_CODES.UNAUTHORIZED_ORIGIN ) { console.warn("Origin not allowed; falling back to first-party SW."); } } ``` ## API Reference - `registerCrossOriginPackedResourceServiceWorker(opts: RegisterCrossOriginOptions): Promise` - `opts.swUrl: string` — absolute SW URL. Required. - `opts.scope: string` — registration scope. Required. - `opts.allowedOrigins: ReadonlyArray` — exact-string match. Required. - `opts.container?` — injectable container. Default: `navigator.serviceWorker`. - `opts.messageResolver?` — i18n resolver. - `opts.signal?` — AbortSignal forwarded to `register()`. - Returns `{ registration, registrations }`. ## Implementation Notes - Origin equality is exact-string — there is no host-suffix matching. Allowlisting both `https://cdn.example.com` and `https://cdn-fallback.example.com` is explicit by design. - Malformed `swUrl` strings (relative paths, plain identifiers) yield `UNAUTHORIZED_ORIGIN`, not `SW_REGISTRATION_FAILED`, because the helper deliberately rejects before consulting the container. - The `registrations` list is the full `container.getRegistrations()` return value when a container is supplied; without one (e.g. in a Node smoke harness) the underlying `register()` already rejects with `SW_REGISTRATION_FAILED` so the caller never sees a partial list.