Last active
December 23, 2019 21:55
-
-
Save manchuck/9aa5d08a41cc2f306fc0bbdf7ee54072 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @fileOverview Generate an Id | |
*/ | |
const _ = require('lodash'); | |
const Hashids = require('hashids'); | |
const hashids = new Hashids( | |
'', | |
null, | |
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-', | |
); | |
const SEQUENCE_BITS = 12; | |
const CUSTOM_EPOCH = 1514725199000n; | |
const maxSequence = Math.pow(2, SEQUENCE_BITS) - 1; | |
let currentTimestamp = BigInt(new Date().getTime()) - CUSTOM_EPOCH; | |
let lastTimestamp = currentTimestamp; | |
let sequence = 0; | |
/** | |
* Create a nodeId buffer | |
* | |
* Read in the mac addresses into a buffer | |
* | |
* @type {(function(): Buffer) & MemoizedFunction} | |
*/ | |
const createNodeId = _.memoize(() => { | |
const interfaces = _.compact( | |
_.flatMap( | |
require('os').networkInterfaces(), | |
(value) => { | |
return _.map(value, (ifaceData) => { | |
const mac = _.get( | |
ifaceData, | |
'mac', | |
'000000000000' | |
).replace(/:/gm, ''); | |
if (mac === '000000000000') { | |
return null; | |
} | |
return BigInt(`0x${mac}`); | |
}); | |
} | |
) | |
); | |
return _.reduce( | |
interfaces, | |
(result, value) => { | |
result = result + value; | |
return result; | |
}, | |
BigInt('0x0') | |
); | |
}); | |
/** | |
* (-.-) zzZZ | |
* | |
* @return {Promise<undefined>} | |
*/ | |
const sleep = () => { | |
return new Promise((resolve) => setTimeout(resolve, 1000)); | |
}; | |
const nodeId = createNodeId(); | |
/** | |
* Generates an id | |
* | |
* @return {Promise<*>} | |
*/ | |
module.exports = async () => { | |
sequence = (currentTimestamp === lastTimestamp) | |
? (sequence + 1) & maxSequence | |
: 0; | |
// Sequence Exhausted, wait till next millisecond. | |
if (sequence === 0) { | |
await sleep(); | |
currentTimestamp = BigInt(new Date().getTime()) - CUSTOM_EPOCH; | |
} | |
lastTimestamp = currentTimestamp; | |
const idParts = currentTimestamp + nodeId + BigInt(`0x${sequence}`); | |
return hashids.encodeHex(idParts); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment