JavaScript APIs / oro:latica

oro:latica

oro:latica/* exposes the runtime’s Latica networking primitives, packet helpers, and crypto utilities.

Examples#

Use Latica helpers directly when you are working at the packet and transport layer:

import { sha256 } from 'oro:latica'

const topic = await sha256(new TextEncoder().encode('docs-demo'))

console.log(topic)

API reference#

Module specifiers#

oro:latica
oro:latica/api
oro:latica/cache
oro:latica/encryption
oro:latica/index
oro:latica/nat
oro:latica/packets
oro:latica/proxy
oro:latica/worker

TypeScript declarations#

These declarations are generated from the runtime's published TypeScript surface.

oro:latica#

declare module "oro:latica" {
    export * from "oro:latica/index";
    export default def;
    import def from "oro:latica/index";
}

oro:latica/api#

declare module "oro:latica/api" {
    export default api;
    export type EventEmitter = import("oro:events").EventEmitter;
    /**
     * @typedef {import('../events.js').EventEmitter} EventEmitter
     */
    /**
     * Initializes and returns the network bus.
     *
     * @async
     * @function
     * @param {object} options - Configuration options for the network bus.
     * @param {object} events - A nodejs compatibe implementation of the events module.
     * @param {object} dgram - A nodejs compatible implementation of the dgram module.
     * @returns {Promise<EventEmitter>} - A promise that resolves to the initialized network bus.
     */
    export function api(options: object, events: object, dgram: object): Promise<EventEmitter>;
}

oro:latica/cache#

declare module "oro:latica/cache" {
    /**
     * @typedef {Packet} CacheEntry
     * @typedef {function(CacheEntry, CacheEntry): number} CacheEntrySiblingResolver
     */
    /**
     * Default cache sibling resolver that computes a delta between
     * two entries clocks.
     * @param {CacheEntry} a
     * @param {CacheEntry} b
     * @return {number}
     */
    export function defaultSiblingResolver(a: CacheEntry, b: CacheEntry): number;
    /**
     * Default max size of a `Cache` instance.
     */
    export const DEFAULT_MAX_SIZE: number;
    /**
     * Internal mapping of packet IDs to packet data used by `Cache`.
     */
    export class CacheData extends Map<any, any> {
        constructor();
        constructor(entries?: readonly (readonly [any, any])[]);
        constructor();
        constructor(iterable?: Iterable<readonly [any, any]>);
    }
    /**
     * A class for storing a cache of packets by ID. This class includes a scheme
     * for reconciling disjointed packet caches in a large distributed system. The
     * following are key design characteristics.
     *
     * Space Efficiency: This scheme can be space-efficient because it summarizes
     * the cache's contents in a compact binary format. By sharing these summaries,
     * two computers can quickly determine whether their caches have common data or
     * differences.
     *
     * Bandwidth Efficiency: Sharing summaries instead of the full data can save
     * bandwidth. If the differences between the caches are small, sharing summaries
     * allows for more efficient data synchronization.
     *
     * Time Efficiency: The time efficiency of this scheme depends on the size of
     * the cache and the differences between the two caches. Generating summaries
     * and comparing them can be faster than transferring and comparing the entire
     * dataset, especially for large caches.
     *
     * Complexity: The scheme introduces some complexity due to the need to encode
     * and decode summaries. In some cases, the overhead introduced by this
     * complexity might outweigh the benefits, especially if the caches are
     * relatively small. In this case, you should be using a query.
     *
     * Data Synchronization Needs: The efficiency also depends on the data
     * synchronization needs. If the data needs to be synchronized in real-time,
     * this scheme might not be suitable. It's more appropriate for cases where
     * periodic or batch synchronization is acceptable.
     *
     * Scalability: The scheme's efficiency can vary depending on the scalability
     * of the system. As the number of cache entries or computers involved
     * increases, the complexity of generating and comparing summaries will stay
     * bound to a maximum of 16Mb.
     *
     */
    export class Cache {
        static HASH_SIZE_BYTES: number;
        static HASH_EMPTY: string;
        /**
         * The encodeSummary method provides a compact binary encoding of the output
         * of summary()
         *
         * @param {Object} summary - the output of calling summary()
         * @return {Buffer}
         **/
        static encodeSummary(summary: any): Buffer;
        /**
         * The decodeSummary method decodes the output of encodeSummary()
         *
         * @param {Buffer} bin - the output of calling encodeSummary()
         * @return {Object} summary
         **/
        static decodeSummary(bin: Buffer): any;
        /**
         * Test a summary hash format is valid
         *
         * @param {string} hash
         * @returns boolean
         */
        static isValidSummaryHashFormat(hash: string): boolean;
        /**
         * `Cache` class constructor.
         * @param {CacheData?} [data]
         */
        constructor(data?: CacheData | null, siblingResolver?: typeof defaultSiblingResolver);
        data: CacheData;
        maxSize: number;
        siblingResolver: typeof defaultSiblingResolver;
        /**
         * Readonly count of the number of cache entries.
         * @type {number}
         */
        get size(): number;
        /**
         * Readonly size of the cache in bytes.
         * @type {number}
         */
        get bytes(): number;
        /**
         * Inserts a `CacheEntry` value `v` into the cache at key `k`.
         * @param {string} k
         * @param {CacheEntry} v
         * @return {boolean}
         */
        insert(k: string, v: CacheEntry): boolean;
        /**
         * Gets a `CacheEntry` value at key `k`.
         * @param {string} k
         * @return {CacheEntry?}
         */
        get(k: string): CacheEntry | null;
        /**
         * @param {string} k
         * @return {boolean}
         */
        delete(k: string): boolean;
        /**
         * Predicate to determine if cache contains an entry at key `k`.
         * @param {string} k
         * @return {boolean}
         */
        has(k: string): boolean;
        /**
         * Composes an indexed packet into a new `Packet`
         * @param {Packet} packet
         */
        compose(packet: Packet, source?: CacheData): Promise<Packet>;
        sha1(value: any, toHex: any): Promise<any>;
        /**
         *
         * The summarize method returns a terse yet comparable summary of the cache
         * contents.
         *
         * Think of the cache as a trie of hex characters, the summary returns a
         * checksum for the current level of the trie and for its 16 children.
         *
         * This is similar to a merkel tree as equal subtrees can easily be detected
         * without the need for further recursion. When the subtree checksums are
         * inequivalent then further negotiation at lower levels may be required, this
         * process continues until the two trees become synchonized.
         *
         * When the prefix is empty, the summary will return an array of 16 checksums
         * these checksums provide a way of comparing that subtree with other peers.
         *
         * When a variable-length hexidecimal prefix is provided, then only cache
         * member hashes sharing this prefix will be considered.
         *
         * For each hex character provided in the prefix, the trie will decend by one
         * level, each level divides the 2^128 address space by 16. For exmaple...
         *
         * ```
         * Level  0   1   2
         * ----------------
         * 2b00
         * aa0e  ━┓  ━┓
         * aa1b   ┃   ┃
         * aae3   ┃   ┃  ━┓
         * aaea   ┃   ┃   ┃
         * aaeb   ┃  ━┛  ━┛
         * ab00   ┃  ━┓
         * ab1e   ┃   ┃
         * ab2a   ┃   ┃
         * abef   ┃   ┃
         * abf0  ━┛  ━┛
         * bff9
         * ```
         *
         * @param {string} prefix - a string of lowercased hexidecimal characters
         * @return {Object}
         *
         */
        summarize(prefix?: string, predicate?: () => boolean): any;
    }
    export default Cache;
    export type CacheEntry = Packet;
    export type CacheEntrySiblingResolver = (arg0: CacheEntry, arg1: CacheEntry) => number;
    import { Packet } from "oro:latica/packets";
    import { Buffer } from "oro:buffer";
}

oro:latica/encryption#

declare module "oro:latica/encryption" {
    /**
     * Class for handling encryption and key management.
     */
    export class Encryption {
        /**
         * Creates a shared key based on the provided seed or generates a random one.
         * @param {Uint8Array|string} seed - Seed for key generation.
         * @returns {Promise<Uint8Array>} - Shared key.
         */
        static createSharedKey(seed: Uint8Array | string): Promise<Uint8Array>;
        /**
         * Creates a key pair for signing and verification.
         * @param {Uint8Array|string} seed - Seed for key generation.
         * @returns {Promise<{ publicKey: Uint8Array, privateKey: Uint8Array }>} - Key pair.
         */
        static createKeyPair(seed: Uint8Array | string): Promise<{
            publicKey: Uint8Array;
            privateKey: Uint8Array;
        }>;
        /**
         * Creates an ID using SHA-256 hash.
         * @param {string} str - String to hash.
         * @returns {Promise<Uint8Array>} - SHA-256 hash.
         */
        static createId(str: string): Promise<Uint8Array>;
        /**
         * Creates a cluster ID using SHA-256 hash with specified output size.
         * @param {string} str - String to hash.
         * @returns {Promise<Uint8Array>} - SHA-256 hash with specified output size.
         */
        static createClusterId(str: string): Promise<Uint8Array>;
        /**
         * Signs a message using the given secret key.
         * @param {Buffer} b - The message to sign.
         * @param {Uint8Array} sk - The secret key to use.
         * @returns {Uint8Array} - Signature.
         */
        static sign(b: Buffer, sk: Uint8Array): Uint8Array;
        /**
         * Verifies the signature of a message using the given public key.
         * @param {Buffer} b - The message to verify.
         * @param {Uint8Array} sig - The signature to check.
         * @param {Uint8Array} pk - The public key to use.
         * @returns {number} - Returns non-zero if the buffer could not be verified.
         */
        static verify(b: Buffer, sig: Uint8Array, pk: Uint8Array): number;
        /**
         * Mapping of public keys to key objects.
         * @type {Object.<string, { publicKey: Uint8Array, privateKey: Uint8Array, ts: number }>}
         */
        keys: {
            [x: string]: {
                publicKey: Uint8Array;
                privateKey: Uint8Array;
                ts: number;
            };
        };
        /**
         * Adds a key pair to the keys mapping.
         * @param {Uint8Array|string} publicKey - Public key.
         * @param {Uint8Array} privateKey - Private key.
         */
        add(publicKey: Uint8Array | string, privateKey: Uint8Array): void;
        /**
         * Removes a key from the keys mapping.
         * @param {Uint8Array|string} publicKey - Public key.
         */
        remove(publicKey: Uint8Array | string): void;
        /**
         * Checks if a key is in the keys mapping.
         * @param {Uint8Array|string} to - Public key or Uint8Array.
         * @returns {boolean} - True if the key is present, false otherwise.
         */
        has(to: Uint8Array | string): boolean;
        /**
         * Opens a sealed message using the specified key.
         * @param {Buffer} message - The sealed message.
         * @param {Object|string} v - Key object or public key.
         * @returns {Buffer} - Decrypted message.
         * @throws {Error} - Throws ENOKEY if the key is not found.
         */
        openUnsigned(message: Buffer, v: any | string): Buffer;
        sealUnsigned(message: any, v: any): any;
        /**
         * Decrypts a sealed and signed message for a specific receiver.
         * @param {Buffer} message - The sealed message.
         * @param {Object|string} v - Key object or public key.
         * @returns {Buffer} - Decrypted message.
         * @throws {Error} - Throws ENOKEY if the key is not found, EMALFORMED if the message is malformed, ENOTVERIFIED if the message cannot be verified.
         */
        open(message: Buffer, v: any | string): Buffer;
        /**
         * Seals and signs a message for a specific receiver using their public key.
         *
         * `Seal(message, receiver)` performs an _encrypt-sign-encrypt_ (ESE) on
         * a plaintext `message` for a `receiver` identity. This prevents repudiation
         * attacks and doesn't rely on packet chain guarantees.
         *
         * let ct = Seal(sender | pt, receiver)
         * let sig = Sign(ct, sk)
         * let out = Seal(sig | ct)
         *
         * In an setup between Alice & Bob, this means:
         * - Only Bob sees the plaintext
         * - Alice wrote the plaintext and the ciphertext
         * - Only Bob can see that Alice wrote the plaintext and ciphertext
         * - Bob cannot forward the message without invalidating Alice's signature.
         * - The outer encryption serves to prevent an attacker from replacing Alice's
         *   signature. As with _sign-encrypt-sign (SES), ESE is a variant of
         *   including the recipient's name inside the plaintext, which is then signed
         *   and encrypted Alice signs her plaintext along with her ciphertext, so as
         *   to protect herself from a laintext-substitution attack. At the same time,
         *   Alice's signed plaintext gives Bob non-repudiation.
         *
         * @see https://theworld.com/~dtd/sign_encrypt/sign_encrypt7.html
         *
         * @param {Buffer} message - The message to seal.
         * @param {Object|string} v - Key object or public key.
         * @returns {Buffer} - Sealed message.
         * @throws {Error} - Throws ENOKEY if the key is not found.
         */
        seal(message: Buffer, v: any | string): Buffer;
    }
    import Buffer from "oro:buffer";
}

oro:latica/index#

declare module "oro:latica/index" {
    /**
     * Computes rate limit predicate value for a port and address pair for a given
     * threshold updating an input rates map. This method is accessed concurrently,
     * the rates object makes operations atomic to avoid race conditions.
     *
     * @param {Map} rates
     * @param {number} type
     * @param {number} port
     * @param {string} address
     * @return {boolean}
     */
    export function rateLimit(rates: Map<any, any>, type: number, port: number, address: string, subclusterIdQuota: any): boolean;
    /**
     * Retry delay in milliseconds for ping.
     * @type {number}
     */
    export const PING_RETRY: number;
    /**
     * Probe wait timeout in milliseconds.
     * @type {number}
     */
    export const PROBE_WAIT: number;
    /**
     * Default keep alive timeout.
     * @type {number}
     */
    export const DEFAULT_KEEP_ALIVE: number;
    /**
     * Default rate limit threshold in milliseconds.
     * @type {number}
     */
    export const DEFAULT_RATE_LIMIT_THRESHOLD: number;
    export function getRandomPort(ports: object, p: number | null): number;
    /**
     * A `RemotePeer` represents an initial, discovered, or connected remote peer.
     * Typically, you will not need to create instances of this class directly.
     */
    export class RemotePeer {
        /**
         * `RemotePeer` class constructor.
         * @param {{
         *   peerId?: string,
         *   address?: string,
         *   port?: number,
         *   natType?: number,
         *   clusters: object,
         *   reflectionId?: string,
         *   distance?: number,
         *   publicKey?: string,
         *   privateKey?: string,
         *   clock?: number,
         *   lastUpdate?: number,
         *   lastRequest?: number
         * }} o
         */
        constructor(o: {
            peerId?: string;
            address?: string;
            port?: number;
            natType?: number;
            clusters: object;
            reflectionId?: string;
            distance?: number;
            publicKey?: string;
            privateKey?: string;
            clock?: number;
            lastUpdate?: number;
            lastRequest?: number;
        }, peer: any);
        peerId: any;
        address: any;
        port: number;
        natType: any;
        clusters: {};
        pingId: any;
        distance: number;
        connected: boolean;
        opening: number;
        probed: number;
        proxy: any;
        clock: number;
        uptime: number;
        lastUpdate: number;
        lastRequest: number;
        localPeer: any;
        write(sharedKey: any, args: any): Promise<any[]>;
    }
    /**
     * `Peer` class factory.
     * @param {{ createSocket: function('udp4', null, object?): object }} options
     */
    export class Peer {
        /**
         * Test a peerID is valid
         *
         * @param {string} pid
         * @returns boolean
         */
        static isValidPeerId(pid: string): boolean;
        /**
         * Test a reflectionID is valid
         *
         * @param {string} rid
         * @returns boolean
         */
        static isValidReflectionId(rid: string): boolean;
        /**
         * Test a pingID is valid
         *
         * @param {string} pid
         * @returns boolean
         */
        static isValidPingId(pid: string): boolean;
        /**
         * Returns the online status of the browser, else true.
         *
         * note: globalThis.navigator was added to node in v22.
         *
         * @returns boolean
         */
        static onLine(): boolean;
        /**
         * `Peer` class constructor.
         * @param {object=} opts - Options
         * @param {Buffer} opts.peerId - A 32 byte buffer (ie, `Encryption.createId()`).
         * @param {Buffer} opts.clusterId - A 32 byte buffer (ie, `Encryption.createClusterId()`).
         * @param {number=} opts.port - A port number.
         * @param {number=} opts.probeInternalPort - An internal port number (semi-private for testing).
         * @param {number=} opts.probeExternalPort - An external port number (semi-private for testing).
         * @param {number=} opts.natType - A nat type.
         * @param {string=} opts.address - An ipv4 address.
         * @param {number=} opts.keepalive - The interval of the main loop.
         * @param {function=} opts.siblingResolver - A function that can be used to determine canonical data in case two packets have concurrent clock values.
         * @param {object} dgram - A nodejs compatible implementation of the dgram module (sans multicast).
         */
        constructor(persistedState: {}, dgram: object);
        port: any;
        address: any;
        natType: number;
        nextNatType: number;
        clusters: {};
        syncs: {};
        reflectionId: any;
        reflectionTimeout: any;
        reflectionStage: number;
        reflectionRetry: number;
        reflectionFirstResponder: any;
        peerId: string;
        isListening: boolean;
        ctime: number;
        lastUpdate: number;
        lastSync: number;
        closing: boolean;
        clock: number;
        unpublished: {};
        cache: any;
        uptime: number;
        maxHops: number;
        bdpCache: number[];
        dgram: any;
        onListening: any;
        onDelete: any;
        sendQueue: any[];
        firewall: any;
        rates: Map<any, any>;
        streamBuffer: Map<any, any>;
        gate: Map<any, any>;
        returnRoutes: Map<any, any>;
        metrics: {
            i: {
                0: number;
                1: number;
                2: number;
                3: number;
                4: number;
                5: number;
                6: number;
                7: number;
                8: number;
                DROPPED: number;
            };
            o: {
                0: number;
                1: number;
                2: number;
                3: number;
                4: number;
                5: number;
                6: number;
                7: number;
                8: number;
            };
        };
        peers: any;
        encryption: Encryption;
        config: any;
        _onError: (err: any) => any;
        socket: any;
        probeSocket: any;
        /**
         * An implementation for clearing an interval that can be overridden by the test suite
         * @param Number the number that identifies the timer
         * @return {undefined}
         * @ignore
         */
        _clearInterval(tid: any): undefined;
        /**
         * An implementation for clearing a timeout that can be overridden by the test suite
         * @param Number the number that identifies the timer
         * @return {undefined}
         * @ignore
         */
        _clearTimeout(tid: any): undefined;
        /**
         * An implementation of an internal timer that can be overridden by the test suite
         * @return {Number}
         * @ignore
         */
        _setInterval(fn: any, t: any): number;
        /**
         * An implementation of an timeout timer that can be overridden by the test suite
         * @return {Number}
         * @ignore
         */
        _setTimeout(fn: any, t: any): number;
        _onDebug(...args: any[]): void;
        _stableStringify(value: any): string;
        _cpPayload(type: any, clusterId: any, subclusterId: any, message: any): Uint8Array<any>;
        _applyControlAuth(PacketCtor: any, props: any): any;
        _verifyControlAuth(packet: any): any;
        /**
         * A method that encapsulates the listing procedure
         * @return {undefined}
         * @ignore
         */
        _listen(): undefined;
        init(cb: any): Promise<any>;
        onReady: any;
        mainLoopTimer: number;
        /**
         * Continuously evaluate the state of the peer and its network
         * @return {undefined}
         * @ignore
         */
        _mainLoop(ts: any): undefined;
        /**
         * Enqueue packets to be sent to the network
         * @param {Buffer} data - An encoded packet
         * @param {number} port - The desination port of the remote host
         * @param {string} address - The destination address of the remote host
         * @param {Socket=this.socket} socket - The socket to send on
         * @return {undefined}
         * @ignore
         */
        send(data: Buffer, port: number, address: string, socket?: any): undefined;
        /**
         * @private
         */
        private stream;
        /**
         * @private
         */
        private _scheduleSend;
        sendTimeout: number;
        /**
         * @private
         */
        private _dequeue;
        /**
         * Send any unpublished packets
         * @return {undefined}
         * @ignore
         */
        sendUnpublished(): undefined;
        /**
         * Get the serializable state of the peer (can be passed to the constructor or create method)
         * @return {undefined}
         */
        getState(): undefined;
        getInfo(): Promise<{
            address: any;
            port: any;
            clock: number;
            uptime: number;
            natType: number;
            natName: string;
            peerId: string;
        }>;
        cacheInsert(packet: any): Promise<void>;
        addIndexedPeer(info: any): Promise<void>;
        reconnect(): Promise<void>;
        disconnect(): Promise<void>;
        probeReflectionTimeout: any;
        sealUnsigned(...args: any[]): Promise<any>;
        openUnsigned(...args: any[]): Promise<Buffer>;
        seal(...args: any[]): Promise<Buffer>;
        open(...args: any[]): Promise<Buffer>;
        addEncryptionKey(...args: any[]): Promise<void>;
        /**
         * Get a selection of known peers
         * @return {Array<RemotePeer>}
         * @ignore
         */
        getPeers(packet: any, peers: any, ignorelist: any, filter?: (o: any) => any): Array<RemotePeer>;
        /**
         * Send an eventually consistent packet to a selection of peers (fanout)
         * @return {undefined}
         * @ignore
         */
        mcast(packet: any, ignorelist?: any[]): undefined;
        /**
         * The process of determining this peer's NAT behavior (firewall and dependentness)
         * @return {undefined}
         * @ignore
         */
        requestReflection(): undefined;
        /**
         * Ping another peer
         * @return {PacketPing}
         * @ignore
         */
        ping(peer: any, withRetry: any, props: any, socket: any): PacketPing;
        /**
         * Get a peer
         * @return {RemotePeer}
         * @ignore
         */
        getPeer(id: any): RemotePeer;
        /**
         * This should be called at least once when an app starts to multicast
         * this peer, and starts querying the network to discover peers.
         * @param {object} keys - Created by `Encryption.createKeyPair()`.
         * @param {object=} args - Options
         * @param {number=MAX_BANDWIDTH} args.rateLimit - How many requests per second to allow for this subclusterId.
         * @return {RemotePeer}
         */
        join(sharedKey: any, args?: object | undefined): RemotePeer;
        /**
         * @param {Packet} T - The constructor to be used to create packets.
         * @param {Any} message - The message to be split and packaged.
         * @return {Array<Packet<T>>}
         * @ignore
         */
        _message2packets(T: Packet, message: Any, args: any): Array<Packet<Packet>>;
        /**
         * Sends a packet into the network that will be replicated and buffered.
         * Each peer that receives it will buffer it until TTL and then replicate
         * it provided it has has not exceeded their maximum number of allowed hops.
         *
         * @param {object} keys - the public and private key pair created by `Encryption.createKeyPair()`.
         * @param {object} args - The arguments to be applied.
         * @param {Buffer} args.message - The message to be encrypted by keys and sent.
         * @param {Packet<T>=} args.packet - The previous packet in the packet chain.
         * @param {Buffer} args.usr1 - 32 bytes of arbitrary clusterId in the protocol framing.
         * @param {Buffer} args.usr2 - 32 bytes of arbitrary clusterId in the protocol framing.
         * @return {Array<PacketPublish>}
         */
        publish(sharedKey: any, args: {
            message: Buffer;
            packet?: Packet<T> | undefined;
            usr1: Buffer;
            usr2: Buffer;
        }): Array<PacketPublish>;
        /**
         * @return {undefined}
         */
        sync(peer: any, ptime?: number): undefined;
        close(): void;
        /**
         * Deploy a query into the network
         * @return {undefined}
         *
         */
        query(query: any): undefined;
        /**
         *
         * This is a default implementation for deciding what to summarize
         * from the cache when receiving a request to sync. that can be overridden
         *
         */
        cachePredicate(ts: any): (packet: any) => boolean;
        /**
         * A connection was made, add the peer to the local list of known
         * peers and call the onConnection if it is defined by the user.
         *
         * @return {undefined}
         * @ignore
         */
        _onConnection(packet: any, peerId: any, port: any, address: any, proxy: any, socket: any): undefined;
        /**
         * Received a Sync Packet
         * @return {undefined}
         * @ignore
         */
        _onSync(packet: any, port: any, address: any): undefined;
        /**
         * Received a Query Packet
         *
         * a -> b -> c -> (d) -> c -> b -> a
         *
         * @return {undefined}
         * @example
         *
         * ```js
         * peer.onQuery = (packet) => {
         *   //
         *   // read a database or something
         *   //
         *   return {
         *     message: Buffer.from('hello'),
         *     publicKey: '',
         *     privateKey: ''
         *   }
         * }
         * ```
         */
        _onQuery(packet: any, port: any, address: any): undefined;
        /**
         * Received a Ping Packet
         * @return {undefined}
         * @ignore
         */
        _onPing(packet: any, port: any, address: any): undefined;
        /**
         * Received a Pong Packet
         * @return {undefined}
         * @ignore
         */
        _onPong(packet: any, port: any, address: any): undefined;
        reflectionFirstReponderTimeout: number;
        /**
         * Received an Intro Packet
         * @return {undefined}
         * @ignore
         */
        _onIntro(packet: any, port: any, address: any, _: any, opts?: {
            attempts: number;
        }): undefined;
        socketPool: any[];
        /**
         * Received an Join Packet
         * @return {undefined}
         * @ignore
         */
        _onJoin(packet: any, port: any, address: any, _data: any): undefined;
        /**
         * Received an Publish Packet
         * @return {undefined}
         * @ignore
         */
        _onPublish(packet: any, port: any, address: any, _data: any): undefined;
        /**
         * Received an Stream Packet
         * @return {undefined}
         * @ignore
         */
        _onStream(packet: any, port: any, address: any, _data: any): undefined;
        /**
         * Received any packet on the probe port to determine the firewall:
         * are you port restricted, host restricted, or unrestricted.
         * @return {undefined}
         * @ignore
         */
        _onProbeMessage(data: any, { port, address }: {
            port: any;
            address: any;
        }): undefined;
        /**
         * When a packet is received it is decoded, the packet contains the type
         * of the message. Based on the message type it is routed to a function.
         * like WebSockets, don't answer queries unless we know its another SRP peer.
         *
         * @param {Buffer|Uint8Array} data
         * @param {{ port: number, address: string }} info
         */
        _onMessage(data: Buffer | Uint8Array, { port, address }: {
            port: number;
            address: string;
        }): Promise<undefined>;
    }
    export default Peer;
    import { Packet } from "oro:latica/packets";
    import { sha256 } from "oro:latica/packets";
    import { Cache } from "oro:latica/cache";
    import { Encryption } from "oro:latica/encryption";
    import * as NAT from "oro:latica/nat";
    import { Buffer } from "oro:buffer";
    import { PacketPing } from "oro:latica/packets";
    import { PacketPublish } from "oro:latica/packets";
    export { Packet, sha256, Cache, Encryption, NAT };
}

oro:latica/nat#

declare module "oro:latica/nat" {
    /**
     * The NAT type is encoded using 5 bits:
     *
     * 0b00001 : the lsb indicates if endpoint dependence information is included
     * 0b00010 : the second bit indicates the endpoint dependence value
     *
     * 0b00100 : the third bit indicates if firewall information is included
     * 0b01000 : the fourth bit describes which requests can pass the firewall, only known IPs (0) or any IP (1)
     * 0b10000 : the fifth bit describes which requests can pass the firewall, only known ports (0) or any port (1)
     */
    /**
     * Every remote will see the same IP:PORT mapping for this peer.
     *
     *                        :3333 ┌──────┐
     *   :1111                ┌───▶ │  R1  │
     * ┌──────┐    ┌───────┐  │     └──────┘
     * │  P1  ├───▶│  NAT  ├──┤
     * └──────┘    └───────┘  │     ┌──────┐
     *                        └───▶ │  R2  │
     *                        :3333 └──────┘
     */
    export const MAPPING_ENDPOINT_INDEPENDENT: 3;
    /**
     * Every remote will see a different IP:PORT mapping for this peer.
     *
     *                        :4444 ┌──────┐
     *   :1111                ┌───▶ │  R1  │
     * ┌──────┐    ┌───────┐  │     └──────┘
     * │  P1  ├───▶│  NAT  ├──┤
     * └──────┘    └───────┘  │     ┌──────┐
     *                        └───▶ │  R2  │
     *                        :5555 └──────┘
     */
    export const MAPPING_ENDPOINT_DEPENDENT: 1;
    /**
     * The firewall allows the port mapping to be accessed by:
     * - Any IP:PORT combination (FIREWALL_ALLOW_ANY)
     * - Any PORT on a previously connected IP (FIREWALL_ALLOW_KNOWN_IP)
     * - Only from previously connected IP:PORT combinations (FIREWALL_ALLOW_KNOWN_IP_AND_PORT)
     */
    export const FIREWALL_ALLOW_ANY: 28;
    export const FIREWALL_ALLOW_KNOWN_IP: 12;
    export const FIREWALL_ALLOW_KNOWN_IP_AND_PORT: 4;
    /**
     * The initial state of the nat is unknown and its value is 0
     */
    export const UNKNOWN: 0;
    /**
     * Full-cone NAT, also known as one-to-one NAT
     *
     * Any external host can send packets to iAddr:iPort by sending packets to eAddr:ePort.
     *
     * @summary its a packet party at this mapping and everyone's invited
     */
    export const UNRESTRICTED: number;
    /**
     * (Address)-restricted-cone NAT
     *
     * An external host (hAddr:any) can send packets to iAddr:iPort by sending packets to eAddr:ePort only
     * if iAddr:iPort has previously sent a packet to hAddr:any. "Any" means the port number doesn't matter.
     *
     * @summary The NAT will drop your packets unless a peer within its network has previously messaged you from *any* port.
     */
    export const ADDR_RESTRICTED: number;
    /**
     * Port-restricted cone NAT
     *
     * An external host (hAddr:hPort) can send packets to iAddr:iPort by sending
     * packets to eAddr:ePort only if iAddr:iPort has previously sent a packet to
     * hAddr:hPort.
     *
     * @summary The NAT will drop your packets unless a peer within its network
     * has previously messaged you from this *specific* port.
     */
    export const PORT_RESTRICTED: number;
    /**
     * Symmetric NAT
     *
     * Only an external host that receives a packet from an internal host can send
     * a packet back.
     *
     * @summary The NAT will only accept replies to a correspondence initialized
     * by itself, the mapping it created is only valid for you.
     */
    export const ENDPOINT_RESTRICTED: number;
    export function isEndpointDependenceDefined(nat: any): boolean;
    export function isFirewallDefined(nat: any): boolean;
    export function isValid(nat: any): boolean;
    export function toString(n: any): "UNRESTRICTED" | "ADDR_RESTRICTED" | "PORT_RESTRICTED" | "ENDPOINT_RESTRICTED" | "UNKNOWN";
    export function toStringStrategy(n: any): "STRATEGY_DEFER" | "STRATEGY_DIRECT_CONNECT" | "STRATEGY_TRAVERSAL_OPEN" | "STRATEGY_TRAVERSAL_CONNECT" | "STRATEGY_PROXY" | "STRATEGY_UNKNOWN";
    export const STRATEGY_DEFER: 0;
    export const STRATEGY_DIRECT_CONNECT: 1;
    export const STRATEGY_TRAVERSAL_OPEN: 2;
    export const STRATEGY_TRAVERSAL_CONNECT: 3;
    export const STRATEGY_PROXY: 4;
    export function connectionStrategy(a: any, b: any): 0 | 1 | 2 | 3 | 4;
}

oro:latica/packets#

declare module "oro:latica/packets" {
    /**
     * The magic bytes prefixing every packet. They are the
     * 2nd, 3rd, 5th, and 7th, prime numbers.
     * @type {number[]}
     */
    export const MAGIC_BYTES_PREFIX: number[];
    /**
     * The version of the protocol.
     */
    export const VERSION: 6;
    /**
     * The size in bytes of the prefix magic bytes.
     */
    export const MAGIC_BYTES: 4;
    /**
     * The maximum size of the user message.
     */
    export const MESSAGE_BYTES: 1024;
    /**
     * The cache TTL in milliseconds.
     */
    export const CACHE_TTL: number;
    export namespace PACKET_SPEC {
        namespace type {
            let bytes: number;
            let encoding: string;
        }
        namespace version {
            let bytes_1: number;
            export { bytes_1 as bytes };
            let encoding_1: string;
            export { encoding_1 as encoding };
            export { VERSION as default };
        }
        namespace clock {
            let bytes_2: number;
            export { bytes_2 as bytes };
            let encoding_2: string;
            export { encoding_2 as encoding };
            let _default: number;
            export { _default as default };
        }
        namespace hops {
            let bytes_3: number;
            export { bytes_3 as bytes };
            let encoding_3: string;
            export { encoding_3 as encoding };
            let _default_1: number;
            export { _default_1 as default };
        }
        namespace index {
            let bytes_4: number;
            export { bytes_4 as bytes };
            let encoding_4: string;
            export { encoding_4 as encoding };
            let _default_2: number;
            export { _default_2 as default };
            export let signed: boolean;
        }
        namespace ttl {
            let bytes_5: number;
            export { bytes_5 as bytes };
            let encoding_5: string;
            export { encoding_5 as encoding };
            export { CACHE_TTL as default };
        }
        namespace clusterId {
            let bytes_6: number;
            export { bytes_6 as bytes };
            let encoding_6: string;
            export { encoding_6 as encoding };
            let _default_3: number[];
            export { _default_3 as default };
        }
        namespace subclusterId {
            let bytes_7: number;
            export { bytes_7 as bytes };
            let encoding_7: string;
            export { encoding_7 as encoding };
            let _default_4: number[];
            export { _default_4 as default };
        }
        namespace previousId {
            let bytes_8: number;
            export { bytes_8 as bytes };
            let encoding_8: string;
            export { encoding_8 as encoding };
            let _default_5: number[];
            export { _default_5 as default };
        }
        namespace packetId {
            let bytes_9: number;
            export { bytes_9 as bytes };
            let encoding_9: string;
            export { encoding_9 as encoding };
            let _default_6: number[];
            export { _default_6 as default };
        }
        namespace nextId {
            let bytes_10: number;
            export { bytes_10 as bytes };
            let encoding_10: string;
            export { encoding_10 as encoding };
            let _default_7: number[];
            export { _default_7 as default };
        }
        namespace usr1 {
            let bytes_11: number;
            export { bytes_11 as bytes };
            let _default_8: number[];
            export { _default_8 as default };
        }
        namespace usr2 {
            let bytes_12: number;
            export { bytes_12 as bytes };
            let _default_9: number[];
            export { _default_9 as default };
        }
        namespace usr3 {
            let bytes_13: number;
            export { bytes_13 as bytes };
            let _default_10: number[];
            export { _default_10 as default };
        }
        namespace usr4 {
            let bytes_14: number;
            export { bytes_14 as bytes };
            let _default_11: number[];
            export { _default_11 as default };
        }
        namespace message {
            let bytes_15: number;
            export { bytes_15 as bytes };
            let _default_12: number[];
            export { _default_12 as default };
        }
        namespace sig {
            let bytes_16: number;
            export { bytes_16 as bytes };
            let _default_13: number[];
            export { _default_13 as default };
        }
    }
    /**
     * The size in bytes of the total packet frame and message.
     */
    export const PACKET_BYTES: number;
    /**
     * The maximum distance that a packet can be replicated.
     */
    export const MAX_HOPS: 16;
    export function validateMessage(o: object, constraints: {
        [key: string]: constraint;
    }): void;
    /**
     * Computes a SHA-256 hash of input returning a hex encoded string.
     * @type {function(string|Buffer|Uint8Array): Promise<string>}
     */
    export const sha256: (arg0: string | Buffer | Uint8Array) => Promise<string>;
    export function decode(buf: Buffer): Packet;
    export function getTypeFromBytes(buf: any): any;
    export class Packet {
        static ttl: number;
        static maxLength: number;
        /**
         * Returns an empty `Packet` instance.
         * @return {Packet}
         */
        static empty(): Packet;
        /**
         * @param {Packet|object} packet
         * @return {Packet}
         */
        static from(packet: Packet | object): Packet;
        /**
         * Determines if input is a packet.
         * @param {Buffer|Uint8Array|number[]|object|Packet} packet
         * @return {boolean}
         */
        static isPacket(packet: Buffer | Uint8Array | number[] | object | Packet): boolean;
        /**
         */
        static encode(p: any): Promise<Uint8Array<any>>;
        static decode(buf: any): Packet;
        /**
         * `Packet` class constructor.
         * @param {Packet|object?} options
         */
        constructor(options?: Packet | (object | null));
        /**
         * @param {Packet} packet
         * @return {Packet}
         */
        copy(): Packet;
        timestamp: any;
        isComposed: any;
        isReconciled: any;
        meta: any;
    }
    export class PacketPing extends Packet {
        static type: number;
    }
    export class PacketPong extends Packet {
        static type: number;
    }
    export class PacketIntro extends Packet {
        static type: number;
    }
    export class PacketJoin extends Packet {
        static type: number;
    }
    export class PacketPublish extends Packet {
        static type: number;
    }
    export class PacketStream extends Packet {
        static type: number;
    }
    export class PacketSync extends Packet {
        static type: number;
    }
    export class PacketQuery extends Packet {
        static type: number;
    }
    export default Packet;
    export type constraint = {
        type: string;
        required?: boolean;
        /**
         * optional validator fn returning boolean
         */
        assert?: Function;
    };
    import { Buffer } from "oro:buffer";
}

oro:latica/proxy#

declare module "oro:latica/proxy" {
    export default PeerWorkerProxy;
    /**
     * `Proxy` class factory, returns a Proxy class that is a proxy to the Peer.
     * @param {{ createSocket: function('udp4', null, object?): object }} options
     */
    export class PeerWorkerProxy {
        constructor(options: any, port: any, fn: any);
        init(): Promise<any>;
        reconnect(): Promise<any>;
        disconnect(): Promise<any>;
        getInfo(): Promise<any>;
        getMetrics(): Promise<any>;
        getState(): Promise<any>;
        open(...args: any[]): Promise<any>;
        seal(...args: any[]): Promise<any>;
        sealUnsigned(...args: any[]): Promise<any>;
        openUnsigned(...args: any[]): Promise<any>;
        addEncryptionKey(...args: any[]): Promise<any>;
        send(...args: any[]): Promise<any>;
        sendUnpublished(...args: any[]): Promise<any>;
        cacheInsert(...args: any[]): Promise<any>;
        mcast(...args: any[]): Promise<any>;
        requestReflection(...args: any[]): Promise<any>;
        stream(...args: any[]): Promise<any>;
        join(...args: any[]): Promise<any>;
        publish(...args: any[]): Promise<any>;
        sync(...args: any[]): Promise<any>;
        close(...args: any[]): Promise<any>;
        query(...args: any[]): Promise<any>;
        compileCachePredicate(src: any): Promise<any>;
        callWorkerThread(prop: any, data: any): any;
        callMainThread(prop: any, args: any): void;
        resolveMainThread(seq: any, result: any): any;
        #private;
    }
}

oro:latica/worker#

declare module "oro:latica/worker" {
    export {};
}

See also#

Source repository · Edit this page · View Markdown