@cogenta/render 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/astro/integration.d.ts +57 -0
  2. package/dist/astro/integration.d.ts.map +1 -0
  3. package/dist/astro/integration.js +72 -0
  4. package/dist/astro/integration.js.map +1 -0
  5. package/dist/build/index.d.ts +7 -0
  6. package/dist/build/index.d.ts.map +1 -0
  7. package/dist/build/index.js +7 -0
  8. package/dist/build/index.js.map +1 -0
  9. package/dist/build/integration.d.ts +25 -0
  10. package/dist/build/integration.d.ts.map +1 -0
  11. package/dist/build/integration.js +41 -0
  12. package/dist/build/integration.js.map +1 -0
  13. package/dist/build/plan.d.ts +41 -0
  14. package/dist/build/plan.d.ts.map +1 -0
  15. package/dist/build/plan.js +48 -0
  16. package/dist/build/plan.js.map +1 -0
  17. package/dist/build/refusal.d.ts +14 -0
  18. package/dist/build/refusal.d.ts.map +1 -0
  19. package/dist/build/refusal.js +110 -0
  20. package/dist/build/refusal.js.map +1 -0
  21. package/dist/build/requirements.d.ts +59 -0
  22. package/dist/build/requirements.d.ts.map +1 -0
  23. package/dist/build/requirements.js +74 -0
  24. package/dist/build/requirements.js.map +1 -0
  25. package/dist/build/run-build.d.ts +43 -0
  26. package/dist/build/run-build.d.ts.map +1 -0
  27. package/dist/build/run-build.js +73 -0
  28. package/dist/build/run-build.js.map +1 -0
  29. package/dist/build/targets.d.ts +47 -0
  30. package/dist/build/targets.d.ts.map +1 -0
  31. package/dist/build/targets.js +69 -0
  32. package/dist/build/targets.js.map +1 -0
  33. package/dist/cache/index.d.ts +7 -0
  34. package/dist/cache/index.d.ts.map +1 -0
  35. package/dist/cache/index.js +4 -0
  36. package/dist/cache/index.js.map +1 -0
  37. package/dist/cache/page-cache.d.ts +64 -0
  38. package/dist/cache/page-cache.d.ts.map +1 -0
  39. package/dist/cache/page-cache.js +128 -0
  40. package/dist/cache/page-cache.js.map +1 -0
  41. package/dist/cache/recorder.d.ts +49 -0
  42. package/dist/cache/recorder.d.ts.map +1 -0
  43. package/dist/cache/recorder.js +77 -0
  44. package/dist/cache/recorder.js.map +1 -0
  45. package/dist/cache/tags.d.ts +55 -0
  46. package/dist/cache/tags.d.ts.map +1 -0
  47. package/dist/cache/tags.js +62 -0
  48. package/dist/cache/tags.js.map +1 -0
  49. package/dist/config.d.ts +48 -0
  50. package/dist/config.d.ts.map +1 -0
  51. package/dist/config.js +44 -0
  52. package/dist/config.js.map +1 -0
  53. package/dist/content/client.d.ts +35 -0
  54. package/dist/content/client.d.ts.map +1 -0
  55. package/dist/content/client.js +155 -0
  56. package/dist/content/client.js.map +1 -0
  57. package/dist/content/types.d.ts +104 -0
  58. package/dist/content/types.d.ts.map +1 -0
  59. package/dist/content/types.js +16 -0
  60. package/dist/content/types.js.map +1 -0
  61. package/dist/context/render-context.d.ts +31 -0
  62. package/dist/context/render-context.d.ts.map +1 -0
  63. package/dist/context/render-context.js +152 -0
  64. package/dist/context/render-context.js.map +1 -0
  65. package/dist/context/types.d.ts +49 -0
  66. package/dist/context/types.d.ts.map +1 -0
  67. package/dist/context/types.js +2 -0
  68. package/dist/context/types.js.map +1 -0
  69. package/dist/images/errors.d.ts +20 -0
  70. package/dist/images/errors.d.ts.map +1 -0
  71. package/dist/images/errors.js +58 -0
  72. package/dist/images/errors.js.map +1 -0
  73. package/dist/images/format.d.ts +18 -0
  74. package/dist/images/format.d.ts.map +1 -0
  75. package/dist/images/format.js +34 -0
  76. package/dist/images/format.js.map +1 -0
  77. package/dist/images/geometry.d.ts +46 -0
  78. package/dist/images/geometry.d.ts.map +1 -0
  79. package/dist/images/geometry.js +127 -0
  80. package/dist/images/geometry.js.map +1 -0
  81. package/dist/images/index.d.ts +29 -0
  82. package/dist/images/index.d.ts.map +1 -0
  83. package/dist/images/index.js +30 -0
  84. package/dist/images/index.js.map +1 -0
  85. package/dist/images/pipeline.d.ts +51 -0
  86. package/dist/images/pipeline.d.ts.map +1 -0
  87. package/dist/images/pipeline.js +105 -0
  88. package/dist/images/pipeline.js.map +1 -0
  89. package/dist/images/sharp.d.ts +57 -0
  90. package/dist/images/sharp.d.ts.map +1 -0
  91. package/dist/images/sharp.js +139 -0
  92. package/dist/images/sharp.js.map +1 -0
  93. package/dist/images/srcset.d.ts +33 -0
  94. package/dist/images/srcset.d.ts.map +1 -0
  95. package/dist/images/srcset.js +94 -0
  96. package/dist/images/srcset.js.map +1 -0
  97. package/dist/images/store.d.ts +32 -0
  98. package/dist/images/store.d.ts.map +1 -0
  99. package/dist/images/store.js +54 -0
  100. package/dist/images/store.js.map +1 -0
  101. package/dist/images/types.d.ts +128 -0
  102. package/dist/images/types.d.ts.map +1 -0
  103. package/dist/images/types.js +22 -0
  104. package/dist/images/types.js.map +1 -0
  105. package/dist/images/wasm.d.ts +43 -0
  106. package/dist/images/wasm.d.ts.map +1 -0
  107. package/dist/images/wasm.js +128 -0
  108. package/dist/images/wasm.js.map +1 -0
  109. package/dist/index.d.ts +29 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +29 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/pwa/build.d.ts +39 -0
  114. package/dist/pwa/build.d.ts.map +1 -0
  115. package/dist/pwa/build.js +38 -0
  116. package/dist/pwa/build.js.map +1 -0
  117. package/dist/pwa/client.d.ts +90 -0
  118. package/dist/pwa/client.d.ts.map +1 -0
  119. package/dist/pwa/client.js +76 -0
  120. package/dist/pwa/client.js.map +1 -0
  121. package/dist/pwa/index.d.ts +29 -0
  122. package/dist/pwa/index.d.ts.map +1 -0
  123. package/dist/pwa/index.js +22 -0
  124. package/dist/pwa/index.js.map +1 -0
  125. package/dist/pwa/manifest.d.ts +69 -0
  126. package/dist/pwa/manifest.d.ts.map +1 -0
  127. package/dist/pwa/manifest.js +108 -0
  128. package/dist/pwa/manifest.js.map +1 -0
  129. package/dist/pwa/offline.d.ts +44 -0
  130. package/dist/pwa/offline.d.ts.map +1 -0
  131. package/dist/pwa/offline.js +94 -0
  132. package/dist/pwa/offline.js.map +1 -0
  133. package/dist/pwa/service-worker.d.ts +71 -0
  134. package/dist/pwa/service-worker.d.ts.map +1 -0
  135. package/dist/pwa/service-worker.js +119 -0
  136. package/dist/pwa/service-worker.js.map +1 -0
  137. package/dist/pwa/strategy.d.ts +36 -0
  138. package/dist/pwa/strategy.d.ts.map +1 -0
  139. package/dist/pwa/strategy.js +180 -0
  140. package/dist/pwa/strategy.js.map +1 -0
  141. package/dist/pwa/sw-runtime.d.ts +109 -0
  142. package/dist/pwa/sw-runtime.d.ts.map +1 -0
  143. package/dist/pwa/sw-runtime.js +214 -0
  144. package/dist/pwa/sw-runtime.js.map +1 -0
  145. package/dist/pwa/types.d.ts +107 -0
  146. package/dist/pwa/types.d.ts.map +1 -0
  147. package/dist/pwa/types.js +18 -0
  148. package/dist/pwa/types.js.map +1 -0
  149. package/dist/pwa/version.d.ts +45 -0
  150. package/dist/pwa/version.d.ts.map +1 -0
  151. package/dist/pwa/version.js +89 -0
  152. package/dist/pwa/version.js.map +1 -0
  153. package/dist/skin/color.d.ts +50 -0
  154. package/dist/skin/color.d.ts.map +1 -0
  155. package/dist/skin/color.js +176 -0
  156. package/dist/skin/color.js.map +1 -0
  157. package/dist/skin/css.d.ts +19 -0
  158. package/dist/skin/css.d.ts.map +1 -0
  159. package/dist/skin/css.js +69 -0
  160. package/dist/skin/css.js.map +1 -0
  161. package/dist/skin/errors.d.ts +22 -0
  162. package/dist/skin/errors.d.ts.map +1 -0
  163. package/dist/skin/errors.js +59 -0
  164. package/dist/skin/errors.js.map +1 -0
  165. package/dist/skin/index.d.ts +15 -0
  166. package/dist/skin/index.d.ts.map +1 -0
  167. package/dist/skin/index.js +11 -0
  168. package/dist/skin/index.js.map +1 -0
  169. package/dist/skin/sheet.d.ts +42 -0
  170. package/dist/skin/sheet.d.ts.map +1 -0
  171. package/dist/skin/sheet.js +36 -0
  172. package/dist/skin/sheet.js.map +1 -0
  173. package/dist/skin/tokens.d.ts +90 -0
  174. package/dist/skin/tokens.d.ts.map +1 -0
  175. package/dist/skin/tokens.js +56 -0
  176. package/dist/skin/tokens.js.map +1 -0
  177. package/dist/skin/validate.d.ts +14 -0
  178. package/dist/skin/validate.d.ts.map +1 -0
  179. package/dist/skin/validate.js +272 -0
  180. package/dist/skin/validate.js.map +1 -0
  181. package/dist/theme/load-theme.d.ts +37 -0
  182. package/dist/theme/load-theme.d.ts.map +1 -0
  183. package/dist/theme/load-theme.js +102 -0
  184. package/dist/theme/load-theme.js.map +1 -0
  185. package/dist/theme/manifest.d.ts +48 -0
  186. package/dist/theme/manifest.d.ts.map +1 -0
  187. package/dist/theme/manifest.js +36 -0
  188. package/dist/theme/manifest.js.map +1 -0
  189. package/dist/theme/verify/forbidden.d.ts +39 -0
  190. package/dist/theme/verify/forbidden.d.ts.map +1 -0
  191. package/dist/theme/verify/forbidden.js +107 -0
  192. package/dist/theme/verify/forbidden.js.map +1 -0
  193. package/dist/theme/verify/scan-file.d.ts +15 -0
  194. package/dist/theme/verify/scan-file.d.ts.map +1 -0
  195. package/dist/theme/verify/scan-file.js +151 -0
  196. package/dist/theme/verify/scan-file.js.map +1 -0
  197. package/dist/theme/verify/scanner.d.ts +52 -0
  198. package/dist/theme/verify/scanner.d.ts.map +1 -0
  199. package/dist/theme/verify/scanner.js +304 -0
  200. package/dist/theme/verify/scanner.js.map +1 -0
  201. package/dist/theme/verify/verify-theme.d.ts +44 -0
  202. package/dist/theme/verify/verify-theme.d.ts.map +1 -0
  203. package/dist/theme/verify/verify-theme.js +179 -0
  204. package/dist/theme/verify/verify-theme.js.map +1 -0
  205. package/package.json +56 -0
@@ -0,0 +1,119 @@
1
+ import { chooseStrategy } from './strategy.js';
2
+ import { serviceWorkerMain, tombstoneMain } from './sw-runtime.js';
3
+ import { cacheNameFor, cachesToPurge } from './version.js';
4
+ /**
5
+ * Generation of the service worker script.
6
+ *
7
+ * ## The update strategy, stated in full
8
+ *
9
+ * `skipWaiting()` and `clients.claim()` are two calls; the strategy is the four
10
+ * properties that make those two calls safe.
11
+ *
12
+ * **1. Every generation owns its caches.** Cache names embed a version derived
13
+ * from the offline page, the precache list and the route table
14
+ * (`computeCacheVersion`). A new deploy therefore writes into new caches and
15
+ * cannot mix generations, which is what makes immediate activation safe: there
16
+ * is no window in which half the entries are old.
17
+ *
18
+ * **2. Activation purges the previous generations.** `cachesToPurge` returns
19
+ * every cache of ours whose version is not the current one, and activation
20
+ * deletes them before claiming clients. Storage does not accumulate one
21
+ * generation per deploy, and — the part that matters — yesterday's HTML is
22
+ * *gone*, not merely lower priority.
23
+ *
24
+ * **3. Documents are never served from cache while the network works.** Even a
25
+ * worker that somehow survived a bad deploy cannot pin an old page: the
26
+ * document strategy is network-first, so the cache answers only when the
27
+ * network has already failed. This is the property that keeps a mistake
28
+ * recoverable by deploying a fix, rather than requiring every visitor to clear
29
+ * their site data.
30
+ *
31
+ * **4. There is an exit.** The worker answers a message by purging every cache
32
+ * it owns and calling `registration.unregister()` — that is the admin's "clear
33
+ * client cache" button. For clients we can no longer run code on,
34
+ * `renderTombstoneServiceWorker` produces a worker that unregisters itself on
35
+ * activation; deploying it at the same URL removes the PWA from every browser
36
+ * that re-fetches the script, which browsers do at least daily.
37
+ *
38
+ * ## What is deliberately *not* done
39
+ *
40
+ * The worker does not reload open pages when it activates. A forced reload
41
+ * destroys scroll position, half-typed comments and video playback, and it
42
+ * turns one bad deploy into a reload loop. It posts `cogenta:activated`
43
+ * instead, and the page decides — the registration helper in `client.ts` turns
44
+ * that into an "a new version is available" prompt.
45
+ *
46
+ * The worker is a *classic* script, not an ES module: module workers are still
47
+ * unevenly supported, and there is nothing to import — the script is
48
+ * self-contained by construction.
49
+ */
50
+ /**
51
+ * Headers the server must send for the service worker script.
52
+ *
53
+ * This is not decoration. A worker script cached by the HTTP cache for a year
54
+ * is the canonical unkillable zombie: the browser's daily update check reads
55
+ * the stale copy from disk, sees no change, and keeps the old worker alive —
56
+ * including after the tombstone has been deployed. `no-cache` (revalidate, do
57
+ * not blindly reuse) is the minimum, and the scope header lets the script live
58
+ * anywhere while controlling the whole origin.
59
+ */
60
+ export const SERVICE_WORKER_HEADERS = {
61
+ 'cache-control': 'no-cache, max-age=0, must-revalidate',
62
+ 'content-type': 'text/javascript; charset=utf-8',
63
+ 'service-worker-allowed': '/',
64
+ };
65
+ /**
66
+ * `Function.prototype.toString` returns the source of the function itself; the
67
+ * `export` keyword is a separate declaration in the module grammar. Stripping
68
+ * it anyway costs one line and removes a dependency on that detail of whichever
69
+ * engine ran `tsc`.
70
+ */
71
+ function sourceOf(fn) {
72
+ return String(fn).replace(/^export\s+/, '');
73
+ }
74
+ const BANNER = [
75
+ '/*',
76
+ ' * Generated by @cogenta/render. Do not edit: this file is rewritten on every',
77
+ ' * build, and its content determines the cache generation.',
78
+ ' *',
79
+ ' * Serve it with `cache-control: no-cache` (see SERVICE_WORKER_HEADERS). A',
80
+ ' * worker script held in the HTTP cache cannot be updated or removed.',
81
+ ' */',
82
+ ].join('\n');
83
+ function scriptFor(body) {
84
+ return `${BANNER}\n${body}\n`;
85
+ }
86
+ export function renderServiceWorker(config) {
87
+ // Pretty-printed on purpose: this file is the first thing anyone reads when a
88
+ // browser is serving something unexpected, and a minified route table is
89
+ // unreadable at exactly that moment.
90
+ const configLiteral = JSON.stringify(config, null, 2);
91
+ return scriptFor([
92
+ `const COGENTA_PWA_CONFIG = ${configLiteral}\n`,
93
+ sourceOf(cacheNameFor),
94
+ sourceOf(cachesToPurge),
95
+ sourceOf(chooseStrategy),
96
+ sourceOf(serviceWorkerMain),
97
+ '',
98
+ 'serviceWorkerMain(self, COGENTA_PWA_CONFIG)',
99
+ ].join('\n\n'));
100
+ }
101
+ /**
102
+ * The kill switch, as a deployable artefact.
103
+ *
104
+ * Deploy this at the URL the real worker was served from. It caches nothing,
105
+ * intercepts nothing, deletes every cache under `cachePrefix` and unregisters
106
+ * itself. Keep it deployed for at least one update cycle — twenty-four hours
107
+ * covers browsers that only check the script once a day — before removing the
108
+ * route entirely, because a 404 on the worker URL also unregisters the worker
109
+ * but tells the caches nothing.
110
+ */
111
+ export function renderTombstoneServiceWorker(cachePrefix) {
112
+ return scriptFor([
113
+ `const COGENTA_CACHE_PREFIX = ${JSON.stringify(cachePrefix)}\n`,
114
+ sourceOf(tombstoneMain),
115
+ '',
116
+ 'tombstoneMain(self, COGENTA_CACHE_PREFIX)',
117
+ ].join('\n\n'));
118
+ }
119
+ //# sourceMappingURL=service-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-worker.js","sourceRoot":"","sources":["../../src/pwa/service-worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAqC;IACtE,eAAe,EAAE,sCAAsC;IACvD,cAAc,EAAE,gCAAgC;IAChD,wBAAwB,EAAE,GAAG;CAC9B,CAAA;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,EAAiC;IACjD,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,MAAM,GAAG;IACb,IAAI;IACJ,+EAA+E;IAC/E,4DAA4D;IAC5D,IAAI;IACJ,4EAA4E;IAC5E,uEAAuE;IACvE,KAAK;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEZ,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,GAAG,MAAM,KAAK,IAAI,IAAI,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,8EAA8E;IAC9E,yEAAyE;IACzE,qCAAqC;IACrC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAErD,OAAO,SAAS,CACd;QACE,8BAA8B,aAAa,IAAI;QAC/C,QAAQ,CAAC,YAAY,CAAC;QACtB,QAAQ,CAAC,aAAa,CAAC;QACvB,QAAQ,CAAC,cAAc,CAAC;QACxB,QAAQ,CAAC,iBAAiB,CAAC;QAC3B,EAAE;QACF,6CAA6C;KAC9C,CAAC,IAAI,CAAC,MAAM,CAAC,CACf,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAAC,WAAmB;IAC9D,OAAO,SAAS,CACd;QACE,gCAAgC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI;QAC/D,QAAQ,CAAC,aAAa,CAAC;QACvB,EAAE;QACF,2CAA2C;KAC5C,CAAC,IAAI,CAAC,MAAM,CAAC,CACf,CAAA;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { RequestDescriptor, RouteRule, StrategyDecision } from './types.js';
2
+ /**
3
+ * Which strategy answers which request, and why.
4
+ *
5
+ * The rule that governs every choice below: **a resource may be served from
6
+ * cache without revalidation only when its URL changes whenever its content
7
+ * changes.** Fingerprinted assets satisfy that. Nothing else on a CMS-driven
8
+ * site does — an author republishes an article at the same URL, replaces an
9
+ * image at the same path, fixes a typo in a JSON feed. Serving those cache-first
10
+ * is exactly the "stale content forever" failure the L3 spec warns about.
11
+ */
12
+ /**
13
+ * A URL is treated as immutable when it lives under Astro's hashed asset
14
+ * directory or carries a content hash in its filename. Both forms change on
15
+ * every content change, which is the entire justification for cache-first.
16
+ */
17
+ export declare const IMMUTABLE_ASSET_PATTERN = "(^/_astro/)|(\\.[0-9a-f]{8,}\\.[a-z0-9]+(?:$|\\?))";
18
+ /**
19
+ * The default route table, in priority order. Each rule states its bucket, so
20
+ * caches stay separable, and its cap, so no bucket can grow without bound.
21
+ */
22
+ export declare const DEFAULT_ROUTES: readonly RouteRule[];
23
+ /**
24
+ * Picks the strategy for one request.
25
+ *
26
+ * Pure, total, and free of any reference to module scope — this function is
27
+ * inlined verbatim into the generated service worker (see `runtime-source.ts`)
28
+ * so that the behaviour under test and the behaviour shipped are the same text.
29
+ *
30
+ * The bypasses come first and are deliberately generous. Every one of them is a
31
+ * case where storing a response would produce a wrong answer later, and a
32
+ * service worker that returns a wrong answer is worse than no service worker:
33
+ * it is a wrong answer nobody can reproduce without clearing site data.
34
+ */
35
+ export declare function chooseStrategy(request: RequestDescriptor, routes: readonly RouteRule[]): StrategyDecision;
36
+ //# sourceMappingURL=strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../src/pwa/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAEhF;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,uDAAuD,CAAA;AAE3F;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,SAAS,EAuF9C,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,SAAS,SAAS,EAAE,GAC3B,gBAAgB,CA6DlB"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Which strategy answers which request, and why.
3
+ *
4
+ * The rule that governs every choice below: **a resource may be served from
5
+ * cache without revalidation only when its URL changes whenever its content
6
+ * changes.** Fingerprinted assets satisfy that. Nothing else on a CMS-driven
7
+ * site does — an author republishes an article at the same URL, replaces an
8
+ * image at the same path, fixes a typo in a JSON feed. Serving those cache-first
9
+ * is exactly the "stale content forever" failure the L3 spec warns about.
10
+ */
11
+ /**
12
+ * A URL is treated as immutable when it lives under Astro's hashed asset
13
+ * directory or carries a content hash in its filename. Both forms change on
14
+ * every content change, which is the entire justification for cache-first.
15
+ */
16
+ export const IMMUTABLE_ASSET_PATTERN = '(^/_astro/)|(\\.[0-9a-f]{8,}\\.[a-z0-9]+(?:$|\\?))';
17
+ /**
18
+ * The default route table, in priority order. Each rule states its bucket, so
19
+ * caches stay separable, and its cap, so no bucket can grow without bound.
20
+ */
21
+ export const DEFAULT_ROUTES = [
22
+ {
23
+ // HTML is the index of everything else: it names the asset URLs, the nav,
24
+ // the current article. Stale HTML points at assets a purge has already
25
+ // deleted, so a cache-first document is both wrong and broken. Network
26
+ // first, with a short timeout so a captive portal or a dead mobile leg
27
+ // falls back to the last copy instead of hanging on a white screen.
28
+ id: 'documents',
29
+ destinations: ['document'],
30
+ pattern: null,
31
+ crossOrigin: false,
32
+ strategy: 'network-first',
33
+ bucket: 'documents',
34
+ maxEntries: 50,
35
+ networkTimeoutMs: 3000,
36
+ },
37
+ {
38
+ // Fingerprinted assets. The URL is a content hash, so the cached body can
39
+ // never be wrong; revalidating it would only cost a round trip. This is the
40
+ // one and only place cache-first is safe, and it is where the offline win
41
+ // actually comes from.
42
+ id: 'immutable-assets',
43
+ destinations: ['script', 'style', 'font', 'worker'],
44
+ pattern: IMMUTABLE_ASSET_PATTERN,
45
+ crossOrigin: false,
46
+ strategy: 'cache-first',
47
+ bucket: 'assets',
48
+ maxEntries: 200,
49
+ networkTimeoutMs: null,
50
+ },
51
+ {
52
+ // Scripts, stylesheets and fonts served from a stable URL. The body can
53
+ // change under that URL, so cache-first would pin an old build; but they
54
+ // are render-blocking, so network-first would cost a round trip on every
55
+ // page. Stale-while-revalidate is the honest middle: fast now, correct on
56
+ // the next navigation.
57
+ id: 'mutable-assets',
58
+ destinations: ['script', 'style', 'font'],
59
+ pattern: null,
60
+ crossOrigin: false,
61
+ strategy: 'stale-while-revalidate',
62
+ bucket: 'assets',
63
+ maxEntries: 60,
64
+ networkTimeoutMs: null,
65
+ },
66
+ {
67
+ // Images are large, replaceable at the same path by an editor, and never
68
+ // load-bearing for correctness: one page view showing yesterday's crop is a
69
+ // cosmetic defect, not a wrong answer. Capped, because an image cache is
70
+ // the one that fills a phone.
71
+ id: 'images',
72
+ destinations: ['image'],
73
+ pattern: null,
74
+ crossOrigin: false,
75
+ strategy: 'stale-while-revalidate',
76
+ bucket: 'images',
77
+ maxEntries: 80,
78
+ networkTimeoutMs: null,
79
+ },
80
+ {
81
+ // API data. Never stale-while-revalidate: JSON drives what the interface
82
+ // asserts, and rendering last week's data as if it were current is the
83
+ // failure mode users report as "the site is lying". Network first, cached
84
+ // only so that an offline reader still sees the last state they had, with
85
+ // a longer timeout than documents because a list endpoint is legitimately
86
+ // slower than a page.
87
+ id: 'api-data',
88
+ destinations: ['', 'empty'],
89
+ pattern: '^/api/',
90
+ crossOrigin: false,
91
+ strategy: 'network-first',
92
+ bucket: 'data',
93
+ maxEntries: 40,
94
+ networkTimeoutMs: 4000,
95
+ },
96
+ {
97
+ // The manifest itself. Rarely changes, tiny, and needed for the install
98
+ // prompt to appear offline.
99
+ id: 'manifest',
100
+ destinations: ['manifest'],
101
+ pattern: null,
102
+ crossOrigin: false,
103
+ strategy: 'stale-while-revalidate',
104
+ bucket: 'assets',
105
+ maxEntries: 5,
106
+ networkTimeoutMs: null,
107
+ },
108
+ ];
109
+ /**
110
+ * Picks the strategy for one request.
111
+ *
112
+ * Pure, total, and free of any reference to module scope — this function is
113
+ * inlined verbatim into the generated service worker (see `runtime-source.ts`)
114
+ * so that the behaviour under test and the behaviour shipped are the same text.
115
+ *
116
+ * The bypasses come first and are deliberately generous. Every one of them is a
117
+ * case where storing a response would produce a wrong answer later, and a
118
+ * service worker that returns a wrong answer is worse than no service worker:
119
+ * it is a wrong answer nobody can reproduce without clearing site data.
120
+ */
121
+ export function chooseStrategy(request, routes) {
122
+ const bypass = (reason) => ({
123
+ strategy: 'network-only',
124
+ bucket: 'documents',
125
+ maxEntries: null,
126
+ networkTimeoutMs: null,
127
+ ruleId: 'bypass',
128
+ reason,
129
+ });
130
+ // The Cache API only keys on GET. A POST answered from a cache would be a
131
+ // silent correctness bug, and a POST *stored* in one would be a data leak.
132
+ if (request.method !== 'GET')
133
+ return bypass(`method ${request.method} is not cacheable`);
134
+ // The caller explicitly asked to skip caches: a hard reload, or a fetch with
135
+ // `cache: 'no-store'`. Overruling that is how a service worker earns its
136
+ // reputation for being impossible to bypass.
137
+ if (request.cacheMode === 'no-store' || request.cacheMode === 'reload') {
138
+ return bypass(`request cache mode ${request.cacheMode} forbids caching`);
139
+ }
140
+ // A ranged response is a fragment. Storing it and later matching a full
141
+ // request against it hands back a truncated body — the classic broken-video
142
+ // bug.
143
+ if (request.hasRange)
144
+ return bypass('ranged request has a partial body');
145
+ let pathAndQuery;
146
+ let sameOrigin;
147
+ try {
148
+ const parsed = new URL(request.url);
149
+ sameOrigin = parsed.origin === request.origin;
150
+ pathAndQuery = parsed.pathname + parsed.search;
151
+ }
152
+ catch {
153
+ return bypass('request url could not be parsed');
154
+ }
155
+ // A navigation is a document even when the destination field is empty, which
156
+ // it is on some engines for the very first request of a page.
157
+ const destination = request.mode === 'navigate' ? 'document' : request.destination;
158
+ for (const rule of routes) {
159
+ if (!sameOrigin && !rule.crossOrigin)
160
+ continue;
161
+ if (rule.destinations.length > 0 && !rule.destinations.includes(destination))
162
+ continue;
163
+ if (rule.pattern !== null && !new RegExp(rule.pattern).test(pathAndQuery))
164
+ continue;
165
+ return {
166
+ strategy: rule.strategy,
167
+ bucket: rule.bucket,
168
+ maxEntries: rule.maxEntries,
169
+ networkTimeoutMs: rule.networkTimeoutMs,
170
+ ruleId: rule.id,
171
+ reason: `matched rule ${rule.id}`,
172
+ };
173
+ }
174
+ // No rule claimed it, so we do not touch it. Defaulting to a cache here would
175
+ // mean the service worker quietly takes ownership of resources nobody
176
+ // reasoned about, including opaque cross-origin responses whose status it
177
+ // cannot even read.
178
+ return bypass(sameOrigin ? `no rule matches destination "${destination}"` : 'cross-origin request');
179
+ }
180
+ //# sourceMappingURL=strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../src/pwa/strategy.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,oDAAoD,CAAA;AAE3F;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAyB;IAClD;QACE,0EAA0E;QAC1E,uEAAuE;QACvE,uEAAuE;QACvE,uEAAuE;QACvE,oEAAoE;QACpE,EAAE,EAAE,WAAW;QACf,YAAY,EAAE,CAAC,UAAU,CAAC;QAC1B,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,eAAe;QACzB,MAAM,EAAE,WAAW;QACnB,UAAU,EAAE,EAAE;QACd,gBAAgB,EAAE,IAAI;KACvB;IACD;QACE,0EAA0E;QAC1E,4EAA4E;QAC5E,0EAA0E;QAC1E,uBAAuB;QACvB,EAAE,EAAE,kBAAkB;QACtB,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC;QACnD,OAAO,EAAE,uBAAuB;QAChC,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,aAAa;QACvB,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,GAAG;QACf,gBAAgB,EAAE,IAAI;KACvB;IACD;QACE,wEAAwE;QACxE,yEAAyE;QACzE,yEAAyE;QACzE,0EAA0E;QAC1E,uBAAuB;QACvB,EAAE,EAAE,gBAAgB;QACpB,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC;QACzC,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,wBAAwB;QAClC,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,EAAE;QACd,gBAAgB,EAAE,IAAI;KACvB;IACD;QACE,yEAAyE;QACzE,4EAA4E;QAC5E,yEAAyE;QACzE,8BAA8B;QAC9B,EAAE,EAAE,QAAQ;QACZ,YAAY,EAAE,CAAC,OAAO,CAAC;QACvB,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,wBAAwB;QAClC,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,EAAE;QACd,gBAAgB,EAAE,IAAI;KACvB;IACD;QACE,yEAAyE;QACzE,uEAAuE;QACvE,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,sBAAsB;QACtB,EAAE,EAAE,UAAU;QACd,YAAY,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC;QAC3B,OAAO,EAAE,QAAQ;QACjB,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,eAAe;QACzB,MAAM,EAAE,MAAM;QACd,UAAU,EAAE,EAAE;QACd,gBAAgB,EAAE,IAAI;KACvB;IACD;QACE,wEAAwE;QACxE,4BAA4B;QAC5B,EAAE,EAAE,UAAU;QACd,YAAY,EAAE,CAAC,UAAU,CAAC;QAC1B,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,wBAAwB;QAClC,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,CAAC;QACb,gBAAgB,EAAE,IAAI;KACvB;CACF,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC5B,OAA0B,EAC1B,MAA4B;IAE5B,MAAM,MAAM,GAAG,CAAC,MAAc,EAAoB,EAAE,CAAC,CAAC;QACpD,QAAQ,EAAE,cAAc;QACxB,MAAM,EAAE,WAAW;QACnB,UAAU,EAAE,IAAI;QAChB,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE,QAAQ;QAChB,MAAM;KACP,CAAC,CAAA;IAEF,0EAA0E;IAC1E,2EAA2E;IAC3E,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,MAAM,CAAC,UAAU,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAA;IAExF,6EAA6E;IAC7E,yEAAyE;IACzE,6CAA6C;IAC7C,IAAI,OAAO,CAAC,SAAS,KAAK,UAAU,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACvE,OAAO,MAAM,CAAC,sBAAsB,OAAO,CAAC,SAAS,kBAAkB,CAAC,CAAA;IAC1E,CAAC;IAED,wEAAwE;IACxE,4EAA4E;IAC5E,OAAO;IACP,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,MAAM,CAAC,mCAAmC,CAAC,CAAA;IAExE,IAAI,YAAoB,CAAA;IACxB,IAAI,UAAmB,CAAA;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACnC,UAAU,GAAG,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAA;QAC7C,YAAY,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAA;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,iCAAiC,CAAC,CAAA;IAClD,CAAC;IAED,6EAA6E;IAC7E,8DAA8D;IAC9D,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;IAElF,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,SAAQ;QAC9C,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,SAAQ;QACtF,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,SAAQ;QACnF,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,MAAM,EAAE,gBAAgB,IAAI,CAAC,EAAE,EAAE;SAClC,CAAA;IACH,CAAC;IAED,8EAA8E;IAC9E,sEAAsE;IACtE,0EAA0E;IAC1E,oBAAoB;IACpB,OAAO,MAAM,CACX,UAAU,CAAC,CAAC,CAAC,gCAAgC,WAAW,GAAG,CAAC,CAAC,CAAC,sBAAsB,CACrF,CAAA;AACH,CAAC"}
@@ -0,0 +1,109 @@
1
+ import type { PwaConfig } from './types.js';
2
+ /**
3
+ * The service worker runtime, written as ordinary TypeScript.
4
+ *
5
+ * It is never *imported* by a browser: `renderServiceWorker` inlines the source
6
+ * text of these functions into the script it generates. That indirection buys
7
+ * three things a hand-written string template cannot. The runtime is
8
+ * type-checked and linted like the rest of the package. The routing decision
9
+ * shipped to browsers is character-for-character the function the unit tests
10
+ * exercise, so the two cannot drift. And there is no bundler in the loop, which
11
+ * matters because a service worker must be one self-contained file served from
12
+ * the site root.
13
+ *
14
+ * The constraint that comes with it: **nothing in this file may reference
15
+ * module scope.** Only the parameters, and the three helpers that are inlined
16
+ * alongside (`chooseStrategy`, `cacheNameFor`, `cachesToPurge`). A test asserts
17
+ * that the generated script defines each of them.
18
+ *
19
+ * The scope is typed against the minimal interfaces below rather than
20
+ * `lib.webworker`: the package compiles with `lib: ES2023`, and a narrow
21
+ * hand-written surface documents exactly which browser APIs the worker is
22
+ * allowed to touch.
23
+ */
24
+ export interface ExtendableEventLike {
25
+ waitUntil(promise: Promise<unknown>): void;
26
+ }
27
+ export interface HeadersLike {
28
+ has(name: string): boolean;
29
+ }
30
+ export interface RequestLike {
31
+ readonly method: string;
32
+ readonly url: string;
33
+ readonly destination: string;
34
+ readonly mode: string;
35
+ readonly cache: string;
36
+ readonly headers: HeadersLike;
37
+ }
38
+ export interface ResponseLike {
39
+ readonly ok: boolean;
40
+ readonly status: number;
41
+ clone(): ResponseLike;
42
+ }
43
+ export interface FetchEventLike extends ExtendableEventLike {
44
+ readonly request: RequestLike;
45
+ respondWith(response: Promise<ResponseLike>): void;
46
+ }
47
+ export interface MessageEventLike extends ExtendableEventLike {
48
+ readonly data: unknown;
49
+ }
50
+ export interface CacheLike {
51
+ match(request: RequestLike | string): Promise<ResponseLike | undefined>;
52
+ put(request: RequestLike | string, response: ResponseLike): Promise<void>;
53
+ addAll(urls: readonly string[]): Promise<void>;
54
+ keys(): Promise<readonly RequestLike[]>;
55
+ delete(request: RequestLike | string): Promise<boolean>;
56
+ }
57
+ export interface CacheStorageLike {
58
+ open(name: string): Promise<CacheLike>;
59
+ keys(): Promise<string[]>;
60
+ delete(name: string): Promise<boolean>;
61
+ }
62
+ export interface WindowClientLike {
63
+ postMessage(message: unknown): void;
64
+ }
65
+ export interface ClientsLike {
66
+ claim(): Promise<void>;
67
+ matchAll(options: {
68
+ type: 'window';
69
+ }): Promise<readonly WindowClientLike[]>;
70
+ }
71
+ export interface ResponseInitLike {
72
+ readonly status?: number;
73
+ readonly headers?: Record<string, string>;
74
+ }
75
+ export interface ServiceWorkerScope {
76
+ addEventListener(type: 'install' | 'activate', handler: (event: ExtendableEventLike) => void): void;
77
+ addEventListener(type: 'fetch', handler: (event: FetchEventLike) => void): void;
78
+ addEventListener(type: 'message', handler: (event: MessageEventLike) => void): void;
79
+ readonly caches: CacheStorageLike;
80
+ readonly clients: ClientsLike;
81
+ readonly registration: {
82
+ unregister(): Promise<boolean>;
83
+ };
84
+ readonly location: {
85
+ readonly origin: string;
86
+ };
87
+ readonly Response: new (body: string | null, init?: ResponseInitLike) => ResponseLike;
88
+ fetch(request: RequestLike): Promise<ResponseLike>;
89
+ skipWaiting(): Promise<void>;
90
+ setTimeout(handler: () => void, ms: number): unknown;
91
+ }
92
+ /** Messages the page may send the worker. Part of the public PWA contract. */
93
+ export declare const SW_MESSAGE_PURGE = "cogenta:purge";
94
+ export declare const SW_MESSAGE_UNREGISTER = "cogenta:unregister";
95
+ export declare const SW_MESSAGE_ACTIVATED = "cogenta:activated";
96
+ export declare const SW_MESSAGE_UNREGISTERED = "cogenta:unregistered";
97
+ export declare function serviceWorkerMain(scope: ServiceWorkerScope, config: PwaConfig): void;
98
+ /**
99
+ * The tombstone worker.
100
+ *
101
+ * Deployed at the *same URL* as the real worker when the PWA has to be turned
102
+ * off. It registers no fetch handler, empties every cache the site owns and
103
+ * unregisters itself. Browsers re-fetch a service worker script at least every
104
+ * 24 hours, so shipping this file is the only mechanism that reaches clients we
105
+ * can no longer run code on — which is precisely the situation the "zombie
106
+ * worker" incident describes.
107
+ */
108
+ export declare function tombstoneMain(scope: ServiceWorkerScope, cachePrefix: string): void;
109
+ //# sourceMappingURL=sw-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw-runtime.d.ts","sourceRoot":"","sources":["../../src/pwa/sw-runtime.ts"],"names":[],"mappings":"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"}