chore: move more element stuff (#10780)

* move bindings

* move transitions

* move custom-elements.js

* move operations.js

* move hydration.js

* move reconciler.js

* move map stuff out of dom operations

* move action code

* move transition code

* missing imports

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/10770/head
Rich Harris 10 months ago committed by GitHub
parent de021aebb5
commit eb40417c36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,9 +1,9 @@
import { is_promise } from '../../../common.js'; import { is_promise } from '../../../common.js';
import { hydrate_block_anchor } from '../../hydration.js'; import { hydrate_block_anchor } from '../hydration.js';
import { remove } from '../../reconciler.js'; import { remove } from '../reconciler.js';
import { current_block, execute_effect, flushSync } from '../../runtime.js'; import { current_block, execute_effect, flushSync } from '../../runtime.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../elements/transitions.js';
import { AWAIT_BLOCK, UNINITIALIZED } from '../../constants.js'; import { AWAIT_BLOCK, UNINITIALIZED } from '../../constants.js';
/** @returns {import('../../types.js').AwaitBlock} */ /** @returns {import('../../types.js').AwaitBlock} */

@ -1,8 +1,8 @@
import { namespace_svg } from '../../../../constants.js'; import { namespace_svg } from '../../../../constants.js';
import { current_hydration_fragment, hydrate_block_anchor, hydrating } from '../../hydration.js'; import { current_hydration_fragment, hydrate_block_anchor, hydrating } from '../hydration.js';
import { empty } from '../../operations.js'; import { empty } from '../operations.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/effects.js';
import { insert, remove } from '../../reconciler.js'; import { insert, remove } from '../reconciler.js';
/** /**
* @param {Element | Text | Comment} anchor * @param {Element | Text | Comment} anchor

@ -13,14 +13,14 @@ import {
hydrate_block_anchor, hydrate_block_anchor,
hydrating, hydrating,
set_current_hydration_fragment set_current_hydration_fragment
} from '../../hydration.js'; } from '../hydration.js';
import { clear_text_content, empty, map_get, map_set } from '../../operations.js'; import { clear_text_content, empty } from '../operations.js';
import { insert, remove } from '../../reconciler.js'; import { insert, remove } from '../reconciler.js';
import { current_block, execute_effect } from '../../runtime.js'; import { current_block, execute_effect } from '../../runtime.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { source, mutable_source, set } from '../../reactivity/sources.js'; import { source, mutable_source, set } from '../../reactivity/sources.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../elements/transitions.js';
import { is_array, is_frozen } from '../../utils.js'; import { is_array, is_frozen, map_get, map_set } from '../../utils.js';
import { EACH_BLOCK, EACH_ITEM_BLOCK, STATE_SYMBOL } from '../../constants.js'; import { EACH_BLOCK, EACH_ITEM_BLOCK, STATE_SYMBOL } from '../../constants.js';
const NEW_BLOCK = -1; const NEW_BLOCK = -1;

@ -1,5 +1,5 @@
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/effects.js';
import { reconcile_html, remove } from '../../reconciler.js'; import { reconcile_html, remove } from '../reconciler.js';
/** /**
* @param {Element | Text | Comment} dom * @param {Element | Text | Comment} dom

@ -4,11 +4,11 @@ import {
hydrate_block_anchor, hydrate_block_anchor,
hydrating, hydrating,
set_current_hydration_fragment set_current_hydration_fragment
} from '../../hydration.js'; } from '../hydration.js';
import { remove } from '../../reconciler.js'; import { remove } from '../reconciler.js';
import { current_block, execute_effect } from '../../runtime.js'; import { current_block, execute_effect } from '../../runtime.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../elements/transitions.js';
/** @returns {import('../../types.js').IfBlock} */ /** @returns {import('../../types.js').IfBlock} */
function create_if_block() { function create_if_block() {

@ -1,9 +1,9 @@
import { UNINITIALIZED, KEY_BLOCK } from '../../constants.js'; import { UNINITIALIZED, KEY_BLOCK } from '../../constants.js';
import { hydrate_block_anchor } from '../../hydration.js'; import { hydrate_block_anchor } from '../hydration.js';
import { remove } from '../../reconciler.js'; import { remove } from '../reconciler.js';
import { current_block, execute_effect } from '../../runtime.js'; import { current_block, execute_effect } from '../../runtime.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../elements/transitions.js';
import { safe_not_equal } from '../../reactivity/equality.js'; import { safe_not_equal } from '../../reactivity/equality.js';
/** @returns {import('../../types.js').KeyBlock} */ /** @returns {import('../../types.js').KeyBlock} */

@ -1,6 +1,6 @@
import { SNIPPET_BLOCK } from '../../constants.js'; import { SNIPPET_BLOCK } from '../../constants.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/effects.js';
import { remove } from '../../reconciler.js'; import { remove } from '../reconciler.js';
import { current_block, untrack } from '../../runtime.js'; import { current_block, untrack } from '../../runtime.js';
/** /**

@ -1,9 +1,9 @@
import { DYNAMIC_COMPONENT_BLOCK } from '../../constants.js'; import { DYNAMIC_COMPONENT_BLOCK } from '../../constants.js';
import { hydrate_block_anchor } from '../../hydration.js'; import { hydrate_block_anchor } from '../hydration.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { remove } from '../../reconciler.js'; import { remove } from '../reconciler.js';
import { current_block, execute_effect } from '../../runtime.js'; import { current_block, execute_effect } from '../../runtime.js';
import { trigger_transitions } from '../../transitions.js'; import { trigger_transitions } from '../elements/transitions.js';
/** /**
* @template P * @template P

@ -1,9 +1,9 @@
import { namespace_svg } from '../../../../constants.js'; import { namespace_svg } from '../../../../constants.js';
import { DYNAMIC_ELEMENT_BLOCK } from '../../constants.js'; import { DYNAMIC_ELEMENT_BLOCK } from '../../constants.js';
import { current_hydration_fragment, hydrate_block_anchor, hydrating } from '../../hydration.js'; import { current_hydration_fragment, hydrate_block_anchor, hydrating } from '../hydration.js';
import { empty } from '../../operations.js'; import { empty } from '../operations.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { insert, remove } from '../../reconciler.js'; import { insert, remove } from '../reconciler.js';
import { current_block, execute_effect } from '../../runtime.js'; import { current_block, execute_effect } from '../../runtime.js';
import { is_array } from '../../utils.js'; import { is_array } from '../../utils.js';

@ -4,10 +4,10 @@ import {
get_hydration_fragment, get_hydration_fragment,
hydrating, hydrating,
set_current_hydration_fragment set_current_hydration_fragment
} from '../../hydration.js'; } from '../hydration.js';
import { empty } from '../../operations.js'; import { empty } from '../operations.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/effects.js';
import { remove } from '../../reconciler.js'; import { remove } from '../reconciler.js';
import { current_block } from '../../runtime.js'; import { current_block } from '../../runtime.js';
/** /**

@ -0,0 +1,53 @@
import { effect } from '../../reactivity/effects.js';
import { deep_read_state, untrack } from '../../runtime.js';
/**
* @template P
* @param {Element} dom
* @param {(dom: Element, value?: P) => import('#client').ActionPayload<P>} action
* @param {() => P} [value_fn]
* @returns {void}
*/
export function action(dom, action, value_fn) {
/** @type {undefined | import('#client').ActionPayload<P>} */
var payload = undefined;
var needs_deep_read = false;
// Action could come from a prop, therefore could be a signal, therefore untrack
// TODO we could take advantage of this and enable https://github.com/sveltejs/svelte/issues/6942
effect(() => {
if (value_fn) {
var value = value_fn();
untrack(() => {
if (payload === undefined) {
payload = action(dom, value) || {};
needs_deep_read = !!payload?.update;
} else {
var update = payload.update;
if (typeof update === 'function') {
update(value);
}
}
});
// Action's update method is coarse-grained, i.e. when anything in the passed value changes, update.
// This works in legacy mode because of mutable_source being updated as a whole, but when using $state
// together with actions and mutation, it wouldn't notice the change without a deep read.
if (needs_deep_read) {
deep_read_state(value);
}
} else {
untrack(() => (payload = action(dom)));
}
});
effect(() => {
if (payload !== undefined) {
var destroy = payload.destroy;
if (typeof destroy === 'function') {
return () => {
/** @type {Function} */ (destroy)();
};
}
}
});
}

@ -1,8 +1,7 @@
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { hydrating } from '../../hydration.js'; import { hydrating } from '../hydration.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/effects.js';
import { get_descriptors, object_assign } from '../../utils.js'; import { get_descriptors, map_get, map_set, object_assign } from '../../utils.js';
import { map_get, map_set } from '../../operations.js';
import { AttributeAliases, DelegatedEvents, namespace_svg } from '../../../../constants.js'; import { AttributeAliases, DelegatedEvents, namespace_svg } from '../../../../constants.js';
import { delegate } from './events.js'; import { delegate } from './events.js';
import { autofocus } from './misc.js'; import { autofocus } from './misc.js';

@ -1,6 +1,6 @@
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../../reactivity/effects.js';
import { stringify } from '../../render.js'; import { stringify } from '../../../render.js';
/** /**
* @param {HTMLInputElement} input * @param {HTMLInputElement} input

@ -1,5 +1,5 @@
import { hydrating } from '../../hydration.js'; import { hydrating } from '../../hydration.js';
import { destroy_effect, managed_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, managed_effect, render_effect } from '../../../reactivity/effects.js';
import { listen } from './shared.js'; import { listen } from './shared.js';
/** @param {TimeRanges} ranges */ /** @param {TimeRanges} ranges */

@ -1,5 +1,5 @@
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../../reactivity/effects.js';
import { get_descriptor } from '../../utils.js'; import { get_descriptor } from '../../../utils.js';
/** /**
* Makes an `export`ed (non-prop) variable available on the `$$props` object * Makes an `export`ed (non-prop) variable available on the `$$props` object

@ -1,4 +1,4 @@
import { effect } from '../../reactivity/effects.js'; import { effect } from '../../../reactivity/effects.js';
/** /**
* Selects the correct option(s) (depending on whether this is a multiple select) * Selects the correct option(s) (depending on whether this is a multiple select)

@ -1,4 +1,4 @@
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../../reactivity/effects.js';
/** /**
* Fires the handler once immediately (unless corresponding arg is set to `false`), * Fires the handler once immediately (unless corresponding arg is set to `false`),

@ -1,5 +1,5 @@
import { effect, render_effect } from '../../reactivity/effects.js'; import { effect, render_effect } from '../../../reactivity/effects.js';
import { untrack } from '../../runtime.js'; import { untrack } from '../../../runtime.js';
/** /**
* Resize observer singleton. * Resize observer singleton.

@ -1,6 +1,6 @@
import { STATE_SYMBOL } from '../../constants.js'; import { STATE_SYMBOL } from '../../../constants.js';
import { effect } from '../../reactivity/effects.js'; import { effect } from '../../../reactivity/effects.js';
import { untrack } from '../../runtime.js'; import { untrack } from '../../../runtime.js';
/** /**
* @param {any} bound_value * @param {any} bound_value

@ -1,4 +1,4 @@
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../../reactivity/effects.js';
/** /**
* @param {'innerHTML' | 'textContent' | 'innerText'} property * @param {'innerHTML' | 'textContent' | 'innerText'} property

@ -1,4 +1,4 @@
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../../reactivity/effects.js';
import { listen } from './shared.js'; import { listen } from './shared.js';
/** /**

@ -1,5 +1,5 @@
import { hydrating } from '../../hydration.js'; import { hydrating } from '../hydration.js';
import { set_class_name } from '../../operations.js'; import { set_class_name } from '../operations.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/effects.js';
/** /**

@ -1,7 +1,7 @@
import { createClassComponent } from '../../legacy/legacy-client.js'; import { createClassComponent } from '../../../../legacy/legacy-client.js';
import { destroy_effect, render_effect } from './reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { open, close } from './dom/template.js'; import { open, close } from '../template.js';
import { define_property } from './utils.js'; import { define_property } from '../../utils.js';
/** /**
* @typedef {Object} CustomElementPropDefinition * @typedef {Object} CustomElementPropDefinition

@ -1,4 +1,4 @@
import { hydrating } from '../../hydration.js'; import { hydrating } from '../hydration.js';
import { render_effect } from '../../reactivity/effects.js'; import { render_effect } from '../../reactivity/effects.js';
import { current_block } from '../../runtime.js'; import { current_block } from '../../runtime.js';

@ -1,5 +1,5 @@
import { EACH_IS_ANIMATED, EACH_IS_CONTROLLED } from '../../constants.js'; import { EACH_IS_ANIMATED, EACH_IS_CONTROLLED } from '../../../../constants.js';
import { run_all } from '../common.js'; import { run_all } from '../../../common.js';
import { import {
AWAIT_BLOCK, AWAIT_BLOCK,
DYNAMIC_COMPONENT_BLOCK, DYNAMIC_COMPONENT_BLOCK,
@ -8,24 +8,24 @@ import {
IF_BLOCK, IF_BLOCK,
KEY_BLOCK, KEY_BLOCK,
ROOT_BLOCK ROOT_BLOCK
} from './constants.js'; } from '../../constants.js';
import { destroy_each_item_block, get_first_element } from './dom/blocks/each.js'; import { destroy_each_item_block, get_first_element } from '../blocks/each.js';
import { schedule_raf_task } from './dom/task.js'; import { schedule_raf_task } from '../task.js';
import { append_child, empty } from './operations.js'; import { append_child, empty } from '../operations.js';
import { import {
destroy_effect, destroy_effect,
effect, effect,
managed_effect, managed_effect,
managed_pre_effect managed_pre_effect
} from './reactivity/effects.js'; } from '../../reactivity/effects.js';
import { import {
current_block, current_block,
current_effect, current_effect,
execute_effect, execute_effect,
mark_subtree_inert, mark_subtree_inert,
untrack untrack
} from './runtime.js'; } from '../../runtime.js';
import { raf } from './timing.js'; import { raf } from '../../timing.js';
const active_tick_animations = new Set(); const active_tick_animations = new Set();
const DELAY_NEXT_TICK = Number.MIN_SAFE_INTEGER; const DELAY_NEXT_TICK = Number.MIN_SAFE_INTEGER;
@ -33,6 +33,54 @@ const DELAY_NEXT_TICK = Number.MIN_SAFE_INTEGER;
/** @type {undefined | number} */ /** @type {undefined | number} */
let active_tick_ref = undefined; let active_tick_ref = undefined;
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('#client').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @param {any} global
* @returns {void}
*/
export function transition(dom, get_transition_fn, props, global = false) {
bind_transition(dom, get_transition_fn, props, 'both', global);
}
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('#client').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @returns {void}
*/
export function animate(dom, get_transition_fn, props) {
bind_transition(dom, get_transition_fn, props, 'key', false);
}
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('#client').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @param {any} global
* @returns {void}
*/
function in_fn(dom, get_transition_fn, props, global = false) {
bind_transition(dom, get_transition_fn, props, 'in', global);
}
export { in_fn as in };
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('#client').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @param {any} global
* @returns {void}
*/
export function out(dom, get_transition_fn, props, global = false) {
bind_transition(dom, get_transition_fn, props, 'out', global);
}
/** /**
* @template T * @template T
* @param {string} type * @param {string} type
@ -297,10 +345,10 @@ const linear = (t) => t;
/** /**
* @param {HTMLElement} dom * @param {HTMLElement} dom
* @param {() => import('./types.js').TransitionPayload} init * @param {() => import('../../types.js').TransitionPayload} init
* @param {'in' | 'out' | 'both' | 'key'} direction * @param {'in' | 'out' | 'both' | 'key'} direction
* @param {import('./types.js').Effect} effect * @param {import('../../types.js').Effect} effect
* @returns {import('./types.js').Transition} * @returns {import('../../types.js').Transition}
*/ */
function create_transition(dom, init, direction, effect) { function create_transition(dom, init, direction, effect) {
let curr_direction = 'in'; let curr_direction = 'in';
@ -313,7 +361,7 @@ function create_transition(dom, init, direction, effect) {
let cancelled = false; let cancelled = false;
const create_animation = () => { const create_animation = () => {
let payload = /** @type {import('./types.js').TransitionPayload} */ (transition.p); let payload = /** @type {import('../../types.js').TransitionPayload} */ (transition.p);
if (typeof payload === 'function') { if (typeof payload === 'function') {
// @ts-ignore // @ts-ignore
payload = payload({ direction: curr_direction }); payload = payload({ direction: curr_direction });
@ -354,7 +402,7 @@ function create_transition(dom, init, direction, effect) {
}; };
}; };
/** @type {import('./types.js').Transition} */ /** @type {import('../../types.js').Transition} */
const transition = { const transition = {
e: effect, e: effect,
i: init, i: init,
@ -482,7 +530,7 @@ function create_transition(dom, init, direction, effect) {
} }
/** /**
* @param {import('./types.js').Block} block * @param {import('../../types.js').Block} block
* @returns {boolean} * @returns {boolean}
*/ */
function is_transition_block(block) { function is_transition_block(block) {
@ -500,14 +548,14 @@ function is_transition_block(block) {
/** /**
* @template P * @template P
* @param {HTMLElement} dom * @param {HTMLElement} dom
* @param {() => import('./types.js').TransitionFn<P | undefined> | import('./types.js').AnimateFn<P | undefined>} get_transition_fn * @param {() => import('../../types.js').TransitionFn<P | undefined> | import('../../types.js').AnimateFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props_fn * @param {(() => P) | null} props_fn
* @param {'in' | 'out' | 'both' | 'key'} direction * @param {'in' | 'out' | 'both' | 'key'} direction
* @param {boolean} global * @param {boolean} global
* @returns {void} * @returns {void}
*/ */
export function bind_transition(dom, get_transition_fn, props_fn, direction, global) { function bind_transition(dom, get_transition_fn, props_fn, direction, global) {
const transition_effect = /** @type {import('./types.js').Effect} */ (current_effect); const transition_effect = /** @type {import('../../types.js').Effect} */ (current_effect);
const block = current_block; const block = current_block;
const is_keyed_transition = direction === 'key'; const is_keyed_transition = direction === 'key';
@ -518,7 +566,7 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
// @ts-ignore // @ts-ignore
dom.__animate = true; dom.__animate = true;
} }
/** @type {import('./types.js').Block | null} */ /** @type {import('../../types.js').Block | null} */
let transition_block = block; let transition_block = block;
main: while (transition_block !== null) { main: while (transition_block !== null) {
if (is_transition_block(transition_block)) { if (is_transition_block(transition_block)) {
@ -532,7 +580,7 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
} else if (transition_block.t === IF_BLOCK) { } else if (transition_block.t === IF_BLOCK) {
transition_block.r = if_block_transition; transition_block.r = if_block_transition;
if (can_show_intro_on_mount) { if (can_show_intro_on_mount) {
/** @type {import('./types.js').Block | null} */ /** @type {import('../../types.js').Block | null} */
let if_block = transition_block; let if_block = transition_block;
while (if_block.t === IF_BLOCK) { while (if_block.t === IF_BLOCK) {
// If we have an if block parent that is currently falsy then // If we have an if block parent that is currently falsy then
@ -557,7 +605,7 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
transition_block = transition_block.p; transition_block = transition_block.p;
} }
/** @type {import('./types.js').Transition} */ /** @type {import('../../types.js').Transition} */
let transition; let transition;
effect(() => { effect(() => {
@ -573,13 +621,13 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
untrack(() => { untrack(() => {
const props = props_fn === null ? {} : props_fn(); const props = props_fn === null ? {} : props_fn();
return is_keyed_transition return is_keyed_transition
? /** @type {import('./types.js').AnimateFn<any>} */ (transition_fn)( ? /** @type {import('../../types.js').AnimateFn<any>} */ (transition_fn)(
dom, dom,
{ from: /** @type {DOMRect} */ (from), to: dom.getBoundingClientRect() }, { from: /** @type {DOMRect} */ (from), to: dom.getBoundingClientRect() },
props, props,
{} {}
) )
: /** @type {import('./types.js').TransitionFn<any>} */ (transition_fn)(dom, props, { : /** @type {import('../../types.js').TransitionFn<any>} */ (transition_fn)(dom, props, {
direction direction
}); });
}); });
@ -600,7 +648,7 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
transition.in(); transition.in();
} }
/** @type {import('./types.js').Block | null} */ /** @type {import('../../types.js').Block | null} */
let transition_block = block; let transition_block = block;
while (!is_intro && transition_block !== null) { while (!is_intro && transition_block !== null) {
const parent = transition_block.p; const parent = transition_block.p;
@ -630,7 +678,7 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
} }
/** /**
* @param {Set<import('./types.js').Transition>} transitions * @param {Set<import('../../types.js').Transition>} transitions
* @param {'in' | 'out' | 'key'} target_direction * @param {'in' | 'out' | 'key'} target_direction
* @param {DOMRect} [from] * @param {DOMRect} [from]
* @returns {void} * @returns {void}
@ -680,8 +728,8 @@ export function trigger_transitions(transitions, target_direction, from) {
} }
/** /**
* @this {import('./types.js').IfBlock} * @this {import('../../types.js').IfBlock}
* @param {import('./types.js').Transition} transition * @param {import('../../types.js').Transition} transition
* @returns {void} * @returns {void}
*/ */
function if_block_transition(transition) { function if_block_transition(transition) {
@ -691,32 +739,32 @@ function if_block_transition(transition) {
const consequent_transitions = (block.c ??= new Set()); const consequent_transitions = (block.c ??= new Set());
consequent_transitions.add(transition); consequent_transitions.add(transition);
transition.f(() => { transition.f(() => {
const c = /** @type {Set<import('./types.js').Transition>} */ (consequent_transitions); const c = /** @type {Set<import('../../types.js').Transition>} */ (consequent_transitions);
c.delete(transition); c.delete(transition);
// If the block has changed to falsy and has transitions // If the block has changed to falsy and has transitions
if (!block.v && c.size === 0) { if (!block.v && c.size === 0) {
const consequent_effect = block.ce; const consequent_effect = block.ce;
execute_effect(/** @type {import('./types.js').Effect} */ (consequent_effect)); execute_effect(/** @type {import('../../types.js').Effect} */ (consequent_effect));
} }
}); });
} else { } else {
const alternate_transitions = (block.a ??= new Set()); const alternate_transitions = (block.a ??= new Set());
alternate_transitions.add(transition); alternate_transitions.add(transition);
transition.f(() => { transition.f(() => {
const a = /** @type {Set<import('./types.js').Transition>} */ (alternate_transitions); const a = /** @type {Set<import('../../types.js').Transition>} */ (alternate_transitions);
a.delete(transition); a.delete(transition);
// If the block has changed to truthy and has transitions // If the block has changed to truthy and has transitions
if (block.v && a.size === 0) { if (block.v && a.size === 0) {
const alternate_effect = block.ae; const alternate_effect = block.ae;
execute_effect(/** @type {import('./types.js').Effect} */ (alternate_effect)); execute_effect(/** @type {import('../../types.js').Effect} */ (alternate_effect));
} }
}); });
} }
} }
/** /**
* @this {import('./types.js').EachItemBlock} * @this {import('../../types.js').EachItemBlock}
* @param {import('./types.js').Transition} transition * @param {import('../../types.js').Transition} transition
* @returns {void} * @returns {void}
*/ */
function each_item_transition(transition) { function each_item_transition(transition) {
@ -754,8 +802,8 @@ function each_item_transition(transition) {
/** /**
* *
* @param {import('./types.js').EachItemBlock} block * @param {import('../../types.js').EachItemBlock} block
* @param {Set<import('./types.js').Transition>} transitions * @param {Set<import('../../types.js').Transition>} transitions
*/ */
function each_item_animate(block, transitions) { function each_item_animate(block, transitions) {
const from_dom = /** @type {Element} */ (get_first_element(block)); const from_dom = /** @type {Element} */ (get_first_element(block));

@ -1,6 +1,6 @@
// Handle hydration // Handle hydration
import { schedule_task } from './dom/task.js'; import { schedule_task } from './task.js';
import { empty } from './operations.js'; import { empty } from './operations.js';
/** /**
@ -13,27 +13,27 @@ export let hydrating = false;
* Array of nodes to traverse for hydration. This will be null if we're not hydrating, but for * Array of nodes to traverse for hydration. This will be null if we're not hydrating, but for
* the sake of simplicity we're not going to use `null` checks everywhere and instead rely on * the sake of simplicity we're not going to use `null` checks everywhere and instead rely on
* the `hydrating` flag to tell whether or not we're in hydration mode at which point this is set. * the `hydrating` flag to tell whether or not we're in hydration mode at which point this is set.
* @type {import('./types.js').TemplateNode[]} * @type {import('../types.js').TemplateNode[]}
*/ */
export let current_hydration_fragment = /** @type {any} */ (null); export let current_hydration_fragment = /** @type {any} */ (null);
/** /**
* @param {null | import('./types.js').TemplateNode[]} fragment * @param {null | import('../types.js').TemplateNode[]} fragment
* @returns {void} * @returns {void}
*/ */
export function set_current_hydration_fragment(fragment) { export function set_current_hydration_fragment(fragment) {
hydrating = fragment !== null; hydrating = fragment !== null;
current_hydration_fragment = /** @type {import('./types.js').TemplateNode[]} */ (fragment); current_hydration_fragment = /** @type {import('../types.js').TemplateNode[]} */ (fragment);
} }
/** /**
* Returns all nodes between the first `<!--ssr:...-->` comment tag pair encountered. * Returns all nodes between the first `<!--ssr:...-->` comment tag pair encountered.
* @param {Node | null} node * @param {Node | null} node
* @param {boolean} [insert_text] Whether to insert an empty text node if the fragment is empty * @param {boolean} [insert_text] Whether to insert an empty text node if the fragment is empty
* @returns {import('./types.js').TemplateNode[] | null} * @returns {import('../types.js').TemplateNode[] | null}
*/ */
export function get_hydration_fragment(node, insert_text = false) { export function get_hydration_fragment(node, insert_text = false) {
/** @type {import('./types.js').TemplateNode[]} */ /** @type {import('../types.js').TemplateNode[]} */
const fragment = []; const fragment = [];
/** @type {null | Node} */ /** @type {null | Node} */

@ -1,5 +1,5 @@
import { current_hydration_fragment, get_hydration_fragment, hydrating } from './hydration.js'; import { current_hydration_fragment, get_hydration_fragment, hydrating } from './hydration.js';
import { get_descriptor } from './utils.js'; import { get_descriptor } from '../utils.js';
// We cache the Node and Element prototype methods, so that we can avoid doing // We cache the Node and Element prototype methods, so that we can avoid doing
// expensive prototype chain lookups. // expensive prototype chain lookups.
@ -13,12 +13,6 @@ var element_prototype;
/** @type {Text} */ /** @type {Text} */
var text_prototype; var text_prototype;
/** @type {Map<any, any>} */
var map_prototype = Map.prototype;
var map_set_method = map_prototype.set;
var map_get_method = map_prototype.get;
var map_delete_method = map_prototype.delete;
/** @type {typeof Node.prototype.appendChild} */ /** @type {typeof Node.prototype.appendChild} */
var append_child_method; var append_child_method;
@ -105,38 +99,6 @@ export function append_child(element, child) {
append_child_method.call(element, child); append_child_method.call(element, child);
} }
/**
* @template K
* @template V
* @param {Map<K, V>} map
* @param {K} key
* @param {V} value
*/
export function map_set(map, key, value) {
map_set_method.call(map, key, value);
}
/**
* @template K
* @template V
* @param {Map<K, V>} map
* @param {K} key
*/
export function map_delete(map, key) {
map_delete_method.call(map, key);
}
/**
* @template K
* @template V
* @param {Map<K, V>} map
* @param {K} key
* @return {V}
*/
export function map_get(map, key) {
return map_get_method.call(map, key);
}
/** /**
* @template {Node} N * @template {Node} N
* @param {N} node * @param {N} node

@ -1,6 +1,6 @@
import { append_child } from './operations.js'; import { append_child } from './operations.js';
import { current_hydration_fragment, hydrate_block_anchor, hydrating } from './hydration.js'; import { current_hydration_fragment, hydrate_block_anchor, hydrating } from './hydration.js';
import { is_array } from './utils.js'; import { is_array } from '../utils.js';
/** @param {string} html */ /** @param {string} html */
export function create_fragment_from_html(html) { export function create_fragment_from_html(html) {
@ -29,7 +29,7 @@ export function create_fragment_with_script_from_html(html) {
} }
/** /**
* @param {Array<import('./types.js').TemplateNode> | import('./types.js').TemplateNode} current * @param {Array<import('../types.js').TemplateNode> | import('../types.js').TemplateNode} current
* @param {null | Element} parent_element * @param {null | Element} parent_element
* @param {null | Text | Element | Comment} sibling * @param {null | Text | Element | Comment} sibling
* @returns {Text | Element | Comment} * @returns {Text | Element | Comment}
@ -58,7 +58,7 @@ export function insert(current, parent_element, sibling) {
} }
/** /**
* @param {Array<import('./types.js').TemplateNode> | import('./types.js').TemplateNode} current * @param {Array<import('../types.js').TemplateNode> | import('../types.js').TemplateNode} current
* @returns {Element | Comment | Text} * @returns {Element | Comment | Text}
*/ */
export function remove(current) { export function remove(current) {

@ -1,10 +1,10 @@
import { current_hydration_fragment, hydrate_block_anchor, hydrating } from '../hydration.js'; import { current_hydration_fragment, hydrate_block_anchor, hydrating } from './hydration.js';
import { child, clone_node, empty } from '../operations.js'; import { child, clone_node, empty } from './operations.js';
import { import {
create_fragment_from_html, create_fragment_from_html,
create_fragment_with_script_from_html, create_fragment_with_script_from_html,
insert insert
} from '../reconciler.js'; } from './reconciler.js';
import { current_block } from '../runtime.js'; import { current_block } from '../runtime.js';
import { is_array } from '../utils.js'; import { is_array } from '../utils.js';

@ -1,25 +1,17 @@
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { append_child, create_element, empty, init_operations } from './operations.js'; import { append_child, create_element, empty, init_operations } from './dom/operations.js';
import { PassiveDelegatedEvents } from '../../constants.js'; import { PassiveDelegatedEvents } from '../../constants.js';
import { remove } from './reconciler.js'; import { remove } from './dom/reconciler.js';
import { import { flush_sync, push, pop, current_component_context } from './runtime.js';
untrack, import { render_effect, destroy_effect } from './reactivity/effects.js';
flush_sync,
push,
pop,
current_component_context,
deep_read_state
} from './runtime.js';
import { render_effect, effect, destroy_effect } from './reactivity/effects.js';
import { import {
current_hydration_fragment, current_hydration_fragment,
get_hydration_fragment, get_hydration_fragment,
hydrate_block_anchor, hydrate_block_anchor,
hydrating, hydrating,
set_current_hydration_fragment set_current_hydration_fragment
} from './hydration.js'; } from './dom/hydration.js';
import { array_from } from './utils.js'; import { array_from } from './utils.js';
import { bind_transition } from './transitions.js';
import { ROOT_BLOCK } from './constants.js'; import { ROOT_BLOCK } from './constants.js';
import { handle_event_propagation } from './dom/elements/events.js'; import { handle_event_propagation } from './dom/elements/events.js';
@ -83,103 +75,6 @@ export function stringify(value) {
return typeof value === 'string' ? value : value == null ? '' : value + ''; return typeof value === 'string' ? value : value == null ? '' : value + '';
} }
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('./types.js').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @param {any} global
* @returns {void}
*/
export function transition(dom, get_transition_fn, props, global = false) {
bind_transition(dom, get_transition_fn, props, 'both', global);
}
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('./types.js').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @returns {void}
*/
export function animate(dom, get_transition_fn, props) {
bind_transition(dom, get_transition_fn, props, 'key', false);
}
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('./types.js').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @param {any} global
* @returns {void}
*/
function in_fn(dom, get_transition_fn, props, global = false) {
bind_transition(dom, get_transition_fn, props, 'in', global);
}
export { in_fn as in };
/**
* @template P
* @param {HTMLElement} dom
* @param {() => import('./types.js').TransitionFn<P | undefined>} get_transition_fn
* @param {(() => P) | null} props
* @param {any} global
* @returns {void}
*/
export function out(dom, get_transition_fn, props, global = false) {
bind_transition(dom, get_transition_fn, props, 'out', global);
}
/**
* @template P
* @param {Element} dom
* @param {(dom: Element, value?: P) => import('./types.js').ActionPayload<P>} action
* @param {() => P} [value_fn]
* @returns {void}
*/
export function action(dom, action, value_fn) {
/** @type {undefined | import('./types.js').ActionPayload<P>} */
let payload = undefined;
let needs_deep_read = false;
// Action could come from a prop, therefore could be a signal, therefore untrack
// TODO we could take advantage of this and enable https://github.com/sveltejs/svelte/issues/6942
effect(() => {
if (value_fn) {
const value = value_fn();
untrack(() => {
if (payload === undefined) {
payload = action(dom, value) || {};
needs_deep_read = !!payload?.update;
} else {
const update = payload.update;
if (typeof update === 'function') {
update(value);
}
}
});
// Action's update method is coarse-grained, i.e. when anything in the passed value changes, update.
// This works in legacy mode because of mutable_source being updated as a whole, but when using $state
// together with actions and mutation, it wouldn't notice the change without a deep read.
if (needs_deep_read) {
deep_read_state(value);
}
} else {
untrack(() => (payload = action(dom)));
}
});
effect(() => {
if (payload !== undefined) {
const destroy = payload.destroy;
if (typeof destroy === 'function') {
return () => {
destroy();
};
}
}
});
}
// TODO 5.0 remove this // TODO 5.0 remove this
/** /**
* @deprecated Use `mount` or `hydrate` instead * @deprecated Use `mount` or `hydrate` instead

@ -13,6 +13,44 @@ export var object_prototype = Object.prototype;
export var array_prototype = Array.prototype; export var array_prototype = Array.prototype;
export var get_prototype_of = Object.getPrototypeOf; export var get_prototype_of = Object.getPrototypeOf;
/** @type {Map<any, any>} */
var map_prototype = Map.prototype;
var map_set_method = map_prototype.set;
var map_get_method = map_prototype.get;
var map_delete_method = map_prototype.delete;
/**
* @template K
* @template V
* @param {Map<K, V>} map
* @param {K} key
* @param {V} value
*/
export function map_set(map, key, value) {
map_set_method.call(map, key, value);
}
/**
* @template K
* @template V
* @param {Map<K, V>} map
* @param {K} key
*/
export function map_delete(map, key) {
map_delete_method.call(map, key);
}
/**
* @template K
* @template V
* @param {Map<K, V>} map
* @param {K} key
* @return {V}
*/
export function map_get(map, key) {
return map_get_method.call(map, key);
}
/** /**
* @param {any} thing * @param {any} thing
* @returns {thing is Function} * @returns {thing is Function}

@ -21,15 +21,6 @@ export {
hasContext hasContext
} from './client/runtime.js'; } from './client/runtime.js';
export * from './client/dev/ownership.js'; export * from './client/dev/ownership.js';
export * from './client/dom/bindings/input.js';
export * from './client/dom/bindings/media.js';
export * from './client/dom/bindings/navigator.js';
export * from './client/dom/bindings/props.js';
export * from './client/dom/bindings/select.js';
export * from './client/dom/bindings/size.js';
export * from './client/dom/bindings/this.js';
export * from './client/dom/bindings/universal.js';
export * from './client/dom/bindings/window.js';
export { await_block as await } from './client/dom/blocks/await.js'; export { await_block as await } from './client/dom/blocks/await.js';
export { if_block as if } from './client/dom/blocks/if.js'; export { if_block as if } from './client/dom/blocks/if.js';
export { key_block as key } from './client/dom/blocks/key.js'; export { key_block as key } from './client/dom/blocks/key.js';
@ -40,11 +31,22 @@ export * from './client/dom/blocks/snippet.js';
export * from './client/dom/blocks/svelte-component.js'; export * from './client/dom/blocks/svelte-component.js';
export * from './client/dom/blocks/svelte-element.js'; export * from './client/dom/blocks/svelte-element.js';
export * from './client/dom/blocks/svelte-head.js'; export * from './client/dom/blocks/svelte-head.js';
export * from './client/dom/elements/actions.js';
export * from './client/dom/elements/attributes.js'; export * from './client/dom/elements/attributes.js';
export * from './client/dom/elements/class.js'; export * from './client/dom/elements/class.js';
export * from './client/dom/elements/events.js'; export * from './client/dom/elements/events.js';
export * from './client/dom/elements/misc.js'; export * from './client/dom/elements/misc.js';
export * from './client/dom/elements/style.js'; export * from './client/dom/elements/style.js';
export * from './client/dom/elements/transitions.js';
export * from './client/dom/elements/bindings/input.js';
export * from './client/dom/elements/bindings/media.js';
export * from './client/dom/elements/bindings/navigator.js';
export * from './client/dom/elements/bindings/props.js';
export * from './client/dom/elements/bindings/select.js';
export * from './client/dom/elements/bindings/size.js';
export * from './client/dom/elements/bindings/this.js';
export * from './client/dom/elements/bindings/universal.js';
export * from './client/dom/elements/bindings/window.js';
export * from './client/dom/legacy/event-modifiers.js'; export * from './client/dom/legacy/event-modifiers.js';
export * from './client/dom/legacy/lifecycle.js'; export * from './client/dom/legacy/lifecycle.js';
export * from './client/dom/legacy/misc.js'; export * from './client/dom/legacy/misc.js';
@ -59,12 +61,12 @@ export * from './client/render.js';
export * from './client/validate.js'; export * from './client/validate.js';
export { raf } from './client/timing.js'; export { raf } from './client/timing.js';
export { proxy, unstate } from './client/proxy.js'; export { proxy, unstate } from './client/proxy.js';
export { create_custom_element } from './client/custom-element.js'; export { create_custom_element } from './client/dom/elements/custom-element.js';
export { export {
child, child,
child_frag, child_frag,
sibling, sibling,
$window as window, $window as window,
$document as document $document as document
} from './client/operations.js'; } from './client/dom/operations.js';
export { noop } from './common.js'; export { noop } from './common.js';

Loading…
Cancel
Save