npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

zip24

v0.1.6

Published

A zip package for the modern age

Downloads

10

Readme

zip24

A zip library for the modern age!

Reading Zips

From a random-access reader

You can open a zip reader directly from a file on Node as follows:

import { ZipReader } from "zip24/reader";

const reader = await ZipReader.open("my-stuff.zip");

for await (const file of reader) {
  // iterate through all the files
  console.log(file.path);
}

You can also manage the reader manually like this:

import { open } from "node:fs/promises";
import { ZipReader } from "zip24/reader";

const file = await open("my-stuff.zip");
// the size is needed so that the Central Directory can be
// found at the end of the file
const { size } = await file.stat();
const reader = await ZipReader.fromReader(file, size);

for await (const file of reader) {
  // iterate through all the files
  console.log(file.path);
}

You can create your own data source by implementing RandomAccessReader:

type RandomAccessReader = {
  close?: () => void | PromiseLike<void>;

  read: (
    options: RandomAccessReadOptions,
  ) => PromiseLike<RandomAccessReadResult>;
};

type RandomAccessReadOptions = {
  buffer: Uint8Array;
  offset?: number;
  length?: number;
  position: number;
};

type RandomAccessReadResult = {
  bytesRead: number;
  buffer: Uint8Array;
};

From a Buffer, Uint8Array, ArrayBuffer, etc

import { ZipBufferReader } from "zip24/buffer";

// get the buffer somehow
const buffer = getZipBuffer();
const reader = new ZipBufferReader(buffer);

// iteration can be done synchronously
for (const file of reader) {
  console.log(file.path);
}

From a stream

Nope! Reading a zip forwards from start to finish is something that the zip format is not designed to do. The authoritative index of all files contained in the zip (the Central Directory) is stored at the end of the zip file, which means you can‘t start at the start. It could be possible to read the local headers, but these contain less information (e.g. they don‘t store the file attributes), and in theory could represent a deleted file which is no longer present in the Central Directory, which is allowed by the zip format. Also, the local header often doesn‘t contain the size of the data, meaning that determining the end of the data is quite tricky.

Writing Zips

import { ZipWriter } from "zip24/writer";

const writer = ZipWriter.open("my-file.zip");

await writer.addFile(
  {
    path: "hello.txt",
    comment: "comment 1",
    attributes: new UnixFileAttributes(0o644),
  },
  "hello world",
);

await writer.addFile(
  {
    path: "uncompressed.txt",
    compressionMethod: CompressionMethod.Stored,
    lastModified: new Date(`1994-03-02T22:44:08Z`),
    comment: "comment 2",
  },
  "this will be stored as-is",
);

await writer.finalize("Gordon is cool");

About this library

Why zip24?

When I committed to writing it, I thought “it's 2024 and there's still not a built-in/standard/modern zip library for Node”.

Why I wrote this

I had been using Josh Wolfe‘s yazl (Yet Another Zip Library) and yauzl (Yet Another UnZip Library). These are great and I owe a tonne of thanks to Josh, but I don‘t like the event-based interface of yauzl and there was a long period when these libraries were unmaintained, leading me to become interested in writing my own.

I wrote unzip-iterable to make a nice iterable interface for yauzl, but in the end I wanted to get into the bits and bytes myself. I also wanted to make a modern library, written in TypeScript, with types shipped in the same package.