summaryrefslogtreecommitdiffstats
path: root/src/renderer/util.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/util.ts')
-rw-r--r--src/renderer/util.ts84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/renderer/util.ts b/src/renderer/util.ts
new file mode 100644
index 0000000..cea404b
--- /dev/null
+++ b/src/renderer/util.ts
@@ -0,0 +1,84 @@
+export function recordToMap<T>(r: Record<string, T>): Map<string, T> {
+ const ret = new Map();
+
+ for (const k of Object.keys(r))
+ ret.set(k, r[k]);
+
+ return ret;
+}
+
+export function mapValues<K, V1, V2>(f: (v: V1) => V2, map: Map<K, V1>): Map<K, V2> {
+ const ret: Map<K, V2> = new Map();
+
+ for (const [k, v] of map)
+ ret.set(k, f(v));
+
+ return ret;
+}
+
+export async function mapValuesAsync<K, V1, V2>(f: (v: V1) => Promise<V2>, map: Map<K, V1>): Promise<Map<K, V2>> {
+ const ret: Map<K, V2> = new Map();
+
+ for (const [k, v] of mapValues(f, map))
+ ret.set(k, await v);
+
+ return ret;
+}
+
+export function nextPowerOf2(n: number): number {
+ let i = 1;
+
+ while (i < n)
+ i *= 2;
+
+ return i;
+}
+
+export class Listenable<T extends any[]> {
+ private readonly listeners: Array<(...args: T) => void> = [];
+
+ public addListener(listener: (...args: T) => void): void {
+ this.listeners.push(listener);
+ }
+
+ protected runListeners(...args: T): void {
+ this.listeners.forEach((l) => l(...args));
+ }
+}
+
+export function get(url: string): Promise<XMLHttpRequest> {
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+
+ const handleError = () => {
+ if (xhr.readyState !== xhr.DONE) {
+ reject(new Error('HTTP request ended in state ' + xhr.readyState));
+ return;
+ }
+
+ reject(new Error('HTTP request returned status ' + xhr.status));
+ };
+
+ xhr.addEventListener('error', handleError);
+
+ xhr.addEventListener('load', () => {
+ if (xhr.readyState !== xhr.DONE || xhr.status !== 200) {
+ handleError();
+ return;
+ }
+
+ resolve(xhr);
+ });
+
+ xhr.open('GET', url, true);
+ xhr.send();
+ });
+}
+
+export async function getJSON(url: string): Promise<any> {
+ return JSON.parse((await get(url)).responseText);
+}
+
+export function nextAnimationFrame(): Promise<DOMHighResTimeStamp> {
+ return new Promise((resolve) => window.requestAnimationFrame(resolve));
+}