pull/9826/head
Rich Harris 3 years ago
parent d781798800
commit f6e821a497

@ -255,8 +255,8 @@ export function client_component(source, analysis, options) {
const key = binding.prop_alias ?? name;
properties.push(
b.get(key, [b.return(b.call('$.get', b.id(name)))]),
b.set(key, [b.stmt(b.call('$.set_sync', b.id(name), b.id('$$value')))])
b.get(key, [b.return(b.call(b.id(name)))]),
b.set(key, [b.stmt(b.call(b.id(name), b.id('$$value')))])
);
}
}

@ -74,11 +74,14 @@ export function serialize_get_binding(node, state) {
}
if (
!state.analysis.accessors &&
!(state.analysis.immutable ? binding.reassigned : binding.mutated)
state.analysis.accessors ||
(state.analysis.immutable ? binding.reassigned : binding.mutated) ||
binding.initial
) {
return binding.initial ? b.call(node) : b.member(b.id('$$props'), node);
return b.call(node);
}
return b.member(b.id('$$props'), node);
}
if (binding.kind === 'legacy_reactive_import') {
@ -89,7 +92,6 @@ export function serialize_get_binding(node, state) {
(binding.kind === 'state' &&
(!state.analysis.immutable || state.analysis.accessors || binding.reassigned)) ||
binding.kind === 'derived' ||
binding.kind === 'prop' ||
binding.kind === 'legacy_reactive'
) {
return b.call('$.get', node);
@ -208,9 +210,12 @@ export function serialize_set_binding(node, context, fallback) {
}
const value = get_assignment_value(node, context);
const serialize = () => {
if (left === node.left) {
if (is_store) {
if (binding.kind === 'prop') {
return b.call(left, value);
} else if (is_store) {
return b.call('$.store_set', serialize_get_binding(b.id(left_name), state), value);
} else {
return b.call(
@ -232,15 +237,27 @@ export function serialize_set_binding(node, context, fallback) {
b.call('$' + left_name)
);
} else if (!state.analysis.runes) {
return b.call(
'$.mutate',
b.id(left_name),
b.assignment(
node.operator,
/** @type {import('estree').Pattern} */ (visit(node.left)),
value
)
);
if (binding.kind === 'prop') {
return b.call(
left,
b.assignment(
node.operator,
/** @type {import('estree').Pattern} */ (visit(node.left)),
value
),
b.literal(true)
);
} else {
return b.call(
'$.mutate',
b.id(left_name),
b.assignment(
node.operator,
/** @type {import('estree').Pattern} */ (visit(node.left)),
value
)
);
}
} else {
return b.assignment(
node.operator,
@ -365,7 +382,10 @@ export function get_prop_source(binding, state, name, initial) {
flags |= PROPS_IS_RUNES;
}
if (state.analysis.immutable ? binding.reassigned : binding.mutated) {
if (
state.analysis.accessors ||
(state.analysis.immutable ? binding.reassigned : binding.mutated)
) {
flags |= PROPS_IS_UPDATED;
}

@ -2661,7 +2661,7 @@ export function createRoot(component, options) {
/** @param {any} value */
set(value) {
// @ts-expect-error TS doesn't know key exists on accessor
accessors[key] = value;
flushSync(() => (accessors[key] = value));
},
enumerable: true
});

@ -1409,7 +1409,7 @@ export function is_store(val) {
* @param {string} key
* @param {number} flags
* @param {V | (() => V)} [initial]
* @returns {import('./types.js').Signal<V> | (() => V)}
* @returns {(() => V | ((arg: V) => V) | ((arg: V, mutation: boolean) => V))}
*/
export function prop(props, key, flags, initial) {
var immutable = (flags & PROPS_IS_IMMUTABLE) !== 0;
@ -1422,101 +1422,53 @@ export function prop(props, key, flags, initial) {
}
var value = /** @type {V} */ (props[key]);
var should_set_default_value = value === undefined && initial !== undefined;
if (should_set_default_value) {
if (value === undefined && initial !== undefined) {
// @ts-expect-error would need a cumbersome method overload to type this
value = (flags & PROPS_IS_LAZY_INITIAL) !== 0 ? initial() : initial;
if ((flags & PROPS_IS_LAZY_INITIAL) !== 0) initial = initial();
if (DEV && runes) {
value = readonly(proxy(/** @type {any} */ (value)));
initial = readonly(proxy(/** @type {any} */ (initial)));
}
}
if ((flags & PROPS_IS_UPDATED) === 0) {
return () => {
var value = /** @type {V} */ (props[key]);
if (value !== undefined) initial = undefined;
return value === undefined ? /** @type {V} */ (initial) : value;
};
value = /** @type {V} */ (initial);
}
var source_signal = immutable ? source(value) : mutable_source(value);
// Synchronize prop changes with source signal.
// Needs special equality checking because the prop in the
// parent could be changed through `foo.bar = 'new value'`.
var ignore_next1 = false;
var ignore_next2 = false;
var did_update_to_defined = !should_set_default_value;
var mount = true;
sync_effect(() => {
// Before if to ensure signal dependency is registered
var propagating_value = props[key];
if (mount) {
mount = false;
return;
}
if (ignore_next1) {
ignore_next1 = false;
return;
}
var getter = () => {
var value = /** @type {V} */ (props[key]);
if (value !== undefined) initial = undefined;
return value === undefined ? /** @type {V} */ (initial) : value;
};
if (
// Ensure that updates from undefined to undefined are ignored
(did_update_to_defined || propagating_value !== undefined) &&
not_equal(immutable, propagating_value, source_signal.v)
) {
ignore_next2 = true;
did_update_to_defined = true;
// TODO figure out why we need it this way and the explain in a comment;
// some tests fail is we just do set_signal_value(source_signal, propagating_value)
untrack(() => set_signal_value(source_signal, propagating_value));
}
});
if ((flags & PROPS_IS_UPDATED) === 0) {
return getter;
}
if (setter !== undefined) {
var ignore_first = did_update_to_defined;
sync_effect(() => {
// Before if to ensure signal dependency is registered
const propagating_value = get(source_signal);
if (ignore_first) {
ignore_first = false;
return;
}
if (ignore_next2) {
ignore_next2 = false;
return;
if (setter) {
return function (/** @type {V} */ value) {
if (arguments.length === 1) {
/** @type {Function} */ (setter)(value);
return value;
} else {
return getter();
}
ignore_next1 = true;
did_update_to_defined = true;
untrack(() => /** @type {Function} */ (setter)(propagating_value));
});
};
}
return /** @type {import('./types.js').Signal<V>} */ (source_signal);
}
var source_signal = immutable ? source(value) : mutable_source(value);
/**
* @param {boolean} immutable
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
function not_equal(immutable, a, b) {
return immutable ? immutable_not_equal(a, b) : safe_not_equal(a, b);
}
pre_effect(() => {
set(source_signal, getter());
});
/**
* @param {unknown} a
* @param {unknown} b
* @returns {boolean}
*/
function immutable_not_equal(a, b) {
// eslint-disable-next-line eqeqeq
return a != a ? b == b : a !== b;
return function (/** @type {V} */ value, mutation = false) {
if (arguments.length > 0) {
(mutation ? mutate : set)(source_signal, value);
return value;
} else {
return get(source_signal);
}
};
}
/**

@ -6,12 +6,12 @@ import * as $ from "svelte/internal";
export default function Svelte_element($$anchor, $$props) {
$.push($$props, true);
let tag = $.prop_source($$props, "tag", 3, 'hr');
let tag = $.prop($$props, "tag", 3, 'hr');
/* Init */
var fragment = $.comment($$anchor);
var node = $.child_frag(fragment);
$.element(node, () => $.get(tag));
$.element(node, () => tag());
$.close_frag($$anchor, fragment);
$.pop();
}
}

Loading…
Cancel
Save