@thomas.f/prnext 0.1.19-alpha → 0.1.21-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/build/app.mjs +46 -78
- package/build/build-lock.mjs +2 -71
- package/build/build-retention.mjs +119 -0
- package/build/build-timings.mjs +38 -0
- package/build/bundle-runtime.mjs +17 -16
- package/build/cache-command.mjs +31 -0
- package/build/check.mjs +41 -3
- package/build/compilation-cache.mjs +32 -12
- package/build/compilation-storage.mjs +190 -0
- package/build/compiler.mjs +5 -4
- package/build/config.mjs +23 -2
- package/build/create.mjs +1 -1
- package/build/css-modules.mjs +4 -0
- package/build/dev-action-graph.mjs +21 -0
- package/build/flight-summary.mjs +64 -0
- package/build/font-cache.mjs +9 -6
- package/build/font-files.mjs +1 -1
- package/build/index.mjs +57 -36
- package/build/inspect.mjs +3 -0
- package/build/inspection-summary.mjs +7 -2
- package/build/native-discovery.mjs +18 -6
- package/build/native-ppr.mjs +32 -0
- package/build/npm-packages.mjs +2 -2
- package/build/og.mjs +121 -1
- package/build/parallel-plan.mjs +55 -0
- package/build/persistent-cache.mjs +29 -24
- package/build/production-check.mjs +34 -0
- package/build/react-compiler-report.mjs +31 -8
- package/build/react-compiler.mjs +101 -10
- package/build/server-config.mjs +35 -0
- package/build/source-analysis.mjs +108 -5
- package/build/standalone-copy.mjs +48 -0
- package/build/standalone.mjs +2 -22
- package/build/static-adapter.mjs +7 -3
- package/build/transform-cache.mjs +17 -3
- package/build/transform.mjs +38 -6
- package/build/typescript-dev.mjs +3 -1
- package/cli.mjs +27 -5
- package/compat/app-layout-context.cjs +7 -3
- package/compat/diagnostics.cjs +5 -4
- package/compat/flight-delta.cjs +47 -12
- package/compat/index.d.ts +24 -1
- package/compat/navigation-authorization.cjs +8 -1
- package/compat/runtime-sample.cjs +56 -0
- package/compat/use-cache.cjs +5 -2
- package/docs/ai/compatibility.md +113 -10
- package/docs/ai/deployment.md +144 -0
- package/docs/ai/quickstart.md +5 -0
- package/docs/ai/troubleshooting.md +22 -0
- package/package.json +25 -22
- package/release/fontkit.mjs +31 -0
- package/release/verify.mjs +3 -0
- package/runtime/api.mjs +5 -2
- package/runtime/app-client.mjs +246 -54
- package/runtime/app-partial.mjs +2 -10
- package/runtime/app-prefetch.mjs +2 -2
- package/runtime/app-render.mjs +42 -13
- package/runtime/app-stream-channel.mjs +20 -6
- package/runtime/app-stream-html.mjs +30 -11
- package/runtime/app-styles.mjs +22 -4
- package/runtime/cache-components-rsc.mjs +26 -6
- package/runtime/cache-result.mjs +58 -0
- package/runtime/compile-cache-retention.mjs +53 -0
- package/runtime/compile-cache.mjs +28 -1
- package/runtime/dev-client.mjs +32 -8
- package/runtime/dev-compiler-broker.mjs +20 -23
- package/runtime/dev-gateway.mjs +23 -6
- package/runtime/dev-route-selection.mjs +64 -0
- package/runtime/dev-runtime-pool.mjs +3 -2
- package/runtime/dev-runtime-spare.mjs +1 -1
- package/runtime/dev-session-retention.mjs +154 -0
- package/runtime/development-flight.mjs +59 -0
- package/runtime/development-queue.mjs +33 -0
- package/runtime/development.mjs +37 -16
- package/runtime/env.mjs +9 -0
- package/runtime/flight-delta.mjs +31 -5
- package/runtime/flight-diagnostics.mjs +48 -0
- package/runtime/flight-tap.mjs +10 -5
- package/runtime/html-envelope.mjs +34 -0
- package/runtime/loopback-rpc.mjs +92 -0
- package/runtime/native-ppr.mjs +88 -0
- package/runtime/og/NOTICE.txt +1 -1
- package/runtime/og/index.node.mjs +76 -31216
- package/runtime/og/upstream.json +115 -0
- package/runtime/persistent/client.mjs +5 -3
- package/runtime/persistent/common.mjs +7 -18
- package/runtime/persistent/daemon.mjs +4 -12
- package/runtime/persistent/health.mjs +58 -0
- package/runtime/persistent/native-proxy.mjs +1 -1
- package/runtime/persistent/watchdog.mjs +12 -27
- package/runtime/prewarm.mjs +35 -0
- package/runtime/project-lock.mjs +71 -0
- package/runtime/request-transport.mjs +112 -32
- package/runtime/rsc-worker.mjs +58 -8
- package/runtime/storage-path.mjs +36 -0
- package/runtime/trace.mjs +44 -4
- package/runtime/worker.mjs +37 -17
- package/vendor/fontkit/NOTICE.txt +5 -0
- package/vendor/fontkit/SOURCE-NOTICES.txt +209 -0
- package/vendor/fontkit/index.mjs +3 -0
- package/vendor/fontkit/licenses/@swc__helpers/LICENSE +201 -0
- package/vendor/fontkit/licenses/base64-js/LICENSE +21 -0
- package/vendor/fontkit/licenses/brotli/readme.md +61 -0
- package/vendor/fontkit/licenses/clone/LICENSE +18 -0
- package/vendor/fontkit/licenses/dfa/README.md +83 -0
- package/vendor/fontkit/licenses/fast-deep-equal/LICENSE +21 -0
- package/vendor/fontkit/licenses/fontkit/README.md +266 -0
- package/vendor/fontkit/licenses/restructure/LICENSE +21 -0
- package/vendor/fontkit/licenses/tiny-inflate/LICENSE +21 -0
- package/vendor/fontkit/licenses/tslib/LICENSE.txt +12 -0
- package/vendor/fontkit/licenses/unicode-properties/LICENSE +8 -0
- package/vendor/fontkit/licenses/unicode-trie/LICENSE +8 -0
- package/vendor/fontkit/upstream.json +215 -0
package/compat/flight-delta.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const WINDOW = 32, MAX_VALUE = 2 * 1024 * 1024, MAX_RESPONSE = 16 * 1024 * 1024;
|
|
4
4
|
const TYPE = 'application/x-prnext-flight-delta';
|
|
5
5
|
const MAGIC = new Uint8Array([80,82,68,49]);
|
|
6
|
-
const BLOCK_BYTES = 32 * 1024, MAX_COMMANDS_PER_CHUNK = 256, MAX_COMMANDS = 2048;
|
|
6
|
+
const BLOCK_BYTES = 32 * 1024, MAX_COMMANDS_PER_CHUNK = 256, MAX_COMMANDS = 2048, MAX_CAPTURE_PARTS = 2048;
|
|
7
7
|
let POWER = 1; for(let n=1;n<WINDOW;n++) POWER = Math.imul(POWER,31) >>> 0;
|
|
8
8
|
function hash(bytes,offset) { let result=0; for(let n=0;n<WINDOW;n++) result=(Math.imul(result,31)+bytes[offset+n])>>>0; return result; }
|
|
9
9
|
function createIndex(base) {
|
|
@@ -44,12 +44,47 @@ function blocks(parts) {
|
|
|
44
44
|
for(const part of parts)for(let offset=0;offset<part.length;){const n=Math.min(BLOCK_BYTES-size,part.length-offset);pending.push(part.subarray(offset,offset+n));size+=n;offset+=n;if(size===BLOCK_BYTES)flush();}
|
|
45
45
|
flush();return output;
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
// Only the worker bridge registers streams here. Their backing allocations
|
|
48
|
+
// crossed a transfer boundary, have no producer aliases, and the framework's
|
|
49
|
+
// outgoing transport does not mutate or transfer them again. Arbitrary React,
|
|
50
|
+
// fetch and application streams retain the defensive per-chunk copy.
|
|
51
|
+
// Even an owned partial view is copied: retaining its much larger backing
|
|
52
|
+
// allocation would defeat the byte-based capture limit.
|
|
53
|
+
const ownedStreams=new WeakSet();
|
|
54
|
+
function ownFlightStream(source){ownedStreams.add(source);return source;}
|
|
55
|
+
function collectStream(source,{onComplete,onEnd,onCancel,onFinally,capture=true}={}) {
|
|
56
|
+
const owned=ownedStreams.has(source);
|
|
57
|
+
const reader=source.getReader(), parts=[];let size=0,complete=false,finished=false,cancelled=false;
|
|
49
58
|
const finish=()=>{if(!finished){finished=true;onFinally?.();}};
|
|
50
59
|
return new ReadableStream({
|
|
51
|
-
async pull(controller) {
|
|
52
|
-
|
|
60
|
+
async pull(controller) {
|
|
61
|
+
try {
|
|
62
|
+
const next=await reader.read();
|
|
63
|
+
if(cancelled)return;
|
|
64
|
+
if(next.done){
|
|
65
|
+
complete=true;
|
|
66
|
+
if(capture)onComplete?.(join(parts,size));
|
|
67
|
+
parts.length=0;onEnd?.();finish();controller.close();return;
|
|
68
|
+
}
|
|
69
|
+
const value=next.value;
|
|
70
|
+
if(!(value instanceof Uint8Array))throw new Error('Invalid Flight bytes');
|
|
71
|
+
size+=value.length;
|
|
72
|
+
if(size>MAX_RESPONSE)throw new Error('Flight exceeds transport budget');
|
|
73
|
+
if(capture){
|
|
74
|
+
// Limits include the number of retained allocations, not just their
|
|
75
|
+
// payload bytes. An abandoned capture never interrupts the response.
|
|
76
|
+
if(size>MAX_VALUE||value.length&&parts.length>=MAX_CAPTURE_PARTS){capture=false;parts.length=0;}
|
|
77
|
+
else if(value.length){
|
|
78
|
+
const wholeOwned=owned&&value.buffer instanceof ArrayBuffer&&value.byteOffset===0&&value.byteLength===value.buffer.byteLength;
|
|
79
|
+
// Buffer.slice() aliases its producer's backing allocation. The
|
|
80
|
+
// plain Uint8Array constructor always copies just the visible bytes.
|
|
81
|
+
parts.push(wholeOwned?value:new Uint8Array(value));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
controller.enqueue(value);
|
|
85
|
+
}catch(error){parts.length=0;finish();if(cancelled)return;controller.error(error);await reader.cancel(error).catch(()=>{});}
|
|
86
|
+
},
|
|
87
|
+
async cancel(reason){cancelled=true;parts.length=0;finish();if(!complete)onCancel?.();await reader.cancel(reason);},
|
|
53
88
|
},{highWaterMark:0});
|
|
54
89
|
}
|
|
55
90
|
async function deltaStream(source,base,{assess}={}) {
|
|
@@ -58,10 +93,10 @@ async function deltaStream(source,base,{assess}={}) {
|
|
|
58
93
|
// A short first chunk always selects ordinary Flight. Do not build a base
|
|
59
94
|
// index that this response cannot use, or wait for a later streaming chunk.
|
|
60
95
|
let index=first.value.length>=WINDOW&&base instanceof Uint8Array&&base.length<=MAX_VALUE?createIndex(base):null;
|
|
61
|
-
const profitable=(raw,frames,initial)=>frames&&frames.reduce((n,b)=>n+b.length,0)+(initial?5:1)<raw.length*0.9&&(!assess||assess(raw,join(initial?[MAGIC,...frames,new Uint8Array([2])]:frames,frames.reduce((n,b)=>n+b.length,0)+(initial?5:0)))===true);
|
|
96
|
+
const profitable=async(raw,frames,initial)=>frames&&frames.reduce((n,b)=>n+b.length,0)+(initial?5:1)<raw.length*0.9&&(!assess||await assess(raw,join(initial?[MAGIC,...frames,new Uint8Array([2])]:frames,frames.reduce((n,b)=>n+b.length,0)+(initial?5:0)))===true);
|
|
62
97
|
const firstFrames=index&&first.value.length>=WINDOW?encodeChunk(first.value,base,index):null;
|
|
63
98
|
let useDelta;
|
|
64
|
-
try{useDelta=!!profitable(first.value,firstFrames,true);}catch(error){await reader.cancel(error).catch(()=>{});throw error;}
|
|
99
|
+
try{useDelta=!!(await profitable(first.value,firstFrames,true));}catch(error){await reader.cancel(error).catch(()=>{});throw error;}
|
|
65
100
|
let pending=useDelta?blocks([MAGIC,...firstFrames]):[first.value], pendingAt=0,ended=false,tail=false,commands=firstFrames?.commands||0;
|
|
66
101
|
if(!useDelta){base=undefined;index=undefined;}
|
|
67
102
|
return {delta:!!useDelta,body:new ReadableStream({
|
|
@@ -69,7 +104,7 @@ async function deltaStream(source,base,{assess}={}) {
|
|
|
69
104
|
if(pendingAt===pending.length&&!ended){pending=[];pendingAt=0;const next=await reader.read();
|
|
70
105
|
if(next.done){ended=true;if(useDelta&&!tail)pending=[new Uint8Array([2])];}
|
|
71
106
|
else if(useDelta&&!tail){const encoded=encodeChunk(next.value,base,index);commands+=encoded?.commands||0;
|
|
72
|
-
if(commands>MAX_COMMANDS||!profitable(next.value,encoded,false)){tail=true;index=undefined;base=undefined;pending=blocks([new Uint8Array([3]),next.value]);}
|
|
107
|
+
if(commands>MAX_COMMANDS||!await profitable(next.value,encoded,false)){tail=true;index=undefined;base=undefined;pending=blocks([new Uint8Array([3]),next.value]);}
|
|
73
108
|
else pending=blocks(encoded);
|
|
74
109
|
}else pending=[next.value];
|
|
75
110
|
}
|
|
@@ -134,19 +169,19 @@ function createFlightTransport() {
|
|
|
134
169
|
let current,serial=0;
|
|
135
170
|
return {
|
|
136
171
|
snapshot(){return current;},
|
|
137
|
-
async response(response,base) {
|
|
172
|
+
async response(response,base,{onEnd}={}) {
|
|
138
173
|
const version=++serial;
|
|
139
174
|
const token=response.headers.get('x-prnext-flight-token'), headers=new Headers(response.headers);
|
|
140
175
|
let source=response.body;
|
|
141
|
-
if(!source)return response;
|
|
176
|
+
if(!source){onEnd?.();return response;}
|
|
142
177
|
if(headers.get('content-type')?.startsWith(TYPE)) {
|
|
143
178
|
if(!base||headers.get('x-prnext-flight-base')!==base.token){await source.cancel();throw new Error('Missing Flight delta base');}
|
|
144
179
|
source=decodeStream(source,base.bytes);
|
|
145
180
|
}
|
|
146
181
|
headers.set('content-type','text/x-component; charset=utf-8');headers.delete('content-length');headers.delete('content-encoding');
|
|
147
|
-
return new Response(collectStream(source,{capture:!!token&&/^[a-f0-9]{48}$/.test(token),onComplete:bytes=>{if(version===serial&&token&&/^[a-f0-9]{48}$/.test(token))current={token,bytes};}}),{status:response.status,statusText:response.statusText,headers});
|
|
182
|
+
return new Response(collectStream(source,{capture:!!token&&/^[a-f0-9]{48}$/.test(token),onEnd,onComplete:bytes=>{if(version===serial&&token&&/^[a-f0-9]{48}$/.test(token))current={token,bytes};}}),{status:response.status,statusText:response.statusText,headers});
|
|
148
183
|
},
|
|
149
184
|
clear(){serial++;current=undefined;},
|
|
150
185
|
};
|
|
151
186
|
}
|
|
152
|
-
module.exports={TYPE,MAX_VALUE,createIndex,encodeChunk,deltaStream,decodeStream,collectStream,createFlightTransport};
|
|
187
|
+
module.exports={TYPE,MAX_VALUE,createIndex,encodeChunk,deltaStream,decodeStream,collectStream,createFlightTransport,ownFlightStream};
|
package/compat/index.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface InstantSample {
|
|
|
14
14
|
export type InstantConfig = boolean | { level?: 'warning' | 'experimental-error'; unstable_samples?: InstantSample[]; unstable_disableValidation?: true; unstable_disableDevValidation?: true; unstable_disableBuildValidation?: true };
|
|
15
15
|
|
|
16
16
|
export interface ReactCompilerOptions {
|
|
17
|
+
/** Babel by default. The native Oxc backend is experimental and opt-in. */
|
|
18
|
+
backend?: 'babel' | 'oxc';
|
|
17
19
|
compilationMode?: 'infer' | 'annotation';
|
|
18
20
|
panicThreshold?: 'none' | 'critical_errors' | 'all_errors';
|
|
19
21
|
/** PRNext requires matching React 19 peers. */
|
|
@@ -121,6 +123,8 @@ export interface Rewrite extends CustomRoute { destination: string }
|
|
|
121
123
|
export type ConfigRedirect = CustomRoute & Redirect;
|
|
122
124
|
/** Implemented project options. Unsupported behavior-changing options fail the build. */
|
|
123
125
|
export interface NextConfig {
|
|
126
|
+
/** Public origin and transport peers permitted to set X-Forwarded-Host/Proto. */
|
|
127
|
+
server?: {publicOrigin?: string; trustedProxies?: readonly string[]};
|
|
124
128
|
/** PRNext only. CLI > environment > build configuration > profile.
|
|
125
129
|
* 0 disables the corresponding retirement; keepWarm retains one lane per used host.
|
|
126
130
|
*/
|
|
@@ -131,6 +135,10 @@ export interface NextConfig {
|
|
|
131
135
|
workerPreload?: false | { routes: string[]; maxRssMb?: number; timeoutMs?: number };
|
|
132
136
|
/** Keep bounded previous public hashed assets. false disables carry-over. Defaults: one hour, two generations, 64 MiB. */
|
|
133
137
|
deploymentRetention?: false | {maxAge?: number; maxGenerations?: number; maxBytes?: number};
|
|
138
|
+
/** Common disk budget for regenerable compiler caches, in bytes (default 256 MiB).
|
|
139
|
+
* Applied after builds; active dev sessions/workers can defer reclamation.
|
|
140
|
+
* Runtime data, invalidations, page and image caches are excluded. */
|
|
141
|
+
compilationCache?: {maxDiskSize?: number};
|
|
134
142
|
/** PRNext production prerender processes; maxMemoryMb bounds their combined observed memory. */
|
|
135
143
|
prerender?: {workers?: number; maxMemoryMb?: number};
|
|
136
144
|
/** Explicit App route patterns that must produce complete static HTML without browser JavaScript. */
|
|
@@ -167,7 +175,20 @@ export interface NextConfig {
|
|
|
167
175
|
implementation?: 'sass' | 'sass-embedded';
|
|
168
176
|
[option: string]: unknown;
|
|
169
177
|
};
|
|
170
|
-
experimental?: {
|
|
178
|
+
experimental?: {
|
|
179
|
+
nextScriptWorkers?: boolean;
|
|
180
|
+
/** App Router development only; compile literal client imports on first use. */
|
|
181
|
+
lazyDynamicImports?: boolean;
|
|
182
|
+
/** Start App Route Handlers before upload EOF; mutations must handle aborted uploads. */
|
|
183
|
+
streamingRequestBodies?: boolean;
|
|
184
|
+
/** Serve certified public PPR document shells before starting Node. Requires cacheComponents. */
|
|
185
|
+
nativePprShell?: boolean;
|
|
186
|
+
/** Bound independent production CSS builds after graph discovery. Disabled by default. */
|
|
187
|
+
parallelBuilds?: boolean | {maxWorkers?: number; maxMemoryMb?: number};
|
|
188
|
+
optimizePackageImports?: string[];
|
|
189
|
+
proxyClientMaxBodySize?: number | string;
|
|
190
|
+
serverActions?: true | {allowedOrigins?: string[]; bodySizeLimit?: number | string};
|
|
191
|
+
};
|
|
171
192
|
trailingSlash?: boolean;
|
|
172
193
|
skipTrailingSlashRedirect?: boolean;
|
|
173
194
|
skipMiddlewareUrlNormalize?: boolean;
|
|
@@ -216,6 +237,7 @@ export interface StaticBuildOptions {
|
|
|
216
237
|
}
|
|
217
238
|
export interface ReactCompilerReport {
|
|
218
239
|
version: 1;
|
|
240
|
+
backend?: 'babel' | 'oxc';
|
|
219
241
|
compilerVersion: string | null;
|
|
220
242
|
enabled: boolean;
|
|
221
243
|
buildId: string | null;
|
|
@@ -227,6 +249,7 @@ export interface ReactCompilerReport {
|
|
|
227
249
|
summary: {files: number; functions: number; optimized: number; skipped: number; errors: number; diagnostics: number; mixed: number; transforms: number; cacheReuses: number};
|
|
228
250
|
files: Array<{
|
|
229
251
|
file: string; transforms: number; cacheReuses: number; targets: string[]; notes: string[];
|
|
252
|
+
diagnostics?: Array<{kind: 'CompileError' | 'CompileDiagnostic'; status: 'error' | 'diagnostic'; reason: string | null; category: string | null; targets: Array<'browser' | 'node' | 'edge' | 'unspecified'>}>;
|
|
230
253
|
functions: Array<{
|
|
231
254
|
name: string | null;
|
|
232
255
|
start: {line: number; column: number} | null;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const { createHmac } = require('node:crypto');
|
|
3
|
+
function developmentNavigationSecret(actionKey) {
|
|
4
|
+
if (typeof actionKey !== 'string' || !actionKey) return undefined;
|
|
5
|
+
// The compiler retains this private key across generations of one dev
|
|
6
|
+
// session. Derive a separate purpose key so worker replacement cannot look
|
|
7
|
+
// like an account change, without publishing or reusing the encryption key.
|
|
8
|
+
return createHmac('sha256', actionKey).update('prnext:development:navigation-authorization:v1').digest('hex');
|
|
9
|
+
}
|
|
3
10
|
function navigationAuthorization(context, secret, cookieNames) {
|
|
4
11
|
if (!secret || context?.staticState) return undefined;
|
|
5
12
|
const names = cookieNames === undefined ? null : new Set(cookieNames);
|
|
6
13
|
const cookies = context.cookies.getAll().filter(cookie => !names || names.has(cookie.name)).map(({ name, value }) => [name, value]).sort((a, b) => a[0].localeCompare(b[0]));
|
|
7
14
|
return createHmac('sha256', secret).update(JSON.stringify([cookies, context.headers.get('authorization') || ''])).digest('hex');
|
|
8
15
|
}
|
|
9
|
-
module.exports = { navigationAuthorization };
|
|
16
|
+
module.exports = { navigationAuthorization, developmentNavigationSecret };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Constructed only for opt-in diagnostics. Samples contain numeric runtime
|
|
4
|
+
// counters, never application values, request context or allocation stacks.
|
|
5
|
+
function createRuntimeSampler() {
|
|
6
|
+
const { PerformanceObserver, performance } = require('node:perf_hooks');
|
|
7
|
+
const { threadId, resourceLimits } = require('node:worker_threads');
|
|
8
|
+
const { getHeapSpaceStatistics } = require('node:v8');
|
|
9
|
+
let count = 0, durationMs = 0, maxPauseMs = 0;
|
|
10
|
+
let previousTime = performance.now();
|
|
11
|
+
let previousLoop = performance.eventLoopUtilization();
|
|
12
|
+
let previousCpu = threadId === 0 ? process.cpuUsage() : undefined;
|
|
13
|
+
const consume = entries => {
|
|
14
|
+
for (const entry of entries) {
|
|
15
|
+
count++;
|
|
16
|
+
durationMs += entry.duration;
|
|
17
|
+
maxPauseMs = Math.max(maxPauseMs, entry.duration);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const observer = new PerformanceObserver(list => consume(list.getEntries()));
|
|
21
|
+
observer.observe({ entryTypes: ['gc'] });
|
|
22
|
+
return {
|
|
23
|
+
sample() {
|
|
24
|
+
consume(observer.takeRecords());
|
|
25
|
+
const now = performance.now();
|
|
26
|
+
const loop = performance.eventLoopUtilization();
|
|
27
|
+
const eventLoop = performance.eventLoopUtilization(loop, previousLoop);
|
|
28
|
+
const { rss, heapUsed, heapTotal, external, arrayBuffers } = process.memoryUsage();
|
|
29
|
+
const young = getHeapSpaceStatistics().find(space => space.space_name === 'new_space');
|
|
30
|
+
const value = {
|
|
31
|
+
node: process.version, v8: process.versions.v8, threadId,
|
|
32
|
+
intervalMs: now - previousTime,
|
|
33
|
+
rssBytes: rss, heapUsedBytes: heapUsed, heapTotalBytes: heapTotal,
|
|
34
|
+
externalBytes: external, arrayBufferBytes: arrayBuffers,
|
|
35
|
+
youngSpaceBytes: young?.space_size ?? 0,
|
|
36
|
+
workerLimits: { ...resourceLimits },
|
|
37
|
+
gc: { count, durationMs, maxPauseMs },
|
|
38
|
+
eventLoop,
|
|
39
|
+
};
|
|
40
|
+
// CPU usage is process-wide, including all worker threads. Emit it only
|
|
41
|
+
// in the main isolate so aggregators cannot count the RSC CPU twice.
|
|
42
|
+
if (previousCpu) {
|
|
43
|
+
const cpu = process.cpuUsage();
|
|
44
|
+
value.cpu = { scope: 'process', userMicros: cpu.user - previousCpu.user,
|
|
45
|
+
systemMicros: cpu.system - previousCpu.system };
|
|
46
|
+
previousCpu = cpu;
|
|
47
|
+
}
|
|
48
|
+
previousLoop = loop; previousTime = now;
|
|
49
|
+
count = durationMs = maxPauseMs = 0;
|
|
50
|
+
return value;
|
|
51
|
+
},
|
|
52
|
+
close() { observer.disconnect(); },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = { createRuntimeSampler };
|
package/compat/use-cache.cjs
CHANGED
|
@@ -93,14 +93,17 @@ async function invokeCache(id, kind, captures, args, callback, segment = '') {
|
|
|
93
93
|
then(_resolve, reject) { reject(new Error("searchParams cannot be read inside 'use cache'; read them outside and pass their values as arguments")); },
|
|
94
94
|
};
|
|
95
95
|
if (encoded.key.length > MAX_BYTES) throw new Error("'use cache' arguments exceed 2 MiB");
|
|
96
|
-
const
|
|
96
|
+
const format=codec===plainCodec?':v8:':codec.cacheKeyVersion==='flight-primitives-v2'?':flight-primitives-v2:':':flight:';
|
|
97
|
+
const key = createHash('sha256').update(id).update(kind).update(format).update(encoded.key).digest('hex');
|
|
97
98
|
const profiles = context.cacheLife || context.manifest?.config?.cacheLife || defaults;
|
|
98
99
|
const scope = { kind, profiles, life: { ...profiles.default }, explicit: new Set(), tags: new Set() };
|
|
99
100
|
let producedMetadata;
|
|
100
101
|
const producer = async () => runCacheScope(async () => {
|
|
101
102
|
const value = await codec.render(() => callback(...encoded.values), encoded, context);
|
|
102
103
|
producedMetadata = metadata(scope, context);
|
|
103
|
-
|
|
104
|
+
// envelope owns its result immediately; an already owned codec Buffer need
|
|
105
|
+
// not be copied into another temporary Buffer before this synchronous copy.
|
|
106
|
+
return envelope(producedMetadata, Buffer.isBuffer(value)?value:Buffer.from(value));
|
|
104
107
|
}, scope);
|
|
105
108
|
let bytes, handlerMetadata;
|
|
106
109
|
const custom = kind !== 'private' && !context.draftMode && Object.hasOwn(configured(context), kind);
|
package/docs/ai/compatibility.md
CHANGED
|
@@ -18,6 +18,13 @@ transpilation, image/font tooling and caching deserve targeted build and browser
|
|
|
18
18
|
tests. Support for one configuration shape does not imply support for all
|
|
19
19
|
upstream plugin behavior.
|
|
20
20
|
|
|
21
|
+
When moving from 0.1.19-alpha, use the installed
|
|
22
|
+
[upgrade checklist](deployment.md#upgrading-from-0119-alpha): rebuild matching
|
|
23
|
+
artifacts, configure the public HTTPS origin and proxy trust, verify strict
|
|
24
|
+
account transitions and review saved persistent health routes. Storage cleanup
|
|
25
|
+
must preserve runtime data and invalidation history. Experimental performance
|
|
26
|
+
options remain independent and opt-in.
|
|
27
|
+
|
|
21
28
|
## Instrumentation and tracing
|
|
22
29
|
|
|
23
30
|
Use a single `instrumentation.ts`, `.js`, `.mjs` or `.cjs` at the project root
|
|
@@ -97,7 +104,7 @@ implemented through PRNext's generated route registry. Do not copy a full
|
|
|
97
104
|
Next.js configuration template into a new application.
|
|
98
105
|
|
|
99
106
|
The repository's reference tests build and run matching applications against
|
|
100
|
-
Next.js 16.4.
|
|
107
|
+
Next.js 16.4.4, including mounted App navigation, form Actions and cookies,
|
|
101
108
|
metadata, Pages locale routing, redirects, APIs and selected webpack loader
|
|
102
109
|
contracts. These executable examples cover specific behavior; they do not
|
|
103
110
|
certify every Next.js application or plugin. `NextRequest.nextUrl` understands
|
|
@@ -105,10 +112,10 @@ data-route build IDs and locales, and request-cookie mutations synchronize the
|
|
|
105
112
|
request header. Request cookies have different mutation results from response
|
|
106
113
|
cookies; do not use them interchangeably.
|
|
107
114
|
|
|
108
|
-
A locked real-application fixture additionally exercises Better Auth 1.7.
|
|
115
|
+
A locked real-application fixture additionally exercises Better Auth 1.7.15
|
|
109
116
|
(email/password, session cookies and logout), Drizzle ORM 0.45.4 over SQLite
|
|
110
117
|
through its proxy driver, next-intl 4.14.9 (server and client translations),
|
|
111
|
-
and the MDX 3.1.1 webpack loader against Next.js 16.4.
|
|
118
|
+
and the MDX 3.1.1 webpack loader against Next.js 16.4.4. It covers authenticated
|
|
112
119
|
Server Actions, user-owned rows, cookie/locale isolation, client navigation and
|
|
113
120
|
Server Component `after()` callbacks. This is evidence for those workflows,
|
|
114
121
|
not a guarantee for every plugin, provider or deployment configuration.
|
|
@@ -132,6 +139,66 @@ new source files and configuration changes restart the native watch generation.
|
|
|
132
139
|
adding its generated declaration to the config. Compiler support does not imply
|
|
133
140
|
that every application is ready for TypeScript 7's own language/config changes.
|
|
134
141
|
|
|
142
|
+
## Experimental performance paths
|
|
143
|
+
|
|
144
|
+
These options are independent and disabled by default. Enable them in the
|
|
145
|
+
application's existing configuration, then qualify its actual workflows:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
export default {
|
|
149
|
+
cacheComponents: true,
|
|
150
|
+
experimental: {
|
|
151
|
+
nativePprShell: true,
|
|
152
|
+
streamingRequestBodies: true,
|
|
153
|
+
parallelBuilds: {maxWorkers: 4, maxMemoryMb: 1024},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`nativePprShell` lets Rust send the exact certified build shell before starting
|
|
159
|
+
Node, then resume its React continuation. The initial implementation covers
|
|
160
|
+
concrete App PPR document GETs without query strings, cookies, authorization,
|
|
161
|
+
middleware, rewrites, base paths, router-state/Flight/prefetch headers or CSP
|
|
162
|
+
nonces. Generic parameter shells, Edge, external caches and unsupported requests
|
|
163
|
+
keep the ordinary Node path. Prefixes and artifacts have checked hashes and
|
|
164
|
+
bounded sizes; continuations use a private transport field, never an HTTP flag.
|
|
165
|
+
Responses remain private and no-store. The cache generation must still be zero
|
|
166
|
+
and the build artifact unexpired: any persisted invalidation disables this build
|
|
167
|
+
snapshot optimization, including across server restarts. It does not disable
|
|
168
|
+
PPR itself or invalidate an already committed response. Requests already using
|
|
169
|
+
a snapshot finish with that same artifact when an invalidation races them.
|
|
170
|
+
|
|
171
|
+
`streamingRequestBodies` makes `Request.body` available to Node App Route
|
|
172
|
+
Handlers before upload EOF. It negotiates its own protocol capability and sends
|
|
173
|
+
at most one 64 KiB frame per reader credit. Unsupported workers use the existing
|
|
174
|
+
buffered path. Server Actions, Pages APIs and middleware-buffered requests retain
|
|
175
|
+
their previous buffering behavior. Streaming handlers can begin application
|
|
176
|
+
effects before a truncated or excessive upload is rejected: validate the input
|
|
177
|
+
and complete authorization before committing a mutation. The total request limit
|
|
178
|
+
remains 32 MiB. Existing ingress byte reservations are preserved; this feature
|
|
179
|
+
does not promise a smaller V8 heap or higher memory admission concurrency. A
|
|
180
|
+
cancelled or early-returned upload closes its single-use lane without replaying
|
|
181
|
+
the mutation, while retaining the healthy Node host.
|
|
182
|
+
|
|
183
|
+
`parallelBuilds` freezes App stylesheet plans after dependency discovery,
|
|
184
|
+
deduplicates outputs and emits independent jobs with deterministic linking.
|
|
185
|
+
Graph discovery itself remains ordered. Concurrency is bounded by CPU count,
|
|
186
|
+
available memory and the configured worker/budget limits. `maxWorkers` accepts
|
|
187
|
+
1–8; `maxMemoryMb` accepts 256–8192 and is an admission estimate, not a hard RSS
|
|
188
|
+
limit for third-party code. Custom webpack/loaders, custom PostCSS pipelines and
|
|
189
|
+
Sass callbacks retain serial execution. A failed job stops new admission and
|
|
190
|
+
settles started jobs before the staging build is discarded; the last published
|
|
191
|
+
build is preserved. An enabled build records its actual stylesheet job count
|
|
192
|
+
and selected concurrency in `manifest.buildParallelism`.
|
|
193
|
+
|
|
194
|
+
Development refreshes can also target the routes that import a changed Server
|
|
195
|
+
Action or its transitive dependencies. Certification uses both dependency
|
|
196
|
+
graphs before and after a change. An unrelated tab still applies a deferred
|
|
197
|
+
generation before navigating to a changed route. Unknown or incomplete graphs,
|
|
198
|
+
binding/runtime/route changes, global configuration, rewrites/middleware,
|
|
199
|
+
internationalized or parallel/intercepting routing retain a global refresh.
|
|
200
|
+
Server generations still publish as a whole; pending mutations are never replayed.
|
|
201
|
+
|
|
135
202
|
## React Compiler
|
|
136
203
|
|
|
137
204
|
Enable the bundled official React Compiler in the project's existing config:
|
|
@@ -142,7 +209,7 @@ export default {
|
|
|
142
209
|
};
|
|
143
210
|
```
|
|
144
211
|
|
|
145
|
-
|
|
212
|
+
The default Babel backend needs no separate compiler installation. The default is disabled;
|
|
146
213
|
`reactCompiler: false` preserves the uncompiled component path. Enabled builds
|
|
147
214
|
optimize project-owned browser components in both Pages and App applications,
|
|
148
215
|
in development and production. App Client Components also use the transform in
|
|
@@ -153,17 +220,43 @@ Components, Server Action modules, PRNext internals, generated entrypoints and
|
|
|
153
220
|
npm packages are not compiled. Keep the matching React 19 peer versions required
|
|
154
221
|
by the installed framework.
|
|
155
222
|
|
|
156
|
-
|
|
157
|
-
in those extensions remain unsupported.
|
|
223
|
+
With the default Babel backend, ordinary `.mts`/`.cts` hook helpers can be
|
|
224
|
+
optimized; server/client directives in those extensions remain unsupported.
|
|
225
|
+
Decorated `.mts`/`.cts` utility modules
|
|
158
226
|
keep their native compilation path while importing React components can still
|
|
159
227
|
be optimized.
|
|
160
228
|
|
|
161
229
|
For gradual adoption, use `reactCompiler: { compilationMode: 'annotation' }`, then
|
|
162
230
|
put `"use memo";` at the beginning of each component or hook to optimize. In
|
|
163
231
|
either mode, `"use no memo";` excludes an individual function. Supported object
|
|
164
|
-
options are `compilationMode: 'infer' | 'annotation'`,
|
|
232
|
+
options are `backend: 'babel' | 'oxc'`, `compilationMode: 'infer' | 'annotation'`,
|
|
165
233
|
`panicThreshold: 'none' | 'critical_errors' | 'all_errors'` and `target: '19'`.
|
|
166
|
-
Defaults are `'infer'`, `'none'` and `'19'`; other fields are rejected.
|
|
234
|
+
Defaults are Babel, `'infer'`, `'none'` and `'19'`; other fields are rejected.
|
|
235
|
+
|
|
236
|
+
The experimental native Rust backend is an explicit alternative:
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
npm install --save-dev oxc-transform-react@0.157.0
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```js
|
|
243
|
+
export default {
|
|
244
|
+
reactCompiler: { backend: 'oxc' },
|
|
245
|
+
};
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Oxc is an optional peer, so ordinary Babel builds do not install its compiler,
|
|
249
|
+
WASM distribution or native binding. Run the installation above in the application
|
|
250
|
+
project on the build machine, with optional platform dependencies enabled. A
|
|
251
|
+
global CLI also resolves this project-local peer. This option
|
|
252
|
+
requires the native binding; an absent or incompatible compiler, missing binding
|
|
253
|
+
or compilation failure fails explicitly. PRNext never silently changes the backend. JSX remains available
|
|
254
|
+
to the existing graph compiler, while this backend removes TypeScript syntax.
|
|
255
|
+
App Client Component server rendering uses Oxc's SSR output; browser graphs use
|
|
256
|
+
its client output. The same project boundaries and Server Action exclusions
|
|
257
|
+
apply. Source maps, loader maps and the existing Fast Refresh pipeline remain
|
|
258
|
+
part of the compilation path. Unsupported options are rejected rather than
|
|
259
|
+
passed through to the native compiler.
|
|
167
260
|
|
|
168
261
|
After a successful build, inspect the compiler's actual results:
|
|
169
262
|
|
|
@@ -172,8 +265,8 @@ prnext compiler
|
|
|
172
265
|
prnext compiler --json
|
|
173
266
|
```
|
|
174
267
|
|
|
175
|
-
|
|
176
|
-
or skip status, and the compiler's reasons. These are transform decisions;
|
|
268
|
+
For Babel, the report names observed functions, their project-relative files,
|
|
269
|
+
optimization or skip status, and the compiler's reasons. These are transform decisions;
|
|
177
270
|
server-code removal and tree shaking can later omit a function from the browser
|
|
178
271
|
bundle. Cached transforms retain their
|
|
179
272
|
diagnostics and are identified as reused. Browser and server graphs do not
|
|
@@ -183,6 +276,12 @@ complete application coverage. Disabled compilation is reported explicitly.
|
|
|
183
276
|
The report describes the last successful build, stays outside public assets and
|
|
184
277
|
does not include source code. A failed build preserves the previous report.
|
|
185
278
|
|
|
279
|
+
The Oxc report identifies the backend and package version, records native
|
|
280
|
+
diagnostics at file scope, and states that function optimization totals are
|
|
281
|
+
unavailable: its API does not expose Babel's function-success events. This is
|
|
282
|
+
not a count of zero optimized functions. Cached native diagnostics are replayed;
|
|
283
|
+
cache identities include the backend, compiler version and client/SSR mode.
|
|
284
|
+
|
|
186
285
|
The compiler can skip code that cannot be safely optimized. Follow the Rules of
|
|
187
286
|
React and check actual behavior rather than assuming every component was
|
|
188
287
|
compiled. It reduces repeated component work; it does not guarantee faster
|
|
@@ -192,6 +291,10 @@ production build with the option enabled and disabled. Compilation adds build
|
|
|
192
291
|
work; PRNext caches pure transforms with their compiler version and settings.
|
|
193
292
|
|
|
194
293
|
See the [official React Compiler documentation](https://react.dev/learn/react-compiler).
|
|
294
|
+
The [Oxc React Compiler guide](https://oxc.rs/docs/guide/usage/transformer/react-compiler.html)
|
|
295
|
+
describes the experimental backend. Measure compilation and application behavior
|
|
296
|
+
with the selected backend before adopting it; selecting Rust alone is not a
|
|
297
|
+
measured speedup for a project.
|
|
195
298
|
|
|
196
299
|
Only explicit private Next.js import adapters are supported. Do not add arbitrary
|
|
197
300
|
`next/dist/...` imports or install another Next runtime to satisfy one: isolate
|
package/docs/ai/deployment.md
CHANGED
|
@@ -8,12 +8,93 @@ Build with the installed PRNext and run the resulting trusted output with its
|
|
|
8
8
|
matching runtime:
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
+
prnext check --production
|
|
11
12
|
prnext typecheck
|
|
12
13
|
prnext build
|
|
13
14
|
prnext output --json
|
|
14
15
|
prnext start --hostname 127.0.0.1 --port 3000
|
|
15
16
|
```
|
|
16
17
|
|
|
18
|
+
### Upgrading from an earlier alpha
|
|
19
|
+
|
|
20
|
+
Install matching framework/native versions, then rebuild and restart the complete
|
|
21
|
+
application or standalone output. Keep Node and the React protocol peers aligned
|
|
22
|
+
with this package's metadata. Existing compiler entries are reused only when
|
|
23
|
+
their identities match; never delete `data.sqlite3` or invalidation history to
|
|
24
|
+
perform an upgrade. Read the storage section below before pruning compiler caches.
|
|
25
|
+
|
|
26
|
+
Persistent apps need a supervisor restart too. In a maintenance window for the
|
|
27
|
+
whole `PRNEXT_PM_HOME`, run the old installation's `prnext pdown` with that same
|
|
28
|
+
home before replacing packages. The 0.1.21 local protocol rejects an old
|
|
29
|
+
supervisor rather than silently taking it over. Shutdown stops all managed apps
|
|
30
|
+
and preserves saved settings and enabled
|
|
31
|
+
entries; `prestart` alone keeps the already loaded supervisor code. Update and
|
|
32
|
+
rebuild the installations that must return with the new version, then launch `pstart` or
|
|
33
|
+
`prestart` through the new CLI. It also restores all enabled entries, with their
|
|
34
|
+
saved binary paths and health routes. Check `pstatus` and real health responses;
|
|
35
|
+
a global CLI update does not replace each app's package or binary. Keep independent
|
|
36
|
+
lifecycles in separate homes. Do not stop unrelated Node processes or external
|
|
37
|
+
databases, Redis, proxies and OS services as an automatic upgrade fallback.
|
|
38
|
+
|
|
39
|
+
Set `server.publicOrigin` to the external HTTPS origin and `server.trustedProxies`
|
|
40
|
+
to the immediate proxy's IP/CIDR addresses. The configured origin wins; forwarded
|
|
41
|
+
host/protocol headers are trusted only from those peers. Rebuild after config
|
|
42
|
+
changes and check redirects, secure cookies and authentication callbacks over
|
|
43
|
+
the actual public URL. This does not establish a forwarded client-IP chain.
|
|
44
|
+
|
|
45
|
+
Run production preflight, then test account A → sign out → account B with the
|
|
46
|
+
actual `navigationCache.authCookies`, including shared layouts and browser
|
|
47
|
+
history. Changed or unknown strict identities require a fresh document; cached
|
|
48
|
+
PPR previews wait for fresh identity. Authorize protected reads and writes in
|
|
49
|
+
the application as before.
|
|
50
|
+
|
|
51
|
+
Use a dedicated complete HTTP 200 application health response for database/service
|
|
52
|
+
readiness. `/_prnext/health` checks native readiness only; redirects no longer
|
|
53
|
+
pass persistent health checks. Previously saved applications keep their health
|
|
54
|
+
path, so a redirecting `/` must be replaced in the saved persistent settings.
|
|
55
|
+
Observe the post-switch rollback window and exercise an explicit idempotent
|
|
56
|
+
retry; a lost response can follow a successful write, and mutations are never
|
|
57
|
+
automatically replayed. Keep schema changes compatible with the previous server.
|
|
58
|
+
|
|
59
|
+
### Production preflight
|
|
60
|
+
|
|
61
|
+
Run `prnext check --production --json` to collect deployment diagnostics without
|
|
62
|
+
building or rewriting the application. It evaluates the production config and
|
|
63
|
+
environment files, restores the calling process environment afterward, and checks
|
|
64
|
+
installed dependencies, route conventions, the public origin, proxy trust,
|
|
65
|
+
authentication retention settings and active experimental options. JSON diagnostics
|
|
66
|
+
include `code`, `path`, `severity` and an action where one is needed. Errors fail
|
|
67
|
+
the command; warnings require review and do not change its exit status.
|
|
68
|
+
|
|
69
|
+
If a build already exists, preflight also compares its public origin, proxy and
|
|
70
|
+
authentication retention settings with the current config and rejects a development artifact. Rebuild after
|
|
71
|
+
changing deployment settings: `prnext start` reads the selected artifact and does
|
|
72
|
+
not reevaluate the source configuration. Missing output is informational before
|
|
73
|
+
the first build; unreadable existing metadata requires review.
|
|
74
|
+
|
|
75
|
+
For authenticated App Router applications, explicitly list every session cookie
|
|
76
|
+
name, including HTTPS variants used by the authentication library:
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
export default {
|
|
80
|
+
navigationCache: {
|
|
81
|
+
authCookies: ['session-cookie-name', '__Secure-session-cookie-name'],
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Replace these example names with the application's actual cookies; PRNext does
|
|
87
|
+
not infer authentication from cookie names. This enables strict retained-page
|
|
88
|
+
state resets when the server's authorization identity changes. Test account A →
|
|
89
|
+
sign out → account B with both active and retained pages, and confirm that private
|
|
90
|
+
drafts disappear. Public applications can review the guidance or disable page
|
|
91
|
+
retention with `navigationCache: false`.
|
|
92
|
+
|
|
93
|
+
A successful preflight checks configuration, not external services or application
|
|
94
|
+
authorization. Qualify the final build over public HTTPS, including authentication,
|
|
95
|
+
health checks, failure recovery and rollback. Experimental warnings identify the
|
|
96
|
+
options that need workload-specific validation; they are not performance claims.
|
|
97
|
+
|
|
17
98
|
The default build directory is `.prnext`; `distDir` can change it. The private
|
|
18
99
|
project output selector is `.prnext-output.json`. Do not assume `.next` layout,
|
|
19
100
|
run `next start` on a PRNext build or hand-edit its manifests to bypass runtime
|
|
@@ -254,6 +335,69 @@ an explicit choice, not a reason to print credentials or copy `.env` into assets
|
|
|
254
335
|
|
|
255
336
|
## Observe before tuning
|
|
256
337
|
|
|
338
|
+
### Installation and disk storage
|
|
339
|
+
|
|
340
|
+
The default installation includes Babel React Compiler support. The Oxc React
|
|
341
|
+
Compiler backend is an optional peer installed explicitly; read the
|
|
342
|
+
[compatibility guide](compatibility.md) before selecting it. Keep optional native
|
|
343
|
+
platform dependencies enabled. The framework's internal Fontkit bundle includes
|
|
344
|
+
its provenance and dependency licenses under `vendor/fontkit`; applications do
|
|
345
|
+
not need a separate Fontkit dependency for `next/font`.
|
|
346
|
+
|
|
347
|
+
Production builds retain one OpenGraph renderer when needed. A bounded analysis
|
|
348
|
+
of the compiled server graph may omit it only when the application can be
|
|
349
|
+
certified not to use `ImageResponse`. Development, Edge, unknown external modules
|
|
350
|
+
and computed loading keep it. No configuration change is needed. Deploy the
|
|
351
|
+
standalone output alone when using `output: 'standalone'`; copying the complete
|
|
352
|
+
ordinary build beside it duplicates those artifacts.
|
|
353
|
+
|
|
354
|
+
Compiler caches share a **256 MiB** retention budget per project:
|
|
355
|
+
|
|
356
|
+
```js
|
|
357
|
+
export default {
|
|
358
|
+
compilationCache: {maxDiskSize: 128 * 1024 * 1024}, // bytes, 0–4 GiB
|
|
359
|
+
};
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
PRNext applies the policy after a build, including failures, and after a clean
|
|
363
|
+
development shutdown. It is a retention target, not a hard filesystem quota:
|
|
364
|
+
active development, pinned V8 workers, busy files or an incomplete bounded scan
|
|
365
|
+
can defer reclamation. Existing per-cache limits still apply. Eviction can make
|
|
366
|
+
the next build slower; evicted downloaded fonts need network access again.
|
|
367
|
+
Large JSON entries use bounded, checksummed compression; old raw records remain
|
|
368
|
+
readable, and corrupt/incompatible records are cache misses.
|
|
369
|
+
|
|
370
|
+
Inspect and preview changes without executing application configuration:
|
|
371
|
+
|
|
372
|
+
```sh
|
|
373
|
+
prnext cache --json
|
|
374
|
+
prnext cache --prune --dry-run --max-bytes 67108864 --json
|
|
375
|
+
prnext cache --prune --max-bytes 67108864
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
The CLI reads the policy saved by the last build. `--max-bytes` overrides only
|
|
379
|
+
that purge; `0` removes eligible compiler records. Statistics cover recognized
|
|
380
|
+
framework cache files, excluding unknown paths; `scanComplete: false` means a
|
|
381
|
+
lower bound and prevents purging from an incomplete snapshot. Stop development
|
|
382
|
+
before purging. Concurrent builds are protected by the publisher lock, active
|
|
383
|
+
managed workers pin their namespace, and failed deletions can be retried.
|
|
384
|
+
|
|
385
|
+
These commands never remove runtime data, `data.sqlite3`, page/image indexes,
|
|
386
|
+
invalidation generations, tags or fill leases. Never delete/reset the data
|
|
387
|
+
database to reclaim compiler storage: that can lose invalidation history. The
|
|
388
|
+
runtime instead performs small incremental SQLite reclamation steps and bounded
|
|
389
|
+
orphan-file maintenance on its own timer. Existing SQLite databases without
|
|
390
|
+
incremental auto-vacuum retain their existing format; no full VACUUM runs on a
|
|
391
|
+
request. Older page files without a verifiable reader lease are retained.
|
|
392
|
+
|
|
393
|
+
Builds and dev sessions also journal their owned temporary directories. After a
|
|
394
|
+
crash, later starts reclaim eligible entries only after a grace period and proof
|
|
395
|
+
that their local owner/workers have exited. Unknown directories, foreign-host or
|
|
396
|
+
unverifiable owners and uncommitted build backups are kept for recovery. Do not
|
|
397
|
+
remove a recovery backup until the selected build has been checked.
|
|
398
|
+
|
|
399
|
+
### Runtime observations
|
|
400
|
+
|
|
257
401
|
Production rendering, API and regeneration admission use bounded queues grouped
|
|
258
402
|
by resolved route pattern. Different parameter values share one pattern's
|
|
259
403
|
waiting budget. Waiting patterns take turns as capacity becomes available;
|
package/docs/ai/quickstart.md
CHANGED
|
@@ -13,6 +13,11 @@ react-server-dom-webpack 19.3.1**. Its Node engine range is
|
|
|
13
13
|
`^22.23.4 || ^24.22.1 || >=26.12.1`. Check the installed package manifest when
|
|
14
14
|
upgrading; these requirements may change between releases.
|
|
15
15
|
|
|
16
|
+
Optional peers are installed only for the features that use them:
|
|
17
|
+
`@redis/client` for [shared Redis caching](data.md), and `oxc-transform-react`
|
|
18
|
+
for the [experimental Oxc React Compiler](compatibility.md#react-compiler).
|
|
19
|
+
The default Babel compiler needs no additional compiler installation.
|
|
20
|
+
|
|
16
21
|
Published releases include a matching native component through optional
|
|
17
22
|
dependencies for Windows, macOS and glibc Linux, on x64 and ARM64. Keep optional
|
|
18
23
|
dependencies enabled. Consumers do not need Rust; building PRNext from its source
|