ripple 0.3.8 → 0.3.9

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 (37) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +2 -2
  3. package/src/compiler/phases/1-parse/index.js +13 -157
  4. package/src/compiler/phases/2-analyze/index.js +289 -43
  5. package/src/compiler/phases/3-transform/client/index.js +9 -157
  6. package/src/compiler/phases/3-transform/segments.js +0 -7
  7. package/src/compiler/phases/3-transform/server/index.js +15 -130
  8. package/src/compiler/types/acorn.d.ts +1 -1
  9. package/src/compiler/types/estree.d.ts +1 -1
  10. package/src/compiler/types/import.d.ts +0 -2
  11. package/src/compiler/types/index.d.ts +5 -17
  12. package/src/compiler/types/parse.d.ts +1 -9
  13. package/src/compiler/utils.js +53 -20
  14. package/src/runtime/index-client.js +2 -13
  15. package/src/runtime/index-server.js +2 -2
  16. package/src/runtime/internal/client/bindings.js +3 -1
  17. package/src/runtime/internal/client/composite.js +1 -0
  18. package/src/runtime/internal/client/events.js +1 -1
  19. package/src/runtime/internal/client/head.js +3 -4
  20. package/src/runtime/internal/client/index.js +0 -1
  21. package/src/runtime/internal/client/runtime.js +0 -52
  22. package/src/runtime/internal/server/index.js +31 -55
  23. package/tests/client/basic/basic.errors.test.ripple +28 -0
  24. package/tests/client/basic/basic.reactivity.test.ripple +10 -155
  25. package/tests/client/compiler/compiler.basic.test.ripple +31 -12
  26. package/tests/client/composite/composite.props.test.ripple +5 -7
  27. package/tests/client/composite/composite.reactivity.test.ripple +35 -36
  28. package/tests/client/dynamic-elements.test.ripple +3 -4
  29. package/tests/client/lazy-destructuring.test.ripple +69 -12
  30. package/tests/server/compiler.test.ripple +22 -0
  31. package/tests/server/composite.props.test.ripple +5 -7
  32. package/tests/server/dynamic-elements.test.ripple +3 -4
  33. package/tests/server/lazy-destructuring.test.ripple +68 -12
  34. package/tsconfig.typecheck.json +4 -0
  35. package/types/index.d.ts +0 -19
  36. package/tests/client/__snapshots__/tracked-expression.test.ripple.snap +0 -34
  37. package/tests/client/tracked-expression.test.ripple +0 -26
@@ -58,6 +58,7 @@ import {
58
58
  flatten_switch_consequent,
59
59
  get_ripple_namespace_call_name,
60
60
  is_ripple_import,
61
+ replace_lazy_param_pattern,
61
62
  ripple_import_requires_block,
62
63
  } from '../../../utils.js';
63
64
  import {
@@ -111,16 +112,12 @@ function visit_function(node, context) {
111
112
  // Replace lazy destructuring params with generated identifiers
112
113
  const transformed_params = node.params.map((param) => {
113
114
  const pattern = param.type === 'AssignmentPattern' ? param.left : param;
114
- if (
115
- (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
116
- pattern.lazy &&
117
- pattern.metadata?.lazy_id
118
- ) {
119
- const id = b.id(pattern.metadata.lazy_id);
115
+ if (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') {
116
+ const transformed_pattern = replace_lazy_param_pattern(pattern);
120
117
  if (param.type === 'AssignmentPattern') {
121
- return /** @type {AST.AssignmentPattern} */ ({ ...param, left: id });
118
+ return /** @type {AST.AssignmentPattern} */ ({ ...param, left: transformed_pattern });
122
119
  }
123
- return id;
120
+ return transformed_pattern;
124
121
  }
125
122
  return param;
126
123
  });
@@ -633,7 +630,7 @@ const visitors = {
633
630
 
634
631
  const matched_track_call = !context.state.to_ts ? is_ripple_track_call(callee, context) : null;
635
632
  if (matched_track_call) {
636
- const track_method_name = matched_track_call === 'trackSplit' ? 'track_split' : 'track';
633
+ const track_method_name = 'track';
637
634
 
638
635
  if (callee.type === 'Identifier' && callee.name === 'track') {
639
636
  if (node.arguments.length === 0) {
@@ -803,71 +800,11 @@ const visitors = {
803
800
  return b.call('_$_.with_scope', b.id('__block'), b.thunk(new_node));
804
801
  },
805
802
 
806
- TrackedExpression(node, context) {
807
- if (context.state.to_ts) {
808
- const visited = /** @type {AST.Expression} */ (context.visit(node.argument));
809
- const member = b.member(
810
- visited,
811
- b.literal('#v'),
812
- true,
813
- !is_inside_left_side_assignment(node),
814
- /** @type {AST.NodeWithLocation} */ (node),
815
- );
816
- member.tracked = true;
817
- return member;
818
- }
819
- return b.call('_$_.get', /** @type {AST.Expression} */ (context.visit(node.argument)));
820
- },
821
-
822
803
  MemberExpression(node, context) {
823
804
  if (context.state.metadata?.tracking === false) {
824
805
  context.state.metadata.tracking = true;
825
806
  }
826
807
 
827
- if (
828
- node.tracked ||
829
- ((node.property.type === 'Identifier' || node.property.type === 'Literal') &&
830
- node.property.tracked)
831
- ) {
832
- if (context.state.to_ts) {
833
- // In TypeScript mode, transform @user.@name or @user.@['name'] or @user?.@name
834
- // to user['#v'].name['#v'] or user['#v']['name']['#v'] or user['#v']?.name['#v']
835
- const visited_object = /** @type {AST.Expression} */ (context.visit(node.object));
836
- const visited_property = /** @type {AST.Expression} */ (context.visit(node.property));
837
-
838
- // Build the member access: object.property or object[property]
839
- const member = b.member(
840
- visited_object,
841
- visited_property,
842
- node.computed,
843
- node.optional,
844
- /** @type {AST.NodeWithLocation} */ (node),
845
- );
846
-
847
- // Wrap with ['#v'] access
848
- const member_expanded = b.member(
849
- member,
850
- b.literal('#v'),
851
- true,
852
- !is_inside_left_side_assignment(node),
853
- /** @type {AST.NodeWithLocation} */ (node),
854
- );
855
- member_expanded.tracked = true;
856
- return member_expanded;
857
- } else {
858
- if (!context.state.to_ts) {
859
- return b.call(
860
- '_$_.get_property',
861
- /** @type {AST.Expression} */ (context.visit(node.object)),
862
- node.computed
863
- ? /** @type {AST.Expression} */ (context.visit(node.property))
864
- : b.literal(/** @type {AST.Identifier} */ (node.property).name),
865
- node.optional ? b.true : undefined,
866
- );
867
- }
868
- }
869
- }
870
-
871
808
  if (node.object.type === 'MemberExpression' && node.object.optional) {
872
809
  const metadata = { tracking: false, await: false };
873
810
 
@@ -1986,7 +1923,9 @@ const visitors = {
1986
1923
  delete props_param.typeAnnotation;
1987
1924
  if (!props_param.lazy) {
1988
1925
  // Non-lazy destructuring: use the pattern directly as the function param
1989
- props = props_param;
1926
+ props = /** @type {AST.ObjectPattern | AST.ArrayPattern} */ (
1927
+ replace_lazy_param_pattern(props_param)
1928
+ );
1990
1929
  }
1991
1930
  // Lazy destructuring: props stays as __props, bindings resolved via transforms
1992
1931
  }
@@ -2059,56 +1998,6 @@ const visitors = {
2059
1998
  }
2060
1999
  }
2061
2000
 
2062
- if (
2063
- left.type === 'MemberExpression' &&
2064
- (left.tracked || (left.property.type === 'Identifier' && left.property.tracked))
2065
- ) {
2066
- const operator = node.operator;
2067
- const right = node.right;
2068
-
2069
- if (operator !== '=' && context.state.metadata?.tracking === false) {
2070
- context.state.metadata.tracking = true;
2071
- }
2072
-
2073
- return b.call(
2074
- '_$_.set_property',
2075
- /** @type {AST.Expression} */ (
2076
- context.visit(left.object, { ...context.state, metadata: { tracking: false } })
2077
- ),
2078
- left.computed
2079
- ? /** @type {AST.Expression} */ (context.visit(left.property))
2080
- : b.literal(/** @type {AST.Identifier} */ (left.property).name),
2081
- operator === '='
2082
- ? /** @type {AST.Expression} */ (context.visit(right))
2083
- : b.binary(
2084
- operator === '+=' ? '+' : operator === '-=' ? '-' : operator === '*=' ? '*' : '/',
2085
- /** @type {AST.Expression} */ (context.visit(left)),
2086
- /** @type {AST.Expression} */ (context.visit(right)),
2087
- ),
2088
- );
2089
- }
2090
-
2091
- if (left.type === 'Identifier' && left.tracked) {
2092
- const operator = node.operator;
2093
- const right = node.right;
2094
-
2095
- return b.call(
2096
- '_$_.set',
2097
- /** @type {AST.Expression} */ (
2098
- context.visit(left, { ...context.state, metadata: { tracking: null } })
2099
- ),
2100
- operator === '='
2101
- ? /** @type {AST.Expression} */ (context.visit(right))
2102
- : b.binary(
2103
- operator === '+=' ? '+' : operator === '-=' ? '-' : operator === '*=' ? '*' : '/',
2104
- /** @type {AST.Expression} */ (
2105
- context.visit(left, { ...context.state, metadata: { tracking: false } })
2106
- ),
2107
- /** @type {AST.Expression} */ (context.visit(right)),
2108
- ),
2109
- );
2110
- }
2111
-
2112
2001
  return visit_assignment_expression(node, context, build_assignment) ?? context.next();
2113
2002
  },
2114
2003
 
@@ -2126,43 +2015,6 @@ const visitors = {
2126
2015
  }
2127
2016
  }
2128
2017
 
2129
- if (
2130
- argument.type === 'MemberExpression' &&
2131
- (argument.tracked || (argument.property.type === 'Identifier' && argument.property.tracked))
2132
- ) {
2133
- if (context.state.metadata?.tracking === false) {
2134
- context.state.metadata.tracking = true;
2135
- }
2136
-
2137
- return b.call(
2138
- node.prefix ? '_$_.update_pre_property' : '_$_.update_property',
2139
- /** @type {AST.Expression} */
2140
- (context.visit(argument.object, { ...context.state, metadata: { tracking: false } })),
2141
- argument.computed
2142
- ? /** @type {AST.Expression} */ (context.visit(argument.property))
2143
- : b.literal(/** @type {AST.Identifier} */ (argument.property).name),
2144
- node.operator === '--' ? b.literal(-1) : undefined,
2145
- );
2146
- }
2147
-
2148
- if (argument.type === 'Identifier' && argument.tracked) {
2149
- return b.call(
2150
- node.prefix ? '_$_.update_pre' : '_$_.update',
2151
- /** @type {AST.Expression} */
2152
- (context.visit(argument, { ...context.state, metadata: { tracking: null } })),
2153
- node.operator === '--' ? b.literal(-1) : undefined,
2154
- );
2155
- }
2156
-
2157
- if (argument.type === 'TrackedExpression') {
2158
- return b.call(
2159
- node.prefix ? '_$_.update_pre' : '_$_.update',
2160
- /** @type {AST.Expression} */
2161
- (context.visit(argument.argument, { ...context.state, metadata: { tracking: null } })),
2162
- node.operator === '--' ? b.literal(-1) : undefined,
2163
- );
2164
- }
2165
-
2166
2018
  const left = object(/** @type {AST.MemberExpression | AST.Identifier} */ (argument));
2167
2019
  const binding = left && context.state.scope.get(left.name);
2168
2020
  const transformers = left && binding?.transform;
@@ -1123,13 +1123,6 @@ export function convert_source_map_to_mappings(
1123
1123
  mapping_data_verify_only,
1124
1124
  );
1125
1125
 
1126
- if (node.tracked) {
1127
- mapping.generatedLengths[0] = mapping.generatedLengths[0] + "['#v']".length;
1128
- if (node.optional) {
1129
- mapping.generatedLengths[0] = mapping.generatedLengths[0] + '.?'.length;
1130
- }
1131
- }
1132
-
1133
1126
  mappings.push(mapping);
1134
1127
  }
1135
1128
 
@@ -27,7 +27,7 @@ import {
27
27
  is_element_dynamic,
28
28
  is_ripple_track_call,
29
29
  is_ripple_import,
30
- ripple_import_requires_block,
30
+ replace_lazy_param_pattern,
31
31
  hash,
32
32
  flatten_switch_consequent,
33
33
  get_ripple_namespace_call_name,
@@ -355,7 +355,7 @@ const visitors = {
355
355
  // Lazy destructuring: use __props identifier, bindings resolved via transforms
356
356
  props_param_output = b.id('__props');
357
357
  } else {
358
- props_param_output = props_param;
358
+ props_param_output = replace_lazy_param_pattern(props_param);
359
359
  }
360
360
  } else {
361
361
  props_param_output = props_param;
@@ -500,7 +500,7 @@ const visitors = {
500
500
 
501
501
  const track_call_name = is_ripple_track_call(callee, context);
502
502
  if (track_call_name) {
503
- const track_method_name = track_call_name === 'trackSplit' ? 'track_split' : 'track';
503
+ const track_method_name = 'track';
504
504
 
505
505
  return {
506
506
  ...node,
@@ -597,16 +597,12 @@ const visitors = {
597
597
  }
598
598
  // Replace lazy destructuring params with generated identifiers
599
599
  const pattern = param.type === 'AssignmentPattern' ? param.left : param;
600
- if (
601
- (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
602
- pattern.lazy &&
603
- pattern.metadata?.lazy_id
604
- ) {
605
- const id = b.id(pattern.metadata.lazy_id);
600
+ if (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') {
601
+ const transformed_pattern = replace_lazy_param_pattern(pattern);
606
602
  node.params[i] =
607
603
  param.type === 'AssignmentPattern'
608
- ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
609
- : id;
604
+ ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: transformed_pattern })
605
+ : transformed_pattern;
610
606
  }
611
607
  }
612
608
  }
@@ -626,16 +622,12 @@ const visitors = {
626
622
  }
627
623
  // Replace lazy destructuring params with generated identifiers
628
624
  const pattern = param.type === 'AssignmentPattern' ? param.left : param;
629
- if (
630
- (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
631
- pattern.lazy &&
632
- pattern.metadata?.lazy_id
633
- ) {
634
- const id = b.id(pattern.metadata.lazy_id);
625
+ if (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') {
626
+ const transformed_pattern = replace_lazy_param_pattern(pattern);
635
627
  node.params[i] =
636
628
  param.type === 'AssignmentPattern'
637
- ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
638
- : id;
629
+ ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: transformed_pattern })
630
+ : transformed_pattern;
639
631
  }
640
632
  }
641
633
  }
@@ -665,16 +657,12 @@ const visitors = {
665
657
  }
666
658
  // Replace lazy destructuring params with generated identifiers
667
659
  const pattern = param.type === 'AssignmentPattern' ? param.left : param;
668
- if (
669
- (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
670
- pattern.lazy &&
671
- pattern.metadata?.lazy_id
672
- ) {
673
- const id = b.id(pattern.metadata.lazy_id);
660
+ if (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') {
661
+ const transformed_pattern = replace_lazy_param_pattern(pattern);
674
662
  node.params[i] =
675
663
  param.type === 'AssignmentPattern'
676
- ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
677
- : id;
664
+ ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: transformed_pattern })
665
+ : transformed_pattern;
678
666
  }
679
667
  }
680
668
 
@@ -1429,53 +1417,6 @@ const visitors = {
1429
1417
  }
1430
1418
  }
1431
1419
 
1432
- if (
1433
- left.type === 'MemberExpression' &&
1434
- (left.tracked || (left.property.type === 'Identifier' && left.property.tracked))
1435
- ) {
1436
- const operator = node.operator;
1437
- const right = node.right;
1438
-
1439
- return b.call(
1440
- '_$_.set_property',
1441
- /** @type {AST.Expression} */ (context.visit(left.object)),
1442
- left.computed
1443
- ? /** @type {AST.Expression} */ (context.visit(left.property))
1444
- : b.literal(/** @type {AST.Identifier} */ (left.property).name),
1445
- operator === '='
1446
- ? /** @type {AST.Expression} */ (context.visit(right))
1447
- : b.binary(
1448
- operator === '+=' ? '+' : operator === '-=' ? '-' : operator === '*=' ? '*' : '/',
1449
- b.call(
1450
- '_$_.get_property',
1451
- /** @type {AST.Expression} */ (context.visit(left.object)),
1452
- left.computed
1453
- ? /** @type {AST.Expression} */ (context.visit(left.property))
1454
- : b.literal(/** @type {AST.Identifier} */ (left.property).name),
1455
- undefined,
1456
- ),
1457
- /** @type {AST.Expression} */ (context.visit(right)),
1458
- ),
1459
- );
1460
- }
1461
-
1462
- if (left.type === 'Identifier' && left.tracked) {
1463
- const operator = node.operator;
1464
- const right = node.right;
1465
-
1466
- return b.call(
1467
- '_$_.set',
1468
- /** @type {AST.Expression} */ (context.visit(left)),
1469
- operator === '='
1470
- ? /** @type {AST.Expression} */ (context.visit(right))
1471
- : b.binary(
1472
- operator === '+=' ? '+' : operator === '-=' ? '-' : operator === '*=' ? '*' : '/',
1473
- b.call('_$_.get', left),
1474
- /** @type {AST.Expression} */ (context.visit(right)),
1475
- ),
1476
- );
1477
- }
1478
-
1479
1420
  return context.next();
1480
1421
  },
1481
1422
 
@@ -1489,39 +1430,6 @@ const visitors = {
1489
1430
  return binding.transform.update(node);
1490
1431
  }
1491
1432
  }
1492
-
1493
- if (
1494
- argument.type === 'MemberExpression' &&
1495
- (argument.tracked || (argument.property.type === 'Identifier' && argument.property.tracked))
1496
- ) {
1497
- return b.call(
1498
- node.prefix ? '_$_.update_pre_property' : '_$_.update_property',
1499
- /** @type {AST.Expression} */
1500
- (context.visit(argument.object, { ...context.state, metadata: { tracking: false } })),
1501
- argument.computed
1502
- ? /** @type {AST.Expression} */ (context.visit(argument.property))
1503
- : b.literal(/** @type {AST.Identifier} */ (argument.property).name),
1504
- node.operator === '--' ? b.literal(-1) : undefined,
1505
- );
1506
- }
1507
-
1508
- if (argument.type === 'Identifier' && argument.tracked) {
1509
- return b.call(
1510
- node.prefix ? '_$_.update_pre' : '_$_.update',
1511
- /** @type {AST.Expression} */
1512
- (context.visit(argument)),
1513
- node.operator === '--' ? b.literal(-1) : undefined,
1514
- );
1515
- }
1516
-
1517
- if (argument.type === 'TrackedExpression') {
1518
- return b.call(
1519
- node.prefix ? '_$_.update_pre' : '_$_.update',
1520
- /** @type {AST.Expression} */
1521
- (context.visit(argument.argument)),
1522
- node.operator === '--' ? b.literal(-1) : undefined,
1523
- );
1524
- }
1525
1433
  },
1526
1434
 
1527
1435
  ServerIdentifier(node, context) {
@@ -1703,26 +1611,7 @@ const visitors = {
1703
1611
  return b.await(/** @type {AST.AwaitExpression} */ (context.visit(node.argument)));
1704
1612
  },
1705
1613
 
1706
- TrackedExpression(node, context) {
1707
- return b.call('_$_.get', /** @type {AST.Expression} */ (context.visit(node.argument)));
1708
- },
1709
-
1710
1614
  MemberExpression(node, context) {
1711
- if (
1712
- node.tracked ||
1713
- ((node.property.type === 'Identifier' || node.property.type === 'Literal') &&
1714
- node.property.tracked)
1715
- ) {
1716
- return b.call(
1717
- '_$_.get_property',
1718
- /** @type {AST.Expression} */ (context.visit(node.object)),
1719
- node.computed
1720
- ? /** @type {AST.Expression} */ (context.visit(node.property))
1721
- : b.literal(/** @type {AST.Identifier} */ (node.property).name),
1722
- node.optional ? b.true : undefined,
1723
- );
1724
- }
1725
-
1726
1615
  return context.next();
1727
1616
  },
1728
1617
 
@@ -1730,10 +1619,6 @@ const visitors = {
1730
1619
  const metadata = { await: false };
1731
1620
  let expression = /** @type {AST.Expression} */ (visit(node.expression, { ...state, metadata }));
1732
1621
 
1733
- if (expression.type === 'Identifier' && expression.tracked) {
1734
- expression = b.call('_$_.get', expression);
1735
- }
1736
-
1737
1622
  if (expression.type === 'Literal') {
1738
1623
  state.init?.push(
1739
1624
  b.stmt(
@@ -6,6 +6,6 @@
6
6
  //
7
7
  // The relative import of './parser' loads the augmentation declarations
8
8
  // (declare module 'acorn' { ... }) so the re-exported types include
9
- // Ripple-specific nodes like Component, Element, TrackedExpression, etc.
9
+ // Ripple-specific nodes like Component, Element, etc.
10
10
  import './parser.d.ts';
11
11
  export * from 'acorn';
@@ -6,6 +6,6 @@
6
6
  //
7
7
  // The relative import of './index' loads the augmentation declarations
8
8
  // (declare module 'estree' { ... }) so the re-exported types include
9
- // Ripple-specific nodes like Component, Element, TrackedExpression, etc.
9
+ // Ripple-specific nodes like Component, Element, etc.
10
10
  import './index';
11
11
  export * from 'estree';
@@ -41,7 +41,6 @@ import {
41
41
  MediaQuery as _$_MediaQuery__,
42
42
  createRefKey as _$_RefKey__create,
43
43
  track as _$_track__,
44
- trackSplit as _$_trackSplit__,
45
44
  effect as _$_effect__,
46
45
  untrack as _$_untrack__,
47
46
  ripple_namespace as _$__u0023_ripple,
@@ -59,7 +58,6 @@ export {
59
58
  _$_MediaQuery__,
60
59
  _$_RefKey__create,
61
60
  _$_track__,
62
- _$_trackSplit__,
63
61
  _$_effect__,
64
62
  _$_untrack__,
65
63
  _$__u0023_ripple,
@@ -116,19 +116,17 @@ declare module 'estree' {
116
116
 
117
117
  // We mark the whole node as marked when member is @[expression]
118
118
  // Otherwise, we only mark Identifier nodes
119
- interface MemberExpression extends AST.TrackedNode {}
119
+ interface MemberExpression {}
120
120
 
121
- // These 3 are needed so that Literal can extend TrackedNode
122
- // since Literal is a union type we have to extend each individually
123
- interface SimpleLiteral extends AST.LiteralTrackedNode {}
124
- interface RegExpLiteral extends AST.LiteralTrackedNode {}
125
- interface BigIntLiteral extends AST.LiteralTrackedNode {}
121
+ interface SimpleLiteral extends AST.LiteralNode {}
122
+ interface RegExpLiteral extends AST.LiteralNode {}
123
+ interface BigIntLiteral extends AST.LiteralNode {}
126
124
 
127
125
  interface TrackedNode {
128
126
  tracked?: boolean;
129
127
  }
130
128
 
131
- interface LiteralTrackedNode extends AST.TrackedNode {
129
+ interface LiteralNode {
132
130
  was_expression?: boolean;
133
131
  }
134
132
 
@@ -143,7 +141,6 @@ declare module 'estree' {
143
141
  ServerBlockStatement: ServerBlockStatement;
144
142
  ServerIdentifier: ServerIdentifier;
145
143
  StyleIdentifier: StyleIdentifier;
146
- TrackedExpression: TrackedExpression;
147
144
  Attribute: Attribute;
148
145
  RefAttribute: RefAttribute;
149
146
  SpreadAttribute: SpreadAttribute;
@@ -152,7 +149,6 @@ declare module 'estree' {
152
149
  }
153
150
 
154
151
  interface ExpressionMap {
155
- TrackedExpression: TrackedExpression;
156
152
  StyleIdentifier: StyleIdentifier;
157
153
  ServerIdentifier: ServerIdentifier;
158
154
  Text: TextNode;
@@ -345,14 +341,6 @@ declare module 'estree' {
345
341
  content: string;
346
342
  }
347
343
 
348
- /**
349
- * Tracked Expressions
350
- */
351
- interface TrackedExpression extends AST.BaseExpression {
352
- argument: AST.Expression;
353
- type: 'TrackedExpression';
354
- }
355
-
356
344
  /**
357
345
  * Ripple attribute nodes
358
346
  */
@@ -924,13 +924,7 @@ export namespace Parse {
924
924
  refDestructuringErrors?: DestructuringErrors,
925
925
  forInit?: ForInit,
926
926
  forNew?: boolean,
927
- ):
928
- | AST.ServerIdentifier
929
- | AST.StyleIdentifier
930
- | AST.TrackedExpression
931
- | AST.Component
932
- | AST.Identifier
933
- | AST.Literal;
927
+ ): AST.ServerIdentifier | AST.StyleIdentifier | AST.Component | AST.Identifier | AST.Literal;
934
928
 
935
929
  /** Default handler for parseExprAtom when no other case matches */
936
930
  parseExprAtomDefault(): AST.Expression;
@@ -950,8 +944,6 @@ export namespace Parse {
950
944
  /** Parse parenthesized expression (just the expression) */
951
945
  parseParenExpression(): AST.Expression;
952
946
 
953
- parseTrackedExpression(): AST.TrackedExpression;
954
-
955
947
  /**
956
948
  * Parse item in parentheses (can be overridden for flow/ts)
957
949
  */
@@ -292,25 +292,25 @@ export function is_component_level_function(context) {
292
292
  * Returns the matched Ripple tracking call name
293
293
  * @param {AST.Expression | AST.Super} callee
294
294
  * @param {CommonContext} context
295
- * @returns {'track' | 'trackSplit' | null}
295
+ * @returns {'track' | null}
296
296
  */
297
297
  export function is_ripple_track_call(callee, context) {
298
298
  // Super expressions cannot be Ripple track calls
299
299
  if (callee.type === 'Super') return null;
300
300
 
301
- if (callee.type === 'Identifier' && (callee.name === 'track' || callee.name === 'trackSplit')) {
302
- return is_ripple_import(callee, context) ? callee.name : null;
301
+ if (callee.type === 'Identifier' && callee.name === 'track') {
302
+ return is_ripple_import(callee, context) ? 'track' : null;
303
303
  }
304
304
 
305
305
  if (
306
306
  callee.type === 'MemberExpression' &&
307
307
  callee.object.type === 'Identifier' &&
308
308
  callee.property.type === 'Identifier' &&
309
- (callee.property.name === 'track' || callee.property.name === 'trackSplit') &&
309
+ callee.property.name === 'track' &&
310
310
  !callee.computed &&
311
311
  is_ripple_import(callee, context)
312
312
  ) {
313
- return callee.property.name;
313
+ return 'track';
314
314
  }
315
315
 
316
316
  return null;
@@ -606,21 +606,8 @@ export function is_element_dynamic(node) {
606
606
  * @returns {boolean}
607
607
  */
608
608
  function is_id_dynamic(node) {
609
- if (node.type === 'Identifier' || node.type === 'Literal') {
610
- if (node.tracked) {
611
- return true;
612
- }
613
-
614
- return false;
615
- } else if (node.type === 'MemberExpression') {
616
- if (/** @type {AST.Identifier} */ (node.object).tracked === true) {
617
- return true;
618
- }
619
- if (node.property.type === 'MemberExpression') {
620
- return is_id_dynamic(node.property);
621
- }
622
-
623
- return !!(/** @type {AST.Identifier} */ (node.property).tracked);
609
+ if (node.type === 'Identifier') {
610
+ return !!node.tracked;
624
611
  }
625
612
 
626
613
  return false;
@@ -686,6 +673,52 @@ function normalize_child(node, normalized, context) {
686
673
  }
687
674
  }
688
675
 
676
+ /**
677
+ * Replaces any lazy subpatterns in a parameter pattern with their generated identifiers.
678
+ * This is used by client and server transforms so nested lazy destructuring can coexist
679
+ * with otherwise normal object/array params.
680
+ * @param {AST.Pattern} pattern
681
+ * @returns {AST.Pattern}
682
+ */
683
+ export function replace_lazy_param_pattern(pattern) {
684
+ switch (pattern.type) {
685
+ case 'AssignmentPattern':
686
+ return { ...pattern, left: replace_lazy_param_pattern(pattern.left) };
687
+
688
+ case 'ObjectPattern':
689
+ if (pattern.lazy && pattern.metadata?.lazy_id) {
690
+ return /** @type {AST.Pattern} */ (b.id(pattern.metadata.lazy_id));
691
+ }
692
+
693
+ return {
694
+ ...pattern,
695
+ properties: pattern.properties.map((property) =>
696
+ property.type === 'RestElement'
697
+ ? { ...property, argument: replace_lazy_param_pattern(property.argument) }
698
+ : { ...property, value: replace_lazy_param_pattern(property.value) },
699
+ ),
700
+ };
701
+
702
+ case 'ArrayPattern':
703
+ if (pattern.lazy && pattern.metadata?.lazy_id) {
704
+ return /** @type {AST.Pattern} */ (b.id(pattern.metadata.lazy_id));
705
+ }
706
+
707
+ return {
708
+ ...pattern,
709
+ elements: pattern.elements.map((element) =>
710
+ element === null ? null : replace_lazy_param_pattern(element),
711
+ ),
712
+ };
713
+
714
+ case 'RestElement':
715
+ return { ...pattern, argument: replace_lazy_param_pattern(pattern.argument) };
716
+
717
+ default:
718
+ return pattern;
719
+ }
720
+ }
721
+
689
722
  /**
690
723
  * @param {CommonContext} context
691
724
  */