@tsrx/core 0.0.25 → 0.0.26

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Core compiler infrastructure for TSRX syntax",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.0.25",
6
+ "version": "0.0.26",
7
7
  "type": "module",
8
8
  "repository": {
9
9
  "type": "git",
@@ -624,6 +624,10 @@ function build_render_statements(body_nodes, return_null_when_empty, transform_c
624
624
  // any JSX is constructed, and every JSX child would observe the final
625
625
  // state of mutable variables.
626
626
  const interleaved = is_interleaved_body(body_nodes);
627
+ const capture_static_early_return_nodes =
628
+ !interleaved &&
629
+ !transform_context.platform.hooks?.isTopLevelSetupCall &&
630
+ body_nodes.filter(is_returning_if_statement).length > 1;
627
631
  let capture_index = 0;
628
632
 
629
633
  for (let i = 0; i < body_nodes.length; i += 1) {
@@ -648,6 +652,15 @@ function build_render_statements(body_nodes, return_null_when_empty, transform_c
648
652
  true,
649
653
  );
650
654
 
655
+ if (capture_static_early_return_nodes) {
656
+ capture_index = capture_static_early_return_render_nodes(
657
+ render_nodes,
658
+ statements,
659
+ capture_index,
660
+ transform_context,
661
+ );
662
+ }
663
+
651
664
  if (branch_has_hooks || continuation_has_hooks) {
652
665
  if (transform_context.platform.hooks?.isTopLevelSetupCall) {
653
666
  statements.push(
@@ -1325,6 +1338,59 @@ function hoist_static_render_nodes(render_nodes, transform_context) {
1325
1338
  }
1326
1339
  }
1327
1340
 
1341
+ /**
1342
+ * Static JSX that appears before multiple early-return guards is otherwise
1343
+ * cloned into every generated return. Capture it once at its source position
1344
+ * and reuse the reference, matching the interleaved-statement capture path
1345
+ * without moving dynamic render-time expressions across guards.
1346
+ *
1347
+ * @param {any[]} render_nodes
1348
+ * @param {any[]} statements
1349
+ * @param {number} capture_index
1350
+ * @param {TransformContext} transform_context
1351
+ * @returns {number}
1352
+ */
1353
+ function capture_static_early_return_render_nodes(
1354
+ render_nodes,
1355
+ statements,
1356
+ capture_index,
1357
+ transform_context,
1358
+ ) {
1359
+ for (let i = 0; i < render_nodes.length; i += 1) {
1360
+ const node = render_nodes[i];
1361
+ if (!is_static_early_return_capture_node(node, transform_context)) {
1362
+ continue;
1363
+ }
1364
+
1365
+ const { declaration, reference } = captureJsxChild(node, capture_index++);
1366
+ statements.push(declaration);
1367
+ render_nodes[i] = reference;
1368
+ }
1369
+
1370
+ return capture_index;
1371
+ }
1372
+
1373
+ /**
1374
+ * @param {any} node
1375
+ * @param {TransformContext} transform_context
1376
+ * @returns {boolean}
1377
+ */
1378
+ function is_static_early_return_capture_node(node, transform_context) {
1379
+ if (node?.type !== 'JSXElement' && node?.type !== 'JSXFragment') {
1380
+ return false;
1381
+ }
1382
+ if (!is_hoist_safe_jsx_node(node)) {
1383
+ return false;
1384
+ }
1385
+ if (
1386
+ transform_context.platform.hooks?.canHoistStaticNode &&
1387
+ !transform_context.platform.hooks.canHoistStaticNode(node, transform_context)
1388
+ ) {
1389
+ return false;
1390
+ }
1391
+ return !references_scope_bindings(node, transform_context.available_bindings);
1392
+ }
1393
+
1328
1394
  /**
1329
1395
  * @param {AST.Program} program
1330
1396
  * @returns {AST.Program}