@kudzujs/core 0.8.17 → 0.8.19
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/MIGRATION_ROADMAP.md +14 -0
- package/PERFORMANCE.md +79 -0
- package/README.md +1 -1
- package/RELEASES.md +66 -0
- package/docs/next-architecture/README.md +1 -1
- package/docs/next-architecture/compiler-current-architecture.md +7 -5
- package/docs/next-architecture/goal-a-compiler-foundation.md +2 -2
- package/docs/next-architecture/versioning.md +1 -1
- package/framework/README.md +4 -2
- package/framework/build.mjs +194 -49
- package/framework/compiler/analysis/component-analysis.mjs +49 -0
- package/framework/compiler/descriptor-session.mjs +88 -21
- package/framework/compiler/handler-codegen.mjs +6 -279
- package/framework/compiler/handler-lowering.mjs +278 -0
- package/framework/compiler/ir/module-ir.mjs +23 -5
- package/package.json +1 -1
package/MIGRATION_ROADMAP.md
CHANGED
|
@@ -202,6 +202,20 @@ This queue orders the next investigations by general migration value. Start only
|
|
|
202
202
|
- Same-named state in separate owners no longer aliases in IR, shared setter environments reuse signal identity, and synthetic specialized callbacks receive no fabricated source position.
|
|
203
203
|
- For unchanged source input, Counter HTML, route plans, command runtime, and generated artifacts remain byte-identical to 0.8.16; no browser capability or source syntax changed.
|
|
204
204
|
|
|
205
|
+
### Completed In 0.8.18
|
|
206
|
+
|
|
207
|
+
- Every compiled non-Worker source retains an ordered JSON-safe component analysis result covering lexical state/setter pairs, destructured props, object refs, deterministic IDs, and supported component specializations.
|
|
208
|
+
- Command signals now resolve ownership per referenced state rather than per setter-map identity, preserving distinct parent, specialized-child, keyed-row, reducer, custom-hook, and Context Provider relationships.
|
|
209
|
+
- Specialized prop records retain default application and direct signal links; imported hook declarations keep source provenance while synthetic ownership invents no source range.
|
|
210
|
+
- `core.mjs` remains authoritative for final route/layout state, ref, ID, conditional, and keyed allocation. Repeated, conditional, imported, setter-adapter, Context, and reducer fixtures preserve their existing ownership and deploy output.
|
|
211
|
+
|
|
212
|
+
### Completed In 0.8.19
|
|
213
|
+
|
|
214
|
+
- Native and effect callback exports now finalize into JSON-safe HandlerIR with ordered signals, setters, captures, snapshot policy, imports, roles, source provenance, and generated module source.
|
|
215
|
+
- Reactive bindings, list expressions, and list condition evaluators finalize into BindingIR with explicit states, captures, parameters, imports, and deterministic export slots.
|
|
216
|
+
- Existing tagged collection expressions and selectors are canonical DerivedIR for rendered lists and derived effect dependencies; transformed source embeds the registered records rather than parallel analyzer values.
|
|
217
|
+
- AST, `Map`, and `Set` callback descriptors remain private only until source-local lowering completes. Handler codegen now performs no TypeScript traversal or state/capture/reducer/import discovery, while command-only routes retain zero handler ESM.
|
|
218
|
+
|
|
205
219
|
## Cross-Cutting Performance Gates
|
|
206
220
|
|
|
207
221
|
Every migration feature must preserve:
|
package/PERFORMANCE.md
CHANGED
|
@@ -1,5 +1,84 @@
|
|
|
1
1
|
# Performance Records
|
|
2
2
|
|
|
3
|
+
## 0.8.19 Handler, Binding, And Derived IR
|
|
4
|
+
|
|
5
|
+
Measured UTC 2026-08-08 on Apple M3, 8 logical CPUs, 8 GiB RAM, macOS 26.5.2 / Darwin 25.5.0, Node 25.6.1, and npm 11.18.0. Baseline `0.8.18` tag `3598be0` and the `0.8.19` compiler-only candidate used detached worktrees on the same temporary volume with identical installed dependencies.
|
|
6
|
+
|
|
7
|
+
The candidate compiler patch over `3598be0` had SHA-256 `7b2afc4c9a0d1963c8d3ccacfb1e95152136d77cc7afc250d17b1986ca329fb3`, produced by:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git diff --binary 3598be0 -- framework/build.mjs framework/compiler/descriptor-session.mjs framework/compiler/handler-codegen.mjs framework/compiler/handler-lowering.mjs framework/compiler/ir/module-ir.mjs | shasum -a 256
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Both targets received one warm-up followed by 21 clean `worker-effects` production builds in round-robin alternating order. Cleanup remained outside timing. The distributions overlap; the candidate median was 0.32% lower and does not establish a material change.
|
|
14
|
+
|
|
15
|
+
| Target | Build median | Worker raw / gzip | Window raw / gzip |
|
|
16
|
+
|---|---:|---:|---:|
|
|
17
|
+
| 0.8.18 baseline | 253.4 ms | 907 B / 475 B | 12,148 B / 5,427 B |
|
|
18
|
+
| 0.8.19 candidate | 252.6 ms | 907 B / 475 B | 12,148 B / 5,427 B |
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
0.8.18: [252.3,254.5,251.0,254.8,254.3,253.8,253.4,251.6,255.4,252.4,249.6,254.2,251.0,253.7,256.0,250.4,251.0,255.4,253.3,253.6,250.5]
|
|
22
|
+
0.8.19: [252.3,251.7,252.9,251.9,251.5,253.0,252.3,251.3,253.0,252.1,254.3,258.4,249.8,251.6,256.2,253.7,253.5,252.6,252.9,252.5,255.9]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Before release-content updates, the complete site `dist` was byte-identical. Representative fixture builds retained identical file lists and SHA-256 content; `.kudzu` comparisons replaced only each detached worktree's absolute root in existing source-location strings. The complete fixture lists were:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
bindings: dist/assets/handlers/pages/index.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/index.html, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs
|
|
29
|
+
native: dist/assets/handlers/pages/index.js, dist/assets/handlers/pages/other/index.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/assets/native/other/index.js, dist/index.html, dist/other/index.html, .kudzu/helpers.mjs, .kudzu/kudzu-plan.json, .kudzu/math.mjs, .kudzu/pages/index.mjs, .kudzu/pages/other/index.mjs
|
|
30
|
+
reducer: dist/assets/handlers/pages/index.js, dist/assets/handlers/pages/lazy.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-list.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, dist/lazy/index.html, .kudzu/ImportedControls.mjs, .kudzu/ImportedInput.mjs, .kudzu/ImportedItem.mjs, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs, .kudzu/pages/lazy.mjs, .kudzu/todoReducer.mjs, .kudzu/todoSupport.mjs
|
|
31
|
+
context-actions: dist/assets/handlers/pages/index.js, dist/assets/kudzu-list.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, dist/static/index.html, .kudzu/kudzu-plan.json, .kudzu/notes.mjs, .kudzu/pages/index.mjs, .kudzu/pages/static.mjs, .kudzu/useNotes.mjs
|
|
32
|
+
zustand-migration: dist/assets/handlers/Shell.js, dist/assets/handlers/pages/cart.js, dist/assets/handlers/pages/index.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-native.js, dist/assets/kudzu-navigation.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/cart/index.js, dist/assets/native/index.js, dist/cart/index.html, dist/index.html, .kudzu/Shell.mjs, .kudzu/kudzu-plan.json, .kudzu/pages/cart.mjs, .kudzu/pages/index.mjs, .kudzu/store.mjs
|
|
33
|
+
event-package: dist/assets/handlers/pages/index.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs
|
|
34
|
+
list-expressions: dist/assets/handlers/pages/index.js, dist/assets/kudzu-list.js, dist/assets/kudzu.js, dist/index.html, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs
|
|
35
|
+
effect-dependencies: dist/assets/effects/index.js, dist/assets/handlers/pages/index.js, dist/assets/kudzu-collection-selector.js, dist/assets/kudzu-deps.js, dist/assets/kudzu-effect.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu.js, dist/command/index.html, dist/index.html, .kudzu/kudzu-plan.json, .kudzu/pages/command.mjs, .kudzu/pages/index.mjs
|
|
36
|
+
landing-page-migration: dist/assets/assets/badge.png, dist/assets/assets/hero.svg, dist/assets/assets/landing.woff2, dist/assets/assets/module-mark.svg, dist/assets/assets/preview.webp, dist/assets/handlers/pages/index.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/assets/styles/Hero.module.css, dist/assets/styles/landing.css, dist/index.html, dist/static/index.html, .kudzu/LandingSections.mjs, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs, .kudzu/pages/static.mjs
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This measurement covers compiler clean-build startup and artifact size, not browser interaction latency or cross-framework performance.
|
|
40
|
+
|
|
41
|
+
The recorded cleanup, warm-up, and alternating 21-run loop is reproducible with:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
BASELINE_ROOT="/private/var/folders/bt/3r_ntp5x65j81brs6_p93rl00000gn/T/opencode/kudzu-0819-baseline" CANDIDATE_ROOT="/var/folders/bt/3r_ntp5x65j81brs6_p93rl00000gn/T/opencode/kudzu-0.8.19-candidate" node --input-type=module -e 'import { spawnSync } from "node:child_process"; import { rmSync } from "node:fs"; import { performance } from "node:perf_hooks"; import { resolve } from "node:path"; const roots={baseline:process.env.BASELINE_ROOT,candidate:process.env.CANDIDATE_ROOT}; const runs={baseline:[],candidate:[]}; const build=name=>{const root=roots[name],fixture=resolve(root,"test/fixtures/worker-effects"); rmSync(resolve(fixture,"dist"),{recursive:true,force:true}); rmSync(resolve(fixture,".kudzu"),{recursive:true,force:true}); const start=performance.now(); const result=spawnSync(process.execPath,[resolve(root,"bin/kudzu.mjs"),"build"],{cwd:fixture,encoding:"utf8"}); if(result.status!==0) throw new Error(result.stderr||result.stdout); return Number((performance.now()-start).toFixed(1));}; build("baseline"); build("candidate"); for(let index=0;index<21;index++) for(const name of index%2?["candidate","baseline"]:["baseline","candidate"]) runs[name].push(build(name)); console.log(JSON.stringify(runs));'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The complete `worker-effects` benchmark list was: `dist/assets/effects/dashboard/index.js`, `dist/assets/handlers/pages/dashboard.js`, `dist/assets/kudzu-effect.js`, `dist/assets/kudzu-navigation.js`, `dist/assets/kudzu.js`, `dist/assets/workers/telemetry.worker-BVG2SA55.js`, `dist/dashboard/index.html`, `dist/plain/index.html`, `dist/static/index.html`, `.kudzu/Shell.mjs`, `.kudzu/chart.mjs`, `.kudzu/kudzu-plan.json`, `.kudzu/pages/dashboard.mjs`, `.kudzu/pages/plain.mjs`, `.kudzu/pages/static.mjs`, `.kudzu/telemetry/downsample.mjs`, and `.kudzu/telemetry/ring.mjs`.
|
|
48
|
+
|
|
49
|
+
## 0.8.18 Explicit Component Ownership
|
|
50
|
+
|
|
51
|
+
Measured UTC 2026-08-08 on Apple M3, 8 logical CPUs, 8 GiB RAM, macOS 26.5.2 / Darwin 25.5.0, Node 25.6.1, and npm 11.18.0. Baseline `0.8.17` tag `d48f0cf` and the `0.8.18` compiler-only candidate used detached worktrees on the same temporary volume with identical installed dependencies.
|
|
52
|
+
|
|
53
|
+
Both targets received one warm-up followed by 21 clean `worker-effects` production builds in round-robin alternating order. Cleanup remained outside timing. The distributions overlap; the 2.43% candidate median difference remains below the 5% architecture gate and does not establish a material regression.
|
|
54
|
+
|
|
55
|
+
| Target | Build median | Worker raw / gzip | Window raw / gzip |
|
|
56
|
+
|---|---:|---:|---:|
|
|
57
|
+
| 0.8.17 baseline | 770.9 ms | 907 B / 475 B | 12,148 B / 5,427 B |
|
|
58
|
+
| 0.8.18 candidate | 789.6 ms | 907 B / 475 B | 12,148 B / 5,427 B |
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
0.8.17: [770.9,705.6,817.1,768.5,760.2,839.8,758.3,756.1,960.7,834.6,707.9,706.5,582.9,463.5,625.5,1004.2,846.9,821.3,837.5,876.9,810.8]
|
|
62
|
+
0.8.18: [753.9,726.4,879.3,851.5,942.8,949.3,758.4,761.3,794.3,782.2,620.6,622.9,610.8,726.8,732.3,833.0,789.6,816.3,845.2,811.3,825.0]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Before release-content updates, the complete `dist` and `.kudzu` trees were byte-identical. The Worker and window graphs remain byte-identical. This measurement covers compiler clean-build startup and artifact size, not browser interaction latency or cross-framework performance.
|
|
66
|
+
|
|
67
|
+
Representative fixture builds also retained identical file lists and SHA-256 content against `v0.8.17`. Deploy `dist` bytes matched exactly; `.kudzu` hashes matched after replacing only each detached worktree's absolute root in existing source-location strings. The complete compared lists were:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
bindings: dist/assets/handlers/pages/index.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/index.html, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs
|
|
71
|
+
conditionals: dist/assets/handlers/pages/index.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs
|
|
72
|
+
nested-component-lists: dist/assets/effects/index.js, dist/assets/handlers/pages/index.js, dist/assets/kudzu-effect.js, dist/assets/kudzu-list.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, .kudzu/ImportedItem.mjs, .kudzu/ImportedShell.mjs, .kudzu/kudzu-plan.json, .kudzu/label.mjs, .kudzu/pages/index.mjs
|
|
73
|
+
effects: dist/api/items.json, dist/assets/effects/index.js, dist/assets/effects/oak/index.js, dist/assets/effects/only/index.js, dist/assets/handlers/pages/[slug].js, dist/assets/handlers/pages/index.js, dist/assets/handlers/pages/only.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-effect.js, dist/assets/kudzu-list.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/index.html, dist/oak/index.html, dist/only/index.html, dist/static/index.html, .kudzu/kudzu-plan.json, .kudzu/pages/[slug].mjs, .kudzu/pages/index.mjs, .kudzu/pages/only.mjs, .kudzu/pages/static.mjs
|
|
74
|
+
worker-effects: dist/assets/effects/dashboard/index.js, dist/assets/handlers/pages/dashboard.js, dist/assets/kudzu-effect.js, dist/assets/kudzu-navigation.js, dist/assets/kudzu.js, dist/assets/workers/telemetry.worker-BVG2SA55.js, dist/dashboard/index.html, dist/plain/index.html, dist/static/index.html, .kudzu/Shell.mjs, .kudzu/chart.mjs, .kudzu/kudzu-plan.json, .kudzu/pages/dashboard.mjs, .kudzu/pages/plain.mjs, .kudzu/pages/static.mjs, .kudzu/telemetry/downsample.mjs, .kudzu/telemetry/ring.mjs
|
|
75
|
+
runtime-params: dist/assets/effects/orgs/[org]/items/[id]/index.js, dist/assets/handlers/pages/orgs/[org]/items/[id].js, dist/assets/kudzu-binding.js, dist/assets/kudzu-effect.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/orgs/[org]/items/[id]/index.js, dist/assets/params/orgs/[org]/items/[id]/index.js, dist/orgs/[org]/items/[id]/index.html, dist/orgs/acme/items/new/index.html, dist/rewrites.json, .kudzu/kudzu-plan.json, .kudzu/pages/orgs/[org]/items/[id].mjs, .kudzu/pages/orgs/acme/items/new.mjs
|
|
76
|
+
navigation: dist/[section]/[id]/index.html, dist/assets/effects/[section]/[id]/index.js, dist/assets/effects/broken/index.js, dist/assets/effects/cart/index.js, dist/assets/effects/chart/index.js, dist/assets/effects/items/[id]/index.js, dist/assets/effects/items/new/index.js, dist/assets/effects/product/index.js, dist/assets/handlers/Shell.js, dist/assets/handlers/chunks/chunk-VIS4MAAV.js, dist/assets/handlers/pages/cart.js, dist/assets/handlers/pages/chart.js, dist/assets/handlers/pages/items/[id].js, dist/assets/handlers/pages/product.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-effect.js, dist/assets/kudzu-list.js, dist/assets/kudzu-native.js, dist/assets/kudzu-navigation.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/items/[id]/index.js, dist/assets/native/product/index.js, dist/assets/params/[section]/[id]/index.js, dist/assets/params/items/[id]/index.js, dist/broken/index.html, dist/browser-test.js, dist/cart/index.html, dist/chart/index.html, dist/items/[id]/index.html, dist/items/new/index.html, dist/outside/index.html, dist/product/index.html, .kudzu/Shell.mjs, .kudzu/chart.mjs, .kudzu/kudzu-plan.json, .kudzu/pages/[section]/[id].mjs, .kudzu/pages/broken.mjs, .kudzu/pages/cart.mjs, .kudzu/pages/chart.mjs, .kudzu/pages/items/[id].mjs, .kudzu/pages/items/new.mjs, .kudzu/pages/outside.mjs, .kudzu/pages/product.mjs
|
|
77
|
+
callback-ref-ownership: dist/assets/effects/index.js, dist/assets/handlers/pages/index.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-effect.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, .kudzu/ImportedAgeInput.mjs, .kudzu/ImportedButton.mjs, .kudzu/ImportedSearch.mjs, .kudzu/ImportedTooltip.mjs, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs
|
|
78
|
+
context-actions: dist/assets/handlers/pages/index.js, dist/assets/kudzu-list.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, dist/static/index.html, .kudzu/kudzu-plan.json, .kudzu/notes.mjs, .kudzu/pages/index.mjs, .kudzu/pages/static.mjs, .kudzu/useNotes.mjs
|
|
79
|
+
reducer: dist/assets/handlers/pages/index.js, dist/assets/handlers/pages/lazy.js, dist/assets/kudzu-binding.js, dist/assets/kudzu-list.js, dist/assets/kudzu-native.js, dist/assets/kudzu-serialization.js, dist/assets/kudzu-style.js, dist/assets/kudzu.js, dist/assets/native/index.js, dist/index.html, dist/lazy/index.html, .kudzu/ImportedControls.mjs, .kudzu/ImportedInput.mjs, .kudzu/ImportedItem.mjs, .kudzu/kudzu-plan.json, .kudzu/pages/index.mjs, .kudzu/pages/lazy.mjs, .kudzu/todoReducer.mjs, .kudzu/todoSupport.mjs
|
|
80
|
+
```
|
|
81
|
+
|
|
3
82
|
## 0.8.17 Command ModuleIR
|
|
4
83
|
|
|
5
84
|
Measured UTC 2026-08-08 on Apple M3, 8 logical CPUs, 8 GiB RAM, macOS 26.5.2 / Darwin 25.5.0, Node 25.6.1, and npm 11.18.0. Baseline `0.8.16` tag `98a4ad9` and the `0.8.17` release candidate used detached worktrees on the same temporary volume with identical installed dependencies.
|
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.19 - Handler, binding, and derived IR.** Native callbacks, reactive bindings, list evaluators, imports, and pure derived expressions now cross one JSON-safe ModuleIR boundary before source-only artifact codegen. Read the [release notes](./RELEASES.md#0819---handler-binding-and-derived-ir), open the [release page](https://kudzujs.cloud/releases/0.8.19), or follow the [next 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,71 @@
|
|
|
1
1
|
# Kudzu Releases
|
|
2
2
|
|
|
3
|
+
## 0.8.19 - Handler, binding, and derived IR
|
|
4
|
+
|
|
5
|
+
Kudzu 0.8.19 completes the next Goal A source-analysis boundary: native callbacks, reactive bindings, list evaluators, imports, and pure derived expressions now finalize into JSON-safe ModuleIR before mechanical artifact codegen.
|
|
6
|
+
|
|
7
|
+
### Changed in 0.8.19
|
|
8
|
+
|
|
9
|
+
- Native and effect callback exports retain explicit roles, signals, setters, captures, snapshot policy, imports, source ranges, and finalized export source in HandlerIR.
|
|
10
|
+
- Reactive bindings, list expressions, and list condition evaluators retain explicit states, captures, parameters, imports, and deterministic module-export slots in BindingIR.
|
|
11
|
+
- Rendered list selectors and derived effect dependencies use the existing tagged collection-expression language as canonical DerivedIR; transformed build source reads back the registered records.
|
|
12
|
+
- Reducer, Context, Zustand, package-import, nested snapshot, and scope semantics finish lowering while source AST and diagnostics are still available.
|
|
13
|
+
- `handler-codegen.mjs` imports no TypeScript or AST helpers. It renders the finalized ordered imports and concatenates generated HandlerIR/BindingIR export source.
|
|
14
|
+
- The previous semantic artifact arrays containing callback/expression AST, `Map`, and `Set` values were deleted. They remain only inside the source-local session until finalization and do not cross the IR boundary.
|
|
15
|
+
|
|
16
|
+
### Goal A boundary
|
|
17
|
+
|
|
18
|
+
- Effect lifetime, cleanup, dependencies, Worker edges, and ownership remain on the existing path until EffectIR in `0.8.21`; only their generated callback exports join HandlerIR now.
|
|
19
|
+
- Keyed DOM ownership remains on the existing path until KeyedBlockIR in `0.8.20`; list evaluators and pure selectors are explicit without moving key-path ownership early.
|
|
20
|
+
- `core.mjs` remains authoritative for complete HTML, final route/layout state IDs, and the serializable route plan.
|
|
21
|
+
- No accepted syntax, public API, runtime capability, VDOM, hydration, component rerender, or retained browser component tree was added.
|
|
22
|
+
|
|
23
|
+
### Validation
|
|
24
|
+
|
|
25
|
+
- The complete suite passes 167/167 tests, including ModuleIR JSON round-trip, command-only exclusion, native async handlers, bindings, package imports, reducer, Context, Zustand, list-derived, and effect-derived contracts.
|
|
26
|
+
- Before release-content updates, the complete site `dist` and nine representative fixture output trees matched `v0.8.18`; detached-worktree roots were normalized only in existing `.kudzu` diagnostic strings.
|
|
27
|
+
- Worker and window graphs remain byte-identical. A same-volume 21-run interleaved comparison measured a 0.32% lower candidate median; raw arrays, file lists, and environment are recorded in `PERFORMANCE.md`.
|
|
28
|
+
- `create-kudzu` remains 0.1.101 because its unchanged template already accepts `@kudzujs/core@^0.8.15`.
|
|
29
|
+
|
|
30
|
+
### Upgrade
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @kudzujs/core@^0.8.19
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 0.8.18 - Explicit component ownership
|
|
37
|
+
|
|
38
|
+
Kudzu 0.8.18 completes the next Goal A source-analysis seam: state, setters, props, refs, IDs, and supported component specializations now have one ordered JSON-safe ownership result without changing final route allocation or deploy behavior.
|
|
39
|
+
|
|
40
|
+
### Changed in 0.8.18
|
|
41
|
+
|
|
42
|
+
- Every compiled non-Worker source retains component analysis alongside its transformed build module and optional handler module; Worker graphs keep their existing dedicated result.
|
|
43
|
+
- Lexical owners record ordered state and setter slots, destructured prop shape, object refs, deterministic IDs, and honest source ranges.
|
|
44
|
+
- Specialized calls record supplied/defaulted props, generated state/ref/ID ownership, and direct links to parent, reducer, custom-hook, or Context signals.
|
|
45
|
+
- Command IR resolves owner identity per state command instead of assigning one setter-map scope to an entire handler. Mixed parent/child and nested keyed commands remain distinct.
|
|
46
|
+
- Context consumer signals point to a stable Provider source owner; repeated imported and structural specializations retain independent compile-time ownership.
|
|
47
|
+
- AST `WeakMap` indexes remain private to immediate source rewriting. They do not cross the JSON-safe source result or become a runtime component model.
|
|
48
|
+
|
|
49
|
+
### Goal A boundary
|
|
50
|
+
|
|
51
|
+
- `core.mjs` still executes transformed components at build time and allocates final route/layout state, ref, ID, conditional, and keyed ownership in the same order.
|
|
52
|
+
- Initial values, browser state IDs, complete HTML, and the serializable route plan remain authoritative runtime inputs; the component result does not duplicate them.
|
|
53
|
+
- HandlerIR, BindingIR, and DerivedIR are the planned `0.8.19` seam. KeyedBlockIR and EffectIR remain on their existing paths until `0.8.20` and `0.8.21`.
|
|
54
|
+
- No accepted syntax, public API, VDOM, hydration, component rerender, or retained browser component tree was added.
|
|
55
|
+
|
|
56
|
+
### Validation
|
|
57
|
+
|
|
58
|
+
- The complete suite passes 167/167 tests, including JSON round-trip, per-signal owner, repeated/conditional/imported state, setter adapter, ref, ID, Context, reducer, and nested keyed ownership contracts.
|
|
59
|
+
- Before release-content updates, the complete `dist` and `.kudzu` trees were byte-identical to `v0.8.17`.
|
|
60
|
+
- Worker and window graphs remain byte-identical. A same-volume 21-run interleaved comparison measured a 2.43% candidate median difference, below the 5% architecture gate; raw arrays and environment are recorded in `PERFORMANCE.md`.
|
|
61
|
+
- `create-kudzu` remains 0.1.101 because its unchanged template already accepts `@kudzujs/core@^0.8.15`.
|
|
62
|
+
|
|
63
|
+
### Upgrade
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install @kudzujs/core@^0.8.18
|
|
67
|
+
```
|
|
68
|
+
|
|
3
69
|
## 0.8.17 - Command ModuleIR
|
|
4
70
|
|
|
5
71
|
Kudzu 0.8.17 lands the first real Goal A vertical slice: supported command handlers are recognized as plain JSON-safe data, registered in a sparse per-source ModuleIR, and lowered back through focused source codegen without changing deploy output.
|
|
@@ -6,7 +6,7 @@ The top-level [`GOAL_A.md`](../../GOAL_A.md) and [`GOAL_B.md`](../../GOAL_B.md)
|
|
|
6
6
|
|
|
7
7
|
| Goal | Decision | Start condition |
|
|
8
8
|
|---|---|---|
|
|
9
|
-
| A: compiler foundation | `0.8.
|
|
9
|
+
| A: compiler foundation | `0.8.19` handler/binding/derived IR complete | Continue with `0.8.20` KeyedBlockIR ownership after the release boundary. |
|
|
10
10
|
| B: optimization benchmarks | Deferred | Goal A complete and its output baseline recorded |
|
|
11
11
|
| C: state/resource model | Research only | Reduced fixtures expose a limitation |
|
|
12
12
|
| D: routing compatibility | Current behavior preserved | Revisit only with migration evidence and invariant review |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Current Compiler Architecture
|
|
2
2
|
|
|
3
|
-
This maps the completed `0.8.
|
|
3
|
+
This maps the completed `0.8.19` handler, binding, and derived IR boundary. File and function names are the stable references; line numbers are intentionally omitted because Goal A moves code.
|
|
4
4
|
|
|
5
5
|
## Responsibility Map
|
|
6
6
|
|
|
@@ -13,11 +13,13 @@ This maps the completed `0.8.17` command ModuleIR boundary. File and function na
|
|
|
13
13
|
| Focused normalization passes | [`framework/compiler/`](../../framework/compiler/) | React, Router, browser signals, animation-frame refs, custom-hook timers, Zustand, and render control each validate and lower a narrow source shape. |
|
|
14
14
|
| Shared AST/scope helpers | [`framework/compiler/ast-helpers.mjs`](../../framework/compiler/ast-helpers.mjs) | Binding, scope, reference, effect-return, and source-location analysis. |
|
|
15
15
|
| Pure collection language | [`framework/compiler/collection-analysis.mjs`](../../framework/compiler/collection-analysis.mjs) | Analyzes collection roots/selectors and serializes the allowed pure expression language used by lists and derived dependencies. |
|
|
16
|
-
| Main semantic analysis | `framework/build.mjs`, `createKudzuTransformer()` |
|
|
17
|
-
|
|
|
16
|
+
| Main semantic analysis | `framework/build.mjs`, `createKudzuTransformer()` | Produces transformed source plus explicit component, handler, binding, and derived results while still owning effect and keyed-list ownership side tables. |
|
|
17
|
+
| Component ownership analysis | [`framework/compiler/analysis/component-analysis.mjs`](../../framework/compiler/analysis/component-analysis.mjs) | Retains ordered JSON-safe owner and specialization records for state, setters, props, refs, IDs, direct signal links, and source provenance; AST identity remains private to its source-local session. |
|
|
18
|
+
| Per-source descriptor registration | [`framework/compiler/descriptor-session.mjs`](../../framework/compiler/descriptor-session.mjs), `createSemanticArtifact()`, `createDescriptorSession()` | Keeps AST descriptors private during analysis, then finalizes deterministic JSON-safe HandlerIR, BindingIR, DerivedIR, imports, and client roots into ModuleIR. |
|
|
18
19
|
| Command IR and codegen | [`framework/compiler/optimize/command-specialization.mjs`](../../framework/compiler/optimize/command-specialization.mjs), [`framework/compiler/ir/module-ir.mjs`](../../framework/compiler/ir/module-ir.mjs), [`framework/compiler/codegen/command-codegen.mjs`](../../framework/compiler/codegen/command-codegen.mjs) | Supported command handlers specialize to JSON-safe ModuleIR, then emit the existing `__kBehavior` AST without changing route plans. |
|
|
19
20
|
| Build module generation | `framework/build.mjs`, `compile()` | Runs TypeScript with the Kudzu transformer, writes build-executable modules to `.kudzu`, rejects surviving React/Router runtime references, and generates handler source when descriptors exist. |
|
|
20
|
-
| Handler/evaluator
|
|
21
|
+
| Handler/evaluator lowering | [`framework/compiler/handler-lowering.mjs`](../../framework/compiler/handler-lowering.mjs) | Completes source-local callback/binding/list AST rewriting and diagnostics before the JSON-safe IR boundary. |
|
|
22
|
+
| Handler module codegen | [`framework/compiler/handler-codegen.mjs`](../../framework/compiler/handler-codegen.mjs) | Renders finalized ordered imports and concatenates generated module-export source without TypeScript AST or semantic discovery. |
|
|
21
23
|
| Worker graph | [`framework/compiler/worker-compiler.mjs`](../../framework/compiler/worker-compiler.mjs) | Validates the exact effect-owned Worker form, validates its relative graph, emits content-hashed ESM, and resolves placeholders only for rendered effects. |
|
|
22
24
|
| Build-time JSX execution | [`framework/core.mjs`](../../framework/core.mjs), `renderPage()` | Executes compiled pages/layouts, allocates deterministic route/layout ownership IDs, emits complete HTML, and returns the serializable route plan and capability booleans. |
|
|
23
25
|
| Route capability projection | [`framework/compiler/route-capability-planner.mjs`](../../framework/compiler/route-capability-planner.mjs), `planRouteCapabilities()` | Purely folds rendered route plans and route facts into aggregate runtime/artifact requirements. |
|
|
@@ -56,7 +58,7 @@ The browser consumes static HTML first. State seeds and descriptors in that HTML
|
|
|
56
58
|
## Current Coupling To Remove
|
|
57
59
|
|
|
58
60
|
- `createKudzuTransformer()` combines discovery, validation, specialization, descriptor registration, and transformed-source emission.
|
|
59
|
-
-
|
|
61
|
+
- Effect/keyed ownership relationships and transient component rewrite indexes remain in `WeakMap`/`WeakSet` tables keyed by AST identity; handler, binding, derived, and component ownership now have explicit JSON-safe source results.
|
|
60
62
|
- `build()` destructures a broad capability manifest into many booleans and performs artifact-specific source surgery.
|
|
61
63
|
- Runtime specialization relies on exact source-string and regular-expression replacements in `framework/build.mjs`.
|
|
62
64
|
- Route facts, rendered plans, artifact requirements, and emitted-file decisions are represented at adjacent but not fully explicit boundaries.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
4
|
|
|
5
|
-
The `0.8.
|
|
5
|
+
The `0.8.19` HandlerIR, BindingIR, and DerivedIR seam is complete. Goal A continues with the planned `0.8.20` KeyedBlockIR ownership result while preserving accepted React-shaped syntax, diagnostics, complete HTML, emitted capability behavior, and current public APIs.
|
|
6
6
|
|
|
7
7
|
## Target Boundaries
|
|
8
8
|
|
|
@@ -77,7 +77,7 @@ Analysis produces plain data:
|
|
|
77
77
|
}
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
The `0.8.
|
|
80
|
+
The `0.8.19` source result adds module-export HandlerIR, BindingIR, ordered imports/client roots, and canonical tagged DerivedIR beside command and component ownership. Source-local AST lowering completes before this boundary; artifact codegen consumes finalized records without semantic traversal. Initial values, final state IDs, effect ownership, and keyed blocks join their explicit results in later planned patches; `core.mjs` remains authoritative for route allocation today.
|
|
81
81
|
|
|
82
82
|
Source codegen lowers that data through the existing build ABI:
|
|
83
83
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Planned Version Sequence
|
|
2
2
|
|
|
3
|
-
This is an execution sequence, not release history. `0.8.16`
|
|
3
|
+
This is an execution sequence, not release history. `0.8.16` through `0.8.19` are completed scopes represented by package/release records; later rows remain planned until their package version and release record exist.
|
|
4
4
|
|
|
5
5
|
Keep each patch behavior-preserving and independently reviewable. If a boundary proves inseparable, revise this plan before combining releases; do not silently broaden a patch.
|
|
6
6
|
|
package/framework/README.md
CHANGED
|
@@ -32,16 +32,18 @@ Reduced Zustand migration stores lower to one ordinary layout-lifetime state slo
|
|
|
32
32
|
|
|
33
33
|
- `build.mjs`: TSX compilation, static, `getStaticPaths`, and runtime-fallback routes, base paths, CSS collection, post-build hooks, behavior extraction, and static HTML output.
|
|
34
34
|
- `compiler/ast-helpers.mjs`: shared TypeScript AST traversal, scope, binding, effect-return, and source-location helpers used by compiler passes.
|
|
35
|
+
- `compiler/analysis/component-analysis.mjs`: ordered JSON-safe state, setter, prop, ref, ID, and component-specialization ownership results.
|
|
35
36
|
- `compiler/animation-frame-pass.mjs`: effect-owned animation-frame ref validation and plain mutable effect-scope lowering.
|
|
36
37
|
- `compiler/browser-signal-passes.mjs`: static media-query external-store and navigator capability-condition normalization.
|
|
37
38
|
- `compiler/collection-analysis.mjs`: pure collection expression IR, selector pipeline, alias, and imported-transform analysis.
|
|
38
|
-
- `compiler/descriptor-session.mjs`:
|
|
39
|
+
- `compiler/descriptor-session.mjs`: private source-local descriptor registration and deterministic JSON-safe HandlerIR, BindingIR, DerivedIR, import, and client-root finalization.
|
|
39
40
|
- `compiler/normalization-pipeline.mjs`: ordered source normalization with parent-pointer repair after every compiler pass.
|
|
40
41
|
- `compiler/react-migration-pass.mjs`: React import, memo, callback, `forwardRef`, and `useId` migration validation and lowering.
|
|
41
42
|
- `compiler/custom-hook-timer-pass.mjs`: private custom-hook timeout-ref validation and compiler-owned timer-state lowering.
|
|
42
43
|
- `compiler/effect-codegen.mjs`: route-specific ordinary, owned, and navigable effect entry generation.
|
|
43
44
|
- `compiler/optimize/command-specialization.mjs`, `compiler/ir/module-ir.mjs`, and `compiler/codegen/command-codegen.mjs`: JSON-safe command analysis, sparse per-source ModuleIR, and source-analysis-free existing behavior-call generation.
|
|
44
|
-
- `compiler/handler-
|
|
45
|
+
- `compiler/handler-lowering.mjs`: source-local native/effect callback, reducer, Context, Zustand, reactive-binding, and list-evaluator AST lowering before IR finalization.
|
|
46
|
+
- `compiler/handler-codegen.mjs`: AST-free ordered import rendering and finalized handler/binding export-source assembly.
|
|
45
47
|
- `compiler/render-control-pass.mjs`: render-function early-return and exhaustive adjacent-assignment normalization.
|
|
46
48
|
- `compiler/router-pass.mjs`: React Router import validation and native Link, pathname parameter, search parameter, and imperative navigation lowering.
|
|
47
49
|
- `compiler/route-capability-planner.mjs`: pure route-plan projection into runtime and artifact capability requirements.
|