Skip to content

Commit 7714e61

Browse files
committed
Change bundling strategy with rollup
1 parent 76605eb commit 7714e61

12 files changed

Lines changed: 1314 additions & 357 deletions

File tree

.babelrc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"presets": [
3+
[
4+
"env",
5+
{
6+
"modules": false
7+
}
8+
]
9+
],
10+
"plugins": ["external-helpers"]
11+
}

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ npm install --save ulid
4141
### Usage
4242

4343
```javascript
44-
import ulid from 'ulid'
44+
import { ulid } from 'ulid'
4545

4646
ulid() // 01ARZ3NDEKTSV4RRFFQ69G5FAV
4747

@@ -56,9 +56,9 @@ ulid(1469918176385) // 01ARYZ6S41TSV4RRFFQ69G5FAV
5656
To generate monotonically increasing ULIDs, create a monotonic counter.
5757

5858
```javascript
59-
import { createMonotonic } from 'ulid'
59+
import { monotonicFactory } from 'ulid'
6060

61-
const ulid = createMonotonic()
61+
const ulid = monotonicFactory()
6262

6363
// Strict ordering for the same timestamp, by incrementing the least-significant random bit by 1
6464
ulid(150000) // 000XAL6S41ACTAV9WEVGEMMVR8
@@ -165,6 +165,10 @@ When generating a ULID within the same millisecond, we can provide some
165165
guarantees regarding sort order. Namely, if the same millisecond is detected, the `random` component is incremented by 1 bit in the least significant bit position (with carrying). For example:
166166

167167
```javascript
168+
import { monotonicFactory } from 'ulid'
169+
170+
const ulid = monotonicFactory()
171+
168172
// Assume that these calls occur within the same millisecond
169173
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRZ
170174
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS0
@@ -173,12 +177,16 @@ ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS0
173177
If, in the extremely unlikely event that, you manage to generate at most 80 ^ 2 ULIDs within the same millisecond, or cause the random component to overflow with less, the generation will fail.
174178

175179
```javascript
180+
import { monotonicFactory } from 'ulid'
181+
182+
const ulid = monotonicFactory()
183+
176184
// Assume that these calls occur within the same millisecond
177185
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRY
178186
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRZ
179187
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS0
180188
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS1
181-
....
189+
...
182190
ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZX
183191
ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZY
184192
ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZZ

cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#! /usr/bin/env node
22

3-
const ulid = require('./index')
3+
const ulid = require('./dist/ulid.umd.js')
44
console.log(ulid())

dist/ulid.es.js

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
function createError(message) {
2+
const err = new Error(message);
3+
err.source = "ulid";
4+
return err;
5+
}
6+
// These values should NEVER change. If
7+
// they do, we're no longer making ulids!
8+
const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; // Crockford's Base32
9+
const ENCODING_LEN = ENCODING.length;
10+
const TIME_MAX = Math.pow(2, 48) - 1;
11+
const TIME_LEN = 10;
12+
const RANDOM_LEN = 16;
13+
function replaceCharAt(str, index, char) {
14+
if (index > str.length - 1) {
15+
return str;
16+
}
17+
return str.substr(0, index) + char + str.substr(index + 1);
18+
}
19+
function incrementBase32(str) {
20+
let done = undefined;
21+
let index = str.length;
22+
let char;
23+
let charIndex;
24+
const maxCharIndex = ENCODING_LEN - 1;
25+
while (!done && index-- >= 0) {
26+
char = str[index];
27+
charIndex = ENCODING.indexOf(char);
28+
if (charIndex === -1) {
29+
throw createError("incorrectly encoded string");
30+
}
31+
if (charIndex === maxCharIndex) {
32+
str = replaceCharAt(str, index, ENCODING[0]);
33+
continue;
34+
}
35+
done = replaceCharAt(str, index, ENCODING[charIndex + 1]);
36+
}
37+
if (typeof done === "string") {
38+
return done;
39+
}
40+
throw createError("cannot increment this string");
41+
}
42+
function randomChar(prng) {
43+
let rand = Math.floor(prng() * ENCODING_LEN);
44+
if (rand === ENCODING_LEN) {
45+
rand = ENCODING_LEN - 1;
46+
}
47+
return ENCODING.charAt(rand);
48+
}
49+
function encodeTime(now, len) {
50+
if (isNaN(now)) {
51+
throw new Error(now + " must be a number");
52+
}
53+
if (now > TIME_MAX) {
54+
throw createError("cannot encode time greater than " + TIME_MAX);
55+
}
56+
if (now < 0) {
57+
throw createError("time must be positive");
58+
}
59+
if (Number.isInteger(now) === false) {
60+
throw createError("time must be an integer");
61+
}
62+
let mod;
63+
let str = "";
64+
for (; len > 0; len--) {
65+
mod = now % ENCODING_LEN;
66+
str = ENCODING.charAt(mod) + str;
67+
now = (now - mod) / ENCODING_LEN;
68+
}
69+
return str;
70+
}
71+
function encodeRandom(len, prng) {
72+
let str = "";
73+
for (; len > 0; len--) {
74+
str = randomChar(prng) + str;
75+
}
76+
return str;
77+
}
78+
function decodeTime(id) {
79+
if (id.length !== TIME_LEN + RANDOM_LEN) {
80+
throw createError("malformed ulid");
81+
}
82+
var time = id
83+
.substr(0, TIME_LEN)
84+
.split("")
85+
.reverse()
86+
.reduce((carry, char, index) => {
87+
const encodingIndex = ENCODING.indexOf(char);
88+
if (encodingIndex === -1) {
89+
throw createError("invalid character found: " + char);
90+
}
91+
return (carry += encodingIndex * Math.pow(ENCODING_LEN, index));
92+
}, 0);
93+
if (time > TIME_MAX) {
94+
throw createError("malformed ulid, timestamp too large");
95+
}
96+
return time;
97+
}
98+
function detectPrng(allowInsecure = true, root) {
99+
if (!root) {
100+
root = typeof window !== "undefined" ? window : null;
101+
}
102+
const browserCrypto = root && (root.crypto || root.msCrypto);
103+
if (browserCrypto) {
104+
try {
105+
return () => browserCrypto.getRandomValues(new Uint8Array(1))[0] / 0xff;
106+
}
107+
catch (e) { }
108+
}
109+
else {
110+
try {
111+
const nodeCrypto = require("crypto");
112+
return () => nodeCrypto.randomBytes(1).readUInt8() / 0xff;
113+
}
114+
catch (e) { }
115+
}
116+
if (allowInsecure) {
117+
try {
118+
console.error("secure crypto unusable, falling back to insecure Math.random()!");
119+
}
120+
catch (e) { }
121+
return () => Math.random();
122+
}
123+
throw createError("secure crypto unusable, insecure Math.random not allowedW");
124+
}
125+
function factory(currPrng) {
126+
if (!currPrng) {
127+
currPrng = detectPrng();
128+
}
129+
return function ulid(seedTime) {
130+
if (isNaN(seedTime)) {
131+
seedTime = Date.now();
132+
}
133+
return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN, currPrng);
134+
};
135+
}
136+
function monotonicFactory(currPrng) {
137+
if (!currPrng) {
138+
currPrng = detectPrng();
139+
}
140+
let lastTime = 0;
141+
let lastRandom;
142+
return function ulid(seedTime) {
143+
if (isNaN(seedTime)) {
144+
seedTime = Date.now();
145+
}
146+
if (seedTime <= lastTime) {
147+
const incrementedRandom = (lastRandom = incrementBase32(lastRandom));
148+
return encodeTime(lastTime, TIME_LEN) + incrementedRandom;
149+
}
150+
lastTime = seedTime;
151+
const newRandom = (lastRandom = encodeRandom(RANDOM_LEN, currPrng));
152+
return encodeTime(seedTime, TIME_LEN) + newRandom;
153+
};
154+
}
155+
const ulid = factory();
156+
157+
export { replaceCharAt, incrementBase32, randomChar, encodeTime, encodeRandom, decodeTime, detectPrng, factory, monotonicFactory, ulid };

0 commit comments

Comments
 (0)