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

latest release: @marko/compiler@5.41.3
18 hours ago

Patch Changes

  • #3486 764da5b Thanks @DylanPiercey! - Report a clear migration error for a removed class {} component block. A Marko 5 class { … } block compiled with the tags API previously surfaced htmljs-parser's generic Invalid attribute name. with the caret on the class body, giving no hint that the class-component API was involved. The tags translator now recognizes class as a removed core tag and reports class {} component blocks are no longer supported. Use <let> and <const> tags for state. with the caret on class. Class-API (Marko 5) compilation is unaffected.

  • #3480 af23841 Thanks @DylanPiercey! - Fix a controlled <select> / <input type=checkbox|radio> selecting a different option on the server than on the client when its value is 0n or NaN. The SSR value normalizer (normalizeStrAttrValue) dropped 0n/NaN to "" while the DOM normalizer wrote "0"/"NaN", so e.g. a controlled <select value=0n> with <option value=0> and <option value=""> marked the empty option selected under SSR but the 0 option on the client, a hydration mismatch. The HTML normalizer now mirrors the DOM one (isNotVoid(value) && value !== true), so both pick the same option. (false already agreed, normalizing to "" on both sides.)

  • #3495 447e00d Thanks @DylanPiercey! - Fix a client-side ReferenceError and lost reactivity when a locally-invoked <define> has an unused non-final positional parameter. The compiler's argument analysis advanced its positional index only for used parameters, so an unused earlier parameter desynced every following argument, dropping its reference while the DOM output still emitted a per-parameter signal call for it, producing a bare undeclared identifier at init. Server rendering was unaffected, so the mismatch surfaced only on the client.

  • #3497 40b5154 Thanks @DylanPiercey! - Fix a locally-invoked <define> with a positional rest parameter (<define/MyTag|a, ...rest|>) silently dropping every rest argument on the client. Server rendering passed all arguments positionally, but the DOM path wired only the named parameters and never applied the rest, so <MyTag(x, "two", "three")/> rendered the rest on the server and lost it after hydration. A positional rest now routes through the whole-arguments path on both runtimes.

  • #3474 2270237 Thanks @DylanPiercey! - Throw clear development errors for invalid <for> inputs instead of failing opaquely. A <for of> whose value is a truthy non-iterable (a number, plain object, Date, …) previously surfaced the engine's x is not iterable with a stack pointing into compiled runtime; it now names the of attribute. A <for to>/<for until> with a non-finite bound previously rendered nothing (NaN) or looped forever (Infinity, hanging server rendering); it now reports the offending attribute and value. These checks are development-only, so production output is unchanged.

  • #3491 c7e7879 Thanks @DylanPiercey! - Include until in the error thrown when a <for> tag has no range attribute. until is a first-class <for> range (<for until=n>), but the message only listed of=, in=, and to=, hiding a valid option; it now reads requires an of=, in=, to=, or until= attribute.

  • #3485 9694272 Thanks @DylanPiercey! - Stop the compiler hanging on a dynamic tag name that resolves through cyclic <const> tags. Classifying a <${...}> tag name walks the bound expression, following <const> values with no visited set, so a self-referential <const/x=x/> or a mutually-referential <const/a=b/><const/b=a/> used as a tag name looped forever during analysis. The walk now records the expressions it has visited: a self-reference surfaces the existing Tag variable circular references are not supported. error instead of hanging, and a mutual cycle resolves like any other dynamic tag.

  • #3488 6b1b898 Thanks @DylanPiercey! - Stop the compiler crashing with RangeError: Maximum call stack size exceeded on a self- or mutually-referential static/export function. getStaticDeclRefs recursed on every value reference of a static-scope declaration with no visited set, so static function tick() { requestAnimationFrame(tick); } (and the export function and mutual ping/pong variants) re-entered the same binding forever during analysis, aborting every output with an opaque error and no source location, even though calling the function (tick()) compiled fine. The walk now tracks the declarations it has visited, so idiomatic self-scheduling, retry-loop, and self-registering-listener patterns compile.

  • #3496 8f0143d Thanks @DylanPiercey! - Fix a dev-mode (MARKO_DEBUG) crash when a camelCase SVG or MathML element (<linearGradient>, <clipPath>, <feGaussianBlur>, …) carries a tag variable, dynamic attribute, event handler, or a lone control-flow child. The compiler wrote the element's debug scope accessor using the source-case tag name, while the DOM walker looks the node up by its lowercased tagName, so the accessor never resolved and mounting or hydrating threw. The debug accessor name is now lowercased to match the walker. Optimized builds use numeric accessors and were unaffected.

  • #3489 b5b4cc5 Thanks @DylanPiercey! - Stop a formatting-only newline in a <textarea> body from being treated as content. <textarea> preserves whitespace, so a natural multi-line <textarea value=v> with </textarea> on the next line — whose body is just a newline — threw A textarea cannot have both a value attribute and body content., while the byte-equivalent single-line form compiled fine (and a newline-only body compiled to an initial value of "\n"). preAnalyze now strips a single leading newline from the body, matching how the HTML parser ignores one newline right after the <textarea> start tag. An intentional non-whitespace body still reports the value/body conflict.

  • #3483 099a1ff Thanks @DylanPiercey! - Warn at compile time when a native element sets the same attribute more than once. <div class="card" class="override">, <button onClick(){…} onClick(){…}>, or <img id=a id=b> previously collapsed to the last occurrence with no diagnostic, even though Marko already errors for the analogous <let>/<const>/<script> duplicates. The compiler now emits a warning naming the duplicated attribute (the last value is still the one applied).

Don't miss a new marko release

NewReleases is sending notifications on new releases.