@swoff/cli 0.3.8 → 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/README.md +47 -33
- package/dist/__tests__/assemble-sw.test.js +14 -53
- package/dist/__tests__/assemble-sw.test.js.map +1 -1
- package/dist/__tests__/cli-integration.test.js +119 -11
- package/dist/__tests__/cli-integration.test.js.map +1 -1
- package/dist/__tests__/config-types.test.js +44 -17
- 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__/glob-matcher.test.js +86 -0
- package/dist/__tests__/glob-matcher.test.js.map +1 -0
- package/dist/__tests__/invalidation-tags.test.js +207 -23
- package/dist/__tests__/invalidation-tags.test.js.map +1 -1
- package/dist/__tests__/loader.test.js +16 -12
- package/dist/__tests__/loader.test.js.map +1 -1
- package/dist/__tests__/validator.test.js +140 -100
- package/dist/__tests__/validator.test.js.map +1 -1
- package/dist/index.js +39 -34
- package/dist/index.js.map +1 -1
- package/dist/lib/cli/help.js +12 -12
- package/dist/lib/cli/help.js.map +1 -1
- package/dist/lib/commands/add.js +84 -36
- 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 +32 -30
- 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 +17 -24
- package/dist/lib/commands/generate.js.map +1 -1
- package/dist/lib/commands/info.js +41 -48
- package/dist/lib/commands/info.js.map +1 -1
- package/dist/lib/commands/init.js +27 -13
- package/dist/lib/commands/init.js.map +1 -1
- package/dist/lib/commands/validate.js +4 -4
- package/dist/lib/commands/validate.js.map +1 -1
- package/dist/lib/config/loader.js +25 -23
- package/dist/lib/config/loader.js.map +1 -1
- package/dist/lib/config/validator.js +169 -91
- 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 -38
- package/dist/lib/generators/file-generators/cache.js.map +1 -1
- package/dist/lib/generators/file-generators/client-injector.js +2 -91
- 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 -267
- 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 -145
- package/dist/lib/generators/file-generators/gql-wrapper.js.map +1 -1
- package/dist/lib/generators/file-generators/guide-generator.js +24 -630
- package/dist/lib/generators/file-generators/guide-generator.js.map +1 -1
- package/dist/lib/generators/file-generators/invalidation-tags.js +18 -86
- package/dist/lib/generators/file-generators/invalidation-tags.js.map +1 -1
- package/dist/lib/generators/file-generators/manifest.js +15 -5
- package/dist/lib/generators/file-generators/manifest.js.map +1 -1
- package/dist/lib/generators/file-generators/mutation-queue.js +3 -285
- 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 -139
- 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/quick-readme.js +8 -125
- package/dist/lib/generators/file-generators/quick-readme.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 -124
- package/dist/lib/generators/file-generators/server-push.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-generator-build.js +8 -9
- package/dist/lib/generators/file-generators/sw-generator-build.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-injector.js +10 -230
- package/dist/lib/generators/file-generators/sw-injector.js.map +1 -1
- package/dist/lib/generators/file-generators/type-definitions.js +2 -114
- package/dist/lib/generators/file-generators/type-definitions.js.map +1 -1
- package/dist/lib/generators/sw-generator.js +10 -20
- 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 +20 -16
- package/dist/lib/generators/sw-sections/assemble-sw.js.map +1 -1
- package/dist/lib/generators/sw-sections/background-sync-handler.js +68 -19
- package/dist/lib/generators/sw-sections/background-sync-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/config-header.js +2 -2
- package/dist/lib/generators/sw-sections/config-header.js.map +1 -1
- package/dist/lib/generators/sw-sections/fetch-handler.js +506 -144
- 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/message-handler.js +55 -15
- package/dist/lib/generators/sw-sections/message-handler.js.map +1 -1
- 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/sw-push.js +67 -0
- package/dist/lib/generators/sw-sections/sw-push.js.map +1 -0
- package/dist/lib/generators/sw-sections/tag-management.js +65 -23
- package/dist/lib/generators/sw-sections/tag-management.js.map +1 -1
- package/dist/lib/generators/swoff-files-generator.js +66 -45
- package/dist/lib/generators/swoff-files-generator.js.map +1 -1
- package/dist/lib/shared/config-types.js +182 -71
- package/dist/lib/shared/config-types.js.map +1 -1
- package/dist/lib/shared/glob-matcher.js +77 -0
- package/dist/lib/shared/glob-matcher.js.map +1 -0
- package/dist/lib/utils/tty-status.js +21 -0
- package/dist/lib/utils/tty-status.js.map +1 -0
- 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 -1
- 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/useMutationState.jsx +13 -0
- package/templates/react/useMutationState.tsx +25 -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 +7 -7
- package/templates/{hooks → react}/usePushSubscription.tsx +7 -7
- 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/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 -94
- package/templates/hooks/useCachedFetch.tsx +0 -112
- package/templates/hooks/useMutation.jsx +0 -76
- package/templates/hooks/useMutation.tsx +0 -97
- package/templates/hooks/useMutationQueue.jsx +0 -42
- package/templates/hooks/useMutationQueue.tsx +0 -49
- package/templates/hooks/useMutationState.jsx +0 -27
- package/templates/hooks/useMutationState.tsx +0 -41
- 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
|
@@ -4,123 +4,8 @@
|
|
|
4
4
|
* enabling useMutation-style hooks and fine-grained mutation status UI.
|
|
5
5
|
*/
|
|
6
6
|
import { writeFile } from "./context.js";
|
|
7
|
+
import { generateMutationStateCode } from "../../../runtime/mutation-state.js";
|
|
7
8
|
export function generateMutationState(ctx) {
|
|
8
|
-
|
|
9
|
-
const ts = ext === "ts";
|
|
10
|
-
const T = (type) => (ts ? `: ${type}` : "");
|
|
11
|
-
const R = (type) => (ts ? `: ${type}` : " ");
|
|
12
|
-
const code = `/**
|
|
13
|
-
* Swoff Mutation State
|
|
14
|
-
* Lightweight in-memory mutation state tracker.
|
|
15
|
-
* Enables per-mutation status UI (loading spinners, error states, success indicators).
|
|
16
|
-
*
|
|
17
|
-
* Usage:
|
|
18
|
-
* import { trackMutation, getMutationState, clearMutationState } from './swoff/mutation-state.${ext}';
|
|
19
|
-
*
|
|
20
|
-
* // After queueing a mutation
|
|
21
|
-
* const id = "mutation-" + crypto.randomUUID();
|
|
22
|
-
* trackMutation(id, "pending");
|
|
23
|
-
*
|
|
24
|
-
* // Check state later
|
|
25
|
-
* const state = getMutationState(id);
|
|
26
|
-
* if (state?.status === "error") { showError(state.error); }
|
|
27
|
-
*
|
|
28
|
-
* // Clear when done
|
|
29
|
-
* clearMutationState(id);
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
export type MutationStatus = "idle" | "pending" | "success" | "error";
|
|
33
|
-
|
|
34
|
-
export interface MutationState {
|
|
35
|
-
id${T("string")};
|
|
36
|
-
status${T("MutationStatus")};
|
|
37
|
-
error${T("Error | null")};
|
|
38
|
-
data${T("unknown")};
|
|
39
|
-
timestamp${T("number")};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const mutations = new Map<string, MutationState>();
|
|
43
|
-
|
|
44
|
-
let listenerId = 0;
|
|
45
|
-
const listeners = new Map<number, (state: MutationState) => void>();
|
|
46
|
-
|
|
47
|
-
/** Track a mutation with the given ID and initial status. */
|
|
48
|
-
export function trackMutation(id${T("string")}, status${T("MutationStatus")} = "idle")${R("MutationState")}{
|
|
49
|
-
let state = mutations.get(id);
|
|
50
|
-
if (!state) {
|
|
51
|
-
state = { id, status, error: null, data: null, timestamp: Date.now() };
|
|
52
|
-
mutations.set(id, state);
|
|
53
|
-
} else {
|
|
54
|
-
state.status = status;
|
|
55
|
-
state.timestamp = Date.now();
|
|
56
|
-
}
|
|
57
|
-
notifyListeners(state);
|
|
58
|
-
window.dispatchEvent(new CustomEvent("mutation-state-changed", { detail: state }));
|
|
59
|
-
return state;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Update an existing mutation's state. */
|
|
63
|
-
export function updateMutationState(id${T("string")}, partial${T("Partial<MutationState>")})${R("MutationState | null")}{
|
|
64
|
-
const state = mutations.get(id);
|
|
65
|
-
if (!state) return null;
|
|
66
|
-
Object.assign(state, partial);
|
|
67
|
-
state.timestamp = Date.now();
|
|
68
|
-
notifyListeners(state);
|
|
69
|
-
window.dispatchEvent(new CustomEvent("mutation-state-changed", { detail: state }));
|
|
70
|
-
return state;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** Mark a mutation as successful with optional data. */
|
|
74
|
-
export function resolveMutation(id${T("string")}, data${T("unknown")} = null)${R("void")}{
|
|
75
|
-
updateMutationState(id, { status: "success", data, error: null });
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Mark a mutation as failed with an error. */
|
|
79
|
-
export function rejectMutation(id${T("string")}, error${T("Error")})${R("void")}{
|
|
80
|
-
updateMutationState(id, { status: "error", error });
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** Get the current state of a mutation by ID. */
|
|
84
|
-
export function getMutationState(id${T("string")})${R("MutationState | undefined")}{
|
|
85
|
-
return mutations.get(id);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Remove a mutation's state from the tracker. */
|
|
89
|
-
export function clearMutationState(id${T("string")})${R("void")}{
|
|
90
|
-
mutations.delete(id);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** Get all tracked mutations. */
|
|
94
|
-
export function getAllMutationStates()${R("MutationState[]")}{
|
|
95
|
-
return Array.from(mutations.values());
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** Get the count of mutations in a given status. */
|
|
99
|
-
export function getMutationCount(status${T("MutationStatus")})${R("number")}{
|
|
100
|
-
let count = 0;
|
|
101
|
-
for (const state of mutations.values()) {
|
|
102
|
-
if (state.status === status) count++;
|
|
103
|
-
}
|
|
104
|
-
return count;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Subscribe to mutation state changes. Returns an unsubscribe function. */
|
|
108
|
-
export function onMutationStateChange(callback${T("(state: MutationState) => void")})${R("() => void")}{
|
|
109
|
-
const id = ++listenerId;
|
|
110
|
-
listeners.set(id, callback);
|
|
111
|
-
return () => { listeners.delete(id); };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function notifyListeners(state${T("MutationState")})${R("void")}{
|
|
115
|
-
for (const cb of listeners.values()) {
|
|
116
|
-
try {
|
|
117
|
-
cb(state);
|
|
118
|
-
} catch {
|
|
119
|
-
// Handle listener errors silently
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
`;
|
|
124
|
-
writeFile(ctx, `mutation-state.${ext}`, code);
|
|
9
|
+
writeFile(ctx, `offline/state.${ctx.ext}`, generateMutationStateCode({ ts: ctx.ext === "ts", ext: ctx.ext }));
|
|
125
10
|
}
|
|
126
11
|
//# sourceMappingURL=mutation-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutation-state.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/mutation-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"mutation-state.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/mutation-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAE/E,MAAM,UAAU,qBAAqB,CAAC,GAAqB;IACzD,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,CAAC,GAAG,EAAE,EAAE,yBAAyB,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAChH,CAAC"}
|
|
@@ -1,143 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates push.{js|ts} - push notification subscription management.
|
|
3
|
-
*/
|
|
4
1
|
import { writeFile } from "./context.js";
|
|
2
|
+
import { generatePushCode } from "../../../runtime/push.js";
|
|
5
3
|
export function generatePush(ctx) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const AS = (type) => (ts ? ` as ${type}` : "");
|
|
12
|
-
const code = `/**
|
|
13
|
-
* Swoff Push Notifications
|
|
14
|
-
* Push subscription management with IndexedDB persistence.
|
|
15
|
-
*
|
|
16
|
-
* Usage:
|
|
17
|
-
* import { subscribeToPush, unsubscribeFromPush, isSubscribed } from './swoff/push.${ext}';
|
|
18
|
-
*
|
|
19
|
-
* // Enable (triggers permission prompt)
|
|
20
|
-
* const subscription = await subscribeToPush("YOUR_VAPID_PUBLIC_KEY");
|
|
21
|
-
* await fetch("/api/push/subscribe", {
|
|
22
|
-
* method: "POST",
|
|
23
|
-
* body: JSON.stringify(subscription.toJSON()),
|
|
24
|
-
* });
|
|
25
|
-
*
|
|
26
|
-
* // Disable
|
|
27
|
-
* await unsubscribeFromPush();
|
|
28
|
-
*
|
|
29
|
-
* Window events:
|
|
30
|
-
* push-permission-changed - Permission granted/denied (detail: { permission })
|
|
31
|
-
* push-subscription-changed - Subscribed/unsubscribed (detail: { subscribed })
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
const SUBSCRIPTION_DB = "swoff-push";
|
|
35
|
-
const SUBSCRIPTION_STORE = "subscription";
|
|
36
|
-
|
|
37
|
-
let permissionState = Notification.permission;
|
|
38
|
-
|
|
39
|
-
function openPushDB()${R("Promise<IDBDatabase>")}{
|
|
40
|
-
return new Promise${PT("IDBDatabase")}((resolve, reject) => {
|
|
41
|
-
const request = indexedDB.open(SUBSCRIPTION_DB, 1);
|
|
42
|
-
request.onupgradeneeded = (e) => {
|
|
43
|
-
const db = (e.target${AS("IDBOpenDBRequest")}).result;
|
|
44
|
-
if (!db.objectStoreNames.contains(SUBSCRIPTION_STORE)) {
|
|
45
|
-
db.createObjectStore(SUBSCRIPTION_STORE, { keyPath: "id" });
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
request.onsuccess = (e) => resolve((e.target${AS("IDBOpenDBRequest")}).result);
|
|
49
|
-
request.onerror = (e) => reject((e.target${AS("IDBRequest")}).error);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Request notification permission from the user. Returns true if granted. */
|
|
54
|
-
export async function requestNotificationPermission()${R("Promise<boolean>")}{
|
|
55
|
-
if (permissionState === "granted") return true;
|
|
56
|
-
if (permissionState === "denied") return false;
|
|
57
|
-
|
|
58
|
-
const result = await Notification.requestPermission();
|
|
59
|
-
permissionState = result;
|
|
60
|
-
window.dispatchEvent(
|
|
61
|
-
new CustomEvent("push-permission-changed", { detail: { permission: result } }),
|
|
62
|
-
);
|
|
63
|
-
return result === "granted";
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Get the current push subscription, or null if not subscribed. */
|
|
67
|
-
export async function getPushSubscription()${R("Promise<PushSubscription | null>")}{
|
|
68
|
-
try {
|
|
69
|
-
const registration = await navigator.serviceWorker.ready;
|
|
70
|
-
return await registration.pushManager.getSubscription();
|
|
71
|
-
} catch {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Subscribe to push notifications. Returns the subscription or null if permission denied. */
|
|
77
|
-
export async function subscribeToPush(vapidPublicKey${T("string")})${R("Promise<PushSubscription | null>")}{
|
|
78
|
-
const granted = await requestNotificationPermission();
|
|
79
|
-
if (!granted) return null;
|
|
80
|
-
|
|
81
|
-
const registration = await navigator.serviceWorker.ready;
|
|
82
|
-
const subscription = await registration.pushManager.subscribe({
|
|
83
|
-
userVisibleOnly: true,
|
|
84
|
-
applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)${AS("BufferSource")},
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const db = await openPushDB();
|
|
88
|
-
const tx = db.transaction(SUBSCRIPTION_STORE, "readwrite");
|
|
89
|
-
tx.objectStore(SUBSCRIPTION_STORE).put({
|
|
90
|
-
id: "current",
|
|
91
|
-
endpoint: subscription.endpoint,
|
|
92
|
-
keys: subscription.toJSON().keys,
|
|
93
|
-
subscribedAt: Date.now(),
|
|
94
|
-
});
|
|
95
|
-
await new Promise<void>((resolve, reject) => {
|
|
96
|
-
tx.oncomplete = () => resolve();
|
|
97
|
-
tx.onerror = () => reject(tx.error);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
window.dispatchEvent(
|
|
101
|
-
new CustomEvent("push-subscription-changed", { detail: { subscribed: true } }),
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
return subscription;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Unsubscribe from push notifications. */
|
|
108
|
-
export async function unsubscribeFromPush()${R("Promise<void>")}{
|
|
109
|
-
const subscription = await getPushSubscription();
|
|
110
|
-
if (!subscription) return;
|
|
111
|
-
|
|
112
|
-
await subscription.unsubscribe();
|
|
113
|
-
|
|
114
|
-
const db = await openPushDB();
|
|
115
|
-
const tx = db.transaction(SUBSCRIPTION_STORE, "readwrite");
|
|
116
|
-
tx.objectStore(SUBSCRIPTION_STORE).delete("current");
|
|
117
|
-
await new Promise<void>((resolve, reject) => {
|
|
118
|
-
tx.oncomplete = () => resolve();
|
|
119
|
-
tx.onerror = () => reject(tx.error);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
window.dispatchEvent(
|
|
123
|
-
new CustomEvent("push-subscription-changed", { detail: { subscribed: false } }),
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/** Check if the user is subscribed to push notifications. */
|
|
128
|
-
export async function isSubscribed()${R("Promise<boolean>")}{
|
|
129
|
-
const sub = await getPushSubscription();
|
|
130
|
-
return sub !== null;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/** Convert a base64 VAPID public key to a Uint8Array for pushManager.subscribe(). */
|
|
134
|
-
function urlBase64ToUint8Array(base64String${T("string")})${R("Uint8Array")}{
|
|
135
|
-
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
|
|
136
|
-
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
|
|
137
|
-
const rawData = atob(base64);
|
|
138
|
-
return Uint8Array.from(rawData, (c) => c.charCodeAt(0));
|
|
139
|
-
}
|
|
140
|
-
`;
|
|
141
|
-
writeFile(ctx, `push.${ext}`, code);
|
|
4
|
+
writeFile(ctx, `realtime/notifications.${ctx.ext}`, generatePushCode({
|
|
5
|
+
ts: ctx.ext === "ts",
|
|
6
|
+
ext: ctx.ext,
|
|
7
|
+
vapidKey: ctx.config.features.pushNotifications?.vapidPublicKey ?? "",
|
|
8
|
+
}));
|
|
142
9
|
}
|
|
143
10
|
//# sourceMappingURL=push.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/push.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/push.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,UAAU,YAAY,CAAC,GAAqB;IAChD,SAAS,CACP,GAAG,EACH,0BAA0B,GAAG,CAAC,GAAG,EAAE,EACnC,gBAAgB,CAAC;QACf,EAAE,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI;QACpB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,cAAc,IAAI,EAAE;KACtE,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1,90 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates pwa
|
|
2
|
+
* Generates pwa/ files — injector, prompt, and index barrel.
|
|
3
3
|
*/
|
|
4
4
|
import { writeFile } from "./context.js";
|
|
5
|
+
import { generatePwaInjectorCode } from "../../../runtime/pwa-injector.js";
|
|
6
|
+
import { generatePwaPromptCode } from "../../../runtime/pwa-prompt.js";
|
|
7
|
+
import { generatePwaIndexCode } from "../../../runtime/pwa-index.js";
|
|
5
8
|
export function generatePwaInstall(ctx) {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* Manual install trigger, installability check, and event listener setup.
|
|
14
|
-
*
|
|
15
|
-
* Usage:
|
|
16
|
-
* import { setupPwaInstall, isInstallable, promptInstall } from './swoff/pwa/install.${ext}';
|
|
17
|
-
*
|
|
18
|
-
* setupPwaInstall(); // sets up beforeinstallprompt and appinstalled listeners
|
|
19
|
-
*
|
|
20
|
-
* if (isInstallable()) {
|
|
21
|
-
* const result = await promptInstall();
|
|
22
|
-
* }
|
|
23
|
-
*
|
|
24
|
-
* Window properties:
|
|
25
|
-
* window.deferredInstallPrompt - The captured BeforeInstallPromptEvent
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/** Set up beforeinstallprompt and appinstalled event listeners. Call once at app startup. */
|
|
29
|
-
export function setupPwaInstall()${R("void")}{
|
|
30
|
-
window.addEventListener("beforeinstallprompt", (e) => {
|
|
31
|
-
window.deferredInstallPrompt = e as BeforeInstallPromptEvent;
|
|
32
|
-
window.pwaInstallable = true;
|
|
33
|
-
|
|
34
|
-
${preventLine}
|
|
35
|
-
window.dispatchEvent(
|
|
36
|
-
new CustomEvent("pwa-installable", {
|
|
37
|
-
detail: { isInstallable: true },
|
|
38
|
-
})
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
window.addEventListener("appinstalled", () => {
|
|
43
|
-
window.deferredInstallPrompt = null;
|
|
44
|
-
window.pwaInstallable = false;
|
|
45
|
-
|
|
46
|
-
window.dispatchEvent(
|
|
47
|
-
new CustomEvent("pwa-installed", {
|
|
48
|
-
detail: { outcome: "accepted" },
|
|
49
|
-
})
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** Check if the PWA install prompt is available (user has met install criteria). */
|
|
55
|
-
export function isInstallable()${R("boolean")}{
|
|
56
|
-
return !!window.deferredInstallPrompt;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/** Show the browser's native install prompt. Throws if prompt is not available. */
|
|
60
|
-
export async function promptInstall()${R("Promise<{ outcome: string }>")}{
|
|
61
|
-
if (!window.deferredInstallPrompt) {
|
|
62
|
-
throw new Error("Install prompt not available");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const promptEvent = window.deferredInstallPrompt;
|
|
66
|
-
await promptEvent.prompt();
|
|
67
|
-
|
|
68
|
-
const choice = await promptEvent.userChoice;
|
|
69
|
-
|
|
70
|
-
if (choice.outcome === "accepted") {
|
|
71
|
-
window.dispatchEvent(
|
|
72
|
-
new CustomEvent("pwa-installed", {
|
|
73
|
-
detail: { outcome: "accepted" },
|
|
74
|
-
})
|
|
75
|
-
);
|
|
76
|
-
} else {
|
|
77
|
-
window.dispatchEvent(
|
|
78
|
-
new CustomEvent("pwa-dismissed", {
|
|
79
|
-
detail: { outcome: "dismissed" },
|
|
80
|
-
})
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
window.deferredInstallPrompt = null;
|
|
85
|
-
return choice;
|
|
86
|
-
}
|
|
87
|
-
`;
|
|
88
|
-
writeFile(ctx, `pwa/install.${ext}`, code);
|
|
9
|
+
const opts = { ts: ctx.ext === "ts", ext: ctx.ext };
|
|
10
|
+
writeFile(ctx, `pwa/injector.${ctx.ext}`, generatePwaInjectorCode({
|
|
11
|
+
...opts,
|
|
12
|
+
preventDefaultInstall: ctx.config.features.pwa.preventDefaultInstall,
|
|
13
|
+
}));
|
|
14
|
+
writeFile(ctx, `pwa/prompt.${ctx.ext}`, generatePwaPromptCode(opts));
|
|
15
|
+
writeFile(ctx, `pwa/index.${ctx.ext}`, generatePwaIndexCode(opts));
|
|
89
16
|
}
|
|
90
17
|
//# sourceMappingURL=pwa-install.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pwa-install.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/pwa-install.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"pwa-install.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/pwa-install.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,MAAM,UAAU,kBAAkB,CAAC,GAAqB;IACtD,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IAEpD,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,CAAC,GAAG,EAAE,EAAE,uBAAuB,CAAC;QAChE,GAAG,IAAI;QACP,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,qBAAqB;KACrE,CAAC,CAAC,CAAC;IAEJ,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,CAAC,GAAG,EAAE,EAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IAErE,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -1,138 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates README.md — quick reference
|
|
2
|
+
* Generates README.md — quick reference that points to the static docs.
|
|
3
3
|
*/
|
|
4
4
|
import { writeFile } from "./context.js";
|
|
5
5
|
export function generateReadme(ctx) {
|
|
6
|
-
const { config } = ctx;
|
|
7
|
-
const ext = ctx.ext;
|
|
8
6
|
const lines = [];
|
|
9
7
|
const w = (s) => lines.push(s);
|
|
10
8
|
w("# Swoff — Quick Reference");
|
|
11
9
|
w("");
|
|
12
|
-
w("For the
|
|
10
|
+
w("For the complete API reference, see:");
|
|
13
11
|
w("");
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
w("initServiceWorker();");
|
|
20
|
-
w("```");
|
|
21
|
-
w("");
|
|
22
|
-
}
|
|
23
|
-
w("## API calls (use for all fetch requests)");
|
|
24
|
-
w("Use `fetchWithCache` instead of `fetch()` — it sets caching headers the SW needs.");
|
|
25
|
-
w("Plain `fetch()` skips SW caching when `cacheStrategy` is `\"explicit-only\"`.");
|
|
26
|
-
w("```ts");
|
|
27
|
-
w(`import { fetchWithCache } from "./swoff/fetch-wrapper.${ext}";`);
|
|
28
|
-
w('const data = await fetchWithCache("/api/data").then(r => r.json());');
|
|
29
|
-
w("```");
|
|
12
|
+
w("- `node_modules/@swoff/cli/docs/API.md` — every generated function");
|
|
13
|
+
w("- `node_modules/@swoff/cli/docs/ARCHITECTURE.md` — design & rationale");
|
|
14
|
+
w("- `node_modules/@swoff/cli/docs/CLI.md` — CLI commands");
|
|
15
|
+
w("- `node_modules/@swoff/cli/docs/CONFIG.md` — config schema");
|
|
16
|
+
w("- `node_modules/@swoff/cli/docs/COMPARISON.md` — library comparison");
|
|
30
17
|
w("");
|
|
31
|
-
|
|
32
|
-
w("## Authenticated API calls");
|
|
33
|
-
w("```ts");
|
|
34
|
-
w(`import { fetchWithCache } from "./swoff/fetch-wrapper.${ext}";`);
|
|
35
|
-
w('const data = await fetchWithCache("/api/me", { auth: true }).then(r => r.json());');
|
|
36
|
-
w("```");
|
|
37
|
-
w("");
|
|
38
|
-
}
|
|
39
|
-
if (config.features.mutationQueue.enabled) {
|
|
40
|
-
w("## Offline mutations (queue writes when offline)");
|
|
41
|
-
w("```ts");
|
|
42
|
-
w(`import { queueMutation, getPendingCount } from "./swoff/mutation-queue.${ext}";`);
|
|
43
|
-
w("await queueMutation({ method: \"POST\", url: \"/api/todos\", body: {...} });");
|
|
44
|
-
w("```");
|
|
45
|
-
w("");
|
|
46
|
-
if (config.features.auth.enabled) {
|
|
47
|
-
w("## After re-login (flush queued mutations)");
|
|
48
|
-
w("```ts");
|
|
49
|
-
w(`import { flushMutations } from "./swoff/mutation-queue.${ext}";`);
|
|
50
|
-
w("await flushMutations();");
|
|
51
|
-
w("```");
|
|
52
|
-
w("");
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (config.features.graphql.enabled) {
|
|
56
|
-
w("## GraphQL (cached queries with body-hash)");
|
|
57
|
-
w("```ts");
|
|
58
|
-
w(`import { queryGql, mutateGql } from "./swoff/gql-wrapper.${ext}";`);
|
|
59
|
-
w('const { data } = await queryGql("{ todos { id title } }");');
|
|
60
|
-
w('const { data: created } = await mutateGql(');
|
|
61
|
-
w(' "mutation CreateTodo($t: String!) { createTodo(title: $t) { id } }",');
|
|
62
|
-
w(' { t: "New task" },');
|
|
63
|
-
w(");");
|
|
64
|
-
w("```");
|
|
65
|
-
w("");
|
|
66
|
-
}
|
|
67
|
-
if (config.features.serverPush.enabled) {
|
|
68
|
-
w("## Server push events (real-time cache invalidation)");
|
|
69
|
-
w("```ts");
|
|
70
|
-
w(`import { startPushEvents } from "./swoff/server-push.${ext}";`);
|
|
71
|
-
w("startPushEvents();");
|
|
72
|
-
w("```");
|
|
73
|
-
w("");
|
|
74
|
-
}
|
|
75
|
-
if (config.features.pushNotifications?.enabled) {
|
|
76
|
-
w("## Push notifications");
|
|
77
|
-
w("```ts");
|
|
78
|
-
w(`import { subscribeToPush, unsubscribeFromPush, isSubscribed } from "./swoff/push.${ext}";`);
|
|
79
|
-
w('const sub = await subscribeToPush("YOUR_VAPID_PUBLIC_KEY");');
|
|
80
|
-
w("```");
|
|
81
|
-
w("");
|
|
82
|
-
}
|
|
83
|
-
if (ctx.frameworkName === "react") {
|
|
84
|
-
w("## React hooks");
|
|
85
|
-
w("```tsx");
|
|
86
|
-
w(`import { useCachedFetch } from "./swoff/hooks/useCachedFetch.${ext}x";`);
|
|
87
|
-
w(`import { useMutation } from "./swoff/hooks/useMutation.${ext}x";`);
|
|
88
|
-
w(`import { usePrefetch } from "./swoff/hooks/usePrefetch.${ext}x";`);
|
|
89
|
-
w(`import { useMutationState } from "./swoff/hooks/useMutationState.${ext}x";`);
|
|
90
|
-
w("");
|
|
91
|
-
w('const { data, error, loading, refetch } = useCachedFetch("/api/todos", {');
|
|
92
|
-
w(' refetchOnWindowFocus: true,');
|
|
93
|
-
w('});');
|
|
94
|
-
w("");
|
|
95
|
-
w('// Dependent query — skip until user is loaded');
|
|
96
|
-
w('const { data: posts } = useCachedFetch("/api/posts", { enabled: !!user });');
|
|
97
|
-
w("");
|
|
98
|
-
w('const { mutate } = useMutation({ onSuccess: (data) => console.log(data) });');
|
|
99
|
-
w('mutate("/api/todos", { method: "POST", body: JSON.stringify({ title: "New" }) });');
|
|
100
|
-
w("");
|
|
101
|
-
w('const prefetch = usePrefetch();');
|
|
102
|
-
w('prefetch("/api/todos");');
|
|
103
|
-
w("");
|
|
104
|
-
w('// Track a specific mutation by its returned id');
|
|
105
|
-
w('const mutation = useMutationState(mutationId);');
|
|
106
|
-
w("```");
|
|
107
|
-
w("");
|
|
108
|
-
if (config.features.mutationQueue.enabled) {
|
|
109
|
-
w("## Mutation queue hooks");
|
|
110
|
-
w("```tsx");
|
|
111
|
-
w(`import { useMutationQueue } from "./swoff/hooks/useMutationQueue.${ext}x";`);
|
|
112
|
-
w(`import { useMutationState } from "./swoff/hooks/useMutationState.${ext}x";`);
|
|
113
|
-
w("");
|
|
114
|
-
w('const { pending, items, lastSync } = useMutationQueue();');
|
|
115
|
-
w("// items: MutationQueueItem[] — each with id, url, method, status, retryCount");
|
|
116
|
-
w("// lastSync: { succeeded, failed } | null — result of the last sync attempt");
|
|
117
|
-
w("```");
|
|
118
|
-
w("");
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
if (config.features.tagInvalidation) {
|
|
122
|
-
w("## Cache invalidation");
|
|
123
|
-
w("```ts");
|
|
124
|
-
w(`import { generateTags, invalidateUrl } from "./swoff/invalidation-tags.${ext}";`);
|
|
125
|
-
w('const data = await fetchWithCache("/api/todos", { tags: generateTags("/api/todos") });');
|
|
126
|
-
w('await invalidateUrl("/api/todos/42"); // after mutation');
|
|
127
|
-
w("```");
|
|
128
|
-
w("");
|
|
129
|
-
}
|
|
130
|
-
w("## Build script");
|
|
131
|
-
w("The SW generator learns your build output to precache assets.");
|
|
132
|
-
w("Swoff has already added this to your `package.json`:");
|
|
133
|
-
w("```json");
|
|
134
|
-
w('"build": "<your-build> && node swoff/sw/generator.js"');
|
|
135
|
-
w("```");
|
|
18
|
+
w("Or run `swoff info <feature>` for targeted help.");
|
|
136
19
|
writeFile(ctx, "README.md", lines.join("\n"));
|
|
137
20
|
}
|
|
138
21
|
//# sourceMappingURL=quick-readme.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quick-readme.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/quick-readme.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,UAAU,cAAc,CAAC,GAAqB;IAClD,MAAM,
|
|
1
|
+
{"version":3,"file":"quick-readme.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/quick-readme.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,UAAU,cAAc,CAAC,GAAqB;IAClD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEvC,CAAC,CAAC,2BAA2B,CAAC,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC,CAAC;IACN,CAAC,CAAC,sCAAsC,CAAC,CAAC;IAC1C,CAAC,CAAC,EAAE,CAAC,CAAC;IACN,CAAC,CAAC,oEAAoE,CAAC,CAAC;IACxE,CAAC,CAAC,uEAAuE,CAAC,CAAC;IAC3E,CAAC,CAAC,wDAAwD,CAAC,CAAC;IAC5D,CAAC,CAAC,4DAA4D,CAAC,CAAC;IAChE,CAAC,CAAC,qEAAqE,CAAC,CAAC;IACzE,CAAC,CAAC,EAAE,CAAC,CAAC;IACN,CAAC,CAAC,kDAAkD,CAAC,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { writeFile } from "./context.js";
|
|
2
|
+
import { generateResetCode } from "../../../runtime/reset.js";
|
|
3
|
+
export function generateReset(ctx) {
|
|
4
|
+
writeFile(ctx, `reset.${ctx.ext}`, generateResetCode({ ts: ctx.ext === "ts", ext: ctx.ext }));
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=reset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,UAAU,aAAa,CAAC,GAAqB;IACjD,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,GAAG,EAAE,EAAE,iBAAiB,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAChG,CAAC"}
|