import { CpuTopology, DeckLinkCard, MA35DCard, Nic, NvidiaCard } from "./types"; import { ST2110InputNode, ST2110InputSettings, ST2110OutputNode, ST2110OutputSettings } from "./media_nodes/st2110"; /** * @public */ export interface HardwareInfo { cpuTopology: CpuTopology; systemMemory: number; deckLinkCards: DeckLinkCard[]; ma35dCards: MA35DCard[]; nvidiaCards: NvidiaCard[]; nics: Nic[]; /** Local audio output devices (for {@link NorskOutput.localAudioMonitor}'s * deviceName). Empty when the host has no audio subsystem. */ audioDevices: AudioDevice[]; } /** * @public * One local audio output device. */ export interface AudioDevice { name: string; isDefault: boolean; } /** * @public * Options that affect automatic conversion behaviour (e.g. decode steps * inserted when subscribing between nodes). Only supplied fields are * changed; omitted fields retain their current (or default) values. * Changes take effect on future subscriptions only. */ export interface GlobalOptions { /** Thread count for software video decoders in automatic conversions */ decodeThreadCount?: number; /** Enable low-delay mode for software video decoders in automatic conversions */ decodeLowDelay?: boolean; } /** * Configuration for the shared per-instance iroh endpoint (key-addressed * QUIC: peers dial the endpoint's public key — its NodeId — rather than an * ip:port). All fields optional; unset fields fall back to the * NORSK_IROH_* environment, then defaults (fresh unpersisted identity; * inbound rejected until an allow-list is set). * @public */ export interface IrohEndpointSettings { /** * Path to the identity key file. Load-or-generate: created (mode 0600) * if absent, so the NodeId survives restarts. */ secretKeyFile?: string; /** 'default' (relays + discovery) or 'disabled' (direct paths only). */ relayMode?: 'default' | 'disabled'; /** Verified remote NodeIds (64-char hex) allowed to connect inbound. */ allowedPeers?: string[]; /** Explicit opt-in to accept ANY peer (never the default). */ allowAnyPeer?: boolean; /** Path to an allow-list file (one hex NodeId per line, # comments). */ allowedPeersFile?: string; /** * Self-hosted relay server URLs (https). Setting these uses YOUR relays * and disables n0's discovery services entirely — peers are then reached * via addr hints (`iroh://?addr=`). Mutually exclusive * with relayMode 'disabled'. */ relayUrls?: string[]; } /** @public */ export interface IrohEndpointInfo { /** The endpoint's public key (64-char hex) — dial it as iroh://. */ nodeId: string; /** Bound socket addresses ("ip:port") — direct-dial hints for LAN use. */ directAddrs: string[]; /** 'default' | 'disabled' | 'custom' */ relayMode: string; /** Self-hosted relay URLs when relayMode is 'custom'. */ relayUrls: string[]; allowAnyPeer: boolean; allowedPeers: string[]; connections: number; } /** * One live iroh listener — the shared endpoint (slot 0) or a dedicated * one (matched by the slot configured in irohDedicated). * @public */ export interface IrohListenerInfo { name: string; slot: number; info: IrohEndpointInfo; } /** * Endpoint-level connection event on the shared iroh endpoint — delivered * via the onIrohEndpointEvent SDK setting. remoteNodeId is TLS-verified. * @public */ export interface IrohEndpointEvent { event: 'peer_connected' | 'peer_rejected' | 'peer_disconnected'; remoteNodeId: string; } /** * @public */ export interface NdiSource { name: string; url: string; } /** * @public */ export interface NdiDiscoverySettings { showLocalSources: boolean; groups?: string; extraIps?: string; cb: (sources: NdiSource[]) => void; onClose?: (() => Promise) | (() => void); onError?: (error: Error) => void; } /** * @public */ export declare class NdiDiscovery { close(): void; } /** * @public * Methods that allow you query and update the features of the system that Norsk is running in */ export interface NorskSystem { hardwareInfo(): Promise; /** * Set global options that affect automatic conversion behaviour. * Only supplied fields are changed; omitted fields retain their * current (or default) values. Changes take effect on future * subscriptions only. */ setGlobalOptions(options: GlobalOptions): Promise; /** * Rotate TLS certificates on a running MoQT listener. Existing * connections are unaffected — only new connections use the new cert. */ rotateMoqListenerCerts(type: 'wt' | 'quic', port: number, certFile: string, keyFile: string): Promise<{ success: boolean; error?: string; }>; /** * The shared per-instance iroh endpoint: one key-addressed QUIC identity * (NodeId) that every default iroh dial presents and remote peers dial * into (iroh://). Endpoint-level connection events arrive via * the onIrohEndpointEvent SDK setting. */ iroh: { /** * Start (or return) the shared endpoint. Idempotent: if already * running its info is returned and the config is ignored (first * configuration wins). Rejects on misconfiguration. */ setup(settings: IrohEndpointSettings): Promise; /** Endpoint identity/state (starting it env-configured if needed). */ info(): Promise; /** * Replace the inbound allow-list ('any' to accept every peer). * Revocation is immediate: live connections from delisted peers are * closed. */ setAllowedPeers(peers: string[] | 'any'): Promise; /** * Every live iroh listener's identity — the shared endpoint (slot 0) * plus any dedicated listeners, matched by the slot configured in * `irohDedicated`. The read-back for a dedicated listener's NodeId. */ listeners(): Promise; }; /** * Suppress the "No subscriber for node output, data is being dropped" * warning (and the matching recovery message) for a specific media * node. Use for fallback sources that are expected to spend long * stretches unsubscribed. Suppression state is cleared automatically * when the node exits. */ suppressNoSubscriberWarning(mediaNodeId: string): Promise; /** * Clear a prior `suppressNoSubscriberWarning` for a node. */ unsuppressNoSubscriberWarning(mediaNodeId: string): Promise; ndiDiscovery(settings: NdiDiscoverySettings): Promise; st2110: NorskSystemST2110; } /** * @public * TODO * see: {@link NorskTransform.videoEncode} */ export interface NorskSystemST2110 { node(settings: ST2110NmosNodeSettings): Promise; nic(settings: ST2110NicSettings): Promise; /** * Like `nic`, but resolves once the server-side gen_server is up and * preflight validation has passed — without waiting for MTL_Init / * MTL_Start to finish. Useful for orchestration paths that want * downstream component creation (NMOS devices, senders, receivers) * to overlap with NIC bring-up. The returned NIC's `initialised` * Promise still resolves when MTL is fully ready, if you want to * await it separately before sending or receiving packets. */ nicAfterPreflight(settings: ST2110NicSettings): Promise; /** * Ask the server to pick a NUMA-local set of DPDK lcores for the * given NIC. The server reads the NIC's `local_cpulist` plus the * kernel's `isolcpus` / `nohz_full` sets, so callers don't have to * know the host's CPU topology themselves — handy for tests that * may run on different hardware in CI. * * The returned shape is exactly what `scheduling: { type: "pinned", … }` * on a subsequent `nic()` call expects. * * @public */ recommendCoresFor(settings: { nic: Nic; count: number; }): Promise<{ mainCore: number; otherCores: number[]; }>; } export interface ST2110InternalClock { type: "internal"; name: string; } /** * PTP profile version. `IEEE1588-2008` (PTPv2 — used by SMPTE 2059-2 * and AES67) is the default and what virtually every modern ST 2110 * deployment will report; `IEEE1588-2002` (PTPv1) is legacy. */ export type ST2110PtpVersion = "IEEE1588-2008" | "IEEE1588-2002"; export interface ST2110PtpClock { type: "ptp"; name: string; traceable: boolean; gmid: string; locked: boolean; /** * PTP profile version. Defaults to `"IEEE1588-2008"`. Advertised in * IS-04 node clocks `version` field and as the `` token * in outgoing SDP `ts-refclk:ptp=::` lines. */ version?: ST2110PtpVersion; /** * PTP domain number (0–127). SMPTE 2059-2 typically uses 127. * Defaults to 127. Surfaces in the outgoing SDP * `ts-refclk:ptp=::`. MTL auto-detects the * domain from incoming PTP messages on the wire, so this field is * descriptive — set it to whatever your grandmaster advertises. */ domainNumber?: number; } export type ST2110Clock = ST2110InternalClock | ST2110PtpClock; /** * @public * Settings to create an ST2110 NMOS Node * see: {@link NorskSystemST2110.node} * */ export interface ST2110NmosNodeSettings { label: string; description: string; ip: string; hostname: string; chassisId?: string; clocks: ST2110Clock[]; interfaces?: { name: string; macAddress: string; }[]; tags: { [k: string]: string[]; }; onClose?: (() => Promise) | (() => void); onError?: (error: Error) => void; } /** * @public * see: {@link NorskSystemST2110.node} */ export declare class ST2110NmosNode { createOutputDevice(settings: ST2110OutputSettings): Promise>; createInputDevice(settings: ST2110InputSettings): Promise; } export type ST2110DhcpAddress = { type: "dhcp"; }; export type ST2110StaticAddress = { type: "static"; address: string; }; /** * @public * Settings to create an ST2110 Nic * see: {@link NorskSystemST2110.nic} * */ /** * How MTL schedules its internal tasklets for an ST 2110 NIC. * * - `pinned`: MTL pins each scheduler to its own DPDK lcore. Required * for ST 2110-A (narrow) deterministic timing. Caller supplies the * EAL main lcore and a list of worker lcores; all of them should be * on the same NUMA node as the NIC. * - `free`: Schedulers run as pthreads (MTL_FLAG_TASKLET_THREAD). * Caller supplies only the EAL main lcore. Suitable for ST 2110-C * (wide) and dev/test where strict pinning isn't a goal. * * @public */ export type ST2110SchedulingMode = { type: "pinned"; mainCore: number; otherCores: number[]; } | { type: "free"; mainCore: number; }; export interface ST2110NicSettings { id: string; scheduling: ST2110SchedulingMode; /** * Primary NIC. For a single-port (non-redundant) host this is the * only NIC bound. For ST 2022-7 hitless redundancy also set * `secondaryNic` + `secondaryAddress`. */ nic: Nic; /** * Optional. When set, this MTL instance binds both NICs and every * sender / receiver registered on the host gets a redundant outbound * (or inbound) path on the second NIC. Requires `secondaryAddress` to * be set alongside it. */ secondaryNic?: Nic; numTxQueues: number; numRxQueues: number; address: ST2110DhcpAddress | ST2110StaticAddress; /** * Optional. Required iff `secondaryNic` is set — gives the secondary * NIC its DHCP / static address. The two NICs typically sit on * different subnets (red/blue networks), so the addresses are * configured per-port rather than shared. */ secondaryAddress?: ST2110DhcpAddress | ST2110StaticAddress; /** * Optional ceiling on how long {@link NorskSystemST2110.nic} waits * for the NIC to become usable (MTL_Start complete + all ports' * IP addresses known). Defaults to 30000 ms. Override upward for * slow-boot deployments where PTP convergence or DHCP takes * longer; downward for tight failover scenarios where you'd rather * fail fast than block. */ initialiseTimeoutMs?: number; /** * Hugetlbfs mount path that this NIC's DPDK primary should use as * `--huge-dir`. Required when more than one DPDK primary runs in the * same norsk instance (e.g. norsk-core's allocator plus multiple ST * 2110 NICs); EAL takes an exclusive flock on the hugetlbfs mount * root during init, so each primary needs its own mount. The path * must be a hugetlbfs mount provided by the operator at host / * container setup time — norsk does not create it. * * Leave undefined when this is the only DPDK primary in the * container, in which case EAL picks a default mount. */ hugeDir?: string; onClose?: (() => Promise) | (() => void); onError?: (error: Error) => void; /** * Called whenever the NIC's bring-up advances to a new stage. Mirrors * the proto `ST2110NicStageChanged` sequence: "initialising" → * "loadingHost" → "waitingMtl" → "ready"; or "failed" with a `reason` * if any phase rejects. The `nic()` promise still resolves on the * legacy `mtl_ready` signal — this callback is purely for progress * reporting (UI status, structured logs). */ onStageChange?: (event: ST2110NicStageEvent) => void; } /** * @public * NIC bring-up lifecycle stage. The sequence is: * * "initialising" — supervisor's gen_server is up; pre-flight checks * passed; heavy work queued via self-message * "loadingHost" — spawning the isox plugin host OS process * "waitingMtl" — MTL_Init / DPDK / NIC ramp running inside the host; * awaiting completion * "ready" — MTL up and accepting per-session create calls; the * legacy `mtl_ready` event also fires on this edge * "failed" — any phase rejected; `reason` carries the message * "dhcpTimedOut" — MTL is up but at least one DHCP-configured port * didn't acquire a lease within the server-side * timeout. Non-terminal — polling continues, and * a later lease transitions back to "ready". The * `reason` field carries the port number and a * human-readable remediation hint. */ export type ST2110NicStageEvent = { state: "initialising"; } | { state: "loadingHost"; } | { state: "waitingMtl"; } | { state: "ready"; } | { state: "failed"; reason: string; } | { state: "dhcpTimedOut"; reason: string; }; /** * @public * see: {@link NorskSystemST2110.nic} */ export declare class ST2110Nic { /** * @public * Resolves once the NIC is *actually usable*: MTL_Init / MTL_Start have * completed inside the isox host and an IP address is known (from * static config or DHCP). Rejects with the failure reason if any * later step in the bring-up errors — including the deep zig-side * preflight, which fires asynchronously after `preflightComplete` * has already resolved. Callers that don't need to await readiness * SHOULD still attach a `.catch` so a late failure isn't logged as * an unhandled rejection by Node; `settings.onError` is the * recommended place to handle that failure for UI surfacing. */ initialised: Promise; /** * @public * Resolves once the server-side gen_server is up and its preflight * validation has passed (i.e. the NIC accepts commands), but BEFORE * MTL_Init / MTL_Start have completed and BEFORE any IP address has * been learned. Use this when downstream resource creation (NMOS * devices, senders, receivers) can proceed without the wire being * live yet — Norsk will queue any operation that requires MTL until * MTL_Start completes. Use `initialised` instead when you intend to * push or receive packets immediately. Rejects if preflight fails. */ preflightComplete: Promise; pendingIpAddressRequests: ((ipAddress: string) => void)[]; /** * @public * Resolves to the primary NIC's assigned IP. For 2022-7 hosts use * `ipAddresses()` to observe both ports. */ ipAddress(): Promise; /** * @public * Per-port IPs in NIC order (primary first). Length is 1 for single- * port hosts and 2 for ST 2022-7 hosts. Resolves only once *every* * port's IP is known (relevant for DHCP NICs that arrive * independently). */ ipAddresses(): Promise; } //# sourceMappingURL=system.d.ts.map