@actuallab/core 12.3.4 → 12.3.14

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
@@ -169,7 +169,7 @@ var DisposableBag = class {
169
169
  this._items = [];
170
170
  for (let i = items.length - 1; i >= 0; i--) {
171
171
  const item = items[i];
172
- if (item != null && "dispose" in item) item.dispose();
172
+ if ("dispose" in item) item.dispose();
173
173
  }
174
174
  }
175
175
  async disposeAsync() {
@@ -179,7 +179,6 @@ var DisposableBag = class {
179
179
  this._items = [];
180
180
  for (let i = items.length - 1; i >= 0; i--) {
181
181
  const item = items[i];
182
- if (item == null) continue;
183
182
  if ("disposeAsync" in item) await item.disposeAsync();
184
183
  else if ("dispose" in item) item.dispose();
185
184
  }
@@ -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 {\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// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\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<symbol, unknown>();\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 = new Set<(arg: T) => void>();\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":[]}
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// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\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<symbol, unknown>();\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 ('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 ('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 = new Set<(arg: T) => void>();\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
@@ -127,7 +127,7 @@ var DisposableBag = class {
127
127
  this._items = [];
128
128
  for (let i = items.length - 1; i >= 0; i--) {
129
129
  const item = items[i];
130
- if (item != null && "dispose" in item) item.dispose();
130
+ if ("dispose" in item) item.dispose();
131
131
  }
132
132
  }
133
133
  async disposeAsync() {
@@ -137,7 +137,6 @@ var DisposableBag = class {
137
137
  this._items = [];
138
138
  for (let i = items.length - 1; i >= 0; i--) {
139
139
  const item = items[i];
140
- if (item == null) continue;
141
140
  if ("disposeAsync" in item) await item.disposeAsync();
142
141
  else if ("dispose" in item) item.dispose();
143
142
  }
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// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\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<symbol, unknown>();\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 = new Set<(arg: T) => void>();\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":[]}
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// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\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<symbol, unknown>();\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 ('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 ('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 = new Set<(arg: T) => void>();\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":";AAGC,OAAe,aAAa,uBAAO,iBAAiB;;;ACA9C,IAAM,kBAAN,MAAyB;AAAA,EACnB;AAAA,EACA;AAAA,EAET,YAAY,MAAc,cAAiB;AACvC,SAAK,KAAK,OAAO,IAAI;AACrB,SAAK,eAAe;AAAA,EACxB;AACJ;AAGO,IAAM,iBAAiB,IAAI;AAAA,EAC9B;AAAA,EACA;AACJ;AAEO,IAAM,eAAN,MAAM,cAAa;AAAA,EACtB,OAAO,UAAoC;AAAA;AAAA,EAG3C,OAAgB,QAAsB,IAAI,cAAa;AAAA,EAEvD,OAAe,YAAY,oBAAI,IAAqB;AAAA,EAE5C;AAAA,EAER,YAAY,QAA+B;AACvC,SAAK,UAAU,UAAU,oBAAI,IAAqB;AAAA,EACtD;AAAA,EAEA,IAAO,KAA4B;AAC/B,QAAI,KAAK,QAAQ,IAAI,IAAI,EAAE,EAAG,QAAO,KAAK,QAAQ,IAAI,IAAI,EAAE;AAC5D,QAAI,cAAa,UAAU,IAAI,IAAI,EAAE;AACjC,aAAO,cAAa,UAAU,IAAI,IAAI,EAAE;AAC5C,WAAO,IAAI;AAAA,EACf;AAAA,EAEA,KAAQ,KAAyB,OAAwB;AACrD,UAAM,OAAO,IAAI,IAAI,KAAK,OAAO;AACjC,SAAK,IAAI,IAAI,IAAI,KAAK;AACtB,WAAO,IAAI,cAAa,IAAI;AAAA,EAChC;AAAA,EAEA,WAAuB;AACnB,UAAM,OAAO,cAAa;AAC1B,kBAAa,UAAU;AACvB,WAAO;AAAA,MACH,SAAS,MAAM;AACX,sBAAa,UAAU;AAAA,MAC3B;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,IAAO,IAAgB;AACnB,UAAM,OAAO,cAAa;AAC1B,kBAAa,UAAU;AACvB,QAAI;AACA,aAAO,GAAG;AAAA,IACd,UAAE;AACE,oBAAa,UAAU;AAAA,IAC3B;AAAA,EACJ;AAAA;AAAA,EAGA,cAAc,MAA4B;AACtC,WAAO,KAAK,KAAK,SAAS,CAAC,MAAM,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI;AAAA,EAChE;AAAA;AAAA,EAGA,OAAO,KAAK,KAAyD;AACjE,WAAO,OAAO,cAAa;AAAA,EAC/B;AAAA;AAAA,EAGA,OAAO,SAAS,MAA2C;AACvD,UAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AACjC,WAAO,gBAAgB,gBAAe,OAAO,cAAa;AAAA,EAC9D;AAAA,EAEA,OAAO,WAAc,KAAyB,OAAgB;AAC1D,kBAAa,UAAU,IAAI,IAAI,IAAI,KAAK;AAAA,EAC5C;AAAA,EAEA,OAAO,cAA4B;AAC/B,WAAO,cAAa,WAAW,cAAa;AAAA,EAChD;AACJ;;;ACxFO,IAAM,YAAN,MAAgB;AAAA,EACX,SAAyB,CAAC;AAAA,EAC1B,UAAU;AAAA,EAElB,IAAI,WAAoB;AACpB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,UAAyB;AAC3B,QAAI,CAAC,KAAK,SAAS;AACf,WAAK,UAAU;AACf;AAAA,IACJ;AACA,WAAO,IAAI,QAAc,aAAW;AAChC,WAAK,OAAO,KAAK,OAAO;AAAA,IAC5B,CAAC;AAAA,EACL;AAAA,EAEA,UAAgB;AACZ,QAAI,CAAC,KAAK,QAAS,OAAM,IAAI,MAAM,0BAA0B;AAE7D,UAAM,OAAO,KAAK,OAAO,MAAM;AAC/B,QAAI,SAAS,QAAW;AAEpB,WAAK;AAAA,IACT,OAAO;AACH,WAAK,UAAU;AAAA,IACnB;AAAA,EACJ;AAAA,EAEA,MAAM,IAAO,IAAsC;AAC/C,UAAM,KAAK,QAAQ;AACnB,QAAI;AACA,aAAO,MAAM,GAAG;AAAA,IACpB,UAAE;AACE,WAAK,QAAQ;AAAA,IACjB;AAAA,EACJ;AACJ;;;AC5BO,IAAM,gBAAN,MAA2D;AAAA,EACtD,SAA2C,CAAC;AAAA,EAC5C,YAAY;AAAA,EAEpB,IAAI,aAAsB;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,MAA0C;AAC1C,QAAI,KAAK;AACL,YAAM,IAAI,MAAM,oCAAoC;AACxD,SAAK,OAAO,KAAK,IAAI;AAAA,EACzB;AAAA,EAEA,UAAgB;AACZ,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,UAAM,QAAQ,KAAK;AACnB,SAAK,SAAS,CAAC;AAEf,aAAS,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AACxC,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,aAAa,KAAM,MAAK,QAAQ;AAAA,IACxC;AAAA,EACJ;AAAA,EAEA,MAAM,eAA8B;AAChC,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,UAAM,QAAQ,KAAK;AACnB,SAAK,SAAS,CAAC;AACf,aAAS,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AACxC,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,kBAAkB,KAAM,OAAM,KAAK,aAAa;AAAA,eAC3C,aAAa,KAAM,MAAK,QAAQ;AAAA,IAC7C;AAAA,EACJ;AACJ;;;AC/CO,IAAM,gBAAN,MAAuB;AAAA,EACjB;AAAA,EACD;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EAEvB,cAAc;AACV,SAAK,UAAU,IAAI,QAAW,CAAC,SAAS,WAAW;AAC/C,WAAK,WAAW;AAChB,WAAK,UAAU;AAAA,IACnB,CAAC;AAAA,EACL;AAAA,EAEA,IAAI,cAAuB;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAAQ,OAAmB;AACvB,QAAI,KAAK,aAAc,QAAO;AAC9B,SAAK,eAAe;AACpB,SAAK,SAAS,KAAK;AACnB,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,QAA2B;AAC9B,QAAI,KAAK,aAAc,QAAO;AAC9B,SAAK,eAAe;AACpB,SAAK,QAAQ,MAAM;AACnB,WAAO;AAAA,EACX;AACJ;AAEO,IAAM,sBAAqC,QAAQ,QAAQ;;;AC9B3D,IAAM,kBAAN,MAAyB;AAAA,EACpB,YAAY,oBAAI,IAAsB;AAAA,EAE9C,IAAI,QAAgB;AAChB,WAAO,KAAK,UAAU;AAAA,EAC1B;AAAA,EAEA,IAAI,SAAiC;AACjC,SAAK,UAAU,IAAI,OAAO;AAAA,EAC9B;AAAA,EAEA,OAAO,SAAiC;AACpC,SAAK,UAAU,OAAO,OAAO;AAAA,EACjC;AAAA,EAEA,QAAQ,KAAc;AAClB,eAAW,WAAW,KAAK,UAAW,SAAQ,GAAG;AAAA,EACrD;AAAA,EAEA,QAAc;AACV,SAAK,UAAU,MAAM;AAAA,EACzB;AAAA,EAEA,WAAuB;AACnB,UAAM,KAAK,IAAI,cAAiB;AAChC,UAAM,UAAU,CAAC,QAAW;AACxB,WAAK,UAAU,OAAO,OAAO;AAC7B,SAAG,QAAQ,GAAG;AAAA,IAClB;AACA,SAAK,UAAU,IAAI,OAAO;AAC1B,WAAO,GAAG;AAAA,EACd;AACJ;;;ACzBO,IAAM,SAAN,MAAM,QAAgC;AAAA,EAChC;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EAEV,YAAY,OAAsB,OAAiB;AACtD,SAAK,WAAW,UAAU;AAC1B,SAAK,WAAW,CAAC,KAAK;AACtB,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,IAAI,QAAW;AACX,QAAI,KAAK,SAAU,OAAM,KAAK;AAC9B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,QAAiB;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,mBAAkC;AAClC,WAAO,KAAK,WAAW,KAAK,SAAS;AAAA,EACzC;AAAA,EAEA,OAAO,GAAM,OAAqB;AAC9B,WAAO,IAAI,QAAU,KAAK;AAAA,EAC9B;AAAA,EAEA,OAAO,MAAS,OAA2B;AACvC,WAAO,IAAI,QAAU,QAAW,KAAK;AAAA,EACzC;AACJ;AAEO,SAAS,OAAU,OAAU,OAA4B;AAC5D,SAAO,IAAI,OAAU,OAAO,KAAK;AACrC;AAEO,SAAS,YAAe,OAA2B;AACtD,SAAO,OAAO,MAAM,KAAK;AAC7B;AAEO,SAAS,WAAc,IAAwB;AAClD,MAAI;AACA,WAAO,OAAO,GAAG,CAAC;AAAA,EACtB,SAAS,GAAG;AACR,WAAO,YAAY,CAAC;AAAA,EACxB;AACJ;AAEA,eAAsB,gBAClB,IACkB;AAClB,MAAI;AACA,WAAO,OAAO,MAAM,GAAG,CAAC;AAAA,EAC5B,SAAS,GAAG;AACR,WAAO,YAAY,CAAC;AAAA,EACxB;AACJ;;;ACnEA,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAE1B,SAAS,YAAY,QAAgB,QAAwB;AACzD,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,QAAQ,SAAS;AACvB,SAAO,UAAU,KAAK,OAAO,IAAI,IAAI,KAAK;AAC9C;AAEO,IAAM,gBAAN,MAAM,eAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACI,KACA,KACA,SAAiB,eACjB,aAAqB,mBACvB;AACE,SAAK,MAAM;AACX,SAAK,MAAM;AACX,SAAK,SAAS;AACd,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,OAAO,MACH,SACA,SAAiB,eACJ;AACb,WAAO,IAAI,eAAc,SAAS,SAAS,QAAQ,CAAC;AAAA,EACxD;AAAA,EAEA,OAAO,IACH,OACA,OACA,SAAiB,eACjB,aAAqB,mBACR;AACb,WAAO,IAAI,eAAc,OAAO,OAAO,QAAQ,UAAU;AAAA,EAC7D;AAAA,EAEA,SAAS,cAA8B;AACnC,QAAI,KAAK,MAAM;AACX,YAAM,IAAI,MAAM,yCAAyC;AAC7D,QAAI,gBAAgB,EAAG,QAAO;AAE9B,QAAI,KAAK,cAAc,GAAG;AAEtB,aAAO,KAAK;AAAA,QACR;AAAA,QACA,KAAK,UAAU,IAAI,KAAK,MAAM,YAAY,KAAK,KAAK,KAAK,MAAM;AAAA,MACnE;AAAA,IACJ;AAEA,UAAM,aAAa,KAAK,IAAI,KAAK,YAAY,eAAe,CAAC;AAC7D,UAAM,MAAM,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,UAAU;AACpD,WAAO,KAAK,IAAI,GAAG,YAAY,KAAK,KAAK,MAAM,CAAC;AAAA,EACpD;AACJ;;;ACnDO,IAAM,iBAA6B;AAAA,EACtC,SAAS,QAAQ,QAAQ;AAAA,EACzB,QAAQ;AAAA,EACR,iBAAiB;AACrB;AAEO,IAAM,0BAAsC;AAAA,EAC/C,SAAS,QAAQ,QAAQ;AAAA,EACzB,QAAQ;AAAA,EACR,iBAAiB;AACrB;AAEO,IAAM,eAAN,MAAmB;AAAA,EACd,oBAAoB,IAAI,gBAAgB;AAAA,EAEhD,SAAwB,cAAc,MAAM,GAAI;AAAA,EAChD,QAA4B;AAAA,EAEnB,sBAAsB,IAAI,gBAAsB;AAAA,EAEzD,SAAS,UAAkB,oBAA8C;AACrE,QAAI,KAAK,UAAU,UAAa,YAAY,KAAK;AAC7C,aAAO;AAEX,UAAM,UAAU,KAAK,OAAO,SAAS,QAAQ;AAC7C,QAAI,aAAa,KAAK,WAAW,EAAG,QAAO;AAE3C,UAAM,gBAAgB,KAAK,IAAI,GAAG,OAAO;AACzC,UAAM,SAAS,KAAK,IAAI,IAAI;AAE5B,UAAM,eAAe,KAAK,kBAAkB;AAC5C,UAAM,UAAU,IAAI,QAAc,CAAC,SAAS,WAAW;AACnD,YAAM,QAAQ,WAAW,MAAM;AAC3B,gBAAQ;AACR,gBAAQ;AAAA,MACZ,GAAG,aAAa;AAEhB,YAAM,WAAW,MAAM;AACnB,qBAAa,KAAK;AAClB,gBAAQ;AACR,gBAAQ;AAAA,MACZ;AAEA,YAAM,UAAU,MAAM;AAClB,qBAAa,KAAK;AAClB,gBAAQ;AACR,eAAO,IAAI,MAAM,sBAAsB,CAAC;AAAA,MAC5C;AAEA,YAAM,UAAU,MAAM;AAClB,qBAAa,oBAAoB,SAAS,QAAQ;AAClD,4BAAoB,oBAAoB,SAAS,OAAO;AAAA,MAC5D;AAEA,mBAAa,iBAAiB,SAAS,UAAU,EAAE,MAAM,KAAK,CAAC;AAC/D,0BAAoB,iBAAiB,SAAS,SAAS;AAAA,QACnD,MAAM;AAAA,MACV,CAAC;AAAA,IACL,CAAC;AAED,WAAO,EAAE,SAAS,QAAQ,iBAAiB,MAAM;AAAA,EACrD;AAAA,EAEA,eAAqB;AACjB,UAAM,MAAM,KAAK;AACjB,SAAK,oBAAoB,IAAI,gBAAgB;AAC7C,QAAI,MAAM;AACV,SAAK,oBAAoB,QAAQ;AAAA,EACrC;AACJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actuallab/core",
3
- "version": "12.3.4",
3
+ "version": "12.3.14",
4
4
  "description": "Core primitives for ActualLab TypeScript libraries",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",