@kudzujs/core 0.9.1 → 0.9.2

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.9.x`: the compiler API and supported TSX surface may change.
16
16
 
17
- **Latest release: 0.9.1 - Positional primitive lists.** JSON-safe primitive values now render in position-keyed collections while property-keyed rows retain their plain-object boundary. Read the [release notes](./RELEASES.md#091---positional-primitive-lists), open the [release page](https://github.com/kudzujs/kudzu/releases/tag/v0.9.1), or follow the [architecture packet](./docs/next-architecture/README.md).
17
+ **Latest release: 0.9.2 - Legacy CSS safety.** Projects with source CSS but no explicit style ownership retain their pre-0.8.53 global styles with an actionable migration warning; explicit apps keep route-aware CSS unchanged. Read the [release notes](./RELEASES.md#092---legacy-css-safety), open the [release page](https://github.com/kudzujs/kudzu/releases/tag/v0.9.2), or follow the [architecture packet](./docs/next-architecture/README.md).
18
18
 
19
19
  - [Documentation](https://kudzujs.cloud/docs)
20
20
  - [Installation guide](https://kudzujs.cloud/docs#install)
package/RELEASES.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Kudzu Releases
2
2
 
3
+ ## 0.9.2 - Legacy CSS safety
4
+
5
+ Kudzu 0.9.2 prevents pre-0.8.53 applications from silently producing an
6
+ unstyled deploy after upgrading to route-aware CSS ownership.
7
+
8
+ ### Changed in 0.9.2
9
+
10
+ - When no route imports CSS and `kudzu.config styles` is empty, source CSS is
11
+ linked globally in deterministic path order using the legacy behavior.
12
+ - The build prints an actionable warning directing applications to explicit
13
+ source imports or global configuration.
14
+ - Projects with any explicit CSS ownership retain unchanged route-aware output;
15
+ the fallback adds no browser JavaScript or explicit-path build work.
16
+
17
+ ### Validation
18
+
19
+ - A two-route legacy fixture emits both unimported styles on both routes in path
20
+ order and keeps both routes JavaScript-free.
21
+ - Configured global styles and explicit source-style tests retain their existing
22
+ output.
23
+ - `npm run check`, `npm test`, and `npm run test:package` pass with 254 tests.
24
+
25
+ ### Upgrade
26
+
27
+ ```sh
28
+ npm install @kudzujs/core@^0.9.2
29
+ ```
30
+
3
31
  ## 0.9.1 - Positional primitive lists
4
32
 
5
33
  Kudzu 0.9.1 allows JSON-safe primitive values in lists keyed by their authored
@@ -80,7 +80,7 @@ Static routes receive no browser runtime. Command routes receive `runtime.js`; d
80
80
 
81
81
  Exact relative `.worker.ts` constructors in inline effects are validated and bundled in a separate content-hashed ESM graph under `dist/assets/workers/`. Those files are referenced only by rendered effect handlers and never become document capability scripts, preloads, or window imports; unreachable source effects do not emit their Worker roots. Worker graphs allow relative TypeScript ESM runtime imports only and reject JSX, package runtime imports, import-equals declarations, dynamic imports, `require()`, and paths outside `src`. Ordinary runtime imports or re-exports of `.worker.ts` and Worker construction in imported keyed-row effects are rejected.
82
82
 
83
- Page `metadata` can emit description, canonical, favicon, manifest, Open Graph, and Twitter Card tags without a client runtime. Relative source CSS imports follow each page's reachable TypeScript graph and link only from those routes; `kudzu.config` styles remain explicitly global. Enhanced navigation loads incoming managed styles before route replacement, reuses shared links, and removes outgoing links. All styles are emitted before `afterBuild()` runs; static stylesheet links in component JSX fail compilation instead of loading from the body.
83
+ Page `metadata` can emit description, canonical, favicon, manifest, Open Graph, and Twitter Card tags without a client runtime. Relative source CSS imports follow each page's reachable TypeScript graph and link only from those routes; `kudzu.config` styles remain explicitly global. For pre-0.8.53 projects with source CSS but no explicit style ownership at all, Kudzu preserves the former global path-ordered output and prints a migration warning instead of silently emitting an unstyled deploy. Enhanced navigation loads incoming managed styles before route replacement, reuses shared links, and removes outgoing links. All styles are emitted before `afterBuild()` runs; static stylesheet links in component JSX fail compilation instead of loading from the body.
84
84
 
85
85
  Inline SVG rendering normalizes an explicit set of common React presentation aliases before static serialization and binding descriptor creation. Reactive aliases use the existing generic `setAttribute` path. Reactive conditionals and flat intrinsic keyed lists store inert branch or row markup on SVG markers and parse it in the actual parent namespace only when replacement nodes are needed; existing condition/list ownership then handles insertion, identity, updates, and removal. Focus, keyboard, and click handlers on keyed SVG points may update parent state for an external accessible HTML tooltip, and retained handlers read the latest item after list updates. Builds without structural SVG compile out that fragment path, and static SVG adds no JavaScript. Keyed-item conditions, nested SVG lists, MathML structures, and namespaced attributes remain unsupported.
86
86
 
@@ -45,7 +45,7 @@ export async function buildWithSession(project, { changedFiles, quiet = false, m
45
45
  try {
46
46
  await recoverOutput(outputDirectory, backupOutput)
47
47
  await rm(stagedOutput, { recursive: true, force: true })
48
- const { result, pageCount, behaviorCount, cache } = await buildInto(project, stagedOutput, { changedFiles, minify, retainCache })
48
+ const { result, pageCount, behaviorCount, cache } = await buildInto(project, stagedOutput, { changedFiles, minify, quiet, retainCache })
49
49
  await promoteOutput(stagedOutput, outputDirectory, backupOutput)
50
50
  project.buildCache = retainCache ? cache : undefined
51
51
  if (!quiet) console.log(`Built ${pageCount} page(s), ${behaviorCount} interactive page(s) into dist/`)
@@ -63,7 +63,7 @@ export async function buildWithSession(project, { changedFiles, quiet = false, m
63
63
  }
64
64
  }
65
65
 
66
- async function buildInto(project, outputDirectory, { changedFiles, minify, retainCache }) {
66
+ async function buildInto(project, outputDirectory, { changedFiles, minify, quiet, retainCache }) {
67
67
  const { root, sourceDirectory, pagesDirectory, workDirectory } = project
68
68
  const previous = retainCache ? project.buildCache : undefined
69
69
  project.buildGeneration = (project.buildGeneration ?? 0) + 1
@@ -108,6 +108,14 @@ async function buildInto(project, outputDirectory, { changedFiles, minify, retai
108
108
  for (const file of sourceFiles) sourceFileSet.add(file)
109
109
  const staticFiles = await safeStaticFiles(projectFiles)
110
110
  const stylesByPage = new Map(pageFiles.map(file => [file, orderSourceStyles([file], sourceFiles, sourceIndex, staticFiles).filter(style => !configuredStyleSources.has(style))]))
111
+ const explicitSourceStyles = new Set([...stylesByPage.values()].flat())
112
+ const legacyStyles = configuredStyles.sources.length || configuredStyles.urls.length || explicitSourceStyles.size
113
+ ? []
114
+ : [...staticFiles].filter(file => file.toLowerCase().endsWith(".css")).sort()
115
+ if (legacyStyles.length) {
116
+ for (const file of pageFiles) stylesByPage.set(file, legacyStyles)
117
+ if (!quiet) console.warn("Kudzu: no route imports CSS and kudzu.config styles is empty; applying the legacy global CSS fallback. Import CSS from reachable source or declare config.styles for route-aware output.")
118
+ }
111
119
  const cssFiles = [...new Set([...stylesByPage.values()].flat())]
112
120
  const importedAssets = new Set()
113
121
  const { cssModules, cssOutputs } = await prepareSourceStyles(cssFiles, staticFiles, importedAssets, base, project)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kudzujs/core",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "HTML-first TSX framework with synchronous state semantics and no virtual DOM",
5
5
  "type": "module",
6
6
  "license": "MIT",