skip to Main Content

Rewriting a webapp so that it can run in both Node or Deno2, I get stuck on the following. The function has to read a base64 encoded gzip buffer containing a JSON string. This is the node implementation:

import zlib from 'node:zlib';

function from_base64_gzip(str){
  let buff = Buffer.from(str, 'base64');
  let json = zlib.unzipSync(buff).toString('utf-8');
  return JSON.parse(json);
}

However deno2 does not have the Buffer object, and atob() only seems to work for strings and not for binary data.

Is there an elegant way to rewrite this such that it will run both in node and deno (preferably without extra npm deps)?

2

Answers


  1. Chosen as BEST ANSWER

    The answer was given in the comments: we can import the node buffer API as documented:

    import { Buffer } from "node:buffer";
    import zlib from 'node:zlib';
    
    function from_base64_gzip(str){
      let buff = Buffer.from(str, 'base64');
      let json = zlib.unzipSync(buff).toString('utf-8');
      return JSON.parse(json);
    }
    

    Note that Buffer is not the default export, hence we have to use import { Buffer } instead of import Buffer, which is why I initially thought it did not work.


  2. A method that works in Deno, Node and the browser would be to use the decodeBase64 function from jsr:@std/encoding, and toBytes from jsr:@std/streams/unstable-to-bytes. With these two dependencies, and the global DecompressionStream, one can construct the below function.

    import { decodeBase64 } from "@std/encoding";
    import { toBytes } from "@std/streams/unstable-to-bytes";
    
    const text = "H4sIAAAAAAAAE6tWyk0tLk5MT1WyUvJIzcnJVwjPL8pJUVSqBQBrh/YJGgAAAA==";
    console.log(await fromBase64Gzip(text)); // { message: 'Hello World!' }
    
    export async function fromBase64Gzip(str) {
      return JSON.parse(
        new TextDecoder().decode(
          await toBytes(
            ReadableStream.from([decodeBase64(str)]).pipeThrough(
              new DecompressionStream("gzip"),
            ),
          ),
        ),
      );
    }
    

    The only difference between the output of these two functions is that this one is asynchronous and yours in synchronous.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search