import { S as Servicer } from "./servicer.js";
import { M as MessageType, B as BatchMessage } from "./index38.js";
import { c as clone } from "./clone.js";
import "./index.js";
import "vue";
function WorkerWrapper() {
  return new Worker("/assets/servicer.worker.61a749ce.js", {
    "type": "module"
  });
}
function isMessageHasReturn(message) {
  const [target, action] = message.split(".").map((s) => s.toUpperCase());
  if (!action || !target) {
    return false;
  }
  return action.includes("CREATE") || action.includes("GET") || target.includes("FILE");
}
class WorkerServicer extends Servicer {
  constructor(config) {
    super();
    this.batchMode = false;
    this.batchCommands = [];
    this.batchTransfer = [];
    this.messageId = 0;
    this.promiseMap = /* @__PURE__ */ new Map();
    this.worker = new WorkerWrapper();
    this.worker.onmessage = this.onMessage.bind(this);
    this.init(config);
  }
  init(config) {
    this.postMessage(-1, MessageType.init, [config]);
  }
  createPromise() {
    const messageId = this.messageId;
    this.messageId += 1;
    const promise = new Promise((resolve, reject) => {
      this.promiseMap.set(messageId, { resolve, reject });
    });
    return [messageId, promise];
  }
  onMessage(message) {
    const { id, type, data, error } = message.data;
    const { listenerMap, promiseMap } = this;
    if (listenerMap.has(type)) {
      const listeners = listenerMap.get(type);
      listeners && listeners.forEach((listener) => {
        listener(data);
      });
    }
    if (promiseMap.has(id)) {
      const promise = promiseMap.get(id);
      promiseMap.delete(id);
      if (error) {
        promise.reject(new Error(error));
      } else {
        promise.resolve(data);
      }
    }
  }
  postMessage(id, messageType, data, transfer = []) {
    this.worker.postMessage({
      id,
      type: messageType,
      data
    }, transfer);
  }
  do(messageType, data, transfers) {
    if (this.batchMode && !isMessageHasReturn(messageType)) {
      this.batchCommands.push({ messageType, data });
      if (transfers) {
        transfers.forEach((transfer) => {
          if (!this.batchTransfer.includes(transfer)) {
            this.batchTransfer.push(transfer);
          }
        });
      }
      return Promise.resolve();
    } else {
      const [messageId, promise] = this.createPromise();
      this.postMessage(messageId, messageType, data, transfers);
      return promise;
    }
  }
  async batchDo(func) {
    const [messageId, promise] = this.createPromise();
    this.batchMode = true;
    await func();
    const batchCommands = clone(this.batchCommands);
    const batchTransfer = clone(this.batchTransfer);
    this.batchCommands = [];
    this.batchTransfer = [];
    this.postMessage(messageId, BatchMessage, batchCommands, batchTransfer);
    await promise;
    this.batchMode = false;
  }
  destory() {
    this.worker.terminate();
  }
}
export { WorkerServicer };
