feat: Add setDisableFakeTimersDetection to opt out of fake-timer fingerprinting#532
Open
nev21 wants to merge 1 commit into
Open
feat: Add setDisableFakeTimersDetection to opt out of fake-timer fingerprinting#532nev21 wants to merge 1 commit into
nev21 wants to merge 1 commit into
Conversation
…erprinting _isFakeTimersEnabled() detects Sinon-style fake timers by checking for a patched setTimeout.clock property, and uses that to decide whether deferred promise continuations hop via a 0ms timeout (fake-timer-friendly) or a real microtask. This fingerprint is always active in production, so any code that patches setTimeout and happens to expose a .clock property (not necessarily Sinon) silently changes the library's internal scheduling. Rather than stripping the check via a #ifdef DEBUG build flag, add setDisableFakeTimersDetection(disable?: boolean) so consumers can opt out at runtime while keeping the affordance available by default. Passing undefined restores the default (detection enabled); any other value is coerced via !!.
There was a problem hiding this comment.
Pull request overview
Adds a runtime opt-out for the library’s Sinon-style fake-timer detection (setTimeout.clock fingerprint) so consumers can force deferred continuations to use real microtasks even when a patched setTimeout.clock exists. This extends the existing internal scheduling behavior while keeping default behavior unchanged unless the new setter is called.
Changes:
- Added
setDisableFakeTimersDetection(disable?: boolean)and integrated it into_isFakeTimersEnabled()so detection can be disabled at runtime. - Exported the new API from the package root and added a dedicated test suite validating default/disabled/restored behavior under Sinon fake timers.
- Documented the behavior and side effects in both
README.mdanddocs/README.md, and added an unreleased changelog entry.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds a top-level section pointing readers to the new fake-timer detection docs and opt-out API. |
| lib/test/src/promise/fakeTimersDetection.test.ts | Adds tests covering default detection behavior, opt-out behavior, and restoring defaults. |
| lib/src/promise/itemProcessor.ts | Implements the opt-out flag and exposes setDisableFakeTimersDetection(); updates fake-timer detection path. |
| lib/src/index.ts | Exports setDisableFakeTimersDetection from the package root entrypoint. |
| docs/README.md | Adds detailed documentation on fake timer detection, usage, and side effects. |
| CHANGELIST.md | Adds an Unreleased feature entry describing the new API and its behavior. |
Comment on lines
+102
to
+104
| * @param disable - When `true` (or any other truthy value), disables fake timer detection so | ||
| * {@link _isFakeTimersEnabled} always returns `false`. When `false` (or any other falsy value), | ||
| * (re-)enables detection. When `undefined`, restores the default (detection enabled). |
| | `setDisableFakeTimersDetection(true)` | Disables the check -- the library always behaves as though fake timers are **not** present and always uses real microtask scheduling to defer work, even if a patched `setTimeout.clock` is present. | | ||
| | `setDisableFakeTimersDetection(false)` | Explicitly (re-)enables the check (same as the default). | | ||
| | `setDisableFakeTimersDetection()` / `setDisableFakeTimersDetection(undefined)` | Restores the default (detection enabled). | | ||
| | Any other value | Coerced to a boolean via `!!value`, so e.g. `setDisableFakeTimersDetection(1)` behaves the same as passing `true`. | |
| - `createAsyncPromise` was re-wrapping the raw (potentially array) timeout as the chained promise's additional args on every `then()`/`catch()`/`finally()` link, growing an extra array-nesting level per link. Combined with the new depth cap this silently dropped an explicit timeout after ~5-6 chained calls. Fixed by normalizing the timeout once before it is stored, matching the existing `createIdlePromise` pattern, so nesting never exceeds one level regardless of chain length. | ||
| - [Feature] Add `setDisableFakeTimersDetection` to allow opting out of Sinon fake-timer fingerprinting | ||
| - New exported function `setDisableFakeTimersDetection(disable?: boolean)` allows a consumer to force the library's internal Sinon-fake-timer detection (a patched `setTimeout.clock` fingerprint used to decide whether deferred continuations use a `0ms` timeout or a microtask) to always report "not present", so deferred work always uses a real microtask. | ||
| - Default behavior (detection enabled) is unchanged when never called, or called with `undefined`. Any other value is coerced via `!!`. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #532 +/- ##
==========================================
+ Coverage 97.57% 97.66% +0.08%
==========================================
Files 28 28
Lines 1527 1540 +13
Branches 358 362 +4
==========================================
+ Hits 1490 1504 +14
+ Misses 37 36 -1
🚀 New features to boost your workflow:
|
nevware21-bot
approved these changes
Jul 10, 2026
nevware21-bot
left a comment
Contributor
There was a problem hiding this comment.
Approved by nevware21-bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
_isFakeTimersEnabled() detects Sinon-style fake timers by checking for a patched setTimeout.clock property, and uses that to decide whether deferred promise continuations hop via a 0ms timeout (fake-timer-friendly) or a real microtask. This fingerprint is always active in production, so any code that patches setTimeout and happens to expose a .clock property (not necessarily Sinon) silently changes the library's internal scheduling.
Rather than stripping the check via a #ifdef DEBUG build flag, add setDisableFakeTimersDetection(disable?: boolean) so consumers can opt out at runtime while keeping the affordance available by default. Passing undefined restores the default (detection enabled); any other value is coerced via !!.