ripple 0.2.93 → 0.2.95

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.93",
6
+ "version": "0.2.95",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -301,6 +301,15 @@ const visitors = {
301
301
  }
302
302
  },
303
303
 
304
+ TSTypeReference(node, context) {
305
+ // bug in our acorn pasrer: it uses typeParameters instead of typeArguments
306
+ if (node.typeParameters) {
307
+ node.typeArguments = node.typeParameters;
308
+ delete node.typeParameters;
309
+ }
310
+ context.next();
311
+ },
312
+
304
313
  IfStatement(node, context) {
305
314
  if (!is_inside_component(context)) {
306
315
  return context.next();
@@ -419,59 +419,7 @@ const visitors = {
419
419
  delete declarator.id.typeAnnotation;
420
420
  }
421
421
 
422
- if (binding !== null && binding.kind === 'tracked') {
423
- let expression;
424
-
425
- if (context.state.to_ts) {
426
- // TypeScript mode: lighter transformation
427
- if (metadata.tracking && !metadata.await) {
428
- expression = b.call(
429
- '_$_.derived',
430
- b.thunk(context.visit(declarator.init)),
431
- b.id('__block'),
432
- );
433
- } else {
434
- expression = b.call(
435
- '_$_.tracked',
436
- declarator.init === null ? undefined : context.visit(declarator.init),
437
- b.id('__block'),
438
- );
439
- }
440
- } else {
441
- debugger;
442
- // Runtime mode: full transformation
443
- if (metadata.tracking && metadata.await) {
444
- expression = b.call(
445
- b.await(
446
- b.call(
447
- '_$_.resume_context',
448
- b.call(
449
- '_$_.async_computed',
450
- b.thunk(context.visit(declarator.init), true),
451
- b.id('__block'),
452
- ),
453
- ),
454
- ),
455
- );
456
- } else if (metadata.tracking && !metadata.await) {
457
- expression = b.call(
458
- '_$_.derived',
459
- b.thunk(context.visit(declarator.init)),
460
- b.id('__block'),
461
- );
462
- } else {
463
- expression = b.call(
464
- '_$_.tracked',
465
- declarator.init === null ? undefined : context.visit(declarator.init),
466
- b.id('__block'),
467
- );
468
- }
469
- }
470
-
471
- declarations.push(b.declarator(declarator.id, expression));
472
- } else {
473
- declarations.push(context.visit(declarator));
474
- }
422
+ declarations.push(context.visit(declarator));
475
423
  } else {
476
424
  if (!context.state.to_ts) {
477
425
  delete declarator.id.typeAnnotation;
@@ -1458,12 +1406,14 @@ function transform_ts_child(node, context) {
1458
1406
  state.init.push(b.if(visit(node.test), consequent, alternate));
1459
1407
  } else if (node.type === 'ForOfStatement') {
1460
1408
  const body_scope = context.state.scopes.get(node.body);
1461
- const body = b.block(
1462
- transform_body(node.body.body, {
1463
- ...context,
1464
- state: { ...context.state, scope: body_scope },
1465
- }),
1466
- );
1409
+ const block_body = transform_body(node.body.body, {
1410
+ ...context,
1411
+ state: { ...context.state, scope: body_scope },
1412
+ });
1413
+ if (node.index) {
1414
+ block_body.unshift(b.let(visit(node.index), b.literal(0)));
1415
+ }
1416
+ const body = b.block(block_body);
1467
1417
 
1468
1418
  state.init.push(b.for_of(visit(node.left), visit(node.right), body, node.await));
1469
1419
  } else if (node.type === 'TryStatement') {
@@ -22,6 +22,15 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
22
22
  let sourceIndex = 0;
23
23
  let generatedIndex = 0;
24
24
 
25
+ /**
26
+ * Check if character is a word boundary (not alphanumeric or underscore)
27
+ * @param {string} char
28
+ * @returns {boolean}
29
+ */
30
+ const isWordBoundary = (char) => {
31
+ return char === undefined || !/[a-zA-Z0-9_$]/.test(char);
32
+ };
33
+
25
34
  /**
26
35
  * Find text in source string, searching character by character from sourceIndex
27
36
  * @param {string} text - Text to find
@@ -37,6 +46,16 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
37
46
  }
38
47
  }
39
48
  if (match) {
49
+ // Check word boundaries for identifier-like tokens
50
+ const isIdentifierLike = /^[a-zA-Z_$]/.test(text);
51
+ if (isIdentifierLike) {
52
+ const charBefore = source[i - 1];
53
+ const charAfter = source[i + text.length];
54
+ if (!isWordBoundary(charBefore) || !isWordBoundary(charAfter)) {
55
+ continue; // Not a whole word match, keep searching
56
+ }
57
+ }
58
+
40
59
  sourceIndex = i + text.length;
41
60
  return i;
42
61
  }
@@ -59,6 +78,16 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
59
78
  }
60
79
  }
61
80
  if (match) {
81
+ // Check word boundaries for identifier-like tokens
82
+ const isIdentifierLike = /^[a-zA-Z_$]/.test(text);
83
+ if (isIdentifierLike) {
84
+ const charBefore = generated_code[i - 1];
85
+ const charAfter = generated_code[i + text.length];
86
+ if (!isWordBoundary(charBefore) || !isWordBoundary(charAfter)) {
87
+ continue; // Not a whole word match, keep searching
88
+ }
89
+ }
90
+
62
91
  generatedIndex = i + text.length;
63
92
  return i;
64
93
  }
@@ -204,13 +233,17 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
204
233
  }
205
234
  return;
206
235
  } else if (node.type === 'ForOfStatement' || node.type === 'ForInStatement') {
207
- // Visit in source order: left, right, body
236
+ // Visit in source order: left, right, index (Ripple-specific), body
208
237
  if (node.left) {
209
238
  visit(node.left);
210
239
  }
211
240
  if (node.right) {
212
241
  visit(node.right);
213
242
  }
243
+ // Ripple-specific: index variable
244
+ if (node.index) {
245
+ visit(node.index);
246
+ }
214
247
  if (node.body) {
215
248
  visit(node.body);
216
249
  }