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