Skip to content

slate 0.0.28 — the client-side gap

Choose a tag to compare

@edadma edadma released this 05 Sep 09:14
· 81 commits to dev since this release

The client-side gap. slate could build a page and could not read one; it can now, which is what
makes hydration possible — and a link behave like a link.

Behaviour changes

A call the program wrote is strict on both back ends. The JavaScript back end checked no arity at
all: f(1, 2) to a one-parameter f dropped the 2 and ran. It is a fault now, as it always was
under the interpreter. A function with no parameters carried no signature at all, which is why a
component given props was the silent case.

A native calls your function with as many arguments as it declares. on(node, "click", () -> …)
is what a person writes and now what runs; declaring more than the native has is a fault naming the
native. The checker follows the machine through a seam, fits_callback, so a program-declared
(integer, integer) -> integer still refuses n -> n.

A browser's print is the print dialog, and slate was reaching for it. A page's every
print("hi") opened a printer chooser and wrote nothing. It writes to the console now. A document is
what tells a browser from quickjs, whose print is a writer.

Connecting to a literal address no longer touches the resolver. connect("127.0.0.1", p) asked
getaddrinfo what 127.0.0.1 means — a call of unbounded latency in front of a connection whose
destination was never in doubt. Anything inet_pton refuses still goes the long way, so 127.1 and
2130706433 are unchanged.

slate:dom can read a page

children(node), tagName(node), nodeText(node) and attribute(node, name). Every one of the
module's thirteen document names either made a node or changed one, so a framework adopting markup a
server rendered had nothing to walk it with.

A handle for an element the program never created is not a new kind of value — byId and query
have minted one since the module shipped — so this is the read side of an arrangement that already
existed. children answers every child node and not only the elements, because a text node between
two elements is a position; tagName answers null for one, which is how the two are told apart;
attribute answers true for a bare attribute, which is the reading setAttribute writes.

parent, the siblings and an innerHTML reader are deliberately absent: a page is walked downwards
from something the program already holds.

lath 0.3.0 is what this is for: hydrate(el, host)
adopts a server's markup instead of rebuilding it, and makes no DOM mutations at all — measured
with a MutationObserver rather than asserted.

A click says which button and which modifiers

mods{ meta, ctrl, shift, alt } — and button join type, value, checked, key, stop
and prevent on the record a handler is given.

A link cannot be written without them. A framework intercepting a click has to let a cmd-click, a
ctrl-click, a shift-click and a middle click through to the browser, and until now it could not tell
any of them from a plain click — so a router would have swallowed the most ordinary thing anybody
does to a link.

slate:url

percentDecode, encodeComponent, parseQuery and parsePairs, in a module of their own.

They were slate:http's, exported from it with a comment saying a framework over that module needs
the same decoder its router uses. That was true and it was not enough: the JavaScript back end
emits the whole of an imported module
, so a browser page importing slate:http to reach two of
them went from 340,761 bytes to 579,710 — a file server and an HTTP/2 speaker downloaded to read a
query string.

slate:http imports them back and exports all four under their old names, so nothing written against
it changed. Import them from slate:url in anything that is not a server.

Also in this release

The OWED list is checked as three sets, which found five natives that were in neither the runtime
nor the list. A diagnostic about a function names it. slate:gzip, fetch, the ws client and the
calendar are all whole under slate js — see the parity
page
.