ripple 0.2.208 → 0.2.210

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 (108) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +2 -1
  3. package/package.json +2 -6
  4. package/shims/rollup-estree-types.d.ts +1 -1
  5. package/src/compiler/index.d.ts +1 -0
  6. package/src/compiler/index.js +7 -1
  7. package/src/compiler/phases/1-parse/index.js +15 -6
  8. package/src/compiler/phases/2-analyze/css-analyze.js +100 -104
  9. package/src/compiler/phases/2-analyze/index.js +215 -2
  10. package/src/compiler/phases/3-transform/client/index.js +388 -50
  11. package/src/compiler/phases/3-transform/segments.js +123 -39
  12. package/src/compiler/phases/3-transform/server/index.js +266 -13
  13. package/src/compiler/types/index.d.ts +16 -3
  14. package/src/compiler/utils.js +1 -15
  15. package/src/constants.js +0 -2
  16. package/src/helpers.d.ts +4 -0
  17. package/src/html-tree-validation.js +211 -0
  18. package/src/jsx-runtime.d.ts +260 -259
  19. package/src/jsx-runtime.js +12 -12
  20. package/src/runtime/array.js +17 -17
  21. package/src/runtime/create-subscriber.js +1 -1
  22. package/src/runtime/index-client.js +1 -5
  23. package/src/runtime/index-server.js +15 -0
  24. package/src/runtime/internal/client/compat.js +3 -3
  25. package/src/runtime/internal/client/composite.js +6 -1
  26. package/src/runtime/internal/client/head.js +50 -4
  27. package/src/runtime/internal/client/html.js +73 -12
  28. package/src/runtime/internal/client/hydration.js +12 -0
  29. package/src/runtime/internal/client/index.js +1 -1
  30. package/src/runtime/internal/client/portal.js +54 -29
  31. package/src/runtime/internal/client/rpc.js +3 -1
  32. package/src/runtime/internal/client/switch.js +5 -0
  33. package/src/runtime/internal/client/template.js +117 -11
  34. package/src/runtime/internal/client/try.js +1 -0
  35. package/src/runtime/internal/server/index.js +113 -1
  36. package/src/runtime/internal/server/rpc.js +4 -4
  37. package/src/runtime/map.js +2 -2
  38. package/src/runtime/object.js +6 -6
  39. package/src/runtime/proxy.js +12 -11
  40. package/src/runtime/reactive-value.js +9 -1
  41. package/src/runtime/set.js +12 -7
  42. package/src/runtime/url-search-params.js +0 -1
  43. package/src/server/index.js +4 -0
  44. package/src/utils/hashing.js +15 -0
  45. package/src/utils/normalize_css_property_name.js +1 -1
  46. package/tests/client/array/array.mutations.test.ripple +8 -8
  47. package/tests/client/basic/basic.errors.test.ripple +28 -0
  48. package/tests/client/basic/basic.events.test.ripple +6 -3
  49. package/tests/client/basic/basic.utilities.test.ripple +1 -1
  50. package/tests/client/compiler/compiler.regex.test.ripple +10 -8
  51. package/tests/client/composite/composite.generics.test.ripple +5 -2
  52. package/tests/client/dynamic-elements.test.ripple +30 -1
  53. package/tests/client/function-overload-import.ripple +6 -7
  54. package/tests/client/html.test.ripple +0 -1
  55. package/tests/client/object.test.ripple +2 -2
  56. package/tests/client/portal.test.ripple +3 -3
  57. package/tests/client/return.test.ripple +2500 -0
  58. package/tests/client/try.test.ripple +69 -0
  59. package/tests/client/typescript-generics.test.ripple +1 -1
  60. package/tests/client/url/url.derived.test.ripple +1 -1
  61. package/tests/client/url/url.parsing.test.ripple +3 -3
  62. package/tests/client/url/url.partial-removal.test.ripple +7 -7
  63. package/tests/client/url/url.reactivity.test.ripple +15 -15
  64. package/tests/client/url/url.serialization.test.ripple +2 -2
  65. package/tests/hydration/basic.test.js +23 -0
  66. package/tests/hydration/build-components.js +10 -4
  67. package/tests/hydration/compiled/client/basic.js +165 -3
  68. package/tests/hydration/compiled/client/for.js +1140 -23
  69. package/tests/hydration/compiled/client/head.js +234 -0
  70. package/tests/hydration/compiled/client/html.js +135 -0
  71. package/tests/hydration/compiled/client/portal.js +172 -0
  72. package/tests/hydration/compiled/client/reactivity.js +3 -1
  73. package/tests/hydration/compiled/client/return.js +1976 -0
  74. package/tests/hydration/compiled/client/switch.js +162 -0
  75. package/tests/hydration/compiled/server/basic.js +249 -0
  76. package/tests/hydration/compiled/server/events.js +1 -1
  77. package/tests/hydration/compiled/server/for.js +891 -1
  78. package/tests/hydration/compiled/server/head.js +291 -0
  79. package/tests/hydration/compiled/server/html.js +133 -0
  80. package/tests/hydration/compiled/server/if.js +1 -1
  81. package/tests/hydration/compiled/server/portal.js +250 -0
  82. package/tests/hydration/compiled/server/reactivity.js +1 -1
  83. package/tests/hydration/compiled/server/return.js +1969 -0
  84. package/tests/hydration/compiled/server/switch.js +130 -0
  85. package/tests/hydration/components/basic.ripple +55 -0
  86. package/tests/hydration/components/for.ripple +403 -0
  87. package/tests/hydration/components/head.ripple +111 -0
  88. package/tests/hydration/components/html.ripple +38 -0
  89. package/tests/hydration/components/portal.ripple +49 -0
  90. package/tests/hydration/components/return.ripple +564 -0
  91. package/tests/hydration/components/switch.ripple +51 -0
  92. package/tests/hydration/for.test.js +363 -0
  93. package/tests/hydration/head.test.js +105 -0
  94. package/tests/hydration/html.test.js +46 -0
  95. package/tests/hydration/portal.test.js +71 -0
  96. package/tests/hydration/return.test.js +544 -0
  97. package/tests/hydration/switch.test.js +42 -0
  98. package/tests/server/basic.attributes.test.ripple +1 -1
  99. package/tests/server/compiler.test.ripple +22 -0
  100. package/tests/server/composite.test.ripple +5 -2
  101. package/tests/server/html-nesting-validation.test.ripple +237 -0
  102. package/tests/server/return.test.ripple +1379 -0
  103. package/tests/setup-hydration.js +6 -1
  104. package/tests/utils/escaping.test.js +3 -1
  105. package/tests/utils/normalize_css_property_name.test.js +0 -1
  106. package/tests/utils/patterns.test.js +6 -2
  107. package/tests/utils/sanitize_template_string.test.js +3 -2
  108. package/types/server.d.ts +16 -0
@@ -61,6 +61,34 @@ describe('basic client > errors', () => {
61
61
  }).toThrow('Unclosed tag');
62
62
  });
63
63
 
64
+ it('should throw error for interpolating children as text', () => {
65
+ const code = `
66
+ export component Layout({ children }) {
67
+ <div>{children}</div>
68
+ }
69
+ `;
70
+
71
+ expect(() => {
72
+ compile(code, 'test.ripple');
73
+ }).toThrow(
74
+ '`children` cannot be rendered using text interpolation. Use `<children />` instead.',
75
+ );
76
+ });
77
+
78
+ it('should throw error for interpolating props.children as text', () => {
79
+ const code = `
80
+ export component Layout(props) {
81
+ <div>{props.children}</div>
82
+ }
83
+ `;
84
+
85
+ expect(() => {
86
+ compile(code, 'test.ripple');
87
+ }).toThrow(
88
+ '`children` cannot be rendered using text interpolation. Use `<children />` instead.',
89
+ );
90
+ });
91
+
64
92
  it('errors on mutating tracked value inside computed track() evaluation', () => {
65
93
  component Basic() {
66
94
  let count = track(0);
@@ -42,9 +42,12 @@ describe('basic client > events', () => {
42
42
  let bubbleClicks = track(0);
43
43
 
44
44
  <div
45
- onClick={{handleEvent: () => {
46
- @captureClicks++;
47
- }, capture: true}}
45
+ onClick={{
46
+ handleEvent: () => {
47
+ @captureClicks++;
48
+ },
49
+ capture: true,
50
+ }}
48
51
  >
49
52
  <button
50
53
  onClick={() => {
@@ -3,7 +3,7 @@ import { track, effect, untrack, tick } from 'ripple';
3
3
  describe('basic client > utilities', () => {
4
4
  it('tick function', async () => {
5
5
  let resolve: () => void;
6
- const promise = new Promise<void>((res) => resolve = res);
6
+ const promise = new Promise<void>((res) => (resolve = res));
7
7
 
8
8
  component Basic() {
9
9
  let value = track(0);
@@ -59,16 +59,18 @@ describe('compiler > regex', () => {
59
59
  // Mix of regex parsing and legitimate JSX
60
60
  let paragraphs = htmlString.match(/<p[^>]*>.*?<\/p>/g);
61
61
  let cleaned = htmlString.replace(/<\/?[^>]+>/g, '');
62
- let splitArray = htmlString.split(/<\/?\w+>/g).filter(s => s.trim());
62
+ let splitArray = htmlString.split(/<\/?\w+>/g).filter((s) => s.trim());
63
63
 
64
- <div class='container'>
65
- <span class='result'>{String(paragraphs)}</span>
66
- <span class='cleaned'>{cleaned}</span>
64
+ <div class="container">
65
+ <span class="result">{String(paragraphs)}</span>
66
+ <span class="cleaned">{cleaned}</span>
67
67
  <p>{'This is real JSX'}</p>
68
- <div><span>
69
- {'Split result: '}
70
- {splitArray.join(', ')}
71
- </span></div>
68
+ <div>
69
+ <span>
70
+ {'Split result: '}
71
+ {splitArray.join(', ')}
72
+ </span>
73
+ </div>
72
74
  </div>
73
75
  }
74
76
 
@@ -201,8 +201,11 @@ describe('composite > generics', () => {
201
201
  this.map = new Map<Key, Value>();
202
202
  }
203
203
  }
204
- const gg = new Mapper<// key type
205
- string /* value type */, number>();
204
+ const gg = new Mapper<
205
+ // key type
206
+ string /* value type */,
207
+ number
208
+ >();
206
209
 
207
210
  // 33. Map of generic instance as key
208
211
  const mm = new Map<TrackedArray<number>, TrackedArray<string>>();
@@ -1,4 +1,4 @@
1
- import type { Props, PropsWithChildren, PropsNoChildren, PropsWithExtras } from 'ripple';
1
+ import type { PropsWithExtras } from 'ripple';
2
2
  import { flushSync, track, createRefKey, trackSplit } from 'ripple';
3
3
 
4
4
  describe('dynamic DOM elements', () => {
@@ -592,4 +592,33 @@ describe('dynamic DOM elements', () => {
592
592
  expect(outerScopes).toHaveLength(1);
593
593
  expect(innerScopes).toHaveLength(0);
594
594
  });
595
+
596
+ it('should remove and add back a text node in a conditional statement with a tracked', () => {
597
+ component App() {
598
+ let b = track(true);
599
+ <div>
600
+ if (@b) {
601
+ {'Inside if'}
602
+ }
603
+ </div>
604
+ <button onClick={() => (@b = !@b)}>{'Toggle b'}</button>
605
+ }
606
+
607
+ render(App);
608
+
609
+ const button = container.querySelector('button');
610
+ const div = container.querySelector('div');
611
+
612
+ expect(div.textContent).toBe('Inside if');
613
+
614
+ button.click();
615
+ flushSync();
616
+
617
+ expect(div.textContent).toBe('');
618
+
619
+ button.click();
620
+ flushSync();
621
+
622
+ expect(div.textContent).toBe('Inside if');
623
+ });
595
624
  });
@@ -1,10 +1,9 @@
1
- export function test(arg: string): string
2
- export function test(arg: number): string
3
-
1
+ export function test(arg: string): string;
2
+ export function test(arg: number): string;
4
3
  export function test(arg: string | number): string {
5
- if (typeof arg === 'string') {
6
- return arg;
7
- }
4
+ if (typeof arg === 'string') {
5
+ return arg;
6
+ }
8
7
 
9
- return arg.toString();
8
+ return arg.toString();
10
9
  }
@@ -57,7 +57,6 @@ describe('html directive', () => {
57
57
  let str = '<mi>x</mi><mo>+</mo><mi>y</mi>';
58
58
 
59
59
  <math>{html str}</math>
60
-
61
60
  }
62
61
 
63
62
  render(App);
@@ -4,7 +4,7 @@ import { TRACKED_OBJECT } from '../../src/runtime/internal/client/constants.js';
4
4
  describe('TrackedObject', () => {
5
5
  it('makes new properties reactive', () => {
6
6
  component ObjectTest() {
7
- const obj = new TrackedObject<{ a: number }>({a: -1});
7
+ const obj = new TrackedObject<{ a: number }>({ a: -1 });
8
8
 
9
9
  obj.a = 0;
10
10
 
@@ -60,7 +60,7 @@ describe('TrackedObject', () => {
60
60
 
61
61
  it('checks if property exists via the has trap', () => {
62
62
  component ObjectTest() {
63
- const obj = new TrackedObject<{ a: number; b: number }>({ a: - 1, b: 1 });
63
+ const obj = new TrackedObject<{ a: number; b: number }>({ a: -1, b: 1 });
64
64
 
65
65
  obj.a = 0;
66
66
 
@@ -54,7 +54,7 @@ describe('Portal', () => {
54
54
  </Portal>
55
55
  }
56
56
 
57
- <button onClick={() => @open = false}>{'Close'}</button>
57
+ <button onClick={() => (@open = false)}>{'Close'}</button>
58
58
  }
59
59
 
60
60
  render(TestPortal);
@@ -78,13 +78,13 @@ describe('Portal', () => {
78
78
  <Portal target={document.body}>
79
79
  <div class="test-portal">
80
80
  {'Content'}
81
- <button onClick={() => @open = false}>{'Close'}</button>
81
+ <button onClick={() => (@open = false)}>{'Close'}</button>
82
82
  </div>
83
83
  </Portal>
84
84
  }
85
85
 
86
86
  if (!@open) {
87
- <button onClick={() => @open = true}>{'Open'}</button>
87
+ <button onClick={() => (@open = true)}>{'Open'}</button>
88
88
  }
89
89
  }
90
90