marko 5.39.30 → 5.39.32

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.
@@ -178,7 +178,7 @@ exports.p = function (domCompat) {
178
178
  );
179
179
  }
180
180
  host = rootNode.startNode;
181
- domCompat.setScopeNodes(host, rootNode.startNode, rootNode.endNode);
181
+ domCompat.setScopeNodes(scope, rootNode.startNode, rootNode.endNode);
182
182
  }
183
183
  const existingComponent = scope.bs_;
184
184
  const componentsContext = T_(out);
@@ -39,38 +39,45 @@ exports.p = function (htmlCompat) {
39
39
  const { classAPI, tagsAPI } = writers;
40
40
  let scripts = "";
41
41
  let componentDefs = flushDefs;
42
+ let chunk;
42
43
 
43
44
  if (classAPI.length) {
44
45
  componentDefs = flushDefs ? flushDefs.concat(classAPI) : classAPI;
45
46
  writers.classAPI = [];
46
47
  }
47
48
 
49
+ if (tagsAPI.length) {
50
+ chunk = tagsAPI[0];
51
+ for (let i = 1; i < tagsAPI.length; i++) {
52
+ chunk.append(tagsAPI[i]);
53
+ }
54
+ writers.tagsAPI = [];
55
+ }
56
+
48
57
  if (componentDefs?.length) {
49
- scripts = _h_($global, componentDefs);
58
+ // Serializing a bridged handler registers a tags scope, so it needs a chunk:
59
+ // this flush's, else the one rendering, else a new one for a direct render.
60
+ const live = chunk || htmlCompat.getChunk();
61
+ const target = live || htmlCompat.createChunk($global);
62
+ scripts = htmlCompat.withChunk(target, () =>
63
+ _h_($global, componentDefs)
64
+ );
50
65
  if (scripts) {
51
66
  htmlCompat.ensureState($global).walkOnNextFlush = true;
52
67
 
53
- if (!tagsAPI.length) {
54
- scripts = concatScripts(htmlCompat.flushScript($global), scripts);
68
+ if (!chunk) {
69
+ scripts = concatScripts(
70
+ live ?
71
+ htmlCompat.flushScript($global) :
72
+ htmlCompat.flushScript($global, target),
73
+ scripts
74
+ );
55
75
  }
56
76
  }
57
77
  }
58
78
 
59
- if (tagsAPI.length) {
60
- const [chunk] = tagsAPI;
61
- for (let i = 1; i < tagsAPI.length; i++) {
62
- chunk.append(tagsAPI[i]);
63
- }
64
-
65
- chunk.boundary.flush();
66
- if (chunk.boundary.count) {
67
- throw new Error(
68
- "Cannot serialize promise across tags/class compat layer."
69
- );
70
- }
71
-
72
- scripts = concatScripts(chunk.flushScript().scripts, scripts);
73
- writers.tagsAPI = [];
79
+ if (chunk) {
80
+ scripts = concatScripts(htmlCompat.flushScript($global, chunk), scripts);
74
81
  }
75
82
 
76
83
  return scripts;
@@ -93,9 +100,8 @@ exports.p = function (htmlCompat) {
93
100
 
94
101
  return (input, out) => {
95
102
  if (!tagsRenderer && renderBody) {
96
- renderBody.toJSON = htmlCompat.toJSON(
97
- htmlCompat.ensureState(out.global)
98
- );
103
+ htmlCompat.ensureState(out.global);
104
+ renderBody.toJSON = htmlCompat.toJSON();
99
105
  }
100
106
  TagsCompat(
101
107
  args ?
@@ -128,6 +134,7 @@ exports.p = function (htmlCompat) {
128
134
  const tagsRenderer = _.r;
129
135
  const willRerender = componentDef._wrr || htmlCompat.isInResumedBranch();
130
136
  out.bf("1", component, willRerender);
137
+ htmlCompat.registerClassFunctions(input);
131
138
  // A split parent won't re-feed the child a live handler at hydration, so
132
139
  // register the child scope to let the resolver revive a bridged marker.
133
140
  htmlCompat.render(
@@ -173,7 +180,7 @@ exports.p = function (htmlCompat) {
173
180
  return (input, ...args) => {
174
181
  // tags to class
175
182
  const $global = htmlCompat.$global();
176
- const state = htmlCompat.ensureState($global);
183
+ htmlCompat.ensureState($global);
177
184
  const out = defaultCreateOut($global);
178
185
  const branchId = htmlCompat.nextScopeId();
179
186
  let forceBoundary = boundaryModeByRenderer.get(tag);
@@ -192,7 +199,7 @@ exports.p = function (htmlCompat) {
192
199
  value]
193
200
  );
194
201
  forceBoundary = true;
195
- value.toJSON = htmlCompat.toJSON(state);
202
+ value.toJSON = htmlCompat.toJSON();
196
203
  } else {
197
204
  input[key === "content" ? "renderBody" : key] = value;
198
205
  }
@@ -22,6 +22,26 @@ function analyzeLoadImport(importDecl, tagEntry) {
22
22
 
23
23
  if (!loadAttrPath) return;
24
24
 
25
+ const loadImport = getLoadImportConfig(loadAttrPath.get("value"));
26
+
27
+ if ((importDecl.node.importKind || "value") !== "value") {
28
+ throw importDecl.buildCodeFrameError("Invalid load import.");
29
+ }
30
+
31
+ for (const specifier of importDecl.get("specifiers")) {
32
+ if (!_compiler.types.isImportDefaultSpecifier(specifier.node)) {
33
+ throw specifier.buildCodeFrameError(
34
+ "Invalid load import, only a default specifier is allowed."
35
+ );
36
+ }
37
+ }
38
+
39
+ if (!importDecl.node.specifiers.some(_compiler.types.isImportDefaultSpecifier)) {
40
+ throw importDecl.buildCodeFrameError(
41
+ "Invalid load import, a default specifier is required."
42
+ );
43
+ }
44
+
25
45
  // Under hot reload every module is already eagerly loaded, so the lazy facade
26
46
  // buys nothing and its HMR-cached template collides with the real template's
27
47
  // `_` slot, recursing on render (see load-tag-browser.js). Without `linkAssets`
@@ -33,28 +53,13 @@ function analyzeLoadImport(importDecl, tagEntry) {
33
53
  return;
34
54
  }
35
55
 
36
- const loadAttrValuePath = loadAttrPath.get("value");
37
-
38
56
  if (!tagEntry) {
39
57
  throw importDecl.buildCodeFrameError(
40
58
  "Unable to resolve marko file for load import."
41
59
  );
42
60
  }
43
61
 
44
- if ((importDecl.node.importKind || "value") !== "value") {
45
- throw importDecl.buildCodeFrameError("Invalid load import.");
46
- }
47
-
48
- for (const specifier of importDecl.get("specifiers")) {
49
- if (!_compiler.types.isImportDefaultSpecifier(specifier.node)) {
50
- throw specifier.buildCodeFrameError(
51
- "Invalid load import, only a default specifier is allowed."
52
- );
53
- }
54
- }
55
-
56
- (importDecl.node.extra ??= {}).loadImport =
57
- getLoadImportConfig(loadAttrValuePath);
62
+ (importDecl.node.extra ??= {}).loadImport = loadImport;
58
63
  }
59
64
 
60
65
  function translateLoadTag(path, tagName, relativePath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "5.39.30",
3
+ "version": "5.39.32",
4
4
  "private": false,
5
5
  "description": "UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.",
6
6
  "keywords": [
@@ -67,8 +67,8 @@
67
67
  },
68
68
  "types": "index.d.ts",
69
69
  "dependencies": {
70
- "@marko/compiler": "^5.41.10",
71
- "@marko/runtime-tags": "^6.3.26",
70
+ "@marko/compiler": "^5.41.18",
71
+ "@marko/runtime-tags": "^6.3.34",
72
72
  "app-module-path": "^2.2.0",
73
73
  "argly": "^1.2.0",
74
74
  "browser-refresh-client": "1.1.4",
@@ -85,7 +85,7 @@
85
85
  "warp10": "^2.1.0"
86
86
  },
87
87
  "devDependencies": {
88
- "marko": "5.39.30"
88
+ "marko": "5.39.32"
89
89
  },
90
90
  "engines": {
91
91
  "node": ">=22"
@@ -178,7 +178,7 @@ exports.p = function (domCompat) {
178
178
  );
179
179
  }
180
180
  host = rootNode.startNode;
181
- domCompat.setScopeNodes(host, rootNode.startNode, rootNode.endNode);
181
+ domCompat.setScopeNodes(scope, rootNode.startNode, rootNode.endNode);
182
182
  }
183
183
  const existingComponent = scope.___marko5Component;
184
184
  const componentsContext = ___getComponentsContext(out);
@@ -39,38 +39,45 @@ exports.p = function (htmlCompat) {
39
39
  const { classAPI, tagsAPI } = writers;
40
40
  let scripts = "";
41
41
  let componentDefs = flushDefs;
42
+ let chunk;
42
43
 
43
44
  if (classAPI.length) {
44
45
  componentDefs = flushDefs ? flushDefs.concat(classAPI) : classAPI;
45
46
  writers.classAPI = [];
46
47
  }
47
48
 
49
+ if (tagsAPI.length) {
50
+ chunk = tagsAPI[0];
51
+ for (let i = 1; i < tagsAPI.length; i++) {
52
+ chunk.append(tagsAPI[i]);
53
+ }
54
+ writers.tagsAPI = [];
55
+ }
56
+
48
57
  if (componentDefs?.length) {
49
- scripts = ___getInitComponentsCodeForDefs($global, componentDefs);
58
+ // Serializing a bridged handler registers a tags scope, so it needs a chunk:
59
+ // this flush's, else the one rendering, else a new one for a direct render.
60
+ const live = chunk || htmlCompat.getChunk();
61
+ const target = live || htmlCompat.createChunk($global);
62
+ scripts = htmlCompat.withChunk(target, () =>
63
+ ___getInitComponentsCodeForDefs($global, componentDefs),
64
+ );
50
65
  if (scripts) {
51
66
  htmlCompat.ensureState($global).walkOnNextFlush = true;
52
67
 
53
- if (!tagsAPI.length) {
54
- scripts = concatScripts(htmlCompat.flushScript($global), scripts);
68
+ if (!chunk) {
69
+ scripts = concatScripts(
70
+ live
71
+ ? htmlCompat.flushScript($global)
72
+ : htmlCompat.flushScript($global, target),
73
+ scripts,
74
+ );
55
75
  }
56
76
  }
57
77
  }
58
78
 
59
- if (tagsAPI.length) {
60
- const [chunk] = tagsAPI;
61
- for (let i = 1; i < tagsAPI.length; i++) {
62
- chunk.append(tagsAPI[i]);
63
- }
64
-
65
- chunk.boundary.flush();
66
- if (chunk.boundary.count) {
67
- throw new Error(
68
- "Cannot serialize promise across tags/class compat layer.",
69
- );
70
- }
71
-
72
- scripts = concatScripts(chunk.flushScript().scripts, scripts);
73
- writers.tagsAPI = [];
79
+ if (chunk) {
80
+ scripts = concatScripts(htmlCompat.flushScript($global, chunk), scripts);
74
81
  }
75
82
 
76
83
  return scripts;
@@ -93,9 +100,8 @@ exports.p = function (htmlCompat) {
93
100
 
94
101
  return (input, out) => {
95
102
  if (!tagsRenderer && renderBody) {
96
- renderBody.toJSON = htmlCompat.toJSON(
97
- htmlCompat.ensureState(out.global),
98
- );
103
+ htmlCompat.ensureState(out.global);
104
+ renderBody.toJSON = htmlCompat.toJSON();
99
105
  }
100
106
  TagsCompat(
101
107
  args
@@ -128,6 +134,7 @@ exports.p = function (htmlCompat) {
128
134
  const tagsRenderer = _.r;
129
135
  const willRerender = componentDef._wrr || htmlCompat.isInResumedBranch();
130
136
  out.bf("1", component, willRerender);
137
+ htmlCompat.registerClassFunctions(input);
131
138
  // A split parent won't re-feed the child a live handler at hydration, so
132
139
  // register the child scope to let the resolver revive a bridged marker.
133
140
  htmlCompat.render(
@@ -173,7 +180,7 @@ exports.p = function (htmlCompat) {
173
180
  return (input, ...args) => {
174
181
  // tags to class
175
182
  const $global = htmlCompat.$global();
176
- const state = htmlCompat.ensureState($global);
183
+ htmlCompat.ensureState($global);
177
184
  const out = defaultCreateOut($global);
178
185
  const branchId = htmlCompat.nextScopeId();
179
186
  let forceBoundary = boundaryModeByRenderer.get(tag);
@@ -192,7 +199,7 @@ exports.p = function (htmlCompat) {
192
199
  value,
193
200
  ]);
194
201
  forceBoundary = true;
195
- value.toJSON = htmlCompat.toJSON(state);
202
+ value.toJSON = htmlCompat.toJSON();
196
203
  } else {
197
204
  input[key === "content" ? "renderBody" : key] = value;
198
205
  }
@@ -22,6 +22,26 @@ export function analyzeLoadImport(importDecl, tagEntry) {
22
22
 
23
23
  if (!loadAttrPath) return;
24
24
 
25
+ const loadImport = getLoadImportConfig(loadAttrPath.get("value"));
26
+
27
+ if ((importDecl.node.importKind || "value") !== "value") {
28
+ throw importDecl.buildCodeFrameError("Invalid load import.");
29
+ }
30
+
31
+ for (const specifier of importDecl.get("specifiers")) {
32
+ if (!t.isImportDefaultSpecifier(specifier.node)) {
33
+ throw specifier.buildCodeFrameError(
34
+ "Invalid load import, only a default specifier is allowed.",
35
+ );
36
+ }
37
+ }
38
+
39
+ if (!importDecl.node.specifiers.some(t.isImportDefaultSpecifier)) {
40
+ throw importDecl.buildCodeFrameError(
41
+ "Invalid load import, a default specifier is required.",
42
+ );
43
+ }
44
+
25
45
  // Under hot reload every module is already eagerly loaded, so the lazy facade
26
46
  // buys nothing and its HMR-cached template collides with the real template's
27
47
  // `_` slot, recursing on render (see load-tag-browser.js). Without `linkAssets`
@@ -33,28 +53,13 @@ export function analyzeLoadImport(importDecl, tagEntry) {
33
53
  return;
34
54
  }
35
55
 
36
- const loadAttrValuePath = loadAttrPath.get("value");
37
-
38
56
  if (!tagEntry) {
39
57
  throw importDecl.buildCodeFrameError(
40
58
  "Unable to resolve marko file for load import.",
41
59
  );
42
60
  }
43
61
 
44
- if ((importDecl.node.importKind || "value") !== "value") {
45
- throw importDecl.buildCodeFrameError("Invalid load import.");
46
- }
47
-
48
- for (const specifier of importDecl.get("specifiers")) {
49
- if (!t.isImportDefaultSpecifier(specifier.node)) {
50
- throw specifier.buildCodeFrameError(
51
- "Invalid load import, only a default specifier is allowed.",
52
- );
53
- }
54
- }
55
-
56
- (importDecl.node.extra ??= {}).loadImport =
57
- getLoadImportConfig(loadAttrValuePath);
62
+ (importDecl.node.extra ??= {}).loadImport = loadImport;
58
63
  }
59
64
 
60
65
  export function translateLoadTag(path, tagName, relativePath) {