|
|
|
|
@ -9,23 +9,23 @@ 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<void>} */
|
|
|
|
|
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
|
|
|
|
|
@ -49,65 +49,63 @@ 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`.
|
|
|
|
|
@ -115,13 +113,9 @@ function update($$) {
|
|
|
|
|
* @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;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|