Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES-Module support (next) #337

Merged
merged 4 commits into from Dec 3, 2019
Merged

ES-Module support (next) #337

merged 4 commits into from Dec 3, 2019

Conversation

ctavan
Copy link
Member

@ctavan ctavan commented Oct 16, 2019

This is #331 but against the next branch instead of master.

@ctavan ctavan requested a review from broofa October 16, 2019 18:51
@ctavan ctavan mentioned this pull request Oct 16, 2019
@43081j
Copy link

43081j commented Oct 18, 2019

Back when i did this too, i made the original sources browser ready and only had a build for producing a commonjs version.

Did you consider this? It does mean any node specific things need to be dropped or conditionally used somehow (i.e. crypto).

@ctavan
Copy link
Member Author

ctavan commented Oct 19, 2019

@43081j yes, I did consider this. However I believe that this approach only really works with universal modules that don't have node- or browser-specific dependencies.

What would you suggest with respect to random number generation? It is absolutely vital that uuid uses a cryptographically secure pseudo-random number generator (CSPRNG) under the hood and so far the JavaScript language does not provide one so we have to rely on platform specific APIs like node's crypto module or WebCrypto in the browser.

So unfortunately I think in the case of uuid we will have to ship different builds for use in node and in the browser (until something like https://github.com/tc39/proposal-uuid gets through which might add a cryptographically secure pseudo-random number generator (CSPRNG) directly to the JavaScript language).

@@ -8,11 +8,13 @@
var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can fix a number of issues here by distilling the implementation of this file down to:

export default function() {
  if (Math.getRandomValues) {
    return Math.getRandomValues(new UInt8Array(16));
  } else if (typeof(crypto) != 'undefined' && crypto.getRandomValues) {
    return crypto.getRandomValues(new UInt8Array(16));
  } else if (typeof(msCrypto) != 'undefined' &&  && msCrypto.getRandomValues) {
    return msCrypto.getRandomValues(new UInt8Array(16));
  }

  // TODO: Add README verbiage describing error and how to resolve by providing user-supplied rng function
  throw Error('Unable to locate getRandomValues() API.  See https://github.com/kelektiv/node-uuid#secure-api');
}

By not caching a reference to getRandomValues it becomes trivial for uses to supply their own implementation as needed. There's probably a modest perf penalty to feature sniffing this on each call but I don't think it's a significant concern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@broofa I'm all-in for this change, however I intentionally tried to not introduce any functional change within this pull request but instead exclusively get the switch to esmodules done before working on functionality changes.

Would you be fine with merging this PR first? I will make sure to implement your above suggestion in a follow-up PR and I absolutely agree, that we should fix #173 before releasing a next major versions.

Let's just finalize the es module switch first so we have smaller, easier-to-review pull requests for the functional changes.

@@ -0,0 +1,5 @@
import crypto from 'crypto';

export default function nodeRNG() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export default function nodeRNG() {
export default function() {

Look for Math.getRandomValues() here, as above?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wait with functional changes for a follow-up PR.

broofa and others added 4 commits October 25, 2019 21:58
BREAKING CHANGE: Convert code base to ECMAScript Modules (ESM) and
release CommonJS build for node and ESM build for browser bundlers.
@ctavan
Copy link
Member Author

ctavan commented Oct 31, 2019

@broofa would it be OK for you to merge this issue without changing the RNG-behavior yet?

I have outlined my roadmap for the next major release in #343 (feedback very welcome!) and I would like to establish some browser tests before changing the API!

The only planned API change in this case is to make insecure RNGs opt-in.

Copy link
Member

@broofa broofa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Sorry for the long wait on this - 'been vacationing with the 'fam. 🤷‍♂

@ctavan ctavan merged commit e6c9e44 into uuidjs:next Dec 3, 2019
@ctavan ctavan deleted the esm branch December 3, 2019 21:27
@ctavan ctavan mentioned this pull request Jan 20, 2020
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants