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 🙏

© 2026 – Pkg Stats / Ryan Hefner

viall

v1.2.0

Published

Simple but powerful Map enhancement.

Readme


Viall is a new, type of variable that tries to be very close to old Map(). In essence, classic Map allow for an association between unique keys and their values, but lack an iterative interface. For example, how can you transform every value or filter the entries in a Map easily? This is the point of the Viall class! We are combining best functionality of Maps and Arrays in one.

Array-like methods

Many of the methods on Viall are based on their namesake in Array. One of them is find:

// Assume we have an array of cars and a viall of the same cars.
someArray.find(car => car.color === 'black');
someViall.find(car => car.color === 'black');

The interface of the callback function is very similar between the two. For arrays, callbacks are usually passed the parameters (value, index, array), where value is the value it iterated to, index is the current index, and array is the array itself. For vialls, you would have (value, key, viall). Here, value is the same, but key is the key of the value, and viall is the viall itself instead.

Methods that follow this philosophy of staying close to the Array interface are as follows:

filter() & map() returns an Array of values instead of a Viall!

Converting to Array

You can easily convert any Viall to Array if you like to:

import Viall from 'viall';

const myViall: Viall<number> = new Viall();
// <TS> Add value type ☝️
// You can add own interfaces, types, etc.
// Viall's values can store any type of data.

myViall.set('A', 1).set('B', 2).set('C', 3);

// Grab everything
const data = myViall.entries();
// => [['A', 1], ['B', 2], ['C', 3]]

// I want just keys!
const keys = myViall.keys();
// => ['A', 'B', 'C']

// How about values? No problem!
const values = myViall.values();
// => [1, 2, 3]

⏱️ Remember that this convertion can take some time on really large amount of values! (like milions of objects)

Extra Utilities

Some methods are not from Array and are completely new to standard JavaScript.

// Return random value from Viall.
myViall.random();

// Grabs first value from Viall.
myViall.first();

// Grabs first 5 values.
myViall.first(5);

// Similar to first(), but from the end.
myViall.last();
myViall.last(2);

// Removes from the viall anything that meets a criteria.
// Sort of like filter, but in-place.
myViall.sweep(book => book.price > 100);

Viall vs. Map

Vialls are generally over 2x times faster than regular Maps and uses less memory. How this is possible?

⚙️ Vialls operates on special, hidden object instead reusing already existing Map(). Each method like get() or set() is in reality a set of instructions that are not exactly the same like in regular Map, but works in very similar way - final result is the same. Like always - there are pros & cons of this idea:

| ❌ CONS | ✅ PROS | |:------------------------------------------------------------------------------------: |:------------------------------------------: | | Key type is limited to number or string(Automatically rewrites to string type) | Highly effective (faster) | | sort() method works only onvalues with string type key | Lightweight (less memory usage) | | | Can easily convert to Array | | | Supports a large range of filters | | | Contains extra methods for easier usage | | | Works without self replication of own data | | | Full TypeScript support |

Let's make simple capacity test

💽 I want to show you the speed/capacity difference. I made really simple capacity test that just loads 1,000,000 keys & values (ints) into both - Map & Viall

// Clear, before test (pure Node.js)
rss: 18MB
heapTotal: 4MB
heapUsed: 3MB
external: 0MB
arrayBuffers: 0MB

// Using regular Map
rss: 73MB
heapTotal: 59MB
heapUsed: 43MB
external: 0MB
arrayBuffers: 0MB

// Using Viall
rss: 41MB
heapTotal: 31MB
heapUsed: 22MB
external: 0MB
arrayBuffers: 0MB

⏱️ Additionally, I registered times of each loop:

  • Map
    • First try: 421.093ms
    • Second try: 409.127ms
    • Third try: 637.104ms
  • Viall
    • First try: 164.221ms
    • Second try: 114.025ms
    • Third try: 182.431ms

Of course, it strongly depends from type of processor it was run on. I used just MacBook Air with CPU: Intel(R) Core(TM) i3-1000NG4 CPU @ 1.10GHz (4 cores)


❗ Warning ❗

That gonna most likely never happen while normal usage, but you should know that Viall works on original data set instead making self replication over and over like Map does. During my work I never run into any issue with damaging data inside, but for safety, make a copy before you start making brutal operations on larger scale.

Example way how you should use a copy:

interface data {
  health: number,
  mana: number,
  stamina: number
  money: number
  isFighting: boolean
  inventory: Array<...>
}

const characters: Viall<data> = new Viall();

characters.set({...});
characters.set({...});
characters.set({...});

// You can safely read/write, map, filter, etc.
// But you cannot be sure what gonna happen when you push Viall
// To other, unknown 3rd-party property...
dangerousOperation(characters); // ❌ Bad idea

const chars = characters.copy();
dangerousOperation(chars); // 👍 Better
// => Even if you damage data, hey! Thay was just a copy :)