fix: improve ssr derived output to ensure memoization remains (#10664)

pull/10665/head
Dominic Gannaway 7 months ago committed by GitHub
parent 56315df679
commit 61e7442ccf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -546,11 +546,88 @@ const javascript_visitors = {
/** @type {import('./types').Visitors} */
const javascript_visitors_runes = {
ClassBody(node, { state, visit, next }) {
if (!state.analysis.runes) {
next();
}
/** @type {import('estree').PropertyDefinition[]} */
const deriveds = [];
/** @type {import('estree').MethodDefinition | null} */
let constructor = null;
// Get the constructor
for (const definition of node.body) {
if (definition.type === 'MethodDefinition' && definition.kind === 'constructor') {
constructor = /** @type {import('estree').MethodDefinition} */ (visit(definition));
}
}
// Move $derived() runes to the end of the body if there is a constructor
if (constructor !== null) {
const body = [];
for (const definition of node.body) {
if (
definition.type === 'PropertyDefinition' &&
(definition.key.type === 'Identifier' || definition.key.type === 'PrivateIdentifier')
) {
const is_private = definition.key.type === 'PrivateIdentifier';
if (definition.value?.type === 'CallExpression') {
const rune = get_rune(definition.value, state.scope);
if (rune === '$derived') {
deriveds.push(/** @type {import('estree').PropertyDefinition} */ (visit(definition)));
if (is_private) {
// Keep the private #name initializer if private, but remove initial value
body.push({
...definition,
value: null
});
}
continue;
}
}
}
if (definition.type !== 'MethodDefinition' || definition.kind !== 'constructor') {
body.push(
/** @type {import('estree').PropertyDefinition | import('estree').MethodDefinition | import('estree').StaticBlock} */ (
visit(definition)
)
);
}
}
if (deriveds.length > 0) {
body.push({
...constructor,
value: {
...constructor.value,
body: b.block([
...constructor.value.body.body,
...deriveds.map((d) => {
return b.stmt(
b.assignment(
'=',
b.member(b.this, d.key),
/** @type {import('estree').Expression} */ (d.value)
)
);
})
])
}
});
} else {
body.push(constructor);
}
return {
...node,
body
};
}
next();
},
PropertyDefinition(node, { state, next, visit }) {
if (node.value != null && node.value.type === 'CallExpression') {
const rune = get_rune(node.value, state.scope);
if (rune === '$state' || rune === '$state.frozen') {
if (rune === '$state' || rune === '$state.frozen' || rune === '$derived') {
return {
...node,
value:
@ -559,26 +636,6 @@ const javascript_visitors_runes = {
: /** @type {import('estree').Expression} */ (visit(node.value.arguments[0]))
};
}
if (rune === '$derived') {
return {
type: 'MethodDefinition',
kind: 'get',
key: node.key,
computed: false,
static: false,
value: b.function(
null,
[],
b.block([
b.return(
node.value.arguments.length === 0
? null
: /** @type {import('estree').Expression} */ (visit(node.value.arguments[0]))
)
])
)
};
}
if (rune === '$derived.by') {
return {
...node,

Loading…
Cancel
Save