/** * Service Worker bootstrap functions for Weft. * * Composable functions that users wire up in their own Service Worker file. * Does NOT auto-register event listeners. * * @module service-worker */ import type { RegistryAgnosticEngine } from '../core/engine'; import type { ServiceWorkerScheduler } from './scheduler.ts'; import type { ServiceWorkerHandlerOptions } from './setup.ts'; import type { MinimalExtendableEvent, MinimalFetchEvent, MinimalPeriodicSyncEvent } from './shared.ts'; export { ServiceWorkerScheduler } from './scheduler.ts'; export type { ServiceWorkerSchedulerOptions } from './scheduler.ts'; export { buildDelegatedRequest, DEFAULT_PERIODIC_SYNC_TAG, normalizePathPrefix } from './shared.ts'; export type { MinimalExtendableEvent, MinimalFetchEvent, MinimalPeriodicSyncEvent, } from './shared.ts'; /** * Options for the Service Worker bootstrap functions * (`createFetchHandler`, `createPeriodicSyncHandler`, `createLifecycleHandlers`). * * Supply the {@link Engine} instance that the service worker should delegate * workflow requests to. Use `pathPrefix` to scope which fetch requests the * handler intercepts (default: `'/weft/'`). * * @example * ```ts * import { createFetchHandler, type ServiceWorkerOptions } from '@lostgradient/weft/service-worker'; * import { Engine, MemoryStorage } from '@lostgradient/weft'; * * const storage = new MemoryStorage(); * const engine = new Engine({ storage }); * * const options: ServiceWorkerOptions = { engine, pathPrefix: '/weft/' }; * const handleFetch = createFetchHandler(options); * // In a Service Worker file: self.addEventListener('fetch', handleFetch); * void handleFetch; * ``` */ export interface ServiceWorkerOptions { /** * The engine this handler delegates workflow requests to. Typed as * {@link RegistryAgnosticEngine} (see its JSDoc) rather than the plain * default `Engine`, so both `new Engine({ storage })` and * `Engine.create({ workflows })` type-check here directly. */ engine: RegistryAgnosticEngine; pathPrefix?: string; /** Handler options supported by the Service Worker runtime. */ handlerOptions?: ServiceWorkerHandlerOptions; } /** * Create a fetch event handler that intercepts requests matching the given * path prefix and delegates them to the Weft HTTP handler. * * The default `pathPrefix` is `'/weft/'`. A trailing slash is auto-appended * when missing, so `'/weft'` and `'/weft/'` behave identically. Requests * whose pathname does not start with the (normalized) prefix are passed * through — the handler simply returns without calling * `event.respondWith`, leaving the request to the next service-worker * listener or the network. Matching requests have the prefix stripped * before delegation: `/weft/v1/health` becomes `/v1/health` for * {@link Engine}. * * @example * ```ts * import { Engine, MemoryStorage } from '@lostgradient/weft'; * import { createFetchHandler } from '@lostgradient/weft/service-worker'; * * const engine = new Engine({ storage: new MemoryStorage() }); * const handler = createFetchHandler({ engine, pathPrefix: '/weft/' }); * * // In your Service Worker: * // self.addEventListener('fetch', handler); * console.log(typeof handler); // 'function' * ``` */ export declare function createFetchHandler(options: ServiceWorkerOptions): (event: MinimalFetchEvent) => void; /** * Create a periodic sync event handler that ticks the scheduler * when the matching tag fires. * * The default `tag` is `'weft-timers'`. Events with non-matching tags are * silently ignored. The returned handler invokes `scheduler.tick()` inside * `event.waitUntil(...)` so the sync extends until the tick promise * resolves. * * @example * ```ts * import { ServiceWorkerScheduler, createPeriodicSyncHandler } from '@lostgradient/weft/service-worker'; * import { MemoryStorage } from '@lostgradient/weft'; * * const storage = new MemoryStorage(); * * const scheduler = new ServiceWorkerScheduler({ * storage, * onTimerFired: (entry) => { * console.log(`Timer ${entry.id} fired.`); * }, * }); * const handler = createPeriodicSyncHandler(scheduler, 'weft-timers'); * // self.addEventListener('periodicsync', handler); * console.log(typeof handler); // 'function' * ``` */ export declare function createPeriodicSyncHandler(scheduler: ServiceWorkerScheduler, tag?: string): (event: MinimalPeriodicSyncEvent) => void; /** * Create install and activate lifecycle event handlers. * * - `install`: Calls `skipWaiting()` so the new Service Worker activates immediately. * - `activate`: Calls `clients.claim()` so open tabs use the new Service Worker. * * Both handlers are defensive: when `skipWaiting` or `clients.claim` are * not present on `globalThis` (e.g. when the module is imported in a unit * test or an environment that is not a Service Worker scope), they silently * fall back to a resolved promise so the import remains safe. * * @example * ```ts * import { createLifecycleHandlers } from '@lostgradient/weft/service-worker'; * * const { install, activate } = createLifecycleHandlers(); * * // In your Service Worker file: * // self.addEventListener('install', install); * // self.addEventListener('activate', activate); * console.log(typeof install, typeof activate); // 'function function' * ``` */ export declare function createLifecycleHandlers(): { install: (event: MinimalExtendableEvent) => void; activate: (event: MinimalExtendableEvent) => void; }; export { setupServiceWorker, type ServiceWorkerHandlerOptions, type SetupServiceWorkerOptions, type SetupServiceWorkerResult, } from './setup.ts';