Package Exports
- dm-std
- dm-std/src/index.ts
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (dm-std) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
dm-std
A standard library for TypeScript focused on predictability, type safety, and cross-runtime compatibility.
dm-std brings the precision of lower-level languages to TypeScript. It provides clamped numeric types to prevent logic errors, a powerful declarative command-line parser, unified file system abstractions (running seamlessly on Node, Bun, or Memory), and high-performance string scanning utilities.
It is designed for building CLIs, simulations, game logic, and robust tools where explicit data types and predictable behavior are paramount.
🚀 Key Features
- 🛡️ Clamped Numeric Types:
U8,U32, andF64implementations. Math operations (add,sub,div,pow) are clamped to bounds, preventing overflows/underflows. Includes integer-mapped trigonometry (sin,coson integers). - 💾 Universal File System: Write code once, run anywhere. Switch between Bun, Node.js, and Memory (Virtual FS) implementations instantly. Perfect for unit testing file manipulations without touching the disk.
- 💻 Robust CLI Parser: A declarative, type-safe argument parser. Supports typed values (
int,float,json,bool), validation maps, aliases, array accumulation, and deep object targeting. - ⚡ Fast String Scanning: Lookup-table based
findChar/skipCharutilities for building high-performance parsers. - 📦 Zero Dependencies: Lightweight and completely self-contained.
📦 Installation
# Bun
bun add dm-std
# NPM
npm install dm-std
# Yarn
yarn add dm-std⚡ Quick Cheat Sheet
import { U8, CmdLine, Str, Char, BunFileSystem, NodeFileSystem, MemoryFileSystem } from 'dm-std';
// --- 1. Clamped Arithmetic (U8: 0-255) ---
U8.add(250, 20); // => 255 (Clamped at MAX, no rollover)
U8.sub(5, 10); // => 0 (Clamped at MIN)
U8.div(100, 0); // => 255 (Safe division, no Infinity)
// --- 2. Universal File System ---
// Switch implementation based on environment (Disk for Prod, Memory for Test)
const fs = (process.env.NODE_ENV === 'test') ? new MemoryFileSystem() : new BunFileSystem();
await fs.writeFileAsJSON('config.json', { volume: 100 }, true); // Pretty print
await fs.streamTo('config.json', new MemoryFileSystem(), '/virtual/backup.json'); // Pipe between FS types!
// --- 3. Fast String Scanning ---
const input = "key=value; type=u8";
const DELIMITERS = Char.createList('=; '); // O(1) lookup table
// Skip spaces
const start = Str.skipChar(input, Char.createList(' '), 0);
// Find next delimiter
const next = Str.findChar(input, DELIMITERS, start);
// --- 4. CLI Parsing ---
const rawOptions = [
{ triggers: ['-p', '--port'], type: 'integer', default: 8080 },
{ triggers: ['--config'], type: 'json' } // Parses '{"a":1}' automatically
];
// Parse args (automagically handles arrays, flags, and type conversion)
const args = CmdLine.parse(
CmdLine.Options.parse(rawOptions),
process.argv.slice(2)
);📚 Core Concepts & Usage
1. The Universal File System
The FileSystem abstraction allows you to write file logic that is agnostic of the underlying storage. This is a game-changer for testing.
Implementations:
BunFileSystem: Uses native Bun I/O.NodeFileSystem: Uses Nodefs/promises.MemoryFileSystem: A complete virtual file system in RAM.
Example: Streaming from Disk to Memory
You can seamlessly pipe data between different file systems using streamTo.
import { NodeFileSystem, MemoryFileSystem } from 'dm-std';
const disk = new NodeFileSystem();
const mem = new MemoryFileSystem();
// Recursively copy a real folder into the virtual memory FS
// Useful for loading assets into a test environment
await disk.streamTo('./src/assets', mem, '/virtual/assets');
const existsInMem = await mem.exist('/virtual/assets/logo.png'); // true2. Robust Command Line Parsing
CmdLine handles complex argument parsing configurations with a simple declarative array.
Features:
- Multi-type support: Allow an option to be a
stringORjson. - Maps: Restrict inputs to a specific whitelist (e.g.,
prod,dev). - Deep Targeting: specific arguments can populate nested objects (e.g.,
--server-port->{ server: { port: 80 } }).
import { CmdLine } from 'dm-std';
const options = CmdLine.Options.parse([
{
triggers: ['-m', '--mode'],
type: 'string',
map: {
'fast': 'MODE_FAST', // Maps input 'fast' to value 'MODE_FAST'
'safe': 'MODE_SAFE'
},
default: 'MODE_SAFE'
},
{
triggers: ['--db'],
type: 'json', // Parses input string directly into an object
target: 'database.config' // Deep nesting in result
},
{
triggers: ['--tags'],
type: 'string',
isArray: true // Collects multiple usages: --tags a --tags b
}
]);
// Input: node app.js --mode fast --tags one --tags two --db '{"host":"localhost"}'
const result = CmdLine.parse(options, process.argv.slice(2));
/* Result:
{
mode: 'MODE_FAST',
database: { config: { host: 'localhost' } },
tags: ['one', 'two']
}
*/3. Predictable Math (U8, U32)
Standard JavaScript numbers are IEEE 754 floats. dm-std provides namespaces for integer arithmetic that clamps values instead of rolling over or returning Infinity.
- U8: 0 to 255.
- U32: 0 to 4,294,967,295.
Integer Trigonometry:
Functions like sin, cos, and tan in U8 and U32 map the input integer range to 0..2π and return the result mapped back to the integer range.
import { U8, U32 } from 'dm-std';
// Color Math (Safe Clamping)
const brightness = 200;
const boost = 100;
// Standard JS: 300 (Invalid color byte)
// U8: 255 (Clamped Max)
const final = U8.add(brightness, boost);
// Integer Rotation
// U32.MAX represents a full 360deg rotation (2PI)
const angle = U32.MAX / 2; // ~PI (180 degrees)
const val = U32.sin(angle); // Returns result mapped to U32 range📖 API Reference
📂 FileSystem
Interface FileSystem_Interface. Classes: BunFileSystem, NodeFileSystem, MemoryFileSystem.
All FileSystem classes accept an optional logGroup parameter in their constructor to specify a custom logging group for error messages.
| Method | Returns | Description |
|---|---|---|
readFile(path) |
Promise<Buffer> |
Read file as buffer. |
writeFile(path, data) |
Promise<boolean> |
Write buffer to file. Creates parent dirs. |
readFileAsText(path) |
Promise<string> |
Read file as UTF-8 string. |
writeFileAsText(path, txt) |
Promise<boolean> |
Write string to file. |
readFileAsJSON<T>(path) |
Promise<T> |
Read and parse JSON. |
writeFileAsJSON(path, data) |
Promise<boolean> |
Stringify and write JSON. |
createDir(path) |
Promise<void> |
Create directory (recursive). |
copy(src, dest) |
Promise<boolean> |
Recursive copy of files/folders. |
remove(path, recursive?) |
Promise<boolean> |
Delete file or directory. |
streamTo(src, fs, dest) |
Promise<boolean> |
Pipe data from this FS to another FS instance. |
exist(path) |
Promise<boolean> |
Check existence. |
getSize(path) |
Promise<number> |
Get size (bytes). Recursive for folders. |
💻 CmdLine
CmdLine.parse(options, argv)
Parses arguments based on the compiled options.
- options: Result of
CmdLine.Options.parse([...]). - argv: String array (usually
process.argv.slice(2)). - Returns:
T(result object) orstring(error message).
CmdLine.Option Configuration
| Property | Type | Description |
|---|---|---|
triggers |
string[] |
Flags to activate option (e.g., ['-f', '--force']). |
type |
string | string[] |
"integer", "float", "boolean", "json", "string", "none". |
target |
string |
Dot-notation path for result (e.g., server.port). |
isArray |
boolean |
If true, values collect into an array. |
map |
Object |
Whitelist valid inputs (e.g., { 'y': true, 'n': false }). |
default |
any |
Value used if trigger is missing. |
🔢 Numeric Types (U8, U32, F64)
Common Methods:
add(a, b),sub(a, b),mul(a, b),div(a, b): Clamped arithmetic.pow(base, exp): Power function.mod(a, b): Modulo.ter(a, b, c, d): Ternary (if a <= b return c else d).getRandom(),getRandomFromRange(min, max).
Trigonometry (U8, U32):
sin(val),cos(val),tan(val): Input is normalized from type range (0..MAX) to (0..2π). Output is denormalized back to type range.
Bitwise (U8, U32):
shl(a, b): Shift Left.shr(a, b): Logical Shift Right.
Special U32:
setSeed(seed): Sets the seed for the internal pseudo-random number generator (Xorshift).
📝 String & Char (Str, Char)
Char.createList(chars)
Creates a boolean lookup map (Record<string, boolean>) from a string or array of strings. faster than array.includes().
Str Methods:
findChar(text, charList, start?): Find index of first char present in list.skipChar(text, charList, start?): Find index of first char NOT in list.findCharRev(...)/skipCharRev(...): Reverse search from end of string.isNotFound(pos): Returns true if index is -1.
🛠️ Utilities
Obj: Helpers for deep object manipulation (get,set,clone).Err: Structured error object creation (Err.create,Err.fromError).DateTime: Simple wrappers likeDateTime.now.
📄 License
MIT License.