Skip to content
Ask
Reference

API Reference

createJobEngine, the producer surface, subscription events, the JobStore contract, memory + RTDB stores, and sweeps.

This page describes the public surface of @inbrowser/resumable.

Exports

Import pathExports
@inbrowser/resumableEverything: createJobEngine, stores (createMemoryJobStore, createIdbJobStore, createRtdbJobStore + token providers), HTTP/client/worker helpers, probeStoreDurability, probeSweepTtl, and related types. Deep subpaths are not part of the public map.

createJobEngine

TS
function createJobEngine<TEvent>(
  opts: CreateJobEngineOpts<TEvent>,
): JobEngine<TEvent>;

CreateJobEngineOpts<TEvent>:

FieldTypeDescription
storeJobStore<TEvent>Required backing store.
loggerLoggerOptional structured logger. Defaults to a silent logger.
sweepSweepScheduleOptional periodic sweep. Requires store.sweepExpired.
now() => numberOptional clock. Defaults to Date.now.

JobEngine<TEvent>:

MethodDescription
start(producer, meta?)Creates a job, drives the producer in the background, and returns { jobId }.
subscribe(jobId, opts?)Returns an async iterable of job events starting at opts.from ?? 0.
get(jobId)Returns the current JobSnapshot<TEvent> or null.
stop()Stops scheduled sweeps and waits for in-flight producers to settle.

Producer

TS
type Producer<TEvent> = (ctx: ProducerCtx) => AsyncIterable<TEvent>;

interface ProducerCtx {
  jobId: string;
  signal: AbortSignal;
}

A producer yields the domain events for a job. If the producer throws, the engine finishes the job with terminal status error and stores the thrown message as the terminal reason.

Subscription Events

TS
type JobEvent<TEvent> =
  | { kind: 'event'; seq: number; value: TEvent }
  | { kind: 'terminal'; status: 'done' | 'error' | 'cancelled'; reason?: string };

The from option is the first sequence number to yield. Events before from are skipped. The terminal marker is yielded once when the job status is no longer running.

Job Metadata And Snapshots

TS
interface JobMeta {
  ttlMs?: number;
  data?: Record<string, unknown>;
}

ttlMs controls post-terminal retention. Running jobs do not expire.

TS
interface JobSnapshot<TEvent> {
  id: string;
  status: 'running' | 'done' | 'error' | 'cancelled';
  reason: string | null;
  events: TEvent[];
  data: Record<string, unknown>;
  createdAt: number;
  updatedAt: number;
  finishedAt: number | null;
  expiresAt: number | null;
}

JobStore<TEvent>

TS
interface JobStore<TEvent> {
  create(meta: JobMeta): Promise<{ jobId: string }>;
  append(jobId: string, seq: number, event: TEvent): Promise<void>;
  finish(
    jobId: string,
    status: 'done' | 'error' | 'cancelled',
    reason?: string,
  ): Promise<void>;
  snapshot(jobId: string): Promise<JobSnapshot<TEvent> | null>;
  watch(
    jobId: string,
    opts?: { from?: number; signal?: AbortSignal },
  ): AsyncIterable<JobSnapshot<TEvent>>;
  delete(jobId: string): Promise<void>;
  sweepExpired?(opts: SweepOpts): Promise<SweepResult>;
}

watch() yields at least one current snapshot when the job exists, then yields again on subsequent mutations. It ends when the signal aborts, the job is deleted, or the backing transport closes.

Memory Store

TS
function createMemoryJobStore<TEvent>(
  opts?: CreateMemoryJobStoreOpts,
): JobStore<TEvent>;

Options:

FieldDescription
defaultTtlMsDefault post-terminal TTL for jobs without meta.ttlMs.
generateIdOptional id generator. Defaults to crypto.randomUUID().
nowOptional clock. Defaults to Date.now.

The memory store is not durable across process restart. It implements sweepExpired.

RTDB Store

TS
function createRtdbJobStore<TEvent>(
  opts: CreateRtdbJobStoreOpts,
): JobStore<TEvent>;

Options:

FieldDescription
urlRTDB base URL, for example https://my-db.firebaseio.com.
authTokenProvider used for REST and SSE requests.
rootPathJob namespace. Defaults to resumable_jobs.
defaultTtlMsDefault post-terminal TTL.
nowOptional clock. Defaults to Date.now.
generateIdOptional id generator. Defaults to crypto.randomUUID().
onWarnOptional callback for non-fatal warnings.

The RTDB layout under {rootPath}/{jobId} stores job metadata at the job root and serialised events at events/{seq}. The store implements sweepExpired.

Token Providers

TS
interface TokenProvider {
  getToken(): Promise<string>;
}

staticTokenProvider(token) returns a fixed bearer token.

serviceAccountTokenProvider(opts) mints and caches OAuth access tokens from a service account JSON file or parsed service account object.

Sweep Types

TS
interface SweepOpts {
  olderThan: number;
  statusFilter?: Array<'done' | 'error' | 'cancelled'>;
  batchSize?: number;
}

interface SweepResult {
  scanned: number;
  deleted: number;
  durationMs: number;
}

Testing Utilities

probeStoreDurability(opts) runs a producer to terminal under one engine, then subscribes from a new engine against the same underlying store data.

probeSweepTtl(opts) verifies that terminal jobs are swept after TTL and that running jobs are not swept.