gildas-lormeau / zip.js

JavaScript library to zip and unzip files supporting multi-core compression, compression streams, zip64, split files and encryption.
https://gildas-lormeau.github.io/zip.js
BSD 3-Clause "New" or "Revised" License
3.38k stars 510 forks source link

Throws `TypeError: Illegal invocation` on deno deploy #367

Closed SaadiSave closed 1 year ago

SaadiSave commented 1 year ago

I deployed a script on deno deploy today and noticed the following error:

TypeError: Illegal invocation
    at Object.assertBranded (deno:ext/webidl/00_webidl.js:884:13)
    at Navigator.get [as hardwareConcurrency] (deno:deploy/js/99_main.js:361:16)
    at https://deno.land/x/zipjs@v2.6.27/lib/core/configuration.js:35:60

The exception seems to be caused by this code in lib/core/configuration.js

const DEFAULT_CONFIGURATION = {
    chunkSize: 512 * 1024,
    maxWorkers: (typeof navigator != "undefined" && navigator.hardwareConcurrency) || 2,
    terminateWorkerTimeout: 5000,
    useWebWorkers: true,
    workerScripts: undefined
};
gildas-lormeau commented 1 year ago

From my point of view, it's a bug in Deno deploy (maybe related to https://github.com/denoland/deno/issues/12353?). However, I made this portion of code more robust to circumvent it in the version 2.6.28 I just deployed. I did a test in Deno Playground with the code below and it works now as expected.

import { serve } from "https://deno.land/std@0.145.0/http/server.ts";
import {
    BlobReader,
    BlobWriter,
    TextReader,
    TextWriter,
    ZipReader,
    ZipWriter,
} from "https://deno.land/x/zipjs/index.js";

serve(async req => {
    // ----
    // Write the zip file
    // ----

    // Creates a BlobWriter object where the zip content will be written.
    const zipFileWriter = new BlobWriter();
    // Creates a TextReader object storing the text of the entry to add in the zip
    // (i.e. "Hello world!").
    const helloWorldReader = new TextReader("Hello world!");

    // Creates a ZipWriter object writing data via `zipFileWriter`, adds the entry
    // "hello.txt" containing the text "Hello world!" via `helloWorldReader`, and
    // closes the writer.
    const zipWriter = new ZipWriter(zipFileWriter);
    await zipWriter.add("hello.txt", helloWorldReader);
    await zipWriter.close();

    // Retrieves the Blob object containing the zip content into `zipFileBlob`. It
    // is also returned by zipWriter.close() for more convenience.
    const zipFileBlob = await zipFileWriter.getData();

    // ----
    // Read the zip file
    // ----

    // Creates a BlobReader object used to read `zipFileBlob`.
    const zipFileReader = new BlobReader(zipFileBlob);
    // Creates a TextWriter object where the content of the first entry in the zip
    // will be written.
    const helloWorldWriter = new TextWriter();

    // Creates a ZipReader object reading the zip content via `zipFileReader`,
    // retrieves metadata (name, dates, etc.) of the first entry, retrieves its
    // content via `helloWorldWriter`, and closes the reader.
    const zipReader = new ZipReader(zipFileReader);
    const firstEntry = (await zipReader.getEntries()).shift();
    const helloWorldText = await firstEntry.getData(helloWorldWriter);
    await zipReader.close();

    // Displays "Hello world!".
    return new Response(helloWorldText);
});
gildas-lormeau commented 1 year ago

For the record, I reported this issue here: https://github.com/denoland/deploy_feedback/issues/287.

SaadiSave commented 1 year ago

From my point of view, it's a bug in Deno deploy (maybe related to https://github.com/denoland/deno/issues/12353?).

I completely agree that it's a problem with Deno Deploy. But it doesn't seem like they're going to fix those bugs anytime soon, so something had to be done on the library side.

Thank you for the quick response and solution.

gildas-lormeau commented 1 year ago

@SaadiSave FYI, the bug has been fixed in Deno Deploy.