import type { AdvertisementObservation, OwnerScanOptions } from './advertisement'; import type { FeatureRegistry } from './capabilities'; import { type AdapterStateSnapshot, type AdapterStateWatch, type AttachmentRecord, type BackendIdentity } from './identity'; import type { CharacteristicPath, ConnectionPath, DatabasePath, DescriptorPath, GattDatabase } from './gatt'; import type { NotificationValue } from './gatt'; import type { BackendOperationDispatch, OperationOptions, OperationTerminalRecord, PublicOperationOptions, ReadRequest, ReadResult, SubscribeRequest, WriteRequest, WriteResult } from './operations'; import type { ConnectionMaximumWriteLengthMeasurement, ConnectionMaximumWriteLengthRequest, ConnectionPhyObservation, ConnectionPhyRequest, ConnectionPriorityRequest, ConnectionWriteReadinessWatch, EffectiveMtuMeasurement, EffectiveMtuRequest, MtuNegotiation, ReadRssiRequest, ReadPhyRequest, RequestPhyRequest, RequestPriorityRequest, RequestMtuRequest, RssiMeasurement } from './connection-controls'; import type { CleanupRecord } from './errors'; import type { AttachmentId, BackendCompatibilityOffer, ClientId, ConnectionId, GenerationId, LeaseId, ManagerId, PeerId, ResourceCount, ScanShareToken, ScanSessionId, SubscriptionId, SerializableRecord } from './primitives'; import type { BoundedAsyncStream } from './streams'; import type { ManagerRestorationCapability } from './restoration'; import type { PeerReference } from './peer-reference'; import type { SecurityBackend } from './security'; import type { DiagnosticTraceDocument } from '../diagnostics/trace-format'; import type { NormalizedScanQuery } from './scan-query'; import type { ScanPlan } from './scan-planning'; export type OwnerMode = 'owning' | 'borrowing'; export type ManagerState = 'new' | 'ready' | 'destroying' | 'destroyed' | 'failed'; export type ConnectionState = 'connecting' | 'connected' | 'disconnecting' | 'disconnected' | 'lost'; export interface ResourceCounters { readonly activeScanControllers: ResourceCount; readonly scanConsumers: ResourceCount; readonly chooserSessions: ResourceCount; readonly connectionLeases: ResourceCount; readonly physicalLinks: ResourceCount; readonly databaseSnapshots: ResourceCount; readonly physicalCccdEnablements: ResourceCount; readonly subscriptionConsumers: ResourceCount; readonly queuedOperations: ResourceCount; readonly dispatchedOperations: ResourceCount; readonly retainedByteBuffers: ResourceCount; readonly restorationRecords: ResourceCount; readonly orphanedIpcOwners: ResourceCount; } export interface AdapterBackend { currentState(): Promise>; watchState(): Promise>; } export type PeerSource = 'scan-observed' | 'app-reference' | 'system-connected' | 'system-bonded' | 'origin-authorized' | 'restored' | 'backend-cache'; export interface BlePeerState { readonly reachability: 'reachable' | 'unreachable' | 'unknown'; readonly connection: 'connected' | 'disconnected' | 'unknown'; readonly bond: 'bonded' | 'not-bonded' | 'unknown' | 'unsupported'; readonly lastSeenAtMonotonicMs: number | null; } export interface BackendPeerQuery extends PublicOperationOptions { readonly sources?: readonly PeerSource[]; readonly services?: readonly string[]; readonly references?: readonly PeerReference[]; readonly includeUnavailable?: boolean; } export interface BackendPeerRecord { readonly reference: PeerReference; readonly peerId: PeerId; readonly name: string | null; readonly rssi: number | null; readonly source: PeerSource; readonly state: BlePeerState; readonly clockScope?: string; } export interface PeerDirectoryBackend { resolve(reference: PeerReference, options: BackendPeerQuery): Promise | null>; known(options: BackendPeerQuery): Promise[]>; connected(options: BackendPeerQuery): Promise[]>; bonded(options: BackendPeerQuery): Promise[]>; authorized(options: BackendPeerQuery): Promise[]>; restored(options: BackendPeerQuery): Promise[]>; } export interface ScanLease { readonly scanSessionId: ScanSessionId; readonly leaseId: LeaseId; readonly shareToken: ScanShareToken | null; readonly observations: BoundedAsyncStream>; stop(): Promise; } export interface ScannerBackend { plan?(query: NormalizedScanQuery): ScanPlan; start(options: OwnerScanOptions, clientId: ClientId): Promise>; join(sharedLeaseId: LeaseId, shareToken: ScanShareToken, clientId: ClientId): Promise>; } export interface ConnectionLease { readonly leaseId: LeaseId; readonly connection: BackendConnection; release(): Promise; } export interface BackendConnection { readonly attachment: AttachmentRecord; readonly attachmentId: AttachmentId; readonly peerId: PeerId; readonly connectionId: ConnectionId; readonly connectionGeneration: GenerationId<'connection-generation', string>; readonly state: ConnectionState; disconnect(): Promise; } export type ConnectionIntent = 'direct' | 'when-available'; /** * A canonical out-of-band radio address accepted by the optional `peer:address-targeting` * capability. Only public/static addresses are expressible; resolvable private addresses * must re-enter through a durable `PeerReference`. */ export interface PeerAddressDescriptor { readonly address: string; readonly addressType: 'public' | 'random'; } export type BlePhy = 'le-1m' | 'le-2m' | 'le-coded'; export interface ConnectionOptions extends PublicOperationOptions { readonly intent?: ConnectionIntent; readonly transport?: 'le' | 'auto'; readonly preferredPhy?: readonly BlePhy[]; } export interface ConnectionBackend { connect(peerId: PeerId, clientId: ClientId, options: ConnectionOptions): Promise>; /** * Optional `peer:address-targeting` seam: mints a connectable peer handle for a canonical * radio address known out of band, without requiring a prior scan observation. Backends * that do not register the capability leave this undefined and callers fail closed. */ peerFromAddress?(descriptor: PeerAddressDescriptor): PeerId; readRssi?(connection: BackendConnection, request: ReadRssiRequest): BackendOperationDispatch>; requestMtu?(connection: BackendConnection, request: RequestMtuRequest): BackendOperationDispatch>; effectiveMtu?(connection: BackendConnection, request: EffectiveMtuRequest): BackendOperationDispatch>; requestPriority?(connection: BackendConnection, request: RequestPriorityRequest): BackendOperationDispatch>; readPhy?(connection: BackendConnection, request: ReadPhyRequest): BackendOperationDispatch>; requestPhy?(connection: BackendConnection, request: RequestPhyRequest): BackendOperationDispatch>; writeWithoutResponseReadiness?(connection: BackendConnection, options?: PublicOperationOptions): Promise>; maximumWriteLength?(connection: BackendConnection, request: ConnectionMaximumWriteLengthRequest): BackendOperationDispatch>; } export interface GattBackend { discover(connection: BackendConnection, options: PublicOperationOptions): Promise>; read(path: CharacteristicPath, request: ReadRequest): BackendOperationDispatch>; write(path: CharacteristicPath, request: WriteRequest): BackendOperationDispatch>; readDescriptor(path: DescriptorPath, request: ReadRequest): BackendOperationDispatch>; writeDescriptor(path: DescriptorPath, request: WriteRequest): BackendOperationDispatch>; subscribe(path: CharacteristicPath, request: SubscribeRequest): BackendOperationDispatch>; unsubscribe(subscription: BackendSubscription, operation: OperationOptions): BackendOperationDispatch>; } export interface BackendSubscription { readonly subscriptionId: SubscriptionId; readonly path: CharacteristicPath; readonly terminal: OperationTerminalRecord; readonly notifications: BoundedAsyncStream; } export interface BackendEventBase { readonly attachment: AttachmentRecord; readonly attachmentId: AttachmentId; readonly ingressOrdinal: number; } export interface BackendDatabaseChangedEvent extends BackendEventBase { readonly kind: 'database-changed'; readonly database: DatabasePath; } /** A loss is scoped to the exact attachment, connection generation, and owner lease. */ export interface BackendConnectionLostEvent extends BackendEventBase { readonly kind: 'connection-lost'; readonly connection: ConnectionPath; } export interface BackendGenericEvent extends BackendEventBase { readonly kind: 'adapter-state' | 'backend-restarted' | 'diagnostic'; } /** Normalized scan delivery, separate from a stream's bounded overflow accounting record. */ export interface BackendScanResultEvent extends BackendEventBase { readonly kind: 'scan-result'; readonly observation: AdvertisementObservation; } export interface BackendScanOverflowEvent extends BackendEventBase { readonly kind: 'scan-overflow'; readonly scanSessionId: ScanSessionId; readonly policy: import('./streams').OverflowPolicy; readonly droppedItems: ResourceCount; readonly droppedBytes: ResourceCount; readonly replacedItems: ResourceCount; } export type BackendDisconnectReason = 'local' | 'peer' | 'adapter' | 'backend-restart'; export interface BackendConnectionStateChangedEvent extends BackendEventBase { readonly kind: 'connection-state-changed'; readonly connection: ConnectionPath; readonly previous: ConnectionState; readonly current: ConnectionState; readonly reason: BackendDisconnectReason | null; } export interface BackendDisconnectedEvent extends BackendEventBase { readonly kind: 'disconnected'; readonly connection: ConnectionPath; readonly reason: BackendDisconnectReason; } export interface BackendCharacteristicValueChangedEvent extends BackendEventBase { readonly kind: 'characteristic-value-changed'; readonly path: CharacteristicPath; readonly value: NotificationValue; } export interface BackendNotificationOverflowEvent extends BackendEventBase { readonly kind: 'notification-overflow'; readonly subscriptionId: SubscriptionId; readonly policy: import('./streams').OverflowPolicy; readonly droppedItems: ResourceCount; readonly droppedBytes: ResourceCount; readonly replacedItems: ResourceCount; } export interface BackendMtuChangedEvent extends BackendEventBase { readonly kind: 'mtu-changed'; readonly connection: ConnectionPath; readonly mtu: number; readonly maximumWriteLength: number; } export interface BackendBondSecurityEvent extends BackendEventBase { readonly kind: 'bond-security-changed'; readonly peerId: PeerId; readonly bond: 'none' | 'bonding' | 'bonded' | 'failed' | 'unavailable'; readonly security: 'unencrypted' | 'encrypted' | 'authenticated' | 'unavailable'; } export interface BackendPhyChangedEvent extends BackendEventBase { readonly kind: 'phy-changed'; readonly connection: ConnectionPath; readonly txPhy: '1m' | '2m' | 'coded' | 'unavailable'; readonly rxPhy: '1m' | '2m' | 'coded' | 'unavailable'; } export interface BackendPermissionStateChangedEvent extends BackendEventBase { readonly kind: 'permission-state-changed'; readonly state: AdapterStateSnapshot; } export interface BackendRestorationEvent extends BackendEventBase { readonly kind: 'restoration-received'; readonly record: SerializableRecord; } export interface BackendRestartingEvent extends BackendEventBase { readonly kind: 'backend-restarting'; readonly reason: string; } export interface BackendDiagnosticEvent extends BackendEventBase { readonly kind: 'diagnostic-warning'; readonly code: string; readonly message: string; readonly detail: SerializableRecord; } /** Open extension lane: namespaced event kinds retain typed serializable payloads without central-union edits. */ export interface BackendExtensionEvent extends BackendEventBase { readonly kind: `extension:${string}`; readonly payload: SerializableRecord; } export type BackendEvent = BackendDatabaseChangedEvent | BackendConnectionLostEvent | BackendGenericEvent | BackendScanResultEvent | BackendScanOverflowEvent | BackendConnectionStateChangedEvent | BackendDisconnectedEvent | BackendCharacteristicValueChangedEvent | BackendNotificationOverflowEvent | BackendMtuChangedEvent | BackendBondSecurityEvent | BackendPhyChangedEvent | BackendPermissionStateChangedEvent | BackendRestorationEvent | BackendRestartingEvent | BackendDiagnosticEvent | BackendExtensionEvent; export declare function assertBackendEvent(event: BackendEvent): void; export interface BleCentralBackend> { readonly identity: Identity; readonly adapter: AdapterBackend; readonly scanner: ScannerBackend; readonly connections: ConnectionBackend; readonly gatt: GattBackend; readonly security?: SecurityBackend; readonly peers?: PeerDirectoryBackend; readonly features: FeatureRegistry; readonly traceDocument?: () => DiagnosticTraceDocument; attach(request: BackendAttachmentRequest): Promise>; events(): BoundedAsyncStream>; resourceCounters(): ResourceCounters; destroy(): Promise; } /** Opaque result of the one manager-neutral backend attachment handshake. */ export declare abstract class AttachedBackend> { private readonly authenticatedReceiptMarker; protected constructor(); abstract readonly backend: BleCentralBackend; abstract readonly attachment: BackendAttachment; protected hasAuthenticatedReceiptMarker(): boolean; } /** Negotiates one backend attachment before logical manager admission. */ export declare function attachBackend>(backend: BleCentralBackend, coreCompatibility: BackendCompatibilityOffer): Promise>; /** Rejects mismatched backend/identity tuples before any manager can use the binding. */ export declare function assertAttachedBackend>(attachedBackend: AttachedBackend): void; export interface ManagerConstructionBase> { readonly attachedBackend: AttachedBackend; readonly clientId: ClientId; readonly managerId: ManagerId; /** Present only when this provider owns a bound native restoration authority. */ readonly restoration?: ManagerRestorationCapability; } export interface BackendAttachmentRequest { readonly coreCompatibility: BackendCompatibilityOffer; } export interface BackendAttachment> { readonly attachment: AttachmentRecord; readonly identity: Identity; } export interface OwningManagerConstruction> extends ManagerConstructionBase { readonly ownerMode: 'owning'; } export interface BorrowingManagerConstruction> extends ManagerConstructionBase { readonly ownerMode: 'borrowing'; } export type ManagerConstruction> = OwningManagerConstruction | BorrowingManagerConstruction; //# sourceMappingURL=backend.d.ts.map