@tsrx/solid 0.0.25 → 0.0.27

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.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Solid compiler built on @tsrx/core",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.0.25",
6
+ "version": "0.0.27",
7
7
  "type": "module",
8
8
  "publishConfig": {
9
9
  "access": "public"
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "esrap": "^2.1.0",
24
24
  "zimmerframe": "^1.1.2",
25
- "@tsrx/core": "0.0.25"
25
+ "@tsrx/core": "0.0.27"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "solid-js": ">=1.8 || >=2.0.0-beta"
package/src/index.js CHANGED
@@ -22,7 +22,7 @@ export function parse(source, filename, options) {
22
22
  * @param {string} source
23
23
  * @param {string} [filename]
24
24
  * @param {{ collect?: boolean, loose?: boolean }} [options]
25
- * @returns {{ code: string, map: any, css: { code: string, hash: string } | null, errors: CompileError[] }}
25
+ * @returns {{ code: string, map: any, css: string, cssHash: string | null, errors: CompileError[] }}
26
26
  */
27
27
  export function compile(source, filename, options) {
28
28
  const errors = /** @type {CompileError[]} */ ([]);
@@ -63,6 +63,7 @@ export function compile_to_volar_mappings(source, filename, options) {
63
63
  const transformed = transform(ast, source, filename, {
64
64
  collect: true,
65
65
  loose: !!options?.loose,
66
+ typeOnly: true,
66
67
  errors,
67
68
  comments,
68
69
  });
package/src/transform.js CHANGED
@@ -26,6 +26,7 @@ import {
26
26
  flatten_switch_consequent,
27
27
  get_for_of_iteration_params,
28
28
  identifier_to_jsx_name,
29
+ is_bare_render_expression,
29
30
  is_dynamic_element_id,
30
31
  is_jsx_child,
31
32
  set_loc,
@@ -176,7 +177,11 @@ function component_to_function_declaration(component, transform_context) {
176
177
  const params = component.params || [];
177
178
  const body = /** @type {any[]} */ (component.body || []);
178
179
 
179
- const lazy_bindings = collect_lazy_bindings_from_component(params, body, transform_context);
180
+ // In type-only mode the lazy rewrite is skipped so destructuring patterns
181
+ // survive into the virtual TSX and TypeScript can flow real types.
182
+ const lazy_bindings = transform_context.typeOnly
183
+ ? new Map()
184
+ : collect_lazy_bindings_from_component(params, body, transform_context);
180
185
 
181
186
  // Detect top-level early-return patterns such as `if (cond) { return; }`
182
187
  // and `if (cond) { <p />; return; }`.
@@ -233,6 +238,10 @@ function component_to_function_declaration(component, transform_context) {
233
238
  const collect = (nodes, outer, jsx_bucket) => {
234
239
  for (const child of nodes) {
235
240
  if (is_jsx_child(child)) {
241
+ if (get_returning_if_info(child) !== null) {
242
+ jsx_bucket.push(child);
243
+ continue;
244
+ }
236
245
  if (early_interleaved) {
237
246
  const jsx = to_jsx_child(child, transform_context);
238
247
  if (is_capturable_jsx_child(jsx)) {
@@ -260,11 +269,11 @@ function component_to_function_declaration(component, transform_context) {
260
269
  transform_context.needs_show = true;
261
270
  const branch_body = body_to_jsx_child(early_info.consequent_body, transform_context);
262
271
  const fallback_body =
263
- after_jsx.length > 0 ? body_to_jsx_child(after_jsx, transform_context) : null;
272
+ after_jsx.length > 0 ? body_to_early_return_jsx_child(after_jsx, transform_context) : null;
264
273
  next_body.push(build_show_element(early_if.test, branch_body, fallback_body));
265
274
  } else if (after_jsx.length > 0) {
266
275
  transform_context.needs_show = true;
267
- const show_body = body_to_jsx_child(after_jsx, transform_context);
276
+ const show_body = body_to_early_return_jsx_child(after_jsx, transform_context);
268
277
  next_body.push(build_show_element(negate_expression(early_if.test), show_body, null));
269
278
  }
270
279
 
@@ -286,6 +295,8 @@ function component_to_function_declaration(component, transform_context) {
286
295
  } else {
287
296
  render_nodes.push(jsx);
288
297
  }
298
+ } else if (is_bare_render_expression(child)) {
299
+ render_nodes.push(to_jsx_expression_container(child, child));
289
300
  } else {
290
301
  statements.push(child);
291
302
  }
@@ -478,6 +489,8 @@ function body_to_jsx_child(body_nodes, transform_context) {
478
489
  } else {
479
490
  children.push(jsx);
480
491
  }
492
+ } else if (is_bare_render_expression(child)) {
493
+ children.push(to_jsx_expression_container(child, child));
481
494
  } else {
482
495
  statements.push(child);
483
496
  }
@@ -522,6 +535,45 @@ function body_to_jsx_child(body_nodes, transform_context) {
522
535
  });
523
536
  }
524
537
 
538
+ /**
539
+ * Lower render-continuation bodies that may contain additional early-return
540
+ * guards. Sequential guards need to nest the remaining continuation instead
541
+ * of rendering later children beside a `<Show>` for the guard itself.
542
+ *
543
+ * @param {any[]} body_nodes
544
+ * @param {TransformContext} transform_context
545
+ * @returns {any}
546
+ */
547
+ function body_to_early_return_jsx_child(body_nodes, transform_context) {
548
+ const early_idx = body_nodes.findIndex((node) => get_returning_if_info(node) !== null);
549
+ if (early_idx === -1) {
550
+ return body_to_jsx_child(body_nodes, transform_context);
551
+ }
552
+
553
+ const early_if = /** @type {any} */ (body_nodes[early_idx]);
554
+ const early_info = /** @type {{ consequent_body: any[], return_index: number }} */ (
555
+ get_returning_if_info(early_if)
556
+ );
557
+ const before = body_nodes.slice(0, early_idx);
558
+ const after = body_nodes.slice(early_idx + 1);
559
+ const branch_has_content_before_return = early_info.return_index > 0;
560
+ const children = [...before];
561
+
562
+ if (branch_has_content_before_return) {
563
+ transform_context.needs_show = true;
564
+ const branch_body = body_to_jsx_child(early_info.consequent_body, transform_context);
565
+ const fallback_body =
566
+ after.length > 0 ? body_to_early_return_jsx_child(after, transform_context) : null;
567
+ children.push(build_show_element(early_if.test, branch_body, fallback_body));
568
+ } else if (after.length > 0) {
569
+ transform_context.needs_show = true;
570
+ const show_body = body_to_early_return_jsx_child(after, transform_context);
571
+ children.push(build_show_element(negate_expression(early_if.test), show_body, null));
572
+ }
573
+
574
+ return body_to_jsx_child(children, transform_context);
575
+ }
576
+
525
577
  /**
526
578
  * @param {any} node
527
579
  * @returns {boolean}
@@ -618,6 +670,8 @@ function loop_body_to_callback_statements(body_nodes, transform_context) {
618
670
 
619
671
  if (is_jsx_child(child)) {
620
672
  children.push(to_jsx_child(child, transform_context));
673
+ } else if (is_bare_render_expression(child)) {
674
+ children.push(to_jsx_expression_container(child, child));
621
675
  } else {
622
676
  statements.push(child);
623
677
  }
@@ -825,11 +879,15 @@ function get_returning_if_info(node) {
825
879
  * @returns {any}
826
880
  */
827
881
  function negate_expression(expr) {
882
+ if (expr?.type === 'UnaryExpression' && expr.operator === '!') {
883
+ return clone_expression_node(expr.argument);
884
+ }
885
+
828
886
  return {
829
887
  type: 'UnaryExpression',
830
888
  operator: '!',
831
889
  prefix: true,
832
- argument: expr,
890
+ argument: clone_expression_node(expr),
833
891
  metadata: { path: [] },
834
892
  };
835
893
  }
package/types/index.d.ts CHANGED
@@ -1,21 +1,8 @@
1
1
  import type { Program } from 'estree';
2
- import type { CompileError, ParseOptions, VolarMappingsResult } from '@tsrx/core/types';
2
+ import type { CompileFn, ParseOptions, VolarCompileFn } from '@tsrx/core/types';
3
3
 
4
4
  export function parse(source: string, filename?: string, options?: ParseOptions): Program;
5
5
 
6
- export function compile(
7
- source: string,
8
- filename?: string,
9
- options?: { collect?: boolean; loose?: boolean },
10
- ): {
11
- code: string;
12
- map: unknown;
13
- css: { code: string; hash: string } | null;
14
- errors: CompileError[];
15
- };
6
+ export const compile: CompileFn;
16
7
 
17
- export function compile_to_volar_mappings(
18
- source: string,
19
- filename?: string,
20
- options?: ParseOptions,
21
- ): VolarMappingsResult;
8
+ export const compile_to_volar_mappings: VolarCompileFn;