@thepassle/app-tools 0.0.10 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/api/index.js +31 -9
- package/api/plugins/abort.js +1 -0
- package/api/plugins/cache.js +4 -3
- package/api/plugins/debounce.js +37 -0
- package/api/plugins/delay.js +4 -1
- package/api/plugins/jsonPrefix.js +1 -0
- package/api/plugins/logger.js +1 -0
- package/api/plugins/mock.js +2 -14
- package/api/plugins/xsrf.js +29 -0
- package/dialog/dialog.test.js +66 -0
- package/dialog/events.js +14 -0
- package/dialog/index.js +184 -0
- package/dialog/utils.js +40 -0
- package/dialog.js +1 -0
- package/package.json +19 -16
- package/pwa/capabilities.js +7 -0
- package/pwa/events.js +33 -0
- package/pwa/index.js +174 -0
- package/pwa.js +2 -0
- package/router/index.js +221 -0
- package/router/plugins/appName.js +12 -0
- package/router/plugins/checkServiceWorkerUpdate.js +15 -0
- package/router/plugins/data.js +13 -0
- package/router/plugins/lazy.js +13 -0
- package/router/plugins/offline.js +16 -0
- package/router/plugins/redirect.js +13 -0
- package/router/plugins/resetFocus.js +31 -0
- package/router/plugins/scrollToTop.js +9 -0
- package/router.js +1 -0
- package/state/index.js +6 -1
- package/utils/CONSTANTS.js +1 -0
- package/utils/Service.js +83 -0
- package/utils/async.js +81 -0
- package/utils/log.js +44 -0
- package/utils/media.js +47 -0
- package/utils.js +3 -0
package/utils/async.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {Function} f
|
|
3
|
+
* @returns {<Args>(...args: Args[]) => void}
|
|
4
|
+
*/
|
|
5
|
+
export function debounce(f) {
|
|
6
|
+
let timeoutId;
|
|
7
|
+
|
|
8
|
+
return (...args) => {
|
|
9
|
+
clearTimeout(timeoutId);
|
|
10
|
+
timeoutId = setTimeout(() => {
|
|
11
|
+
timeoutId = null;
|
|
12
|
+
f(...args);
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @returns {Promise<number>}
|
|
19
|
+
*/
|
|
20
|
+
export const onePaint = () => new Promise(r => requestAnimationFrame(r));
|
|
21
|
+
/**
|
|
22
|
+
* @param {HTMLElement} element
|
|
23
|
+
* @returns {Promise<PromiseSettledResult<Animation>[]>}
|
|
24
|
+
*/
|
|
25
|
+
export const animationsComplete = element => Promise.allSettled(element.getAnimations().map(animation => animation.finished));
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {() => void} f
|
|
29
|
+
* @param {number} ms
|
|
30
|
+
* @param {{
|
|
31
|
+
* signal?: AbortSignal
|
|
32
|
+
* }} options
|
|
33
|
+
*/
|
|
34
|
+
export function setAbortableTimeout(f, ms, {signal}) {
|
|
35
|
+
let t;
|
|
36
|
+
if(!signal?.aborted) {
|
|
37
|
+
t = setTimeout(f, ms);
|
|
38
|
+
}
|
|
39
|
+
signal?.addEventListener('abort', () => clearTimeout(t), {once: true});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {() => boolean} predicate
|
|
44
|
+
* @param {{
|
|
45
|
+
* timeout?: number,
|
|
46
|
+
* message?: string,
|
|
47
|
+
* interval?: number
|
|
48
|
+
* }} options
|
|
49
|
+
* @returns {Promise<void>}
|
|
50
|
+
*/
|
|
51
|
+
export function waitUntil(predicate, options = {}) {
|
|
52
|
+
const {
|
|
53
|
+
timeout = 1000,
|
|
54
|
+
message = `waitUntil timed out after ${timeout}ms`,
|
|
55
|
+
interval = 50,
|
|
56
|
+
} = options;
|
|
57
|
+
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
let timeoutId;
|
|
60
|
+
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
reject(new Error(message));
|
|
64
|
+
}, timeout);
|
|
65
|
+
|
|
66
|
+
async function nextInterval() {
|
|
67
|
+
try {
|
|
68
|
+
if (await predicate()) {
|
|
69
|
+
resolve();
|
|
70
|
+
} else {
|
|
71
|
+
timeoutId = setTimeout(() => {
|
|
72
|
+
nextInterval();
|
|
73
|
+
}, interval);
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
reject(error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
nextInterval();
|
|
80
|
+
});
|
|
81
|
+
}
|
package/utils/log.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const KEY = Symbol.for('app-tools::log::1.x');
|
|
2
|
+
|
|
3
|
+
globalThis[KEY] = {
|
|
4
|
+
setDebug,
|
|
5
|
+
debug: new URL(window.location.href).searchParams.has('app-tools-debug')
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {boolean} value
|
|
10
|
+
*/
|
|
11
|
+
export function setDebug(value) {
|
|
12
|
+
globalThis[KEY].debug = !!value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
18
|
+
export function getDebug() {
|
|
19
|
+
return globalThis[KEY].debug;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} action - describing the action
|
|
24
|
+
* @param {*} [data] - any js value
|
|
25
|
+
*/
|
|
26
|
+
export function log(action, data) {
|
|
27
|
+
if(globalThis[KEY].debug) {
|
|
28
|
+
console.groupCollapsed(`[app-tools] ${action}`);
|
|
29
|
+
if(data) {
|
|
30
|
+
console.log(data);
|
|
31
|
+
}
|
|
32
|
+
console.groupEnd();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {string} title
|
|
38
|
+
* @returns {(action: string, data?: any) => void}
|
|
39
|
+
*/
|
|
40
|
+
export function createLogger(title) {
|
|
41
|
+
return (action, data) => {
|
|
42
|
+
log(`${title}: ${action}`, data);
|
|
43
|
+
}
|
|
44
|
+
}
|
package/utils/media.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const media = {
|
|
2
|
+
MIN: {
|
|
3
|
+
XXXL: createMatch('(min-width: 1440px)'),
|
|
4
|
+
XXL: createMatch('(min-width: 1280px)'),
|
|
5
|
+
XL: createMatch('(min-width: 960px)'),
|
|
6
|
+
LG: createMatch('(min-width: 840px)'),
|
|
7
|
+
MD: createMatch('(min-width: 600px)'),
|
|
8
|
+
SM: createMatch('(min-width: 480px)'),
|
|
9
|
+
XS: createMatch('(min-width: 320px)'),
|
|
10
|
+
XXS: createMatch('(min-width: 0px)'),
|
|
11
|
+
XXXS: createMatch('(min-width: 0px)'),
|
|
12
|
+
},
|
|
13
|
+
MAX: {
|
|
14
|
+
XXXL: createMatch('(max-width: 1600px)'),
|
|
15
|
+
XXL: createMatch('(max-width: 1440px)'),
|
|
16
|
+
XL: createMatch('(max-width: 1280px)'),
|
|
17
|
+
LG: createMatch('(max-width: 960px)'),
|
|
18
|
+
MD: createMatch('(max-width: 840px)'),
|
|
19
|
+
SM: createMatch('(max-width: 600px)'),
|
|
20
|
+
XS: createMatch('(max-width: 480px)'),
|
|
21
|
+
XXS: createMatch('(max-width: 320px)'),
|
|
22
|
+
XXXS: createMatch('(max-width: 0px)'),
|
|
23
|
+
},
|
|
24
|
+
STANDALONE: createMatch('(display-mode: standalone)'),
|
|
25
|
+
REDUCED_MOTION: createMatch('(prefers-reduced-motion: reduce)'),
|
|
26
|
+
DARK_MODE: createMatch('(prefers-color-scheme: dark)'),
|
|
27
|
+
LIGHT_MODE: createMatch('(prefers-color-scheme: light)'),
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function createMatch(query) {
|
|
31
|
+
return function match(callback) {
|
|
32
|
+
const mediaQuery = window.matchMedia(query);
|
|
33
|
+
|
|
34
|
+
if(callback) {
|
|
35
|
+
function executeCb({matches}) {
|
|
36
|
+
callback?.(matches);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
mediaQuery.addListener(executeCb);
|
|
40
|
+
callback(mediaQuery.matches);
|
|
41
|
+
return () => {
|
|
42
|
+
mediaQuery.removeListener(executeCb);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return mediaQuery.matches;
|
|
46
|
+
}
|
|
47
|
+
}
|
package/utils.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
+
export { waitUntil, debounce, setAbortableTimeout } from './utils/async.js';
|
|
2
|
+
export { media } from './utils/media.js';
|
|
1
3
|
export { when } from './utils/index.js';
|
|
4
|
+
export { log, setDebug, getDebug } from './utils/log.js';
|
|
2
5
|
export { createService } from './utils/Service.js';
|