diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2023-02-14 17:38:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-14 17:38:45 +0100 |
commit | d47147fb6ad229b1c039aff9d0959b6e281f4df5 (patch) | |
tree | 6e9e790f2b9bc71b5f0c9c7e64b95cae31579d58 /ext/node/polyfills/internal/timers.mjs | |
parent | 1d00bbe47e2ca14e2d2151518e02b2324461a065 (diff) |
feat(ext/node): embed std/node into the snapshot (#17724)
This commit moves "deno_std/node" in "ext/node" crate. The code is
transpiled and snapshotted during the build process.
During the first pass a minimal amount of work was done to create the
snapshot, a lot of code in "ext/node" depends on presence of "Deno"
global. This code will be gradually fixed in the follow up PRs to migrate
it to import relevant APIs from "internal:" modules.
Currently the code from snapshot is not used in any way, and all
Node/npm compatibility still uses code from
"https://deno.land/std/node" (or from the location specified by
"DENO_NODE_COMPAT_URL"). This will also be handled in a follow
up PRs.
---------
Co-authored-by: crowlkats <crowlkats@toaxl.com>
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
Diffstat (limited to 'ext/node/polyfills/internal/timers.mjs')
-rw-r--r-- | ext/node/polyfills/internal/timers.mjs | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/ext/node/polyfills/internal/timers.mjs b/ext/node/polyfills/internal/timers.mjs new file mode 100644 index 000000000..648fb1bc1 --- /dev/null +++ b/ext/node/polyfills/internal/timers.mjs @@ -0,0 +1,125 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +// Copyright Joyent and Node contributors. All rights reserved. MIT license. + +import { inspect } from "internal:deno_node/polyfills/internal/util/inspect.mjs"; +import { validateFunction, validateNumber } from "internal:deno_node/polyfills/internal/validators.mjs"; +import { ERR_OUT_OF_RANGE } from "internal:deno_node/polyfills/internal/errors.ts"; +import { emitWarning } from "internal:deno_node/polyfills/process.ts"; + +const setTimeout_ = globalThis.setTimeout; +const clearTimeout_ = globalThis.clearTimeout; +const setInterval_ = globalThis.setInterval; + +// Timeout values > TIMEOUT_MAX are set to 1. +export const TIMEOUT_MAX = 2 ** 31 - 1; + +export const kTimerId = Symbol("timerId"); +export const kTimeout = Symbol("timeout"); +const kRefed = Symbol("refed"); +const createTimer = Symbol("createTimer"); + +// Timer constructor function. +export function Timeout(callback, after, args, isRepeat, isRefed) { + if (typeof after === "number" && after > TIMEOUT_MAX) { + after = 1; + } + this._idleTimeout = after; + this._onTimeout = callback; + this._timerArgs = args; + this._isRepeat = isRepeat; + this[kRefed] = isRefed; + this[kTimerId] = this[createTimer](); +} + +Timeout.prototype[createTimer] = function () { + const callback = this._onTimeout; + const cb = (...args) => callback.bind(this)(...args); + const id = this._isRepeat + ? setInterval_(cb, this._idleTimeout, ...this._timerArgs) + : setTimeout_(cb, this._idleTimeout, ...this._timerArgs); + if (!this[kRefed]) { + Deno.unrefTimer(id); + } + return id; +}; + +// Make sure the linked list only shows the minimal necessary information. +Timeout.prototype[inspect.custom] = function (_, options) { + return inspect(this, { + ...options, + // Only inspect one level. + depth: 0, + // It should not recurse. + customInspect: false, + }); +}; + +Timeout.prototype.refresh = function () { + clearTimeout_(this[kTimerId]); + this[kTimerId] = this[createTimer](); + return this; +}; + +Timeout.prototype.unref = function () { + if (this[kRefed]) { + this[kRefed] = false; + Deno.unrefTimer(this[kTimerId]); + } + return this; +}; + +Timeout.prototype.ref = function () { + if (!this[kRefed]) { + this[kRefed] = true; + Deno.refTimer(this[kTimerId]); + } + return this; +}; + +Timeout.prototype.hasRef = function () { + return this[kRefed]; +}; + +Timeout.prototype[Symbol.toPrimitive] = function () { + return this[kTimerId]; +}; + +/** + * @param {number} msecs + * @param {string} name + * @returns + */ +export function getTimerDuration(msecs, name) { + validateNumber(msecs, name); + + if (msecs < 0 || !Number.isFinite(msecs)) { + throw new ERR_OUT_OF_RANGE(name, "a non-negative finite number", msecs); + } + + // Ensure that msecs fits into signed int32 + if (msecs > TIMEOUT_MAX) { + emitWarning( + `${msecs} does not fit into a 32-bit signed integer.` + + `\nTimer duration was truncated to ${TIMEOUT_MAX}.`, + "TimeoutOverflowWarning", + ); + + return TIMEOUT_MAX; + } + + return msecs; +} + +export function setUnrefTimeout(callback, timeout, ...args) { + validateFunction(callback, "callback"); + return new Timeout(callback, timeout, args, false, false); +} + +export default { + getTimerDuration, + kTimerId, + kTimeout, + setUnrefTimeout, + Timeout, + TIMEOUT_MAX, +}; |