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 +2 -2
- package/src/compiler/index.d.ts +18 -1
- package/src/compiler/phases/3-transform/client/index.js +60 -5
- package/src/compiler/phases/3-transform/segments.js +62 -8
- package/src/compiler/types/index.d.ts +4 -0
- package/src/utils/builders.js +13 -2
- package/tests/client/__snapshots__/tracked-expression.test.ripple.snap +1 -1
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.
|
|
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.
|
|
86
|
+
"ripple": "0.2.178"
|
|
87
87
|
}
|
|
88
88
|
}
|
package/src/compiler/index.d.ts
CHANGED
|
@@ -22,7 +22,24 @@ export interface CompileResult {
|
|
|
22
22
|
css: string;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export interface
|
|
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({
|
|
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,
|
|
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,
|
|
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.
|
|
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
|
|
package/src/utils/builders.js
CHANGED
|
@@ -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
|
-
* @
|
|
709
|
+
* @return {ESTree.CatchClause}
|
|
699
710
|
*/
|
|
700
711
|
export function catch_clause_builder(param, body) {
|
|
701
712
|
return {
|