1 | import rng from './rng.js';
|
---|
2 | import { unsafeStringify } from './stringify.js';
|
---|
3 | const _state = {};
|
---|
4 | function v7(options, buf, offset) {
|
---|
5 | let bytes;
|
---|
6 | if (options) {
|
---|
7 | bytes = v7Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.seq, buf, offset);
|
---|
8 | }
|
---|
9 | else {
|
---|
10 | const now = Date.now();
|
---|
11 | const rnds = rng();
|
---|
12 | updateV7State(_state, now, rnds);
|
---|
13 | bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
|
---|
14 | }
|
---|
15 | return buf ? bytes : unsafeStringify(bytes);
|
---|
16 | }
|
---|
17 | export function updateV7State(state, now, rnds) {
|
---|
18 | state.msecs ??= -Infinity;
|
---|
19 | state.seq ??= 0;
|
---|
20 | if (now > state.msecs) {
|
---|
21 | state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
|
---|
22 | state.msecs = now;
|
---|
23 | }
|
---|
24 | else {
|
---|
25 | state.seq = (state.seq + 1) | 0;
|
---|
26 | if (state.seq === 0) {
|
---|
27 | state.msecs++;
|
---|
28 | }
|
---|
29 | }
|
---|
30 | return state;
|
---|
31 | }
|
---|
32 | function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
|
---|
33 | if (!buf) {
|
---|
34 | buf = new Uint8Array(16);
|
---|
35 | offset = 0;
|
---|
36 | }
|
---|
37 | msecs ??= Date.now();
|
---|
38 | seq ??= ((rnds[6] * 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
|
---|
39 | buf[offset++] = (msecs / 0x10000000000) & 0xff;
|
---|
40 | buf[offset++] = (msecs / 0x100000000) & 0xff;
|
---|
41 | buf[offset++] = (msecs / 0x1000000) & 0xff;
|
---|
42 | buf[offset++] = (msecs / 0x10000) & 0xff;
|
---|
43 | buf[offset++] = (msecs / 0x100) & 0xff;
|
---|
44 | buf[offset++] = msecs & 0xff;
|
---|
45 | buf[offset++] = 0x70 | ((seq >>> 28) & 0x0f);
|
---|
46 | buf[offset++] = (seq >>> 20) & 0xff;
|
---|
47 | buf[offset++] = 0x80 | ((seq >>> 14) & 0x3f);
|
---|
48 | buf[offset++] = (seq >>> 6) & 0xff;
|
---|
49 | buf[offset++] = ((seq << 2) & 0xff) | (rnds[10] & 0x03);
|
---|
50 | buf[offset++] = rnds[11];
|
---|
51 | buf[offset++] = rnds[12];
|
---|
52 | buf[offset++] = rnds[13];
|
---|
53 | buf[offset++] = rnds[14];
|
---|
54 | buf[offset++] = rnds[15];
|
---|
55 | return buf;
|
---|
56 | }
|
---|
57 | export default v7;
|
---|