ts / dist / esm / mailbox.d.ts
761 words
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
/**
 * The p2p offline mailbox: deposit an encrypted payload for a room and let
 * a peer that shows up later replay it. This is the catch-up path for peers
 * that are never online at the same time — for js-libp2p/Helia/OrbitDB
 * apps, where encrypted log entries and head CIDs go, keyed by the database
 * address.
 *
 * Unlike the rest of this client these calls do not go to api.ird.ro: they
 * go to the app's own node at `https://<hostname>/mailbox/v1`,
 * authenticated with a short-lived bearer token. Mint one with
 * `credentials` (which wraps `p2p.mintMailboxCredentials`) and pass the
 * returned value as the first argument to `deposit` and `replay`; it
 * carries both the `endpoint` and the `token`. The app needs
 * `mailbox_enabled` — see `p2p.updateApp`.
 *
 * The node stores exactly the bytes you send and holds no keys: encrypt
 * before depositing. Payloads are capped by the app's
 * `mailbox_max_message_kb` (default 64), retained for `mailbox_ttl_hours`
 * (default 24) and bounded by a per-app `mailbox_max_mb` ring buffer — so
 * replayed history can be truncated under you; see `isHistoryGap`.
 */
import type { Client } from './client.js';
import type { Body, Res } from './types.js';
export type MailboxCredentials = Res<'/p2p/apps/{id}/mailbox-credentials', 'post'>['credentials'];
export type MailboxOptions = Readonly<{
    fetch?: typeof fetch;
    timeoutMs?: number;
}>;
export type MailboxPayload = Uint8Array | string | Blob | ReadableStream<Uint8Array>;
export type MailboxMessage = Readonly<{
    /** Opaque ordered token; a string that must stay one (see `isHistoryGap`). */
    seq: string;
    id: string;
    ts: number;
    /** Standard base64; decode with `payloadBytes`. */
    payload: string;
}>;
export type ReplayPage = Readonly<{
    messages: readonly MailboxMessage[];
    has_more: boolean;
    oldest_seq?: string | null;
    latest_seq?: string | null;
}>;
export type DepositResult = Readonly<{
    seq: string;
    id: string;
    expires_at: number;
    deduped: boolean;
}>;
export type ReplayOptions = MailboxOptions & Readonly<{
    /** Replay forward from this seq, exclusive (the usual cursor). */
    after?: string;
    /** Scroll back from this seq, exclusive. */
    before?: string;
    /** Page size, default 100, capped at 500. */
    limit?: number;
}>;
export type ReplayAllOptions = MailboxOptions & Readonly<{
    after?: string;
    limit?: number;
}>;
export type ReplayAllResult = Readonly<{
    messages: readonly MailboxMessage[];
    /** The seq to resume from next time (the last one seen, or the `after` you passed). */
    cursor: string | undefined;
    /** Whether history was truncated before your cursor (checked on the first page). */
    gap: boolean;
}>;
/**
 * Mint a mailbox token for APP-ID and return the credentials directly —
 * `{ token, ttl, expires_at, endpoint, room? }` — ready to pass to
 * `deposit` and `replay`. BODY may scope the token to one `room` and set
 * `ttl_sec` (default 3600, capped at 86400). Mint short and reuse one
 * across calls: every mint is a charged request.
 */
export declare const credentials: (client: Client, appId: string, body?: Body<"/p2p/apps/{id}/mailbox-credentials", "post">) => Promise<MailboxCredentials>;
/**
 * POST /mailbox/v1/rooms/{room}/messages — Deposit PAYLOAD into ROOM for
 * peers that arrive later. Identical payloads deduplicate per room within
 * the retention window (`deduped: true`), so retries are safe and free.
 * Throws an api error whose `code` is the node's, notably
 * "message_too_large" and "node_storage_full".
 */
export declare const deposit: (creds: MailboxCredentials, room: string, payload: MailboxPayload, options?: MailboxOptions) => Promise<DepositResult>;
/**
 * GET /mailbox/v1/rooms/{room}/messages — Replay ROOM, oldest first. Every
 * `seq` is a string and must stay one: it packs a millisecond clock into
 * its high bits, far past what a JSON number survives. There is no
 * server-side ack: the cursor is yours to keep; check it against
 * `oldest_seq` with `isHistoryGap` on every replay.
 */
export declare const replay: (creds: MailboxCredentials, room: string, options?: ReplayOptions) => Promise<ReplayPage>;
/** Decode one replayed message's base64 payload into bytes. */
export declare const payloadBytes: (message: Pick<MailboxMessage, "payload">) => Uint8Array;
/** Decode one replayed message's payload as UTF-8 text (only meaningful for text deposits). */
export declare const payloadString: (message: Pick<MailboxMessage, "payload">) => string;
/**
 * True when CURSOR — the seq you last saw — is older than PAGE's
 * `oldest_seq`, meaning messages were evicted (TTL or the app's ring
 * buffer) between your visits. Report that as truncated history, not as a
 * quiet room. An absent/blank cursor (a first visit) is never a gap.
 */
export declare const isHistoryGap: (cursor: string | null | undefined, page: Pick<ReplayPage, "oldest_seq">) => boolean;
/**
 * Replay ROOM forward from `after` until `has_more` is exhausted,
 * collecting every message. Every page is a charged request, so pass the
 * largest `limit` you can use.
 */
export declare const replayAll: (creds: MailboxCredentials, room: string, options?: ReplayAllOptions) => Promise<ReplayAllResult>;

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/ts.git