{"version":3,"file":"image-resize.d.ts","sourceRoot":"","sources":["../../src/utils/image-resize.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAwB,MAAM,wBAAwB,CAAC;AAE1G,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AA0E/E;;;;;;GAMG;AACH,wBAAsB,WAAW,CAChC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqB9B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAO5E","sourcesContent":["import { Worker } from \"node:worker_threads\";\nimport { type ImageResizeOptions, type ResizedImage, resizeImageInProcess } from \"./image-resize-core.ts\";\n\nexport type { ImageResizeOptions, ResizedImage } from \"./image-resize-core.ts\";\n\ninterface ResizeImageWorkerResponse {\n\tresult?: ResizedImage | null;\n\terror?: string;\n}\n\nfunction toTransferableBytes(input: Uint8Array): Uint8Array {\n\t// Transfer detaches the buffer, so transfer a worker-owned copy and leave the\n\t// caller's bytes intact.\n\treturn new Uint8Array(input);\n}\n\nfunction isResizeImageWorkerResponse(value: unknown): value is ResizeImageWorkerResponse {\n\treturn value !== null && typeof value === \"object\";\n}\n\nfunction createResizeWorker(workerSpecifier: string | URL): Worker {\n\treturn new Worker(workerSpecifier);\n}\n\nasync function resizeImageInWorker(\n\tworkerSpecifier: string | URL,\n\tinputBytes: Uint8Array,\n\tmimeType: string,\n\toptions?: ImageResizeOptions,\n): Promise {\n\tconst worker = createResizeWorker(workerSpecifier);\n\ttry {\n\t\tconst inputBytesForWorker = toTransferableBytes(inputBytes);\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tlet settled = false;\n\t\t\tconst settle = (result: ResizedImage | null): void => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tresolve(result);\n\t\t\t};\n\t\t\tconst fail = (error: Error): void => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\treject(error);\n\t\t\t};\n\n\t\t\tworker.once(\"message\", (message: unknown) => {\n\t\t\t\tif (!isResizeImageWorkerResponse(message)) {\n\t\t\t\t\tfail(new Error(\"Invalid image resize worker response\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.error) {\n\t\t\t\t\tfail(new Error(message.error));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(message.result ?? null);\n\t\t\t});\n\t\t\tworker.once(\"error\", fail);\n\t\t\tworker.once(\"exit\", (code) => {\n\t\t\t\tif (!settled) {\n\t\t\t\t\tfail(new Error(`Image resize worker exited with code ${code}`));\n\t\t\t\t}\n\t\t\t});\n\t\t\tworker.postMessage(\n\t\t\t\t{\n\t\t\t\t\tinputBytes: inputBytesForWorker,\n\t\t\t\t\tmimeType,\n\t\t\t\t\toptions,\n\t\t\t\t},\n\t\t\t\t[inputBytesForWorker.buffer],\n\t\t\t);\n\t\t});\n\t} finally {\n\t\tvoid worker.terminate().catch(() => undefined);\n\t}\n}\n\n/**\n * Resize an image to fit within the specified max dimensions and encoded file size.\n * Runs Photon in a worker thread so WASM decoding, resizing, and encoding do not\n * block the TUI event loop. If the worker cannot be loaded (for example in some\n * Bun compiled executable layouts), fall back to in-process resizing so image\n * reads still work.\n */\nexport async function resizeImage(\n\tinputBytes: Uint8Array,\n\tmimeType: string,\n\toptions?: ImageResizeOptions,\n): Promise {\n\tconst isTypeScriptRuntime = import.meta.url.endsWith(\".ts\");\n\tconst workerUrl = new URL(\n\t\tisTypeScriptRuntime ? \"./image-resize-worker.ts\" : \"./image-resize-worker.js\",\n\t\timport.meta.url,\n\t);\n\n\t// Bun compiled executables resolve worker entrypoints by string path, not via\n\t// new URL(..., import.meta.url). Try the string path first under Bun so the\n\t// release binary uses the embedded worker instead of falling back in-process.\n\tif (typeof process.versions.bun === \"string\") {\n\t\ttry {\n\t\t\treturn await resizeImageInWorker(\"./src/utils/image-resize-worker.ts\", inputBytes, mimeType, options);\n\t\t} catch {}\n\t}\n\n\ttry {\n\t\treturn await resizeImageInWorker(workerUrl, inputBytes, mimeType, options);\n\t} catch {\n\t\treturn resizeImageInProcess(inputBytes, mimeType, options);\n\t}\n}\n\n/**\n * Format a dimension note for resized images.\n * This helps the model understand the coordinate mapping.\n */\nexport function formatDimensionNote(result: ResizedImage): string | undefined {\n\tif (!result.wasResized) {\n\t\treturn undefined;\n\t}\n\n\tconst scale = result.originalWidth / result.width;\n\treturn `[Image: original ${result.originalWidth}x${result.originalHeight}, displayed at ${result.width}x${result.height}. Multiply coordinates by ${scale.toFixed(2)} to map to original image.]`;\n}\n"]}