( uniqueId?: Id, getNow: GetNow = Date.now, )
| 28 | }; |
| 29 | |
| 30 | export const getHlcFunctions: typeof getHlcFunctionsDecl = ( |
| 31 | uniqueId?: Id, |
| 32 | getNow: GetNow = Date.now, |
| 33 | ): [ |
| 34 | getNextHlc: () => Hlc, |
| 35 | seenHlc: (remoteHlc: Hlc) => void, |
| 36 | encodeHlc: (logicalTime: number, counter: number, clientId?: Id) => Hlc, |
| 37 | decodeHlc: (hlc: Hlc) => [logicalTime: number, counter: number, clientId: Id], |
| 38 | getLastLogicalTime: () => number, |
| 39 | getLastCounter: () => number, |
| 40 | getClientId: () => Id, |
| 41 | ] => { |
| 42 | let lastLogicalTime = 0; |
| 43 | let lastCounter = -1; |
| 44 | |
| 45 | const thisClientId = ifNotUndefined(uniqueId, getClientIdFromUniqueId, () => |
| 46 | getUniqueId(5), |
| 47 | ) as string; |
| 48 | |
| 49 | const getNextHlc = (): Hlc => { |
| 50 | seenHlc(); |
| 51 | return encodeHlc(lastLogicalTime, ++lastCounter); |
| 52 | }; |
| 53 | |
| 54 | const seenHlc = (hlc?: Hlc): void => { |
| 55 | const previousLogicalTime = lastLogicalTime; |
| 56 | const [remoteLogicalTime, remoteCounter] = |
| 57 | isUndefined(hlc) || hlc == EMPTY_STRING ? [0, 0] : decodeHlc(hlc); |
| 58 | lastLogicalTime = mathMax(previousLogicalTime, remoteLogicalTime, getNow()); |
| 59 | lastCounter = |
| 60 | lastLogicalTime == previousLogicalTime |
| 61 | ? lastLogicalTime == remoteLogicalTime |
| 62 | ? mathMax(lastCounter, remoteCounter) |
| 63 | : lastCounter |
| 64 | : lastLogicalTime == remoteLogicalTime |
| 65 | ? remoteCounter |
| 66 | : -1; |
| 67 | }; |
| 68 | |
| 69 | const encodeHlc = (logicalTime42: number, counter24: number, clientId?: Id) => |
| 70 | encode(logicalTime42 / SHIFT36) + |
| 71 | encode(logicalTime42 / SHIFT30) + |
| 72 | encode(logicalTime42 / SHIFT24) + |
| 73 | encode(logicalTime42 / SHIFT18) + |
| 74 | encode(logicalTime42 / SHIFT12) + |
| 75 | encode(logicalTime42 / SHIFT6) + |
| 76 | encode(logicalTime42) + |
| 77 | encode(counter24 / SHIFT18) + |
| 78 | encode(counter24 / SHIFT12) + |
| 79 | encode(counter24 / SHIFT6) + |
| 80 | encode(counter24) + |
| 81 | (isUndefined(clientId) ? thisClientId : getClientIdFromUniqueId(clientId)); |
| 82 | |
| 83 | const decodeHlc = ( |
| 84 | hlc16: Hlc, |
| 85 | ): [logicalTime42: number, counter24: number, clientId: Id] => [ |
| 86 | decode(hlc16, 0) * SHIFT36 + |
| 87 | decode(hlc16, 1) * SHIFT30 + |
no test coverage detected
searching dependent graphs…