From 591aeb0cbc18ffb383faee8766a9c274a0b84ee1 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 26 Jun 2025 12:14:55 -0400 Subject: [PATCH] groundwork for async attribute_effect --- .../client/visitors/shared/element.js | 3 ++- .../client/dom/elements/attributes.js | 27 ++++++++++++++++--- .../src/internal/client/reactivity/effects.js | 6 ++--- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js index 869dd16956..b1b1a8fae4 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js @@ -96,8 +96,9 @@ export function build_attribute_effect( expressions.map(({ id }) => id), b.object(values) ), - // TODO need to handle async expressions too expressions.length > 0 && b.array(expressions.map(({ expression }) => b.thunk(expression))), + async_expressions.length > 0 && + b.array(async_expressions.map(({ expression }) => b.thunk(expression))), element.metadata.scoped && context.state.analysis.css.hash !== '' && b.literal(context.state.analysis.css.hash), diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index 2d3d6a921d..83035cc6a1 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -1,4 +1,4 @@ -/** @import { Effect } from '#client' */ +/** @import { Effect, Value } from '#client' */ import { DEV } from 'esm-env'; import { hydrating, set_hydrating } from '../hydration.js'; import { get_descriptors, get_prototype_of } from '../../../shared/utils.js'; @@ -462,20 +462,39 @@ export function set_attributes(element, prev, next, css_hash, skip_warning = fal /** * @param {Element & ElementCSSInlineStyle} element * @param {(...expressions: any) => Record} fn - * @param {Array<() => any>} thunks + * @param {Array<() => any>} sync + * @param {Array<() => Promise>} async * @param {string} [css_hash] * @param {boolean} [skip_warning] */ export function attribute_effect( element, fn, - thunks = [], + sync = [], + async = [], css_hash, skip_warning = false, d = derived ) { - const deriveds = thunks.map(d); + const deriveds = sync.map(d); + create_attribute_effect(element, fn, deriveds, css_hash, skip_warning); +} + +/** + * @param {Element & ElementCSSInlineStyle} element + * @param {(...expressions: any) => Record} fn + * @param {Value[]} deriveds + * @param {string} [css_hash] + * @param {boolean} [skip_warning] + */ +export function create_attribute_effect( + element, + fn, + deriveds = [], + css_hash, + skip_warning = false +) { /** @type {Record | undefined} */ var prev = undefined; diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 15f16a0691..1bef217476 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -341,10 +341,10 @@ export function render_effect(fn, flags = 0) { * @param {(fn: () => T) => Derived} d */ export function template_effect(fn, sync = [], async = [], d = derived) { - var batch = current_batch; - var parent = /** @type {Effect} */ (active_effect); - if (async.length > 0) { + var batch = current_batch; + var parent = /** @type {Effect} */ (active_effect); + var restore = capture(); Promise.all(async.map((expression) => async_derived(expression))).then((result) => {