@swoff/cli 0.0.2 → 0.2.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 +49 -0
- package/bin/swoff +0 -0
- package/dist/__tests__/assemble-sw.test.js +145 -0
- package/dist/__tests__/assemble-sw.test.js.map +1 -0
- package/dist/__tests__/cli-integration.test.js +128 -0
- package/dist/__tests__/cli-integration.test.js.map +1 -0
- package/dist/__tests__/config-types.test.js +82 -0
- package/dist/__tests__/config-types.test.js.map +1 -0
- package/dist/__tests__/detect-language.test.js +51 -0
- package/dist/__tests__/detect-language.test.js.map +1 -0
- package/dist/__tests__/file-generators.test.js +271 -0
- package/dist/__tests__/file-generators.test.js.map +1 -0
- package/dist/__tests__/invalidation-tags.test.js +99 -0
- package/dist/__tests__/invalidation-tags.test.js.map +1 -0
- package/dist/__tests__/loader.test.js +77 -0
- package/dist/__tests__/loader.test.js.map +1 -0
- package/dist/__tests__/validator.test.js +232 -0
- package/dist/__tests__/validator.test.js.map +1 -0
- package/dist/index.js +36 -348
- package/dist/index.js.map +1 -1
- package/dist/lib/cli/colors.js +14 -0
- package/dist/lib/cli/colors.js.map +1 -0
- package/dist/lib/cli/help.js +63 -0
- package/dist/lib/cli/help.js.map +1 -0
- package/dist/lib/cli/logger.js +13 -0
- package/dist/lib/cli/logger.js.map +1 -0
- package/dist/lib/commands/add.js +58 -0
- package/dist/lib/commands/add.js.map +1 -0
- package/dist/lib/commands/clean.js +39 -0
- package/dist/lib/commands/clean.js.map +1 -0
- package/dist/lib/commands/generate.js +84 -0
- package/dist/lib/commands/generate.js.map +1 -0
- package/dist/lib/commands/info.js +44 -0
- package/dist/lib/commands/info.js.map +1 -0
- package/dist/lib/commands/init.js +46 -0
- package/dist/lib/commands/init.js.map +1 -0
- package/dist/lib/commands/validate.js +30 -0
- package/dist/lib/commands/validate.js.map +1 -0
- package/dist/lib/config/loader.js +80 -0
- package/dist/lib/config/loader.js.map +1 -0
- package/dist/lib/config/validator.js +102 -0
- package/dist/lib/config/validator.js.map +1 -0
- package/dist/lib/generators/file-generators/background-sync.js +59 -0
- package/dist/lib/generators/file-generators/background-sync.js.map +1 -0
- package/dist/lib/generators/file-generators/cache.js +55 -0
- package/dist/lib/generators/file-generators/cache.js.map +1 -0
- package/dist/lib/generators/file-generators/context.js +16 -0
- package/dist/lib/generators/file-generators/context.js.map +1 -0
- package/dist/lib/generators/file-generators/fetch-wrapper.js +80 -0
- package/dist/lib/generators/file-generators/fetch-wrapper.js.map +1 -0
- package/dist/lib/generators/file-generators/indexeddb.js +73 -0
- package/dist/lib/generators/file-generators/indexeddb.js.map +1 -0
- package/dist/lib/generators/file-generators/invalidation-tags.js +91 -0
- package/dist/lib/generators/file-generators/invalidation-tags.js.map +1 -0
- package/dist/lib/generators/file-generators/manifest.js +26 -0
- package/dist/lib/generators/file-generators/manifest.js.map +1 -0
- package/dist/lib/generators/file-generators/mutation-queue.js +226 -0
- package/dist/lib/generators/file-generators/mutation-queue.js.map +1 -0
- package/dist/lib/generators/file-generators/pwa-install.js +102 -0
- package/dist/lib/generators/file-generators/pwa-install.js.map +1 -0
- package/dist/lib/generators/file-generators/reconcile.js +54 -0
- package/dist/lib/generators/file-generators/reconcile.js.map +1 -0
- package/dist/lib/generators/file-generators/store.js +75 -0
- package/dist/lib/generators/file-generators/store.js.map +1 -0
- package/dist/lib/generators/file-generators/sw-generator-build.js +70 -0
- package/dist/lib/generators/file-generators/sw-generator-build.js.map +1 -0
- package/dist/lib/generators/file-generators/sw-injector.js +195 -0
- package/dist/lib/generators/file-generators/sw-injector.js.map +1 -0
- package/dist/lib/generators/file-generators/sw-template.js +143 -0
- package/dist/lib/generators/file-generators/sw-template.js.map +1 -0
- package/dist/lib/generators/file-generators/type-definitions.js +69 -0
- package/dist/lib/generators/file-generators/type-definitions.js.map +1 -0
- package/dist/lib/generators/sw-generator.js +37 -239
- package/dist/lib/generators/sw-generator.js.map +1 -1
- package/dist/lib/generators/sw-sections/activate-handler.js +16 -0
- package/dist/lib/generators/sw-sections/activate-handler.js.map +1 -0
- package/dist/lib/generators/sw-sections/assemble-sw.js +38 -0
- package/dist/lib/generators/sw-sections/assemble-sw.js.map +1 -0
- package/dist/lib/generators/sw-sections/background-sync-handler.js +106 -0
- package/dist/lib/generators/sw-sections/background-sync-handler.js.map +1 -0
- package/dist/lib/generators/sw-sections/config-header.js +15 -0
- package/dist/lib/generators/sw-sections/config-header.js.map +1 -0
- package/dist/lib/generators/sw-sections/default-template.js +51 -0
- package/dist/lib/generators/sw-sections/default-template.js.map +1 -0
- package/dist/lib/generators/sw-sections/fetch-handler.js +210 -0
- package/dist/lib/generators/sw-sections/fetch-handler.js.map +1 -0
- package/dist/lib/generators/sw-sections/install-handler.js +35 -0
- package/dist/lib/generators/sw-sections/install-handler.js.map +1 -0
- package/dist/lib/generators/sw-sections/message-handler.js +20 -0
- package/dist/lib/generators/sw-sections/message-handler.js.map +1 -0
- package/dist/lib/generators/sw-sections/tag-management.js +69 -0
- package/dist/lib/generators/sw-sections/tag-management.js.map +1 -0
- package/dist/lib/generators/swoff-files-generator.js +80 -1043
- package/dist/lib/generators/swoff-files-generator.js.map +1 -1
- package/dist/lib/shared/config-types.js +87 -0
- package/dist/lib/shared/config-types.js.map +1 -0
- package/dist/lib/utils/detect-language.js +33 -0
- package/dist/lib/utils/detect-language.js.map +1 -0
- package/package.json +6 -2
- package/src/lib/templates/sw-template.js +23 -6
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates sw-injector.{js|ts} - client-side SW registration with version checking.
|
|
3
|
+
*/
|
|
4
|
+
import { writeFile } from "./context.js";
|
|
5
|
+
export function generateSwInjector(ctx) {
|
|
6
|
+
const autoRegister = ctx.config.serviceWorker.autoRegister;
|
|
7
|
+
const autoUpdate = ctx.config.serviceWorker.autoUpdate;
|
|
8
|
+
const ext = ctx.ext;
|
|
9
|
+
const code = `/**
|
|
10
|
+
* Swoff Service Worker Injector
|
|
11
|
+
* Framework-agnostic client registration with version checking.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* import { initServiceWorker, shouldRegisterSW } from './swoff/sw-injector.${ext}';
|
|
15
|
+
*
|
|
16
|
+
* // Call in your app entry point (e.g., main.tsx, app.js):
|
|
17
|
+
* if (shouldRegisterSW()) {
|
|
18
|
+
* initServiceWorker();
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* // Or defer until after onboarding:
|
|
22
|
+
* function myShouldRegister() {
|
|
23
|
+
* return localStorage.getItem('onboarding-complete') === 'true';
|
|
24
|
+
* }
|
|
25
|
+
* if (myShouldRegister()) {
|
|
26
|
+
* initServiceWorker();
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* Window events:
|
|
30
|
+
* sw-version-detected - Version info available on window
|
|
31
|
+
* sw-update-available - New version ready for user consent (detail: { version })
|
|
32
|
+
* sw-progress - Download progress (detail: { percent, downloaded, total })
|
|
33
|
+
* sw-ready - SW active and controlling page
|
|
34
|
+
* sw-error - SW registration failed
|
|
35
|
+
*
|
|
36
|
+
* Window properties:
|
|
37
|
+
* window.latestSWVersion - Latest version from version.json
|
|
38
|
+
* window.currentSWVersion - Active SW version
|
|
39
|
+
* window.swAvailableVersion - Pending update version
|
|
40
|
+
* window.swUpdateRequired - Forced update needed (version < minSupportedVersion)
|
|
41
|
+
* window.swMinSupportedVersion - Minimum supported version from version.json
|
|
42
|
+
* window.swReady - SW is active
|
|
43
|
+
* window.swError - Registration failed
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
const AUTO_REGISTER = ${autoRegister};
|
|
47
|
+
const AUTO_UPDATE = ${autoUpdate};
|
|
48
|
+
|
|
49
|
+
async function checkForUpdate() {
|
|
50
|
+
const response = await fetch("/version.json");
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error("Failed to fetch version.json");
|
|
53
|
+
}
|
|
54
|
+
return response.json();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function doRegisterServiceWorker(version) {
|
|
58
|
+
const swUrl = \`/sw-v\${version}.js\`;
|
|
59
|
+
const registration = await navigator.serviceWorker.register(swUrl);
|
|
60
|
+
localStorage.setItem("swRegisteredVersion", version);
|
|
61
|
+
window.currentSWVersion = version;
|
|
62
|
+
window.swRegisteredVersion = version;
|
|
63
|
+
window.dispatchEvent(new CustomEvent("sw-version-detected"));
|
|
64
|
+
window.dispatchEvent(new CustomEvent("sw-ready"));
|
|
65
|
+
return registration;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function shouldRegisterSW() {
|
|
69
|
+
if (!AUTO_REGISTER) return false;
|
|
70
|
+
|
|
71
|
+
// Add custom conditions here. Return false to prevent registration.
|
|
72
|
+
// Examples:
|
|
73
|
+
// - Check if user completed onboarding
|
|
74
|
+
// - Check if user accepted terms
|
|
75
|
+
// - Check if user is on a slow connection
|
|
76
|
+
//
|
|
77
|
+
// if (!localStorage.getItem("onboarding-complete")) return false;
|
|
78
|
+
// if (navigator.connection?.effectiveType === "slow-2g") return false;
|
|
79
|
+
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function initServiceWorker() {
|
|
84
|
+
if (!("serviceWorker" in navigator)) {
|
|
85
|
+
console.warn("Service Workers not supported");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const manifest = await checkForUpdate();
|
|
91
|
+
const currentVersion = localStorage.getItem("swRegisteredVersion");
|
|
92
|
+
window.latestSWVersion = manifest.version;
|
|
93
|
+
window.swMinSupportedVersion = manifest.minSupportedVersion || "0.0.0";
|
|
94
|
+
|
|
95
|
+
if (currentVersion === manifest.version) {
|
|
96
|
+
const registration = await navigator.serviceWorker.getRegistration();
|
|
97
|
+
if (registration && registration.active) {
|
|
98
|
+
window.currentSWVersion = currentVersion;
|
|
99
|
+
window.dispatchEvent(new CustomEvent("sw-version-detected"));
|
|
100
|
+
window.dispatchEvent(new CustomEvent("sw-ready"));
|
|
101
|
+
}
|
|
102
|
+
} else if (currentVersion && currentVersion !== manifest.version) {
|
|
103
|
+
window.swAvailableVersion = manifest.version;
|
|
104
|
+
window.swUpdateRequired =
|
|
105
|
+
currentVersion < (manifest.minSupportedVersion || "0.0.0");
|
|
106
|
+
|
|
107
|
+
if (AUTO_UPDATE) {
|
|
108
|
+
const registration = await navigator.serviceWorker.getRegistration();
|
|
109
|
+
if (registration && registration.waiting) {
|
|
110
|
+
registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
111
|
+
} else {
|
|
112
|
+
await doRegisterServiceWorker(manifest.version);
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
window.dispatchEvent(
|
|
116
|
+
new CustomEvent("sw-update-available", {
|
|
117
|
+
detail: { version: manifest.version },
|
|
118
|
+
})
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
await doRegisterServiceWorker(manifest.version);
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
// Offline or version.json fetch failed — try using existing registration
|
|
126
|
+
try {
|
|
127
|
+
const existing = await navigator.serviceWorker.getRegistration();
|
|
128
|
+
if (existing && existing.active) {
|
|
129
|
+
window.currentSWVersion = localStorage.getItem("swRegisteredVersion") || "unknown";
|
|
130
|
+
window.dispatchEvent(new CustomEvent("sw-version-detected"));
|
|
131
|
+
window.dispatchEvent(new CustomEvent("sw-ready"));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
} catch {
|
|
135
|
+
// Registration check also failed, nothing we can do
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.error("Service Worker initialization failed:", error);
|
|
139
|
+
window.swError = true;
|
|
140
|
+
window.dispatchEvent(new CustomEvent("sw-error"));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export async function handleUpdateApproved(newVersion) {
|
|
145
|
+
const registration = await navigator.serviceWorker.getRegistration();
|
|
146
|
+
if (registration && registration.waiting) {
|
|
147
|
+
registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
148
|
+
registration.addEventListener("controllerchange", () => {
|
|
149
|
+
window.location.reload();
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
await doRegisterServiceWorker(newVersion);
|
|
153
|
+
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
|
154
|
+
window.location.reload();
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export async function skipWaiting() {
|
|
160
|
+
const registration = await navigator.serviceWorker.ready;
|
|
161
|
+
if (registration.waiting) {
|
|
162
|
+
registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (typeof window !== "undefined" && "serviceWorker" in navigator) {
|
|
167
|
+
navigator.serviceWorker.addEventListener("message", (event) => {
|
|
168
|
+
if (event.data.type === "SW_PROGRESS") {
|
|
169
|
+
const { percent, downloaded, total } = event.data;
|
|
170
|
+
window.dispatchEvent(
|
|
171
|
+
new CustomEvent("sw-progress", {
|
|
172
|
+
detail: { percent, downloaded, total },
|
|
173
|
+
})
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
if (event.data.type === "BACKGROUND_SYNC_COMPLETE") {
|
|
177
|
+
const { succeeded, failed, tags } = event.data.detail;
|
|
178
|
+
window.dispatchEvent(
|
|
179
|
+
new CustomEvent("mutation-sync-complete", {
|
|
180
|
+
detail: { succeeded, failed },
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
if (tags && tags.length > 0) {
|
|
184
|
+
window.dispatchEvent(
|
|
185
|
+
new CustomEvent("cache-invalidated", { detail: { tags } })
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
window.dispatchEvent(new CustomEvent("mutation-queue-changed"));
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
`;
|
|
193
|
+
writeFile(ctx, `sw-injector.${ext}`, code);
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=sw-injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sw-injector.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/sw-injector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,UAAU,kBAAkB,CAAC,GAAqB;IACtD,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC;IAC3D,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC;IACvD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IAEpB,MAAM,IAAI,GAAG;;;;;gFAKiE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAgC3D,YAAY;sBACd,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiJ/B,CAAC;IAEA,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates sw-template.js - the SW template with placeholders.
|
|
3
|
+
*/
|
|
4
|
+
import { writeFile } from "./context.js";
|
|
5
|
+
export function generateSwTemplate(ctx) {
|
|
6
|
+
const code = `/**
|
|
7
|
+
* Swoff Service Worker Template
|
|
8
|
+
*
|
|
9
|
+
* This file is processed by swoff/sw-generator.js to create
|
|
10
|
+
* a versioned service worker. Placeholders are replaced during build.
|
|
11
|
+
*
|
|
12
|
+
* Placeholders:
|
|
13
|
+
* // [[CACHE_NAME]] - Replaced with versioned cache name
|
|
14
|
+
* // [[ASSETS_LIST]] - Replaced with assets to cache
|
|
15
|
+
* // [[AUTO_SKIP_WAITING]] - Replaced with autoUpdate config
|
|
16
|
+
*
|
|
17
|
+
* You can customize this template before running the build script.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
let CACHE_NAME = "";
|
|
21
|
+
let ASSETS_TO_CACHE = [];
|
|
22
|
+
|
|
23
|
+
// [[CACHE_NAME]]
|
|
24
|
+
// [[ASSETS_LIST]]
|
|
25
|
+
// [[AUTO_SKIP_WAITING]]
|
|
26
|
+
|
|
27
|
+
const CACHE_NAME_RUNTIME = "swoff-runtime";
|
|
28
|
+
|
|
29
|
+
// Install - download assets with progress tracking
|
|
30
|
+
self.addEventListener("install", (event) => {
|
|
31
|
+
event.waitUntil(
|
|
32
|
+
(async () => {
|
|
33
|
+
const cache = await caches.open(CACHE_NAME);
|
|
34
|
+
let downloaded = 0;
|
|
35
|
+
for (const asset of ASSETS_TO_CACHE) {
|
|
36
|
+
try {
|
|
37
|
+
const request = new Request(asset.url, asset.options);
|
|
38
|
+
await cache.add(request);
|
|
39
|
+
downloaded++;
|
|
40
|
+
const percent = Math.round((downloaded / ASSETS_TO_CACHE.length) * 100);
|
|
41
|
+
const clients = await self.clients.matchAll({ includeUncontrolled: true });
|
|
42
|
+
clients.forEach((client) => {
|
|
43
|
+
client.postMessage({
|
|
44
|
+
type: "SW_PROGRESS",
|
|
45
|
+
percent,
|
|
46
|
+
downloaded,
|
|
47
|
+
total: ASSETS_TO_CACHE.length,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.error(\`Failed to cache \${asset.url}:\`, err);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (AUTO_SKIP_WAITING) self.skipWaiting();
|
|
55
|
+
})(),
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Activate - clean old caches
|
|
60
|
+
self.addEventListener("activate", (event) => {
|
|
61
|
+
event.waitUntil(
|
|
62
|
+
caches.keys().then((keys) =>
|
|
63
|
+
Promise.all(
|
|
64
|
+
keys.filter((key) => key !== CACHE_NAME && key !== CACHE_NAME_RUNTIME).map((key) => caches.delete(key))
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Message - skip waiting and cache invalidation
|
|
71
|
+
self.addEventListener("message", (event) => {
|
|
72
|
+
if (event.data.type === "SKIP_WAITING") {
|
|
73
|
+
self.skipWaiting();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Fetch - cache strategies
|
|
78
|
+
self.addEventListener("fetch", (event) => {
|
|
79
|
+
if (event.request.method !== "GET" && event.request.method !== "HEAD") return;
|
|
80
|
+
|
|
81
|
+
event.respondWith(
|
|
82
|
+
(async () => {
|
|
83
|
+
const cache = await caches.open(CACHE_NAME);
|
|
84
|
+
const runtimeCache = await caches.open(CACHE_NAME_RUNTIME);
|
|
85
|
+
const url = new URL(event.request.url);
|
|
86
|
+
|
|
87
|
+
const byPath = await cache.match(url.pathname);
|
|
88
|
+
if (byPath) return byPath;
|
|
89
|
+
|
|
90
|
+
const byRequest = await runtimeCache.match(event.request);
|
|
91
|
+
if (byRequest) return byRequest;
|
|
92
|
+
|
|
93
|
+
if (event.request.mode === "navigate") {
|
|
94
|
+
const spa = await cache.match("/index.html");
|
|
95
|
+
if (spa) return spa;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
const response = await fetch(event.request);
|
|
100
|
+
if (response.ok) {
|
|
101
|
+
await runtimeCache.put(event.request, response.clone());
|
|
102
|
+
}
|
|
103
|
+
return response;
|
|
104
|
+
} catch {
|
|
105
|
+
return new Response("Offline: content not available", { status: 503 });
|
|
106
|
+
}
|
|
107
|
+
})(),
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const SWOFF = {
|
|
112
|
+
cache: {
|
|
113
|
+
async get(key) {
|
|
114
|
+
const cache = await caches.open(CACHE_NAME);
|
|
115
|
+
return cache.match(key);
|
|
116
|
+
},
|
|
117
|
+
async put(request, response) {
|
|
118
|
+
const cache = await caches.open(CACHE_NAME);
|
|
119
|
+
await cache.put(request, response);
|
|
120
|
+
},
|
|
121
|
+
async delete(request) {
|
|
122
|
+
const cache = await caches.open(CACHE_NAME);
|
|
123
|
+
return cache.delete(request);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
network: {
|
|
127
|
+
async fetch(request, options = {}) {
|
|
128
|
+
try {
|
|
129
|
+
return await fetch(request, options);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
throw new Error(\`Network request failed: \${error.message}\`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
if (typeof self !== 'undefined') {
|
|
138
|
+
self.SWOFF = SWOFF;
|
|
139
|
+
}
|
|
140
|
+
`;
|
|
141
|
+
writeFile(ctx, "sw-template.js", code);
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=sw-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sw-template.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/sw-template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,UAAU,kBAAkB,CAAC,GAAqB;IACtD,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsId,CAAC;IAEA,SAAS,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates swoff.d.ts - TypeScript type declarations.
|
|
3
|
+
*/
|
|
4
|
+
import { writeFile } from "./context.js";
|
|
5
|
+
export function generateTypeDefinitions(ctx) {
|
|
6
|
+
if (ctx.ext !== "ts")
|
|
7
|
+
return;
|
|
8
|
+
const code = `interface BeforeInstallPromptEvent extends Event {
|
|
9
|
+
prompt(): Promise<void>;
|
|
10
|
+
userChoice: Promise<{ outcome: "accepted" | "dismissed" }>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare global {
|
|
14
|
+
interface Window {
|
|
15
|
+
deferredInstallPrompt: BeforeInstallPromptEvent | null;
|
|
16
|
+
latestSWVersion?: string;
|
|
17
|
+
currentSWVersion?: string;
|
|
18
|
+
swRegisteredVersion?: string;
|
|
19
|
+
swAvailableVersion?: string;
|
|
20
|
+
swUpdateRequired?: boolean;
|
|
21
|
+
swMinSupportedVersion?: string;
|
|
22
|
+
swReady?: boolean;
|
|
23
|
+
swError?: boolean;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SWOFFCache {
|
|
28
|
+
get(key: Request | string): Promise<Response | undefined>;
|
|
29
|
+
put(request: Request | string, response: Response): Promise<void>;
|
|
30
|
+
delete(request: Request | string): Promise<boolean>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SWOFF {
|
|
34
|
+
cache: SWOFFCache;
|
|
35
|
+
network: {
|
|
36
|
+
fetch(request: Request | string, options?: RequestInit): Promise<Response>;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface FetchWithCacheOptions extends RequestInit {
|
|
41
|
+
strategy?: "read" | "mutation";
|
|
42
|
+
tags?: string[];
|
|
43
|
+
staleWhileRevalidate?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface MutationQueueItem {
|
|
47
|
+
id: string;
|
|
48
|
+
method: string;
|
|
49
|
+
url: string;
|
|
50
|
+
body: unknown;
|
|
51
|
+
headers: Record<string, string>;
|
|
52
|
+
previousData: unknown | null;
|
|
53
|
+
timestamp: number;
|
|
54
|
+
retryCount: number;
|
|
55
|
+
tags: string[];
|
|
56
|
+
storeName: string | null;
|
|
57
|
+
tempId: string | null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface MutationQueueResult {
|
|
61
|
+
succeeded: number;
|
|
62
|
+
failed: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export {};
|
|
66
|
+
`;
|
|
67
|
+
writeFile(ctx, "swoff.d.ts", code);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=type-definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-definitions.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/type-definitions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,UAAU,uBAAuB,CAAC,GAAqB;IAC3D,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI;QAAE,OAAO;IAE7B,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Dd,CAAC;IAEA,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC"}
|