ripple 0.3.68 → 0.3.69

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