From fb6a83acf91841f926318dafaabdb3823b408fbc Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 8 May 2023 22:02:38 -0600 Subject: [PATCH] Convert src/runtime/internal/scheduler.ts to JavaScript --- src/runtime/internal/scheduler.ts | 172 ++++++++++++++---------------- 1 file changed, 82 insertions(+), 90 deletions(-) diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 0330f64f53..bf153d95ab 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -1,36 +1,32 @@ import { run_all } from './utils'; import { current_component, set_current_component } from './lifecycle'; - 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); - } + if (!update_scheduled) { + update_scheduled = true; + resolved_promise.then(flush); + } } - +/** @returns {Promise} */ export function tick() { - schedule_update(); - return resolved_promise; + schedule_update(); + return resolved_promise; } - +/** @returns {void} */ export function add_render_callback(fn) { - render_callbacks.push(fn); + render_callbacks.push(fn); } - +/** @returns {void} */ export function add_flush_callback(fn) { - flush_callbacks.push(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. @@ -51,85 +47,81 @@ export function add_flush_callback(fn) { // 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); + // 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); - } + 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: Function[]): void { - 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; +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; } + + + +