nanoid 2.1.7 → 2.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](http://semver.org/).
3
3
 
4
+ ## 2.1.11
5
+ * Reduce size (by Anton Evzhakov).
6
+
7
+ ## 2.1.10
8
+ * Reduce size by 10% (by Anton Khlynovskiy).
9
+
10
+ ## 2.1.9
11
+ * Reduce `format` and `async/format` size (by Dair Aidarkhanov).
12
+
13
+ ## 2.1.8
14
+ * Improve React docs (by Nahum Zsilva).
15
+
4
16
  ## 2.1.7
5
17
  * Reduce `index`, `async` and `non-secure` size (by @polemius).
6
18
 
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  A tiny, secure, URL-friendly, unique string ID generator for JavaScript.
7
7
 
8
- * **Small.** 137 bytes (minified and gzipped). No dependencies.
8
+ * **Small.** 119 bytes (minified and gzipped). No dependencies.
9
9
  [Size Limit] controls the size.
10
10
  * **Safe.** It uses cryptographically strong random APIs.
11
11
  Can be used in clusters.
@@ -62,8 +62,8 @@ There are three main differences between Nano ID and UUID v4:
62
62
 
63
63
  1. Nano ID uses a bigger alphabet, so a similar number of random bits
64
64
  are packed in just 21 symbols instead of 36.
65
- 2. Nano ID code is 3 times less than `uuid/v4` package:
66
- 137 bytes instead of 435.
65
+ 2. Nano ID code is 4 times less than `uuid/v4` package:
66
+ 119 bytes instead of 435.
67
67
  3. Because of memory allocation tricks, Nano ID is 16% faster than UUID.
68
68
 
69
69
 
@@ -176,13 +176,12 @@ between renders. This is bad code:
176
176
  <Item key={nanoid()} /> /* DON’T DO IT */
177
177
  ```
178
178
 
179
- This is good code. `this.id` will be generated only once:
179
+ This is good code. `id` will be generated only once:
180
180
 
181
181
  ```jsx
182
- id = nanoid()
183
- render () {
184
- return <Item key={this.id}>;
185
- }
182
+ const Element = () => {
183
+ const [id] = React.useState(nanoid)
184
+ return <Item key={id}>
186
185
  }
187
186
  ```
188
187
 
@@ -1,12 +1,38 @@
1
+ // This file replaces `async/format.js` in bundlers like webpack or Rollup,
2
+ // according to `browser` config in `package.json`.
3
+
1
4
  module.exports = function (random, alphabet, size) {
2
- var mask = (2 << 31 - Math.clz32((alphabet.length - 1) | 1)) - 1
3
- var step = Math.ceil(1.6 * mask * size / alphabet.length)
5
+ // We can’t use bytes bigger than the alphabet. To make bytes values closer
6
+ // to the alphabet, we apply bitmask on them. We look for the closest
7
+ // `2 ** x - 1` number, which will be bigger than alphabet size. If we have
8
+ // 30 symbols in the alphabet, we will take 31 (00011111).
9
+ // We do not use faster Math.clz32, because it is not available in browsers.
10
+ var mask = (2 << Math.log(alphabet.length - 1) / Math.LN2) - 1
11
+ // Bitmask is not a perfect solution (in our example it will pass 31 bytes,
12
+ // which is bigger than the alphabet). As a result, we will need more bytes,
13
+ // than ID size, because we will refuse bytes bigger than the alphabet.
14
+
15
+ // Every hardware random generator call is costly,
16
+ // because we need to wait for entropy collection. This is why often it will
17
+ // be faster to ask for few extra bytes in advance, to avoid additional calls.
18
+
19
+ // Here we calculate how many random bytes should we call in advance.
20
+ // It depends on ID length, mask / alphabet size and magic number 1.6
21
+ // (which was selected according benchmarks).
22
+
23
+ // -~f => Math.ceil(f) if n is float number
24
+ // -~i => i + 1 if n is integer number
25
+ var step = -~(1.6 * mask * size / alphabet.length)
4
26
 
5
27
  function tick (id) {
6
28
  return random(step).then(function (bytes) {
29
+ // Compact alternative for `for (var i = 0; i < step; i++)`
7
30
  var i = step
8
31
  while (i--) {
32
+ // If random byte is bigger than alphabet even after bitmask,
33
+ // we refuse it by `|| ''`.
9
34
  id += alphabet[bytes[i] & mask] || ''
35
+ // More compact than `id.length + 1 === size`
10
36
  if (id.length === +size) return id
11
37
  }
12
38
  return tick(id)
package/async/format.js CHANGED
@@ -29,14 +29,33 @@
29
29
  * @function
30
30
  */
31
31
  module.exports = function (random, alphabet, size) {
32
- var mask = (2 << Math.log(alphabet.length - 1) / Math.LN2) - 1
32
+ // We can’t use bytes bigger than the alphabet. To make bytes values closer
33
+ // to the alphabet, we apply bitmask on them. We look for the closest
34
+ // `2 ** x - 1` number, which will be bigger than alphabet size. If we have
35
+ // 30 symbols in the alphabet, we will take 31 (00011111).
36
+ var mask = (2 << 31 - Math.clz32((alphabet.length - 1) | 1)) - 1
37
+ // Bitmask is not a perfect solution (in our example it will pass 31 bytes,
38
+ // which is bigger than the alphabet). As a result, we will need more bytes,
39
+ // than ID size, because we will refuse bytes bigger than the alphabet.
40
+
41
+ // Every hardware random generator call is costly,
42
+ // because we need to wait for entropy collection. This is why often it will
43
+ // be faster to ask for few extra bytes in advance, to avoid additional calls.
44
+
45
+ // Here we calculate how many random bytes should we call in advance.
46
+ // It depends on ID length, mask / alphabet size and magic number 1.6
47
+ // (which was selected according benchmarks).
33
48
  var step = Math.ceil(1.6 * mask * size / alphabet.length)
34
49
 
35
50
  function tick (id) {
36
51
  return random(step).then(function (bytes) {
52
+ // Compact alternative for `for (var i = 0; i < step; i++)`
37
53
  var i = step
38
54
  while (i--) {
55
+ // If random byte is bigger than alphabet even after bitmask,
56
+ // we refuse it by `|| ''`.
39
57
  id += alphabet[bytes[i] & mask] || ''
58
+ // More compact than `id.length + 1 === size`
40
59
  if (id.length === +size) return id
41
60
  }
42
61
  return tick(id)
@@ -1,17 +1,37 @@
1
+ // This file replaces `async/index.js` in bundlers like webpack or Rollup,
2
+ // according to `browser` config in `package.json`.
3
+
1
4
  var crypto = self.crypto || self.msCrypto
2
5
 
3
- /*
4
- * This alphabet uses a-z A-Z 0-9 _- symbols.
5
- * Symbols order was changed for better gzip compression.
6
- */
7
- var url = 'IUint8Ar21ModulvezGFYPCJ7_p0V4XSymbLBNH6fTqQ35xD9ZREghasOw-cjkWK'
6
+ // This alphabet uses a-z A-Z 0-9 _- symbols.
7
+ // Symbols are generated for smaller size.
8
+ // -_zyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA
9
+ var url = '-_'
10
+ // Loop from 36 to 0 (from z to a and 9 to 0 in Base36).
11
+ var i = 36
12
+ while (i--) {
13
+ // 36 is radix. Number.prototype.toString(36) returns number
14
+ // in Base36 representation. Base36 is like hex, but it uses 0–9 and a-z.
15
+ url += i.toString(36)
16
+ }
17
+ // Loop from 36 to 10 (from Z to A in Base36).
18
+ i = 36
19
+ while (i-- - 10) {
20
+ url += i.toString(36).toUpperCase()
21
+ }
8
22
 
9
23
  module.exports = function (size) {
10
- size = size || 21
11
24
  var id = ''
12
- var bytes = crypto.getRandomValues(new Uint8Array(size))
13
- while (size--) {
14
- id += url[bytes[size] & 63]
25
+ var bytes = crypto.getRandomValues(new Uint8Array(size || 21))
26
+ i = size || 21
27
+
28
+ // Compact alternative for `for (var i = 0; i < size; i++)`
29
+ while (i--) {
30
+ // We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
31
+ // This mask reduces random byte 0-255 to 0-63 values.
32
+ // There is no need in `|| ''` and `* 1.6` hacks in here,
33
+ // because bitmask trim bytes exact to alphabet size.
34
+ id += url[bytes[i] & 63]
15
35
  }
16
36
  return Promise.resolve(id)
17
37
  }
package/async/index.js CHANGED
@@ -24,7 +24,12 @@ module.exports = function (size) {
24
24
  size = size || 21
25
25
  return random(size).then(function (bytes) {
26
26
  var id = ''
27
+ // Compact alternative for `for (var i = 0; i < size; i++)`
27
28
  while (size--) {
29
+ // We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
30
+ // This mask reduces random byte 0-255 to 0-63 values.
31
+ // There is no need in `|| ''` and `* 1.6` hacks in here,
32
+ // because bitmask trim bytes exact to alphabet size.
28
33
  id += url[bytes[size] & 63]
29
34
  }
30
35
  return id
@@ -1,3 +1,6 @@
1
+ // This file replaces `async/random.js` in bundlers like webpack or Rollup,
2
+ // according to `browser` config in `package.json`.
3
+
1
4
  var crypto = self.crypto || self.msCrypto
2
5
 
3
6
  module.exports = function (bytes) {
package/async/random.js CHANGED
@@ -1,8 +1,12 @@
1
1
  var crypto = require('crypto')
2
2
 
3
3
  if (crypto.randomFill) {
4
+ // `crypto.randomFill()` is a little fatser than `crypto.randomBytes()`,
5
+ // because we can use faster `Buffer.allocUnsafe()`.
4
6
  module.exports = function (bytes) {
5
7
  return new Promise(function (resolve, reject) {
8
+ // `Buffer.allocUnsafe()` faster because it don’t clean memory.
9
+ // We do not need it, since we will fill memory with new bytes anyway.
6
10
  crypto.randomFill(Buffer.allocUnsafe(bytes), function (err, buf) {
7
11
  if (err) {
8
12
  reject(err)
package/format.browser.js CHANGED
@@ -1,13 +1,39 @@
1
+ // This file replaces `format.js` in bundlers like webpack or Rollup,
2
+ // according to `browser` config in `package.json`.
3
+
1
4
  module.exports = function (random, alphabet, size) {
5
+ // We can’t use bytes bigger than the alphabet. To make bytes values closer
6
+ // to the alphabet, we apply bitmask on them. We look for the closest
7
+ // `2 ** x - 1` number, which will be bigger than alphabet size. If we have
8
+ // 30 symbols in the alphabet, we will take 31 (00011111).
9
+ // We do not use faster Math.clz32, because it is not available in browsers.
2
10
  var mask = (2 << Math.log(alphabet.length - 1) / Math.LN2) - 1
3
- var step = Math.ceil(1.6 * mask * size / alphabet.length)
11
+ // Bitmask is not a perfect solution (in our example it will pass 31 bytes,
12
+ // which is bigger than the alphabet). As a result, we will need more bytes,
13
+ // than ID size, because we will refuse bytes bigger than the alphabet.
14
+
15
+ // Every hardware random generator call is costly,
16
+ // because we need to wait for entropy collection. This is why often it will
17
+ // be faster to ask for few extra bytes in advance, to avoid additional calls.
18
+
19
+ // Here we calculate how many random bytes should we call in advance.
20
+ // It depends on ID length, mask / alphabet size and magic number 1.6
21
+ // (which was selected according benchmarks).
22
+
23
+ // -~f => Math.ceil(f) if n is float number
24
+ // -~i => i + 1 if n is integer number
25
+ var step = -~(1.6 * mask * size / alphabet.length)
4
26
  var id = ''
5
27
 
6
28
  while (true) {
29
+ var bytes = random(step)
30
+ // Compact alternative for `for (var i = 0; i < step; i++)`
7
31
  var i = step
8
- var bytes = random(i)
9
32
  while (i--) {
33
+ // If random byte is bigger than alphabet even after bitmask,
34
+ // we refuse it by `|| ''`.
10
35
  id += alphabet[bytes[i] & mask] || ''
36
+ // More compact than `id.length + 1 === size`
11
37
  if (id.length === +size) return id
12
38
  }
13
39
  }
package/format.js CHANGED
@@ -27,15 +27,34 @@
27
27
  * @function
28
28
  */
29
29
  module.exports = function (random, alphabet, size) {
30
+ // We can’t use bytes bigger than the alphabet. To make bytes values closer
31
+ // to the alphabet, we apply bitmask on them. We look for the closest
32
+ // `2 ** x - 1` number, which will be bigger than alphabet size. If we have
33
+ // 30 symbols in the alphabet, we will take 31 (00011111).
30
34
  var mask = (2 << 31 - Math.clz32((alphabet.length - 1) | 1)) - 1
35
+ // Bitmask is not a perfect solution (in our example it will pass 31 bytes,
36
+ // which is bigger than the alphabet). As a result, we will need more bytes,
37
+ // than ID size, because we will refuse bytes bigger than the alphabet.
38
+
39
+ // Every hardware random generator call is costly,
40
+ // because we need to wait for entropy collection. This is why often it will
41
+ // be faster to ask for few extra bytes in advance, to avoid additional calls.
42
+
43
+ // Here we calculate how many random bytes should we call in advance.
44
+ // It depends on ID length, mask / alphabet size and magic number 1.6
45
+ // (which was selected according benchmarks).
31
46
  var step = Math.ceil(1.6 * mask * size / alphabet.length)
32
47
  var id = ''
33
48
 
34
49
  while (true) {
50
+ var bytes = random(step)
51
+ // Compact alternative for `for (var i = 0; i < step; i++)`
35
52
  var i = step
36
- var bytes = random(i)
37
53
  while (i--) {
54
+ // If random byte is bigger than alphabet even after bitmask,
55
+ // we refuse it by `|| ''`.
38
56
  id += alphabet[bytes[i] & mask] || ''
57
+ // More compact than `id.length + 1 === size`
39
58
  if (id.length === +size) return id
40
59
  }
41
60
  }
package/index.browser.js CHANGED
@@ -1,4 +1,8 @@
1
+ // This file replaces `index.js` in bundlers like webpack or Rollup,
2
+ // according to `browser` config in `package.json`.
3
+
1
4
  if (process.env.NODE_ENV !== 'production') {
5
+ // All bundlers will remove this block in production bundle
2
6
  if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
3
7
  throw new Error(
4
8
  'React Native does not have a built-in secure random generator. ' +
@@ -16,18 +20,35 @@ if (process.env.NODE_ENV !== 'production') {
16
20
 
17
21
  var crypto = self.crypto || self.msCrypto
18
22
 
19
- /*
20
- * This alphabet uses a-z A-Z 0-9 _- symbols.
21
- * Symbols order was changed for better gzip compression.
22
- */
23
- var url = 'QLUint8ARdomValuesObj0h6345-79BCrypgJzHKTNYDSMkXPZ_FfG1WcqvwxEI2'
23
+ // This alphabet uses a-z A-Z 0-9 _- symbols.
24
+ // Symbols are generated for smaller size.
25
+ // -_zyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA
26
+ var url = '-_'
27
+ // Loop from 36 to 0 (from z to a and 9 to 0 in Base36).
28
+ var i = 36
29
+ while (i--) {
30
+ // 36 is radix. Number.prototype.toString(36) returns number
31
+ // in Base36 representation. Base36 is like hex, but it uses 0–9 and a-z.
32
+ url += i.toString(36)
33
+ }
34
+ // Loop from 36 to 10 (from Z to A in Base36).
35
+ i = 36
36
+ while (i-- - 10) {
37
+ url += i.toString(36).toUpperCase()
38
+ }
24
39
 
25
40
  module.exports = function (size) {
26
- size = size || 21
27
41
  var id = ''
28
- var bytes = crypto.getRandomValues(new Uint8Array(size))
29
- while (size--) {
30
- id += url[bytes[size] & 63]
42
+ var bytes = crypto.getRandomValues(new Uint8Array(size || 21))
43
+ i = size || 21
44
+
45
+ // Compact alternative for `for (var i = 0; i < size; i++)`
46
+ while (i--) {
47
+ // We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
48
+ // This mask reduces random byte 0-255 to 0-63 values.
49
+ // There is no need in `|| ''` and `* 1.6` hacks in here,
50
+ // because bitmask trim bytes exact to alphabet size.
51
+ id += url[bytes[i] & 63]
31
52
  }
32
53
  return id
33
54
  }
package/index.js CHANGED
@@ -22,7 +22,12 @@ module.exports = function (size) {
22
22
  size = size || 21
23
23
  var bytes = random(size)
24
24
  var id = ''
25
+ // Compact alternative for `for (var i = 0; i < size; i++)`
25
26
  while (size--) {
27
+ // We can’t use bytes bigger than the alphabet. 63 is 00111111 bitmask.
28
+ // This mask reduces random byte 0-255 to 0-63 values.
29
+ // There is no need in `|| ''` and `* 1.6` hacks in here,
30
+ // because bitmask trim bytes exact to alphabet size.
26
31
  id += url[bytes[size] & 63]
27
32
  }
28
33
  return id
@@ -17,7 +17,9 @@
17
17
  module.exports = function (alphabet, size) {
18
18
  size = size || 21
19
19
  var id = ''
20
+ // Compact alternative for `for (var i = 0; i < size; i++)`
20
21
  while (size--) {
22
+ // `| 0` is compact and faster alternative for `Math.floor()`
21
23
  id += alphabet[Math.random() * alphabet.length | 0]
22
24
  }
23
25
  return id
@@ -1,4 +1,19 @@
1
- var url = 'sOwnPropMN49CEiq-hXvHJdSymlFURTag61GQfuD8YIWz2Zk5xKB7LV30_Abject'
1
+ // This alphabet uses a-z A-Z 0-9 _- symbols.
2
+ // Symbols are generated for smaller size.
3
+ // -_zyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA
4
+ var url = '-_'
5
+ // Loop from 36 to 0 (from z to a and 9 to 0 in Base36).
6
+ var i = 36
7
+ while (i--) {
8
+ // 36 is radix. Number.prototype.toString(36) returns number
9
+ // in Base36 representation. Base36 is like hex, but it uses 0–9 and a-z.
10
+ url += i.toString(36)
11
+ }
12
+ // Loop from 36 to 10 (from Z to A in Base36).
13
+ i = 36
14
+ while (i-- - 10) {
15
+ url += i.toString(36).toUpperCase()
16
+ }
2
17
 
3
18
  /**
4
19
  * Generate URL-friendly unique ID. This method use non-secure predictable
@@ -16,9 +31,11 @@ var url = 'sOwnPropMN49CEiq-hXvHJdSymlFURTag61GQfuD8YIWz2Zk5xKB7LV30_Abject'
16
31
  * @function
17
32
  */
18
33
  module.exports = function (size) {
19
- size = size || 21
20
34
  var id = ''
21
- while (size--) {
35
+ i = size || 21
36
+ // Compact alternative for `for (var i = 0; i < size; i++)`
37
+ while (i--) {
38
+ // `| 0` is compact and faster alternative for `Math.floor()`
22
39
  id += url[Math.random() * 64 | 0]
23
40
  }
24
41
  return id
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nanoid",
3
- "version": "2.1.7",
4
- "description": "A tiny (137 bytes), secure URL-friendly unique string ID generator",
3
+ "version": "2.1.11",
4
+ "description": "A tiny (119 bytes), secure URL-friendly unique string ID generator",
5
5
  "keywords": [
6
6
  "uuid",
7
7
  "random",
@@ -28,6 +28,6 @@
28
28
  ],
29
29
  "sharec": {
30
30
  "config": "@logux/sharec-config",
31
- "version": "0.5.3"
31
+ "version": "0.5.6"
32
32
  }
33
33
  }
package/random.js CHANGED
@@ -1,10 +1,14 @@
1
1
  var crypto = require('crypto')
2
2
 
3
3
  if (crypto.randomFillSync) {
4
+ // We reuse buffers with the same size to avoid memory fragmentations
5
+ // for better performance
4
6
  var buffers = { }
5
7
  module.exports = function (bytes) {
6
8
  var buffer = buffers[bytes]
7
9
  if (!buffer) {
10
+ // `Buffer.allocUnsafe()` faster because it don’t clean memory.
11
+ // We do not need it, since we will fill memory with new bytes anyway.
8
12
  buffer = Buffer.allocUnsafe(bytes)
9
13
  if (bytes <= 255) buffers[bytes] = buffer
10
14
  }
package/url.js CHANGED
@@ -1,9 +1,11 @@
1
+ // This alphabet uses a-z A-Z 0-9 _- symbols.
2
+ // Despite the fact the source code is quite long, its entropy
3
+ // is low and there are lots of duplicates - just what compressors
4
+ // like GZIP and Brotli likes the best.
5
+
1
6
  /**
2
7
  * URL safe symbols.
3
8
  *
4
- * This alphabet uses a-z A-Z 0-9 _- symbols.
5
- * Symbols order was changed for better gzip compression.
6
- *
7
9
  * @name url
8
10
  * @type {string}
9
11
  *
@@ -11,5 +13,15 @@
11
13
  * const url = require('nanoid/url')
12
14
  * generate(url, 10) //=> "Uakgb_J5m9"
13
15
  */
14
- module.exports =
15
- 'ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW'
16
+
17
+ // This alphabet uses a-z A-Z 0-9 _- symbols.
18
+ // Symbols are generated for smaller size.
19
+ // -_zyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA
20
+ module.exports = '-_'
21
+ var i = 36
22
+ while (i--) {
23
+ // 36 is radix. Number.prototype.toString(36) returns number
24
+ // in Base36 representation. Base36 is like hex, but it uses 0–9 and a-z.
25
+ module.exports += i.toString(36)
26
+ i > 9 && (module.exports += i.toString(36).toUpperCase())
27
+ }