@actuallab/core 13.0.12 → 13.0.15
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 +11 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -655,6 +655,7 @@ var AsyncLock = class {
|
|
|
655
655
|
// src/promise-source.ts
|
|
656
656
|
var PromiseSource = class {
|
|
657
657
|
promise;
|
|
658
|
+
[Symbol.toStringTag] = "Promise";
|
|
658
659
|
_resolve;
|
|
659
660
|
_reject;
|
|
660
661
|
_isCompleted = false;
|
|
@@ -679,6 +680,15 @@ var PromiseSource = class {
|
|
|
679
680
|
this._reject(reason);
|
|
680
681
|
return true;
|
|
681
682
|
}
|
|
683
|
+
then(onfulfilled, onrejected) {
|
|
684
|
+
return this.promise.then(onfulfilled, onrejected);
|
|
685
|
+
}
|
|
686
|
+
catch(onrejected) {
|
|
687
|
+
return this.promise.catch(onrejected);
|
|
688
|
+
}
|
|
689
|
+
finally(onfinally) {
|
|
690
|
+
return this.promise.finally(onfinally);
|
|
691
|
+
}
|
|
682
692
|
};
|
|
683
693
|
var resolvedVoidPromise = Promise.resolve();
|
|
684
694
|
|
|
@@ -707,7 +717,7 @@ var EventHandlerSet = class {
|
|
|
707
717
|
ps.resolve(arg);
|
|
708
718
|
};
|
|
709
719
|
this._handlers.add(handler);
|
|
710
|
-
return ps
|
|
720
|
+
return ps;
|
|
711
721
|
}
|
|
712
722
|
};
|
|
713
723
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/polyfills.ts","../src/disposable.ts","../src/logging-init.ts","../src/logging.ts","../src/result.ts","../src/async-context.ts","../src/async-lock.ts","../src/promise-source.ts","../src/events.ts","../src/withTimeout.ts","../src/promise-source-with-timeout.ts","../src/resolved-promise.ts","../src/timed-out.ts","../src/delay.ts","../src/abort-promise.ts","../src/internal-logging.ts","../src/throttle.ts","../src/serialize.ts","../src/ring-buffer.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts","../src/retry.ts"],"sourcesContent":["import './polyfills.js';\n\n// Disposable\nexport type { Disposable, AsyncDisposable } from './disposable.js';\nexport { DisposableBag } from './disposable.js';\n\n// Logging\nexport type { LogRef, LogScopeFns } from './logging.js';\nexport { Log, LogLevel, createLogProvider } from './logging.js';\nexport { initLogging, initWorkerLogging, LogLevelController } from './logging-init.js';\n\n// Result & IResult\nexport type { IResult } from './result.js';\nexport {\n Result,\n result,\n errorResult,\n resultFrom,\n resultFromAsync,\n} from './result.js';\n\n// Async-related\nexport {\n AsyncContext,\n AsyncContextKey,\n abortSignalKey,\n} from './async-context.js';\nexport { AsyncLock } from './async-lock.js';\n\n// Event handling, primises\nexport { EventHandlerSet } from './events.js';\nexport { PromiseSource, resolvedVoidPromise } from './promise-source.js';\nexport { PromiseSourceWithTimeout } from './promise-source-with-timeout.js';\nexport { ResolvedPromise } from './resolved-promise.js';\nexport { TimedOut } from './timed-out.js';\nexport { TimeoutError, withTimeout } from './withTimeout.js';\nexport { delayAsync, delayAsyncWith } from './delay.js';\nexport { abortPromise } from './abort-promise.js';\n\n// Higher-order async operators\nexport type { ResettableFunc, ThrottleMode } from './throttle.js';\nexport { throttle, debounce } from './throttle.js';\nexport { serialize } from './serialize.js';\n\n// Collections\nexport { RingBuffer } from './ring-buffer.js';\n\n// Resilience\nexport { RetryDelaySeq } from './retry-delay-seq.js';\nexport type { RetryDelay } from './retry-delayer.js';\nexport {\n RetryDelayer,\n RetryDelayNone,\n RetryDelayLimitExceeded,\n} from './retry-delayer.js';\nexport type { RetryDelaySchedule } from './retry.js';\nexport { retry, catchErrors } from './retry.js';\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","/** 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","// Initialization helpers for the logging system.\n//\n// The Log class uses a single Map<string, LogLevel> to determine the minimum\n// level for each scope. This module is responsible for:\n// - Persisting the map across page reloads via localStorage on the main\n// thread, and via IndexedDB for workers.\n// - Exposing a globally accessible LogLevelController so developers can tweak\n// levels at runtime from the browser dev console (globalThis.logLevels).\n//\n// initLogging() is idempotent and called automatically on the first Log.get().\n//\n// Runtime override examples (paste into browser dev console):\n// logLevels.override('rpc.RpcPeer', 1) // exact: one scope to Debug\n// logLevels.override('rpc.*', 1) // prefix: all rpc.* scopes\n// logLevels.override('*Video*', 1) // contains: every scope with 'Video'\n// logLevels.override('*Decoder', 1) // suffix: every scope ending in 'Decoder'\n// logLevels.reset() // reset to package defaults\n// logLevels.clear() // clear all overrides\n\nimport { Log, LogLevel } from './logging.js';\n\nconst GlobalThisKey = 'logLevels';\nconst StorageKey = 'logLevels';\nconst DateStorageKey = `${StorageKey}.date`;\nconst MaxStorageAge = 86_400_000 * 3; // 3 days\nconst IndexedDbName = 'actuallab-logging';\nconst IndexedDbStore = 'settings';\nconst IndexedDbKey = 'logLevels';\n\nconst localStorage: Storage | null = tryGetLocalStorage();\n\n// Workers, worklets, and service workers run in separate JS realms with\n// their own globalThis. Within one realm, esbuild can also produce multiple\n// chunks that each carry their own copy of @actuallab/core (so multiple\n// distinct `Log` classes exist). We want the install + restore + console\n// message to happen exactly once per realm — gate via globalThis.logLevels.\nconst isMainThread = typeof window !== 'undefined';\n\nexport function initLogging(): void {\n // Warn is the global baseline — packages set per-scope defaults\n // (typically Info or Warn) via createLogProvider.\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n // Another chunk in this realm already initialized. Mirror its\n // overrides into our local Log.minLevels so this Log class observes\n // the same effective levels. (Each chunk has its own Log class with\n // its own static minLevels Map — they only converge through this\n // one-shot copy at init time.)\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = restore(minLevels);\n if (wasRestored) {\n if (isMainThread)\n console.log('Logging: logLevels are restored');\n }\n else {\n if (isMainThread)\n console.log('Logging: logLevels are reset');\n reset(minLevels);\n }\n}\n\n/** Worker bootstrap path: await this before dynamically importing any module\n * that may call getLogs() at top level. */\nexport async function initWorkerLogging(): Promise<void> {\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = await restoreFromIndexedDb(minLevels);\n if (!wasRestored)\n reset(minLevels, false);\n}\n\nexport class LogLevelController {\n constructor(private minLevels: Map<string, LogLevel>)\n { }\n\n /** Internal: used by initLogging() in secondary bundles to share the\n * primary bundle's minLevels map. */\n public getMinLevels(): Map<string, LogLevel> {\n return this.minLevels;\n }\n\n /** List the current set of overrides. */\n public list(): Record<string, LogLevel> {\n return Object.fromEntries(this.minLevels);\n }\n\n /** Print every known scope's effective level to the console as a table.\n * Shows: scope, effective level, the source ('override' / 'default-key' /\n * 'package-default' / 'baseline'), and the package default for reference.\n * Use this from the dev console to discover what to pass to override(). */\n public dump(): void {\n const baseline = Log.defaultMinLevel;\n const globalOverride = this.minLevels.get('default');\n const allScopes = new Set<string>([\n ...Log.knownScopes,\n ...Log.scopeDefaults.keys(),\n ...this.minLevels.keys(),\n ]);\n // Drop the special 'default' bucket — surfaced separately below.\n allScopes.delete('default');\n const rows: Record<string, {\n level: string;\n source: string;\n packageDefault: string;\n }> = {};\n const sorted = [...allScopes].sort();\n for (const scope of sorted) {\n const override = this.minLevels.get(scope);\n const pkgDefault = Log.scopeDefaults.get(scope);\n let level: LogLevel;\n let source: string;\n if (override !== undefined) {\n level = override;\n source = 'override';\n }\n else if (globalOverride !== undefined) {\n level = globalOverride;\n source = \"minLevels.get('default')\";\n }\n else if (pkgDefault !== undefined) {\n level = pkgDefault;\n source = 'package-default';\n }\n else {\n level = baseline;\n source = 'baseline';\n }\n rows[scope] = {\n level: LogLevel[level],\n source,\n packageDefault: pkgDefault === undefined ? '-' : LogLevel[pkgDefault],\n };\n }\n console.table(rows);\n console.log(\n `Baseline: ${LogLevel[baseline]}` +\n (globalOverride === undefined ? '' : `, default override: ${LogLevel[globalOverride]}`),\n );\n }\n\n /** Override the level for every scope matching a glob-like pattern.\n * `*` matches any sequence of characters; everything else is literal.\n * Examples:\n * override('rpc.RpcPeer', 1) // exact — one scope to Debug\n * override('rpc.*', 1) // prefix — every scope starting with 'rpc.'\n * override('*rpc*', 1) // contains — every scope with 'rpc' in it\n * override('*Peer', 1) // suffix — every scope ending with 'Peer'\n * Matches scopes that are user-overridden, package-registered (defaults),\n * or have ever been requested via Log.get(). If the pattern has no `*`\n * and nothing known matches, the literal scope is set anyway — so an\n * exact-name override placed before its scope is loaded still applies.\n * Persisted to localStorage + IndexedDB. */\n public override(pattern: string, newLevel: LogLevel): void {\n const matched = new Set<string>();\n if (pattern.includes('*')) {\n const re = patternToRegExp(pattern);\n for (const [scope] of this.minLevels)\n if (re.test(scope)) matched.add(scope);\n for (const [scope] of Log.scopeDefaults)\n if (re.test(scope)) matched.add(scope);\n for (const scope of Log.knownScopes)\n if (re.test(scope)) matched.add(scope);\n }\n else {\n matched.add(pattern);\n }\n for (const scope of matched)\n this.minLevels.set(scope, newLevel);\n persist(this.minLevels);\n }\n\n /** Reset all overrides; package defaults take effect again. Persisted. */\n public reset(): void {\n reset(this.minLevels);\n }\n\n /** Clear all overrides (no global default unless `defaultLevel` is given). */\n public clear(defaultLevel?: LogLevel): void {\n this.minLevels.clear();\n if (defaultLevel !== undefined)\n this.minLevels.set('default', defaultLevel);\n persist(this.minLevels);\n }\n}\n\nfunction patternToRegExp(pattern: string): RegExp {\n // Escape regex metacharacters except `*`, then turn each `*` into `.*`.\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*');\n return new RegExp(`^${escaped}$`);\n}\n\ninterface PersistedLogLevels {\n date: number;\n entries: [string, LogLevel][];\n}\n\nfunction restore(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = readFromStorage(localStorage);\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nasync function restoreFromIndexedDb(minLevels: Map<string, LogLevel>): Promise<boolean> {\n const snapshot = await readFromIndexedDb();\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nfunction readFromStorage(storage: Storage | null): PersistedLogLevels | null {\n if (!storage)\n return null;\n\n try {\n const dateJson = storage.getItem(DateStorageKey);\n const entriesJson = storage.getItem(StorageKey);\n if (!dateJson || !entriesJson)\n return null;\n\n return {\n date: JSON.parse(dateJson) as number,\n entries: JSON.parse(entriesJson) as [string, LogLevel][],\n };\n } catch {\n return null;\n }\n}\n\nfunction applySnapshot(minLevels: Map<string, LogLevel>, snapshot: PersistedLogLevels): boolean {\n if (typeof snapshot.date !== 'number')\n return false;\n if (Date.now() - snapshot.date > MaxStorageAge)\n return false;\n if (!Array.isArray(snapshot.entries))\n return false;\n\n minLevels.clear();\n for (const entry of snapshot.entries) {\n // Runtime guard for JSON-parsed input — types claim it's a tuple, but\n // localStorage may carry corrupted data. eslint flags the length check\n // as always-false against the static type; that's the point.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!Array.isArray(entry) || entry.length !== 2)\n return false;\n const [key, value] = entry;\n if (typeof key !== 'string' || typeof value !== 'number')\n return false;\n minLevels.set(key, value);\n }\n\n return true;\n}\n\nfunction persist(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = createSnapshot(minLevels);\n let wasPersisted = false;\n\n if (localStorage) {\n try {\n localStorage.setItem(DateStorageKey, JSON.stringify(snapshot.date));\n localStorage.setItem(StorageKey, JSON.stringify(snapshot.entries));\n wasPersisted = true;\n } catch {\n // Storage may be unavailable in private / sandboxed contexts.\n }\n }\n\n void writeToIndexedDb(snapshot);\n return wasPersisted;\n}\n\nfunction createSnapshot(minLevels: Map<string, LogLevel>): PersistedLogLevels {\n return {\n date: Date.now(),\n entries: Array.from(minLevels.entries()),\n };\n}\n\nfunction tryGetLocalStorage(): Storage | null {\n if (typeof globalThis === 'undefined' || !('localStorage' in globalThis))\n return null;\n\n try {\n return (globalThis as unknown as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n}\n\nasync function openLoggingDb(): Promise<IDBDatabase | null> {\n if (typeof indexedDB === 'undefined')\n return null;\n\n return new Promise(resolve => {\n const request = indexedDB.open(IndexedDbName, 1);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(IndexedDbStore))\n db.createObjectStore(IndexedDbStore);\n };\n request.onerror = () => resolve(null);\n request.onblocked = () => resolve(null);\n request.onsuccess = () => resolve(request.result);\n });\n}\n\nasync function readFromIndexedDb(): Promise<PersistedLogLevels | null> {\n const db = await openLoggingDb();\n if (!db)\n return null;\n\n return new Promise(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readonly');\n const request = tx.objectStore(IndexedDbStore).get(IndexedDbKey);\n request.onerror = () => resolve(null);\n request.onsuccess = () => resolve(request.result as PersistedLogLevels | null);\n tx.oncomplete = () => db.close();\n tx.onerror = () => db.close();\n tx.onabort = () => db.close();\n });\n}\n\nasync function writeToIndexedDb(snapshot: PersistedLogLevels): Promise<void> {\n const db = await openLoggingDb();\n if (!db)\n return;\n\n await new Promise<void>(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readwrite');\n tx.objectStore(IndexedDbStore).put(snapshot, IndexedDbKey);\n tx.oncomplete = () => {\n db.close();\n resolve();\n };\n tx.onerror = () => {\n db.close();\n resolve();\n };\n tx.onabort = () => {\n db.close();\n resolve();\n };\n });\n}\n\nfunction reset(minLevels: Map<string, LogLevel>, mustPersist = true): void {\n minLevels.clear();\n // Add per-scope defaults here for development.\n // Use prefix conventions: 'rpc.', 'fusion.', 'app.', etc.\n\n // minLevels.set('rpc.RpcPeer', LogLevel.Debug);\n // minLevels.set('fusion.Computed', LogLevel.Debug);\n\n if (mustPersist)\n persist(minLevels);\n}\n","// Lightweight logging primitives shared by all ActualLab TypeScript packages.\n//\n// Design:\n// - Log.get(scope) returns a bag of optional loggers ({ debugLog, infoLog,\n// warnLog, errorLog }). Each is null when its level is below the scope's\n// minimum level, so the typical call site looks like:\n//\n// debugLog?.log('something happened', value);\n//\n// The optional chaining short-circuits before evaluating the arguments —\n// so the cost of disabled logs is just one nullish check.\n//\n// - Scopes are plain strings. Each package defines its own typed scope union\n// and uses createLogProvider<TScope>(prefix) to get a typed helper that keeps\n// scope names short at call sites while ensuring globally unique keys\n// ('rpc.RpcPeer', 'fusion.Computed', etc.).\n//\n// - Minimum levels live in Log.minLevels (a Map<string, LogLevel>). An\n// entry 'default' acts as a fallback before Log.defaultMinLevel.\n//\n// - initLogging() is invoked lazily on the first Log.get() call. It restores\n// persisted levels and installs globalThis.logLevels so devs can tweak\n// levels at runtime.\n\nimport { initLogging } from './logging-init.js';\n\nexport enum LogLevel {\n Debug = 1,\n Info,\n Warn,\n Error,\n None = 1000,\n}\n\nexport interface LogRef {\n target: unknown;\n id: number;\n}\n\ninterface LogRefSetItem {\n ref: LogRef;\n touchedAt: number;\n}\n\ninterface LogRefData {\n __logRefId?: number;\n}\n\nclass LogRefSet {\n private items: LogRefSetItem[] = [];\n private idSeed = 0;\n\n constructor(private capacity: number)\n { }\n\n public ref(data: object): LogRef {\n const itemIndex = this.items.findIndex(el => el.ref.target === data);\n if (itemIndex >= 0) {\n const existing = this.items[itemIndex];\n existing.touchedAt = Date.now();\n return existing.ref;\n }\n const id = (data as LogRefData).__logRefId ?? this.idSeed++;\n const newRef: LogRef = { target: data, id };\n (data as LogRefData).__logRefId = id;\n if (this.items.length >= this.capacity)\n this.removeOldest();\n this.items.push({ ref: newRef, touchedAt: Date.now() });\n return newRef;\n }\n\n private removeOldest(): void {\n let indexToEvict = 0;\n let itemToEvict = this.items[0];\n for (let i = 1; i < this.items.length; i++) {\n const item = this.items[i];\n if (item.touchedAt < itemToEvict.touchedAt) {\n itemToEvict = item;\n indexToEvict = i;\n }\n }\n this.items.splice(indexToEvict, 1);\n // Replace the live target with its string form so we don't keep the\n // object alive purely for log identity reasons.\n const ref = itemToEvict.ref;\n ref.target = ref.target?.toString();\n }\n}\n\nexport class Log {\n private static isInitialized = false;\n private static logRefs = new LogRefSet(10);\n /** User-set overrides (persisted by logging-init). Empty by default. */\n public static readonly minLevels = new Map<string, LogLevel>();\n /** Per-scope defaults registered by packages via createLogProvider(). */\n public static readonly scopeDefaults = new Map<string, LogLevel>();\n /** Every scope ever requested via Log.get(). Used by logLevels.dump()\n * so devs can discover what's available to override at runtime. */\n public static readonly knownScopes = new Set<string>();\n /** Global baseline for any scope without a default or override. */\n public static defaultMinLevel = LogLevel.Warn;\n public static loggerFactory: (scope: string, level: LogLevel) => Log = (scope, level) => new Log(scope, level);\n\n public log: (...data: unknown[]) => void;\n public trace: (...data: unknown[]) => void;\n\n constructor(\n public readonly scope: string,\n public readonly level: LogLevel,\n ) {\n const prefix = `[${scope}]`;\n switch (level) {\n case LogLevel.Debug:\n this.log = (...data: unknown[]) => console.debug(prefix, ...data);\n break;\n case LogLevel.Info:\n this.log = (...data: unknown[]) => console.log(prefix, ...data);\n break;\n case LogLevel.Warn:\n this.log = (...data: unknown[]) => console.warn(prefix, ...data);\n break;\n case LogLevel.Error:\n this.log = (...data: unknown[]) => console.error(prefix, ...data);\n break;\n case LogLevel.None:\n throw new Error('LogLevel.None cannot be used here');\n }\n this.trace = (...data: unknown[]) => console.trace(prefix, ...data);\n }\n\n public static get(scope: string): LogScopeFns {\n if (!this.isInitialized) {\n this.isInitialized = true;\n initLogging();\n }\n this.knownScopes.add(scope);\n\n const minLevels = this.minLevels;\n // Resolution order:\n // 1. User override for this scope (persisted by logging-init)\n // 2. User-set global override (minLevels.get('default'))\n // 3. Package default for this scope (registered via createLogProvider)\n // 4. Framework baseline (Log.defaultMinLevel, Warn)\n const minLevel = minLevels.get(scope)\n ?? minLevels.get('default')\n ?? this.scopeDefaults.get(scope)\n ?? this.defaultMinLevel;\n\n const getLogger = (level: LogLevel): Log | null =>\n level >= minLevel ? this.loggerFactory(scope, level) : null;\n\n return {\n logScope: scope,\n debugLog: getLogger(LogLevel.Debug),\n infoLog: getLogger(LogLevel.Info),\n warnLog: getLogger(LogLevel.Warn),\n errorLog: getLogger(LogLevel.Error),\n };\n }\n\n public static ref(data: object | null | undefined): object | null | undefined {\n if (!data)\n return data;\n return this.logRefs.ref(data);\n }\n\n public assert(predicate?: boolean, ...data: unknown[]): void {\n if (!predicate)\n this.log(...data);\n }\n}\n\nexport interface LogScopeFns {\n logScope: string;\n debugLog: Log | null;\n infoLog: Log | null;\n warnLog: Log | null;\n errorLog: Log | null;\n}\n\n// Per-package factory: creates a typed getLogs(scope) that prepends the package\n// prefix to the scope name before delegating to Log.get. Keeps call sites\n// concise while ensuring globally unique scope keys.\n//\n// `defaults` is required (not Partial) so that every scope in TScope has an\n// explicit default level — TypeScript will refuse to compile if a scope is\n// missing. Defaults register into Log.scopeDefaults and act as the fallback\n// when no user override is set.\n//\n// All declared scopes are also pre-registered in Log.knownScopes so that\n// logLevels.dump() (in dev console) can list them even before they're first\n// touched at runtime.\nexport function createLogProvider<TScope extends string>(\n prefix: string,\n defaults: Record<TScope, LogLevel>,\n): (scope: TScope) => LogScopeFns {\n for (const [scope, level] of Object.entries(defaults) as [TScope, LogLevel][]) {\n const fullName = prefix + scope;\n Log.scopeDefaults.set(fullName, level);\n Log.knownScopes.add(fullName);\n }\n return scope => Log.get(prefix + scope);\n}\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","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","/** 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","/** Error type rejected by {@link withTimeout} when its budget elapses. */\nexport class TimeoutError extends Error {\n override readonly name = 'TimeoutError';\n\n constructor(message = 'Operation timed out') {\n super(message);\n }\n}\n\n/**\n * Race `promise` against a `ms`-millisecond timer. Resolves with the inner\n * promise's value if it settles first; otherwise rejects with a\n * {@link TimeoutError} carrying `message`. The timer is always cleared in\n * a `finally`, so it cannot keep the event loop alive after the race ends.\n *\n * The inner promise's rejection (and the timeout's) are routed through\n * `Promise.race`, so callers should `await` the result inside a `try/catch`\n * exactly as they would for a single awaited promise. There's no\n * \"unhandled rejection\" hazard from the timeout branch — the race always\n * observes whichever promise wins, and the loser is allowed to settle\n * silently into the void.\n */\nexport async function withTimeout<T>(\n promise: PromiseLike<T>,\n ms: number,\n message?: string\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new TimeoutError(message ?? `Operation timed out after ${ms}ms`)),\n ms\n );\n });\n // Routed via `Promise.race` below; suppress the standalone unhandled-\n // rejection warning that fires when `promise` wins instead.\n timeoutPromise.catch(() => { /* noop */ });\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n","import { PromiseSource } from './promise-source.js';\nimport { TimeoutError } from './withTimeout.js';\n\n/**\n * A {@link PromiseSource} with a built-in timer that can reject (or run a\n * caller-supplied callback) after a configurable delay. The timer is\n * automatically cleared when the promise settles by other means, so callers\n * don't have to remember to `clearTimeout()` on every success path.\n *\n * Typical use:\n * ```ts\n * const ps = new PromiseSourceWithTimeout<string>();\n * ps.setTimeout(5_000); // rejects after 5s if still pending\n * ps.setTimeout(5_000, () => ps.resolve('fallback')); // or run a custom callback\n * ```\n *\n * Replaces the `PromiseSourceWithTimeout` previously kept in\n * `ActualChat/src/nodejs/src/promises.ts`. Note: the Voxt original supported a\n * \"precise\" (requestAnimationFrame-based) variant; we drop it here because no\n * caller in ActualChat uses it outside `promises.ts` itself.\n */\nexport class PromiseSourceWithTimeout<T> extends PromiseSource<T> {\n private _timer: ReturnType<typeof setTimeout> | undefined;\n\n hasTimeout(): boolean {\n return this._timer !== undefined;\n }\n\n /**\n * Install (or replace) a timeout. Pass `null` to remove without setting a\n * new one. `callback` is invoked when the timer fires — if omitted, the\n * promise is rejected with a generic \"timed out\" error.\n */\n setTimeout(ms: number | null, callback?: () => unknown): void {\n this.clearTimeout();\n if (ms === null || this.isCompleted) return;\n\n this._timer = setTimeout(() => {\n this._timer = undefined;\n if (callback) callback();\n else this.reject(new TimeoutError(`The promise has timed out after ${ms}ms.`));\n }, ms);\n }\n\n clearTimeout(): void {\n if (this._timer === undefined) return;\n clearTimeout(this._timer);\n this._timer = undefined;\n }\n\n override resolve(value: T): boolean {\n const didSettle = super.resolve(value);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n\n override reject(reason?: unknown): boolean {\n const didSettle = super.reject(reason);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n}\n","/**\n * Pre-resolved promises for the three values most often returned as a\n * \"no-op\" successful path: `void`, `true`, `false`. Returning these\n * avoids allocating a fresh promise per call site.\n *\n * Idiomatic use:\n * ```ts\n * if (alreadyInitialized) return ResolvedPromise.Void;\n * ```\n */\nexport const ResolvedPromise = {\n Void: Promise.resolve(),\n True: Promise.resolve(true),\n False: Promise.resolve(false),\n} as const;\n","/**\n * Sentinel returned/thrown by code that distinguishes \"the operation took\n * too long\" from a generic rejection. Identity-comparable via the\n * `instance` singleton — callers can branch on `result === TimedOut.instance`.\n */\nexport class TimedOut {\n static readonly instance: TimedOut = new TimedOut();\n}\n","/** Resolves after `ms` milliseconds. */\nexport function delayAsync(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\n/** Resolves with `value` after `ms` milliseconds. */\nexport function delayAsyncWith<T>(ms: number, value: T): Promise<T> {\n return new Promise<T>(resolve => {\n setTimeout(() => resolve(value), ms);\n });\n}\n","/**\n * Adapt an `AbortSignal` to a Promise that **rejects** with the signal's\n * `reason` once the signal fires (or immediately, if it's already\n * aborted). Mirrors `signal.throwIfAborted()` semantics in Promise form:\n * the rejected value is exactly what `throwIfAborted()` would have\n * thrown — by default a `DOMException` with `name === 'AbortError'`,\n * or whatever was passed to `abortController.abort(reason)`.\n *\n * Operators racing upstream pulls / timers against cancellation plug\n * this into `Promise.race(...)` so abort propagates as a thrown error —\n * `try/finally` blocks unwind naturally; no sentinel values to thread.\n *\n * Promises are cached per signal: every call for the same signal returns\n * the SAME promise and registers AT MOST ONE listener. Operators that\n * race per-iteration (e.g. encode loops calling this once per chunk)\n * won't accumulate listeners or hit Node's `MaxListenersExceeded` warning.\n * The cache is a `WeakMap` so signals remain GC-eligible normally.\n *\n * Callers that prefer a sentinel can attach `.catch()` to convert the\n * rejection back into a value: `abortPromise(s).catch(() => 'stopped')`.\n */\nconst abortPromiseCache = new WeakMap<AbortSignal, Promise<never>>();\n\nexport function abortPromise(signal: AbortSignal): Promise<never> {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- mirroring `signal.throwIfAborted()`: the rejection value IS the signal's reason, which by Web spec is a `DOMException` by default but can be any value the caller passed to `abort(reason)`.\n if (signal.aborted) return Promise.reject(signal.reason);\n let cached = abortPromiseCache.get(signal);\n if (!cached) {\n cached = new Promise<never>((_, reject) => {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- see comment above; signal.reason is the canonical thrown value.\n signal.addEventListener('abort', () => reject(signal.reason), { once: true });\n });\n // Mark the cached rejection as observed so unhandled-rejection\n // warnings don't fire when a caller never `await`s it (e.g. an\n // operator that completed before abort and let the race promise\n // GC). The actual await-time rejection still surfaces normally.\n cached.catch(() => { /* swallow for cache-only consumers */ });\n abortPromiseCache.set(signal, cached);\n }\n return cached;\n}\n","import { LogLevel, createLogProvider } from './logging.js';\n\n/** Log scopes used inside `@actuallab/core` itself. Each is registered at\n * `core.<scope>`. Keep the list tight — most utilities should propagate\n * errors rather than log them. */\nexport type CoreLogScope =\n | 'retry'\n | 'throttle';\n\nconst scopeDefaults: Record<CoreLogScope, LogLevel> = {\n retry: LogLevel.Warn,\n throttle: LogLevel.Warn,\n};\n\nexport const getLogs = createLogProvider<CoreLogScope>('core.', scopeDefaults);\n","import { getLogs } from './internal-logging.js';\n\nconst { errorLog } = getLogs('throttle');\n\n/** A function wrapped by {@link throttle} or {@link debounce}. Calling it\n * triggers the underlying function according to the scheduling rule;\n * `reset()` discards any pending scheduled call. */\nexport interface ResettableFunc<TArgs extends unknown[]> {\n (...args: TArgs): void;\n reset(): void;\n}\n\nclass Call<TArgs extends unknown[]> {\n constructor(\n readonly func: (...args: TArgs) => unknown,\n readonly self: unknown,\n readonly parameters: TArgs\n ) { }\n\n invoke(): unknown {\n return this.func.apply(this.self, this.parameters);\n }\n\n invokeSilently(): unknown {\n try {\n return this.invoke();\n } catch (error) {\n errorLog?.log('Call.invokeSilently: unhandled error:', error);\n }\n }\n}\n\n/** Throttle modes:\n * - `default` — fire the head call immediately, then drop further calls\n * until the interval elapses; the *last* one is fired at interval end.\n * - `skip` — fire the head call immediately, drop ALL calls during the\n * interval (no tail call).\n * - `delayHead` — delay even the head call by one interval; subsequent\n * calls overwrite the pending one. */\nexport type ThrottleMode = 'default' | 'skip' | 'delayHead';\n\n/**\n * Throttle calls to `func` so that it fires at most once every `intervalMs`.\n * The returned function has a `.reset()` that discards any pending tail call\n * and re-arms the head-call behavior on the next invocation.\n */\nexport function throttle<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number,\n mode: ThrottleMode = 'default'\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n call.invokeSilently(); // Must be last\n } else {\n timeoutHandle = null;\n nextFireTime = 0;\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n const call = new Call<TArgs>(func, this, args);\n const fireDelay = nextFireTime - Date.now();\n if (timeoutHandle !== null && fireDelay <= 0) {\n // Delayed \"fire\" is ready but not yet executed — flush it now.\n fire();\n }\n\n if (timeoutHandle === null) {\n // lastCall is null here\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n if (mode === 'delayHead') {\n lastCall = call;\n } else {\n call.invokeSilently();\n }\n } else if (mode !== 'skip') {\n lastCall = call;\n }\n };\n wrapped.reset = reset;\n return wrapped;\n}\n\n/**\n * Debounce calls to `func`: the function fires only after `intervalMs` have\n * elapsed since the LAST call. Each new call resets the timer. `.reset()`\n * discards any pending fire without invoking `func`.\n */\nexport function debounce<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n // Don't clearTimeout here: the live timer will see `lastCall === null`\n // and exit quietly. Avoids a churn of cleared-then-set timers when\n // callers `reset()` then immediately call again.\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n\n const fireDelay = nextFireTime - Date.now();\n if (fireDelay <= 0) {\n nextFireTime = 0;\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n call.invokeSilently(); // Must be last\n }\n } else {\n // Another call landed; reschedule for the new deadline.\n timeoutHandle = setTimeout(fire, fireDelay);\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n lastCall = new Call<TArgs>(func, this, args);\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle ??= setTimeout(fire, intervalMs);\n };\n wrapped.reset = reset;\n return wrapped;\n}\n","/**\n * Wrap an async function so concurrent invocations are serialized into a\n * single chain — each call awaits the previous one before running, and the\n * caller receives the result of *its* own invocation.\n *\n * Useful for stateful async operations (DB writes, file I/O, network I/O\n * that must not overlap) where the underlying contract is \"one at a time.\"\n *\n * If `limit` is set and the queue is already that deep, the call short-\n * circuits and returns the same promise the most recent queued call returned\n * — i.e. it coalesces excess pressure onto the trailing in-flight call.\n * Pass `null` (the default) for unbounded queueing.\n */\nexport function serialize<TArgs extends unknown[], TResult>(\n func: (...args: TArgs) => PromiseLike<TResult> | TResult,\n limit: number | null = null\n): (...args: TArgs) => Promise<TResult> {\n let lastCall: Promise<TResult> = Promise.resolve(null as TResult);\n let queueSize = 0;\n\n return function (this: unknown, ...args: TArgs): Promise<TResult> {\n if (limit !== null && queueSize >= limit) return lastCall;\n\n queueSize++;\n const prevCall = lastCall;\n // Capture `this` via the bound caller chain so we don't have to alias\n // `this` to a local (which the linter flags).\n const invoke = (): PromiseLike<TResult> | TResult => func.apply(this, args);\n return lastCall = (async () => {\n try {\n // Wait for the previous call to settle — but don't inherit its\n // rejection. The previous caller already owns that error; if we\n // re-threw here, a single failure would poison the queue\n // forever (every subsequent call awaits the previous one).\n await prevCall.catch(() => { /* see comment above */ });\n return await invoke();\n } finally {\n queueSize--;\n }\n })();\n };\n}\n","/**\n * A fixed-capacity circular buffer supporting efficient push/pull at both\n * head and tail.\n *\n * Direct port of .NET `ActualLab.Collections.RingBuffer<T>` at\n * src/ActualLab.Core/Collections/RingBuffer.cs (simplified — TS uses plain\n * modulo instead of the power-of-two-minus-one bit-mask trick, since the\n * performance difference is negligible in JavaScript).\n */\nexport class RingBuffer<T> {\n private _buffer: (T | undefined)[];\n private _start = 0;\n private _end = 0;\n private _count = 0;\n\n readonly capacity: number;\n\n get count(): number { return this._count; }\n get isEmpty(): boolean { return this._count === 0; }\n get isFull(): boolean { return this._count === this.capacity; }\n get remainingCapacity(): number { return this.capacity - this._count; }\n get hasRemainingCapacity(): boolean { return this._count < this.capacity; }\n\n constructor(capacity: number) {\n if (capacity < 1)\n throw new RangeError(`RingBuffer capacity must be >= 1 (was ${capacity}).`);\n this.capacity = capacity;\n this._buffer = new Array<T | undefined>(capacity);\n }\n\n /** Read the item at `index` (0-indexed, from head). */\n get(index: number): T {\n if (index < 0 || index >= this._count)\n throw new RangeError(`Index ${index} out of range [0, ${this._count}).`);\n return this._buffer[(this._start + index) % this.capacity] as T;\n }\n\n /** Add an item at the tail. Throws if the buffer is full. */\n pushTail(item: T): void {\n if (this._count >= this.capacity)\n throw new Error('RingBuffer is full.');\n this._buffer[this._end] = item;\n this._end = (this._end + 1) % this.capacity;\n this._count++;\n }\n\n /** Add an item at the tail, evicting the head item if the buffer is full. */\n pushTailAndMoveHeadIfFull(item: T): void {\n if (this._count >= this.capacity) {\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n }\n this.pushTail(item);\n }\n\n /** Remove the head item. Throws if the buffer is empty. */\n pullHead(): T {\n if (this._count === 0)\n throw new Error('RingBuffer is empty.');\n const head = this._buffer[this._start] as T;\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n return head;\n }\n\n /**\n * Advance the head by `skipCount` slots, releasing references to skipped\n * items so they can be garbage-collected.\n */\n moveHead(skipCount: number): void {\n if (skipCount === 0) return;\n if (skipCount < 0 || skipCount > this._count)\n throw new RangeError(`skipCount ${skipCount} out of range [0, ${this._count}].`);\n for (let k = 0; k < skipCount; k++) {\n this._buffer[(this._start + k) % this.capacity] = undefined;\n }\n this._start = (this._start + skipCount) % this.capacity;\n this._count -= skipCount;\n }\n\n /** Remove all items. */\n clear(): void {\n for (let i = 0; i < this.capacity; i++) this._buffer[i] = undefined;\n this._start = 0;\n this._end = 0;\n this._count = 0;\n }\n\n /** Copy the buffer's contents to a new array, head-first. */\n toArray(): T[] {\n const out = new Array<T>(this._count);\n for (let i = 0; i < this._count; i++) {\n out[i] = this._buffer[(this._start + i) % this.capacity] as T;\n }\n return out;\n }\n}\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","import { delayAsync } from './delay.js';\nimport { getLogs } from './internal-logging.js';\n\nconst { warnLog } = getLogs('retry');\n\n/** A sequence of retry delays — given a 1-based try index (1 = first\n * retry, i.e. AFTER the initial failure), returns the delay in ms before\n * the next attempt. For more elaborate delay schemes, see\n * {@link RetryDelaySeq.getDelay}. */\nexport type RetryDelaySchedule = (tryIndex: number) => number;\n\nconst defaultRetryDelays: RetryDelaySchedule = () => 50;\n\n/**\n * Run `fn` up to `tryCount` times, awaiting a delay between attempts.\n * The last error is rethrown if every attempt fails.\n *\n * `fn` is passed the 0-based attempt index and the last error (or\n * `undefined` for the first attempt) — useful for adapting behavior per\n * try (e.g. switching endpoints, escalating timeouts).\n */\nexport async function retry<TResult>(\n tryCount: number,\n fn: (tryIndex: number, lastError: unknown) => PromiseLike<TResult> | TResult,\n retryDelays: RetryDelaySchedule = defaultRetryDelays,\n): Promise<TResult> {\n if (tryCount <= 0)\n throw new Error('retry: tryCount must be positive.');\n\n let lastError: unknown;\n for (let tryIndex = 0; ; ) {\n if (tryIndex >= tryCount) throw lastError;\n try {\n return await fn(tryIndex, lastError);\n } catch (e) {\n lastError = e;\n }\n ++tryIndex;\n if (tryIndex >= tryCount) throw lastError;\n warnLog?.log(`retry(${tryIndex}/${tryCount}): error:`, lastError);\n await delayAsync(retryDelays(tryIndex));\n }\n}\n\n/**\n * Run `fn` and swallow any throw, returning `onError(e)` if provided or\n * `undefined` otherwise. The returned promise always settles successfully\n * — the caller never has to `try/catch` it.\n *\n * Useful where a logical \"best-effort\" return is wanted but the runtime\n * defaults — unhandled rejection warnings, exception escape past finally\n * blocks — are not.\n */\nexport async function catchErrors<TResult>(\n fn: () => PromiseLike<TResult> | TResult,\n onError?: (e: unknown) => TResult,\n): Promise<TResult | undefined> {\n try {\n return await fn();\n } catch (e) {\n return onError ? onError(e) : undefined;\n }\n}\n"],"mappings":"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","names":["LogLevel","reset"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/polyfills.ts","../src/disposable.ts","../src/logging-init.ts","../src/logging.ts","../src/result.ts","../src/async-context.ts","../src/async-lock.ts","../src/promise-source.ts","../src/events.ts","../src/withTimeout.ts","../src/promise-source-with-timeout.ts","../src/resolved-promise.ts","../src/timed-out.ts","../src/delay.ts","../src/abort-promise.ts","../src/internal-logging.ts","../src/throttle.ts","../src/serialize.ts","../src/ring-buffer.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts","../src/retry.ts"],"sourcesContent":["import './polyfills.js';\n\n// Disposable\nexport type { Disposable, AsyncDisposable } from './disposable.js';\nexport { DisposableBag } from './disposable.js';\n\n// Logging\nexport type { LogRef, LogScopeFns } from './logging.js';\nexport { Log, LogLevel, createLogProvider } from './logging.js';\nexport { initLogging, initWorkerLogging, LogLevelController } from './logging-init.js';\n\n// Result & IResult\nexport type { IResult } from './result.js';\nexport {\n Result,\n result,\n errorResult,\n resultFrom,\n resultFromAsync,\n} from './result.js';\n\n// Async-related\nexport {\n AsyncContext,\n AsyncContextKey,\n abortSignalKey,\n} from './async-context.js';\nexport { AsyncLock } from './async-lock.js';\n\n// Event handling, primises\nexport { EventHandlerSet } from './events.js';\nexport { PromiseSource, resolvedVoidPromise } from './promise-source.js';\nexport { PromiseSourceWithTimeout } from './promise-source-with-timeout.js';\nexport { ResolvedPromise } from './resolved-promise.js';\nexport { TimedOut } from './timed-out.js';\nexport { TimeoutError, withTimeout } from './withTimeout.js';\nexport { delayAsync, delayAsyncWith } from './delay.js';\nexport { abortPromise } from './abort-promise.js';\n\n// Higher-order async operators\nexport type { ResettableFunc, ThrottleMode } from './throttle.js';\nexport { throttle, debounce } from './throttle.js';\nexport { serialize } from './serialize.js';\n\n// Collections\nexport { RingBuffer } from './ring-buffer.js';\n\n// Resilience\nexport { RetryDelaySeq } from './retry-delay-seq.js';\nexport type { RetryDelay } from './retry-delayer.js';\nexport {\n RetryDelayer,\n RetryDelayNone,\n RetryDelayLimitExceeded,\n} from './retry-delayer.js';\nexport type { RetryDelaySchedule } from './retry.js';\nexport { retry, catchErrors } from './retry.js';\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","/** 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","// Initialization helpers for the logging system.\n//\n// The Log class uses a single Map<string, LogLevel> to determine the minimum\n// level for each scope. This module is responsible for:\n// - Persisting the map across page reloads via localStorage on the main\n// thread, and via IndexedDB for workers.\n// - Exposing a globally accessible LogLevelController so developers can tweak\n// levels at runtime from the browser dev console (globalThis.logLevels).\n//\n// initLogging() is idempotent and called automatically on the first Log.get().\n//\n// Runtime override examples (paste into browser dev console):\n// logLevels.override('rpc.RpcPeer', 1) // exact: one scope to Debug\n// logLevels.override('rpc.*', 1) // prefix: all rpc.* scopes\n// logLevels.override('*Video*', 1) // contains: every scope with 'Video'\n// logLevels.override('*Decoder', 1) // suffix: every scope ending in 'Decoder'\n// logLevels.reset() // reset to package defaults\n// logLevels.clear() // clear all overrides\n\nimport { Log, LogLevel } from './logging.js';\n\nconst GlobalThisKey = 'logLevels';\nconst StorageKey = 'logLevels';\nconst DateStorageKey = `${StorageKey}.date`;\nconst MaxStorageAge = 86_400_000 * 3; // 3 days\nconst IndexedDbName = 'actuallab-logging';\nconst IndexedDbStore = 'settings';\nconst IndexedDbKey = 'logLevels';\n\nconst localStorage: Storage | null = tryGetLocalStorage();\n\n// Workers, worklets, and service workers run in separate JS realms with\n// their own globalThis. Within one realm, esbuild can also produce multiple\n// chunks that each carry their own copy of @actuallab/core (so multiple\n// distinct `Log` classes exist). We want the install + restore + console\n// message to happen exactly once per realm — gate via globalThis.logLevels.\nconst isMainThread = typeof window !== 'undefined';\n\nexport function initLogging(): void {\n // Warn is the global baseline — packages set per-scope defaults\n // (typically Info or Warn) via createLogProvider.\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n // Another chunk in this realm already initialized. Mirror its\n // overrides into our local Log.minLevels so this Log class observes\n // the same effective levels. (Each chunk has its own Log class with\n // its own static minLevels Map — they only converge through this\n // one-shot copy at init time.)\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = restore(minLevels);\n if (wasRestored) {\n if (isMainThread)\n console.log('Logging: logLevels are restored');\n }\n else {\n if (isMainThread)\n console.log('Logging: logLevels are reset');\n reset(minLevels);\n }\n}\n\n/** Worker bootstrap path: await this before dynamically importing any module\n * that may call getLogs() at top level. */\nexport async function initWorkerLogging(): Promise<void> {\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = await restoreFromIndexedDb(minLevels);\n if (!wasRestored)\n reset(minLevels, false);\n}\n\nexport class LogLevelController {\n constructor(private minLevels: Map<string, LogLevel>)\n { }\n\n /** Internal: used by initLogging() in secondary bundles to share the\n * primary bundle's minLevels map. */\n public getMinLevels(): Map<string, LogLevel> {\n return this.minLevels;\n }\n\n /** List the current set of overrides. */\n public list(): Record<string, LogLevel> {\n return Object.fromEntries(this.minLevels);\n }\n\n /** Print every known scope's effective level to the console as a table.\n * Shows: scope, effective level, the source ('override' / 'default-key' /\n * 'package-default' / 'baseline'), and the package default for reference.\n * Use this from the dev console to discover what to pass to override(). */\n public dump(): void {\n const baseline = Log.defaultMinLevel;\n const globalOverride = this.minLevels.get('default');\n const allScopes = new Set<string>([\n ...Log.knownScopes,\n ...Log.scopeDefaults.keys(),\n ...this.minLevels.keys(),\n ]);\n // Drop the special 'default' bucket — surfaced separately below.\n allScopes.delete('default');\n const rows: Record<string, {\n level: string;\n source: string;\n packageDefault: string;\n }> = {};\n const sorted = [...allScopes].sort();\n for (const scope of sorted) {\n const override = this.minLevels.get(scope);\n const pkgDefault = Log.scopeDefaults.get(scope);\n let level: LogLevel;\n let source: string;\n if (override !== undefined) {\n level = override;\n source = 'override';\n }\n else if (globalOverride !== undefined) {\n level = globalOverride;\n source = \"minLevels.get('default')\";\n }\n else if (pkgDefault !== undefined) {\n level = pkgDefault;\n source = 'package-default';\n }\n else {\n level = baseline;\n source = 'baseline';\n }\n rows[scope] = {\n level: LogLevel[level],\n source,\n packageDefault: pkgDefault === undefined ? '-' : LogLevel[pkgDefault],\n };\n }\n console.table(rows);\n console.log(\n `Baseline: ${LogLevel[baseline]}` +\n (globalOverride === undefined ? '' : `, default override: ${LogLevel[globalOverride]}`),\n );\n }\n\n /** Override the level for every scope matching a glob-like pattern.\n * `*` matches any sequence of characters; everything else is literal.\n * Examples:\n * override('rpc.RpcPeer', 1) // exact — one scope to Debug\n * override('rpc.*', 1) // prefix — every scope starting with 'rpc.'\n * override('*rpc*', 1) // contains — every scope with 'rpc' in it\n * override('*Peer', 1) // suffix — every scope ending with 'Peer'\n * Matches scopes that are user-overridden, package-registered (defaults),\n * or have ever been requested via Log.get(). If the pattern has no `*`\n * and nothing known matches, the literal scope is set anyway — so an\n * exact-name override placed before its scope is loaded still applies.\n * Persisted to localStorage + IndexedDB. */\n public override(pattern: string, newLevel: LogLevel): void {\n const matched = new Set<string>();\n if (pattern.includes('*')) {\n const re = patternToRegExp(pattern);\n for (const [scope] of this.minLevels)\n if (re.test(scope)) matched.add(scope);\n for (const [scope] of Log.scopeDefaults)\n if (re.test(scope)) matched.add(scope);\n for (const scope of Log.knownScopes)\n if (re.test(scope)) matched.add(scope);\n }\n else {\n matched.add(pattern);\n }\n for (const scope of matched)\n this.minLevels.set(scope, newLevel);\n persist(this.minLevels);\n }\n\n /** Reset all overrides; package defaults take effect again. Persisted. */\n public reset(): void {\n reset(this.minLevels);\n }\n\n /** Clear all overrides (no global default unless `defaultLevel` is given). */\n public clear(defaultLevel?: LogLevel): void {\n this.minLevels.clear();\n if (defaultLevel !== undefined)\n this.minLevels.set('default', defaultLevel);\n persist(this.minLevels);\n }\n}\n\nfunction patternToRegExp(pattern: string): RegExp {\n // Escape regex metacharacters except `*`, then turn each `*` into `.*`.\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*');\n return new RegExp(`^${escaped}$`);\n}\n\ninterface PersistedLogLevels {\n date: number;\n entries: [string, LogLevel][];\n}\n\nfunction restore(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = readFromStorage(localStorage);\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nasync function restoreFromIndexedDb(minLevels: Map<string, LogLevel>): Promise<boolean> {\n const snapshot = await readFromIndexedDb();\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nfunction readFromStorage(storage: Storage | null): PersistedLogLevels | null {\n if (!storage)\n return null;\n\n try {\n const dateJson = storage.getItem(DateStorageKey);\n const entriesJson = storage.getItem(StorageKey);\n if (!dateJson || !entriesJson)\n return null;\n\n return {\n date: JSON.parse(dateJson) as number,\n entries: JSON.parse(entriesJson) as [string, LogLevel][],\n };\n } catch {\n return null;\n }\n}\n\nfunction applySnapshot(minLevels: Map<string, LogLevel>, snapshot: PersistedLogLevels): boolean {\n if (typeof snapshot.date !== 'number')\n return false;\n if (Date.now() - snapshot.date > MaxStorageAge)\n return false;\n if (!Array.isArray(snapshot.entries))\n return false;\n\n minLevels.clear();\n for (const entry of snapshot.entries) {\n // Runtime guard for JSON-parsed input — types claim it's a tuple, but\n // localStorage may carry corrupted data. eslint flags the length check\n // as always-false against the static type; that's the point.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!Array.isArray(entry) || entry.length !== 2)\n return false;\n const [key, value] = entry;\n if (typeof key !== 'string' || typeof value !== 'number')\n return false;\n minLevels.set(key, value);\n }\n\n return true;\n}\n\nfunction persist(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = createSnapshot(minLevels);\n let wasPersisted = false;\n\n if (localStorage) {\n try {\n localStorage.setItem(DateStorageKey, JSON.stringify(snapshot.date));\n localStorage.setItem(StorageKey, JSON.stringify(snapshot.entries));\n wasPersisted = true;\n } catch {\n // Storage may be unavailable in private / sandboxed contexts.\n }\n }\n\n void writeToIndexedDb(snapshot);\n return wasPersisted;\n}\n\nfunction createSnapshot(minLevels: Map<string, LogLevel>): PersistedLogLevels {\n return {\n date: Date.now(),\n entries: Array.from(minLevels.entries()),\n };\n}\n\nfunction tryGetLocalStorage(): Storage | null {\n if (typeof globalThis === 'undefined' || !('localStorage' in globalThis))\n return null;\n\n try {\n return (globalThis as unknown as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n}\n\nasync function openLoggingDb(): Promise<IDBDatabase | null> {\n if (typeof indexedDB === 'undefined')\n return null;\n\n return new Promise(resolve => {\n const request = indexedDB.open(IndexedDbName, 1);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(IndexedDbStore))\n db.createObjectStore(IndexedDbStore);\n };\n request.onerror = () => resolve(null);\n request.onblocked = () => resolve(null);\n request.onsuccess = () => resolve(request.result);\n });\n}\n\nasync function readFromIndexedDb(): Promise<PersistedLogLevels | null> {\n const db = await openLoggingDb();\n if (!db)\n return null;\n\n return new Promise(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readonly');\n const request = tx.objectStore(IndexedDbStore).get(IndexedDbKey);\n request.onerror = () => resolve(null);\n request.onsuccess = () => resolve(request.result as PersistedLogLevels | null);\n tx.oncomplete = () => db.close();\n tx.onerror = () => db.close();\n tx.onabort = () => db.close();\n });\n}\n\nasync function writeToIndexedDb(snapshot: PersistedLogLevels): Promise<void> {\n const db = await openLoggingDb();\n if (!db)\n return;\n\n await new Promise<void>(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readwrite');\n tx.objectStore(IndexedDbStore).put(snapshot, IndexedDbKey);\n tx.oncomplete = () => {\n db.close();\n resolve();\n };\n tx.onerror = () => {\n db.close();\n resolve();\n };\n tx.onabort = () => {\n db.close();\n resolve();\n };\n });\n}\n\nfunction reset(minLevels: Map<string, LogLevel>, mustPersist = true): void {\n minLevels.clear();\n // Add per-scope defaults here for development.\n // Use prefix conventions: 'rpc.', 'fusion.', 'app.', etc.\n\n // minLevels.set('rpc.RpcPeer', LogLevel.Debug);\n // minLevels.set('fusion.Computed', LogLevel.Debug);\n\n if (mustPersist)\n persist(minLevels);\n}\n","// Lightweight logging primitives shared by all ActualLab TypeScript packages.\n//\n// Design:\n// - Log.get(scope) returns a bag of optional loggers ({ debugLog, infoLog,\n// warnLog, errorLog }). Each is null when its level is below the scope's\n// minimum level, so the typical call site looks like:\n//\n// debugLog?.log('something happened', value);\n//\n// The optional chaining short-circuits before evaluating the arguments —\n// so the cost of disabled logs is just one nullish check.\n//\n// - Scopes are plain strings. Each package defines its own typed scope union\n// and uses createLogProvider<TScope>(prefix) to get a typed helper that keeps\n// scope names short at call sites while ensuring globally unique keys\n// ('rpc.RpcPeer', 'fusion.Computed', etc.).\n//\n// - Minimum levels live in Log.minLevels (a Map<string, LogLevel>). An\n// entry 'default' acts as a fallback before Log.defaultMinLevel.\n//\n// - initLogging() is invoked lazily on the first Log.get() call. It restores\n// persisted levels and installs globalThis.logLevels so devs can tweak\n// levels at runtime.\n\nimport { initLogging } from './logging-init.js';\n\nexport enum LogLevel {\n Debug = 1,\n Info,\n Warn,\n Error,\n None = 1000,\n}\n\nexport interface LogRef {\n target: unknown;\n id: number;\n}\n\ninterface LogRefSetItem {\n ref: LogRef;\n touchedAt: number;\n}\n\ninterface LogRefData {\n __logRefId?: number;\n}\n\nclass LogRefSet {\n private items: LogRefSetItem[] = [];\n private idSeed = 0;\n\n constructor(private capacity: number)\n { }\n\n public ref(data: object): LogRef {\n const itemIndex = this.items.findIndex(el => el.ref.target === data);\n if (itemIndex >= 0) {\n const existing = this.items[itemIndex];\n existing.touchedAt = Date.now();\n return existing.ref;\n }\n const id = (data as LogRefData).__logRefId ?? this.idSeed++;\n const newRef: LogRef = { target: data, id };\n (data as LogRefData).__logRefId = id;\n if (this.items.length >= this.capacity)\n this.removeOldest();\n this.items.push({ ref: newRef, touchedAt: Date.now() });\n return newRef;\n }\n\n private removeOldest(): void {\n let indexToEvict = 0;\n let itemToEvict = this.items[0];\n for (let i = 1; i < this.items.length; i++) {\n const item = this.items[i];\n if (item.touchedAt < itemToEvict.touchedAt) {\n itemToEvict = item;\n indexToEvict = i;\n }\n }\n this.items.splice(indexToEvict, 1);\n // Replace the live target with its string form so we don't keep the\n // object alive purely for log identity reasons.\n const ref = itemToEvict.ref;\n ref.target = ref.target?.toString();\n }\n}\n\nexport class Log {\n private static isInitialized = false;\n private static logRefs = new LogRefSet(10);\n /** User-set overrides (persisted by logging-init). Empty by default. */\n public static readonly minLevels = new Map<string, LogLevel>();\n /** Per-scope defaults registered by packages via createLogProvider(). */\n public static readonly scopeDefaults = new Map<string, LogLevel>();\n /** Every scope ever requested via Log.get(). Used by logLevels.dump()\n * so devs can discover what's available to override at runtime. */\n public static readonly knownScopes = new Set<string>();\n /** Global baseline for any scope without a default or override. */\n public static defaultMinLevel = LogLevel.Warn;\n public static loggerFactory: (scope: string, level: LogLevel) => Log = (scope, level) => new Log(scope, level);\n\n public log: (...data: unknown[]) => void;\n public trace: (...data: unknown[]) => void;\n\n constructor(\n public readonly scope: string,\n public readonly level: LogLevel,\n ) {\n const prefix = `[${scope}]`;\n switch (level) {\n case LogLevel.Debug:\n this.log = (...data: unknown[]) => console.debug(prefix, ...data);\n break;\n case LogLevel.Info:\n this.log = (...data: unknown[]) => console.log(prefix, ...data);\n break;\n case LogLevel.Warn:\n this.log = (...data: unknown[]) => console.warn(prefix, ...data);\n break;\n case LogLevel.Error:\n this.log = (...data: unknown[]) => console.error(prefix, ...data);\n break;\n case LogLevel.None:\n throw new Error('LogLevel.None cannot be used here');\n }\n this.trace = (...data: unknown[]) => console.trace(prefix, ...data);\n }\n\n public static get(scope: string): LogScopeFns {\n if (!this.isInitialized) {\n this.isInitialized = true;\n initLogging();\n }\n this.knownScopes.add(scope);\n\n const minLevels = this.minLevels;\n // Resolution order:\n // 1. User override for this scope (persisted by logging-init)\n // 2. User-set global override (minLevels.get('default'))\n // 3. Package default for this scope (registered via createLogProvider)\n // 4. Framework baseline (Log.defaultMinLevel, Warn)\n const minLevel = minLevels.get(scope)\n ?? minLevels.get('default')\n ?? this.scopeDefaults.get(scope)\n ?? this.defaultMinLevel;\n\n const getLogger = (level: LogLevel): Log | null =>\n level >= minLevel ? this.loggerFactory(scope, level) : null;\n\n return {\n logScope: scope,\n debugLog: getLogger(LogLevel.Debug),\n infoLog: getLogger(LogLevel.Info),\n warnLog: getLogger(LogLevel.Warn),\n errorLog: getLogger(LogLevel.Error),\n };\n }\n\n public static ref(data: object | null | undefined): object | null | undefined {\n if (!data)\n return data;\n return this.logRefs.ref(data);\n }\n\n public assert(predicate?: boolean, ...data: unknown[]): void {\n if (!predicate)\n this.log(...data);\n }\n}\n\nexport interface LogScopeFns {\n logScope: string;\n debugLog: Log | null;\n infoLog: Log | null;\n warnLog: Log | null;\n errorLog: Log | null;\n}\n\n// Per-package factory: creates a typed getLogs(scope) that prepends the package\n// prefix to the scope name before delegating to Log.get. Keeps call sites\n// concise while ensuring globally unique scope keys.\n//\n// `defaults` is required (not Partial) so that every scope in TScope has an\n// explicit default level — TypeScript will refuse to compile if a scope is\n// missing. Defaults register into Log.scopeDefaults and act as the fallback\n// when no user override is set.\n//\n// All declared scopes are also pre-registered in Log.knownScopes so that\n// logLevels.dump() (in dev console) can list them even before they're first\n// touched at runtime.\nexport function createLogProvider<TScope extends string>(\n prefix: string,\n defaults: Record<TScope, LogLevel>,\n): (scope: TScope) => LogScopeFns {\n for (const [scope, level] of Object.entries(defaults) as [TScope, LogLevel][]) {\n const fullName = prefix + scope;\n Log.scopeDefaults.set(fullName, level);\n Log.knownScopes.add(fullName);\n }\n return scope => Log.get(prefix + scope);\n}\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","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","/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */\r\nexport class PromiseSource<T> implements Promise<T> {\r\n readonly promise: Promise<T>;\r\n readonly [Symbol.toStringTag] = 'Promise';\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 then<TResult1 = T, TResult2 = never>(\r\n onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\r\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.promise.then(onfulfilled, onrejected);\r\n }\r\n\r\n catch<TResult = never>(\r\n onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,\r\n ): Promise<T | TResult> {\r\n return this.promise.catch(onrejected);\r\n }\r\n\r\n finally(onfinally?: (() => void) | null): Promise<T> {\r\n return this.promise.finally(onfinally);\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;\r\n }\r\n}\r\n","/** Error type rejected by {@link withTimeout} when its budget elapses. */\nexport class TimeoutError extends Error {\n override readonly name = 'TimeoutError';\n\n constructor(message = 'Operation timed out') {\n super(message);\n }\n}\n\n/**\n * Race `promise` against a `ms`-millisecond timer. Resolves with the inner\n * promise's value if it settles first; otherwise rejects with a\n * {@link TimeoutError} carrying `message`. The timer is always cleared in\n * a `finally`, so it cannot keep the event loop alive after the race ends.\n *\n * The inner promise's rejection (and the timeout's) are routed through\n * `Promise.race`, so callers should `await` the result inside a `try/catch`\n * exactly as they would for a single awaited promise. There's no\n * \"unhandled rejection\" hazard from the timeout branch — the race always\n * observes whichever promise wins, and the loser is allowed to settle\n * silently into the void.\n */\nexport async function withTimeout<T>(\n promise: PromiseLike<T>,\n ms: number,\n message?: string\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new TimeoutError(message ?? `Operation timed out after ${ms}ms`)),\n ms\n );\n });\n // Routed via `Promise.race` below; suppress the standalone unhandled-\n // rejection warning that fires when `promise` wins instead.\n timeoutPromise.catch(() => { /* noop */ });\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n","import { PromiseSource } from './promise-source.js';\nimport { TimeoutError } from './withTimeout.js';\n\n/**\n * A {@link PromiseSource} with a built-in timer that can reject (or run a\n * caller-supplied callback) after a configurable delay. The timer is\n * automatically cleared when the promise settles by other means, so callers\n * don't have to remember to `clearTimeout()` on every success path.\n *\n * Typical use:\n * ```ts\n * const ps = new PromiseSourceWithTimeout<string>();\n * ps.setTimeout(5_000); // rejects after 5s if still pending\n * ps.setTimeout(5_000, () => ps.resolve('fallback')); // or run a custom callback\n * ```\n *\n * Replaces the `PromiseSourceWithTimeout` previously kept in\n * `ActualChat/src/nodejs/src/promises.ts`. Note: the Voxt original supported a\n * \"precise\" (requestAnimationFrame-based) variant; we drop it here because no\n * caller in ActualChat uses it outside `promises.ts` itself.\n */\nexport class PromiseSourceWithTimeout<T> extends PromiseSource<T> {\n private _timer: ReturnType<typeof setTimeout> | undefined;\n\n hasTimeout(): boolean {\n return this._timer !== undefined;\n }\n\n /**\n * Install (or replace) a timeout. Pass `null` to remove without setting a\n * new one. `callback` is invoked when the timer fires — if omitted, the\n * promise is rejected with a generic \"timed out\" error.\n */\n setTimeout(ms: number | null, callback?: () => unknown): void {\n this.clearTimeout();\n if (ms === null || this.isCompleted) return;\n\n this._timer = setTimeout(() => {\n this._timer = undefined;\n if (callback) callback();\n else this.reject(new TimeoutError(`The promise has timed out after ${ms}ms.`));\n }, ms);\n }\n\n clearTimeout(): void {\n if (this._timer === undefined) return;\n clearTimeout(this._timer);\n this._timer = undefined;\n }\n\n override resolve(value: T): boolean {\n const didSettle = super.resolve(value);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n\n override reject(reason?: unknown): boolean {\n const didSettle = super.reject(reason);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n}\n","/**\n * Pre-resolved promises for the three values most often returned as a\n * \"no-op\" successful path: `void`, `true`, `false`. Returning these\n * avoids allocating a fresh promise per call site.\n *\n * Idiomatic use:\n * ```ts\n * if (alreadyInitialized) return ResolvedPromise.Void;\n * ```\n */\nexport const ResolvedPromise = {\n Void: Promise.resolve(),\n True: Promise.resolve(true),\n False: Promise.resolve(false),\n} as const;\n","/**\n * Sentinel returned/thrown by code that distinguishes \"the operation took\n * too long\" from a generic rejection. Identity-comparable via the\n * `instance` singleton — callers can branch on `result === TimedOut.instance`.\n */\nexport class TimedOut {\n static readonly instance: TimedOut = new TimedOut();\n}\n","/** Resolves after `ms` milliseconds. */\nexport function delayAsync(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\n/** Resolves with `value` after `ms` milliseconds. */\nexport function delayAsyncWith<T>(ms: number, value: T): Promise<T> {\n return new Promise<T>(resolve => {\n setTimeout(() => resolve(value), ms);\n });\n}\n","/**\n * Adapt an `AbortSignal` to a Promise that **rejects** with the signal's\n * `reason` once the signal fires (or immediately, if it's already\n * aborted). Mirrors `signal.throwIfAborted()` semantics in Promise form:\n * the rejected value is exactly what `throwIfAborted()` would have\n * thrown — by default a `DOMException` with `name === 'AbortError'`,\n * or whatever was passed to `abortController.abort(reason)`.\n *\n * Operators racing upstream pulls / timers against cancellation plug\n * this into `Promise.race(...)` so abort propagates as a thrown error —\n * `try/finally` blocks unwind naturally; no sentinel values to thread.\n *\n * Promises are cached per signal: every call for the same signal returns\n * the SAME promise and registers AT MOST ONE listener. Operators that\n * race per-iteration (e.g. encode loops calling this once per chunk)\n * won't accumulate listeners or hit Node's `MaxListenersExceeded` warning.\n * The cache is a `WeakMap` so signals remain GC-eligible normally.\n *\n * Callers that prefer a sentinel can attach `.catch()` to convert the\n * rejection back into a value: `abortPromise(s).catch(() => 'stopped')`.\n */\nconst abortPromiseCache = new WeakMap<AbortSignal, Promise<never>>();\n\nexport function abortPromise(signal: AbortSignal): Promise<never> {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- mirroring `signal.throwIfAborted()`: the rejection value IS the signal's reason, which by Web spec is a `DOMException` by default but can be any value the caller passed to `abort(reason)`.\n if (signal.aborted) return Promise.reject(signal.reason);\n let cached = abortPromiseCache.get(signal);\n if (!cached) {\n cached = new Promise<never>((_, reject) => {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- see comment above; signal.reason is the canonical thrown value.\n signal.addEventListener('abort', () => reject(signal.reason), { once: true });\n });\n // Mark the cached rejection as observed so unhandled-rejection\n // warnings don't fire when a caller never `await`s it (e.g. an\n // operator that completed before abort and let the race promise\n // GC). The actual await-time rejection still surfaces normally.\n cached.catch(() => { /* swallow for cache-only consumers */ });\n abortPromiseCache.set(signal, cached);\n }\n return cached;\n}\n","import { LogLevel, createLogProvider } from './logging.js';\n\n/** Log scopes used inside `@actuallab/core` itself. Each is registered at\n * `core.<scope>`. Keep the list tight — most utilities should propagate\n * errors rather than log them. */\nexport type CoreLogScope =\n | 'retry'\n | 'throttle';\n\nconst scopeDefaults: Record<CoreLogScope, LogLevel> = {\n retry: LogLevel.Warn,\n throttle: LogLevel.Warn,\n};\n\nexport const getLogs = createLogProvider<CoreLogScope>('core.', scopeDefaults);\n","import { getLogs } from './internal-logging.js';\n\nconst { errorLog } = getLogs('throttle');\n\n/** A function wrapped by {@link throttle} or {@link debounce}. Calling it\n * triggers the underlying function according to the scheduling rule;\n * `reset()` discards any pending scheduled call. */\nexport interface ResettableFunc<TArgs extends unknown[]> {\n (...args: TArgs): void;\n reset(): void;\n}\n\nclass Call<TArgs extends unknown[]> {\n constructor(\n readonly func: (...args: TArgs) => unknown,\n readonly self: unknown,\n readonly parameters: TArgs\n ) { }\n\n invoke(): unknown {\n return this.func.apply(this.self, this.parameters);\n }\n\n invokeSilently(): unknown {\n try {\n return this.invoke();\n } catch (error) {\n errorLog?.log('Call.invokeSilently: unhandled error:', error);\n }\n }\n}\n\n/** Throttle modes:\n * - `default` — fire the head call immediately, then drop further calls\n * until the interval elapses; the *last* one is fired at interval end.\n * - `skip` — fire the head call immediately, drop ALL calls during the\n * interval (no tail call).\n * - `delayHead` — delay even the head call by one interval; subsequent\n * calls overwrite the pending one. */\nexport type ThrottleMode = 'default' | 'skip' | 'delayHead';\n\n/**\n * Throttle calls to `func` so that it fires at most once every `intervalMs`.\n * The returned function has a `.reset()` that discards any pending tail call\n * and re-arms the head-call behavior on the next invocation.\n */\nexport function throttle<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number,\n mode: ThrottleMode = 'default'\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n call.invokeSilently(); // Must be last\n } else {\n timeoutHandle = null;\n nextFireTime = 0;\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n const call = new Call<TArgs>(func, this, args);\n const fireDelay = nextFireTime - Date.now();\n if (timeoutHandle !== null && fireDelay <= 0) {\n // Delayed \"fire\" is ready but not yet executed — flush it now.\n fire();\n }\n\n if (timeoutHandle === null) {\n // lastCall is null here\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n if (mode === 'delayHead') {\n lastCall = call;\n } else {\n call.invokeSilently();\n }\n } else if (mode !== 'skip') {\n lastCall = call;\n }\n };\n wrapped.reset = reset;\n return wrapped;\n}\n\n/**\n * Debounce calls to `func`: the function fires only after `intervalMs` have\n * elapsed since the LAST call. Each new call resets the timer. `.reset()`\n * discards any pending fire without invoking `func`.\n */\nexport function debounce<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n // Don't clearTimeout here: the live timer will see `lastCall === null`\n // and exit quietly. Avoids a churn of cleared-then-set timers when\n // callers `reset()` then immediately call again.\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n\n const fireDelay = nextFireTime - Date.now();\n if (fireDelay <= 0) {\n nextFireTime = 0;\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n call.invokeSilently(); // Must be last\n }\n } else {\n // Another call landed; reschedule for the new deadline.\n timeoutHandle = setTimeout(fire, fireDelay);\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n lastCall = new Call<TArgs>(func, this, args);\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle ??= setTimeout(fire, intervalMs);\n };\n wrapped.reset = reset;\n return wrapped;\n}\n","/**\n * Wrap an async function so concurrent invocations are serialized into a\n * single chain — each call awaits the previous one before running, and the\n * caller receives the result of *its* own invocation.\n *\n * Useful for stateful async operations (DB writes, file I/O, network I/O\n * that must not overlap) where the underlying contract is \"one at a time.\"\n *\n * If `limit` is set and the queue is already that deep, the call short-\n * circuits and returns the same promise the most recent queued call returned\n * — i.e. it coalesces excess pressure onto the trailing in-flight call.\n * Pass `null` (the default) for unbounded queueing.\n */\nexport function serialize<TArgs extends unknown[], TResult>(\n func: (...args: TArgs) => PromiseLike<TResult> | TResult,\n limit: number | null = null\n): (...args: TArgs) => Promise<TResult> {\n let lastCall: Promise<TResult> = Promise.resolve(null as TResult);\n let queueSize = 0;\n\n return function (this: unknown, ...args: TArgs): Promise<TResult> {\n if (limit !== null && queueSize >= limit) return lastCall;\n\n queueSize++;\n const prevCall = lastCall;\n // Capture `this` via the bound caller chain so we don't have to alias\n // `this` to a local (which the linter flags).\n const invoke = (): PromiseLike<TResult> | TResult => func.apply(this, args);\n return lastCall = (async () => {\n try {\n // Wait for the previous call to settle — but don't inherit its\n // rejection. The previous caller already owns that error; if we\n // re-threw here, a single failure would poison the queue\n // forever (every subsequent call awaits the previous one).\n await prevCall.catch(() => { /* see comment above */ });\n return await invoke();\n } finally {\n queueSize--;\n }\n })();\n };\n}\n","/**\n * A fixed-capacity circular buffer supporting efficient push/pull at both\n * head and tail.\n *\n * Direct port of .NET `ActualLab.Collections.RingBuffer<T>` at\n * src/ActualLab.Core/Collections/RingBuffer.cs (simplified — TS uses plain\n * modulo instead of the power-of-two-minus-one bit-mask trick, since the\n * performance difference is negligible in JavaScript).\n */\nexport class RingBuffer<T> {\n private _buffer: (T | undefined)[];\n private _start = 0;\n private _end = 0;\n private _count = 0;\n\n readonly capacity: number;\n\n get count(): number { return this._count; }\n get isEmpty(): boolean { return this._count === 0; }\n get isFull(): boolean { return this._count === this.capacity; }\n get remainingCapacity(): number { return this.capacity - this._count; }\n get hasRemainingCapacity(): boolean { return this._count < this.capacity; }\n\n constructor(capacity: number) {\n if (capacity < 1)\n throw new RangeError(`RingBuffer capacity must be >= 1 (was ${capacity}).`);\n this.capacity = capacity;\n this._buffer = new Array<T | undefined>(capacity);\n }\n\n /** Read the item at `index` (0-indexed, from head). */\n get(index: number): T {\n if (index < 0 || index >= this._count)\n throw new RangeError(`Index ${index} out of range [0, ${this._count}).`);\n return this._buffer[(this._start + index) % this.capacity] as T;\n }\n\n /** Add an item at the tail. Throws if the buffer is full. */\n pushTail(item: T): void {\n if (this._count >= this.capacity)\n throw new Error('RingBuffer is full.');\n this._buffer[this._end] = item;\n this._end = (this._end + 1) % this.capacity;\n this._count++;\n }\n\n /** Add an item at the tail, evicting the head item if the buffer is full. */\n pushTailAndMoveHeadIfFull(item: T): void {\n if (this._count >= this.capacity) {\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n }\n this.pushTail(item);\n }\n\n /** Remove the head item. Throws if the buffer is empty. */\n pullHead(): T {\n if (this._count === 0)\n throw new Error('RingBuffer is empty.');\n const head = this._buffer[this._start] as T;\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n return head;\n }\n\n /**\n * Advance the head by `skipCount` slots, releasing references to skipped\n * items so they can be garbage-collected.\n */\n moveHead(skipCount: number): void {\n if (skipCount === 0) return;\n if (skipCount < 0 || skipCount > this._count)\n throw new RangeError(`skipCount ${skipCount} out of range [0, ${this._count}].`);\n for (let k = 0; k < skipCount; k++) {\n this._buffer[(this._start + k) % this.capacity] = undefined;\n }\n this._start = (this._start + skipCount) % this.capacity;\n this._count -= skipCount;\n }\n\n /** Remove all items. */\n clear(): void {\n for (let i = 0; i < this.capacity; i++) this._buffer[i] = undefined;\n this._start = 0;\n this._end = 0;\n this._count = 0;\n }\n\n /** Copy the buffer's contents to a new array, head-first. */\n toArray(): T[] {\n const out = new Array<T>(this._count);\n for (let i = 0; i < this._count; i++) {\n out[i] = this._buffer[(this._start + i) % this.capacity] as T;\n }\n return out;\n }\n}\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","import { delayAsync } from './delay.js';\nimport { getLogs } from './internal-logging.js';\n\nconst { warnLog } = getLogs('retry');\n\n/** A sequence of retry delays — given a 1-based try index (1 = first\n * retry, i.e. AFTER the initial failure), returns the delay in ms before\n * the next attempt. For more elaborate delay schemes, see\n * {@link RetryDelaySeq.getDelay}. */\nexport type RetryDelaySchedule = (tryIndex: number) => number;\n\nconst defaultRetryDelays: RetryDelaySchedule = () => 50;\n\n/**\n * Run `fn` up to `tryCount` times, awaiting a delay between attempts.\n * The last error is rethrown if every attempt fails.\n *\n * `fn` is passed the 0-based attempt index and the last error (or\n * `undefined` for the first attempt) — useful for adapting behavior per\n * try (e.g. switching endpoints, escalating timeouts).\n */\nexport async function retry<TResult>(\n tryCount: number,\n fn: (tryIndex: number, lastError: unknown) => PromiseLike<TResult> | TResult,\n retryDelays: RetryDelaySchedule = defaultRetryDelays,\n): Promise<TResult> {\n if (tryCount <= 0)\n throw new Error('retry: tryCount must be positive.');\n\n let lastError: unknown;\n for (let tryIndex = 0; ; ) {\n if (tryIndex >= tryCount) throw lastError;\n try {\n return await fn(tryIndex, lastError);\n } catch (e) {\n lastError = e;\n }\n ++tryIndex;\n if (tryIndex >= tryCount) throw lastError;\n warnLog?.log(`retry(${tryIndex}/${tryCount}): error:`, lastError);\n await delayAsync(retryDelays(tryIndex));\n }\n}\n\n/**\n * Run `fn` and swallow any throw, returning `onError(e)` if provided or\n * `undefined` otherwise. The returned promise always settles successfully\n * — the caller never has to `try/catch` it.\n *\n * Useful where a logical \"best-effort\" return is wanted but the runtime\n * defaults — unhandled rejection warnings, exception escape past finally\n * blocks — are not.\n */\nexport async function catchErrors<TResult>(\n fn: () => PromiseLike<TResult> | TResult,\n onError?: (e: unknown) => TResult,\n): Promise<TResult | undefined> {\n try {\n return await fn();\n } catch (e) {\n return onError ? onError(e) : undefined;\n }\n}\n"],"mappings":"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","names":["LogLevel","reset"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -171,8 +171,9 @@ declare class EventHandlerSet<T> {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */
|
|
174
|
-
declare class PromiseSource<T> {
|
|
174
|
+
declare class PromiseSource<T> implements Promise<T> {
|
|
175
175
|
readonly promise: Promise<T>;
|
|
176
|
+
readonly [Symbol.toStringTag] = "Promise";
|
|
176
177
|
private _resolve;
|
|
177
178
|
private _reject;
|
|
178
179
|
private _isCompleted;
|
|
@@ -180,6 +181,9 @@ declare class PromiseSource<T> {
|
|
|
180
181
|
get isCompleted(): boolean;
|
|
181
182
|
resolve(value: T): boolean;
|
|
182
183
|
reject(reason?: unknown): boolean;
|
|
184
|
+
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
185
|
+
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
|
|
186
|
+
finally(onfinally?: (() => void) | null): Promise<T>;
|
|
183
187
|
}
|
|
184
188
|
declare const resolvedVoidPromise: Promise<void>;
|
|
185
189
|
|
package/dist/index.d.ts
CHANGED
|
@@ -171,8 +171,9 @@ declare class EventHandlerSet<T> {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */
|
|
174
|
-
declare class PromiseSource<T> {
|
|
174
|
+
declare class PromiseSource<T> implements Promise<T> {
|
|
175
175
|
readonly promise: Promise<T>;
|
|
176
|
+
readonly [Symbol.toStringTag] = "Promise";
|
|
176
177
|
private _resolve;
|
|
177
178
|
private _reject;
|
|
178
179
|
private _isCompleted;
|
|
@@ -180,6 +181,9 @@ declare class PromiseSource<T> {
|
|
|
180
181
|
get isCompleted(): boolean;
|
|
181
182
|
resolve(value: T): boolean;
|
|
182
183
|
reject(reason?: unknown): boolean;
|
|
184
|
+
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
185
|
+
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
|
|
186
|
+
finally(onfinally?: (() => void) | null): Promise<T>;
|
|
183
187
|
}
|
|
184
188
|
declare const resolvedVoidPromise: Promise<void>;
|
|
185
189
|
|
package/dist/index.js
CHANGED
|
@@ -593,6 +593,7 @@ var AsyncLock = class {
|
|
|
593
593
|
// src/promise-source.ts
|
|
594
594
|
var PromiseSource = class {
|
|
595
595
|
promise;
|
|
596
|
+
[Symbol.toStringTag] = "Promise";
|
|
596
597
|
_resolve;
|
|
597
598
|
_reject;
|
|
598
599
|
_isCompleted = false;
|
|
@@ -617,6 +618,15 @@ var PromiseSource = class {
|
|
|
617
618
|
this._reject(reason);
|
|
618
619
|
return true;
|
|
619
620
|
}
|
|
621
|
+
then(onfulfilled, onrejected) {
|
|
622
|
+
return this.promise.then(onfulfilled, onrejected);
|
|
623
|
+
}
|
|
624
|
+
catch(onrejected) {
|
|
625
|
+
return this.promise.catch(onrejected);
|
|
626
|
+
}
|
|
627
|
+
finally(onfinally) {
|
|
628
|
+
return this.promise.finally(onfinally);
|
|
629
|
+
}
|
|
620
630
|
};
|
|
621
631
|
var resolvedVoidPromise = Promise.resolve();
|
|
622
632
|
|
|
@@ -645,7 +655,7 @@ var EventHandlerSet = class {
|
|
|
645
655
|
ps.resolve(arg);
|
|
646
656
|
};
|
|
647
657
|
this._handlers.add(handler);
|
|
648
|
-
return ps
|
|
658
|
+
return ps;
|
|
649
659
|
}
|
|
650
660
|
};
|
|
651
661
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/polyfills.ts","../src/disposable.ts","../src/logging-init.ts","../src/logging.ts","../src/result.ts","../src/async-context.ts","../src/async-lock.ts","../src/promise-source.ts","../src/events.ts","../src/withTimeout.ts","../src/promise-source-with-timeout.ts","../src/resolved-promise.ts","../src/timed-out.ts","../src/delay.ts","../src/abort-promise.ts","../src/internal-logging.ts","../src/throttle.ts","../src/serialize.ts","../src/ring-buffer.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts","../src/retry.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","/** 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","// Initialization helpers for the logging system.\n//\n// The Log class uses a single Map<string, LogLevel> to determine the minimum\n// level for each scope. This module is responsible for:\n// - Persisting the map across page reloads via localStorage on the main\n// thread, and via IndexedDB for workers.\n// - Exposing a globally accessible LogLevelController so developers can tweak\n// levels at runtime from the browser dev console (globalThis.logLevels).\n//\n// initLogging() is idempotent and called automatically on the first Log.get().\n//\n// Runtime override examples (paste into browser dev console):\n// logLevels.override('rpc.RpcPeer', 1) // exact: one scope to Debug\n// logLevels.override('rpc.*', 1) // prefix: all rpc.* scopes\n// logLevels.override('*Video*', 1) // contains: every scope with 'Video'\n// logLevels.override('*Decoder', 1) // suffix: every scope ending in 'Decoder'\n// logLevels.reset() // reset to package defaults\n// logLevels.clear() // clear all overrides\n\nimport { Log, LogLevel } from './logging.js';\n\nconst GlobalThisKey = 'logLevels';\nconst StorageKey = 'logLevels';\nconst DateStorageKey = `${StorageKey}.date`;\nconst MaxStorageAge = 86_400_000 * 3; // 3 days\nconst IndexedDbName = 'actuallab-logging';\nconst IndexedDbStore = 'settings';\nconst IndexedDbKey = 'logLevels';\n\nconst localStorage: Storage | null = tryGetLocalStorage();\n\n// Workers, worklets, and service workers run in separate JS realms with\n// their own globalThis. Within one realm, esbuild can also produce multiple\n// chunks that each carry their own copy of @actuallab/core (so multiple\n// distinct `Log` classes exist). We want the install + restore + console\n// message to happen exactly once per realm — gate via globalThis.logLevels.\nconst isMainThread = typeof window !== 'undefined';\n\nexport function initLogging(): void {\n // Warn is the global baseline — packages set per-scope defaults\n // (typically Info or Warn) via createLogProvider.\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n // Another chunk in this realm already initialized. Mirror its\n // overrides into our local Log.minLevels so this Log class observes\n // the same effective levels. (Each chunk has its own Log class with\n // its own static minLevels Map — they only converge through this\n // one-shot copy at init time.)\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = restore(minLevels);\n if (wasRestored) {\n if (isMainThread)\n console.log('Logging: logLevels are restored');\n }\n else {\n if (isMainThread)\n console.log('Logging: logLevels are reset');\n reset(minLevels);\n }\n}\n\n/** Worker bootstrap path: await this before dynamically importing any module\n * that may call getLogs() at top level. */\nexport async function initWorkerLogging(): Promise<void> {\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = await restoreFromIndexedDb(minLevels);\n if (!wasRestored)\n reset(minLevels, false);\n}\n\nexport class LogLevelController {\n constructor(private minLevels: Map<string, LogLevel>)\n { }\n\n /** Internal: used by initLogging() in secondary bundles to share the\n * primary bundle's minLevels map. */\n public getMinLevels(): Map<string, LogLevel> {\n return this.minLevels;\n }\n\n /** List the current set of overrides. */\n public list(): Record<string, LogLevel> {\n return Object.fromEntries(this.minLevels);\n }\n\n /** Print every known scope's effective level to the console as a table.\n * Shows: scope, effective level, the source ('override' / 'default-key' /\n * 'package-default' / 'baseline'), and the package default for reference.\n * Use this from the dev console to discover what to pass to override(). */\n public dump(): void {\n const baseline = Log.defaultMinLevel;\n const globalOverride = this.minLevels.get('default');\n const allScopes = new Set<string>([\n ...Log.knownScopes,\n ...Log.scopeDefaults.keys(),\n ...this.minLevels.keys(),\n ]);\n // Drop the special 'default' bucket — surfaced separately below.\n allScopes.delete('default');\n const rows: Record<string, {\n level: string;\n source: string;\n packageDefault: string;\n }> = {};\n const sorted = [...allScopes].sort();\n for (const scope of sorted) {\n const override = this.minLevels.get(scope);\n const pkgDefault = Log.scopeDefaults.get(scope);\n let level: LogLevel;\n let source: string;\n if (override !== undefined) {\n level = override;\n source = 'override';\n }\n else if (globalOverride !== undefined) {\n level = globalOverride;\n source = \"minLevels.get('default')\";\n }\n else if (pkgDefault !== undefined) {\n level = pkgDefault;\n source = 'package-default';\n }\n else {\n level = baseline;\n source = 'baseline';\n }\n rows[scope] = {\n level: LogLevel[level],\n source,\n packageDefault: pkgDefault === undefined ? '-' : LogLevel[pkgDefault],\n };\n }\n console.table(rows);\n console.log(\n `Baseline: ${LogLevel[baseline]}` +\n (globalOverride === undefined ? '' : `, default override: ${LogLevel[globalOverride]}`),\n );\n }\n\n /** Override the level for every scope matching a glob-like pattern.\n * `*` matches any sequence of characters; everything else is literal.\n * Examples:\n * override('rpc.RpcPeer', 1) // exact — one scope to Debug\n * override('rpc.*', 1) // prefix — every scope starting with 'rpc.'\n * override('*rpc*', 1) // contains — every scope with 'rpc' in it\n * override('*Peer', 1) // suffix — every scope ending with 'Peer'\n * Matches scopes that are user-overridden, package-registered (defaults),\n * or have ever been requested via Log.get(). If the pattern has no `*`\n * and nothing known matches, the literal scope is set anyway — so an\n * exact-name override placed before its scope is loaded still applies.\n * Persisted to localStorage + IndexedDB. */\n public override(pattern: string, newLevel: LogLevel): void {\n const matched = new Set<string>();\n if (pattern.includes('*')) {\n const re = patternToRegExp(pattern);\n for (const [scope] of this.minLevels)\n if (re.test(scope)) matched.add(scope);\n for (const [scope] of Log.scopeDefaults)\n if (re.test(scope)) matched.add(scope);\n for (const scope of Log.knownScopes)\n if (re.test(scope)) matched.add(scope);\n }\n else {\n matched.add(pattern);\n }\n for (const scope of matched)\n this.minLevels.set(scope, newLevel);\n persist(this.minLevels);\n }\n\n /** Reset all overrides; package defaults take effect again. Persisted. */\n public reset(): void {\n reset(this.minLevels);\n }\n\n /** Clear all overrides (no global default unless `defaultLevel` is given). */\n public clear(defaultLevel?: LogLevel): void {\n this.minLevels.clear();\n if (defaultLevel !== undefined)\n this.minLevels.set('default', defaultLevel);\n persist(this.minLevels);\n }\n}\n\nfunction patternToRegExp(pattern: string): RegExp {\n // Escape regex metacharacters except `*`, then turn each `*` into `.*`.\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*');\n return new RegExp(`^${escaped}$`);\n}\n\ninterface PersistedLogLevels {\n date: number;\n entries: [string, LogLevel][];\n}\n\nfunction restore(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = readFromStorage(localStorage);\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nasync function restoreFromIndexedDb(minLevels: Map<string, LogLevel>): Promise<boolean> {\n const snapshot = await readFromIndexedDb();\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nfunction readFromStorage(storage: Storage | null): PersistedLogLevels | null {\n if (!storage)\n return null;\n\n try {\n const dateJson = storage.getItem(DateStorageKey);\n const entriesJson = storage.getItem(StorageKey);\n if (!dateJson || !entriesJson)\n return null;\n\n return {\n date: JSON.parse(dateJson) as number,\n entries: JSON.parse(entriesJson) as [string, LogLevel][],\n };\n } catch {\n return null;\n }\n}\n\nfunction applySnapshot(minLevels: Map<string, LogLevel>, snapshot: PersistedLogLevels): boolean {\n if (typeof snapshot.date !== 'number')\n return false;\n if (Date.now() - snapshot.date > MaxStorageAge)\n return false;\n if (!Array.isArray(snapshot.entries))\n return false;\n\n minLevels.clear();\n for (const entry of snapshot.entries) {\n // Runtime guard for JSON-parsed input — types claim it's a tuple, but\n // localStorage may carry corrupted data. eslint flags the length check\n // as always-false against the static type; that's the point.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!Array.isArray(entry) || entry.length !== 2)\n return false;\n const [key, value] = entry;\n if (typeof key !== 'string' || typeof value !== 'number')\n return false;\n minLevels.set(key, value);\n }\n\n return true;\n}\n\nfunction persist(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = createSnapshot(minLevels);\n let wasPersisted = false;\n\n if (localStorage) {\n try {\n localStorage.setItem(DateStorageKey, JSON.stringify(snapshot.date));\n localStorage.setItem(StorageKey, JSON.stringify(snapshot.entries));\n wasPersisted = true;\n } catch {\n // Storage may be unavailable in private / sandboxed contexts.\n }\n }\n\n void writeToIndexedDb(snapshot);\n return wasPersisted;\n}\n\nfunction createSnapshot(minLevels: Map<string, LogLevel>): PersistedLogLevels {\n return {\n date: Date.now(),\n entries: Array.from(minLevels.entries()),\n };\n}\n\nfunction tryGetLocalStorage(): Storage | null {\n if (typeof globalThis === 'undefined' || !('localStorage' in globalThis))\n return null;\n\n try {\n return (globalThis as unknown as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n}\n\nasync function openLoggingDb(): Promise<IDBDatabase | null> {\n if (typeof indexedDB === 'undefined')\n return null;\n\n return new Promise(resolve => {\n const request = indexedDB.open(IndexedDbName, 1);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(IndexedDbStore))\n db.createObjectStore(IndexedDbStore);\n };\n request.onerror = () => resolve(null);\n request.onblocked = () => resolve(null);\n request.onsuccess = () => resolve(request.result);\n });\n}\n\nasync function readFromIndexedDb(): Promise<PersistedLogLevels | null> {\n const db = await openLoggingDb();\n if (!db)\n return null;\n\n return new Promise(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readonly');\n const request = tx.objectStore(IndexedDbStore).get(IndexedDbKey);\n request.onerror = () => resolve(null);\n request.onsuccess = () => resolve(request.result as PersistedLogLevels | null);\n tx.oncomplete = () => db.close();\n tx.onerror = () => db.close();\n tx.onabort = () => db.close();\n });\n}\n\nasync function writeToIndexedDb(snapshot: PersistedLogLevels): Promise<void> {\n const db = await openLoggingDb();\n if (!db)\n return;\n\n await new Promise<void>(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readwrite');\n tx.objectStore(IndexedDbStore).put(snapshot, IndexedDbKey);\n tx.oncomplete = () => {\n db.close();\n resolve();\n };\n tx.onerror = () => {\n db.close();\n resolve();\n };\n tx.onabort = () => {\n db.close();\n resolve();\n };\n });\n}\n\nfunction reset(minLevels: Map<string, LogLevel>, mustPersist = true): void {\n minLevels.clear();\n // Add per-scope defaults here for development.\n // Use prefix conventions: 'rpc.', 'fusion.', 'app.', etc.\n\n // minLevels.set('rpc.RpcPeer', LogLevel.Debug);\n // minLevels.set('fusion.Computed', LogLevel.Debug);\n\n if (mustPersist)\n persist(minLevels);\n}\n","// Lightweight logging primitives shared by all ActualLab TypeScript packages.\n//\n// Design:\n// - Log.get(scope) returns a bag of optional loggers ({ debugLog, infoLog,\n// warnLog, errorLog }). Each is null when its level is below the scope's\n// minimum level, so the typical call site looks like:\n//\n// debugLog?.log('something happened', value);\n//\n// The optional chaining short-circuits before evaluating the arguments —\n// so the cost of disabled logs is just one nullish check.\n//\n// - Scopes are plain strings. Each package defines its own typed scope union\n// and uses createLogProvider<TScope>(prefix) to get a typed helper that keeps\n// scope names short at call sites while ensuring globally unique keys\n// ('rpc.RpcPeer', 'fusion.Computed', etc.).\n//\n// - Minimum levels live in Log.minLevels (a Map<string, LogLevel>). An\n// entry 'default' acts as a fallback before Log.defaultMinLevel.\n//\n// - initLogging() is invoked lazily on the first Log.get() call. It restores\n// persisted levels and installs globalThis.logLevels so devs can tweak\n// levels at runtime.\n\nimport { initLogging } from './logging-init.js';\n\nexport enum LogLevel {\n Debug = 1,\n Info,\n Warn,\n Error,\n None = 1000,\n}\n\nexport interface LogRef {\n target: unknown;\n id: number;\n}\n\ninterface LogRefSetItem {\n ref: LogRef;\n touchedAt: number;\n}\n\ninterface LogRefData {\n __logRefId?: number;\n}\n\nclass LogRefSet {\n private items: LogRefSetItem[] = [];\n private idSeed = 0;\n\n constructor(private capacity: number)\n { }\n\n public ref(data: object): LogRef {\n const itemIndex = this.items.findIndex(el => el.ref.target === data);\n if (itemIndex >= 0) {\n const existing = this.items[itemIndex];\n existing.touchedAt = Date.now();\n return existing.ref;\n }\n const id = (data as LogRefData).__logRefId ?? this.idSeed++;\n const newRef: LogRef = { target: data, id };\n (data as LogRefData).__logRefId = id;\n if (this.items.length >= this.capacity)\n this.removeOldest();\n this.items.push({ ref: newRef, touchedAt: Date.now() });\n return newRef;\n }\n\n private removeOldest(): void {\n let indexToEvict = 0;\n let itemToEvict = this.items[0];\n for (let i = 1; i < this.items.length; i++) {\n const item = this.items[i];\n if (item.touchedAt < itemToEvict.touchedAt) {\n itemToEvict = item;\n indexToEvict = i;\n }\n }\n this.items.splice(indexToEvict, 1);\n // Replace the live target with its string form so we don't keep the\n // object alive purely for log identity reasons.\n const ref = itemToEvict.ref;\n ref.target = ref.target?.toString();\n }\n}\n\nexport class Log {\n private static isInitialized = false;\n private static logRefs = new LogRefSet(10);\n /** User-set overrides (persisted by logging-init). Empty by default. */\n public static readonly minLevels = new Map<string, LogLevel>();\n /** Per-scope defaults registered by packages via createLogProvider(). */\n public static readonly scopeDefaults = new Map<string, LogLevel>();\n /** Every scope ever requested via Log.get(). Used by logLevels.dump()\n * so devs can discover what's available to override at runtime. */\n public static readonly knownScopes = new Set<string>();\n /** Global baseline for any scope without a default or override. */\n public static defaultMinLevel = LogLevel.Warn;\n public static loggerFactory: (scope: string, level: LogLevel) => Log = (scope, level) => new Log(scope, level);\n\n public log: (...data: unknown[]) => void;\n public trace: (...data: unknown[]) => void;\n\n constructor(\n public readonly scope: string,\n public readonly level: LogLevel,\n ) {\n const prefix = `[${scope}]`;\n switch (level) {\n case LogLevel.Debug:\n this.log = (...data: unknown[]) => console.debug(prefix, ...data);\n break;\n case LogLevel.Info:\n this.log = (...data: unknown[]) => console.log(prefix, ...data);\n break;\n case LogLevel.Warn:\n this.log = (...data: unknown[]) => console.warn(prefix, ...data);\n break;\n case LogLevel.Error:\n this.log = (...data: unknown[]) => console.error(prefix, ...data);\n break;\n case LogLevel.None:\n throw new Error('LogLevel.None cannot be used here');\n }\n this.trace = (...data: unknown[]) => console.trace(prefix, ...data);\n }\n\n public static get(scope: string): LogScopeFns {\n if (!this.isInitialized) {\n this.isInitialized = true;\n initLogging();\n }\n this.knownScopes.add(scope);\n\n const minLevels = this.minLevels;\n // Resolution order:\n // 1. User override for this scope (persisted by logging-init)\n // 2. User-set global override (minLevels.get('default'))\n // 3. Package default for this scope (registered via createLogProvider)\n // 4. Framework baseline (Log.defaultMinLevel, Warn)\n const minLevel = minLevels.get(scope)\n ?? minLevels.get('default')\n ?? this.scopeDefaults.get(scope)\n ?? this.defaultMinLevel;\n\n const getLogger = (level: LogLevel): Log | null =>\n level >= minLevel ? this.loggerFactory(scope, level) : null;\n\n return {\n logScope: scope,\n debugLog: getLogger(LogLevel.Debug),\n infoLog: getLogger(LogLevel.Info),\n warnLog: getLogger(LogLevel.Warn),\n errorLog: getLogger(LogLevel.Error),\n };\n }\n\n public static ref(data: object | null | undefined): object | null | undefined {\n if (!data)\n return data;\n return this.logRefs.ref(data);\n }\n\n public assert(predicate?: boolean, ...data: unknown[]): void {\n if (!predicate)\n this.log(...data);\n }\n}\n\nexport interface LogScopeFns {\n logScope: string;\n debugLog: Log | null;\n infoLog: Log | null;\n warnLog: Log | null;\n errorLog: Log | null;\n}\n\n// Per-package factory: creates a typed getLogs(scope) that prepends the package\n// prefix to the scope name before delegating to Log.get. Keeps call sites\n// concise while ensuring globally unique scope keys.\n//\n// `defaults` is required (not Partial) so that every scope in TScope has an\n// explicit default level — TypeScript will refuse to compile if a scope is\n// missing. Defaults register into Log.scopeDefaults and act as the fallback\n// when no user override is set.\n//\n// All declared scopes are also pre-registered in Log.knownScopes so that\n// logLevels.dump() (in dev console) can list them even before they're first\n// touched at runtime.\nexport function createLogProvider<TScope extends string>(\n prefix: string,\n defaults: Record<TScope, LogLevel>,\n): (scope: TScope) => LogScopeFns {\n for (const [scope, level] of Object.entries(defaults) as [TScope, LogLevel][]) {\n const fullName = prefix + scope;\n Log.scopeDefaults.set(fullName, level);\n Log.knownScopes.add(fullName);\n }\n return scope => Log.get(prefix + scope);\n}\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","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","/** 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","/** Error type rejected by {@link withTimeout} when its budget elapses. */\nexport class TimeoutError extends Error {\n override readonly name = 'TimeoutError';\n\n constructor(message = 'Operation timed out') {\n super(message);\n }\n}\n\n/**\n * Race `promise` against a `ms`-millisecond timer. Resolves with the inner\n * promise's value if it settles first; otherwise rejects with a\n * {@link TimeoutError} carrying `message`. The timer is always cleared in\n * a `finally`, so it cannot keep the event loop alive after the race ends.\n *\n * The inner promise's rejection (and the timeout's) are routed through\n * `Promise.race`, so callers should `await` the result inside a `try/catch`\n * exactly as they would for a single awaited promise. There's no\n * \"unhandled rejection\" hazard from the timeout branch — the race always\n * observes whichever promise wins, and the loser is allowed to settle\n * silently into the void.\n */\nexport async function withTimeout<T>(\n promise: PromiseLike<T>,\n ms: number,\n message?: string\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new TimeoutError(message ?? `Operation timed out after ${ms}ms`)),\n ms\n );\n });\n // Routed via `Promise.race` below; suppress the standalone unhandled-\n // rejection warning that fires when `promise` wins instead.\n timeoutPromise.catch(() => { /* noop */ });\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n","import { PromiseSource } from './promise-source.js';\nimport { TimeoutError } from './withTimeout.js';\n\n/**\n * A {@link PromiseSource} with a built-in timer that can reject (or run a\n * caller-supplied callback) after a configurable delay. The timer is\n * automatically cleared when the promise settles by other means, so callers\n * don't have to remember to `clearTimeout()` on every success path.\n *\n * Typical use:\n * ```ts\n * const ps = new PromiseSourceWithTimeout<string>();\n * ps.setTimeout(5_000); // rejects after 5s if still pending\n * ps.setTimeout(5_000, () => ps.resolve('fallback')); // or run a custom callback\n * ```\n *\n * Replaces the `PromiseSourceWithTimeout` previously kept in\n * `ActualChat/src/nodejs/src/promises.ts`. Note: the Voxt original supported a\n * \"precise\" (requestAnimationFrame-based) variant; we drop it here because no\n * caller in ActualChat uses it outside `promises.ts` itself.\n */\nexport class PromiseSourceWithTimeout<T> extends PromiseSource<T> {\n private _timer: ReturnType<typeof setTimeout> | undefined;\n\n hasTimeout(): boolean {\n return this._timer !== undefined;\n }\n\n /**\n * Install (or replace) a timeout. Pass `null` to remove without setting a\n * new one. `callback` is invoked when the timer fires — if omitted, the\n * promise is rejected with a generic \"timed out\" error.\n */\n setTimeout(ms: number | null, callback?: () => unknown): void {\n this.clearTimeout();\n if (ms === null || this.isCompleted) return;\n\n this._timer = setTimeout(() => {\n this._timer = undefined;\n if (callback) callback();\n else this.reject(new TimeoutError(`The promise has timed out after ${ms}ms.`));\n }, ms);\n }\n\n clearTimeout(): void {\n if (this._timer === undefined) return;\n clearTimeout(this._timer);\n this._timer = undefined;\n }\n\n override resolve(value: T): boolean {\n const didSettle = super.resolve(value);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n\n override reject(reason?: unknown): boolean {\n const didSettle = super.reject(reason);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n}\n","/**\n * Pre-resolved promises for the three values most often returned as a\n * \"no-op\" successful path: `void`, `true`, `false`. Returning these\n * avoids allocating a fresh promise per call site.\n *\n * Idiomatic use:\n * ```ts\n * if (alreadyInitialized) return ResolvedPromise.Void;\n * ```\n */\nexport const ResolvedPromise = {\n Void: Promise.resolve(),\n True: Promise.resolve(true),\n False: Promise.resolve(false),\n} as const;\n","/**\n * Sentinel returned/thrown by code that distinguishes \"the operation took\n * too long\" from a generic rejection. Identity-comparable via the\n * `instance` singleton — callers can branch on `result === TimedOut.instance`.\n */\nexport class TimedOut {\n static readonly instance: TimedOut = new TimedOut();\n}\n","/** Resolves after `ms` milliseconds. */\nexport function delayAsync(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\n/** Resolves with `value` after `ms` milliseconds. */\nexport function delayAsyncWith<T>(ms: number, value: T): Promise<T> {\n return new Promise<T>(resolve => {\n setTimeout(() => resolve(value), ms);\n });\n}\n","/**\n * Adapt an `AbortSignal` to a Promise that **rejects** with the signal's\n * `reason` once the signal fires (or immediately, if it's already\n * aborted). Mirrors `signal.throwIfAborted()` semantics in Promise form:\n * the rejected value is exactly what `throwIfAborted()` would have\n * thrown — by default a `DOMException` with `name === 'AbortError'`,\n * or whatever was passed to `abortController.abort(reason)`.\n *\n * Operators racing upstream pulls / timers against cancellation plug\n * this into `Promise.race(...)` so abort propagates as a thrown error —\n * `try/finally` blocks unwind naturally; no sentinel values to thread.\n *\n * Promises are cached per signal: every call for the same signal returns\n * the SAME promise and registers AT MOST ONE listener. Operators that\n * race per-iteration (e.g. encode loops calling this once per chunk)\n * won't accumulate listeners or hit Node's `MaxListenersExceeded` warning.\n * The cache is a `WeakMap` so signals remain GC-eligible normally.\n *\n * Callers that prefer a sentinel can attach `.catch()` to convert the\n * rejection back into a value: `abortPromise(s).catch(() => 'stopped')`.\n */\nconst abortPromiseCache = new WeakMap<AbortSignal, Promise<never>>();\n\nexport function abortPromise(signal: AbortSignal): Promise<never> {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- mirroring `signal.throwIfAborted()`: the rejection value IS the signal's reason, which by Web spec is a `DOMException` by default but can be any value the caller passed to `abort(reason)`.\n if (signal.aborted) return Promise.reject(signal.reason);\n let cached = abortPromiseCache.get(signal);\n if (!cached) {\n cached = new Promise<never>((_, reject) => {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- see comment above; signal.reason is the canonical thrown value.\n signal.addEventListener('abort', () => reject(signal.reason), { once: true });\n });\n // Mark the cached rejection as observed so unhandled-rejection\n // warnings don't fire when a caller never `await`s it (e.g. an\n // operator that completed before abort and let the race promise\n // GC). The actual await-time rejection still surfaces normally.\n cached.catch(() => { /* swallow for cache-only consumers */ });\n abortPromiseCache.set(signal, cached);\n }\n return cached;\n}\n","import { LogLevel, createLogProvider } from './logging.js';\n\n/** Log scopes used inside `@actuallab/core` itself. Each is registered at\n * `core.<scope>`. Keep the list tight — most utilities should propagate\n * errors rather than log them. */\nexport type CoreLogScope =\n | 'retry'\n | 'throttle';\n\nconst scopeDefaults: Record<CoreLogScope, LogLevel> = {\n retry: LogLevel.Warn,\n throttle: LogLevel.Warn,\n};\n\nexport const getLogs = createLogProvider<CoreLogScope>('core.', scopeDefaults);\n","import { getLogs } from './internal-logging.js';\n\nconst { errorLog } = getLogs('throttle');\n\n/** A function wrapped by {@link throttle} or {@link debounce}. Calling it\n * triggers the underlying function according to the scheduling rule;\n * `reset()` discards any pending scheduled call. */\nexport interface ResettableFunc<TArgs extends unknown[]> {\n (...args: TArgs): void;\n reset(): void;\n}\n\nclass Call<TArgs extends unknown[]> {\n constructor(\n readonly func: (...args: TArgs) => unknown,\n readonly self: unknown,\n readonly parameters: TArgs\n ) { }\n\n invoke(): unknown {\n return this.func.apply(this.self, this.parameters);\n }\n\n invokeSilently(): unknown {\n try {\n return this.invoke();\n } catch (error) {\n errorLog?.log('Call.invokeSilently: unhandled error:', error);\n }\n }\n}\n\n/** Throttle modes:\n * - `default` — fire the head call immediately, then drop further calls\n * until the interval elapses; the *last* one is fired at interval end.\n * - `skip` — fire the head call immediately, drop ALL calls during the\n * interval (no tail call).\n * - `delayHead` — delay even the head call by one interval; subsequent\n * calls overwrite the pending one. */\nexport type ThrottleMode = 'default' | 'skip' | 'delayHead';\n\n/**\n * Throttle calls to `func` so that it fires at most once every `intervalMs`.\n * The returned function has a `.reset()` that discards any pending tail call\n * and re-arms the head-call behavior on the next invocation.\n */\nexport function throttle<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number,\n mode: ThrottleMode = 'default'\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n call.invokeSilently(); // Must be last\n } else {\n timeoutHandle = null;\n nextFireTime = 0;\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n const call = new Call<TArgs>(func, this, args);\n const fireDelay = nextFireTime - Date.now();\n if (timeoutHandle !== null && fireDelay <= 0) {\n // Delayed \"fire\" is ready but not yet executed — flush it now.\n fire();\n }\n\n if (timeoutHandle === null) {\n // lastCall is null here\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n if (mode === 'delayHead') {\n lastCall = call;\n } else {\n call.invokeSilently();\n }\n } else if (mode !== 'skip') {\n lastCall = call;\n }\n };\n wrapped.reset = reset;\n return wrapped;\n}\n\n/**\n * Debounce calls to `func`: the function fires only after `intervalMs` have\n * elapsed since the LAST call. Each new call resets the timer. `.reset()`\n * discards any pending fire without invoking `func`.\n */\nexport function debounce<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n // Don't clearTimeout here: the live timer will see `lastCall === null`\n // and exit quietly. Avoids a churn of cleared-then-set timers when\n // callers `reset()` then immediately call again.\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n\n const fireDelay = nextFireTime - Date.now();\n if (fireDelay <= 0) {\n nextFireTime = 0;\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n call.invokeSilently(); // Must be last\n }\n } else {\n // Another call landed; reschedule for the new deadline.\n timeoutHandle = setTimeout(fire, fireDelay);\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n lastCall = new Call<TArgs>(func, this, args);\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle ??= setTimeout(fire, intervalMs);\n };\n wrapped.reset = reset;\n return wrapped;\n}\n","/**\n * Wrap an async function so concurrent invocations are serialized into a\n * single chain — each call awaits the previous one before running, and the\n * caller receives the result of *its* own invocation.\n *\n * Useful for stateful async operations (DB writes, file I/O, network I/O\n * that must not overlap) where the underlying contract is \"one at a time.\"\n *\n * If `limit` is set and the queue is already that deep, the call short-\n * circuits and returns the same promise the most recent queued call returned\n * — i.e. it coalesces excess pressure onto the trailing in-flight call.\n * Pass `null` (the default) for unbounded queueing.\n */\nexport function serialize<TArgs extends unknown[], TResult>(\n func: (...args: TArgs) => PromiseLike<TResult> | TResult,\n limit: number | null = null\n): (...args: TArgs) => Promise<TResult> {\n let lastCall: Promise<TResult> = Promise.resolve(null as TResult);\n let queueSize = 0;\n\n return function (this: unknown, ...args: TArgs): Promise<TResult> {\n if (limit !== null && queueSize >= limit) return lastCall;\n\n queueSize++;\n const prevCall = lastCall;\n // Capture `this` via the bound caller chain so we don't have to alias\n // `this` to a local (which the linter flags).\n const invoke = (): PromiseLike<TResult> | TResult => func.apply(this, args);\n return lastCall = (async () => {\n try {\n // Wait for the previous call to settle — but don't inherit its\n // rejection. The previous caller already owns that error; if we\n // re-threw here, a single failure would poison the queue\n // forever (every subsequent call awaits the previous one).\n await prevCall.catch(() => { /* see comment above */ });\n return await invoke();\n } finally {\n queueSize--;\n }\n })();\n };\n}\n","/**\n * A fixed-capacity circular buffer supporting efficient push/pull at both\n * head and tail.\n *\n * Direct port of .NET `ActualLab.Collections.RingBuffer<T>` at\n * src/ActualLab.Core/Collections/RingBuffer.cs (simplified — TS uses plain\n * modulo instead of the power-of-two-minus-one bit-mask trick, since the\n * performance difference is negligible in JavaScript).\n */\nexport class RingBuffer<T> {\n private _buffer: (T | undefined)[];\n private _start = 0;\n private _end = 0;\n private _count = 0;\n\n readonly capacity: number;\n\n get count(): number { return this._count; }\n get isEmpty(): boolean { return this._count === 0; }\n get isFull(): boolean { return this._count === this.capacity; }\n get remainingCapacity(): number { return this.capacity - this._count; }\n get hasRemainingCapacity(): boolean { return this._count < this.capacity; }\n\n constructor(capacity: number) {\n if (capacity < 1)\n throw new RangeError(`RingBuffer capacity must be >= 1 (was ${capacity}).`);\n this.capacity = capacity;\n this._buffer = new Array<T | undefined>(capacity);\n }\n\n /** Read the item at `index` (0-indexed, from head). */\n get(index: number): T {\n if (index < 0 || index >= this._count)\n throw new RangeError(`Index ${index} out of range [0, ${this._count}).`);\n return this._buffer[(this._start + index) % this.capacity] as T;\n }\n\n /** Add an item at the tail. Throws if the buffer is full. */\n pushTail(item: T): void {\n if (this._count >= this.capacity)\n throw new Error('RingBuffer is full.');\n this._buffer[this._end] = item;\n this._end = (this._end + 1) % this.capacity;\n this._count++;\n }\n\n /** Add an item at the tail, evicting the head item if the buffer is full. */\n pushTailAndMoveHeadIfFull(item: T): void {\n if (this._count >= this.capacity) {\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n }\n this.pushTail(item);\n }\n\n /** Remove the head item. Throws if the buffer is empty. */\n pullHead(): T {\n if (this._count === 0)\n throw new Error('RingBuffer is empty.');\n const head = this._buffer[this._start] as T;\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n return head;\n }\n\n /**\n * Advance the head by `skipCount` slots, releasing references to skipped\n * items so they can be garbage-collected.\n */\n moveHead(skipCount: number): void {\n if (skipCount === 0) return;\n if (skipCount < 0 || skipCount > this._count)\n throw new RangeError(`skipCount ${skipCount} out of range [0, ${this._count}].`);\n for (let k = 0; k < skipCount; k++) {\n this._buffer[(this._start + k) % this.capacity] = undefined;\n }\n this._start = (this._start + skipCount) % this.capacity;\n this._count -= skipCount;\n }\n\n /** Remove all items. */\n clear(): void {\n for (let i = 0; i < this.capacity; i++) this._buffer[i] = undefined;\n this._start = 0;\n this._end = 0;\n this._count = 0;\n }\n\n /** Copy the buffer's contents to a new array, head-first. */\n toArray(): T[] {\n const out = new Array<T>(this._count);\n for (let i = 0; i < this._count; i++) {\n out[i] = this._buffer[(this._start + i) % this.capacity] as T;\n }\n return out;\n }\n}\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","import { delayAsync } from './delay.js';\nimport { getLogs } from './internal-logging.js';\n\nconst { warnLog } = getLogs('retry');\n\n/** A sequence of retry delays — given a 1-based try index (1 = first\n * retry, i.e. AFTER the initial failure), returns the delay in ms before\n * the next attempt. For more elaborate delay schemes, see\n * {@link RetryDelaySeq.getDelay}. */\nexport type RetryDelaySchedule = (tryIndex: number) => number;\n\nconst defaultRetryDelays: RetryDelaySchedule = () => 50;\n\n/**\n * Run `fn` up to `tryCount` times, awaiting a delay between attempts.\n * The last error is rethrown if every attempt fails.\n *\n * `fn` is passed the 0-based attempt index and the last error (or\n * `undefined` for the first attempt) — useful for adapting behavior per\n * try (e.g. switching endpoints, escalating timeouts).\n */\nexport async function retry<TResult>(\n tryCount: number,\n fn: (tryIndex: number, lastError: unknown) => PromiseLike<TResult> | TResult,\n retryDelays: RetryDelaySchedule = defaultRetryDelays,\n): Promise<TResult> {\n if (tryCount <= 0)\n throw new Error('retry: tryCount must be positive.');\n\n let lastError: unknown;\n for (let tryIndex = 0; ; ) {\n if (tryIndex >= tryCount) throw lastError;\n try {\n return await fn(tryIndex, lastError);\n } catch (e) {\n lastError = e;\n }\n ++tryIndex;\n if (tryIndex >= tryCount) throw lastError;\n warnLog?.log(`retry(${tryIndex}/${tryCount}): error:`, lastError);\n await delayAsync(retryDelays(tryIndex));\n }\n}\n\n/**\n * Run `fn` and swallow any throw, returning `onError(e)` if provided or\n * `undefined` otherwise. The returned promise always settles successfully\n * — the caller never has to `try/catch` it.\n *\n * Useful where a logical \"best-effort\" return is wanted but the runtime\n * defaults — unhandled rejection warnings, exception escape past finally\n * blocks — are not.\n */\nexport async function catchErrors<TResult>(\n fn: () => PromiseLike<TResult> | TResult,\n onError?: (e: unknown) => TResult,\n): Promise<TResult | undefined> {\n try {\n return await fn();\n } catch (e) {\n return onError ? onError(e) : undefined;\n }\n}\n"],"mappings":"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","names":["LogLevel","reset"]}
|
|
1
|
+
{"version":3,"sources":["../src/polyfills.ts","../src/disposable.ts","../src/logging-init.ts","../src/logging.ts","../src/result.ts","../src/async-context.ts","../src/async-lock.ts","../src/promise-source.ts","../src/events.ts","../src/withTimeout.ts","../src/promise-source-with-timeout.ts","../src/resolved-promise.ts","../src/timed-out.ts","../src/delay.ts","../src/abort-promise.ts","../src/internal-logging.ts","../src/throttle.ts","../src/serialize.ts","../src/ring-buffer.ts","../src/retry-delay-seq.ts","../src/retry-delayer.ts","../src/retry.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","/** 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","// Initialization helpers for the logging system.\n//\n// The Log class uses a single Map<string, LogLevel> to determine the minimum\n// level for each scope. This module is responsible for:\n// - Persisting the map across page reloads via localStorage on the main\n// thread, and via IndexedDB for workers.\n// - Exposing a globally accessible LogLevelController so developers can tweak\n// levels at runtime from the browser dev console (globalThis.logLevels).\n//\n// initLogging() is idempotent and called automatically on the first Log.get().\n//\n// Runtime override examples (paste into browser dev console):\n// logLevels.override('rpc.RpcPeer', 1) // exact: one scope to Debug\n// logLevels.override('rpc.*', 1) // prefix: all rpc.* scopes\n// logLevels.override('*Video*', 1) // contains: every scope with 'Video'\n// logLevels.override('*Decoder', 1) // suffix: every scope ending in 'Decoder'\n// logLevels.reset() // reset to package defaults\n// logLevels.clear() // clear all overrides\n\nimport { Log, LogLevel } from './logging.js';\n\nconst GlobalThisKey = 'logLevels';\nconst StorageKey = 'logLevels';\nconst DateStorageKey = `${StorageKey}.date`;\nconst MaxStorageAge = 86_400_000 * 3; // 3 days\nconst IndexedDbName = 'actuallab-logging';\nconst IndexedDbStore = 'settings';\nconst IndexedDbKey = 'logLevels';\n\nconst localStorage: Storage | null = tryGetLocalStorage();\n\n// Workers, worklets, and service workers run in separate JS realms with\n// their own globalThis. Within one realm, esbuild can also produce multiple\n// chunks that each carry their own copy of @actuallab/core (so multiple\n// distinct `Log` classes exist). We want the install + restore + console\n// message to happen exactly once per realm — gate via globalThis.logLevels.\nconst isMainThread = typeof window !== 'undefined';\n\nexport function initLogging(): void {\n // Warn is the global baseline — packages set per-scope defaults\n // (typically Info or Warn) via createLogProvider.\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n // Another chunk in this realm already initialized. Mirror its\n // overrides into our local Log.minLevels so this Log class observes\n // the same effective levels. (Each chunk has its own Log class with\n // its own static minLevels Map — they only converge through this\n // one-shot copy at init time.)\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = restore(minLevels);\n if (wasRestored) {\n if (isMainThread)\n console.log('Logging: logLevels are restored');\n }\n else {\n if (isMainThread)\n console.log('Logging: logLevels are reset');\n reset(minLevels);\n }\n}\n\n/** Worker bootstrap path: await this before dynamically importing any module\n * that may call getLogs() at top level. */\nexport async function initWorkerLogging(): Promise<void> {\n Log.defaultMinLevel = LogLevel.Warn;\n const minLevels = Log.minLevels;\n const g = globalThis as Record<string, unknown>;\n const existing = g[GlobalThisKey] as LogLevelController | undefined;\n\n if (existing !== undefined) {\n for (const [k, v] of existing.getMinLevels())\n minLevels.set(k, v);\n return;\n }\n\n g[GlobalThisKey] = new LogLevelController(minLevels);\n const wasRestored = await restoreFromIndexedDb(minLevels);\n if (!wasRestored)\n reset(minLevels, false);\n}\n\nexport class LogLevelController {\n constructor(private minLevels: Map<string, LogLevel>)\n { }\n\n /** Internal: used by initLogging() in secondary bundles to share the\n * primary bundle's minLevels map. */\n public getMinLevels(): Map<string, LogLevel> {\n return this.minLevels;\n }\n\n /** List the current set of overrides. */\n public list(): Record<string, LogLevel> {\n return Object.fromEntries(this.minLevels);\n }\n\n /** Print every known scope's effective level to the console as a table.\n * Shows: scope, effective level, the source ('override' / 'default-key' /\n * 'package-default' / 'baseline'), and the package default for reference.\n * Use this from the dev console to discover what to pass to override(). */\n public dump(): void {\n const baseline = Log.defaultMinLevel;\n const globalOverride = this.minLevels.get('default');\n const allScopes = new Set<string>([\n ...Log.knownScopes,\n ...Log.scopeDefaults.keys(),\n ...this.minLevels.keys(),\n ]);\n // Drop the special 'default' bucket — surfaced separately below.\n allScopes.delete('default');\n const rows: Record<string, {\n level: string;\n source: string;\n packageDefault: string;\n }> = {};\n const sorted = [...allScopes].sort();\n for (const scope of sorted) {\n const override = this.minLevels.get(scope);\n const pkgDefault = Log.scopeDefaults.get(scope);\n let level: LogLevel;\n let source: string;\n if (override !== undefined) {\n level = override;\n source = 'override';\n }\n else if (globalOverride !== undefined) {\n level = globalOverride;\n source = \"minLevels.get('default')\";\n }\n else if (pkgDefault !== undefined) {\n level = pkgDefault;\n source = 'package-default';\n }\n else {\n level = baseline;\n source = 'baseline';\n }\n rows[scope] = {\n level: LogLevel[level],\n source,\n packageDefault: pkgDefault === undefined ? '-' : LogLevel[pkgDefault],\n };\n }\n console.table(rows);\n console.log(\n `Baseline: ${LogLevel[baseline]}` +\n (globalOverride === undefined ? '' : `, default override: ${LogLevel[globalOverride]}`),\n );\n }\n\n /** Override the level for every scope matching a glob-like pattern.\n * `*` matches any sequence of characters; everything else is literal.\n * Examples:\n * override('rpc.RpcPeer', 1) // exact — one scope to Debug\n * override('rpc.*', 1) // prefix — every scope starting with 'rpc.'\n * override('*rpc*', 1) // contains — every scope with 'rpc' in it\n * override('*Peer', 1) // suffix — every scope ending with 'Peer'\n * Matches scopes that are user-overridden, package-registered (defaults),\n * or have ever been requested via Log.get(). If the pattern has no `*`\n * and nothing known matches, the literal scope is set anyway — so an\n * exact-name override placed before its scope is loaded still applies.\n * Persisted to localStorage + IndexedDB. */\n public override(pattern: string, newLevel: LogLevel): void {\n const matched = new Set<string>();\n if (pattern.includes('*')) {\n const re = patternToRegExp(pattern);\n for (const [scope] of this.minLevels)\n if (re.test(scope)) matched.add(scope);\n for (const [scope] of Log.scopeDefaults)\n if (re.test(scope)) matched.add(scope);\n for (const scope of Log.knownScopes)\n if (re.test(scope)) matched.add(scope);\n }\n else {\n matched.add(pattern);\n }\n for (const scope of matched)\n this.minLevels.set(scope, newLevel);\n persist(this.minLevels);\n }\n\n /** Reset all overrides; package defaults take effect again. Persisted. */\n public reset(): void {\n reset(this.minLevels);\n }\n\n /** Clear all overrides (no global default unless `defaultLevel` is given). */\n public clear(defaultLevel?: LogLevel): void {\n this.minLevels.clear();\n if (defaultLevel !== undefined)\n this.minLevels.set('default', defaultLevel);\n persist(this.minLevels);\n }\n}\n\nfunction patternToRegExp(pattern: string): RegExp {\n // Escape regex metacharacters except `*`, then turn each `*` into `.*`.\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*');\n return new RegExp(`^${escaped}$`);\n}\n\ninterface PersistedLogLevels {\n date: number;\n entries: [string, LogLevel][];\n}\n\nfunction restore(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = readFromStorage(localStorage);\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nasync function restoreFromIndexedDb(minLevels: Map<string, LogLevel>): Promise<boolean> {\n const snapshot = await readFromIndexedDb();\n if (!snapshot)\n return false;\n\n return applySnapshot(minLevels, snapshot);\n}\n\nfunction readFromStorage(storage: Storage | null): PersistedLogLevels | null {\n if (!storage)\n return null;\n\n try {\n const dateJson = storage.getItem(DateStorageKey);\n const entriesJson = storage.getItem(StorageKey);\n if (!dateJson || !entriesJson)\n return null;\n\n return {\n date: JSON.parse(dateJson) as number,\n entries: JSON.parse(entriesJson) as [string, LogLevel][],\n };\n } catch {\n return null;\n }\n}\n\nfunction applySnapshot(minLevels: Map<string, LogLevel>, snapshot: PersistedLogLevels): boolean {\n if (typeof snapshot.date !== 'number')\n return false;\n if (Date.now() - snapshot.date > MaxStorageAge)\n return false;\n if (!Array.isArray(snapshot.entries))\n return false;\n\n minLevels.clear();\n for (const entry of snapshot.entries) {\n // Runtime guard for JSON-parsed input — types claim it's a tuple, but\n // localStorage may carry corrupted data. eslint flags the length check\n // as always-false against the static type; that's the point.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!Array.isArray(entry) || entry.length !== 2)\n return false;\n const [key, value] = entry;\n if (typeof key !== 'string' || typeof value !== 'number')\n return false;\n minLevels.set(key, value);\n }\n\n return true;\n}\n\nfunction persist(minLevels: Map<string, LogLevel>): boolean {\n const snapshot = createSnapshot(minLevels);\n let wasPersisted = false;\n\n if (localStorage) {\n try {\n localStorage.setItem(DateStorageKey, JSON.stringify(snapshot.date));\n localStorage.setItem(StorageKey, JSON.stringify(snapshot.entries));\n wasPersisted = true;\n } catch {\n // Storage may be unavailable in private / sandboxed contexts.\n }\n }\n\n void writeToIndexedDb(snapshot);\n return wasPersisted;\n}\n\nfunction createSnapshot(minLevels: Map<string, LogLevel>): PersistedLogLevels {\n return {\n date: Date.now(),\n entries: Array.from(minLevels.entries()),\n };\n}\n\nfunction tryGetLocalStorage(): Storage | null {\n if (typeof globalThis === 'undefined' || !('localStorage' in globalThis))\n return null;\n\n try {\n return (globalThis as unknown as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n}\n\nasync function openLoggingDb(): Promise<IDBDatabase | null> {\n if (typeof indexedDB === 'undefined')\n return null;\n\n return new Promise(resolve => {\n const request = indexedDB.open(IndexedDbName, 1);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(IndexedDbStore))\n db.createObjectStore(IndexedDbStore);\n };\n request.onerror = () => resolve(null);\n request.onblocked = () => resolve(null);\n request.onsuccess = () => resolve(request.result);\n });\n}\n\nasync function readFromIndexedDb(): Promise<PersistedLogLevels | null> {\n const db = await openLoggingDb();\n if (!db)\n return null;\n\n return new Promise(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readonly');\n const request = tx.objectStore(IndexedDbStore).get(IndexedDbKey);\n request.onerror = () => resolve(null);\n request.onsuccess = () => resolve(request.result as PersistedLogLevels | null);\n tx.oncomplete = () => db.close();\n tx.onerror = () => db.close();\n tx.onabort = () => db.close();\n });\n}\n\nasync function writeToIndexedDb(snapshot: PersistedLogLevels): Promise<void> {\n const db = await openLoggingDb();\n if (!db)\n return;\n\n await new Promise<void>(resolve => {\n const tx = db.transaction(IndexedDbStore, 'readwrite');\n tx.objectStore(IndexedDbStore).put(snapshot, IndexedDbKey);\n tx.oncomplete = () => {\n db.close();\n resolve();\n };\n tx.onerror = () => {\n db.close();\n resolve();\n };\n tx.onabort = () => {\n db.close();\n resolve();\n };\n });\n}\n\nfunction reset(minLevels: Map<string, LogLevel>, mustPersist = true): void {\n minLevels.clear();\n // Add per-scope defaults here for development.\n // Use prefix conventions: 'rpc.', 'fusion.', 'app.', etc.\n\n // minLevels.set('rpc.RpcPeer', LogLevel.Debug);\n // minLevels.set('fusion.Computed', LogLevel.Debug);\n\n if (mustPersist)\n persist(minLevels);\n}\n","// Lightweight logging primitives shared by all ActualLab TypeScript packages.\n//\n// Design:\n// - Log.get(scope) returns a bag of optional loggers ({ debugLog, infoLog,\n// warnLog, errorLog }). Each is null when its level is below the scope's\n// minimum level, so the typical call site looks like:\n//\n// debugLog?.log('something happened', value);\n//\n// The optional chaining short-circuits before evaluating the arguments —\n// so the cost of disabled logs is just one nullish check.\n//\n// - Scopes are plain strings. Each package defines its own typed scope union\n// and uses createLogProvider<TScope>(prefix) to get a typed helper that keeps\n// scope names short at call sites while ensuring globally unique keys\n// ('rpc.RpcPeer', 'fusion.Computed', etc.).\n//\n// - Minimum levels live in Log.minLevels (a Map<string, LogLevel>). An\n// entry 'default' acts as a fallback before Log.defaultMinLevel.\n//\n// - initLogging() is invoked lazily on the first Log.get() call. It restores\n// persisted levels and installs globalThis.logLevels so devs can tweak\n// levels at runtime.\n\nimport { initLogging } from './logging-init.js';\n\nexport enum LogLevel {\n Debug = 1,\n Info,\n Warn,\n Error,\n None = 1000,\n}\n\nexport interface LogRef {\n target: unknown;\n id: number;\n}\n\ninterface LogRefSetItem {\n ref: LogRef;\n touchedAt: number;\n}\n\ninterface LogRefData {\n __logRefId?: number;\n}\n\nclass LogRefSet {\n private items: LogRefSetItem[] = [];\n private idSeed = 0;\n\n constructor(private capacity: number)\n { }\n\n public ref(data: object): LogRef {\n const itemIndex = this.items.findIndex(el => el.ref.target === data);\n if (itemIndex >= 0) {\n const existing = this.items[itemIndex];\n existing.touchedAt = Date.now();\n return existing.ref;\n }\n const id = (data as LogRefData).__logRefId ?? this.idSeed++;\n const newRef: LogRef = { target: data, id };\n (data as LogRefData).__logRefId = id;\n if (this.items.length >= this.capacity)\n this.removeOldest();\n this.items.push({ ref: newRef, touchedAt: Date.now() });\n return newRef;\n }\n\n private removeOldest(): void {\n let indexToEvict = 0;\n let itemToEvict = this.items[0];\n for (let i = 1; i < this.items.length; i++) {\n const item = this.items[i];\n if (item.touchedAt < itemToEvict.touchedAt) {\n itemToEvict = item;\n indexToEvict = i;\n }\n }\n this.items.splice(indexToEvict, 1);\n // Replace the live target with its string form so we don't keep the\n // object alive purely for log identity reasons.\n const ref = itemToEvict.ref;\n ref.target = ref.target?.toString();\n }\n}\n\nexport class Log {\n private static isInitialized = false;\n private static logRefs = new LogRefSet(10);\n /** User-set overrides (persisted by logging-init). Empty by default. */\n public static readonly minLevels = new Map<string, LogLevel>();\n /** Per-scope defaults registered by packages via createLogProvider(). */\n public static readonly scopeDefaults = new Map<string, LogLevel>();\n /** Every scope ever requested via Log.get(). Used by logLevels.dump()\n * so devs can discover what's available to override at runtime. */\n public static readonly knownScopes = new Set<string>();\n /** Global baseline for any scope without a default or override. */\n public static defaultMinLevel = LogLevel.Warn;\n public static loggerFactory: (scope: string, level: LogLevel) => Log = (scope, level) => new Log(scope, level);\n\n public log: (...data: unknown[]) => void;\n public trace: (...data: unknown[]) => void;\n\n constructor(\n public readonly scope: string,\n public readonly level: LogLevel,\n ) {\n const prefix = `[${scope}]`;\n switch (level) {\n case LogLevel.Debug:\n this.log = (...data: unknown[]) => console.debug(prefix, ...data);\n break;\n case LogLevel.Info:\n this.log = (...data: unknown[]) => console.log(prefix, ...data);\n break;\n case LogLevel.Warn:\n this.log = (...data: unknown[]) => console.warn(prefix, ...data);\n break;\n case LogLevel.Error:\n this.log = (...data: unknown[]) => console.error(prefix, ...data);\n break;\n case LogLevel.None:\n throw new Error('LogLevel.None cannot be used here');\n }\n this.trace = (...data: unknown[]) => console.trace(prefix, ...data);\n }\n\n public static get(scope: string): LogScopeFns {\n if (!this.isInitialized) {\n this.isInitialized = true;\n initLogging();\n }\n this.knownScopes.add(scope);\n\n const minLevels = this.minLevels;\n // Resolution order:\n // 1. User override for this scope (persisted by logging-init)\n // 2. User-set global override (minLevels.get('default'))\n // 3. Package default for this scope (registered via createLogProvider)\n // 4. Framework baseline (Log.defaultMinLevel, Warn)\n const minLevel = minLevels.get(scope)\n ?? minLevels.get('default')\n ?? this.scopeDefaults.get(scope)\n ?? this.defaultMinLevel;\n\n const getLogger = (level: LogLevel): Log | null =>\n level >= minLevel ? this.loggerFactory(scope, level) : null;\n\n return {\n logScope: scope,\n debugLog: getLogger(LogLevel.Debug),\n infoLog: getLogger(LogLevel.Info),\n warnLog: getLogger(LogLevel.Warn),\n errorLog: getLogger(LogLevel.Error),\n };\n }\n\n public static ref(data: object | null | undefined): object | null | undefined {\n if (!data)\n return data;\n return this.logRefs.ref(data);\n }\n\n public assert(predicate?: boolean, ...data: unknown[]): void {\n if (!predicate)\n this.log(...data);\n }\n}\n\nexport interface LogScopeFns {\n logScope: string;\n debugLog: Log | null;\n infoLog: Log | null;\n warnLog: Log | null;\n errorLog: Log | null;\n}\n\n// Per-package factory: creates a typed getLogs(scope) that prepends the package\n// prefix to the scope name before delegating to Log.get. Keeps call sites\n// concise while ensuring globally unique scope keys.\n//\n// `defaults` is required (not Partial) so that every scope in TScope has an\n// explicit default level — TypeScript will refuse to compile if a scope is\n// missing. Defaults register into Log.scopeDefaults and act as the fallback\n// when no user override is set.\n//\n// All declared scopes are also pre-registered in Log.knownScopes so that\n// logLevels.dump() (in dev console) can list them even before they're first\n// touched at runtime.\nexport function createLogProvider<TScope extends string>(\n prefix: string,\n defaults: Record<TScope, LogLevel>,\n): (scope: TScope) => LogScopeFns {\n for (const [scope, level] of Object.entries(defaults) as [TScope, LogLevel][]) {\n const fullName = prefix + scope;\n Log.scopeDefaults.set(fullName, level);\n Log.knownScopes.add(fullName);\n }\n return scope => Log.get(prefix + scope);\n}\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","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","/** Externally-resolvable promise — similar to .NET's TaskCompletionSource<T>. */\r\nexport class PromiseSource<T> implements Promise<T> {\r\n readonly promise: Promise<T>;\r\n readonly [Symbol.toStringTag] = 'Promise';\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 then<TResult1 = T, TResult2 = never>(\r\n onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\r\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.promise.then(onfulfilled, onrejected);\r\n }\r\n\r\n catch<TResult = never>(\r\n onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,\r\n ): Promise<T | TResult> {\r\n return this.promise.catch(onrejected);\r\n }\r\n\r\n finally(onfinally?: (() => void) | null): Promise<T> {\r\n return this.promise.finally(onfinally);\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;\r\n }\r\n}\r\n","/** Error type rejected by {@link withTimeout} when its budget elapses. */\nexport class TimeoutError extends Error {\n override readonly name = 'TimeoutError';\n\n constructor(message = 'Operation timed out') {\n super(message);\n }\n}\n\n/**\n * Race `promise` against a `ms`-millisecond timer. Resolves with the inner\n * promise's value if it settles first; otherwise rejects with a\n * {@link TimeoutError} carrying `message`. The timer is always cleared in\n * a `finally`, so it cannot keep the event loop alive after the race ends.\n *\n * The inner promise's rejection (and the timeout's) are routed through\n * `Promise.race`, so callers should `await` the result inside a `try/catch`\n * exactly as they would for a single awaited promise. There's no\n * \"unhandled rejection\" hazard from the timeout branch — the race always\n * observes whichever promise wins, and the loser is allowed to settle\n * silently into the void.\n */\nexport async function withTimeout<T>(\n promise: PromiseLike<T>,\n ms: number,\n message?: string\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new TimeoutError(message ?? `Operation timed out after ${ms}ms`)),\n ms\n );\n });\n // Routed via `Promise.race` below; suppress the standalone unhandled-\n // rejection warning that fires when `promise` wins instead.\n timeoutPromise.catch(() => { /* noop */ });\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n","import { PromiseSource } from './promise-source.js';\nimport { TimeoutError } from './withTimeout.js';\n\n/**\n * A {@link PromiseSource} with a built-in timer that can reject (or run a\n * caller-supplied callback) after a configurable delay. The timer is\n * automatically cleared when the promise settles by other means, so callers\n * don't have to remember to `clearTimeout()` on every success path.\n *\n * Typical use:\n * ```ts\n * const ps = new PromiseSourceWithTimeout<string>();\n * ps.setTimeout(5_000); // rejects after 5s if still pending\n * ps.setTimeout(5_000, () => ps.resolve('fallback')); // or run a custom callback\n * ```\n *\n * Replaces the `PromiseSourceWithTimeout` previously kept in\n * `ActualChat/src/nodejs/src/promises.ts`. Note: the Voxt original supported a\n * \"precise\" (requestAnimationFrame-based) variant; we drop it here because no\n * caller in ActualChat uses it outside `promises.ts` itself.\n */\nexport class PromiseSourceWithTimeout<T> extends PromiseSource<T> {\n private _timer: ReturnType<typeof setTimeout> | undefined;\n\n hasTimeout(): boolean {\n return this._timer !== undefined;\n }\n\n /**\n * Install (or replace) a timeout. Pass `null` to remove without setting a\n * new one. `callback` is invoked when the timer fires — if omitted, the\n * promise is rejected with a generic \"timed out\" error.\n */\n setTimeout(ms: number | null, callback?: () => unknown): void {\n this.clearTimeout();\n if (ms === null || this.isCompleted) return;\n\n this._timer = setTimeout(() => {\n this._timer = undefined;\n if (callback) callback();\n else this.reject(new TimeoutError(`The promise has timed out after ${ms}ms.`));\n }, ms);\n }\n\n clearTimeout(): void {\n if (this._timer === undefined) return;\n clearTimeout(this._timer);\n this._timer = undefined;\n }\n\n override resolve(value: T): boolean {\n const didSettle = super.resolve(value);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n\n override reject(reason?: unknown): boolean {\n const didSettle = super.reject(reason);\n if (didSettle) this.clearTimeout();\n return didSettle;\n }\n}\n","/**\n * Pre-resolved promises for the three values most often returned as a\n * \"no-op\" successful path: `void`, `true`, `false`. Returning these\n * avoids allocating a fresh promise per call site.\n *\n * Idiomatic use:\n * ```ts\n * if (alreadyInitialized) return ResolvedPromise.Void;\n * ```\n */\nexport const ResolvedPromise = {\n Void: Promise.resolve(),\n True: Promise.resolve(true),\n False: Promise.resolve(false),\n} as const;\n","/**\n * Sentinel returned/thrown by code that distinguishes \"the operation took\n * too long\" from a generic rejection. Identity-comparable via the\n * `instance` singleton — callers can branch on `result === TimedOut.instance`.\n */\nexport class TimedOut {\n static readonly instance: TimedOut = new TimedOut();\n}\n","/** Resolves after `ms` milliseconds. */\nexport function delayAsync(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\n/** Resolves with `value` after `ms` milliseconds. */\nexport function delayAsyncWith<T>(ms: number, value: T): Promise<T> {\n return new Promise<T>(resolve => {\n setTimeout(() => resolve(value), ms);\n });\n}\n","/**\n * Adapt an `AbortSignal` to a Promise that **rejects** with the signal's\n * `reason` once the signal fires (or immediately, if it's already\n * aborted). Mirrors `signal.throwIfAborted()` semantics in Promise form:\n * the rejected value is exactly what `throwIfAborted()` would have\n * thrown — by default a `DOMException` with `name === 'AbortError'`,\n * or whatever was passed to `abortController.abort(reason)`.\n *\n * Operators racing upstream pulls / timers against cancellation plug\n * this into `Promise.race(...)` so abort propagates as a thrown error —\n * `try/finally` blocks unwind naturally; no sentinel values to thread.\n *\n * Promises are cached per signal: every call for the same signal returns\n * the SAME promise and registers AT MOST ONE listener. Operators that\n * race per-iteration (e.g. encode loops calling this once per chunk)\n * won't accumulate listeners or hit Node's `MaxListenersExceeded` warning.\n * The cache is a `WeakMap` so signals remain GC-eligible normally.\n *\n * Callers that prefer a sentinel can attach `.catch()` to convert the\n * rejection back into a value: `abortPromise(s).catch(() => 'stopped')`.\n */\nconst abortPromiseCache = new WeakMap<AbortSignal, Promise<never>>();\n\nexport function abortPromise(signal: AbortSignal): Promise<never> {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- mirroring `signal.throwIfAborted()`: the rejection value IS the signal's reason, which by Web spec is a `DOMException` by default but can be any value the caller passed to `abort(reason)`.\n if (signal.aborted) return Promise.reject(signal.reason);\n let cached = abortPromiseCache.get(signal);\n if (!cached) {\n cached = new Promise<never>((_, reject) => {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- see comment above; signal.reason is the canonical thrown value.\n signal.addEventListener('abort', () => reject(signal.reason), { once: true });\n });\n // Mark the cached rejection as observed so unhandled-rejection\n // warnings don't fire when a caller never `await`s it (e.g. an\n // operator that completed before abort and let the race promise\n // GC). The actual await-time rejection still surfaces normally.\n cached.catch(() => { /* swallow for cache-only consumers */ });\n abortPromiseCache.set(signal, cached);\n }\n return cached;\n}\n","import { LogLevel, createLogProvider } from './logging.js';\n\n/** Log scopes used inside `@actuallab/core` itself. Each is registered at\n * `core.<scope>`. Keep the list tight — most utilities should propagate\n * errors rather than log them. */\nexport type CoreLogScope =\n | 'retry'\n | 'throttle';\n\nconst scopeDefaults: Record<CoreLogScope, LogLevel> = {\n retry: LogLevel.Warn,\n throttle: LogLevel.Warn,\n};\n\nexport const getLogs = createLogProvider<CoreLogScope>('core.', scopeDefaults);\n","import { getLogs } from './internal-logging.js';\n\nconst { errorLog } = getLogs('throttle');\n\n/** A function wrapped by {@link throttle} or {@link debounce}. Calling it\n * triggers the underlying function according to the scheduling rule;\n * `reset()` discards any pending scheduled call. */\nexport interface ResettableFunc<TArgs extends unknown[]> {\n (...args: TArgs): void;\n reset(): void;\n}\n\nclass Call<TArgs extends unknown[]> {\n constructor(\n readonly func: (...args: TArgs) => unknown,\n readonly self: unknown,\n readonly parameters: TArgs\n ) { }\n\n invoke(): unknown {\n return this.func.apply(this.self, this.parameters);\n }\n\n invokeSilently(): unknown {\n try {\n return this.invoke();\n } catch (error) {\n errorLog?.log('Call.invokeSilently: unhandled error:', error);\n }\n }\n}\n\n/** Throttle modes:\n * - `default` — fire the head call immediately, then drop further calls\n * until the interval elapses; the *last* one is fired at interval end.\n * - `skip` — fire the head call immediately, drop ALL calls during the\n * interval (no tail call).\n * - `delayHead` — delay even the head call by one interval; subsequent\n * calls overwrite the pending one. */\nexport type ThrottleMode = 'default' | 'skip' | 'delayHead';\n\n/**\n * Throttle calls to `func` so that it fires at most once every `intervalMs`.\n * The returned function has a `.reset()` that discards any pending tail call\n * and re-arms the head-call behavior on the next invocation.\n */\nexport function throttle<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number,\n mode: ThrottleMode = 'default'\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n call.invokeSilently(); // Must be last\n } else {\n timeoutHandle = null;\n nextFireTime = 0;\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n const call = new Call<TArgs>(func, this, args);\n const fireDelay = nextFireTime - Date.now();\n if (timeoutHandle !== null && fireDelay <= 0) {\n // Delayed \"fire\" is ready but not yet executed — flush it now.\n fire();\n }\n\n if (timeoutHandle === null) {\n // lastCall is null here\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle = setTimeout(fire, intervalMs);\n if (mode === 'delayHead') {\n lastCall = call;\n } else {\n call.invokeSilently();\n }\n } else if (mode !== 'skip') {\n lastCall = call;\n }\n };\n wrapped.reset = reset;\n return wrapped;\n}\n\n/**\n * Debounce calls to `func`: the function fires only after `intervalMs` have\n * elapsed since the LAST call. Each new call resets the timer. `.reset()`\n * discards any pending fire without invoking `func`.\n */\nexport function debounce<TArgs extends unknown[]>(\n func: (...args: TArgs) => unknown,\n intervalMs: number\n): ResettableFunc<TArgs> {\n let lastCall: Call<TArgs> | null = null;\n let nextFireTime = 0;\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n\n const reset = (): void => {\n // Don't clearTimeout here: the live timer will see `lastCall === null`\n // and exit quietly. Avoids a churn of cleared-then-set timers when\n // callers `reset()` then immediately call again.\n timeoutHandle = null;\n lastCall = null;\n nextFireTime = 0;\n };\n\n const fire = (): void => {\n if (timeoutHandle !== null) clearTimeout(timeoutHandle);\n timeoutHandle = null;\n\n const fireDelay = nextFireTime - Date.now();\n if (fireDelay <= 0) {\n nextFireTime = 0;\n if (lastCall !== null) {\n const call = lastCall;\n lastCall = null;\n call.invokeSilently(); // Must be last\n }\n } else {\n // Another call landed; reschedule for the new deadline.\n timeoutHandle = setTimeout(fire, fireDelay);\n }\n };\n\n const wrapped: ResettableFunc<TArgs> = function (this: unknown, ...args: TArgs): void {\n lastCall = new Call<TArgs>(func, this, args);\n nextFireTime = Date.now() + intervalMs;\n timeoutHandle ??= setTimeout(fire, intervalMs);\n };\n wrapped.reset = reset;\n return wrapped;\n}\n","/**\n * Wrap an async function so concurrent invocations are serialized into a\n * single chain — each call awaits the previous one before running, and the\n * caller receives the result of *its* own invocation.\n *\n * Useful for stateful async operations (DB writes, file I/O, network I/O\n * that must not overlap) where the underlying contract is \"one at a time.\"\n *\n * If `limit` is set and the queue is already that deep, the call short-\n * circuits and returns the same promise the most recent queued call returned\n * — i.e. it coalesces excess pressure onto the trailing in-flight call.\n * Pass `null` (the default) for unbounded queueing.\n */\nexport function serialize<TArgs extends unknown[], TResult>(\n func: (...args: TArgs) => PromiseLike<TResult> | TResult,\n limit: number | null = null\n): (...args: TArgs) => Promise<TResult> {\n let lastCall: Promise<TResult> = Promise.resolve(null as TResult);\n let queueSize = 0;\n\n return function (this: unknown, ...args: TArgs): Promise<TResult> {\n if (limit !== null && queueSize >= limit) return lastCall;\n\n queueSize++;\n const prevCall = lastCall;\n // Capture `this` via the bound caller chain so we don't have to alias\n // `this` to a local (which the linter flags).\n const invoke = (): PromiseLike<TResult> | TResult => func.apply(this, args);\n return lastCall = (async () => {\n try {\n // Wait for the previous call to settle — but don't inherit its\n // rejection. The previous caller already owns that error; if we\n // re-threw here, a single failure would poison the queue\n // forever (every subsequent call awaits the previous one).\n await prevCall.catch(() => { /* see comment above */ });\n return await invoke();\n } finally {\n queueSize--;\n }\n })();\n };\n}\n","/**\n * A fixed-capacity circular buffer supporting efficient push/pull at both\n * head and tail.\n *\n * Direct port of .NET `ActualLab.Collections.RingBuffer<T>` at\n * src/ActualLab.Core/Collections/RingBuffer.cs (simplified — TS uses plain\n * modulo instead of the power-of-two-minus-one bit-mask trick, since the\n * performance difference is negligible in JavaScript).\n */\nexport class RingBuffer<T> {\n private _buffer: (T | undefined)[];\n private _start = 0;\n private _end = 0;\n private _count = 0;\n\n readonly capacity: number;\n\n get count(): number { return this._count; }\n get isEmpty(): boolean { return this._count === 0; }\n get isFull(): boolean { return this._count === this.capacity; }\n get remainingCapacity(): number { return this.capacity - this._count; }\n get hasRemainingCapacity(): boolean { return this._count < this.capacity; }\n\n constructor(capacity: number) {\n if (capacity < 1)\n throw new RangeError(`RingBuffer capacity must be >= 1 (was ${capacity}).`);\n this.capacity = capacity;\n this._buffer = new Array<T | undefined>(capacity);\n }\n\n /** Read the item at `index` (0-indexed, from head). */\n get(index: number): T {\n if (index < 0 || index >= this._count)\n throw new RangeError(`Index ${index} out of range [0, ${this._count}).`);\n return this._buffer[(this._start + index) % this.capacity] as T;\n }\n\n /** Add an item at the tail. Throws if the buffer is full. */\n pushTail(item: T): void {\n if (this._count >= this.capacity)\n throw new Error('RingBuffer is full.');\n this._buffer[this._end] = item;\n this._end = (this._end + 1) % this.capacity;\n this._count++;\n }\n\n /** Add an item at the tail, evicting the head item if the buffer is full. */\n pushTailAndMoveHeadIfFull(item: T): void {\n if (this._count >= this.capacity) {\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n }\n this.pushTail(item);\n }\n\n /** Remove the head item. Throws if the buffer is empty. */\n pullHead(): T {\n if (this._count === 0)\n throw new Error('RingBuffer is empty.');\n const head = this._buffer[this._start] as T;\n this._buffer[this._start] = undefined;\n this._start = (this._start + 1) % this.capacity;\n this._count--;\n return head;\n }\n\n /**\n * Advance the head by `skipCount` slots, releasing references to skipped\n * items so they can be garbage-collected.\n */\n moveHead(skipCount: number): void {\n if (skipCount === 0) return;\n if (skipCount < 0 || skipCount > this._count)\n throw new RangeError(`skipCount ${skipCount} out of range [0, ${this._count}].`);\n for (let k = 0; k < skipCount; k++) {\n this._buffer[(this._start + k) % this.capacity] = undefined;\n }\n this._start = (this._start + skipCount) % this.capacity;\n this._count -= skipCount;\n }\n\n /** Remove all items. */\n clear(): void {\n for (let i = 0; i < this.capacity; i++) this._buffer[i] = undefined;\n this._start = 0;\n this._end = 0;\n this._count = 0;\n }\n\n /** Copy the buffer's contents to a new array, head-first. */\n toArray(): T[] {\n const out = new Array<T>(this._count);\n for (let i = 0; i < this._count; i++) {\n out[i] = this._buffer[(this._start + i) % this.capacity] as T;\n }\n return out;\n }\n}\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","import { delayAsync } from './delay.js';\nimport { getLogs } from './internal-logging.js';\n\nconst { warnLog } = getLogs('retry');\n\n/** A sequence of retry delays — given a 1-based try index (1 = first\n * retry, i.e. AFTER the initial failure), returns the delay in ms before\n * the next attempt. For more elaborate delay schemes, see\n * {@link RetryDelaySeq.getDelay}. */\nexport type RetryDelaySchedule = (tryIndex: number) => number;\n\nconst defaultRetryDelays: RetryDelaySchedule = () => 50;\n\n/**\n * Run `fn` up to `tryCount` times, awaiting a delay between attempts.\n * The last error is rethrown if every attempt fails.\n *\n * `fn` is passed the 0-based attempt index and the last error (or\n * `undefined` for the first attempt) — useful for adapting behavior per\n * try (e.g. switching endpoints, escalating timeouts).\n */\nexport async function retry<TResult>(\n tryCount: number,\n fn: (tryIndex: number, lastError: unknown) => PromiseLike<TResult> | TResult,\n retryDelays: RetryDelaySchedule = defaultRetryDelays,\n): Promise<TResult> {\n if (tryCount <= 0)\n throw new Error('retry: tryCount must be positive.');\n\n let lastError: unknown;\n for (let tryIndex = 0; ; ) {\n if (tryIndex >= tryCount) throw lastError;\n try {\n return await fn(tryIndex, lastError);\n } catch (e) {\n lastError = e;\n }\n ++tryIndex;\n if (tryIndex >= tryCount) throw lastError;\n warnLog?.log(`retry(${tryIndex}/${tryCount}): error:`, lastError);\n await delayAsync(retryDelays(tryIndex));\n }\n}\n\n/**\n * Run `fn` and swallow any throw, returning `onError(e)` if provided or\n * `undefined` otherwise. The returned promise always settles successfully\n * — the caller never has to `try/catch` it.\n *\n * Useful where a logical \"best-effort\" return is wanted but the runtime\n * defaults — unhandled rejection warnings, exception escape past finally\n * blocks — are not.\n */\nexport async function catchErrors<TResult>(\n fn: () => PromiseLike<TResult> | TResult,\n onError?: (e: unknown) => TResult,\n): Promise<TResult | undefined> {\n try {\n return await fn();\n } catch (e) {\n return onError ? onError(e) : undefined;\n }\n}\n"],"mappings":"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","names":["LogLevel","reset"]}
|