ripple 0.2.139 → 0.2.140
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/phases/1-parse/index.js +1 -0
- package/src/compiler/phases/3-transform/client/index.js +173 -55
- package/src/compiler/phases/3-transform/segments.js +31 -74
- package/src/runtime/internal/client/bindings.js +9 -9
- package/src/runtime/internal/client/for.js +2 -2
- package/src/runtime/internal/client/runtime.js +26 -31
- package/src/utils/builders.js +1 -0
- package/tests/client/basic/basic.get-set.test.ripple +37 -49
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +4 -4
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.140",
|
|
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.
|
|
84
|
+
"ripple": "0.2.140"
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -987,6 +987,7 @@ function RipplePlugin(config) {
|
|
|
987
987
|
this.finishNode(id, 'Identifier');
|
|
988
988
|
node.name = id;
|
|
989
989
|
node.value = id;
|
|
990
|
+
node.shorthand = true; // Mark as shorthand since name and value are the same
|
|
990
991
|
this.next();
|
|
991
992
|
this.expect(tt.braceR);
|
|
992
993
|
return this.finishNode(node, 'Attribute');
|
|
@@ -190,9 +190,17 @@ const visitors = {
|
|
|
190
190
|
const binding = context.state.scope.get(node.name);
|
|
191
191
|
if (binding?.metadata?.is_dynamic_component) {
|
|
192
192
|
// Capitalize the identifier for TypeScript
|
|
193
|
-
const
|
|
194
|
-
const
|
|
195
|
-
|
|
193
|
+
const capitalized_name = node.name.charAt(0).toUpperCase() + node.name.slice(1);
|
|
194
|
+
const capitalized_node = {
|
|
195
|
+
...node,
|
|
196
|
+
name: capitalized_name,
|
|
197
|
+
metadata: {
|
|
198
|
+
...node.metadata,
|
|
199
|
+
original_name: node.name,
|
|
200
|
+
is_capitalized: true,
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
return b.member(capitalized_node, b.literal('#v'), true);
|
|
196
204
|
}
|
|
197
205
|
return b.member(node, b.literal('#v'), true);
|
|
198
206
|
}
|
|
@@ -525,13 +533,74 @@ const visitors = {
|
|
|
525
533
|
|
|
526
534
|
VariableDeclarator(node, context) {
|
|
527
535
|
// In TypeScript mode, capitalize identifiers that are used as dynamic components
|
|
528
|
-
if (context.state.to_ts
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
536
|
+
if (context.state.to_ts) {
|
|
537
|
+
/**
|
|
538
|
+
* Recursively capitalize identifiers in patterns (ArrayPattern, ObjectPattern)
|
|
539
|
+
* @param {any} pattern - The pattern node to process
|
|
540
|
+
* @returns {any} The transformed pattern
|
|
541
|
+
*/
|
|
542
|
+
const capitalize_pattern = (pattern) => {
|
|
543
|
+
if (pattern.type === 'Identifier') {
|
|
544
|
+
const binding = context.state.scope.get(pattern.name);
|
|
545
|
+
if (binding?.metadata?.is_dynamic_component) {
|
|
546
|
+
const capitalized_name = pattern.name.charAt(0).toUpperCase() + pattern.name.slice(1);
|
|
547
|
+
// Add metadata to track the original name for Volar mappings
|
|
548
|
+
return {
|
|
549
|
+
...pattern,
|
|
550
|
+
name: capitalized_name,
|
|
551
|
+
metadata: {
|
|
552
|
+
...pattern.metadata,
|
|
553
|
+
original_name: pattern.name,
|
|
554
|
+
is_capitalized: true,
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
return pattern;
|
|
559
|
+
} else if (pattern.type === 'ArrayPattern') {
|
|
560
|
+
return {
|
|
561
|
+
...pattern,
|
|
562
|
+
elements: pattern.elements.map((element) =>
|
|
563
|
+
element ? capitalize_pattern(element) : element
|
|
564
|
+
),
|
|
565
|
+
};
|
|
566
|
+
} else if (pattern.type === 'ObjectPattern') {
|
|
567
|
+
return {
|
|
568
|
+
...pattern,
|
|
569
|
+
properties: pattern.properties.map((prop) => {
|
|
570
|
+
if (prop.type === 'Property') {
|
|
571
|
+
return {
|
|
572
|
+
...prop,
|
|
573
|
+
value: capitalize_pattern(prop.value),
|
|
574
|
+
};
|
|
575
|
+
} else if (prop.type === 'RestElement') {
|
|
576
|
+
return {
|
|
577
|
+
...prop,
|
|
578
|
+
argument: capitalize_pattern(prop.argument),
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
return prop;
|
|
582
|
+
}),
|
|
583
|
+
};
|
|
584
|
+
} else if (pattern.type === 'RestElement') {
|
|
585
|
+
return {
|
|
586
|
+
...pattern,
|
|
587
|
+
argument: capitalize_pattern(pattern.argument),
|
|
588
|
+
};
|
|
589
|
+
} else if (pattern.type === 'AssignmentPattern') {
|
|
590
|
+
return {
|
|
591
|
+
...pattern,
|
|
592
|
+
left: capitalize_pattern(pattern.left),
|
|
593
|
+
right: context.visit(pattern.right),
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
return pattern;
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
const transformed_id = capitalize_pattern(node.id);
|
|
600
|
+
if (transformed_id !== node.id) {
|
|
532
601
|
return {
|
|
533
602
|
...node,
|
|
534
|
-
id:
|
|
603
|
+
id: transformed_id,
|
|
535
604
|
init: node.init ? context.visit(node.init) : null,
|
|
536
605
|
};
|
|
537
606
|
}
|
|
@@ -1244,7 +1313,6 @@ const visitors = {
|
|
|
1244
1313
|
/** @type {Expression} */ (context.visit(left)),
|
|
1245
1314
|
/** @type {Expression} */ (context.visit(right)),
|
|
1246
1315
|
),
|
|
1247
|
-
b.id('__block'),
|
|
1248
1316
|
);
|
|
1249
1317
|
}
|
|
1250
1318
|
|
|
@@ -1265,7 +1333,6 @@ const visitors = {
|
|
|
1265
1333
|
),
|
|
1266
1334
|
/** @type {Expression} */ (context.visit(right)),
|
|
1267
1335
|
),
|
|
1268
|
-
b.id('__block'),
|
|
1269
1336
|
);
|
|
1270
1337
|
}
|
|
1271
1338
|
|
|
@@ -1291,7 +1358,6 @@ const visitors = {
|
|
|
1291
1358
|
node.prefix ? '_$_.update_pre_property' : '_$_.update_property',
|
|
1292
1359
|
context.visit(argument.object, { ...context.state, metadata: { tracking: false } }),
|
|
1293
1360
|
argument.computed ? context.visit(argument.property) : b.literal(argument.property.name),
|
|
1294
|
-
b.id('__block'),
|
|
1295
1361
|
node.operator === '--' ? b.literal(-1) : undefined,
|
|
1296
1362
|
);
|
|
1297
1363
|
}
|
|
@@ -1300,7 +1366,6 @@ const visitors = {
|
|
|
1300
1366
|
return b.call(
|
|
1301
1367
|
node.prefix ? '_$_.update_pre' : '_$_.update',
|
|
1302
1368
|
context.visit(argument, { ...context.state, metadata: { tracking: null } }),
|
|
1303
|
-
b.id('__block'),
|
|
1304
1369
|
node.operator === '--' ? b.literal(-1) : undefined,
|
|
1305
1370
|
);
|
|
1306
1371
|
}
|
|
@@ -1309,7 +1374,6 @@ const visitors = {
|
|
|
1309
1374
|
return b.call(
|
|
1310
1375
|
node.prefix ? '_$_.update_pre' : '_$_.update',
|
|
1311
1376
|
context.visit(argument.argument, { ...context.state, metadata: { tracking: null } }),
|
|
1312
|
-
b.id('__block'),
|
|
1313
1377
|
node.operator === '--' ? b.literal(-1) : undefined,
|
|
1314
1378
|
);
|
|
1315
1379
|
}
|
|
@@ -1740,7 +1804,10 @@ function transform_ts_child(node, context) {
|
|
|
1740
1804
|
}
|
|
1741
1805
|
jsx_name.loc = attr.name.loc || name.loc;
|
|
1742
1806
|
|
|
1743
|
-
|
|
1807
|
+
const jsx_attr = b.jsx_attribute(jsx_name, b.jsx_expression_container(value));
|
|
1808
|
+
// Preserve shorthand flag from parser (set for {identifier} syntax)
|
|
1809
|
+
jsx_attr.shorthand = attr.shorthand ?? false;
|
|
1810
|
+
return jsx_attr;
|
|
1744
1811
|
} else if (attr.type === 'SpreadAttribute') {
|
|
1745
1812
|
const metadata = { await: false };
|
|
1746
1813
|
const argument = visit(attr.argument, { ...state, metadata });
|
|
@@ -1783,31 +1850,75 @@ function transform_ts_child(node, context) {
|
|
|
1783
1850
|
closing_type = node.selfClosing ? undefined : type_expression;
|
|
1784
1851
|
} else {
|
|
1785
1852
|
opening_type = b.jsx_id(type_expression);
|
|
1786
|
-
//
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1853
|
+
// For tracked identifiers (dynamic components), adjust the loc to skip the '@' prefix
|
|
1854
|
+
// and add metadata for mapping
|
|
1855
|
+
if (node.id.tracked && node.id.loc) {
|
|
1856
|
+
// The original identifier loc includes the '@', so we need to skip it
|
|
1857
|
+
opening_type.loc = {
|
|
1858
|
+
start: {
|
|
1859
|
+
line: node.id.loc.start.line,
|
|
1860
|
+
column: node.id.loc.start.column + 1, // Skip '@'
|
|
1861
|
+
},
|
|
1862
|
+
end: node.id.loc.end,
|
|
1863
|
+
};
|
|
1864
|
+
// Add metadata if this was capitalized
|
|
1865
|
+
if (node.metadata?.ts_name && node.metadata?.original_name) {
|
|
1866
|
+
opening_type.metadata = {
|
|
1867
|
+
original_name: node.metadata.original_name,
|
|
1868
|
+
is_capitalized: true,
|
|
1869
|
+
};
|
|
1870
|
+
}
|
|
1871
|
+
} else {
|
|
1872
|
+
// Use node.id.loc if available, otherwise create a loc based on the element's position
|
|
1873
|
+
opening_type.loc = node.id.loc || {
|
|
1801
1874
|
start: {
|
|
1802
|
-
line: node.loc.
|
|
1803
|
-
column: node.loc.
|
|
1875
|
+
line: node.loc.start.line,
|
|
1876
|
+
column: node.loc.start.column + 2, // After "<@"
|
|
1804
1877
|
},
|
|
1805
1878
|
end: {
|
|
1806
|
-
line: node.loc.
|
|
1807
|
-
column: node.loc.
|
|
1879
|
+
line: node.loc.start.line,
|
|
1880
|
+
column: node.loc.start.column + 2 + type_expression.length,
|
|
1808
1881
|
},
|
|
1809
1882
|
};
|
|
1810
1883
|
}
|
|
1884
|
+
|
|
1885
|
+
if (!node.selfClosing) {
|
|
1886
|
+
closing_type = b.jsx_id(type_expression);
|
|
1887
|
+
// For tracked identifiers, also adjust closing tag location
|
|
1888
|
+
if (node.id.tracked && node.id.loc) {
|
|
1889
|
+
// Calculate position relative to closing tag
|
|
1890
|
+
// Format: </@identifier>
|
|
1891
|
+
const closing_tag_start = node.loc.end.column - type_expression.length - 3; // </@
|
|
1892
|
+
closing_type.loc = {
|
|
1893
|
+
start: {
|
|
1894
|
+
line: node.loc.end.line,
|
|
1895
|
+
column: closing_tag_start + 3, // Skip '</@'
|
|
1896
|
+
},
|
|
1897
|
+
end: {
|
|
1898
|
+
line: node.loc.end.line,
|
|
1899
|
+
column: closing_tag_start + 3 + (node.metadata?.original_name?.length || type_expression.length),
|
|
1900
|
+
},
|
|
1901
|
+
};
|
|
1902
|
+
// Add metadata if this was capitalized
|
|
1903
|
+
if (node.metadata?.ts_name && node.metadata?.original_name) {
|
|
1904
|
+
closing_type.metadata = {
|
|
1905
|
+
original_name: node.metadata.original_name,
|
|
1906
|
+
is_capitalized: true,
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
} else {
|
|
1910
|
+
closing_type.loc = {
|
|
1911
|
+
start: {
|
|
1912
|
+
line: node.loc.end.line,
|
|
1913
|
+
column: node.loc.end.column - type_expression.length - 1,
|
|
1914
|
+
},
|
|
1915
|
+
end: {
|
|
1916
|
+
line: node.loc.end.line,
|
|
1917
|
+
column: node.loc.end.column - 1,
|
|
1918
|
+
},
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1811
1922
|
}
|
|
1812
1923
|
|
|
1813
1924
|
const jsxElement = b.jsx_element(
|
|
@@ -2396,12 +2507,13 @@ export function transform_client(filename, source, analysis, to_ts) {
|
|
|
2396
2507
|
|
|
2397
2508
|
const language_handler = to_ts ? create_tsx_with_typescript_support() : tsx();
|
|
2398
2509
|
|
|
2399
|
-
const js =
|
|
2400
|
-
print
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2510
|
+
const js =
|
|
2511
|
+
/** @type {ReturnType<typeof print> & { post_processing_changes?: PostProcessingChanges, line_offsets?: number[] }} */ (
|
|
2512
|
+
print(program, language_handler, {
|
|
2513
|
+
sourceMapContent: source,
|
|
2514
|
+
sourceMapSource: path.basename(filename),
|
|
2515
|
+
})
|
|
2516
|
+
);
|
|
2405
2517
|
|
|
2406
2518
|
// Post-process TypeScript output to remove 'declare' from function overload signatures
|
|
2407
2519
|
// Function overload signatures in regular .ts files should not have 'declare' keyword
|
|
@@ -2427,7 +2539,10 @@ export function transform_client(filename, source, analysis, to_ts) {
|
|
|
2427
2539
|
*/
|
|
2428
2540
|
const offset_to_line = (offset) => {
|
|
2429
2541
|
for (let i = 0; i < line_offsets.length; i++) {
|
|
2430
|
-
if (
|
|
2542
|
+
if (
|
|
2543
|
+
offset >= line_offsets[i] &&
|
|
2544
|
+
(i === line_offsets.length - 1 || offset < line_offsets[i + 1])
|
|
2545
|
+
) {
|
|
2431
2546
|
return i + 1;
|
|
2432
2547
|
}
|
|
2433
2548
|
}
|
|
@@ -2440,22 +2555,25 @@ export function transform_client(filename, source, analysis, to_ts) {
|
|
|
2440
2555
|
// Remove 'export declare function' -> 'export function' (for overloads only, not implementations)
|
|
2441
2556
|
// Match: export declare function name(...): type;
|
|
2442
2557
|
// Don't match: export declare function name(...): type { (has body)
|
|
2443
|
-
js.code = js.code.replace(
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2558
|
+
js.code = js.code.replace(
|
|
2559
|
+
/^(export\s+)declare\s+(function\s+\w+[^{\n]*;)$/gm,
|
|
2560
|
+
(match, p1, p2, offset) => {
|
|
2561
|
+
const replacement = p1 + p2;
|
|
2562
|
+
const line = offset_to_line(offset);
|
|
2563
|
+
const delta = replacement.length - match.length; // negative (removing 'declare ')
|
|
2564
|
+
|
|
2565
|
+
// Track first change offset and total delta per line
|
|
2566
|
+
if (!line_deltas.has(line)) {
|
|
2567
|
+
line_deltas.set(line, { offset, delta });
|
|
2568
|
+
} else {
|
|
2569
|
+
// Additional change on same line - accumulate delta
|
|
2570
|
+
// @ts-ignore
|
|
2571
|
+
line_deltas.get(line).delta += delta;
|
|
2572
|
+
}
|
|
2456
2573
|
|
|
2457
|
-
|
|
2458
|
-
|
|
2574
|
+
return replacement;
|
|
2575
|
+
},
|
|
2576
|
+
);
|
|
2459
2577
|
|
|
2460
2578
|
post_processing_changes = line_deltas;
|
|
2461
2579
|
}
|
|
@@ -70,26 +70,6 @@ export function convert_source_map_to_mappings(ast, source, generated_code, esra
|
|
|
70
70
|
return line_offsets[line - 1] + column;
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
// Map to track capitalized names: original name -> capitalized name
|
|
74
|
-
/** @type {Map<string, string>} */
|
|
75
|
-
const capitalized_names = new Map();
|
|
76
|
-
// Reverse map: capitalized name -> original name
|
|
77
|
-
/** @type {Map<string, string>} */
|
|
78
|
-
const reverse_capitalized_names = new Map();
|
|
79
|
-
|
|
80
|
-
// Pre-walk to collect capitalized names from JSXElement nodes (transformed AST)
|
|
81
|
-
// These are identifiers that are used as dynamic components/elements
|
|
82
|
-
walk(ast, null, {
|
|
83
|
-
_(node, { next }) {
|
|
84
|
-
// Check JSXElement nodes with metadata (preserved from Element nodes)
|
|
85
|
-
if (node.type === 'JSXElement' && node.metadata?.ts_name && node.metadata?.original_name) {
|
|
86
|
-
capitalized_names.set(node.metadata.original_name, node.metadata.ts_name);
|
|
87
|
-
reverse_capitalized_names.set(node.metadata.ts_name, node.metadata.original_name);
|
|
88
|
-
}
|
|
89
|
-
next();
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
73
|
const adjusted_source_map = build_source_to_generated_map(
|
|
94
74
|
esrap_source_map,
|
|
95
75
|
post_processing_changes,
|
|
@@ -110,51 +90,30 @@ export function convert_source_map_to_mappings(ast, source, generated_code, esra
|
|
|
110
90
|
walk(ast, null, {
|
|
111
91
|
_(node, { visit }) {
|
|
112
92
|
// Collect key node types: Identifiers, Literals, and JSX Elements
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
93
|
+
if (node.type === 'Identifier') {
|
|
94
|
+
// Only create mappings for identifiers with location info (from source)
|
|
95
|
+
// Synthesized identifiers (created by builders) don't have .loc and are skipped
|
|
96
|
+
if (node.name && node.loc) {
|
|
116
97
|
// Check if this identifier has tracked_shorthand metadata (e.g., TrackedMap -> #Map)
|
|
117
98
|
if (node.metadata?.tracked_shorthand) {
|
|
118
99
|
tokens.push({ source: node.metadata.tracked_shorthand, generated: node.name, loc: node.loc });
|
|
100
|
+
} else if (node.metadata?.is_capitalized) {
|
|
101
|
+
// This identifier was capitalized during transformation
|
|
102
|
+
// Map the original lowercase name to the capitalized generated name
|
|
103
|
+
tokens.push({ source: node.metadata.original_name, generated: node.name, loc: node.loc });
|
|
119
104
|
} else {
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
if (original_name) {
|
|
123
|
-
// This is a capitalized name in generated code, map to lowercase in source
|
|
124
|
-
tokens.push({ source: original_name, generated: node.name, loc: node.loc });
|
|
125
|
-
} else {
|
|
126
|
-
// Check if this identifier should be capitalized (forward lookup)
|
|
127
|
-
const cap_name = capitalized_names.get(node.name);
|
|
128
|
-
if (cap_name) {
|
|
129
|
-
tokens.push({ source: node.name, generated: cap_name, loc: node.loc });
|
|
130
|
-
} else {
|
|
131
|
-
// Check if this identifier should be capitalized (forward lookup)
|
|
132
|
-
const cap_name = capitalized_names.get(node.name);
|
|
133
|
-
if (cap_name) {
|
|
134
|
-
tokens.push({ source: node.name, generated: cap_name, loc: node.loc });
|
|
135
|
-
} else {
|
|
136
|
-
// Store token with .loc for accurate positioning
|
|
137
|
-
tokens.push({ source: node.name, generated: node.name, loc: node.loc });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
105
|
+
// No transformation - source and generated names are the same
|
|
106
|
+
tokens.push({ source: node.name, generated: node.name, loc: node.loc });
|
|
141
107
|
}
|
|
142
108
|
}
|
|
143
109
|
return; // Leaf node, don't traverse further
|
|
144
|
-
} else if (node.type === 'JSXIdentifier'
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
tokens.push({ source: originalName, generated: node.name, loc: node.loc });
|
|
110
|
+
} else if (node.type === 'JSXIdentifier') {
|
|
111
|
+
// JSXIdentifiers can also be capitalized (for dynamic components)
|
|
112
|
+
if (node.loc && node.name) {
|
|
113
|
+
if (node.metadata?.is_capitalized) {
|
|
114
|
+
tokens.push({ source: node.metadata.original_name, generated: node.name, loc: node.loc });
|
|
150
115
|
} else {
|
|
151
|
-
|
|
152
|
-
const capitalizedName = capitalized_names.get(node.name);
|
|
153
|
-
if (capitalizedName) {
|
|
154
|
-
tokens.push({ source: node.name, generated: capitalizedName, loc: node.loc });
|
|
155
|
-
} else {
|
|
156
|
-
tokens.push({ source: node.name, generated: node.name, loc: node.loc });
|
|
157
|
-
}
|
|
116
|
+
tokens.push({ source: node.name, generated: node.name, loc: node.loc });
|
|
158
117
|
}
|
|
159
118
|
}
|
|
160
119
|
return; // Leaf node, don't traverse further
|
|
@@ -242,11 +201,18 @@ export function convert_source_map_to_mappings(ast, source, generated_code, esra
|
|
|
242
201
|
return;
|
|
243
202
|
} else if (node.type === 'JSXAttribute') {
|
|
244
203
|
// Visit name and value in source order
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
204
|
+
// For shorthand attributes ({ count }), key and value are the same node, only visit once
|
|
205
|
+
if (node.shorthand) {
|
|
206
|
+
if (node.value) {
|
|
207
|
+
visit(node.value);
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
if (node.name) {
|
|
211
|
+
visit(node.name);
|
|
212
|
+
}
|
|
213
|
+
if (node.value) {
|
|
214
|
+
visit(node.value);
|
|
215
|
+
}
|
|
250
216
|
}
|
|
251
217
|
return;
|
|
252
218
|
} else if (node.type === 'JSXSpreadAttribute') {
|
|
@@ -282,19 +248,10 @@ export function convert_source_map_to_mappings(ast, source, generated_code, esra
|
|
|
282
248
|
// 3. Push closing tag name (not visited by AST walker)
|
|
283
249
|
if (!node.openingElement?.selfClosing && node.closingElement?.name?.type === 'JSXIdentifier') {
|
|
284
250
|
const closingNameNode = node.closingElement.name;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const originalName = reverse_capitalized_names.get(closingName);
|
|
288
|
-
if (originalName) {
|
|
289
|
-
tokens.push({ source: originalName, generated: closingName, loc: closingNameNode.loc });
|
|
251
|
+
if (closingNameNode.metadata?.is_capitalized) {
|
|
252
|
+
tokens.push({ source: closingNameNode.metadata.original_name, generated: closingNameNode.name, loc: closingNameNode.loc });
|
|
290
253
|
} else {
|
|
291
|
-
|
|
292
|
-
const capitalizedName = capitalized_names.get(closingName);
|
|
293
|
-
if (capitalizedName) {
|
|
294
|
-
tokens.push({ source: closingName, generated: capitalizedName, loc: closingNameNode.loc });
|
|
295
|
-
} else {
|
|
296
|
-
tokens.push({ source: closingName, generated: closingName, loc: closingNameNode.loc });
|
|
297
|
-
}
|
|
254
|
+
tokens.push({ source: closingNameNode.name, generated: closingNameNode.name, loc: closingNameNode.loc });
|
|
298
255
|
}
|
|
299
256
|
}
|
|
300
257
|
|
|
@@ -175,7 +175,7 @@ export function bindValue(maybe_tracked) {
|
|
|
175
175
|
value = selected_option && get_option_value(selected_option);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
set(tracked, value
|
|
178
|
+
set(tracked, value);
|
|
179
179
|
});
|
|
180
180
|
|
|
181
181
|
effect(() => {
|
|
@@ -189,7 +189,7 @@ export function bindValue(maybe_tracked) {
|
|
|
189
189
|
var selected_option = select.querySelector(':checked');
|
|
190
190
|
if (selected_option !== null) {
|
|
191
191
|
value = get_option_value(selected_option);
|
|
192
|
-
set(tracked, value
|
|
192
|
+
set(tracked, value);
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -202,7 +202,7 @@ export function bindValue(maybe_tracked) {
|
|
|
202
202
|
/** @type {any} */
|
|
203
203
|
var value = input.value;
|
|
204
204
|
value = is_numberlike_input(input) ? to_number(value) : value;
|
|
205
|
-
set(tracked, value
|
|
205
|
+
set(tracked, value);
|
|
206
206
|
|
|
207
207
|
await tick();
|
|
208
208
|
|
|
@@ -254,7 +254,7 @@ export function bindChecked(maybe_tracked) {
|
|
|
254
254
|
|
|
255
255
|
return (input) => {
|
|
256
256
|
const clear_event = on(input, 'change', () => {
|
|
257
|
-
set(tracked, input.checked
|
|
257
|
+
set(tracked, input.checked);
|
|
258
258
|
});
|
|
259
259
|
|
|
260
260
|
return clear_event;
|
|
@@ -277,11 +277,11 @@ function bind_element_size(maybe_tracked, type) {
|
|
|
277
277
|
|
|
278
278
|
return (/** @type {HTMLElement} */ element) => {
|
|
279
279
|
var unsubscribe = resize_observer_border_box.observe(element, () =>
|
|
280
|
-
set(tracked, element[type]
|
|
280
|
+
set(tracked, element[type]),
|
|
281
281
|
);
|
|
282
282
|
|
|
283
283
|
effect(() => {
|
|
284
|
-
untrack(() => set(tracked, element[type]
|
|
284
|
+
untrack(() => set(tracked, element[type]));
|
|
285
285
|
return unsubscribe;
|
|
286
286
|
});
|
|
287
287
|
};
|
|
@@ -342,7 +342,7 @@ function bind_element_rect(maybe_tracked, type) {
|
|
|
342
342
|
return (/** @type {HTMLElement} */ element) => {
|
|
343
343
|
var unsubscribe = observer.observe(
|
|
344
344
|
element,
|
|
345
|
-
/** @param {any} entry */ (entry) => set(tracked, entry[type]
|
|
345
|
+
/** @param {any} entry */ (entry) => set(tracked, entry[type]),
|
|
346
346
|
);
|
|
347
347
|
|
|
348
348
|
effect(() => unsubscribe);
|
|
@@ -398,7 +398,7 @@ export function bind_content_editable(maybe_tracked, property) {
|
|
|
398
398
|
|
|
399
399
|
return (element) => {
|
|
400
400
|
const clear_event = on(element, 'input', () => {
|
|
401
|
-
set(tracked, element[property]
|
|
401
|
+
set(tracked, element[property]);
|
|
402
402
|
});
|
|
403
403
|
|
|
404
404
|
render(() => {
|
|
@@ -408,7 +408,7 @@ export function bind_content_editable(maybe_tracked, property) {
|
|
|
408
408
|
if (value == null) {
|
|
409
409
|
// @ts-ignore
|
|
410
410
|
var non_null_value = element[property];
|
|
411
|
-
set(tracked, non_null_value
|
|
411
|
+
set(tracked, non_null_value);
|
|
412
412
|
} else {
|
|
413
413
|
// @ts-ignore
|
|
414
414
|
element[property] = value + '';
|
|
@@ -186,7 +186,7 @@ function reconcile_fast_clear(anchor, block, array) {
|
|
|
186
186
|
* @returns {void}
|
|
187
187
|
*/
|
|
188
188
|
function update_index(block, index) {
|
|
189
|
-
set(block.s.i, index
|
|
189
|
+
set(block.s.i, index);
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
/**
|
|
@@ -195,7 +195,7 @@ function update_index(block, index) {
|
|
|
195
195
|
* @returns {void}
|
|
196
196
|
*/
|
|
197
197
|
function update_value(block, value) {
|
|
198
|
-
set(block.s.v, value
|
|
198
|
+
set(block.s.v, value);
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
/**
|
|
@@ -345,6 +345,9 @@ export function track(v, get, set, b) {
|
|
|
345
345
|
if (is_tracked_object(v)) {
|
|
346
346
|
return v;
|
|
347
347
|
}
|
|
348
|
+
if (b === null) {
|
|
349
|
+
throw new TypeError('track() requires a valid component context');
|
|
350
|
+
}
|
|
348
351
|
|
|
349
352
|
if (typeof v === 'function') {
|
|
350
353
|
return derived(v, b, get, set);
|
|
@@ -440,7 +443,7 @@ function is_tracking_dirty(tracking) {
|
|
|
440
443
|
var tracked = tracking.t;
|
|
441
444
|
|
|
442
445
|
if ((tracked.f & DERIVED) !== 0) {
|
|
443
|
-
update_derived(/** @type {Derived} **/(tracked));
|
|
446
|
+
update_derived(/** @type {Derived} **/ (tracked));
|
|
444
447
|
}
|
|
445
448
|
|
|
446
449
|
if (tracked.c > tracking.c) {
|
|
@@ -500,7 +503,7 @@ export function async_computed(fn, block) {
|
|
|
500
503
|
}
|
|
501
504
|
|
|
502
505
|
promise.then((v) => {
|
|
503
|
-
if (parent && is_destroyed(/** @type {Block} */(parent))) {
|
|
506
|
+
if (parent && is_destroyed(/** @type {Block} */ (parent))) {
|
|
504
507
|
return;
|
|
505
508
|
}
|
|
506
509
|
if (promise === current && t.__v !== v) {
|
|
@@ -509,7 +512,7 @@ export function async_computed(fn, block) {
|
|
|
509
512
|
if (t.__v === UNINITIALIZED) {
|
|
510
513
|
t.__v = v;
|
|
511
514
|
} else {
|
|
512
|
-
set(t, v
|
|
515
|
+
set(t, v);
|
|
513
516
|
}
|
|
514
517
|
}
|
|
515
518
|
|
|
@@ -774,7 +777,7 @@ export function get(tracked) {
|
|
|
774
777
|
}
|
|
775
778
|
|
|
776
779
|
return (tracked.f & DERIVED) !== 0
|
|
777
|
-
? get_derived(/** @type {Derived} */(tracked))
|
|
780
|
+
? get_derived(/** @type {Derived} */ (tracked))
|
|
778
781
|
: get_tracked(tracked);
|
|
779
782
|
}
|
|
780
783
|
|
|
@@ -803,15 +806,14 @@ export function get_tracked(tracked) {
|
|
|
803
806
|
* @param {any} value
|
|
804
807
|
*/
|
|
805
808
|
export function public_set(tracked, value) {
|
|
806
|
-
set(tracked, value
|
|
809
|
+
set(tracked, value);
|
|
807
810
|
}
|
|
808
811
|
|
|
809
812
|
/**
|
|
810
813
|
* @param {Derived | Tracked} tracked
|
|
811
814
|
* @param {any} value
|
|
812
|
-
* @param {Block} block
|
|
813
815
|
*/
|
|
814
|
-
export function set(tracked, value
|
|
816
|
+
export function set(tracked, value) {
|
|
815
817
|
if (!is_mutating_allowed) {
|
|
816
818
|
throw new Error(
|
|
817
819
|
'Assignments or updates to tracked values are not allowed during computed "track(() => ...)" evaluation',
|
|
@@ -823,7 +825,7 @@ export function set(tracked, value, block) {
|
|
|
823
825
|
if (value !== old_value) {
|
|
824
826
|
var tracked_block = tracked.b;
|
|
825
827
|
|
|
826
|
-
if ((
|
|
828
|
+
if ((tracked_block.f & CONTAINS_TEARDOWN) !== 0) {
|
|
827
829
|
if (teardown) {
|
|
828
830
|
old_values.set(tracked, value);
|
|
829
831
|
} else {
|
|
@@ -991,85 +993,78 @@ export function get_property(obj, property, chain = false) {
|
|
|
991
993
|
* @param {any} obj
|
|
992
994
|
* @param {string | number | symbol} property
|
|
993
995
|
* @param {any} value
|
|
994
|
-
* @param {Block} block
|
|
995
996
|
* @returns {void}
|
|
996
997
|
*/
|
|
997
|
-
export function set_property(obj, property, value
|
|
998
|
+
export function set_property(obj, property, value) {
|
|
998
999
|
var tracked = obj[property];
|
|
999
|
-
set(tracked, value
|
|
1000
|
+
set(tracked, value);
|
|
1000
1001
|
}
|
|
1001
1002
|
|
|
1002
1003
|
/**
|
|
1003
1004
|
* @param {Tracked} tracked
|
|
1004
|
-
* @param {Block} block
|
|
1005
1005
|
* @param {number} [d]
|
|
1006
1006
|
* @returns {number}
|
|
1007
1007
|
*/
|
|
1008
|
-
export function update(tracked,
|
|
1008
|
+
export function update(tracked, d = 1) {
|
|
1009
1009
|
var value = get(tracked);
|
|
1010
1010
|
var result = d === 1 ? value++ : value--;
|
|
1011
|
-
set(tracked, value
|
|
1011
|
+
set(tracked, value);
|
|
1012
1012
|
return result;
|
|
1013
1013
|
}
|
|
1014
1014
|
|
|
1015
1015
|
/**
|
|
1016
1016
|
* @param {Tracked} tracked
|
|
1017
|
-
* @param {Block} block
|
|
1018
1017
|
* @returns {void}
|
|
1019
1018
|
*/
|
|
1020
|
-
export function increment(tracked
|
|
1021
|
-
set(tracked, tracked.__v + 1
|
|
1019
|
+
export function increment(tracked) {
|
|
1020
|
+
set(tracked, tracked.__v + 1);
|
|
1022
1021
|
}
|
|
1023
1022
|
|
|
1024
1023
|
/**
|
|
1025
1024
|
* @param {Tracked} tracked
|
|
1026
|
-
* @param {Block} block
|
|
1027
1025
|
* @returns {void}
|
|
1028
1026
|
*/
|
|
1029
|
-
export function decrement(tracked
|
|
1030
|
-
set(tracked, tracked.__v - 1
|
|
1027
|
+
export function decrement(tracked) {
|
|
1028
|
+
set(tracked, tracked.__v - 1);
|
|
1031
1029
|
}
|
|
1032
1030
|
|
|
1033
1031
|
/**
|
|
1034
1032
|
* @param {Tracked} tracked
|
|
1035
|
-
* @param {Block} block
|
|
1036
1033
|
* @param {number} [d]
|
|
1037
1034
|
* @returns {number}
|
|
1038
1035
|
*/
|
|
1039
|
-
export function update_pre(tracked,
|
|
1036
|
+
export function update_pre(tracked, d = 1) {
|
|
1040
1037
|
var value = get(tracked);
|
|
1041
1038
|
var new_value = d === 1 ? ++value : --value;
|
|
1042
|
-
set(tracked, new_value
|
|
1039
|
+
set(tracked, new_value);
|
|
1043
1040
|
return new_value;
|
|
1044
1041
|
}
|
|
1045
1042
|
|
|
1046
1043
|
/**
|
|
1047
1044
|
* @param {any} obj
|
|
1048
1045
|
* @param {string | number | symbol} property
|
|
1049
|
-
* @param {Block} block
|
|
1050
1046
|
* @param {number} [d=1]
|
|
1051
1047
|
* @returns {number}
|
|
1052
1048
|
*/
|
|
1053
|
-
export function update_property(obj, property,
|
|
1049
|
+
export function update_property(obj, property, d = 1) {
|
|
1054
1050
|
var tracked = obj[property];
|
|
1055
1051
|
var value = get(tracked);
|
|
1056
1052
|
var new_value = d === 1 ? value++ : value--;
|
|
1057
|
-
set(tracked, value
|
|
1053
|
+
set(tracked, value);
|
|
1058
1054
|
return new_value;
|
|
1059
1055
|
}
|
|
1060
1056
|
|
|
1061
1057
|
/**
|
|
1062
1058
|
* @param {any} obj
|
|
1063
1059
|
* @param {string | number | symbol} property
|
|
1064
|
-
* @param {Block} block
|
|
1065
1060
|
* @param {number} [d=1]
|
|
1066
1061
|
* @returns {number}
|
|
1067
1062
|
*/
|
|
1068
|
-
export function update_pre_property(obj, property,
|
|
1063
|
+
export function update_pre_property(obj, property, d = 1) {
|
|
1069
1064
|
var tracked = obj[property];
|
|
1070
1065
|
var value = get(tracked);
|
|
1071
1066
|
var new_value = d === 1 ? ++value : --value;
|
|
1072
|
-
set(tracked, new_value
|
|
1067
|
+
set(tracked, new_value);
|
|
1073
1068
|
return new_value;
|
|
1074
1069
|
}
|
|
1075
1070
|
|
|
@@ -1093,7 +1088,7 @@ export function with_scope(block, fn) {
|
|
|
1093
1088
|
* @returns {Block | null}
|
|
1094
1089
|
*/
|
|
1095
1090
|
export function scope() {
|
|
1096
|
-
return active_scope;
|
|
1091
|
+
return active_scope || active_block;
|
|
1097
1092
|
}
|
|
1098
1093
|
|
|
1099
1094
|
/**
|
|
@@ -1206,7 +1201,7 @@ export async function maybe_tracked(v) {
|
|
|
1206
1201
|
} else {
|
|
1207
1202
|
value = await async_computed(async () => {
|
|
1208
1203
|
return await get_tracked(v);
|
|
1209
|
-
}, /** @type {Block} */(active_block));
|
|
1204
|
+
}, /** @type {Block} */ (active_block));
|
|
1210
1205
|
}
|
|
1211
1206
|
} else {
|
|
1212
1207
|
value = await v;
|
package/src/utils/builders.js
CHANGED
|
@@ -39,11 +39,15 @@ describe('basic client > get/set functions', () => {
|
|
|
39
39
|
let count = track(0);
|
|
40
40
|
|
|
41
41
|
<p>{get(count)}</p>
|
|
42
|
-
<button
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
<button
|
|
43
|
+
onClick={() => {
|
|
44
|
+
@count++;
|
|
45
|
+
@count++;
|
|
46
|
+
@count++;
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
{'increment'}
|
|
50
|
+
</button>
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
render(Test);
|
|
@@ -83,11 +87,15 @@ describe('basic client > get/set functions', () => {
|
|
|
83
87
|
let count = track(0);
|
|
84
88
|
|
|
85
89
|
<p>{get(count)}</p>
|
|
86
|
-
<button
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
<button
|
|
91
|
+
onClick={() => {
|
|
92
|
+
set(count, 5);
|
|
93
|
+
set(count, 15);
|
|
94
|
+
set(count, 25);
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
{'set multiple times'}
|
|
98
|
+
</button>
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
render(Test);
|
|
@@ -133,11 +141,15 @@ describe('basic client > get/set functions', () => {
|
|
|
133
141
|
let count = track(0);
|
|
134
142
|
|
|
135
143
|
<p>{get(count)}</p>
|
|
136
|
-
<button
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
<button
|
|
145
|
+
onClick={() => {
|
|
146
|
+
set(count, get(count) + 5);
|
|
147
|
+
set(count, get(count) + 15);
|
|
148
|
+
set(count, get(count) + 25);
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
{'add multiple times'}
|
|
152
|
+
</button>
|
|
141
153
|
}
|
|
142
154
|
|
|
143
155
|
render(Test);
|
|
@@ -158,11 +170,11 @@ describe('basic client > get/set functions', () => {
|
|
|
158
170
|
expect(p.textContent).toBe('90');
|
|
159
171
|
});
|
|
160
172
|
|
|
161
|
-
function store() {
|
|
162
|
-
return track(0);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
173
|
it('gets value declared outside Ripple component', () => {
|
|
174
|
+
function store() {
|
|
175
|
+
return track(0);
|
|
176
|
+
}
|
|
177
|
+
|
|
166
178
|
component Test() {
|
|
167
179
|
let count = store();
|
|
168
180
|
<p>{get(count)}</p>
|
|
@@ -175,6 +187,10 @@ describe('basic client > get/set functions', () => {
|
|
|
175
187
|
});
|
|
176
188
|
|
|
177
189
|
it('sets value declared outside Ripple component', () => {
|
|
190
|
+
function store() {
|
|
191
|
+
return track(0);
|
|
192
|
+
}
|
|
193
|
+
|
|
178
194
|
component Test() {
|
|
179
195
|
let count = store();
|
|
180
196
|
|
|
@@ -257,35 +273,7 @@ describe('basic client > get/set functions', () => {
|
|
|
257
273
|
expect(p.textContent).toBe('2');
|
|
258
274
|
});
|
|
259
275
|
|
|
260
|
-
it(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
component Test() {
|
|
264
|
-
<p>{get(count)}</p>
|
|
265
|
-
<button onClick={() => { set(count, get(count) + 1) }}>{'increment'}</button>
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
expect(get(count)).toBe(0);
|
|
269
|
-
|
|
270
|
-
render(Test);
|
|
271
|
-
|
|
272
|
-
const p = container.querySelector('p');
|
|
273
|
-
expect(p.textContent).toBe('0');
|
|
274
|
-
expect(get(count)).toBe(0);
|
|
275
|
-
|
|
276
|
-
const button = container.querySelector('button');
|
|
277
|
-
button.click();
|
|
278
|
-
flushSync();
|
|
279
|
-
|
|
280
|
-
expect(p.textContent).toBe('0');
|
|
281
|
-
expect(get(count)).toBe(1);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it('throws on trying to set a value outside Ripple component', () => {
|
|
285
|
-
let count = store();
|
|
286
|
-
|
|
287
|
-
expect(get(count)).toBe(0);
|
|
288
|
-
expect(() => set(count, 1)).toThrow();
|
|
289
|
-
expect(get(count)).toBe(0);
|
|
276
|
+
it('throws on trying to create tracked Ripple component', () => {
|
|
277
|
+
expect(() => track(0)).toThrow();
|
|
290
278
|
});
|
|
291
279
|
});
|
|
@@ -4,9 +4,9 @@ exports[`compiler > assignments > compiles tracked values in effect with assignm
|
|
|
4
4
|
|
|
5
5
|
exports[`compiler > assignments > compiles tracked values in effect with update expressions 1`] = `
|
|
6
6
|
"_$_.with_scope(__block, () => untrack(() => {
|
|
7
|
-
state.preIncrement = _$_.update_pre(count
|
|
8
|
-
state.postIncrement = _$_.update(count
|
|
9
|
-
state.preDecrement = _$_.update_pre(count,
|
|
10
|
-
state.postDecrement = _$_.update(count,
|
|
7
|
+
state.preIncrement = _$_.update_pre(count);
|
|
8
|
+
state.postIncrement = _$_.update(count);
|
|
9
|
+
state.preDecrement = _$_.update_pre(count, -1);
|
|
10
|
+
state.postDecrement = _$_.update(count, -1);
|
|
11
11
|
}));"
|
|
12
12
|
`;
|