ripple 0.2.215 → 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 +86 -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 +216 -16
- package/src/compiler/phases/2-analyze/prune.js +2 -2
- package/src/compiler/phases/3-transform/client/index.js +326 -94
- 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/template.js +1 -1
- 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 +111 -30
- 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 +56 -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 +84 -0
- 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 +107 -0
- 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 +34 -0
- 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/hydration/hmr.test.js +74 -0
- 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
|
);
|
|
@@ -2162,7 +2317,12 @@ const visitors = {
|
|
|
2162
2317
|
callback_body.push(b.stmt(b.call('_$_.set', b.id(info.name), b.false)));
|
|
2163
2318
|
callback_body.push(
|
|
2164
2319
|
b.if(
|
|
2165
|
-
/** @type {AST.Expression} */ (
|
|
2320
|
+
/** @type {AST.Expression} */ (
|
|
2321
|
+
context.visit(node.test, {
|
|
2322
|
+
...context.state,
|
|
2323
|
+
metadata: { ...context.state.metadata, await: false },
|
|
2324
|
+
})
|
|
2325
|
+
),
|
|
2166
2326
|
b.stmt(b.call('_$_.set', b.id(info.name), b.true)),
|
|
2167
2327
|
),
|
|
2168
2328
|
);
|
|
@@ -2170,7 +2330,12 @@ const visitors = {
|
|
|
2170
2330
|
callback_body.push(b.stmt(b.assignment('=', b.id(info.name), b.false)));
|
|
2171
2331
|
callback_body.push(
|
|
2172
2332
|
b.if(
|
|
2173
|
-
/** @type {AST.Expression} */ (
|
|
2333
|
+
/** @type {AST.Expression} */ (
|
|
2334
|
+
context.visit(node.test, {
|
|
2335
|
+
...context.state,
|
|
2336
|
+
metadata: { ...context.state.metadata, await: false },
|
|
2337
|
+
})
|
|
2338
|
+
),
|
|
2174
2339
|
b.stmt(b.assignment('=', b.id(info.name), b.true)),
|
|
2175
2340
|
),
|
|
2176
2341
|
);
|
|
@@ -2203,10 +2368,15 @@ const visitors = {
|
|
|
2203
2368
|
let alternate_id;
|
|
2204
2369
|
|
|
2205
2370
|
if (node.alternate !== null) {
|
|
2206
|
-
const alternate = /** @type {AST.
|
|
2371
|
+
const alternate = /** @type {AST.Statement} */ (node.alternate);
|
|
2207
2372
|
const alternate_scope = context.state.scopes.get(alternate) || context.state.scope;
|
|
2208
2373
|
/** @type {AST.Node[]} */
|
|
2209
|
-
let alternate_body =
|
|
2374
|
+
let alternate_body =
|
|
2375
|
+
alternate.type === 'IfStatement'
|
|
2376
|
+
? [alternate]
|
|
2377
|
+
: alternate.type === 'BlockStatement'
|
|
2378
|
+
? alternate.body
|
|
2379
|
+
: [alternate];
|
|
2210
2380
|
const alternate_block = b.block(
|
|
2211
2381
|
transform_body(alternate_body, {
|
|
2212
2382
|
...context,
|
|
@@ -2237,7 +2407,12 @@ const visitors = {
|
|
|
2237
2407
|
|
|
2238
2408
|
callback_body.push(
|
|
2239
2409
|
b.if(
|
|
2240
|
-
/** @type {AST.Expression} */ (
|
|
2410
|
+
/** @type {AST.Expression} */ (
|
|
2411
|
+
context.visit(node.test, {
|
|
2412
|
+
...context.state,
|
|
2413
|
+
metadata: { ...context.state.metadata, await: false },
|
|
2414
|
+
})
|
|
2415
|
+
),
|
|
2241
2416
|
b.stmt(b.call(b.id('__render'), b.id(consequent_id))),
|
|
2242
2417
|
alternate_id
|
|
2243
2418
|
? b.stmt(
|
|
@@ -2479,8 +2654,8 @@ const visitors = {
|
|
|
2479
2654
|
|
|
2480
2655
|
const server_identifier = b.id(SERVER_IDENTIFIER);
|
|
2481
2656
|
server_identifier.loc = node.loc;
|
|
2482
|
-
// Add source_name to properly map longer generated back to '#server'
|
|
2483
|
-
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';
|
|
2484
2659
|
|
|
2485
2660
|
const server_const = b.const(server_identifier, value);
|
|
2486
2661
|
server_const.loc = node.loc;
|
|
@@ -2489,7 +2664,7 @@ const visitors = {
|
|
|
2489
2664
|
}
|
|
2490
2665
|
|
|
2491
2666
|
if (!context.state.serverIdentifierPresent) {
|
|
2492
|
-
// 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
|
|
2493
2668
|
return b.empty;
|
|
2494
2669
|
}
|
|
2495
2670
|
|
|
@@ -2692,12 +2867,42 @@ function transform_ts_child(node, context) {
|
|
|
2692
2867
|
if (!node.selfClosing && !node.unclosed && !has_children_props && node.children.length > 0) {
|
|
2693
2868
|
const is_dom_element = is_element_dom_element(node);
|
|
2694
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
|
+
}
|
|
2695
2899
|
const thunk =
|
|
2696
|
-
/** @type {AST.Identifier} */ (node.id).name === 'style'
|
|
2900
|
+
/** @type {AST.Identifier} */ (node.id).name === 'style' ||
|
|
2901
|
+
non_component_children.length === 0
|
|
2697
2902
|
? null
|
|
2698
2903
|
: b.thunk(
|
|
2699
2904
|
b.block(
|
|
2700
|
-
transform_body(
|
|
2905
|
+
transform_body(non_component_children, {
|
|
2701
2906
|
...context,
|
|
2702
2907
|
state: {
|
|
2703
2908
|
...state,
|
|
@@ -2780,10 +2985,14 @@ function transform_ts_child(node, context) {
|
|
|
2780
2985
|
let alternate;
|
|
2781
2986
|
|
|
2782
2987
|
if (node.alternate !== null) {
|
|
2783
|
-
const alternate_node = /** @type {AST.
|
|
2988
|
+
const alternate_node = /** @type {AST.Statement} */ (node.alternate);
|
|
2784
2989
|
const alternate_scope = context.state.scopes.get(alternate_node) || context.state.scope;
|
|
2785
2990
|
const alternate_body =
|
|
2786
|
-
alternate_node.type === 'IfStatement'
|
|
2991
|
+
alternate_node.type === 'IfStatement'
|
|
2992
|
+
? [alternate_node]
|
|
2993
|
+
: alternate_node.type === 'BlockStatement'
|
|
2994
|
+
? alternate_node.body
|
|
2995
|
+
: [alternate_node];
|
|
2787
2996
|
alternate = b.block(
|
|
2788
2997
|
transform_body(alternate_body, {
|
|
2789
2998
|
...context,
|
|
@@ -3926,6 +4135,12 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
3926
4135
|
|
|
3927
4136
|
visit(node);
|
|
3928
4137
|
},
|
|
4138
|
+
TSExpressionWithTypeArguments(node, context) {
|
|
4139
|
+
context.visit(node.expression);
|
|
4140
|
+
if (node.typeParameters) {
|
|
4141
|
+
context.visit(node.typeParameters);
|
|
4142
|
+
}
|
|
4143
|
+
},
|
|
3929
4144
|
AssignmentPattern(node, context) {
|
|
3930
4145
|
// We need to make sure that the whole AssignmentPattern has a start and end mapping
|
|
3931
4146
|
// Acorn only maps pieces but not the whole thing
|
|
@@ -4028,14 +4243,30 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4028
4243
|
}
|
|
4029
4244
|
},
|
|
4030
4245
|
NewExpression(node, context) {
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
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);
|
|
4034
4269
|
}
|
|
4035
|
-
const loc = /** @type {AST.SourceLocation} */ (node.loc);
|
|
4036
|
-
context.location(loc.start.line, loc.start.column);
|
|
4037
|
-
base_tsx.NewExpression?.(node, context);
|
|
4038
|
-
context.location(loc.end.line, loc.end.column);
|
|
4039
4270
|
},
|
|
4040
4271
|
TemplateLiteral(node, context) {
|
|
4041
4272
|
if (!node.loc) {
|
|
@@ -4159,6 +4390,15 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4159
4390
|
}
|
|
4160
4391
|
} else {
|
|
4161
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
|
+
}
|
|
4162
4402
|
// only visit value since key and value are the same
|
|
4163
4403
|
// or the value will contain the key like in AssignmentPattern: { foo = 1 }
|
|
4164
4404
|
context.visit(node.value);
|
|
@@ -4403,11 +4643,7 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4403
4643
|
if (node.loc) {
|
|
4404
4644
|
context.location(node.loc.start.line, node.loc.start.column);
|
|
4405
4645
|
}
|
|
4406
|
-
|
|
4407
|
-
context.write(node.name);
|
|
4408
|
-
} else if (node.name && node.name.name) {
|
|
4409
|
-
context.write(node.name.name);
|
|
4410
|
-
}
|
|
4646
|
+
context.write(node.name);
|
|
4411
4647
|
if (node.constraint) {
|
|
4412
4648
|
context.write(' extends ');
|
|
4413
4649
|
context.visit(node.constraint);
|
|
@@ -4548,11 +4784,7 @@ function create_tsx_with_typescript_support(comments) {
|
|
|
4548
4784
|
context.location(tp.loc.start.line, tp.loc.start.column);
|
|
4549
4785
|
}
|
|
4550
4786
|
// Write the parameter name
|
|
4551
|
-
|
|
4552
|
-
context.write(tp.name);
|
|
4553
|
-
} else if (tp.name && tp.name.name) {
|
|
4554
|
-
context.write(tp.name.name);
|
|
4555
|
-
}
|
|
4787
|
+
context.write(tp.name);
|
|
4556
4788
|
// In mapped types, constraint uses 'in' instead of 'extends'
|
|
4557
4789
|
if (tp.constraint) {
|
|
4558
4790
|
context.write(' in ');
|