ripple 0.2.216 → 0.3.1
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 +52 -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 +27 -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
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// If block components for hydration testing
|
|
2
|
-
import { track } from 'ripple';
|
|
3
2
|
|
|
4
3
|
export component IfTruthy() {
|
|
5
4
|
const show = true;
|
|
@@ -25,7 +24,7 @@ export component IfElse() {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export component ReactiveIf() {
|
|
28
|
-
let show = track(true);
|
|
27
|
+
let show = #ripple.track(true);
|
|
29
28
|
<button
|
|
30
29
|
class="toggle"
|
|
31
30
|
onClick={() => {
|
|
@@ -40,7 +39,7 @@ export component ReactiveIf() {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
export component ReactiveIfElse() {
|
|
43
|
-
let isOn = track(false);
|
|
42
|
+
let isOn = #ripple.track(false);
|
|
44
43
|
<button
|
|
45
44
|
class="toggle"
|
|
46
45
|
onClick={() => {
|
|
@@ -57,8 +56,8 @@ export component ReactiveIfElse() {
|
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
export component NestedIf() {
|
|
60
|
-
let outer = track(true);
|
|
61
|
-
let inner = track(true);
|
|
59
|
+
let outer = #ripple.track(true);
|
|
60
|
+
let inner = #ripple.track(true);
|
|
62
61
|
<button
|
|
63
62
|
class="outer-toggle"
|
|
64
63
|
onClick={() => {
|
|
@@ -86,7 +85,7 @@ export component NestedIf() {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
export component IfElseIfChain() {
|
|
89
|
-
let status = track<'loading' | 'success' | 'error'>('loading');
|
|
88
|
+
let status = #ripple.track<'loading' | 'success' | 'error'>('loading');
|
|
90
89
|
<div>
|
|
91
90
|
<button
|
|
92
91
|
class="success"
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { track } from 'ripple';
|
|
2
|
-
|
|
3
1
|
export component MixedControlFlowStatic() {
|
|
4
2
|
const rows = [
|
|
5
3
|
{ id: 1, kind: 'a', enabled: true },
|
|
@@ -31,9 +29,9 @@ export component MixedControlFlowStatic() {
|
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
export component MixedControlFlowReactive() {
|
|
34
|
-
let show = track(true);
|
|
35
|
-
let mode = track<'a' | 'b'>('a');
|
|
36
|
-
let items = track([
|
|
32
|
+
let show = #ripple.track(true);
|
|
33
|
+
let mode = #ripple.track<'a' | 'b'>('a');
|
|
34
|
+
let items = #ripple.track([
|
|
37
35
|
{ id: 1, label: 'One' },
|
|
38
36
|
{ id: 2, label: 'Two' },
|
|
39
37
|
]);
|
|
@@ -108,7 +106,7 @@ export component MixedControlFlowAsyncPending() {
|
|
|
108
106
|
}
|
|
109
107
|
}
|
|
110
108
|
|
|
111
|
-
component AsyncRow({ label }) {
|
|
109
|
+
component AsyncRow({ label }: { label: string }) {
|
|
112
110
|
let value = await Promise.resolve(label);
|
|
113
111
|
<div class="resolved-row">{value}</div>
|
|
114
112
|
}
|
|
@@ -13,7 +13,7 @@ export component SimplePortal() {
|
|
|
13
13
|
|
|
14
14
|
// Portal with conditional rendering
|
|
15
15
|
export component ConditionalPortal() {
|
|
16
|
-
let show =
|
|
16
|
+
let show = #ripple.track(true);
|
|
17
17
|
|
|
18
18
|
<div class="container">
|
|
19
19
|
<button class="toggle" onClick={() => (@show = !@show)}>{'Toggle'}</button>
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
// Reactive components for hydration testing
|
|
2
|
-
import { track } from 'ripple';
|
|
3
2
|
|
|
4
3
|
export component TrackedState() {
|
|
5
|
-
let count = track(0);
|
|
4
|
+
let count = #ripple.track(0);
|
|
6
5
|
<div class="count">{@count}</div>
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
export component CounterWithInitial(props: { initial: number }) {
|
|
10
|
-
let count = track(props.initial);
|
|
9
|
+
let count = #ripple.track(props.initial);
|
|
11
10
|
<div>
|
|
12
11
|
<span class="count">{@count}</span>
|
|
13
12
|
</div>
|
|
@@ -18,24 +17,24 @@ export component CounterWrapper() {
|
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export component ComputedValues() {
|
|
21
|
-
let a = track(2);
|
|
22
|
-
let b = track(3);
|
|
20
|
+
let a = #ripple.track(2);
|
|
21
|
+
let b = #ripple.track(3);
|
|
23
22
|
const sum = () => @a + @b;
|
|
24
23
|
<div class="sum">{sum()}</div>
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export component MultipleTracked() {
|
|
28
|
-
let x = track(10);
|
|
29
|
-
let y = track(20);
|
|
30
|
-
let z = track(30);
|
|
27
|
+
let x = #ripple.track(10);
|
|
28
|
+
let y = #ripple.track(20);
|
|
29
|
+
let z = #ripple.track(30);
|
|
31
30
|
<div class="x">{@x}</div>
|
|
32
31
|
<div class="y">{@y}</div>
|
|
33
32
|
<div class="z">{@z}</div>
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
export component DerivedState() {
|
|
37
|
-
let firstName = track('John');
|
|
38
|
-
let lastName = track('Doe');
|
|
36
|
+
let firstName = #ripple.track('John');
|
|
37
|
+
let lastName = #ripple.track('Doe');
|
|
39
38
|
const fullName = () => `${@firstName} ${@lastName}`;
|
|
40
39
|
<div class="name">{fullName()}</div>
|
|
41
40
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// Return statement components for hydration testing
|
|
2
|
-
import { track } from 'ripple';
|
|
3
2
|
|
|
4
3
|
// Basic return - skips content after direct return
|
|
5
4
|
export component DirectReturn() {
|
|
@@ -265,7 +264,7 @@ export component ReturnWithElseBothReturn() {
|
|
|
265
264
|
|
|
266
265
|
// Reactive return - starts true, can toggle to false
|
|
267
266
|
export component ReactiveReturnTrueToFalse() {
|
|
268
|
-
let condition = track(true);
|
|
267
|
+
let condition = #ripple.track(true);
|
|
269
268
|
|
|
270
269
|
<button
|
|
271
270
|
class="toggle"
|
|
@@ -284,7 +283,7 @@ export component ReactiveReturnTrueToFalse() {
|
|
|
284
283
|
|
|
285
284
|
// Reactive return - starts false, can toggle to true
|
|
286
285
|
export component ReactiveReturnFalseToTrue() {
|
|
287
|
-
let condition = track(false);
|
|
286
|
+
let condition = #ripple.track(false);
|
|
288
287
|
|
|
289
288
|
<button
|
|
290
289
|
class="toggle"
|
|
@@ -304,7 +303,7 @@ export component ReactiveReturnFalseToTrue() {
|
|
|
304
303
|
// Reactive nested return - only inner condition (b) is tracked
|
|
305
304
|
export component ReactiveNestedReturn() {
|
|
306
305
|
let a = true;
|
|
307
|
-
let b = track(true);
|
|
306
|
+
let b = #ripple.track(true);
|
|
308
307
|
|
|
309
308
|
<button
|
|
310
309
|
class="toggle"
|
|
@@ -397,7 +396,7 @@ export component MultipleSiblingReturns() {
|
|
|
397
396
|
|
|
398
397
|
// Reactive sibling returns - cycles first -> second -> fallback
|
|
399
398
|
export component ReactiveSiblingReturns() {
|
|
400
|
-
let mode = track('first');
|
|
399
|
+
let mode = #ripple.track('first');
|
|
401
400
|
|
|
402
401
|
<button
|
|
403
402
|
class="toggle"
|
|
@@ -429,8 +428,8 @@ export component ReactiveSiblingReturns() {
|
|
|
429
428
|
|
|
430
429
|
// Reactive nested returns with tracked outer and inner conditions
|
|
431
430
|
export component ReactiveOuterInnerReturns() {
|
|
432
|
-
let a = track(true);
|
|
433
|
-
let b = track(true);
|
|
431
|
+
let a = #ripple.track(true);
|
|
432
|
+
let b = #ripple.track(true);
|
|
434
433
|
|
|
435
434
|
<button
|
|
436
435
|
class="toggle-a"
|
|
@@ -463,7 +462,7 @@ export component ReactiveOuterInnerReturns() {
|
|
|
463
462
|
|
|
464
463
|
// Reactive else-if return chain that transitions between return and non-return states
|
|
465
464
|
export component ReactiveElseIfReturns() {
|
|
466
|
-
let status = track(0);
|
|
465
|
+
let status = #ripple.track(0);
|
|
467
466
|
|
|
468
467
|
<button
|
|
469
468
|
class="toggle"
|
|
@@ -488,10 +487,10 @@ export component ReactiveElseIfReturns() {
|
|
|
488
487
|
|
|
489
488
|
// Deeply nested independent return guards with multiple root-level siblings
|
|
490
489
|
export component ReactiveDeepNestedIndependentReturns() {
|
|
491
|
-
let c1 = track(false);
|
|
492
|
-
let c2 = track(false);
|
|
493
|
-
let c3 = track(false);
|
|
494
|
-
let c4 = track(false);
|
|
490
|
+
let c1 = #ripple.track(false);
|
|
491
|
+
let c2 = #ripple.track(false);
|
|
492
|
+
let c3 = #ripple.track(false);
|
|
493
|
+
let c4 = #ripple.track(false);
|
|
495
494
|
|
|
496
495
|
<button
|
|
497
496
|
class="toggle-c1"
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { track } from 'ripple';
|
|
2
|
-
|
|
3
1
|
export component SwitchStatic() {
|
|
4
|
-
const status = 'success';
|
|
2
|
+
const status: string = 'success';
|
|
5
3
|
switch (status) {
|
|
6
4
|
case 'success':
|
|
7
5
|
<div class="status-success">{'Success'}</div>
|
|
@@ -15,7 +13,7 @@ export component SwitchStatic() {
|
|
|
15
13
|
}
|
|
16
14
|
|
|
17
15
|
export component SwitchReactive() {
|
|
18
|
-
let status = track<'a' | 'b' | 'c'>('a');
|
|
16
|
+
let status = #ripple.track<'a' | 'b' | 'c'>('a');
|
|
19
17
|
<button
|
|
20
18
|
class="toggle"
|
|
21
19
|
onClick={() => {
|
|
@@ -39,7 +37,7 @@ export component SwitchReactive() {
|
|
|
39
37
|
}
|
|
40
38
|
|
|
41
39
|
export component SwitchFallthrough() {
|
|
42
|
-
const val = 1;
|
|
40
|
+
const val: number = 1;
|
|
43
41
|
switch (val) {
|
|
44
42
|
case 1:
|
|
45
43
|
case 2:
|
|
@@ -51,7 +49,7 @@ export component SwitchFallthrough() {
|
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
export component SwitchNumericLevels() {
|
|
54
|
-
let level = track<1 | 2 | 3>(1);
|
|
52
|
+
let level = #ripple.track<1 | 2 | 3>(1);
|
|
55
53
|
<button
|
|
56
54
|
class="level-toggle"
|
|
57
55
|
onClick={() => {
|
|
@@ -76,7 +74,7 @@ export component SwitchNumericLevels() {
|
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
export component SwitchBlockScoped() {
|
|
79
|
-
let level = track<1 | 2 | 3>(1);
|
|
77
|
+
let level = #ripple.track<1 | 2 | 3>(1);
|
|
80
78
|
<button
|
|
81
79
|
class="block-toggle"
|
|
82
80
|
onClick={() => {
|
|
@@ -104,7 +102,7 @@ export component SwitchBlockScoped() {
|
|
|
104
102
|
}
|
|
105
103
|
|
|
106
104
|
export component SwitchNoBreak() {
|
|
107
|
-
let level = track<1 | 2 | 3>(1);
|
|
105
|
+
let level = #ripple.track<1 | 2 | 3>(1);
|
|
108
106
|
<button
|
|
109
107
|
class="nobreak-toggle"
|
|
110
108
|
onClick={() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { set, get } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('await in control flow', () => {
|
|
4
4
|
it('all tests are commented out for now as await in control flow is not yet supported', () => {
|
|
@@ -8,7 +8,7 @@ describe('await in control flow', () => {
|
|
|
8
8
|
// it('should handle await inside if statement', async () => {
|
|
9
9
|
// component App() {
|
|
10
10
|
// let condition = true;
|
|
11
|
-
// let data = track('loading');
|
|
11
|
+
// let data = #ripple.track('loading');
|
|
12
12
|
|
|
13
13
|
// if (condition) {
|
|
14
14
|
// await new Promise((resolve) => setTimeout(() => {
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { track } from 'ripple';
|
|
2
|
-
|
|
3
1
|
describe('basic server > attribute rendering', () => {
|
|
4
2
|
it('render static attributes', async () => {
|
|
5
3
|
component Basic() {
|
|
@@ -19,7 +17,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
19
17
|
|
|
20
18
|
it('render dynamic class attribute', async () => {
|
|
21
19
|
component Basic() {
|
|
22
|
-
let active = track(false);
|
|
20
|
+
let active = #ripple.track(false);
|
|
23
21
|
|
|
24
22
|
<div class={@active ? 'active' : 'inactive'}>{'Dynamic Class'}</div>
|
|
25
23
|
|
|
@@ -89,7 +87,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
89
87
|
|
|
90
88
|
it('render dynamic class object', async () => {
|
|
91
89
|
component Basic() {
|
|
92
|
-
let active = track(false);
|
|
90
|
+
let active = #ripple.track(false);
|
|
93
91
|
|
|
94
92
|
<div class={{ active: @active, inactive: !@active }}>{'Dynamic Class'}</div>
|
|
95
93
|
|
|
@@ -116,7 +114,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
116
114
|
'applies scoped ripple class to multiple elements with dynamic class expressions',
|
|
117
115
|
async () => {
|
|
118
116
|
component Basic() {
|
|
119
|
-
let selected = track(1);
|
|
117
|
+
let selected = #ripple.track(1);
|
|
120
118
|
|
|
121
119
|
<div class={@selected === 0 ? 'selected' : ''}>{`div 1`}</div>
|
|
122
120
|
<div class={@selected === 0 ? 'selected' : ''}>{`div 2`}</div>
|
|
@@ -147,7 +145,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
147
145
|
|
|
148
146
|
it('render dynamic id attribute', async () => {
|
|
149
147
|
component Basic() {
|
|
150
|
-
let count = track(0);
|
|
148
|
+
let count = #ripple.track(0);
|
|
151
149
|
|
|
152
150
|
<div id={`item-${@count}`}>{'Dynamic ID'}</div>
|
|
153
151
|
}
|
|
@@ -162,7 +160,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
162
160
|
|
|
163
161
|
it('render dynamic style attribute', async () => {
|
|
164
162
|
component Basic() {
|
|
165
|
-
let color = track('red');
|
|
163
|
+
let color = #ripple.track('red');
|
|
166
164
|
|
|
167
165
|
<div style={`color: ${@color}; font-weight: bold;`}>{'Dynamic Style'}</div>
|
|
168
166
|
}
|
|
@@ -178,7 +176,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
178
176
|
|
|
179
177
|
it('render style attribute as dynamic object', async () => {
|
|
180
178
|
component Basic() {
|
|
181
|
-
let color = track('red');
|
|
179
|
+
let color = #ripple.track('red');
|
|
182
180
|
|
|
183
181
|
<div style={{ color: @color, fontWeight: 'bold' }}>{'Dynamic Style'}</div>
|
|
184
182
|
}
|
|
@@ -194,7 +192,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
194
192
|
|
|
195
193
|
it('render tracked variable as style attribute', async () => {
|
|
196
194
|
component Basic() {
|
|
197
|
-
let style = track({ color: 'red', fontWeight: 'bold' });
|
|
195
|
+
let style = #ripple.track({ color: 'red', fontWeight: 'bold' });
|
|
198
196
|
|
|
199
197
|
<div {@style}>{'Dynamic Style'}</div>
|
|
200
198
|
}
|
|
@@ -210,7 +208,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
210
208
|
|
|
211
209
|
it('render tracked object as style attribute', async () => {
|
|
212
210
|
component Basic() {
|
|
213
|
-
let style = #{ color: 'red', fontWeight: 'bold' };
|
|
211
|
+
let style = #ripple{ color: 'red', fontWeight: 'bold' };
|
|
214
212
|
|
|
215
213
|
<div style={{ color: style.color, fontWeight: style.fontWeight }}>{'Dynamic Style'}</div>
|
|
216
214
|
}
|
|
@@ -277,8 +275,8 @@ describe('basic server > attribute rendering', () => {
|
|
|
277
275
|
|
|
278
276
|
it('render dynamic boolean attributes as false', async () => {
|
|
279
277
|
component Basic() {
|
|
280
|
-
let disabled = track(false);
|
|
281
|
-
let checked = track(false);
|
|
278
|
+
let disabled = #ripple.track(false);
|
|
279
|
+
let checked = #ripple.track(false);
|
|
282
280
|
|
|
283
281
|
<input type="checkbox" {@disabled} {@checked} />
|
|
284
282
|
}
|
|
@@ -312,8 +310,8 @@ describe('basic server > attribute rendering', () => {
|
|
|
312
310
|
|
|
313
311
|
it('render dynamic boolean attributes as true', async () => {
|
|
314
312
|
component Basic() {
|
|
315
|
-
let disabled = track(true);
|
|
316
|
-
let checked = track(true);
|
|
313
|
+
let disabled = #ripple.track(true);
|
|
314
|
+
let checked = #ripple.track(true);
|
|
317
315
|
|
|
318
316
|
<input type="checkbox" {@disabled} {@checked} />
|
|
319
317
|
}
|
|
@@ -347,8 +345,8 @@ describe('basic server > attribute rendering', () => {
|
|
|
347
345
|
|
|
348
346
|
it('render multiple dynamic attributes', async () => {
|
|
349
347
|
component Basic() {
|
|
350
|
-
let theme = track('light');
|
|
351
|
-
let size = track('medium');
|
|
348
|
+
let theme = #ripple.track('light');
|
|
349
|
+
let size = #ripple.track('medium');
|
|
352
350
|
|
|
353
351
|
<div class={`theme-${@theme} size-${@size}`} data-theme={@theme} data-size={@size}>
|
|
354
352
|
{'Multiple Dynamic Attributes'}
|
|
@@ -367,8 +365,8 @@ describe('basic server > attribute rendering', () => {
|
|
|
367
365
|
|
|
368
366
|
it('render conditional attributes', async () => {
|
|
369
367
|
component Basic() {
|
|
370
|
-
let showTitle = track(false);
|
|
371
|
-
let showAria = track(false);
|
|
368
|
+
let showTitle = #ripple.track(false);
|
|
369
|
+
let showAria = #ripple.track(false);
|
|
372
370
|
|
|
373
371
|
<div
|
|
374
372
|
title={@showTitle ? 'This is a title' : undefined}
|
|
@@ -389,7 +387,7 @@ describe('basic server > attribute rendering', () => {
|
|
|
389
387
|
|
|
390
388
|
it('render spread attributes', async () => {
|
|
391
389
|
component Basic() {
|
|
392
|
-
let attrs = track<TestAttributes>(
|
|
390
|
+
let attrs = #ripple.track<TestAttributes>(
|
|
393
391
|
{
|
|
394
392
|
class: 'initial',
|
|
395
393
|
id: 'test-1',
|
|
@@ -411,12 +409,12 @@ describe('basic server > attribute rendering', () => {
|
|
|
411
409
|
|
|
412
410
|
it('renders with reactive attributes with nested reactive attributes', async () => {
|
|
413
411
|
component Basic() {
|
|
414
|
-
let value = track('parent-class');
|
|
412
|
+
let value = #ripple.track('parent-class');
|
|
415
413
|
|
|
416
414
|
<p class={@value}>{'Colored parent value'}</p>
|
|
417
415
|
|
|
418
416
|
<div>
|
|
419
|
-
let nested = track('nested-class');
|
|
417
|
+
let nested = #ripple.track('nested-class');
|
|
420
418
|
|
|
421
419
|
<p class={@nested}>{'Colored nested value'}</p>
|
|
422
420
|
</div>
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
Tracked,
|
|
3
|
+
PropsWithChildren,
|
|
4
|
+
PropsWithExtras,
|
|
5
|
+
Component,
|
|
6
|
+
PropsWithChildrenOptional,
|
|
7
|
+
} from 'ripple';
|
|
3
8
|
|
|
4
9
|
describe('basic server > components & composition', () => {
|
|
5
10
|
it('renders with component composition and children', async () => {
|
|
@@ -28,8 +33,9 @@ describe('basic server > components & composition', () => {
|
|
|
28
33
|
});
|
|
29
34
|
|
|
30
35
|
it('does not render a falsy component call', async () => {
|
|
31
|
-
component Card(props:
|
|
36
|
+
component Card(props: PropsWithChildrenOptional<{ test: Component }>) {
|
|
32
37
|
<div class="card">
|
|
38
|
+
// @ts-expect-error - ripple automatically handles falsy children
|
|
33
39
|
<props.children />
|
|
34
40
|
</div>
|
|
35
41
|
}
|
|
@@ -100,7 +106,7 @@ describe('basic server > components & composition', () => {
|
|
|
100
106
|
}
|
|
101
107
|
|
|
102
108
|
component Basic() {
|
|
103
|
-
let clicked = track(false);
|
|
109
|
+
let clicked = #ripple.track(false);
|
|
104
110
|
|
|
105
111
|
<Card
|
|
106
112
|
title="Test Card"
|
|
@@ -137,8 +143,8 @@ describe('basic server > components & composition', () => {
|
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
component Basic() {
|
|
140
|
-
let message = track('Hello');
|
|
141
|
-
let number = track(1);
|
|
146
|
+
let message = #ripple.track('Hello');
|
|
147
|
+
let number = #ripple.track(1);
|
|
142
148
|
|
|
143
149
|
<ChildComponent text={message} count={number} />
|
|
144
150
|
<button
|
|
@@ -225,7 +231,7 @@ describe('basic server > components & composition', () => {
|
|
|
225
231
|
}
|
|
226
232
|
|
|
227
233
|
component App() {
|
|
228
|
-
let Content = track(() => Noop);
|
|
234
|
+
let Content = #ripple.track(() => Noop);
|
|
229
235
|
<@Content />
|
|
230
236
|
}
|
|
231
237
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Tracked, PropsNoChildren } from 'ripple';
|
|
2
|
-
import { track } from 'ripple';
|
|
3
2
|
|
|
4
3
|
describe('basic client', () => {
|
|
5
4
|
it('render static text', async () => {
|
|
@@ -15,7 +14,7 @@ describe('basic client', () => {
|
|
|
15
14
|
|
|
16
15
|
it('renders tracked state updates', async () => {
|
|
17
16
|
component Counter() {
|
|
18
|
-
const count = track(0);
|
|
17
|
+
const count = #ripple.track(0);
|
|
19
18
|
|
|
20
19
|
@count++;
|
|
21
20
|
@count = @count + 5;
|
|
@@ -38,8 +37,8 @@ describe('basic client', () => {
|
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
component Parent() {
|
|
41
|
-
const count = track(10);
|
|
42
|
-
let Dynamic = track(() => Child);
|
|
40
|
+
const count = #ripple.track(10);
|
|
41
|
+
let Dynamic = #ripple.track(() => Child);
|
|
43
42
|
|
|
44
43
|
<@Dynamic {count} class={{ test: true }} />
|
|
45
44
|
}
|
|
@@ -51,7 +50,7 @@ describe('basic client', () => {
|
|
|
51
50
|
|
|
52
51
|
it('renders tracked object properties', async () => {
|
|
53
52
|
component ObjCounter() {
|
|
54
|
-
const obj = { count: track(2) };
|
|
53
|
+
const obj = { count: #ripple.track(2) };
|
|
55
54
|
|
|
56
55
|
obj.@count += 3;
|
|
57
56
|
obj.@count = obj.@count + 1;
|
|
@@ -66,9 +65,9 @@ describe('basic client', () => {
|
|
|
66
65
|
|
|
67
66
|
it('renders spread props with tracked values', async () => {
|
|
68
67
|
component SpreadProps() {
|
|
69
|
-
const id = track('unique-id');
|
|
70
|
-
const isActive = track(true);
|
|
71
|
-
const styles = track({ color: 'red', fontSize: '16px' });
|
|
68
|
+
const id = #ripple.track('unique-id');
|
|
69
|
+
const isActive = #ripple.track(true);
|
|
70
|
+
const styles = #ripple.track({ color: 'red', fontSize: '16px' });
|
|
72
71
|
|
|
73
72
|
<div {...{ id: @id, class: { active: @isActive }, style: @styles }}>{'Spread Props'}</div>
|
|
74
73
|
}
|
|
@@ -82,8 +81,8 @@ describe('basic client', () => {
|
|
|
82
81
|
|
|
83
82
|
it('handles AssignExpressions with tracked values or properties correctly', async () => {
|
|
84
83
|
component Assignments() {
|
|
85
|
-
const count = track(0);
|
|
86
|
-
const obj = { value: track(5) };
|
|
84
|
+
const count = #ripple.track(0);
|
|
85
|
+
const obj = { value: #ripple.track(5) };
|
|
87
86
|
|
|
88
87
|
@count += 10;
|
|
89
88
|
obj.@value *= 2;
|
|
@@ -99,9 +98,9 @@ describe('basic client', () => {
|
|
|
99
98
|
|
|
100
99
|
it(`handles derived changes via tracked dependencies' changes`, async () => {
|
|
101
100
|
component Derived() {
|
|
102
|
-
let base = track(5);
|
|
103
|
-
let multiplier = track(3);
|
|
104
|
-
const derived = track(() => @base * @multiplier);
|
|
101
|
+
let base = #ripple.track(5);
|
|
102
|
+
let multiplier = #ripple.track(3);
|
|
103
|
+
const derived = #ripple.track(() => @base * @multiplier);
|
|
105
104
|
|
|
106
105
|
<div>{@derived}</div>
|
|
107
106
|
|
|
@@ -118,10 +117,10 @@ describe('basic client', () => {
|
|
|
118
117
|
|
|
119
118
|
it(`handles derived changes based on another derived's dependencies' changes`, async () => {
|
|
120
119
|
component NestedDerived() {
|
|
121
|
-
let a = track(2);
|
|
122
|
-
let b = track(3);
|
|
123
|
-
const sum = track(() => @a + @b);
|
|
124
|
-
const product = track(() => @sum * 2);
|
|
120
|
+
let a = #ripple.track(2);
|
|
121
|
+
let b = #ripple.track(3);
|
|
122
|
+
const sum = #ripple.track(() => @a + @b);
|
|
123
|
+
const product = #ripple.track(() => @sum * 2);
|
|
125
124
|
|
|
126
125
|
<div>{@product}</div>
|
|
127
126
|
|
|
@@ -138,19 +137,19 @@ describe('basic client', () => {
|
|
|
138
137
|
|
|
139
138
|
it('handles lexical scopes correctly', async () => {
|
|
140
139
|
component LexicalScopes() {
|
|
141
|
-
let x = track(1);
|
|
140
|
+
let x = #ripple.track(1);
|
|
142
141
|
<div>{@x}</div>
|
|
143
142
|
|
|
144
143
|
<div>
|
|
145
|
-
let x = track(10);
|
|
144
|
+
let x = #ripple.track(10);
|
|
146
145
|
{@x}
|
|
147
146
|
</div>
|
|
148
147
|
|
|
149
148
|
<div>
|
|
150
|
-
let x = track(12);
|
|
149
|
+
let x = #ripple.track(12);
|
|
151
150
|
{@x}
|
|
152
151
|
<span>
|
|
153
|
-
let x = track(15);
|
|
152
|
+
let x = #ripple.track(15);
|
|
154
153
|
{@x}
|
|
155
154
|
</span>
|
|
156
155
|
</div>
|
|
@@ -67,7 +67,7 @@ export component Layout(props) {
|
|
|
67
67
|
describe('compiler server block tests', () => {
|
|
68
68
|
it('compiles server block with with only supported types', () => {
|
|
69
69
|
const source = `
|
|
70
|
-
#server {
|
|
70
|
+
#ripple.server {
|
|
71
71
|
function something() {
|
|
72
72
|
return 'unexported function';
|
|
73
73
|
}
|
|
@@ -105,7 +105,7 @@ describe('compiler server block tests', () => {
|
|
|
105
105
|
|
|
106
106
|
it('throws error for unsupported exported object pattern in server block', () => {
|
|
107
107
|
const source = `
|
|
108
|
-
#server {
|
|
108
|
+
#ripple.server {
|
|
109
109
|
const obj = { fn1: () => {}, fn2: () => {} };
|
|
110
110
|
|
|
111
111
|
export const { fn1, fn2 } = obj;
|
|
@@ -116,7 +116,7 @@ describe('compiler server block tests', () => {
|
|
|
116
116
|
|
|
117
117
|
it('throws error for unsupported exported array pattern in server block', () => {
|
|
118
118
|
const source = `
|
|
119
|
-
#server {
|
|
119
|
+
#ripple.server {
|
|
120
120
|
const arr = [() => {}, () => {}];
|
|
121
121
|
|
|
122
122
|
export const [fnarr1, fnarr2] = arr;
|
|
@@ -127,7 +127,7 @@ describe('compiler server block tests', () => {
|
|
|
127
127
|
|
|
128
128
|
it('throws error for unsupported exported member expression via object in server block', () => {
|
|
129
129
|
const source = `
|
|
130
|
-
#server {
|
|
130
|
+
#ripple.server {
|
|
131
131
|
const obj = { fn1: () => {}, fn2: () => {} };
|
|
132
132
|
|
|
133
133
|
export const objProp = obj.fn1;
|
|
@@ -138,7 +138,7 @@ describe('compiler server block tests', () => {
|
|
|
138
138
|
|
|
139
139
|
it('throws error for unsupported exported member expression via array in server block', () => {
|
|
140
140
|
const source = `
|
|
141
|
-
#server {
|
|
141
|
+
#ripple.server {
|
|
142
142
|
const arr = [() => {}, () => {}];
|
|
143
143
|
|
|
144
144
|
export const arrIndex0 = arr[0];
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Tracked, Props } from 'ripple';
|
|
2
|
-
import { track, trackSplit } from 'ripple';
|
|
3
2
|
|
|
4
3
|
describe('composite > props', () => {
|
|
5
4
|
it('correctly handles default prop values', async () => {
|
|
@@ -8,7 +7,7 @@ describe('composite > props', () => {
|
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
component App() {
|
|
11
|
-
let foo = track(123);
|
|
10
|
+
let foo = #ripple.track(123);
|
|
12
11
|
|
|
13
12
|
<Child />
|
|
14
13
|
<Child {@foo} />
|
|
@@ -46,7 +45,7 @@ describe('composite > props', () => {
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
component App() {
|
|
49
|
-
let foo = track(123);
|
|
48
|
+
let foo = #ripple.track(123);
|
|
50
49
|
|
|
51
50
|
<Child />
|
|
52
51
|
<Child {foo} />
|
|
@@ -65,7 +64,7 @@ describe('composite > props', () => {
|
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
component App() {
|
|
68
|
-
let foo = track(123);
|
|
67
|
+
let foo = #ripple.track(123);
|
|
69
68
|
|
|
70
69
|
<Child />
|
|
71
70
|
<Child {@foo} />
|
|
@@ -80,7 +79,7 @@ describe('composite > props', () => {
|
|
|
80
79
|
|
|
81
80
|
it('correctly retains prop accessors and reactivity when using rest props', async () => {
|
|
82
81
|
component Button(props: Props) {
|
|
83
|
-
const [children, rest] = trackSplit(props, ['children']);
|
|
82
|
+
const [children, rest] = #ripple.trackSplit(props, ['children']);
|
|
84
83
|
<button {...@rest}>
|
|
85
84
|
<@children />
|
|
86
85
|
</button>
|
|
@@ -95,14 +94,14 @@ describe('composite > props', () => {
|
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
component Toggle(props: { pressed: Tracked<boolean> }) {
|
|
98
|
-
const [pressed, rest] = trackSplit(props, ['pressed']);
|
|
97
|
+
const [pressed, rest] = #ripple.trackSplit(props, ['pressed']);
|
|
99
98
|
const onClick = () => (@pressed = !@pressed);
|
|
100
99
|
<Button {...@rest} class={@pressed ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
|
|
101
100
|
<Button class={@pressed ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
component App() {
|
|
105
|
-
const pressed = track(true);
|
|
104
|
+
const pressed = #ripple.track(true);
|
|
106
105
|
<Toggle {pressed} />
|
|
107
106
|
}
|
|
108
107
|
|