@kudzujs/core 0.8.10 → 0.8.12
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 +1 -1
- package/RELEASES.md +55 -0
- package/framework/build.mjs +14 -4
- package/package.json +1 -1
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.8.x`: the compiler API and supported TSX surface may change.
|
|
16
16
|
|
|
17
|
-
**Latest release: 0.8.
|
|
17
|
+
**Latest release: 0.8.12 - Static icon migration.** Used Lucide-shaped icons move to relative TSX and compile to accessible static SVG while build-folded evaluator JavaScript disappears from deploy output. Read the [release notes](./RELEASES.md#0812---static-icon-migration) or open the [release page](https://kudzujs.cloud/releases/0.8.12).
|
|
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,60 @@
|
|
|
1
1
|
# Kudzu Releases
|
|
2
2
|
|
|
3
|
+
## 0.8.12 - Static icon migration
|
|
4
|
+
|
|
5
|
+
Kudzu 0.8.12 proves a source migration path from Lucide React-shaped icon usage to accessible static SVG without a package factory or browser runtime.
|
|
6
|
+
|
|
7
|
+
### New in 0.8.12
|
|
8
|
+
|
|
9
|
+
- Used icons move into relative TSX components with direct intrinsic SVG roots and familiar size, stroke, class, fill, ARIA, and title props.
|
|
10
|
+
- Meaningful icons retain explicit roles and titles, while decorative icons remain hidden from assistive technology.
|
|
11
|
+
- React-shaped SVG presentation attributes normalize to native output and complete icon routes ship zero JavaScript.
|
|
12
|
+
- Unreachable icon modules are excluded from compilation instead of becoming deploy artifacts.
|
|
13
|
+
- Public documentation records the migration recipe and its deliberate package boundary.
|
|
14
|
+
|
|
15
|
+
### Fixed in 0.8.12
|
|
16
|
+
|
|
17
|
+
- Handler emission now follows references in the final route plan and HTML, removing evaluator modules left behind by build-folded component conditions while preserving list-expression evaluators.
|
|
18
|
+
- The complete suite passes 143/143 tests.
|
|
19
|
+
|
|
20
|
+
### Boundary
|
|
21
|
+
|
|
22
|
+
This release does not execute `lucide-react`. Dynamic icon lookup, `createLucideIcon()`, package-owned factories, and a generic icon runtime remain unsupported source migration work.
|
|
23
|
+
|
|
24
|
+
### Upgrade
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @kudzujs/core@^0.8.12
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 0.8.11 - Stale-safe data migration
|
|
31
|
+
|
|
32
|
+
Kudzu 0.8.11 proves source migration paths for TanStack Query-shaped data and React Hook Form-shaped forms while strengthening dependency-effect stale-write isolation.
|
|
33
|
+
|
|
34
|
+
### New in 0.8.11
|
|
35
|
+
|
|
36
|
+
- Build-known query data moves to async pages and emits complete zero-JavaScript HTML.
|
|
37
|
+
- Browser-only query data uses one dependency effect with application-owned loading, error, result, and primitive refetch state.
|
|
38
|
+
- Superseded unowned dependency effects invalidate their invocation before cleanup, so late promise or fetch setters cannot overwrite newer state.
|
|
39
|
+
- A deterministic Chrome race verifies that a fast refetch remains visible after a delayed prior response arrives, followed by HTTP failure and recovery.
|
|
40
|
+
- React Hook Form-shaped signup source migrates to native controls, constraint validation, `FormData`, one async submit handler, accessible server errors, and retained uncontrolled values.
|
|
41
|
+
- Static sibling routes remain JavaScript-free, with no TanStack Query or React Hook Form runtime in deploy output.
|
|
42
|
+
|
|
43
|
+
### Fixed in 0.8.11
|
|
44
|
+
|
|
45
|
+
- Mobile documentation now uses a true 100% layout wrapper with explicit inner gutters instead of a reduced outer width.
|
|
46
|
+
- The complete suite passes 142/142 tests.
|
|
47
|
+
|
|
48
|
+
### Boundary
|
|
49
|
+
|
|
50
|
+
This release does not execute TanStack Query or React Hook Form. Query clients, Providers, caches, retries, deduplication, optimistic cache updates, query-key arrays, Suspense, controllers, watchers, resolvers, and dynamic field registration remain source migration work.
|
|
51
|
+
|
|
52
|
+
### Upgrade
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install @kudzujs/core@^0.8.11
|
|
56
|
+
```
|
|
57
|
+
|
|
3
58
|
## 0.8.10 - Native dialog migration
|
|
4
59
|
|
|
5
60
|
Kudzu 0.8.10 proves a source migration path from a shadcn/Radix-shaped dialog to the native `<dialog>` element without adding package compatibility runtime.
|
package/framework/build.mjs
CHANGED
|
@@ -145,7 +145,8 @@ export async function build({ quiet = false, minify = true } = {}) {
|
|
|
145
145
|
runtimeParams: runtimeSchema?.params,
|
|
146
146
|
...(navigable ? { navigationAsset: navigationGroup.assetPath, applicationId: navigationGroup.applicationId, layoutId: navigationGroup.layoutId, routeId: applicationRoute } : {})
|
|
147
147
|
}, props, module.layout)
|
|
148
|
-
|
|
148
|
+
const renderedOutput = `${JSON.stringify(result.plan)}\n${result.html}`
|
|
149
|
+
for (const url of result.handlerModules) if (renderedOutput.includes(JSON.stringify(url))) renderedHandlerUrls.add(url)
|
|
149
150
|
if (navigationGroup) {
|
|
150
151
|
navigationGroup.hasEffects ||= result.hasEffects
|
|
151
152
|
navigationGroup.hasParams ||= result.hasParams
|
|
@@ -581,7 +582,7 @@ addEventListener("pagehide", event => {
|
|
|
581
582
|
if (hasDependencies) return `${imports.join("\n")}
|
|
582
583
|
const effects = ${inlineJson(effects)}
|
|
583
584
|
const modules = new Map([${entries}])
|
|
584
|
-
const records = effects.map((effect, index) => ({ effect, index, values: undefined, cleanup: undefined }))
|
|
585
|
+
const records = effects.map((effect, index) => ({ effect, index, values: undefined, cleanup: undefined, token: undefined }))
|
|
585
586
|
const dependencies = new Map()
|
|
586
587
|
const pending = new Set()
|
|
587
588
|
let scheduled = false
|
|
@@ -649,7 +650,9 @@ ${hasDependencyExpressions ? printDerivedDependencyRead("browserState") : ""}
|
|
|
649
650
|
function invoke(record) {
|
|
650
651
|
try {
|
|
651
652
|
const effect = record.effect
|
|
652
|
-
const
|
|
653
|
+
const token = { active: true }
|
|
654
|
+
record.token = token
|
|
655
|
+
const result = modules.get(effect.module)[effect.handler](createEffectContext(browserState, effect.states, commitDom, effect.scope, () => active && token.active && record.token === token))
|
|
653
656
|
if (effect.cleanup && typeof result === "function") record.cleanup = result
|
|
654
657
|
else if (result && typeof result.then === "function") result.catch(error => console.error(error))
|
|
655
658
|
} catch (error) {
|
|
@@ -657,6 +660,8 @@ function invoke(record) {
|
|
|
657
660
|
}
|
|
658
661
|
}
|
|
659
662
|
async function invokeCleanup(record) {
|
|
663
|
+
if (record.token) record.token.active = false
|
|
664
|
+
record.token = undefined
|
|
660
665
|
const cleanup = record.cleanup
|
|
661
666
|
record.cleanup = undefined
|
|
662
667
|
if (!cleanup) return
|
|
@@ -1352,6 +1357,7 @@ const effect = ${inlineJson(effect)}
|
|
|
1352
1357
|
const dependency = effect.dependencies[0]
|
|
1353
1358
|
let value
|
|
1354
1359
|
let cleanup
|
|
1360
|
+
let token
|
|
1355
1361
|
let active = true
|
|
1356
1362
|
let pending = false
|
|
1357
1363
|
let scheduled = false
|
|
@@ -1402,7 +1408,9 @@ function readDependency() {
|
|
|
1402
1408
|
}
|
|
1403
1409
|
function invoke() {
|
|
1404
1410
|
try {
|
|
1405
|
-
const
|
|
1411
|
+
const current = { active: true }
|
|
1412
|
+
token = current
|
|
1413
|
+
const result = __kEffectModule0[effect.handler](createEffectContext(browserState, effect.states, commitDom, effect.scope, () => active && current.active && token === current))
|
|
1406
1414
|
if (effect.cleanup && typeof result === "function") cleanup = result
|
|
1407
1415
|
else if (result && typeof result.then === "function") result.catch(error => console.error(error))
|
|
1408
1416
|
} catch (error) {
|
|
@@ -1410,6 +1418,8 @@ function invoke() {
|
|
|
1410
1418
|
}
|
|
1411
1419
|
}
|
|
1412
1420
|
async function invokeCleanup() {
|
|
1421
|
+
if (token) token.active = false
|
|
1422
|
+
token = undefined
|
|
1413
1423
|
const current = cleanup
|
|
1414
1424
|
cleanup = undefined
|
|
1415
1425
|
if (!current) return
|