source: node_modules/short-unique-id/dist/short-unique-id.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 18.9 KB
Line 
1"use strict";
2var ShortUniqueId = (() => {
3 var __defProp = Object.defineProperty;
4 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5 var __getOwnPropNames = Object.getOwnPropertyNames;
6 var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7 var __hasOwnProp = Object.prototype.hasOwnProperty;
8 var __propIsEnum = Object.prototype.propertyIsEnumerable;
9 var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10 var __spreadValues = (a, b) => {
11 for (var prop in b || (b = {}))
12 if (__hasOwnProp.call(b, prop))
13 __defNormalProp(a, prop, b[prop]);
14 if (__getOwnPropSymbols)
15 for (var prop of __getOwnPropSymbols(b)) {
16 if (__propIsEnum.call(b, prop))
17 __defNormalProp(a, prop, b[prop]);
18 }
19 return a;
20 };
21 var __export = (target, all) => {
22 for (var name in all)
23 __defProp(target, name, { get: all[name], enumerable: true });
24 };
25 var __copyProps = (to, from, except, desc) => {
26 if (from && typeof from === "object" || typeof from === "function") {
27 for (let key of __getOwnPropNames(from))
28 if (!__hasOwnProp.call(to, key) && key !== except)
29 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
30 }
31 return to;
32 };
33 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34 var __publicField = (obj, key, value) => {
35 __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
36 return value;
37 };
38
39 // src/index.ts
40 var src_exports = {};
41 __export(src_exports, {
42 DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
43 DEFAULT_UUID_LENGTH: () => DEFAULT_UUID_LENGTH,
44 default: () => ShortUniqueId
45 });
46
47 // package.json
48 var version = "5.0.3";
49
50 // src/index.ts
51 var DEFAULT_UUID_LENGTH = 6;
52 var DEFAULT_OPTIONS = {
53 dictionary: "alphanum",
54 shuffle: true,
55 debug: false,
56 length: DEFAULT_UUID_LENGTH,
57 counter: 0
58 };
59 var _ShortUniqueId = class _ShortUniqueId {
60 constructor(argOptions = {}) {
61 __publicField(this, "counter");
62 __publicField(this, "debug");
63 __publicField(this, "dict");
64 __publicField(this, "version");
65 __publicField(this, "dictIndex", 0);
66 __publicField(this, "dictRange", []);
67 __publicField(this, "lowerBound", 0);
68 __publicField(this, "upperBound", 0);
69 __publicField(this, "dictLength", 0);
70 __publicField(this, "uuidLength");
71 __publicField(this, "_digit_first_ascii", 48);
72 __publicField(this, "_digit_last_ascii", 58);
73 __publicField(this, "_alpha_lower_first_ascii", 97);
74 __publicField(this, "_alpha_lower_last_ascii", 123);
75 __publicField(this, "_hex_last_ascii", 103);
76 __publicField(this, "_alpha_upper_first_ascii", 65);
77 __publicField(this, "_alpha_upper_last_ascii", 91);
78 __publicField(this, "_number_dict_ranges", {
79 digits: [this._digit_first_ascii, this._digit_last_ascii]
80 });
81 __publicField(this, "_alpha_dict_ranges", {
82 lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii],
83 upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii]
84 });
85 __publicField(this, "_alpha_lower_dict_ranges", {
86 lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii]
87 });
88 __publicField(this, "_alpha_upper_dict_ranges", {
89 upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii]
90 });
91 __publicField(this, "_alphanum_dict_ranges", {
92 digits: [this._digit_first_ascii, this._digit_last_ascii],
93 lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii],
94 upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii]
95 });
96 __publicField(this, "_alphanum_lower_dict_ranges", {
97 digits: [this._digit_first_ascii, this._digit_last_ascii],
98 lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii]
99 });
100 __publicField(this, "_alphanum_upper_dict_ranges", {
101 digits: [this._digit_first_ascii, this._digit_last_ascii],
102 upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii]
103 });
104 __publicField(this, "_hex_dict_ranges", {
105 decDigits: [this._digit_first_ascii, this._digit_last_ascii],
106 alphaDigits: [this._alpha_lower_first_ascii, this._hex_last_ascii]
107 });
108 __publicField(this, "_dict_ranges", {
109 _number_dict_ranges: this._number_dict_ranges,
110 _alpha_dict_ranges: this._alpha_dict_ranges,
111 _alpha_lower_dict_ranges: this._alpha_lower_dict_ranges,
112 _alpha_upper_dict_ranges: this._alpha_upper_dict_ranges,
113 _alphanum_dict_ranges: this._alphanum_dict_ranges,
114 _alphanum_lower_dict_ranges: this._alphanum_lower_dict_ranges,
115 _alphanum_upper_dict_ranges: this._alphanum_upper_dict_ranges,
116 _hex_dict_ranges: this._hex_dict_ranges
117 });
118 /* tslint:disable consistent-return */
119 __publicField(this, "log", (...args) => {
120 const finalArgs = [...args];
121 finalArgs[0] = `[short-unique-id] ${args[0]}`;
122 if (this.debug === true) {
123 if (typeof console !== "undefined" && console !== null) {
124 return console.log(...finalArgs);
125 }
126 }
127 });
128 /* tslint:enable consistent-return */
129 /** Change the dictionary after initialization. */
130 __publicField(this, "setDictionary", (dictionary, shuffle) => {
131 let finalDict;
132 if (dictionary && Array.isArray(dictionary) && dictionary.length > 1) {
133 finalDict = dictionary;
134 } else {
135 finalDict = [];
136 let i;
137 this.dictIndex = i = 0;
138 const rangesName = `_${dictionary}_dict_ranges`;
139 const ranges = this._dict_ranges[rangesName];
140 Object.keys(ranges).forEach((rangeType) => {
141 const rangeTypeKey = rangeType;
142 this.dictRange = ranges[rangeTypeKey];
143 this.lowerBound = this.dictRange[0];
144 this.upperBound = this.dictRange[1];
145 for (this.dictIndex = i = this.lowerBound; this.lowerBound <= this.upperBound ? i < this.upperBound : i > this.upperBound; this.dictIndex = this.lowerBound <= this.upperBound ? i += 1 : i -= 1) {
146 finalDict.push(String.fromCharCode(this.dictIndex));
147 }
148 });
149 }
150 if (shuffle) {
151 const PROBABILITY = 0.5;
152 finalDict = finalDict.sort(() => Math.random() - PROBABILITY);
153 }
154 this.dict = finalDict;
155 this.dictLength = this.dict.length;
156 this.setCounter(0);
157 });
158 __publicField(this, "seq", () => {
159 return this.sequentialUUID();
160 });
161 /**
162 * Generates UUID based on internal counter that's incremented after each ID generation.
163 * @alias `const uid = new ShortUniqueId(); uid.seq();`
164 */
165 __publicField(this, "sequentialUUID", () => {
166 let counterDiv;
167 let counterRem;
168 let id = "";
169 counterDiv = this.counter;
170 do {
171 counterRem = counterDiv % this.dictLength;
172 counterDiv = Math.trunc(counterDiv / this.dictLength);
173 id += this.dict[counterRem];
174 } while (counterDiv !== 0);
175 this.counter += 1;
176 return id;
177 });
178 __publicField(this, "rnd", (uuidLength = this.uuidLength || DEFAULT_UUID_LENGTH) => {
179 return this.randomUUID(uuidLength);
180 });
181 /**
182 * Generates UUID by creating each part randomly.
183 * @alias `const uid = new ShortUniqueId(); uid.rnd(uuidLength: number);`
184 */
185 __publicField(this, "randomUUID", (uuidLength = this.uuidLength || DEFAULT_UUID_LENGTH) => {
186 let id;
187 let randomPartIdx;
188 let j;
189 if (uuidLength === null || typeof uuidLength === "undefined" || uuidLength < 1) {
190 throw new Error("Invalid UUID Length Provided");
191 }
192 const isPositive = uuidLength >= 0;
193 id = "";
194 for (j = 0; j < uuidLength; j += 1) {
195 randomPartIdx = parseInt(
196 (Math.random() * this.dictLength).toFixed(0),
197 10
198 ) % this.dictLength;
199 id += this.dict[randomPartIdx];
200 }
201 return id;
202 });
203 __publicField(this, "fmt", (format, date) => {
204 return this.formattedUUID(format, date);
205 });
206 /**
207 * Generates custom UUID with the provided format string.
208 * @alias `const uid = new ShortUniqueId(); uid.fmt(format: string);`
209 */
210 __publicField(this, "formattedUUID", (format, date) => {
211 const fnMap = {
212 "$r": this.randomUUID,
213 "$s": this.sequentialUUID,
214 "$t": this.stamp
215 };
216 const result = format.replace(
217 /\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g,
218 (m) => {
219 const fn = m.slice(0, 2);
220 const len = parseInt(m.slice(2), 10);
221 if (fn === "$s") {
222 return fnMap[fn]().padStart(len, "0");
223 }
224 if (fn === "$t" && date) {
225 return fnMap[fn](len, date);
226 }
227 return fnMap[fn](len);
228 }
229 );
230 return result;
231 });
232 /**
233 * Calculates total number of possible UUIDs.
234 *
235 * Given that:
236 *
237 * - `H` is the total number of possible UUIDs
238 * - `n` is the number of unique characters in the dictionary
239 * - `l` is the UUID length
240 *
241 * Then `H` is defined as `n` to the power of `l`:
242 *
243 * <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;">
244 * <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20H=n%5El"/>
245 * </div>
246 *
247 * This function returns `H`.
248 */
249 __publicField(this, "availableUUIDs", (uuidLength = this.uuidLength) => {
250 return parseFloat(
251 Math.pow([...new Set(this.dict)].length, uuidLength).toFixed(0)
252 );
253 });
254 /**
255 * Calculates approximate number of hashes before first collision.
256 *
257 * Given that:
258 *
259 * - `H` is the total number of possible UUIDs, or in terms of this library,
260 * the result of running `availableUUIDs()`
261 * - the expected number of values we have to choose before finding the
262 * first collision can be expressed as the quantity `Q(H)`
263 *
264 * Then `Q(H)` can be approximated as the square root of the product of half
265 * of pi times `H`:
266 *
267 * <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;">
268 * <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20Q(H)%5Capprox%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7DH%7D"/>
269 * </div>
270 *
271 * This function returns `Q(H)`.
272 *
273 * (see [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution))
274 */
275 __publicField(this, "approxMaxBeforeCollision", (rounds = this.availableUUIDs(this.uuidLength)) => {
276 return parseFloat(
277 Math.sqrt(Math.PI / 2 * rounds).toFixed(20)
278 );
279 });
280 /**
281 * Calculates probability of generating duplicate UUIDs (a collision) in a
282 * given number of UUID generation rounds.
283 *
284 * Given that:
285 *
286 * - `r` is the maximum number of times that `randomUUID()` will be called,
287 * or better said the number of _rounds_
288 * - `H` is the total number of possible UUIDs, or in terms of this library,
289 * the result of running `availableUUIDs()`
290 *
291 * Then the probability of collision `p(r; H)` can be approximated as the result
292 * of dividing the square root of the product of half of pi times `r` by `H`:
293 *
294 * <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;">
295 * <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20p(r%3B%20H)%5Capprox%5Cfrac%7B%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7Dr%7D%7D%7BH%7D"/>
296 * </div>
297 *
298 * This function returns `p(r; H)`.
299 *
300 * (see [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution))
301 *
302 * (Useful if you are wondering _"If I use this lib and expect to perform at most
303 * `r` rounds of UUID generations, what is the probability that I will hit a duplicate UUID?"_.)
304 */
305 __publicField(this, "collisionProbability", (rounds = this.availableUUIDs(this.uuidLength), uuidLength = this.uuidLength) => {
306 return parseFloat(
307 (this.approxMaxBeforeCollision(rounds) / this.availableUUIDs(uuidLength)).toFixed(20)
308 );
309 });
310 /**
311 * Calculate a "uniqueness" score (from 0 to 1) of UUIDs based on size of
312 * dictionary and chosen UUID length.
313 *
314 * Given that:
315 *
316 * - `H` is the total number of possible UUIDs, or in terms of this library,
317 * the result of running `availableUUIDs()`
318 * - `Q(H)` is the approximate number of hashes before first collision,
319 * or in terms of this library, the result of running `approxMaxBeforeCollision()`
320 *
321 * Then `uniqueness` can be expressed as the additive inverse of the probability of
322 * generating a "word" I had previously generated (a duplicate) at any given iteration
323 * up to the the total number of possible UUIDs expressed as the quotiend of `Q(H)` and `H`:
324 *
325 * <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;">
326 * <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%201-%5Cfrac%7BQ(H)%7D%7BH%7D"/>
327 * </div>
328 *
329 * (Useful if you need a value to rate the "quality" of the combination of given dictionary
330 * and UUID length. The closer to 1, higher the uniqueness and thus better the quality.)
331 */
332 __publicField(this, "uniqueness", (rounds = this.availableUUIDs(this.uuidLength)) => {
333 const score = parseFloat(
334 (1 - this.approxMaxBeforeCollision(rounds) / rounds).toFixed(20)
335 );
336 return score > 1 ? 1 : score < 0 ? 0 : score;
337 });
338 /**
339 * Return the version of this module.
340 */
341 __publicField(this, "getVersion", () => {
342 return this.version;
343 });
344 /**
345 * Generates a UUID with a timestamp that can be extracted using `uid.parseStamp(stampString);`.
346 *
347 * ```js
348 * const uidWithTimestamp = uid.stamp(32);
349 * console.log(uidWithTimestamp);
350 * // GDa608f973aRCHLXQYPTbKDbjDeVsSb3
351 *
352 * console.log(uid.parseStamp(uidWithTimestamp));
353 * // 2021-05-03T06:24:58.000Z
354 * ```
355 */
356 __publicField(this, "stamp", (finalLength, date) => {
357 const hexStamp = Math.floor(+(date || /* @__PURE__ */ new Date()) / 1e3).toString(16);
358 if (typeof finalLength === "number" && finalLength === 0) {
359 return hexStamp;
360 }
361 if (typeof finalLength !== "number" || finalLength < 10) {
362 throw new Error(
363 [
364 "Param finalLength must be a number greater than or equal to 10,",
365 "or 0 if you want the raw hexadecimal timestamp"
366 ].join("\n")
367 );
368 }
369 const idLength = finalLength - 9;
370 const rndIdx = Math.round(Math.random() * (idLength > 15 ? 15 : idLength));
371 const id = this.randomUUID(idLength);
372 return `${id.substring(0, rndIdx)}${hexStamp}${id.substring(rndIdx)}${rndIdx.toString(16)}`;
373 });
374 /**
375 * Extracts the date embeded in a UUID generated using the `uid.stamp(finalLength);` method.
376 *
377 * ```js
378 * const uidWithTimestamp = uid.stamp(32);
379 * console.log(uidWithTimestamp);
380 * // GDa608f973aRCHLXQYPTbKDbjDeVsSb3
381 *
382 * console.log(uid.parseStamp(uidWithTimestamp));
383 * // 2021-05-03T06:24:58.000Z
384 * ```
385 */
386 __publicField(this, "parseStamp", (suid, format) => {
387 if (format && !/t0|t[1-9]\d{1,}/.test(format)) {
388 throw new Error("Cannot extract date from a formated UUID with no timestamp in the format");
389 }
390 const stamp = format ? format.replace(
391 /\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g,
392 (m) => {
393 const fnMap = {
394 "$r": (len2) => [...Array(len2)].map(() => "r").join(""),
395 "$s": (len2) => [...Array(len2)].map(() => "s").join(""),
396 "$t": (len2) => [...Array(len2)].map(() => "t").join("")
397 };
398 const fn = m.slice(0, 2);
399 const len = parseInt(m.slice(2), 10);
400 return fnMap[fn](len);
401 }
402 ).replace(
403 /^(.*?)(t{8,})(.*)$/g,
404 (_m, p1, p2) => {
405 return suid.substring(p1.length, p1.length + p2.length);
406 }
407 ) : suid;
408 if (stamp.length === 8) {
409 return new Date(parseInt(stamp, 16) * 1e3);
410 }
411 if (stamp.length < 10) {
412 throw new Error("Stamp length invalid");
413 }
414 const rndIdx = parseInt(stamp.substring(stamp.length - 1), 16);
415 return new Date(parseInt(stamp.substring(rndIdx, rndIdx + 8), 16) * 1e3);
416 });
417 /**
418 * Set the counter to a specific value.
419 */
420 __publicField(this, "setCounter", (counter) => {
421 this.counter = counter;
422 });
423 const options = __spreadValues(__spreadValues({}, DEFAULT_OPTIONS), argOptions);
424 this.counter = 0;
425 this.debug = false;
426 this.dict = [];
427 this.version = version;
428 const {
429 dictionary,
430 shuffle,
431 length,
432 counter
433 } = options;
434 this.uuidLength = length;
435 this.setDictionary(dictionary, shuffle);
436 this.setCounter(counter);
437 this.debug = options.debug;
438 this.log(this.dict);
439 this.log(
440 `Generator instantiated with Dictionary Size ${this.dictLength} and counter set to ${this.counter}`
441 );
442 this.log = this.log.bind(this);
443 this.setDictionary = this.setDictionary.bind(this);
444 this.setCounter = this.setCounter.bind(this);
445 this.seq = this.seq.bind(this);
446 this.sequentialUUID = this.sequentialUUID.bind(this);
447 this.rnd = this.rnd.bind(this);
448 this.randomUUID = this.randomUUID.bind(this);
449 this.fmt = this.fmt.bind(this);
450 this.formattedUUID = this.formattedUUID.bind(this);
451 this.availableUUIDs = this.availableUUIDs.bind(this);
452 this.approxMaxBeforeCollision = this.approxMaxBeforeCollision.bind(this);
453 this.collisionProbability = this.collisionProbability.bind(this);
454 this.uniqueness = this.uniqueness.bind(this);
455 this.getVersion = this.getVersion.bind(this);
456 this.stamp = this.stamp.bind(this);
457 this.parseStamp = this.parseStamp.bind(this);
458 return this;
459 }
460 };
461 /** @hidden */
462 __publicField(_ShortUniqueId, "default", _ShortUniqueId);
463 var ShortUniqueId = _ShortUniqueId;
464 return __toCommonJS(src_exports);
465})();
466//# sourceMappingURL=short-unique-id.js.map
467'undefined'!=typeof module&&(module.exports=ShortUniqueId.default),'undefined'!=typeof window&&(ShortUniqueId=ShortUniqueId.default);
Note: See TracBrowser for help on using the repository browser.