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

@kjangid/array-async-tools

v1.0.1

Published

Object, array, and async utilities for transforming data, managing collections, and controlling asynchronous workflows.

Readme

@kjangid/array-async-tools

TypeScript Zero Dependencies Module CI Release npm version Tests License: MIT Node Coverage

A production-grade, zero-runtime-dependency TypeScript utility library and standalone CLI toolkit designed for high-performance data transformations, collection manipulation, and robust asynchronous control flow.

Built natively for Node.js (>= 18.0.0), Modern Browsers, Bun, Deno, and Cloudflare Workers with dual ESM (.mjs) and CommonJS (.cjs) output, tree-shakeable subpath exports, and comprehensive prototype pollution defenses.


Table of Contents


Key Features

  • Zero Runtime Dependencies: Every single utility is implemented from first principles. No hidden sub-dependencies, no supply-chain bloat.
  • Dual ESM / CommonJS Architecture: Seamless integration in both modern native ESM (import) and legacy CommonJS (require) runtimes with exact TypeScript type definitions (.d.ts / .d.cts).
  • Security by Default: Defenses against prototype pollution attacks (__proto__, constructor, prototype) across object cloning, diffing, grouping, and cleaning.
  • Universal Runtime Support: Fully functional across Node.js 18+, Bun, Deno, modern web browsers, and edge environments like Cloudflare Workers.
  • Standalone CLI: High-performance unified binary (oa-tools) and dedicated binary aliases (oa-clone, oa-diff, oa-clean, oa-chunk, oa-sort, oa-retry, oa-timeout) supporting stdin pipes and file arguments.
  • 100% Test Pass Rate: Thorough test suites with >96% statement and branch coverage via Vitest and V8 coverage (168 tests across 18 test files).

Tools & Utilities Overview

| # | Utility | Category | Description | | --- | ------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- | | 1 | deepClone | Object | Independent deep copy of nested objects/arrays handling circular references, Maps, Sets, Dates, RegExps, TypedArrays, and Errors. | | 2 | deepEqual | Object | Recursive structural equality comparator for complex graphs, circular structures, Maps, Sets, and binary buffers. | | 3 | objectDiff | Object | Computes structural differences returning added, removed, and updated fields with flat dot-paths or nested hierarchies. | | 4 | objectClean | Object | Immutable cleaner filtering nulls, undefineds, empty strings, empty arrays, empty objects, and NaNs. | | 5 | chunk | Array | Partitions arrays into uniform fixed-size batches for pagination, batch requests, and worker dispatching. | | 6 | groupBy / groupByMap | Array | Groups elements by key or callback into a prototype-free record (Object.create(null)) or an ES6 Map. | | 7 | uniqueArray | Array | Removes duplicates while preserving order, supporting primitive fast-paths, key selectors, or deep structural equality. | | 8 | smartSort | Array | Pure stable sorting supporting multi-field ordering, natural string collation (e.g. v2 before v10), dates, and null placement. | | 9 | debounce | Async | Delays callback execution until after a quiet period, supporting leading/trailing edges, maxWait guarantees, cancel(), and flush(). | | 10 | throttle | Async | Regulates execution frequency to at most once per time window with configurable leading/trailing edges. | | 11 | retry | Async | Automatically retries failed async tasks with exponential/linear backoff, full/half jitter, error filters, and AbortSignal support. | | 12 | promiseTimeout | Async | Enforces execution deadlines, rejecting with TimeoutError or triggering fallback handlers with automated timer teardown. | | 13 | AsyncQueue | Async | Concurrency-limited worker queue supporting priority scheduling, per-task timeouts, pause/resume, and lifecycle hooks (onIdle). |


Installation

# Using npm
npm install @kjangid/array-async-tools

# Using pnpm
pnpm add @kjangid/array-async-tools

# Using yarn
yarn add @kjangid/array-async-tools

# Using bun
bun add @kjangid/array-async-tools

For global CLI usage:

npm install -g @kjangid/array-async-tools

Quick Start

import {
  deepClone,
  deepEqual,
  objectDiff,
  objectClean,
  chunk,
  groupBy,
  uniqueArray,
  smartSort,
  debounce,
  throttle,
  retry,
  promiseTimeout,
  AsyncQueue,
} from "@kjangid/array-async-tools";

// 1. Safe Deep Cloning (Handles circular references)
const graph: any = { name: "Node A" };
graph.self = graph;
const clonedGraph = deepClone(graph);
console.log(clonedGraph.self === clonedGraph); // true (independent clone)

// 2. Structural Deep Equality
console.log(deepEqual({ a: [1, 2], d: new Date(0) }, { a: [1, 2], d: new Date(0) })); // true

// 3. Object Diffing
const before = { id: 1, config: { theme: "light", debug: false } };
const after = { id: 1, config: { theme: "dark", port: 8080 } };
const diff = objectDiff(before, after);
// diff.updated -> { 'config.theme': { before: 'light', after: 'dark' } }
// diff.removed -> { 'config.debug': false }
// diff.added   -> { 'config.port': 8080 }

// 4. Object Cleaning
const dirty = { name: "Alice", bio: "", role: null, flags: [] };
const clean = objectClean(dirty, { emptyStrings: true, emptyArrays: true });
// { name: 'Alice' }

// 5. Array Chunking
const batches = chunk([1, 2, 3, 4, 5], 2);
// [[1, 2], [3, 4], [5]]

// 6. Resilient Async Retries
const data = await retry(
  async ({ attempt }) => {
    return await fetchUserData(attempt);
  },
  { retries: 3, backoff: "exponential", factor: 2 },
);

Subpath Imports (Tree-Shaking)

To minimize bundle size in web applications, each utility can be imported individually via dedicated subpaths:

import { deepClone } from "@kjangid/array-async-tools/deep-clone";
import { deepEqual } from "@kjangid/array-async-tools/deep-equal";
import { objectDiff } from "@kjangid/array-async-tools/object-diff";
import { objectClean } from "@kjangid/array-async-tools/object-clean";
import { chunk } from "@kjangid/array-async-tools/chunk";
import { groupBy } from "@kjangid/array-async-tools/group-by";
import { uniqueArray } from "@kjangid/array-async-tools/unique-array";
import { smartSort } from "@kjangid/array-async-tools/smart-sort";
import { debounce } from "@kjangid/array-async-tools/debounce";
import { throttle } from "@kjangid/array-async-tools/throttle";
import { retry } from "@kjangid/array-async-tools/retry";
import { promiseTimeout } from "@kjangid/array-async-tools/promise-timeout";
import { AsyncQueue } from "@kjangid/array-async-tools/async-queue";

CLI Toolkit

The package provides a unified binary oa-tools along with dedicated binary aliases for standard command-line data processing:

# Display CLI help
oa-tools --help

# Piped stdin: chunk array into batches of 2
cat users.json | oa-tools chunk --size 2

# Compare two JSON files
oa-tools equal file1.json file2.json

# View JSON structural diff (exits with code 1 if changed with --check)
oa-tools diff file1.json file2.json --check

# Clean empty fields from payload
cat input.json | oa-tools clean --empty-strings --empty-objects

# Sort dataset naturally by a property
oa-tools sort records.json --by version --order asc

# Run an external command with retry logic
oa-tools retry --retries 3 --delay 2000 -- curl -f https://api.example.com/health

# Run an external command with a timeout deadline (milliseconds)
oa-tools timeout --ms 5000 -- npm test

Exit Codes

  • 0: Success (or identical structures).
  • 1: Operation failure / Difference detected with --check / Task execution failed.
  • 2: CLI usage syntax error / Missing required arguments.

Security Architecture

  1. Prototype Pollution Protection:
    • Traversal logic in deepClone, objectClean, and objectDiff explicitly skips __proto__, prototype, and constructor properties.
    • groupBy returns prototype-less dictionaries created via Object.create(null) so grouping on attacker-controlled keys (e.g. '__proto__') cannot poison Object prototypes.
  2. Safe Object Creation:
    • Exported createSafeRecord() and safeAssign() utilities ensure zero prototype pollution across object transformations.
  3. Timer Teardown:
    • promiseTimeout, retry, debounce, and throttle actively remove listeners and clear pending timers immediately on resolution, rejection, or abort, eliminating event-loop memory leaks.

NPM Scripts

| Script | Command | Purpose | | ---------------- | ----------------------------------------------- | ----------------------------------------------- | | lint | tsc --noEmit | Strict TypeScript typechecking as linter gate. | | build | tsup | Compiles dual ESM/CJS and .d.ts declarations. | | test | vitest run | Executes all 18 test suites once. | | test:watch | vitest | Runs Vitest in interactive watch mode. | | test:coverage | vitest run --coverage | Generates V8 code coverage reports. | | typecheck | tsc --noEmit | Strict TypeScript compiler validation. | | bump:patch | npm version patch | Increments patch version & creates git tag. | | bump:minor | npm version minor | Increments minor version & creates git tag. | | bump:major | npm version major | Increments major version & creates git tag. | | prepublishOnly | npm run lint && npm run test && npm run build | Automated pre-release verification pipeline. | | publish:dry | npm publish --dry-run | Verifies tarball contents without publishing. |


Release & Publishing (CI/CD)

This repository includes a production-ready, completely free CI/CD pipeline using GitHub Actions, npm Trusted Publishing (OIDC), and GitHub Releases. No static secrets (NPM_TOKEN) are stored in GitHub.

Release Workflow

npm version patch | minor | major
              ↓
    git push --follow-tags
              ↓
      GitHub tag v1.2.3
              ↓
        GitHub Actions
              ↓
  npm ci → lint → test → build → verify tag
              ↓
   npm publish (OIDC + Provenance)
              ↓
        GitHub Release
  1. Bump Version: Never manually edit version in package.json. Use npm version:

    npm version patch   # Bug fixes (e.g. 1.0.0 -> 1.0.1)
    # or
    npm version minor   # New backwards-compatible features (1.0.0 -> 1.1.0)
    # or
    npm version major   # Breaking changes (1.0.0 -> 2.0.0)

    This automatically updates package.json, creates a Git commit, and creates a signed Git tag vX.Y.Z.

  2. Push Commit & Tag:

    git push --follow-tags
  3. Automated Publishing:

    • The .github/workflows/release.yml workflow triggers on the v* tag.
    • Verifies the Git tag matches package.json version.
    • Runs npm ci → npm run lint → npm test → npm run build.
    • Publishes to npm using OpenID Connect (OIDC) with provenance attestation.
    • Automatically drafts and publishes a GitHub Release with auto-generated release notes.

One-Time npm Trusted Publishing Configuration

Before your first release, configure npmjs.com to trust GitHub Actions:

  1. Log in to npmjs.com.
  2. Navigate to your package settings: https://www.npmjs.com/package/@kjangid/array-async-tools/access (or go to Account Settings → Trusted Publishers if creating the package for the first time).
  3. Under Trusted Publishers, click "Add Trusted Publisher" and select "GitHub Actions".
  4. Configure the publisher:
    • GitHub Organization / User: kajangid
    • Repository: ObjectArrayAsyncTools
    • Workflow filename: release.yml
    • Environment: (leave blank)
  5. Click "Add Publisher".

Once configured, releases occur automatically via Git tags without managing or rotating API tokens.


Documentation Index

  • Architecture Guide: Runtime design, memory models, module decomposition, and bundling design.
  • Installation Guide: Setup instructions for Node, Bun, Deno, Browsers, and Cloudflare Workers.
  • Features Reference: Comprehensive API reference, type signatures, and real-world code examples for all 13 tools.
  • Limitations & Boundaries: Edge cases, recursion boundaries, memory limits, and performance considerations.
  • Testing & Quality Guide: Test matrix, coverage reports, and security attack test cases.
  • Deployment Guide: Step-by-step npm release workflow, automated CI/CD, and publishing checklist.

License

MIT © Karan Jangid