ripple 0.3.71 → 0.3.74
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 +75 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -8
- package/src/runtime/index-client.js +3 -13
- package/src/runtime/internal/client/blocks.js +3 -25
- package/src/runtime/internal/client/for.js +80 -5
- package/src/runtime/internal/client/index.js +0 -2
- package/src/runtime/internal/client/types.d.ts +0 -10
- package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
- package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
- package/tests/client/array/array.copy-within.test.tsrx +19 -19
- package/tests/client/array/array.derived.test.tsrx +97 -109
- package/tests/client/array/array.iteration.test.tsrx +28 -28
- package/tests/client/array/array.mutations.test.tsrx +68 -68
- package/tests/client/array/array.static.test.tsrx +82 -92
- package/tests/client/array/array.to-methods.test.tsrx +15 -15
- package/tests/client/async-suspend.test.tsrx +180 -179
- package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
- package/tests/client/basic/basic.attributes.test.tsrx +273 -317
- package/tests/client/basic/basic.collections.test.tsrx +59 -71
- package/tests/client/basic/basic.components.test.tsrx +196 -222
- package/tests/client/basic/basic.errors.test.tsrx +72 -78
- package/tests/client/basic/basic.events.test.tsrx +80 -85
- package/tests/client/basic/basic.get-set.test.tsrx +54 -64
- package/tests/client/basic/basic.hmr.test.tsrx +15 -19
- package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
- package/tests/client/basic/basic.rendering.test.tsrx +273 -178
- package/tests/client/basic/basic.utilities.test.tsrx +8 -10
- package/tests/client/boundaries.test.tsrx +18 -18
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
- package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
- package/tests/client/compiler/compiler.basic.test.tsrx +364 -296
- package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +41 -44
- package/tests/client/composite/composite.generics.test.tsrx +165 -167
- package/tests/client/composite/composite.props.test.tsrx +66 -74
- package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
- package/tests/client/composite/composite.render.test.tsrx +92 -101
- package/tests/client/computed-properties.test.tsrx +14 -18
- package/tests/client/context.test.tsrx +14 -18
- package/tests/client/css/global-additional-cases.test.tsrx +491 -437
- package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
- package/tests/client/css/global-at-rules.test.tsrx +71 -66
- package/tests/client/css/global-basic.test.tsrx +105 -98
- package/tests/client/css/global-classes-ids.test.tsrx +128 -114
- package/tests/client/css/global-combinators.test.tsrx +83 -78
- package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
- package/tests/client/css/global-edge-cases.test.tsrx +138 -120
- package/tests/client/css/global-keyframes.test.tsrx +108 -96
- package/tests/client/css/global-nested.test.tsrx +88 -78
- package/tests/client/css/global-pseudo.test.tsrx +104 -98
- package/tests/client/css/global-scoping.test.tsrx +145 -125
- package/tests/client/css/style-identifier.test.tsrx +62 -69
- package/tests/client/date.test.tsrx +83 -83
- package/tests/client/dynamic-elements.test.tsrx +227 -283
- package/tests/client/events.test.tsrx +252 -266
- package/tests/client/for.test.tsrx +120 -127
- package/tests/client/head.test.tsrx +40 -48
- package/tests/client/html.test.tsrx +37 -49
- package/tests/client/input-value.test.tsrx +1125 -1354
- package/tests/client/lazy-array.test.tsrx +10 -16
- package/tests/client/lazy-destructuring.test.tsrx +169 -221
- package/tests/client/map.test.tsrx +39 -41
- package/tests/client/media-query.test.tsrx +15 -19
- package/tests/client/object.test.tsrx +46 -56
- package/tests/client/portal.test.tsrx +31 -37
- package/tests/client/ref.test.tsrx +173 -193
- package/tests/client/return.test.tsrx +62 -37
- package/tests/client/set.test.tsrx +33 -33
- package/tests/client/svg.test.tsrx +195 -215
- package/tests/client/switch.test.tsrx +201 -191
- package/tests/client/track-async-hydration.test.tsrx +14 -18
- package/tests/client/tracked-index-access.test.tsrx +18 -28
- package/tests/client/try.test.tsrx +494 -619
- package/tests/client/tsx.test.tsrx +290 -371
- package/tests/client/typescript-generics.test.tsrx +121 -129
- package/tests/client/url/url.derived.test.tsrx +21 -25
- package/tests/client/url/url.parsing.test.tsrx +35 -35
- package/tests/client/url/url.partial-removal.test.tsrx +32 -32
- package/tests/client/url/url.reactivity.test.tsrx +68 -72
- package/tests/client/url/url.serialization.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
- package/tests/hydration/compiled/client/basic.js +396 -325
- package/tests/hydration/compiled/client/composite.js +52 -44
- package/tests/hydration/compiled/client/for.js +734 -604
- package/tests/hydration/compiled/client/head.js +183 -103
- package/tests/hydration/compiled/client/html.js +93 -86
- package/tests/hydration/compiled/client/if-children.js +95 -71
- package/tests/hydration/compiled/client/if.js +113 -89
- package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
- package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
- package/tests/hydration/compiled/client/reactivity.js +26 -24
- package/tests/hydration/compiled/client/return.js +8 -42
- package/tests/hydration/compiled/client/switch.js +208 -173
- package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
- package/tests/hydration/compiled/client/try.js +29 -21
- package/tests/hydration/compiled/server/basic.js +210 -221
- package/tests/hydration/compiled/server/composite.js +13 -14
- package/tests/hydration/compiled/server/for.js +427 -444
- package/tests/hydration/compiled/server/head.js +199 -189
- package/tests/hydration/compiled/server/html.js +33 -41
- package/tests/hydration/compiled/server/if-children.js +114 -117
- package/tests/hydration/compiled/server/if.js +77 -83
- package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
- package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
- package/tests/hydration/compiled/server/reactivity.js +24 -22
- package/tests/hydration/compiled/server/return.js +6 -18
- package/tests/hydration/compiled/server/switch.js +179 -176
- package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
- package/tests/hydration/compiled/server/try.js +31 -35
- package/tests/hydration/components/basic.tsrx +216 -286
- package/tests/hydration/components/composite.tsrx +32 -42
- package/tests/hydration/components/events.tsrx +81 -101
- package/tests/hydration/components/for.tsrx +270 -336
- package/tests/hydration/components/head.tsrx +43 -39
- package/tests/hydration/components/hmr.tsrx +16 -22
- package/tests/hydration/components/html-in-template.tsrx +15 -21
- package/tests/hydration/components/html.tsrx +442 -526
- package/tests/hydration/components/if-children.tsrx +107 -125
- package/tests/hydration/components/if.tsrx +68 -90
- package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
- package/tests/hydration/components/nested-control-flow.tsrx +202 -216
- package/tests/hydration/components/portal.tsrx +33 -41
- package/tests/hydration/components/reactivity.tsrx +26 -34
- package/tests/hydration/components/return.tsrx +4 -6
- package/tests/hydration/components/switch.tsrx +73 -78
- package/tests/hydration/components/track-async-serialization.tsrx +83 -93
- package/tests/hydration/components/try.tsrx +37 -51
- package/tests/hydration/switch.test.js +8 -8
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +120 -167
- package/tests/server/basic.components.test.tsrx +163 -197
- package/tests/server/basic.test.tsrx +298 -220
- package/tests/server/compiler.test.tsrx +142 -72
- package/tests/server/composite.props.test.tsrx +54 -58
- package/tests/server/composite.test.tsrx +165 -167
- package/tests/server/context.test.tsrx +13 -17
- package/tests/server/dynamic-elements.test.tsrx +103 -135
- package/tests/server/for.test.tsrx +115 -84
- package/tests/server/head.test.tsrx +31 -31
- package/tests/server/html-nesting-validation.test.tsrx +16 -8
- package/tests/server/if.test.tsrx +49 -59
- package/tests/server/lazy-destructuring.test.tsrx +288 -366
- package/tests/server/return.test.tsrx +58 -36
- package/tests/server/streaming-ssr.test.tsrx +4 -4
- package/tests/server/style-identifier.test.tsrx +58 -66
- package/tests/server/switch.test.tsrx +89 -97
- package/tests/server/track-async-serialization.test.tsrx +85 -103
- package/tests/server/try.test.tsrx +275 -360
- package/tests/utils/ref-types.test.js +72 -0
- package/tests/utils/vite-plugin-config.test.js +41 -74
- package/types/index.d.ts +1 -0
- package/src/runtime/internal/client/compat.js +0 -40
- package/tests/utils/compiler-compat-config.test.js +0 -38
|
@@ -3,8 +3,8 @@ import type { Tracked, PropsNoChildren } from 'ripple';
|
|
|
3
3
|
|
|
4
4
|
describe('basic client', () => {
|
|
5
5
|
it('render static text', async () => {
|
|
6
|
-
function Basic() {
|
|
7
|
-
|
|
6
|
+
function Basic() @{
|
|
7
|
+
<div>{'Hello World'}</div>
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const { head, body } = await render(Basic);
|
|
@@ -14,11 +14,9 @@ describe('basic client', () => {
|
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
it('renders string interpolation as escaped text', async () => {
|
|
17
|
-
function Basic() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<div>{markup}</div>
|
|
21
|
-
</>;
|
|
17
|
+
function Basic() @{
|
|
18
|
+
let markup = '<span>Not HTML</span>';
|
|
19
|
+
<div>{markup}</div>
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
const { body } = await render(Basic);
|
|
@@ -26,32 +24,35 @@ describe('basic client', () => {
|
|
|
26
24
|
expect(body).toBeHtml('<div><span>Not HTML</span></div>');
|
|
27
25
|
});
|
|
28
26
|
|
|
29
|
-
it('renders direct
|
|
30
|
-
function Basic() {
|
|
31
|
-
|
|
32
|
-
<div>
|
|
33
|
-
<div>
|
|
34
|
-
<pre>
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
it('renders direct JSX text children as text', async () => {
|
|
28
|
+
function Basic() @{
|
|
29
|
+
<>
|
|
30
|
+
<div>Rock & "Roll"</div>
|
|
31
|
+
<div>line break</div>
|
|
32
|
+
<pre>
|
|
33
|
+
first
|
|
34
|
+
second
|
|
35
|
+
</pre>
|
|
36
|
+
</>
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const { body } = await render(Basic);
|
|
40
40
|
|
|
41
41
|
expect(body).toBeHtml(
|
|
42
|
-
'<div>Rock & "Roll"</div><div>line
|
|
42
|
+
'<div>Rock & "Roll"</div><div>line break</div><pre>first\nsecond</pre>',
|
|
43
43
|
);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
it('does not render
|
|
47
|
-
function Basic() {
|
|
46
|
+
it('does not render JavaScript statements outside returned component templates', async () => {
|
|
47
|
+
function Basic() @{
|
|
48
48
|
const ready = true;
|
|
49
49
|
|
|
50
50
|
if (ready) {
|
|
51
|
-
|
|
51
|
+
const leaked = 'should not render';
|
|
52
|
+
void leaked;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
<>Hello world</>
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
const { body } = await render(Basic);
|
|
@@ -60,14 +61,12 @@ second"</pre>
|
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
it('renders primitive component return branches', async () => {
|
|
63
|
-
function Basic() {
|
|
64
|
+
function Basic() @{
|
|
64
65
|
const ready = false;
|
|
65
|
-
|
|
66
66
|
if (!ready) {
|
|
67
67
|
return 'Waiting';
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
return <>"Ready"</>;
|
|
69
|
+
<>Ready</>
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
const { body } = await render(Basic);
|
|
@@ -105,10 +104,115 @@ second"</pre>
|
|
|
105
104
|
expect(body).toBeHtml('');
|
|
106
105
|
});
|
|
107
106
|
|
|
108
|
-
it('does not
|
|
107
|
+
it('does not stringify adjacent call-containing expression children', async () => {
|
|
108
|
+
function child(label: string) @{
|
|
109
|
+
<span>{label}</span>
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function empty() {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const Constructed = function Constructed(label: string) {
|
|
117
|
+
return child(label);
|
|
118
|
+
} as unknown as {
|
|
119
|
+
new (label: string): ReturnType<typeof child>;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const factory = child;
|
|
123
|
+
|
|
124
|
+
function tag(_strings: TemplateStringsArray) {
|
|
125
|
+
return child('tagged');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const lookup = {
|
|
129
|
+
member: child('member'),
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
function getKey(): keyof typeof lookup {
|
|
133
|
+
return 'member';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function touch() {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let assigned;
|
|
141
|
+
|
|
142
|
+
function Basic() @{
|
|
143
|
+
<>
|
|
144
|
+
<div>
|
|
145
|
+
{'call:'}
|
|
146
|
+
{child('call')}
|
|
147
|
+
</div>
|
|
148
|
+
<div>
|
|
149
|
+
{'new:'}
|
|
150
|
+
{new Constructed('new')}
|
|
151
|
+
</div>
|
|
152
|
+
<div>
|
|
153
|
+
{'chain:'}
|
|
154
|
+
{factory?.('chain')}
|
|
155
|
+
</div>
|
|
156
|
+
<div>
|
|
157
|
+
{'ts-wrapper:'}
|
|
158
|
+
{child('ts-wrapper')!}
|
|
159
|
+
</div>
|
|
160
|
+
<div>
|
|
161
|
+
{'array:'}
|
|
162
|
+
{[child('array')]}
|
|
163
|
+
</div>
|
|
164
|
+
<div>
|
|
165
|
+
{'assignment:'}
|
|
166
|
+
{assigned = child('assignment')}
|
|
167
|
+
</div>
|
|
168
|
+
<div>
|
|
169
|
+
{'logical:'}
|
|
170
|
+
{true && child('logical')}
|
|
171
|
+
</div>
|
|
172
|
+
<div>
|
|
173
|
+
{'conditional:'}
|
|
174
|
+
{true ? child('conditional') : ''}
|
|
175
|
+
</div>
|
|
176
|
+
<div>
|
|
177
|
+
{'member:'}
|
|
178
|
+
{lookup[getKey()]}
|
|
179
|
+
</div>
|
|
180
|
+
<div>
|
|
181
|
+
{'object:'}
|
|
182
|
+
{{
|
|
183
|
+
[Symbol.for('ripple.element')]: true,
|
|
184
|
+
render() {
|
|
185
|
+
return child('object');
|
|
186
|
+
},
|
|
187
|
+
}}
|
|
188
|
+
</div>
|
|
189
|
+
<div>
|
|
190
|
+
{'sequence:'}
|
|
191
|
+
{(touch(), child('sequence'))}
|
|
192
|
+
</div>
|
|
193
|
+
<div>
|
|
194
|
+
{'tagged:'}
|
|
195
|
+
{tag`tagged`}
|
|
196
|
+
</div>
|
|
197
|
+
<div>
|
|
198
|
+
{'unary:'}
|
|
199
|
+
{void empty()}
|
|
200
|
+
</div>
|
|
201
|
+
</>
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const { body } = await render(Basic);
|
|
205
|
+
|
|
206
|
+
expect(body).toBeHtml(
|
|
207
|
+
'<div>call:<span>call</span></div><div>new:<span>new</span></div><div>chain:<span>chain</span></div><div>ts-wrapper:<span>ts-wrapper</span></div><div>array:<span>array</span></div><div>assignment:<span>assignment</span></div><div>logical:<span>logical</span></div><div>conditional:<span>conditional</span></div><div>member:<span>member</span></div><div>object:<span>object</span></div><div>sequence:<span>sequence</span></div><div>tagged:<span>tagged</span></div><div>unary:</div>',
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('does not render unreachable statements after an ASI return', async () => {
|
|
109
212
|
function Basic() {
|
|
110
213
|
return;
|
|
111
|
-
|
|
214
|
+
const leaked = 'should not render';
|
|
215
|
+
void leaked;
|
|
112
216
|
}
|
|
113
217
|
|
|
114
218
|
const { body } = await render(Basic);
|
|
@@ -117,14 +221,10 @@ second"</pre>
|
|
|
117
221
|
});
|
|
118
222
|
|
|
119
223
|
it('renders inline tsrx fragments', async () => {
|
|
120
|
-
function Basic() {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
<span>{label}</span>
|
|
125
|
-
</>;
|
|
126
|
-
<div>{content}</div>
|
|
127
|
-
</>;
|
|
224
|
+
function Basic() @{
|
|
225
|
+
const label = 'Server';
|
|
226
|
+
const content = <span>{label}</span>;
|
|
227
|
+
<div>{content}</div>
|
|
128
228
|
}
|
|
129
229
|
|
|
130
230
|
const { body } = await render(Basic);
|
|
@@ -133,11 +233,9 @@ second"</pre>
|
|
|
133
233
|
});
|
|
134
234
|
|
|
135
235
|
it('renders Fragment innerHTML', async () => {
|
|
136
|
-
function Basic() {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
<Fragment innerHTML={html} />
|
|
140
|
-
</>;
|
|
236
|
+
function Basic() @{
|
|
237
|
+
const html = '<strong>Server Fragment HTML</strong>';
|
|
238
|
+
<Fragment innerHTML={html} />
|
|
141
239
|
}
|
|
142
240
|
|
|
143
241
|
const { body } = await render(Basic);
|
|
@@ -148,28 +246,20 @@ second"</pre>
|
|
|
148
246
|
|
|
149
247
|
it('renders deeply nested tsx and tsrx expression values', async () => {
|
|
150
248
|
function makeFragment(label: string) {
|
|
249
|
+
const test = <>
|
|
250
|
+
{[1, 2, 3, 4].map((item) => <div class="helper-item">{item}</div>)}
|
|
251
|
+
</>;
|
|
151
252
|
return <>
|
|
152
253
|
<span class="label">{label}</span>
|
|
153
|
-
const test = <tsx>
|
|
154
|
-
{[1, 2, 3, 4].map(
|
|
155
|
-
(item) => <tsx>
|
|
156
|
-
{<>
|
|
157
|
-
<div class="helper-item">{item}</div>
|
|
158
|
-
</>}
|
|
159
|
-
</tsx>,
|
|
160
|
-
)}
|
|
161
|
-
</tsx>;
|
|
162
254
|
{test}
|
|
163
255
|
</>;
|
|
164
256
|
}
|
|
165
257
|
|
|
166
|
-
function Basic() {
|
|
167
|
-
|
|
168
|
-
{<
|
|
169
|
-
{[1, 2, 3].map((item) => <div class="app-item">{item}</div>)}
|
|
170
|
-
</tsx>}
|
|
258
|
+
function Basic() @{
|
|
259
|
+
<>
|
|
260
|
+
{[1, 2, 3].map((item) => <div class="app-item">{item}</div>)}
|
|
171
261
|
{makeFragment('from helper')}
|
|
172
|
-
|
|
262
|
+
</>
|
|
173
263
|
}
|
|
174
264
|
|
|
175
265
|
const { body } = await render(Basic);
|
|
@@ -180,19 +270,15 @@ second"</pre>
|
|
|
180
270
|
});
|
|
181
271
|
|
|
182
272
|
it('renders tsrx nested directly inside a top-level tsx expression value', async () => {
|
|
183
|
-
function Basic() {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
<
|
|
187
|
-
|
|
188
|
-
<div class="inner">
|
|
189
|
-
{'from tsrx'}
|
|
190
|
-
</div>
|
|
191
|
-
</>}
|
|
192
|
-
</section>
|
|
193
|
-
</tsx>;
|
|
194
|
-
{content}
|
|
273
|
+
function Basic() @{
|
|
274
|
+
const content = <>
|
|
275
|
+
<section class="outer">
|
|
276
|
+
<div class="inner">{'from tsrx'}</div>
|
|
277
|
+
</section>
|
|
195
278
|
</>;
|
|
279
|
+
<>
|
|
280
|
+
{content}
|
|
281
|
+
</>
|
|
196
282
|
}
|
|
197
283
|
|
|
198
284
|
const { body } = await render(Basic);
|
|
@@ -201,21 +287,17 @@ second"</pre>
|
|
|
201
287
|
});
|
|
202
288
|
|
|
203
289
|
it('renders nested elements from tsrx inside a top-level tsx value', async () => {
|
|
204
|
-
function Basic() {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
<
|
|
208
|
-
{
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
{'inside nested tsrx'}
|
|
212
|
-
</span>
|
|
213
|
-
</section>
|
|
214
|
-
</>}
|
|
215
|
-
</div>
|
|
216
|
-
</tsx>;
|
|
217
|
-
{content}
|
|
290
|
+
function Basic() @{
|
|
291
|
+
const content = <>
|
|
292
|
+
<div class="wrapper">
|
|
293
|
+
<section class="native">
|
|
294
|
+
<span class="nested-tsrx">{'inside nested tsrx'}</span>
|
|
295
|
+
</section>
|
|
296
|
+
</div>
|
|
218
297
|
</>;
|
|
298
|
+
<>
|
|
299
|
+
{content}
|
|
300
|
+
</>
|
|
219
301
|
}
|
|
220
302
|
|
|
221
303
|
const { body } = await render(Basic);
|
|
@@ -226,18 +308,12 @@ second"</pre>
|
|
|
226
308
|
});
|
|
227
309
|
|
|
228
310
|
it('renders tsx declared before a top-level tsx value', async () => {
|
|
229
|
-
function Basic() {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
{'inside nested tsx'}
|
|
234
|
-
</span>
|
|
235
|
-
</tsx>;
|
|
236
|
-
const content = <tsx>
|
|
237
|
-
<div class="native">{nested}</div>
|
|
238
|
-
</tsx>;
|
|
311
|
+
function Basic() @{
|
|
312
|
+
const nested = <span class="nested-tsx">inside nested tsx</span>;
|
|
313
|
+
const content = <><div class="native">{nested}</div></>;
|
|
314
|
+
<>
|
|
239
315
|
{content}
|
|
240
|
-
|
|
316
|
+
</>
|
|
241
317
|
}
|
|
242
318
|
|
|
243
319
|
const { body } = await render(Basic);
|
|
@@ -248,21 +324,17 @@ second"</pre>
|
|
|
248
324
|
});
|
|
249
325
|
|
|
250
326
|
it('flattens nested primitive arrays inside mixed tsrx collections', async () => {
|
|
251
|
-
function Basic() {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
{
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
]}
|
|
263
|
-
</tsx>}
|
|
264
|
-
</div>
|
|
265
|
-
</>;
|
|
327
|
+
function Basic() @{
|
|
328
|
+
<div>
|
|
329
|
+
{<>
|
|
330
|
+
{[
|
|
331
|
+
'start:',
|
|
332
|
+
['one', 2, true, null, false],
|
|
333
|
+
<strong>{'!'}</strong>,
|
|
334
|
+
':end',
|
|
335
|
+
]}
|
|
336
|
+
</>}
|
|
337
|
+
</div>
|
|
266
338
|
}
|
|
267
339
|
|
|
268
340
|
const { body } = await render(Basic);
|
|
@@ -271,12 +343,14 @@ second"</pre>
|
|
|
271
343
|
});
|
|
272
344
|
|
|
273
345
|
it('flattens direct primitive array expressions', async () => {
|
|
274
|
-
function Basic() {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
<div>
|
|
346
|
+
function Basic() @{
|
|
347
|
+
const items = ['start:', ['one', 2], null, true, false, ':end'];
|
|
348
|
+
<>
|
|
349
|
+
<div>
|
|
350
|
+
{['start:', ['one', 2], null, true, false, ':end']}
|
|
351
|
+
</div>
|
|
278
352
|
<div>{items}</div>
|
|
279
|
-
|
|
353
|
+
</>
|
|
280
354
|
}
|
|
281
355
|
|
|
282
356
|
const { body } = await render(Basic);
|
|
@@ -285,16 +359,16 @@ second"</pre>
|
|
|
285
359
|
});
|
|
286
360
|
|
|
287
361
|
it('flattens conditional primitive array expressions', async () => {
|
|
288
|
-
function Basic() {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
362
|
+
function Basic() @{
|
|
363
|
+
const condition = true;
|
|
364
|
+
const ternary_items = condition
|
|
365
|
+
? ['start:', ['one', 2], null, true, false, ':end']
|
|
366
|
+
: ['fallback'];
|
|
367
|
+
const logical_items = condition && ['start:', ['one', 2], null, true, false, ':end'];
|
|
368
|
+
<>
|
|
295
369
|
<div>{ternary_items}</div>
|
|
296
370
|
<div>{logical_items}</div>
|
|
297
|
-
|
|
371
|
+
</>
|
|
298
372
|
}
|
|
299
373
|
|
|
300
374
|
const { body } = await render(Basic);
|
|
@@ -303,13 +377,11 @@ second"</pre>
|
|
|
303
377
|
});
|
|
304
378
|
|
|
305
379
|
it('renders tracked state updates', async () => {
|
|
306
|
-
function Counter() {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
<div>{count}</div>
|
|
312
|
-
</>;
|
|
380
|
+
function Counter() @{
|
|
381
|
+
let &[count] = track(0);
|
|
382
|
+
count++;
|
|
383
|
+
count = count + 5;
|
|
384
|
+
<div>{count}</div>
|
|
313
385
|
}
|
|
314
386
|
|
|
315
387
|
const { body } = await render(Counter);
|
|
@@ -321,19 +393,17 @@ second"</pre>
|
|
|
321
393
|
function Child({ count, ...rest }: PropsNoChildren<{
|
|
322
394
|
count: Tracked<number>;
|
|
323
395
|
class: { test: boolean };
|
|
324
|
-
}>) {
|
|
325
|
-
|
|
396
|
+
}>) @{
|
|
397
|
+
<>
|
|
326
398
|
<div {...rest}>{'Child Component'}</div>
|
|
327
399
|
<div>{count.value}</div>
|
|
328
|
-
|
|
400
|
+
</>
|
|
329
401
|
}
|
|
330
402
|
|
|
331
|
-
function Parent() {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
<@Dynamic {count} class={{ test: true }} />
|
|
336
|
-
</>;
|
|
403
|
+
function Parent() @{
|
|
404
|
+
const count = track(10);
|
|
405
|
+
let Dynamic = track(() => Child);
|
|
406
|
+
<@Dynamic {count} class={{ test: true }} />
|
|
337
407
|
}
|
|
338
408
|
|
|
339
409
|
const { body } = await render(Parent);
|
|
@@ -342,13 +412,11 @@ second"</pre>
|
|
|
342
412
|
});
|
|
343
413
|
|
|
344
414
|
it('renders tracked object properties', async () => {
|
|
345
|
-
function ObjCounter() {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
<div>{obj.count.value}</div>
|
|
351
|
-
</>;
|
|
415
|
+
function ObjCounter() @{
|
|
416
|
+
const obj = { count: track(2) };
|
|
417
|
+
obj.count.value += 3;
|
|
418
|
+
obj.count.value = obj.count.value + 1;
|
|
419
|
+
<div>{obj.count.value}</div>
|
|
352
420
|
}
|
|
353
421
|
|
|
354
422
|
const { body } = await render(ObjCounter);
|
|
@@ -357,13 +425,11 @@ second"</pre>
|
|
|
357
425
|
});
|
|
358
426
|
|
|
359
427
|
it('renders spread props with tracked values', async () => {
|
|
360
|
-
function SpreadProps() {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
<div {...{ id: id, class: { active: isActive }, style: styles }}>{'Spread Props'}</div>
|
|
366
|
-
</>;
|
|
428
|
+
function SpreadProps() @{
|
|
429
|
+
let &[id] = track('unique-id');
|
|
430
|
+
let &[isActive] = track(true);
|
|
431
|
+
let &[styles] = track({ color: 'red', fontSize: '16px' });
|
|
432
|
+
<div {...{ id: id, class: { active: isActive }, style: styles }}>{'Spread Props'}</div>
|
|
367
433
|
}
|
|
368
434
|
|
|
369
435
|
const { body } = await render(SpreadProps);
|
|
@@ -374,15 +440,15 @@ second"</pre>
|
|
|
374
440
|
});
|
|
375
441
|
|
|
376
442
|
it('handles AssignExpressions with tracked values or properties correctly', async () => {
|
|
377
|
-
function Assignments() {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
443
|
+
function Assignments() @{
|
|
444
|
+
let &[count] = track(0);
|
|
445
|
+
const obj = { value: track(5) };
|
|
446
|
+
count += 10;
|
|
447
|
+
obj.value.value *= 2;
|
|
448
|
+
<>
|
|
383
449
|
<div>{count}</div>
|
|
384
450
|
<div>{obj.value.value}</div>
|
|
385
|
-
|
|
451
|
+
</>
|
|
386
452
|
}
|
|
387
453
|
|
|
388
454
|
const { body } = await render(Assignments);
|
|
@@ -391,15 +457,17 @@ second"</pre>
|
|
|
391
457
|
});
|
|
392
458
|
|
|
393
459
|
it(`handles derived changes via tracked dependencies' changes`, async () => {
|
|
394
|
-
function Derived() {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
460
|
+
function Derived() @{
|
|
461
|
+
let &[base] = track(5);
|
|
462
|
+
let &[multiplier] = track(3);
|
|
463
|
+
let &[derived] = track(() => base * multiplier);
|
|
464
|
+
const before = derived;
|
|
465
|
+
base += 2;
|
|
466
|
+
const after = derived;
|
|
467
|
+
<>
|
|
468
|
+
<div>{before}</div>
|
|
469
|
+
<div>{after}</div>
|
|
470
|
+
</>
|
|
403
471
|
}
|
|
404
472
|
|
|
405
473
|
const { body } = await render(Derived);
|
|
@@ -408,16 +476,18 @@ second"</pre>
|
|
|
408
476
|
});
|
|
409
477
|
|
|
410
478
|
it(`handles derived changes based on another derived's dependencies' changes`, async () => {
|
|
411
|
-
function NestedDerived() {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
479
|
+
function NestedDerived() @{
|
|
480
|
+
let &[a] = track(2);
|
|
481
|
+
let &[b] = track(3);
|
|
482
|
+
let &[sum] = track(() => a + b);
|
|
483
|
+
let &[product] = track(() => sum * 2);
|
|
484
|
+
const before = product;
|
|
485
|
+
a = 4;
|
|
486
|
+
const after = product;
|
|
487
|
+
<>
|
|
488
|
+
<div>{before}</div>
|
|
489
|
+
<div>{after}</div>
|
|
490
|
+
</>
|
|
421
491
|
}
|
|
422
492
|
|
|
423
493
|
const { body } = await render(NestedDerived);
|
|
@@ -426,23 +496,31 @@ second"</pre>
|
|
|
426
496
|
});
|
|
427
497
|
|
|
428
498
|
it('handles lexical scopes correctly', async () => {
|
|
429
|
-
function LexicalScopes() {
|
|
430
|
-
|
|
431
|
-
|
|
499
|
+
function LexicalScopes() @{
|
|
500
|
+
let &[x] = track(1);
|
|
501
|
+
let nested = '';
|
|
502
|
+
let deep = '';
|
|
503
|
+
let deeper = '';
|
|
504
|
+
{
|
|
505
|
+
let &[x] = track(10);
|
|
506
|
+
nested = String(x);
|
|
507
|
+
}
|
|
508
|
+
{
|
|
509
|
+
let &[x] = track(12);
|
|
510
|
+
deep = String(x);
|
|
511
|
+
{
|
|
512
|
+
let &[x] = track(15);
|
|
513
|
+
deeper = String(x);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
<>
|
|
432
517
|
<div>{x}</div>
|
|
518
|
+
<div>{nested}</div>
|
|
433
519
|
<div>
|
|
434
|
-
|
|
435
|
-
{
|
|
436
|
-
</div>
|
|
437
|
-
<div>
|
|
438
|
-
let &[x] = track(12);
|
|
439
|
-
{x}
|
|
440
|
-
<span>
|
|
441
|
-
let &[x] = track(15);
|
|
442
|
-
{x}
|
|
443
|
-
</span>
|
|
520
|
+
{deep}
|
|
521
|
+
<span>{deeper}</span>
|
|
444
522
|
</div>
|
|
445
|
-
|
|
523
|
+
</>
|
|
446
524
|
}
|
|
447
525
|
|
|
448
526
|
const { body } = await render(LexicalScopes);
|
|
@@ -451,48 +529,48 @@ second"</pre>
|
|
|
451
529
|
});
|
|
452
530
|
|
|
453
531
|
it('runs nested JavaScript blocks inside component-local callables', async () => {
|
|
454
|
-
function App() {
|
|
455
|
-
|
|
456
|
-
function
|
|
457
|
-
|
|
458
|
-
|
|
532
|
+
function App() @{
|
|
533
|
+
function readFunction() {
|
|
534
|
+
const label = 'function outer';
|
|
535
|
+
let result = '';
|
|
536
|
+
|
|
537
|
+
{
|
|
538
|
+
const label = 'function inner';
|
|
539
|
+
result = label;
|
|
540
|
+
}
|
|
459
541
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
542
|
+
return `${result} / ${label}`;
|
|
543
|
+
}
|
|
544
|
+
const readArrow = () => {
|
|
545
|
+
const offset = 5;
|
|
546
|
+
let value = offset;
|
|
464
547
|
|
|
465
|
-
|
|
548
|
+
{
|
|
549
|
+
const offset = 17;
|
|
550
|
+
value += offset;
|
|
466
551
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
552
|
+
|
|
553
|
+
return value;
|
|
554
|
+
};
|
|
555
|
+
class Reader {
|
|
556
|
+
read() {
|
|
557
|
+
const label = 'method outer';
|
|
558
|
+
let result = '';
|
|
470
559
|
|
|
471
560
|
{
|
|
472
|
-
const
|
|
473
|
-
|
|
561
|
+
const label = 'method inner';
|
|
562
|
+
result = label;
|
|
474
563
|
}
|
|
475
564
|
|
|
476
|
-
return
|
|
477
|
-
};
|
|
478
|
-
class Reader {
|
|
479
|
-
read() {
|
|
480
|
-
const label = 'method outer';
|
|
481
|
-
let result = '';
|
|
482
|
-
|
|
483
|
-
{
|
|
484
|
-
const label = 'method inner';
|
|
485
|
-
result = label;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
return `${result} / ${label}`;
|
|
489
|
-
}
|
|
565
|
+
return `${result} / ${label}`;
|
|
490
566
|
}
|
|
491
|
-
|
|
567
|
+
}
|
|
568
|
+
const reader = new Reader();
|
|
569
|
+
<>
|
|
492
570
|
<div class="block-function">{readFunction()}</div>
|
|
493
571
|
<div class="block-arrow">{readArrow()}</div>
|
|
494
572
|
<div class="block-method">{reader.read()}</div>
|
|
495
|
-
|
|
573
|
+
</>
|
|
496
574
|
}
|
|
497
575
|
|
|
498
576
|
const { body } = await render(App);
|