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.
Files changed (110) hide show
  1. package/CHANGELOG.md +43 -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 +290 -26
  5. package/src/compiler/phases/3-transform/client/index.js +54 -14
  6. package/src/compiler/phases/3-transform/server/index.js +19 -35
  7. package/src/compiler/types/index.d.ts +3 -1
  8. package/src/compiler/types/parse.d.ts +0 -8
  9. package/src/compiler/utils.js +10 -6
  10. package/src/runtime/internal/client/composite.js +2 -2
  11. package/src/runtime/internal/client/index.js +2 -0
  12. package/src/runtime/internal/client/runtime.js +95 -45
  13. package/src/runtime/internal/client/types.d.ts +10 -0
  14. package/src/runtime/internal/client/utils.js +12 -0
  15. package/src/runtime/internal/server/index.js +89 -17
  16. package/src/runtime/internal/server/types.d.ts +10 -0
  17. package/src/utils/ast.js +1 -1
  18. package/tests/client/array/array.copy-within.test.ripple +12 -12
  19. package/tests/client/array/array.derived.test.ripple +46 -46
  20. package/tests/client/array/array.iteration.test.ripple +10 -10
  21. package/tests/client/array/array.mutations.test.ripple +20 -20
  22. package/tests/client/array/array.to-methods.test.ripple +6 -6
  23. package/tests/client/async-suspend.test.ripple +5 -5
  24. package/tests/client/basic/basic.attributes.test.ripple +81 -81
  25. package/tests/client/basic/basic.collections.test.ripple +9 -9
  26. package/tests/client/basic/basic.components.test.ripple +28 -28
  27. package/tests/client/basic/basic.errors.test.ripple +18 -18
  28. package/tests/client/basic/basic.events.test.ripple +37 -37
  29. package/tests/client/basic/basic.get-set.test.ripple +6 -6
  30. package/tests/client/basic/basic.reactivity.test.ripple +68 -68
  31. package/tests/client/basic/basic.rendering.test.ripple +19 -19
  32. package/tests/client/basic/basic.utilities.test.ripple +3 -3
  33. package/tests/client/boundaries.test.ripple +12 -12
  34. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
  35. package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
  36. package/tests/client/compiler/compiler.basic.test.ripple +44 -15
  37. package/tests/client/compiler/compiler.tracked-access.test.ripple +68 -2
  38. package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
  39. package/tests/client/composite/composite.props.test.ripple +11 -11
  40. package/tests/client/composite/composite.reactivity.test.ripple +43 -43
  41. package/tests/client/composite/composite.render.test.ripple +3 -3
  42. package/tests/client/computed-properties.test.ripple +4 -4
  43. package/tests/client/date.test.ripple +42 -42
  44. package/tests/client/dynamic-elements.test.ripple +42 -42
  45. package/tests/client/events.test.ripple +70 -70
  46. package/tests/client/for.test.ripple +25 -25
  47. package/tests/client/head.test.ripple +19 -19
  48. package/tests/client/html.test.ripple +3 -3
  49. package/tests/client/input-value.test.ripple +84 -84
  50. package/tests/client/lazy-destructuring.test.ripple +123 -14
  51. package/tests/client/map.test.ripple +16 -16
  52. package/tests/client/media-query.test.ripple +7 -7
  53. package/tests/client/portal.test.ripple +11 -11
  54. package/tests/client/ref.test.ripple +4 -4
  55. package/tests/client/return.test.ripple +52 -52
  56. package/tests/client/set.test.ripple +6 -6
  57. package/tests/client/svg.test.ripple +5 -5
  58. package/tests/client/switch.test.ripple +44 -44
  59. package/tests/client/try.test.ripple +5 -5
  60. package/tests/client/url/url.derived.test.ripple +6 -6
  61. package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
  62. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
  63. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
  64. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
  65. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
  66. package/tests/hydration/compiled/client/events.js +25 -25
  67. package/tests/hydration/compiled/client/for.js +70 -66
  68. package/tests/hydration/compiled/client/head.js +25 -25
  69. package/tests/hydration/compiled/client/hmr.js +2 -2
  70. package/tests/hydration/compiled/client/html.js +3 -3
  71. package/tests/hydration/compiled/client/if-children.js +24 -24
  72. package/tests/hydration/compiled/client/if.js +18 -18
  73. package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
  74. package/tests/hydration/compiled/client/portal.js +3 -3
  75. package/tests/hydration/compiled/client/reactivity.js +16 -16
  76. package/tests/hydration/compiled/client/return.js +40 -40
  77. package/tests/hydration/compiled/client/switch.js +12 -12
  78. package/tests/hydration/compiled/server/events.js +19 -19
  79. package/tests/hydration/compiled/server/for.js +41 -41
  80. package/tests/hydration/compiled/server/head.js +26 -26
  81. package/tests/hydration/compiled/server/hmr.js +2 -2
  82. package/tests/hydration/compiled/server/html.js +2 -2
  83. package/tests/hydration/compiled/server/if-children.js +16 -16
  84. package/tests/hydration/compiled/server/if.js +11 -11
  85. package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
  86. package/tests/hydration/compiled/server/portal.js +2 -2
  87. package/tests/hydration/compiled/server/reactivity.js +16 -16
  88. package/tests/hydration/compiled/server/return.js +25 -25
  89. package/tests/hydration/compiled/server/switch.js +8 -8
  90. package/tests/hydration/components/events.ripple +25 -25
  91. package/tests/hydration/components/for.ripple +66 -66
  92. package/tests/hydration/components/head.ripple +16 -16
  93. package/tests/hydration/components/hmr.ripple +2 -2
  94. package/tests/hydration/components/html.ripple +3 -3
  95. package/tests/hydration/components/if-children.ripple +24 -24
  96. package/tests/hydration/components/if.ripple +18 -18
  97. package/tests/hydration/components/mixed-control-flow.ripple +9 -9
  98. package/tests/hydration/components/portal.ripple +3 -3
  99. package/tests/hydration/components/reactivity.ripple +16 -16
  100. package/tests/hydration/components/return.ripple +40 -40
  101. package/tests/hydration/components/switch.ripple +20 -20
  102. package/tests/server/await.test.ripple +3 -3
  103. package/tests/server/basic.attributes.test.ripple +34 -34
  104. package/tests/server/basic.components.test.ripple +10 -10
  105. package/tests/server/basic.test.ripple +38 -40
  106. package/tests/server/composite.props.test.ripple +9 -9
  107. package/tests/server/dynamic-elements.test.ripple +13 -12
  108. package/tests/server/head.test.ripple +11 -11
  109. package/tests/server/lazy-destructuring.test.ripple +72 -0
  110. package/types/index.d.ts +7 -2
@@ -101,19 +101,19 @@ describe('for statements', () => {
101
101
 
102
102
  it('correctly handles keyed for...of loops', () => {
103
103
  component App() {
104
- let items = track([
104
+ let &[items] = track([
105
105
  { id: 1, text: 'Item 1' },
106
106
  { id: 2, text: 'Item 2' },
107
107
  { id: 3, text: 'Item 3' },
108
108
  ]);
109
109
 
110
- for (let item of @items; index i; key item.id) {
110
+ for (let item of items; index i; key item.id) {
111
111
  <div>{i + ':' + item.text}</div>
112
112
  }
113
113
 
114
114
  <button
115
115
  onClick={() => {
116
- @items = @items.toReversed();
116
+ items = items.toReversed();
117
117
  }}
118
118
  >
119
119
  {'Reverse'}
@@ -134,23 +134,23 @@ describe('for statements', () => {
134
134
 
135
135
  it('keyed for over derived updates sibling text nodes', () => {
136
136
  component App() {
137
- let count = track(0);
137
+ let &[count] = track(0);
138
138
 
139
- const items = track(
140
- () => Array.from({ length: @count }).map((_, id) => ({ id, label: `Item ${id}` })),
139
+ let &[items] = track(
140
+ () => Array.from({ length: count }).map((_, id) => ({ id, label: `Item ${id}` })),
141
141
  );
142
142
 
143
143
  <button
144
144
  onClick={() => {
145
- @count++;
145
+ count++;
146
146
  }}
147
147
  >
148
148
  {'Add'}
149
149
  </button>
150
- for (const item of @items; key item.id) {
150
+ for (const item of items; key item.id) {
151
151
  <div class="item">{item.label}</div>
152
152
  }
153
- <p class="count">{@count}</p>
153
+ <p class="count">{count}</p>
154
154
  }
155
155
 
156
156
  render(App);
@@ -175,17 +175,17 @@ describe('for statements', () => {
175
175
 
176
176
  it('keyed for with 32+ items: full reversal updates values via Map path', () => {
177
177
  component App() {
178
- let items = track(Array.from({ length: 40 }, (_, i) => ({ id: i, text: `Item ${i}` })));
178
+ let &[items] = track(Array.from({ length: 40 }, (_, i) => ({ id: i, text: `Item ${i}` })));
179
179
 
180
180
  <div>
181
- for (let item of @items; index idx; key item.id) {
181
+ for (let item of items; index idx; key item.id) {
182
182
  <span class="item">{idx + ':' + item.text}</span>
183
183
  }
184
184
  </div>
185
185
 
186
186
  <button
187
187
  onClick={() => {
188
- @items = @items.toReversed();
188
+ items = items.toReversed();
189
189
  }}
190
190
  >
191
191
  {'Reverse'}
@@ -208,26 +208,26 @@ describe('for statements', () => {
208
208
 
209
209
  it('handles updating with new objects with same key', () => {
210
210
  component App() {
211
- let items = track([
211
+ let &[items] = track([
212
212
  { id: 1, text: 'Item 1' },
213
213
  { id: 2, text: 'Item 2' },
214
214
  { id: 3, text: 'Item 3' },
215
215
  ]);
216
216
 
217
- for (let item of @items; index i; key item.id) {
217
+ for (let item of items; index i; key item.id) {
218
218
  <div>{i + ':' + item.text}</div>
219
219
  }
220
220
 
221
221
  <button
222
222
  onClick={() => {
223
- @items[0].id = 3;
224
- @items[1].id = 2;
225
- @items[2].id = 1;
226
-
227
- @items = [
228
- { ...@items[0], text: 'Item 1!' },
229
- { ...@items[1], text: 'Item 2!' },
230
- { ...@items[2], text: 'Item 3!' },
223
+ items[0].id = 3;
224
+ items[1].id = 2;
225
+ items[2].id = 1;
226
+
227
+ items = [
228
+ { ...items[0], text: 'Item 1!' },
229
+ { ...items[1], text: 'Item 2!' },
230
+ { ...items[2], text: 'Item 3!' },
231
231
  ];
232
232
  }}
233
233
  >
@@ -249,17 +249,17 @@ describe('for statements', () => {
249
249
  const objects = Array.from({ length: 50 }, (_, i) => ({ id: i, text: `Obj ${i}` }));
250
250
 
251
251
  component App() {
252
- let items = track(objects.slice());
252
+ let &[items] = track(objects.slice());
253
253
 
254
254
  <div>
255
- for (const item of @items) {
255
+ for (const item of items) {
256
256
  <span class="item">{item.text}</span>
257
257
  }
258
258
  </div>
259
259
 
260
260
  <button
261
261
  onClick={() => {
262
- @items = objects.slice(15).reverse();
262
+ items = objects.slice(15).reverse();
263
263
  }}
264
264
  >
265
265
  {'Trim and reverse'}
@@ -29,20 +29,20 @@ describe('head elements', () => {
29
29
 
30
30
  it('renders reactive title element', () => {
31
31
  component App() {
32
- let title = track('Initial Title');
32
+ let &[title] = track('Initial Title');
33
33
 
34
34
  <head>
35
- <title>{@title}</title>
35
+ <title>{title}</title>
36
36
  </head>
37
37
  <div>
38
38
  <button
39
39
  onClick={() => {
40
- @title = 'Updated Title';
40
+ title = 'Updated Title';
41
41
  }}
42
42
  >
43
43
  {'Update Title'}
44
44
  </button>
45
- <span>{@title}</span>
45
+ <span>{title}</span>
46
46
  </div>
47
47
  }
48
48
 
@@ -61,15 +61,15 @@ describe('head elements', () => {
61
61
 
62
62
  it('renders title with template literal', () => {
63
63
  component App() {
64
- let name = track('World');
64
+ let &[name] = track('World');
65
65
 
66
66
  <head>
67
- <title>{`Hello ${@name}!`}</title>
67
+ <title>{`Hello ${name}!`}</title>
68
68
  </head>
69
69
  <div>
70
70
  <button
71
71
  onClick={() => {
72
- @name = 'Ripple';
72
+ name = 'Ripple';
73
73
  }}
74
74
  >
75
75
  {'Change Name'}
@@ -90,21 +90,21 @@ describe('head elements', () => {
90
90
 
91
91
  it('renders title with computed value', () => {
92
92
  component App() {
93
- let count = track(0);
93
+ let &[count] = track(0);
94
94
  let prefix = 'Count: ';
95
95
 
96
96
  <head>
97
- <title>{prefix + @count}</title>
97
+ <title>{prefix + count}</title>
98
98
  </head>
99
99
  <div>
100
100
  <button
101
101
  onClick={() => {
102
- @count++;
102
+ count++;
103
103
  }}
104
104
  >
105
105
  {'Increment'}
106
106
  </button>
107
- <span>{@count}</span>
107
+ <span>{count}</span>
108
108
  </div>
109
109
  }
110
110
 
@@ -122,15 +122,15 @@ describe('head elements', () => {
122
122
 
123
123
  it('handles multiple title updates', () => {
124
124
  component App() {
125
- let step = track(1);
125
+ let &[step] = track(1);
126
126
 
127
127
  <head>
128
- <title>{`Step ${@step} of 3`}</title>
128
+ <title>{`Step ${step} of 3`}</title>
129
129
  </head>
130
130
  <div>
131
131
  <button
132
132
  onClick={() => {
133
- @step = @step % 3 + 1;
133
+ step = step % 3 + 1;
134
134
  }}
135
135
  >
136
136
  {'Next Step'}
@@ -172,23 +172,23 @@ describe('head elements', () => {
172
172
 
173
173
  it('renders title with conditional content', () => {
174
174
  component App() {
175
- let showPrefix = track(true);
176
- let title = track('Main Page');
175
+ let &[showPrefix] = track(true);
176
+ let &[title] = track('Main Page');
177
177
 
178
178
  <head>
179
- <title>{@showPrefix ? 'App - ' + @title : @title}</title>
179
+ <title>{showPrefix ? 'App - ' + title : title}</title>
180
180
  </head>
181
181
  <div>
182
182
  <button
183
183
  onClick={() => {
184
- @showPrefix = !@showPrefix;
184
+ showPrefix = !showPrefix;
185
185
  }}
186
186
  >
187
187
  {'Toggle Prefix'}
188
188
  </button>
189
189
  <button
190
190
  onClick={() => {
191
- @title = @title === 'Main Page' ? 'Settings' : 'Main Page';
191
+ title = title === 'Main Page' ? 'Settings' : 'Main Page';
192
192
  }}
193
193
  >
194
194
  {'Change Page'}
@@ -14,13 +14,13 @@ describe('html directive', () => {
14
14
 
15
15
  it('renders dynamic html', () => {
16
16
  component App() {
17
- let str = track('<div>Test</div>');
17
+ let &[str] = track('<div>Test</div>');
18
18
 
19
- {html @str}
19
+ {html str}
20
20
 
21
21
  <button
22
22
  onClick={() => {
23
- @str = '<div>Updated</div>';
23
+ str = '<div>Updated</div>';
24
24
  }}
25
25
  >
26
26
  {'Update'}