multiple bug fixes

aaa
Dominic Gannaway 7 months ago
parent 118e28445d
commit 48cf4a25f6

@ -371,11 +371,7 @@ export function client_component(analysis, options) {
const body = b.function_declaration(
b.id('$$body'),
[b.id('$$anchor'), b.id('$$props')],
b.block([
b.var('$$unsuspend', b.call('$.suspend')),
...component_block.body,
b.stmt(b.call('$$unsuspend'))
])
b.block([...component_block.body, b.stmt(b.call('$.exit'))])
);
body.async = true;

@ -1,6 +1,7 @@
/** @import { AwaitExpression, Expression } from 'estree' */
/** @import { Context } from '../types' */
import * as b from '../../../../utils/builders.js';
import { get_rune } from '../../../scope.js';
/**
* @param {AwaitExpression} node
@ -13,9 +14,17 @@ export function AwaitExpression(node, context) {
return context.next();
}
return b.call(
const inside_derived = context.path.some(
(n) => n.type === 'CallExpression' && get_rune(n, context.state.scope) === '$derived'
);
const expression = b.call(
b.await(
b.call('$.save', node.argument && /** @type {Expression} */ (context.visit(node.argument)))
)
);
return inside_derived
? expression
: b.await(b.call('$.script_suspend', b.arrow([], expression, true)));
}

@ -273,13 +273,15 @@ export function capture() {
var previous_reaction = active_reaction;
var previous_component_context = component_context;
return function restore() {
return function restore(should_exit = true) {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_component_context);
// prevent the active effect from outstaying its welcome
queue_post_micro_task(exit);
if (should_exit) {
queue_post_micro_task(exit);
}
};
}
@ -307,6 +309,21 @@ export function suspend() {
};
}
/**
* @template T
* @param {() => Promise<T>} fn
*/
export async function script_suspend(fn) {
const restore = capture();
const unsuspend = suspend();
try {
return await fn();
} finally {
restore(false);
unsuspend();
}
}
/**
* @template T
* @param {Promise<T>} promise

@ -130,7 +130,7 @@ export {
update_store,
mark_store_binding
} from './reactivity/store.js';
export { boundary, exit, save, suspend } from './dom/blocks/boundary.js';
export { boundary, exit, save, suspend, script_suspend } from './dom/blocks/boundary.js';
export { set_text } from './render.js';
export {
get,

@ -29,6 +29,7 @@ import { inspect_effects, internal_set, set_inspect_effects, source } from './so
import { get_stack } from '../dev/tracing.js';
import { tracing_mode_flag } from '../../flags/index.js';
import { capture, suspend } from '../dom/blocks/boundary.js';
import { flush_boundary_micro_tasks } from '../dom/task.js';
/**
* @template V
@ -99,12 +100,19 @@ export function async_derived(fn) {
var current_deps = new Set(async_deps);
var effect = block(async () => {
block(async () => {
var effect = /** @type {Effect} */ (active_effect);
var current = (promise = fn());
var restore = capture();
var unsuspend = suspend();
// Ensure the effect tree is paused/resume otherwise user-effects will
// not run correctly
if (effect.deps !== null) {
flush_boundary_micro_tasks();
}
try {
var v = await promise;

@ -2,6 +2,14 @@
let { promise, num } = $props();
let value = $derived((await promise) * num);
$effect(() => {
console.log('should run');
});
$effect(() => {
console.log(value, num);
});
</script>
<p>{value}</p>

@ -17,12 +17,14 @@ export default test({
};
},
async test({ assert, target, component }) {
async test({ assert, target, component, logs }) {
d.resolve(42);
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await tick();
flushSync();
assert.htmlEqual(target.innerHTML, '<p>42</p>');
@ -31,6 +33,8 @@ export default test({
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await tick();
assert.htmlEqual(target.innerHTML, '<p>84</p>');
@ -42,7 +46,11 @@ export default test({
d.resolve(43);
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await tick();
assert.htmlEqual(target.innerHTML, '<p>86</p>');
assert.deepEqual(logs, ['should run', 42, 1, 84, 2, 86, 2]);
}
});

@ -19,6 +19,8 @@ export default test({
async test({ assert, target }) {
d.resolve('hello');
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
await tick();
flushSync();
assert.htmlEqual(target.innerHTML, '<p>hello</p>');

Loading…
Cancel
Save