diff --git a/packages/svelte/src/index-server.js b/packages/svelte/src/index-server.js
index ab2258ac5f..e5039cf150 100644
--- a/packages/svelte/src/index-server.js
+++ b/packages/svelte/src/index-server.js
@@ -2,7 +2,6 @@
import { current_component } from './internal/server/context.js';
import { noop } from './internal/shared/utils.js';
import * as e from './internal/server/errors.js';
-import { STALE_REACTION } from '#client/constants';
/** @param {() => void} fn */
export function onDestroy(fn) {
@@ -36,20 +35,7 @@ export function unmount() {
export async function tick() {}
-/** @type {AbortController | null} */
-let controller = null;
-
-export function getAbortSignal() {
- if (controller === null) {
- const c = (controller = new AbortController());
- queueMicrotask(() => {
- c.abort(STALE_REACTION);
- controller = null;
- });
- }
-
- return controller.signal;
-}
+export { getAbortSignal } from './internal/server/abort-signal.js';
export { getAllContexts, getContext, hasContext, setContext } from './internal/server/context.js';
diff --git a/packages/svelte/src/internal/server/abort-signal.js b/packages/svelte/src/internal/server/abort-signal.js
new file mode 100644
index 0000000000..4e44254c5d
--- /dev/null
+++ b/packages/svelte/src/internal/server/abort-signal.js
@@ -0,0 +1,15 @@
+import { STALE_REACTION } from '#client/constants';
+
+/** @type {AbortController | null} */
+export let controller = null;
+
+export function abort() {
+ if (controller !== null) {
+ controller.abort(STALE_REACTION);
+ controller = null;
+ }
+}
+
+export function getAbortSignal() {
+ return (controller ??= new AbortController()).signal;
+}
diff --git a/packages/svelte/src/internal/server/index.js b/packages/svelte/src/internal/server/index.js
index 2ca85fff44..ceb516ebb0 100644
--- a/packages/svelte/src/internal/server/index.js
+++ b/packages/svelte/src/internal/server/index.js
@@ -18,6 +18,7 @@ import { validate_store } from '../shared/validate.js';
import { is_boolean_attribute, is_raw_text_element, is_void } from '../../utils.js';
import { reset_elements } from './dev.js';
import { Payload } from './payload.js';
+import { abort } from './abort-signal.js';
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
// https://infra.spec.whatwg.org/#noncharacter
@@ -66,50 +67,54 @@ export let on_destroy = [];
* @returns {RenderOutput}
*/
export function render(component, options = {}) {
- const payload = new Payload(options.idPrefix ? options.idPrefix + '-' : '');
+ try {
+ const payload = new Payload(options.idPrefix ? options.idPrefix + '-' : '');
- const prev_on_destroy = on_destroy;
- on_destroy = [];
- payload.out += BLOCK_OPEN;
+ const prev_on_destroy = on_destroy;
+ on_destroy = [];
+ payload.out += BLOCK_OPEN;
- let reset_reset_element;
+ let reset_reset_element;
- if (DEV) {
- // prevent parent/child element state being corrupted by a bad render
- reset_reset_element = reset_elements();
- }
+ if (DEV) {
+ // prevent parent/child element state being corrupted by a bad render
+ reset_reset_element = reset_elements();
+ }
- if (options.context) {
- push();
- /** @type {Component} */ (current_component).c = options.context;
- }
+ if (options.context) {
+ push();
+ /** @type {Component} */ (current_component).c = options.context;
+ }
- // @ts-expect-error
- component(payload, options.props ?? {}, {}, {});
+ // @ts-expect-error
+ component(payload, options.props ?? {}, {}, {});
- if (options.context) {
- pop();
- }
+ if (options.context) {
+ pop();
+ }
- if (reset_reset_element) {
- reset_reset_element();
- }
+ if (reset_reset_element) {
+ reset_reset_element();
+ }
- payload.out += BLOCK_CLOSE;
- for (const cleanup of on_destroy) cleanup();
- on_destroy = prev_on_destroy;
+ payload.out += BLOCK_CLOSE;
+ for (const cleanup of on_destroy) cleanup();
+ on_destroy = prev_on_destroy;
- let head = payload.head.out + payload.head.title;
+ let head = payload.head.out + payload.head.title;
- for (const { hash, code } of payload.css) {
- head += ``;
- }
+ for (const { hash, code } of payload.css) {
+ head += ``;
+ }
- return {
- head,
- html: payload.out,
- body: payload.out
- };
+ return {
+ head,
+ html: payload.out,
+ body: payload.out
+ };
+ } finally {
+ abort();
+ }
}
/**