Allow unsubscribing from client events
Summary: In the next diffs, we are going to show a message only once when the plugin gets activated. This diff adds a way to unsubscribe from Flipper events after the first execution. Reviewed By: LukeDefeo Differential Revision: D47366239 fbshipit-source-id: 18cb99df865f9cf26c055a99b7d1b7058dcb123c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7644c9092a
commit
f59a2e5fba
@@ -59,34 +59,44 @@ export interface PluginClient<
|
|||||||
* the onConnect event is fired whenever the plugin is connected to it's counter part on the device.
|
* the onConnect event is fired whenever the plugin is connected to it's counter part on the device.
|
||||||
* For most plugins this event is fired if the user selects the plugin,
|
* For most plugins this event is fired if the user selects the plugin,
|
||||||
* for background plugins when the initial connection is made.
|
* for background plugins when the initial connection is made.
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onConnect(cb: () => void): void;
|
onConnect(cb: () => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The counterpart of the `onConnect` handler.
|
* The counterpart of the `onConnect` handler.
|
||||||
* Will also be fired before the plugin is cleaned up if the connection is currently active:
|
* Will also be fired before the plugin is cleaned up if the connection is currently active:
|
||||||
* - when the client disconnects
|
* - when the client disconnects
|
||||||
* - when the plugin is disabled
|
* - when the plugin is disabled
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onDisconnect(cb: () => void): void;
|
onDisconnect(cb: () => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to a specific event arriving from the device.
|
* Subscribe to a specific event arriving from the device.
|
||||||
*
|
*
|
||||||
* Messages can only arrive if the plugin is enabled and connected.
|
* Messages can only arrive if the plugin is enabled and connected.
|
||||||
* For background plugins messages will be batched and arrive the next time the plugin is connected.
|
* For background plugins messages will be batched and arrive the next time the plugin is connected.
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onMessage<Event extends keyof Events>(
|
onMessage<Event extends keyof Events>(
|
||||||
event: Event,
|
event: Event,
|
||||||
callback: (params: Events[Event]) => void,
|
callback: (params: Events[Event]) => void,
|
||||||
): void;
|
): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to all messages arriving from the devices not handled by another listener.
|
* Subscribe to all messages arriving from the devices not handled by another listener.
|
||||||
*
|
*
|
||||||
* This handler is untyped, and onMessage should be favored over using onUnhandledMessage if the event name is known upfront.
|
* This handler is untyped, and onMessage should be favored over using onUnhandledMessage if the event name is known upfront.
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onUnhandledMessage(callback: (event: string, params: any) => void): void;
|
onUnhandledMessage(
|
||||||
|
callback: (event: string, params: any) => void,
|
||||||
|
): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a message to the connected client
|
* Send a message to the connected client
|
||||||
@@ -192,10 +202,18 @@ export class SandyPluginInstance extends BasePluginInstance {
|
|||||||
return self.connected.get();
|
return self.connected.get();
|
||||||
},
|
},
|
||||||
onConnect: (cb) => {
|
onConnect: (cb) => {
|
||||||
this.events.on('connect', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('connect', cbWrapped);
|
||||||
|
return () => {
|
||||||
|
this.events.off('connect', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
onDisconnect: (cb) => {
|
onDisconnect: (cb) => {
|
||||||
this.events.on('disconnect', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('disconnect', cbWrapped);
|
||||||
|
return () => {
|
||||||
|
this.events.off('disconnect', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
send: async (method, params) => {
|
send: async (method, params) => {
|
||||||
this.assertConnected();
|
this.assertConnected();
|
||||||
@@ -207,10 +225,19 @@ export class SandyPluginInstance extends BasePluginInstance {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
onMessage: (event, cb) => {
|
onMessage: (event, cb) => {
|
||||||
this.events.on(`event-${event.toString()}`, batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
const eventName = `event-${event.toString()}`;
|
||||||
|
this.events.on(eventName, cbWrapped);
|
||||||
|
return () => {
|
||||||
|
this.events.off(eventName, cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
onUnhandledMessage: (cb) => {
|
onUnhandledMessage: (cb) => {
|
||||||
this.events.on('unhandled-event', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('unhandled-event', cbWrapped);
|
||||||
|
return () => {
|
||||||
|
this.events.off('unhandled-event', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
supportsMethod: async (method) => {
|
supportsMethod: async (method) => {
|
||||||
return await realClient.supportsMethod(
|
return await realClient.supportsMethod(
|
||||||
|
|||||||
@@ -46,18 +46,24 @@ export interface BasePluginClient<
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* the onActivate event is fired whenever the plugin is actived in the UI
|
* the onActivate event is fired whenever the plugin is actived in the UI
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onActivate(cb: () => void): void;
|
onActivate(cb: () => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The counterpart of the `onActivate` handler.
|
* The counterpart of the `onActivate` handler.
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onDeactivate(cb: () => void): void;
|
onDeactivate(cb: () => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when this plugin is opened through a deeplink
|
* Triggered when this plugin is opened through a deeplink
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onDeepLink(cb: (deepLink: unknown) => void): void;
|
onDeepLink(cb: (deepLink: unknown) => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when the current plugin is being exported and should create a snapshot of the state exported.
|
* Triggered when the current plugin is being exported and should create a snapshot of the state exported.
|
||||||
@@ -78,8 +84,10 @@ export interface BasePluginClient<
|
|||||||
* The `onReady` event is triggered immediately after a plugin has been initialized and any pending state was restored.
|
* The `onReady` event is triggered immediately after a plugin has been initialized and any pending state was restored.
|
||||||
* This event fires after `onImport` / the interpretation of any `persist` flags and indicates that the initialization process has finished.
|
* This event fires after `onImport` / the interpretation of any `persist` flags and indicates that the initialization process has finished.
|
||||||
* This event does not signal that the plugin is loaded in the UI yet (see `onActivated`) and does fire before deeplinks (see `onDeepLink`) are handled.
|
* This event does not signal that the plugin is loaded in the UI yet (see `onActivated`) and does fire before deeplinks (see `onDeepLink`) are handled.
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onReady(handler: () => void): void;
|
onReady(handler: () => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register menu entries in the Flipper toolbar
|
* Register menu entries in the Flipper toolbar
|
||||||
@@ -141,14 +149,18 @@ export interface BasePluginClient<
|
|||||||
* You should send messages to the server add-on only after it connects.
|
* You should send messages to the server add-on only after it connects.
|
||||||
* Do not forget to stop all communication when the add-on stops.
|
* Do not forget to stop all communication when the add-on stops.
|
||||||
* See `onServerAddStop`.
|
* See `onServerAddStop`.
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onServerAddOnStart(callback: () => void): void;
|
onServerAddOnStart(callback: () => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when a server add-on stops.
|
* Triggered when a server add-on stops.
|
||||||
* You should stop all communication with the server add-on when the add-on stops.
|
* You should stop all communication with the server add-on when the add-on stops.
|
||||||
|
*
|
||||||
|
* @returns an unsubscribe callback
|
||||||
*/
|
*/
|
||||||
onServerAddOnStop(callback: () => void): void;
|
onServerAddOnStop(callback: () => void): () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to a specific event arriving from the server add-on.
|
* Subscribe to a specific event arriving from the server add-on.
|
||||||
@@ -333,13 +345,25 @@ export abstract class BasePluginInstance {
|
|||||||
pluginKey: this.pluginKey,
|
pluginKey: this.pluginKey,
|
||||||
device: this.device,
|
device: this.device,
|
||||||
onActivate: (cb) => {
|
onActivate: (cb) => {
|
||||||
this.events.on('activate', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('activate', cbWrapped);
|
||||||
|
return () => {
|
||||||
|
this.events.off('activate', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
onDeactivate: (cb) => {
|
onDeactivate: (cb) => {
|
||||||
|
const cbWrapped = batched(cb);
|
||||||
this.events.on('deactivate', batched(cb));
|
this.events.on('deactivate', batched(cb));
|
||||||
|
return () => {
|
||||||
|
this.events.off('deactivate', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
onDeepLink: (cb) => {
|
onDeepLink: (cb) => {
|
||||||
this.events.on('deeplink', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('deeplink', cbWrapped);
|
||||||
|
return () => {
|
||||||
|
this.events.off('deeplink', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
onDestroy: (cb) => {
|
onDestroy: (cb) => {
|
||||||
this.events.on('destroy', batched(cb));
|
this.events.on('destroy', batched(cb));
|
||||||
@@ -357,7 +381,11 @@ export abstract class BasePluginInstance {
|
|||||||
this.importHandler = cb;
|
this.importHandler = cb;
|
||||||
},
|
},
|
||||||
onReady: (cb) => {
|
onReady: (cb) => {
|
||||||
this.events.on('ready', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('ready', cbWrapped);
|
||||||
|
return () => {
|
||||||
|
this.events.off('ready', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
addMenuEntry: (...entries) => {
|
addMenuEntry: (...entries) => {
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
@@ -401,16 +429,24 @@ export abstract class BasePluginInstance {
|
|||||||
},
|
},
|
||||||
logger: this.flipperLib.logger,
|
logger: this.flipperLib.logger,
|
||||||
onServerAddOnStart: (cb) => {
|
onServerAddOnStart: (cb) => {
|
||||||
this.events.on('serverAddOnStart', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('serverAddOnStart', cbWrapped);
|
||||||
if (this.serverAddOnStarted) {
|
if (this.serverAddOnStarted) {
|
||||||
batched(cb)();
|
cbWrapped();
|
||||||
}
|
}
|
||||||
|
return () => {
|
||||||
|
this.events.off('serverAddOnStart', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
onServerAddOnStop: (cb) => {
|
onServerAddOnStop: (cb) => {
|
||||||
this.events.on('serverAddOnStop', batched(cb));
|
const cbWrapped = batched(cb);
|
||||||
|
this.events.on('serverAddOnStop', cbWrapped);
|
||||||
if (this.serverAddOnStopped) {
|
if (this.serverAddOnStopped) {
|
||||||
batched(cb)();
|
cbWrapped();
|
||||||
}
|
}
|
||||||
|
return () => {
|
||||||
|
this.events.off('serverAddOnStop', cbWrapped);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
sendToServerAddOn: (method, params) =>
|
sendToServerAddOn: (method, params) =>
|
||||||
this.serverAddOnControls.sendMessage(
|
this.serverAddOnControls.sendMessage(
|
||||||
|
|||||||
Reference in New Issue
Block a user