@botmesh/core - v2.0.0-alpha.2
    Preparing search index...

    Interface DurabilityConfig

    BotConfig.durability. Every field is optional; {} enables durability with the in-memory backend.

    interface DurabilityConfig {
        backend?: DurabilityBackend;
        journal?: DurabilityBackend;
        instanceId?: string;
        failOpen?: boolean;
        inbox?: {
            leaseMs?: string | number;
            maxAttempts?: number;
            backoff?: RetryBackoff;
            mediaRefs?: boolean;
        };
        outbox?: {
            retries?: number;
            backoff?: RetryBackoff;
            inlineMaxMs?: string
            | number;
            onAmbiguous?: "skip" | "resend";
            maxPayloadBytes?: number;
            leaseMs?: string | number;
            onDiverged?: "send" | "skip";
        };
        pollMs?: string
        | number;
        retention?: string | number;
    }
    Index

    Where the inbox and outbox records live: MemoryDurability, FileDurability, or a store's backend (PostgresStore#durability(), RedisStore#durability(), …). Default: a new MemoryDurability (survives nothing but redeliveries within the process).

    Use DurabilityConfig.backend (same value; the old name of the option). Setting both to different backends throws a ConfigValidationError.

    instanceId?: string

    Lease owner of this process. Keep it STABLE across restarts of the same deployment (a restarted process then reclaims its own in-flight records at once, without waiting for their leases to expire) and UNIQUE per concurrently running replica (two live processes with one id would take each other's leases).

    Default: <hostname>/<botId>/<connectionId> on a single-process backend (memory, file); on a shared backend (Postgres, Redis) that id plus a per-boot suffix, so two processes on one host never share it — a restart then waits for the old leases to expire.

    failOpen?: boolean

    false (default): when the journal cannot record an inbound event, the event is NOT dispatched (fail-closed) — an 'error' is emitted and the dedupe key is released so a transport redelivery is processed. true: dispatch it without the journal.

    inbox?: {
        leaseMs?: string | number;
        maxAttempts?: number;
        backoff?: RetryBackoff;
        mediaRefs?: boolean;
    }

    Type Declaration

    • OptionalleaseMs?: string | number

      Processing lease (heartbeat-extended while the event is running). Default 60_000 ms.

    • OptionalmaxAttempts?: number

      Attempts before an event whose processing keeps failing is dead-lettered. Default 5.

    • Optionalbackoff?: RetryBackoff

      Backoff between failed attempts. Default { baseMs: 1000, capMs: 60000, jitter: 0.2 }.

    • OptionalmediaRefs?: boolean

      Journal a serializable reference to each message's media (IProvider.serializeMediaRef) so a replayed message (crash recovery, background retry) can still download it (IProvider.rehydrateMediaRef). Only applies to providers with those hooks. The reference grants access to the media, like the message body stored next to it. false: journal media tokens as they are, as before (a replayed message may then be unable to download its media). Default true.

    outbox?: {
        retries?: number;
        backoff?: RetryBackoff;
        inlineMaxMs?: string | number;
        onAmbiguous?: "skip" | "resend";
        maxPayloadBytes?: number;
        leaseMs?: string | number;
        onDiverged?: "send" | "skip";
    }

    Type Declaration

    • Optionalretries?: number

      Retries after the first attempt before a send is dead-lettered. Default 5.

    • Optionalbackoff?: RetryBackoff

      Backoff between attempts (a RateLimitedError waits at least its retryAfterMs). Default as inbox.backoff.

    • OptionalinlineMaxMs?: string | number

      How long a ctx.reply / bot.send keeps retrying inline before it rejects with SendDeferredError and leaves the send to the background sweeper. Default '15s'.

    • OptionalonAmbiguous?: "skip" | "resend"

      A send whose outcome is unknown after a crash (the provider was called, the result was never recorded): 'skip' (default) marks it unknown — possible loss, never a duplicate; 'resend' sends it again — never a loss, possible duplicate.

    • OptionalmaxPayloadBytes?: number

      Encoded payloads above this size bypass the outbox (sent directly, with a warning). Default 1 MiB.

    • OptionalleaseMs?: string | number

      Lease of a send in flight (heartbeat-extended while the provider call runs). Default 60_000 ms.

    • OptionalonDiverged?: "send" | "skip"

      A replayed handler whose n-th send differs from the one recorded under the same derived key (<inboundId>:<n>) took another path (e.g. a non-persistent flow lost on a crash): 'send' (default) sends the new content under a new key — never a lost reply; 'skip' answers it with the recorded ref, as if it were the same send. Explicit idempotencyKeys are never compared: the caller names the send.

    pollMs?: string | number

    Background sweeper period (retries, expired leases). Default 1000 ms.

    retention?: string | number

    Keep done/sent records this long before the sweeper purges them. It bounds how long a late transport redelivery is still recognised as a duplicate. Default '7d'; 0 disables purging.