From df67772711fba44e3c7f6fdb79f7bd4f8033d612 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 23 Jan 2025 14:06:02 -0500 Subject: [PATCH] separate suspend and capture from save --- .../src/internal/client/dom/blocks/async.js | 11 ++++++--- .../internal/client/dom/blocks/boundary.js | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/svelte/src/internal/client/dom/blocks/async.js b/packages/svelte/src/internal/client/dom/blocks/async.js index 4d2a624559..c3073d8611 100644 --- a/packages/svelte/src/internal/client/dom/blocks/async.js +++ b/packages/svelte/src/internal/client/dom/blocks/async.js @@ -1,7 +1,7 @@ /** @import { TemplateNode, Value } from '#client' */ import { async_derived } from '../../reactivity/deriveds.js'; -import { save } from './boundary.js'; +import { capture, suspend } from './boundary.js'; /** * @param {TemplateNode} node @@ -11,7 +11,12 @@ import { save } from './boundary.js'; export function async(node, expressions, fn) { // TODO handle hydration - save(Promise.all(expressions.map(async_derived))).then((result) => { - fn(node, ...result.restore()); + var restore = capture(); + var unsuspend = suspend(); + + Promise.all(expressions.map(async_derived)).then((result) => { + restore(); + fn(node, ...result); + unsuspend(); }); } diff --git a/packages/svelte/src/internal/client/dom/blocks/boundary.js b/packages/svelte/src/internal/client/dom/blocks/boundary.js index 76a39b4d77..549425320d 100644 --- a/packages/svelte/src/internal/client/dom/blocks/boundary.js +++ b/packages/svelte/src/internal/client/dom/blocks/boundary.js @@ -268,6 +268,30 @@ export function capture() { }; } +export function suspend() { + var boundary = active_effect; + + while (boundary !== null) { + if ((boundary.f & BOUNDARY_EFFECT) !== 0) { + break; + } + + boundary = boundary.parent; + } + + if (boundary === null) { + e.await_outside_boundary(); + } + + // @ts-ignore + boundary?.fn(ASYNC_INCREMENT); + + return function unsuspend() { + // @ts-ignore + boundary?.fn(ASYNC_DECREMENT); + }; +} + /** * @template T * @param {Promise} promise