All files / src/UUID makeVersionOneUUIDValues.ts

100% Statements 28/28
100% Branches 19/19
100% Functions 2/2
100% Lines 28/28
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 762x                 2x     2x       2x 10x 10x 10x 10x 10x       3x   7x           10x 10x 3x   7x 7x   7x     2x 2x   2x   2x 2x   1x     2x       7x       4x       10x               2x  
import {
  getLastResults,
} from '../getLastResults';
import {
  IUUIDComponentValues,
} from './IUUIDComponentValues';
import {
  IUUIDOptions,
} from './UUIDOptions/IUUIDOptions';
import {
  uintArrayAsBigNumber,
} from '../uintArrayAsBigNumber';
import {
  UUIDVersions,
} from '../Enums/UUIDVersions';
 
export const makeVersionOneUUIDValues = (options: IUUIDOptions): IUUIDComponentValues & { shouldWrite: boolean, } => {
  const nodeIdentifier = options.nodeIdentifierGetter(options.version);
  const timestamp = options.timestampGetter(options.version);
  const lastResults = getLastResults();
  let clockSequence = (() => {
    if (lastResults &&
        uintArrayAsBigNumber(lastResults.nodeIdentifier).neq(uintArrayAsBigNumber(nodeIdentifier)))
    {
      /* Create a random clock sequence if the node identifier has changed. */ 
      return options.clockSequenceGetter(UUIDVersions.Four);
    } else {
      return options.clockSequenceGetter(options.version);
    }
  })();
 
  /* Indicate that the new results should be written to the external file if
   * any have changed or could not be found. */
  let shouldWrite = false;
  if (!lastResults) {
    shouldWrite = true;
  } else {
    const oldTimestamp = lastResults.timestamp;
    const oldClockSequence = lastResults.clockSequence;
    /* Check if the last recorded timestamp is after the current time. */
    if ((oldTimestamp && 'BYTES_PER_ELEMENT' in oldTimestamp) &&
        (oldClockSequence && 'BYTES_PER_ELEMENT' in oldClockSequence))
    {
      const oldTimeInt = uintArrayAsBigNumber(oldTimestamp);
      const newTimeInt = uintArrayAsBigNumber(timestamp);
      /* istanbul ignore else */
      if (oldTimeInt.geq(newTimeInt)) {
        /* Increment the clock sequence given that the timestamp is invalid. */
        clockSequence[1] += 1;
        if (clockSequence[1] === 0) {
          /* Increment the upper byte if the lower byte wrapped around. */
          clockSequence[0] += 1;
        }
 
        shouldWrite = true;
      }
    }
 
    if (
      uintArrayAsBigNumber(clockSequence).neq(uintArrayAsBigNumber(lastResults.clockSequence)) ||
      uintArrayAsBigNumber(nodeIdentifier).neq(uintArrayAsBigNumber(lastResults.nodeIdentifier)))
    {
      shouldWrite = true;
    }
  }
 
  return {
    clockSequence,
    nodeIdentifier,
    shouldWrite,
    timestamp,
  };
};
 
export default makeVersionOneUUIDValues;