tiny-ulid
Version:
Make and decode ULIDs.
88 lines (87 loc) • 3.92 kB
JavaScript
import {
cloneUlidBuffer,
incrementUlidBuffer,
makeEmptyUlidBuffer,
makeUlidBuffer as makeUlidBuffer$1,
setUlidBufferTime
} from "./default.js"
let lastGeneratedBuffer = !1,
stateTime = 0
const stateUlidBuffer = makeEmptyUlidBuffer(),
stateUlidBytes = new Uint8Array(stateUlidBuffer),
makeUlidBuffer = () => {
const time = Date.now()
if (stateTime < time) {
stateTime = time
makeUlidBuffer$1({ ulidBuffer: stateUlidBuffer })
stateUlidBytes[6] &= 127
} else {
if (!lastGeneratedBuffer) {
setUlidBufferTime(stateUlidBuffer, stateTime)
for (let bytesIndex = 0, ulidIndex = 0; bytesIndex < 15; bytesIndex++) {
stateUlidBytes[bytesIndex] =
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[ulidIndex]) << 5) |
CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex])
stateUlidBytes[++bytesIndex] =
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex]) << 3) |
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex]) >> 2)
stateUlidBytes[++bytesIndex] =
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[ulidIndex]) << 6) |
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex]) << 1) |
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex]) >> 4)
stateUlidBytes[++bytesIndex] =
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[ulidIndex]) << 4) |
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex]) >> 1)
stateUlidBytes[++bytesIndex] =
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[ulidIndex]) << 7) |
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex]) << 2) |
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[++ulidIndex]) >> 3)
}
stateUlidBytes[15] =
(CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[24]) << 5) |
CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[25])
}
incrementUlidBuffer(stateUlidBuffer, { throwOnOverflow: !0 })
}
lastGeneratedBuffer = !0
return cloneUlidBuffer(stateUlidBuffer)
},
stateUlidStringBytes = new Uint8Array(26),
textDecoder = new TextDecoder(),
CROCKFORD_BASE32_CHAR_CODES = new Uint8Array([
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 77, 78, 80, 81, 82, 83, 84, 86,
87, 88, 89, 90
]),
makeUlid = () => {
const time = Date.now()
if_: {
if (!(stateTime < time)) {
if (lastGeneratedBuffer) {
const dataView = new DataView(stateUlidBuffer)
stateUlidStringBytes[0] = CROCKFORD_BASE32_CHAR_CODES[dataView.getUint8(0) >> 5]
for (let bitOffset = 3, index = 1; bitOffset < 123; bitOffset += 5, index++) {
const byteOffset = Math.floor(bitOffset / 8)
stateUlidStringBytes[index] =
CROCKFORD_BASE32_CHAR_CODES[(dataView.getUint16(byteOffset) >> (11 - (bitOffset % 8))) & 31]
}
stateUlidStringBytes[25] = CROCKFORD_BASE32_CHAR_CODES[31 & dataView.getUint8(15)]
}
for (let index = 25; index > 9; index--) {
const value = (CROCKFORD_BASE32_CHAR_CODES.indexOf(stateUlidStringBytes[index]) + 1) & 31
stateUlidStringBytes[index] = CROCKFORD_BASE32_CHAR_CODES[value]
if (value) break if_
}
throw Error("Overflow when incrementing ULID")
}
stateTime = time
for (let offset = 50, index = 0; offset;)
stateUlidStringBytes[index++] = CROCKFORD_BASE32_CHAR_CODES[(time / 2 ** (offset -= 5)) & 31]
crypto.getRandomValues(new Uint8Array(stateUlidStringBytes.buffer, 10))
stateUlidStringBytes[10] = CROCKFORD_BASE32_CHAR_CODES[15 & stateUlidStringBytes[10]]
for (let index = 11; index < 26;)
stateUlidStringBytes[index] = CROCKFORD_BASE32_CHAR_CODES[31 & stateUlidStringBytes[index++]]
}
lastGeneratedBuffer = !1
return textDecoder.decode(stateUlidStringBytes)
}
export { makeUlid, makeUlidBuffer }