Files
2026-05-27 23:47:53 +01:00

2.0 KiB

sync-queue/memory-store.ts

Purpose

Fastest possible SyncQueueStore implementation, backed by a private array. Used as the default in unit tests and as a fallback in environments where neither localStorage nor indexedDB is available (notably inside a Service Worker global scope, where persistence must be managed via Cache or a side channel). Entries are deep-copied on every read and write so callers cannot mutate the store's internal state by retaining a reference.

Features

  • Synchronous semantics wrapped in Promise.resolve so it conforms to the async SyncQueueStore contract identically to the IDB-backed store.
  • Optional seed array for tests that want a pre-populated queue.
  • Defensive copies on load() and save().

Usage: Basic

import { MemoryStore, SyncQueue } from "@suaveplan/pwa";

const queue = new SyncQueue({ store: new MemoryStore() });

Usage: Advanced

Seed a queue with entries that need processing on the very first process() call (useful for replaying a snapshot):

import { MemoryStore } from "@suaveplan/pwa";

const seeded = new MemoryStore([
    {
        id: "sq_1",
        url: "/api/x",
        method: "POST",
        createdAt: Date.now(),
        retryCount: 0,
        maxRetries: 3,
        schemaVersion: 2,
    },
]);

API Reference

  • new MemoryStore(seed?: readonly SyncQueueEntry[]).
  • load(): Promise<Record<string, unknown>[]>.
  • save(entries: readonly SyncQueueEntry[]): Promise<void>.

Implementation Notes

The store always copies entries via { ...e } rather than returning the raw array, so a caller that mutates a returned entry never corrupts the store's internal state. The shallow copy is sufficient because SyncQueueEntry contains only primitives, optional plain records, and optional plain strings — no nested mutable references that need a deeper clone. The synchronous body wrapped in async keeps the interface trivially substitutable with the IDB and LocalStorage stores without any caller-side branching.