ripple 0.3.2 → 0.3.4
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 +85 -0
- package/package.json +2 -2
- package/src/compiler/identifier-utils.js +0 -2
- package/src/compiler/phases/1-parse/index.js +101 -195
- package/src/compiler/phases/2-analyze/index.js +82 -174
- package/src/compiler/phases/2-analyze/prune.js +2 -2
- package/src/compiler/phases/3-transform/client/index.js +174 -264
- package/src/compiler/phases/3-transform/segments.js +0 -22
- package/src/compiler/phases/3-transform/server/index.js +185 -42
- package/src/compiler/types/index.d.ts +14 -33
- package/src/compiler/utils.js +32 -20
- package/src/runtime/index-client.js +0 -17
- package/src/runtime/internal/client/bindings.js +118 -7
- package/src/runtime/internal/client/render.js +5 -1
- package/src/runtime/internal/client/runtime.js +1 -1
- package/src/runtime/internal/client/types.d.ts +4 -0
- package/tests/client/array/array.copy-within.test.ripple +7 -7
- package/tests/client/array/array.derived.test.ripple +24 -24
- package/tests/client/array/array.iteration.test.ripple +7 -7
- package/tests/client/array/array.mutations.test.ripple +17 -17
- package/tests/client/array/array.to-methods.test.ripple +4 -4
- package/tests/client/async-suspend.test.ripple +3 -3
- package/tests/client/basic/basic.attributes.test.ripple +31 -31
- package/tests/client/basic/basic.collections.test.ripple +6 -6
- package/tests/client/basic/basic.components.test.ripple +8 -8
- package/tests/client/basic/basic.errors.test.ripple +31 -34
- 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 +36 -36
- 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.typescript.test.ripple.snap +24 -0
- package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
- package/tests/client/compiler/compiler.basic.test.ripple +58 -60
- package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
- package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
- package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
- package/tests/client/composite/composite.props.test.ripple +9 -9
- package/tests/client/composite/composite.reactivity.test.ripple +23 -23
- package/tests/client/composite/composite.render.test.ripple +52 -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 +5 -2
- package/tests/client/css/style-identifier.test.ripple +40 -49
- package/tests/client/date.test.ripple +39 -39
- package/tests/client/dynamic-elements.test.ripple +37 -37
- package/tests/client/events.test.ripple +25 -25
- package/tests/client/for.test.ripple +8 -8
- package/tests/client/head.test.ripple +7 -7
- package/tests/client/html.test.ripple +2 -2
- package/tests/client/input-value.test.ripple +376 -177
- package/tests/client/lazy-destructuring.test.ripple +185 -0
- package/tests/client/map.test.ripple +20 -20
- package/tests/client/media-query.test.ripple +4 -4
- package/tests/client/object.test.ripple +5 -5
- package/tests/client/portal.test.ripple +4 -4
- package/tests/client/ref.test.ripple +3 -3
- package/tests/client/return.test.ripple +17 -17
- package/tests/client/set.test.ripple +10 -10
- package/tests/client/svg.test.ripple +6 -5
- package/tests/client/switch.test.ripple +10 -10
- package/tests/client/tracked-expression.test.ripple +3 -1
- package/tests/client/try.test.ripple +4 -4
- package/tests/client/url/url.derived.test.ripple +6 -7
- package/tests/client/url/url.parsing.test.ripple +9 -9
- package/tests/client/url/url.partial-removal.test.ripple +9 -9
- package/tests/client/url/url.reactivity.test.ripple +16 -16
- package/tests/client/url/url.serialization.test.ripple +3 -3
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
- package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
- package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
- package/tests/hydration/build-components.js +4 -10
- package/tests/hydration/compiled/client/basic.js +4 -4
- package/tests/hydration/compiled/client/events.js +2 -0
- package/tests/hydration/compiled/client/for.js +2 -0
- package/tests/hydration/compiled/client/head.js +13 -11
- package/tests/hydration/compiled/client/hmr.js +4 -2
- package/tests/hydration/compiled/client/html.js +82 -95
- package/tests/hydration/compiled/client/if-children.js +8 -9
- package/tests/hydration/compiled/client/if.js +2 -0
- package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
- package/tests/hydration/compiled/client/portal.js +1 -1
- package/tests/hydration/compiled/client/reactivity.js +2 -0
- package/tests/hydration/compiled/client/return.js +2 -0
- package/tests/hydration/compiled/client/switch.js +2 -0
- package/tests/hydration/compiled/server/composite.js +2 -2
- package/tests/hydration/compiled/server/events.js +2 -0
- package/tests/hydration/compiled/server/for.js +2 -0
- package/tests/hydration/compiled/server/head.js +13 -11
- package/tests/hydration/compiled/server/hmr.js +2 -0
- package/tests/hydration/compiled/server/html.js +2 -0
- package/tests/hydration/compiled/server/if-children.js +2 -0
- package/tests/hydration/compiled/server/if.js +2 -0
- package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
- package/tests/hydration/compiled/server/portal.js +1 -1
- package/tests/hydration/compiled/server/reactivity.js +2 -0
- package/tests/hydration/compiled/server/return.js +2 -0
- package/tests/hydration/compiled/server/switch.js +2 -0
- package/tests/hydration/components/composite.ripple +1 -1
- package/tests/hydration/components/events.ripple +10 -8
- package/tests/hydration/components/for.ripple +22 -20
- package/tests/hydration/components/head.ripple +8 -6
- package/tests/hydration/components/hmr.ripple +3 -1
- package/tests/hydration/components/html.ripple +3 -1
- package/tests/hydration/components/if-children.ripple +9 -7
- package/tests/hydration/components/if.ripple +7 -5
- package/tests/hydration/components/mixed-control-flow.ripple +5 -3
- package/tests/hydration/components/portal.ripple +2 -2
- package/tests/hydration/components/reactivity.ripple +11 -9
- package/tests/hydration/components/return.ripple +13 -11
- package/tests/hydration/components/switch.ripple +6 -4
- package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
- package/tests/server/await.test.ripple +2 -2
- package/tests/server/basic.attributes.test.ripple +21 -19
- package/tests/server/basic.components.test.ripple +5 -4
- package/tests/server/basic.test.ripple +21 -20
- package/tests/server/compiler.test.ripple +36 -5
- package/tests/server/composite.props.test.ripple +7 -6
- package/tests/server/context.test.ripple +3 -1
- package/tests/server/dynamic-elements.test.ripple +24 -24
- package/tests/server/head.test.ripple +7 -5
- package/tests/server/style-identifier.test.ripple +95 -16
- package/types/index.d.ts +4 -1
|
@@ -26,6 +26,8 @@ import {
|
|
|
26
26
|
is_binding_function,
|
|
27
27
|
is_element_dynamic,
|
|
28
28
|
is_ripple_track_call,
|
|
29
|
+
is_ripple_import,
|
|
30
|
+
ripple_import_requires_block,
|
|
29
31
|
hash,
|
|
30
32
|
flatten_switch_consequent,
|
|
31
33
|
get_ripple_namespace_call_name,
|
|
@@ -73,6 +75,23 @@ function build_return_guard(flags) {
|
|
|
73
75
|
return condition;
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
/**
|
|
79
|
+
* @param {AST.ClassDeclaration | AST.ClassExpression} node
|
|
80
|
+
* @param {TransformServerContext} context
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
function strip_class_typescript_syntax(node, context) {
|
|
84
|
+
delete node.typeParameters;
|
|
85
|
+
delete node.superTypeParameters;
|
|
86
|
+
delete node.implements;
|
|
87
|
+
|
|
88
|
+
if (node.superClass?.type === 'TSInstantiationExpression') {
|
|
89
|
+
node.superClass = /** @type {AST.Expression} */ (context.visit(node.superClass.expression));
|
|
90
|
+
} else if (node.superClass && 'typeArguments' in node.superClass) {
|
|
91
|
+
delete node.superClass.typeArguments;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
76
95
|
/**
|
|
77
96
|
* Collects all unique return statements from the direct children of a body
|
|
78
97
|
* @param {AST.Node[]} children
|
|
@@ -307,6 +326,27 @@ const visitors = {
|
|
|
307
326
|
const parent = /** @type {AST.Node} */ (context.path.at(-1));
|
|
308
327
|
|
|
309
328
|
if (is_reference(node, parent)) {
|
|
329
|
+
// Apply lazy destructuring binding transforms only
|
|
330
|
+
const binding = context.state.scope?.get(node.name);
|
|
331
|
+
if (
|
|
332
|
+
binding?.transform?.read &&
|
|
333
|
+
binding.node !== node &&
|
|
334
|
+
(binding.kind === 'lazy' || binding.kind === 'lazy_fallback')
|
|
335
|
+
) {
|
|
336
|
+
const transformed = binding.transform.read(node);
|
|
337
|
+
if (node.tracked) {
|
|
338
|
+
const is_right_side_of_assignment =
|
|
339
|
+
parent.type === 'AssignmentExpression' && parent.right === node;
|
|
340
|
+
if (
|
|
341
|
+
(parent.type !== 'AssignmentExpression' && parent.type !== 'UpdateExpression') ||
|
|
342
|
+
is_right_side_of_assignment
|
|
343
|
+
) {
|
|
344
|
+
return b.call('_$_.get', transformed);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return transformed;
|
|
348
|
+
}
|
|
349
|
+
|
|
310
350
|
if (node.tracked) {
|
|
311
351
|
const is_right_side_of_assignment =
|
|
312
352
|
parent.type === 'AssignmentExpression' && parent.right === node;
|
|
@@ -323,13 +363,24 @@ const visitors = {
|
|
|
323
363
|
},
|
|
324
364
|
|
|
325
365
|
Component(node, context) {
|
|
366
|
+
let props_param_output;
|
|
367
|
+
|
|
326
368
|
if (node.params.length > 0) {
|
|
327
369
|
let props_param = node.params[0];
|
|
328
370
|
|
|
329
371
|
if (props_param.type === 'Identifier') {
|
|
330
372
|
delete props_param.typeAnnotation;
|
|
331
|
-
|
|
373
|
+
props_param_output = props_param;
|
|
374
|
+
} else if (props_param.type === 'ObjectPattern' || props_param.type === 'ArrayPattern') {
|
|
332
375
|
delete props_param.typeAnnotation;
|
|
376
|
+
if (props_param.lazy) {
|
|
377
|
+
// Lazy destructuring: use __props identifier, bindings resolved via transforms
|
|
378
|
+
props_param_output = b.id('__props');
|
|
379
|
+
} else {
|
|
380
|
+
props_param_output = props_param;
|
|
381
|
+
}
|
|
382
|
+
} else {
|
|
383
|
+
props_param_output = props_param;
|
|
333
384
|
}
|
|
334
385
|
}
|
|
335
386
|
|
|
@@ -378,7 +429,7 @@ const visitors = {
|
|
|
378
429
|
|
|
379
430
|
let component_fn = b.function(
|
|
380
431
|
node.id,
|
|
381
|
-
node.params.length > 0 ? [b.id('__output'),
|
|
432
|
+
node.params.length > 0 ? [b.id('__output'), props_param_output] : [b.id('__output')],
|
|
382
433
|
b.block([
|
|
383
434
|
...(metadata.await
|
|
384
435
|
? [b.return(b.call('_$_.async', b.thunk(b.block(body_statements), true)))]
|
|
@@ -454,17 +505,19 @@ const visitors = {
|
|
|
454
505
|
}
|
|
455
506
|
|
|
456
507
|
const callee = node.callee;
|
|
457
|
-
const source_name = callee.type === 'Identifier' ? callee.metadata?.source_name : undefined;
|
|
458
|
-
const ripple_runtime_method = get_ripple_namespace_call_name(source_name);
|
|
459
508
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
...node
|
|
466
|
-
|
|
467
|
-
|
|
509
|
+
// Handle direct calls to ripple-imported functions: effect(), untrack(), RippleArray(), etc.
|
|
510
|
+
if (callee.type === 'Identifier' && is_ripple_import(callee, context)) {
|
|
511
|
+
const ripple_runtime_method = get_ripple_namespace_call_name(callee.name);
|
|
512
|
+
if (ripple_runtime_method !== null) {
|
|
513
|
+
return {
|
|
514
|
+
...node,
|
|
515
|
+
callee: b.member(b.id('_$_'), b.id(ripple_runtime_method)),
|
|
516
|
+
arguments: /** @type {(AST.Expression | AST.SpreadElement)[]} */ ([
|
|
517
|
+
...node.arguments.map((arg) => context.visit(arg)),
|
|
518
|
+
]),
|
|
519
|
+
};
|
|
520
|
+
}
|
|
468
521
|
}
|
|
469
522
|
|
|
470
523
|
if (is_ripple_track_call(callee, context)) {
|
|
@@ -488,18 +541,16 @@ const visitors = {
|
|
|
488
541
|
};
|
|
489
542
|
}
|
|
490
543
|
|
|
491
|
-
//
|
|
544
|
+
// Handle member calls on ripple imports, like RippleArray.from()
|
|
492
545
|
if (
|
|
493
546
|
callee.type === 'MemberExpression' &&
|
|
494
|
-
callee.object.metadata?.source_name?.startsWith('#ripple.') &&
|
|
495
547
|
callee.object.type === 'Identifier' &&
|
|
496
|
-
callee.property.type === 'Identifier'
|
|
548
|
+
callee.property.type === 'Identifier' &&
|
|
549
|
+
is_ripple_import(callee, context)
|
|
497
550
|
) {
|
|
498
551
|
const object = callee.object;
|
|
499
552
|
const property = callee.property;
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
const method_name = get_ripple_namespace_call_name(source_name);
|
|
553
|
+
const method_name = get_ripple_namespace_call_name(object.name);
|
|
503
554
|
if (method_name !== null) {
|
|
504
555
|
return b.member(
|
|
505
556
|
b.id('_$_'),
|
|
@@ -525,6 +576,20 @@ const visitors = {
|
|
|
525
576
|
if (!context.state.to_ts) {
|
|
526
577
|
delete node.typeArguments;
|
|
527
578
|
}
|
|
579
|
+
|
|
580
|
+
// Transform `new RippleArray(...)`, `new RippleMap(...)`, etc. imported from 'ripple'
|
|
581
|
+
if (callee.type === 'Identifier' && is_ripple_import(callee, context)) {
|
|
582
|
+
const ripple_runtime_method = get_ripple_namespace_call_name(callee.name);
|
|
583
|
+
if (ripple_runtime_method !== null) {
|
|
584
|
+
return b.call(
|
|
585
|
+
'_$_.' + ripple_runtime_method,
|
|
586
|
+
.../** @type {(AST.Expression | AST.SpreadElement)[]} */ (
|
|
587
|
+
node.arguments.map((arg) => context.visit(arg))
|
|
588
|
+
),
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
528
593
|
return context.next();
|
|
529
594
|
},
|
|
530
595
|
|
|
@@ -535,16 +600,44 @@ const visitors = {
|
|
|
535
600
|
return context.next();
|
|
536
601
|
},
|
|
537
602
|
|
|
603
|
+
ClassDeclaration(node, context) {
|
|
604
|
+
if (!context.state.to_ts) {
|
|
605
|
+
strip_class_typescript_syntax(node, context);
|
|
606
|
+
}
|
|
607
|
+
return context.next();
|
|
608
|
+
},
|
|
609
|
+
|
|
610
|
+
ClassExpression(node, context) {
|
|
611
|
+
if (!context.state.to_ts) {
|
|
612
|
+
strip_class_typescript_syntax(node, context);
|
|
613
|
+
}
|
|
614
|
+
return context.next();
|
|
615
|
+
},
|
|
616
|
+
|
|
538
617
|
FunctionDeclaration(node, context) {
|
|
539
618
|
if (!context.state.to_ts) {
|
|
540
619
|
delete node.returnType;
|
|
541
620
|
delete node.typeParameters;
|
|
542
|
-
for (
|
|
621
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
622
|
+
const param = node.params[i];
|
|
543
623
|
delete param.typeAnnotation;
|
|
544
624
|
// Handle AssignmentPattern (parameters with default values)
|
|
545
625
|
if (param.type === 'AssignmentPattern' && param.left) {
|
|
546
626
|
delete param.left.typeAnnotation;
|
|
547
627
|
}
|
|
628
|
+
// Replace lazy destructuring params with generated identifiers
|
|
629
|
+
const pattern = param.type === 'AssignmentPattern' ? param.left : param;
|
|
630
|
+
if (
|
|
631
|
+
(pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
|
|
632
|
+
pattern.lazy &&
|
|
633
|
+
pattern.metadata?.lazy_id
|
|
634
|
+
) {
|
|
635
|
+
const id = b.id(pattern.metadata.lazy_id);
|
|
636
|
+
node.params[i] =
|
|
637
|
+
param.type === 'AssignmentPattern'
|
|
638
|
+
? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
|
|
639
|
+
: id;
|
|
640
|
+
}
|
|
548
641
|
}
|
|
549
642
|
}
|
|
550
643
|
return context.next();
|
|
@@ -554,12 +647,26 @@ const visitors = {
|
|
|
554
647
|
if (!context.state.to_ts) {
|
|
555
648
|
delete node.returnType;
|
|
556
649
|
delete node.typeParameters;
|
|
557
|
-
for (
|
|
650
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
651
|
+
const param = node.params[i];
|
|
558
652
|
delete param.typeAnnotation;
|
|
559
653
|
// Handle AssignmentPattern (parameters with default values)
|
|
560
654
|
if (param.type === 'AssignmentPattern' && param.left) {
|
|
561
655
|
delete param.left.typeAnnotation;
|
|
562
656
|
}
|
|
657
|
+
// Replace lazy destructuring params with generated identifiers
|
|
658
|
+
const pattern = param.type === 'AssignmentPattern' ? param.left : param;
|
|
659
|
+
if (
|
|
660
|
+
(pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
|
|
661
|
+
pattern.lazy &&
|
|
662
|
+
pattern.metadata?.lazy_id
|
|
663
|
+
) {
|
|
664
|
+
const id = b.id(pattern.metadata.lazy_id);
|
|
665
|
+
node.params[i] =
|
|
666
|
+
param.type === 'AssignmentPattern'
|
|
667
|
+
? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
|
|
668
|
+
: id;
|
|
669
|
+
}
|
|
563
670
|
}
|
|
564
671
|
}
|
|
565
672
|
return context.next();
|
|
@@ -579,12 +686,26 @@ const visitors = {
|
|
|
579
686
|
ArrowFunctionExpression(node, context) {
|
|
580
687
|
delete node.returnType;
|
|
581
688
|
delete node.typeParameters;
|
|
582
|
-
for (
|
|
689
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
690
|
+
const param = node.params[i];
|
|
583
691
|
delete param.typeAnnotation;
|
|
584
692
|
// Handle AssignmentPattern (parameters with default values)
|
|
585
693
|
if (param.type === 'AssignmentPattern' && param.left) {
|
|
586
694
|
delete param.left.typeAnnotation;
|
|
587
695
|
}
|
|
696
|
+
// Replace lazy destructuring params with generated identifiers
|
|
697
|
+
const pattern = param.type === 'AssignmentPattern' ? param.left : param;
|
|
698
|
+
if (
|
|
699
|
+
(pattern.type === 'ObjectPattern' || pattern.type === 'ArrayPattern') &&
|
|
700
|
+
pattern.lazy &&
|
|
701
|
+
pattern.metadata?.lazy_id
|
|
702
|
+
) {
|
|
703
|
+
const id = b.id(pattern.metadata.lazy_id);
|
|
704
|
+
node.params[i] =
|
|
705
|
+
param.type === 'AssignmentPattern'
|
|
706
|
+
? /** @type {AST.AssignmentPattern} */ ({ ...param, left: id })
|
|
707
|
+
: id;
|
|
708
|
+
}
|
|
588
709
|
}
|
|
589
710
|
|
|
590
711
|
return context.next();
|
|
@@ -726,6 +847,15 @@ const visitors = {
|
|
|
726
847
|
for (const declarator of node.declarations) {
|
|
727
848
|
if (!context.state.to_ts) {
|
|
728
849
|
delete declarator.id.typeAnnotation;
|
|
850
|
+
|
|
851
|
+
// Replace lazy destructuring patterns with the generated identifier
|
|
852
|
+
if (
|
|
853
|
+
(declarator.id.type === 'ObjectPattern' || declarator.id.type === 'ArrayPattern') &&
|
|
854
|
+
declarator.id.lazy &&
|
|
855
|
+
declarator.id.metadata?.lazy_id
|
|
856
|
+
) {
|
|
857
|
+
declarator.id = b.id(declarator.id.metadata.lazy_id);
|
|
858
|
+
}
|
|
729
859
|
}
|
|
730
860
|
}
|
|
731
861
|
|
|
@@ -984,10 +1114,7 @@ const visitors = {
|
|
|
984
1114
|
/** @type {AST.Expression | null} */
|
|
985
1115
|
let children_prop = null;
|
|
986
1116
|
|
|
987
|
-
|
|
988
|
-
// We're inside a component, don't continue applying css hash to class
|
|
989
|
-
state.applyParentCssScope = undefined;
|
|
990
|
-
}
|
|
1117
|
+
const apply_parent_css_scope = state.applyParentCssScope;
|
|
991
1118
|
|
|
992
1119
|
for (const attr of node.attributes) {
|
|
993
1120
|
if (attr.type === 'Attribute') {
|
|
@@ -1051,6 +1178,14 @@ const visitors = {
|
|
|
1051
1178
|
const children = /** @type {AST.Expression} */ (
|
|
1052
1179
|
visit(b.component(b.id('children'), [], children_filtered), {
|
|
1053
1180
|
...context.state,
|
|
1181
|
+
...(apply_parent_css_scope ||
|
|
1182
|
+
(is_element_dynamic(node) && node.metadata.scoped && state.component?.css)
|
|
1183
|
+
? {
|
|
1184
|
+
applyParentCssScope:
|
|
1185
|
+
apply_parent_css_scope ||
|
|
1186
|
+
/** @type {AST.CSS.StyleSheet} */ (state.component?.css).hash,
|
|
1187
|
+
}
|
|
1188
|
+
: {}),
|
|
1054
1189
|
scope: component_scope,
|
|
1055
1190
|
namespace: child_namespace,
|
|
1056
1191
|
})
|
|
@@ -1293,6 +1428,23 @@ const visitors = {
|
|
|
1293
1428
|
AssignmentExpression(node, context) {
|
|
1294
1429
|
const left = node.left;
|
|
1295
1430
|
|
|
1431
|
+
// Handle lazy binding assignments (e.g., a = 5 where a is from let &{a} = obj)
|
|
1432
|
+
if (left.type === 'Identifier') {
|
|
1433
|
+
const binding = context.state.scope?.get(left.name);
|
|
1434
|
+
if (binding?.transform?.assign && binding.node !== left) {
|
|
1435
|
+
let value = /** @type {AST.Expression} */ (context.visit(node.right));
|
|
1436
|
+
|
|
1437
|
+
// For compound operators (+=, -=, *=, /=), expand to read + operation
|
|
1438
|
+
if (node.operator !== '=') {
|
|
1439
|
+
const operator = node.operator.slice(0, -1); // '+=' -> '+'
|
|
1440
|
+
const current = binding.transform.read(left);
|
|
1441
|
+
value = b.binary(/** @type {AST.BinaryOperator} */ (operator), current, value);
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
return binding.transform.assign(left, value);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1296
1448
|
if (
|
|
1297
1449
|
left.type === 'MemberExpression' &&
|
|
1298
1450
|
(left.tracked || (left.property.type === 'Identifier' && left.property.tracked))
|
|
@@ -1346,6 +1498,14 @@ const visitors = {
|
|
|
1346
1498
|
UpdateExpression(node, context) {
|
|
1347
1499
|
const argument = node.argument;
|
|
1348
1500
|
|
|
1501
|
+
// Handle lazy binding updates (e.g., a++ where a is from let &{a} = obj)
|
|
1502
|
+
if (argument.type === 'Identifier') {
|
|
1503
|
+
const binding = context.state.scope?.get(argument.name);
|
|
1504
|
+
if (binding?.transform?.update && binding.node !== argument) {
|
|
1505
|
+
return binding.transform.update(node);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1349
1509
|
if (
|
|
1350
1510
|
argument.type === 'MemberExpression' &&
|
|
1351
1511
|
(argument.tracked || (argument.property.type === 'Identifier' && argument.property.tracked))
|
|
@@ -1563,23 +1723,6 @@ const visitors = {
|
|
|
1563
1723
|
return b.call('_$_.get', /** @type {AST.Expression} */ (context.visit(node.argument)));
|
|
1564
1724
|
},
|
|
1565
1725
|
|
|
1566
|
-
RippleObjectExpression(node, context) {
|
|
1567
|
-
// For SSR, we just evaluate the object as-is since there's no reactivity
|
|
1568
|
-
return b.object(
|
|
1569
|
-
/** @type {(AST.Property | AST.SpreadElement)[]} */
|
|
1570
|
-
(node.properties.map((prop) => context.visit(prop))),
|
|
1571
|
-
);
|
|
1572
|
-
},
|
|
1573
|
-
|
|
1574
|
-
RippleArrayExpression(node, context) {
|
|
1575
|
-
return b.call(
|
|
1576
|
-
'_$_.ripple_array',
|
|
1577
|
-
.../** @type {(AST.Expression | AST.SpreadElement)[]} */ (
|
|
1578
|
-
node.elements.map((el) => context.visit(/** @type {AST.Node} */ (el)))
|
|
1579
|
-
),
|
|
1580
|
-
);
|
|
1581
|
-
},
|
|
1582
|
-
|
|
1583
1726
|
MemberExpression(node, context) {
|
|
1584
1727
|
if (
|
|
1585
1728
|
node.tracked ||
|
|
@@ -13,25 +13,7 @@ interface BaseNodeMetaData {
|
|
|
13
13
|
scoped?: boolean;
|
|
14
14
|
path: AST.Node[];
|
|
15
15
|
has_template?: boolean;
|
|
16
|
-
source_name?:
|
|
17
|
-
| string
|
|
18
|
-
| '#ripple'
|
|
19
|
-
| '#ripple.map'
|
|
20
|
-
| '#ripple.set'
|
|
21
|
-
| '#ripple.server'
|
|
22
|
-
| '#ripple.style'
|
|
23
|
-
| '#ripple.array'
|
|
24
|
-
| '#ripple.object'
|
|
25
|
-
| '#ripple.effect'
|
|
26
|
-
| '#ripple.track'
|
|
27
|
-
| '#ripple.trackSplit'
|
|
28
|
-
| '#ripple.untrack'
|
|
29
|
-
| '#ripple.url'
|
|
30
|
-
| '#ripple.urlSearchParams'
|
|
31
|
-
| '#ripple.date'
|
|
32
|
-
| '#ripple.mediaQuery'
|
|
33
|
-
| '#ripple.context'
|
|
34
|
-
| '#ripple.validate';
|
|
16
|
+
source_name?: string | '#server' | '#style';
|
|
35
17
|
is_capitalized?: boolean;
|
|
36
18
|
has_await?: boolean;
|
|
37
19
|
commentContainerId?: number;
|
|
@@ -43,6 +25,7 @@ interface BaseNodeMetaData {
|
|
|
43
25
|
is_reactive?: boolean;
|
|
44
26
|
lone_return?: boolean;
|
|
45
27
|
forceMapping?: boolean;
|
|
28
|
+
lazy_id?: string;
|
|
46
29
|
}
|
|
47
30
|
|
|
48
31
|
interface FunctionMetaData extends BaseNodeMetaData {
|
|
@@ -103,13 +86,13 @@ declare module 'estree' {
|
|
|
103
86
|
|
|
104
87
|
interface ClassDeclaration {
|
|
105
88
|
typeParameters?: AST.TSTypeParameterDeclaration;
|
|
106
|
-
|
|
89
|
+
superTypeParameters?: AST.TSTypeParameterInstantiation;
|
|
107
90
|
implements?: AST.TSClassImplements[];
|
|
108
91
|
}
|
|
109
92
|
|
|
110
93
|
interface ClassExpression {
|
|
111
94
|
typeParameters?: AST.TSTypeParameterDeclaration;
|
|
112
|
-
|
|
95
|
+
superTypeParameters?: AST.TSTypeParameterInstantiation;
|
|
113
96
|
implements?: AST.TSClassImplements[];
|
|
114
97
|
}
|
|
115
98
|
|
|
@@ -123,6 +106,14 @@ declare module 'estree' {
|
|
|
123
106
|
optional: boolean;
|
|
124
107
|
}
|
|
125
108
|
|
|
109
|
+
// Lazy destructuring patterns (&{...} and &[...])
|
|
110
|
+
interface ObjectPattern {
|
|
111
|
+
lazy?: boolean;
|
|
112
|
+
}
|
|
113
|
+
interface ArrayPattern {
|
|
114
|
+
lazy?: boolean;
|
|
115
|
+
}
|
|
116
|
+
|
|
126
117
|
// We mark the whole node as marked when member is @[expression]
|
|
127
118
|
// Otherwise, we only mark Identifier nodes
|
|
128
119
|
interface MemberExpression extends AST.TrackedNode {}
|
|
@@ -161,8 +152,6 @@ declare module 'estree' {
|
|
|
161
152
|
}
|
|
162
153
|
|
|
163
154
|
interface ExpressionMap {
|
|
164
|
-
RippleArrayExpression: RippleArrayExpression;
|
|
165
|
-
RippleObjectExpression: RippleObjectExpression;
|
|
166
155
|
TrackedExpression: TrackedExpression;
|
|
167
156
|
StyleIdentifier: StyleIdentifier;
|
|
168
157
|
ServerIdentifier: ServerIdentifier;
|
|
@@ -359,21 +348,11 @@ declare module 'estree' {
|
|
|
359
348
|
/**
|
|
360
349
|
* Tracked Expressions
|
|
361
350
|
*/
|
|
362
|
-
interface RippleArrayExpression extends Omit<AST.ArrayExpression, 'type'> {
|
|
363
|
-
type: 'RippleArrayExpression';
|
|
364
|
-
elements: (AST.Expression | AST.SpreadElement | null)[];
|
|
365
|
-
}
|
|
366
|
-
|
|
367
351
|
interface TrackedExpression extends AST.BaseExpression {
|
|
368
352
|
argument: AST.Expression;
|
|
369
353
|
type: 'TrackedExpression';
|
|
370
354
|
}
|
|
371
355
|
|
|
372
|
-
interface RippleObjectExpression extends Omit<AST.ObjectExpression, 'type'> {
|
|
373
|
-
type: 'RippleObjectExpression';
|
|
374
|
-
properties: (AST.Property | AST.SpreadElement)[];
|
|
375
|
-
}
|
|
376
|
-
|
|
377
356
|
/**
|
|
378
357
|
* Ripple attribute nodes
|
|
379
358
|
*/
|
|
@@ -1136,6 +1115,8 @@ export type BindingKind =
|
|
|
1136
1115
|
| 'rest_prop'
|
|
1137
1116
|
| 'prop'
|
|
1138
1117
|
| 'prop_fallback'
|
|
1118
|
+
| 'lazy'
|
|
1119
|
+
| 'lazy_fallback'
|
|
1139
1120
|
| 'index';
|
|
1140
1121
|
|
|
1141
1122
|
/**
|
package/src/compiler/utils.js
CHANGED
|
@@ -164,18 +164,18 @@ const DOM_PROPERTIES = [
|
|
|
164
164
|
];
|
|
165
165
|
|
|
166
166
|
/** @type {Record<string, string>} */
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
167
|
+
const RIPPLE_IMPORT_CALL_NAME = {
|
|
168
|
+
RippleURL: 'ripple_url',
|
|
169
|
+
RippleURLSearchParams: 'ripple_url_search_params',
|
|
170
|
+
RippleDate: 'ripple_date',
|
|
171
|
+
RippleMap: 'ripple_map',
|
|
172
|
+
RippleSet: 'ripple_set',
|
|
173
|
+
MediaQuery: 'media_query',
|
|
174
|
+
Context: 'context',
|
|
175
|
+
effect: 'effect',
|
|
176
|
+
untrack: 'untrack',
|
|
177
|
+
RippleArray: 'ripple_array',
|
|
178
|
+
RippleObject: 'ripple_object',
|
|
179
179
|
};
|
|
180
180
|
|
|
181
181
|
/**
|
|
@@ -298,14 +298,17 @@ export function is_ripple_track_call(callee, context) {
|
|
|
298
298
|
// Super expressions cannot be Ripple track calls
|
|
299
299
|
if (callee.type === 'Super') return false;
|
|
300
300
|
|
|
301
|
+
if (callee.type === 'Identifier' && (callee.name === 'track' || callee.name === 'trackSplit')) {
|
|
302
|
+
return is_ripple_import(callee, context);
|
|
303
|
+
}
|
|
304
|
+
|
|
301
305
|
return (
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
is_ripple_import(callee, context))
|
|
306
|
+
callee.type === 'MemberExpression' &&
|
|
307
|
+
callee.object.type === 'Identifier' &&
|
|
308
|
+
callee.property.type === 'Identifier' &&
|
|
309
|
+
(callee.property.name === 'track' || callee.property.name === 'trackSplit') &&
|
|
310
|
+
!callee.computed &&
|
|
311
|
+
is_ripple_import(callee, context)
|
|
309
312
|
);
|
|
310
313
|
}
|
|
311
314
|
|
|
@@ -936,5 +939,14 @@ export function flatten_switch_consequent(consequent) {
|
|
|
936
939
|
* @returns {string | null}
|
|
937
940
|
*/
|
|
938
941
|
export function get_ripple_namespace_call_name(name) {
|
|
939
|
-
return name == null ? null : (
|
|
942
|
+
return name == null ? null : (RIPPLE_IMPORT_CALL_NAME[name] ?? null);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Returns true if the given import name requires a __block parameter
|
|
947
|
+
* @param {string} name
|
|
948
|
+
* @returns {boolean}
|
|
949
|
+
*/
|
|
950
|
+
export function ripple_import_requires_block(name) {
|
|
951
|
+
return name !== 'effect' && name !== 'untrack' && name !== 'Context';
|
|
940
952
|
}
|
|
@@ -172,20 +172,3 @@ import {
|
|
|
172
172
|
ref_prop as createRefKey,
|
|
173
173
|
} from './internal/client/runtime.js';
|
|
174
174
|
import { user_effect as effect } from './internal/client/blocks.js';
|
|
175
|
-
|
|
176
|
-
export const ripple_namespace = {
|
|
177
|
-
map: RippleMap,
|
|
178
|
-
set: RippleSet,
|
|
179
|
-
array: RippleArray,
|
|
180
|
-
object: RippleObject,
|
|
181
|
-
context: Context,
|
|
182
|
-
url: RippleURL,
|
|
183
|
-
urlSearchParams: RippleURLSearchParams,
|
|
184
|
-
date: RippleDate,
|
|
185
|
-
mediaQuery: MediaQuery,
|
|
186
|
-
createRefKey,
|
|
187
|
-
track,
|
|
188
|
-
trackSplit,
|
|
189
|
-
effect,
|
|
190
|
-
untrack,
|
|
191
|
-
};
|