mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
mostly fix node:timers
This commit is contained in:
15
packages/bun-types/timers.d.ts
vendored
15
packages/bun-types/timers.d.ts
vendored
@@ -10,11 +10,18 @@
|
||||
*/
|
||||
|
||||
declare module "timers" {
|
||||
class Timer {
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
hasRef(): boolean;
|
||||
}
|
||||
|
||||
const _exported: {
|
||||
clearTimeout: typeof clearTimeout;
|
||||
clearInterval: typeof clearInterval;
|
||||
setTimeout: typeof setTimeout;
|
||||
setInterval: typeof setInterval;
|
||||
clearTimeout: (timer: Timer | number) => void;
|
||||
clearInterval: (timer: Timer | number) => void;
|
||||
setInterval: (cb: CallableFunction, msDelay: number, ...args: any[]) => Timer;
|
||||
setTimeout: (cb: CallableFunction, msDelay: number, ...args: any[]) => Timer;
|
||||
setImmediate: (cb: CallableFunction, ...args: any[]) => Timer;
|
||||
};
|
||||
export = _exported;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// This implementation isn't 100% correct
|
||||
// Ref/unref does not impact whether the process is kept alive
|
||||
|
||||
var clear = Symbol("clear");
|
||||
class Timeout {
|
||||
#id;
|
||||
#refCount = 1;
|
||||
@@ -17,6 +21,15 @@ class Timeout {
|
||||
return this.#refCount > 0;
|
||||
}
|
||||
|
||||
[clear]() {
|
||||
this.#refCount = 0;
|
||||
var clearFunction = this.#clearFunction;
|
||||
if (clearFunction) {
|
||||
this.#clearFunction = null;
|
||||
clearFunction(this.#id);
|
||||
}
|
||||
}
|
||||
|
||||
unref() {
|
||||
this.#refCount -= 1;
|
||||
var clearFunction = this.#clearFunction;
|
||||
@@ -26,23 +39,78 @@ class Timeout {
|
||||
}
|
||||
}
|
||||
}
|
||||
export const setInterval = globalThis.setInterval;
|
||||
export const setImmediate = globalThis.queueMicrotask;
|
||||
export const setTimeout = globalThis.setTimeout;
|
||||
export const clearInterval = globalThis.clearInterval;
|
||||
var {
|
||||
setTimeout: setTimeout_,
|
||||
setImmediate: setImmediate_,
|
||||
clearTimeout: clearTimeout_,
|
||||
setInterval: setInterval_,
|
||||
clearInterval: clearInterval_,
|
||||
} = globalThis;
|
||||
|
||||
// not implemented
|
||||
export const clearImmediate = () => {};
|
||||
export function setImmediate(callback, ...args) {
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError("callback must be a function");
|
||||
}
|
||||
var cleared = false;
|
||||
function clearImmediate(id) {
|
||||
cleared = true;
|
||||
}
|
||||
|
||||
export const clearTimeout = globalThis.clearTimeout;
|
||||
export const queueMicrotask = globalThis.queueMicrotask;
|
||||
const wrapped = function (callback, args) {
|
||||
if (cleared) {
|
||||
return;
|
||||
}
|
||||
cleared = true;
|
||||
try {
|
||||
callback(...args);
|
||||
} catch (e) {
|
||||
reportError(e);
|
||||
} finally {
|
||||
}
|
||||
};
|
||||
|
||||
return new Timeout(setImmediate_(wrapped, callback, args), clearImmediate);
|
||||
}
|
||||
|
||||
export function setTimeout(callback, delay, ...args) {
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError("callback must be a function");
|
||||
}
|
||||
|
||||
return new Timeout(setTimeout_.apply(globalThis, arguments), clearTimeout_);
|
||||
}
|
||||
|
||||
export function setInterval(callback, delay, ...args) {
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError("callback must be a function");
|
||||
}
|
||||
|
||||
return new Timeout(setInterval_.apply(globalThis, arguments), clearInterval_);
|
||||
}
|
||||
|
||||
export function clearTimeout(id) {
|
||||
if (id && typeof id === "object" && id[clear]) {
|
||||
id[clear]();
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout_(id);
|
||||
}
|
||||
|
||||
export function clearInterval(id) {
|
||||
if (id && typeof id === "object" && id[clear]) {
|
||||
id[clear]();
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval_(id);
|
||||
}
|
||||
|
||||
export default {
|
||||
setInterval,
|
||||
queueMicrotask,
|
||||
setImmediate,
|
||||
setTimeout,
|
||||
clearInterval,
|
||||
clearImmediate,
|
||||
clearTimeout,
|
||||
[Symbol.for("CommonJS")]: 0,
|
||||
};
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { test } from "bun:test";
|
||||
import { setTimeout } from "node:timers";
|
||||
import { describe, test } from "bun:test";
|
||||
import { setTimeout, clearTimeout, setInterval, setImmediate } from "node:timers";
|
||||
|
||||
// not implemented yet
|
||||
// test("unref is possible", () => {
|
||||
// const timer = setTimeout(() => {
|
||||
// throw new Error("should not be called");
|
||||
// }, 1000);
|
||||
// timer.unref();
|
||||
// clearTimeout(timer);
|
||||
// });
|
||||
for (const fn of [setTimeout, setInterval, setImmediate]) {
|
||||
describe(fn.name, () => {
|
||||
test("unref is possible", done => {
|
||||
const timer = fn(() => {
|
||||
done(new Error("should not be called"));
|
||||
}, 1);
|
||||
fn(() => {
|
||||
done();
|
||||
}, 2);
|
||||
timer.unref();
|
||||
if (fn !== setImmediate) clearTimeout(timer);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user