pull/16197/head
Rich Harris 4 months ago
parent b1960ce467
commit 37333df908

@ -27,6 +27,8 @@ export const EFFECT_PRESERVED = 1 << 23; // effects with this flag should not be
export const REACTION_IS_UPDATING = 1 << 24;
export const EFFECT_ASYNC = 1 << 25;
export const ASYNC_ERROR = 1;
export const STATE_SYMBOL = Symbol('$state');
export const LEGACY_PROPS = Symbol('legacy props');
export const LOADING_ATTR_SYMBOL = Symbol('');

@ -122,13 +122,19 @@ export function if_block(node, fn, elseif = false) {
offscreen_fragment.append((target = create_text()));
}
var batch = /** @type {Batch} */ (current_batch);
// TODO need to do this for other block types
if (pending_effect) {
// batch.skipped_effects.add(pending_effect);
// pending_effect = null;
}
if (condition ? !consequent_effect : !alternate_effect) {
pending_effect = fn && branch(() => fn(target));
}
if (defer) {
var batch = /** @type {Batch} */ (current_batch);
const skipped = condition ? alternate_effect : consequent_effect;
if (skipped !== null) {
// TODO need to do this for other kinds of blocks

@ -26,7 +26,12 @@ function update_pending() {
/** @type {Map<Derived, any> | null} */
export let batch_deriveds = null;
/** TODO handy for debugging, but we should probably eventually delete it */
let uid = 1;
export class Batch {
id = uid++;
/** @type {Map<Source, any>} */
#previous = new Map();
@ -259,6 +264,22 @@ export class Batch {
this.#callbacks.add(fn);
}
/** @param {Effect} effect */
skips(effect) {
/** @type {Effect | null} */
var e = effect;
while (e !== null) {
if (this.skipped_effects.has(e)) {
return true;
}
e = e.parent;
}
return false;
}
static ensure() {
if (current_batch === null) {
if (batches.size === 0) {

@ -2,6 +2,7 @@
/** @import { Batch } from './batch.js'; */
import { DEV } from 'esm-env';
import {
ASYNC_ERROR,
CLEAN,
DERIVED,
DESTROYED,
@ -158,7 +159,8 @@ export function async_derived(fn, location) {
if (error) {
if (error !== STALE_REACTION) {
handle_error(error, parent, null, parent.ctx);
signal.f |= ASYNC_ERROR;
internal_set(signal, error);
}
} else {
internal_set(signal, value);

@ -41,7 +41,7 @@ import { get_next_sibling } from '../dom/operations.js';
import { async_derived, derived } from './deriveds.js';
import { capture } from '../dom/blocks/boundary.js';
import { component_context, dev_current_component_function } from '../context.js';
import { Batch } from './batch.js';
import { Batch, current_batch } from './batch.js';
/**
* @param {'$effect' | '$effect.pre' | '$inspect'} rune
@ -339,6 +339,7 @@ export function render_effect(fn, flags = 0) {
* @param {Array<() => Promise<any>>} async
*/
export function template_effect(fn, sync = [], async = [], d = derived) {
var batch = /** @type {Batch} */ (current_batch);
var parent = /** @type {Effect} */ (active_effect);
if (async.length > 0) {
@ -347,8 +348,13 @@ export function template_effect(fn, sync = [], async = [], d = derived) {
Promise.all(async.map((expression) => async_derived(expression))).then((result) => {
if ((parent.f & DESTROYED) !== 0) return;
// TODO probably need to do this in async.js as well
batch.restore();
restore();
create_template_effect(fn, [...sync.map(d), ...result]);
batch.flush();
});
} else {
create_template_effect(fn, sync.map(d));

@ -33,7 +33,8 @@ import {
EFFECT_IS_UPDATING,
EFFECT_ASYNC,
RENDER_EFFECT,
STALE_REACTION
STALE_REACTION,
ASYNC_ERROR
} from './constants.js';
import { flush_tasks } from './dom/task.js';
import { internal_set, old_values } from './reactivity/sources.js';
@ -303,6 +304,12 @@ export function reset_is_throwing_error() {
* @param {ComponentContext | null} component_context
*/
export function handle_error(error, effect, previous_effect, component_context) {
// if the error occurred inside an effect that's
// about to be destroyed, look the other way
if (current_batch?.skips(effect)) {
return;
}
if (is_throwing_error) {
if (previous_effect === null) {
is_throwing_error = false;
@ -1040,6 +1047,10 @@ export function get(signal) {
return batch_deriveds.get(derived);
}
if ((signal.f & ASYNC_ERROR) !== 0) {
throw signal.v;
}
return signal.v;
}

Loading…
Cancel
Save