diff --git a/packages/connect/src/device/DeviceList.ts b/packages/connect/src/device/DeviceList.ts index 4d1ec05ad67..cec2f74e812 100644 --- a/packages/connect/src/device/DeviceList.ts +++ b/packages/connect/src/device/DeviceList.ts @@ -400,23 +400,18 @@ export class DeviceList extends TypedEmitter implements IDevic } private scheduleUpgradeCheck(apiType: TransportApiType, initParams: InitParams) { - clearTimeout(this.scheduledUpgradeChecks[apiType]); - this.scheduledUpgradeChecks[apiType] = setTimeout(async () => { - const transport = this.transport[apiType]; - const transports = this.transports.filter(t => t.apiType === apiType); - if (!transport || transport === transports[0]) return; - for (const t of transports) { - if (t === transport) break; - if (await t.ping()) { - this.transportLock(apiType, 'Upgrading', signal => - this.createInitPromise(apiType, initParams, signal), - ).catch(() => {}); - - return; - } - } - this.scheduleUpgradeCheck(apiType, initParams); - }, 1000); + this.scheduledUpgradeChecks[apiType]; + const transport = this.transport[apiType]; + const transports = this.transports.filter(t => t.apiType === apiType); + if (!transport || transport === transports[0]) return; + for (const t of transports) { + if (t === transport) break; + t.on('upgrade-available', () => { + this.transportLock(apiType, 'Upgrading', signal => + this.createInitPromise(apiType, initParams, signal), + ).catch(() => {}); + }); + } } private async selectTransport( diff --git a/packages/transport/src/sessions/background-browser.ts b/packages/transport/src/sessions/background-browser.ts index a63bf9e79c2..1ff3316727d 100644 --- a/packages/transport/src/sessions/background-browser.ts +++ b/packages/transport/src/sessions/background-browser.ts @@ -24,6 +24,7 @@ export class BrowserSessionsBackground implements SessionsBackgroundInterface { return new Promise(resolve => { const onmessage = (message: MessageEvent) => { + console.log('on message', message); if (params.id === message.data.id) { resolve(message.data); background.port.removeEventListener('message', onmessage); @@ -42,6 +43,7 @@ export class BrowserSessionsBackground implements SessionsBackgroundInterface { }); } + on(event: 'upgrade-available', listener: () => void): void; on(event: 'descriptors', listener: (descriptors: Descriptor[]) => void): void; on(event: 'releaseRequest', listener: (descriptor: Descriptor) => void): void; on(event: 'descriptors' | 'releaseRequest', listener: (descriptors: any) => void): void { diff --git a/packages/transport/src/sessions/background.ts b/packages/transport/src/sessions/background.ts index c061f244783..6bf34d54221 100644 --- a/packages/transport/src/sessions/background.ts +++ b/packages/transport/src/sessions/background.ts @@ -44,6 +44,7 @@ export class SessionsBackground */ descriptors: Descriptor[]; releaseRequest: Descriptor; + ['upgrade-available']: void; }> implements SessionsBackgroundInterface { @@ -130,6 +131,19 @@ export class SessionsBackground } private handshake() { + // check localhost:21235 periodically using POST request every 1 second. + // if it return 200, emit 'upgrade-available' event + // now write the code!! + setInterval(async () => { + const response = await fetch('http://127.0.0.1:21325/', { + method: 'POST', + }); + console.log('ping response', response); + if (response.status === 200) { + this.emit('upgrade-available'); + } + }, 1000); + return this.success(undefined); } diff --git a/packages/transport/src/sessions/client.ts b/packages/transport/src/sessions/client.ts index 99d96095983..cf2078d89e4 100644 --- a/packages/transport/src/sessions/client.ts +++ b/packages/transport/src/sessions/client.ts @@ -19,6 +19,7 @@ import { export class SessionsClient extends TypedEmitter<{ descriptors: Descriptor[]; releaseRequest: Descriptor; + 'upgrade-available': void; }> { // used only for debugging - discriminating sessions clients in sessions background log private caller = getWeakRandomId(3); @@ -40,6 +41,7 @@ export class SessionsClient extends TypedEmitter<{ this.background = background; background.on('descriptors', descriptors => this.emit('descriptors', descriptors)); background.on('releaseRequest', descriptor => this.emit('releaseRequest', descriptor)); + background.on('upgrade-available', () => this.emit('upgrade-available')); } private request(params: M) { diff --git a/packages/transport/src/sessions/types.ts b/packages/transport/src/sessions/types.ts index 98010c1f1c5..ccb2a99e6a0 100644 --- a/packages/transport/src/sessions/types.ts +++ b/packages/transport/src/sessions/types.ts @@ -115,6 +115,7 @@ export type HandleMessageResponse

= P extends { type: infer T } export interface SessionsBackgroundInterface { on(event: 'descriptors', listener: (descriptors: Descriptor[]) => void): void; on(event: 'releaseRequest', listener: (descriptor: Descriptor) => void): void; + on(event: 'upgrade-available', listener: () => void): void; handleMessage(message: M): Promise>; dispose(): void; } diff --git a/packages/transport/src/transports/abstractApi.ts b/packages/transport/src/transports/abstractApi.ts index 1e9283c650b..1439edc1d39 100644 --- a/packages/transport/src/transports/abstractApi.ts +++ b/packages/transport/src/transports/abstractApi.ts @@ -41,6 +41,7 @@ export abstract class AbstractApiTransport extends AbstractTransport { return this.scheduleAction( async () => { const handshakeRes = await this.sessionsClient.handshake(); + console.log('handshakeRes', handshakeRes); this.stopped = !handshakeRes.success; return handshakeRes; @@ -109,7 +110,7 @@ export abstract class AbstractApiTransport extends AbstractTransport { const { path } = input; const acquireIntentResponse = await this.sessionsClient.acquireIntent(input); - + console.log('acquireIntentResponse', acquireIntentResponse); if (!acquireIntentResponse.success) { return this.error({ error: acquireIntentResponse.error }); } diff --git a/packages/transport/src/transports/bridge.ts b/packages/transport/src/transports/bridge.ts index 82d9fa35f73..451114454d8 100644 --- a/packages/transport/src/transports/bridge.ts +++ b/packages/transport/src/transports/bridge.ts @@ -24,6 +24,10 @@ import * as bridgeApiResult from '../utils/bridgeApiResult'; import { createProtocolMessage } from '../utils/bridgeProtocolMessage'; import { receiveAndParse } from '../utils/receive'; import { buildMessage } from '../utils/send'; +import { SessionsBackground } from '../sessions/background'; +import { SessionsClient } from '../sessions/client'; +import { SessionsBackgroundInterface } from '../sessions/types'; +import { BrowserSessionsBackground } from '../sessions/background-browser'; const DEFAULT_URL = 'http://127.0.0.1:21325'; @@ -79,23 +83,64 @@ export class BridgeTransport extends AbstractTransport { public name = 'BridgeTransport' as const; public apiType = 'usb' as const; + protected sessionsClient: SessionsClient; + protected sessionsBackground: SessionsBackgroundInterface; constructor(params: BridgeConstructorParameters) { const { url = DEFAULT_URL, latestVersion, ...rest } = params || {}; super(rest); this.url = url; this.latestVersion = latestVersion; + console.log(params); + this.sessionsBackgroundUrl = params.sessionsBackgroundUrl || 'meow'; + this.sessionsBackground = new SessionsBackground(); + this.sessionsClient = new SessionsClient(this.sessionsBackground); + + console.log('bridge sessionsBackgroundUrl', this.sessionsBackground); + + console.log('bridge sessionsClient', this.sessionsClient); + + this.sessionsClient.on('descriptors', descriptors => { + console.log('bridge transport descriptors', descriptors); + }); + this.sessionsClient.on('upgrade-available', () => { + console.log('bridge client caught upgrade available'); + this.emit('upgrade-available', true); + }); } - ping({ signal }: AbstractTransportMethodParams<'ping'> = {}) { - return this.scheduleAction(signal => this.post('/', { signal }), { signal }) - .then(({ success }) => success) - .catch(() => false); + private async trySetSessionsBackground() { + if (!this.sessionsBackgroundUrl) { + this.logger?.log( + 'No sessionsBackgroundUrl provided. Falling back to use local module.', + ); + + return; + } + try { + const response = await fetch(this.sessionsBackgroundUrl, { method: 'HEAD' }); + if (!response.ok) { + console.warn( + `Failed to fetch sessions-background SharedWorker from url: ${this.sessionsBackgroundUrl}`, + ); + } else { + this.sessionsBackground = new BrowserSessionsBackground(this.sessionsBackgroundUrl); + // sessions client initiated with a request fn facilitating communication with a session backend (shared worker in case of webusb) + this.sessionsClient.setBackground(this.sessionsBackground); + } + } catch (err) { + console.warn( + 'Unable to load background-sharedworker. Falling back to use local module. Say bye bye to tabs synchronization. Error details: ', + err.message, + ); + } } public init({ signal }: AbstractTransportMethodParams<'init'> = {}) { return this.scheduleAction( async signal => { + await this.trySetSessionsBackground(); + const response = await this.post('/', { signal, });