ripple 0.3.7 → 0.3.9

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 (119) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +2 -2
  3. package/src/compiler/phases/1-parse/index.js +48 -349
  4. package/src/compiler/phases/2-analyze/index.js +343 -52
  5. package/src/compiler/phases/3-transform/client/index.js +28 -160
  6. package/src/compiler/phases/3-transform/segments.js +0 -7
  7. package/src/compiler/phases/3-transform/server/index.js +31 -154
  8. package/src/compiler/types/acorn.d.ts +1 -1
  9. package/src/compiler/types/estree.d.ts +1 -1
  10. package/src/compiler/types/import.d.ts +0 -2
  11. package/src/compiler/types/index.d.ts +5 -17
  12. package/src/compiler/types/parse.d.ts +1 -17
  13. package/src/compiler/utils.js +53 -20
  14. package/src/runtime/index-client.js +2 -13
  15. package/src/runtime/index-server.js +2 -2
  16. package/src/runtime/internal/client/bindings.js +3 -1
  17. package/src/runtime/internal/client/composite.js +3 -2
  18. package/src/runtime/internal/client/events.js +1 -1
  19. package/src/runtime/internal/client/head.js +3 -4
  20. package/src/runtime/internal/client/index.js +0 -1
  21. package/src/runtime/internal/client/runtime.js +0 -52
  22. package/src/runtime/internal/server/index.js +31 -55
  23. package/tests/client/array/array.copy-within.test.ripple +12 -12
  24. package/tests/client/array/array.derived.test.ripple +46 -46
  25. package/tests/client/array/array.iteration.test.ripple +10 -10
  26. package/tests/client/array/array.mutations.test.ripple +20 -20
  27. package/tests/client/array/array.to-methods.test.ripple +6 -6
  28. package/tests/client/async-suspend.test.ripple +5 -5
  29. package/tests/client/basic/basic.attributes.test.ripple +81 -81
  30. package/tests/client/basic/basic.collections.test.ripple +9 -9
  31. package/tests/client/basic/basic.components.test.ripple +28 -28
  32. package/tests/client/basic/basic.errors.test.ripple +46 -18
  33. package/tests/client/basic/basic.events.test.ripple +37 -37
  34. package/tests/client/basic/basic.get-set.test.ripple +6 -6
  35. package/tests/client/basic/basic.reactivity.test.ripple +58 -203
  36. package/tests/client/basic/basic.rendering.test.ripple +19 -19
  37. package/tests/client/basic/basic.utilities.test.ripple +3 -3
  38. package/tests/client/boundaries.test.ripple +12 -12
  39. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
  40. package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
  41. package/tests/client/compiler/compiler.basic.test.ripple +46 -27
  42. package/tests/client/compiler/compiler.tracked-access.test.ripple +2 -2
  43. package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
  44. package/tests/client/composite/composite.props.test.ripple +14 -16
  45. package/tests/client/composite/composite.reactivity.test.ripple +69 -70
  46. package/tests/client/composite/composite.render.test.ripple +3 -3
  47. package/tests/client/computed-properties.test.ripple +4 -4
  48. package/tests/client/date.test.ripple +42 -42
  49. package/tests/client/dynamic-elements.test.ripple +44 -45
  50. package/tests/client/events.test.ripple +70 -70
  51. package/tests/client/for.test.ripple +25 -25
  52. package/tests/client/head.test.ripple +19 -19
  53. package/tests/client/html.test.ripple +3 -3
  54. package/tests/client/input-value.test.ripple +84 -84
  55. package/tests/client/lazy-destructuring.test.ripple +138 -26
  56. package/tests/client/map.test.ripple +16 -16
  57. package/tests/client/media-query.test.ripple +7 -7
  58. package/tests/client/portal.test.ripple +11 -11
  59. package/tests/client/ref.test.ripple +4 -4
  60. package/tests/client/return.test.ripple +52 -52
  61. package/tests/client/set.test.ripple +6 -6
  62. package/tests/client/svg.test.ripple +5 -5
  63. package/tests/client/switch.test.ripple +44 -44
  64. package/tests/client/try.test.ripple +5 -5
  65. package/tests/client/url/url.derived.test.ripple +6 -6
  66. package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
  67. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
  68. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
  69. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
  70. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
  71. package/tests/hydration/compiled/client/events.js +25 -25
  72. package/tests/hydration/compiled/client/for.js +70 -66
  73. package/tests/hydration/compiled/client/head.js +25 -25
  74. package/tests/hydration/compiled/client/hmr.js +2 -2
  75. package/tests/hydration/compiled/client/html.js +3 -3
  76. package/tests/hydration/compiled/client/if-children.js +24 -24
  77. package/tests/hydration/compiled/client/if.js +18 -18
  78. package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
  79. package/tests/hydration/compiled/client/portal.js +3 -3
  80. package/tests/hydration/compiled/client/reactivity.js +16 -16
  81. package/tests/hydration/compiled/client/return.js +40 -40
  82. package/tests/hydration/compiled/client/switch.js +12 -12
  83. package/tests/hydration/compiled/server/events.js +19 -19
  84. package/tests/hydration/compiled/server/for.js +41 -41
  85. package/tests/hydration/compiled/server/head.js +26 -26
  86. package/tests/hydration/compiled/server/hmr.js +2 -2
  87. package/tests/hydration/compiled/server/html.js +2 -2
  88. package/tests/hydration/compiled/server/if-children.js +16 -16
  89. package/tests/hydration/compiled/server/if.js +11 -11
  90. package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
  91. package/tests/hydration/compiled/server/portal.js +2 -2
  92. package/tests/hydration/compiled/server/reactivity.js +16 -16
  93. package/tests/hydration/compiled/server/return.js +25 -25
  94. package/tests/hydration/compiled/server/switch.js +8 -8
  95. package/tests/hydration/components/events.ripple +25 -25
  96. package/tests/hydration/components/for.ripple +66 -66
  97. package/tests/hydration/components/head.ripple +16 -16
  98. package/tests/hydration/components/hmr.ripple +2 -2
  99. package/tests/hydration/components/html.ripple +3 -3
  100. package/tests/hydration/components/if-children.ripple +24 -24
  101. package/tests/hydration/components/if.ripple +18 -18
  102. package/tests/hydration/components/mixed-control-flow.ripple +9 -9
  103. package/tests/hydration/components/portal.ripple +3 -3
  104. package/tests/hydration/components/reactivity.ripple +16 -16
  105. package/tests/hydration/components/return.ripple +40 -40
  106. package/tests/hydration/components/switch.ripple +20 -20
  107. package/tests/server/await.test.ripple +3 -3
  108. package/tests/server/basic.attributes.test.ripple +34 -34
  109. package/tests/server/basic.components.test.ripple +10 -10
  110. package/tests/server/basic.test.ripple +38 -40
  111. package/tests/server/compiler.test.ripple +22 -0
  112. package/tests/server/composite.props.test.ripple +12 -14
  113. package/tests/server/dynamic-elements.test.ripple +15 -15
  114. package/tests/server/head.test.ripple +11 -11
  115. package/tests/server/lazy-destructuring.test.ripple +92 -13
  116. package/tsconfig.typecheck.json +4 -0
  117. package/types/index.d.ts +0 -19
  118. package/tests/client/__snapshots__/tracked-expression.test.ripple.snap +0 -34
  119. package/tests/client/tracked-expression.test.ripple +0 -26
@@ -4,22 +4,22 @@ import { compile } from 'ripple/compiler';
4
4
  describe('basic client > errors', () => {
5
5
  it('renders with error handling simulation', () => {
6
6
  component Basic() {
7
- let hasError = track(false);
8
- let errorMessage = track('');
7
+ let &[hasError] = track(false);
8
+ let &[errorMessage] = track('');
9
9
 
10
10
  const triggerError = () => {
11
11
  try {
12
12
  throw new Error('Test error');
13
13
  } catch (e) {
14
- @hasError = true;
15
- @errorMessage = (e as Error).message;
14
+ hasError = true;
15
+ errorMessage = (e as Error).message;
16
16
  }
17
17
  };
18
18
 
19
19
  <div>
20
20
  <button onClick={triggerError}>{'Trigger Error'}</button>
21
- if (@hasError) {
22
- <div class="error">{'Error caught: ' + @errorMessage}</div>
21
+ if (hasError) {
22
+ <div class="error">{'Error caught: ' + errorMessage}</div>
23
23
  } else {
24
24
  <div class="success">{'No error'}</div>
25
25
  }
@@ -89,19 +89,47 @@ describe('basic client > errors', () => {
89
89
  );
90
90
  });
91
91
 
92
+ it('should throw error for calling children as a function', () => {
93
+ const code = `
94
+ export component Layout({ children }) {
95
+ {children()}
96
+ }
97
+ `;
98
+
99
+ expect(() => {
100
+ compile(code, 'test.ripple');
101
+ }).toThrow(
102
+ '`children` cannot be called like a regular function. Use element syntax instead, e.g. `<children />` or `<props.children />`.',
103
+ );
104
+ });
105
+
106
+ it('should throw error for calling props.children as a function', () => {
107
+ const code = `
108
+ export component Layout(props) {
109
+ {props.children()}
110
+ }
111
+ `;
112
+
113
+ expect(() => {
114
+ compile(code, 'test.ripple');
115
+ }).toThrow(
116
+ '`children` cannot be called like a regular function. Use element syntax instead, e.g. `<children />` or `<props.children />`.',
117
+ );
118
+ });
119
+
92
120
  it('errors on mutating tracked value inside computed track() evaluation', () => {
93
121
  component Basic() {
94
- let count = track(0);
122
+ let &[count] = track(0);
95
123
 
96
- const doubled = track(() => {
124
+ const &[doubled] = track(() => {
97
125
  try {
98
- @count *= 2;
126
+ count *= 2;
99
127
  } catch (e) {
100
128
  error = (e as Error).message;
101
129
  }
102
130
  });
103
131
 
104
- <p>{@doubled}</p>
132
+ <p>{doubled}</p>
105
133
  }
106
134
 
107
135
  render(Basic);
@@ -113,19 +141,19 @@ describe('basic client > errors', () => {
113
141
 
114
142
  it('errors on mutating tracked value inside untrack() in computed track() evaluation', () => {
115
143
  component Basic() {
116
- let count = track(0);
144
+ let &[count] = track(0);
117
145
 
118
- const doubled = track(() => {
146
+ const &[doubled] = track(() => {
119
147
  try {
120
148
  untrack(() => {
121
- @count *= 2;
149
+ count *= 2;
122
150
  });
123
151
  } catch (e) {
124
152
  error = (e as Error).message;
125
153
  }
126
154
  });
127
155
 
128
- <p>{@doubled}</p>
156
+ <p>{doubled}</p>
129
157
  }
130
158
 
131
159
  render(Basic);
@@ -137,18 +165,18 @@ describe('basic client > errors', () => {
137
165
 
138
166
  it('errors on mutating a tracked variable in track() getter', () => {
139
167
  component Basic() {
140
- let count = track(0);
168
+ let &[count] = track(0);
141
169
 
142
- const doubled = track(0, (value) => {
170
+ const &[doubled] = track(0, (value) => {
143
171
  try {
144
- @count += 1;
172
+ count += 1;
145
173
  } catch (e) {
146
174
  error = (e as Error).message;
147
175
  }
148
176
  return value;
149
177
  });
150
178
 
151
- <p>{@doubled}</p>
179
+ <p>{doubled}</p>
152
180
  }
153
181
 
154
182
  render(Basic);
@@ -4,21 +4,21 @@ import { flushSync, track } from 'ripple';
4
4
  describe('basic client > events', () => {
5
5
  it('renders with different event types', () => {
6
6
  component Basic() {
7
- let focusCount = track(0);
8
- let clickCount = track(0);
7
+ let &[focusCount] = track(0);
8
+ let &[clickCount] = track(0);
9
9
 
10
10
  <button
11
11
  onFocus={() => {
12
- @focusCount++;
12
+ focusCount++;
13
13
  }}
14
14
  onClick={() => {
15
- @clickCount++;
15
+ clickCount++;
16
16
  }}
17
17
  >
18
18
  {'Test Button'}
19
19
  </button>
20
- <div class="focus-count">{@focusCount}</div>
21
- <div class="click-count">{@clickCount}</div>
20
+ <div class="focus-count">{focusCount}</div>
21
+ <div class="click-count">{clickCount}</div>
22
22
  }
23
23
 
24
24
  render(Basic);
@@ -38,26 +38,26 @@ describe('basic client > events', () => {
38
38
 
39
39
  it('renders with capture events', () => {
40
40
  component Basic() {
41
- let captureClicks = track(0);
42
- let bubbleClicks = track(0);
41
+ let &[captureClicks] = track(0);
42
+ let &[bubbleClicks] = track(0);
43
43
 
44
44
  <div
45
45
  onClick={{
46
46
  handleEvent: () => {
47
- @captureClicks++;
47
+ captureClicks++;
48
48
  },
49
49
  capture: true,
50
50
  }}
51
51
  >
52
52
  <button
53
53
  onClick={() => {
54
- @bubbleClicks++;
54
+ bubbleClicks++;
55
55
  }}
56
56
  >
57
57
  {'Click me'}
58
58
  </button>
59
- <div class="capture-count">{@captureClicks}</div>
60
- <div class="bubble-count">{@bubbleClicks}</div>
59
+ <div class="capture-count">{captureClicks}</div>
60
+ <div class="bubble-count">{bubbleClicks}</div>
61
61
  </div>
62
62
  }
63
63
 
@@ -76,23 +76,23 @@ describe('basic client > events', () => {
76
76
 
77
77
  it('renders with event listeners in spread props', () => {
78
78
  component Basic() {
79
- let count = track(0);
79
+ let &[count] = track(0);
80
80
 
81
81
  const minus = {
82
82
  onClick() {
83
- @count--;
83
+ count--;
84
84
  },
85
85
  };
86
86
 
87
87
  const plus = {
88
88
  onClick() {
89
- @count++;
89
+ count++;
90
90
  },
91
91
  };
92
92
 
93
93
  <div>
94
94
  <button {...minus} class="minus">{'-'}</button>
95
- <span class="count">{@count}</span>
95
+ <span class="count">{count}</span>
96
96
  <button {...plus} class="plus">{'+'}</button>
97
97
  </div>
98
98
  }
@@ -125,24 +125,24 @@ describe('basic client > events', () => {
125
125
 
126
126
  it('handles both delegated and non-delegated events in spread props', () => {
127
127
  component Basic() {
128
- let clickCount = track(0);
129
- let focusCount = track(0);
128
+ let &[clickCount] = track(0);
129
+ let &[focusCount] = track(0);
130
130
 
131
131
  const mixedHandler = {
132
132
  onClick() {
133
133
  // Delegated event
134
- @clickCount++;
134
+ clickCount++;
135
135
  },
136
136
  onFocus() {
137
137
  // Non-delegated event
138
- @focusCount++;
138
+ focusCount++;
139
139
  },
140
140
  };
141
141
 
142
142
  <div>
143
143
  <button {...mixedHandler} class="mixed-button">{'Test'}</button>
144
- <span class="click-count">{@clickCount}</span>
145
- <span class="focus-count">{@focusCount}</span>
144
+ <span class="click-count">{clickCount}</span>
145
+ <span class="focus-count">{focusCount}</span>
146
146
  </div>
147
147
  }
148
148
 
@@ -168,31 +168,31 @@ describe('basic client > events', () => {
168
168
 
169
169
  it('renders with complex event handling and state updates', () => {
170
170
  component Basic() {
171
- let counter = track(0);
172
- let history = track<string[]>([]);
173
- let isEven = track(true);
171
+ let &[counter] = track(0);
172
+ let &[history] = track<string[]>([]);
173
+ let &[isEven] = track(true);
174
174
 
175
175
  const handleIncrement = () => {
176
- @counter++;
177
- @history = [...@history, `Inc to ${@counter}`];
178
- @isEven = @counter % 2 === 0;
176
+ counter++;
177
+ history = [...history, `Inc to ${counter}`];
178
+ isEven = counter % 2 === 0;
179
179
  };
180
180
 
181
181
  const handleDecrement = () => {
182
- @counter--;
183
- @history = [...@history, `Dec to ${@counter}`];
184
- @isEven = @counter % 2 === 0;
182
+ counter--;
183
+ history = [...history, `Dec to ${counter}`];
184
+ isEven = counter % 2 === 0;
185
185
  };
186
186
 
187
187
  const handleReset = () => {
188
- @counter = 0;
189
- @history = [...@history, 'Reset'];
190
- @isEven = true;
188
+ counter = 0;
189
+ history = [...history, 'Reset'];
190
+ isEven = true;
191
191
  };
192
192
 
193
- <div class="counter">{@counter}</div>
194
- <div class="parity">{@isEven ? 'Even' : 'Odd'}</div>
195
- <div class="history-count">{@history.length}</div>
193
+ <div class="counter">{counter}</div>
194
+ <div class="parity">{isEven ? 'Even' : 'Odd'}</div>
195
+ <div class="history-count">{history.length}</div>
196
196
 
197
197
  <button class="inc-btn" onClick={handleIncrement}>{'+'}</button>
198
198
  <button class="dec-btn" onClick={handleDecrement}>{'-'}</button>
@@ -16,10 +16,10 @@ describe('basic client > get/set functions', () => {
16
16
 
17
17
  it('gets tracked value after mutation', () => {
18
18
  component Test() {
19
- let count = track(0);
19
+ let &[count] = track(0);
20
20
 
21
21
  <p>{get(count)}</p>
22
- <button onClick={() => @count++}>{'increment'}</button>
22
+ <button onClick={() => count++}>{'increment'}</button>
23
23
  }
24
24
 
25
25
  render(Test);
@@ -36,14 +36,14 @@ describe('basic client > get/set functions', () => {
36
36
 
37
37
  it('gets tracked value after multiple mutations', () => {
38
38
  component Test() {
39
- let count = track(0);
39
+ let &[count] = track(0);
40
40
 
41
41
  <p>{get(count)}</p>
42
42
  <button
43
43
  onClick={() => {
44
- @count++;
45
- @count++;
46
- @count++;
44
+ count++;
45
+ count++;
46
+ count++;
47
47
  }}
48
48
  >
49
49
  {'increment'}