/** * HTTP Transport — fetch-based client for SDN server API endpoints. */ import type { AuthProvider } from './auth'; /** A single schema entry in the catalog. */ export interface SchemaCatalogEntry { name: string; record_count: number; total_bytes: number; oldest_epoch?: string; newest_epoch?: string; } /** Catalog response from GET /api/v1/catalog. */ export interface NodeCatalog { peer_id: string; schemas: SchemaCatalogEntry[]; capabilities: string[]; rate_limits: Record; } /** Content type of the aligned size-prefixed FlatBuffer record stream. */ export declare const FLATBUFFER_STREAM_CONTENT_TYPE = "application/vnd.sdn.flatbuffers.stream"; /** * Options for querying data via the flow-served bulk endpoint * (`GET /api/v1/data//bulk`, loop C.4 — param parsing, profile * resolution, format selection and ETag/304 handling run inside the * data-retrieval WASM flow). */ export interface DataQueryOptions { /** SDS schema/standard identifier (`OMM.fbs`, `OMM`, or `omm`). */ schema: string; /** * Epoch profile (`nearest` / `as_of` / `forward`; `mode` alias accepted * server-side). Absent = retrieval-module default (`nearest`). */ profile?: string; /** Target epoch: unix seconds (fractional allowed) or RFC3339. Default: now (server-side). */ epoch?: number | string; /** Row limit (positive integer). */ limit?: number; /** Provider source partition (bare source name, e.g. `celestrak-gp`). */ source?: string; /** * Wire format. DEFAULT `flatbuffers` — the aligned size-prefixed * FlatBuffer record stream, consumed zero-copy. `json` is the opt-in * edge adapter. */ format?: 'flatbuffers' | 'json'; /** * Cached entity tag for a conditional request. Sent as `If-None-Match`; * a 304 response comes back as `notModified: true` with an empty body — * serve the local engine store copy. */ ifNoneMatch?: string | null; } /** * FlatBuffer-stream query result (the DEFAULT): the verbatim aligned * size-prefixed record stream plus the flow's caching/count headers. */ export interface DataQueryStreamResult { format: 'flatbuffers'; /** HTTP status (200, or 304 for a conditional-request hit). */ status: number; /** True when the server answered 304 Not Modified (stream is empty). */ notModified: boolean; /** `ETag` header (`W/"fnv1a64-"`), for the next conditional request. */ etag: string | null; /** `X-SDN-Record-Count` header (0 when absent / not modified). */ recordCount: number; /** Aligned size-prefixed (u32 LE) FlatBuffer frames — the verbatim body. */ stream: Uint8Array; /** Zero-copy per-record frame iterator (subarray views into `stream`). */ frames(): Generator; } /** JSON edge-adapter query result (opt-in via `format: 'json'`). */ export interface DataQueryJsonResult { format: 'json'; status: number; notModified: boolean; etag: string | null; count: number; records: Array>; } /** * Iterate the frames of an aligned size-prefixed FlatBuffer record stream * (u32 little-endian length prefixes — the engine/server wire format, * `X-SDN-Stream-Format: flatsql-size-prefixed-le-u32`). Every yielded frame * is a zero-copy subarray view into `stream`. */ export declare function iterateSizePrefixedFrames(stream: Uint8Array): Generator; /** Result of a publish operation. */ export interface PublishResult { cid: string; schema: string; stored_at: string; bytes: number; } /** Batch publish result. */ export interface BatchPublishResult { schema: string; stored_at: string; count: number; results: Array<{ cid?: string; error?: string; bytes: number; }>; } /** Log head response from GET /api/v1/log/{schema}/head. */ export interface LogHeadResponse { schema_type: string; publisher_peer_id: string; head_sequence: number; head_entry_hash: string; record_count: number; oldest_epoch_day: string; newest_epoch_day: string; } /** A single publisher's log head info. */ export interface LogHeadInfo { publisher_peer_id: string; schema_type: string; head_sequence: number; head_entry_hash: string; timestamp: string; } /** Log heads response from GET /api/v1/log/{schema}/heads. */ export interface LogHeadsResponse { schema_type: string; count: number; heads: LogHeadInfo[]; } export interface ChannelAccessOptions { subject?: string; grantId?: string; visibility?: string; encryptedStreamHeader?: string; encryptedRecordIndex?: number | string; } export interface ChannelListOptions extends ChannelAccessOptions { standardCode?: string; } export interface ChannelSummary { channelId: string; sourceId?: string; standardCode: string; feedUuid?: string | null; visibility?: string; subscribed?: boolean; pnmVerified?: boolean; dpmVerified?: boolean; grantState?: string; encryptionState?: string; [key: string]: unknown; } export interface ChannelMonitor extends ChannelSummary { channelHead?: string; providerPeer?: string; localRows?: number; remoteRows?: number; syncedRows?: number; missingRows?: number; pinnedCount?: number; pinnedRows?: number; pinnedBytes?: number; syncedBytes?: number; throughputBytesPerSecond?: number; wireSpeedUtilization?: number | null; timingsMs?: ChannelMonitorTimings; lastVerifiedUpdate?: string; } export interface ChannelMonitorTimings { discovery?: number; grantNegotiation?: number; pnmDpmVerification?: number; transfer?: number; decrypt?: number; hashVerification?: number; durableImport?: number; } export type ChannelActionResponse = Record; export type ChannelGrantRequest = Record; export interface ChannelKeyEnvelopeRequest { recipientKeyId: string; contentKeyId?: string; } export interface ChannelKeyEnvelopeResponse { channelId: string; sourceId?: string; standardCode: string; feedUuid?: string | null; grantState?: string; contentKeyId: string; recipientKeyId: string; keyEpoch?: string; algorithm?: string; envelopeCid?: string; wrappedKeyEnvelopeBase64?: string; [key: string]: unknown; } /** Anonymous default-$APP discovery document route. */ export declare const DEFAULT_APPS_PATH = "/api/v1/apps/default"; /** Anonymous $APP record byte route prefix. */ export declare const APP_RECORD_PATH_PREFIX = "/api/v1/apps/records/"; /** Media type the node serves $APP record bytes as. */ export declare const APP_RECORD_CONTENT_TYPE = "application/x-flatbuffers; schema=APP"; /** * Runtime class of an SDN default app: `server` is the node daemon (its * Dashboard), `browser` is this client (the Orbital Console). These map onto * the $APP schema's `appRuntimeTarget` NODE / PAGE vocabulary. */ export type AppRuntimeClass = 'server' | 'browser'; /** One UI page of an $APP, as reported by the node's registry. */ export interface DefaultAppUIPage { ID: string; TITLE?: string; DESCRIPTION?: string; ICON?: string; MEDIA_TYPE?: string; ENCODING?: string; CONTENT_SHA256?: string; ENTRY: boolean; MODULE_ID?: string; URL?: string; content_bytes?: number; } /** Link from one runtime class's default app to the other's. */ export interface DefaultAppCrossLink { runtime_class: AppRuntimeClass; app_id?: string; name?: string; url?: string; } /** * One default app. * * Two key vocabularies, per the SDN JSON-capitalization law: fields read out * of the $APP FlatBuffer keep the IDL's UPPER_SNAKE spelling; everything the * node synthesizes (runtime class, state, URLs, cross-link) is lowercase. */ export interface DefaultAppEntry { runtime_class: AppRuntimeClass; /** `installed` — the node holds the $APP record; `declared` — it only points at the app. */ state: 'installed' | 'declared'; default: boolean; /** Where this runtime opens the app (origin-relative when the node serves it). */ url?: string; /** Where the $APP record bytes are fetched. Absent for a declared app. */ record_url?: string; record_bytes?: number; cross_link?: DefaultAppCrossLink; ID: string; NAME?: string; VERSION?: string; DESCRIPTION?: string; CREATED_AT?: string; UPDATED_AT?: string; UI?: DefaultAppUIPage[]; } /** Response of `GET /api/v1/apps/default`. */ export interface DefaultAppsDocument { generated_at: string; node_peer_id?: string; runtime_classes: AppRuntimeClass[]; /** * Keyed by runtime class. A class with no default is ABSENT rather than * null — the node is saying nothing about it, which is not the same as * saying it has none configured. */ defaults: Partial>; } /** Construction options for {@link HttpTransport}. */ export interface HttpTransportOptions { /** * Fetch credentials mode. Defaults to `'include'` (session-cookie auth * against a same-origin / trusted SDN node — the historical behavior). * * Pass `'omit'` for anonymous cross-origin data queries: browsers BLOCK * credentialed CORS responses unless the server answers with * `Access-Control-Allow-Credentials: true`, which SDN nodes do not send * on the public data endpoints — a credentialed cross-origin `queryData` * therefore fails with a network error even though the endpoint itself * is publicly readable. */ credentials?: RequestCredentials; } /** HTTP transport for SDN server APIs. */ export declare class HttpTransport { private baseUrl; private authProvider?; private credentials; constructor(baseUrl: string, authProvider?: AuthProvider, options?: HttpTransportOptions); /** Fetch the node's schema catalog. */ getCatalog(): Promise; /** * Query data records via the flow-served bulk endpoint * (`GET /api/v1/data//bulk`). * * FLATBUFFERS-FIRST (loop D.3): the default is ONE request whose body is * the aligned size-prefixed FlatBuffer record stream, returned verbatim * for zero-copy consumption (`frames()` yields subarray views; feed * `stream` straight into `ingestFlatBufferStream` for persistence). JSON * is the opt-in edge adapter (`format: 'json'`). Pass `ifNoneMatch` with * a previously returned `etag` to make the request conditional; a 304 * comes back as `notModified: true` — serve the local engine store copy. */ queryData(opts: DataQueryOptions & { format: 'json'; }): Promise; queryData(opts: DataQueryOptions & { format?: 'flatbuffers'; }): Promise; queryData(opts: DataQueryOptions): Promise; /** * Get a single record's raw FlatBuffer bytes by CID * (`GET /api/v1/data/records/{schema}/{cid}`, `application/x-flatbuffers` * — no base64, no JSON envelope). Returns null when the record is absent. */ getRecord(schema: string, cid: string): Promise; /** Publish a single FlatBuffer record. Requires authentication. */ publishData(schema: string, data: Uint8Array): Promise; /** Publish multiple records as a uint32BE-length-prefixed stream. */ publishBatch(schema: string, records: Uint8Array[]): Promise; /** Get log head for a publisher+schema. */ getLogHead(schema: string, publisherPeerID: string): Promise; /** Get all publishers' log heads for a schema. */ getLogHeads(schema: string): Promise; /** Get node info. */ getNodeInfo(): Promise>; /** * Discover the node's DEFAULT $APP per runtime class * (`GET /api/v1/apps/default`). * * ANONYMOUS by contract on the node side — a browser client asking "what do * I open?" has no session yet — so pass `credentials: 'omit'` when reading a * node cross-origin, exactly as for the public data endpoints. * * `defaults.browser` is the app THIS client opens; `defaults.server` is the * node's own dashboard, and each carries a `cross_link` to the other so the * two faces can link to each other (owner ruling 2026-08-04). */ getDefaultApps(): Promise; /** * Fetch an app's $APP record bytes (`GET /api/v1/apps/records/`), the * canonical size-prefixed FlatBuffer. Returns `null` when the node holds no * record for that id — a DECLARED default app is a pointer to where the app * is served, not a record this node can hand over. */ getAppRecord(appId: string): Promise; listChannels(options?: ChannelListOptions): Promise; getChannel(channelId: string, options?: ChannelAccessOptions): Promise; subscribeChannel(channelId: string, options?: ChannelAccessOptions): Promise; unsubscribeChannel(channelId: string, options?: ChannelAccessOptions): Promise; publishChannelStream(channelId: string, stream: Uint8Array, options?: ChannelAccessOptions): Promise; issueChannelGrant(channelId: string, grant: ChannelGrantRequest, options?: ChannelAccessOptions): Promise; requestChannelKeyEnvelope(channelId: string, request: ChannelKeyEnvelopeRequest, options?: ChannelAccessOptions): Promise; openChannelStream(channelId: string, options?: ChannelAccessOptions): Promise; openChannelModuleFeed(channelId: string, options?: ChannelAccessOptions): Promise; monitorChannel(channelId: string, options?: ChannelAccessOptions): Promise; private postChannelAction; /** Internal fetch with auth headers. */ private fetch; } /** Error thrown by HttpTransport on non-2xx responses. */ export declare class SDNTransportError extends Error { status: number; body: string; url: string; constructor(status: number, body: string, url: string); } //# sourceMappingURL=http.d.ts.map