@actuallab/core 12.1.100 → 12.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -52,7 +52,10 @@ var AsyncContextKey = class {
52
52
  this.defaultValue = defaultValue;
53
53
  }
54
54
  };
55
- var abortSignalKey = new AsyncContextKey("AbortSignal", void 0);
55
+ var abortSignalKey = new AsyncContextKey(
56
+ "AbortSignal",
57
+ void 0
58
+ );
56
59
  var AsyncContext = class _AsyncContext {
57
60
  static current = void 0;
58
61
  /** Immutable empty singleton — avoids allocating new AsyncContext(). */
@@ -64,7 +67,8 @@ var AsyncContext = class _AsyncContext {
64
67
  }
65
68
  get(key) {
66
69
  if (this._values.has(key.id)) return this._values.get(key.id);
67
- if (_AsyncContext._defaults.has(key.id)) return _AsyncContext._defaults.get(key.id);
70
+ if (_AsyncContext._defaults.has(key.id))
71
+ return _AsyncContext._defaults.get(key.id);
68
72
  return key.defaultValue;
69
73
  }
70
74
  with(key, value) {
@@ -75,9 +79,11 @@ var AsyncContext = class _AsyncContext {
75
79
  activate() {
76
80
  const prev = _AsyncContext.current;
77
81
  _AsyncContext.current = this;
78
- return { dispose: () => {
79
- _AsyncContext.current = prev;
80
- } };
82
+ return {
83
+ dispose: () => {
84
+ _AsyncContext.current = prev;
85
+ }
86
+ };
81
87
  }
82
88
  run(fn) {
83
89
  const prev = _AsyncContext.current;
@@ -126,8 +132,7 @@ var AsyncLock = class {
126
132
  });
127
133
  }
128
134
  release() {
129
- if (!this._locked)
130
- throw new Error("AsyncLock is not locked.");
135
+ if (!this._locked) throw new Error("AsyncLock is not locked.");
131
136
  const next = this._queue.shift();
132
137
  if (next !== void 0) {
133
138
  next();
@@ -316,10 +321,14 @@ var RetryDelaySeq = class _RetryDelaySeq {
316
321
  return new _RetryDelaySeq(minMs, maxMs, spread, multiplier);
317
322
  }
318
323
  getDelay(failureCount) {
319
- if (this.min < 0) throw new Error("RetryDelaySeq.min must be non-negative.");
324
+ if (this.min < 0)
325
+ throw new Error("RetryDelaySeq.min must be non-negative.");
320
326
  if (failureCount <= 0) return 0;
321
327
  if (this.multiplier <= 1) {
322
- return Math.max(0, this.spread <= 0 ? this.min : applySpread(this.min, this.spread));
328
+ return Math.max(
329
+ 0,
330
+ this.spread <= 0 ? this.min : applySpread(this.min, this.spread)
331
+ );
323
332
  }
324
333
  const multiplier = Math.pow(this.multiplier, failureCount - 1);
325
334
  const raw = Math.min(this.max, this.min * multiplier);
@@ -347,8 +356,7 @@ var RetryDelayer = class {
347
356
  if (this.limit !== void 0 && tryIndex >= this.limit)
348
357
  return RetryDelayLimitExceeded;
349
358
  const delayMs = this.delays.getDelay(tryIndex);
350
- if (tryIndex === 0 || delayMs <= 0)
351
- return RetryDelayNone;
359
+ if (tryIndex === 0 || delayMs <= 0) return RetryDelayNone;
352
360
  const actualDelayMs = Math.max(1, delayMs);
353
361
  const endsAt = Date.now() + actualDelayMs;
354
362
  const cancelSignal = this._cancelController.signal;
@@ -372,7 +380,9 @@ var RetryDelayer = class {
372
380
  cancellationSignal?.removeEventListener("abort", onAbort);
373
381
  };
374
382
  cancelSignal.addEventListener("abort", onCancel, { once: true });
375
- cancellationSignal?.addEventListener("abort", onAbort, { once: true });
383
+ cancellationSignal?.addEventListener("abort", onAbort, {
384
+ once: true
385
+ });
376
386
  });
377
387
  return { promise, endsAt, isLimitExceeded: false };
378
388
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/polyfills.ts","../src/async-context.ts","../src/async-lock.ts","../src/disposable.ts","../src/promise-source.ts","../src/events.ts","../src/result.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts"],"sourcesContent":["import \"./polyfills.js\";\r\nexport { AsyncContext, AsyncContextKey, abortSignalKey } from \"./async-context.js\";\r\nexport { AsyncLock } from \"./async-lock.js\";\r\nexport type { Disposable, AsyncDisposable } from \"./disposable.js\";\r\nexport { DisposableBag } from \"./disposable.js\";\r\nexport { EventHandlerSet } from \"./events.js\";\r\nexport { PromiseSource, resolvedVoidPromise } from \"./promise-source.js\";\r\nexport type { IResult } from \"./result.js\";\r\nexport { Result, result, errorResult, resultFrom, resultFromAsync } from \"./result.js\";\r\nexport { RetryDelaySeq } from \"./retry-delay-seq.js\";\r\nexport type { RetryDelay } from \"./retry-delayer.js\";\r\nexport { RetryDelayer, RetryDelayNone, RetryDelayLimitExceeded } from \"./retry-delayer.js\";\r\n","// TC39 decorator metadata polyfill — required for Symbol.metadata support\r\n// in runtimes that don't yet implement it natively.\r\n(Symbol as any).metadata ??= Symbol(\"Symbol.metadata\");\r\n","import type { Disposable } from \"./disposable.js\";\r\n\r\n/** Typed key for values stored in AsyncContext — each subsystem defines its own keys. */\r\nexport class AsyncContextKey<T> {\r\n readonly id: symbol;\r\n readonly defaultValue: T;\r\n\r\n constructor(name: string, defaultValue: T) {\r\n this.id = Symbol(name);\r\n this.defaultValue = defaultValue;\r\n }\r\n}\r\n\r\n/** General-purpose typed context container — named for forward-compatibility with TC39 AsyncContext proposal. */\r\nexport const abortSignalKey =\r\n new AsyncContextKey<AbortSignal | undefined>(\"AbortSignal\", undefined);\r\n\r\nexport class AsyncContext {\r\n static current: AsyncContext | undefined = undefined;\r\n\r\n /** Immutable empty singleton — avoids allocating new AsyncContext(). */\r\n static readonly empty: AsyncContext = new AsyncContext();\r\n\r\n private static _defaults = new Map<symbol, unknown>();\r\n\r\n private _values: Map<symbol, unknown>;\r\n\r\n constructor(values?: Map<symbol, unknown>) {\r\n this._values = values ?? new Map();\r\n }\r\n\r\n get<T>(key: AsyncContextKey<T>): T {\r\n if (this._values.has(key.id)) return this._values.get(key.id) as T;\r\n if (AsyncContext._defaults.has(key.id)) return AsyncContext._defaults.get(key.id) as T;\r\n return key.defaultValue;\r\n }\r\n\r\n with<T>(key: AsyncContextKey<T>, value: T): AsyncContext {\r\n const copy = new Map(this._values);\r\n copy.set(key.id, value);\r\n return new AsyncContext(copy);\r\n }\r\n\r\n activate(): Disposable {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n return { dispose: () => { AsyncContext.current = prev; } };\r\n }\r\n\r\n run<R>(fn: () => R): R {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n try {\r\n return fn();\r\n } finally {\r\n AsyncContext.current = prev;\r\n }\r\n }\r\n\r\n /** Strip THIS exact instance from args if it's the last element (reference equality). */\r\n stripFromArgs(args: unknown[]): unknown[] {\r\n return args[args.length - 1] === this ? args.slice(0, -1) : args;\r\n }\r\n\r\n /** Resolve: return ctx if provided, otherwise AsyncContext.current. */\r\n static from(ctx: AsyncContext | undefined): AsyncContext | undefined {\r\n return ctx ?? AsyncContext.current;\r\n }\r\n\r\n /** Extract AsyncContext from last arg if instanceof AsyncContext, else fall back to .current. */\r\n static fromArgs(args: unknown[]): AsyncContext | undefined {\r\n const last = args[args.length - 1];\r\n return last instanceof AsyncContext ? last : AsyncContext.current;\r\n }\r\n\r\n static setDefault<T>(key: AsyncContextKey<T>, value: T): void {\r\n AsyncContext._defaults.set(key.id, value);\r\n }\r\n\r\n static getOrCreate(): AsyncContext {\r\n return AsyncContext.current ?? AsyncContext.empty;\r\n }\r\n}\r\n","/** Promise-based mutual exclusion lock for serializing async operations. */\r\nexport class AsyncLock {\r\n private _queue: (() => void)[] = [];\r\n private _locked = false;\r\n\r\n get isLocked(): boolean {\r\n return this._locked;\r\n }\r\n\r\n async acquire(): Promise<void> {\r\n if (!this._locked) {\r\n this._locked = true;\r\n return;\r\n }\r\n return new Promise<void>((resolve) => {\r\n this._queue.push(resolve);\r\n });\r\n }\r\n\r\n release(): void {\r\n if (!this._locked)\r\n throw new Error(\"AsyncLock is not locked.\");\r\n\r\n const next = this._queue.shift();\r\n if (next !== undefined) {\r\n // Transfer lock to the next waiter\r\n next();\r\n } else {\r\n this._locked = false;\r\n }\r\n }\r\n\r\n async run<T>(fn: () => T | Promise<T>): Promise<T> {\r\n await this.acquire();\r\n try {\r\n return await fn();\r\n } finally {\r\n this.release();\r\n }\r\n }\r\n}\r\n","/** Synchronous dispose pattern, similar to .NET's IDisposable. */\r\nexport interface Disposable {\r\n dispose(): void;\r\n}\r\n\r\n/** Asynchronous dispose pattern, similar to .NET's IAsyncDisposable. */\r\nexport interface AsyncDisposable {\r\n disposeAsync(): Promise<void>;\r\n}\r\n\r\n/** Aggregates multiple disposables and disposes them together. */\r\nexport class DisposableBag implements Disposable, AsyncDisposable {\r\n private _items: (Disposable | AsyncDisposable)[] = [];\r\n private _disposed = false;\r\n\r\n get isDisposed(): boolean {\r\n return this._disposed;\r\n }\r\n\r\n add(item: Disposable | AsyncDisposable): void {\r\n if (this._disposed)\r\n throw new Error(\"DisposableBag is already disposed.\");\r\n this._items.push(item);\r\n }\r\n\r\n dispose(): void {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n // Dispose in reverse order (LIFO)\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item != null && \"dispose\" in item) item.dispose();\r\n }\r\n }\r\n\r\n async disposeAsync(): Promise<void> {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item == null) continue;\r\n if (\"disposeAsync\" in item) await item.disposeAsync();\r\n else if (\"dispose\" in item) item.dispose();\r\n }\r\n }\r\n}\r\n","/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */\r\nexport class PromiseSource<T> {\r\n readonly promise: Promise<T>;\r\n private _resolve!: (value: T | PromiseLike<T>) => void;\r\n private _reject!: (reason?: unknown) => void;\r\n private _isCompleted = false;\r\n\r\n constructor() {\r\n this.promise = new Promise<T>((resolve, reject) => {\r\n this._resolve = resolve;\r\n this._reject = reject;\r\n });\r\n }\r\n\r\n get isCompleted(): boolean {\r\n return this._isCompleted;\r\n }\r\n\r\n resolve(value: T): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._resolve(value);\r\n return true;\r\n }\r\n\r\n reject(reason?: unknown): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._reject(reason);\r\n return true;\r\n }\r\n}\r\n\r\nexport const resolvedVoidPromise: Promise<void> = Promise.resolve();","import { PromiseSource } from \"./promise-source.js\";\r\n\r\n/** Typed pub/sub event handler set — similar to .NET's EventHandler<T> multicast delegate. */\r\nexport class EventHandlerSet<T> {\r\n private _handlers: Set<(arg: T) => void> = new Set();\r\n\r\n get count(): number {\r\n return this._handlers.size;\r\n }\r\n\r\n add(handler: (arg: T) => void): void {\r\n this._handlers.add(handler);\r\n }\r\n\r\n remove(handler: (arg: T) => void): void {\r\n this._handlers.delete(handler);\r\n }\r\n\r\n trigger(arg: T): void {\r\n for (const handler of this._handlers) handler(arg);\r\n }\r\n\r\n clear(): void {\r\n this._handlers.clear();\r\n }\r\n\r\n whenNext(): Promise<T> {\r\n const ps = new PromiseSource<T>();\r\n const handler = (arg: T) => {\r\n this._handlers.delete(handler);\r\n ps.resolve(arg);\r\n };\r\n this._handlers.add(handler);\r\n return ps.promise;\r\n }\r\n}\r\n","/** Common interface for types that carry a value-or-error outcome. */\r\nexport interface IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n readonly value: T;\r\n readonly error: unknown;\r\n readonly valueOrUndefined: T | undefined;\r\n}\r\n\r\n/** Immutable value-or-error container — similar to .NET's Result<T>. */\r\nexport class Result<T> implements IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n private readonly _value: T | undefined;\r\n private readonly _error: unknown;\r\n\r\n public constructor(value: T | undefined, error?: unknown) {\r\n this.hasValue = error === undefined;\r\n this.hasError = !this.hasValue;\r\n this._value = value;\r\n this._error = error;\r\n }\r\n\r\n get value(): T {\r\n if (this.hasError) throw this._error;\r\n return this._value as T;\r\n }\r\n\r\n get error(): unknown {\r\n return this._error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.hasValue ? this._value : undefined;\r\n }\r\n\r\n static ok<T>(value: T): Result<T> {\r\n return new Result<T>(value);\r\n }\r\n\r\n static error<T>(error: unknown): Result<T> {\r\n return new Result<T>(undefined, error);\r\n }\r\n}\r\n\r\nexport function result<T>(value: T, error?: unknown): Result<T> {\r\n return new Result<T>(value, error);\r\n}\r\n\r\nexport function errorResult<T>(error: unknown): Result<T> {\r\n return Result.error(error);\r\n}\r\n\r\nexport function resultFrom<T>(fn: () => T): Result<T> {\r\n try {\r\n return result(fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n\r\nexport async function resultFromAsync<T>(fn: () => Promise<T>): Promise<Result<T>> {\r\n try {\r\n return result(await fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n","// .NET counterpart: ActualLab.Time.RetryDelaySeq\r\n\r\nconst DefaultSpread = 0.1;\r\nconst DefaultMultiplier = 1.41421356237; // Math.sqrt(2)\r\n\r\nfunction applySpread(origin: number, spread: number): number {\r\n if (spread <= 0) return origin;\r\n const delta = origin * spread;\r\n return origin + (Math.random() * 2 - 1) * delta;\r\n}\r\n\r\nexport class RetryDelaySeq {\r\n readonly min: number;\r\n readonly max: number;\r\n readonly spread: number;\r\n readonly multiplier: number;\r\n\r\n constructor(min: number, max: number, spread: number = DefaultSpread, multiplier: number = DefaultMultiplier) {\r\n this.min = min;\r\n this.max = max;\r\n this.spread = spread;\r\n this.multiplier = multiplier;\r\n }\r\n\r\n static fixed(delayMs: number, spread: number = DefaultSpread): RetryDelaySeq {\r\n return new RetryDelaySeq(delayMs, delayMs, spread, 1);\r\n }\r\n\r\n static exp(\r\n minMs: number,\r\n maxMs: number,\r\n spread: number = DefaultSpread,\r\n multiplier: number = DefaultMultiplier,\r\n ): RetryDelaySeq {\r\n return new RetryDelaySeq(minMs, maxMs, spread, multiplier);\r\n }\r\n\r\n getDelay(failureCount: number): number {\r\n if (this.min < 0) throw new Error(\"RetryDelaySeq.min must be non-negative.\");\r\n if (failureCount <= 0) return 0;\r\n\r\n if (this.multiplier <= 1) {\r\n // Fixed — no exponential component\r\n return Math.max(0, this.spread <= 0 ? this.min : applySpread(this.min, this.spread));\r\n }\r\n\r\n const multiplier = Math.pow(this.multiplier, failureCount - 1);\r\n const raw = Math.min(this.max, this.min * multiplier);\r\n return Math.max(0, applySpread(raw, this.spread));\r\n }\r\n}\r\n","// .NET counterparts: ActualLab.Net.RetryDelayer, ActualLab.Net.RetryDelay\r\n\r\nimport { EventHandlerSet } from \"./events.js\";\r\nimport { RetryDelaySeq } from \"./retry-delay-seq.js\";\r\n\r\nexport interface RetryDelay {\r\n readonly promise: Promise<void>;\r\n readonly endsAt: number; // Date.now()-based timestamp, 0 = no delay\r\n readonly isLimitExceeded: boolean;\r\n}\r\n\r\nexport const RetryDelayNone: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: false,\r\n};\r\n\r\nexport const RetryDelayLimitExceeded: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: true,\r\n};\r\n\r\nexport class RetryDelayer {\r\n private _cancelController = new AbortController();\r\n\r\n delays: RetryDelaySeq = RetryDelaySeq.fixed(1000);\r\n limit: number | undefined = undefined;\r\n\r\n readonly cancelDelaysChanged = new EventHandlerSet<void>();\r\n\r\n getDelay(tryIndex: number, cancellationSignal?: AbortSignal): RetryDelay {\r\n if (this.limit !== undefined && tryIndex >= this.limit)\r\n return RetryDelayLimitExceeded;\r\n\r\n const delayMs = this.delays.getDelay(tryIndex);\r\n if (tryIndex === 0 || delayMs <= 0)\r\n return RetryDelayNone;\r\n\r\n const actualDelayMs = Math.max(1, delayMs);\r\n const endsAt = Date.now() + actualDelayMs;\r\n\r\n const cancelSignal = this._cancelController.signal;\r\n const promise = new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, actualDelayMs);\r\n\r\n const onCancel = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n resolve(); // cancelDelays resolves, does NOT reject\r\n };\r\n\r\n const onAbort = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n reject(new Error(\"Retry delay aborted.\"));\r\n };\r\n\r\n const cleanup = () => {\r\n cancelSignal.removeEventListener(\"abort\", onCancel);\r\n cancellationSignal?.removeEventListener(\"abort\", onAbort);\r\n };\r\n\r\n cancelSignal.addEventListener(\"abort\", onCancel, { once: true });\r\n cancellationSignal?.addEventListener(\"abort\", onAbort, { once: true });\r\n });\r\n\r\n return { promise, endsAt, isLimitExceeded: false };\r\n }\r\n\r\n cancelDelays(): void {\r\n const old = this._cancelController;\r\n this._cancelController = new AbortController();\r\n old.abort();\r\n this.cancelDelaysChanged.trigger();\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/polyfills.ts","../src/async-context.ts","../src/async-lock.ts","../src/disposable.ts","../src/promise-source.ts","../src/events.ts","../src/result.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts"],"sourcesContent":["import './polyfills.js';\r\nexport {\r\n AsyncContext,\r\n AsyncContextKey,\r\n abortSignalKey,\r\n} from './async-context.js';\r\nexport { AsyncLock } from './async-lock.js';\r\nexport type { Disposable, AsyncDisposable } from './disposable.js';\r\nexport { DisposableBag } from './disposable.js';\r\nexport { EventHandlerSet } from './events.js';\r\nexport { PromiseSource, resolvedVoidPromise } from './promise-source.js';\r\nexport type { IResult } from './result.js';\r\nexport {\r\n Result,\r\n result,\r\n errorResult,\r\n resultFrom,\r\n resultFromAsync,\r\n} from './result.js';\r\nexport { RetryDelaySeq } from './retry-delay-seq.js';\r\nexport type { RetryDelay } from './retry-delayer.js';\r\nexport {\r\n RetryDelayer,\r\n RetryDelayNone,\r\n RetryDelayLimitExceeded,\r\n} from './retry-delayer.js';\r\n","// TC39 decorator metadata polyfill — required for Symbol.metadata support\r\n// in runtimes that don't yet implement it natively.\r\n(Symbol as any).metadata ??= Symbol('Symbol.metadata');\r\n","import type { Disposable } from './disposable.js';\r\n\r\n/** Typed key for values stored in AsyncContext — each subsystem defines its own keys. */\r\nexport class AsyncContextKey<T> {\r\n readonly id: symbol;\r\n readonly defaultValue: T;\r\n\r\n constructor(name: string, defaultValue: T) {\r\n this.id = Symbol(name);\r\n this.defaultValue = defaultValue;\r\n }\r\n}\r\n\r\n/** General-purpose typed context container — named for forward-compatibility with TC39 AsyncContext proposal. */\r\nexport const abortSignalKey = new AsyncContextKey<AbortSignal | undefined>(\r\n 'AbortSignal',\r\n undefined\r\n);\r\n\r\nexport class AsyncContext {\r\n static current: AsyncContext | undefined = undefined;\r\n\r\n /** Immutable empty singleton — avoids allocating new AsyncContext(). */\r\n static readonly empty: AsyncContext = new AsyncContext();\r\n\r\n private static _defaults = new Map<symbol, unknown>();\r\n\r\n private _values: Map<symbol, unknown>;\r\n\r\n constructor(values?: Map<symbol, unknown>) {\r\n this._values = values ?? new Map();\r\n }\r\n\r\n get<T>(key: AsyncContextKey<T>): T {\r\n if (this._values.has(key.id)) return this._values.get(key.id) as T;\r\n if (AsyncContext._defaults.has(key.id))\r\n return AsyncContext._defaults.get(key.id) as T;\r\n return key.defaultValue;\r\n }\r\n\r\n with<T>(key: AsyncContextKey<T>, value: T): AsyncContext {\r\n const copy = new Map(this._values);\r\n copy.set(key.id, value);\r\n return new AsyncContext(copy);\r\n }\r\n\r\n activate(): Disposable {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n return {\r\n dispose: () => {\r\n AsyncContext.current = prev;\r\n },\r\n };\r\n }\r\n\r\n run<R>(fn: () => R): R {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n try {\r\n return fn();\r\n } finally {\r\n AsyncContext.current = prev;\r\n }\r\n }\r\n\r\n /** Strip THIS exact instance from args if it's the last element (reference equality). */\r\n stripFromArgs(args: unknown[]): unknown[] {\r\n return args[args.length - 1] === this ? args.slice(0, -1) : args;\r\n }\r\n\r\n /** Resolve: return ctx if provided, otherwise AsyncContext.current. */\r\n static from(ctx: AsyncContext | undefined): AsyncContext | undefined {\r\n return ctx ?? AsyncContext.current;\r\n }\r\n\r\n /** Extract AsyncContext from last arg if instanceof AsyncContext, else fall back to .current. */\r\n static fromArgs(args: unknown[]): AsyncContext | undefined {\r\n const last = args[args.length - 1];\r\n return last instanceof AsyncContext ? last : AsyncContext.current;\r\n }\r\n\r\n static setDefault<T>(key: AsyncContextKey<T>, value: T): void {\r\n AsyncContext._defaults.set(key.id, value);\r\n }\r\n\r\n static getOrCreate(): AsyncContext {\r\n return AsyncContext.current ?? AsyncContext.empty;\r\n }\r\n}\r\n","/** Promise-based mutual exclusion lock for serializing async operations. */\r\nexport class AsyncLock {\r\n private _queue: (() => void)[] = [];\r\n private _locked = false;\r\n\r\n get isLocked(): boolean {\r\n return this._locked;\r\n }\r\n\r\n async acquire(): Promise<void> {\r\n if (!this._locked) {\r\n this._locked = true;\r\n return;\r\n }\r\n return new Promise<void>(resolve => {\r\n this._queue.push(resolve);\r\n });\r\n }\r\n\r\n release(): void {\r\n if (!this._locked) throw new Error('AsyncLock is not locked.');\r\n\r\n const next = this._queue.shift();\r\n if (next !== undefined) {\r\n // Transfer lock to the next waiter\r\n next();\r\n } else {\r\n this._locked = false;\r\n }\r\n }\r\n\r\n async run<T>(fn: () => T | Promise<T>): Promise<T> {\r\n await this.acquire();\r\n try {\r\n return await fn();\r\n } finally {\r\n this.release();\r\n }\r\n }\r\n}\r\n","/** Synchronous dispose pattern, similar to .NET's IDisposable. */\r\nexport interface Disposable {\r\n dispose(): void;\r\n}\r\n\r\n/** Asynchronous dispose pattern, similar to .NET's IAsyncDisposable. */\r\nexport interface AsyncDisposable {\r\n disposeAsync(): Promise<void>;\r\n}\r\n\r\n/** Aggregates multiple disposables and disposes them together. */\r\nexport class DisposableBag implements Disposable, AsyncDisposable {\r\n private _items: (Disposable | AsyncDisposable)[] = [];\r\n private _disposed = false;\r\n\r\n get isDisposed(): boolean {\r\n return this._disposed;\r\n }\r\n\r\n add(item: Disposable | AsyncDisposable): void {\r\n if (this._disposed)\r\n throw new Error('DisposableBag is already disposed.');\r\n this._items.push(item);\r\n }\r\n\r\n dispose(): void {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n // Dispose in reverse order (LIFO)\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item != null && 'dispose' in item) item.dispose();\r\n }\r\n }\r\n\r\n async disposeAsync(): Promise<void> {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item == null) continue;\r\n if ('disposeAsync' in item) await item.disposeAsync();\r\n else if ('dispose' in item) item.dispose();\r\n }\r\n }\r\n}\r\n","/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */\r\nexport class PromiseSource<T> {\r\n readonly promise: Promise<T>;\r\n private _resolve!: (value: T | PromiseLike<T>) => void;\r\n private _reject!: (reason?: unknown) => void;\r\n private _isCompleted = false;\r\n\r\n constructor() {\r\n this.promise = new Promise<T>((resolve, reject) => {\r\n this._resolve = resolve;\r\n this._reject = reject;\r\n });\r\n }\r\n\r\n get isCompleted(): boolean {\r\n return this._isCompleted;\r\n }\r\n\r\n resolve(value: T): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._resolve(value);\r\n return true;\r\n }\r\n\r\n reject(reason?: unknown): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._reject(reason);\r\n return true;\r\n }\r\n}\r\n\r\nexport const resolvedVoidPromise: Promise<void> = Promise.resolve();\r\n","import { PromiseSource } from './promise-source.js';\r\n\r\n/** Typed pub/sub event handler set — similar to .NET's EventHandler<T> multicast delegate. */\r\nexport class EventHandlerSet<T> {\r\n private _handlers: Set<(arg: T) => void> = new Set();\r\n\r\n get count(): number {\r\n return this._handlers.size;\r\n }\r\n\r\n add(handler: (arg: T) => void): void {\r\n this._handlers.add(handler);\r\n }\r\n\r\n remove(handler: (arg: T) => void): void {\r\n this._handlers.delete(handler);\r\n }\r\n\r\n trigger(arg: T): void {\r\n for (const handler of this._handlers) handler(arg);\r\n }\r\n\r\n clear(): void {\r\n this._handlers.clear();\r\n }\r\n\r\n whenNext(): Promise<T> {\r\n const ps = new PromiseSource<T>();\r\n const handler = (arg: T) => {\r\n this._handlers.delete(handler);\r\n ps.resolve(arg);\r\n };\r\n this._handlers.add(handler);\r\n return ps.promise;\r\n }\r\n}\r\n","/** Common interface for types that carry a value-or-error outcome. */\r\nexport interface IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n readonly value: T;\r\n readonly error: unknown;\r\n readonly valueOrUndefined: T | undefined;\r\n}\r\n\r\n/** Immutable value-or-error container — similar to .NET's Result<T>. */\r\nexport class Result<T> implements IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n private readonly _value: T | undefined;\r\n private readonly _error: unknown;\r\n\r\n public constructor(value: T | undefined, error?: unknown) {\r\n this.hasValue = error === undefined;\r\n this.hasError = !this.hasValue;\r\n this._value = value;\r\n this._error = error;\r\n }\r\n\r\n get value(): T {\r\n if (this.hasError) throw this._error;\r\n return this._value as T;\r\n }\r\n\r\n get error(): unknown {\r\n return this._error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.hasValue ? this._value : undefined;\r\n }\r\n\r\n static ok<T>(value: T): Result<T> {\r\n return new Result<T>(value);\r\n }\r\n\r\n static error<T>(error: unknown): Result<T> {\r\n return new Result<T>(undefined, error);\r\n }\r\n}\r\n\r\nexport function result<T>(value: T, error?: unknown): Result<T> {\r\n return new Result<T>(value, error);\r\n}\r\n\r\nexport function errorResult<T>(error: unknown): Result<T> {\r\n return Result.error(error);\r\n}\r\n\r\nexport function resultFrom<T>(fn: () => T): Result<T> {\r\n try {\r\n return result(fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n\r\nexport async function resultFromAsync<T>(\r\n fn: () => Promise<T>\r\n): Promise<Result<T>> {\r\n try {\r\n return result(await fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n","// .NET counterpart: ActualLab.Time.RetryDelaySeq\r\n\r\nconst DefaultSpread = 0.1;\r\nconst DefaultMultiplier = 1.41421356237; // Math.sqrt(2)\r\n\r\nfunction applySpread(origin: number, spread: number): number {\r\n if (spread <= 0) return origin;\r\n const delta = origin * spread;\r\n return origin + (Math.random() * 2 - 1) * delta;\r\n}\r\n\r\nexport class RetryDelaySeq {\r\n readonly min: number;\r\n readonly max: number;\r\n readonly spread: number;\r\n readonly multiplier: number;\r\n\r\n constructor(\r\n min: number,\r\n max: number,\r\n spread: number = DefaultSpread,\r\n multiplier: number = DefaultMultiplier\r\n ) {\r\n this.min = min;\r\n this.max = max;\r\n this.spread = spread;\r\n this.multiplier = multiplier;\r\n }\r\n\r\n static fixed(\r\n delayMs: number,\r\n spread: number = DefaultSpread\r\n ): RetryDelaySeq {\r\n return new RetryDelaySeq(delayMs, delayMs, spread, 1);\r\n }\r\n\r\n static exp(\r\n minMs: number,\r\n maxMs: number,\r\n spread: number = DefaultSpread,\r\n multiplier: number = DefaultMultiplier\r\n ): RetryDelaySeq {\r\n return new RetryDelaySeq(minMs, maxMs, spread, multiplier);\r\n }\r\n\r\n getDelay(failureCount: number): number {\r\n if (this.min < 0)\r\n throw new Error('RetryDelaySeq.min must be non-negative.');\r\n if (failureCount <= 0) return 0;\r\n\r\n if (this.multiplier <= 1) {\r\n // Fixed — no exponential component\r\n return Math.max(\r\n 0,\r\n this.spread <= 0 ? this.min : applySpread(this.min, this.spread)\r\n );\r\n }\r\n\r\n const multiplier = Math.pow(this.multiplier, failureCount - 1);\r\n const raw = Math.min(this.max, this.min * multiplier);\r\n return Math.max(0, applySpread(raw, this.spread));\r\n }\r\n}\r\n","// .NET counterparts: ActualLab.Net.RetryDelayer, ActualLab.Net.RetryDelay\r\n\r\nimport { EventHandlerSet } from './events.js';\r\nimport { RetryDelaySeq } from './retry-delay-seq.js';\r\n\r\nexport interface RetryDelay {\r\n readonly promise: Promise<void>;\r\n readonly endsAt: number; // Date.now()-based timestamp, 0 = no delay\r\n readonly isLimitExceeded: boolean;\r\n}\r\n\r\nexport const RetryDelayNone: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: false,\r\n};\r\n\r\nexport const RetryDelayLimitExceeded: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: true,\r\n};\r\n\r\nexport class RetryDelayer {\r\n private _cancelController = new AbortController();\r\n\r\n delays: RetryDelaySeq = RetryDelaySeq.fixed(1000);\r\n limit: number | undefined = undefined;\r\n\r\n readonly cancelDelaysChanged = new EventHandlerSet<void>();\r\n\r\n getDelay(tryIndex: number, cancellationSignal?: AbortSignal): RetryDelay {\r\n if (this.limit !== undefined && tryIndex >= this.limit)\r\n return RetryDelayLimitExceeded;\r\n\r\n const delayMs = this.delays.getDelay(tryIndex);\r\n if (tryIndex === 0 || delayMs <= 0) return RetryDelayNone;\r\n\r\n const actualDelayMs = Math.max(1, delayMs);\r\n const endsAt = Date.now() + actualDelayMs;\r\n\r\n const cancelSignal = this._cancelController.signal;\r\n const promise = new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, actualDelayMs);\r\n\r\n const onCancel = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n resolve(); // cancelDelays resolves, does NOT reject\r\n };\r\n\r\n const onAbort = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n reject(new Error('Retry delay aborted.'));\r\n };\r\n\r\n const cleanup = () => {\r\n cancelSignal.removeEventListener('abort', onCancel);\r\n cancellationSignal?.removeEventListener('abort', onAbort);\r\n };\r\n\r\n cancelSignal.addEventListener('abort', onCancel, { once: true });\r\n cancellationSignal?.addEventListener('abort', onAbort, {\r\n once: true,\r\n });\r\n });\r\n\r\n return { promise, endsAt, isLimitExceeded: false };\r\n }\r\n\r\n cancelDelays(): void {\r\n const old = this._cancelController;\r\n this._cancelController = new AbortController();\r\n old.abort();\r\n this.cancelDelaysChanged.trigger();\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -10,7 +10,10 @@ var AsyncContextKey = class {
10
10
  this.defaultValue = defaultValue;
11
11
  }
12
12
  };
13
- var abortSignalKey = new AsyncContextKey("AbortSignal", void 0);
13
+ var abortSignalKey = new AsyncContextKey(
14
+ "AbortSignal",
15
+ void 0
16
+ );
14
17
  var AsyncContext = class _AsyncContext {
15
18
  static current = void 0;
16
19
  /** Immutable empty singleton — avoids allocating new AsyncContext(). */
@@ -22,7 +25,8 @@ var AsyncContext = class _AsyncContext {
22
25
  }
23
26
  get(key) {
24
27
  if (this._values.has(key.id)) return this._values.get(key.id);
25
- if (_AsyncContext._defaults.has(key.id)) return _AsyncContext._defaults.get(key.id);
28
+ if (_AsyncContext._defaults.has(key.id))
29
+ return _AsyncContext._defaults.get(key.id);
26
30
  return key.defaultValue;
27
31
  }
28
32
  with(key, value) {
@@ -33,9 +37,11 @@ var AsyncContext = class _AsyncContext {
33
37
  activate() {
34
38
  const prev = _AsyncContext.current;
35
39
  _AsyncContext.current = this;
36
- return { dispose: () => {
37
- _AsyncContext.current = prev;
38
- } };
40
+ return {
41
+ dispose: () => {
42
+ _AsyncContext.current = prev;
43
+ }
44
+ };
39
45
  }
40
46
  run(fn) {
41
47
  const prev = _AsyncContext.current;
@@ -84,8 +90,7 @@ var AsyncLock = class {
84
90
  });
85
91
  }
86
92
  release() {
87
- if (!this._locked)
88
- throw new Error("AsyncLock is not locked.");
93
+ if (!this._locked) throw new Error("AsyncLock is not locked.");
89
94
  const next = this._queue.shift();
90
95
  if (next !== void 0) {
91
96
  next();
@@ -274,10 +279,14 @@ var RetryDelaySeq = class _RetryDelaySeq {
274
279
  return new _RetryDelaySeq(minMs, maxMs, spread, multiplier);
275
280
  }
276
281
  getDelay(failureCount) {
277
- if (this.min < 0) throw new Error("RetryDelaySeq.min must be non-negative.");
282
+ if (this.min < 0)
283
+ throw new Error("RetryDelaySeq.min must be non-negative.");
278
284
  if (failureCount <= 0) return 0;
279
285
  if (this.multiplier <= 1) {
280
- return Math.max(0, this.spread <= 0 ? this.min : applySpread(this.min, this.spread));
286
+ return Math.max(
287
+ 0,
288
+ this.spread <= 0 ? this.min : applySpread(this.min, this.spread)
289
+ );
281
290
  }
282
291
  const multiplier = Math.pow(this.multiplier, failureCount - 1);
283
292
  const raw = Math.min(this.max, this.min * multiplier);
@@ -305,8 +314,7 @@ var RetryDelayer = class {
305
314
  if (this.limit !== void 0 && tryIndex >= this.limit)
306
315
  return RetryDelayLimitExceeded;
307
316
  const delayMs = this.delays.getDelay(tryIndex);
308
- if (tryIndex === 0 || delayMs <= 0)
309
- return RetryDelayNone;
317
+ if (tryIndex === 0 || delayMs <= 0) return RetryDelayNone;
310
318
  const actualDelayMs = Math.max(1, delayMs);
311
319
  const endsAt = Date.now() + actualDelayMs;
312
320
  const cancelSignal = this._cancelController.signal;
@@ -330,7 +338,9 @@ var RetryDelayer = class {
330
338
  cancellationSignal?.removeEventListener("abort", onAbort);
331
339
  };
332
340
  cancelSignal.addEventListener("abort", onCancel, { once: true });
333
- cancellationSignal?.addEventListener("abort", onAbort, { once: true });
341
+ cancellationSignal?.addEventListener("abort", onAbort, {
342
+ once: true
343
+ });
334
344
  });
335
345
  return { promise, endsAt, isLimitExceeded: false };
336
346
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/polyfills.ts","../src/async-context.ts","../src/async-lock.ts","../src/disposable.ts","../src/promise-source.ts","../src/events.ts","../src/result.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts"],"sourcesContent":["// TC39 decorator metadata polyfill — required for Symbol.metadata support\r\n// in runtimes that don't yet implement it natively.\r\n(Symbol as any).metadata ??= Symbol(\"Symbol.metadata\");\r\n","import type { Disposable } from \"./disposable.js\";\r\n\r\n/** Typed key for values stored in AsyncContext — each subsystem defines its own keys. */\r\nexport class AsyncContextKey<T> {\r\n readonly id: symbol;\r\n readonly defaultValue: T;\r\n\r\n constructor(name: string, defaultValue: T) {\r\n this.id = Symbol(name);\r\n this.defaultValue = defaultValue;\r\n }\r\n}\r\n\r\n/** General-purpose typed context container — named for forward-compatibility with TC39 AsyncContext proposal. */\r\nexport const abortSignalKey =\r\n new AsyncContextKey<AbortSignal | undefined>(\"AbortSignal\", undefined);\r\n\r\nexport class AsyncContext {\r\n static current: AsyncContext | undefined = undefined;\r\n\r\n /** Immutable empty singleton — avoids allocating new AsyncContext(). */\r\n static readonly empty: AsyncContext = new AsyncContext();\r\n\r\n private static _defaults = new Map<symbol, unknown>();\r\n\r\n private _values: Map<symbol, unknown>;\r\n\r\n constructor(values?: Map<symbol, unknown>) {\r\n this._values = values ?? new Map();\r\n }\r\n\r\n get<T>(key: AsyncContextKey<T>): T {\r\n if (this._values.has(key.id)) return this._values.get(key.id) as T;\r\n if (AsyncContext._defaults.has(key.id)) return AsyncContext._defaults.get(key.id) as T;\r\n return key.defaultValue;\r\n }\r\n\r\n with<T>(key: AsyncContextKey<T>, value: T): AsyncContext {\r\n const copy = new Map(this._values);\r\n copy.set(key.id, value);\r\n return new AsyncContext(copy);\r\n }\r\n\r\n activate(): Disposable {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n return { dispose: () => { AsyncContext.current = prev; } };\r\n }\r\n\r\n run<R>(fn: () => R): R {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n try {\r\n return fn();\r\n } finally {\r\n AsyncContext.current = prev;\r\n }\r\n }\r\n\r\n /** Strip THIS exact instance from args if it's the last element (reference equality). */\r\n stripFromArgs(args: unknown[]): unknown[] {\r\n return args[args.length - 1] === this ? args.slice(0, -1) : args;\r\n }\r\n\r\n /** Resolve: return ctx if provided, otherwise AsyncContext.current. */\r\n static from(ctx: AsyncContext | undefined): AsyncContext | undefined {\r\n return ctx ?? AsyncContext.current;\r\n }\r\n\r\n /** Extract AsyncContext from last arg if instanceof AsyncContext, else fall back to .current. */\r\n static fromArgs(args: unknown[]): AsyncContext | undefined {\r\n const last = args[args.length - 1];\r\n return last instanceof AsyncContext ? last : AsyncContext.current;\r\n }\r\n\r\n static setDefault<T>(key: AsyncContextKey<T>, value: T): void {\r\n AsyncContext._defaults.set(key.id, value);\r\n }\r\n\r\n static getOrCreate(): AsyncContext {\r\n return AsyncContext.current ?? AsyncContext.empty;\r\n }\r\n}\r\n","/** Promise-based mutual exclusion lock for serializing async operations. */\r\nexport class AsyncLock {\r\n private _queue: (() => void)[] = [];\r\n private _locked = false;\r\n\r\n get isLocked(): boolean {\r\n return this._locked;\r\n }\r\n\r\n async acquire(): Promise<void> {\r\n if (!this._locked) {\r\n this._locked = true;\r\n return;\r\n }\r\n return new Promise<void>((resolve) => {\r\n this._queue.push(resolve);\r\n });\r\n }\r\n\r\n release(): void {\r\n if (!this._locked)\r\n throw new Error(\"AsyncLock is not locked.\");\r\n\r\n const next = this._queue.shift();\r\n if (next !== undefined) {\r\n // Transfer lock to the next waiter\r\n next();\r\n } else {\r\n this._locked = false;\r\n }\r\n }\r\n\r\n async run<T>(fn: () => T | Promise<T>): Promise<T> {\r\n await this.acquire();\r\n try {\r\n return await fn();\r\n } finally {\r\n this.release();\r\n }\r\n }\r\n}\r\n","/** Synchronous dispose pattern, similar to .NET's IDisposable. */\r\nexport interface Disposable {\r\n dispose(): void;\r\n}\r\n\r\n/** Asynchronous dispose pattern, similar to .NET's IAsyncDisposable. */\r\nexport interface AsyncDisposable {\r\n disposeAsync(): Promise<void>;\r\n}\r\n\r\n/** Aggregates multiple disposables and disposes them together. */\r\nexport class DisposableBag implements Disposable, AsyncDisposable {\r\n private _items: (Disposable | AsyncDisposable)[] = [];\r\n private _disposed = false;\r\n\r\n get isDisposed(): boolean {\r\n return this._disposed;\r\n }\r\n\r\n add(item: Disposable | AsyncDisposable): void {\r\n if (this._disposed)\r\n throw new Error(\"DisposableBag is already disposed.\");\r\n this._items.push(item);\r\n }\r\n\r\n dispose(): void {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n // Dispose in reverse order (LIFO)\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item != null && \"dispose\" in item) item.dispose();\r\n }\r\n }\r\n\r\n async disposeAsync(): Promise<void> {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item == null) continue;\r\n if (\"disposeAsync\" in item) await item.disposeAsync();\r\n else if (\"dispose\" in item) item.dispose();\r\n }\r\n }\r\n}\r\n","/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */\r\nexport class PromiseSource<T> {\r\n readonly promise: Promise<T>;\r\n private _resolve!: (value: T | PromiseLike<T>) => void;\r\n private _reject!: (reason?: unknown) => void;\r\n private _isCompleted = false;\r\n\r\n constructor() {\r\n this.promise = new Promise<T>((resolve, reject) => {\r\n this._resolve = resolve;\r\n this._reject = reject;\r\n });\r\n }\r\n\r\n get isCompleted(): boolean {\r\n return this._isCompleted;\r\n }\r\n\r\n resolve(value: T): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._resolve(value);\r\n return true;\r\n }\r\n\r\n reject(reason?: unknown): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._reject(reason);\r\n return true;\r\n }\r\n}\r\n\r\nexport const resolvedVoidPromise: Promise<void> = Promise.resolve();","import { PromiseSource } from \"./promise-source.js\";\r\n\r\n/** Typed pub/sub event handler set — similar to .NET's EventHandler<T> multicast delegate. */\r\nexport class EventHandlerSet<T> {\r\n private _handlers: Set<(arg: T) => void> = new Set();\r\n\r\n get count(): number {\r\n return this._handlers.size;\r\n }\r\n\r\n add(handler: (arg: T) => void): void {\r\n this._handlers.add(handler);\r\n }\r\n\r\n remove(handler: (arg: T) => void): void {\r\n this._handlers.delete(handler);\r\n }\r\n\r\n trigger(arg: T): void {\r\n for (const handler of this._handlers) handler(arg);\r\n }\r\n\r\n clear(): void {\r\n this._handlers.clear();\r\n }\r\n\r\n whenNext(): Promise<T> {\r\n const ps = new PromiseSource<T>();\r\n const handler = (arg: T) => {\r\n this._handlers.delete(handler);\r\n ps.resolve(arg);\r\n };\r\n this._handlers.add(handler);\r\n return ps.promise;\r\n }\r\n}\r\n","/** Common interface for types that carry a value-or-error outcome. */\r\nexport interface IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n readonly value: T;\r\n readonly error: unknown;\r\n readonly valueOrUndefined: T | undefined;\r\n}\r\n\r\n/** Immutable value-or-error container — similar to .NET's Result<T>. */\r\nexport class Result<T> implements IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n private readonly _value: T | undefined;\r\n private readonly _error: unknown;\r\n\r\n public constructor(value: T | undefined, error?: unknown) {\r\n this.hasValue = error === undefined;\r\n this.hasError = !this.hasValue;\r\n this._value = value;\r\n this._error = error;\r\n }\r\n\r\n get value(): T {\r\n if (this.hasError) throw this._error;\r\n return this._value as T;\r\n }\r\n\r\n get error(): unknown {\r\n return this._error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.hasValue ? this._value : undefined;\r\n }\r\n\r\n static ok<T>(value: T): Result<T> {\r\n return new Result<T>(value);\r\n }\r\n\r\n static error<T>(error: unknown): Result<T> {\r\n return new Result<T>(undefined, error);\r\n }\r\n}\r\n\r\nexport function result<T>(value: T, error?: unknown): Result<T> {\r\n return new Result<T>(value, error);\r\n}\r\n\r\nexport function errorResult<T>(error: unknown): Result<T> {\r\n return Result.error(error);\r\n}\r\n\r\nexport function resultFrom<T>(fn: () => T): Result<T> {\r\n try {\r\n return result(fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n\r\nexport async function resultFromAsync<T>(fn: () => Promise<T>): Promise<Result<T>> {\r\n try {\r\n return result(await fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n","// .NET counterpart: ActualLab.Time.RetryDelaySeq\r\n\r\nconst DefaultSpread = 0.1;\r\nconst DefaultMultiplier = 1.41421356237; // Math.sqrt(2)\r\n\r\nfunction applySpread(origin: number, spread: number): number {\r\n if (spread <= 0) return origin;\r\n const delta = origin * spread;\r\n return origin + (Math.random() * 2 - 1) * delta;\r\n}\r\n\r\nexport class RetryDelaySeq {\r\n readonly min: number;\r\n readonly max: number;\r\n readonly spread: number;\r\n readonly multiplier: number;\r\n\r\n constructor(min: number, max: number, spread: number = DefaultSpread, multiplier: number = DefaultMultiplier) {\r\n this.min = min;\r\n this.max = max;\r\n this.spread = spread;\r\n this.multiplier = multiplier;\r\n }\r\n\r\n static fixed(delayMs: number, spread: number = DefaultSpread): RetryDelaySeq {\r\n return new RetryDelaySeq(delayMs, delayMs, spread, 1);\r\n }\r\n\r\n static exp(\r\n minMs: number,\r\n maxMs: number,\r\n spread: number = DefaultSpread,\r\n multiplier: number = DefaultMultiplier,\r\n ): RetryDelaySeq {\r\n return new RetryDelaySeq(minMs, maxMs, spread, multiplier);\r\n }\r\n\r\n getDelay(failureCount: number): number {\r\n if (this.min < 0) throw new Error(\"RetryDelaySeq.min must be non-negative.\");\r\n if (failureCount <= 0) return 0;\r\n\r\n if (this.multiplier <= 1) {\r\n // Fixed — no exponential component\r\n return Math.max(0, this.spread <= 0 ? this.min : applySpread(this.min, this.spread));\r\n }\r\n\r\n const multiplier = Math.pow(this.multiplier, failureCount - 1);\r\n const raw = Math.min(this.max, this.min * multiplier);\r\n return Math.max(0, applySpread(raw, this.spread));\r\n }\r\n}\r\n","// .NET counterparts: ActualLab.Net.RetryDelayer, ActualLab.Net.RetryDelay\r\n\r\nimport { EventHandlerSet } from \"./events.js\";\r\nimport { RetryDelaySeq } from \"./retry-delay-seq.js\";\r\n\r\nexport interface RetryDelay {\r\n readonly promise: Promise<void>;\r\n readonly endsAt: number; // Date.now()-based timestamp, 0 = no delay\r\n readonly isLimitExceeded: boolean;\r\n}\r\n\r\nexport const RetryDelayNone: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: false,\r\n};\r\n\r\nexport const RetryDelayLimitExceeded: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: true,\r\n};\r\n\r\nexport class RetryDelayer {\r\n private _cancelController = new AbortController();\r\n\r\n delays: RetryDelaySeq = RetryDelaySeq.fixed(1000);\r\n limit: number | undefined = undefined;\r\n\r\n readonly cancelDelaysChanged = new EventHandlerSet<void>();\r\n\r\n getDelay(tryIndex: number, cancellationSignal?: AbortSignal): RetryDelay {\r\n if (this.limit !== undefined && tryIndex >= this.limit)\r\n return RetryDelayLimitExceeded;\r\n\r\n const delayMs = this.delays.getDelay(tryIndex);\r\n if (tryIndex === 0 || delayMs <= 0)\r\n return RetryDelayNone;\r\n\r\n const actualDelayMs = Math.max(1, delayMs);\r\n const endsAt = Date.now() + actualDelayMs;\r\n\r\n const cancelSignal = this._cancelController.signal;\r\n const promise = new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, actualDelayMs);\r\n\r\n const onCancel = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n resolve(); // cancelDelays resolves, does NOT reject\r\n };\r\n\r\n const onAbort = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n reject(new Error(\"Retry delay aborted.\"));\r\n };\r\n\r\n const cleanup = () => {\r\n cancelSignal.removeEventListener(\"abort\", onCancel);\r\n cancellationSignal?.removeEventListener(\"abort\", onAbort);\r\n };\r\n\r\n cancelSignal.addEventListener(\"abort\", onCancel, { once: true });\r\n cancellationSignal?.addEventListener(\"abort\", onAbort, { once: true });\r\n });\r\n\r\n return { promise, endsAt, isLimitExceeded: false };\r\n }\r\n\r\n cancelDelays(): void {\r\n const old = this._cancelController;\r\n this._cancelController = new AbortController();\r\n old.abort();\r\n this.cancelDelaysChanged.trigger();\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/polyfills.ts","../src/async-context.ts","../src/async-lock.ts","../src/disposable.ts","../src/promise-source.ts","../src/events.ts","../src/result.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts"],"sourcesContent":["// TC39 decorator metadata polyfill — required for Symbol.metadata support\r\n// in runtimes that don't yet implement it natively.\r\n(Symbol as any).metadata ??= Symbol('Symbol.metadata');\r\n","import type { Disposable } from './disposable.js';\r\n\r\n/** Typed key for values stored in AsyncContext — each subsystem defines its own keys. */\r\nexport class AsyncContextKey<T> {\r\n readonly id: symbol;\r\n readonly defaultValue: T;\r\n\r\n constructor(name: string, defaultValue: T) {\r\n this.id = Symbol(name);\r\n this.defaultValue = defaultValue;\r\n }\r\n}\r\n\r\n/** General-purpose typed context container — named for forward-compatibility with TC39 AsyncContext proposal. */\r\nexport const abortSignalKey = new AsyncContextKey<AbortSignal | undefined>(\r\n 'AbortSignal',\r\n undefined\r\n);\r\n\r\nexport class AsyncContext {\r\n static current: AsyncContext | undefined = undefined;\r\n\r\n /** Immutable empty singleton — avoids allocating new AsyncContext(). */\r\n static readonly empty: AsyncContext = new AsyncContext();\r\n\r\n private static _defaults = new Map<symbol, unknown>();\r\n\r\n private _values: Map<symbol, unknown>;\r\n\r\n constructor(values?: Map<symbol, unknown>) {\r\n this._values = values ?? new Map();\r\n }\r\n\r\n get<T>(key: AsyncContextKey<T>): T {\r\n if (this._values.has(key.id)) return this._values.get(key.id) as T;\r\n if (AsyncContext._defaults.has(key.id))\r\n return AsyncContext._defaults.get(key.id) as T;\r\n return key.defaultValue;\r\n }\r\n\r\n with<T>(key: AsyncContextKey<T>, value: T): AsyncContext {\r\n const copy = new Map(this._values);\r\n copy.set(key.id, value);\r\n return new AsyncContext(copy);\r\n }\r\n\r\n activate(): Disposable {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n return {\r\n dispose: () => {\r\n AsyncContext.current = prev;\r\n },\r\n };\r\n }\r\n\r\n run<R>(fn: () => R): R {\r\n const prev = AsyncContext.current;\r\n AsyncContext.current = this;\r\n try {\r\n return fn();\r\n } finally {\r\n AsyncContext.current = prev;\r\n }\r\n }\r\n\r\n /** Strip THIS exact instance from args if it's the last element (reference equality). */\r\n stripFromArgs(args: unknown[]): unknown[] {\r\n return args[args.length - 1] === this ? args.slice(0, -1) : args;\r\n }\r\n\r\n /** Resolve: return ctx if provided, otherwise AsyncContext.current. */\r\n static from(ctx: AsyncContext | undefined): AsyncContext | undefined {\r\n return ctx ?? AsyncContext.current;\r\n }\r\n\r\n /** Extract AsyncContext from last arg if instanceof AsyncContext, else fall back to .current. */\r\n static fromArgs(args: unknown[]): AsyncContext | undefined {\r\n const last = args[args.length - 1];\r\n return last instanceof AsyncContext ? last : AsyncContext.current;\r\n }\r\n\r\n static setDefault<T>(key: AsyncContextKey<T>, value: T): void {\r\n AsyncContext._defaults.set(key.id, value);\r\n }\r\n\r\n static getOrCreate(): AsyncContext {\r\n return AsyncContext.current ?? AsyncContext.empty;\r\n }\r\n}\r\n","/** Promise-based mutual exclusion lock for serializing async operations. */\r\nexport class AsyncLock {\r\n private _queue: (() => void)[] = [];\r\n private _locked = false;\r\n\r\n get isLocked(): boolean {\r\n return this._locked;\r\n }\r\n\r\n async acquire(): Promise<void> {\r\n if (!this._locked) {\r\n this._locked = true;\r\n return;\r\n }\r\n return new Promise<void>(resolve => {\r\n this._queue.push(resolve);\r\n });\r\n }\r\n\r\n release(): void {\r\n if (!this._locked) throw new Error('AsyncLock is not locked.');\r\n\r\n const next = this._queue.shift();\r\n if (next !== undefined) {\r\n // Transfer lock to the next waiter\r\n next();\r\n } else {\r\n this._locked = false;\r\n }\r\n }\r\n\r\n async run<T>(fn: () => T | Promise<T>): Promise<T> {\r\n await this.acquire();\r\n try {\r\n return await fn();\r\n } finally {\r\n this.release();\r\n }\r\n }\r\n}\r\n","/** Synchronous dispose pattern, similar to .NET's IDisposable. */\r\nexport interface Disposable {\r\n dispose(): void;\r\n}\r\n\r\n/** Asynchronous dispose pattern, similar to .NET's IAsyncDisposable. */\r\nexport interface AsyncDisposable {\r\n disposeAsync(): Promise<void>;\r\n}\r\n\r\n/** Aggregates multiple disposables and disposes them together. */\r\nexport class DisposableBag implements Disposable, AsyncDisposable {\r\n private _items: (Disposable | AsyncDisposable)[] = [];\r\n private _disposed = false;\r\n\r\n get isDisposed(): boolean {\r\n return this._disposed;\r\n }\r\n\r\n add(item: Disposable | AsyncDisposable): void {\r\n if (this._disposed)\r\n throw new Error('DisposableBag is already disposed.');\r\n this._items.push(item);\r\n }\r\n\r\n dispose(): void {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n // Dispose in reverse order (LIFO)\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item != null && 'dispose' in item) item.dispose();\r\n }\r\n }\r\n\r\n async disposeAsync(): Promise<void> {\r\n if (this._disposed) return;\r\n this._disposed = true;\r\n const items = this._items;\r\n this._items = [];\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n const item = items[i];\r\n if (item == null) continue;\r\n if ('disposeAsync' in item) await item.disposeAsync();\r\n else if ('dispose' in item) item.dispose();\r\n }\r\n }\r\n}\r\n","/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */\r\nexport class PromiseSource<T> {\r\n readonly promise: Promise<T>;\r\n private _resolve!: (value: T | PromiseLike<T>) => void;\r\n private _reject!: (reason?: unknown) => void;\r\n private _isCompleted = false;\r\n\r\n constructor() {\r\n this.promise = new Promise<T>((resolve, reject) => {\r\n this._resolve = resolve;\r\n this._reject = reject;\r\n });\r\n }\r\n\r\n get isCompleted(): boolean {\r\n return this._isCompleted;\r\n }\r\n\r\n resolve(value: T): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._resolve(value);\r\n return true;\r\n }\r\n\r\n reject(reason?: unknown): boolean {\r\n if (this._isCompleted) return false;\r\n this._isCompleted = true;\r\n this._reject(reason);\r\n return true;\r\n }\r\n}\r\n\r\nexport const resolvedVoidPromise: Promise<void> = Promise.resolve();\r\n","import { PromiseSource } from './promise-source.js';\r\n\r\n/** Typed pub/sub event handler set — similar to .NET's EventHandler<T> multicast delegate. */\r\nexport class EventHandlerSet<T> {\r\n private _handlers: Set<(arg: T) => void> = new Set();\r\n\r\n get count(): number {\r\n return this._handlers.size;\r\n }\r\n\r\n add(handler: (arg: T) => void): void {\r\n this._handlers.add(handler);\r\n }\r\n\r\n remove(handler: (arg: T) => void): void {\r\n this._handlers.delete(handler);\r\n }\r\n\r\n trigger(arg: T): void {\r\n for (const handler of this._handlers) handler(arg);\r\n }\r\n\r\n clear(): void {\r\n this._handlers.clear();\r\n }\r\n\r\n whenNext(): Promise<T> {\r\n const ps = new PromiseSource<T>();\r\n const handler = (arg: T) => {\r\n this._handlers.delete(handler);\r\n ps.resolve(arg);\r\n };\r\n this._handlers.add(handler);\r\n return ps.promise;\r\n }\r\n}\r\n","/** Common interface for types that carry a value-or-error outcome. */\r\nexport interface IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n readonly value: T;\r\n readonly error: unknown;\r\n readonly valueOrUndefined: T | undefined;\r\n}\r\n\r\n/** Immutable value-or-error container — similar to .NET's Result<T>. */\r\nexport class Result<T> implements IResult<T> {\r\n readonly hasValue: boolean;\r\n readonly hasError: boolean;\r\n private readonly _value: T | undefined;\r\n private readonly _error: unknown;\r\n\r\n public constructor(value: T | undefined, error?: unknown) {\r\n this.hasValue = error === undefined;\r\n this.hasError = !this.hasValue;\r\n this._value = value;\r\n this._error = error;\r\n }\r\n\r\n get value(): T {\r\n if (this.hasError) throw this._error;\r\n return this._value as T;\r\n }\r\n\r\n get error(): unknown {\r\n return this._error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.hasValue ? this._value : undefined;\r\n }\r\n\r\n static ok<T>(value: T): Result<T> {\r\n return new Result<T>(value);\r\n }\r\n\r\n static error<T>(error: unknown): Result<T> {\r\n return new Result<T>(undefined, error);\r\n }\r\n}\r\n\r\nexport function result<T>(value: T, error?: unknown): Result<T> {\r\n return new Result<T>(value, error);\r\n}\r\n\r\nexport function errorResult<T>(error: unknown): Result<T> {\r\n return Result.error(error);\r\n}\r\n\r\nexport function resultFrom<T>(fn: () => T): Result<T> {\r\n try {\r\n return result(fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n\r\nexport async function resultFromAsync<T>(\r\n fn: () => Promise<T>\r\n): Promise<Result<T>> {\r\n try {\r\n return result(await fn());\r\n } catch (e) {\r\n return errorResult(e);\r\n }\r\n}\r\n","// .NET counterpart: ActualLab.Time.RetryDelaySeq\r\n\r\nconst DefaultSpread = 0.1;\r\nconst DefaultMultiplier = 1.41421356237; // Math.sqrt(2)\r\n\r\nfunction applySpread(origin: number, spread: number): number {\r\n if (spread <= 0) return origin;\r\n const delta = origin * spread;\r\n return origin + (Math.random() * 2 - 1) * delta;\r\n}\r\n\r\nexport class RetryDelaySeq {\r\n readonly min: number;\r\n readonly max: number;\r\n readonly spread: number;\r\n readonly multiplier: number;\r\n\r\n constructor(\r\n min: number,\r\n max: number,\r\n spread: number = DefaultSpread,\r\n multiplier: number = DefaultMultiplier\r\n ) {\r\n this.min = min;\r\n this.max = max;\r\n this.spread = spread;\r\n this.multiplier = multiplier;\r\n }\r\n\r\n static fixed(\r\n delayMs: number,\r\n spread: number = DefaultSpread\r\n ): RetryDelaySeq {\r\n return new RetryDelaySeq(delayMs, delayMs, spread, 1);\r\n }\r\n\r\n static exp(\r\n minMs: number,\r\n maxMs: number,\r\n spread: number = DefaultSpread,\r\n multiplier: number = DefaultMultiplier\r\n ): RetryDelaySeq {\r\n return new RetryDelaySeq(minMs, maxMs, spread, multiplier);\r\n }\r\n\r\n getDelay(failureCount: number): number {\r\n if (this.min < 0)\r\n throw new Error('RetryDelaySeq.min must be non-negative.');\r\n if (failureCount <= 0) return 0;\r\n\r\n if (this.multiplier <= 1) {\r\n // Fixed — no exponential component\r\n return Math.max(\r\n 0,\r\n this.spread <= 0 ? this.min : applySpread(this.min, this.spread)\r\n );\r\n }\r\n\r\n const multiplier = Math.pow(this.multiplier, failureCount - 1);\r\n const raw = Math.min(this.max, this.min * multiplier);\r\n return Math.max(0, applySpread(raw, this.spread));\r\n }\r\n}\r\n","// .NET counterparts: ActualLab.Net.RetryDelayer, ActualLab.Net.RetryDelay\r\n\r\nimport { EventHandlerSet } from './events.js';\r\nimport { RetryDelaySeq } from './retry-delay-seq.js';\r\n\r\nexport interface RetryDelay {\r\n readonly promise: Promise<void>;\r\n readonly endsAt: number; // Date.now()-based timestamp, 0 = no delay\r\n readonly isLimitExceeded: boolean;\r\n}\r\n\r\nexport const RetryDelayNone: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: false,\r\n};\r\n\r\nexport const RetryDelayLimitExceeded: RetryDelay = {\r\n promise: Promise.resolve(),\r\n endsAt: 0,\r\n isLimitExceeded: true,\r\n};\r\n\r\nexport class RetryDelayer {\r\n private _cancelController = new AbortController();\r\n\r\n delays: RetryDelaySeq = RetryDelaySeq.fixed(1000);\r\n limit: number | undefined = undefined;\r\n\r\n readonly cancelDelaysChanged = new EventHandlerSet<void>();\r\n\r\n getDelay(tryIndex: number, cancellationSignal?: AbortSignal): RetryDelay {\r\n if (this.limit !== undefined && tryIndex >= this.limit)\r\n return RetryDelayLimitExceeded;\r\n\r\n const delayMs = this.delays.getDelay(tryIndex);\r\n if (tryIndex === 0 || delayMs <= 0) return RetryDelayNone;\r\n\r\n const actualDelayMs = Math.max(1, delayMs);\r\n const endsAt = Date.now() + actualDelayMs;\r\n\r\n const cancelSignal = this._cancelController.signal;\r\n const promise = new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, actualDelayMs);\r\n\r\n const onCancel = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n resolve(); // cancelDelays resolves, does NOT reject\r\n };\r\n\r\n const onAbort = () => {\r\n clearTimeout(timer);\r\n cleanup();\r\n reject(new Error('Retry delay aborted.'));\r\n };\r\n\r\n const cleanup = () => {\r\n cancelSignal.removeEventListener('abort', onCancel);\r\n cancellationSignal?.removeEventListener('abort', onAbort);\r\n };\r\n\r\n cancelSignal.addEventListener('abort', onCancel, { once: true });\r\n cancellationSignal?.addEventListener('abort', onAbort, {\r\n once: true,\r\n });\r\n });\r\n\r\n return { promise, endsAt, isLimitExceeded: false };\r\n }\r\n\r\n cancelDelays(): void {\r\n const old = this._cancelController;\r\n this._cancelController = new AbortController();\r\n old.abort();\r\n this.cancelDelaysChanged.trigger();\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actuallab/core",
3
- "version": "12.1.100",
3
+ "version": "12.2.21",
4
4
  "description": "Core primitives for ActualLab TypeScript libraries",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",