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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@temporal-contract/boxed

v0.0.7

Published

Custom Future and Result implementation for Temporal workflows

Readme

@temporal-contract/boxed

Custom Future and Result implementation for Temporal workflows, providing type-safe error handling and async operations compatible with Temporal's deterministic execution model.

Why This Package?

The @swan-io/boxed library doesn't work properly with Temporal workflows due to Temporal's deterministic execution requirements. This package provides a Temporal-compatible implementation of the Result/Future patterns with an identical API surface.

Installation

pnpm add @temporal-contract/boxed

Basic Usage

Result Pattern

The Result type provides explicit error handling without exceptions:

import { Result } from '@temporal-contract/boxed';

// Create results
const success = Result.Ok(42);
const failure = Result.Error("Something went wrong");

// Pattern matching
const value = success.match({
  Ok: (value) => value * 2,
  Error: (error) => 0,
});

// Transformations
const doubled = success.map(x => x * 2);
const recovered = failure.mapError(e => `Error: ${e}`);

Future Pattern

The Future type wraps Promises with Result-based error handling:

import { Future, Result } from '@temporal-contract/boxed';

// Create futures
const future = Future.value(42);
const fromPromise = Future.fromPromise(fetch('/api/data'));

// Transform values
const doubled = future.map(x => x * 2);
const chained = future.flatMap(x => Future.value(x * 2));

// Work with Results in Futures
const result = await Future.fromPromise(asyncOperation());
result.match({
  Ok: (value) => console.log('Success:', value),
  Error: (error) => console.error('Failed:', error),
});

Usage in Temporal Workflows

Activities

Activities return Future<Result<T, ActivityError>> for explicit error handling:

import { Future, Result } from '@temporal-contract/boxed';
import { declareActivitiesHandler } from '@temporal-contract/worker/activity';

export const activities = declareActivitiesHandler(contract, {
  processPayment: async (args) => {
    return Future.fromPromise(paymentService.charge(args))
      .mapError(error => new ActivityError('PAYMENT_FAILED', error.message));
  },
});

Workflows

import { Result } from '@temporal-contract/boxed';

export const workflow = declareWorkflow(contract, (ctx) => ({
  async execute(input) {
    const payment = await ctx.activities.processPayment(input);

    if (payment.isError()) {
      return Result.Error({
        type: 'PAYMENT_FAILED',
        error: payment.error
      });
    }

    return Result.Ok({ success: true });
  },
}));

Interoperability with @swan-io/boxed

This package provides bi-directional interoperability with @swan-io/boxed for smooth migration and compatibility.

Default Compatibility (Recommended)

Our Result and Future types implement the same interface as @swan-io/boxed, making them compatible by default:

import { Result, Future } from '@temporal-contract/boxed';

// Your types are already compatible with @swan-io/boxed consumers
const result = Result.Ok(42);
const future = Future.value(42);

// These work with any library expecting @swan-io/boxed types
function processSwanResult(r: SwanResult<number, string>) {
  return r.match({
    Ok: (v) => v * 2,
    Error: () => 0,
  });
}

processSwanResult(result); // ✅ Works directly

Explicit Converters

For cases where you need explicit conversion, use the interop module:

import { Result, Future } from '@temporal-contract/boxed';
import {
  fromSwanResult,
  toSwanResult,
  fromSwanFuture,
  toSwanFuture,
  fromSwanFutureResult,
  toSwanFutureResult,
} from '@temporal-contract/boxed/interop';

// Convert from @swan-io/boxed to @temporal-contract/boxed
const swanResult = externalLibrary.getSomething();
const temporalResult = fromSwanResult(swanResult);

// Convert from @temporal-contract/boxed to @swan-io/boxed
const temporalResult = Result.Ok(42);
const swanCompatible = toSwanResult(temporalResult);
externalLibrary.processSomething(swanCompatible);

Interop API Reference

Result Converters:

  • fromSwanResult<T, E>(swanResult) - Convert @swan-io/boxed Result to @temporal-contract/boxed Result
  • toSwanResult<T, E>(temporalResult) - Convert @temporal-contract/boxed Result to @swan-io/boxed compatible Result

Future Converters:

  • fromSwanFuture<T>(swanFuture) - Convert @swan-io/boxed Future to @temporal-contract/boxed Future
  • toSwanFuture<T>(temporalFuture) - Convert @temporal-contract/boxed Future to @swan-io/boxed compatible Future

Future Converters:

  • fromSwanFutureResult<T, E>(swanFutureResult) - Convert @swan-io/boxed Future to @temporal-contract/boxed Future
  • toSwanFutureResult<T, E>(temporalFutureResult) - Convert @temporal-contract/boxed Future to @swan-io/boxed compatible Future

Note: @swan-io/boxed is an optional peer dependency and only needed if you're explicitly converting between implementations.

API Reference

Result<T, E>

  • Result.Ok<T>(value: T) - Create a successful result
  • Result.Error<E>(error: E) - Create an error result
  • isOk() - Check if result is Ok
  • isError() - Check if result is Error
  • match<R>(pattern) - Pattern match on result
  • map<U>(fn) - Transform Ok value
  • mapError<F>(fn) - Transform Error value
  • flatMap<U>(fn) - Chain results
  • getOr(defaultValue) - Get value or default
  • toOption() - Convert to Option type

Future<T>

  • Future.value<T>(value) - Create resolved future
  • Future.fromPromise<T>(promise) - Create future from promise (returns Future<Result<T, Error>>)
  • Future.make<T>(executor) - Create future from executor function
  • Future.reject<T>(error) - Create rejected future
  • Future.all(futures) - Combine multiple futures
  • Future.race(futures) - Race multiple futures
  • map<U>(fn) - Transform future value
  • flatMap<U>(fn) - Chain futures
  • mapOk<U>(fn) - Transform Ok value in Future
  • mapError<F>(fn) - Transform Error value in Future
  • tap(fn) - Execute side effect
  • tapOk(fn) - Execute side effect on Ok
  • tapError(fn) - Execute side effect on Error

TypeScript Support

This package is written in TypeScript and provides full type safety:

// Type inference works automatically
const result = Result.Ok(42); // Result<number, never>
const error = Result.Error("failed"); // Result<never, string>

// Generic types can be specified explicitly
const typed: Result<number, string> = Result.Ok(42);

Testing

cd packages/boxed
pnpm test

All tests verify:

  • Result operations and transformations
  • Future operations and async behavior
  • Interoperability with @swan-io/boxed
  • Type safety and compatibility

Documentation

📖 Read the full documentation →

License

MIT