// src/core/core-discovery.ts import { BackendContractError, contractError } from '../backend-contract/errors' import type { BleCentralBackend } from '../backend-contract/backend' import type { GattDatabase, GattDatabaseChangedEvent } from '../backend-contract/gatt' import type { BackendIdentity } from '../backend-contract/identity' import type { PublicOperationOptions } from '../backend-contract/operations' import type { CoreConnection, CoreGattDatabase } from './core-gatt-handles' import { CoreGattDatabase as CoreGattDatabaseRuntime } from './core-gatt-handles' import type { ResourceLedger } from './resource-ledger' import type { UnifiedBleCore } from './unified-ble-core' /** Performs a fresh database discovery after invalidating the prior generation-bound snapshot. */ export async function discoverCoreGattDatabase>( core: UnifiedBleCore, backend: BleCentralBackend, resourceLedger: ResourceLedger, connection: CoreConnection, options: PublicOperationOptions, assertReady: (operation: string) => void, assertOperationAdmission: (options: PublicOperationOptions, operation: string) => void, assertAdmissionCurrent: (admissionEpoch: number, options: PublicOperationOptions, operation: string) => void, admissionEpoch: number, changeReason: GattDatabaseChangedEvent['reason'] | null, awaitQuarantineDrain: (() => Promise) | null ): Promise> { assertReady('discover') assertOperationAdmission(options, 'discover') connection.assertCurrent() const connectionGeneration = connection.resource.connectionGeneration const invalidation = await connection.invalidateDatabase('owner-released', changeReason) if (invalidation.state === 'release-failed') { throw new BackendContractError( invalidation.failures[0]?.error ?? contractError('platform.failure', 'gatt', 'unified-core.discover-cleanup').normalized ) } if (awaitQuarantineDrain !== null) { await awaitQuarantineDrain() } assertAdmissionCurrent(admissionEpoch, options, 'discover') connection.assertCurrent() let backendDatabase: GattDatabase try { backendDatabase = await backend.gatt.discover(connection.resource, options) } catch (error) { if (error instanceof BackendContractError) { throw error } throw contractError('gatt.discovery-required', 'gatt', 'unified-core.discover') } assertAdmissionCurrent(admissionEpoch, options, 'discover') connection.assertCurrent() if (connection.resource.connectionGeneration !== connectionGeneration) { throw contractError('connection.stale', 'connection', 'unified-core.discover') } const database = new CoreGattDatabaseRuntime(core, connection, backendDatabase) connection.setDatabase(database) resourceLedger.increment('databaseSnapshots') return database }