npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@appboypov/turbo-response

v0.1.5

Published

Result type (Success/Fail) for operation outcomes in TypeScript/React

Downloads

217

Readme

turbo-response

A TypeScript library providing a type-safe Result type (Success/Fail) for handling operation outcomes without exceptions.

Installation

npm install @appboypov/turbo-response

Features

  • Type-safe result handling with discriminated unions
  • Zero dependencies
  • Full TypeScript support with complete type inference
  • Functional programming utilities for chaining and transforming results
  • Async support with andThenAsync, recoverAsync, and traverse
  • Batch operations with sequence for combining multiple results

Quick Start

import { success, fail, fold, isSuccess, TurboResponse } from '@appboypov/turbo-response';

// Creating responses
const successResult = success({ id: '123', name: 'John' });
const failResult = fail(new Error('Not found'));

// Type guards
if (isSuccess(response)) {
  console.log(response.result);
}

// Pattern matching with fold
const message = fold(
  response,
  (data) => `Found user: ${data.name}`,
  (error) => `Error: ${error}`
);

API

Creating Responses

success<T>(result: T, title?: string, message?: string): Success<T>

Creates a successful response.

const user = success({ id: '1', name: 'John' });
const withMeta = success(data, 'Created', 'User created successfully');

fail<T>(error: unknown, title?: string, message?: string, stackTrace?: string): Fail<T>

Creates a failed response.

const error = fail(new Error('Not found'));
const withMeta = fail(err, 'Not Found', 'User does not exist');

Type Guards

isSuccess<T>(r: TurboResponse<T>): r is Success<T>

if (isSuccess(response)) {
  console.log(response.result); // TypeScript knows this is Success<T>
}

isFail<T>(r: TurboResponse<T>): r is Fail<T>

if (isFail(response)) {
  console.log(response.error); // TypeScript knows this is Fail<T>
}

Pattern Matching

fold<T, R>(response, onSuccess, onFail): R

Transform a response into a single value.

const message = fold(
  response,
  (user) => `Hello, ${user.name}`,
  (error) => `Error: ${error}`
);

when<T, R>(response, handlers): R

Pattern match with full response access.

const result = when(response, {
  success: (s) => `Got ${s.result.name} - ${s.message}`,
  fail: (f) => `Failed: ${f.title}`,
});

maybeWhen<T, R>(response, handlers): R

Pattern match with optional handlers and fallback.

const result = maybeWhen(response, {
  success: (s) => s.result.name,
  orElse: () => 'Unknown',
});

Transformations

mapSuccess<T, R>(r, fn): TurboResponse<R>

Transform the success value.

const nameResponse = mapSuccess(userResponse, (user) => user.name);

mapFail<T>(r, fn): TurboResponse<T>

Transform the error value.

const mapped = mapFail(response, (err) => new CustomError(err));

Chaining

andThen<T, R>(r, fn): TurboResponse<R>

Chain operations that return TurboResponse (flatMap/bind).

const result = andThen(
  getUserById('123'),
  (user) => getOrdersByUser(user.id)
);

andThenAsync<T, R>(r, fn): Promise<TurboResponse<R>>

Async version of andThen for chaining async operations.

const result = await andThenAsync(
  fetchUser('123'),
  async (user) => fetchOrders(user.id)
);

// Chain multiple async operations
let result = await fetchUser('123');
result = await andThenAsync(result, async (user) => fetchProfile(user.id));
result = await andThenAsync(result, async (profile) => fetchSettings(profile.id));

Error Recovery

recover<T>(r, fn): TurboResponse<T>

Attempt to recover from a failure.

const result = recover(
  failedResponse,
  (error) => success(defaultValue)
);

recoverAsync<T>(r, fn): Promise<TurboResponse<T>>

Async version of recover.

const result = await recoverAsync(
  failedResponse,
  async (error) => {
    const fallback = await fetchFallbackData();
    return success(fallback);
  }
);

Unwrapping

unwrap<T>(r): T

Get the success value or throw the error.

try {
  const value = unwrap(response);
} catch (error) {
  // Handle error
}

unwrapOr<T>(r, defaultValue): T

Get the success value or return a default.

const value = unwrapOr(response, defaultUser);

unwrapOrCompute<T>(r, compute): T

Get the success value or compute a default lazily.

const value = unwrapOrCompute(response, () => createDefaultUser());

Batch Operations

traverse<T, R>(items, fn): Promise<TurboResponse<R[]>>

Apply an async operation to each item, collecting results. Fails fast on first error.

const userIds = ['1', '2', '3'];

const result = await traverse(userIds, async (id) => {
  const user = await fetchUser(id);
  return user ? success(user) : fail(new Error(`User ${id} not found`));
});

if (isSuccess(result)) {
  console.log('All users:', result.result); // User[]
}

sequence<T>(responses): TurboResponse<T[]>

Combine an array of responses into a single response. Fails fast on first error.

const responses = [
  success(1),
  success(2),
  success(3),
];

const combined = sequence(responses);
// Success<number[]> with [1, 2, 3]

const withFailure = sequence([
  success(1),
  fail(new Error('oops')),
  success(3),
]);
// Fail - returns the first failure

Validation

ensure<T>(r, predicate, error): TurboResponse<T>

Validate the success value against a predicate.

const validated = ensure(
  userResponse,
  (user) => user.age >= 18,
  new Error('Must be 18 or older')
);

Utilities

swap<T>(r): TurboResponse<T>

Swap success and fail states.

getResult<T>(r): T | undefined

Safely get the result value.

getError<T>(r): unknown | undefined

Safely get the error value.

getTitle<T>(r): string | undefined

Get the title metadata.

getMessage<T>(r): string | undefined

Get the message metadata.

License

MIT