ripple 0.3.2 → 0.3.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 (128) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/package.json +2 -2
  3. package/src/compiler/identifier-utils.js +0 -2
  4. package/src/compiler/phases/1-parse/index.js +101 -195
  5. package/src/compiler/phases/2-analyze/index.js +82 -174
  6. package/src/compiler/phases/2-analyze/prune.js +2 -2
  7. package/src/compiler/phases/3-transform/client/index.js +174 -264
  8. package/src/compiler/phases/3-transform/segments.js +0 -22
  9. package/src/compiler/phases/3-transform/server/index.js +185 -42
  10. package/src/compiler/types/index.d.ts +14 -33
  11. package/src/compiler/utils.js +32 -20
  12. package/src/runtime/index-client.js +0 -17
  13. package/src/runtime/internal/client/bindings.js +118 -7
  14. package/src/runtime/internal/client/render.js +5 -1
  15. package/src/runtime/internal/client/runtime.js +1 -1
  16. package/src/runtime/internal/client/types.d.ts +4 -0
  17. package/tests/client/array/array.copy-within.test.ripple +7 -7
  18. package/tests/client/array/array.derived.test.ripple +24 -24
  19. package/tests/client/array/array.iteration.test.ripple +7 -7
  20. package/tests/client/array/array.mutations.test.ripple +17 -17
  21. package/tests/client/array/array.to-methods.test.ripple +4 -4
  22. package/tests/client/async-suspend.test.ripple +3 -3
  23. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  24. package/tests/client/basic/basic.collections.test.ripple +6 -6
  25. package/tests/client/basic/basic.components.test.ripple +8 -8
  26. package/tests/client/basic/basic.errors.test.ripple +31 -34
  27. package/tests/client/basic/basic.events.test.ripple +11 -11
  28. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  29. package/tests/client/basic/basic.reactivity.test.ripple +36 -36
  30. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  31. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  32. package/tests/client/boundaries.test.ripple +7 -7
  33. package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +24 -0
  34. package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
  35. package/tests/client/compiler/compiler.basic.test.ripple +58 -60
  36. package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
  37. package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
  38. package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
  39. package/tests/client/composite/composite.props.test.ripple +9 -9
  40. package/tests/client/composite/composite.reactivity.test.ripple +23 -23
  41. package/tests/client/composite/composite.render.test.ripple +52 -4
  42. package/tests/client/computed-properties.test.ripple +3 -3
  43. package/tests/client/context.test.ripple +3 -3
  44. package/tests/client/css/global-additional-cases.test.ripple +5 -2
  45. package/tests/client/css/style-identifier.test.ripple +40 -49
  46. package/tests/client/date.test.ripple +39 -39
  47. package/tests/client/dynamic-elements.test.ripple +37 -37
  48. package/tests/client/events.test.ripple +25 -25
  49. package/tests/client/for.test.ripple +8 -8
  50. package/tests/client/head.test.ripple +7 -7
  51. package/tests/client/html.test.ripple +2 -2
  52. package/tests/client/input-value.test.ripple +376 -177
  53. package/tests/client/lazy-destructuring.test.ripple +185 -0
  54. package/tests/client/map.test.ripple +20 -20
  55. package/tests/client/media-query.test.ripple +4 -4
  56. package/tests/client/object.test.ripple +5 -5
  57. package/tests/client/portal.test.ripple +4 -4
  58. package/tests/client/ref.test.ripple +3 -3
  59. package/tests/client/return.test.ripple +17 -17
  60. package/tests/client/set.test.ripple +10 -10
  61. package/tests/client/svg.test.ripple +6 -5
  62. package/tests/client/switch.test.ripple +10 -10
  63. package/tests/client/tracked-expression.test.ripple +3 -1
  64. package/tests/client/try.test.ripple +4 -4
  65. package/tests/client/url/url.derived.test.ripple +6 -7
  66. package/tests/client/url/url.parsing.test.ripple +9 -9
  67. package/tests/client/url/url.partial-removal.test.ripple +9 -9
  68. package/tests/client/url/url.reactivity.test.ripple +16 -16
  69. package/tests/client/url/url.serialization.test.ripple +3 -3
  70. package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
  71. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
  72. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
  73. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
  74. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
  75. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
  76. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
  77. package/tests/hydration/build-components.js +4 -10
  78. package/tests/hydration/compiled/client/basic.js +4 -4
  79. package/tests/hydration/compiled/client/events.js +2 -0
  80. package/tests/hydration/compiled/client/for.js +2 -0
  81. package/tests/hydration/compiled/client/head.js +13 -11
  82. package/tests/hydration/compiled/client/hmr.js +4 -2
  83. package/tests/hydration/compiled/client/html.js +82 -95
  84. package/tests/hydration/compiled/client/if-children.js +8 -9
  85. package/tests/hydration/compiled/client/if.js +2 -0
  86. package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
  87. package/tests/hydration/compiled/client/portal.js +1 -1
  88. package/tests/hydration/compiled/client/reactivity.js +2 -0
  89. package/tests/hydration/compiled/client/return.js +2 -0
  90. package/tests/hydration/compiled/client/switch.js +2 -0
  91. package/tests/hydration/compiled/server/composite.js +2 -2
  92. package/tests/hydration/compiled/server/events.js +2 -0
  93. package/tests/hydration/compiled/server/for.js +2 -0
  94. package/tests/hydration/compiled/server/head.js +13 -11
  95. package/tests/hydration/compiled/server/hmr.js +2 -0
  96. package/tests/hydration/compiled/server/html.js +2 -0
  97. package/tests/hydration/compiled/server/if-children.js +2 -0
  98. package/tests/hydration/compiled/server/if.js +2 -0
  99. package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
  100. package/tests/hydration/compiled/server/portal.js +1 -1
  101. package/tests/hydration/compiled/server/reactivity.js +2 -0
  102. package/tests/hydration/compiled/server/return.js +2 -0
  103. package/tests/hydration/compiled/server/switch.js +2 -0
  104. package/tests/hydration/components/composite.ripple +1 -1
  105. package/tests/hydration/components/events.ripple +10 -8
  106. package/tests/hydration/components/for.ripple +22 -20
  107. package/tests/hydration/components/head.ripple +8 -6
  108. package/tests/hydration/components/hmr.ripple +3 -1
  109. package/tests/hydration/components/html.ripple +3 -1
  110. package/tests/hydration/components/if-children.ripple +9 -7
  111. package/tests/hydration/components/if.ripple +7 -5
  112. package/tests/hydration/components/mixed-control-flow.ripple +5 -3
  113. package/tests/hydration/components/portal.ripple +2 -2
  114. package/tests/hydration/components/reactivity.ripple +11 -9
  115. package/tests/hydration/components/return.ripple +13 -11
  116. package/tests/hydration/components/switch.ripple +6 -4
  117. package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
  118. package/tests/server/await.test.ripple +2 -2
  119. package/tests/server/basic.attributes.test.ripple +21 -19
  120. package/tests/server/basic.components.test.ripple +5 -4
  121. package/tests/server/basic.test.ripple +21 -20
  122. package/tests/server/compiler.test.ripple +36 -5
  123. package/tests/server/composite.props.test.ripple +7 -6
  124. package/tests/server/context.test.ripple +3 -1
  125. package/tests/server/dynamic-elements.test.ripple +24 -24
  126. package/tests/server/head.test.ripple +7 -5
  127. package/tests/server/style-identifier.test.ripple +95 -16
  128. package/types/index.d.ts +4 -1
@@ -26,6 +26,8 @@ import {
26
26
  is_binding_function,
27
27
  is_element_dynamic,
28
28
  is_ripple_track_call,
29
+ is_ripple_import,
30
+ ripple_import_requires_block,
29
31
  hash,
30
32
  flatten_switch_consequent,
31
33
  get_ripple_namespace_call_name,
@@ -73,6 +75,23 @@ function build_return_guard(flags) {
73
75
  return condition;
74
76
  }
75
77
 
78
+ /**
79
+ * @param {AST.ClassDeclaration | AST.ClassExpression} node
80
+ * @param {TransformServerContext} context
81
+ * @returns {void}
82
+ */
83
+ function strip_class_typescript_syntax(node, context) {
84
+ delete node.typeParameters;
85
+ delete node.superTypeParameters;
86
+ delete node.implements;
87
+
88
+ if (node.superClass?.type === 'TSInstantiationExpression') {
89
+ node.superClass = /** @type {AST.Expression} */ (context.visit(node.superClass.expression));
90
+ } else if (node.superClass && 'typeArguments' in node.superClass) {
91
+ delete node.superClass.typeArguments;
92
+ }
93
+ }
94
+
76
95
  /**
77
96
  * Collects all unique return statements from the direct children of a body
78
97
  * @param {AST.Node[]} children
@@ -307,6 +326,27 @@ const visitors = {
307
326
  const parent = /** @type {AST.Node} */ (context.path.at(-1));
308
327
 
309
328
  if (is_reference(node, parent)) {
329
+ // Apply lazy destructuring binding transforms only
330
+ const binding = context.state.scope?.get(node.name);
331
+ if (
332
+ binding?.transform?.read &&
333
+ binding.node !== node &&
334
+ (binding.kind === 'lazy' || binding.kind === 'lazy_fallback')
335
+ ) {
336
+ const transformed = binding.transform.read(node);
337
+ if (node.tracked) {
338
+ const is_right_side_of_assignment =
339
+ parent.type === 'AssignmentExpression' && parent.right === node;
340
+ if (
341
+ (parent.type !== 'AssignmentExpression' && parent.type !== 'UpdateExpression') ||
342
+ is_right_side_of_assignment
343
+ ) {
344
+ return b.call('_$_.get', transformed);
345
+ }
346
+ }
347
+ return transformed;
348
+ }
349
+
310
350
  if (node.tracked) {
311
351
  const is_right_side_of_assignment =
312
352
  parent.type === 'AssignmentExpression' && parent.right === node;
@@ -323,13 +363,24 @@ const visitors = {
323
363
  },
324
364
 
325
365
  Component(node, context) {
366
+ let props_param_output;
367
+
326
368
  if (node.params.length > 0) {
327
369
  let props_param = node.params[0];
328
370
 
329
371
  if (props_param.type === 'Identifier') {
330
372
  delete props_param.typeAnnotation;
331
- } else if (props_param.type === 'ObjectPattern') {
373
+ props_param_output = props_param;
374
+ } else if (props_param.type === 'ObjectPattern' || props_param.type === 'ArrayPattern') {
332
375
  delete props_param.typeAnnotation;
376
+ if (props_param.lazy) {
377
+ // Lazy destructuring: use __props identifier, bindings resolved via transforms
378
+ props_param_output = b.id('__props');
379
+ } else {
380
+ props_param_output = props_param;
381
+ }
382
+ } else {
383
+ props_param_output = props_param;
333
384
  }
334
385
  }
335
386
 
@@ -378,7 +429,7 @@ const visitors = {
378
429
 
379
430
  let component_fn = b.function(
380
431
  node.id,
381
- node.params.length > 0 ? [b.id('__output'), node.params[0]] : [b.id('__output')],
432
+ node.params.length > 0 ? [b.id('__output'), props_param_output] : [b.id('__output')],
382
433
  b.block([
383
434
  ...(metadata.await
384
435
  ? [b.return(b.call('_$_.async', b.thunk(b.block(body_statements), true)))]
@@ -454,17 +505,19 @@ const visitors = {
454
505
  }
455
506
 
456
507
  const callee = node.callee;
457
- const source_name = callee.type === 'Identifier' ? callee.metadata?.source_name : undefined;
458
- const ripple_runtime_method = get_ripple_namespace_call_name(source_name);
459
508
 
460
- if (ripple_runtime_method !== null) {
461
- return {
462
- ...node,
463
- callee: b.member(b.id('_$_'), b.id(ripple_runtime_method)),
464
- arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ ([
465
- ...node.arguments.map((arg) => context.visit(arg)),
466
- ]),
467
- };
509
+ // Handle direct calls to ripple-imported functions: effect(), untrack(), RippleArray(), etc.
510
+ if (callee.type === 'Identifier' && is_ripple_import(callee, context)) {
511
+ const ripple_runtime_method = get_ripple_namespace_call_name(callee.name);
512
+ if (ripple_runtime_method !== null) {
513
+ return {
514
+ ...node,
515
+ callee: b.member(b.id('_$_'), b.id(ripple_runtime_method)),
516
+ arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ ([
517
+ ...node.arguments.map((arg) => context.visit(arg)),
518
+ ]),
519
+ };
520
+ }
468
521
  }
469
522
 
470
523
  if (is_ripple_track_call(callee, context)) {
@@ -488,18 +541,16 @@ const visitors = {
488
541
  };
489
542
  }
490
543
 
491
- // Check for more than two nested level calls, like #ripple.array.from()
544
+ // Handle member calls on ripple imports, like RippleArray.from()
492
545
  if (
493
546
  callee.type === 'MemberExpression' &&
494
- callee.object.metadata?.source_name?.startsWith('#ripple.') &&
495
547
  callee.object.type === 'Identifier' &&
496
- callee.property.type === 'Identifier'
548
+ callee.property.type === 'Identifier' &&
549
+ is_ripple_import(callee, context)
497
550
  ) {
498
551
  const object = callee.object;
499
552
  const property = callee.property;
500
- const source_name = /** @type {string} */ (object.metadata?.source_name);
501
-
502
- const method_name = get_ripple_namespace_call_name(source_name);
553
+ const method_name = get_ripple_namespace_call_name(object.name);
503
554
  if (method_name !== null) {
504
555
  return b.member(
505
556
  b.id('_$_'),
@@ -525,6 +576,20 @@ const visitors = {
525
576
  if (!context.state.to_ts) {
526
577
  delete node.typeArguments;
527
578
  }
579
+
580
+ // Transform `new RippleArray(...)`, `new RippleMap(...)`, etc. imported from 'ripple'
581
+ if (callee.type === 'Identifier' && is_ripple_import(callee, context)) {
582
+ const ripple_runtime_method = get_ripple_namespace_call_name(callee.name);
583
+ if (ripple_runtime_method !== null) {
584
+ return b.call(
585
+ '_$_.' + ripple_runtime_method,
586
+ .../** @type {(AST.Expression | AST.SpreadElement)[]} */ (
587
+ node.arguments.map((arg) => context.visit(arg))
588
+ ),
589
+ );
590
+ }
591
+ }
592
+
528
593
  return context.next();
529
594
  },
530
595
 
@@ -535,16 +600,44 @@ const visitors = {
535
600
  return context.next();
536
601
  },
537
602
 
603
+ ClassDeclaration(node, context) {
604
+ if (!context.state.to_ts) {
605
+ strip_class_typescript_syntax(node, context);
606
+ }
607
+ return context.next();
608
+ },
609
+
610
+ ClassExpression(node, context) {
611
+ if (!context.state.to_ts) {
612
+ strip_class_typescript_syntax(node, context);
613
+ }
614
+ return context.next();
615
+ },
616
+
538
617
  FunctionDeclaration(node, context) {
539
618
  if (!context.state.to_ts) {
540
619
  delete node.returnType;
541
620
  delete node.typeParameters;
542
- for (const param of node.params) {
621
+ for (let i = 0; i < node.params.length; i++) {
622
+ const param = node.params[i];
543
623
  delete param.typeAnnotation;
544
624
  // Handle AssignmentPattern (parameters with default values)
545
625
  if (param.type === 'AssignmentPattern' && param.left) {
546
626
  delete param.left.typeAnnotation;
547
627
  }
628
+ // Replace lazy destructuring params with generated identifiers
629
+ const pattern = param.type === 'AssignmentPattern' ? param.left : param;
630
+ if (
631
+ (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
632
+ pattern.lazy &&
633
+ pattern.metadata?.lazy_id
634
+ ) {
635
+ const id = b.id(pattern.metadata.lazy_id);
636
+ node.params[i] =
637
+ param.type === 'AssignmentPattern'
638
+ ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
639
+ : id;
640
+ }
548
641
  }
549
642
  }
550
643
  return context.next();
@@ -554,12 +647,26 @@ const visitors = {
554
647
  if (!context.state.to_ts) {
555
648
  delete node.returnType;
556
649
  delete node.typeParameters;
557
- for (const param of node.params) {
650
+ for (let i = 0; i < node.params.length; i++) {
651
+ const param = node.params[i];
558
652
  delete param.typeAnnotation;
559
653
  // Handle AssignmentPattern (parameters with default values)
560
654
  if (param.type === 'AssignmentPattern' && param.left) {
561
655
  delete param.left.typeAnnotation;
562
656
  }
657
+ // Replace lazy destructuring params with generated identifiers
658
+ const pattern = param.type === 'AssignmentPattern' ? param.left : param;
659
+ if (
660
+ (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
661
+ pattern.lazy &&
662
+ pattern.metadata?.lazy_id
663
+ ) {
664
+ const id = b.id(pattern.metadata.lazy_id);
665
+ node.params[i] =
666
+ param.type === 'AssignmentPattern'
667
+ ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
668
+ : id;
669
+ }
563
670
  }
564
671
  }
565
672
  return context.next();
@@ -579,12 +686,26 @@ const visitors = {
579
686
  ArrowFunctionExpression(node, context) {
580
687
  delete node.returnType;
581
688
  delete node.typeParameters;
582
- for (const param of node.params) {
689
+ for (let i = 0; i < node.params.length; i++) {
690
+ const param = node.params[i];
583
691
  delete param.typeAnnotation;
584
692
  // Handle AssignmentPattern (parameters with default values)
585
693
  if (param.type === 'AssignmentPattern' && param.left) {
586
694
  delete param.left.typeAnnotation;
587
695
  }
696
+ // Replace lazy destructuring params with generated identifiers
697
+ const pattern = param.type === 'AssignmentPattern' ? param.left : param;
698
+ if (
699
+ (pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
700
+ pattern.lazy &&
701
+ pattern.metadata?.lazy_id
702
+ ) {
703
+ const id = b.id(pattern.metadata.lazy_id);
704
+ node.params[i] =
705
+ param.type === 'AssignmentPattern'
706
+ ? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
707
+ : id;
708
+ }
588
709
  }
589
710
 
590
711
  return context.next();
@@ -726,6 +847,15 @@ const visitors = {
726
847
  for (const declarator of node.declarations) {
727
848
  if (!context.state.to_ts) {
728
849
  delete declarator.id.typeAnnotation;
850
+
851
+ // Replace lazy destructuring patterns with the generated identifier
852
+ if (
853
+ (declarator.id.type === 'ObjectPattern' || declarator.id.type === 'ArrayPattern') &&
854
+ declarator.id.lazy &&
855
+ declarator.id.metadata?.lazy_id
856
+ ) {
857
+ declarator.id = b.id(declarator.id.metadata.lazy_id);
858
+ }
729
859
  }
730
860
  }
731
861
 
@@ -984,10 +1114,7 @@ const visitors = {
984
1114
  /** @type {AST.Expression | null} */
985
1115
  let children_prop = null;
986
1116
 
987
- if (state.applyParentCssScope) {
988
- // We're inside a component, don't continue applying css hash to class
989
- state.applyParentCssScope = undefined;
990
- }
1117
+ const apply_parent_css_scope = state.applyParentCssScope;
991
1118
 
992
1119
  for (const attr of node.attributes) {
993
1120
  if (attr.type === 'Attribute') {
@@ -1051,6 +1178,14 @@ const visitors = {
1051
1178
  const children = /** @type {AST.Expression} */ (
1052
1179
  visit(b.component(b.id('children'), [], children_filtered), {
1053
1180
  ...context.state,
1181
+ ...(apply_parent_css_scope ||
1182
+ (is_element_dynamic(node) && node.metadata.scoped && state.component?.css)
1183
+ ? {
1184
+ applyParentCssScope:
1185
+ apply_parent_css_scope ||
1186
+ /** @type {AST.CSS.StyleSheet} */ (state.component?.css).hash,
1187
+ }
1188
+ : {}),
1054
1189
  scope: component_scope,
1055
1190
  namespace: child_namespace,
1056
1191
  })
@@ -1293,6 +1428,23 @@ const visitors = {
1293
1428
  AssignmentExpression(node, context) {
1294
1429
  const left = node.left;
1295
1430
 
1431
+ // Handle lazy binding assignments (e.g., a = 5 where a is from let &{a} = obj)
1432
+ if (left.type === 'Identifier') {
1433
+ const binding = context.state.scope?.get(left.name);
1434
+ if (binding?.transform?.assign && binding.node !== left) {
1435
+ let value = /** @type {AST.Expression} */ (context.visit(node.right));
1436
+
1437
+ // For compound operators (+=, -=, *=, /=), expand to read + operation
1438
+ if (node.operator !== '=') {
1439
+ const operator = node.operator.slice(0, -1); // '+=' -> '+'
1440
+ const current = binding.transform.read(left);
1441
+ value = b.binary(/** @type {AST.BinaryOperator} */ (operator), current, value);
1442
+ }
1443
+
1444
+ return binding.transform.assign(left, value);
1445
+ }
1446
+ }
1447
+
1296
1448
  if (
1297
1449
  left.type === 'MemberExpression' &&
1298
1450
  (left.tracked || (left.property.type === 'Identifier' && left.property.tracked))
@@ -1346,6 +1498,14 @@ const visitors = {
1346
1498
  UpdateExpression(node, context) {
1347
1499
  const argument = node.argument;
1348
1500
 
1501
+ // Handle lazy binding updates (e.g., a++ where a is from let &{a} = obj)
1502
+ if (argument.type === 'Identifier') {
1503
+ const binding = context.state.scope?.get(argument.name);
1504
+ if (binding?.transform?.update && binding.node !== argument) {
1505
+ return binding.transform.update(node);
1506
+ }
1507
+ }
1508
+
1349
1509
  if (
1350
1510
  argument.type === 'MemberExpression' &&
1351
1511
  (argument.tracked || (argument.property.type === 'Identifier' && argument.property.tracked))
@@ -1563,23 +1723,6 @@ const visitors = {
1563
1723
  return b.call('_$_.get', /** @type {AST.Expression} */ (context.visit(node.argument)));
1564
1724
  },
1565
1725
 
1566
- RippleObjectExpression(node, context) {
1567
- // For SSR, we just evaluate the object as-is since there's no reactivity
1568
- return b.object(
1569
- /** @type {(AST.Property | AST.SpreadElement)[]} */
1570
- (node.properties.map((prop) => context.visit(prop))),
1571
- );
1572
- },
1573
-
1574
- RippleArrayExpression(node, context) {
1575
- return b.call(
1576
- '_$_.ripple_array',
1577
- .../** @type {(AST.Expression | AST.SpreadElement)[]} */ (
1578
- node.elements.map((el) => context.visit(/** @type {AST.Node} */ (el)))
1579
- ),
1580
- );
1581
- },
1582
-
1583
1726
  MemberExpression(node, context) {
1584
1727
  if (
1585
1728
  node.tracked ||
@@ -13,25 +13,7 @@ interface BaseNodeMetaData {
13
13
  scoped?: boolean;
14
14
  path: AST.Node[];
15
15
  has_template?: boolean;
16
- source_name?:
17
- | string
18
- | '#ripple'
19
- | '#ripple.map'
20
- | '#ripple.set'
21
- | '#ripple.server'
22
- | '#ripple.style'
23
- | '#ripple.array'
24
- | '#ripple.object'
25
- | '#ripple.effect'
26
- | '#ripple.track'
27
- | '#ripple.trackSplit'
28
- | '#ripple.untrack'
29
- | '#ripple.url'
30
- | '#ripple.urlSearchParams'
31
- | '#ripple.date'
32
- | '#ripple.mediaQuery'
33
- | '#ripple.context'
34
- | '#ripple.validate';
16
+ source_name?: string | '#server' | '#style';
35
17
  is_capitalized?: boolean;
36
18
  has_await?: boolean;
37
19
  commentContainerId?: number;
@@ -43,6 +25,7 @@ interface BaseNodeMetaData {
43
25
  is_reactive?: boolean;
44
26
  lone_return?: boolean;
45
27
  forceMapping?: boolean;
28
+ lazy_id?: string;
46
29
  }
47
30
 
48
31
  interface FunctionMetaData extends BaseNodeMetaData {
@@ -103,13 +86,13 @@ declare module 'estree' {
103
86
 
104
87
  interface ClassDeclaration {
105
88
  typeParameters?: AST.TSTypeParameterDeclaration;
106
- superTypeArguments?: AST.TSTypeParameterInstantiation;
89
+ superTypeParameters?: AST.TSTypeParameterInstantiation;
107
90
  implements?: AST.TSClassImplements[];
108
91
  }
109
92
 
110
93
  interface ClassExpression {
111
94
  typeParameters?: AST.TSTypeParameterDeclaration;
112
- superTypeArguments?: AST.TSTypeParameterInstantiation;
95
+ superTypeParameters?: AST.TSTypeParameterInstantiation;
113
96
  implements?: AST.TSClassImplements[];
114
97
  }
115
98
 
@@ -123,6 +106,14 @@ declare module 'estree' {
123
106
  optional: boolean;
124
107
  }
125
108
 
109
+ // Lazy destructuring patterns (&{...} and &[...])
110
+ interface ObjectPattern {
111
+ lazy?: boolean;
112
+ }
113
+ interface ArrayPattern {
114
+ lazy?: boolean;
115
+ }
116
+
126
117
  // We mark the whole node as marked when member is @[expression]
127
118
  // Otherwise, we only mark Identifier nodes
128
119
  interface MemberExpression extends AST.TrackedNode {}
@@ -161,8 +152,6 @@ declare module 'estree' {
161
152
  }
162
153
 
163
154
  interface ExpressionMap {
164
- RippleArrayExpression: RippleArrayExpression;
165
- RippleObjectExpression: RippleObjectExpression;
166
155
  TrackedExpression: TrackedExpression;
167
156
  StyleIdentifier: StyleIdentifier;
168
157
  ServerIdentifier: ServerIdentifier;
@@ -359,21 +348,11 @@ declare module 'estree' {
359
348
  /**
360
349
  * Tracked Expressions
361
350
  */
362
- interface RippleArrayExpression extends Omit<AST.ArrayExpression, 'type'> {
363
- type: 'RippleArrayExpression';
364
- elements: (AST.Expression | AST.SpreadElement | null)[];
365
- }
366
-
367
351
  interface TrackedExpression extends AST.BaseExpression {
368
352
  argument: AST.Expression;
369
353
  type: 'TrackedExpression';
370
354
  }
371
355
 
372
- interface RippleObjectExpression extends Omit<AST.ObjectExpression, 'type'> {
373
- type: 'RippleObjectExpression';
374
- properties: (AST.Property | AST.SpreadElement)[];
375
- }
376
-
377
356
  /**
378
357
  * Ripple attribute nodes
379
358
  */
@@ -1136,6 +1115,8 @@ export type BindingKind =
1136
1115
  | 'rest_prop'
1137
1116
  | 'prop'
1138
1117
  | 'prop_fallback'
1118
+ | 'lazy'
1119
+ | 'lazy_fallback'
1139
1120
  | 'index';
1140
1121
 
1141
1122
  /**
@@ -164,18 +164,18 @@ const DOM_PROPERTIES = [
164
164
  ];
165
165
 
166
166
  /** @type {Record<string, string>} */
167
- const RIPPLE_NAMESPACE_CALL_NAME = {
168
- '#ripple.url': 'ripple_url',
169
- '#ripple.urlSearchParams': 'ripple_url_search_params',
170
- '#ripple.date': 'ripple_date',
171
- '#ripple.map': 'ripple_map',
172
- '#ripple.set': 'ripple_set',
173
- '#ripple.mediaQuery': 'media_query',
174
- '#ripple.context': 'context',
175
- '#ripple.effect': 'effect',
176
- '#ripple.untrack': 'untrack',
177
- '#ripple.array': 'ripple_array',
178
- '#ripple.object': 'ripple_object',
167
+ const RIPPLE_IMPORT_CALL_NAME = {
168
+ RippleURL: 'ripple_url',
169
+ RippleURLSearchParams: 'ripple_url_search_params',
170
+ RippleDate: 'ripple_date',
171
+ RippleMap: 'ripple_map',
172
+ RippleSet: 'ripple_set',
173
+ MediaQuery: 'media_query',
174
+ Context: 'context',
175
+ effect: 'effect',
176
+ untrack: 'untrack',
177
+ RippleArray: 'ripple_array',
178
+ RippleObject: 'ripple_object',
179
179
  };
180
180
 
181
181
  /**
@@ -298,14 +298,17 @@ export function is_ripple_track_call(callee, context) {
298
298
  // Super expressions cannot be Ripple track calls
299
299
  if (callee.type === 'Super') return false;
300
300
 
301
+ if (callee.type === 'Identifier' && (callee.name === 'track' || callee.name === 'trackSplit')) {
302
+ return is_ripple_import(callee, context);
303
+ }
304
+
301
305
  return (
302
- (callee.type === 'Identifier' && (callee.name === 'track' || callee.name === 'trackSplit')) ||
303
- (callee.type === 'MemberExpression' &&
304
- callee.object.type === 'Identifier' &&
305
- callee.property.type === 'Identifier' &&
306
- (callee.property.name === 'track' || callee.property.name === 'trackSplit') &&
307
- !callee.computed &&
308
- is_ripple_import(callee, context))
306
+ callee.type === 'MemberExpression' &&
307
+ callee.object.type === 'Identifier' &&
308
+ callee.property.type === 'Identifier' &&
309
+ (callee.property.name === 'track' || callee.property.name === 'trackSplit') &&
310
+ !callee.computed &&
311
+ is_ripple_import(callee, context)
309
312
  );
310
313
  }
311
314
 
@@ -936,5 +939,14 @@ export function flatten_switch_consequent(consequent) {
936
939
  * @returns {string | null}
937
940
  */
938
941
  export function get_ripple_namespace_call_name(name) {
939
- return name == null ? null : (RIPPLE_NAMESPACE_CALL_NAME[name] ?? null);
942
+ return name == null ? null : (RIPPLE_IMPORT_CALL_NAME[name] ?? null);
943
+ }
944
+
945
+ /**
946
+ * Returns true if the given import name requires a __block parameter
947
+ * @param {string} name
948
+ * @returns {boolean}
949
+ */
950
+ export function ripple_import_requires_block(name) {
951
+ return name !== 'effect' && name !== 'untrack' && name !== 'Context';
940
952
  }
@@ -172,20 +172,3 @@ import {
172
172
  ref_prop as createRefKey,
173
173
  } from './internal/client/runtime.js';
174
174
  import { user_effect as effect } from './internal/client/blocks.js';
175
-
176
- export const ripple_namespace = {
177
- map: RippleMap,
178
- set: RippleSet,
179
- array: RippleArray,
180
- object: RippleObject,
181
- context: Context,
182
- url: RippleURL,
183
- urlSearchParams: RippleURLSearchParams,
184
- date: RippleDate,
185
- mediaQuery: MediaQuery,
186
- createRefKey,
187
- track,
188
- trackSplit,
189
- effect,
190
- untrack,
191
- };