@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.
Files changed (216) hide show
  1. package/dist/__tests__/assemble-sw.test.js +8 -17
  2. package/dist/__tests__/assemble-sw.test.js.map +1 -1
  3. package/dist/__tests__/cli-integration.test.js +2 -2
  4. package/dist/__tests__/cli-integration.test.js.map +1 -1
  5. package/dist/__tests__/config-types.test.js +18 -8
  6. package/dist/__tests__/config-types.test.js.map +1 -1
  7. package/dist/__tests__/file-generators.test.js +3 -3
  8. package/dist/__tests__/file-generators.test.js.map +1 -1
  9. package/dist/__tests__/loader.test.js +5 -1
  10. package/dist/__tests__/loader.test.js.map +1 -1
  11. package/dist/__tests__/validator.test.js +6 -13
  12. package/dist/__tests__/validator.test.js.map +1 -1
  13. package/dist/index.js +39 -35
  14. package/dist/index.js.map +1 -1
  15. package/dist/lib/cli/help.js +13 -8
  16. package/dist/lib/cli/help.js.map +1 -1
  17. package/dist/lib/commands/add.js +38 -8
  18. package/dist/lib/commands/add.js.map +1 -1
  19. package/dist/lib/commands/assets.js +37 -0
  20. package/dist/lib/commands/assets.js.map +1 -0
  21. package/dist/lib/commands/clean.js +33 -17
  22. package/dist/lib/commands/clean.js.map +1 -1
  23. package/dist/lib/commands/generate-assets.js +44 -0
  24. package/dist/lib/commands/generate-assets.js.map +1 -0
  25. package/dist/lib/commands/generate-guide.js +22 -29
  26. package/dist/lib/commands/generate-guide.js.map +1 -1
  27. package/dist/lib/commands/generate.js +16 -9
  28. package/dist/lib/commands/generate.js.map +1 -1
  29. package/dist/lib/commands/info.js +36 -45
  30. package/dist/lib/commands/info.js.map +1 -1
  31. package/dist/lib/commands/init.js +25 -3
  32. package/dist/lib/commands/init.js.map +1 -1
  33. package/dist/lib/commands/validate.js +1 -1
  34. package/dist/lib/commands/validate.js.map +1 -1
  35. package/dist/lib/config/loader.js +25 -20
  36. package/dist/lib/config/loader.js.map +1 -1
  37. package/dist/lib/config/validator.js +20 -11
  38. package/dist/lib/config/validator.js.map +1 -1
  39. package/dist/lib/generators/asset-generator/dependency-resolver.js +76 -0
  40. package/dist/lib/generators/asset-generator/dependency-resolver.js.map +1 -0
  41. package/dist/lib/generators/asset-generator/generate.js +111 -0
  42. package/dist/lib/generators/asset-generator/generate.js.map +1 -0
  43. package/dist/lib/generators/asset-generator/guide.js +43 -0
  44. package/dist/lib/generators/asset-generator/guide.js.map +1 -0
  45. package/dist/lib/generators/asset-generator/html-patcher.js +65 -0
  46. package/dist/lib/generators/asset-generator/html-patcher.js.map +1 -0
  47. package/dist/lib/generators/asset-generator/ico-encoder.js +29 -0
  48. package/dist/lib/generators/asset-generator/ico-encoder.js.map +1 -0
  49. package/dist/lib/generators/asset-generator/manifest-patcher.js +23 -0
  50. package/dist/lib/generators/asset-generator/manifest-patcher.js.map +1 -0
  51. package/dist/lib/generators/asset-generator/maskable.js +15 -0
  52. package/dist/lib/generators/asset-generator/maskable.js.map +1 -0
  53. package/dist/lib/generators/asset-generator/rasterize.js +32 -0
  54. package/dist/lib/generators/asset-generator/rasterize.js.map +1 -0
  55. package/dist/lib/generators/asset-generator/sizes.js +25 -0
  56. package/dist/lib/generators/asset-generator/sizes.js.map +1 -0
  57. package/dist/lib/generators/file-generators/api-config.js +6 -0
  58. package/dist/lib/generators/file-generators/api-config.js.map +1 -0
  59. package/dist/lib/generators/file-generators/auth-state.js +2 -34
  60. package/dist/lib/generators/file-generators/auth-state.js.map +1 -1
  61. package/dist/lib/generators/file-generators/auth-store.js +2 -250
  62. package/dist/lib/generators/file-generators/auth-store.js.map +1 -1
  63. package/dist/lib/generators/file-generators/auth-user.js +3 -81
  64. package/dist/lib/generators/file-generators/auth-user.js.map +1 -1
  65. package/dist/lib/generators/file-generators/background-sync.js +2 -57
  66. package/dist/lib/generators/file-generators/background-sync.js.map +1 -1
  67. package/dist/lib/generators/file-generators/cache.js +2 -30
  68. package/dist/lib/generators/file-generators/cache.js.map +1 -1
  69. package/dist/lib/generators/file-generators/client-injector.js +2 -130
  70. package/dist/lib/generators/file-generators/client-injector.js.map +1 -1
  71. package/dist/lib/generators/file-generators/fetch-state.js +6 -0
  72. package/dist/lib/generators/file-generators/fetch-state.js.map +1 -0
  73. package/dist/lib/generators/file-generators/fetch-wrapper.js +3 -295
  74. package/dist/lib/generators/file-generators/fetch-wrapper.js.map +1 -1
  75. package/dist/lib/generators/file-generators/generate-framework-adapters.js +56 -0
  76. package/dist/lib/generators/file-generators/generate-framework-adapters.js.map +1 -0
  77. package/dist/lib/generators/file-generators/generate-hooks.js +4 -3
  78. package/dist/lib/generators/file-generators/generate-hooks.js.map +1 -1
  79. package/dist/lib/generators/file-generators/gql-wrapper.js +3 -132
  80. package/dist/lib/generators/file-generators/gql-wrapper.js.map +1 -1
  81. package/dist/lib/generators/file-generators/guide-generator.js +29 -1
  82. package/dist/lib/generators/file-generators/guide-generator.js.map +1 -1
  83. package/dist/lib/generators/file-generators/invalidation-tags.js +3 -258
  84. package/dist/lib/generators/file-generators/invalidation-tags.js.map +1 -1
  85. package/dist/lib/generators/file-generators/manifest.js +13 -3
  86. package/dist/lib/generators/file-generators/manifest.js.map +1 -1
  87. package/dist/lib/generators/file-generators/mutation-queue.js +3 -305
  88. package/dist/lib/generators/file-generators/mutation-queue.js.map +1 -1
  89. package/dist/lib/generators/file-generators/mutation-state.js +2 -117
  90. package/dist/lib/generators/file-generators/mutation-state.js.map +1 -1
  91. package/dist/lib/generators/file-generators/push.js +6 -138
  92. package/dist/lib/generators/file-generators/push.js.map +1 -1
  93. package/dist/lib/generators/file-generators/pwa-install.js +11 -84
  94. package/dist/lib/generators/file-generators/pwa-install.js.map +1 -1
  95. package/dist/lib/generators/file-generators/reset.js +6 -0
  96. package/dist/lib/generators/file-generators/reset.js.map +1 -0
  97. package/dist/lib/generators/file-generators/server-push.js +3 -134
  98. package/dist/lib/generators/file-generators/server-push.js.map +1 -1
  99. package/dist/lib/generators/file-generators/sw-generator-build.js +4 -4
  100. package/dist/lib/generators/file-generators/sw-injector.js +9 -230
  101. package/dist/lib/generators/file-generators/sw-injector.js.map +1 -1
  102. package/dist/lib/generators/file-generators/type-definitions.js +2 -111
  103. package/dist/lib/generators/file-generators/type-definitions.js.map +1 -1
  104. package/dist/lib/generators/sw-generator.js +5 -5
  105. package/dist/lib/generators/sw-generator.js.map +1 -1
  106. package/dist/lib/generators/sw-sections/activate-handler.js +25 -3
  107. package/dist/lib/generators/sw-sections/activate-handler.js.map +1 -1
  108. package/dist/lib/generators/sw-sections/assemble-sw.js +13 -12
  109. package/dist/lib/generators/sw-sections/assemble-sw.js.map +1 -1
  110. package/dist/lib/generators/sw-sections/background-sync-handler.js +14 -7
  111. package/dist/lib/generators/sw-sections/background-sync-handler.js.map +1 -1
  112. package/dist/lib/generators/sw-sections/config-header.js +1 -1
  113. package/dist/lib/generators/sw-sections/config-header.js.map +1 -1
  114. package/dist/lib/generators/sw-sections/fetch-handler.js +165 -104
  115. package/dist/lib/generators/sw-sections/fetch-handler.js.map +1 -1
  116. package/dist/lib/generators/sw-sections/glob-matcher-code.js.map +1 -0
  117. package/dist/lib/generators/sw-sections/server-push-handler.js +12 -0
  118. package/dist/lib/generators/sw-sections/server-push-handler.js.map +1 -1
  119. package/dist/lib/generators/sw-sections/tag-management.js +6 -4
  120. package/dist/lib/generators/sw-sections/tag-management.js.map +1 -1
  121. package/dist/lib/generators/swoff-files-generator.js +66 -35
  122. package/dist/lib/generators/swoff-files-generator.js.map +1 -1
  123. package/dist/lib/shared/config-types.js +89 -28
  124. package/dist/lib/shared/config-types.js.map +1 -1
  125. package/dist/runtime/api-config.js +18 -0
  126. package/dist/runtime/api-config.js.map +1 -0
  127. package/dist/runtime/auth-state.js +35 -0
  128. package/dist/runtime/auth-state.js.map +1 -0
  129. package/dist/runtime/auth-store.js +273 -0
  130. package/dist/runtime/auth-store.js.map +1 -0
  131. package/dist/runtime/auth-user.js +168 -0
  132. package/dist/runtime/auth-user.js.map +1 -0
  133. package/dist/runtime/background-sync.js +59 -0
  134. package/dist/runtime/background-sync.js.map +1 -0
  135. package/dist/runtime/cache.js +30 -0
  136. package/dist/runtime/cache.js.map +1 -0
  137. package/dist/runtime/client-injector.js +136 -0
  138. package/dist/runtime/client-injector.js.map +1 -0
  139. package/dist/runtime/fetch-state.js +42 -0
  140. package/dist/runtime/fetch-state.js.map +1 -0
  141. package/dist/runtime/fetch-wrapper.js +355 -0
  142. package/dist/runtime/fetch-wrapper.js.map +1 -0
  143. package/dist/runtime/gql-wrapper.js +135 -0
  144. package/dist/runtime/gql-wrapper.js.map +1 -0
  145. package/dist/runtime/invalidation-tags.js +260 -0
  146. package/dist/runtime/invalidation-tags.js.map +1 -0
  147. package/dist/runtime/mutation-queue.js +304 -0
  148. package/dist/runtime/mutation-queue.js.map +1 -0
  149. package/dist/runtime/mutation-state.js +117 -0
  150. package/dist/runtime/mutation-state.js.map +1 -0
  151. package/dist/runtime/push.js +138 -0
  152. package/dist/runtime/push.js.map +1 -0
  153. package/dist/runtime/pwa-index.js +11 -0
  154. package/dist/runtime/pwa-index.js.map +1 -0
  155. package/dist/runtime/pwa-injector.js +44 -0
  156. package/dist/runtime/pwa-injector.js.map +1 -0
  157. package/dist/runtime/pwa-install.js +83 -0
  158. package/dist/runtime/pwa-install.js.map +1 -0
  159. package/dist/runtime/pwa-prompt.js +54 -0
  160. package/dist/runtime/pwa-prompt.js.map +1 -0
  161. package/dist/runtime/reset.js +148 -0
  162. package/dist/runtime/reset.js.map +1 -0
  163. package/dist/runtime/server-push.js +148 -0
  164. package/dist/runtime/server-push.js.map +1 -0
  165. package/dist/runtime/sw-injector.js +236 -0
  166. package/dist/runtime/sw-injector.js.map +1 -0
  167. package/dist/runtime/type-definitions.js +138 -0
  168. package/dist/runtime/type-definitions.js.map +1 -0
  169. package/dist/runtime/utils.js +27 -0
  170. package/dist/runtime/utils.js.map +1 -0
  171. package/package.json +3 -2
  172. package/templates/react/useAuth.jsx +106 -0
  173. package/templates/react/useAuth.tsx +118 -0
  174. package/templates/{hooks → react}/useBackgroundSync.jsx +6 -4
  175. package/templates/{hooks → react}/useBackgroundSync.tsx +6 -4
  176. package/templates/{hooks → react}/useCacheInvalidation.jsx +2 -2
  177. package/templates/react/useCacheInvalidation.tsx +52 -0
  178. package/templates/react/useCachedFetch.jsx +140 -0
  179. package/templates/react/useCachedFetch.tsx +160 -0
  180. package/templates/react/useIsFetching.jsx +32 -0
  181. package/templates/react/useIsFetching.tsx +32 -0
  182. package/templates/react/useMutation.jsx +141 -0
  183. package/templates/react/useMutation.tsx +180 -0
  184. package/templates/react/useMutationQueue.jsx +69 -0
  185. package/templates/react/useMutationQueue.tsx +83 -0
  186. package/templates/react/useNetworkStatus.jsx +61 -0
  187. package/templates/react/useNetworkStatus.tsx +76 -0
  188. package/templates/react/usePrefetch.jsx +32 -0
  189. package/templates/react/usePrefetch.tsx +42 -0
  190. package/templates/{hooks → react}/usePushSubscription.jsx +4 -4
  191. package/templates/{hooks → react}/usePushSubscription.tsx +4 -4
  192. package/templates/{hooks → react}/useSWUpdate.jsx +3 -3
  193. package/templates/{hooks → react}/useSWUpdate.tsx +4 -4
  194. package/templates/react/useSwoffReset.jsx +32 -0
  195. package/templates/react/useSwoffReset.tsx +39 -0
  196. package/docs/API.md +0 -565
  197. package/docs/ARCHITECTURE.md +0 -374
  198. package/docs/CLI.md +0 -148
  199. package/docs/COMPARISON.md +0 -192
  200. package/docs/CONFIG.md +0 -277
  201. package/docs/ECOSYSTEM.md +0 -33
  202. package/templates/hooks/useAuth.jsx +0 -30
  203. package/templates/hooks/useAuth.tsx +0 -30
  204. package/templates/hooks/useCacheInvalidation.tsx +0 -19
  205. package/templates/hooks/useCachedFetch.jsx +0 -69
  206. package/templates/hooks/useCachedFetch.tsx +0 -81
  207. package/templates/hooks/useMutation.jsx +0 -76
  208. package/templates/hooks/useMutation.tsx +0 -109
  209. package/templates/hooks/useMutationQueue.jsx +0 -43
  210. package/templates/hooks/useMutationQueue.tsx +0 -50
  211. package/templates/hooks/useNetworkStatus.jsx +0 -19
  212. package/templates/hooks/useNetworkStatus.tsx +0 -19
  213. package/templates/hooks/usePrefetch.jsx +0 -10
  214. package/templates/hooks/usePrefetch.tsx +0 -25
  215. /package/templates/{hooks → react}/useMutationState.jsx +0 -0
  216. /package/templates/{hooks → react}/useMutationState.tsx +0 -0
@@ -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
- const ext = ctx.ext;
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;AAE3D,MAAM,UAAU,qBAAqB,CAAC,GAAqB;IACzD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IACpB,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG;;;;;;mGAMoF,GAAG;;;;;;;;;;;;;;;;;MAiBhG,CAAC,CAAC,QAAQ,CAAC;UACP,CAAC,CAAC,gBAAgB,CAAC;SACpB,CAAC,CAAC,cAAc,CAAC;QAClB,CAAC,CAAC,SAAS,CAAC;aACP,CAAC,CAAC,QAAQ,CAAC;;;;;;;;;kCASU,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;wCAelE,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,sBAAsB,CAAC;;;;;;;;;;;oCAWnF,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;;;;;mCAKrD,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;;;;;qCAK1C,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,2BAA2B,CAAC;;;;;uCAK3C,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;;;;;wCAKvB,CAAC,CAAC,iBAAiB,CAAC;;;;;yCAKnB,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;;;;;;;;;gDAS3B,CAAC,CAAC,gCAAgC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC;;;;;;gCAMtE,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;;;;;;;;;CAS9D,CAAC;IAEA,SAAS,CAAC,GAAG,EAAE,kBAAkB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AAChD,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,142 +1,10 @@
1
1
  import { writeFile } from "./context.js";
2
+ import { generatePushCode } from "../../../runtime/push.js";
2
3
  export function generatePush(ctx) {
3
- const ext = ctx.ext;
4
- const ts = ext === "ts";
5
- const T = (type) => (ts ? `: ${type}` : "");
6
- const R = (type) => (ts ? `: ${type} ` : " ");
7
- const PT = (type) => (ts ? `<${type}>` : "");
8
- const AS = (type) => (ts ? ` as ${type}` : "");
9
- const vapidKey = ctx.config.features.pushNotifications?.vapidPublicKey ?? "";
10
- const code = `/**
11
- * Swoff Push Notifications
12
- * Push subscription management with IndexedDB persistence.
13
- *
14
- * Usage:
15
- * import { subscribeToPush, unsubscribeFromPush, isSubscribed } from './swoff/push.${ext}';
16
- *
17
- * // Enable (triggers permission prompt)
18
- * const subscription = await subscribeToPush();
19
- * await fetch("/api/push/subscribe", {
20
- * method: "POST",
21
- * body: JSON.stringify(subscription.toJSON()),
22
- * });
23
- *
24
- * // Disable
25
- * await unsubscribeFromPush();
26
- *
27
- * Window events:
28
- * push-permission-changed - Permission granted/denied (detail: { permission })
29
- * push-subscription-changed - Subscribed/unsubscribed (detail: { subscribed })
30
- */
31
-
32
- const SUBSCRIPTION_DB = "swoff-push";
33
- const SUBSCRIPTION_STORE = "subscription";
34
- const VAPID_PUBLIC_KEY = ${JSON.stringify(vapidKey)};
35
-
36
- let permissionState = Notification.permission;
37
-
38
- function openPushDB()${R("Promise<IDBDatabase>")}{
39
- return new Promise${PT("IDBDatabase")}((resolve, reject) => {
40
- const request = indexedDB.open(SUBSCRIPTION_DB, 1);
41
- request.onupgradeneeded = (e) => {
42
- const db = (e.target${AS("IDBOpenDBRequest")}).result;
43
- if (!db.objectStoreNames.contains(SUBSCRIPTION_STORE)) {
44
- db.createObjectStore(SUBSCRIPTION_STORE, { keyPath: "id" });
45
- }
46
- };
47
- request.onsuccess = (e) => resolve((e.target${AS("IDBOpenDBRequest")}).result);
48
- request.onerror = (e) => reject((e.target${AS("IDBRequest")}).error);
49
- });
50
- }
51
-
52
- /** Request notification permission from the user. Returns true if granted. */
53
- export async function requestNotificationPermission()${R("Promise<boolean>")}{
54
- if (permissionState === "granted") return true;
55
- if (permissionState === "denied") return false;
56
-
57
- const result = await Notification.requestPermission();
58
- permissionState = result;
59
- window.dispatchEvent(
60
- new CustomEvent("push-permission-changed", { detail: { permission: result } }),
61
- );
62
- return result === "granted";
63
- }
64
-
65
- /** Get the current push subscription, or null if not subscribed. */
66
- export async function getPushSubscription()${R("Promise<PushSubscription | null>")}{
67
- try {
68
- const registration = await navigator.serviceWorker.ready;
69
- return await registration.pushManager.getSubscription();
70
- } catch {
71
- return null;
72
- }
73
- }
74
-
75
- /** Subscribe to push notifications. Returns the subscription or null if permission denied. Uses the VAPID public key from your swoff.config.json. */
76
- export async function subscribeToPush()${R("Promise<PushSubscription | null>")}{
77
- const granted = await requestNotificationPermission();
78
- if (!granted) return null;
79
-
80
- const registration = await navigator.serviceWorker.ready;
81
- const subscription = await registration.pushManager.subscribe({
82
- userVisibleOnly: true,
83
- applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)${AS("BufferSource")},
84
- });
85
-
86
- const db = await openPushDB();
87
- const tx = db.transaction(SUBSCRIPTION_STORE, "readwrite");
88
- tx.objectStore(SUBSCRIPTION_STORE).put({
89
- id: "current",
90
- endpoint: subscription.endpoint,
91
- keys: subscription.toJSON().keys,
92
- subscribedAt: Date.now(),
93
- });
94
- await new Promise<void>((resolve, reject) => {
95
- tx.oncomplete = () => resolve();
96
- tx.onerror = () => reject(tx.error);
97
- });
98
-
99
- window.dispatchEvent(
100
- new CustomEvent("push-subscription-changed", { detail: { subscribed: true } }),
101
- );
102
-
103
- return subscription;
104
- }
105
-
106
- /** Unsubscribe from push notifications. */
107
- export async function unsubscribeFromPush()${R("Promise<void>")}{
108
- const subscription = await getPushSubscription();
109
- if (!subscription) return;
110
-
111
- await subscription.unsubscribe();
112
-
113
- const db = await openPushDB();
114
- const tx = db.transaction(SUBSCRIPTION_STORE, "readwrite");
115
- tx.objectStore(SUBSCRIPTION_STORE).delete("current");
116
- await new Promise<void>((resolve, reject) => {
117
- tx.oncomplete = () => resolve();
118
- tx.onerror = () => reject(tx.error);
119
- });
120
-
121
- window.dispatchEvent(
122
- new CustomEvent("push-subscription-changed", { detail: { subscribed: false } }),
123
- );
124
- }
125
-
126
- /** Check if the user is subscribed to push notifications. */
127
- export async function isSubscribed()${R("Promise<boolean>")}{
128
- const sub = await getPushSubscription();
129
- return sub !== null;
130
- }
131
-
132
- /** Convert a base64 VAPID public key to a Uint8Array for pushManager.subscribe(). */
133
- function urlBase64ToUint8Array(base64String${T("string")})${R("Uint8Array")}{
134
- const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
135
- const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
136
- const rawData = atob(base64);
137
- return Uint8Array.from(rawData, (c) => c.charCodeAt(0));
138
- }
139
- `;
140
- 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
+ }));
141
9
  }
142
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,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,UAAU,YAAY,CAAC,GAAqB;IAChD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IACpB,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrD,MAAM,EAAE,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,cAAc,IAAI,EAAE,CAAC;IAE7E,MAAM,IAAI,GAAG;;;;;wFAKyE,GAAG;;;;;;;;;;;;;;;;;;;2BAmBhE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;;;;uBAI5B,CAAC,CAAC,sBAAsB,CAAC;sBAC1B,EAAE,CAAC,aAAa,CAAC;;;4BAGX,EAAE,CAAC,kBAAkB,CAAC;;;;;kDAKA,EAAE,CAAC,kBAAkB,CAAC;+CACzB,EAAE,CAAC,YAAY,CAAC;;;;;uDAKR,CAAC,CAAC,kBAAkB,CAAC;;;;;;;;;;;;;6CAa/B,CAAC,CAAC,kCAAkC,CAAC;;;;;;;;;;yCAUzC,CAAC,CAAC,kCAAkC,CAAC;;;;;;;mEAOX,EAAE,CAAC,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;6CAwBxC,CAAC,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;sCAoBzB,CAAC,CAAC,kBAAkB,CAAC;;;;;;6CAMd,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC;;;;;;CAM1E,CAAC;IAEA,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC"}
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-install.{js|ts} - PWA install prompt utility.
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 ext = ctx.ext;
7
- const ts = ext === "ts";
8
- const R = (type) => (ts ? `: ${type} ` : " ");
9
- const preventDefaultInstall = ctx.config.features.pwa.preventDefaultInstall;
10
- const preventLine = preventDefaultInstall ? " e.preventDefault();\n" : "";
11
- const code = `/**
12
- * Swoff PWA Install Support
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;AAE3D,MAAM,UAAU,kBAAkB,CAAC,GAAqB;IACtD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IACpB,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACtD,MAAM,qBAAqB,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAC5E,MAAM,WAAW,GAAG,qBAAqB,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7E,MAAM,IAAI,GAAG;;;;;0FAK2E,GAAG;;;;;;;;;;;;;mCAa1D,CAAC,CAAC,MAAM,CAAC;;;;;EAK1C,WAAW;;;;;;;;;;;;;;;;;;;;;iCAqBoB,CAAC,CAAC,SAAS,CAAC;;;;;uCAKN,CAAC,CAAC,8BAA8B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BvE,CAAC;IAEA,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AAC7C,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"}
@@ -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"}
@@ -4,143 +4,12 @@
4
4
  * This client-side helper provides a fallback and status events for the UI.
5
5
  */
6
6
  import { writeFile } from "./context.js";
7
+ import { generateServerPushCode } from "../../../runtime/server-push.js";
7
8
  export function generateServerPush(ctx) {
8
9
  const ext = ctx.ext;
9
10
  const ts = ext === "ts";
10
- const T = (type) => (ts ? `: ${type}` : "");
11
- const R = (type) => (ts ? `: ${type}` : " ");
12
11
  const sp = ctx.config.features.serverPush;
13
- const endpoint = sp.endpoint;
14
- const reconnectDelayMs = sp.reconnectDelayMs;
15
- const invalidate = `
16
- // Forward to SW for cache invalidation
17
- if (navigator.serviceWorker.controller) {
18
- for (const tag of tags) {
19
- navigator.serviceWorker.controller.postMessage({ type: "INVALIDATE_TAG", tag });
20
- }
21
- }`;
22
- const sseConnect = `
23
- return new Promise((resolve) => {
24
- fetch("${endpoint}", {
25
- headers: { Accept: "text/event-stream" },
26
- signal: options.signal,
27
- }).then(async (response) => {
28
- if (!response.ok || !response.body) { resolve(); return; }
29
- notifyStatus(true);
30
- const reader = response.body.getReader();
31
- const decoder = new TextDecoder();
32
- let buffer = "";
33
- let eventType = "";
34
- let dataStr = "";
35
-
36
- while (true) {
37
- const { done, value } = await reader.read();
38
- if (done) break;
39
- buffer += decoder.decode(value, { stream: true });
40
- const lines = buffer.split("\\n");
41
- buffer = lines.pop() || "";
42
- for (const line of lines) {
43
- if (line.startsWith("event: ")) eventType = line.slice(7).trim();
44
- else if (line.startsWith("data: ")) dataStr = line.slice(6);
45
- else if (line === "" && eventType === "invalidate" && dataStr) {
46
- try {
47
- const p = JSON.parse(dataStr); if (p.tags) handleInvalidation(p.tags);
48
- } catch {
49
- // Handle invalidation data
50
- }
51
- eventType = ""; dataStr = "";
52
- }
53
- }
54
- }
55
- }).catch(() => {}).finally(() => {
56
- notifyStatus(false);
57
- resolve();
58
- });
59
- });`;
60
- const wsConnect = `
61
- return new Promise((resolve) => {
62
- try {
63
- const ws = new WebSocket("${endpoint}");
64
- ws.onopen = () => notifyStatus(true);
65
- ws.onmessage = (event) => {
66
- try { const d = JSON.parse(event.data); if (d.type === "invalidate" && d.tags) handleInvalidation(d.tags); } catch {}
67
- };
68
- ws.onclose = () => { notifyStatus(false); resolve(); };
69
- ws.onerror = () => { ws.close(); resolve(); };
70
- if (options.signal) {
71
- options.signal.addEventListener("abort", () => ws.close());
72
- }
73
- } catch { resolve(); }
74
- });`;
75
- const code = `/**
76
- * Swoff Server Push Events
77
- *
78
- * The service worker connects to ${endpoint} and invalidates cache tags
79
- * when the server sends "invalidate" events — no polling needed.
80
- * This client-side helper provides status tracking and a manual start/stop API.
81
- *
82
- * Usage:
83
- * import { startPushEvents, stopPushEvents, isPushConnected } from "./server-push.${ext}";
84
- * startPushEvents();
85
- *
86
- * Server sends:
87
- * event: invalidate
88
- * data: {"tags": ["todos", "todo:42"]}
89
- */
90
-
91
- type PushEventOptions= {
92
- signal${T("AbortSignal")};
93
- };
94
-
95
- let active${T("boolean")} = false;
96
- let reconnectTimer${T("ReturnType<typeof setTimeout> | null")} = null;
97
-
98
- function handleInvalidation(tags${T("string[]")})${R("void")}{${invalidate}
99
- window.dispatchEvent(new CustomEvent("cache-invalidated", { detail: { tags } }));
100
- }
101
-
102
- function notifyStatus(connected${T("boolean")})${R("void")}{
103
- window.dispatchEvent(new CustomEvent("push-events-status", { detail: { connected } }));
104
- }
105
-
106
- async function connect(options${T("PushEventOptions")} = {} as PushEventOptions)${R("Promise<void>")}{
107
- ${sp.type === "sse" ? sseConnect : wsConnect}
108
- }
109
-
110
- /** 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. */
111
- export async function startPushEvents(){
112
- if (active) return;
113
-
114
- // If SW is already controlling the page, skip client-side connection — the SW handles push events.
115
- if (navigator.serviceWorker.controller) return;
116
-
117
- // Listen for SW activation — if SW takes over, disconnect the client fallback.
118
- const onControllerChange = () => { stopPushEvents(); };
119
- navigator.serviceWorker.addEventListener("controllerchange", onControllerChange);
120
-
121
- active = true;
122
- let delay = ${reconnectDelayMs};
123
- while (active) {
124
- await connect();
125
- if (!active) break;
126
- await new Promise((r) => { reconnectTimer = setTimeout(r, delay); });
127
- delay = Math.min(delay * 1.5, 30000); // cap at 30s
128
- }
129
-
130
- navigator.serviceWorker.removeEventListener("controllerchange", onControllerChange);
131
- }
132
-
133
- /** Stop listening for push events. */
134
- export function stopPushEvents(){
135
- active = false;
136
- if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
137
- }
138
-
139
- /** Check if the push connection is currently established. */
140
- export function isPushConnected(){
141
- return active;
142
- }
143
- `;
144
- writeFile(ctx, `server-push.${ext}`, code);
12
+ const code = generateServerPushCode({ ts, ext }, sp.type, sp.endpoint, sp.reconnectDelayMs);
13
+ writeFile(ctx, `realtime/server-push.${ext}`, code);
145
14
  }
146
15
  //# sourceMappingURL=server-push.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-push.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/server-push.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,UAAU,kBAAkB,CAAC,GAAqB;IACtD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IACpB,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC1C,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC;IAC7B,MAAM,gBAAgB,GAAG,EAAE,CAAC,gBAAgB,CAAC;IAE7C,MAAM,UAAU,GAAG;;;;;;IAMjB,CAAC;IAEH,MAAM,UAAU,GAAG;;aAER,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAmCf,CAAC;IAEL,MAAM,SAAS,GAAG;;;kCAGc,QAAQ;;;;;;;;;;;MAWpC,CAAC;IAEL,MAAM,IAAI,GAAG;;;oCAGqB,QAAQ;;;;;uFAK2C,GAAG;;;;;;;;;UAShF,CAAC,CAAC,aAAa,CAAC;;;YAGd,CAAC,CAAC,SAAS,CAAC;oBACJ,CAAC,CAAC,sCAAsC,CAAC;;kCAE3B,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,UAAU;;;;iCAIzC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;;;;gCAI1B,CAAC,CAAC,kBAAkB,CAAC,6BAA6B,CAAC,CAAC,eAAe,CAAC;IAChG,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;;;;;;;;;;;;;;;gBAe9B,gBAAgB;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;IAEA,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"server-push.js","sourceRoot":"","sources":["../../../../src/lib/generators/file-generators/server-push.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,MAAM,UAAU,kBAAkB,CAAC,GAAqB;IACtD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IACpB,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,CAAC;IACxB,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;IAE1C,MAAM,IAAI,GAAG,sBAAsB,CACjC,EAAE,EAAE,EAAE,GAAG,EAAE,EACX,EAAE,CAAC,IAAI,EACP,EAAE,CAAC,QAAQ,EACX,EAAE,CAAC,gBAAgB,CACpB,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE,wBAAwB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AACtD,CAAC"}
@@ -38,12 +38,12 @@ const template = readFileSync(templatePath, 'utf8');
38
38
 
39
39
  const swConfig = config.features?.serviceWorker || {};
40
40
  const versionField = swConfig.version;
41
- const versionEnabled = versionField !== false && versionField !== "hash";
41
+ const versionEnabled = versionField !== "hash";
42
42
  const version = versionField === "package"
43
43
  ? (pkg.version || '1.0.0')
44
- : versionField && versionField !== "hash"
45
- ? versionField
46
- : (pkg.version || '1.0.0');
44
+ : versionField === "hash"
45
+ ? "0.0.0"
46
+ : versionField || (pkg.version || '1.0.0');
47
47
  const outputDir = config.build?.outputDir || 'dist';
48
48
  const swFilename = config.build?.swFilename || 'sw';
49
49