ripple 0.2.128 → 0.2.130

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.128",
6
+ "version": "0.2.130",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -79,5 +79,8 @@
79
79
  "@types/estree": "^1.0.8",
80
80
  "@types/node": "^24.3.0",
81
81
  "typescript": "^5.9.2"
82
+ },
83
+ "peerDependencies": {
84
+ "ripple": "0.2.130"
82
85
  }
83
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