|
|
|
@ -225,15 +225,7 @@ function execute_signal_fn(signal) {
|
|
|
|
|
current_untracking = false;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let res;
|
|
|
|
|
if (is_render_effect) {
|
|
|
|
|
res = /** @type {(block: null, signal: import('#client').Signal) => V} */ (init)(
|
|
|
|
|
null,
|
|
|
|
|
/** @type {import('#client').Signal} */ (signal)
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
res = /** @type {() => V} */ (init)();
|
|
|
|
|
}
|
|
|
|
|
const res = /** @type {() => V} */ (init)();
|
|
|
|
|
let dependencies = /** @type {import('#client').ValueSignal<unknown>[]} **/ (signal.d);
|
|
|
|
|
if (current_dependencies !== null) {
|
|
|
|
|
let i;
|
|
|
|
@ -269,7 +261,7 @@ function execute_signal_fn(signal) {
|
|
|
|
|
dependencies[current_dependencies_index + i] = current_dependencies[i];
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
signal.d = /** @type {import('#client').Signal<V>[]} **/ (
|
|
|
|
|
signal.d = /** @type {import('#client').ValueSignal<V>[]} **/ (
|
|
|
|
|
dependencies = current_dependencies
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
@ -747,18 +739,81 @@ export function get(signal) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template V
|
|
|
|
|
* @param {import('#client').Signal<V>} signal
|
|
|
|
|
* @param {import('#client').Source<V>} signal
|
|
|
|
|
* @param {V} value
|
|
|
|
|
* @returns {V}
|
|
|
|
|
*/
|
|
|
|
|
export function set(signal, value) {
|
|
|
|
|
set_signal_value(signal, value);
|
|
|
|
|
if (
|
|
|
|
|
!current_untracking &&
|
|
|
|
|
!ignore_mutation_validation &&
|
|
|
|
|
current_consumer !== null &&
|
|
|
|
|
is_runes(null) &&
|
|
|
|
|
(current_consumer.f & DERIVED) !== 0
|
|
|
|
|
) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
'ERR_SVELTE_UNSAFE_MUTATION' +
|
|
|
|
|
(DEV
|
|
|
|
|
? ": Unsafe mutations during Svelte's render or derived phase are not permitted in runes mode. " +
|
|
|
|
|
'This can lead to unexpected errors and possibly cause infinite loops.\n\nIf this mutation is not meant ' +
|
|
|
|
|
'to be reactive do not use the "$state" rune for that declaration.'
|
|
|
|
|
: '')
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
(signal.f & SOURCE) !== 0 &&
|
|
|
|
|
!(/** @type {import('#client').EqualsFunctions} */ (signal.e)(value, signal.v))
|
|
|
|
|
) {
|
|
|
|
|
signal.v = value;
|
|
|
|
|
// Increment write version so that unowned signals can properly track dirtyness
|
|
|
|
|
signal.w++;
|
|
|
|
|
// If the current signal is running for the first time, it won't have any
|
|
|
|
|
// consumers as we only allocate and assign the consumers after the signal
|
|
|
|
|
// has fully executed. So in the case of ensuring it registers the consumer
|
|
|
|
|
// properly for itself, we need to ensure the current effect actually gets
|
|
|
|
|
// scheduled. i.e:
|
|
|
|
|
//
|
|
|
|
|
// $effect(() => x++)
|
|
|
|
|
//
|
|
|
|
|
// We additionally want to skip this logic for when ignore_mutation_validation is
|
|
|
|
|
// true, as stores write to source signal on initialization.
|
|
|
|
|
if (
|
|
|
|
|
is_runes(null) &&
|
|
|
|
|
!ignore_mutation_validation &&
|
|
|
|
|
current_effect !== null &&
|
|
|
|
|
current_effect.c === null &&
|
|
|
|
|
(current_effect.f & CLEAN) !== 0 &&
|
|
|
|
|
(current_effect.f & MANAGED) === 0
|
|
|
|
|
) {
|
|
|
|
|
if (current_dependencies !== null && current_dependencies.includes(signal)) {
|
|
|
|
|
set_signal_status(current_effect, DIRTY);
|
|
|
|
|
schedule_effect(current_effect, false);
|
|
|
|
|
} else {
|
|
|
|
|
if (current_untracked_writes === null) {
|
|
|
|
|
current_untracked_writes = [signal];
|
|
|
|
|
} else {
|
|
|
|
|
current_untracked_writes.push(signal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mark_signal_consumers(signal, DIRTY, true);
|
|
|
|
|
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
if (DEV && signal.inspect) {
|
|
|
|
|
if (is_batching_effect) {
|
|
|
|
|
last_inspected_signal = /** @type {import('#client').SourceDebug} */ (signal);
|
|
|
|
|
} else {
|
|
|
|
|
for (const fn of /** @type {import('#client').SourceDebug} */ (signal).inspect) fn();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template V
|
|
|
|
|
* @param {import('#client').Signal<V>} signal
|
|
|
|
|
* @param {import('#client').Source<V>} signal
|
|
|
|
|
* @param {V} value
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
@ -796,11 +851,11 @@ export function invalidate_inner_signals(fn) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template V
|
|
|
|
|
* @param {import('#client').Signal<V>} source
|
|
|
|
|
* @param {import('#client').Source<V>} source
|
|
|
|
|
* @param {V} value
|
|
|
|
|
*/
|
|
|
|
|
export function mutate(source, value) {
|
|
|
|
|
set_signal_value(
|
|
|
|
|
set(
|
|
|
|
|
source,
|
|
|
|
|
untrack(() => get(source))
|
|
|
|
|
);
|
|
|
|
@ -847,79 +902,6 @@ function mark_signal_consumers(signal, to_status, force_schedule) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template V
|
|
|
|
|
* @param {import('#client').Signal<V>} signal
|
|
|
|
|
* @param {V} value
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
export function set_signal_value(signal, value) {
|
|
|
|
|
if (
|
|
|
|
|
!current_untracking &&
|
|
|
|
|
!ignore_mutation_validation &&
|
|
|
|
|
current_consumer !== null &&
|
|
|
|
|
is_runes(null) &&
|
|
|
|
|
(current_consumer.f & DERIVED) !== 0
|
|
|
|
|
) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
'ERR_SVELTE_UNSAFE_MUTATION' +
|
|
|
|
|
(DEV
|
|
|
|
|
? ": Unsafe mutations during Svelte's render or derived phase are not permitted in runes mode. " +
|
|
|
|
|
'This can lead to unexpected errors and possibly cause infinite loops.\n\nIf this mutation is not meant ' +
|
|
|
|
|
'to be reactive do not use the "$state" rune for that declaration.'
|
|
|
|
|
: '')
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
(signal.f & SOURCE) !== 0 &&
|
|
|
|
|
!(/** @type {import('#client').EqualsFunctions} */ (signal.e)(value, signal.v))
|
|
|
|
|
) {
|
|
|
|
|
signal.v = value;
|
|
|
|
|
// Increment write version so that unowned signals can properly track dirtyness
|
|
|
|
|
signal.w++;
|
|
|
|
|
// If the current signal is running for the first time, it won't have any
|
|
|
|
|
// consumers as we only allocate and assign the consumers after the signal
|
|
|
|
|
// has fully executed. So in the case of ensuring it registers the consumer
|
|
|
|
|
// properly for itself, we need to ensure the current effect actually gets
|
|
|
|
|
// scheduled. i.e:
|
|
|
|
|
//
|
|
|
|
|
// $effect(() => x++)
|
|
|
|
|
//
|
|
|
|
|
// We additionally want to skip this logic for when ignore_mutation_validation is
|
|
|
|
|
// true, as stores write to source signal on initialization.
|
|
|
|
|
if (
|
|
|
|
|
is_runes(null) &&
|
|
|
|
|
!ignore_mutation_validation &&
|
|
|
|
|
current_effect !== null &&
|
|
|
|
|
current_effect.c === null &&
|
|
|
|
|
(current_effect.f & CLEAN) !== 0 &&
|
|
|
|
|
(current_effect.f & MANAGED) === 0
|
|
|
|
|
) {
|
|
|
|
|
if (current_dependencies !== null && current_dependencies.includes(signal)) {
|
|
|
|
|
set_signal_status(current_effect, DIRTY);
|
|
|
|
|
schedule_effect(current_effect, false);
|
|
|
|
|
} else {
|
|
|
|
|
if (current_untracked_writes === null) {
|
|
|
|
|
current_untracked_writes = [signal];
|
|
|
|
|
} else {
|
|
|
|
|
current_untracked_writes.push(signal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mark_signal_consumers(signal, DIRTY, true);
|
|
|
|
|
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
if (DEV && signal.inspect) {
|
|
|
|
|
if (is_batching_effect) {
|
|
|
|
|
last_inspected_signal = /** @type {import('#client').SourceDebug} */ (signal);
|
|
|
|
|
} else {
|
|
|
|
|
for (const fn of /** @type {import('#client').SourceDebug} */ (signal).inspect) fn();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template V
|
|
|
|
|
* @param {import('#client').Reaction} signal
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
@ -1021,7 +1003,7 @@ function get_parent_context(component_context) {
|
|
|
|
|
*/
|
|
|
|
|
export function update(signal, d = 1) {
|
|
|
|
|
const value = get(signal);
|
|
|
|
|
set_signal_value(signal, value + d);
|
|
|
|
|
set(signal, value + d);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1043,7 +1025,7 @@ export function update_prop(fn, d = 1) {
|
|
|
|
|
*/
|
|
|
|
|
export function update_pre(signal, d = 1) {
|
|
|
|
|
const value = get(signal) + d;
|
|
|
|
|
set_signal_value(signal, value);
|
|
|
|
|
set(signal, value);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|