signal-desktop/ts/CI.ts

78 lines
1.9 KiB
TypeScript
Raw Normal View History

2021-08-11 19:29:07 +00:00
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { ipcRenderer } from 'electron';
import { explodePromise } from './util/explodePromise';
type ResolveType = (data: unknown) => void;
export const electronRequire = require;
export class CI {
private readonly eventListeners = new Map<string, Array<ResolveType>>();
private readonly completedEvents = new Map<string, Array<unknown>>();
constructor(public readonly deviceName: string) {
ipcRenderer.on('ci:event', (_, event, data) => {
this.handleEvent(event, data);
});
}
public async waitForEvent(event: string): Promise<unknown> {
const pendingCompleted = this.completedEvents.get(event) || [];
const pending = pendingCompleted.shift();
if (pending) {
window.log.info(`CI: resolving pending result for ${event}`, pending);
if (pendingCompleted.length === 0) {
this.completedEvents.delete(event);
}
return pending;
}
window.log.info(`CI: waiting for event ${event}`);
const { resolve, promise } = explodePromise();
let list = this.eventListeners.get(event);
if (!list) {
list = [];
this.eventListeners.set(event, list);
}
list.push(resolve);
return promise;
}
public setProvisioningURL(url: string): void {
this.handleEvent('provisioning-url', url);
}
public handleEvent(event: string, data: unknown): void {
const list = this.eventListeners.get(event) || [];
const resolve = list.shift();
if (resolve) {
if (list.length === 0) {
this.eventListeners.delete(event);
}
window.log.info(`CI: got event ${event} with data`, data);
resolve(data);
return;
}
window.log.info(`CI: postponing event ${event}`);
let resultList = this.completedEvents.get(event);
if (!resultList) {
resultList = [];
this.completedEvents.set(event, resultList);
}
resultList.push(data);
}
}