differentiate between 'top-level' and 'needs context preservation' so that SSR errors occur correctly

aaa
Rich Harris 8 months ago
parent 3be5a88b6f
commit f355eaf9a0

@ -266,7 +266,7 @@ export function analyze_module(ast, options) {
immutable: true,
tracing: analysis.tracing,
async_deriveds: new Set(),
suspenders: new Set()
suspenders: new Map()
};
}
@ -455,7 +455,7 @@ export function analyze_component(root, source, options) {
snippets: new Set(),
is_async: false,
async_deriveds: new Set(),
suspenders: new Set()
suspenders: new Map()
};
if (!runes) {

@ -8,8 +8,11 @@
export function AwaitExpression(node, context) {
const tla = context.state.ast_type === 'instance' && context.state.function_depth === 1;
let suspend = tla;
let preserve_context = tla;
if (context.state.expression) {
suspend = true;
// wrap the expression in `(await $.suspend(...)).exit()` if necessary,
// i.e. whether anything could potentially be read _after_ the await
let i = context.path.length;
@ -23,7 +26,7 @@ export function AwaitExpression(node, context) {
// TODO make this more accurate — we don't need to call suspend
// if this is the last thing that could be read
suspend = true;
preserve_context = true;
}
}
@ -32,7 +35,7 @@ export function AwaitExpression(node, context) {
throw new Error('TODO runes mode only');
}
context.state.analysis.suspenders.add(node);
context.state.analysis.suspenders.set(node, preserve_context);
}
if (context.state.expression) {

@ -7,7 +7,7 @@ import * as b from '../../../../utils/builders.js';
* @param {Context} context
*/
export function AwaitExpression(node, context) {
const suspend = context.state.analysis.suspenders.has(node);
const suspend = context.state.analysis.suspenders.get(node);
if (!suspend) {
return context.next();

@ -7,6 +7,9 @@ import * as b from '../../../../utils/builders.js';
* @param {ComponentContext} context
*/
export function AwaitExpression(node, context) {
// `has`, not `get`, because all top-level await expressions should
// block regardless of whether they need context preservation
// in the client output
const suspend = context.state.analysis.suspenders.has(node);
if (!suspend) {

@ -42,8 +42,8 @@ export interface Analysis {
/** A set of deriveds that contain `await` expressions */
async_deriveds: Set<CallExpression>;
/** A set of `await` expressions that should trigger suspense */
suspenders: Set<AwaitExpression>;
/** A map of `await` expressions that should block, and whether they should preserve context */
suspenders: Map<AwaitExpression, boolean>;
}
export interface ComponentAnalysis extends Analysis {

Loading…
Cancel
Save