ripple 0.2.129 → 0.2.131

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": "Ripple is an elegant TypeScript UI framework",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.2.129",
6
+ "version": "0.2.131",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -81,6 +81,6 @@
81
81
  "typescript": "^5.9.2"
82
82
  },
83
83
  "peerDependencies": {
84
- "ripple": "0.2.129"
84
+ "ripple": "0.2.131"
85
85
  }
86
86
  }
@@ -501,10 +501,27 @@ function RipplePlugin(config) {
501
501
  parseTrackedCollectionExpression(type) {
502
502
  const node = this.startNode();
503
503
  this.next(); // consume '#Map' or '#Set'
504
+
505
+ // Check if we should NOT consume the parentheses
506
+ // This happens when #Map/#Set appears as a callee in 'new #Map(...)'
507
+ // In this case, the parentheses and arguments belong to the NewExpression
508
+ // We detect this by checking if next token is '(' but we just consumed a token
509
+ // that came right after 'new' keyword (indicated by context or recent token)
510
+
511
+ // Simple heuristic: if the input around our start position looks like 'new #Map('
512
+ // then don't consume the parens
513
+ const beforeStart = this.input.substring(Math.max(0, node.start - 5), node.start);
514
+ const isAfterNew = /new\s*$/.test(beforeStart);
515
+
516
+ if (isAfterNew && this.type === tt.parenL) {
517
+ // Don't consume parens - they belong to NewExpression
518
+ node.arguments = [];
519
+ return this.finishNode(node, type);
520
+ }
521
+
504
522
  this.expect(tt.parenL); // expect '('
505
523
 
506
524
  node.arguments = [];
507
-
508
525
  // Parse arguments similar to function call arguments
509
526
  let first = true;
510
527
  while (!this.eat(tt.parenR)) {
@@ -1233,11 +1250,13 @@ function RipplePlugin(config) {
1233
1250
  const content = input.slice(0, end);
1234
1251
 
1235
1252
  const component = this.#path.findLast((n) => n.type === 'Component');
1253
+ const parsed_css = parse_style(content);
1254
+
1236
1255
  if (!inside_head) {
1237
1256
  if (component.css !== null) {
1238
1257
  throw new Error('Components can only have one style tag');
1239
1258
  }
1240
- component.css = parse_style(content);
1259
+ component.css = parsed_css;
1241
1260
  }
1242
1261
 
1243
1262
  const newLines = content.match(regex_newline_characters)?.length;
@@ -1256,11 +1275,10 @@ function RipplePlugin(config) {
1256
1275
  this.#path.pop();
1257
1276
  this.next();
1258
1277
  }
1259
- // This node is used for Prettier, we don't actually need
1260
- // the node for Ripple's transform process
1261
- if (!inside_head) {
1262
- element.children = [component.css];
1263
- }
1278
+ // This node is used for Prettier - always add parsed CSS as children
1279
+ // for proper formatting, regardless of whether it's inside head or not
1280
+ element.children = [parsed_css];
1281
+
1264
1282
  // Ensure we escape JSX <tag></tag> context
1265
1283
  const tokContexts = this.acornTypeScript.tokContexts;
1266
1284
  const curContext = this.curContext();
@@ -1392,7 +1410,7 @@ function RipplePlugin(config) {
1392
1410
  this.next();
1393
1411
  this.enterScope(0);
1394
1412
  node.id = this.parseIdent();
1395
- this.declareName(node.id.name, 'var', node.id.start);
1413
+ this.declareName(node.id.name, 'var', node.id.start);
1396
1414
  this.parseFunctionParams(node);
1397
1415
  this.eat(tt.braceL);
1398
1416
  node.body = [];
@@ -335,6 +335,23 @@ const visitors = {
335
335
  if (!context.state.to_ts) {
336
336
  delete node.typeArguments;
337
337
  }
338
+
339
+ // Special handling for TrackedMapExpression and TrackedSetExpression
340
+ // When source is "new #Map(...)", the callee is TrackedMapExpression with empty arguments
341
+ // and the actual arguments are in NewExpression.arguments
342
+ // We need to merge them before transforming
343
+ if (
344
+ context.state.to_ts &&
345
+ (callee.type === 'TrackedMapExpression' || callee.type === 'TrackedSetExpression')
346
+ ) {
347
+ // If the callee has empty arguments, use the NewExpression's arguments instead
348
+ if (callee.arguments.length === 0 && node.arguments.length > 0) {
349
+ callee.arguments = node.arguments;
350
+ }
351
+ // Transform the tracked expression directly - it will return a NewExpression
352
+ return context.visit(callee);
353
+ }
354
+
338
355
  return context.next();
339
356
  }
340
357
 
@@ -358,7 +375,7 @@ const visitors = {
358
375
 
359
376
  return b.call(
360
377
  b.member(b.id('TrackedArray'), b.id('from')),
361
- ...node.elements.map((el) => context.visit(el)),
378
+ b.array(node.elements.map((el) => context.visit(el))),
362
379
  );
363
380
  }
364
381
 
@@ -366,9 +366,13 @@ export function convert_source_map_to_mappings(ast, source, generated_code, sour
366
366
  }
367
367
  return;
368
368
  } else if (node.type === 'VariableDeclarator') {
369
- // Visit in source order: id, init
369
+ // Visit in source order: id, typeAnnotation, init
370
370
  if (node.id) {
371
371
  visit(node.id);
372
+ // Visit type annotation if present
373
+ if (node.id.typeAnnotation) {
374
+ visit(node.id.typeAnnotation);
375
+ }
372
376
  }
373
377
  if (node.init) {
374
378
  visit(node.init);
@@ -486,9 +490,13 @@ export function convert_source_map_to_mappings(ast, source, generated_code, sour
486
490
  }
487
491
  return;
488
492
  } else if (node.type === 'AssignmentExpression' || node.type === 'AssignmentPattern') {
489
- // Visit in source order: left, right
493
+ // Visit in source order: left, typeAnnotation, right
490
494
  if (node.left) {
491
495
  visit(node.left);
496
+ // Visit type annotation if present (for AssignmentPattern)
497
+ if (node.left.typeAnnotation) {
498
+ visit(node.left.typeAnnotation);
499
+ }
492
500
  }
493
501
  if (node.right) {
494
502
  visit(node.right);
@@ -647,6 +655,14 @@ export function convert_source_map_to_mappings(ast, source, generated_code, sour
647
655
  // Visit the argument
648
656
  if (node.argument) {
649
657
  visit(node.argument);
658
+ // Visit type annotation if present (for RestElement)
659
+ if (node.argument.typeAnnotation) {
660
+ visit(node.argument.typeAnnotation);
661
+ }
662
+ }
663
+ // RestElement itself can have typeAnnotation
664
+ if (node.typeAnnotation) {
665
+ visit(node.typeAnnotation);
650
666
  }
651
667
  return;
652
668
  } else if (node.type === 'YieldExpression' || node.type === 'AwaitExpression') {