|
|
|
@ -9,18 +9,18 @@ import { should_proxy } from '../utils.js';
|
|
|
|
|
* @param {Context} context
|
|
|
|
|
*/
|
|
|
|
|
export function ObjectExpression(node, context) {
|
|
|
|
|
/**
|
|
|
|
|
* @typedef {[string, NonNullable<ReturnType<typeof get_rune>>]} ReactiveProperty
|
|
|
|
|
*/
|
|
|
|
|
let has_runes = false;
|
|
|
|
|
const valid_property_runes = ['$state', '$derived', '$state.raw', '$derived.by'];
|
|
|
|
|
/** @type {Statement[]} */
|
|
|
|
|
const body = [];
|
|
|
|
|
/** @type {Map<Property, ReactiveProperty>} */
|
|
|
|
|
const sources = new Map();
|
|
|
|
|
let counter = 0;
|
|
|
|
|
/** @type {(Property | SpreadElement)[]} */
|
|
|
|
|
const properties = [];
|
|
|
|
|
for (let property of node.properties) {
|
|
|
|
|
if (property.type !== 'Property') continue;
|
|
|
|
|
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;
|
|
|
|
@ -30,41 +30,23 @@ export function ObjectExpression(node, context) {
|
|
|
|
|
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;
|
|
|
|
|
/** @type {ReactiveProperty} */
|
|
|
|
|
const source = [name, rune];
|
|
|
|
|
sources.set(property, source);
|
|
|
|
|
body.push(b.let(name, b.call(call, value)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!has_runes) {
|
|
|
|
|
context.next();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/** @type {(Property | SpreadElement)[]} */
|
|
|
|
|
const properties = [];
|
|
|
|
|
for (let property of node.properties) {
|
|
|
|
|
if (property.type === 'SpreadElement') {
|
|
|
|
|
properties.push(/** @type {SpreadElement} */ (context.visit(property)));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (sources.has(property)) {
|
|
|
|
|
const [name, rune] = /** @type {ReactiveProperty} */ (sources.get(property));
|
|
|
|
|
properties.push(
|
|
|
|
|
b.prop(
|
|
|
|
|
'get',
|
|
|
|
|
/** @type {Expression} */ (context.visit(/**@type {Expression} */ (property.key))),
|
|
|
|
|
key,
|
|
|
|
|
b.function(null, [], b.block([b.return(b.call('$.get', b.id(name)))])),
|
|
|
|
|
property.computed
|
|
|
|
|
),
|
|
|
|
|
b.prop(
|
|
|
|
|
'set',
|
|
|
|
|
/** @type {Expression} */ (context.visit(property.key)),
|
|
|
|
|
key,
|
|
|
|
|
b.function(
|
|
|
|
|
null,
|
|
|
|
|
[b.id('$$value')],
|
|
|
|
@ -77,10 +59,15 @@ export function ObjectExpression(node, context) {
|
|
|
|
|
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)));
|
|
|
|
|
}
|
|
|
|
|