yield
Dominic Gannaway 1 week ago
parent 6b24dcddf9
commit c5a1f2d0fa

@ -255,7 +255,7 @@ declare namespace $effect {
*/ */
export function pre(fn: () => void | (() => void)): void; export function pre(fn: () => void | (() => void)): void;
export function yield(fn: () => void | (() => void)): void; export function post(fn: () => void | (() => void)): void;
/** /**
* The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template. * The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template.

@ -95,7 +95,7 @@ export function CallExpression(node, context) {
case '$effect': case '$effect':
case '$effect.pre': case '$effect.pre':
case '$effect.yield': case '$effect.post':
if (parent.type !== 'ExpressionStatement') { if (parent.type !== 'ExpressionStatement') {
e.effect_invalid_placement(node); e.effect_invalid_placement(node);
} }

@ -11,12 +11,12 @@ export function ExpressionStatement(node, context) {
if (node.expression.type === 'CallExpression') { if (node.expression.type === 'CallExpression') {
const rune = get_rune(node.expression, context.state.scope); const rune = get_rune(node.expression, context.state.scope);
if (rune === '$effect' || rune === '$effect.pre' || rune === '$effect.yield') { if (rune === '$effect' || rune === '$effect.pre' || rune === '$effect.post') {
const callee = const callee =
rune === '$effect' rune === '$effect'
? '$.user_effect' ? '$.user_effect'
: rune === '$effect.yield' : rune === '$effect.post'
? '$.user_yield_effect' ? '$.user_post_effect'
: '$.user_pre_effect'; : '$.user_pre_effect';
const func = /** @type {Expression} */ (context.visit(node.expression.arguments[0])); const func = /** @type {Expression} */ (context.visit(node.expression.arguments[0]));

@ -13,7 +13,7 @@ export function ExpressionStatement(node, context) {
if ( if (
rune === '$effect' || rune === '$effect' ||
rune === '$effect.pre' || rune === '$effect.pre' ||
rune === '$effect.yield' || rune === '$effect.post' ||
rune === '$effect.root' || rune === '$effect.root' ||
rune === '$inspect.trace' rune === '$inspect.trace'
) { ) {

@ -5,7 +5,7 @@ export const BLOCK_EFFECT = 1 << 4;
export const BRANCH_EFFECT = 1 << 5; export const BRANCH_EFFECT = 1 << 5;
export const ROOT_EFFECT = 1 << 6; export const ROOT_EFFECT = 1 << 6;
export const BOUNDARY_EFFECT = 1 << 7; export const BOUNDARY_EFFECT = 1 << 7;
export const YIELD_EFFECT = 1 << 8; export const POST_EFFECT = 1 << 8;
export const UNOWNED = 1 << 9; export const UNOWNED = 1 << 9;
export const DISCONNECTED = 1 << 10; export const DISCONNECTED = 1 << 10;
export const CLEAN = 1 << 11; export const CLEAN = 1 << 11;

@ -12,11 +12,11 @@ export const schedule_yield =
// @ts-ignore // @ts-ignore
typeof scheduler === 'undefined' typeof scheduler === 'undefined'
? (/** @type {() => void} */ cb) => { ? (/** @type {() => void} */ cb) => {
// For Safari, we fallback to using MessageChannel // For Safari, we fallback to using MessageChannel
const channel = new MessageChannel(); const channel = new MessageChannel();
channel.port1.onmessage = cb; channel.port1.onmessage = cb;
channel.port2.postMessage(undefined); channel.port2.postMessage(undefined);
} }
: async (/** @type {() => void} */ fn) => { : async (/** @type {() => void} */ fn) => {
// @ts-ignore // @ts-ignore
await scheduler.yield(); await scheduler.yield();

@ -108,7 +108,7 @@ export {
effect, effect,
user_effect, user_effect,
user_pre_effect, user_pre_effect,
user_yield_effect user_post_effect
} from './reactivity/effects.js'; } from './reactivity/effects.js';
export { mutable_state, mutate, set, state } from './reactivity/sources.js'; export { mutable_state, mutate, set, state } from './reactivity/sources.js';
export { export {

@ -36,7 +36,7 @@ import {
HEAD_EFFECT, HEAD_EFFECT,
MAYBE_DIRTY, MAYBE_DIRTY,
EFFECT_HAS_DERIVED, EFFECT_HAS_DERIVED,
YIELD_EFFECT POST_EFFECT
} from '../constants.js'; } from '../constants.js';
import { set } from './sources.js'; import { set } from './sources.js';
import * as e from '../errors.js'; import * as e from '../errors.js';
@ -46,7 +46,7 @@ import { get_next_sibling } from '../dom/operations.js';
import { destroy_derived } from './deriveds.js'; import { destroy_derived } from './deriveds.js';
/** /**
* @param {'$effect' | '$effect.pre' | '$effect.yield' | '$inspect'} rune * @param {'$effect' | '$effect.pre' | '$effect.post' | '$inspect'} rune
*/ */
export function validate_effect(rune) { export function validate_effect(rune) {
if (active_effect === null && active_reaction === null) { if (active_effect === null && active_reaction === null) {
@ -233,19 +233,19 @@ export function user_pre_effect(fn) {
} }
/** /**
* Internal representation of `$effect.yield(...)` * Internal representation of `$effect.post(...)`
* @param {() => void | (() => void)} fn * @param {() => void | (() => void)} fn
* @returns {Effect} * @returns {Effect}
*/ */
export function user_yield_effect(fn) { export function user_post_effect(fn) {
validate_effect('$effect.yield'); validate_effect('$effect.post');
if (DEV) { if (DEV) {
define_property(fn, 'name', { define_property(fn, 'name', {
value: '$effect.yield' value: '$effect.post'
}); });
} }
return yield_effect(fn); return post_effect(fn);
} }
/** @param {() => void | (() => void)} fn */ /** @param {() => void | (() => void)} fn */
@ -301,8 +301,8 @@ export function effect(fn) {
* @param {() => void | (() => void)} fn * @param {() => void | (() => void)} fn
* @returns {Effect} * @returns {Effect}
*/ */
export function yield_effect(fn) { export function post_effect(fn) {
return create_effect(YIELD_EFFECT, fn, false); return create_effect(POST_EFFECT, fn, false);
} }
/** /**

@ -26,7 +26,7 @@ import {
LEGACY_DERIVED_PROP, LEGACY_DERIVED_PROP,
DISCONNECTED, DISCONNECTED,
BOUNDARY_EFFECT, BOUNDARY_EFFECT,
YIELD_EFFECT POST_EFFECT
} from './constants.js'; } from './constants.js';
import { flush_tasks, schedule_yield } from './dom/task.js'; import { flush_tasks, schedule_yield } from './dom/task.js';
import { add_owner } from './dev/ownership.js'; import { add_owner } from './dev/ownership.js';
@ -49,9 +49,9 @@ export let is_throwing_error = false;
let scheduler_mode = FLUSH_MICROTASK; let scheduler_mode = FLUSH_MICROTASK;
// Used for handling scheduling // Used for handling scheduling
let is_micro_task_queued = false; let is_micro_task_queued = false;
let is_yield_queued = false; let is_post_task_queued = false;
/** @type {Effect[]} */ /** @type {Effect[]} */
let queued_yield_effects = []; let queued_post_effects = [];
/** @type {Effect | null} */ /** @type {Effect | null} */
let last_scheduled_effect = null; let last_scheduled_effect = null;
@ -594,10 +594,10 @@ function infinite_loop_guard() {
/** /**
* @param {Array<Effect>} root_effects * @param {Array<Effect>} root_effects
* @param {boolean} yielded_effects * @param {boolean} post_effects
* @returns {void} * @returns {void}
*/ */
function flush_queued_root_effects(root_effects, yielded_effects) { function flush_queued_root_effects(root_effects, post_effects) {
var length = root_effects.length; var length = root_effects.length;
if (length === 0) { if (length === 0) {
return; return;
@ -618,7 +618,7 @@ function flush_queued_root_effects(root_effects, yielded_effects) {
/** @type {Effect[]} */ /** @type {Effect[]} */
var collected_effects = []; var collected_effects = [];
process_effects(effect, collected_effects, yielded_effects); process_effects(effect, collected_effects, post_effects);
flush_queued_effects(collected_effects); flush_queued_effects(collected_effects);
} }
} finally { } finally {
@ -664,14 +664,14 @@ function flush_queued_effects(effects) {
} }
} }
function flush_deferred_effects(yielded_effects = false) { function flush_deferred_effects(post_effects = false) {
is_micro_task_queued = false; is_micro_task_queued = false;
if (flush_count > 1001) { if (flush_count > 1001) {
return; return;
} }
const previous_queued_root_effects = queued_root_effects; const previous_queued_root_effects = queued_root_effects;
queued_root_effects = []; queued_root_effects = [];
flush_queued_root_effects(previous_queued_root_effects, yielded_effects); flush_queued_root_effects(previous_queued_root_effects, post_effects);
if (!is_micro_task_queued) { if (!is_micro_task_queued) {
flush_count = 0; flush_count = 0;
@ -682,18 +682,18 @@ function flush_deferred_effects(yielded_effects = false) {
} }
} }
function flush_yield_effects() { function flush_post_effects() {
is_yield_queued = false; is_post_task_queued = false;
for (var i = 0; i < queued_yield_effects.length; i++) { for (var i = 0; i < queued_post_effects.length; i++) {
var effect = queued_yield_effects[i]; var effect = queued_post_effects[i];
if ((effect.f & (DESTROYED | INERT)) === 0) { if ((effect.f & (DESTROYED | INERT)) === 0) {
last_scheduled_effect = effect; last_scheduled_effect = effect;
mark_parent_effects(effect); mark_parent_effects(effect);
} }
} }
queued_yield_effects = []; queued_post_effects = [];
flush_deferred_effects(true); flush_deferred_effects(true);
} }
@ -723,12 +723,12 @@ function mark_parent_effects(signal) {
*/ */
export function schedule_effect(signal) { export function schedule_effect(signal) {
if (scheduler_mode !== FLUSH_SYNC) { if (scheduler_mode !== FLUSH_SYNC) {
if ((signal.f & YIELD_EFFECT) !== 0) { if ((signal.f & POST_EFFECT) !== 0) {
if (!is_yield_queued) { if (!is_post_task_queued) {
is_yield_queued = true; is_post_task_queued = true;
schedule_yield(flush_yield_effects); schedule_yield(flush_post_effects);
} }
queued_yield_effects.push(signal); queued_post_effects.push(signal);
return; return;
} }
if (!is_micro_task_queued) { if (!is_micro_task_queued) {
@ -750,10 +750,10 @@ export function schedule_effect(signal) {
* *
* @param {Effect} effect * @param {Effect} effect
* @param {Effect[]} collected_effects * @param {Effect[]} collected_effects
* @param {boolean} yielded_effects * @param {boolean} post_effects
* @returns {void} * @returns {void}
*/ */
function process_effects(effect, collected_effects, yielded_effects) { function process_effects(effect, collected_effects, post_effects) {
var current_effect = effect.first; var current_effect = effect.first;
var effects = []; var effects = [];
@ -783,7 +783,7 @@ function process_effects(effect, collected_effects, yielded_effects) {
current_effect = child; current_effect = child;
continue; continue;
} }
} else if ((flags & EFFECT) !== 0 || (yielded_effects && (flags & YIELD_EFFECT) !== 0)) { } else if ((flags & EFFECT) !== 0 || (post_effects && (flags & POST_EFFECT) !== 0)) {
effects.push(current_effect); effects.push(current_effect);
} }
} }
@ -812,7 +812,7 @@ function process_effects(effect, collected_effects, yielded_effects) {
for (var i = 0; i < effects.length; i++) { for (var i = 0; i < effects.length; i++) {
child = effects[i]; child = effects[i];
collected_effects.push(child); collected_effects.push(child);
process_effects(child, collected_effects, yielded_effects); process_effects(child, collected_effects, post_effects);
} }
} }

@ -427,7 +427,7 @@ const RUNES = /** @type {const} */ ([
'$derived.by', '$derived.by',
'$effect', '$effect',
'$effect.pre', '$effect.pre',
'$effect.yield', '$effect.post',
'$effect.tracking', '$effect.tracking',
'$effect.root', '$effect.root',
'$inspect', '$inspect',

Loading…
Cancel
Save