decouple from boundaries

state-eager-derived-block
Rich Harris 2 days ago
parent 7c0fef4c61
commit 4fa2be67ee

@ -51,7 +51,7 @@ export function CallExpression(node, context) {
case '$state.eager':
return b.call(
'$.pending',
'$.eager',
b.thunk(/** @type {Expression} */ (context.visit(node.arguments[0])))
);

@ -13,10 +13,8 @@ import {
active_effect,
active_reaction,
get,
read_pending,
set_active_effect,
set_active_reaction,
set_read_pending
set_active_reaction
} from '../../runtime.js';
import {
hydrate_next,
@ -449,10 +447,7 @@ export function get_boundary() {
return /** @type {Boundary} */ (/** @type {Effect} */ (active_effect).b);
}
/**
* @param {() => any} [fn]
*/
export function pending(fn) {
export function pending() {
if (active_effect === null) {
e.effect_pending_outside_reaction();
}
@ -460,23 +455,8 @@ export function pending(fn) {
var boundary = active_effect.b;
if (boundary === null) {
return fn ? fn() : 0; // TODO eventually we will need this to be global
return 0; // TODO eventually we will need this to be global
}
var pending = boundary.get_effect_pending();
if (fn) {
var value;
var prev_read_pending = read_pending;
set_read_pending(true);
try {
value = fn();
} finally {
set_read_pending(prev_read_pending);
}
return value;
} else {
return pending;
}
return boundary.get_effect_pending();
}

@ -103,7 +103,7 @@ export {
save,
track_reactivity_loss
} from './reactivity/async.js';
export { flushSync as flush } from './reactivity/batch.js';
export { eager, flushSync as flush } from './reactivity/batch.js';
export {
async_derived,
user_derived as derived,

@ -17,6 +17,7 @@ import { async_mode_flag } from '../../flags/index.js';
import { deferred, define_property } from '../../shared/utils.js';
import {
active_effect,
get,
is_dirty,
is_updating_effect,
set_is_updating_effect,
@ -27,8 +28,8 @@ import * as e from '../errors.js';
import { flush_tasks, queue_micro_task } from '../dom/task.js';
import { DEV } from 'esm-env';
import { invoke_error_boundary } from '../error-handling.js';
import { old_values } from './sources.js';
import { unlink_effect } from './effects.js';
import { old_values, source, update } from './sources.js';
import { inspect_effect, unlink_effect } from './effects.js';
/** @type {Set<Batch>} */
const batches = new Set();
@ -702,6 +703,48 @@ export function schedule_effect(signal) {
queued_root_effects.push(effect);
}
/** @type {Source<number>} */
let version;
let eager_flushing = false;
function eager_flush() {
try {
flushSync(() => {
update(version);
});
} finally {
eager_flushing = false;
}
}
/**
* @template T
* @param {() => T} fn
* @returns {T}
*/
export function eager(fn) {
const previous_batch_values = batch_values;
try {
get((version ??= source(0)));
inspect_effect(() => {
fn();
if (!eager_flushing) {
eager_flushing = true;
queueMicrotask(eager_flush);
}
});
batch_values = null;
return fn();
} finally {
batch_values = previous_batch_values;
}
}
/**
* Forcibly remove all current batches, to prevent cross-talk between tests
*/

@ -144,17 +144,6 @@ export function increment_write_version() {
return ++write_version;
}
/**
* Whether or not we should get the latest value of a signal regardless of whether or not it is pending,
* i.e. inside a boundary with pending async work in which case normally a stale value might be shown.
*/
export let read_pending = false;
/** @param {boolean} value */
export function set_read_pending(value) {
read_pending = value;
}
/**
* Determines whether a derived or effect is dirty.
* If it is MAYBE_DIRTY, will set the status to CLEAN
@ -691,7 +680,7 @@ export function get(signal) {
}
}
if (!read_pending && batch_values?.has(signal)) {
if (batch_values?.has(signal)) {
return batch_values.get(signal);
}

Loading…
Cancel
Save