@wasmedia/wexiftool 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +0,0 @@
1
- "use strict";var N=Object.create;var P=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,V=Object.prototype.hasOwnProperty;var J=(n,t,e)=>t in n?P(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var K=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of z(t))!V.call(n,o)&&o!==e&&P(n,o,{get:()=>t[o],enumerable:!(r=q(t,o))||r.enumerable});return n};var g=(n,t,e)=>(e=n!=null?N(G(n)):{},K(t||!n||!n.__esModule?P(e,"default",{value:n,enumerable:!0}):e,n));var A=(n,t,e)=>J(n,typeof t!="symbol"?t+"":t,e);var S=typeof document<"u"?document.currentScript:null;class b extends Error{constructor(t,e){super(t,e),this.name=new.target.name}}class X extends b{}class Q extends b{constructor(e,r){super(`${e} is locked by another sync access handle (another tab or worker may be using it)`,{cause:r});A(this,"path");this.path=e}}class _ extends b{}class Y extends b{}class Z extends b{}class tt extends b{constructor(e,r){super(`commit() failed after ${e.length} file(s): ${(r==null?void 0:r.message)??String(r)}`,{cause:r});A(this,"committed");this.committed=e}}const E="/wexiftool",et="/opt/perlwasm/bin/exiftool";function rt(n){n.ENV&&(n.ENV.LC_ALL="C")}class nt{constructor(t,e){this.wasmUrl=t,this.onWasmProgress=e,this.module=null,this.modulePromise=null,this.tail=Promise.resolve(),this.createModule=null,this.stdoutSink=null,this.stderrSink=null}async init(){if(!this.module){if(this.modulePromise){await this.modulePromise;return}this.modulePromise=this.loadModule(),this.module=await this.modulePromise;try{this.module.FS.mkdir(E)}catch{}}}async loadModule(){const t={noInitialRun:!0,print:i=>{var s;(s=this.stdoutSink)==null||s.call(this,i)},printErr:i=>{var s;(s=this.stderrSink)==null||s.call(this,i)},preRun:[rt]},e=this.wasmUrl??this.defaultWasmUrl(),r=await this.importModuleFactory(e);this.createModule=r;const o=e.substring(0,e.lastIndexOf("/")+1);if(this.onWasmProgress&&typeof fetch<"u"){const i=await this.fetchWithProgress(o+"perl.wasm");return await r({...t,locateFile:s=>o+s,wasmBinary:i})}return await r({...t,locateFile:i=>o+i})}async fetchWithProgress(t){const e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch ${t}: ${e.status} ${e.statusText}`);const r=e.headers.get("content-length"),o=r?parseInt(r,10):null,i=e.body.getReader(),s=[];let c=0;for(;;){const{done:d,value:u}=await i.read();if(d)break;s.push(u),c+=u.byteLength,this.onWasmProgress(c,o)}const a=new Uint8Array(c);let l=0;for(const d of s)a.set(d,l),l+=d.byteLength;return a}async importModuleFactory(t){var i;if(typeof process<"u"&&((i=process.versions)!=null&&i.node)){const s=await import(t);return s.default??s}const e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch ${t}: ${e.status} ${e.statusText}`);const r=await e.text();return new Function("exports","module","define",`${r}
2
- return createPerlModule;`)(void 0,void 0,void 0)}defaultWasmUrl(){return new URL("../wasm/perl.js",typeof document>"u"?require("url").pathToFileURL(__filename).href:S&&S.tagName.toUpperCase()==="SCRIPT"&&S.src||new URL("wexiftool-Dt9AnMsh.cjs",document.baseURI).href).href}async exec(t,e){const r=[...e].map(([s,c])=>({name:s,source:c})),{committed:o,...i}=await this.run(t,r);return i}async run(t,e,r={}){return await this.init(),this.enqueue(()=>e.some(o=>!(o.source instanceof Uint8Array))?this.runMounted(t,e,r):this.runStaged(t,e))}runStaged(t,e){const r=this.module.FS,o=e.map((s,c)=>`${E}/${c}/${x(s)}`),i=new Map;try{e.forEach((c,a)=>{r.mkdir(`${E}/${a}`),r.writeFile(o[a],c.source),r.chmod(o[a],292),i.set(o[a],O(r,o[a]))});const s=this.callExiftool(t,e,o);return e.forEach((c,a)=>{if(O(r,o[a])!==i.get(o[a]))try{s.files.set(c.name,r.readFile(o[a]))}catch{}}),{...s,committed:new Map}}finally{e.forEach((s,c)=>D(r,`${E}/${c}`))}}async runMounted(t,e,r){var a;const{mountFiles:o}=await Promise.resolve().then(()=>require("./index-Czh_jOH1.cjs")).then(l=>l.index),i=this.module,s=e.map((l,d)=>`${E}/${d}/${x(l)}`),c=[];try{for(const[u,h]of e.entries()){const w=((a=h.commitTo)==null?void 0:a.dir)??(r.readOnly?void 0:r.privateDir);if(w===void 0&&!r.readOnly)throw new Error(`Input "${h.name}" is mounted, so the run needs a privateDir, a commitTo or readOnly`);c.push(await o(i,`${E}/${u}`,{inputs:{[x(h)]:h.source},outputDir:w,scratch:w===void 0?0:r.scratch??1,onExhausted:"spill",backend:r.backend}))}const l=this.callExiftool(t,e,s),d=new Map;for(const[u,h]of e.entries()){const w=await c[u].commit(),m=w.find(f=>f.path===x(h));if(h.commitTo)m&&d.set(h.name,m);else for(const f of w)f===m&&l.files.set(h.name,await ot(f)),await st(f,r.privateDir)}return{...l,committed:d}}finally{for(const l of c)await l.release()}}callExiftool(t,e,r){const o=this.module,i=new Map(e.map((u,h)=>[u.name,r[h]])),s=[et];for(const u of t)s.push(u.toLowerCase()==="-overwrite_original_in_place"?"-overwrite_original":i.get(u)??u);const c=new Set(t);for(const u of e)c.has(u.name)||s.push(i.get(u.name));let a="",l="";this.stdoutSink=u=>{a+=u+`
3
- `},this.stderrSink=u=>{l+=u+`
4
- `};let d;try{d=o.callMain(s)}catch(u){if(u.status!==void 0)d=u.status;else throw u}finally{this.stdoutSink=null,this.stderrSink=null}for(const[u,h]of i)a=a.replaceAll(h,u),l=l.replaceAll(h,u);return e.forEach((u,h)=>{const w=new RegExp(`${E}/${h}(?![0-9])`,"g"),m=u.name.lastIndexOf("/"),f=m>0?u.name.slice(0,m):m===0?"/":".";a=a.replace(w,()=>f),l=l.replace(w,()=>f)}),{stdout:a.trimEnd(),stderr:l.trimEnd(),exitCode:d,files:new Map}}enqueue(t){const e=this.tail.then(t,t);return this.tail=e.catch(()=>{}),e}destroy(){this.module=null,this.modulePromise=null,this.createModule=null,this.tail=Promise.resolve()}}function x(n){var e;const t=(((e=n.commitTo)==null?void 0:e.as)??n.name).split("/").pop();return t&&t!=="."&&t!==".."?t:"input.bin"}function O(n,t){try{const e=n.stat(t);return`${e.ino}:${e.size}:${+e.mtime}`}catch{return"missing"}}function D(n,t){let e;try{e=n.readdir(t)}catch{return}for(const r of e){if(r==="."||r==="..")continue;const o=`${t}/${r}`;try{n.unlink(o)}catch{D(n,o)}}try{n.rmdir(t)}catch{}}async function ot(n){if(n.handle)return new Uint8Array(await(await n.handle.getFile()).arrayBuffer());if(n.hostPath){const{readFile:t}=await import("node:fs/promises");return new Uint8Array(await t(n.hostPath))}return n.bytes??new Uint8Array}async function st(n,t){if(n.hostPath){const{rm:e}=await import("node:fs/promises");await e(n.hostPath,{force:!0});return}if(typeof t!="string"){const e=n.path.split("/"),r=e.pop();let o=t;for(const i of e)o=await o.getDirectoryHandle(i);await o.removeEntry(r).catch(()=>{})}}function p(n){return typeof n=="object"&&n!==null&&n.kind==="file"&&typeof n.getFile=="function"}async function W(n){if(n instanceof Uint8Array)return{name:"input.bin",data:n};if(n instanceof ArrayBuffer)return{name:"input.bin",data:new Uint8Array(n)};if(p(n)){const t=await n.getFile();return{name:n.name||"input.bin",data:new Uint8Array(await t.arrayBuffer())}}if(typeof File<"u"&&n instanceof File){const t=await n.arrayBuffer();return{name:n.name||"input.bin",data:new Uint8Array(t)}}if(typeof Blob<"u"&&n instanceof Blob){const t=await n.arrayBuffer();return{name:"input.bin",data:new Uint8Array(t)}}throw new Error("Unsupported input type")}async function it(n,t){const e=at(t);if(typeof n.createSyncAccessHandle=="function"){const r=await n.createSyncAccessHandle();try{r.truncate(0);let o=0;for(;o<e.byteLength;){const i=o===0?e:e.slice(o),s=r.write(i,{at:o});if(s<=0)throw new Error(`Short write to ${n.name} at byte ${o} of ${e.byteLength}`);o+=s}r.flush()}finally{r.close()}return}if(typeof n.createWritable=="function"){const r=await n.createWritable();try{await r.write(e),await r.close()}catch(o){throw await r.abort(o).catch(()=>{}),o}return}throw new Error(`Cannot write to file handle "${n.name}": it has neither createSyncAccessHandle() (dedicated workers only) nor createWritable().`)}function at(n){const{buffer:t,byteOffset:e,byteLength:r}=n;return t instanceof ArrayBuffer&&e===0&&r===t.byteLength?t:n.slice().buffer}const ct=Object.freeze(Object.defineProperty({__proto__:null,isFileHandle:p,resolveInput:W,writeToHandle:it},Symbol.toStringTag,{value:"Module"})),H=".wexiftool";function L(){var i,s;const n=globalThis,t=!!((s=(i=n.process)==null?void 0:i.versions)!=null&&s.node)&&typeof n.window>"u",e=n.DedicatedWorkerGlobalScope,r=n.FileSystemFileHandle,o=!t&&typeof e=="function"&&globalThis instanceof e&&!!(r&&"createSyncAccessHandle"in r.prototype);return{node:t,opfs:o}}async function F(n,t,e,r){if(typeof t=="string"){if(!e.node)throw new Error(`"${t}": file paths are only supported under Node`);const{resolve:i,dirname:s,basename:c}=await import("node:path"),a=i(t);if(r===void 0)return{input:{name:n,source:a}};if(typeof r!="string")return{input:{name:n,source:a},writeAfter:r};const l=i(r);return{input:{name:n,source:a,commitTo:{dir:s(l),as:c(l)}}}}if(p(t)&&e.opfs&&await R(t)){const i=t;if(r===void 0)return{input:{name:n,source:i}};const s=p(r)?await ht(r):null;return s?{input:{name:n,source:i,commitTo:{dir:s,as:r.name}}}:{input:{name:n,source:i},writeAfter:r}}const{data:o}=await W(t);return{input:{name:n,source:o},writeAfter:r}}const T=new WeakMap;async function lt(n,t){try{const e=await ft(t);e&&await e.isSameEntry(n)&&T.set(n,t)}catch{}}async function ut(n){return(await navigator.storage.getDirectory()).resolve(n)}async function ft(n){if(n.length===0)return null;let t=await navigator.storage.getDirectory();for(const e of n.slice(0,-1))t=await t.getDirectoryHandle(e);return t.getFileHandle(n[n.length-1])}const dt=5e3;async function R(n){const t=T.get(n);if(t)return t;const r=[[await navigator.storage.getDirectory(),[]]];let o=0;for(;r.length>0;){const[i,s]=r.shift();for await(const[c,a]of i.entries()){if(++o>dt)return null;if(a.kind==="file"){if(c===n.name&&await a.isSameEntry(n)){const l=[...s,c];return T.set(n,l),l}}else s.length===0&&c===H||r.push([a,[...s,c]])}}return null}async function ht(n){const t=await R(n);if(!t)return null;let e=await navigator.storage.getDirectory();for(const r of t.slice(0,-1))e=await e.getDirectoryHandle(r);return e}async function C(n,t){const e=globalThis.crypto.randomUUID().slice(0,8);if(n.node){const{mkdtemp:s,rm:c}=await import("node:fs/promises"),{tmpdir:a}=await import("node:os"),{join:l}=await import("node:path"),d=await s(l(a(),`wexiftool-${e}-`));try{return await t(d)}finally{await c(d,{recursive:!0,force:!0})}}const o=await(await navigator.storage.getDirectory()).getDirectoryHandle(H,{create:!0}),i=await o.getDirectoryHandle(e,{create:!0});try{return await t(i)}finally{await o.removeEntry(e,{recursive:!0}).catch(()=>{})}}async function M(n,t){if(typeof n=="string"){const{writeFile:r}=await import("node:fs/promises");await r(n,t);return}const{writeToHandle:e}=await Promise.resolve().then(()=>ct);await e(n,t)}const B=Object.freeze(Object.defineProperty({__proto__:null,detectEnvironment:L,planInput:F,registerHint:lt,resolveOnCallerSide:ut,withPrivateDir:C,writeRef:M},Symbol.toStringTag,{value:"Module"}));function j(n){const t=n,e=[];return"input"in t&&e.push(t.input),t.inputs&&e.push(...t.inputs),t.files&&e.push(...t.files.values()),t.options&&"output"in t.options&&e.push(t.options.output),e.filter(p)}class U{constructor(t,e){this.port=t,this.onWasmProgress=e,this.nextId=1,this.pending=new Map,this.destroyed=!1,t.addEventListener("message",r=>this.receive(r.data)),t.addEventListener("error",r=>this.failAll(mt(r,"Worker error"))),t.addEventListener("messageerror",()=>this.failAll("Worker sent a message that could not be deserialized"))}static async create(t,e){const r=new U(t,e==null?void 0:e.onWasmProgress);return await r.call({op:"init",options:{wasmUrl:e==null?void 0:e.wasmUrl,progress:!!(e!=null&&e.onWasmProgress)}}),r}read(t){return this.call({op:"read",input:t})}readMany(t){return this.call({op:"readMany",inputs:t})}readRaw(t,e){return this.call({op:"readRaw",input:t,args:e})}write(t,e,r){return this.call({op:"write",input:t,tags:e,options:r})}exec(t,e,r){return this.call({op:"exec",args:t,files:e,options:r})}async destroy(){if(this.destroyed=!0,typeof this.port.terminate=="function"){this.port.terminate(),this.failAll("WExifToolWorker was destroyed");return}await this.call({op:"destroy"})}async call(t){const e=this.nextId++,r=await wt(t);if(this.destroyed&&t.op!=="destroy")throw new Error("WExifToolWorker was destroyed");return new Promise((o,i)=>{this.pending.set(e,{resolve:o,reject:i});try{this.port.postMessage({...t,id:e,hints:r})}catch(s){this.pending.delete(e),i(s instanceof Error?s:new Error(String(s)))}})}receive(t){var r;if(t.kind==="progress"){(r=this.onWasmProgress)==null||r.call(this,t.loaded,t.total);return}const e=this.pending.get(t.id);e&&(this.pending.delete(t.id),t.ok?e.resolve(t.value):e.reject(new Error(t.error)))}failAll(t){const e=new Error(t);for(const r of this.pending.values())r.reject(e);this.pending.clear()}}async function wt(n){var o,i;const t=globalThis;if(typeof t.window>"u"||typeof((i=(o=t.navigator)==null?void 0:o.storage)==null?void 0:i.getDirectory)!="function")return;const e=j(n);if(e.length===0)return;const{resolveOnCallerSide:r}=await Promise.resolve().then(()=>B);return Promise.all(e.map(s=>r(s).catch(()=>null)))}function mt(n,t){const e=n==null?void 0:n.message;return typeof e=="string"&&e?`${t}: ${e}`:t}class I{constructor(t){this.glue=t}static async create(t){const e=new nt(t==null?void 0:t.wasmUrl,t==null?void 0:t.onWasmProgress);return await e.init(),new I(e)}async read(t){const e=k(t),r=await this.runFiles(["-json","-G",e],[[e,t]],{readOnly:!0});if(r.exitCode!==0&&r.stderr)throw new Error(`ExifTool error: ${r.stderr}`);try{const o=JSON.parse(r.stdout);return Array.isArray(o)?o[0]:o}catch{throw new Error(`Failed to parse ExifTool output: ${r.stdout}`)}}async readMany(t){if(t.length===0)return[];const e=yt(t.map(k)),r=await this.runFiles(["-json","-G",...e],t.map((i,s)=>[e[s],i]),{readOnly:!0});let o;try{o=JSON.parse(r.stdout)}catch{throw new Error(`ExifTool error: ${r.stderr||`unparseable output: ${r.stdout}`}`)}if(!Array.isArray(o)||o.length!==t.length)throw new Error(`ExifTool error: ${r.stderr||`expected ${t.length} results`}`);return o}async write(t,e,r){const o=k(t),i=Object.entries(e).map(([l,d])=>`-${l}=${d}`),s=typeof t=="string"||p(t),c=s?(r==null?void 0:r.output)??t:void 0,a=await this.runFiles(["-overwrite_original",...i,o],[[o,t]],{targets:c===void 0?void 0:new Map([[o,c]])});if(a.exitCode!==0&&a.stderr)throw new Error(`ExifTool error: ${a.stderr}`);return s?(!a.written.includes(o)&&c!==t&&await M(c,(await W(t)).data),c):a.files.get(o)??(await W(t)).data}async readRaw(t,e){const r=k(t),o=await this.runFiles([...e,r],[[r,t]],{scratch:0});if(o.exitCode!==0&&o.stderr)throw new Error(`ExifTool error: ${o.stderr}`);return o.stdout}async exec(t,e,r){const o=[...e??[]],i=r!=null&&r.writeBack?new Map(o.filter(([,s])=>typeof s=="string"||p(s))):void 0;return this.runFiles(t,o,{targets:i})}async runFiles(t,e,r){const o=L();try{return await this.runPlanned(t,e,r,o)}catch(i){if(o.opfs&&i instanceof _)return this.runPlanned(t,e,r,{...o,opfs:!1});throw i}}async runPlanned(t,e,{targets:r,scratch:o,readOnly:i},s){var m;const c=[],a=[];for(const[f,y]of e){let $=await F(f,y,s,r==null?void 0:r.get(f));const v=$.input.source;typeof v=="object"&&!(v instanceof Uint8Array)&&(await pt(v,a)?$=await F(f,y,{...s,opfs:!1},r==null?void 0:r.get(f)):a.push(v)),c.push($)}const l=c.map(f=>f.input);let d;if(l.every(f=>f.source instanceof Uint8Array))d=await this.glue.exec(t,new Map(l.map(f=>[f.name,f.source])));else{const f=s.node?"node":"opfs";d=!i&&l.some(y=>!y.commitTo)?await C(s,y=>this.glue.run(t,l,{privateDir:y,backend:f,scratch:o})):await this.glue.run(t,l,{backend:f,scratch:o,readOnly:i})}const u=[...((m=d.committed)==null?void 0:m.keys())??[]];for(const{input:f,writeAfter:y}of c){const $=d.files.get(f.name);y&&$&&(await M(y,$),d.files.delete(f.name),u.push(f.name))}const{committed:h,...w}=d;return{...w,written:u}}destroy(){this.glue.destroy()}}function k(n){return typeof n=="string"?n:(p(n)||typeof File<"u"&&n instanceof File)&&n.name||"input.bin"}function yt(n){const t=new Set(n),e=new Map;return n.map(r=>{const o=(e.get(r)??0)+1;if(e.set(r,o),o===1)return r;const i=r.lastIndexOf("/"),s=r.lastIndexOf("."),c=s>i+1?s:r.length;let a=o,l=`${r.slice(0,c)} (${a})${r.slice(c)}`;for(;t.has(l);)l=`${r.slice(0,c)} (${++a})${r.slice(c)}`;return t.add(l),l})}async function pt(n,t){for(const e of t)if(e===n||await e.isSameEntry(n))return!0;return!1}exports.WExifTool=I;exports.WExifToolWorker=U;exports.WopfsCommitError=tt;exports.WopfsError=b;exports.WopfsInputError=X;exports.WopfsLockedError=Q;exports.WopfsRuntimeError=Y;exports.WopfsStateError=Z;exports.WopfsUnsupportedError=_;exports.handlesIn=j;exports.isFileHandle=p;exports.mounts=B;