/** * @fileoverview Keepalive Manager * @description Global singleton service for managing Service Worker keepalive. * * This module provides a unified interface for acquiring and releasing keepalive * references. Multiple modules can acquire keepalive independently using tags, * and the underlying keepalive mechanism will remain active as long as at least * one reference is held. */ import { createOffscreenKeepaliveController, type KeepaliveController, } from './record-replay-v3/engine/keepalive/offscreen-keepalive'; const LOG_PREFIX = '[KeepaliveManager]'; /** * Singleton keepalive controller instance. * Created lazily to avoid initialization issues during module loading. */ let controller: KeepaliveController | null = null; /** * Get or create the singleton keepalive controller. */ function getController(): KeepaliveController { if (!controller) { controller = createOffscreenKeepaliveController({ logger: console }); console.debug(`${LOG_PREFIX} Controller initialized`); } return controller; } /** * Acquire a keepalive reference with a tag. * * @param tag - Identifier for the reference (e.g., 'native-host', 'rr-engine') * @returns A release function to call when keepalive is no longer needed * * @example * ```typescript * const release = acquireKeepalive('native-host'); * // ... do work that needs SW to stay alive ... * release(); // Release when done * ``` */ export function acquireKeepalive(tag: string): () => void { try { const release = getController().acquire(tag); console.debug(`${LOG_PREFIX} Acquired keepalive for tag: ${tag}`); return () => { try { release(); console.debug(`${LOG_PREFIX} Released keepalive for tag: ${tag}`); } catch (error) { console.warn(`${LOG_PREFIX} Failed to release keepalive for ${tag}:`, error); } }; } catch (error) { console.warn(`${LOG_PREFIX} Failed to acquire keepalive for ${tag}:`, error); return () => {}; } } /** * Check if keepalive is currently active (any references held). */ export function isKeepaliveActive(): boolean { try { return getController().isActive(); } catch { return false; } } /** * Get the current keepalive reference count. * Useful for debugging. */ export function getKeepaliveRefCount(): number { try { return getController().getRefCount(); } catch { return 0; } }