move some code

pull/15844/head
Rich Harris 2 months ago
parent 2f227b1218
commit 74b7f89679

@ -366,69 +366,6 @@ export function get_pending_boundary() {
return boundary;
}
/**
* Captures the current effect context so that we can restore it after
* some asynchronous work has happened if `track` is true (so that e.g.
* `await a + b` causes `b` to be registered as a dependency).
*
* If `track` is false, we just take a note of which async derived
* brought us here, so that we can emit a `async_reactivity_loss`
* warning when it's appropriate to do so.
*
* @param {boolean} track
*/
export function capture(track = true) {
var previous_effect = active_effect;
var previous_reaction = active_reaction;
var previous_component_context = component_context;
if (DEV && !track) {
var previous_async_effect = current_async_effect;
}
return function restore() {
if (track) {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_component_context);
}
if (DEV) {
set_from_async_derived(track ? null : previous_async_effect);
}
// prevent the active effect from outstaying its welcome
// TODO this feels brittle
queue_micro_task(exit);
};
}
/**
* Wraps an `await` expression in such a way that the effect context that was
* active before the expression evaluated can be reapplied afterwards
* `await a + b` becomes `(await $.save(a))() + b`
* @template T
* @param {Promise<T>} promise
* @param {boolean} [track]
* @returns {Promise<() => T>}
*/
export async function save(promise, track = true) {
var restore = capture(track);
var value = await promise;
return () => {
restore();
return value;
};
}
function exit() {
set_active_effect(null);
set_active_reaction(null);
set_component_context(null);
if (DEV) set_from_async_derived(null);
}
export function pending() {
if (active_effect === null) {
e.effect_pending_outside_reaction();

@ -98,6 +98,7 @@ export {
props_id,
with_script
} from './dom/template.js';
export { save } from './reactivity/async.js';
export { flushSync as flush, suspend } from './reactivity/batch.js';
export {
async_derived,
@ -136,7 +137,7 @@ export {
update_store,
mark_store_binding
} from './reactivity/store.js';
export { boundary, pending, save } from './dom/blocks/boundary.js';
export { boundary, pending } from './dom/blocks/boundary.js';
export { set_text } from './render.js';
export {
get,

@ -1,12 +1,25 @@
/** @import { Effect, Value } from '#client' */
import { DESTROYED } from '#client/constants';
import { is_runes } from '../context.js';
import { capture, get_pending_boundary } from '../dom/blocks/boundary.js';
import { DEV } from 'esm-env';
import { component_context, is_runes, set_component_context } from '../context.js';
import { get_pending_boundary } from '../dom/blocks/boundary.js';
import { invoke_error_boundary } from '../error-handling.js';
import { active_effect } from '../runtime.js';
import {
active_effect,
active_reaction,
set_active_effect,
set_active_reaction
} from '../runtime.js';
import { current_batch } from './batch.js';
import { async_derived, derived, derived_safe_equal } from './deriveds.js';
import {
async_derived,
current_async_effect,
derived,
derived_safe_equal,
set_from_async_derived
} from './deriveds.js';
import { queue_micro_task } from '../dom/task.js';
/**
*
@ -49,3 +62,66 @@ export function flatten(sync, async, fn) {
boundary.error(error);
});
}
/**
* Captures the current effect context so that we can restore it after
* some asynchronous work has happened if `track` is true (so that e.g.
* `await a + b` causes `b` to be registered as a dependency).
*
* If `track` is false, we just take a note of which async derived
* brought us here, so that we can emit a `async_reactivity_loss`
* warning when it's appropriate to do so.
*
* @param {boolean} track
*/
export function capture(track = true) {
var previous_effect = active_effect;
var previous_reaction = active_reaction;
var previous_component_context = component_context;
if (DEV && !track) {
var previous_async_effect = current_async_effect;
}
return function restore() {
if (track) {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_component_context);
}
if (DEV) {
set_from_async_derived(track ? null : previous_async_effect);
}
// prevent the active effect from outstaying its welcome
// TODO this feels brittle
queue_micro_task(exit);
};
}
/**
* Wraps an `await` expression in such a way that the effect context that was
* active before the expression evaluated can be reapplied afterwards
* `await a + b` becomes `(await $.save(a))() + b`
* @template T
* @param {Promise<T>} promise
* @param {boolean} [track]
* @returns {Promise<() => T>}
*/
export async function save(promise, track = true) {
var restore = capture(track);
var value = await promise;
return () => {
restore();
return value;
};
}
function exit() {
set_active_effect(null);
set_active_reaction(null);
set_component_context(null);
if (DEV) set_from_async_derived(null);
}

Loading…
Cancel
Save