out-of-order-rendering
Rich Harris 2 days ago
parent 3f06b6cf5d
commit aa547c58e5

@ -6,7 +6,12 @@ import { dev, locator } from '../../../../state.js';
import * as b from '#compiler/builders'; import * as b from '#compiler/builders';
import { determine_namespace_for_children } from '../../utils.js'; import { determine_namespace_for_children } from '../../utils.js';
import { build_element_attributes } from './shared/element.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 * @param {AST.SvelteElement} node
@ -39,11 +44,14 @@ export function SvelteElement(node, context) {
const optimiser = new PromiseOptimiser(); const optimiser = new PromiseOptimiser();
/** @type {Statement[]} */
let statements = [];
build_element_attributes(node, { ...context, state }, optimiser.transform); build_element_attributes(node, { ...context, state }, optimiser.transform);
if (dev) { if (dev) {
const location = /** @type {Location} */ (locator(node.start)); const location = /** @type {Location} */ (locator(node.start));
context.state.template.push( statements.push(
b.stmt( b.stmt(
b.call( b.call(
'$.push_element', '$.push_element',
@ -74,9 +82,21 @@ export function SvelteElement(node, context) {
statement = create_child_block(b.block([optimiser.apply(), statement]), true); statement = create_child_block(b.block([optimiser.apply(), statement]), true);
} }
context.state.template.push(statement); statements.push(statement);
if (dev) { 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 * @param {(renderer: Renderer) => void} fn
*/ */
async(blockers, 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.#out.push(BLOCK_OPEN);
this.child( this.child(callback);
blockers.length > 0 ? (renderer) => Promise.all(blockers).then(() => fn(renderer)) : fn
);
this.#out.push(BLOCK_CLOSE); this.#out.push(BLOCK_CLOSE);
} }
@ -122,13 +139,13 @@ export class Renderer {
for (const fn of thunks.slice(1)) { for (const fn of thunks.slice(1)) {
promise = promise.then(() => { promise = promise.then(() => {
const previous_ssr_context = ssr_context; const previous_context = ssr_context;
set_ssr_context(context); set_ssr_context(context);
try { try {
return fn(); return fn();
} finally { } finally {
set_ssr_context(previous_ssr_context); set_ssr_context(previous_context);
} }
}); });
} }

Loading…
Cancel
Save