@dynatrace/runtime-simulator
Version:
The Dynatrace JavaScript runtime simulator.
142 lines (140 loc) • 6.15 kB
TypeScript
/**
* The `timer` module exposes a global API for scheduling functions to
* be called at some future period of time. Because the timer functions are
* globals, there is no need to call `require('timers')` to use the API.
*
* The timer functions within Node.js implement a similar API as the timers API
* provided by Web Browsers but use a different internal implementation that is
* built around the Node.js [Event Loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#setimmediate-vs-settimeout).
* @see [source](https://github.com/nodejs/node/blob/v18.0.0/lib/timers.js)
*/
declare module 'timers' {
import { Abortable } from 'node:events';
import {
setTimeout as setTimeoutPromise,
setImmediate as setImmediatePromise,
setInterval as setIntervalPromise,
} from 'node:timers/promises';
interface TimerOptions extends Abortable {
/**
* Set to `false` to indicate that the scheduled `Timeout`
* should not require the Node.js event loop to remain active.
* @default true
*/
ref?: boolean | undefined;
}
let setTimeout: typeof global.setTimeout;
let clearTimeout: typeof global.clearTimeout;
let setInterval: typeof global.setInterval;
let clearInterval: typeof global.clearInterval;
let setImmediate: typeof global.setImmediate;
let clearImmediate: typeof global.clearImmediate;
global {
namespace NodeJS {
// compatibility with older typings
interface Timer extends RefCounted {
hasRef(): boolean;
refresh(): this;
[Symbol.toPrimitive](): number;
}
interface Immediate extends RefCounted {
/**
* If true, the `Immediate` object will keep the Node.js event loop active.
* @since v11.0.0
*/
hasRef(): boolean;
_onImmediate: Function; // to distinguish it from the Timeout class
}
interface Timeout extends Timer {
/**
* If true, the `Timeout` object will keep the Node.js event loop active.
* @since v11.0.0
*/
hasRef(): boolean;
/**
* Sets the timer's start time to the current time, and reschedules the timer to
* call its callback at the previously specified duration adjusted to the current
* time. This is useful for refreshing a timer without allocating a new
* JavaScript object.
*
* Using this on a timer that has already called its callback will reactivate the
* timer.
* @since v10.2.0
* @return a reference to `timeout`
*/
refresh(): this;
[Symbol.toPrimitive](): number;
}
}
// DT-specific: Returning `Timeout & number` allows assigning the result to both `Timeout` and `number`
// (same for `Timer`). This is required since both the global `setTimeout` and the function in the Node.js
// `timers` module reference the same function on `globalThis` in the typings, but actually have different return types.
// Using a separate function definition for the `timers` module that returns `Timeout` doesn't seem to be possible
// because `@types/node` references the function on `globalThis`, so any inclusion in a third-party library would
// "poison" the entire project with a type definition that has a `number` return type in the module.
//
// Removing the definition below doesn't help because the function definition in `global.d.ts` is overridden once
// Node.js typings are referenced by *any* third-party module. If this is the case, an incorrect return type
// would be used for `window.setTimeout`, which leads to an error when attempting to assign the return value to
// a variable with type `number` (although the actual return value is a number).
function setTimeout<TArgs extends any[]>(
callback: (...args: TArgs) => void,
ms?: number,
...args: TArgs
): NodeJS.Timeout & number; // DT-specific
// util.promisify no rest args compability
// tslint:disable-next-line void-return
function setTimeout(
callback: (args: void) => void,
ms?: number,
): NodeJS.Timeout & number; // DT-specific
namespace setTimeout {
const __promisify__: typeof setTimeoutPromise;
}
function clearTimeout(
timeoutId: NodeJS.Timeout | string | number | undefined,
): void;
function setInterval<TArgs extends any[]>(
callback: (...args: TArgs) => void,
ms?: number,
...args: TArgs
): NodeJS.Timer & number; // DT-specific
// util.promisify no rest args compability
// tslint:disable-next-line void-return
function setInterval(
callback: (args: void) => void,
ms?: number,
): NodeJS.Timer & number; // DT-specific
namespace setInterval {
const __promisify__: typeof setIntervalPromise;
}
function clearInterval(
intervalId: NodeJS.Timeout | string | number | undefined,
): void;
function setImmediate<TArgs extends any[]>(
callback: (...args: TArgs) => void,
...args: TArgs
): NodeJS.Immediate;
// util.promisify no rest args compability
// tslint:disable-next-line void-return
function setImmediate(callback: (args: void) => void): NodeJS.Immediate;
namespace setImmediate {
const __promisify__: typeof setImmediatePromise;
}
function clearImmediate(immediateId: NodeJS.Immediate | undefined): void;
function queueMicrotask(callback: () => void): void;
}
}
/**
* The `timer` module exposes a global API for scheduling functions to
* be called at some future period of time. Because the timer functions are
* globals, there is no need to call `require('timers')` to use the API.
*
* The timer functions within Node.js implement a similar API as the timers API
* provided by Web Browsers but use a different internal implementation that is
* built around the Node.js [Event Loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#setimmediate-vs-settimeout).
* @see [source](https://github.com/nodejs/node/blob/v18.0.0/lib/timers.js)
*/
declare module 'node:timers' {
export * from 'timers';
}