mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-01 17:57:36 +08:00
This also adds Python-2.0 to the list of accepted licenses. Lastly, it fixes a bug where the package.json files were incorrectly reordered. For the `exports` of a particular package, the order that the entrypoints are defined in is crucial. Therefore, we should not alter the order of entrypoints and instead maintain the originally defined ordering. We can use an `OrderedDict` to ensure that Python always loads the JSON files in the same order. DISABLE_THIRD_PARTY_CHECK=NPM update R=jacktfranklin@chromium.org Bug: none Change-Id: I5a309782de6015edea6ba3b502aa0db1f008d973 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2692909 Auto-Submit: Tim van der Lippe <tvanderlippe@chromium.org> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
72 lines
2.7 KiB
JavaScript
72 lines
2.7 KiB
JavaScript
import crypto from 'crypto'
|
||
|
||
import { urlAlphabet } from '../url-alphabet/index.js'
|
||
|
||
// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`,
|
||
// because it is possible to use in combination with `Buffer.allocUnsafe()`.
|
||
let random = bytes =>
|
||
new Promise((resolve, reject) => {
|
||
// `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory.
|
||
// Memory flushing is unnecessary since the buffer allocation itself resets
|
||
// the memory with the new bytes.
|
||
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
|
||
if (err) {
|
||
reject(err)
|
||
} else {
|
||
resolve(buf)
|
||
}
|
||
})
|
||
})
|
||
|
||
let customAlphabet = (alphabet, size) => {
|
||
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
||
// values closer to the alphabet size. The bitmask calculates the closest
|
||
// `2^31 - 1` number, which exceeds the alphabet size.
|
||
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
||
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
||
// Though, the bitmask solution is not perfect since the bytes exceeding
|
||
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
||
// the random bytes redundancy has to be satisfied.
|
||
|
||
// Note: every hardware random generator call is performance expensive,
|
||
// because the system call for entropy collection takes a lot of time.
|
||
// So, to avoid additional system calls, extra bytes are requested in advance.
|
||
|
||
// Next, a step determines how many random bytes to generate.
|
||
// The number of random bytes gets decided upon the ID size, mask,
|
||
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
||
// according to benchmarks).
|
||
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
|
||
|
||
let tick = id =>
|
||
random(step).then(bytes => {
|
||
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
||
let i = step
|
||
while (i--) {
|
||
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
||
id += alphabet[bytes[i] & mask] || ''
|
||
if (id.length === size) return id
|
||
}
|
||
return tick(id)
|
||
})
|
||
|
||
return () => tick('')
|
||
}
|
||
|
||
let nanoid = (size = 21) =>
|
||
random(size).then(bytes => {
|
||
let id = ''
|
||
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
||
while (size--) {
|
||
// It is incorrect to use bytes exceeding the alphabet size.
|
||
// The following mask reduces the random byte in the 0-255 value
|
||
// range to the 0-63 value range. Therefore, adding hacks, such
|
||
// as empty string fallback or magic numbers, is unneccessary because
|
||
// the bitmask trims bytes down to the alphabet size.
|
||
id += urlAlphabet[bytes[size] & 63]
|
||
}
|
||
return id
|
||
})
|
||
|
||
export { nanoid, customAlphabet, random }
|