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.
- Installation
- Quick start
- API Overview
- API Details
- Error Handling Patterns
- Development
- Contributing
- License
| 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';
const success = Result.ok({ id: 1 });
const failure = Result.fail(new Error('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';
const r1 = createResult('ok'); // success
const r2 = createResult(new Error()); // failureThe Result class provides flexible error handling.
The .expect() method allows you to customize what happens on error:
const r = Result.fail(new Error('fail!'));
r.expect({
msg: 'Something went wrong',
handler: ({ err }) => {
// Custom logic, e.g., log or transform error
return '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';
const safe = createResultableFn((a: number, b: number) => a + b);
const ok = safe(1, 2); // IOKResult<number>
const asyncSafe = createResultableFn(async () => {
const res = await fetch('https://...');
return res.json();
});
const result = await asyncSafe(); // 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 * as D from '@monitext/ndata'; // or import * as DataTypes from '@monitext/ndata'
type P = 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 * as D from '@monitext/ndata/src/lib/data-types'; // or `import * as D from '@monitext/ndata'` when consumed via packageCreate success/failure Results:
const ok = Result.ok(42); // { value: 42, error: undefined }
const fail = Result.fail(new Error('oops')); // { value: undefined, error: Error }Wrap arbitrary values:
const wrapped = createResult('hello'); // success result
const wrappedErr = createResult(new Error('boom')); // failure resultMake a safe function that returns IResult instead of throwing:
const safeAdd = createResultableFn((a: number, b: number) => a + b);
const r = safeAdd(2, 3);
if (r.error) {
// handle error
} else {
console.log(r.value); // 5
}Async support:
const safeFetch = createResultableFn(async (url: string) => {
const res = await fetch(url);
return res.json();
});
const result = await safeFetch('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';
const success = Result.ok({ id: 1 });
const failure = Result.fail(new Error('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';
const r1 = createResult('ok'); // success
const r2 = createResult(new Error()); // 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';
const safe = createResultableFn((a: number, b: number) => a + b);
const ok = safe(1, 2); // IOKResult<number>
const asyncSafe = createResultableFn(async () => {
const res = await fetch('https://...');
return res.json();
});
const result = await asyncSafe(); // 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 * as D from '@monitext/ndata';
type P = 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