1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| import { randomBytes } from 'crypto'
let increaser = Math.trunc(Math.random() * 0xffffff) const PROCESS_UNIQUE = randomBytes(5)
class ObjectId { constructor(id) { if (!id) { this.id = ObjectId.generate(Math.trunc(Date.now() / 1000)) } else if (typeof id === 'string' && id.length === 24) { this.id = Buffer.from(id, 'hex') } else if (typeof id === 'number') { this.id = ObjectId.generate(id) } else if ((Buffer.isBuffer(id) || Array.isArray(id)) && id.length === 12) { this.id = Buffer.from(id) } else { throw new TypeError( 'Argument passed in must be a single String of 12 bytes or a string of 24 hex characters' ) } }
static generate(timestamp) { const buffer = Buffer.alloc(12) const counter = increaser++
buffer[3] = timestamp & 0xff buffer[2] = (timestamp >> 8) & 0xff buffer[1] = (timestamp >> 16) & 0xff buffer[0] = (timestamp >> 24) & 0xff
buffer[4] = PROCESS_UNIQUE[0] buffer[5] = PROCESS_UNIQUE[1] buffer[6] = PROCESS_UNIQUE[2] buffer[7] = PROCESS_UNIQUE[3] buffer[8] = PROCESS_UNIQUE[4]
buffer[11] = counter & 0xff buffer[10] = (counter >> 8) & 0xff buffer[9] = (counter >> 16) & 0xff
return buffer }
getTimestamp() { return new Date(this.id.readUInt32BE(0) * 1000) }
toString() { return this.id.toString('hex') }
toJson() { return this.toString() } }
|