@hkdigital/lib-sveltekit 0.0.47 → 0.0.50
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 +3 -4
- package/dist/classes/promise/HkPromise.d.ts +116 -0
- package/dist/classes/promise/HkPromise.js +387 -0
- package/dist/classes/promise/index.d.ts +1 -0
- package/dist/classes/promise/index.js +1 -0
- package/dist/util/function/index.d.ts +20 -0
- package/dist/util/{function.js__ → function/index.js} +35 -37
- package/dist/util/time/index.d.ts +120 -0
- package/dist/util/{time.js__ → time/index.js} +137 -128
- package/package.json +13 -1
package/README.md
CHANGED
@@ -42,12 +42,11 @@ ncu "@hkdigital/*" -u && pnpm install
|
|
42
42
|
```
|
43
43
|
We use a wildcard to upgrade all installed `node_modules` in the scope `@hkdigital`.
|
44
44
|
|
45
|
-
You can also add this command to your project
|
45
|
+
You can also add this command to your project. To do so, add the lines to the bottom of the `scripts` section of your `package.json`.
|
46
46
|
|
47
47
|
```bash
|
48
|
-
"
|
49
|
-
|
50
|
-
"upgrade:all": "ncu -u && pnpm install"
|
48
|
+
"upgrade:hklib": "ncu '@hkdigital/*' -u && pnpm install",
|
49
|
+
"upgrade:all": "ncu -u && pnpm install"
|
51
50
|
```
|
52
51
|
|
53
52
|
### Import JS & Svelte
|
@@ -0,0 +1,116 @@
|
|
1
|
+
/**
|
2
|
+
* HkPromise extends the default javascript Promise class
|
3
|
+
*/
|
4
|
+
export default class HkPromise extends Promise<any> {
|
5
|
+
constructor(initFn: any);
|
6
|
+
/**
|
7
|
+
* Get value of property [resolved]
|
8
|
+
*
|
9
|
+
* @returns {boolean} true if the promise has been resolved
|
10
|
+
*/
|
11
|
+
get resolved(): boolean;
|
12
|
+
/**
|
13
|
+
* Get value of property [rejected]
|
14
|
+
*
|
15
|
+
* @returns {boolean} true if the promise was rejected
|
16
|
+
*/
|
17
|
+
get rejected(): boolean;
|
18
|
+
/**
|
19
|
+
* Get value of property [pending]
|
20
|
+
*
|
21
|
+
* @returns {boolean} true if the promise is still pending
|
22
|
+
*/
|
23
|
+
get pending(): boolean;
|
24
|
+
/**
|
25
|
+
* Get value of property [cancelled]
|
26
|
+
*
|
27
|
+
* @returns {boolean} true if the promise was cancelled
|
28
|
+
*/
|
29
|
+
get cancelled(): boolean;
|
30
|
+
/**
|
31
|
+
* Get value of property [timeout]
|
32
|
+
*
|
33
|
+
* @returns {boolean} true if the promise was cancelled due to a timeout
|
34
|
+
*/
|
35
|
+
get timeout(): boolean;
|
36
|
+
/**
|
37
|
+
* Resolve the promise
|
38
|
+
*
|
39
|
+
* @param {mixed} [value] - Value to pass to the "then" callbacks
|
40
|
+
*
|
41
|
+
* @returns {object} this
|
42
|
+
*/
|
43
|
+
resolve(...args: any[]): object;
|
44
|
+
/**
|
45
|
+
* Resolve the promise if the promise is still pending
|
46
|
+
*
|
47
|
+
* @param {mixed} [value] - Value to pass to the "catch" callbacks
|
48
|
+
*
|
49
|
+
* @returns {object} this
|
50
|
+
*/
|
51
|
+
tryResolve(...args: any[]): object;
|
52
|
+
/**
|
53
|
+
* Reject the promise
|
54
|
+
*
|
55
|
+
* @param {Object} [errorOrInfo]
|
56
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
57
|
+
*
|
58
|
+
* @returns {object} this
|
59
|
+
*/
|
60
|
+
reject(...args: any[]): object;
|
61
|
+
/**
|
62
|
+
* Reject the promise if the promise is still pending
|
63
|
+
*
|
64
|
+
* @param {Object} [errorOrInfo]
|
65
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
66
|
+
*
|
67
|
+
* @returns {object} this
|
68
|
+
*/
|
69
|
+
tryReject(...args: any[]): object;
|
70
|
+
/**
|
71
|
+
* Reject the promise and set this.cancelled=true
|
72
|
+
*
|
73
|
+
* @param {Object} [errorOrInfo]
|
74
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
75
|
+
*
|
76
|
+
* @returns {object} this
|
77
|
+
*/
|
78
|
+
cancel(errorOrInfo?: any, ...args: any[]): object;
|
79
|
+
/**
|
80
|
+
* Reject the promise and set this.cancelled=true
|
81
|
+
*
|
82
|
+
* @param {Object} [errorOrInfo]
|
83
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
84
|
+
*
|
85
|
+
* @returns {object} this
|
86
|
+
*/
|
87
|
+
tryCancel(...args: any[]): object;
|
88
|
+
/**
|
89
|
+
* Specify the number of milliseconds until the promise should time out.
|
90
|
+
* - When a timeout occurs: the promise is cancelled and the following
|
91
|
+
* properties are both set
|
92
|
+
*
|
93
|
+
* this.timeout=true
|
94
|
+
* this.cancelled=true
|
95
|
+
*
|
96
|
+
* @param {number} ms
|
97
|
+
* Number of milliseconds after which the promise should time out
|
98
|
+
*
|
99
|
+
* @param {string} [message="Timeout"]
|
100
|
+
* Message of the error that will be thrown when the timeout occurs
|
101
|
+
*/
|
102
|
+
setTimeout(ms: number, message?: string): this;
|
103
|
+
/**
|
104
|
+
* Register a callback that is called when the promise resolves
|
105
|
+
*
|
106
|
+
* @param {function} callback
|
107
|
+
*/
|
108
|
+
then(...args: any[]): Promise<any>;
|
109
|
+
/**
|
110
|
+
* Register a callback that is called when the promise rejects, is
|
111
|
+
* cancelled or times out
|
112
|
+
*
|
113
|
+
* @param {function} callback
|
114
|
+
*/
|
115
|
+
catch(...args: any[]): Promise<any>;
|
116
|
+
}
|
@@ -0,0 +1,387 @@
|
|
1
|
+
/**
|
2
|
+
* Hkpromise.js
|
3
|
+
*
|
4
|
+
* @description
|
5
|
+
* HkPromise extends the default Promise class. A HkPromise offers some
|
6
|
+
* additional methods, e.g. resolve, reject and setTimeout, which makes it
|
7
|
+
* easier to use than the build in Promise class in some code constructions.
|
8
|
+
*
|
9
|
+
* @example
|
10
|
+
*
|
11
|
+
* import HkPromise from "./HkPromise.js";
|
12
|
+
*
|
13
|
+
* function() {
|
14
|
+
* const promise = new HkPromise();
|
15
|
+
*
|
16
|
+
* setTimeout( promise.resolve, 1000 );
|
17
|
+
*
|
18
|
+
* return promise;
|
19
|
+
* }
|
20
|
+
*/
|
21
|
+
|
22
|
+
/* ------------------------------------------------------------------ Imports */
|
23
|
+
|
24
|
+
import * as expect from '../../util/expect/index.js';
|
25
|
+
|
26
|
+
import { noop } from '../../util/function/index.js';
|
27
|
+
|
28
|
+
/* ---------------------------------------------------------------- Internals */
|
29
|
+
|
30
|
+
const resolved$ = Symbol('resolved');
|
31
|
+
const rejected$ = Symbol('rejected');
|
32
|
+
const pending$ = Symbol('pending');
|
33
|
+
|
34
|
+
const timeout$ = Symbol('timeout');
|
35
|
+
const cancelled$ = Symbol('cancelled');
|
36
|
+
|
37
|
+
const resolveFn$ = Symbol('resolveFn');
|
38
|
+
const rejectFn$ = Symbol('rejectFn');
|
39
|
+
|
40
|
+
const timeoutTimer$ = Symbol('timeoutTimer');
|
41
|
+
|
42
|
+
const hasThen$ = Symbol('hasThen');
|
43
|
+
|
44
|
+
/* ------------------------------------------------------------------- Export */
|
45
|
+
|
46
|
+
/**
|
47
|
+
* HkPromise extends the default javascript Promise class
|
48
|
+
*/
|
49
|
+
export default class HkPromise extends Promise {
|
50
|
+
constructor(initFn) {
|
51
|
+
let _resolveFn;
|
52
|
+
let _rejectFn;
|
53
|
+
|
54
|
+
super((resolveFn, rejectFn) => {
|
55
|
+
//
|
56
|
+
// @note if initFn cannot be called an exception will be thrown:
|
57
|
+
// TypeError: Promise resolve or reject function is not callable
|
58
|
+
//
|
59
|
+
if (initFn) {
|
60
|
+
initFn(resolveFn, rejectFn);
|
61
|
+
}
|
62
|
+
|
63
|
+
_resolveFn = resolveFn;
|
64
|
+
_rejectFn = rejectFn;
|
65
|
+
});
|
66
|
+
|
67
|
+
// @note some values are not initialized on purpose,
|
68
|
+
// to save time during promise creation
|
69
|
+
|
70
|
+
this[resolveFn$] = _resolveFn;
|
71
|
+
this[rejectFn$] = _rejectFn;
|
72
|
+
|
73
|
+
// this[ resolved$ ] = false;
|
74
|
+
// this[ rejected$ ] = false;
|
75
|
+
|
76
|
+
this[pending$] = true;
|
77
|
+
|
78
|
+
// this[ cancelled$ ] = false;
|
79
|
+
// this[ timeout$ ] = false;
|
80
|
+
|
81
|
+
// this[ timeoutTimer$ ] = undefined;
|
82
|
+
}
|
83
|
+
|
84
|
+
// -------------------------------------------------------------------- Method
|
85
|
+
|
86
|
+
/**
|
87
|
+
* Get value of property [resolved]
|
88
|
+
*
|
89
|
+
* @returns {boolean} true if the promise has been resolved
|
90
|
+
*/
|
91
|
+
get resolved() {
|
92
|
+
return this[resolved$] ? true : false;
|
93
|
+
}
|
94
|
+
|
95
|
+
// -------------------------------------------------------------------- Method
|
96
|
+
|
97
|
+
/**
|
98
|
+
* Get value of property [rejected]
|
99
|
+
*
|
100
|
+
* @returns {boolean} true if the promise was rejected
|
101
|
+
*/
|
102
|
+
get rejected() {
|
103
|
+
return this[rejected$] ? true : false;
|
104
|
+
}
|
105
|
+
|
106
|
+
// -------------------------------------------------------------------- Method
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Get value of property [pending]
|
110
|
+
*
|
111
|
+
* @returns {boolean} true if the promise is still pending
|
112
|
+
*/
|
113
|
+
get pending() {
|
114
|
+
return this[pending$];
|
115
|
+
}
|
116
|
+
|
117
|
+
// -------------------------------------------------------------------- Method
|
118
|
+
|
119
|
+
/**
|
120
|
+
* Get value of property [cancelled]
|
121
|
+
*
|
122
|
+
* @returns {boolean} true if the promise was cancelled
|
123
|
+
*/
|
124
|
+
get cancelled() {
|
125
|
+
return this[cancelled$] ? true : false;
|
126
|
+
}
|
127
|
+
|
128
|
+
// -------------------------------------------------------------------- Method
|
129
|
+
|
130
|
+
/**
|
131
|
+
* Get value of property [timeout]
|
132
|
+
*
|
133
|
+
* @returns {boolean} true if the promise was cancelled due to a timeout
|
134
|
+
*/
|
135
|
+
get timeout() {
|
136
|
+
return this[timeout$] ? true : false;
|
137
|
+
}
|
138
|
+
|
139
|
+
// -------------------------------------------------------------------- Method
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Resolve the promise
|
143
|
+
*
|
144
|
+
* @param {mixed} [value] - Value to pass to the "then" callbacks
|
145
|
+
*
|
146
|
+
* @returns {object} this
|
147
|
+
*/
|
148
|
+
resolve(/* value */) {
|
149
|
+
// -- Check current Promise state
|
150
|
+
|
151
|
+
if (!this[pending$]) {
|
152
|
+
if (this[resolved$]) {
|
153
|
+
throw new Error('Cannot resolve Promise. Promise has already resolved');
|
154
|
+
} else {
|
155
|
+
throw new Error('Cannot resolve Promise. Promise has already been rejected');
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
// -- Clear timeout timer (if any)
|
160
|
+
|
161
|
+
if (undefined !== this[timeoutTimer$]) {
|
162
|
+
clearTimeout(this[timeoutTimer$]);
|
163
|
+
|
164
|
+
this[timeoutTimer$] = undefined;
|
165
|
+
}
|
166
|
+
|
167
|
+
// -- Set flags and call resolve function
|
168
|
+
|
169
|
+
this[resolved$] = true;
|
170
|
+
this[pending$] = false;
|
171
|
+
|
172
|
+
this[resolveFn$](...arguments);
|
173
|
+
|
174
|
+
return this;
|
175
|
+
}
|
176
|
+
|
177
|
+
// -------------------------------------------------------------------- Method
|
178
|
+
|
179
|
+
/**
|
180
|
+
* Resolve the promise if the promise is still pending
|
181
|
+
*
|
182
|
+
* @param {mixed} [value] - Value to pass to the "catch" callbacks
|
183
|
+
*
|
184
|
+
* @returns {object} this
|
185
|
+
*/
|
186
|
+
tryResolve(/* value */) {
|
187
|
+
if (this[pending$]) {
|
188
|
+
this.resolve(...arguments);
|
189
|
+
}
|
190
|
+
|
191
|
+
return this;
|
192
|
+
}
|
193
|
+
|
194
|
+
// -------------------------------------------------------------------- Method
|
195
|
+
|
196
|
+
/**
|
197
|
+
* Reject the promise
|
198
|
+
*
|
199
|
+
* @param {Object} [errorOrInfo]
|
200
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
201
|
+
*
|
202
|
+
* @returns {object} this
|
203
|
+
*/
|
204
|
+
reject(/* errorOrInfo */) {
|
205
|
+
if (!this[hasThen$]) {
|
206
|
+
//
|
207
|
+
// No then (or await) has been used
|
208
|
+
// add catch to prevent useless unhandled promise rejection
|
209
|
+
//
|
210
|
+
this.catch(noop);
|
211
|
+
}
|
212
|
+
|
213
|
+
// -- Check current Promise state
|
214
|
+
|
215
|
+
if (!this[pending$]) {
|
216
|
+
if (this[resolved$]) {
|
217
|
+
throw new Error('Cannot reject Promise. Promise has already resolved');
|
218
|
+
} else {
|
219
|
+
throw new Error('Cannot reject Promise. Promise has already been rejected');
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
// -- Clear timeout timer (if any)
|
224
|
+
|
225
|
+
if (undefined !== this[timeoutTimer$]) {
|
226
|
+
clearTimeout(this[timeoutTimer$]);
|
227
|
+
|
228
|
+
this[timeoutTimer$] = undefined;
|
229
|
+
}
|
230
|
+
|
231
|
+
// -- Set flags and call reject function
|
232
|
+
|
233
|
+
this[rejected$] = true;
|
234
|
+
this[pending$] = false;
|
235
|
+
|
236
|
+
this[rejectFn$](...arguments);
|
237
|
+
|
238
|
+
return this;
|
239
|
+
}
|
240
|
+
|
241
|
+
// -------------------------------------------------------------------- Method
|
242
|
+
|
243
|
+
/**
|
244
|
+
* Reject the promise if the promise is still pending
|
245
|
+
*
|
246
|
+
* @param {Object} [errorOrInfo]
|
247
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
248
|
+
*
|
249
|
+
* @returns {object} this
|
250
|
+
*/
|
251
|
+
tryReject(/* errorOrInfo */) {
|
252
|
+
if (this[pending$]) {
|
253
|
+
this.reject(...arguments);
|
254
|
+
}
|
255
|
+
|
256
|
+
return this;
|
257
|
+
}
|
258
|
+
|
259
|
+
// -------------------------------------------------------------------- Method
|
260
|
+
|
261
|
+
/**
|
262
|
+
* Reject the promise and set this.cancelled=true
|
263
|
+
*
|
264
|
+
* @param {Object} [errorOrInfo]
|
265
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
266
|
+
*
|
267
|
+
* @returns {object} this
|
268
|
+
*/
|
269
|
+
cancel(errorOrInfo) {
|
270
|
+
if (errorOrInfo) {
|
271
|
+
if (!(errorOrInfo instanceof Object)) {
|
272
|
+
throw new Error('Invalid parameter [errorOrInfo] (expected (error) object');
|
273
|
+
}
|
274
|
+
} else {
|
275
|
+
errorOrInfo = new Error('Cancelled');
|
276
|
+
}
|
277
|
+
|
278
|
+
errorOrInfo.cancelled = true;
|
279
|
+
|
280
|
+
this[cancelled$] = true;
|
281
|
+
this.reject(...arguments);
|
282
|
+
|
283
|
+
return this;
|
284
|
+
}
|
285
|
+
|
286
|
+
// -------------------------------------------------------------------- Method
|
287
|
+
|
288
|
+
/**
|
289
|
+
* Reject the promise and set this.cancelled=true
|
290
|
+
*
|
291
|
+
* @param {Object} [errorOrInfo]
|
292
|
+
* Object to pass to the "catch" callbacks, usually an Error object
|
293
|
+
*
|
294
|
+
* @returns {object} this
|
295
|
+
*/
|
296
|
+
tryCancel(/*errorOrInfo*/) {
|
297
|
+
if (this[pending$]) {
|
298
|
+
this.cancel(...arguments);
|
299
|
+
}
|
300
|
+
|
301
|
+
return this;
|
302
|
+
}
|
303
|
+
|
304
|
+
// -------------------------------------------------------------------- Method
|
305
|
+
|
306
|
+
/**
|
307
|
+
* Specify the number of milliseconds until the promise should time out.
|
308
|
+
* - When a timeout occurs: the promise is cancelled and the following
|
309
|
+
* properties are both set
|
310
|
+
*
|
311
|
+
* this.timeout=true
|
312
|
+
* this.cancelled=true
|
313
|
+
*
|
314
|
+
* @param {number} ms
|
315
|
+
* Number of milliseconds after which the promise should time out
|
316
|
+
*
|
317
|
+
* @param {string} [message="Timeout"]
|
318
|
+
* Message of the error that will be thrown when the timeout occurs
|
319
|
+
*/
|
320
|
+
setTimeout(ms, message = 'Timeout') {
|
321
|
+
expect.number(ms);
|
322
|
+
expect.string(message);
|
323
|
+
|
324
|
+
// -- Check current Promise state
|
325
|
+
|
326
|
+
if (!this[pending$]) {
|
327
|
+
if (this[resolved$]) {
|
328
|
+
throw new Error('Cannot set timeout. Promise has already resolved');
|
329
|
+
} else {
|
330
|
+
throw new Error('Cannot set timeout. Promise has already been rejected');
|
331
|
+
}
|
332
|
+
}
|
333
|
+
|
334
|
+
// -- Clear existing timeout (if any)
|
335
|
+
|
336
|
+
if (undefined !== this[timeoutTimer$]) {
|
337
|
+
clearTimeout(this[timeoutTimer$]);
|
338
|
+
}
|
339
|
+
|
340
|
+
// -- Set timeout
|
341
|
+
|
342
|
+
const err = new Error(message);
|
343
|
+
|
344
|
+
this[timeoutTimer$] = setTimeout(() => {
|
345
|
+
if (!this[pending$]) {
|
346
|
+
// Promise has already been resolved (should not happen)
|
347
|
+
return;
|
348
|
+
}
|
349
|
+
|
350
|
+
this[timeout$] = true;
|
351
|
+
this[cancelled$] = true;
|
352
|
+
|
353
|
+
err.timeout = true;
|
354
|
+
err.cancelled = true;
|
355
|
+
|
356
|
+
this.reject(err);
|
357
|
+
}, ms);
|
358
|
+
|
359
|
+
// return this -> chainable method
|
360
|
+
return this;
|
361
|
+
}
|
362
|
+
|
363
|
+
// -------------------------------------------------------------------- Method
|
364
|
+
|
365
|
+
/**
|
366
|
+
* Register a callback that is called when the promise resolves
|
367
|
+
*
|
368
|
+
* @param {function} callback
|
369
|
+
*/
|
370
|
+
then(/* callback */) {
|
371
|
+
this[hasThen$] = true;
|
372
|
+
|
373
|
+
return super.then(...arguments);
|
374
|
+
}
|
375
|
+
|
376
|
+
// -------------------------------------------------------------------- Method
|
377
|
+
|
378
|
+
/**
|
379
|
+
* Register a callback that is called when the promise rejects, is
|
380
|
+
* cancelled or times out
|
381
|
+
*
|
382
|
+
* @param {function} callback
|
383
|
+
*/
|
384
|
+
catch(/* callback */) {
|
385
|
+
return super.catch(...arguments);
|
386
|
+
}
|
387
|
+
} // end class
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default as HkPromise } from "./HkPromise.js";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default as HkPromise } from './HkPromise.js';
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/**
|
2
|
+
* Wraps a function so that the callback function will be called only once
|
3
|
+
*
|
4
|
+
* @param {function} callback
|
5
|
+
*
|
6
|
+
* @returns {function} callback wrapped in `once` function
|
7
|
+
*/
|
8
|
+
export function once(callback: Function): Function;
|
9
|
+
/**
|
10
|
+
* Returns a debounced function
|
11
|
+
* - The original function is not called more than once during the
|
12
|
+
* specified interval
|
13
|
+
*
|
14
|
+
* @param {function} fn
|
15
|
+
* @param {number} [intervalMs=200]
|
16
|
+
*
|
17
|
+
* @returns {function} debounced function
|
18
|
+
*/
|
19
|
+
export function debounce(fn: Function, intervalMs?: number): Function;
|
20
|
+
export function noop(): void;
|
@@ -16,7 +16,7 @@
|
|
16
16
|
|
17
17
|
/* ------------------------------------------------------------------ Imports */
|
18
18
|
|
19
|
-
import * as
|
19
|
+
import * as expect from '../expect/index.js';
|
20
20
|
|
21
21
|
/* ------------------------------------------------------------------ Exports */
|
22
22
|
|
@@ -36,18 +36,16 @@ export const noop = () => {};
|
|
36
36
|
* @returns {function} callback wrapped in `once` function
|
37
37
|
*/
|
38
38
|
export function once(callback) {
|
39
|
-
|
39
|
+
expect.function(callback);
|
40
40
|
|
41
|
-
|
41
|
+
let ignore = false;
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
}
|
50
|
-
};
|
43
|
+
return function () {
|
44
|
+
if (!ignore) {
|
45
|
+
ignore = true;
|
46
|
+
callback(...arguments);
|
47
|
+
}
|
48
|
+
};
|
51
49
|
}
|
52
50
|
|
53
51
|
// -----------------------------------------------------------------------------
|
@@ -63,40 +61,40 @@ export function once(callback) {
|
|
63
61
|
* @returns {function} debounced function
|
64
62
|
*/
|
65
63
|
export function debounce(fn, intervalMs = 200) {
|
66
|
-
|
67
|
-
|
64
|
+
let idleTimer;
|
65
|
+
let lastArguments;
|
68
66
|
|
69
|
-
|
67
|
+
// console.log("debounce");
|
70
68
|
|
71
|
-
|
72
|
-
|
69
|
+
return function debounced() {
|
70
|
+
// console.log("debounced");
|
73
71
|
|
74
|
-
|
75
|
-
|
72
|
+
if (idleTimer) {
|
73
|
+
// console.log("idleTimer running");
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
75
|
+
// The function has been called recently
|
76
|
+
lastArguments = arguments;
|
77
|
+
return;
|
78
|
+
}
|
81
79
|
|
82
|
-
|
83
|
-
|
80
|
+
idleTimer = setTimeout(() => {
|
81
|
+
// console.log("idleTimer finished", lastArguments);
|
84
82
|
|
85
|
-
|
83
|
+
idleTimer = null;
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
85
|
+
if (lastArguments) {
|
86
|
+
//
|
87
|
+
// At least one call has been "debounced"
|
88
|
+
// -> make call with last arguments, so function always receives
|
89
|
+
// the arguments of the last call to the function
|
90
|
+
//
|
91
|
+
fn(...lastArguments);
|
92
|
+
lastArguments = undefined;
|
93
|
+
}
|
94
|
+
}, intervalMs);
|
97
95
|
|
98
|
-
|
99
|
-
|
96
|
+
fn(...arguments);
|
97
|
+
};
|
100
98
|
}
|
101
99
|
|
102
100
|
// -----------------------------------------------------------------------------
|
@@ -0,0 +1,120 @@
|
|
1
|
+
/**
|
2
|
+
* Returns a promise that resolves after a specified timeout
|
3
|
+
* - If the returned promise is rejected, the timeout is cancelled
|
4
|
+
*
|
5
|
+
* @param {number} delayOrMinDelayMs
|
6
|
+
* Number of milliseconds to wait before promise resolves
|
7
|
+
*
|
8
|
+
* @param {number} [maxDelayMs=delayOrMinDelayMs]
|
9
|
+
* Maximum number of milliseconds to wait before the returned promise
|
10
|
+
* resolves. If this parameter is set, the delay will be chosen randomly
|
11
|
+
* between the values [delayOrMinDelayMs, maxDelayMs]
|
12
|
+
*
|
13
|
+
* @returns {Promise} promise that resolves after a specified timeout
|
14
|
+
*/
|
15
|
+
export function delay(delayOrMinDelayMs: number, maxDelayMs?: number): Promise<any>;
|
16
|
+
/**
|
17
|
+
* Get the number of milliseconds since the specified time stamp of the default
|
18
|
+
* reference time stamp TIME_2020_01_01
|
19
|
+
*
|
20
|
+
* @param {number} [sinceMs=TIME_2020_01_01]
|
21
|
+
*
|
22
|
+
* @returns {number} number of milliseconds since the specified time
|
23
|
+
*/
|
24
|
+
export function sinceMs(sinceMs?: number): number;
|
25
|
+
/**
|
26
|
+
* Get a string that represents the time in a readable
|
27
|
+
* string format: [DD:][HH:]MM:SS.mmm
|
28
|
+
*
|
29
|
+
* @param {number} timeMs [description]
|
30
|
+
*
|
31
|
+
* @returns {string} time in human readable format
|
32
|
+
*/
|
33
|
+
export function timeToString(timeMs: number): string;
|
34
|
+
/**
|
35
|
+
* Returns a Date object
|
36
|
+
* - The input can be a Date object or a numeric timestamp
|
37
|
+
*
|
38
|
+
* @param {Date|number} dateOrTimestamp
|
39
|
+
*
|
40
|
+
* @returns {Date} date object
|
41
|
+
*/
|
42
|
+
export function toDate(dateOrTimestamp: Date | number): Date;
|
43
|
+
/**
|
44
|
+
* Get the ISO 8601 week number of the specified date
|
45
|
+
*
|
46
|
+
* @see https://stackoverflow.com
|
47
|
+
* /questions/6117814/get-week-of-year-in-javascript-like-in-php
|
48
|
+
*
|
49
|
+
* @param {Date|number} dateOrTimestamp
|
50
|
+
*
|
51
|
+
* @returns {number} week number
|
52
|
+
*/
|
53
|
+
export function getWeekNumber(dateOrTimestamp: Date | number): number;
|
54
|
+
/**
|
55
|
+
* Get the name of the month
|
56
|
+
* - Returns the English name of the month
|
57
|
+
*
|
58
|
+
* - Use the output as label in combination with the functions
|
59
|
+
* text() and translate() for international month names
|
60
|
+
*
|
61
|
+
* e.g.
|
62
|
+
*
|
63
|
+
* setTranslations()
|
64
|
+
* ...
|
65
|
+
*
|
66
|
+
* text( getMonthName( new Date() ) );
|
67
|
+
*
|
68
|
+
* --
|
69
|
+
*
|
70
|
+
* @param {Date|number} dateOrTimestamp
|
71
|
+
*
|
72
|
+
* @returns {string} name of the month (English)
|
73
|
+
*/
|
74
|
+
export function getMonthName(dateOrTimestamp: Date | number): string;
|
75
|
+
/**
|
76
|
+
* Get the name of the day
|
77
|
+
* - Returns the English name of the day
|
78
|
+
*
|
79
|
+
* - Use the output as label in combination with the functions
|
80
|
+
* text() and translate() for international day names
|
81
|
+
*
|
82
|
+
* e.g.
|
83
|
+
*
|
84
|
+
* setTranslations()
|
85
|
+
* ...
|
86
|
+
*
|
87
|
+
* text( getDayName( new Date() ) );
|
88
|
+
*
|
89
|
+
* --
|
90
|
+
*
|
91
|
+
* @param {Date|number} dateOrTimestamp
|
92
|
+
*
|
93
|
+
* @returns {string} name of the day (English)
|
94
|
+
*/
|
95
|
+
export function getDayName(dateOrTimestamp: Date | number): string;
|
96
|
+
/**
|
97
|
+
* Return the timestamp of the start of the day
|
98
|
+
* - Midnight
|
99
|
+
*
|
100
|
+
* @param {Date|number} dateOrTimestamp
|
101
|
+
*
|
102
|
+
* @returns {number} timestamp of start of the day (00:00:00:0000)
|
103
|
+
*/
|
104
|
+
export function getTimeAtStartOfDay(dateOrTimestamp: Date | number): number;
|
105
|
+
/**
|
106
|
+
* Return the timestamp of the end of the day
|
107
|
+
* - Midnight - 1 millisecond
|
108
|
+
*
|
109
|
+
* @param {Date|number} dateOrTimestamp
|
110
|
+
*
|
111
|
+
* @returns {number} timestamp of start of the day
|
112
|
+
*/
|
113
|
+
export function getTimeAtEndOfDay(dateOrTimestamp: Date | number): number;
|
114
|
+
export const SECOND_MS: 1000;
|
115
|
+
export const MINUTE_MS: number;
|
116
|
+
export const HOUR_MS: number;
|
117
|
+
export const DAY_MS: number;
|
118
|
+
export const WEEK_MS: number;
|
119
|
+
export const TIME_2020_01_01: 1577836800000;
|
120
|
+
export const TIME_2100_01_01: 4102444800000;
|
@@ -30,13 +30,22 @@
|
|
30
30
|
|
31
31
|
/* ------------------------------------------------------------------ Imports */
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
import * as expect from '../expect/index.js';
|
34
|
+
import { HkPromise } from '../../classes/promise/index.js';
|
35
35
|
|
36
36
|
/* ---------------------------------------------------------------- Internals */
|
37
37
|
|
38
38
|
/* ------------------------------------------------------------------ Exports */
|
39
39
|
|
40
|
+
export const SECOND_MS = 1000;
|
41
|
+
export const MINUTE_MS = 60 * SECOND_MS;
|
42
|
+
export const HOUR_MS = 60 * MINUTE_MS;
|
43
|
+
export const DAY_MS = 24 * HOUR_MS;
|
44
|
+
export const WEEK_MS = 7 * DAY_MS;
|
45
|
+
|
46
|
+
export const TIME_2020_01_01 = 1577836800000; // 2020-01-01T00:00:00.000Z
|
47
|
+
export const TIME_2100_01_01 = 4102444800000; // 2100-01-01T00:00:00.000Z
|
48
|
+
|
40
49
|
/**
|
41
50
|
* Returns a promise that resolves after a specified timeout
|
42
51
|
* - If the returned promise is rejected, the timeout is cancelled
|
@@ -52,37 +61,35 @@
|
|
52
61
|
* @returns {Promise} promise that resolves after a specified timeout
|
53
62
|
*/
|
54
63
|
export function delay(delayOrMinDelayMs, maxDelayMs) {
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
return promise;
|
64
|
+
expect.number(delayOrMinDelayMs);
|
65
|
+
|
66
|
+
if (maxDelayMs) {
|
67
|
+
//
|
68
|
+
// maxDelayMs was set -> generate random delay
|
69
|
+
//
|
70
|
+
if (maxDelayMs > delayOrMinDelayMs) {
|
71
|
+
delayOrMinDelayMs = Math.floor(
|
72
|
+
delayOrMinDelayMs + Math.random() * (maxDelayMs - delayOrMinDelayMs)
|
73
|
+
);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
const promise = new HkPromise();
|
78
|
+
|
79
|
+
let timer = setTimeout(() => {
|
80
|
+
timer = null;
|
81
|
+
promise.resolve();
|
82
|
+
}, delayOrMinDelayMs);
|
83
|
+
|
84
|
+
// Register catch method to cancel timer when promise is rejected
|
85
|
+
promise.catch(() => {
|
86
|
+
if (timer) {
|
87
|
+
clearTimeout(timer);
|
88
|
+
timer = null;
|
89
|
+
}
|
90
|
+
});
|
91
|
+
|
92
|
+
return promise;
|
86
93
|
}
|
87
94
|
|
88
95
|
// -----------------------------------------------------------------------------
|
@@ -96,7 +103,7 @@ export function delay(delayOrMinDelayMs, maxDelayMs) {
|
|
96
103
|
* @returns {number} number of milliseconds since the specified time
|
97
104
|
*/
|
98
105
|
export function sinceMs(sinceMs = TIME_2020_01_01) {
|
99
|
-
|
106
|
+
return Date.now() - sinceMs;
|
100
107
|
}
|
101
108
|
|
102
109
|
// -----------------------------------------------------------------------------
|
@@ -110,36 +117,36 @@ export function sinceMs(sinceMs = TIME_2020_01_01) {
|
|
110
117
|
* @returns {string} time in human readable format
|
111
118
|
*/
|
112
119
|
export function timeToString(timeMs) {
|
113
|
-
|
120
|
+
const days = Math.floor(timeMs / DAY_MS);
|
114
121
|
|
115
|
-
|
122
|
+
let restMs = timeMs - days * DAY_MS;
|
116
123
|
|
117
|
-
|
124
|
+
const hours = Math.floor(restMs / HOUR_MS);
|
118
125
|
|
119
|
-
|
126
|
+
restMs = restMs - hours * HOUR_MS;
|
120
127
|
|
121
|
-
|
128
|
+
const minutes = Math.floor(restMs / MINUTE_MS);
|
122
129
|
|
123
|
-
|
130
|
+
restMs = restMs - minutes * MINUTE_MS;
|
124
131
|
|
125
|
-
|
132
|
+
const seconds = Math.floor(restMs / SECOND_MS);
|
126
133
|
|
127
|
-
|
134
|
+
restMs = restMs - seconds * SECOND_MS;
|
128
135
|
|
129
|
-
|
136
|
+
let str = '';
|
130
137
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
138
|
+
if (days) {
|
139
|
+
str += `${days.toString().padStart(2, '0')}:`;
|
140
|
+
str += `${hours.toString().padStart(2, '0')}:`;
|
141
|
+
} else if (hours) {
|
142
|
+
str += `${hours.toString().padStart(2, '0')}:`;
|
143
|
+
}
|
137
144
|
|
138
|
-
|
139
|
-
|
140
|
-
|
145
|
+
str += `${minutes.toString().padStart(2, '0')}:`;
|
146
|
+
str += `${seconds.toString().padStart(2, '0')}.`;
|
147
|
+
str += `${restMs.toString().padEnd(3, '0')}`;
|
141
148
|
|
142
|
-
|
149
|
+
return str;
|
143
150
|
}
|
144
151
|
|
145
152
|
// -----------------------------------------------------------------------------
|
@@ -153,15 +160,15 @@ export function timeToString(timeMs) {
|
|
153
160
|
* @returns {Date} date object
|
154
161
|
*/
|
155
162
|
export function toDate(dateOrTimestamp) {
|
156
|
-
|
157
|
-
|
158
|
-
|
163
|
+
if (dateOrTimestamp instanceof Date) {
|
164
|
+
return dateOrTimestamp;
|
165
|
+
}
|
159
166
|
|
160
|
-
|
161
|
-
|
162
|
-
|
167
|
+
if (typeof dateOrTimestamp === 'number') {
|
168
|
+
return new Date(dateOrTimestamp);
|
169
|
+
}
|
163
170
|
|
164
|
-
|
171
|
+
throw new Error('Missing or invalid parameter [dateOrTimestamp]');
|
165
172
|
}
|
166
173
|
|
167
174
|
// -----------------------------------------------------------------------------
|
@@ -177,48 +184,48 @@ export function toDate(dateOrTimestamp) {
|
|
177
184
|
* @returns {number} week number
|
178
185
|
*/
|
179
186
|
export function getWeekNumber(dateOrTimestamp) {
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
187
|
+
const date = toDate(dateOrTimestamp);
|
188
|
+
|
189
|
+
//
|
190
|
+
// Create a copy of this date object
|
191
|
+
//
|
192
|
+
const target = new Date(date.valueOf());
|
193
|
+
|
194
|
+
//
|
195
|
+
// ISO week date weeks start on Monday, so correct the day number
|
196
|
+
//
|
197
|
+
const dayNumber = (date.getDay() + 6) % 7;
|
198
|
+
|
199
|
+
//
|
200
|
+
// ISO 8601 states that week 1 is the week with the first Thursday
|
201
|
+
// of that year.
|
202
|
+
//
|
203
|
+
// Set the target date to the Thursday in the target week
|
204
|
+
//
|
205
|
+
target.setDate(target.getDate() - dayNumber + 3);
|
206
|
+
|
207
|
+
//
|
208
|
+
// Store the millisecond value of the target date
|
209
|
+
//
|
210
|
+
const firstThursday = target.valueOf();
|
211
|
+
|
212
|
+
// Set the target to the first Thursday of the year
|
213
|
+
// First, set the target to January 1st
|
214
|
+
target.setMonth(0, 1);
|
215
|
+
|
216
|
+
//
|
217
|
+
// Not a Thursday? Correct the date to the next Thursday
|
218
|
+
//
|
219
|
+
if (target.getDay() !== 4) {
|
220
|
+
target.setMonth(0, 1 + ((4 - target.getDay() + 7) % 7));
|
221
|
+
}
|
222
|
+
|
223
|
+
//
|
224
|
+
// The week number is the number of weeks between the first Thursday
|
225
|
+
// of the year and the Thursday in the target week
|
226
|
+
// (604800000 = 7 * 24 * 3600 * 1000)
|
227
|
+
//
|
228
|
+
return 1 + Math.ceil((firstThursday - target) / 604800000);
|
222
229
|
}
|
223
230
|
|
224
231
|
// -----------------------------------------------------------------------------
|
@@ -244,7 +251,8 @@ export function getWeekNumber(dateOrTimestamp) {
|
|
244
251
|
* @returns {string} name of the month (English)
|
245
252
|
*/
|
246
253
|
export function getMonthName(dateOrTimestamp) {
|
247
|
-
|
254
|
+
throw new Error('Not implemented yet');
|
255
|
+
// return MONTH_NAME_LABELS_EN[toDate(dateOrTimestamp).getMonth()];
|
248
256
|
}
|
249
257
|
|
250
258
|
// -----------------------------------------------------------------------------
|
@@ -270,7 +278,8 @@ export function getMonthName(dateOrTimestamp) {
|
|
270
278
|
* @returns {string} name of the day (English)
|
271
279
|
*/
|
272
280
|
export function getDayName(dateOrTimestamp) {
|
273
|
-
|
281
|
+
throw new Error('Not implemented yet');
|
282
|
+
// return DAY_NAME_LABELS_EN[toDate(dateOrTimestamp).getDay()];
|
274
283
|
}
|
275
284
|
|
276
285
|
// -----------------------------------------------------------------------------
|
@@ -284,21 +293,21 @@ export function getDayName(dateOrTimestamp) {
|
|
284
293
|
* @returns {number} timestamp of start of the day (00:00:00:0000)
|
285
294
|
*/
|
286
295
|
export function getTimeAtStartOfDay(dateOrTimestamp) {
|
287
|
-
|
296
|
+
let d;
|
288
297
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
298
|
+
if (dateOrTimestamp) {
|
299
|
+
d = toDate(dateOrTimestamp);
|
300
|
+
} else {
|
301
|
+
// today, now
|
302
|
+
d = new Date();
|
303
|
+
}
|
295
304
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
305
|
+
d.setHours(0);
|
306
|
+
d.setMinutes(0);
|
307
|
+
d.setSeconds(0);
|
308
|
+
d.setMilliseconds(0);
|
300
309
|
|
301
|
-
|
310
|
+
return d.getTime();
|
302
311
|
}
|
303
312
|
|
304
313
|
// -----------------------------------------------------------------------------
|
@@ -312,19 +321,19 @@ export function getTimeAtStartOfDay(dateOrTimestamp) {
|
|
312
321
|
* @returns {number} timestamp of start of the day
|
313
322
|
*/
|
314
323
|
export function getTimeAtEndOfDay(dateOrTimestamp) {
|
315
|
-
|
324
|
+
let d;
|
316
325
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
326
|
+
if (dateOrTimestamp) {
|
327
|
+
d = toDate(dateOrTimestamp);
|
328
|
+
} else {
|
329
|
+
// today, now
|
330
|
+
d = new Date();
|
331
|
+
}
|
323
332
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
333
|
+
d.setHours(23);
|
334
|
+
d.setMinutes(59);
|
335
|
+
d.setSeconds(59);
|
336
|
+
d.setMilliseconds(999);
|
328
337
|
|
329
|
-
|
338
|
+
return d.getTime();
|
330
339
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hkdigital/lib-sveltekit",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.50",
|
4
4
|
"author": "Jens Kleinhout, HKdigital (https://hkdigital.nl)",
|
5
5
|
"license": "ISC",
|
6
6
|
"repository": {
|
@@ -54,6 +54,10 @@
|
|
54
54
|
"types": "./dist/classes/data/index.d.ts",
|
55
55
|
"svelte": "./dist/classes/data/index.js"
|
56
56
|
},
|
57
|
+
"./classes/promise": {
|
58
|
+
"types": "./dist/classes/promise/index.d.ts",
|
59
|
+
"svelte": "./dist/classes/promise/index.js"
|
60
|
+
},
|
57
61
|
"./classes/streams": {
|
58
62
|
"types": "./dist/classes/streams/index.d.ts",
|
59
63
|
"svelte": "./dist/classes/streams/index.js"
|
@@ -122,6 +126,10 @@
|
|
122
126
|
"types": "./dist/util/expect/index.d.ts",
|
123
127
|
"svelte": "./dist/util/expect/index.js"
|
124
128
|
},
|
129
|
+
"./util/function": {
|
130
|
+
"types": "./dist/util/function/index.d.ts",
|
131
|
+
"svelte": "./dist/util/function/index.js"
|
132
|
+
},
|
125
133
|
"./util/is": {
|
126
134
|
"types": "./dist/util/is/index.d.ts",
|
127
135
|
"svelte": "./dist/util/is/index.js"
|
@@ -146,6 +154,10 @@
|
|
146
154
|
"types": "./dist/util/svelte/index.d.ts",
|
147
155
|
"svelte": "./dist/util/svelte/index.js"
|
148
156
|
},
|
157
|
+
"./util/time": {
|
158
|
+
"types": "./dist/util/time/index.d.ts",
|
159
|
+
"svelte": "./dist/util/time/index.js"
|
160
|
+
},
|
149
161
|
"./util/svelte/observe": {
|
150
162
|
"types": "./dist/util/svelte/observe/index.d.ts",
|
151
163
|
"svelte": "./dist/util/svelte/observe/index.js"
|