ripple 0.3.12 → 0.3.13

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 (190) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/package.json +8 -2
  3. package/src/compiler/phases/1-parse/index.js +73 -30
  4. package/src/compiler/phases/2-analyze/index.js +28 -58
  5. package/src/compiler/phases/3-transform/client/index.js +127 -164
  6. package/src/compiler/phases/3-transform/segments.js +4 -8
  7. package/src/compiler/phases/3-transform/server/index.js +210 -360
  8. package/src/compiler/types/import.d.ts +0 -12
  9. package/src/compiler/types/index.d.ts +12 -5
  10. package/src/compiler/types/parse.d.ts +2 -0
  11. package/src/compiler/utils.js +39 -44
  12. package/src/helpers.d.ts +2 -0
  13. package/src/runtime/index-client.js +15 -13
  14. package/src/runtime/index-server.js +18 -11
  15. package/src/runtime/internal/client/blocks.js +19 -23
  16. package/src/runtime/internal/client/constants.js +20 -9
  17. package/src/runtime/internal/client/index.js +14 -4
  18. package/src/runtime/internal/client/runtime.js +435 -173
  19. package/src/runtime/internal/client/try.js +334 -156
  20. package/src/runtime/internal/client/types.d.ts +26 -0
  21. package/src/runtime/internal/server/blocks.js +183 -0
  22. package/src/runtime/internal/server/constants.js +7 -0
  23. package/src/runtime/internal/server/index.js +780 -148
  24. package/src/runtime/internal/server/types.d.ts +35 -0
  25. package/src/server/index.js +1 -1
  26. package/src/utils/async.js +35 -0
  27. package/src/utils/builders.js +3 -1
  28. package/tests/client/__snapshots__/computed-properties.test.rsrx.snap +49 -0
  29. package/tests/client/__snapshots__/for.test.rsrx.snap +319 -0
  30. package/tests/client/__snapshots__/html.test.rsrx.snap +40 -0
  31. package/tests/client/_etc.test.rsrx +7 -0
  32. package/tests/client/array/{array.static.test.ripple → array.static.test.rsrx} +18 -20
  33. package/tests/client/async-suspend.test.rsrx +662 -0
  34. package/tests/client/basic/__snapshots__/basic.attributes.test.rsrx.snap +60 -0
  35. package/tests/client/basic/__snapshots__/basic.rendering.test.rsrx.snap +59 -0
  36. package/tests/client/basic/{basic.errors.test.ripple → basic.errors.test.rsrx} +2 -2
  37. package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +12 -0
  38. package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +46 -0
  39. package/tests/client/compiler/{compiler.try-in-function.test.ripple → compiler.try-in-function.test.rsrx} +8 -6
  40. package/tests/client/composite/__snapshots__/composite.render.test.rsrx.snap +37 -0
  41. package/tests/client/{function-overload.test.ripple → function-overload.test.rsrx} +1 -1
  42. package/tests/client/try.test.rsrx +1702 -0
  43. package/tests/hydration/build-components.js +5 -3
  44. package/tests/hydration/compiled/client/head.js +11 -11
  45. package/tests/hydration/compiled/client/mixed-control-flow.js +55 -70
  46. package/tests/hydration/compiled/client/nested-control-flow.js +72 -88
  47. package/tests/hydration/compiled/client/try.js +42 -54
  48. package/tests/hydration/compiled/server/basic.js +491 -369
  49. package/tests/hydration/compiled/server/composite.js +153 -128
  50. package/tests/hydration/compiled/server/events.js +166 -145
  51. package/tests/hydration/compiled/server/for.js +821 -677
  52. package/tests/hydration/compiled/server/head.js +200 -165
  53. package/tests/hydration/compiled/server/hmr.js +62 -54
  54. package/tests/hydration/compiled/server/html-in-template.js +64 -55
  55. package/tests/hydration/compiled/server/html.js +1477 -1360
  56. package/tests/hydration/compiled/server/if-children.js +448 -408
  57. package/tests/hydration/compiled/server/if.js +204 -171
  58. package/tests/hydration/compiled/server/mixed-control-flow.js +237 -195
  59. package/tests/hydration/compiled/server/nested-control-flow.js +533 -467
  60. package/tests/hydration/compiled/server/portal.js +94 -107
  61. package/tests/hydration/compiled/server/reactivity.js +87 -64
  62. package/tests/hydration/compiled/server/return.js +1424 -1174
  63. package/tests/hydration/compiled/server/switch.js +268 -238
  64. package/tests/hydration/compiled/server/try.js +98 -87
  65. package/tests/hydration/components/{mixed-control-flow.ripple → mixed-control-flow.rsrx} +2 -2
  66. package/tests/hydration/components/{try.ripple → try.rsrx} +4 -2
  67. package/tests/hydration/mixed-control-flow.test.js +14 -0
  68. package/tests/hydration/nested-control-flow.test.js +50 -48
  69. package/tests/hydration/try.test.js +25 -0
  70. package/tests/server/__snapshots__/compiler.test.ripple.snap +0 -32
  71. package/tests/server/__snapshots__/compiler.test.rsrx.snap +95 -0
  72. package/tests/server/{compiler.test.ripple → compiler.test.rsrx} +0 -17
  73. package/tests/server/{html-nesting-validation.test.ripple → html-nesting-validation.test.rsrx} +3 -3
  74. package/tests/server/streaming-ssr.test.rsrx +115 -0
  75. package/tests/server/try.test.rsrx +503 -0
  76. package/tests/utils/compiler-compat-config.test.js +3 -3
  77. package/tests/utils/vite-plugin-config.test.js +1 -1
  78. package/tests/utils/vite-plugin-hmr.test.js +5 -5
  79. package/tsconfig.json +2 -0
  80. package/types/index.d.ts +13 -23
  81. package/types/server.d.ts +43 -16
  82. package/tests/client/_etc.test.ripple +0 -5
  83. package/tests/client/async-suspend.test.ripple +0 -94
  84. package/tests/client/try.test.ripple +0 -196
  85. package/tests/server/streaming-ssr.test.ripple +0 -68
  86. package/tests/server/try.test.ripple +0 -82
  87. /package/tests/client/array/{array.copy-within.test.ripple → array.copy-within.test.rsrx} +0 -0
  88. /package/tests/client/array/{array.derived.test.ripple → array.derived.test.rsrx} +0 -0
  89. /package/tests/client/array/{array.iteration.test.ripple → array.iteration.test.rsrx} +0 -0
  90. /package/tests/client/array/{array.mutations.test.ripple → array.mutations.test.rsrx} +0 -0
  91. /package/tests/client/array/{array.to-methods.test.ripple → array.to-methods.test.rsrx} +0 -0
  92. /package/tests/client/basic/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
  93. /package/tests/client/basic/{basic.collections.test.ripple → basic.collections.test.rsrx} +0 -0
  94. /package/tests/client/basic/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
  95. /package/tests/client/basic/{basic.events.test.ripple → basic.events.test.rsrx} +0 -0
  96. /package/tests/client/basic/{basic.get-set.test.ripple → basic.get-set.test.rsrx} +0 -0
  97. /package/tests/client/basic/{basic.hmr.test.ripple → basic.hmr.test.rsrx} +0 -0
  98. /package/tests/client/basic/{basic.reactivity.test.ripple → basic.reactivity.test.rsrx} +0 -0
  99. /package/tests/client/basic/{basic.rendering.test.ripple → basic.rendering.test.rsrx} +0 -0
  100. /package/tests/client/basic/{basic.styling.test.ripple → basic.styling.test.rsrx} +0 -0
  101. /package/tests/client/basic/{basic.utilities.test.ripple → basic.utilities.test.rsrx} +0 -0
  102. /package/tests/client/{boundaries.test.ripple → boundaries.test.rsrx} +0 -0
  103. /package/tests/client/compiler/{compiler.assignments.test.ripple → compiler.assignments.test.rsrx} +0 -0
  104. /package/tests/client/compiler/{compiler.attributes.test.ripple → compiler.attributes.test.rsrx} +0 -0
  105. /package/tests/client/compiler/{compiler.basic.test.ripple → compiler.basic.test.rsrx} +0 -0
  106. /package/tests/client/compiler/{compiler.regex.test.ripple → compiler.regex.test.rsrx} +0 -0
  107. /package/tests/client/compiler/{compiler.tracked-access.test.ripple → compiler.tracked-access.test.rsrx} +0 -0
  108. /package/tests/client/compiler/{compiler.typescript.test.ripple → compiler.typescript.test.rsrx} +0 -0
  109. /package/tests/client/composite/{composite.dynamic-components.test.ripple → composite.dynamic-components.test.rsrx} +0 -0
  110. /package/tests/client/composite/{composite.generics.test.ripple → composite.generics.test.rsrx} +0 -0
  111. /package/tests/client/composite/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
  112. /package/tests/client/composite/{composite.reactivity.test.ripple → composite.reactivity.test.rsrx} +0 -0
  113. /package/tests/client/composite/{composite.render.test.ripple → composite.render.test.rsrx} +0 -0
  114. /package/tests/client/{computed-properties.test.ripple → computed-properties.test.rsrx} +0 -0
  115. /package/tests/client/{context.test.ripple → context.test.rsrx} +0 -0
  116. /package/tests/client/css/{global-additional-cases.test.ripple → global-additional-cases.test.rsrx} +0 -0
  117. /package/tests/client/css/{global-advanced-selectors.test.ripple → global-advanced-selectors.test.rsrx} +0 -0
  118. /package/tests/client/css/{global-at-rules.test.ripple → global-at-rules.test.rsrx} +0 -0
  119. /package/tests/client/css/{global-basic.test.ripple → global-basic.test.rsrx} +0 -0
  120. /package/tests/client/css/{global-classes-ids.test.ripple → global-classes-ids.test.rsrx} +0 -0
  121. /package/tests/client/css/{global-combinators.test.ripple → global-combinators.test.rsrx} +0 -0
  122. /package/tests/client/css/{global-complex-nesting.test.ripple → global-complex-nesting.test.rsrx} +0 -0
  123. /package/tests/client/css/{global-edge-cases.test.ripple → global-edge-cases.test.rsrx} +0 -0
  124. /package/tests/client/css/{global-keyframes.test.ripple → global-keyframes.test.rsrx} +0 -0
  125. /package/tests/client/css/{global-nested.test.ripple → global-nested.test.rsrx} +0 -0
  126. /package/tests/client/css/{global-pseudo.test.ripple → global-pseudo.test.rsrx} +0 -0
  127. /package/tests/client/css/{global-scoping.test.ripple → global-scoping.test.rsrx} +0 -0
  128. /package/tests/client/css/{style-identifier.test.ripple → style-identifier.test.rsrx} +0 -0
  129. /package/tests/client/{date.test.ripple → date.test.rsrx} +0 -0
  130. /package/tests/client/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
  131. /package/tests/client/{events.test.ripple → events.test.rsrx} +0 -0
  132. /package/tests/client/{for.test.ripple → for.test.rsrx} +0 -0
  133. /package/tests/client/{function-overload-import.ripple → function-overload-import.rsrx} +0 -0
  134. /package/tests/client/{head.test.ripple → head.test.rsrx} +0 -0
  135. /package/tests/client/{html.test.ripple → html.test.rsrx} +0 -0
  136. /package/tests/client/{input-value.test.ripple → input-value.test.rsrx} +0 -0
  137. /package/tests/client/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
  138. /package/tests/client/{map.test.ripple → map.test.rsrx} +0 -0
  139. /package/tests/client/{media-query.test.ripple → media-query.test.rsrx} +0 -0
  140. /package/tests/client/{object.test.ripple → object.test.rsrx} +0 -0
  141. /package/tests/client/{portal.test.ripple → portal.test.rsrx} +0 -0
  142. /package/tests/client/{ref.test.ripple → ref.test.rsrx} +0 -0
  143. /package/tests/client/{return.test.ripple → return.test.rsrx} +0 -0
  144. /package/tests/client/{set.test.ripple → set.test.rsrx} +0 -0
  145. /package/tests/client/{svg.test.ripple → svg.test.rsrx} +0 -0
  146. /package/tests/client/{switch.test.ripple → switch.test.rsrx} +0 -0
  147. /package/tests/client/{tsx.test.ripple → tsx.test.rsrx} +0 -0
  148. /package/tests/client/{typescript-generics.test.ripple → typescript-generics.test.rsrx} +0 -0
  149. /package/tests/client/url/{url.derived.test.ripple → url.derived.test.rsrx} +0 -0
  150. /package/tests/client/url/{url.parsing.test.ripple → url.parsing.test.rsrx} +0 -0
  151. /package/tests/client/url/{url.partial-removal.test.ripple → url.partial-removal.test.rsrx} +0 -0
  152. /package/tests/client/url/{url.reactivity.test.ripple → url.reactivity.test.rsrx} +0 -0
  153. /package/tests/client/url/{url.serialization.test.ripple → url.serialization.test.rsrx} +0 -0
  154. /package/tests/client/url-search-params/{url-search-params.derived.test.ripple → url-search-params.derived.test.rsrx} +0 -0
  155. /package/tests/client/url-search-params/{url-search-params.initialization.test.ripple → url-search-params.initialization.test.rsrx} +0 -0
  156. /package/tests/client/url-search-params/{url-search-params.iteration.test.ripple → url-search-params.iteration.test.rsrx} +0 -0
  157. /package/tests/client/url-search-params/{url-search-params.mutation.test.ripple → url-search-params.mutation.test.rsrx} +0 -0
  158. /package/tests/client/url-search-params/{url-search-params.retrieval.test.ripple → url-search-params.retrieval.test.rsrx} +0 -0
  159. /package/tests/client/url-search-params/{url-search-params.serialization.test.ripple → url-search-params.serialization.test.rsrx} +0 -0
  160. /package/tests/client/url-search-params/{url-search-params.tracked-url.test.ripple → url-search-params.tracked-url.test.rsrx} +0 -0
  161. /package/tests/hydration/components/{basic.ripple → basic.rsrx} +0 -0
  162. /package/tests/hydration/components/{composite.ripple → composite.rsrx} +0 -0
  163. /package/tests/hydration/components/{events.ripple → events.rsrx} +0 -0
  164. /package/tests/hydration/components/{for.ripple → for.rsrx} +0 -0
  165. /package/tests/hydration/components/{head.ripple → head.rsrx} +0 -0
  166. /package/tests/hydration/components/{hmr.ripple → hmr.rsrx} +0 -0
  167. /package/tests/hydration/components/{html-in-template.ripple → html-in-template.rsrx} +0 -0
  168. /package/tests/hydration/components/{html.ripple → html.rsrx} +0 -0
  169. /package/tests/hydration/components/{if-children.ripple → if-children.rsrx} +0 -0
  170. /package/tests/hydration/components/{if.ripple → if.rsrx} +0 -0
  171. /package/tests/hydration/components/{nested-control-flow.ripple → nested-control-flow.rsrx} +0 -0
  172. /package/tests/hydration/components/{portal.ripple → portal.rsrx} +0 -0
  173. /package/tests/hydration/components/{reactivity.ripple → reactivity.rsrx} +0 -0
  174. /package/tests/hydration/components/{return.ripple → return.rsrx} +0 -0
  175. /package/tests/hydration/components/{switch.ripple → switch.rsrx} +0 -0
  176. /package/tests/server/{await.test.ripple → await.test.rsrx} +0 -0
  177. /package/tests/server/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
  178. /package/tests/server/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
  179. /package/tests/server/{basic.test.ripple → basic.test.rsrx} +0 -0
  180. /package/tests/server/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
  181. /package/tests/server/{composite.test.ripple → composite.test.rsrx} +0 -0
  182. /package/tests/server/{context.test.ripple → context.test.rsrx} +0 -0
  183. /package/tests/server/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
  184. /package/tests/server/{for.test.ripple → for.test.rsrx} +0 -0
  185. /package/tests/server/{head.test.ripple → head.test.rsrx} +0 -0
  186. /package/tests/server/{if.test.ripple → if.test.rsrx} +0 -0
  187. /package/tests/server/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
  188. /package/tests/server/{return.test.ripple → return.test.rsrx} +0 -0
  189. /package/tests/server/{style-identifier.test.ripple → style-identifier.test.rsrx} +0 -0
  190. /package/tests/server/{switch.test.ripple → switch.test.rsrx} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # ripple
2
2
 
3
+ ## 0.3.13
4
+
5
+ ### Patch Changes
6
+
7
+ - [#842](https://github.com/Ripple-TS/ripple/pull/842)
8
+ [`4eb4d68`](https://github.com/Ripple-TS/ripple/commit/4eb4d6851573d771d65f1e85b1b442ad3cdc53d2)
9
+ Thanks [@leonidaz](https://github.com/leonidaz)! - fix(server): inject SSR web
10
+ stream sinks instead of creating node streams
11
+
12
+ - [#862](https://github.com/Ripple-TS/ripple/pull/862)
13
+ [`48af856`](https://github.com/Ripple-TS/ripple/commit/48af85678d5e1b32bb1c5e3fbb2fb07498bc88a3)
14
+ Thanks [@leonidaz](https://github.com/leonidaz)! - Add a release changeset for
15
+ the async tracking work introduced in commit
16
+ `4eb4d6851573d771d65f1e85b1b442ad3cdc53d2`.
17
+
18
+ This ships async tracking as a first-class feature in Ripple:
19
+ - remove and prohibit direct component-level `await`; async component flows now
20
+ require using `trackAsync()` (with `trackPending()` for pending state checks)
21
+ - add `trackAsync()` and `trackPending()` support so async values can be read
22
+ through Ripple's reactive runtime using tracked async values
23
+ - update compiler/runtime behavior for `try`/`catch`/`pending` boundaries so
24
+ async pending and error states can render and recover correctly in client and
25
+ SSR paths
26
+ - align `@ripple-ts/compat-react` async boundary behavior with the new Ripple
27
+ async tracking semantics
28
+ - update editor/tooling integration to match the new async syntax/runtime shape
29
+
30
+ - [`6e11177`](https://github.com/Ripple-TS/ripple/commit/6e111778cae4e7d9876e51e293520f0859eb5890)
31
+ Thanks [@trueadm](https://github.com/trueadm)! - Add `.rsrx` support across
32
+ Ripple tooling and rename the repository's tracked `.ripple` modules to `.rsrx`.
33
+ - Updated dependencies
34
+ [[`4eb4d68`](https://github.com/Ripple-TS/ripple/commit/4eb4d6851573d771d65f1e85b1b442ad3cdc53d2),
35
+ [`48af856`](https://github.com/Ripple-TS/ripple/commit/48af85678d5e1b32bb1c5e3fbb2fb07498bc88a3),
36
+ [`6e11177`](https://github.com/Ripple-TS/ripple/commit/6e111778cae4e7d9876e51e293520f0859eb5890)]:
37
+ - ripple@0.3.13
38
+
3
39
  ## 0.3.12
4
40
 
5
41
  ### Patch Changes
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Ripple is an elegant TypeScript UI framework",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.3.12",
6
+ "version": "0.3.13",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -64,9 +64,15 @@
64
64
  "./internal/client": {
65
65
  "default": "./src/runtime/internal/client/index.js"
66
66
  },
67
+ "./internal/client-types": {
68
+ "types": "./src/runtime/internal/client/types.d.ts"
69
+ },
67
70
  "./internal/server": {
68
71
  "default": "./src/runtime/internal/server/index.js"
69
72
  },
73
+ "./internal/server-types": {
74
+ "types": "./src/runtime/internal/server/types.d.ts"
75
+ },
70
76
  "./jsx-runtime": {
71
77
  "types": "./src/jsx-runtime.d.ts",
72
78
  "import": "./src/jsx-runtime.js",
@@ -105,6 +111,6 @@
105
111
  "vscode-languageserver-types": "^3.17.5"
106
112
  },
107
113
  "peerDependencies": {
108
- "ripple": "0.3.12"
114
+ "ripple": "0.3.13"
109
115
  }
110
116
  }
@@ -675,8 +675,7 @@ function RipplePlugin(config) {
675
675
  * Override isLet to recognize `let &{` and `let &[` as variable declarations.
676
676
  * Acorn's isLet checks the char after `let` and only recognizes `{`, `[`, or identifiers.
677
677
  * The `&` char (38) is not in that set, so `let &{...}` would not be parsed as a declaration.
678
- * @param {string} context
679
- * @returns {boolean}
678
+ * @type {Parse.Parser['isLet']}
680
679
  */
681
680
  isLet(context) {
682
681
  if (!this.isContextual('let')) return false;
@@ -1337,12 +1336,44 @@ function RipplePlugin(config) {
1337
1336
  const clause = /** @type {AST.CatchClause} */ (this.startNode());
1338
1337
  this.next();
1339
1338
  if (this.eat(tt.parenL)) {
1340
- clause.param = this.parseBindingAtom();
1339
+ // Parse first param (error) manually to support optional second param (reset).
1340
+ // We can't use parseCatchClauseParam() because it eats the closing paren.
1341
+ const param = this.parseBindingAtom();
1342
+ const simple = param.type === 'Identifier';
1343
+ this.enterScope(simple ? BINDING_TYPES.BIND_SIMPLE_CATCH : 0);
1344
+ this.checkLValPattern(
1345
+ param,
1346
+ simple ? BINDING_TYPES.BIND_SIMPLE_CATCH : BINDING_TYPES.BIND_LEXICAL,
1347
+ );
1348
+ const type = this.tsTryParseTypeAnnotation();
1349
+ if (type) {
1350
+ param.typeAnnotation = type;
1351
+ this.resetEndLocation(param);
1352
+ }
1353
+ clause.param = param;
1354
+
1355
+ // Optional second parameter: reset function
1356
+ if (this.eat(tt.comma)) {
1357
+ const reset_param = this.parseBindingAtom();
1358
+ this.checkLValSimple(reset_param, BINDING_TYPES.BIND_LEXICAL);
1359
+ const reset_type = this.tsTryParseTypeAnnotation();
1360
+ if (reset_type) {
1361
+ reset_param.typeAnnotation = reset_type;
1362
+ this.resetEndLocation(reset_param);
1363
+ }
1364
+ clause.resetParam = reset_param;
1365
+ } else {
1366
+ clause.resetParam = null;
1367
+ }
1368
+
1341
1369
  this.expect(tt.parenR);
1342
1370
  } else {
1343
1371
  clause.param = null;
1372
+ clause.resetParam = null;
1373
+ this.enterScope(0);
1344
1374
  }
1345
- clause.body = this.parseBlock();
1375
+ clause.body = this.parseBlock(false);
1376
+ this.exitScope();
1346
1377
  node.handler = this.finishNode(clause, 'CatchClause');
1347
1378
  }
1348
1379
  node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
@@ -2616,6 +2647,16 @@ function get_comment_handlers(source, comments, index = 0) {
2616
2647
  next();
2617
2648
 
2618
2649
  if (comments[0]) {
2650
+ if (node.type === 'Program' && node.body.length === 0) {
2651
+ // Collect all comments in an empty program (file with only comments)
2652
+ while (comments.length) {
2653
+ const comment = /** @type {AST.CommentWithLocation} */ (comments.shift());
2654
+ (node.innerComments ||= []).push(comment);
2655
+ }
2656
+ if (node.innerComments && node.innerComments.length > 0) {
2657
+ return;
2658
+ }
2659
+ }
2619
2660
  if (node.type === 'BlockStatement' && node.body.length === 0) {
2620
2661
  // Collect all comments that fall within this empty block
2621
2662
  while (
@@ -2674,32 +2715,34 @@ function get_comment_handlers(source, comments, index = 0) {
2674
2715
  let isArgument = false;
2675
2716
  let isSwitchCaseSibling = false;
2676
2717
 
2677
- if (
2678
- parent.type === 'BlockStatement' ||
2679
- parent.type === 'Program' ||
2680
- parent.type === 'Component' ||
2681
- parent.type === 'ClassBody'
2682
- ) {
2683
- node_array = parent.body;
2684
- } else if (parent.type === 'SwitchStatement') {
2685
- node_array = parent.cases;
2686
- isSwitchCaseSibling = true;
2687
- } else if (parent.type === 'SwitchCase') {
2688
- node_array = parent.consequent;
2689
- } else if (parent.type === 'ArrayExpression') {
2690
- node_array = parent.elements;
2691
- } else if (parent.type === 'ObjectExpression') {
2692
- node_array = parent.properties;
2693
- } else if (
2694
- parent.type === 'FunctionDeclaration' ||
2695
- parent.type === 'FunctionExpression' ||
2696
- parent.type === 'ArrowFunctionExpression'
2697
- ) {
2698
- node_array = parent.params;
2699
- isParam = true;
2700
- } else if (parent.type === 'CallExpression' || parent.type === 'NewExpression') {
2701
- node_array = parent.arguments;
2702
- isArgument = true;
2718
+ if (parent) {
2719
+ if (
2720
+ parent.type === 'BlockStatement' ||
2721
+ parent.type === 'Program' ||
2722
+ parent.type === 'Component' ||
2723
+ parent.type === 'ClassBody'
2724
+ ) {
2725
+ node_array = parent.body;
2726
+ } else if (parent.type === 'SwitchStatement') {
2727
+ node_array = parent.cases;
2728
+ isSwitchCaseSibling = true;
2729
+ } else if (parent.type === 'SwitchCase') {
2730
+ node_array = parent.consequent;
2731
+ } else if (parent.type === 'ArrayExpression') {
2732
+ node_array = parent.elements;
2733
+ } else if (parent.type === 'ObjectExpression') {
2734
+ node_array = parent.properties;
2735
+ } else if (
2736
+ parent.type === 'FunctionDeclaration' ||
2737
+ parent.type === 'FunctionExpression' ||
2738
+ parent.type === 'ArrowFunctionExpression'
2739
+ ) {
2740
+ node_array = parent.params;
2741
+ isParam = true;
2742
+ } else if (parent.type === 'CallExpression' || parent.type === 'NewExpression') {
2743
+ node_array = parent.arguments;
2744
+ isArgument = true;
2745
+ }
2703
2746
  }
2704
2747
 
2705
2748
  if (node_array && Array.isArray(node_array)) {
@@ -312,6 +312,7 @@ function setup_lazy_array_transforms(pattern, source_id, state, writable) {
312
312
 
313
313
  const actual = element.type === 'AssignmentPattern' ? element.left : element;
314
314
  const has_fallback = element.type === 'AssignmentPattern';
315
+ /** @type {AST.Expression | null} */
315
316
  const fallback_value = has_fallback
316
317
  ? /** @type {AST.AssignmentPattern} */ (element).right
317
318
  : null;
@@ -1127,7 +1128,7 @@ const visitors = {
1127
1128
  context.state.analysis.comments,
1128
1129
  );
1129
1130
  }
1130
- const metadata = { tracking: false, await: false };
1131
+ const metadata = { tracking: false };
1131
1132
 
1132
1133
  if (declarator.id.type === 'Identifier') {
1133
1134
  const binding = state.scope.get(declarator.id.name);
@@ -1136,10 +1137,14 @@ const visitors = {
1136
1137
  // Check if it's a call to `track` or `tracked`
1137
1138
  if (
1138
1139
  (callee.type === 'Identifier' &&
1139
- (callee.name === 'track' || callee.name === 'tracked')) ||
1140
+ (callee.name === 'track' ||
1141
+ callee.name === 'trackAsync' ||
1142
+ callee.name === 'tracked')) ||
1140
1143
  (callee.type === 'MemberExpression' &&
1141
1144
  callee.property.type === 'Identifier' &&
1142
- (callee.property.name === 'track' || callee.property.name === 'tracked'))
1145
+ (callee.property.name === 'track' ||
1146
+ callee.property.name === 'trackAsync' ||
1147
+ callee.property.name === 'tracked'))
1143
1148
  ) {
1144
1149
  binding.metadata = { ...binding.metadata, is_ripple_object: true };
1145
1150
  }
@@ -1153,9 +1158,10 @@ const visitors = {
1153
1158
  ) {
1154
1159
  const lazy_id = b.id(state.scope.generate('lazy'));
1155
1160
  const writable = node.kind !== 'const';
1156
- const init_is_track =
1161
+ const call_name =
1157
1162
  declarator.init?.type === 'CallExpression' &&
1158
- is_ripple_track_call(declarator.init.callee, context) === 'track';
1163
+ is_ripple_track_call(declarator.init.callee, context);
1164
+ const init_is_track = call_name === 'track' || call_name === 'trackAsync';
1159
1165
  setup_lazy_transforms(declarator.id, lazy_id, state, writable, !!init_is_track);
1160
1166
  // Store the generated identifier name on the pattern for the transform phase
1161
1167
  declarator.id.metadata = { ...declarator.id.metadata, lazy_id: lazy_id.name };
@@ -1267,7 +1273,6 @@ const visitors = {
1267
1273
 
1268
1274
  // Track metadata for this component
1269
1275
  const metadata = {
1270
- await: false,
1271
1276
  styleClasses: /** @type {StyleClasses} */ (new Map()),
1272
1277
  };
1273
1278
 
@@ -1317,7 +1322,6 @@ const visitors = {
1317
1322
  if (node.id) {
1318
1323
  context.state.analysis.component_metadata.push({
1319
1324
  id: node.id.name,
1320
- async: metadata.await,
1321
1325
  });
1322
1326
  }
1323
1327
  },
@@ -1352,14 +1356,13 @@ const visitors = {
1352
1356
  node.metadata = {
1353
1357
  ...node.metadata,
1354
1358
  has_template: false,
1355
- has_await: false,
1356
1359
  };
1357
1360
 
1358
1361
  context.visit(switch_case, context.state);
1359
1362
 
1360
- if (!node.metadata.has_template && !node.metadata.has_await) {
1363
+ if (!node.metadata.has_template) {
1361
1364
  error(
1362
- 'Component switch statements must contain a template or an await expression in each of their cases. Move the switch statement into an effect if it does not render anything.',
1365
+ 'Component switch statements must contain a template in each of their cases. Move the switch statement into an effect if it does not render anything.',
1363
1366
  context.state.analysis.module.filename,
1364
1367
  switch_case,
1365
1368
  context.state.loose ? context.state.analysis.errors : undefined,
@@ -1427,13 +1430,12 @@ const visitors = {
1427
1430
  node.metadata = {
1428
1431
  ...node.metadata,
1429
1432
  has_template: false,
1430
- has_await: false,
1431
1433
  };
1432
1434
  context.next();
1433
1435
 
1434
- if (!node.metadata.has_template && !node.metadata.has_await) {
1436
+ if (!node.metadata.has_template) {
1435
1437
  error(
1436
- 'Component for...of loops must contain a template or an await expression in their body. Move the for loop into an effect if it does not render anything.',
1438
+ 'Component for...of loops must contain a template in their body. Move the for loop into an effect if it does not render anything.',
1437
1439
  context.state.analysis.module.filename,
1438
1440
  node.body,
1439
1441
  context.state.loose ? context.state.analysis.errors : undefined,
@@ -1567,7 +1569,6 @@ const visitors = {
1567
1569
  node.metadata = {
1568
1570
  ...node.metadata,
1569
1571
  has_template: false,
1570
- has_await: false,
1571
1572
  has_throw: false,
1572
1573
  };
1573
1574
 
@@ -1604,7 +1605,6 @@ const visitors = {
1604
1605
  const saved_has_return = node.metadata.has_return;
1605
1606
  const saved_returns = node.metadata.returns;
1606
1607
  node.metadata.has_template = false;
1607
- node.metadata.has_await = false;
1608
1608
  node.metadata.has_throw = false;
1609
1609
  context.visit(node.alternate, context.state);
1610
1610
 
@@ -1711,11 +1711,6 @@ const visitors = {
1711
1711
  }
1712
1712
 
1713
1713
  if (node.pending) {
1714
- // Try/pending blocks indicate async operations
1715
- if (state.metadata?.await === false) {
1716
- state.metadata.await = true;
1717
- }
1718
-
1719
1714
  node.metadata = {
1720
1715
  ...node.metadata,
1721
1716
  has_template: false,
@@ -1749,6 +1744,8 @@ const visitors = {
1749
1744
  context.state.analysis.comments,
1750
1745
  );
1751
1746
  }
1747
+ } else {
1748
+ context.visit(node.block, state);
1752
1749
  }
1753
1750
 
1754
1751
  if (node.handler) {
@@ -2109,16 +2106,6 @@ const visitors = {
2109
2106
  RippleExpression(node, context) {
2110
2107
  mark_control_flow_has_template(context.path);
2111
2108
 
2112
- if (expression_has_side_effects(node.expression)) {
2113
- error(
2114
- 'Template expressions must not contain side effects.',
2115
- context.state.analysis.module.filename,
2116
- node.expression,
2117
- context.state.loose ? context.state.analysis.errors : undefined,
2118
- context.state.analysis.comments,
2119
- );
2120
- }
2121
-
2122
2109
  context.next();
2123
2110
  },
2124
2111
 
@@ -2142,40 +2129,23 @@ const visitors = {
2142
2129
  const parent_block = get_parent_block_node(context);
2143
2130
 
2144
2131
  if (is_inside_component(context)) {
2145
- if (context.state.metadata?.await === false) {
2146
- context.state.metadata.await = true;
2147
- }
2148
-
2149
- if (
2150
- parent_block !== null &&
2151
- parent_block?.type !== 'Component' &&
2152
- !context.state.ancestor_server_block &&
2153
- !(
2154
- parent_block.type === 'TryStatement' &&
2155
- parent_block.pending &&
2156
- is_inside_try_block(parent_block, context)
2157
- )
2158
- ) {
2159
- // we want the error to live on the `await` keyword vs the whole expression
2160
- const adjusted_node /** @type {AST.AwaitExpression} */ = {
2161
- ...node,
2162
- end: /** @type {AST.NodeWithLocation} */ (node).start + 'await'.length,
2163
- };
2164
- error(
2165
- '`await` is not allowed in client-side control-flow statements',
2166
- context.state.analysis.module.filename,
2167
- adjusted_node,
2168
- context.state.loose ? context.state.analysis.errors : undefined,
2169
- context.state.analysis.comments,
2170
- );
2171
- }
2132
+ const adjusted_node /** @type {AST.AwaitExpression} */ = {
2133
+ ...node,
2134
+ end: /** @type {AST.NodeWithLocation} */ (node).start + 'await'.length,
2135
+ };
2136
+ error(
2137
+ '`await` is not allowed inside client components. Use `trackAsync(() => ...)` with an upstream `try { ... } pending { ... }` boundary instead.',
2138
+ context.state.analysis.module.filename,
2139
+ adjusted_node,
2140
+ context.state.loose ? context.state.analysis.errors : undefined,
2141
+ context.state.analysis.comments,
2142
+ );
2172
2143
  }
2173
2144
 
2174
2145
  if (parent_block) {
2175
2146
  if (!parent_block.metadata) {
2176
2147
  parent_block.metadata = { path: [...context.path] };
2177
2148
  }
2178
- parent_block.metadata.has_await = true;
2179
2149
  }
2180
2150
 
2181
2151
  context.next();