@@ -61,12 +61,21 @@ class Snowflake : public Napi::ObjectWrap<Snowflake>
61
61
Napi::Value getUniqueIDBigInt (const Napi::CallbackInfo &info);
62
62
Napi::Value getTimestampFromID (const Napi::CallbackInfo &info);
63
63
Napi::Value getNodeIDFomID (const Napi::CallbackInfo &info);
64
+ Napi::Value getIDFromTimestamp (const Napi::CallbackInfo &info);
64
65
};
65
66
66
67
Napi::Object Snowflake::Init (Napi::Env env, Napi::Object exports)
67
68
{
68
69
// This method is used to hook the accessor and method callbacks
69
- auto func = DefineClass (env, " Snowflake" , {InstanceMethod (" getUniqueID" , &Snowflake::getUniqueIDBigInt), InstanceMethod (" getTimestampFromID" , &Snowflake::getTimestampFromID), InstanceMethod (" getNodeIDFromID" , &Snowflake::getNodeIDFomID)});
70
+ auto func = DefineClass (
71
+ env,
72
+ " Snowflake" ,
73
+ {
74
+ InstanceMethod (" getUniqueID" , &Snowflake::getUniqueIDBigInt),
75
+ InstanceMethod (" getTimestampFromID" , &Snowflake::getTimestampFromID),
76
+ InstanceMethod (" getNodeIDFromID" , &Snowflake::getNodeIDFomID),
77
+ InstanceMethod (" getIDFromTimestamp" , &Snowflake::getIDFromTimestamp),
78
+ });
70
79
71
80
// Create a peristent reference to the class constructor. This will allow
72
81
// a function called on a class prototype and a function
@@ -152,13 +161,14 @@ Napi::Value Snowflake::getTimestampFromID(const Napi::CallbackInfo &info)
152
161
153
162
uniqueID = std::stoull (first.Utf8Value ());
154
163
}
155
- else if (info[0 ].IsNumber ())
164
+ else if (info[0 ].IsBigInt ())
156
165
{
157
- uniqueID = info[0 ].As <Napi::Number>().Int64Value ();
166
+ bool lossless = true ;
167
+ uniqueID = info[0 ].As <Napi::BigInt>().Int64Value (&lossless);
158
168
}
159
169
else
160
170
{
161
- Napi::TypeError::New (env, " Number or string expected" ).ThrowAsJavaScriptException ();
171
+ Napi::TypeError::New (env, " BigInt or string expected" ).ThrowAsJavaScriptException ();
162
172
}
163
173
164
174
uint64_t timestamp = uniqueID >> (TOTAL_BITS - EPOCH_BITS);
@@ -167,9 +177,7 @@ Napi::Value Snowflake::getTimestampFromID(const Napi::CallbackInfo &info)
167
177
}
168
178
169
179
/* *
170
- * Returns timestamp at which the id was generated by retreiving
171
- * the first 42 bits of the id, which are filled with current timestamp
172
- * bits
180
+ * Returns NodeID/Machine ID at which the id was generated
173
181
*/
174
182
Napi::Value Snowflake::getNodeIDFomID (const Napi::CallbackInfo &info)
175
183
{
@@ -182,13 +190,14 @@ Napi::Value Snowflake::getNodeIDFomID(const Napi::CallbackInfo &info)
182
190
183
191
uniqueID = std::stoull (first.Utf8Value ());
184
192
}
185
- else if (info[0 ].IsNumber ())
193
+ else if (info[0 ].IsBigInt ())
186
194
{
187
- uniqueID = info[0 ].As <Napi::Number>().Int64Value ();
195
+ bool lossless = true ;
196
+ uniqueID = info[0 ].As <Napi::BigInt>().Int64Value (&lossless);
188
197
}
189
198
else
190
199
{
191
- Napi::TypeError::New (env, " Number or string expected" ).ThrowAsJavaScriptException ();
200
+ Napi::TypeError::New (env, " BigInt or string expected" ).ThrowAsJavaScriptException ();
192
201
}
193
202
194
203
int BITS = TOTAL_BITS - NODE_ID_BITS - SEQUENCE_BITS;
@@ -197,6 +206,39 @@ Napi::Value Snowflake::getNodeIDFomID(const Napi::CallbackInfo &info)
197
206
return Napi::Number::New (env, machineID);
198
207
}
199
208
209
+ /* *
210
+ * getIDFromTimestamp takes in a timestamp and will produce
211
+ * id corresponding to that timestamp. It will generate ID with
212
+ * sequence number 0.
213
+ *
214
+ * This method can be useful in writing SQL queries
215
+ * where you want results which were created after
216
+ * a certain timestamp
217
+ */
218
+ Napi::Value Snowflake::getIDFromTimestamp (const Napi::CallbackInfo &info)
219
+ {
220
+ auto env = info.Env ();
221
+ uint64_t timestamp = 0 ;
222
+
223
+ if (info[0 ].IsString ())
224
+ {
225
+ auto first = info[0 ].As <Napi::String>();
226
+ timestamp = std::stoull (first.Utf8Value ());
227
+ }
228
+ else if (info[0 ].IsNumber ())
229
+ {
230
+ timestamp = info[0 ].As <Napi::Number>().Int64Value ();
231
+ }
232
+
233
+ uint64_t currentTimestamp = timestamp - this ->_CUSTOM_EPOCH ;
234
+
235
+ uint64_t id{};
236
+ id = currentTimestamp << (TOTAL_BITS - EPOCH_BITS);
237
+ id |= (this ->_nodeID << (TOTAL_BITS - EPOCH_BITS - NODE_ID_BITS));
238
+
239
+ return Napi::BigInt::New (env, id);
240
+ }
241
+
200
242
// ////////////////////////////////////////////////////////////////////////////////////////
201
243
202
244
Napi::Object InitAll (Napi::Env env, Napi::Object exports)
0 commit comments