kerfjs 0.2.0 → 0.2.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/CHANGELOG.md CHANGED
@@ -4,6 +4,11 @@ All notable changes to **kerf** are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.2.1] - 2026-05-07
8
+
9
+
10
+ - Add `Fragment` export to the `kerfjs` barrel for explicit JSX fragment usage
11
+
7
12
  ## [0.2.0] - 2026-05-07
8
13
 
9
14
 
@@ -25,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
25
30
 
26
31
  ### Fixed
27
32
 
33
+ - **`Fragment` was missing from the `kerfjs` barrel (KF-24).** `Fragment` was implemented in `src/jsx-runtime.ts`, exported from `kerfjs/jsx-runtime`, and present in the shared chunk — but the barrel `src/index.ts` didn't re-export it. Importing `Fragment` from `'kerfjs'` resolved to `undefined`, so a manual `<Fragment>...</Fragment>` rendered as `<undefined>...</undefined>`. The `<>...</>` shorthand was unaffected because the JSX transform pulls `Fragment` from `kerfjs/jsx-runtime` directly. Added `Fragment` to the barrel re-export, and pinned the entire public-API contract with a new `tests/dist/barrel-completeness.test.ts` so any future omission fails CI loudly. Docs updated to list `Fragment` in the public API surface (`CLAUDE.md`, `llms.txt`, `docs/ai/usage-guide.md`, `docs/ai/code-summary.md`, `docs/6-jsx-runtime.md`, `docs/8-api-reference.md`).
28
34
  - **Focused contenteditable was being morphed, clobbering in-progress edits (KF-19).** The docs claimed contenteditable elements got focus + selection preservation alongside `<input>` and `<textarea>`, but the implementation only handled the latter two — a focused contenteditable's typed content was overwritten by morphdom on the next re-render. `mount()` now short-circuits the morph entirely when the active element is a contenteditable (same mechanism as `data-morph-skip`), so the user's edit, caret position, and any multi-range selection survive verbatim. Attribute updates are deferred until the next render after blur — that's the explicit trade-off, and matches what you want for in-progress rich-text editing. `docs/4-render.md` §4.4 and `docs/8-api-reference.md` §8.7 updated to describe the per-element-kind behaviour. The check uses the `contenteditable` attribute directly (the spec's source of truth) rather than the derived `isContentEditable` property, so test environments that don't populate the latter still get correct behaviour.
29
35
  - **`clearStoreRegistry` was a no-op in the published bundle (KF-15).** `dist/testing.js` shipped an empty function body. Root cause: `tsup` bundled each entry independently with `splitting: false`, so the testing entry tree-shook the module-level `REGISTRY` array out as unreferenced — leaving `REGISTRY.length = 0` as dead code. Same root cause as KF-14. Fixed by enabling `splitting: true` in `tsup.config.ts`: shared modules now live in chunk files that all entries import, so `defineStore`'s registry and `clearStoreRegistry`'s reference are the same array. Side benefit: the duplicate `SafeHtml` class definition is gone too — there's now exactly one copy across the whole dist. Build output now includes `dist/chunk-*.js` files (covered by the existing `"files": ["dist"]` in `package.json`). New regression test in `tests/dist/store-registry-shared.test.ts` exercises the cross-entry registry from the built bundles.
30
36
  - **`SafeHtml` cross-bundle identity (KF-14).** When a consumer's bundler ended up loading two copies of kerf — for example, the barrel (`kerfjs`) and the JSX-runtime entry (`kerfjs/jsx-runtime`) resolving as separate modules — `instanceof SafeHtml` failed inside the JSX runtime because the two `SafeHtml` classes were structurally identical but referentially distinct. The renderer would then throw `JSX: unsupported child of type object (SafeHtml)` on perfectly valid JSX. `SafeHtml` instances now carry a `Symbol.for('kerfjs.SafeHtml')` brand and the runtime checks for the brand instead of using `instanceof`. New unit tests simulate the duplicate-class scenario, and a new `npm run test:dist` job exercises the actual built bundles in CI.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { SafeHtml } from './jsx-runtime.js';
2
- export { isSafeHtml, raw } from './jsx-runtime.js';
2
+ export { Fragment, isSafeHtml, raw } from './jsx-runtime.js';
3
3
  export { ReadonlySignal, Signal, batch, computed, effect, signal } from '@preact/signals-core';
4
4
  export { S as Store, d as defineStore, r as resetAllStores } from './testing-CdMgVVoI.js';
5
5
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isSafeHtml } from './chunk-URMYMSGU.js';
2
- export { SafeHtml, isSafeHtml, raw } from './chunk-URMYMSGU.js';
2
+ export { Fragment, SafeHtml, isSafeHtml, raw } from './chunk-URMYMSGU.js';
3
3
  import { effect } from './chunk-IZJIKRCE.js';
4
4
  export { batch, computed, defineStore, effect, resetAllStores, signal } from './chunk-IZJIKRCE.js';
5
5
  import morphdom from 'morphdom';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kerfjs",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Tiny reactive UI framework — fine-grained signals + DOM morphing + JSX. Apply the smallest possible cut to update your DOM.",
5
5
  "type": "module",
6
6
  "sideEffects": false,