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 🙏

© 2025 – Pkg Stats / Ryan Hefner

dbl-utils

v1.0.21

Published

Utilities for dbl, adba and others projects

Readme

dbl-utils

dbl-utils is a JavaScript/TypeScript utility library designed to simplify common application development tasks. This collection includes functions for event handling, queue processing, text manipulation, and date and currency formatting, among others.

Documentation DeepWiki Analysis

Table of Contents

Installation

You can install dbl-utils via npm:

npm install dbl-utils

Or using yarn:

yarn add dbl-utils

Usage

Import the modules and functions in your project as needed. Below is a basic example of how to use dbl-utils:

// Import individual functions
import { formatCurrency, flatten, t } from 'dbl-utils';
// Use functions
console.log(formatCurrency(1234.56)); // Example of currency formatting
console.log(flatten({ a: { b: { c: 1 } } })); // Converts a nested object into a flat object

Minimal example of the CLI logic for CSS purging:

import purgeCss from 'dbl-utils/src/purge-css';
purgeCss('styles.css', 'index.html', 'clean.css');

Imports directly from any file to don't include all:

CommonJS use /dist/cjs/*

// Import individual functions
const i18n = require('dbl-utils/dist/cjs/i18n');
// Use functions
console.log(i18n.formatCurrency(1234.56));

ESM use /dist/esm/*

// Import individual functions
import t, { formatCurrency } from 'dbl-utils/dist/esm/i18n';
// Use functions
console.log(i18n.formatCurrency(1234.56));

TypeScript use /src/*

// Import individual functions
import t, { formatCurrency } from 'dbl-utils/src/i18n';
// Use functions
console.log(i18n.formatCurrency(1234.56));

For a complete reference of all available functions, visit the full documentation here.

Main Modules

Below are the main modules available in dbl-utils:

Utilities

event-handler

Decouple communication by subscribing to and dispatching custom events.

import { EventHandler } from 'dbl-utils';

const handler = new EventHandler();
handler.subscribe('ping', msg => console.log(msg), 'id'); // listen to events
await handler.dispatch('ping', 'pong'); // emit an event
handler.unsubscribe('ping', 'id'); // stop listening

fetch-queue

Deduplicate concurrent HTTP calls so the same request is only made once.

import FetchQueue from 'dbl-utils/src/fetch-queue';

const queue = new FetchQueue(fetch);
const [a, b] = await Promise.all([
  queue.addRequest('https://example.com'),
  queue.addRequest('https://example.com')
]);
// a === b

flat

Convert nested objects to and from dot notation.

import { flatten, unflatten } from 'dbl-utils';

flatten({ a: { b: 1 } }); // { 'a.b': 1 }
unflatten({ 'a.b': 1 }); // { a: { b: 1 } }

format-value

Format numbers, dates, or dictionary entries using locale-aware helpers.

import formatValue from 'dbl-utils/src/format-value';

formatValue(1000, { format: 'currency', currency: 'USD' }); // "$1,000.00"

i18n

Manage dictionaries and locale-aware formatting.

import t, { addDictionary, setLang, formatDate } from 'dbl-utils';

addDictionary({ es: { hello: 'Hola' } });
setLang('es');
t('hello'); // 'Hola'
formatDate(); // date formatted in Spanish

object-mutation

Combine and transform objects without modifying the originals.

import { deepMerge, mergeWithMutation, transformJson } from 'dbl-utils';

deepMerge({}, { a: 1 }, { b: 2 }); // merge nested structures
await mergeWithMutation({ a: { b: 1 } }, { mutation: () => ({ c: 2 }) }); // async mutation
transformJson({ a: { b: 1 } }, { filter: 'a' }); // extract subset

resolve-refs

Advanced reference resolution system for dynamic object composition and template inheritance. Perfect for configuration management, content templating, and complex data transformations.

Core Features

  • 🌐 Global References: Access any value in your data schema
  • 🔗 Relative References: Reference values within the current object context
  • 📝 String Interpolation: Embed references within strings seamlessly
  • 🎨 Template Inheritance: Create reusable object templates with property overrides
  • ⚙️ Custom Rules & Tasks: Define advanced transformation logic
  • 🔄 Recursive Resolution: Handle complex nested reference chains

Reference Types

1. Global References

const config = { api: { url: "https://api.com", key: "secret" } };
const settings = {
  endpoint: "$api/url",           // Direct reference → "https://api.com"
  auth: "Bearer ${api/key}",      // String interpolation → "Bearer secret"
  full: "${api/url}/v1/users"     // Mixed interpolation → "https://api.com/v1/users"
};

2. Template Inheritance

const data = {
  // Base template
  userTemplate: { name: "Guest", role: "viewer", active: false },
  
  // Inherit and override properties
  admin: { ref: "$userTemplate", name: "Admin", role: "admin", active: true },
  john: { ref: "$userTemplate", name: "John Doe" }
};

const result = resolveRefs(data);
// result.admin = { name: "Admin", role: "admin", active: true }
// result.john = { name: "John Doe", role: "viewer", active: false }

3. Relative References with Template System

const data = {
  user1: { ref: "$templates/user", firstName: "Alice", lastName: "Smith" },
  user2: { ref: "$templates/user", firstName: "Bob", lastName: "Jones" },
  
  templates: {
    user: {
      firstName: "",
      lastName: "",
      ".": {
        // These resolve AFTER template merging
        fullName: "${./firstName} ${./lastName}",           // Relative interpolation
        email: "${./firstName}.${./lastName}@company.com",  // Complex relative refs
        profile: {
          displayName: "$./fullName",    // Reference to another relative ref
          initials: "${./firstName/0}${./lastName/0}"  // Access array/string indices
        }
      }
    }
  }
};

const result = resolveRefs(data);
// result.user1.fullName = "Alice Smith"
// result.user1.email = "[email protected]"  
// result.user1.profile.displayName = "Alice Smith"
// result.user1.profile.initials = "AS"

Advanced Usage

Configuration Management

const config = {
  // Environment settings
  env: { 
    name: "production",
    domain: "myapp.com",
    apiVersion: "v2"
  },
  
  // Service definitions using templates
  services: {
    auth: { ref: "$templates/service", path: "/auth", timeout: 5000 },
    users: { ref: "$templates/service", path: "/users", port: 8080 },
    payments: { ref: "$templates/service", path: "/payments", ssl: true }
  },
  
  templates: {
    service: {
      path: "/",
      port: 3000,
      timeout: 30000,
      ssl: false,
      ".": {
        // Dynamic URL generation
        baseUrl: "http${./ssl ? 's' : ''}://${env/domain}:${./port}",
        fullUrl: "${./baseUrl}/${env/apiVersion}${./path}",
        
        // Service configuration
        config: {
          endpoint: "$./fullUrl",
          timeout: "$./timeout",
          retries: 3,
          headers: {
            "X-Service-Name": "${env/name}",
            "X-API-Version": "${env/apiVersion}"
          }
        }
      }
    }
  }
};

const result = resolveRefs(config);
// result.services.auth.fullUrl = "http://myapp.com:3000/v2/auth"
// result.services.users.fullUrl = "http://myapp.com:8080/v2/users"
// result.services.payments.fullUrl = "https://myapp.com:3000/v2/payments"

Custom Rules and Tasks

const data = {
  users: ["Alice", "Bob", "Charlie"],
  products: [{ name: "Widget", price: 10 }, { name: "Gadget", price: 25 }]
};

const template = {
  welcomeMessage: "$greetUsers",
  productSummary: "$summarizeProducts",
  totalValue: "$calculateTotal"
};

// Define custom processing rules
const rules = {
  "$greetUsers": ["join", "$users", " and "],
  "$summarizeProducts": ["iterate", "$products", "product"],
  "$calculateTotal": ["sum", "$products", "price"]
};

// Custom task implementations
const extraTasks = {
  sum: (array: any[], property: string) => 
    array.reduce((total, item) => total + item[property], 0),
  
  format: (template: string, ...values: any[]) =>
    template.replace(/{(\d+)}/g, (_, i) => values[i]),
    
  conditional: (condition: boolean, trueVal: any, falseVal: any) =>
    condition ? trueVal : falseVal
};

const result = resolveRefs(template, data, rules, extraTasks);
// result.welcomeMessage = "Alice and Bob and Charlie"
// result.totalValue = 35

Built-in Tasks

  • iterate(array, itemName) - Process array items with current schema context
  • join(values, separator, ...extras) - Join arrays or concatenate values
  • ignore(path, fallback) - Safe property access with fallback values
  • if(condition, trueValue, falseValue) - Conditional value resolution

API Reference

resolveRefs<T>(
  object: ResolvableValue,      // Object/array with references to resolve
  schema?: Record<string, any>, // Base schema for global references
  rules?: ResolveRefsRules,     // Custom rule definitions
  extraTasks?: ResolveRefsTasks // Additional task implementations
): T

Best Practices

  1. 🏗️ Structure: Organize templates in dedicated sections (e.g., templates/, definitions/)
  2. 📋 Naming: Use descriptive paths like config/database/url over abbreviated versions
  3. 🎯 Performance: Avoid deep circular references and excessive nesting
  4. 🔒 Type Safety: Define TypeScript interfaces for your schema structure
  5. 🧪 Testing: Test complex reference chains with various data combinations

Real-World Examples

For comprehensive examples and advanced use cases, see the detailed examples documentation.

  • Multi-environment Configuration: Different API endpoints per environment
  • Component Templates: Reusable UI component configurations
  • Dynamic Content: Blog posts with shared metadata and custom overrides
  • API Documentation: Auto-generated endpoint documentation from templates
  • Feature Flags: Conditional configuration based on environment/user settings

utils

sliceIntoChunks

Split an array into smaller arrays for batching.

import { sliceIntoChunks } from 'dbl-utils';
sliceIntoChunks([1,2,3,4],2); // [[1,2],[3,4]]

splitAndFlat

Turn a list of strings into unique tokens.

import { splitAndFlat } from 'dbl-utils';
splitAndFlat(['a b','c']); // ['a','b','c']

generateRandomColors

Generate distinct colors for visualizations.

import { generateRandomColors } from 'dbl-utils';
generateRandomColors(2); // ['#aabbcc', '#ddeeff']

evaluateColorSimilarity

Check how close colors are to each other.

import { evaluateColorSimilarity } from 'dbl-utils';
evaluateColorSimilarity(['#fff','#ffe']); // value near 1

normalize

Remove accents and lowercase text.

import { normalize } from 'dbl-utils';
normalize('á'); // 'a'

slugify

Create URL-friendly slugs.

import { slugify } from 'dbl-utils';
slugify('Hello World'); // 'hello-world'

randomS4

Produce a short hex segment.

import { randomS4 } from 'dbl-utils';
randomS4(); // '9f3b'

randomString

Generate a random alphanumeric string.

import { randomString } from 'dbl-utils';
randomString(5); // e.g., 'abcde'

timeChunks

Build time intervals between two dates.

import { timeChunks } from 'dbl-utils';
timeChunks({ from:'2020-01-01', to:'2020-01-02', step:3600 }); // [...]

delay

Pause execution for a given time.

import { delay } from 'dbl-utils';
await delay(10); // waits 10ms

hash

Generate a numeric hash.

import { hash } from 'dbl-utils';
hash('data'); // 123456789

LCG

Deterministic pseudo-random number generator.

import { LCG } from 'dbl-utils';
const gen = new LCG(123);
gen.random(); // 0.5967...

Documentation

For a detailed description of each module and function, visit the full documentation automatically generated with Typedoc. The documentation includes usage examples and in-depth explanations of each function.

For an in-depth analysis of the project architecture, codebase structure, and implementation details, check out the comprehensive DeepWiki analysis.

Testing

Run the test suite with:

npm test

This project uses Jest with ts-jest. New tests cover the i18n and object-mutation modules.

Recent Changes

  • Comprehensive resolve-refs documentation: Completely redesigned documentation with:
    • Enhanced JSDoc comments with detailed examples and use cases
    • Full TypeScript type definitions and interfaces
    • Comprehensive README section with visual examples
    • Real-world usage examples including configuration management, API documentation, and component systems
    • Advanced examples covering feature flags, e-commerce catalogs, and multi-environment setups
  • Enhanced resolve-refs module: Added support for relative references with $./ and ${./} syntax
    • New template system using the "." key for relative references
    • Ability to create reusable templates that can be extended with different values
    • Support for references that point to other references (recursive resolution)
    • Comprehensive unit tests covering all relative reference scenarios
  • Fixed handling of numeric keys in unflatten so arrays are reconstructed correctly.
  • Added unit tests for the i18n and object-mutation modules.
  • Expanded coverage with additional tests for utils, format-value, and i18n.

TODO

  • Move number compact formatting to the i18n module.

Development & Testing

When developing or debugging tests, use yarn test -- <pattern> to run only the relevant test cases.

License

This project is under the ISC license. See the LICENSE file for more details.