UNPKG

dbl-utils

Version:

Utilities for dbl, adba and others projects

508 lines (383 loc) โ€ข 15.1 kB
# 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](https://img.shields.io/badge/docs-view-green.svg)](https://joneldiablo.github.io/dbl-utils/modules.html) [![DeepWiki Analysis](https://img.shields.io/badge/DeepWiki-analysis-blue.svg)](https://deepwiki.com/joneldiablo/dbl-utils) ## Table of Contents - [Installation](#installation) - [Usage](#usage) - [Main Modules](#main-modules) - [Utilities](#utilities) - [Documentation](#documentation) - [License](#license) ## Installation You can install `dbl-utils` via npm: ```bash npm install dbl-utils ``` Or using yarn: ```bash 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`: ```javascript // 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: ```ts 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/\*** ```javascript // Import individual functions const i18n = require('dbl-utils/dist/cjs/i18n'); // Use functions console.log(i18n.formatCurrency(1234.56)); ``` ESM use **/dist/esm/\*** ```javascript // Import individual functions import t, { formatCurrency } from 'dbl-utils/dist/esm/i18n'; // Use functions console.log(i18n.formatCurrency(1234.56)); ``` TypeScript use **/src/\*** ```javascript // 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](https://joneldiablo.github.io/dbl-utils/modules.html). ## Main Modules Below are the main modules available in `dbl-utils`: - [event-handler](https://github.com/joneldiablo/dbl-utils/blob/master/src/event-handler.ts) - [fetch-queue](https://github.com/joneldiablo/dbl-utils/blob/master/src/fetch-queue.ts) - [flat](https://github.com/joneldiablo/dbl-utils/blob/master/src/flat.ts) - [format-value](https://github.com/joneldiablo/dbl-utils/blob/master/src/format-value.ts) - [i18n](https://github.com/joneldiablo/dbl-utils/blob/master/src/i18n.ts) - [object-mutation](https://github.com/joneldiablo/dbl-utils/blob/master/src/object-mutation.ts) - [resolve-refs](https://github.com/joneldiablo/dbl-utils/blob/master/src/resolve-refs.ts) - [utils](https://github.com/joneldiablo/dbl-utils/blob/master/src/utils.ts) ## Utilities ### event-handler Decouple communication by subscribing to and dispatching custom events. ```ts 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. ```ts 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. ```ts 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. ```ts import formatValue from 'dbl-utils/src/format-value'; formatValue(1000, { format: 'currency', currency: 'USD' }); // "$1,000.00" ``` ### i18n Manage dictionaries and locale-aware formatting. ```ts 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. ```ts 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** ```ts 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** ```ts 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** ```ts 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 = "Alice.Smith@company.com" // result.user1.profile.displayName = "Alice Smith" // result.user1.profile.initials = "AS" ``` #### Advanced Usage **Configuration Management** ```ts 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** ```ts 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 ```ts 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](./examples/resolve-refs-examples.md). - **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. ```ts import { sliceIntoChunks } from 'dbl-utils'; sliceIntoChunks([1,2,3,4],2); // [[1,2],[3,4]] ``` #### splitAndFlat Turn a list of strings into unique tokens. ```ts import { splitAndFlat } from 'dbl-utils'; splitAndFlat(['a b','c']); // ['a','b','c'] ``` #### generateRandomColors Generate distinct colors for visualizations. ```ts import { generateRandomColors } from 'dbl-utils'; generateRandomColors(2); // ['#aabbcc', '#ddeeff'] ``` #### evaluateColorSimilarity Check how close colors are to each other. ```ts import { evaluateColorSimilarity } from 'dbl-utils'; evaluateColorSimilarity(['#fff','#ffe']); // value near 1 ``` #### normalize Remove accents and lowercase text. ```ts import { normalize } from 'dbl-utils'; normalize('รก'); // 'a' ``` #### slugify Create URL-friendly slugs. ```ts import { slugify } from 'dbl-utils'; slugify('Hello World'); // 'hello-world' ``` #### randomS4 Produce a short hex segment. ```ts import { randomS4 } from 'dbl-utils'; randomS4(); // '9f3b' ``` #### randomString Generate a random alphanumeric string. ```ts import { randomString } from 'dbl-utils'; randomString(5); // e.g., 'abcde' ``` #### timeChunks Build time intervals between two dates. ```ts import { timeChunks } from 'dbl-utils'; timeChunks({ from:'2020-01-01', to:'2020-01-02', step:3600 }); // [...] ``` #### delay Pause execution for a given time. ```ts import { delay } from 'dbl-utils'; await delay(10); // waits 10ms ``` #### hash Generate a numeric hash. ```ts import { hash } from 'dbl-utils'; hash('data'); // 123456789 ``` #### LCG Deterministic pseudo-random number generator. ```ts 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](https://joneldiablo.github.io/dbl-utils/modules.html) 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](https://deepwiki.com/joneldiablo/dbl-utils). ## Testing Run the test suite with: ```bash 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.