From 1f88f3d1ea802f92abfff7135365b8db092148eb Mon Sep 17 00:00:00 2001 From: Glen Keane Date: Thu, 8 Oct 2026 13:38:04 +0100 Subject: [PATCH] chore!: prepare dependency-free version 3 package --- LICENSE | 21 ++++ package-lock.json | 14 +-- package.json | 22 +++-- readme.md | 243 ++++++++++++++++++---------------------------- when.js | 2 - 5 files changed, 132 insertions(+), 170 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d58e674 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2015 Glen Keane + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package-lock.json b/package-lock.json index 49e685b..4a0916d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,16 @@ { "name": "when-conditional", - "version": "2.0.0", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "when-conditional", - "version": "2.0.0", + "version": "3.0.0", "license": "MIT", - "dependencies": { - "setimmediate": "^1.0.2" + "engines": { + "node": ">=22.13.0" } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "license": "MIT" } } } diff --git a/package.json b/package.json index 6ed7a7c..b4de0ea 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,27 @@ { "name": "when-conditional", - "version": "2.0.0", - "description": "A simple little asyncronous if check and conditional method", + "version": "3.0.0", + "description": "Poll a synchronous condition and run a callback when it becomes truthy.", "main": "when.js", + "type": "commonjs", + "files": [ + "when.js" + ], + "engines": { + "node": ">=22.13.0" + }, "scripts": { "test": "node --test test/*.js" }, "repository": { "type": "git", - "url": "https://github.com/thekemkid/when-conditional.git" + "url": "git+https://github.com/GlenTiki/when-conditional.git" }, "keywords": [ "if", "when", "async", - "asyncronous", + "polling", "utility", "condition", "conditional" @@ -22,10 +29,7 @@ "author": "Glen Keane", "license": "MIT", "bugs": { - "url": "https://github.com/thekemkid/when-conditional/issues" + "url": "https://github.com/GlenTiki/when-conditional/issues" }, - "homepage": "https://github.com/thekemkid/when-conditional", - "dependencies": { - "setimmediate": "^1.0.2" - } + "homepage": "https://github.com/GlenTiki/when-conditional#readme" } diff --git a/readme.md b/readme.md index 965fcdc..262e336 100644 --- a/readme.md +++ b/readme.md @@ -1,149 +1,94 @@ -# When-conditional ------------------------ - -A utility library for asyncronous conditional checking, and then running a callback when the condition is true. - -To get started, type the following: - -`npm install when-conditional` - -## Syntax ------------------------- - -``` -when(logicStatement, callback) -``` - -#### Parameters - -###### logicStatement -A function which should `return` a `truthy` statement. The return is equivalent to what you would put in an `if` statement. - -###### callback -A function which is called when the logicStatement function returns a truthy value. - -#### Returns a when object with 4 functions: -###### `whenObj.clear()`: A function to clear the when statement, if you don't want to wait for the condition to be true anymore. -###### `whenObj.reset()`: This is for when you need reset the whenObj after it fired the code, and wait for the same condition again. -###### `whenObj.setCondition(newCondition)`: Overwrite the `condition` function you passed in on creation. -###### `whenObj.setCode(newCode)`: Overwrite the `code` function you passed in on creation. - -## Examples ------------------------- -The example code shown below will print out someVar is false a number of times until it becomes true, then will tell you its true and exit. - -```javascript -var when = require('when-conditional'); -var someVar = false; - -var interval = setInterval(function(){ - console.log("someVar is " + someVar); - if(someVar === true) clearInterval(interval); -}, 1000); - -when(function condition(){ - return (someVar === true); -}, function code(){ - console.log("someVar is now true, and this was only triggered when it became true!"); -}); - -setTimeout(function(){ - someVar = true; -}, 10000); - -``` - -### Removing the when listener ---------------------- - -You might feel that you no longer need to wait for something to happen. if this is the case, you can call a `.clear()` function on the return value of `when(condition, code)`. - -The following example is very similar to the one above, but will never print `someVar is now true, and this was only triggered when it became true!` as it is no longer waiting for `when` someVar is true! - -```javascript -var when = require('when-conditional'); -var someVar = false; - -var interval = setInterval(function(){ - console.log("someVar is " + someVar); - if(someVar === true) clearInterval(interval); -}, 1000); - -var whenObj = when(function condition(){ - return (someVar === true); -}, function code(){ - console.log("someVar is now true, and this was only triggered when it became true!"); -}); - -setTimeout(function(){ - someVar = true; -}, 10000); - -setTimeout(function(){ - whenObj.clear(); -}, 5000); -``` - -### reseting the when listener and changing the code callback. - -```javascript -var when = require('when-conditional'); -var someVar = false; - -var interval = setInterval(function(){ - console.log("someVar is " + someVar); - if(someVar === true) clearInterval(interval); -}, 1000); - -var whenObj = when(function condition(){ - return (someVar === true); -}, function code(){ - console.log("someVar is now true, and this was only triggered when it became true!"); -}); - -setTimeout(function(){ - someVar = true; -}, 10000); - -setTimeout(function(){ - whenObj.clear(); -}, 5000); - -setTimeout(function(){ - whenObj.reset(); - whenObj.setCode(function newCodeCB(){ - console.log("someVar is now true, and this was only triggered when it became true, AND after the when was reset AND after the code callback was changed!"); - }); -}, 8000); -``` - -## Contributing --------------------- - -If you feel there is a feature missing you would like to see, or an issue, feel free to log an issue on Github, or even better, send a PR! :D - -## Inspiration ---------------------- - -I wanted an asyncronous if statement that only fired once the condition became true, but I couldn't extend the engine natively. - -The example code above should similar to something like: - -```javascript -var someVar = false; - -when(someVar === true){ - console.log("someVar is now true, and this was only triggered when it became true!"); -} - -setTimeout(function(){ - someVar = true; -}, 10000) -``` - -To get my little shim working, I check the condition every tick. this is not ideal. ideally, I want to Object.observe the conditions, and only fire the `when` check once when the conditions have been observed to change - -The when-method module is expected to be more efficient than an interval. - -## See you when-ever! -Copyright Glen Keane - 2015 - MIT Licence +# when-conditional + +Check a synchronous condition until it becomes truthy, then call a callback once. + +```sh +npm install when-conditional +``` + +Requires Node.js 22.13 or later. CI tests Node.js 22, 24 and 26. Browsers need a bundler that accepts CommonJS and a JavaScript environment that supports ES2022 and standard timers. This package does not install global polyfills. + +## Usage + +```js +const when = require("when-conditional"); + +let ready = false; +const controller = when( + () => ready, + () => console.log("Ready"), + { interval: 10 }, +); + +setTimeout(() => { + ready = true; +}, 100); +``` + +Native ES modules can use `import when from 'when-conditional'`. + +## API + +### `when(condition, code, { interval = 10 } = {})` + +Both `condition` and `code` must be functions. The first condition check runs synchronously. If it returns a truthy value, `code()` runs before `when()` returns. The callback's return value is ignored. + +When the condition is false, another check runs after the configured interval. `interval` is a positive integer in milliseconds, from `1` to `2147483647`. It defaults to `10`. Timer delays are not exact deadlines; a busy event loop can delay a check. + +Conditions must return synchronous values. Promise results and values with a callable `then` property raise a `TypeError`, even if they would resolve to `false`. The package consumes their rejection through `Promise.resolve()`, which also invokes a custom thenable's `then` method. It does not wait for their result. + +A predicate error stops that polling chain. Errors in the initial check or a synchronous `reset()` check throw to the caller. Errors during a later check throw from the timer callback. There is no asynchronous error callback. + +### `controller.clear()` + +Cancel future checks. Repeated calls are safe. Calling `clear()` inside the condition also discards that check's result, so it cannot invoke the callback or schedule another check. + +There is no timeout. Call `clear()` when you no longer need to wait. An active polling timer keeps Node.js running. + +### `controller.reset()` + +Cancel the current check cycle and check the condition again synchronously. Use this after cancellation or completion to wait again. + +Calling `reset()` inside the condition invalidates the old check's result. Only the new cycle can complete or schedule another check. A condition that always calls `reset()` recursively can exhaust the call stack. + +### `controller.setCondition(condition)` + +Replace the condition function. This does not run it immediately or restart a cancelled or completed controller. A non-function raises a `TypeError`. + +### `controller.setCode(code)` + +Replace the callback function. This does not restart a cancelled or completed controller. A non-function raises a `TypeError`. + +## Cancellation example + +```js +const controller = when( + () => connection.isReady(), + () => connection.send(message), + { interval: 50 }, +); + +controller.clear(); +controller.setCondition(() => replacementConnection.isReady()); +controller.setCode(() => replacementConnection.send(message)); +controller.reset(); +``` + +Set replacement functions before `reset()`: its synchronous check can call the callback immediately. + +## Migration from version 2 + +Version 3 polls every 10 ms by default instead of on every event-loop turn. Pass an explicit `interval` if you need a different delay. The first check and each reset still run synchronously. + +Version 3 requires Node.js 22.13 or later and removes the `setimmediate` polyfill dependency. It validates functions and interval values, and rejects Promise and thenable predicate results. Callers that relied on those results being truthy must use a synchronous condition instead. + +## Contributing + +1. Run `npm ci` to install the checkout. +2. Run `npm test` to run the tests. + +Report bugs or propose changes on [GitHub](https://github.com/GlenTiki/when-conditional). + +## License + +[MIT](LICENSE), copyright 2015 Glen Keane. diff --git a/when.js b/when.js index 08ac99e..de748e0 100644 --- a/when.js +++ b/when.js @@ -1,5 +1,3 @@ -require("setimmediate"); - function when(condition, code, options = {}) { assertFunction(condition, "condition"); assertFunction(code, "code");