Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ai/nanoid
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3.3.10
Choose a base ref
...
head repository: ai/nanoid
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3.3.11
Choose a head ref
  • 4 commits
  • 28 files changed
  • 1 contributor

Commits on Mar 18, 2025

  1. Move to manually ESM/CJS dual package

    ai committed Mar 18, 2025
    Copy the full SHA
    a83734e View commit details
  2. Fix RN support

    ai committed Mar 18, 2025
    Copy the full SHA
    c147962 View commit details
  3. Fix CI

    ai committed Mar 18, 2025
    Copy the full SHA
    23690b7 View commit details
  4. Release 3.3.11 version

    ai committed Mar 18, 2025
    Copy the full SHA
    37289ce View commit details
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
version: 10
- name: Install Node.js
uses: actions/setup-node@v3
with:
@@ -42,7 +42,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
version: 10
- name: Install Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
@@ -51,7 +51,7 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Run unit tests
run: pnpm unit
run: pnpm test
old:
runs-on: ubuntu-latest
strategy:
@@ -77,4 +77,4 @@ jobs:
- name: Install dependencies
run: pnpm install --no-frozen-lockfile --ignore-scripts
- name: Run unit tests
run: pnpm unit
run: pnpm test
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Change Log
This project adheres to [Semantic Versioning](http://semver.org/).

## 3.3.11
* Fixed React Native support.

## 3.3.10
* Fixed React Native support (by @steida).

69 changes: 69 additions & 0 deletions async/index.browser.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes))

let customAlphabet = (alphabet, defaultSize = 21) => {
// 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).
// `Math.clz32` is not used, because it is not available in browsers.
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 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).

// `-~f => Math.ceil(f)` if f is a float
// `-~i => i + 1` if i is an integer
let step = -~((1.6 * mask * defaultSize) / alphabet.length)

return async (size = defaultSize) => {
let id = ''
while (true) {
let bytes = crypto.getRandomValues(new Uint8Array(step))
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = step | 0
while (i--) {
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
id += alphabet[bytes[i] & mask] || ''
if (id.length === size) return id
}
}
}
}

let nanoid = async (size = 21) => {
let id = ''
let bytes = crypto.getRandomValues(new Uint8Array((size |= 0)))

// 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.
let byte = bytes[size] & 63
if (byte < 36) {
// `0-9a-z`
id += byte.toString(36)
} else if (byte < 62) {
// `A-Z`
id += (byte - 26).toString(36).toUpperCase()
} else if (byte < 63) {
id += '_'
} else {
id += '-'
}
}
return id
}

module.exports = { nanoid, customAlphabet, random }
2 changes: 1 addition & 1 deletion async/index.browser.js
Original file line number Diff line number Diff line change
@@ -66,4 +66,4 @@ let nanoid = async (size = 21) => {
return id
}

module.exports = { nanoid, customAlphabet, random }
export { nanoid, customAlphabet, random }
71 changes: 71 additions & 0 deletions async/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
let crypto = require('crypto')

let { urlAlphabet } = require('../url-alphabet/index.cjs')

// `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, defaultSize = 21) => {
// 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 * defaultSize) / alphabet.length)

let tick = (id, size = defaultSize) =>
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, size)
})

return size => tick('', size)
}

let nanoid = (size = 21) =>
random((size |= 0)).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
})

module.exports = { nanoid, customAlphabet, random }
6 changes: 3 additions & 3 deletions async/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let crypto = require('crypto')
import crypto from 'crypto'

let { urlAlphabet } = require('../url-alphabet')
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()`.
@@ -68,4 +68,4 @@ let nanoid = (size = 21) =>
return id
})

module.exports = { nanoid, customAlphabet, random }
export { nanoid, customAlphabet, random }
6 changes: 3 additions & 3 deletions async/index.native.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let { getRandomBytesAsync } = require('expo-random')
import { getRandomBytesAsync } from 'expo-random'

let { urlAlphabet } = require('../url-alphabet')
import { urlAlphabet } from '../url-alphabet/index.js'

let random = getRandomBytesAsync

@@ -54,4 +54,4 @@ let nanoid = (size = 21) =>
return id
})

module.exports = { nanoid, customAlphabet, random }
export { nanoid, customAlphabet, random }
12 changes: 12 additions & 0 deletions async/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "module",
"main": "index.cjs",
"module": "index.js",
"react-native": {
"./index.js": "./index.native.js"
},
"browser": {
"./index.js": "./index.browser.js",
"./index.cjs": "./index.browser.cjs"
}
}
72 changes: 72 additions & 0 deletions index.browser.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// This file replaces `index.js` in bundlers like webpack or Rollup,
// according to `browser` config in `package.json`.

let { urlAlphabet } = require('./url-alphabet/index.cjs')

let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))

let customRandom = (alphabet, defaultSize, getRandom) => {
// 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).
// `Math.clz32` is not used, because it is not available in browsers.
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 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).

// `-~f => Math.ceil(f)` if f is a float
// `-~i => i + 1` if i is an integer
let step = -~((1.6 * mask * defaultSize) / alphabet.length)

return (size = defaultSize) => {
let id = ''
while (true) {
let bytes = getRandom(step)
// A compact alternative for `for (var i = 0; i < step; i++)`.
let j = step | 0
while (j--) {
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
id += alphabet[bytes[j] & mask] || ''
if (id.length === size) return id
}
}
}
}

let customAlphabet = (alphabet, size = 21) =>
customRandom(alphabet, size, random)

let nanoid = (size = 21) =>
crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
// 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.
byte &= 63
if (byte < 36) {
// `0-9a-z`
id += byte.toString(36)
} else if (byte < 62) {
// `A-Z`
id += (byte - 26).toString(36).toUpperCase()
} else if (byte > 62) {
id += '-'
} else {
id += '_'
}
return id
}, '')

module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
4 changes: 2 additions & 2 deletions index.browser.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file replaces `index.js` in bundlers like webpack or Rollup,
// according to `browser` config in `package.json`.

let { urlAlphabet } = require('./url-alphabet')
import { urlAlphabet } from './url-alphabet/index.js'

let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))

@@ -69,4 +69,4 @@ let nanoid = (size = 21) =>
return id
}, '')

module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
85 changes: 85 additions & 0 deletions index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
let crypto = require('crypto')

let { urlAlphabet } = require('./url-alphabet/index.cjs')

// It is best to make fewer, larger requests to the crypto module to
// avoid system call overhead. So, random numbers are generated in a
// pool. The pool is a Buffer that is larger than the initial random
// request size by this multiplier. The pool is enlarged if subsequent
// requests exceed the maximum buffer size.
const POOL_SIZE_MULTIPLIER = 128
let pool, poolOffset

let fillPool = bytes => {
if (!pool || pool.length < bytes) {
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
crypto.randomFillSync(pool)
poolOffset = 0
} else if (poolOffset + bytes > pool.length) {
crypto.randomFillSync(pool)
poolOffset = 0
}
poolOffset += bytes
}

let random = bytes => {
// `|=` convert `bytes` to number to prevent `valueOf` abusing and pool pollution
fillPool((bytes |= 0))
return pool.subarray(poolOffset - bytes, poolOffset)
}

let customRandom = (alphabet, defaultSize, getRandom) => {
// 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 * defaultSize) / alphabet.length)

return (size = defaultSize) => {
let id = ''
while (true) {
let bytes = getRandom(step)
// A compact alternative for `for (let 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
}
}
}
}

let customAlphabet = (alphabet, size = 21) =>
customRandom(alphabet, size, random)

let nanoid = (size = 21) => {
// `|=` convert `size` to number to prevent `valueOf` abusing and pool pollution
fillPool((size |= 0))
let id = ''
// We are reading directly from the random pool to avoid creating new array
for (let i = poolOffset - size; i < poolOffset; i++) {
// 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[pool[i] & 63]
}
return id
}

module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
91 changes: 91 additions & 0 deletions index.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* Generate secure URL-friendly unique ID.
*
* By default, the ID will have 21 symbols to have a collision probability
* similar to UUID v4.
*
* ```js
* import { nanoid } from 'nanoid'
* model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL"
* ```
*
* @param size Size of the ID. The default size is 21.
* @returns A random string.
*/
export function nanoid(size?: number): string

/**
* Generate secure unique ID with custom alphabet.
*
* Alphabet must contain 256 symbols or less. Otherwise, the generator
* will not be secure.
*
* @param alphabet Alphabet used to generate the ID.
* @param defaultSize Size of the ID. The default size is 21.
* @returns A random string generator.
*
* ```js
* const { customAlphabet } = require('nanoid')
* const nanoid = customAlphabet('0123456789абвгдеё', 5)
* nanoid() //=> "8ё56а"
* ```
*/
export function customAlphabet(
alphabet: string,
defaultSize?: number
): (size?: number) => string

/**
* Generate unique ID with custom random generator and alphabet.
*
* Alphabet must contain 256 symbols or less. Otherwise, the generator
* will not be secure.
*
* ```js
* import { customRandom } from 'nanoid/format'
*
* const nanoid = customRandom('abcdef', 5, size => {
* const random = []
* for (let i = 0; i < size; i++) {
* random.push(randomByte())
* }
* return random
* })
*
* nanoid() //=> "fbaef"
* ```
*
* @param alphabet Alphabet used to generate a random string.
* @param size Size of the random string.
* @param random A random bytes generator.
* @returns A random string generator.
*/
export function customRandom(
alphabet: string,
size: number,
random: (bytes: number) => Uint8Array
): () => string

/**
* URL safe symbols.
*
* ```js
* import { urlAlphabet } from 'nanoid'
* const nanoid = customAlphabet(urlAlphabet, 10)
* nanoid() //=> "Uakgb_J5m9"
* ```
*/
export const urlAlphabet: string

/**
* Generate an array of random bytes collected from hardware noise.
*
* ```js
* import { customRandom, random } from 'nanoid'
* const nanoid = customRandom("abcdef", 5, random)
* ```
*
* @param bytes Size of the array.
* @returns An array of random bytes.
*/
export function random(bytes: number): Uint8Array
6 changes: 3 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let crypto = require('crypto')
import crypto from 'crypto'

let { urlAlphabet } = require('./url-alphabet')
import { urlAlphabet } from './url-alphabet/index.js'

// It is best to make fewer, larger requests to the crypto module to
// avoid system call overhead. So, random numbers are generated in a
@@ -82,4 +82,4 @@ let nanoid = (size = 21) => {
return id
}

module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
34 changes: 34 additions & 0 deletions non-secure/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// This alphabet uses `A-Za-z0-9_-` symbols.
// The order of characters is optimized for better gzip and brotli compression.
// References to the same file (works both for gzip and brotli):
// `'use`, `andom`, and `rict'`
// References to the brotli default dictionary:
// `-26T`, `1983`, `40px`, `75px`, `bush`, `jack`, `mind`, `very`, and `wolf`
let urlAlphabet =
'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'

let customAlphabet = (alphabet, defaultSize = 21) => {
return (size = defaultSize) => {
let id = ''
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = size | 0
while (i--) {
// `| 0` is more compact and faster than `Math.floor()`.
id += alphabet[(Math.random() * alphabet.length) | 0]
}
return id
}
}

let nanoid = (size = 21) => {
let id = ''
// A compact alternative for `for (var i = 0; i < step; i++)`.
let i = size | 0
while (i--) {
// `| 0` is more compact and faster than `Math.floor()`.
id += urlAlphabet[(Math.random() * 64) | 0]
}
return id
}

module.exports = { nanoid, customAlphabet }
2 changes: 1 addition & 1 deletion non-secure/index.js
Original file line number Diff line number Diff line change
@@ -31,4 +31,4 @@ let nanoid = (size = 21) => {
return id
}

module.exports = { nanoid, customAlphabet }
export { nanoid, customAlphabet }
6 changes: 6 additions & 0 deletions non-secure/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "module",
"main": "index.cjs",
"module": "index.js",
"react-native": "index.js"
}
182 changes: 63 additions & 119 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nanoid",
"version": "3.3.10",
"version": "3.3.11",
"description": "A tiny (116 bytes), secure URL-friendly unique string ID generator",
"keywords": [
"uuid",
@@ -9,10 +9,7 @@
"url"
],
"scripts": {
"clean": "rm -R coverage",
"unit": "uvu . .test.js$",
"test": "c8 pnpm unit && eslint . && pnpm clean && size-limit",
"start": "vite test/demo/ --open"
"test": "uvu . .test.cjs$"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
@@ -29,132 +26,79 @@
"browser": {
"./index.js": "./index.browser.js",
"./async/index.js": "./async/index.browser.js",
"./async/index.cjs": "./async/index.browser.cjs"
},
"react-native": {
"./index.js": "./index.browser.js",
"./async/index.js": "./async/index.native.js"
"./async/index.cjs": "./async/index.browser.cjs",
"./index.cjs": "./index.browser.cjs"
},
"react-native": "index.js",
"bin": "./bin/nanoid.cjs",
"sideEffects": false,
"types": "./index.d.ts",
"type": "module",
"main": "index.cjs",
"module": "index.js",
"exports": {
".": {
"react-native": "./index.browser.js",
"browser": "./index.browser.js",
"require": {
"types": "./index.d.cts",
"default": "./index.cjs"
},
"import": {
"types": "./index.d.ts",
"default": "./index.js"
},
"default": "./index.js"
},
"./package.json": "./package.json",
"./async/package.json": "./async/package.json",
"./async": {
"browser": "./async/index.browser.js",
"require": {
"types": "./index.d.cts",
"default": "./async/index.cjs"
},
"import": {
"types": "./index.d.ts",
"default": "./async/index.js"
},
"default": "./async/index.js"
},
"./non-secure/package.json": "./non-secure/package.json",
"./non-secure": {
"require": {
"types": "./index.d.cts",
"default": "./non-secure/index.cjs"
},
"import": {
"types": "./index.d.ts",
"default": "./non-secure/index.js"
},
"default": "./non-secure/index.js"
},
"./url-alphabet/package.json": "./url-alphabet/package.json",
"./url-alphabet": {
"require": {
"types": "./index.d.cts",
"default": "./url-alphabet/index.cjs"
},
"import": {
"types": "./index.d.ts",
"default": "./url-alphabet/index.js"
},
"default": "./url-alphabet/index.js"
}
},
"devDependencies": {
"@babel/core": "^7.18.2",
"@logux/eslint-config": "^47.2.0",
"@lukeed/uuid": "^2.0.0",
"@napi-rs/uuid": "^0.2.1",
"@originjs/vite-plugin-commonjs": "^1.0.3",
"@size-limit/dual-publish": "^7.0.8",
"@size-limit/file": "^7.0.8",
"@size-limit/webpack": "^7.0.8",
"@types/node": "^17.0.40",
"benchmark": "^2.1.4",
"c8": "^7.11.3",
"cuid": "^2.1.8",
"dual-publish": "^4.0.0",
"eslint": "^8.17.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.2.1",
"eslint-plugin-prefer-let": "^3.0.1",
"eslint-plugin-promise": "^6.0.0",
"clean-publish": "^5.1.0",
"nanospy": "^0.5.0",
"picocolors": "^1.0.0",
"postcss": "^8.4.14",
"rndm": "^1.2.0",
"secure-random-string": "^1.1.3",
"shortid": "^2.2.16",
"size-limit": "^7.0.8",
"terser": "^5.14.0",
"uid": "^2.0.0",
"uid-safe": "^2.1.5",
"uuid": "^8.3.2",
"uvu": "^0.5.3",
"vite": "^2.9.10"
"uvu": "^0.5.3"
},
"size-limit": [
{
"name": "nanoid",
"import": "{ nanoid }",
"limit": "115 B"
},
{
"name": "customAlphabet",
"import": "{ customAlphabet }",
"limit": "174 B"
},
{
"name": "urlAlphabet",
"import": "{ urlAlphabet }",
"limit": "61 B"
},
{
"name": "non-secure nanoid",
"import": "{ nanoid }",
"path": "non-secure/index.js",
"limit": "120 B"
},
{
"name": "non-secure customAlphabet",
"import": "{ customAlphabet }",
"path": "non-secure/index.js",
"limit": "71 B"
},
{
"name": "async nanoid",
"import": "{ nanoid }",
"path": "async/index.js",
"limit": "138 B"
},
{
"name": "async customAlphabet",
"import": "{ customAlphabet }",
"path": "async/index.js",
"limit": "159 B"
},
{
"name": "Brotli all",
"brotli": true,
"import": "{ nanoid, customAlphabet, urlAlphabet }",
"limit": "267 B"
},
{
"name": "Brotli non-secure",
"brotli": true,
"import": "{ nanoid, customAlphabet }",
"path": "non-secure/index.js",
"limit": "118 B"
},
{
"name": "Brotli async",
"brotli": true,
"import": "{ nanoid, customAlphabet }",
"path": "async/index.js",
"limit": "213 B"
}
],
"eslintConfig": {
"extends": "@logux/eslint-config",
"rules": {
"consistent-return": "off",
"func-style": "off",
"yoda": "off"
},
"overrides": [
{
"files": "*.native.js",
"rules": {
"n/no-missing-require": "off",
"global-require": "off"
}
}
]
},
"eslintIgnore": [
"test/demo/build",
"nanoid.js",
"**/errors.ts"
],
"prettier": {
"arrowParens": "avoid",
"jsxSingleQuote": false,
3,341 changes: 775 additions & 2,566 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

File renamed without changes.
117 changes: 0 additions & 117 deletions test/benchmark.js

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions url-alphabet/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This alphabet uses `A-Za-z0-9_-` symbols.
// The order of characters is optimized for better gzip and brotli compression.
// Same as in non-secure/index.js
let urlAlphabet =
'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'

module.exports = { urlAlphabet }
2 changes: 1 addition & 1 deletion url-alphabet/index.js
Original file line number Diff line number Diff line change
@@ -4,4 +4,4 @@
let urlAlphabet =
'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'

module.exports = { urlAlphabet }
export { urlAlphabet }
6 changes: 6 additions & 0 deletions url-alphabet/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "module",
"main": "index.cjs",
"module": "index.js",
"react-native": "index.js"
}