The Future of Etcher

TheCommieAxolotl
March 9, 2023

Until this point Etcher’s parsing/rendering process has happened fully in the Client. The client script was passed a string of XTML and registered a component.

window.etcher.transform(`<div>{{some.value}}</div>`, 'etcher-xxx');

This means that the Client bundle size was exceeding 20kb and executed some heavy Regular Expressions.


Verision 2.3.0 changes that behaviour completely. The new compiler uses html-parse-string under the hood to create an AST and output an explicit series of internal function calls.

export const props = {}

const {transform: _$transform, template: _$template, listen: _$listen, insert: _$insert} = _$etcherCore
const {onMount: _$on_mount} = etcher

const __COMP__ = (__$index__, $) => {
	const temp$ = _$template('etcher-xxx', `<div><!></div>`)

	const node$0 = temp$.childNodes[0].childNodes[0]
	_$insert('etcher-xxx', node$0, temp$, () => some.value, )

	return [temp$, ]
}

export default () => _$transform('etcher-xxx', __COMP__)

So, what does this mean?

Before these changes, etcher tried to implement fine-grained reactivity by generating a CSS selector to target an element with an interpolated expression. The new system walks down the DOM tree to accurately find the correct node.

Our new reactive system uses pseudo-signals to create a more reliable and maintainable feature.

<script>
	const {createSignal} = etcher;
	
	const [count, setCount] = createSignal(0);
</script>

/* the text node that contains count() will re-render when setCount is called */
<div>{{count()}}</div>

Syntax Changes.

This update will also bring some major syntax changes aside from the obvious removal of the {@state count = 0} syntax.

Loop

The loop directive is now written in an xml format. It can also support 2 different attribute formats.

<Loop 3>
	<p>{{index}}</p>
</Loop>
// OR
<Loop #iterations={3}>
	<p>{{index}}</p>
</Loop>

For

Like <Loop>, the for directive is also now written in an xml format.

<For label="item" #items={["item 1", "item 2", "item 3"]}>
		<p>{{item}}</p>
</For>
// OR
<For #items={["item 1", "item 2", "item 3"]}>
		/* `item` is the inferred label here */
		<p>{{item}}</p>
</For>

If

I think you know the drill by now…

<If #condition={true}>
    <p>condition is truthy!</p>
</If>

In summation, this pull request is a momentous occasion for Etcher. It re-defines how our Client script works and sows the seeds for future updates to flourish.