You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

26 lines
814 B

2 years ago
  1. import { getRandomBytesAsync } from 'expo-random'
  2. import { urlAlphabet } from '../url-alphabet/index.js'
  3. let random = getRandomBytesAsync
  4. let customAlphabet = (alphabet, defaultSize = 21) => {
  5. let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
  6. let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
  7. let tick = (id, size = defaultSize) =>
  8. random(step).then(bytes => {
  9. let i = step
  10. while (i--) {
  11. id += alphabet[bytes[i] & mask] || ''
  12. if (id.length === size) return id
  13. }
  14. return tick(id, size)
  15. })
  16. return size => tick('', size)
  17. }
  18. let nanoid = (size = 21) =>
  19. random(size).then(bytes => {
  20. let id = ''
  21. while (size--) {
  22. id += urlAlphabet[bytes[size] & 63]
  23. }
  24. return id
  25. })
  26. export { nanoid, customAlphabet, random }