@hkdigital/lib-sveltekit 0.0.48 → 0.0.51
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.
@@ -18,3 +18,17 @@ export function once(callback: Function): Function;
|
|
18
18
|
*/
|
19
19
|
export function debounce(fn: Function, intervalMs?: number): Function;
|
20
20
|
export function noop(): void;
|
21
|
+
/**
|
22
|
+
* Defer the execution of a function
|
23
|
+
* - Uses the best 'setImmediate' implementation supported by the current
|
24
|
+
* runtime environment
|
25
|
+
*
|
26
|
+
* @param {function} fn - Function to execute
|
27
|
+
*
|
28
|
+
* --
|
29
|
+
*
|
30
|
+
* @note setImmediate is preferred over nextTick
|
31
|
+
*
|
32
|
+
* @see https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
|
33
|
+
*/
|
34
|
+
export const defer: any;
|
@@ -12,12 +12,65 @@
|
|
12
12
|
*
|
13
13
|
* sayHelloOnce();
|
14
14
|
* sayHelloOnce();
|
15
|
+
*
|
16
|
+
* @example
|
17
|
+
*
|
18
|
+
* import { defer } from './process.js';
|
19
|
+
*
|
20
|
+
* defer( () => {
|
21
|
+
* console.log("The execution of the function has been defered");
|
22
|
+
* } );
|
15
23
|
*/
|
16
24
|
|
17
25
|
/* ------------------------------------------------------------------ Imports */
|
18
26
|
|
19
27
|
import * as expect from '../expect/index.js';
|
20
28
|
|
29
|
+
/* ---------------------------------------------------------------- Internals */
|
30
|
+
|
31
|
+
const NEXT_TICK_MESSAGE = 'hk-next-tick';
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Detect and return the most suitable setImmediate implementation available
|
35
|
+
* on the current platform
|
36
|
+
*/
|
37
|
+
function set_immediate_implementation() {
|
38
|
+
if (typeof global !== 'undefined') {
|
39
|
+
if (undefined !== global.setImmediate) {
|
40
|
+
return global.setImmediate;
|
41
|
+
}
|
42
|
+
} else if (typeof window !== 'undefined') {
|
43
|
+
if (window.postMessage && window.addEventListener) {
|
44
|
+
const queue = [];
|
45
|
+
|
46
|
+
window.addEventListener(
|
47
|
+
'message',
|
48
|
+
(event) => {
|
49
|
+
const source = event.source;
|
50
|
+
|
51
|
+
if ((source === window || source === null) && event.data === NEXT_TICK_MESSAGE) {
|
52
|
+
event.stopPropagation();
|
53
|
+
if (queue.length > 0) {
|
54
|
+
const fn = queue.shift();
|
55
|
+
fn();
|
56
|
+
}
|
57
|
+
}
|
58
|
+
},
|
59
|
+
true
|
60
|
+
);
|
61
|
+
|
62
|
+
return function nextTickUsingPostMessage(fn) {
|
63
|
+
expect.function(fn);
|
64
|
+
|
65
|
+
queue.push(fn);
|
66
|
+
window.postMessage(NEXT_TICK_MESSAGE, '*');
|
67
|
+
};
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
throw new Error('No suitable [setImmediate] implementation available');
|
72
|
+
}
|
73
|
+
|
21
74
|
/* ------------------------------------------------------------------ Exports */
|
22
75
|
|
23
76
|
/**
|
@@ -99,6 +152,23 @@ export function debounce(fn, intervalMs = 200) {
|
|
99
152
|
|
100
153
|
// -----------------------------------------------------------------------------
|
101
154
|
|
155
|
+
/**
|
156
|
+
* Defer the execution of a function
|
157
|
+
* - Uses the best 'setImmediate' implementation supported by the current
|
158
|
+
* runtime environment
|
159
|
+
*
|
160
|
+
* @param {function} fn - Function to execute
|
161
|
+
*
|
162
|
+
* --
|
163
|
+
*
|
164
|
+
* @note setImmediate is preferred over nextTick
|
165
|
+
*
|
166
|
+
* @see https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
|
167
|
+
*/
|
168
|
+
export const defer = set_immediate_implementation();
|
169
|
+
|
170
|
+
// -----------------------------------------------------------------------------
|
171
|
+
|
102
172
|
/**
|
103
173
|
* Adds a wrapper around a function that only calls the supplied function
|
104
174
|
* if the (first) supplied argument to the returned function is not `null`
|
@@ -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.51",
|
4
4
|
"author": "Jens Kleinhout, HKdigital (https://hkdigital.nl)",
|
5
5
|
"license": "ISC",
|
6
6
|
"repository": {
|
@@ -154,6 +154,10 @@
|
|
154
154
|
"types": "./dist/util/svelte/index.d.ts",
|
155
155
|
"svelte": "./dist/util/svelte/index.js"
|
156
156
|
},
|
157
|
+
"./util/time": {
|
158
|
+
"types": "./dist/util/time/index.d.ts",
|
159
|
+
"svelte": "./dist/util/time/index.js"
|
160
|
+
},
|
157
161
|
"./util/svelte/observe": {
|
158
162
|
"types": "./dist/util/svelte/observe/index.d.ts",
|
159
163
|
"svelte": "./dist/util/svelte/observe/index.js"
|