type magic

This commit is contained in:
Robin Appelman 2022-09-04 16:09:14 +02:00
commit 75fe6573ba

View file

@ -2,8 +2,6 @@ import {SearchFilter} from "./search";
import {Packet} from "./parser"; import {Packet} from "./parser";
import {Header} from "./header"; import {Header} from "./header";
import {PacketMeta} from "./App"; import {PacketMeta} from "./App";
import {Simulate} from "react-dom/test-utils";
import progress = Simulate.progress;
export type RequestMessageData = { type: "data", sequence?: number, data: ArrayBuffer } export type RequestMessageData = { type: "data", sequence?: number, data: ArrayBuffer }
| { type: "get", sequence?: number, packet: number } | { type: "get", sequence?: number, packet: number }
@ -15,12 +13,14 @@ export type ResponseMessageData = { type: "error", sequence: number, e: Error }
| { type: "done", sequence: number, packets: PacketMeta[], header: Header, prop_names: { identifier: string, table: string, prop: string }[], class_names: { identifier: number, name: string }[] } | { type: "done", sequence: number, packets: PacketMeta[], header: Header, prop_names: { identifier: string, table: string, prop: string }[], class_names: { identifier: number, name: string }[] }
| { type: "search_result", sequence: number, matches: number[] }; | { type: "search_result", sequence: number, matches: number[] };
const ResponseTypeMap = { type ResponseTypeMap = {
"search": "search_result", "search": "search_result",
"get": "packet", "get": "packet",
"data": "done", "data": "done",
} }
type ResponseTypeFor<T extends RequestMessageData> = {type: ResponseTypeMap[T['type']]} & ResponseMessageData
export interface ParsedDemo { export interface ParsedDemo {
packets: PacketMeta[], packets: PacketMeta[],
header: Header, header: Header,
@ -30,7 +30,6 @@ export interface ParsedDemo {
export class DemoWorker { export class DemoWorker {
worker: Worker worker: Worker
packets: PacketMeta[] = [];
lastSequence = 0; lastSequence = 0;
callbacks: Map<number, [(_: ResponseMessageData) => void, (_: Error) => void]>; callbacks: Map<number, [(_: ResponseMessageData) => void, (_: Error) => void]>;
onProgress: null | ((progress: number) => void) = null; onProgress: null | ((progress: number) => void) = null;
@ -56,12 +55,12 @@ export class DemoWorker {
}); });
} }
postMessage(message: RequestMessageData, transfer: Transferable[] = []): Promise<ResponseMessageData> { postMessage<T extends RequestMessageData>(message: T, transfer: Transferable[] = []): Promise<ResponseTypeFor<T>> {
const sequence = this.lastSequence++; const sequence = this.lastSequence++;
message.sequence = sequence; message.sequence = sequence;
this.worker.postMessage(message, transfer); this.worker.postMessage(message, transfer);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.callbacks.set(sequence, [resolve, reject]); this.callbacks.set(sequence, [resolve as (_: ResponseMessageData) => void, reject]);
}); });
} }
@ -72,11 +71,7 @@ export class DemoWorker {
data, data,
}, [data]); }, [data]);
this.onProgress = null; this.onProgress = null;
if (response.type === "done") {
return response; return response;
} else {
throw new Error("Invalid response type");
}
} }
public async get(packet: number): Promise<Packet> { public async get(packet: number): Promise<Packet> {
@ -84,11 +79,7 @@ export class DemoWorker {
type: "get", type: "get",
packet, packet,
}); });
if (response.type === "packet") {
return response.packet; return response.packet;
} else {
throw new Error("Invalid response type");
}
} }
public async search(filter: SearchFilter): Promise<number[]> { public async search(filter: SearchFilter): Promise<number[]> {
@ -96,10 +87,6 @@ export class DemoWorker {
type: "search", type: "search",
filter, filter,
}); });
if (response.type === "search_result") {
return response.matches; return response.matches;
} else {
throw new Error("Invalid response type");
}
} }
} }