import { PhyHubClient } from '.'; import { PeripheralTwinInstance } from './peripheral-twin'; import { PeripheralInstance } from './types/twin.types'; import { DescriptorValidator } from './advisory-validation'; /** * registry to create, store and retrieve instances of different types of twins e.g. Device, Screen, Peripheral */ export class TwinRegistry { private peripheralInstances: Map = new Map(); constructor(private phyHubClient: PhyHubClient) {} // create an instance of PeripheralTwinInstance class. // `advisoryValidator` is optional opt-in advisory descriptor validation; when // supplied it is applied to the instance (also to an already-cached one, so the // opt-in is honored regardless of call order). Omit it for unchanged behavior. async getPeripheralInstance( twinId: string, advisoryValidator?: DescriptorValidator, ): Promise { try { // check whether we've already created instance for this twinId if (this.peripheralInstances.has(twinId)) { const cached = this.peripheralInstances.get(twinId)!; if (advisoryValidator) { cached.enableAdvisoryValidation(advisoryValidator); } return cached; } // create an object of PeripheralTwinInstance class const peripheralTwinInstance = new PeripheralTwinInstance(this.phyHubClient, twinId); // class object is created, but perform sanity checks such as whether PhyHubClient is valid, twinId is valid etc. // to make sure we are able to correct and return a valid instance await peripheralTwinInstance.initialize(); if (advisoryValidator) { peripheralTwinInstance.enableAdvisoryValidation(advisoryValidator); } // set the newly created instance in the map for future use this.peripheralInstances.set(twinId, peripheralTwinInstance); return peripheralTwinInstance; } catch (error) { throw error; } } /** * Pool lookup WITHOUT creation (TECH-1394) — the client's ownership-loss * detection must only act on twins this app actually acquired; building an * instance for a foreign twinUpdated would be wrong (and would subscribe). */ getCachedPeripheralInstance(twinId: string): PeripheralTwinInstance | undefined { return this.peripheralInstances.get(twinId); } /** * Drop a revoked instance from the pool (TECH-1394) so a later * getPeripheralInstance — e.g. after this app re-registers and takes the * twin back — builds a FRESH, non-revoked instance instead of returning * the poisoned cached one. */ removePeripheralInstance(twinId: string): void { this.peripheralInstances.delete(twinId); } }