diff --git a/.changeset/violet-camels-heal.md b/.changeset/violet-camels-heal.md new file mode 100644 index 000000000000..31e72fa33d53 --- /dev/null +++ b/.changeset/violet-camels-heal.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: update types and inline docs for flushSync diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_avoidable.js b/benchmarking/benchmarks/reactivity/kairo/kairo_avoidable.js index 6b058cdc3c1d..9daea6de99cb 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_avoidable.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_avoidable.js @@ -20,12 +20,12 @@ function setup() { return { destroy, run() { - $.flush_sync(() => { + $.flush(() => { $.set(head, 1); }); assert($.get(computed5) === 6); for (let i = 0; i < 1000; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(head, i); }); assert($.get(computed5) === 6); diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_broad.js b/benchmarking/benchmarks/reactivity/kairo/kairo_broad.js index d1cde5958edf..8dc5710c87db 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_broad.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_broad.js @@ -25,12 +25,12 @@ function setup() { return { destroy, run() { - $.flush_sync(() => { + $.flush(() => { $.set(head, 1); }); counter = 0; for (let i = 0; i < 50; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(head, i); }); assert($.get(last) === i + 50); diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_deep.js b/benchmarking/benchmarks/reactivity/kairo/kairo_deep.js index 149457ede156..8690c85f864a 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_deep.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_deep.js @@ -25,12 +25,12 @@ function setup() { return { destroy, run() { - $.flush_sync(() => { + $.flush(() => { $.set(head, 1); }); counter = 0; for (let i = 0; i < iter; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(head, i); }); assert($.get(current) === len + i); diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_diamond.js b/benchmarking/benchmarks/reactivity/kairo/kairo_diamond.js index 958a1bcd7890..bf4e07ee8962 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_diamond.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_diamond.js @@ -28,13 +28,13 @@ function setup() { return { destroy, run() { - $.flush_sync(() => { + $.flush(() => { $.set(head, 1); }); assert($.get(sum) === 2 * width); counter = 0; for (let i = 0; i < 500; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(head, i); }); assert($.get(sum) === (i + 1) * width); diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_mux.js b/benchmarking/benchmarks/reactivity/kairo/kairo_mux.js index b645051c09bf..fc252a27b5f8 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_mux.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_mux.js @@ -22,13 +22,13 @@ function setup() { destroy, run() { for (let i = 0; i < 10; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(heads[i], i); }); assert($.get(splited[i]) === i + 1); } for (let i = 0; i < 10; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(heads[i], i * 2); }); assert($.get(splited[i]) === i * 2 + 1); diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_repeated.js b/benchmarking/benchmarks/reactivity/kairo/kairo_repeated.js index 53b85acd3766..3bee06ca0e8f 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_repeated.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_repeated.js @@ -25,13 +25,13 @@ function setup() { return { destroy, run() { - $.flush_sync(() => { + $.flush(() => { $.set(head, 1); }); assert($.get(current) === size); counter = 0; for (let i = 0; i < 100; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(head, i); }); assert($.get(current) === i * size); diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_triangle.js b/benchmarking/benchmarks/reactivity/kairo/kairo_triangle.js index b9e2ad9fa4a3..11a419a52e7b 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_triangle.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_triangle.js @@ -38,13 +38,13 @@ function setup() { destroy, run() { const constant = count(width); - $.flush_sync(() => { + $.flush(() => { $.set(head, 1); }); assert($.get(sum) === constant); counter = 0; for (let i = 0; i < 100; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(head, i); }); assert($.get(sum) === constant - width + i * width); diff --git a/benchmarking/benchmarks/reactivity/kairo/kairo_unstable.js b/benchmarking/benchmarks/reactivity/kairo/kairo_unstable.js index 0e783732dc67..54eb732cb29d 100644 --- a/benchmarking/benchmarks/reactivity/kairo/kairo_unstable.js +++ b/benchmarking/benchmarks/reactivity/kairo/kairo_unstable.js @@ -25,13 +25,13 @@ function setup() { return { destroy, run() { - $.flush_sync(() => { + $.flush(() => { $.set(head, 1); }); assert($.get(current) === 40); counter = 0; for (let i = 0; i < 100; i++) { - $.flush_sync(() => { + $.flush(() => { $.set(head, i); }); } diff --git a/benchmarking/benchmarks/reactivity/mol_bench.js b/benchmarking/benchmarks/reactivity/mol_bench.js index c9f492f61967..536b078d74a4 100644 --- a/benchmarking/benchmarks/reactivity/mol_bench.js +++ b/benchmarking/benchmarks/reactivity/mol_bench.js @@ -51,11 +51,11 @@ function setup() { */ run(i) { res.length = 0; - $.flush_sync(() => { + $.flush(() => { $.set(B, 1); $.set(A, 1 + i * 2); }); - $.flush_sync(() => { + $.flush(() => { $.set(A, 2 + i * 2); $.set(B, 2); }); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js index 2e6307a4b7a6..cf5ba285cbf3 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js @@ -312,7 +312,7 @@ export function client_component(analysis, options) { const setter = b.set(key, [ b.stmt(b.call(b.id(name), b.id('$$value'))), - b.stmt(b.call('$.flush_sync')) + b.stmt(b.call('$.flush')) ]); if (analysis.runes && binding.initial) { diff --git a/packages/svelte/src/index-client.js b/packages/svelte/src/index-client.js index ca29d5bfbe3c..efcf7b727b8d 100644 --- a/packages/svelte/src/index-client.js +++ b/packages/svelte/src/index-client.js @@ -1,7 +1,7 @@ /** @import { ComponentContext, ComponentContextLegacy } from '#client' */ /** @import { EventDispatcher } from './index.js' */ /** @import { NotFunction } from './internal/types.js' */ -import { flush_sync, untrack } from './internal/client/runtime.js'; +import { untrack } from './internal/client/runtime.js'; import { is_array } from './internal/shared/utils.js'; import { user_effect } from './internal/client/index.js'; import * as e from './internal/client/errors.js'; @@ -206,15 +206,7 @@ function init_update_callbacks(context) { return (l.u ??= { a: [], b: [], m: [] }); } -/** - * Synchronously flushes any pending state changes and those that result from it. - * @param {() => void} [fn] - * @returns {void} - */ -export function flushSync(fn) { - flush_sync(fn); -} - +export { flushSync } from './internal/client/runtime.js'; export { getContext, getAllContexts, hasContext, setContext } from './internal/client/context.js'; export { hydrate, mount, unmount } from './internal/client/render.js'; export { tick, untrack } from './internal/client/runtime.js'; diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index c8c7c1c0ea77..2e3d22977914 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -3,7 +3,7 @@ import { DEV } from 'esm-env'; import { is_promise } from '../../../shared/utils.js'; import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js'; import { internal_set, mutable_source, source } from '../../reactivity/sources.js'; -import { flush_sync, set_active_effect, set_active_reaction } from '../../runtime.js'; +import { flushSync, set_active_effect, set_active_reaction } from '../../runtime.js'; import { hydrate_next, hydrate_node, hydrating } from '../hydration.js'; import { queue_micro_task } from '../task.js'; import { UNINITIALIZED } from '../../../../constants.js'; @@ -105,7 +105,7 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { // without this, the DOM does not update until two ticks after the promise // resolves, which is unexpected behaviour (and somewhat irksome to test) - flush_sync(); + flushSync(); } } } diff --git a/packages/svelte/src/internal/client/dom/task.js b/packages/svelte/src/internal/client/dom/task.js index acb5a5b117f0..fe37d4828f7a 100644 --- a/packages/svelte/src/internal/client/dom/task.js +++ b/packages/svelte/src/internal/client/dom/task.js @@ -6,25 +6,21 @@ export const request_idle_callback = ? (/** @type {() => void} */ cb) => setTimeout(cb, 1) : requestIdleCallback; -let is_micro_task_queued = false; -let is_idle_task_queued = false; - /** @type {Array<() => void>} */ -let current_queued_micro_tasks = []; +let micro_tasks = []; + /** @type {Array<() => void>} */ -let current_queued_idle_tasks = []; +let idle_tasks = []; -function process_micro_tasks() { - is_micro_task_queued = false; - const tasks = current_queued_micro_tasks.slice(); - current_queued_micro_tasks = []; +function run_micro_tasks() { + var tasks = micro_tasks; + micro_tasks = []; run_all(tasks); } -function process_idle_tasks() { - is_idle_task_queued = false; - const tasks = current_queued_idle_tasks.slice(); - current_queued_idle_tasks = []; +function run_idle_tasks() { + var tasks = idle_tasks; + idle_tasks = []; run_all(tasks); } @@ -32,32 +28,33 @@ function process_idle_tasks() { * @param {() => void} fn */ export function queue_micro_task(fn) { - if (!is_micro_task_queued) { - is_micro_task_queued = true; - queueMicrotask(process_micro_tasks); + if (micro_tasks.length === 0) { + queueMicrotask(run_micro_tasks); } - current_queued_micro_tasks.push(fn); + + micro_tasks.push(fn); } /** * @param {() => void} fn */ export function queue_idle_task(fn) { - if (!is_idle_task_queued) { - is_idle_task_queued = true; - request_idle_callback(process_idle_tasks); + if (idle_tasks.length === 0) { + request_idle_callback(run_idle_tasks); } - current_queued_idle_tasks.push(fn); + + idle_tasks.push(fn); } /** * Synchronously run any queued tasks. */ export function flush_tasks() { - if (is_micro_task_queued) { - process_micro_tasks(); + if (micro_tasks.length > 0) { + run_micro_tasks(); } - if (is_idle_task_queued) { - process_idle_tasks(); + + if (idle_tasks.length > 0) { + run_idle_tasks(); } } diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index d78f6d452e84..f5ccb9413ba0 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -137,7 +137,7 @@ export { get, safe_get, invalidate_inner_signals, - flush_sync, + flushSync as flush, tick, untrack, exclude_from_object, diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 9d7b5e9de624..28589ce94df1 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -6,15 +6,12 @@ import { update_effect, get, is_destroying_effect, - is_flushing_effect, remove_reactions, schedule_effect, set_active_reaction, set_is_destroying_effect, - set_is_flushing_effect, set_signal_status, untrack, - skip_reaction, untracking } from '../runtime.js'; import { @@ -118,17 +115,12 @@ function create_effect(type, fn, sync, push = true) { } if (sync) { - var previously_flushing_effect = is_flushing_effect; - try { - set_is_flushing_effect(true); update_effect(effect); effect.f |= EFFECT_RAN; } catch (e) { destroy_effect(effect); throw e; - } finally { - set_is_flushing_effect(previously_flushing_effect); } } else if (fn !== null) { schedule_effect(effect); diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index ded0ca05846b..f6a3fd7e330a 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -14,8 +14,6 @@ import { derived_sources, set_derived_sources, check_dirtiness, - set_is_flushing_effect, - is_flushing_effect, untracking } from '../runtime.js'; import { equals, safe_equals } from './equality.js'; @@ -202,22 +200,18 @@ export function internal_set(source, value) { if (DEV && inspect_effects.size > 0) { const inspects = Array.from(inspect_effects); - var previously_flushing_effect = is_flushing_effect; - set_is_flushing_effect(true); - try { - for (const effect of inspects) { - // Mark clean inspect-effects as maybe dirty and then check their dirtiness - // instead of just updating the effects - this way we avoid overfiring. - if ((effect.f & CLEAN) !== 0) { - set_signal_status(effect, MAYBE_DIRTY); - } - if (check_dirtiness(effect)) { - update_effect(effect); - } + + for (const effect of inspects) { + // Mark clean inspect-effects as maybe dirty and then check their dirtiness + // instead of just updating the effects - this way we avoid overfiring. + if ((effect.f & CLEAN) !== 0) { + set_signal_status(effect, MAYBE_DIRTY); + } + if (check_dirtiness(effect)) { + update_effect(effect); } - } finally { - set_is_flushing_effect(previously_flushing_effect); } + inspect_effects.clear(); } } diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 8c98f948f3f0..cd3f794421b7 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -9,7 +9,6 @@ import { } from './reactivity/effects.js'; import { EFFECT, - RENDER_EFFECT, DIRTY, MAYBE_DIRTY, CLEAN, @@ -41,28 +40,19 @@ import { } from './context.js'; import { is_firefox } from './dom/operations.js'; -const FLUSH_MICROTASK = 0; -const FLUSH_SYNC = 1; // Used for DEV time error handling /** @param {WeakSet} value */ const handled_errors = new WeakSet(); export let is_throwing_error = false; -// Used for controlling the flush of effects. -let scheduler_mode = FLUSH_MICROTASK; -// Used for handling scheduling -let is_micro_task_queued = false; +let is_flushing = false; /** @type {Effect | null} */ let last_scheduled_effect = null; -export let is_flushing_effect = false; -export let is_destroying_effect = false; +let is_updating_effect = false; -/** @param {boolean} value */ -export function set_is_flushing_effect(value) { - is_flushing_effect = value; -} +export let is_destroying_effect = false; /** @param {boolean} value */ export function set_is_destroying_effect(value) { @@ -74,7 +64,6 @@ export function set_is_destroying_effect(value) { /** @type {Effect[]} */ let queued_root_effects = []; -let flush_count = 0; /** @type {Effect[]} Stack of effects, dev only */ let dev_effect_stack = []; // Handle signal reactivity tree dependencies and reactions @@ -410,10 +399,9 @@ export function update_reaction(reaction) { new_deps = /** @type {null | Value[]} */ (null); skipped_deps = 0; untracked_writes = null; - active_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null; skip_reaction = - (flags & UNOWNED) !== 0 && - (!is_flushing_effect || previous_reaction === null || previous_untracking); + (flags & UNOWNED) !== 0 && (untracking || !is_updating_effect || active_reaction === null); + active_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null; derived_sources = null; set_component_context(reaction.ctx); @@ -559,8 +547,10 @@ export function update_effect(effect) { var previous_effect = active_effect; var previous_component_context = component_context; + var was_updating_effect = is_updating_effect; active_effect = effect; + is_updating_effect = true; if (DEV) { var previous_component_fn = dev_current_component_function; @@ -602,6 +592,7 @@ export function update_effect(effect) { } catch (error) { handle_error(error, effect, previous_effect, previous_component_context || effect.ctx); } finally { + is_updating_effect = was_updating_effect; active_effect = previous_effect; if (DEV) { @@ -620,69 +611,70 @@ function log_effect_stack() { } function infinite_loop_guard() { - if (flush_count > 1000) { - flush_count = 0; - try { - e.effect_update_depth_exceeded(); - } catch (error) { + try { + e.effect_update_depth_exceeded(); + } catch (error) { + if (DEV) { + // stack is garbage, ignore. Instead add a console.error message. + define_property(error, 'stack', { + value: '' + }); + } + // Try and handle the error so it can be caught at a boundary, that's + // if there's an effect available from when it was last scheduled + if (last_scheduled_effect !== null) { if (DEV) { - // stack is garbage, ignore. Instead add a console.error message. - define_property(error, 'stack', { - value: '' - }); - } - // Try and handle the error so it can be caught at a boundary, that's - // if there's an effect available from when it was last scheduled - if (last_scheduled_effect !== null) { - if (DEV) { - try { - handle_error(error, last_scheduled_effect, null, null); - } catch (e) { - // Only log the effect stack if the error is re-thrown - log_effect_stack(); - throw e; - } - } else { + try { handle_error(error, last_scheduled_effect, null, null); - } - } else { - if (DEV) { + } catch (e) { + // Only log the effect stack if the error is re-thrown log_effect_stack(); + throw e; } - throw error; + } else { + handle_error(error, last_scheduled_effect, null, null); } + } else { + if (DEV) { + log_effect_stack(); + } + throw error; } } - flush_count++; } -/** - * @param {Array} root_effects - * @returns {void} - */ -function flush_queued_root_effects(root_effects) { - var length = root_effects.length; - if (length === 0) { - return; - } - infinite_loop_guard(); - - var previously_flushing_effect = is_flushing_effect; - is_flushing_effect = true; - +function flush_queued_root_effects() { try { - for (var i = 0; i < length; i++) { - var effect = root_effects[i]; + var flush_count = 0; - if ((effect.f & CLEAN) === 0) { - effect.f ^= CLEAN; + while (queued_root_effects.length > 0) { + if (flush_count++ > 1000) { + infinite_loop_guard(); } - var collected_effects = process_effects(effect); - flush_queued_effects(collected_effects); + var root_effects = queued_root_effects; + var length = root_effects.length; + + queued_root_effects = []; + + for (var i = 0; i < length; i++) { + var root = root_effects[i]; + + if ((root.f & CLEAN) === 0) { + root.f ^= CLEAN; + } + + var collected_effects = process_effects(root); + flush_queued_effects(collected_effects); + } } } finally { - is_flushing_effect = previously_flushing_effect; + is_flushing = false; + + last_scheduled_effect = null; + if (DEV) { + dev_effect_stack = []; + } } } @@ -724,39 +716,17 @@ function flush_queued_effects(effects) { } } -function process_deferred() { - is_micro_task_queued = false; - if (flush_count > 1001) { - return; - } - const previous_queued_root_effects = queued_root_effects; - queued_root_effects = []; - flush_queued_root_effects(previous_queued_root_effects); - - if (!is_micro_task_queued) { - flush_count = 0; - last_scheduled_effect = null; - if (DEV) { - dev_effect_stack = []; - } - } -} - /** * @param {Effect} signal * @returns {void} */ export function schedule_effect(signal) { - if (scheduler_mode === FLUSH_MICROTASK) { - if (!is_micro_task_queued) { - is_micro_task_queued = true; - queueMicrotask(process_deferred); - } + if (!is_flushing) { + is_flushing = true; + queueMicrotask(flush_queued_root_effects); } - last_scheduled_effect = signal; - - var effect = signal; + var effect = (last_scheduled_effect = signal); while (effect.parent !== null) { effect = effect.parent; @@ -846,42 +816,30 @@ function process_effects(effect) { } /** - * Internal version of `flushSync` with the option to not flush previous effects. - * Returns the result of the passed function, if given. - * @param {() => any} [fn] - * @returns {any} + * Synchronously flush any pending updates. + * Returns void if no callback is provided, otherwise returns the result of calling the callback. + * @template [T=void] + * @param {(() => T) | undefined} [fn] + * @returns {T} */ -export function flush_sync(fn) { - var previous_scheduler_mode = scheduler_mode; - var previous_queued_root_effects = queued_root_effects; - - try { - infinite_loop_guard(); +export function flushSync(fn) { + var result; - scheduler_mode = FLUSH_SYNC; - queued_root_effects = []; - is_micro_task_queued = false; - - flush_queued_root_effects(previous_queued_root_effects); + if (fn) { + is_flushing = true; + flush_queued_root_effects(); + result = fn(); + } - var result = fn?.(); + flush_tasks(); + while (queued_root_effects.length > 0) { + is_flushing = true; + flush_queued_root_effects(); flush_tasks(); - if (queued_root_effects.length > 0) { - flush_sync(); - } - - flush_count = 0; - last_scheduled_effect = null; - if (DEV) { - dev_effect_stack = []; - } - - return result; - } finally { - scheduler_mode = previous_scheduler_mode; - queued_root_effects = previous_queued_root_effects; } + + return /** @type {T} */ (result); } /** @@ -890,9 +848,9 @@ export function flush_sync(fn) { */ export async function tick() { await Promise.resolve(); - // By calling flush_sync we guarantee that any pending state changes are applied after one tick. + // By calling flushSync we guarantee that any pending state changes are applied after one tick. // TODO look into whether we can make flushing subsequent updates synchronously in the future. - flush_sync(); + flushSync(); } /** diff --git a/packages/svelte/src/legacy/legacy-client.js b/packages/svelte/src/legacy/legacy-client.js index 3a05bc04963f..bb9a5a9c039b 100644 --- a/packages/svelte/src/legacy/legacy-client.js +++ b/packages/svelte/src/legacy/legacy-client.js @@ -3,7 +3,7 @@ import { DIRTY, LEGACY_PROPS, MAYBE_DIRTY } from '../internal/client/constants.j import { user_pre_effect } from '../internal/client/reactivity/effects.js'; import { mutable_source, set } from '../internal/client/reactivity/sources.js'; import { hydrate, mount, unmount } from '../internal/client/render.js'; -import { active_effect, flush_sync, get, set_signal_status } from '../internal/client/runtime.js'; +import { active_effect, flushSync, get, set_signal_status } from '../internal/client/runtime.js'; import { lifecycle_outside_component } from '../internal/shared/errors.js'; import { define_property, is_array } from '../internal/shared/utils.js'; import * as w from '../internal/client/warnings.js'; @@ -119,9 +119,9 @@ class Svelte4Component { recover: options.recover }); - // We don't flush_sync for custom element wrappers or if the user doesn't want it + // We don't flushSync for custom element wrappers or if the user doesn't want it if (!options?.props?.$$host || options.sync === false) { - flush_sync(); + flushSync(); } this.#events = props.$$events; diff --git a/packages/svelte/tests/runtime-legacy/samples/animation-css/_config.js b/packages/svelte/tests/runtime-legacy/samples/animation-css/_config.js index b6b601a96b1d..b6bd818e65db 100644 --- a/packages/svelte/tests/runtime-legacy/samples/animation-css/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/animation-css/_config.js @@ -47,6 +47,8 @@ export default test({ { id: 1, name: 'a' } ]; + raf.tick(0); + divs = target.querySelectorAll('div'); assert.ok(divs[0].getAnimations().length > 0); assert.equal(divs[1].getAnimations().length, 0); diff --git a/packages/svelte/tests/runtime-legacy/samples/animation-js-easing/_config.js b/packages/svelte/tests/runtime-legacy/samples/animation-js-easing/_config.js index 5b7ed1c73209..f4a3554b29f9 100644 --- a/packages/svelte/tests/runtime-legacy/samples/animation-js-easing/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/animation-js-easing/_config.js @@ -46,6 +46,8 @@ export default test({ { id: 1, name: 'a' } ]; + raf.tick(0); + divs = document.querySelectorAll('div'); assert.equal(divs[0].dy, 120); assert.equal(divs[4].dy, -120); diff --git a/packages/svelte/tests/runtime-legacy/samples/animation-js/_config.js b/packages/svelte/tests/runtime-legacy/samples/animation-js/_config.js index 3606f7d17b77..a2e17b49f869 100644 --- a/packages/svelte/tests/runtime-legacy/samples/animation-js/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/animation-js/_config.js @@ -46,6 +46,8 @@ export default test({ { id: 1, name: 'a' } ]; + raf.tick(0); + divs = document.querySelectorAll('div'); assert.equal(divs[0].dy, 120); assert.equal(divs[4].dy, -120); @@ -66,6 +68,8 @@ export default test({ { id: 5, name: 'e' } ]; + raf.tick(100); + divs = document.querySelectorAll('div'); assert.equal(divs[0].dy, 120); diff --git a/packages/svelte/tests/runtime-legacy/samples/dynamic-element-animation/_config.js b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-animation/_config.js index 3d127f1375e7..05c2dc73048a 100644 --- a/packages/svelte/tests/runtime-legacy/samples/dynamic-element-animation/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/dynamic-element-animation/_config.js @@ -50,6 +50,8 @@ export default test({ { id: 1, name: 'a' } ]; + raf.tick(0); + divs = target.querySelectorAll('div'); assert.equal(divs[0].style.transform, 'translate(0px, 120px)'); assert.equal(divs[1].style.transform, ''); diff --git a/packages/svelte/tests/store/test.ts b/packages/svelte/tests/store/test.ts index b23ea195d6c9..77cecca7e525 100644 --- a/packages/svelte/tests/store/test.ts +++ b/packages/svelte/tests/store/test.ts @@ -602,7 +602,7 @@ describe('toStore', () => { assert.deepEqual(log, [0]); set(count, 1); - $.flush_sync(); + $.flushSync(); assert.deepEqual(log, [0, 1]); unsubscribe(); @@ -625,7 +625,7 @@ describe('toStore', () => { assert.deepEqual(log, [0]); set(count, 1); - $.flush_sync(); + $.flushSync(); assert.deepEqual(log, [0, 1]); store.set(2); @@ -654,11 +654,11 @@ describe('fromStore', () => { assert.deepEqual(log, [0]); store.set(1); - $.flush_sync(); + $.flushSync(); assert.deepEqual(log, [0, 1]); count.current = 2; - $.flush_sync(); + $.flushSync(); assert.deepEqual(log, [0, 1, 2]); assert.equal(get(store), 2); diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 77d78477ee93..4cb66aa87d30 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -408,10 +408,6 @@ declare module 'svelte' { * @deprecated Use [`$effect`](https://svelte.dev/docs/svelte/$effect) instead * */ export function afterUpdate(fn: () => void): void; - /** - * Synchronously flushes any pending state changes and those that result from it. - * */ - export function flushSync(fn?: (() => void) | undefined): void; /** * Create a snippet programmatically * */ @@ -421,6 +417,29 @@ declare module 'svelte' { }): Snippet; /** Anything except a function */ type NotFunction = T extends Function ? never : T; + /** + * Synchronously flush any pending updates. + * Returns void if no callback is provided, otherwise returns the result of calling the callback. + * */ + export function flushSync(fn?: (() => T) | undefined): T; + /** + * Returns a promise that resolves once any pending state changes have been applied. + * */ + export function tick(): Promise; + /** + * When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect), + * any state read inside `fn` will not be treated as a dependency. + * + * ```ts + * $effect(() => { + * // this will run when `data` changes, but not when `time` changes + * save(data, { + * timestamp: untrack(() => time) + * }); + * }); + * ``` + * */ + export function untrack(fn: () => T): T; /** * Retrieves the context that belongs to the closest parent component with the specified `key`. * Must be called during component initialisation. @@ -494,24 +513,6 @@ declare module 'svelte' { export function unmount(component: Record, options?: { outro?: boolean; } | undefined): Promise; - /** - * Returns a promise that resolves once any pending state changes have been applied. - * */ - export function tick(): Promise; - /** - * When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect), - * any state read inside `fn` will not be treated as a dependency. - * - * ```ts - * $effect(() => { - * // this will run when `data` changes, but not when `time` changes - * save(data, { - * timestamp: untrack(() => time) - * }); - * }); - * ``` - * */ - export function untrack(fn: () => T): T; type Getters = { [K in keyof T]: () => T[K]; }; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy