import { type PortAllocator } from '@serfab/cadre-provider'; import type { NodePorts } from './types.js'; /** * Allocate a full NodePorts set atomically, in {@link NODE_PORT_KEYS} order. * `overrides` supply a port instead of allocating one (a re-spawn's previous * ports, see {@link reusedNodePorts}). Overrides are reserved before anything is allocated * and are trusted, not checked — see `allocatePortSet`. */ export declare function allocateNodePorts(allocator: PortAllocator, overrides?: Partial): NodePorts; /** * Hold a node's whole port set against `allocator` — the inverse of * {@link releaseNodePorts}. A key the set lacks is skipped (see `markUsed`). */ export declare function reserveNodePorts(allocator: PortAllocator, ports: NodePorts): void; /** * Give a node's whole port set back to `allocator`. A key the set lacks releases * nothing: deleting a value the used-set never held is a no-op. */ export declare function releaseNodePorts(allocator: PortAllocator, ports: NodePorts): void; /** * The ports a re-spawn comes back on: the set the dropped handle held, as * {@link allocateNodePorts} overrides. `{}` when nothing was dropped (a first * spawn, or a handle lost along with `state.json`), so every port is allocated * fresh. * * Why a re-spawn must not simply take the lowest free ports: an owner with no * address of its own (a phone) reaches a hosted node only by dialing the address * it scanned, so a node that comes back on a different port is one that owner * can no longer find. * * A key the dropped handle lacks — `ws` on a handle persisted by an older build — * is left out, and so allocated fresh. When more than one handle was dropped (only * possible from a `state.json` that already held duplicates), the last one stored * wins and the others' ports stay released. */ export declare function reusedNodePorts(dropped: readonly { ports: NodePorts; }[]): Partial;