customfunctionlib
v1.0.0
Published
TypeScript utilities
Downloads
12
Readme
customfunctionlib
A production-focused, zero-dependency TypeScript functional utility library with:
- Immutability-first behavior (no mutation of input arrays/objects)
- Clean, readable loop-based implementations
- Polymorphic utilities (
find,pluck) - Simple Lens utilities (
lens,view,set) - 100% Jest coverage (including branch coverage)
1) Project Goal
This library was built from scratch to provide common functional utilities in TypeScript without relying on Array.prototype.map/filter/reduce internally.
Key principles followed:
- Keep implementation easy to read (mid-level developer style)
- Avoid over-engineering and advanced TS tricks
- Use simple runtime checks (
typeof,Array.isArray) for polymorphism - Ensure immutability with explicit tests
2) Exact Commands Used (from scratch)
Run these in order:
npm init -y
npm install -D typescript jest ts-jest @types/jest
npx tsc --init
npx ts-jest config:init
npm test
npm run buildWhat each command does
npm init -y- Creates
package.jsonwith default fields.
- Creates
npm install -D typescript jest ts-jest @types/jest- Installs TypeScript compiler, Jest test runner,
ts-jestbridge, and Jest typings.
- Installs TypeScript compiler, Jest test runner,
npx tsc --init- Generates
tsconfig.json.
- Generates
npx ts-jest config:init- Generates
jest.config.jsconfigured for TypeScript tests.
- Generates
npm test- Runs Jest with coverage, validates behavior and coverage thresholds.
npm run build- Compiles
srcTypeScript intodistJavaScript + declaration files.
- Compiles
3) Folder Structure
customFunctionlib/
├─ src/
│ ├─ map.ts
│ ├─ filter.ts
│ ├─ reduce.ts
│ ├─ reduceRight.ts
│ ├─ some.ts
│ ├─ every.ts
│ ├─ find.ts
│ ├─ pluck.ts
│ ├─ lens.ts
│ └─ index.ts
├─ tests/
│ ├─ map.test.ts
│ ├─ filter.test.ts
│ ├─ reduce.test.ts
│ ├─ reduceRight.test.ts
│ ├─ some.test.ts
│ ├─ every.test.ts
│ ├─ find.test.ts
│ ├─ pluck.test.ts
│ └─ lens.test.ts
├─ dist/
├─ jest.config.js
├─ tsconfig.json
└─ package.json4) Implementation Strategy
Foundation Functions
Implemented using plain for loops and new result containers:
map(transform, array)filter(predicate, array)reduce(reducer, initialValue, array)reduceRight(reducer, initialValue, array)some(predicate, array)every(predicate, array)
Behavior details:
null/undefinedinputs are handled safely.- No mutation of input arrays.
- Fresh arrays/values returned.
every([])returnstrue(native JS semantics).
Polymorphic find
Supports two signatures:
- Predicate mode:
find(users, user => user.id === 1)
- Key-value mode:
find(users, 'name', 'Vishnu')
Implementation uses runtime dispatch:
- If second argument is a function → predicate mode
- Otherwise → key/value mode
Polymorphic pluck
Supports:
- Single key:
pluck('id', data) - Deep path:
pluck('info.email', data) - Multi-key:
pluck(['id', 'tags'], data)
Implementation details:
- Dot path parsing with
split('.') - Safe deep traversal returning
undefinedfor missing values - Multi-key mode returns newly created shallow-picked objects
Lens Utilities
Implemented:
lens(path: string)view(lens, object)set(lens, value, object)
Design:
- Path format: dot notation (
profile.settings.theme) viewreads safely from nested pathssetclones branch-by-branch and writes new value without mutating source- Missing path segments are created during
set
5) Testing Strategy
Jest tests were created for every function with:
- Normal functional cases
- Edge cases:
- Empty arrays
null/undefinedinputs- Missing deep paths
- Immutability checks:
- Input arrays/objects are compared before and after calls
Coverage config enforces strict thresholds:
- 100% statements
- 100% branches
- 100% functions
- 100% lines
This is configured in jest.config.js under coverageThreshold.global.
6) TypeScript Build Configuration
tsconfig.json is configured for package builds:
outDir: "dist"→ compiled JS goes todist/declaration: true→ generates.d.tsfilesrootDir: "src"→ compiles only library sourcetypes: ["jest", "node"]→ test typing support
Why this matters:
distkeeps build artifacts separate from source.d.tsgives consumers IDE IntelliSense and type safety
7) package.json Setup
Important fields:
main: "dist/index.js"types: "dist/index.d.ts"sideEffects: falsescripts.build: "tsc"scripts.test: "jest --coverage"
Why these are important:
mainpoints Node/bundlers to compiled entrytypesenables TypeScript auto type discoverysideEffects: falsehelps bundlers tree-shake unused exports
8) How to Use Locally
Build
npm run buildTest with coverage
npm testImport examples
import { map, filter, find, pluck, lens, view, set } from 'customfunctionlib';
const numbers = [1, 2, 3];
const doubled = map((n) => n * 2, numbers);
const active = filter((n) => n > 1, numbers);
const users = [{ id: 1, name: 'Vishnu' }, { id: 2, name: 'Guest' }];
const user1 = find(users, (u) => u.id === 1);
const userByName = find(users, 'name', 'Guest');
const data = [{ id: 1, info: { email: '[email protected]' } }];
const ids = pluck('id', data);
const emails = pluck('info.email', data);
const themeLens = lens('profile.settings.theme');
const user = { profile: { settings: { theme: 'light' } } };
const theme = view(themeLens, user);
const updated = set(themeLens, 'dark', user);9) Publish to npm
Step 1: Create npm account
- Sign up at https://www.npmjs.com/
Step 2: Login from terminal
npm loginStep 3: Publish
npm publish --access publicNote: If package name is already taken, update
nameinpackage.jsonfirst.
10) Versioning (SemVer)
Use standard SemVer:
1.0.0→ first stable release1.0.1→ bug fix (patch)1.1.0→ backward-compatible feature2.0.0→ breaking changes
Helpful commands:
npm version patch
npm version minor
npm version major11) Post-publish Verification
In another project:
npm install customfunctionlibThen run a quick smoke test:
import { map } from 'customfunctionlib';
console.log(map((n) => n + 1, [1, 2, 3])); // [2, 3, 4]If this works and types resolve in editor, publish is good.
12) Bundle Size Verification (recommended)
As part of optimization checks, verify package impact using:
- https://pkg-size.dev/
This helps confirm the library stays lightweight and tree-shakable.
13) Final Notes
This project intentionally keeps code straightforward:
- No advanced FP libraries
- No heavy abstractions
- No unnecessary TypeScript complexity
The current implementation is production-friendly, test-verified, and ready for npm publishing. #� �c�u�s�t�o�m�f�u�n�c�t�i�o�n�l�i�b� � �
