@jay-framework/compiler-jay-html 0.24.6 → 0.25.0
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/dist/index.d.cts +27 -19
- package/dist/index.js +872 -624
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { camelCase as camelCase$1, JayImportedType, JayString, isObjectType as isObjectType$1, isImportedType, isRecursiveType,
|
|
1
|
+
import { camelCase as camelCase$1, JayImportedType, JayString, JayUnknown, isObjectType as isObjectType$1, isImportedType, isRecursiveType, Imports, Import, RenderFragment, WithValidations, isArrayType as isArrayType$1, isAtomicType, isPromiseType, isEnumType, GenerateTarget, hasRefs, JayTypeAlias, JayUnionType, mkRefsTree, equalJayTypes, mkRef, JayComponentType, JayHTMLType, getModeFileExtension, isHtmlStringType, RuntimeMode, nestRefs, mergeRefsTrees, SourceFileFormat, JayEnumType, JayObjectType, JayArrayType, JayPromiseType, resolvePrimitiveType, JayRecursiveType, JAY_CONTRACT_EXTENSION as JAY_CONTRACT_EXTENSION$1, ImportsFor, JAY_FULLSTACK_COMPONENTS, hoistFreeRefs, freeRefsAugmentedRefType, isComponentType as isComponentType$1, JayErrorType, JayOptionalType, JayRecordType, isOptionalType, isRecordType, resolvePluginManifest, resolvePluginComponent } from "@jay-framework/compiler-shared";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { getLogger } from "@jay-framework/logger";
|
|
4
|
-
import fs
|
|
5
|
-
import fs from "fs";
|
|
4
|
+
import fs from "fs/promises";
|
|
5
|
+
import fs$1 from "fs";
|
|
6
6
|
import { analyzeExportedTypes } from "@jay-framework/compiler-analyze-exported-types";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
@@ -5777,6 +5777,7 @@ parse$1.TextNode = text_1.default;
|
|
|
5777
5777
|
parse$1.NodeType = type_1.default;
|
|
5778
5778
|
const COORD_ATTR$1 = "jay-coordinate-base";
|
|
5779
5779
|
const SCOPE_ATTR = "jay-scope";
|
|
5780
|
+
const AUTO_REF_PATTERN = /^AR\d+$/;
|
|
5780
5781
|
function assignCoordinatesToJayHtml(jayHtml, headlessContractNames) {
|
|
5781
5782
|
const root = parse_2(jayHtml, {
|
|
5782
5783
|
comment: true,
|
|
@@ -5790,6 +5791,12 @@ function assignCoordinatesToJayHtml(jayHtml, headlessContractNames) {
|
|
|
5790
5791
|
function nextScopeId(counter) {
|
|
5791
5792
|
return `S${counter.next++}`;
|
|
5792
5793
|
}
|
|
5794
|
+
function isScopeAnchorDiv(node2) {
|
|
5795
|
+
if (node2.nodeType !== NodeType.ELEMENT_NODE) return false;
|
|
5796
|
+
const el = node2;
|
|
5797
|
+
if (el.tagName?.toLowerCase() !== "div") return false;
|
|
5798
|
+
return (el.getAttribute("style") ?? "").replace(/\s+/g, "").includes("display:contents");
|
|
5799
|
+
}
|
|
5793
5800
|
function assignCoordinates(body, options) {
|
|
5794
5801
|
if (!options._refCounters) options._refCounters = /* @__PURE__ */ new Map();
|
|
5795
5802
|
const rootChildren = body.childNodes.filter(
|
|
@@ -5814,6 +5821,7 @@ function walkChildren(parent, parentCoord, scopeId, options, counter) {
|
|
|
5814
5821
|
const contractName = tagName.substring(4);
|
|
5815
5822
|
if (options.headlessContractNames.has(contractName)) {
|
|
5816
5823
|
let ref = element.getAttribute("ref");
|
|
5824
|
+
const explicitRef = !!ref && !AUTO_REF_PATTERN.test(ref);
|
|
5817
5825
|
if (!ref) {
|
|
5818
5826
|
const idx = options._refCounters.get(contractName) ?? 0;
|
|
5819
5827
|
options._refCounters.set(contractName, idx + 1);
|
|
@@ -5825,9 +5833,9 @@ function walkChildren(parent, parentCoord, scopeId, options, counter) {
|
|
|
5825
5833
|
contractName,
|
|
5826
5834
|
ref,
|
|
5827
5835
|
parentCoord,
|
|
5828
|
-
scopeId,
|
|
5829
5836
|
options,
|
|
5830
|
-
counter
|
|
5837
|
+
counter,
|
|
5838
|
+
explicitRef
|
|
5831
5839
|
);
|
|
5832
5840
|
continue;
|
|
5833
5841
|
}
|
|
@@ -5851,18 +5859,20 @@ function walkChildren(parent, parentCoord, scopeId, options, counter) {
|
|
|
5851
5859
|
walkChildren(element, coord, scopeId, options, counter);
|
|
5852
5860
|
}
|
|
5853
5861
|
}
|
|
5854
|
-
function assignHeadlessInstance(element, contractName, ref, parentCoord,
|
|
5862
|
+
function assignHeadlessInstance(element, contractName, ref, parentCoord, options, counter, explicitRef) {
|
|
5855
5863
|
const instanceCoord = `${parentCoord}/${contractName}:${ref}`;
|
|
5856
5864
|
element.setAttribute(COORD_ATTR$1, instanceCoord);
|
|
5857
5865
|
const childScopeId = nextScopeId(counter);
|
|
5858
5866
|
element.setAttribute(SCOPE_ATTR, childScopeId);
|
|
5859
|
-
const
|
|
5867
|
+
const significantTemplateChildren = element.childNodes.filter(
|
|
5860
5868
|
(n) => n.nodeType === NodeType.ELEMENT_NODE || n.nodeType === NodeType.TEXT_NODE && (n.innerText || "").trim() !== ""
|
|
5861
5869
|
);
|
|
5862
|
-
|
|
5870
|
+
const alreadyWrapped = significantTemplateChildren.length === 1 && isScopeAnchorDiv(significantTemplateChildren[0]);
|
|
5871
|
+
if (!alreadyWrapped && (explicitRef || significantTemplateChildren.length > 1)) {
|
|
5863
5872
|
const wrapper = parse_2("<div></div>").querySelector("div");
|
|
5873
|
+
if (explicitRef) wrapper.setAttribute("class", ref);
|
|
5864
5874
|
wrapper.setAttribute("style", "display: contents");
|
|
5865
|
-
const children =
|
|
5875
|
+
const children = element.childNodes;
|
|
5866
5876
|
element.innerHTML = "";
|
|
5867
5877
|
children.forEach((child) => wrapper.appendChild(child));
|
|
5868
5878
|
element.appendChild(wrapper);
|
|
@@ -5879,6 +5889,7 @@ function walkForEachChildren(parent, itemScopeId, options, counter) {
|
|
|
5879
5889
|
const contractName = tagName.substring(4);
|
|
5880
5890
|
if (options.headlessContractNames.has(contractName)) {
|
|
5881
5891
|
let ref = element.getAttribute("ref");
|
|
5892
|
+
const explicitRef = !!ref && !AUTO_REF_PATTERN.test(ref);
|
|
5882
5893
|
if (!ref) {
|
|
5883
5894
|
const counterKey = `forEach/${contractName}`;
|
|
5884
5895
|
const idx = options._refCounters.get(counterKey) ?? 0;
|
|
@@ -5891,9 +5902,9 @@ function walkForEachChildren(parent, itemScopeId, options, counter) {
|
|
|
5891
5902
|
contractName,
|
|
5892
5903
|
ref,
|
|
5893
5904
|
itemScopeId,
|
|
5894
|
-
itemScopeId,
|
|
5895
5905
|
options,
|
|
5896
|
-
counter
|
|
5906
|
+
counter,
|
|
5907
|
+
explicitRef
|
|
5897
5908
|
);
|
|
5898
5909
|
continue;
|
|
5899
5910
|
}
|
|
@@ -6108,6 +6119,18 @@ function capitalCase(input, options) {
|
|
|
6108
6119
|
}
|
|
6109
6120
|
return noCase(input, __assign({ delimiter: " ", transform: capitalCaseTransform }, options));
|
|
6110
6121
|
}
|
|
6122
|
+
function dotCase(input, options) {
|
|
6123
|
+
if (options === void 0) {
|
|
6124
|
+
options = {};
|
|
6125
|
+
}
|
|
6126
|
+
return noCase(input, __assign({ delimiter: "." }, options));
|
|
6127
|
+
}
|
|
6128
|
+
function paramCase(input, options) {
|
|
6129
|
+
if (options === void 0) {
|
|
6130
|
+
options = {};
|
|
6131
|
+
}
|
|
6132
|
+
return dotCase(input, __assign({ delimiter: "-" }, options));
|
|
6133
|
+
}
|
|
6111
6134
|
function shouldIncludeInPhase(propertyPhase, targetPhase) {
|
|
6112
6135
|
if (targetPhase === "slow") {
|
|
6113
6136
|
return propertyPhase === "slow";
|
|
@@ -6588,11 +6611,11 @@ function peg$parse(input, options) {
|
|
|
6588
6611
|
}, peg$c1 = function(comment2) {
|
|
6589
6612
|
return null;
|
|
6590
6613
|
}, peg$c2 = ":", peg$c3 = peg$literalExpectation(":", false), peg$c4 = ";", peg$c5 = peg$literalExpectation(";", false), peg$c6 = function(prop, value) {
|
|
6591
|
-
const camelProp = prop.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
6614
|
+
const camelProp = prop.startsWith("--") ? prop : prop.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
6592
6615
|
const [valueFragment, isDynamic] = value;
|
|
6593
6616
|
return {
|
|
6594
6617
|
property: camelProp,
|
|
6595
|
-
valueFragment: isDynamic ? valueFragment.map((_) => `dp(${
|
|
6618
|
+
valueFragment: isDynamic ? valueFragment.map((_) => `dp(${jayParams(valueFragment)} => ${_})`).plusImport(dp) : valueFragment,
|
|
6596
6619
|
isDynamic
|
|
6597
6620
|
};
|
|
6598
6621
|
}, peg$c7 = function() {
|
|
@@ -6630,31 +6653,32 @@ function peg$parse(input, options) {
|
|
|
6630
6653
|
if (isDynamic) {
|
|
6631
6654
|
if (tail.length === 0)
|
|
6632
6655
|
return head.map((_) => `{${_}}`);
|
|
6633
|
-
const
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
const reduced = mappedClasses.reduce(
|
|
6637
|
-
(result, fragment) => RenderFragment2.merge(result, fragment, " "),
|
|
6656
|
+
const elements = classes.map((cls) => cls instanceof RenderFragment2 ? cls : new RenderFragment2(`'${cls}'`));
|
|
6657
|
+
const reduced = elements.reduce(
|
|
6658
|
+
(result, fragment) => RenderFragment2.merge(result, fragment, ", "),
|
|
6638
6659
|
RenderFragment2.empty()
|
|
6639
6660
|
);
|
|
6640
|
-
return reduced.map((_) => `{
|
|
6661
|
+
return reduced.map((_) => `{cx(${_})}`).plusImport(cx);
|
|
6641
6662
|
} else
|
|
6642
6663
|
return new RenderFragment2(classes.join(" "), none).map((_) => `"${_}"`);
|
|
6643
6664
|
}, peg$c43 = function(head, tail) {
|
|
6644
|
-
|
|
6645
|
-
const
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
const
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6665
|
+
const classes = [head, ...tail.map((tuple) => tuple[1])];
|
|
6666
|
+
const isDynamic = classes.some((cls) => cls instanceof RenderFragment2);
|
|
6667
|
+
if (isDynamic) {
|
|
6668
|
+
if (tail.length === 0)
|
|
6669
|
+
return head.map((_) => `da(${jayParams(head)} => ${_})`);
|
|
6670
|
+
const elements = classes.map((cls) => cls instanceof RenderFragment2 ? cls : new RenderFragment2(`'${cls}'`));
|
|
6671
|
+
const arrayContents = elements.reduce(
|
|
6672
|
+
(result, fragment) => RenderFragment2.merge(result, fragment, ", "),
|
|
6673
|
+
RenderFragment2.empty()
|
|
6674
|
+
);
|
|
6675
|
+
return arrayContents.map((_) => `da(${jayParams(arrayContents)} => cx(${_}))`).plusImport(cx);
|
|
6676
|
+
}
|
|
6677
|
+
return new RenderFragment2(classes.join(" "), none).map((_) => `'${_}'`);
|
|
6654
6678
|
}, peg$c44 = function(cls) {
|
|
6655
6679
|
return cls.render().plusImport(da);
|
|
6656
6680
|
}, peg$c45 = /^[{]/, peg$c46 = peg$classExpectation(["{"], false, false), peg$c47 = /^[?]/, peg$c48 = peg$classExpectation(["?"], false, false), peg$c49 = /^[:]/, peg$c50 = peg$classExpectation([":"], false, false), peg$c51 = /^[}]/, peg$c52 = peg$classExpectation(["}"], false, false), peg$c53 = function(acc, classY, classN) {
|
|
6657
|
-
return new RenderFragment2(`${acc.rendered}?'${classY}':'${classN ? classN[3] : ""}'`, da, acc.validations);
|
|
6681
|
+
return new RenderFragment2(`${acc.rendered}?'${classY}':'${classN ? classN[3] : ""}'`, da, acc.validations, void 0, void 0, acc.parentDepth);
|
|
6658
6682
|
}, peg$c54 = /^[\-]/, peg$c55 = peg$classExpectation(["-"], false, false), peg$c56 = /^[_a-zA-Z]/, peg$c57 = peg$classExpectation(["_", ["a", "z"], ["A", "Z"]], false, false), peg$c58 = /^[_a-zA-Z0-9\-]/, peg$c59 = peg$classExpectation(["_", ["a", "z"], ["A", "Z"], ["0", "9"], "-"], false, false), peg$c60 = function() {
|
|
6659
6683
|
return text2();
|
|
6660
6684
|
}, peg$c61 = "as", peg$c62 = peg$literalExpectation("as", false), peg$c63 = ",", peg$c64 = peg$literalExpectation(",", false), peg$c65 = function(head, rename, tail) {
|
|
@@ -6669,10 +6693,10 @@ function peg$parse(input, options) {
|
|
|
6669
6693
|
return [...acc, val[3]];
|
|
6670
6694
|
}, [first]);
|
|
6671
6695
|
}, peg$c78 = function(cond) {
|
|
6672
|
-
return cond.map((_) => `ba(${
|
|
6696
|
+
return cond.map((_) => `ba(${jayParams(cond)} => ${_})`).plusImport(ba);
|
|
6673
6697
|
}, peg$c79 = function(template) {
|
|
6674
6698
|
let [renderFragment, isDynamic] = template;
|
|
6675
|
-
return isDynamic ? renderFragment.map((_) => `da(${
|
|
6699
|
+
return isDynamic ? renderFragment.map((_) => `da(${jayParams(renderFragment)} => ${_})`).plusImport(da) : renderFragment;
|
|
6676
6700
|
}, peg$c80 = function(num) {
|
|
6677
6701
|
return new RenderFragment2(num);
|
|
6678
6702
|
}, peg$c81 = function(template) {
|
|
@@ -6680,7 +6704,7 @@ function peg$parse(input, options) {
|
|
|
6680
6704
|
return renderFragment;
|
|
6681
6705
|
}, peg$c82 = function(template) {
|
|
6682
6706
|
let [renderFragment, isDynamic] = template;
|
|
6683
|
-
return isDynamic ? renderFragment.map((_) => `dp(${
|
|
6707
|
+
return isDynamic ? renderFragment.map((_) => `dp(${jayParams(renderFragment)} => ${_})`).plusImport(dp) : renderFragment;
|
|
6684
6708
|
}, peg$c83 = function(template) {
|
|
6685
6709
|
let [renderFragment, isDynamic] = template;
|
|
6686
6710
|
return isDynamic ? renderFragment.map((_) => `{${_}}`) : renderFragment;
|
|
@@ -6705,7 +6729,7 @@ function peg$parse(input, options) {
|
|
|
6705
6729
|
}
|
|
6706
6730
|
}, peg$c86 = function(template) {
|
|
6707
6731
|
let [renderFragment, isDynamic] = template;
|
|
6708
|
-
return isDynamic ? renderFragment.map((_) => `dt(${
|
|
6732
|
+
return isDynamic ? renderFragment.map((_) => `dt(${jayParams(renderFragment)} => ${_})`).plusImport(dt) : renderFragment;
|
|
6709
6733
|
}, peg$c87 = function(a, head, tail) {
|
|
6710
6734
|
const renderText2 = (w2, h) => {
|
|
6711
6735
|
return h ? h.reduce((acc, str2) => acc + str2[0] + (str2[1].length ? " " : ""), w2.length ? " " : "") : w2.length ? " " : "";
|
|
@@ -6730,7 +6754,7 @@ function peg$parse(input, options) {
|
|
|
6730
6754
|
const raw = text2();
|
|
6731
6755
|
return { kind: "binding", value: raw.slice(1, -1).trim() };
|
|
6732
6756
|
}, peg$c93 = function(cond) {
|
|
6733
|
-
return cond.map((_) => `${
|
|
6757
|
+
return cond.map((_) => `${jayParams(cond)} => ${_}`);
|
|
6734
6758
|
}, peg$c94 = "||", peg$c95 = peg$literalExpectation("||", false), peg$c96 = function(head, tail) {
|
|
6735
6759
|
if (tail.length === 0) return head;
|
|
6736
6760
|
return tail.reduce((acc, curr) => combineOr(acc, curr[3]), head);
|
|
@@ -13302,6 +13326,7 @@ function peg$parse(input, options) {
|
|
|
13302
13326
|
let da = options.da;
|
|
13303
13327
|
let dp = options.dp;
|
|
13304
13328
|
let ba = options.ba;
|
|
13329
|
+
let cx = options.cx;
|
|
13305
13330
|
let slowContext = options.slowContext;
|
|
13306
13331
|
function isSlowPhase2(path2) {
|
|
13307
13332
|
if (!slowContext) return false;
|
|
@@ -13420,6 +13445,13 @@ function peg$parse(input, options) {
|
|
|
13420
13445
|
expr: `${leftExpr} ${jsOp} ${rightExpr}`
|
|
13421
13446
|
};
|
|
13422
13447
|
}
|
|
13448
|
+
function jayParams(renderFragment) {
|
|
13449
|
+
const depth = renderFragment && renderFragment.parentDepth || 0;
|
|
13450
|
+
if (depth === 0) return vars.currentVar;
|
|
13451
|
+
let params = vars.currentVar;
|
|
13452
|
+
for (let i = 1; i <= depth; i++) params += `, _p${i}`;
|
|
13453
|
+
return `(${params})`;
|
|
13454
|
+
}
|
|
13423
13455
|
function applyStartsWith(left, right) {
|
|
13424
13456
|
if (left.type === "resolved" && right.type === "resolved") {
|
|
13425
13457
|
return { type: "resolved", value: String(left.value).startsWith(String(right.value)) };
|
|
@@ -13450,18 +13482,37 @@ function peg$parse(input, options) {
|
|
|
13450
13482
|
var expressionParser = {
|
|
13451
13483
|
parse: peg$parse
|
|
13452
13484
|
};
|
|
13485
|
+
const PARENT_TOKEN = "$parent";
|
|
13486
|
+
function parentParamName(level) {
|
|
13487
|
+
return `_p${level}`;
|
|
13488
|
+
}
|
|
13453
13489
|
class Accessor {
|
|
13454
13490
|
rootVar;
|
|
13455
13491
|
terms;
|
|
13456
13492
|
validations;
|
|
13457
13493
|
resolvedType;
|
|
13458
|
-
|
|
13494
|
+
/** DL#193: how many scopes a `$parent` access climbs (0 = current scope). */
|
|
13495
|
+
parentLevel;
|
|
13496
|
+
constructor(rootVar, terms, validations, resolvedType, parentLevel = 0) {
|
|
13459
13497
|
this.rootVar = rootVar;
|
|
13460
13498
|
this.terms = terms;
|
|
13461
13499
|
this.validations = validations;
|
|
13462
13500
|
this.resolvedType = resolvedType;
|
|
13501
|
+
this.parentLevel = parentLevel;
|
|
13463
13502
|
}
|
|
13464
13503
|
render() {
|
|
13504
|
+
if (this.parentLevel > 0) {
|
|
13505
|
+
const param = parentParamName(this.parentLevel);
|
|
13506
|
+
const rendered = this.terms.length === 0 ? param : param + "." + this.terms.join("?.");
|
|
13507
|
+
return new RenderFragment(
|
|
13508
|
+
rendered,
|
|
13509
|
+
Imports.none(),
|
|
13510
|
+
this.validations,
|
|
13511
|
+
void 0,
|
|
13512
|
+
void 0,
|
|
13513
|
+
this.parentLevel
|
|
13514
|
+
);
|
|
13515
|
+
}
|
|
13465
13516
|
let renderedAccessor = this.terms.length === 1 && this.terms[0] === "." ? this.rootVar : this.rootVar + "." + this.terms.join("?.");
|
|
13466
13517
|
return new RenderFragment(`${renderedAccessor}`, Imports.none(), this.validations);
|
|
13467
13518
|
}
|
|
@@ -13471,20 +13522,76 @@ class Variables {
|
|
|
13471
13522
|
currentType;
|
|
13472
13523
|
currentContext;
|
|
13473
13524
|
parent;
|
|
13474
|
-
children
|
|
13525
|
+
children;
|
|
13475
13526
|
depth;
|
|
13476
|
-
|
|
13527
|
+
/**
|
|
13528
|
+
* DL#193 Phase 2c: when true, this scope's `currentVar` is a real variable that is lexically
|
|
13529
|
+
* in scope at every descendant binding site (the server target inlines the whole tree into one
|
|
13530
|
+
* `renderToStream`, so `vs`, forEach item vars, and instance vars are all reachable by name).
|
|
13531
|
+
* In that world a `$parent` climb that lands on this scope must emit `currentVar` directly, not
|
|
13532
|
+
* a `_pN` closure param (which only exists in the client/hydrate per-binding callbacks). The
|
|
13533
|
+
* flag is inherited by every child scope so setting it once on the server root covers the tree.
|
|
13534
|
+
*/
|
|
13535
|
+
lexicallyInScope;
|
|
13536
|
+
constructor(currentTypes, parent = void 0, depth = 0, customVarName, children = {}, lexicallyInScope = false) {
|
|
13477
13537
|
this.currentVar = customVarName || (depth === 0 ? "vs" : "vs" + depth);
|
|
13478
13538
|
this.currentContext = depth === 0 ? "context" : "cx" + depth;
|
|
13479
13539
|
this.depth = depth;
|
|
13480
13540
|
this.parent = parent;
|
|
13481
13541
|
this.currentType = currentTypes instanceof JayImportedType ? currentTypes.type : currentTypes;
|
|
13542
|
+
this.children = children;
|
|
13543
|
+
this.lexicallyInScope = lexicallyInScope;
|
|
13544
|
+
}
|
|
13545
|
+
/**
|
|
13546
|
+
* DL#193 Phase 2c: return a view of this scope marked lexically-in-scope (see
|
|
13547
|
+
* {@link lexicallyInScope}). Used by the server target on its root scope; child scopes
|
|
13548
|
+
* inherit the flag automatically through {@link childVariableFor} / {@link childVariableForWithData}.
|
|
13549
|
+
*/
|
|
13550
|
+
asLexical() {
|
|
13551
|
+
if (this.lexicallyInScope) return this;
|
|
13552
|
+
return new Variables(
|
|
13553
|
+
this.currentType,
|
|
13554
|
+
this.parent,
|
|
13555
|
+
this.depth,
|
|
13556
|
+
this.currentVar,
|
|
13557
|
+
this.children,
|
|
13558
|
+
true
|
|
13559
|
+
);
|
|
13482
13560
|
}
|
|
13483
13561
|
resolveAccessor(accessor) {
|
|
13484
13562
|
if (accessor[0] === "jay") {
|
|
13485
13563
|
const jayPath = ["__jay", ...accessor.slice(1)];
|
|
13486
13564
|
return new Accessor(this.currentVar, jayPath, [], JayString);
|
|
13487
13565
|
}
|
|
13566
|
+
if (accessor[0] === PARENT_TOKEN) {
|
|
13567
|
+
let parentLevel = 0;
|
|
13568
|
+
let scope = this;
|
|
13569
|
+
let terms = accessor;
|
|
13570
|
+
while (terms[0] === PARENT_TOKEN) {
|
|
13571
|
+
parentLevel++;
|
|
13572
|
+
if (!scope.parent) {
|
|
13573
|
+
const message = `${"$parent".repeat(parentLevel)} used but there is no parent scope ${parentLevel} level(s) up`;
|
|
13574
|
+
return new Accessor(
|
|
13575
|
+
this.currentVar,
|
|
13576
|
+
terms.slice(1),
|
|
13577
|
+
[message],
|
|
13578
|
+
JayUnknown,
|
|
13579
|
+
parentLevel
|
|
13580
|
+
);
|
|
13581
|
+
}
|
|
13582
|
+
scope = scope.parent;
|
|
13583
|
+
terms = terms.slice(1);
|
|
13584
|
+
}
|
|
13585
|
+
const resolved = scope.resolveAccessor(terms);
|
|
13586
|
+
const effectiveParentLevel = scope.lexicallyInScope ? resolved.parentLevel : parentLevel + resolved.parentLevel;
|
|
13587
|
+
return new Accessor(
|
|
13588
|
+
scope.currentVar,
|
|
13589
|
+
resolved.terms,
|
|
13590
|
+
resolved.validations,
|
|
13591
|
+
resolved.resolvedType,
|
|
13592
|
+
effectiveParentLevel
|
|
13593
|
+
);
|
|
13594
|
+
}
|
|
13488
13595
|
let curr = this.currentType;
|
|
13489
13596
|
let validations = [];
|
|
13490
13597
|
accessor.forEach((member) => {
|
|
@@ -13506,7 +13613,14 @@ class Variables {
|
|
|
13506
13613
|
if (this.children[path2]) return this.children[path2];
|
|
13507
13614
|
else {
|
|
13508
13615
|
const resolvedForEachType = accessor.resolvedType.itemType;
|
|
13509
|
-
const variables = new Variables(
|
|
13616
|
+
const variables = new Variables(
|
|
13617
|
+
resolvedForEachType,
|
|
13618
|
+
this,
|
|
13619
|
+
this.depth + 1,
|
|
13620
|
+
void 0,
|
|
13621
|
+
{},
|
|
13622
|
+
this.lexicallyInScope
|
|
13623
|
+
);
|
|
13510
13624
|
this.children[path2] = variables;
|
|
13511
13625
|
return variables;
|
|
13512
13626
|
}
|
|
@@ -13522,7 +13636,14 @@ class Variables {
|
|
|
13522
13636
|
depth++;
|
|
13523
13637
|
parent = parent.parent;
|
|
13524
13638
|
}
|
|
13525
|
-
const variables = new Variables(
|
|
13639
|
+
const variables = new Variables(
|
|
13640
|
+
accessor.resolvedType,
|
|
13641
|
+
this,
|
|
13642
|
+
depth,
|
|
13643
|
+
void 0,
|
|
13644
|
+
{},
|
|
13645
|
+
this.lexicallyInScope
|
|
13646
|
+
);
|
|
13526
13647
|
this.children[path2] = variables;
|
|
13527
13648
|
return variables;
|
|
13528
13649
|
}
|
|
@@ -13677,6 +13798,7 @@ function doParse(expression, startRule, vars, throwOnError = false) {
|
|
|
13677
13798
|
da: Imports.for(Import.dynamicAttribute),
|
|
13678
13799
|
dp: Imports.for(Import.dynamicProperty),
|
|
13679
13800
|
ba: Imports.for(Import.booleanAttribute),
|
|
13801
|
+
cx: Imports.for(Import.classNames),
|
|
13680
13802
|
startRule
|
|
13681
13803
|
});
|
|
13682
13804
|
} catch (e2) {
|
|
@@ -13697,8 +13819,19 @@ function parseAccessor(expression, vars) {
|
|
|
13697
13819
|
function parseCondition(expression, vars) {
|
|
13698
13820
|
return doParse(expression, "conditionFunc", vars);
|
|
13699
13821
|
}
|
|
13822
|
+
function guardReactParentBinding(fragment) {
|
|
13823
|
+
if (fragment.parentDepth === 0) return fragment;
|
|
13824
|
+
return new RenderFragment(
|
|
13825
|
+
fragment.rendered,
|
|
13826
|
+
fragment.imports,
|
|
13827
|
+
[...fragment.validations, "$parent bindings are not supported in the React target"],
|
|
13828
|
+
fragment.refs,
|
|
13829
|
+
fragment.recursiveRegions,
|
|
13830
|
+
fragment.parentDepth
|
|
13831
|
+
);
|
|
13832
|
+
}
|
|
13700
13833
|
function parseReactCondition(expression, vars) {
|
|
13701
|
-
return doParse(expression, "condition", vars);
|
|
13834
|
+
return guardReactParentBinding(doParse(expression, "condition", vars));
|
|
13702
13835
|
}
|
|
13703
13836
|
function parseTextExpression(expression, vars) {
|
|
13704
13837
|
return doParse(expression, "dynamicText", vars);
|
|
@@ -13721,7 +13854,9 @@ function unescapeBackslash(jsCode) {
|
|
|
13721
13854
|
});
|
|
13722
13855
|
}
|
|
13723
13856
|
function parseReactTextExpression(expression, vars) {
|
|
13724
|
-
return
|
|
13857
|
+
return guardReactParentBinding(
|
|
13858
|
+
doParse(expression, "reactDynamicText", vars).map((_) => unescapeBackslash(_))
|
|
13859
|
+
);
|
|
13725
13860
|
}
|
|
13726
13861
|
function parseBooleanAttributeExpression(expression, vars) {
|
|
13727
13862
|
return doParse(expression, "booleanAttribute", vars);
|
|
@@ -13733,7 +13868,7 @@ function parsePropertyExpression(expression, vars) {
|
|
|
13733
13868
|
return doParse(expression, "dynamicProperty", vars);
|
|
13734
13869
|
}
|
|
13735
13870
|
function parseReactPropertyExpression(expression, vars) {
|
|
13736
|
-
return doParse(expression, "reactDynamicProperty", vars);
|
|
13871
|
+
return guardReactParentBinding(doParse(expression, "reactDynamicProperty", vars));
|
|
13737
13872
|
}
|
|
13738
13873
|
function parseComponentPropExpression(expression, vars) {
|
|
13739
13874
|
return doParse(expression, "dynamicComponentProp", vars);
|
|
@@ -13741,23 +13876,34 @@ function parseComponentPropExpression(expression, vars) {
|
|
|
13741
13876
|
function parseClassExpression(expression, vars) {
|
|
13742
13877
|
return doParse(expression, "classExpression", vars);
|
|
13743
13878
|
}
|
|
13879
|
+
const UNSUPPORTED_TARGET_PARENT_MESSAGE = "$parent bindings are not yet supported in the server target";
|
|
13880
|
+
class UnsupportedServerParentBindingError extends Error {
|
|
13881
|
+
constructor() {
|
|
13882
|
+
super(UNSUPPORTED_TARGET_PARENT_MESSAGE);
|
|
13883
|
+
this.name = "UnsupportedServerParentBindingError";
|
|
13884
|
+
}
|
|
13885
|
+
}
|
|
13886
|
+
function guardServerParentBinding(fragment) {
|
|
13887
|
+
if (fragment.parentDepth === 0) return fragment;
|
|
13888
|
+
throw new UnsupportedServerParentBindingError();
|
|
13889
|
+
}
|
|
13744
13890
|
function parseServerTemplateExpression(expression, vars) {
|
|
13745
|
-
|
|
13891
|
+
const [fragment, isDynamic] = doParse(expression, "template", vars);
|
|
13892
|
+
return [guardServerParentBinding(fragment), isDynamic];
|
|
13746
13893
|
}
|
|
13747
13894
|
function parseTemplateParts(value) {
|
|
13748
13895
|
if (!value) return [];
|
|
13749
13896
|
return doParse(value, "templateParts");
|
|
13750
13897
|
}
|
|
13751
13898
|
function parseServerCondition(expression, vars) {
|
|
13752
|
-
return doParse(expression, "condition", vars);
|
|
13899
|
+
return guardServerParentBinding(doParse(expression, "condition", vars));
|
|
13753
13900
|
}
|
|
13754
13901
|
function parseReactClassExpression(expression, vars) {
|
|
13755
|
-
const
|
|
13756
|
-
|
|
13757
|
-
|
|
13758
|
-
|
|
13902
|
+
const parsed = doParse(expression, "reactClassExpression", vars);
|
|
13903
|
+
const { rendered, validations, refs } = parsed;
|
|
13904
|
+
return guardReactParentBinding(
|
|
13905
|
+
new RenderFragment(rendered, Imports.none(), validations, refs, [], parsed.parentDepth)
|
|
13759
13906
|
);
|
|
13760
|
-
return new RenderFragment(rendered, Imports.none(), validations, refs);
|
|
13761
13907
|
}
|
|
13762
13908
|
function parseImportNames(expression) {
|
|
13763
13909
|
return doParse(expression, "importNames", void 0, true);
|
|
@@ -14136,7 +14282,7 @@ const isComponentType = (type2) => type2 instanceof JayComponentType || type2 in
|
|
|
14136
14282
|
const isComponentRef = (ref) => isComponentType(ref.elementType);
|
|
14137
14283
|
const isCollectionRef = (ref) => ref.repeated;
|
|
14138
14284
|
const isComponentCollectionRef = (ref) => isCollectionRef(ref) && isComponentRef(ref);
|
|
14139
|
-
function renderRefsType(refs, refsType, generateTarget = GenerateTarget.jay) {
|
|
14285
|
+
function renderRefsType(refs, refsType, generateTarget = GenerateTarget.jay, emitComponentRefHelpers = true, emittedHelpers) {
|
|
14140
14286
|
let renderedRefs;
|
|
14141
14287
|
let imports = Imports.none();
|
|
14142
14288
|
const componentRefs = /* @__PURE__ */ new Map();
|
|
@@ -14193,7 +14339,7 @@ function renderRefsType(refs, refsType, generateTarget = GenerateTarget.jay) {
|
|
|
14193
14339
|
}
|
|
14194
14340
|
return `${indent.curr}${ref.ref}: ${referenceType}`;
|
|
14195
14341
|
}).join(",\n");
|
|
14196
|
-
const childTypes = Object.entries(refsTree.children).filter(([
|
|
14342
|
+
const childTypes = Object.entries(refsTree.children).filter(([, childRefNode]) => {
|
|
14197
14343
|
return childRefNode.imported || hasRefs(childRefNode, false);
|
|
14198
14344
|
}).map(([childName, childRefNode]) => {
|
|
14199
14345
|
if (childRefNode.imported) {
|
|
@@ -14213,20 +14359,28 @@ ${allTypes}
|
|
|
14213
14359
|
${indent.lastLine}}`;
|
|
14214
14360
|
};
|
|
14215
14361
|
const mainType = generateTypeForPath(refs, new Indent("", true, true));
|
|
14216
|
-
const renderedComponentRefs = [...componentRefs].map(([componentName, refsNeeded]) => {
|
|
14362
|
+
const renderedComponentRefs = emitComponentRefHelpers ? [...componentRefs].map(([componentName, refsNeeded]) => {
|
|
14217
14363
|
const elementType = generateTarget === GenerateTarget.jay ? `ReturnType<typeof ${componentName}>` : "any";
|
|
14218
|
-
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14364
|
+
const refId = `${componentName}Ref`;
|
|
14365
|
+
const refsId = `${componentName}Refs`;
|
|
14366
|
+
const parts = [];
|
|
14367
|
+
if (!emittedHelpers?.has(refId)) {
|
|
14368
|
+
parts.push(
|
|
14369
|
+
`export type ${refId}<ParentVS> = MapEventEmitterViewState<ParentVS, ${elementType}>;`
|
|
14370
|
+
);
|
|
14371
|
+
imports = imports.plus(Import.MapEventEmitterViewState);
|
|
14372
|
+
emittedHelpers?.add(refId);
|
|
14373
|
+
}
|
|
14374
|
+
if (refsNeeded === 1 && !emittedHelpers?.has(refsId)) {
|
|
14375
|
+
parts.push(`export type ${refsId}<ParentVS> =
|
|
14376
|
+
ComponentCollectionProxy<ParentVS, ${refId}<ParentVS>> &
|
|
14377
|
+
OnlyEventEmitters<${refId}<ParentVS>>
|
|
14378
|
+
`);
|
|
14226
14379
|
imports = imports.plus(Import.ComponentCollectionProxy).plus(Import.OnlyEventEmitters);
|
|
14380
|
+
emittedHelpers?.add(refsId);
|
|
14227
14381
|
}
|
|
14228
|
-
return
|
|
14229
|
-
});
|
|
14382
|
+
return parts.join("\n");
|
|
14383
|
+
}).filter(Boolean) : [];
|
|
14230
14384
|
renderedRefs = `${renderedComponentRefs.join("\n")}
|
|
14231
14385
|
export interface ${refsType} ${mainType}`;
|
|
14232
14386
|
} else renderedRefs = `export interface ${refsType} {}`;
|
|
@@ -14241,16 +14395,6 @@ class RefNameGenerator {
|
|
|
14241
14395
|
newAutoRefNameGenerator() {
|
|
14242
14396
|
return "aR" + this.nextId++;
|
|
14243
14397
|
}
|
|
14244
|
-
/**
|
|
14245
|
-
* Register a constName as used with the given Variables context.
|
|
14246
|
-
* This is used when an imported ref is used to ensure later refs
|
|
14247
|
-
* with the same name get a different suffix.
|
|
14248
|
-
*/
|
|
14249
|
-
registerUsedConstName(constName, variables) {
|
|
14250
|
-
if (!this.constNamesToVariables.has(constName)) {
|
|
14251
|
-
this.constNamesToVariables.set(constName, variables);
|
|
14252
|
-
}
|
|
14253
|
-
}
|
|
14254
14398
|
newConstantName(refName, variables) {
|
|
14255
14399
|
let suffix = 2;
|
|
14256
14400
|
let constName = camelCase$1(`ref ${refName}`);
|
|
@@ -14528,6 +14672,8 @@ const REFERENCE_MANAGER_TYPES = {
|
|
|
14528
14672
|
function renderReferenceManager(refs, target) {
|
|
14529
14673
|
const { referenceManagerInit, imports } = REFERENCE_MANAGER_TYPES[target];
|
|
14530
14674
|
const options = target === 0 ? "options, " : "";
|
|
14675
|
+
let usesComponentRefsImpl = false;
|
|
14676
|
+
let usesComponentCollectionRefsImpl = false;
|
|
14531
14677
|
const usedRefManagerNames = /* @__PURE__ */ new Set();
|
|
14532
14678
|
const usedRefConstNames = /* @__PURE__ */ new Set();
|
|
14533
14679
|
const collectReservedConstNames = (refsTree) => {
|
|
@@ -14587,11 +14733,15 @@ function renderReferenceManager(refs, target) {
|
|
|
14587
14733
|
const elemCollectionRefsDeclarations = elemCollectionRefs.map((ref) => `'${ref.ref}'`).join(", ");
|
|
14588
14734
|
const compRefsDeclarations = compRefs.map((ref) => `'${ref.ref}'`).join(", ");
|
|
14589
14735
|
const compCollectionRefsDeclarations = compCollectionRefs.map((ref) => `'${ref.ref}'`).join(", ");
|
|
14736
|
+
const elemRefVars = elemRefs.map((ref) => getUniqueRefConstName(ref));
|
|
14737
|
+
const elemCollectionRefVars = elemCollectionRefs.map((ref) => getUniqueRefConstName(ref));
|
|
14738
|
+
const compRefVars = compRefs.map((ref) => getUniqueRefConstName(ref));
|
|
14739
|
+
const compCollectionRefVars = compCollectionRefs.map((ref) => getUniqueRefConstName(ref));
|
|
14590
14740
|
const refVariables = [
|
|
14591
|
-
...
|
|
14592
|
-
...
|
|
14593
|
-
...
|
|
14594
|
-
...
|
|
14741
|
+
...elemRefVars,
|
|
14742
|
+
...elemCollectionRefVars,
|
|
14743
|
+
...compRefVars,
|
|
14744
|
+
...compCollectionRefVars
|
|
14595
14745
|
].join(", ");
|
|
14596
14746
|
const childRenderedRefManagers = [];
|
|
14597
14747
|
const childRefManagerMembers = [];
|
|
@@ -14606,11 +14756,38 @@ function renderReferenceManager(refs, target) {
|
|
|
14606
14756
|
}` : "";
|
|
14607
14757
|
const renderedRefManager = ` const [${name}, [${refVariables}]] =
|
|
14608
14758
|
${referenceManagerInit}(${options}[${elemRefsDeclarations}], [${elemCollectionRefsDeclarations}], [${compRefsDeclarations}], [${compCollectionRefsDeclarations}]${childRefManager});`;
|
|
14609
|
-
|
|
14759
|
+
const emitFreeRefManager = (ref, constName, regionIsCollection) => {
|
|
14760
|
+
const freeMgrName = `${constName}FreeRefManager`;
|
|
14761
|
+
const asCollection = (free) => regionIsCollection || free.repeated;
|
|
14762
|
+
const elementNames = ref.freeRefs.filter((free) => !asCollection(free)).map((free) => `'${free.name}'`).join(", ");
|
|
14763
|
+
const collectionNames = ref.freeRefs.filter((free) => asCollection(free)).map((free) => `'${free.name}'`).join(", ");
|
|
14764
|
+
const forCall = `${referenceManagerInit}(${options}[${elementNames}], [${collectionNames}], [], [])`;
|
|
14765
|
+
if (regionIsCollection) {
|
|
14766
|
+
usesComponentCollectionRefsImpl = true;
|
|
14767
|
+
return ` const [${freeMgrName}] = ${forCall};
|
|
14768
|
+
(${name}.get('${ref.ref}') as ComponentCollectionRefImpl<any, any>).setFreeRefManager(${freeMgrName});`;
|
|
14769
|
+
} else {
|
|
14770
|
+
usesComponentRefsImpl = true;
|
|
14771
|
+
return ` const [${freeMgrName}] = ${forCall};
|
|
14772
|
+
(${name}.get('${ref.ref}') as ComponentRefsImpl<any, any>).setFreeRefManager(${freeMgrName});`;
|
|
14773
|
+
}
|
|
14774
|
+
};
|
|
14775
|
+
const freeRefManagerLines = target === 0 ? [
|
|
14776
|
+
...compRefs.map((ref, i) => ({ ref, constName: compRefVars[i] })).filter(({ ref }) => ref.freeRefs && ref.freeRefs.length > 0).map(({ ref, constName }) => emitFreeRefManager(ref, constName, false)),
|
|
14777
|
+
...compCollectionRefs.map((ref, i) => ({ ref, constName: compCollectionRefVars[i] })).filter(({ ref }) => ref.freeRefs && ref.freeRefs.length > 0).map(({ ref, constName }) => emitFreeRefManager(ref, constName, true))
|
|
14778
|
+
] : [];
|
|
14779
|
+
return [...childRenderedRefManagers, renderedRefManager, ...freeRefManagerLines].join("\n");
|
|
14610
14780
|
};
|
|
14611
14781
|
if (hasRefs(refs, true)) {
|
|
14612
14782
|
const renderedRefsManager = renderRefManagerNode("refManager", refs);
|
|
14613
|
-
|
|
14783
|
+
let refsManagerImport = imports;
|
|
14784
|
+
if (usesComponentRefsImpl)
|
|
14785
|
+
refsManagerImport = refsManagerImport.plus(Imports.for(Import.ComponentRefsImpl));
|
|
14786
|
+
if (usesComponentCollectionRefsImpl)
|
|
14787
|
+
refsManagerImport = refsManagerImport.plus(
|
|
14788
|
+
Imports.for(Import.ComponentCollectionRefImpl)
|
|
14789
|
+
);
|
|
14790
|
+
return { renderedRefsManager, refsManagerImport };
|
|
14614
14791
|
} else {
|
|
14615
14792
|
const renderedRefsManager = `const [refManager, []] = ${referenceManagerInit}(${options}[], [], [], []);`;
|
|
14616
14793
|
return { renderedRefsManager, refsManagerImport: imports };
|
|
@@ -14618,16 +14795,27 @@ function renderReferenceManager(refs, target) {
|
|
|
14618
14795
|
}
|
|
14619
14796
|
function renderImports$1(imports, importsFor, componentImports, importerMode) {
|
|
14620
14797
|
const runtimeImport = imports.render(importsFor);
|
|
14621
|
-
|
|
14622
|
-
|
|
14623
|
-
|
|
14624
|
-
|
|
14625
|
-
|
|
14626
|
-
|
|
14627
|
-
|
|
14628
|
-
|
|
14629
|
-
)
|
|
14630
|
-
|
|
14798
|
+
const mergedByModule = /* @__PURE__ */ new Map();
|
|
14799
|
+
for (const importStatement of componentImports) {
|
|
14800
|
+
const key = `${importStatement.sandbox ? "sandbox:" : ""}${importStatement.module}`;
|
|
14801
|
+
let entry = mergedByModule.get(key);
|
|
14802
|
+
if (!entry) {
|
|
14803
|
+
entry = { link: { ...importStatement, names: [] }, symbols: /* @__PURE__ */ new Set() };
|
|
14804
|
+
mergedByModule.set(key, entry);
|
|
14805
|
+
}
|
|
14806
|
+
for (const symbol of importStatement.names) {
|
|
14807
|
+
const rendered = symbol.as ? `${symbol.name} as ${symbol.as}` : symbol.name;
|
|
14808
|
+
if (entry.symbols.has(rendered)) continue;
|
|
14809
|
+
entry.symbols.add(rendered);
|
|
14810
|
+
entry.link.names.push(symbol);
|
|
14811
|
+
}
|
|
14812
|
+
}
|
|
14813
|
+
let renderedComponentImports = [...mergedByModule.values()].map(({ link }) => {
|
|
14814
|
+
let symbols = link.names.map((symbol) => symbol.as ? `${symbol.name} as ${symbol.as}` : symbol.name).join(", ");
|
|
14815
|
+
return `import {${symbols}} from "${link.module}${getModeFileExtension(
|
|
14816
|
+
link.sandbox,
|
|
14817
|
+
importerMode
|
|
14818
|
+
)}";`;
|
|
14631
14819
|
});
|
|
14632
14820
|
return [runtimeImport, ...renderedComponentImports].join("\n");
|
|
14633
14821
|
}
|
|
@@ -14837,6 +15025,12 @@ const DIRECTIVE_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
14837
15025
|
"slow",
|
|
14838
15026
|
"jay-coordinate-base",
|
|
14839
15027
|
"jay-scope",
|
|
15028
|
+
// Component provenance marker stamped by the parser on `<jay:Name>` usage tags (DL#123 discovery).
|
|
15029
|
+
// Read by the coordinate/discovery pipeline, never a component prop or a rendered attribute.
|
|
15030
|
+
"jc",
|
|
15031
|
+
// DL#202 — template-side content-slot marker. A pure build-time authoring directive read by the
|
|
15032
|
+
// drift/sync differ; it rides into the flattened page copy (verbatim flatten) but must never render.
|
|
15033
|
+
"jay-content",
|
|
14840
15034
|
AsyncDirectiveTypes.loading.directive,
|
|
14841
15035
|
AsyncDirectiveTypes.resolved.directive,
|
|
14842
15036
|
AsyncDirectiveTypes.rejected.directive
|
|
@@ -18960,7 +19154,7 @@ function dedentYaml(text2) {
|
|
|
18960
19154
|
const minIndent = Math.min(...lines.map((l) => l.match(/^\s*/)?.[0].length ?? 0));
|
|
18961
19155
|
return lines.map((l) => l.slice(minIndent)).join("\n");
|
|
18962
19156
|
}
|
|
18963
|
-
async function parseHeadlessImports(elements, validations, filePath, importResolver, projectRoot) {
|
|
19157
|
+
async function parseHeadlessImports(elements, validations, filePath, importResolver, projectRoot, options) {
|
|
18964
19158
|
const result = [];
|
|
18965
19159
|
for await (const element of elements) {
|
|
18966
19160
|
const pluginAttr = element.getAttribute("plugin");
|
|
@@ -18972,10 +19166,16 @@ async function parseHeadlessImports(elements, validations, filePath, importResol
|
|
|
18972
19166
|
);
|
|
18973
19167
|
continue;
|
|
18974
19168
|
}
|
|
18975
|
-
|
|
18976
|
-
|
|
19169
|
+
const asAttr = element.getAttribute("as") ?? void 0;
|
|
19170
|
+
if (asAttr && !/^[a-z][a-z0-9-]*$/.test(asAttr)) {
|
|
19171
|
+
validations.push(
|
|
19172
|
+
`Headless component as="${asAttr}" is not a valid region tag name. Use kebab-case (e.g., as="feature-card").`
|
|
19173
|
+
);
|
|
18977
19174
|
continue;
|
|
18978
19175
|
}
|
|
19176
|
+
const srcAttr = element.getAttribute("src") ?? void 0;
|
|
19177
|
+
const templateAttr = element.getAttribute("template") ?? void 0;
|
|
19178
|
+
const suppressedValidations = (element.getAttribute("jay-validations") ?? "").split(/[\s,]+/).map((s) => s.trim().toUpperCase()).filter(Boolean);
|
|
18979
19179
|
if (!contractAttr) {
|
|
18980
19180
|
validations.push("headless import must specify contract attribute");
|
|
18981
19181
|
continue;
|
|
@@ -18997,41 +19197,75 @@ async function parseHeadlessImports(elements, validations, filePath, importResol
|
|
|
18997
19197
|
);
|
|
18998
19198
|
}
|
|
18999
19199
|
}
|
|
19000
|
-
|
|
19001
|
-
|
|
19002
|
-
|
|
19003
|
-
projectRoot
|
|
19004
|
-
);
|
|
19005
|
-
validations.push(...resolveResult.validations);
|
|
19006
|
-
if (!resolveResult.val) {
|
|
19007
|
-
continue;
|
|
19008
|
-
}
|
|
19009
|
-
const absoluteComponentPath = resolveResult.val.componentPath;
|
|
19010
|
-
const name = resolveResult.val.componentName;
|
|
19011
|
-
const isNpmPackage = resolveResult.val.isNpmPackage;
|
|
19012
|
-
const packageName = resolveResult.val.packageName;
|
|
19200
|
+
let loadedContract;
|
|
19201
|
+
let contractFile;
|
|
19202
|
+
let contractMetadata = void 0;
|
|
19013
19203
|
let module;
|
|
19014
|
-
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
module = path.relative(filePath, absoluteComponentPath);
|
|
19018
|
-
if (!module.startsWith(".")) {
|
|
19019
|
-
module = "./" + module;
|
|
19020
|
-
}
|
|
19021
|
-
}
|
|
19204
|
+
let name;
|
|
19205
|
+
let structural = false;
|
|
19206
|
+
let contractTagName = contractAttr;
|
|
19022
19207
|
try {
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19208
|
+
if (pluginAttr) {
|
|
19209
|
+
const resolveResult = importResolver.resolvePluginComponent(
|
|
19210
|
+
pluginAttr,
|
|
19211
|
+
contractAttr,
|
|
19212
|
+
projectRoot
|
|
19213
|
+
);
|
|
19214
|
+
validations.push(...resolveResult.validations);
|
|
19215
|
+
if (!resolveResult.val) {
|
|
19216
|
+
continue;
|
|
19217
|
+
}
|
|
19218
|
+
const absoluteComponentPath = resolveResult.val.componentPath;
|
|
19219
|
+
name = resolveResult.val.componentName;
|
|
19220
|
+
const isNpmPackage = resolveResult.val.isNpmPackage;
|
|
19221
|
+
const packageName = resolveResult.val.packageName;
|
|
19222
|
+
if (isNpmPackage && packageName) {
|
|
19223
|
+
module = packageName;
|
|
19224
|
+
} else {
|
|
19225
|
+
module = path.relative(filePath, absoluteComponentPath);
|
|
19226
|
+
if (!module.startsWith(".")) module = "./" + module;
|
|
19227
|
+
}
|
|
19228
|
+
const contractResult = importResolver.loadPluginContract(
|
|
19229
|
+
pluginAttr,
|
|
19230
|
+
contractAttr,
|
|
19231
|
+
projectRoot
|
|
19232
|
+
);
|
|
19233
|
+
validations.push(...contractResult.validations);
|
|
19234
|
+
if (!contractResult.val) {
|
|
19235
|
+
continue;
|
|
19236
|
+
}
|
|
19237
|
+
loadedContract = contractResult.val.contract;
|
|
19238
|
+
contractFile = contractResult.val.contractPath;
|
|
19239
|
+
contractMetadata = contractResult.val.metadata;
|
|
19240
|
+
} else {
|
|
19241
|
+
const contractPath = path.resolve(filePath, contractAttr);
|
|
19242
|
+
const contractResult = importResolver.loadContract(contractPath);
|
|
19243
|
+
validations.push(...contractResult.validations);
|
|
19244
|
+
if (!contractResult.val) {
|
|
19245
|
+
continue;
|
|
19246
|
+
}
|
|
19247
|
+
loadedContract = contractResult.val;
|
|
19248
|
+
contractFile = contractPath;
|
|
19249
|
+
if (srcAttr) {
|
|
19250
|
+
const importedFile = importResolver.resolveLink(filePath, srcAttr);
|
|
19251
|
+
const exportedComponents = importResolver.analyzeExportedTypes(importedFile, options).filter((t) => t instanceof JayComponentType);
|
|
19252
|
+
if (exportedComponents.length !== 1) {
|
|
19253
|
+
validations.push(
|
|
19254
|
+
`headless import src="${srcAttr}" must export exactly one Jay component (found ${exportedComponents.length})`
|
|
19255
|
+
);
|
|
19256
|
+
continue;
|
|
19257
|
+
}
|
|
19258
|
+
name = exportedComponents[0].name;
|
|
19259
|
+
module = path.relative(filePath, importedFile);
|
|
19260
|
+
if (!module.startsWith(".")) module = "./" + module;
|
|
19261
|
+
} else {
|
|
19262
|
+
structural = true;
|
|
19263
|
+
name = pascalCase(loadedContract.name);
|
|
19264
|
+
module = "";
|
|
19265
|
+
}
|
|
19266
|
+
contractTagName = paramCase(loadedContract.name);
|
|
19031
19267
|
}
|
|
19032
|
-
|
|
19033
|
-
const contractFile = contractResult.val.contractPath;
|
|
19034
|
-
const contractMetadata = contractResult.val.metadata;
|
|
19268
|
+
if (asAttr) contractTagName = asAttr;
|
|
19035
19269
|
const contractTypes = await contractToImportsViewStateAndRefs(
|
|
19036
19270
|
loadedContract,
|
|
19037
19271
|
contractFile,
|
|
@@ -19048,13 +19282,17 @@ async function parseHeadlessImports(elements, validations, filePath, importResol
|
|
|
19048
19282
|
refsTypeName,
|
|
19049
19283
|
repeatedRefsTypeName
|
|
19050
19284
|
);
|
|
19285
|
+
const toRelativeModule = (to) => {
|
|
19286
|
+
const relative = path.relative(filePath, to);
|
|
19287
|
+
return relative.startsWith(".") ? relative : "./" + relative;
|
|
19288
|
+
};
|
|
19051
19289
|
const enumsToImportRelativeToJayHtml = enumsToImport.map(
|
|
19052
19290
|
(enumsToImport2) => ({
|
|
19053
19291
|
type: enumsToImport2.type,
|
|
19054
|
-
declaringModule:
|
|
19292
|
+
declaringModule: toRelativeModule(enumsToImport2.declaringModule)
|
|
19055
19293
|
})
|
|
19056
19294
|
);
|
|
19057
|
-
const relativeContractPath =
|
|
19295
|
+
const relativeContractPath = toRelativeModule(contractFile);
|
|
19058
19296
|
const enumsFromContract = enumsToImportRelativeToJayHtml.filter((_) => _.declaringModule === relativeContractPath).map((_) => _.type);
|
|
19059
19297
|
const nestedTypeNames = collectNestedTypeNames(type2);
|
|
19060
19298
|
const nestedTypeImports = nestedTypeNames.filter((name2) => name2 !== type2.name).map((name2) => ({ name: name2, type: JayUnknown }));
|
|
@@ -19098,7 +19336,7 @@ async function parseHeadlessImports(elements, validations, filePath, importResol
|
|
|
19098
19336
|
};
|
|
19099
19337
|
result.push({
|
|
19100
19338
|
...key && { key },
|
|
19101
|
-
contractName:
|
|
19339
|
+
contractName: contractTagName,
|
|
19102
19340
|
refs,
|
|
19103
19341
|
rootType: type2,
|
|
19104
19342
|
contractLinks,
|
|
@@ -19106,355 +19344,28 @@ async function parseHeadlessImports(elements, validations, filePath, importResol
|
|
|
19106
19344
|
contract: loadedContract,
|
|
19107
19345
|
contractPath: contractFile,
|
|
19108
19346
|
metadata: contractMetadata,
|
|
19109
|
-
headlessProps
|
|
19347
|
+
headlessProps,
|
|
19348
|
+
...structural && { structural },
|
|
19349
|
+
...templateAttr && { template: templateAttr },
|
|
19350
|
+
...suppressedValidations.length && { suppressedValidations }
|
|
19110
19351
|
});
|
|
19111
19352
|
});
|
|
19112
19353
|
} catch (e2) {
|
|
19113
19354
|
validations.push(`failed to parse linked contract - ${e2.message}${e2.stack}`);
|
|
19114
19355
|
}
|
|
19115
19356
|
}
|
|
19116
|
-
|
|
19117
|
-
|
|
19118
|
-
|
|
19119
|
-
const root = parse_2(html2);
|
|
19120
|
-
const allHeadfullElements = root.querySelectorAll('script[type="application/jay-headfull"]');
|
|
19121
|
-
const fsElements = allHeadfullElements.filter((el) => el.getAttribute("contract"));
|
|
19122
|
-
if (fsElements.length === 0) return html2;
|
|
19123
|
-
const body = root.querySelector("body");
|
|
19124
|
-
if (!body) return html2;
|
|
19125
|
-
injectHeadfullFSTemplatesRecursive(fsElements, body, sourceDir, importResolver, /* @__PURE__ */ new Set());
|
|
19126
|
-
return root.toString();
|
|
19127
|
-
}
|
|
19128
|
-
function injectHeadfullFSTemplatesRecursive(fsElements, body, sourceDir, importResolver, visited) {
|
|
19129
|
-
for (const element of fsElements) {
|
|
19130
|
-
const src = element.getAttribute("src");
|
|
19131
|
-
const rawNames = element.getAttribute("names");
|
|
19132
|
-
if (!src || !rawNames) continue;
|
|
19133
|
-
const names = parseImportNames(rawNames);
|
|
19134
|
-
if (names.length === 0) continue;
|
|
19135
|
-
const contractName = (names[0].as || names[0].name).toLowerCase();
|
|
19136
|
-
const resolvedSrc = path.resolve(sourceDir, src);
|
|
19137
|
-
if (visited.has(resolvedSrc)) continue;
|
|
19138
|
-
visited.add(resolvedSrc);
|
|
19139
|
-
const jayHtmlResult = importResolver.readJayHtml(sourceDir, src);
|
|
19140
|
-
if (!jayHtmlResult) continue;
|
|
19141
|
-
const jayHtmlRoot = parse_2(jayHtmlResult.content);
|
|
19142
|
-
const jayHtmlBody = jayHtmlRoot.querySelector("body");
|
|
19143
|
-
if (!jayHtmlBody) continue;
|
|
19144
|
-
const nestedHeadfullElements = jayHtmlRoot.querySelectorAll('script[type="application/jay-headfull"]').filter((el) => el.getAttribute("contract"));
|
|
19145
|
-
if (nestedHeadfullElements.length > 0) {
|
|
19146
|
-
const childDir = jayHtmlResult.componentDir;
|
|
19147
|
-
injectHeadfullFSTemplatesRecursive(
|
|
19148
|
-
nestedHeadfullElements,
|
|
19149
|
-
jayHtmlBody,
|
|
19150
|
-
childDir,
|
|
19151
|
-
importResolver,
|
|
19152
|
-
visited
|
|
19153
|
-
);
|
|
19154
|
-
}
|
|
19155
|
-
const jayTags = body.querySelectorAll("*").filter((el) => el.tagName?.toLowerCase() === `jay:${contractName}`);
|
|
19156
|
-
for (const jayTag of jayTags) {
|
|
19157
|
-
if (!jayTag.innerHTML.trim()) {
|
|
19158
|
-
jayTag.set_content(jayHtmlBody.innerHTML);
|
|
19159
|
-
jayTag.setAttribute("style", "display: contents");
|
|
19160
|
-
jayTag.setAttribute("jc", contractName);
|
|
19161
|
-
}
|
|
19162
|
-
}
|
|
19357
|
+
const tagCounts = /* @__PURE__ */ new Map();
|
|
19358
|
+
for (const imp of result) {
|
|
19359
|
+
tagCounts.set(imp.contractName, (tagCounts.get(imp.contractName) ?? 0) + 1);
|
|
19163
19360
|
}
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
const headlessImports = [];
|
|
19167
|
-
const cssParts = [];
|
|
19168
|
-
const linkedCssFiles = [];
|
|
19169
|
-
const linkedComponentFiles = [];
|
|
19170
|
-
for (const element of elements) {
|
|
19171
|
-
const src = element.getAttribute("src");
|
|
19172
|
-
const contractAttr = element.getAttribute("contract");
|
|
19173
|
-
const rawNames = element.getAttribute("names");
|
|
19174
|
-
if (!src) {
|
|
19175
|
-
validations.push("headfull FS import must specify src attribute");
|
|
19176
|
-
continue;
|
|
19177
|
-
}
|
|
19178
|
-
if (!contractAttr) {
|
|
19179
|
-
continue;
|
|
19180
|
-
}
|
|
19181
|
-
if (!rawNames) {
|
|
19182
|
-
validations.push(`headfull FS import for module ${src} must specify names attribute`);
|
|
19183
|
-
continue;
|
|
19184
|
-
}
|
|
19185
|
-
const names = parseImportNames(rawNames);
|
|
19186
|
-
if (names.length === 0) {
|
|
19187
|
-
validations.push(
|
|
19188
|
-
`headfull FS import for module ${src} does not specify what to import`
|
|
19189
|
-
);
|
|
19190
|
-
continue;
|
|
19191
|
-
}
|
|
19192
|
-
const componentExportName = names[0].name;
|
|
19193
|
-
const contractName = (names[0].as || componentExportName).toLowerCase();
|
|
19194
|
-
const resolvedSrc = path.resolve(filePath, src);
|
|
19195
|
-
if (visited.has(resolvedSrc)) {
|
|
19196
|
-
validations.push(
|
|
19197
|
-
`Circular headfull FS import detected: ${src} has already been processed`
|
|
19198
|
-
);
|
|
19199
|
-
continue;
|
|
19200
|
-
}
|
|
19201
|
-
visited.add(resolvedSrc);
|
|
19202
|
-
const resolveDir = sourceDir || filePath;
|
|
19203
|
-
let jayHtmlResult = importResolver.readJayHtml(resolveDir, src);
|
|
19204
|
-
let moduleResolveDir = resolveDir;
|
|
19205
|
-
if (jayHtmlResult === null && resolveDir !== filePath) {
|
|
19206
|
-
jayHtmlResult = importResolver.readJayHtml(filePath, src);
|
|
19207
|
-
if (jayHtmlResult !== null) {
|
|
19208
|
-
moduleResolveDir = filePath;
|
|
19209
|
-
}
|
|
19210
|
-
}
|
|
19211
|
-
if (jayHtmlResult === null && projectRoot && projectRoot !== filePath && projectRoot !== resolveDir) {
|
|
19212
|
-
jayHtmlResult = importResolver.readJayHtml(projectRoot, src);
|
|
19213
|
-
if (jayHtmlResult !== null) {
|
|
19214
|
-
moduleResolveDir = projectRoot;
|
|
19215
|
-
}
|
|
19216
|
-
}
|
|
19217
|
-
if (jayHtmlResult === null) {
|
|
19218
|
-
validations.push(
|
|
19219
|
-
`jay-html file not found for headfull FS component ${src} (expected ${src}.jay-html)`
|
|
19220
|
-
);
|
|
19221
|
-
continue;
|
|
19222
|
-
}
|
|
19223
|
-
linkedComponentFiles.push(jayHtmlResult.filePath);
|
|
19224
|
-
let contractPath = path.resolve(resolveDir, contractAttr);
|
|
19225
|
-
let loadedContract;
|
|
19226
|
-
try {
|
|
19227
|
-
const contractResult = importResolver.loadContract(contractPath);
|
|
19228
|
-
validations.push(...contractResult.validations);
|
|
19229
|
-
if (!contractResult.val) {
|
|
19230
|
-
continue;
|
|
19231
|
-
}
|
|
19232
|
-
loadedContract = contractResult.val;
|
|
19233
|
-
} catch (e2) {
|
|
19234
|
-
let resolved = false;
|
|
19235
|
-
if (projectRoot && projectRoot !== filePath) {
|
|
19236
|
-
try {
|
|
19237
|
-
contractPath = path.resolve(projectRoot, contractAttr);
|
|
19238
|
-
const fallbackResult = importResolver.loadContract(contractPath);
|
|
19239
|
-
validations.push(...fallbackResult.validations);
|
|
19240
|
-
if (!fallbackResult.val) {
|
|
19241
|
-
continue;
|
|
19242
|
-
}
|
|
19243
|
-
loadedContract = fallbackResult.val;
|
|
19244
|
-
resolved = true;
|
|
19245
|
-
} catch {
|
|
19246
|
-
}
|
|
19247
|
-
}
|
|
19248
|
-
if (!resolved) {
|
|
19249
|
-
try {
|
|
19250
|
-
contractPath = path.resolve(
|
|
19251
|
-
jayHtmlResult.componentDir,
|
|
19252
|
-
path.basename(contractAttr)
|
|
19253
|
-
);
|
|
19254
|
-
const fallbackResult = importResolver.loadContract(contractPath);
|
|
19255
|
-
validations.push(...fallbackResult.validations);
|
|
19256
|
-
if (!fallbackResult.val) {
|
|
19257
|
-
continue;
|
|
19258
|
-
}
|
|
19259
|
-
loadedContract = fallbackResult.val;
|
|
19260
|
-
} catch (e3) {
|
|
19261
|
-
validations.push(
|
|
19262
|
-
`Failed to load contract for headfull FS component ${src}: ${e3.message}`
|
|
19263
|
-
);
|
|
19264
|
-
continue;
|
|
19265
|
-
}
|
|
19266
|
-
}
|
|
19267
|
-
}
|
|
19268
|
-
const jayHtmlRoot = parse_2(jayHtmlResult.content);
|
|
19269
|
-
const jayHtmlBody = jayHtmlRoot.querySelector("body");
|
|
19270
|
-
if (!jayHtmlBody) {
|
|
19271
|
-
validations.push(`headfull FS component ${src} jay-html must have a body tag`);
|
|
19272
|
-
continue;
|
|
19273
|
-
}
|
|
19274
|
-
const componentDir = jayHtmlResult.componentDir;
|
|
19275
|
-
const componentCssResult = await extractCss(jayHtmlRoot, componentDir, pageLinkedCssPaths);
|
|
19276
|
-
validations.push(...componentCssResult.validations);
|
|
19277
|
-
if (componentCssResult.val?.css) {
|
|
19278
|
-
cssParts.push(`/* Component: ${contractName} */
|
|
19279
|
-
${componentCssResult.val.css}`);
|
|
19280
|
-
}
|
|
19281
|
-
if (componentCssResult.val?.linkedCssFiles) {
|
|
19282
|
-
linkedCssFiles.push(...componentCssResult.val.linkedCssFiles);
|
|
19283
|
-
}
|
|
19284
|
-
const nestedHeadlessElements = jayHtmlRoot.querySelectorAll(
|
|
19285
|
-
'script[type="application/jay-headless"]'
|
|
19286
|
-
);
|
|
19287
|
-
if (nestedHeadlessElements.length > 0) {
|
|
19288
|
-
const nestedHeadless = await parseHeadlessImports(
|
|
19289
|
-
nestedHeadlessElements,
|
|
19290
|
-
validations,
|
|
19291
|
-
filePath,
|
|
19292
|
-
importResolver,
|
|
19293
|
-
projectRoot
|
|
19294
|
-
);
|
|
19295
|
-
headlessImports.push(...nestedHeadless);
|
|
19296
|
-
}
|
|
19297
|
-
const nestedHeadfullFSElements = jayHtmlRoot.querySelectorAll('script[type="application/jay-headfull"]').filter((el) => el.getAttribute("contract"));
|
|
19298
|
-
if (nestedHeadfullFSElements.length > 0) {
|
|
19299
|
-
for (const nestedEl of nestedHeadfullFSElements) {
|
|
19300
|
-
const nestedSrc = nestedEl.getAttribute("src");
|
|
19301
|
-
if (nestedSrc) {
|
|
19302
|
-
const absoluteSrc = path.resolve(componentDir, nestedSrc);
|
|
19303
|
-
let relativeSrc = path.relative(filePath, absoluteSrc);
|
|
19304
|
-
if (!relativeSrc.startsWith(".")) relativeSrc = "./" + relativeSrc;
|
|
19305
|
-
nestedEl.setAttribute("src", relativeSrc);
|
|
19306
|
-
}
|
|
19307
|
-
const nestedContract = nestedEl.getAttribute("contract");
|
|
19308
|
-
if (nestedContract) {
|
|
19309
|
-
const absoluteContract = path.resolve(componentDir, nestedContract);
|
|
19310
|
-
let relativeContract = path.relative(filePath, absoluteContract);
|
|
19311
|
-
if (!relativeContract.startsWith("."))
|
|
19312
|
-
relativeContract = "./" + relativeContract;
|
|
19313
|
-
nestedEl.setAttribute("contract", relativeContract);
|
|
19314
|
-
}
|
|
19315
|
-
}
|
|
19316
|
-
const nestedResult = await parseHeadfullFSImports(
|
|
19317
|
-
nestedHeadfullFSElements,
|
|
19318
|
-
validations,
|
|
19319
|
-
filePath,
|
|
19320
|
-
importResolver,
|
|
19321
|
-
jayHtmlBody,
|
|
19322
|
-
projectRoot,
|
|
19323
|
-
visited,
|
|
19324
|
-
void 0,
|
|
19325
|
-
pageLinkedCssPaths
|
|
19326
|
-
);
|
|
19327
|
-
headlessImports.push(...nestedResult.headlessImports);
|
|
19328
|
-
if (nestedResult.css) {
|
|
19329
|
-
cssParts.push(nestedResult.css);
|
|
19330
|
-
}
|
|
19331
|
-
linkedCssFiles.push(...nestedResult.linkedCssFiles);
|
|
19332
|
-
linkedComponentFiles.push(...nestedResult.linkedComponentFiles);
|
|
19333
|
-
}
|
|
19334
|
-
const jayTags = body.querySelectorAll("*").filter((el) => el.tagName?.toLowerCase() === `jay:${contractName}`);
|
|
19335
|
-
for (const jayTag of jayTags) {
|
|
19336
|
-
const existingContent = jayTag.innerHTML.trim();
|
|
19337
|
-
if (existingContent) {
|
|
19338
|
-
continue;
|
|
19339
|
-
}
|
|
19340
|
-
jayTag.set_content(jayHtmlBody.innerHTML);
|
|
19341
|
-
jayTag.setAttribute("jc", contractName);
|
|
19342
|
-
}
|
|
19343
|
-
let resolvedSrcPath;
|
|
19344
|
-
try {
|
|
19345
|
-
resolvedSrcPath = importResolver.resolveLink(moduleResolveDir, src);
|
|
19346
|
-
} catch {
|
|
19347
|
-
resolvedSrcPath = path.resolve(moduleResolveDir, src);
|
|
19348
|
-
}
|
|
19349
|
-
const hasCodeFile = fs.existsSync(resolvedSrcPath + ".ts") || fs.existsSync(resolvedSrcPath + ".js") || fs.existsSync(path.join(resolvedSrcPath, "index.ts")) || fs.existsSync(path.join(resolvedSrcPath, "index.js"));
|
|
19350
|
-
if (!hasCodeFile) {
|
|
19351
|
-
for (const jayTag of jayTags) {
|
|
19352
|
-
jayTag.replaceWith(jayTag.innerHTML);
|
|
19353
|
-
}
|
|
19354
|
-
continue;
|
|
19355
|
-
}
|
|
19356
|
-
try {
|
|
19357
|
-
const contractTypes = await contractToImportsViewStateAndRefs(
|
|
19358
|
-
loadedContract,
|
|
19359
|
-
contractPath,
|
|
19360
|
-
importResolver
|
|
19361
|
-
);
|
|
19362
|
-
contractTypes.map(({ type: type2, refs: subContractRefsTree, enumsToImport }) => {
|
|
19363
|
-
const contractInternalName = loadedContract.name;
|
|
19364
|
-
const refsTypeName = `${pascalCase(contractInternalName)}Refs`;
|
|
19365
|
-
const repeatedRefsTypeName = `${pascalCase(contractInternalName)}RepeatedRefs`;
|
|
19366
|
-
const refs = mkRefsTree(
|
|
19367
|
-
subContractRefsTree.refs,
|
|
19368
|
-
subContractRefsTree.children,
|
|
19369
|
-
subContractRefsTree.repeated,
|
|
19370
|
-
refsTypeName,
|
|
19371
|
-
repeatedRefsTypeName
|
|
19372
|
-
);
|
|
19373
|
-
const relativeContractPath = path.relative(filePath, contractPath);
|
|
19374
|
-
const enumsToImportRelativeToJayHtml = enumsToImport.map(
|
|
19375
|
-
(enumToImport) => ({
|
|
19376
|
-
type: enumToImport.type,
|
|
19377
|
-
declaringModule: path.relative(filePath, enumToImport.declaringModule)
|
|
19378
|
-
})
|
|
19379
|
-
);
|
|
19380
|
-
const enumsFromContract = enumsToImportRelativeToJayHtml.filter((_) => _.declaringModule === relativeContractPath).map((_) => _.type);
|
|
19381
|
-
const nestedTypeNames = collectNestedTypeNames(type2);
|
|
19382
|
-
const nestedTypeImports = nestedTypeNames.filter((name) => name !== type2.name).map((name) => ({ name, type: JayUnknown }));
|
|
19383
|
-
const contractLink = {
|
|
19384
|
-
module: relativeContractPath,
|
|
19385
|
-
names: [
|
|
19386
|
-
{ name: type2.name, type: type2 },
|
|
19387
|
-
{ name: refsTypeName, type: JayUnknown },
|
|
19388
|
-
...nestedTypeImports,
|
|
19389
|
-
...enumsFromContract.map((_) => ({ name: _.name, type: _ }))
|
|
19390
|
-
]
|
|
19391
|
-
};
|
|
19392
|
-
const enumsFromOtherContracts = deduplicateEnums(
|
|
19393
|
-
enumsToImportRelativeToJayHtml.filter(
|
|
19394
|
-
(_) => _.declaringModule !== relativeContractPath
|
|
19395
|
-
)
|
|
19396
|
-
);
|
|
19397
|
-
const enumImportLinks = Object.entries(
|
|
19398
|
-
enumsFromOtherContracts.reduce(
|
|
19399
|
-
(acc, enumToImport) => {
|
|
19400
|
-
const module = enumToImport.declaringModule;
|
|
19401
|
-
if (!acc[module]) {
|
|
19402
|
-
acc[module] = [];
|
|
19403
|
-
}
|
|
19404
|
-
acc[module].push(enumToImport);
|
|
19405
|
-
return acc;
|
|
19406
|
-
},
|
|
19407
|
-
{}
|
|
19408
|
-
)
|
|
19409
|
-
).map(([module, enums]) => ({
|
|
19410
|
-
module,
|
|
19411
|
-
names: enums.map((enumToImport) => ({
|
|
19412
|
-
name: enumToImport.type.name,
|
|
19413
|
-
type: enumToImport.type
|
|
19414
|
-
}))
|
|
19415
|
-
}));
|
|
19416
|
-
const contractLinks = [contractLink, ...enumImportLinks];
|
|
19417
|
-
let resolvedModulePath;
|
|
19418
|
-
try {
|
|
19419
|
-
resolvedModulePath = importResolver.resolveLink(moduleResolveDir, src);
|
|
19420
|
-
} catch {
|
|
19421
|
-
resolvedModulePath = path.resolve(moduleResolveDir, src);
|
|
19422
|
-
}
|
|
19423
|
-
let relativeModule = path.relative(filePath, resolvedModulePath);
|
|
19424
|
-
if (!relativeModule.startsWith(".")) {
|
|
19425
|
-
relativeModule = "./" + relativeModule;
|
|
19426
|
-
}
|
|
19427
|
-
const codeLink = {
|
|
19428
|
-
module: relativeModule,
|
|
19429
|
-
names: [
|
|
19430
|
-
{
|
|
19431
|
-
name: componentExportName,
|
|
19432
|
-
type: new JayComponentType(componentExportName, [])
|
|
19433
|
-
}
|
|
19434
|
-
]
|
|
19435
|
-
};
|
|
19436
|
-
headlessImports.push({
|
|
19437
|
-
contractName,
|
|
19438
|
-
refs,
|
|
19439
|
-
rootType: type2,
|
|
19440
|
-
contractLinks,
|
|
19441
|
-
codeLink,
|
|
19442
|
-
contract: loadedContract,
|
|
19443
|
-
contractPath
|
|
19444
|
-
});
|
|
19445
|
-
});
|
|
19446
|
-
} catch (e2) {
|
|
19361
|
+
for (const [tag, count] of tagCounts) {
|
|
19362
|
+
if (count > 1) {
|
|
19447
19363
|
validations.push(
|
|
19448
|
-
`
|
|
19364
|
+
`Two headless imports back the same <jay:${tag}> region tag. Add as="<alias>" to one of them to flatten them as distinct design variants (e.g. as="feature-${tag}" → <jay:feature-${tag}>).`
|
|
19449
19365
|
);
|
|
19450
19366
|
}
|
|
19451
19367
|
}
|
|
19452
|
-
return
|
|
19453
|
-
headlessImports,
|
|
19454
|
-
css: cssParts.length > 0 ? cssParts.join("\n\n") : void 0,
|
|
19455
|
-
linkedCssFiles,
|
|
19456
|
-
linkedComponentFiles
|
|
19457
|
-
};
|
|
19368
|
+
return result;
|
|
19458
19369
|
}
|
|
19459
19370
|
function normalizeFilename(filename) {
|
|
19460
19371
|
return filename.replace(".jay-html", "");
|
|
@@ -19588,7 +19499,7 @@ function resolveNestedCssImports(css, cssDir, visited) {
|
|
|
19588
19499
|
if (seen.has(resolved)) return `/* circular import: ${importPath} */`;
|
|
19589
19500
|
seen.add(resolved);
|
|
19590
19501
|
try {
|
|
19591
|
-
const imported = fs.readFileSync(resolved, "utf-8");
|
|
19502
|
+
const imported = fs$1.readFileSync(resolved, "utf-8");
|
|
19592
19503
|
return `/* @import ${importPath} */
|
|
19593
19504
|
${resolveNestedCssImports(imported, path.dirname(resolved), seen)}`;
|
|
19594
19505
|
} catch {
|
|
@@ -19610,9 +19521,8 @@ async function extractCss(root, filePath, skipPaths) {
|
|
|
19610
19521
|
if (filePath) {
|
|
19611
19522
|
const cssFilePath = path.resolve(filePath, href);
|
|
19612
19523
|
linkedCssFiles.push(cssFilePath);
|
|
19613
|
-
if (skipPaths?.has(cssFilePath)) continue;
|
|
19614
19524
|
try {
|
|
19615
|
-
const cssContent = await fs
|
|
19525
|
+
const cssContent = await fs.readFile(cssFilePath, "utf-8");
|
|
19616
19526
|
const resolvedCss = resolveNestedCssImports(
|
|
19617
19527
|
cssContent,
|
|
19618
19528
|
path.dirname(cssFilePath)
|
|
@@ -19707,10 +19617,16 @@ async function parseJayFile(html2, filename, filePath, options, linkedContractRe
|
|
|
19707
19617
|
const { val: jayYaml, validations } = parseYaml(root);
|
|
19708
19618
|
if (validations.length > 0) return new WithValidations(void 0, validations);
|
|
19709
19619
|
const allHeadfullElements = root.querySelectorAll('script[type="application/jay-headfull"]');
|
|
19620
|
+
for (const el of allHeadfullElements) {
|
|
19621
|
+
if (el.getAttribute("contract")) {
|
|
19622
|
+
validations.push(
|
|
19623
|
+
`application/jay-headfull with a contract attribute is no longer supported (DL#196). Declare the component with application/jay-headless and flatten it into a <jay:X> region (run \`jay-stack sync\`).`
|
|
19624
|
+
);
|
|
19625
|
+
}
|
|
19626
|
+
}
|
|
19710
19627
|
const regularHeadfullElements = allHeadfullElements.filter(
|
|
19711
19628
|
(el) => !el.getAttribute("contract")
|
|
19712
19629
|
);
|
|
19713
|
-
const fsHeadfullElements = allHeadfullElements.filter((el) => el.getAttribute("contract"));
|
|
19714
19630
|
const headfullImports = parseHeadfullImports(
|
|
19715
19631
|
regularHeadfullElements,
|
|
19716
19632
|
validations,
|
|
@@ -19723,33 +19639,15 @@ async function parseJayFile(html2, filename, filePath, options, linkedContractRe
|
|
|
19723
19639
|
validations.push(`jay file must have exactly a body tag`);
|
|
19724
19640
|
return new WithValidations(void 0, validations);
|
|
19725
19641
|
}
|
|
19726
|
-
const pageLinkedCssPaths = /* @__PURE__ */ new Set();
|
|
19727
|
-
for (const link of root.querySelectorAll('head link[rel="stylesheet"]')) {
|
|
19728
|
-
const href = link.getAttribute("href");
|
|
19729
|
-
if (href && !href.startsWith("http://") && !href.startsWith("https://") && !href.startsWith("//")) {
|
|
19730
|
-
pageLinkedCssPaths.add(path.resolve(filePath, href));
|
|
19731
|
-
}
|
|
19732
|
-
}
|
|
19733
|
-
const headfullFSResult = await parseHeadfullFSImports(
|
|
19734
|
-
fsHeadfullElements,
|
|
19735
|
-
validations,
|
|
19736
|
-
filePath,
|
|
19737
|
-
linkedContractResolver,
|
|
19738
|
-
body,
|
|
19739
|
-
projectRoot,
|
|
19740
|
-
void 0,
|
|
19741
|
-
// visited
|
|
19742
|
-
sourceDir,
|
|
19743
|
-
pageLinkedCssPaths
|
|
19744
|
-
);
|
|
19745
19642
|
const headlessImports = await parseHeadlessImports(
|
|
19746
19643
|
root.querySelectorAll('script[type="application/jay-headless"]'),
|
|
19747
19644
|
validations,
|
|
19748
19645
|
filePath,
|
|
19749
19646
|
linkedContractResolver,
|
|
19750
|
-
projectRoot
|
|
19647
|
+
projectRoot,
|
|
19648
|
+
options
|
|
19751
19649
|
);
|
|
19752
|
-
const allHeadlessImports = [...headlessImports
|
|
19650
|
+
const allHeadlessImports = [...headlessImports];
|
|
19753
19651
|
resolveEnumCollisions(allHeadlessImports);
|
|
19754
19652
|
const importNames = headfullImports.flatMap((_) => _.names);
|
|
19755
19653
|
const types2 = await parseTypes(
|
|
@@ -19780,17 +19678,11 @@ async function parseJayFile(html2, filename, filePath, options, linkedContractRe
|
|
|
19780
19678
|
validations.push(...cssResult.validations);
|
|
19781
19679
|
if (validations.length > 0) return new WithValidations(void 0, validations);
|
|
19782
19680
|
let css = cssResult.val?.css;
|
|
19783
|
-
if (headfullFSResult.css) {
|
|
19784
|
-
css = css ? css + "\n\n" + headfullFSResult.css : headfullFSResult.css;
|
|
19785
|
-
}
|
|
19786
19681
|
if (css) {
|
|
19787
19682
|
detectCssNameCollisions(css, validations);
|
|
19788
19683
|
}
|
|
19789
|
-
|
|
19790
|
-
|
|
19791
|
-
allLinkedCssFiles = [...allLinkedCssFiles, ...headfullFSResult.linkedCssFiles];
|
|
19792
|
-
}
|
|
19793
|
-
const allLinkedComponentFiles = headfullFSResult.linkedComponentFiles;
|
|
19684
|
+
const allLinkedCssFiles = cssResult.val?.linkedCssFiles || [];
|
|
19685
|
+
const allLinkedComponentFiles = [];
|
|
19794
19686
|
const { serverTrackByMap, clientTrackByMap } = extractTrackByMaps(
|
|
19795
19687
|
jayYaml.parsedContract,
|
|
19796
19688
|
allHeadlessImports
|
|
@@ -20117,7 +20009,15 @@ function generateRefsInterface(contract, refs) {
|
|
|
20117
20009
|
${repeatedRefsRendered}`;
|
|
20118
20010
|
return { imports: imports.plus(imports2), renderedRefs };
|
|
20119
20011
|
}
|
|
20120
|
-
function
|
|
20012
|
+
function collectViewStateEnumNames(type2, acc = /* @__PURE__ */ new Set()) {
|
|
20013
|
+
if (isEnumType(type2)) acc.add(type2.name);
|
|
20014
|
+
else if (isObjectType$1(type2))
|
|
20015
|
+
for (const key of Object.keys(type2.props)) collectViewStateEnumNames(type2.props[key], acc);
|
|
20016
|
+
else if (isArrayType$1(type2) || isPromiseType(type2))
|
|
20017
|
+
collectViewStateEnumNames(type2.itemType, acc);
|
|
20018
|
+
return acc;
|
|
20019
|
+
}
|
|
20020
|
+
function generatePropsInterface(contractName, props, existingEnumNames = /* @__PURE__ */ new Set()) {
|
|
20121
20021
|
const propsTypeName = `${contractName}Props`;
|
|
20122
20022
|
const enums = [];
|
|
20123
20023
|
if (props.length === 0) {
|
|
@@ -20129,10 +20029,13 @@ function generatePropsInterface(contractName, props) {
|
|
|
20129
20029
|
let typeName;
|
|
20130
20030
|
if (isEnumType(prop.dataType)) {
|
|
20131
20031
|
typeName = prop.dataType.name;
|
|
20132
|
-
|
|
20032
|
+
if (!existingEnumNames.has(prop.dataType.name)) {
|
|
20033
|
+
const genEnum = `export enum ${prop.dataType.name} {
|
|
20133
20034
|
${prop.dataType.values.map((_) => " " + _).join(",\n")}
|
|
20134
20035
|
}`;
|
|
20135
|
-
|
|
20036
|
+
enums.push(genEnum);
|
|
20037
|
+
existingEnumNames.add(prop.dataType.name);
|
|
20038
|
+
}
|
|
20136
20039
|
} else if (isAtomicType(prop.dataType)) {
|
|
20137
20040
|
typeName = prop.dataType.name;
|
|
20138
20041
|
} else {
|
|
@@ -20198,9 +20101,11 @@ async function compileContract(contractWithValidations, contractFilePath, jayImp
|
|
|
20198
20101
|
const propsTypeName = `${contractName}Props`;
|
|
20199
20102
|
let renderedProps = "";
|
|
20200
20103
|
if (hasProps) {
|
|
20104
|
+
const existingEnumNames = collectViewStateEnumNames(type2);
|
|
20201
20105
|
const { propsInterface, propsEnums } = generatePropsInterface(
|
|
20202
20106
|
contractName,
|
|
20203
|
-
contract.props
|
|
20107
|
+
contract.props,
|
|
20108
|
+
existingEnumNames
|
|
20204
20109
|
);
|
|
20205
20110
|
renderedProps = propsEnums ? `${propsEnums}
|
|
20206
20111
|
|
|
@@ -20876,10 +20781,13 @@ ${indent.firstLine} }`;
|
|
|
20876
20781
|
allImports = allImports.plus(Import.adoptElement);
|
|
20877
20782
|
}
|
|
20878
20783
|
const itemRootCoordForEach = element.getAttribute(COORD_ATTR) || "0";
|
|
20784
|
+
const bodyParentDepth = Math.max(itemContent.parentDepth, createChildren.parentDepth);
|
|
20785
|
+
const dependsOnParent = bodyParentDepth > 0;
|
|
20879
20786
|
const hydrateForEachFragment = new RenderFragment(
|
|
20880
20787
|
`${indent.firstLine}hydrateForEach(${forEachFragment.rendered}, '${trackBy}', '${itemRootCoordForEach}',
|
|
20881
20788
|
${indent.firstLine} ${adoptBody},
|
|
20882
|
-
${indent.firstLine} ${createBody}
|
|
20789
|
+
${indent.firstLine} ${createBody},${dependsOnParent ? `
|
|
20790
|
+
${indent.firstLine} true,` : ""}
|
|
20883
20791
|
${indent.firstLine})`,
|
|
20884
20792
|
allImports,
|
|
20885
20793
|
[
|
|
@@ -20887,7 +20795,9 @@ ${indent.firstLine})`,
|
|
|
20887
20795
|
...itemContent.validations,
|
|
20888
20796
|
...createChildren.validations
|
|
20889
20797
|
],
|
|
20890
|
-
mergeRefsTrees(itemContent.refs, itemRefFragment.refs)
|
|
20798
|
+
mergeRefsTrees(itemContent.refs, itemRefFragment.refs),
|
|
20799
|
+
[],
|
|
20800
|
+
Math.max(forEachFragment.parentDepth, Math.max(0, bodyParentDepth - 1))
|
|
20891
20801
|
);
|
|
20892
20802
|
return nestRefs(forEachAccessor.terms, hydrateForEachFragment);
|
|
20893
20803
|
}
|
|
@@ -20937,7 +20847,7 @@ function renderHydrateHeadlessInstance(element, context, renderContext, contract
|
|
|
20937
20847
|
} else {
|
|
20938
20848
|
coordinateKey2 = instanceCoord;
|
|
20939
20849
|
}
|
|
20940
|
-
const componentVariables = new Variables(headlessImport.rootType);
|
|
20850
|
+
const componentVariables = new Variables(headlessImport.rootType, renderContext.variables);
|
|
20941
20851
|
const childNodes = filterContentNodes(element.childNodes);
|
|
20942
20852
|
if (childNodes.length === 0) {
|
|
20943
20853
|
return new RenderFragment("", Imports.none(), [
|
|
@@ -20987,14 +20897,50 @@ ${adoptChildren.rendered}
|
|
|
20987
20897
|
${adoptChildIndent.firstLine}])`,
|
|
20988
20898
|
adoptChildren.imports.plus(Import.adoptElement),
|
|
20989
20899
|
adoptChildren.validations,
|
|
20990
|
-
adoptChildren.refs
|
|
20900
|
+
adoptChildren.refs,
|
|
20901
|
+
adoptChildren.recursiveRegions,
|
|
20902
|
+
// DL#193 Capability A: preserve the deepest `$parent` climb so the usage site
|
|
20903
|
+
// still weakens gates when instance content spans multiple root children.
|
|
20904
|
+
adoptChildren.parentDepth
|
|
20991
20905
|
);
|
|
20992
20906
|
}
|
|
20993
|
-
const
|
|
20907
|
+
const contractRefNames = /* @__PURE__ */ new Set();
|
|
20908
|
+
const collectContractRefNames = (tree) => {
|
|
20909
|
+
for (const r of tree.refs) contractRefNames.add(camelCase$1(r.ref));
|
|
20910
|
+
for (const child of Object.values(tree.children)) collectContractRefNames(child);
|
|
20911
|
+
};
|
|
20912
|
+
collectContractRefNames(headlessImport.refs);
|
|
20913
|
+
const freeRefDecls = [];
|
|
20914
|
+
const seenFreeRefNames = /* @__PURE__ */ new Set();
|
|
20915
|
+
const collectFreeRefs = (tree) => {
|
|
20916
|
+
for (const r of tree.refs) {
|
|
20917
|
+
if (isComponentType$1(r.elementType)) continue;
|
|
20918
|
+
if (contractRefNames.has(camelCase$1(r.ref))) continue;
|
|
20919
|
+
if (seenFreeRefNames.has(r.ref)) continue;
|
|
20920
|
+
seenFreeRefNames.add(r.ref);
|
|
20921
|
+
freeRefDecls.push({
|
|
20922
|
+
name: r.ref,
|
|
20923
|
+
repeated: r.repeated,
|
|
20924
|
+
viewStateType: r.viewStateType.name,
|
|
20925
|
+
elementType: r.elementType.name
|
|
20926
|
+
});
|
|
20927
|
+
}
|
|
20928
|
+
for (const child of Object.values(tree.children)) collectFreeRefs(child);
|
|
20929
|
+
};
|
|
20930
|
+
collectFreeRefs(adoptInlineBody.refs);
|
|
20931
|
+
const freeRefNames = freeRefDecls.map((f) => f.name);
|
|
20932
|
+
const freeRefsArg = freeRefNames.length > 0 ? `
|
|
20933
|
+
[${freeRefNames.map((r) => `'${r}'`).join(", ")}],` : "";
|
|
20934
|
+
const adoptMergedRefs = hoistFreeRefs(
|
|
20935
|
+
mergeContractStubRefs(adoptInlineBody.refs, headlessImport.refs),
|
|
20936
|
+
new Set(freeRefNames)
|
|
20937
|
+
);
|
|
20994
20938
|
const { renderedRefsManager, refsManagerImport } = renderReferenceManager(
|
|
20995
20939
|
adoptMergedRefs,
|
|
20996
20940
|
ReferenceManagerTarget.element
|
|
20997
20941
|
);
|
|
20942
|
+
const refOriginalName = element.attributes.ref || context.refNameGenerator.newAutoRefNameGenerator();
|
|
20943
|
+
const refRefName = camelCase$1(refOriginalName);
|
|
20998
20944
|
const adoptRenderFnCode = `
|
|
20999
20945
|
// Hydrate inline template for headless component: ${contractName} #${idx}
|
|
21000
20946
|
type ${elementType} = JayElement<${interactiveViewStateType}, ${refsTypeName}>;
|
|
@@ -21011,22 +20957,31 @@ ${adoptInlineBody.rendered}
|
|
|
21011
20957
|
}`;
|
|
21012
20958
|
let adoptComponentSymbol;
|
|
21013
20959
|
let adoptComponentDef;
|
|
21014
|
-
|
|
20960
|
+
const coordinateArg = isInsideForEach ? `(dataIds) => [...dataIds, '${coordinateSuffix}'].toString()` : `'${coordinateKey2}'`;
|
|
20961
|
+
if (headlessImport.structural) {
|
|
20962
|
+
adoptComponentSymbol = `_Headless${pascal}${idx}`;
|
|
20963
|
+
adoptComponentDef = `const ${adoptComponentSymbol} = makePassthroughHeadlessInstanceComponent(
|
|
20964
|
+
${renderFnName},
|
|
20965
|
+
${coordinateArg},${freeRefsArg}
|
|
20966
|
+
);`;
|
|
20967
|
+
} else if (isInsideForEach) {
|
|
21015
20968
|
adoptComponentSymbol = `_Headless${pascal}${idx}Adopt`;
|
|
21016
20969
|
adoptComponentDef = `const ${adoptComponentSymbol} = makeHeadlessInstanceComponent(
|
|
21017
20970
|
${renderFnName},
|
|
21018
20971
|
${pluginComponentName},
|
|
21019
|
-
(dataIds) => [...dataIds, '${coordinateSuffix}'].toString()
|
|
20972
|
+
(dataIds) => [...dataIds, '${coordinateSuffix}'].toString(),${freeRefsArg}
|
|
21020
20973
|
);`;
|
|
21021
20974
|
} else {
|
|
21022
20975
|
adoptComponentSymbol = `_Headless${pascal}${idx}`;
|
|
21023
20976
|
adoptComponentDef = `const ${adoptComponentSymbol} = makeHeadlessInstanceComponent(
|
|
21024
20977
|
${renderFnName},
|
|
21025
20978
|
${pluginComponentName},
|
|
21026
|
-
'${coordinateKey2}'
|
|
20979
|
+
'${coordinateKey2}',${freeRefsArg}
|
|
21027
20980
|
);`;
|
|
21028
20981
|
}
|
|
21029
|
-
let adoptImports = adoptInlineBody.imports.plus(refsManagerImport).plus(Import.ConstructContext).plus(
|
|
20982
|
+
let adoptImports = adoptInlineBody.imports.plus(refsManagerImport).plus(Import.ConstructContext).plus(
|
|
20983
|
+
headlessImport.structural ? Import.makePassthroughHeadlessInstanceComponent : Import.makeHeadlessInstanceComponent
|
|
20984
|
+
);
|
|
21030
20985
|
const ifCondition = element.attributes.if;
|
|
21031
20986
|
const needsCreateVersion = !!ifCondition;
|
|
21032
20987
|
let createComponentSymbol;
|
|
@@ -21067,7 +21022,10 @@ ${createRenderedChildren.rendered}
|
|
|
21067
21022
|
} else {
|
|
21068
21023
|
createInlineBody = createRenderedChildren;
|
|
21069
21024
|
}
|
|
21070
|
-
const createMergedRefs =
|
|
21025
|
+
const createMergedRefs = hoistFreeRefs(
|
|
21026
|
+
mergeContractStubRefs(createInlineBody.refs, headlessImport.refs),
|
|
21027
|
+
new Set(freeRefNames)
|
|
21028
|
+
);
|
|
21071
21029
|
const { renderedRefsManager: createRefsManager, refsManagerImport: createRefsImport } = renderReferenceManager(createMergedRefs, ReferenceManagerTarget.element);
|
|
21072
21030
|
createRenderFnCode = `
|
|
21073
21031
|
function ${createRenderFnName}(options?: RenderElementOptions): ${preRenderType} {
|
|
@@ -21079,10 +21037,10 @@ ${createInlineBody.rendered}
|
|
|
21079
21037
|
return [refManager.getPublicAPI() as ${refsTypeName}, render];
|
|
21080
21038
|
}
|
|
21081
21039
|
|
|
21082
|
-
const ${createComponentSymbol} = makeHeadlessInstanceComponent(
|
|
21083
|
-
${createRenderFnName}
|
|
21084
|
-
${pluginComponentName}
|
|
21085
|
-
${isInsideForEach ? `(dataIds) => [...dataIds, '${coordinateSuffix}'].toString()` : `'${coordinateKey2}'`}
|
|
21040
|
+
const ${createComponentSymbol} = ${headlessImport.structural ? "makePassthroughHeadlessInstanceComponent" : "makeHeadlessInstanceComponent"}(
|
|
21041
|
+
${createRenderFnName},${headlessImport.structural ? "" : `
|
|
21042
|
+
${pluginComponentName},`}
|
|
21043
|
+
${isInsideForEach ? `(dataIds) => [...dataIds, '${coordinateSuffix}'].toString()` : `'${coordinateKey2}'`},${freeRefsArg}
|
|
21086
21044
|
);`;
|
|
21087
21045
|
createImports = createInlineBody.imports.plus(createRefsImport);
|
|
21088
21046
|
}
|
|
@@ -21090,7 +21048,7 @@ const ${createComponentSymbol} = makeHeadlessInstanceComponent(
|
|
|
21090
21048
|
componentSymbol: adoptComponentSymbol,
|
|
21091
21049
|
renderFnName,
|
|
21092
21050
|
renderFnCode: adoptRenderFnCode + "\n" + adoptComponentDef + (createRenderFnCode ? "\n" + createRenderFnCode : ""),
|
|
21093
|
-
pluginComponentName,
|
|
21051
|
+
pluginComponentName: headlessImport.structural ? void 0 : pluginComponentName,
|
|
21094
21052
|
imports: adoptImports.plus(createImports)
|
|
21095
21053
|
});
|
|
21096
21054
|
const propsGetterAndRefs = renderChildCompProps$1(
|
|
@@ -21099,8 +21057,6 @@ const ${createComponentSymbol} = makeHeadlessInstanceComponent(
|
|
|
21099
21057
|
headlessImport.contract?.props
|
|
21100
21058
|
);
|
|
21101
21059
|
const getProps = `(${context.variables.currentVar}: ${context.variables.currentType.name}) => ${propsGetterAndRefs.rendered}`;
|
|
21102
|
-
const refOriginalName = element.attributes.ref || context.refNameGenerator.newAutoRefNameGenerator();
|
|
21103
|
-
const refRefName = camelCase$1(refOriginalName);
|
|
21104
21060
|
const refConstName = context.refNameGenerator.newConstantName(refRefName, context.variables);
|
|
21105
21061
|
const isRepeated = context.dynamicRef;
|
|
21106
21062
|
const contractRefType = isRepeated ? `${pascal}RepeatedRefs` : `${pascal}Refs`;
|
|
@@ -21109,6 +21065,22 @@ const ${createComponentSymbol} = makeHeadlessInstanceComponent(
|
|
|
21109
21065
|
link.names.push({ name: contractRefType, type: JayUnknown });
|
|
21110
21066
|
}
|
|
21111
21067
|
}
|
|
21068
|
+
const augmented = freeRefsAugmentedRefType(contractRefType, freeRefDecls, isRepeated);
|
|
21069
|
+
if (freeRefDecls.length > 0) {
|
|
21070
|
+
for (const f of freeRefDecls) {
|
|
21071
|
+
if (!f.viewStateType) continue;
|
|
21072
|
+
for (const link of headlessImport.contractLinks) {
|
|
21073
|
+
if (!link.names.some((n) => n.name === f.viewStateType)) {
|
|
21074
|
+
link.names.push({ name: f.viewStateType, type: JayUnknown });
|
|
21075
|
+
}
|
|
21076
|
+
}
|
|
21077
|
+
}
|
|
21078
|
+
}
|
|
21079
|
+
let freeRefProxyImports = Imports.for();
|
|
21080
|
+
if (augmented.needsElementProxy)
|
|
21081
|
+
freeRefProxyImports = freeRefProxyImports.plus(Import.HTMLElementProxy);
|
|
21082
|
+
if (augmented.needsCollectionProxy)
|
|
21083
|
+
freeRefProxyImports = freeRefProxyImports.plus(Import.HTMLElementCollectionProxy);
|
|
21112
21084
|
const instanceRef = mkRef(
|
|
21113
21085
|
refRefName,
|
|
21114
21086
|
refOriginalName,
|
|
@@ -21116,25 +21088,25 @@ const ${createComponentSymbol} = makeHeadlessInstanceComponent(
|
|
|
21116
21088
|
isRepeated,
|
|
21117
21089
|
!element.attributes.ref,
|
|
21118
21090
|
context.variables.currentType,
|
|
21119
|
-
new JayTypeAlias(
|
|
21120
|
-
|
|
21121
|
-
|
|
21122
|
-
|
|
21123
|
-
Imports.for(),
|
|
21124
|
-
[],
|
|
21125
|
-
mkRefsTree([instanceRef], {})
|
|
21091
|
+
new JayTypeAlias(augmented.type),
|
|
21092
|
+
// DL#198 — declare free refs on the page-side region ref so the page-level renderReferenceManager
|
|
21093
|
+
// emits the per-region FreeReferenceManager (`${refConstName}FreeRefManager`) + setFreeRefManager.
|
|
21094
|
+
freeRefDecls.length > 0 ? freeRefDecls : void 0
|
|
21126
21095
|
);
|
|
21096
|
+
const instanceRefsTree = mkRefsTree([instanceRef], {});
|
|
21097
|
+
let renderedRef = new RenderFragment(`${refConstName}()`, Imports.for(), [], instanceRefsTree);
|
|
21127
21098
|
if (renderedRef.rendered !== "") renderedRef = renderedRef.map((_) => ", " + _);
|
|
21099
|
+
const freeRefManagerArg = freeRefNames.length > 0 ? `, ${refConstName}FreeRefManager` : "";
|
|
21128
21100
|
const scopeRootCoord = childScopeId ? `'${childScopeId}/0'` : "undefined";
|
|
21129
21101
|
if (ifCondition) {
|
|
21130
21102
|
const renderedCondition = parseCondition(ifCondition, context.variables);
|
|
21131
|
-
const adoptCall = `() => childCompHydrate(${adoptComponentSymbol}, ${getProps}, ${scopeRootCoord}${renderedRef.rendered})`;
|
|
21132
|
-
const createCall = `() => childComp(${createComponentSymbol}, ${getProps}${renderedRef.rendered})`;
|
|
21103
|
+
const adoptCall = `() => childCompHydrate(${adoptComponentSymbol}, ${getProps}, ${scopeRootCoord}${renderedRef.rendered}${freeRefManagerArg})`;
|
|
21104
|
+
const createCall = `() => childComp(${createComponentSymbol}, ${getProps}${renderedRef.rendered}${freeRefManagerArg})`;
|
|
21133
21105
|
const callExpr = `${context.indent.firstLine}hydrateConditional(${renderedCondition.rendered}, ${adoptCall},
|
|
21134
21106
|
${context.indent.firstLine} ${createCall})`;
|
|
21135
21107
|
return new RenderFragment(
|
|
21136
21108
|
callExpr,
|
|
21137
|
-
Imports.for(Import.childCompHydrate, Import.hydrateConditional, Import.childComp).plus(propsGetterAndRefs.imports).plus(renderedRef.imports).plus(renderedCondition.imports),
|
|
21109
|
+
Imports.for(Import.childCompHydrate, Import.hydrateConditional, Import.childComp).plus(propsGetterAndRefs.imports).plus(renderedRef.imports).plus(renderedCondition.imports).plus(freeRefProxyImports),
|
|
21138
21110
|
[
|
|
21139
21111
|
...propsGetterAndRefs.validations,
|
|
21140
21112
|
...adoptInlineBody.validations,
|
|
@@ -21144,8 +21116,8 @@ ${context.indent.firstLine} ${createCall})`;
|
|
|
21144
21116
|
);
|
|
21145
21117
|
}
|
|
21146
21118
|
return new RenderFragment(
|
|
21147
|
-
`${context.indent.firstLine}childCompHydrate(${adoptComponentSymbol}, ${getProps}, ${scopeRootCoord}${renderedRef.rendered})`,
|
|
21148
|
-
Imports.for(Import.childCompHydrate).plus(propsGetterAndRefs.imports).plus(renderedRef.imports),
|
|
21119
|
+
`${context.indent.firstLine}childCompHydrate(${adoptComponentSymbol}, ${getProps}, ${scopeRootCoord}${renderedRef.rendered}${freeRefManagerArg})`,
|
|
21120
|
+
Imports.for(Import.childCompHydrate).plus(propsGetterAndRefs.imports).plus(renderedRef.imports).plus(freeRefProxyImports),
|
|
21149
21121
|
[
|
|
21150
21122
|
...propsGetterAndRefs.validations,
|
|
21151
21123
|
...adoptInlineBody.validations,
|
|
@@ -21221,6 +21193,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21221
21193
|
let childImports = Imports.none();
|
|
21222
21194
|
const childValidations = [];
|
|
21223
21195
|
const childRefs = [];
|
|
21196
|
+
let childParentDepth = 0;
|
|
21224
21197
|
for (const child of childNodes) {
|
|
21225
21198
|
if (child.nodeType !== NodeType.ELEMENT_NODE) continue;
|
|
21226
21199
|
const htmlChild = child;
|
|
@@ -21234,6 +21207,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21234
21207
|
childImports = childImports.plus(frag.imports);
|
|
21235
21208
|
childValidations.push(...frag.validations);
|
|
21236
21209
|
if (frag.refs) childRefs.push(frag.refs);
|
|
21210
|
+
childParentDepth = Math.max(childParentDepth, frag.parentDepth);
|
|
21237
21211
|
}
|
|
21238
21212
|
} else {
|
|
21239
21213
|
const htmlChild2 = child;
|
|
@@ -21256,6 +21230,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21256
21230
|
childImports = childImports.plus(frag.imports);
|
|
21257
21231
|
childValidations.push(...frag.validations);
|
|
21258
21232
|
if (frag.refs) childRefs.push(frag.refs);
|
|
21233
|
+
childParentDepth = Math.max(childParentDepth, frag.parentDepth);
|
|
21259
21234
|
} else {
|
|
21260
21235
|
childParts.push(`${indent.firstLine}STATIC`);
|
|
21261
21236
|
childImports = childImports.plus(Import.STATIC);
|
|
@@ -21263,12 +21238,16 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21263
21238
|
}
|
|
21264
21239
|
}
|
|
21265
21240
|
const refSuffix2 = renderedRef.rendered ? `, ${renderedRef.rendered}` : "";
|
|
21266
|
-
const childrenArr2 = childParts.length ? `[
|
|
21241
|
+
const childrenArr2 = childParts.length ? `[
|
|
21242
|
+
${childParts.join(",\n")}
|
|
21243
|
+
${indent.firstLine}]` : "[]";
|
|
21267
21244
|
return new RenderFragment(
|
|
21268
21245
|
`${indent.firstLine}adoptDynamicElement("${coordinate}", ${attributes2.rendered}, ${childrenArr2}${refSuffix2})`,
|
|
21269
21246
|
Imports.for(Import.adoptDynamicElement).plus(attributes2.imports).plus(childImports).plus(renderedRef.imports),
|
|
21270
21247
|
[...attributes2.validations, ...childValidations, ...renderedRef.validations],
|
|
21271
|
-
mergeRefsTrees(...childRefs, renderedRef.refs)
|
|
21248
|
+
mergeRefsTrees(...childRefs, renderedRef.refs),
|
|
21249
|
+
[],
|
|
21250
|
+
Math.max(childParentDepth, attributes2.parentDepth)
|
|
21272
21251
|
);
|
|
21273
21252
|
}
|
|
21274
21253
|
if (hasMixedContentDynamicText2 && !hasDynamicAttrs) {
|
|
@@ -21276,6 +21255,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21276
21255
|
let childImports = Imports.none();
|
|
21277
21256
|
const childValidations = [];
|
|
21278
21257
|
const childRefs = [];
|
|
21258
|
+
let childParentDepth = 0;
|
|
21279
21259
|
childNodes.forEach((child) => {
|
|
21280
21260
|
if (child.nodeType === NodeType.ELEMENT_NODE) {
|
|
21281
21261
|
const frag = renderHydrateNode(child, context);
|
|
@@ -21284,6 +21264,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21284
21264
|
childImports = childImports.plus(frag.imports);
|
|
21285
21265
|
childValidations.push(...frag.validations);
|
|
21286
21266
|
if (frag.refs) childRefs.push(frag.refs);
|
|
21267
|
+
childParentDepth = Math.max(childParentDepth, frag.parentDepth);
|
|
21287
21268
|
}
|
|
21288
21269
|
}
|
|
21289
21270
|
});
|
|
@@ -21299,6 +21280,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21299
21280
|
);
|
|
21300
21281
|
childImports = childImports.plus(Import.adoptText).plus(rendered.imports.minus(Import.dynamicText));
|
|
21301
21282
|
childValidations.push(...rendered.validations);
|
|
21283
|
+
childParentDepth = Math.max(childParentDepth, rendered.parentDepth);
|
|
21302
21284
|
}
|
|
21303
21285
|
}
|
|
21304
21286
|
}
|
|
@@ -21309,7 +21291,9 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21309
21291
|
`${indent.firstLine}adoptElement("${coordinate}", ${attributes2.rendered}, ${childrenArr2}${refSuffix2})`,
|
|
21310
21292
|
Imports.for(Import.adoptElement).plus(attributes2.imports).plus(childImports).plus(renderedRef.imports),
|
|
21311
21293
|
[...attributes2.validations, ...childValidations, ...renderedRef.validations],
|
|
21312
|
-
mergeRefsTrees(...childRefs, renderedRef.refs)
|
|
21294
|
+
mergeRefsTrees(...childRefs, renderedRef.refs),
|
|
21295
|
+
[],
|
|
21296
|
+
childParentDepth
|
|
21313
21297
|
);
|
|
21314
21298
|
}
|
|
21315
21299
|
if (isHtmlStringChild && textFragment && !hasDynamicAttrs) {
|
|
@@ -21319,7 +21303,9 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21319
21303
|
`${indent.firstLine}adoptElement("${coordinate}", ${attributes2.rendered}, [dh(${accessor})]${refSuffix2})`,
|
|
21320
21304
|
Imports.for(Import.adoptElement).plus(Import.dynamicHtml).plus(textFragment.imports.minus(Import.dynamicText)).plus(renderedRef.imports).plus(attributes2.imports),
|
|
21321
21305
|
[...textFragment.validations, ...renderedRef.validations, ...attributes2.validations],
|
|
21322
|
-
renderedRef.refs
|
|
21306
|
+
renderedRef.refs,
|
|
21307
|
+
[],
|
|
21308
|
+
textFragment.parentDepth
|
|
21323
21309
|
);
|
|
21324
21310
|
}
|
|
21325
21311
|
if (textFragment && !hasDynamicAttrs) {
|
|
@@ -21334,13 +21320,19 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21334
21320
|
...renderedRef.validations,
|
|
21335
21321
|
...attributes2.validations
|
|
21336
21322
|
],
|
|
21337
|
-
renderedRef.refs
|
|
21323
|
+
renderedRef.refs,
|
|
21324
|
+
[],
|
|
21325
|
+
// DL#193 Capability A: carry the `$parent` climb up so enclosing forEach gates weaken.
|
|
21326
|
+
textFragment.parentDepth
|
|
21338
21327
|
);
|
|
21339
21328
|
}
|
|
21340
21329
|
return new RenderFragment(
|
|
21341
21330
|
`${indent.firstLine}adoptText("${coordinate}", ${accessor})`,
|
|
21342
21331
|
Imports.for(Import.adoptText).plus(textFragment.imports.minus(Import.dynamicText)),
|
|
21343
|
-
[...textFragment.validations]
|
|
21332
|
+
[...textFragment.validations],
|
|
21333
|
+
mkRefsTree([], {}),
|
|
21334
|
+
[],
|
|
21335
|
+
textFragment.parentDepth
|
|
21344
21336
|
);
|
|
21345
21337
|
}
|
|
21346
21338
|
if (hasDynamicAttrs) {
|
|
@@ -21348,6 +21340,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21348
21340
|
let childImports = Imports.none();
|
|
21349
21341
|
let childValidations = [];
|
|
21350
21342
|
let childRefs;
|
|
21343
|
+
let childParentDepth = 0;
|
|
21351
21344
|
if (textFragment) {
|
|
21352
21345
|
const accessor = textFragment.rendered.replace(/^dt\(/, "").replace(/\)$/, "");
|
|
21353
21346
|
childrenRendered = `[adoptText("${coordinate}", ${accessor})]`;
|
|
@@ -21355,6 +21348,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21355
21348
|
textFragment.imports.minus(Import.dynamicText)
|
|
21356
21349
|
);
|
|
21357
21350
|
childValidations = textFragment.validations;
|
|
21351
|
+
childParentDepth = textFragment.parentDepth;
|
|
21358
21352
|
} else {
|
|
21359
21353
|
const children = mergeHydrateFragments(
|
|
21360
21354
|
childNodes.map((child) => renderHydrateNode(child, context)),
|
|
@@ -21365,6 +21359,7 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21365
21359
|
childImports = children.imports;
|
|
21366
21360
|
childValidations = children.validations;
|
|
21367
21361
|
childRefs = children.refs;
|
|
21362
|
+
childParentDepth = children.parentDepth;
|
|
21368
21363
|
}
|
|
21369
21364
|
}
|
|
21370
21365
|
const refSuffix2 = renderedRef.rendered ? `, ${renderedRef.rendered}` : "";
|
|
@@ -21372,7 +21367,11 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21372
21367
|
`${indent.firstLine}adoptElement("${coordinate}", ${attributes2.rendered}, ${childrenRendered}${refSuffix2})`,
|
|
21373
21368
|
Imports.for(Import.adoptElement).plus(attributes2.imports).plus(childImports).plus(renderedRef.imports),
|
|
21374
21369
|
[...attributes2.validations, ...childValidations, ...renderedRef.validations],
|
|
21375
|
-
mergeRefsTrees(...[childRefs, renderedRef.refs].filter(Boolean))
|
|
21370
|
+
mergeRefsTrees(...[childRefs, renderedRef.refs].filter(Boolean)),
|
|
21371
|
+
[],
|
|
21372
|
+
// DL#193 Phase 2a: carry the override binding's `$parent` climb up (attributes may
|
|
21373
|
+
// themselves be `$parent`-bound; a wrapping element adds no scope).
|
|
21374
|
+
Math.max(childParentDepth, attributes2.parentDepth)
|
|
21376
21375
|
);
|
|
21377
21376
|
}
|
|
21378
21377
|
const childFragments = mergeHydrateFragments(
|
|
@@ -21385,7 +21384,11 @@ function renderHydrateElementContent(element, context, renderContext, coordinate
|
|
|
21385
21384
|
`${indent.firstLine}adoptElement("${coordinate}", {}, ${childrenArr}${refSuffix})`,
|
|
21386
21385
|
Imports.for(Import.adoptElement).plus(childFragments.imports).plus(renderedRef.imports),
|
|
21387
21386
|
[...childFragments.validations, ...renderedRef.validations],
|
|
21388
|
-
mergeRefsTrees(childFragments.refs, renderedRef.refs)
|
|
21387
|
+
mergeRefsTrees(childFragments.refs, renderedRef.refs),
|
|
21388
|
+
[],
|
|
21389
|
+
// DL#193 Capability A: a wrapping element adds no scope, so carry children's `$parent`
|
|
21390
|
+
// climb up unchanged so enclosing forEach gates weaken.
|
|
21391
|
+
childFragments.parentDepth
|
|
21389
21392
|
);
|
|
21390
21393
|
}
|
|
21391
21394
|
function renderHydrate(types2, body, importStatements, elementType, preRenderType, refsType, headlessImports, contract) {
|
|
@@ -21411,7 +21414,9 @@ function renderHydrate(types2, body, importStatements, elementType, preRenderTyp
|
|
|
21411
21414
|
};
|
|
21412
21415
|
const rootElement = ensureSingleChildElement(body);
|
|
21413
21416
|
if (!rootElement.val) {
|
|
21414
|
-
return
|
|
21417
|
+
return {
|
|
21418
|
+
fragment: new RenderFragment("", Imports.none(), rootElement.validations)
|
|
21419
|
+
};
|
|
21415
21420
|
}
|
|
21416
21421
|
const rootComponentMatch = getComponentName(
|
|
21417
21422
|
rootElement.val.rawTagName,
|
|
@@ -21437,8 +21442,8 @@ function renderHydrate(types2, body, importStatements, elementType, preRenderTyp
|
|
|
21437
21442
|
ReferenceManagerTarget.element
|
|
21438
21443
|
);
|
|
21439
21444
|
const hasAdoptCalls = renderedHydrate.rendered.trim().length > 0;
|
|
21440
|
-
const hydrateBody = hasAdoptCalls ? `() =>
|
|
21441
|
-
${renderedHydrate.rendered}
|
|
21445
|
+
const hydrateBody = !hasAdoptCalls ? `() => ({ dom: rootElement, update: () => {}, mount: () => {}, unmount: () => {} })` : `() =>
|
|
21446
|
+
${renderedHydrate.rendered}`;
|
|
21442
21447
|
const headlessDefsCode = context.headlessInstanceDefs.map((def) => def.renderFnCode).join("\n");
|
|
21443
21448
|
let headlessImportsAll = Imports.none();
|
|
21444
21449
|
for (const def of context.headlessInstanceDefs) {
|
|
@@ -21453,12 +21458,14 @@ ${renderedRefsManager}
|
|
|
21453
21458
|
const fullOutput = headlessDefsCode ? `${headlessDefsCode}
|
|
21454
21459
|
|
|
21455
21460
|
${hydrateFunction}` : hydrateFunction;
|
|
21456
|
-
return
|
|
21457
|
-
|
|
21458
|
-
|
|
21459
|
-
|
|
21460
|
-
|
|
21461
|
-
|
|
21461
|
+
return {
|
|
21462
|
+
fragment: new RenderFragment(
|
|
21463
|
+
fullOutput,
|
|
21464
|
+
Imports.for(Import.ConstructContext, Import.RenderElementOptions).plus(renderedHydrate.imports).plus(refsManagerImport).plus(headlessImportsAll),
|
|
21465
|
+
renderedHydrate.validations,
|
|
21466
|
+
renderedHydrate.refs
|
|
21467
|
+
)
|
|
21468
|
+
};
|
|
21462
21469
|
}
|
|
21463
21470
|
function renderFunctionDeclaration(preRenderType) {
|
|
21464
21471
|
return `export declare function render(options?: RenderElementOptions): ${preRenderType}`;
|
|
@@ -21549,7 +21556,7 @@ function renderDynamicAttributes(element, { variables }) {
|
|
|
21549
21556
|
if (isDirectiveAttribute(attrCanonical)) return;
|
|
21550
21557
|
if (attrCanonical === "style") {
|
|
21551
21558
|
const styleFragment = renderStyleAttribute(attributes2[attrName], variables);
|
|
21552
|
-
if (styleFragment.imports.has(Import.dynamicAttribute)) {
|
|
21559
|
+
if (styleFragment.imports.has(Import.dynamicAttribute) || styleFragment.imports.has(Import.dynamicProperty)) {
|
|
21553
21560
|
renderedAttributes.push(styleFragment);
|
|
21554
21561
|
}
|
|
21555
21562
|
} else if (attrCanonical === "class") {
|
|
@@ -21640,6 +21647,21 @@ function renderElementRef$1(element, { dynamicRef, variables, importedRefNameToR
|
|
|
21640
21647
|
return new RenderFragment(`${constName}()`, Imports.none(), [], refs);
|
|
21641
21648
|
} else return RenderFragment.empty();
|
|
21642
21649
|
}
|
|
21650
|
+
function coerceStaticComponentProp(value, expectedType) {
|
|
21651
|
+
if (!expectedType) return void 0;
|
|
21652
|
+
if (isEnumType(expectedType)) {
|
|
21653
|
+
return expectedType.values.includes(value) ? `${expectedType.alias ?? expectedType.name}.${value}` : void 0;
|
|
21654
|
+
}
|
|
21655
|
+
if (expectedType.name === "number") {
|
|
21656
|
+
return /^-?\d+(\.\d+)?$/.test(value) ? value : void 0;
|
|
21657
|
+
}
|
|
21658
|
+
if (expectedType.name === "boolean") {
|
|
21659
|
+
if (value === "true") return "true";
|
|
21660
|
+
if (value === "false") return "false";
|
|
21661
|
+
return void 0;
|
|
21662
|
+
}
|
|
21663
|
+
return void 0;
|
|
21664
|
+
}
|
|
21643
21665
|
function renderChildCompProps$1(element, { variables }, contractProps) {
|
|
21644
21666
|
let attributes2 = element.attributes;
|
|
21645
21667
|
let props = [];
|
|
@@ -21657,10 +21679,15 @@ function renderChildCompProps$1(element, { variables }, contractProps) {
|
|
|
21657
21679
|
if (attrCanonical === "ref") {
|
|
21658
21680
|
return;
|
|
21659
21681
|
} else {
|
|
21660
|
-
|
|
21682
|
+
const rawValue = attributes2[attrName];
|
|
21683
|
+
const isStatic = !rawValue.includes("{");
|
|
21684
|
+
let prop = parseComponentPropExpression(rawValue, variables);
|
|
21661
21685
|
const outputKey = contractProps?.find((p) => p.name.toLowerCase() === attrCanonical)?.name ?? attrKey;
|
|
21662
21686
|
const expectedType = propTypeMap?.get(attrName) ?? propTypeMap?.get(outputKey);
|
|
21663
|
-
|
|
21687
|
+
const coerced = isStatic ? coerceStaticComponentProp(rawValue.trim(), expectedType) : void 0;
|
|
21688
|
+
if (coerced !== void 0) {
|
|
21689
|
+
prop = prop.map(() => coerced);
|
|
21690
|
+
} else if (expectedType && expectedType.name === "string" && /^\d+$/.test(prop.rendered)) {
|
|
21664
21691
|
prop = prop.map((_) => `'${_}'`);
|
|
21665
21692
|
}
|
|
21666
21693
|
props.push(prop.map((_) => `${outputKey}: ${_}`));
|
|
@@ -21733,7 +21760,9 @@ function renderNode(node2, context) {
|
|
|
21733
21760
|
children.imports.plus(Import.dynamicElement).plus(attributes2.imports).plus(ref.imports).plus(tagFunc.import),
|
|
21734
21761
|
[...attributes2.validations, ...children.validations, ...ref.validations],
|
|
21735
21762
|
mergeRefsTrees(attributes2.refs, children.refs, ref.refs),
|
|
21736
|
-
[...attributes2.recursiveRegions, ...children.recursiveRegions, ...ref.recursiveRegions]
|
|
21763
|
+
[...attributes2.recursiveRegions, ...children.recursiveRegions, ...ref.recursiveRegions],
|
|
21764
|
+
// DL#193: carry the deepest `$parent` climb up so scope-switch rules can force it.
|
|
21765
|
+
Math.max(attributes2.parentDepth, children.parentDepth, ref.parentDepth)
|
|
21737
21766
|
);
|
|
21738
21767
|
}
|
|
21739
21768
|
function e2(tagName, attributes2, children, ref, currIndent = indent) {
|
|
@@ -21744,7 +21773,9 @@ function renderNode(node2, context) {
|
|
|
21744
21773
|
children.imports.plus(Import.element).plus(attributes2.imports).plus(ref.imports).plus(tagFunc.import),
|
|
21745
21774
|
[...attributes2.validations, ...children.validations, ...ref.validations],
|
|
21746
21775
|
mergeRefsTrees(attributes2.refs, children.refs, ref.refs),
|
|
21747
|
-
[...attributes2.recursiveRegions, ...children.recursiveRegions, ...ref.recursiveRegions]
|
|
21776
|
+
[...attributes2.recursiveRegions, ...children.recursiveRegions, ...ref.recursiveRegions],
|
|
21777
|
+
// DL#193: carry the deepest `$parent` climb up so scope-switch rules can force it.
|
|
21778
|
+
Math.max(attributes2.parentDepth, children.parentDepth, ref.parentDepth)
|
|
21748
21779
|
);
|
|
21749
21780
|
}
|
|
21750
21781
|
function renderHtmlElement(htmlElement, newContext) {
|
|
@@ -21857,7 +21888,8 @@ ${contextForChildren.indent.firstLine}` : children
|
|
|
21857
21888
|
result.imports.plus(Import.baseJayElement),
|
|
21858
21889
|
result.validations,
|
|
21859
21890
|
result.refs,
|
|
21860
|
-
[...result.recursiveRegions, recursiveRegion]
|
|
21891
|
+
[...result.recursiveRegions, recursiveRegion],
|
|
21892
|
+
result.parentDepth
|
|
21861
21893
|
);
|
|
21862
21894
|
}
|
|
21863
21895
|
return result;
|
|
@@ -21870,17 +21902,26 @@ ${indent.firstLine})`,
|
|
|
21870
21902
|
Imports.merge(childElement.imports, renderedCondition.imports).plus(Import.conditional),
|
|
21871
21903
|
[...renderedCondition.validations, ...childElement.validations],
|
|
21872
21904
|
mergeRefsTrees(renderedCondition.refs, childElement.refs),
|
|
21873
|
-
[...renderedCondition.recursiveRegions, ...childElement.recursiveRegions]
|
|
21905
|
+
[...renderedCondition.recursiveRegions, ...childElement.recursiveRegions],
|
|
21906
|
+
// DL#193: `if` is not a data-scope switch — it re-runs its body on every parent
|
|
21907
|
+
// update at runtime, so the residual `$parent` depth passes through unchanged.
|
|
21908
|
+
Math.max(renderedCondition.parentDepth, childElement.parentDepth)
|
|
21874
21909
|
);
|
|
21875
21910
|
}
|
|
21876
21911
|
function renderForEach(renderedForEach, collectionVariables, trackBy, childElement) {
|
|
21912
|
+
const dependsOnParent = childElement.parentDepth > 0;
|
|
21913
|
+
const residualParentDepth = Math.max(
|
|
21914
|
+
renderedForEach.parentDepth,
|
|
21915
|
+
Math.max(0, childElement.parentDepth - 1)
|
|
21916
|
+
);
|
|
21877
21917
|
return new RenderFragment(
|
|
21878
21918
|
`${indent.firstLine}forEach(${renderedForEach.rendered}, (${collectionVariables.currentVar}: ${collectionVariables.currentType.name}) => {
|
|
21879
|
-
${indent.curr}return ${childElement.rendered}}, '${trackBy}')`,
|
|
21919
|
+
${indent.curr}return ${childElement.rendered}}, '${trackBy}'${dependsOnParent ? ", true" : ""})`,
|
|
21880
21920
|
childElement.imports.plus(Import.forEach),
|
|
21881
21921
|
[...renderedForEach.validations, ...childElement.validations],
|
|
21882
21922
|
childElement.refs,
|
|
21883
|
-
[...renderedForEach.recursiveRegions, ...childElement.recursiveRegions]
|
|
21923
|
+
[...renderedForEach.recursiveRegions, ...childElement.recursiveRegions],
|
|
21924
|
+
residualParentDepth
|
|
21884
21925
|
);
|
|
21885
21926
|
}
|
|
21886
21927
|
function renderAsync(asyncType, getPromiseFragment, childElement, resolvedGenericTypes) {
|
|
@@ -21889,7 +21930,10 @@ ${indent.curr}return ${childElement.rendered}}, '${trackBy}')`,
|
|
|
21889
21930
|
childElement.imports.plus(asyncType.import),
|
|
21890
21931
|
[...getPromiseFragment.validations, ...childElement.validations],
|
|
21891
21932
|
childElement.refs,
|
|
21892
|
-
[...getPromiseFragment.recursiveRegions, ...childElement.recursiveRegions]
|
|
21933
|
+
[...getPromiseFragment.recursiveRegions, ...childElement.recursiveRegions],
|
|
21934
|
+
// DL#193: `when`/async is a data-scope switch; it re-runs its body on every parent
|
|
21935
|
+
// update at runtime (no flag needed), and the residual `$parent` depth drops by one.
|
|
21936
|
+
Math.max(getPromiseFragment.parentDepth, Math.max(0, childElement.parentDepth - 1))
|
|
21893
21937
|
);
|
|
21894
21938
|
}
|
|
21895
21939
|
function renderNestedComponent(htmlElement, newContext, componentName) {
|
|
@@ -21932,7 +21976,7 @@ ${indent.curr}return ${childElement.rendered}}, '${trackBy}')`,
|
|
|
21932
21976
|
link.names.push({ name: interactiveViewStateType, type: JayUnknown });
|
|
21933
21977
|
}
|
|
21934
21978
|
}
|
|
21935
|
-
const componentVariables = new Variables(headlessImport.rootType);
|
|
21979
|
+
const componentVariables = new Variables(headlessImport.rootType, newContext.variables);
|
|
21936
21980
|
const childIndent = newContext.indent.child(false);
|
|
21937
21981
|
const childNodes = filterContentNodes(htmlElement.childNodes);
|
|
21938
21982
|
let inlineBody;
|
|
@@ -21958,6 +22002,18 @@ ${indent.curr}return ${childElement.rendered}}, '${trackBy}')`,
|
|
|
21958
22002
|
recursiveRegions: [],
|
|
21959
22003
|
isInsideGuard: false,
|
|
21960
22004
|
insideFastForEach: false,
|
|
22005
|
+
// Each inline template compiles into its OWN `_headless…Render` function, so its ref
|
|
22006
|
+
// const names (`refCardAction`) are function-local. Give it a fresh generator so two
|
|
22007
|
+
// instances of the same contract don't dedup across the boundary (`refCardAction` in
|
|
22008
|
+
// both, not `refCardAction` / `refCardAction2`).
|
|
22009
|
+
refNameGenerator: new RefNameGenerator(),
|
|
22010
|
+
// DL#193 Phase 3: an instance's OWN template refs are always single — the instance is
|
|
22011
|
+
// one unit. When the instance is repeated at the usage site (inside a forEach), that
|
|
22012
|
+
// collection-ness is captured by the page-level ref manager collecting the instances,
|
|
22013
|
+
// not by the instance's inner refs. Reset `dynamicRef` so forwarded inner refs (e.g.
|
|
22014
|
+
// `<jay:Counter ref="cta">`) stay single here; contract-declared refs already use the
|
|
22015
|
+
// stub's `repeated` flag via importedRefNameToRef, so they are unaffected.
|
|
22016
|
+
dynamicRef: false,
|
|
21961
22017
|
// Pass headless contract names through so nested headless instances
|
|
21962
22018
|
// inside headfull FS component templates can be detected (DL#123)
|
|
21963
22019
|
headlessContractNames: newContext.headlessContractNames
|
|
@@ -21974,13 +22030,46 @@ ${renderedChildren.rendered}
|
|
|
21974
22030
|
renderedChildren.imports.plus(Import.dynamicElement),
|
|
21975
22031
|
renderedChildren.validations,
|
|
21976
22032
|
renderedChildren.refs,
|
|
21977
|
-
renderedChildren.recursiveRegions
|
|
22033
|
+
renderedChildren.recursiveRegions,
|
|
22034
|
+
// DL#193 Capability A: preserve the deepest `$parent` climb so the usage site
|
|
22035
|
+
// still weakens gates when instance content spans multiple root children.
|
|
22036
|
+
renderedChildren.parentDepth
|
|
21978
22037
|
);
|
|
21979
22038
|
} else {
|
|
21980
22039
|
inlineBody = renderedChildren;
|
|
21981
22040
|
}
|
|
21982
22041
|
}
|
|
21983
|
-
const
|
|
22042
|
+
const refOriginalName = htmlElement.attributes.ref || newContext.refNameGenerator.newAutoRefNameGenerator();
|
|
22043
|
+
const refRefName = camelCase$1(refOriginalName);
|
|
22044
|
+
const contractRefNames = /* @__PURE__ */ new Set();
|
|
22045
|
+
const collectContractRefNames = (tree) => {
|
|
22046
|
+
for (const r of tree.refs) contractRefNames.add(camelCase$1(r.ref));
|
|
22047
|
+
for (const child of Object.values(tree.children)) collectContractRefNames(child);
|
|
22048
|
+
};
|
|
22049
|
+
collectContractRefNames(headlessImport.refs);
|
|
22050
|
+
const freeRefDecls = [];
|
|
22051
|
+
const seenFreeRefNames = /* @__PURE__ */ new Set();
|
|
22052
|
+
const collectFreeRefs = (tree) => {
|
|
22053
|
+
for (const r of tree.refs) {
|
|
22054
|
+
if (isComponentType$1(r.elementType)) continue;
|
|
22055
|
+
if (contractRefNames.has(camelCase$1(r.ref))) continue;
|
|
22056
|
+
if (seenFreeRefNames.has(r.ref)) continue;
|
|
22057
|
+
seenFreeRefNames.add(r.ref);
|
|
22058
|
+
freeRefDecls.push({
|
|
22059
|
+
name: r.ref,
|
|
22060
|
+
repeated: r.repeated,
|
|
22061
|
+
viewStateType: r.viewStateType.name,
|
|
22062
|
+
elementType: r.elementType.name
|
|
22063
|
+
});
|
|
22064
|
+
}
|
|
22065
|
+
for (const child of Object.values(tree.children)) collectFreeRefs(child);
|
|
22066
|
+
};
|
|
22067
|
+
collectFreeRefs(inlineBody.refs);
|
|
22068
|
+
const freeRefNames = freeRefDecls.map((f) => f.name);
|
|
22069
|
+
const mergedRefs = hoistFreeRefs(
|
|
22070
|
+
mergeContractStubRefs(inlineBody.refs, headlessImport.refs),
|
|
22071
|
+
new Set(freeRefNames)
|
|
22072
|
+
);
|
|
21984
22073
|
const { renderedRefsManager, refsManagerImport } = renderReferenceManager(
|
|
21985
22074
|
mergedRefs,
|
|
21986
22075
|
ReferenceManagerTarget.element
|
|
@@ -21999,6 +22088,17 @@ ${renderedChildren.rendered}
|
|
|
21999
22088
|
const coordinateSuffix = `${contractName}:${coordinateRef}`;
|
|
22000
22089
|
const instanceCoordBase = htmlElement.getAttribute("jay-coordinate-base");
|
|
22001
22090
|
const coordinateKey2 = isInsideForEach ? void 0 : instanceCoordBase || coordinateSuffix;
|
|
22091
|
+
const coordinateArg = isInsideForEach ? `(dataIds) => [...dataIds, '${coordinateSuffix}'].toString()` : `'${coordinateKey2}'`;
|
|
22092
|
+
const freeRefsArg = freeRefNames.length > 0 ? `
|
|
22093
|
+
[${freeRefNames.map((r) => `'${r}'`).join(", ")}],` : "";
|
|
22094
|
+
const componentDefCode = headlessImport.structural ? `const ${componentSymbol} = makePassthroughHeadlessInstanceComponent(
|
|
22095
|
+
${renderFnName},
|
|
22096
|
+
${coordinateArg},${freeRefsArg}
|
|
22097
|
+
);` : `const ${componentSymbol} = makeHeadlessInstanceComponent(
|
|
22098
|
+
${renderFnName},
|
|
22099
|
+
${pluginComponentName},
|
|
22100
|
+
${coordinateArg},${freeRefsArg}
|
|
22101
|
+
);`;
|
|
22002
22102
|
const renderFnCode = `
|
|
22003
22103
|
// Inline template for headless component: ${contractName} #${idx}
|
|
22004
22104
|
type ${elementType} = JayElement<${interactiveViewStateType}, ${refsTypeName}>;
|
|
@@ -22014,11 +22114,7 @@ ${inlineBody.rendered}
|
|
|
22014
22114
|
return [refManager.getPublicAPI() as ${refsTypeName}, render];
|
|
22015
22115
|
}
|
|
22016
22116
|
|
|
22017
|
-
|
|
22018
|
-
${renderFnName},
|
|
22019
|
-
${headlessImport.structural ? `{ comp: (_props, _refs) => ({ render: () => _props }) }` : pluginComponentName},
|
|
22020
|
-
${isInsideForEach ? `(dataIds) => [...dataIds, '${coordinateSuffix}'].toString()` : `'${coordinateKey2}'`},
|
|
22021
|
-
);`;
|
|
22117
|
+
${componentDefCode}`;
|
|
22022
22118
|
newContext.headlessInstanceDefs.push({
|
|
22023
22119
|
componentSymbol,
|
|
22024
22120
|
renderFnName,
|
|
@@ -22031,9 +22127,8 @@ const ${componentSymbol} = makeHeadlessInstanceComponent(
|
|
|
22031
22127
|
newContext,
|
|
22032
22128
|
headlessImport.contract?.props
|
|
22033
22129
|
);
|
|
22034
|
-
|
|
22035
|
-
|
|
22036
|
-
const refRefName = camelCase$1(refOriginalName);
|
|
22130
|
+
const outerVar = newContext.variables.currentVar;
|
|
22131
|
+
let getProps = `(${outerVar}: ${newContext.variables.currentType.name}) => ${propsGetterAndRefs.rendered}`;
|
|
22037
22132
|
const refConstName = newContext.refNameGenerator.newConstantName(
|
|
22038
22133
|
refRefName,
|
|
22039
22134
|
newContext.variables
|
|
@@ -22046,6 +22141,18 @@ const ${componentSymbol} = makeHeadlessInstanceComponent(
|
|
|
22046
22141
|
}
|
|
22047
22142
|
}
|
|
22048
22143
|
newContext.usedComponentImports.add(contractRefType);
|
|
22144
|
+
const augmented = freeRefsAugmentedRefType(contractRefType, freeRefDecls, isRepeated);
|
|
22145
|
+
if (freeRefDecls.length > 0) {
|
|
22146
|
+
for (const f of freeRefDecls) {
|
|
22147
|
+
if (!f.viewStateType) continue;
|
|
22148
|
+
for (const link of headlessImport.contractLinks) {
|
|
22149
|
+
if (!link.names.some((n) => n.name === f.viewStateType)) {
|
|
22150
|
+
link.names.push({ name: f.viewStateType, type: JayUnknown });
|
|
22151
|
+
}
|
|
22152
|
+
}
|
|
22153
|
+
newContext.usedComponentImports.add(f.viewStateType);
|
|
22154
|
+
}
|
|
22155
|
+
}
|
|
22049
22156
|
const instanceRef = mkRef(
|
|
22050
22157
|
refRefName,
|
|
22051
22158
|
refOriginalName,
|
|
@@ -22053,18 +22160,30 @@ const ${componentSymbol} = makeHeadlessInstanceComponent(
|
|
|
22053
22160
|
isRepeated,
|
|
22054
22161
|
!htmlElement.attributes.ref,
|
|
22055
22162
|
newContext.variables.currentType,
|
|
22056
|
-
new JayTypeAlias(
|
|
22163
|
+
new JayTypeAlias(augmented.type),
|
|
22164
|
+
// DL#198 — declare free refs on the page-side region ref so renderReferenceManager emits the
|
|
22165
|
+
// per-region FreeReferenceManager (with per-free-ref `repeated` driving element vs collection).
|
|
22166
|
+
freeRefDecls.length > 0 ? freeRefDecls : void 0
|
|
22057
22167
|
);
|
|
22168
|
+
const instanceRefsTree = mkRefsTree([instanceRef], {});
|
|
22058
22169
|
let renderedRef = new RenderFragment(
|
|
22059
22170
|
`${refConstName}()`,
|
|
22060
22171
|
Imports.for(),
|
|
22061
22172
|
[],
|
|
22062
|
-
|
|
22173
|
+
instanceRefsTree
|
|
22063
22174
|
);
|
|
22064
22175
|
if (renderedRef.rendered !== "") renderedRef = renderedRef.map((_) => ", " + _);
|
|
22176
|
+
const freeRefManagerArg = freeRefNames.length > 0 ? `, ${refConstName}FreeRefManager` : "";
|
|
22177
|
+
let childCompImports = Imports.for(Import.childComp).plus(propsGetterAndRefs.imports).plus(renderedRef.imports).plus(Import.ConstructContext).plus(
|
|
22178
|
+
headlessImport.structural ? Import.makePassthroughHeadlessInstanceComponent : Import.makeHeadlessInstanceComponent
|
|
22179
|
+
);
|
|
22180
|
+
if (augmented.needsElementProxy)
|
|
22181
|
+
childCompImports = childCompImports.plus(Import.HTMLElementProxy);
|
|
22182
|
+
if (augmented.needsCollectionProxy)
|
|
22183
|
+
childCompImports = childCompImports.plus(Import.HTMLElementCollectionProxy);
|
|
22065
22184
|
return new RenderFragment(
|
|
22066
|
-
`${newContext.indent.firstLine}childComp(${componentSymbol}, ${getProps}${renderedRef.rendered})`,
|
|
22067
|
-
|
|
22185
|
+
`${newContext.indent.firstLine}childComp(${componentSymbol}, ${getProps}${renderedRef.rendered}${freeRefManagerArg})`,
|
|
22186
|
+
childCompImports,
|
|
22068
22187
|
[
|
|
22069
22188
|
...propsGetterAndRefs.validations,
|
|
22070
22189
|
...inlineBody.validations,
|
|
@@ -22113,7 +22232,11 @@ const ${componentSymbol} = makeHeadlessInstanceComponent(
|
|
|
22113
22232
|
nestedChildElement.imports.plus(Import.withData).plus(accessorExpr.render().imports),
|
|
22114
22233
|
[...accessorExpr.validations, ...nestedChildElement.validations],
|
|
22115
22234
|
nestedChildElement.refs,
|
|
22116
|
-
nestedChildElement.recursiveRegions
|
|
22235
|
+
nestedChildElement.recursiveRegions,
|
|
22236
|
+
// DL#193: `with-data` is a data-scope switch; it re-runs its body on every
|
|
22237
|
+
// parent update at runtime (no flag needed), and the residual `$parent`
|
|
22238
|
+
// depth drops by one.
|
|
22239
|
+
Math.max(0, nestedChildElement.parentDepth - 1)
|
|
22117
22240
|
);
|
|
22118
22241
|
} else if (isRecurse(htmlElement)) {
|
|
22119
22242
|
const refAttr = htmlElement.getAttribute("ref");
|
|
@@ -22187,7 +22310,6 @@ const ${componentSymbol} = makeHeadlessInstanceComponent(
|
|
|
22187
22310
|
isInsideGuard: true,
|
|
22188
22311
|
// Mark that we're inside a guard
|
|
22189
22312
|
insideFastForEach: true
|
|
22190
|
-
// Fast-phase forEach — headless instances not supported
|
|
22191
22313
|
};
|
|
22192
22314
|
let childElement = renderHtmlElement(htmlElement, newContext);
|
|
22193
22315
|
return nestRefs(
|
|
@@ -22295,9 +22417,7 @@ function renderFunctionImplementation$1(types2, rootBodyElement, importStatement
|
|
|
22295
22417
|
const variables = new Variables(types2);
|
|
22296
22418
|
const { importedSymbols, importedSandboxedSymbols } = processImportedComponents(importStatements);
|
|
22297
22419
|
const importedRefNameToRef = processImportedHeadless(headlessImports);
|
|
22298
|
-
const headlessContractNames = new Set(
|
|
22299
|
-
headlessImports.filter((h) => !h.structural).map((h) => h.contractName)
|
|
22300
|
-
);
|
|
22420
|
+
const headlessContractNames = new Set(headlessImports.map((h) => h.contractName));
|
|
22301
22421
|
assignCoordinates(rootBodyElement, { headlessContractNames });
|
|
22302
22422
|
const rootElement = ensureSingleChildElement(rootBodyElement);
|
|
22303
22423
|
let renderedRoot;
|
|
@@ -22359,8 +22479,12 @@ ${renderedRoot.rendered}
|
|
|
22359
22479
|
if (headLinks.length > 0) {
|
|
22360
22480
|
imports = imports.plus(Import.injectHeadLinks);
|
|
22361
22481
|
}
|
|
22362
|
-
const { imports: refImports, renderedRefs } = renderRefsType(
|
|
22482
|
+
const { imports: refImports, renderedRefs: renderedPageRefs } = renderRefsType(
|
|
22483
|
+
renderedRoot.refs,
|
|
22484
|
+
refsType
|
|
22485
|
+
);
|
|
22363
22486
|
imports = imports.plus(refImports);
|
|
22487
|
+
const renderedRefs = renderedPageRefs;
|
|
22364
22488
|
let renderedElement = `export type ${elementType} = JayElement<${viewStateType}, ${refsType}>
|
|
22365
22489
|
export type ${renderType2} = RenderElement<${viewStateType}, ${refsType}, ${elementType}>
|
|
22366
22490
|
export type ${preRenderType} = [${refsType}, ${renderType2}]
|
|
@@ -22374,10 +22498,11 @@ ${Indent.forceIndent(code, 4)},
|
|
|
22374
22498
|
funcRepository)`
|
|
22375
22499
|
);
|
|
22376
22500
|
}
|
|
22377
|
-
const { renderedRefsManager } = renderReferenceManager(
|
|
22501
|
+
const { renderedRefsManager, refsManagerImport } = renderReferenceManager(
|
|
22378
22502
|
renderedRoot.refs,
|
|
22379
22503
|
ReferenceManagerTarget.element
|
|
22380
22504
|
);
|
|
22505
|
+
imports = imports.plus(refsManagerImport);
|
|
22381
22506
|
const headLinksInjection = headLinks.length > 0 ? ` injectHeadLinks(${renderHeadLinksArray(headLinks)});
|
|
22382
22507
|
` : "";
|
|
22383
22508
|
const recursiveFunctions = generateRecursiveFunctions(renderedRoot.recursiveRegions);
|
|
@@ -22389,11 +22514,12 @@ ${recursiveFunctions}
|
|
|
22389
22514
|
for (const def of headlessInstanceDefs) {
|
|
22390
22515
|
imports = imports.plus(def.imports);
|
|
22391
22516
|
}
|
|
22517
|
+
const rootCallback = `() => ${renderedRoot.rendered.trim()}`;
|
|
22392
22518
|
const body = `${headlessDefsCode}export function render(options?: RenderElementOptions): ${preRenderType} {
|
|
22393
|
-
${renderedRefsManager}
|
|
22519
|
+
${renderedRefsManager}
|
|
22394
22520
|
${headLinksInjection}${recursiveFunctionsSection} const render = (viewState: ${viewStateType}) => ConstructContext.withRootContext(
|
|
22395
22521
|
viewState, refManager,
|
|
22396
|
-
|
|
22522
|
+
${rootCallback}
|
|
22397
22523
|
) as ${elementType};
|
|
22398
22524
|
return [refManager.getPublicAPI() as ${refsType}, render];
|
|
22399
22525
|
}`;
|
|
@@ -22498,11 +22624,15 @@ function generateElementFile(jayFile, importerMode) {
|
|
|
22498
22624
|
const usedHeadlessTypeNames = new Set(usedComponentImports);
|
|
22499
22625
|
const headlessModules = /* @__PURE__ */ new Set();
|
|
22500
22626
|
for (const headless of jayFile.headlessImports) {
|
|
22501
|
-
|
|
22627
|
+
if (!headless.structural) {
|
|
22628
|
+
usedHeadlessTypeNames.add(headless.rootType.name);
|
|
22629
|
+
}
|
|
22502
22630
|
for (const link of headless.contractLinks) {
|
|
22503
22631
|
headlessModules.add(link.module);
|
|
22504
22632
|
for (const name of link.names) {
|
|
22505
|
-
if (
|
|
22633
|
+
if (isEnumType(name.type)) {
|
|
22634
|
+
usedHeadlessTypeNames.add(name.name);
|
|
22635
|
+
} else if (!headless.structural && name.name.endsWith("Refs")) {
|
|
22506
22636
|
usedHeadlessTypeNames.add(name.name);
|
|
22507
22637
|
}
|
|
22508
22638
|
}
|
|
@@ -22584,7 +22714,7 @@ function generateElementBridgeFile(jayFile) {
|
|
|
22584
22714
|
}
|
|
22585
22715
|
function generateElementHydrateFile(jayFile, importerMode) {
|
|
22586
22716
|
const types2 = generateTypes(jayFile.types);
|
|
22587
|
-
const headlessImports = jayFile.headlessImports?.filter((h) => !h.key
|
|
22717
|
+
const headlessImports = jayFile.headlessImports?.filter((h) => !h.key) ?? [];
|
|
22588
22718
|
const headlessContractNames = new Set(headlessImports.map((h) => h.contractName));
|
|
22589
22719
|
assignCoordinates(jayFile.body, { headlessContractNames });
|
|
22590
22720
|
const {
|
|
@@ -22605,7 +22735,7 @@ function generateElementHydrateFile(jayFile, importerMode) {
|
|
|
22605
22735
|
jayFile.headLinks
|
|
22606
22736
|
);
|
|
22607
22737
|
const phaseTypes = generatePhaseSpecificTypes(jayFile);
|
|
22608
|
-
const renderedHydrate = renderHydrate(
|
|
22738
|
+
const { fragment: renderedHydrate } = renderHydrate(
|
|
22609
22739
|
jayFile.types,
|
|
22610
22740
|
jayFile.body,
|
|
22611
22741
|
jayFile.imports,
|
|
@@ -22615,16 +22745,43 @@ function generateElementHydrateFile(jayFile, importerMode) {
|
|
|
22615
22745
|
jayFile.headlessImports,
|
|
22616
22746
|
jayFile.contract
|
|
22617
22747
|
);
|
|
22748
|
+
const allRenderedRefs = renderedRefs;
|
|
22618
22749
|
let finalRenderedElement = renderedElement;
|
|
22619
22750
|
if (jayFile.contract || jayFile.hasInlineData) {
|
|
22620
22751
|
finalRenderedElement = expandContractType(finalRenderedElement, jayFile.baseElementName);
|
|
22621
22752
|
}
|
|
22622
22753
|
const typeOnlyImports = renderedImplementation.imports.minus(renderedHydrate.imports).minus(Import.element).minus(Import.dynamicText).minus(Import.dynamicElement).minus(Import.conditional).minus(Import.forEach);
|
|
22623
22754
|
const hydrateImports = typeOnlyImports.plus(Import.jayElement).plus(renderedHydrate.imports);
|
|
22755
|
+
const structuralHeadless = (jayFile.headlessImports ?? []).filter((h) => h.structural);
|
|
22756
|
+
let filteredHydrateImports = jayFile.imports;
|
|
22757
|
+
if (structuralHeadless.length > 0) {
|
|
22758
|
+
const structuralModules = new Set(
|
|
22759
|
+
structuralHeadless.flatMap((h) => h.contractLinks.map((l) => l.module))
|
|
22760
|
+
);
|
|
22761
|
+
const dropNames = /* @__PURE__ */ new Set();
|
|
22762
|
+
for (const headless of structuralHeadless) {
|
|
22763
|
+
dropNames.add(headless.rootType.name);
|
|
22764
|
+
}
|
|
22765
|
+
for (const headless of (jayFile.headlessImports ?? []).filter((h) => !h.structural)) {
|
|
22766
|
+
dropNames.delete(headless.rootType.name);
|
|
22767
|
+
for (const link of headless.contractLinks)
|
|
22768
|
+
for (const name of link.names) dropNames.delete(name.name);
|
|
22769
|
+
}
|
|
22770
|
+
filteredHydrateImports = jayFile.imports.map((importLink) => {
|
|
22771
|
+
if (!structuralModules.has(importLink.module)) return importLink;
|
|
22772
|
+
const names = importLink.names.filter((n) => !dropNames.has(n.as || n.name));
|
|
22773
|
+
return names.length === 0 ? null : { ...importLink, names };
|
|
22774
|
+
}).filter((imp) => imp !== null);
|
|
22775
|
+
}
|
|
22624
22776
|
const renderedFile = [
|
|
22625
|
-
renderImports$1(
|
|
22777
|
+
renderImports$1(
|
|
22778
|
+
hydrateImports,
|
|
22779
|
+
ImportsFor.implementation,
|
|
22780
|
+
filteredHydrateImports,
|
|
22781
|
+
importerMode
|
|
22782
|
+
),
|
|
22626
22783
|
types2,
|
|
22627
|
-
|
|
22784
|
+
allRenderedRefs,
|
|
22628
22785
|
phaseTypes,
|
|
22629
22786
|
finalRenderedElement,
|
|
22630
22787
|
renderedHydrate.rendered
|
|
@@ -22863,7 +23020,10 @@ function renderAttributes(element, { variables }) {
|
|
|
22863
23020
|
);
|
|
22864
23021
|
else if (attrName === "class") {
|
|
22865
23022
|
let classExpression = parseReactClassExpression(attributes2[attrName], variables);
|
|
22866
|
-
|
|
23023
|
+
let classFragment = classExpression.map((_) => `className=${_}`);
|
|
23024
|
+
if (classExpression.rendered.includes("cx("))
|
|
23025
|
+
classFragment = classFragment.plusImport(Imports.for(Import.classNamesReact));
|
|
23026
|
+
renderedAttributes.push(classFragment);
|
|
22867
23027
|
} else if (booleanAttributes.has(attrCanonical)) {
|
|
22868
23028
|
const attrValue = attributes2[attrName];
|
|
22869
23029
|
if (attrValue === "") {
|
|
@@ -23198,6 +23358,24 @@ function generateElementFileReactTarget(jayFile, importerMode) {
|
|
|
23198
23358
|
].filter((_) => _ !== null && _ !== "").join("\n\n");
|
|
23199
23359
|
return new WithValidations(renderedFile, renderedImplementation.validations);
|
|
23200
23360
|
}
|
|
23361
|
+
function buildStructuralCoercions(rawVar, tags) {
|
|
23362
|
+
const coercions = [];
|
|
23363
|
+
for (const tag of tags) {
|
|
23364
|
+
const dt = tag.dataType;
|
|
23365
|
+
if (!dt) continue;
|
|
23366
|
+
const field = `${rawVar}.${tag.tag}`;
|
|
23367
|
+
if (isEnumType(dt)) {
|
|
23368
|
+
coercions.push(
|
|
23369
|
+
`${tag.tag}: typeof (${dt.name} as any)[${field}] === 'number' ? (${dt.name} as any)[${field}] : Number(${field})`
|
|
23370
|
+
);
|
|
23371
|
+
} else if (dt.name === "number") {
|
|
23372
|
+
coercions.push(`${tag.tag}: Number(${field})`);
|
|
23373
|
+
} else if (dt.name === "boolean") {
|
|
23374
|
+
coercions.push(`${tag.tag}: ${field} === true || ${field} === 'true'`);
|
|
23375
|
+
}
|
|
23376
|
+
}
|
|
23377
|
+
return coercions;
|
|
23378
|
+
}
|
|
23201
23379
|
function w(indent, code, imports = Imports.none()) {
|
|
23202
23380
|
return new RenderFragment(`${indent.firstLine}w(${code});`, imports);
|
|
23203
23381
|
}
|
|
@@ -23314,7 +23492,12 @@ function renderServerHeadlessInstance(element, context, contractName) {
|
|
|
23314
23492
|
instanceKeyExpr = `'${instanceCoord}'`;
|
|
23315
23493
|
}
|
|
23316
23494
|
const ifCondition = element.attributes.if;
|
|
23317
|
-
const componentVariables = new Variables(
|
|
23495
|
+
const componentVariables = new Variables(
|
|
23496
|
+
headlessImport.rootType,
|
|
23497
|
+
context.variables,
|
|
23498
|
+
0,
|
|
23499
|
+
varName
|
|
23500
|
+
).asLexical();
|
|
23318
23501
|
const childNodes = filterContentNodes(element.childNodes);
|
|
23319
23502
|
if (childNodes.length === 0) {
|
|
23320
23503
|
return new RenderFragment("", Imports.none(), [
|
|
@@ -23346,8 +23529,15 @@ function renderServerHeadlessInstance(element, context, contractName) {
|
|
|
23346
23529
|
})
|
|
23347
23530
|
);
|
|
23348
23531
|
const guardIndent = ifCondition ? new Indent(indent.curr + " ") : indent;
|
|
23532
|
+
const coercions = headlessImport.structural ? buildStructuralCoercions(`${varName}_raw`, headlessImport.contract?.tags ?? []) : [];
|
|
23533
|
+
const extractionLines = coercions.length > 0 ? [
|
|
23534
|
+
`${guardIndent.firstLine}const ${varName}_raw = (vs as any).__headlessInstances?.[${instanceKeyExpr}] as any;`,
|
|
23535
|
+
`${guardIndent.firstLine}const ${varName} = ${varName}_raw ? ({ ...${varName}_raw, ${coercions.join(", ")} } as ${viewStateTypeName}) : undefined;`
|
|
23536
|
+
] : [
|
|
23537
|
+
`${guardIndent.firstLine}const ${varName} = (vs as any).__headlessInstances?.[${instanceKeyExpr}] as ${viewStateTypeName} | undefined;`
|
|
23538
|
+
];
|
|
23349
23539
|
const guardedBlock = [
|
|
23350
|
-
|
|
23540
|
+
...extractionLines,
|
|
23351
23541
|
`${guardIndent.firstLine}if (${varName}) {`,
|
|
23352
23542
|
renderedChildren.rendered,
|
|
23353
23543
|
`${guardIndent.firstLine}}`
|
|
@@ -23419,12 +23609,9 @@ function renderServerAttributes(element, context) {
|
|
|
23419
23609
|
const classExpr = parseClassExpression(attrValue, variables);
|
|
23420
23610
|
if (classExpr.imports.has(Import.dynamicAttribute)) {
|
|
23421
23611
|
const rawExpr = classExpr.rendered.replace(/^da\(\w+ => /, "").replace(/\)$/, "");
|
|
23612
|
+
const classImports = classExpr.imports.has(Import.classNames) ? Imports.for(Import.escapeAttr, Import.classNamesServer) : Imports.for(Import.escapeAttr);
|
|
23422
23613
|
parts.push(
|
|
23423
|
-
w(
|
|
23424
|
-
indent,
|
|
23425
|
-
`' class="' + escapeAttr(String(${rawExpr})) + '"'`,
|
|
23426
|
-
Imports.for(Import.escapeAttr)
|
|
23427
|
-
)
|
|
23614
|
+
w(indent, `' class="' + escapeAttr(String(${rawExpr})) + '"'`, classImports)
|
|
23428
23615
|
);
|
|
23429
23616
|
} else {
|
|
23430
23617
|
const escaped = escapeForJsString(attrValue);
|
|
@@ -23614,10 +23801,11 @@ function renderServerAttributesAsString(element, context) {
|
|
|
23614
23801
|
const classExpr = parseClassExpression(attrValue, variables);
|
|
23615
23802
|
if (classExpr.imports.has(Import.dynamicAttribute)) {
|
|
23616
23803
|
const rawExpr = classExpr.rendered.replace(/^da\(\w+ => /, "").replace(/\)$/, "");
|
|
23804
|
+
const classImports = classExpr.imports.has(Import.classNames) ? Imports.for(Import.escapeAttr, Import.classNamesServer) : Imports.for(Import.escapeAttr);
|
|
23617
23805
|
parts.push(
|
|
23618
23806
|
new RenderFragment(
|
|
23619
23807
|
`' class="' + escapeAttr(String(${rawExpr})) + '"'`,
|
|
23620
|
-
|
|
23808
|
+
classImports
|
|
23621
23809
|
)
|
|
23622
23810
|
);
|
|
23623
23811
|
} else {
|
|
@@ -23807,7 +23995,14 @@ function renderServerAsyncGroup(group, context) {
|
|
|
23807
23995
|
const templateValidations = [];
|
|
23808
23996
|
if (group.resolvedElement) {
|
|
23809
23997
|
const promiseResolvedType = asyncAccessor.resolvedType.itemType;
|
|
23810
|
-
const resolvedVariables = new Variables(
|
|
23998
|
+
const resolvedVariables = new Variables(
|
|
23999
|
+
promiseResolvedType,
|
|
24000
|
+
variables,
|
|
24001
|
+
1,
|
|
24002
|
+
void 0,
|
|
24003
|
+
{},
|
|
24004
|
+
variables.lexicallyInScope
|
|
24005
|
+
);
|
|
23811
24006
|
const resolvedContext = {
|
|
23812
24007
|
...context,
|
|
23813
24008
|
variables: resolvedVariables
|
|
@@ -23824,7 +24019,14 @@ function renderServerAsyncGroup(group, context) {
|
|
|
23824
24019
|
templateValidations.push(...resolvedString.validations);
|
|
23825
24020
|
}
|
|
23826
24021
|
if (group.rejectedElement) {
|
|
23827
|
-
const rejectedVariables = new Variables(
|
|
24022
|
+
const rejectedVariables = new Variables(
|
|
24023
|
+
JayErrorType,
|
|
24024
|
+
variables,
|
|
24025
|
+
1,
|
|
24026
|
+
void 0,
|
|
24027
|
+
{},
|
|
24028
|
+
variables.lexicallyInScope
|
|
24029
|
+
);
|
|
23828
24030
|
const rejectedContext = {
|
|
23829
24031
|
...context,
|
|
23830
24032
|
variables: rejectedVariables
|
|
@@ -23884,7 +24086,7 @@ function hasMixedContentDynamicTextInteractive(childNodes, interactivePaths) {
|
|
|
23884
24086
|
}
|
|
23885
24087
|
function generateServerElementFile(jayFile, _options) {
|
|
23886
24088
|
const types2 = generateTypes(jayFile.types);
|
|
23887
|
-
const variables = new Variables(jayFile.types);
|
|
24089
|
+
const variables = new Variables(jayFile.types).asLexical();
|
|
23888
24090
|
const rootElement = ensureSingleChildElement(jayFile.body);
|
|
23889
24091
|
if (!rootElement.val) {
|
|
23890
24092
|
return new WithValidations("", rootElement.validations);
|
|
@@ -23903,14 +24105,29 @@ function generateServerElementFile(jayFile, _options) {
|
|
|
23903
24105
|
interactivePaths: buildInteractivePaths(jayFile.contract),
|
|
23904
24106
|
parentHasInteractiveChildren: false
|
|
23905
24107
|
};
|
|
23906
|
-
const
|
|
23907
|
-
|
|
23908
|
-
|
|
24108
|
+
const rootComponentMatch = getComponentName(
|
|
24109
|
+
rootElement.val.rawTagName,
|
|
24110
|
+
/* @__PURE__ */ new Set(),
|
|
24111
|
+
// No headful component imports in server-element target
|
|
24112
|
+
headlessContractNames
|
|
24113
|
+
);
|
|
24114
|
+
let rendered;
|
|
24115
|
+
try {
|
|
24116
|
+
rendered = rootComponentMatch !== null && rootComponentMatch.kind === "headless-instance" ? renderServerElement(rootElement.val, context) : renderServerElementContent(rootElement.val, context, {
|
|
24117
|
+
isRoot: true
|
|
24118
|
+
});
|
|
24119
|
+
} catch (e2) {
|
|
24120
|
+
if (e2 instanceof UnsupportedServerParentBindingError) {
|
|
24121
|
+
return new WithValidations("", [UNSUPPORTED_TARGET_PARENT_MESSAGE]);
|
|
24122
|
+
}
|
|
24123
|
+
throw e2;
|
|
24124
|
+
}
|
|
23909
24125
|
const viewStateType = jayFile.types.name;
|
|
23910
24126
|
const hasAsync = rendered.rendered.includes("onAsync(");
|
|
23911
24127
|
const importParts = [];
|
|
23912
24128
|
if (rendered.imports.has(Import.escapeHtml)) importParts.push("escapeHtml");
|
|
23913
24129
|
if (rendered.imports.has(Import.escapeAttr)) importParts.push("escapeAttr");
|
|
24130
|
+
if (rendered.imports.has(Import.classNamesServer)) importParts.push("classNames as cx");
|
|
23914
24131
|
importParts.push("type ServerRenderContext");
|
|
23915
24132
|
const importStatement = `import {${importParts.join(", ")}} from "@jay-framework/ssr-runtime";`;
|
|
23916
24133
|
const usedTypeNames = /* @__PURE__ */ new Set();
|
|
@@ -23920,17 +24137,35 @@ function generateServerElementFile(jayFile, _options) {
|
|
|
23920
24137
|
for (const link of headless.contractLinks) {
|
|
23921
24138
|
headlessModules.add(link.module);
|
|
23922
24139
|
for (const name of link.names) {
|
|
23923
|
-
if (
|
|
24140
|
+
if (isEnumType(name.type)) {
|
|
24141
|
+
usedTypeNames.add(name.name);
|
|
24142
|
+
} else if (!name.name.endsWith("Refs")) {
|
|
23924
24143
|
usedTypeNames.add(name.name);
|
|
23925
24144
|
}
|
|
23926
24145
|
}
|
|
23927
24146
|
}
|
|
23928
24147
|
}
|
|
23929
|
-
const
|
|
23930
|
-
|
|
23931
|
-
|
|
23932
|
-
|
|
23933
|
-
|
|
24148
|
+
const typeNamesByModule = /* @__PURE__ */ new Map();
|
|
24149
|
+
const typeNamesSeen = /* @__PURE__ */ new Map();
|
|
24150
|
+
for (const imp of jayFile.imports) {
|
|
24151
|
+
if (!headlessModules.has(imp.module)) continue;
|
|
24152
|
+
let names = typeNamesByModule.get(imp.module);
|
|
24153
|
+
let seen = typeNamesSeen.get(imp.module);
|
|
24154
|
+
if (!names) {
|
|
24155
|
+
names = [];
|
|
24156
|
+
seen = /* @__PURE__ */ new Set();
|
|
24157
|
+
typeNamesByModule.set(imp.module, names);
|
|
24158
|
+
typeNamesSeen.set(imp.module, seen);
|
|
24159
|
+
}
|
|
24160
|
+
for (const n of imp.names) {
|
|
24161
|
+
if (!usedTypeNames.has(n.as || n.name)) continue;
|
|
24162
|
+
const rendered2 = n.as ? `${n.name} as ${n.as}` : n.name;
|
|
24163
|
+
if (seen.has(rendered2)) continue;
|
|
24164
|
+
seen.add(rendered2);
|
|
24165
|
+
names.push(rendered2);
|
|
24166
|
+
}
|
|
24167
|
+
}
|
|
24168
|
+
const contractImports = [...typeNamesByModule.entries()].filter(([, typeNames]) => typeNames.length > 0).map(([module, typeNames]) => `import {${typeNames.join(", ")}} from "${module}";`);
|
|
23934
24169
|
const ctxDestructure = hasAsync ? "const { write: w, onAsync } = ctx;" : "const { write: w } = ctx;";
|
|
23935
24170
|
const renderedFile = [
|
|
23936
24171
|
importStatement,
|
|
@@ -30653,12 +30888,13 @@ const JAY_IMPORT_RESOLVER = {
|
|
|
30653
30888
|
return analyzeExportedTypes(fullPath, options);
|
|
30654
30889
|
},
|
|
30655
30890
|
loadContract(fullPath) {
|
|
30656
|
-
const content = fs.readFileSync(fullPath).toString();
|
|
30891
|
+
const content = fs$1.readFileSync(fullPath).toString();
|
|
30657
30892
|
return parseContract(content, fullPath);
|
|
30658
30893
|
},
|
|
30659
30894
|
resolveLink(importingModuleDir, link) {
|
|
30660
30895
|
if (link?.[0] === ".") return path.resolve(importingModuleDir, link);
|
|
30661
|
-
|
|
30896
|
+
if (link?.[0] === "/") return link;
|
|
30897
|
+
return require$1.resolve(link, { paths: require$1.resolve.paths(importingModuleDir) });
|
|
30662
30898
|
},
|
|
30663
30899
|
resolvePluginComponent(pluginName, contractName, projectRoot) {
|
|
30664
30900
|
return resolvePluginComponent(projectRoot, pluginName, contractName);
|
|
@@ -30667,7 +30903,7 @@ const JAY_IMPORT_RESOLVER = {
|
|
|
30667
30903
|
const resolution = resolvePluginComponent(projectRoot, pluginName, contractName);
|
|
30668
30904
|
if (resolution.val && resolution.val.contractPath) {
|
|
30669
30905
|
const contractPath = resolution.val.contractPath;
|
|
30670
|
-
const content = fs.readFileSync(contractPath).toString();
|
|
30906
|
+
const content = fs$1.readFileSync(contractPath).toString();
|
|
30671
30907
|
const contractResult = parseContract(content, contractPath);
|
|
30672
30908
|
return contractResult.map((contract) => ({ contract, contractPath }));
|
|
30673
30909
|
}
|
|
@@ -30675,14 +30911,14 @@ const JAY_IMPORT_RESOLVER = {
|
|
|
30675
30911
|
const pluginDir = pluginName.startsWith("@") ? pluginName.split("/").pop() || pluginName : pluginName;
|
|
30676
30912
|
const contractFileName = contractName.replace(/\//g, "-") + ".jay-contract";
|
|
30677
30913
|
const materializedPath = path.join(materializedDir, pluginDir, contractFileName);
|
|
30678
|
-
if (fs.existsSync(materializedPath)) {
|
|
30679
|
-
const content = fs.readFileSync(materializedPath).toString();
|
|
30914
|
+
if (fs$1.existsSync(materializedPath)) {
|
|
30915
|
+
const content = fs$1.readFileSync(materializedPath).toString();
|
|
30680
30916
|
const contractResult = parseContract(content, materializedPath);
|
|
30681
30917
|
let metadata;
|
|
30682
30918
|
const indexPath = path.join(projectRoot, "agent-kit", "plugins-index.yaml");
|
|
30683
|
-
if (fs.existsSync(indexPath)) {
|
|
30919
|
+
if (fs$1.existsSync(indexPath)) {
|
|
30684
30920
|
try {
|
|
30685
|
-
const indexContent = fs.readFileSync(indexPath, "utf-8");
|
|
30921
|
+
const indexContent = fs$1.readFileSync(indexPath, "utf-8");
|
|
30686
30922
|
const index2 = YAML.parse(indexContent);
|
|
30687
30923
|
const plugin = index2.plugins?.find(
|
|
30688
30924
|
(p) => p.name === pluginName || p.name === pluginDir
|
|
@@ -30711,13 +30947,13 @@ const JAY_IMPORT_RESOLVER = {
|
|
|
30711
30947
|
const resolvedPath = src.startsWith(".") ? path.resolve(importingModuleDir, src) : src;
|
|
30712
30948
|
const jayHtmlPath = resolvedPath + ".jay-html";
|
|
30713
30949
|
try {
|
|
30714
|
-
const content = fs.readFileSync(jayHtmlPath, "utf-8");
|
|
30950
|
+
const content = fs$1.readFileSync(jayHtmlPath, "utf-8");
|
|
30715
30951
|
return { content, componentDir: path.dirname(jayHtmlPath), filePath: jayHtmlPath };
|
|
30716
30952
|
} catch {
|
|
30717
30953
|
}
|
|
30718
30954
|
const dirJayHtmlPath = path.resolve(resolvedPath, path.basename(resolvedPath)) + ".jay-html";
|
|
30719
30955
|
try {
|
|
30720
|
-
const content = fs.readFileSync(dirJayHtmlPath, "utf-8");
|
|
30956
|
+
const content = fs$1.readFileSync(dirJayHtmlPath, "utf-8");
|
|
30721
30957
|
return {
|
|
30722
30958
|
content,
|
|
30723
30959
|
componentDir: path.dirname(dirJayHtmlPath),
|
|
@@ -30907,6 +31143,10 @@ function resolveRelativePaths(root, sourceDir) {
|
|
|
30907
31143
|
if (src && isRelativePath(src)) {
|
|
30908
31144
|
script.setAttribute("src", path.resolve(sourceDir, src));
|
|
30909
31145
|
}
|
|
31146
|
+
const contract = script.getAttribute("contract");
|
|
31147
|
+
if (contract && isRelativePath(contract)) {
|
|
31148
|
+
script.setAttribute("contract", path.resolve(sourceDir, contract));
|
|
31149
|
+
}
|
|
30910
31150
|
}
|
|
30911
31151
|
const links = root.querySelectorAll('link[rel="stylesheet"]');
|
|
30912
31152
|
for (const link of links) {
|
|
@@ -31014,7 +31254,7 @@ function discoverHeadlessInstances(preRenderedJayHtml) {
|
|
|
31014
31254
|
const instances = [];
|
|
31015
31255
|
const forEachInstances = [];
|
|
31016
31256
|
const coordinateCounters = /* @__PURE__ */ new Map();
|
|
31017
|
-
function walk(element, insidePreservedForEach, forEachContexts) {
|
|
31257
|
+
function walk(element, insidePreservedForEach, forEachContexts, parentCoordinate) {
|
|
31018
31258
|
const tagName = element.tagName?.toLowerCase();
|
|
31019
31259
|
const forEachAttr = element.getAttribute("forEach");
|
|
31020
31260
|
const hasForEach = forEachAttr != null;
|
|
@@ -31028,6 +31268,7 @@ function discoverHeadlessInstances(preRenderedJayHtml) {
|
|
|
31028
31268
|
props[toCamelCase(key)] = value;
|
|
31029
31269
|
}
|
|
31030
31270
|
}
|
|
31271
|
+
let childParentCoordinate = parentCoordinate;
|
|
31031
31272
|
if (!insidePreservedForEach) {
|
|
31032
31273
|
let ref = element.getAttribute("ref");
|
|
31033
31274
|
if (!ref) {
|
|
@@ -31043,8 +31284,10 @@ function discoverHeadlessInstances(preRenderedJayHtml) {
|
|
|
31043
31284
|
instances.push({
|
|
31044
31285
|
contractName,
|
|
31045
31286
|
props,
|
|
31046
|
-
coordinate
|
|
31287
|
+
coordinate,
|
|
31288
|
+
parentCoordinate
|
|
31047
31289
|
});
|
|
31290
|
+
childParentCoordinate = coordinate;
|
|
31048
31291
|
} else {
|
|
31049
31292
|
const innerForEach = forEachContexts[forEachContexts.length - 1];
|
|
31050
31293
|
if (innerForEach) {
|
|
@@ -31066,7 +31309,12 @@ function discoverHeadlessInstances(preRenderedJayHtml) {
|
|
|
31066
31309
|
}
|
|
31067
31310
|
for (const child of element.childNodes) {
|
|
31068
31311
|
if (child.nodeType === NodeType.ELEMENT_NODE) {
|
|
31069
|
-
walk(
|
|
31312
|
+
walk(
|
|
31313
|
+
child,
|
|
31314
|
+
insidePreservedForEach,
|
|
31315
|
+
forEachContexts,
|
|
31316
|
+
childParentCoordinate
|
|
31317
|
+
);
|
|
31070
31318
|
}
|
|
31071
31319
|
}
|
|
31072
31320
|
return;
|
|
@@ -31077,14 +31325,15 @@ function discoverHeadlessInstances(preRenderedJayHtml) {
|
|
|
31077
31325
|
walk(
|
|
31078
31326
|
child,
|
|
31079
31327
|
insidePreservedForEach || hasForEach,
|
|
31080
|
-
updatedForEachContexts
|
|
31328
|
+
updatedForEachContexts,
|
|
31329
|
+
parentCoordinate
|
|
31081
31330
|
);
|
|
31082
31331
|
}
|
|
31083
31332
|
}
|
|
31084
31333
|
}
|
|
31085
31334
|
const body = root.querySelector("body");
|
|
31086
31335
|
if (body) {
|
|
31087
|
-
walk(body, false, []);
|
|
31336
|
+
walk(body, false, [], void 0);
|
|
31088
31337
|
}
|
|
31089
31338
|
return { instances, forEachInstances, preRenderedJayHtml: root.toString() };
|
|
31090
31339
|
}
|
|
@@ -31215,7 +31464,6 @@ export {
|
|
|
31215
31464
|
getLinkedContractDir,
|
|
31216
31465
|
hasSlowPhaseProperties,
|
|
31217
31466
|
htmlElementTagNameMap,
|
|
31218
|
-
injectHeadfullFSTemplates,
|
|
31219
31467
|
isTagInPhase,
|
|
31220
31468
|
loadLinkedContract,
|
|
31221
31469
|
parseAction,
|