@ibiliaze/stringman 3.12.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/order.d.ts +0 -4
- package/dist/order.js +26 -58
- package/package.json +2 -2
- package/src/order.ts +29 -58
package/dist/order.d.ts
CHANGED
package/dist/order.js
CHANGED
|
@@ -1,74 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// orderId-numeric.
|
|
3
|
-
//
|
|
2
|
+
// src/orderId-numeric.ts
|
|
3
|
+
// 20 digits: <unixMs(13)><counter(4)><random(3)>
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
5
|
exports.createNumericOrderId = void 0;
|
|
6
6
|
let _lastMs = 0;
|
|
7
7
|
let _ctr = 0;
|
|
8
|
+
const cryptoObj = globalThis.crypto;
|
|
8
9
|
const randomDigits = (n) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const out = [];
|
|
12
|
-
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
13
|
-
const buf = new Uint8Array(n);
|
|
14
|
-
let i = 0;
|
|
15
|
-
while (i < n) {
|
|
16
|
-
const b = new Uint8Array(1);
|
|
17
|
-
crypto.getRandomValues(b);
|
|
18
|
-
const x = b[0];
|
|
19
|
-
if (x < 250) {
|
|
20
|
-
// 250 is 25*10, rejection sampling to avoid bias
|
|
21
|
-
out.push((x % 10).toString());
|
|
22
|
-
i++;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
// Node.js fallback
|
|
28
|
-
const { randomBytes } = require('crypto');
|
|
29
|
-
let i = 0;
|
|
30
|
-
while (i < n) {
|
|
31
|
-
const b = randomBytes(1)[0];
|
|
32
|
-
if (b < 250) {
|
|
33
|
-
out.push((b % 10).toString());
|
|
34
|
-
i++;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return out.join('');
|
|
10
|
+
if (!cryptoObj?.getRandomValues) {
|
|
11
|
+
throw new Error('Secure RNG not available. Use Node 18+ (globalThis.crypto) or a browser with Web Crypto.');
|
|
39
12
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
13
|
+
const out = [];
|
|
14
|
+
const b = new Uint8Array(1);
|
|
15
|
+
while (out.length < n) {
|
|
16
|
+
cryptoObj.getRandomValues(b);
|
|
17
|
+
const x = b[0];
|
|
18
|
+
if (x < 250)
|
|
19
|
+
out.push(String(x % 10)); // rejection sampling avoids modulo bias
|
|
43
20
|
}
|
|
21
|
+
return out.join('');
|
|
44
22
|
};
|
|
45
|
-
/**
|
|
46
|
-
* createNumericOrderId
|
|
47
|
-
* @returns {string} 20-digit, digits-only, sortable ID
|
|
48
|
-
*/
|
|
49
23
|
const createNumericOrderId = () => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
while (Date.now() === now) { } // busy-wait a fraction of a ms
|
|
57
|
-
_ctr = 0;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
_lastMs = now;
|
|
24
|
+
const now = Date.now(); // 13 digits
|
|
25
|
+
if (now === _lastMs) {
|
|
26
|
+
_ctr++;
|
|
27
|
+
if (_ctr > 9999) {
|
|
28
|
+
// non-blocking: bump ms instead of busy-wait
|
|
29
|
+
_lastMs = now + 1;
|
|
62
30
|
_ctr = 0;
|
|
63
31
|
}
|
|
64
|
-
const timePart = String(now); // 13
|
|
65
|
-
const ctrPart = String(_ctr).padStart(4, '0'); // 4
|
|
66
|
-
const randPart = randomDigits(3); // 3
|
|
67
|
-
return timePart + ctrPart + randPart; // 20 digits
|
|
68
32
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
33
|
+
else {
|
|
34
|
+
_lastMs = now;
|
|
35
|
+
_ctr = 0;
|
|
72
36
|
}
|
|
37
|
+
const timePart = String(_lastMs);
|
|
38
|
+
const ctrPart = String(_ctr).padStart(4, '0');
|
|
39
|
+
const randPart = randomDigits(3);
|
|
40
|
+
return timePart + ctrPart + randPart; // 20 digits
|
|
73
41
|
};
|
|
74
42
|
exports.createNumericOrderId = createNumericOrderId;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ibiliaze/stringman",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"pub": "npm publish --access public",
|
|
10
|
-
"git": "git add .; git commit -m 'changes'; git tag -a v3.
|
|
10
|
+
"git": "git add .; git commit -m 'changes'; git tag -a v3.13.0 -m 'v3.13.0'; git push origin v3.13.0; git push",
|
|
11
11
|
"push": "npm run build; npm run git; npm run pub"
|
|
12
12
|
},
|
|
13
13
|
"author": "Ibi Hasanli",
|
package/src/order.ts
CHANGED
|
@@ -1,72 +1,43 @@
|
|
|
1
|
-
// orderId-numeric.
|
|
2
|
-
//
|
|
1
|
+
// src/orderId-numeric.ts
|
|
2
|
+
// 20 digits: <unixMs(13)><counter(4)><random(3)>
|
|
3
3
|
|
|
4
4
|
let _lastMs = 0;
|
|
5
5
|
let _ctr = 0;
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// 250 is 25*10, rejection sampling to avoid bias
|
|
20
|
-
out.push((x % 10).toString());
|
|
21
|
-
i++;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
} else {
|
|
25
|
-
// Node.js fallback
|
|
26
|
-
const { randomBytes } = require('crypto');
|
|
27
|
-
let i = 0;
|
|
28
|
-
while (i < n) {
|
|
29
|
-
const b = randomBytes(1)[0];
|
|
30
|
-
if (b < 250) {
|
|
31
|
-
out.push((b % 10).toString());
|
|
32
|
-
i++;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return out.join('');
|
|
37
|
-
} catch (e) {
|
|
38
|
-
console.error(e);
|
|
39
|
-
return '';
|
|
7
|
+
const cryptoObj = (globalThis as any).crypto as Crypto | undefined;
|
|
8
|
+
|
|
9
|
+
const randomDigits = (n: number): string => {
|
|
10
|
+
if (!cryptoObj?.getRandomValues) {
|
|
11
|
+
throw new Error('Secure RNG not available. Use Node 18+ (globalThis.crypto) or a browser with Web Crypto.');
|
|
12
|
+
}
|
|
13
|
+
const out: string[] = [];
|
|
14
|
+
const b = new Uint8Array(1);
|
|
15
|
+
while (out.length < n) {
|
|
16
|
+
cryptoObj.getRandomValues(b);
|
|
17
|
+
const x = b[0];
|
|
18
|
+
if (x < 250) out.push(String(x % 10)); // rejection sampling avoids modulo bias
|
|
40
19
|
}
|
|
20
|
+
return out.join('');
|
|
41
21
|
};
|
|
42
22
|
|
|
43
|
-
/**
|
|
44
|
-
* createNumericOrderId
|
|
45
|
-
* @returns {string} 20-digit, digits-only, sortable ID
|
|
46
|
-
*/
|
|
47
23
|
export const createNumericOrderId = (): string => {
|
|
48
|
-
|
|
49
|
-
const now = Date.now(); // 13 digits
|
|
24
|
+
const now = Date.now(); // 13 digits
|
|
50
25
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
_ctr = 0;
|
|
57
|
-
}
|
|
58
|
-
} else {
|
|
59
|
-
_lastMs = now;
|
|
26
|
+
if (now === _lastMs) {
|
|
27
|
+
_ctr++;
|
|
28
|
+
if (_ctr > 9999) {
|
|
29
|
+
// non-blocking: bump ms instead of busy-wait
|
|
30
|
+
_lastMs = now + 1;
|
|
60
31
|
_ctr = 0;
|
|
61
32
|
}
|
|
33
|
+
} else {
|
|
34
|
+
_lastMs = now;
|
|
35
|
+
_ctr = 0;
|
|
36
|
+
}
|
|
62
37
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
38
|
+
const timePart = String(_lastMs);
|
|
39
|
+
const ctrPart = String(_ctr).padStart(4, '0');
|
|
40
|
+
const randPart = randomDigits(3);
|
|
66
41
|
|
|
67
|
-
|
|
68
|
-
} catch (e) {
|
|
69
|
-
console.error(e);
|
|
70
|
-
return '';
|
|
71
|
-
}
|
|
42
|
+
return timePart + ctrPart + randPart; // 20 digits
|
|
72
43
|
};
|