diff --git a/ext/node/polyfills/internal/timers.mjs b/ext/node/polyfills/internal/timers.mjs index 92fb51d5747d9b..bdaf95d9179261 100644 --- a/ext/node/polyfills/internal/timers.mjs +++ b/ext/node/polyfills/internal/timers.mjs @@ -20,6 +20,7 @@ import { ERR_OUT_OF_RANGE } from "ext:deno_node/internal/errors.ts"; import { emitWarning } from "node:process"; import { clearTimeout as clearTimeout_, + setImmediate as setImmediate_, setInterval as setInterval_, setTimeout as setTimeout_, } from "ext:deno_web/02_timers.js"; @@ -115,6 +116,35 @@ Timeout.prototype[Symbol.toPrimitive] = function () { return this[kTimerId]; }; +// Immediate constructor function. +export function Immediate(callback, args) { + this._immediateId = setImmediate_(callback, args); +} + +// Make sure the linked list only shows the minimal necessary information. +Immediate.prototype[inspect.custom] = function (_, options) { + return inspect(this, { + ...options, + // Only inspect one level. + depth: 0, + // It should not recurse. + customInspect: false, + }); +}; + +// FIXME(nathanwhit): actually implement {ref,unref,hasRef} once deno_core supports it +Immediate.prototype.unref = function () { + return this; +}; + +Immediate.prototype.ref = function () { + return this; +}; + +Immediate.prototype.hasRef = function () { + return true; +}; + /** * @param {number} msecs * @param {string} name diff --git a/ext/node/polyfills/timers.ts b/ext/node/polyfills/timers.ts index 9a7d59ab204444..033afd9526f7ab 100644 --- a/ext/node/polyfills/timers.ts +++ b/ext/node/polyfills/timers.ts @@ -11,6 +11,7 @@ const { import { activeTimers, + Immediate, setUnrefTimeout, Timeout, } from "ext:deno_node/internal/timers.mjs"; @@ -21,7 +22,6 @@ import * as timers from "ext:deno_web/02_timers.js"; const clearTimeout_ = timers.clearTimeout; const clearInterval_ = timers.clearInterval; -const setImmediate_ = timers.setImmediate; export function setTimeout( callback: (...args: unknown[]) => void, @@ -70,15 +70,21 @@ export function clearInterval(timeout?: Timeout | number | string) { } clearInterval_(id); } -// TODO(bartlomieju): implement the 'NodeJS.Immediate' versions of the timers. -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/1163ead296d84e7a3c80d71e7c81ecbd1a130e9a/types/node/v12/globals.d.ts#L1120-L1131 export function setImmediate( cb: (...args: unknown[]) => void, ...args: unknown[] ): Timeout { - return setImmediate_(cb, ...args); + return new Immediate(cb, ...args); +} +export function clearImmediate(immediate: Immediate) { + if (immediate == null) { + return; + } + + // FIXME(nathanwhit): will probably change once + // deno_core has proper support for immediates + clearTimeout_(immediate._immediateId); } -export const clearImmediate = clearTimeout; export default { setTimeout, diff --git a/tests/unit_node/timers_test.ts b/tests/unit_node/timers_test.ts index 9ce015d23ee217..c0b49c998c8582 100644 --- a/tests/unit_node/timers_test.ts +++ b/tests/unit_node/timers_test.ts @@ -33,13 +33,13 @@ Deno.test("[node/timers setInterval]", () => { Deno.test("[node/timers setImmediate]", () => { { const { clearImmediate, setImmediate } = timers; - const id = setImmediate(() => {}); - clearImmediate(id); + const imm = setImmediate(() => {}); + clearImmediate(imm); } { - const id = timers.setImmediate(() => {}); - timers.clearImmediate(id); + const imm = timers.setImmediate(() => {}); + timers.clearImmediate(imm); } }); @@ -60,3 +60,13 @@ Deno.test("[node/timers refresh cancelled timer]", () => { clearTimeout(p); p.refresh(); }); + +Deno.test("[node/timers setImmediate returns Immediate object]", () => { + const { clearImmediate, setImmediate } = timers; + + const imm = setImmediate(() => {}); + imm.unref(); + imm.ref(); + imm.hasRef(); + clearImmediate(imm); +});