Skip to content

Commit b8aa1f9

Browse files
committed
expose getIDFromTimestamp
Signed-off-by: Utkarsh Srivastava <srivastavautkarsh8097@gmail.com>
1 parent e5ead3c commit b8aa1f9

File tree

2 files changed

+119
-83
lines changed

2 files changed

+119
-83
lines changed

src/generateUniqueID.ts

Lines changed: 116 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,139 @@
1-
import isFalsy from './isFalsy'
1+
import isFalsy from "./isFalsy";
22

3-
const { Snowflake } = require('../build/Release/snowflake');
3+
const { Snowflake } = require("../build/Release/snowflake");
44

55
const CUSTOM_EPOCH = 1546300800000; // 01-01-2019
66
const MAX_MACHINE_ID = (1 << 12) - 1;
77

88
interface Config {
9-
customEpoch?: number;
10-
returnNumber?: boolean;
11-
machineID?: number;
9+
customEpoch?: number;
10+
returnNumber?: boolean;
11+
machineID?: number;
1212
}
1313

1414
const initConfig: Config = {
15-
customEpoch: CUSTOM_EPOCH,
16-
returnNumber: false
17-
}
18-
19-
15+
customEpoch: CUSTOM_EPOCH,
16+
returnNumber: false,
17+
};
2018

2119
/**
2220
* Constructs a UniqueID object which stores method for generation
2321
* of a unique 64 bit time sortable id and a method for retreiving
2422
* time of creation for the ids
25-
*
23+
*
2624
* @param {config} config
2725
* in ms, defaults to 1546300800000 (01-01-2019)
28-
*
26+
*
2927
* ```
3028
* const uid = new UniqueID();
3129
* const ID = uid.getUniqueID();
3230
* const IDCreateAt = uid.getTimestampFromID(ID);
3331
* ```
3432
*/
3533
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+
}

src/isFalsy.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
export default (value: any) => {
1+
export default (value: any): boolean => {
22
if (value === undefined) return true;
33
if (isNaN(value)) return true;
44
if (Array.isArray(value) && !value.length) return true;
55
if (value === "") return true;
66
if (value === null) return true;
7+
8+
return false
79
}

0 commit comments

Comments
 (0)