Docs
Adapters
Remote Adapter

Remote Adapter

RemoteAdapter keeps dismissal/read state synchronized through your backend API.

Use it when users switch devices and you need consistent state.

Typical integration

featuredrop.config.ts
import { RemoteAdapter } from 'featuredrop/adapters'
 
export const storage = new RemoteAdapter({
  url: '/api/featuredrop',
  userId: 'current-user-id',
  fetchInterval: 300_000,
  requestTimeoutMs: 10_000,
  retryAttempts: 3,
  retryBaseDelayMs: 300,
  retryOnStatuses: [408, 429, 500, 502, 503, 504],
  circuitBreakerThreshold: 5,
  circuitBreakerCooldownMs: 60_000,
  dismissBatchWindowMs: 150,
  syncOnOnline: true,
  syncOnVisibilityChange: true,
  syncIntervalMs: 60_000,
  onError: (error, context) => {
    console.warn('featuredrop remote error', context.operation, context.attempt, error)
  }
})

Expected endpoints

  • GET /api/featuredrop (manifest, optional if you fetch manifest separately)
  • GET /api/featuredrop/state -> { watermark, dismissedIds }
  • POST /api/featuredrop/dismiss with { featureId }
  • POST /api/featuredrop/dismiss-batch with { featureIds } (optional but recommended)
  • POST /api/featuredrop/dismiss-all with { watermark }

Operational notes

  • Adapter retries failed requests with exponential backoff.
  • Parallel fetchManifest() / syncState() calls are coalesced to a single in-flight request.
  • Circuit breaker opens after repeated failures to avoid request storms.
  • Rapid dismiss interactions are batched by dismissBatchWindowMs.
  • Failed queued dismisses are retained and retried on subsequent flushes.
  • Enable syncOnOnline / syncOnVisibilityChange when you want automatic recovery sync after reconnect or tab return.
  • Use await storage.isHealthy() for diagnostics.
  • Use await storage.flushPendingDismisses() before route unloads if you need aggressive durability.
  • Call await storage.destroy() during teardown tests to remove listeners/timers.
⚠️

Keep backend route latency predictable and return explicit non-2xx on failures so retry logic behaves correctly.