From bce557cc2dc767628bed6aac87301a1be7c5431b Mon Sep 17 00:00:00 2001 From: rxliuli Date: Tue, 4 Nov 2025 05:03:50 +0800 Subject: init commit --- .../svelte/src/runtime/internal/scheduler.js | 135 +++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 node_modules/svelte/src/runtime/internal/scheduler.js (limited to 'node_modules/svelte/src/runtime/internal/scheduler.js') diff --git a/node_modules/svelte/src/runtime/internal/scheduler.js b/node_modules/svelte/src/runtime/internal/scheduler.js new file mode 100644 index 0000000..e62f536 --- /dev/null +++ b/node_modules/svelte/src/runtime/internal/scheduler.js @@ -0,0 +1,135 @@ +import { run_all } from './utils.js'; +import { current_component, set_current_component } from './lifecycle.js'; + +export const dirty_components = []; +export const intros = { enabled: false }; +export const binding_callbacks = []; + +let render_callbacks = []; + +const flush_callbacks = []; + +const resolved_promise = /* @__PURE__ */ Promise.resolve(); + +let update_scheduled = false; + +/** @returns {void} */ +export function schedule_update() { + if (!update_scheduled) { + update_scheduled = true; + resolved_promise.then(flush); + } +} + +/** @returns {Promise} */ +export function tick() { + schedule_update(); + return resolved_promise; +} + +/** @returns {void} */ +export function add_render_callback(fn) { + render_callbacks.push(fn); +} + +/** @returns {void} */ +export function add_flush_callback(fn) { + flush_callbacks.push(fn); +} + +// flush() calls callbacks in this order: +// 1. All beforeUpdate callbacks, in order: parents before children +// 2. All bind:this callbacks, in reverse order: children before parents. +// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT +// for afterUpdates called during the initial onMount, which are called in +// reverse order: children before parents. +// Since callbacks might update component values, which could trigger another +// call to flush(), the following steps guard against this: +// 1. During beforeUpdate, any updated components will be added to the +// dirty_components array and will cause a reentrant call to flush(). Because +// the flush index is kept outside the function, the reentrant call will pick +// up where the earlier call left off and go through all dirty components. The +// current_component value is saved and restored so that the reentrant call will +// not interfere with the "parent" flush() call. +// 2. bind:this callbacks cannot trigger new flush() calls. +// 3. During afterUpdate, any updated components will NOT have their afterUpdate +// callback called a second time; the seen_callbacks set, outside the flush() +// function, guarantees this behavior. +const seen_callbacks = new Set(); + +let flushidx = 0; // Do *not* move this inside the flush() function + +/** @returns {void} */ +export function flush() { + // Do not reenter flush while dirty components are updated, as this can + // result in an infinite loop. Instead, let the inner flush handle it. + // Reentrancy is ok afterwards for bindings etc. + if (flushidx !== 0) { + return; + } + const saved_component = current_component; + do { + // first, call beforeUpdate functions + // and update components + try { + while (flushidx < dirty_components.length) { + const component = dirty_components[flushidx]; + flushidx++; + set_current_component(component); + update(component.$$); + } + } catch (e) { + // reset dirty state to not end up in a deadlocked state and then rethrow + dirty_components.length = 0; + flushidx = 0; + throw e; + } + set_current_component(null); + dirty_components.length = 0; + flushidx = 0; + while (binding_callbacks.length) binding_callbacks.pop()(); + // then, once components are updated, call + // afterUpdate functions. This may cause + // subsequent updates... + for (let i = 0; i < render_callbacks.length; i += 1) { + const callback = render_callbacks[i]; + if (!seen_callbacks.has(callback)) { + // ...so guard against infinite loops + seen_callbacks.add(callback); + callback(); + } + } + render_callbacks.length = 0; + } while (dirty_components.length); + while (flush_callbacks.length) { + flush_callbacks.pop()(); + } + update_scheduled = false; + seen_callbacks.clear(); + set_current_component(saved_component); +} + +/** @returns {void} */ +function update($$) { + if ($$.fragment !== null) { + $$.update(); + run_all($$.before_update); + const dirty = $$.dirty; + $$.dirty = [-1]; + $$.fragment && $$.fragment.p($$.ctx, dirty); + $$.after_update.forEach(add_render_callback); + } +} + +/** + * Useful for example to execute remaining `afterUpdate` callbacks before executing `destroy`. + * @param {Function[]} fns + * @returns {void} + */ +export function flush_render_callbacks(fns) { + const filtered = []; + const targets = []; + render_callbacks.forEach((c) => (fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c))); + targets.forEach((c) => c()); + render_callbacks = filtered; +} -- cgit v1.2.3