Skip to content

v0.2.0

Choose a tag to compare

@joe-dakroub joe-dakroub released this 04 Aug 20:11

Two things that were rendering the wrong output are compile errors now, and a
config that names only what it changes finally works.

Both packages move together: @transclude/core and @transclude/create are
0.2.0.

npm install @transclude/core@latest

Before you upgrade

Two new compile errors. If your build passes, nothing here changes what it
produces.
If it fails, it was producing something you did not ask for.

An interpolated attribute name is refused.

<div ${name}="x"></div>

An attribute name is written out as it stands, so this reached the page as the
five characters ${name} rather than a value. No error, no warning, a page that
looked fine until somebody read the output. It was the only interpolation
mistake here that did not fail. To choose between two spellings, put the
condition in the value: class="${done ? 'a' : 'b'}".

A <script server> block cannot bind a name the generated module already
defines.

import { elements } from '../data/elements.js';

elements is one of the names a compiled page exports, so this broke the build
inside the bundler, pointing at a virtual module rather than at anyone's file.
The check was already there for exports; an import binds a name and exports
nothing, so it walked straight past. Rename or alias it. The reserved list is
css, load, render, renderHead, renderTitle, renderHtmlAttrs,
layouts, client, elements, headScript, hasTitle and includes.

Fixed

A config gets the documented defaults. appDir, routesDir, elementsDir,
publicDir, outDir, typesFile, stylesheet, lang, fragmentParam,
trailingSlash, strict, csrf and csp were written in the documentation as
defaults and applied nowhere. A config leaving outDir out reached
path.join(root, undefined) and threw ERR_INVALID_ARG_TYPE, naming neither
the key nor the file. Every starter template sets all of them, which is why this
survived.

A top-level <script src> in a page reaches the page. It was read as a
client block, which made it an empty one, and the tag was dropped with its
src. The page rendered and the script it asked for was simply absent. A src
means there is no code to compile, so it is markup. A nested one always was.

A loader that can answer with a Response still types its own template.
Returning Response.redirect(...) from a layout is the documented way to write
a guard, and doing it made every name in that layout's markup an error about a
union the template can never be handed. ctx.action has excluded Response
since it was written; a loader does now too.

Also

Seven new example apps, each an ordinary project you can copy out of the
repository: TodoMVC with nothing but forms, a prerendered blog with a sitemap
and a feed, search over a fragment, the same search driven by htmx, transclusion
from three sources, a guarded section with a signed-cookie session, and a board
that updates itself over server-sent events.

New documentation for recipes, examples, contributing, and the parts that had
none: what an attribute value does, what the directives are, revalidate and
tags, and an endpoint that answers with a stream.

Full documentation at transclude.dev.

A note on the version

Below 1.0, a minor may break something. These two do, in the sense that a
build which passed can now fail. Both were turning a mistake into wrong output
rather than into a message, so the change is the point rather than a cost.

Full changelog: v0.1.1...v0.2.0