@kudzujs/core 0.16.27 → 0.16.28

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 CHANGED
@@ -14,7 +14,7 @@ Kudzu compiles ordinary React-shaped TypeScript and TSX into complete static HTM
14
14
 
15
15
  > Experimental `0.16.x`: the compiler API and supported TSX surface may change.
16
16
 
17
- **Current release: [0.16.27](https://github.com/kudzujs/kudzu/releases/tag/v0.16.27).** Write reusable components, native event handlers, and pure collection expressions; Kudzu specializes supported source into static content and direct browser updates.
17
+ **Current release: [0.16.28](https://github.com/kudzujs/kudzu/releases/tag/v0.16.28).** Write reusable components, native event handlers, and pure collection expressions; Kudzu specializes supported source into static content and direct browser updates.
18
18
 
19
19
  - [Documentation](https://kudzujs.cloud/docs)
20
20
  - [Installation guide](https://kudzujs.cloud/docs#install)
@@ -138,6 +138,13 @@ interactions, labels, status updates, keyboard focus, and responsive layouts in
138
138
  browser as needed. Binding comments and inert templates mean raw HTML string
139
139
  matches or tag stripping are not reliable checks of rendered text.
140
140
 
141
+ Normal builds also scan generated route HTML after `afterBuild`, reporting counts
142
+ with/without script or modulepreload text markers and unreadable files, with up to
143
+ five paths per category (long paths are truncated). This is a literal text scan,
144
+ not proof of script freedom: comments and inert content can match, inline event
145
+ attributes are not checked, and extra public HTML files are outside the route
146
+ inventory. Quiet and JSON builds omit this summary.
147
+
141
148
  Keep checks bounded and report concise counts and failing paths rather than
142
149
  repeatedly dumping minified artifacts. A missing tool or truncated response is
143
150
  not a pass. After source changes, rerun affected checks. Optional compiler/artifact
@@ -59,13 +59,14 @@ export async function buildWithSession(project, { changedFiles, quiet = false, m
59
59
  try {
60
60
  await recoverOutput(outputDirectory, backupOutput)
61
61
  await rm(stagedOutput, { recursive: true, force: true })
62
- const { result, pageCount, behaviorCount, cache, inspectionData, explanation } = await buildInto(project, stagedOutput, { changedFiles, minify, quiet, retainCache, explanationRoute })
62
+ const { result, pageCount, behaviorCount, cache, inspectionData, explanation, htmlSummary } = await buildInto(project, stagedOutput, { changedFiles, minify, quiet, retainCache, explanationRoute })
63
63
  const promoteStarted = project.timings ? performance.now() : 0
64
64
  await promoteOutput(stagedOutput, outputDirectory, backupOutput)
65
65
  addTiming(project.timings, "writeMs", promoteStarted)
66
66
  project.buildCache = retainCache ? cache : undefined
67
67
  if (!quiet) {
68
68
  console.log(`Built ${pageCount} page(s), ${behaviorCount} interactive page(s) into dist/`)
69
+ console.log(htmlSummary)
69
70
  console.log("Browser behavior and accessibility need verification: https://kudzujs.cloud/docs#build")
70
71
  }
71
72
  return explanationRoute ? explanation : inspection ? createInspectionReport(inspectionData) : result
@@ -553,6 +554,34 @@ async function buildInto(project, outputDirectory, { changedFiles, minify, quiet
553
554
  if (typeof config.afterBuild !== "function") throw new Error("kudzu.config afterBuild must be a function")
554
555
  await config.afterBuild({ root, outDir: outputDirectory, sourceDir: sourceDirectory, base, routes: plans.map(plan => plan.route), plans, rewrites: sortedRewrites, artifacts })
555
556
  }
557
+ let htmlSummary
558
+ if (!quiet) {
559
+ const counts = { "With markers": 0, Unreadable: 0 }
560
+ const samples = { "With markers": [], Unreadable: [] }
561
+ // Scan final route files, not compiler closure metadata or a previous build's scratch report.
562
+ const outputs = routeRecords.map(record => record.output).sort()
563
+ for (let offset = 0; offset < outputs.length; offset += 64) {
564
+ const batch = outputs.slice(offset, offset + 64)
565
+ const categories = await Promise.all(batch.map(async output => {
566
+ try {
567
+ const html = await readFile(join(outputDirectory, output, "index.html"), "utf8")
568
+ if (/<script(?=[\s/>])|<link(?=[\s/>])[^>]*\bmodulepreload\b/i.test(html)) return "With markers"
569
+ } catch {
570
+ return "Unreadable"
571
+ }
572
+ }))
573
+ for (const [index, category] of categories.entries()) {
574
+ if (!category) continue
575
+ counts[category]++
576
+ if (samples[category].length < 5) {
577
+ const path = join("dist", batch[index], "index.html").replaceAll(sep, "/")
578
+ samples[category].push(JSON.stringify(path.length > 240 ? `${path.slice(0, 240)}...` : path))
579
+ }
580
+ }
581
+ }
582
+ htmlSummary = `Route HTML scan: ${routeRecords.length - counts["With markers"] - counts.Unreadable} without script/modulepreload text markers, ${counts["With markers"]} with markers, ${counts.Unreadable} unreadable.`
583
+ for (const category of Object.keys(counts)) if (counts[category]) htmlSummary += `\n ${category}: ${samples[category].join(", ")}${counts[category] > 5 ? ` (+${counts[category] - 5} more)` : ""}`
584
+ }
556
585
  addTiming(project.timings, "writeMs", writeStarted)
557
586
 
558
587
  let explanation
@@ -570,6 +599,7 @@ async function buildInto(project, outputDirectory, { changedFiles, minify, quiet
570
599
  result: { sourceResults, incremental },
571
600
  inspectionData: { sourceFiles: sourceFiles.map(file => relative(root, file).replaceAll(sep, "/")), sourceResults, compatibility, artifacts },
572
601
  explanation,
602
+ htmlSummary,
573
603
  pageCount: routeRecords.length,
574
604
  behaviorCount,
575
605
  cache: { pageRenders, pageSources, placeholders, sourceResults: sourceResultsByFile }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kudzujs/core",
3
- "version": "0.16.27",
3
+ "version": "0.16.28",
4
4
  "description": "HTML-first TSX framework with synchronous state semantics and no virtual DOM",
5
5
  "type": "module",
6
6
  "license": "MIT",