Skip to content

Instantly share code, notes, and snippets.

@manchuck
Last active December 23, 2019 21:55
Show Gist options
  • Save manchuck/9aa5d08a41cc2f306fc0bbdf7ee54072 to your computer and use it in GitHub Desktop.
Save manchuck/9aa5d08a41cc2f306fc0bbdf7ee54072 to your computer and use it in GitHub Desktop.
/**
* @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