From f48fe21eaa6e9fbe9723ee0ca3d5310d073160b4 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Wed, 11 Sep 2019 05:36:42 -0700 Subject: [PATCH] Make client.device fulfill type constraints Summary: This is an interesting invariant that TS caught here. We expect `getDevice()` to always return a device but it cannot because it's set lazily. John Knox suggested we instead set up a promise in the constructor and resolve it instead of overriding the stateful promise later. Reviewed By: jknoxville Differential Revision: D17313468 fbshipit-source-id: 8fd75f2720546abf67beead23db56216f1a5e0df --- src/Client.tsx | 19 ++++++++++++++----- src/plugin.tsx | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Client.tsx b/src/Client.tsx index fc211e344..42f5e3bb0 100644 --- a/src/Client.tsx +++ b/src/Client.tsx @@ -115,7 +115,9 @@ export default class Client extends EventEmitter { responder: Partial>; store: Store; activePlugins: Set; - device: Promise | undefined; + device: Promise; + _deviceResolve: (device: BaseDevice) => void = _ => {}; + _deviceSet: boolean = false; logger: Logger; lastSeenDeviceList: Array; broadcastCallbacks: Map>>; @@ -154,6 +156,10 @@ export default class Client extends EventEmitter { this.activePlugins = new Set(); this.lastSeenDeviceList = []; + this.device = new Promise((resolve, _reject) => { + this._deviceResolve = resolve; + }); + const client = this; // node.js doesn't support requestIdleCallback const rIC = @@ -211,11 +217,11 @@ export default class Client extends EventEmitter { However, clients can connect before a device is registered, so wait a while for the device to be registered if it isn't already. */ setMatchingDevice(): void { - if (this.device) { + if (this._deviceSet) { return; } - this.device = reportPlatformFailures( - new Promise((resolve, reject) => { + reportPlatformFailures( + new Promise((resolve, reject) => { const device = this.store .getState() .connections.devices.find( @@ -248,7 +254,10 @@ export default class Client extends EventEmitter { }, 5000); }), 'client-setMatchingDevice', - ); + ).then(device => { + this._deviceSet = true; + this._deviceResolve(device); + }); } supportsPlugin(Plugin: typeof FlipperPlugin): boolean { diff --git a/src/plugin.tsx b/src/plugin.tsx index 552321367..f5b4ee9ef 100644 --- a/src/plugin.tsx +++ b/src/plugin.tsx @@ -120,7 +120,7 @@ export abstract class FlipperBasePlugin< reducers: { [actionName: string]: (state: State, actionData: any) => Partial; } = {}; - app: App; + app: App | null = null; onKeyboardAction: ((action: string) => void) | undefined; toJSON() {