1
- import isFalsy from ' ./isFalsy'
1
+ import isFalsy from " ./isFalsy" ;
2
2
3
- const { Snowflake } = require ( ' ../build/Release/snowflake' ) ;
3
+ const { Snowflake } = require ( " ../build/Release/snowflake" ) ;
4
4
5
5
const CUSTOM_EPOCH = 1546300800000 ; // 01-01-2019
6
6
const MAX_MACHINE_ID = ( 1 << 12 ) - 1 ;
7
7
8
8
interface Config {
9
- customEpoch ?: number ;
10
- returnNumber ?: boolean ;
11
- machineID ?: number ;
9
+ customEpoch ?: number ;
10
+ returnNumber ?: boolean ;
11
+ machineID ?: number ;
12
12
}
13
13
14
14
const initConfig : Config = {
15
- customEpoch : CUSTOM_EPOCH ,
16
- returnNumber : false
17
- }
18
-
19
-
15
+ customEpoch : CUSTOM_EPOCH ,
16
+ returnNumber : false ,
17
+ } ;
20
18
21
19
/**
22
20
* Constructs a UniqueID object which stores method for generation
23
21
* of a unique 64 bit time sortable id and a method for retreiving
24
22
* time of creation for the ids
25
- *
23
+ *
26
24
* @param {config } config
27
25
* in ms, defaults to 1546300800000 (01-01-2019)
28
- *
26
+ *
29
27
* ```
30
28
* const uid = new UniqueID();
31
29
* const ID = uid.getUniqueID();
32
30
* const IDCreateAt = uid.getTimestampFromID(ID);
33
31
* ```
34
32
*/
35
33
export class UniqueID {
36
- private _CUSTOM_EPOCH : number ;
37
- private _snowflake : any ;
38
- private _MACHINE_ID : number ;
39
- private returnNumber = true ;
40
-
41
- constructor ( config : Config = initConfig ) {
42
- this . _CUSTOM_EPOCH = config . customEpoch || CUSTOM_EPOCH ;
43
- this . returnNumber = ! ! config . returnNumber ;
44
-
45
- // A 12 bit machine id, if not passed in then a random id will be used
46
- // Ternary operator was used to make sure "0" isn't considered to be falsy.
47
- this . _MACHINE_ID = (
48
- ! isFalsy ( config . machineID ) ? config . machineID : Math . floor ( Math . random ( ) * MAX_MACHINE_ID )
49
- ) as number ;
50
-
51
- // Check if the number is satisfies all the conditions
52
- if ( ! Number . isInteger ( this . _MACHINE_ID ) ) throw Error ( "Machine Id should be a decimal number" ) ;
53
- if ( this . _MACHINE_ID > MAX_MACHINE_ID ) throw Error ( "Maximum value of machine id can be 2^12 - 1 (4095)" )
54
-
55
- this . _snowflake = new Snowflake ( this . _CUSTOM_EPOCH , this . _MACHINE_ID ) ;
56
- }
57
-
58
- /**
59
- * Generates a unique time sortable 64 bit number using native code
60
- * @returns {string | bigint } the unique id
61
- */
62
- getUniqueID ( ) : string | bigint {
63
- const val = this . _snowflake . getUniqueID ( )
64
- if ( ! this . returnNumber )
65
- return val . toString ( ) ;
66
- return val
67
- }
68
-
69
- /**
70
- * Promisified unique id function
71
- * @returns {Promise<string | number> } promise to a unique 64 bit long id
72
- */
73
- async asyncGetUniqueID ( ) : Promise < string | bigint > {
74
- return new Promise ( resolve => resolve ( this . getUniqueID ( ) ) )
75
- }
76
-
77
- /**
78
- * Retrieves the epoch/unix timestamp at which the ID was generated
79
- * irrespective of the machine it was generated on, PROVIDED no or same
80
- * custom epoch was used in generation
81
- * @param {number | string } id generated through getUniqueID method
82
- * @returns {number } timestamp of id creations
83
- */
84
- getTimestampFromID ( id : bigint | string ) : number {
85
- return this . _snowflake . getTimestampFromID ( id ) ;
86
- }
87
-
88
- /**
89
- * Retrieves the 12 bit machine id where the id was generated,
90
- * irrespective of the machine it was generated on.
91
- * @param id
92
- */
93
- getMachineIDFromID ( id : bigint | string ) : number {
94
- return this . _snowflake . getNodeIDFromID ( id ) ;
95
- }
96
-
97
- /**
98
- * Machine ID of the current machine. This ID is of 12 bit.
99
- * This can be either provided by the user (preferred) or will be assigned
100
- * randomly.
101
- */
102
- get machineID ( ) {
103
- return this . _MACHINE_ID ;
104
- }
105
- }
34
+ private _CUSTOM_EPOCH : number ;
35
+ private _snowflake : any ;
36
+ private _MACHINE_ID : number ;
37
+ private returnNumber = true ;
38
+
39
+ constructor ( config : Config = initConfig ) {
40
+ this . _CUSTOM_EPOCH = config . customEpoch || CUSTOM_EPOCH ;
41
+ this . returnNumber = ! ! config . returnNumber ;
42
+ this . _MACHINE_ID = getMachineID ( config . machineID ) ;
43
+
44
+ this . _snowflake = new Snowflake ( this . _CUSTOM_EPOCH , this . _MACHINE_ID ) ;
45
+ }
46
+
47
+ /**
48
+ * Generates a unique time sortable 64 bit number using native code
49
+ * @returns {string | bigint } the unique id
50
+ */
51
+ getUniqueID ( ) : string | bigint {
52
+ const val = this . _snowflake . getUniqueID ( ) ;
53
+ if ( ! this . returnNumber ) return val . toString ( ) ;
54
+ return val ;
55
+ }
56
+
57
+ /**
58
+ * Promisified unique id function
59
+ * @returns {Promise<string | number> } promise to a unique 64 bit long id
60
+ */
61
+ async asyncGetUniqueID ( ) : Promise < string | bigint > {
62
+ return new Promise ( ( resolve ) => resolve ( this . getUniqueID ( ) ) ) ;
63
+ }
64
+
65
+ /**
66
+ * Retrieves the epoch/unix timestamp at which the ID was generated
67
+ * irrespective of the machine it was generated on, PROVIDED no or same
68
+ * custom epoch was used in generation
69
+ * @param {number | string } id generated through getUniqueID method
70
+ * @returns {number } timestamp of id creations
71
+ */
72
+ getTimestampFromID ( id : bigint | string ) : number {
73
+ return this . _snowflake . getTimestampFromID ( id ) ;
74
+ }
75
+
76
+ /**
77
+ * Retrieves the 12 bit machine id where the id was generated,
78
+ * irrespective of the machine it was generated on.
79
+ * @param {bigint | string } id unique ID
80
+ * @returns {number } machine ID
81
+ */
82
+ getMachineIDFromID ( id : bigint | string ) : number {
83
+ return this . _snowflake . getNodeIDFromID ( id ) ;
84
+ }
85
+
86
+ /**
87
+ * getIDFromTimestamp generates an ID corresponding to the given timestamp
88
+ *
89
+ * This ID is generated with sequence number 0
90
+ *
91
+ * Ideal for use cases where a database query requires to entries created after some timestamp
92
+ * @param {number | string } timestamp timestamp corresponding to which an ID is required
93
+ * @returns {bigint } ID corresponding to the timestamp
94
+ */
95
+ getIDFromTimestamp ( timestamp : number | string ) : bigint {
96
+ return this . _snowflake . getIDFromTimestamp ( timestamp ) ;
97
+ }
98
+
99
+ /**
100
+ * Machine ID of the current machine. This ID is of 12 bit.
101
+ * This can be either provided by the user (preferred) or will be assigned
102
+ * randomly.
103
+ */
104
+ get machineID ( ) {
105
+ return this . _MACHINE_ID ;
106
+ }
107
+ }
108
+
109
+ /**
110
+ * getMachineID takes in a machine id and verifies if it withstand
111
+ * the following contraints:
112
+ *
113
+ * 1. Should not be "falsy" but could be 0
114
+ * 2. Should be of type "number"
115
+ * 3. Is a whole number
116
+ * 4. Doesn't exceeds the limit of 4095
117
+ *
118
+ * It will return a random value ε [0, 4095] if parameter is
119
+ * undefined
120
+ * @param mid machine id
121
+ */
122
+ function getMachineID ( mid : number | undefined ) : number {
123
+ let id = 0 ;
124
+
125
+ if ( isFalsy ( mid ) || typeof mid !== "number" )
126
+ id = Math . floor ( Math . random ( ) * MAX_MACHINE_ID ) ;
127
+ else id = mid ;
128
+
129
+ verifyMachineID ( id ) ;
130
+
131
+ return id ;
132
+ }
133
+
134
+ function verifyMachineID ( mid : number ) {
135
+ if ( ! Number . isInteger ( mid ) )
136
+ throw Error ( "Machine Id should be a decimal number" ) ;
137
+ if ( mid > MAX_MACHINE_ID )
138
+ throw Error ( "Maximum value of machine id can be 2^12 - 1 (4095)" ) ;
139
+ }
0 commit comments