chore: rename internal object properties (#9532)

* chore: rename internal object properties

chore: rename internal object properties

order properties and add comments

add missing remove_in_transitions

* jsdoc
pull/9535/head
Dominic Gannaway 2 years ago committed by GitHub
parent 5458ea7735
commit 5809ac6758
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: rename internal object properties

@ -12,87 +12,123 @@ export const DYNAMIC_ELEMENT_BLOCK = 8;
export const SNIPPET_BLOCK = 9;
/**
* @param {Node} container
* @param {boolean} intro
* @returns {import('./types.js').RootBlock}
*/
export function create_root_block(container, intro) {
export function create_root_block(intro) {
return {
dom: null,
effect: null,
container,
intro,
parent: null,
transition: null,
type: ROOT_BLOCK
// dom
d: null,
// effect
e: null,
// intro
i: intro,
// parent
p: null,
// transition
r: null,
// type
t: ROOT_BLOCK
};
}
/** @returns {import('./types.js').IfBlock} */
export function create_if_block() {
return {
current: false,
dom: null,
effect: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
transition: null,
type: IF_BLOCK
// current
c: false,
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('./types.js').Block} */ (current_block),
// transition
r: null,
// type
t: IF_BLOCK
};
}
/** @returns {import('./types.js').KeyBlock} */
export function create_key_block() {
return {
dom: null,
effect: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
transition: null,
type: KEY_BLOCK
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('./types.js').Block} */ (current_block),
// transition
r: null,
// type
t: KEY_BLOCK
};
}
/** @returns {import('./types.js').HeadBlock} */
export function create_head_block() {
return {
dom: null,
effect: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
transition: null,
type: HEAD_BLOCK
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('./types.js').Block} */ (current_block),
// transition
r: null,
// type
t: HEAD_BLOCK
};
}
/** @returns {import('./types.js').DynamicElementBlock} */
export function create_dynamic_element_block() {
return {
dom: null,
effect: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
transition: null,
type: DYNAMIC_ELEMENT_BLOCK
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('./types.js').Block} */ (current_block),
// transition
r: null,
// type
t: DYNAMIC_ELEMENT_BLOCK
};
}
/** @returns {import('./types.js').DynamicComponentBlock} */
export function create_dynamic_component_block() {
return {
dom: null,
effect: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
transition: null,
type: DYNAMIC_COMPONENT_BLOCK
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('./types.js').Block} */ (current_block),
// transition
r: null,
// type
t: DYNAMIC_COMPONENT_BLOCK
};
}
/** @returns {import('./types.js').AwaitBlock} */
export function create_await_block() {
return {
dom: null,
effect: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
pending: true,
transition: null,
type: AWAIT_BLOCK
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('./types.js').Block} */ (current_block),
// pending
n: true,
// transition
r: null,
// type
t: AWAIT_BLOCK
};
}
@ -103,15 +139,23 @@ export function create_await_block() {
*/
export function create_each_block(flags, anchor) {
return {
anchor,
dom: null,
flags,
items: [],
effect: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
transition: null,
transitions: [],
type: EACH_BLOCK
// anchor
a: anchor,
// dom
d: null,
// flags
f: flags,
// items
v: [],
// effect
e: null,
p: /** @type {import('./types.js').Block} */ (current_block),
// transition
r: null,
// transitions
s: [],
// type
t: EACH_BLOCK
};
}
@ -123,25 +167,38 @@ export function create_each_block(flags, anchor) {
*/
export function create_each_item_block(item, index, key) {
return {
dom: null,
effect: null,
index,
key,
item,
parent: /** @type {import('./types.js').EachBlock} */ (current_block),
transition: null,
transitions: null,
type: EACH_ITEM_BLOCK
// dom
d: null,
// effect
e: null,
i: index,
// key
k: key,
// item
v: item,
// parent
p: /** @type {import('./types.js').EachBlock} */ (current_block),
// transition
r: null,
// transitions
s: null,
// type
t: EACH_ITEM_BLOCK
};
}
/** @returns {import('./types.js').SnippetBlock} */
export function create_snippet_block() {
return {
dom: null,
parent: /** @type {import('./types.js').Block} */ (current_block),
effect: null,
transition: null,
type: SNIPPET_BLOCK
// dom
d: null,
// parent
p: /** @type {import('./types.js').Block} */ (current_block),
// effect
e: null,
// transition
r: null,
// type
t: SNIPPET_BLOCK
};
}

@ -112,7 +112,7 @@ export function reconcile_html(dom, value, svg) {
* @returns {Text | Element | Comment}
*/
function insert_each_item_block(block, dom, is_controlled, sibling) {
var current = /** @type {import('./types.js').TemplateNode} */ (block.dom);
var current = /** @type {import('./types.js').TemplateNode} */ (block.d);
if (sibling === null) {
if (is_controlled) {
return insert(current, /** @type {Element} */ (dom), null);
@ -128,7 +128,7 @@ function insert_each_item_block(block, dom, is_controlled, sibling) {
* @returns {Text | Element | Comment}
*/
function get_first_child(block) {
var current = block.dom;
var current = block.d;
if (is_array(current)) {
return /** @type {Text | Element | Comment} */ (current[0]);
}
@ -147,9 +147,9 @@ function destroy_active_transition_blocks(active_transitions) {
var transition;
for (; i < length; i++) {
block = active_transitions[i];
transition = block.transition;
transition = block.r;
if (transition !== null) {
block.transition = null;
block.r = null;
destroy_each_item_block(block, null, false);
}
}
@ -177,8 +177,8 @@ export function reconcile_indexed_array(
flags,
apply_transitions
) {
var a_blocks = each_block.items;
var active_transitions = each_block.transitions;
var a_blocks = each_block.v;
var active_transitions = each_block.s;
/** @type {number | void} */
var a = a_blocks.length;
@ -245,7 +245,7 @@ export function reconcile_indexed_array(
}
}
}
each_block.items = b_blocks;
each_block.v = b_blocks;
}
// Reconcile arrays by the equality of the elements in the array. This algorithm
// is based on Ivi's reconcilation logic:
@ -275,9 +275,9 @@ export function reconcile_tracked_array(
apply_transitions,
keys
) {
var a_blocks = each_block.items;
var a_blocks = each_block.v;
const is_computed_key = keys !== null;
var active_transitions = each_block.transitions;
var active_transitions = each_block.s;
/** @type {number | void} */
var a = a_blocks.length;
@ -352,7 +352,7 @@ export function reconcile_tracked_array(
// Step 1
outer: while (true) {
// From the end
while (a_blocks[a_end].key === key) {
while (a_blocks[a_end].k === key) {
block = a_blocks[a_end--];
item = array[b_end];
if (should_update_block) {
@ -368,7 +368,7 @@ export function reconcile_tracked_array(
item = array[start];
key = is_computed_key ? keys[start] : item;
// At the start
while (start <= a_end && start <= b_end && a_blocks[start].key === key) {
while (start <= a_end && start <= b_end && a_blocks[start].k === key) {
item = array[start];
block = a_blocks[start];
if (should_update_block) {
@ -410,7 +410,7 @@ export function reconcile_tracked_array(
map_set(item_index, key, a);
}
for (b = start; b <= a_end; ++b) {
a = map_get(item_index, /** @type {V} */ (a_blocks[b].key));
a = map_get(item_index, /** @type {V} */ (a_blocks[b].k));
block = a_blocks[b];
if (a !== undefined) {
pos = pos < a ? a : MOVED_BLOCK;
@ -464,7 +464,7 @@ export function reconcile_tracked_array(
}
}
}
each_block.items = b_blocks;
each_block.v = b_blocks;
}
// Longest Increased Subsequence algorithm.

@ -193,7 +193,7 @@ function close_template(dom, is_fragment, anchor) {
if (anchor !== null && current_hydration_fragment === null) {
insert(current, null, anchor);
}
block.dom = current;
block.d = current;
}
/**
@ -1366,15 +1366,16 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
let has_mounted = false;
let has_mounted_branch = false;
block.transition =
block.r =
/**
* @param {import('./types.js').Transition} transition
* @returns {void}
*/
(transition) => {
if (block.current) {
// block.current
if (block.c) {
consequent_transitions.add(transition);
transition.finished(() => {
transition.f(() => {
consequent_transitions.delete(transition);
remove_in_transitions(consequent_transitions);
if (consequent_transitions.size === 0) {
@ -1383,7 +1384,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
});
} else {
alternate_transitions.add(transition);
transition.finished(() => {
transition.f(() => {
alternate_transitions.delete(transition);
remove_in_transitions(alternate_transitions);
if (alternate_transitions.size === 0) {
@ -1395,8 +1396,8 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
const if_effect = render_effect(
() => {
const result = !!condition_fn();
if (block.current !== result || !has_mounted) {
block.current = result;
if (block.c !== result || !has_mounted) {
block.c = result;
if (has_mounted) {
if (result) {
remove_in_transitions(alternate_transitions);
@ -1454,7 +1455,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
remove(consequent_dom);
consequent_dom = null;
}
if (block.current) {
if (block.c) {
consequent_fn(anchor_node);
if (!has_mounted_branch) {
// Restore previous fragment so that Svelte continues to operate in hydration mode
@ -1462,8 +1463,8 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
has_mounted_branch = true;
}
}
consequent_dom = block.dom;
block.dom = null;
consequent_dom = block.d;
block.d = null;
},
block,
true
@ -1475,7 +1476,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
remove(alternate_dom);
alternate_dom = null;
}
if (!block.current) {
if (!block.c) {
if (alternate_fn !== null) {
alternate_fn(anchor_node);
}
@ -1485,8 +1486,8 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
has_mounted_branch = true;
}
}
alternate_dom = block.dom;
block.dom = null;
alternate_dom = block.d;
block.d = null;
},
block,
true
@ -1501,7 +1502,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
destroy_signal(consequent_effect);
destroy_signal(alternate_effect);
});
block.effect = if_effect;
block.e = if_effect;
}
export { if_block as if };
@ -1520,10 +1521,10 @@ export function head(render_fn) {
try {
const head_effect = render_effect(
() => {
const current = block.dom;
const current = block.d;
if (current !== null) {
remove(current);
block.dom = null;
block.d = null;
}
let anchor = null;
if (current_hydration_fragment === null) {
@ -1536,12 +1537,12 @@ export function head(render_fn) {
false
);
push_destroy_fn(head_effect, () => {
const current = block.dom;
const current = block.d;
if (current !== null) {
remove(current);
}
});
block.effect = head_effect;
block.e = head_effect;
} finally {
set_current_hydration_fragment(previous_hydration_fragment);
}
@ -1554,7 +1555,7 @@ export function head(render_fn) {
* @returns {void}
*/
function swap_block_dom(block, from, to) {
const dom = block.dom;
const dom = block.d;
if (is_array(dom)) {
for (let i = 0; i < dom.length; i++) {
if (dom[i] === from) {
@ -1563,7 +1564,7 @@ function swap_block_dom(block, from, to) {
}
}
} else if (dom === from) {
block.dom = to;
block.d = to;
}
}
@ -1607,7 +1608,7 @@ export function element(anchor_node, tag_fn, render_fn, is_svg = false) {
: null;
const prev_element = element;
if (prev_element !== null) {
block.dom = null;
block.d = null;
}
element = next_element;
if (element !== null && render_fn !== null) {
@ -1629,7 +1630,7 @@ export function element(anchor_node, tag_fn, render_fn, is_svg = false) {
if (element !== null) {
insert(element, null, anchor_node);
if (has_prev_element) {
const parent_block = block.parent;
const parent_block = block.p;
swap_block_dom(parent_block, prev_element, element);
}
}
@ -1640,12 +1641,12 @@ export function element(anchor_node, tag_fn, render_fn, is_svg = false) {
push_destroy_fn(element_effect, () => {
if (element !== null) {
remove(element);
block.dom = null;
block.d = null;
element = null;
}
destroy_signal(render_effect_signal);
});
block.effect = element_effect;
block.e = element_effect;
}
/**
@ -1664,26 +1665,26 @@ export function component(anchor_node, component_fn, render_fn) {
/** @type {null | ((props: P) => void)} */
let component = null;
block.transition =
block.r =
/**
* @param {import('./types.js').Transition} transition
* @returns {void}
*/
(transition) => {
const render = /** @type {import('./types.js').Render} */ (current_render);
const transitions = render.transitions;
const transitions = render.s;
transitions.add(transition);
transition.finished(() => {
transition.f(() => {
transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) {
if (render.effect !== null) {
if (render.dom !== null) {
remove(render.dom);
render.dom = null;
if (render.e !== null) {
if (render.d !== null) {
remove(render.d);
render.d = null;
}
destroy_signal(render.effect);
render.effect = null;
destroy_signal(render.e);
render.e = null;
}
}
});
@ -1691,29 +1692,29 @@ export function component(anchor_node, component_fn, render_fn) {
const create_render_effect = () => {
/** @type {import('./types.js').Render} */
const render = {
dom: null,
effect: null,
transitions: new Set(),
prev: current_render
d: null,
e: null,
s: new Set(),
p: current_render
};
// Managed effect
const effect = render_effect(
() => {
const current = block.dom;
const current = block.d;
if (current !== null) {
remove(current);
block.dom = null;
block.d = null;
}
if (component) {
render_fn(component);
}
render.dom = block.dom;
block.dom = null;
render.d = block.d;
block.d = null;
},
block,
true
);
render.effect = effect;
render.e = effect;
current_render = render;
};
const render = () => {
@ -1722,14 +1723,15 @@ export function component(anchor_node, component_fn, render_fn) {
create_render_effect();
return;
}
const transitions = render.transitions;
const transitions = render.s;
remove_in_transitions(transitions);
if (transitions.size === 0) {
if (render.dom !== null) {
remove(render.dom);
render.dom = null;
if (render.d !== null) {
remove(render.d);
render.d = null;
}
if (render.effect) {
execute_effect(render.effect);
if (render.e) {
execute_effect(render.e);
} else {
create_render_effect();
}
@ -1752,18 +1754,18 @@ export function component(anchor_node, component_fn, render_fn) {
push_destroy_fn(component_effect, () => {
let render = current_render;
while (render !== null) {
const dom = render.dom;
const dom = render.d;
if (dom !== null) {
remove(dom);
}
const effect = render.effect;
const effect = render.e;
if (effect !== null) {
destroy_signal(effect);
}
render = render.prev;
render = render.p;
}
});
block.effect = component_effect;
block.e = component_effect;
}
/**
@ -1791,26 +1793,26 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
/** @type {unknown} */
let error = UNINITIALIZED;
let pending = false;
block.transition =
block.r =
/**
* @param {import('./types.js').Transition} transition
* @returns {void}
*/
(transition) => {
const render = /** @type {import('./types.js').Render} */ (current_render);
const transitions = render.transitions;
const transitions = render.s;
transitions.add(transition);
transition.finished(() => {
transition.f(() => {
transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) {
if (render.effect !== null) {
if (render.dom !== null) {
remove(render.dom);
render.dom = null;
if (render.e !== null) {
if (render.d !== null) {
remove(render.d);
render.d = null;
}
destroy_signal(render.effect);
render.effect = null;
destroy_signal(render.e);
render.e = null;
}
}
});
@ -1818,35 +1820,38 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
const create_render_effect = () => {
/** @type {import('./types.js').Render} */
const render = {
dom: null,
effect: null,
transitions: new Set(),
prev: current_render
d: null,
e: null,
s: new Set(),
p: current_render
};
const effect = render_effect(
() => {
if (error === UNINITIALIZED) {
if (resolved_value === UNINITIALIZED) {
block.pending = true;
// pending = true
block.n = true;
if (pending_fn !== null) {
pending_fn(anchor_node);
}
} else if (then_fn !== null) {
block.pending = false;
// pending = false
block.n = false;
then_fn(anchor_node, resolved_value);
}
} else if (catch_fn !== null) {
block.pending = false;
// pending = false
block.n = false;
catch_fn(anchor_node, error);
}
render.dom = block.dom;
block.dom = null;
render.d = block.d;
block.d = null;
},
block,
true,
true
);
render.effect = effect;
render.e = effect;
current_render = render;
};
const render = () => {
@ -1855,15 +1860,15 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
create_render_effect();
return;
}
const transitions = render.transitions;
const transitions = render.s;
remove_in_transitions(transitions);
if (transitions.size === 0) {
if (render.dom !== null) {
remove(render.dom);
render.dom = null;
if (render.d !== null) {
remove(render.d);
render.d = null;
}
if (render.effect) {
execute_effect(render.effect);
if (render.e) {
execute_effect(render.e);
} else {
create_render_effect();
}
@ -1918,18 +1923,18 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
let render = current_render;
latest_token = {};
while (render !== null) {
const dom = render.dom;
const dom = render.d;
if (dom !== null) {
remove(dom);
}
const effect = render.effect;
const effect = render.e;
if (effect !== null) {
destroy_signal(effect);
}
render = render.prev;
render = render.p;
}
});
block.effect = await_effect;
block.e = await_effect;
}
export { await_block as await };
@ -1950,26 +1955,26 @@ export function key(anchor_node, key, render_fn) {
/** @type {V | typeof UNINITIALIZED} */
let key_value = UNINITIALIZED;
let mounted = false;
block.transition =
block.r =
/**
* @param {import('./types.js').Transition} transition
* @returns {void}
*/
(transition) => {
const render = /** @type {import('./types.js').Render} */ (current_render);
const transitions = render.transitions;
const transitions = render.s;
transitions.add(transition);
transition.finished(() => {
transition.f(() => {
transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) {
if (render.effect !== null) {
if (render.dom !== null) {
remove(render.dom);
render.dom = null;
if (render.e !== null) {
if (render.d !== null) {
remove(render.d);
render.d = null;
}
destroy_signal(render.effect);
render.effect = null;
destroy_signal(render.e);
render.e = null;
}
}
});
@ -1977,22 +1982,22 @@ export function key(anchor_node, key, render_fn) {
const create_render_effect = () => {
/** @type {import('./types.js').Render} */
const render = {
dom: null,
effect: null,
transitions: new Set(),
prev: current_render
d: null,
e: null,
s: new Set(),
p: current_render
};
const effect = render_effect(
() => {
render_fn(anchor_node);
render.dom = block.dom;
block.dom = null;
render.d = block.d;
block.d = null;
},
block,
true,
true
);
render.effect = effect;
render.e = effect;
current_render = render;
};
const render = () => {
@ -2001,15 +2006,15 @@ export function key(anchor_node, key, render_fn) {
create_render_effect();
return;
}
const transitions = render.transitions;
const transitions = render.s;
remove_in_transitions(transitions);
if (transitions.size === 0) {
if (render.dom !== null) {
remove(render.dom);
render.dom = null;
if (render.d !== null) {
remove(render.d);
render.d = null;
}
if (render.effect) {
execute_effect(render.effect);
if (render.e) {
execute_effect(render.e);
} else {
create_render_effect();
}
@ -2036,18 +2041,18 @@ export function key(anchor_node, key, render_fn) {
push_destroy_fn(key_effect, () => {
let render = current_render;
while (render !== null) {
const dom = render.dom;
const dom = render.d;
if (dom !== null) {
remove(dom);
}
const effect = render.effect;
const effect = render.e;
if (effect !== null) {
destroy_signal(effect);
}
render = render.prev;
render = render.p;
}
});
block.effect = key_effect;
block.e = key_effect;
}
/**
@ -2055,7 +2060,7 @@ export function key(anchor_node, key, render_fn) {
* @returns {Text | Element | Comment}
*/
function get_first_element(block) {
const current = block.dom;
const current = block.d;
if (is_array(current)) {
for (let i = 0; i < current.length; i++) {
const node = current[i];
@ -2076,17 +2081,17 @@ function get_first_element(block) {
*/
export function update_each_item_block(block, item, index, type) {
if ((type & EACH_ITEM_REACTIVE) !== 0) {
set_signal_value(block.item, item);
set_signal_value(block.v, item);
}
const transitions = block.transitions;
const transitions = block.s;
const index_is_reactive = (type & EACH_INDEX_REACTIVE) !== 0;
// Handle each item animations
if (transitions !== null && (type & EACH_KEYED) !== 0) {
let prev_index = block.index;
let prev_index = block.i;
if (index_is_reactive) {
prev_index = /** @type {import('./types.js').Signal<number>} */ (prev_index).v;
}
const items = block.parent.items;
const items = block.p.v;
if (prev_index !== index && /** @type {number} */ (index) < items.length) {
const from_dom = /** @type {Element} */ (get_first_element(block));
const from = from_dom.getBoundingClientRect();
@ -2096,9 +2101,9 @@ export function update_each_item_block(block, item, index, type) {
}
}
if (index_is_reactive) {
set_signal_value(/** @type {import('./types.js').Signal<number>} */ (block.index), index);
set_signal_value(/** @type {import('./types.js').Signal<number>} */ (block.i), index);
} else {
block.index = index;
block.i = index;
}
}
@ -2115,18 +2120,18 @@ export function destroy_each_item_block(
apply_transitions,
controlled = false
) {
const transitions = block.transitions;
const transitions = block.s;
if (apply_transitions && transitions !== null) {
trigger_transitions(transitions, 'out');
if (transition_block !== null) {
transition_block.push(block);
}
} else {
const dom = block.dom;
const dom = block.d;
if (!controlled && dom !== null) {
remove(dom);
}
destroy_signal(/** @type {import('./types.js').EffectSignal} */ (block.effect));
destroy_signal(/** @type {import('./types.js').EffectSignal} */ (block.e));
}
}
@ -2146,12 +2151,12 @@ export function each_item_block(item, key, index, render_fn, flags) {
const effect = render_effect(
/** @param {import('./types.js').EachItemBlock} block */
(block) => {
render_fn(null, block.item, block.index);
render_fn(null, block.v, block.i);
},
block,
true
);
block.effect = effect;
block.e = effect;
return block;
}
@ -2182,23 +2187,23 @@ function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, re
/** @type {null | import('./types.js').EffectSignal} */
let render = null;
block.transition =
block.r =
/** @param {import('./types.js').Transition} transition */
(transition) => {
const fallback = /** @type {import('./types.js').Render} */ (current_fallback);
const transitions = fallback.transitions;
const transitions = fallback.s;
transitions.add(transition);
transition.finished(() => {
transition.f(() => {
transitions.delete(transition);
remove_in_transitions(transitions);
if (transitions.size === 0) {
if (fallback.effect !== null) {
if (fallback.dom !== null) {
remove(fallback.dom);
fallback.dom = null;
if (fallback.e !== null) {
if (fallback.d !== null) {
remove(fallback.d);
fallback.d = null;
}
destroy_signal(fallback.effect);
fallback.effect = null;
destroy_signal(fallback.e);
fallback.e = null;
}
}
});
@ -2206,33 +2211,33 @@ function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, re
const create_fallback_effect = () => {
/** @type {import('./types.js').Render} */
const fallback = {
dom: null,
effect: null,
transitions: new Set(),
prev: current_fallback
d: null,
e: null,
s: new Set(),
p: current_fallback
};
// Managed effect
const effect = render_effect(
() => {
const dom = block.dom;
const dom = block.d;
if (dom !== null) {
remove(dom);
block.dom = null;
block.d = null;
}
let anchor = block.anchor;
const is_controlled = (block.flags & EACH_IS_CONTROLLED) !== 0;
let anchor = block.a;
const is_controlled = (block.f & EACH_IS_CONTROLLED) !== 0;
if (is_controlled) {
anchor = empty();
block.anchor.appendChild(anchor);
block.a.appendChild(anchor);
}
/** @type {(anchor: Node) => void} */ (fallback_fn)(anchor);
fallback.dom = block.dom;
block.dom = null;
fallback.d = block.d;
block.d = null;
},
block,
true
);
fallback.effect = effect;
fallback.e = effect;
current_fallback = fallback;
};
const each = render_effect(
@ -2249,16 +2254,16 @@ function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, re
}
if (fallback_fn !== null) {
if (array.length === 0) {
if (block.items.length !== 0 || render === null) {
if (block.v.length !== 0 || render === null) {
create_fallback_effect();
}
} else if (block.items.length === 0 && current_fallback !== null) {
} else if (block.v.length === 0 && current_fallback !== null) {
const fallback = current_fallback;
const transitions = fallback.transitions;
const transitions = fallback.s;
if (transitions.size === 0) {
if (fallback.dom !== null) {
remove(fallback.dom);
fallback.dom = null;
if (fallback.d !== null) {
remove(fallback.d);
fallback.d = null;
}
} else {
trigger_transitions(transitions, 'out');
@ -2275,35 +2280,35 @@ function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, re
render = render_effect(
/** @param {import('./types.js').EachBlock} block */
(block) => {
const flags = block.flags;
const flags = block.f;
const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;
const anchor_node = block.anchor;
const anchor_node = block.a;
reconcile_fn(array, block, anchor_node, is_controlled, render_fn, flags, true, keys);
},
block,
true
);
push_destroy_fn(each, () => {
const flags = block.flags;
const flags = block.f;
const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;
const anchor_node = block.anchor;
const anchor_node = block.a;
let fallback = current_fallback;
while (fallback !== null) {
const dom = fallback.dom;
const dom = fallback.d;
if (dom !== null) {
remove(dom);
}
const effect = fallback.effect;
const effect = fallback.e;
if (effect !== null) {
destroy_signal(effect);
}
fallback = fallback.prev;
fallback = fallback.p;
}
// Clear the array
reconcile_fn([], block, anchor_node, is_controlled, render_fn, flags, false, keys);
destroy_signal(/** @type {import('./types.js').EffectSignal} */ (render));
});
block.effect = each;
block.e = each;
}
/**
@ -3071,7 +3076,7 @@ export function mount(component, options) {
init_operations();
const registered_events = new Set();
const container = options.target;
const block = create_root_block(container, options.intro || false);
const block = create_root_block(options.intro || false);
const first_child = /** @type {ChildNode} */ (container.firstChild);
const hydration_fragment = get_hydration_fragment(first_child);
const previous_hydration_fragment = current_hydration_fragment;
@ -3094,7 +3099,7 @@ export function mount(component, options) {
push({});
/** @type {import('../client/types.js').ComponentContext} */ (
current_component_context
).context = options.context;
).c = options.context;
}
// @ts-expect-error the public typings are not what the actual function looks like
accessors = component(anchor, options.props || {}, options.events || {});
@ -3105,7 +3110,7 @@ export function mount(component, options) {
block,
true
);
block.effect = effect;
block.e = effect;
} catch (error) {
if (options.recover !== false && hydration_fragment !== null) {
// eslint-disable-next-line no-console
@ -3153,14 +3158,14 @@ export function mount(component, options) {
container.removeEventListener(event_name, bound_event_listener);
}
root_event_handles.delete(event_handle);
const dom = block.dom;
const dom = block.d;
if (dom !== null) {
remove(dom);
}
if (hydration_fragment !== null) {
remove(hydration_fragment);
}
destroy_signal(/** @type {import('./types.js').EffectSignal} */ (block.effect));
destroy_signal(/** @type {import('./types.js').EffectSignal} */ (block.e));
}
];
}
@ -3196,8 +3201,8 @@ export function snippet_effect(create_snippet) {
render_effect(() => {
create_snippet();
return () => {
if (block.dom !== null) {
remove(block.dom);
if (block.d !== null) {
remove(block.d);
}
};
}, block);
@ -3233,57 +3238,3 @@ function get_root_for_style(node) {
}
return /** @type {Document} */ (node.ownerDocument);
}
/**
* @param {string} message
* @param {string} filename
* @param {Array<{ line: number; highlight: boolean; source: string }>} [code_highlights]
* @returns {void}
*/
export function compile_error(message, filename, code_highlights) {
// Construct error page
const page = document.createElement('div');
const container = document.createElement('div');
const pre = document.createElement('pre');
const h1 = document.createElement('h1');
const h2 = document.createElement('h2');
const p = document.createElement('p');
h1.textContent = 'Compilation Error';
h2.textContent = message;
p.textContent = filename;
pre.appendChild(h1);
pre.appendChild(h2);
if (code_highlights) {
const code_container = document.createElement('div');
for (const line of code_highlights) {
const code_line = document.createElement('div');
const code_line_number = document.createElement('span');
code_line_number.textContent = String(line.line);
const code_source = document.createElement('span');
code_source.textContent = line.source;
if (line.highlight) {
code_line.style.cssText = 'padding:8px;background:#333;color:#fff';
} else {
code_line.style.cssText = 'padding:8px;background:#000;color:#999';
}
code_line_number.style.cssText = 'color:#888;padding:0 15px 0 5px;text-align:right;';
code_line.appendChild(code_line_number);
code_line.appendChild(code_source);
code_container.appendChild(code_line);
}
pre.appendChild(code_container);
}
h1.style.cssText = 'color:#ff5555;font-weight:normal;margin-top:0;padding:0;font-size:20px;';
h2.style.cssText =
'color:#ccc;font-weight:normal;margin-top:0;padding:0;font-size:16px;white-space:normal;';
p.style.cssText = 'color: #999;';
page.style.cssText =
'z-index:9999;margin:0;position:fixed;top: 0;left: 0;height:100%;width:100%;background:rgba(0,0,0,0.66)';
container.style.cssText = `background:#181818;margin:30px auto;padding:25px 40px;position:relative;color:#d8d8d8;border-radius:6px 6px 8px 8px;width:800px;font-family:'SF Mono', SFMono-Regular, ui-monospace,'DejaVu Sans Mono', Menlo, Consolas, monospace;;border-top:8px solid #ff5555;`;
pre.appendChild(p);
container.appendChild(pre);
page.appendChild(container);
document.body.appendChild(page);
// eslint-disable-next-line no-console
console.error('[Compilation Error] ' + message);
}

@ -94,15 +94,24 @@ export function set_is_ssr(ssr) {
export function create_component_context(props) {
const parent = current_component_context;
return {
effects: null,
props,
parent,
accessors: null,
context: null,
immutable: false,
mounted: false,
runes: false,
update_callbacks: null
// accessors
a: null,
// context
c: null,
// effects
e: null,
// immutable
i: false,
// mounted
m: false,
// parent
p: parent,
// props
s: props,
// runes
r: false,
// update_callbacks
u: null
};
}
@ -112,7 +121,7 @@ export function create_component_context(props) {
*/
function is_runes(context) {
const component_context = context || current_component_context;
return component_context !== null && component_context.runes;
return component_context !== null && component_context.r;
}
/**
@ -139,14 +148,19 @@ function default_equals(a, b) {
* @returns {import('./types.js').SourceSignal<V>}
*/
function create_source_signal(flags, value) {
return {
const source = {
// consumers
c: null,
// We can remove this if we get rid of beforeUpdate/afterUpdate
x: null,
// equals
e: null,
// flags
f: flags,
v: value
// value
v: value,
// context: We can remove this if we get rid of beforeUpdate/afterUpdate
x: null
};
return source;
}
/**
@ -158,16 +172,26 @@ function create_source_signal(flags, value) {
*/
function create_computation_signal(flags, value, block) {
return {
// block
b: block,
// consumers
c: null,
x: null,
// destroy
d: null,
y: null,
// equals
e: null,
// flags
f: flags,
// init
i: null,
// references
r: null,
v: value
// value
v: value,
// context: We can remove this if we get rid of beforeUpdate/afterUpdate
x: null,
// destroy
y: null
};
}
@ -252,8 +276,9 @@ function execute_signal_fn(signal) {
current_untracking = false;
// Render effects are invoked when the UI is about to be updated - run beforeUpdate at that point
if (is_render_effect && current_component_context?.update_callbacks != null) {
current_component_context.update_callbacks.execute();
if (is_render_effect && current_component_context?.u != null) {
// update_callbacks.execute()
current_component_context.u.e();
}
try {
@ -978,12 +1003,12 @@ export function set_signal_value(signal, value) {
// then we will need to manually invoke the beforeUpdate/afterUpdate logic.
// TODO: should we put this being a is_runes check and only run it in non-runes mode?
if (current_effect === null && current_queued_pre_and_render_effects.length === 0) {
const update_callbacks = component_context?.update_callbacks;
const update_callbacks = component_context?.u;
if (update_callbacks != null) {
update_callbacks.before.forEach(/** @param {any} c */ (c) => c());
update_callbacks.b.forEach(/** @param {any} c */ (c) => c());
const managed = managed_effect(() => {
destroy_signal(managed);
update_callbacks.after.forEach(/** @param {any} c */ (c) => c());
update_callbacks.a.forEach(/** @param {any} c */ (c) => c());
});
}
}
@ -1070,7 +1095,7 @@ function get_equals_method(equals) {
return equals;
}
const context = current_component_context;
if (context && !context.immutable) {
if (context && !context.i) {
return safe_equal;
}
return default_equals;
@ -1126,7 +1151,7 @@ export function user_effect(init) {
const apply_component_effect_heuristics =
current_effect.f & RENDER_EFFECT &&
current_component_context !== null &&
!current_component_context.mounted;
!current_component_context.m;
const effect = internal_create_effect(
EFFECT,
init,
@ -1136,11 +1161,10 @@ export function user_effect(init) {
);
if (apply_component_effect_heuristics) {
let effects = /** @type {import('./types.js').ComponentContext} */ (current_component_context)
.effects;
.e;
if (effects === null) {
effects = /** @type {import('./types.js').ComponentContext} */ (
current_component_context
).effects = [];
effects = /** @type {import('./types.js').ComponentContext} */ (current_component_context).e =
[];
}
effects.push(effect);
}
@ -1350,7 +1374,7 @@ export function prop_source(props_obj, key, default_value, call_default_value) {
// Needs special equality checking because the prop in the
// parent could be changed through `foo.bar = 'new value'`.
const immutable = /** @type {import('./types.js').ComponentContext} */ (current_component_context)
.immutable;
.i;
let ignore_next1 = false;
let ignore_next2 = false;
@ -1462,10 +1486,10 @@ export function get_or_init_context_map() {
if (component_context === null) {
throw new Error('Context can only be used during component initialisation.');
}
let context_map = component_context.context;
let context_map = component_context.c;
if (context_map === null) {
const parent_context = get_parent_context(component_context);
context_map = component_context.context = new Map(parent_context || undefined);
context_map = component_context.c = new Map(parent_context || undefined);
}
return context_map;
}
@ -1475,13 +1499,13 @@ export function get_or_init_context_map() {
* @returns {Map<unknown, unknown> | null}
*/
function get_parent_context(component_context) {
let parent = component_context.parent;
let parent = component_context.p;
while (parent !== null) {
const context_map = parent.context;
const context_map = parent.c;
if (context_map !== null) {
return context_map;
}
parent = parent.parent;
parent = parent.p;
}
return null;
}
@ -1656,8 +1680,8 @@ export function onDestroy(fn) {
*/
export function push(props, runes = false, immutable = false) {
const context_stack_item = create_component_context(props);
context_stack_item.runes = runes;
context_stack_item.immutable = immutable;
context_stack_item.r = runes;
context_stack_item.i = immutable;
current_component_context = context_stack_item;
}
@ -1669,16 +1693,16 @@ export function pop(accessors) {
const context_stack_item = current_component_context;
if (context_stack_item !== null) {
if (accessors !== undefined) {
context_stack_item.accessors = accessors;
context_stack_item.a = accessors;
}
const effects = context_stack_item.effects;
const effects = context_stack_item.e;
if (effects !== null) {
context_stack_item.effects = null;
context_stack_item.e = null;
for (let i = 0; i < effects.length; i++) {
schedule_effect(effects[i], false);
}
}
current_component_context = context_stack_item.parent;
context_stack_item.mounted = true;
current_component_context = context_stack_item.p;
context_stack_item.m = true;
}
}

@ -267,7 +267,7 @@ function create_transition(dom, init, direction, effect) {
let cancelled = false;
const create_animation = () => {
let payload = /** @type {import('./types.js').TransitionPayload} */ (transition.payload);
let payload = /** @type {import('./types.js').TransitionPayload} */ (transition.p);
if (typeof payload === 'function') {
// @ts-ignore
payload = payload({ direction: curr_direction });
@ -332,12 +332,14 @@ function create_transition(dom, init, direction, effect) {
/** @type {import('./types.js').Transition} */
const transition = {
effect,
init,
payload: null,
e: effect,
i: init,
// payload
p: null,
// finished
/** @param {() => void} fn */
finished(fn) {
f(fn) {
subs.push(fn);
},
in() {
@ -353,7 +355,8 @@ function create_transition(dom, init, direction, effect) {
}
/** @type {Animation | TickAnimation} */ (animation).play();
},
out() {
// out
o() {
const needs_reverse = direction === 'both' && curr_direction !== 'out';
curr_direction = 'out';
if (animation === null || cancelled) {
@ -367,18 +370,20 @@ function create_transition(dom, init, direction, effect) {
/** @type {Animation | TickAnimation} */ (animation).play();
}
},
cancel() {
// cancel
c() {
/** @type {Animation | TickAnimation} */ (animation).cancel();
cancelled = true;
},
cleanup() {
// cleanup
x() {
for (const sub of subs) {
sub();
}
subs = [];
},
direction,
dom
r: direction,
d: dom
};
return transition;
}
@ -388,13 +393,14 @@ function create_transition(dom, init, direction, effect) {
* @returns {boolean}
*/
function is_transition_block(block) {
const type = block.t;
return (
block.type === IF_BLOCK ||
block.type === EACH_ITEM_BLOCK ||
block.type === KEY_BLOCK ||
block.type === AWAIT_BLOCK ||
block.type === DYNAMIC_COMPONENT_BLOCK ||
(block.type === EACH_BLOCK && block.items.length === 0)
type === IF_BLOCK ||
type === EACH_ITEM_BLOCK ||
type === KEY_BLOCK ||
type === AWAIT_BLOCK ||
type === DYNAMIC_COMPONENT_BLOCK ||
(type === EACH_BLOCK && block.v.length === 0)
);
}
@ -418,26 +424,26 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
let transition_block = block;
while (transition_block !== null) {
if (is_transition_block(transition_block)) {
if (transition_block.type === EACH_ITEM_BLOCK) {
if (transition_block.t === EACH_ITEM_BLOCK) {
// Lazily apply the each block transition
transition_block.transition = each_item_transition;
transition_block = transition_block.parent;
} else if (transition_block.type === AWAIT_BLOCK && transition_block.pending) {
transition_block.r = each_item_transition;
transition_block = transition_block.p;
} else if (transition_block.t === AWAIT_BLOCK && transition_block.n /* pending */) {
skip_intro = false;
}
if (skip_intro) {
skip_intro = transition_block.effect === null;
skip_intro = transition_block.e === null;
}
if (!skip_intro || !global) {
break;
}
} else if (
transition_block.type === ROOT_BLOCK &&
(transition_block.effect !== null || transition_block.intro)
transition_block.t === ROOT_BLOCK &&
(transition_block.e !== null || transition_block.i)
) {
skip_intro = false;
}
transition_block = transition_block.parent;
transition_block = transition_block.p;
}
/** @type {import('./types.js').Transition} */
@ -464,7 +470,7 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
const show_intro = !skip_intro && (is_intro || direction === 'both');
if (show_intro) {
transition.payload = transition.init();
transition.p = transition.i();
}
const effect = managed_pre_effect(() => {
@ -478,15 +484,14 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
/** @type {import('./types.js').Block | null} */
let transition_block = block;
while (transition_block !== null) {
const parent = transition_block.parent;
const parent = transition_block.p;
if (is_transition_block(transition_block)) {
if (transition_block.transition !== null) {
transition_block.transition(transition);
if (transition_block.r !== null) {
transition_block.r(transition);
}
if (
parent === null ||
(!global &&
(transition_block.type !== IF_BLOCK || parent.type !== IF_BLOCK || parent.current))
(!global && (transition_block.t !== IF_BLOCK || parent.t !== IF_BLOCK || parent.c))
) {
break;
}
@ -499,7 +504,7 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
if (direction === 'key') {
effect(() => {
return () => {
transition.cleanup();
transition.x();
};
});
}
@ -509,9 +514,10 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
* @param {Set<import('./types.js').Transition>} transitions
*/
export function remove_in_transitions(transitions) {
for (let other of transitions) {
if (other.direction === 'in') {
transitions.delete(other);
for (let transition of transitions) {
const direction = transition.r;
if (direction === 'in') {
transitions.delete(transition);
}
}
}
@ -526,27 +532,27 @@ export function trigger_transitions(transitions, target_direction, from) {
/** @type {Array<() => void>} */
const outros = [];
for (const transition of transitions) {
const direction = transition.direction;
const direction = transition.r;
if (target_direction === 'in') {
if (direction === 'in' || direction === 'both') {
transition.in();
} else {
transition.cancel();
transition.c();
}
transition.dom.inert = false;
mark_subtree_inert(transition.effect, false);
transition.d.inert = false;
mark_subtree_inert(transition.e, false);
} else if (target_direction === 'key') {
if (direction === 'key') {
transition.payload = transition.init(/** @type {DOMRect} */ (from));
transition.p = transition.i(/** @type {DOMRect} */ (from));
transition.in();
}
} else {
if (direction === 'out' || direction === 'both') {
transition.payload = transition.init();
outros.push(transition.out);
transition.p = transition.i();
outros.push(transition.o);
}
transition.dom.inert = true;
mark_subtree_inert(transition.effect, true);
transition.d.inert = true;
mark_subtree_inert(transition.e, true);
}
}
if (outros.length > 0) {
@ -568,33 +574,33 @@ export function trigger_transitions(transitions, target_direction, from) {
*/
function each_item_transition(transition) {
const block = this;
const each_block = block.parent;
const is_controlled = (each_block.flags & EACH_IS_CONTROLLED) !== 0;
const each_block = block.p;
const is_controlled = (each_block.f & EACH_IS_CONTROLLED) !== 0;
// Disable optimization
if (is_controlled) {
const anchor = empty();
each_block.flags ^= EACH_IS_CONTROLLED;
append_child(/** @type {Element} */ (each_block.anchor), anchor);
each_block.anchor = anchor;
each_block.f ^= EACH_IS_CONTROLLED;
append_child(/** @type {Element} */ (each_block.a), anchor);
each_block.a = anchor;
}
if (transition.direction === 'key' && (each_block.flags & EACH_IS_ANIMATED) === 0) {
each_block.flags |= EACH_IS_ANIMATED;
if (transition.r === 'key' && (each_block.f & EACH_IS_ANIMATED) === 0) {
each_block.f |= EACH_IS_ANIMATED;
}
let transitions = block.transitions;
let transitions = block.s;
if (transitions === null) {
block.transitions = transitions = new Set();
block.s = transitions = new Set();
}
transition.finished(() => {
transition.f(() => {
if (transitions !== null) {
transitions.delete(transition);
if (transition.direction !== 'key') {
if (transition.r !== 'key') {
for (let other of transitions) {
if (other.direction === 'key' || other.direction === 'in') {
if (other.r === 'key' || other.r === 'in') {
transitions.delete(other);
}
}
if (transitions.size === 0) {
block.transitions = null;
block.s = null;
destroy_each_item_block(block, null, true);
}
}

@ -30,28 +30,42 @@ export type Store<V> = {
set(value: V): void;
};
// For all the core internal objects, we use signal character property strings.
// This not only reduces code-size and parsing, but it also improves the performance
// when the JS VM JITs the code.
export type ComponentContext = {
props: MaybeSignal<Record<string, unknown>>;
accessors: Record<string, any> | null;
effects: null | Array<EffectSignal>;
mounted: boolean;
parent: null | ComponentContext;
context: null | Map<unknown, unknown>;
immutable: boolean;
runes: boolean;
update_callbacks: null | {
before: Array<() => void>;
after: Array<() => void>;
execute: () => void;
/** props */
s: MaybeSignal<Record<string, unknown>>;
/** accessors */
a: Record<string, any> | null;
/** effectgs */
e: null | Array<EffectSignal>;
/** mounted */
m: boolean;
/** parent */
p: null | ComponentContext;
/** context */
c: null | Map<unknown, unknown>;
/** immutable */
i: boolean;
/** runes */
r: boolean;
/** update_callbacks */
u: null | {
/** before */
b: Array<() => void>;
/** after */
a: Array<() => void>;
/** execute */
e: () => void;
};
};
// For both SourceSignal and ComputationSignal, we use signal character property string.
// This now only reduces code-size and parsing, but it also improves the performance of the JIT compiler.
// It's likely not to have any real wins wwhen the JIT is disabled. Lastly, we keep two shapes rather than
// a single monomorphic shape to improve the memory usage. Source signals don't need the same shape as they
// simply don't do as much as computations (effects and derived signals). Thus we can improve the memory
// profile at the slight cost of some runtime performance.
// We keep two shapes rather than a single monomorphic shape to improve the memory usage.
// Source signals don't need the same shape as they simply don't do as much as computations
// (effects and derived signals). Thus we can improve the memory profile at the slight cost
// of some runtime performance.
export type SourceSignal<V = unknown> = {
/** consumers: Signals that read from the current signal */
@ -114,108 +128,177 @@ export type BlockType =
export type TemplateNode = Text | Element | Comment;
export type Transition = {
effect: EffectSignal;
payload: null | TransitionPayload;
init: (from?: DOMRect) => TransitionPayload;
finished: (fn: () => void) => void;
/** effect */
e: EffectSignal;
/** payload */
p: null | TransitionPayload;
/** init */
i: (from?: DOMRect) => TransitionPayload;
/** finished */
f: (fn: () => void) => void;
in: () => void;
out: () => void;
cancel: () => void;
cleanup: () => void;
direction: 'in' | 'out' | 'both' | 'key';
dom: HTMLElement;
/** out */
o: () => void;
/** cancel */
c: () => void;
/** cleanup */
x: () => void;
/** direction */
r: 'in' | 'out' | 'both' | 'key';
/** dom */
d: HTMLElement;
};
export type RootBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
container: Node;
intro: boolean;
parent: null;
transition: null | ((transition: Transition) => void);
type: typeof ROOT_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** intro */
i: boolean;
/** parent */
p: null;
/** transition */
r: null | ((transition: Transition) => void);
/** type */
t: typeof ROOT_BLOCK;
};
export type IfBlock = {
current: boolean;
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
parent: Block;
transition: null | ((transition: Transition) => void);
type: typeof IF_BLOCK;
/** current */
c: boolean;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** parent */
p: Block;
/** transition */
r: null | ((transition: Transition) => void);
/** type */
t: typeof IF_BLOCK;
};
export type KeyBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
parent: Block;
transition: null | ((transition: Transition) => void);
type: typeof KEY_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** parent */
p: Block;
/** transition */
r: null | ((transition: Transition) => void);
/** type */
t: typeof KEY_BLOCK;
};
export type HeadBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
parent: Block;
transition: null | ((transition: Transition) => void);
type: typeof HEAD_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** parent */
p: Block;
/** transition */
r: null | ((transition: Transition) => void);
/** type */
t: typeof HEAD_BLOCK;
};
export type DynamicElementBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
parent: Block;
transition: null | ((transition: Transition) => void);
type: typeof DYNAMIC_ELEMENT_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** parent */
p: Block;
/** transition */
r: null | ((transition: Transition) => void);
/** type */
t: typeof DYNAMIC_ELEMENT_BLOCK;
};
export type DynamicComponentBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
parent: Block;
transition: null | ((transition: Transition) => void);
type: typeof DYNAMIC_COMPONENT_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** parent */
p: Block;
/** transition */
r: null | ((transition: Transition) => void);
/** type */
t: typeof DYNAMIC_COMPONENT_BLOCK;
};
export type AwaitBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
parent: Block;
pending: boolean;
transition: null | ((transition: Transition) => void);
type: typeof AWAIT_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** parent */
p: Block;
/** pending */
n: boolean;
/** transition */
r: null | ((transition: Transition) => void);
/** type */
t: typeof AWAIT_BLOCK;
};
export type EachBlock = {
anchor: Element | Comment;
flags: number;
dom: null | TemplateNode | Array<TemplateNode>;
items: EachItemBlock[];
effect: null | ComputationSignal;
parent: Block;
transition: null | ((transition: Transition) => void);
transitions: Array<EachItemBlock>;
type: typeof EACH_BLOCK;
/** anchor */
a: Element | Comment;
/** flags */
f: number;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** items */
v: EachItemBlock[];
/** effewct */
e: null | ComputationSignal;
/** parent */
p: Block;
/** transition */
r: null | ((transition: Transition) => void);
/** transitions */
s: Array<EachItemBlock>;
/** type */
t: typeof EACH_BLOCK;
};
export type EachItemBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | ComputationSignal;
item: any | Signal<any>;
index: number | Signal<number>;
key: unknown;
parent: EachBlock;
transition: null | ((transition: Transition) => void);
transitions: null | Set<Transition>;
type: typeof EACH_ITEM_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | ComputationSignal;
/** item */
v: any | Signal<any>;
/** index */
i: number | Signal<number>;
/** key */
k: unknown;
/** parent */
p: EachBlock;
/** transition */
r: null | ((transition: Transition) => void);
/** transitions */
s: null | Set<Transition>;
/** type */
t: typeof EACH_ITEM_BLOCK;
};
export type SnippetBlock = {
dom: null | TemplateNode | Array<TemplateNode>;
parent: Block;
effect: null | ComputationSignal;
transition: null;
type: typeof SNIPPET_BLOCK;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** parent */
p: Block;
/** effect */
e: null | ComputationSignal;
/** transition */
r: null;
/** type */
t: typeof SNIPPET_BLOCK;
};
export type Block =
@ -264,10 +347,14 @@ export type StoreReferencesContainer = Record<
export type ActionPayload<P> = { destroy?: () => void; update?: (value: P) => void };
export type Render = {
dom: null | TemplateNode | Array<TemplateNode>;
effect: null | EffectSignal;
transitions: Set<Transition>;
prev: Render | null;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | EffectSignal;
/** transitions */
s: Set<Transition>;
/** prev */
p: Render | null;
};
export type Raf = {

@ -121,9 +121,8 @@ export function render(component, options) {
if (options.context) {
$.push({});
/** @type {import('../client/types.js').ComponentContext} */ (
$.current_component_context
).context = options.context;
/** @type {import('../client/types.js').ComponentContext} */ ($.current_component_context).c =
options.context;
}
component(payload, options.props, {}, {});
if (options.context) {

@ -140,7 +140,7 @@ export function createEventDispatcher() {
return (type, detail, options) => {
const $$events = /** @type {Record<string, Function | Function[]>} */ (
unwrap(component_context.props).$$events
unwrap(component_context.s).$$events
);
const events = $$events?.[/** @type {any} */ (type)];
@ -151,9 +151,9 @@ export function createEventDispatcher() {
const event = create_custom_event(/** @type {string} */ (type), detail, options);
for (const fn of callbacks) {
if (is_signal(fn)) {
get(fn).call(component_context.accessors, event);
get(fn).call(component_context.a, event);
} else {
fn.call(component_context.accessors, event);
fn.call(component_context.a, event);
}
}
return !event.defaultPrevented;
@ -167,17 +167,17 @@ function init_update_callbacks() {
let called_before = false;
let called_after = false;
/** @type {NonNullable<import('../internal/client/types.js').ComponentContext['update_callbacks']>} */
/** @type {NonNullable<import('../internal/client/types.js').ComponentContext['u']>} */
const update_callbacks = {
before: [],
after: [],
execute() {
b: [],
a: [],
e() {
if (!called_before) {
called_before = true;
// TODO somehow beforeUpdate ran twice on mount in Svelte 4 if it causes a render
// possibly strategy to get this back if needed: analyse beforeUpdate function for assignements to state,
// if yes, add a call to the component to force-run beforeUpdate once.
untrack(() => update_callbacks.before.forEach(/** @param {any} c */ (c) => c()));
untrack(() => update_callbacks.b.forEach(/** @param {any} c */ (c) => c()));
flush_local_render_effects();
// beforeUpdate can run again once if afterUpdate causes another update,
// but afterUpdate shouldn't be called again in that case to prevent infinite loops
@ -185,7 +185,7 @@ function init_update_callbacks() {
user_effect(() => {
called_before = false;
called_after = true;
untrack(() => update_callbacks.after.forEach(/** @param {any} c */ (c) => c()));
untrack(() => update_callbacks.a.forEach(/** @param {any} c */ (c) => c()));
// managed_effect so that it's not cleaned up when the parent effect is cleaned up
const managed = managed_effect(() => {
destroy_signal(managed);
@ -223,10 +223,10 @@ export function beforeUpdate(fn) {
throw new Error('beforeUpdate can only be used during component initialisation.');
}
if (component_context.update_callbacks === null) {
component_context.update_callbacks = init_update_callbacks();
if (component_context.u === null) {
component_context.u = init_update_callbacks();
}
component_context.update_callbacks.before.push(fn);
component_context.u.b.push(fn);
}
/**
@ -247,10 +247,10 @@ export function afterUpdate(fn) {
throw new Error('afterUpdate can only be used during component initialisation.');
}
if (component_context.update_callbacks === null) {
component_context.update_callbacks = init_update_callbacks();
if (component_context.u === null) {
component_context.u = init_update_callbacks();
}
component_context.update_callbacks.after.push(fn);
component_context.u.a.push(fn);
}
// TODO bring implementations in here

Loading…
Cancel
Save