@swoff/cli 0.3.14 → 0.4.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.
Files changed (147) hide show
  1. package/dist/index.js +2 -2
  2. package/dist/index.js.map +1 -1
  3. package/dist/lib/cli/help.js +3 -3
  4. package/dist/lib/cli/help.js.map +1 -1
  5. package/dist/lib/commands/clean.js +8 -17
  6. package/dist/lib/commands/clean.js.map +1 -1
  7. package/dist/lib/commands/generate-guide.js +3 -5
  8. package/dist/lib/commands/generate-guide.js.map +1 -1
  9. package/dist/lib/commands/generate.js +9 -7
  10. package/dist/lib/commands/generate.js.map +1 -1
  11. package/dist/lib/commands/init.js +218 -184
  12. package/dist/lib/commands/init.js.map +1 -1
  13. package/dist/lib/commands/validate.js.map +1 -1
  14. package/dist/lib/config/minimal-config.js +64 -0
  15. package/dist/lib/config/minimal-config.js.map +1 -0
  16. package/dist/lib/config/validator.js +42 -19
  17. package/dist/lib/config/validator.js.map +1 -1
  18. package/dist/lib/generators/file-generators/client-injector-bundle.js +1 -1
  19. package/dist/lib/generators/file-generators/client-injector-bundle.js.map +1 -1
  20. package/dist/lib/generators/file-generators/context.js +3 -2
  21. package/dist/lib/generators/file-generators/context.js.map +1 -1
  22. package/dist/lib/generators/file-generators/generate-framework-adapters.js +1 -1
  23. package/dist/lib/generators/file-generators/generate-framework-adapters.js.map +1 -1
  24. package/dist/lib/generators/file-generators/sw-generator-build.js +34 -14
  25. package/dist/lib/generators/file-generators/sw-generator-build.js.map +1 -1
  26. package/dist/lib/generators/file-generators/sw-injector.js +1 -0
  27. package/dist/lib/generators/file-generators/sw-injector.js.map +1 -1
  28. package/dist/lib/generators/sw-build-utils.js +17 -3
  29. package/dist/lib/generators/sw-build-utils.js.map +1 -1
  30. package/dist/lib/generators/sw-generator.js +5 -5
  31. package/dist/lib/generators/sw-generator.js.map +1 -1
  32. package/dist/lib/generators/sw-sections/activate-handler.js +4 -1
  33. package/dist/lib/generators/sw-sections/activate-handler.js.map +1 -1
  34. package/dist/lib/generators/sw-sections/assemble-sw.js +7 -4
  35. package/dist/lib/generators/sw-sections/assemble-sw.js.map +1 -1
  36. package/dist/lib/generators/sw-sections/background-precache.js +118 -0
  37. package/dist/lib/generators/sw-sections/background-precache.js.map +1 -0
  38. package/dist/lib/generators/sw-sections/default-template.js +11 -3
  39. package/dist/lib/generators/sw-sections/default-template.js.map +1 -1
  40. package/dist/lib/generators/sw-sections/fetch-handler.js +2 -2
  41. package/dist/lib/generators/sw-sections/fetch-handler.js.map +1 -1
  42. package/dist/lib/generators/sw-sections/message-handler.js +9 -1
  43. package/dist/lib/generators/sw-sections/message-handler.js.map +1 -1
  44. package/dist/lib/generators/sw-sections/shared.js +2 -2
  45. package/dist/lib/generators/sw-sections/shared.js.map +1 -1
  46. package/dist/lib/generators/swoff-files-generator.js +2 -2
  47. package/dist/lib/generators/swoff-files-generator.js.map +1 -1
  48. package/dist/lib/shared/config-types.js +20 -18
  49. package/dist/lib/shared/config-types.js.map +1 -1
  50. package/dist/lib/utils/detect-framework.js +3 -27
  51. package/dist/lib/utils/detect-framework.js.map +1 -1
  52. package/dist/runtime/client-injector-bundle.js +16 -23
  53. package/dist/runtime/client-injector-bundle.js.map +1 -1
  54. package/dist/runtime/client-injector.js +15 -2
  55. package/dist/runtime/client-injector.js.map +1 -1
  56. package/dist/runtime/sw-injector.js +6 -19
  57. package/dist/runtime/sw-injector.js.map +1 -1
  58. package/dist/runtime/type-definitions.js +0 -5
  59. package/dist/runtime/type-definitions.js.map +1 -1
  60. package/package.json +9 -3
  61. package/templates/react/usePrecacheProgress.jsx +20 -0
  62. package/templates/react/usePrecacheProgress.tsx +20 -0
  63. package/dist/lib/commands/add.js +0 -62
  64. package/dist/lib/commands/add.js.map +0 -1
  65. package/dist/lib/commands/assets.js +0 -45
  66. package/dist/lib/commands/assets.js.map +0 -1
  67. package/dist/lib/commands/generate-assets.js +0 -44
  68. package/dist/lib/commands/generate-assets.js.map +0 -1
  69. package/dist/lib/commands/info.js +0 -183
  70. package/dist/lib/commands/info.js.map +0 -1
  71. package/dist/lib/generators/asset-generator/dependency-resolver.js +0 -85
  72. package/dist/lib/generators/asset-generator/dependency-resolver.js.map +0 -1
  73. package/dist/lib/generators/asset-generator/generate.js +0 -111
  74. package/dist/lib/generators/asset-generator/generate.js.map +0 -1
  75. package/dist/lib/generators/asset-generator/guide.js +0 -43
  76. package/dist/lib/generators/asset-generator/guide.js.map +0 -1
  77. package/dist/lib/generators/asset-generator/html-patcher.js +0 -65
  78. package/dist/lib/generators/asset-generator/html-patcher.js.map +0 -1
  79. package/dist/lib/generators/asset-generator/ico-encoder.js +0 -29
  80. package/dist/lib/generators/asset-generator/ico-encoder.js.map +0 -1
  81. package/dist/lib/generators/asset-generator/manifest-patcher.js +0 -23
  82. package/dist/lib/generators/asset-generator/manifest-patcher.js.map +0 -1
  83. package/dist/lib/generators/asset-generator/maskable.js +0 -15
  84. package/dist/lib/generators/asset-generator/maskable.js.map +0 -1
  85. package/dist/lib/generators/asset-generator/rasterize.js +0 -32
  86. package/dist/lib/generators/asset-generator/rasterize.js.map +0 -1
  87. package/dist/lib/generators/asset-generator/sizes.js +0 -25
  88. package/dist/lib/generators/asset-generator/sizes.js.map +0 -1
  89. package/dist/lib/generators/file-generators/auth-fetch.js +0 -151
  90. package/dist/lib/generators/file-generators/auth-fetch.js.map +0 -1
  91. package/dist/lib/generators/file-generators/auth-user.js +0 -13
  92. package/dist/lib/generators/file-generators/auth-user.js.map +0 -1
  93. package/dist/lib/generators/file-generators/connectivity-manager.js +0 -12
  94. package/dist/lib/generators/file-generators/connectivity-manager.js.map +0 -1
  95. package/dist/lib/generators/file-generators/fetch-state.js +0 -6
  96. package/dist/lib/generators/file-generators/fetch-state.js.map +0 -1
  97. package/dist/lib/generators/file-generators/generate-hooks.js +0 -44
  98. package/dist/lib/generators/file-generators/generate-hooks.js.map +0 -1
  99. package/dist/lib/generators/file-generators/indexeddb.js +0 -74
  100. package/dist/lib/generators/file-generators/indexeddb.js.map +0 -1
  101. package/dist/lib/generators/file-generators/manifest.js +0 -46
  102. package/dist/lib/generators/file-generators/manifest.js.map +0 -1
  103. package/dist/lib/generators/file-generators/mutation-reconcile.js +0 -57
  104. package/dist/lib/generators/file-generators/mutation-reconcile.js.map +0 -1
  105. package/dist/lib/generators/file-generators/notification-generator.js +0 -6
  106. package/dist/lib/generators/file-generators/notification-generator.js.map +0 -1
  107. package/dist/lib/generators/file-generators/quick-readme.js +0 -21
  108. package/dist/lib/generators/file-generators/quick-readme.js.map +0 -1
  109. package/dist/lib/generators/file-generators/reconcile.js +0 -50
  110. package/dist/lib/generators/file-generators/reconcile.js.map +0 -1
  111. package/dist/lib/generators/file-generators/storage-generator.js +0 -6
  112. package/dist/lib/generators/file-generators/storage-generator.js.map +0 -1
  113. package/dist/lib/generators/file-generators/storage-notify.js +0 -6
  114. package/dist/lib/generators/file-generators/storage-notify.js.map +0 -1
  115. package/dist/lib/generators/file-generators/store.js +0 -86
  116. package/dist/lib/generators/file-generators/store.js.map +0 -1
  117. package/dist/lib/generators/file-generators/sw-push.js +0 -67
  118. package/dist/lib/generators/file-generators/sw-push.js.map +0 -1
  119. package/dist/lib/generators/file-generators/sw-version-gen.js +0 -32
  120. package/dist/lib/generators/file-generators/sw-version-gen.js.map +0 -1
  121. package/dist/lib/generators/sw-sections/glob-matcher-code.js.map +0 -1
  122. package/dist/lib/generators/sw-sections/install-handler.js +0 -54
  123. package/dist/lib/generators/sw-sections/install-handler.js.map +0 -1
  124. package/dist/lib/utils/build-script.js +0 -35
  125. package/dist/lib/utils/build-script.js.map +0 -1
  126. package/dist/lib/utils/tty-status.js +0 -21
  127. package/dist/lib/utils/tty-status.js.map +0 -1
  128. package/dist/runtime/auth-user.js +0 -154
  129. package/dist/runtime/auth-user.js.map +0 -1
  130. package/dist/runtime/connectivity-manager.js +0 -83
  131. package/dist/runtime/connectivity-manager.js.map +0 -1
  132. package/dist/runtime/fetch-state.js +0 -42
  133. package/dist/runtime/fetch-state.js.map +0 -1
  134. package/dist/runtime/notification.js +0 -65
  135. package/dist/runtime/notification.js.map +0 -1
  136. package/dist/runtime/pwa-index.js +0 -11
  137. package/dist/runtime/pwa-index.js.map +0 -1
  138. package/dist/runtime/pwa-injector.js +0 -15
  139. package/dist/runtime/pwa-injector.js.map +0 -1
  140. package/dist/runtime/pwa-install.js +0 -83
  141. package/dist/runtime/pwa-install.js.map +0 -1
  142. package/dist/runtime/sw-version.js +0 -13
  143. package/dist/runtime/sw-version.js.map +0 -1
  144. package/dist/swoff-nkdhhmw8. +0 -18
  145. package/dist/swoff.js +0 -5
  146. package/templates/react/useSWUpdate.jsx +0 -31
  147. package/templates/react/useSWUpdate.tsx +0 -37
@@ -1,65 +0,0 @@
1
- import { T, R } from "./utils.js";
2
- export function generateNotificationCode(ctx) {
3
- const { ext, ts } = ctx;
4
- return `/**
5
- * Swoff Notification
6
- * Dispatches \`swoff:notification\` custom events so your app can
7
- * show toast/alert UI for offline-first events (fetch failures,
8
- * storage quota warnings, background sync errors, etc.).
9
- *
10
- * Usage:
11
- * import { checkStorage } from "./swoff/notification.${ext}";
12
- * const { usage, quota, percentUsed } = await checkStorage();
13
- *
14
- * Window events:
15
- * swoff:notification — dispatched by the service worker or by checkStorage()
16
- * detail: { level: "error"|"warn"|"info", code: string, message: string }
17
- *
18
- * ── Placeholder listener ────────────────────────────────
19
- * Add a listener in your app entry point and replace the body
20
- * with your own toast library (e.g. react-hot-toast, vue-toastification):
21
- *
22
- * window.addEventListener("swoff:notification", (event) => {
23
- * const { level, code, message } = event.detail;
24
- * // console.log(\`[swoff:\${level}] \${code}: \${message}\`);
25
- * // alert(\`\${code}: \${message}\`);
26
- * });
27
- */
28
-
29
- /** Get raw storage estimate without dispatching events. Reuse in your own UI. */
30
- export async function getStorageEstimate()${R(ts, "Promise<{ usage: number; quota: number; percentUsed: number }>")}{
31
- if (!navigator.storage?.estimate) {
32
- return { usage: 0, quota: 0, percentUsed: 0 };
33
- }
34
- const { usage = 0, quota = 0 } = await navigator.storage.estimate();
35
- const percentUsed = quota > 0 ? Math.round((usage / quota) * 100) : 0;
36
- return { usage, quota, percentUsed };
37
- }
38
-
39
- /** Check available storage and dispatch a warning if >80% used. */
40
- export async function checkStorage()${R(ts, "Promise<{ usage: number; quota: number; percentUsed: number }>")}{
41
- const result = await getStorageEstimate();
42
- if (result.percentUsed > 80) {
43
- window.dispatchEvent(
44
- new CustomEvent("swoff:notification", {
45
- detail: {
46
- level: "warn",
47
- code: "STORAGE_QUOTA_HIGH",
48
- message: \`Storage at \${result.percentUsed}% capacity (\${formatBytes(result.usage)} / \${formatBytes(result.quota)})\`,
49
- },
50
- }),
51
- );
52
- }
53
- return result;
54
- }
55
-
56
- /** Format bytes to a human-readable string (e.g. "1.5 MB"). */
57
- export function formatBytes(bytes${T(ts, "number")})${R(ts, "string")}{
58
- if (bytes === 0) return "0 B";
59
- const units = ["B", "KB", "MB", "GB"];
60
- const i = Math.floor(Math.log(bytes) / Math.log(1024));
61
- return \`\${(bytes / Math.pow(1024, i)).toFixed(1)} \${units[i]}\`;
62
- }
63
- `;
64
- }
65
- //# sourceMappingURL=notification.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"notification.js","sourceRoot":"","sources":["../../src/runtime/notification.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,UAAU,wBAAwB,CAAC,GAAmB;IAC1D,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC;IACxB,OAAO;;;;;;;0DAOiD,GAAG;;;;;;;;;;;;;;;;;;;4CAmBjB,CAAC,CAAC,EAAE,EAAE,gEAAgE,CAAC;;;;;;;;;;sCAU7E,CAAC,CAAC,EAAE,EAAE,gEAAgE,CAAC;;;;;;;;;;;;;;;;;mCAiB1E,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC;;;;;;CAMpE,CAAC;AACF,CAAC"}
@@ -1,11 +0,0 @@
1
- export function generatePwaIndexCode(ctx) {
2
- const { ext } = ctx;
3
- return `/**
4
- * Swoff PWA
5
- * Re-exports from PWA sub-modules for convenience imports.
6
- */
7
- export { setupPwaInstall } from "./injector.${ext}";
8
- export { isInstallable, promptInstall } from "./prompt.${ext}";
9
- `;
10
- }
11
- //# sourceMappingURL=pwa-index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pwa-index.js","sourceRoot":"","sources":["../../src/runtime/pwa-index.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAAC,GAAmB;IACtD,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAEpB,OAAO;;;;8CAIqC,GAAG;yDACQ,GAAG;CAC3D,CAAC;AACF,CAAC"}
@@ -1,15 +0,0 @@
1
- export function generatePwaInjectorCode(ctx) {
2
- const { ext } = ctx;
3
- return `/**
4
- * Swoff PWA Injector
5
- * Re-exports setupPwaInstall from the prompt module.
6
- *
7
- * Usage:
8
- * import { setupPwaInstall } from './swoff/pwa/injector.${ext}';
9
- * setupPwaInstall();
10
- */
11
-
12
- export { setupPwaInstall } from "./prompt.${ext}";
13
- `;
14
- }
15
- //# sourceMappingURL=pwa-injector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pwa-injector.js","sourceRoot":"","sources":["../../src/runtime/pwa-injector.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,uBAAuB,CAAC,GAAmB;IACzD,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAEpB,OAAO;;;;;6DAKoD,GAAG;;;;4CAIpB,GAAG;CAC9C,CAAC;AACF,CAAC"}
@@ -1,83 +0,0 @@
1
- import { R } from "./utils.js";
2
- export function generatePwaInstallCode(ctx) {
3
- const { ext, ts } = ctx;
4
- const preventLine = ctx.preventDefaultInstall ? " e.preventDefault();\n" : "";
5
- return `/**
6
- * Swoff PWA Install Support
7
- * Manual install trigger, installability check, and event listener setup.
8
- *
9
- * Usage:
10
- * import { setupPwaInstall, isInstallable, promptInstall } from './swoff/pwa/prompt.${ext}';
11
- *
12
- * setupPwaInstall(); // sets up beforeinstallprompt and appinstalled listeners
13
- *
14
- * if (isInstallable()) {
15
- * const result = await promptInstall();
16
- * }
17
- *
18
- * Window properties:
19
- * window.deferredInstallPrompt - The captured BeforeInstallPromptEvent
20
- */
21
-
22
- /** Set up beforeinstallprompt and appinstalled event listeners. Call once at app startup. */
23
- export function setupPwaInstall()${R(ts, "void")}{
24
- window.addEventListener("beforeinstallprompt", (e) => {
25
- window.deferredInstallPrompt = e as BeforeInstallPromptEvent;
26
- window.pwaInstallable = true;
27
-
28
- ${preventLine}
29
- window.dispatchEvent(
30
- new CustomEvent("pwa-installable", {
31
- detail: { isInstallable: true },
32
- })
33
- );
34
- });
35
-
36
- window.addEventListener("appinstalled", () => {
37
- window.deferredInstallPrompt = null;
38
- window.pwaInstallable = false;
39
-
40
- window.dispatchEvent(
41
- new CustomEvent("pwa-installed", {
42
- detail: { outcome: "accepted" },
43
- })
44
- );
45
- });
46
- }
47
-
48
- /** Check if the PWA install prompt is available (user has met install criteria). */
49
- export function isInstallable()${R(ts, "boolean")}{
50
- return !!window.deferredInstallPrompt;
51
- }
52
-
53
- /** Show the browser's native install prompt. Throws if prompt is not available. */
54
- export async function promptInstall()${R(ts, "Promise<{ outcome: string }>")}{
55
- if (!window.deferredInstallPrompt) {
56
- throw new Error("Install prompt not available");
57
- }
58
-
59
- const promptEvent = window.deferredInstallPrompt;
60
- await promptEvent.prompt();
61
-
62
- const choice = await promptEvent.userChoice;
63
-
64
- if (choice.outcome === "accepted") {
65
- window.dispatchEvent(
66
- new CustomEvent("pwa-installed", {
67
- detail: { outcome: "accepted" },
68
- })
69
- );
70
- } else {
71
- window.dispatchEvent(
72
- new CustomEvent("pwa-dismissed", {
73
- detail: { outcome: "dismissed" },
74
- })
75
- );
76
- }
77
-
78
- window.deferredInstallPrompt = null;
79
- return choice;
80
- }
81
- `;
82
- }
83
- //# sourceMappingURL=pwa-install.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pwa-install.js","sourceRoot":"","sources":["../../src/runtime/pwa-install.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAE/B,MAAM,UAAU,sBAAsB,CAAC,GAAwD;IAC7F,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC;IACxB,MAAM,WAAW,GAAG,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjF,OAAO;;;;;yFAKgF,GAAG;;;;;;;;;;;;;mCAazD,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC;;;;;EAK9C,WAAW;;;;;;;;;;;;;;;;;;;;;iCAqBoB,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC;;;;;uCAKV,CAAC,CAAC,EAAE,EAAE,8BAA8B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2B3E,CAAC;AACF,CAAC"}
@@ -1,13 +0,0 @@
1
- export function generateSwVersionCode(ctx) {
2
- return `/**
3
- * Swoff SW Version
4
- *
5
- * Developer-editable version used for SW URL and cache naming.
6
- * - "package" mode: The build script overwrites this from package.json
7
- * - "manual" mode: Edit this file directly to bump the version
8
- * - "hash" mode: Not used (SW URL is fixed, cache is content-addressed)
9
- */
10
- export const SW_VERSION = ${JSON.stringify(ctx.version)};
11
- `;
12
- }
13
- //# sourceMappingURL=sw-version.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sw-version.js","sourceRoot":"","sources":["../../src/runtime/sw-version.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CACnC,GAAyC;IAEzC,OAAO;;;;;;;;4BAQmB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;CACtD,CAAC;AACF,CAAC"}
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { existsSync } from 'node:fs';
4
- import { dirname, join } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const entryPoint = join(__dirname, '..', 'dist', 'index.js');
9
-
10
- if (!existsSync(entryPoint)) {
11
- console.error('Error: CLI not built. Run: npm run build');
12
- process.exit(1);
13
- }
14
-
15
- import(entryPoint).catch((err) => {
16
- console.error('Error:', err instanceof Error ? err.message : String(err));
17
- process.exit(1);
18
- });
package/dist/swoff.js DELETED
@@ -1,5 +0,0 @@
1
- // apps/cli/bin/swoff
2
- var swoff_default = "./swoff-nkdhhmw8.";
3
- export {
4
- swoff_default as default
5
- };
@@ -1,31 +0,0 @@
1
- import { useState, useEffect } from "react";
2
-
3
- export function useSWUpdate() {
4
- const [state, setState] = useState(() => ({
5
- status: "idle",
6
- progress: 0,
7
- error: null,
8
- }));
9
-
10
- useEffect(() => {
11
- const onProgress = (e) =>
12
- setState((s) => ({ ...s, status: "installing", progress: e.detail.percent }));
13
-
14
- const onReady = () =>
15
- setState({ status: "idle", progress: 0, error: null });
16
-
17
- const onError = () =>
18
- setState({ status: "idle", progress: 0, error: "SW registration failed" });
19
-
20
- window.addEventListener("sw-progress", onProgress);
21
- window.addEventListener("sw-ready", onReady);
22
- window.addEventListener("sw-error", onError);
23
- return () => {
24
- window.removeEventListener("sw-progress", onProgress);
25
- window.removeEventListener("sw-ready", onReady);
26
- window.removeEventListener("sw-error", onError);
27
- };
28
- }, []);
29
-
30
- return state;
31
- }
@@ -1,37 +0,0 @@
1
- import { useState, useEffect } from "react";
2
-
3
- type UpdateStatus = "idle" | "installing";
4
-
5
- export function useSWUpdate() {
6
- const [state, setState] = useState(() => ({
7
- status: "idle" as UpdateStatus,
8
- progress: 0,
9
- error: null as string | null,
10
- }));
11
-
12
- useEffect(() => {
13
- const onProgress = (e: WindowEventMap["sw-progress"]) =>
14
- setState((s) => ({
15
- ...s,
16
- status: "installing",
17
- progress: e.detail.percent,
18
- }));
19
-
20
- const onReady = () =>
21
- setState({ status: "idle", progress: 0, error: null });
22
-
23
- const onError = () =>
24
- setState({ status: "idle", progress: 0, error: "SW registration failed" });
25
-
26
- window.addEventListener("sw-progress", onProgress);
27
- window.addEventListener("sw-ready", onReady);
28
- window.addEventListener("sw-error", onError);
29
- return () => {
30
- window.removeEventListener("sw-progress", onProgress);
31
- window.removeEventListener("sw-ready", onReady);
32
- window.removeEventListener("sw-error", onError);
33
- };
34
- }, []);
35
-
36
- return state;
37
- }