comlink-worker.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import { ensureElectron } from "@/next/electron";
  2. import log, { logToDisk } from "@/next/log";
  3. import { expose, wrap, type Remote } from "comlink";
  4. import { ensureLocalUser } from "../local-user";
  5. export class ComlinkWorker<T extends new () => InstanceType<T>> {
  6. public remote: Promise<Remote<InstanceType<T>>>;
  7. private worker: Worker;
  8. private name: string;
  9. constructor(name: string, worker: Worker) {
  10. this.name = name;
  11. this.worker = worker;
  12. worker.onerror = (event) => {
  13. log.error(
  14. `Got error event from worker: ${JSON.stringify({ event, name })}`,
  15. );
  16. };
  17. log.debug(() => `Initiated web worker ${name}`);
  18. const comlink = wrap<T>(worker);
  19. this.remote = new comlink() as Promise<Remote<InstanceType<T>>>;
  20. expose(workerBridge, worker);
  21. }
  22. public terminate() {
  23. this.worker.terminate();
  24. log.debug(() => `Terminated ${this.name}`);
  25. }
  26. }
  27. /**
  28. * A set of utility functions that we expose to all workers that we create.
  29. *
  30. * Inside the worker's code, this can be accessed by using the sibling
  31. * `workerBridge` object after importing it from `worker-bridge.ts`.
  32. *
  33. * Not all workers need access to all these functions, and this can indeed be
  34. * done in a more fine-grained, per-worker, manner if needed. For now, since it
  35. * is a motley bunch, we just inject them all.
  36. */
  37. const workerBridge = {
  38. // Needed: generally (presumably)
  39. logToDisk,
  40. // Needed by ML worker
  41. getAuthToken: () => ensureLocalUser().then((user) => user.token),
  42. convertToJPEG: (imageData: Uint8Array) =>
  43. ensureElectron().convertToJPEG(imageData),
  44. detectFaces: (input: Float32Array) => ensureElectron().detectFaces(input),
  45. computeFaceEmbeddings: (input: Float32Array) =>
  46. ensureElectron().computeFaceEmbeddings(input),
  47. };
  48. export type WorkerBridge = typeof workerBridge;