@orkestrel/timeout 0.0.13 → 0.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/src/core/index.cjs +5 -10
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.js +5 -10
- package/dist/src/core/index.js.map +1 -1
- package/package.json +14 -14
package/dist/src/core/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _orkestrel_contract = require("@orkestrel/contract");
|
|
3
|
-
|
|
3
|
+
// src/core/constants.ts
|
|
4
4
|
/**
|
|
5
5
|
* Names the largest timeout duration the package accepts, `2_147_483_647` milliseconds.
|
|
6
6
|
*
|
|
@@ -10,8 +10,7 @@ let _orkestrel_contract = require("@orkestrel/contract");
|
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
12
|
var MAX_TIMEOUT_MS = 2147483647;
|
|
13
|
-
|
|
14
|
-
//#region src/core/validators.ts
|
|
13
|
+
// src/core/validators.ts
|
|
15
14
|
/**
|
|
16
15
|
* Determines whether a value is an integer in the inclusive range from `0` through
|
|
17
16
|
* `MAX_TIMEOUT_MS`, staying total for every input.
|
|
@@ -52,8 +51,7 @@ function isTimeoutSignal(value) {
|
|
|
52
51
|
return (0, _orkestrel_contract.isBoolean)(Reflect.apply(getter, value, []));
|
|
53
52
|
});
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
//#region src/core/helpers.ts
|
|
54
|
+
// src/core/helpers.ts
|
|
57
55
|
/**
|
|
58
56
|
* Validates once-read timeout construction options and returns a fresh normalized copy
|
|
59
57
|
* omitting absent optional keys.
|
|
@@ -133,8 +131,7 @@ function validateTimeoutOptions(options) {
|
|
|
133
131
|
};
|
|
134
132
|
return { ms };
|
|
135
133
|
}
|
|
136
|
-
|
|
137
|
-
//#region src/core/Timeout.ts
|
|
134
|
+
// src/core/Timeout.ts
|
|
138
135
|
/**
|
|
139
136
|
* Implements `TimeoutInterface` exactly, as a controllable `setTimeout` wrapper over one
|
|
140
137
|
* owned `AbortController` whose signal aborts when the deadline expires.
|
|
@@ -215,8 +212,7 @@ var Timeout = class {
|
|
|
215
212
|
this.#parent?.removeEventListener("abort", this.#listener);
|
|
216
213
|
}
|
|
217
214
|
};
|
|
218
|
-
|
|
219
|
-
//#region src/core/factories.ts
|
|
215
|
+
// src/core/factories.ts
|
|
220
216
|
/**
|
|
221
217
|
* Creates a deadline handle from validated `TimeoutOptions` and returns it as a
|
|
222
218
|
* `TimeoutInterface`.
|
|
@@ -255,7 +251,6 @@ var Timeout = class {
|
|
|
255
251
|
function createTimeout(options) {
|
|
256
252
|
return new Timeout(options);
|
|
257
253
|
}
|
|
258
|
-
//#endregion
|
|
259
254
|
exports.MAX_TIMEOUT_MS = MAX_TIMEOUT_MS;
|
|
260
255
|
exports.Timeout = Timeout;
|
|
261
256
|
exports.createTimeout = createTimeout;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["isInteger","holds","isFunction","isBoolean","isRecord","ContractError","preview","readValue","isString"],"sources":["../../../src/core/constants.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Timeout.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Names the largest timeout duration the package accepts, `2_147_483_647` milliseconds.\n *\n * @example\n * ```ts\n * createTimeout({ ms: MAX_TIMEOUT_MS })\n * ```\n */\nexport const MAX_TIMEOUT_MS = 2_147_483_647\n","import { holds, isBoolean, isFunction, isInteger } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\n\n/**\n * Determines whether a value is an integer in the inclusive range from `0` through\n * `MAX_TIMEOUT_MS`, staying total for every input.\n *\n * @param value - Unknown duration candidate\n * @returns True if the value is an integer in the inclusive timeout range; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutDuration(0) // true\n * isTimeoutDuration(1.5) // false\n * ```\n */\nexport function isTimeoutDuration(value: unknown): value is number {\n\treturn isInteger(value) && value >= 0 && value <= MAX_TIMEOUT_MS\n}\n\n/**\n * Determines whether a value is a genuine native `AbortSignal`, staying total for a\n * structural spoof and for a hostile or revoked proxy.\n *\n * @remarks\n * The intrinsic `aborted` getter performs the native brand check, and the boundary\n * returns `false` rather than letting a receiver's error escape.\n *\n * @param value - Unknown signal candidate\n * @returns True if the native `AbortSignal` getter accepts the value; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutSignal(new AbortController().signal) // true\n * isTimeoutSignal({ aborted: false }) // false\n * ```\n */\nexport function isTimeoutSignal(value: unknown): value is AbortSignal {\n\treturn holds(() => {\n\t\tconst getter = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted')?.get\n\t\tif (!isFunction(getter)) return false\n\t\treturn isBoolean(Reflect.apply(getter, value, []))\n\t})\n}\n","import type { TimeoutOptions } from './types.js'\nimport { ContractError, isRecord, isString, preview, readValue } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\nimport { isTimeoutDuration, isTimeoutSignal } from './validators.js'\n\n/**\n * Validates once-read timeout construction options and returns a fresh normalized copy\n * omitting absent optional keys.\n *\n * @remarks\n * Each property is read before any validation runs, and no timer, controller, or\n * listener lifecycle begins at this boundary.\n *\n * @param options - Potentially untrusted timeout options\n * @returns A fresh validated `TimeoutOptions` object\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * input does not satisfy `TimeoutOptions`\n *\n * @example\n * ```ts\n * const options = validateTimeoutOptions({ ms: 5_000 })\n * ```\n */\nexport function validateTimeoutOptions(options: TimeoutOptions): TimeoutOptions {\n\tif (!isRecord(options)) {\n\t\tthrow new ContractError('Timeout: options must be a plain record', {\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t})\n\t}\n\n\tconst { id, ms, signal } = readValue(\n\t\t() => ({\n\t\t\tid: options.id,\n\t\t\tms: options.ms,\n\t\t\tsignal: options.signal,\n\t\t}),\n\t\t'Timeout',\n\t\t{\n\t\t\tsubject: 'options',\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'readable plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t},\n\t)\n\n\tif (id !== undefined && !isString(id)) {\n\t\tthrow new ContractError('Timeout: id must be a string when defined', {\n\t\t\tcode: 'literal',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'id'],\n\t\t\t\tlimit: 'string or undefined',\n\t\t\t\treceived: preview(id),\n\t\t\t},\n\t\t})\n\t}\n\tif (!isTimeoutDuration(ms)) {\n\t\tthrow new ContractError('Timeout: ms must be an integer in the supported range', {\n\t\t\tcode: 'range',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'ms'],\n\t\t\t\tlimit: `integer in [0, ${MAX_TIMEOUT_MS}]`,\n\t\t\t\treceived: preview(ms),\n\t\t\t},\n\t\t})\n\t}\n\tif (signal !== undefined && !isTimeoutSignal(signal)) {\n\t\tthrow new ContractError('Timeout: signal must be a native AbortSignal when defined', {\n\t\t\tcode: 'placement',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'signal'],\n\t\t\t\tlimit: 'native AbortSignal or undefined',\n\t\t\t\treceived: preview(signal),\n\t\t\t},\n\t\t})\n\t}\n\n\tif (id !== undefined && signal !== undefined) return { id, ms, signal }\n\tif (id !== undefined) return { id, ms }\n\tif (signal !== undefined) return { ms, signal }\n\treturn { ms }\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { validateTimeoutOptions } from './helpers.js'\n\n/**\n * Implements `TimeoutInterface` exactly, as a controllable `setTimeout` wrapper over one\n * owned `AbortController` whose signal aborts when the deadline expires.\n *\n * @remarks\n * `start()` arms or replaces the current deadline. Expiry sets `expired` and\n * aborts the current signal once. `clear()` cancels without aborting and resets\n * `expired`. Starting or clearing after expiry installs a fresh signal. A parent\n * abort deliberately clears the timeout without aborting its signal; once the\n * parent has aborted, later starts are inert.\n *\n * Construction validates the complete JavaScript boundary before creating an\n * `AbortController`. A malformed or unreadable options record throws a\n * `bound`-coded {@link import('@orkestrel/contract').ContractError}; an invalid\n * `id`, `ms`, or `signal` uses `literal`, `range`, or `placement`, respectively.\n *\n * @example\n * ```ts\n * import { Timeout } from '@orkestrel/timeout'\n *\n * const timeout = new Timeout({ ms: 5_000 })\n * timeout.start()\n * timeout.signal.addEventListener('abort', () => giveUp(), { once: true })\n * timeout.clear()\n * ```\n */\nexport class Timeout implements TimeoutInterface {\n\treadonly #id: string\n\treadonly #ms: number\n\treadonly #parent: AbortSignal | undefined\n\treadonly #listener: () => void\n\t#controller: AbortController\n\t#handle: ReturnType<typeof setTimeout> | undefined\n\n\tconstructor(options: TimeoutOptions) {\n\t\tconst input = validateTimeoutOptions(options)\n\t\tthis.#id = input.id === undefined ? crypto.randomUUID() : input.id\n\t\tthis.#ms = input.ms\n\t\tthis.#parent = input.signal\n\t\tthis.#controller = new AbortController()\n\t\tthis.#listener = this.clear.bind(this)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget ms(): number {\n\t\treturn this.#ms\n\t}\n\n\tget signal(): AbortSignal {\n\t\treturn this.#controller.signal\n\t}\n\n\tget expired(): boolean {\n\t\treturn this.#controller.signal.aborted\n\t}\n\n\tstart(): void {\n\t\tif (this.#parent?.aborted === true) return\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t\tif (this.#parent !== undefined) {\n\t\t\tthis.#parent.addEventListener('abort', this.#listener, { once: true })\n\t\t}\n\t\tthis.#handle = setTimeout(() => {\n\t\t\tthis.#handle = undefined\n\t\t\tthis.#detach()\n\t\t\tthis.#controller.abort()\n\t\t}, this.#ms)\n\t}\n\n\tclear(): void {\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t}\n\n\t#detach(): void {\n\t\tthis.#parent?.removeEventListener('abort', this.#listener)\n\t}\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { Timeout } from './Timeout.js'\n\n/**\n * Creates a deadline handle from validated `TimeoutOptions` and returns it as a\n * `TimeoutInterface`.\n *\n * @remarks\n * `options.ms` must be an integer from `0` through `2_147_483_647`, inclusive.\n * A parent `options.signal` clears an armed timeout without aborting the\n * timeout's own signal. `start()` returns without arming when the parent\n * `signal` supplied at construction has already aborted, so a handle whose\n * parent aborted never expires again and its `signal` never fires. Omitted\n * `options.id` values generate a random UUID. Malformed or unreadable options\n * use contract code `bound`; invalid `id`, `ms`, and `signal` values use\n * `literal`, `range`, and `placement`.\n *\n * @param options - Validated deadline, optional trace label, and optional native parent signal\n * @returns A reusable timeout handle\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * JavaScript input does not satisfy `TimeoutOptions`\n *\n * @example Race work against a deadline\n * ```ts\n * import { createTimeout } from '@orkestrel/timeout'\n *\n * async function fetchWithDeadline(url: string, ms: number): Promise<Response> {\n * \tconst timeout = createTimeout({ ms })\n * \ttimeout.start()\n *\n * \ttry {\n * \t\treturn await fetch(url, { signal: timeout.signal })\n * \t} finally {\n * \t\ttimeout.clear() // cancels the still-armed deadline when the fetch won the race\n * \t}\n * }\n * ```\n */\nexport function createTimeout(options: TimeoutOptions): TimeoutInterface {\n\treturn new Timeout(options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["isInteger","holds","isFunction","isBoolean","isRecord","ContractError","preview","readValue","isString"],"sources":["../../../src/core/constants.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Timeout.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Names the largest timeout duration the package accepts, `2_147_483_647` milliseconds.\n *\n * @example\n * ```ts\n * createTimeout({ ms: MAX_TIMEOUT_MS })\n * ```\n */\nexport const MAX_TIMEOUT_MS = 2_147_483_647\n","import { holds, isBoolean, isFunction, isInteger } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\n\n/**\n * Determines whether a value is an integer in the inclusive range from `0` through\n * `MAX_TIMEOUT_MS`, staying total for every input.\n *\n * @param value - Unknown duration candidate\n * @returns True if the value is an integer in the inclusive timeout range; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutDuration(0) // true\n * isTimeoutDuration(1.5) // false\n * ```\n */\nexport function isTimeoutDuration(value: unknown): value is number {\n\treturn isInteger(value) && value >= 0 && value <= MAX_TIMEOUT_MS\n}\n\n/**\n * Determines whether a value is a genuine native `AbortSignal`, staying total for a\n * structural spoof and for a hostile or revoked proxy.\n *\n * @remarks\n * The intrinsic `aborted` getter performs the native brand check, and the boundary\n * returns `false` rather than letting a receiver's error escape.\n *\n * @param value - Unknown signal candidate\n * @returns True if the native `AbortSignal` getter accepts the value; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutSignal(new AbortController().signal) // true\n * isTimeoutSignal({ aborted: false }) // false\n * ```\n */\nexport function isTimeoutSignal(value: unknown): value is AbortSignal {\n\treturn holds(() => {\n\t\tconst getter = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted')?.get\n\t\tif (!isFunction(getter)) return false\n\t\treturn isBoolean(Reflect.apply(getter, value, []))\n\t})\n}\n","import type { TimeoutOptions } from './types.js'\nimport { ContractError, isRecord, isString, preview, readValue } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\nimport { isTimeoutDuration, isTimeoutSignal } from './validators.js'\n\n/**\n * Validates once-read timeout construction options and returns a fresh normalized copy\n * omitting absent optional keys.\n *\n * @remarks\n * Each property is read before any validation runs, and no timer, controller, or\n * listener lifecycle begins at this boundary.\n *\n * @param options - Potentially untrusted timeout options\n * @returns A fresh validated `TimeoutOptions` object\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * input does not satisfy `TimeoutOptions`\n *\n * @example\n * ```ts\n * const options = validateTimeoutOptions({ ms: 5_000 })\n * ```\n */\nexport function validateTimeoutOptions(options: TimeoutOptions): TimeoutOptions {\n\tif (!isRecord(options)) {\n\t\tthrow new ContractError('Timeout: options must be a plain record', {\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t})\n\t}\n\n\tconst { id, ms, signal } = readValue(\n\t\t() => ({\n\t\t\tid: options.id,\n\t\t\tms: options.ms,\n\t\t\tsignal: options.signal,\n\t\t}),\n\t\t'Timeout',\n\t\t{\n\t\t\tsubject: 'options',\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'readable plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t},\n\t)\n\n\tif (id !== undefined && !isString(id)) {\n\t\tthrow new ContractError('Timeout: id must be a string when defined', {\n\t\t\tcode: 'literal',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'id'],\n\t\t\t\tlimit: 'string or undefined',\n\t\t\t\treceived: preview(id),\n\t\t\t},\n\t\t})\n\t}\n\tif (!isTimeoutDuration(ms)) {\n\t\tthrow new ContractError('Timeout: ms must be an integer in the supported range', {\n\t\t\tcode: 'range',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'ms'],\n\t\t\t\tlimit: `integer in [0, ${MAX_TIMEOUT_MS}]`,\n\t\t\t\treceived: preview(ms),\n\t\t\t},\n\t\t})\n\t}\n\tif (signal !== undefined && !isTimeoutSignal(signal)) {\n\t\tthrow new ContractError('Timeout: signal must be a native AbortSignal when defined', {\n\t\t\tcode: 'placement',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'signal'],\n\t\t\t\tlimit: 'native AbortSignal or undefined',\n\t\t\t\treceived: preview(signal),\n\t\t\t},\n\t\t})\n\t}\n\n\tif (id !== undefined && signal !== undefined) return { id, ms, signal }\n\tif (id !== undefined) return { id, ms }\n\tif (signal !== undefined) return { ms, signal }\n\treturn { ms }\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { validateTimeoutOptions } from './helpers.js'\n\n/**\n * Implements `TimeoutInterface` exactly, as a controllable `setTimeout` wrapper over one\n * owned `AbortController` whose signal aborts when the deadline expires.\n *\n * @remarks\n * `start()` arms or replaces the current deadline. Expiry sets `expired` and\n * aborts the current signal once. `clear()` cancels without aborting and resets\n * `expired`. Starting or clearing after expiry installs a fresh signal. A parent\n * abort deliberately clears the timeout without aborting its signal; once the\n * parent has aborted, later starts are inert.\n *\n * Construction validates the complete JavaScript boundary before creating an\n * `AbortController`. A malformed or unreadable options record throws a\n * `bound`-coded {@link import('@orkestrel/contract').ContractError}; an invalid\n * `id`, `ms`, or `signal` uses `literal`, `range`, or `placement`, respectively.\n *\n * @example\n * ```ts\n * import { Timeout } from '@orkestrel/timeout'\n *\n * const timeout = new Timeout({ ms: 5_000 })\n * timeout.start()\n * timeout.signal.addEventListener('abort', () => giveUp(), { once: true })\n * timeout.clear()\n * ```\n */\nexport class Timeout implements TimeoutInterface {\n\treadonly #id: string\n\treadonly #ms: number\n\treadonly #parent: AbortSignal | undefined\n\treadonly #listener: () => void\n\t#controller: AbortController\n\t#handle: ReturnType<typeof setTimeout> | undefined\n\n\tconstructor(options: TimeoutOptions) {\n\t\tconst input = validateTimeoutOptions(options)\n\t\tthis.#id = input.id === undefined ? crypto.randomUUID() : input.id\n\t\tthis.#ms = input.ms\n\t\tthis.#parent = input.signal\n\t\tthis.#controller = new AbortController()\n\t\tthis.#listener = this.clear.bind(this)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget ms(): number {\n\t\treturn this.#ms\n\t}\n\n\tget signal(): AbortSignal {\n\t\treturn this.#controller.signal\n\t}\n\n\tget expired(): boolean {\n\t\treturn this.#controller.signal.aborted\n\t}\n\n\tstart(): void {\n\t\tif (this.#parent?.aborted === true) return\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t\tif (this.#parent !== undefined) {\n\t\t\tthis.#parent.addEventListener('abort', this.#listener, { once: true })\n\t\t}\n\t\tthis.#handle = setTimeout(() => {\n\t\t\tthis.#handle = undefined\n\t\t\tthis.#detach()\n\t\t\tthis.#controller.abort()\n\t\t}, this.#ms)\n\t}\n\n\tclear(): void {\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t}\n\n\t#detach(): void {\n\t\tthis.#parent?.removeEventListener('abort', this.#listener)\n\t}\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { Timeout } from './Timeout.js'\n\n/**\n * Creates a deadline handle from validated `TimeoutOptions` and returns it as a\n * `TimeoutInterface`.\n *\n * @remarks\n * `options.ms` must be an integer from `0` through `2_147_483_647`, inclusive.\n * A parent `options.signal` clears an armed timeout without aborting the\n * timeout's own signal. `start()` returns without arming when the parent\n * `signal` supplied at construction has already aborted, so a handle whose\n * parent aborted never expires again and its `signal` never fires. Omitted\n * `options.id` values generate a random UUID. Malformed or unreadable options\n * use contract code `bound`; invalid `id`, `ms`, and `signal` values use\n * `literal`, `range`, and `placement`.\n *\n * @param options - Validated deadline, optional trace label, and optional native parent signal\n * @returns A reusable timeout handle\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * JavaScript input does not satisfy `TimeoutOptions`\n *\n * @example Race work against a deadline\n * ```ts\n * import { createTimeout } from '@orkestrel/timeout'\n *\n * async function fetchWithDeadline(url: string, ms: number): Promise<Response> {\n * \tconst timeout = createTimeout({ ms })\n * \ttimeout.start()\n *\n * \ttry {\n * \t\treturn await fetch(url, { signal: timeout.signal })\n * \t} finally {\n * \t\ttimeout.clear() // cancels the still-armed deadline when the fetch won the race\n * \t}\n * }\n * ```\n */\nexport function createTimeout(options: TimeoutOptions): TimeoutInterface {\n\treturn new Timeout(options)\n}\n"],"mappings":"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"}
|
package/dist/src/core/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ContractError, holds, isBoolean, isFunction, isInteger, isRecord, isString, preview, readValue } from "@orkestrel/contract";
|
|
2
|
-
|
|
2
|
+
// src/core/constants.ts
|
|
3
3
|
/**
|
|
4
4
|
* Names the largest timeout duration the package accepts, `2_147_483_647` milliseconds.
|
|
5
5
|
*
|
|
@@ -9,8 +9,7 @@ import { ContractError, holds, isBoolean, isFunction, isInteger, isRecord, isStr
|
|
|
9
9
|
* ```
|
|
10
10
|
*/
|
|
11
11
|
var MAX_TIMEOUT_MS = 2147483647;
|
|
12
|
-
|
|
13
|
-
//#region src/core/validators.ts
|
|
12
|
+
// src/core/validators.ts
|
|
14
13
|
/**
|
|
15
14
|
* Determines whether a value is an integer in the inclusive range from `0` through
|
|
16
15
|
* `MAX_TIMEOUT_MS`, staying total for every input.
|
|
@@ -51,8 +50,7 @@ function isTimeoutSignal(value) {
|
|
|
51
50
|
return isBoolean(Reflect.apply(getter, value, []));
|
|
52
51
|
});
|
|
53
52
|
}
|
|
54
|
-
|
|
55
|
-
//#region src/core/helpers.ts
|
|
53
|
+
// src/core/helpers.ts
|
|
56
54
|
/**
|
|
57
55
|
* Validates once-read timeout construction options and returns a fresh normalized copy
|
|
58
56
|
* omitting absent optional keys.
|
|
@@ -132,8 +130,7 @@ function validateTimeoutOptions(options) {
|
|
|
132
130
|
};
|
|
133
131
|
return { ms };
|
|
134
132
|
}
|
|
135
|
-
|
|
136
|
-
//#region src/core/Timeout.ts
|
|
133
|
+
// src/core/Timeout.ts
|
|
137
134
|
/**
|
|
138
135
|
* Implements `TimeoutInterface` exactly, as a controllable `setTimeout` wrapper over one
|
|
139
136
|
* owned `AbortController` whose signal aborts when the deadline expires.
|
|
@@ -214,8 +211,7 @@ var Timeout = class {
|
|
|
214
211
|
this.#parent?.removeEventListener("abort", this.#listener);
|
|
215
212
|
}
|
|
216
213
|
};
|
|
217
|
-
|
|
218
|
-
//#region src/core/factories.ts
|
|
214
|
+
// src/core/factories.ts
|
|
219
215
|
/**
|
|
220
216
|
* Creates a deadline handle from validated `TimeoutOptions` and returns it as a
|
|
221
217
|
* `TimeoutInterface`.
|
|
@@ -254,7 +250,6 @@ var Timeout = class {
|
|
|
254
250
|
function createTimeout(options) {
|
|
255
251
|
return new Timeout(options);
|
|
256
252
|
}
|
|
257
|
-
//#endregion
|
|
258
253
|
export { MAX_TIMEOUT_MS, Timeout, createTimeout, isTimeoutDuration, isTimeoutSignal, validateTimeoutOptions };
|
|
259
254
|
|
|
260
255
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Timeout.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Names the largest timeout duration the package accepts, `2_147_483_647` milliseconds.\n *\n * @example\n * ```ts\n * createTimeout({ ms: MAX_TIMEOUT_MS })\n * ```\n */\nexport const MAX_TIMEOUT_MS = 2_147_483_647\n","import { holds, isBoolean, isFunction, isInteger } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\n\n/**\n * Determines whether a value is an integer in the inclusive range from `0` through\n * `MAX_TIMEOUT_MS`, staying total for every input.\n *\n * @param value - Unknown duration candidate\n * @returns True if the value is an integer in the inclusive timeout range; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutDuration(0) // true\n * isTimeoutDuration(1.5) // false\n * ```\n */\nexport function isTimeoutDuration(value: unknown): value is number {\n\treturn isInteger(value) && value >= 0 && value <= MAX_TIMEOUT_MS\n}\n\n/**\n * Determines whether a value is a genuine native `AbortSignal`, staying total for a\n * structural spoof and for a hostile or revoked proxy.\n *\n * @remarks\n * The intrinsic `aborted` getter performs the native brand check, and the boundary\n * returns `false` rather than letting a receiver's error escape.\n *\n * @param value - Unknown signal candidate\n * @returns True if the native `AbortSignal` getter accepts the value; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutSignal(new AbortController().signal) // true\n * isTimeoutSignal({ aborted: false }) // false\n * ```\n */\nexport function isTimeoutSignal(value: unknown): value is AbortSignal {\n\treturn holds(() => {\n\t\tconst getter = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted')?.get\n\t\tif (!isFunction(getter)) return false\n\t\treturn isBoolean(Reflect.apply(getter, value, []))\n\t})\n}\n","import type { TimeoutOptions } from './types.js'\nimport { ContractError, isRecord, isString, preview, readValue } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\nimport { isTimeoutDuration, isTimeoutSignal } from './validators.js'\n\n/**\n * Validates once-read timeout construction options and returns a fresh normalized copy\n * omitting absent optional keys.\n *\n * @remarks\n * Each property is read before any validation runs, and no timer, controller, or\n * listener lifecycle begins at this boundary.\n *\n * @param options - Potentially untrusted timeout options\n * @returns A fresh validated `TimeoutOptions` object\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * input does not satisfy `TimeoutOptions`\n *\n * @example\n * ```ts\n * const options = validateTimeoutOptions({ ms: 5_000 })\n * ```\n */\nexport function validateTimeoutOptions(options: TimeoutOptions): TimeoutOptions {\n\tif (!isRecord(options)) {\n\t\tthrow new ContractError('Timeout: options must be a plain record', {\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t})\n\t}\n\n\tconst { id, ms, signal } = readValue(\n\t\t() => ({\n\t\t\tid: options.id,\n\t\t\tms: options.ms,\n\t\t\tsignal: options.signal,\n\t\t}),\n\t\t'Timeout',\n\t\t{\n\t\t\tsubject: 'options',\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'readable plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t},\n\t)\n\n\tif (id !== undefined && !isString(id)) {\n\t\tthrow new ContractError('Timeout: id must be a string when defined', {\n\t\t\tcode: 'literal',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'id'],\n\t\t\t\tlimit: 'string or undefined',\n\t\t\t\treceived: preview(id),\n\t\t\t},\n\t\t})\n\t}\n\tif (!isTimeoutDuration(ms)) {\n\t\tthrow new ContractError('Timeout: ms must be an integer in the supported range', {\n\t\t\tcode: 'range',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'ms'],\n\t\t\t\tlimit: `integer in [0, ${MAX_TIMEOUT_MS}]`,\n\t\t\t\treceived: preview(ms),\n\t\t\t},\n\t\t})\n\t}\n\tif (signal !== undefined && !isTimeoutSignal(signal)) {\n\t\tthrow new ContractError('Timeout: signal must be a native AbortSignal when defined', {\n\t\t\tcode: 'placement',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'signal'],\n\t\t\t\tlimit: 'native AbortSignal or undefined',\n\t\t\t\treceived: preview(signal),\n\t\t\t},\n\t\t})\n\t}\n\n\tif (id !== undefined && signal !== undefined) return { id, ms, signal }\n\tif (id !== undefined) return { id, ms }\n\tif (signal !== undefined) return { ms, signal }\n\treturn { ms }\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { validateTimeoutOptions } from './helpers.js'\n\n/**\n * Implements `TimeoutInterface` exactly, as a controllable `setTimeout` wrapper over one\n * owned `AbortController` whose signal aborts when the deadline expires.\n *\n * @remarks\n * `start()` arms or replaces the current deadline. Expiry sets `expired` and\n * aborts the current signal once. `clear()` cancels without aborting and resets\n * `expired`. Starting or clearing after expiry installs a fresh signal. A parent\n * abort deliberately clears the timeout without aborting its signal; once the\n * parent has aborted, later starts are inert.\n *\n * Construction validates the complete JavaScript boundary before creating an\n * `AbortController`. A malformed or unreadable options record throws a\n * `bound`-coded {@link import('@orkestrel/contract').ContractError}; an invalid\n * `id`, `ms`, or `signal` uses `literal`, `range`, or `placement`, respectively.\n *\n * @example\n * ```ts\n * import { Timeout } from '@orkestrel/timeout'\n *\n * const timeout = new Timeout({ ms: 5_000 })\n * timeout.start()\n * timeout.signal.addEventListener('abort', () => giveUp(), { once: true })\n * timeout.clear()\n * ```\n */\nexport class Timeout implements TimeoutInterface {\n\treadonly #id: string\n\treadonly #ms: number\n\treadonly #parent: AbortSignal | undefined\n\treadonly #listener: () => void\n\t#controller: AbortController\n\t#handle: ReturnType<typeof setTimeout> | undefined\n\n\tconstructor(options: TimeoutOptions) {\n\t\tconst input = validateTimeoutOptions(options)\n\t\tthis.#id = input.id === undefined ? crypto.randomUUID() : input.id\n\t\tthis.#ms = input.ms\n\t\tthis.#parent = input.signal\n\t\tthis.#controller = new AbortController()\n\t\tthis.#listener = this.clear.bind(this)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget ms(): number {\n\t\treturn this.#ms\n\t}\n\n\tget signal(): AbortSignal {\n\t\treturn this.#controller.signal\n\t}\n\n\tget expired(): boolean {\n\t\treturn this.#controller.signal.aborted\n\t}\n\n\tstart(): void {\n\t\tif (this.#parent?.aborted === true) return\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t\tif (this.#parent !== undefined) {\n\t\t\tthis.#parent.addEventListener('abort', this.#listener, { once: true })\n\t\t}\n\t\tthis.#handle = setTimeout(() => {\n\t\t\tthis.#handle = undefined\n\t\t\tthis.#detach()\n\t\t\tthis.#controller.abort()\n\t\t}, this.#ms)\n\t}\n\n\tclear(): void {\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t}\n\n\t#detach(): void {\n\t\tthis.#parent?.removeEventListener('abort', this.#listener)\n\t}\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { Timeout } from './Timeout.js'\n\n/**\n * Creates a deadline handle from validated `TimeoutOptions` and returns it as a\n * `TimeoutInterface`.\n *\n * @remarks\n * `options.ms` must be an integer from `0` through `2_147_483_647`, inclusive.\n * A parent `options.signal` clears an armed timeout without aborting the\n * timeout's own signal. `start()` returns without arming when the parent\n * `signal` supplied at construction has already aborted, so a handle whose\n * parent aborted never expires again and its `signal` never fires. Omitted\n * `options.id` values generate a random UUID. Malformed or unreadable options\n * use contract code `bound`; invalid `id`, `ms`, and `signal` values use\n * `literal`, `range`, and `placement`.\n *\n * @param options - Validated deadline, optional trace label, and optional native parent signal\n * @returns A reusable timeout handle\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * JavaScript input does not satisfy `TimeoutOptions`\n *\n * @example Race work against a deadline\n * ```ts\n * import { createTimeout } from '@orkestrel/timeout'\n *\n * async function fetchWithDeadline(url: string, ms: number): Promise<Response> {\n * \tconst timeout = createTimeout({ ms })\n * \ttimeout.start()\n *\n * \ttry {\n * \t\treturn await fetch(url, { signal: timeout.signal })\n * \t} finally {\n * \t\ttimeout.clear() // cancels the still-armed deadline when the fetch won the race\n * \t}\n * }\n * ```\n */\nexport function createTimeout(options: TimeoutOptions): TimeoutInterface {\n\treturn new Timeout(options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Timeout.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Names the largest timeout duration the package accepts, `2_147_483_647` milliseconds.\n *\n * @example\n * ```ts\n * createTimeout({ ms: MAX_TIMEOUT_MS })\n * ```\n */\nexport const MAX_TIMEOUT_MS = 2_147_483_647\n","import { holds, isBoolean, isFunction, isInteger } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\n\n/**\n * Determines whether a value is an integer in the inclusive range from `0` through\n * `MAX_TIMEOUT_MS`, staying total for every input.\n *\n * @param value - Unknown duration candidate\n * @returns True if the value is an integer in the inclusive timeout range; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutDuration(0) // true\n * isTimeoutDuration(1.5) // false\n * ```\n */\nexport function isTimeoutDuration(value: unknown): value is number {\n\treturn isInteger(value) && value >= 0 && value <= MAX_TIMEOUT_MS\n}\n\n/**\n * Determines whether a value is a genuine native `AbortSignal`, staying total for a\n * structural spoof and for a hostile or revoked proxy.\n *\n * @remarks\n * The intrinsic `aborted` getter performs the native brand check, and the boundary\n * returns `false` rather than letting a receiver's error escape.\n *\n * @param value - Unknown signal candidate\n * @returns True if the native `AbortSignal` getter accepts the value; false otherwise\n *\n * @example\n * ```ts\n * isTimeoutSignal(new AbortController().signal) // true\n * isTimeoutSignal({ aborted: false }) // false\n * ```\n */\nexport function isTimeoutSignal(value: unknown): value is AbortSignal {\n\treturn holds(() => {\n\t\tconst getter = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted')?.get\n\t\tif (!isFunction(getter)) return false\n\t\treturn isBoolean(Reflect.apply(getter, value, []))\n\t})\n}\n","import type { TimeoutOptions } from './types.js'\nimport { ContractError, isRecord, isString, preview, readValue } from '@orkestrel/contract'\nimport { MAX_TIMEOUT_MS } from './constants.js'\nimport { isTimeoutDuration, isTimeoutSignal } from './validators.js'\n\n/**\n * Validates once-read timeout construction options and returns a fresh normalized copy\n * omitting absent optional keys.\n *\n * @remarks\n * Each property is read before any validation runs, and no timer, controller, or\n * listener lifecycle begins at this boundary.\n *\n * @param options - Potentially untrusted timeout options\n * @returns A fresh validated `TimeoutOptions` object\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * input does not satisfy `TimeoutOptions`\n *\n * @example\n * ```ts\n * const options = validateTimeoutOptions({ ms: 5_000 })\n * ```\n */\nexport function validateTimeoutOptions(options: TimeoutOptions): TimeoutOptions {\n\tif (!isRecord(options)) {\n\t\tthrow new ContractError('Timeout: options must be a plain record', {\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t})\n\t}\n\n\tconst { id, ms, signal } = readValue(\n\t\t() => ({\n\t\t\tid: options.id,\n\t\t\tms: options.ms,\n\t\t\tsignal: options.signal,\n\t\t}),\n\t\t'Timeout',\n\t\t{\n\t\t\tsubject: 'options',\n\t\t\tcode: 'bound',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options'],\n\t\t\t\tlimit: 'readable plain record',\n\t\t\t\treceived: preview(options),\n\t\t\t},\n\t\t},\n\t)\n\n\tif (id !== undefined && !isString(id)) {\n\t\tthrow new ContractError('Timeout: id must be a string when defined', {\n\t\t\tcode: 'literal',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'id'],\n\t\t\t\tlimit: 'string or undefined',\n\t\t\t\treceived: preview(id),\n\t\t\t},\n\t\t})\n\t}\n\tif (!isTimeoutDuration(ms)) {\n\t\tthrow new ContractError('Timeout: ms must be an integer in the supported range', {\n\t\t\tcode: 'range',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'ms'],\n\t\t\t\tlimit: `integer in [0, ${MAX_TIMEOUT_MS}]`,\n\t\t\t\treceived: preview(ms),\n\t\t\t},\n\t\t})\n\t}\n\tif (signal !== undefined && !isTimeoutSignal(signal)) {\n\t\tthrow new ContractError('Timeout: signal must be a native AbortSignal when defined', {\n\t\t\tcode: 'placement',\n\t\t\tcontext: {\n\t\t\t\tpath: ['options', 'signal'],\n\t\t\t\tlimit: 'native AbortSignal or undefined',\n\t\t\t\treceived: preview(signal),\n\t\t\t},\n\t\t})\n\t}\n\n\tif (id !== undefined && signal !== undefined) return { id, ms, signal }\n\tif (id !== undefined) return { id, ms }\n\tif (signal !== undefined) return { ms, signal }\n\treturn { ms }\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { validateTimeoutOptions } from './helpers.js'\n\n/**\n * Implements `TimeoutInterface` exactly, as a controllable `setTimeout` wrapper over one\n * owned `AbortController` whose signal aborts when the deadline expires.\n *\n * @remarks\n * `start()` arms or replaces the current deadline. Expiry sets `expired` and\n * aborts the current signal once. `clear()` cancels without aborting and resets\n * `expired`. Starting or clearing after expiry installs a fresh signal. A parent\n * abort deliberately clears the timeout without aborting its signal; once the\n * parent has aborted, later starts are inert.\n *\n * Construction validates the complete JavaScript boundary before creating an\n * `AbortController`. A malformed or unreadable options record throws a\n * `bound`-coded {@link import('@orkestrel/contract').ContractError}; an invalid\n * `id`, `ms`, or `signal` uses `literal`, `range`, or `placement`, respectively.\n *\n * @example\n * ```ts\n * import { Timeout } from '@orkestrel/timeout'\n *\n * const timeout = new Timeout({ ms: 5_000 })\n * timeout.start()\n * timeout.signal.addEventListener('abort', () => giveUp(), { once: true })\n * timeout.clear()\n * ```\n */\nexport class Timeout implements TimeoutInterface {\n\treadonly #id: string\n\treadonly #ms: number\n\treadonly #parent: AbortSignal | undefined\n\treadonly #listener: () => void\n\t#controller: AbortController\n\t#handle: ReturnType<typeof setTimeout> | undefined\n\n\tconstructor(options: TimeoutOptions) {\n\t\tconst input = validateTimeoutOptions(options)\n\t\tthis.#id = input.id === undefined ? crypto.randomUUID() : input.id\n\t\tthis.#ms = input.ms\n\t\tthis.#parent = input.signal\n\t\tthis.#controller = new AbortController()\n\t\tthis.#listener = this.clear.bind(this)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget ms(): number {\n\t\treturn this.#ms\n\t}\n\n\tget signal(): AbortSignal {\n\t\treturn this.#controller.signal\n\t}\n\n\tget expired(): boolean {\n\t\treturn this.#controller.signal.aborted\n\t}\n\n\tstart(): void {\n\t\tif (this.#parent?.aborted === true) return\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t\tif (this.#parent !== undefined) {\n\t\t\tthis.#parent.addEventListener('abort', this.#listener, { once: true })\n\t\t}\n\t\tthis.#handle = setTimeout(() => {\n\t\t\tthis.#handle = undefined\n\t\t\tthis.#detach()\n\t\t\tthis.#controller.abort()\n\t\t}, this.#ms)\n\t}\n\n\tclear(): void {\n\t\tif (this.#handle !== undefined) {\n\t\t\tclearTimeout(this.#handle)\n\t\t\tthis.#handle = undefined\n\t\t}\n\t\tthis.#detach()\n\t\tif (this.#controller.signal.aborted) this.#controller = new AbortController()\n\t}\n\n\t#detach(): void {\n\t\tthis.#parent?.removeEventListener('abort', this.#listener)\n\t}\n}\n","import type { TimeoutInterface, TimeoutOptions } from './types.js'\nimport { Timeout } from './Timeout.js'\n\n/**\n * Creates a deadline handle from validated `TimeoutOptions` and returns it as a\n * `TimeoutInterface`.\n *\n * @remarks\n * `options.ms` must be an integer from `0` through `2_147_483_647`, inclusive.\n * A parent `options.signal` clears an armed timeout without aborting the\n * timeout's own signal. `start()` returns without arming when the parent\n * `signal` supplied at construction has already aborted, so a handle whose\n * parent aborted never expires again and its `signal` never fires. Omitted\n * `options.id` values generate a random UUID. Malformed or unreadable options\n * use contract code `bound`; invalid `id`, `ms`, and `signal` values use\n * `literal`, `range`, and `placement`.\n *\n * @param options - Validated deadline, optional trace label, and optional native parent signal\n * @returns A reusable timeout handle\n * @throws {@link import('@orkestrel/contract').ContractError} Thrown when the\n * JavaScript input does not satisfy `TimeoutOptions`\n *\n * @example Race work against a deadline\n * ```ts\n * import { createTimeout } from '@orkestrel/timeout'\n *\n * async function fetchWithDeadline(url: string, ms: number): Promise<Response> {\n * \tconst timeout = createTimeout({ ms })\n * \ttimeout.start()\n *\n * \ttry {\n * \t\treturn await fetch(url, { signal: timeout.signal })\n * \t} finally {\n * \t\ttimeout.clear() // cancels the still-armed deadline when the fetch won the race\n * \t}\n * }\n * ```\n */\nexport function createTimeout(options: TimeoutOptions): TimeoutInterface {\n\treturn new Timeout(options)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkestrel/timeout",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "A typed, controllable setTimeout wrapper — an AbortSignal deadline with start/clear lifecycle and parent-signal linking. Part of the @orkestrel line.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"abort-signal",
|
|
@@ -65,25 +65,25 @@
|
|
|
65
65
|
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release",
|
|
66
66
|
"test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
|
|
67
67
|
"test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
|
|
68
|
-
"test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
|
|
68
|
+
"test:bench": "vitest bench --config vite.config.ts --no-cache --project \"probe (bench)\" --mode benchmark",
|
|
69
69
|
"prepack": "npm run build",
|
|
70
70
|
"test:setup": "vitest run --config vite.config.ts --no-cache --reporter=dot --project setup"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@orkestrel/contract": "^0.0.
|
|
73
|
+
"@orkestrel/contract": "^0.0.21"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@microsoft/api-extractor": "^7.
|
|
77
|
-
"@orkestrel/guide": "^0.0.
|
|
78
|
-
"@orkestrel/probe": "^0.0.
|
|
79
|
-
"@orkestrel/scaffold": "^0.0.
|
|
80
|
-
"@orkestrel/test": "^0.0.
|
|
81
|
-
"@types/node": "^26.6.
|
|
82
|
-
"oxfmt": "^0.
|
|
83
|
-
"oxlint": "^1.
|
|
84
|
-
"typescript": "^
|
|
85
|
-
"vite": "^8.3.
|
|
86
|
-
"vitest": "^
|
|
76
|
+
"@microsoft/api-extractor": "^7.60.1",
|
|
77
|
+
"@orkestrel/guide": "^0.0.28",
|
|
78
|
+
"@orkestrel/probe": "^0.0.26",
|
|
79
|
+
"@orkestrel/scaffold": "^0.0.119",
|
|
80
|
+
"@orkestrel/test": "^0.0.31",
|
|
81
|
+
"@types/node": "^26.6.6",
|
|
82
|
+
"oxfmt": "^0.75.0",
|
|
83
|
+
"oxlint": "^1.90.0",
|
|
84
|
+
"typescript": "^7.0.2",
|
|
85
|
+
"vite": "^8.3.5",
|
|
86
|
+
"vitest": "^5.0.5"
|
|
87
87
|
},
|
|
88
88
|
"engines": {
|
|
89
89
|
"node": ">=22.12.0"
|