ripple 0.3.3 → 0.3.4

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 (126) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/package.json +2 -2
  3. package/src/compiler/identifier-utils.js +1 -8
  4. package/src/compiler/phases/1-parse/index.js +101 -195
  5. package/src/compiler/phases/2-analyze/index.js +82 -174
  6. package/src/compiler/phases/2-analyze/prune.js +2 -2
  7. package/src/compiler/phases/3-transform/client/index.js +169 -261
  8. package/src/compiler/phases/3-transform/server/index.js +185 -42
  9. package/src/compiler/types/index.d.ts +14 -33
  10. package/src/compiler/utils.js +32 -20
  11. package/src/runtime/index-client.js +0 -17
  12. package/src/runtime/internal/client/bindings.js +118 -7
  13. package/src/runtime/internal/client/render.js +5 -1
  14. package/src/runtime/internal/client/runtime.js +1 -1
  15. package/src/runtime/internal/client/types.d.ts +4 -0
  16. package/tests/client/array/array.copy-within.test.ripple +7 -7
  17. package/tests/client/array/array.derived.test.ripple +24 -24
  18. package/tests/client/array/array.iteration.test.ripple +7 -7
  19. package/tests/client/array/array.mutations.test.ripple +17 -17
  20. package/tests/client/array/array.to-methods.test.ripple +4 -4
  21. package/tests/client/async-suspend.test.ripple +3 -3
  22. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  23. package/tests/client/basic/basic.collections.test.ripple +6 -6
  24. package/tests/client/basic/basic.components.test.ripple +8 -8
  25. package/tests/client/basic/basic.errors.test.ripple +31 -34
  26. package/tests/client/basic/basic.events.test.ripple +11 -11
  27. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  28. package/tests/client/basic/basic.reactivity.test.ripple +36 -36
  29. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  30. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  31. package/tests/client/boundaries.test.ripple +7 -7
  32. package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +24 -0
  33. package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
  34. package/tests/client/compiler/compiler.basic.test.ripple +57 -58
  35. package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
  36. package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
  37. package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
  38. package/tests/client/composite/composite.props.test.ripple +9 -9
  39. package/tests/client/composite/composite.reactivity.test.ripple +23 -23
  40. package/tests/client/composite/composite.render.test.ripple +52 -4
  41. package/tests/client/computed-properties.test.ripple +3 -3
  42. package/tests/client/context.test.ripple +3 -3
  43. package/tests/client/css/global-additional-cases.test.ripple +5 -2
  44. package/tests/client/css/style-identifier.test.ripple +40 -49
  45. package/tests/client/date.test.ripple +39 -39
  46. package/tests/client/dynamic-elements.test.ripple +37 -37
  47. package/tests/client/events.test.ripple +25 -25
  48. package/tests/client/for.test.ripple +8 -8
  49. package/tests/client/head.test.ripple +7 -7
  50. package/tests/client/html.test.ripple +2 -2
  51. package/tests/client/input-value.test.ripple +376 -177
  52. package/tests/client/lazy-destructuring.test.ripple +185 -0
  53. package/tests/client/map.test.ripple +20 -20
  54. package/tests/client/media-query.test.ripple +4 -4
  55. package/tests/client/object.test.ripple +5 -5
  56. package/tests/client/portal.test.ripple +4 -4
  57. package/tests/client/ref.test.ripple +3 -3
  58. package/tests/client/return.test.ripple +17 -17
  59. package/tests/client/set.test.ripple +10 -10
  60. package/tests/client/svg.test.ripple +6 -5
  61. package/tests/client/switch.test.ripple +10 -10
  62. package/tests/client/tracked-expression.test.ripple +3 -1
  63. package/tests/client/try.test.ripple +4 -4
  64. package/tests/client/url/url.derived.test.ripple +6 -7
  65. package/tests/client/url/url.parsing.test.ripple +9 -9
  66. package/tests/client/url/url.partial-removal.test.ripple +9 -9
  67. package/tests/client/url/url.reactivity.test.ripple +16 -16
  68. package/tests/client/url/url.serialization.test.ripple +3 -3
  69. package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
  70. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
  71. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
  72. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
  73. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
  74. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
  75. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
  76. package/tests/hydration/build-components.js +4 -10
  77. package/tests/hydration/compiled/client/basic.js +4 -4
  78. package/tests/hydration/compiled/client/events.js +2 -0
  79. package/tests/hydration/compiled/client/for.js +2 -0
  80. package/tests/hydration/compiled/client/head.js +13 -11
  81. package/tests/hydration/compiled/client/hmr.js +4 -2
  82. package/tests/hydration/compiled/client/html.js +82 -95
  83. package/tests/hydration/compiled/client/if-children.js +8 -9
  84. package/tests/hydration/compiled/client/if.js +2 -0
  85. package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
  86. package/tests/hydration/compiled/client/portal.js +1 -1
  87. package/tests/hydration/compiled/client/reactivity.js +2 -0
  88. package/tests/hydration/compiled/client/return.js +2 -0
  89. package/tests/hydration/compiled/client/switch.js +2 -0
  90. package/tests/hydration/compiled/server/composite.js +2 -2
  91. package/tests/hydration/compiled/server/events.js +2 -0
  92. package/tests/hydration/compiled/server/for.js +2 -0
  93. package/tests/hydration/compiled/server/head.js +13 -11
  94. package/tests/hydration/compiled/server/hmr.js +2 -0
  95. package/tests/hydration/compiled/server/html.js +2 -0
  96. package/tests/hydration/compiled/server/if-children.js +2 -0
  97. package/tests/hydration/compiled/server/if.js +2 -0
  98. package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
  99. package/tests/hydration/compiled/server/portal.js +1 -1
  100. package/tests/hydration/compiled/server/reactivity.js +2 -0
  101. package/tests/hydration/compiled/server/return.js +2 -0
  102. package/tests/hydration/compiled/server/switch.js +2 -0
  103. package/tests/hydration/components/composite.ripple +1 -1
  104. package/tests/hydration/components/events.ripple +10 -8
  105. package/tests/hydration/components/for.ripple +22 -20
  106. package/tests/hydration/components/head.ripple +8 -6
  107. package/tests/hydration/components/hmr.ripple +3 -1
  108. package/tests/hydration/components/html.ripple +3 -1
  109. package/tests/hydration/components/if-children.ripple +9 -7
  110. package/tests/hydration/components/if.ripple +7 -5
  111. package/tests/hydration/components/mixed-control-flow.ripple +5 -3
  112. package/tests/hydration/components/portal.ripple +2 -2
  113. package/tests/hydration/components/reactivity.ripple +11 -9
  114. package/tests/hydration/components/return.ripple +13 -11
  115. package/tests/hydration/components/switch.ripple +6 -4
  116. package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
  117. package/tests/server/await.test.ripple +2 -2
  118. package/tests/server/basic.attributes.test.ripple +21 -19
  119. package/tests/server/basic.components.test.ripple +5 -4
  120. package/tests/server/basic.test.ripple +21 -20
  121. package/tests/server/compiler.test.ripple +36 -5
  122. package/tests/server/composite.props.test.ripple +7 -6
  123. package/tests/server/context.test.ripple +3 -1
  124. package/tests/server/dynamic-elements.test.ripple +24 -24
  125. package/tests/server/head.test.ripple +7 -5
  126. package/tests/server/style-identifier.test.ripple +95 -16
@@ -1,3 +1,5 @@
1
+ import { track } from 'ripple';
2
+
1
3
  export component MixedControlFlowStatic() {
2
4
  const rows = [
3
5
  { id: 1, kind: 'a', enabled: true },
@@ -29,9 +31,9 @@ export component MixedControlFlowStatic() {
29
31
  }
30
32
 
31
33
  export component MixedControlFlowReactive() {
32
- let show = #ripple.track(true);
33
- let mode = #ripple.track<'a' | 'b'>('a');
34
- let items = #ripple.track([
34
+ let show = track(true);
35
+ let mode = track<'a' | 'b'>('a');
36
+ let items = track([
35
37
  { id: 1, label: 'One' },
36
38
  { id: 2, label: 'Two' },
37
39
  ]);
@@ -1,5 +1,5 @@
1
1
  // Portal components for hydration testing
2
- import { Portal } from 'ripple';
2
+ import { Portal, track } from 'ripple';
3
3
 
4
4
  // Simple portal with static content
5
5
  export component SimplePortal() {
@@ -13,7 +13,7 @@ export component SimplePortal() {
13
13
 
14
14
  // Portal with conditional rendering
15
15
  export component ConditionalPortal() {
16
- let show = #ripple.track(true);
16
+ let show = track(true);
17
17
 
18
18
  <div class="container">
19
19
  <button class="toggle" onClick={() => (@show = !@show)}>{'Toggle'}</button>
@@ -1,12 +1,14 @@
1
+ import { track } from 'ripple';
2
+
1
3
  // Reactive components for hydration testing
2
4
 
3
5
  export component TrackedState() {
4
- let count = #ripple.track(0);
6
+ let count = track(0);
5
7
  <div class="count">{@count}</div>
6
8
  }
7
9
 
8
10
  export component CounterWithInitial(props: { initial: number }) {
9
- let count = #ripple.track(props.initial);
11
+ let count = track(props.initial);
10
12
  <div>
11
13
  <span class="count">{@count}</span>
12
14
  </div>
@@ -17,24 +19,24 @@ export component CounterWrapper() {
17
19
  }
18
20
 
19
21
  export component ComputedValues() {
20
- let a = #ripple.track(2);
21
- let b = #ripple.track(3);
22
+ let a = track(2);
23
+ let b = track(3);
22
24
  const sum = () => @a + @b;
23
25
  <div class="sum">{sum()}</div>
24
26
  }
25
27
 
26
28
  export component MultipleTracked() {
27
- let x = #ripple.track(10);
28
- let y = #ripple.track(20);
29
- let z = #ripple.track(30);
29
+ let x = track(10);
30
+ let y = track(20);
31
+ let z = track(30);
30
32
  <div class="x">{@x}</div>
31
33
  <div class="y">{@y}</div>
32
34
  <div class="z">{@z}</div>
33
35
  }
34
36
 
35
37
  export component DerivedState() {
36
- let firstName = #ripple.track('John');
37
- let lastName = #ripple.track('Doe');
38
+ let firstName = track('John');
39
+ let lastName = track('Doe');
38
40
  const fullName = () => `${@firstName} ${@lastName}`;
39
41
  <div class="name">{fullName()}</div>
40
42
  }
@@ -1,3 +1,5 @@
1
+ import { track } from 'ripple';
2
+
1
3
  // Return statement components for hydration testing
2
4
 
3
5
  // Basic return - skips content after direct return
@@ -264,7 +266,7 @@ export component ReturnWithElseBothReturn() {
264
266
 
265
267
  // Reactive return - starts true, can toggle to false
266
268
  export component ReactiveReturnTrueToFalse() {
267
- let condition = #ripple.track(true);
269
+ let condition = track(true);
268
270
 
269
271
  <button
270
272
  class="toggle"
@@ -283,7 +285,7 @@ export component ReactiveReturnTrueToFalse() {
283
285
 
284
286
  // Reactive return - starts false, can toggle to true
285
287
  export component ReactiveReturnFalseToTrue() {
286
- let condition = #ripple.track(false);
288
+ let condition = track(false);
287
289
 
288
290
  <button
289
291
  class="toggle"
@@ -303,7 +305,7 @@ export component ReactiveReturnFalseToTrue() {
303
305
  // Reactive nested return - only inner condition (b) is tracked
304
306
  export component ReactiveNestedReturn() {
305
307
  let a = true;
306
- let b = #ripple.track(true);
308
+ let b = track(true);
307
309
 
308
310
  <button
309
311
  class="toggle"
@@ -396,7 +398,7 @@ export component MultipleSiblingReturns() {
396
398
 
397
399
  // Reactive sibling returns - cycles first -> second -> fallback
398
400
  export component ReactiveSiblingReturns() {
399
- let mode = #ripple.track('first');
401
+ let mode = track('first');
400
402
 
401
403
  <button
402
404
  class="toggle"
@@ -428,8 +430,8 @@ export component ReactiveSiblingReturns() {
428
430
 
429
431
  // Reactive nested returns with tracked outer and inner conditions
430
432
  export component ReactiveOuterInnerReturns() {
431
- let a = #ripple.track(true);
432
- let b = #ripple.track(true);
433
+ let a = track(true);
434
+ let b = track(true);
433
435
 
434
436
  <button
435
437
  class="toggle-a"
@@ -462,7 +464,7 @@ export component ReactiveOuterInnerReturns() {
462
464
 
463
465
  // Reactive else-if return chain that transitions between return and non-return states
464
466
  export component ReactiveElseIfReturns() {
465
- let status = #ripple.track(0);
467
+ let status = track(0);
466
468
 
467
469
  <button
468
470
  class="toggle"
@@ -487,10 +489,10 @@ export component ReactiveElseIfReturns() {
487
489
 
488
490
  // Deeply nested independent return guards with multiple root-level siblings
489
491
  export component ReactiveDeepNestedIndependentReturns() {
490
- let c1 = #ripple.track(false);
491
- let c2 = #ripple.track(false);
492
- let c3 = #ripple.track(false);
493
- let c4 = #ripple.track(false);
492
+ let c1 = track(false);
493
+ let c2 = track(false);
494
+ let c3 = track(false);
495
+ let c4 = track(false);
494
496
 
495
497
  <button
496
498
  class="toggle-c1"
@@ -1,3 +1,5 @@
1
+ import { track } from 'ripple';
2
+
1
3
  export component SwitchStatic() {
2
4
  const status: string = 'success';
3
5
  switch (status) {
@@ -13,7 +15,7 @@ export component SwitchStatic() {
13
15
  }
14
16
 
15
17
  export component SwitchReactive() {
16
- let status = #ripple.track<'a' | 'b' | 'c'>('a');
18
+ let status = track<'a' | 'b' | 'c'>('a');
17
19
  <button
18
20
  class="toggle"
19
21
  onClick={() => {
@@ -49,7 +51,7 @@ export component SwitchFallthrough() {
49
51
  }
50
52
 
51
53
  export component SwitchNumericLevels() {
52
- let level = #ripple.track<1 | 2 | 3>(1);
54
+ let level = track<1 | 2 | 3>(1);
53
55
  <button
54
56
  class="level-toggle"
55
57
  onClick={() => {
@@ -74,7 +76,7 @@ export component SwitchNumericLevels() {
74
76
  }
75
77
 
76
78
  export component SwitchBlockScoped() {
77
- let level = #ripple.track<1 | 2 | 3>(1);
79
+ let level = track<1 | 2 | 3>(1);
78
80
  <button
79
81
  class="block-toggle"
80
82
  onClick={() => {
@@ -102,7 +104,7 @@ export component SwitchBlockScoped() {
102
104
  }
103
105
 
104
106
  export component SwitchNoBreak() {
105
- let level = #ripple.track<1 | 2 | 3>(1);
107
+ let level = track<1 | 2 | 3>(1);
106
108
  <button
107
109
  class="nobreak-toggle"
108
110
  onClick={() => {
@@ -96,6 +96,28 @@ export async function App(__output) {
96
96
  App.async = true;"
97
97
  `;
98
98
 
99
+ exports[`compiler typescript tests > removes class TypeScript syntax from JS output 1`] = `
100
+ "import * as _$_ from 'ripple/internal/server';
101
+
102
+ class PrintEvent {
103
+ text;
104
+
105
+ constructor(text) {
106
+ this.text = text;
107
+ }
108
+ }"
109
+ `;
110
+
111
+ exports[`compiler typescript tests > removes class extends type arguments from JS output 1`] = `
112
+ "import * as _$_ from 'ripple/internal/server';
113
+
114
+ class StringMap extends Map {
115
+ constructor() {
116
+ super();
117
+ }
118
+ }"
119
+ `;
120
+
99
121
  exports[`compiler typescript tests > removes type assertions from function parameters and leaves default values 1`] = `
100
122
  "import * as _$_ from 'ripple/internal/server';
101
123
 
@@ -1,4 +1,4 @@
1
- import { set, get } from 'ripple';
1
+ import { get, set, track } from 'ripple';
2
2
 
3
3
  describe('await in control flow', () => {
4
4
  it('all tests are commented out for now as await in control flow is not yet supported', () => {
@@ -8,7 +8,7 @@ describe('await in control flow', () => {
8
8
  // it('should handle await inside if statement', async () => {
9
9
  // component App() {
10
10
  // let condition = true;
11
- // let data = #ripple.track('loading');
11
+ // let data = track('loading');
12
12
 
13
13
  // if (condition) {
14
14
  // await new Promise((resolve) => setTimeout(() => {
@@ -1,3 +1,5 @@
1
+ import { RippleObject, track } from 'ripple';
2
+
1
3
  describe('basic server > attribute rendering', () => {
2
4
  it('render static attributes', async () => {
3
5
  component Basic() {
@@ -17,7 +19,7 @@ describe('basic server > attribute rendering', () => {
17
19
 
18
20
  it('render dynamic class attribute', async () => {
19
21
  component Basic() {
20
- let active = #ripple.track(false);
22
+ let active = track(false);
21
23
 
22
24
  <div class={@active ? 'active' : 'inactive'}>{'Dynamic Class'}</div>
23
25
 
@@ -87,7 +89,7 @@ describe('basic server > attribute rendering', () => {
87
89
 
88
90
  it('render dynamic class object', async () => {
89
91
  component Basic() {
90
- let active = #ripple.track(false);
92
+ let active = track(false);
91
93
 
92
94
  <div class={{ active: @active, inactive: !@active }}>{'Dynamic Class'}</div>
93
95
 
@@ -114,7 +116,7 @@ describe('basic server > attribute rendering', () => {
114
116
  'applies scoped ripple class to multiple elements with dynamic class expressions',
115
117
  async () => {
116
118
  component Basic() {
117
- let selected = #ripple.track(1);
119
+ let selected = track(1);
118
120
 
119
121
  <div class={@selected === 0 ? 'selected' : ''}>{`div 1`}</div>
120
122
  <div class={@selected === 0 ? 'selected' : ''}>{`div 2`}</div>
@@ -145,7 +147,7 @@ describe('basic server > attribute rendering', () => {
145
147
 
146
148
  it('render dynamic id attribute', async () => {
147
149
  component Basic() {
148
- let count = #ripple.track(0);
150
+ let count = track(0);
149
151
 
150
152
  <div id={`item-${@count}`}>{'Dynamic ID'}</div>
151
153
  }
@@ -160,7 +162,7 @@ describe('basic server > attribute rendering', () => {
160
162
 
161
163
  it('render dynamic style attribute', async () => {
162
164
  component Basic() {
163
- let color = #ripple.track('red');
165
+ let color = track('red');
164
166
 
165
167
  <div style={`color: ${@color}; font-weight: bold;`}>{'Dynamic Style'}</div>
166
168
  }
@@ -176,7 +178,7 @@ describe('basic server > attribute rendering', () => {
176
178
 
177
179
  it('render style attribute as dynamic object', async () => {
178
180
  component Basic() {
179
- let color = #ripple.track('red');
181
+ let color = track('red');
180
182
 
181
183
  <div style={{ color: @color, fontWeight: 'bold' }}>{'Dynamic Style'}</div>
182
184
  }
@@ -192,7 +194,7 @@ describe('basic server > attribute rendering', () => {
192
194
 
193
195
  it('render tracked variable as style attribute', async () => {
194
196
  component Basic() {
195
- let style = #ripple.track({ color: 'red', fontWeight: 'bold' });
197
+ let style = track({ color: 'red', fontWeight: 'bold' });
196
198
 
197
199
  <div {@style}>{'Dynamic Style'}</div>
198
200
  }
@@ -208,7 +210,7 @@ describe('basic server > attribute rendering', () => {
208
210
 
209
211
  it('render tracked object as style attribute', async () => {
210
212
  component Basic() {
211
- let style = #ripple{ color: 'red', fontWeight: 'bold' };
213
+ let style = new RippleObject({ color: 'red', fontWeight: 'bold' });
212
214
 
213
215
  <div style={{ color: style.color, fontWeight: style.fontWeight }}>{'Dynamic Style'}</div>
214
216
  }
@@ -275,8 +277,8 @@ describe('basic server > attribute rendering', () => {
275
277
 
276
278
  it('render dynamic boolean attributes as false', async () => {
277
279
  component Basic() {
278
- let disabled = #ripple.track(false);
279
- let checked = #ripple.track(false);
280
+ let disabled = track(false);
281
+ let checked = track(false);
280
282
 
281
283
  <input type="checkbox" {@disabled} {@checked} />
282
284
  }
@@ -310,8 +312,8 @@ describe('basic server > attribute rendering', () => {
310
312
 
311
313
  it('render dynamic boolean attributes as true', async () => {
312
314
  component Basic() {
313
- let disabled = #ripple.track(true);
314
- let checked = #ripple.track(true);
315
+ let disabled = track(true);
316
+ let checked = track(true);
315
317
 
316
318
  <input type="checkbox" {@disabled} {@checked} />
317
319
  }
@@ -345,8 +347,8 @@ describe('basic server > attribute rendering', () => {
345
347
 
346
348
  it('render multiple dynamic attributes', async () => {
347
349
  component Basic() {
348
- let theme = #ripple.track('light');
349
- let size = #ripple.track('medium');
350
+ let theme = track('light');
351
+ let size = track('medium');
350
352
 
351
353
  <div class={`theme-${@theme} size-${@size}`} data-theme={@theme} data-size={@size}>
352
354
  {'Multiple Dynamic Attributes'}
@@ -365,8 +367,8 @@ describe('basic server > attribute rendering', () => {
365
367
 
366
368
  it('render conditional attributes', async () => {
367
369
  component Basic() {
368
- let showTitle = #ripple.track(false);
369
- let showAria = #ripple.track(false);
370
+ let showTitle = track(false);
371
+ let showAria = track(false);
370
372
 
371
373
  <div
372
374
  title={@showTitle ? 'This is a title' : undefined}
@@ -387,7 +389,7 @@ describe('basic server > attribute rendering', () => {
387
389
 
388
390
  it('render spread attributes', async () => {
389
391
  component Basic() {
390
- let attrs = #ripple.track<TestAttributes>(
392
+ let attrs = track<TestAttributes>(
391
393
  {
392
394
  class: 'initial',
393
395
  id: 'test-1',
@@ -409,12 +411,12 @@ describe('basic server > attribute rendering', () => {
409
411
 
410
412
  it('renders with reactive attributes with nested reactive attributes', async () => {
411
413
  component Basic() {
412
- let value = #ripple.track('parent-class');
414
+ let value = track('parent-class');
413
415
 
414
416
  <p class={@value}>{'Colored parent value'}</p>
415
417
 
416
418
  <div>
417
- let nested = #ripple.track('nested-class');
419
+ let nested = track('nested-class');
418
420
 
419
421
  <p class={@nested}>{'Colored nested value'}</p>
420
422
  </div>
@@ -1,3 +1,4 @@
1
+ import { track } from 'ripple';
1
2
  import type {
2
3
  Tracked,
3
4
  PropsWithChildren,
@@ -106,7 +107,7 @@ describe('basic server > components & composition', () => {
106
107
  }
107
108
 
108
109
  component Basic() {
109
- let clicked = #ripple.track(false);
110
+ let clicked = track(false);
110
111
 
111
112
  <Card
112
113
  title="Test Card"
@@ -143,8 +144,8 @@ describe('basic server > components & composition', () => {
143
144
  }
144
145
 
145
146
  component Basic() {
146
- let message = #ripple.track('Hello');
147
- let number = #ripple.track(1);
147
+ let message = track('Hello');
148
+ let number = track(1);
148
149
 
149
150
  <ChildComponent text={message} count={number} />
150
151
  <button
@@ -231,7 +232,7 @@ describe('basic server > components & composition', () => {
231
232
  }
232
233
 
233
234
  component App() {
234
- let Content = #ripple.track(() => Noop);
235
+ let Content = track(() => Noop);
235
236
  <@Content />
236
237
  }
237
238
 
@@ -1,3 +1,4 @@
1
+ import { track } from 'ripple';
1
2
  import type { Tracked, PropsNoChildren } from 'ripple';
2
3
 
3
4
  describe('basic client', () => {
@@ -14,7 +15,7 @@ describe('basic client', () => {
14
15
 
15
16
  it('renders tracked state updates', async () => {
16
17
  component Counter() {
17
- const count = #ripple.track(0);
18
+ const count = track(0);
18
19
 
19
20
  @count++;
20
21
  @count = @count + 5;
@@ -37,8 +38,8 @@ describe('basic client', () => {
37
38
  }
38
39
 
39
40
  component Parent() {
40
- const count = #ripple.track(10);
41
- let Dynamic = #ripple.track(() => Child);
41
+ const count = track(10);
42
+ let Dynamic = track(() => Child);
42
43
 
43
44
  <@Dynamic {count} class={{ test: true }} />
44
45
  }
@@ -50,7 +51,7 @@ describe('basic client', () => {
50
51
 
51
52
  it('renders tracked object properties', async () => {
52
53
  component ObjCounter() {
53
- const obj = { count: #ripple.track(2) };
54
+ const obj = { count: track(2) };
54
55
 
55
56
  obj.@count += 3;
56
57
  obj.@count = obj.@count + 1;
@@ -65,9 +66,9 @@ describe('basic client', () => {
65
66
 
66
67
  it('renders spread props with tracked values', async () => {
67
68
  component SpreadProps() {
68
- const id = #ripple.track('unique-id');
69
- const isActive = #ripple.track(true);
70
- const styles = #ripple.track({ color: 'red', fontSize: '16px' });
69
+ const id = track('unique-id');
70
+ const isActive = track(true);
71
+ const styles = track({ color: 'red', fontSize: '16px' });
71
72
 
72
73
  <div {...{ id: @id, class: { active: @isActive }, style: @styles }}>{'Spread Props'}</div>
73
74
  }
@@ -81,8 +82,8 @@ describe('basic client', () => {
81
82
 
82
83
  it('handles AssignExpressions with tracked values or properties correctly', async () => {
83
84
  component Assignments() {
84
- const count = #ripple.track(0);
85
- const obj = { value: #ripple.track(5) };
85
+ const count = track(0);
86
+ const obj = { value: track(5) };
86
87
 
87
88
  @count += 10;
88
89
  obj.@value *= 2;
@@ -98,9 +99,9 @@ describe('basic client', () => {
98
99
 
99
100
  it(`handles derived changes via tracked dependencies' changes`, async () => {
100
101
  component Derived() {
101
- let base = #ripple.track(5);
102
- let multiplier = #ripple.track(3);
103
- const derived = #ripple.track(() => @base * @multiplier);
102
+ let base = track(5);
103
+ let multiplier = track(3);
104
+ const derived = track(() => @base * @multiplier);
104
105
 
105
106
  <div>{@derived}</div>
106
107
 
@@ -117,10 +118,10 @@ describe('basic client', () => {
117
118
 
118
119
  it(`handles derived changes based on another derived's dependencies' changes`, async () => {
119
120
  component NestedDerived() {
120
- let a = #ripple.track(2);
121
- let b = #ripple.track(3);
122
- const sum = #ripple.track(() => @a + @b);
123
- const product = #ripple.track(() => @sum * 2);
121
+ let a = track(2);
122
+ let b = track(3);
123
+ const sum = track(() => @a + @b);
124
+ const product = track(() => @sum * 2);
124
125
 
125
126
  <div>{@product}</div>
126
127
 
@@ -137,19 +138,19 @@ describe('basic client', () => {
137
138
 
138
139
  it('handles lexical scopes correctly', async () => {
139
140
  component LexicalScopes() {
140
- let x = #ripple.track(1);
141
+ let x = track(1);
141
142
  <div>{@x}</div>
142
143
 
143
144
  <div>
144
- let x = #ripple.track(10);
145
+ let x = track(10);
145
146
  {@x}
146
147
  </div>
147
148
 
148
149
  <div>
149
- let x = #ripple.track(12);
150
+ let x = track(12);
150
151
  {@x}
151
152
  <span>
152
- let x = #ripple.track(15);
153
+ let x = track(15);
153
154
  {@x}
154
155
  </span>
155
156
  </div>
@@ -41,6 +41,37 @@ function getString(e: string = 'test') {
41
41
  expect(result.js.code).toMatchSnapshot();
42
42
  });
43
43
 
44
+ it('removes class TypeScript syntax from JS output', () => {
45
+ const source = `interface BaseEvent {}
46
+
47
+ class PrintEvent implements BaseEvent {
48
+ text: string;
49
+
50
+ constructor(text: string) {
51
+ this.text = text;
52
+ }
53
+ }`;
54
+
55
+ const result = compile(source, 'test.ripple', { mode: 'server' });
56
+
57
+ expect(result.js.code).not.toContain('implements');
58
+ expect(result.js.code).toMatchSnapshot();
59
+ });
60
+
61
+ it('removes class extends type arguments from JS output', () => {
62
+ const source = `class StringMap extends Map<string, string> {
63
+ constructor() {
64
+ super();
65
+ }
66
+ }`;
67
+
68
+ const result = compile(source, 'test.ripple', { mode: 'server' });
69
+
70
+ expect(result.js.code).not.toContain('Map<string, string>');
71
+ expect(result.js.code).toContain('class StringMap extends Map');
72
+ expect(result.js.code).toMatchSnapshot();
73
+ });
74
+
44
75
  it('throws error for interpolating children as text in SSR mode', () => {
45
76
  const source = `
46
77
  export component Layout({ children }) {
@@ -67,7 +98,7 @@ export component Layout(props) {
67
98
  describe('compiler server block tests', () => {
68
99
  it('compiles server block with with only supported types', () => {
69
100
  const source = `
70
- #ripple.server {
101
+ #server {
71
102
  function something() {
72
103
  return 'unexported function';
73
104
  }
@@ -105,7 +136,7 @@ describe('compiler server block tests', () => {
105
136
 
106
137
  it('throws error for unsupported exported object pattern in server block', () => {
107
138
  const source = `
108
- #ripple.server {
139
+ #server {
109
140
  const obj = { fn1: () => {}, fn2: () => {} };
110
141
 
111
142
  export const { fn1, fn2 } = obj;
@@ -116,7 +147,7 @@ describe('compiler server block tests', () => {
116
147
 
117
148
  it('throws error for unsupported exported array pattern in server block', () => {
118
149
  const source = `
119
- #ripple.server {
150
+ #server {
120
151
  const arr = [() => {}, () => {}];
121
152
 
122
153
  export const [fnarr1, fnarr2] = arr;
@@ -127,7 +158,7 @@ describe('compiler server block tests', () => {
127
158
 
128
159
  it('throws error for unsupported exported member expression via object in server block', () => {
129
160
  const source = `
130
- #ripple.server {
161
+ #server {
131
162
  const obj = { fn1: () => {}, fn2: () => {} };
132
163
 
133
164
  export const objProp = obj.fn1;
@@ -138,7 +169,7 @@ describe('compiler server block tests', () => {
138
169
 
139
170
  it('throws error for unsupported exported member expression via array in server block', () => {
140
171
  const source = `
141
- #ripple.server {
172
+ #server {
142
173
  const arr = [() => {}, () => {}];
143
174
 
144
175
  export const arrIndex0 = arr[0];
@@ -1,3 +1,4 @@
1
+ import { track, trackSplit } from 'ripple';
1
2
  import type { Tracked, Props } from 'ripple';
2
3
 
3
4
  describe('composite > props', () => {
@@ -7,7 +8,7 @@ describe('composite > props', () => {
7
8
  }
8
9
 
9
10
  component App() {
10
- let foo = #ripple.track(123);
11
+ let foo = track(123);
11
12
 
12
13
  <Child />
13
14
  <Child {@foo} />
@@ -45,7 +46,7 @@ describe('composite > props', () => {
45
46
  }
46
47
 
47
48
  component App() {
48
- let foo = #ripple.track(123);
49
+ let foo = track(123);
49
50
 
50
51
  <Child />
51
52
  <Child {foo} />
@@ -64,7 +65,7 @@ describe('composite > props', () => {
64
65
  }
65
66
 
66
67
  component App() {
67
- let foo = #ripple.track(123);
68
+ let foo = track(123);
68
69
 
69
70
  <Child />
70
71
  <Child {@foo} />
@@ -79,7 +80,7 @@ describe('composite > props', () => {
79
80
 
80
81
  it('correctly retains prop accessors and reactivity when using rest props', async () => {
81
82
  component Button(props: Props) {
82
- const [children, rest] = #ripple.trackSplit(props, ['children']);
83
+ const [children, rest] = trackSplit(props, ['children']);
83
84
  <button {...@rest}>
84
85
  <@children />
85
86
  </button>
@@ -94,14 +95,14 @@ describe('composite > props', () => {
94
95
  }
95
96
 
96
97
  component Toggle(props: { pressed: Tracked<boolean> }) {
97
- const [pressed, rest] = #ripple.trackSplit(props, ['pressed']);
98
+ const [pressed, rest] = trackSplit(props, ['pressed']);
98
99
  const onClick = () => (@pressed = !@pressed);
99
100
  <Button {...@rest} class={@pressed ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
100
101
  <Button class={@pressed ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
101
102
  }
102
103
 
103
104
  component App() {
104
- const pressed = #ripple.track(true);
105
+ const pressed = track(true);
105
106
  <Toggle {pressed} />
106
107
  }
107
108
 
@@ -1,6 +1,8 @@
1
+ import { Context } from 'ripple';
2
+
1
3
  describe('Context API', () => {
2
4
  it('handles context override in nested components', async () => {
3
- const MessageContext = #ripple.context('default');
5
+ const MessageContext = Context('default');
4
6
 
5
7
  component Inner() {
6
8
  const msg = MessageContext.get();