1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Node `timers` and `timers/promises` modules.
//!
//! `require('timers')` re-exports the SAME timer primitives that already exist as
//! globals (`setTimeout`/`setInterval`/`setImmediate` + their `clear*`), so this
//! module owns NO queue of its own: every method delegates straight to
//! `builtins::call_builtin_function`, which schedules onto the single shared
//! `JsHost.macrotasks` queue. `timers.foo(...)` is therefore observably identical
//! to the global `foo(...)`.
//!
//! `require('timers/promises')` returns the promise-based variants: `setTimeout`
//! and `setImmediate` resolve a Promise after the delay instead of invoking a
//! callback. They are built on the SAME two substrates — the global timer
//! scheduler and the `@@presolve:<id>` native-continuation convention that
//! `builtins.rs` uses for Promise resolve reactions — so no new mechanism is
//! introduced: a timer is scheduled whose callback is the promise's resolver.
use arg_num;
use crate;
use Value;
// ── timers (callback API) ────────────────────────────────────────────────────
/// Methods of the `timers` module. Each name is also a global; `call` forwards to
/// the identical global implementation, so there is one timer queue, not two.
pub const METHODS: & = &;
/// Dispatch a `timers.<method>` call by delegating to the matching global timer
/// builtin. `clearImmediate` has no distinct global handler (the loop cancels by
/// id regardless of kind), so it maps to `clearTimeout`.
// ── timers/promises (Promise API) ────────────────────────────────────────────
/// Methods of the `timers/promises` module (its namespace name carries no `.`, so
/// `stdlib::is_method` treats the whole `"timers/promises"` as the namespace).
///
/// `setInterval(delay[, value])` (an async iterator) is NOT implemented: the
/// `for await` machinery finds a native object's async iterator only via
/// `host::user_async_iterator_fn`, which needs a *callable* `@@asyncIterator`
/// stored property discoverable by `lookup_chain` — native-tagged objects
/// dispatch methods through the parent `instance_call` table, not stored
/// properties, so there is no way to expose it without editing `builtins.rs`/
/// `host.rs` (out of scope here).
pub const PROMISES_METHODS: & = &;
/// Dispatch a `timers/promises.<method>` call.
///
/// `setTimeout(delay[, value])` → a Promise that fulfills with `value` (undefined
/// if absent) after `delay` ms. `setImmediate([value])` → a Promise that fulfills
/// with `value` on the next loop turn. Any trailing `options` argument (Node's
/// `{ signal, ref }`) is accepted and ignored — abort/unref are not modeled.
/// Allocate a pending Promise and schedule its resolution with `value` via the
/// existing global timer scheduler. The scheduled callback is a
/// `Builtin("@@presolve:<id>")` value — the same native continuation
/// `builtins.rs` invokes to fulfill a Promise — so when the timer fires it
/// resolves the Promise with the timer's extra argument (`value`).