Skip to content

@marko/runtime-tags@6.4.2

Choose a tag to compare

@github-actions github-actions released this 05 Oct 23:52
· 8 commits to main since this release

Patch Changes

  • #4401 9411bbe Thanks @DylanPiercey! - Call the change handler when assigning a name destructured from a property another destructure also declares, such as b in <const/{ a }=input> beside <const/{ a: b }=input>. The second name is read as the first, so assigning it now assigns the first, where it used to compile to a value that went nowhere. A property destructured by a string key, such as "my-key", also no longer produces an invalid server destructure for its change handler.

  • #4406 9d7a771 Thanks @DylanPiercey! - Write the assets a lazily loaded tag needs where nothing removes them. Those found before the page's <head> renders go in it, or ahead of the first flush on a page without one, so a lazily loaded layout's assets no longer precede its doctype. After that they're written where the tag renders, and when that content may be removed (by a @catch, by the body replacing a @placeholder, or by client control flow), its stylesheets are also copied into the <head> so the tag stays styled when it renders again. A tag whose assets or load trigger a @catch dropped writes them again. Assets used to be written all at once where the first lazy tag rendered, so a @catch replacing that content could drop the page's entry script, and the stylesheets, modules and load triggers other instances of the tag needed. A load trigger now inserts its module into the <head>.

  • #4400 6bba1bc Thanks @DylanPiercey! - Leave nothing of a caught <try> body live after the page resumes. Sections the body rendered before its @catch fired no longer stay subscribed to closures, which threw on the client once the closure changed. A @catch that renders after its <try> already streamed is no longer treated as a <try> itself, so an error thrown in it reaches the enclosing @catch instead of re-rendering the same @catch.

  • #4402 b6486e9 Thanks @DylanPiercey! - Fix Tags API <try> content rendered with Class API components on the server. Tags API content inside a Class API component now stops rendering when a <try> around it catches, at any depth and even when it was still awaiting, instead of sending its data and effects for content that never arrived, and its effects wait for in-order content still streaming and drop with a @catch, like any content around them. A Class API component's init code no longer takes the page's out-of-order content with it, which lost a @catch sent after its body streamed and ran its effects early. On a Class API page, a Tags API @catch that waits on content of its own now shows, streamed after the markers it replaces even while a pending Class API <await> holds them back.

  • #4410 7756061 Thanks @DylanPiercey! - Write a Class API lazy tag's assets through the Tags API writer when it renders within Tags content. It used to write every pending asset inline, the page's entry script included, so a Tags @catch that replaced that content left the page unable to hydrate, and the lazy module could be lost for other instances of the tag.

  • #4405 bbd3f8c Thanks @DylanPiercey! - A toggled class may not repeat a name the rest of its class value writes: class=["a", { a: on }] is now a compile error, and a stylesheet module read that repeats one only while rendering throws in development. In exchange the client toggles single classes instead of rewriting the attribute: class=["a", on && "b"] and computed keys such as { [KEY]: on } now toggle b, keeping a in the template.

  • #4395 2166e2a Thanks @DylanPiercey! - Keep the effects of content streamed before a <try> when its @catch replaces a body that was still streaming, including lazily loaded content and content a @placeholder swapped in meanwhile. The caught body's own effects, lazy content and placeholders still drop, and so now do those of a caught <try> inside content streamed out of order. Effects written by the page before lazily loaded content that holds the stream now run with the page, instead of waiting for that content's module. Held effects of lazily loaded content now run in stream order.

  • #4408 98e6b85 Thanks @DylanPiercey! - Keep a <try>'s @placeholder until a lazily loaded tag in its body has inserted when the tag's module was already loaded, for example by the same tag in the placeholder, but its input was not. The body used to swap in before the tag's content, running its effects early. A lazily loaded tag also no longer throws NotFoundError on the client when its input lands after the <try> around it moved its content to show or dismiss the placeholder.

  • #4409 b78fd9c Thanks @DylanPiercey! - Resolve a lazily loaded tag's assets through the asset runtime its importing template passes, instead of one only a page entry of the same API sets. A Class API lazy tag no longer throws assetFlush is not a function on a Tags API page, and a Tags API lazy tag no longer renders nothing on a Class API page.

  • #4403 7f17150 Thanks @DylanPiercey! - Fix Unable to serialize a value shared between independently lazy loaded content when a @placeholder shares a value with a lazily loaded tag in it or before it. The placeholder's data now serializes first, and the lazy tag reads the value back from it.

  • #4396 7a7c6ac Thanks @DylanPiercey! - Read a tag variable's property from its object once any code assigns that property in place, such as live.open = true or box.count++. Reads used to go through a copy of the property taken when the variable itself last changed, so a handler, <lifecycle> listener or <script> reading it after another one assigned it saw the old value. This includes a name destructured from the variable, such as open in <const/{ open }=live>, and properties assigned deeper in, such as live.nested.depth = 2.

  • #4404 eeabb88 Thanks @DylanPiercey! - Let a <define> that calls itself, or a template that renders itself, pass its input per prop once its body is analyzed. A whole read of the input that nothing ends up using, such as an unread <const/all=input>, used to make the inner call build and pass one object through an extra intersection.

  • #4396 7a7c6ac Thanks @DylanPiercey! - Report a compile error when code assigns a rest element, such as rest in <const/{ ...rest }=input.obj> or args in <for|...args| of=list>. A rest has no change handler to receive a new value, so the assignment used to compile into one that did nothing. Assigning a member of a rest taken beside other names, such as rest.b = 5 with <const/{ a, ...rest }=input.obj>, is also an error: that rest is a copy rebuilt whenever its source changes, so later reads never saw the assignment.

  • #4398 0e118c3 Thanks @DylanPiercey! - Report a compile error when module level code, a static, server, client or export statement, references a name that exists only while the template renders: a tag variable or parameter, input, $global or $signal. Such code runs once as the template loads, so export { count } for a <let/count>, or a static function reading or assigning it, used to compile and then fail when the module loaded or the function ran.

  • #4407 10b2e75 Thanks @DylanPiercey! - Resume a @catch that streams after its <try>'s body inside the <try>'s branch, so removing the content around the <try> also stops the catch's effects and closures. It used to stream under an id the client could not tie to any branch, leaving the removed catch running. Content streamed after a @placeholder body's reorder is also no longer adopted into its <try> when the page's client script runs late, which froze the page once the <try> was removed.

  • #4405 bbd3f8c Thanks @DylanPiercey! - Render a class built from stylesheet module reads (CSS modules, vanilla-extract .css.ts, or a <style/styles> block) like a literal class. The client template holds it and toggles such as [styles.a, active && styles.b] or { [styles.b]: active } update only that class; the server computes each combination's markup once as the module loads instead of on every render.

  • #4399 f9d4412 Thanks @DylanPiercey! - Build a new array for a whole-array rest such as <const/[...chars]=text>, as destructuring does, instead of reading it as the value it rests. A string or other iterable source used to be read directly, so chars.join("-") threw in the browser, and on the server when the rest was read in another section.