SvenJS 3.4.0 improves component method typing and fixes lifecycle ordering, failed-render recovery, controlled forms, and playground module execution. Existing component APIs remain compatible.
npm install svenjs@3.4.0Added
create({...})infers declared instance method arguments and return types. Explicitcreate<Props, State>remains compatible; an optional third method type is supported bycreateandComponentSpecwhen strict explicit signatures are needed.pnpm benchbuilds the production library and measures 68 list, batching, store and SSR cases with 100/1,000 items. Reports include environment, artifact hash, raw samples and percentiles, without CI timing thresholds.
Fixed
flushSyncnow drains updates scheduled during the same flush — e.g.setStatefromonUpdateor a store notification is applied beforeflushSyncreturns, instead of deferring to a microtask. Flushes cap at 50 passes and defer the remainder; components mounted mid-flush runonMountbefore a later pass can fire theironUpdate.- Each flush pass finishes its DOM commit before the next pass. Nested flushes preserve pending outer mount hooks, and roots created by
onMountinitialize before their queued updates run. - Unkeyed list matching no longer scans the old child list per new child; matching is linear in list length with identical pairing semantics.
- A spec can no longer overwrite internal instance fields (
_dirty,_mounted,_vnode, …) ortype/state/propsduringcreate. Destroyed instances release their parent node reference. - Failed root renders and hydration clear partial trees and release their refs, subscriptions and instances. Failed component patches retain the owner and an empty placeholder for a later state update; successful independent nested roots keep their mount hooks.
- Ref cleanup tracks the callback actually attached to each element, and shared instances are destroyed only once when recovering overlapping old and new trees.
- List updates finish all teardown and commit the resulting tree before reporting cleanup errors.
- Explicit
ComponentSpec<Props, State>annotations retain typed state and support extra instance methods. - Hydration restores controlled input values and checked state even when server attributes already match.
- Playground clipboard/export status is separate from code errors; delayed sharing cannot restore an older example, and missing clipboard support is handled.
- SSR select context is local to each render, including failed and reentrant renders. Component-generated option text is matched without rendering twice.
- Ignored raw-HTML children receive no ref teardown. State documentation now correctly allows cyclic structures.
- Playground sources compile JSX and TypeScript with Sucrase and run as native ES modules. An inline import map resolves SvenJS to the bundled runtime, including offline exports; namespace, mixed, side-effect and dynamic imports plus
export/export defaultwork without colliding with localrequire,exportsormoduledeclarations. A shared link whose code fails to compile shows an error in the preview instead of crashing the app shell. - Router and docs metadata tolerate malformed percent-encoded paths instead of throwing. Anchors without
hrefbypass SPA navigation. The hello examples carry the SvenJS credit chip.
Verification
- All five playground examples have offline file export tests in Chromium, Firefox and WebKit, including interactions, inlined runtime/CSS and the visible versioned credit chip.
- Full verification reuses its completed site build for e2e; standalone
pnpm test:e2estill builds first. - Packed consumers exercise production/development ESM and JSX entries, strict NodeNext/Bundler types with both automatic JSX modes, and the actual production/development IIFEs in Chromium, Firefox, and WebKit.
- CI and release run the same full verification including e2e and release-tag/package/runtime/starter version checks. Local publishing uses the same verification.
Release validation
pnpm verify: 124 runtime tests and 75 end-to-end tests passed, with Chromium, Firefox, and WebKit coverage.- Packed package consumers passed production/development ESM, JSX, NodeNext/Bundler TypeScript, and browser IIFE checks.
- Release-tag validation passed for
v3.4.0. npm publish svenjs-3.4.0.tgz --dry-run --ignore-scripts --access publicpassed; the archive contains 26 files (107.8 kB packed).- Production IIFE: 6,129 bytes gzip, within the 6,144-byte budget.
Full changelog: https://github.com/robbestad/svenjs/blob/012e2701b3589b953732b55d0332c9a69386dd16/CHANGELOG.md