@serwist/svelte 9.4.4 → 9.5.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.
@@ -0,0 +1,14 @@
1
+ import { type InjectManifestOptions } from "@serwist/build";
2
+ import type { Optional } from "@serwist/utils";
3
+ import type { Adapter } from "@sveltejs/kit";
4
+ export interface SerwistOptions extends Optional<Omit<InjectManifestOptions, "swSrc" | "swDest">, "globDirectory"> {
5
+ }
6
+ export declare const DEFAULT_GLOB_PATTERNS: string[];
7
+ /**
8
+ * Adapter post-processing a SvelteKit service worker. Accepts another adapter.
9
+ *
10
+ * @param adapter
11
+ * @returns
12
+ */
13
+ export declare const serwist: (adapter?: Adapter, options?: SerwistOptions) => Adapter;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,qBAAqB,EAAkB,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,cAAe,SAAQ,QAAQ,CAAC,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,QAAQ,CAAC,EAAE,eAAe,CAAC;CAAG;AAErH,eAAO,MAAM,qBAAqB,UAIjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,OAAO,aAAc,OAAO,YAAY,cAAc,KAAG,OA6ErE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,91 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { injectManifest } from "@serwist/build";
4
+ export const DEFAULT_GLOB_PATTERNS = [
5
+ "client/**/*.{js,css,ico,png,svg,webp,json,webmanifest}",
6
+ "prerendered/pages/**/*.html",
7
+ "prerendered/dependencies/**/__data.json",
8
+ ];
9
+ /**
10
+ * Adapter post-processing a SvelteKit service worker. Accepts another adapter.
11
+ *
12
+ * @param adapter
13
+ * @returns
14
+ */
15
+ export const serwist = (adapter, options) => {
16
+ return {
17
+ ...adapter,
18
+ name: adapter ? `${adapter.name} + @serwist/svelte` : `@serwist/svelte`,
19
+ async adapt(builder) {
20
+ let buildAssetsDir = builder.config.kit.appDir;
21
+ if (buildAssetsDir[0] === "/") {
22
+ buildAssetsDir = buildAssetsDir.slice(1);
23
+ }
24
+ if (buildAssetsDir[buildAssetsDir.length - 1] !== "/") {
25
+ buildAssetsDir += "/";
26
+ }
27
+ const swSrc = path.join(builder.getClientDirectory(), "service-worker.js");
28
+ if (!existsSync(swSrc)) {
29
+ builder.log.warn("Failed to locate service worker.");
30
+ }
31
+ else {
32
+ const { count, size, warnings } = await injectManifest({
33
+ dontCacheBustURLsMatching: new RegExp(`^client/${buildAssetsDir}immutable/`),
34
+ globDirectory: builder.getBuildDirectory("output"),
35
+ globPatterns: DEFAULT_GLOB_PATTERNS,
36
+ ...options,
37
+ swSrc,
38
+ swDest: swSrc,
39
+ globIgnores: ["server/*.*", "client/service-worker.js", ...(options?.globIgnores ?? [])],
40
+ manifestTransforms: [
41
+ ...(options?.manifestTransforms ?? []),
42
+ // This `manifestTransform` makes the precache manifest valid.
43
+ async (entries) => {
44
+ const manifest = entries.map((e) => {
45
+ // Static assets are in the ".svelte-kit/output/client" directory.
46
+ // Prerender pages are in the ".svelte-kit/output/prerendered/pages" directory.
47
+ // Remove the prefix, but keep the ending slash.
48
+ if (e.url.startsWith("client/")) {
49
+ e.url = e.url.slice(6);
50
+ }
51
+ else if (e.url.startsWith("prerendered/pages/")) {
52
+ e.url = e.url.slice(17);
53
+ }
54
+ else if (e.url.startsWith("prerendered/dependencies/")) {
55
+ e.url = e.url.slice(24);
56
+ }
57
+ if (e.url.endsWith(".html")) {
58
+ // trailingSlash: 'always'
59
+ // https://kit.svelte.dev/docs/page-options#trailingslash
60
+ // "/abc/index.html" -> "/abc/"
61
+ // "/index.html" -> "/"
62
+ if (e.url.endsWith("/index.html")) {
63
+ e.url = e.url.slice(0, e.url.lastIndexOf("/") + 1);
64
+ }
65
+ // trailingSlash: 'ignored'
66
+ // trailingSlash: 'never'
67
+ // https://kit.svelte.dev/docs/page-options#trailingslash
68
+ // "/xxx.html" -> "/xxx"
69
+ else {
70
+ e.url = e.url.substring(0, e.url.lastIndexOf("."));
71
+ }
72
+ }
73
+ // Finally, prepend `viteConfig.base`.
74
+ // "/path" -> "/base/path"
75
+ // "/" -> "/base/"
76
+ e.url = path.posix.join(builder.config.kit.paths.base, e.url);
77
+ return e;
78
+ });
79
+ return { manifest };
80
+ },
81
+ ],
82
+ });
83
+ builder.log(`Generated service worker with ${count} precache entries (${(size / 1024).toFixed(2)} KiB)`);
84
+ if (warnings && warnings.length > 0) {
85
+ builder.log.warn(warnings.join("\n"));
86
+ }
87
+ }
88
+ return adapter?.adapt(builder);
89
+ },
90
+ };
91
+ };
@@ -0,0 +1,10 @@
1
+ import { Serwist } from "@serwist/window";
2
+ declare global {
3
+ interface Window {
4
+ serwist: Serwist | undefined;
5
+ }
6
+ }
7
+ export declare const useSerwist: (swUrl: string, registerOptions?: RegistrationOptions) => {
8
+ readonly serwist: Serwist | null;
9
+ };
10
+ //# sourceMappingURL=index.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.svelte.d.ts","sourceRoot":"","sources":["../src/lib/index.svelte.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;KAC9B;CACF;AAED,eAAO,MAAM,UAAU,UAAW,MAAM,oBAAoB,mBAAmB;;CAa9E,CAAC"}
@@ -0,0 +1,18 @@
1
+ /// <reference types="svelte" />
2
+ import { Serwist } from "@serwist/window";
3
+ import { BROWSER } from "esm-env";
4
+ export const useSerwist = (swUrl, registerOptions) => {
5
+ const serwist = $derived.by(() => {
6
+ if (!BROWSER)
7
+ return null;
8
+ if (!(window.serwist && window.serwist instanceof Serwist) && "serviceWorker" in navigator) {
9
+ window.serwist = new Serwist(swUrl, registerOptions);
10
+ }
11
+ return window.serwist ?? null;
12
+ });
13
+ return {
14
+ get serwist() {
15
+ return serwist;
16
+ },
17
+ };
18
+ };
@@ -1,3 +1,4 @@
1
+ /// <reference types="@sveltejs/kit" />
1
2
  import type { PrecacheEntry, RuntimeCaching } from "serwist";
2
3
  import { base as basePath, build as immutableAssets, prerendered as prerenderedRoutes, version as serviceWorkerVersion, files as staticAssets } from "$service-worker";
3
4
  export { basePath, immutableAssets, staticAssets, prerenderedRoutes, serviceWorkerVersion };
@@ -1 +1 @@
1
- {"version":3,"file":"index.worker.d.ts","sourceRoot":"","sources":["../src/index.worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI7D,OAAO,EACL,IAAI,IAAI,QAAQ,EAChB,KAAK,IAAI,eAAe,EACxB,WAAW,IAAI,iBAAiB,EAChC,OAAO,IAAI,oBAAoB,EAC/B,KAAK,IAAI,YAAY,EACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,CAAC;AAE5F,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAExE,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK;IAC7D,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACjC,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,mGAMjC,0BAA+B,KAAG,aAAa,EAAE,GAAG,SA2CtD,CAAC;AAEF,eAAO,MAAM,0BAA0B,UAAgC,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,EAmHpC,CAAC"}
1
+ {"version":3,"file":"index.worker.d.ts","sourceRoot":"","sources":["../src/lib/index.worker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI7D,OAAO,EACL,IAAI,IAAI,QAAQ,EAChB,KAAK,IAAI,eAAe,EACxB,WAAW,IAAI,iBAAiB,EAChC,OAAO,IAAI,oBAAoB,EAC/B,KAAK,IAAI,YAAY,EACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,CAAC;AAE5F,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAExE,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK;IAC7D,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACjC,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,sGAM7B,0BAA0B,KAAQ,aAAa,EAAE,GAAG,SA2CtD,CAAC;AAEF,eAAO,MAAM,0BAA0B,UAAgC,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,EAmHpC,CAAC"}
@@ -1,27 +1,38 @@
1
- import { NetworkOnly, CacheFirst, StaleWhileRevalidate, NetworkFirst, ExpirationPlugin } from 'serwist';
2
- import { logger } from 'serwist/internal';
3
- import { build, files, prerendered, version } from '$service-worker';
4
- export { base as basePath, build as immutableAssets, prerendered as prerenderedRoutes, version as serviceWorkerVersion, files as staticAssets } from '$service-worker';
5
-
6
- const getPrecacheManifest = ({ precacheImmutable = true, precacheStatic = true, precachePrerendered = true, staticRevisions, manifestTransforms } = {})=>{
7
- const staticMapper = (url)=>({
8
- url,
9
- revision: typeof staticRevisions === "string" ? staticRevisions : typeof staticRevisions === "object" ? url in staticRevisions ? staticRevisions[url] : version : version
10
- });
1
+ import { DEV } from "esm-env";
2
+ import { CacheFirst, ExpirationPlugin, NetworkFirst, NetworkOnly, StaleWhileRevalidate } from "serwist";
3
+ import { logger } from "serwist/internal";
4
+ import { base as basePath, build as immutableAssets, prerendered as prerenderedRoutes, version as serviceWorkerVersion, files as staticAssets, } from "$service-worker";
5
+ export { basePath, immutableAssets, staticAssets, prerenderedRoutes, serviceWorkerVersion };
6
+ /**
7
+ * Retrieves the precache manifest generated by SvelteKit. A simple
8
+ * wrapper around SvelteKit's built-in service worker support. For more
9
+ * complex use cases, seek [the `@serwist/vite` recipe for SvelteKit](https://serwist.pages.dev/docs/vite/recipes/svelte-kit).
10
+ *
11
+ * @param options
12
+ * @returns
13
+ */
14
+ export const getPrecacheManifest = ({ precacheImmutable = true, precacheStatic = true, precachePrerendered = true, staticRevisions, manifestTransforms, } = {}) => {
15
+ const staticMapper = (url) => ({
16
+ url,
17
+ revision: typeof staticRevisions === "string"
18
+ ? staticRevisions
19
+ : typeof staticRevisions === "object"
20
+ ? url in staticRevisions
21
+ ? staticRevisions[url]
22
+ : serviceWorkerVersion
23
+ : serviceWorkerVersion,
24
+ });
11
25
  let precacheManifest = [
12
- ...precacheImmutable ? build.map((url)=>({
13
- url,
14
- revision: null
15
- })) : [],
16
- ...precacheStatic ? files.map(staticMapper) : [],
17
- ...precachePrerendered ? prerendered.map((url)=>({
18
- url,
19
- revision: version
20
- })) : []
26
+ // Immutable files generated by Vite.
27
+ ...(precacheImmutable ? immutableAssets.map((url) => ({ url, revision: null })) : []),
28
+ // Files in the static directory.
29
+ ...(precacheStatic ? staticAssets.map(staticMapper) : []),
30
+ // Prerendered routes.
31
+ ...(precachePrerendered ? prerenderedRoutes.map((url) => ({ url, revision: serviceWorkerVersion })) : []),
21
32
  ];
22
33
  if (manifestTransforms) {
23
34
  const allWarnings = [];
24
- for (const transform of manifestTransforms){
35
+ for (const transform of manifestTransforms) {
25
36
  const result = transform(precacheManifest);
26
37
  if (!("manifest" in result)) {
27
38
  if (process.env.NODE_ENV !== "production") {
@@ -30,12 +41,12 @@ const getPrecacheManifest = ({ precacheImmutable = true, precacheStatic = true,
30
41
  return undefined;
31
42
  }
32
43
  precacheManifest = result.manifest;
33
- allWarnings.push(...result.warnings || []);
44
+ allWarnings.push(...(result.warnings || []));
34
45
  }
35
46
  if (process.env.NODE_ENV !== "production" && allWarnings.length > 0) {
36
47
  logger.warn("Received warnings while transforming the precache manifest.");
37
48
  logger.groupCollapsed("View details here.");
38
- for (const warning of allWarnings){
49
+ for (const warning of allWarnings) {
39
50
  logger.warn(warning);
40
51
  }
41
52
  logger.groupEnd();
@@ -43,122 +54,126 @@ const getPrecacheManifest = ({ precacheImmutable = true, precacheStatic = true,
43
54
  }
44
55
  return precacheManifest;
45
56
  };
46
- const defaultIgnoreUrlParameters = [
47
- /^x-sveltekit-invalidated$/
48
- ];
49
- const defaultCache = import.meta.env.DEV ? [
50
- {
51
- matcher: /.*/i,
52
- handler: new NetworkOnly()
53
- }
54
- ] : [
55
- {
56
- matcher: /^https:\/\/fonts\.(?:googleapis|gstatic)\.com\/.*/i,
57
- handler: new CacheFirst({
58
- cacheName: "google-fonts",
59
- plugins: [
60
- new ExpirationPlugin({
61
- maxEntries: 4,
62
- maxAgeSeconds: 365 * 24 * 60 * 60,
63
- maxAgeFrom: "last-used"
64
- })
65
- ]
66
- })
67
- },
68
- {
69
- matcher: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
70
- handler: new StaleWhileRevalidate({
71
- cacheName: "static-font-assets",
72
- plugins: [
73
- new ExpirationPlugin({
74
- maxEntries: 4,
75
- maxAgeSeconds: 7 * 24 * 60 * 60,
76
- maxAgeFrom: "last-used"
77
- })
78
- ]
79
- })
80
- },
81
- {
82
- matcher: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
83
- handler: new StaleWhileRevalidate({
84
- cacheName: "static-image-assets",
85
- plugins: [
86
- new ExpirationPlugin({
87
- maxEntries: 64,
88
- maxAgeSeconds: 24 * 60 * 60,
89
- maxAgeFrom: "last-used"
90
- })
91
- ]
92
- })
93
- },
94
- {
95
- matcher: /\.(?:js)$/i,
96
- handler: new StaleWhileRevalidate({
97
- cacheName: "static-js-assets",
98
- plugins: [
99
- new ExpirationPlugin({
100
- maxEntries: 32,
101
- maxAgeSeconds: 24 * 60 * 60,
102
- maxAgeFrom: "last-used"
103
- })
104
- ]
105
- })
106
- },
107
- {
108
- matcher: /\.(?:css|less)$/i,
109
- handler: new StaleWhileRevalidate({
110
- cacheName: "static-style-assets",
111
- plugins: [
112
- new ExpirationPlugin({
113
- maxEntries: 32,
114
- maxAgeSeconds: 24 * 60 * 60,
115
- maxAgeFrom: "last-used"
116
- })
117
- ]
118
- })
119
- },
120
- {
121
- matcher: /\.(?:json|xml|csv)$/i,
122
- handler: new NetworkFirst({
123
- cacheName: "static-data-assets",
124
- plugins: [
125
- new ExpirationPlugin({
126
- maxEntries: 32,
127
- maxAgeSeconds: 24 * 60 * 60,
128
- maxAgeFrom: "last-used"
129
- })
130
- ]
131
- })
132
- },
133
- {
134
- matcher: /\/api\/.*$/i,
135
- method: "GET",
136
- handler: new NetworkFirst({
137
- cacheName: "apis",
138
- plugins: [
139
- new ExpirationPlugin({
140
- maxEntries: 16,
141
- maxAgeSeconds: 24 * 60 * 60,
142
- maxAgeFrom: "last-used"
143
- })
144
- ],
145
- networkTimeoutSeconds: 10
146
- })
147
- },
148
- {
149
- matcher: /.*/i,
150
- handler: new NetworkFirst({
151
- cacheName: "others",
152
- plugins: [
153
- new ExpirationPlugin({
154
- maxEntries: 32,
155
- maxAgeSeconds: 24 * 60 * 60,
156
- maxAgeFrom: "last-used"
157
- })
158
- ],
159
- networkTimeoutSeconds: 10
160
- })
161
- }
162
- ];
163
-
164
- export { defaultCache, defaultIgnoreUrlParameters, getPrecacheManifest };
57
+ export const defaultIgnoreUrlParameters = [/^x-sveltekit-invalidated$/];
58
+ /**
59
+ * The default, recommended list of caching strategies for applications
60
+ * built with SvelteKit.
61
+ *
62
+ * @see https://serwist.pages.dev/docs/svelte/worker-exports#default-cache
63
+ */
64
+ export const defaultCache = DEV
65
+ ? [
66
+ {
67
+ matcher: /.*/i,
68
+ handler: new NetworkOnly(),
69
+ },
70
+ ]
71
+ : [
72
+ {
73
+ matcher: /^https:\/\/fonts\.(?:googleapis|gstatic)\.com\/.*/i,
74
+ handler: new CacheFirst({
75
+ cacheName: "google-fonts",
76
+ plugins: [
77
+ new ExpirationPlugin({
78
+ maxEntries: 4,
79
+ maxAgeSeconds: 365 * 24 * 60 * 60, // 365 days
80
+ maxAgeFrom: "last-used",
81
+ }),
82
+ ],
83
+ }),
84
+ },
85
+ {
86
+ matcher: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
87
+ handler: new StaleWhileRevalidate({
88
+ cacheName: "static-font-assets",
89
+ plugins: [
90
+ new ExpirationPlugin({
91
+ maxEntries: 4,
92
+ maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
93
+ maxAgeFrom: "last-used",
94
+ }),
95
+ ],
96
+ }),
97
+ },
98
+ {
99
+ matcher: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
100
+ handler: new StaleWhileRevalidate({
101
+ cacheName: "static-image-assets",
102
+ plugins: [
103
+ new ExpirationPlugin({
104
+ maxEntries: 64,
105
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
106
+ maxAgeFrom: "last-used",
107
+ }),
108
+ ],
109
+ }),
110
+ },
111
+ {
112
+ matcher: /\.(?:js)$/i,
113
+ handler: new StaleWhileRevalidate({
114
+ cacheName: "static-js-assets",
115
+ plugins: [
116
+ new ExpirationPlugin({
117
+ maxEntries: 32,
118
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
119
+ maxAgeFrom: "last-used",
120
+ }),
121
+ ],
122
+ }),
123
+ },
124
+ {
125
+ matcher: /\.(?:css|less)$/i,
126
+ handler: new StaleWhileRevalidate({
127
+ cacheName: "static-style-assets",
128
+ plugins: [
129
+ new ExpirationPlugin({
130
+ maxEntries: 32,
131
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
132
+ maxAgeFrom: "last-used",
133
+ }),
134
+ ],
135
+ }),
136
+ },
137
+ {
138
+ matcher: /\.(?:json|xml|csv)$/i,
139
+ handler: new NetworkFirst({
140
+ cacheName: "static-data-assets",
141
+ plugins: [
142
+ new ExpirationPlugin({
143
+ maxEntries: 32,
144
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
145
+ maxAgeFrom: "last-used",
146
+ }),
147
+ ],
148
+ }),
149
+ },
150
+ {
151
+ matcher: /\/api\/.*$/i,
152
+ method: "GET",
153
+ handler: new NetworkFirst({
154
+ cacheName: "apis",
155
+ plugins: [
156
+ new ExpirationPlugin({
157
+ maxEntries: 16,
158
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
159
+ maxAgeFrom: "last-used",
160
+ }),
161
+ ],
162
+ networkTimeoutSeconds: 10, // fallback to cache if API does not response within 10 seconds
163
+ }),
164
+ },
165
+ {
166
+ matcher: /.*/i,
167
+ handler: new NetworkFirst({
168
+ cacheName: "others",
169
+ plugins: [
170
+ new ExpirationPlugin({
171
+ maxEntries: 32,
172
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
173
+ maxAgeFrom: "last-used",
174
+ }),
175
+ ],
176
+ networkTimeoutSeconds: 10,
177
+ }),
178
+ },
179
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serwist/svelte",
3
- "version": "9.4.4",
3
+ "version": "9.5.0",
4
4
  "type": "module",
5
5
  "description": "A module that complements SvelteKit's built-in service worker support.",
6
6
  "files": [
@@ -25,14 +25,27 @@
25
25
  "repository": "https://github.com/serwist/serwist",
26
26
  "bugs": "https://github.com/serwist/serwist/issues",
27
27
  "homepage": "https://serwist.pages.dev",
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
28
30
  "typesVersions": {
29
31
  "*": {
32
+ "client": [
33
+ "./dist/index.svelte.d.ts"
34
+ ],
30
35
  "worker": [
31
36
  "./dist/index.worker.d.ts"
32
37
  ]
33
38
  }
34
39
  },
35
40
  "exports": {
41
+ ".": {
42
+ "types": "./dist/index.d.ts",
43
+ "default": "./dist/index.js"
44
+ },
45
+ "./client": {
46
+ "types": "./dist/index.svelte.d.ts",
47
+ "svelte": "./dist/index.svelte.js"
48
+ },
36
49
  "./worker": {
37
50
  "types": "./dist/index.worker.d.ts",
38
51
  "default": "./dist/index.worker.js"
@@ -40,25 +53,33 @@
40
53
  "./package.json": "./package.json"
41
54
  },
42
55
  "dependencies": {
43
- "serwist": "9.4.4"
56
+ "@sveltejs/package": "2.5.7",
57
+ "esm-env": "1.2.2",
58
+ "@serwist/build": "9.5.0",
59
+ "@serwist/utils": "9.5.0",
60
+ "@serwist/window": "9.5.0",
61
+ "serwist": "9.5.0"
44
62
  },
45
63
  "devDependencies": {
46
64
  "@sveltejs/kit": "2.49.2",
47
- "rollup": "4.54.0",
48
- "@serwist/configs": "9.4.4"
65
+ "svelte": "5.46.1"
49
66
  },
50
67
  "peerDependencies": {
51
68
  "@sveltejs/kit": ">=2.0.0",
69
+ "svelte": ">=5.0.0",
52
70
  "typescript": ">=5.0.0"
53
71
  },
54
72
  "peerDependenciesMeta": {
73
+ "svelte": {
74
+ "optional": true
75
+ },
55
76
  "typescript": {
56
77
  "optional": true
57
78
  }
58
79
  },
59
80
  "scripts": {
60
- "build": "rimraf dist && NODE_ENV=production rollup --config rollup.config.js",
61
- "dev": "rollup --config rollup.config.js --watch",
81
+ "build": "rimraf dist && svelte-package",
82
+ "dev": "svelte-package --watch",
62
83
  "lint": "biome lint ./src",
63
84
  "typecheck": "tsc"
64
85
  }
@@ -0,0 +1,24 @@
1
+ /// <reference types="svelte" />
2
+ import { Serwist } from "@serwist/window";
3
+ import { BROWSER } from "esm-env";
4
+
5
+ declare global {
6
+ interface Window {
7
+ serwist: Serwist | undefined;
8
+ }
9
+ }
10
+
11
+ export const useSerwist = (swUrl: string, registerOptions?: RegistrationOptions) => {
12
+ const serwist = $derived.by(() => {
13
+ if (!BROWSER) return null;
14
+ if (!(window.serwist && window.serwist instanceof Serwist) && "serviceWorker" in navigator) {
15
+ window.serwist = new Serwist(swUrl, registerOptions);
16
+ }
17
+ return window.serwist ?? null;
18
+ });
19
+ return {
20
+ get serwist() {
21
+ return serwist;
22
+ },
23
+ };
24
+ };
@@ -0,0 +1,98 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { type InjectManifestOptions, injectManifest } from "@serwist/build";
4
+ import type { Optional } from "@serwist/utils";
5
+ import type { Adapter } from "@sveltejs/kit";
6
+
7
+ export interface SerwistOptions extends Optional<Omit<InjectManifestOptions, "swSrc" | "swDest">, "globDirectory"> {}
8
+
9
+ export const DEFAULT_GLOB_PATTERNS = [
10
+ "client/**/*.{js,css,ico,png,svg,webp,json,webmanifest}",
11
+ "prerendered/pages/**/*.html",
12
+ "prerendered/dependencies/**/__data.json",
13
+ ];
14
+
15
+ /**
16
+ * Adapter post-processing a SvelteKit service worker. Accepts another adapter.
17
+ *
18
+ * @param adapter
19
+ * @returns
20
+ */
21
+ export const serwist = (adapter?: Adapter, options?: SerwistOptions): Adapter => {
22
+ return {
23
+ ...adapter,
24
+ name: adapter ? `${adapter.name} + @serwist/svelte` : `@serwist/svelte`,
25
+ async adapt(builder) {
26
+ let buildAssetsDir = builder.config.kit.appDir;
27
+ if (buildAssetsDir[0] === "/") {
28
+ buildAssetsDir = buildAssetsDir.slice(1);
29
+ }
30
+ if (buildAssetsDir[buildAssetsDir.length - 1] !== "/") {
31
+ buildAssetsDir += "/";
32
+ }
33
+ const swSrc = path.join(builder.getClientDirectory(), "service-worker.js");
34
+ if (!existsSync(swSrc)) {
35
+ builder.log.warn("Failed to locate service worker.");
36
+ } else {
37
+ const { count, size, warnings } = await injectManifest({
38
+ dontCacheBustURLsMatching: new RegExp(`^client/${buildAssetsDir}immutable/`),
39
+ globDirectory: builder.getBuildDirectory("output"),
40
+ globPatterns: DEFAULT_GLOB_PATTERNS,
41
+ ...options,
42
+ swSrc,
43
+ swDest: swSrc,
44
+ globIgnores: ["server/*.*", "client/service-worker.js", ...(options?.globIgnores ?? [])],
45
+ manifestTransforms: [
46
+ ...(options?.manifestTransforms ?? []),
47
+ // This `manifestTransform` makes the precache manifest valid.
48
+ async (entries) => {
49
+ const manifest = entries.map((e) => {
50
+ // Static assets are in the ".svelte-kit/output/client" directory.
51
+ // Prerender pages are in the ".svelte-kit/output/prerendered/pages" directory.
52
+ // Remove the prefix, but keep the ending slash.
53
+ if (e.url.startsWith("client/")) {
54
+ e.url = e.url.slice(6);
55
+ } else if (e.url.startsWith("prerendered/pages/")) {
56
+ e.url = e.url.slice(17);
57
+ } else if (e.url.startsWith("prerendered/dependencies/")) {
58
+ e.url = e.url.slice(24);
59
+ }
60
+
61
+ if (e.url.endsWith(".html")) {
62
+ // trailingSlash: 'always'
63
+ // https://kit.svelte.dev/docs/page-options#trailingslash
64
+ // "/abc/index.html" -> "/abc/"
65
+ // "/index.html" -> "/"
66
+ if (e.url.endsWith("/index.html")) {
67
+ e.url = e.url.slice(0, e.url.lastIndexOf("/") + 1);
68
+ }
69
+ // trailingSlash: 'ignored'
70
+ // trailingSlash: 'never'
71
+ // https://kit.svelte.dev/docs/page-options#trailingslash
72
+ // "/xxx.html" -> "/xxx"
73
+ else {
74
+ e.url = e.url.substring(0, e.url.lastIndexOf("."));
75
+ }
76
+ }
77
+
78
+ // Finally, prepend `viteConfig.base`.
79
+ // "/path" -> "/base/path"
80
+ // "/" -> "/base/"
81
+ e.url = path.posix.join(builder.config.kit.paths.base, e.url);
82
+
83
+ return e;
84
+ });
85
+
86
+ return { manifest };
87
+ },
88
+ ],
89
+ });
90
+ builder.log(`Generated service worker with ${count} precache entries (${(size / 1024).toFixed(2)} KiB)`);
91
+ if (warnings && warnings.length > 0) {
92
+ builder.log.warn(warnings.join("\n"));
93
+ }
94
+ }
95
+ return adapter?.adapt(builder);
96
+ },
97
+ };
98
+ };
@@ -1,3 +1,4 @@
1
+ import { DEV } from "esm-env";
1
2
  import type { PrecacheEntry, RuntimeCaching } from "serwist";
2
3
  import { CacheFirst, ExpirationPlugin, NetworkFirst, NetworkOnly, StaleWhileRevalidate } from "serwist";
3
4
  import { logger } from "serwist/internal";
@@ -126,7 +127,7 @@ export const defaultIgnoreUrlParameters = [/^x-sveltekit-invalidated$/];
126
127
  *
127
128
  * @see https://serwist.pages.dev/docs/svelte/worker-exports#default-cache
128
129
  */
129
- export const defaultCache: RuntimeCaching[] = import.meta.env.DEV
130
+ export const defaultCache: RuntimeCaching[] = DEV
130
131
  ? [
131
132
  {
132
133
  matcher: /.*/i,