@tsrx/core 0.1.13 → 0.1.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.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Core compiler infrastructure for TSRX syntax",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.1.13",
6
+ "version": "0.1.14",
7
7
  "type": "module",
8
8
  "repository": {
9
9
  "type": "git",
package/src/index.js CHANGED
@@ -142,6 +142,7 @@ export { escape, escape_script as escapeScript } from './utils/escaping.js';
142
142
 
143
143
  // Transform
144
144
  export {
145
+ add_ref_target_type_to_ref_prop_attributes as addRefTargetTypeToRefPropAttributes,
145
146
  add_jsx_setup_declaration as addJsxSetupDeclaration,
146
147
  clone_switch_helper_invocation as cloneSwitchHelperInvocation,
147
148
  collect_param_bindings as collectParamBindings,
@@ -149,12 +150,15 @@ export {
149
150
  create_hook_safe_helper as createHookSafeHelper,
150
151
  create_host_html_attribute as createHostHtmlAttribute,
151
152
  create_host_html_conflict_error as createHostHtmlConflictError,
153
+ create_element_ref_target_type as createElementRefTargetType,
154
+ create_element_ref_target_type_for_name as createElementRefTargetTypeForName,
152
155
  createJsxTransform,
153
156
  CREATE_REF_PROP_INTERNAL_NAME,
154
157
  extract_jsx_setup_declarations as extractJsxSetupDeclarations,
155
158
  get_host_html_conflicting_attribute as getHostHtmlConflictingAttribute,
156
159
  get_invalid_html_child_error_message as getInvalidHtmlChildErrorMessage,
157
160
  is_component_like_element,
161
+ is_ref_expression_attribute_value as isRefExpressionAttributeValue,
158
162
  is_ref_prop_expression as isRefPropExpression,
159
163
  MERGE_REFS_INTERNAL_NAME,
160
164
  merge_duplicate_refs as mergeDuplicateRefs,
@@ -55,3 +55,37 @@ export function array_slice(array_like, ...args) {
55
55
  ? array_like.slice(...args)
56
56
  : array_prototype.slice.call(array_like, ...args);
57
57
  }
58
+
59
+ /**
60
+ * Converts iterables, iterators, and array-like values to an array from an index.
61
+ * @template T
62
+ * @param {Iterable<T> | Iterator<T> | ArrayLike<T>} iterable
63
+ * @param {number} [index]
64
+ * @returns {T[]}
65
+ */
66
+ export function iterable_array_from(iterable, index = 0) {
67
+ /** @type {Iterator<T>} */
68
+ var iterator;
69
+ var iterable_prop = /** @type {Iterable<T>} */ (iterable)[Symbol.iterator];
70
+
71
+ if (typeof iterable_prop === 'function') {
72
+ iterator = iterable_prop.call(iterable);
73
+ } else if (typeof (/** @type {Iterator<T>} */ (iterable).next) === 'function') {
74
+ iterator = Iterator.from(/** @type {Iterator<T>} */ (iterable));
75
+ } else {
76
+ return array_from(/** @type {ArrayLike<T>} */ (iterable)).slice(index);
77
+ }
78
+
79
+ var result = [];
80
+ var i = 0;
81
+ var current = iterator.next();
82
+ while (!current.done) {
83
+ if (i++ < index) {
84
+ current = iterator.next();
85
+ continue;
86
+ }
87
+ result.push(current.value);
88
+ current = iterator.next();
89
+ }
90
+ return result;
91
+ }
@@ -570,6 +570,12 @@ export function createJsxTransform(platform) {
570
570
  !is_component,
571
571
  transform_context,
572
572
  );
573
+ if (transform_context.typeOnly) {
574
+ add_ref_target_type_to_ref_prop_attributes(
575
+ attrs,
576
+ !is_component ? create_element_ref_target_type(visited) : null,
577
+ );
578
+ }
573
579
  return {
574
580
  ...visited,
575
581
  attributes: merge_duplicate_refs(
@@ -5174,12 +5180,43 @@ function transform_element_attributes_dispatch(attrs, transform_context, element
5174
5180
  const result = hook
5175
5181
  ? hook(attrs, transform_context, element)
5176
5182
  : attrs.map((/** @type {any} */ a) => to_jsx_attribute(a, transform_context));
5183
+ if (transform_context.typeOnly) {
5184
+ add_ref_target_type_to_ref_prop_attributes(
5185
+ result,
5186
+ !is_component ? create_element_ref_target_type(element) : null,
5187
+ );
5188
+ }
5177
5189
  return merge_duplicate_refs(
5178
5190
  normalize_host_ref_spreads(result, !is_component, transform_context),
5179
5191
  transform_context,
5180
5192
  );
5181
5193
  }
5182
5194
 
5195
+ /**
5196
+ * @param {any[]} attrs
5197
+ * @param {AST.TypeNode | null} ref_target_type
5198
+ * @returns {void}
5199
+ */
5200
+ export function add_ref_target_type_to_ref_prop_attributes(attrs, ref_target_type) {
5201
+ if (!ref_target_type) return;
5202
+ for (const attr of attrs) {
5203
+ const expression =
5204
+ attr?.type === 'JSXAttribute' &&
5205
+ attr.value?.type === 'JSXExpressionContainer' &&
5206
+ attr.value.expression?.type !== 'JSXEmptyExpression'
5207
+ ? attr.value.expression
5208
+ : null;
5209
+ if (
5210
+ expression?.type === 'CallExpression' &&
5211
+ expression.callee?.type === 'Identifier' &&
5212
+ expression.callee.name === CREATE_REF_PROP_INTERNAL_NAME &&
5213
+ !expression.typeArguments
5214
+ ) {
5215
+ expression.typeArguments = b.ts_type_parameter_instantiation([ref_target_type]);
5216
+ }
5217
+ }
5218
+ }
5219
+
5183
5220
  /**
5184
5221
  * @param {any} element
5185
5222
  * @returns {boolean}
@@ -5597,6 +5634,115 @@ export const NORMALIZE_SPREAD_PROPS_INTERNAL_NAME = '__normalize_spread_props';
5597
5634
  export const MAP_ITERABLE_INTERNAL_NAME = '__map_iterable';
5598
5635
  export const ITERATION_VALUE_INTERNAL_NAME = '__IterationValue';
5599
5636
 
5637
+ const HTML_REF_TAG_NAMES = new Set(
5638
+ 'a abbr address area article aside audio b base bdi bdo blockquote body br button canvas caption cite code col colgroup data datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins kbd label legend li link main map mark menu meta meter nav noscript object ol optgroup option output p picture pre progress q rp rt ruby s samp script search section select slot small source span strong style sub summary sup table tbody td template textarea tfoot th thead time title tr track u ul var video wbr'.split(
5639
+ ' ',
5640
+ ),
5641
+ );
5642
+
5643
+ const SVG_REF_TAG_NAMES = new Set(
5644
+ 'a animate animateMotion animateTransform circle clipPath defs desc ellipse feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feDropShadow feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence filter foreignObject g image line linearGradient marker mask metadata mpath path pattern polygon polyline radialGradient rect script set stop style svg switch symbol text textPath title tspan use view'.split(
5645
+ ' ',
5646
+ ),
5647
+ );
5648
+
5649
+ const MATHML_REF_TAG_NAMES = new Set(
5650
+ 'annotation annotation-xml maction math merror mfrac mi mmultiscripts mn mo mover mpadded mphantom mprescripts mroot mrow ms mspace msqrt mstyle msub msubsup msup mtable mtd mtext mtr munder munderover semantics'.split(
5651
+ ' ',
5652
+ ),
5653
+ );
5654
+
5655
+ /**
5656
+ * @param {any} value
5657
+ * @returns {boolean}
5658
+ */
5659
+ export function is_ref_expression_attribute_value(value) {
5660
+ return (
5661
+ value?.type === 'RefExpression' ||
5662
+ (value?.type === 'JSXExpressionContainer' && value.expression?.type === 'RefExpression')
5663
+ );
5664
+ }
5665
+
5666
+ /**
5667
+ * @param {any} element
5668
+ * @param {'html' | 'svg' | 'mathml'} [namespace]
5669
+ * @returns {AST.TypeNode | null}
5670
+ */
5671
+ export function create_element_ref_target_type(element, namespace) {
5672
+ const tag_name = get_element_ref_tag_name(element);
5673
+ return tag_name === null ? null : create_element_ref_target_type_for_name(tag_name, namespace);
5674
+ }
5675
+
5676
+ /**
5677
+ * @param {string} tag_name
5678
+ * @param {'html' | 'svg' | 'mathml'} [namespace]
5679
+ * @returns {AST.TypeNode}
5680
+ */
5681
+ export function create_element_ref_target_type_for_name(tag_name, namespace = 'html') {
5682
+ const resolved_namespace =
5683
+ tag_name === 'svg'
5684
+ ? 'svg'
5685
+ : tag_name === 'math'
5686
+ ? 'mathml'
5687
+ : namespace === 'html'
5688
+ ? infer_ref_namespace(tag_name)
5689
+ : namespace;
5690
+
5691
+ if (resolved_namespace === 'svg') {
5692
+ return SVG_REF_TAG_NAMES.has(tag_name)
5693
+ ? create_tag_name_map_ref_type('SVGElementTagNameMap', tag_name)
5694
+ : b.ts_type_reference(b.id('SVGElement'));
5695
+ }
5696
+ if (resolved_namespace === 'mathml') {
5697
+ return MATHML_REF_TAG_NAMES.has(tag_name)
5698
+ ? create_tag_name_map_ref_type('MathMLElementTagNameMap', tag_name)
5699
+ : b.ts_type_reference(b.id('MathMLElement'));
5700
+ }
5701
+ return HTML_REF_TAG_NAMES.has(tag_name)
5702
+ ? create_tag_name_map_ref_type('HTMLElementTagNameMap', tag_name)
5703
+ : b.ts_type_reference(b.id('HTMLElement'));
5704
+ }
5705
+
5706
+ /**
5707
+ * @param {string} tag_name
5708
+ * @returns {'html' | 'svg' | 'mathml'}
5709
+ */
5710
+ function infer_ref_namespace(tag_name) {
5711
+ if (HTML_REF_TAG_NAMES.has(tag_name)) return 'html';
5712
+ if (SVG_REF_TAG_NAMES.has(tag_name)) return 'svg';
5713
+ if (MATHML_REF_TAG_NAMES.has(tag_name)) return 'mathml';
5714
+ return 'html';
5715
+ }
5716
+
5717
+ /**
5718
+ * @param {any} element
5719
+ * @returns {string | null}
5720
+ */
5721
+ function get_element_ref_tag_name(element) {
5722
+ const id = element?.id;
5723
+ if (id?.type === 'Identifier') return id.name;
5724
+ const name = element?.name;
5725
+ if (name?.type === 'JSXIdentifier') return name.name;
5726
+ if (element?.openingElement?.name?.type === 'JSXIdentifier') {
5727
+ return element.openingElement.name.name;
5728
+ }
5729
+ return null;
5730
+ }
5731
+
5732
+ /**
5733
+ * @param {string} map_name
5734
+ * @param {string} tag_name
5735
+ * @returns {AST.TypeNode}
5736
+ */
5737
+ function create_tag_name_map_ref_type(map_name, tag_name) {
5738
+ return /** @type {AST.TypeNode} */ ({
5739
+ type: 'TSIndexedAccessType',
5740
+ objectType: b.ts_type_reference(b.id(map_name)),
5741
+ indexType: b.ts_literal_type(b.literal(tag_name)),
5742
+ metadata: { path: [] },
5743
+ });
5744
+ }
5745
+
5600
5746
  /**
5601
5747
  * @param {any} attr
5602
5748
  * @param {TransformContext} transform_context
package/types/index.d.ts CHANGED
@@ -827,7 +827,7 @@ declare module 'estree' {
827
827
  interface TSBooleanKeyword extends AcornTSNode<TSESTree.TSBooleanKeyword> {}
828
828
  interface TSCallSignatureDeclaration extends Omit<
829
829
  AcornTSNode<TSESTree.TSCallSignatureDeclaration>,
830
- 'typeParameters' | 'typeAnnotation'
830
+ 'typeParameters' | 'params' | 'returnType'
831
831
  > {
832
832
  parameters: Parameter[];
833
833
  typeParameters: TSTypeParameterDeclaration | undefined;
@@ -844,7 +844,7 @@ declare module 'estree' {
844
844
  }
845
845
  interface TSConstructorType extends Omit<
846
846
  AcornTSNode<TSESTree.TSConstructorType>,
847
- 'typeParameters' | 'params'
847
+ 'typeParameters' | 'params' | 'returnType'
848
848
  > {
849
849
  typeAnnotation: TSTypeAnnotation | undefined;
850
850
  typeParameters: TSTypeParameterDeclaration | undefined;
@@ -852,7 +852,7 @@ declare module 'estree' {
852
852
  }
853
853
  interface TSConstructSignatureDeclaration extends Omit<
854
854
  AcornTSNode<TSESTree.TSConstructSignatureDeclaration>,
855
- 'typeParameters' | 'typeAnnotation'
855
+ 'typeParameters' | 'params' | 'returnType'
856
856
  > {
857
857
  parameters: Parameter[];
858
858
  typeParameters: TSTypeParameterDeclaration | undefined;
@@ -892,7 +892,7 @@ declare module 'estree' {
892
892
  }
893
893
  interface TSFunctionType extends Omit<
894
894
  AcornTSNode<TSESTree.TSFunctionType>,
895
- 'typeParameters' | 'params'
895
+ 'typeParameters' | 'params' | 'returnType'
896
896
  > {
897
897
  typeAnnotation: TSTypeAnnotation | undefined;
898
898
  typeParameters: TSTypeParameterDeclaration | undefined;
@@ -961,7 +961,7 @@ declare module 'estree' {
961
961
  }
962
962
  interface TSMethodSignature extends Omit<
963
963
  AcornTSNode<TSESTree.TSMethodSignature>,
964
- 'key' | 'typeParameters' | 'params' | 'typeAnnotation'
964
+ 'key' | 'typeParameters' | 'params' | 'returnType'
965
965
  > {
966
966
  key: PropertyNameComputed | PropertyNameNonComputed;
967
967
  typeParameters: TSTypeParameterDeclaration | undefined;
@@ -1264,6 +1264,10 @@ export interface Binding {
1264
1264
  pattern?: AST.Identifier;
1265
1265
  is_ripple_object?: boolean;
1266
1266
  is_template_value?: boolean;
1267
+ lazy_array_source?: string;
1268
+ lazy_array_index?: number;
1269
+ lazy_array_source_tracked?: boolean;
1270
+ lazy_array_rest?: boolean;
1267
1271
  } | null;
1268
1272
  /** Kind of binding */
1269
1273
  kind: BindingKind;
@@ -1457,6 +1461,7 @@ export interface TransformClientState extends BaseState {
1457
1461
  return_flags?: Map<AST.ReturnStatement, { name: string; tracked: boolean }>;
1458
1462
  is_tsrx_element?: boolean;
1459
1463
  jsx_to_tsrx_element?: boolean;
1464
+ ref_target_type?: AST.TypeNode;
1460
1465
  }
1461
1466
 
1462
1467
  /** Override zimmerframe types and provide our own */
@@ -15,3 +15,7 @@ export const has_own_property: typeof Object.prototype.hasOwnProperty;
15
15
 
16
16
  export function has_prototype_accessor(value: object, key: PropertyKey): boolean;
17
17
  export function array_slice(array_like: ArrayLike<any>, ...args: number[]): any[];
18
+ export function iterable_array_from<T>(
19
+ iterable: Iterable<T> | Iterator<T> | ArrayLike<T>,
20
+ index?: number,
21
+ ): T[];
@@ -4,6 +4,13 @@ export type MergeableRefCallback<T> = {
4
4
  export type MergeableRefObject<T> = { current: T | null };
5
5
  export type MergeableVueRef<T> = { value: T | null };
6
6
  export type RefProp<T = unknown> = (node: T | null) => void | (() => void);
7
+ export type RefValue<T = Element> =
8
+ | ((node: T) => void | (() => void))
9
+ | { current: T | null }
10
+ | { value: T | null }
11
+ | T
12
+ | null
13
+ | undefined;
7
14
 
8
15
  export type MergeableRef<T> =
9
16
  | MergeableRefCallback<T>
@@ -14,9 +21,9 @@ export type MergeableRef<T> =
14
21
 
15
22
  export function mergeRefs<T = any>(...refs: Array<MergeableRef<T>>): (node: T | null) => () => void;
16
23
  export function isRefProp(value: unknown): boolean;
17
- export function create_ref_prop<T>(
18
- get_ref_value: () => T,
19
- set_ref_value?: (value: T) => void,
24
+ export function create_ref_prop<T = Element>(
25
+ get_ref_value: () => RefValue<T>,
26
+ set_ref_value?: (value: any) => void,
20
27
  ): RefProp<T>;
21
28
  export function apply_ref_value<T>(
22
29
  ref_value: unknown,