import Adapter , { AddressType , Advertisement } from "@sblendid/adapter-node" ; import Service , { MaybeConverters } from "./service" ; export interface Options { address : string ; addressType : AddressType ; advertisement : Advertisement ; connectable ? : boolean ; } export type ServiceConverters = Record < SUUID , MaybeConverters > ; export type State = "connecting" | "connected" | "disconnecting" | "disconnected" ; export default class Peripheral { public uuid : PUUID ; public adapter : Adapter ; public name : string ; public address : string ; public addressType : AddressType ; public advertisement : Advertisement = { } ; public connectable ? : boolean ; public state : State = "disconnected" ; private serviceUuids ? : SUUID [ ] ; constructor ( uuid , adapter , options ) { this . uuid = uuid ; this . adapter = adapter ; this . name = options . advertisement . localName || "" ; this . address = options . address ; this . addressType = options . addressType ; this . advertisement = options . advertisement ; this . connectable = options . connectable ; } public async connect ( ) { if ( this . state !== "disconnected" ) return ; this . state = "connecting" ; await this . adapter . connect ( this . uuid ) ; this . state = "connected" ; } public async disconnect ( ) { if ( this . state !== "connected" ) return ; this . state = "disconnecting" ; await this . adapter . disconnect ( this . uuid ) ; this . state = "disconnected" ; } public async getService < C extends MaybeConverters = undefined > ( uuid , converters ? ) { const serviceConverters = converters ? { [ uuid ] : converters } : undefined ; const services = await this . getServices ( serviceConverters ) ; return services . find ( s => s . uuid === uuid ) ; } public async getServices ( serviceConverters ? ) { return this . ensureTempraryConnection ( async ( ) => { const uuids = await this . getSUUIDs ( ) ; return this . mapUUIDsToServices ( uuids , serviceConverters ) ; } , [ ] ) ; } public async hasService ( uuid ) { const services = await this . getServices ( ) ; return services . some ( s => s . uuid === uuid ) ; } public async getRssi ( ) { return this . ensureTempraryConnection ( ( ) => this . adapter . getRssi ( this . uuid ) , undefined ) ; } public isConnected ( ) { return this . state === "connected" ; } private async ensureTempraryConnection < C > ( callback , fallback ) { if ( this . state !== "disconnected" ) return callback ( ) ; if ( ! this . connectable ) return fallback ; await this . connect ( ) ; const returnValue = await callback ( ) ; await this . disconnect ( ) ; return returnValue ; } private mapUUIDsToServices ( uuids , serviceConverters ? ) { return uuids . map ( uuid => this . getServiceForUUID ( uuid , serviceConverters ) ) ; } private getServiceForUUID ( uuid , serviceConverters = { } ) { const converters = serviceConverters [ uuid ] ; return new Service ( uuid , this , { converters } ) ; } private async getSUUIDs ( ) { if ( this . serviceUuids ) return this . serviceUuids ; this . serviceUuids = await this . adapter . getServices ( this . uuid ) ; return this . serviceUuids ; } }