senaev-utils 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +11 -0
  2. package/package.json +66 -0
  3. package/src/reactHooks/setDeepEqualState.ts +19 -0
  4. package/src/reactHooks/useLocationParameter.ts +46 -0
  5. package/src/reactHooks/useObjectDeepChangesCounter.ts +22 -0
  6. package/src/reactHooks/useObservableMap/useObservableMap.ts +21 -0
  7. package/src/reactHooks/useRecentChangeTimer.ts +42 -0
  8. package/src/reactHooks/useReload.ts +17 -0
  9. package/src/reactHooks/useVisualizedProcessesTree.ts +202 -0
  10. package/src/types/Boolean.ts +9 -0
  11. package/src/types/DeepPartial.ts +1 -0
  12. package/src/types/GlobalContext.ts +8 -0
  13. package/src/types/HexColorString.ts +9 -0
  14. package/src/types/ISOLang.ts +5 -0
  15. package/src/types/IsEqualUnion.ts +1 -0
  16. package/src/types/IterableWithIndexAccess.ts +4 -0
  17. package/src/types/Kilobits.ts +4 -0
  18. package/src/types/Network/Bits.ts +4 -0
  19. package/src/types/Network/Bps.ts +4 -0
  20. package/src/types/Network/Kbps.ts +4 -0
  21. package/src/types/Network/Mbps.ts +4 -0
  22. package/src/types/Number/AngleInDegrees.ts +3 -0
  23. package/src/types/Number/FiniteNumber.ts +11 -0
  24. package/src/types/Number/Integer.ts +14 -0
  25. package/src/types/Number/IntegerInString.ts +13 -0
  26. package/src/types/Number/Number.ts +15 -0
  27. package/src/types/Number/Portion.ts +4 -0
  28. package/src/types/Number/PositiveInteger.ts +30 -0
  29. package/src/types/Number/PositiveNumber.ts +4 -0
  30. package/src/types/Number/StringUnsignedInteger.ts +4 -0
  31. package/src/types/Number/UnsignedFiniteNumber.ts +13 -0
  32. package/src/types/Number/UnsignedInteger.ts +28 -0
  33. package/src/types/Object/Object.ts +20 -0
  34. package/src/types/Percent.ts +4 -0
  35. package/src/types/PixelPosition.ts +9 -0
  36. package/src/types/PixelSize.ts +9 -0
  37. package/src/types/Pixels.ts +4 -0
  38. package/src/types/RangeTuple.ts +1 -0
  39. package/src/types/Size.ts +8 -0
  40. package/src/types/Time/DaysCount.ts +6 -0
  41. package/src/types/Time/Hours.ts +4 -0
  42. package/src/types/Time/ISODateString/ISODateString.ts +16 -0
  43. package/src/types/Time/Milliseconds.ts +4 -0
  44. package/src/types/Time/Minutes.ts +4 -0
  45. package/src/types/Time/Seconds.ts +5 -0
  46. package/src/types/Time/Time.ts +13 -0
  47. package/src/types/Time/Timestamp.ts +6 -0
  48. package/src/types/Time/UnixTimeMs.ts +6 -0
  49. package/src/types/Time/UnixTimeSec.ts +11 -0
  50. package/src/types/Time/const.ts +24 -0
  51. package/src/types/any/AnyAsyncFunction.ts +2 -0
  52. package/src/types/any/AnyFunction.ts +2 -0
  53. package/src/types/assertions/ANY_VALUE.ts +2 -0
  54. package/src/types/assertions/isNever/isNever.ts +34 -0
  55. package/src/types/assertions/isTrue/isTrue.ts +13 -0
  56. package/src/utils/AbortableProcess.ts +160 -0
  57. package/src/utils/Array/createArray/createArray.ts +8 -0
  58. package/src/utils/Array/createIntegerSequenceArray/createIntegerSequenceArray.ts +3 -0
  59. package/src/utils/Array/getUniqueValues/getUniqueValues.ts +3 -0
  60. package/src/utils/Array/separateToArrays/separateToArrays.ts +24 -0
  61. package/src/utils/Array/shuffleArray/shuffleArray.ts +18 -0
  62. package/src/utils/CircularBuffer/CircularBuffer.ts +117 -0
  63. package/src/utils/DOM/blurDocument.ts +3 -0
  64. package/src/utils/DOM/unfocusDocument.ts +3 -0
  65. package/src/utils/Date/dateToUnixTimeSec/dateToUnixTimeSec.ts +6 -0
  66. package/src/utils/Date/isoDateStringToUnixTimeMs/isoDateStringToUnixTimeMs.ts +6 -0
  67. package/src/utils/Date/isoDateStringToUnixTimeSec/isoDateStringToUnixTimeSec.ts +7 -0
  68. package/src/utils/Date/unixTimeSecToIsoDateString/unixTimeSecToIsoDateString.ts +6 -0
  69. package/src/utils/Deque/Deque.ts +530 -0
  70. package/src/utils/DeviceDetection/isTouchScreenDevice/isTouchScreenDevice.ts +16 -0
  71. package/src/utils/Error/rethrowError/rethrowError.ts +8 -0
  72. package/src/utils/Error/wrapError.ts +32 -0
  73. package/src/utils/Function/callFirstThenOther/callFirstThenOther.ts +24 -0
  74. package/src/utils/Function/callFunctions/callFunctions.ts +11 -0
  75. package/src/utils/Function/callTimes/callTimes.ts +5 -0
  76. package/src/utils/Function/isFunction.ts +3 -0
  77. package/src/utils/Function/noop/index.ts +4 -0
  78. package/src/utils/Function/once/once.ts +32 -0
  79. package/src/utils/Function/subscribeUpdatesWithTimeout/index.ts +44 -0
  80. package/src/utils/Function/throttleFunction/throttleFunction.ts +18 -0
  81. package/src/utils/Function/throttleWithPromiseFunction/throttleWithPromiseFunction.ts +19 -0
  82. package/src/utils/Function/tryCatch/tryCatch.ts +13 -0
  83. package/src/utils/Latch/Latch.ts +63 -0
  84. package/src/utils/Map/ObservableMap/ObservableMap.ts +55 -0
  85. package/src/utils/Map/findMapsDifferences/findMapsDifferences.ts +35 -0
  86. package/src/utils/Map/mapGetOrSet/mapGetOrSet.ts +7 -0
  87. package/src/utils/Map/mapMapToArray/mapMapToArray.ts +6 -0
  88. package/src/utils/Map/mapMapValues/mapMapValues.ts +9 -0
  89. package/src/utils/Math/createSimpleMovingAverageSeries/createSimpleMovingAverageSeries.ts +22 -0
  90. package/src/utils/Math/mean/mean.ts +14 -0
  91. package/src/utils/Math/simpleMovingAverageUsingAccFabric/simpleMovingAverageUsingAccFabric.ts +29 -0
  92. package/src/utils/Math/sum/sum.ts +45 -0
  93. package/src/utils/MinHeap/MinHeap.ts +88 -0
  94. package/src/utils/MinHeapUniqueNumber/MinHeapUniqueNumber.ts +105 -0
  95. package/src/utils/MinMaxHeap/MinMaxHeap.ts +91 -0
  96. package/src/utils/Number/collectIntegerSequences/collectIntegerSequences.ts +36 -0
  97. package/src/utils/Number/numberToFixedPrecision/numberToFixedPrecision.ts +13 -0
  98. package/src/utils/Object/cloneObject/cloneObject.ts +3 -0
  99. package/src/utils/Object/deepEqual/deepEqual.ts +45 -0
  100. package/src/utils/Object/deleteUndefinedProperties/index.ts +13 -0
  101. package/src/utils/Object/entriesToObject/entriesToObject.ts +12 -0
  102. package/src/utils/Object/filterObject/filterObject.ts +18 -0
  103. package/src/utils/Object/forOwn/forOwn.ts +12 -0
  104. package/src/utils/Object/getObjectEntries/getObjectEntries.ts +3 -0
  105. package/src/utils/Object/getObjectKeys/getObjectKeys.ts +3 -0
  106. package/src/utils/Object/getObjectValues/index.ts +3 -0
  107. package/src/utils/Object/hasOwnProperty/hasOwnProperty.ts +3 -0
  108. package/src/utils/Object/invertObject/InvertedObject.ts +3 -0
  109. package/src/utils/Object/invertObject/invertObject.ts +15 -0
  110. package/src/utils/Object/isEmptyObject/index.ts +5 -0
  111. package/src/utils/Object/isObject/index.ts +8 -0
  112. package/src/utils/Object/mapObjectKeys/mapObjectKeys.ts +25 -0
  113. package/src/utils/Object/mapObjectValues/mapObjectValues.ts +16 -0
  114. package/src/utils/Object/mirrorObject/ObjectKeysMirror.ts +1 -0
  115. package/src/utils/Object/mirrorObject/mirrorObject.ts +7 -0
  116. package/src/utils/Pagination/DEFAULT_PAGE.ts +1 -0
  117. package/src/utils/Pagination/calculatePaginationParameters.ts +29 -0
  118. package/src/utils/Promise/promiseAll/promiseAll.ts +6 -0
  119. package/src/utils/Promise/restrictParallelCalls/restrictParallelCalls.ts +18 -0
  120. package/src/utils/Ranges/checkRangesAdjacent/checkRangesAdjacent.ts +23 -0
  121. package/src/utils/Ranges/checkRangesIntersection/checkRangesIntersection.ts +8 -0
  122. package/src/utils/Ranges/excludeRanges/excludeRanges.ts +42 -0
  123. package/src/utils/Ranges/getDistanceToRange/getDistanceToRange.ts +14 -0
  124. package/src/utils/Ranges/isRangeWithinRanges.ts +14 -0
  125. package/src/utils/Ranges/mapDateRangeToISODateStringRange/mapDateRangeToISODateStringRange.ts +7 -0
  126. package/src/utils/Ranges/mapISODateStringRangeToUnixTimeMsRange/mapISODateStringRangeToUnixTimeMsRange.ts +8 -0
  127. package/src/utils/Ranges/mapRange/mapRange.ts +13 -0
  128. package/src/utils/Ranges/mapUnixTimeMsRangeToISODateStringRange/mapUnixTimeMsRangeToISODateStringRange.ts +8 -0
  129. package/src/utils/Ranges/mergeRanges/mergeRanges.ts +34 -0
  130. package/src/utils/Signal/Signal.ts +47 -0
  131. package/src/utils/Signal/SignalCallback.ts +1 -0
  132. package/src/utils/Signal/combineSignalsIntoNewOne/combineSignalsIntoNewOne.ts +75 -0
  133. package/src/utils/Signal/subscribeSignalAndCallWithCurrentValue/subscribeSignalAndCallWithCurrentValue.ts +7 -0
  134. package/src/utils/Signal/useSignal.ts +10 -0
  135. package/src/utils/String/HexString/HEX_SYMBOLS.ts +1 -0
  136. package/src/utils/String/HexString/HexString.ts +2 -0
  137. package/src/utils/String/HexString/isHexString.ts +16 -0
  138. package/src/utils/String/NonEmptyString/NonEmptyString.ts +22 -0
  139. package/src/utils/String/endsWith/index.ts +6 -0
  140. package/src/utils/String/isString.ts +3 -0
  141. package/src/utils/binarySearch/binarySearch.ts +20 -0
  142. package/src/utils/binarySearchClosest/binarySearchClosest.ts +43 -0
  143. package/src/utils/createIncrementalIntegerGenerator.ts +7 -0
  144. package/src/utils/createRemoteDataProcessingWindow/createRemoteDataProcessingWindow.ts +157 -0
  145. package/src/utils/createSimultaneousOperationsHandler/createSimultaneousOperationsHandler.ts +65 -0
  146. package/src/utils/encryptDecryptString/encryptDecryptString.ts +34 -0
  147. package/src/utils/getPrimeNumbersWithEratosthenesSieve/getPrimeNumbersWithEratosthenesSieve.ts +21 -0
  148. package/src/utils/isPromise/isPromise.ts +30 -0
  149. package/src/utils/makeAsyncFunctionCallsSimultaneous/makeAsyncFunctionCallsSimultaneous.ts +64 -0
  150. package/src/utils/parallelsLimitPromise/index.ts +28 -0
  151. package/src/utils/parallelsLimitQueue/parallelsLimitQueue.ts +69 -0
  152. package/src/utils/prettyStringify/index.ts +3 -0
  153. package/src/utils/random/fnv1a/fnv1a.ts +87 -0
  154. package/src/utils/random/generateHashedFloats/generateHashedFloats.ts +28 -0
  155. package/src/utils/random/getRandomIntegerInARange/getRandomIntegerInARange.ts +3 -0
  156. package/src/utils/random/getSampleIndexByStringHash/getSampleIndexByStringHash.ts +10 -0
  157. package/src/utils/random/randomBoolean/randomBoolean.ts +3 -0
  158. package/src/utils/random/randomHexString/randomHexString.ts +12 -0
  159. package/src/utils/requestAnimationFrame/requestAnimationFramePromise/requestAnimationFramePromise.ts +7 -0
  160. package/src/utils/requestAnimationFrame/requestAnimationFrameThrottle/requestAnimationFrameThrottle.ts +6 -0
  161. package/src/utils/retryFunctionWrapper/retryFunctionWrapper.ts +40 -0
  162. package/src/utils/runParallelTimescalesProcessing/runParallelTimescalesProcessing.ts +113 -0
  163. package/src/utils/stringifyError.ts +3 -0
  164. package/src/utils/timers/promiseTimeout/promiseTimeout.ts +26 -0
  165. package/src/utils/timers/subscribeSyntheticInterval/subscribeSyntheticInterval.ts +47 -0
  166. package/src/utils/waitForFunction/waitForFunction.ts +50 -0
@@ -0,0 +1,44 @@
1
+ import { Milliseconds } from '../../../types/Time/Milliseconds';
2
+ import { noop } from '../noop';
3
+
4
+ export function subscribeUpdatesWithTimeout<T> ({
5
+ callback,
6
+ subscribe,
7
+ timeout,
8
+ onResubscribe,
9
+ }: {
10
+ callback: (value: T) => void;
11
+ subscribe: (cb: typeof callback) => VoidFunction;
12
+ timeout: Milliseconds;
13
+ onResubscribe: VoidFunction;
14
+ }): void {
15
+ let refreshTimeoutId: ReturnType<typeof setTimeout>;
16
+ const clearResubscribeTimeout = () => {
17
+ clearTimeout(refreshTimeoutId);
18
+ };
19
+ const setResubscribeTimeout = () => {
20
+ refreshTimeoutId = setTimeout(resubscribe, timeout);
21
+ };
22
+
23
+ let unsubscribe = noop;
24
+ const resubscribe = (isFirst = false) => {
25
+ if (!isFirst) {
26
+ onResubscribe();
27
+ }
28
+
29
+ clearResubscribeTimeout();
30
+ unsubscribe();
31
+
32
+ unsubscribe = subscribe((value) => {
33
+ clearResubscribeTimeout();
34
+
35
+ callback(value);
36
+
37
+ setResubscribeTimeout();
38
+ });
39
+
40
+ setResubscribeTimeout();
41
+ };
42
+
43
+ resubscribe(true);
44
+ }
@@ -0,0 +1,18 @@
1
+ import { Subject, throttleTime } from 'rxjs';
2
+
3
+ import { Milliseconds } from '../../../types/Time/Milliseconds';
4
+
5
+ export function throttleFunction(func: VoidFunction, delay: Milliseconds): VoidFunction {
6
+ const subject = new Subject();
7
+
8
+ subject
9
+ .pipe(throttleTime(delay, undefined, {
10
+ leading: true,
11
+ trailing: true,
12
+ }))
13
+ .subscribe(func);
14
+
15
+ return () => {
16
+ subject.next(undefined);
17
+ };
18
+ }
@@ -0,0 +1,19 @@
1
+ export function throttleWithPromiseFunction(callback: VoidFunction, promiseFunction: () => Promise<void>) {
2
+ let isRunning = false;
3
+
4
+ const throttled = () => {
5
+ if (isRunning) {
6
+ return;
7
+ }
8
+
9
+ isRunning = true;
10
+
11
+ promiseFunction().finally(() => {
12
+ callback();
13
+
14
+ isRunning = false;
15
+ });
16
+ };
17
+
18
+ return throttled;
19
+ }
@@ -0,0 +1,13 @@
1
+ import { AnyFunction } from '../../../types/any/AnyFunction';
2
+
3
+ export function tryCatch<T extends AnyFunction>(fn: T, onError?: (e: Error) => void): ReturnType<T> | undefined {
4
+ try {
5
+ return fn();
6
+ } catch (e) {
7
+ if (typeof onError === 'function') {
8
+ onError(e as Error);
9
+ }
10
+ }
11
+
12
+ return undefined;
13
+ }
@@ -0,0 +1,63 @@
1
+ import { callFunctions } from '../Function/callFunctions/callFunctions';
2
+ import { isFunction } from '../Function/isFunction';
3
+ import { noop } from '../Function/noop';
4
+ import { once } from '../Function/once/once';
5
+
6
+ export type LatchCallback<T> = (parameter: T) => void;
7
+
8
+ /**
9
+ * Класс, инстанс которого хранит неизменяемое значение и может находиться в двух состояниях
10
+ * - значение не задано
11
+ * - значение задано
12
+ *
13
+ * Если значение не задано, подписаться на его установку можно с помощью метода subscribe,
14
+ * а установить значение вызвав метод dispatch
15
+ *
16
+ * В случае, если значение задано, при вызове метода subscribe callback отрабатывает сразу,
17
+ * а дальнейшие вызовы dispatch игнорируются
18
+ */
19
+ export class Latch<T = undefined> {
20
+ public dispatch = once((value: T): void => {
21
+ this.value = value;
22
+ this._isDispatched = true;
23
+
24
+ callFunctions(this.callbacks, value);
25
+ this.callbacks.clear();
26
+ });
27
+
28
+ private readonly callbacks: Set<LatchCallback<T>> = new Set();
29
+ private _isDispatched = false;
30
+ private value?: T;
31
+
32
+ public constructor(callback?: LatchCallback<T>) {
33
+ if (isFunction(callback)) {
34
+ this.callbacks.add(callback);
35
+ }
36
+ }
37
+
38
+ public subscribe(callback: LatchCallback<T>): VoidFunction {
39
+ if (this._isDispatched) {
40
+ callback(this.value!);
41
+
42
+ return noop;
43
+ }
44
+
45
+ this.callbacks.add(callback);
46
+
47
+ return () => {
48
+ this.callbacks.delete(callback);
49
+ };
50
+ }
51
+
52
+ public unsubscribe(callback: LatchCallback<T>): void {
53
+ this.callbacks.delete(callback);
54
+ }
55
+
56
+ public isDispatched(): boolean {
57
+ return this._isDispatched;
58
+ }
59
+
60
+ public getValue(): T | undefined {
61
+ return this.value;
62
+ }
63
+ }
@@ -0,0 +1,55 @@
1
+ import { callFunctions } from '../../Function/callFunctions/callFunctions';
2
+
3
+ type ObservableMapEvent<K, V> =
4
+ | {
5
+ type: 'set';
6
+ key: K;
7
+ value: V;
8
+ }
9
+ | {
10
+ type: 'delete';
11
+ key: K;
12
+ };
13
+
14
+ type ObservableMapCallback<K, V> = (event: ObservableMapEvent<K, V>) => void;
15
+
16
+ export class ObservableMap<K, V> extends Map<K, V> {
17
+ private readonly _callbacks: Set<ObservableMapCallback<K, V>> = new Set();
18
+
19
+ public subscribe(callback: ObservableMapCallback<K, V>): VoidFunction {
20
+ this._callbacks.add(callback);
21
+
22
+ return () => {
23
+ this._callbacks.delete(callback);
24
+ };
25
+ }
26
+
27
+ public set (key: K, value: V): this {
28
+ const previousValue = this.get(key);
29
+
30
+ super.set(key, value);
31
+
32
+ if (value !== previousValue) {
33
+ callFunctions(this._callbacks ?? [], {
34
+ type: 'set',
35
+ key,
36
+ value,
37
+ });
38
+ }
39
+
40
+ return this;
41
+ }
42
+
43
+ public delete (key: K): boolean {
44
+ const result = super.delete(key);
45
+
46
+ if (result) {
47
+ callFunctions(this._callbacks ?? [], {
48
+ type: 'delete',
49
+ key,
50
+ });
51
+ }
52
+
53
+ return result;
54
+ }
55
+ }
@@ -0,0 +1,35 @@
1
+ export function findMapsDifferences<K, V, V2>(originalMap: Map<K, V>, targetMap: Map<K, V2>): {
2
+ added: K[];
3
+ updated: K[];
4
+ deleted: K[];
5
+ } {
6
+ const result = {
7
+ added: [] as K[],
8
+ updated: [] as K[],
9
+ deleted: [] as K[],
10
+ };
11
+
12
+ // Value added to the original map
13
+ targetMap.forEach((_, id) => {
14
+ if (!originalMap.has(id)) {
15
+ result.added.push(id);
16
+ }
17
+ });
18
+
19
+ originalMap.forEach((_, id) => {
20
+ if (targetMap.has(id)) {
21
+ const originalValue = originalMap.get(id);
22
+ const targetValue = targetMap.get(id);
23
+
24
+ // Value has been changed
25
+ if (originalValue !== targetValue) {
26
+ result.updated.push(id);
27
+ }
28
+ } else {
29
+ // Value is not represented in settings anymore
30
+ result.deleted.push(id);
31
+ }
32
+ });
33
+
34
+ return result;
35
+ }
@@ -0,0 +1,7 @@
1
+ export const mapGetOrSet = <K, V>(map: Map<K, V>, key: K, value: V): V => {
2
+ if (!map.has(key)) {
3
+ map.set(key, value);
4
+ }
5
+
6
+ return map.get(key)!;
7
+ };
@@ -0,0 +1,6 @@
1
+ export function mapMapToArray<K, V, R>(map: Map<K, V>, callback: (value: V, key: K) => R): R[] {
2
+ return Array.from(map.entries(), ([
3
+ key,
4
+ value,
5
+ ]) => callback(value, key));
6
+ }
@@ -0,0 +1,9 @@
1
+ export function mapMapValues<K, V, R>(map: Map<K, V>, callback: (value: V, key: K) => R): Map<K, R> {
2
+ const result = new Map<K, R>();
3
+
4
+ map.forEach((value, key) => {
5
+ result.set(key, callback(value, key));
6
+ });
7
+
8
+ return result;
9
+ }
@@ -0,0 +1,22 @@
1
+ import { PositiveInteger } from '../../../types/Number/PositiveInteger';
2
+ import { mean } from '../mean/mean';
3
+
4
+ export function createSimpleMovingAverageSeries({
5
+ series,
6
+ windowSize,
7
+ }: {
8
+ series: number[];
9
+ windowSize: PositiveInteger;
10
+ }): (number | undefined)[] {
11
+ const movingAverageData: (number | undefined)[] = [];
12
+
13
+ for (let i = 0; i < series.length; i++) {
14
+ if (i < windowSize - 1) {
15
+ movingAverageData.push(undefined);
16
+ } else {
17
+ movingAverageData.push(mean(series.slice(i - windowSize + 1, i + 1)));
18
+ }
19
+ }
20
+
21
+ return movingAverageData;
22
+ }
@@ -0,0 +1,14 @@
1
+ import { IterableWithIndexAccess } from '../../../types/IterableWithIndexAccess';
2
+ import { sum } from '../sum/sum';
3
+
4
+ /**
5
+ * Stolen from here
6
+ * https://github.com/simple-statistics/simple-statistics/blob/ac07cbec74534a4b4c71a541292e9ae8c26f0930/src/mean.js#L17C1-L23C2
7
+ */
8
+ export function mean(x: IterableWithIndexAccess<number>): number {
9
+ if (x.length === 0) {
10
+ throw new Error('mean requires at least one data point');
11
+ }
12
+
13
+ return sum(x) / x.length;
14
+ }
@@ -0,0 +1,29 @@
1
+ import { PositiveInteger } from '../../../types/Number/PositiveInteger';
2
+ import { CircularBuffer } from '../../CircularBuffer/CircularBuffer';
3
+
4
+ /**
5
+ * Calculates using accumulator to avoid re-calculating the mean
6
+ * Can have small floating point errors
7
+ */
8
+ export function simpleMovingAverageUsingAccFabric(windowSize: PositiveInteger): (value: number) => number | undefined {
9
+ const queue = new CircularBuffer<number>(windowSize);
10
+ let accumulator = 0;
11
+
12
+ return (newValue: number) => {
13
+ let diff = newValue;
14
+
15
+ if (queue.length === windowSize) {
16
+ diff -= queue.shift()!;
17
+ }
18
+
19
+ queue.push(newValue);
20
+
21
+ accumulator += diff / windowSize;
22
+
23
+ if (queue.length < windowSize) {
24
+ return undefined;
25
+ }
26
+
27
+ return accumulator;
28
+ };
29
+ }
@@ -0,0 +1,45 @@
1
+ import { IterableWithIndexAccess } from '../../../types/IterableWithIndexAccess';
2
+
3
+ /**
4
+ * Stolen from here
5
+ * https://github.com/simple-statistics/simple-statistics/blob/ac07cbec74534a4b4c71a541292e9ae8c26f0930/src/sum.js#L19C1-L56C2
6
+ */
7
+ export function sum(x: IterableWithIndexAccess<number>): number {
8
+ // If the array is empty, we needn't bother computing its sum
9
+ if (x.length === 0) {
10
+ return 0;
11
+ }
12
+
13
+ // Initializing the sum as the first number in the array
14
+ let sumResult = x.at(0);
15
+
16
+ // Keeping track of the floating-point error correction
17
+ let correction: number = 0;
18
+
19
+ let transition: number;
20
+
21
+ if (typeof sumResult !== 'number') {
22
+ return Number.NaN;
23
+ }
24
+
25
+ for (let i = 1; i < x.length; i++) {
26
+ if (typeof x.at(i) !== 'number') {
27
+ return Number.NaN;
28
+ }
29
+
30
+ transition = sumResult + x.at(i)!;
31
+
32
+ // Here we need to update the correction in a different fashion
33
+ // if the new absolute value is greater than the absolute sum
34
+ if (Math.abs(sumResult) >= Math.abs(x.at(i)!)) {
35
+ correction += sumResult - transition + x.at(i)!;
36
+ } else {
37
+ correction += x.at(i)! - transition + sumResult;
38
+ }
39
+
40
+ sumResult = transition;
41
+ }
42
+
43
+ // Returning the corrected sum
44
+ return sumResult + correction;
45
+ }
@@ -0,0 +1,88 @@
1
+ export type MinHeapTuple<T> = [number, T];
2
+
3
+ export class MinHeap<T> {
4
+ private _heap: MinHeapTuple<T>[];
5
+
6
+ public constructor() {
7
+ this._heap = [];
8
+ }
9
+ public push(value: MinHeapTuple<T>): void {
10
+ this._heap.push(value);
11
+ this._bubbleUp();
12
+ }
13
+ public getFirst(): MinHeapTuple<T> | undefined {
14
+ return this._heap[0];
15
+ }
16
+
17
+ public getSize(): number {
18
+ return this._heap.length;
19
+ }
20
+
21
+ public pop(): MinHeapTuple<T> | undefined {
22
+ if (this._heap.length <= 1) {
23
+ return this._heap.pop();
24
+ }
25
+
26
+ const top = this._heap[0];
27
+
28
+ this._heap[0] = this._heap.pop()!;
29
+ this._bubbleDown();
30
+
31
+ return top;
32
+ }
33
+
34
+ private _bubbleUp(): void {
35
+ let idx = this._heap.length - 1;
36
+
37
+ while (idx > 0) {
38
+ const parentIdx = Math.floor((idx - 1) / 2);
39
+ const current = this._heap[idx];
40
+ const parent = this._heap[parentIdx];
41
+
42
+ if (parent[0] <= current[0]) {
43
+ break;
44
+ }
45
+
46
+ this._heap[idx] = parent;
47
+ this._heap[parentIdx] = current;
48
+
49
+ idx = parentIdx;
50
+ }
51
+ }
52
+
53
+ private _bubbleDown(): void {
54
+ let idx = 0;
55
+
56
+ while (true) {
57
+ const leftIdx = 2 * idx + 1;
58
+ const rightIdx = 2 * idx + 2;
59
+
60
+ if (leftIdx >= this._heap.length) {
61
+ break;
62
+ }
63
+
64
+ let smallestIdx = leftIdx;
65
+ const hasRight = rightIdx < this._heap.length;
66
+
67
+ if (hasRight) {
68
+ const rightIsPrior = this._heap[rightIdx][0] < this._heap[leftIdx][0];
69
+
70
+ if (rightIsPrior) {
71
+ smallestIdx = rightIdx;
72
+ }
73
+ }
74
+
75
+ const value = this._heap[idx];
76
+ const smallestValue = this._heap[smallestIdx];
77
+
78
+ if (value[0] <= smallestValue[0]) {
79
+ break;
80
+ }
81
+
82
+ this._heap[idx] = smallestValue;
83
+ this._heap[smallestIdx] = value;
84
+
85
+ idx = smallestIdx;
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,105 @@
1
+ export class MinHeapUniqueNumber {
2
+ private readonly _heap: number[];
3
+ private readonly _set: Set<number> = new Set();
4
+
5
+ public constructor() {
6
+ this._heap = [];
7
+ }
8
+
9
+ public push(value: number): void {
10
+ if (this._set.has(value)) {
11
+ return;
12
+ }
13
+
14
+ this._set.add(value);
15
+
16
+ this._heap.push(value);
17
+ this._bubbleUp();
18
+ }
19
+
20
+ public getFirst(): number | undefined {
21
+ return this._heap[0];
22
+ }
23
+
24
+ public getSize(): number {
25
+ return this._heap.length;
26
+ }
27
+
28
+ public pop(): number | undefined {
29
+ if (this._heap.length === 0) {
30
+ return undefined;
31
+ }
32
+
33
+ if (this._heap.length <= 1) {
34
+ const value = this._heap.pop()!;
35
+
36
+ this._set.delete(value);
37
+
38
+ return value;
39
+ }
40
+
41
+ const top = this._heap[0];
42
+
43
+ this._heap[0] = this._heap.pop()!;
44
+ this._bubbleDown();
45
+
46
+ this._set.delete(top);
47
+
48
+ return top;
49
+ }
50
+
51
+ private _bubbleUp(): void {
52
+ let idx = this._heap.length - 1;
53
+
54
+ while (idx > 0) {
55
+ const parentIdx = Math.floor((idx - 1) / 2);
56
+ const current = this._heap[idx];
57
+ const parent = this._heap[parentIdx];
58
+
59
+ if (parent < current) {
60
+ break;
61
+ }
62
+
63
+ this._heap[idx] = parent;
64
+ this._heap[parentIdx] = current;
65
+
66
+ idx = parentIdx;
67
+ }
68
+ }
69
+
70
+ private _bubbleDown(): void {
71
+ let idx = 0;
72
+
73
+ while (true) {
74
+ const leftIdx = 2 * idx + 1;
75
+ const rightIdx = 2 * idx + 2;
76
+
77
+ if (leftIdx >= this._heap.length) {
78
+ break;
79
+ }
80
+
81
+ let smallestIdx = leftIdx;
82
+ const hasRight = rightIdx < this._heap.length;
83
+
84
+ if (hasRight) {
85
+ const rightIsPrior = this._heap[rightIdx] < this._heap[leftIdx];
86
+
87
+ if (rightIsPrior) {
88
+ smallestIdx = rightIdx;
89
+ }
90
+ }
91
+
92
+ const value = this._heap[idx];
93
+ const smallestValue = this._heap[smallestIdx];
94
+
95
+ if (value < smallestValue) {
96
+ break;
97
+ }
98
+
99
+ this._heap[idx] = smallestValue;
100
+ this._heap[smallestIdx] = value;
101
+
102
+ idx = smallestIdx;
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,91 @@
1
+ export type MinMaxHeapTuple<T> = [number, T];
2
+ export type MinMaxHeapCompareFunction = (a: number, b: number) => number;
3
+
4
+ export class MinMaxHeap<T> {
5
+ private _heap: MinMaxHeapTuple<T>[];
6
+ private _compare: MinMaxHeapCompareFunction;
7
+
8
+ public constructor(compare: MinMaxHeapCompareFunction) {
9
+ this._heap = [];
10
+ this._compare = compare;
11
+ }
12
+ public push(value: MinMaxHeapTuple<T>): void {
13
+ this._heap.push(value);
14
+ this._bubbleUp();
15
+ }
16
+ public getFirst(): MinMaxHeapTuple<T> | undefined {
17
+ return this._heap[0];
18
+ }
19
+
20
+ public getSize(): number {
21
+ return this._heap.length;
22
+ }
23
+
24
+ public pop(): MinMaxHeapTuple<T> | undefined {
25
+ if (this._heap.length <= 1) {
26
+ return this._heap.pop();
27
+ }
28
+
29
+ const top = this._heap[0];
30
+
31
+ this._heap[0] = this._heap.pop()!;
32
+ this._bubbleDown();
33
+
34
+ return top;
35
+ }
36
+
37
+ private _bubbleUp(): void {
38
+ let idx = this._heap.length - 1;
39
+
40
+ while (idx > 0) {
41
+ const parentIdx = Math.floor((idx - 1) / 2);
42
+ const current = this._heap[idx];
43
+ const parent = this._heap[parentIdx];
44
+
45
+ if (this._compare(parent[0], current[0]) < 0) {
46
+ break;
47
+ }
48
+
49
+ this._heap[idx] = parent;
50
+ this._heap[parentIdx] = current;
51
+
52
+ idx = parentIdx;
53
+ }
54
+ }
55
+
56
+ private _bubbleDown(): void {
57
+ let idx = 0;
58
+
59
+ while (true) {
60
+ const leftIdx = 2 * idx + 1;
61
+ const rightIdx = 2 * idx + 2;
62
+
63
+ if (leftIdx >= this._heap.length) {
64
+ break;
65
+ }
66
+
67
+ let smallestIdx = leftIdx;
68
+ const hasRight = rightIdx < this._heap.length;
69
+
70
+ if (hasRight) {
71
+ const rightIsPrior = this._compare(this._heap[rightIdx][0], this._heap[leftIdx][0]) < 0;
72
+
73
+ if (rightIsPrior) {
74
+ smallestIdx = rightIdx;
75
+ }
76
+ }
77
+
78
+ const value = this._heap[idx];
79
+ const smallestValue = this._heap[smallestIdx];
80
+
81
+ if (this._compare(value[0], smallestValue[0]) < 0) {
82
+ break;
83
+ }
84
+
85
+ this._heap[idx] = smallestValue;
86
+ this._heap[smallestIdx] = value;
87
+
88
+ idx = smallestIdx;
89
+ }
90
+ }
91
+ }