@nifrajs/web 2.14.1 → 3.2.0
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/boundary.d.ts +158 -0
- package/dist/boundary.d.ts.map +1 -0
- package/dist/boundary.js +237 -0
- package/dist/boundary.js.map +1 -0
- package/dist/build-plan.d.ts +228 -0
- package/dist/build-plan.d.ts.map +1 -0
- package/dist/build-plan.js +514 -0
- package/dist/build-plan.js.map +1 -0
- package/dist/build-vite.d.ts +2 -1
- package/dist/build-vite.d.ts.map +1 -1
- package/dist/build-vite.js +5 -3
- package/dist/build-vite.js.map +1 -1
- package/dist/build.d.ts +2 -197
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +92 -515
- package/dist/build.js.map +1 -1
- package/dist/chunk-names.d.ts.map +1 -1
- package/dist/chunk-names.js +3 -2
- package/dist/chunk-names.js.map +1 -1
- package/dist/dev-ssr-graph.d.ts.map +1 -1
- package/dist/dev-ssr-graph.js +63 -28
- package/dist/dev-ssr-graph.js.map +1 -1
- package/dist/diagnostic.d.ts.map +1 -1
- package/dist/diagnostic.js +9 -2
- package/dist/diagnostic.js.map +1 -1
- package/dist/fonts-google.d.ts.map +1 -1
- package/dist/fonts-google.js +3 -1
- package/dist/fonts-google.js.map +1 -1
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +2 -1
- package/dist/fs.js.map +1 -1
- package/dist/index.d.ts +16 -589
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -1824
- package/dist/index.js.map +1 -1
- package/dist/internal/codegen.d.ts +68 -0
- package/dist/internal/codegen.d.ts.map +1 -0
- package/dist/internal/codegen.js +317 -0
- package/dist/internal/codegen.js.map +1 -0
- package/dist/internal/fetcher-runtime.d.ts +19 -0
- package/dist/internal/fetcher-runtime.d.ts.map +1 -0
- package/dist/internal/fetcher-runtime.js +26 -0
- package/dist/internal/fetcher-runtime.js.map +1 -0
- package/dist/internal/head-merge.d.ts +2 -0
- package/dist/internal/head-merge.d.ts.map +1 -1
- package/dist/internal/head-merge.js +17 -1
- package/dist/internal/head-merge.js.map +1 -1
- package/dist/internal/identity-policy.d.ts +51 -0
- package/dist/internal/identity-policy.d.ts.map +1 -0
- package/dist/internal/identity-policy.js +67 -0
- package/dist/internal/identity-policy.js.map +1 -0
- package/dist/internal/parity.d.ts +104 -8
- package/dist/internal/parity.d.ts.map +1 -1
- package/dist/internal/parity.js +472 -56
- package/dist/internal/parity.js.map +1 -1
- package/dist/internal/query-runtime.d.ts +8 -0
- package/dist/internal/query-runtime.d.ts.map +1 -0
- package/dist/internal/query-runtime.js +29 -0
- package/dist/internal/query-runtime.js.map +1 -0
- package/dist/internal/render-document.d.ts +372 -0
- package/dist/internal/render-document.d.ts.map +1 -0
- package/dist/internal/render-document.js +744 -0
- package/dist/internal/render-document.js.map +1 -0
- package/dist/internal/runtime-contract.d.ts +48 -0
- package/dist/internal/runtime-contract.d.ts.map +1 -0
- package/dist/internal/runtime-contract.js +27 -0
- package/dist/internal/runtime-contract.js.map +1 -0
- package/dist/internal/web-app.d.ts +171 -0
- package/dist/internal/web-app.d.ts.map +1 -0
- package/dist/internal/web-app.js +844 -0
- package/dist/internal/web-app.js.map +1 -0
- package/dist/islands.d.ts +50 -2
- package/dist/islands.d.ts.map +1 -1
- package/dist/islands.js +96 -36
- package/dist/islands.js.map +1 -1
- package/dist/manifest.d.ts +41 -6
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js.map +1 -1
- package/dist/module-graph.d.ts.map +1 -1
- package/dist/module-graph.js +22 -9
- package/dist/module-graph.js.map +1 -1
- package/dist/nano.d.ts +125 -0
- package/dist/nano.d.ts.map +1 -0
- package/dist/nano.js +190 -0
- package/dist/nano.js.map +1 -0
- package/dist/plugins/css-modules.js +2 -2
- package/dist/plugins/css-modules.js.map +1 -1
- package/dist/plugins/kit.d.ts +12 -0
- package/dist/plugins/kit.d.ts.map +1 -1
- package/dist/plugins/kit.js +62 -12
- package/dist/plugins/kit.js.map +1 -1
- package/dist/plugins/postcss.js +2 -2
- package/dist/plugins/postcss.js.map +1 -1
- package/dist/plugins/scss.js +2 -2
- package/dist/plugins/scss.js.map +1 -1
- package/dist/plugins/stylex.d.ts +70 -0
- package/dist/plugins/stylex.d.ts.map +1 -0
- package/dist/plugins/stylex.js +166 -0
- package/dist/plugins/stylex.js.map +1 -0
- package/dist/plugins/svg.js +2 -2
- package/dist/plugins/svg.js.map +1 -1
- package/dist/render-seam.d.ts +5 -0
- package/dist/render-seam.d.ts.map +1 -1
- package/dist/render-seam.js +10 -0
- package/dist/render-seam.js.map +1 -1
- package/dist/router.d.ts +11 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +254 -47
- package/dist/router.js.map +1 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +34 -16
- package/dist/vite.js.map +1 -1
- package/package.json +49 -2
- package/src/boundary.ts +407 -0
- package/src/build-plan.ts +741 -0
- package/src/build-vite.ts +6 -7
- package/src/build.ts +120 -730
- package/src/chunk-names.ts +3 -2
- package/src/dev-ssr-graph.ts +63 -28
- package/src/diagnostic.ts +14 -2
- package/src/fonts-google.ts +3 -1
- package/src/fs.ts +2 -1
- package/src/index.ts +107 -2553
- package/src/internal/codegen.ts +400 -0
- package/src/internal/fetcher-runtime.ts +36 -0
- package/src/internal/head-merge.ts +19 -1
- package/src/internal/identity-policy.ts +94 -0
- package/src/internal/parity.ts +603 -71
- package/src/internal/query-runtime.ts +31 -0
- package/src/internal/render-document.ts +1116 -0
- package/src/internal/runtime-contract.ts +54 -0
- package/src/internal/web-app.ts +1114 -0
- package/src/islands.ts +106 -40
- package/src/manifest.ts +50 -3
- package/src/module-graph.ts +23 -9
- package/src/nano.ts +246 -0
- package/src/plugins/css-modules.ts +2 -2
- package/src/plugins/kit.ts +65 -12
- package/src/plugins/postcss.ts +2 -2
- package/src/plugins/scss.ts +2 -2
- package/src/plugins/stylex.ts +298 -0
- package/src/plugins/svg.ts +2 -2
- package/src/render-seam.ts +6 -0
- package/src/router.ts +293 -51
- package/src/vite.ts +41 -15
package/src/chunk-names.ts
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* unsafe→safe basename map lets the build manifest point at the renamed files.
|
|
9
9
|
*/
|
|
10
10
|
import { readFileSync, renameSync, writeFileSync } from "node:fs"
|
|
11
|
+
import { dirname, join, basename as pathBasename } from "node:path"
|
|
11
12
|
|
|
12
|
-
const basename = (path: string): string =>
|
|
13
|
+
const basename = (path: string): string => pathBasename(path)
|
|
13
14
|
const URL_UNSAFE_NAME = /[^A-Za-z0-9._-]/g
|
|
14
15
|
|
|
15
16
|
export function sanitizeOutputNames(
|
|
@@ -38,7 +39,7 @@ export function sanitizeOutputNames(
|
|
|
38
39
|
for (const out of outputs) {
|
|
39
40
|
const safe = renames.get(basename(out.path))
|
|
40
41
|
if (safe !== undefined) {
|
|
41
|
-
renameSync(out.path,
|
|
42
|
+
renameSync(out.path, join(dirname(out.path), safe))
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
return renames
|
package/src/dev-ssr-graph.ts
CHANGED
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
* Bun-only + dev-only; never imported by the edge runtime or by a production build.
|
|
56
56
|
*/
|
|
57
57
|
import { statSync } from "node:fs"
|
|
58
|
-
import { dirname } from "node:path"
|
|
58
|
+
import { dirname, isAbsolute, relative, resolve, sep } from "node:path"
|
|
59
|
+
import { fileURLToPath } from "node:url"
|
|
59
60
|
import type { BunPlugin } from "bun"
|
|
60
61
|
|
|
61
62
|
/**
|
|
@@ -76,11 +77,25 @@ const REWRITABLE = "mts|cts|mjs|cjs|tsx|jsx|ts|js"
|
|
|
76
77
|
* no dot-directory (`.nifra-bun/`, `.git/`), and a source extension, with an optional cache-busting
|
|
77
78
|
* query. It mirrors {@link SsrGraph}'s ownership test; keep the two in step.
|
|
78
79
|
*/
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const escapeRegExp = (value: string): string => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
81
|
+
|
|
82
|
+
/** All path spellings Bun has used for an absolute Windows module id. */
|
|
83
|
+
const pathForms = (path: string): string[] => {
|
|
84
|
+
const native = plainPath(path)
|
|
85
|
+
const portable = native.replaceAll("\\", "/")
|
|
86
|
+
const forms = [native, portable]
|
|
87
|
+
if (process.platform === "win32" && /^[A-Za-z]:\//.test(portable)) forms.push(`/${portable}`)
|
|
88
|
+
return [...new Set(forms)]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const appSourceFilter = (root: string): RegExp => {
|
|
92
|
+
const roots = pathForms(root).map(escapeRegExp).join("|")
|
|
93
|
+
return new RegExp(
|
|
94
|
+
`^(?:${roots})[\\\\/]` +
|
|
95
|
+
`(?!(?:.*[\\\\/])?node_modules[\\\\/])` +
|
|
96
|
+
`(?!\\.)(?!.*[\\\\/]\\.)[^?]*\\.(?:${REWRITABLE})(?:\\?|$)`,
|
|
83
97
|
)
|
|
98
|
+
}
|
|
84
99
|
|
|
85
100
|
/**
|
|
86
101
|
* `from "x"`, `import "x"`, `import("x")`, `require("x")` - every form that carries a static specifier,
|
|
@@ -113,10 +128,18 @@ export interface SsrGraph {
|
|
|
113
128
|
|
|
114
129
|
/** `/abs/path.ts?v=2` and `file:///abs/path.ts` both name `/abs/path.ts`. */
|
|
115
130
|
function plainPath(path: string): string {
|
|
116
|
-
const withoutQuery = path.split("?")[0] ?? path
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
131
|
+
const withoutQuery = path.split("?", 1)[0] ?? path
|
|
132
|
+
let value = withoutQuery
|
|
133
|
+
if (value.startsWith("file://")) {
|
|
134
|
+
try {
|
|
135
|
+
value = fileURLToPath(value)
|
|
136
|
+
} catch {
|
|
137
|
+
// Let the caller's filesystem/resolver operation report a malformed URL.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (process.platform !== "win32") return value
|
|
141
|
+
if (/^\/[A-Za-z]:[\\/]/.test(value)) value = value.slice(1)
|
|
142
|
+
return value.replaceAll("/", "\\")
|
|
120
143
|
}
|
|
121
144
|
|
|
122
145
|
const mtimeOf = (path: string): number =>
|
|
@@ -161,8 +184,7 @@ export function rewriteSsrImports(contents: string, path: string, generate: "dom
|
|
|
161
184
|
|
|
162
185
|
/** Track and version the app's own server-side module graph. See the module doc for the whole design. */
|
|
163
186
|
export function createSsrGraph(options: SsrGraphOptions): SsrGraph {
|
|
164
|
-
const root =
|
|
165
|
-
const prefix = `${root}/`
|
|
187
|
+
const root = resolve(plainPath(options.root))
|
|
166
188
|
/** Every tracked module, by absolute path: its current cache version and the mtime it was read at. */
|
|
167
189
|
const nodes = new Map<string, { version: number; mtime: number }>()
|
|
168
190
|
/** Reverse edges - who imports this file - which is the direction invalidation travels. */
|
|
@@ -171,20 +193,30 @@ export function createSsrGraph(options: SsrGraphOptions): SsrGraph {
|
|
|
171
193
|
|
|
172
194
|
/** Inside the app, outside `node_modules`, outside dot-directories, and a file worth re-reading. */
|
|
173
195
|
const owned = (abs: string): boolean => {
|
|
174
|
-
|
|
175
|
-
|
|
196
|
+
const candidate = resolve(plainPath(abs))
|
|
197
|
+
const rel = relative(root, candidate)
|
|
198
|
+
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel) || rel === "") return false
|
|
176
199
|
// Relative to the app, so a project that itself lives under a dotted directory is not excluded
|
|
177
200
|
// wholesale - this is about the app's own generated trees (`.nifra/`, `.nifra-bun/`, `.git/`).
|
|
178
|
-
const
|
|
179
|
-
if (
|
|
180
|
-
|
|
201
|
+
const portable = rel.replaceAll("\\", "/")
|
|
202
|
+
if (
|
|
203
|
+
portable === "node_modules" ||
|
|
204
|
+
portable.startsWith("node_modules/") ||
|
|
205
|
+
portable.includes("/node_modules/") ||
|
|
206
|
+
portable.startsWith(".") ||
|
|
207
|
+
portable.includes("/.")
|
|
208
|
+
)
|
|
209
|
+
return false
|
|
210
|
+
return VERSIONED.test(candidate)
|
|
181
211
|
}
|
|
182
212
|
|
|
183
213
|
const track = (abs: string, importer: string): void => {
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
if (
|
|
187
|
-
|
|
214
|
+
const file = resolve(plainPath(abs))
|
|
215
|
+
const parent = resolve(plainPath(importer))
|
|
216
|
+
if (!nodes.has(file)) nodes.set(file, { version: 0, mtime: mtimeOf(file) })
|
|
217
|
+
const parents = importers.get(file)
|
|
218
|
+
if (parents === undefined) importers.set(file, new Set([parent]))
|
|
219
|
+
else parents.add(parent)
|
|
188
220
|
}
|
|
189
221
|
|
|
190
222
|
// `Bun.resolveSync` re-enters this plugin's own `onResolve`, which is an unbounded recursion rather
|
|
@@ -210,18 +242,21 @@ export function createSsrGraph(options: SsrGraphOptions): SsrGraph {
|
|
|
210
242
|
*/
|
|
211
243
|
const keyFor = (specifier: string, importer: string): string | undefined => {
|
|
212
244
|
const abs = resolveFrom(specifier, dirname(importer))
|
|
213
|
-
if (abs === undefined
|
|
214
|
-
|
|
215
|
-
|
|
245
|
+
if (abs === undefined) return undefined
|
|
246
|
+
const file = resolve(plainPath(abs))
|
|
247
|
+
if (!owned(file)) return undefined
|
|
248
|
+
track(file, importer)
|
|
249
|
+
const version = nodes.get(file)?.version ?? 0
|
|
216
250
|
// Version 0 is the shared, unversioned instance - see the module doc.
|
|
217
|
-
return version === 0 ? undefined : `${
|
|
251
|
+
return version === 0 ? undefined : `${file.replaceAll("\\", "/")}?v=${version}`
|
|
218
252
|
}
|
|
219
253
|
|
|
220
254
|
const rewrite = (contents: string, importer: string): string => {
|
|
221
|
-
|
|
255
|
+
const importerPath = resolve(plainPath(importer))
|
|
256
|
+
if (!owned(importerPath)) return contents
|
|
222
257
|
let scanned: readonly { readonly path: string }[]
|
|
223
258
|
try {
|
|
224
|
-
scanned = new Bun.Transpiler({ loader: scanLoaderFor(
|
|
259
|
+
scanned = new Bun.Transpiler({ loader: scanLoaderFor(importerPath) }).scanImports(contents)
|
|
225
260
|
} catch {
|
|
226
261
|
// Source Bun cannot parse is source Bun is about to reject with a real error message. Hand it
|
|
227
262
|
// through untouched rather than adding a second, worse one.
|
|
@@ -231,7 +266,7 @@ export function createSsrGraph(options: SsrGraphOptions): SsrGraph {
|
|
|
231
266
|
if (candidates.size === 0) return contents
|
|
232
267
|
const keys = new Map<string, string>()
|
|
233
268
|
for (const specifier of candidates) {
|
|
234
|
-
const key = keyFor(specifier,
|
|
269
|
+
const key = keyFor(specifier, importerPath)
|
|
235
270
|
if (key !== undefined) keys.set(specifier, key)
|
|
236
271
|
}
|
|
237
272
|
if (keys.size === 0) return contents
|
|
@@ -260,7 +295,7 @@ export function createSsrGraph(options: SsrGraphOptions): SsrGraph {
|
|
|
260
295
|
// virtual sub-request (`?vue-css` and friends) - both are already keyed.
|
|
261
296
|
if (args.path.includes("?")) return undefined
|
|
262
297
|
const importer = plainPath(args.importer)
|
|
263
|
-
if (!
|
|
298
|
+
if (!owned(importer)) return undefined
|
|
264
299
|
const key = keyFor(args.path, importer)
|
|
265
300
|
return key === undefined ? undefined : { path: key }
|
|
266
301
|
})
|
package/src/diagnostic.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { readFileSync, realpathSync } from "node:fs"
|
|
15
15
|
import { isAbsolute, relative, resolve } from "node:path"
|
|
16
|
+
import { fileURLToPath } from "node:url"
|
|
16
17
|
|
|
17
18
|
/** Shared endpoint name used by both dev pipelines and the agent-facing MCP tools. */
|
|
18
19
|
export const LAST_ERROR_PATH = "/__nifra/last-error"
|
|
@@ -71,7 +72,13 @@ function cleanFramePath(path: string): string | undefined {
|
|
|
71
72
|
let p = path.trim()
|
|
72
73
|
if (p.startsWith("file://")) {
|
|
73
74
|
try {
|
|
74
|
-
|
|
75
|
+
const url = new URL(p)
|
|
76
|
+
const pathname = decodeURIComponent(url.pathname)
|
|
77
|
+
// Keep synthetic POSIX paths such as file:///app/... stable for injected readers and unit
|
|
78
|
+
// fixtures. A drive-qualified or UNC URL, however, needs Node's native conversion on Windows;
|
|
79
|
+
// using URL.pathname there leaves the leading slash (`/C:/…`) and makes the filesystem look in
|
|
80
|
+
// the wrong directory.
|
|
81
|
+
p = url.hostname !== "" || /^\/[A-Za-z]:[\\/]/.test(pathname) ? fileURLToPath(url) : pathname
|
|
75
82
|
} catch {
|
|
76
83
|
return undefined
|
|
77
84
|
}
|
|
@@ -259,7 +266,12 @@ export function buildDiagnostic(err: unknown, options: BuildDiagnosticOptions =
|
|
|
259
266
|
const top = topUserFrame(frames, root)
|
|
260
267
|
const codeframe =
|
|
261
268
|
top?.file !== undefined && top.line !== undefined
|
|
262
|
-
? buildCodeframe(
|
|
269
|
+
? buildCodeframe(
|
|
270
|
+
options.read === undefined ? canonicalPath(top.file) : top.file,
|
|
271
|
+
top.line,
|
|
272
|
+
top.column,
|
|
273
|
+
options.read,
|
|
274
|
+
)
|
|
263
275
|
: undefined
|
|
264
276
|
const { code, cause, fix, docsAnchor } = classify(error.name || "Error", message)
|
|
265
277
|
return {
|
package/src/fonts-google.ts
CHANGED
|
@@ -424,7 +424,9 @@ export async function loadGoogleFont(
|
|
|
424
424
|
const hash = await contentHash(bytes)
|
|
425
425
|
const style = face.style === "italic" ? "italic" : "normal"
|
|
426
426
|
const fileName = `${slug(family)}-${slug(face.subset)}-${style}-${face.weight.replace(/\s+/g, "_")}-${hash}.woff2`
|
|
427
|
-
|
|
427
|
+
// The injected writer is also a public/test seam. Forward slashes are accepted by Node/Bun on
|
|
428
|
+
// Windows and keep its observed path stable instead of leaking the host separator.
|
|
429
|
+
const path = join(io.outDir, fileName).replaceAll("\\", "/")
|
|
428
430
|
await writeFile(path, bytes)
|
|
429
431
|
|
|
430
432
|
const href = `${publicPath}/${fileName}`
|
package/src/fs.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* only. It scans a routes dir and feeds the pure `buildManifest`.
|
|
5
5
|
*/
|
|
6
6
|
import { readdirSync } from "node:fs"
|
|
7
|
+
import { join } from "node:path"
|
|
7
8
|
import { buildManifest, type Manifest, type RouteModule } from "./manifest.ts"
|
|
8
9
|
|
|
9
10
|
/** Options for {@link discoverRoutes}. */
|
|
@@ -39,6 +40,6 @@ export function discoverRoutes(dir: string, options: DiscoverRoutesOptions = {})
|
|
|
39
40
|
: // No `importQuery` here: an injected loader owns its own invalidation (Vite's module graph
|
|
40
41
|
// re-evaluates on change), and appending a cache-buster would defeat it by minting a new
|
|
41
42
|
// module id per request.
|
|
42
|
-
() => load(
|
|
43
|
+
() => load(join(dir, file)) as Promise<RouteModule>,
|
|
43
44
|
)
|
|
44
45
|
}
|