diff --git a/packages/svelte/src/internal/client/dom/blocks/async.js b/packages/svelte/src/internal/client/dom/blocks/async.js index db6a7fda79..c3283081ab 100644 --- a/packages/svelte/src/internal/client/dom/blocks/async.js +++ b/packages/svelte/src/internal/client/dom/blocks/async.js @@ -3,7 +3,7 @@ import { async_derived } from '../../reactivity/deriveds.js'; import { current_batch } from '../../reactivity/batch.js'; import { active_effect, schedule_effect } from '../../runtime.js'; -import { capture } from './boundary.js'; +import { capture, get_pending_boundary } from './boundary.js'; /** * @param {TemplateNode} node @@ -15,19 +15,10 @@ export function async(node, expressions, fn) { var batch = /** @type {Batch} */ (current_batch); var effect = /** @type {Effect} */ (active_effect); + var boundary = get_pending_boundary(effect); var restore = capture(); - let boundary = effect.b; - - while (boundary !== null && !boundary.has_pending_snippet()) { - boundary = boundary.parent; - } - - if (boundary === null) { - throw new Error('TODO cannot create async derived outside a boundary with a pending snippet'); - } - boundary.increment(); Promise.all(expressions.map((fn) => async_derived(fn))).then((result) => { diff --git a/packages/svelte/src/internal/client/dom/blocks/boundary.js b/packages/svelte/src/internal/client/dom/blocks/boundary.js index a98a354bd0..2f7c0d2e4d 100644 --- a/packages/svelte/src/internal/client/dom/blocks/boundary.js +++ b/packages/svelte/src/internal/client/dom/blocks/boundary.js @@ -327,6 +327,21 @@ function move_effect(effect, fragment) { } } +/** @param {Effect} effect */ +export function get_pending_boundary(effect) { + let boundary = effect.b; + + while (boundary !== null && !boundary.has_pending_snippet()) { + boundary = boundary.parent; + } + + if (boundary === null) { + e.await_outside_boundary(); + } + + return boundary; +} + export function capture(track = true) { var previous_effect = active_effect; var previous_reaction = active_reaction; @@ -352,20 +367,7 @@ export function capture(track = true) { // TODO we should probably be incrementing the current batch, not the boundary? export function suspend() { - let boundary = /** @type {Effect} */ (active_effect).b; - - while (boundary !== null) { - // TODO pretty sure this is wrong - if (boundary.has_pending_snippet()) { - break; - } - - boundary = boundary.parent; - } - - if (boundary === null) { - e.await_outside_boundary(); - } + let boundary = get_pending_boundary(/** @type {Effect} */ (active_effect)); boundary.increment(); diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 314595c937..5c33a827dd 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -29,7 +29,7 @@ import { destroy_effect, render_effect } from './effects.js'; import { inspect_effects, internal_set, set_inspect_effects, source } from './sources.js'; import { get_stack } from '../dev/tracing.js'; import { tracing_mode_flag } from '../../flags/index.js'; -import { capture } from '../dom/blocks/boundary.js'; +import { capture, get_pending_boundary } from '../dom/blocks/boundary.js'; import { component_context } from '../context.js'; import { UNINITIALIZED } from '../../../constants.js'; import { current_batch } from './batch.js'; @@ -101,15 +101,7 @@ export function async_derived(fn, location) { throw new Error('TODO cannot create unowned async derived'); } - let boundary = parent.b; - - while (boundary !== null && !boundary.has_pending_snippet()) { - boundary = boundary.parent; - } - - if (boundary === null) { - throw new Error('TODO cannot create async derived outside a boundary with a pending snippet'); - } + let boundary = get_pending_boundary(parent); var promise = /** @type {Promise} */ (/** @type {unknown} */ (undefined)); var signal = source(/** @type {V} */ (UNINITIALIZED));