| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 | import * as fflate from '../../..';import toNativeStream from './stream-adapter';type Callback = (...args: unknown[]) => void;type WorkerProxy = Record<string, Callback>;const concat = (chunks: Uint8Array[]) => {  const out = new Uint8Array(    chunks.reduce((a, v) => v.length + a, 0)  );  let loc = 0;  for (const chunk of chunks) {    out.set(chunk, loc);    loc += chunk.length;  }  return out;}const createWorkerProxy = (lib: string, keys: string[]): WorkerProxy => {  const p: WorkerProxy = {};  for (const k of keys) {    const base = function(cb: (...args: unknown[]) => void) {      const w = new Worker('../../util/workers.ts');      w.postMessage([lib, k]);      w.onmessage = function(msg) {        const args = msg.data;        args.unshift(null);        cb.apply(null, args);      }      w.onerror = err => cb(err);      return w;    }    if (k != 'zip' && k != 'unzip') {      p[k] = function(dat, cb) {        const chks: unknown[] = [];        const w = base((err, dat, final) => {          if (err) (cb as Callback)(err);          else {            if (final) {              if (!chks.length) (cb as Callback)(null, dat);              else (cb as Callback)(null, concat(chks as Uint8Array[]));            } else chks.push(dat);          }        });        w.postMessage([dat, true], [(dat as Uint8Array).buffer]);      }      p['create' + k.slice(0, 1).toUpperCase() + k.slice(1)] = function() {        let trueCb = arguments[0];        const w = base((err, dat, final) => {          trueCb(err, dat, final);        });        const out = {          ondata: trueCb,          push(v: Uint8Array, f: boolean) {            if (!out.ondata) throw 'no callback';            trueCb = out.ondata;            w.postMessage([v, f], [v.buffer]);          },          terminate() {            w.terminate();          }        }        return out;      }    } else {      p[k] = function() {        let trueCb = arguments[0];        const w = base((err, dat) => {          trueCb(err, dat);        });        const out = {          ondata: trueCb,          add(name: string, buf: Uint8Array) {             buf = new Uint8Array(buf);            w.postMessage([name, buf], [buf.buffer]);          },          end() {            if (!out.ondata) throw 'no callback';            trueCb = out.ondata;            w.postMessage(null);          }        }        return out;      }    }  }  return p;}const keys = ['zip', 'unzip', 'deflate', 'inflate', 'gzip', 'gunzip', 'zlib', 'unzlib'];const uzipWorker = createWorkerProxy('uzip', keys);const pakoWorker = createWorkerProxy('pako', keys);const fileToU8 = (file: File, cb: (out: Uint8Array) => void) => {  const fr = new FileReader();  fr.onloadend = () => {    cb(new Uint8Array(fr.result as ArrayBuffer));  }  fr.readAsArrayBuffer(file);};const download = (file: BlobPart, name?: string) => {  const url = URL.createObjectURL(new Blob([file]));  const dl = document.createElement('a');  dl.download = name || ('fflate-demo-' + Date.now() + '.dat');  dl.href = url;  dl.click();  URL.revokeObjectURL(url);}const bts = ['B', ' kB', ' MB', ' GB'];const hrbt = (bt: number) => {  let i = 0;  for (; bt > 1023; ++i) bt /= 1024;  return bt.toFixed((i != 0) as unknown as number) + bts[i];}const prettySizes = (files: Record<string, [number, number]>) => {  let out = '\n\n';  let tot = 0;  let totc = 0;  let cnt = 0;  for (const k in files) {    ++cnt;    out += '<span style="font-weight:bold">' + k + '</span> compressed from <span style="font-weight:bold;color:red">' + hrbt(files[k][1]) + '</span> to <span style="font-weight:bold;color:green">' + hrbt(files[k][0]) + '</span>\n';    totc += files[k][0];    tot += files[k][1];  }  return out + (cnt > 1 ? '\n\n<span style="font-weight:bold">In total, all files originally <span style="font-style:italic;color:red">' + hrbt(tot) + '</span>, compressed to <span style="font-style:italic;color:green">' + hrbt(totc) + '</span></span>' : '');}const exec = (code: string, files: File[], callback: Callback) => {  const scope = {    fflate,    uzipWorker,    pakoWorker,    toNativeStream,    callback,    fileToU8,    files,    download,    prettySizes  };  try {    new Function('"use strict";' + Object.keys(scope).map(k => 'var ' + k + ' = this["' + k + '"];').join('') + code).call(scope);  } catch(e) {    callback(e);  }}export default exec;
 |