aa-fork
Rich Harris 8 months ago
parent 4069441488
commit 5294730486

@ -30,3 +30,5 @@ export const STATE_SYMBOL = Symbol('$state');
export const STATE_SYMBOL_METADATA = Symbol('$state metadata'); export const STATE_SYMBOL_METADATA = Symbol('$state metadata');
export const LEGACY_PROPS = Symbol('legacy props'); export const LEGACY_PROPS = Symbol('legacy props');
export const LOADING_ATTR_SYMBOL = Symbol(''); export const LOADING_ATTR_SYMBOL = Symbol('');
export const FORK_ROOT = 1 << 1;

@ -1,5 +1,5 @@
/** @import { Effect, TemplateNode } from '#client' */ /** @import { Effect, TemplateNode } from '#client' */
import { EFFECT_TRANSPARENT } from '../../constants.js'; import { EFFECT_TRANSPARENT, FORK_ROOT } from '../../constants.js';
import { import {
hydrate_next, hydrate_next,
hydrate_node, hydrate_node,
@ -10,6 +10,7 @@ import {
} from '../hydration.js'; } from '../hydration.js';
import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js'; import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js';
import { HYDRATION_START_ELSE, UNINITIALIZED } from '../../../../constants.js'; import { HYDRATION_START_ELSE, UNINITIALIZED } from '../../../../constants.js';
import { active_fork } from '../../fork.js';
/** /**
* @param {TemplateNode} node * @param {TemplateNode} node
@ -65,6 +66,50 @@ export function if_block(node, fn, elseif = false) {
} }
} }
if (active_fork !== null && (active_fork.f & FORK_ROOT) !== 0) {
active_fork.f ^= FORK_ROOT;
const fragment = document.createDocumentFragment();
const offscreen_condition = condition;
const offscreen_anchor = document.createComment('');
fragment.append(offscreen_anchor);
const offscreen_effect = fn && branch(() => fn(offscreen_anchor));
active_fork.branches.push(() => {
anchor.before(fragment);
if (condition) {
if (consequent_effect) {
resume_effect(consequent_effect);
} else {
consequent_effect = offscreen_effect;
if (alternate_effect) {
pause_effect(alternate_effect, () => {
alternate_effect = null;
});
}
}
} else {
if (alternate_effect) {
resume_effect(alternate_effect);
} else {
alternate_effect = offscreen_effect;
if (consequent_effect) {
pause_effect(consequent_effect, () => {
consequent_effect = null;
});
}
}
}
});
return;
}
if (condition) { if (condition) {
if (consequent_effect) { if (consequent_effect) {
resume_effect(consequent_effect); resume_effect(consequent_effect);

@ -1,5 +1,5 @@
/** @import { Derived, Effect, Fork, Value } from '#client' */ /** @import { Derived, Effect, Fork, Value } from '#client' */
import { BLOCK_EFFECT, DERIVED, DIRTY, TEMPLATE_EFFECT } from './constants.js'; import { BLOCK_EFFECT, DERIVED, DIRTY, FORK_ROOT, TEMPLATE_EFFECT } from './constants.js';
import { queue_micro_task } from './dom/task.js'; import { queue_micro_task } from './dom/task.js';
import { flush_sync, schedule_effect, set_signal_status } from './runtime.js'; import { flush_sync, schedule_effect, set_signal_status } from './runtime.js';
@ -19,8 +19,10 @@ export function set_active_fork(fork) {
*/ */
function create_fork(callback) { function create_fork(callback) {
return { return {
f: FORK_ROOT,
pending: 0, pending: 0,
sources: new Map(), sources: new Map(),
branches: [],
callback callback
}; };
} }
@ -80,6 +82,10 @@ function apply_fork(fork) {
mark_effects(source); mark_effects(source);
} }
for (const fn of fork.branches) {
fn();
}
} }
/** /**

@ -185,8 +185,10 @@ export interface SourceFork {
} }
export interface Fork { export interface Fork {
f: number;
sources: Map<Source, SourceFork>; sources: Map<Source, SourceFork>;
pending: number; pending: number;
branches: Array<() => void>;
callback: (error?: Error) => void; callback: (error?: Error) => void;
} }

Loading…
Cancel
Save