@actuallab/core
v14.3.34
Published
Core primitives for ActualLab TypeScript libraries
Readme
@actuallab/core
Core primitives shared by every ActualLab.Fusion TypeScript
package — Result<T>, AsyncContext, AsyncLock, PromiseSource, events, retry policies, and
cancellation helpers. It is the TypeScript counterpart of parts of ActualLab.Core in .NET, and it
has zero runtime dependencies.
You rarely install it directly: @actuallab/rpc, @actuallab/fusion, @actuallab/fusion-rpc, and
@actuallab/fusion-react all depend on it. Install it explicitly when you want its primitives on
their own.
Installation
npm install @actuallab/coreESM-first with a CJS fallback; ships its own .d.ts.
What's inside
| API | Description |
|-----|-------------|
| Result<T>, result, errorResult, resultFrom, resultFromAsync | Immutable value-or-error container (.NET's Result<T>) |
| PromiseSource<T>, PromiseSourceWithTimeout<T> | Externally-resolvable promise (.NET's TaskCompletionSource<T>) |
| AsyncContext, AsyncContextKey, abortSignalKey | AsyncLocal<T>-like typed context; backed by AsyncLocalStorage on Node ≥ 20.16 |
| AsyncLock, AsyncSignal | Promise-based mutual exclusion and signalling |
| EventHandlerSet<T> | Typed multicast pub/sub with whenNext() |
| isCancellation, cancellationError, delayAsync, abortPromise, awaitWithCleanup | AbortSignal-based cancellation, with .NET's "cancellation is not a failure" semantics |
| RetryDelaySeq, RetryDelayer, retry | Exponential-backoff retry policies |
| throttle, debounce, serialize | Higher-order async operators |
| RingBuffer, DisposableBag | Small collections / lifetime helpers |
| Log, LogLevel, initLogging, LogLevelController | Scoped logging used by all Fusion TS packages |
Examples
import { Result, result, errorResult, resultFrom } from '@actuallab/core';
const ok = result(42);
ok.hasValue; // true
ok.value; // 42
ok.valueOrUndefined; // 42 — never throws
const err = errorResult<number>(new Error('fail'));
err.hasError; // true
err.value; // throws Error("fail")
resultFrom(() => JSON.parse('{}')); // Result<any>, exception capturedimport { AsyncContext, AsyncContextKey } from '@actuallab/core';
const userKey = new AsyncContextKey<string>('user', 'anonymous');
const ctx = AsyncContext.empty.with(userKey, 'Alice');
ctx.run(() => AsyncContext.current!.get(userKey)); // "Alice"import { AsyncLock, delayAsync, RetryDelaySeq } from '@actuallab/core';
const lock = new AsyncLock();
await lock.run(async () => { /* critical section */ });
await delayAsync(1000, abortSignal); // abortable delay
RetryDelaySeq.exp(1000, 30000); // 1s, 1.4s, 2s, 2.8s, … (×√2, ±10% spread), capped at 30sDocumentation
@actuallab/corereference — full API tables and semantics- TypeScript port overview — architecture,
AsyncContextrules, .NET differences - Fusion documentation
License
MIT — see LICENSE.
