perf: save some bytes with more concise comparisons

rm-bytes
Ben McCann 2 years ago
parent d16f17c306
commit 72b32640e2

@ -111,7 +111,7 @@ export function set_is_ssr(ssr) {
*/ */
function is_runes(context) { function is_runes(context) {
const component_context = context || current_component_context; const component_context = context || current_component_context;
return component_context !== null && component_context.r; return !!component_context && component_context.r;
} }
/** /**
@ -128,7 +128,7 @@ export function batch_inspect(target, prop, receiver) {
return Reflect.apply(value, receiver, arguments); return Reflect.apply(value, receiver, arguments);
} finally { } finally {
is_batching_effect = previously_batching_effect; is_batching_effect = previously_batching_effect;
if (last_inspected_signal !== null) { if (last_inspected_signal) {
for (const fn of last_inspected_signal.inspect) fn(); for (const fn of last_inspected_signal.inspect) fn();
last_inspected_signal = null; last_inspected_signal = null;
} }
@ -256,10 +256,10 @@ function create_computation_signal(flags, value, block) {
*/ */
function push_reference(target_signal, ref_signal) { function push_reference(target_signal, ref_signal) {
const references = target_signal.r; const references = target_signal.r;
if (references === null) { if (references) {
target_signal.r = [ref_signal];
} else {
references.push(ref_signal); references.push(ref_signal);
} else {
target_signal.r = [ref_signal];
} }
} }
@ -270,30 +270,30 @@ function push_reference(target_signal, ref_signal) {
*/ */
function is_signal_dirty(signal) { function is_signal_dirty(signal) {
const flags = signal.f; const flags = signal.f;
if ((flags & DIRTY) !== 0 || signal.v === UNINITIALIZED) { if (flags & DIRTY || signal.v === UNINITIALIZED) {
return true; return true;
} }
if ((flags & MAYBE_DIRTY) !== 0) { if (flags & MAYBE_DIRTY) {
const dependencies = /** @type {import('./types.js').ComputationSignal<V>} **/ (signal).d; const dependencies = /** @type {import('./types.js').ComputationSignal<V>} **/ (signal).d;
if (dependencies !== null) { if (dependencies) {
const length = dependencies.length; const length = dependencies.length;
let i; let i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
const dependency = dependencies[i]; const dependency = dependencies[i];
if ((dependency.f & MAYBE_DIRTY) !== 0 && !is_signal_dirty(dependency)) { if (dependency.f & MAYBE_DIRTY && !is_signal_dirty(dependency)) {
set_signal_status(dependency, CLEAN); set_signal_status(dependency, CLEAN);
continue; continue;
} }
// The flags can be marked as dirty from the above is_signal_dirty call. // The flags can be marked as dirty from the above is_signal_dirty call.
if ((dependency.f & DIRTY) !== 0) { if (dependency.f & DIRTY) {
if ((dependency.f & DERIVED) !== 0) { if (dependency.f & DERIVED) {
update_derived( update_derived(
/** @type {import('./types.js').ComputationSignal<V>} **/ (dependency), /** @type {import('./types.js').ComputationSignal<V>} **/ (dependency),
true true
); );
// Might have been mutated from above get. // Might have been mutated from above get.
if ((signal.f & DIRTY) !== 0) { if (signal.f & DIRTY) {
return true; return true;
} }
} else { } else {
@ -320,7 +320,7 @@ function execute_signal_fn(signal) {
const previous_block = current_block; const previous_block = current_block;
const previous_component_context = current_component_context; const previous_component_context = current_component_context;
const previous_skip_consumer = current_skip_consumer; const previous_skip_consumer = current_skip_consumer;
const is_render_effect = (signal.f & RENDER_EFFECT) !== 0; const is_render_effect = signal.f & RENDER_EFFECT;
const previous_untracking = current_untracking; const previous_untracking = current_untracking;
current_dependencies = /** @type {null | import('./types.js').Signal[]} */ (null); current_dependencies = /** @type {null | import('./types.js').Signal[]} */ (null);
current_dependencies_index = 0; current_dependencies_index = 0;
@ -328,11 +328,11 @@ function execute_signal_fn(signal) {
current_consumer = signal; current_consumer = signal;
current_block = signal.b; current_block = signal.b;
current_component_context = signal.x; current_component_context = signal.x;
current_skip_consumer = current_effect === null && (signal.f & UNOWNED) !== 0; current_skip_consumer = !current_effect && !!(signal.f & UNOWNED);
current_untracking = false; current_untracking = false;
// Render effects are invoked when the UI is about to be updated - run beforeUpdate at that point // Render effects are invoked when the UI is about to be updated - run beforeUpdate at that point
if (is_render_effect && current_component_context?.u != null) { if (is_render_effect && current_component_context?.u) {
// update_callbacks.execute() // update_callbacks.execute()
current_component_context.u.e(); current_component_context.u.e();
} }
@ -348,12 +348,11 @@ function execute_signal_fn(signal) {
} }
let dependencies = /** @type {import('./types.js').Signal<unknown>[]} **/ (signal.d); let dependencies = /** @type {import('./types.js').Signal<unknown>[]} **/ (signal.d);
if (current_dependencies !== null) { if (current_dependencies) {
let i; let i;
if (dependencies !== null) { if (dependencies) {
// Include any dependencies up until the current_dependencies_index. // Include any dependencies up until the current_dependencies_index.
const full_dependencies = const full_dependencies = !current_dependencies_index
current_dependencies_index === 0
? dependencies ? dependencies
: dependencies.slice(0, current_dependencies_index).concat(current_dependencies); : dependencies.slice(0, current_dependencies_index).concat(current_dependencies);
const dep_length = full_dependencies.length; const dep_length = full_dependencies.length;
@ -364,7 +363,7 @@ function execute_signal_fn(signal) {
for (i = current_dependencies_index; i < dep_length; i++) { for (i = current_dependencies_index; i < dep_length; i++) {
const dependency = full_dependencies[i]; const dependency = full_dependencies[i];
if ( if (
(current_dependencies_set !== null && !current_dependencies_set.has(dependency)) || (current_dependencies_set && !current_dependencies_set.has(dependency)) ||
!full_dependencies.includes(dependency) !full_dependencies.includes(dependency)
) { ) {
remove_consumer(signal, dependency, false); remove_consumer(signal, dependency, false);
@ -372,7 +371,7 @@ function execute_signal_fn(signal) {
} }
} }
if (dependencies !== null && current_dependencies_index > 0) { if (dependencies && current_dependencies_index > 0) {
dependencies.length = current_dependencies_index + current_dependencies.length; dependencies.length = current_dependencies_index + current_dependencies.length;
for (i = 0; i < current_dependencies.length; i++) { for (i = 0; i < current_dependencies.length; i++) {
dependencies[current_dependencies_index + i] = current_dependencies[i]; dependencies[current_dependencies_index + i] = current_dependencies[i];
@ -388,14 +387,14 @@ function execute_signal_fn(signal) {
const dependency = dependencies[i]; const dependency = dependencies[i];
const consumers = dependency.c; const consumers = dependency.c;
if (consumers === null) { if (!consumers) {
dependency.c = [signal]; dependency.c = [signal];
} else if (consumers[consumers.length - 1] !== signal) { } else if (consumers[consumers.length - 1] !== signal) {
consumers.push(signal); consumers.push(signal);
} }
} }
} }
} else if (dependencies !== null && current_dependencies_index < dependencies.length) { } else if (dependencies && current_dependencies_index < dependencies.length) {
remove_consumers(signal, current_dependencies_index, false); remove_consumers(signal, current_dependencies_index, false);
dependencies.length = current_dependencies_index; dependencies.length = current_dependencies_index;
} }
@ -422,11 +421,11 @@ function execute_signal_fn(signal) {
function remove_consumer(signal, dependency, remove_unowned) { function remove_consumer(signal, dependency, remove_unowned) {
const consumers = dependency.c; const consumers = dependency.c;
let consumers_length = 0; let consumers_length = 0;
if (consumers !== null) { if (consumers) {
consumers_length = consumers.length - 1; consumers_length = consumers.length - 1;
const index = consumers.indexOf(signal); const index = consumers.indexOf(signal);
if (index !== -1) { if (index !== -1) {
if (consumers_length === 0) { if (!consumers_length) {
dependency.c = null; dependency.c = null;
} else { } else {
// Swap with last element and then remove. // Swap with last element and then remove.
@ -435,7 +434,7 @@ function remove_consumer(signal, dependency, remove_unowned) {
} }
} }
} }
if (remove_unowned && consumers_length === 0 && (dependency.f & UNOWNED) !== 0) { if (remove_unowned && !consumers_length && dependency.f & UNOWNED) {
// If the signal is unowned then we need to make sure to change it to dirty. // If the signal is unowned then we need to make sure to change it to dirty.
set_signal_status(dependency, DIRTY); set_signal_status(dependency, DIRTY);
remove_consumers( remove_consumers(
@ -455,13 +454,13 @@ function remove_consumer(signal, dependency, remove_unowned) {
*/ */
function remove_consumers(signal, start_index, remove_unowned) { function remove_consumers(signal, start_index, remove_unowned) {
const dependencies = signal.d; const dependencies = signal.d;
if (dependencies !== null) { if (dependencies) {
const active_dependencies = start_index === 0 ? null : dependencies.slice(0, start_index); const active_dependencies = !start_index ? null : dependencies.slice(0, start_index);
let i; let i;
for (i = start_index; i < dependencies.length; i++) { for (i = start_index; i < dependencies.length; i++) {
const dependency = dependencies[i]; const dependency = dependencies[i];
// Avoid removing a consumer if we know that it is active (start_index will not be 0) // Avoid removing a consumer if we know that it is active (start_index will not be 0)
if (active_dependencies === null || !active_dependencies.includes(dependency)) { if (!active_dependencies || !active_dependencies.includes(dependency)) {
remove_consumer(signal, dependency, remove_unowned); remove_consumer(signal, dependency, remove_unowned);
} }
} }
@ -476,11 +475,11 @@ function remove_consumers(signal, start_index, remove_unowned) {
function destroy_references(signal) { function destroy_references(signal) {
const references = signal.r; const references = signal.r;
signal.r = null; signal.r = null;
if (references !== null) { if (references) {
let i; let i;
for (i = 0; i < references.length; i++) { for (i = 0; i < references.length; i++) {
const reference = references[i]; const reference = references[i];
if ((reference.f & IS_EFFECT) !== 0) { if (reference.f & IS_EFFECT) {
destroy_signal(reference); destroy_signal(reference);
} else { } else {
remove_consumers(reference, 0, true); remove_consumers(reference, 0, true);
@ -490,26 +489,12 @@ function destroy_references(signal) {
} }
} }
/**
* @param {import('./types.js').Block} block
* @param {unknown} error
* @returns {void}
*/
function report_error(block, error) {
/** @type {import('./types.js').Block | null} */
let current_block = block;
if (current_block !== null) {
throw error;
}
}
/** /**
* @param {import('./types.js').EffectSignal} signal * @param {import('./types.js').EffectSignal} signal
* @returns {void} * @returns {void}
*/ */
export function execute_effect(signal) { export function execute_effect(signal) {
if ((signal.f & DESTROYED) !== 0) { if (signal.f & DESTROYED) {
return; return;
} }
const teardown = signal.v; const teardown = signal.v;
@ -518,7 +503,7 @@ export function execute_effect(signal) {
try { try {
destroy_references(signal); destroy_references(signal);
if (teardown !== null) { if (teardown) {
teardown(); teardown();
} }
const possible_teardown = execute_signal_fn(signal); const possible_teardown = execute_signal_fn(signal);
@ -527,18 +512,14 @@ export function execute_effect(signal) {
} }
} catch (error) { } catch (error) {
const block = signal.b; const block = signal.b;
if (block !== null) {
report_error(block, error);
} else {
throw error; throw error;
}
} finally { } finally {
current_effect = previous_effect; current_effect = previous_effect;
} }
const component_context = signal.x; const component_context = signal.x;
if ( if (
is_runes(component_context) && // Don't rerun pre effects more than once to accomodate for "$: only runs once" behavior is_runes(component_context) && // Don't rerun pre effects more than once to accomodate for "$: only runs once" behavior
(signal.f & PRE_EFFECT) !== 0 && signal.f & PRE_EFFECT &&
current_queued_pre_and_render_effects.length > 0 current_queued_pre_and_render_effects.length > 0
) { ) {
flush_local_pre_effects(component_context); flush_local_pre_effects(component_context);
@ -570,11 +551,11 @@ function flush_queued_effects(effects) {
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
const signal = effects[i]; const signal = effects[i];
const flags = signal.f; const flags = signal.f;
if ((flags & (DESTROYED | INERT)) === 0) { if (!(flags & (DESTROYED | INERT))) {
if (is_signal_dirty(signal)) { if (is_signal_dirty(signal)) {
set_signal_status(signal, CLEAN); set_signal_status(signal, CLEAN);
execute_effect(signal); execute_effect(signal);
} else if ((flags & MAYBE_DIRTY) !== 0) { } else if (flags & MAYBE_DIRTY) {
set_signal_status(signal, CLEAN); set_signal_status(signal, CLEAN);
} }
} }
@ -621,7 +602,7 @@ export function schedule_effect(signal, sync) {
queueMicrotask(process_microtask); queueMicrotask(process_microtask);
} }
} }
if ((flags & EFFECT) !== 0) { if (flags & EFFECT) {
current_queued_effects.push(signal); current_queued_effects.push(signal);
} else { } else {
current_queued_pre_and_render_effects.push(signal); current_queued_pre_and_render_effects.push(signal);
@ -667,7 +648,7 @@ export function flush_local_render_effects() {
const effects = []; const effects = [];
for (let i = 0; i < current_queued_pre_and_render_effects.length; i++) { for (let i = 0; i < current_queued_pre_and_render_effects.length; i++) {
const effect = current_queued_pre_and_render_effects[i]; const effect = current_queued_pre_and_render_effects[i];
if ((effect.f & RENDER_EFFECT) !== 0 && effect.x === current_component_context) { if (effect.f & RENDER_EFFECT && effect.x === current_component_context) {
effects.push(effect); effects.push(effect);
current_queued_pre_and_render_effects.splice(i, 1); current_queued_pre_and_render_effects.splice(i, 1);
i--; i--;
@ -684,7 +665,7 @@ export function flush_local_pre_effects(context) {
const effects = []; const effects = [];
for (let i = 0; i < current_queued_pre_and_render_effects.length; i++) { for (let i = 0; i < current_queued_pre_and_render_effects.length; i++) {
const effect = current_queued_pre_and_render_effects[i]; const effect = current_queued_pre_and_render_effects[i];
if ((effect.f & PRE_EFFECT) !== 0 && effect.x === context) { if (effect.f & PRE_EFFECT && effect.x === context) {
effects.push(effect); effects.push(effect);
current_queued_pre_and_render_effects.splice(i, 1); current_queued_pre_and_render_effects.splice(i, 1);
i--; i--;
@ -714,7 +695,7 @@ export function flushSync(fn) {
current_queued_effects = effects; current_queued_effects = effects;
flush_queued_effects(previous_queued_pre_and_render_effects); flush_queued_effects(previous_queued_pre_and_render_effects);
flush_queued_effects(previous_queued_effects); flush_queued_effects(previous_queued_effects);
if (fn !== undefined) { if (fn) {
fn(); fn();
} }
if (current_queued_pre_and_render_effects.length > 0 || effects.length > 0) { if (current_queued_pre_and_render_effects.length > 0 || effects.length > 0) {
@ -756,10 +737,7 @@ function update_derived(signal, force_schedule) {
updating_derived = true; updating_derived = true;
const value = execute_signal_fn(signal); const value = execute_signal_fn(signal);
updating_derived = previous_updating_derived; updating_derived = previous_updating_derived;
const status = const status = current_skip_consumer || (!current_effect && signal.f & UNOWNED) ? DIRTY : CLEAN;
current_skip_consumer || (current_effect === null && (signal.f & UNOWNED) !== 0)
? DIRTY
: CLEAN;
set_signal_status(signal, status); set_signal_status(signal, status);
const equals = /** @type {import('./types.js').EqualsFunctions} */ (signal.e); const equals = /** @type {import('./types.js').EqualsFunctions} */ (signal.e);
if (!equals(value, signal.v)) { if (!equals(value, signal.v)) {
@ -821,7 +799,7 @@ export function store_get(store, store_name, stores) {
* @param {import('./types.js').SourceSignal<V>} source * @param {import('./types.js').SourceSignal<V>} source
*/ */
function connect_store_to_signal(store, source) { function connect_store_to_signal(store, source) {
if (store == null) { if (!store) {
set(source, undefined); set(source, undefined);
return EMPTY_FUNC; return EMPTY_FUNC;
} }
@ -877,7 +855,7 @@ export function get(signal) {
} }
const flags = signal.f; const flags = signal.f;
if ((flags & DESTROYED) !== 0) { if (flags & DESTROYED) {
return signal.v; return signal.v;
} }
@ -886,31 +864,31 @@ export function get(signal) {
} }
// Register the dependency on the current consumer signal. // Register the dependency on the current consumer signal.
if (current_consumer !== null && (current_consumer.f & MANAGED) === 0 && !current_untracking) { if (current_consumer && !(current_consumer.f & MANAGED) && !current_untracking) {
const unowned = (current_consumer.f & UNOWNED) !== 0; const unowned = current_consumer.f & UNOWNED;
const dependencies = current_consumer.d; const dependencies = current_consumer.d;
if ( if (
current_dependencies === null && !current_dependencies &&
dependencies !== null && dependencies &&
dependencies[current_dependencies_index] === signal && dependencies[current_dependencies_index] === signal &&
!(unowned && current_effect !== null) !(unowned && current_effect)
) { ) {
current_dependencies_index++; current_dependencies_index++;
} else if ( } else if (
dependencies === null || !dependencies ||
current_dependencies_index === 0 || !current_dependencies_index ||
dependencies[current_dependencies_index - 1] !== signal dependencies[current_dependencies_index - 1] !== signal
) { ) {
if (current_dependencies === null) { if (!current_dependencies) {
current_dependencies = [signal]; current_dependencies = [signal];
} else if (signal !== current_dependencies[current_dependencies.length - 1]) { } else if (signal !== current_dependencies[current_dependencies.length - 1]) {
current_dependencies.push(signal); current_dependencies.push(signal);
} }
} }
if ( if (
current_untracked_writes !== null && current_untracked_writes &&
current_effect !== null && current_effect &&
(current_effect.f & CLEAN) !== 0 && current_effect.f & CLEAN &&
current_untracked_writes.includes(signal) current_untracked_writes.includes(signal)
) { ) {
set_signal_status(current_effect, DIRTY); set_signal_status(current_effect, DIRTY);
@ -918,7 +896,7 @@ export function get(signal) {
} }
} }
if ((flags & DERIVED) !== 0 && is_signal_dirty(signal)) { if (flags & DERIVED && is_signal_dirty(signal)) {
if (DEV) { if (DEV) {
// we want to avoid tracking indirect dependencies // we want to avoid tracking indirect dependencies
const previous_inspect_fn = inspect_fn; const previous_inspect_fn = inspect_fn;
@ -1013,15 +991,15 @@ export function mutate_store(store, expression, new_value) {
*/ */
export function mark_subtree_inert(signal, inert) { export function mark_subtree_inert(signal, inert) {
const flags = signal.f; const flags = signal.f;
const is_already_inert = (flags & INERT) !== 0; const is_already_inert = !!(flags & INERT);
if (is_already_inert !== inert) { if (is_already_inert !== inert) {
signal.f ^= INERT; signal.f ^= INERT;
if (!inert && (flags & IS_EFFECT) !== 0 && (flags & CLEAN) === 0) { if (!inert && flags & IS_EFFECT && !(flags & CLEAN)) {
schedule_effect(/** @type {import('./types.js').EffectSignal} */ (signal), false); schedule_effect(/** @type {import('./types.js').EffectSignal} */ (signal), false);
} }
} }
const references = signal.r; const references = signal.r;
if (references !== null) { if (references) {
let i; let i;
for (i = 0; i < references.length; i++) { for (i = 0; i < references.length; i++) {
mark_subtree_inert(references[i], inert); mark_subtree_inert(references[i], inert);
@ -1039,14 +1017,14 @@ export function mark_subtree_inert(signal, inert) {
function mark_signal_consumers(signal, to_status, force_schedule) { function mark_signal_consumers(signal, to_status, force_schedule) {
const runes = is_runes(signal.x); const runes = is_runes(signal.x);
const consumers = signal.c; const consumers = signal.c;
if (consumers !== null) { if (consumers) {
const length = consumers.length; const length = consumers.length;
let i; let i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
const consumer = consumers[i]; const consumer = consumers[i];
const flags = consumer.f; const flags = consumer.f;
const unowned = (flags & UNOWNED) !== 0; const unowned = flags & UNOWNED;
const dirty = (flags & DIRTY) !== 0; const dirty = flags & DIRTY;
// We skip any effects that are already dirty (but not unowned). Additionally, we also // We skip any effects that are already dirty (but not unowned). Additionally, we also
// skip if the consumer is the same as the current effect (except if we're not in runes or we // skip if the consumer is the same as the current effect (except if we're not in runes or we
// are in force schedule mode). // are in force schedule mode).
@ -1057,8 +1035,8 @@ function mark_signal_consumers(signal, to_status, force_schedule) {
// If the signal is not clean, then skip over it with the exception of unowned signals that // If the signal is not clean, then skip over it with the exception of unowned signals that
// are already dirty. Unowned signals might be dirty because they are not captured as part of an // are already dirty. Unowned signals might be dirty because they are not captured as part of an
// effect. // effect.
if ((flags & CLEAN) !== 0 || (dirty && unowned)) { if (flags & CLEAN || (dirty && unowned)) {
if ((consumer.f & IS_EFFECT) !== 0) { if (consumer.f & IS_EFFECT) {
schedule_effect(/** @type {import('./types.js').EffectSignal} */ (consumer), false); schedule_effect(/** @type {import('./types.js').EffectSignal} */ (consumer), false);
} else { } else {
mark_signal_consumers(consumer, MAYBE_DIRTY, force_schedule); mark_signal_consumers(consumer, MAYBE_DIRTY, force_schedule);
@ -1078,9 +1056,9 @@ export function set_signal_value(signal, value) {
if ( if (
!current_untracking && !current_untracking &&
!ignore_mutation_validation && !ignore_mutation_validation &&
current_consumer !== null && current_consumer &&
is_runes(signal.x) && is_runes(signal.x) &&
(current_consumer.f & DERIVED) !== 0 current_consumer.f & DERIVED
) { ) {
throw new Error( throw new Error(
'ERR_SVELTE_UNSAFE_MUTATION' + 'ERR_SVELTE_UNSAFE_MUTATION' +
@ -1092,7 +1070,7 @@ export function set_signal_value(signal, value) {
); );
} }
if ( if (
(signal.f & SOURCE) !== 0 && signal.f & SOURCE &&
!(/** @type {import('./types.js').EqualsFunctions} */ (signal.e)(value, signal.v)) !(/** @type {import('./types.js').EqualsFunctions} */ (signal.e)(value, signal.v))
) { ) {
const component_context = signal.x; const component_context = signal.x;
@ -1107,18 +1085,18 @@ export function set_signal_value(signal, value) {
// //
if ( if (
is_runes(component_context) && is_runes(component_context) &&
current_effect !== null && current_effect &&
current_effect.c === null && !current_effect.c &&
(current_effect.f & CLEAN) !== 0 current_effect.f & CLEAN
) { ) {
if (current_dependencies !== null && current_dependencies.includes(signal)) { if (current_dependencies && current_dependencies.includes(signal)) {
set_signal_status(current_effect, DIRTY); set_signal_status(current_effect, DIRTY);
schedule_effect(current_effect, false); schedule_effect(current_effect, false);
} else { } else {
if (current_untracked_writes === null) { if (current_untracked_writes) {
current_untracked_writes = [signal];
} else {
current_untracked_writes.push(signal); current_untracked_writes.push(signal);
} else {
current_untracked_writes = [signal];
} }
} }
} }
@ -1126,9 +1104,9 @@ export function set_signal_value(signal, value) {
// If we have afterUpdates locally on the component, but we're within a render effect // If we have afterUpdates locally on the component, but we're within a render effect
// then we will need to manually invoke the beforeUpdate/afterUpdate logic. // then we will need to manually invoke the beforeUpdate/afterUpdate logic.
// TODO: should we put this being a is_runes check and only run it in non-runes mode? // TODO: should we put this being a is_runes check and only run it in non-runes mode?
if (current_effect === null && current_queued_pre_and_render_effects.length === 0) { if (!current_effect && !current_queued_pre_and_render_effects.length) {
const update_callbacks = component_context?.u; const update_callbacks = component_context?.u;
if (update_callbacks != null) { if (update_callbacks) {
run_all(update_callbacks.b); run_all(update_callbacks.b);
const managed = managed_effect(() => { const managed = managed_effect(() => {
destroy_signal(managed); destroy_signal(managed);
@ -1170,14 +1148,14 @@ export function destroy_signal(signal) {
signal.c = signal.c =
null; null;
set_signal_status(signal, DESTROYED); set_signal_status(signal, DESTROYED);
if (destroy !== null) { if (destroy) {
if (is_array(destroy)) { if (is_array(destroy)) {
run_all(destroy); run_all(destroy);
} else { } else {
destroy(); destroy();
} }
} }
if (teardown !== null && (flags & IS_EFFECT) !== 0) { if (teardown && flags & IS_EFFECT) {
teardown(); teardown();
} }
} }
@ -1189,7 +1167,7 @@ export function destroy_signal(signal) {
*/ */
/*#__NO_SIDE_EFFECTS__*/ /*#__NO_SIDE_EFFECTS__*/
export function derived(init) { export function derived(init) {
const is_unowned = current_effect === null; const is_unowned = !current_effect;
const flags = is_unowned ? DERIVED | UNOWNED : DERIVED; const flags = is_unowned ? DERIVED | UNOWNED : DERIVED;
const signal = /** @type {import('./types.js').ComputationSignal<V>} */ ( const signal = /** @type {import('./types.js').ComputationSignal<V>} */ (
create_computation_signal(flags | CLEAN, UNINITIALIZED, current_block) create_computation_signal(flags | CLEAN, UNINITIALIZED, current_block)
@ -1260,7 +1238,7 @@ function internal_create_effect(type, init, sync, block, schedule) {
if (schedule) { if (schedule) {
schedule_effect(signal, sync); schedule_effect(signal, sync);
} }
if (current_effect !== null && (type & MANAGED) === 0) { if (current_effect && !(type & MANAGED)) {
push_reference(current_effect, signal); push_reference(current_effect, signal);
} }
return signal; return signal;
@ -1270,7 +1248,7 @@ function internal_create_effect(type, init, sync, block, schedule) {
* @returns {boolean} * @returns {boolean}
*/ */
export function effect_active() { export function effect_active() {
return current_effect ? (current_effect.f & MANAGED) === 0 : false; return current_effect ? !(current_effect.f & MANAGED) : false;
} }
/** /**
@ -1278,16 +1256,14 @@ export function effect_active() {
* @returns {import('./types.js').EffectSignal} * @returns {import('./types.js').EffectSignal}
*/ */
export function user_effect(init) { export function user_effect(init) {
if (current_effect === null) { if (!current_effect) {
throw new Error( throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' + 'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV ? ': The Svelte $effect rune can only be used during component initialisation.' : '') (DEV ? ': The Svelte $effect rune can only be used during component initialisation.' : '')
); );
} }
const apply_component_effect_heuristics = const apply_component_effect_heuristics =
current_effect.f & RENDER_EFFECT && current_effect.f & RENDER_EFFECT && current_component_context && !current_component_context.m;
current_component_context !== null &&
!current_component_context.m;
const effect = internal_create_effect( const effect = internal_create_effect(
EFFECT, EFFECT,
init, init,
@ -1298,7 +1274,7 @@ export function user_effect(init) {
if (apply_component_effect_heuristics) { if (apply_component_effect_heuristics) {
let effects = /** @type {import('./types.js').ComponentContext} */ (current_component_context) let effects = /** @type {import('./types.js').ComponentContext} */ (current_component_context)
.e; .e;
if (effects === null) { if (!effects) {
effects = /** @type {import('./types.js').ComponentContext} */ (current_component_context).e = effects = /** @type {import('./types.js').ComponentContext} */ (current_component_context).e =
[]; [];
} }
@ -1348,7 +1324,7 @@ export function managed_pre_effect(init, sync) {
* @returns {import('./types.js').EffectSignal} * @returns {import('./types.js').EffectSignal}
*/ */
export function pre_effect(init) { export function pre_effect(init) {
if (current_effect === null) { if (!current_effect) {
throw new Error( throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' + 'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV (DEV
@ -1356,7 +1332,7 @@ export function pre_effect(init) {
: '') : '')
); );
} }
const sync = current_effect !== null && (current_effect.f & RENDER_EFFECT) !== 0; const sync = current_effect && !!(current_effect.f & RENDER_EFFECT);
return internal_create_effect( return internal_create_effect(
PRE_EFFECT, PRE_EFFECT,
() => { () => {
@ -1417,7 +1393,7 @@ export function managed_render_effect(init, block = current_block, sync = true)
*/ */
export function push_destroy_fn(signal, destroy_fn) { export function push_destroy_fn(signal, destroy_fn) {
let destroy = signal.y; let destroy = signal.y;
if (destroy === null) { if (!destroy) {
signal.y = destroy_fn; signal.y = destroy_fn;
} else if (is_array(destroy)) { } else if (is_array(destroy)) {
destroy.push(destroy_fn); destroy.push(destroy_fn);
@ -1445,7 +1421,7 @@ export function set_signal_status(signal, status) {
export function is_signal(val) { export function is_signal(val) {
return ( return (
typeof val === 'object' && typeof val === 'object' &&
val !== null && val &&
typeof (/** @type {import('./types.js').Signal<V>} */ (val).f) === 'number' typeof (/** @type {import('./types.js').Signal<V>} */ (val).f) === 'number'
); );
} }
@ -1459,7 +1435,7 @@ export function is_signal(val) {
export function is_lazy_property(val) { export function is_lazy_property(val) {
return ( return (
typeof val === 'object' && typeof val === 'object' &&
val !== null && val &&
/** @type {import('./types.js').LazyProperty<O, P>} */ (val).t === LAZY_PROPERTY /** @type {import('./types.js').LazyProperty<O, P>} */ (val).t === LAZY_PROPERTY
); );
} }
@ -1472,7 +1448,7 @@ export function is_lazy_property(val) {
export function is_store(val) { export function is_store(val) {
return ( return (
typeof val === 'object' && typeof val === 'object' &&
val !== null && !!val &&
typeof (/** @type {import('./types.js').Store<V>} */ (val).subscribe) === 'function' typeof (/** @type {import('./types.js').Store<V>} */ (val).subscribe) === 'function'
); );
} }
@ -1488,8 +1464,8 @@ export function is_store(val) {
* @returns {(() => V | ((arg: V) => V) | ((arg: V, mutation: boolean) => V))} * @returns {(() => V | ((arg: V) => V) | ((arg: V, mutation: boolean) => V))}
*/ */
export function prop(props, key, flags, initial) { export function prop(props, key, flags, initial) {
var immutable = (flags & PROPS_IS_IMMUTABLE) !== 0; var immutable = flags & PROPS_IS_IMMUTABLE;
var runes = (flags & PROPS_IS_RUNES) !== 0; var runes = flags & PROPS_IS_RUNES;
var setter = get_descriptor(props, key)?.set; var setter = get_descriptor(props, key)?.set;
if (DEV && setter && runes && initial !== undefined) { if (DEV && setter && runes && initial !== undefined) {
@ -1501,7 +1477,7 @@ export function prop(props, key, flags, initial) {
if (prop_value === undefined && initial !== undefined) { if (prop_value === undefined && initial !== undefined) {
// @ts-expect-error would need a cumbersome method overload to type this // @ts-expect-error would need a cumbersome method overload to type this
if ((flags & PROPS_IS_LAZY_INITIAL) !== 0) initial = initial(); if (flags & PROPS_IS_LAZY_INITIAL) initial = initial();
if (DEV && runes) { if (DEV && runes) {
initial = readonly(proxy(/** @type {any} */ (initial))); initial = readonly(proxy(/** @type {any} */ (initial)));
@ -1519,7 +1495,7 @@ export function prop(props, key, flags, initial) {
}; };
// easy mode — prop is never written to // easy mode — prop is never written to
if ((flags & PROPS_IS_UPDATED) === 0) { if (!(flags & PROPS_IS_UPDATED)) {
return getter; return getter;
} }
@ -1614,14 +1590,14 @@ export function safe_equal(a, b) {
/** @returns {Map<unknown, unknown>} */ /** @returns {Map<unknown, unknown>} */
export function get_or_init_context_map() { export function get_or_init_context_map() {
const component_context = current_component_context; const component_context = current_component_context;
if (component_context === null) { if (!component_context) {
throw new Error( throw new Error(
'ERR_SVELTE_ORPHAN_CONTEXT' + 'ERR_SVELTE_ORPHAN_CONTEXT' +
(DEV ? 'Context can only be used during component initialisation.' : '') (DEV ? 'Context can only be used during component initialisation.' : '')
); );
} }
let context_map = component_context.c; let context_map = component_context.c;
if (context_map === null) { if (!context_map) {
const parent_context = get_parent_context(component_context); const parent_context = get_parent_context(component_context);
context_map = component_context.c = new Map(parent_context || undefined); context_map = component_context.c = new Map(parent_context || undefined);
} }
@ -1634,9 +1610,9 @@ export function get_or_init_context_map() {
*/ */
function get_parent_context(component_context) { function get_parent_context(component_context) {
let parent = component_context.p; let parent = component_context.p;
while (parent !== null) { while (parent) {
const context_map = parent.c; const context_map = parent.c;
if (context_map !== null) { if (context_map) {
return context_map; return context_map;
} }
parent = parent.p; parent = parent.p;
@ -1818,12 +1794,12 @@ export function push(props, runes = false) {
*/ */
export function pop(accessors) { export function pop(accessors) {
const context_stack_item = current_component_context; const context_stack_item = current_component_context;
if (context_stack_item !== null) { if (context_stack_item) {
if (accessors !== undefined) { if (accessors) {
context_stack_item.a = accessors; context_stack_item.a = accessors;
} }
const effects = context_stack_item.e; const effects = context_stack_item.e;
if (effects !== null) { if (effects) {
context_stack_item.e = null; context_stack_item.e = null;
for (let i = 0; i < effects.length; i++) { for (let i = 0; i < effects.length; i++) {
schedule_effect(effects[i], false); schedule_effect(effects[i], false);

@ -8,7 +8,7 @@ import { EMPTY_FUNC } from '../internal/common.js';
* @returns {() => void} * @returns {() => void}
*/ */
export function subscribe_to_store(store, run, invalidate) { export function subscribe_to_store(store, run, invalidate) {
if (store == null) { if (!store) {
// @ts-expect-error // @ts-expect-error
run(undefined); run(undefined);

Loading…
Cancel
Save