@serwist/next 9.0.0-preview.15 → 9.0.0-preview.17

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAInE;;;;GAIG;AACH,QAAA,MAAM,eAAe,gBAAiB,qBAAqB,mBAAkB,UAAU,KAAK,UAkO3F,CAAC;AAEF,eAAe,eAAe,CAAC;AAC/B,OAAO,EAAE,6BAA6B,EAAE,CAAC;AACzC,YAAY,EAAE,qBAAqB,IAAI,aAAa,EAAE,6BAA6B,IAAI,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAInE;;;;GAIG;AACH,QAAA,MAAM,eAAe,gBAAiB,qBAAqB,mBAAkB,UAAU,KAAK,UAwN3F,CAAC;AAEF,eAAe,eAAe,CAAC;AAC/B,OAAO,EAAE,6BAA6B,EAAE,CAAC;AACzC,YAAY,EAAE,qBAAqB,IAAI,aAAa,EAAE,6BAA6B,IAAI,qBAAqB,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -211,20 +211,14 @@ const withSerwistInit = (userOptions)=>{
211
211
  info(` Scope: ${_scope}`);
212
212
  let resolvedManifestEntries = additionalPrecacheEntries;
213
213
  if (!resolvedManifestEntries) {
214
- const userPublicGlob = typeof globPublicPatterns === "string" ? [
215
- globPublicPatterns
216
- ] : globPublicPatterns ?? [
217
- "**/*"
218
- ];
219
- const publicScan = globSync([
220
- ...userPublicGlob,
221
- "!swe-worker-*.js",
222
- "!swe-worker-*.js.map",
223
- `!${destBase}`,
224
- `!${destBase}.map`
225
- ], {
214
+ const publicScan = globSync(globPublicPatterns, {
226
215
  nodir: true,
227
- cwd: publicDir
216
+ cwd: publicDir,
217
+ ignore: [
218
+ "swe-worker-*.js",
219
+ destBase,
220
+ `${destBase}.map`
221
+ ]
228
222
  });
229
223
  resolvedManifestEntries = publicScan.map((f)=>({
230
224
  url: path.posix.join(basePath, f),
@@ -8,7 +8,7 @@ const PAGES_CACHE_NAME = {
8
8
  html: "pages"
9
9
  };
10
10
 
11
- const defaultCache = [
11
+ const defaultCache = process.env.NODE_ENV !== "production" ? [] : [
12
12
  {
13
13
  matcher: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,
14
14
  handler: new CacheFirst({
@@ -31,100 +31,100 @@ export declare const injectManifestOptions: z.ZodObject<Omit<{
31
31
  include: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>, z.ZodFunction<z.ZodTuple<[z.ZodAny], null>, z.ZodBoolean>]>, "many">>;
32
32
  additionalPrecacheEntries: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
33
33
  integrity: z.ZodOptional<z.ZodString>;
34
- revision: z.ZodNullable<z.ZodString>;
34
+ revision: z.ZodOptional<z.ZodNullable<z.ZodString>>;
35
35
  url: z.ZodString;
36
36
  }, "strict", z.ZodTypeAny, {
37
- revision: string | null;
38
37
  url: string;
39
38
  integrity?: string | undefined;
39
+ revision?: string | null | undefined;
40
40
  }, {
41
- revision: string | null;
42
41
  url: string;
43
42
  integrity?: string | undefined;
43
+ revision?: string | null | undefined;
44
44
  }>]>, "many">>;
45
45
  disablePrecacheManifest: z.ZodDefault<z.ZodBoolean>;
46
46
  dontCacheBustURLsMatching: z.ZodOptional<z.ZodType<RegExp, z.ZodTypeDef, RegExp>>;
47
47
  manifestTransforms: z.ZodOptional<z.ZodArray<z.ZodFunction<z.ZodTuple<[z.ZodArray<z.ZodObject<{
48
48
  integrity: z.ZodOptional<z.ZodString>;
49
- revision: z.ZodNullable<z.ZodString>;
49
+ revision: z.ZodOptional<z.ZodNullable<z.ZodString>>;
50
50
  url: z.ZodString;
51
51
  size: z.ZodNumber;
52
52
  }, "strip", z.ZodTypeAny, {
53
- revision: string | null;
54
53
  url: string;
55
54
  size: number;
56
55
  integrity?: string | undefined;
56
+ revision?: string | null | undefined;
57
57
  }, {
58
- revision: string | null;
59
58
  url: string;
60
59
  size: number;
61
60
  integrity?: string | undefined;
61
+ revision?: string | null | undefined;
62
62
  }>, "many">, z.ZodOptional<z.ZodUnknown>], null>, z.ZodUnion<[z.ZodPromise<z.ZodObject<{
63
63
  manifest: z.ZodArray<z.ZodObject<{
64
64
  integrity: z.ZodOptional<z.ZodString>;
65
- revision: z.ZodNullable<z.ZodString>;
65
+ revision: z.ZodOptional<z.ZodNullable<z.ZodString>>;
66
66
  url: z.ZodString;
67
67
  size: z.ZodNumber;
68
68
  }, "strip", z.ZodTypeAny, {
69
- revision: string | null;
70
69
  url: string;
71
70
  size: number;
72
71
  integrity?: string | undefined;
72
+ revision?: string | null | undefined;
73
73
  }, {
74
- revision: string | null;
75
74
  url: string;
76
75
  size: number;
77
76
  integrity?: string | undefined;
77
+ revision?: string | null | undefined;
78
78
  }>, "many">;
79
79
  warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
80
80
  }, "strict", z.ZodTypeAny, {
81
81
  manifest: {
82
- revision: string | null;
83
82
  url: string;
84
83
  size: number;
85
84
  integrity?: string | undefined;
85
+ revision?: string | null | undefined;
86
86
  }[];
87
87
  warnings?: string[] | undefined;
88
88
  }, {
89
89
  manifest: {
90
- revision: string | null;
91
90
  url: string;
92
91
  size: number;
93
92
  integrity?: string | undefined;
93
+ revision?: string | null | undefined;
94
94
  }[];
95
95
  warnings?: string[] | undefined;
96
96
  }>>, z.ZodObject<{
97
97
  manifest: z.ZodArray<z.ZodObject<{
98
98
  integrity: z.ZodOptional<z.ZodString>;
99
- revision: z.ZodNullable<z.ZodString>;
99
+ revision: z.ZodOptional<z.ZodNullable<z.ZodString>>;
100
100
  url: z.ZodString;
101
101
  size: z.ZodNumber;
102
102
  }, "strip", z.ZodTypeAny, {
103
- revision: string | null;
104
103
  url: string;
105
104
  size: number;
106
105
  integrity?: string | undefined;
106
+ revision?: string | null | undefined;
107
107
  }, {
108
- revision: string | null;
109
108
  url: string;
110
109
  size: number;
111
110
  integrity?: string | undefined;
111
+ revision?: string | null | undefined;
112
112
  }>, "many">;
113
113
  warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
114
114
  }, "strict", z.ZodTypeAny, {
115
115
  manifest: {
116
- revision: string | null;
117
116
  url: string;
118
117
  size: number;
119
118
  integrity?: string | undefined;
119
+ revision?: string | null | undefined;
120
120
  }[];
121
121
  warnings?: string[] | undefined;
122
122
  }, {
123
123
  manifest: {
124
- revision: string | null;
125
124
  url: string;
126
125
  size: number;
127
126
  integrity?: string | undefined;
127
+ revision?: string | null | undefined;
128
128
  }[];
129
129
  warnings?: string[] | undefined;
130
130
  }>]>>, "many">>;
@@ -160,30 +160,30 @@ export declare const injectManifestOptions: z.ZodObject<Omit<{
160
160
  excludeChunks?: string[] | undefined;
161
161
  include?: (string | RegExp | ((args_0: any) => boolean))[] | undefined;
162
162
  additionalPrecacheEntries?: (string | {
163
- revision: string | null;
164
163
  url: string;
165
164
  integrity?: string | undefined;
165
+ revision?: string | null | undefined;
166
166
  })[] | undefined;
167
167
  dontCacheBustURLsMatching?: RegExp | undefined;
168
168
  manifestTransforms?: ((args_0: {
169
- revision: string | null;
170
169
  url: string;
171
170
  size: number;
172
171
  integrity?: string | undefined;
172
+ revision?: string | null | undefined;
173
173
  }[], args_1: unknown) => {
174
174
  manifest: {
175
- revision: string | null;
176
175
  url: string;
177
176
  size: number;
178
177
  integrity?: string | undefined;
178
+ revision?: string | null | undefined;
179
179
  }[];
180
180
  warnings?: string[] | undefined;
181
181
  } | Promise<{
182
182
  manifest: {
183
- revision: string | null;
184
183
  url: string;
185
184
  size: number;
186
185
  integrity?: string | undefined;
186
+ revision?: string | null | undefined;
187
187
  }[];
188
188
  warnings?: string[] | undefined;
189
189
  }>)[] | undefined;
@@ -204,30 +204,30 @@ export declare const injectManifestOptions: z.ZodObject<Omit<{
204
204
  excludeChunks?: string[] | undefined;
205
205
  include?: (string | RegExp | ((args_0: any) => boolean))[] | undefined;
206
206
  additionalPrecacheEntries?: (string | {
207
- revision: string | null;
208
207
  url: string;
209
208
  integrity?: string | undefined;
209
+ revision?: string | null | undefined;
210
210
  })[] | undefined;
211
211
  dontCacheBustURLsMatching?: RegExp | undefined;
212
212
  manifestTransforms?: ((args_0: {
213
- revision: string | null;
214
213
  url: string;
215
214
  size: number;
216
215
  integrity?: string | undefined;
216
+ revision?: string | null | undefined;
217
217
  }[], args_1: unknown) => {
218
218
  manifest: {
219
- revision: string | null;
220
219
  url: string;
221
220
  size: number;
222
221
  integrity?: string | undefined;
222
+ revision?: string | null | undefined;
223
223
  }[];
224
224
  warnings?: string[] | undefined;
225
225
  } | Promise<{
226
226
  manifest: {
227
- revision: string | null;
228
227
  url: string;
229
228
  size: number;
230
229
  integrity?: string | undefined;
230
+ revision?: string | null | undefined;
231
231
  }[];
232
232
  warnings?: string[] | undefined;
233
233
  }>)[] | undefined;
@@ -1,3 +1,9 @@
1
1
  import type { RuntimeCaching } from "@serwist/sw";
2
+ /**
3
+ * The default, recommended list of caching strategies for applications
4
+ * built with Next.js.
5
+ *
6
+ * @see https://serwist.pages.dev/docs/next/worker-exports#default-cache
7
+ */
2
8
  export declare const defaultCache: RuntimeCaching[];
3
9
  //# sourceMappingURL=defaultCache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaultCache.d.ts","sourceRoot":"","sources":["../../src/worker/defaultCache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,eAAO,MAAM,YAAY,EAAE,cAAc,EA8PxC,CAAC"}
1
+ {"version":3,"file":"defaultCache.d.ts","sourceRoot":"","sources":["../../src/worker/defaultCache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,EAiQlC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serwist/next",
3
- "version": "9.0.0-preview.15",
3
+ "version": "9.0.0-preview.17",
4
4
  "type": "module",
5
5
  "description": "A module that integrates Serwist into your Next.js application.",
6
6
  "files": [
@@ -65,13 +65,13 @@
65
65
  "chalk": "5.3.0",
66
66
  "glob": "10.3.10",
67
67
  "zod": "3.22.4",
68
- "@serwist/build": "9.0.0-preview.15",
69
- "@serwist/core": "9.0.0-preview.15",
70
- "@serwist/expiration": "9.0.0-preview.15",
71
- "@serwist/range-requests": "9.0.0-preview.15",
72
- "@serwist/strategies": "9.0.0-preview.15",
73
- "@serwist/webpack-plugin": "9.0.0-preview.15",
74
- "@serwist/window": "9.0.0-preview.15"
68
+ "@serwist/build": "9.0.0-preview.17",
69
+ "@serwist/core": "9.0.0-preview.17",
70
+ "@serwist/expiration": "9.0.0-preview.17",
71
+ "@serwist/range-requests": "9.0.0-preview.17",
72
+ "@serwist/strategies": "9.0.0-preview.17",
73
+ "@serwist/webpack-plugin": "9.0.0-preview.17",
74
+ "@serwist/window": "9.0.0-preview.17"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@types/node": "20.11.30",
@@ -82,14 +82,14 @@
82
82
  "type-fest": "4.13.1",
83
83
  "typescript": "5.5.0-dev.20240323",
84
84
  "webpack": "5.91.0",
85
- "@serwist/constants": "9.0.0-preview.15",
86
- "@serwist/sw": "9.0.0-preview.15",
87
- "@serwist/utils": "9.0.0-preview.15"
85
+ "@serwist/constants": "9.0.0-preview.17",
86
+ "@serwist/sw": "9.0.0-preview.17",
87
+ "@serwist/utils": "9.0.0-preview.17"
88
88
  },
89
89
  "peerDependencies": {
90
90
  "next": ">=14.0.0",
91
91
  "typescript": ">=5.0.0",
92
- "@serwist/sw": "9.0.0-preview.15"
92
+ "@serwist/sw": "9.0.0-preview.17"
93
93
  },
94
94
  "peerDependenciesMeta": {
95
95
  "@serwist/sw": {
package/src/index.ts CHANGED
@@ -169,21 +169,11 @@ const withSerwistInit = (userOptions: InjectManifestOptions): ((nextConfig?: Nex
169
169
  let resolvedManifestEntries = additionalPrecacheEntries;
170
170
 
171
171
  if (!resolvedManifestEntries) {
172
- const userPublicGlob = typeof globPublicPatterns === "string" ? [globPublicPatterns] : globPublicPatterns ?? ["**/*"];
173
- const publicScan = globSync(
174
- [
175
- ...userPublicGlob,
176
- // Forcibly include these in case the user outputs these files to `public`.
177
- "!swe-worker-*.js",
178
- "!swe-worker-*.js.map",
179
- `!${destBase}`,
180
- `!${destBase}.map`,
181
- ],
182
- {
183
- nodir: true,
184
- cwd: publicDir,
185
- },
186
- );
172
+ const publicScan = globSync(globPublicPatterns, {
173
+ nodir: true,
174
+ cwd: publicDir,
175
+ ignore: ["swe-worker-*.js", destBase, `${destBase}.map`],
176
+ });
187
177
  resolvedManifestEntries = publicScan.map((f) => ({
188
178
  url: path.posix.join(basePath, f),
189
179
  revision: getFileHash(path.join(publicDir, f)),
@@ -5,259 +5,267 @@ import type { RuntimeCaching } from "@serwist/sw";
5
5
 
6
6
  import { PAGES_CACHE_NAME } from "./constants.js";
7
7
 
8
- // Serwist RuntimeCaching config: https://serwist.pages.dev/docs/sw/register-runtime-caching
9
- export const defaultCache: RuntimeCaching[] = [
10
- {
11
- matcher: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,
12
- handler: new CacheFirst({
13
- cacheName: "google-fonts-webfonts",
14
- plugins: [
15
- new ExpirationPlugin({
16
- maxEntries: 4,
17
- maxAgeSeconds: 365 * 24 * 60 * 60, // 365 days
18
- maxAgeFrom: "last-used",
19
- }),
20
- ],
21
- }),
22
- },
23
- {
24
- matcher: /^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,
25
- handler: new StaleWhileRevalidate({
26
- cacheName: "google-fonts-stylesheets",
27
- plugins: [
28
- new ExpirationPlugin({
29
- maxEntries: 4,
30
- maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
31
- maxAgeFrom: "last-used",
32
- }),
33
- ],
34
- }),
35
- },
36
- {
37
- matcher: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
38
- handler: new StaleWhileRevalidate({
39
- cacheName: "static-font-assets",
40
- plugins: [
41
- new ExpirationPlugin({
42
- maxEntries: 4,
43
- maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
44
- maxAgeFrom: "last-used",
45
- }),
46
- ],
47
- }),
48
- },
49
- {
50
- matcher: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
51
- handler: new StaleWhileRevalidate({
52
- cacheName: "static-image-assets",
53
- plugins: [
54
- new ExpirationPlugin({
55
- maxEntries: 64,
56
- maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
57
- maxAgeFrom: "last-used",
58
- }),
59
- ],
60
- }),
61
- },
62
- {
63
- matcher: /\/_next\/static.+\.js$/i,
64
- handler: new CacheFirst({
65
- cacheName: "next-static-js-assets",
66
- plugins: [
67
- new ExpirationPlugin({
68
- maxEntries: 64,
69
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
70
- maxAgeFrom: "last-used",
71
- }),
72
- ],
73
- }),
74
- },
75
- {
76
- matcher: /\/_next\/image\?url=.+$/i,
77
- handler: new StaleWhileRevalidate({
78
- cacheName: "next-image",
79
- plugins: [
80
- new ExpirationPlugin({
81
- maxEntries: 64,
82
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
83
- maxAgeFrom: "last-used",
84
- }),
85
- ],
86
- }),
87
- },
88
- {
89
- matcher: /\.(?:mp3|wav|ogg)$/i,
90
- handler: new CacheFirst({
91
- cacheName: "static-audio-assets",
92
- plugins: [
93
- new ExpirationPlugin({
94
- maxEntries: 32,
95
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
96
- maxAgeFrom: "last-used",
97
- }),
98
- new RangeRequestsPlugin(),
99
- ],
100
- }),
101
- },
102
- {
103
- matcher: /\.(?:mp4|webm)$/i,
104
- handler: new CacheFirst({
105
- cacheName: "static-video-assets",
106
- plugins: [
107
- new ExpirationPlugin({
108
- maxEntries: 32,
109
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
110
- maxAgeFrom: "last-used",
111
- }),
112
- new RangeRequestsPlugin(),
113
- ],
114
- }),
115
- },
116
- {
117
- matcher: /\.(?:js)$/i,
118
- handler: new StaleWhileRevalidate({
119
- cacheName: "static-js-assets",
120
- plugins: [
121
- new ExpirationPlugin({
122
- maxEntries: 48,
123
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
124
- maxAgeFrom: "last-used",
125
- }),
126
- ],
127
- }),
128
- },
129
- {
130
- matcher: /\.(?:css|less)$/i,
131
- handler: new StaleWhileRevalidate({
132
- cacheName: "static-style-assets",
133
- plugins: [
134
- new ExpirationPlugin({
135
- maxEntries: 32,
136
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
137
- maxAgeFrom: "last-used",
138
- }),
139
- ],
140
- }),
141
- },
142
- {
143
- matcher: /\/_next\/data\/.+\/.+\.json$/i,
144
- handler: new NetworkFirst({
145
- cacheName: "next-data",
146
- plugins: [
147
- new ExpirationPlugin({
148
- maxEntries: 32,
149
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
150
- maxAgeFrom: "last-used",
151
- }),
152
- ],
153
- }),
154
- },
155
- {
156
- matcher: /\.(?:json|xml|csv)$/i,
157
- handler: new NetworkFirst({
158
- cacheName: "static-data-assets",
159
- plugins: [
160
- new ExpirationPlugin({
161
- maxEntries: 32,
162
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
163
- maxAgeFrom: "last-used",
164
- }),
165
- ],
166
- }),
167
- },
168
- {
169
- matcher: ({ sameOrigin, url: { pathname } }) => {
170
- // Exclude /api/auth/callback/* to fix OAuth workflow in Safari without having
171
- // an impact on other environments
172
- // The above route is the default for next-auth, you may need to change it if
173
- // your OAuth workflow has a different callback route.
174
- // Issue: https://github.com/shadowwalker/next-pwa/issues/131#issuecomment-821894809
175
- // TODO(ducanhgh): Investigate Auth.js's "/api/auth/*" failing when we allow them
176
- // to be cached (the current behaviour).
177
- if (!sameOrigin || pathname.startsWith("/api/auth/callback")) {
178
- return false;
179
- }
8
+ /**
9
+ * The default, recommended list of caching strategies for applications
10
+ * built with Next.js.
11
+ *
12
+ * @see https://serwist.pages.dev/docs/next/worker-exports#default-cache
13
+ */
14
+ export const defaultCache: RuntimeCaching[] =
15
+ process.env.NODE_ENV !== "production"
16
+ ? []
17
+ : [
18
+ {
19
+ matcher: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,
20
+ handler: new CacheFirst({
21
+ cacheName: "google-fonts-webfonts",
22
+ plugins: [
23
+ new ExpirationPlugin({
24
+ maxEntries: 4,
25
+ maxAgeSeconds: 365 * 24 * 60 * 60, // 365 days
26
+ maxAgeFrom: "last-used",
27
+ }),
28
+ ],
29
+ }),
30
+ },
31
+ {
32
+ matcher: /^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,
33
+ handler: new StaleWhileRevalidate({
34
+ cacheName: "google-fonts-stylesheets",
35
+ plugins: [
36
+ new ExpirationPlugin({
37
+ maxEntries: 4,
38
+ maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
39
+ maxAgeFrom: "last-used",
40
+ }),
41
+ ],
42
+ }),
43
+ },
44
+ {
45
+ matcher: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
46
+ handler: new StaleWhileRevalidate({
47
+ cacheName: "static-font-assets",
48
+ plugins: [
49
+ new ExpirationPlugin({
50
+ maxEntries: 4,
51
+ maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
52
+ maxAgeFrom: "last-used",
53
+ }),
54
+ ],
55
+ }),
56
+ },
57
+ {
58
+ matcher: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
59
+ handler: new StaleWhileRevalidate({
60
+ cacheName: "static-image-assets",
61
+ plugins: [
62
+ new ExpirationPlugin({
63
+ maxEntries: 64,
64
+ maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
65
+ maxAgeFrom: "last-used",
66
+ }),
67
+ ],
68
+ }),
69
+ },
70
+ {
71
+ matcher: /\/_next\/static.+\.js$/i,
72
+ handler: new CacheFirst({
73
+ cacheName: "next-static-js-assets",
74
+ plugins: [
75
+ new ExpirationPlugin({
76
+ maxEntries: 64,
77
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
78
+ maxAgeFrom: "last-used",
79
+ }),
80
+ ],
81
+ }),
82
+ },
83
+ {
84
+ matcher: /\/_next\/image\?url=.+$/i,
85
+ handler: new StaleWhileRevalidate({
86
+ cacheName: "next-image",
87
+ plugins: [
88
+ new ExpirationPlugin({
89
+ maxEntries: 64,
90
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
91
+ maxAgeFrom: "last-used",
92
+ }),
93
+ ],
94
+ }),
95
+ },
96
+ {
97
+ matcher: /\.(?:mp3|wav|ogg)$/i,
98
+ handler: new CacheFirst({
99
+ cacheName: "static-audio-assets",
100
+ plugins: [
101
+ new ExpirationPlugin({
102
+ maxEntries: 32,
103
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
104
+ maxAgeFrom: "last-used",
105
+ }),
106
+ new RangeRequestsPlugin(),
107
+ ],
108
+ }),
109
+ },
110
+ {
111
+ matcher: /\.(?:mp4|webm)$/i,
112
+ handler: new CacheFirst({
113
+ cacheName: "static-video-assets",
114
+ plugins: [
115
+ new ExpirationPlugin({
116
+ maxEntries: 32,
117
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
118
+ maxAgeFrom: "last-used",
119
+ }),
120
+ new RangeRequestsPlugin(),
121
+ ],
122
+ }),
123
+ },
124
+ {
125
+ matcher: /\.(?:js)$/i,
126
+ handler: new StaleWhileRevalidate({
127
+ cacheName: "static-js-assets",
128
+ plugins: [
129
+ new ExpirationPlugin({
130
+ maxEntries: 48,
131
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
132
+ maxAgeFrom: "last-used",
133
+ }),
134
+ ],
135
+ }),
136
+ },
137
+ {
138
+ matcher: /\.(?:css|less)$/i,
139
+ handler: new StaleWhileRevalidate({
140
+ cacheName: "static-style-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: /\/_next\/data\/.+\/.+\.json$/i,
152
+ handler: new NetworkFirst({
153
+ cacheName: "next-data",
154
+ plugins: [
155
+ new ExpirationPlugin({
156
+ maxEntries: 32,
157
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
158
+ maxAgeFrom: "last-used",
159
+ }),
160
+ ],
161
+ }),
162
+ },
163
+ {
164
+ matcher: /\.(?:json|xml|csv)$/i,
165
+ handler: new NetworkFirst({
166
+ cacheName: "static-data-assets",
167
+ plugins: [
168
+ new ExpirationPlugin({
169
+ maxEntries: 32,
170
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
171
+ maxAgeFrom: "last-used",
172
+ }),
173
+ ],
174
+ }),
175
+ },
176
+ {
177
+ matcher: ({ sameOrigin, url: { pathname } }) => {
178
+ // Exclude /api/auth/callback/* to fix OAuth workflow in Safari without having
179
+ // an impact on other environments
180
+ // The above route is the default for next-auth, you may need to change it if
181
+ // your OAuth workflow has a different callback route.
182
+ // Issue: https://github.com/shadowwalker/next-pwa/issues/131#issuecomment-821894809
183
+ // TODO(ducanhgh): Investigate Auth.js's "/api/auth/*" failing when we allow them
184
+ // to be cached (the current behaviour).
185
+ if (!sameOrigin || pathname.startsWith("/api/auth/callback")) {
186
+ return false;
187
+ }
180
188
 
181
- if (pathname.startsWith("/api/")) {
182
- return true;
183
- }
189
+ if (pathname.startsWith("/api/")) {
190
+ return true;
191
+ }
184
192
 
185
- return false;
186
- },
187
- method: "GET",
188
- handler: new NetworkFirst({
189
- cacheName: "apis",
190
- plugins: [
191
- new ExpirationPlugin({
192
- maxEntries: 16,
193
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
194
- maxAgeFrom: "last-used",
195
- }),
196
- ],
197
- networkTimeoutSeconds: 10, // fallback to cache if API does not response within 10 seconds
198
- }),
199
- },
200
- {
201
- matcher: ({ request, url: { pathname }, sameOrigin }) =>
202
- request.headers.get("RSC") === "1" && request.headers.get("Next-Router-Prefetch") === "1" && sameOrigin && !pathname.startsWith("/api/"),
203
- handler: new NetworkFirst({
204
- cacheName: PAGES_CACHE_NAME.rscPrefetch,
205
- plugins: [
206
- new ExpirationPlugin({
207
- maxEntries: 32,
208
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
209
- }),
210
- ],
211
- }),
212
- },
213
- {
214
- matcher: ({ request, url: { pathname }, sameOrigin }) => request.headers.get("RSC") === "1" && sameOrigin && !pathname.startsWith("/api/"),
215
- handler: new NetworkFirst({
216
- cacheName: PAGES_CACHE_NAME.rsc,
217
- plugins: [
218
- new ExpirationPlugin({
219
- maxEntries: 32,
220
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
221
- }),
222
- ],
223
- }),
224
- },
225
- {
226
- matcher: ({ request, url: { pathname }, sameOrigin }) =>
227
- request.headers.get("Content-Type")?.includes("text/html") && sameOrigin && !pathname.startsWith("/api/"),
228
- handler: new NetworkFirst({
229
- cacheName: PAGES_CACHE_NAME.html,
230
- plugins: [
231
- new ExpirationPlugin({
232
- maxEntries: 32,
233
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
234
- }),
235
- ],
236
- }),
237
- },
238
- {
239
- matcher: ({ url: { pathname }, sameOrigin }) => sameOrigin && !pathname.startsWith("/api/"),
240
- handler: new NetworkFirst({
241
- cacheName: "others",
242
- plugins: [
243
- new ExpirationPlugin({
244
- maxEntries: 32,
245
- maxAgeSeconds: 24 * 60 * 60, // 24 hours
246
- }),
247
- ],
248
- }),
249
- },
250
- {
251
- matcher: ({ sameOrigin }) => !sameOrigin,
252
- handler: new NetworkFirst({
253
- cacheName: "cross-origin",
254
- plugins: [
255
- new ExpirationPlugin({
256
- maxEntries: 32,
257
- maxAgeSeconds: 60 * 60, // 1 hour
258
- }),
259
- ],
260
- networkTimeoutSeconds: 10,
261
- }),
262
- },
263
- ];
193
+ return false;
194
+ },
195
+ method: "GET",
196
+ handler: new NetworkFirst({
197
+ cacheName: "apis",
198
+ plugins: [
199
+ new ExpirationPlugin({
200
+ maxEntries: 16,
201
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
202
+ maxAgeFrom: "last-used",
203
+ }),
204
+ ],
205
+ networkTimeoutSeconds: 10, // fallback to cache if API does not response within 10 seconds
206
+ }),
207
+ },
208
+ {
209
+ matcher: ({ request, url: { pathname }, sameOrigin }) =>
210
+ request.headers.get("RSC") === "1" && request.headers.get("Next-Router-Prefetch") === "1" && sameOrigin && !pathname.startsWith("/api/"),
211
+ handler: new NetworkFirst({
212
+ cacheName: PAGES_CACHE_NAME.rscPrefetch,
213
+ plugins: [
214
+ new ExpirationPlugin({
215
+ maxEntries: 32,
216
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
217
+ }),
218
+ ],
219
+ }),
220
+ },
221
+ {
222
+ matcher: ({ request, url: { pathname }, sameOrigin }) => request.headers.get("RSC") === "1" && sameOrigin && !pathname.startsWith("/api/"),
223
+ handler: new NetworkFirst({
224
+ cacheName: PAGES_CACHE_NAME.rsc,
225
+ plugins: [
226
+ new ExpirationPlugin({
227
+ maxEntries: 32,
228
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
229
+ }),
230
+ ],
231
+ }),
232
+ },
233
+ {
234
+ matcher: ({ request, url: { pathname }, sameOrigin }) =>
235
+ request.headers.get("Content-Type")?.includes("text/html") && sameOrigin && !pathname.startsWith("/api/"),
236
+ handler: new NetworkFirst({
237
+ cacheName: PAGES_CACHE_NAME.html,
238
+ plugins: [
239
+ new ExpirationPlugin({
240
+ maxEntries: 32,
241
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
242
+ }),
243
+ ],
244
+ }),
245
+ },
246
+ {
247
+ matcher: ({ url: { pathname }, sameOrigin }) => sameOrigin && !pathname.startsWith("/api/"),
248
+ handler: new NetworkFirst({
249
+ cacheName: "others",
250
+ plugins: [
251
+ new ExpirationPlugin({
252
+ maxEntries: 32,
253
+ maxAgeSeconds: 24 * 60 * 60, // 24 hours
254
+ }),
255
+ ],
256
+ }),
257
+ },
258
+ {
259
+ matcher: ({ sameOrigin }) => !sameOrigin,
260
+ handler: new NetworkFirst({
261
+ cacheName: "cross-origin",
262
+ plugins: [
263
+ new ExpirationPlugin({
264
+ maxEntries: 32,
265
+ maxAgeSeconds: 60 * 60, // 1 hour
266
+ }),
267
+ ],
268
+ networkTimeoutSeconds: 10,
269
+ }),
270
+ },
271
+ ];