ripple 0.3.6 → 0.3.8
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 +43 -0
- package/package.json +2 -2
- package/src/compiler/phases/1-parse/index.js +37 -194
- package/src/compiler/phases/2-analyze/index.js +290 -26
- package/src/compiler/phases/3-transform/client/index.js +54 -14
- package/src/compiler/phases/3-transform/server/index.js +19 -35
- package/src/compiler/types/index.d.ts +3 -1
- package/src/compiler/types/parse.d.ts +0 -8
- package/src/compiler/utils.js +10 -6
- package/src/runtime/internal/client/composite.js +2 -2
- package/src/runtime/internal/client/index.js +2 -0
- package/src/runtime/internal/client/runtime.js +95 -45
- package/src/runtime/internal/client/types.d.ts +10 -0
- package/src/runtime/internal/client/utils.js +12 -0
- package/src/runtime/internal/server/index.js +89 -17
- package/src/runtime/internal/server/types.d.ts +10 -0
- package/src/utils/ast.js +1 -1
- package/tests/client/array/array.copy-within.test.ripple +12 -12
- package/tests/client/array/array.derived.test.ripple +46 -46
- package/tests/client/array/array.iteration.test.ripple +10 -10
- package/tests/client/array/array.mutations.test.ripple +20 -20
- package/tests/client/array/array.to-methods.test.ripple +6 -6
- package/tests/client/async-suspend.test.ripple +5 -5
- package/tests/client/basic/basic.attributes.test.ripple +81 -81
- package/tests/client/basic/basic.collections.test.ripple +9 -9
- package/tests/client/basic/basic.components.test.ripple +28 -28
- package/tests/client/basic/basic.errors.test.ripple +18 -18
- package/tests/client/basic/basic.events.test.ripple +37 -37
- package/tests/client/basic/basic.get-set.test.ripple +6 -6
- package/tests/client/basic/basic.reactivity.test.ripple +68 -68
- package/tests/client/basic/basic.rendering.test.ripple +19 -19
- package/tests/client/basic/basic.utilities.test.ripple +3 -3
- package/tests/client/boundaries.test.ripple +12 -12
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
- package/tests/client/compiler/compiler.basic.test.ripple +44 -15
- package/tests/client/compiler/compiler.tracked-access.test.ripple +68 -2
- package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
- package/tests/client/composite/composite.props.test.ripple +11 -11
- package/tests/client/composite/composite.reactivity.test.ripple +43 -43
- package/tests/client/composite/composite.render.test.ripple +3 -3
- package/tests/client/computed-properties.test.ripple +4 -4
- package/tests/client/date.test.ripple +42 -42
- package/tests/client/dynamic-elements.test.ripple +42 -42
- package/tests/client/events.test.ripple +70 -70
- package/tests/client/for.test.ripple +25 -25
- package/tests/client/head.test.ripple +19 -19
- package/tests/client/html.test.ripple +3 -3
- package/tests/client/input-value.test.ripple +84 -84
- package/tests/client/lazy-destructuring.test.ripple +123 -14
- package/tests/client/map.test.ripple +16 -16
- package/tests/client/media-query.test.ripple +7 -7
- package/tests/client/portal.test.ripple +11 -11
- package/tests/client/ref.test.ripple +4 -4
- package/tests/client/return.test.ripple +52 -52
- package/tests/client/set.test.ripple +6 -6
- package/tests/client/svg.test.ripple +5 -5
- package/tests/client/switch.test.ripple +44 -44
- package/tests/client/try.test.ripple +5 -5
- package/tests/client/url/url.derived.test.ripple +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
- package/tests/hydration/compiled/client/events.js +25 -25
- package/tests/hydration/compiled/client/for.js +70 -66
- package/tests/hydration/compiled/client/head.js +25 -25
- package/tests/hydration/compiled/client/hmr.js +2 -2
- package/tests/hydration/compiled/client/html.js +3 -3
- package/tests/hydration/compiled/client/if-children.js +24 -24
- package/tests/hydration/compiled/client/if.js +18 -18
- package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
- package/tests/hydration/compiled/client/portal.js +3 -3
- package/tests/hydration/compiled/client/reactivity.js +16 -16
- package/tests/hydration/compiled/client/return.js +40 -40
- package/tests/hydration/compiled/client/switch.js +12 -12
- package/tests/hydration/compiled/server/events.js +19 -19
- package/tests/hydration/compiled/server/for.js +41 -41
- package/tests/hydration/compiled/server/head.js +26 -26
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +2 -2
- package/tests/hydration/compiled/server/if-children.js +16 -16
- package/tests/hydration/compiled/server/if.js +11 -11
- package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
- package/tests/hydration/compiled/server/portal.js +2 -2
- package/tests/hydration/compiled/server/reactivity.js +16 -16
- package/tests/hydration/compiled/server/return.js +25 -25
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/components/events.ripple +25 -25
- package/tests/hydration/components/for.ripple +66 -66
- package/tests/hydration/components/head.ripple +16 -16
- package/tests/hydration/components/hmr.ripple +2 -2
- package/tests/hydration/components/html.ripple +3 -3
- package/tests/hydration/components/if-children.ripple +24 -24
- package/tests/hydration/components/if.ripple +18 -18
- package/tests/hydration/components/mixed-control-flow.ripple +9 -9
- package/tests/hydration/components/portal.ripple +3 -3
- package/tests/hydration/components/reactivity.ripple +16 -16
- package/tests/hydration/components/return.ripple +40 -40
- package/tests/hydration/components/switch.ripple +20 -20
- package/tests/server/await.test.ripple +3 -3
- package/tests/server/basic.attributes.test.ripple +34 -34
- package/tests/server/basic.components.test.ripple +10 -10
- package/tests/server/basic.test.ripple +38 -40
- package/tests/server/composite.props.test.ripple +9 -9
- package/tests/server/dynamic-elements.test.ripple +13 -12
- package/tests/server/head.test.ripple +11 -11
- package/tests/server/lazy-destructuring.test.ripple +72 -0
- package/types/index.d.ts +7 -2
|
@@ -27,16 +27,16 @@ describe('basic client > rendering & text', () => {
|
|
|
27
27
|
|
|
28
28
|
it('renders dynamic text', () => {
|
|
29
29
|
component Basic() {
|
|
30
|
-
let text = track('Hello World');
|
|
30
|
+
let &[text] = track('Hello World');
|
|
31
31
|
|
|
32
32
|
<button
|
|
33
33
|
onClick={() => {
|
|
34
|
-
|
|
34
|
+
text = 'Hello Ripple';
|
|
35
35
|
}}
|
|
36
36
|
>
|
|
37
37
|
{'Change Text'}
|
|
38
38
|
</button>
|
|
39
|
-
<div>{
|
|
39
|
+
<div>{text}</div>
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
render(Basic);
|
|
@@ -104,24 +104,24 @@ describe('basic client > rendering & text', () => {
|
|
|
104
104
|
|
|
105
105
|
it('renders with mixed static and dynamic content', () => {
|
|
106
106
|
component Basic() {
|
|
107
|
-
let name = track('World');
|
|
108
|
-
let count = track(0);
|
|
107
|
+
let &[name] = track('World');
|
|
108
|
+
let &[count] = track(0);
|
|
109
109
|
const staticMessage = 'Welcome to Ripple!';
|
|
110
110
|
|
|
111
111
|
<div class="mixed-content">
|
|
112
112
|
<h1>{staticMessage}</h1>
|
|
113
|
-
<p class="greeting">{'Hello, ' +
|
|
114
|
-
<p class="notifications">{'You have ' +
|
|
113
|
+
<p class="greeting">{'Hello, ' + name + '!'}</p>
|
|
114
|
+
<p class="notifications">{'You have ' + count + ' notifications'}</p>
|
|
115
115
|
<button
|
|
116
116
|
onClick={() => {
|
|
117
|
-
|
|
117
|
+
count++;
|
|
118
118
|
}}
|
|
119
119
|
>
|
|
120
120
|
{'Add Notification'}
|
|
121
121
|
</button>
|
|
122
122
|
<button
|
|
123
123
|
onClick={() => {
|
|
124
|
-
|
|
124
|
+
name = name === 'World' ? 'User' : 'World';
|
|
125
125
|
}}
|
|
126
126
|
>
|
|
127
127
|
{'Toggle Name'}
|
|
@@ -151,11 +151,11 @@ describe('basic client > rendering & text', () => {
|
|
|
151
151
|
|
|
152
152
|
it('basic operations', () => {
|
|
153
153
|
component App() {
|
|
154
|
-
let count = track(0);
|
|
155
|
-
<div>{
|
|
156
|
-
<div>{
|
|
154
|
+
let &[count] = track(0);
|
|
155
|
+
<div>{count++}</div>
|
|
156
|
+
<div>{++count}</div>
|
|
157
157
|
<div>{5}</div>
|
|
158
|
-
<div>{
|
|
158
|
+
<div>{count}</div>
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
render(App);
|
|
@@ -164,27 +164,27 @@ describe('basic client > rendering & text', () => {
|
|
|
164
164
|
|
|
165
165
|
it('renders with conditional rendering using if statements', () => {
|
|
166
166
|
component Basic() {
|
|
167
|
-
let showContent = track(false);
|
|
168
|
-
let userRole = track('guest');
|
|
167
|
+
let &[showContent] = track(false);
|
|
168
|
+
let &[userRole] = track('guest');
|
|
169
169
|
|
|
170
170
|
<button
|
|
171
171
|
onClick={() => {
|
|
172
|
-
|
|
172
|
+
showContent = !showContent;
|
|
173
173
|
}}
|
|
174
174
|
>
|
|
175
175
|
{'Toggle Content'}
|
|
176
176
|
</button>
|
|
177
177
|
<button
|
|
178
178
|
onClick={() => {
|
|
179
|
-
|
|
179
|
+
userRole = userRole === 'guest' ? 'admin' : 'guest';
|
|
180
180
|
}}
|
|
181
181
|
>
|
|
182
182
|
{'Toggle Role'}
|
|
183
183
|
</button>
|
|
184
184
|
|
|
185
185
|
<div class="content">
|
|
186
|
-
if (
|
|
187
|
-
if (
|
|
186
|
+
if (showContent) {
|
|
187
|
+
if (userRole === 'admin') {
|
|
188
188
|
<div class="admin-content">{'Admin content'}</div>
|
|
189
189
|
} else {
|
|
190
190
|
<div class="user-content">{'User content'}</div>
|
|
@@ -6,14 +6,14 @@ describe('basic client > utilities', () => {
|
|
|
6
6
|
const promise = new Promise<void>((res) => (resolve = res));
|
|
7
7
|
|
|
8
8
|
component Basic() {
|
|
9
|
-
let value = track(0);
|
|
9
|
+
let &[value] = track(0);
|
|
10
10
|
effect(() => {
|
|
11
11
|
untrack(() => {
|
|
12
|
-
|
|
12
|
+
value++;
|
|
13
13
|
tick().then(() => resolve());
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
|
-
<p>{
|
|
16
|
+
<p>{value}</p>
|
|
17
17
|
}
|
|
18
18
|
render(Basic);
|
|
19
19
|
|
|
@@ -4,25 +4,25 @@ describe('passing reactivity between boundaries tests', () => {
|
|
|
4
4
|
it('can pass reactivity between functions with simple arrays and destructuring', () => {
|
|
5
5
|
let log: string[] = [];
|
|
6
6
|
|
|
7
|
-
function createDouble([count]:
|
|
8
|
-
const double = track(() =>
|
|
7
|
+
function createDouble(&[count]: Tracked<number>) {
|
|
8
|
+
const double = track(() => count * 2);
|
|
9
9
|
|
|
10
10
|
effect(() => {
|
|
11
|
-
log.push('Count:' +
|
|
11
|
+
log.push('Count:' + count);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
return
|
|
14
|
+
return double;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
component App() {
|
|
18
|
-
let count = track(0);
|
|
18
|
+
let &[count, countTracked] = track(0);
|
|
19
19
|
|
|
20
|
-
const [double] = createDouble(
|
|
20
|
+
const &[double] = createDouble(countTracked);
|
|
21
21
|
|
|
22
|
-
<div>{'Double: ' +
|
|
22
|
+
<div>{'Double: ' + double}</div>
|
|
23
23
|
<button
|
|
24
24
|
onClick={() => {
|
|
25
|
-
|
|
25
|
+
count++;
|
|
26
26
|
}}
|
|
27
27
|
>
|
|
28
28
|
{'Increment'}
|
|
@@ -54,10 +54,10 @@ describe('passing reactivity between boundaries tests', () => {
|
|
|
54
54
|
let log: string[] = [];
|
|
55
55
|
|
|
56
56
|
function createDouble({ count }: { count: Tracked<number> }) {
|
|
57
|
-
const double = track(() =>
|
|
57
|
+
const double = track(() => count.value * 2);
|
|
58
58
|
|
|
59
59
|
effect(() => {
|
|
60
|
-
log.push('Count:' +
|
|
60
|
+
log.push('Count:' + count.value);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
return { double };
|
|
@@ -68,10 +68,10 @@ describe('passing reactivity between boundaries tests', () => {
|
|
|
68
68
|
|
|
69
69
|
const { double } = createDouble({ count });
|
|
70
70
|
|
|
71
|
-
<div>{'Double: ' +
|
|
71
|
+
<div>{'Double: ' + double.value}</div>
|
|
72
72
|
<button
|
|
73
73
|
onClick={() => {
|
|
74
|
-
|
|
74
|
+
count.value++;
|
|
75
75
|
}}
|
|
76
76
|
>
|
|
77
77
|
{'Increment'}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`compiler > assignments > compiles tracked values in effect with assignment expression 1`] = `"state.count = _$_.get(
|
|
3
|
+
exports[`compiler > assignments > compiles tracked values in effect with assignment expression 1`] = `"state.count = _$_.get(lazy);"`;
|
|
4
4
|
|
|
5
5
|
exports[`compiler > assignments > compiles tracked values in effect with update expressions 1`] = `
|
|
6
6
|
"_$_.untrack(() => {
|
|
7
|
-
state.preIncrement = _$_.update_pre(
|
|
8
|
-
state.postIncrement = _$_.update(
|
|
9
|
-
state.preDecrement = _$_.update_pre(
|
|
10
|
-
state.postDecrement = _$_.update(
|
|
7
|
+
state.preIncrement = _$_.update_pre(lazy);
|
|
8
|
+
state.postIncrement = _$_.update(lazy);
|
|
9
|
+
state.preDecrement = _$_.update_pre(lazy, -1);
|
|
10
|
+
state.postDecrement = _$_.update(lazy, -1);
|
|
11
11
|
});"
|
|
12
12
|
`;
|
|
@@ -16,8 +16,8 @@ describe('compiler > assignments', () => {
|
|
|
16
16
|
|
|
17
17
|
logs.push(items[0]);
|
|
18
18
|
logs.push(items[i]);
|
|
19
|
-
logs.push(
|
|
20
|
-
logs.push(
|
|
19
|
+
logs.push(tracked_items.value[0]);
|
|
20
|
+
logs.push(tracked_items.value[i]);
|
|
21
21
|
logs.push(items2[0]);
|
|
22
22
|
logs.push(items2[i]);
|
|
23
23
|
logs.push(items3[0]);
|
|
@@ -25,8 +25,8 @@ describe('compiler > assignments', () => {
|
|
|
25
25
|
|
|
26
26
|
items[0] = 123;
|
|
27
27
|
items[i] = 123;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
tracked_items.value[0] = 123;
|
|
29
|
+
tracked_items.value[i] = 123;
|
|
30
30
|
items2[0] = 123;
|
|
31
31
|
items2[i] = 123;
|
|
32
32
|
items3[0] = 123;
|
|
@@ -34,8 +34,8 @@ describe('compiler > assignments', () => {
|
|
|
34
34
|
|
|
35
35
|
logs.push(items[0]);
|
|
36
36
|
logs.push(items[i]);
|
|
37
|
-
logs.push(
|
|
38
|
-
logs.push(
|
|
37
|
+
logs.push(tracked_items.value[0]);
|
|
38
|
+
logs.push(tracked_items.value[i]);
|
|
39
39
|
logs.push(items2[0]);
|
|
40
40
|
logs.push(items2[i]);
|
|
41
41
|
logs.push(items3[0]);
|
|
@@ -43,8 +43,8 @@ describe('compiler > assignments', () => {
|
|
|
43
43
|
|
|
44
44
|
items[0]++;
|
|
45
45
|
items[i]++;
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
tracked_items.value[0]++;
|
|
47
|
+
tracked_items.value[i]++;
|
|
48
48
|
items2[0]++;
|
|
49
49
|
items2[i]++;
|
|
50
50
|
items3[0]++;
|
|
@@ -52,8 +52,8 @@ describe('compiler > assignments', () => {
|
|
|
52
52
|
|
|
53
53
|
logs.push(items[0]);
|
|
54
54
|
logs.push(items[i]);
|
|
55
|
-
logs.push(
|
|
56
|
-
logs.push(
|
|
55
|
+
logs.push(tracked_items.value[0]);
|
|
56
|
+
logs.push(tracked_items.value[i]);
|
|
57
57
|
logs.push(items2[0]);
|
|
58
58
|
logs.push(items2[i]);
|
|
59
59
|
logs.push(items3[0]);
|
|
@@ -61,8 +61,8 @@ describe('compiler > assignments', () => {
|
|
|
61
61
|
|
|
62
62
|
logs.push(--items[0]);
|
|
63
63
|
logs.push(--items[i]);
|
|
64
|
-
logs.push(
|
|
65
|
-
logs.push(
|
|
64
|
+
logs.push(--tracked_items.value[0]);
|
|
65
|
+
logs.push(--tracked_items.value[i]);
|
|
66
66
|
logs.push(--items2[0]);
|
|
67
67
|
logs.push(--items2[i]);
|
|
68
68
|
logs.push(--items3[0]);
|
|
@@ -110,10 +110,10 @@ describe('compiler > assignments', () => {
|
|
|
110
110
|
it('compiles tracked values in effect with assignment expression', () => {
|
|
111
111
|
const source = `import { track, effect } from 'ripple';
|
|
112
112
|
component App() {
|
|
113
|
-
let count = track(0);
|
|
113
|
+
let &[count] = track(0);
|
|
114
114
|
|
|
115
115
|
effect(() => {
|
|
116
|
-
state.count =
|
|
116
|
+
state.count = count;
|
|
117
117
|
});
|
|
118
118
|
}`;
|
|
119
119
|
const result = compile(source, 'test.ripple');
|
|
@@ -124,14 +124,14 @@ component App() {
|
|
|
124
124
|
it('compiles tracked values in effect with update expressions', () => {
|
|
125
125
|
const source = `import { track, effect, untrack } from 'ripple';
|
|
126
126
|
component App() {
|
|
127
|
-
let count = track(5);
|
|
127
|
+
let &[count] = track(5);
|
|
128
128
|
|
|
129
129
|
effect(() => {
|
|
130
130
|
untrack(() => {
|
|
131
|
-
state.preIncrement =
|
|
132
|
-
state.postIncrement =
|
|
133
|
-
state.preDecrement =
|
|
134
|
-
state.postDecrement =
|
|
131
|
+
state.preIncrement = ++count;
|
|
132
|
+
state.postIncrement = count++;
|
|
133
|
+
state.preDecrement = --count;
|
|
134
|
+
state.postDecrement = count--;
|
|
135
135
|
});
|
|
136
136
|
});
|
|
137
137
|
}`;
|
|
@@ -324,20 +324,49 @@ describe('compiler > basics', () => {
|
|
|
324
324
|
const source = `
|
|
325
325
|
import { RippleArray, RippleMap, RippleObject, RippleSet, createRefKey, effect, track, untrack } from 'ripple';
|
|
326
326
|
component App() {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
327
|
+
let value = track('test');
|
|
328
|
+
function inputRef(node) {}
|
|
329
|
+
|
|
330
|
+
const props = {
|
|
331
|
+
id: 'example',
|
|
332
|
+
value: value.value,
|
|
333
|
+
[createRefKey()]: inputRef,
|
|
334
|
+
};
|
|
335
335
|
}
|
|
336
336
|
`;
|
|
337
337
|
|
|
338
338
|
const result = compile_to_volar_mappings(source, 'test.ripple').code;
|
|
339
339
|
|
|
340
|
-
expect(result).toMatch(/value:\s*value
|
|
340
|
+
expect(result).toMatch(/value:\s*value\.value/);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('keeps lazy destructuring as plain destructuring in to_ts output', () => {
|
|
344
|
+
const track_split_source = `
|
|
345
|
+
import { trackSplit } from 'ripple';
|
|
346
|
+
component App() {
|
|
347
|
+
const source = { a: 1, b: 2, c: 3 };
|
|
348
|
+
let &[a, b, rest] = trackSplit(source, ['a', 'b']);
|
|
349
|
+
const sum = a + b + rest.c;
|
|
350
|
+
}
|
|
351
|
+
`;
|
|
352
|
+
const track_split_result = compile_to_volar_mappings(track_split_source, 'test.ripple').code;
|
|
353
|
+
expect(track_split_result).toContain('let [a, b, rest] = trackSplit(source, [\'a\', \'b\']);');
|
|
354
|
+
expect(track_split_result).not.toContain('let lazy = trackSplit');
|
|
355
|
+
|
|
356
|
+
const track_source = `
|
|
357
|
+
import { track } from 'ripple';
|
|
358
|
+
component App() {
|
|
359
|
+
let &[value, ...rest] = track(0);
|
|
360
|
+
const x = value;
|
|
361
|
+
}
|
|
362
|
+
`;
|
|
363
|
+
const track_result = compile_to_volar_mappings(track_source, 'test.ripple').code;
|
|
364
|
+
expect(track_result).toContain('let [value, ...rest] = track(0);');
|
|
365
|
+
expect(track_result).toContain('const x = value;');
|
|
366
|
+
expect(track_result).not.toContain('let lazy = track(0)');
|
|
367
|
+
expect(track_result).not.toContain('.slice(');
|
|
368
|
+
expect(track_result).not.toContain('_$_.get(');
|
|
369
|
+
expect(track_result).not.toContain('lazy0');
|
|
341
370
|
});
|
|
342
371
|
|
|
343
372
|
it('preserves generic type args in interface extends for Volar mappings', () => {
|
|
@@ -364,13 +393,13 @@ export component App(props: Props) {
|
|
|
364
393
|
const source = `
|
|
365
394
|
import { track } from 'ripple';
|
|
366
395
|
export component App() {
|
|
367
|
-
let level = track(1);
|
|
396
|
+
let &[level] = track(1);
|
|
368
397
|
|
|
369
398
|
<button
|
|
370
399
|
onClick={() => {
|
|
371
|
-
if (
|
|
372
|
-
else if (
|
|
373
|
-
else
|
|
400
|
+
if (level === 1) level = 2;
|
|
401
|
+
else if (level === 2) level = 3;
|
|
402
|
+
else level = 1;
|
|
374
403
|
}}
|
|
375
404
|
>
|
|
376
405
|
{'Toggle'}
|
|
@@ -467,10 +496,10 @@ export component App() {
|
|
|
467
496
|
import { track, effect, untrack } from 'ripple';
|
|
468
497
|
|
|
469
498
|
component App() {
|
|
470
|
-
let count = track(0);
|
|
499
|
+
let &[count] = track(0);
|
|
471
500
|
|
|
472
501
|
effect(() => {
|
|
473
|
-
const snapshot = untrack(() =>
|
|
502
|
+
const snapshot = untrack(() => count);
|
|
474
503
|
console.log(snapshot);
|
|
475
504
|
});
|
|
476
505
|
}
|
|
@@ -70,8 +70,8 @@ import { track } from 'ripple';
|
|
|
70
70
|
const code = `
|
|
71
71
|
import { track } from 'ripple';
|
|
72
72
|
export default component App() {
|
|
73
|
-
let count = track(0);
|
|
74
|
-
console.log(
|
|
73
|
+
let &[count] = track(0);
|
|
74
|
+
console.log(count);
|
|
75
75
|
}
|
|
76
76
|
`;
|
|
77
77
|
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
@@ -121,4 +121,70 @@ import { get, track } from 'ripple';
|
|
|
121
121
|
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
122
122
|
},
|
|
123
123
|
);
|
|
124
|
+
|
|
125
|
+
it('should allow indexed [0] access on a tracked object', () => {
|
|
126
|
+
const code = `
|
|
127
|
+
import { track } from 'ripple';
|
|
128
|
+
export default component App() {
|
|
129
|
+
let count = track(0);
|
|
130
|
+
console.log(count[0]);
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should allow indexed [1] access on a tracked object', () => {
|
|
137
|
+
const code = `
|
|
138
|
+
import { track } from 'ripple';
|
|
139
|
+
export default component App() {
|
|
140
|
+
let count = track(0);
|
|
141
|
+
let raw = count[1];
|
|
142
|
+
}
|
|
143
|
+
`;
|
|
144
|
+
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should allow [0] write on a tracked object', () => {
|
|
148
|
+
const code = `
|
|
149
|
+
import { track } from 'ripple';
|
|
150
|
+
export default component App() {
|
|
151
|
+
let count = track(0);
|
|
152
|
+
count[0] = 5;
|
|
153
|
+
}
|
|
154
|
+
`;
|
|
155
|
+
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should allow .value read access on a tracked object', () => {
|
|
159
|
+
const code = `
|
|
160
|
+
import { track } from 'ripple';
|
|
161
|
+
export default component App() {
|
|
162
|
+
let count = track(0);
|
|
163
|
+
console.log(count.value);
|
|
164
|
+
}
|
|
165
|
+
`;
|
|
166
|
+
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should allow .value assignment on a tracked object', () => {
|
|
170
|
+
const code = `
|
|
171
|
+
import { track } from 'ripple';
|
|
172
|
+
export default component App() {
|
|
173
|
+
let count = track(0);
|
|
174
|
+
count.value = 5;
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
177
|
+
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should allow .length read access on a tracked object', () => {
|
|
181
|
+
const code = `
|
|
182
|
+
import { track } from 'ripple';
|
|
183
|
+
export default component App() {
|
|
184
|
+
let count = track(0);
|
|
185
|
+
console.log(count.length);
|
|
186
|
+
}
|
|
187
|
+
`;
|
|
188
|
+
expect(() => compile(code, 'test.ripple')).not.toThrow();
|
|
189
|
+
});
|
|
124
190
|
});
|
|
@@ -18,7 +18,7 @@ describe('composite > dynamic components', () => {
|
|
|
18
18
|
expect(container.textContent).toBe('Basic Component');
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
it('supports rendering composite components
|
|
21
|
+
it('supports rendering composite components from object properties', () => {
|
|
22
22
|
component App() {
|
|
23
23
|
component basic() {
|
|
24
24
|
<div>{'Basic Component'}</div>
|
|
@@ -30,7 +30,8 @@ describe('composite > dynamic components', () => {
|
|
|
30
30
|
tracked_basic,
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
const comp = obj.tracked_basic;
|
|
34
|
+
<@comp />
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
render(App);
|
|
@@ -39,7 +40,7 @@ describe('composite > dynamic components', () => {
|
|
|
39
40
|
expect(container.textContent).toBe('Basic Component');
|
|
40
41
|
});
|
|
41
42
|
|
|
42
|
-
it('supports rendering composite components
|
|
43
|
+
it('supports rendering composite components from tracked object properties', () => {
|
|
43
44
|
component App() {
|
|
44
45
|
component basic() {
|
|
45
46
|
<div>{'Basic Component'}</div>
|
|
@@ -51,9 +52,10 @@ describe('composite > dynamic components', () => {
|
|
|
51
52
|
tracked_basic,
|
|
52
53
|
};
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
let &[inner] = track(obj);
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
const comp = inner.tracked_basic;
|
|
58
|
+
<@comp />
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
render(App);
|
|
@@ -72,15 +74,13 @@ describe('composite > dynamic components', () => {
|
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
component App() {
|
|
75
|
-
let thing = track(() => Child1);
|
|
77
|
+
let &[thing] = track(() => Child1);
|
|
76
78
|
|
|
77
79
|
<div id="container">
|
|
78
80
|
<@thing />
|
|
79
81
|
</div>
|
|
80
82
|
|
|
81
|
-
<button onClick={() => (
|
|
82
|
-
{'Change Child'}
|
|
83
|
-
</button>
|
|
83
|
+
<button onClick={() => (thing = thing === Child1 ? Child2 : Child1)}>{'Change Child'}</button>
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
render(App);
|
|
@@ -8,10 +8,10 @@ describe('composite > props', () => {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
component App() {
|
|
11
|
-
let foo = track(123);
|
|
11
|
+
let &[foo] = track(123);
|
|
12
12
|
|
|
13
13
|
<Child />
|
|
14
|
-
<Child {
|
|
14
|
+
<Child {foo} />
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
render(App);
|
|
@@ -40,7 +40,7 @@ describe('composite > props', () => {
|
|
|
40
40
|
|
|
41
41
|
it('correctly handles no props', () => {
|
|
42
42
|
component Child(props: { foo?: Tracked<number> }) {
|
|
43
|
-
<div>{props
|
|
43
|
+
<div>{props.foo?.value}</div>
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
component App() {
|
|
@@ -62,10 +62,10 @@ describe('composite > props', () => {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
component App() {
|
|
65
|
-
let foo = track(123);
|
|
65
|
+
let &[foo] = track(123);
|
|
66
66
|
|
|
67
67
|
<Child />
|
|
68
|
-
<Child {
|
|
68
|
+
<Child {foo} />
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
render(App);
|
|
@@ -79,10 +79,10 @@ describe('composite > props', () => {
|
|
|
79
79
|
|
|
80
80
|
component Counter({ count }: { count: Tracked<number> }) {
|
|
81
81
|
effect(() => {
|
|
82
|
-
logs.push(
|
|
82
|
+
logs.push(count.value);
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
<button onClick={() => (
|
|
85
|
+
<button onClick={() => (count.value = count.value + 1)}>{'+'}</button>
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
component App() {
|
|
@@ -108,7 +108,7 @@ describe('composite > props', () => {
|
|
|
108
108
|
it('correctly retains prop accessors and reactivity when using rest props', () => {
|
|
109
109
|
component Button(props: Props) {
|
|
110
110
|
const [children, rest] = trackSplit(props, ['children']);
|
|
111
|
-
<button {
|
|
111
|
+
<button {...rest.value}>
|
|
112
112
|
<@children />
|
|
113
113
|
</button>
|
|
114
114
|
<style>
|
|
@@ -123,9 +123,9 @@ describe('composite > props', () => {
|
|
|
123
123
|
|
|
124
124
|
component Toggle(props: { pressed: Tracked<boolean> }) {
|
|
125
125
|
const [pressed, rest] = trackSplit(props, ['pressed']);
|
|
126
|
-
const onClick = () => (
|
|
127
|
-
<Button {
|
|
128
|
-
<Button class={
|
|
126
|
+
const onClick = () => (pressed.value = !pressed.value);
|
|
127
|
+
<Button {...rest.value} class={pressed.value ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
|
|
128
|
+
<Button class={pressed.value ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
component App() {
|