{"version":3,"sources":["../src/snowflake.ts"],"sourcesContent":["/**\n * A distributed unique ID generator inspired by Twitter's Snowflake.\n *\n * ID data bits:\n * +----------------------+----------------+-----------+\n * |  delta millisecond   |   machine id   | sequence  |\n * +----------------------+----------------+-----------+\n * |        41bits        |     10bits     |   12bits  |\n * +----------------------+----------------+-----------+\n *\n */\n\nfunction getNextMillisecond(timestamp: bigint) {\n  let now = BigInt(Date.now());\n  while (now < timestamp) {\n    now = BigInt(Date.now());\n  }\n  return now;\n}\n\nexport class UidGenerator {\n  public readonly MAX = (1n << 63n) - 1n;\n  private readonly machineBits = BigInt(10);\n  private readonly sequenceBits = BigInt(12);\n  private readonly epochMillisecond = BigInt(1577808000000); // 2020-1-1 00:00:00\n  private readonly sequenceMask = ~(BigInt(-1) << this.sequenceBits);\n  private readonly maxMachineId = ~(BigInt(-1) << this.machineBits);\n  private readonly machineIdShift = this.sequenceBits;\n  private readonly timeStampShift = this.machineBits + this.sequenceBits;\n  private readonly machineId: bigint;\n  private sequence = BigInt(0);\n  private lastTimestamp = BigInt(-1);\n\n  constructor(mackineId: number) {\n    this.machineId = BigInt(mackineId) % this.maxMachineId;\n  }\n\n  public readonly next = (): bigint => {\n    let timestamp = BigInt(Date.now());\n    if (timestamp < this.lastTimestamp) {\n      console.error(`Clock moved backwards. time gap = ${this.lastTimestamp - timestamp}`);\n      timestamp = getNextMillisecond(this.lastTimestamp);\n    }\n    if (timestamp === this.lastTimestamp) {\n      this.sequence = (this.sequence + BigInt(1)) & this.sequenceMask;\n      if (this.sequence === BigInt(0)) {\n        timestamp = getNextMillisecond(timestamp);\n      }\n    } else {\n      this.sequence = BigInt(0);\n    }\n    this.lastTimestamp = timestamp;\n    return (\n      ((timestamp - this.epochMillisecond) << this.timeStampShift) |\n      (this.machineId << this.machineIdShift) |\n      this.sequence\n    );\n  };\n}\n\nconst machineId = Math.floor(Math.random() * 1024);\nexport const uid = new UidGenerator(machineId);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,SAAS,mBAAmB,WAAmB;AAC7C,MAAI,MAAM,OAAO,KAAK,IAAI,CAAC;AAC3B,SAAO,MAAM,WAAW;AACtB,UAAM,OAAO,KAAK,IAAI,CAAC;AAAA,EACzB;AACA,SAAO;AACT;AAEO,IAAM,eAAN,MAAmB;AAAA,EACR,OAAO,MAAM,OAAO;AAAA,EACnB,cAAc,OAAO,EAAE;AAAA,EACvB,eAAe,OAAO,EAAE;AAAA,EACxB,mBAAmB,OAAO,SAAa;AAAA;AAAA,EACvC,eAAe,EAAE,OAAO,EAAE,KAAK,KAAK;AAAA,EACpC,eAAe,EAAE,OAAO,EAAE,KAAK,KAAK;AAAA,EACpC,iBAAiB,KAAK;AAAA,EACtB,iBAAiB,KAAK,cAAc,KAAK;AAAA,EACzC;AAAA,EACT,WAAW,OAAO,CAAC;AAAA,EACnB,gBAAgB,OAAO,EAAE;AAAA,EAEjC,YAAY,WAAmB;AAC7B,SAAK,YAAY,OAAO,SAAS,IAAI,KAAK;AAAA,EAC5C;AAAA,EAEgB,OAAO,MAAc;AACnC,QAAI,YAAY,OAAO,KAAK,IAAI,CAAC;AACjC,QAAI,YAAY,KAAK,eAAe;AAClC,cAAQ,MAAM,qCAAqC,KAAK,gBAAgB,SAAS,EAAE;AACnF,kBAAY,mBAAmB,KAAK,aAAa;AAAA,IACnD;AACA,QAAI,cAAc,KAAK,eAAe;AACpC,WAAK,WAAY,KAAK,WAAW,OAAO,CAAC,IAAK,KAAK;AACnD,UAAI,KAAK,aAAa,OAAO,CAAC,GAAG;AAC/B,oBAAY,mBAAmB,SAAS;AAAA,MAC1C;AAAA,IACF,OAAO;AACL,WAAK,WAAW,OAAO,CAAC;AAAA,IAC1B;AACA,SAAK,gBAAgB;AACrB,WACI,YAAY,KAAK,oBAAqB,KAAK,iBAC5C,KAAK,aAAa,KAAK,iBACxB,KAAK;AAAA,EAET;AACF;AAEA,IAAM,YAAY,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI;AAC1C,IAAM,MAAM,IAAI,aAAa,SAAS;","names":[]}