async-changeset
Rich Harris 7 months ago
parent 2e65e6eb54
commit e9962194f8

@ -86,6 +86,10 @@ export class Boundary {
/** @type {Effect | null} */ /** @type {Effect | null} */
#failed_effect = null; #failed_effect = null;
/** @type {DocumentFragment | null} */
#offscreen_fragment = null;
#pending_count = 0;
#keep_pending_snippet = false; // TODO get rid of this #keep_pending_snippet = false; // TODO get rid of this
#is_creating_fallback = false; #is_creating_fallback = false;
@ -102,10 +106,6 @@ export class Boundary {
active_boundary = this; active_boundary = this;
this.#effect = block(() => { this.#effect = block(() => {
/** @type {DocumentFragment | null} */
var offscreen_fragment = null;
var async_count = 0;
var boundary_effect = /** @type {Effect} */ (active_effect); var boundary_effect = /** @type {Effect} */ (active_effect);
var hydrate_open = hydrate_node; var hydrate_open = hydrate_node;
@ -130,7 +130,7 @@ export class Boundary {
}; };
const reset = () => { const reset = () => {
async_count = 0; this.#pending_count = 0;
if ((boundary_effect.f & BOUNDARY_SUSPENDED) !== 0) { if ((boundary_effect.f & BOUNDARY_SUSPENDED) !== 0) {
boundary_effect.f ^= BOUNDARY_SUSPENDED; boundary_effect.f ^= BOUNDARY_SUSPENDED;
@ -152,56 +152,12 @@ export class Boundary {
} }
}); });
if (async_count > 0) { if (this.#pending_count > 0) {
boundary_effect.f |= BOUNDARY_SUSPENDED; boundary_effect.f |= BOUNDARY_SUSPENDED;
show_pending_snippet(true); show_pending_snippet(true);
} }
}; };
const unsuspend = () => {
if (this.#keep_pending_snippet || async_count > 0) {
return;
}
if ((boundary_effect.f & BOUNDARY_SUSPENDED) !== 0) {
boundary_effect.f ^= BOUNDARY_SUSPENDED;
}
for (const e of this.#render_effects) {
try {
if (check_dirtiness(e)) {
update_effect(e);
}
} catch (error) {
handle_error(error, e, null, e.ctx);
}
}
for (const fn of this.#callbacks) fn();
this.#callbacks.clear();
if (this.#pending_effect) {
pause_effect(this.#pending_effect, () => {
this.#pending_effect = null;
});
}
if (offscreen_fragment) {
this.#anchor.before(offscreen_fragment);
offscreen_fragment = null;
}
for (const e of this.#effects) {
try {
if (check_dirtiness(e)) {
update_effect(e);
}
} catch (error) {
handle_error(error, e, null, e.ctx);
}
}
};
/** /**
* @param {boolean} initial * @param {boolean} initial
*/ */
@ -211,8 +167,8 @@ export class Boundary {
if (pending !== undefined) { if (pending !== undefined) {
// TODO can this be false? // TODO can this be false?
if (this.#main_effect !== null) { if (this.#main_effect !== null) {
offscreen_fragment = document.createDocumentFragment(); this.#offscreen_fragment = document.createDocumentFragment();
move_effect(this.#main_effect, offscreen_fragment); move_effect(this.#main_effect, this.#offscreen_fragment);
} }
if (this.#pending_effect === null) { if (this.#pending_effect === null) {
@ -228,7 +184,7 @@ export class Boundary {
loop((now) => { loop((now) => {
if (now >= end) { if (now >= end) {
this.#keep_pending_snippet = false; this.#keep_pending_snippet = false;
unsuspend(); this.commit();
return false; return false;
} }
@ -254,7 +210,7 @@ export class Boundary {
var end = start + (this.#props.showPendingAfter ?? 500); var end = start + (this.#props.showPendingAfter ?? 500);
loop((now) => { loop((now) => {
if (async_count === 0) return false; if (this.#pending_count === 0) return false;
if (now < end) return true; if (now < end) return true;
show_pending_snippet(false); show_pending_snippet(false);
@ -262,14 +218,14 @@ export class Boundary {
} }
boundary_effect.f |= BOUNDARY_SUSPENDED; boundary_effect.f |= BOUNDARY_SUSPENDED;
async_count++; this.#pending_count++;
return; return;
} }
if (input === ASYNC_DECREMENT) { if (input === ASYNC_DECREMENT) {
if (--async_count === 0 && !this.#keep_pending_snippet) { if (--this.#pending_count === 0 && !this.#keep_pending_snippet) {
unsuspend(); this.commit();
if (this.#main_effect !== null) { if (this.#main_effect !== null) {
// TODO do we also need to `resume_effect` here? // TODO do we also need to `resume_effect` here?
@ -281,7 +237,7 @@ export class Boundary {
} }
if (input === COMMIT) { if (input === COMMIT) {
unsuspend(); this.commit();
return; return;
} }
@ -362,7 +318,7 @@ export class Boundary {
} else { } else {
this.#main_effect = branch(() => children(this.#anchor)); this.#main_effect = branch(() => children(this.#anchor));
if (async_count > 0) { if (this.#pending_count > 0) {
boundary_effect.f |= BOUNDARY_SUSPENDED; boundary_effect.f |= BOUNDARY_SUSPENDED;
show_pending_snippet(true); show_pending_snippet(true);
} }
@ -414,6 +370,50 @@ export class Boundary {
add_effect(effect) { add_effect(effect) {
((effect.f & RENDER_EFFECT) !== 0 ? this.#render_effects : this.#effects).push(effect); ((effect.f & RENDER_EFFECT) !== 0 ? this.#render_effects : this.#effects).push(effect);
} }
commit() {
if (this.#keep_pending_snippet || this.#pending_count > 0) {
return;
}
if ((this.#effect.f & BOUNDARY_SUSPENDED) !== 0) {
this.#effect.f ^= BOUNDARY_SUSPENDED;
}
for (const e of this.#render_effects) {
try {
if (check_dirtiness(e)) {
update_effect(e);
}
} catch (error) {
handle_error(error, e, null, e.ctx);
}
}
for (const fn of this.#callbacks) fn();
this.#callbacks.clear();
if (this.#pending_effect) {
pause_effect(this.#pending_effect, () => {
this.#pending_effect = null;
});
}
if (this.#offscreen_fragment) {
this.#anchor.before(this.#offscreen_fragment);
this.#offscreen_fragment = null;
}
for (const e of this.#effects) {
try {
if (check_dirtiness(e)) {
update_effect(e);
}
} catch (error) {
handle_error(error, e, null, e.ctx);
}
}
}
} }
const ASYNC_INCREMENT = Symbol(); const ASYNC_INCREMENT = Symbol();

Loading…
Cancel
Save