Releases: ryansolid/dom-expressions
v0.23.0
- Change SSR key to data-hk to pass HTML validation
- Simplify component spreads removing extra wrappers with flag
- Typedefs for role attribute
- Add web stream API (support Cloudflare Worker streaming)
- Remove extra function wrappers on DOM insert expressions when simple function call signal() becomes signal instead of () => signal()
v0.20.0
v0.19.0
- Fixes to handling to static expressions in textNodes
- Better attribute handling to handle attribute removal
- Optimize function refs
- Improve SSR performance
- Fix CSS property Types
- Add basic support for JSX attribute namespaces
- Fix HyperScript when given null props
v0.18.0 - String SSR
This release represents a complete restructure of the project. Both for handling multiple render targets for the Babel plugin, and to move away from EJS for building the runtime. Instead using Babel to rewrite the entry. This drastically simplifies the process of using it.
Breaking Changes
- Runtime methods have been renamed, and method of using the runtime is completely different.
- removed
forwardRef
and merged the functionality withref
. - New approach to TypeScript involving packaging with library rather than shipped with Babel Plugin.
- Changed Babel Plugin generate options. Old DOM SSR is "dom-ssr".
New Features
- String SSR
Fixes
- Support for hyphenated attributes on components
- Fixed attributes in spreads
v0.17.0
Breaking Changes to Event System
- Removed casing consideration. All
on____
events handled the same. If they are not non-composable or non-bubbling they will be delegated by default otherwise level 1 events. - Renamed the
events
binding as theon
binding. This adds typical level 3 event handlers for irregular events or events you do not wish to delegate. - Removed model mechanism. Bound events are now using an array syntax inspired by Inferno
[handler, boundValue]
where the handler takes the boundValue as the first parameter and the event as the second.
Other Improvements
- Drastically shrunk list reconciler based on udomdiff
- Changed template checking method to count tags instead of string compare to reduce false warnings.
- Improved ternary heuristics to reduce unnecessary wrapping.
- Added the static
@once
indicator to force not wrapping expressions.
v0.15.0
A lot of updates and tweaks since the last minor version:
- Update SSR:
- use async capable
renderToString
method - Provides a generator for script for event capture for progressive hydration
- use async capable
- Update hydration:
- Support multiple contexts (partial hydration)
- Event capture and replay (progressive hydration)
- Support for ternaries and binary operators in JSX templates
- Better
classList
binding performance - Better handling of
children
in spreads - Pass props to render function in class components
v0.14.0
v0.13.0
Breaking Change - Removal of Explicit Binding "Parens" Syntax
The new heuristic for how bindings will be reactive will work as follows:
There are certain types of syntax that will never be reactive like function declarations, literal values.
// these bindings never need to be wrapped
<div onClick={() => setState({clicked: true})} name={"mydiv"} />
Similarly since reactivity requires access only function calls or property accesses can be reactive. So simple variables will never need to be wrapped
// also never needs to be wrapped
<div name={myName} maxlength={count * 2} />
So we can limit wrapping to only expressions that could be reactive like:
// wrap because they could be reactive
<div name={props.name} title={getTitle()} />
Also for Component props that take Components like fallback
or children
we will wrap any expression with a tag to allow deferred evaluation.
// these will be wrapped
<Show when={state.accepted} fallback={<Denied />}>
<Accepted />
</Show>
What if you wish for these things to be static? Hoist the value access. Since normal variables aren't reactive just assign it to a variable. This is JSX so we have all the power of JavaScript at our side and do not need a special syntax.
const name = props.name;
// not wrapped as simple variable
<div name={name} />
v0.12.0
v0.11.0
Major Breaking Changes
This release removes several features by taking a fundamental architecture switch. Overall this is a huge simplification and code reduction.
Removing Control Flow
Instead of hard compiling Control Flows, the library is putting the work on Components in userland. This is infinitely more flexible and opens up different solutions to fit the library that uses it. It meant beefing up the core reconciler to be able to handle pretty much whatever gets thrown at it.
Fragments as Arrays
Document Fragments have this pesky characteristic of losing their child nodes. Using arrays is a must if you wish to retain references and pass them around. Which is necessary change if control flow is outside of the main library. This reduces the Node creation in many places, but it also means multi-nested fragments end up getting reconciled all at the same time on update. So there are some performance characteristic changes.
insert
at entry
With these changes, the returned code from JSX is no longer guaranteed to be a DOM node. It may be an array or a function. In so if you use top-level child components or fragments your mount method should use insert
to ensure different inputs are handled properly.
props.children
changes
Now when you pass a single child you get a single value and multi-children are represented as arrays. This is consistent with how React handles children and allows a lot of different capacities for Component design. JSX element children by default are handled as dynamic and are lazily evaluated. Allowing for more powerful templating with Components.
Removing Custom Directives
Also, custom directives have been removed. They were a confusing alternative way to do things and did not play well with Typescript. Using forwardRef
can achieve the same thing. The naming is under consideration and whether the library should be concerned with multiple instances on the same element (technically it works).
Better TypeScript support
Removal of Control Flow, Custom Directives, and consistent handling of JSX Children all improve TypeScript support.
Wide Open Future
While on the surface many of these changes may seem like detractors this widely opens up the ecosystem. Components or custom methods can benefit from all the performance capable here. The reactive system feeds into the renderer instead of being so closely entwined. It makes custom logic much simpler to write in the libraries without having to worry about markers and node ranges.
Look forward to updates in related Libraries over the coming weeks.