ripple 0.3.12 → 0.3.14

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 (217) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/package.json +11 -30
  3. package/src/compiler/types/import.d.ts +0 -12
  4. package/src/helpers.d.ts +2 -0
  5. package/src/runtime/array.js +38 -38
  6. package/src/runtime/create-subscriber.js +2 -2
  7. package/src/runtime/index-client.js +15 -13
  8. package/src/runtime/index-server.js +18 -11
  9. package/src/runtime/internal/client/bindings.js +4 -6
  10. package/src/runtime/internal/client/blocks.js +19 -23
  11. package/src/runtime/internal/client/constants.js +20 -9
  12. package/src/runtime/internal/client/events.js +8 -3
  13. package/src/runtime/internal/client/hmr.js +5 -17
  14. package/src/runtime/internal/client/index.js +14 -4
  15. package/src/runtime/internal/client/runtime.js +436 -173
  16. package/src/runtime/internal/client/try.js +334 -156
  17. package/src/runtime/internal/client/types.d.ts +26 -0
  18. package/src/runtime/internal/server/blocks.js +181 -0
  19. package/src/runtime/internal/server/constants.js +7 -0
  20. package/src/runtime/internal/server/index.js +774 -150
  21. package/src/runtime/internal/server/types.d.ts +35 -0
  22. package/src/runtime/media-query.js +34 -33
  23. package/src/runtime/object.js +7 -10
  24. package/src/runtime/proxy.js +2 -3
  25. package/src/runtime/reactive-value.js +23 -21
  26. package/src/server/index.js +1 -1
  27. package/src/utils/ast.js +1 -1
  28. package/src/utils/async.js +35 -0
  29. package/src/utils/attributes.js +43 -0
  30. package/src/utils/builders.js +5 -3
  31. package/tests/client/__snapshots__/computed-properties.test.rsrx.snap +49 -0
  32. package/tests/client/__snapshots__/for.test.rsrx.snap +319 -0
  33. package/tests/client/__snapshots__/html.test.rsrx.snap +40 -0
  34. package/tests/client/_etc.test.rsrx +7 -0
  35. package/tests/client/array/{array.static.test.ripple → array.static.test.rsrx} +18 -20
  36. package/tests/client/async-suspend.test.rsrx +662 -0
  37. package/tests/client/basic/__snapshots__/basic.attributes.test.rsrx.snap +60 -0
  38. package/tests/client/basic/__snapshots__/basic.rendering.test.rsrx.snap +59 -0
  39. package/tests/client/basic/{basic.errors.test.ripple → basic.errors.test.rsrx} +3 -3
  40. package/tests/client/basic/{basic.styling.test.ripple → basic.styling.test.rsrx} +1 -1
  41. package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +12 -0
  42. package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +46 -0
  43. package/tests/client/compiler/{compiler.assignments.test.ripple → compiler.assignments.test.rsrx} +1 -1
  44. package/tests/client/compiler/{compiler.attributes.test.ripple → compiler.attributes.test.rsrx} +1 -1
  45. package/tests/client/compiler/{compiler.basic.test.ripple → compiler.basic.test.rsrx} +13 -13
  46. package/tests/client/compiler/{compiler.tracked-access.test.ripple → compiler.tracked-access.test.rsrx} +1 -1
  47. package/tests/client/compiler/{compiler.try-in-function.test.ripple → compiler.try-in-function.test.rsrx} +9 -7
  48. package/tests/client/compiler/{compiler.typescript.test.ripple → compiler.typescript.test.rsrx} +1 -1
  49. package/tests/client/composite/__snapshots__/composite.render.test.rsrx.snap +37 -0
  50. package/tests/client/css/{global-additional-cases.test.ripple → global-additional-cases.test.rsrx} +1 -1
  51. package/tests/client/css/{global-advanced-selectors.test.ripple → global-advanced-selectors.test.rsrx} +1 -1
  52. package/tests/client/css/{global-at-rules.test.ripple → global-at-rules.test.rsrx} +1 -1
  53. package/tests/client/css/{global-basic.test.ripple → global-basic.test.rsrx} +1 -1
  54. package/tests/client/css/{global-classes-ids.test.ripple → global-classes-ids.test.rsrx} +1 -1
  55. package/tests/client/css/{global-combinators.test.ripple → global-combinators.test.rsrx} +1 -1
  56. package/tests/client/css/{global-complex-nesting.test.ripple → global-complex-nesting.test.rsrx} +1 -1
  57. package/tests/client/css/{global-edge-cases.test.ripple → global-edge-cases.test.rsrx} +1 -1
  58. package/tests/client/css/{global-keyframes.test.ripple → global-keyframes.test.rsrx} +1 -1
  59. package/tests/client/css/{global-nested.test.ripple → global-nested.test.rsrx} +1 -1
  60. package/tests/client/css/{global-pseudo.test.ripple → global-pseudo.test.rsrx} +1 -1
  61. package/tests/client/css/{global-scoping.test.ripple → global-scoping.test.rsrx} +1 -1
  62. package/tests/client/css/{style-identifier.test.ripple → style-identifier.test.rsrx} +1 -1
  63. package/tests/client/{function-overload.test.ripple → function-overload.test.rsrx} +1 -1
  64. package/tests/client/{return.test.ripple → return.test.rsrx} +1 -1
  65. package/tests/client/try.test.rsrx +1702 -0
  66. package/tests/hydration/build-components.js +6 -4
  67. package/tests/hydration/compiled/client/head.js +11 -11
  68. package/tests/hydration/compiled/client/mixed-control-flow.js +55 -70
  69. package/tests/hydration/compiled/client/nested-control-flow.js +72 -88
  70. package/tests/hydration/compiled/client/try.js +42 -54
  71. package/tests/hydration/compiled/server/basic.js +491 -369
  72. package/tests/hydration/compiled/server/composite.js +153 -128
  73. package/tests/hydration/compiled/server/events.js +166 -145
  74. package/tests/hydration/compiled/server/for.js +821 -677
  75. package/tests/hydration/compiled/server/head.js +200 -165
  76. package/tests/hydration/compiled/server/hmr.js +62 -54
  77. package/tests/hydration/compiled/server/html-in-template.js +64 -55
  78. package/tests/hydration/compiled/server/html.js +1477 -1360
  79. package/tests/hydration/compiled/server/if-children.js +448 -408
  80. package/tests/hydration/compiled/server/if.js +204 -171
  81. package/tests/hydration/compiled/server/mixed-control-flow.js +237 -195
  82. package/tests/hydration/compiled/server/nested-control-flow.js +533 -467
  83. package/tests/hydration/compiled/server/portal.js +94 -107
  84. package/tests/hydration/compiled/server/reactivity.js +87 -64
  85. package/tests/hydration/compiled/server/return.js +1424 -1174
  86. package/tests/hydration/compiled/server/switch.js +268 -238
  87. package/tests/hydration/compiled/server/try.js +98 -87
  88. package/tests/hydration/components/{mixed-control-flow.ripple → mixed-control-flow.rsrx} +2 -2
  89. package/tests/hydration/components/{try.ripple → try.rsrx} +4 -2
  90. package/tests/hydration/mixed-control-flow.test.js +14 -0
  91. package/tests/hydration/nested-control-flow.test.js +50 -48
  92. package/tests/hydration/try.test.js +25 -0
  93. package/tests/server/__snapshots__/compiler.test.ripple.snap +0 -32
  94. package/tests/server/__snapshots__/compiler.test.rsrx.snap +95 -0
  95. package/tests/server/{compiler.test.ripple → compiler.test.rsrx} +0 -17
  96. package/tests/server/{html-nesting-validation.test.ripple → html-nesting-validation.test.rsrx} +3 -3
  97. package/tests/server/streaming-ssr.test.rsrx +115 -0
  98. package/tests/server/{style-identifier.test.ripple → style-identifier.test.rsrx} +1 -1
  99. package/tests/server/try.test.rsrx +503 -0
  100. package/tests/setup-server.js +1 -1
  101. package/tests/utils/compiler-compat-config.test.js +4 -4
  102. package/tests/utils/vite-plugin-config.test.js +1 -1
  103. package/tests/utils/vite-plugin-hmr.test.js +5 -5
  104. package/tsconfig.json +2 -0
  105. package/types/index.d.ts +13 -23
  106. package/types/server.d.ts +43 -16
  107. package/src/compiler/comment-utils.js +0 -91
  108. package/src/compiler/errors.js +0 -77
  109. package/src/compiler/identifier-utils.js +0 -80
  110. package/src/compiler/index.d.ts +0 -127
  111. package/src/compiler/index.js +0 -89
  112. package/src/compiler/phases/1-parse/index.js +0 -2964
  113. package/src/compiler/phases/1-parse/style.js +0 -704
  114. package/src/compiler/phases/2-analyze/css-analyze.js +0 -160
  115. package/src/compiler/phases/2-analyze/index.js +0 -2238
  116. package/src/compiler/phases/2-analyze/prune.js +0 -1131
  117. package/src/compiler/phases/2-analyze/validation.js +0 -168
  118. package/src/compiler/phases/3-transform/client/index.js +0 -5301
  119. package/src/compiler/phases/3-transform/segments.js +0 -2129
  120. package/src/compiler/phases/3-transform/server/index.js +0 -1899
  121. package/src/compiler/phases/3-transform/stylesheet.js +0 -545
  122. package/src/compiler/scope.js +0 -476
  123. package/src/compiler/source-map-utils.js +0 -358
  124. package/src/compiler/types/acorn.d.ts +0 -11
  125. package/src/compiler/types/estree-jsx.d.ts +0 -11
  126. package/src/compiler/types/estree.d.ts +0 -11
  127. package/src/compiler/types/index.d.ts +0 -1404
  128. package/src/compiler/types/parse.d.ts +0 -1721
  129. package/src/compiler/utils.js +0 -1263
  130. package/tests/client/_etc.test.ripple +0 -5
  131. package/tests/client/async-suspend.test.ripple +0 -94
  132. package/tests/client/try.test.ripple +0 -196
  133. package/tests/server/streaming-ssr.test.ripple +0 -68
  134. package/tests/server/try.test.ripple +0 -82
  135. /package/tests/client/array/{array.copy-within.test.ripple → array.copy-within.test.rsrx} +0 -0
  136. /package/tests/client/array/{array.derived.test.ripple → array.derived.test.rsrx} +0 -0
  137. /package/tests/client/array/{array.iteration.test.ripple → array.iteration.test.rsrx} +0 -0
  138. /package/tests/client/array/{array.mutations.test.ripple → array.mutations.test.rsrx} +0 -0
  139. /package/tests/client/array/{array.to-methods.test.ripple → array.to-methods.test.rsrx} +0 -0
  140. /package/tests/client/basic/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
  141. /package/tests/client/basic/{basic.collections.test.ripple → basic.collections.test.rsrx} +0 -0
  142. /package/tests/client/basic/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
  143. /package/tests/client/basic/{basic.events.test.ripple → basic.events.test.rsrx} +0 -0
  144. /package/tests/client/basic/{basic.get-set.test.ripple → basic.get-set.test.rsrx} +0 -0
  145. /package/tests/client/basic/{basic.hmr.test.ripple → basic.hmr.test.rsrx} +0 -0
  146. /package/tests/client/basic/{basic.reactivity.test.ripple → basic.reactivity.test.rsrx} +0 -0
  147. /package/tests/client/basic/{basic.rendering.test.ripple → basic.rendering.test.rsrx} +0 -0
  148. /package/tests/client/basic/{basic.utilities.test.ripple → basic.utilities.test.rsrx} +0 -0
  149. /package/tests/client/{boundaries.test.ripple → boundaries.test.rsrx} +0 -0
  150. /package/tests/client/compiler/{compiler.regex.test.ripple → compiler.regex.test.rsrx} +0 -0
  151. /package/tests/client/composite/{composite.dynamic-components.test.ripple → composite.dynamic-components.test.rsrx} +0 -0
  152. /package/tests/client/composite/{composite.generics.test.ripple → composite.generics.test.rsrx} +0 -0
  153. /package/tests/client/composite/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
  154. /package/tests/client/composite/{composite.reactivity.test.ripple → composite.reactivity.test.rsrx} +0 -0
  155. /package/tests/client/composite/{composite.render.test.ripple → composite.render.test.rsrx} +0 -0
  156. /package/tests/client/{computed-properties.test.ripple → computed-properties.test.rsrx} +0 -0
  157. /package/tests/client/{context.test.ripple → context.test.rsrx} +0 -0
  158. /package/tests/client/{date.test.ripple → date.test.rsrx} +0 -0
  159. /package/tests/client/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
  160. /package/tests/client/{events.test.ripple → events.test.rsrx} +0 -0
  161. /package/tests/client/{for.test.ripple → for.test.rsrx} +0 -0
  162. /package/tests/client/{function-overload-import.ripple → function-overload-import.rsrx} +0 -0
  163. /package/tests/client/{head.test.ripple → head.test.rsrx} +0 -0
  164. /package/tests/client/{html.test.ripple → html.test.rsrx} +0 -0
  165. /package/tests/client/{input-value.test.ripple → input-value.test.rsrx} +0 -0
  166. /package/tests/client/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
  167. /package/tests/client/{map.test.ripple → map.test.rsrx} +0 -0
  168. /package/tests/client/{media-query.test.ripple → media-query.test.rsrx} +0 -0
  169. /package/tests/client/{object.test.ripple → object.test.rsrx} +0 -0
  170. /package/tests/client/{portal.test.ripple → portal.test.rsrx} +0 -0
  171. /package/tests/client/{ref.test.ripple → ref.test.rsrx} +0 -0
  172. /package/tests/client/{set.test.ripple → set.test.rsrx} +0 -0
  173. /package/tests/client/{svg.test.ripple → svg.test.rsrx} +0 -0
  174. /package/tests/client/{switch.test.ripple → switch.test.rsrx} +0 -0
  175. /package/tests/client/{tsx.test.ripple → tsx.test.rsrx} +0 -0
  176. /package/tests/client/{typescript-generics.test.ripple → typescript-generics.test.rsrx} +0 -0
  177. /package/tests/client/url/{url.derived.test.ripple → url.derived.test.rsrx} +0 -0
  178. /package/tests/client/url/{url.parsing.test.ripple → url.parsing.test.rsrx} +0 -0
  179. /package/tests/client/url/{url.partial-removal.test.ripple → url.partial-removal.test.rsrx} +0 -0
  180. /package/tests/client/url/{url.reactivity.test.ripple → url.reactivity.test.rsrx} +0 -0
  181. /package/tests/client/url/{url.serialization.test.ripple → url.serialization.test.rsrx} +0 -0
  182. /package/tests/client/url-search-params/{url-search-params.derived.test.ripple → url-search-params.derived.test.rsrx} +0 -0
  183. /package/tests/client/url-search-params/{url-search-params.initialization.test.ripple → url-search-params.initialization.test.rsrx} +0 -0
  184. /package/tests/client/url-search-params/{url-search-params.iteration.test.ripple → url-search-params.iteration.test.rsrx} +0 -0
  185. /package/tests/client/url-search-params/{url-search-params.mutation.test.ripple → url-search-params.mutation.test.rsrx} +0 -0
  186. /package/tests/client/url-search-params/{url-search-params.retrieval.test.ripple → url-search-params.retrieval.test.rsrx} +0 -0
  187. /package/tests/client/url-search-params/{url-search-params.serialization.test.ripple → url-search-params.serialization.test.rsrx} +0 -0
  188. /package/tests/client/url-search-params/{url-search-params.tracked-url.test.ripple → url-search-params.tracked-url.test.rsrx} +0 -0
  189. /package/tests/hydration/components/{basic.ripple → basic.rsrx} +0 -0
  190. /package/tests/hydration/components/{composite.ripple → composite.rsrx} +0 -0
  191. /package/tests/hydration/components/{events.ripple → events.rsrx} +0 -0
  192. /package/tests/hydration/components/{for.ripple → for.rsrx} +0 -0
  193. /package/tests/hydration/components/{head.ripple → head.rsrx} +0 -0
  194. /package/tests/hydration/components/{hmr.ripple → hmr.rsrx} +0 -0
  195. /package/tests/hydration/components/{html-in-template.ripple → html-in-template.rsrx} +0 -0
  196. /package/tests/hydration/components/{html.ripple → html.rsrx} +0 -0
  197. /package/tests/hydration/components/{if-children.ripple → if-children.rsrx} +0 -0
  198. /package/tests/hydration/components/{if.ripple → if.rsrx} +0 -0
  199. /package/tests/hydration/components/{nested-control-flow.ripple → nested-control-flow.rsrx} +0 -0
  200. /package/tests/hydration/components/{portal.ripple → portal.rsrx} +0 -0
  201. /package/tests/hydration/components/{reactivity.ripple → reactivity.rsrx} +0 -0
  202. /package/tests/hydration/components/{return.ripple → return.rsrx} +0 -0
  203. /package/tests/hydration/components/{switch.ripple → switch.rsrx} +0 -0
  204. /package/tests/server/{await.test.ripple → await.test.rsrx} +0 -0
  205. /package/tests/server/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
  206. /package/tests/server/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
  207. /package/tests/server/{basic.test.ripple → basic.test.rsrx} +0 -0
  208. /package/tests/server/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
  209. /package/tests/server/{composite.test.ripple → composite.test.rsrx} +0 -0
  210. /package/tests/server/{context.test.ripple → context.test.rsrx} +0 -0
  211. /package/tests/server/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
  212. /package/tests/server/{for.test.ripple → for.test.rsrx} +0 -0
  213. /package/tests/server/{head.test.ripple → head.test.rsrx} +0 -0
  214. /package/tests/server/{if.test.ripple → if.test.rsrx} +0 -0
  215. /package/tests/server/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
  216. /package/tests/server/{return.test.ripple → return.test.rsrx} +0 -0
  217. /package/tests/server/{switch.test.ripple → switch.test.rsrx} +0 -0
@@ -1,5 +0,0 @@
1
- // This file is for tests that don't fit anywhere else
2
-
3
- describe('etc', () => {
4
- it.skip('this is here so the empty test suite does not fail');
5
- });
@@ -1,94 +0,0 @@
1
- import { flushSync, track } from 'ripple';
2
-
3
- describe('async suspense', () => {
4
- it('hides child content during re-suspension when tracked dependency changes', async () => {
5
- let resolve_fn: (() => void) | null = null;
6
-
7
- component Child({ countTracked }: { countTracked: any }) {
8
- await track(() => {
9
- countTracked.value;
10
- return new Promise<void>((resolve) => {
11
- resolve_fn = resolve;
12
- });
13
- });
14
-
15
- <div class="child-content">{'child content'}</div>
16
- }
17
-
18
- component App() {
19
- let &[count, countTracked] = track(0);
20
-
21
- try {
22
- <Child {countTracked} />
23
- } pending {
24
- <div class="pending">{'pending...'}</div>
25
- }
26
-
27
- <button onClick={() => count++}>{'Increment'}</button>
28
- }
29
-
30
- render(App);
31
-
32
- // Initial state: should show pending
33
- await new Promise((resolve) => setTimeout(resolve, 0));
34
- flushSync();
35
- expect(container.innerHTML).toContain('pending...');
36
- expect(container.innerHTML).not.toContain('child content');
37
-
38
- // Resolve the first promise
39
- (resolve_fn as () => void)?.();
40
- await new Promise((resolve) => setTimeout(resolve, 0));
41
- flushSync();
42
-
43
- // After resolution: should show child content, not pending
44
- expect(container.innerHTML).toContain('child content');
45
- expect(container.innerHTML).not.toContain('pending...');
46
-
47
- // Now trigger re-suspension by changing count
48
- const button = container.querySelector('button');
49
- button?.click();
50
- flushSync();
51
-
52
- // Wait for microtask to process
53
- await new Promise((resolve) => setTimeout(resolve, 0));
54
- flushSync();
55
-
56
- // BUG: During re-suspension, we should only see pending, not child content
57
- // The child content should be hidden when the new promise is pending
58
- expect(container.innerHTML).toContain('pending...');
59
- expect(container.innerHTML).not.toContain('child content');
60
- });
61
-
62
- it('shows pending UI immediately when child suspends', async () => {
63
- component Child() {
64
- await new Promise((resolve) => setTimeout(resolve, 50));
65
- <div class="child">{'loaded'}</div>
66
- }
67
-
68
- component App() {
69
- try {
70
- <Child />
71
- } pending {
72
- <div class="pending">{'loading...'}</div>
73
- }
74
- }
75
-
76
- render(App);
77
-
78
- // Wait for microtask
79
- await new Promise((resolve) => setTimeout(resolve, 0));
80
- flushSync();
81
-
82
- // Should show pending, not child content
83
- expect(container.innerHTML).toContain('loading...');
84
- expect(container.innerHTML).not.toContain('loaded');
85
-
86
- // Wait for child to resolve
87
- await new Promise((resolve) => setTimeout(resolve, 100));
88
- flushSync();
89
-
90
- // Should show child content, not pending
91
- expect(container.innerHTML).toContain('loaded');
92
- expect(container.innerHTML).not.toContain('loading...');
93
- });
94
- });
@@ -1,196 +0,0 @@
1
- import { RippleArray, bindValue, flushSync, track } from 'ripple';
2
-
3
- describe('try block with catch and pending', () => {
4
- it('catch block works when component throws before await with pending block', async () => {
5
- component App() {
6
- try {
7
- <ThrowingChild />
8
- } pending {
9
- <p>{'loading...'}</p>
10
- } catch (err) {
11
- <p>{'caught error'}</p>
12
- }
13
- }
14
-
15
- component ThrowingChild() {
16
- throw new Error('sync error');
17
- let data = await Promise.resolve('hello');
18
- <p>{data}</p>
19
- }
20
-
21
- render(App);
22
-
23
- await new Promise((resolve) => setTimeout(resolve, 0));
24
- flushSync();
25
-
26
- expect(container.innerHTML).toContain('caught error');
27
- expect(container.innerHTML).not.toContain('loading...');
28
- });
29
-
30
- it('catch block works when component throws after await with pending block', async () => {
31
- component App() {
32
- try {
33
- <ThrowingAfterAwait />
34
- } pending {
35
- <p>{'loading...'}</p>
36
- } catch (err) {
37
- <p>{'caught error'}</p>
38
- }
39
- }
40
-
41
- component ThrowingAfterAwait() {
42
- let data = await Promise.resolve('hello');
43
- throw new Error('error after await');
44
- <p>{data}</p>
45
- }
46
-
47
- render(App);
48
-
49
- await new Promise((resolve) => setTimeout(resolve, 0));
50
- flushSync();
51
-
52
- expect(container.innerHTML).toContain('caught error');
53
- expect(container.innerHTML).not.toContain('loading...');
54
- });
55
-
56
- it('catch block works with try/catch/pending when async body rejects', async () => {
57
- component App() {
58
- try {
59
- let data = await Promise.reject(new Error('rejected'));
60
- <p>{data}</p>
61
- } pending {
62
- <p>{'loading...'}</p>
63
- } catch (err) {
64
- <p>{'caught rejection'}</p>
65
- }
66
- }
67
-
68
- render(App);
69
-
70
- await new Promise((resolve) => setTimeout(resolve, 0));
71
- flushSync();
72
-
73
- expect(container.innerHTML).toContain('caught rejection');
74
- expect(container.innerHTML).not.toContain('loading...');
75
- });
76
- });
77
-
78
- describe('try block', () => {
79
- it(
80
- 'does not compile ref binds as async callbacks inside try/pending async branches',
81
- async () => {
82
- component App() {
83
- try {
84
- <Child />
85
- } pending {
86
- <p>{'loading...'}</p>
87
- }
88
- }
89
-
90
- component Child() {
91
- let &[value, valueTracked] = track(1);
92
- await Promise.resolve(value + 1);
93
-
94
- <input type="number" {ref bindValue(valueTracked)} />
95
- }
96
-
97
- render(App);
98
-
99
- await new Promise((resolve) => setTimeout(resolve, 0));
100
- flushSync();
101
-
102
- const input = container.querySelector('input') as HTMLInputElement | null;
103
- expect(input?.value).toBe('1');
104
- expect(container.innerHTML).not.toContain('loading...');
105
- },
106
- );
107
-
108
- it('does not crash when async component is used inside try/pending', async () => {
109
- component App() {
110
- try {
111
- <AsyncChild />
112
- } pending {
113
- <p>{'loading...'}</p>
114
- }
115
- }
116
-
117
- component AsyncChild() {
118
- let data = await Promise.resolve(['a', 'b', 'c']);
119
-
120
- <ul>
121
- for (let item of data) {
122
- <li>{item}</li>
123
- }
124
- </ul>
125
- }
126
-
127
- render(App);
128
-
129
- await new Promise((resolve) => setTimeout(resolve, 0));
130
- flushSync();
131
-
132
- const items = container.querySelectorAll('li');
133
- expect(items.length).toBe(3);
134
- expect(items[0].textContent).toBe('a');
135
- expect(items[1].textContent).toBe('b');
136
- expect(items[2].textContent).toBe('c');
137
- });
138
-
139
- it(
140
- 'does not crash when async component with tracked state is used inside try/pending',
141
- async () => {
142
- component App() {
143
- let query = track('');
144
-
145
- try {
146
- <FilteredList {query} />
147
- } pending {
148
- <p>{'loading...'}</p>
149
- }
150
- }
151
-
152
- component FilteredList({ query }: { query: any }) {
153
- let items = await Promise.resolve(['apple', 'banana', 'cherry']);
154
- let list = RippleArray.from(items);
155
- let &[filtered] = track(() => list.filter((item: string) => item.includes(query.value)));
156
-
157
- <ul>
158
- for (let item of filtered) {
159
- <li>{item}</li>
160
- }
161
- </ul>
162
- }
163
-
164
- render(App);
165
-
166
- await new Promise((resolve) => setTimeout(resolve, 0));
167
- flushSync();
168
-
169
- const listItems = container.querySelectorAll('li');
170
- expect(listItems.length).toBe(3);
171
- },
172
- );
173
-
174
- it('if test condition does not become async within try/pending', async () => {
175
- component App() {
176
- try {
177
- let items = await Promise.resolve(['apple', 'banana', 'cherry']);
178
-
179
- if (items.includes('not-in-list')) {
180
- <p>{'not-in-list is in the list!'}</p>
181
- } else {
182
- <p>{'not-in-list is not in the list.'}</p>
183
- }
184
- } pending {
185
- <p>{'loading...'}</p>
186
- }
187
- }
188
-
189
- render(App);
190
-
191
- await new Promise((resolve) => setTimeout(resolve, 0));
192
- flushSync();
193
-
194
- expect(container.innerHTML).toContain('not-in-list is not in the list.');
195
- });
196
- });
@@ -1,68 +0,0 @@
1
- import { renderToStream } from 'ripple/server';
2
-
3
- test('renderToStream renders a simple component', async ({ expect }) => {
4
- component Basic() {
5
- <div>{'Hello, streaming SSR!'}</div>
6
- }
7
-
8
- const stream = renderToStream(Basic);
9
-
10
- let result = '';
11
- await new Promise((resolve) => {
12
- stream.on('data', (chunk) => {
13
- result += chunk.toString();
14
- });
15
- stream.on('end', resolve);
16
- });
17
-
18
- expect(result).toBe('<div>Hello, streaming SSR!</div>');
19
- });
20
-
21
- test('renderToStream handles async components', async ({ expect }) => {
22
- component AsyncComponent() {
23
- await new Promise((resolve) => setTimeout(resolve, 10));
24
- <p>{'Async content loaded.'}</p>
25
- }
26
-
27
- const stream = renderToStream(AsyncComponent);
28
-
29
- let result = '';
30
- await new Promise((resolve) => {
31
- stream.on('data', (chunk) => {
32
- result += chunk.toString();
33
- });
34
- stream.on('end', resolve);
35
- });
36
-
37
- expect(result).toBe('<p>Async content loaded.</p>');
38
- });
39
-
40
- test('renderToStream handles await blocks with pending state', async ({ expect }) => {
41
- component AwaitComponent() {
42
- let data = 'initial';
43
- await new Promise((resolve) => setTimeout(() => {
44
- data = 'resolved';
45
- resolve('');
46
- }, 20));
47
- try {
48
- <div>
49
- {'Data: '}
50
- {data}
51
- </div>
52
- } pending {
53
- <div>{'Loading...'}</div>
54
- }
55
- }
56
-
57
- const stream = renderToStream(AwaitComponent);
58
-
59
- let result = '';
60
- await new Promise((resolve) => {
61
- stream.on('data', (chunk) => {
62
- result += chunk.toString();
63
- });
64
- stream.on('end', resolve);
65
- });
66
-
67
- expect(result).toBe('<!--[--><div>Loading...</div><div>Data: resolved</div><!--]-->');
68
- });
@@ -1,82 +0,0 @@
1
- describe('try block with catch and pending (server)', () => {
2
- it('catch block works when component throws before await with pending block', async () => {
3
- component ThrowingChild() {
4
- throw new Error('sync error');
5
- let data = await Promise.resolve('hello');
6
- <p>{data}</p>
7
- }
8
-
9
- component App() {
10
- try {
11
- <ThrowingChild />
12
- } pending {
13
- <p>{'loading...'}</p>
14
- } catch (err) {
15
- <p>{'caught error'}</p>
16
- }
17
- }
18
-
19
- const { body } = await render(App);
20
- expect(body).toContain('caught error');
21
- expect(body).not.toContain('loading...');
22
- });
23
-
24
- it('catch block works when component throws after await with pending block', async () => {
25
- component ThrowingAfterAwait() {
26
- let data = await Promise.resolve('hello');
27
- throw new Error('error after await');
28
- <p>{data}</p>
29
- }
30
-
31
- component App() {
32
- try {
33
- <ThrowingAfterAwait />
34
- } pending {
35
- <p>{'loading...'}</p>
36
- } catch (err) {
37
- <p>{'caught error'}</p>
38
- }
39
- }
40
-
41
- const { body } = await render(App);
42
- expect(body).toContain('caught error');
43
- expect(body).not.toContain('loading...');
44
- });
45
-
46
- it('catch block works with try/catch/pending when async body rejects', async () => {
47
- component App() {
48
- try {
49
- let data = await Promise.reject(new Error('rejected'));
50
- <p>{data}</p>
51
- } pending {
52
- <p>{'loading...'}</p>
53
- } catch (err) {
54
- <p>{'caught rejection'}</p>
55
- }
56
- }
57
-
58
- const { body } = await render(App);
59
- expect(body).toContain('caught rejection');
60
- expect(body).not.toContain('loading...');
61
- });
62
-
63
- it('removes pending content for nested try/pending blocks', async () => {
64
- component App() {
65
- try {
66
- try {
67
- let data = await Promise.resolve('resolved');
68
- <p>{data}</p>
69
- } pending {
70
- <p>{'inner loading...'}</p>
71
- }
72
- } pending {
73
- <p>{'outer loading...'}</p>
74
- }
75
- }
76
-
77
- const { body } = await render(App);
78
- expect(body).toContain('resolved');
79
- expect(body).not.toContain('outer loading...');
80
- expect(body).not.toContain('inner loading...');
81
- });
82
- });
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes