ripple 0.3.7 → 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.
Files changed (100) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +2 -2
  3. package/src/compiler/phases/1-parse/index.js +37 -194
  4. package/src/compiler/phases/2-analyze/index.js +63 -18
  5. package/src/compiler/phases/3-transform/client/index.js +19 -3
  6. package/src/compiler/phases/3-transform/server/index.js +16 -24
  7. package/src/compiler/types/parse.d.ts +0 -8
  8. package/src/runtime/internal/client/composite.js +2 -2
  9. package/tests/client/array/array.copy-within.test.ripple +12 -12
  10. package/tests/client/array/array.derived.test.ripple +46 -46
  11. package/tests/client/array/array.iteration.test.ripple +10 -10
  12. package/tests/client/array/array.mutations.test.ripple +20 -20
  13. package/tests/client/array/array.to-methods.test.ripple +6 -6
  14. package/tests/client/async-suspend.test.ripple +5 -5
  15. package/tests/client/basic/basic.attributes.test.ripple +81 -81
  16. package/tests/client/basic/basic.collections.test.ripple +9 -9
  17. package/tests/client/basic/basic.components.test.ripple +28 -28
  18. package/tests/client/basic/basic.errors.test.ripple +18 -18
  19. package/tests/client/basic/basic.events.test.ripple +37 -37
  20. package/tests/client/basic/basic.get-set.test.ripple +6 -6
  21. package/tests/client/basic/basic.reactivity.test.ripple +68 -68
  22. package/tests/client/basic/basic.rendering.test.ripple +19 -19
  23. package/tests/client/basic/basic.utilities.test.ripple +3 -3
  24. package/tests/client/boundaries.test.ripple +12 -12
  25. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
  26. package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
  27. package/tests/client/compiler/compiler.basic.test.ripple +16 -16
  28. package/tests/client/compiler/compiler.tracked-access.test.ripple +2 -2
  29. package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
  30. package/tests/client/composite/composite.props.test.ripple +11 -11
  31. package/tests/client/composite/composite.reactivity.test.ripple +43 -43
  32. package/tests/client/composite/composite.render.test.ripple +3 -3
  33. package/tests/client/computed-properties.test.ripple +4 -4
  34. package/tests/client/date.test.ripple +42 -42
  35. package/tests/client/dynamic-elements.test.ripple +42 -42
  36. package/tests/client/events.test.ripple +70 -70
  37. package/tests/client/for.test.ripple +25 -25
  38. package/tests/client/head.test.ripple +19 -19
  39. package/tests/client/html.test.ripple +3 -3
  40. package/tests/client/input-value.test.ripple +84 -84
  41. package/tests/client/lazy-destructuring.test.ripple +71 -16
  42. package/tests/client/map.test.ripple +16 -16
  43. package/tests/client/media-query.test.ripple +7 -7
  44. package/tests/client/portal.test.ripple +11 -11
  45. package/tests/client/ref.test.ripple +4 -4
  46. package/tests/client/return.test.ripple +52 -52
  47. package/tests/client/set.test.ripple +6 -6
  48. package/tests/client/svg.test.ripple +5 -5
  49. package/tests/client/switch.test.ripple +44 -44
  50. package/tests/client/try.test.ripple +5 -5
  51. package/tests/client/url/url.derived.test.ripple +6 -6
  52. package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
  53. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
  54. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
  55. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
  56. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
  57. package/tests/hydration/compiled/client/events.js +25 -25
  58. package/tests/hydration/compiled/client/for.js +70 -66
  59. package/tests/hydration/compiled/client/head.js +25 -25
  60. package/tests/hydration/compiled/client/hmr.js +2 -2
  61. package/tests/hydration/compiled/client/html.js +3 -3
  62. package/tests/hydration/compiled/client/if-children.js +24 -24
  63. package/tests/hydration/compiled/client/if.js +18 -18
  64. package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
  65. package/tests/hydration/compiled/client/portal.js +3 -3
  66. package/tests/hydration/compiled/client/reactivity.js +16 -16
  67. package/tests/hydration/compiled/client/return.js +40 -40
  68. package/tests/hydration/compiled/client/switch.js +12 -12
  69. package/tests/hydration/compiled/server/events.js +19 -19
  70. package/tests/hydration/compiled/server/for.js +41 -41
  71. package/tests/hydration/compiled/server/head.js +26 -26
  72. package/tests/hydration/compiled/server/hmr.js +2 -2
  73. package/tests/hydration/compiled/server/html.js +2 -2
  74. package/tests/hydration/compiled/server/if-children.js +16 -16
  75. package/tests/hydration/compiled/server/if.js +11 -11
  76. package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
  77. package/tests/hydration/compiled/server/portal.js +2 -2
  78. package/tests/hydration/compiled/server/reactivity.js +16 -16
  79. package/tests/hydration/compiled/server/return.js +25 -25
  80. package/tests/hydration/compiled/server/switch.js +8 -8
  81. package/tests/hydration/components/events.ripple +25 -25
  82. package/tests/hydration/components/for.ripple +66 -66
  83. package/tests/hydration/components/head.ripple +16 -16
  84. package/tests/hydration/components/hmr.ripple +2 -2
  85. package/tests/hydration/components/html.ripple +3 -3
  86. package/tests/hydration/components/if-children.ripple +24 -24
  87. package/tests/hydration/components/if.ripple +18 -18
  88. package/tests/hydration/components/mixed-control-flow.ripple +9 -9
  89. package/tests/hydration/components/portal.ripple +3 -3
  90. package/tests/hydration/components/reactivity.ripple +16 -16
  91. package/tests/hydration/components/return.ripple +40 -40
  92. package/tests/hydration/components/switch.ripple +20 -20
  93. package/tests/server/await.test.ripple +3 -3
  94. package/tests/server/basic.attributes.test.ripple +34 -34
  95. package/tests/server/basic.components.test.ripple +10 -10
  96. package/tests/server/basic.test.ripple +38 -40
  97. package/tests/server/composite.props.test.ripple +9 -9
  98. package/tests/server/dynamic-elements.test.ripple +13 -12
  99. package/tests/server/head.test.ripple +11 -11
  100. package/tests/server/lazy-destructuring.test.ripple +27 -4
@@ -3,36 +3,36 @@ import { track } from 'ripple';
3
3
  // Event handling components for hydration testing
4
4
 
5
5
  export component ClickCounter() {
6
- let count = track(0);
6
+ let &[count] = track(0);
7
7
  <div>
8
8
  <button
9
9
  class="increment"
10
10
  onClick={() => {
11
- @count++;
11
+ count++;
12
12
  }}
13
13
  >
14
14
  {'Increment'}
15
15
  </button>
16
- <span class="count">{@count}</span>
16
+ <span class="count">{count}</span>
17
17
  </div>
18
18
  }
19
19
 
20
20
  export component IncrementDecrement() {
21
- let count = track(0);
21
+ let &[count] = track(0);
22
22
  <div>
23
23
  <button
24
24
  class="decrement"
25
25
  onClick={() => {
26
- @count--;
26
+ count--;
27
27
  }}
28
28
  >
29
29
  {'-'}
30
30
  </button>
31
- <span class="count">{@count}</span>
31
+ <span class="count">{count}</span>
32
32
  <button
33
33
  class="increment"
34
34
  onClick={() => {
35
- @count++;
35
+ count++;
36
36
  }}
37
37
  >
38
38
  {'+'}
@@ -41,51 +41,51 @@ export component IncrementDecrement() {
41
41
  }
42
42
 
43
43
  export component MultipleEvents() {
44
- let clicks = track(0);
45
- let hovers = track(0);
44
+ let &[clicks] = track(0);
45
+ let &[hovers] = track(0);
46
46
  <div>
47
47
  <button
48
48
  class="target"
49
49
  onClick={() => {
50
- @clicks++;
50
+ clicks++;
51
51
  }}
52
52
  onMouseEnter={() => {
53
- @hovers++;
53
+ hovers++;
54
54
  }}
55
55
  >
56
56
  {'Target'}
57
57
  </button>
58
- <span class="clicks">{@clicks}</span>
59
- <span class="hovers">{@hovers}</span>
58
+ <span class="clicks">{clicks}</span>
59
+ <span class="hovers">{hovers}</span>
60
60
  </div>
61
61
  }
62
62
 
63
63
  export component MultiStateUpdate() {
64
- let count = track(0);
65
- let lastAction = track('none');
64
+ let &[count] = track(0);
65
+ let &[lastAction] = track('none');
66
66
 
67
67
  const handleClick = () => {
68
- @count++;
69
- @lastAction = 'increment';
68
+ count++;
69
+ lastAction = 'increment';
70
70
  };
71
71
 
72
72
  <div>
73
73
  <button class="btn" onClick={handleClick}>{'Click'}</button>
74
- <span class="count">{@count}</span>
75
- <span class="action">{@lastAction}</span>
74
+ <span class="count">{count}</span>
75
+ <span class="action">{lastAction}</span>
76
76
  </div>
77
77
  }
78
78
 
79
79
  export component ToggleButton() {
80
- let isOn = track(false);
80
+ let &[isOn] = track(false);
81
81
  <div>
82
82
  <button
83
83
  class="toggle"
84
84
  onClick={() => {
85
- @isOn = !@isOn;
85
+ isOn = !isOn;
86
86
  }}
87
87
  >
88
- {@isOn ? 'ON' : 'OFF'}
88
+ {isOn ? 'ON' : 'OFF'}
89
89
  </button>
90
90
  </div>
91
91
  }
@@ -95,14 +95,14 @@ export component ChildButton(props: { onClick: () => void; label: string }) {
95
95
  }
96
96
 
97
97
  export component ParentWithChildButton() {
98
- let count = track(0);
98
+ let &[count] = track(0);
99
99
  <div>
100
100
  <ChildButton
101
101
  onClick={() => {
102
- @count++;
102
+ count++;
103
103
  }}
104
104
  label="Click me"
105
105
  />
106
- <span class="count">{@count}</span>
106
+ <span class="count">{count}</span>
107
107
  </div>
108
108
  }
@@ -34,51 +34,51 @@ export component KeyedForLoop() {
34
34
  }
35
35
 
36
36
  export component ReactiveForLoopAdd() {
37
- let items = track(['A', 'B']);
37
+ let &[items] = track(['A', 'B']);
38
38
  <button
39
39
  class="add"
40
40
  onClick={() => {
41
- @items = [...@items, 'C'];
41
+ items = [...items, 'C'];
42
42
  }}
43
43
  >
44
44
  {'Add'}
45
45
  </button>
46
46
  <ul>
47
- for (const item of @items) {
47
+ for (const item of items) {
48
48
  <li>{item}</li>
49
49
  }
50
50
  </ul>
51
51
  }
52
52
 
53
53
  export component ReactiveForLoopRemove() {
54
- let items = track(['A', 'B', 'C']);
54
+ let &[items] = track(['A', 'B', 'C']);
55
55
  <button
56
56
  class="remove"
57
57
  onClick={() => {
58
- @items = @items.slice(0, -1);
58
+ items = items.slice(0, -1);
59
59
  }}
60
60
  >
61
61
  {'Remove'}
62
62
  </button>
63
63
  <ul>
64
- for (const item of @items) {
64
+ for (const item of items) {
65
65
  <li>{item}</li>
66
66
  }
67
67
  </ul>
68
68
  }
69
69
 
70
70
  export component ForLoopInteractive() {
71
- let counts = track([0, 0, 0]);
71
+ let &[counts] = track([0, 0, 0]);
72
72
  <div>
73
- for (const count of @counts; index i) {
73
+ for (const count of counts; index i) {
74
74
  <div class={`item-${i}`}>
75
75
  <span class="value">{count}</span>
76
76
  <button
77
77
  class="increment"
78
78
  onClick={() => {
79
- const newCounts = [...@counts];
79
+ const newCounts = [...counts];
80
80
  newCounts[i]++;
81
- @counts = newCounts;
81
+ counts = newCounts;
82
82
  }}
83
83
  >
84
84
  {'+'}
@@ -130,7 +130,7 @@ export component ForLoopComplexObjects() {
130
130
 
131
131
  // Test reordering items in a keyed for loop
132
132
  export component KeyedForLoopReorder() {
133
- let items = track([
133
+ let &[items] = track([
134
134
  { id: 1, name: 'First' },
135
135
  { id: 2, name: 'Second' },
136
136
  { id: 3, name: 'Third' },
@@ -138,13 +138,13 @@ export component KeyedForLoopReorder() {
138
138
  <button
139
139
  class="reorder"
140
140
  onClick={() => {
141
- @items = [@items[2], @items[0], @items[1]];
141
+ items = [items[2], items[0], items[1]];
142
142
  }}
143
143
  >
144
144
  {'Reorder'}
145
145
  </button>
146
146
  <ul>
147
- for (const item of @items; key item.id) {
147
+ for (const item of items; key item.id) {
148
148
  <li class={`item-${item.id}`}>{item.name}</li>
149
149
  }
150
150
  </ul>
@@ -152,20 +152,20 @@ export component KeyedForLoopReorder() {
152
152
 
153
153
  // Test for loop with item property updates (keyed)
154
154
  export component KeyedForLoopUpdate() {
155
- let items = track([
155
+ let &[items] = track([
156
156
  { id: 1, name: 'Item 1' },
157
157
  { id: 2, name: 'Item 2' },
158
158
  ]);
159
159
  <button
160
160
  class="update"
161
161
  onClick={() => {
162
- @items = @items.map((item) => (item.id === 1 ? { ...item, name: 'Updated' } : item));
162
+ items = items.map((item) => (item.id === 1 ? { ...item, name: 'Updated' } : item));
163
163
  }}
164
164
  >
165
165
  {'Update'}
166
166
  </button>
167
167
  <ul>
168
- for (const item of @items; key item.id) {
168
+ for (const item of items; key item.id) {
169
169
  <li class={`item-${item.id}`}>{item.name}</li>
170
170
  }
171
171
  </ul>
@@ -173,18 +173,18 @@ export component KeyedForLoopUpdate() {
173
173
 
174
174
  // Test for loop with combined add/remove/reorder
175
175
  export component ForLoopMixedOperations() {
176
- let items = track(['A', 'B', 'C', 'D']);
176
+ let &[items] = track(['A', 'B', 'C', 'D']);
177
177
  <button
178
178
  class="shuffle"
179
179
  onClick={() => {
180
180
  // Remove B, add E, reorder to D, C, A, E
181
- @items = ['D', 'C', 'A', 'E'];
181
+ items = ['D', 'C', 'A', 'E'];
182
182
  }}
183
183
  >
184
184
  {'Shuffle'}
185
185
  </button>
186
186
  <ul>
187
- for (const item of @items) {
187
+ for (const item of items) {
188
188
  <li class={`item-${item}`}>{item}</li>
189
189
  }
190
190
  </ul>
@@ -192,12 +192,12 @@ export component ForLoopMixedOperations() {
192
192
 
193
193
  // Test for loop inside if block (combined control flow)
194
194
  export component ForLoopInsideIf() {
195
- let showList = track(true);
196
- let items = track(['X', 'Y', 'Z']);
195
+ let &[showList] = track(true);
196
+ let &[items] = track(['X', 'Y', 'Z']);
197
197
  <button
198
198
  class="toggle"
199
199
  onClick={() => {
200
- @showList = !@showList;
200
+ showList = !showList;
201
201
  }}
202
202
  >
203
203
  {'Toggle List'}
@@ -205,14 +205,14 @@ export component ForLoopInsideIf() {
205
205
  <button
206
206
  class="add"
207
207
  onClick={() => {
208
- @items = [...@items, 'W'];
208
+ items = [...items, 'W'];
209
209
  }}
210
210
  >
211
211
  {'Add Item'}
212
212
  </button>
213
- if (@showList) {
213
+ if (showList) {
214
214
  <ul class="list">
215
- for (const item of @items) {
215
+ for (const item of items) {
216
216
  <li>{item}</li>
217
217
  }
218
218
  </ul>
@@ -221,17 +221,17 @@ export component ForLoopInsideIf() {
221
221
 
222
222
  // Test for loop that transitions from empty to populated
223
223
  export component ForLoopEmptyToPopulated() {
224
- let items = track<string[]>([]);
224
+ let &[items] = track<string[]>([]);
225
225
  <button
226
226
  class="populate"
227
227
  onClick={() => {
228
- @items = ['One', 'Two', 'Three'];
228
+ items = ['One', 'Two', 'Three'];
229
229
  }}
230
230
  >
231
231
  {'Populate'}
232
232
  </button>
233
233
  <ul class="list">
234
- for (const item of @items) {
234
+ for (const item of items) {
235
235
  <li>{item}</li>
236
236
  }
237
237
  </ul>
@@ -239,17 +239,17 @@ export component ForLoopEmptyToPopulated() {
239
239
 
240
240
  // Test for loop that transitions from populated to empty
241
241
  export component ForLoopPopulatedToEmpty() {
242
- let items = track(['One', 'Two', 'Three']);
242
+ let &[items] = track(['One', 'Two', 'Three']);
243
243
  <button
244
244
  class="clear"
245
245
  onClick={() => {
246
- @items = [];
246
+ items = [];
247
247
  }}
248
248
  >
249
249
  {'Clear'}
250
250
  </button>
251
251
  <ul class="list">
252
- for (const item of @items) {
252
+ for (const item of items) {
253
253
  <li>{item}</li>
254
254
  }
255
255
  </ul>
@@ -257,14 +257,14 @@ export component ForLoopPopulatedToEmpty() {
257
257
 
258
258
  // Test nested for loops with reactivity
259
259
  export component NestedForLoopReactive() {
260
- let grid = track([
260
+ let &[grid] = track([
261
261
  [1, 2],
262
262
  [3, 4],
263
263
  ]);
264
264
  <button
265
265
  class="add-row"
266
266
  onClick={() => {
267
- @grid = [...@grid, [5, 6]];
267
+ grid = [...grid, [5, 6]];
268
268
  }}
269
269
  >
270
270
  {'Add Row'}
@@ -272,15 +272,15 @@ export component NestedForLoopReactive() {
272
272
  <button
273
273
  class="update-cell"
274
274
  onClick={() => {
275
- const newGrid = @grid.map((row) => [...row]);
275
+ const newGrid = grid.map((row) => [...row]);
276
276
  newGrid[0][0] = 99;
277
- @grid = newGrid;
277
+ grid = newGrid;
278
278
  }}
279
279
  >
280
280
  {'Update Cell'}
281
281
  </button>
282
282
  <div class="grid">
283
- for (const row of @grid; index rowIndex) {
283
+ for (const row of grid; index rowIndex) {
284
284
  <div class={`row-${rowIndex}`}>
285
285
  for (const cell of row; index colIndex) {
286
286
  <span class={`cell-${rowIndex}-${colIndex}`}>{cell}</span>
@@ -330,17 +330,17 @@ export component ForLoopDeeplyNested() {
330
330
 
331
331
  // Test for loop with index that gets updated
332
332
  export component ForLoopIndexUpdate() {
333
- let items = track(['First', 'Second', 'Third']);
333
+ let &[items] = track(['First', 'Second', 'Third']);
334
334
  <button
335
335
  class="prepend"
336
336
  onClick={() => {
337
- @items = ['Zeroth', ...@items];
337
+ items = ['Zeroth', ...items];
338
338
  }}
339
339
  >
340
340
  {'Prepend'}
341
341
  </button>
342
342
  <ul>
343
- for (const item of @items; index i) {
343
+ for (const item of items; index i) {
344
344
  <li class={`item-${i}`}>{`[${i}] ${item}`}</li>
345
345
  }
346
346
  </ul>
@@ -348,7 +348,7 @@ export component ForLoopIndexUpdate() {
348
348
 
349
349
  // Test keyed for loop with index
350
350
  export component KeyedForLoopWithIndex() {
351
- let items = track([
351
+ let &[items] = track([
352
352
  { id: 'a', value: 'Alpha' },
353
353
  { id: 'b', value: 'Beta' },
354
354
  { id: 'c', value: 'Gamma' },
@@ -356,13 +356,13 @@ export component KeyedForLoopWithIndex() {
356
356
  <button
357
357
  class="reorder"
358
358
  onClick={() => {
359
- @items = [@items[1], @items[2], @items[0]];
359
+ items = [items[1], items[2], items[0]];
360
360
  }}
361
361
  >
362
362
  {'Rotate'}
363
363
  </button>
364
364
  <ul>
365
- for (const item of @items; index i; key item.id) {
365
+ for (const item of items; index i; key item.id) {
366
366
  <li class={`item-${item.id}`} data-index={i}>{`[${i}] ${item.id}: ${item.value}`}</li>
367
367
  }
368
368
  </ul>
@@ -370,10 +370,10 @@ export component KeyedForLoopWithIndex() {
370
370
 
371
371
  // Test for loop with sibling elements
372
372
  export component ForLoopWithSiblings() {
373
- let items = track(['A', 'B']);
373
+ let &[items] = track(['A', 'B']);
374
374
  <div class="wrapper">
375
375
  <header class="before">{'Before'}</header>
376
- for (const item of @items) {
376
+ for (const item of items) {
377
377
  <div class={`item-${item}`}>{item}</div>
378
378
  }
379
379
  <footer class="after">{'After'}</footer>
@@ -381,7 +381,7 @@ export component ForLoopWithSiblings() {
381
381
  <button
382
382
  class="add"
383
383
  onClick={() => {
384
- @items = [...@items, 'C'];
384
+ items = [...items, 'C'];
385
385
  }}
386
386
  >
387
387
  {'Add'}
@@ -403,17 +403,17 @@ export component ForLoopItemState() {
403
403
  }
404
404
 
405
405
  component TodoItem(props: { id: number; text: string }) {
406
- let done = track(false);
406
+ let &[done] = track(false);
407
407
  <div class={`todo-${props.id}`}>
408
408
  <input
409
409
  type="checkbox"
410
410
  class="checkbox"
411
- checked={@done}
411
+ checked={done}
412
412
  onChange={(e) => {
413
- @done = (e.target as HTMLInputElement).checked;
413
+ done = (e.target as HTMLInputElement).checked;
414
414
  }}
415
415
  />
416
- <span class={@done ? 'completed' : 'pending'}>{props.text}</span>
416
+ <span class={done ? 'completed' : 'pending'}>{props.text}</span>
417
417
  </div>
418
418
  }
419
419
 
@@ -429,17 +429,17 @@ export component ForLoopSingleItem() {
429
429
 
430
430
  // Test for loop adding at beginning
431
431
  export component ForLoopAddAtBeginning() {
432
- let items = track(['B', 'C']);
432
+ let &[items] = track(['B', 'C']);
433
433
  <button
434
434
  class="prepend"
435
435
  onClick={() => {
436
- @items = ['A', ...@items];
436
+ items = ['A', ...items];
437
437
  }}
438
438
  >
439
439
  {'Prepend A'}
440
440
  </button>
441
441
  <ul>
442
- for (const item of @items) {
442
+ for (const item of items) {
443
443
  <li class={`item-${item}`}>{item}</li>
444
444
  }
445
445
  </ul>
@@ -447,19 +447,19 @@ export component ForLoopAddAtBeginning() {
447
447
 
448
448
  // Test for loop adding in the middle
449
449
  export component ForLoopAddInMiddle() {
450
- let items = track(['A', 'C']);
450
+ let &[items] = track(['A', 'C']);
451
451
  <button
452
452
  class="insert"
453
453
  onClick={() => {
454
- const copy = [...@items];
454
+ const copy = [...items];
455
455
  copy.splice(1, 0, 'B');
456
- @items = copy;
456
+ items = copy;
457
457
  }}
458
458
  >
459
459
  {'Insert B'}
460
460
  </button>
461
461
  <ul>
462
- for (const item of @items) {
462
+ for (const item of items) {
463
463
  <li class={`item-${item}`}>{item}</li>
464
464
  }
465
465
  </ul>
@@ -467,17 +467,17 @@ export component ForLoopAddInMiddle() {
467
467
 
468
468
  // Test for loop removing from the middle
469
469
  export component ForLoopRemoveFromMiddle() {
470
- let items = track(['A', 'B', 'C']);
470
+ let &[items] = track(['A', 'B', 'C']);
471
471
  <button
472
472
  class="remove-middle"
473
473
  onClick={() => {
474
- @items = @items.filter((item) => item !== 'B');
474
+ items = items.filter((item) => item !== 'B');
475
475
  }}
476
476
  >
477
477
  {'Remove B'}
478
478
  </button>
479
479
  <ul>
480
- for (const item of @items) {
480
+ for (const item of items) {
481
481
  <li class={`item-${item}`}>{item}</li>
482
482
  }
483
483
  </ul>
@@ -495,19 +495,19 @@ export component ForLoopLargeList() {
495
495
 
496
496
  // Test for loop with swap operation
497
497
  export component ForLoopSwap() {
498
- let items = track(['A', 'B', 'C', 'D']);
498
+ let &[items] = track(['A', 'B', 'C', 'D']);
499
499
  <button
500
500
  class="swap"
501
501
  onClick={() => {
502
- const copy = [...@items];
502
+ const copy = [...items];
503
503
  [copy[0], copy[3]] = [copy[3], copy[0]];
504
- @items = copy;
504
+ items = copy;
505
505
  }}
506
506
  >
507
507
  {'Swap First and Last'}
508
508
  </button>
509
509
  <ul>
510
- for (const item of @items) {
510
+ for (const item of items) {
511
511
  <li class={`item-${item}`}>{item}</li>
512
512
  }
513
513
  </ul>
@@ -515,17 +515,17 @@ export component ForLoopSwap() {
515
515
 
516
516
  // Test for loop with reverse operation
517
517
  export component ForLoopReverse() {
518
- let items = track(['A', 'B', 'C', 'D']);
518
+ let &[items] = track(['A', 'B', 'C', 'D']);
519
519
  <button
520
520
  class="reverse"
521
521
  onClick={() => {
522
- @items = [...@items].reverse();
522
+ items = [...items].reverse();
523
523
  }}
524
524
  >
525
525
  {'Reverse'}
526
526
  </button>
527
527
  <ul>
528
- for (const item of @items) {
528
+ for (const item of items) {
529
529
  <li class={`item-${item}`}>{item}</li>
530
530
  }
531
531
  </ul>
@@ -11,13 +11,13 @@ export component StaticTitle() {
11
11
 
12
12
  // Reactive title
13
13
  export component ReactiveTitle() {
14
- let title = track('Initial Title');
14
+ let &[title] = track('Initial Title');
15
15
 
16
16
  <head>
17
- <title>{@title}</title>
17
+ <title>{title}</title>
18
18
  </head>
19
19
  <div>
20
- <span>{@title}</span>
20
+ <span>{title}</span>
21
21
  </div>
22
22
  }
23
23
 
@@ -34,25 +34,25 @@ export component MultipleHeadElements() {
34
34
 
35
35
  // Head with reactive meta tags
36
36
  export component ReactiveMetaTags() {
37
- let description = track('Initial description');
37
+ let &[description] = track('Initial description');
38
38
 
39
39
  <head>
40
40
  <title>{'My Page'}</title>
41
- <meta name="description" content={@description} />
41
+ <meta name="description" content={description} />
42
42
  </head>
43
43
 
44
- <div>{@description}</div>
44
+ <div>{description}</div>
45
45
  }
46
46
 
47
47
  // Title with template literal
48
48
  export component TitleWithTemplate() {
49
- let name = track('World');
49
+ let &[name] = track('World');
50
50
 
51
51
  <head>
52
- <title>{`Hello ${@name}!`}</title>
52
+ <title>{`Hello ${name}!`}</title>
53
53
  </head>
54
54
 
55
- <div>{@name}</div>
55
+ <div>{name}</div>
56
56
  }
57
57
 
58
58
  // Empty title
@@ -65,26 +65,26 @@ export component EmptyTitle() {
65
65
 
66
66
  // Title with conditional content
67
67
  export component ConditionalTitle() {
68
- let showPrefix = track(true);
69
- let title = track('Main Page');
68
+ let &[showPrefix] = track(true);
69
+ let &[title] = track('Main Page');
70
70
 
71
71
  <head>
72
- <title>{@showPrefix ? 'App - ' + @title : @title}</title>
72
+ <title>{showPrefix ? 'App - ' + title : title}</title>
73
73
  </head>
74
74
 
75
- <div>{@title}</div>
75
+ <div>{title}</div>
76
76
  }
77
77
 
78
78
  // Title with computed value
79
79
  export component ComputedTitle() {
80
- let count = track(0);
80
+ let &[count] = track(0);
81
81
  let prefix = 'Count: ';
82
82
 
83
83
  <head>
84
- <title>{prefix + @count}</title>
84
+ <title>{prefix + count}</title>
85
85
  </head>
86
86
  <div>
87
- <span>{@count}</span>
87
+ <span>{count}</span>
88
88
  </div>
89
89
  }
90
90
 
@@ -19,10 +19,10 @@ export component Layout({ children }: { children: any }) {
19
19
 
20
20
  // A child component with an if block (the key source of deep hydrate_node)
21
21
  export component Content() {
22
- let visible = track(true);
22
+ let &[visible] = track(true);
23
23
 
24
24
  <div class="content">
25
- if (@visible) {
25
+ if (visible) {
26
26
  <p class="text">{'Hello world'}</p>
27
27
  }
28
28
  </div>
@@ -229,13 +229,13 @@ component NavItem({
229
229
  }
230
230
 
231
231
  component SidebarSection({ title, children }: { title: string; children: any }) {
232
- let expanded = track(true);
232
+ let &[expanded] = track(true);
233
233
  <section class="sidebar-section">
234
234
  <div class="section-header">
235
235
  <h2>{title}</h2>
236
- <button onClick={() => (@expanded = !@expanded)}>{'Toggle'}</button>
236
+ <button onClick={() => (expanded = !expanded)}>{'Toggle'}</button>
237
237
  </div>
238
- if (@expanded) {
238
+ if (expanded) {
239
239
  <div class="section-items">
240
240
  <children />
241
241
  </div>