66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import type { Runtime } from "webextension-polyfill";
|
|
|
|
export interface commandFunction {
|
|
args: any;
|
|
return: any;
|
|
}
|
|
|
|
export interface commandList {
|
|
[functionName: string]: commandFunction;
|
|
}
|
|
|
|
interface commandMessage<T extends commandList, K extends keyof T> {
|
|
name: K;
|
|
args: T[K]["args"];
|
|
}
|
|
|
|
declare type listener<T extends commandList, K extends keyof T> = (
|
|
args: T[K]["args"],
|
|
s?: Runtime.MessageSender
|
|
) => Promise<T[K]["return"]> | T[K]["return"];
|
|
|
|
export abstract class Communicator<
|
|
RecvCommands extends commandList,
|
|
SendCommands extends commandList
|
|
> {
|
|
private listeners = new Map<
|
|
keyof RecvCommands,
|
|
listener<RecvCommands, keyof RecvCommands>
|
|
>();
|
|
|
|
abstract runCommand<K extends keyof SendCommands>(
|
|
command: K,
|
|
args: SendCommands[K]["args"],
|
|
...rest: unknown[]
|
|
): Promise<SendCommands[K]["return"]>;
|
|
|
|
addMessageListener<K extends keyof RecvCommands>(
|
|
command: K,
|
|
callback: listener<RecvCommands, K>
|
|
) {
|
|
this.listeners.set(command, callback as any);
|
|
}
|
|
|
|
protected getCommandMessage<K extends keyof RecvCommands>(
|
|
command: K,
|
|
...args: RecvCommands[K]["args"]
|
|
): commandMessage<RecvCommands, K> {
|
|
return { name: command, args: args };
|
|
}
|
|
|
|
protected onMessage<K extends keyof RecvCommands>(
|
|
m: commandMessage<RecvCommands, K>,
|
|
s?: Runtime.MessageSender
|
|
) {
|
|
const listener = this.listeners.get(m.name);
|
|
const args: [
|
|
RecvCommands[keyof RecvCommands]["args"],
|
|
Runtime.MessageSender
|
|
] = m.args;
|
|
if (args[0] === undefined) args.pop();
|
|
args.push(s);
|
|
if (listener) return listener(...args);
|
|
}
|
|
}
|