import * as node_crypto from 'node:crypto'; /** * Runtime shim for `Symbol.metadata` (TC39 decorator-metadata proposal). * * TS 5 standard decorators read/write per-class metadata through `Symbol.metadata`. * Some runtimes (e.g. current Node) don't define it yet, so we polyfill it with a * registered symbol. This module must be imported before any decorated class is * evaluated; the decorator implementations import it for that reason. */ declare global { interface SymbolConstructor { readonly metadata: unique symbol; } } /** Category of an {@link AsyncException}. Wire-significant: sent in error replies. */ declare enum ErrorType { Management = 0, Exception = 1, Warning = 2 } /** * Esiur management error codes (C# `ExceptionCode : ushort`). * Numeric values are wire-significant — keep order in sync with the C# enum. */ declare enum ExceptionCode { RuntimeException = 0, HostNotReachable = 1, AccessDenied = 2, UserOrTokenNotFound = 3, ChallengeFailed = 4, ResourceNotFound = 5, AttachDenied = 6, InvalidMethod = 7, InvokeDenied = 8, CreateDenied = 9, AddParentDenied = 10, AddChildDenied = 11, ViewAttributeDenied = 12, UpdateAttributeDenied = 13, StoreNotFound = 14, ParentNotFound = 15, ChildNotFound = 16, ResourceIsNotStore = 17, DeleteDenied = 18, DeleteFailed = 19, UpdateAttributeFailed = 20, GetAttributesFailed = 21, ClearAttributesFailed = 22, TypeDefNotFound = 23, RenameDenied = 24, ClassNotFound = 25, MethodNotFound = 26, PropertyNotFound = 27, SetPropertyDenied = 28, ReadOnlyProperty = 29, GeneralFailure = 30, AddToStoreFailed = 31, NotAttached = 32, AlreadyListened = 33, AlreadyUnsubscribed = 34, NotSubscribable = 35, ParseError = 36, Timeout = 37, NotSupported = 38, NotImplemented = 39, NotAllowed = 40 } /** Phase a progress report refers to. */ declare enum ProgressType { Execution = 0, Network = 1 } /** Severity for library logging. */ declare enum LogType { Debug = 0, Warning = 1, Error = 2 } /** * Error type used throughout Esiur (port of C# `AsyncException`). * * Carries an {@link ErrorType} category and an {@link ExceptionCode}. Wrapping a * plain error produces a `Type = Exception` instance with `Code = RuntimeException`. */ declare class AsyncException extends Error { readonly type: ErrorType; readonly code: ExceptionCode; /** The original error, when this wraps a thrown exception. */ readonly inner?: Error; constructor(inner: Error); constructor(type: ErrorType, code: number, message: string); toString(): string; /** Coerce any thrown value into an {@link AsyncException}. */ static from(value: unknown): AsyncException; } /** Callback fired when an {@link IDestructible} is destroyed. */ type DestroyedEvent = (sender: unknown) => void; /** * An object whose lifetime is explicitly managed; raises {@link DestroyedEvent} * when it is torn down (port of C# `IDestructible`). */ interface IDestructible { /** Register/unregister a handler invoked when this object is destroyed. */ addDestroyHandler(handler: DestroyedEvent): void; removeDestroyHandler(handler: DestroyedEvent): void; /** Tear down the object and notify destroy handlers. */ destroy(): void; } type Awaitable = R | AsyncReply | PromiseLike; type FulfilledFn = (value: T) => Awaitable; type RejectedFn = (reason: AsyncException) => Awaitable; /** * Esiur's universal asynchronous result (port of C# `AsyncReply`). * * It is a {@link PromiseLike} — `await reply` works and `then`/`catch`/`finally` * behave like a Promise — while additionally exposing Esiur's side channels: * `progress`, `chunk`, `propagation` and `warning`. Unlike a native Promise, * callbacks registered after the result is ready are invoked **synchronously**, * matching the C# implementation. * * The blocking `Wait()` of the C# version is intentionally omitted (JS has no * synchronous blocking); use `await` instead. */ declare class AsyncReply implements PromiseLike { protected _ready: boolean; protected _result: T | undefined; protected _exception: AsyncException | undefined; protected readonly _callbacks: Array<(value: T) => void>; private _errorCallbacks; private _progressCallbacks; private _chunkCallbacks; private _propagationCallbacks; private _warningCallbacks; /** Wall-clock time the result became ready. */ readyTime: number | undefined; constructor(result?: T); /** True once a result has been delivered. */ get ready(): boolean; /** True if the reply completed with an error. */ get failed(): boolean; /** The exception, if {@link failed}. */ get exception(): AsyncException | undefined; /** The result value, or `undefined` if not ready. */ get result(): T | undefined; /** A pre-resolved reply. */ static fromResult(result: U): AsyncReply; then(onFulfilled?: FulfilledFn | null, onRejected?: RejectedFn | null): AsyncReply; /** Promise-style rejection handler. */ catch(onRejected: RejectedFn): AsyncReply; /** Promise-style settle handler. */ finally(onFinally: () => void): AsyncReply; /** Register a result handler (C# `Then`); returns `this` for chaining channels. */ onReady(callback: (value: T) => void): this; /** Register an error handler (C# `Error`). */ error(callback: (ex: AsyncException) => void): this; /** Register a progress handler. */ progress(callback: (type: ProgressType, value: number, max: number) => void): this; /** Register a chunk handler (streamed partial values). */ chunk(callback: (value: unknown) => void): this; /** Register a propagation handler. */ propagation(callback: (value: unknown) => void): this; /** Register a warning handler. */ warning(callback: (level: number, message: string) => void): this; private addErrorHandler; /** Deliver the result. No-op if already settled. */ trigger(result: T): void; /** Fail the reply. No-op if a result was already delivered. */ triggerError(exception: Error | AsyncException): void; triggerProgress(type: ProgressType, value: number, max: number): void; triggerWarning(level: number, message: string): void; triggerChunk(value: unknown): void; triggerPropagation(value: unknown): void; /** Fail the reply with a Timeout error after `ms` if it has not settled. */ timeout(ms: number, callback?: () => void): this; } /** Streaming direction(s) a function supports (port of C# `StreamMode`). Flags. */ declare enum StreamMode { None = 0, Push = 1, Pull = 2 } /** * Represents a remotely executing stream and exposes its lifecycle controls * (port of C# `AsyncStreamReply`/`AsyncStreamReply`, collapsed into one * generic class — TS has no need for C#'s non-generic/generic split, which * exists only because `IAsyncEnumerable` needs a concrete `T`). * * All of C#'s `lock (_streamLock)`/`lock (_itemsLock)` blocks are dropped: * they're pure mutual-exclusion guards around synchronous state mutation, * with no JS equivalent needed since none of these methods yield to the * event loop mid-mutation. */ declare class AsyncStreamReply extends AsyncReply implements AsyncIterable { readonly streamMode: StreamMode; private readonly pullFn; private readonly terminateFn; private readonly haltFn; private readonly resumeFn; private streamStarted; private streamCompleted; private terminationSent; private streamException; private readonly startedDeferred; private readonly items; private itemAvailable; private enumeratorCreated; private movePending; constructor(streamMode: StreamMode, pullFn: () => AsyncReply, terminateFn: () => AsyncReply, haltFn: () => AsyncReply, resumeFn: () => AsyncReply); /** Whether the peer acknowledged that the stream has started. */ get started(): boolean; /** Whether the stream completed or was terminated. */ get completed(): boolean; /** Request the next item of a pull stream. */ pull(): AsyncReply; /** Terminate the remote stream execution and release its enumerator. */ terminate(): AsyncReply; /** Halt a pausable remote stream execution. */ halt(): AsyncReply; /** Resume a halted remote stream execution. */ resume(): AsyncReply; /** @internal Called by `EpConnection` when the peer's `Stream` reply arrives. */ triggerStreamStarted(): void; /** @internal Called by `EpConnection` when the stream's `Completed` reply arrives. */ triggerStreamCompleted(): void; /** @internal Called by `EpConnection` on an `ExecutionError`/`PermissionError` reply. */ triggerStreamError(exception: AsyncException): void; triggerError(exception: Error | AsyncException): void; protected onStreamStarted(): void; protected onStreamCompleted(): void; protected onStreamError(exception: AsyncException): void; private receiveItem; private moveNextAsync; /** Consume with `for await (const item of stream)`. A stream can only be enumerated once. */ [Symbol.asyncIterator](): AsyncIterator; } /** * Collects a set of values and/or {@link AsyncReply}s and resolves to an array * once every member is ready (port of C# `AsyncBag`). * * Add members with {@link add}, then {@link seal}; the bag triggers with the * results in insertion order. Any member error fails the whole bag. */ declare class AsyncBag extends AsyncReply { protected replies: Array | T>; private count; private sealedBag; /** Optional cast applied to plain (non-reply) members before storing. */ arrayCast?: (value: unknown) => T; constructor(results?: T[]); /** Add a value or a pending reply to the bag (ignored once sealed). */ add(valueOrReply: AsyncReply | T): void; /** Merge all members of another bag into this one. */ addBag(bag: AsyncBag): void; /** Freeze the bag and arrange to trigger once all members are ready. */ seal(): void; } /** * Ordered, streaming delivery of {@link AsyncReply}s (port of C# `AsyncQueue`). * * Replies are delivered to handlers registered via {@link AsyncReply.onReady} in * the exact order they were added, even if they become ready out of order — a * later reply waits for all earlier ones. Used for in-order event/notification * dispatch in the protocol layer. */ declare class AsyncQueue extends AsyncReply { private currentId; private items; /** Enqueue a reply; it is delivered once it and all earlier ones are ready. */ add(reply: AsyncReply): void; /** Drop a reply from the queue. */ remove(reply: AsyncReply): void; private processQueue; /** Fire result handlers for a single item without latching the ready state. */ private deliver; } /** * A minimal multicast event (the TypeScript stand-in for a C# `event`). * Handlers are invoked synchronously in registration order. */ declare class EventHandler { private readonly handlers; /** Subscribe; returns this for chaining. */ add(handler: (arg: T) => void): this; /** Unsubscribe a previously-added handler. */ remove(handler: (arg: T) => void): void; /** Invoke all handlers with `arg`. */ emit(arg: T): void; /** Number of subscribed handlers. */ get count(): number; } /** Byte order. The Esiur wire format is little-endian by default. */ declare enum Endian { Big = 0, Little = 1 } /** Milliseconds between .NET epoch (0001-01-01) and Unix epoch (1970-01-01). */ declare const DOTNET_EPOCH_OFFSET_MS = 62135596800000; /** .NET ticks per millisecond (1 tick = 100 ns). */ declare const TICKS_PER_MS = 10000n; declare function boolToBytes(value: boolean): Uint8Array; declare function uint8ToBytes(value: number): Uint8Array; declare function int8ToBytes(value: number): Uint8Array; declare function int16ToBytes(value: number, endian?: Endian): Uint8Array; declare function uint16ToBytes(value: number, endian?: Endian): Uint8Array; declare function int32ToBytes(value: number, endian?: Endian): Uint8Array; declare function uint32ToBytes(value: number, endian?: Endian): Uint8Array; declare function int64ToBytes(value: bigint, endian?: Endian): Uint8Array; declare function uint64ToBytes(value: bigint, endian?: Endian): Uint8Array; declare function float32ToBytes(value: number, endian?: Endian): Uint8Array; declare function float64ToBytes(value: number, endian?: Endian): Uint8Array; /** UTF-8 encode a string (no length prefix). */ declare function stringToBytes(value: string): Uint8Array; /** A .NET `DateTime` as a little-endian int64 of UTC ticks. */ declare function dateTimeToBytes(value: Date): Uint8Array; /** Convert a JS `Date` to .NET UTC ticks. */ declare function dateToTicks(value: Date): bigint; /** Convert .NET UTC ticks to a JS `Date`. */ declare function ticksToDate(ticks: bigint): Date; declare function getUint8(data: Uint8Array, offset: number): number; declare function getInt8(data: Uint8Array, offset: number): number; declare function getInt16(data: Uint8Array, offset: number, endian?: Endian): number; declare function getUint16(data: Uint8Array, offset: number, endian?: Endian): number; declare function getInt32(data: Uint8Array, offset: number, endian?: Endian): number; declare function getUint32(data: Uint8Array, offset: number, endian?: Endian): number; declare function getInt64(data: Uint8Array, offset: number, endian?: Endian): bigint; declare function getUint64(data: Uint8Array, offset: number, endian?: Endian): bigint; declare function getFloat32(data: Uint8Array, offset: number, endian?: Endian): number; declare function getFloat64(data: Uint8Array, offset: number, endian?: Endian): number; declare function getBoolean(data: Uint8Array, offset: number): boolean; /** Decode `length` bytes of UTF-8 starting at `offset`. */ declare function getString(data: Uint8Array, offset: number, length: number): string; declare function getDateTime(data: Uint8Array, offset: number, endian?: Endian): Date; /** Concatenate any number of byte arrays. */ declare function merge(...arrays: Uint8Array[]): Uint8Array; /** Concatenate two byte ranges (port of C# `DC.Combine`). */ declare function combine(src1: Uint8Array, src1Offset: number, src1Length: number, src2: Uint8Array, src2Offset: number, src2Length: number): Uint8Array; /** Return a copy of `length` bytes starting at `offset`. */ declare function clip(data: Uint8Array, offset: number, length: number): Uint8Array; /** Lowercase hex of a byte range (no separator by default). */ declare function toHex(data: Uint8Array, offset?: number, length?: number, separator?: string): string; /** Parse a hex string (optionally separated) into bytes. */ declare function fromHex(hex: string, separator?: string | null): Uint8Array; declare const DC_DOTNET_EPOCH_OFFSET_MS: typeof DOTNET_EPOCH_OFFSET_MS; declare const DC_TICKS_PER_MS: typeof TICKS_PER_MS; declare const DC_boolToBytes: typeof boolToBytes; declare const DC_clip: typeof clip; declare const DC_combine: typeof combine; declare const DC_dateTimeToBytes: typeof dateTimeToBytes; declare const DC_dateToTicks: typeof dateToTicks; declare const DC_float32ToBytes: typeof float32ToBytes; declare const DC_float64ToBytes: typeof float64ToBytes; declare const DC_fromHex: typeof fromHex; declare const DC_getBoolean: typeof getBoolean; declare const DC_getDateTime: typeof getDateTime; declare const DC_getFloat32: typeof getFloat32; declare const DC_getFloat64: typeof getFloat64; declare const DC_getInt16: typeof getInt16; declare const DC_getInt32: typeof getInt32; declare const DC_getInt64: typeof getInt64; declare const DC_getInt8: typeof getInt8; declare const DC_getString: typeof getString; declare const DC_getUint16: typeof getUint16; declare const DC_getUint32: typeof getUint32; declare const DC_getUint64: typeof getUint64; declare const DC_getUint8: typeof getUint8; declare const DC_int16ToBytes: typeof int16ToBytes; declare const DC_int32ToBytes: typeof int32ToBytes; declare const DC_int64ToBytes: typeof int64ToBytes; declare const DC_int8ToBytes: typeof int8ToBytes; declare const DC_merge: typeof merge; declare const DC_stringToBytes: typeof stringToBytes; declare const DC_ticksToDate: typeof ticksToDate; declare const DC_toHex: typeof toHex; declare const DC_uint16ToBytes: typeof uint16ToBytes; declare const DC_uint32ToBytes: typeof uint32ToBytes; declare const DC_uint64ToBytes: typeof uint64ToBytes; declare const DC_uint8ToBytes: typeof uint8ToBytes; declare namespace DC { export { DC_DOTNET_EPOCH_OFFSET_MS as DOTNET_EPOCH_OFFSET_MS, DC_TICKS_PER_MS as TICKS_PER_MS, DC_boolToBytes as boolToBytes, DC_clip as clip, DC_combine as combine, DC_dateTimeToBytes as dateTimeToBytes, DC_dateToTicks as dateToTicks, DC_float32ToBytes as float32ToBytes, DC_float64ToBytes as float64ToBytes, DC_fromHex as fromHex, DC_getBoolean as getBoolean, DC_getDateTime as getDateTime, DC_getFloat32 as getFloat32, DC_getFloat64 as getFloat64, DC_getInt16 as getInt16, DC_getInt32 as getInt32, DC_getInt64 as getInt64, DC_getInt8 as getInt8, DC_getString as getString, DC_getUint16 as getUint16, DC_getUint32 as getUint32, DC_getUint64 as getUint64, DC_getUint8 as getUint8, DC_int16ToBytes as int16ToBytes, DC_int32ToBytes as int32ToBytes, DC_int64ToBytes as int64ToBytes, DC_int8ToBytes as int8ToBytes, DC_merge as merge, DC_stringToBytes as stringToBytes, DC_ticksToDate as ticksToDate, DC_toHex as toHex, DC_uint16ToBytes as uint16ToBytes, DC_uint32ToBytes as uint32ToBytes, DC_uint64ToBytes as uint64ToBytes, DC_uint8ToBytes as uint8ToBytes }; } /** * A 16-byte universally-unique identifier (port of C# `Uuid`). * * Stores the raw bytes as-is (no group reordering); {@link toString} formats * them in the canonical 8-4-4-4-12 grouping directly from byte order. */ declare class Uuid { /** The raw 16 bytes. */ readonly data: Uint8Array; constructor(data: Uint8Array, offset?: number); toString(): string; equals(other: unknown): boolean; /** Parse a canonical UUID string ("xxxxxxxx-xxxx-...") into raw bytes. */ static parse(value: string): Uuid; /** A random v4-style UUID (uses crypto when available). */ static newUuid(): Uuid; } /** * Signed 128-bit integer (port of C# `Int128`, a `{MSB, LSB}` value struct). * * Backed by a JS `bigint`. Also serves as an explicit wire-width marker so the * serializer encodes the value as a 128-bit integer rather than inferring a * narrower width from a bare `bigint`. */ declare class Int128 { /** Two's-complement value in the signed 128-bit range. */ readonly value: bigint; constructor(value: bigint); constructor(lsb: bigint, msb: bigint); /** Low 64 bits. */ get lsb(): bigint; /** High 64 bits. */ get msb(): bigint; toString(): string; equals(other: unknown): boolean; } /** * Unsigned 128-bit integer (port of C# `UInt128`, a `{MSB, LSB}` value struct). * * Backed by a JS `bigint`. Also serves as an explicit wire-width marker so the * serializer encodes the value as a 128-bit integer. */ declare class UInt128 { /** Value in the unsigned 128-bit range. */ readonly value: bigint; constructor(value: bigint); constructor(lsb: bigint, msb: bigint); /** Low 64 bits. */ get lsb(): bigint; /** High 64 bits. */ get msb(): bigint; toString(): string; equals(other: unknown): boolean; } /** * 128-bit base-10 floating point, wire-compatible with .NET `decimal` * (port of the value carried by C# `Decimal128`). * * Value = (-1)^negative × mantissa × 10^(−scale), where `mantissa` is a 96-bit * unsigned integer and `scale` ∈ [0, 28]. Serialized as the raw .NET in-memory * layout: four little-endian 32-bit words in the order `[flags, hi, lo, mid]`. */ declare class Decimal128 { readonly negative: boolean; readonly scale: number; readonly mantissa: bigint; constructor(negative: boolean, scale: number, mantissa: bigint); /** 16-byte .NET layout: LE words `[flags, hi, lo, mid]`. */ toBytes(endian?: Endian): Uint8Array; static fromBytes(data: Uint8Array, offset?: number, endian?: Endian): Decimal128; /** Parse a decimal string (e.g. "-12.3450"); preserves trailing-zero scale. */ static parse(text: string): Decimal128; static fromNumber(value: number): Decimal128; toString(): string; toNumber(): number; equals(other: unknown): boolean; } /** * The top 2 bits of a TDU identifier select its class, which determines how the * payload length is framed (port of C# `TduClass`). */ declare enum TduClass { /** Self-sized primitive (length implied by the identifier's exponent). */ Fixed = 0, /** Length-prefixed payload (string, list, raw bytes, …). */ Dynamic = 1, /** Length-prefixed payload preceded by a type-representation (Tru). */ Typed = 2, /** Reserved extension space. */ Extension = 3, /** Not a valid TDU. */ Invalid = 4 } /** * Leading type byte of a Transmission Data Unit (port of C# `TduIdentifier`). * * Bit layout: `[class:2][size-or-exponent:3][index:3]`. For {@link TduClass.Fixed} * the middle 3 bits are the size exponent; for {@link TduClass.Dynamic} they hold * the byte-count of the length prefix when a payload is present. */ declare enum TduIdentifier { Null = 0, False = 1, True = 2, NotModified = 3, Infinity = 4, UInt8 = 8, Int8 = 9, Char8 = 10, LocalResource8 = 11, RemoteResource8 = 12, LocalProcedure8 = 13, RemoteProcedure8 = 14, UInt16 = 16, Int16 = 17, Char16 = 18, LocalResource16 = 19, RemoteResource16 = 20, LocalProcedure16 = 21, RemoteProcedure16 = 22, UInt32 = 24, Int32 = 25, Float32 = 26, LocalResource32 = 27, RemoteResource32 = 28, LocalProcedure32 = 29, RemoteProcedure32 = 30, UInt64 = 32, Int64 = 33, Float64 = 34, DateTime = 35, UInt128 = 40, Int128 = 41, Decimal128 = 42, UUID = 43, RawData = 64, String = 65, List = 66, ResourceList = 67, RecordList = 68, ResourceLink = 69, Map = 70, MapList = 71, Typed = 128, TypeDef = 129, TRU = 130, TypeContinuation = 192, TypeOfTarget = 193 } /** Type-representation metadata that can serialize itself (implemented by Tru). */ interface ComposableTru { compose(connection: unknown): Uint8Array; match(other: ComposableTru): boolean; } /** * A Transmission Data Unit — one self-describing value on the wire * (port of C# `Tdu`). The constructor produces {@link composed}, the full * encoded bytes including the leading identifier. */ declare class Tdu { readonly identifier: TduIdentifier; readonly tduClass: TduClass; /** Fully encoded bytes (identifier + framing + payload). */ readonly composed: Uint8Array; /** Offset within {@link composed} at which the value payload begins. */ readonly contentOffset: number; /** Type metadata for {@link TduClass.Typed} units. */ readonly metadata: ComposableTru | null; constructor(identifier: TduIdentifier, data: Uint8Array | null, length: number, metadata?: ComposableTru | null, connection?: unknown); /** True if both are typed TDUs of the same identifier and matching metadata. */ matchType(other: Tdu): boolean; } /** * A decoded TDU header pointing back into the source buffer (port of C# * `ParsedTdu`). `parseSync` reads the identifier/length framing and locates the * payload; the actual value is produced by the parsers in `DataDeserializer`. */ declare class ParsedTdu { identifier: TduIdentifier; index: number; tduClass: TduClass; payloadOffset: number; payloadLength: number; data: Uint8Array; exponent: number; totalLength: number; /** Type metadata (Tru) for {@link TduClass.Typed}; populated in Step B. */ metadata: unknown; ends: number; static invalid(totalLength: number): ParsedTdu; /** Parse a TDU header at `offset` (sync path; resolves typed metadata via warehouse). */ static parseSync(data: Uint8Array, offset: number, ends: number, warehouse?: unknown, maximumPayloadLength?: number): ParsedTdu; /** * Async twin of {@link parseSync}, used when a `Tru` value (embedded * metadata, or a nested `TduIdentifier.TRU`/`TypeDef` value further down the * tree) may need to resolve a not-yet-fetched remote TypeDef reference. * Structurally identical to `parseSync`; the one embedded-Tru-metadata spot * awaits the async Tru parser instead of the sync one. */ static parseAsync(data: Uint8Array, offset: number, ends: number, warehouse: unknown, remoteResolver: unknown, requestSequence: readonly number[] | null, maximumPayloadLength?: number): Promise; } /** Wire up the Tru parser (called by the Tru module on import). */ declare function registerTruParser(fn: (data: Uint8Array, offset: number, warehouse: unknown) => { value: unknown; size: number; }): void; /** Wire up the async Tru parser (called by the Tru module on import). */ declare function registerTruParserAsync(fn: (data: Uint8Array, offset: number, warehouse: unknown, remoteResolver: unknown, requestSequence: readonly number[] | null) => Promise<{ value: unknown; size: number; }>): void; /** * A measured-but-undecoded TDU (port of C# `PlainTdu`). Used by the packet layer * to delimit a value within a packet without decoding it — the decode (which may * need the connection to resolve remote resources/typedefs) is deferred and run * later via the async {@link Codec} parse path. Unlike {@link ParsedTdu}, the * Typed branch does not parse its Tru metadata; `payloadLength` covers the whole * content (metadata + value). */ declare class PlainTdu { identifier: TduIdentifier; index: number; tduClass: TduClass; /** Offset of the TDU start (the identifier byte). */ tduOffset: number; payloadOffset: number; payloadLength: number; exponent: number; totalLength: number; data: Uint8Array; ends: number; static invalid(totalLength: number): PlainTdu; /** Measure the TDU at `offset` without decoding its value. */ static parse(data: Uint8Array, offset: number, ends: number, maximumPayloadLength?: number): PlainTdu; } /** * Sentinel meaning "value unchanged" (port of C# `NotModified`). Used in * property-update replies to signal that a property keeps its current value. */ declare class NotModified { static readonly Default: NotModified; private constructor(); } /** * A placeholder produced when a resource reference is decoded without a * connection/warehouse to resolve it (port of C# `ResourceId`). Carries whether * the reference is local and the numeric instance id. */ declare class ResourceId { readonly local: boolean; readonly id: number; constructor(local: boolean, id: number); } /** * A textual link to a resource, e.g. "iip://host/path" (port of C# * `ResourceLink`, which is implicitly convertible to/from string). */ declare class ResourceLink { readonly link: string; constructor(link: string); toString(): string; } /** * Explicit numeric-width wrappers. A bare JS `number` is treated as a C# * `double` and a bare `bigint` as a C# `long`; wrap a value in one of these to * pin the wire width the serializer should use (e.g. unsigned types, or a * 32-bit float). Like the C# composers, these still narrow to the smallest * representation that fits — `u32(255)` encodes as `UInt8`. */ declare class Int8 { readonly value: number; constructor(value: number); } declare class UInt8 { readonly value: number; constructor(value: number); } declare class Int16 { readonly value: number; constructor(value: number); } declare class UInt16 { readonly value: number; constructor(value: number); } declare class Int32 { readonly value: number; constructor(value: number); } declare class UInt32 { readonly value: number; constructor(value: number); } declare class Int64 { readonly value: bigint; constructor(value: bigint); } declare class UInt64 { readonly value: bigint; constructor(value: bigint); } declare class Float32 { readonly value: number; constructor(value: number); } /** A UTF-16 code unit, encoded as the `Char16` TDU. */ declare class Char16 { readonly value: number; constructor(value: number); } /** Convenience factories for the width wrappers. */ declare const i8: (v: number) => Int8; declare const u8: (v: number) => UInt8; declare const i16: (v: number) => Int16; declare const u16: (v: number) => UInt16; declare const i32: (v: number) => Int32; declare const u32: (v: number) => UInt32; declare const i64: (v: bigint) => Int64; declare const u64: (v: bigint) => UInt64; declare const f32: (v: number) => Float32; declare const char16: (v: number | string) => Char16; /** * Type-Representation Unit identifier (port of C# `TruIdentifier`). * * Values < 0x40 are primitives. Values ≥ 0x40 set bit 6 (the "composite/ref" * flag); their bits 3-5 encode the sub-type count, so `TypedList` (0x48) implies * one sub-type and `TypedMap`/`Tuple2` (0x50/0x51) imply two. */ declare enum TruIdentifier { Void = 0, Dynamic = 1, Bool = 2, UInt8 = 3, Int8 = 4, Char = 5, UInt16 = 6, Int16 = 7, UInt32 = 8, Int32 = 9, Float32 = 10, UInt64 = 11, Int64 = 12, Float64 = 13, DateTime = 14, UInt128 = 15, Int128 = 16, Decimal = 17, String = 18, RawData = 19, Resource = 20, Record = 21, List = 22, Map = 23, LocalType8 = 64, RemoteType8 = 65, LocalType16 = 66, RemoteType16 = 67, LocalType32 = 68, RemoteType32 = 69, LocalType64 = 70, RemoteType64 = 71, TypedList = 72, Tuple2 = 80, TypedMap = 81, Tuple3 = 88, Tuple4 = 96, Tuple5 = 104, Tuple6 = 112, Tuple7 = 120 } /** Kind of a type definition (port of C# `TypeDefKind`). */ declare enum TypeDefKind { Resource = 0, Record = 1, Enum = 2, Function = 3 } /** A property entry within a type definition. */ interface TypeDefProperty { name: string; valueType?: Tru; } /** A constant entry within an enum type definition. */ interface TypeDefConstant { name: string; value: unknown; index: number; } /** * Minimal, layer-neutral view of a type definition used by the serializer * (records/enums). The full implementation (`LocalTypeDef`) lives in the * resource layer and is resolved via a registered hook, keeping `data/` * independent of the resource model. */ interface ITypeDef { readonly id: number; readonly kind: TypeDefKind; readonly name: string; readonly properties: ReadonlyArray; readonly constants?: ReadonlyArray; /** Create a fresh instance of the described type. */ createInstance(): object; /** Assign a decoded property value to an instance. */ setProperty(instance: object, name: string, value: unknown): void; } type RemoteTypeDefResolver = (id: number, requestSequence: readonly number[] | null) => ITypeDef | PromiseLike; /** * Type-Representation Unit (port of C# `Tru`). Describes how a value's type maps * onto the wire. Because TypeScript has no runtime reflection, Trus are built * explicitly via the `t.*` descriptors (see `descriptors.ts`) rather than from a * CLR `Type`. * * Wire encoding (one header byte): `(nullable ? 0x80 : 0) | identifier`. For * composites the identifier's bits 3-5 imply the sub-type count, whose Trus * follow inline. */ declare abstract class Tru implements ComposableTru { identifier: TruIdentifier; nullable: boolean; protected constructor(identifier: TruIdentifier, nullable: boolean); abstract compose(connection?: unknown): Uint8Array; abstract match(other: Tru): boolean; abstract toNullable(): Tru; protected get headerByte(): number; /** Parse a Tru at `offset`; returns the Tru and the number of bytes consumed. */ static parseSync(data: Uint8Array, offset: number, warehouse?: unknown): { value: Tru; size: number; }; /** Async parser variant used when remote TypeDef references may need fetching. */ static parseAsync(data: Uint8Array, offset: number, warehouse?: unknown, remoteResolver?: RemoteTypeDefResolver, requestSequence?: readonly number[] | null): Promise<{ value: Tru; size: number; }>; } /** A primitive Tru (single header byte, no sub-types). */ declare class TruPrimitive extends Tru { constructor(identifier: TruIdentifier, nullable?: boolean); compose(): Uint8Array; match(other: Tru): boolean; toNullable(): TruPrimitive; toString(): string; } /** A composite Tru (typed list/map/tuple) carrying inline sub-type Trus. */ declare class TruComposite extends Tru { readonly subTypes: Tru[]; constructor(identifier: TruIdentifier, nullable: boolean, subTypes: Tru[]); compose(connection?: unknown): Uint8Array; match(other: Tru): boolean; toNullable(): TruComposite; toString(): string; } /** A Tru referencing a registered type definition (record/enum/resource). */ declare class TruTypeDef extends Tru { readonly typeDef: ITypeDef; constructor(nullable: boolean, typeDef: ITypeDef); compose(): Uint8Array; match(other: Tru): boolean; toNullable(): TruTypeDef; toString(): string; } /** Register the typedef resolver used when decoding TypeDef-referencing Trus. */ declare function registerTypeDefResolver(fn: (warehouse: unknown, id: number) => ITypeDef): void; /** * Type descriptors — the TypeScript stand-in for C#'s reflection-driven * `Tru.FromType`. Use these to declare element/key/value types where the wire * needs a type representation (typed lists/maps/tuples), e.g. * `t.list(t.i32)` or `t.map(t.string, t.f64)`. The codegen CLI emits these. */ declare function tupleIdentifier(count: number): TruIdentifier; declare const t: { readonly void: TruPrimitive; readonly dynamic: TruPrimitive; readonly bool: TruPrimitive; readonly char: TruPrimitive; readonly u8: TruPrimitive; readonly i8: TruPrimitive; readonly u16: TruPrimitive; readonly i16: TruPrimitive; readonly u32: TruPrimitive; readonly i32: TruPrimitive; readonly u64: TruPrimitive; readonly i64: TruPrimitive; readonly u128: TruPrimitive; readonly i128: TruPrimitive; readonly f32: TruPrimitive; readonly f64: TruPrimitive; readonly decimal: TruPrimitive; readonly string: TruPrimitive; readonly rawData: TruPrimitive; readonly datetime: TruPrimitive; readonly resource: TruPrimitive; readonly record: TruPrimitive; readonly list: (element: Tru) => TruComposite; readonly map: (key: Tru, value: Tru) => TruComposite; readonly tuple: (...subTypes: Tru[]) => TruComposite; readonly nullable: (type: Tru) => Tru; }; /** * An explicitly-typed array value. Composing it produces a Typed TDU whose * metadata is `TypedList`; numeric element types use the compact Gvwie * group encoding. */ declare class TypedList { readonly element: Tru; readonly values: readonly unknown[]; constructor(element: Tru, values: readonly unknown[]); } /** Construct a {@link TypedList} value, e.g. `typedList(t.i32, [1, 2, 3])`. */ declare function typedList(element: Tru, values: readonly unknown[]): TypedList; /** * An explicitly-typed map value. Composing it produces a Typed TDU with * metadata `TypedMap` whose payload is the keys array followed by * the values array. */ declare class TypedMap { readonly keyType: Tru; readonly valueType: Tru; readonly entries: ReadonlyArray; constructor(keyType: Tru, valueType: Tru, entries: Map | ReadonlyArray); } /** Construct a {@link TypedMap}, e.g. `typedMap(t.string, t.i32, myMap)`. */ declare function typedMap(keyType: Tru, valueType: Tru, entries: Map | ReadonlyArray): TypedMap; /** * An explicitly-typed tuple value (2-7 elements). Composing it produces a Typed * TDU with metadata `TupleN<...elementTypes>`. */ declare class TypedTuple { readonly elements: readonly Tru[]; readonly values: readonly unknown[]; constructor(elements: readonly Tru[], values: readonly unknown[]); } /** Construct a {@link TypedTuple}, e.g. `typedTuple([t.i32, t.string], [1, "a"])`. */ declare function typedTuple(elements: readonly Tru[], values: readonly unknown[]): TypedTuple; /** * Self-describing value codec (port of C# `Codec`). Encodes a value to its * type-prefixed TDU representation. * * Type mapping for bare JS values: * - `null`/`undefined` → Null * - `boolean` → True/False * - `number` → C# `double` semantics (narrowed; integral → smallest int) * - `bigint` → C# `long` semantics (narrowed) * - `string` → String * - `Date` → DateTime, `Uuid` → UUID, `Decimal128` → Decimal128 * - width wrappers (`u8`, `i32`, `f32`, …) pin an explicit wire width * * Collections, maps, records and resources require the type registry and * connection context and are added in the Phase 2 continuation. */ declare function composeInternal(value: unknown, warehouse?: unknown, connection?: unknown): Tdu; /** Register a structured-type composer hook (called by the resource layer). */ declare function registerComposer(fn: (value: unknown, warehouse: unknown, connection: unknown) => Tdu | undefined): void; /** Encode a value to its self-describing TDU bytes (leading identifier included). */ declare function compose(value: unknown, warehouse?: unknown, connection?: unknown): Uint8Array; /** Dispatch an already-parsed TDU header to the matching value parser. */ declare function parseSyncTdu(tdu: ParsedTdu, warehouse?: unknown): unknown; /** Decode one value at `offset`; returns the value and bytes consumed. */ declare function parseSync(data: Uint8Array, offset?: number, warehouse?: unknown): { value: unknown; length: number; }; /** Decode one value at `offset` and return just the value. */ declare function parse(data: Uint8Array, offset?: number, warehouse?: unknown): unknown; /** Async twin of {@link parseSyncTdu}. */ declare function parseAsyncTdu(tdu: ParsedTdu, warehouse: unknown, remoteResolver: RemoteTypeDefResolver | undefined, requestSequence: readonly number[] | null): Promise; /** Async twin of {@link parseSync}. */ declare function parseAsync(data: Uint8Array, offset: number, warehouse: unknown, remoteResolver: RemoteTypeDefResolver | undefined, requestSequence: readonly number[] | null): Promise<{ value: unknown; length: number; }>; declare const Codec_compose: typeof compose; declare const Codec_composeInternal: typeof composeInternal; declare const Codec_parse: typeof parse; declare const Codec_parseAsync: typeof parseAsync; declare const Codec_parseAsyncTdu: typeof parseAsyncTdu; declare const Codec_parseSync: typeof parseSync; declare const Codec_parseSyncTdu: typeof parseSyncTdu; declare const Codec_registerComposer: typeof registerComposer; declare namespace Codec { export { Codec_compose as compose, Codec_composeInternal as composeInternal, Codec_parse as parse, Codec_parseAsync as parseAsync, Codec_parseAsyncTdu as parseAsyncTdu, Codec_parseSync as parseSync, Codec_parseSyncTdu as parseSyncTdu, Codec_registerComposer as registerComposer }; } /** * Marker base for local, schema-less types whose members are identified by * byte indexes on the wire (port of C# `IndexedStructure`). Composed as a * sparse `TypedMap` — `null`/`undefined` members are omitted, * and unknown indices are silently ignored on decode (version tolerant). */ declare abstract class IndexedStructure { } declare function boolComposer(value: boolean): Tdu; declare function notModifiedComposer(): Tdu; declare function uint8Composer(value: number): Tdu; declare function int8Composer(value: number): Tdu; declare function char16Composer(value: number): Tdu; declare function int16Composer(value: number): Tdu; declare function uint16Composer(value: number): Tdu; declare function int32Composer(value: number): Tdu; declare function uint32Composer(value: number): Tdu; declare function int64Composer(value: bigint): Tdu; declare function uint64Composer(value: bigint): Tdu; declare function float32Composer(value: number): Tdu; declare function float64Composer(value: number): Tdu; declare function dateTimeComposer(value: Date): Tdu; declare function stringComposer(value: string): Tdu; declare function uuidComposer(value: Uuid): Tdu; declare function rawDataComposer(value: Uint8Array): Tdu; /** Compose an {@link IndexedStructure} as a sparse `TypedMap` (`Typed`, 0x80). */ declare function structureComposer(value: IndexedStructure | null, warehouse: unknown, connection: unknown): Tdu; /** Compose a standalone {@link Tru} value into its own dedicated, metadata-free slot (0x82). */ declare function truComposer(value: Tru, _warehouse: unknown, connection: unknown): Tdu; /** Compose a {@link TypeDefInfo}-shaped structure into its dedicated wire slot (0x81). */ declare function typeDefComposer(value: IndexedStructure | null, warehouse: unknown, connection: unknown): Tdu; /** * Decimal composer. Narrows a scale-0 decimal to the smallest signed integer * that fits (matching C#); otherwise emits the full 16-byte .NET layout. * * Note: C# additionally shrinks decimals that are exactly representable as * float32/float64. We always send full precision for fractional decimals — a * lossless, interoperable choice — so those specific byte sequences differ while * the decoded value is identical. */ declare function decimal128Composer(value: Decimal128): Tdu; declare const DataSerializer_boolComposer: typeof boolComposer; declare const DataSerializer_char16Composer: typeof char16Composer; declare const DataSerializer_dateTimeComposer: typeof dateTimeComposer; declare const DataSerializer_decimal128Composer: typeof decimal128Composer; declare const DataSerializer_float32Composer: typeof float32Composer; declare const DataSerializer_float64Composer: typeof float64Composer; declare const DataSerializer_int16Composer: typeof int16Composer; declare const DataSerializer_int32Composer: typeof int32Composer; declare const DataSerializer_int64Composer: typeof int64Composer; declare const DataSerializer_int8Composer: typeof int8Composer; declare const DataSerializer_notModifiedComposer: typeof notModifiedComposer; declare const DataSerializer_rawDataComposer: typeof rawDataComposer; declare const DataSerializer_stringComposer: typeof stringComposer; declare const DataSerializer_structureComposer: typeof structureComposer; declare const DataSerializer_truComposer: typeof truComposer; declare const DataSerializer_typeDefComposer: typeof typeDefComposer; declare const DataSerializer_uint16Composer: typeof uint16Composer; declare const DataSerializer_uint32Composer: typeof uint32Composer; declare const DataSerializer_uint64Composer: typeof uint64Composer; declare const DataSerializer_uint8Composer: typeof uint8Composer; declare const DataSerializer_uuidComposer: typeof uuidComposer; declare namespace DataSerializer { export { DataSerializer_boolComposer as boolComposer, DataSerializer_char16Composer as char16Composer, DataSerializer_dateTimeComposer as dateTimeComposer, DataSerializer_decimal128Composer as decimal128Composer, DataSerializer_float32Composer as float32Composer, DataSerializer_float64Composer as float64Composer, DataSerializer_int16Composer as int16Composer, DataSerializer_int32Composer as int32Composer, DataSerializer_int64Composer as int64Composer, DataSerializer_int8Composer as int8Composer, DataSerializer_notModifiedComposer as notModifiedComposer, DataSerializer_rawDataComposer as rawDataComposer, DataSerializer_stringComposer as stringComposer, DataSerializer_structureComposer as structureComposer, DataSerializer_truComposer as truComposer, DataSerializer_typeDefComposer as typeDefComposer, DataSerializer_uint16Composer as uint16Composer, DataSerializer_uint32Composer as uint32Composer, DataSerializer_uint64Composer as uint64Composer, DataSerializer_uint8Composer as uint8Composer, DataSerializer_uuidComposer as uuidComposer }; } /** * Sync value parsers (port of the sync parsers in C# `DataDeserializer`). Each * reads its value from `tdu.data` at `tdu.payloadOffset`. Returned JS types: * integers ≤32-bit and floats → `number`, 64-bit → `bigint`, decimal → * {@link Decimal128}, datetime → `Date`, uuid → {@link Uuid}. */ type Parser = (tdu: ParsedTdu, warehouse: unknown) => unknown; /** * Async twin of {@link Parser}, used where a `Tru`/`TypeDef`-family value * anywhere in the tree may need to resolve a not-yet-fetched remote TypeDef * reference via `remoteResolver`. */ type AsyncParser = (tdu: ParsedTdu, warehouse: unknown, remoteResolver: RemoteTypeDefResolver | undefined, requestSequence: readonly number[] | null) => Promise; declare const nullParser: Parser; declare const booleanTrueParser: Parser; declare const booleanFalseParser: Parser; declare const notModifiedParser: Parser; declare const infinityParser: Parser; declare const uint8Parser: Parser; declare const int8Parser: Parser; declare const char8Parser: Parser; declare const char16Parser: Parser; declare const int16Parser: Parser; declare const uint16Parser: Parser; declare const int32Parser: Parser; declare const uint32Parser: Parser; declare const float32Parser: Parser; declare const float64Parser: Parser; declare const int64Parser: Parser; declare const uint64Parser: Parser; declare const dateTimeParser: Parser; declare const decimal128Parser: Parser; declare const uuidParser: Parser; declare const int128Parser: Parser; declare const uint128Parser: Parser; declare const resourceLinkParser: Parser; declare const rawDataParser: Parser; declare const stringParser: Parser; declare const resource8Parser: Parser; declare const resource16Parser: Parser; declare const resource32Parser: Parser; declare const localResource8Parser: Parser; declare const localResource16Parser: Parser; declare const localResource32Parser: Parser; declare const listParser: Parser; declare const resourceListParser: Parser; declare const recordListParser: Parser; declare const mapParser: Parser; declare const mapListParser: Parser; declare const typedParser: Parser; /** Decode a `TduIdentifier.TypeDef` (0x81) payload into a {@link TypeDefInfo}. */ declare const typeDefInfoParser: Parser; /** Decode a `TduIdentifier.TRU` (0x82) payload into a standalone {@link Tru} value. */ declare const truParser: Parser; declare const listParserAsync: AsyncParser; declare const resourceListParserAsync: AsyncParser; declare const recordListParserAsync: AsyncParser; declare const mapParserAsync: AsyncParser; declare const mapListParserAsync: AsyncParser; declare const rawDataParserAsync: AsyncParser; declare const stringParserAsync: AsyncParser; declare const resourceLinkParserAsync: AsyncParser; declare const typedParserAsync: AsyncParser; /** Async twin of {@link typeDefInfoParser}. */ declare const typeDefInfoParserAsync: AsyncParser; /** Async twin of {@link truParser}. */ declare const truParserAsync: AsyncParser; type DataDeserializer_AsyncParser = AsyncParser; type DataDeserializer_Parser = Parser; declare const DataDeserializer_booleanFalseParser: typeof booleanFalseParser; declare const DataDeserializer_booleanTrueParser: typeof booleanTrueParser; declare const DataDeserializer_char16Parser: typeof char16Parser; declare const DataDeserializer_char8Parser: typeof char8Parser; declare const DataDeserializer_dateTimeParser: typeof dateTimeParser; declare const DataDeserializer_decimal128Parser: typeof decimal128Parser; declare const DataDeserializer_float32Parser: typeof float32Parser; declare const DataDeserializer_float64Parser: typeof float64Parser; declare const DataDeserializer_infinityParser: typeof infinityParser; declare const DataDeserializer_int128Parser: typeof int128Parser; declare const DataDeserializer_int16Parser: typeof int16Parser; declare const DataDeserializer_int32Parser: typeof int32Parser; declare const DataDeserializer_int64Parser: typeof int64Parser; declare const DataDeserializer_int8Parser: typeof int8Parser; declare const DataDeserializer_listParser: typeof listParser; declare const DataDeserializer_listParserAsync: typeof listParserAsync; declare const DataDeserializer_localResource16Parser: typeof localResource16Parser; declare const DataDeserializer_localResource32Parser: typeof localResource32Parser; declare const DataDeserializer_localResource8Parser: typeof localResource8Parser; declare const DataDeserializer_mapListParser: typeof mapListParser; declare const DataDeserializer_mapListParserAsync: typeof mapListParserAsync; declare const DataDeserializer_mapParser: typeof mapParser; declare const DataDeserializer_mapParserAsync: typeof mapParserAsync; declare const DataDeserializer_notModifiedParser: typeof notModifiedParser; declare const DataDeserializer_nullParser: typeof nullParser; declare const DataDeserializer_rawDataParser: typeof rawDataParser; declare const DataDeserializer_rawDataParserAsync: typeof rawDataParserAsync; declare const DataDeserializer_recordListParser: typeof recordListParser; declare const DataDeserializer_recordListParserAsync: typeof recordListParserAsync; declare const DataDeserializer_resource16Parser: typeof resource16Parser; declare const DataDeserializer_resource32Parser: typeof resource32Parser; declare const DataDeserializer_resource8Parser: typeof resource8Parser; declare const DataDeserializer_resourceLinkParser: typeof resourceLinkParser; declare const DataDeserializer_resourceLinkParserAsync: typeof resourceLinkParserAsync; declare const DataDeserializer_resourceListParser: typeof resourceListParser; declare const DataDeserializer_resourceListParserAsync: typeof resourceListParserAsync; declare const DataDeserializer_stringParser: typeof stringParser; declare const DataDeserializer_stringParserAsync: typeof stringParserAsync; declare const DataDeserializer_truParser: typeof truParser; declare const DataDeserializer_truParserAsync: typeof truParserAsync; declare const DataDeserializer_typeDefInfoParser: typeof typeDefInfoParser; declare const DataDeserializer_typeDefInfoParserAsync: typeof typeDefInfoParserAsync; declare const DataDeserializer_typedParser: typeof typedParser; declare const DataDeserializer_typedParserAsync: typeof typedParserAsync; declare const DataDeserializer_uint128Parser: typeof uint128Parser; declare const DataDeserializer_uint16Parser: typeof uint16Parser; declare const DataDeserializer_uint32Parser: typeof uint32Parser; declare const DataDeserializer_uint64Parser: typeof uint64Parser; declare const DataDeserializer_uint8Parser: typeof uint8Parser; declare const DataDeserializer_uuidParser: typeof uuidParser; declare namespace DataDeserializer { export { type DataDeserializer_AsyncParser as AsyncParser, type DataDeserializer_Parser as Parser, DataDeserializer_booleanFalseParser as booleanFalseParser, DataDeserializer_booleanTrueParser as booleanTrueParser, DataDeserializer_char16Parser as char16Parser, DataDeserializer_char8Parser as char8Parser, DataDeserializer_dateTimeParser as dateTimeParser, DataDeserializer_decimal128Parser as decimal128Parser, DataDeserializer_float32Parser as float32Parser, DataDeserializer_float64Parser as float64Parser, DataDeserializer_infinityParser as infinityParser, DataDeserializer_int128Parser as int128Parser, DataDeserializer_int16Parser as int16Parser, DataDeserializer_int32Parser as int32Parser, DataDeserializer_int64Parser as int64Parser, DataDeserializer_int8Parser as int8Parser, DataDeserializer_listParser as listParser, DataDeserializer_listParserAsync as listParserAsync, DataDeserializer_localResource16Parser as localResource16Parser, DataDeserializer_localResource32Parser as localResource32Parser, DataDeserializer_localResource8Parser as localResource8Parser, DataDeserializer_mapListParser as mapListParser, DataDeserializer_mapListParserAsync as mapListParserAsync, DataDeserializer_mapParser as mapParser, DataDeserializer_mapParserAsync as mapParserAsync, DataDeserializer_notModifiedParser as notModifiedParser, DataDeserializer_nullParser as nullParser, DataDeserializer_rawDataParser as rawDataParser, DataDeserializer_rawDataParserAsync as rawDataParserAsync, DataDeserializer_recordListParser as recordListParser, DataDeserializer_recordListParserAsync as recordListParserAsync, DataDeserializer_resource16Parser as resource16Parser, DataDeserializer_resource32Parser as resource32Parser, DataDeserializer_resource8Parser as resource8Parser, DataDeserializer_resourceLinkParser as resourceLinkParser, DataDeserializer_resourceLinkParserAsync as resourceLinkParserAsync, DataDeserializer_resourceListParser as resourceListParser, DataDeserializer_resourceListParserAsync as resourceListParserAsync, DataDeserializer_stringParser as stringParser, DataDeserializer_stringParserAsync as stringParserAsync, DataDeserializer_truParser as truParser, DataDeserializer_truParserAsync as truParserAsync, DataDeserializer_typeDefInfoParser as typeDefInfoParser, DataDeserializer_typeDefInfoParserAsync as typeDefInfoParserAsync, DataDeserializer_typedParser as typedParser, DataDeserializer_typedParserAsync as typedParserAsync, DataDeserializer_uint128Parser as uint128Parser, DataDeserializer_uint16Parser as uint16Parser, DataDeserializer_uint32Parser as uint32Parser, DataDeserializer_uint64Parser as uint64Parser, DataDeserializer_uint8Parser as uint8Parser, DataDeserializer_uuidParser as uuidParser }; } /** * Generic group-varint codec core (port of the shared structure of C#'s * `Gvwie.GroupIntNNCodec` family). One header byte frames a run: * `1 | countField[countBits] | (width-1)[widthBits]`, where `countBits + * widthBits === 7`. Values ≤ 7 bits take a single literal byte. Signed widths * zig-zag; unsigned widths store the value directly. Everything is computed in * `bigint` so a single implementation serves the 16/32/64-bit variants. */ interface GroupConfig { /** Bits in the header's count field (16→6, 32→5, 64→4). */ countBits: number; /** Maximum payload width in bytes (16→2, 32→4, 64→8). */ maxWidth: number; /** Total value width in bits (16/32/64) — used for the zig-zag mask. */ bits: number; /** Whether values are zig-zag encoded (signed) or stored directly. */ signed: boolean; } /** A group codec over JS `number` arrays (16/32-bit widths). */ declare function makeNumberCodec(cfg: GroupConfig): { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => number[]; }; /** A group codec over JS `bigint` arrays (64-bit widths). */ declare function makeBigIntCodec(cfg: GroupConfig): { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => bigint[]; }; /** Group-varint zig-zag codec for `Int16` arrays (port of `GroupInt16Codec`). */ declare const GroupInt16Codec: { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => number[]; }; /** Group-varint zig-zag codec for `Int32` arrays (port of `GroupInt32Codec`). */ declare const GroupInt32Codec: { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => number[]; }; /** Group-varint zig-zag codec for `Int64` arrays (port of `GroupInt64Codec`). */ declare const GroupInt64Codec: { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => bigint[]; }; /** Group-varint codec for `UInt16` arrays (port of `GroupUInt16Codec`). */ declare const GroupUInt16Codec: { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => number[]; }; /** Group-varint codec for `UInt32` arrays (port of `GroupUInt32Codec`). */ declare const GroupUInt32Codec: { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => number[]; }; /** Group-varint codec for `UInt64` arrays (port of `GroupUInt64Codec`). */ declare const GroupUInt64Codec: { encode: (values: ArrayLike) => Uint8Array; decode: (src: Uint8Array, start?: number, end?: number) => bigint[]; }; /** Lifecycle operations dispatched to a resource via `handle` (port of C# `ResourceOperation`). */ declare enum ResourceOperation { Open = 0, Initialize = 1, Configure = 2, Close = 3, Terminate = 4, SystemReady = 5, SystemReloading = 6, SystemReloaded = 7, SystemTerminating = 8, /** Second termination phase; intentionally shares dotnet's `SystemTerminating` value. */ SystemTerminated = 8, Save = 9, Load = 10, Pause = 11, Resume = 12 } /** * Lightweight TypeDef describing a resource's exported members, built from * decorator metadata instead of reflection. */ declare enum MemberType { Function = 0, Property = 1, Event = 2 } declare class ArgumentTemplate { name: string; type: Tru | undefined; optional: boolean; annotations?: Map | undefined; constructor(name: string, type: Tru | undefined, optional?: boolean, annotations?: Map | undefined); } declare class PropertyTemplate { name: string; index: number; valueType: Tru | undefined; readOnly: boolean; annotations?: Map | undefined; readonly memberType = MemberType.Property; /** Named Warehouse rate policy applied by `@RateControl(name)`. */ ratePolicyName?: string; constructor(name: string, index: number, valueType: Tru | undefined, readOnly?: boolean, annotations?: Map | undefined); } declare class FunctionTemplate { name: string; index: number; returnType: Tru | undefined; args: ArgumentTemplate[]; isStatic: boolean; annotations?: Map | undefined; /** `None` for an ordinary call; `Push`/`Pull` for a streamed one (see `@Export`'s `streamMode` option). */ streamMode: StreamMode; /** Whether an in-flight stream from this function can be halted/resumed. Meaningless when `streamMode` is `None`. */ pausable: boolean; readonly memberType = MemberType.Function; /** Named Warehouse rate policy applied by `@RateControl(name)`. */ ratePolicyName?: string; constructor(name: string, index: number, returnType: Tru | undefined, args?: ArgumentTemplate[], isStatic?: boolean, annotations?: Map | undefined, /** `None` for an ordinary call; `Push`/`Pull` for a streamed one (see `@Export`'s `streamMode` option). */ streamMode?: StreamMode, /** Whether an in-flight stream from this function can be halted/resumed. Meaningless when `streamMode` is `None`. */ pausable?: boolean); } declare class EventTemplate { name: string; index: number; argType: Tru | undefined; annotations?: Map | undefined; subscribable: boolean; readonly memberType = MemberType.Event; constructor(name: string, index: number, argType: Tru | undefined, annotations?: Map | undefined, subscribable?: boolean); } type MemberTemplate = PropertyTemplate | FunctionTemplate | EventTemplate; /** Describes the exported surface of a resource type. */ declare class TypeDef { className: string; members: MemberTemplate[]; annotations?: Map | undefined; constructor(className: string, members: MemberTemplate[], annotations?: Map | undefined); get properties(): PropertyTemplate[]; get functions(): FunctionTemplate[]; get events(): EventTemplate[]; getPropertyByName(name: string): PropertyTemplate | undefined; getPropertyByIndex(index: number): PropertyTemplate | undefined; getFunctionByName(name: string): FunctionTemplate | undefined; getFunctionByIndex(index: number): FunctionTemplate | undefined; getEventByName(name: string): EventTemplate | undefined; getEventByIndex(index: number): EventTemplate | undefined; } /** * Which category a resource manager belongs to. dotnet discriminates * `IPermissionsManager`/`IRateControlManager`/`IAuditingManager` at runtime * via `is` pattern-matching over their (otherwise-empty) marker interface; * TS has no equivalent runtime interface check, so every concrete manager * carries this brand instead. */ type ManagerCategory = "permissions" | "rateControl" | "auditing"; /** * Identifies a manager that participates in resource operation processing * (port of C# `IResourceManager`). Category interfaces add the behavior * appropriate to each manager type. */ interface IResourceManager { readonly managerCategory: ManagerCategory; } /** A named enum constant. */ interface EnumConstant { name: string; value: number; index: number; } /** * Describes an enumeration for serialization (port of the enum side of C# * `TypeDef`/`LocalTypeDef`). Since a TS enum value is a bare number, wrap values * with {@link value}/{@link enumValue} so the serializer knows the enum type. */ declare class EnumType { readonly name: string; readonly constants: EnumConstant[]; constructor(name: string, members: Record); /** Wrap a numeric value as an {@link EnumValue} for serialization. */ value(v: number): EnumValue; } /** A value tagged with its {@link EnumType} for serialization. */ declare class EnumValue { readonly enumType: EnumType; readonly value: number; constructor(enumType: EnumType, value: number); } /** Define an enum type, e.g. `defineEnum("Color", { Red: 0, Green: 1, Blue: 2 })`. */ declare function defineEnum(name: string, members: Record): EnumType; /** Tag a numeric value with an enum type for serialization. */ declare function enumValue(enumType: EnumType, value: number): EnumValue; /** * Accumulating receive buffer (port of C# `NetworkBuffer`). The protocol parser * drains it with {@link read}; when a partial unit remains, it calls * {@link protect}/{@link holdFor} to push the unparsed tail back so it is * prepended to the next {@link write}. {@link protected_} is true while waiting * for more bytes. */ declare class NetworkBuffer { private data; private neededDataLength; /** True while more bytes are required before the held data can be read. */ get protected_(): boolean; /** Number of buffered bytes. */ get available(): number; /** Hold the next write, expecting at least `src.length + 1` bytes total. */ holdForNextWrite(src: Uint8Array): void; /** Prepend `src[offset..offset+size]` to the buffer and wait for `needed` bytes. */ holdFor(src: Uint8Array, offset: number, size: number, needed: number): void; /** * If `src` from `offset` has fewer than `needed` bytes, hold the remainder and * return true (caller should stop and wait); otherwise return false. */ protect(src: Uint8Array, offset: number, needed: number): boolean; /** Append bytes to the buffer. */ write(src: Uint8Array, offset?: number, length?: number): void; /** True if a full held unit (or any data, when not holding) is available. */ get canRead(): boolean; /** Take all buffered bytes if available (respecting any hold), else null. */ read(): Uint8Array | null; } /** Receives transport events from an {@link ISocket} (port of C# `INetworkReceiver`). */ interface INetworkReceiver { networkClose(sender: T): void; networkReceive(sender: T, buffer: NetworkBuffer): void; networkConnect(sender: T): void; } /** Lifecycle state of an {@link ISocket} (port of C# `SocketState`). */ declare enum SocketState { Initial = 0, Listening = 1, Connecting = 2, Established = 3, Closed = 4 } /** * Transport abstraction (port of C# `ISocket`, trimmed to the isomorphic * surface). Implementations wrap a WebSocket or TCP socket and push inbound * bytes to their {@link receiver}. */ interface ISocket extends IDestructible { readonly state: SocketState; receiver?: INetworkReceiver; /** Send bytes to the peer. */ send(message: Uint8Array): void; /** Close the connection. */ close(): void; /** Connect to a remote endpoint (client sockets); resolves once established. */ connect(url: string): AsyncReply; } /** * Base for a logical connection over an {@link ISocket} (port of C# * `NetworkConnection`). Owns the socket, drains inbound buffers to * {@link dataReceived}, and exposes send helpers. Subclasses implement the * protocol-specific framing. */ declare abstract class NetworkConnection implements INetworkReceiver, IDestructible { protected socket?: ISocket; private receivingFlag; readonly onConnect: EventHandler; readonly onClose: EventHandler; private readonly destroyHandlers; /** Attach a socket and route its events here. */ assign(socket: ISocket): void; /** Detach the socket without closing it (e.g. for a protocol upgrade). */ unassign(): ISocket | undefined; get isConnected(): boolean; send(message: Uint8Array): void; close(): void; networkConnect(_socket: ISocket): void; networkClose(_socket: ISocket): void; networkReceive(_sender: ISocket, buffer: NetworkBuffer): void; protected abstract dataReceived(buffer: NetworkBuffer): void; protected abstract connected(): void; protected abstract disconnected(): void; addDestroyHandler(handler: DestroyedEvent): void; removeDestroyHandler(handler: DestroyedEvent): void; destroy(): void; } /** Request actions, in the low 5 bits of the header (port of C# `EpPacketRequest`). */ declare enum EpPacketRequest { InvokeFunction = 0, SetProperty = 1, Subscribe = 2, Unsubscribe = 3, /** Batch name → id lookup (request: `string[]`, reply: `ulong[]`). */ TypeDefIdsByNames = 8, TypeDefById = 9, TypeDefByResourceId = 10, Query = 11, LinkTypeDefs = 12, Token = 13, GetResourceIdByLink = 14, AttachResource = 16, ReattachResource = 17, DetachResource = 18, CreateResource = 19, DeleteResource = 20, MoveResource = 21, KeepAlive = 24, ProcedureCall = 25, StaticCall = 26, IndirectCall = 27, PullStream = 28, TerminateExecution = 29, HaltExecution = 30, ResumeExecution = 31 } /** Reply actions, in the low 5 bits of the header (port of C# `EpPacketReply`). */ declare enum EpPacketReply { Completed = 0, Propagated = 1, Stream = 2, PermissionError = 4, ExecutionError = 5, Progress = 8, Chunk = 9, Warning = 10 } /** Notification actions, in the low 5 bits of the header (port of C# `EpPacketNotification`). */ declare enum EpPacketNotification { PropertyModified = 0, EventOccurred = 1, ResourceDestroyed = 8, ResourceReassigned = 9, ResourceMoved = 10, SystemFailure = 11 } /** Which parties prove identity during the handshake (port of C# `AuthenticationMode`). */ declare enum AuthenticationMode { None = 0, InitializerIdentity = 1, ResponderIdentity = 2, DualIdentity = 3 } /** Transport encryption mode (port of C# `EncryptionMode`). */ declare enum EncryptionMode { None = 0, EncryptWithSessionKey = 1, EncryptWithSessionKeyAndAddress = 2 } /** Material kinds passed to authentication providers. */ declare enum AuthenticationMaterialType { Secret = 0, Key = 1, Identity = 2, Data = 3 } /** Extra material passed to an authentication provider when creating a handler. */ interface AuthenticationMaterial { type: AuthenticationMaterialType; value: unknown; } /** Which side of the authentication exchange this handler represents. */ declare enum AuthenticationDirection { Initiator = 0, Responder = 1 } /** Context used by an authentication provider to create a per-connection handler. */ interface AuthenticationContext { direction: AuthenticationDirection; mode: AuthenticationMode; domain?: string | null; initiatorIdentity?: string | null; responderIdentity?: string | null; materials?: AuthenticationMaterial[]; hostName?: string | null; } /** Header keys carried in an auth packet's TypedMap (port of C# `EpAuthPacketHeader`). */ declare enum EpAuthPacketHeader { Version = 0, Domain = 1, SupportedAuthentications = 2, SupportedHashAlgorithms = 3, SupportedCiphers = 4, SupportedCompression = 5, SupportedMultiFactorAuthentications = 6, CipherType = 7, CipherKey = 8, SoftwareIdentity = 9, Referrer = 10, Time = 11, IPAddress = 12, Identity = 13, AuthenticationProtocol = 14, AuthenticationData = 15, ErrorMessage = 16, /** Fresh public nonce used with the authenticated session key to derive unique per-connection encryption keys. */ CipherNonce = 17 } /** * Authenticated and negotiated material used to create a session cipher * (port of C# `EncryptionContext`). Initiator/responder values always retain * their protocol roles, regardless of which peer creates the cipher. */ interface EncryptionContext { /** Shared secret produced by the authentication provider. */ key: Uint8Array; /** Role of the peer creating the cipher. */ direction: AuthenticationDirection; /** Negotiated encryption mode. */ mode: EncryptionMode; /** Negotiated provider protocol name. */ protocol: string; /** Encryption protocols offered by the initiator, in their original wire order. */ offeredProtocols: readonly string[]; /** Authentication mode that produced the shared session key. */ authenticationMode: AuthenticationMode; /** Negotiated authentication protocol that produced the shared key. */ authenticationProtocol: string; /** Authentication realm/domain requested by the initiator. */ domain: string | null; /** Fresh public nonce generated by the session initiator. */ initiatorNonce: Uint8Array; /** Fresh public nonce generated by the session responder. */ responderNonce: Uint8Array; /** Initiator address used by address-bound encryption mode. */ initiatorAddress?: Uint8Array | null; /** Responder address used by address-bound encryption mode. */ responderAddress?: Uint8Array | null; } /** * A per-session symmetric record cipher (port of C# `ISymetricCipher`). * `encrypt`/`decrypt` are deliberately synchronous — they run on * `NetworkConnection`'s hot send/receive path, which has no async contract * (see `AesEncryptionProvider.ts` for how the Node-only implementation keeps * this true despite deriving key material asynchronously at construction). */ interface ISymetricCipher { readonly identifier: number; encrypt(data: Uint8Array): Uint8Array; decrypt(data: Uint8Array): Uint8Array; /** Initialize the cipher key. Session ciphers are immutable after their one call. */ setKey(key: Uint8Array): Uint8Array; } /** * Creates a per-session symmetric cipher from authenticated session material * (port of C# `IEncryptionProvider`). Providers are registered and * negotiated by {@link defaultName}. * * `createCipher` is async (unlike C#'s synchronous method) purely so a * Node-only implementation can dynamically import `node:crypto` once, at * cipher-creation time — this runs once per session during the handshake, * not on the hot per-record path, so it doesn't ripple into * `ISymetricCipher.encrypt`/`decrypt`'s (or `ISocket.send`'s) synchronous * contract. */ interface IEncryptionProvider { readonly defaultName: string; /** * Maximum bytes {@link ISymetricCipher.encrypt} adds to one plaintext * record. Used to reject an oversized send before it consumes a cipher * sequence number. */ readonly maximumRecordOverhead: number; createCipher(context: EncryptionContext): Promise; } /** Authenticated session metadata exposed to provider login/logout hooks. */ interface AuthenticationSession { authenticationMode: AuthenticationMode; localHeaders: Map; remoteHeaders: Map; localIdentity: string | null; remoteIdentity: string | null; key: Uint8Array | null; authenticated: boolean; variables: Map; /** Negotiated transport encryption mode. */ encryptionMode: EncryptionMode; /** The negotiated {@link IEncryptionProvider}, once selected during the handshake. */ encryptionProvider: IEncryptionProvider | null; /** The session's record cipher, once {@link encryptionProvider} has derived it. */ symetricCipher: ISymetricCipher | null; /** True once outbound/inbound records are actually being protected. */ encryptionActive: boolean; } /** Result state returned by an authentication handler step. */ declare enum AuthenticationRuling { Failed = 0, InProgress = 1, Succeeded = 2 } /** Result returned by one authentication handler step. */ declare class AuthenticationResult { readonly ruling: AuthenticationRuling; readonly authenticationData: unknown; readonly localIdentity: string | null; readonly remoteIdentity: string | null; readonly sessionKey: Uint8Array | null; readonly exceptionCode: ExceptionCode | null; readonly exceptionMessage: string | null; constructor(ruling: AuthenticationRuling, authenticationData: unknown, localIdentity?: string | null, remoteIdentity?: string | null, sessionKey?: Uint8Array | null, exceptionCode?: ExceptionCode | null, exceptionMessage?: string | null); } /** Per-connection authentication state machine. */ interface IAuthenticationHandler { readonly provider: IAuthenticationProvider; readonly protocol: string; process(authData: unknown): AuthenticationResult; } type AuthenticationProviderReply = boolean | PromiseLike | AsyncReply; /** Factory and lifecycle hooks for an authentication protocol. */ interface IAuthenticationProvider { readonly defaultName: string; createAuthenticationHandler(context: AuthenticationContext): IAuthenticationHandler | null; login?(session: AuthenticationSession): AuthenticationProviderReply; logout?(session: AuthenticationSession): AuthenticationProviderReply; } /** * A resource whose properties aren't backed by real class fields — e.g. a * remote {@link EpResource} proxy, whose values live in a wire-driven cache * indexed by property number rather than named class members. Implementing * this lets {@link Instance} read/write/serialize it the same way it does a * locally-defined resource (port of C# `IDynamicResource`). */ interface IDynamicResource { /** The TypeDef describing this resource's shape (bypasses constructor-based lookup). */ readonly resourceDefinition: TypeDef; getResourceProperty(index: number): unknown; setResourceProperty(index: number, value: unknown): void; getResourcePropertyAge(index: number): number; getResourcePropertyDate(index: number): Date | undefined; } /** Notification payload for a remote property change. */ interface RemotePropertyChange { name: string; index: number; value: unknown; age?: number; date?: Date; } /** Snapshot metadata for one remote property value. */ interface RemotePropertyValue { index: number; age: number; date?: Date; value: unknown; } interface EpResourceOptions { typeDefId?: number; age?: number; link?: string; hops?: number; } /** Constructor shape emitted by generated TypeScript remote resource stubs. */ type EpResourceConstructor = new (connection: EpConnection, instanceId: number, age: number, link: string) => T; /** * A remote resource proxy (port of C# `EpResource`). Wraps a connection + * instance id + TypeDef; exported functions invoke remotely, exported * properties read from a locally-cached value (kept fresh by PropertyModified * notifications), and exported events surface via {@link eventOccurred}. * * Use {@link createProxy} to get an ergonomic object where `res.sayHi(x)` and * `res.counts` work directly. * * Implements {@link IResource}/{@link IDynamicResource} so it can be * `warehouse.put()` into this node's own warehouse — every proxy is itself a * resource with a life cycle, and once put, a third node connecting to this * one can attach to it too, relaying reads/writes/invokes/events through to * the original connection transparently. */ declare class EpResource implements IResource, IDynamicResource { /** Assigned by the {@link Warehouse} on `put()` — absent until relayed. */ instance?: Instance; private readonly destroyHandlers; /** Property index to last known value. */ readonly cache: Map; /** Property index to last known property age. */ readonly propertyAges: Map; /** Property index to last known modification date. */ readonly propertyModificationDates: Map; /** Fires when a property is updated by a notification. */ readonly propertyModified: EventHandler; /** Fires when a remote event occurs. */ readonly eventOccurred: EventHandler; /** `.on(":name", cb)` listeners, keyed by property index. */ private readonly propertyListeners; /** `.on("name", cb)` listeners, keyed by event index. */ private readonly eventListeners; /** Events we believe the server currently has us subscribed to — checked * before sending a Subscribe/Unsubscribe request, since the server errors * (`AlreadyListened`/`AlreadyUnsubscribed`) on a redundant one. */ private readonly subscribedEvents; /** Event indices with a subscription-reconciliation loop currently running. */ private readonly reconciling; typeDefId?: number; age: number; link: string; hops: number; connection: EpConnection; instanceId: number; typeDef: TypeDef; /** Array alias used by generated stubs (`this.properties[index]`). */ protected readonly properties: unknown[]; /** .NET-name alias used by generated stubs (`this._properties[index]`). */ protected readonly _properties: unknown[]; constructor(); constructor(connection: EpConnection, instanceId: number, typeDef: TypeDef, options?: EpResourceOptions); constructor(connection: EpConnection, instanceId: number, age: number, link?: string); /** * Listen for a property change (`.on(":propName", cb)`) or an exported * event (`.on("eventName", cb)`). For events where the TypeDef marks * `subscribable` (i.e. not `autoDelivered`), the first listener triggers a * `Subscribe` request and the last {@link off} triggers `Unsubscribe` — * ref-counted by listener count, so redundant wire requests aren't sent * for a second/third listener on the same already-subscribed event. */ on(name: string, callback: (value: unknown) => void): this; /** Remove a listener registered with {@link on}. */ off(name: string, callback: (value: unknown) => void): this; /** * Settle the wire subscription state for event `index` toward whatever the * current listener count implies, retrying against the *current* desired * state on each step — so a burst of `on()`/`off()` calls while a request * is in flight is coalesced into whatever the state actually is once the * in-flight request settles, rather than replaying every transition. */ private reconcileSubscription; /** * @internal After a reattach on a fresh connection (post-reconnect), our * belief about server-side subscription state is stale — a brand-new * connection starts with no subscriptions of its own, even for events we * were subscribed to before the disconnect. Clear that belief and re-run * reconciliation for every event that still has active listeners (from * `.on()` or, on the .NET side's equivalent, `+=`), so subscriptions * survive a reconnect transparently. */ resubscribeAfterReconnect(): void; /** @deprecated Use {@link typeDef}. */ get template(): TypeDef; /** .NET-compatible alias for {@link connection}. */ get ResourceConnection(): EpConnection; /** .NET-compatible alias for {@link link}. */ get ResourceLink(): string; /** .NET-compatible alias for {@link instanceId}. */ get ResourceInstanceId(): number; set ResourceInstanceId(value: number); /** .NET-compatible alias for {@link typeDef}. */ get ResourceDefinition(): TypeDef; set ResourceDefinition(value: TypeDef); /** @internal Initialize an instance created from a generated subclass. */ initializeRemote(connection: EpConnection, instanceId: number, typeDef: TypeDef, options?: EpResourceOptions): void; /** @internal Update resource-level metadata returned by attach/reattach. */ setRemoteIdentity(options: EpResourceOptions & { instanceId?: number; }): void; /** @internal Seed or merge a property snapshot without implying a notification. */ setPropertySnapshot(index: number, age: number, date: Date | undefined, value: unknown): void; /** Last known age for a property index. */ getAge(index: number): number; /** Last known modification date for a property index. */ getModificationDate(index: number): Date | undefined; /** @internal Merge a sparse reattach delta. */ applyDelta(delta: readonly RemotePropertyValue[]): void; /** @internal Apply a property value pushed by the server. */ updateProperty(index: number, value: unknown, age?: number, date?: Date): void; /** @internal Apply an event occurrence pushed by the server. */ applyEvent(index: number, value: unknown): void; /** Invoke a remote function by index. Used by generated EpResource stubs. */ protected _Invoke(index: number, args?: unknown): AsyncReply; /** Older generated-stub alias for invoking by positional argument array. */ protected _InvokeByArrayArguments(index: number, args?: readonly unknown[]): AsyncReply; /** Read a cached remote property by index. Used by generated EpResource stubs. */ protected GetResourceProperty(index: number): T; /** Set a remote property asynchronously by index. */ protected SetResourcePropertyAsync(index: number, value: unknown): AsyncReply; /** camelCase alias for {@link SetResourcePropertyAsync}. */ protected setResourcePropertyAsync(index: number, value: unknown): AsyncReply; /** Set a remote property by index and update the local cache optimistically. */ protected SetResourceProperty(index: number, value: unknown): AsyncReply; /** Override point for generated typed event dispatch. */ protected _EmitEventByIndex(_index: number, _value: unknown): void; private setLocalProperty; private requireConnection; /** Wrap an {@link EpResource} in an ergonomic dynamic proxy. */ static createProxy(resource: EpResource): EpResource & Record; handle(_operation: ResourceOperation, _context?: IResourceContext): AsyncReply; addDestroyHandler(handler: DestroyedEvent): void; removeDestroyHandler(handler: DestroyedEvent): void; destroy(): void; get resourceDefinition(): TypeDef; getResourceProperty(index: number): T; /** Forward a write to the upstream connection this proxy is relaying — the same path the ergonomic proxy's `set` trap uses. */ setResourceProperty(index: number, value: unknown): AsyncReply; getResourcePropertyAge(index: number): number; getResourcePropertyDate(index: number): Date | undefined; /** Invoke a remote function by index — the same path the ergonomic proxy's function-call trap uses. */ invoke(index: number, args: unknown[]): AsyncReply; } /** * Documentation/semantics metadata shared by every member kind, introduced * alongside the `IndexedStructure`-based wire format. Absent (`undefined`) * for members decoded from the legacy manual byte format. */ interface RemoteMemberMetadata { deprecated?: boolean; deprecationMessage?: string; description?: string; usage?: string; examples?: unknown[]; tags?: string[]; unit?: string; minimum?: unknown; maximum?: unknown; allowedValues?: unknown[]; pattern?: string; format?: string; preconditions?: string[]; postconditions?: string[]; /** {@link import("../data/types/OperationEffects.js").OperationEffects} bitmask. */ effects?: number; warnings?: string[]; relatedMembers?: number[]; } interface RemoteArgumentDef extends RemoteMemberMetadata { index: number; name: string; type?: Tru; optional: boolean; variadic?: boolean; defaultValue?: unknown; annotations?: Map; } interface RemoteFunctionDef extends RemoteMemberMetadata { index: number; name: string; returnType?: Tru; arguments: RemoteArgumentDef[]; inherited: boolean; isStatic: boolean; readOnly?: boolean; idempotent?: boolean; cancellable?: boolean; pausable?: boolean; /** {@link import("../data/types/StreamMode.js").StreamMode} bitmask. */ streamMode?: number; annotations?: Map; } interface RemotePropertyDef extends RemoteMemberMetadata { index: number; name: string; valueType?: Tru; inherited: boolean; /** Legacy 2-bit permission field; not populated by the new-format decoder (unused downstream — see `readOnly`/`constant`/`volatile`). */ permission: number; hasHistory: boolean; readOnly?: boolean; constant?: boolean; volatile?: boolean; orderingControl?: number; historyControl?: number; defaultValue?: unknown; annotations?: Map; } interface RemoteEventDef extends RemoteMemberMetadata { index: number; name: string; argumentType?: Tru; argumentName?: string; inherited: boolean; subscribable: boolean; autoDelivered?: boolean; orderingControl?: number; historyControl?: number; annotations?: Map; } interface RemoteConstantDef extends RemoteMemberMetadata { index: number; name: string; valueType?: Tru; value: unknown; inherited: boolean; annotations?: Map; } interface RemoteTypeDefSnapshot { id: number; name: string; kind: string; version: number; parentTypeId?: number; annotations?: Record; properties: Array>; functions: Array>; events: Array>; constants: Array>; } declare class RemoteTypeDef implements ITypeDef { template: TypeDef; private cachedProperties; private _id; private _kind; private _name; private _version; private _parentTypeId; private _annotations; private _remoteProperties; private _remoteFunctions; private _remoteEvents; private _remoteConstants; get id(): number; get kind(): TypeDefKind; get name(): string; get version(): number; get parentTypeId(): number | undefined; get annotations(): Map | undefined; get remoteProperties(): ReadonlyArray; get remoteFunctions(): ReadonlyArray; get remoteEvents(): ReadonlyArray; get remoteConstants(): ReadonlyArray; hydrate(id: number, kind: TypeDefKind, name: string, version: number, parentTypeId: number | undefined, annotations: Map | undefined, remoteProperties: RemotePropertyDef[], remoteFunctions: RemoteFunctionDef[], remoteEvents: RemoteEventDef[], remoteConstants: RemoteConstantDef[]): void; get properties(): TypeDefProperty[]; get constants(): TypeDefConstant[]; createInstance(): object; setProperty(instance: object, name: string, value: unknown): void; toJSON(): RemoteTypeDefSnapshot; static parse(data: Uint8Array, warehouse?: unknown): RemoteTypeDef; static parseAsync(data: Uint8Array, warehouse?: unknown, remoteResolver?: RemoteTypeDefResolver, requestSequence?: readonly number[] | null): Promise; static parseAsyncInto(target: RemoteTypeDef, data: Uint8Array, warehouse?: unknown, remoteResolver?: RemoteTypeDefResolver, requestSequence?: readonly number[] | null): Promise; } /** Handles an inbound request packet (server-side dispatch). */ type RequestHandler = (connection: EpConnection, action: EpPacketRequest, callbackId: number, tdu: PlainTdu | null) => void; /** Handles an inbound notification packet. */ type NotificationHandler = (connection: EpConnection, action: EpPacketNotification, tdu: PlainTdu | null) => void; interface EpConnectionOptions { /** Reconnect automatically after an unexpected client-side disconnect. */ autoReconnect?: boolean; /** .NET-compatible alias for {@link autoReconnect}. */ AutoReconnect?: boolean; /** Delay between reconnect attempts, in milliseconds. */ reconnectInterval?: number; /** .NET-compatible alias for {@link reconnectInterval}. */ ReconnectInterval?: number; /** Authentication mode requested by the initiator. Default `None`. */ authenticationMode?: AuthenticationMode; /** .NET-compatible alias for {@link authenticationMode}. */ AuthenticationMode?: AuthenticationMode; /** Authentication protocol name. Default `"password-sha3-v1"`. */ authenticationProtocol?: string; /** .NET-compatible alias for {@link authenticationProtocol}. */ AuthenticationProtocol?: string; /** Transport encryption mode requested by the initiator. Default `None`. */ encryptionMode?: EncryptionMode; /** .NET-compatible alias for {@link encryptionMode}. */ EncryptionMode?: EncryptionMode; /** Provider used to create the initiator authentication handler. */ authenticationProvider?: IAuthenticationProvider; /** PascalCase alias for {@link authenticationProvider}. */ AuthenticationProvider?: IAuthenticationProvider; /** Initiator identity for protocols that need one. */ identity?: string; /** .NET-compatible alias for {@link identity}. */ Identity?: string; /** Optional responder identity for protocols that need one. */ responderIdentity?: string; /** PascalCase alias for {@link responderIdentity}. */ ResponderIdentity?: string; /** Remote domain. Defaults to the WebSocket host. */ domain?: string; /** .NET-compatible alias for {@link domain}. */ Domain?: string; /** * Absolute `ws`/`wss` URL used verbatim as the socket transport, overriding * whatever host/port was parsed from the `Warehouse.get`/`connect` path. * Lets a resource path (e.g. `sys/counter`) and a WebSocket upgrade route * that doesn't match it (e.g. an ASP.NET Core host mounting Esiur at * `/esiur`) be specified independently — mirrors dotnet's * `EpConnectionContext.WebSocketUri`, which is used as-is, never * concatenated with the resource path. */ webSocketUri?: string | URL; /** .NET-compatible alias for {@link webSocketUri}. */ WebSocketUri?: string | URL; } /** .NET-compatible connection context accepted by `Warehouse.get` and `EpConnection.connect`. */ declare class EpConnectionContext implements EpConnectionOptions { AutoReconnect?: boolean; ReconnectInterval?: number; AuthenticationMode?: AuthenticationMode; AuthenticationProtocol?: string; AuthenticationProvider?: IAuthenticationProvider; EncryptionMode?: EncryptionMode; Identity?: string; ResponderIdentity?: string; Domain?: string; WebSocketUri?: string | URL; constructor(options?: EpConnectionOptions); } interface EpReconnectMetrics { connectMs: number; reattachMs: number; recoveryMs: number; restoredResources: number; failedResources: number; } type EpResourceAttachTarget = TypeDef | EpResourceConstructor; /** * IIP/Ep connection — request/reply correlation and packet dispatch * (the backbone of C# `EpConnection`/`EpConnectionProtocol`). * * This build implements the request/reply engine, SHA3 password-hash * authentication, resource operations, and reply decoding. Incoming * requests/notifications can still be surfaced via {@link onRequest}/ * {@link onNotification} for custom protocol handlers. */ declare class EpConnection extends NetworkConnection { /** Warehouse used to resolve types/resources during (de)serialization. */ warehouse?: Warehouse; /** Invoked for inbound Request packets. */ onRequest?: RequestHandler; /** Invoked for inbound Notification packets. */ onNotification?: NotificationHandler; private readonly requests; private callbackCounter; private readonly packet; /** Remote resources attached through this connection (instance id → proxy state). */ private readonly attachedResources; /** * The raw {@link EpResource} behind an id returned by {@link get}/{@link attach} * (which hand back the ergonomic dot-access proxy instead). Needed to * `warehouse.put()` a fetched resource for relaying to a third node — the * warehouse machinery needs the real object, not a Proxy wrapper, so it can * assign `.instance` and use it as an `IDynamicResource` directly. */ getAttachedResource(instanceId: number): EpResource | undefined; /** Remote TypeDefs currently needed by an in-flight parse (type id to placeholder). */ private readonly neededTypeDefs; /** Fully parsed remote TypeDefs (type id to definition). */ private readonly cachedTypeDefs; /** In-flight TypeDef fetches, used to share work and detect recursive cycles. */ private readonly typeDefRequests; /** Wait-for graph for in-flight remote TypeDef parsing. */ private readonly typeDefsFetchBlockedOn; /** Server-side notification subscriptions (instance id → unsubscribe). */ private readonly subscriptions; /** * Server-side explicit per-event subscriptions (instance id → subscribed * event indices), consulted only for events where {@link EventTemplate.subscribable} * is true — other events keep being pushed to every attached connection * unconditionally, as `subscribeToInstance` already does. */ private readonly eventSubscriptions; /** * Per (instanceId, eventIndex) marker listener used to ref-count an * upstream `.on()` subscription when relaying a `subscribable` event * through an {@link EpResource} — keeps the upstream connection subscribed * only while at least one downstream peer here still is. */ private readonly relayListeners; /** * In-flight streamed calls, keyed by the *originating* `InvokeFunction`/ * `StaticCall` request's callback id — the same id `PullStream`/ * `TerminateExecution`/`HaltExecution`/`ResumeExecution` reference as * their "execution callback" (see `sendStreamRequest`, the client-side * counterpart that keys these the same way). */ private readonly invocations; /** * True once the connection is past the auth phase. Defaults to true so a * directly-`assign`ed connection processes packets immediately; `connect` and * `EpServer` switch it off to run the (anonymous) handshake first. */ private authenticated; private authSessionEstablished; private direction; private readonly authPacket; private readyReply?; private domain; private hostName; private authenticationMode; private encryptionMode; private encryptionProvider; private symetricCipher; /** True once inbound records are being decrypted (mirrors dotnet's `_decryptInbound`). */ private decryptInbound; /** True once outbound records are being encrypted. */ private encryptionActive; /** Encryption protocols offered in this connection's own Initialize headers (initiator only). */ private offeredEncryptionProviders; private authenticationProtocol; private authenticationProvider?; private authenticationHandler?; private localIdentity; private remoteIdentity; private responderIdentity; private sessionKey; private readonly localHeaders; private readonly remoteHeaders; private readonly variables; /** Responder: accept unauthenticated (anonymous, None-mode) peers. */ allowUnauthorized: boolean; /** Reconnect automatically after an unexpected client-side disconnect. */ autoReconnect: boolean; /** Delay between reconnect attempts, in milliseconds. */ reconnectInterval: number; /** Metrics from the most recent reconnect attempt. */ lastReconnectMetrics?: EpReconnectMetrics; /** True once the authentication phase has completed. */ get isAuthenticated(): boolean; /** Local identity reported by the authentication handler. */ get localAuthenticationIdentity(): string | null; /** Remote identity reported by the authentication handler. */ get remoteAuthenticationIdentity(): string | null; /** Derived session key, when the selected authentication protocol creates one. */ get authenticationSessionKey(): Uint8Array | null; private reconnectUrl?; private reconnectTimer?; private reconnectReply?; private manualClose; private lastRestoreStats; /** Begin the client-side handshake; resolves via {@link whenReady}. */ startInitiatorHandshake(domain?: string): void; /** Begin the server-side handshake (waits for the peer's Initialize). */ startResponderHandshake(): void; /** Resolves when the handshake completes (initiator side). */ whenReady(): AsyncReply; /** * Open a client connection to `url` over WebSocket, run the anonymous * handshake, and resolve once the session is established. */ static connect(url: string, warehouseOrOptions?: Warehouse | EpConnectionOptions, options?: EpConnectionOptions): Promise; private applyOptions; private openClientSocket; /** * Choose the transport for `url`'s scheme. Unlike C#'s `CreateClientSocket` * (which picks `TcpSocket` vs `FrameworkWebSocket` based on whether * `WebSocketUri`/a browser runtime is in play, since dotnet's connect API * takes a bare host/port), esiur-ts's `connect()`/`Warehouse.get()` always * take a single URL string — so the URL's own scheme is the natural, * explicit selector here: `tcp://host:port` dials a raw {@link TcpSocket} * (Node-only; esiur-dotnet servers exposing only their native `TcpServer`, * with no WebSocket upgrade route, are otherwise unreachable from * esiur-ts), anything else (`ws://`/`wss://`/`ep://`/`eps://`) keeps using * {@link WSocket} as before. */ private createClientSocket; /** Send the initiator's Initialize packet. */ private declare; /** Initiator: offer supported cipher names and a fresh nonce before sending Initialize. */ private prepareEncryptionOffer; /** * Responder: negotiate an offered cipher against this connection's * registered providers, mutating `localHeaders` (the Acknowledge headers * about to be sent) with the selection. */ private negotiateEncryptionAsResponder; /** Initiator: accept the responder's cipher selection from its Acknowledge headers. */ private acceptEncryptionAsInitiator; private rejectEncryption; /** * Once a session key and negotiated provider are available, derive the * session cipher (port of C# `PrepareSessionEncryption`). Async only * because {@link IEncryptionProvider.createCipher} may need to resolve a * Node-only crypto module once per session — see `AesEncryptionProvider.ts`. */ private prepareSessionEncryption; /** Turn on record protection for both directions once the cipher is ready. */ private enableEncryption; /** Handle an auth-phase packet. */ private handleAuthPacket; private handleAuthInitialize; private handleAuthAcknowledge; private handleAuthAction; private handleAuthEvent; private getOrCreateInitiatorAuthenticationHandler; private requireAuthenticationHandler; private composeAuthHeaders; private sendAuth; private sendAuthData; private sendAuthHeaders; private parseAuthHeaders; private decodeAuthValue; private readAuthErrorMessage; private storeAuthenticationResult; private completeAuthentication; private finishAuthenticationReady; private failAuthentication; private getAuthenticationSession; /** Send a request and return a reply that settles when the peer responds. */ sendRequest(action: EpPacketRequest, ...args: unknown[]): AsyncReply; /** Invoke function `index` on the resource with `instanceId`, resolving its result. */ invoke(instanceId: number, index: number, ...args: unknown[]): AsyncReply; /** Invoke a `static` exported function `index` on TypeDef `typeId` — no resource instance involved. */ staticCall(typeId: number, index: number, ...args: unknown[]): AsyncReply; /** * Send a stream-flavored request: the callback id also drives * `PullStream`/`TerminateExecution`/`HaltExecution`/`ResumeExecution` * against the same remote invocation via the returned {@link AsyncStreamReply}. */ sendStreamRequest(streamMode: StreamMode, action: EpPacketRequest, ...args: unknown[]): AsyncStreamReply; /** Invoke a streaming function `index` on the resource with `instanceId`. */ invokeStream(streamMode: StreamMode, instanceId: number, index: number, ...args: unknown[]): AsyncStreamReply; /** Invoke function `index` with an already-shaped argument payload. */ invokeWithArguments(instanceId: number, index: number, args: unknown): AsyncReply; /** Set property `index` on the resource with `instanceId`. */ set(instanceId: number, index: number, value: unknown): AsyncReply; /** * Subscribe to event `index` on the resource with `instanceId` — required * before the server pushes `EventOccurred` notifications for events where * {@link RemoteEventDef.subscribable} is true (`autoDelivered` events are * pushed unconditionally and never need this). The server errors * (`AlreadyListened`) on a duplicate call for an already-subscribed event, * so callers must track subscription state themselves — see * {@link EpResource.on}, which does this per-event, ref-counted by listener * count, rather than sending on every call. */ subscribe(instanceId: number, index: number): AsyncReply; /** Unsubscribe from event `index` on the resource with `instanceId`. See {@link subscribe}. */ unsubscribe(instanceId: number, index: number): AsyncReply; /** Resolve a resource path to a {@link ResourceId} reference. */ getResourceIdByLink(link: string): AsyncReply; /** Stop receiving notifications for a resource on this connection (it keeps living for other subscribers). */ detach(instanceId: number): AsyncReply; /** Rename a resource (single path segment — no `/`). */ moveResource(instanceId: number, newName: string): AsyncReply; /** Remove a resource from the peer's warehouse. */ deleteResource(instanceId: number): AsyncReply; /** * Create a resource of a type already registered on the peer's warehouse. * `properties` is keyed by wire property index; replies with the new * resource's instance id. */ createResource(path: string, typeIdOrName: number | string, properties?: Map, attributes?: Map): AsyncReply; /** * Resolve a resource path, replying with its children as `[id, link]` * pairs (see `epRequestQueryResources`'s doc comment for why this isn't * full auto-attaching resource references, unlike dotnet's `Query`). * Distinct from {@link getResourceIdByLink}, which resolves a single link. */ queryResources(path: string): AsyncReply>; /** Bulk-fetch a resource type's full TypeDef dependency graph in one round trip. */ fetchLinkedTypeDefs(path: string): AsyncReply; /** Fetch and parse the runtime TypeDef for a remote resource id. */ fetchTypeDefByResourceId(instanceId: number): AsyncReply; /** Fetch and parse a runtime TypeDef by its remote TypeDef id. */ fetchTypeDefById(typeDefId: number): AsyncReply; /** Batch-resolve full class names to their remote TypeDef ids. */ getTypeDefIds(fullNames: string[]): AsyncReply; /** Fetch and parse a runtime TypeDef by id, resolving cyclic remote TypeDef references. */ fetchTypeDef(typeDefId: number, requestSequence?: readonly number[] | null): AsyncReply; private expectTypeDefPayload; private parseTypeDefPayload; private finishTypeDefRequest; private addTypeDefFetchBlock; private clearTypeDefFetchNode; private hasTypeDefWaitForCycle; /** * Resolve and attach a remote resource by its path on this connection. When * `typeDef` is omitted, its TypeDef is fetched from the server first (one * extra round trip) — mirrors dotnet's `Get`, which never needs a * caller-supplied type because C# generates the proxy dynamically. */ get(path: string, target?: EpResourceAttachTarget): AsyncReply; /** .NET-compatible alias for {@link get}. */ Get(path: string, target?: EpResourceAttachTarget): AsyncReply; /** Reopen the WebSocket session and reattach all known remote resources. */ reconnect(): AsyncReply; /** * Attach to a remote resource, returning a live {@link EpResource}. Passing * a generated EpResource subclass instantiates that class; passing a TypeDef * keeps the dynamic-proxy behavior. */ attach(instanceId: number): AsyncReply; attach(instanceId: number, typeDef: TypeDef): AsyncReply; attach(instanceId: number, ctor: EpResourceConstructor): AsyncReply>; attach(instanceId: number, target?: EpResourceAttachTarget): AsyncReply; private attachWithTypeDef; private resolveAttachTarget; private createAttachedResource; private findProxyType; /** * Reattach an already-known resource by link or instance id, sending its * last-known age. The peer returns only properties modified after that * age. Prefer the link — the remote node may have freed/recreated the * resource since, so its id is not permanent, but the link is. The reply * leads with the resolved id so an id change (link re-resolved to a * different instance) can be detected and tracking re-keyed. */ reattach(resourceLinkOrId: string | number, age: number, resource: EpResource): AsyncReply; /** Send a reply to a peer request. */ sendReply(action: EpPacketReply, callbackId: number, ...args: unknown[]): void; /** Send a notification (no reply expected). */ sendNotification(action: EpPacketNotification, ...args: unknown[]): void; /** Send an error/warning reply. */ sendError(type: ErrorType, callbackId: number, code: number, message?: string): void; sendProgress(callbackId: number, value: number, max: number): void; /** Encode request/reply arguments: one value as-is, multiple as a list, none → no TDU. */ private composeArgs; private parsePropertyValueArray; private parsePropertyValueMap; private composePropertyValueArray; private composePropertyValueMap; private restoreAttachedResources; private static readonly ENCRYPTED_RECORD_HEADER_SIZE; /** * Wrap outbound bytes in an AES-GCM-protected record once encryption is * active (port of C# `SendAsync`'s `ComposeEncryptedRecord` path): * `[4-byte BE protected-length][cipher.encrypt(message)]`. Plain * pass-through otherwise. */ send(message: Uint8Array): void; protected dataReceived(buffer: NetworkBuffer): void; /** * Parse and dispatch every complete packet within an already-decrypted * record. Unlike the plaintext path above, a truncated packet here is a * genuine protocol error rather than "need more data" — the whole record * was already fully received and authenticated before decryption. */ private dispatchPlaintext; private dispatch; /** Route an inbound request to a built-in handler, or fall back to {@link onRequest}. */ private processRequest; /** * Evaluate permissions/rate-control/auditing managers for one operation * (port of C# `TryApplyManagers`). Sends the denial error itself and * returns `false` when the operation isn't admitted; otherwise waits out * any rate-control-assigned delay and returns `true`. * * Scope note: dotnet additionally tracks repeated rate-control denials * per connection and, past a threshold, blocks the connection outright * (`IsRateControlBlocked`/`DenyRateControlledRequest`) — a secondary * DoS-hardening layer on top of this per-operation check, not ported here. */ private tryApplyManagers; /** Server handler: send current property values and subscribe the peer to changes. */ private epRequestAttachResource; /** * Server handler: send only properties modified after the caller's known * age. Accepts either a resource link (string) or a previously-known * instance id (number) — the id is not permanent (the remote node may * free/recreate a resource from memory), but the link is, so reconnecting * clients resolve by link. Reply leads with the resolved id so the caller * can detect it changed since its last attach. */ private epRequestReattachResource; /** Server handler: resolve a resource path to an instance id. */ private epRequestGetResourceIdByLink; /** Server handler: compose and reply with a registered TypeDef by its numeric id. */ private epRequestTypeDefById; /** Server handler: compose and reply with a resource's TypeDef. */ private epRequestTypeDefByResourceId; /** Server handler: batch name -> id lookup. Misses are skipped, not errored. */ private epRequestTypeDefIdsByNames; /** * Server handler (Query, 0xB): resolve a link, reply with the resource's * children as `{id, link}` descriptors, filtered to what the caller is * allowed to Attach. Distinct from {@link epRequestGetResourceIdByLink}, * which resolves a single link rather than listing children. * * Dotnet replies with full resource references that auto-attach on * decode; esiur-ts has no compose-side counterpart for that at all yet * (`LocalResource8/16/32` TDUs are decode-only — see `ResourceId.ts` / * `DataDeserializer.ts` — and nothing turns a decoded `ResourceId` into an * attached `EpResource` either). Building that bidirectional * resource-reference wire support is its own substantial feature; this * intentionally replies with plain, already-composable descriptors * instead — the caller can `attach()`/`get()` any id it wants from there. */ private epRequestQueryResources; /** * Server handler (LinkTypeDefs, 0xC): resolve a link, reply with the * composed TypeDef payloads for the resource's type and every type it * transitively references through property/argument/return `Tru`s — a * bulk fetch of a type's full dependency graph in one round trip. Remote * (relayed) types are unsupported, matching dotnet. */ private epRequestLinkTypeDefs; /** * Silent (no error reply) permission check, for filtering a list of * candidates (e.g. Query's children) rather than gating a single request. */ private isActionAllowed; /** * Server handler: pure per-connection bookkeeping — stop notifying *this* * connection about a resource; the resource itself keeps living in the * warehouse for other subscribers. The cleanup closure is the same one * {@link subscribeToInstance} stores on attach. */ private epRequestDetachResource; /** * Server handler: rename a resource within its current parent (dotnet's * MoveResource never actually re-parents — same restriction here, no `/` * allowed in the new name). Unlike dotnet, which gets away with a bare * `Instance.Name = name` assignment, ts's `MemoryStore.link()` tracks a * resource's path via a separate `instance.variables` entry rather than * deriving it from `Instance.name` — so the rename has to go through * `IStore.move()`, which keeps both in sync. */ private epRequestMoveResource; /** Server handler: remove a resource from the warehouse and its store. */ private epRequestDeleteResource; /** * Server handler: create a resource of a type already registered on this * warehouse (no dynamic/generic creation — matches dotnet's * `Activator.CreateInstance`-on-a-known-compiled-`Type` restriction). */ private epRequestCreateResource; private subscribeToInstance; /** Server handler: resolve the resource, invoke the function by index, reply with its result. */ private epRequestInvokeFunction; /** Shared invoke-result reply tail for {@link epRequestInvokeFunction} and {@link epRequestStaticCall}. */ private replyWithFunctionResult; /** * Register a streaming call's result and reply `Stream` on `callbackId` * (the "execution callback" `PullStream`/etc. later reference). A `Push` * source is pumped immediately; a `Pull` source just sits registered until * an explicit `PullStream` request drives it. */ private beginStreamedReply; /** Drive a `Push`-mode stream to completion, sending one `Chunk` reply per item. */ private pumpStream; /** Server handler (PullStream): advance a `Pull`-mode stream by one item. */ private epRequestPullStream; /** Server handler (TerminateExecution): stop a stream and release its iterator. */ private epRequestTerminateExecution; /** Server handler (HaltExecution): pause a pausable stream. */ private epRequestHaltExecution; /** Server handler (ResumeExecution): resume a halted stream. */ private epRequestResumeExecution; /** * Server handler (StaticCall): invoke a `static` exported function by * TypeDef id + function index — class-level, no resource instance * involved. */ private epRequestStaticCall; /** Server handler: resolve the resource and set a property by index. */ private epRequestSetProperty; /** * Server handler: an already-attached connection asks to start receiving a * `subscribable` event's occurrences. Errors `AlreadyListened` on a * duplicate call — callers must track subscription state themselves (see * {@link EpResource.on}) rather than relying on this being a no-op. */ private epRequestSubscribe; /** Server handler: the mirror of {@link epRequestSubscribe}. */ private epRequestUnsubscribe; /** Route an inbound notification to a built-in handler, or fall back to {@link onNotification}. */ private processNotification; private dispatchReply; private decode; private replyCompleted; private replyStream; private replyChunk; private replyWarning; private replyPropagated; private replyError; private replyProgress; protected connected(): void; close(): void; destroy(): void; protected disconnected(): void; private shouldAutoReconnect; private scheduleReconnect; private clearReconnectTimer; } /** A resource operation category evaluated by resource managers (port of C# `ActionType`). */ declare enum ActionType { Attach = 0, Delete = 1, Execute = 2, GetProperty = 3, SetProperty = 4, CreateResource = 5, UpdateAttributes = 6, InquireAttributes = 7, AddParent = 8, RemoveParent = 9, AddChild = 10, RemoveChild = 11, Rename = 12, ReceiveEvent = 13, ViewTypeDef = 14, Detach = 15, Subscribe = 16, Unsubscribe = 17, PullStream = 18, TerminateExecution = 19, HaltExecution = 20, ResumeExecution = 21 } /** * Metadata describing a resource operation being evaluated by managers * (port of C# `ResourceManagerContext`). Operation identity is immutable; * {@link ResourceManagerContext.delay}/{@link ResourceManagerContext.denialReason} * let a manager return admission details. * * `memberPolicyAttributes` is always empty in this port: dotnet lets any * custom `Attribute` ride along for bespoke manager types via reflection; * TS has no reflection-based generic attribute bag to source that from, and * nothing in this port's manager set (Permissions/RateControl/Auditing) * reads it, so it's kept only for shape parity with the C# constructor. */ declare class ResourceManagerContext { readonly warehouse: Warehouse; readonly connection: EpConnection | null; readonly session: AuthenticationSession | null; readonly resource: IResource | null; readonly member: MemberTemplate | null; readonly action: ActionType; readonly inquirer: unknown; readonly supportsDelay: boolean; /** Optional delay requested by a rate-control manager. */ delay: number; /** Optional public-safe reason supplied by a manager when it denies an operation. */ denialReason: string | undefined; readonly memberPolicyAttributes: readonly unknown[]; readonly typeDefinition: TypeDef | null; constructor(warehouse: Warehouse, connection: EpConnection | null, session: AuthenticationSession | null, resource: IResource | null, member: MemberTemplate | null, action: ActionType, inquirer?: unknown, memberPolicyAttributes?: readonly unknown[], typeDefinition?: TypeDef | null, supportsDelay?: boolean); } /** A resource manager's decision on one operation (port of C# `Ruling`). */ declare enum Ruling { Denied = 0, Allowed = 1, DontCare = 2 } /** * Evaluates whether a resource operation is admitted by rate-control policy * (port of C# `IRateControlManager`). A manager may assign * `context.delay` when allowing an operation that should be queued and * `context.supportsDelay` is true. */ interface IRateControlManager extends IResourceManager { readonly managerCategory: "rateControl"; applicable(context: ResourceManagerContext): Ruling; } /** * Audits a resource operation before it is executed (port of C# * `IAuditingManager`). A `Denied` result may veto the operation, while * `Allowed` and `DontCare` never grant authorization or override another * manager's denial. */ interface IAuditingManager extends IResourceManager { readonly managerCategory: "auditing"; applicable(context: ResourceManagerContext): Ruling; } /** * Aggregated decisions from each independent manager category (port of C# * `ResourceManagerEvaluation`). An allow in one category never grants * admission in another category. */ declare class ResourceManagerEvaluation { readonly permissions: Ruling; readonly rateControl: Ruling; readonly auditing: Ruling; readonly permissionsDenialReason?: string | undefined; readonly rateControlDenialReason?: string | undefined; readonly auditingDenialReason?: string | undefined; readonly delay: number; constructor(permissions: Ruling, rateControl: Ruling, auditing: Ruling, delay: number, permissionsDenialReason?: string | undefined, rateControlDenialReason?: string | undefined, auditingDenialReason?: string | undefined); get isAllowed(): boolean; } /** Describes the request currently being evaluated by a rate policy (port of C# `RateControlContext`). */ declare class RateControlContext { readonly warehouse: Warehouse; readonly connection: EpConnection; readonly session: AuthenticationSession; readonly resource: IResource | null; readonly member: MemberTemplate; readonly action: ActionType; /** Optional delay (ms) assigned by a policy to an allowed queued request. */ delay: number; constructor(warehouse: Warehouse, connection: EpConnection, session: AuthenticationSession, resource: IResource | null, member: MemberTemplate, action: ActionType); } /** * Base class for named Warehouse rate-control policies (port of C# * `RatePolicy`). dotnet exposes this as two overloads (a context-free * `Applicable()` and a context-aware `Applicable(RateControlContext)`, * the latter defaulting to calling the former) — TS collapses them into one * overridable method, since it has no overload-resolution equivalent; * context-free policies simply ignore the parameter. */ declare abstract class RatePolicy { name: string; constructor(name?: string); /** Evaluate a request. Override for context-aware policies (e.g. {@link BurstRatePolicy}). */ applicable(_context?: RateControlContext): Ruling; } interface WarehouseRemoteGetOptions extends EpConnectionOptions { /** TypeDef for the remote resource proxy. Required when the URL includes a resource path. */ typeDef?: TypeDef; /** @deprecated Use {@link typeDef}. */ template?: TypeDef; /** Resource/stub constructor used to derive {@link typeDef}. */ type?: Function | EpResourceConstructor; } type WarehouseGetOptions = WarehouseRemoteGetOptions | TypeDef | Function; /** * Central resource manager (port of C# `Warehouse`). Holds stores and active * resources, resolves `*nix`-style paths, and drives the resource lifecycle. * * `get` resolves local paths and EP URLs. A bare EP URL returns an * {@link EpConnection}; an EP URL with a resource path returns an attached * remote proxy when a TypeDef/stub type is supplied. */ declare class Warehouse { static readonly default: Warehouse; readonly storeConnected: EventHandler; readonly storeDisconnected: EventHandler; private readonly resources; private readonly stores; private resourceCounter; private opened; private readonly typeDefs; private readonly typeDefsByCtor; private readonly typeDefsByEnum; private typeDefCounter; private readonly authenticationProviders; private readonly encryptionProviders; private readonly resourceManagers; private readonly defaultResourceManagerTypes; private readonly ratePolicies; private readonly proxyTypes; constructor(); /** Register an authentication provider under its default protocol name. */ registerAuthenticationProvider(provider: IAuthenticationProvider): void; /** Register an authentication provider under an explicit protocol name. */ registerAuthenticationProvider(name: string, provider: IAuthenticationProvider): void; /** .NET-compatible alias for {@link registerAuthenticationProvider}. */ RegisterAuthenticationProvider(provider: IAuthenticationProvider): void; /** .NET-compatible alias for {@link registerAuthenticationProvider}. */ RegisterAuthenticationProvider(name: string, provider: IAuthenticationProvider): void; /** Resolve an authentication provider by protocol name, throwing when missing. */ getAuthenticationProvider(name: string): IAuthenticationProvider; /** .NET-compatible alias for {@link getAuthenticationProvider}. */ GetAuthenticationProvider(name: string): IAuthenticationProvider; /** Try to resolve an authentication provider by protocol name. */ tryGetAuthenticationProvider(name: string): IAuthenticationProvider | undefined; /** .NET-compatible alias for {@link tryGetAuthenticationProvider}. */ TryGetAuthenticationProvider(name: string): IAuthenticationProvider | undefined; /** Register an encryption provider under its default protocol name. */ registerEncryptionProvider(provider: IEncryptionProvider): void; /** Register an encryption provider under an explicit protocol name. */ registerEncryptionProvider(name: string, provider: IEncryptionProvider): void; /** .NET-compatible alias for {@link registerEncryptionProvider}. */ RegisterEncryptionProvider(provider: IEncryptionProvider): void; /** .NET-compatible alias for {@link registerEncryptionProvider}. */ RegisterEncryptionProvider(name: string, provider: IEncryptionProvider): void; /** Unregister an encryption provider previously registered under `name`. */ unregisterEncryptionProvider(name: string, provider: IEncryptionProvider): boolean; /** Resolve an encryption provider by protocol name, throwing when missing. */ getEncryptionProvider(name: string): IEncryptionProvider; /** .NET-compatible alias for {@link getEncryptionProvider}. */ GetEncryptionProvider(name: string): IEncryptionProvider; /** Try to resolve an encryption provider by protocol name. */ tryGetEncryptionProvider(name: string): IEncryptionProvider | undefined; /** .NET-compatible alias for {@link tryGetEncryptionProvider}. */ TryGetEncryptionProvider(name: string): IEncryptionProvider | undefined; /** Names of every registered encryption provider. */ getEncryptionProviderNames(): string[]; /** .NET-compatible alias for {@link getEncryptionProviderNames}. */ GetEncryptionProviderNames(): string[]; /** * Register a manager instance by its concrete type (port of C# * `RegisterManager`). Type-level `@PermissionsManager`/`@RateControlManager`/ * `@AuditingManager` associations and `resolveResourceManagers` can only * reference instances registered here. */ registerManager(manager: IResourceManager, useAsDefault?: boolean): void; /** Compatibility registration for Warehouse-wide permissions (registered managers default to on). */ registerPermissionsManager(manager: IPermissionsManager, useAsDefault?: boolean): void; registerRateControlManager(manager: IRateControlManager, useAsDefault?: boolean): void; registerAuditingManager(manager: IAuditingManager, useAsDefault?: boolean): void; /** Enable/disable a registered manager as a Warehouse-wide default. Multiple defaults per category are allowed. */ setDefaultManager(managerCtor: Function, enabled?: boolean): void; tryGetManager(managerCtor: Function): T | undefined; removeManager(managerCtor: Function): boolean; getDefaultManagers(): IResourceManager[]; private isRegisteredManager; /** Resolve the managers a resource type declared via `@PermissionsManager`/`@RateControlManager`/`@AuditingManager`. */ resolveResourceManagers(resourceCtor: Function): IResourceManager[]; /** * Ask every applicable manager, using independent deny-overrides * aggregation for permissions/rate-control/auditing (port of C# * `EvaluateManagers`). When `managers` isn't supplied, resolves them from * the target resource's type (dotnet also folds in per-instance managers * via `Instance.Managers`; this port has no per-instance manager override * concept, only the type-level `@...Manager` decorators). */ evaluateManagers(context: ResourceManagerContext, managers?: Iterable): ResourceManagerEvaluation; /** Register a named rate policy referenced by `@RateControl(name)`. */ addRatePolicy(policy: RatePolicy): void; addRatePolicy(name: string, policy: RatePolicy): void; tryGetRatePolicy(name: string): RatePolicy | undefined; removeRatePolicy(name: string): boolean; /** Register a generated remote proxy type for automatic EpResource attachment. */ registerProxyType(type: Function): void; /** .NET-compatible alias for {@link registerProxyType}. */ RegisterProxyType(type: Function): void; /** Register multiple generated remote proxy types. */ registerProxyTypes(types: Iterable): void; /** .NET-compatible alias for {@link registerProxyTypes}. */ RegisterProxyTypes(types: Iterable): void; /** Resolve a registered generated proxy type by kind, domain and remote TypeDef name. */ tryGetProxyType(kind: TypeDefKind, domain: string, name: string): Function | undefined; /** .NET-compatible alias for {@link tryGetProxyType}. */ TryGetProxyType(kind: TypeDefKind, domain: string, name: string): Function | undefined; /** Resolve a registered generated proxy type or throw when missing. */ getProxyType(kind: TypeDefKind, domain: string, name: string): Function; /** .NET-compatible alias for {@link getProxyType}. */ GetProxyType(kind: TypeDefKind, domain: string, name: string): Function; /** Build (cached) the decorated TypeDef surface for a resource class. */ getTypeDef(ctor: Function): TypeDef; /** @deprecated Use {@link getTypeDef}. */ getTemplate(ctor: Function): TypeDef; /** Get (or lazily create) the type definition for a resource/record class. */ getLocalTypeDefByType(ctor: Function): ITypeDef; /** Get (or lazily create) the type definition for an enum descriptor. */ getLocalTypeDefByEnum(enumType: EnumType): ITypeDef; /** Resolve a type definition by its numeric id. */ getLocalTypeDefById(id: number): ITypeDef; /** Resolve a type definition registered on this warehouse by its class name. */ getLocalTypeDefByName(name: string): ITypeDef | undefined; /** Look up an active resource by its numeric instance id. */ getById(id: number): IResource | undefined; /** Put a resource (or store) at `path` and initialize it. */ put(path: string, resource: T, context?: IResourceContext): AsyncReply; private putAsync; /** * Resolve a local resource path or an EP URL. `ep://host:port` returns an * {@link EpConnection}; `ep://host:port/path` returns an attached remote proxy * when `options` supplies a {@link TypeDef} or resource/stub constructor. */ get(path: string, options?: WarehouseGetOptions): AsyncReply; /** .NET-compatible alias for {@link get}. */ Get(path: string, options?: WarehouseGetOptions): AsyncReply; /** Resolve a resource by path, returning the raw resource. */ query(path: string): AsyncReply; private getAsync; private queryAsync; /** Open the warehouse: initialize all resources and open all stores. */ open(): AsyncReply; private openAsync; /** * Close the warehouse: terminate all resources in two fully-settled phases * (`Terminate` then `SystemTerminated`), matching C# `Warehouse.Close()`. * Each phase notifies every resource even if some throw; errors from both * phases are aggregated rather than aborting the remaining resources. */ close(): AsyncReply; /** * Remove a resource from the warehouse: drops it from the id/store maps, * tells its owning store to release it, destroys it, and clears its * `.instance`. Kept synchronous (matching dotnet's `Warehouse.Remove`) — * `MemoryStore.remove()`'s own mutation already runs synchronously despite * its `AsyncReply` return type, so the result isn't awaited here. * * Deferred: recursive cascade-delete of a *store* resource's own children * (dotnet does this too) isn't implemented — `IStore.children()` returns * an `AsyncBag`, making that a genuinely async, separate piece of work. */ remove(resource: IResource): boolean; } /** Payload for {@link Instance.propertyModified}. */ interface PropertyModificationInfo { resource: IResource; property: PropertyTemplate; value: unknown; age: number; } /** Payload for {@link Instance.eventOccurred}. */ interface EventOccurredInfo { resource: IResource; event: EventTemplate; value: unknown; } /** * Manages a resource's identity and state (port of C# `Instance`): id, name, * owning store, TypeDef, per-property age/modification date, and the * property-change / event notification channels. */ declare class Instance { readonly warehouse: Warehouse; readonly id: number; name: string; readonly definition: TypeDef; readonly variables: Map; readonly propertyModified: EventHandler; readonly eventOccurred: EventHandler; readonly destroyed: EventHandler; isDestroyed: boolean; private readonly store_; private readonly resourceRef; private readonly ages; private readonly modificationDates; private instanceAge; private loading; constructor(warehouse: Warehouse, id: number, name: string, resource: IResource, store: IStore, age?: number); get store(): IStore; /** The managed resource, or `undefined` if it has been collected. */ get resource(): IResource | undefined; /** Instance age, incremented on each property modification. */ get age(): number; getAge(index: number): number | undefined; setAge(index: number, value: number): void; getModificationDate(index: number): Date | undefined; setModificationDate(index: number, date: Date | undefined): void; /** Notify that an exported property changed (called by the generated setter). */ modified(name: string, value?: unknown): void; private emitModification; /** Raise an exported event by its TypeDef index. */ emitEventByIndex(index: number, value: unknown): void; /** The permanent path link to the resource. */ get link(): string | undefined; } /** Optional context passed when putting/getting a resource. */ interface IResourceContext { age?: number; attributes?: Map; } /** A distributable resource (port of C# `IResource`). */ interface IResource extends IDestructible { /** The managing {@link Instance}; assigned by the {@link Warehouse} on put. */ instance?: Instance; /** Handle a lifecycle operation. */ handle(operation: ResourceOperation, context?: IResourceContext): AsyncReply; } /** A resource that stores and retrieves other resources (port of C# `IStore`). */ interface IStore extends IResource { get(path: string): AsyncReply; put(resource: IResource, path: string): AsyncReply; link(resource: IResource): string | undefined; modify(resource: IResource, property: PropertyTemplate, value: unknown, age: number | undefined, date: Date | undefined): boolean; remove(resource: IResource): AsyncReply; remove(path: string): AsyncReply; move(resource: IResource, newPath: string): AsyncReply; children(resource: IResource, name?: string): AsyncBag; parents(resource: IResource, name?: string): AsyncBag; } /** * Checks permission for a resource operation (port of C# * `IPermissionsManager`). Predates {@link IRateControlManager}/ * {@link IAuditingManager}'s newer `ResourceManagerContext`-based signature * and was never refactored to match — ported faithfully rather than * "cleaned up" to be consistent, since `tryApplyManagers` genuinely calls * permissions managers differently from rate/auditing managers. */ interface IPermissionsManager extends IResourceManager { readonly managerCategory: "permissions"; applicable(resource: IResource | null, session: AuthenticationSession | null, action: ActionType, member: MemberTemplate | null, inquirer?: unknown): Ruling; initialize(settings: Map | undefined, resource: IResource | null): boolean; readonly settings: Map | undefined; } /** Function-only options for {@link Export} — a streaming call's mode and whether it can be halted/resumed mid-flight. */ interface ExportFunctionOptions { streamMode?: StreamMode; pausable?: boolean; } interface RemoteInfo { name: string; domains: string[]; } /** * Marks a class member as exported over Esiur (port of C#'s `[Export]`). * * - On an `accessor` property → a notifying property; the setter reports changes * to the resource's {@link Instance}. Pass the wire type, e.g. `@Export(t.i32)`. * - On a `method` → an exported function. Pass return type and argument types, * e.g. `@Export(t.string, [t.string])`. Pass {@link ExportFunctionOptions} as a * 4th argument to mark it streaming, e.g. `@Export(t.i32, [], { streamMode: StreamMode.Pull })` * — the method should then return an `AsyncIterable`/`Iterable` rather than a plain value. * - On a `field` initialized with {@link event} → an exported event. Pass the * event argument type, e.g. `@Export(t.string)`. */ declare function Export(type?: Tru, args?: Tru[], functionOptions?: ExportFunctionOptions): (value: unknown, context: ClassMemberDecoratorContext) => any; /** * Applies a named Warehouse rate policy to an exported function or property * setter (port of C#'s `[RateControl(policyName)]`). The name is resolved * against `Warehouse.tryGetRatePolicy` by {@link NamedRateControlManager} * when the member is invoked/set. */ declare function RateControl(policyName: string): (_value: unknown, context: ClassMemberDecoratorContext) => void; /** * Marks an exported event as delivered to every attached connection * unconditionally, with no explicit `Subscribe` request needed (port of * C#'s `[AutoDelivery]`/`EventDefFlags.AutoDelivered`). Without this, an * exported event requires an explicit Subscribe before it starts flowing * (`EventDef.Subscribable` is true by default in dotnet) — reach for * `@AutoDelivered()` for low-frequency events every listener wants anyway; * leave it off for high-frequency/expensive-to-compute events clients * should opt into explicitly. */ declare function AutoDelivered(): (_value: unknown, context: ClassMemberDecoratorContext) => void; /** Associates a registered {@link IPermissionsManager} implementation with a resource class. */ declare function PermissionsManager(managerCtor: new (...args: never[]) => IPermissionsManager): (_value: Function, context: ClassDecoratorContext) => void; /** Associates a registered {@link IRateControlManager} implementation with a resource class. */ declare function RateControlManager(managerCtor: new (...args: never[]) => IRateControlManager): (_value: Function, context: ClassDecoratorContext) => void; /** Associates a registered {@link IAuditingManager} implementation with a resource class. */ declare function AuditingManager(managerCtor: new (...args: never[]) => IAuditingManager): (_value: Function, context: ClassDecoratorContext) => void; /** Read the manager constructor types declared (including inherited) on `ctor`. */ declare function getResourceManagerTypes(ctor: Function): Function[]; /** Build (and cache) the decorated {@link TypeDef} surface for a resource class. */ declare function getTypeDef(ctor: Function): TypeDef; /** @deprecated Use {@link getTypeDef}. */ declare function getTemplate(ctor: Function): TypeDef; /** Marks a generated proxy class as representing a remote TypeDef. */ declare function Remote(name: string, ...domains: string[]): (value: Function, _context?: ClassDecoratorContext) => void; /** Read remote proxy metadata from a class decorator or generator statics. */ declare function getRemoteInfo(ctor: Function): RemoteInfo | undefined; /** * A raised-event channel held by a resource (the TypeScript analogue of C#'s * `ResourceEventHandler` delegate field). The resource raises it with * {@link emit}; the {@link Instance} attaches a {@link sink} to forward * occurrences across the network. */ declare class EventSource { private readonly listeners; /** @internal Forwarder installed by the owning Instance. */ sink?: (value: T) => void; /** Subscribe a local listener. */ listen(handler: (arg: T) => void): this; /** Unsubscribe a local listener. */ unlisten(handler: (arg: T) => void): void; /** Raise the event: notify local listeners and the network sink. */ emit(value: T): void; } /** Create an {@link EventSource} for an exported event field. */ declare function event(): EventSource; /** * Convenience base class for resources (port of C# `Resource`). Provides the * {@link Instance} slot, lifecycle `handle`, and destroy notification, so a * subclass need only declare its `@Export`ed members. */ declare class Resource implements IResource { instance?: Instance; private readonly destroyHandlers; handle(operation: ResourceOperation, _context?: IResourceContext): AsyncReply; /** Override to run setup logic on Initialize; return false to fail the put. */ protected create(): boolean; addDestroyHandler(handler: DestroyedEvent): void; removeDestroyHandler(handler: DestroyedEvent): void; destroy(): void; } /** * Concrete type definition built from a resource/record class's decorated * {@link TypeDef} surface. Implements the layer-neutral * {@link ITypeDef} consumed by the serializer. */ declare class LocalTypeDef implements ITypeDef { readonly id: number; readonly kind: TypeDefKind; readonly name: string; readonly template: TypeDef; private readonly ctor?; readonly constants?: TypeDefConstant[] | undefined; private cachedProperties?; constructor(id: number, kind: TypeDefKind, name: string, template: TypeDef, ctor?: (new () => object) | undefined, constants?: TypeDefConstant[] | undefined); get properties(): TypeDefProperty[]; createInstance(): object; setProperty(instance: object, name: string, value: unknown): void; /** * Invoke a `static` exported function by name (port of what dotnet reaches * via `MethodInfo.Invoke(null, args)` for a static `FunctionDef`). The * caller is responsible for having checked `FunctionTemplate.isStatic`. */ invokeStaticFunction(name: string, args: unknown[]): unknown; } /** * Marker base class for record (data-transfer) types. A record exposes * `@Export`ed properties and serializes as a Typed TDU referencing its * {@link LocalTypeDef} (port of C# `Record`/`IRecord`). */ declare class Record$1 { } /** True if a value is a record instance. */ declare function isRecord(value: unknown): value is Record$1; /** Compose a record as a Typed TDU: `TruTypeDef` metadata + each property value. */ declare function recordCompose(value: object, warehouse: Warehouse, connection: unknown): Tdu; /** * Framework-agnostic adapter over the property/event-change notifications * already fired by {@link Instance} (local resources) and {@link EpResource} * (remote resource proxies from `EpConnection.attach()`/`.get()`). Depends * on neither — it duck-types over whatever `EventHandler`-shaped * `propertyModified`/`eventOccurred` it finds, so it works for both without * importing either class (avoiding a dependency on the protocol layer from * here, and keeping this file usable as the basis for *any* UI binding, not * just the `esiur/react` one built on top of it). */ /** A normalized property-change notification, regardless of source shape. */ interface PropertyChangeEvent { name: string; value: unknown; } /** * Subscribe to every property change on `resource` (local or remote). * Returns an unsubscribe function; a no-op if `resource` exposes no * recognizable change notifier. */ declare function subscribeToResource(resource: unknown, onChange: (event: PropertyChangeEvent) => void): () => void; /** Subscribe to a single named property's changes. */ declare function subscribeToProperty(resource: unknown, propertyName: string, onChange: (value: unknown) => void): () => void; /** Read a property's current value directly off a resource/proxy. */ declare function readProperty(resource: unknown, propertyName: string): T | undefined; /** Build a plain snapshot object of every exported property's current value. */ declare function snapshotProperties = Record>(resource: unknown): T; /** * Subscribe to one named exported event, local or remote. Remote proxies * fire everything through the single `eventOccurred` notifier (filtered * here by name); local resources expose each event as its own * {@link EventSource} field with `listen`/`unlisten`. */ declare function subscribeToResourceEvent(resource: unknown, eventName: string, onEvent: (value: unknown) => void): () => void; /** * An in-memory {@link IStore} that keeps its resources in RAM (port of C# * `MemoryStore`). Resources are addressed by their stored link path, or by * `$` for a direct instance-id lookup. */ declare class MemoryStore implements IStore { instance?: Instance; private readonly resources; private readonly destroyHandlers; handle(_operation: ResourceOperation): AsyncReply; link(resource: IResource): string | undefined; get(path: string): AsyncReply; put(resource: IResource, path: string): AsyncReply; modify(): boolean; remove(resource: IResource): AsyncReply; remove(path: string): AsyncReply; move(resource: IResource, newPath: string): AsyncReply; children(resource: IResource): AsyncBag; parents(): AsyncBag; addDestroyHandler(handler: DestroyedEvent): void; removeDestroyHandler(handler: DestroyedEvent): void; destroy(): void; } /** * WebSocket transport (port of C# `WSocket`). Unlike the C# version it does no * frame parsing — both the browser `WebSocket` and Node's global `WebSocket` * (and `ws`) deliver already-deframed binary messages. Works in any environment * that exposes the standard `WebSocket` (browser, Node ≥ 21, or a `ws` instance * passed to the constructor). */ declare class WSocket implements ISocket { state: SocketState; receiver?: INetworkReceiver; private ws?; private readonly buffer; private readonly destroyHandlers; constructor(ws?: WebSocket); connect(url: string): AsyncReply; private attach; send(message: Uint8Array): void; close(): void; addDestroyHandler(handler: DestroyedEvent): void; removeDestroyHandler(handler: DestroyedEvent): void; destroy(): void; } /** * Raw TCP transport (port of C# `TcpSocket`), for Node.js hosts talking to an * esiur-dotnet server that only listens on its native TCP `TcpServer` (no * WebSocket upgrade route registered) — esiur-ts could otherwise only ever * connect via {@link WSocket}. * * Node-only: `node:net` is loaded via a dynamic `import()` inside * {@link connect} rather than a static top-level import, matching * `WSocket.ts`'s environment-detection convention exactly — this file's mere * existence (and the type-only `import("node:net")` above, erased at compile * time) is safe to ship in a browser bundle; it only throws if actually * connected to from a non-Node runtime. */ declare class TcpSocket implements ISocket { state: SocketState; receiver?: INetworkReceiver; private sock?; private readonly buffer; private readonly destroyHandlers; /** `url` is `tcp://host:port`. */ connect(url: string): AsyncReply; private attach; send(message: Uint8Array): void; close(): void; addDestroyHandler(handler: DestroyedEvent): void; removeDestroyHandler(handler: DestroyedEvent): void; destroy(): void; } /** Top 2 bits of an Ep packet header — the packet method (port of C# `EpPacketMethod`). */ declare enum EpPacketMethod { Notification = 0, Request = 1, Reply = 2, Extension = 3 } /** * An IIP/Ep protocol packet (port of C# `EpPacket`). * * Wire layout — header byte `[method:2][hasTDU:1][action:5]`, then a 4-byte * little-endian callback id for Request/Reply, then an optional self-describing * TDU (measured via {@link PlainTdu}, decoded later with connection context). */ declare class EpPacket { method: EpPacketMethod; /** The action in the low 5 bits (an EpPacketRequest/Reply/Notification or extension byte). */ action: number; callbackId: number; hasTdu: boolean; tdu: PlainTdu | null; private dataLengthNeeded; get request(): EpPacketRequest; get reply(): EpPacketReply; get notification(): EpPacketNotification; private notEnough; /** * Parse a packet from `data[offset..ends]`. Returns the number of bytes * consumed, or a negative value (`-bytesStillNeeded`) if the buffer is short. */ parse(data: Uint8Array, offset: number, ends: number): number; private static header; /** Build a Request packet. */ static composeRequest(action: EpPacketRequest, callbackId: number, tdu?: Uint8Array): Uint8Array; /** Build a Reply packet. */ static composeReply(action: EpPacketReply, callbackId: number, tdu?: Uint8Array): Uint8Array; /** Build a Notification packet. */ static composeNotification(action: EpPacketNotification, tdu?: Uint8Array): Uint8Array; } /** Top 2 bits of an auth packet header — the command (port of C# `EpAuthPacketCommand`). */ declare enum EpAuthPacketCommand { Initialize = 0, Acknowledge = 1, Action = 2, Event = 3 } /** * Auth packet methods (port of C# `EpAuthPacketMethod`). The top 2 bits encode * the {@link EpAuthPacketCommand}; e.g. `SessionEstablished` (0x47) is an * Acknowledge. */ declare enum EpAuthPacketMethod { Initialize = 0, Handshake = 128, FinalHandshake = 129, Denied = 64, NotSupported = 65, TrySupported = 66, Retry = 67, ProceedToHandshake = 68, ProceedToFinalHandshake = 69, ProceedToEstablishSession = 70, SessionEstablished = 71, Established = 192, ErrorTerminate = 193, ErrorMustEncrypt = 194, ErrorRetry = 195, IndicationEstablished = 200, IAuthPlain = 208, IAuthHashed = 209, IAuthEncrypted = 210 } /** * Authentication-phase packet (port of C# `EpAuthPacket`). * * Header byte: `[command:2][hasTDU:1][…]`. For Initialize the low bits carry * `authMode<<2 | encryptionMode`; for the other commands they carry the * {@link EpAuthPacketMethod} (whose own top bits repeat the command). An * optional TDU follows — typically a `TypedMap` of headers. */ declare class EpAuthPacket { command: EpAuthPacketCommand; method: EpAuthPacketMethod; authMode: AuthenticationMode; encryptionMode: EncryptionMode; hasTdu: boolean; tdu: PlainTdu | null; errorCode: number; sessionId: Uint8Array | null; /** IAuth reference, set by auth-flow logic (not read from `data[]` by {@link parse}). */ reference: number; private dataLengthNeeded; private notEnough; /** Parse an auth packet; returns bytes consumed or `-bytesNeeded`. */ parse(data: Uint8Array, offset: number, ends: number): number; /** Build an Initialize packet (`authMode`/`encryptionMode` in the low bits). */ static composeInitialize(authMode: AuthenticationMode, encryptionMode: EncryptionMode, headersTdu?: Uint8Array): Uint8Array; /** Build a non-Initialize packet from a method (whose top bits carry the command). */ static composeMethod(method: EpAuthPacketMethod, headersTdu?: Uint8Array): Uint8Array; } interface EpServerOptions { /** Port to listen on (0 = an ephemeral port). */ port: number; /** Host interface (default: all). */ host?: string; /** Warehouse whose resources are served to connecting peers. */ warehouse: Warehouse; /** Accept anonymous (None-mode) peers. Default true. */ allowUnauthorized?: boolean; /** Optional authentication provider to register on the served warehouse. */ authenticationProvider?: IAuthenticationProvider; } /** * A WebSocket server that hosts a {@link Warehouse}'s resources for remote peers * (the TypeScript analogue of C# `DistributedServer`/`EpServer`). Node-only: it * dynamically imports `ws`, so importing this module does not pull `ws` into a * browser bundle. */ declare class EpServer { readonly warehouse: Warehouse; /** Live client connections. */ readonly connections: Set; private wss; private constructor(); /** Start listening and accepting connections bound to `warehouse`. */ static listen(options: EpServerOptions): Promise; /** The bound port (useful when listening on port 0). */ get port(): number; /** Stop the server and close all connections. */ close(): Promise; } /** SHA3 digest compatible with .NET/BouncyCastle SHA3. Supports 224/256/384/512 bits. */ declare function sha3(data: Uint8Array, bitLength?: number): Uint8Array; declare const sha3_256: (data: Uint8Array) => Uint8Array; declare const sha3_512: (data: Uint8Array) => Uint8Array; /** Identity plus raw password bytes returned by a password provider for itself. */ declare class IdentityPassword { readonly identity: string | null; readonly password: Uint8Array | null; constructor(identity?: string | null, password?: Uint8Array | null); } /** Stored salted password hash and salt for a hosted account. */ declare class PasswordHash { readonly hash: Uint8Array | null; readonly salt: Uint8Array | null; constructor(hash?: Uint8Array | null, salt?: Uint8Array | null); } /** Base provider for Esiur's SHA3 password-hash authentication protocol. */ declare class PasswordAuthenticationProvider implements IAuthenticationProvider { readonly defaultName = "password-sha3-v1"; /** Derive a storable, salted {@link PasswordHash} from a plaintext password. */ static createCredential(password: Uint8Array): PasswordHash; createAuthenticationHandler(context: AuthenticationContext): IAuthenticationHandler; getHostedAccountCredential(_identity: string, _domain: string | null): PasswordHash; getSelfIdentityAndCredential(_domain: string | null, _hostname: string | null): IdentityPassword; getSelfCredential(_identity: string, _domain: string | null, _hostname: string | null): Uint8Array | null; login(_session: AuthenticationSession): AsyncReply; logout(_session: AuthenticationSession): AsyncReply; } /** Implements Esiur's `"password-sha3-v1"` SHA3 nonce/challenge-response authentication. */ declare class PasswordAuthenticationHandler implements IAuthenticationHandler { private readonly mode; private readonly direction; private initiatorIdentity; private responderIdentity; private readonly hostName; private readonly domain; readonly provider: PasswordAuthenticationProvider; static readonly nonceLength = 20; readonly protocol = "password-sha3-v1"; private readonly localNonce; private remoteNonce; private localSalt; private remoteSalt; private initiatorPassword; private responderPassword; private step; constructor(mode: AuthenticationMode, direction: AuthenticationDirection, initiatorIdentity: string | null, responderIdentity: string | null, hostName: string | null, domain: string | null, provider: PasswordAuthenticationProvider); static computeSha3(data: Uint8Array, bitLength?: number): Uint8Array; process(authData: unknown): AuthenticationResult; private processInternal; private processInitiatorInitializerIdentity; private processResponderInitializerIdentity; private processInitiatorResponderIdentity; private processResponderResponderIdentity; private processInitiatorDualIdentity; private processResponderDualIdentity; private loadInitiatorSelfPassword; private loadResponderSelfPassword; private validRemoteNonce; private failedAndStop; } /** A key-exchange algorithm (port of C# `IKeyExchanger`). */ interface IKeyExchanger { readonly identifier: number; getPublicKey(): Uint8Array; computeSharedKey(key: Uint8Array): Uint8Array; } type NodeCrypto = typeof node_crypto; /** * Creates AES-256-GCM record ciphers (port of C# `AesEncryptionProvider`). * Session keys and nonce prefixes are derived with HKDF-SHA256 and separated * by protocol direction and purpose. * * Node-only: `node:crypto` is loaded via a dynamic `import()` inside * {@link createCipher} (called once per session, during the handshake) — * matching `TcpSocket.ts`'s environment-detection convention. This is what * lets the actual per-record {@link ISymetricCipher.encrypt}/`decrypt` stay * fully synchronous afterward: Web Crypto has no synchronous AES-GCM in * either browser or Node, but `node:crypto`'s `createCipheriv`/ * `createDecipheriv` does, and resolving the module once per session (not * once per record) keeps `NetworkConnection.send`'s synchronous contract * intact with no ripple into the hot send/receive path. The tradeoff is that * encrypted transport is Node-only for now — a browser WSocket connection * can still connect, just not with `encryptionMode` set. */ declare class AesEncryptionProvider implements IEncryptionProvider { static readonly Name = "aes-gcm"; readonly defaultName = "aes-gcm"; readonly maximumRecordOverhead: number; createCipher(context: EncryptionContext): Promise; } /** * AES-256-GCM session record cipher (port of C# `AesGcmSymetricCipher`). * * A record contains an 8-byte big-endian sequence followed by ciphertext and * a 16-byte GCM tag. The transport's 4-byte record length and the sequence * are authenticated as associated data. Sequence numbers are both implicit * state and explicit record fields, so replay and reordering fail closed. */ declare class AesGcmSymetricCipher implements ISymetricCipher { private readonly nodeCrypto; /** {@link import("../../../esiur-dotnet counterpart").SymetricEncryptionAlgorithmType.AES} */ readonly identifier = 0; private readonly contextSalt; private readonly sendKeyLabel; private readonly receiveKeyLabel; private readonly sendNonceLabel; private readonly receiveNonceLabel; private sendKey; private receiveKey; private sendNoncePrefix; private receiveNoncePrefix; private sendSequence; private receiveSequence; private keyInitialized; constructor(context: EncryptionContext, nodeCrypto: NodeCrypto); encrypt(data: Uint8Array): Uint8Array; decrypt(data: Uint8Array): Uint8Array; /** * Initialize the cipher key. Session ciphers are deliberately immutable * after construction — resetting a key would also reset the GCM nonce * sequence. Create a new cipher with fresh peer nonces to use different * key material. */ setKey(key: Uint8Array): Uint8Array; } /** * Per-identity permissions from a settings map (port of C# * `UserPermissionsManager`). Settings shape: `{ [identity|"public"]: { * [resourcePermissionKey|memberName]: "yes" | ... } }`. */ declare class UserPermissionsManager implements IPermissionsManager { readonly managerCategory: "permissions"; private _settings; constructor(settings?: Map); get settings(): Map | undefined; applicable(resource: IResource | null, session: AuthenticationSession | null, action: ActionType, member: MemberTemplate | null, _inquirer?: unknown): Ruling; initialize(settings: Map | undefined, _resource: IResource | null): boolean; } /** * Delegates permission checks to whatever `IPermissionsManager`s are * registered for the resource's owning store's type (port of C# * `StorePermissionsManager`) — lets a store centralize policy for every * resource it holds rather than annotating each resource type individually. * * Delegates only to managers attached to the store's own type, excluding * itself: re-entering evaluation for the store would run Warehouse defaults * (including this manager) again and could recurse indefinitely or apply a * rate policy twice. */ declare class StorePermissionsManager implements IPermissionsManager { readonly managerCategory: "permissions"; private _settings; get settings(): Map | undefined; applicable(resource: IResource | null, session: AuthenticationSession | null, action: ActionType, member: MemberTemplate | null, inquirer?: unknown): Ruling; initialize(settings: Map | undefined, _resource: IResource | null): boolean; } /** * Per-connection, per-member token-bucket policy with bounded delayed * reservations (port of C# `BurstRatePolicy`). * * Buckets are scoped per `EpConnection` via a `WeakMap` (the GC-friendly * analogue of C#'s `ConditionalWeakTable` — * entries are dropped automatically once a connection is no longer * referenced elsewhere). Timestamps use `performance.now()` (monotonic, * sub-millisecond, available in both Node and browsers) in place of * `Stopwatch.GetTimestamp()`; all durations are in milliseconds rather than * `TimeSpan`. JS's single-threaded event loop makes C#'s per-bucket `lock` * unnecessary — nothing here awaits mid-mutation. */ declare class BurstRatePolicy extends RatePolicy { /** Number of permits replenished during each {@link period}. */ permitLimit: number; /** Replenishment period, in milliseconds. */ period: number; /** Additional permits available for an immediate burst. */ burstLimit: number; /** * Maximum number of delayed reservations per connection and member. * Further requests are denied until queue positions become available. */ queueLimit: number; private readonly connections; constructor(name?: string); applicable(context?: RateControlContext): Ruling; private validate; private replenish; private releaseQueuePosition; } /** * Bridges the named Warehouse rate-policy registry into the unified * resource-manager pipeline (port of C# `NamedRateControlManager`). Applies * only to members carrying a `@RateControl(name)` policy name, and only for * `Execute`/`SetProperty` actions. */ declare class NamedRateControlManager implements IRateControlManager { readonly managerCategory: "rateControl"; applicable(context: ResourceManagerContext): Ruling; } export { ActionType, AesEncryptionProvider, AesGcmSymetricCipher, ArgumentTemplate, AsyncBag, AsyncException, AsyncQueue, AsyncReply, AsyncStreamReply, AuditingManager, type AuthenticationContext, AuthenticationDirection, type AuthenticationMaterial, AuthenticationMaterialType, AuthenticationMode, type AuthenticationProviderReply, AuthenticationResult, AuthenticationRuling, type AuthenticationSession, AutoDelivered, BurstRatePolicy, Char16, Codec, type ComposableTru, DC, DataDeserializer, DataSerializer, Decimal128, type DestroyedEvent, type EncryptionContext, EncryptionMode, Endian, type EnumConstant, EnumType, EnumValue, EpAuthPacket, EpAuthPacketCommand, EpAuthPacketHeader, EpAuthPacketMethod, EpConnection, EpConnectionContext, type EpConnectionOptions, EpPacket, EpPacketMethod, EpPacketNotification, EpPacketReply, EpPacketRequest, type EpReconnectMetrics, EpResource, type EpResourceAttachTarget, type EpResourceConstructor, type EpResourceOptions, EpServer, type EpServerOptions, ErrorType, EventHandler, type EventOccurredInfo, EventSource, EventTemplate, ExceptionCode, Export, type ExportFunctionOptions, Float32, FunctionTemplate, type GroupConfig, GroupInt16Codec, GroupInt32Codec, GroupInt64Codec, GroupUInt16Codec, GroupUInt32Codec, GroupUInt64Codec, type IAuditingManager, type IAuthenticationHandler, type IAuthenticationProvider, type IDestructible, type IEncryptionProvider, type IKeyExchanger, type INetworkReceiver, type IPermissionsManager, type IRateControlManager, type IResource, type IResourceContext, type IResourceManager, type ISocket, type IStore, type ISymetricCipher, type ITypeDef, IdentityPassword, Instance, Int128, Int16, Int32, Int64, Int8, LocalTypeDef, LogType, type ManagerCategory, type MemberTemplate, MemberType, MemoryStore, NamedRateControlManager, NetworkBuffer, NetworkConnection, NotModified, type NotificationHandler, ParsedTdu, PasswordAuthenticationHandler, PasswordAuthenticationProvider, PasswordHash, PermissionsManager, PlainTdu, ProgressType, type PropertyChangeEvent, type PropertyModificationInfo, PropertyTemplate, RateControl, RateControlContext, RateControlManager, RatePolicy, Record$1 as Record, Remote, type RemoteArgumentDef, type RemoteConstantDef, type RemoteEventDef, type RemoteFunctionDef, type RemoteInfo, type RemoteMemberMetadata, type RemotePropertyChange, type RemotePropertyDef, type RemotePropertyValue, RemoteTypeDef, type RemoteTypeDefResolver, type RemoteTypeDefSnapshot, type RequestHandler, Resource, ResourceId, ResourceLink, ResourceManagerContext, ResourceManagerEvaluation, ResourceOperation, Ruling, SocketState, StorePermissionsManager, StreamMode, TcpSocket, Tdu, TduClass, TduIdentifier, Tru, TruComposite, TruIdentifier, TruPrimitive, TruTypeDef, TypeDef, type TypeDefConstant, TypeDefKind, type TypeDefProperty, TypeDef as TypeTemplate, TypedList, TypedMap, TypedTuple, UInt128, UInt16, UInt32, UInt64, UInt8, UserPermissionsManager, Uuid, WSocket, Warehouse, type WarehouseGetOptions, type WarehouseRemoteGetOptions, char16, defineEnum, enumValue, event, f32, getRemoteInfo, getResourceManagerTypes, getTemplate, getTypeDef, i16, i32, i64, i8, isRecord, makeBigIntCodec, makeNumberCodec, readProperty, recordCompose, registerTruParser, registerTruParserAsync, registerTypeDefResolver, sha3, sha3_256, sha3_512, snapshotProperties, subscribeToProperty, subscribeToResource, subscribeToResourceEvent, t, tupleIdentifier, typedList, typedMap, typedTuple, u16, u32, u64, u8 };