mirror of https://github.com/sveltejs/svelte
Merge 1b0918c31c
into 42e7e8168d
commit
05fa5e345b
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: allow runes in POJO properties
|
@ -0,0 +1,73 @@
|
|||||||
|
/** @import { ObjectExpression, Property, CallExpression, Expression, SpreadElement, Statement } from 'estree' */
|
||||||
|
/** @import { Context } from '../types' */
|
||||||
|
import * as b from '../../../../utils/builders.js';
|
||||||
|
import { get_rune } from '../../../scope.js';
|
||||||
|
import { should_proxy } from '../utils.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ObjectExpression} node
|
||||||
|
* @param {Context} context
|
||||||
|
*/
|
||||||
|
export function ObjectExpression(node, context) {
|
||||||
|
let has_runes = false;
|
||||||
|
const valid_property_runes = ['$state', '$derived', '$state.raw', '$derived.by'];
|
||||||
|
/** @type {Statement[]} */
|
||||||
|
const body = [];
|
||||||
|
let counter = 0;
|
||||||
|
/** @type {(Property | SpreadElement)[]} */
|
||||||
|
const properties = [];
|
||||||
|
for (let property of node.properties) {
|
||||||
|
if (property.type !== 'Property') {
|
||||||
|
properties.push(/** @type {SpreadElement} */ (context.visit(property)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const rune = get_rune(property.value, context.state.scope);
|
||||||
|
if (rune && valid_property_runes.includes(rune)) {
|
||||||
|
has_runes = true;
|
||||||
|
const name = context.state.scope.generate(`$$${++counter}`);
|
||||||
|
const call = rune.match(/^\$state/) ? '$.state' : '$.derived';
|
||||||
|
/** @type {Expression} */
|
||||||
|
let value = /** @type {Expression} */ (
|
||||||
|
context.visit(/** @type {CallExpression} */ (property.value).arguments[0] ?? b.void0)
|
||||||
|
);
|
||||||
|
const key = /** @type {Expression} */ (context.visit(property.key));
|
||||||
|
value =
|
||||||
|
rune === '$derived'
|
||||||
|
? b.thunk(value)
|
||||||
|
: rune === '$state' && should_proxy(value, context.state.scope)
|
||||||
|
? b.call('$.proxy', value)
|
||||||
|
: value;
|
||||||
|
properties.push(
|
||||||
|
b.prop(
|
||||||
|
'get',
|
||||||
|
key,
|
||||||
|
b.function(null, [], b.block([b.return(b.call('$.get', b.id(name)))])),
|
||||||
|
property.computed
|
||||||
|
),
|
||||||
|
b.prop(
|
||||||
|
'set',
|
||||||
|
key,
|
||||||
|
b.function(
|
||||||
|
null,
|
||||||
|
[b.id('$$value')],
|
||||||
|
b.block([
|
||||||
|
b.stmt(
|
||||||
|
b.call('$.set', b.id(name), b.id('$$value'), rune === '$state' ? b.true : undefined)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
),
|
||||||
|
property.computed
|
||||||
|
)
|
||||||
|
);
|
||||||
|
body.push(b.let(name, b.call(call, value)));
|
||||||
|
} else {
|
||||||
|
properties.push(/** @type {Property} */ (context.visit(property)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_runes) {
|
||||||
|
context.next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
body.push(b.return(b.object(properties)));
|
||||||
|
return b.call(b.arrow([], b.block(body)));
|
||||||
|
}
|
Loading…
Reference in new issue