TelegramPWA/src/util/createWorkerInterface.ts
Alexander Zinchuk 3afcde3217 Initial commit
2021-04-09 14:11:51 +03:00

100 lines
2.5 KiB
TypeScript

import { CancellableCallback, OriginMessageEvent, WorkerMessageData } from './WorkerConnector';
import { DEBUG } from '../config';
declare const self: WorkerGlobalScope;
handleErrors();
const callbackState = new Map<string, CancellableCallback>();
export default function createInterface(api: Record<string, Function>) {
onmessage = async (message: OriginMessageEvent) => {
const { data } = message;
switch (data.type) {
case 'callMethod': {
const { messageId, name, args } = data;
try {
if (messageId) {
const callback = (...callbackArgs: any[]) => {
const lastArg = callbackArgs[callbackArgs.length - 1];
sendToOrigin({
type: 'methodCallback',
messageId,
callbackArgs,
}, lastArg instanceof ArrayBuffer ? [lastArg] : undefined);
};
callbackState.set(messageId, callback);
args.push(callback as never);
}
const [response, arrayBuffers] = (await api[name](...args)) || [];
if (messageId) {
sendToOrigin(
{
type: 'methodResponse',
messageId,
response,
},
arrayBuffers,
);
}
} catch (error) {
if (DEBUG) {
// eslint-disable-next-line no-console
console.error(error);
}
if (messageId) {
sendToOrigin({
type: 'methodResponse',
messageId,
error: { message: error.message },
});
}
}
if (messageId) {
callbackState.delete(messageId);
}
break;
}
case 'cancelProgress': {
const callback = callbackState.get(data.messageId);
if (callback) {
callback.isCanceled = true;
}
break;
}
}
};
}
function handleErrors() {
self.onerror = (err) => {
// eslint-disable-next-line no-console
console.error(err);
sendToOrigin({ type: 'unhandledError', error: { message: 'Uncaught exception in worker' } });
};
self.addEventListener('unhandledrejection', (err) => {
// eslint-disable-next-line no-console
console.error(err);
sendToOrigin({ type: 'unhandledError', error: { message: 'Uncaught rejection in worker' } });
});
}
function sendToOrigin(data: WorkerMessageData, arrayBuffers?: ArrayBuffer[]) {
if (arrayBuffers) {
postMessage(data, arrayBuffers);
} else {
postMessage(data);
}
}