Comments (9)
Hi @vonagam, thank you for this request 👋
I appreciate the time you have taken to make a suggestion to improve vest 🙏
I definitely see the value in debouncing async requests, and that's something that I've seen being asked for multiple times.
I am, though, not fully certain that debouncing should be something that's provided by Vest, but rather can be done in the userland (or consumer-land, rather), and there are several main reasons for that:
-
Debouncing can (and often should) be done on two different instances:
A. On keystroke - whenever a user types within a field
B. On Async server call.
While Vest could obviously handle both (one on the suite entry, and one on the async field), I think it might more complexity and another level of unexpectedness to how Vest operates. -
Debouncing is not the only volume control function we may use. Along with Debouncing, people often ask for Throttling, which is its more primitive sibling. Adding both will significantly increase the cognitive load of the library.
-
As you've experienced yourself, turning the last argument to an options object makes it more verbose, and change reduce some of the simplicity introduced by Vest. From having the optional fourth argument reserved for reordering only, we need to now use it in multiple scenarios.
-
One last thing, while useful, debounce might not be used by most users of the library. Adding it as an optional to the
test
function, will make it so that the debouncing logic and capabilities will be added to the core of the library and take up (even if just a little) space and increase the bundle size. -
Technically, with debounce, the function needs to be wrapped with debounce in advance, and not written inline, since if it was written in-line, every run would create a new instance of it. Handling this within Vest is possible by caching the first (or last) version of the test function, but this, too, requires some thinking on how it should be done so it does not cause unexpe
All these do not mean I do not see the value in debouncing, but rather, I believe debouncing should be introduced in a different way. A suggestion would be to introduce debouncing as a built-in vest utility, like classnames and parser, so that you could import it separately, something like:
import {test, debounce, enforce} from 'vest';
// ...
test("username", "username is already taken", testUserAlreadyTakenDebounced(data));
// ...
const testUserAlreadyTakenDebounced = debounce(function testUserAlreadyTaken(data) {/*....*/})
What do you think?
from vest.
- ... I think it might more complexity and another level of unexpectedness to how Vest operates.
New functionality is more complexity, understandable, but I don't see how it can increase unexpectedness.
- Debouncing is not the only volume control function we may use. Along with Debouncing, people often ask for Throttling, which is its more primitive sibling. Adding both will significantly increase the cognitive load of the library.
Usage of throttling does not seem proper for validations to me. What happens when a new value arrives and a test call is discarded because of throttling: Does an error for a previous value stays in place even though new value is valid (and other way around old right -> new wrong)? Looks like a bad idea to me... (Also maybe we are talking about different implementations, because I wouldn't call throttling more primitive compared to debounce, they are almost identical, except maybe that debounce does not need to store a result of previous invocation.)
- As you've experienced yourself, turning the last argument to an options object makes it more verbose, and change reduce some of the simplicity introduced by Vest. From having the optional fourth argument reserved for reordering only, we need to now use it in multiple scenarios.
Well, current way with test.memo
works only if you have really small number of modificators that cannot overlap. Since for some cases (like username) one might want to use both memo and debounce there is a need for a way to provide both options. I also assume that with time you might get more functionality like that, so makes sense to think how it should be implemented. Agree that options object does increase verbosity, but it is not expected to be used that often.
- One last thing, while useful, debounce might not be used by most users of the library.
Do agree, but I don't think that debounce is very different from memo. They exist to cover the same cases and debounce is actually easier to implement - memo needs to keep results, keep inputs of previous invocations and check those inputs on every call and have an eviction policy (currently it is hard coded to 10 elements max, perhaps if there were options it could have been configured) while debounce only need to store one integer and do setTimeout
/clearTimeout
with it. So my question about that - do you consider memo and debounce to be on equal footing and resulting solutions applicable to both of them or do you think that memo is more deserving to be part of the core compared to debounce and if yes, why?
- Technically, with debounce, the function needs to be wrapped with debounce in advance, and not written inline, since if it was written in-line, every run would create a new instance of it. Handling this within Vest is possible by caching the first (or last) version of the test function, but this, too, requires some thinking on how it should be done so it does not cause unexpe.. (text is missing after that)
If it is a part of a test (like memo is) then it is the same. Only a timer id for last invocation needs to be stored.
A suggestion would be to introduce debouncing as a built-in vest utility, like classnames and parser, so that you could import it separately
Seems like a good idea if it is possible to do so.
But the shown example has problems - a) it is more verbose than options variant since you would need to import an additional thing, create/name/wrap a test function outside of a suite and then use it in a test, b) debouncing state (timer id) is stored inside the function itself, not suite, so the function cannot be used in multiple suites (unexpected part), c) it will not work with test.memo
since memo will save a promise which will never resolve if debouncing happens.
If we go with decoupling option then this is what I would ideally want to work:
import {test, memo, debounce} from 'vest';
test("username", "username is already taken", debounce(memo([data.username], () => {
// ...
})));
Three "wishes" here:
- If debounce is in utils, so is memo.
- The state is stored in the test context, so is it possible to move a test function definition out of a suite for small performance gain but it is not required.
- Debounce should be able to work with memo.
from vest.
Related Issues (20)
- Getting error `unexpected token export` when running with Jest
- Dynamic fields HOT 6
- Vest@5 is ready! Help test it!
- Last next release does not include development builds in dist HOT 4
- Pending info in summary HOT 7
- Omit without when HOT 5
- Add rule `isValueOf` HOT 5
- Suite test not working on IE11 HOT 11
- using compose with isArrayOf throws error HOT 2
- [Documentation] Cannot scroll some pages / Chrome HOT 1
- [EASY] Add singular form error selectors HOT 6
- Validation errors only after "touched" HOT 4
- Field is considered `valid` when it has tests both inside and outside omitWhen
- Why `enforce(new Date()).isNotEmpty()` throws HOT 2
- Incorrect paths in typing HOT 5
- better TS support HOT 12
- feat: Strict Mode HOT 6
- Does vest supports any integation with zod?
- feat: Detect if property is in test suite HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vest.