CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-effect

The missing standard library for TypeScript, for writing production-grade software.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

concurrency-fibers.mddocs/

Concurrency & Fibers

Lightweight virtual threading system with Fiber for structured concurrency, enabling safe parallel execution, resource management, and cooperative multitasking.

Capabilities

Fiber Operations

interface Fiber<out A, out E = never> extends Pipeable {}

declare namespace Fiber {
  /**
   * Creates a successful fiber
   */
  function succeed<A>(value: A): Fiber<A>;
  
  /**
   * Creates a failed fiber
   */
  function fail<E>(error: E): Fiber<never, E>;
  
  /**
   * Waits for fiber completion
   */
  function await<A, E>(self: Fiber<A, E>): Effect<Exit<A, E>>;
  
  /**
   * Joins a fiber (propagates failure)
   */
  function join<A, E>(self: Fiber<A, E>): Effect<A, E>;
  
  /**
   * Interrupts a fiber
   */
  function interrupt<A, E>(self: Fiber<A, E>): Effect<Exit<A, E>>;
  
  /**
   * Maps over fiber result
   */
  function map<A, B>(f: (a: A) => B): <E>(self: Fiber<A, E>) => Fiber<B, E>;
}

Effect Concurrency

declare namespace Effect {
  /**
   * Forks an effect into a new fiber
   */
  function fork<A, E, R>(self: Effect<A, E, R>): Effect<Fiber<A, E>, never, R>;
  
  /**
   * Forks as daemon fiber
   */
  function forkDaemon<A, E, R>(self: Effect<A, E, R>): Effect<Fiber<A, E>, never, R>;
  
  /**
   * Races two effects
   */
  function race<A, E, R>(self: Effect<A, E, R>): <A2, E2, R2>(that: Effect<A2, E2, R2>) => Effect<A | A2, E | E2, R | R2>;
  
  /**
   * Executes effects in parallel
   */
  function all<Effects extends Iterable<Effect<any, any, any>>>(
    effects: Effects
  ): Effect<
    [Effect.Success<Effects[number]>],
    Effect.Error<Effects[number]>,
    Effect.Context<Effects[number]>
  >;
  
  /**
   * Executes with timeout
   */
  function timeout(duration: Duration): <A, E, R>(self: Effect<A, E, R>) => Effect<Option<A>, E, R>;
}

Usage Examples:

import { Effect, Fiber, Duration, pipe } from "effect";

// Basic forking and joining
const computation = Effect.gen(function* () {
  const fiber1 = yield* Effect.fork(Effect.succeed(1));
  const fiber2 = yield* Effect.fork(Effect.succeed(2));
  
  const result1 = yield* Fiber.join(fiber1);
  const result2 = yield* Fiber.join(fiber2);
  
  return result1 + result2;
});

// Racing operations
const quickTimeout = pipe(
  slowOperation,
  Effect.race(Effect.sleep(Duration.seconds(5)))
);

// Parallel execution
const parallelWork = Effect.all([
  fetchUser("1"),
  fetchUser("2"), 
  fetchUser("3")
]);

Software Transactional Memory (STM)

STM provides composable, thread-safe concurrent programming through transactional memory.

interface STM<out A, out E = never, out R = never> extends Pipeable {}

declare namespace STM {
  /**
   * Creates a successful STM
   */
  function succeed<A>(value: A): STM<A>;
  
  /**
   * Creates a failed STM
   */
  function fail<E>(error: E): STM<never, E>;
  
  /**
   * Suspends an STM computation
   */
  function suspend<A, E, R>(stm: LazyArg<STM<A, E, R>>): STM<A, E, R>;
  
  /**
   * Maps over STM value
   */
  function map<A, B>(f: (a: A) => B): <E, R>(self: STM<A, E, R>) => STM<B, E, R>;
  
  /**
   * FlatMaps over STM value
   */
  function flatMap<A, B, E2, R2>(
    f: (a: A) => STM<B, E2, R2>
  ): <E1, R1>(self: STM<A, E1, R1>) => STM<B, E1 | E2, R1 | R2>;
  
  /**
   * Commits STM transaction
   */
  function commit<A, E, R>(self: STM<A, E, R>): Effect<A, E, R>;
  
  /**
   * Retries STM until successful
   */
  function retry(): STM<never>;
  
  /**
   * Combines STM transactions with orElse semantics
   */
  function orElse<A2, E2, R2>(
    that: LazyArg<STM<A2, E2, R2>>
  ): <A1, E1, R1>(self: STM<A1, E1, R1>) => STM<A1 | A2, E1 | E2, R1 | R2>;
}

Micro Effects

Lightweight Effect system optimized for performance with reduced feature set.

interface Micro<out A, out E = never, out R = never> extends Pipeable {}

declare namespace Micro {
  /**
   * Creates a successful Micro
   */
  function succeed<A>(value: A): Micro<A>;
  
  /**
   * Creates a failed Micro
   */
  function fail<E>(error: E): Micro<never, E>;
  
  /**
   * Creates Micro from sync computation
   */
  function sync<A>(thunk: LazyArg<A>): Micro<A>;
  
  /**
   * Maps over Micro value
   */
  function map<A, B>(f: (a: A) => B): <E, R>(self: Micro<A, E, R>) => Micro<B, E, R>;
  
  /**
   * FlatMaps over Micro value
   */
  function flatMap<A, B, E2, R2>(
    f: (a: A) => Micro<B, E2, R2>
  ): <E1, R1>(self: Micro<A, E1, R1>) => Micro<B, E1 | E2, R1 | R2>;
  
  /**
   * Runs Micro to Promise
   */
  function runPromise<A, E>(micro: Micro<A, E>): Promise<A>;
  
  /**
   * Runs Micro synchronously
   */
  function runSync<A, E>(micro: Micro<A, E>): A;
  
  /**
   * Forks Micro into fiber
   */
  function fork<A, E, R>(self: Micro<A, E, R>): Micro<MicroFiber<A, E>, never, R>;
}

interface MicroFiber<out A, out E = never> extends Pipeable {
  /**
   * Awaits fiber completion
   */
  await(): Micro<MicroExit<A, E>>;
  
  /**
   * Joins fiber result
   */
  join(): Micro<A, E>;
  
  /**
   * Interrupts the fiber
   */
  interrupt(): Micro<MicroExit<A, E>>;
}

Types

interface Duration {
  readonly _tag: "Duration";
  readonly millis: number;
}

interface FiberId {
  readonly _tag: "FiberId";
  readonly id: number;
  readonly startTimeMillis: number;
}

Install with Tessl CLI

npx tessl i tessl/npm-effect

docs

concurrency-fibers.md

context-services.md

data-structures.md

effect-core.md

error-observability.md

function-utilities.md

index.md

layer-system.md

schema-validation.md

streaming.md

tile.json