1 | import rng from './rng.js';
|
---|
2 | import { unsafeStringify } from './stringify.js';
|
---|
3 | const _state = {};
|
---|
4 | function v1(options, buf, offset) {
|
---|
5 | let bytes;
|
---|
6 | const isV6 = options?._v6 ?? false;
|
---|
7 | if (options) {
|
---|
8 | const optionsKeys = Object.keys(options);
|
---|
9 | if (optionsKeys.length === 1 && optionsKeys[0] === '_v6') {
|
---|
10 | options = undefined;
|
---|
11 | }
|
---|
12 | }
|
---|
13 | if (options) {
|
---|
14 | bytes = v1Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset);
|
---|
15 | }
|
---|
16 | else {
|
---|
17 | const now = Date.now();
|
---|
18 | const rnds = rng();
|
---|
19 | updateV1State(_state, now, rnds);
|
---|
20 | bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? undefined : _state.clockseq, isV6 ? undefined : _state.node, buf, offset);
|
---|
21 | }
|
---|
22 | return buf ? bytes : unsafeStringify(bytes);
|
---|
23 | }
|
---|
24 | export function updateV1State(state, now, rnds) {
|
---|
25 | state.msecs ??= -Infinity;
|
---|
26 | state.nsecs ??= 0;
|
---|
27 | if (now === state.msecs) {
|
---|
28 | state.nsecs++;
|
---|
29 | if (state.nsecs >= 10000) {
|
---|
30 | state.node = undefined;
|
---|
31 | state.nsecs = 0;
|
---|
32 | }
|
---|
33 | }
|
---|
34 | else if (now > state.msecs) {
|
---|
35 | state.nsecs = 0;
|
---|
36 | }
|
---|
37 | else if (now < state.msecs) {
|
---|
38 | state.node = undefined;
|
---|
39 | }
|
---|
40 | if (!state.node) {
|
---|
41 | state.node = rnds.slice(10, 16);
|
---|
42 | state.node[0] |= 0x01;
|
---|
43 | state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff;
|
---|
44 | }
|
---|
45 | state.msecs = now;
|
---|
46 | return state;
|
---|
47 | }
|
---|
48 | function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) {
|
---|
49 | if (!buf) {
|
---|
50 | buf = new Uint8Array(16);
|
---|
51 | offset = 0;
|
---|
52 | }
|
---|
53 | msecs ??= Date.now();
|
---|
54 | nsecs ??= 0;
|
---|
55 | clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff;
|
---|
56 | node ??= rnds.slice(10, 16);
|
---|
57 | msecs += 12219292800000;
|
---|
58 | const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
|
---|
59 | buf[offset++] = (tl >>> 24) & 0xff;
|
---|
60 | buf[offset++] = (tl >>> 16) & 0xff;
|
---|
61 | buf[offset++] = (tl >>> 8) & 0xff;
|
---|
62 | buf[offset++] = tl & 0xff;
|
---|
63 | const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff;
|
---|
64 | buf[offset++] = (tmh >>> 8) & 0xff;
|
---|
65 | buf[offset++] = tmh & 0xff;
|
---|
66 | buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10;
|
---|
67 | buf[offset++] = (tmh >>> 16) & 0xff;
|
---|
68 | buf[offset++] = (clockseq >>> 8) | 0x80;
|
---|
69 | buf[offset++] = clockseq & 0xff;
|
---|
70 | for (let n = 0; n < 6; ++n) {
|
---|
71 | buf[offset++] = node[n];
|
---|
72 | }
|
---|
73 | return buf;
|
---|
74 | }
|
---|
75 | export default v1;
|
---|