A small, TypeScript-first utility library for strongly-typed Result wrappers and helpers for working with primitive data structures. Designed to make safe function execution, error handling, and simple data struct typing ergonomic and predictable across environments.
- Package:
@monitext/ndata - License: Apache-2.0
- Goal: Provide zero-dependency utilities for Result objects, primitive data types, and small struct helpers.
| Export | Description |
|---|---|
Result | Class for success/failure results, with helpers and type guards |
Result.primitives | Factory for primitive-only results (see PrimitiveResult) |
createResult | Wraps a value or error into a result object |
createResultableFn | Wraps sync/async functions to always return results (never throws) |
D / DataTypes | Namespace for primitive types and result type definitions |
A simple class used to represent success and failure.
Result.ok<V>(v: V): IOKResult<V>
Create a success result (value present, error undefined).Result.fail(e: Error): IFailResult
Create a failure result (error present, value undefined).Result.primitives.ok<V extends PrimitiveData>(v: V): IOKResult<V>
Create a success result for primitive data.Result.primitives.fail(e: Error): IFailResult
Create a failure result for primitive data.Methods:
unwrap(): Returns value or throws errorunwrapOr(defaultValue): Returns value or defaultisOk(): Type guard for successisErr(): Type guard for failureexpect({ msg, handler, throwErr }): Custom error handling (see Error Handling Patterns)
Usage:
import{Result}from'@monitext/ndata';constsuccess=Result.ok({id: 1});constfailure=Result.fail(newError('problem'));Type shapes:
IOKResult<T>:{ value: T; error: undefined }IFailResult:{ value: undefined; error: Error | string }IResult<T>:IOKResult<T> | IFailResult
A variant intended for primitive-friendly payloads (string/number/boolean/null/undefined/symbol, arrays, and plain primitive objects).
Note: In code, use Result.primitives.ok and Result.primitives.fail for this functionality.
Result.primitives.ok(v)Result.primitives.fail(error)
Use when you want additional semantic clarity that the value is limited to primitive-style data.
Wrap a value (or an Error) into an IResult:
- If
vis anErrorinstance -> returns a failure result. - Otherwise -> returns a success result.
import{createResult}from'@monitext/ndata';constr1=createResult('ok');// successconstr2=createResult(newError());// failureThe Result class provides flexible error handling.
The .expect() method allows you to customize what happens on error:
constr=Result.fail(newError('fail!'));r.expect({msg: 'Something went wrong',handler: ({ err })=>{// Custom logic, e.g., log or transform errorreturn'default value';},throwErr: false// Prevents throwing, returns handler result});- If
handlerreturns a value, it is returned. - If
throwErris true (default) and no handler returns a value, the error is thrown. - If both are omitted, an error is thrown by default.
Creates a wrapper around the given function so that it never throws — instead it returns IResult (for sync functions) or Promise<IResult> (for async functions).
- Works with synchronous and asynchronous functions.
- Catches thrown errors and rejected promises, wrapping them as failure results.
- Preserves return typing (the function's return becomes the
valuein success results).
import{createResultableFn}from'@monitext/ndata';constsafe=createResultableFn((a: number,b: number)=>a+b);constok=safe(1,2);// IOKResult<number>constasyncSafe=createResultableFn(async()=>{constres=awaitfetch('https://...');returnres.json();});constresult=awaitasyncSafe();// Promise<IResult<any>>Notes:
- The wrapper inspects the function text to detect
async. This provides the correct return signature (sync vs async wrapper).
The D (or DataTypes) export contains type definitions and helpers:
D.Primitive— union of basic primitive typesD.PrimitiveArray— nested arrays of primitives/objectsD.PrimitiveObject— plain object with primitive/array/object valuesD.PrimitiveData— union of all primitive data shapesD.IResult<T>,D.IOKResult<T>,D.IFailResult, etc.
Example:
import*asDfrom'@monitext/ndata';// or import * as DataTypes from '@monitext/ndata'typeP=D.PrimitiveObject;Using pnpm (recommended in this monorepo)
pnpm add @monitext/ndataUsing npm
npm install @monitext/ndataUsing yarn
yarn add @monitext/ndataImport the library (TypeScript)
import{Result,createResult,createResultableFn}from'@monitext/ndata';import*asDfrom'@monitext/ndata/src/lib/data-types';// or `import * as D from '@monitext/ndata'` when consumed via packageCreate success/failure Results:
constok=Result.ok(42);// { value: 42, error: undefined }constfail=Result.fail(newError('oops'));// { value: undefined, error: Error }Wrap arbitrary values:
constwrapped=createResult('hello');// success resultconstwrappedErr=createResult(newError('boom'));// failure resultMake a safe function that returns IResult instead of throwing:
constsafeAdd=createResultableFn((a: number,b: number)=>a+b);constr=safeAdd(2,3);if(r.error){// handle error}else{console.log(r.value);// 5}Async support:
constsafeFetch=createResultableFn(async(url: string)=>{constres=awaitfetch(url);returnres.json();});constresult=awaitsafeFetch('https://example.com/data');if(result.error){// error handling}else{// use result.value}All examples below are TypeScript-friendly.
A simple class used to represent success and failure.
Result.ok<V>(v: V): IOKResult<V>
Create a success result (value present, error undefined).Result.fail(e: Error): IFailResult
Create a failure result (error present, value undefined).
Usage:
import{Result}from'@monitext/ndata';constsuccess=Result.ok({id: 1});constfailure=Result.fail(newError('problem'));Type shapes:
IOKResult<T>:{ value: T; error: undefined }IFailResult:{ value: undefined; error: Error | string }IResult<T>:IOKResult<T> | IFailResult
A variant intended for primitive-friendly payloads (string/number/boolean/null/undefined/symbol, arrays, and plain primitive objects). API mirrors Result:
PrimitiveResult.ok(v)PrimitiveResult.fail(error)
Use when you want additional semantic clarity that the value is limited to primitive-style data.
Wrap a value (or an Error) into an IResult:
- If
vis anErrorinstance -> returns a failure result. - Otherwise -> returns a success result.
import{createResult}from'@monitext/ndata';constr1=createResult('ok');// successconstr2=createResult(newError());// failureCreates a wrapper around the given function so that it never throws — instead it returns IResult (for sync functions) or Promise<IResult> (for async functions).
- Works with synchronous and asynchronous functions.
- Catches thrown errors and rejected promises, wrapping them as failure results.
- Preserves return typing (the function's return becomes the
valuein success results).
import{createResultableFn}from'@monitext/ndata';constsafe=createResultableFn((a: number,b: number)=>a+b);constok=safe(1,2);// IOKResult<number>constasyncSafe=createResultableFn(async()=>{constres=awaitfetch('https://...');returnres.json();});constresult=awaitasyncSafe();// Promise<IResult<any>>Notes:
- The wrapper inspects the function text to detect
async. This provides the correct return signature (sync vs async wrapper).
The D export contains type definitions and helpers:
D.Primitive— union of basic primitive typesD.PrimitiveArray— nested arrays of primitives/objectsD.PrimitiveObject— plain object with primitive/array/object valuesD.PrimitiveData— union of all primitive data shapesD.IResult<T>,D.IOKResult<T>,D.IFailResult, etc.
Example:
import*asDfrom'@monitext/ndata';typeP=D.PrimitiveObject;Common scripts (from package.json):
- Format code:
pnpm run format
- Typecheck (no emit):
pnpm run typecheck
- Run tests:
pnpm run test - Bundle (build artifacts to
dist):pnpm run bundle
- Full build (typecheck -> tests -> format -> bundle):
pnpm run build
Project uses TypeScript + Vitest for tests. Ensure Node >= 18 when running tooling.
- Follow the repository's contribution guidelines.
- Run tests and typechecks before opening PRs.
- Keep changes small and well-documented.
- Use the monorepo's project tooling (pnpm workspace) for local development.
Apache-2.0