{"id":39350484,"url":"https://github.com/tlewowski/zurvan","last_synced_at":"2026-01-18T02:29:46.229Z","repository":{"id":36258515,"uuid":"40562938","full_name":"tlewowski/zurvan","owner":"tlewowski","description":"Zurvan fakes timers for your node.js tests.","archived":false,"fork":false,"pushed_at":"2022-12-30T22:38:44.000Z","size":1218,"stargazers_count":10,"open_issues_count":21,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-31T14:20:45.804Z","etag":null,"topics":["callback","schedule","testing","testing-tools","timer"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tlewowski.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-11T20:12:32.000Z","updated_at":"2023-08-22T10:00:07.000Z","dependencies_parsed_at":"2023-01-16T23:54:05.769Z","dependency_job_id":null,"html_url":"https://github.com/tlewowski/zurvan","commit_stats":null,"previous_names":["lewerow/thoth","lewerow/zurvan"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/tlewowski/zurvan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlewowski%2Fzurvan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlewowski%2Fzurvan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlewowski%2Fzurvan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlewowski%2Fzurvan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tlewowski","download_url":"https://codeload.github.com/tlewowski/zurvan/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlewowski%2Fzurvan/sbom","scorecard":{"id":113875,"data":{"date":"2025-08-04","repo":{"name":"github.com/tlewowski/zurvan","commit":"ddfa842597f4db588e3c017812c51ffc98d9215c"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":1.7,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/10 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"89 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-wg6g-ppvx-927h","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-rq8g-5pc5-wrhr","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-j4f2-536g-r55m","Warn: Project is vulnerable to: GHSA-r7qp-cfhv-p84w","Warn: Project is vulnerable to: GHSA-2j2x-2gpw-g8fm","Warn: Project is vulnerable to: GHSA-74fj-2j2h-c42q","Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-957j-59c2-j692","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-m5pj-vjjf-4m3h","Warn: Project is vulnerable to: GHSA-j383-35pm-c5h4","Warn: Project is vulnerable to: GHSA-rm36-94g8-835r","Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6","Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-44pw-h2cw-w3vq","Warn: Project is vulnerable to: GHSA-jp4x-w63m-7wgm","Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-282f-qqgm-c34q","Warn: Project is vulnerable to: GHSA-7x7c-qm48-pq9c","Warn: Project is vulnerable to: GHSA-rc3x-jf5g-xvc5","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-82v2-mx6x-wq7q","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-hxm2-r34f-qmc5","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-qrpm-p2h7-hrv2","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-6fx8-h7jm-663j","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-x3m3-4wpv-5vgc","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-g4rg-993r-mgx7","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-25hc-qcg6-38wj","Warn: Project is vulnerable to: GHSA-qm95-pgcg-qqfq","Warn: Project is vulnerable to: GHSA-cqmj-92xf-r6r9","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-xc7v-wxcw-j472","Warn: Project is vulnerable to: GHSA-394c-5j6w-4xmx","Warn: Project is vulnerable to: GHSA-78cj-fxph-m83p","Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-72mh-269x-7mh5","Warn: Project is vulnerable to: GHSA-h4j5-c7cj-74xg"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T21:13:12.706Z","repository_id":36258515,"created_at":"2025-08-15T21:13:12.706Z","updated_at":"2025-08-15T21:13:12.706Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28526571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["callback","schedule","testing","testing-tools","timer"],"created_at":"2026-01-18T02:29:46.103Z","updated_at":"2026-01-18T02:29:46.195Z","avatar_url":"https://github.com/tlewowski.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zurvan\n\n[![Build Status](https://travis-ci.com/tlewowski/zurvan.svg?branch=master)](https://travis-ci.com/tlewowski/zurvan.svg?branch=master)\n[![Code Climate](https://codeclimate.com/github/Lewerow/Zurvan/badges/gpa.svg)](https://codeclimate.com/github/Lewerow/Zurvan)\n[![codebeat badge](https://codebeat.co/badges/489f95fd-f719-4334-9fce-f7fed2873a56)](https://codebeat.co/projects/github-com-tlewowski-zurvan-master)\n[![Test Coverage](https://codeclimate.com/github/Lewerow/Zurvan/badges/coverage.svg)](https://codeclimate.com/github/Lewerow/Zurvan/coverage)\n[![Dependencies](https://david-dm.org/Lewerow/zurvan.svg)](https://github.com/Lewerow/zurvan/blob/master/package.json)\n[![devDependencies](https://david-dm.org/Lewerow/zurvan/dev-status.svg)](https://david-dm.org/Lewerow/zurvan#info=devDependencies)\n[![GitHub version](https://badge.fury.io/gh/Lewerow%2Fzurvan.svg)](http://badge.fury.io/gh/Lewerow%2Fzurvan)\n[![npm version](https://badge.fury.io/js/zurvan.svg)](http://badge.fury.io/js/zurvan)\n\n_Zurvan_ is an asynchronous library for faking whole real-time dependency of node.js, mainly for test purposes.\n\n## Introduction\n\n_Zurvan_ includes fake implementations for `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval`,\n`Date.now`, `Date`, `process.uptime` and `process.hrtime`. Also several other functions are taken into account,\nsuch as `setImmediate`, `clearImmediate` and `process.nextTick`, but they are not faked - library utilizes asynchronous\nexecution heavily (under assumption that since time is asynchronous by default, it's better to leave it this way).\n\n_Zurvan_ is currently _not_ tested in the browser, so if you want to use it there, you can either hack it yourself (see: [Zurvan requirements](#requirements)) or a\ncontact me.\n\nMultiple testcases cannot be ran in parallel when using _Zurvan_, as there is only a single time stream for forwarding.\n\n_Zurvan_ will _NOT_ work properly (at least in release 0.5.1) if test code uses real I/O (filesystem, sockets etc.).\nTo be exact, `waitForEmptyQueue` will not be able to work, since there will be no scheduled tasks on the queue, despite the fact that I/O is not done.\nIt is possible to use _Zurvan_ in such cases, but additional `Promise`s are required. It is generally preferred to use preloaded data and mock I/O via\nusual async actions (`setImmediate/process.nextTick`).\n\n## API overview\n\n### `zurvan`\n\nThis is the main module of the library. Typical forwarding of time is done step by step:\n\n1.  Event queue is cleared (all immediates and ticks are executed)\n2.  Nearest timer is inspected - if it is after due time (now + requested advance), time is set to requested due time and forwarding ends\n3.  Otherwise a single nearest timer is expired, and the 1. is applied again, with smaller reqested advance time\n\n`zurvan.blockSystem` is an exception, described below.\nIf critical requirements are not met, `zurvan` will throw during first evaluation (at the point of `require`).\n\n#### `zurvan.interceptTimers([config])`\n\nLibrary setup. Causes timers to be intercepted, i.e. all required functions are overridden after this call.\nReturns a Promise that is resolved when timers are faked and event queue is empty and rejected if interception was not possible (e.g. timers were already intercepted)\nIt takes an optional configuration object as parameter, which takes precedence over global configuration.\nDetails of configuration options are described in \u003ca href=\"doc/configuration.md\"\u003econfiguration documentation\u003c/a\u003e.\n\nResolution value is `undefined` and rejection value is `Error` with proper message.\n\nIf the configuration is incompatible or required fields are not filled in, `.interceptTimers()` will throw an error with proper message.\nInvalid configuration has priority over timers already being intercepted, i.e., if timers are already intercepted _and_ configuration is invalid, error about invalid configuration will be thrown.\nErrors due to invalid configuration are thrown synchronously, not via promise rejection.\n\n#### `zurvan.releaseTimers()`\n\nLibrary teardown. Causes timers to be restored, i.e. all original functions are set back.\nReturns a Promise that is resolved when timers are released and event queue is empty and rejected if release was not possible (e.g. timers weren't even intercepted) or failed (e.g. long enough setImmediate loop)\n\nResolution value is and `object`, defined as:\n\n```\n{\n  timeouts: remainingTimeouts,\n  intervals: remainingIntervals,\n  immediates: remainingImmediates,\n  date: zurvanEndDate,\n  processTime: zurvanEndProcessTime,\n  currentTime: zurvanEndTime\n}\n```\n\nthese fields are defined as:\n\n- `remainingTimeouts` is an array of `Timer` objects, representing timeouts that did not expire yet\n- `remainingIntervals` is an array of `Timer` objects, representing intervals that did not expire yet\n- `zurvanEndDate` is _zurvan_ date in same format that is returned when timers are intercepted (not exactly same as usual `Date` - see [limitations]{#limitations})\n- `zurvanEndProcessTime` is _zurvan_ process time in `hrtime` format (`[seconds, nanoseconds]`) at the release site\n- `zurvanEndTime` is `TimeUnit` that can be compared with `dueTime` of `Timer`. It represents amount of time that was forwarded.\n- `remainingImmediates` is an object of immediates that were not yet executed. In `zurvan.releaseTimers()` is should always be an object defined as: { size: 0 }. If you encounter other value,\n  please report it. For other possible values, see `zurvan.forcedReleaseTimers()`.\n\nA `Timer` object consists of at least two fields: `callback` which is a 0-argument function executing what would be done if it expired and\n`dueTime` which is a `TimeUnit`, informing when would the timer be expired. In case of intervals it must also contain `callDelay` field, which is a `TimeUnit`\nrepresenting delay between consecutive calls. It may also contain arbitrary other fields, but they shall not be relied upon.\nOrder of elements in `remainingTimeouts` and `remainingIntervals` is undefined. If _zurvan_ is executed with `ignoreProcessTimers` or `ignoreDate` configuration options,\nrespective fields (`processTime` and `date`) will not be available in `releaseTimers` resolution.\n\nIf is rejected, rejection value is `Error` with proper message.\n\n#### `zurvan.forcedReleaseTimers()`\n\nForced teardown, should be used with extreme care. Works roughly the same way as `zurvan.releaseTimers()`, but does not validate that queue is cleared AND resets internals totally.\nShould be used only in fatal situations, such as after `zurvan.waitForEmptyQueue()` failed due to infinite loop.\nLeaves global variables in unknown state (may cause dropping of some events).\nReturn values are the the same as in `zurvan.releaseTimers()`, except `remainingImmediates` - here it will be an object containing key `size` with value equal to number of dropped immediates and\n`size` of other keys, each corresponding to one dropped immediate. Value of these keys are stacks pointing to location where setting the immediate was requested.\n\n#### `zurvan.withDefaultConfiguration([config])`\n\nReturns a new library object (new `zurvan` instance) with modified default configuration.\nThis means that after calling `.withDefaultConfiguration`, there are two instances of `zurvan`. However, they should not be used in parallel,\ni.e. only one of them should intercept timers at the same time. If another one already does, promise returned by `interceptTimers` will be rejected.\nChain of `withDefaultConfiguration(config)` causes all `config`s to be merged (newer configurations override their fields, rest is taken from previous).\n\nConfiguration options are described in \u003ca href=\"doc/configuration.md\"\u003econfiguration documentation\u003c/a\u003e.\n\nIf called without arguments, returned instance will be created with default parameters.\n\n#### `zurvan.advanceTime(timeToAdvance)`\n\nReturns a `Promise` that is resolved when time is forwarded by given time and all timers with this dueTime are expired,\nor rejected it time cannot be forwarded (e.g. timers were not intercepted yet).\nResolution value is array of callbacks that exited with an exception (if everything went smoothly, it should be empty). If you want `zurvan` to reject\nthe `Promise` in such case, turn `rejectOnCallbackFailure` configuration option to `true`. If you do, it'll be rejected with the array of failed callbacks.\nHowever, if the reason for rejection is different than failed callbacks, it will be rejected with `Error` with proper message.\n\nArgument may be either a number (it is then interpreted as millisecond) or a `TimeUnit` object.\n\n#### `zurvan.blockSystem(blockingTime)`\n\nSimulates a blocking call - expires _synchronously_ all timers up to due time at once, without actually executing them (during expiration).\nArgument may be either a number (it is then interpreted as millisecond) or a `TimeUnit` object.\n\nTo read about why is this function needed, and why does it require a synchronous API, see: \u003ca href=\"doc/blockingCalls.md\"\u003eblocking calls explaination\u003c/a\u003e.\n\nDoes not return anything. Throws if time cannot be forwarded (e.g. timers were not intercepted yet).\n\n#### `zurvan.setSystemTime(newSystemTime)`\n\nSets values returned by `new Date` and `Date.now` at given point of time (returned values will be of course adjusted with advancing time).\nArgument is expected to be \"castable\" to `Date` - this means a `Date` object, `string` which is valid argument to `Date.parse` or `number` (which is then treated as timestamp).\n\n#### `zurvan.expireAllTimeouts()`\n\nAdvances time up to the point when there is no timeout set any more. Intervals will remain.\n\n_Warning!_ Under certain circumstances this function may result in an infinite loop. Example:\n\n```\nfunction f() {\n  setTimeout(f, 100);\n}\n```\n\nReturns a `Promise` that is resolved when all timeouts are already called or rejected it time cannot be forwarded (e.g. timers were not intercepted yet).\nResolution value is array of callbacks that exited with an exception (if everything went smoothly, it should be empty). If you want `zurvan` to reject\nthe `Promise` in such case, turn `rejectOnCallbackFailure` configuration option to `true`. If you do, it'll be rejected with the array of failed callbacks.\nHowever, if the reason for rejection is different than failed callbacks, it will be rejected with `Error` with proper message.\n\n#### `zurvan.forwardTimeToNextTimer()`\n\nForwards the time to the nearest timer and exipires all timers with same due time.\nResolution value is array of callbacks that exited with an exception (if everything went smoothly, it should be empty). If you want `zurvan` to reject\nthe `Promise` in such case, turn `rejectOnCallbackFailure` configuration option to `true`. If you do, it'll be rejected with the array of failed callbacks.\nHowever, if the reason for rejection is different than failed callbacks, it will be rejected with `Error` with proper message.\n\nReturns a `Promise` that is resolved when all callbacks are executed and event queue is empty or rejected it time cannot be forwarded (e.g. timers were not intercepted yet)..\n\n#### `zurvan.waitForEmptyQueue()`\n\nReturns a `Promise` that is resolved when all immediates are already called or rejected it time cannot be forwarded (e.g. timers were not intercepted yet).\nAlso timers with zero time will be expired.\n\nResolution value is array of callbacks that exited with an exception (if everything went smoothly, it should be empty). If you want `zurvan` to reject\nthe `Promise` in such case, turn `rejectOnCallbackFailure` configuration option to `true`. If you do, it'll be rejected with the array of failed callbacks.\nHowever, if the reason for rejection is different than failed callbacks, it will be rejected with `Error` with proper message.\n\n### TimeUnit\n\nA utility module providing time calculations that are - hopefully - more human-readable than operating on milliseconds everywhere.\nProvide factory functions for `TimeUnit` object, that represents time duration:\n\n- `nanoseconds`\n- `microseconds`\n- `milliseconds`\n- `seconds`\n- `minutes`\n- `hours`\n- `days`\n- `weeks`\n\n`TimeUnit` has the following API methods:\n\n- `unit.extended(unit2)` - returns duration represented by sum of durations of `unit` and `unit2`\n- `unit.shortened(unit2)` - returns duration represented by difference of durations between `unit` and `unit2`\n- `unit.add(unit2)` - mutator. Equal to `unit.setTo(unit.extended(unit2))`\n- `unit.subtract(unit2)` - mutator. Equal to `unit.setTo(unit.shortened(unit2))`\n- `unit.setTo(unit2)` - sets `unit` duration to be equal to duration of `unit2`\n- `unit.copy()` - creates a deep copy of `unit`\n- `unit.isShorterThan(unit2)` - checks if `unit` represents shorter duration than `unit2`\n- `unit.isLongerThan(unit2)` - checks if `unit` represents longer duration than `unit2`\n- `unit.isEqualTo(unit2)` - checks if both `unit` and `unit2` represent same duration, within a reasonable epsilon (current resolution is 10^-15 second)\n\nAll of them work only on `TimeUnit` objects, but work smoothly on cross-unit basis. They do not take into account phenomenons such as leap seconds.\nThis is also the reason why units like `month` and `year` are not provided - because they would be ambigous and complicate the utility. To handle the calendar properly\nmuch bigger library would need to be used.\n\nTimeUnit should be used as object with value semantics.\n\n### Other\n\nThere are no other API functions. All functions and modules in `detail` directory are library internal and are not guaranteed to expose a stable set of methods. Please do not use them directly.\nIf you do - do it at your own risk. But if you do, and you find any of these functions useful (which I doubt - that's why they are in `detail`), contact me to make it part of stable API or extract to a separate library.\n\n## \u003ca name=\"limitations\"\u003e\u003c/a\u003e Limitations\n\nAfter intercepting timers, `Date` object is overridden (if `ignoreDate` configuration option is set to `false`). As a result, some external calls that rely on types may fail.\nThis is because for `var d = new Date()` call `Object.prototype.toString(d)` without `zurvan` will return `[object Date]`, and after timer interception, `[object Object]`.\nPlease \u003ca href=\"https://github.com/Lewerow/zurvan/issues\"\u003efile an issue\u003c/a\u003e if this poses a problem for you.\n\nTo use _Zurvan_ with Node.js 0.10 (before global.Promise was introduced) `promiseScheduler` configuration option has to be set. It's value has to be a valid Promise library,\nfulfilling \u003ca href=\"https://promisesaplus.com/\"\u003ePromises/A+\u003c/a\u003e requirements. An additional constraint is that `.then` cannot be scheduled via global `setTimeout` function, as it is\noverridden by `zurvan`, and this would lead to circular dependencies. It is theoretically possible to cache original `setTimeout` in the library and use it as a scheduler, but please\ndo not do this. There are enough good Promise libraries delivering what you need (\u003ca href=\"https://www.npmjs.com/package/bluebird\"\u003ebluebird\u003c/a\u003e for example).\n\nIf there is no `global.Promise` variable in the environment, `zurvan` will attempt to `require('bluebird')`. If this fails, user must give his own scheduler via `promiseScheduler` configuration option.\nWarning: if there is no `global.Promise` and `bluebird` can be loaded, `bluebird`'s scheduler will be permanently overridden with `setImmediate`. It will be possible to override it again, but `zurvan` will _not_\nkeep track of the previous scheduler in such case. Note that this is mostly important in Node.js 0.10 and virtual environment (without context).\nAgain, if this poses a problem, please \u003ca href=\"https://github.com/Lewerow/zurvan/issues\"\u003efile an issue\u003c/a\u003e.\n\nIf your code does not directly access faked functions (`setTimeout`, `setImmediate` etc.), but caches their original values instead, you need to first require `zurvan`, and later your\nmodule that caches the calls (if it's already included due to earlier `require`s, you can reload it by\n\u003ca href=\"http://stackoverflow.com/questions/9210542/node-js-require-cache-possible-to-invalidate\"\u003eclearing cache\u003c/a\u003e).\nThis is exactly why `bluebird` configuration option is needed if you use it (`bluebird` caches `setImmediate`). This might cause trouble when integrating with external libraries, like `request-promise`\n\nIf your code uses multiple versions of `bluebird` (for example your application uses one version, and one of external packages uses a different one), `zurvan` in version 0.3.2 will not work\nproperly. This is because `bluebird` scheduler needs to be overridden, and current configuration allows only for a single `bluebird`. If this poses a problem, please\n\u003ca href=\"https://github.com/Lewerow/zurvan/issues\"\u003efile an issue on GitHub\u003c/a\u003e.\n\nIf you use time-based events that are scheduled by a mechanism different than `setTimeout` and `setInterval` (for example, an externally bound C++ module), events scheduled with it will _not_\nbe subject to be managed by `zurvan`, i.e. `.waitForEmptyQueue()` will not take them into account, thus race conditions will appear.\n\n## Examples\n\nFor simple examples you can refer to \u003ca href=\"examples\"\u003eexamples\u003c/a\u003e directory.\nFor more complex ones, please refer to \u003ca href=\"tests\"\u003etests\u003c/a\u003e directory.\n\nAll examples are executed at each CI loop, i.e., they have to pass in order for build to succeed. This is a guarantee that they are up-to-date with the actual code.\n\n## \u003ca name=\"requirements\"\u003e\u003c/a\u003e Requirements\n\nObviously, JavaScript environment is much bigger than just Node.js, and you might need to fake timers in other environments, such as the browser.\nIf you do, your environment has to fulfill several requirements:\n\n- implement at least ECMAScript 5 (ES6 is better)\n- have a basic implementation of promises (ES6 promises are sufficient or any basically compatible library - be careful though. Promises shall be implemented as microqueue tasks, or at least scheduled by global `setImmediate` - otherwise,\n  `zurvan` has to be started (not loaded - started. timers have to be intercepted) _before_ promise library in _every_ module they both occur. Additionally, promise library alone cannot be required by any file evaluated before first one requiring _zurvan_)\n  For compatibility options with specific libraries (e.g. \u003ca href=\"https://www.npmjs.com/package/bluebird\"\u003ebluebird\u003c/a\u003e), see: \u003ca href=\"doc/compatibility.md\"\u003ecompatibility options\u003c/a\u003e\n- implement `setImmediate/clearImmediate` - they _cannot_ be implemented as wrappers over `setTimeout/clearTimeout`, at least for now.\n- implement `process.uptime` and `process.hrtime` - if it doesn't, _Zurvan_ has to be ran with compatibility option: `ignoreProcessTimers: true`\n\nSee \u003ca href=\"doc/configuration.md\"\u003econfiguration documentation\u003c/a\u003e to check out possible compatibility options (e.g. evaluating strings in `setTimeout`)\nOf course, if you have trouble with running _Zurvan_ on your custom target, feel free to contact me for support\nBe careful about scheduling - some asynchronous features used by browsers (such as `MutationObserver`, `postMessage`, `requestAnimationFrame`) are not faked by `zurvan`. Since this is only a time-faking library, it fakes only time-based async actions.\nAdditionally, `Promise.resolve` and `Promise.reject` are both specified to be executed asynchronously, but engine implementation is free to use either microqueue or macroqueue. Additionally, if it doesn't use API functions (`setImmediate`) for\nscheduling macroqueue tasks, then there will be cases where _Zurvan_ won't behave correctly. Currently there are no such known cases for Node.js - and if they will be found, they are a bug and shall be fixed.\n\nIf you're trying to run on Node.js older than 0.10 - you will have trouble, as in these Nodes `setImmediate` was not implemented and `process.nextTick` was used to handle the macroqueue. However,\n`process.nextTick` is not a function faked by `zurvan`. Again - contact me if you need support (possibly via \u003ca href=\"https://github.com/Lewerow/zurvan/issues\"\u003eGitHub issues\u003c/a\u003e).\n\n## Notes\n\nAs of version 0.5.1, _Zurvan_ is tested on all main node versions starting from 4.0.\nAs for versions below 4.0, either use _Zurvan_ 0.3.2 or try the new one - I'm doing my best not to make breaking changes, but some new features (such as infinite immediate loop detection) may not work in 0.10. They may also not work depending on\nPromise library used - they are only tested with _Zurvan_ in vanilla Promise mode, and definitely do not work if _Zurvan_ uses _bluebird_ as its scheduler (application may use _bluebird_, that's not a problem). It will generally not work with\nany internal scheduler that relies on setImmediate to schedule promises. It's best not to mess with internal scheduler - it was added to satisfy need of node 0.10 and possibly some web browsers, but should not be used in newer node versions.\n\n## TypeScript\nExperimental types for usage with TypeScript are provided with the package. \nThey are not thoroughly tested, so there may be problems. Please report any trouble you encounter with them as an issue on GitHub.\n\n## Other\n\n_Zurvan_ is available as package on NPM. \n\nName is taken after babilonian deity of infinite time, _Zurvan_. For more details see: \u003chttps://en.wikipedia.org/wiki/Zurvanism\u003e\n\nIf you encouter a bug when using _Zurvan_, please \u003ca href=\"https://github.com/Lewerow/zurvan/issues\"\u003ereport it as an issue on GitHub\u003c/a\u003e. Of course, if you are willing to issue a pull request, it is welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlewowski%2Fzurvan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftlewowski%2Fzurvan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlewowski%2Fzurvan/lists"}