@serwist/turbopack 10.0.0-preview.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +182 -0
- package/dist/index.react.d.ts +16 -0
- package/dist/index.react.d.ts.map +1 -0
- package/dist/index.react.js +48 -0
- package/dist/index.schema.d.ts +144 -0
- package/dist/index.schema.d.ts.map +1 -0
- package/dist/index.schema.js +26 -0
- package/dist/index.worker.d.ts +14 -0
- package/dist/index.worker.d.ts.map +1 -0
- package/dist/index.worker.js +258 -0
- package/dist/lib/constants.d.ts +2 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/context.d.ts +7 -0
- package/dist/lib/context.d.ts.map +1 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/logger.d.ts +6 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +103 -0
- package/src/index.react.tsx +44 -0
- package/src/index.schema.ts +22 -0
- package/src/index.ts +126 -0
- package/src/index.worker.ts +278 -0
- package/src/lib/constants.ts +4 -0
- package/src/lib/context.ts +16 -0
- package/src/lib/index.ts +3 -0
- package/src/lib/logger.ts +57 -0
- package/src/types.ts +37 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import type { RuntimeCaching } from "serwist";
|
|
2
|
+
import { CacheFirst, ExpirationPlugin, NetworkFirst, NetworkOnly, RangeRequestsPlugin, StaleWhileRevalidate } from "serwist";
|
|
3
|
+
|
|
4
|
+
export const PAGES_CACHE_NAME = {
|
|
5
|
+
rscPrefetch: "pages-rsc-prefetch",
|
|
6
|
+
rsc: "pages-rsc",
|
|
7
|
+
html: "pages",
|
|
8
|
+
} as const;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The default, recommended list of caching strategies for applications
|
|
12
|
+
* built with Next.js.
|
|
13
|
+
*
|
|
14
|
+
* @see https://serwist.pages.dev/docs/next/worker-exports#default-cache
|
|
15
|
+
*/
|
|
16
|
+
export const defaultCache: RuntimeCaching[] =
|
|
17
|
+
process.env.NODE_ENV !== "production"
|
|
18
|
+
? [
|
|
19
|
+
{
|
|
20
|
+
matcher: /.*/i,
|
|
21
|
+
handler: new NetworkOnly(),
|
|
22
|
+
},
|
|
23
|
+
]
|
|
24
|
+
: [
|
|
25
|
+
{
|
|
26
|
+
matcher: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,
|
|
27
|
+
handler: new CacheFirst({
|
|
28
|
+
cacheName: "google-fonts-webfonts",
|
|
29
|
+
plugins: [
|
|
30
|
+
new ExpirationPlugin({
|
|
31
|
+
maxEntries: 4,
|
|
32
|
+
maxAgeSeconds: 365 * 24 * 60 * 60, // 365 days
|
|
33
|
+
maxAgeFrom: "last-used",
|
|
34
|
+
}),
|
|
35
|
+
],
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
matcher: /^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,
|
|
40
|
+
handler: new StaleWhileRevalidate({
|
|
41
|
+
cacheName: "google-fonts-stylesheets",
|
|
42
|
+
plugins: [
|
|
43
|
+
new ExpirationPlugin({
|
|
44
|
+
maxEntries: 4,
|
|
45
|
+
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
|
|
46
|
+
maxAgeFrom: "last-used",
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
}),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
matcher: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
|
|
53
|
+
handler: new StaleWhileRevalidate({
|
|
54
|
+
cacheName: "static-font-assets",
|
|
55
|
+
plugins: [
|
|
56
|
+
new ExpirationPlugin({
|
|
57
|
+
maxEntries: 4,
|
|
58
|
+
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
|
|
59
|
+
maxAgeFrom: "last-used",
|
|
60
|
+
}),
|
|
61
|
+
],
|
|
62
|
+
}),
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
matcher: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
|
|
66
|
+
handler: new StaleWhileRevalidate({
|
|
67
|
+
cacheName: "static-image-assets",
|
|
68
|
+
plugins: [
|
|
69
|
+
new ExpirationPlugin({
|
|
70
|
+
maxEntries: 64,
|
|
71
|
+
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
|
|
72
|
+
maxAgeFrom: "last-used",
|
|
73
|
+
}),
|
|
74
|
+
],
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
matcher: /\/_next\/static.+\.js$/i,
|
|
79
|
+
handler: new CacheFirst({
|
|
80
|
+
cacheName: "next-static-js-assets",
|
|
81
|
+
plugins: [
|
|
82
|
+
new ExpirationPlugin({
|
|
83
|
+
maxEntries: 64,
|
|
84
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
85
|
+
maxAgeFrom: "last-used",
|
|
86
|
+
}),
|
|
87
|
+
],
|
|
88
|
+
}),
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
matcher: /\/_next\/image\?url=.+$/i,
|
|
92
|
+
handler: new StaleWhileRevalidate({
|
|
93
|
+
cacheName: "next-image",
|
|
94
|
+
plugins: [
|
|
95
|
+
new ExpirationPlugin({
|
|
96
|
+
maxEntries: 64,
|
|
97
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
98
|
+
maxAgeFrom: "last-used",
|
|
99
|
+
}),
|
|
100
|
+
],
|
|
101
|
+
}),
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
matcher: /\.(?:mp3|wav|ogg)$/i,
|
|
105
|
+
handler: new CacheFirst({
|
|
106
|
+
cacheName: "static-audio-assets",
|
|
107
|
+
plugins: [
|
|
108
|
+
new ExpirationPlugin({
|
|
109
|
+
maxEntries: 32,
|
|
110
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
111
|
+
maxAgeFrom: "last-used",
|
|
112
|
+
}),
|
|
113
|
+
new RangeRequestsPlugin(),
|
|
114
|
+
],
|
|
115
|
+
}),
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
matcher: /\.(?:mp4|webm)$/i,
|
|
119
|
+
handler: new CacheFirst({
|
|
120
|
+
cacheName: "static-video-assets",
|
|
121
|
+
plugins: [
|
|
122
|
+
new ExpirationPlugin({
|
|
123
|
+
maxEntries: 32,
|
|
124
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
125
|
+
maxAgeFrom: "last-used",
|
|
126
|
+
}),
|
|
127
|
+
new RangeRequestsPlugin(),
|
|
128
|
+
],
|
|
129
|
+
}),
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
matcher: /\.(?:js)$/i,
|
|
133
|
+
handler: new StaleWhileRevalidate({
|
|
134
|
+
cacheName: "static-js-assets",
|
|
135
|
+
plugins: [
|
|
136
|
+
new ExpirationPlugin({
|
|
137
|
+
maxEntries: 48,
|
|
138
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
139
|
+
maxAgeFrom: "last-used",
|
|
140
|
+
}),
|
|
141
|
+
],
|
|
142
|
+
}),
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
matcher: /\.(?:css|less)$/i,
|
|
146
|
+
handler: new StaleWhileRevalidate({
|
|
147
|
+
cacheName: "static-style-assets",
|
|
148
|
+
plugins: [
|
|
149
|
+
new ExpirationPlugin({
|
|
150
|
+
maxEntries: 32,
|
|
151
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
152
|
+
maxAgeFrom: "last-used",
|
|
153
|
+
}),
|
|
154
|
+
],
|
|
155
|
+
}),
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
matcher: /\/_next\/data\/.+\/.+\.json$/i,
|
|
159
|
+
handler: new NetworkFirst({
|
|
160
|
+
cacheName: "next-data",
|
|
161
|
+
plugins: [
|
|
162
|
+
new ExpirationPlugin({
|
|
163
|
+
maxEntries: 32,
|
|
164
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
165
|
+
maxAgeFrom: "last-used",
|
|
166
|
+
}),
|
|
167
|
+
],
|
|
168
|
+
}),
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
matcher: /\.(?:json|xml|csv)$/i,
|
|
172
|
+
handler: new NetworkFirst({
|
|
173
|
+
cacheName: "static-data-assets",
|
|
174
|
+
plugins: [
|
|
175
|
+
new ExpirationPlugin({
|
|
176
|
+
maxEntries: 32,
|
|
177
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
178
|
+
maxAgeFrom: "last-used",
|
|
179
|
+
}),
|
|
180
|
+
],
|
|
181
|
+
}),
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
matcher: ({ sameOrigin, url: { pathname } }) => {
|
|
185
|
+
// Exclude /api/auth/callback/* to fix OAuth workflow in Safari without having
|
|
186
|
+
// an impact on other environments
|
|
187
|
+
// The above route is the default for next-auth, you may need to change it if
|
|
188
|
+
// your OAuth workflow has a different callback route.
|
|
189
|
+
// Issue: https://github.com/shadowwalker/next-pwa/issues/131#issuecomment-821894809
|
|
190
|
+
// TODO(ducanhgh): Investigate Auth.js's "/api/auth/*" failing when we allow them
|
|
191
|
+
// to be cached (the current behaviour).
|
|
192
|
+
if (!sameOrigin || pathname.startsWith("/api/auth/callback")) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (pathname.startsWith("/api/")) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return false;
|
|
201
|
+
},
|
|
202
|
+
method: "GET",
|
|
203
|
+
handler: new NetworkFirst({
|
|
204
|
+
cacheName: "apis",
|
|
205
|
+
plugins: [
|
|
206
|
+
new ExpirationPlugin({
|
|
207
|
+
maxEntries: 16,
|
|
208
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
209
|
+
maxAgeFrom: "last-used",
|
|
210
|
+
}),
|
|
211
|
+
],
|
|
212
|
+
networkTimeoutSeconds: 10, // fallback to cache if API does not response within 10 seconds
|
|
213
|
+
}),
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
matcher: ({ request, url: { pathname }, sameOrigin }) =>
|
|
217
|
+
request.headers.get("RSC") === "1" && request.headers.get("Next-Router-Prefetch") === "1" && sameOrigin && !pathname.startsWith("/api/"),
|
|
218
|
+
handler: new NetworkFirst({
|
|
219
|
+
cacheName: PAGES_CACHE_NAME.rscPrefetch,
|
|
220
|
+
plugins: [
|
|
221
|
+
new ExpirationPlugin({
|
|
222
|
+
maxEntries: 32,
|
|
223
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
224
|
+
}),
|
|
225
|
+
],
|
|
226
|
+
}),
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
matcher: ({ request, url: { pathname }, sameOrigin }) => request.headers.get("RSC") === "1" && sameOrigin && !pathname.startsWith("/api/"),
|
|
230
|
+
handler: new NetworkFirst({
|
|
231
|
+
cacheName: PAGES_CACHE_NAME.rsc,
|
|
232
|
+
plugins: [
|
|
233
|
+
new ExpirationPlugin({
|
|
234
|
+
maxEntries: 32,
|
|
235
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
236
|
+
}),
|
|
237
|
+
],
|
|
238
|
+
}),
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
matcher: ({ request, url: { pathname }, sameOrigin }) =>
|
|
242
|
+
request.headers.get("Content-Type")?.includes("text/html") && sameOrigin && !pathname.startsWith("/api/"),
|
|
243
|
+
handler: new NetworkFirst({
|
|
244
|
+
cacheName: PAGES_CACHE_NAME.html,
|
|
245
|
+
plugins: [
|
|
246
|
+
new ExpirationPlugin({
|
|
247
|
+
maxEntries: 32,
|
|
248
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
249
|
+
}),
|
|
250
|
+
],
|
|
251
|
+
}),
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
matcher: ({ url: { pathname }, sameOrigin }) => sameOrigin && !pathname.startsWith("/api/"),
|
|
255
|
+
handler: new NetworkFirst({
|
|
256
|
+
cacheName: "others",
|
|
257
|
+
plugins: [
|
|
258
|
+
new ExpirationPlugin({
|
|
259
|
+
maxEntries: 32,
|
|
260
|
+
maxAgeSeconds: 24 * 60 * 60, // 24 hours
|
|
261
|
+
}),
|
|
262
|
+
],
|
|
263
|
+
}),
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
matcher: ({ sameOrigin }) => !sameOrigin,
|
|
267
|
+
handler: new NetworkFirst({
|
|
268
|
+
cacheName: "cross-origin",
|
|
269
|
+
plugins: [
|
|
270
|
+
new ExpirationPlugin({
|
|
271
|
+
maxEntries: 32,
|
|
272
|
+
maxAgeSeconds: 60 * 60, // 1 hour
|
|
273
|
+
}),
|
|
274
|
+
],
|
|
275
|
+
networkTimeoutSeconds: 10,
|
|
276
|
+
}),
|
|
277
|
+
},
|
|
278
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Serwist } from "@serwist/window";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
|
|
4
|
+
export interface SerwistContextValues {
|
|
5
|
+
serwist: Serwist | null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const SerwistContext = createContext<SerwistContextValues>(null!);
|
|
9
|
+
|
|
10
|
+
export const useSerwist = () => {
|
|
11
|
+
const context = useContext(SerwistContext);
|
|
12
|
+
if (!context) {
|
|
13
|
+
throw new Error("[useSerwist]: 'SerwistContext' is not available.");
|
|
14
|
+
}
|
|
15
|
+
return context;
|
|
16
|
+
};
|
package/src/lib/index.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { bold, green, red, white, yellow } from "kolorist";
|
|
2
|
+
|
|
3
|
+
const LOGGING_METHOD = ["wait", "error", "warn", "info", "event"] as const;
|
|
4
|
+
|
|
5
|
+
type LoggingMethods = (typeof LOGGING_METHOD)[number];
|
|
6
|
+
|
|
7
|
+
const mapLoggingMethodToConsole: Record<LoggingMethods, "log" | "error" | "warn" | "log"> = {
|
|
8
|
+
wait: "log",
|
|
9
|
+
error: "error",
|
|
10
|
+
warn: "warn",
|
|
11
|
+
info: "log",
|
|
12
|
+
event: "log",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const prefixes = {
|
|
16
|
+
wait: `${white(bold("○"))} (serwist)`,
|
|
17
|
+
error: `${red(bold("X"))} (serwist)`,
|
|
18
|
+
warn: `${yellow(bold("⚠"))} (serwist)`,
|
|
19
|
+
info: `${white(bold("○"))} (serwist)`,
|
|
20
|
+
event: `${green(bold("✓"))} (serwist)`,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const prefixedLog = (prefixType: LoggingMethods, ...message: any[]) => {
|
|
24
|
+
const consoleMethod = mapLoggingMethodToConsole[prefixType];
|
|
25
|
+
const prefix = prefixes[prefixType];
|
|
26
|
+
|
|
27
|
+
if ((message[0] === "" || message[0] === undefined) && message.length === 1) {
|
|
28
|
+
message.shift();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// If there's no message, don't print the prefix but a new line
|
|
32
|
+
if (message.length === 0) {
|
|
33
|
+
console[consoleMethod]("");
|
|
34
|
+
} else {
|
|
35
|
+
console[consoleMethod](` ${prefix}`, ...message);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const wait = (...message: any[]) => {
|
|
40
|
+
prefixedLog("wait", ...message);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const error = (...message: any[]) => {
|
|
44
|
+
prefixedLog("error", ...message);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const warn = (...message: any[]) => {
|
|
48
|
+
prefixedLog("warn", ...message);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const info = (...message: any[]) => {
|
|
52
|
+
prefixedLog("info", ...message);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const event = (...message: any[]) => {
|
|
56
|
+
prefixedLog("event", ...message);
|
|
57
|
+
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BasePartial,
|
|
3
|
+
BaseResolved,
|
|
4
|
+
GlobPartial,
|
|
5
|
+
GlobResolved,
|
|
6
|
+
InjectPartial,
|
|
7
|
+
InjectResolved,
|
|
8
|
+
OptionalGlobDirectoryPartial,
|
|
9
|
+
RequiredGlobDirectoryResolved,
|
|
10
|
+
} from "@serwist/build";
|
|
11
|
+
import { assertType, type Equals } from "@serwist/build/schema";
|
|
12
|
+
import type { Prettify } from "@serwist/utils";
|
|
13
|
+
import type z from "zod";
|
|
14
|
+
import type { injectManifestOptions } from "./index.schema.js";
|
|
15
|
+
|
|
16
|
+
export interface TurboPartial {
|
|
17
|
+
/**
|
|
18
|
+
* The path to your working directory.
|
|
19
|
+
*
|
|
20
|
+
* @default process.cwd()
|
|
21
|
+
*/
|
|
22
|
+
cwd?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The Next.js `basePath` config option. If this option
|
|
25
|
+
* is not configured, set to `/`.
|
|
26
|
+
*/
|
|
27
|
+
basePath: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type TurboResolved = Required<TurboPartial>;
|
|
31
|
+
|
|
32
|
+
export type InjectManifestOptions = Prettify<BasePartial & GlobPartial & InjectPartial & OptionalGlobDirectoryPartial & TurboPartial>;
|
|
33
|
+
|
|
34
|
+
export type InjectManifestOptionsComplete = Prettify<BaseResolved & GlobResolved & InjectResolved & RequiredGlobDirectoryResolved & TurboResolved>;
|
|
35
|
+
|
|
36
|
+
assertType<Equals<InjectManifestOptions, z.input<typeof injectManifestOptions>>>();
|
|
37
|
+
assertType<Equals<InjectManifestOptionsComplete, z.output<typeof injectManifestOptions>>>();
|