@zelgadis87/utils-core 4.5.0 → 4.6.1

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.
@@ -33,6 +33,16 @@ export class TimeInstant extends TimeBase<TimeInstant> {
33
33
  return TimeDuration.fromMs( Math.abs( this.ms - Date.now() ) );
34
34
  }
35
35
 
36
+ public timeLeftFrom( instant: TimeInstant ): TimeDuration {
37
+ const distance = this.ms - instant.ms;
38
+ return TimeDuration.fromMs( Math.max( distance, 0 ) );
39
+ }
40
+
41
+ public timeLeftFromNow(): TimeDuration {
42
+ const distance = this.ms - Date.now();
43
+ return TimeDuration.fromMs( Math.max( distance, 0 ) );
44
+ }
45
+
36
46
  public distanceFromStartOfDay(): TimeDuration {
37
47
  return this.distanceFrom( this.atStartOfDay() );
38
48
  }
@@ -49,16 +59,20 @@ export class TimeInstant extends TimeBase<TimeInstant> {
49
59
  return this.atTime( { hours: 23, minutes: 59, seconds: 59, milliseconds: 999 } );
50
60
  }
51
61
 
52
- public promise(): ICancelablePromise<void> {
53
- const ms = this.ms - Date.now();
54
- const duration = TimeDuration.fromMs( Math.max( ms, 0 ) );
55
- return duration.promise();
62
+ public promise(): Promise<void> {
63
+ return this.timeLeftFromNow().promise();
64
+ }
65
+
66
+ public cancelablePromise(): ICancelablePromise<void> {
67
+ return this.timeLeftFromNow().cancelablePromise();
56
68
  }
57
69
 
58
- public delay( cb: () => unknown ): ICancelable {
59
- const ms = this.ms - Date.now();
60
- const duration = TimeDuration.fromMs( Math.max( ms, 0 ) );
61
- return duration.delay( cb );
70
+ public delay( cb: () => unknown ): void {
71
+ return this.timeLeftFromNow().delay( cb );
72
+ }
73
+
74
+ public cancelableDelay( cb: () => unknown ): ICancelable {
75
+ return this.timeLeftFromNow().cancelableDelay( cb );
62
76
  }
63
77
 
64
78
  public ensureInTheFuture() {
@@ -191,22 +205,25 @@ export class TimeInstant extends TimeBase<TimeInstant> {
191
205
  }
192
206
 
193
207
  /**
194
- * @deprecated[04/07/2023]: Use distanceFromNow instead
195
- */
208
+ * @deprecated: Use {@link distanceFromNow} instead
209
+ */
210
+ // TODO[2023-07-04, Deprecated]: Remove this method in a future version
196
211
  public fromNow(): TimeDuration {
197
212
  return TimeDuration.ms( this.ms - Date.now() );
198
213
  }
199
214
 
200
215
  /**
201
- * @deprecated[04/07/2023]: Use distanceFrom instead
202
- */
216
+ * @deprecated: Use {@link distanceFrom} instead
217
+ */
218
+ // TODO[2023-07-04, Deprecated]: Remove this method in a future version
203
219
  public from( instant: TimeInstant ): TimeDuration {
204
220
  return TimeDuration.ms( this.ms - instant.ms );
205
221
  }
206
222
 
207
223
  /**
208
- * @deprecated[04/07/2023]: Use distanceFromUnixTimestamp instead
209
- */
224
+ * @deprecated: Use {@link distanceFromUnixTimestamp} instead
225
+ */
226
+ // TODO[2023-07-04, Deprecated]: Remove this method in a future version
210
227
  public fromTimestamp( timestamp: number ): TimeDuration {
211
228
  return TimeDuration.ms( this.ms - timestamp );
212
229
  }
@@ -260,8 +277,8 @@ export class TimeInstant extends TimeBase<TimeInstant> {
260
277
  }
261
278
 
262
279
  /**
263
- * @deprecated[19/07/2023] Use {@link fromParameters} instead.
264
- */
280
+ * @deprecated[19/07/2023] Use {@link fromParameters} instead.
281
+ */
265
282
  public static fromUnits( { date, month, year, hours, minutes, seconds }: { date: number, month: number, year: number, hours?: number, minutes?: number, seconds?: number } ): TimeInstant {
266
283
  const dt = Date.UTC( year, month - 1, date, hours ?? 0, minutes ?? 0, seconds ?? 0 );
267
284
  if ( isNaN( dt ) )
@@ -334,15 +351,15 @@ export class TimeInstant extends TimeBase<TimeInstant> {
334
351
  }
335
352
 
336
353
  /**
337
- * Returns the week number represented by this instant, according to the ISO 8601 standard.
354
+ * Returns the week number represented by this instant, according to the ISO 8601 standard.
338
355
  * Please note that the instant and the week number could be of two different years, eg the friday 1st january is actually part of week 52 of the previous year.
339
- */
356
+ */
340
357
  public get weekNumber(): { weekNumber: TWeekNumber, year: number } {
341
358
  /**
342
359
  * According to the ISO 8601 Standard, week number 1 is defined as the week containing the 4th of january (or, equivalently, the week that contains the first Thursday of the year).
343
360
  * As such, we basically have to count how many Thursdays there has been in this year.
344
361
  * Please note that the thursdayOfThisWeek could be in the previous year.
345
- */
362
+ */
346
363
  const date = this.toDate();
347
364
  const oneDay = 1000 * 60 * 60 * 24;
348
365
  const thursdayOfThisWeek = new Date( date.getFullYear(), date.getMonth(), date.getDate() + 4 - ( date.getDay() || 7 ), 14, 0, 0 );
@@ -353,8 +370,8 @@ export class TimeInstant extends TimeBase<TimeInstant> {
353
370
  }
354
371
 
355
372
  /**
356
- * This method is used to provide a better DX when inspecting a TimeInstant object in DevTools.
357
- */
373
+ * This method is used to provide a better DX when inspecting a TimeInstant object in DevTools.
374
+ */
358
375
  protected get _time() {
359
376
  return this.asHumanTimestamp();
360
377
  }
@@ -1,40 +1,40 @@
1
1
 
2
- import { TFunction, TKeysOfType } from "..";
2
+ import { TFunction, TKeysOfType, TReadableArray } from "..";
3
3
 
4
- export function groupByString<V, K extends TKeysOfType<V, string>>( arr: V[], field: K ): Record<V[K] & string, V[]> {
4
+ export function groupByString<V, K extends TKeysOfType<V, string>>( arr: TReadableArray<V>, field: K ): Record<V[ K ] & string, V[]> {
5
5
  return groupByStringWith( arr, t => t[ field ] as string );
6
6
  }
7
7
 
8
- export function groupByNumber<V, K extends TKeysOfType<V, number>>( arr: V[], field: K ): Record<V[K] & number, V[]> {
8
+ export function groupByNumber<V, K extends TKeysOfType<V, number>>( arr: TReadableArray<V>, field: K ): Record<V[ K ] & number, V[]> {
9
9
  return groupByNumberWith( arr, t => t[ field ] as number );
10
10
  }
11
11
 
12
- export function groupByBoolean<V, K extends TKeysOfType<V, boolean>>( arr: V[], field: K ): Record<"true" | "false", V[]> {
12
+ export function groupByBoolean<V, K extends TKeysOfType<V, boolean>>( arr: TReadableArray<V>, field: K ): Record<"true" | "false", V[]> {
13
13
  return groupByBooleanWith( arr, t => t[ field ] as boolean );
14
14
  }
15
15
 
16
- export function groupBySymbol<V, K extends TKeysOfType<V, symbol>>( arr: V[], field: K ): Record<V[K] & symbol, V[]> {
16
+ export function groupBySymbol<V, K extends TKeysOfType<V, symbol>>( arr: TReadableArray<V>, field: K ): Record<V[ K ] & symbol, V[]> {
17
17
  return groupBySymbolWith( arr, t => t[ field ] as symbol );
18
18
  }
19
19
 
20
- export function groupByStringWith<V, K extends string>( arr: V[], getter: TFunction<V, K> ): Record<K, V[]> {
20
+ export function groupByStringWith<V, K extends string>( arr: TReadableArray<V>, getter: TFunction<V, K> ): Record<K, V[]> {
21
21
  return doGroupByWith<K, V>( arr, getter );
22
22
  }
23
23
 
24
- export function groupByNumberWith<V, K extends number>( arr: V[], getter: TFunction<V, K> ): Record<K, V[]> {
24
+ export function groupByNumberWith<V, K extends number>( arr: TReadableArray<V>, getter: TFunction<V, K> ): Record<K, V[]> {
25
25
  return doGroupByWith<K, V>( arr, getter );
26
26
  }
27
27
 
28
- export function groupByBooleanWith<V, K extends boolean>( arr: V[], getter: TFunction<V, K> ): Record<"true" | "false", V[]> {
28
+ export function groupByBooleanWith<V, K extends boolean>( arr: TReadableArray<V>, getter: TFunction<V, K> ): Record<"true" | "false", V[]> {
29
29
  return doGroupByWith<"true" | "false", V>( arr, item => getter( item ) ? "true" : "false" );
30
30
  }
31
31
 
32
- export function groupBySymbolWith<V, K extends symbol>( arr: V[], getter: TFunction<V, K> ): Record<K, V[]> {
32
+ export function groupBySymbolWith<V, K extends symbol>( arr: TReadableArray<V>, getter: TFunction<V, K> ): Record<K, V[]> {
33
33
  return doGroupByWith<K, V>( arr, getter );
34
34
  }
35
35
 
36
- function doGroupByWith<K extends string | number | symbol, V>( arr: V[], getter: TFunction<V, K> ): Record<K, V[]> {
37
- return arr.reduce( ( dict, cur ) => {
36
+ function doGroupByWith<K extends string | number | symbol, V>( arr: TReadableArray<V>, getter: TFunction<V, K> ): Record<K, V[]> { // TODO[2025-01-03, Native]: Migrate to native @ https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/#object.groupby-and-map.groupby
37
+ return [ ...arr ].reduce( ( dict, cur ) => {
38
38
  const key = getter( cur );
39
39
  if ( key !== null && key !== undefined ) {
40
40
  const arr = dict[ key ] ?? [];
@@ -1,9 +1,15 @@
1
+ import { TPositiveNumber } from "./numbers.ts";
1
2
 
3
+ /** @deprecated[2025-01-14]: Use {@link randomNumberInInterval} instead. */
4
+ export const randomInterval = ( min: number, max: number ): number => randomNumberInInterval( min, max );
2
5
 
3
- export function randomInterval( min: number, max: number ): number {
6
+ /** @deprecated[2025-01-14]: Use {@link randomNumberInInterval} / 100 instead. */
7
+ export const randomPercentage = ( min: number, max: number ): number => randomNumberInInterval( min, max ) / 100;
8
+
9
+ export function randomNumberInInterval( min: number, max: number ): number {
4
10
  return Math.floor( Math.random() * ( max - min + 1 ) + min );
5
11
  }
6
12
 
7
- export function randomPercentage( min: number, max: number ): number {
8
- return randomInterval( min, max ) / 100;
13
+ export const randomId = ( length: TPositiveNumber ): string => {
14
+ return Math.random().toString(36).substring(2, length + 2);
9
15
  }
@@ -26,3 +26,15 @@ export type TConditionalParameterOptions<T, R> = TConditionalParameter<TOptionsW
26
26
  * Given a type T, replaces all fields of type From to fields of type To.
27
27
  */
28
28
  export type TReplaceType<T, From, To> = { [ K in keyof T ]: T[ K ] extends From ? To : T[ K ]; };
29
+
30
+ /**
31
+ * Given a type T, make field K required instead of optional.
32
+ */
33
+ export type TWithRequiredProperty<T, K extends keyof T> = T & {
34
+ [ Property in K ]-?: T[ Property ];
35
+ };
36
+
37
+ /**
38
+ * Given a type T, make all fields required instead of optional.
39
+ */
40
+ export type TWithRequiredProperties<T> = Required<T>;