github marko-js/marko @marko/runtime-tags@6.3.52

4 hours ago

Patch Changes

  • #4180 c35436c Thanks @DylanPiercey! - Compiling an in-memory source whose filename names a directory that does not exist no longer throws ENOENT; the sibling style/component lookup treats an unreadable directory as having no files.

  • #4185 82a520d Thanks @DylanPiercey! - Fix a resume crash (fn is not a function) in optimized builds when a <let> was only assigned from code that is never emitted: an attribute the child tag never reads, or a function held by an unread <const>. Such a binding no longer counts as state, so the server stops serializing resume data (including a <try> placeholder's pending closure replay) for a signal the client bundle correctly tree-shakes. A controllable <let>'s change handler and a rest sibling's Change exclusion likewise follow only the assignments that are emitted, and a value with no side effects (no call, new or assignment outside a function body) is no longer emitted when nothing reads its variable (a <let> included, when nothing assigns it either). A spread on a custom tag whose child reads nothing from it is no longer evaluated by the server render either, matching the client. A <try> placeholder's pending closure replay is also skipped when no effect or registered function can assign the state it closes over, since a resumed instance runs nothing else.

  • #4202 be554dc Thanks @DylanPiercey! - Content passed to a same-file <define> resolves its serialize reason through the call site, as content passed to a tag in another file already did, so static content no longer registers for resume (and bundles) just because the root scope has state.

  • #4182 fc21c51 Thanks @DylanPiercey! - Remove the declare module "*.marko" block from the published types. index.d.ts is a module, so the block was a module augmentation that never applied to anything; typing .marko imports is @marko/language-tools' job, and a wildcard would type away a missing or misspelled template.

  • #4203 bae6ccd Thanks @DylanPiercey! - A dynamic tag body registers for resume on what can actually name it rather than unconditionally. When the name is always a string, that is the tag's own serialize reason: never when the tag cannot resume, unconditionally when the reason is static, and as a droppable side effect when it depends on params, so the tag's signal keeps the registration exactly where client code can change the tag. When the name only ever resolves to known templates, it is those templates' reasons for serializing their content, mapped through the tag's attributes, as content passed to a known tag already resolves. A name that may be anything else keeps registering, since a component can serialize the body for reasons of its own.

  • #4164 1597fc1 Thanks @DylanPiercey! - A dynamic tag's body depends on the tag expression the way a branch body depends on its condition, so its scope only serializes when that expression can change client side.

  • #4179 c58731c Thanks @DylanPiercey! - A <for> parameter beyond what its iteration form provides (|item, index| for of=, |key, value| for in=, one value for to=/until=) is a compile error instead of silently undefined.

  • #4197 a9a6ddd Thanks @DylanPiercey! - Keep an intersection subscribed when one of its values is derived through another intersection, so it no longer renders stale

  • #4188 323aafa Thanks @DylanPiercey! - A value serialized in an earlier flush and read once later is referenced by its path instead of being bound to a register first; the binding is claimed only if it is read again.

  • #4190 7698310 Thanks @DylanPiercey! - Fix a lazily loaded template that reads no input never rendering when passed to a dynamic tag.

  • #4158 a8ea554 Thanks @DylanPiercey! - Serialize reasons keep their sources when forced, the serialize walk answers once per value and property path, and a guard used once is no longer hoisted.

  • #4177 c9a0556 Thanks @DylanPiercey! - A tag variable called with optional chaining (el?.(), or a hoisted focusIt?.()) is read like a plain call instead of compiling to an undeclared identifier.

  • #4162 3ea218a Thanks @DylanPiercey! - A property read through a renamed value (<const/a=item/> then a.id, or rest.label after <const/{ ...rest }=input/>) is the root value's property: one read, and a child template asks its caller for that property alone. Dev runtime entries list every dom feature module so the optimizer sees them up front.

  • #4185 82a520d Thanks @DylanPiercey! - Fix a build failure ("$input_x" is not exported) for a tag that renders itself and then passes an input only to a child that ignores it. The recursive call judged the input as read before that attribute was dropped, and the stale answer kept it in the tag's exported params while its signal was pruned.

  • #4201 5bf546b Thanks @DylanPiercey! - A registration the DOM output makes at the module top level (an exported function, a class API host) assigns into the resume registry, now exported as _resumed, instead of calling _resume: fewer bytes per registration and no call.

  • #4149 b1f6f86 Thanks @DylanPiercey! - Encode a call site's serialize reason as two bits per param-reason group, composing dynamic guards arithmetically instead of allocating a keyed object.

  • #4132 66c2882 Thanks @DylanPiercey! - Fix the client walk for a <style> with dynamic rules followed by sibling elements, and move a branch's edges with an unescaped $!{} hole that is the branch's whole content.

  • #4178 6b647f5 Thanks @DylanPiercey! - An unresolved tag no longer suggests its own name, and a tag that differs from a known tag only by case (<DIV>) is told tag names are case-sensitive.

Don't miss a new marko release

NewReleases is sending notifications on new releases.