@tsrx/core 0.0.6 → 0.0.7
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 +1 -1
- package/src/index.js +7 -0
- package/src/transform/jsx-hoist.js +119 -0
- package/types/index.d.ts +11 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -164,6 +164,13 @@ export {
|
|
|
164
164
|
is_capturable_jsx_child as isCapturableJsxChild,
|
|
165
165
|
capture_jsx_child as captureJsxChild,
|
|
166
166
|
} from './transform/jsx-interleave.js';
|
|
167
|
+
export {
|
|
168
|
+
is_static_literal as isStaticLiteral,
|
|
169
|
+
is_hoist_safe_expression as isHoistSafeExpression,
|
|
170
|
+
is_hoist_safe_jsx_child as isHoistSafeJsxChild,
|
|
171
|
+
is_hoist_safe_jsx_attribute as isHoistSafeJsxAttribute,
|
|
172
|
+
is_hoist_safe_jsx_node as isHoistSafeJsxNode,
|
|
173
|
+
} from './transform/jsx-hoist.js';
|
|
167
174
|
|
|
168
175
|
// Analyze
|
|
169
176
|
export { analyze_css as analyzeCss } from './analyze/css-analyze.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** @import * as ESTreeJSX from 'estree-jsx' */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Predicates that decide whether a JSX subtree can be safely hoisted out of a
|
|
5
|
+
* component body into a module-level `const`. A subtree is hoist-safe only
|
|
6
|
+
* when evaluating it at module-load time produces the same value as
|
|
7
|
+
* evaluating it on every render — i.e. it contains no identifier references,
|
|
8
|
+
* no calls, no spreads, and no other render-time expressions.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {import('estree').Literal} node
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
15
|
+
export function is_static_literal(node) {
|
|
16
|
+
return (
|
|
17
|
+
node.value === null ||
|
|
18
|
+
typeof node.value === 'string' ||
|
|
19
|
+
typeof node.value === 'number' ||
|
|
20
|
+
typeof node.value === 'boolean' ||
|
|
21
|
+
typeof node.value === 'bigint'
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {any} node
|
|
27
|
+
* @returns {boolean}
|
|
28
|
+
*/
|
|
29
|
+
export function is_hoist_safe_expression(node) {
|
|
30
|
+
if (!node || typeof node !== 'object') return false;
|
|
31
|
+
|
|
32
|
+
switch (node.type) {
|
|
33
|
+
case 'Literal':
|
|
34
|
+
return is_static_literal(node);
|
|
35
|
+
case 'TemplateLiteral':
|
|
36
|
+
return node.expressions.length === 0;
|
|
37
|
+
case 'UnaryExpression':
|
|
38
|
+
return node.operator !== 'delete' && is_hoist_safe_expression(node.argument);
|
|
39
|
+
case 'BinaryExpression':
|
|
40
|
+
case 'LogicalExpression':
|
|
41
|
+
return is_hoist_safe_expression(node.left) && is_hoist_safe_expression(node.right);
|
|
42
|
+
case 'ConditionalExpression':
|
|
43
|
+
return (
|
|
44
|
+
is_hoist_safe_expression(node.test) &&
|
|
45
|
+
is_hoist_safe_expression(node.consequent) &&
|
|
46
|
+
is_hoist_safe_expression(node.alternate)
|
|
47
|
+
);
|
|
48
|
+
case 'SequenceExpression':
|
|
49
|
+
return node.expressions.every(is_hoist_safe_expression);
|
|
50
|
+
case 'ParenthesizedExpression':
|
|
51
|
+
return is_hoist_safe_expression(node.expression);
|
|
52
|
+
case 'JSXElement':
|
|
53
|
+
return is_hoist_safe_jsx_node(node);
|
|
54
|
+
case 'JSXFragment':
|
|
55
|
+
return node.children.every(is_hoist_safe_jsx_child);
|
|
56
|
+
default:
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {any} node
|
|
63
|
+
* @returns {boolean}
|
|
64
|
+
*/
|
|
65
|
+
export function is_hoist_safe_jsx_child(node) {
|
|
66
|
+
if (!node || typeof node !== 'object') return false;
|
|
67
|
+
|
|
68
|
+
switch (node.type) {
|
|
69
|
+
case 'JSXText':
|
|
70
|
+
return true;
|
|
71
|
+
case 'JSXElement':
|
|
72
|
+
return is_hoist_safe_jsx_node(node);
|
|
73
|
+
case 'JSXFragment':
|
|
74
|
+
return node.children.every(is_hoist_safe_jsx_child);
|
|
75
|
+
case 'JSXExpressionContainer':
|
|
76
|
+
return (
|
|
77
|
+
node.expression.type !== 'JSXEmptyExpression' && is_hoist_safe_expression(node.expression)
|
|
78
|
+
);
|
|
79
|
+
default:
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {ESTreeJSX.JSXAttribute | ESTreeJSX.JSXSpreadAttribute} attribute
|
|
86
|
+
* @returns {boolean}
|
|
87
|
+
*/
|
|
88
|
+
export function is_hoist_safe_jsx_attribute(attribute) {
|
|
89
|
+
if (attribute.type === 'JSXSpreadAttribute') return false;
|
|
90
|
+
if (attribute.value == null) return true;
|
|
91
|
+
|
|
92
|
+
if (attribute.value.type === 'Literal') {
|
|
93
|
+
return is_static_literal(attribute.value);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (attribute.value.type === 'JSXExpressionContainer') {
|
|
97
|
+
return (
|
|
98
|
+
attribute.value.expression.type !== 'JSXEmptyExpression' &&
|
|
99
|
+
is_hoist_safe_expression(attribute.value.expression)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {ESTreeJSX.JSXElement | ESTreeJSX.JSXFragment} node
|
|
108
|
+
* @returns {boolean}
|
|
109
|
+
*/
|
|
110
|
+
export function is_hoist_safe_jsx_node(node) {
|
|
111
|
+
if (node.type === 'JSXFragment') {
|
|
112
|
+
return node.children.every(is_hoist_safe_jsx_child);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
node.openingElement.attributes.every(is_hoist_safe_jsx_attribute) &&
|
|
117
|
+
node.children.every(is_hoist_safe_jsx_child)
|
|
118
|
+
);
|
|
119
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -98,6 +98,12 @@ declare module 'estree' {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
interface SimpleCallExpression {
|
|
102
|
+
metadata: BaseNodeMetaData & {
|
|
103
|
+
hash?: string;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
101
107
|
type Accessibility = 'public' | 'protected' | 'private'; // missing in acorn-typescript types
|
|
102
108
|
interface MethodDefinition {
|
|
103
109
|
typeParameters?: TSTypeParameterDeclaration;
|
|
@@ -1335,6 +1341,11 @@ export interface AnalysisState extends BaseState {
|
|
|
1335
1341
|
styleClasses?: StyleClasses;
|
|
1336
1342
|
};
|
|
1337
1343
|
mode: CompileOptions['mode'];
|
|
1344
|
+
// keep this as an object as we destructure
|
|
1345
|
+
module: {
|
|
1346
|
+
// Incremented counter for generating unique track/trackAsync hashes
|
|
1347
|
+
track_id: number;
|
|
1348
|
+
};
|
|
1338
1349
|
}
|
|
1339
1350
|
|
|
1340
1351
|
export interface TransformServerState extends BaseState {
|