@paramour-js/next 0.4.0 → 0.4.1
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/dist/app.d.ts +48 -49
- package/dist/app.js +11 -12
- package/dist/cli-args.d.ts +4 -4
- package/dist/cli-args.js +4 -4
- package/dist/cli-inputs.d.ts +6 -7
- package/dist/cli-inputs.js +6 -7
- package/dist/cli.js +1 -1
- package/dist/collisions.d.ts +8 -8
- package/dist/collisions.js +9 -9
- package/dist/commands/generate.d.ts +7 -7
- package/dist/commands/generate.js +16 -16
- package/dist/commands/init.js +1 -1
- package/dist/config.d.ts +10 -10
- package/dist/config.js +4 -4
- package/dist/devtools-seam.d.ts +19 -19
- package/dist/devtools-seam.js +3 -3
- package/dist/doctor/checks.js +1 -1
- package/dist/emit.d.ts +12 -12
- package/dist/emit.js +13 -13
- package/dist/generate.d.ts +14 -14
- package/dist/generate.js +11 -11
- package/dist/list/discover-route-defs.d.ts +4 -4
- package/dist/list/discover-route-defs.js +4 -4
- package/dist/lock.d.ts +8 -9
- package/dist/lock.js +11 -12
- package/dist/navigation-adapter.d.ts +17 -18
- package/dist/navigation-adapter.js +4 -4
- package/dist/observe.d.ts +14 -14
- package/dist/observe.js +4 -4
- package/dist/pages.d.ts +30 -31
- package/dist/pages.js +10 -10
- package/dist/run-cli.d.ts +1 -1
- package/dist/run-cli.js +1 -1
- package/dist/scan-app.d.ts +10 -10
- package/dist/scan-app.js +30 -30
- package/dist/scan-pages.d.ts +6 -6
- package/dist/scan-pages.js +28 -26
- package/dist/scan.d.ts +13 -10
- package/dist/scan.js +7 -7
- package/dist/select.d.ts +40 -40
- package/dist/select.js +30 -30
- package/dist/testing.d.ts +28 -32
- package/dist/testing.js +15 -15
- package/dist/watch.d.ts +12 -12
- package/dist/watch.js +13 -13
- package/dist/with-typed-routes.d.ts +11 -10
- package/dist/with-typed-routes.js +42 -39
- package/package.json +2 -2
|
@@ -7,18 +7,18 @@ import { resolveRouteDirs } from "./scan.js";
|
|
|
7
7
|
import { watchRouteDirs } from "./watch.js";
|
|
8
8
|
/**
|
|
9
9
|
* Phase constants from `next/constants`, hardcoded so the package stays
|
|
10
|
-
* hermetic
|
|
11
|
-
*
|
|
10
|
+
* hermetic: the values are stable, documented public API, and importing them
|
|
11
|
+
* would make `next` a runtime dependency.
|
|
12
12
|
*/
|
|
13
13
|
const PHASE_DEVELOPMENT_SERVER = "phase-development-server";
|
|
14
14
|
const PHASE_PRODUCTION_BUILD = "phase-production-build";
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
* path. Load-bearing even for a single `next dev`:
|
|
18
|
-
*
|
|
16
|
+
* The in-process single-writer guard — a singleton keyed by route dirs +
|
|
17
|
+
* artifact path. Load-bearing even for a single `next dev`: Turbopack dev
|
|
18
|
+
* invokes the config function twice in the same process.
|
|
19
19
|
*/
|
|
20
20
|
const devWatcherTeardowns = new Map();
|
|
21
|
-
/** Messages already logged — "log once"
|
|
21
|
+
/** Messages already logged — "log once" across repeat evaluations. */
|
|
22
22
|
const warnedOnce = new Set();
|
|
23
23
|
/** @internal Test seam: the number of live dev-watcher singletons. */
|
|
24
24
|
export function devWatcherCountForTests() {
|
|
@@ -36,21 +36,22 @@ export function resetDevWatchersForTests() {
|
|
|
36
36
|
warnedOnce.clear();
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
* Wrap a Next config with route-registry generation
|
|
39
|
+
* Wrap a Next config with route-registry generation. Returns the
|
|
40
40
|
* config-function form; Next's phase argument is the mode discriminator:
|
|
41
41
|
*
|
|
42
42
|
* - production build → one generation pass before the config is returned
|
|
43
43
|
* (the build type-checks against fresh routes); drift warns loudly, or
|
|
44
44
|
* fails the build under `strict: true`.
|
|
45
45
|
* - dev server → one immediate generation pass, then the debounced watcher
|
|
46
|
-
*
|
|
46
|
+
* behind both single-writer guards (the in-process singleton and the
|
|
47
|
+
* cross-process pidfile lock).
|
|
47
48
|
* - every other phase → pass-through, no generation.
|
|
48
49
|
*
|
|
49
50
|
* Two states throw during config evaluation instead of degrading to
|
|
50
51
|
* stale-types mode, both phases alike, because Next itself has no valid
|
|
51
|
-
* build for them: an app↔pages route collision
|
|
52
|
-
* populated-ignored-dir config error (
|
|
53
|
-
*
|
|
52
|
+
* build for them: an app↔pages route collision, and discovery's
|
|
53
|
+
* populated-ignored-dir config error (Next is silently serving none of those
|
|
54
|
+
* pages).
|
|
54
55
|
*/
|
|
55
56
|
export function withTypedRoutes(config, options = {}) {
|
|
56
57
|
return async (phase, ctx) => {
|
|
@@ -58,16 +59,17 @@ export function withTypedRoutes(config, options = {}) {
|
|
|
58
59
|
if (phase !== PHASE_DEVELOPMENT_SERVER && phase !== PHASE_PRODUCTION_BUILD)
|
|
59
60
|
return resolved;
|
|
60
61
|
// The dev server and every build worker evaluate the config with the
|
|
61
|
-
// project root as cwd
|
|
62
|
-
//
|
|
62
|
+
// project root as cwd; the CLI flags are the home for anything more
|
|
63
|
+
// configurable than this.
|
|
63
64
|
const projectRoot = process.cwd();
|
|
64
65
|
const artifactPath = resolve(projectRoot, options.outFile ?? "paramour-env.d.ts");
|
|
65
66
|
const pageExtensions = resolved.pageExtensions ?? DEFAULT_PAGE_EXTENSIONS;
|
|
66
|
-
// May throw the
|
|
67
|
+
// May throw the populated-ignored-dir config error — deliberately not
|
|
68
|
+
// caught (see above).
|
|
67
69
|
const dirs = resolveRouteDirs(projectRoot, pageExtensions);
|
|
68
70
|
if (dirs.appDir === undefined && dirs.pagesDir === undefined) {
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
+
// Codegen is never load-bearing — a config wrapper must not take down
|
|
72
|
+
// `next dev`/`next build` over a missing route dir.
|
|
71
73
|
warnOnce(`paramour: no route directory (app/, pages/, src/app/, or src/pages/) under ${projectRoot}; route generation skipped`);
|
|
72
74
|
return resolved;
|
|
73
75
|
}
|
|
@@ -81,12 +83,12 @@ export function withTypedRoutes(config, options = {}) {
|
|
|
81
83
|
};
|
|
82
84
|
}
|
|
83
85
|
/**
|
|
84
|
-
* Build-phase pass
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* CI-degrades-to-world-A scenario the committed file exists to prevent
|
|
89
|
-
*
|
|
86
|
+
* Build-phase pass: regenerate, then warn loudly on drift — naming the paths
|
|
87
|
+
* that appeared/disappeared and the router they moved in — but continue;
|
|
88
|
+
* `strict` upgrades drift to a thrown error *after* the file is already
|
|
89
|
+
* corrected. A missing artifact counts as drift: that is exactly the
|
|
90
|
+
* CI-degrades-to-world-A scenario the committed file exists to prevent. A
|
|
91
|
+
* route collision is NOT incidental failure and rethrows.
|
|
90
92
|
*/
|
|
91
93
|
function generateForBuild(dirs, pageExtensions, artifactPath, strict) {
|
|
92
94
|
let result;
|
|
@@ -94,13 +96,13 @@ function generateForBuild(dirs, pageExtensions, artifactPath, strict) {
|
|
|
94
96
|
result = generate({ ...dirs, artifactPath, pageExtensions });
|
|
95
97
|
}
|
|
96
98
|
catch (error) {
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
+
// Next fails this build anyway; surfacing the collision from the config
|
|
100
|
+
// evaluation names the actual problem instead of leaving a stale
|
|
99
101
|
// artifact to confuse the type errors that follow.
|
|
100
102
|
if (error instanceof RouteCollisionError)
|
|
101
103
|
throw error;
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
+
// Again: incidental generation failure is stale types, not a broken
|
|
105
|
+
// build. Only *drift* is allowed to fail a strict build.
|
|
104
106
|
console.warn("paramour: route generation failed; building with stale route types", error);
|
|
105
107
|
return;
|
|
106
108
|
}
|
|
@@ -119,9 +121,10 @@ function generateForBuild(dirs, pageExtensions, artifactPath, strict) {
|
|
|
119
121
|
console.warn(message);
|
|
120
122
|
}
|
|
121
123
|
/**
|
|
122
|
-
* Dev-phase generation
|
|
123
|
-
* route collision, which throws from the config
|
|
124
|
-
* in the build phase
|
|
124
|
+
* Dev-phase generation: failure warns and continues (codegen is never
|
|
125
|
+
* load-bearing) — except a route collision, which throws from the config
|
|
126
|
+
* evaluation here exactly as in the build phase; only the running WATCHER
|
|
127
|
+
* treats it non-fatally.
|
|
125
128
|
*/
|
|
126
129
|
function generateSafely(dirs, pageExtensions, artifactPath) {
|
|
127
130
|
try {
|
|
@@ -134,8 +137,8 @@ function generateSafely(dirs, pageExtensions, artifactPath) {
|
|
|
134
137
|
}
|
|
135
138
|
}
|
|
136
139
|
/**
|
|
137
|
-
* Start the dev watcher behind both
|
|
138
|
-
* dev running in stale-types mode — never fatal
|
|
140
|
+
* Start the dev watcher behind both single-writer guards. Failure at any
|
|
141
|
+
* layer leaves dev running in stale-types mode — never fatal.
|
|
139
142
|
*/
|
|
140
143
|
function startDevWatcher(projectRoot, dirs, pageExtensions, artifactPath) {
|
|
141
144
|
const watchedDirs = [dirs.appDir, dirs.pagesDir].filter((dir) => dir !== undefined);
|
|
@@ -147,14 +150,14 @@ function startDevWatcher(projectRoot, dirs, pageExtensions, artifactPath) {
|
|
|
147
150
|
lock = acquireWatcherLock(watcherLockPath(projectRoot));
|
|
148
151
|
}
|
|
149
152
|
catch (error) {
|
|
150
|
-
//
|
|
151
|
-
//
|
|
153
|
+
// A corrupt lock location (e.g. a directory at the pidfile path) must
|
|
154
|
+
// not take down `next dev` — stale-types mode, like every other
|
|
152
155
|
// watcher-layer failure.
|
|
153
156
|
warnOnce("paramour: dev watcher failed; dev continues with stale route types", error);
|
|
154
157
|
return;
|
|
155
158
|
}
|
|
156
159
|
if (!lock.acquired) {
|
|
157
|
-
//
|
|
160
|
+
// Another live process owns the watcher (e.g. `paramour generate
|
|
158
161
|
// --watch` beside `next dev`). Initial generation above already ran, so
|
|
159
162
|
// dev is still correct from second zero.
|
|
160
163
|
console.warn(`paramour: watcher already running (pid ${String(lock.ownerPid)})`);
|
|
@@ -171,13 +174,13 @@ function startDevWatcher(projectRoot, dirs, pageExtensions, artifactPath) {
|
|
|
171
174
|
}
|
|
172
175
|
catch (error) {
|
|
173
176
|
if (error instanceof RouteCollisionError) {
|
|
174
|
-
//
|
|
175
|
-
// mid-move — log loudly every time (not once: it stays
|
|
176
|
-
// until fixed), keep the last good artifact, keep running
|
|
177
|
+
// The collision watch exception: a mid-watch collision is usually
|
|
178
|
+
// a file mid-move — log loudly every time (not once: it stays
|
|
179
|
+
// broken until fixed), keep the last good artifact, keep running.
|
|
177
180
|
console.warn(`paramour: ${error.message}; dev continues with the last good artifact`);
|
|
178
181
|
return;
|
|
179
182
|
}
|
|
180
|
-
throw error; // routed to onError by the watcher
|
|
183
|
+
throw error; // routed to onError by the watcher — non-fatal
|
|
181
184
|
}
|
|
182
185
|
},
|
|
183
186
|
});
|
|
@@ -188,7 +191,7 @@ function startDevWatcher(projectRoot, dirs, pageExtensions, artifactPath) {
|
|
|
188
191
|
lock.release?.();
|
|
189
192
|
});
|
|
190
193
|
}
|
|
191
|
-
/**
|
|
194
|
+
/** "Log once": repeat evaluations/events don't spam the dev console. */
|
|
192
195
|
function warnOnce(message, detail) {
|
|
193
196
|
if (warnedOnce.has(message))
|
|
194
197
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paramour-js/next",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"jiti": "^2.7.0",
|
|
35
35
|
"magicast": "^0.3.5",
|
|
36
36
|
"tinyglobby": "^0.2.15",
|
|
37
|
-
"paramour": "0.
|
|
37
|
+
"paramour": "0.6.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"next": ">=15",
|