@tsrx/core 0.1.16 → 0.1.17
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/README.md +4 -3
- package/package.json +1 -1
- package/src/analyze/prune.js +13 -28
- package/src/analyze/validation.js +27 -94
- package/src/diagnostics.js +1 -3
- package/src/index.js +18 -28
- package/src/parse/index.js +37 -4
- package/src/plugin.js +182 -644
- package/src/runtime/ref.js +48 -0
- package/src/scope.js +0 -13
- package/src/transform/await.js +1 -1
- package/src/transform/jsx/ast-builders.js +3 -5
- package/src/transform/jsx/helpers.js +1 -2
- package/src/transform/jsx/index.js +1257 -1491
- package/src/transform/lazy.js +6 -6
- package/src/transform/scoping.js +1 -2
- package/src/transform/segments.js +26 -157
- package/src/transform/style-ref.js +235 -0
- package/src/utils/ast.js +15 -23
- package/src/utils/builders.js +0 -18
- package/types/index.d.ts +32 -74
- package/types/jsx-platform.d.ts +20 -28
- package/types/parse.d.ts +2 -15
- package/types/runtime/ref.d.ts +3 -0
package/src/runtime/ref.js
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
has_own_property,
|
|
3
3
|
get_descriptor,
|
|
4
4
|
has_prototype_accessor,
|
|
5
|
+
is_array,
|
|
5
6
|
} from '@tsrx/core/runtime/language-helpers';
|
|
6
7
|
|
|
7
8
|
const REF_VALUE = Symbol();
|
|
@@ -65,6 +66,25 @@ function is_ref_prop(value) {
|
|
|
65
66
|
* @returns {void | (() => void)}
|
|
66
67
|
*/
|
|
67
68
|
export function apply_ref_value(ref_value, node, set_ref_value) {
|
|
69
|
+
if (is_array(ref_value)) {
|
|
70
|
+
/** @type {Array<() => void>} */
|
|
71
|
+
const cleanups = [];
|
|
72
|
+
for (const item of ref_value) {
|
|
73
|
+
const cleanup = apply_ref_value(item, node);
|
|
74
|
+
if (typeof cleanup === 'function') {
|
|
75
|
+
cleanups.push(cleanup);
|
|
76
|
+
} else if (typeof item === 'function' && node !== null) {
|
|
77
|
+
cleanups.push(() => item(null));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (cleanups.length > 0) {
|
|
81
|
+
return () => {
|
|
82
|
+
for (const cleanup of cleanups) cleanup();
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
68
88
|
if (typeof ref_value === 'function') {
|
|
69
89
|
return ref_value(node);
|
|
70
90
|
}
|
|
@@ -217,6 +237,34 @@ export function normalize_spread_props(props, ...outer_refs) {
|
|
|
217
237
|
return next;
|
|
218
238
|
}
|
|
219
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Normalize spread props for targets that read refs through an explicit
|
|
242
|
+
* `ref={normalized.ref}` attribute. The returned `ref` stays readable for that
|
|
243
|
+
* attribute but is non-enumerable so `{...normalized}` does not also pass it as
|
|
244
|
+
* a DOM prop.
|
|
245
|
+
*
|
|
246
|
+
* @param {Record<string | symbol, any> | null | undefined} props
|
|
247
|
+
* @param {...any} outer_refs
|
|
248
|
+
* @returns {Record<string | symbol, any> | null | undefined}
|
|
249
|
+
*/
|
|
250
|
+
export function normalize_spread_props_for_ref_attr(props, ...outer_refs) {
|
|
251
|
+
const next = normalize_spread_props(props, ...outer_refs);
|
|
252
|
+
if (next == null || !has_own_property.call(next, 'ref')) {
|
|
253
|
+
return next;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const ref = next.ref;
|
|
257
|
+
const without_ref = { ...next };
|
|
258
|
+
delete without_ref.ref;
|
|
259
|
+
Object.defineProperty(without_ref, 'ref', {
|
|
260
|
+
value: ref,
|
|
261
|
+
enumerable: false,
|
|
262
|
+
configurable: true,
|
|
263
|
+
writable: true,
|
|
264
|
+
});
|
|
265
|
+
return without_ref;
|
|
266
|
+
}
|
|
267
|
+
|
|
220
268
|
/**
|
|
221
269
|
* @param {object} value
|
|
222
270
|
* @param {'current' | 'value'} key
|
package/src/scope.js
CHANGED
|
@@ -107,19 +107,6 @@ export function create_scopes(ast, root, parent, error_options) {
|
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
|
|
110
|
-
Component(node, { state, next }) {
|
|
111
|
-
const scope = state.scope.child();
|
|
112
|
-
scopes.set(node, scope);
|
|
113
|
-
|
|
114
|
-
// Only declare the component name if it has an id (not anonymous)
|
|
115
|
-
if (node.id) {
|
|
116
|
-
scope.declare(node.id, 'normal', 'component');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
add_params(scope, node.params);
|
|
120
|
-
next({ scope });
|
|
121
|
-
},
|
|
122
|
-
|
|
123
110
|
Element(node, { state, next }) {
|
|
124
111
|
const scope = state.scope.child();
|
|
125
112
|
scopes.set(node, scope);
|
package/src/transform/await.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @param {any[]} body_nodes
|
|
3
3
|
* @returns {any | null}
|
|
4
4
|
*/
|
|
5
|
-
export function
|
|
5
|
+
export function find_first_top_level_await_in_tsrx_function_body(body_nodes) {
|
|
6
6
|
for (const node of body_nodes) {
|
|
7
7
|
const found = find_first_top_level_await(node, false);
|
|
8
8
|
if (found) return found;
|
|
@@ -248,7 +248,6 @@ export function is_jsx_child(node) {
|
|
|
248
248
|
t === 'Element' ||
|
|
249
249
|
t === 'Text' ||
|
|
250
250
|
t === 'TSRXExpression' ||
|
|
251
|
-
t === 'Html' ||
|
|
252
251
|
t === 'IfStatement' ||
|
|
253
252
|
t === 'ForOfStatement' ||
|
|
254
253
|
t === 'SwitchStatement' ||
|
|
@@ -449,10 +448,9 @@ function is_static_string_expression(expression) {
|
|
|
449
448
|
* a string `Literal` (`"hello"`, `'hello'`) or a `TemplateLiteral` with no
|
|
450
449
|
* interpolations (`` `hello` ``) — the coercion is provably a no-op and
|
|
451
450
|
* the literal is emitted as-is. This covers both direct double-quoted
|
|
452
|
-
* children (`<b>"hello"</b>`) and
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
* prove they're non-null strings.
|
|
451
|
+
* children (`<b>"hello"</b>`). Identifiers and any other expression type
|
|
452
|
+
* still get the ternary because the AST alone can't prove they're non-null
|
|
453
|
+
* strings.
|
|
456
454
|
*
|
|
457
455
|
* @param {AST.Expression} expression
|
|
458
456
|
* @param {any} [source_node]
|
|
@@ -53,8 +53,7 @@ export function tsx_node_to_jsx_expression(node, in_jsx_child = false) {
|
|
|
53
53
|
* Default `node.metadata` to `{ path: [] }` if missing, then continue the
|
|
54
54
|
* walk. Use as the `FunctionDeclaration` / `FunctionExpression` /
|
|
55
55
|
* `ArrowFunctionExpression` visitor in a zimmerframe walk so that downstream
|
|
56
|
-
* consumers
|
|
57
|
-
* on class methods) don't trip on an undefined metadata object.
|
|
56
|
+
* consumers don't trip on an undefined metadata object.
|
|
58
57
|
*
|
|
59
58
|
* Ripple's analyze phase does this via `visit_function`; the tsrx-* targets
|
|
60
59
|
* have no analyze phase, so we default metadata during the main walk.
|