reticulum-js
    Preparing search index...

    Class Resource

    A Reticulum Resource — a fragmented transfer riding on top of an ACTIVE Link.

    Construct with data for the sender side (then await resource.advertise()); or via Resource.accept on the receiver side. Both sides emit progress / complete / failed events, and expose whenComplete() for promise-based consumers.

    Hierarchy

    • EventTarget
      • Resource
    Index
    • Parameters

      • options: {
            autoCompress?: boolean;
            bz2?: Bzip2;
            data?: Uint8Array<ArrayBufferLike>;
            isRequest?: boolean;
            isResponse?: boolean;
            link?: Link;
            metadata?: any;
            originalHash?: Uint8Array<ArrayBufferLike>;
            requestId?: Uint8Array<ArrayBufferLike>;
        } = {}
        • OptionalautoCompress?: boolean
        • Optionalbz2?: Bzip2

          Injected bz2 module; never imported by the library.

        • Optionaldata?: Uint8Array<ArrayBufferLike>

          Sender-side payload.

        • OptionalisRequest?: boolean

          This Resource is a REQUEST body.

        • OptionalisResponse?: boolean

          This Resource is a RESPONSE body.

        • Optionallink?: Link
        • Optionalmetadata?: any

          Sender-side response metadata (§10.4 x flag). Encoded as msgpack and prepended to the payload as 3-byte BE size ‖ packed metadata before hashing/compression, matching the reference implementation's file-with-metadata transfers. Receivers expose the decoded value as Resource.metadata and strip it from Resource.data.

        • OptionaloriginalHash?: Uint8Array<ArrayBufferLike>
        • OptionalrequestId?: Uint8Array<ArrayBufferLike>

          Associated REQUEST id (§11).

      Returns Resource

    _fullPlaintext: Uint8Array<ArrayBufferLike> | undefined
    _gotPartRequests: boolean

    Whether any part request has arrived (sender) — adv vs transfer stall.

    _prepared: boolean

    Whether sender preparation is done.

    _sentPartIndices: Set<any> | undefined
    advSentAt: number

    Epoch ms the current segment's advertisement was (re)sent (sender).

    autoCompress: boolean
    bz2: Bzip2 | undefined
    compressed: boolean
    data: Uint8Array<ArrayBufferLike> | undefined
    encrypted: boolean
    expectedProof: Uint8Array<ArrayBufferLike> | undefined
    fastRateRounds: number = 0

    Consecutive fast windows observed (escalates the ceiling).

    hash: Uint8Array<ArrayBufferLike> | undefined
    hashmap: Uint8Array<ArrayBufferLike>[]
    hasMetadata: boolean
    isRequest: boolean
    isResponse: boolean
    lastActivity: number

    Epoch ms of the last transfer activity in either direction.

    link: Link
    metadata: any

    Response metadata: the decoded value on the receiver (after assembly), or the caller-supplied value on the sender.

    metadataPrefix: Uint8Array<ArrayBufferLike> | undefined

    Sender-side 3-byte BE size ‖ msgpack(metadata) prefix (§10.4). The prefix is part of the hashed/compressed/encrypted blob on the wire.

    originalHash: Uint8Array<ArrayBufferLike> | undefined
    outstanding: number

    Outstanding part requests in the current window (receiver).

    parts: (Uint8Array<ArrayBufferLike> | null)[]
    randomHash: Uint8Array<ArrayBufferLike> | undefined
    receivedCount: number
    reqSentAt: number = 0

    Epoch ms the current window's RESOURCE_REQ went out.

    requestId: Uint8Array<ArrayBufferLike> | undefined
    reqWindowRxd: number = 0

    Part bytes received within the current window.

    retriesLeft: number

    Retries left before the watchdog cancels a stalled transfer.

    segmentIndex: number
    size: number
    split: boolean
    status: number
    totalParts: number
    totalSegments: number
    totalSize: number
    uncompressedSize: number
    verySlowRateRounds: number = 0

    Consecutive very-slow windows observed (drops the ceiling).

    window: number = Resource.WINDOW

    Receiver request window during a transfer.

    windowFlexibility: number = Resource.WINDOW_FLEXIBILITY

    How far the window may drift above the floor before the floor creeps.

    windowMax: number = Resource.WINDOW_MAX_SLOW

    Ceiling the request window grows toward (fast links earn the large one).

    windowMin: number = Resource.WINDOW_MIN

    Floor the request window shrinks to under losses.

    DEFAULT_MAX_PARTS: number = 262144

    Absolute cap on the advertised part count n at accept time. Defends against a single RESOURCE_ADV that advertises a tiny t but a huge n: the receiver allocates new Array(n).fill(null) for the parts, so an unbounded n is a one-packet OOM. Set generously enough that any legitimate transfer up to DEFAULT_MAX_SIZE at the minimum MTU (219 → sdu 183 → ~183k parts for 32 MiB) still fits, with headroom.

    DEFAULT_MAX_SEGMENTS: number = 4096

    Sanity ceiling on an advertised total segment count l.

    DEFAULT_MAX_SIZE: number = ...

    Cap on advertised transfer/logical size at accept time (§10.4 bomb defense).

    DEFAULT_MAX_TOTAL_SIZE: number = ...

    Ceiling on the reassembled logical size of a split Resource — the per-segment t/d caps bound each transfer, this bounds their sum.

    FAST_RATE_THRESHOLD: number = ...

    Consecutive fast windows before the ceiling escalates to fast.

    HASHMAP_FIXED_OVERHEAD: number = 134

    Collision-guard span uses the slow-link window cap (§10.10).

    HEADER_MAX_SIZE: number = 35

    RNS.Packet.HEADER_MAXSIZE — worst-case header after relay HEADER_1→HEADER_2 conversion: flags(1) + hops(1) + transport_id(16) + dest_hash(16) + context(1).

    IFAC_MIN_SIZE: number = 1

    RNS.Reticulum.IFAC_MIN_SIZE — reserved IFAC bytes when computing SDU.

    MAX_EFFICIENT_SIZE: number = ...

    Logical bytes per Resource segment (§10.3). Larger payloads are split into l sequentially-advertised segments tied together by the first segment's hash (o). Segment 1 counts the metadata prefix toward its budget, so its payload share is smaller by the prefix length.

    MAX_RETRIES: number = 16

    Watchdog constants mirroring the Python reference's Resource (MAX_RETRIES, PART_TIMEOUT_FACTOR, PER_RETRY_DELAY, SENDER_GRACE_TIME, PROCESSING_GRACE, RETRY_GRACE_TIME, PROOF_TIMEOUT_FACTOR). The JS watchdog ticks from the link's 1 Hz watchdog instead of a per-resource thread; the semantics — bounded stalls, bounded retries, then a failing cancel that drops the transfer buffers — are the same.

    METADATA_MAX_SIZE: number = 0xffffff

    Max encodable metadata size: 3-byte length prefix limits it to 16 MiB-1.

    PART_TIMEOUT_FACTOR: number = 4

    Multiplier on the expected part-transfer time before a receiver retry.

    PER_RETRY_DELAY: number = 0.5

    Extra per-retry wait (seconds), applied cumulatively (receiver).

    PROCESSING_GRACE: number = 1.0

    Grace over the advertisement timeout (seconds).

    PROOF_TIMEOUT_FACTOR: number = 3

    Multiplier on RTT when waiting for the final proof (vs a full req/resp).

    RANDOM_HASH_SIZE: number = 4

    Size of the throwaway random prefix prepended to the wire body (§10.2 step 3). Distinct from the advertisement r field.

    RATE_FAST: number = ...

    Window rate (bytes/s) considered fast enough for the large window.

    RATE_VERY_SLOW: number = ...

    Window rate (bytes/s) considered very slow.

    RETRY_GRACE_TIME: number = 0.25

    Grace over the part-stall timeout (seconds).

    SENDER_GRACE_TIME: number = 10.0

    Sender grace over the whole request window (seconds).

    VERY_SLOW_RATE_THRESHOLD: number = 2

    Consecutive very-slow windows before the ceiling drops to very slow.

    WINDOW: number = 4

    Initial receiver request window (§10.10).

    WINDOW_FLEXIBILITY: number = 4

    How far the window may drift above the floor before the floor creeps.

    WINDOW_MAX_FAST: number = 75

    Request-window ceiling on fast links (§10.10).

    WINDOW_MAX_SLOW: number = 10

    Request-window ceiling on slow links (§10.10).

    WINDOW_MAX_VERY_SLOW: number = 4

    Request-window ceiling on very slow links (§10.10).

    WINDOW_MIN: number = 2

    Floor the request window shrinks to under losses (§10.10).

    • get collisionGuardSize(): number

      Collision-guard span (§10.2 step 7): map_hashes must be unique within this many parts of any position.

      Returns number

    • get hashmapMaxLen(): number

      Number of 4-byte map_hashes that fit in one advertisement's m field (§10.4): floor((link.mdu - 134) / 4). At the default MDU 431 this is 74.

      Returns number

    • get sdu(): number

      Maximum part body size. Parts are raw slices of the already-encrypted whole, sent as context=RESOURCE packets which are NOT token-encrypted (§10.6 gotcha), so the full SDU is available for part data.

      Returns number

    • Internal

      Called by the link when it transitions to CLOSED: the transfer can never complete, so the resource fails and drops its transfer buffers. Without this a torn-down link is retained by its own resource maps, and the buffers (encrypted payload slices on the sender, accumulated received parts on the receiver) leak for the lifetime of the object — which compounds into multi-GB heap growth when links fail in a storm (the lille-oe OOM of 2026-10-17).

      Parameters

      • Optionalreason: string = "Link closed"

      Returns void

    • Internal

      One watchdog step, driven by the owning link's 1 Hz watchdog tick while the transfer is registered on it (Python Resource.__watchdog_job parity — there it runs as a per-resource thread instead).

      Sender side: an advertisement nobody requested is retried a bounded number of times, then cancelled; a transfer whose part requests dried up is cancelled after the whole retry window (rtt × traffic-timeout × max-retries + grace) elapses with no activity — this also bounds the final proof wait, which Python tightens with PROOF_TIMEOUT_FACTOR (the tighter bound only speeds recovery; the max window already covers it).

      Receiver side: a part stall longer than PART_TIMEOUT_FACTOR × the expected transfer time re-requests the missing parts (resetting the window); exhausted retries cancel the transfer. Without this, a stalled peer on a keepalive-sustained link — alive at the link layer, wedged at the application layer — held its half-received parts (receiver) or its full payload and encrypted part slices (sender) forever: links whose endpoints keep answering keepalives never go stale, so nothing else would ever release the buffers. Each retried sync cycle then accumulated another stalled transfer, compounding into multi-GB heap growth during sync-failure storms.

      Parameters

      • nowMs: number

        Current epoch ms (injected for testability).

      Returns void

    • The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.

      MDN Reference

      Parameters

      • type: string
      • callback: EventListenerOrEventListenerObject | null
      • Optionaloptions: boolean | AddEventListenerOptions

      Returns void

    • Builds and sends the RESOURCE_ADV (§10.4). The link registers this resource as an outgoing transfer keyed by hash.

      Returns Promise<void>

    • Receiver: assembles all parts, link-decrypts, strips the prefix, optional decompress, recomputes the integrity hash, and emits the RESOURCE_PRF (§10.8).

      Returns Promise<void>

    • Cancels the resource. Sender emits RESOURCE_ICL; receiver cancels locally (an ordinary receiver cancel does NOT emit RESOURCE_RCL per §10.9).

      Returns Promise<void>

    • The dispatchEvent() method of the EventTarget sends an Event to the object, (synchronously) invoking the affected event listeners in the appropriate order. The normal event processing rules (including the capturing and optional bubbling phase) also apply to events dispatched manually with dispatchEvent().

      MDN Reference

      Parameters

      • event: Event

      Returns boolean

    • Sender: fulfils an inbound RESOURCE_REQ (§10.5/§10.7) — emits the requested RESOURCE part packets, and a RESOURCE_HMU continuation when the receiver signalled hashmap exhaustion.

      Parameters

      • body: Uint8Array<ArrayBufferLike>

      Returns Promise<void>

    • Receiver: applies a RESOURCE_HMU hashmap continuation (§10.7).

      Parameters

      • body: Uint8Array<ArrayBufferLike>

      Returns Promise<void>

    • Receiver: places an incoming RESOURCE part by matching its 4-byte map_hash against the hashmap (§10.6). Returns true if the part was placed.

      Parameters

      • chunk: Uint8Array<ArrayBufferLike>

      Returns Promise<boolean>

    • The removeEventListener() method of the EventTarget interface removes an event listener previously registered with EventTarget.addEventListener() from the target. The event listener to be removed is identified using a combination of the event type, the event listener function itself, and various optional options that may affect the matching process; see Matching event listeners for removal.

      MDN Reference

      Parameters

      • type: string
      • callback: EventListenerOrEventListenerObject | null
      • Optionaloptions: boolean | EventListenerOptions

      Returns void

    • Receiver: builds and sends the next RESOURCE_REQ for missing parts (§10.5). Windowed stop-and-wait for Phase 2 — requests up to window outstanding missing parts, then waits for them before requesting more.

      Returns Promise<void>

    • Sender: validates a RESOURCE_PRF (§10.8). Body is resource_hash(32) || full_proof(32); full_proof must equal the pre-computed expected_proof.

      Parameters

      • body: Uint8Array<ArrayBufferLike>

      Returns Promise<void>

    • Internal

      Emits a RESOURCE_RCL rejection for a resource hash.

      Parameters

      • link: Link
      • resourceHash: Uint8Array<ArrayBufferLike>

      Returns Promise<void>

    • Accepts an inbound RESOURCE_ADV and prepares to receive parts (§10.4/§10.5).

      Parameters

      • link: Link
      • advertisementPacket: Packet
      • Optionaloptions: { bz2?: Bzip2; maxParts?: number; maxSegments?: number; maxSize?: number } = {}
        • Optionalbz2?: Bzip2
        • OptionalmaxParts?: number

          Reject advertisements whose part count n exceeds this. Defaults to Resource.DEFAULT_MAX_PARTS.

        • OptionalmaxSegments?: number

          Reject split advertisements whose total segment count l exceeds this. Defaults to Resource.DEFAULT_MAX_SEGMENTS.

        • OptionalmaxSize?: number

          Reject advertisements whose t or d exceeds this (§10.4 bomb defense). Defaults to 32 MiB.

      Returns Promise<Resource | null>

      null if the advertisement was rejected.