Arbitrary-precision decimals without `Math.random`
I needed to perform some arithmetic (safely)—specifically, I needed to convert a JS
number
representing dollars into a JS number
representing cents. I tried using https://github.com/MikeMcl/bignumber.js for this in a mutation, but discovered that it imports Math.random
. I ended up settling for https://github.com/MikeMcl/decimal.js-light, which is just a trimmed-down version of https://github.com/MikeMcl/decimal.js (yes, these are all written by the same person—and those aren't even all of the arbitrary-precision decimal libraries he maintains!), as it happens to not import Math.random
, and still accomplishes all of what I need.
I guess this is either a question or an offering of advice—the question is: is anyone aware of another library I ought to have considered for this task (I can't imagine I'll be the only Convex user to have this requirement)? And the offering is: if anyone is looking for such a library, I can confirm that https://github.com/MikeMcl/decimal.js-light works!7 Replies
What's the concern with using
Math.random
here? Convex queries and mutations should provide Math.random
(but we just use the same seed each time we run a particular query / mutation)Oh, I guess I misunderstood the constraints here, then. The concern was that Convex bundling was failing, with some language about
Math.random
!
I can test it again in a little bit and report back with the actual error message I was observing
Here it is:
thanks for sharing! this part looks interesting https://github.com/MikeMcl/bignumber.js/blob/master/bignumber.mjs#L665. we currently don't allow
Math.random()
at import time, because nondeterminism could mess with our function analysis. It's a contrived example, but const myFunction = Math.random() > 0.5 ? query(...) : mutation(...)
would be hard to detect & handle. We've received this feature request before though, and we would like to make npm packages like bignumber libraries work. will keep you updated 🙂GitHub
bignumber.js/bignumber.mjs at master · MikeMcl/bignumber.js
A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic - bignumber.js/bignumber.mjs at master · MikeMcl/bignumber.js
I see, so
Math.random()
being invoked at import time is not permitted, but Math.random()
invocations at runtime are? I suppose I forgot that JS imports might evaluate code 😰so Math.random() being invoked at import time is not permitted, but Math.random() invocations at runtime are?yup exactly Sounds like you have the trimmed down version that does what you want, but another potential workaround would be doing something like
require("bignumber.js")
within your mutation so it executes all those Math.random
calls while executing your mutation (I tried this successfully now, but don't fully understand whether this would always work)I do, but good to keep in mind as another possible option!
We now allow using Math.random at import time. The randomness for the global scope is frozen at deploy time. Hopefully, a lot of the libraries you tried before just work now in Convex's JS environment without additional gymnastics.