@thomas.f/prnext 0.1.17-alpha → 0.1.19-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 +27 -868
- package/build/actions.mjs +27 -15
- 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 +122 -46
- 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 +34 -10
- package/build/config.mjs +34 -3
- 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-assets.mjs +173 -0
- package/build/dev-css-update.mjs +18 -14
- package/build/dev-dependencies.mjs +1 -1
- package/build/dev-discovery.mjs +3 -3
- package/build/dev-lazy-build.mjs +77 -0
- package/build/dev.mjs +15 -8
- package/build/dynamic.mjs +14 -7
- 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/incremental.mjs +112 -18
- package/build/index.mjs +90 -28
- package/build/instrumentation.mjs +30 -0
- package/build/lazy-dynamic-imports.mjs +137 -0
- package/build/metadata-routes.mjs +1 -1
- package/build/migrate.mjs +4 -4
- package/build/migration-audit.mjs +19 -31
- package/build/migration-imports.mjs +245 -0
- package/build/migration-scenarios-runner.mjs +73 -0
- package/build/migration-scenarios.mjs +72 -0
- package/build/native-discovery.mjs +65 -5
- package/build/native-packages.mjs +2 -0
- package/build/native-type-config.mjs +37 -0
- package/build/npm-packages.mjs +1 -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 +59 -10
- package/build/react-compiler-report.mjs +225 -0
- package/build/react-compiler.mjs +139 -0
- package/build/runtime-contract.mjs +2 -2
- package/build/standalone.mjs +21 -3
- 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 +19 -6
- package/build/worker-memory.mjs +9 -0
- package/cli.mjs +70 -5
- package/compat/activity-cache.cjs +26 -0
- package/compat/after.cjs +6 -4
- package/compat/app-dynamic.cjs +12 -1
- package/compat/app-layout-context.cjs +52 -2
- package/compat/base64.cjs +10 -0
- package/compat/cache-handlers.cjs +15 -3
- 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 +152 -0
- package/compat/headers.cjs +4 -2
- package/compat/incremental-cache.cjs +20 -7
- package/compat/index.d.ts +69 -4
- package/compat/link.cjs +13 -10
- 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 +248 -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 +93 -0
- package/docs/ai/troubleshooting.md +116 -2
- package/package.json +40 -9
- package/runtime/action-client.mjs +10 -4
- package/runtime/action-server.mjs +2 -0
- package/runtime/app-client.mjs +316 -92
- 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/atomic-file.mjs +27 -0
- package/runtime/cache-components-rsc.mjs +7 -2
- package/runtime/cache-request.mjs +2 -1
- package/runtime/deployment-client.mjs +19 -0
- package/runtime/dev-client.mjs +13 -3
- package/runtime/dev-compiler-broker.mjs +42 -0
- package/runtime/dev-file-changes.mjs +123 -8
- package/runtime/dev-indicator.mjs +8 -3
- package/runtime/dev-lazy-imports.mjs +121 -0
- package/runtime/dev-lazy-staging.mjs +14 -0
- package/runtime/dev-lazy-tool.mjs +16 -0
- package/runtime/dev-style-retention.mjs +15 -0
- package/runtime/development.mjs +83 -25
- package/runtime/document.mjs +1 -1
- package/runtime/edge.mjs +6 -5
- package/runtime/fetch-cache.mjs +10 -8
- package/runtime/flight-delta.mjs +74 -0
- package/runtime/flight-tap.mjs +28 -0
- package/runtime/fs.mjs +15 -8
- 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/lazy-import-client.mjs +38 -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/vendor/nft/LICENSE +7 -0
- package/vendor/nft/README.md +16 -0
- package/vendor/nft/out/analyze.d.ts +8 -0
- package/vendor/nft/out/analyze.js +1216 -0
- package/vendor/nft/out/analyze.js.map +1 -0
- package/vendor/nft/out/cli.d.ts +2 -0
- package/vendor/nft/out/cli.js +94 -0
- package/vendor/nft/out/cli.js.map +1 -0
- package/vendor/nft/out/fs.d.ts +22 -0
- package/vendor/nft/out/fs.js +106 -0
- package/vendor/nft/out/fs.js.map +1 -0
- package/vendor/nft/out/index.d.ts +4 -0
- package/vendor/nft/out/index.js +25 -0
- package/vendor/nft/out/index.js.map +1 -0
- package/vendor/nft/out/node-file-trace.d.ts +41 -0
- package/vendor/nft/out/node-file-trace.js +380 -0
- package/vendor/nft/out/node-file-trace.js.map +1 -0
- package/vendor/nft/out/resolve-dependency.d.ts +6 -0
- package/vendor/nft/out/resolve-dependency.js +427 -0
- package/vendor/nft/out/resolve-dependency.js.map +1 -0
- package/vendor/nft/out/types.d.ts +66 -0
- package/vendor/nft/out/types.js +2 -0
- package/vendor/nft/out/types.js.map +1 -0
- package/vendor/nft/out/utils/ast-helpers.js +49 -0
- package/vendor/nft/out/utils/ast-helpers.js.map +1 -0
- package/vendor/nft/out/utils/binary-locators.js +88 -0
- package/vendor/nft/out/utils/binary-locators.js.map +1 -0
- package/vendor/nft/out/utils/get-package-base.js +30 -0
- package/vendor/nft/out/utils/get-package-base.js.map +1 -0
- package/vendor/nft/out/utils/interop-require.js +24 -0
- package/vendor/nft/out/utils/interop-require.js.map +1 -0
- package/vendor/nft/out/utils/node-version.js +10 -0
- package/vendor/nft/out/utils/node-version.js.map +1 -0
- package/vendor/nft/out/utils/sharedlib-emit.js +33 -0
- package/vendor/nft/out/utils/sharedlib-emit.js.map +1 -0
- package/vendor/nft/out/utils/special-cases.js +347 -0
- package/vendor/nft/out/utils/special-cases.js.map +1 -0
- package/vendor/nft/out/utils/static-eval.js +579 -0
- package/vendor/nft/out/utils/static-eval.js.map +1 -0
- package/vendor/nft/out/utils/types.js +2 -0
- package/vendor/nft/out/utils/types.js.map +1 -0
- package/vendor/nft/out/utils/wrappers.js +659 -0
- package/vendor/nft/out/utils/wrappers.js.map +1 -0
- package/vendor/nft/package.json +4 -0
- package/vendor/nft/upstream.json +51 -0
package/docs/ai/routing.md
CHANGED
|
@@ -20,6 +20,14 @@ segments and `pages/api/`. Existing `getServerSideProps`, `getStaticProps` and
|
|
|
20
20
|
belong in an App Router page. Check a specific advanced routing feature against
|
|
21
21
|
the installed implementation rather than assuming complete Next.js parity.
|
|
22
22
|
|
|
23
|
+
App styles follow the page and its layout scopes instead of loading every
|
|
24
|
+
page's stylesheet globally. Shared layout sheets are reused, and navigation
|
|
25
|
+
loads the next page's sheets before committing its content. Keep shared global
|
|
26
|
+
rules in the common layout and use CSS Modules for component-specific selectors.
|
|
27
|
+
Do not rely on a sibling page's CSS being present. Loading/error/default and
|
|
28
|
+
parallel-route branches can share a route's style plan; test their cascade as
|
|
29
|
+
well as ordinary forward and back navigation in a production build.
|
|
30
|
+
|
|
23
31
|
## Dynamic segments
|
|
24
32
|
|
|
25
33
|
`app/products/[slug]/page.tsx` matches `/products/example`. App `params` and
|
|
@@ -80,6 +88,9 @@ Client Components can participate in server rendering. Read `window`,
|
|
|
80
88
|
`useEffect`, not unconditionally during render. Server and first browser render
|
|
81
89
|
must agree. Use `.ts` or `.tsx` for `'use client'` and `'use server'` boundaries;
|
|
82
90
|
PRNext rejects those directives in `.mts`/`.cts` instead of silently misbundling.
|
|
91
|
+
The migration audit reports these unsupported boundaries too. It also checks
|
|
92
|
+
`server-only` and `client-only` markers through imported helpers, respecting
|
|
93
|
+
module-level Server Action boundaries and Node Route Handlers.
|
|
83
94
|
|
|
84
95
|
## Navigation and typed routes
|
|
85
96
|
|
|
@@ -94,6 +105,55 @@ Client Component. Pages `useRouter` comes from `next/router`; they are different
|
|
|
94
105
|
contracts. Server code can call `redirect()` or `notFound()` from
|
|
95
106
|
`next/navigation`; let their control-flow exceptions reach the framework.
|
|
96
107
|
|
|
108
|
+
Production link prefetching prioritizes keyboard focus, hover and touch over
|
|
109
|
+
links entering the viewport. Both routers bound speculative work; an actual
|
|
110
|
+
navigation takes priority. Data saver, offline/2G connections and hidden tabs
|
|
111
|
+
disable speculation, while slower connections restrict it to intent. Browsers
|
|
112
|
+
without connection information retain bounded prefetching. `prefetch={false}`
|
|
113
|
+
disables Link speculation, including hover and focus. None of these policies
|
|
114
|
+
blocks a real click or changes authorization and private-data checks. App Link
|
|
115
|
+
automatic prefetching retains its existing partial-rendering requirement.
|
|
116
|
+
Set `prefetch={true}` to warm the full destination explicitly in an ordinary
|
|
117
|
+
App Router application without `cacheComponents`. The same network limits
|
|
118
|
+
apply, and development does not prefetch. Full prefetch warms modules and data;
|
|
119
|
+
the click still sends a fresh server request before showing the destination.
|
|
120
|
+
This includes prerendered pages whose access is controlled by a proxy: a
|
|
121
|
+
prefetched response cannot authorize a later navigation after an HttpOnly
|
|
122
|
+
cookie changes. Leave the prop unset to keep automatic behavior, or use `false`
|
|
123
|
+
to disable speculation.
|
|
124
|
+
|
|
125
|
+
### Connection loss during App navigation
|
|
126
|
+
|
|
127
|
+
App navigation retries transport failures of its GET request within a 30-second
|
|
128
|
+
budget and at most three attempts. While disconnected, the current page and its
|
|
129
|
+
mounted state remain visible. A newer navigation cancels the older attempt.
|
|
130
|
+
Reconnection issues a fresh request with the current cookies; it does not serve
|
|
131
|
+
a saved private response. Application errors and deployment mismatches retain
|
|
132
|
+
their existing handling. Speculative prefetches are not queued offline.
|
|
133
|
+
|
|
134
|
+
For an optional application-owned connection indicator:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
'use client';
|
|
138
|
+
import { useOffline } from '@thomas.f/prnext/offline';
|
|
139
|
+
|
|
140
|
+
export default function ConnectionStatus() {
|
|
141
|
+
const offline = useOffline();
|
|
142
|
+
return offline ? <p role="status">Waiting for a connection…</p> : null;
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The hook reports browser offline status and pending navigation recovery, not a
|
|
147
|
+
guarantee that a server is reachable. Exhausted network recovery preserves the
|
|
148
|
+
page and dispatches `prnext:navigation-error` on `window`, with `detail.message`
|
|
149
|
+
for an application-owned retry notice. This recovery applies to App navigation;
|
|
150
|
+
it does not add offline Pages routing, a service worker or persistent storage.
|
|
151
|
+
|
|
152
|
+
Server Actions and other POSTs are **never automatically replayed**. If a mutation
|
|
153
|
+
loses its response, it may already have run: keep the user's input and verify its
|
|
154
|
+
result before offering an explicit retry. A full reload still loses ordinary
|
|
155
|
+
in-memory state; persist drafts deliberately if they must survive reloads.
|
|
156
|
+
|
|
97
157
|
With `typedRoutes: true`, `prnext typegen` writes a discovered route registry.
|
|
98
158
|
For the dynamic page above, this materializes an encoded URL:
|
|
99
159
|
|
|
@@ -112,6 +172,39 @@ parameters, separators and dot segments. Add query strings through
|
|
|
112
172
|
Generated route checking is PRNext's registry, not the Next.js language-service
|
|
113
173
|
plugin.
|
|
114
174
|
|
|
175
|
+
## Retained App pages
|
|
176
|
+
|
|
177
|
+
App layout branches retain inactive UI through React Activity. Effects stop
|
|
178
|
+
while hidden, and returning to an authorized destination restores its mounted
|
|
179
|
+
form state. The shared default budget is four inactive branches for two minutes,
|
|
180
|
+
not four at every nesting level. It is an entry/time limit, not a byte-level RAM
|
|
181
|
+
guarantee. It applies within a mounted layout; a new root layout loads a document.
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
export default {
|
|
185
|
+
navigationCache: { maxEntries: 3, ttlMs: 60000, authCookies: ['session'] },
|
|
186
|
+
};
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Use `navigationCache: false` to disable retention. Server Actions, `router.refresh()`
|
|
190
|
+
and observed cookie/authorization changes discard inactive branches while keeping
|
|
191
|
+
the current page's client state. Back/forward navigation requests fresh Flight
|
|
192
|
+
before revealing a retained destination. Cache hits do not bypass authorization.
|
|
193
|
+
After a custom authentication request outside Server Actions, call
|
|
194
|
+
`router.refresh()`. A browser integration may also dispatch
|
|
195
|
+
`window.dispatchEvent(new Event('prnext:invalidate-navigation'))` to refresh and
|
|
196
|
+
clear retained/prefetched state. This is in-memory UI retention, not offline
|
|
197
|
+
storage or mutation replay.
|
|
198
|
+
|
|
199
|
+
By default, cookie changes invalidate inactive branches while ordinary refresh
|
|
200
|
+
keeps the active component state. Set `authCookies` to the application's actual
|
|
201
|
+
session cookie names to also reset active branches when those credentials change.
|
|
202
|
+
Unrelated preference cookies then do not affect retention. Authorization headers
|
|
203
|
+
remain part of the identity. Identity is checked in each branch's authorized
|
|
204
|
+
request context, including restored parallel slots. In development, the private
|
|
205
|
+
identity key remains stable across Fast Refresh; build-time action-key rotation
|
|
206
|
+
does not discard the active editor state.
|
|
207
|
+
|
|
115
208
|
## Route Handlers
|
|
116
209
|
|
|
117
210
|
An App Route Handler exports HTTP methods and returns a Web `Response` or
|
|
@@ -2,6 +2,70 @@
|
|
|
2
2
|
|
|
3
3
|
[AI documentation index](../../AI.md)
|
|
4
4
|
|
|
5
|
+
## Compile large client imports only when used in development
|
|
6
|
+
|
|
7
|
+
For App Router applications, the explicit experimental option below keeps
|
|
8
|
+
literal client `import()` targets outside the initial browser graph. It defers
|
|
9
|
+
their transformation and compilation, rather than only downloading an already
|
|
10
|
+
compiled chunk later.
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
// prnext.config.mjs
|
|
14
|
+
export default {
|
|
15
|
+
experimental: { lazyDynamicImports: true }
|
|
16
|
+
};
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The option affects `prnext dev` only. Production keeps its ordinary dynamic
|
|
20
|
+
chunks and does not use a development compilation endpoint. SSR also keeps its
|
|
21
|
+
normal behavior. A `next/dynamic` component with `{ ssr: false }` is a useful
|
|
22
|
+
candidate for an editor or other large browser-only feature; an import needed
|
|
23
|
+
by SSR still needs its server compilation.
|
|
24
|
+
|
|
25
|
+
On first use, the development server compiles the requested subgraph, publishes
|
|
26
|
+
its immutable assets, and loads its CSS before resolving the import. Already
|
|
27
|
+
loaded ESM dependencies are reused through their original module URLs, keeping
|
|
28
|
+
shared objects and live bindings. Once activated, the module participates in
|
|
29
|
+
subsequent JavaScript and stylesheet updates. A failed compilation can be
|
|
30
|
+
requested again after correcting its source.
|
|
31
|
+
|
|
32
|
+
Activated styles remain loaded for the generation, including when parallel
|
|
33
|
+
slots select their own styles. Prefer CSS Modules or selectors scoped to the
|
|
34
|
+
deferred feature when its global styles should not affect other components.
|
|
35
|
+
|
|
36
|
+
The initial scope is App Router applications using the native compiler, with
|
|
37
|
+
same-origin assets and no webpack hook or custom loaders. Literal imports from
|
|
38
|
+
project `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts` and `.tsx` sources are eligible;
|
|
39
|
+
computed imports, import attributes, literal requests containing `?` or `#`,
|
|
40
|
+
imports inside installed packages and typed `.mts`/`.cts` helpers keep the
|
|
41
|
+
ordinary compiler behavior. The compiler keeps the distinct module identities
|
|
42
|
+
of those literal query and fragment imports. If an alias or a transitive
|
|
43
|
+
dependency introduces a resolved query or fragment suffix inside a deferred
|
|
44
|
+
graph, activation returns an explicit error
|
|
45
|
+
before reusing any shared export bridge. Disable the option for that graph;
|
|
46
|
+
query and fragment identities in deferred graphs are not currently supported.
|
|
47
|
+
The compiler does not silently duplicate a shared CommonJS dependency: that
|
|
48
|
+
case returns an explicit error. Convert that shared dependency to ESM or disable
|
|
49
|
+
the option.
|
|
50
|
+
Server Actions first introduced only by a deferred graph also require a static
|
|
51
|
+
import or the ordinary compiler, because the running server implementation
|
|
52
|
+
cannot be extended by publishing browser assets alone.
|
|
53
|
+
|
|
54
|
+
There are at most 128 registered imports and 4,096 static JavaScript dependency
|
|
55
|
+
identities per generation. Deferred assets have a cumulative 128 MiB budget per
|
|
56
|
+
active generation. Existing development request and generation limits still
|
|
57
|
+
apply. Public requests contain opaque registered IDs, never source filenames;
|
|
58
|
+
an unknown ID cannot initiate a deferred compilation. Static ESM export bridges
|
|
59
|
+
have their own startup cost, so measure your application's initial build and
|
|
60
|
+
first-use delay before keeping the option enabled.
|
|
61
|
+
|
|
62
|
+
Deferred JSON imports share their native ESM namespace and default object across
|
|
63
|
+
importers. Deferred assets are written outside the served directory and published
|
|
64
|
+
as complete immutable files. This experimental path requires hardlinks within
|
|
65
|
+
the development generation's filesystem; disable `lazyDynamicImports` if that
|
|
66
|
+
filesystem cannot create them. A failed activation keeps existing assets intact
|
|
67
|
+
and conservatively accounts for any publication whose outcome is uncertain.
|
|
68
|
+
|
|
5
69
|
## Collect a useful failure
|
|
6
70
|
|
|
7
71
|
Read the installed version, command, working directory, Node version, manager,
|
|
@@ -54,11 +118,33 @@ repair. Verify the interactive result after the change.
|
|
|
54
118
|
|
|
55
119
|
## HMR and cache failures
|
|
56
120
|
|
|
121
|
+
When an Action overlaps a refresh or navigation, its mutation result remains
|
|
122
|
+
independent from whether its older render is applied. A newer interaction can
|
|
123
|
+
release a superseded development commit wait; it never replays the mutation.
|
|
124
|
+
|
|
125
|
+
For a development state publication failure, keep the private
|
|
126
|
+
`.prnext-dev/<session>/diagnostics/state-publication.json` receipt. It records the
|
|
127
|
+
operation phase, error code, bounded rename attempts and last published sequence,
|
|
128
|
+
without source contents or a full source path. Windows transient rename failures
|
|
129
|
+
are retried for up to two seconds; a permanent failure preserves the previous
|
|
130
|
+
complete state file. After a replacement runtime has activated, publication
|
|
131
|
+
failure still retires obsolete runtimes through the gateway and keeps the
|
|
132
|
+
existing three-generation snapshot bound. In-flight requests drain before
|
|
133
|
+
their old runtime closes. Record the actual code and phase instead of assuming
|
|
134
|
+
an antivirus or file watcher caused the lock.
|
|
135
|
+
|
|
57
136
|
Development compiles requested routes and preserves state for compatible edits;
|
|
58
137
|
config/environment, custom Document or incompatible module changes can reload
|
|
59
138
|
the document. Production prerendering and compression are not development HMR.
|
|
60
139
|
An unused route need not rebuild until requested.
|
|
61
140
|
|
|
141
|
+
Middleware and rewrites can select a cold destination after routing. PRNext
|
|
142
|
+
compiles that destination through its private development compiler and continues
|
|
143
|
+
the same request. It does not send an upload or action through middleware again.
|
|
144
|
+
Retained parallel branches are compiled together when their source is needed.
|
|
145
|
+
An error in an unrelated unopened route should not force that route into the
|
|
146
|
+
active graph. Safe mode remains available for full-graph comparisons.
|
|
147
|
+
|
|
62
148
|
For a controlled diagnosis, stop only the development process you own and try:
|
|
63
149
|
|
|
64
150
|
```sh
|
|
@@ -66,12 +152,26 @@ prnext dev --safe
|
|
|
66
152
|
```
|
|
67
153
|
|
|
68
154
|
Safe mode uses full builds and fresh workers. `PRNEXT_BUILD_CACHE=0` disables
|
|
69
|
-
PRNext's compiler/build caches when set in the current process environment; use
|
|
155
|
+
PRNext's persistent compiler/build caches when set in the current process environment; use
|
|
70
156
|
the syntax appropriate to the user's shell and restore the previous setting
|
|
71
|
-
after the comparison.
|
|
157
|
+
after the comparison. In-memory compiler/transform reuse is a separate layer.
|
|
158
|
+
Optional cache-storage failures should fall back to work,
|
|
72
159
|
while genuine loader errors remain build failures. Do not delete every cache or
|
|
73
160
|
lockfile as a first response, especially with another server running.
|
|
74
161
|
|
|
162
|
+
Production builds can reuse eligible compiled JavaScript graphs and CSS Module
|
|
163
|
+
outputs from the default CSS engine across processes through the private
|
|
164
|
+
`.prnext-cache` directory. The successful artifact's `compilation-cache-report.json` and the
|
|
165
|
+
programmatic build result's `compilationCache` report actual hits, misses and
|
|
166
|
+
bypasses. These are compilation diagnostics, not response-cache or latency
|
|
167
|
+
measurements. App graphs that discover actions or client boundaries, development
|
|
168
|
+
graphs, the explicit PostCSS engine and custom loader/PostCSS pipelines still
|
|
169
|
+
execute their compiler work.
|
|
170
|
+
HTML, Flight responses and private rendered data are not stored in this cache.
|
|
171
|
+
Changes to tracked dependencies, resolution candidates, options, environment
|
|
172
|
+
or framework identity invalidate eligible entries. Corrupt or unavailable cache
|
|
173
|
+
records fall back to compilation; `PRNEXT_BUILD_CACHE=0` disables their persistent reuse.
|
|
174
|
+
|
|
75
175
|
For production observations:
|
|
76
176
|
|
|
77
177
|
```sh
|
|
@@ -85,6 +185,20 @@ exclude the full streaming body, and missing/dropped samples are not zero.
|
|
|
85
185
|
`prnext analyze`, after building, rather than interpreting request time as
|
|
86
186
|
compiler performance.
|
|
87
187
|
|
|
188
|
+
Initial-JS analysis includes required hydration imports and SSR-used dynamic
|
|
189
|
+
chunks. Schema 2 reports per-prerendered-path samples and the maximum size for
|
|
190
|
+
each compression metric; a route's file list can be the union of its samples.
|
|
191
|
+
Request-dependent or incomplete graphs are lower bounds. Their size budgets
|
|
192
|
+
fail as `initial-unknown`, even if that lower bound is small. Do not present it
|
|
193
|
+
as a complete measurement or a size saving. Rebuild old schema-1 baselines before
|
|
194
|
+
comparing them with schema 2. An opaque webpack graph is also marked incomplete.
|
|
195
|
+
|
|
196
|
+
For memoization questions, run `prnext compiler --json` after a successful build
|
|
197
|
+
with `reactCompiler` enabled. Inspect the affected function and its skip reason,
|
|
198
|
+
the reported graph coverage and cached-transform counts. An absent function in
|
|
199
|
+
an observed-transforms report is not proof that it was optimized or rejected.
|
|
200
|
+
Keep application behavior and hydration checks alongside this diagnostic.
|
|
201
|
+
|
|
88
202
|
## Connect the existing development MCP
|
|
89
203
|
|
|
90
204
|
Start `prnext dev` in the application, then configure a compatible assistant to
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thomas.f/prnext",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19-alpha",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Experimental Rust-powered runtime for Next.js apps, React and npm",
|
|
6
6
|
"homepage": "https://prnext.dev",
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
"runtime/",
|
|
42
42
|
"compat/",
|
|
43
43
|
"native/",
|
|
44
|
-
"release/"
|
|
44
|
+
"release/",
|
|
45
|
+
"vendor/"
|
|
45
46
|
],
|
|
46
47
|
"scripts": {
|
|
47
48
|
"prepublishOnly": "node release/verify.mjs"
|
|
@@ -115,6 +116,14 @@
|
|
|
115
116
|
"./headers": "./compat/headers.cjs",
|
|
116
117
|
"./server": "./compat/server.cjs",
|
|
117
118
|
"./cache": "./compat/cache.cjs",
|
|
119
|
+
"./cache/redis": {
|
|
120
|
+
"types": "./compat/redis-cache.d.cts",
|
|
121
|
+
"default": "./compat/redis-cache.cjs"
|
|
122
|
+
},
|
|
123
|
+
"./offline": {
|
|
124
|
+
"types": "./compat/offline.d.cts",
|
|
125
|
+
"default": "./compat/offline.cjs"
|
|
126
|
+
},
|
|
118
127
|
"./constants": "./compat/constants.cjs"
|
|
119
128
|
},
|
|
120
129
|
"dependencies": {
|
|
@@ -124,38 +133,60 @@
|
|
|
124
133
|
"@babel/traverse": "^7.29.0",
|
|
125
134
|
"@babel/types": "^7.29.0",
|
|
126
135
|
"@edge-runtime/vm": "5.0.0",
|
|
127
|
-
"@
|
|
136
|
+
"@jridgewell/trace-mapping": "0.3.31",
|
|
137
|
+
"@mapbox/node-pre-gyp": "2.0.3",
|
|
138
|
+
"@rollup/pluginutils": "5.4.0",
|
|
139
|
+
"acorn": "8.18.0",
|
|
140
|
+
"acorn-import-attributes": "1.9.5",
|
|
141
|
+
"async-sema": "3.1.1",
|
|
142
|
+
"babel-plugin-react-compiler": "1.0.0",
|
|
143
|
+
"bindings": "1.5.0",
|
|
128
144
|
"browserslist": "4.29.0",
|
|
129
145
|
"dotenv": "16.6.1",
|
|
130
146
|
"dotenv-expand": "11.0.7",
|
|
131
147
|
"esbuild": "^0.28.2",
|
|
148
|
+
"estree-walker": "2.0.2",
|
|
132
149
|
"fontkit": "2.0.4",
|
|
150
|
+
"get-tsconfig": "4.14.3",
|
|
151
|
+
"glob": "14.0.2",
|
|
152
|
+
"graceful-fs": "4.2.11",
|
|
133
153
|
"html-to-image": "1.11.13",
|
|
154
|
+
"jsonc-parser": "3.3.1",
|
|
134
155
|
"lightningcss": "1.31.0",
|
|
135
156
|
"loader-runner": "4.3.2",
|
|
157
|
+
"minimatch": "11.0.1",
|
|
158
|
+
"node-gyp-build": "4.8.4",
|
|
136
159
|
"oxc-parser": "0.155.0",
|
|
137
160
|
"path-to-regexp": "6.3.0",
|
|
138
161
|
"picomatch": "4.0.7",
|
|
139
162
|
"postcss": "8.5.28",
|
|
140
163
|
"postcss-flexbugs-fixes": "5.0.2",
|
|
141
164
|
"postcss-preset-env": "11.5.3",
|
|
165
|
+
"postcss-selector-parser": "7.1.6",
|
|
142
166
|
"postcss-value-parser": "4.2.0",
|
|
143
167
|
"react-refresh": "0.19.0",
|
|
168
|
+
"resolve-from": "5.0.0",
|
|
144
169
|
"schema-utils": "4.3.3",
|
|
145
170
|
"webpack": "5.111.1"
|
|
146
171
|
},
|
|
147
172
|
"peerDependencies": {
|
|
173
|
+
"@redis/client": "^6.3.0",
|
|
148
174
|
"react": "19.3.1",
|
|
149
175
|
"react-dom": "19.3.1",
|
|
150
176
|
"react-server-dom-webpack": "19.3.1"
|
|
151
177
|
},
|
|
178
|
+
"peerDependenciesMeta": {
|
|
179
|
+
"@redis/client": {
|
|
180
|
+
"optional": true
|
|
181
|
+
}
|
|
182
|
+
},
|
|
152
183
|
"optionalDependencies": {
|
|
153
|
-
"
|
|
154
|
-
"
|
|
155
|
-
"prnext-
|
|
156
|
-
"prnext-
|
|
157
|
-
"prnext-
|
|
158
|
-
"prnext-
|
|
184
|
+
"prnext-darwin-arm64": "0.1.19-alpha",
|
|
185
|
+
"prnext-darwin-x64": "0.1.19-alpha",
|
|
186
|
+
"prnext-linux-arm64-gnu": "0.1.19-alpha",
|
|
187
|
+
"prnext-linux-x64-gnu": "0.1.19-alpha",
|
|
188
|
+
"@thomas.f/prnext-win32-x64-msvc": "0.1.19-alpha",
|
|
189
|
+
"@thomas.f/prnext-win32-arm64-msvc": "0.1.19-alpha"
|
|
159
190
|
},
|
|
160
191
|
"engines": {
|
|
161
192
|
"node": "^22.23.4 || ^24.22.1 || >=26.12.1"
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// A newly opened route can move this helper into a different development ESM
|
|
2
|
+
// chunk. Its action proxies still belong to the already mounted application.
|
|
3
|
+
// Production keeps the ordinary per-graph module state.
|
|
4
|
+
const state = process.env.NODE_ENV === 'development'
|
|
5
|
+
? globalThis[Symbol.for('prnext.development.server-actions')] ||= {}
|
|
6
|
+
: {};
|
|
3
7
|
|
|
4
8
|
// App bootstrap installs the official Flight client after its module loader is
|
|
5
9
|
// ready. Action proxy modules load through that same client graph afterwards.
|
|
6
10
|
export function configureServerActions({ createServerReference, callServer }) {
|
|
7
|
-
referenceFactory = createServerReference;
|
|
8
|
-
transport = callServer;
|
|
11
|
+
state.referenceFactory = createServerReference;
|
|
12
|
+
state.transport = callServer;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
export function callServer(id, args) {
|
|
16
|
+
const transport = state.transport;
|
|
12
17
|
if (!transport) return Promise.reject(new Error('The PRNext Server Action transport is not initialized'));
|
|
13
18
|
return transport(id, args);
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
export function createServerReference(id) {
|
|
22
|
+
const referenceFactory = state.referenceFactory;
|
|
17
23
|
if (!referenceFactory) throw new Error('Server Action references must load after the PRNext Flight client');
|
|
18
24
|
return referenceFactory(id, callServer);
|
|
19
25
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {reportRequestError} from './instrumentation.mjs';
|
|
1
2
|
import { decodeReply, decodeAction, decodeFormState, createTemporaryReferenceSet } from 'react-server-dom-webpack/server.node';
|
|
2
3
|
import { pathToFileURL } from 'node:url';
|
|
3
4
|
import path from 'node:path';
|
|
@@ -126,6 +127,7 @@ export async function invokeAction(request) {
|
|
|
126
127
|
} else if (navigation?.status === 404) {
|
|
127
128
|
actionNotFound = true;
|
|
128
129
|
} else {
|
|
130
|
+
reportRequestError(error,{routeType:'action'});
|
|
129
131
|
console.error('[prnext]', error?.stack || error);
|
|
130
132
|
actionError = errorPayload(error, request.production);
|
|
131
133
|
failure = { message: error?.message || String(error), stack: error?.stack, digest: error?.digest };
|