@swoff/cli 0.3.5 → 0.3.7
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 +610 -24
- package/bin/swoff +8 -14
- package/dist/__tests__/assemble-sw.test.js +17 -3
- package/dist/__tests__/assemble-sw.test.js.map +1 -1
- package/dist/__tests__/cli-integration.test.js +9 -9
- package/dist/__tests__/cli-integration.test.js.map +1 -1
- package/dist/__tests__/config-types.test.js +10 -9
- package/dist/__tests__/config-types.test.js.map +1 -1
- package/dist/__tests__/file-generators.test.js +65 -68
- package/dist/__tests__/file-generators.test.js.map +1 -1
- package/dist/__tests__/loader.test.js +12 -14
- package/dist/__tests__/loader.test.js.map +1 -1
- package/dist/__tests__/validator.test.js +41 -22
- package/dist/__tests__/validator.test.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/cli/help.js +3 -3
- package/dist/lib/cli/help.js.map +1 -1
- package/dist/lib/commands/add.js +11 -5
- package/dist/lib/commands/add.js.map +1 -1
- package/dist/lib/commands/clean.js +5 -0
- package/dist/lib/commands/clean.js.map +1 -1
- package/dist/lib/commands/generate-guide.js +43 -13
- package/dist/lib/commands/generate-guide.js.map +1 -1
- package/dist/lib/commands/generate.js +7 -3
- package/dist/lib/commands/generate.js.map +1 -1
- package/dist/lib/commands/info.js +149 -32
- package/dist/lib/commands/info.js.map +1 -1
- package/dist/lib/commands/init.js +6 -2
- package/dist/lib/commands/init.js.map +1 -1
- package/dist/lib/commands/validate.js +3 -1
- package/dist/lib/commands/validate.js.map +1 -1
- package/dist/lib/config/validator.js +25 -16
- package/dist/lib/config/validator.js.map +1 -1
- package/dist/lib/generators/file-generators/auth-fetch.js +29 -34
- package/dist/lib/generators/file-generators/auth-fetch.js.map +1 -1
- package/dist/lib/generators/file-generators/auth-state.js +8 -5
- package/dist/lib/generators/file-generators/auth-state.js.map +1 -1
- package/dist/lib/generators/file-generators/auth-store.js +181 -41
- package/dist/lib/generators/file-generators/auth-store.js.map +1 -1
- package/dist/lib/generators/file-generators/auth-user.js +28 -32
- package/dist/lib/generators/file-generators/auth-user.js.map +1 -1
- package/dist/lib/generators/file-generators/background-sync.js +9 -5
- package/dist/lib/generators/file-generators/background-sync.js.map +1 -1
- package/dist/lib/generators/file-generators/cache.js +8 -5
- package/dist/lib/generators/file-generators/cache.js.map +1 -1
- package/dist/lib/generators/file-generators/client-injector.js +101 -0
- package/dist/lib/generators/file-generators/client-injector.js.map +1 -0
- package/dist/lib/generators/file-generators/context.js +7 -6
- package/dist/lib/generators/file-generators/context.js.map +1 -1
- package/dist/lib/generators/file-generators/fetch-wrapper.js +196 -41
- package/dist/lib/generators/file-generators/fetch-wrapper.js.map +1 -1
- package/dist/lib/generators/file-generators/generate-hooks.js +23 -151
- package/dist/lib/generators/file-generators/generate-hooks.js.map +1 -1
- package/dist/lib/generators/file-generators/guide-generator.js +450 -0
- package/dist/lib/generators/file-generators/guide-generator.js.map +1 -0
- package/dist/lib/generators/file-generators/invalidation-tags.js +12 -10
- package/dist/lib/generators/file-generators/invalidation-tags.js.map +1 -1
- package/dist/lib/generators/file-generators/mutation-queue.js +65 -87
- package/dist/lib/generators/file-generators/mutation-queue.js.map +1 -1
- package/dist/lib/generators/file-generators/mutation-reconcile.js +57 -0
- package/dist/lib/generators/file-generators/mutation-reconcile.js.map +1 -0
- package/dist/lib/generators/file-generators/push.js +143 -0
- package/dist/lib/generators/file-generators/push.js.map +1 -0
- package/dist/lib/generators/file-generators/pwa-install.js +41 -9
- package/dist/lib/generators/file-generators/pwa-install.js.map +1 -1
- package/dist/lib/generators/file-generators/quick-readme.js +88 -0
- package/dist/lib/generators/file-generators/quick-readme.js.map +1 -0
- package/dist/lib/generators/file-generators/reconcile.js +7 -12
- package/dist/lib/generators/file-generators/reconcile.js.map +1 -1
- package/dist/lib/generators/file-generators/store.js +30 -20
- package/dist/lib/generators/file-generators/store.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-generator-build.js +38 -17
- package/dist/lib/generators/file-generators/sw-generator-build.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-injector.js +82 -111
- package/dist/lib/generators/file-generators/sw-injector.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-push.js +67 -0
- package/dist/lib/generators/file-generators/sw-push.js.map +1 -0
- package/dist/lib/generators/file-generators/sw-template.js +3 -1
- package/dist/lib/generators/file-generators/sw-template.js.map +1 -1
- package/dist/lib/generators/file-generators/type-definitions.js +45 -22
- package/dist/lib/generators/file-generators/type-definitions.js.map +1 -1
- package/dist/lib/generators/sw-generator.js +27 -19
- package/dist/lib/generators/sw-generator.js.map +1 -1
- package/dist/lib/generators/sw-sections/activate-handler.js +6 -2
- package/dist/lib/generators/sw-sections/activate-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/assemble-sw.js +36 -12
- package/dist/lib/generators/sw-sections/assemble-sw.js.map +1 -1
- package/dist/lib/generators/sw-sections/config-header.js +1 -1
- package/dist/lib/generators/sw-sections/config-header.js.map +1 -1
- package/dist/lib/generators/sw-sections/default-template.js +1 -30
- package/dist/lib/generators/sw-sections/default-template.js.map +1 -1
- package/dist/lib/generators/sw-sections/fetch-handler.js +176 -90
- package/dist/lib/generators/sw-sections/fetch-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/install-handler.js +12 -10
- package/dist/lib/generators/sw-sections/install-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/tag-management.js +36 -5
- package/dist/lib/generators/sw-sections/tag-management.js.map +1 -1
- package/dist/lib/generators/swoff-files-generator.js +14 -12
- package/dist/lib/generators/swoff-files-generator.js.map +1 -1
- package/dist/lib/shared/config-types.js +26 -9
- package/dist/lib/shared/config-types.js.map +1 -1
- package/dist/lib/utils/build-script.js +35 -0
- package/dist/lib/utils/build-script.js.map +1 -0
- package/package.json +3 -2
- package/templates/hooks/useAuth.jsx +30 -0
- package/templates/hooks/useAuth.tsx +30 -0
- package/templates/hooks/useBackgroundSync.jsx +31 -0
- package/templates/hooks/useBackgroundSync.tsx +31 -0
- package/templates/hooks/useCacheInvalidation.jsx +19 -0
- package/templates/hooks/useCacheInvalidation.tsx +19 -0
- package/templates/hooks/useCachedFetch.jsx +55 -0
- package/templates/hooks/useCachedFetch.tsx +69 -0
- package/templates/hooks/useMutationQueue.jsx +34 -0
- package/templates/hooks/useMutationQueue.tsx +34 -0
- package/templates/hooks/useNetworkStatus.jsx +19 -0
- package/templates/hooks/useNetworkStatus.tsx +19 -0
- package/templates/hooks/usePushSubscription.jsx +67 -0
- package/templates/hooks/usePushSubscription.tsx +67 -0
- package/templates/hooks/useSWUpdate.jsx +76 -0
- package/templates/hooks/useSWUpdate.tsx +76 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import {
|
|
3
|
+
subscribeToPush,
|
|
4
|
+
unsubscribeFromPush,
|
|
5
|
+
isSubscribed,
|
|
6
|
+
getPushSubscription,
|
|
7
|
+
} from "../push.ts";
|
|
8
|
+
|
|
9
|
+
export function usePushSubscription(vapidPublicKey: string) {
|
|
10
|
+
const [state, setState] = useState({
|
|
11
|
+
subscribed: false,
|
|
12
|
+
subscription: null as PushSubscription | null,
|
|
13
|
+
permission: Notification.permission,
|
|
14
|
+
loading: true,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
let cancelled = false;
|
|
19
|
+
|
|
20
|
+
isSubscribed().then((subscribed) => {
|
|
21
|
+
if (cancelled) return;
|
|
22
|
+
if (subscribed) {
|
|
23
|
+
getPushSubscription().then((sub) => {
|
|
24
|
+
if (cancelled) return;
|
|
25
|
+
setState({ subscribed: true, subscription: sub, permission: Notification.permission, loading: false });
|
|
26
|
+
});
|
|
27
|
+
} else {
|
|
28
|
+
setState({ subscribed: false, subscription: null, permission: Notification.permission, loading: false });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const onSubChanged = (e: CustomEvent) => {
|
|
33
|
+
if (cancelled) return;
|
|
34
|
+
if (!e.detail.subscribed) {
|
|
35
|
+
setState({ subscribed: false, subscription: null, permission: Notification.permission, loading: false });
|
|
36
|
+
} else {
|
|
37
|
+
getPushSubscription().then((sub) => {
|
|
38
|
+
if (cancelled) return;
|
|
39
|
+
setState({ subscribed: true, subscription: sub, permission: Notification.permission, loading: false });
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const onPermissionChanged = (e: CustomEvent) => {
|
|
44
|
+
if (cancelled) return;
|
|
45
|
+
setState((s) => ({ ...s, permission: e.detail.permission }));
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
window.addEventListener("push-subscription-changed", onSubChanged);
|
|
49
|
+
window.addEventListener("push-permission-changed", onPermissionChanged);
|
|
50
|
+
return () => {
|
|
51
|
+
cancelled = true;
|
|
52
|
+
window.removeEventListener("push-subscription-changed", onSubChanged);
|
|
53
|
+
window.removeEventListener("push-permission-changed", onPermissionChanged);
|
|
54
|
+
};
|
|
55
|
+
}, []);
|
|
56
|
+
|
|
57
|
+
const subscribe = useCallback(async () => {
|
|
58
|
+
const sub = await subscribeToPush(vapidPublicKey);
|
|
59
|
+
return sub !== null;
|
|
60
|
+
}, [vapidPublicKey]);
|
|
61
|
+
|
|
62
|
+
const unsubscribe = useCallback(async () => {
|
|
63
|
+
await unsubscribeFromPush();
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
66
|
+
return { ...state, subscribe, unsubscribe };
|
|
67
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { handleUpdateApproved } from "../sw/injector.js";
|
|
3
|
+
|
|
4
|
+
export function useSWUpdate() {
|
|
5
|
+
const [state, setState] = useState({
|
|
6
|
+
updateStatus: "idle",
|
|
7
|
+
currentVersion: window.currentSWVersion || null,
|
|
8
|
+
availableVersion: null,
|
|
9
|
+
progress: 0,
|
|
10
|
+
forceUpdate: false,
|
|
11
|
+
error: null,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (sessionStorage.getItem("sw-dismissed-update") === "true") return;
|
|
16
|
+
|
|
17
|
+
const onAvailable = (e) =>
|
|
18
|
+
setState((s) => ({
|
|
19
|
+
...s,
|
|
20
|
+
updateStatus: "available",
|
|
21
|
+
availableVersion: e.detail.version,
|
|
22
|
+
forceUpdate: window.swUpdateRequired || false,
|
|
23
|
+
}));
|
|
24
|
+
const onProgress = (e) =>
|
|
25
|
+
setState((s) => ({ ...s, updateStatus: "downloading", progress: e.detail.percent }));
|
|
26
|
+
const onReady = () =>
|
|
27
|
+
setState((s) => ({ ...s, updateStatus: "idle", progress: 0 }));
|
|
28
|
+
const onError = () =>
|
|
29
|
+
setState((s) => ({ ...s, error: "SW registration failed" }));
|
|
30
|
+
|
|
31
|
+
window.addEventListener("sw-update-available", onAvailable);
|
|
32
|
+
window.addEventListener("sw-progress", onProgress);
|
|
33
|
+
window.addEventListener("sw-ready", onReady);
|
|
34
|
+
window.addEventListener("sw-error", onError);
|
|
35
|
+
return () => {
|
|
36
|
+
window.removeEventListener("sw-update-available", onAvailable);
|
|
37
|
+
window.removeEventListener("sw-progress", onProgress);
|
|
38
|
+
window.removeEventListener("sw-ready", onReady);
|
|
39
|
+
window.removeEventListener("sw-error", onError);
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const acceptUpdate = useCallback(async () => {
|
|
44
|
+
if (!state.availableVersion) return;
|
|
45
|
+
await handleUpdateApproved(state.availableVersion);
|
|
46
|
+
}, [state.availableVersion]);
|
|
47
|
+
|
|
48
|
+
const dismissUpdate = useCallback(() => {
|
|
49
|
+
sessionStorage.setItem("sw-dismissed-update", "true");
|
|
50
|
+
setState((s) => ({ ...s, updateStatus: "idle" }));
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
return { ...state, acceptUpdate, dismissUpdate };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function useSWProgress() {
|
|
57
|
+
const [state, setState] = useState({
|
|
58
|
+
status: "idle",
|
|
59
|
+
progress: 0,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const onProgress = (e) =>
|
|
64
|
+
setState({ status: "installing", progress: e.detail.percent });
|
|
65
|
+
const onReady = () => setState({ status: "idle", progress: 0 });
|
|
66
|
+
|
|
67
|
+
window.addEventListener("sw-progress", onProgress);
|
|
68
|
+
window.addEventListener("sw-ready", onReady);
|
|
69
|
+
return () => {
|
|
70
|
+
window.removeEventListener("sw-progress", onProgress);
|
|
71
|
+
window.removeEventListener("sw-ready", onReady);
|
|
72
|
+
};
|
|
73
|
+
}, []);
|
|
74
|
+
|
|
75
|
+
return state;
|
|
76
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { handleUpdateApproved } from "../sw/injector.ts";
|
|
3
|
+
|
|
4
|
+
export function useSWUpdate() {
|
|
5
|
+
const [state, setState] = useState({
|
|
6
|
+
updateStatus: "idle" as "idle" | "available" | "downloading" | "ready",
|
|
7
|
+
currentVersion: (window.currentSWVersion as string | undefined) || null,
|
|
8
|
+
availableVersion: null as string | null,
|
|
9
|
+
progress: 0 as number,
|
|
10
|
+
forceUpdate: false,
|
|
11
|
+
error: null as string | null,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (sessionStorage.getItem("sw-dismissed-update") === "true") return;
|
|
16
|
+
|
|
17
|
+
const onAvailable = (e: WindowEventMap["sw-update-available"]) =>
|
|
18
|
+
setState((s) => ({
|
|
19
|
+
...s,
|
|
20
|
+
updateStatus: "available",
|
|
21
|
+
availableVersion: e.detail.version,
|
|
22
|
+
forceUpdate: window.swUpdateRequired || false,
|
|
23
|
+
}));
|
|
24
|
+
const onProgress = (e: WindowEventMap["sw-progress"]) =>
|
|
25
|
+
setState((s) => ({ ...s, updateStatus: "downloading", progress: e.detail.percent }));
|
|
26
|
+
const onReady = () =>
|
|
27
|
+
setState((s) => ({ ...s, updateStatus: "idle", progress: 0 }));
|
|
28
|
+
const onError = () =>
|
|
29
|
+
setState((s) => ({ ...s, error: "SW registration failed" }));
|
|
30
|
+
|
|
31
|
+
window.addEventListener("sw-update-available", onAvailable);
|
|
32
|
+
window.addEventListener("sw-progress", onProgress);
|
|
33
|
+
window.addEventListener("sw-ready", onReady);
|
|
34
|
+
window.addEventListener("sw-error", onError);
|
|
35
|
+
return () => {
|
|
36
|
+
window.removeEventListener("sw-update-available", onAvailable);
|
|
37
|
+
window.removeEventListener("sw-progress", onProgress);
|
|
38
|
+
window.removeEventListener("sw-ready", onReady);
|
|
39
|
+
window.removeEventListener("sw-error", onError);
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const acceptUpdate = useCallback(async () => {
|
|
44
|
+
if (!state.availableVersion) return;
|
|
45
|
+
await handleUpdateApproved(state.availableVersion);
|
|
46
|
+
}, [state.availableVersion]);
|
|
47
|
+
|
|
48
|
+
const dismissUpdate = useCallback(() => {
|
|
49
|
+
sessionStorage.setItem("sw-dismissed-update", "true");
|
|
50
|
+
setState((s) => ({ ...s, updateStatus: "idle" }));
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
return { ...state, acceptUpdate, dismissUpdate };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function useSWProgress() {
|
|
57
|
+
const [state, setState] = useState({
|
|
58
|
+
status: "idle" as "idle" | "installing",
|
|
59
|
+
progress: 0 as number,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const onProgress = (e: WindowEventMap["sw-progress"]) =>
|
|
64
|
+
setState({ status: "installing", progress: e.detail.percent });
|
|
65
|
+
const onReady = () => setState({ status: "idle", progress: 0 });
|
|
66
|
+
|
|
67
|
+
window.addEventListener("sw-progress", onProgress);
|
|
68
|
+
window.addEventListener("sw-ready", onReady);
|
|
69
|
+
return () => {
|
|
70
|
+
window.removeEventListener("sw-progress", onProgress);
|
|
71
|
+
window.removeEventListener("sw-ready", onReady);
|
|
72
|
+
};
|
|
73
|
+
}, []);
|
|
74
|
+
|
|
75
|
+
return state;
|
|
76
|
+
}
|