ripple 0.2.216 → 0.3.0
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/CHANGELOG.md +39 -0
- package/package.json +16 -7
- package/src/compiler/errors.js +1 -1
- package/src/compiler/identifier-utils.js +2 -0
- package/src/compiler/index.d.ts +2 -6
- package/src/compiler/phases/1-parse/index.js +171 -233
- package/src/compiler/phases/2-analyze/index.js +192 -16
- package/src/compiler/phases/2-analyze/prune.js +2 -2
- package/src/compiler/phases/3-transform/client/index.js +308 -91
- package/src/compiler/phases/3-transform/segments.js +43 -15
- package/src/compiler/phases/3-transform/server/index.js +71 -21
- package/src/compiler/scope.js +31 -12
- package/src/compiler/source-map-utils.js +4 -6
- package/src/compiler/types/acorn.d.ts +11 -0
- package/src/compiler/types/estree-jsx.d.ts +11 -0
- package/src/compiler/types/estree.d.ts +11 -0
- package/src/compiler/types/import.d.ts +32 -18
- package/src/compiler/types/index.d.ts +75 -23
- package/src/compiler/types/parse.d.ts +7 -10
- package/src/compiler/utils.js +48 -0
- package/src/runtime/array.js +53 -22
- package/src/runtime/date.js +15 -5
- package/src/runtime/index-client.js +41 -7
- package/src/runtime/index-server.js +7 -7
- package/src/runtime/internal/client/bindings.js +2 -2
- package/src/runtime/internal/client/blocks.js +40 -1
- package/src/runtime/internal/client/context.js +8 -0
- package/src/runtime/internal/client/for.js +3 -3
- package/src/runtime/internal/client/index.js +32 -5
- package/src/runtime/internal/client/render.js +20 -8
- package/src/runtime/internal/client/runtime.js +9 -7
- package/src/runtime/internal/client/try.js +15 -22
- package/src/runtime/internal/client/utils.js +1 -1
- package/src/runtime/internal/server/context.js +8 -0
- package/src/runtime/internal/server/index.js +99 -6
- package/src/runtime/map.js +7 -7
- package/src/runtime/media-query.js +10 -1
- package/src/runtime/object.js +6 -6
- package/src/runtime/proxy.js +6 -6
- package/src/runtime/set.js +11 -11
- package/src/runtime/url-search-params.js +13 -2
- package/src/runtime/url.js +15 -5
- package/src/utils/builders.js +13 -3
- package/tests/client/array/array.copy-within.test.ripple +11 -11
- package/tests/client/array/array.derived.test.ripple +42 -42
- package/tests/client/array/array.iteration.test.ripple +12 -12
- package/tests/client/array/array.mutations.test.ripple +25 -25
- package/tests/client/array/array.static.test.ripple +103 -106
- package/tests/client/array/array.to-methods.test.ripple +8 -8
- package/tests/client/async-suspend.test.ripple +94 -0
- package/tests/client/basic/basic.attributes.test.ripple +31 -31
- package/tests/client/basic/basic.collections.test.ripple +7 -7
- package/tests/client/basic/basic.components.test.ripple +48 -10
- package/tests/client/basic/basic.errors.test.ripple +46 -31
- package/tests/client/basic/basic.events.test.ripple +11 -11
- package/tests/client/basic/basic.get-set.test.ripple +18 -18
- package/tests/client/basic/basic.reactivity.test.ripple +47 -42
- package/tests/client/basic/basic.rendering.test.ripple +7 -7
- package/tests/client/basic/basic.utilities.test.ripple +4 -4
- package/tests/client/boundaries.test.ripple +7 -7
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +2 -2
- package/tests/client/compiler/compiler.assignments.test.ripple +21 -21
- package/tests/client/compiler/compiler.basic.test.ripple +223 -82
- package/tests/client/compiler/compiler.tracked-access.test.ripple +8 -9
- package/tests/client/composite/composite.dynamic-components.test.ripple +8 -8
- package/tests/client/composite/composite.generics.test.ripple +4 -4
- package/tests/client/composite/composite.props.test.ripple +9 -9
- package/tests/client/composite/composite.reactivity.test.ripple +32 -26
- package/tests/client/composite/composite.render.test.ripple +13 -4
- package/tests/client/computed-properties.test.ripple +3 -3
- package/tests/client/context.test.ripple +3 -3
- package/tests/client/css/global-additional-cases.test.ripple +4 -4
- package/tests/client/css/style-identifier.test.ripple +49 -41
- package/tests/client/date.test.ripple +40 -40
- package/tests/client/dynamic-elements.test.ripple +165 -30
- package/tests/client/events.test.ripple +25 -25
- package/tests/client/for.test.ripple +76 -8
- package/tests/client/function-overload.test.ripple +0 -1
- package/tests/client/head.test.ripple +7 -7
- package/tests/client/html.test.ripple +2 -2
- package/tests/client/input-value.test.ripple +174 -176
- package/tests/client/map.test.ripple +21 -21
- package/tests/client/media-query.test.ripple +4 -4
- package/tests/client/object.test.ripple +12 -12
- package/tests/client/portal.test.ripple +4 -4
- package/tests/client/ref.test.ripple +5 -5
- package/tests/client/return.test.ripple +17 -17
- package/tests/client/set.test.ripple +16 -16
- package/tests/client/svg.test.ripple +6 -7
- package/tests/client/switch.test.ripple +10 -10
- package/tests/client/tracked-expression.test.ripple +1 -3
- package/tests/client/try.test.ripple +33 -4
- package/tests/client/url/url.derived.test.ripple +10 -9
- package/tests/client/url/url.parsing.test.ripple +10 -10
- package/tests/client/url/url.partial-removal.test.ripple +10 -10
- package/tests/client/url/url.reactivity.test.ripple +17 -17
- package/tests/client/url/url.serialization.test.ripple +4 -4
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +11 -10
- package/tests/client/url-search-params/url-search-params.initialization.test.ripple +5 -7
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +13 -13
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +19 -19
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +17 -17
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +5 -5
- package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +5 -5
- package/tests/hydration/compiled/client/events.js +8 -11
- package/tests/hydration/compiled/client/for.js +20 -23
- package/tests/hydration/compiled/client/head.js +17 -19
- package/tests/hydration/compiled/client/hmr.js +1 -3
- package/tests/hydration/compiled/client/html.js +1 -15
- package/tests/hydration/compiled/client/if-children.js +7 -9
- package/tests/hydration/compiled/client/if.js +5 -7
- package/tests/hydration/compiled/client/mixed-control-flow.js +3 -5
- package/tests/hydration/compiled/client/portal.js +1 -1
- package/tests/hydration/compiled/client/reactivity.js +9 -11
- package/tests/hydration/compiled/client/return.js +11 -13
- package/tests/hydration/compiled/client/switch.js +4 -6
- package/tests/hydration/compiled/server/basic.js +0 -1
- package/tests/hydration/compiled/server/composite.js +0 -3
- package/tests/hydration/compiled/server/events.js +8 -12
- package/tests/hydration/compiled/server/for.js +20 -23
- package/tests/hydration/compiled/server/head.js +17 -19
- package/tests/hydration/compiled/server/hmr.js +1 -4
- package/tests/hydration/compiled/server/html.js +1 -35
- package/tests/hydration/compiled/server/if-children.js +7 -11
- package/tests/hydration/compiled/server/if.js +5 -7
- package/tests/hydration/compiled/server/mixed-control-flow.js +3 -5
- package/tests/hydration/compiled/server/portal.js +1 -9
- package/tests/hydration/compiled/server/reactivity.js +9 -11
- package/tests/hydration/compiled/server/return.js +11 -13
- package/tests/hydration/compiled/server/switch.js +4 -6
- package/tests/hydration/components/events.ripple +8 -9
- package/tests/hydration/components/for.ripple +20 -21
- package/tests/hydration/components/head.ripple +6 -8
- package/tests/hydration/components/hmr.ripple +1 -2
- package/tests/hydration/components/html.ripple +1 -3
- package/tests/hydration/components/if-children.ripple +7 -8
- package/tests/hydration/components/if.ripple +5 -6
- package/tests/hydration/components/mixed-control-flow.ripple +4 -6
- package/tests/hydration/components/portal.ripple +1 -1
- package/tests/hydration/components/reactivity.ripple +9 -10
- package/tests/hydration/components/return.ripple +11 -12
- package/tests/hydration/components/switch.ripple +6 -8
- package/tests/server/await.test.ripple +2 -2
- package/tests/server/basic.attributes.test.ripple +19 -21
- package/tests/server/basic.components.test.ripple +13 -7
- package/tests/server/basic.test.ripple +20 -21
- package/tests/server/compiler.test.ripple +5 -5
- package/tests/server/composite.props.test.ripple +6 -7
- package/tests/server/composite.test.ripple +4 -4
- package/tests/server/context.test.ripple +1 -3
- package/tests/server/dynamic-elements.test.ripple +24 -24
- package/tests/server/head.test.ripple +5 -7
- package/tests/server/style-identifier.test.ripple +16 -17
- package/types/index.d.ts +266 -62
- package/types/server.d.ts +6 -6
|
@@ -56,9 +56,11 @@ import {
|
|
|
56
56
|
is_inside_left_side_assignment,
|
|
57
57
|
hash,
|
|
58
58
|
flatten_switch_consequent,
|
|
59
|
+
get_ripple_namespace_call_name,
|
|
59
60
|
} from '../../../utils.js';
|
|
60
61
|
import {
|
|
61
62
|
CSS_HASH_IDENTIFIER,
|
|
63
|
+
RIPPLE_NAMESPACE_IDENTIFIER,
|
|
62
64
|
STYLE_IDENTIFIER,
|
|
63
65
|
SERVER_IDENTIFIER,
|
|
64
66
|
obfuscate_identifier,
|
|
@@ -343,10 +345,13 @@ function visit_title_element(node, context) {
|
|
|
343
345
|
/**
|
|
344
346
|
* @param {string} name
|
|
345
347
|
* @param {TransformClientContext} context
|
|
348
|
+
* @param {boolean} [is_obfuscated]
|
|
346
349
|
* @returns {string}
|
|
347
350
|
*/
|
|
348
|
-
function set_hidden_import_from_ripple(name, context) {
|
|
349
|
-
|
|
351
|
+
function set_hidden_import_from_ripple(name, context, is_obfuscated = false) {
|
|
352
|
+
if (!is_obfuscated) {
|
|
353
|
+
name = obfuscate_identifier(name);
|
|
354
|
+
}
|
|
350
355
|
if (!context.state.imports.has(`import { ${name} } from 'ripple/compiler/internal/import'`)) {
|
|
351
356
|
context.state.imports.add(`import { ${name} } from 'ripple/compiler/internal/import'`);
|
|
352
357
|
}
|
|
@@ -354,6 +359,64 @@ function set_hidden_import_from_ripple(name, context) {
|
|
|
354
359
|
return name;
|
|
355
360
|
}
|
|
356
361
|
|
|
362
|
+
/**
|
|
363
|
+
* @param {AST.NodeWithLocation} loc_info
|
|
364
|
+
* @param {number} [start_offset]
|
|
365
|
+
* @param {number} [length]
|
|
366
|
+
* @returns {AST.NodeWithLocation}
|
|
367
|
+
*/
|
|
368
|
+
function slice_loc_info(loc_info, start_offset = 0, length) {
|
|
369
|
+
if (length === undefined) {
|
|
370
|
+
length = loc_info.end - loc_info.start - start_offset;
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
start: loc_info.start + start_offset,
|
|
374
|
+
end: loc_info.start + start_offset + length,
|
|
375
|
+
loc: {
|
|
376
|
+
start: {
|
|
377
|
+
line: loc_info.loc.start.line,
|
|
378
|
+
column: loc_info.loc.start.column + start_offset,
|
|
379
|
+
},
|
|
380
|
+
end: {
|
|
381
|
+
line: loc_info.loc.start.line,
|
|
382
|
+
column: loc_info.loc.start.column + start_offset + length,
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* @param {string} property_name
|
|
390
|
+
* @param {string} source_name
|
|
391
|
+
* @param {AST.NodeWithLocation} loc_info
|
|
392
|
+
* @param {TransformClientContext} context
|
|
393
|
+
* @returns {AST.MemberExpression}
|
|
394
|
+
*/
|
|
395
|
+
function build_ripple_namespace_member(property_name, source_name, loc_info, context) {
|
|
396
|
+
const namespace_alias = set_hidden_import_from_ripple(RIPPLE_NAMESPACE_IDENTIFIER, context, true);
|
|
397
|
+
const namespace_loc = slice_loc_info(loc_info, 0, '#ripple'.length);
|
|
398
|
+
const namespace_id = b.id(namespace_alias, namespace_loc);
|
|
399
|
+
namespace_id.metadata.source_name = '#ripple';
|
|
400
|
+
|
|
401
|
+
const property_loc = slice_loc_info(loc_info, '#ripple.'.length, property_name.length);
|
|
402
|
+
const property_id = b.id(property_name, property_loc);
|
|
403
|
+
|
|
404
|
+
return b.member(namespace_id, property_id, false, false, loc_info);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* @param {string | undefined} name
|
|
409
|
+
* @returns {boolean}
|
|
410
|
+
*/
|
|
411
|
+
function ripple_namespace_requires_block(name) {
|
|
412
|
+
return (
|
|
413
|
+
name !== undefined &&
|
|
414
|
+
name !== '#ripple.effect' &&
|
|
415
|
+
name !== '#ripple.untrack' &&
|
|
416
|
+
name !== '#ripple.context'
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
357
420
|
/**
|
|
358
421
|
* @param {TransformClientContext} context
|
|
359
422
|
* @param {Partial<TransformClientState>} [more_state]
|
|
@@ -404,6 +467,17 @@ const visitors = {
|
|
|
404
467
|
|
|
405
468
|
if (is_reference(node, parent)) {
|
|
406
469
|
if (context.state.to_ts) {
|
|
470
|
+
if (node.metadata?.source_name === '#ripple' || node.name === '#ripple') {
|
|
471
|
+
const namespace_alias = set_hidden_import_from_ripple(
|
|
472
|
+
RIPPLE_NAMESPACE_IDENTIFIER,
|
|
473
|
+
context,
|
|
474
|
+
true,
|
|
475
|
+
);
|
|
476
|
+
const namespace_id = b.id(namespace_alias, /** @type {AST.NodeWithLocation} */ (node));
|
|
477
|
+
namespace_id.metadata.source_name = '#ripple';
|
|
478
|
+
return namespace_id;
|
|
479
|
+
}
|
|
480
|
+
|
|
407
481
|
if (node.tracked) {
|
|
408
482
|
// Check if this identifier is used as a dynamic component/element
|
|
409
483
|
// by checking if it has a capitalized name in metadata
|
|
@@ -468,13 +542,13 @@ const visitors = {
|
|
|
468
542
|
|
|
469
543
|
ServerIdentifier(node, context) {
|
|
470
544
|
const id = b.id(SERVER_IDENTIFIER);
|
|
471
|
-
id.metadata.source_name = '#server';
|
|
545
|
+
id.metadata.source_name = '#ripple.server';
|
|
472
546
|
return { ...node, ...id };
|
|
473
547
|
},
|
|
474
548
|
|
|
475
549
|
StyleIdentifier(node, context) {
|
|
476
550
|
const id = b.id(STYLE_IDENTIFIER);
|
|
477
|
-
id.metadata.source_name = '#style';
|
|
551
|
+
id.metadata.source_name = '#ripple.style';
|
|
478
552
|
return { ...node, ...id };
|
|
479
553
|
},
|
|
480
554
|
|
|
@@ -529,12 +603,55 @@ const visitors = {
|
|
|
529
603
|
}
|
|
530
604
|
const callee = node.callee;
|
|
531
605
|
const parent = context.path.at(-1);
|
|
606
|
+
const source_name = callee.type === 'Identifier' ? callee.metadata?.source_name : undefined;
|
|
607
|
+
const ripple_runtime_method = get_ripple_namespace_call_name(source_name);
|
|
608
|
+
const ripple_method_requires_block = ripple_namespace_requires_block(source_name);
|
|
532
609
|
|
|
533
610
|
if (context.state.metadata?.tracking === false) {
|
|
534
611
|
context.state.metadata.tracking = true;
|
|
535
612
|
}
|
|
536
613
|
|
|
614
|
+
if (!context.state.to_ts && ripple_runtime_method !== null) {
|
|
615
|
+
return {
|
|
616
|
+
...node,
|
|
617
|
+
callee: b.member(b.id('_$_'), b.id(ripple_runtime_method)),
|
|
618
|
+
arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ ([
|
|
619
|
+
...(ripple_method_requires_block ? [b.id('__block')] : []),
|
|
620
|
+
...node.arguments.map((arg) => context.visit(arg)),
|
|
621
|
+
]),
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (context.state.to_ts && source_name?.startsWith('#ripple.')) {
|
|
626
|
+
const property_name = source_name.replace('#ripple.', '');
|
|
627
|
+
const namespace_member = build_ripple_namespace_member(
|
|
628
|
+
property_name,
|
|
629
|
+
source_name,
|
|
630
|
+
/** @type {AST.NodeWithLocation} */ (callee),
|
|
631
|
+
context,
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
return {
|
|
635
|
+
...node,
|
|
636
|
+
callee: namespace_member,
|
|
637
|
+
arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ (
|
|
638
|
+
node.arguments.map((arg) => context.visit(arg))
|
|
639
|
+
),
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
|
|
537
643
|
if (!context.state.to_ts && is_ripple_track_call(callee, context)) {
|
|
644
|
+
const track_method_name =
|
|
645
|
+
callee.type === 'Identifier'
|
|
646
|
+
? callee.name === 'trackSplit'
|
|
647
|
+
? 'track_split'
|
|
648
|
+
: 'track'
|
|
649
|
+
: callee.type === 'MemberExpression' && callee.property.type === 'Identifier'
|
|
650
|
+
? callee.property.name === 'trackSplit'
|
|
651
|
+
? 'track_split'
|
|
652
|
+
: 'track'
|
|
653
|
+
: 'track';
|
|
654
|
+
|
|
538
655
|
if (callee.type === 'Identifier' && callee.name === 'track') {
|
|
539
656
|
if (node.arguments.length === 0) {
|
|
540
657
|
node.arguments.push(b.void0, b.void0, b.void0);
|
|
@@ -546,6 +663,7 @@ const visitors = {
|
|
|
546
663
|
}
|
|
547
664
|
return {
|
|
548
665
|
...node,
|
|
666
|
+
callee: b.member(b.id('_$_'), b.id(track_method_name)),
|
|
549
667
|
arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ ([
|
|
550
668
|
...node.arguments.map((arg) => context.visit(arg)),
|
|
551
669
|
b.id('__block'),
|
|
@@ -553,6 +671,63 @@ const visitors = {
|
|
|
553
671
|
};
|
|
554
672
|
}
|
|
555
673
|
|
|
674
|
+
// Check for more than two nested level calls, like #ripple.array.from()
|
|
675
|
+
if (
|
|
676
|
+
callee.type === 'MemberExpression' &&
|
|
677
|
+
callee.object.metadata?.source_name?.startsWith('#ripple.') &&
|
|
678
|
+
callee.object.type === 'Identifier' &&
|
|
679
|
+
callee.property.type === 'Identifier'
|
|
680
|
+
) {
|
|
681
|
+
const object = callee.object;
|
|
682
|
+
const property = callee.property;
|
|
683
|
+
const source_name = /** @type {string} */ (object.metadata?.source_name);
|
|
684
|
+
const property_name = source_name.replace('#ripple.', '');
|
|
685
|
+
|
|
686
|
+
if (context.state.to_ts) {
|
|
687
|
+
// e.g. `#ripple.array`
|
|
688
|
+
const namespace_member = build_ripple_namespace_member(
|
|
689
|
+
property_name,
|
|
690
|
+
source_name,
|
|
691
|
+
/** @type {AST.NodeWithLocation} */ (node.callee),
|
|
692
|
+
context,
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
return /** @type {AST.CallExpression} */ ({
|
|
696
|
+
...node,
|
|
697
|
+
callee: {
|
|
698
|
+
...namespace_member,
|
|
699
|
+
// e.g. `array.from`
|
|
700
|
+
property: b.member(
|
|
701
|
+
/** @type {AST.Identifier} */ (namespace_member.property),
|
|
702
|
+
property,
|
|
703
|
+
false,
|
|
704
|
+
false,
|
|
705
|
+
slice_loc_info(/** @type {AST.NodeWithLocation} */ (node.callee), '#ripple.'.length),
|
|
706
|
+
),
|
|
707
|
+
},
|
|
708
|
+
arguments: node.arguments.map((arg) => context.visit(arg)),
|
|
709
|
+
});
|
|
710
|
+
} else {
|
|
711
|
+
const method_name = get_ripple_namespace_call_name(source_name);
|
|
712
|
+
const requires_block = ripple_namespace_requires_block(source_name);
|
|
713
|
+
if (method_name !== null) {
|
|
714
|
+
return b.member(
|
|
715
|
+
b.id('_$_'),
|
|
716
|
+
b.member(
|
|
717
|
+
b.id(method_name),
|
|
718
|
+
b.call(
|
|
719
|
+
b.id(property.name),
|
|
720
|
+
.../** @type {(AST.Expression | AST.SpreadElement)[]} */ ([
|
|
721
|
+
...(requires_block ? [b.id('__block')] : []),
|
|
722
|
+
...node.arguments.map((arg) => context.visit(arg)),
|
|
723
|
+
]),
|
|
724
|
+
),
|
|
725
|
+
),
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
556
731
|
if (
|
|
557
732
|
!is_inside_component(context, true) ||
|
|
558
733
|
context.state.to_ts ||
|
|
@@ -630,43 +805,6 @@ const visitors = {
|
|
|
630
805
|
context.state.metadata.tracking = true;
|
|
631
806
|
}
|
|
632
807
|
|
|
633
|
-
// Special handling for TrackedMapExpression and TrackedSetExpression
|
|
634
|
-
// When source is "new #Map(...)" or "new #Map<K,V>(...)", the callee is TrackedMapExpression
|
|
635
|
-
// with empty arguments and the actual arguments are in NewExpression.arguments
|
|
636
|
-
if (callee.type === 'TrackedMapExpression' || callee.type === 'TrackedSetExpression') {
|
|
637
|
-
// Use NewExpression's arguments (the callee has empty arguments from parser)
|
|
638
|
-
const argsToUse = node.arguments.length > 0 ? node.arguments : callee.arguments;
|
|
639
|
-
|
|
640
|
-
if (context.state.to_ts) {
|
|
641
|
-
const className = callee.type === 'TrackedMapExpression' ? 'TrackedMap' : 'TrackedSet';
|
|
642
|
-
const alias = set_hidden_import_from_ripple(className, context);
|
|
643
|
-
const calleeId = b.id(alias);
|
|
644
|
-
calleeId.loc = callee.loc;
|
|
645
|
-
calleeId.metadata = {
|
|
646
|
-
source_name: callee.type === 'TrackedMapExpression' ? '#Map' : '#Set',
|
|
647
|
-
path: [...context.path],
|
|
648
|
-
};
|
|
649
|
-
/** @type {AST.NewExpression} */
|
|
650
|
-
const newExpr = b.new(
|
|
651
|
-
calleeId,
|
|
652
|
-
/** @type {AST.NodeWithLocation} */ (node),
|
|
653
|
-
.../** @type {AST.Expression[]} */ (argsToUse.map((arg) => context.visit(arg))),
|
|
654
|
-
);
|
|
655
|
-
// Preserve typeArguments for generics syntax like new #Map<string, number>()
|
|
656
|
-
if (node.typeArguments) {
|
|
657
|
-
newExpr.typeArguments = node.typeArguments;
|
|
658
|
-
}
|
|
659
|
-
return newExpr;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
const helperName = callee.type === 'TrackedMapExpression' ? 'tracked_map' : 'tracked_set';
|
|
663
|
-
return b.call(
|
|
664
|
-
`_$_.${helperName}`,
|
|
665
|
-
b.id('__block'),
|
|
666
|
-
.../** @type {AST.Expression[]} */ (argsToUse.map((arg) => context.visit(arg))),
|
|
667
|
-
);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
808
|
if (
|
|
671
809
|
context.state.to_ts ||
|
|
672
810
|
!is_inside_component(context, true) ||
|
|
@@ -695,54 +833,67 @@ const visitors = {
|
|
|
695
833
|
return b.call('_$_.with_scope', b.id('__block'), b.thunk(new_node));
|
|
696
834
|
},
|
|
697
835
|
|
|
698
|
-
|
|
836
|
+
RippleArrayExpression(node, context) {
|
|
699
837
|
if (context.state.to_ts) {
|
|
700
|
-
const arrayAlias = set_hidden_import_from_ripple('
|
|
838
|
+
const arrayAlias = set_hidden_import_from_ripple('RippleArray', context);
|
|
839
|
+
const id = b.id(
|
|
840
|
+
arrayAlias,
|
|
841
|
+
slice_loc_info(/** @type {AST.NodeWithLocation} */ (node), 0, '#ripple'.length),
|
|
842
|
+
);
|
|
843
|
+
id.metadata.source_name = '#ripple';
|
|
701
844
|
|
|
702
|
-
return
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
),
|
|
845
|
+
return {
|
|
846
|
+
type: 'NewExpression',
|
|
847
|
+
callee: id,
|
|
848
|
+
arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ (
|
|
849
|
+
node.elements.map((el) => context.visit(/** @type {AST.Node} */ (el)))
|
|
708
850
|
),
|
|
709
|
-
|
|
851
|
+
metadata: { path: [] },
|
|
852
|
+
};
|
|
710
853
|
}
|
|
711
854
|
|
|
712
855
|
return b.call(
|
|
713
|
-
'_$_.
|
|
714
|
-
b.array(
|
|
715
|
-
/** @type {(AST.Expression | AST.SpreadElement)[]} */ (
|
|
716
|
-
node.elements.map((el) => context.visit(/** @type {AST.Node} */ (el)))
|
|
717
|
-
),
|
|
718
|
-
),
|
|
856
|
+
'_$_.ripple_array',
|
|
719
857
|
b.id('__block'),
|
|
858
|
+
.../** @type {(AST.Expression | AST.SpreadElement)[]} */ (
|
|
859
|
+
node.elements.map((el) => context.visit(/** @type {AST.Node} */ (el)))
|
|
860
|
+
),
|
|
720
861
|
);
|
|
721
862
|
},
|
|
722
863
|
|
|
723
|
-
|
|
864
|
+
RippleObjectExpression(node, context) {
|
|
724
865
|
if (context.state.to_ts) {
|
|
725
|
-
const objectAlias = set_hidden_import_from_ripple('
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
866
|
+
const objectAlias = set_hidden_import_from_ripple('RippleObject', context);
|
|
867
|
+
const id = b.id(
|
|
868
|
+
objectAlias,
|
|
869
|
+
slice_loc_info(/** @type {AST.NodeWithLocation} */ (node), 0, '#ripple'.length),
|
|
870
|
+
);
|
|
871
|
+
id.metadata.source_name = '#ripple';
|
|
872
|
+
const new_node = b.new(
|
|
873
|
+
id,
|
|
729
874
|
/** @type {AST.NodeWithLocation} */ (node),
|
|
730
875
|
b.object(
|
|
731
876
|
/** @type {(AST.Property | AST.SpreadElement)[]} */ (
|
|
732
877
|
node.properties.map((prop) => context.visit(prop))
|
|
733
878
|
),
|
|
879
|
+
slice_loc_info(/** @type {AST.NodeWithLocation} */ (node), '#ripple'.length),
|
|
734
880
|
),
|
|
735
881
|
);
|
|
882
|
+
// force the source mapping to skip the constructor,
|
|
883
|
+
// otherwise the mapping will be off by 4 and the whole
|
|
884
|
+
// new expression will be mapped to the source which doesn't have `new `
|
|
885
|
+
new_node.metadata.skipNewMapping = true;
|
|
886
|
+
return new_node;
|
|
736
887
|
}
|
|
737
888
|
|
|
738
889
|
return b.call(
|
|
739
|
-
'_$_.
|
|
890
|
+
'_$_.ripple_object',
|
|
891
|
+
b.id('__block'),
|
|
740
892
|
b.object(
|
|
741
893
|
/** @type {(AST.Property | AST.SpreadElement)[]} */ (
|
|
742
894
|
node.properties.map((prop) => context.visit(prop))
|
|
743
895
|
),
|
|
744
896
|
),
|
|
745
|
-
b.id('__block'),
|
|
746
897
|
);
|
|
747
898
|
},
|
|
748
899
|
|
|
@@ -1380,12 +1531,15 @@ const visitors = {
|
|
|
1380
1531
|
);
|
|
1381
1532
|
} else if (attr.type === 'RefAttribute') {
|
|
1382
1533
|
const id = state.flush_node?.();
|
|
1534
|
+
const metadata = { tracking: false, await: false };
|
|
1383
1535
|
state.init?.push(
|
|
1384
1536
|
b.stmt(
|
|
1385
1537
|
b.call(
|
|
1386
1538
|
'_$_.ref',
|
|
1387
1539
|
id,
|
|
1388
|
-
b.thunk(
|
|
1540
|
+
b.thunk(
|
|
1541
|
+
/** @type {AST.Expression} */ (visit(attr.argument, { ...state, metadata })),
|
|
1542
|
+
),
|
|
1389
1543
|
),
|
|
1390
1544
|
),
|
|
1391
1545
|
);
|
|
@@ -1609,12 +1763,13 @@ const visitors = {
|
|
|
1609
1763
|
);
|
|
1610
1764
|
} else if (attr.type === 'RefAttribute') {
|
|
1611
1765
|
const ref_id = state.scope.generate('ref');
|
|
1766
|
+
const metadata = { tracking: false, await: false };
|
|
1612
1767
|
state.init?.push(b.var(ref_id, b.call('_$_.ref_prop')));
|
|
1613
1768
|
props.push(
|
|
1614
1769
|
b.prop(
|
|
1615
1770
|
'init',
|
|
1616
1771
|
b.id(ref_id),
|
|
1617
|
-
/** @type {AST.Expression} */ (visit(attr.argument, state)),
|
|
1772
|
+
/** @type {AST.Expression} */ (visit(attr.argument, { ...state, metadata })),
|
|
1618
1773
|
true,
|
|
1619
1774
|
),
|
|
1620
1775
|
);
|
|
@@ -2213,10 +2368,15 @@ const visitors = {
|
|
|
2213
2368
|
let alternate_id;
|
|
2214
2369
|
|
|
2215
2370
|
if (node.alternate !== null) {
|
|
2216
|
-
const alternate = /** @type {AST.
|
|
2371
|
+
const alternate = /** @type {AST.Statement} */ (node.alternate);
|
|
2217
2372
|
const alternate_scope = context.state.scopes.get(alternate) || context.state.scope;
|
|
2218
2373
|
/** @type {AST.Node[]} */
|
|
2219
|
-
let alternate_body =
|
|
2374
|
+
let alternate_body =
|
|
2375
|
+
alternate.type === 'IfStatement'
|
|
2376
|
+
? [alternate]
|
|
2377
|
+
: alternate.type === 'BlockStatement'
|
|
2378
|
+
? alternate.body
|
|
2379
|
+
: [alternate];
|
|
2220
2380
|
const alternate_block = b.block(
|
|
2221
2381
|
transform_body(alternate_body, {
|
|
2222
2382
|
...context,
|
|
@@ -2494,8 +2654,8 @@ const visitors = {
|
|
|
2494
2654
|
|
|
2495
2655
|
const server_identifier = b.id(SERVER_IDENTIFIER);
|
|
2496
2656
|
server_identifier.loc = node.loc;
|
|
2497
|
-
// Add source_name to properly map longer generated back to '#server'
|
|
2498
|
-
server_identifier.metadata.source_name = '#server';
|
|
2657
|
+
// Add source_name to properly map longer generated back to '#ripple.server'
|
|
2658
|
+
server_identifier.metadata.source_name = '#ripple.server';
|
|
2499
2659
|
|
|
2500
2660
|
const server_const = b.const(server_identifier, value);
|
|
2501
2661
|
server_const.loc = node.loc;
|
|
@@ -2504,7 +2664,7 @@ const visitors = {
|
|
|
2504
2664
|
}
|
|
2505
2665
|
|
|
2506
2666
|
if (!context.state.serverIdentifierPresent) {
|
|
2507
|
-
// no point printing the client-side block if #server.func is not used
|
|
2667
|
+
// no point printing the client-side block if #ripple.server.func is not used
|
|
2508
2668
|
return b.empty;
|
|
2509
2669
|
}
|
|
2510
2670
|
|
|
@@ -2707,12 +2867,42 @@ function transform_ts_child(node, context) {
|
|
|
2707
2867
|
if (!node.selfClosing && !node.unclosed && !has_children_props && node.children.length > 0) {
|
|
2708
2868
|
const is_dom_element = is_element_dom_element(node);
|
|
2709
2869
|
const component_scope = /** @type {ScopeInterface} */ (context.state.scopes.get(node));
|
|
2870
|
+
/** @type {AST.Node[]} */
|
|
2871
|
+
const non_component_children = [];
|
|
2872
|
+
|
|
2873
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2874
|
+
const child = node.children[i];
|
|
2875
|
+
if (!is_dom_element && child.type === 'Component' && child.id) {
|
|
2876
|
+
const transformed_component = /** @type {AST.FunctionDeclaration} */ (
|
|
2877
|
+
visit(child, {
|
|
2878
|
+
...state,
|
|
2879
|
+
scope: component_scope,
|
|
2880
|
+
metadata: { await: false },
|
|
2881
|
+
})
|
|
2882
|
+
);
|
|
2883
|
+
const func = b.arrow(
|
|
2884
|
+
transformed_component.params,
|
|
2885
|
+
transformed_component.body,
|
|
2886
|
+
transformed_component.async,
|
|
2887
|
+
);
|
|
2888
|
+
func.metadata = { ...func.metadata, is_component: true };
|
|
2889
|
+
const id = b.jsx_id(
|
|
2890
|
+
/** @type {AST.Identifier} */ (child.id).name,
|
|
2891
|
+
/** @type {AST.NodeWithLocation} */ (child.id),
|
|
2892
|
+
);
|
|
2893
|
+
id.metadata = { ...id.metadata, is_component: true };
|
|
2894
|
+
attributes.push(b.jsx_attribute(id, b.jsx_expression_container(func)));
|
|
2895
|
+
} else {
|
|
2896
|
+
non_component_children.push(child);
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2710
2899
|
const thunk =
|
|
2711
|
-
/** @type {AST.Identifier} */ (node.id).name === 'style'
|
|
2900
|
+
/** @type {AST.Identifier} */ (node.id).name === 'style' ||
|
|
2901
|
+
non_component_children.length === 0
|
|
2712
2902
|
? null
|
|
2713
2903
|
: b.thunk(
|
|
2714
2904
|
b.block(
|
|
2715
|
-
transform_body(
|
|
2905
|
+
transform_body(non_component_children, {
|
|
2716
2906
|
...context,
|
|
2717
2907
|
state: {
|
|
2718
2908
|
...state,
|
|
@@ -2795,10 +2985,14 @@ function transform_ts_child(node, context) {
|
|
|
2795
2985
|
let alternate;
|
|
2796
2986
|
|
|
2797
2987
|
if (node.alternate !== null) {
|
|
2798
|
-
const alternate_node = /** @type {AST.
|
|
2988
|
+
const alternate_node = /** @type {AST.Statement} */ (node.alternate);
|
|
2799
2989
|
const alternate_scope = context.state.scopes.get(alternate_node) || context.state.scope;
|
|
2800
2990
|
const alternate_body =
|
|
2801
|
-
alternate_node.type === 'IfStatement'
|
|
2991
|
+
alternate_node.type === 'IfStatement'
|
|
2992
|
+
? [alternate_node]
|
|
2993
|
+
: alternate_node.type === 'BlockStatement'
|
|
2994
|
+
? alternate_node.body
|
|
2995
|
+
: [alternate_node];
|
|
2802
2996
|
alternate = b.block(
|
|
2803
2997
|
transform_body(alternate_body, {
|
|
2804
2998
|
...context,
|
|
@@ -3941,6 +4135,12 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
3941
4135
|
|
|
3942
4136
|
visit(node);
|
|
3943
4137
|
},
|
|
4138
|
+
TSExpressionWithTypeArguments(node, context) {
|
|
4139
|
+
context.visit(node.expression);
|
|
4140
|
+
if (node.typeParameters) {
|
|
4141
|
+
context.visit(node.typeParameters);
|
|
4142
|
+
}
|
|
4143
|
+
},
|
|
3944
4144
|
AssignmentPattern(node, context) {
|
|
3945
4145
|
// We need to make sure that the whole AssignmentPattern has a start and end mapping
|
|
3946
4146
|
// Acorn only maps pieces but not the whole thing
|
|
@@ -4043,14 +4243,30 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4043
4243
|
}
|
|
4044
4244
|
},
|
|
4045
4245
|
NewExpression(node, context) {
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4246
|
+
const loc = /** @type {AST.SourceLocation} */ (node.loc) ?? null;
|
|
4247
|
+
|
|
4248
|
+
if (loc && !node?.metadata?.skipNewMapping) {
|
|
4249
|
+
context.location(loc.start.line, loc.start.column);
|
|
4250
|
+
}
|
|
4251
|
+
context.write('new ');
|
|
4252
|
+
|
|
4253
|
+
if (loc && node?.metadata?.skipNewMapping) {
|
|
4254
|
+
context.location(loc.start.line, loc.start.column);
|
|
4255
|
+
}
|
|
4256
|
+
|
|
4257
|
+
context.visit(node.callee);
|
|
4258
|
+
if (node.typeArguments) {
|
|
4259
|
+
context.visit(node.typeArguments);
|
|
4260
|
+
}
|
|
4261
|
+
context.write('(');
|
|
4262
|
+
for (let i = 0; i < node.arguments.length; i++) {
|
|
4263
|
+
if (i > 0) context.write(', ');
|
|
4264
|
+
context.visit(node.arguments[i]);
|
|
4265
|
+
}
|
|
4266
|
+
context.write(')');
|
|
4267
|
+
if (loc) {
|
|
4268
|
+
context.location(loc.end.line, loc.end.column);
|
|
4049
4269
|
}
|
|
4050
|
-
const loc = /** @type {AST.SourceLocation} */ (node.loc);
|
|
4051
|
-
context.location(loc.start.line, loc.start.column);
|
|
4052
|
-
base_tsx.NewExpression?.(node, context);
|
|
4053
|
-
context.location(loc.end.line, loc.end.column);
|
|
4054
4270
|
},
|
|
4055
4271
|
TemplateLiteral(node, context) {
|
|
4056
4272
|
if (!node.loc) {
|
|
@@ -4174,6 +4390,15 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4174
4390
|
}
|
|
4175
4391
|
} else {
|
|
4176
4392
|
if (node.shorthand) {
|
|
4393
|
+
// Shorthand object properties require an Identifier value. When the
|
|
4394
|
+
// transformed value is a tracked MemberExpression (for example
|
|
4395
|
+
// @value), emit longhand to keep valid output.
|
|
4396
|
+
if (node.value.type === 'MemberExpression' && node.value.tracked) {
|
|
4397
|
+
context.visit(node.key);
|
|
4398
|
+
context.write(': ');
|
|
4399
|
+
context.visit(node.value);
|
|
4400
|
+
return;
|
|
4401
|
+
}
|
|
4177
4402
|
// only visit value since key and value are the same
|
|
4178
4403
|
// or the value will contain the key like in AssignmentPattern: { foo = 1 }
|
|
4179
4404
|
context.visit(node.value);
|
|
@@ -4418,11 +4643,7 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4418
4643
|
if (node.loc) {
|
|
4419
4644
|
context.location(node.loc.start.line, node.loc.start.column);
|
|
4420
4645
|
}
|
|
4421
|
-
|
|
4422
|
-
context.write(node.name);
|
|
4423
|
-
} else if (node.name && node.name.name) {
|
|
4424
|
-
context.write(node.name.name);
|
|
4425
|
-
}
|
|
4646
|
+
context.write(node.name);
|
|
4426
4647
|
if (node.constraint) {
|
|
4427
4648
|
context.write(' extends ');
|
|
4428
4649
|
context.visit(node.constraint);
|
|
@@ -4563,11 +4784,7 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4563
4784
|
context.location(tp.loc.start.line, tp.loc.start.column);
|
|
4564
4785
|
}
|
|
4565
4786
|
// Write the parameter name
|
|
4566
|
-
|
|
4567
|
-
context.write(tp.name);
|
|
4568
|
-
} else if (tp.name && tp.name.name) {
|
|
4569
|
-
context.write(tp.name.name);
|
|
4570
|
-
}
|
|
4787
|
+
context.write(tp.name);
|
|
4571
4788
|
// In mapped types, constraint uses 'in' instead of 'extends'
|
|
4572
4789
|
if (tp.constraint) {
|
|
4573
4790
|
context.write(' in ');
|