# Puffy Core

A collection of ES6 modules with zero dependencies to help manage common programming tasks in both Node.js and native JavaScript.

> **Using an AI assistant?** This project provides LLM-optimized documentation. Give your AI one of the links below and it will figure out the rest.
>
> | Module | LLM Doc |
> |---|---|
> | **All modules** (start here) | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms.txt` |
> | **error** — catchErrors, wrapErrors, PuffyResponse | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/error.txt` |
> | **func** — chainAsync, chainSync | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/func.txt` |
> | **collection** — batch, uniq, sortBy, flatten | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/collection.txt` |
> | **obj** — merge, diff, same, getProperty | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/obj.txt` |
> | **converter** — toNumber, toBoolean, case conversion | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/converter.txt` |
> | **crypto** — encoder, jwtDecode | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/crypto.txt` |
> | **date** — formatDate, addDays, getTimeDiff, toTz | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/date.txt` |
> | **math** — avg, median, percentile, getRandomNumber | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/math.txt` |
> | **string** — plural, justifyLeft, safeStringify | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/string.txt` |
> | **db** — newId (BigInt) | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/db.txt` |
> | **time** — delay, Timer | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/time.txt` |
> | **logger** — log | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/logger.txt` |
> | **url** — getUrlParts | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/url.txt` |
> | **validate** — validateUrl, validateEmail | `https://raw.githubusercontent.com/nicolasdao/puffy-core/master/llms/validate.txt` |

> **Note:**
> - Requires Node.js >= 13. For Node.js 12, use the `--experimental-modules` flag.
> - As of v1.3.0, all APIs are available in both camelCase and snake_case (e.g., `newId()` and `new_id()`).

## Table of Contents
- [Overview](#overview)
- [Getting Started](#getting-started)
  - [Installation](#installation)
  - [Import Patterns](#import-patterns)
- [Modules at a Glance](#modules-at-a-glance)
- [Project Structure](#project-structure)
- [Documentation](#documentation)
- [Dev](#dev)
  - [Building](#building)
  - [Linting](#linting)
  - [Testing](#testing)
  - [Releasing](#releasing)
- [Creating URLs with the URL Object](#creating-urls-with-the-url-object)
- [License](#license)

## Overview

Puffy Core provides 14 utility modules covering collections, data conversion, cryptography, dates, database IDs, error handling, functional programming, logging, math, objects, strings, time, URLs, and validation. All modules have zero external dependencies and support both ES Modules (`import/export`) and CommonJS (`require`) via the `exports` and `main` fields in `package.json`.

## Getting Started

### Installation

```
npm i puffy-core
```

### Import Patterns

**ES Modules** -- import individual functions from specific modules:

```js
import { batch, uniq, sortBy } from 'puffy-core/collection'
import { catchErrors, wrapErrors } from 'puffy-core/error'
import { newId } from 'puffy-core/db'
```

**CommonJS** -- destructure from the main entry point:

```js
const { collection, error, db } = require('puffy-core')

collection.batch([1,2,3,4,5], 2) // [[1,2], [3,4], [5]]
error.catchErrors(() => riskyOperation())
db.newId() // 1737111960607002926n
```

## Modules at a Glance

| Module | Import Path | Key Functions | Description |
|---|---|---|---|
| **collection** | `puffy-core/collection` | `batch`, `uniq`, `sortBy`, `flatten`, `flattenUniq`, `seed`, `headTail`, `levelUp` | Array utilities: batching, deduplication, sorting, flattening |
| **converter** | `puffy-core/converter` | `addZero`, `nbrToCurrency`, `s2cCase`, `c2sCase`, `objectC2Scase`, `objectS2Ccase`, `toNumber`, `toBoolean`, `toObj`, `toArray` | Type conversion, case conversion, currency formatting |
| **crypto** | `puffy-core/crypto` | `encoder`, `jwtDecode` | Encoding (base64, hex, bin, buffer) and JWT decoding |
| **date** | `puffy-core/date` | `addDays`, `addMonths`, `addYears`, `formatDate`, `getTimeDiff`, `toTz` | Date arithmetic, formatting, timezone conversion |
| **db** | `puffy-core/db` | `newId` | Monotonically increasing BigInt ID generation |
| **error** | `puffy-core/error` | `catchErrors`, `wrapErrors`, `wrapErrorsFn`, `wrapCustomErrors`, `mergeErrors`, `getErrorMetadata`, `required` | Functional error handling with `[errors, data]` tuples |
| **func** | `puffy-core/func` | `chainAsync`, `chainSync` | Function chaining with automatic error propagation |
| **logger** | `puffy-core/logger` | `log` | Structured JSON logging |
| **math** | `puffy-core/math` | `avg`, `stdDev`, `median`, `percentile`, `getRandomNumber`, `getRandomNumbers` | Statistics and random number generation |
| **obj** | `puffy-core/obj` | `merge`, `diff`, `same`, `exists`, `isEmpty`, `getType`, `setProperty`, `getProperty`, `extractFlattenedJSON` | Deep merge, diff, equality, nested property access |
| **string** | `puffy-core/string` | `plural`, `justifyLeft`, `safeStringify` | Pluralization, text alignment, BigInt-safe JSON |
| **time** | `puffy-core/time` | `delay`, `Timer` | Cancellable delays and time measurement |
| **url** | `puffy-core/url` | `getUrlParts` | URL parsing with extra convenience properties |
| **validate** | `puffy-core/validate` | `validateUrl`, `validateEmail`, `validateDate`, `validateSpecialChar` | Input validation for URLs, emails, dates, special chars |

## Project Structure

```
puffy-core/
├── src/                  # ES6 module source files
│   ├── index.mjs         # Re-exports all modules as namespaces
│   ├── collection.mjs    # Array utilities
│   ├── converter.mjs     # Type and case converters
│   ├── crypto.mjs        # Encoding and JWT
│   ├── date.mjs          # Date arithmetic and formatting
│   ├── db.mjs            # BigInt ID generation
│   ├── error.mjs         # Functional error handling (PuffyResponse)
│   ├── func.mjs          # Function chaining (depends on error.mjs)
│   ├── logger.mjs        # Structured logging (depends on string.mjs)
│   ├── math.mjs          # Statistics and random numbers
│   ├── obj.mjs           # Object utilities
│   ├── string.mjs        # String utilities
│   ├── time.mjs          # Delays and timers
│   ├── url.mjs           # URL parsing
│   └── validate.mjs      # Input validation
├── dist/                 # Rollup-compiled CommonJS output
├── test/                 # Mocha test files (one per module)
├── index.mjs             # Dev/example entry point
├── rollup.config.js      # Rollup config: src/**/*.mjs -> dist/*.cjs
└── package.json          # Dual ESM/CJS exports
```

Most modules are fully standalone. Only two internal dependencies exist:
- `func.mjs` imports from `error.mjs`
- `logger.mjs` imports from `string.mjs`

## Documentation

| Document | Description |
|---|---|
| [API Reference](docs/api.md) | Complete reference for all 14 modules with function signatures and usage examples |
| [Error Handling Guide](docs/error-handling.md) | In-depth guide to the PuffyResponse pattern, `catchErrors`, error wrapping, chaining, and partial-success responses |
| [LLM System Prompts](docs/llm-prompts.md) | Premade system prompts for coding agents to learn puffy-core's error handling APIs |
| [Gotchas](docs/gotchas.md) | Index of non-obvious behavior and pitfalls, organized by domain |

## Dev

### Building

Compile ES6 modules to CommonJS:

```
npm run build
```

This uses [Rollup](https://rollupjs.org/) to compile `src/**/*.mjs` to `.cjs` files in the `dist/` directory.

### Linting

```
npm run lint
```

### Testing

```
npm test
```

Runs [Mocha](https://mochajs.org/) tests from the `test/` directory.

### Releasing

```
npm run rls -- <major|minor|patch>
npm run push
```

Uses [standard-version](https://github.com/conventional-changelog/standard-version) for changelog generation and version bumping, then builds, pushes, and publishes to npm.

## Creating URLs with the URL Object

The `URL` is a native object supported in both browser and Node.js environments:

```js
const u = new URL('https://example.com')
u.pathname = 'blog'
u.searchParams.set('hello', 'world')
u.hash = 'footer'
console.log(u.toString()) // 'https://example.com/blog?hello=world#footer'
```

## License

BSD 3-Clause License

Copyright (c) 2019-2021, Cloudless Consulting Pty Ltd. All rights reserved.

See [LICENSE](LICENSE) for the full text.
