@gjsify/utils 0.3.13 → 0.3.14

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.
@@ -1,135 +1,116 @@
1
+ //#region src/gio-errors.ts
2
+ /** Map from Gio.IOErrorEnum numeric values to Node.js error code strings. */
1
3
  const GIO_ERROR_TO_NODE = {
2
- 0: "EIO",
3
- // FAILED
4
- 1: "ENOENT",
5
- // NOT_FOUND
6
- 2: "EEXIST",
7
- // EXISTS
8
- 3: "EISDIR",
9
- // IS_DIRECTORY
10
- 4: "ENOTDIR",
11
- // NOT_DIRECTORY
12
- 5: "ENOTEMPTY",
13
- // NOT_EMPTY
14
- 6: "ENOENT",
15
- // NOT_REGULAR_FILE
16
- 7: "ENFILE",
17
- // TOO_MANY_OPEN_FILES
18
- 9: "EACCES",
19
- // NOT_MOUNTABLE_FILE
20
- 10: "ENFILE",
21
- // FILENAME_TOO_LONG
22
- 11: "EINVAL",
23
- // INVALID_FILENAME
24
- 12: "ELOOP",
25
- // TOO_MANY_LINKS
26
- 13: "ENOSPC",
27
- // NO_SPACE
28
- 14: "EACCES",
29
- // PERMISSION_DENIED
30
- 17: "ELOOP",
31
- // TOO_MANY_LINKS (duplicate guard)
32
- 19: "ENOSPC",
33
- // NO_SPACE (duplicate guard)
34
- 20: "ENOTSUP",
35
- // NOT_SUPPORTED
36
- 22: "EMFILE",
37
- // TOO_MANY_OPEN_FILES
38
- 24: "EROFS",
39
- // READ_ONLY
40
- 25: "ECANCELED",
41
- // CANCELLED
42
- 26: "EBUSY",
43
- // BUSY
44
- 27: "ETIMEDOUT",
45
- // TIMED_OUT
46
- 28: "EHOSTUNREACH",
47
- // HOST_NOT_FOUND (was WOULD_BLOCK)
48
- 30: "EHOSTUNREACH",
49
- // HOST_NOT_FOUND
50
- 31: "ENETUNREACH",
51
- // NETWORK_UNREACHABLE
52
- 32: "ECONNREFUSED",
53
- // CONNECTION_REFUSED (legacy value)
54
- 33: "EADDRINUSE",
55
- // ADDRESS_IN_USE
56
- 34: "ECONNRESET",
57
- // CONNECTION_CLOSED (mapped to reset)
58
- 36: "EPIPE",
59
- // BROKEN_PIPE
60
- 38: "ENETUNREACH",
61
- // NETWORK_UNREACHABLE (actual GJS value)
62
- 39: "ECONNREFUSED",
63
- // CONNECTION_REFUSED (actual GJS value)
64
- 40: "ECONNREFUSED",
65
- // PROXY_FAILED
66
- 41: "EACCES",
67
- // PROXY_AUTH_FAILED
68
- 44: "ECONNRESET",
69
- // CONNECTION_CLOSED (actual GJS value)
70
- 46: "EMSGSIZE"
71
- // MESSAGE_TOO_LARGE
4
+ 0: "EIO",
5
+ 1: "ENOENT",
6
+ 2: "EEXIST",
7
+ 3: "EISDIR",
8
+ 4: "ENOTDIR",
9
+ 5: "ENOTEMPTY",
10
+ 6: "ENOENT",
11
+ 7: "ENFILE",
12
+ 9: "EACCES",
13
+ 10: "ENFILE",
14
+ 11: "EINVAL",
15
+ 12: "ELOOP",
16
+ 13: "ENOSPC",
17
+ 14: "EACCES",
18
+ 17: "ELOOP",
19
+ 19: "ENOSPC",
20
+ 20: "ENOTSUP",
21
+ 22: "EMFILE",
22
+ 24: "EROFS",
23
+ 25: "ECANCELED",
24
+ 26: "EBUSY",
25
+ 27: "ETIMEDOUT",
26
+ 28: "EHOSTUNREACH",
27
+ 30: "EHOSTUNREACH",
28
+ 31: "ENETUNREACH",
29
+ 32: "ECONNREFUSED",
30
+ 33: "EADDRINUSE",
31
+ 34: "ECONNRESET",
32
+ 36: "EPIPE",
33
+ 38: "ENETUNREACH",
34
+ 39: "ECONNREFUSED",
35
+ 40: "ECONNREFUSED",
36
+ 41: "EACCES",
37
+ 44: "ECONNRESET",
38
+ 46: "EMSGSIZE"
72
39
  };
40
+ /**
41
+ * Create a Node.js-style ErrnoException from a Gio error.
42
+ * Works for fs, net, dns, child-process, and other modules.
43
+ */
73
44
  function createNodeError(err, syscall, details) {
74
- const errObj = err;
75
- const code = GIO_ERROR_TO_NODE[errObj?.code ?? -1] || "EIO";
76
- let msg = `${code}: ${errObj?.message || "unknown error"}, ${syscall}`;
77
- if (details?.path) msg += ` '${details.path}'`;
78
- if (details?.dest) msg += ` -> '${details.dest}'`;
79
- if (details?.address) msg += ` ${details.address}`;
80
- if (details?.port != null) msg += `:${details.port}`;
81
- const error = new Error(msg);
82
- error.code = code;
83
- error.syscall = syscall;
84
- error.errno = -(errObj?.code || 0);
85
- if (details?.path) error.path = details.path;
86
- if (details?.address) error.address = details.address;
87
- if (details?.port != null) error.port = details.port;
88
- return error;
45
+ const errObj = err;
46
+ const code = GIO_ERROR_TO_NODE[errObj?.code ?? -1] || "EIO";
47
+ let msg = `${code}: ${errObj?.message || "unknown error"}, ${syscall}`;
48
+ if (details?.path) msg += ` '${details.path}'`;
49
+ if (details?.dest) msg += ` -> '${details.dest}'`;
50
+ if (details?.address) msg += ` ${details.address}`;
51
+ if (details?.port != null) msg += `:${details.port}`;
52
+ const error = new Error(msg);
53
+ error.code = code;
54
+ error.syscall = syscall;
55
+ error.errno = -(errObj?.code || 0);
56
+ if (details?.path) error.path = details.path;
57
+ if (details?.address) error.address = details.address;
58
+ if (details?.port != null) error.port = details.port;
59
+ return error;
89
60
  }
61
+ /**
62
+ * Check if a Gio error is a "not found" error.
63
+ */
90
64
  function isNotFoundError(err) {
91
- const errObj = err;
92
- return errObj?.code === 1 || errObj?.code === "ENOENT";
65
+ const errObj = err;
66
+ return errObj?.code === 1 || errObj?.code === "ENOENT";
93
67
  }
68
+ /**
69
+ * Map from GLib.FileError numeric values to Node.js error code strings.
70
+ * Distinct from Gio.IOErrorEnum — GLib.IOChannel.new_file() and some other
71
+ * low-level GLib APIs throw GLib.FileError (domain "g-file-error"), which
72
+ * has different numeric values than Gio.IOErrorEnum (domain "g-io-error-quark").
73
+ */
94
74
  const GLIB_FILE_ERROR_TO_NODE = {
95
- 0: "EEXIST",
96
- 1: "EISDIR",
97
- 2: "EACCES",
98
- 3: "ENAMETOOLONG",
99
- 4: "ENOENT",
100
- 5: "ENOTDIR",
101
- 6: "ENXIO",
102
- 7: "ENODEV",
103
- 8: "EROFS",
104
- 11: "ELOOP",
105
- 12: "ENOSPC",
106
- 13: "ENOMEM",
107
- 14: "EMFILE",
108
- 15: "ENFILE",
109
- 16: "EBADF",
110
- 17: "EINVAL",
111
- 18: "EPIPE",
112
- 21: "EIO",
113
- 22: "EPERM",
114
- 24: "EIO"
75
+ 0: "EEXIST",
76
+ 1: "EISDIR",
77
+ 2: "EACCES",
78
+ 3: "ENAMETOOLONG",
79
+ 4: "ENOENT",
80
+ 5: "ENOTDIR",
81
+ 6: "ENXIO",
82
+ 7: "ENODEV",
83
+ 8: "EROFS",
84
+ 11: "ELOOP",
85
+ 12: "ENOSPC",
86
+ 13: "ENOMEM",
87
+ 14: "EMFILE",
88
+ 15: "ENFILE",
89
+ 16: "EBADF",
90
+ 17: "EINVAL",
91
+ 18: "EPIPE",
92
+ 21: "EIO",
93
+ 22: "EPERM",
94
+ 24: "EIO"
115
95
  };
96
+ /**
97
+ * Map a GLib.FileError to a Node.js-style ErrnoException. Counterpart to
98
+ * `createNodeError` for the Gio.IOErrorEnum case; kept separate because the
99
+ * enum domains differ.
100
+ */
116
101
  function createGLibFileError(err, syscall, details) {
117
- const errObj = err;
118
- const code = GLIB_FILE_ERROR_TO_NODE[errObj?.code ?? -1] ?? "EIO";
119
- let msg = `${code}: ${errObj?.message || "unknown error"}, ${syscall}`;
120
- if (details?.path) msg += ` '${details.path}'`;
121
- if (details?.dest) msg += ` -> '${details.dest}'`;
122
- const error = new Error(msg);
123
- error.code = code;
124
- error.syscall = syscall;
125
- error.errno = -(errObj?.code || 0);
126
- if (details?.path) error.path = details.path;
127
- return error;
102
+ const errObj = err;
103
+ const code = GLIB_FILE_ERROR_TO_NODE[errObj?.code ?? -1] ?? "EIO";
104
+ let msg = `${code}: ${errObj?.message || "unknown error"}, ${syscall}`;
105
+ if (details?.path) msg += ` '${details.path}'`;
106
+ if (details?.dest) msg += ` -> '${details.dest}'`;
107
+ const error = new Error(msg);
108
+ error.code = code;
109
+ error.syscall = syscall;
110
+ error.errno = -(errObj?.code || 0);
111
+ if (details?.path) error.path = details.path;
112
+ return error;
128
113
  }
129
- export {
130
- GIO_ERROR_TO_NODE,
131
- GLIB_FILE_ERROR_TO_NODE,
132
- createGLibFileError,
133
- createNodeError,
134
- isNotFoundError
135
- };
114
+
115
+ //#endregion
116
+ export { GIO_ERROR_TO_NODE, GLIB_FILE_ERROR_TO_NODE, createGLibFileError, createNodeError, isNotFoundError };
package/lib/esm/gio.js CHANGED
@@ -1,39 +1,52 @@
1
1
  import GLib from "@girs/glib-2.0";
2
+
3
+ //#region src/gio.ts
2
4
  const byteArray = imports.byteArray;
5
+ /**
6
+ * Generic promise wrapper for Gio async/finish method pairs.
7
+ *
8
+ * Example:
9
+ * const stream = await gioAsync<Gio.InputStream>(session, 'send_async', 'send_finish', msg, priority, null);
10
+ */
3
11
  function gioAsync(obj, asyncMethod, finishMethod, ...args) {
4
- return new Promise((resolve, reject) => {
5
- obj[asyncMethod](...args, (_self, asyncRes) => {
6
- try {
7
- resolve(obj[finishMethod](asyncRes));
8
- } catch (error) {
9
- reject(error);
10
- }
11
- });
12
- });
12
+ return new Promise((resolve, reject) => {
13
+ obj[asyncMethod](...args, (_self, asyncRes) => {
14
+ try {
15
+ resolve(obj[finishMethod](asyncRes));
16
+ } catch (error) {
17
+ reject(error);
18
+ }
19
+ });
20
+ });
13
21
  }
22
+ /**
23
+ * Promise wrapper around `Gio.InputStream.read_bytes_async` / `read_bytes_finish`.
24
+ * Returns a `Uint8Array` or `null` if the end of the stream is reached.
25
+ */
14
26
  async function readBytesAsync(inputStream, count = 4096, ioPriority = GLib.PRIORITY_DEFAULT, cancellable = null) {
15
- return new Promise((resolve, reject) => {
16
- inputStream.read_bytes_async(count, ioPriority, cancellable, (_self, asyncRes) => {
17
- try {
18
- const res = inputStream.read_bytes_finish(asyncRes);
19
- if (res.get_size() === 0) {
20
- return resolve(null);
21
- }
22
- return resolve(byteArray.fromGBytes(res));
23
- } catch (error) {
24
- reject(error);
25
- }
26
- });
27
- });
27
+ return new Promise((resolve, reject) => {
28
+ inputStream.read_bytes_async(count, ioPriority, cancellable, (_self, asyncRes) => {
29
+ try {
30
+ const res = inputStream.read_bytes_finish(asyncRes);
31
+ if (res.get_size() === 0) {
32
+ return resolve(null);
33
+ }
34
+ return resolve(byteArray.fromGBytes(res));
35
+ } catch (error) {
36
+ reject(error);
37
+ }
38
+ });
39
+ });
28
40
  }
41
+ /**
42
+ * Async generator that yields `Uint8Array` chunks from a `Gio.InputStream`.
43
+ */
29
44
  async function* inputStreamAsyncIterator(inputStream, count = 4096, ioPriority = GLib.PRIORITY_DEFAULT, cancellable = null) {
30
- let chunk;
31
- while ((chunk = await readBytesAsync(inputStream, count, ioPriority, cancellable)) !== null) {
32
- yield chunk;
33
- }
45
+ let chunk;
46
+ while ((chunk = await readBytesAsync(inputStream, count, ioPriority, cancellable)) !== null) {
47
+ yield chunk;
48
+ }
34
49
  }
35
- export {
36
- gioAsync,
37
- inputStreamAsyncIterator,
38
- readBytesAsync
39
- };
50
+
51
+ //#endregion
52
+ export { gioAsync, inputStreamAsyncIterator, readBytesAsync };
@@ -1,8 +1,13 @@
1
+ //#region src/globals.ts
2
+ /**
3
+ * Register a value as a global property if it doesn't already exist.
4
+ * This is a no-op in environments where the global is already defined (e.g. Node.js).
5
+ */
1
6
  function registerGlobal(name, value) {
2
- if (typeof globalThis[name] === "undefined") {
3
- globalThis[name] = value;
4
- }
7
+ if (typeof globalThis[name] === "undefined") {
8
+ globalThis[name] = value;
9
+ }
5
10
  }
6
- export {
7
- registerGlobal
8
- };
11
+
12
+ //#endregion
13
+ export { registerGlobal };
package/lib/esm/index.js CHANGED
@@ -1,18 +1,20 @@
1
- export * from "./callable.js";
2
- export * from "./base64.js";
3
- export * from "./byte-array.js";
4
- export * from "./cli.js";
5
- export * from "./defer.js";
6
- export * from "./encoding.js";
7
- export * from "./globals.js";
8
- export * from "./error.js";
9
- export * from "./file.js";
10
- export * from "./fs.js";
11
- export * from "./gio.js";
12
- export * from "./gio-errors.js";
13
- export * from "./message.js";
14
- export * from "./microtask.js";
15
- export * from "./next-tick.js";
16
- export * from "./path.js";
17
- export * from "./structured-clone.js";
18
- export * from "./main-loop.js";
1
+ import { atobPolyfill, base64Decode, base64Encode, btoaPolyfill } from "./base64.js";
2
+ import { gbytesToUint8Array } from "./byte-array.js";
3
+ import { makeCallable } from "./callable.js";
4
+ import { cli } from "./cli.js";
5
+ import { deferEmit } from "./defer.js";
6
+ import { checkEncoding, normalizeEncoding } from "./encoding.js";
7
+ import { initErrorV8Methods } from "./error.js";
8
+ import { readJSON } from "./file.js";
9
+ import { existsFD, existsSync } from "./fs.js";
10
+ import { GIO_ERROR_TO_NODE, GLIB_FILE_ERROR_TO_NODE, createGLibFileError, createNodeError, isNotFoundError } from "./gio-errors.js";
11
+ import { gioAsync, inputStreamAsyncIterator, readBytesAsync } from "./gio.js";
12
+ import { registerGlobal } from "./globals.js";
13
+ import { notImplemented, warnNotImplemented } from "./message.js";
14
+ import { queueMicrotask } from "./microtask.js";
15
+ import { __resetBurstStateForTests, nextTick } from "./next-tick.js";
16
+ import { getNodeModulesPath, getPathSeparator, getProgramDir, getProgramExe, resolve } from "./path.js";
17
+ import { structuredClone } from "./structured-clone.js";
18
+ import { ensureMainLoop, quitMainLoop } from "./main-loop.js";
19
+
20
+ export { GIO_ERROR_TO_NODE, GLIB_FILE_ERROR_TO_NODE, __resetBurstStateForTests, atobPolyfill, base64Decode, base64Encode, btoaPolyfill, checkEncoding, cli, createGLibFileError, createNodeError, deferEmit, ensureMainLoop, existsFD, existsSync, gbytesToUint8Array, getNodeModulesPath, getPathSeparator, getProgramDir, getProgramExe, gioAsync, initErrorV8Methods, inputStreamAsyncIterator, isNotFoundError, makeCallable, nextTick, normalizeEncoding, notImplemented, queueMicrotask, quitMainLoop, readBytesAsync, readJSON, registerGlobal, resolve, structuredClone, warnNotImplemented };
@@ -1,28 +1,46 @@
1
+ //#region src/main-loop.ts
2
+ /** Sentinel to prevent double-start (setMainLoopHook throws if called twice). */
1
3
  let _started = false;
4
+ /** The singleton MainLoop instance, if created. */
2
5
  let _loop = null;
6
+ /**
7
+ * Ensure a GLib MainLoop is running for async I/O dispatch (Soup.Server,
8
+ * Gio.SocketService, etc.). No-op on Node.js. Idempotent.
9
+ *
10
+ * - Called automatically by `http.Server.listen()`, `net.Server.listen()`,
11
+ * `dgram.Socket.bind()` etc.
12
+ * - GTK apps should NOT call this — they use `Gtk.Application.runAsync()` instead.
13
+ *
14
+ * @returns The MainLoop instance on GJS, or `undefined` on Node.js.
15
+ */
3
16
  function ensureMainLoop() {
4
- const gjsImports = globalThis.imports;
5
- if (!gjsImports) return void 0;
6
- if (_started) return _loop;
7
- const GLibModule = gjsImports.gi.GLib;
8
- _loop = new GLibModule.MainLoop(null, false);
9
- _started = true;
10
- if (GLibModule.main_depth() === 0) {
11
- try {
12
- _loop.runAsync();
13
- } catch {
14
- }
15
- }
16
- return _loop;
17
+ const gjsImports = globalThis.imports;
18
+ if (!gjsImports) return undefined;
19
+ if (_started) return _loop;
20
+ const GLibModule = gjsImports.gi.GLib;
21
+ _loop = new GLibModule.MainLoop(null, false);
22
+ _started = true;
23
+ if (GLibModule.main_depth() === 0) {
24
+ try {
25
+ _loop.runAsync();
26
+ } catch {}
27
+ }
28
+ return _loop;
17
29
  }
30
+ /**
31
+ * Quit the MainLoop created by `ensureMainLoop()`. Idempotent, no-op on Node.js.
32
+ *
33
+ * Calling `quit()` on a loop that hasn't started yet pre-quits it — when the
34
+ * `setMainLoopHook` later fires and calls `run()`, it returns immediately.
35
+ * This is used by `@gjsify/unit` to prevent the loop from blocking after tests.
36
+ */
18
37
  function quitMainLoop() {
19
- if (_loop) {
20
- _loop.quit();
21
- _started = false;
22
- _loop = null;
23
- }
38
+ if (_loop) {
39
+ _loop.quit();
40
+ _started = false;
41
+ _loop = null;
42
+ }
24
43
  }
25
- export {
26
- ensureMainLoop,
27
- quitMainLoop
28
- };
44
+
45
+ //#endregion
46
+ export { ensureMainLoop, quitMainLoop };
@@ -1,13 +1,13 @@
1
+ //#region src/message.ts
1
2
  const notImplemented = (msg) => {
2
- const message = msg ? `Not implemented: ${msg}` : "Not implemented";
3
- throw new Error(message);
3
+ const message = msg ? `Not implemented: ${msg}` : "Not implemented";
4
+ throw new Error(message);
4
5
  };
5
6
  const warnNotImplemented = (msg) => {
6
- const message = msg ? `Not implemented: ${msg}` : "Not implemented";
7
- console.warn(message);
8
- return message;
9
- };
10
- export {
11
- notImplemented,
12
- warnNotImplemented
7
+ const message = msg ? `Not implemented: ${msg}` : "Not implemented";
8
+ console.warn(message);
9
+ return message;
13
10
  };
11
+
12
+ //#endregion
13
+ export { notImplemented, warnNotImplemented };
@@ -1,6 +1,7 @@
1
+ //#region src/microtask.ts
1
2
  const queueMicrotask = (fn) => {
2
- Promise.resolve().then(fn);
3
- };
4
- export {
5
- queueMicrotask
3
+ Promise.resolve().then(fn);
6
4
  };
5
+
6
+ //#endregion
7
+ export { queueMicrotask };
@@ -1,60 +1,65 @@
1
+ //#region src/next-tick.ts
1
2
  const CHUNK_SIZE = 64;
2
3
  const YIELD_DELAY_MS = 1;
3
4
  const _queue = [];
4
5
  let _drainerArmed = false;
5
6
  function drainOnce(GLib) {
6
- const end = Math.min(CHUNK_SIZE, _queue.length);
7
- for (let i = 0; i < end; i++) {
8
- const cb = _queue.shift();
9
- try {
10
- cb();
11
- } catch (err) {
12
- try {
13
- GLib.log_default_handler("gjsify-nextTick", GLib.LogLevelFlags.LEVEL_WARNING, String(err?.stack || err), null);
14
- } catch {
15
- }
16
- }
17
- }
18
- if (_queue.length > 0) {
19
- GLib.timeout_add(GLib.PRIORITY_DEFAULT, YIELD_DELAY_MS, () => {
20
- drainOnce(GLib);
21
- return false;
22
- });
23
- } else {
24
- _drainerArmed = false;
25
- }
7
+ const end = Math.min(CHUNK_SIZE, _queue.length);
8
+ for (let i = 0; i < end; i++) {
9
+ const cb = _queue.shift();
10
+ try {
11
+ cb();
12
+ } catch (err) {
13
+ try {
14
+ GLib.log_default_handler("gjsify-nextTick", GLib.LogLevelFlags.LEVEL_WARNING, String(err?.stack || err), null);
15
+ } catch {}
16
+ }
17
+ }
18
+ if (_queue.length > 0) {
19
+ GLib.timeout_add(GLib.PRIORITY_DEFAULT, YIELD_DELAY_MS, () => {
20
+ drainOnce(GLib);
21
+ return false;
22
+ });
23
+ } else {
24
+ _drainerArmed = false;
25
+ }
26
26
  }
27
27
  function tryGLibTimeout(cb) {
28
- const GLib = globalThis.imports?.gi?.GLib;
29
- if (!GLib?.timeout_add) return false;
30
- _queue.push(cb);
31
- if (!_drainerArmed) {
32
- _drainerArmed = true;
33
- GLib.timeout_add(GLib.PRIORITY_DEFAULT, 0, () => {
34
- drainOnce(GLib);
35
- return false;
36
- });
37
- }
38
- return true;
28
+ const GLib = globalThis.imports?.gi?.GLib;
29
+ if (!GLib?.timeout_add) return false;
30
+ _queue.push(cb);
31
+ if (!_drainerArmed) {
32
+ _drainerArmed = true;
33
+ GLib.timeout_add(GLib.PRIORITY_DEFAULT, 0, () => {
34
+ drainOnce(GLib);
35
+ return false;
36
+ });
37
+ }
38
+ return true;
39
39
  }
40
+ /** @internal Test helper: reset burst state. */
40
41
  function __resetBurstStateForTests() {
41
- _queue.length = 0;
42
- _drainerArmed = false;
42
+ _queue.length = 0;
43
+ _drainerArmed = false;
43
44
  }
45
+ /**
46
+ * Schedule a function on the next turn of the event loop.
47
+ * On GJS: uses GLib.timeout_add(PRIORITY_DEFAULT, delay=0).
48
+ * On Node.js: uses process.nextTick → queueMicrotask → Promise.resolve().then().
49
+ */
44
50
  const nextTick = (fn, ...args) => {
45
- const cb = args.length > 0 ? () => fn(...args) : fn;
46
- if (tryGLibTimeout(cb)) return;
47
- if (typeof globalThis.process?.nextTick === "function") {
48
- globalThis.process.nextTick(fn, ...args);
49
- return;
50
- }
51
- if (typeof queueMicrotask === "function") {
52
- queueMicrotask(cb);
53
- return;
54
- }
55
- Promise.resolve().then(cb);
56
- };
57
- export {
58
- __resetBurstStateForTests,
59
- nextTick
51
+ const cb = args.length > 0 ? () => fn(...args) : fn;
52
+ if (tryGLibTimeout(cb)) return;
53
+ if (typeof globalThis.process?.nextTick === "function") {
54
+ globalThis.process.nextTick(fn, ...args);
55
+ return;
56
+ }
57
+ if (typeof queueMicrotask === "function") {
58
+ queueMicrotask(cb);
59
+ return;
60
+ }
61
+ Promise.resolve().then(cb);
60
62
  };
63
+
64
+ //#endregion
65
+ export { __resetBurstStateForTests, nextTick };