import type { ServiceWorkerEventHost } from "./service-worker-runtime.ts"; type NotificationOptions = Parameters< ServiceWorkerEventHost["registration"]["showNotification"] >[1]; type MatchAllOptions = Parameters< ServiceWorkerEventHost["clients"]["matchAll"] >[0]; /** * Adapts a native Service Worker global scope onto the structural * {@link ServiceWorkerEventHost} facade. * * The native `showNotification` call lives here because `src/adapters/web-push` * is the owner of the notification API. The single physical worker entry * (ยง17.1) composes the runtime but never touches the native API itself. */ export type NativeWorkerScope = Readonly<{ location: Readonly<{ origin: string }>; registration: Readonly<{ showNotification(title: string, options: unknown): Promise; }>; clients: Readonly<{ matchAll(options: unknown): Promise; openWindow(url: string): Promise; }>; // Deliberately loose: a native scope declares a richly overloaded listener // signature, and this facade only needs to forward the registration. addEventListener(type: string, listener: never, options?: never): void; removeEventListener(type: string, listener: never, options?: never): void; }>; export function createServiceWorkerScopeHost( scope: NativeWorkerScope, ): ServiceWorkerEventHost { return Object.freeze({ origin: scope.location.origin, registration: Object.freeze({ showNotification: (title: string, options: NotificationOptions) => scope.registration.showNotification(title, { body: options.body, data: options.data, requireInteraction: options.requireInteraction, tag: options.tag, }), }), clients: Object.freeze({ matchAll: (options: MatchAllOptions) => scope.clients.matchAll(options), openWindow: (url: string) => scope.clients.openWindow(url), }), addEventListener: (type, listener) => scope.addEventListener(type, listener as never), removeEventListener: (type, listener) => scope.removeEventListener(type, listener as never), }); }