Releases: thesephist/torus
Minor rendering bug fixes
Besides the usual performance improvements and bug fixes (TM), this patch release addresses three rendering bugs discovered while building side projects.
Fixes
- Fix a major bug that broke templates when
jdom
tags were nested insidejdom
tags with falsy template params - Fixes in
Styled()
: when rendering nested CSS rules, nested rules should take precedence over rules on self - In
render()
: when rendering a reflected HTML attribute, first check if the property is already set, since it may trigger setters inadvertently on HTML elements like<video>
,<iframe>
, and<audio>
.
Debugging improvements
- Improve core library debugging facilities and remove potential breaking points in debugging, especially around logging replacement of nodes
Bundle size optimizations and `{replace: true}` option for Router
This update focuses on two improvements:
-
Error messages have been optimized to be equally helpful, but take up less data on the wire in a gzipped bundle.
-
When calling
Router.go(routeURL)
, we can now also pass the{replace: true}
option to replace a current history entry rather than simply appending.
Performance enhancements for styled components
This is a purely under-the-hood update that includes a significant performance improvement for Styled
components that declare styles using the css
template tag, by taking advantage of caching at multiple levels in the pipeline.
More information about this optimization can be found in 67575b7.
Easier styling with css template tag
Besides regular maintenance / dependency upgrades, this is a feature release containing one major new feature, a template tag called css
to simplify declaring styles for Styled()
components in Torus.
Like React's styled-components, the css
tag takes a template literal that contains SCSS syntax for styles, and converts it to Torus's native style format. This makes authoring style easier, currently at the cost of a bit of measurable performance hit. You can read more about this new API in the documentation page.
See the new syntax in action at https://thesephist.github.io/torus/hacker-news-reader.html
Router bugs fixed
Besides regular maintenance / dependency upgrades, this release fixes a bug in the router that previously made it possible to push the same route onto the history stack multiple times.
Maintenance update
This is a regular maintenance update with small improvements and optimizations
- Bundle size / performance improvements with terser notations around loops and redundant type casts
torus-dom
is now linted with ESLint!yarn lint
to lint the codebase
Security
- No dynamic values passed into
jdom
templates are evaluated as templates, to avoid script injection vulnerabilities. This was existing behavior, but is now made clearer in the documentation and covered by regression tests.
Collection classes enhancements, usability fixes, and optimizations
The API seems to be settling into a definite shape, so I'm anticipating that in a few more releases we'll hit 1.0, at which point most future changes will be API backwards-compatible. There is only one breaking change this release, for an internal API, and a few new APIs for collection types, Store
and List
.
API Changes
- Store class's add/remove/create methods now return the added/removed/created record, for chaining and keeping track of the added record.
- Added
Store#find
method for plucking record with a given ID from a store. - The internal
renderJDOM
function that encapsulates the vDOM reconciliation logic has been renamed torender
. This isn't a "breaking" change sincerender
isn't intended to be a public API, but is an API change worth noting. - Stores and Lists are now full ECMAScript iterables, and you can spread them (
...store
) andfor...of
loop over them!
Fixes
- Fixed broken TypeScript type definitions
- Fixed bug in routing logic where route parameters would match against an empty string, resulting in funny behavior.
Other changes
- If your custom
Component#compose()
method doesn't return valid JDOM (returnsundefined
instead), Torus now emits a more descriptive error message about invalid JDOM being returned, rather than throwing the component's vDOM into a broken state. - Optimized children render paths so there's fewer checks and newer render passes for unchanged children, resulting in faster vDOM reconciliation.
- CI setup with Travis CI for continuous build status monitoring.
Faster rendering, Typescript support, and Bundling
There's been lots of work since the last release, but this release focuses on three big things: a few new APIs, minor bug fixes, and meaningful performance optimizations across the board.
API changes
- Components used as
itemClass
for a list are now passed a second argument to the constructor, which is the callback used to remove the item from the list and the backing store. - Components used as
itemClass
for a list are also transparently passed through any extra nth arguments passed to the list constructor, as n+1th arguments to the item class constructor. - Torus now exports all the APIs through two globals,
Torus
andjdom
, when loaded using a<script>
tag, and exports all APIs correctly (and also installs and builds correctly) when installed using NPM and bundled with Webpack or another bundler.
Fixes and improvements
- Fixed bugs around styling. Specifically, comma-separated CSS selectors in
Styled()
components are now parsed correctly - Fixed bugs that broke the renderer when a
Node
or text elements were rendered as the root node of a component multiple times. - The rendering and reconciliation algorithm was refactored to more easily support asynchronous rendering (React calls this "concurrent" rendering in React Fiber), should Torus want to support that in the future. Before, splitting up render work in
requestIdleCallback
calls would throw. - Improved debugging statements in development mode, especially around rendering children elements.
- Typescript type definitions are now bundled in the package!
Performance
- The renderer now doesn't touch expensive DOM traversal operations until the very end, when committing changes to the DOM. This makes rendering 20-40% faster than before.
- Other parts of the renderer have also been rewritten or refactored to make it interact with the DOM less, take up less bytes on the wire, or run faster without any API changes.
- The
jdom
template tag has received a host of optimizations to make it quicker as well. - The entire bundle is still well under 5kB gzipped, giving you a good performance budget.
Templating performance improvements
Besides resolving some pesky rendering bugs, the templating code has been rewritten/rearchitected in some major ways to be:
- More robust. Rather than parsing the template dynamically, we parse a string version of it and replace in template values, which makes it more resilient to error conditions.
- Much faster. Rather than re-parsing the template each time like in
v0.1.1
, Torus now caches each template the first time it parses it, and on subsequent renders it just takes the dynamic parts of the template and slots it in in the right places, making renders faster. - Smaller. The total bundle size for all features of Torus remains well under 5kb.
Along with this release, some bug fixes have also been deployed to torushn.surge.sh
, the Hacker News reader demo, that addresses aforementioned rendering / reconciliation algorithm bugs and rendering speed.
Initial release
This is a beta release of Torus that's being used with the hacker news demo site. The API is hopefully stable, and most of the major bugs have been worked out, but it's definitely not production ready and I'm hoping to iron out some of the smaller bugs as I built more complex apps with it leading up to a 1.0.
You can find the full API documentation in the repo README. This release contains torus.min.js
, which is the framework, minus the template tag, and index.min.js
which contains the full bundle which is ~4.5kb gzipped.