ripple 0.2.176 → 0.2.178

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.176",
6
+ "version": "0.2.178",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -83,6 +83,6 @@
83
83
  "@volar/language-core": "~2.4.23"
84
84
  },
85
85
  "peerDependencies": {
86
- "ripple": "0.2.176"
86
+ "ripple": "0.2.178"
87
87
  }
88
88
  }
@@ -22,7 +22,24 @@ export interface CompileResult {
22
22
  css: string;
23
23
  }
24
24
 
25
- export interface CustomMappingData {
25
+ export interface PluginActionOverrides {
26
+ /** TypeScript diagnostic codes to suppress for this mapping */
27
+ suppressedDiagnostics?: number[];
28
+ /** Custom hover documentation for this mapping, false to disable */
29
+ hover?:
30
+ | {
31
+ contents: string;
32
+ }
33
+ | false;
34
+ /** Custom definition info for this mapping, false to disable */
35
+ definition?:
36
+ | {
37
+ description: string;
38
+ }
39
+ | false;
40
+ }
41
+
42
+ export interface CustomMappingData extends PluginActionOverrides {
26
43
  generatedLengths: number[];
27
44
  }
28
45
 
@@ -968,7 +968,12 @@ const visitors = {
968
968
  const expression = visit(attr.value, { ...state, metadata });
969
969
 
970
970
  if (metadata.tracking) {
971
- local_updates.push({ operation: b.stmt(b.call('_$_.set_value', id, expression)) });
971
+ local_updates.push({
972
+ operation: (key) => b.stmt(b.call('_$_.set_value', id, key)),
973
+ expression,
974
+ identity: attr.value,
975
+ initial: b.void0,
976
+ });
972
977
  } else {
973
978
  state.init.push(b.stmt(b.call('_$_.set_value', id, expression)));
974
979
  }
@@ -983,7 +988,10 @@ const visitors = {
983
988
 
984
989
  if (metadata.tracking) {
985
990
  local_updates.push({
986
- operation: b.stmt(b.call('_$_.set_checked', id, expression)),
991
+ operation: (key) => b.stmt(b.call('_$_.set_checked', id, key)),
992
+ expression,
993
+ identity: attr.value,
994
+ initial: b.void0,
987
995
  });
988
996
  } else {
989
997
  state.init.push(b.stmt(b.call('_$_.set_checked', id, expression)));
@@ -998,7 +1006,10 @@ const visitors = {
998
1006
 
999
1007
  if (metadata.tracking) {
1000
1008
  local_updates.push({
1001
- operation: b.stmt(b.call('_$_.set_selected', id, expression)),
1009
+ operation: (key) => b.stmt(b.call('_$_.set_selected', id, key)),
1010
+ expression,
1011
+ identity: attr.value,
1012
+ initial: b.void0,
1002
1013
  });
1003
1014
  } else {
1004
1015
  state.init.push(b.stmt(b.call('_$_.set_selected', id, expression)));
@@ -1171,7 +1182,7 @@ const visitors = {
1171
1182
  update.push(...local_updates);
1172
1183
 
1173
1184
  if (update.length > 0) {
1174
- if (state.scope.parent.declarations.size > 0) {
1185
+ if (state.scope.declarations.size > 0) {
1175
1186
  apply_updates(init, update, state);
1176
1187
  } else {
1177
1188
  state.update.push(...update);
@@ -2181,6 +2192,18 @@ function transform_ts_child(node, context) {
2181
2192
  catch_handler = b.catch_clause(node.handler.param || null, catch_body);
2182
2193
  }
2183
2194
 
2195
+ let pending_block = null;
2196
+ if (node.pending) {
2197
+ const pending_scope = context.state.scopes.get(node.pending);
2198
+ pending_block = b.try_item_block(
2199
+ transform_body(node.pending.body, {
2200
+ ...context,
2201
+ state: { ...context.state, scope: pending_scope },
2202
+ }),
2203
+ node.pending.loc,
2204
+ );
2205
+ }
2206
+
2184
2207
  let finally_block = null;
2185
2208
  if (node.finalizer) {
2186
2209
  const finally_scope = context.state.scopes.get(node.finalizer);
@@ -2192,7 +2215,7 @@ function transform_ts_child(node, context) {
2192
2215
  );
2193
2216
  }
2194
2217
 
2195
- state.init.push(b.try(try_body, catch_handler, finally_block));
2218
+ state.init.push(b.try(try_body, catch_handler, finally_block, pending_block));
2196
2219
  } else if (node.type === 'Component') {
2197
2220
  const component = visit(node, state);
2198
2221
 
@@ -2798,6 +2821,38 @@ function create_tsx_with_typescript_support() {
2798
2821
  context.visit(node.body);
2799
2822
  }
2800
2823
  },
2824
+ // Custom handler for TryStatement to support Ripple's pending block
2825
+ TryStatement(node, context) {
2826
+ context.write('try ');
2827
+ context.visit(node.block);
2828
+
2829
+ if (node.pending) {
2830
+ // Output the pending block with source mapping for the 'pending' keyword
2831
+ context.write(' ');
2832
+ context.location(
2833
+ node.pending.loc.start.line,
2834
+ node.pending.loc.start.column - 'pending '.length,
2835
+ );
2836
+ context.write('pending ');
2837
+ context.visit(node.pending);
2838
+ }
2839
+
2840
+ if (node.handler) {
2841
+ context.write(' catch');
2842
+ if (node.handler.param) {
2843
+ context.write(' (');
2844
+ context.visit(node.handler.param);
2845
+ context.write(')');
2846
+ }
2847
+ context.write(' ');
2848
+ context.visit(node.handler.body);
2849
+ }
2850
+
2851
+ if (node.finalizer) {
2852
+ context.write(' finally ');
2853
+ context.visit(node.finalizer);
2854
+ }
2855
+ },
2801
2856
  };
2802
2857
  }
2803
2858
 
@@ -1,7 +1,4 @@
1
- /**
2
- * @typedef {Object} CustomMappingData
3
- * @property {number[]} generatedLengths
4
- */
1
+ /** @import { CustomMappingData, PluginActionOverrides } from 'ripple/compiler'; */
5
2
 
6
3
  /**
7
4
  * @typedef {import('estree').Position} Position
@@ -152,6 +149,7 @@ export function convert_source_map_to_mappings(
152
149
  * is_full_import_statement?: boolean,
153
150
  * loc: Location,
154
151
  * end_loc?: Location,
152
+ * metadata?: PluginActionOverrides
155
153
  * }>}
156
154
  */
157
155
  const tokens = [];
@@ -503,10 +501,50 @@ export function convert_source_map_to_mappings(
503
501
  }
504
502
  return;
505
503
  } else if (node.type === 'TryStatement') {
506
- // Visit in source order: block, handler, finalizer
504
+ // Visit in source order: block, pending, handler, finalizer
507
505
  if (node.block) {
508
506
  visit(node.block);
509
507
  }
508
+ if (node.pending) {
509
+ // Add a special token for the 'pending' keyword with customData
510
+ // to suppress TypeScript diagnostics and provide custom hover/definition
511
+ const pendingKeywordLoc = {
512
+ start: {
513
+ line: node.pending.loc.start.line,
514
+ column: node.pending.loc.start.column - 'pending '.length,
515
+ },
516
+ end: {
517
+ line: node.pending.loc.start.line,
518
+ column: node.pending.loc.start.column - 1,
519
+ },
520
+ };
521
+ tokens.push({
522
+ source: 'pending',
523
+ generated: 'pending',
524
+ loc: pendingKeywordLoc,
525
+ metadata: {
526
+ suppressedDiagnostics: [
527
+ 1472, // 'catch' or 'finally' expected
528
+ 2304, // Cannot find name 'pending'
529
+ ],
530
+ // suppress all hovers
531
+ hover: false,
532
+
533
+ // Example of a custom hover contents (uses markdown)
534
+ // hover: {
535
+ // contents:
536
+ // '```ripple\npending\n```\n\nRipple-specific keyword for try/pending blocks.\n\nThe `pending` block executes while async operations inside the `try` block are awaiting. This provides a built-in loading state for async components.',
537
+ // },
538
+
539
+ // TODO: Definition is not implemented yet, leaving for future use
540
+ // definition: {
541
+ // description:
542
+ // 'Ripple pending block - executes during async operations in the try block',
543
+ // },
544
+ },
545
+ });
546
+ visit(node.pending);
547
+ }
510
548
  if (node.handler) {
511
549
  visit(node.handler);
512
550
  }
@@ -1333,11 +1371,27 @@ export function convert_source_map_to_mappings(
1333
1371
  );
1334
1372
  gen_start = gen_loc_to_offset(gen_line_col.line, gen_line_col.column);
1335
1373
 
1374
+ /** @type {CustomMappingData} */
1375
+ const customData = {
1376
+ generatedLengths: [gen_length],
1377
+ };
1378
+
1379
+ // Add optional metadata from token if present
1380
+ if (token.metadata) {
1381
+ if ('suppressedDiagnostics' in token.metadata) {
1382
+ customData.suppressedDiagnostics = token.metadata.suppressedDiagnostics;
1383
+ }
1384
+ if ('hover' in token.metadata) {
1385
+ customData.hover = token.metadata.hover;
1386
+ }
1387
+ if ('definition' in token.metadata) {
1388
+ customData.definition = token.metadata.definition;
1389
+ }
1390
+ }
1391
+
1336
1392
  data = {
1337
1393
  ...mapping_data,
1338
- customData: {
1339
- generatedLengths: [gen_length],
1340
- },
1394
+ customData,
1341
1395
  };
1342
1396
  }
1343
1397
 
@@ -20,6 +20,10 @@ declare module 'estree' {
20
20
  params: Pattern[];
21
21
  body: BlockStatement;
22
22
  }
23
+
24
+ interface TryStatement {
25
+ pending?: BlockStatement | null;
26
+ }
23
27
  }
24
28
 
25
29
  declare module 'estree-jsx' {
@@ -106,6 +106,15 @@ export function block(body) {
106
106
  return { type: 'BlockStatement', body };
107
107
  }
108
108
 
109
+ /**
110
+ * @param {ESTree.Statement[]} body
111
+ * @param {ESTree.SourceLocation} loc
112
+ * @returns {ESTree.BlockStatement}
113
+ */
114
+ export function try_item_block(body, loc) {
115
+ return { type: 'BlockStatement', body, loc };
116
+ }
117
+
109
118
  /**
110
119
  * @param {string} name
111
120
  * @param {ESTree.Statement} body
@@ -681,21 +690,23 @@ export function throw_error(str) {
681
690
  * @param {ESTree.BlockStatement} block
682
691
  * @param {ESTree.CatchClause | null} handler
683
692
  * @param {ESTree.BlockStatement | null} finalizer
693
+ * @param {ESTree.BlockStatement | null} pending
684
694
  * @returns {ESTree.TryStatement}
685
695
  */
686
- export function try_builder(block, handler = null, finalizer = null) {
696
+ export function try_builder(block, handler = null, finalizer = null, pending = null) {
687
697
  return {
688
698
  type: 'TryStatement',
689
699
  block,
690
700
  handler,
691
701
  finalizer,
702
+ pending,
692
703
  };
693
704
  }
694
705
 
695
706
  /**
696
707
  * @param {ESTree.Pattern | null} param
697
708
  * @param {ESTree.BlockStatement} body
698
- * @returns {ESTree.CatchClause}
709
+ * @return {ESTree.CatchClause}
699
710
  */
700
711
  export function catch_clause_builder(param, body) {
701
712
  return {
@@ -6,7 +6,7 @@ exports[`TrackedExpression tests > should handle the syntax correctly 1`] = `
6
6
  0
7
7
  </div>
8
8
  <div>
9
- 0
9
+ 4
10
10
  </div>
11
11
  <div>
12
12
  1