ripple 0.2.216 → 0.3.1

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 (155) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/package.json +16 -7
  3. package/src/compiler/errors.js +1 -1
  4. package/src/compiler/identifier-utils.js +2 -0
  5. package/src/compiler/index.d.ts +2 -6
  6. package/src/compiler/phases/1-parse/index.js +171 -233
  7. package/src/compiler/phases/2-analyze/index.js +192 -16
  8. package/src/compiler/phases/2-analyze/prune.js +2 -2
  9. package/src/compiler/phases/3-transform/client/index.js +308 -91
  10. package/src/compiler/phases/3-transform/segments.js +43 -15
  11. package/src/compiler/phases/3-transform/server/index.js +71 -21
  12. package/src/compiler/scope.js +31 -12
  13. package/src/compiler/source-map-utils.js +4 -6
  14. package/src/compiler/types/acorn.d.ts +11 -0
  15. package/src/compiler/types/estree-jsx.d.ts +11 -0
  16. package/src/compiler/types/estree.d.ts +11 -0
  17. package/src/compiler/types/import.d.ts +32 -18
  18. package/src/compiler/types/index.d.ts +75 -23
  19. package/src/compiler/types/parse.d.ts +7 -10
  20. package/src/compiler/utils.js +48 -0
  21. package/src/runtime/array.js +53 -22
  22. package/src/runtime/date.js +15 -5
  23. package/src/runtime/index-client.js +41 -7
  24. package/src/runtime/index-server.js +7 -7
  25. package/src/runtime/internal/client/bindings.js +2 -2
  26. package/src/runtime/internal/client/blocks.js +40 -1
  27. package/src/runtime/internal/client/context.js +8 -0
  28. package/src/runtime/internal/client/for.js +3 -3
  29. package/src/runtime/internal/client/index.js +27 -5
  30. package/src/runtime/internal/client/render.js +20 -8
  31. package/src/runtime/internal/client/runtime.js +9 -7
  32. package/src/runtime/internal/client/try.js +15 -22
  33. package/src/runtime/internal/client/utils.js +1 -1
  34. package/src/runtime/internal/server/context.js +8 -0
  35. package/src/runtime/internal/server/index.js +99 -6
  36. package/src/runtime/map.js +7 -7
  37. package/src/runtime/media-query.js +10 -1
  38. package/src/runtime/object.js +6 -6
  39. package/src/runtime/proxy.js +6 -6
  40. package/src/runtime/set.js +11 -11
  41. package/src/runtime/url-search-params.js +13 -2
  42. package/src/runtime/url.js +15 -5
  43. package/src/utils/builders.js +13 -3
  44. package/tests/client/array/array.copy-within.test.ripple +11 -11
  45. package/tests/client/array/array.derived.test.ripple +42 -42
  46. package/tests/client/array/array.iteration.test.ripple +12 -12
  47. package/tests/client/array/array.mutations.test.ripple +25 -25
  48. package/tests/client/array/array.static.test.ripple +103 -106
  49. package/tests/client/array/array.to-methods.test.ripple +8 -8
  50. package/tests/client/async-suspend.test.ripple +94 -0
  51. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  52. package/tests/client/basic/basic.collections.test.ripple +7 -7
  53. package/tests/client/basic/basic.components.test.ripple +48 -10
  54. package/tests/client/basic/basic.errors.test.ripple +46 -31
  55. package/tests/client/basic/basic.events.test.ripple +11 -11
  56. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  57. package/tests/client/basic/basic.reactivity.test.ripple +47 -42
  58. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  59. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  60. package/tests/client/boundaries.test.ripple +7 -7
  61. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +2 -2
  62. package/tests/client/compiler/compiler.assignments.test.ripple +21 -21
  63. package/tests/client/compiler/compiler.basic.test.ripple +223 -82
  64. package/tests/client/compiler/compiler.tracked-access.test.ripple +8 -9
  65. package/tests/client/composite/composite.dynamic-components.test.ripple +8 -8
  66. package/tests/client/composite/composite.generics.test.ripple +4 -4
  67. package/tests/client/composite/composite.props.test.ripple +9 -9
  68. package/tests/client/composite/composite.reactivity.test.ripple +32 -26
  69. package/tests/client/composite/composite.render.test.ripple +13 -4
  70. package/tests/client/computed-properties.test.ripple +3 -3
  71. package/tests/client/context.test.ripple +3 -3
  72. package/tests/client/css/global-additional-cases.test.ripple +4 -4
  73. package/tests/client/css/style-identifier.test.ripple +49 -41
  74. package/tests/client/date.test.ripple +40 -40
  75. package/tests/client/dynamic-elements.test.ripple +165 -30
  76. package/tests/client/events.test.ripple +25 -25
  77. package/tests/client/for.test.ripple +76 -8
  78. package/tests/client/function-overload.test.ripple +0 -1
  79. package/tests/client/head.test.ripple +7 -7
  80. package/tests/client/html.test.ripple +2 -2
  81. package/tests/client/input-value.test.ripple +174 -176
  82. package/tests/client/map.test.ripple +21 -21
  83. package/tests/client/media-query.test.ripple +4 -4
  84. package/tests/client/object.test.ripple +12 -12
  85. package/tests/client/portal.test.ripple +4 -4
  86. package/tests/client/ref.test.ripple +5 -5
  87. package/tests/client/return.test.ripple +17 -17
  88. package/tests/client/set.test.ripple +16 -16
  89. package/tests/client/svg.test.ripple +6 -7
  90. package/tests/client/switch.test.ripple +10 -10
  91. package/tests/client/tracked-expression.test.ripple +1 -3
  92. package/tests/client/try.test.ripple +33 -4
  93. package/tests/client/url/url.derived.test.ripple +10 -9
  94. package/tests/client/url/url.parsing.test.ripple +10 -10
  95. package/tests/client/url/url.partial-removal.test.ripple +10 -10
  96. package/tests/client/url/url.reactivity.test.ripple +17 -17
  97. package/tests/client/url/url.serialization.test.ripple +4 -4
  98. package/tests/client/url-search-params/url-search-params.derived.test.ripple +11 -10
  99. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +5 -7
  100. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +13 -13
  101. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +19 -19
  102. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +17 -17
  103. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +5 -5
  104. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +5 -5
  105. package/tests/hydration/compiled/client/events.js +8 -11
  106. package/tests/hydration/compiled/client/for.js +20 -23
  107. package/tests/hydration/compiled/client/head.js +17 -19
  108. package/tests/hydration/compiled/client/hmr.js +1 -3
  109. package/tests/hydration/compiled/client/html.js +1 -15
  110. package/tests/hydration/compiled/client/if-children.js +7 -9
  111. package/tests/hydration/compiled/client/if.js +5 -7
  112. package/tests/hydration/compiled/client/mixed-control-flow.js +3 -5
  113. package/tests/hydration/compiled/client/portal.js +1 -1
  114. package/tests/hydration/compiled/client/reactivity.js +9 -11
  115. package/tests/hydration/compiled/client/return.js +11 -13
  116. package/tests/hydration/compiled/client/switch.js +4 -6
  117. package/tests/hydration/compiled/server/basic.js +0 -1
  118. package/tests/hydration/compiled/server/composite.js +0 -3
  119. package/tests/hydration/compiled/server/events.js +8 -12
  120. package/tests/hydration/compiled/server/for.js +20 -23
  121. package/tests/hydration/compiled/server/head.js +17 -19
  122. package/tests/hydration/compiled/server/hmr.js +1 -4
  123. package/tests/hydration/compiled/server/html.js +1 -35
  124. package/tests/hydration/compiled/server/if-children.js +7 -11
  125. package/tests/hydration/compiled/server/if.js +5 -7
  126. package/tests/hydration/compiled/server/mixed-control-flow.js +3 -5
  127. package/tests/hydration/compiled/server/portal.js +1 -9
  128. package/tests/hydration/compiled/server/reactivity.js +9 -11
  129. package/tests/hydration/compiled/server/return.js +11 -13
  130. package/tests/hydration/compiled/server/switch.js +4 -6
  131. package/tests/hydration/components/events.ripple +8 -9
  132. package/tests/hydration/components/for.ripple +20 -21
  133. package/tests/hydration/components/head.ripple +6 -8
  134. package/tests/hydration/components/hmr.ripple +1 -2
  135. package/tests/hydration/components/html.ripple +1 -3
  136. package/tests/hydration/components/if-children.ripple +7 -8
  137. package/tests/hydration/components/if.ripple +5 -6
  138. package/tests/hydration/components/mixed-control-flow.ripple +4 -6
  139. package/tests/hydration/components/portal.ripple +1 -1
  140. package/tests/hydration/components/reactivity.ripple +9 -10
  141. package/tests/hydration/components/return.ripple +11 -12
  142. package/tests/hydration/components/switch.ripple +6 -8
  143. package/tests/server/await.test.ripple +2 -2
  144. package/tests/server/basic.attributes.test.ripple +19 -21
  145. package/tests/server/basic.components.test.ripple +13 -7
  146. package/tests/server/basic.test.ripple +20 -21
  147. package/tests/server/compiler.test.ripple +5 -5
  148. package/tests/server/composite.props.test.ripple +6 -7
  149. package/tests/server/composite.test.ripple +4 -4
  150. package/tests/server/context.test.ripple +1 -3
  151. package/tests/server/dynamic-elements.test.ripple +24 -24
  152. package/tests/server/head.test.ripple +5 -7
  153. package/tests/server/style-identifier.test.ripple +16 -17
  154. package/types/index.d.ts +266 -62
  155. package/types/server.d.ts +6 -6
@@ -413,7 +413,7 @@ export function convert_source_map_to_mappings(
413
413
  if (node.name && node.loc) {
414
414
  /** @type {Token} */
415
415
  let token;
416
- // Check if this identifier was changed in metadata (e.g., #Map -> TrackedMap)
416
+ // Check if this identifier was changed in metadata (e.g., #Map -> RippleMap)
417
417
  // Or if it was capitalized during transformation
418
418
  if (node.metadata?.source_name) {
419
419
  token = {
@@ -422,6 +422,22 @@ export function convert_source_map_to_mappings(
422
422
  loc: node.loc,
423
423
  metadata: {},
424
424
  };
425
+
426
+ if (node.metadata.source_name === '#ripple') {
427
+ // Suppress the private-identifier parse diagnostic while the user is
428
+ // still typing a namespace access like `#ripple.` for completions.
429
+ token.metadata.suppressedDiagnostics = [18016];
430
+ }
431
+
432
+ if (
433
+ node.metadata.source_name === '#ripple.server' ||
434
+ node.metadata.source_name === '#ripple.style'
435
+ ) {
436
+ // Let TextMate own the coloring for these namespace forms.
437
+ // Their dedicated AST nodes otherwise cause semantic tokens to repaint
438
+ // the full '#ripple.server' / '#ripple.style' span after TS attaches.
439
+ token.mappingData = { ...mapping_data, semantic: false };
440
+ }
425
441
  } else {
426
442
  token = {
427
443
  source: node.name,
@@ -429,9 +445,10 @@ export function convert_source_map_to_mappings(
429
445
  loc: node.loc,
430
446
  metadata: {},
431
447
  };
432
- if (node.name === '#') {
433
- // Suppress 'Invalid character' to allow typing out the shorthands
434
- token.metadata.suppressedDiagnostics = [1127];
448
+ if (node.name === '#ripple') {
449
+ // Suppress the private-identifier parse diagnostic while the user is
450
+ // still typing a namespace access like `#ripple.` for completions.
451
+ token.metadata.suppressedDiagnostics = [18016];
435
452
  }
436
453
  // No transformation - source and generated names are the same
437
454
  }
@@ -618,7 +635,6 @@ export function convert_source_map_to_mappings(
618
635
  data: {
619
636
  ...mapping_data,
620
637
  customData: {
621
- generatedLengths: [length],
622
638
  hover:
623
639
  '```css\n.' +
624
640
  name +
@@ -639,6 +655,26 @@ export function convert_source_map_to_mappings(
639
655
  if (node.name) {
640
656
  visit(node.name);
641
657
  }
658
+
659
+ if (
660
+ node.name.type === 'JSXIdentifier' &&
661
+ node.name.metadata?.is_component &&
662
+ node.name.loc
663
+ ) {
664
+ const mapping = get_mapping_from_node(
665
+ node.name,
666
+ src_to_gen_map,
667
+ gen_line_offsets,
668
+ mapping_data,
669
+ );
670
+ mapping.sourceOffsets = [
671
+ /** @type {AST.NodeWithLocation} */ (node.name).start - 'component '.length,
672
+ ];
673
+ mapping.lengths = ['component'.length];
674
+
675
+ mapping.data.customData.hover = replace_label_to_component;
676
+ mappings.push(mapping);
677
+ }
642
678
  if (node.value) {
643
679
  visit(node.value);
644
680
  }
@@ -728,7 +764,6 @@ export function convert_source_map_to_mappings(
728
764
  // but since we already map the opening - start, we just need the proper end
729
765
  // and it was causing some issues with mappings
730
766
  mapping.generatedLengths = [mapping.generatedLengths[0] + 1];
731
- mapping.data.customData.generatedLengths = mapping.generatedLengths;
732
767
  mappings.push(mapping);
733
768
  }
734
769
 
@@ -1115,7 +1150,6 @@ export function convert_source_map_to_mappings(
1115
1150
  if (node.optional) {
1116
1151
  mapping.generatedLengths[0] = mapping.generatedLengths[0] + '.?'.length;
1117
1152
  }
1118
- mapping.data.customData.generatedLengths = mapping.generatedLengths;
1119
1153
  }
1120
1154
 
1121
1155
  mappings.push(mapping);
@@ -1280,7 +1314,6 @@ export function convert_source_map_to_mappings(
1280
1314
  const return_keyword_length = 'return'.length;
1281
1315
  mapping.lengths = [return_keyword_length];
1282
1316
  mapping.generatedLengths = [return_keyword_length];
1283
- mapping.data.customData.generatedLengths = mapping.generatedLengths;
1284
1317
 
1285
1318
  mappings.push(mapping);
1286
1319
  }
@@ -2015,9 +2048,7 @@ export function convert_source_map_to_mappings(
2015
2048
  const gen_start = loc_to_offset(gen_line_col.line, gen_line_col.column, gen_line_offsets);
2016
2049
 
2017
2050
  /** @type {CustomMappingData} */
2018
- const customData = {
2019
- generatedLengths: [gen_length],
2020
- };
2051
+ const customData = {};
2021
2052
 
2022
2053
  // Add optional metadata from token if present
2023
2054
  if ('wordHighlight' in token.metadata) {
@@ -2087,9 +2118,7 @@ export function convert_source_map_to_mappings(
2087
2118
  generatedLengths: [1],
2088
2119
  data: {
2089
2120
  ...mapping_data,
2090
- customData: {
2091
- generatedLengths: [1],
2092
- },
2121
+ customData: {},
2093
2122
  },
2094
2123
  });
2095
2124
  }
@@ -2106,7 +2135,6 @@ export function convert_source_map_to_mappings(
2106
2135
  data: {
2107
2136
  ...mapping_data,
2108
2137
  customData: {
2109
- generatedLengths: [region.content.length],
2110
2138
  embeddedId: region.id,
2111
2139
  content: region.content,
2112
2140
  },
@@ -25,8 +25,10 @@ import {
25
25
  normalize_children,
26
26
  is_binding_function,
27
27
  is_element_dynamic,
28
+ is_ripple_track_call,
28
29
  hash,
29
30
  flatten_switch_consequent,
31
+ get_ripple_namespace_call_name,
30
32
  } from '../../../utils.js';
31
33
  import { escape } from '../../../../utils/escaping.js';
32
34
  import { is_event_attribute } from '../../../../utils/events.js';
@@ -450,25 +452,75 @@ const visitors = {
450
452
  if (!context.state.to_ts) {
451
453
  delete node.typeArguments;
452
454
  }
455
+
456
+ 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
+
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
+ };
468
+ }
469
+
470
+ if (is_ripple_track_call(callee, context)) {
471
+ const track_method_name =
472
+ callee.type === 'Identifier'
473
+ ? callee.name === 'trackSplit'
474
+ ? 'track_split'
475
+ : 'track'
476
+ : callee.type === 'MemberExpression' && callee.property.type === 'Identifier'
477
+ ? callee.property.name === 'trackSplit'
478
+ ? 'track_split'
479
+ : 'track'
480
+ : 'track';
481
+
482
+ return {
483
+ ...node,
484
+ callee: b.member(b.id('_$_'), b.id(track_method_name)),
485
+ arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ (
486
+ node.arguments.map((arg) => context.visit(arg))
487
+ ),
488
+ };
489
+ }
490
+
491
+ // Check for more than two nested level calls, like #ripple.array.from()
492
+ if (
493
+ callee.type === 'MemberExpression' &&
494
+ callee.object.metadata?.source_name?.startsWith('#ripple.') &&
495
+ callee.object.type === 'Identifier' &&
496
+ callee.property.type === 'Identifier'
497
+ ) {
498
+ const object = callee.object;
499
+ 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);
503
+ if (method_name !== null) {
504
+ return b.member(
505
+ b.id('_$_'),
506
+ b.member(
507
+ b.id(method_name),
508
+ b.call(
509
+ b.id(property.name),
510
+ .../** @type {(AST.Expression | AST.SpreadElement)[]} */ (
511
+ node.arguments.map((arg) => context.visit(arg))
512
+ ),
513
+ ),
514
+ ),
515
+ );
516
+ }
517
+ }
518
+
453
519
  return context.next();
454
520
  },
455
521
 
456
522
  NewExpression(node, context) {
457
- // Special handling for TrackedMapExpression and TrackedSetExpression
458
- // When source is "new #Map(...)", the callee is TrackedMapExpression with empty arguments
459
- // and the actual arguments are in NewExpression.arguments
460
523
  const callee = node.callee;
461
- if (callee.type === 'TrackedMapExpression' || callee.type === 'TrackedSetExpression') {
462
- // Use NewExpression's arguments (the callee has empty arguments from parser)
463
- const argsToUse = node.arguments.length > 0 ? node.arguments : callee.arguments;
464
- // For SSR, use regular Map/Set
465
- const constructorName = callee.type === 'TrackedMapExpression' ? 'Map' : 'Set';
466
- return b.new(
467
- b.id(constructorName),
468
- undefined,
469
- .../** @type {AST.Expression[]} */ (argsToUse.map((arg) => context.visit(arg))),
470
- );
471
- }
472
524
 
473
525
  if (!context.state.to_ts) {
474
526
  delete node.typeArguments;
@@ -1511,7 +1563,7 @@ const visitors = {
1511
1563
  return b.call('_$_.get', /** @type {AST.Expression} */ (context.visit(node.argument)));
1512
1564
  },
1513
1565
 
1514
- TrackedObjectExpression(node, context) {
1566
+ RippleObjectExpression(node, context) {
1515
1567
  // For SSR, we just evaluate the object as-is since there's no reactivity
1516
1568
  return b.object(
1517
1569
  /** @type {(AST.Property | AST.SpreadElement)[]} */
@@ -1519,12 +1571,10 @@ const visitors = {
1519
1571
  );
1520
1572
  },
1521
1573
 
1522
- TrackedArrayExpression(node, context) {
1523
- // For SSR, we just evaluate the array as-is since there's no reactivity
1524
- return b.array(
1525
- /** @type {(AST.Expression | AST.SpreadElement)[]} */
1526
- (
1527
- /** @param {AST.Node} el */
1574
+ RippleArrayExpression(node, context) {
1575
+ return b.call(
1576
+ '_$_.ripple_array',
1577
+ .../** @type {(AST.Expression | AST.SpreadElement)[]} */ (
1528
1578
  node.elements.map((el) => context.visit(/** @type {AST.Node} */ (el)))
1529
1579
  ),
1530
1580
  );
@@ -3,7 +3,9 @@
3
3
  Binding,
4
4
  ScopeInterface,
5
5
  ScopeRoot as ScopeRootInterface,
6
- Context
6
+ Context,
7
+ ScopeConstructorInterface,
8
+ ScopeConstructorParameters
7
9
  } from '#compiler';
8
10
  @import * as AST from 'estree';
9
11
  */
@@ -12,6 +14,8 @@ import is_reference from 'is-reference';
12
14
  import { extract_identifiers, object, unwrap_pattern } from '../utils/ast.js';
13
15
  import { walk } from 'zimmerframe';
14
16
  import { is_reserved } from './utils.js';
17
+ import { error } from './errors.js';
18
+ import { IDENTIFIER_OBFUSCATION_PREFIX } from './identifier-utils.js';
15
19
  import * as b from '../utils/builders.js';
16
20
 
17
21
  /**
@@ -19,14 +23,15 @@ import * as b from '../utils/builders.js';
19
23
  * @param {AST.Node} ast - The AST to create scopes for
20
24
  * @param {ScopeRootInterface} root - Root scope manager
21
25
  * @param {ScopeInterface | null} parent - Parent scope
26
+ * @param {ScopeConstructorInterface['error_options']} error_options - Error options
22
27
  * @returns {{ scope: ScopeInterface, scopes: Map<AST.Node, ScopeInterface> }} Scope information
23
28
  */
24
- export function create_scopes(ast, root, parent) {
29
+ export function create_scopes(ast, root, parent, error_options) {
25
30
  /** @typedef {{ scope: ScopeInterface }} State */
26
31
 
27
32
  /** @type {Map<AST.Node, ScopeInterface>} */
28
33
  const scopes = new Map();
29
- const scope = new Scope(root, parent, false);
34
+ const scope = new Scope(root, parent, false, error_options);
30
35
  scopes.set(ast, scope);
31
36
 
32
37
  /** @type {State} */
@@ -296,17 +301,19 @@ export class Scope {
296
301
  */
297
302
  server_block = false;
298
303
 
304
+ /** @type {ScopeConstructorInterface['error_options']} */
305
+ #error_options;
306
+
299
307
  /**
300
- *
301
- * @param {ScopeRootInterface} root
302
- * @param {ScopeInterface | null} parent
303
- * @param {boolean} porous
308
+ * @param {ScopeConstructorParameters} params
304
309
  */
305
- constructor(root, parent, porous) {
310
+ constructor(...params) {
311
+ const [root, parent, porous, error_options] = params;
306
312
  this.root = root;
307
313
  this.parent = parent;
308
314
  this.#porous = porous;
309
315
  this.function_depth = parent ? parent.function_depth + (porous ? 0 : 1) : 0;
316
+ this.#error_options = error_options ?? {};
310
317
  }
311
318
 
312
319
  /**
@@ -323,12 +330,24 @@ export class Scope {
323
330
  }
324
331
  }
325
332
 
326
- if (node.name === '_$_') {
327
- throw new Error('Cannot declare a variable named "_$_" as it is a reserved identifier');
333
+ if (node.name.startsWith(IDENTIFIER_OBFUSCATION_PREFIX)) {
334
+ error(
335
+ `Cannot declare a variable named "${node.name}" as identifiers starting with "${IDENTIFIER_OBFUSCATION_PREFIX}" are reserved`,
336
+ this.#error_options.filename,
337
+ node,
338
+ this.#error_options.loose ? this.#error_options.errors : undefined,
339
+ this.#error_options.comments,
340
+ );
328
341
  }
329
342
 
330
343
  if (this.declarations.has(node.name)) {
331
- throw new Error(`'${node.name}' has already been declared in the current scope`);
344
+ error(
345
+ `'${node.name}' has already been declared in the current scope`,
346
+ this.#error_options.filename,
347
+ node,
348
+ this.#error_options.loose ? this.#error_options.errors : undefined,
349
+ this.#error_options.comments,
350
+ );
332
351
  }
333
352
 
334
353
  /** @type {Binding} */
@@ -355,7 +374,7 @@ export class Scope {
355
374
  * @type {ScopeInterface['child']}
356
375
  */
357
376
  child(porous = false) {
358
- return new Scope(this.root, this, porous);
377
+ return new Scope(this.root, this, porous, this.#error_options);
359
378
  }
360
379
 
361
380
  /**
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  @import { PostProcessingChanges, LineOffsets } from './phases/3-transform/client/index.js';
3
3
  @import * as AST from 'estree';
4
- @import { CodeMappingWithAll } from 'ripple/compiler';
4
+ @import { CodeMapping } from 'ripple/compiler';
5
5
  @import { CodeMapping as VolarCodeMapping } from '@volar/language-core';
6
6
  @import { RawSourceMap } from 'source-map';
7
7
  */
@@ -284,7 +284,7 @@ export function build_line_offsets(text) {
284
284
  * @param {Partial<VolarCodeMapping['data']>} [filtered_data]
285
285
  * @param {number} [src_max_len]
286
286
  * @param {number} [gen_max_len]
287
- * @returns {CodeMappingWithAll | Error}
287
+ * @returns {CodeMapping | Error}
288
288
  */
289
289
  function maybe_get_mapping_from_node(
290
290
  node,
@@ -319,9 +319,7 @@ function maybe_get_mapping_from_node(
319
319
  generatedLengths: [gen_length],
320
320
  data: {
321
321
  ...(filtered_data || mapping_data),
322
- customData: {
323
- generatedLengths: [gen_length],
324
- },
322
+ customData: {},
325
323
  },
326
324
  };
327
325
  }
@@ -333,7 +331,7 @@ function maybe_get_mapping_from_node(
333
331
  * @param {Partial<VolarCodeMapping['data']>} [filtered_data]
334
332
  * @param {number} [src_max_len]
335
333
  * @param {number} [gen_max_len]
336
- * @returns {CodeMappingWithAll}
334
+ * @returns {CodeMapping}
337
335
  */
338
336
  export function get_mapping_from_node(
339
337
  node,
@@ -0,0 +1,11 @@
1
+ // Re-export acorn types with Ripple augmentations applied.
2
+ // Since this file lives inside the ripple package, TypeScript resolves
3
+ // '@types/acorn' from ripple's node_modules. Consumers can import from
4
+ // 'ripple/types/acorn' to get the full augmented types without needing
5
+ // @types/acorn in their own package.json.
6
+ //
7
+ // The relative import of './parser' loads the augmentation declarations
8
+ // (declare module 'acorn' { ... }) so the re-exported types include
9
+ // Ripple-specific nodes like Component, Element, TrackedExpression, etc.
10
+ import './parser.d.ts';
11
+ export * from 'acorn';
@@ -0,0 +1,11 @@
1
+ // Re-export estree-jsx types with Ripple augmentations applied.
2
+ // Since this file lives inside the ripple package, TypeScript resolves
3
+ // '@types/estree-jsx' from ripple's node_modules. Consumers can import from
4
+ // 'ripple/types/estree-jsx' to get the full augmented types without needing
5
+ // @types/estree-jsx in their own package.json.
6
+ //
7
+ // The relative import of './index' loads the augmentation declarations
8
+ // (declare module 'estree-jsx' { ... }) so the re-exported types include
9
+ // Ripple-specific extensions like JSXAttribute.shorthand, etc.
10
+ import './index';
11
+ export * from 'estree-jsx';
@@ -0,0 +1,11 @@
1
+ // Re-export estree types with Ripple augmentations applied.
2
+ // Since this file lives inside the ripple package, TypeScript resolves
3
+ // '@types/estree' from ripple's node_modules. Consumers can import from
4
+ // 'ripple/types/estree' to get the full augmented types without needing
5
+ // @types/estree in their own package.json.
6
+ //
7
+ // The relative import of './index' loads the augmentation declarations
8
+ // (declare module 'estree' { ... }) so the re-exported types include
9
+ // Ripple-specific nodes like Component, Element, TrackedExpression, etc.
10
+ import './index';
11
+ export * from 'estree';
@@ -12,11 +12,11 @@
12
12
  * the user made a mistake when the user is missing an import.
13
13
  *
14
14
  * e.g.
15
- * // import { TrackedMap } from 'ripple'; -- assume TrackedMap import is missing
16
- * const map = new TrackedMap();
15
+ * // import { RippleMap } from 'ripple'; -- assume RippleMap import is missing
16
+ * const map = new RippleMap();
17
17
  *
18
- * If a type in the hidden import contains 'TrackedMap', e.g. '__TrackedMap',
19
- * TS would suggest to the user that they meant to use '__TrackedMap' instead of 'TrackedMap'.
18
+ * If a type in the hidden import contains 'RippleMap', e.g. '__RippleMap',
19
+ * TS would suggest to the user that they meant to use '__RippleMap' instead of 'RippleMap'.
20
20
  *
21
21
  * Add additional types as needed if they are used in hidden imports.
22
22
  *
@@ -30,23 +30,37 @@
30
30
  */
31
31
 
32
32
  import {
33
- TrackedMap as _$_Map__Tracked,
34
- TrackedSet as _$_Set__Tracked,
35
- TrackedArray as _$_Array__Tracked,
36
- TrackedObject as _$_Object__Tracked,
37
- TrackedURL as _$_URL__Tracked,
38
- TrackedURLSearchParams as _$_URLSearchParams__Tracked,
39
- TrackedDate as _$_Date__Tracked,
33
+ RippleMap as _$_Map__Ripple,
34
+ RippleSet as _$_Set__Ripple,
35
+ RippleArray as _$_Array__Ripple,
36
+ RippleObject as _$_Object__Ripple,
37
+ Context as _$_Context__Ripple,
38
+ RippleURL as _$_URL__Ripple,
39
+ RippleURLSearchParams as _$_URLSearchParams__Ripple,
40
+ RippleDate as _$_Date__Ripple,
41
+ MediaQuery as _$_MediaQuery__,
40
42
  createRefKey as _$_RefKey__create,
43
+ track as _$_track__,
44
+ trackSplit as _$_trackSplit__,
45
+ effect as _$_effect__,
46
+ untrack as _$_untrack__,
47
+ ripple_namespace as _$__u0023_ripple,
41
48
  } from 'ripple';
42
49
 
43
50
  export {
44
- _$_Map__Tracked,
45
- _$_Set__Tracked,
46
- _$_Array__Tracked,
47
- _$_Object__Tracked,
48
- _$_URL__Tracked,
49
- _$_URLSearchParams__Tracked,
50
- _$_Date__Tracked,
51
+ _$_Map__Ripple,
52
+ _$_Set__Ripple,
53
+ _$_Array__Ripple,
54
+ _$_Object__Ripple,
55
+ _$_Context__Ripple,
56
+ _$_URL__Ripple,
57
+ _$_URLSearchParams__Ripple,
58
+ _$_Date__Ripple,
59
+ _$_MediaQuery__,
51
60
  _$_RefKey__create,
61
+ _$_track__,
62
+ _$_trackSplit__,
63
+ _$_effect__,
64
+ _$_untrack__,
65
+ _$__u0023_ripple,
52
66
  };