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
@@ -28,7 +28,7 @@ describe('vite-plugin-ripple hotUpdate', () => {
28
28
  },
29
29
  },
30
30
  {
31
- file: '/workspace/src/non-component.ripple',
31
+ file: '/workspace/src/non-component.rsrx',
32
32
  modules: [{ id: 'client:non-component', isSelfAccepting: false }],
33
33
  server: {
34
34
  environments: {
@@ -43,8 +43,8 @@ describe('vite-plugin-ripple hotUpdate', () => {
43
43
  },
44
44
  );
45
45
 
46
- expect(transform_request).toHaveBeenCalledWith('/src/non-component.ripple');
47
- expect(get_ssr_modules).toHaveBeenCalledWith('/workspace/src/non-component.ripple');
46
+ expect(transform_request).toHaveBeenCalledWith('/src/non-component.rsrx');
47
+ expect(get_ssr_modules).toHaveBeenCalledWith('/workspace/src/non-component.rsrx');
48
48
  expect(invalidate_ssr_module).toHaveBeenCalledTimes(2);
49
49
  expect(send_hot_update).toHaveBeenCalledWith({ type: 'full-reload' });
50
50
  expect(result).toEqual([]);
@@ -74,7 +74,7 @@ describe('vite-plugin-ripple hotUpdate', () => {
74
74
  },
75
75
  },
76
76
  {
77
- file: '/workspace/src/component.ripple',
77
+ file: '/workspace/src/component.rsrx',
78
78
  modules: [{ id: 'client:component', isSelfAccepting: true }],
79
79
  server: {
80
80
  environments: {
@@ -89,7 +89,7 @@ describe('vite-plugin-ripple hotUpdate', () => {
89
89
  },
90
90
  );
91
91
 
92
- expect(transform_request).toHaveBeenCalledWith('/src/component.ripple');
92
+ expect(transform_request).toHaveBeenCalledWith('/src/component.rsrx');
93
93
  expect(get_ssr_modules).not.toHaveBeenCalled();
94
94
  expect(invalidate_ssr_module).not.toHaveBeenCalled();
95
95
  expect(send_hot_update).not.toHaveBeenCalled();
package/tsconfig.json CHANGED
@@ -26,8 +26,10 @@
26
26
  "./*.js",
27
27
  "./src/",
28
28
  "./tests/**/*.test.ripple",
29
+ "./tests/**/*.test.rsrx",
29
30
  "./tests/**/*.test.tsrx",
30
31
  "./tests/**/*.ripple",
32
+ "./tests/**/*.rsrx",
31
33
  "./tests/**/*.tsrx",
32
34
  "./tests/**/*.d.ts",
33
35
  "./tests/**/*.js"
package/types/index.d.ts CHANGED
@@ -141,18 +141,21 @@ declare global {
141
141
 
142
142
  export function createRefKey(): symbol;
143
143
 
144
+ export const UNINITIALIZED: unique symbol;
145
+ export const DERIVED_UPDATED: unique symbol;
146
+ export const SUSPENSE_PENDING: unique symbol;
147
+ export const SUSPENSE_REJECTED: unique symbol;
148
+
144
149
  // Base Tracked interface - all tracked values have a '#v' property containing the actual value
145
150
  interface TrackedBase<V> {
146
151
  '#v': V;
147
152
  value: V;
148
153
  }
149
-
150
154
  // Augment Tracked to be callable when V is a Component
151
155
  // This allows <@Something /> to work in JSX when Something is Tracked<Component>
152
156
  interface TrackedCallable<V> {
153
157
  (props: V extends Component<infer P> ? P : never): V extends Component ? void : never;
154
158
  }
155
-
156
159
  // Supports indexed access: track(0)[0] → value, track(0)[1] → Tracked<V>
157
160
  // And destructuring `const [one, two] = track(0);`
158
161
  export type Tracked<V> = [V, Tracked<V>] & TrackedBase<V> & TrackedCallable<V>;
@@ -188,6 +191,14 @@ export function track<V>(
188
191
  // Overload for non-function values
189
192
  export function track<V>(value?: V, get?: (v: V) => V, set?: (next: V, prev: V) => V): Tracked<V>;
190
193
 
194
+ export function trackAsync<V>(
195
+ value: () => PromiseLike<V> | { promise: PromiseLike<V>; abortController: AbortController },
196
+ ): Tracked<V>;
197
+
198
+ export function trackPending<V>(value: Tracked<V> | (() => any)): boolean;
199
+
200
+ export function peek<V>(tracked: Tracked<V>): V;
201
+
191
202
  export interface AddEventOptions extends ExtendedEventOptions {
192
203
  customName?: string;
193
204
  }
@@ -531,24 +542,3 @@ export function bindFiles<V extends FileList>(
531
542
  tracked: Tracked<V | null | undefined> | GetFunction<V | null | undefined>,
532
543
  setter?: SetFunction<V>,
533
544
  ): (node: HTMLInputElement) => void;
534
-
535
- type ServerBlock = {};
536
-
537
- export interface RippleNamespace {
538
- array: RippleArrayCallable;
539
- object: RippleObjectCallable;
540
- context: ContextCallable;
541
- date: RippleDateCallable;
542
- effect: typeof effect;
543
- map: RippleMapCallable;
544
- mediaQuery: MediaQueryCallable;
545
- set: RippleSetCallable;
546
- url: RippleURLCallable;
547
- urlSearchParams: RippleURLSearchParamsCallable;
548
- untrack: typeof untrack;
549
- track: typeof track;
550
- style: Record<string, string>;
551
- server: ServerBlock;
552
- }
553
-
554
- export declare const ripple_namespace: RippleNamespace;
package/types/server.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type { Props } from '#public';
2
- import type { Readable } from 'node:stream';
1
+ import type { Component } from '#public';
3
2
 
4
3
  // Re-export runtime types for server-compiled components
5
4
  export {
@@ -17,28 +16,56 @@ export {
17
16
  RippleURLSearchParams,
18
17
  } from './index.js';
19
18
 
20
- export interface SSRRenderOutput {
19
+ export interface RenderResult {
21
20
  head: string;
22
21
  body: string;
23
22
  css: Set<string>;
23
+ topLevelError?: Error | null;
24
+ }
25
+
26
+ export interface RenderStreamResult {
27
+ stream: StreamSink;
28
+ topLevelError?: Error | null;
29
+ }
30
+
31
+ export interface StreamSink {
24
32
  push(chunk: string): void;
25
- register_css(hash: string): void;
33
+ close(): void;
34
+ error(reason: unknown): void;
26
35
  }
27
36
 
28
- export interface SSRComponent {
29
- (output: SSRRenderOutput, props?: Props): void | Promise<void>;
30
- async?: boolean;
37
+ export type WebStream = ReadableStream<Uint8Array>;
38
+
39
+ export interface Stream {
40
+ controller: ReadableStreamDefaultController<Uint8Array>;
41
+ textEncoder: TextEncoder;
42
+ stream: WebStream;
43
+ sink: StreamSink;
31
44
  }
32
45
 
33
- export interface SSRRenderResult {
34
- head: string;
35
- body: string;
36
- css: Set<string>;
46
+ export interface BaseRenderOptions {
47
+ stream?: StreamSink;
48
+ // defaults to true
49
+ // set to false to add more content
50
+ closeStream?: boolean;
51
+ }
52
+
53
+ export interface StreamingRenderOptions extends BaseRenderOptions {
54
+ stream: StreamSink;
37
55
  }
38
56
 
39
- export type SSRRender = (component: SSRComponent) => Promise<SSRRenderResult>;
40
- export type render = (component: SSRComponent) => Promise<SSRRenderResult>;
41
- export type renderToStream = (component: SSRComponent) => Readable;
57
+ export interface RenderOptions extends BaseRenderOptions {
58
+ stream?: undefined;
59
+ }
60
+
61
+ export declare function create_ssr_stream(): Stream;
62
+
63
+ export declare function render(
64
+ component: Component,
65
+ options?: RenderOptions,
66
+ ): Promise<RenderResult>;
42
67
 
43
- export const render: render;
44
- export const renderToStream: renderToStream;
68
+ export declare function render(
69
+ component: Component,
70
+ options: StreamingRenderOptions,
71
+ ): Promise<RenderStreamResult>;
@@ -1,91 +0,0 @@
1
- /**
2
- * @import * as AST from 'estree'
3
- */
4
-
5
- /**
6
- * Check if a comment is a TypeScript pragma (line comment)
7
- * @param {AST.CommentWithLocation} comment
8
- * @returns {boolean}
9
- */
10
- export function is_ts_pragma(comment) {
11
- if (comment.type !== 'Line') return false;
12
-
13
- const pragmas = ['@ts-ignore', '@ts-expect-error', '@ts-nocheck', '@ts-check'];
14
- return pragmas.some((pragma) => comment.value.trimStart().startsWith(pragma));
15
- }
16
-
17
- /**
18
- * Check if a comment is a triple-slash directive
19
- * /// <reference path="..." />
20
- * @param {AST.CommentWithLocation} comment
21
- * @returns {boolean}
22
- */
23
- export function is_triple_slash_directive(comment) {
24
- if (comment.type !== 'Line') return false;
25
-
26
- // Triple slash directives start with / after the // is stripped
27
- // So the value should start with / followed by <reference, <amd-module, or <amd-dependency
28
- const value = comment.value.trim();
29
- return /^\/\s*<(reference|amd-module|amd-dependency)/.test(value);
30
- }
31
-
32
- /**
33
- * Check if a comment is a JSDoc comment with TypeScript annotations
34
- * Examples: block comments containing `@type`, `@typedef`, `@param`, `@returns`, etc.
35
- * @param {AST.CommentWithLocation} comment
36
- * @returns {boolean}
37
- */
38
- export function is_jsdoc_ts_annotation(comment) {
39
- if (comment.type !== 'Block') return false;
40
-
41
- // JSDoc comments start with /** which means the value starts with * after /* is stripped
42
- if (!comment.value.startsWith('*')) return false;
43
-
44
- // Check if it contains TypeScript-relevant tags
45
- const tsAnnotations = [
46
- '@type',
47
- '@typedef',
48
- '@param',
49
- '@returns',
50
- '@template',
51
- '@extends',
52
- '@implements',
53
- '@satisfies',
54
- '@overload',
55
- '@import',
56
- ];
57
-
58
- return tsAnnotations.some((annotation) => comment.value.includes(annotation));
59
- }
60
-
61
- /**
62
- * Check if a comment should be preserved in to_ts mode
63
- * @param {AST.CommentWithLocation} comment
64
- * @returns {boolean}
65
- */
66
- export function should_preserve_comment(comment) {
67
- return (
68
- is_ts_pragma(comment) || is_triple_slash_directive(comment) || is_jsdoc_ts_annotation(comment)
69
- );
70
- }
71
-
72
- /**
73
- * Format a comment for output
74
- * @param {AST.CommentWithLocation} comment
75
- * @returns {string}
76
- */
77
- export function format_comment(comment) {
78
- if (comment.type === 'Line') {
79
- // Check if it's a triple-slash directive (value starts with /)
80
- if (comment.value.trimStart().startsWith('/')) {
81
- return `/// ${comment.value.trimStart().slice(1)}`;
82
- }
83
- return `// ${comment.value.trim()}`;
84
- } else {
85
- // Block comment - check if it's a JSDoc (value starts with *)
86
- if (comment.value.startsWith('*')) {
87
- return `/** ${comment.value.trim().slice(1)} */`;
88
- }
89
- return `/* ${comment.value.trim()} */`;
90
- }
91
- }
@@ -1,77 +0,0 @@
1
- /**
2
- @import * as AST from 'estree';
3
- @import { RippleCompileError } from 'ripple/compiler';
4
- */
5
-
6
- /**
7
- *
8
- * @param {string} message
9
- * @param {string | null} filename
10
- * @param {AST.Node | AST.NodeWithLocation} node
11
- * @param {RippleCompileError[]} [errors]
12
- * @param {AST.CommentWithLocation[]} [comments]
13
- * @returns {void}
14
- */
15
- export function error(message, filename, node, errors, comments) {
16
- if (errors && comments && is_ripple_error_suppressed(node, comments)) {
17
- return;
18
- }
19
-
20
- const error = /** @type {RippleCompileError} */ (new Error(message));
21
-
22
- // same as the acorn compiler error
23
- error.pos = node.start ?? undefined;
24
- error.raisedAt = node.end ?? undefined;
25
-
26
- // custom properties
27
- error.fileName = filename;
28
- error.end = node.end ?? undefined;
29
- error.loc = !node.loc
30
- ? undefined
31
- : {
32
- start: {
33
- line: node.loc.start.line,
34
- column: node.loc.start.column,
35
- },
36
- end: {
37
- line: node.loc.end.line,
38
- column: node.loc.end.column,
39
- },
40
- };
41
-
42
- if (errors) {
43
- error.type = 'usage';
44
- errors.push(error);
45
- return;
46
- }
47
-
48
- error.type = 'fatal';
49
- throw error;
50
- }
51
-
52
- /**
53
- * @param {AST.CommentWithLocation} comment
54
- * @return {boolean}
55
- */
56
- function is_ripple_error_suppress_comment(comment) {
57
- const text = comment.value.trim();
58
- return text.startsWith('@ripple-ignore') || text.startsWith('@ripple-expect-error');
59
- }
60
-
61
- /**
62
- * @param {AST.Node | AST.NodeWithLocation} node
63
- * @param {AST.CommentWithLocation[]} comments
64
- */
65
- function is_ripple_error_suppressed(node, comments) {
66
- if (node.loc) {
67
- const node_start_line = node.loc.start.line;
68
- for (const comment of comments) {
69
- if (comment.type === 'Line' && comment.loc.start.line === node_start_line - 1) {
70
- if (is_ripple_error_suppress_comment(comment)) {
71
- return true;
72
- }
73
- }
74
- }
75
- }
76
- return false;
77
- }
@@ -1,80 +0,0 @@
1
- export const IDENTIFIER_OBFUSCATION_PREFIX = '_$_';
2
- export const STYLE_IDENTIFIER = IDENTIFIER_OBFUSCATION_PREFIX + encode_utf16_char('#') + 'style';
3
- export const SERVER_IDENTIFIER = IDENTIFIER_OBFUSCATION_PREFIX + encode_utf16_char('#') + 'server';
4
- export const CSS_HASH_IDENTIFIER = IDENTIFIER_OBFUSCATION_PREFIX + 'hash';
5
-
6
- const DECODE_UTF16_REGEX = /_u([0-9a-fA-F]{4})_/g;
7
-
8
- /**
9
- * @param {string} char
10
- * @returns {string}
11
- */
12
- function encode_utf16_char(char) {
13
- return `_u${('0000' + char.charCodeAt(0).toString(16)).slice(-4)}_`;
14
- }
15
-
16
- /**
17
- * Finds the next uppercase character or returns name.length
18
- * @param {string} name
19
- * @param {number} start
20
- * @returns {number}
21
- */
22
- function find_next_uppercase(name, start) {
23
- for (let i = start; i < name.length; i++) {
24
- if (name[i] === name[i].toUpperCase()) {
25
- return i;
26
- }
27
- }
28
- return name.length;
29
- }
30
-
31
- /**
32
- * @param {string} encoded
33
- * @returns {string}
34
- */
35
- function decode_utf16_string(encoded) {
36
- return encoded.replace(DECODE_UTF16_REGEX, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
37
- }
38
-
39
- /**
40
- * @param {string} name
41
- * @returns {string}
42
- */
43
- export function obfuscate_identifier(name) {
44
- const first_char = name[0];
45
- let start = 0;
46
- if (first_char === '@' || first_char === '#') {
47
- const encoded = encode_utf16_char(first_char);
48
- name = encoded + name.slice(1);
49
- start = encoded.length;
50
- } else if (first_char === first_char.toUpperCase()) {
51
- start = 1;
52
- }
53
- const index = find_next_uppercase(name, start);
54
-
55
- const first_part = name.slice(0, index);
56
- const second_part = name.slice(index);
57
-
58
- return (
59
- IDENTIFIER_OBFUSCATION_PREFIX +
60
- (second_part ? second_part + '__' + first_part : first_part + '__')
61
- );
62
- }
63
-
64
- /**
65
- * @param {string} name
66
- * @returns {boolean}
67
- */
68
- export function is_identifier_obfuscated(name) {
69
- return name.startsWith(IDENTIFIER_OBFUSCATION_PREFIX);
70
- }
71
-
72
- /**
73
- * @param {string} name
74
- * @returns {string}
75
- */
76
- export function deobfuscate_identifier(name) {
77
- name = name.replaceAll(IDENTIFIER_OBFUSCATION_PREFIX, '');
78
- const parts = name.split('__');
79
- return decode_utf16_string((parts[1] ? parts[1] : '') + parts[0]);
80
- }
@@ -1,127 +0,0 @@
1
- import type * as AST from 'estree';
2
- import type {
3
- CodeInformation as VolarCodeInformation,
4
- Mapping as VolarMapping,
5
- } from '@volar/language-core';
6
- import type { DocumentHighlightKind } from 'vscode-languageserver-types';
7
- import type { RawSourceMap } from 'source-map';
8
-
9
- // ============================================================================
10
- // Compiler API Exports
11
- // ============================================================================
12
- /**
13
- * Result of compilation operation
14
- */
15
- export interface CompileResult {
16
- /** The transformed AST */
17
- ast: AST.Program;
18
- /** The generated JavaScript code with source map */
19
- js: {
20
- code: string;
21
- map: RawSourceMap;
22
- };
23
- /** The generated CSS */
24
- css: string;
25
- }
26
-
27
- export interface DefinitionLocation {
28
- embeddedId: string; // e.g., 'style_0', 'style_1'
29
- start: number; // start offset
30
- end: number; // end offset
31
- }
32
-
33
- export interface PluginActionOverrides {
34
- /** Whether to enable word document highlighting for this mapping */
35
- wordHighlight?: {
36
- kind: DocumentHighlightKind;
37
- };
38
- /** TypeScript diagnostic codes to suppress for this mapping */
39
- suppressedDiagnostics?: number[];
40
- /** Custom hover documentation for this mapping, false to disable */
41
- hover?: string | false | ((content: string) => string);
42
- /** Custom definition info for this mapping, false to disable */
43
- definition?:
44
- | {
45
- description?: string; // just for reference
46
- // Generic location for embedded content (CSS, etc.)
47
- location?: DefinitionLocation;
48
- // Replace the type name in hover/definition with a different name
49
- // And provide the path to import the type definitions from
50
- // the `ripple` package directory, e.g. `types/index.d.ts`
51
- // Currently only supported by the definition plugin
52
- typeReplace?: {
53
- name: string;
54
- path: string;
55
- };
56
- }
57
- | false;
58
- }
59
-
60
- export interface CustomMappingData extends PluginActionOverrides {
61
- embeddedId?: string; // e.g. css regions: 'style_0', 'style_1', etc.
62
- content?: string; // (e.g., css code)
63
- }
64
-
65
- export interface MappingData extends VolarCodeInformation {
66
- customData: CustomMappingData;
67
- }
68
-
69
- export interface CodeMapping extends Omit<VolarMapping<MappingData>, 'generatedLengths'> {
70
- generatedLengths: number[];
71
- data: MappingData;
72
- }
73
-
74
- export interface VolarMappingsResult {
75
- code: string;
76
- mappings: CodeMapping[];
77
- cssMappings: CodeMapping[];
78
- errors: RippleCompileError[];
79
- }
80
-
81
- export interface RippleCompileError extends Error {
82
- pos: number | undefined;
83
- raisedAt: number | undefined;
84
- end: number | undefined;
85
- loc: AST.SourceLocation | undefined;
86
- fileName: string | null;
87
- type: 'fatal' | 'usage';
88
- }
89
-
90
- /**
91
- * Compilation options
92
- */
93
-
94
- interface SharedCompileOptions {
95
- minify_css?: boolean;
96
- dev?: boolean;
97
- }
98
- export interface CompileOptions extends SharedCompileOptions {
99
- mode?: 'client' | 'server';
100
- hmr?: boolean;
101
- compat_kinds?: string[];
102
- }
103
-
104
- export interface ParseOptions {
105
- loose?: boolean;
106
- errors?: RippleCompileError[];
107
- comments?: AST.CommentWithLocation[];
108
- }
109
-
110
- export interface AnalyzeOptions
111
- extends ParseOptions, Pick<CompileOptions, 'mode' | 'compat_kinds'> {
112
- errors?: RippleCompileError[];
113
- to_ts?: boolean;
114
- }
115
-
116
- export interface VolarCompileOptions
117
- extends Omit<ParseOptions, 'errors' | 'comments'>, SharedCompileOptions {}
118
-
119
- export function parse(source: string, options?: ParseOptions): AST.Program;
120
-
121
- export function compile(source: string, filename: string, options?: CompileOptions): CompileResult;
122
-
123
- export function compile_to_volar_mappings(
124
- source: string,
125
- filename: string,
126
- options?: VolarCompileOptions,
127
- ): VolarMappingsResult;
@@ -1,89 +0,0 @@
1
- /** @import * as AST from 'estree' */
2
-
3
- import { parse as parse_module } from './phases/1-parse/index.js';
4
- import { analyze } from './phases/2-analyze/index.js';
5
- import { transform_client } from './phases/3-transform/client/index.js';
6
- import { transform_server } from './phases/3-transform/server/index.js';
7
- import { convert_source_map_to_mappings } from './phases/3-transform/segments.js';
8
-
9
- /**
10
- * Parse Ripple source code to ESTree AST
11
- * @param {string} source
12
- * @returns {AST.Program}
13
- */
14
- export function parse(source) {
15
- return parse_module(source, undefined, undefined);
16
- }
17
-
18
- /**
19
- * Compile Ripple source code to JS/CSS output
20
- * @param {string} source
21
- * @param {string} filename
22
- * @param {CompileOptions} [options]
23
- * @returns {object}
24
- */
25
- export function compile(source, filename, options = {}) {
26
- const ast = parse_module(source, filename, undefined);
27
- const analysis = analyze(ast, filename, options);
28
- const result =
29
- options.mode === 'server'
30
- ? transform_server(
31
- filename,
32
- source,
33
- analysis,
34
- options?.minify_css ?? false,
35
- options?.dev ?? false,
36
- )
37
- : transform_client(
38
- filename,
39
- source,
40
- analysis,
41
- false,
42
- options?.minify_css ?? false,
43
- options?.hmr ?? false,
44
- );
45
-
46
- return result;
47
- }
48
-
49
- /** @import { PostProcessingChanges, LineOffsets } from './phases/3-transform/client/index.js' */
50
- /** @import { VolarMappingsResult, VolarCompileOptions, CompileOptions, RippleCompileError } from 'ripple/compiler' */
51
-
52
- /**
53
- * Compile Ripple component to Volar virtual code with TypeScript mappings
54
- * @param {string} source
55
- * @param {string} filename
56
- * @param {VolarCompileOptions} [options] - Compiler options
57
- * @returns {VolarMappingsResult} Volar mappings object
58
- */
59
- export function compile_to_volar_mappings(source, filename, options = {}) {
60
- const errors = /** @type {RippleCompileError[]} */ ([]);
61
- const comments = /** @type {AST.CommentWithLocation[]} */ ([]);
62
- const ast = parse_module(source, filename, { ...options, errors, comments });
63
- const analysis = analyze(ast, filename, {
64
- to_ts: true,
65
- loose: !!options?.loose,
66
- errors,
67
- comments,
68
- });
69
- const transformed = transform_client(
70
- filename,
71
- source,
72
- analysis,
73
- true,
74
- options?.minify_css ?? false,
75
- );
76
-
77
- return {
78
- ...convert_source_map_to_mappings(
79
- transformed.ast,
80
- ast,
81
- source,
82
- transformed.js.code,
83
- transformed.js.map,
84
- /** @type {PostProcessingChanges} */ (transformed.js.post_processing_changes),
85
- /** @type {LineOffsets} */ (transformed.js.line_offsets),
86
- ),
87
- errors: transformed.errors,
88
- };
89
- }