marko 6.4.2 → 6.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/cheatsheet.md +2 -2
  2. package/dist/common/constants/accessor-prop.d.ts +1 -0
  3. package/dist/common/constants/accessor-prop.debug.d.ts +1 -0
  4. package/dist/common/constants/renderer-prop.d.ts +2 -0
  5. package/dist/common/constants/renderer-prop.debug.d.ts +2 -0
  6. package/dist/common/types.d.ts +1 -0
  7. package/dist/debug/dom/catch.feat.js +1 -1
  8. package/dist/debug/dom/catch.feat.mjs +1 -1
  9. package/dist/debug/dom/controllable-input.feat.js +1 -1
  10. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  11. package/dist/debug/dom/controllable-open.feat.js +1 -1
  12. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  13. package/dist/debug/dom/controllable-select.feat.js +1 -1
  14. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  15. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  16. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  17. package/dist/debug/dom/controllable.feat.js +1 -1
  18. package/dist/debug/dom/controllable.feat.mjs +1 -1
  19. package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
  20. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  21. package/dist/debug/dom/dynamic-tag-var.feat.js +10 -2
  22. package/dist/debug/dom/dynamic-tag-var.feat.mjs +10 -2
  23. package/dist/debug/dom/lazy.feat.js +1 -1
  24. package/dist/debug/dom/lazy.feat.mjs +1 -1
  25. package/dist/debug/dom/placeholder.feat.js +1 -1
  26. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  27. package/dist/debug/{dom-Cii0IA92.mjs → dom-BeY1nGUb.mjs} +74 -36
  28. package/dist/debug/{dom-BLbR0hEx.js → dom-CUxvM4i9.js} +109 -35
  29. package/dist/debug/dom.js +3 -1
  30. package/dist/debug/dom.mjs +3 -2
  31. package/dist/debug/html.js +37 -23
  32. package/dist/debug/html.mjs +37 -23
  33. package/dist/dom/catch.feat.js +3 -3
  34. package/dist/dom/catch.feat.mjs +1 -1
  35. package/dist/dom/control-flow.d.ts +3 -3
  36. package/dist/dom/controllable-input.feat.js +1 -1
  37. package/dist/dom/controllable-input.feat.mjs +1 -1
  38. package/dist/dom/controllable-open.feat.js +1 -1
  39. package/dist/dom/controllable-open.feat.mjs +1 -1
  40. package/dist/dom/controllable-select.feat.js +1 -1
  41. package/dist/dom/controllable-select.feat.mjs +1 -1
  42. package/dist/dom/controllable-textarea.feat.js +1 -1
  43. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  44. package/dist/dom/controllable.feat.js +1 -1
  45. package/dist/dom/controllable.feat.mjs +1 -1
  46. package/dist/dom/dynamic-tag-script.feat.js +2 -2
  47. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  48. package/dist/dom/dynamic-tag-var.feat.js +4 -2
  49. package/dist/dom/dynamic-tag-var.feat.mjs +4 -3
  50. package/dist/dom/lazy.feat.js +1 -1
  51. package/dist/dom/lazy.feat.mjs +1 -1
  52. package/dist/dom/placeholder.feat.js +3 -3
  53. package/dist/dom/placeholder.feat.mjs +1 -1
  54. package/dist/dom/queue.d.ts +4 -1
  55. package/dist/dom/renderer.d.ts +9 -2
  56. package/dist/{dom-BPjLe6YU.mjs → dom-DefWmvQB.mjs} +59 -32
  57. package/dist/{dom-B8UEYzOz.js → dom-Diu8MpmL.js} +132 -90
  58. package/dist/dom.d.ts +1 -1
  59. package/dist/dom.js +30 -30
  60. package/dist/dom.mjs +2 -2
  61. package/dist/html/assets.d.ts +1 -1
  62. package/dist/html/content.d.ts +1 -0
  63. package/dist/html/dynamic-tag.d.ts +1 -1
  64. package/dist/html/template.d.ts +1 -0
  65. package/dist/html/writer.d.ts +1 -1
  66. package/dist/html.js +25 -15
  67. package/dist/html.mjs +25 -15
  68. package/dist/translator/index.js +141 -83
  69. package/dist/translator/util/module-registrations.d.ts +1 -1
  70. package/dist/translator/util/solve-reasons.d.ts +1 -0
  71. package/dist/translator/visitors/function.d.ts +15 -10
  72. package/dist/translator/visitors/import-declaration.d.ts +3 -4
  73. package/package.json +3 -3
  74. package/tags-html.d.ts +9 -7
package/cheatsheet.md CHANGED
@@ -16,7 +16,7 @@ Marko 6 = HTML superset, not JSX and not Marko 4/5 syntax. `.marko` files are co
16
16
  6. Events: method shorthand `onClick() { ... }` or `onClick=fn`. Handlers receive `(event, element)`; delegation means the element is the second parameter, not `event.currentTarget`: `onSubmit(e) { e.preventDefault(); save() }`, `onClick(e, el) { el.focus() }`. Don't sync input values through `onInput`/`onChange`; that's what the change handlers below are for. Prefix with `async` to `await` in the body: `async onClick() { await save() }`.
17
17
  7. Native inputs are uncontrolled by default: `value=` sets the default value. Later writes update what `form.reset()` restores, never a dirty field's display. Adding the matching `*Change` handler is what makes them controlled: `valueChange` on `<input>`/`<textarea>`/`<select>`, `checkedChange` on checkboxes/radios, `openChange` on `<details>`/`<dialog>`. `value:=text` is the shorthand for `value=text valueChange(v) { text = v }`. (`<textarea value:=text/>`: value attribute, not body.) `:=` differs by operand: on an identifier (`value:=text`) it assigns that variable; on a member expression (`<let/count:=input.count>` in a child) it wires `input.countChange`, so the child is controlled when the parent passes that handler and keeps its own state when it doesn't.
18
18
  8. Transform in the handler when needed; number inputs give strings: `<input type="number" value=n valueChange(v) { n = +v }>`, or `value:parseFloat:=n`. Uncommitted edits (debounce, commit on blur) never sync through a `<script>`; that is rule 4's derive-by-effect trap. Pair a controllable `<let/value:=input.value>` with `<let/pending=null>`, show `<const/draft=pending ?? value>`, collect with `valueChange(v) { pending = v }`, and commit by assigning `value = pending; pending = null`. Prefer that to calling `input.valueChange(...)`, which throws unless every caller controls the tag.
19
- 9. Radio/checkbox groups: `checkedValue:=picked` on each input (shared var, distinct `value=`); the match is checked; array var for multi-checkbox. Dropdown: `<select value:=picked>`.
19
+ 9. Radio/checkbox groups: `checkedValue:=picked` on each input (shared var, distinct `value=`); the match is checked; array var for multi-checkbox. Dropdown: `<select value:=picked>`. Every bound value needs a rendered input/`<option>`.
20
20
  10. Module-level values, helpers and type aliases need `static`: `static const LIMIT = 10`, `static function fmt(n) {…}`, `static type Row = {…}`. Prefer it to `<const>` for anything that never changes: `<const/LIMIT=10>` runs per instance, `static` hoists it to a module constant. `server`/`client` narrow `static` to one platform (`client import { Chart } from "chart"`); the binding is `undefined` on the other, so read a `client` one only from `<script>`/handlers/`<lifecycle>`. Reading it while rendering throws `is not a function` during SSR.
21
21
  11. `$!{html}` and the contents of `<html-script>`/`<html-style>` are written as-is: the latter are escaped only so they can't close the element, and run as code. Never put user-provided content in them.
22
22
 
@@ -171,7 +171,7 @@ Imperative libs (charts, maps) needing mount/update/destroy: use `<lifecycle>`,
171
171
 
172
172
  ## Lazy loading
173
173
 
174
- Defer a tag's JS into its own bundle until a trigger fires: `visible#sel`, `idle`, `media(...)`, `on-click#sel` (combine with `|`), or `render` alone. Server HTML renders immediately; in the browser `<try>` shows a `@placeholder` while loading. Don't hand-roll an `IntersectionObserver`.
174
+ Defer a tag's JS into its own bundle until a trigger fires: `visible#sel`, `idle`, `media(...)`, `on-click#sel` (combine with `|`), or `render` alone. Server HTML renders immediately; in the browser `<try>` shows a `@placeholder` while loading. Don't hand-roll an `IntersectionObserver`. A lazy tag takes no tag variable: bind state down instead (`<Modal open:=open/>`).
175
175
 
176
176
  ```marko
177
177
  import PriceChart from "<price-chart>" with { load: "visible#chart" }
@@ -4,6 +4,7 @@ export declare const AbortControllers = "A";
4
4
  export declare const AbortScopes = "B";
5
5
  export declare const AwaitCounter = "O";
6
6
  export declare const BranchAccessor = "C";
7
+ export declare const BranchRenders = "BR";
7
8
  export declare const BranchScopes = "D";
8
9
  export declare const CatchContent = "E";
9
10
  export declare const ClosestBranch = "F";
@@ -4,6 +4,7 @@ export declare const AbortControllers = "#AbortControllers";
4
4
  export declare const AbortScopes = "#AbortScopes";
5
5
  export declare const AwaitCounter = "#AwaitCounter";
6
6
  export declare const BranchAccessor = "#BranchAccessor";
7
+ export declare const BranchRenders = "#BranchRenders";
7
8
  export declare const BranchScopes = "#BranchScopes";
8
9
  export declare const CatchContent = "#CatchContent";
9
10
  export declare const ClosestBranch = "#ClosestBranch";
@@ -5,7 +5,9 @@ export declare const Params = "d";
5
5
  export declare const Owner = "e";
6
6
  export declare const Accessor = "f";
7
7
  export declare const LocalClosures = "g";
8
+ export declare const Returns = "h";
8
9
  export declare const Embed = "i";
10
+ export declare const Lazy = "j";
9
11
  type Self = typeof import("./renderer-prop");
10
12
  export type Value = Self[keyof Self];
11
13
  export {};
@@ -5,7 +5,9 @@ export declare const Params = "params";
5
5
  export declare const Owner = "owner";
6
6
  export declare const Accessor = "accessor";
7
7
  export declare const LocalClosures = "localClosures";
8
+ export declare const Returns = "returns";
8
9
  export declare const Embed = "embed";
10
+ export declare const Lazy = "lazy";
9
11
  type Self = typeof import("./renderer-prop.debug");
10
12
  export type Value = Self[keyof Self];
11
13
  export {};
@@ -21,6 +21,7 @@ export interface BranchScope extends Scope {
21
21
  [AccessorProp.PlaceholderBranch]: BranchScope | undefined | 0;
22
22
  [AccessorProp.TryBranch]: BranchScope | undefined;
23
23
  [AccessorProp.PendingRenders]: PendingRender[] | 0 | undefined;
24
+ [AccessorProp.BranchRenders]: PendingRender | undefined;
24
25
  [AccessorProp.DetachedAwait]: Renderer | 0 | undefined;
25
26
  [AccessorProp.PendingScopes]: Scope[] | void;
26
27
  }
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/catch.feat.ts
4
4
  const handlePendingTry = (fn, scope, branch) => {
5
5
  while (branch) {
@@ -1,4 +1,4 @@
1
- import { In as ParentBranch, Ln as PendingEffectScopes, On as Pending, Rn as PendingEffects, b as runPendingEffects, cn as queueAsyncRender, jn as ClosestBranch, kn as Scope, ln as queueEffect, on as installCatch, y as renderCatch, zn as PendingRenders } from "../dom-Cii0IA92.mjs";
1
+ import { Gn as PendingRenders, Hn as ParentBranch, Ln as ClosestBranch, Nn as Pending, Pn as Scope, Un as PendingEffectScopes, Wn as PendingEffects, b as runPendingEffects, dn as queueAsyncRender, fn as queueEffect, ln as installCatch, y as renderCatch } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/catch.feat.ts
3
3
  const handlePendingTry = (fn, scope, branch) => {
4
4
  while (branch) {
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/controllable-input.feat.ts
4
4
  require_control_flow.controllableScripts[0] = require_control_flow._attr_input_checked_script;
5
5
  require_control_flow.controllableScripts[1] = require_control_flow._attr_input_checkedValue_script;
@@ -1,4 +1,4 @@
1
- import { D as _attr_input_checkedValue_script, P as _attr_input_value_script, U as controllableScripts, k as _attr_input_checked_script } from "../dom-Cii0IA92.mjs";
1
+ import { D as _attr_input_checkedValue_script, P as _attr_input_value_script, U as controllableScripts, k as _attr_input_checked_script } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/controllable-input.feat.ts
3
3
  controllableScripts[0] = _attr_input_checked_script;
4
4
  controllableScripts[1] = _attr_input_checkedValue_script;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/controllable-open.feat.ts
4
4
  require_control_flow.controllableScripts[4] = require_control_flow._attr_details_or_dialog_open_script;
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { C as _attr_details_or_dialog_open_script, U as controllableScripts } from "../dom-Cii0IA92.mjs";
1
+ import { C as _attr_details_or_dialog_open_script, U as controllableScripts } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/controllable-open.feat.ts
3
3
  controllableScripts[4] = _attr_details_or_dialog_open_script;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/controllable-select.feat.ts
4
4
  require_control_flow.controllableScripts[3] = require_control_flow._attr_select_value_script;
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { L as _attr_select_value_script, U as controllableScripts } from "../dom-Cii0IA92.mjs";
1
+ import { L as _attr_select_value_script, U as controllableScripts } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/controllable-select.feat.ts
3
3
  controllableScripts[3] = _attr_select_value_script;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/controllable-textarea.feat.ts
4
4
  require_control_flow.controllableScripts[2] = require_control_flow._attr_input_value_script;
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { P as _attr_input_value_script, U as controllableScripts } from "../dom-Cii0IA92.mjs";
1
+ import { P as _attr_input_value_script, U as controllableScripts } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/controllable-textarea.feat.ts
3
3
  controllableScripts[2] = _attr_input_value_script;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  require("./controllable-input.feat.js");
4
4
  require("./controllable-open.feat.js");
5
5
  require("./controllable-select.feat.js");
@@ -1,4 +1,4 @@
1
- import { B as _controllable_select, H as controllableRenders, R as _controllable_input, V as _controllable_textarea, z as _controllable_open } from "../dom-Cii0IA92.mjs";
1
+ import { B as _controllable_select, H as controllableRenders, R as _controllable_input, V as _controllable_textarea, z as _controllable_open } from "../dom-BeY1nGUb.mjs";
2
2
  import "./controllable-input.feat.mjs";
3
3
  import "./controllable-open.feat.mjs";
4
4
  import "./controllable-select.feat.mjs";
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/dynamic-tag-script.feat.ts
4
4
  require_control_flow._resumed[require_control_flow.DYNAMIC_TAG_SCRIPT_REGISTER_ID] = require_control_flow.withBranches(require_control_flow.dynamicTagScript);
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { Cn as withBranches, St as _resumed, g as dynamicTagScript, tn as DYNAMIC_TAG_SCRIPT_REGISTER_ID } from "../dom-Cii0IA92.mjs";
1
+ import { Ct as _resumed, En as withBranches, g as dynamicTagScript, nn as DYNAMIC_TAG_SCRIPT_REGISTER_ID } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/dynamic-tag-script.feat.ts
3
3
  _resumed[DYNAMIC_TAG_SCRIPT_REGISTER_ID] = withBranches(dynamicTagScript);
4
4
  //#endregion
@@ -1,5 +1,13 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/dynamic-tag-var.feat.ts
4
- require_control_flow.installDynamicTagVar((branch) => branch[require_control_flow.TagVariable](() => require_control_flow._el_read(branch[require_control_flow.StartNode])));
4
+ require_control_flow.installBranchRenders();
5
+ require_control_flow.installDynamicTagVar((scope, branch, scopeKey, renderer) => {
6
+ branch[require_control_flow.BranchRenders] = require_control_flow.createBranchRenders(scope, scopeKey);
7
+ if (typeof renderer === "string") branch[require_control_flow.TagVariable](() => require_control_flow._el_read(branch[require_control_flow.StartNode]));
8
+ else {
9
+ if (renderer["lazy"]) throw new Error(`A dynamic tag with a [tag variable](https://markojs.com/docs/reference/language#tag-variables) rendered \`${renderer["id"]}\`, which is lazily loaded, so it does not support one. Import it without \`load\`, or remove the variable.`);
10
+ if (!(renderer["setup"] || renderer["params"])?.["returns"]) throw new Error(`A dynamic tag with a [tag variable](https://markojs.com/docs/reference/language#tag-variables) rendered \`${renderer["id"]}\`, which does not [\`<return>\`](https://markojs.com/docs/reference/core-tag#return) a value. Add a \`<return>\` to it, or remove the variable.`);
11
+ }
12
+ });
5
13
  //#endregion
@@ -1,4 +1,12 @@
1
- import { Hn as TagVariable, Pt as _el_read, Vn as StartNode, _ as installDynamicTagVar } from "../dom-Cii0IA92.mjs";
1
+ import { Ft as _el_read, In as BranchRenders, Jn as TagVariable, _ as installDynamicTagVar, cn as installBranchRenders, qn as StartNode, sn as createBranchRenders } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/dynamic-tag-var.feat.ts
3
- installDynamicTagVar((branch) => branch[TagVariable](() => _el_read(branch[StartNode])));
3
+ installBranchRenders();
4
+ installDynamicTagVar((scope, branch, scopeKey, renderer) => {
5
+ branch[BranchRenders] = createBranchRenders(scope, scopeKey);
6
+ if (typeof renderer === "string") branch[TagVariable](() => _el_read(branch[StartNode]));
7
+ else {
8
+ if (renderer["lazy"]) throw new Error(`A dynamic tag with a [tag variable](https://markojs.com/docs/reference/language#tag-variables) rendered \`${renderer["id"]}\`, which is lazily loaded, so it does not support one. Import it without \`load\`, or remove the variable.`);
9
+ if (!(renderer["setup"] || renderer["params"])?.["returns"]) throw new Error(`A dynamic tag with a [tag variable](https://markojs.com/docs/reference/language#tag-variables) rendered \`${renderer["id"]}\`, which does not [\`<return>\`](https://markojs.com/docs/reference/core-tag#return) a value. Add a \`<return>\` to it, or remove the variable.`);
10
+ }
11
+ });
4
12
  //#endregion
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  //#region src/dom/lazy.feat.ts
3
- require("../dom-BLbR0hEx.js").withLazy();
3
+ require("../dom-CUxvM4i9.js").withLazy();
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- import { kt as withLazy } from "../dom-Cii0IA92.mjs";
1
+ import { At as withLazy } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/lazy.feat.ts
3
3
  withLazy();
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BLbR0hEx.js");
2
+ const require_control_flow = require("../dom-CUxvM4i9.js");
3
3
  //#region src/dom/placeholder.feat.ts
4
4
  require_control_flow._resumed[require_control_flow.PLACEHOLDER_DISMISS_REGISTER_ID] = (tryBranch) => {
5
5
  if (tryBranch["#PlaceholderBranch"]) {
@@ -1,4 +1,4 @@
1
- import { Bn as PlaceholderBranch, St as _resumed, Zt as destroyBranch, nn as PLACEHOLDER_DISMISS_REGISTER_ID } from "../dom-Cii0IA92.mjs";
1
+ import { Ct as _resumed, Kn as PlaceholderBranch, Qt as destroyBranch, rn as PLACEHOLDER_DISMISS_REGISTER_ID } from "../dom-BeY1nGUb.mjs";
2
2
  //#region src/dom/placeholder.feat.ts
3
3
  _resumed[PLACEHOLDER_DISMISS_REGISTER_ID] = (tryBranch) => {
4
4
  if (tryBranch["#PlaceholderBranch"]) {
@@ -22,6 +22,7 @@ const AbortControllers = "#AbortControllers";
22
22
  const AbortScopes = "#AbortScopes";
23
23
  const AwaitCounter = "#AwaitCounter";
24
24
  const BranchAccessor = "#BranchAccessor";
25
+ const BranchRenders = "#BranchRenders";
25
26
  const BranchScopes = "#BranchScopes";
26
27
  const CatchContent = "#CatchContent";
27
28
  const ClosestBranch = "#ClosestBranch";
@@ -66,6 +67,8 @@ const Params = "params";
66
67
  const Owner = "owner";
67
68
  const Accessor = "accessor";
68
69
  const LocalClosures = "localClosures";
70
+ const Returns = "returns";
71
+ const Lazy = "lazy";
69
72
  //#endregion
70
73
  //#region src/common/helpers.ts
71
74
  const htmlAttrNameReg = /^[^a-z_]|[^a-z0-9._:-]/i;
@@ -341,16 +344,19 @@ let rendering;
341
344
  let runId = 2;
342
345
  let pendingEffects = [];
343
346
  let pendingRenders = [];
344
- const scopeKeyOffset = 1e6;
347
+ const ranRenders = /*@__PURE__*/ new WeakMap();
345
348
  function queueRender(scope, signal, signalKey, value, scopeKey = scope["#Id"]) {
346
349
  let render;
347
350
  if (signalKey >= 0 && (render = scope[signalKey])) {
348
351
  render[Value] = value;
349
- if (render["gen"] === runId || catchEnabled && render["pending"]) return;
352
+ if (render["gen"] === runId || catchEnabled && render["pending"]) {
353
+ if (!render["pending"] && ranRenders.get(render) === runId) console.error("A render was queued again after it ran in this update, so its latest value is dropped. This is a bug in Marko.");
354
+ return;
355
+ }
350
356
  render["gen"] = runId;
351
357
  } else {
352
358
  render = {
353
- ["key"]: scopeKey * scopeKeyOffset + signalKey,
359
+ ["key"]: scopeKey * 1e6 + signalKey,
354
360
  [Scope]: scope,
355
361
  [Signal]: signal,
356
362
  [Value]: value,
@@ -360,7 +366,7 @@ function queueRender(scope, signal, signalKey, value, scopeKey = scope["#Id"]) {
360
366
  }
361
367
  queuePendingRender(render);
362
368
  }
363
- function queuePendingRender(render) {
369
+ let queuePendingRender = (render) => {
364
370
  let i = pendingRenders.push(render) - 1;
365
371
  while (i) {
366
372
  const parentIndex = i - 1 >> 1;
@@ -370,6 +376,34 @@ function queuePendingRender(render) {
370
376
  i = parentIndex;
371
377
  }
372
378
  pendingRenders[i] = render;
379
+ };
380
+ function createBranchRenders(scope, scopeKey) {
381
+ return {
382
+ ["key"]: scopeKey * 1e6 - 1,
383
+ [Scope]: scope,
384
+ [Signal]: runBranchRenders,
385
+ [Value]: [],
386
+ ["gen"]: 0
387
+ };
388
+ }
389
+ function installBranchRenders() {
390
+ const queue = queuePendingRender;
391
+ queuePendingRender = (render) => {
392
+ const branchRenders = render[Scope][ClosestBranch]?.[BranchRenders];
393
+ if (branchRenders) {
394
+ if (branchRenders["gen"] !== runId && !branchRenders["pending"]) branchRenders[Value] = [];
395
+ branchRenders["gen"] = runId;
396
+ const renders = branchRenders[Value];
397
+ if (!renders.length) queuePendingRender(branchRenders);
398
+ const prev = pendingRenders;
399
+ pendingRenders = renders;
400
+ queue(render);
401
+ pendingRenders = prev;
402
+ } else queue(render);
403
+ };
404
+ }
405
+ function runBranchRenders(_scope, renders) {
406
+ runRenders(renders);
373
407
  }
374
408
  function queueEffect(scope, fn) {
375
409
  pendingEffects.push(fn, scope);
@@ -421,26 +455,27 @@ function installCatch(catchEffects, wrapRender) {
421
455
  runEffects = catchEffects;
422
456
  runRender = wrapRender(runRender);
423
457
  }
424
- function runRenders() {
425
- while (pendingRenders.length) {
426
- const render = pendingRenders[0];
427
- const item = pendingRenders.pop();
458
+ function runRenders(renders = pendingRenders) {
459
+ while (renders.length) {
460
+ const render = renders[0];
461
+ const item = renders.pop();
428
462
  if (render !== item) {
429
463
  let i = 0;
430
- const mid = pendingRenders.length >> 1;
431
- const key = (pendingRenders[0] = item)["key"];
464
+ const mid = renders.length >> 1;
465
+ const key = (renders[0] = item)["key"];
432
466
  while (i < mid) {
433
467
  let bestChild = (i << 1) + 1;
434
468
  const right = bestChild + 1;
435
- if (right < pendingRenders.length && pendingRenders[right]["key"] - pendingRenders[bestChild]["key"] < 0) bestChild = right;
436
- if (pendingRenders[bestChild]["key"] - key >= 0) break;
469
+ if (right < renders.length && renders[right]["key"] - renders[bestChild]["key"] < 0) bestChild = right;
470
+ if (renders[bestChild]["key"] - key >= 0) break;
437
471
  else {
438
- pendingRenders[i] = pendingRenders[bestChild];
472
+ renders[i] = renders[bestChild];
439
473
  i = bestChild;
440
474
  }
441
475
  }
442
- pendingRenders[i] = item;
476
+ renders[i] = item;
443
477
  }
478
+ ranRenders.set(render, runId);
444
479
  runRender(render);
445
480
  }
446
481
  }
@@ -684,9 +719,9 @@ function _for_closure(ownerLoopNodeAccessor, fn) {
684
719
  const scopeAccessor = BranchScopes$1 + ownerLoopNodeAccessor;
685
720
  const ownerSignal = (ownerScope) => {
686
721
  const scopes = toArray(ownerScope[scopeAccessor]);
687
- if (scopes.length) queueRender(ownerScope, () => {
722
+ queueRender(ownerScope, () => {
688
723
  for (const scope of scopes) if (scope["#Gen"] > 0 && scope["#Gen"] < runId) fn(scope);
689
- }, -1, 0, scopes[0]["#Id"]);
724
+ }, -1);
690
725
  };
691
726
  ownerSignal._ = fn;
692
727
  return ownerSignal;
@@ -696,8 +731,7 @@ function _for_selector(ownerLoopNodeAccessor, ownerValueAccessor, keyValueAccess
696
731
  const mapAccessor = KeyedScopes + ownerLoopNodeAccessor;
697
732
  const prevKeyProp = `${PreviousKey}${ownerValueAccessor}`;
698
733
  const ownerSignal = (ownerScope) => {
699
- const scopes = toArray(ownerScope[scopeAccessor]);
700
- if (ownerScope["#Gen"] < runId && scopes.length) {
734
+ if (ownerScope["#Gen"] < runId) {
701
735
  const nextKey = ownerScope[ownerValueAccessor];
702
736
  queueRender(ownerScope, () => {
703
737
  const map = keyedScopes(ownerScope, scopeAccessor, mapAccessor, keyValueAccessor);
@@ -710,7 +744,7 @@ function _for_selector(ownerLoopNodeAccessor, ownerValueAccessor, keyValueAccess
710
744
  }
711
745
  } else for (const scope of toArray(ownerScope[scopeAccessor])) runLiveBranch(scope, fn);
712
746
  if (map) map[prevKeyProp] = nextKey;
713
- }, -1, 0, scopes[0]["#Id"]);
747
+ }, -1);
714
748
  }
715
749
  };
716
750
  ownerSignal._ = fn;
@@ -1081,13 +1115,13 @@ function init(runtimeId = "M") {
1081
1115
  visitScope[nextToken()] = visitType === "%" ? visit.parentNode.insertBefore(new Text(), visit) : visit.previousSibling;
1082
1116
  if ((branchesEnabled || lazyEnabled) && pending[pending.length - 1] !== visitScope) pending.push(visitScope);
1083
1117
  }
1118
+ if (embedRenders && !embedAnchor && visit.parentNode) embedRenders.set(embedAnchor = visit.parentNode.insertBefore(new Text(), visit), [renderId, scopeLookup]);
1084
1119
  }
1085
1120
  if (branchesEnabled && visitBranches) {
1086
1121
  visitType = "*";
1087
1122
  lastToken = "";
1088
1123
  visitBranches();
1089
1124
  }
1090
- if (embedRenders && !embedAnchor && visit?.parentNode) embedRenders.set(embedAnchor = visit.parentNode.insertBefore(new Text(), visit.nextSibling), [renderId, scopeLookup]);
1091
1125
  visits.length = retained;
1092
1126
  return effects;
1093
1127
  };
@@ -1155,6 +1189,10 @@ function setupBranch(renderer, branch) {
1155
1189
  if (renderer["setup"]) queueRender(branch, renderer[Setup], -1);
1156
1190
  return branch;
1157
1191
  }
1192
+ function _return_setup(setup) {
1193
+ (setup._ || setup)[Returns] = 1;
1194
+ return setup;
1195
+ }
1158
1196
  function _content(id, template, walks, setup, params, dynamicScopesAccessor) {
1159
1197
  walks = walks ? walks.replace(/[^\0-1]+$/, "") : "";
1160
1198
  setup = setup ? setup._ || setup : void 0;
@@ -1648,11 +1686,8 @@ function getSelectValue(el, multiple) {
1648
1686
  return multiple ? Array.from(el.selectedOptions, (opt) => opt.value) : el.value;
1649
1687
  }
1650
1688
  function assertSelectValueMatchesOption(el, normalizedValue, value) {
1651
- const multiple = Array.isArray(normalizedValue);
1652
- if (multiple ? normalizedValue.some(Boolean) : normalizedValue) {
1653
- for (const opt of el.options) if (multiple ? normalizedValue.includes(opt.value) : opt.value === normalizedValue) return;
1654
- console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
1655
- }
1689
+ const options = Array.from(el.options, (opt) => opt.value);
1690
+ if ((Array.isArray(normalizedValue) ? normalizedValue : [normalizedValue]).some((v) => v && !options.includes(v))) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
1656
1691
  }
1657
1692
  function _attr_details_or_dialog_open_default(scope, nodeAccessor, open) {
1658
1693
  if (scope["#Gen"] === runId) scope[nodeAccessor].open = isNotVoid(open);
@@ -1687,7 +1722,7 @@ function syncControllableFormInput(el, hasChanged, onChange) {
1687
1722
  el._ = onChange;
1688
1723
  el.c = hasChanged;
1689
1724
  delegate("input", handleChange);
1690
- if (el.form) delegate("reset", handleFormReset);
1725
+ delegate("reset", handleFormReset);
1691
1726
  if (isResuming && hasChanged(el)) queueMicrotask(onChange);
1692
1727
  }
1693
1728
  function handleChange(ev) {
@@ -1695,7 +1730,7 @@ function handleChange(ev) {
1695
1730
  }
1696
1731
  function handleFormReset(ev) {
1697
1732
  const handlers = [];
1698
- for (const el of ev.target.elements) if (el._ && el.c(el)) handlers.push(el._);
1733
+ for (const el of ev.target.elements || []) if (el._ && el.c(el)) handlers.push(el._);
1699
1734
  requestAnimationFrame(() => {
1700
1735
  if (!ev.defaultPrevented) for (const change of handlers) change();
1701
1736
  });
@@ -1992,18 +2027,19 @@ function patchDynamicTag(fn) {
1992
2027
  _dynamic_tag = fn(_dynamic_tag);
1993
2028
  }
1994
2029
  let _dynamic_tag = /*@__PURE__*/ withBranches((nodeAccessor, getContent, getTagVar, inputIsArgs) => {
2030
+ const scopeOffsetAccessor = getTagVar && getDebugKey(+nodeAccessor.slice(nodeAccessor.lastIndexOf("/") + 1) + 1, "#scopeOffset");
1995
2031
  const childScopeAccessor = BranchScopes$1 + nodeAccessor;
1996
2032
  const rendererAccessor = ConditionalRenderer + nodeAccessor;
1997
2033
  return (scope, newRenderer, getInput) => {
1998
2034
  const normalizedRenderer = normalizeDynamicRenderer(newRenderer);
1999
- if (scope[rendererAccessor] !== (scope[rendererAccessor] = rendererKey(normalizedRenderer)) || getContent && !(normalizedRenderer || scope[childScopeAccessor])) {
2035
+ if (scope[rendererAccessor] !== (scope[rendererAccessor] = rendererKey(normalizedRenderer) || (getContent ? void 0 : 0)) || getContent && !(normalizedRenderer || scope[childScopeAccessor])) {
2000
2036
  const renderer = normalizedRenderer || (getContent ? getContent(scope) : void 0);
2001
2037
  setConditionalRenderer(scope, nodeAccessor, renderer, createBranchWithTagNameOrRenderer);
2002
2038
  if (getTagVar) {
2003
- if (scope[childScopeAccessor]) {
2039
+ if (normalizedRenderer) {
2004
2040
  scope[childScopeAccessor][TagVariable] = (value) => getTagVar()(scope, value);
2005
- if (typeof normalizedRenderer === "string") bindNativeTagVar?.(scope[childScopeAccessor]);
2006
- } else getTagVar()(scope, void 0);
2041
+ bindTagVar(scope, scope[childScopeAccessor], scope[scopeOffsetAccessor], normalizedRenderer);
2042
+ } else getTagVar()(scope);
2007
2043
  }
2008
2044
  if (typeof renderer === "string") {
2009
2045
  if (getContent) {
@@ -2011,7 +2047,10 @@ let _dynamic_tag = /*@__PURE__*/ withBranches((nodeAccessor, getContent, getTagV
2011
2047
  setConditionalRenderer(scope[childScopeAccessor], `#${renderer.toLowerCase()}/0`, content, createAndSetupBranch);
2012
2048
  if (content["accessor"]) subscribeToScopeSet(content[Owner], content[Accessor], scope[childScopeAccessor][`BranchScopes:#${renderer.toLowerCase()}/0`]);
2013
2049
  }
2014
- } else if (renderer?.["accessor"]) subscribeToScopeSet(renderer[Owner], renderer[Accessor], scope[childScopeAccessor]);
2050
+ } else if (renderer) {
2051
+ setupBranch(renderer, scope[childScopeAccessor]);
2052
+ if (renderer["accessor"]) subscribeToScopeSet(renderer[Owner], renderer[Accessor], scope[childScopeAccessor]);
2053
+ }
2015
2054
  }
2016
2055
  if (normalizedRenderer) {
2017
2056
  const childScope = scope[childScopeAccessor];
@@ -2047,9 +2086,9 @@ const _dynamic_tag_content = /*@__PURE__*/ withBranches((nodeAccessor) => {
2047
2086
  renderer?.[LocalClosures]?.(scope[childScopeAccessor]);
2048
2087
  };
2049
2088
  });
2050
- let bindNativeTagVar;
2089
+ let bindTagVar;
2051
2090
  function installDynamicTagVar(bind) {
2052
- bindNativeTagVar = bind;
2091
+ bindTagVar = bind;
2053
2092
  }
2054
2093
  function dynamicTagScript(branch) {
2055
2094
  _attrs_script(branch, `#${branch[Renderer].toLowerCase()}/0`);
@@ -2202,7 +2241,6 @@ function createBranchWithTagNameOrRenderer($global, tagNameOrRenderer, parentSco
2202
2241
  if (typeof tagNameOrRenderer === "string") assertValidTagName(tagNameOrRenderer);
2203
2242
  const branch = createBranch($global, tagNameOrRenderer, parentScope, parentNode);
2204
2243
  if (typeof tagNameOrRenderer === "string") branch[`#${tagNameOrRenderer.toLowerCase()}/0`] = branch[StartNode] = branch[EndNode] = document.createElementNS(tagNameOrRenderer === "svg" ? "http://www.w3.org/2000/svg" : tagNameOrRenderer === "math" ? "http://www.w3.org/1998/Math/MathML" : parentNode.namespaceURI, tagNameOrRenderer);
2205
- else setupBranch(tagNameOrRenderer, branch);
2206
2244
  return branch;
2207
2245
  }
2208
2246
  function bySecondArg(_item, index) {
@@ -2212,4 +2250,4 @@ function byFirstArg(name) {
2212
2250
  return name;
2213
2251
  }
2214
2252
  //#endregion
2215
- export { _attr_style_items as $, removeAndDestroyBranch as $t, _attr_input_value as A, AwaitCounter as An, _child_setup as At, _controllable_select as B, PlaceholderBranch as Bn, _id as Bt, _attr_details_or_dialog_open_script as C, withBranches as Cn, _var_resume as Ct, _attr_input_checkedValue_script as D, Setup as Dn, ready as Dt, _attr_input_checkedValue_default as E, Params as En, initEmbedded as Et, _attr_select_value as F, Load as Fn, _for_closure as Ft, _attr_class as G, _return as Gt, controllableRenders as H, TagVariable as Hn, _let as Ht, _attr_select_value_default as I, ParentBranch as In, _for_selector as It, _attr_class_names as J, _var as Jt, _attr_class_item as K, _return_change as Kt, _attr_select_value_script as L, PendingEffectScopes as Ln, _global_read as Lt, _attr_input_value_default as M, EndNode as Mn, _closure_get as Mt, _attr_input_value_dynamic_default as N, Gen$1 as Nn, _const as Nt, _attr_input_checked_default as O, Pending as On, readyFailed as Ot, _attr_input_value_script as P, Global as Pn, _el_read as Pt, _attr_style_item as Q, insertBranchBefore as Qt, _controllable_input as R, PendingEffects as Rn, _hoist as Rt, _attr_details_or_dialog_open_default as S, _call as Sn, _resumed as St, _attr_input_checkedValue as T, Owner as Tn, init as Tt, controllableScripts as U, _let_change as Ut, _controllable_textarea as V, StartNode as Vn, _if_closure as Vt, _attr as W, _or as Wt, _attr_nonce as X, _assert_init as Xt, _attr_content as Y, _var_change as Yt, _attr_style as Z, destroyBranch as Zt, installDynamicTagVar as _, forTo as _n, createAndSetupBranch as _t, _for_in as a, $signalReset as an, _html as at, runPendingEffects as b, _assert_hoist as bn, _dynamic_tag_var_resume as bt, _for_to as c, queueAsyncRender as cn, _style_shell as ct, _for_until_unkeyed as d, rendering as dn, _to_text as dt, syncGen as en, _attrs as et, _if as f, run as fn, insertChildNodes as ft, dynamicTagScript as g, forOf as gn, _content_resume as gt, addAwaitCounter as h, forIn as hn, _content_closures as ht, _dynamic_tag_content as i, $signal as in, _attrs_script as it, _attr_input_value_attribute_default as j, ClosestBranch as jn, _closure as jt, _attr_input_checked_script as k, Scope as kn, withLazy as kt, _for_to_unkeyed as l, queueEffect as ln, _text as lt, _try as m, runId as mn, _content as mt, _await_promise as n, PLACEHOLDER_DISMISS_REGISTER_ID as nn, _attrs_partial as nt, _for_of as o, installCatch as on, _lifecycle as ot, _show as p, runEffects as pn, toInsertNode as pt, _attr_class_items as q, _script as qt, _dynamic_tag as r, _on as rn, _attrs_partial_content as rt, _for_of_unkeyed as s, prepareEffects as sn, _style_rule_item as st, _await_content as t, DYNAMIC_TAG_SCRIPT_REGISTER_ID as tn, _attrs_content as tt, _for_until as u, queueRender as un, _text_content as ut, patchDynamicTag as v, forUntil as vn, createBranch as vt, _attr_input_checked as w, Clone as wn, getRegisteredWithScope as wt, _attr_details_or_dialog_open as x, _hoist_read_error as xn, _el as xt, renderCatch as y, _assert_class_toggles as yn, setupBranch as yt, _controllable_open as z, PendingRenders as zn, _hoist_resume as zt };
2253
+ export { _attr_style_items as $, insertBranchBefore as $t, _attr_input_value as A, Params as An, withLazy as At, _controllable_select as B, Global as Bn, _hoist_resume as Bt, _attr_details_or_dialog_open_script as C, _assert_hoist as Cn, _resumed as Ct, _attr_input_checkedValue_script as D, Clone as Dn, initEmbedded as Dt, _attr_input_checkedValue_default as E, withBranches as En, init as Et, _attr_select_value as F, AwaitCounter as Fn, _el_read as Ft, _attr_class as G, PendingRenders as Gn, _or as Gt, controllableRenders as H, ParentBranch as Hn, _if_closure as Ht, _attr_select_value_default as I, BranchRenders as In, _for_closure as It, _attr_class_names as J, TagVariable as Jn, _script as Jt, _attr_class_item as K, PlaceholderBranch as Kn, _return as Kt, _attr_select_value_script as L, ClosestBranch as Ln, _for_selector as Lt, _attr_input_value_default as M, Setup as Mn, _closure as Mt, _attr_input_value_dynamic_default as N, Pending as Nn, _closure_get as Nt, _attr_input_checked_default as O, Lazy as On, ready as Ot, _attr_input_value_script as P, Scope as Pn, _const as Pt, _attr_style_item as Q, destroyBranch as Qt, _controllable_input as R, EndNode as Rn, _global_read as Rt, _attr_details_or_dialog_open_default as S, _assert_class_toggles as Sn, _el as St, _attr_input_checkedValue as T, _call as Tn, getRegisteredWithScope as Tt, controllableScripts as U, PendingEffectScopes as Un, _let as Ut, _controllable_textarea as V, Load as Vn, _id as Vt, _attr as W, PendingEffects as Wn, _let_change as Wt, _attr_nonce as X, _var_change as Xt, _attr_content as Y, _var as Yt, _attr_style as Z, _assert_init as Zt, installDynamicTagVar as _, runId as _n, _return_setup as _t, _for_in as a, $signal as an, _html as at, runPendingEffects as b, forTo as bn, setupBranch as bt, _for_to as c, installBranchRenders as cn, _style_shell as ct, _for_until_unkeyed as d, queueAsyncRender as dn, _to_text as dt, removeAndDestroyBranch as en, _attrs as et, _if as f, queueEffect as fn, insertChildNodes as ft, dynamicTagScript as g, runEffects as gn, _content_resume as gt, addAwaitCounter as h, run as hn, _content_closures as ht, _dynamic_tag_content as i, _on as in, _attrs_script as it, _attr_input_value_attribute_default as j, Returns as jn, _child_setup as jt, _attr_input_checked_script as k, Owner as kn, readyFailed as kt, _for_to_unkeyed as l, installCatch as ln, _text as lt, _try as m, rendering as mn, _content as mt, _await_promise as n, DYNAMIC_TAG_SCRIPT_REGISTER_ID as nn, _attrs_partial as nt, _for_of as o, $signalReset as on, _lifecycle as ot, _show as p, queueRender as pn, toInsertNode as pt, _attr_class_items as q, StartNode as qn, _return_change as qt, _dynamic_tag as r, PLACEHOLDER_DISMISS_REGISTER_ID as rn, _attrs_partial_content as rt, _for_of_unkeyed as s, createBranchRenders as sn, _style_rule_item as st, _await_content as t, syncGen as tn, _attrs_content as tt, _for_until as u, prepareEffects as un, _text_content as ut, patchDynamicTag as v, forIn as vn, createAndSetupBranch as vt, _attr_input_checked as w, _hoist_read_error as wn, _var_resume as wt, _attr_details_or_dialog_open as x, forUntil as xn, _dynamic_tag_var_resume as xt, renderCatch as y, forOf as yn, createBranch as yt, _controllable_open as z, Gen$1 as zn, _hoist as zt };