Patch Changes
-
#4180
c35436cThanks @DylanPiercey! - Compiling an in-memory source whose filename names a directory that does not exist no longer throwsENOENT; the sibling style/component lookup treats an unreadable directory as having no files. -
#4185
82a520dThanks @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'sChangeexclusion likewise follow only the assignments that are emitted, and a value with no side effects (no call,newor 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
be554dcThanks @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
fc21c51Thanks @DylanPiercey! - Remove thedeclare module "*.marko"block from the published types.index.d.tsis a module, so the block was a module augmentation that never applied to anything; typing.markoimports is@marko/language-tools' job, and a wildcard would type away a missing or misspelled template. -
#4203
bae6ccdThanks @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
1597fc1Thanks @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
c58731cThanks @DylanPiercey! - A<for>parameter beyond what its iteration form provides (|item, index|forof=,|key, value|forin=, one value forto=/until=) is a compile error instead of silentlyundefined. -
#4197
a9a6dddThanks @DylanPiercey! - Keep an intersection subscribed when one of its values is derived through another intersection, so it no longer renders stale -
#4188
323aafaThanks @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
7698310Thanks @DylanPiercey! - Fix a lazily loaded template that reads noinputnever rendering when passed to a dynamic tag. -
#4158
a8ea554Thanks @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
c9a0556Thanks @DylanPiercey! - A tag variable called with optional chaining (el?.(), or a hoistedfocusIt?.()) is read like a plain call instead of compiling to an undeclared identifier. -
#4162
3ea218aThanks @DylanPiercey! - A property read through a renamed value (<const/a=item/>thena.id, orrest.labelafter<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
82a520dThanks @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
5bf546bThanks @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
b1f6f86Thanks @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
66c2882Thanks @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
6b647f5Thanks @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.