@thomas.f/prnext 0.1.17-alpha → 0.1.18-alpha
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/README.md +26 -869
- package/build/actions.mjs +1 -1
- package/build/analyze.mjs +180 -24
- package/build/app-config.mjs +13 -0
- package/build/app-static.mjs +34 -12
- package/build/app-styles.mjs +79 -0
- package/build/app.mjs +81 -26
- package/build/bundle-runtime.mjs +22 -9
- package/build/cache-components.mjs +1 -1
- package/build/cache-handlers.mjs +1 -1
- package/build/compact-css.mjs +53 -0
- package/build/compilation-cache.mjs +269 -0
- package/build/compilation-store.mjs +142 -0
- package/build/compiler.mjs +31 -8
- package/build/config.mjs +30 -1
- package/build/create.mjs +239 -0
- package/build/css-modules.mjs +56 -12
- package/build/deployment-assets.mjs +89 -0
- package/build/deployment-config.mjs +18 -0
- package/build/dev-css-update.mjs +4 -2
- package/build/dev-dependencies.mjs +1 -1
- package/build/dev-discovery.mjs +3 -3
- package/build/dev.mjs +15 -8
- package/build/dynamic.mjs +1 -1
- package/build/edge.mjs +3 -3
- package/build/fonts.mjs +1 -1
- package/build/framework-imports.mjs +15 -5
- package/build/html-only-config.mjs +53 -0
- package/build/html-only-graph.mjs +67 -0
- package/build/index.mjs +59 -26
- package/build/instrumentation.mjs +30 -0
- package/build/metadata-routes.mjs +1 -1
- package/build/migration-audit.mjs +1 -1
- package/build/native-type-config.mjs +37 -0
- package/build/persistent-cache.mjs +18 -3
- package/build/precompress.mjs +1 -1
- package/build/prerender-cache.mjs +70 -0
- package/build/prerender-config.mjs +29 -0
- package/build/prerender-pages.mjs +19 -9
- package/build/prerender-pool.mjs +165 -0
- package/build/prerender-process-worker.mjs +58 -0
- package/build/prerender-worker.mjs +5 -5
- package/build/production-builder.mjs +58 -9
- package/build/react-compiler-report.mjs +225 -0
- package/build/react-compiler.mjs +139 -0
- package/build/runtime-contract.mjs +2 -2
- package/build/static-export.mjs +4 -4
- package/build/styles.mjs +6 -4
- package/build/transform.mjs +1 -1
- package/build/typed-routes.mjs +4 -0
- package/build/typescript-dev.mjs +35 -8
- package/build/typescript-native-worker.mjs +55 -0
- package/build/typescript-native.mjs +18 -0
- package/build/typescript-toolchain.mjs +19 -0
- package/build/typescript.mjs +6 -4
- package/build/webpack-graph.mjs +6 -3
- package/build/worker-memory.mjs +9 -0
- package/cli.mjs +60 -4
- package/compat/activity-cache.cjs +26 -0
- package/compat/after.cjs +6 -4
- package/compat/app-layout-context.cjs +52 -2
- package/compat/base64.cjs +10 -0
- package/compat/cache-handlers.cjs +12 -2
- package/compat/cache-wire.cjs +28 -0
- package/compat/cache.cjs +2 -1
- package/compat/cache.d.cts +4 -0
- package/compat/cookies.cjs +21 -5
- package/compat/data-cache.cjs +12 -8
- package/compat/flight-delta.cjs +150 -0
- package/compat/headers.cjs +4 -2
- package/compat/incremental-cache.cjs +20 -7
- package/compat/index.d.ts +68 -3
- package/compat/link.cjs +12 -9
- package/compat/navigation-authorization.cjs +9 -0
- package/compat/navigation-stages.cjs +19 -0
- package/compat/offline-store.cjs +11 -0
- package/compat/offline.cjs +5 -0
- package/compat/offline.d.cts +2 -0
- package/compat/redis-cache.cjs +201 -0
- package/compat/redis-cache.d.cts +37 -0
- package/compat/server-primitives.cjs +31 -11
- package/compat/server.d.cts +15 -2
- package/compat/static-generation.cjs +7 -0
- package/compat/use-cache.cjs +3 -0
- package/docs/ai/compatibility.md +171 -2
- package/docs/ai/data.md +165 -5
- package/docs/ai/deployment.md +158 -0
- package/docs/ai/quickstart.md +29 -4
- package/docs/ai/routing.md +82 -0
- package/docs/ai/troubleshooting.md +37 -2
- package/package.json +26 -7
- package/runtime/action-client.mjs +10 -4
- package/runtime/action-server.mjs +2 -0
- package/runtime/app-client.mjs +212 -65
- package/runtime/app-content.mjs +4 -3
- package/runtime/app-partial-client.mjs +3 -0
- package/runtime/app-partial.mjs +1 -1
- package/runtime/app-prefetch-constants.mjs +4 -0
- package/runtime/app-prefetch.mjs +2 -3
- package/runtime/app-render-key.mjs +5 -0
- package/runtime/app-render.mjs +88 -28
- package/runtime/app-routing.mjs +22 -9
- package/runtime/app-static.mjs +18 -8
- package/runtime/app-stream-html.mjs +10 -53
- package/runtime/app-style-selection.mjs +34 -0
- package/runtime/app-styles.mjs +154 -0
- package/runtime/cache-components-rsc.mjs +4 -1
- package/runtime/cache-request.mjs +2 -1
- package/runtime/deployment-client.mjs +19 -0
- package/runtime/dev-client.mjs +7 -2
- package/runtime/dev-compiler-broker.mjs +42 -0
- package/runtime/dev-indicator.mjs +8 -3
- package/runtime/dev-lazy-tool.mjs +16 -0
- package/runtime/development.mjs +29 -12
- package/runtime/document.mjs +1 -1
- package/runtime/edge.mjs +6 -5
- package/runtime/fetch-cache.mjs +10 -8
- package/runtime/flight-delta.mjs +50 -0
- package/runtime/flight-tap.mjs +28 -0
- package/runtime/html-only.mjs +27 -0
- package/runtime/http.mjs +2 -0
- package/runtime/incremental-cache.mjs +25 -4
- package/runtime/instrumentation.mjs +49 -0
- package/runtime/navigation-recovery.mjs +36 -0
- package/runtime/navigation.mjs +7 -0
- package/runtime/node-html-stream.mjs +47 -0
- package/runtime/pages-client.mjs +14 -7
- package/runtime/pages-navigation.mjs +48 -63
- package/runtime/prefetch-scheduler.mjs +110 -0
- package/runtime/profile.mjs +14 -0
- package/runtime/profiles.json +2 -2
- package/runtime/render.mjs +3 -0
- package/runtime/route-pattern.mjs +44 -0
- package/runtime/rsc-worker.mjs +34 -12
- package/runtime/trace.mjs +78 -0
- package/runtime/watch-project.mjs +19 -15
- package/runtime/worker.mjs +70 -26
package/runtime/worker.mjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {drainTraces} from './trace.mjs';
|
|
2
|
+
import {advancedRoutingSources} from './app-routing-state.mjs';
|
|
3
|
+
import {initializeInstrumentation,withInstrumentation} from './instrumentation.mjs';
|
|
4
|
+
import {deferredCompiler} from './dev-compiler-broker.mjs';
|
|
1
5
|
// prnext-transport:socket-v2
|
|
2
6
|
// prnext-concurrency:512
|
|
3
7
|
import { requestFrames } from './request-transport.mjs';
|
|
@@ -38,6 +42,10 @@ loadEnvConfig(projectRoot, { dev: !!manifest.dev });
|
|
|
38
42
|
// browser graph and the RSC worker's mode, including dev launched from CI.
|
|
39
43
|
process.env.NODE_ENV = manifest.dev ? 'development' : 'production';
|
|
40
44
|
const production = !manifest.dev;
|
|
45
|
+
const compilerDescriptor=process.env.PRNEXT_DEV_COMPILER;
|
|
46
|
+
delete process.env.PRNEXT_DEV_COMPILER;
|
|
47
|
+
process.env.NEXT_RUNTIME='nodejs';
|
|
48
|
+
await initializeInstrumentation(distDir,manifest);
|
|
41
49
|
let dispatchRequest=handleRequest;
|
|
42
50
|
if(!production){
|
|
43
51
|
const {createDevWorkerConsole}=await import('./dev-worker-logs.mjs'),logs=createDevWorkerConsole();globalThis.console=logs.console;
|
|
@@ -48,9 +56,9 @@ if(!production){
|
|
|
48
56
|
if (production) freezeClientModules(manifest.app?.clientModules);
|
|
49
57
|
// Load each renderer beside the application only when that request needs it.
|
|
50
58
|
// Middleware and API workers do not pay for React or the Pages/App renderers.
|
|
51
|
-
const runtimeModule = async name => {
|
|
59
|
+
const runtimeModule = async (name,directory=distDir) => {
|
|
52
60
|
const started = diagnostics.enabled ? performance.now() : 0;
|
|
53
|
-
const module = await import(pathToFileURL(path.join(
|
|
61
|
+
const module = await import(pathToFileURL(path.join(directory, `runtime/${name}.mjs`)).href);
|
|
54
62
|
scheduleCompileCacheFlush();
|
|
55
63
|
if (diagnostics.enabled) diagnostics.record('wake', { phase: 'module', module: name, durationMs: performance.now() - started });
|
|
56
64
|
return module;
|
|
@@ -60,31 +68,61 @@ try { ({ errorResponse } = await runtimeModule('http')); }
|
|
|
60
68
|
catch (error) { console.error('PRNext worker could not load the project runtime:', error.message); process.exit(1); }
|
|
61
69
|
const routes = new Map(manifest.routes.map(route => [route.id, route]));
|
|
62
70
|
const prerendered = new Set((manifest.prerendered || []).map(item => item.path));
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
let
|
|
71
|
+
const deployment={distDir,manifest,routes,prerendered,modules:new Map()};
|
|
72
|
+
const deployments=new Map([[distDir,deployment]]);
|
|
73
|
+
const compileDeferred=!production&&compilerDescriptor?deferredCompiler(compilerDescriptor,{root:projectRoot,home:path.dirname(distDir)}):undefined;
|
|
74
|
+
async function deferredDeployment(route,signal,sources=[]){
|
|
75
|
+
if(!compileDeferred)throw Error('Deferred development compiler is unavailable');
|
|
76
|
+
const next=await compileDeferred(route.pattern,signal,sources);
|
|
77
|
+
let value=deployments.get(next.distDir);
|
|
78
|
+
if(!value){value={...next,routes:new Map(next.manifest.routes.map(route=>[route.id,route])),prerendered:new Set(),modules:new Map()};deployments.set(next.distDir,value);while(deployments.size>4)deployments.delete(deployments.keys().next().value);}
|
|
79
|
+
const resolved=value.routes.get(route.id);
|
|
80
|
+
if(!resolved||resolved.devDeferred)throw Error('Compiler did not materialize the selected route');
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function drainRuntime(){
|
|
85
|
+
for(const value of deployments.values())if(value.modules.has('app-render')||value.modules.has('app-static')){
|
|
86
|
+
const runtime=await(value.modules.get('app-render')||import(pathToFileURL(path.join(value.distDir,'runtime/app-render.mjs')).href));
|
|
87
|
+
await runtime.drainAppRuntime();
|
|
88
|
+
}
|
|
89
|
+
await drainTraces();
|
|
90
|
+
}
|
|
70
91
|
|
|
71
|
-
async function handleRequest(input, output, signalController, responseComplete) {
|
|
92
|
+
async function handleRequest(input, output, signalController, responseComplete, selected=deployment) {
|
|
93
|
+
const {manifest,distDir,routes,prerendered}=selected;
|
|
94
|
+
const renderer=async name=>{
|
|
95
|
+
if(selected.modules.has(name))return selected.modules.get(name);
|
|
96
|
+
// Imports share one pending job, then retain only the namespace. Starting
|
|
97
|
+
// outside the visitor's ALS scope prevents the module cache retaining it.
|
|
98
|
+
const pending=workScope.runInAsyncScope(()=>runtimeModule(name,distDir));
|
|
99
|
+
selected.modules.set(name,pending);
|
|
100
|
+
try{const module=await pending;selected.modules.set(name,module);return module;}
|
|
101
|
+
catch(error){if(selected.modules.get(name)===pending)selected.modules.delete(name);throw error;}
|
|
102
|
+
};
|
|
72
103
|
let responseStarted = false;
|
|
73
104
|
const finalizers = new Set();
|
|
74
105
|
try {
|
|
75
|
-
if(input.routeId==='__prnext_preload'&&input.renderMode
|
|
76
|
-
const
|
|
106
|
+
if(input.routeId==='__prnext_preload'&&['preload','prewarm'].includes(input.renderMode)){
|
|
107
|
+
const frameworkOnly=input.renderMode==='prewarm';
|
|
108
|
+
const options=manifest.config?.workerPreload||(frameworkOnly?{routes:[],maxRssMb:256,timeoutMs:15000}:undefined);
|
|
77
109
|
if(!production||!options){await output(input.id,{status:204,body:''},input);return;}
|
|
110
|
+
if(frameworkOnly){
|
|
111
|
+
if(manifest.routes.some(route=>route.router==='app'&&route.kind==='page'))await(await renderer('app-render')).prewarmAppRenderer(options);
|
|
112
|
+
if(manifest.routes.some(route=>route.kind==='page'&&route.router!=='app'))await renderer('render');
|
|
113
|
+
if(manifest.routes.some(route=>route.kind==='api'))await renderer('api');
|
|
114
|
+
scheduleCompileCacheFlush();await output(input.id,{status:204,body:''},input);return;
|
|
115
|
+
}
|
|
78
116
|
const selected=options.routes.map(pattern=>manifest.routes.find(route=>route.pattern===pattern&&!route.internal)).filter(Boolean);
|
|
79
117
|
const deadline=performance.now()+options.timeoutMs;
|
|
80
118
|
for(const route of selected){
|
|
81
119
|
if(performance.now()>=deadline||process.memoryUsage().rss>=options.maxRssMb*1024*1024)break;
|
|
82
120
|
const remaining={...options,timeoutMs:Math.max(1,deadline-performance.now())};
|
|
83
121
|
if(route.router==='app'&&route.kind==='page'){
|
|
84
|
-
appRuntime
|
|
122
|
+
const appRuntime=await renderer('app-render');
|
|
85
123
|
await appRuntime.preloadAppRoutes([path.resolve(distDir,route.module)],remaining);
|
|
86
124
|
}else{
|
|
87
|
-
if(route.kind==='page')
|
|
125
|
+
if(route.kind==='page')await renderer('render');else await renderer('api');
|
|
88
126
|
await preloadModules([path.resolve(distDir,route.module)],remaining);
|
|
89
127
|
}
|
|
90
128
|
if(process.memoryUsage().rss>=options.maxRssMb*1024*1024)break;
|
|
@@ -92,7 +130,7 @@ async function handleRequest(input, output, signalController, responseComplete)
|
|
|
92
130
|
scheduleCompileCacheFlush();await output(input.id,{status:204,body:''},input);return;
|
|
93
131
|
}
|
|
94
132
|
if (input.renderMode === 'incremental-cache' && input.routeId === '__prnext_incremental_cache') {
|
|
95
|
-
incrementalRuntime
|
|
133
|
+
const incrementalRuntime = await renderer('incremental-cache');
|
|
96
134
|
const result = await incrementalRuntime.runIncrementalCache({ ...input, manifest, distDir, production, signal: signalController.signal });
|
|
97
135
|
input.body = undefined;
|
|
98
136
|
responseStarted = true;
|
|
@@ -104,31 +142,38 @@ async function handleRequest(input, output, signalController, responseComplete)
|
|
|
104
142
|
? { ...manifest.middleware, id: '__prnext_middleware', kind: 'middleware' }
|
|
105
143
|
: routes.get(input.routeId);
|
|
106
144
|
if (!route) { await output(input.id, { status: 404, body: 'Not Found' }, input); return; }
|
|
145
|
+
const sourceModules=!production&&route.router==='app'&&route.kind==='page'?advancedRoutingSources({...input,basePath:manifest.config?.basePath||''},manifest.routes):[];
|
|
146
|
+
const deferredSources=sourceModules.length?manifest.routes.filter(candidate=>candidate.devDeferred&&sourceModules.includes(candidate.module)).map(candidate=>candidate.pattern):[];
|
|
147
|
+
if(route.devDeferred||deferredSources.length){
|
|
148
|
+
const next=await deferredDeployment(route,signalController.signal,deferredSources);
|
|
149
|
+
return await handleRequest(input,output,signalController,responseComplete,next);
|
|
150
|
+
}
|
|
107
151
|
const requestedPath = new URL(input.url).pathname;
|
|
108
152
|
if (route.router !== 'app' && !['isr', 'error404', 'error500'].includes(input.renderMode) && route.fallback === false && !prerendered.has(requestedPath) && !prerendered.has(requestedPath.replace(/\/$/, '') || '/')) {
|
|
109
153
|
await output(input.id, { status: 404, body: 'Not Found' }, input); return;
|
|
110
154
|
}
|
|
111
155
|
const options = { ...input, modulePath: path.resolve(distDir, route.module), route, production, manifest, distDir, signal: signalController.signal, deferFinalizer: finalize => finalizers.add(finalize) };
|
|
156
|
+
return await withInstrumentation(options,async()=>{
|
|
112
157
|
let result;
|
|
113
158
|
if (isMiddleware) {
|
|
114
|
-
middlewareRuntime
|
|
159
|
+
const middlewareRuntime = await renderer('middleware');
|
|
115
160
|
result = await middlewareRuntime.runMiddleware(options);
|
|
116
161
|
} else if (route.router === 'app' && route.kind === 'page') {
|
|
117
162
|
if (input.renderMode === 'isr') {
|
|
118
|
-
appStaticRuntime
|
|
163
|
+
const appStaticRuntime = await renderer('app-static');
|
|
119
164
|
result = await appStaticRuntime.renderAppIsrPage(options);
|
|
120
165
|
} else {
|
|
121
|
-
appRuntime
|
|
166
|
+
const appRuntime = await renderer('app-render');
|
|
122
167
|
result = await appRuntime.renderAppPage(options);
|
|
123
168
|
}
|
|
124
169
|
} else if (route.router === 'app' && route.kind === 'api' && input.renderMode === 'isr') {
|
|
125
|
-
routeStaticRuntime
|
|
170
|
+
const routeStaticRuntime = await renderer('route-static');
|
|
126
171
|
result = await routeStaticRuntime.renderRouteHandlerIsr(options);
|
|
127
172
|
} else if (route.kind === 'api') {
|
|
128
|
-
apiRuntime
|
|
173
|
+
const apiRuntime = await renderer('api');
|
|
129
174
|
result = await apiRuntime.runApi(options);
|
|
130
175
|
} else {
|
|
131
|
-
pagesRuntime
|
|
176
|
+
const pagesRuntime = await renderer('render');
|
|
132
177
|
result = input.renderMode === 'isr' ? await pagesRuntime.renderIsrPage({ ...options, capturePageFailure: true })
|
|
133
178
|
: await pagesRuntime.renderPageRequest({ ...options, nativeErrors: true });
|
|
134
179
|
}
|
|
@@ -140,6 +185,7 @@ async function handleRequest(input, output, signalController, responseComplete)
|
|
|
140
185
|
if (result.finalizeCache) finalizers.add(result.finalizeCache);
|
|
141
186
|
await output(input.id, result, { ...input, production, signalController });
|
|
142
187
|
responseComplete?.();
|
|
188
|
+
});
|
|
143
189
|
} catch (error) {
|
|
144
190
|
const cancelled = signalController.signal.aborted || error instanceof ProtocolWriteError;
|
|
145
191
|
signalController.abort(error);
|
|
@@ -189,7 +235,8 @@ if (token && laneLimit > 1) {
|
|
|
189
235
|
reportedBusy = true;
|
|
190
236
|
writeProtocol('busy\n');
|
|
191
237
|
};
|
|
192
|
-
|
|
238
|
+
let exiting=false;
|
|
239
|
+
const exitWhenDrained = () => { if (shuttingDown && !invocations.size&&!exiting){exiting=true;void drainRuntime().catch(error=>console.error('[prnext] Runtime drain failed:',error?.message)).finally(()=>process.exit(0));} };
|
|
193
240
|
const server = net.createServer(socket => {
|
|
194
241
|
if (sockets.size >= laneLimit) { socket.destroy(); return; }
|
|
195
242
|
sockets.add(socket); socket.setNoDelay(true);
|
|
@@ -316,8 +363,5 @@ if (token && laneLimit > 1) {
|
|
|
316
363
|
// The maintenance/ISR transport is serial and awaits its own finalizers.
|
|
317
364
|
// RSC settlement can still outlive its terminal frame; drain it explicitly
|
|
318
365
|
// before closing the isolate's MessagePorts after parent EOF.
|
|
319
|
-
|
|
320
|
-
const runtime = appRuntime || await runtimeModule('app-render');
|
|
321
|
-
await runtime.drainAppRuntime();
|
|
322
|
-
}
|
|
366
|
+
await drainRuntime();
|
|
323
367
|
}
|