@softsky/utils 2.5.1 → 2.5.3

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.
package/README.md CHANGED
@@ -36,32 +36,32 @@ export function newStuff() {}
36
36
  ## Arrays
37
37
  Everything array related.
38
38
 
39
- ${\textsf{\color{CornflowerBlue}function}}$ randomFromArray - Returns random element from non-empty array
39
+ __function__ `randomFromArray` - Returns random element from non-empty array
40
40
 
41
41
  ---
42
- ${\textsf{\color{CornflowerBlue}function}}$ shuffleArray - Create new shuffled array
42
+ __function__ `shuffleArray` - Create new shuffled array
43
43
 
44
44
  ---
45
- ${\textsf{\color{CornflowerBlue}function}}$ swap - Swap two elements in array
45
+ __function__ `swap` - Swap two elements in array
46
46
 
47
47
  ---
48
- ${\textsf{\color{CornflowerBlue}function}}$ binarySearch - Binary search in sorted array.
48
+ __function__ `binarySearch` - Binary search in sorted array.
49
49
  Compare function should compare your needed value with value on index passed to it.
50
50
  If compare returns 0 it means we found target.
51
51
  If compare returns > 0 it means we have to cut out bigger side of array.
52
52
  If compare returns < 0 it means we have to cut out smaller side of array.
53
53
 
54
54
  ---
55
- ${\textsf{\color{CornflowerBlue}function}}$ chunk - Split array into sub arrays of spicified size
55
+ __function__ `chunk` - Split array into sub arrays of spicified size
56
56
 
57
57
  ---
58
- ${\textsf{\color{CornflowerBlue}function}}$ combinations - Return all combinations of items in array
58
+ __function__ `combinations` - Return all combinations of items in array
59
59
 
60
60
  ---
61
- ${\textsf{\color{CornflowerBlue}function}}$ permutations - Return all permutations of items in array
61
+ __function__ `permutations` - Return all permutations of items in array
62
62
 
63
63
  ---
64
- ${\textsf{\color{CornflowerBlue}function}}$ pushToSorted - Push data to sorted array. Array will always be kept sorted.
64
+ __function__ `pushToSorted` - Push data to sorted array. Array will always be kept sorted.
65
65
 
66
66
  Compare function should compare your needed value with value on index passed to it.
67
67
  If compare returns 0 it means we found target.
@@ -73,13 +73,13 @@ pushToSorted(numArray, 10, x => x - 10);
73
73
  ```
74
74
 
75
75
  ---
76
- ${\textsf{\color{CornflowerBlue}function}}$ removeFromArray - Delete value from array.
76
+ __function__ `removeFromArray` - Delete value from array.
77
77
  Only deletes first encountered.
78
78
 
79
79
  Returns index of deleted value.
80
80
 
81
81
  ---
82
- ${\textsf{\color{CornflowerBlue}function}}$ removeLastFromArray - Delete value from array.
82
+ __function__ `removeLastFromArray` - Delete value from array.
83
83
  Only deletes last encountered.
84
84
 
85
85
  Returns index of deleted value.
@@ -90,16 +90,16 @@ Returns index of deleted value.
90
90
  ## Consts
91
91
  Some useful consts. That's it.
92
92
 
93
- ${\textsf{\color{ForestGreen}const}}$ DAY_MS - Milliseconds in a full day
93
+ __const__ `DAY_MS` - Milliseconds in a full day
94
94
 
95
95
  ---
96
- ${\textsf{\color{ForestGreen}const}}$ HOUR_MS - Milliseconds in a hour
96
+ __const__ `HOUR_MS` - Milliseconds in a hour
97
97
 
98
98
  ---
99
- ${\textsf{\color{ForestGreen}const}}$ MIN_MS - Milliseconds in a minute
99
+ __const__ `MIN_MS` - Milliseconds in a minute
100
100
 
101
101
  ---
102
- ${\textsf{\color{ForestGreen}const}}$ SEC_MS - Milliseconds in a second
102
+ __const__ `SEC_MS` - Milliseconds in a second
103
103
 
104
104
  ---
105
105
 
@@ -107,17 +107,24 @@ ${\textsf{\color{ForestGreen}const}}$ SEC_MS - Milliseconds in a second
107
107
  ## Control
108
108
  Utils related to code execution flow.
109
109
 
110
- ${\textsf{\color{ForestGreen}const}}$ generateNumberId - Get unique number id
110
+ __const__ `SESSION_ID` - Id generated only once per session
111
111
 
112
112
  ---
113
- ${\textsf{\color{CornflowerBlue}function}}$ UUID - Get universally unique string id.
113
+ __function__ `UUID` - Get universally unique string id.
114
114
  You can get information then id was generated using extractUUIDDate(uuid)
115
+ - 13 char - timestamp
116
+ - 13 char - SESSION_ID
117
+ - 4 char - incremental id
118
+
119
+ 30 char total.
120
+
121
+ USING CUSTOM TIMESTAMP MAY RESULT IN COLLISSIONS
115
122
 
116
123
  ---
117
- ${\textsf{\color{CornflowerBlue}function}}$ extractUUIDDate - Extract exact date of uuid generation
124
+ __function__ `extractUUIDDate` - Extract exact date of uuid generation
118
125
 
119
126
  ---
120
- ${\textsf{\color{CornflowerBlue}function}}$ createCashedFunction - Creates cached function. All arguments/results are cached.
127
+ __function__ `createCashedFunction` - Creates cached function. All arguments/results are cached.
121
128
  Returns [
122
129
  fn [cached function],
123
130
  delete [delete cached result for arguments]
@@ -125,7 +132,7 @@ hash
125
132
  ]
126
133
 
127
134
  ---
128
- ${\textsf{\color{CornflowerBlue}function}}$ createCashedAsyncFunction - Creates cached function. All arguments/results are cached. Will store in cache resolved data.
135
+ __function__ `createCashedAsyncFunction` - Creates cached function. All arguments/results are cached. Will store in cache resolved data.
129
136
  Returns [
130
137
  fn [cached function],
131
138
  delete [delete cached result for arguments]
@@ -133,29 +140,32 @@ hash
133
140
  ]
134
141
 
135
142
  ---
136
- ${\textsf{\color{CornflowerBlue}async function}}$ retry - Retry async function
143
+ __async function__ `retry` - Retry async function
137
144
 
138
145
  ---
139
- ${\textsf{\color{CornflowerBlue}function}}$ createDebouncedFunction - Create debounced function. Basically adds cooldown to function. Warning: throws!
146
+ __function__ `createDebouncedFunction` - Create debounced function. Basically adds cooldown to function. Warning: throws!
140
147
 
141
148
  ---
142
- ${\textsf{\color{CornflowerBlue}function}}$ createThrottledFunction - Create throttled function. Basically limits function calls in time period. Warning: throws!
149
+ __function__ `createThrottledFunction` - Create throttled function. Basically limits function calls in time period. Warning: throws!
143
150
 
144
151
  ---
145
- ${\textsf{\color{CornflowerBlue}function}}$ createDelayedFunction - Create debounced function. Basically create function that will be called with delay,
152
+ __function__ `createDelayedFunction` - Create debounced function. Basically create function that will be called with delay,
146
153
  but if another call comes in, we reset the timer.
147
154
 
148
155
  ---
149
- ${\textsf{\color{Orange}class}}$ ImmediatePromise - Promise that accepts no callback, but exposes `resolve` and `reject` methods
156
+ __class__ `ImmediatePromise` - Promise that accepts no callback, but exposes `resolve` and `reject` methods
157
+
158
+ ---
159
+ __function__ `wait` - setTimeout promisify
150
160
 
151
161
  ---
152
- ${\textsf{\color{CornflowerBlue}function}}$ wait - setTimeout promisify
162
+ __function__ `noop` - Empty function that does nothing
153
163
 
154
164
  ---
155
- ${\textsf{\color{CornflowerBlue}function}}$ noop - Empty function that does nothing
165
+ __async function__ `concurrentRun` - Run array of async tasks concurrently
156
166
 
157
167
  ---
158
- ${\textsf{\color{CornflowerBlue}async function}}$ concurrentRun - Run array of async tasks concurrently
168
+ __class__ `SimpleEventSource` - Create simple event source. Consider using `signal()` for reactive state managment.
159
169
 
160
170
  ---
161
171
 
@@ -163,10 +173,10 @@ ${\textsf{\color{CornflowerBlue}async function}}$ concurrentRun - Run array of a
163
173
  ## Errors
164
174
  Custom errors, finding errors and error handling.
165
175
 
166
- ${\textsf{\color{Orange}class}}$ ValidationError - Use as intended error. Basically 4** errors in HTTP
176
+ __class__ `ValidationError` - Use as intended error. Basically 4** errors in HTTP
167
177
 
168
178
  ---
169
- ${\textsf{\color{CornflowerBlue}function}}$ findErrorText - Find error inside anything recursively.
179
+ __function__ `findErrorText` - Find error inside anything recursively.
170
180
  Good for finding human-readable errors.
171
181
  Tries priority keys first.
172
182
  Parses JSON automatically.
@@ -178,37 +188,37 @@ Returns undefind if nothing found.
178
188
  ## Formatting
179
189
  Anything related to formatting and logging.
180
190
 
181
- ${\textsf{\color{Magenta}type}}$ FormatTimeRange - Type for formatTime ranges
191
+ __type__ `FormatTimeRange` - Type for formatTime ranges
182
192
 
183
193
  ---
184
- ${\textsf{\color{ForestGreen}const}}$ FORMAT_NUMBER_RANGES - Default time range
194
+ __const__ `FORMAT_NUMBER_RANGES` - Default time range
185
195
 
186
196
  ---
187
- ${\textsf{\color{ForestGreen}const}}$ FORMAT_NUMBER_RANGES_READABLE - Time range more suitable for readability
197
+ __const__ `FORMAT_NUMBER_RANGES_READABLE` - Time range more suitable for readability
188
198
 
189
199
  ---
190
- ${\textsf{\color{ForestGreen}const}}$ FORMAT_NUMBER_RANGES_BYTES - Bytes range
200
+ __const__ `FORMAT_NUMBER_RANGES_BYTES` - Bytes range
191
201
 
192
202
  ---
193
- ${\textsf{\color{CornflowerBlue}function}}$ formatNumber - Milliseconds to human readable time. Minimum accuracy, if set to 1000 will stop at seconds
203
+ __function__ `formatNumber` - Milliseconds to human readable time. Minimum accuracy, if set to 1000 will stop at seconds
194
204
 
195
205
  ---
196
- ${\textsf{\color{CornflowerBlue}function}}$ camelToSnakeCase - thisCase to this_case
206
+ __function__ `camelToSnakeCase` - thisCase to this_case
197
207
 
198
208
  ---
199
- ${\textsf{\color{CornflowerBlue}function}}$ snakeToCamelCase - this_case to thisCase
209
+ __function__ `snakeToCamelCase` - this_case to thisCase
200
210
 
201
211
  ---
202
- ${\textsf{\color{CornflowerBlue}function}}$ formatBytes - Bytes to KB,MB,GB,TB
212
+ __function__ `formatBytes` - Bytes to KB,MB,GB,TB
203
213
 
204
214
  ---
205
- ${\textsf{\color{CornflowerBlue}function}}$ log - Format logging
215
+ __function__ `log` - Format logging
206
216
 
207
217
  ---
208
- ${\textsf{\color{CornflowerBlue}function}}$ capitalizeFirstLetter - Capitalize first letter
218
+ __function__ `capitalizeFirstLetter` - Capitalize first letter
209
219
 
210
220
  ---
211
- ${\textsf{\color{CornflowerBlue}function}}$ pipe - pipe() can be called on one or more functions, each of which can take the return of previous value.
221
+ __function__ `pipe` - pipe() can be called on one or more functions, each of which can take the return of previous value.
212
222
 
213
223
  ```ts
214
224
  // Takes string, converts to int, calc sqrt, convert and return date
@@ -225,21 +235,21 @@ pipe(
225
235
  ## Graphs
226
236
  Pos
227
237
 
228
- ${\textsf{\color{CornflowerBlue}function}}$ unfoldPathfindingResult - Unfold pathfinding result to path array.
238
+ __function__ `unfoldPathfindingResult` - Unfold pathfinding result to path array.
229
239
 
230
240
  ---
231
- ${\textsf{\color{CornflowerBlue}function}}$ aStar - Pathfind using aStar.
241
+ __function__ `aStar` - Pathfind using aStar.
232
242
  Returns a target and map of parents.
233
243
  You can use `unfoldPathfindingResult()` to get array of nodes.
234
244
 
235
245
  ---
236
- ${\textsf{\color{CornflowerBlue}function}}$ bfs - Breadth-first search. Slower than dfs.
246
+ __function__ `bfs` - Breadth-first search. Slower than dfs.
237
247
  If isTarget is omitted becomes floodfill.
238
248
  Returns a target and map of parents.
239
249
  You can use `unfoldPathfindingResult()` to get array of nodes.
240
250
 
241
251
  ---
242
- ${\textsf{\color{CornflowerBlue}function}}$ dfs - Depth-first search. Faster than bfs.
252
+ __function__ `dfs` - Depth-first search. Faster than bfs.
243
253
  If isTarget is omitted becomes floodfill.
244
254
  Returns a target and map of parents.
245
255
  You can use `unfoldPathfindingResult()` to get array of nodes.
@@ -250,19 +260,19 @@ You can use `unfoldPathfindingResult()` to get array of nodes.
250
260
  ## Numbers
251
261
  Numbers, math, etc.
252
262
 
253
- ${\textsf{\color{CornflowerBlue}function}}$ random - Random number between min and max. May enable float
263
+ __function__ `random` - Random number between min and max. May enable float
254
264
 
255
265
  ---
256
- ${\textsf{\color{CornflowerBlue}function}}$ parseInt - Same as Number.parseInt but throws if NaN or not safe
266
+ __function__ `parseInt` - Same as Number.parseInt but throws if NaN or not safe
257
267
 
258
268
  ---
259
- ${\textsf{\color{CornflowerBlue}function}}$ parseFloat - Same as Number.parseFloat but throws if NaN or Infinity
269
+ __function__ `parseFloat` - Same as Number.parseFloat but throws if NaN or Infinity
260
270
 
261
271
  ---
262
- ${\textsf{\color{CornflowerBlue}function}}$ factorial - Factorial
272
+ __function__ `factorial` - Factorial
263
273
 
264
274
  ---
265
- ${\textsf{\color{CornflowerBlue}function}}$ fib - Fibonacci
275
+ __function__ `fib` - Fibonacci
266
276
 
267
277
  ---
268
278
 
@@ -270,19 +280,19 @@ ${\textsf{\color{CornflowerBlue}function}}$ fib - Fibonacci
270
280
  ## Objects
271
281
  [object Object]
272
282
 
273
- ${\textsf{\color{CornflowerBlue}function}}$ getPropertyNames - Get all prorerty names, including in prototype
283
+ __function__ `getPropertyNames` - Get all prorerty names, including in prototype
274
284
 
275
285
  ---
276
- ${\textsf{\color{CornflowerBlue}function}}$ objectMap - Map function like for arrays, but for objects
286
+ __function__ `objectMap` - Map function like for arrays, but for objects
277
287
 
278
288
  ---
279
- ${\textsf{\color{CornflowerBlue}function}}$ objectFilter - Filter function like for arrays, but for objects
289
+ __function__ `objectFilter` - Filter function like for arrays, but for objects
280
290
 
281
291
  ---
282
- ${\textsf{\color{CornflowerBlue}function}}$ addPrefixToObject - Adds prefix to every key in object
292
+ __function__ `addPrefixToObject` - Adds prefix to every key in object
283
293
 
284
294
  ---
285
- ${\textsf{\color{CornflowerBlue}function}}$ deepEquals - Check if objects are deep equal
295
+ __function__ `deepEquals` - Check if objects are deep equal
286
296
 
287
297
  **Supports:**
288
298
  - All primitives (String, Number, BigNumber, Null, undefined, Symbol)
@@ -300,10 +310,10 @@ Behavior with types above are not defined, but
300
310
  it will still check them by reference.
301
311
 
302
312
  ---
303
- ${\textsf{\color{CornflowerBlue}function}}$ pick - Pick keys from object
313
+ __function__ `pick` - Pick keys from object
304
314
 
305
315
  ---
306
- ${\textsf{\color{Orange}class}}$ Base - Base class that helps to manage ids and subclasses.
316
+ __class__ `Base` - Base class that helps to manage ids and subclasses.
307
317
 
308
318
  Include next lines when extending this class:
309
319
  ```js
@@ -318,7 +328,7 @@ this.registerSubclass()
318
328
  ## Signals
319
329
  Reactive signals
320
330
 
321
- ${\textsf{\color{CornflowerBlue}function}}$ signal - __SIGNALS SYSTEM__
331
+ __function__ `signal` - __SIGNALS SYSTEM__
322
332
 
323
333
  Signal can hold any data (except functions),
324
334
  when this data has changed any effects containing
@@ -336,7 +346,7 @@ console.log($mySignal())
336
346
  ```
337
347
 
338
348
  ---
339
- ${\textsf{\color{CornflowerBlue}function}}$ effect - __SIGNALS SYSTEM__
349
+ __function__ `effect` - __SIGNALS SYSTEM__
340
350
 
341
351
  Effects are simplest way to react to signal changes.
342
352
  Returned data from handler function will be passed to it on next signal change.
@@ -355,7 +365,7 @@ return mySignal;
355
365
  })
356
366
 
357
367
  ---
358
- ${\textsf{\color{CornflowerBlue}function}}$ untrack - __SIGNALS SYSTEM__
368
+ __function__ `untrack` - __SIGNALS SYSTEM__
359
369
 
360
370
  Untrack helps to not react to changes in effects.
361
371
  ```ts
@@ -368,7 +378,7 @@ console.log(untrack($a)+$b())
368
378
  ```
369
379
 
370
380
  ---
371
- ${\textsf{\color{CornflowerBlue}function}}$ derived - __SIGNALS SYSTEM__
381
+ __function__ `derived` - __SIGNALS SYSTEM__
372
382
 
373
383
  Creates a derived reactive memoized signal.
374
384
 
@@ -378,7 +388,7 @@ const { signal: $sumOfTwo, clear: clearSum } = derived((value) => value + $a(),
378
388
  ```
379
389
 
380
390
  ---
381
- ${\textsf{\color{CornflowerBlue}function}}$ batch - __SIGNALS SYSTEM__
391
+ __function__ `batch` - __SIGNALS SYSTEM__
382
392
 
383
393
  Batches multiple edits, so they don't call same effects multiple times
384
394
 
@@ -398,7 +408,7 @@ $b(5);
398
408
  ```
399
409
 
400
410
  ---
401
- ${\textsf{\color{CornflowerBlue}function}}$ when - __SIGNALS SYSTEM__
411
+ __function__ `when` - __SIGNALS SYSTEM__
402
412
 
403
413
  Returns ImmediatePromise that is resolved when check function returns truthy value.
404
414
  If you want to, you can resolve or reject promise beforehand.
@@ -417,15 +427,15 @@ primise.then(() => clearTimeout(timeout))
417
427
  ## Time
418
428
  Timers, CRON, etc.
419
429
 
420
- ${\textsf{\color{CornflowerBlue}function}}$ measurePerformance - Measure performance of a function
430
+ __function__ `measurePerformance` - Measure performance of a function
421
431
 
422
432
  ---
423
- ${\textsf{\color{CornflowerBlue}function}}$ cronInterval - Like setInterval but with cron.
433
+ __function__ `cronInterval` - Like setInterval but with cron.
424
434
  Returns clear function.
425
435
  For cron string syntax check __getNextCron()__ description
426
436
 
427
437
  ---
428
- ${\textsf{\color{CornflowerBlue}function}}$ getNextCron - Find next cron date after passed date.
438
+ __function__ `getNextCron` - Find next cron date after passed date.
429
439
 
430
440
  This function __DOES NOT__ implement regular CRON 1 to 1.
431
441
 
@@ -435,7 +445,7 @@ Main differences:
435
445
  - Second and millisecond support: __* * * * * 30 999__ - executes every 30 seconds at the end of a second
436
446
 
437
447
  ---
438
- ${\textsf{\color{Orange}class}}$ SpeedCalculator - Object that calculates speed, ETA and percent of any measurable task.
448
+ __class__ `SpeedCalculator` - Object that calculates speed, ETA and percent of any measurable task.
439
449
 
440
450
  `push()` chunks into speed calculator and then read `stats` for results.
441
451
  `size` - a target then task is finished. Without it only speed is calculated.
@@ -447,45 +457,45 @@ ${\textsf{\color{Orange}class}}$ SpeedCalculator - Object that calculates speed,
447
457
  ## Types
448
458
  Damn, I **love** TypeScript.
449
459
 
450
- ${\textsf{\color{Magenta}type}}$ Primitive - Values that are copied by value, not by reference
460
+ __type__ `Primitive` - Values that are copied by value, not by reference
451
461
 
452
462
  ---
453
- ${\textsf{\color{Magenta}type}}$ AnyFunction - Function with any arguments or return type
463
+ __type__ `AnyFunction` - Function with any arguments or return type
454
464
 
455
465
  ---
456
- ${\textsf{\color{Magenta}type}}$ Falsy - Values that convert to false
466
+ __type__ `Falsy` - Values that convert to false
457
467
 
458
468
  ---
459
- ${\textsf{\color{Magenta}type}}$ Optional - Make keys in object optional
469
+ __type__ `Optional` - Make keys in object optional
460
470
 
461
471
  ---
462
- ${\textsf{\color{Magenta}type}}$ RequiredKey - Make keys in object required
472
+ __type__ `RequiredKey` - Make keys in object required
463
473
 
464
474
  ---
465
- ${\textsf{\color{Magenta}type}}$ Constructor - Get contructor type of an instance
475
+ __type__ `Constructor` - Get contructor type of an instance
466
476
 
467
477
  ---
468
- ${\textsf{\color{Magenta}type}}$ AwaitedObject - Recursively resolves promises in objects and arrays
478
+ __type__ `AwaitedObject` - Recursively resolves promises in objects and arrays
469
479
 
470
480
  ---
471
- ${\textsf{\color{Magenta}type}}$ JSONSerializable - Anything that can be serialized to JSON
481
+ __type__ `JSONSerializable` - Anything that can be serialized to JSON
472
482
 
473
483
  ---
474
- ${\textsf{\color{Magenta}type}}$ ObjectAddPrefix - Adds prefix to all keys in object
484
+ __type__ `ObjectAddPrefix` - Adds prefix to all keys in object
475
485
 
476
486
  ---
477
- ${\textsf{\color{Magenta}type}}$ CamelToSnakeCase - Convert type of thisCase to this_case
487
+ __type__ `CamelToSnakeCase` - Convert type of thisCase to this_case
478
488
 
479
489
  ---
480
- ${\textsf{\color{Magenta}type}}$ ObjectCamelToSnakeCase - Convert object keys of thisCase to this_case
490
+ __type__ `ObjectCamelToSnakeCase` - Convert object keys of thisCase to this_case
481
491
 
482
492
  ---
483
- ${\textsf{\color{Magenta}type}}$ SnakeToCamel - Convert type of this-case to thisCase
493
+ __type__ `SnakeToCamel` - Convert type of this-case to thisCase
484
494
 
485
495
  ---
486
- ${\textsf{\color{Magenta}type}}$ ObjectSnakeToCamel - Convert object keys of this-case to thisCase
496
+ __type__ `ObjectSnakeToCamel` - Convert object keys of this-case to thisCase
487
497
 
488
498
  ---
489
- ${\textsf{\color{Magenta}type}}$ Concat - Concat types of array or objects
499
+ __type__ `Concat` - Concat types of array or objects
490
500
 
491
501
  ---
package/dist/control.d.ts CHANGED
@@ -2,13 +2,20 @@
2
2
  * Utils related to code execution flow.
3
3
  */
4
4
  import { AwaitedObject, JSONSerializable } from './types';
5
- /** Get unique number id */
6
- export declare const generateNumberId: () => number;
5
+ /** Id generated only once per session */
6
+ export declare const SESSION_ID: string;
7
7
  /**
8
8
  * Get universally unique string id.
9
9
  * You can get information then id was generated using extractUUIDDate(uuid)
10
+ * - 13 char - timestamp
11
+ * - 13 char - SESSION_ID
12
+ * - 4 char - incremental id
13
+ *
14
+ * 30 char total.
15
+ *
16
+ * USING CUSTOM TIMESTAMP MAY RESULT IN COLLISSIONS
10
17
  */
11
- export declare function UUID(): string;
18
+ export declare function UUID(timestamp?: number): string;
12
19
  /** Extract exact date of uuid generation */
13
20
  export declare function extractUUIDDate(uuid: string): Date;
14
21
  /**
@@ -53,4 +60,19 @@ export declare function wait(time: number): Promise<unknown>;
53
60
  export declare function noop(): void;
54
61
  /** Run array of async tasks concurrently */
55
62
  export declare function concurrentRun<T>(tasks: (() => Promise<T>)[], concurrency?: number): Promise<T[]>;
63
+ /** Create simple event source. Consider using `signal()` for reactive state managment. */
64
+ export declare class SimpleEventSource<EVENTS extends Record<string, unknown>> {
65
+ protected handlers: Map<keyof EVENTS, ((data: EVENTS[keyof EVENTS]) => unknown)[]>;
66
+ /** Send event to all subscribers */
67
+ send<T extends keyof EVENTS>(name: T, data: EVENTS[T]): unknown[];
68
+ /** Subscribe. Returns function to unsubscribe. */
69
+ on<T extends keyof EVENTS>(name: T, handler: (data: EVENTS[T]) => unknown): () => void;
70
+ /** Unsubscribe. Alternatively use return function of `on()` */
71
+ off<T extends keyof EVENTS>(name: T, handler: (data: EVENTS[T]) => unknown): void;
72
+ /** Use this to hide send function */
73
+ get source(): {
74
+ on: <T extends keyof EVENTS>(name: T, handler: (data: EVENTS[T]) => unknown) => () => void;
75
+ off: <T extends keyof EVENTS>(name: T, handler: (data: EVENTS[T]) => unknown) => void;
76
+ };
77
+ }
56
78
  export {};
package/dist/control.js CHANGED
@@ -1,25 +1,34 @@
1
1
  /**
2
2
  * Utils related to code execution flow.
3
3
  */
4
- let stringIdInc = 0;
5
- let _uuid = Date.now() * 1000;
6
- /** Get unique number id */
7
- export const generateNumberId = () => _uuid++;
8
- const SESSION_ID = ((Math.random() * 2_147_483_648) | 0).toString(16);
4
+ import { removeFromArray } from './arrays';
5
+ let lastIncId = Math.floor(Math.random() * 0x1_00_00);
6
+ /** Id generated only once per session */
7
+ export const SESSION_ID = Math.floor(Math.random() * 0x10_00_00_00_00_00_00)
8
+ .toString(16)
9
+ .padStart(13, '0');
9
10
  /**
10
11
  * Get universally unique string id.
11
12
  * You can get information then id was generated using extractUUIDDate(uuid)
13
+ * - 13 char - timestamp
14
+ * - 13 char - SESSION_ID
15
+ * - 4 char - incremental id
16
+ *
17
+ * 30 char total.
18
+ *
19
+ * USING CUSTOM TIMESTAMP MAY RESULT IN COLLISSIONS
12
20
  */
13
- export function UUID() {
14
- if (stringIdInc === 46_655)
15
- stringIdInc = 0;
16
- else
17
- stringIdInc++;
18
- return `${Date.now().toString(36).padStart(11, '0')}${(++stringIdInc).toString(36).padStart(3, '0')}${SESSION_ID}`;
21
+ export function UUID(timestamp = Date.now()) {
22
+ let inc = (++lastIncId).toString(16).padStart(4, '0');
23
+ if (inc.length === 5) {
24
+ lastIncId = 0;
25
+ inc = '0000';
26
+ }
27
+ return `${timestamp.toString(16).padStart(13, '0')}${inc}${SESSION_ID}`;
19
28
  }
20
29
  /** Extract exact date of uuid generation */
21
30
  export function extractUUIDDate(uuid) {
22
- return new Date(Number.parseInt(uuid.slice(0, 11), 36));
31
+ return new Date(Number.parseInt(uuid.slice(0, 13), 16));
23
32
  }
24
33
  /**
25
34
  * Creates cached function. All arguments/results are cached.
@@ -192,3 +201,41 @@ export async function concurrentRun(tasks, concurrency = 4) {
192
201
  runNext();
193
202
  });
194
203
  }
204
+ /** Create simple event source. Consider using `signal()` for reactive state managment. */
205
+ export class SimpleEventSource {
206
+ handlers = new Map();
207
+ /** Send event to all subscribers */
208
+ send(name, data) {
209
+ return this.handlers.get(name)?.map((handler) => handler(data)) ?? [];
210
+ }
211
+ /** Subscribe. Returns function to unsubscribe. */
212
+ on(name, handler) {
213
+ let handlers = this.handlers.get(name);
214
+ if (!handlers) {
215
+ handlers = [];
216
+ this.handlers.set(name, handlers);
217
+ }
218
+ handlers.push(handler);
219
+ return () => {
220
+ removeFromArray(handlers, handler);
221
+ if (handlers.length === 0)
222
+ this.handlers.delete(name);
223
+ };
224
+ }
225
+ /** Unsubscribe. Alternatively use return function of `on()` */
226
+ off(name, handler) {
227
+ const handlers = this.handlers.get(name);
228
+ if (!handlers)
229
+ return;
230
+ removeFromArray(handlers, handler);
231
+ if (handlers.length === 0)
232
+ this.handlers.delete(name);
233
+ }
234
+ /** Use this to hide send function */
235
+ get source() {
236
+ return {
237
+ on: this.on.bind(this),
238
+ off: this.off.bind(this),
239
+ };
240
+ }
241
+ }
@@ -80,7 +80,7 @@ export function formatNumber(time, min = 0, ranges = FORMAT_NUMBER_RANGES) {
80
80
  break;
81
81
  if (time < start && !pad)
82
82
  continue;
83
- let value = ((time / start) | 0).toString();
83
+ let value = Math.floor(time / start).toString();
84
84
  time %= start;
85
85
  if (pad)
86
86
  value = value.padStart(pad, '0');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softsky/utils",
3
- "version": "2.5.1",
3
+ "version": "2.5.3",
4
4
  "description": "JavaScript/TypeScript utilities",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {