out-of-order-rendering
Rich Harris 1 day ago
parent 3f06b6cf5d
commit aa547c58e5

@ -6,7 +6,12 @@ import { dev, locator } from '../../../../state.js';
import * as b from '#compiler/builders';
import { determine_namespace_for_children } from '../../utils.js';
import { build_element_attributes } from './shared/element.js';
import { build_template, create_child_block, PromiseOptimiser } from './shared/utils.js';
import {
build_template,
create_async_block,
create_child_block,
PromiseOptimiser
} from './shared/utils.js';
/**
* @param {AST.SvelteElement} node
@ -39,11 +44,14 @@ export function SvelteElement(node, context) {
const optimiser = new PromiseOptimiser();
/** @type {Statement[]} */
let statements = [];
build_element_attributes(node, { ...context, state }, optimiser.transform);
if (dev) {
const location = /** @type {Location} */ (locator(node.start));
context.state.template.push(
statements.push(
b.stmt(
b.call(
'$.push_element',
@ -74,9 +82,21 @@ export function SvelteElement(node, context) {
statement = create_child_block(b.block([optimiser.apply(), statement]), true);
}
context.state.template.push(statement);
statements.push(statement);
if (dev) {
context.state.template.push(b.stmt(b.call('$.pop_element')));
statements.push(b.stmt(b.call('$.pop_element')));
}
if (node.metadata.expression.is_async()) {
statements = [
create_async_block(
b.block(statements),
node.metadata.expression.blockers(),
node.metadata.expression.has_await
)
];
}
context.state.template.push(...statements);
}

@ -104,10 +104,27 @@ export class Renderer {
* @param {(renderer: Renderer) => void} fn
*/
async(blockers, fn) {
let callback = fn;
if (blockers.length > 0) {
const context = ssr_context;
callback = (renderer) => {
return Promise.all(blockers).then(() => {
const previous_context = ssr_context;
try {
set_ssr_context(context);
return fn(renderer);
} finally {
set_ssr_context(previous_context);
}
});
};
}
this.#out.push(BLOCK_OPEN);
this.child(
blockers.length > 0 ? (renderer) => Promise.all(blockers).then(() => fn(renderer)) : fn
);
this.child(callback);
this.#out.push(BLOCK_CLOSE);
}
@ -122,13 +139,13 @@ export class Renderer {
for (const fn of thunks.slice(1)) {
promise = promise.then(() => {
const previous_ssr_context = ssr_context;
const previous_context = ssr_context;
set_ssr_context(context);
try {
return fn();
} finally {
set_ssr_context(previous_ssr_context);
set_ssr_context(previous_context);
}
});
}

Loading…
Cancel
Save