Dark matter is a TypeScript library for handling success and failure cases in a type-safe way. It provides a Result type system and utilities for working with Results, including type guards, creation functions, and composition utilities.
deno add @joyautomation/dark-matter
Use createSuccess
and createFail
to create Result objects:
import { createSuccess, createFail } from "@joyautomation/dark-matter"; // Create a success result const success = createSuccess(42); // Type: ResultSuccess<number> // Value: { success: true, output: 42 } // Create a failure result const failure = createFail("Something went wrong"); // Type: ResultFail // Value: { success: false, error: "Something went wrong" }
Use isSuccess
and isFail
to check the type of a Result:
import { isSuccess, isFail } from "@joyautomation/dark-matter"; const result = createSuccess(42); if (isSuccess(result)) { // TypeScript knows result.output is a number console.log(result.output * 2); // 84 } if (isFail(result)) { // TypeScript knows result.error exists console.log(result.error); }
Use unwrapResults
to safely extract values from an array of Results:
import { unwrapResults } from "@joyautomation/dark-matter"; const results = [ createSuccess(1), createSuccess("hello"), createSuccess({ key: "value" }) ] as const; // Unwrap all results at once const [num, str, obj] = unwrapResults(results); // num: 1 // str: "hello" // obj: { key: "value" } // Throws if any result is a failure try { unwrapResults([createSuccess(1), createFail("error")]); } catch (e) { console.error(e); // "Cannot unwrap failed result: error" }
Use resultPipe
to compose functions that return Results:
import { resultPipe } from "@joyautomation/dark-matter"; const addOne = (n: number) => createSuccess(n + 1); const double = (n: number) => createSuccess(n * 2); const validatePositive = (n: number) => n > 0 ? createSuccess(n) : createFail("Number must be positive"); // Pipe synchronous functions const result1 = await resultPipe( () => createSuccess(5), addOne, double ); // Success(12) // Pipe async functions const result2 = await resultPipe( async () => createSuccess(1), async (n) => createSuccess(n + 1), validatePositive ); // Success(2) // Early failure const result3 = await resultPipe( () => createSuccess(-1), validatePositive, // Fails here double // Never executed ); // Fail("Number must be positive")
Use allSuccess
to check if all Results in a collection are successful:
import { allSuccess } from "@joyautomation/dark-matter"; const results = [ createSuccess(1), createSuccess("test") ] as const; if (allSuccess(results)) { // TypeScript knows results is [ResultSuccess<1>, ResultSuccess<"test">] const [num, str] = results.map(r => r.output); console.log(num, str); // 1, "test" } // Works with any number of results const mixed = [createSuccess(1), createFail("error"), createSuccess(3)]; console.log(allSuccess(mixed)); // false
GPL-3.0
Example 1
import { createSuccess, createFail, isSuccess, resultPipe } from "@joyautomation/dark-matter"; // Create Results const success = createSuccess(42); const failure = createFail("Something went wrong"); // Use type guards if (isSuccess(success)) { console.log(success.output); // 42 } // Compose functions const result = await resultPipe( () => createSuccess(1), (n) => createSuccess(n + 1) );
Add Package
deno add jsr:@joyautomation/dark-matter
Import symbol
import * as dark_matter from "@joyautomation/dark-matter";
---- OR ----
Import directly with a jsr specifier
import * as dark_matter from "jsr:@joyautomation/dark-matter";
Add Package
npx jsr add @joyautomation/dark-matter
Import symbol
import * as dark_matter from "@joyautomation/dark-matter";
Add Package
yarn dlx jsr add @joyautomation/dark-matter
Import symbol
import * as dark_matter from "@joyautomation/dark-matter";
Add Package
pnpm dlx jsr add @joyautomation/dark-matter
Import symbol
import * as dark_matter from "@joyautomation/dark-matter";
Add Package
bunx jsr add @joyautomation/dark-matter
Import symbol
import * as dark_matter from "@joyautomation/dark-matter";