@gjsify/timers 0.4.35 → 0.4.37

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.
Files changed (2) hide show
  1. package/globals.mjs +64 -9
  2. package/package.json +18 -6
package/globals.mjs CHANGED
@@ -1,13 +1,68 @@
1
1
  /**
2
- * Re-exports native `node:timers` for use in Node.js builds.
2
+ * Cross-runtime re-export of the native timer globals for use in Node.js
3
+ * AND browser builds.
3
4
  *
4
- * On Node, `node:timers` is built into the runtime — so a Node-target
5
- * bundle that imports `@gjsify/timers` is routed here by the
6
- * resolver's `gjsify.runtimes.node === "native"` rule. This avoids dragging
7
- * the GJS polyfill into Node bundles entirely.
5
+ * `setTimeout`/`setInterval`/`setImmediate`/`queueMicrotask` and their
6
+ * `clear*` counterparts exist on both Node 18+ and every modern browser.
7
+ * The browser does NOT have native `setImmediate` we polyfill it via
8
+ * `Promise.resolve().then(...)` (a turn boundary, the closest browser
9
+ * equivalent to Node's "I/O phase callback"; the MessageChannel-based
10
+ * shim is heavier and only buys ~µs of priority over Promise — not worth
11
+ * the complexity for a polyfill no real browser code targets directly).
8
12
  *
9
- * GJS bundles do NOT consult this file; they route to `@gjsify/timers`'s
10
- * own `lib/esm/index.js` (the polyfill).
13
+ * IMPORTANT: this file MUST NOT reference `node:timers` (or any other
14
+ * `node:` specifier) — the audit-runtimes `--strict` probe rejects re-exports
15
+ * from `node:*` for a slot declared cross-runtime, and `node:timers`
16
+ * fails to resolve in a browser bundle.
17
+ *
18
+ * GJS bundles do NOT consult this file; the GJS-target alias layer routes
19
+ * `@gjsify/timers` to the polyfill at `lib/esm/index.js` (which provides
20
+ * the GLib-source-safe Timeout class — see CLAUDE.md "GLib MainLoop").
11
21
  */
12
- export * from 'node:timers';
13
- export { default } from 'node:timers';
22
+
23
+ // Standard timers bind to globalThis so callers can detach them and the
24
+ // `this` context still resolves to the runtime's timer host. Node's
25
+ // `setTimeout` is callable without rebinding, but `setTimeout.bind(undefined)`
26
+ // matches the lib.dom `(handler, timeout?, ...args) => number` signature.
27
+ export const setTimeout = globalThis.setTimeout.bind(globalThis);
28
+ export const clearTimeout = globalThis.clearTimeout.bind(globalThis);
29
+ export const setInterval = globalThis.setInterval.bind(globalThis);
30
+ export const clearInterval = globalThis.clearInterval.bind(globalThis);
31
+
32
+ // queueMicrotask is native on both Node 12+ and every browser.
33
+ export const queueMicrotask = globalThis.queueMicrotask.bind(globalThis);
34
+
35
+ // setImmediate / clearImmediate — Node-only natively. In the browser we
36
+ // polyfill via Promise.resolve().then so the callback fires on the very next
37
+ // microtask turn. We hand out a Symbol token so `clearImmediate` can
38
+ // no-op (a real cancellation isn't possible once `.then` has scheduled);
39
+ // every npm consumer treats clearImmediate as best-effort already.
40
+ const _hasNativeImmediate = typeof globalThis.setImmediate === 'function';
41
+
42
+ export const setImmediate = _hasNativeImmediate
43
+ ? globalThis.setImmediate.bind(globalThis)
44
+ : ((cb, ...args) => {
45
+ const handle = { __cancelled: false };
46
+ Promise.resolve().then(() => {
47
+ if (!handle.__cancelled) cb(...args);
48
+ });
49
+ return handle;
50
+ });
51
+
52
+ export const clearImmediate = _hasNativeImmediate
53
+ ? globalThis.clearImmediate.bind(globalThis)
54
+ : ((handle) => {
55
+ if (handle && typeof handle === 'object') handle.__cancelled = true;
56
+ });
57
+
58
+ // Default-export shape — every named timer exported as a property so
59
+ // `import timers from '@gjsify/timers'; timers.setTimeout(...)` resolves.
60
+ export default {
61
+ setTimeout,
62
+ clearTimeout,
63
+ setInterval,
64
+ clearInterval,
65
+ setImmediate,
66
+ clearImmediate,
67
+ queueMicrotask,
68
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/timers",
3
- "version": "0.4.35",
3
+ "version": "0.4.37",
4
4
  "description": "Node.js timers module for Gjs",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -29,6 +29,7 @@
29
29
  "build:test": "gjsify run build:test:gjs && gjsify run build:test:node",
30
30
  "build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs",
31
31
  "build:test:node": "gjsify build src/test.mts --app node --outfile test.node.mjs",
32
+ "build:test:browser": "gjsify build src/test.browser.mts --app browser --outfile dist/test.browser.mjs",
32
33
  "test": "gjsify run build:gjsify && gjsify run build:test && gjsify run test:node && gjsify run test:gjs",
33
34
  "test:gjs": "gjsify run test.gjs.mjs",
34
35
  "test:node": "node test.node.mjs"
@@ -39,16 +40,27 @@
39
40
  "timers"
40
41
  ],
41
42
  "devDependencies": {
42
- "@gjsify/cli": "^0.4.35",
43
- "@gjsify/unit": "^0.4.35",
43
+ "@gjsify/cli": "^0.4.37",
44
+ "@gjsify/unit": "^0.4.37",
44
45
  "@types/node": "^25.9.1",
45
- "typescript": "^6.0.3"
46
+ "typescript": "^5.9.3"
46
47
  },
47
48
  "gjsify": {
48
49
  "runtimes": {
49
50
  "gjs": "polyfill",
50
51
  "node": "native",
51
- "browser": "polyfill"
52
+ "browser": "native",
53
+ "nativescript": "polyfill"
52
54
  }
53
- }
55
+ },
56
+ "license": "MIT",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/gjsify/gjsify.git",
60
+ "directory": "packages/node/timers"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/gjsify/gjsify/issues"
64
+ },
65
+ "homepage": "https://github.com/gjsify/gjsify/tree/main/packages/node/timers#readme"
54
66
  }