marko 6.3.44 → 6.3.45
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.
- package/cheatsheet.md +7 -3
- package/dist/debug/html.js +2 -1
- package/dist/debug/html.mjs +2 -1
- package/dist/html.js +1 -1
- package/dist/html.mjs +1 -1
- package/dist/translator/index.js +213 -125
- package/dist/translator/interop/index.d.ts +8 -0
- package/dist/translator/util/entry-builder.d.ts +17 -3
- package/dist/translator/util/known-tag.d.ts +1 -5
- package/dist/translator/util/references.d.ts +10 -1
- package/dist/translator/util/sections.d.ts +3 -1
- package/dist/translator/util/serialize-reasons.d.ts +3 -1
- package/dist/translator/util/set-tag-sections-downstream.d.ts +2 -2
- package/dist/translator/util/tag-name-type.d.ts +2 -0
- package/dist/translator/visitors/import-declaration.d.ts +4 -0
- package/dist/translator/visitors/program/index.d.ts +1 -0
- package/package.json +4 -4
package/cheatsheet.md
CHANGED
|
@@ -7,7 +7,7 @@ Marko 6 = HTML superset, not JSX and not Marko 4/5 syntax. `.marko` files are co
|
|
|
7
7
|
1. Text interpolation: `${expr}` inside tag bodies. A bare line at the template root parses as a tag (concise mode): `Welcome aboard` fails to compile, but `p is a tag` compiles **silently** to `<p is a tag></p>`, since any line starting with a real tag name loses its words to attributes. Wrap text in an element (`<p>Welcome aboard</p>`) or prefix the line with `--` and a space (`-- Welcome ${name}`). Attributes take raw JS after `=` with no braces or quotes: `<div title=user.name data-n=1 + 1>`.
|
|
8
8
|
2. A top-level `>` hugging its operand in an attribute value **ends the tag** silently: `<button disabled=count>=8 onClick() {…}>More</button>` is `disabled=count` plus the text `=8 onClick() {…}>`, so the handler never binds. Space a `>=` (`disabled=count >= 8`), and parenthesize a bare `>` comparison (`hidden=(a > b)`) and a TS type argument `<let/s=(new Set<string>())>`. Do not move the type onto the tag variable instead: `<let/s:Set<string>=new Set()>` compiles but fails type-check with TS2322 (the annotation does not flow into the initializer). A `>` nested inside `(…)`/`{…}`/`[…]` is safe (`class={ big: n > 1 }`). `<` never closes a tag (`disabled=count<=1` is fine).
|
|
9
9
|
3. State: `<let/name=initial>` (slash then var name!). Update by plain assignment in an event handler: `count++`, `text = "hi"`. No setState, no hooks.
|
|
10
|
-
4. Derived values: `<const/total=items.length * price>` auto-recomputes. Never use an effect to derive state. A tag variable is whatever the tag returns, not the attribute you passed. `<let/draft=input.text>` re-runs on every `input.text` change but returns state it controls, so `draft` keeps your edits. Pick by intent: recomputes → `<const>`, seeds then diverges → `<let>`. A `<let>` you never assign is just a frozen `<const>`. Updates batch: mid-handler a reassigned `<let>` reads current but its derived `<const>` reads stale, so recompute from the `<let>`.
|
|
10
|
+
4. Derived values: `<const/total=items.length * price>` auto-recomputes. Never use an effect to derive state. A tag variable is whatever the tag returns, not the attribute you passed. `<let/draft=input.text>` re-runs on every `input.text` change but returns state it controls, so `draft` keeps your edits; only a controllable `<let>` (`valueChange=`, or `<let/draft:=input.text>`) takes the new value. Pick by intent: recomputes → `<const>`, seeds then diverges → `<let>`. A `<let>` you never assign is just a frozen `<const>`. Updates batch: mid-handler a reassigned `<let>` reads current but its derived `<const>` reads stale, so recompute from the `<let>`.
|
|
11
11
|
5. Never mutate state in place: `items.push(x)` does not update the UI. Always reassign:
|
|
12
12
|
- add: `items = items.concat(x)`
|
|
13
13
|
- remove: `items = items.toSpliced(i, 1)`
|
|
@@ -15,9 +15,9 @@ Marko 6 = HTML superset, not JSX and not Marko 4/5 syntax. `.marko` files are co
|
|
|
15
15
|
- object: `user = { ...user, name }`
|
|
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
|
-
8. Transform in the handler when needed; number inputs give strings: `<input type="number" value=n valueChange(v) { n = +v }>`, or `value:parseFloat:=n`.
|
|
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
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>`.
|
|
20
|
-
10. Module-level values, helpers and type aliases need `static`: `static const LIMIT = 10`, `static function fmt(n) {…}`, `static type Row = {…}`. Without it `function fmt(n) {` parses as a tag: ``Unable to find entry point for custom tag `<function>` ``, an error that
|
|
20
|
+
10. Module-level values, helpers and type aliases need `static`: `static const LIMIT = 10`, `static function fmt(n) {…}`, `static type Row = {…}`. Without it `function fmt(n) {` parses as a tag: ``Unable to find entry point for custom tag `<function>` ``, an error that points at `static`. Prefer it to `<const>` for anything that never changes: `<const/LIMIT=10>` emits a per-instance signal plus a `$setup` call. `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
|
|
|
22
22
|
## Canonical component
|
|
23
23
|
|
|
@@ -129,6 +129,7 @@ Don't fetch while rendering: start data loads early, pass the promise through th
|
|
|
129
129
|
- Conditional attrs: `false`/`null` attrs are omitted from HTML. `aria-selected` etc. want strings: `aria-selected=(i === active && "true")`.
|
|
130
130
|
- `class=` / `style=` accept strings, objects, arrays: `class=["btn", { active }]`, `style={ color }` (single braces). `style=` keys are kebab-case CSS names (`{ "background-color": c }`), not camelCase.
|
|
131
131
|
- `<id/x>` mints a collision-free id for label/input wiring (`<label for=x>`/`<input id=x>`); don't hardcode ids in reusable tags; `<id/x=input.id>` reuses a caller's.
|
|
132
|
+
- Head tags render where written: a `<title>`/`<meta>`/`<link>` inside a nested component stays in the body, giving a second title or an inert canonical. `<head>` is already written by the time descendants render, so page meta has to be known before it: under @marko/run declare it in the route's `+meta.*` file and read `$global.meta` from the layout that owns `<head>`, otherwise pass it down or set it on `$global` at the render call.
|
|
132
133
|
|
|
133
134
|
## Sharing data (`$global`)
|
|
134
135
|
|
|
@@ -201,6 +202,7 @@ Each left-hand habit is an error or silently wrong.
|
|
|
201
202
|
| `const [x, setX] = useState()` / `state` / `class {}` block | `<let/x=0>` then `x = 1` |
|
|
202
203
|
| `$ const y = x * 2;` (scriptlets are removed) | `<const/y=x * 2>` |
|
|
203
204
|
| `<let/n=a + b>` for a value that should recompute | `<const/n=a + b>`; `<let>` seeds an initial value, then de-syncs by design |
|
|
205
|
+
| `<let/x=input.x>` expecting it to track `input.x` | `<const/x=input.x>`, or `<let/x:=input.x>` to make it controllable |
|
|
204
206
|
| `function fmt(n) {…}` / `const LIMIT = 10` at module level | `static function fmt(n) {…}` / `static const LIMIT = 10` |
|
|
205
207
|
| `type Row = {…}` at module level | `static type Row = {…}` |
|
|
206
208
|
| `<let x=0>` | `<let/x=0>` |
|
|
@@ -213,6 +215,7 @@ Each left-hand habit is an error or silently wrong.
|
|
|
213
215
|
| bare text on its own line at template root | wrap in an element (`<p>...`), or prefix the line with `--` and a space |
|
|
214
216
|
| `by=item` using the loop variable | `by="propName"` or `by=(item) => key`; `by=` is evaluated outside the loop |
|
|
215
217
|
| `onInput(e) { q = e.target.value }` to sync an input | `value:=q`; the change handler owns the value |
|
|
218
|
+
| `<script>` syncing a draft field back from `value` | `<const/draft=pending ?? value>`; a `<let>` holds only the uncommitted edit |
|
|
216
219
|
| fetching inside the component that renders the data | start the promise early (route handler / top of template), pass it down to `<await>` |
|
|
217
220
|
| `style={ backgroundColor: c }` (camelCase keys) | `style={ "background-color": c }` (kebab-case) |
|
|
218
221
|
| `this.querySelector` / `this.getRootNode()` in `<script>` | element ref getter: `<div/el>` then `el()` (there is no `this`) |
|
|
@@ -221,6 +224,7 @@ Each left-hand habit is an error or silently wrong.
|
|
|
221
224
|
| hand-rolled `IntersectionObserver` to defer a widget's JS | `import W from "<w>" with { load: "visible#sel" }` |
|
|
222
225
|
| imperative lib wired through `<script>` mount + cleanup | `<lifecycle onMount/onUpdate/onDestroy>` (keeps `this` across all three) |
|
|
223
226
|
| `createContext`/provider to share data | `input` (prop drilling) or request-scoped `$global` |
|
|
227
|
+
| `<title>`/`<meta>` in a nested component | put page meta in the layout that owns `<head>`; head tags never hoist |
|
|
224
228
|
| `$global.x` in client-reactive code, not allow-listed | `$global.serializedGlobals = { x: true }` first; otherwise the read is `undefined` |
|
|
225
229
|
| hand-namespaced global classes (`.my-card-title`) | `<style/styles>` + `class=styles.card` (scoped CSS modules) |
|
|
226
230
|
| `tsc --noEmit` to type check templates | `mtc`; `tsc` skips `.marko` files and exits 0 |
|
package/dist/debug/html.js
CHANGED
|
@@ -1011,7 +1011,8 @@ const replaceUnsafeRegExpSourceChar = (match) => {
|
|
|
1011
1011
|
};
|
|
1012
1012
|
function writeRegExp(state, val) {
|
|
1013
1013
|
const { source } = val;
|
|
1014
|
-
state.buf.push(
|
|
1014
|
+
if (source.includes("<")) state.buf.push(`RegExp(${quote(source, 0)}${val.flags ? ",\"" + val.flags + "\"" : ""})`);
|
|
1015
|
+
else state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags);
|
|
1015
1016
|
return true;
|
|
1016
1017
|
}
|
|
1017
1018
|
function writePromise(state, val, ref) {
|
package/dist/debug/html.mjs
CHANGED
|
@@ -1009,7 +1009,8 @@ const replaceUnsafeRegExpSourceChar = (match) => {
|
|
|
1009
1009
|
};
|
|
1010
1010
|
function writeRegExp(state, val) {
|
|
1011
1011
|
const { source } = val;
|
|
1012
|
-
state.buf.push(
|
|
1012
|
+
if (source.includes("<")) state.buf.push(`RegExp(${quote(source, 0)}${val.flags ? ",\"" + val.flags + "\"" : ""})`);
|
|
1013
|
+
else state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags);
|
|
1013
1014
|
return true;
|
|
1014
1015
|
}
|
|
1015
1016
|
function writePromise(state, val, ref) {
|
package/dist/html.js
CHANGED
|
@@ -780,7 +780,7 @@ function writeDate(state, val) {
|
|
|
780
780
|
}
|
|
781
781
|
function writeRegExp(state, val) {
|
|
782
782
|
let { source } = val;
|
|
783
|
-
return state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags), !0;
|
|
783
|
+
return source.includes("<") ? state.buf.push(`RegExp(${quote(source, 0)}${val.flags ? ",\"" + val.flags + "\"" : ""})`) : state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags), !0;
|
|
784
784
|
}
|
|
785
785
|
function writePromise(state, val, ref) {
|
|
786
786
|
let { boundary, channel } = state;
|
package/dist/html.mjs
CHANGED
|
@@ -779,7 +779,7 @@ function writeDate(state, val) {
|
|
|
779
779
|
}
|
|
780
780
|
function writeRegExp(state, val) {
|
|
781
781
|
let { source } = val;
|
|
782
|
-
return state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags), !0;
|
|
782
|
+
return source.includes("<") ? state.buf.push(`RegExp(${quote(source, 0)}${val.flags ? ",\"" + val.flags + "\"" : ""})`) : state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags), !0;
|
|
783
783
|
}
|
|
784
784
|
function writePromise(state, val, ref) {
|
|
785
785
|
let { boundary, channel } = state;
|
package/dist/translator/index.js
CHANGED
|
@@ -35,8 +35,6 @@ let package_json = require("../../package.json");
|
|
|
35
35
|
package_json = __toESM(package_json, 1);
|
|
36
36
|
let _marko_compiler = require("@marko/compiler");
|
|
37
37
|
let _marko_compiler_babel_utils = require("@marko/compiler/babel-utils");
|
|
38
|
-
let node_path = require("node:path");
|
|
39
|
-
node_path = __toESM(node_path, 1);
|
|
40
38
|
let path = require("path");
|
|
41
39
|
path = __toESM(path, 1);
|
|
42
40
|
let magic_string = require("magic-string");
|
|
@@ -1201,6 +1199,37 @@ function getSerializeSourcesForRef(ref) {
|
|
|
1201
1199
|
} else return ref.sources;
|
|
1202
1200
|
}
|
|
1203
1201
|
}
|
|
1202
|
+
function mapCrossProgramReason(program, reason, exprs) {
|
|
1203
|
+
let params;
|
|
1204
|
+
let mapped;
|
|
1205
|
+
let crossProgram = false;
|
|
1206
|
+
forEach(reason.param, (param) => {
|
|
1207
|
+
if (param.section.program === program) params = bindingUtil.add(params, param);
|
|
1208
|
+
else {
|
|
1209
|
+
crossProgram = true;
|
|
1210
|
+
mapped = exprs ? mergeSerializeReasons(mapped, getSerializeSourcesForExprs(mapParamBindingToExpr(exprs, param))) : true;
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
if (!crossProgram) return reason;
|
|
1214
|
+
return mergeRemappedSources(reason, params, mapped);
|
|
1215
|
+
}
|
|
1216
|
+
function mapDownstreamReason(program, reason, exprs) {
|
|
1217
|
+
let params;
|
|
1218
|
+
let mapped;
|
|
1219
|
+
let downstream = false;
|
|
1220
|
+
forEach(reason.param, (param) => {
|
|
1221
|
+
if (param.section.program === program) {
|
|
1222
|
+
downstream = true;
|
|
1223
|
+
mapped = mergeSerializeReasons(mapped, getSerializeSourcesForExprs(mapParamBindingToExpr(exprs, param)));
|
|
1224
|
+
} else params = bindingUtil.add(params, param);
|
|
1225
|
+
});
|
|
1226
|
+
if (!downstream) return reason;
|
|
1227
|
+
return mergeRemappedSources(reason, params, mapped);
|
|
1228
|
+
}
|
|
1229
|
+
function mergeRemappedSources(reason, params, mapped) {
|
|
1230
|
+
if (mapped !== true && (reason.state || reason.global || params)) mapped = mergeSerializeReasons(mapped, createSources(reason.state, params, reason.global));
|
|
1231
|
+
return mapped;
|
|
1232
|
+
}
|
|
1204
1233
|
function mergeSerializeReasons(a, b) {
|
|
1205
1234
|
if (a === true || b === true) return true;
|
|
1206
1235
|
return mergeSources(a, b);
|
|
@@ -1347,6 +1376,7 @@ function analyzeTagNameType(tag, allowDynamic) {
|
|
|
1347
1376
|
extra.tagNameType = 2;
|
|
1348
1377
|
extra.tagNameDynamic = true;
|
|
1349
1378
|
extra.featureType = "class";
|
|
1379
|
+
if (childFile?.ast.program.extra?.hydratesTags) (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
|
|
1350
1380
|
} else if (!childFile) {
|
|
1351
1381
|
extra.tagNameType = 2;
|
|
1352
1382
|
extra.tagNameDynamic = true;
|
|
@@ -1447,6 +1477,7 @@ function startSection(path) {
|
|
|
1447
1477
|
loc: parentTag?.node.name.loc || void 0,
|
|
1448
1478
|
depth: parentSection ? parentSection.depth + 1 : 0,
|
|
1449
1479
|
parent: parentSection,
|
|
1480
|
+
program: void 0,
|
|
1450
1481
|
sectionAccessor: void 0,
|
|
1451
1482
|
params: void 0,
|
|
1452
1483
|
referencedLocalClosures: void 0,
|
|
@@ -1470,6 +1501,7 @@ function startSection(path) {
|
|
|
1470
1501
|
isBranch: false,
|
|
1471
1502
|
structure: parentSection && !parentSection.structure ? null : []
|
|
1472
1503
|
};
|
|
1504
|
+
section.program = parentSection ? parentSection.program : section;
|
|
1473
1505
|
sections.push(section);
|
|
1474
1506
|
}
|
|
1475
1507
|
return section;
|
|
@@ -1573,7 +1605,8 @@ function getSectionRegisterReasons(section) {
|
|
|
1573
1605
|
if (section.isBranch) return false;
|
|
1574
1606
|
const { downstreamBinding } = section;
|
|
1575
1607
|
if (downstreamBinding) {
|
|
1576
|
-
|
|
1608
|
+
let downstreamReasons = getAllSerializeReasonsForBinding(downstreamBinding.binding, downstreamBinding.properties);
|
|
1609
|
+
if (downstreamReasons && downstreamReasons !== true) downstreamReasons = mapCrossProgramReason(section.program, downstreamReasons, downstreamBinding.exprs);
|
|
1577
1610
|
if (!downstreamReasons) return false;
|
|
1578
1611
|
if (isReasonDynamic(downstreamReasons) && !section.serializeReason && !section.serializeReasons.size && !section.parent?.serializeReason && !section.parent?.serializeReasons.size) return false;
|
|
1579
1612
|
return downstreamReasons;
|
|
@@ -1913,6 +1946,26 @@ function isClientAssetImport(file, request) {
|
|
|
1913
1946
|
return typeof hydrateIncludeImports === "function" ? hydrateIncludeImports(request) : !!hydrateIncludeImports?.test(request);
|
|
1914
1947
|
}
|
|
1915
1948
|
//#endregion
|
|
1949
|
+
//#region src/translator/util/binding-has-prop.ts
|
|
1950
|
+
function isSectionRendererElided(section) {
|
|
1951
|
+
return !!section.downstreamBinding && !bindingHasProperty(section.downstreamBinding.binding, section.downstreamBinding.properties);
|
|
1952
|
+
}
|
|
1953
|
+
function bindingHasProperty(binding, properties) {
|
|
1954
|
+
if (binding.pruned) return false;
|
|
1955
|
+
else if (binding.pruned === void 0) throw new Error("Binding must be pruned before checking properties");
|
|
1956
|
+
if (binding.reads.size || !properties) return true;
|
|
1957
|
+
let property;
|
|
1958
|
+
let rest;
|
|
1959
|
+
if (Array.isArray(properties)) {
|
|
1960
|
+
property = properties[0];
|
|
1961
|
+
rest = properties.length === 2 ? properties[1] : properties.slice(1);
|
|
1962
|
+
} else property = properties;
|
|
1963
|
+
const propBinding = binding.propertyAliases.get(property);
|
|
1964
|
+
if (propBinding && bindingHasProperty(propBinding, rest)) return true;
|
|
1965
|
+
for (const alias of binding.aliases) if (bindingHasProperty(alias, properties)) return true;
|
|
1966
|
+
return false;
|
|
1967
|
+
}
|
|
1968
|
+
//#endregion
|
|
1916
1969
|
//#region src/translator/util/binding-prop-tree.ts
|
|
1917
1970
|
const kDirectContent = Symbol("direct content");
|
|
1918
1971
|
function getBindingPropTree(binding) {
|
|
@@ -1973,35 +2026,70 @@ function resolveRelativeToEntry(entryFile, file, req) {
|
|
|
1973
2026
|
//#endregion
|
|
1974
2027
|
//#region src/translator/util/entry-builder.ts
|
|
1975
2028
|
const kState = Symbol();
|
|
1976
|
-
|
|
2029
|
+
const builder = {
|
|
1977
2030
|
build(entryFile, exportInit) {
|
|
1978
2031
|
const state = entryFile[kState];
|
|
1979
2032
|
if (!state) throw entryFile.path.buildCodeFrameError("Unable to build hydrate code, no files were visited before finalizing the build");
|
|
1980
2033
|
const body = [];
|
|
1981
|
-
|
|
2034
|
+
for (const asset of state.assets) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(asset)));
|
|
2035
|
+
if (state.init || state.load) {
|
|
1982
2036
|
const isPage = entryFile.path.node.extra.page;
|
|
1983
2037
|
const initHelper = isPage ? "init" : "initEmbedded";
|
|
1984
|
-
body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importSpecifier(_marko_compiler.types.identifier(initHelper), _marko_compiler.types.identifier(initHelper))], _marko_compiler.types.stringLiteral(`${runtime_info_default.name}/${entryFile.markoOpts.optimize ? "" : "debug/"}dom`))
|
|
2038
|
+
if (state.init) body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importSpecifier(_marko_compiler.types.identifier(initHelper), _marko_compiler.types.identifier(initHelper))], _marko_compiler.types.stringLiteral(`${runtime_info_default.name}/${entryFile.markoOpts.optimize ? "" : "debug/"}dom`)));
|
|
2039
|
+
for (const root of state.roots) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(root)));
|
|
2040
|
+
if (!state.init) {
|
|
2041
|
+
if (exportInit) body.push(_marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([]))));
|
|
2042
|
+
return body;
|
|
2043
|
+
}
|
|
1985
2044
|
const { runtimeId } = entryFile.markoOpts;
|
|
1986
2045
|
const readyId = !isPage && (0, _marko_compiler_babel_utils.getTemplateId)(entryFile.markoOpts, entryFile.opts.filename);
|
|
1987
2046
|
const initExpression = _marko_compiler.types.callExpression(_marko_compiler.types.identifier(initHelper), readyId ? runtimeId ? [_marko_compiler.types.stringLiteral(readyId), _marko_compiler.types.stringLiteral(runtimeId)] : [_marko_compiler.types.stringLiteral(readyId)] : runtimeId ? [_marko_compiler.types.stringLiteral(runtimeId)] : []);
|
|
1988
2047
|
body.push(exportInit ? _marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], initExpression)) : _marko_compiler.types.expressionStatement(initExpression));
|
|
1989
2048
|
} else {
|
|
1990
|
-
for (const asset of state.
|
|
2049
|
+
for (const asset of state.bundledAssets) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(asset)));
|
|
1991
2050
|
if (exportInit) body.push(_marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([]))));
|
|
1992
2051
|
}
|
|
1993
2052
|
return body;
|
|
1994
2053
|
},
|
|
1995
|
-
visit(file, entryFile, visitChild) {
|
|
2054
|
+
visit(file, entryFile, visitChild = (id, bundled = false) => {
|
|
2055
|
+
const state = entryFile[kState];
|
|
2056
|
+
const resolved = resolveRelativeToEntry(entryFile, file, id);
|
|
2057
|
+
const seenBundled = state.visited.get(resolved);
|
|
2058
|
+
if (seenBundled === false || seenBundled && bundled) return;
|
|
2059
|
+
state.visited.set(resolved, bundled);
|
|
2060
|
+
const childFile = (0, _marko_compiler_babel_utils.loadFileForImport)(entryFile, resolved);
|
|
2061
|
+
if (childFile) builder.visit(childFile, entryFile);
|
|
2062
|
+
}) {
|
|
1996
2063
|
const state = entryFile[kState] ||= {
|
|
1997
2064
|
init: false,
|
|
1998
|
-
|
|
2065
|
+
load: false,
|
|
2066
|
+
bundled: 0,
|
|
2067
|
+
roots: [],
|
|
2068
|
+
assets: /* @__PURE__ */ new Set(),
|
|
2069
|
+
bundledAssets: /* @__PURE__ */ new Set(),
|
|
2070
|
+
visited: /* @__PURE__ */ new Map([[(0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, entryFile.opts.filename), false]])
|
|
1999
2071
|
};
|
|
2000
2072
|
const programExtra = file.path.node.extra;
|
|
2001
2073
|
const { analyzedTags, assetImports } = file.metadata.marko;
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2074
|
+
const { loadImports } = programExtra;
|
|
2075
|
+
const init = !!(programExtra.isInteractive || programExtra.needsCompat);
|
|
2076
|
+
const load = !!programExtra.hasClientStatement;
|
|
2077
|
+
const isRoot = !state.bundled && (init || load || !!programExtra.hasResumes);
|
|
2078
|
+
if (init) state.init = true;
|
|
2079
|
+
if (load) state.load = true;
|
|
2080
|
+
if (isRoot) state.roots.push((0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, file.opts.filename));
|
|
2081
|
+
if (assetImports) {
|
|
2082
|
+
const assets = isRoot || state.bundled ? state.bundledAssets : state.assets;
|
|
2083
|
+
for (const request of assetImports) assets.add(resolveRelativeToEntry(entryFile, file, request));
|
|
2084
|
+
}
|
|
2085
|
+
if (isRoot) state.bundled++;
|
|
2086
|
+
for (const tag of analyzedTags ? [...analyzedTags] : []) {
|
|
2087
|
+
const lazy = loadImports?.has(tag);
|
|
2088
|
+
if (lazy) state.bundled++;
|
|
2089
|
+
visitChild(tag, !!state.bundled);
|
|
2090
|
+
if (lazy) state.bundled--;
|
|
2091
|
+
}
|
|
2092
|
+
if (isRoot) state.bundled--;
|
|
2005
2093
|
}
|
|
2006
2094
|
};
|
|
2007
2095
|
//#endregion
|
|
@@ -2536,26 +2624,6 @@ function sectionHasSetupStatements(section) {
|
|
|
2536
2624
|
return false;
|
|
2537
2625
|
}
|
|
2538
2626
|
//#endregion
|
|
2539
|
-
//#region src/translator/util/binding-has-prop.ts
|
|
2540
|
-
function isSectionRendererElided(section) {
|
|
2541
|
-
return !!section.downstreamBinding && !bindingHasProperty(section.downstreamBinding.binding, section.downstreamBinding.properties);
|
|
2542
|
-
}
|
|
2543
|
-
function bindingHasProperty(binding, properties) {
|
|
2544
|
-
if (binding.pruned) return false;
|
|
2545
|
-
else if (binding.pruned === void 0) throw new Error("Binding must be pruned before checking properties");
|
|
2546
|
-
if (binding.reads.size || !properties) return true;
|
|
2547
|
-
let property;
|
|
2548
|
-
let rest;
|
|
2549
|
-
if (Array.isArray(properties)) {
|
|
2550
|
-
property = properties[0];
|
|
2551
|
-
rest = properties.length === 2 ? properties[1] : properties.slice(1);
|
|
2552
|
-
} else property = properties;
|
|
2553
|
-
const propBinding = binding.propertyAliases.get(property);
|
|
2554
|
-
if (propBinding && bindingHasProperty(propBinding, rest)) return true;
|
|
2555
|
-
for (const alias of binding.aliases) if (bindingHasProperty(alias, properties)) return true;
|
|
2556
|
-
return false;
|
|
2557
|
-
}
|
|
2558
|
-
//#endregion
|
|
2559
2627
|
//#region src/translator/util/module-registrations.ts
|
|
2560
2628
|
/**
|
|
2561
2629
|
* Writes the registrations for module scoped functions: the ones this template
|
|
@@ -6364,6 +6432,9 @@ var program_default = {
|
|
|
6364
6432
|
const paramsBinding = programExtra.binding;
|
|
6365
6433
|
if (paramsBinding && !paramsBinding.pruned) programExtra.domExports.params = getBindingPropTree(paramsBinding);
|
|
6366
6434
|
const section = programExtra.section;
|
|
6435
|
+
forEachSection((childSection) => {
|
|
6436
|
+
programExtra.hasResumes ||= !!(childSection.serializeReason || childSection.serializeReasons.size || childSection !== section && !isSectionRendererElided(childSection) && getSectionRegisterReasons(childSection));
|
|
6437
|
+
});
|
|
6367
6438
|
if (!section.hoistedTo && !sectionHasSetupStatements(section)) programExtra.domExports.setupEmpty = true;
|
|
6368
6439
|
}
|
|
6369
6440
|
},
|
|
@@ -6388,16 +6459,8 @@ var program_default = {
|
|
|
6388
6459
|
}
|
|
6389
6460
|
if (isDOMPageEntry) {
|
|
6390
6461
|
const entryFile = program.hub.file;
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
entry_builder_default.visit(entryFile, entryFile, function visitChild(resolved) {
|
|
6394
|
-
if (!visitedFiles.has(resolved)) {
|
|
6395
|
-
visitedFiles.add(resolved);
|
|
6396
|
-
const file = (0, _marko_compiler_babel_utils.loadFileForImport)(entryFile, resolved);
|
|
6397
|
-
if (file) entry_builder_default.visit(file, entryFile, (id) => visitChild(resolveRelativeToEntry(entryFile, file, id)));
|
|
6398
|
-
}
|
|
6399
|
-
});
|
|
6400
|
-
program.node.body = entry_builder_default.build(entryFile);
|
|
6462
|
+
builder.visit(entryFile, entryFile);
|
|
6463
|
+
program.node.body = builder.build(entryFile);
|
|
6401
6464
|
program.skip();
|
|
6402
6465
|
return;
|
|
6403
6466
|
}
|
|
@@ -6444,13 +6507,16 @@ var program_default = {
|
|
|
6444
6507
|
//#endregion
|
|
6445
6508
|
//#region src/translator/util/set-tag-sections-downstream.ts
|
|
6446
6509
|
const [getTagDownstreams] = createSectionState("tag-downstreams", () => /* @__PURE__ */ new Map());
|
|
6447
|
-
function setTagDownstream(tag, binding) {
|
|
6448
|
-
if (binding) getTagDownstreams(getSection(tag)).set(tag,
|
|
6510
|
+
function setTagDownstream(tag, binding, exprs) {
|
|
6511
|
+
if (binding) getTagDownstreams(getSection(tag)).set(tag, {
|
|
6512
|
+
binding,
|
|
6513
|
+
exprs
|
|
6514
|
+
});
|
|
6449
6515
|
}
|
|
6450
6516
|
function finalizeTagDownstreams(section) {
|
|
6451
|
-
for (const [tag, binding] of getTagDownstreams(section)) crawlSectionsAndSetBinding(tag, binding);
|
|
6517
|
+
for (const [tag, { binding, exprs }] of getTagDownstreams(section)) crawlSectionsAndSetBinding(tag, binding, exprs);
|
|
6452
6518
|
}
|
|
6453
|
-
function crawlSectionsAndSetBinding(tag, binding, properties, skip) {
|
|
6519
|
+
function crawlSectionsAndSetBinding(tag, binding, exprs, properties, skip) {
|
|
6454
6520
|
if (!skip) {
|
|
6455
6521
|
const contentSection = getSectionForBody(tag.get("body"));
|
|
6456
6522
|
if (contentSection) {
|
|
@@ -6460,7 +6526,8 @@ function crawlSectionsAndSetBinding(tag, binding, properties, skip) {
|
|
|
6460
6526
|
});
|
|
6461
6527
|
contentSection.downstreamBinding = target && (target.noSerialize || includes(target.noSerializeProperties, "content")) ? false : {
|
|
6462
6528
|
binding,
|
|
6463
|
-
properties: concat(properties, "content")
|
|
6529
|
+
properties: concat(properties, "content"),
|
|
6530
|
+
exprs
|
|
6464
6531
|
};
|
|
6465
6532
|
}
|
|
6466
6533
|
}
|
|
@@ -6469,8 +6536,8 @@ function crawlSectionsAndSetBinding(tag, binding, properties, skip) {
|
|
|
6469
6536
|
const attrTags = getAttrTagPaths(tag);
|
|
6470
6537
|
for (const child of attrTags) if (child.isMarkoTag()) if ((0, _marko_compiler_babel_utils.isAttributeTag)(child)) {
|
|
6471
6538
|
const attrTagMeta = attrTagLookup[getTagName(child)];
|
|
6472
|
-
crawlSectionsAndSetBinding(child, binding, concat(properties, attrTagMeta.name));
|
|
6473
|
-
} else crawlSectionsAndSetBinding(child, binding, properties, true);
|
|
6539
|
+
crawlSectionsAndSetBinding(child, binding, exprs, concat(properties, attrTagMeta.name));
|
|
6540
|
+
} else crawlSectionsAndSetBinding(child, binding, exprs, properties, true);
|
|
6474
6541
|
}
|
|
6475
6542
|
//#endregion
|
|
6476
6543
|
//#region src/translator/util/translate-var.ts
|
|
@@ -6537,10 +6604,10 @@ function knownTagAnalyze(tag, contentSection, propTree) {
|
|
|
6537
6604
|
startSection(tagBody);
|
|
6538
6605
|
trackParamsReferences(tagBody, 3);
|
|
6539
6606
|
getKnownTags(section).push(tagExtra);
|
|
6540
|
-
setTagDownstream(tag, propTree?.props?.[0]?.binding);
|
|
6541
6607
|
tagExtra[kContentSection] = contentSection;
|
|
6542
6608
|
const varBinding = trackVarReferences(tag, 5);
|
|
6543
6609
|
const exprs = tagExtra[kKnownExprs] = analyzeParams(tagExtra, section, tag, propTree, attrExprs);
|
|
6610
|
+
setTagDownstream(tag, propTree?.props?.[0]?.binding, exprs);
|
|
6544
6611
|
if (varBinding) {
|
|
6545
6612
|
addSetupStatement(section);
|
|
6546
6613
|
const mutatesTagVar = !!(tag.node.var.type === "Identifier" && tag.scope.getBinding(tag.node.var.name)?.constantViolations.length);
|
|
@@ -6656,7 +6723,7 @@ function analyzeParams(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
|
6656
6723
|
}
|
|
6657
6724
|
if (!propTree.props || propTree.rest || tag.node.arguments?.some((node) => _marko_compiler.types.isSpreadElement(node))) {
|
|
6658
6725
|
const extra = inputExpr.value = mergeReferences(section, tag.node, getAllTagReferenceNodes(tag.node));
|
|
6659
|
-
setBindingDownstream(propTree.binding, extra);
|
|
6726
|
+
setBindingDownstream(propTree.binding, extra, inputExpr);
|
|
6660
6727
|
return inputExpr;
|
|
6661
6728
|
}
|
|
6662
6729
|
const known = inputExpr.known = {};
|
|
@@ -6671,7 +6738,7 @@ function analyzeParams(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
|
6671
6738
|
i++;
|
|
6672
6739
|
}
|
|
6673
6740
|
const attrPropsTree = propTree.props[i];
|
|
6674
|
-
if (attrPropsTree) known[i] = analyzeAttrs(rootTagExtra, section, tag, attrPropsTree, rootAttrExprs);
|
|
6741
|
+
if (attrPropsTree) known[i] = analyzeAttrs(rootTagExtra, section, tag, attrPropsTree, rootAttrExprs, inputExpr);
|
|
6675
6742
|
else {
|
|
6676
6743
|
const args = tag.node.arguments;
|
|
6677
6744
|
tag.node.arguments = null;
|
|
@@ -6680,11 +6747,11 @@ function analyzeParams(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
|
6680
6747
|
}
|
|
6681
6748
|
return inputExpr;
|
|
6682
6749
|
}
|
|
6683
|
-
function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
6750
|
+
function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs, rootExprs) {
|
|
6684
6751
|
const inputExpr = {};
|
|
6685
6752
|
if (!propTree.props) {
|
|
6686
6753
|
const extra = inputExpr.value = mergeReferences(section, tag.node, getAllTagReferenceNodes(tag.node));
|
|
6687
|
-
setBindingDownstream(propTree.binding, extra);
|
|
6754
|
+
setBindingDownstream(propTree.binding, extra, rootExprs);
|
|
6688
6755
|
return inputExpr;
|
|
6689
6756
|
}
|
|
6690
6757
|
const known = inputExpr.known = {};
|
|
@@ -6716,7 +6783,7 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
|
6716
6783
|
known[attrTagMeta.name] = { value: rootTagExtra };
|
|
6717
6784
|
} else if (childAttrExport.props) {
|
|
6718
6785
|
remaining.delete(attrTagMeta.name);
|
|
6719
|
-
known[attrTagMeta.name] = analyzeAttrs(rootTagExtra, section, child, childAttrExport, rootAttrExprs);
|
|
6786
|
+
known[attrTagMeta.name] = analyzeAttrs(rootTagExtra, section, child, childAttrExport, rootAttrExprs, rootExprs);
|
|
6720
6787
|
} else analyzeDynamicAttrTagChildGroup(attrTagMeta.group, child);
|
|
6721
6788
|
} else {
|
|
6722
6789
|
const group = child.node.extra.attributeTagGroup;
|
|
@@ -6752,7 +6819,7 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
|
6752
6819
|
const groupKnownValue = { value: groupExtra };
|
|
6753
6820
|
rootAttrExprs.add(groupExtra);
|
|
6754
6821
|
forEach(bindings, (binding) => {
|
|
6755
|
-
setBindingDownstream(binding, groupExtra);
|
|
6822
|
+
setBindingDownstream(binding, groupExtra, rootExprs);
|
|
6756
6823
|
});
|
|
6757
6824
|
for (const name of group) {
|
|
6758
6825
|
const attrTagMeta = attrTagLookup[name];
|
|
@@ -6795,7 +6862,7 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
|
6795
6862
|
known[attr.name] = { value: attrExtra };
|
|
6796
6863
|
rootAttrExprs.add(attrExtra);
|
|
6797
6864
|
addSetupExpr(section, attr.value);
|
|
6798
|
-
setBindingDownstream(templateExportAttr.binding, attrExtra);
|
|
6865
|
+
setBindingDownstream(templateExportAttr.binding, attrExtra, rootExprs);
|
|
6799
6866
|
if (getRootSection(templateExportAttr.binding.section) !== (0, _marko_compiler_babel_utils.getProgram)().node.extra.section && isInvokeOnlyBinding(templateExportAttr.binding)) attrExtra.invokeOnly = true;
|
|
6800
6867
|
if (knownSpread && !includes(knownSpread.binding.excludeProperties, attr.name)) addRead(attrExtra, {}, getOrCreatePropertyAlias(knownSpread.binding, attr.name), section, void 0);
|
|
6801
6868
|
}
|
|
@@ -6813,16 +6880,16 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
|
|
|
6813
6880
|
known[prop] = { value: propExtra };
|
|
6814
6881
|
rootAttrExprs.add(propExtra);
|
|
6815
6882
|
addRead(propExtra, propExtra, propBinding, section, void 0);
|
|
6816
|
-
setBindingDownstream(templateExportAttr === true ? propTree.rest.binding : templateExportAttr.binding, propExtra);
|
|
6883
|
+
setBindingDownstream(templateExportAttr === true ? propTree.rest.binding : templateExportAttr.binding, propExtra, rootExprs);
|
|
6817
6884
|
}
|
|
6818
6885
|
else if (spreadReferenceNodes) if (remaining.size || propTree.rest && !propTree.rest.props) {
|
|
6819
6886
|
inputExpr.value = mergeReferences(section, tag.node, spreadReferenceNodes);
|
|
6820
|
-
setBindingDownstream(propTree.rest?.binding || propTree.binding, inputExpr.value);
|
|
6887
|
+
setBindingDownstream(propTree.rest?.binding || propTree.binding, inputExpr.value, rootExprs);
|
|
6821
6888
|
} else dropNodes(spreadReferenceNodes);
|
|
6822
6889
|
else {
|
|
6823
6890
|
if (restReferenceNodes) {
|
|
6824
6891
|
inputExpr.value = mergeReferences(section, tag.node, restReferenceNodes);
|
|
6825
|
-
setBindingDownstream(propTree.rest.binding, inputExpr.value);
|
|
6892
|
+
setBindingDownstream(propTree.rest.binding, inputExpr.value, rootExprs);
|
|
6826
6893
|
}
|
|
6827
6894
|
if (remaining.size) addSetupStatement(section);
|
|
6828
6895
|
if (propTree.rest && !propTree.rest.props) addSetupExpr(section, tag.node);
|
|
@@ -7057,41 +7124,6 @@ function writeAttrsToSignals(tag, propTree, importAlias, info) {
|
|
|
7057
7124
|
if (propTree.rest && !propTree.rest.props) addStatement("render", info.tagSection, tagReferencedBindings, _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(info.getBindingIdentifier(propTree.rest.binding, importAlias + "_$rest"), [createScopeReadExpression(info.childScopeBinding, info.tagSection), _marko_compiler.types.objectExpression(restProps || [])])), true);
|
|
7058
7125
|
}
|
|
7059
7126
|
}
|
|
7060
|
-
function mapParamReasonToExpr(exprs, reason) {
|
|
7061
|
-
if (reason) {
|
|
7062
|
-
if (reason === true) return true;
|
|
7063
|
-
const result = /* @__PURE__ */ new Set();
|
|
7064
|
-
forEach(reason, (prop) => {
|
|
7065
|
-
forEach(mapParamBindingToExpr(exprs, prop), (expr) => {
|
|
7066
|
-
result.add(expr);
|
|
7067
|
-
});
|
|
7068
|
-
});
|
|
7069
|
-
return fromIter(result);
|
|
7070
|
-
}
|
|
7071
|
-
}
|
|
7072
|
-
function mapParamBindingToExpr(exprs, binding) {
|
|
7073
|
-
const isWholeAlias = binding.property === void 0 && binding.upstreamAlias !== void 0;
|
|
7074
|
-
const props = [];
|
|
7075
|
-
let curBinding = isWholeAlias ? binding.upstreamAlias : binding;
|
|
7076
|
-
while (curBinding && (curBinding.property !== void 0 || curBinding.upstreamAlias)) {
|
|
7077
|
-
if (curBinding.property !== void 0) props.push(curBinding.property);
|
|
7078
|
-
curBinding = curBinding.upstreamAlias;
|
|
7079
|
-
}
|
|
7080
|
-
let curExpr = exprs;
|
|
7081
|
-
for (let i = props.length; i--;) {
|
|
7082
|
-
const nestedExpr = curExpr.known?.[props[i]];
|
|
7083
|
-
if (!nestedExpr) return curExpr.value;
|
|
7084
|
-
curExpr = nestedExpr;
|
|
7085
|
-
}
|
|
7086
|
-
if (isWholeAlias) {
|
|
7087
|
-
let result = curExpr.value;
|
|
7088
|
-
if (curExpr.known) {
|
|
7089
|
-
for (const key in curExpr.known) if (!includes(binding.excludeProperties, key)) result = concat(result, curExpr.known[key].value);
|
|
7090
|
-
}
|
|
7091
|
-
return result;
|
|
7092
|
-
}
|
|
7093
|
-
return curExpr.value;
|
|
7094
|
-
}
|
|
7095
7127
|
function callStatement(id, ...args) {
|
|
7096
7128
|
return _marko_compiler.types.expressionStatement(callExpression(id, ...args));
|
|
7097
7129
|
}
|
|
@@ -7730,10 +7762,11 @@ function getCollapsibleIntersectionSource(intersection, section) {
|
|
|
7730
7762
|
const source = sources.state || sources.param;
|
|
7731
7763
|
return source && !Array.isArray(source) && source.section === section && !source.scopeOffset ? source : void 0;
|
|
7732
7764
|
}
|
|
7733
|
-
function setBindingDownstream(binding, expr) {
|
|
7765
|
+
function setBindingDownstream(binding, expr, exprs) {
|
|
7734
7766
|
getBindingValueExprs().set(binding, expr || false);
|
|
7735
7767
|
if (expr && expr !== true) forEach(expr, (expr) => {
|
|
7736
7768
|
expr.downstream = bindingUtil.add(expr.downstream, binding);
|
|
7769
|
+
if (exprs) expr.downstreamExprs = exprs;
|
|
7737
7770
|
});
|
|
7738
7771
|
}
|
|
7739
7772
|
const [getResolvedSources] = createProgramState(() => /* @__PURE__ */ new Set());
|
|
@@ -8301,7 +8334,12 @@ function getAllSerializeReasonsForExtra(extra) {
|
|
|
8301
8334
|
else {
|
|
8302
8335
|
serializeReasonCache.set(extra, false);
|
|
8303
8336
|
forEach(extra.downstream, (binding) => {
|
|
8304
|
-
|
|
8337
|
+
let linked = getAllSerializeReasonsForBinding(binding, true);
|
|
8338
|
+
if (linked && linked !== true) {
|
|
8339
|
+
const exprs = extra.downstreamExprs;
|
|
8340
|
+
if (exprs) linked = mapDownstreamReason(binding.section.program, linked, exprs);
|
|
8341
|
+
}
|
|
8342
|
+
reason = mergeSerializeReasons(reason, linked);
|
|
8305
8343
|
});
|
|
8306
8344
|
}
|
|
8307
8345
|
if (reason) serializeReasonCache.set(extra, reason);
|
|
@@ -8383,6 +8421,41 @@ function setReadsOwner(from, to) {
|
|
|
8383
8421
|
cur = cur.parent;
|
|
8384
8422
|
}
|
|
8385
8423
|
}
|
|
8424
|
+
function mapParamReasonToExpr(exprs, reason) {
|
|
8425
|
+
if (reason) {
|
|
8426
|
+
if (reason === true) return true;
|
|
8427
|
+
const result = /* @__PURE__ */ new Set();
|
|
8428
|
+
forEach(reason, (prop) => {
|
|
8429
|
+
forEach(mapParamBindingToExpr(exprs, prop), (expr) => {
|
|
8430
|
+
result.add(expr);
|
|
8431
|
+
});
|
|
8432
|
+
});
|
|
8433
|
+
return fromIter(result);
|
|
8434
|
+
}
|
|
8435
|
+
}
|
|
8436
|
+
function mapParamBindingToExpr(exprs, binding) {
|
|
8437
|
+
const isWholeAlias = binding.property === void 0 && binding.upstreamAlias !== void 0;
|
|
8438
|
+
const props = [];
|
|
8439
|
+
let curBinding = isWholeAlias ? binding.upstreamAlias : binding;
|
|
8440
|
+
while (curBinding && (curBinding.property !== void 0 || curBinding.upstreamAlias)) {
|
|
8441
|
+
if (curBinding.property !== void 0) props.push(curBinding.property);
|
|
8442
|
+
curBinding = curBinding.upstreamAlias;
|
|
8443
|
+
}
|
|
8444
|
+
let curExpr = exprs;
|
|
8445
|
+
for (let i = props.length; i--;) {
|
|
8446
|
+
const nestedExpr = curExpr.known?.[props[i]];
|
|
8447
|
+
if (!nestedExpr) return curExpr.value;
|
|
8448
|
+
curExpr = nestedExpr;
|
|
8449
|
+
}
|
|
8450
|
+
if (isWholeAlias) {
|
|
8451
|
+
let result = curExpr.value;
|
|
8452
|
+
if (curExpr.known) {
|
|
8453
|
+
for (const key in curExpr.known) if (!includes(binding.excludeProperties, key)) result = concat(result, curExpr.known[key].value);
|
|
8454
|
+
}
|
|
8455
|
+
return result;
|
|
8456
|
+
}
|
|
8457
|
+
return curExpr.value;
|
|
8458
|
+
}
|
|
8386
8459
|
//#endregion
|
|
8387
8460
|
//#region src/translator/core/await.ts
|
|
8388
8461
|
const kDOMBinding$2 = Symbol("await tag dom binding");
|
|
@@ -9811,6 +9884,7 @@ var import_declaration_default = {
|
|
|
9811
9884
|
const { file } = importDecl.hub;
|
|
9812
9885
|
const loadFile = tagImport && (0, _marko_compiler_babel_utils.loadFileForImport)(file, value);
|
|
9813
9886
|
if (!loadFile) throw importDecl.buildCodeFrameError("Unable to resolve marko file for load import.");
|
|
9887
|
+
(file.path.node.extra.loadImports ??= /* @__PURE__ */ new Set()).add(loadFile.opts.filename);
|
|
9814
9888
|
if (loadFile.ast.program.extra?.featureType === "class") throw importDecl.buildCodeFrameError(`The [\`load\` import attribute](https://markojs.com/docs/reference/lazy-loading) is not supported for the Marko 5 (class API) tag \`${value}\`. Import it without \`load\`, or migrate the tag to the tags API.`);
|
|
9815
9889
|
}
|
|
9816
9890
|
},
|
|
@@ -10173,7 +10247,7 @@ var scriptlet_default = {
|
|
|
10173
10247
|
return;
|
|
10174
10248
|
}
|
|
10175
10249
|
mergeReferences(getOrCreateSection(scriptlet), scriptlet.node, scriptlet.node.body);
|
|
10176
|
-
if (scriptlet.node.target === "client") (0, _marko_compiler_babel_utils.getProgram)().node.extra.
|
|
10250
|
+
if (scriptlet.node.target === "client") (0, _marko_compiler_babel_utils.getProgram)().node.extra.hasClientStatement = true;
|
|
10177
10251
|
},
|
|
10178
10252
|
translate: { exit(scriptlet) {
|
|
10179
10253
|
const { node } = scriptlet;
|
|
@@ -10335,10 +10409,18 @@ function getTagRelativePath(tag) {
|
|
|
10335
10409
|
if (!relativePath) throw tagNotFoundError(tag);
|
|
10336
10410
|
return relativePath;
|
|
10337
10411
|
}
|
|
10412
|
+
const staticHint = "To declare module level JavaScript, prefix the statement with `static`.";
|
|
10338
10413
|
const knownWrongTags = /* @__PURE__ */ new Map([
|
|
10339
10414
|
["slot", "To render content passed to this tag, use a [dynamic tag](https://markojs.com/docs/reference/language#dynamic-tags): `<${input.content}/>`."],
|
|
10340
10415
|
["state", "Reactive state is declared with the [`<let>` tag](https://markojs.com/docs/reference/core-tag#let): `<let/name=initialValue>`."],
|
|
10341
|
-
["fragment", "Marko templates and tag bodies may have multiple root nodes; no fragment wrapper is needed."]
|
|
10416
|
+
["fragment", "Marko templates and tag bodies may have multiple root nodes; no fragment wrapper is needed."],
|
|
10417
|
+
["async", staticHint],
|
|
10418
|
+
["class", staticHint],
|
|
10419
|
+
["declare", staticHint],
|
|
10420
|
+
["enum", staticHint],
|
|
10421
|
+
["function", staticHint],
|
|
10422
|
+
["interface", staticHint],
|
|
10423
|
+
["type", staticHint]
|
|
10342
10424
|
]);
|
|
10343
10425
|
function tagNotFoundError(tag) {
|
|
10344
10426
|
const tagName = getTagName(tag);
|
|
@@ -10352,7 +10434,7 @@ function tagNotFoundError(tag) {
|
|
|
10352
10434
|
const closestTag = (0, fastest_levenshtein.closest)(tagName, Object.keys((0, _marko_compiler_babel_utils.getTaglibLookup)(tag.hub.file).merged.tags));
|
|
10353
10435
|
if ((0, fastest_levenshtein.distance)(tagName, closestTag) < 4) didYouMean = ` Did you mean \`<${closestTag}>\`?`;
|
|
10354
10436
|
}
|
|
10355
|
-
return tag.get("name").buildCodeFrameError(`Unable to find entry point for [custom tag](https://markojs.com/docs/reference/custom-tag#relative-custom-tags) \`<${tagName}>\`.${didYouMean}`);
|
|
10437
|
+
return tag.get("name").buildCodeFrameError(`Unable to find entry point for [custom tag](https://markojs.com/docs/reference/custom-tag#relative-custom-tags) \`<${tagName ?? getStaticTagName(tag.node)}>\`.${didYouMean}`);
|
|
10356
10438
|
}
|
|
10357
10439
|
const wordReg = /^[A-Za-z]+$/;
|
|
10358
10440
|
function getProseText(tag) {
|
|
@@ -10720,7 +10802,7 @@ var text_default = {
|
|
|
10720
10802
|
function buildAggregateError(file, rootMsg, ...paths) {
|
|
10721
10803
|
const err = /* @__PURE__ */ new SyntaxError();
|
|
10722
10804
|
const fileName = path.default.relative(_marko_compiler_modules.cwd, file.opts.filename);
|
|
10723
|
-
const finalMsg = `${rootMsg}:\n\n${paths.map(([msg, path$
|
|
10805
|
+
const finalMsg = `${rootMsg}:\n\n${paths.map(([msg, path$13]) => `\x1b[90m${msg} at ${getFileNameWithLoc(fileName, path$13)}:\x1b[0m\n${getFrame(file, path$13)}`).join("\n\n")}`;
|
|
10724
10806
|
if (!("MARKO_DEBUG" in process.env)) err.stack = finalMsg;
|
|
10725
10807
|
Object.defineProperty(err, "message", {
|
|
10726
10808
|
get() {
|
|
@@ -10884,24 +10966,30 @@ function createInteropTranslator(translate5) {
|
|
|
10884
10966
|
})));
|
|
10885
10967
|
};
|
|
10886
10968
|
return [
|
|
10887
|
-
|
|
10969
|
+
...state.needsCompat ? [_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(getCompatRuntimeFile()))] : [],
|
|
10970
|
+
...Array.from(state.compatFiles, (compatFile) => _marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(compatFile))),
|
|
10971
|
+
importHydrateProgram("6", builder.build(entryFile, true)),
|
|
10888
10972
|
importHydrateProgram("5", translate5.internalEntryBuilder.build(entryFile, true)),
|
|
10889
10973
|
_marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(_marko_compiler.types.identifier("init6"), [])),
|
|
10890
10974
|
_marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(_marko_compiler.types.identifier("init5"), []))
|
|
10891
10975
|
];
|
|
10892
10976
|
} else return translate5.internalEntryBuilder.build(entryFile);
|
|
10893
|
-
else return
|
|
10977
|
+
else return builder.build(entryFile);
|
|
10894
10978
|
},
|
|
10895
10979
|
visit(file, entryFile, visitChild) {
|
|
10896
10980
|
const state = entryFile[kState] ||= {
|
|
10897
10981
|
has5: false,
|
|
10898
|
-
has6: false
|
|
10982
|
+
has6: false,
|
|
10983
|
+
needsCompat: false,
|
|
10984
|
+
compatFiles: /* @__PURE__ */ new Set()
|
|
10899
10985
|
};
|
|
10900
10986
|
if (isTagsAPI(file)) {
|
|
10901
10987
|
state.has6 = true;
|
|
10902
|
-
|
|
10988
|
+
builder.visit(file, entryFile, visitChild);
|
|
10903
10989
|
} else {
|
|
10904
10990
|
state.has5 = true;
|
|
10991
|
+
if (file.path.node.extra?.resumesCompat) state.needsCompat = true;
|
|
10992
|
+
if (file.path.node.extra?.resumesClassFns) state.compatFiles.add((0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, file.opts.filename));
|
|
10905
10993
|
translate5.internalEntryBuilder.visit(file, entryFile, visitChild);
|
|
10906
10994
|
}
|
|
10907
10995
|
}
|
|
@@ -10914,13 +11002,13 @@ function createInteropTranslator(translate5) {
|
|
|
10914
11002
|
const entryFile = program.hub.file;
|
|
10915
11003
|
const { output, entry } = entryFile.markoOpts;
|
|
10916
11004
|
if (!(output === "dom" && entry === "page" || output === "hydrate")) return enterProgram?.call(this, program, state);
|
|
10917
|
-
const visitedFiles = /* @__PURE__ */ new
|
|
10918
|
-
entryBuilder.visit(entryFile, entryFile, function visitChild(resolved) {
|
|
10919
|
-
|
|
10920
|
-
|
|
10921
|
-
|
|
10922
|
-
|
|
10923
|
-
|
|
11005
|
+
const visitedFiles = /* @__PURE__ */ new Map([[(0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, entryFile.opts.filename), false]]);
|
|
11006
|
+
entryBuilder.visit(entryFile, entryFile, function visitChild(resolved, bundled = false) {
|
|
11007
|
+
const seenBundled = visitedFiles.get(resolved);
|
|
11008
|
+
if (seenBundled === false || seenBundled && bundled) return;
|
|
11009
|
+
visitedFiles.set(resolved, bundled);
|
|
11010
|
+
const file = (0, _marko_compiler_babel_utils.loadFileForImport)(entryFile, resolved);
|
|
11011
|
+
if (file) entryBuilder.visit(file, entryFile, (id, childBundled = false) => visitChild(resolveRelativeToEntry(entryFile, file, id), childBundled || bundled));
|
|
10924
11012
|
});
|
|
10925
11013
|
program.node.body = entryBuilder.build(entryFile);
|
|
10926
11014
|
program.skip();
|
|
@@ -10936,13 +11024,13 @@ function mergeVisitors(visitor5, visitor6) {
|
|
|
10936
11024
|
function mergeVisit(visit5, visit6) {
|
|
10937
11025
|
const enter5 = getVisitorEnter(visit5);
|
|
10938
11026
|
const enter6 = getVisitorEnter(visit6);
|
|
10939
|
-
const enter = (enter5 || enter6) && function enter(path$
|
|
10940
|
-
return (isTagsAPI() ? enter6 : enter5)?.call(this, path$
|
|
11027
|
+
const enter = (enter5 || enter6) && function enter(path$9, state) {
|
|
11028
|
+
return (isTagsAPI() ? enter6 : enter5)?.call(this, path$9, state);
|
|
10941
11029
|
};
|
|
10942
11030
|
const exit5 = getVisitorExit(visit5);
|
|
10943
11031
|
const exit6 = getVisitorExit(visit6);
|
|
10944
|
-
const exit = (exit5 || exit6) && function exit(path$
|
|
10945
|
-
return (isTagsAPI() ? exit6 : exit5)?.call(this, path$
|
|
11032
|
+
const exit = (exit5 || exit6) && function exit(path$10, state) {
|
|
11033
|
+
return (isTagsAPI() ? exit6 : exit5)?.call(this, path$10, state);
|
|
10946
11034
|
};
|
|
10947
11035
|
return exit ? enter ? {
|
|
10948
11036
|
enter,
|
|
@@ -11025,17 +11113,17 @@ function sequenceVisit(first, second) {
|
|
|
11025
11113
|
if (!first || !second) return first || second;
|
|
11026
11114
|
const enterFirst = getVisitorEnter(first);
|
|
11027
11115
|
const enterSecond = getVisitorEnter(second);
|
|
11028
|
-
const enter = (enterFirst || enterSecond) && function enter(path$
|
|
11029
|
-
const { node } = path$
|
|
11030
|
-
enterFirst?.call(this, path$
|
|
11031
|
-
if (path$
|
|
11116
|
+
const enter = (enterFirst || enterSecond) && function enter(path$11, state) {
|
|
11117
|
+
const { node } = path$11;
|
|
11118
|
+
enterFirst?.call(this, path$11, state);
|
|
11119
|
+
if (path$11.node === node) enterSecond?.call(this, path$11, state);
|
|
11032
11120
|
};
|
|
11033
11121
|
const exitFirst = getVisitorExit(first);
|
|
11034
11122
|
const exitSecond = getVisitorExit(second);
|
|
11035
|
-
const exit = (exitFirst || exitSecond) && function exit(path$
|
|
11036
|
-
const { node } = path$
|
|
11037
|
-
exitFirst?.call(this, path$
|
|
11038
|
-
if (path$
|
|
11123
|
+
const exit = (exitFirst || exitSecond) && function exit(path$12, state) {
|
|
11124
|
+
const { node } = path$12;
|
|
11125
|
+
exitFirst?.call(this, path$12, state);
|
|
11126
|
+
if (path$12.node === node) exitSecond?.call(this, path$12, state);
|
|
11039
11127
|
};
|
|
11040
11128
|
return exit ? enter ? {
|
|
11041
11129
|
enter,
|
|
@@ -11083,7 +11171,7 @@ exports.analyze = analyze;
|
|
|
11083
11171
|
exports.cheatsheet = cheatsheet;
|
|
11084
11172
|
exports.createInteropTranslator = createInteropTranslator;
|
|
11085
11173
|
exports.getRuntimeEntryFiles = getRuntimeEntryFiles;
|
|
11086
|
-
exports.internalEntryBuilder =
|
|
11174
|
+
exports.internalEntryBuilder = builder;
|
|
11087
11175
|
exports.preferAPI = preferAPI;
|
|
11088
11176
|
exports.tagDiscoveryDirs = tagDiscoveryDirs;
|
|
11089
11177
|
exports.taglibs = taglibs;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { type Config, types as t } from "@marko/compiler";
|
|
2
|
+
declare module "@marko/compiler/dist/types" {
|
|
3
|
+
interface ProgramExtra {
|
|
4
|
+
/** A Class API template that registers hoisted handlers for Tags resume. */
|
|
5
|
+
resumesClassFns?: boolean;
|
|
6
|
+
/** A Class API template whose Tags child revives through the compat runtime. */
|
|
7
|
+
resumesCompat?: boolean;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
2
10
|
type Taglibs = [taglibId: string, taglib: Record<string, unknown>][];
|
|
3
11
|
export declare function createInteropTranslator(translate5: any): {
|
|
4
12
|
version: any;
|
|
@@ -3,19 +3,33 @@ declare module "@marko/compiler/dist/types" {
|
|
|
3
3
|
interface ProgramExtra {
|
|
4
4
|
needsCompat?: boolean;
|
|
5
5
|
isInteractive?: boolean;
|
|
6
|
+
hasClientStatement?: boolean;
|
|
6
7
|
page?: boolean;
|
|
7
8
|
}
|
|
8
9
|
}
|
|
9
10
|
interface EntryState {
|
|
10
11
|
init: boolean;
|
|
12
|
+
load: boolean;
|
|
13
|
+
/** Depth of enclosing templates whose modules the bundle already loads:
|
|
14
|
+
* below a root everything arrives through its imports, and a lazy subtree
|
|
15
|
+
* is loaded by its own load entry. */
|
|
16
|
+
bundled: number;
|
|
17
|
+
roots: string[];
|
|
18
|
+
/** Assets of templates the bundle never loads; the entry imports them. */
|
|
11
19
|
assets: Set<string>;
|
|
20
|
+
/** Assets that arrive through a bundled template's imports; the entry
|
|
21
|
+
* imports them itself only when it links nothing (a server only page). */
|
|
22
|
+
bundledAssets: Set<string>;
|
|
23
|
+
/** Whether each reached file was only ever seen below a bundled template. */
|
|
24
|
+
visited: Map<string, boolean>;
|
|
12
25
|
}
|
|
13
26
|
type EntryFile = t.BabelFile & {
|
|
14
27
|
[kState]?: EntryState;
|
|
15
28
|
};
|
|
29
|
+
type VisitChild = (id: string, bundled?: boolean) => void;
|
|
16
30
|
declare const kState: unique symbol;
|
|
17
|
-
declare const
|
|
31
|
+
declare const builder: {
|
|
18
32
|
build(entryFile: EntryFile, exportInit?: boolean): t.Statement[];
|
|
19
|
-
visit(file: t.BabelFile, entryFile: EntryFile, visitChild
|
|
33
|
+
visit(file: t.BabelFile, entryFile: EntryFile, visitChild?: VisitChild): void;
|
|
20
34
|
};
|
|
21
|
-
export default
|
|
35
|
+
export default builder;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { types as t } from "@marko/compiler";
|
|
2
2
|
import { type BindingPropTree } from "./binding-prop-tree";
|
|
3
|
-
import { type Binding } from "./references";
|
|
3
|
+
import { type Binding, type KnownExprs } from "./references";
|
|
4
4
|
import { type Section } from "./sections";
|
|
5
|
-
interface KnownExprs {
|
|
6
|
-
known?: Record<string, KnownExprs>;
|
|
7
|
-
value?: t.NodeExtra;
|
|
8
|
-
}
|
|
9
5
|
declare const kContentSection: unique symbol;
|
|
10
6
|
declare const kChildScopeBinding: unique symbol;
|
|
11
7
|
declare const kChildOffsetScopeBinding: unique symbol;
|
|
@@ -90,6 +90,9 @@ declare module "@marko/compiler/dist/types" {
|
|
|
90
90
|
section?: Section;
|
|
91
91
|
referencedBindings?: ReferencedBindings;
|
|
92
92
|
downstream?: Opt<Binding>;
|
|
93
|
+
/** The tag-root `KnownExprs` of the call site that linked this expression
|
|
94
|
+
* to a downstream template's binding, for dereferencing its reasons. */
|
|
95
|
+
downstreamExprs?: KnownExprs;
|
|
93
96
|
binding?: Binding;
|
|
94
97
|
assignment?: Binding;
|
|
95
98
|
assignmentTo?: Binding;
|
|
@@ -141,7 +144,7 @@ export declare const intersectionMeta: WeakMap<Intersection, {
|
|
|
141
144
|
scopeOffset: Binding | undefined;
|
|
142
145
|
}>;
|
|
143
146
|
export declare const collapsedIntersectionSource: WeakMap<Intersection, Binding>;
|
|
144
|
-
export declare function setBindingDownstream(binding: Binding, expr: boolean | Opt<t.NodeExtra
|
|
147
|
+
export declare function setBindingDownstream(binding: Binding, expr: boolean | Opt<t.NodeExtra>, exprs?: KnownExprs): void;
|
|
145
148
|
export declare function createSources(state: Sources["state"], param: Sources["param"], global?: Sources["global"]): Sources;
|
|
146
149
|
export declare function compareSources(a: Sources, b: Sources): number;
|
|
147
150
|
export declare function mergeSources(a: undefined | Sources, b: undefined | Sources): Sources | undefined;
|
|
@@ -191,3 +194,9 @@ export declare function isRegisteredFnExtra(extra: t.NodeExtra | undefined): ext
|
|
|
191
194
|
export declare function getCanonicalExtra<T extends t.NodeExtra>(extra: T): T;
|
|
192
195
|
export declare function getAllSerializeReasonsForExtra(extra: t.NodeExtra): undefined | SerializeReason;
|
|
193
196
|
export declare function getAllSerializeReasonsForBinding(binding: Binding, properties?: Opt<string> | true): undefined | SerializeReason;
|
|
197
|
+
export interface KnownExprs {
|
|
198
|
+
known?: Record<string, KnownExprs>;
|
|
199
|
+
value?: t.NodeExtra;
|
|
200
|
+
}
|
|
201
|
+
export declare function mapParamReasonToExpr(exprs: KnownExprs, reason: boolean | Opt<InputBinding | ParamBinding>): true | Many<t.NodeExtra> | t.NodeExtra | undefined;
|
|
202
|
+
export declare function mapParamBindingToExpr(exprs: KnownExprs, binding: InputBinding | ParamBinding): Opt<t.NodeExtra>;
|
|
@@ -5,7 +5,7 @@ import * as ContentType from "./constants/content-type";
|
|
|
5
5
|
import type * as Step from "./constants/step";
|
|
6
6
|
import * as StructureKind from "./constants/structure-kind";
|
|
7
7
|
import { type Opt, Sorted } from "./optional";
|
|
8
|
-
import { type Binding, type InputBinding, type ParamBinding, type ReferencedBindings, type Sources } from "./references";
|
|
8
|
+
import { type Binding, type InputBinding, type KnownExprs, type ParamBinding, type ReferencedBindings, type Sources } from "./references";
|
|
9
9
|
import { type SerializeReason } from "./serialize-reasons";
|
|
10
10
|
export interface ParamSerializeReasonGroup {
|
|
11
11
|
id: symbol;
|
|
@@ -50,6 +50,7 @@ export interface Section {
|
|
|
50
50
|
loc: t.SourceLocation | undefined;
|
|
51
51
|
depth: number;
|
|
52
52
|
parent: Section | undefined;
|
|
53
|
+
program: Section;
|
|
53
54
|
sectionAccessor: {
|
|
54
55
|
binding: Binding;
|
|
55
56
|
prefix: AccessorPrefix;
|
|
@@ -71,6 +72,7 @@ export interface Section {
|
|
|
71
72
|
downstreamBinding: {
|
|
72
73
|
binding: Binding;
|
|
73
74
|
properties: Opt<string>;
|
|
75
|
+
exprs: KnownExprs | undefined;
|
|
74
76
|
} | false | undefined;
|
|
75
77
|
hasAbortSignal: boolean;
|
|
76
78
|
/** Count of distinct `$signal` expression roots; analyze allocates each
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { types as t } from "@marko/compiler";
|
|
2
2
|
import { AccessorPrefix, AccessorProp } from "../../common/types";
|
|
3
3
|
import { type Opt } from "./optional";
|
|
4
|
-
import { type Binding, type ReferencedBindings, type Sources } from "./references";
|
|
4
|
+
import { type Binding, type KnownExprs, type ReferencedBindings, type Sources } from "./references";
|
|
5
5
|
import type { Section } from "./sections";
|
|
6
6
|
export type SerializeReasons = true | [Sources, ...Sources[]];
|
|
7
7
|
export type SerializeReason = true | Sources;
|
|
@@ -19,6 +19,8 @@ export declare function getSerializeReason(section: Section, prop?: Binding | Ac
|
|
|
19
19
|
export declare function getSerializeSourcesForExpr(expr: t.NodeExtra): Sources | undefined;
|
|
20
20
|
export declare function getSerializeSourcesForExprs(exprs: Opt<t.NodeExtra> | boolean): true | Sources | undefined;
|
|
21
21
|
export declare function getSerializeSourcesForRef(ref: ReferencedBindings): Sources | undefined;
|
|
22
|
+
export declare function mapCrossProgramReason(program: Section, reason: Sources, exprs: KnownExprs | undefined): SerializeReason | undefined;
|
|
23
|
+
export declare function mapDownstreamReason(program: Section, reason: Sources, exprs: KnownExprs): SerializeReason | undefined;
|
|
22
24
|
export declare function mergeSerializeReasons(a: SerializeReason, b: undefined | SerializeReason): SerializeReason;
|
|
23
25
|
export declare function mergeSerializeReasons(a: undefined | SerializeReason, b: SerializeReason): SerializeReason;
|
|
24
26
|
export declare function mergeSerializeReasons(a: undefined | SerializeReason, b: undefined | SerializeReason): SerializeReason | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { types as t } from "@marko/compiler";
|
|
2
|
-
import type { Binding } from "./references";
|
|
2
|
+
import type { Binding, KnownExprs } from "./references";
|
|
3
3
|
import { type Section } from "./sections";
|
|
4
|
-
export declare function setTagDownstream(tag: t.NodePath<t.MarkoTag>, binding: undefined | Binding): void;
|
|
4
|
+
export declare function setTagDownstream(tag: t.NodePath<t.MarkoTag>, binding: undefined | Binding, exprs?: KnownExprs): void;
|
|
5
5
|
export declare function finalizeTagDownstreams(section: Section): void;
|
|
@@ -4,6 +4,8 @@ import * as TagNameType from "./constants/tag-name-type";
|
|
|
4
4
|
declare module "@marko/compiler/dist/types" {
|
|
5
5
|
interface ProgramExtra {
|
|
6
6
|
featureType?: "class" | "tags";
|
|
7
|
+
/** Set by the Class API translator when Tags content resumes below here. */
|
|
8
|
+
hydratesTags?: boolean;
|
|
7
9
|
}
|
|
8
10
|
interface MarkoTagExtra {
|
|
9
11
|
tagNameType?: TagNameType;
|
|
@@ -2,6 +2,10 @@ import { types as t } from "@marko/compiler";
|
|
|
2
2
|
import type { LoadTrigger } from "../../html/assets";
|
|
3
3
|
import { type ResolvedExport } from "./function";
|
|
4
4
|
declare module "@marko/compiler/dist/types" {
|
|
5
|
+
interface ProgramExtra {
|
|
6
|
+
/** Absolute filenames of templates this one imports with `load`. */
|
|
7
|
+
loadImports?: Set<string>;
|
|
8
|
+
}
|
|
5
9
|
interface NodeExtra {
|
|
6
10
|
tagImport?: string;
|
|
7
11
|
loadImport?: LoadImportConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "marko",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.45",
|
|
4
4
|
"description": "Optimized runtime for Marko templates.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -51,14 +51,14 @@
|
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@marko/compiler": "^5.42.
|
|
54
|
+
"@marko/compiler": "^5.42.3",
|
|
55
55
|
"csstype": "^3.2.3",
|
|
56
56
|
"fastest-levenshtein": "^1.0.16",
|
|
57
57
|
"magic-string": "^0.30.21"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"
|
|
61
|
-
"marko": "
|
|
60
|
+
"marko": "5.39.37",
|
|
61
|
+
"@marko/runtime-tags": "npm:marko@6.3.45"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=22"
|