{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * libimagequant WASM - Promise-based API for PNG image quantization in browsers\n *\n * This module provides a high-level, promise-based interface for the libimagequant\n * image quantization library running in a Web Worker with WASM.\n */\n\nexport interface QuantizationOptions {\n  /** Speed vs quality trade-off (1-10, lower = better quality) */\n  speed?: number;\n  /** Quality settings */\n  quality?: {\n    min: number;\n    target: number;\n  };\n  /** Maximum colors in palette (2-256) */\n  maxColors?: number;\n  /** Dithering level (0.0-1.0) */\n  dithering?: number;\n  /** Posterization level (0-4) */\n  posterization?: number;\n}\n\nexport interface QuantizationResult {\n  /** Color palette array */\n  palette: number[][];\n  /** PNG bytes (Uint8Array) - quantized image as indexed PNG */\n  pngBytes: Uint8Array;\n  /** ImageData object - quantized image as RGBA data */\n  imageData: ImageData;\n  /** Achieved quality (0-1) */\n  quality: number;\n  /** Number of colors in palette */\n  paletteLength: number;\n  /** Image width */\n  width: number;\n  /** Image height */\n  height: number;\n}\n\nexport interface LibImageQuantOptions {\n  /** Custom path to worker.js file */\n  workerUrl?: string;\n  /** Custom path to WASM module directory (should contain libimagequant_wasm.js) */\n  wasmUrl?: string;\n  /** Timeout for worker initialization in milliseconds (default: 10000) */\n  initTimeout?: number;\n  /** Timeout for individual operations in milliseconds (default: 30000) */\n  operationTimeout?: number;\n}\n\nexport default class LibImageQuant {\n  private worker: Worker | null = null;\n  private isReady: boolean = false;\n  private pendingOperations = new Map<\n    number,\n    { resolve: (value: any) => void; reject: (reason?: any) => void }\n  >();\n  private operationCounter: number = 0;\n  private workerUrl?: string;\n  private wasmUrl?: string;\n  private initTimeout: number;\n  private operationTimeout: number;\n  private initPromise: Promise<void>;\n\n  constructor(options: LibImageQuantOptions = {}) {\n    this.workerUrl = options.workerUrl;\n    this.wasmUrl = options.wasmUrl;\n    this.initTimeout = options.initTimeout || 10000;\n    this.operationTimeout = options.operationTimeout || 30000;\n    this.initPromise = this.initialize();\n  }\n\n  /**\n   * Initialize the worker and WASM module\n   */\n  private async initialize(): Promise<void> {\n    if (this.isReady) return;\n\n    return new Promise((resolve, reject) => {\n      try {\n        let workerUrl;\n        if (this.workerUrl) {\n          workerUrl = this.workerUrl;\n        } else {\n          workerUrl = new URL('./worker', import.meta.url).href;\n        }\n        this.worker = new Worker(workerUrl, { type: \"module\" });\n\n        this.worker.onmessage = (e) => {\n          const { type, id, success, result, error } = e.data;\n\n          if (type === \"ready\") {\n            // Send WASM URL configuration to worker if provided\n            if (this.wasmUrl) {\n              this.worker?.postMessage({\n                type: \"configure\",\n                wasmUrl: this.wasmUrl,\n              });\n            }\n            this.isReady = true;\n            resolve();\n            return;\n          }\n\n          const operation = this.pendingOperations.get(id);\n          if (operation) {\n            this.pendingOperations.delete(id);\n\n            if (success) {\n              operation.resolve(result);\n            } else {\n              operation.reject(new Error(error));\n            }\n          }\n        };\n\n        this.worker.onerror = (error) => {\n          reject(new Error(`Worker error: ${error.message}`));\n        };\n\n        // Set a timeout for initialization\n        setTimeout(() => {\n          if (!this.isReady) {\n            reject(new Error(\"Worker initialization timeout\"));\n          }\n        }, this.initTimeout);\n      } catch (error) {\n        reject(error);\n      }\n    });\n  }\n\n  /**\n   * Send a message to the worker and return a promise\n   */\n  private async sendMessage(action: string, data: any): Promise<any> {\n    await this.initPromise;\n\n    return new Promise((resolve, reject) => {\n      const id = ++this.operationCounter;\n\n      this.pendingOperations.set(id, { resolve, reject });\n\n      this.worker?.postMessage({\n        id,\n        action,\n        data,\n      });\n\n      // Set a timeout for the operation\n      setTimeout(() => {\n        if (this.pendingOperations.has(id)) {\n          this.pendingOperations.delete(id);\n          reject(new Error(\"Operation timeout\"));\n        }\n      }, this.operationTimeout);\n    });\n  }\n\n  /**\n   * Quantize a PNG from bytes or Blob\n   */\n  async quantizePng(\n    pngData: Uint8Array | ArrayBuffer | Blob,\n    options: QuantizationOptions = {}\n  ): Promise<QuantizationResult> {\n    let pngBytes: Uint8Array;\n\n    if (pngData instanceof Blob) {\n      const arrayBuffer = await pngData.arrayBuffer();\n      pngBytes = new Uint8Array(arrayBuffer);\n    } else if (pngData instanceof ArrayBuffer) {\n      pngBytes = new Uint8Array(pngData);\n    } else {\n      pngBytes = pngData;\n    }\n\n    return this.sendMessage(\"quantize_png\", {\n      pngBytes: Array.from(pngBytes),\n      options,\n    });\n  }\n\n  /**\n   * Quantize from ImageData and return as PNG bytes or ImageData\n   */\n  async quantizeImageData(\n    imageData: ImageData,\n    options: QuantizationOptions = {}\n  ): Promise<QuantizationResult> {\n    return this.sendMessage(\"quantize_imagedata\", {\n      imageData: Array.from(imageData.data),\n      width: imageData.width,\n      height: imageData.height,\n      options,\n    });\n  }\n\n  /**\n   * Terminate the worker and clean up resources\n   */\n  dispose() {\n    if (this.worker) {\n      this.worker.terminate();\n      this.worker = null;\n    }\n\n    this.isReady = false;\n    this.pendingOperations.clear();\n  }\n}\n"],"names":["constructor","options","this","worker","isReady","pendingOperations","Map","operationCounter","workerUrl","wasmUrl","initTimeout","operationTimeout","initPromise","initialize","Promise","resolve","reject","URL","document","require","pathToFileURL","__filename","href","_documentCurrentScript","tagName","toUpperCase","src","baseURI","Worker","type","onmessage","e","id","success","result","error","data","postMessage","operation","get","delete","Error","onerror","message","setTimeout","sendMessage","action","set","has","quantizePng","pngData","pngBytes","Blob","arrayBuffer","Uint8Array","ArrayBuffer","Array","from","quantizeImageData","imageData","width","height","dispose","terminate","clear"],"mappings":"2FAmDA,MAcE,WAAAA,CAAYC,EAAgC,IAb5CC,KAAQC,OAAwB,KAChCD,KAAQE,SAAmB,EAC3BF,KAAQG,sBAAwBC,IAIhCJ,KAAQK,iBAA2B,EAQjCL,KAAKM,UAAYP,EAAQO,UACzBN,KAAKO,QAAUR,EAAQQ,QACvBP,KAAKQ,YAAcT,EAAQS,aAAe,IAC1CR,KAAKS,iBAAmBV,EAAQU,kBAAoB,IACpDT,KAAKU,YAAcV,KAAKW,YAC1B,CAKA,gBAAcA,GACZ,IAAIX,KAAKE,QAET,OAAO,IAAIU,QAAQ,CAACC,EAASC,KAC3B,IACE,IAAIR,EAEFA,EADEN,KAAKM,UACKN,KAAKM,UAEL,IAAAS,IAAA,kmMAAA,oBAAAC,SAAAC,QAAA,OAAAC,cAAAC,YAAAC,KAAAC,GAAA,WAAAA,EAAAC,QAAAC,eAAAF,EAAAG,KAAA,IAAAT,IAAA,YAAAC,SAAAS,SAAAL,MAAqCA,KAEnDpB,KAAKC,OAAS,IAAIyB,OAAOpB,EAAW,CAAEqB,KAAM,WAE5C3B,KAAKC,OAAO2B,UAAaC,IACvB,MAAMF,KAAEA,EAAAG,GAAMA,EAAAC,QAAIA,SAASC,EAAAC,MAAQA,GAAUJ,EAAEK,KAE/C,GAAa,UAATP,EAUF,OARI3B,KAAKO,SACPP,KAAKC,QAAQkC,YAAY,CACvBR,KAAM,YACNpB,QAASP,KAAKO,UAGlBP,KAAKE,SAAU,OACfW,IAIF,MAAMuB,EAAYpC,KAAKG,kBAAkBkC,IAAIP,GACzCM,IACFpC,KAAKG,kBAAkBmC,OAAOR,GAE1BC,EACFK,EAAUvB,QAAQmB,GAElBI,EAAUtB,OAAO,IAAIyB,MAAMN,MAKjCjC,KAAKC,OAAOuC,QAAWP,IACrBnB,EAAO,IAAIyB,MAAM,iBAAiBN,EAAMQ,aAI1CC,WAAW,KACJ1C,KAAKE,SACRY,EAAO,IAAIyB,MAAM,mCAElBvC,KAAKQ,YACV,OAASyB,GACPnB,EAAOmB,EACT,GAEJ,CAKA,iBAAcU,CAAYC,EAAgBV,GAGxC,aAFMlC,KAAKU,YAEJ,IAAIE,QAAQ,CAACC,EAASC,KAC3B,MAAMgB,IAAO9B,KAAKK,iBAElBL,KAAKG,kBAAkB0C,IAAIf,EAAI,CAAEjB,UAASC,WAE1Cd,KAAKC,QAAQkC,YAAY,CACvBL,KACAc,SACAV,SAIFQ,WAAW,KACL1C,KAAKG,kBAAkB2C,IAAIhB,KAC7B9B,KAAKG,kBAAkBmC,OAAOR,GAC9BhB,EAAO,IAAIyB,MAAM,wBAElBvC,KAAKS,mBAEZ,CAKA,iBAAMsC,CACJC,EACAjD,EAA+B,IAE/B,IAAIkD,EAEJ,GAAID,aAAmBE,KAAM,CAC3B,MAAMC,QAAoBH,EAAQG,cAClCF,EAAW,IAAIG,WAAWD,EAC5B,MACEF,EADSD,aAAmBK,YACjB,IAAID,WAAWJ,GAEfA,EAGb,OAAOhD,KAAK2C,YAAY,eAAgB,CACtCM,SAAUK,MAAMC,KAAKN,GACrBlD,WAEJ,CAKA,uBAAMyD,CACJC,EACA1D,EAA+B,IAE/B,OAAOC,KAAK2C,YAAY,qBAAsB,CAC5Cc,UAAWH,MAAMC,KAAKE,EAAUvB,MAChCwB,MAAOD,EAAUC,MACjBC,OAAQF,EAAUE,OAClB5D,WAEJ,CAKA,OAAA6D,GACM5D,KAAKC,SACPD,KAAKC,OAAO4D,YACZ7D,KAAKC,OAAS,MAGhBD,KAAKE,SAAU,EACfF,KAAKG,kBAAkB2D,OACzB"}