@kudzujs/core 0.8.0 → 0.8.1

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
@@ -10,7 +10,7 @@ Kudzu compiles ordinary React-shaped TypeScript and TSX into complete static HTM
10
10
 
11
11
  > Experimental `0.8.x`: the compiler API and supported TSX surface may change.
12
12
 
13
- **Latest release: 0.8.0 - URL-backed custom hooks.** Relative React custom hooks, reachable source graphs, imported structured calculations and static collections, event-only package ESM, and native SVG now compose across a fourteen-route FIRE migration without adding React or a hook runtime. Read the [release notes](./RELEASES.md#080---url-backed-custom-hooks) or open the [release page](https://kudzujs.cloud/releases/0.8.0).
13
+ **Latest release: 0.8.1 - Custom-hook reset actions.** Relative custom hooks can batch direct primitive state resets into one behavior command, including imported negative and null literals, while dependent URL and storage effects observe the same commit. Read the [release notes](./RELEASES.md#081---custom-hook-reset-actions) or open the [release page](https://kudzujs.cloud/releases/0.8.1).
14
14
 
15
15
  - [Documentation](https://kudzujs.cloud/docs)
16
16
  - [Installation guide](https://kudzujs.cloud/docs#install)
package/RELEASES.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Kudzu Releases
2
2
 
3
+ ## 0.8.1 - Custom-hook reset actions
4
+
5
+ Kudzu 0.8.1 compiles direct multi-state reset callbacks returned by relative custom hooks into one existing behavior command, keeping conventional hook ownership without adding a callback runtime.
6
+
7
+ ### New in 0.8.1
8
+
9
+ - Returned custom-hook callbacks may reset their exposed state/setter pairs to direct string, number, negative-number, boolean, or `null` literals in one batched commit.
10
+ - Imported callback literals are synthesized before command emission, fixing source-range corruption when optimized behavior commands originate in another module.
11
+ - The FIRE Standard calculator now owns its twelve-field reset inside `useStandardParams()`; existing dependency effects update URL parameters and local storage after the same commit.
12
+ - A React/Vite migration fixture verifies exact optimized command output plus browser updates for multiple reset values.
13
+ - Static routes and routes without reset actions add no JavaScript or runtime capability.
14
+
15
+ ### Boundary
16
+
17
+ Reset callbacks may capture only directly returned state/setter pairs and use direct literal setter calls. Private defaults, helper-indirect setters, dynamic values, timers, clipboard work, aliases, and arbitrary callback graphs remain unsupported.
18
+
19
+ ### Upgrade
20
+
21
+ ```bash
22
+ npm install @kudzujs/core@^0.8.1
23
+ ```
24
+
3
25
  ## 0.8.0 - URL-backed custom hooks
4
26
 
5
27
  Kudzu 0.8.0 migrates practical relative React custom hooks that combine local state, effects, direct actions, writable URL search parameters, and guarded browser storage while preserving static HTML and route-specific capabilities.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Kudzu specializes ordinary common React-shaped TSX so migrations need minimal source restructuring. Declarative components, collection pipelines, conditions, hooks, and handlers should be lowered at build time rather than replaced with application-owned imperative DOM code. This principle applies across migrations and is not Stay-specific; it does not imply a React package, VDOM, hydration, or ecosystem runtime.
4
4
 
5
- Migration source may retain conventional `react` imports for supported named or aliased hooks, direct members such as `React.useState`, same-file `memo`, inline `useCallback`, direct-state expression or analyzable collection-pipeline `useMemo`, direct intrinsic `forwardRef`, top-level `const` identifiers initialized by `useId()`, and default, namespace, or named `Fragment`. A named or default zero-argument custom hook imported from a relative TypeScript module may return direct shorthand state/setter pairs and callbacks that capture those states; callers use one top-level `const` object destructuring without aliases, defaults, or rest. Kudzu's JSX declarations accept ReactNode-shaped component returns and contextually type common intrinsic DOM events, so strict React component props do not need migration-only `unknown` or explicit event annotations. `forwardRef()` accepts one inline synchronous `(props, ref)` function and requires the object ref exactly once on its direct intrinsic root; the compiler removes `ref` from props/rest and erases the wrapper. `useId()` becomes a deterministic build-time HTML ID and emits no browser capability; keyed rows reject it because cloned row templates cannot safely duplicate HTML IDs. Collection memos may start from local array state or a named relative import of an exported JSON-safe `const` array, including type-only `as const` and `satisfies` wrappers, and may read direct local state declared in their dependency array. `build.mjs` canonicalizes those forms and rewrites module references to `@kudzujs/core` before build-time evaluation. Memo wrappers are erased or inlined into existing bindings and keyed-list selectors because no browser component rerender or memo cache exists. Static routes remain JavaScript-free and emitted modules are checked for surviving React imports.
5
+ Migration source may retain conventional `react` imports for supported named or aliased hooks, direct members such as `React.useState`, same-file `memo`, inline `useCallback`, direct-state expression or analyzable collection-pipeline `useMemo`, direct intrinsic `forwardRef`, top-level `const` identifiers initialized by `useId()`, and default, namespace, or named `Fragment`. A named or default zero-argument custom hook imported from a relative TypeScript module may return direct shorthand state/setter pairs and callbacks that capture those states, including a callback that resets multiple states to direct primitive literals; callers use one top-level `const` object destructuring without aliases, defaults, or rest. Kudzu's JSX declarations accept ReactNode-shaped component returns and contextually type common intrinsic DOM events, so strict React component props do not need migration-only `unknown` or explicit event annotations. `forwardRef()` accepts one inline synchronous `(props, ref)` function and requires the object ref exactly once on its direct intrinsic root; the compiler removes `ref` from props/rest and erases the wrapper. `useId()` becomes a deterministic build-time HTML ID and emits no browser capability; keyed rows reject it because cloned row templates cannot safely duplicate HTML IDs. Collection memos may start from local array state or a named relative import of an exported JSON-safe `const` array, including type-only `as const` and `satisfies` wrappers, and may read direct local state declared in their dependency array. `build.mjs` canonicalizes those forms and rewrites module references to `@kudzujs/core` before build-time evaluation. Memo wrappers are erased or inlined into existing bindings and keyed-list selectors because no browser component rerender or memo cache exists. Static routes remain JavaScript-free and emitted modules are checked for surviving React imports.
6
6
 
7
7
  Compilation begins from page entries and follows relative runtime imports, re-exports, and validated Worker references; unreachable TypeScript migration files are not transformed. Direct maps over imported immutable JSON-safe arrays fold to literals for zero-JavaScript static rows. Synchronous relative calculation functions may return objects whose direct static fields feed reactive JSX bindings; build rendering uses current signal values and route-specific binding ESM reevaluates the same helper after state commits. Package imports have a separate narrow boundary: direct references inside intrinsic JSX event callbacks are erased from build modules and bundled into route handler ESM, while render-time, effect, helper-indirect, and mixed package use fails.
8
8
 
@@ -6136,7 +6136,7 @@ function scopeRead(factory, name) {
6136
6136
 
6137
6137
  function compileEventCommand(expression, setters, factory) {
6138
6138
  if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression) && ts.isIdentifier(expression.expression.expression) && expression.expression.expression.text === "console" && expression.expression.name.text === "log" && expression.arguments.length === 2 && ts.isStringLiteral(expression.arguments[0]) && ts.isIdentifier(expression.arguments[1]) && [...setters.values()].includes(expression.arguments[1].text)) {
6139
- return command(factory, "log", expression.arguments[1], expression.arguments[0])
6139
+ return command(factory, "log", expression.arguments[1], factory.createStringLiteral(expression.arguments[0].text))
6140
6140
  }
6141
6141
 
6142
6142
  if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.arguments.length !== 1) return undefined
@@ -6153,7 +6153,7 @@ function compileEventCommand(expression, setters, factory) {
6153
6153
  if (value.body.operatorToken.kind !== ts.SyntaxKind.PlusToken && value.body.operatorToken.kind !== ts.SyntaxKind.MinusToken) return undefined
6154
6154
  return command(factory, "add", state, numericExpression(factory, Number(value.body.right.text), value.body.operatorToken.kind === ts.SyntaxKind.MinusToken))
6155
6155
  }
6156
- if (isPrimitiveLiteral(value)) return command(factory, "set", state, value)
6156
+ if (isPrimitiveLiteral(value)) return command(factory, "set", state, synthesizeSerializableStateLiteral(value, factory))
6157
6157
  return undefined
6158
6158
  }
6159
6159
 
@@ -6162,7 +6162,7 @@ function command(factory, operation, state, value) {
6162
6162
  }
6163
6163
 
6164
6164
  function isPrimitiveLiteral(node) {
6165
- return ts.isStringLiteral(node) || ts.isNumericLiteral(node) || node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword
6165
+ return isPrimitiveDefaultLiteral(node)
6166
6166
  }
6167
6167
 
6168
6168
  function numericExpression(factory, value, negative) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kudzujs/core",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "HTML-first TSX framework with synchronous state semantics and no virtual DOM",
5
5
  "type": "module",
6
6
  "license": "MIT",