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

dual-floor

v0.2.2

Published

Dual-stage performance utilities for JavaScript and TypeScript.

Downloads

29

Readme

dual-floor

dual-floor is a performance toolkit for JavaScript and TypeScript.

The idea behind Dual Floor is simple:

  • Floor 1 reduces entry cost by simplifying keys, inputs, and scheduling.
  • Floor 2 reduces repeat cost by reusing work through cache, pooling, batching, and transform reuse.

It is useful for bots, APIs, CLIs, loaders, and build pipelines where the same work tends to happen over and over.

Included utilities

  • createLRUCache: bounded cache for hot-path lookups.
  • memoize: fast memoization with unbounded Map by default or bounded LRU mode.
  • createBatcher: merges many async calls into fewer operations.
  • createObjectPool: reuses objects to reduce allocation pressure.
  • createTransformCache: skips repeated compile/transform work when the source fingerprint has not changed.
  • createParallelRunner: limits concurrency so builds and transforms stay saturated without overloading the event loop.
  • createFingerprint: fast fingerprint helper for source text, config strings, or cache keys.
  • createNumberCache: array-backed cache for dense integer keys.
  • createSingleFlight: merges duplicate concurrent work into one execution.
  • createPersistentTransformCache: stores transform results on disk for repeated builds and CLI runs.
  • createCompiler: esbuild-powered transform engine with cache and parallel execution built in.
  • createHybridCache: local memory cache + shared cache with stampede protection, tag invalidation, and circuit breaker support.
  • createRedisCompatibleStore: adapts a Redis-like client to dual-floor shared cache.
  • createMemorySharedStore: local mock/shared store for tests and single-node deployments.

Install

npm install dual-floor

Usage

import {
  createBatcher,
  createCompiler,
  createHybridCache,
  createRedisCompatibleStore,
  createPersistentTransformCache,
  createSingleFlight,
  createParallelRunner,
  createTransformCache,
  memoize
} from "dual-floor";

const compileCache = createTransformCache<string, string>();

async function compileModule(id: string, source: string) {
  return compileCache.run({
    key: id,
    source,
    transform: async () => source.toUpperCase()
  });
}

const runParallel = createParallelRunner({ concurrency: 4 });

const compileMany = async (files: Array<{ id: string; source: string }>) =>
  runParallel(files, (file) => compileModule(file.id, file.source));

const commandLookup = memoize((name: string) => name.trim().toLowerCase());

const batchedFetch = createBatcher(async (ids: readonly string[]) => {
  return ids.map((id) => `resolved:${id}`);
});

const singleFlight = createSingleFlight<string, string>();

const compileShared = (id: string, source: string) =>
  singleFlight.run(id, () =>
    compileCache.run({
      key: id,
      source,
      transform: async () => source.toUpperCase()
    })
  );

const persistent = createPersistentTransformCache<string, string>({
  dir: ".dual-floor-cache"
});

const compilePersistent = (id: string, source: string) =>
  persistent.run({
    key: id,
    source,
    transform: async () => source.toUpperCase()
  });

const compiler = createCompiler({
  cacheDir: ".dual-floor-compile",
  concurrency: 4
});

const output = await compiler.compile({
  source: "const answer: number = 42",
  loader: "ts",
  format: "esm",
  target: "es2020"
});

const builtFile = await compiler.compileFile({
  inputPath: "src/index.ts",
  outputPath: "dist/index.js",
  format: "esm",
  target: "es2020",
  sourcemap: true
});

const builtProject = await compiler.compileProject({
  rootDir: "src",
  outDir: "build",
  format: "esm",
  target: "es2020",
  cleanOutDir: true
});

const shared = createRedisCompatibleStore(redisClient);

const cache = createHybridCache({
  ttl: 5_000,
  staleTtl: 30_000,
  shared,
  breaker: {
    failureThreshold: 3,
    cooldownMs: 10_000
  }
});

const profile = await cache.get(
  "user:42",
  () => fetchUserProfile(42),
  { tags: ["users", "user:42"] }
);

await cache.invalidateTag("users");

Build acceleration

createTransformCache is aimed at loaders, code generators, bundler hooks, and command compilers.

  • If the source and fingerprint are unchanged, it reuses the previous output.
  • If the content changes, it recompiles only that unit.
  • You can include compiler options in the fingerprint to invalidate safely when config changes.
  • If the same file is requested concurrently, in-flight work is reused instead of recompiled multiple times.
  • If you use createPersistentTransformCache, cached outputs can survive process restarts and speed up repeated builds.

createCompiler is the higher-level entry point when you want dual-floor to handle transform caching and parallel execution for TS/JS code directly.

  • compile: transforms a source string.
  • compileFile: reads one file, compiles it, and optionally writes the output.
  • compileProject: walks a directory and writes compiled output while preserving relative paths.

createNumberCache is the stronger hot-path option when your keys are integer IDs such as shard IDs, opcode IDs, command IDs, or compact enum indexes.

Distributed caching

createHybridCache is the enterprise cache layer for multi-instance services.

  • L1 local memory cache minimizes network round trips.
  • L2 shared cache lets instances share hot data.
  • Single-flight loading helps prevent cache stampedes.
  • Tag invalidation supports broad cache busts like users, products, or tenant:123.
  • Circuit breaker logic keeps shared-cache outages from cascading through the app.
  • Built-in stats expose hit rates, stale hits, shared errors, invalidations, and breaker state.

To use Redis, pass a Redis-like client to createRedisCompatibleStore. Any client exposing get, set, del, and optionally sAdd, sMembers, sRem, expire will work.

Benchmark

npm run bench

This compares dual-floor against common alternatives in the same local environment. Real performance depends on key shape, hit rate, transform cost, and workload pattern, so benchmark with your own input before making speed claims.