cynx-lib 1.3.28
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/index.js +3 -0
- package/package.json +36 -0
- package/ui/components/ActionsMenu.jsx +158 -0
- package/ui/components/ActivityCard.jsx +184 -0
- package/ui/components/AuthOverlay.jsx +94 -0
- package/ui/components/Badge.jsx +186 -0
- package/ui/components/BrandingCard.jsx +146 -0
- package/ui/components/Button.jsx +148 -0
- package/ui/components/Card.jsx +132 -0
- package/ui/components/Checkbox.jsx +59 -0
- package/ui/components/ChipSelect.jsx +54 -0
- package/ui/components/CircularProgress.jsx +216 -0
- package/ui/components/Confirm.jsx +79 -0
- package/ui/components/DatePicker.jsx +605 -0
- package/ui/components/Divider.jsx +96 -0
- package/ui/components/Dropzone.jsx +203 -0
- package/ui/components/FilePicker.jsx +205 -0
- package/ui/components/HoverCard.jsx +81 -0
- package/ui/components/ImageUpload.jsx +147 -0
- package/ui/components/InfoBadge.jsx +204 -0
- package/ui/components/Input.jsx +229 -0
- package/ui/components/LineProgress.jsx +133 -0
- package/ui/components/LinearProgress.jsx +132 -0
- package/ui/components/Modal.jsx +212 -0
- package/ui/components/Pagination.jsx +52 -0
- package/ui/components/PulseDot.jsx +77 -0
- package/ui/components/Select.jsx +415 -0
- package/ui/components/Skeleton.jsx +118 -0
- package/ui/components/Spinner.jsx +108 -0
- package/ui/components/StatBarCard.jsx +25 -0
- package/ui/components/StatsBar.jsx +88 -0
- package/ui/components/StatsCard.jsx +171 -0
- package/ui/components/TabBar.jsx +404 -0
- package/ui/components/Tabs.jsx +29 -0
- package/ui/components/TimePicker.jsx +1069 -0
- package/ui/components/Toast.jsx +106 -0
- package/ui/components/Toggle.jsx +67 -0
- package/ui/components/UptimeBar.jsx +135 -0
- package/ui/components/XTable.jsx +44 -0
- package/ui/index.js +97 -0
- package/utils/index.js +11 -0
- package/utils/utils/oidc.js +209 -0
- package/utils/utils/realtime.js +1040 -0
- package/utils/utils/storage.js +393 -0
- package/utils/utils/tz.js +625 -0
- package/utils/utils/uid.js +252 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cynx/utils — Universal UID / UUID Generator
|
|
3
|
+
*
|
|
4
|
+
* Works seamlessly in Browser, Node.js, Web Workers, React Native, and SSR/Edge environments.
|
|
5
|
+
* Cryptographically secure with zero external dependencies and graceful fallbacks.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const ALPHABETS = {
|
|
9
|
+
urlSafe: 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLFGQZ_rich5hexURL',
|
|
10
|
+
alphanumeric: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
|
|
11
|
+
lowercase: '0123456789abcdefghijklmnopqrstuvwxyz',
|
|
12
|
+
uppercase: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
|
13
|
+
numeric: '0123456789',
|
|
14
|
+
hex: '0123456789abcdef',
|
|
15
|
+
// Human-friendly alphabet without lookalikes (no 0, O, I, l, 1)
|
|
16
|
+
noLookalikes: '346789ABCDEFGHJKLMNPQRTUVWXYabcdefghijkmnpqrtwxyz',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Safely obtain the Crypto interface across all JS runtime environments.
|
|
21
|
+
*/
|
|
22
|
+
function getCrypto() {
|
|
23
|
+
if (typeof globalThis !== 'undefined' && globalThis.crypto) {
|
|
24
|
+
return globalThis.crypto;
|
|
25
|
+
}
|
|
26
|
+
if (typeof window !== 'undefined' && window.crypto) {
|
|
27
|
+
return window.crypto;
|
|
28
|
+
}
|
|
29
|
+
if (typeof self !== 'undefined' && self.crypto) {
|
|
30
|
+
return self.crypto;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fill a Uint8Array with cryptographically secure random bytes.
|
|
37
|
+
* Falls back to high-entropy pseudo-random bytes if Web Crypto is unavailable.
|
|
38
|
+
*
|
|
39
|
+
* @param {number} [size=16]
|
|
40
|
+
* @returns {Uint8Array}
|
|
41
|
+
*/
|
|
42
|
+
export function getRandomBytes(size = 16) {
|
|
43
|
+
const bytes = new Uint8Array(size);
|
|
44
|
+
const cryptoObj = getCrypto();
|
|
45
|
+
if (cryptoObj && typeof cryptoObj.getRandomValues === 'function') {
|
|
46
|
+
cryptoObj.getRandomValues(bytes);
|
|
47
|
+
return bytes;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Fallback for non-secure / legacy environments
|
|
51
|
+
for (let i = 0; i < size; i++) {
|
|
52
|
+
const timeJitter = ((Date.now() + (typeof performance !== 'undefined' ? performance.now() : 0)) * 1000) % 256;
|
|
53
|
+
bytes[i] = (Math.floor(Math.random() * 256) ^ Math.floor(timeJitter)) & 0xff;
|
|
54
|
+
}
|
|
55
|
+
return bytes;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generate standard RFC 4122 version 4 UUID.
|
|
60
|
+
* Uses native crypto.randomUUID() when available.
|
|
61
|
+
*
|
|
62
|
+
* Example: "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
|
|
63
|
+
*
|
|
64
|
+
* @returns {string}
|
|
65
|
+
*/
|
|
66
|
+
export function uuid() {
|
|
67
|
+
const cryptoObj = getCrypto();
|
|
68
|
+
if (cryptoObj && typeof cryptoObj.randomUUID === 'function') {
|
|
69
|
+
return cryptoObj.randomUUID();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// RFC 4122 v4 generator fallback
|
|
73
|
+
const bytes = getRandomBytes(16);
|
|
74
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4
|
|
75
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant 10xx
|
|
76
|
+
|
|
77
|
+
let out = '';
|
|
78
|
+
for (let i = 0; i < 16; i++) {
|
|
79
|
+
if (i === 4 || i === 6 || i === 8 || i === 10) out += '-';
|
|
80
|
+
out += bytes[i].toString(16).padStart(2, '0');
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const uuidv4 = uuid;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create a custom ID generator with a given alphabet and default length.
|
|
89
|
+
* Features uniform distribution (zero modulo bias).
|
|
90
|
+
*
|
|
91
|
+
* @param {string} [alphabet=ALPHABETS.urlSafe]
|
|
92
|
+
* @param {number} [defaultSize=21]
|
|
93
|
+
* @returns {(size?: number) => string}
|
|
94
|
+
*/
|
|
95
|
+
export function customAlphabet(alphabet = ALPHABETS.urlSafe, defaultSize = 21) {
|
|
96
|
+
const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1;
|
|
97
|
+
const step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length);
|
|
98
|
+
|
|
99
|
+
return function generate(size = defaultSize) {
|
|
100
|
+
let id = '';
|
|
101
|
+
while (true) {
|
|
102
|
+
const bytes = getRandomBytes(step);
|
|
103
|
+
for (let i = 0; i < step; i++) {
|
|
104
|
+
const byte = bytes[i] & mask;
|
|
105
|
+
if (alphabet[byte]) {
|
|
106
|
+
id += alphabet[byte];
|
|
107
|
+
if (id.length === size) return id;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Generate a fast, URL-friendly unique ID (similar to NanoID).
|
|
116
|
+
*
|
|
117
|
+
* @param {number} [size=12] Length of the generated ID (default: 12)
|
|
118
|
+
* @param {string} [alphabet=ALPHABETS.urlSafe] Custom alphabet string
|
|
119
|
+
* @returns {string}
|
|
120
|
+
*/
|
|
121
|
+
export function uid(size = 12, alphabet = ALPHABETS.urlSafe) {
|
|
122
|
+
if (alphabet === ALPHABETS.urlSafe) {
|
|
123
|
+
const bytes = getRandomBytes(size);
|
|
124
|
+
let id = '';
|
|
125
|
+
const len = alphabet.length;
|
|
126
|
+
for (let i = 0; i < size; i++) {
|
|
127
|
+
id += alphabet[bytes[i] % len];
|
|
128
|
+
}
|
|
129
|
+
return id;
|
|
130
|
+
}
|
|
131
|
+
return customAlphabet(alphabet, size)(size);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* NanoID-compatible generator.
|
|
136
|
+
*
|
|
137
|
+
* @param {number} [size=21]
|
|
138
|
+
* @returns {string}
|
|
139
|
+
*/
|
|
140
|
+
export const nanoid = (size = 21) => uid(size, ALPHABETS.urlSafe);
|
|
141
|
+
export const genUid = (size = 12) => uid(size, ALPHABETS.urlSafe);
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Generate a compact alphanumeric ID.
|
|
145
|
+
* Example: "9xKb7Zm2"
|
|
146
|
+
*
|
|
147
|
+
* @param {number} [size=8]
|
|
148
|
+
* @returns {string}
|
|
149
|
+
*/
|
|
150
|
+
export function shortId(size = 8) {
|
|
151
|
+
return uid(size, ALPHABETS.alphanumeric);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Generate a prefixed unique identifier (ideal for React keys, DOM IDs, and entity records).
|
|
156
|
+
* Example: prefixedId('usr', 10) => "usr_9xKb7Zm20A"
|
|
157
|
+
*
|
|
158
|
+
* @param {string} [prefix='id']
|
|
159
|
+
* @param {number} [size=12]
|
|
160
|
+
* @param {string} [alphabet=ALPHABETS.alphanumeric]
|
|
161
|
+
* @returns {string}
|
|
162
|
+
*/
|
|
163
|
+
export function prefixedId(prefix = 'id', size = 12, alphabet = ALPHABETS.alphanumeric) {
|
|
164
|
+
return `${prefix}_${uid(size, alphabet)}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Create an incremental sequence ID generator (safe for SSR, React unique keys, form labels).
|
|
169
|
+
* Example:
|
|
170
|
+
* const nextId = createSequence('modal');
|
|
171
|
+
* nextId() // "modal_1"
|
|
172
|
+
* nextId() // "modal_2"
|
|
173
|
+
*
|
|
174
|
+
* @param {string} [prefix='cynx']
|
|
175
|
+
* @returns {(customPrefix?: string) => string}
|
|
176
|
+
*/
|
|
177
|
+
export function createSequence(prefix = 'cynx') {
|
|
178
|
+
let counter = 0;
|
|
179
|
+
return function next(customPrefix = prefix) {
|
|
180
|
+
counter += 1;
|
|
181
|
+
return `${customPrefix}_${counter}`;
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Global default sequence ID generator.
|
|
187
|
+
*/
|
|
188
|
+
export const seqId = createSequence('cynx');
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Generate a time-sortable unique ID (timestamp in base36 + random entropy).
|
|
192
|
+
* Perfect for log entries, time-ordered database records, and transaction IDs.
|
|
193
|
+
* Example: "18f2a4bc890_9xk2b7qm"
|
|
194
|
+
*
|
|
195
|
+
* @param {string} [prefix='']
|
|
196
|
+
* @returns {string}
|
|
197
|
+
*/
|
|
198
|
+
export function timestampId(prefix = '') {
|
|
199
|
+
const ts = Date.now().toString(36);
|
|
200
|
+
const rand = uid(8, ALPHABETS.lowercase);
|
|
201
|
+
return prefix ? `${prefix}_${ts}_${rand}` : `${ts}_${rand}`;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Validate standard UUID string format (v1-v5).
|
|
206
|
+
*
|
|
207
|
+
* @param {unknown} str
|
|
208
|
+
* @returns {boolean}
|
|
209
|
+
*/
|
|
210
|
+
export function isValidUUID(str) {
|
|
211
|
+
if (typeof str !== 'string') return false;
|
|
212
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(str);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Validate custom UID format with optional length and alphabet constraints.
|
|
217
|
+
*
|
|
218
|
+
* @param {unknown} str
|
|
219
|
+
* @param {object} [options]
|
|
220
|
+
* @param {number} [options.minLength=1]
|
|
221
|
+
* @param {number} [options.maxLength=128]
|
|
222
|
+
* @param {string} [options.alphabet]
|
|
223
|
+
* @returns {boolean}
|
|
224
|
+
*/
|
|
225
|
+
export function isValidUID(str, { minLength = 1, maxLength = 128, alphabet } = {}) {
|
|
226
|
+
if (typeof str !== 'string') return false;
|
|
227
|
+
if (str.length < minLength || str.length > maxLength) return false;
|
|
228
|
+
if (alphabet) {
|
|
229
|
+
const chars = new Set(alphabet);
|
|
230
|
+
for (const char of str) {
|
|
231
|
+
if (!chars.has(char)) return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export default {
|
|
238
|
+
uuid,
|
|
239
|
+
uuidv4,
|
|
240
|
+
uid,
|
|
241
|
+
nanoid,
|
|
242
|
+
shortId,
|
|
243
|
+
prefixedId,
|
|
244
|
+
timestampId,
|
|
245
|
+
createSequence,
|
|
246
|
+
seqId,
|
|
247
|
+
customAlphabet,
|
|
248
|
+
getRandomBytes,
|
|
249
|
+
isValidUUID,
|
|
250
|
+
isValidUID,
|
|
251
|
+
ALPHABETS,
|
|
252
|
+
};
|