@jay-framework/compiler-jay-html 0.16.3 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +48 -21
  2. package/package.json +9 -9
package/dist/index.js CHANGED
@@ -13410,6 +13410,9 @@ function parseConditionForSlowRender(expr, slowContext, vars) {
13410
13410
  return { type: "runtime", code: fragment, simplifiedExpr: expr };
13411
13411
  }
13412
13412
  }
13413
+ function kebabToCamel(str2) {
13414
+ return str2.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
13415
+ }
13413
13416
  function isConditional(node2) {
13414
13417
  return node2.nodeType !== NodeType.TEXT_NODE && node2.hasAttribute("if");
13415
13418
  }
@@ -13506,9 +13509,13 @@ function getComponentName(tagName, importedSymbols, headlessContractNames) {
13506
13509
  if (headlessContractNames?.has(componentName.toLowerCase())) {
13507
13510
  return { name: componentName, kind: "headless-instance" };
13508
13511
  }
13512
+ const camelName = kebabToCamel(componentName);
13509
13513
  if (importedSymbols.has(componentName)) {
13510
13514
  return { name: componentName, kind: "headful" };
13511
13515
  }
13516
+ if (camelName !== componentName && importedSymbols.has(camelName)) {
13517
+ return { name: camelName, kind: "headful" };
13518
+ }
13512
13519
  return { name: componentName, kind: "unknown" };
13513
13520
  }
13514
13521
  if (importedSymbols.has(tagName)) {
@@ -19598,6 +19605,15 @@ function renderHydrateElement(element, context) {
19598
19605
  context.headlessContractNames
19599
19606
  );
19600
19607
  if (componentMatch !== null && componentMatch.kind === "headless-instance") {
19608
+ const contractNameLower = componentMatch.name.toLowerCase();
19609
+ const isInstanceImport = context.headlessImports.some(
19610
+ (h) => h.contractName === contractNameLower
19611
+ );
19612
+ if (!isInstanceImport) {
19613
+ return new RenderFragment("", Imports.none(), [
19614
+ `<jay:${componentMatch.name}> cannot be used as an inline element because it was imported with a key. Keyed headless components merge their ViewState into the page — remove the key to use it as an inline instance.`
19615
+ ]);
19616
+ }
19601
19617
  return renderHydrateHeadlessInstance(element, context, renderContext, componentMatch.name);
19602
19618
  }
19603
19619
  if (isConditional(element) && conditionIsInteractive(element.getAttribute("if"), context.interactivePaths)) {
@@ -19980,7 +19996,7 @@ function renderHydrateHeadlessInstance(element, context, renderContext, contract
19980
19996
  };
19981
19997
  const adoptRenderContext = buildRenderContext(adoptItemContext);
19982
19998
  let adoptInlineBody;
19983
- if (childNodes.length === 1) {
19999
+ if (childNodes.length === 1 && !isForEach(childNodes[0]) && !isConditional(childNodes[0])) {
19984
20000
  adoptInlineBody = renderHydrateElementContent(
19985
20001
  childNodes[0],
19986
20002
  adoptItemContext,
@@ -19989,6 +20005,8 @@ function renderHydrateHeadlessInstance(element, context, renderContext, contract
19989
20005
  true
19990
20006
  // forceAdopt
19991
20007
  );
20008
+ } else if (childNodes.length === 1) {
20009
+ adoptInlineBody = renderHydrateNode(childNodes[0], adoptItemContext);
19992
20010
  } else {
19993
20011
  const wrapperCoord = childScopeId ? `${childScopeId}/0` : "0";
19994
20012
  const adoptChildContext = {
@@ -20375,7 +20393,7 @@ function renderHydrate(types2, body, importStatements, elementType, preRenderTyp
20375
20393
  const importedRefNameToRef = processImportedHeadless(headlessImports);
20376
20394
  const { importedSymbols } = processImportedComponents(importStatements);
20377
20395
  const instanceHeadlessImports = headlessImports.filter((h) => !h.key);
20378
- const headlessContractNames = new Set(instanceHeadlessImports.map((h) => h.contractName));
20396
+ const headlessContractNames = new Set(headlessImports.map((h) => h.contractName));
20379
20397
  assignCoordinates(body, { headlessContractNames });
20380
20398
  const context = {
20381
20399
  variables,
@@ -20708,6 +20726,14 @@ function renderNode(node2, context) {
20708
20726
  );
20709
20727
  if (componentMatch !== null) {
20710
20728
  if (componentMatch.kind === "headless-instance") {
20729
+ const keyedImport = newContext.headlessImports.find(
20730
+ (h) => h.key && h.contractName === componentMatch.name.toLowerCase()
20731
+ );
20732
+ if (keyedImport) {
20733
+ return new RenderFragment("", Imports.none(), [
20734
+ `<jay:${componentMatch.name}> cannot be used as an inline element because it was imported with key="${keyedImport.key}". Keyed headless components merge their ViewState into the page — use {${keyedImport.key}.fieldName} bindings instead, or remove the key to use it as an inline instance.`
20735
+ ]);
20736
+ }
20711
20737
  return renderHeadlessInstance(htmlElement, newContext, componentMatch.name);
20712
20738
  }
20713
20739
  return renderNestedComponent(htmlElement, newContext, componentMatch.name);
@@ -22341,7 +22367,11 @@ function renderServerHeadlessInstance(element, context, contractName) {
22341
22367
  const renderedChildren = mergeServerFragments(
22342
22368
  childNodes.map((child) => {
22343
22369
  if (child.nodeType === NodeType.ELEMENT_NODE) {
22344
- return renderServerElementContent(child, instanceContext, {
22370
+ const el = child;
22371
+ if (isForEach(el) || isConditional(el)) {
22372
+ return renderServerElement(el, instanceContext);
22373
+ }
22374
+ return renderServerElementContent(el, instanceContext, {
22345
22375
  isRoot: true
22346
22376
  });
22347
22377
  }
@@ -30053,25 +30083,22 @@ function discoverHeadlessInstances(preRenderedJayHtml) {
30053
30083
  }
30054
30084
  }
30055
30085
  if (!insidePreservedForEach) {
30056
- const hasUnresolvedProps = Object.values(props).some((v) => hasBindings(v));
30057
- if (!hasUnresolvedProps) {
30058
- let ref = element.getAttribute("ref");
30059
- if (!ref) {
30060
- const prefix = buildCoordinatePrefix(element);
30061
- const counterKey = [...prefix, contractName].join("/");
30062
- const localIndex = coordinateCounters.get(counterKey) ?? 0;
30063
- coordinateCounters.set(counterKey, localIndex + 1);
30064
- ref = `AR${localIndex}`;
30065
- element.setAttribute("ref", ref);
30066
- }
30067
- const coordBase = element.getAttribute("jay-coordinate-base");
30068
- const coordinate = coordBase ? coordBase.split("/") : [...buildCoordinatePrefix(element), `${contractName}:${ref}`];
30069
- instances.push({
30070
- contractName,
30071
- props,
30072
- coordinate
30073
- });
30086
+ let ref = element.getAttribute("ref");
30087
+ if (!ref) {
30088
+ const prefix = buildCoordinatePrefix(element);
30089
+ const counterKey = [...prefix, contractName].join("/");
30090
+ const localIndex = coordinateCounters.get(counterKey) ?? 0;
30091
+ coordinateCounters.set(counterKey, localIndex + 1);
30092
+ ref = `AR${localIndex}`;
30093
+ element.setAttribute("ref", ref);
30074
30094
  }
30095
+ const coordBase = element.getAttribute("jay-coordinate-base");
30096
+ const coordinate = coordBase ? coordBase.split("/") : [...buildCoordinatePrefix(element), `${contractName}:${ref}`];
30097
+ instances.push({
30098
+ contractName,
30099
+ props,
30100
+ coordinate
30101
+ });
30075
30102
  } else {
30076
30103
  const innerForEach = forEachContexts[forEachContexts.length - 1];
30077
30104
  if (innerForEach) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/compiler-jay-html",
3
- "version": "0.16.3",
3
+ "version": "0.16.4",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -34,12 +34,12 @@
34
34
  },
35
35
  "author": "",
36
36
  "dependencies": {
37
- "@jay-framework/compiler-analyze-exported-types": "^0.16.3",
38
- "@jay-framework/compiler-shared": "^0.16.3",
39
- "@jay-framework/component": "^0.16.3",
40
- "@jay-framework/logger": "^0.16.3",
41
- "@jay-framework/runtime": "^0.16.3",
42
- "@jay-framework/secure": "^0.16.3",
37
+ "@jay-framework/compiler-analyze-exported-types": "^0.16.4",
38
+ "@jay-framework/compiler-shared": "^0.16.4",
39
+ "@jay-framework/component": "^0.16.4",
40
+ "@jay-framework/logger": "^0.16.4",
41
+ "@jay-framework/runtime": "^0.16.4",
42
+ "@jay-framework/secure": "^0.16.4",
43
43
  "@types/js-yaml": "^4.0.9",
44
44
  "change-case": "^4.1.2",
45
45
  "js-yaml": "^4.1.0",
@@ -51,8 +51,8 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@caiogondim/strip-margin": "^1.0.0",
54
- "@jay-framework/4-react": "^0.16.3",
55
- "@jay-framework/dev-environment": "^0.16.3",
54
+ "@jay-framework/4-react": "^0.16.4",
55
+ "@jay-framework/dev-environment": "^0.16.4",
56
56
  "@testing-library/jest-dom": "^6.2.0",
57
57
  "@types/js-beautify": "^1",
58
58
  "@types/node": "^20.11.5",