@swoff/cli 0.3.9 → 0.3.10
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/dist/__tests__/assemble-sw.test.js +8 -17
- package/dist/__tests__/assemble-sw.test.js.map +1 -1
- package/dist/__tests__/cli-integration.test.js +2 -2
- package/dist/__tests__/cli-integration.test.js.map +1 -1
- package/dist/__tests__/config-types.test.js +18 -8
- package/dist/__tests__/config-types.test.js.map +1 -1
- package/dist/__tests__/file-generators.test.js +3 -3
- package/dist/__tests__/file-generators.test.js.map +1 -1
- package/dist/__tests__/loader.test.js +5 -1
- package/dist/__tests__/loader.test.js.map +1 -1
- package/dist/__tests__/validator.test.js +6 -13
- package/dist/__tests__/validator.test.js.map +1 -1
- package/dist/index.js +39 -35
- package/dist/index.js.map +1 -1
- package/dist/lib/cli/help.js +13 -8
- package/dist/lib/cli/help.js.map +1 -1
- package/dist/lib/commands/add.js +38 -8
- package/dist/lib/commands/add.js.map +1 -1
- package/dist/lib/commands/assets.js +37 -0
- package/dist/lib/commands/assets.js.map +1 -0
- package/dist/lib/commands/clean.js +33 -17
- package/dist/lib/commands/clean.js.map +1 -1
- package/dist/lib/commands/generate-assets.js +44 -0
- package/dist/lib/commands/generate-assets.js.map +1 -0
- package/dist/lib/commands/generate-guide.js +22 -29
- package/dist/lib/commands/generate-guide.js.map +1 -1
- package/dist/lib/commands/generate.js +16 -9
- package/dist/lib/commands/generate.js.map +1 -1
- package/dist/lib/commands/info.js +36 -45
- package/dist/lib/commands/info.js.map +1 -1
- package/dist/lib/commands/init.js +25 -3
- package/dist/lib/commands/init.js.map +1 -1
- package/dist/lib/commands/validate.js +1 -1
- package/dist/lib/commands/validate.js.map +1 -1
- package/dist/lib/config/loader.js +25 -20
- package/dist/lib/config/loader.js.map +1 -1
- package/dist/lib/config/validator.js +20 -11
- package/dist/lib/config/validator.js.map +1 -1
- package/dist/lib/generators/asset-generator/dependency-resolver.js +76 -0
- package/dist/lib/generators/asset-generator/dependency-resolver.js.map +1 -0
- package/dist/lib/generators/asset-generator/generate.js +111 -0
- package/dist/lib/generators/asset-generator/generate.js.map +1 -0
- package/dist/lib/generators/asset-generator/guide.js +43 -0
- package/dist/lib/generators/asset-generator/guide.js.map +1 -0
- package/dist/lib/generators/asset-generator/html-patcher.js +65 -0
- package/dist/lib/generators/asset-generator/html-patcher.js.map +1 -0
- package/dist/lib/generators/asset-generator/ico-encoder.js +29 -0
- package/dist/lib/generators/asset-generator/ico-encoder.js.map +1 -0
- package/dist/lib/generators/asset-generator/manifest-patcher.js +23 -0
- package/dist/lib/generators/asset-generator/manifest-patcher.js.map +1 -0
- package/dist/lib/generators/asset-generator/maskable.js +15 -0
- package/dist/lib/generators/asset-generator/maskable.js.map +1 -0
- package/dist/lib/generators/asset-generator/rasterize.js +32 -0
- package/dist/lib/generators/asset-generator/rasterize.js.map +1 -0
- package/dist/lib/generators/asset-generator/sizes.js +25 -0
- package/dist/lib/generators/asset-generator/sizes.js.map +1 -0
- package/dist/lib/generators/file-generators/api-config.js +6 -0
- package/dist/lib/generators/file-generators/api-config.js.map +1 -0
- package/dist/lib/generators/file-generators/auth-state.js +2 -34
- package/dist/lib/generators/file-generators/auth-state.js.map +1 -1
- package/dist/lib/generators/file-generators/auth-store.js +2 -250
- package/dist/lib/generators/file-generators/auth-store.js.map +1 -1
- package/dist/lib/generators/file-generators/auth-user.js +3 -81
- package/dist/lib/generators/file-generators/auth-user.js.map +1 -1
- package/dist/lib/generators/file-generators/background-sync.js +2 -57
- package/dist/lib/generators/file-generators/background-sync.js.map +1 -1
- package/dist/lib/generators/file-generators/cache.js +2 -30
- package/dist/lib/generators/file-generators/cache.js.map +1 -1
- package/dist/lib/generators/file-generators/client-injector.js +2 -130
- package/dist/lib/generators/file-generators/client-injector.js.map +1 -1
- package/dist/lib/generators/file-generators/fetch-state.js +6 -0
- package/dist/lib/generators/file-generators/fetch-state.js.map +1 -0
- package/dist/lib/generators/file-generators/fetch-wrapper.js +3 -295
- package/dist/lib/generators/file-generators/fetch-wrapper.js.map +1 -1
- package/dist/lib/generators/file-generators/generate-framework-adapters.js +56 -0
- package/dist/lib/generators/file-generators/generate-framework-adapters.js.map +1 -0
- package/dist/lib/generators/file-generators/generate-hooks.js +4 -3
- package/dist/lib/generators/file-generators/generate-hooks.js.map +1 -1
- package/dist/lib/generators/file-generators/gql-wrapper.js +3 -132
- package/dist/lib/generators/file-generators/gql-wrapper.js.map +1 -1
- package/dist/lib/generators/file-generators/guide-generator.js +29 -1
- package/dist/lib/generators/file-generators/guide-generator.js.map +1 -1
- package/dist/lib/generators/file-generators/invalidation-tags.js +3 -258
- package/dist/lib/generators/file-generators/invalidation-tags.js.map +1 -1
- package/dist/lib/generators/file-generators/manifest.js +13 -3
- package/dist/lib/generators/file-generators/manifest.js.map +1 -1
- package/dist/lib/generators/file-generators/mutation-queue.js +3 -305
- package/dist/lib/generators/file-generators/mutation-queue.js.map +1 -1
- package/dist/lib/generators/file-generators/mutation-state.js +2 -117
- package/dist/lib/generators/file-generators/mutation-state.js.map +1 -1
- package/dist/lib/generators/file-generators/push.js +6 -138
- package/dist/lib/generators/file-generators/push.js.map +1 -1
- package/dist/lib/generators/file-generators/pwa-install.js +11 -84
- package/dist/lib/generators/file-generators/pwa-install.js.map +1 -1
- package/dist/lib/generators/file-generators/reset.js +6 -0
- package/dist/lib/generators/file-generators/reset.js.map +1 -0
- package/dist/lib/generators/file-generators/server-push.js +3 -134
- package/dist/lib/generators/file-generators/server-push.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-generator-build.js +4 -4
- package/dist/lib/generators/file-generators/sw-injector.js +9 -230
- package/dist/lib/generators/file-generators/sw-injector.js.map +1 -1
- package/dist/lib/generators/file-generators/type-definitions.js +2 -111
- package/dist/lib/generators/file-generators/type-definitions.js.map +1 -1
- package/dist/lib/generators/sw-generator.js +5 -5
- package/dist/lib/generators/sw-generator.js.map +1 -1
- package/dist/lib/generators/sw-sections/activate-handler.js +25 -3
- package/dist/lib/generators/sw-sections/activate-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/assemble-sw.js +13 -12
- package/dist/lib/generators/sw-sections/assemble-sw.js.map +1 -1
- package/dist/lib/generators/sw-sections/background-sync-handler.js +14 -7
- package/dist/lib/generators/sw-sections/background-sync-handler.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/fetch-handler.js +165 -104
- package/dist/lib/generators/sw-sections/fetch-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/glob-matcher-code.js.map +1 -0
- package/dist/lib/generators/sw-sections/server-push-handler.js +12 -0
- package/dist/lib/generators/sw-sections/server-push-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/tag-management.js +6 -4
- package/dist/lib/generators/sw-sections/tag-management.js.map +1 -1
- package/dist/lib/generators/swoff-files-generator.js +66 -35
- package/dist/lib/generators/swoff-files-generator.js.map +1 -1
- package/dist/lib/shared/config-types.js +89 -28
- package/dist/lib/shared/config-types.js.map +1 -1
- package/dist/runtime/api-config.js +18 -0
- package/dist/runtime/api-config.js.map +1 -0
- package/dist/runtime/auth-state.js +35 -0
- package/dist/runtime/auth-state.js.map +1 -0
- package/dist/runtime/auth-store.js +273 -0
- package/dist/runtime/auth-store.js.map +1 -0
- package/dist/runtime/auth-user.js +168 -0
- package/dist/runtime/auth-user.js.map +1 -0
- package/dist/runtime/background-sync.js +59 -0
- package/dist/runtime/background-sync.js.map +1 -0
- package/dist/runtime/cache.js +30 -0
- package/dist/runtime/cache.js.map +1 -0
- package/dist/runtime/client-injector.js +136 -0
- package/dist/runtime/client-injector.js.map +1 -0
- package/dist/runtime/fetch-state.js +42 -0
- package/dist/runtime/fetch-state.js.map +1 -0
- package/dist/runtime/fetch-wrapper.js +355 -0
- package/dist/runtime/fetch-wrapper.js.map +1 -0
- package/dist/runtime/gql-wrapper.js +135 -0
- package/dist/runtime/gql-wrapper.js.map +1 -0
- package/dist/runtime/invalidation-tags.js +260 -0
- package/dist/runtime/invalidation-tags.js.map +1 -0
- package/dist/runtime/mutation-queue.js +304 -0
- package/dist/runtime/mutation-queue.js.map +1 -0
- package/dist/runtime/mutation-state.js +117 -0
- package/dist/runtime/mutation-state.js.map +1 -0
- package/dist/runtime/push.js +138 -0
- package/dist/runtime/push.js.map +1 -0
- package/dist/runtime/pwa-index.js +11 -0
- package/dist/runtime/pwa-index.js.map +1 -0
- package/dist/runtime/pwa-injector.js +44 -0
- package/dist/runtime/pwa-injector.js.map +1 -0
- package/dist/runtime/pwa-install.js +83 -0
- package/dist/runtime/pwa-install.js.map +1 -0
- package/dist/runtime/pwa-prompt.js +54 -0
- package/dist/runtime/pwa-prompt.js.map +1 -0
- package/dist/runtime/reset.js +148 -0
- package/dist/runtime/reset.js.map +1 -0
- package/dist/runtime/server-push.js +148 -0
- package/dist/runtime/server-push.js.map +1 -0
- package/dist/runtime/sw-injector.js +236 -0
- package/dist/runtime/sw-injector.js.map +1 -0
- package/dist/runtime/type-definitions.js +138 -0
- package/dist/runtime/type-definitions.js.map +1 -0
- package/dist/runtime/utils.js +27 -0
- package/dist/runtime/utils.js.map +1 -0
- package/package.json +3 -2
- package/templates/react/useAuth.jsx +106 -0
- package/templates/react/useAuth.tsx +118 -0
- package/templates/{hooks → react}/useBackgroundSync.jsx +6 -4
- package/templates/{hooks → react}/useBackgroundSync.tsx +6 -4
- package/templates/{hooks → react}/useCacheInvalidation.jsx +2 -2
- package/templates/react/useCacheInvalidation.tsx +52 -0
- package/templates/react/useCachedFetch.jsx +140 -0
- package/templates/react/useCachedFetch.tsx +160 -0
- package/templates/react/useIsFetching.jsx +32 -0
- package/templates/react/useIsFetching.tsx +32 -0
- package/templates/react/useMutation.jsx +141 -0
- package/templates/react/useMutation.tsx +180 -0
- package/templates/react/useMutationQueue.jsx +69 -0
- package/templates/react/useMutationQueue.tsx +83 -0
- package/templates/react/useNetworkStatus.jsx +61 -0
- package/templates/react/useNetworkStatus.tsx +76 -0
- package/templates/react/usePrefetch.jsx +32 -0
- package/templates/react/usePrefetch.tsx +42 -0
- package/templates/{hooks → react}/usePushSubscription.jsx +4 -4
- package/templates/{hooks → react}/usePushSubscription.tsx +4 -4
- package/templates/{hooks → react}/useSWUpdate.jsx +3 -3
- package/templates/{hooks → react}/useSWUpdate.tsx +4 -4
- package/templates/react/useSwoffReset.jsx +32 -0
- package/templates/react/useSwoffReset.tsx +39 -0
- package/docs/API.md +0 -565
- package/docs/ARCHITECTURE.md +0 -374
- package/docs/CLI.md +0 -148
- package/docs/COMPARISON.md +0 -192
- package/docs/CONFIG.md +0 -277
- package/docs/ECOSYSTEM.md +0 -33
- package/templates/hooks/useAuth.jsx +0 -30
- package/templates/hooks/useAuth.tsx +0 -30
- package/templates/hooks/useCacheInvalidation.tsx +0 -19
- package/templates/hooks/useCachedFetch.jsx +0 -69
- package/templates/hooks/useCachedFetch.tsx +0 -81
- package/templates/hooks/useMutation.jsx +0 -76
- package/templates/hooks/useMutation.tsx +0 -109
- package/templates/hooks/useMutationQueue.jsx +0 -43
- package/templates/hooks/useMutationQueue.tsx +0 -50
- package/templates/hooks/useNetworkStatus.jsx +0 -19
- package/templates/hooks/useNetworkStatus.tsx +0 -19
- package/templates/hooks/usePrefetch.jsx +0 -10
- package/templates/hooks/usePrefetch.tsx +0 -25
- /package/templates/{hooks → react}/useMutationState.jsx +0 -0
- /package/templates/{hooks → react}/useMutationState.tsx +0 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { T, R } from "./utils.js";
|
|
2
|
+
export function generateServerPushCode(ctx, pushType, endpoint, reconnectDelayMs) {
|
|
3
|
+
const { ext, ts } = ctx;
|
|
4
|
+
const invalidate = `
|
|
5
|
+
// Forward to SW for cache invalidation
|
|
6
|
+
if (navigator.serviceWorker.controller) {
|
|
7
|
+
for (const tag of tags) {
|
|
8
|
+
navigator.serviceWorker.controller.postMessage({ type: "INVALIDATE_TAG", tag });
|
|
9
|
+
}
|
|
10
|
+
}`;
|
|
11
|
+
const sseConnect = `
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
fetch(API_BASE + "${endpoint}", {
|
|
14
|
+
headers: { Accept: "text/event-stream" },
|
|
15
|
+
credentials: "include",
|
|
16
|
+
signal: options.signal,
|
|
17
|
+
}).then(async (response) => {
|
|
18
|
+
if (!response.ok || !response.body) { resolve(); return; }
|
|
19
|
+
notifyStatus(true);
|
|
20
|
+
const reader = response.body.getReader();
|
|
21
|
+
const decoder = new TextDecoder();
|
|
22
|
+
let buffer = "";
|
|
23
|
+
let eventType = "";
|
|
24
|
+
let dataStr = "";
|
|
25
|
+
|
|
26
|
+
while (true) {
|
|
27
|
+
const { done, value } = await reader.read();
|
|
28
|
+
if (done) break;
|
|
29
|
+
buffer += decoder.decode(value, { stream: true });
|
|
30
|
+
const lines = buffer.split("\\n");
|
|
31
|
+
buffer = lines.pop() || "";
|
|
32
|
+
for (const line of lines) {
|
|
33
|
+
if (line.startsWith("event: ")) eventType = line.slice(7).trim();
|
|
34
|
+
else if (line.startsWith("data: ")) dataStr = line.slice(6);
|
|
35
|
+
else if (line === "" && eventType === "invalidate" && dataStr) {
|
|
36
|
+
try {
|
|
37
|
+
const p = JSON.parse(dataStr); if (p.tags) handleInvalidation(p.tags);
|
|
38
|
+
} catch {
|
|
39
|
+
// Handle invalidation data
|
|
40
|
+
}
|
|
41
|
+
eventType = ""; dataStr = "";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}).catch(() => {}).finally(() => {
|
|
46
|
+
notifyStatus(false);
|
|
47
|
+
resolve();
|
|
48
|
+
});
|
|
49
|
+
});`;
|
|
50
|
+
const wsConnect = `
|
|
51
|
+
return new Promise((resolve) => {
|
|
52
|
+
try {
|
|
53
|
+
const ws = new WebSocket(API_BASE + "${endpoint}");
|
|
54
|
+
ws.onopen = () => notifyStatus(true);
|
|
55
|
+
ws.onmessage = (event) => {
|
|
56
|
+
try { const d = JSON.parse(event.data); if (d.type === "invalidate" && d.tags) handleInvalidation(d.tags); } catch {}
|
|
57
|
+
};
|
|
58
|
+
ws.onclose = () => { notifyStatus(false); resolve(); };
|
|
59
|
+
ws.onerror = () => { ws.close(); resolve(); };
|
|
60
|
+
if (options.signal) {
|
|
61
|
+
options.signal.addEventListener("abort", () => ws.close());
|
|
62
|
+
}
|
|
63
|
+
} catch { resolve(); }
|
|
64
|
+
});`;
|
|
65
|
+
return `/**
|
|
66
|
+
* Swoff Server Push Events
|
|
67
|
+
*
|
|
68
|
+
* The service worker connects to ${endpoint} and invalidates cache tags
|
|
69
|
+
* when the server sends "invalidate" events — no polling needed.
|
|
70
|
+
* This client-side helper provides status tracking and a manual start/stop API.
|
|
71
|
+
*
|
|
72
|
+
* Usage:
|
|
73
|
+
* import { startPushEvents, stopPushEvents, isPushConnected } from "./realtime/server-push.${ext}";
|
|
74
|
+
* startPushEvents();
|
|
75
|
+
*
|
|
76
|
+
* Server sends:
|
|
77
|
+
* event: invalidate
|
|
78
|
+
* data: {"tags": ["todos", "todo:42"]}
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
import { API_BASE } from "../config.${ext}";
|
|
82
|
+
|
|
83
|
+
type PushEventOptions= {
|
|
84
|
+
signal${T(ts, "AbortSignal")};
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
let active${T(ts, "boolean")} = false;
|
|
88
|
+
let swConnected${T(ts, "boolean")} = false;
|
|
89
|
+
let reconnectTimer${T(ts, "ReturnType<typeof setTimeout> | null")} = null;
|
|
90
|
+
|
|
91
|
+
function handleInvalidation(tags${T(ts, "string[]")})${R(ts, "void")}{${invalidate}
|
|
92
|
+
window.dispatchEvent(new CustomEvent("cache-invalidated", { detail: { tags } }));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function notifyStatus(connected${T(ts, "boolean")})${R(ts, "void")}{
|
|
96
|
+
window.dispatchEvent(new CustomEvent("push-events-status", { detail: { connected } }));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Listen for SSE status from the SW
|
|
100
|
+
if (typeof navigator !== "undefined" && navigator.serviceWorker) {
|
|
101
|
+
navigator.serviceWorker.addEventListener("message", (event) => {
|
|
102
|
+
if (event.data?.type === "SSE_STATUS") {
|
|
103
|
+
swConnected = event.data.connected;
|
|
104
|
+
notifyStatus(swConnected);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function connect(options${T(ts, "PushEventOptions")} = {} as PushEventOptions)${R(ts, "Promise<void>")}{
|
|
110
|
+
${pushType === "sse" ? sseConnect : wsConnect}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Start listening for server push events. Only connects when the SW is not active — the SW is the primary connection manager. Retries on connection loss with exponential backoff. */
|
|
114
|
+
export async function startPushEvents(){
|
|
115
|
+
if (active) return;
|
|
116
|
+
|
|
117
|
+
// If SW is already controlling the page, skip client-side connection — the SW handles push events.
|
|
118
|
+
if (navigator.serviceWorker.controller) return;
|
|
119
|
+
|
|
120
|
+
// Listen for SW activation — if SW takes over, disconnect the client fallback.
|
|
121
|
+
const onControllerChange = () => { stopPushEvents(); };
|
|
122
|
+
navigator.serviceWorker.addEventListener("controllerchange", onControllerChange);
|
|
123
|
+
|
|
124
|
+
active = true;
|
|
125
|
+
let delay = ${reconnectDelayMs};
|
|
126
|
+
while (active) {
|
|
127
|
+
await connect();
|
|
128
|
+
if (!active) break;
|
|
129
|
+
await new Promise((r) => { reconnectTimer = setTimeout(r, delay); });
|
|
130
|
+
delay = Math.min(delay * 1.5, 30000); // cap at 30s
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
navigator.serviceWorker.removeEventListener("controllerchange", onControllerChange);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Stop listening for push events. */
|
|
137
|
+
export function stopPushEvents(){
|
|
138
|
+
active = false;
|
|
139
|
+
if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Check if the push connection is currently established. */
|
|
143
|
+
export function isPushConnected(){
|
|
144
|
+
return active || swConnected;
|
|
145
|
+
}
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=server-push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-push.js","sourceRoot":"","sources":["../../src/runtime/server-push.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,UAAU,sBAAsB,CACpC,GAAmB,EACnB,QAAgB,EAChB,QAAgB,EAChB,gBAAwB;IAExB,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC;IAExB,MAAM,UAAU,GAAG;;;;;;IAMjB,CAAC;IAEH,MAAM,UAAU,GAAG;;wBAEG,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAoC1B,CAAC;IAEL,MAAM,SAAS,GAAG;;;6CAGyB,QAAQ;;;;;;;;;;;MAW/C,CAAC;IAEL,OAAO;;;oCAG2B,QAAQ;;;;;gGAKoD,GAAG;;;;;;;;sCAQ7D,GAAG;;;UAG/B,CAAC,CAAC,EAAE,EAAE,aAAa,CAAC;;;YAGlB,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC;iBACX,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC;oBACb,CAAC,CAAC,EAAE,EAAE,sCAAsC,CAAC;;kCAE/B,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,UAAU;;;;iCAIjD,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC;;;;;;;;;;;;;;gCAclC,CAAC,CAAC,EAAE,EAAE,kBAAkB,CAAC,6BAA6B,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC;IACxG,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;;;;;;;;;;;;;;;gBAe/B,gBAAgB;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { T, R } from "./utils.js";
|
|
2
|
+
export function generateSwInjectorCode(ctx) {
|
|
3
|
+
const { ext, ts, autoUpdate, autoActivate, versionEnabled } = ctx;
|
|
4
|
+
if (!versionEnabled) {
|
|
5
|
+
return `/**
|
|
6
|
+
* Swoff SW Injector (Simple Mode)
|
|
7
|
+
* Fixed SW URL with hash-based cache name — no versioned URLs or update events.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { initServiceWorker } from './swoff/sw/injector.${ext}';
|
|
11
|
+
* initServiceWorker();
|
|
12
|
+
*
|
|
13
|
+
* Window events:
|
|
14
|
+
* sw-ready - SW active and controlling page
|
|
15
|
+
* sw-error - SW registration failed
|
|
16
|
+
*
|
|
17
|
+
* Window properties:
|
|
18
|
+
* window.currentSWVersion - "simple"
|
|
19
|
+
* window.swReady - SW is active
|
|
20
|
+
* window.swError - Registration failed
|
|
21
|
+
*/
|
|
22
|
+
async function waitForController()${R(ts, "Promise<void>")}{
|
|
23
|
+
return new Promise<void>((resolve) => {
|
|
24
|
+
if (navigator.serviceWorker.controller) {
|
|
25
|
+
resolve();
|
|
26
|
+
} else {
|
|
27
|
+
const timeout = setTimeout(() => resolve(), 30000);
|
|
28
|
+
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
|
29
|
+
clearTimeout(timeout);
|
|
30
|
+
resolve();
|
|
31
|
+
}, { once: true });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Register the SW with a fixed URL (non-versioned mode). Dispatches sw-ready/sw-error. */
|
|
37
|
+
export async function initServiceWorker()${R(ts, "Promise<void>")}{
|
|
38
|
+
if (!("serviceWorker" in navigator)) {
|
|
39
|
+
console.warn("Service Workers not supported");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const registration = await navigator.serviceWorker.register("/sw.js");
|
|
44
|
+
window.currentSWVersion = "simple";
|
|
45
|
+
window.dispatchEvent(new CustomEvent("sw-version-detected"));
|
|
46
|
+
await waitForController();
|
|
47
|
+
window.dispatchEvent(new CustomEvent("sw-ready"));
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error("Service Worker registration failed:", error);
|
|
50
|
+
window.swError = true;
|
|
51
|
+
window.dispatchEvent(new CustomEvent("sw-error"));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
return `/**
|
|
57
|
+
* Swoff SW Injector
|
|
58
|
+
* Framework-agnostic SW registration with versioned URLs and update flow.
|
|
59
|
+
*
|
|
60
|
+
* Usage:
|
|
61
|
+
* import { initServiceWorker } from './swoff/sw/injector.${ext}';
|
|
62
|
+
* initServiceWorker();
|
|
63
|
+
*
|
|
64
|
+
* Window events:
|
|
65
|
+
* sw-version-detected - Version info available on window
|
|
66
|
+
* sw-update-available - New version ready for user consent (detail: { version })
|
|
67
|
+
* sw-progress - Download progress (detail: { percent, downloaded, total })
|
|
68
|
+
* sw-ready - SW active and controlling page
|
|
69
|
+
* sw-error - SW registration failed
|
|
70
|
+
*
|
|
71
|
+
* Window properties:
|
|
72
|
+
* window.latestSWVersion - Latest version from version.json
|
|
73
|
+
* window.currentSWVersion - Active SW version
|
|
74
|
+
* window.swAvailableVersion - Pending update version
|
|
75
|
+
* window.swUpdateRequired - Forced update needed (version < minSupportedVersion)
|
|
76
|
+
* window.swMinSupportedVersion - Minimum supported version
|
|
77
|
+
* window.swReady - SW is active
|
|
78
|
+
* window.swError - Registration failed
|
|
79
|
+
*/
|
|
80
|
+
const AUTO_UPDATE = ${autoUpdate};
|
|
81
|
+
const AUTO_ACTIVATE = ${autoActivate};
|
|
82
|
+
|
|
83
|
+
function semverCompare(a${T(ts, "string")}, b${T(ts, "string")})${R(ts, "number")}{
|
|
84
|
+
const pa = a.split('.').map(Number);
|
|
85
|
+
const pb = b.split('.').map(Number);
|
|
86
|
+
for (let i = 0; i < 3; i++) {
|
|
87
|
+
if (pa[i] > pb[i]) return 1;
|
|
88
|
+
if (pa[i] < pb[i]) return -1;
|
|
89
|
+
}
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function checkForUpdate() {
|
|
94
|
+
const response = await fetch("/version.json?t=" + Date.now());
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
throw new Error("Failed to fetch version.json");
|
|
97
|
+
}
|
|
98
|
+
return response.json();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function waitForController()${R(ts, "Promise<void>")}{
|
|
102
|
+
return new Promise<void>((resolve) => {
|
|
103
|
+
if (navigator.serviceWorker.controller) {
|
|
104
|
+
resolve();
|
|
105
|
+
} else {
|
|
106
|
+
const timeout = setTimeout(() => resolve(), 30000);
|
|
107
|
+
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
|
108
|
+
clearTimeout(timeout);
|
|
109
|
+
resolve();
|
|
110
|
+
}, { once: true });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function doRegisterServiceWorker(version${T(ts, "string")})${R(ts, "Promise<ServiceWorkerRegistration>")}{
|
|
116
|
+
const swUrl = \`/sw-v\${version}.js\`;
|
|
117
|
+
const registration = await navigator.serviceWorker.register(swUrl);
|
|
118
|
+
localStorage.setItem("swRegisteredVersion", version);
|
|
119
|
+
window.currentSWVersion = version;
|
|
120
|
+
window.swRegisteredVersion = version;
|
|
121
|
+
window.dispatchEvent(new CustomEvent("sw-version-detected"));
|
|
122
|
+
await waitForController();
|
|
123
|
+
window.dispatchEvent(new CustomEvent("sw-ready"));
|
|
124
|
+
return registration;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Register the SW with version checking and update flow. Checks version.json, handles updates, and dispatches sw-ready/sw-error events. */
|
|
128
|
+
export async function initServiceWorker()${R(ts, "Promise<void>")}{
|
|
129
|
+
if (!("serviceWorker" in navigator)) {
|
|
130
|
+
console.warn("Service Workers not supported");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const manifest = await checkForUpdate();
|
|
136
|
+
const currentVersion = localStorage.getItem("swRegisteredVersion");
|
|
137
|
+
window.latestSWVersion = manifest.version;
|
|
138
|
+
window.swMinSupportedVersion = manifest.minSupportedVersion || "0.0.0";
|
|
139
|
+
|
|
140
|
+
if (currentVersion === manifest.version) {
|
|
141
|
+
const registration = await navigator.serviceWorker.getRegistration();
|
|
142
|
+
if (registration && registration.active) {
|
|
143
|
+
window.currentSWVersion = currentVersion ?? undefined;
|
|
144
|
+
window.dispatchEvent(new CustomEvent("sw-version-detected"));
|
|
145
|
+
await waitForController();
|
|
146
|
+
if (!window.swReady) {
|
|
147
|
+
window.dispatchEvent(new CustomEvent("sw-ready"));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
} else if (currentVersion && currentVersion !== manifest.version) {
|
|
151
|
+
window.swAvailableVersion = manifest.version;
|
|
152
|
+
window.swUpdateRequired =
|
|
153
|
+
semverCompare(currentVersion, manifest.minSupportedVersion || "0.0.0") < 0;
|
|
154
|
+
|
|
155
|
+
if (AUTO_UPDATE) {
|
|
156
|
+
const registration = await navigator.serviceWorker.getRegistration();
|
|
157
|
+
if (registration && registration.waiting) {
|
|
158
|
+
if (AUTO_ACTIVATE) {
|
|
159
|
+
registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
160
|
+
} else {
|
|
161
|
+
window.dispatchEvent(
|
|
162
|
+
new CustomEvent("sw-update-available", {
|
|
163
|
+
detail: { version: manifest.version },
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
const newReg = await doRegisterServiceWorker(manifest.version);
|
|
169
|
+
if (AUTO_ACTIVATE && newReg.waiting) {
|
|
170
|
+
newReg.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
171
|
+
} else {
|
|
172
|
+
window.dispatchEvent(
|
|
173
|
+
new CustomEvent("sw-update-available", {
|
|
174
|
+
detail: { version: manifest.version },
|
|
175
|
+
})
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
window.dispatchEvent(
|
|
181
|
+
new CustomEvent("sw-update-available", {
|
|
182
|
+
detail: { version: manifest.version },
|
|
183
|
+
})
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
await doRegisterServiceWorker(manifest.version);
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
try {
|
|
191
|
+
const existing = await navigator.serviceWorker.getRegistration();
|
|
192
|
+
if (existing && existing.active) {
|
|
193
|
+
window.currentSWVersion = localStorage.getItem("swRegisteredVersion") || "unknown";
|
|
194
|
+
window.dispatchEvent(new CustomEvent("sw-version-detected"));
|
|
195
|
+
await waitForController();
|
|
196
|
+
if (!window.swReady) {
|
|
197
|
+
window.dispatchEvent(new CustomEvent("sw-ready"));
|
|
198
|
+
}
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
} catch {
|
|
202
|
+
// Handle the case where no existing active registration is found
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
console.error("Service Worker initialization failed:", error);
|
|
206
|
+
window.swError = true;
|
|
207
|
+
window.dispatchEvent(new CustomEvent("sw-error"));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Accept a pending SW update. Reloads the page once the new SW takes control. */
|
|
212
|
+
export async function handleUpdateApproved(newVersion${T(ts, "string")})${R(ts, "Promise<void>")}{
|
|
213
|
+
const registration = await navigator.serviceWorker.getRegistration();
|
|
214
|
+
if (registration && registration.waiting) {
|
|
215
|
+
registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
216
|
+
registration.addEventListener("controllerchange", () => {
|
|
217
|
+
window.location.reload();
|
|
218
|
+
});
|
|
219
|
+
} else {
|
|
220
|
+
await doRegisterServiceWorker(newVersion);
|
|
221
|
+
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
|
222
|
+
window.location.reload();
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Activate a waiting SW without reloading. Useful when you handle the transition yourself. */
|
|
228
|
+
export async function skipWaiting()${R(ts, "Promise<void>")}{
|
|
229
|
+
const registration = await navigator.serviceWorker.ready;
|
|
230
|
+
if (registration.waiting) {
|
|
231
|
+
registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
`;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=sw-injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sw-injector.js","sourceRoot":"","sources":["../../src/runtime/sw-injector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,UAAU,sBAAsB,CACpC,GAA6F;IAE7F,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC;IAElE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO;;;;;8DAKmD,GAAG;;;;;;;;;;;;oCAY7B,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC;;;;;;;;;;;;;;;2CAef,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC;;;;;;;;;;;;;;;;;CAiBhE,CAAC;IACA,CAAC;IAED,OAAO;;;;;8DAKqD,GAAG;;;;;;;;;;;;;;;;;;;sBAmB3C,UAAU;wBACR,YAAY;;0BAEV,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC;;;;;;;;;;;;;;;;;;oCAkB7C,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC;;;;;;;;;;;;;;gDAcV,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,oCAAoC,CAAC;;;;;;;;;;;;;2CAanE,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uDAoFV,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC;;;;;;;;;;;;;;;;qCAgB3D,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC;;;;;;CAM1D,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
export function generateTypeDefinitionsCode() {
|
|
2
|
+
return `
|
|
3
|
+
// Background Sync API types
|
|
4
|
+
interface SyncManager {
|
|
5
|
+
register(tag: string): Promise<void>;
|
|
6
|
+
getTags(): Promise<string[]>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface SyncEvent extends Event {
|
|
10
|
+
readonly tag: string;
|
|
11
|
+
readonly lastChance: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ServiceWorkerGlobalScope {
|
|
15
|
+
onsync: ((this: ServiceWorkerGlobalScope, ev: SyncEvent) => unknown) | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare global {
|
|
19
|
+
// Network Information API
|
|
20
|
+
interface NetworkInformation extends EventTarget {
|
|
21
|
+
readonly effectiveType: "slow-2g" | "2g" | "3g" | "4g";
|
|
22
|
+
readonly type: "bluetooth" | "cellular" | "ethernet" | "none" | "wifi" | "wimax" | "other" | "unknown";
|
|
23
|
+
readonly downlink: number;
|
|
24
|
+
readonly downlinkMax: number;
|
|
25
|
+
readonly rtt: number;
|
|
26
|
+
readonly saveData: boolean;
|
|
27
|
+
onchange: ((this: NetworkInformation, ev: Event) => unknown) | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface Navigator {
|
|
31
|
+
readonly connection?: NetworkInformation;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface BeforeInstallPromptEvent extends Event {
|
|
35
|
+
prompt(): Promise<void>;
|
|
36
|
+
userChoice: Promise<{ outcome: "accepted" | "dismissed" }>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface WindowEventMap {
|
|
40
|
+
beforeinstallprompt: BeforeInstallPromptEvent;
|
|
41
|
+
"sw-update-available": CustomEvent<{ version: string }>;
|
|
42
|
+
"sw-progress": CustomEvent<{ percent: number; downloaded: number; total: number }>;
|
|
43
|
+
"sw-ready": CustomEvent;
|
|
44
|
+
"sw-error": CustomEvent;
|
|
45
|
+
"sw-version-detected": CustomEvent;
|
|
46
|
+
"sw-auth-state-change": CustomEvent;
|
|
47
|
+
"mutation-sync-complete": CustomEvent<{ succeeded: number; failed: number }>;
|
|
48
|
+
"mutation-queue-changed": CustomEvent;
|
|
49
|
+
"cache-invalidated": CustomEvent<{ tags?: string[] }>;
|
|
50
|
+
"fetch-count-changed": CustomEvent<{ count: number }>;
|
|
51
|
+
"mutation-state-changed": CustomEvent<{ id: string; status: string; error?: Error; data?: unknown }>;
|
|
52
|
+
"background-sync-complete": CustomEvent<{ succeeded: number; failed: number }>;
|
|
53
|
+
"swoff:reset-start": CustomEvent;
|
|
54
|
+
"swoff:reset-complete": CustomEvent<{ unregistered: boolean; reregistered: boolean; warnings: string[] }>;
|
|
55
|
+
"push-subscription-changed": CustomEvent<{ subscribed: boolean }>;
|
|
56
|
+
"push-permission-changed": CustomEvent<{ permission: NotificationPermission }>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface Window {
|
|
60
|
+
deferredInstallPrompt: BeforeInstallPromptEvent | null;
|
|
61
|
+
pwaInstallable?: boolean;
|
|
62
|
+
latestSWVersion?: string;
|
|
63
|
+
currentSWVersion?: string;
|
|
64
|
+
swRegisteredVersion?: string;
|
|
65
|
+
swAvailableVersion?: string;
|
|
66
|
+
swUpdateRequired?: boolean;
|
|
67
|
+
swMinSupportedVersion?: string;
|
|
68
|
+
swReady?: boolean;
|
|
69
|
+
swError?: boolean;
|
|
70
|
+
swAuthState?: "authenticated" | "unauthenticated" | "loading";
|
|
71
|
+
swCurrentUser?: Record<string, unknown> | null;
|
|
72
|
+
SyncManager?: { new(): SyncManager };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Extend ServiceWorkerRegistration in the global scope for TS
|
|
76
|
+
interface ServiceWorkerRegistration {
|
|
77
|
+
readonly sync: SyncManager;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface FetchWithCacheOptions extends RequestInit {
|
|
82
|
+
strategy?: "read" | "mutation";
|
|
83
|
+
tags?: string[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type MutationStatus = "idle" | "pending" | "success" | "error";
|
|
87
|
+
|
|
88
|
+
export interface MutationState {
|
|
89
|
+
id: string;
|
|
90
|
+
status: MutationStatus;
|
|
91
|
+
error: Error | null;
|
|
92
|
+
data: unknown;
|
|
93
|
+
timestamp: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface ResetSwoffOptions {
|
|
97
|
+
clearCache?: boolean;
|
|
98
|
+
clearIdb?: boolean;
|
|
99
|
+
clearStorage?: boolean;
|
|
100
|
+
unregisterSW?: boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface GqlOptions {
|
|
104
|
+
variables?: Record<string, unknown>;
|
|
105
|
+
tags?: string[];
|
|
106
|
+
auth?: boolean;
|
|
107
|
+
queueOffline?: boolean;
|
|
108
|
+
invalidate?: 'auto' | string[] | false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface GqlResult<T> {
|
|
112
|
+
data: T;
|
|
113
|
+
fromCache: boolean;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface MutationQueueItem {
|
|
117
|
+
id: string;
|
|
118
|
+
method: string;
|
|
119
|
+
url: string;
|
|
120
|
+
body: unknown;
|
|
121
|
+
bodyType?: "json" | "formdata" | "blob" | "buffer" | "text";
|
|
122
|
+
headers: Record<string, string>;
|
|
123
|
+
timestamp: number;
|
|
124
|
+
retryCount: number;
|
|
125
|
+
nextRetryAt?: number;
|
|
126
|
+
tags: string[];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface MutationQueueResult {
|
|
130
|
+
succeeded: number;
|
|
131
|
+
failed: number;
|
|
132
|
+
total?: number;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export {};
|
|
136
|
+
`;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=type-definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-definitions.js","sourceRoot":"","sources":["../../src/runtime/type-definitions.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,2BAA2B;IACzC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsIR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function T(ts, type) {
|
|
2
|
+
return ts ? `: ${type}` : "";
|
|
3
|
+
}
|
|
4
|
+
export function R(ts, type) {
|
|
5
|
+
return ts ? `: ${type} ` : " ";
|
|
6
|
+
}
|
|
7
|
+
export function G(ts, type) {
|
|
8
|
+
return ts ? `<${type}>` : "";
|
|
9
|
+
}
|
|
10
|
+
/** Generic type parameter (alias for G) */
|
|
11
|
+
export function PT(ts, type) {
|
|
12
|
+
return G(ts, type);
|
|
13
|
+
}
|
|
14
|
+
/** Type assertion */
|
|
15
|
+
export function AS(ts, type) {
|
|
16
|
+
return ts ? ` as ${type}` : "";
|
|
17
|
+
}
|
|
18
|
+
export function genHelpers(ctx) {
|
|
19
|
+
return {
|
|
20
|
+
T: (type) => T(ctx.ts, type),
|
|
21
|
+
R: (type) => R(ctx.ts, type),
|
|
22
|
+
G: (type) => G(ctx.ts, type),
|
|
23
|
+
PT: (type) => PT(ctx.ts, type),
|
|
24
|
+
AS: (type) => AS(ctx.ts, type),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/runtime/utils.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,CAAC,CAAC,EAAW,EAAE,IAAY;IACzC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,CAAC,CAAC,EAAW,EAAE,IAAY;IACzC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,CAAC,CAAC,EAAW,EAAE,IAAY;IACzC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/B,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,EAAE,CAAC,EAAW,EAAE,IAAY;IAC1C,OAAO,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,qBAAqB;AACrB,MAAM,UAAU,EAAE,CAAC,EAAW,EAAE,IAAY;IAC1C,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAmB;IAC5C,OAAO;QACL,CAAC,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC;QACpC,CAAC,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC;QACpC,CAAC,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC;QACpC,EAAE,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC;QACtC,EAAE,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC;KACvC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swoff/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for Swoff - Offline-first web apps made easy",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"bin/",
|
|
21
21
|
"dist/",
|
|
22
|
-
"docs/",
|
|
23
22
|
"templates/"
|
|
24
23
|
],
|
|
25
24
|
"keywords": [
|
|
@@ -32,7 +31,9 @@
|
|
|
32
31
|
"license": "MIT",
|
|
33
32
|
"dependencies": {},
|
|
34
33
|
"devDependencies": {
|
|
34
|
+
"@resvg/resvg-wasm": "^2.6.2",
|
|
35
35
|
"@types/node": "^25.9.1",
|
|
36
|
+
"jimp": "^1.6.0",
|
|
36
37
|
"typescript": "^5.0.0",
|
|
37
38
|
"vitest": "^4.1.7"
|
|
38
39
|
}
|