0.1.1Updated 7 months ago
import { type Entity } from "@infinity-beyond/modules/entity.ts";

interface HangingPromise {
  resolve: (...args: any[]) => void
  reject: (...args: any[]) => void
}

export class EntityWorker {
  private socket: WebSocket
  private static resolvers: Record<string, HangingPromise> = {}
  readonly uuid: string;

  constructor(uuid: string, socket: WebSocket, entity: typeof Entity) {
    this.uuid = uuid;
    this.socket = socket;

    this.socket.addEventListener('message', (ev) => {
      try {
        EntityWorker.receive(JSON.parse(ev.data));
      } catch(e: any) {
        console.error(`Could not parse incoming message! [${this.uuid}]`, e.message);
      }
    });

    this.socket.addEventListener('close', () => {
      console.warn(`♾️X Worker lost! [${uuid}]`);
      entity.__RemoveWorker(this);
    })

    console.log(`♾️  Worker initialized! [${this.uuid}]\n   Current workers: ${entity.__worker_count + 1}`);
  }

  static receive(data: I_ProcessorResponse) {
    const id = data.id;

    if(data.success) {
      this.resolvers[id].resolve(data.data);
    } else {
      this.resolvers[id].reject(data.error ?? data.message);
    }

    delete this.resolvers[id];
  }

  async dispatch(request: I_ProcessorRequest) {
    return new Promise((resolve, reject) => {
      this.socket.send(JSON.stringify(request));
      EntityWorker.resolvers[request.id] = { reject, resolve };
    })
  }
}