UNPKG

wxt-zustand

Version:

High-performance Zustand state management for WXT web extensions with seamless cross-tab synchronization and sub-10ms React re-renders

87 lines 3.5 kB
import { createWXTZustandStoreService } from '../background/service'; import { isExtensionContextInvalidated, reloadPageOnInvalidation, } from './errors'; function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } /** * Get a proxy-service client for a given store with retry/backoff. * - Uses only `fetchInitialState`/`dispatch` on the service per design. * - Background→frontend updates should be handled via `storage.watch` separately. */ export async function getBackendServiceWithRetry(storeName, opts = {}) { const [, getService] = createWXTZustandStoreService(storeName); const service = getService(); // Probe connectivity by fetching initial state. If background // has not registered yet, proxy calls may fail; retry with backoff. const maxRetries = opts.retries ?? 5; const baseMs = opts.baseMs ?? 50; let attempt = 0; // Try immediately once, then backoff on failures. // Only the probe is retried; the service instance is synchronous. while (true) { try { // Minimal probe to ensure background registered the service await service.fetchInitialState(); return service; } catch (err) { if (isExtensionContextInvalidated(err)) { reloadPageOnInvalidation(); throw err; } if (attempt >= maxRetries) { console.error(`Failed to connect to WXTZustandStore-${storeName} after ${attempt + 1} attempts.`, err); throw err; } const wait = baseMs * 2 ** attempt; if (attempt === 0) { console.warn(`WXT Zustand: Service not ready for "${storeName}". Retrying up to ${maxRetries}x...`); } await delay(wait); attempt++; } } } /** * Lightweight helper that returns the raw service without probing. * Consumers should prefer `getBackendServiceWithRetry` in most cases. */ export function getBackendService(storeName) { const [, getService] = createWXTZustandStoreService(storeName); return getService(); } /** * Connects to the backend service and returns both the service and the * initial state with retry/backoff. This avoids a double fetch of * `fetchInitialState()` when the caller needs the initial state immediately. */ export async function connectAndFetchInitialState(storeName, opts = {}) { const [, getService] = createWXTZustandStoreService(storeName); const service = getService(); const maxRetries = opts.retries ?? 5; const baseMs = opts.baseMs ?? 50; let attempt = 0; while (true) { try { const initialState = await service.fetchInitialState(); return { service, initialState }; } catch (err) { if (isExtensionContextInvalidated(err)) { reloadPageOnInvalidation(); throw err; } if (attempt >= maxRetries) { console.error(`Failed to fetch initial state for WXTZustandStore-${storeName} after ${attempt + 1} attempts.`, err); throw err; } const wait = baseMs * 2 ** attempt; if (attempt === 0) { console.warn(`WXT Zustand: Initial state not ready for "${storeName}". Retrying up to ${maxRetries}x...`); } await delay(wait); attempt++; } } } //# sourceMappingURL=connect.js.map