Add onUnhandledMesssage handler

Summary: This diff adds the `client.onUnhandledMessage` handler, to be able to handle messages for which we don't know the names upfront. Some existing plugins that only send one kind of message can benefit from this, as can generic plugins, like the createTablePlugin

Reviewed By: passy

Differential Revision: D24949453

fbshipit-source-id: 0fed81e28aee350632c09ee3bb834f306dc8b100
This commit is contained in:
Michel Weststrate
2020-11-16 13:08:05 -08:00
committed by Facebook GitHub Bot
parent 9a3cd63d55
commit 33e527f39a
3 changed files with 31 additions and 1 deletions

View File

@@ -36,6 +36,7 @@ export function plugin(client: PluginClient<Events, Methods>) {
persist: 'counter',
},
);
const unhandledMessages = createState<any[]>([]);
client.onConnect(connectStub);
client.onDisconnect(disconnectStub);
@@ -47,6 +48,11 @@ export function plugin(client: PluginClient<Events, Methods>) {
draft.count += delta;
});
});
client.onUnhandledMessage((event, params) => {
unhandledMessages.update((draft) => {
draft.push({event, params});
});
});
function _unused_JustTypeChecks() {
// @ts-expect-error Argument of type '"bla"' is not assignable
@@ -77,6 +83,7 @@ export function plugin(client: PluginClient<Events, Methods>) {
disconnectStub,
getCurrentState,
state,
unhandledMessages,
appId: client.appId,
appName: client.appName,
};

View File

@@ -180,6 +180,15 @@ test('a plugin can receive messages', async () => {
},
}
`);
expect(instance.unhandledMessages.get().length).toBe(0);
sendEvent('unhandled' as any, {hello: 'world'});
expect(instance.unhandledMessages.get()).toEqual([
{
event: 'unhandled',
params: {hello: 'world'},
},
]);
});
test('plugins support non-serializable state', async () => {

View File

@@ -63,6 +63,13 @@ export interface PluginClient<
callback: (params: Events[Event]) => void,
): void;
/**
* 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.
*/
onUnhandledMessage(callback: (event: string, params: any) => void): void;
/**
* Send a message to the connected client
*/
@@ -156,6 +163,9 @@ export class SandyPluginInstance extends BasePluginInstance {
onMessage: (event, callback) => {
this.events.on('event-' + event, callback);
},
onUnhandledMessage: (callback) => {
this.events.on('unhandled-event', callback);
},
supportsMethod: async (method) => {
this.assertConnected();
return await realClient.supportsMethod(
@@ -212,7 +222,11 @@ export class SandyPluginInstance extends BasePluginInstance {
receiveMessages(messages: Message[]) {
messages.forEach((message) => {
this.events.emit('event-' + message.method, message.params);
if (this.events.listenerCount('event-' + message.method) > 0) {
this.events.emit('event-' + message.method, message.params);
} else {
this.events.emit('unhandled-event', message.method, message.params);
}
});
}