Socket
Socket
Sign inDemoInstall

svelte

Package Overview
Dependencies
18
Maintainers
3
Versions
617
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.0.0-next.84 to 5.0.0-next.85

2

package.json

@@ -5,3 +5,3 @@ {

"license": "MIT",
"version": "5.0.0-next.84",
"version": "5.0.0-next.85",
"type": "module",

@@ -8,0 +8,0 @@ "types": "./types/index.d.ts",

@@ -52,2 +52,9 @@ import { walk } from 'zimmerframe';

// these should be set by create_block - if they're called outside, it's a bug
get before_init() {
/** @type {any[]} */
const a = [];
a.push = () =>
error(null, 'INTERNAL', 'before_init.push should not be called outside create_block');
return a;
},
get init() {

@@ -54,0 +61,0 @@ /** @type {any[]} */

@@ -33,2 +33,4 @@ import type {

/** Stuff that happens before the render effect(s) */
readonly before_init: Statement[];
/** Stuff that happens before the render effect(s) */
readonly init: Statement[];

@@ -35,0 +37,0 @@ /** Stuff that happens inside the render effect */

@@ -374,3 +374,3 @@ import { get_rune } from '../../../scope.js';

...node,
expression: b.call('$.pre_effect', /** @type {import('estree').Expression} */ (func))
expression: b.call('$.user_pre_effect', /** @type {import('estree').Expression} */ (func))
};

@@ -377,0 +377,0 @@ }

import { is_promise } from '../../../common.js';
import { hydrate_block_anchor } from '../hydration.js';
import { remove } from '../reconciler.js';

@@ -26,4 +25,2 @@ import {

hydrate_block_anchor(anchor);
/** @type {any} */

@@ -30,0 +27,0 @@ let input;

import { namespace_svg } from '../../../../constants.js';
import { hydrate_nodes, hydrate_block_anchor, hydrating } from '../hydration.js';
import { hydrate_anchor, hydrate_nodes, hydrating } from '../hydration.js';
import { empty } from '../operations.js';

@@ -15,4 +15,2 @@ import { render_effect } from '../../reactivity/effects.js';

export function css_props(anchor, is_html, props, component) {
hydrate_block_anchor(anchor);
/** @type {HTMLElement | SVGElement} */

@@ -28,3 +26,5 @@ let element;

// ... and the child(ren) of the css props element is also surround by a ssr comment
component_anchor = /** @type {Comment} */ (element.firstChild);
component_anchor = /** @type {Comment} */ (
hydrate_anchor(/** @type {Comment} */ (element.firstChild))
);
} else {

@@ -31,0 +31,0 @@ if (is_html) {

@@ -9,9 +9,3 @@ import {

} from '../../../../constants.js';
import {
hydrate_nodes,
hydrate_block_anchor,
hydrating,
set_hydrating,
update_hydrate_nodes
} from '../hydration.js';
import { hydrate_anchor, hydrate_nodes, hydrating, set_hydrating } from '../hydration.js';
import { empty } from '../operations.js';

@@ -50,11 +44,11 @@ import { insert, remove } from '../reconciler.js';

* @param {Element | Comment} anchor The next sibling node, or the parent node if this is a 'controlled' block
* @param {number} flags
* @param {() => V[]} get_collection
* @param {number} flags
* @param {null | ((item: V) => string)} get_key
* @param {(anchor: null, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
* @param {null | ((anchor: Node | null) => void)} fallback_fn
* @param {(anchor: Node, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
* @param {null | ((anchor: Node) => void)} fallback_fn
* @param {typeof reconcile_indexed_array | reconcile_tracked_array} reconcile_fn
* @returns {void}
*/
function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, reconcile_fn) {
function each(anchor, flags, get_collection, get_key, render_fn, fallback_fn, reconcile_fn) {
/** @type {import('#client').EachState} */

@@ -64,7 +58,11 @@ var state = { flags, items: [] };

var is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;
hydrate_block_anchor(is_controlled ? /** @type {Node} */ (anchor.firstChild) : anchor);
if (is_controlled) {
var parent_node = /** @type {Element} */ (anchor);
parent_node.append((anchor = empty()));
anchor = hydrating
? /** @type {Comment | Text} */ (
hydrate_anchor(/** @type {Comment | Text} */ (parent_node.firstChild))
)
: parent_node.appendChild(empty());
}

@@ -121,10 +119,7 @@

// Hydrate block
var hydration_list = /** @type {import('#client').TemplateNode[]} */ (hydrate_nodes);
var hydrating_node = hydration_list[0];
/** @type {Node} */
var child_anchor = hydrate_nodes[0];
for (var i = 0; i < length; i++) {
var nodes = update_hydrate_nodes(hydrating_node);
if (nodes === null) {
if (child_anchor.nodeType !== 8 || /** @type {Comment} */ (child_anchor).data !== '[') {
// If `nodes` is null, then that means that the server rendered fewer items than what

@@ -137,14 +132,16 @@ // expected, so break out and continue appending non-hydrated items

b_items[i] = create_item(array[i], keys?.[i], i, render_fn, flags);
child_anchor = hydrate_anchor(child_anchor);
b_items[i] = create_item(child_anchor, array[i], keys?.[i], i, render_fn, flags);
child_anchor = /** @type {Comment} */ (child_anchor.nextSibling);
}
// TODO helperise this
hydrating_node = /** @type {import('#client').TemplateNode} */ (
/** @type {Node} */ (
/** @type {Node} */ (nodes[nodes.length - 1] || hydrating_node).nextSibling
).nextSibling
);
// remove excess nodes
if (length > 0) {
while (child_anchor !== anchor) {
var next = /** @type {import('#client').TemplateNode} */ (child_anchor.nextSibling);
/** @type {import('#client').TemplateNode} */ (child_anchor).remove();
child_anchor = next;
}
}
remove_excess_hydration_nodes(hydration_list, hydrating_node);
state.items = b_items;

@@ -164,3 +161,3 @@ }

fallback = render_effect(() => {
var dom = fallback_fn(hydrating ? null : anchor);
var dom = fallback_fn(anchor);

@@ -202,11 +199,11 @@ return () => {

* @param {Element | Comment} anchor
* @param {number} flags
* @param {() => V[]} get_collection
* @param {number} flags
* @param {null | ((item: V) => string)} get_key
* @param {(anchor: null, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
* @param {null | ((anchor: Node | null) => void)} fallback_fn
* @param {(anchor: Node, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
* @param {null | ((anchor: Node) => void)} [fallback_fn]
* @returns {void}
*/
export function each_keyed(anchor, get_collection, flags, get_key, render_fn, fallback_fn) {
each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, reconcile_tracked_array);
export function each_keyed(anchor, flags, get_collection, get_key, render_fn, fallback_fn = null) {
each(anchor, flags, get_collection, get_key, render_fn, fallback_fn, reconcile_tracked_array);
}

@@ -217,10 +214,10 @@

* @param {Element | Comment} anchor
* @param {number} flags
* @param {() => V[]} get_collection
* @param {number} flags
* @param {(anchor: null, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
* @param {null | ((anchor: Node | null) => void)} fallback_fn
* @param {(anchor: Node, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
* @param {null | ((anchor: Node) => void)} [fallback_fn]
* @returns {void}
*/
export function each_indexed(anchor, get_collection, flags, render_fn, fallback_fn) {
each(anchor, get_collection, flags, null, render_fn, fallback_fn, reconcile_indexed_array);
export function each_indexed(anchor, flags, get_collection, render_fn, fallback_fn = null) {
each(anchor, flags, get_collection, null, render_fn, fallback_fn, reconcile_indexed_array);
}

@@ -233,3 +230,3 @@

* @param {Element | Comment | Text} anchor
* @param {(anchor: null, item: V, index: number | import('#client').Source<number>) => void} render_fn
* @param {(anchor: Node, item: V, index: number | import('#client').Source<number>) => void} render_fn
* @param {number} flags

@@ -264,5 +261,4 @@ * @returns {void}

value = array[i];
item = create_item(value, null, i, render_fn, flags);
item = create_item(anchor, value, null, i, render_fn, flags);
b_items[i] = item;
insert_item(item, anchor);
}

@@ -292,3 +288,3 @@

* @param {Element | Comment | Text} anchor
* @param {(anchor: null, item: V, index: number | import('#client').Source<number>) => void} render_fn
* @param {(anchor: Node, item: V, index: number | import('#client').Source<number>) => void} render_fn
* @param {number} flags

@@ -344,5 +340,4 @@ * @param {any[]} keys

while (start < b) {
item = create_item(array[start], keys[start], start, render_fn, flags);
item = create_item(anchor, array[start], keys[start], start, render_fn, flags);
b_items[start++] = item;
insert_item(item, anchor);
}

@@ -416,6 +411,7 @@ } else if (start === b) {

index = sources[b - start];
var insert = index === NEW_ITEM;
var should_insert = index === NEW_ITEM;
if (insert) {
item = create_item(array[b], keys[b], b, render_fn, flags);
if (should_insert) {
if (last_item !== undefined) anchor = get_first_child(last_item);
item = create_item(anchor, array[b], keys[b], b, render_fn, flags);
} else {

@@ -426,7 +422,7 @@ item = b_items[b];

}
}
if (insert || (moved && index !== LIS_ITEM)) {
last_sibling = last_item === undefined ? anchor : get_first_child(last_item);
anchor = insert_item(item, last_sibling);
if (moved && index !== LIS_ITEM) {
if (last_item !== undefined) anchor = get_first_child(last_item);
insert(/** @type {import('#client').Dom} */ (item.e.dom), anchor);
}
}

@@ -458,16 +454,2 @@

/**
* The server could have rendered more list items than the client specifies.
* In that case, we need to remove the remaining server-rendered nodes.
* @param {import('#client').TemplateNode[]} hydration_list
* @param {import('#client').TemplateNode | null} next_node
*/
function remove_excess_hydration_nodes(hydration_list, next_node) {
if (next_node === null) return;
var idx = hydration_list.indexOf(next_node);
if (idx !== -1 && hydration_list.length > idx + 1) {
remove(hydration_list.slice(idx));
}
}
/**
* Longest Increased Subsequence algorithm

@@ -547,14 +529,4 @@ * @param {Int32Array} a

* @param {import('#client').EachItem} item
* @param {Text | Element | Comment} anchor
* @returns {Text | Element | Comment}
*/
function insert_item(item, anchor) {
var current = /** @type {import('#client').Dom} */ (item.e.dom);
return insert(current, anchor);
}
/**
* @param {import('#client').EachItem} item
* @returns {Text | Element | Comment}
*/
function get_first_child(item) {

@@ -591,10 +563,11 @@ var current = item.e.dom;

* @template V
* @param {Node} anchor
* @param {V} value
* @param {unknown} key
* @param {number} index
* @param {(anchor: null, item: V, index: number | import('#client').Value<number>) => void} render_fn
* @param {(anchor: Node, item: V, index: number | import('#client').Value<number>) => void} render_fn
* @param {number} flags
* @returns {import('#client').EachItem}
*/
function create_item(value, key, index, render_fn, flags) {
function create_item(anchor, value, key, index, render_fn, flags) {
var each_item_not_reactive = (flags & EACH_ITEM_REACTIVE) === 0;

@@ -626,3 +599,3 @@

item.e = render_effect(() => {
var dom = render_fn(null, item.v, item.i);
var dom = render_fn(anchor, item.v, item.i);

@@ -629,0 +602,0 @@ return () => {

import { IS_ELSEIF } from '../../constants.js';
import { hydrate_nodes, hydrate_block_anchor, hydrating, set_hydrating } from '../hydration.js';
import { hydrate_nodes, hydrating, set_hydrating } from '../hydration.js';
import { remove } from '../reconciler.js';

@@ -26,4 +26,2 @@ import {

) {
hydrate_block_anchor(anchor);
/** @type {import('#client').Effect | null} */

@@ -30,0 +28,0 @@ let consequent_effect = null;

import { UNINITIALIZED } from '../../constants.js';
import { hydrate_block_anchor } from '../hydration.js';
import { remove } from '../reconciler.js';

@@ -15,4 +14,2 @@ import { pause_effect, render_effect } from '../../reactivity/effects.js';

export function key_block(anchor, get_key, render_fn) {
hydrate_block_anchor(anchor);
/** @type {V | typeof UNINITIALIZED} */

@@ -19,0 +16,0 @@ let key = UNINITIALIZED;

@@ -1,2 +0,1 @@

import { hydrate_block_anchor } from '../hydration.js';
import { pause_effect, render_effect } from '../../reactivity/effects.js';

@@ -17,4 +16,2 @@ import { remove } from '../reconciler.js';

export function component(anchor, get_component, render_fn) {
hydrate_block_anchor(anchor);
/** @type {C} */

@@ -21,0 +18,0 @@ let component;

import { namespace_svg } from '../../../../constants.js';
import { hydrate_nodes, hydrate_block_anchor, hydrating } from '../hydration.js';
import { hydrate_anchor, hydrate_nodes, hydrating } from '../hydration.js';
import { empty } from '../operations.js';

@@ -47,4 +47,2 @@ import {

hydrate_block_anchor(anchor);
/** @type {string | null} */

@@ -118,3 +116,3 @@ let tag;

var child_anchor = hydrating
? /** @type {Comment} */ (element.firstChild)
? element.firstChild && hydrate_anchor(/** @type {Comment} */ (element.firstChild))
: element.appendChild(empty());

@@ -121,0 +119,0 @@

@@ -1,2 +0,2 @@

import { hydrate_nodes, hydrating, set_hydrate_nodes, update_hydrate_nodes } from '../hydration.js';
import { hydrate_anchor, hydrate_nodes, hydrating, set_hydrate_nodes } from '../hydration.js';
import { empty } from '../operations.js';

@@ -7,3 +7,3 @@ import { render_effect } from '../../reactivity/effects.js';

/**
* @param {(anchor: Node | null) => import('#client').Dom | void} render_fn
* @param {(anchor: Node) => import('#client').Dom | void} render_fn
* @returns {void}

@@ -19,3 +19,9 @@ */

previous_hydrate_nodes = hydrate_nodes;
update_hydrate_nodes(document.head.firstChild);
let anchor = /** @type {import('#client').TemplateNode} */ (document.head.firstChild);
while (anchor.nodeType !== 8 || /** @type {Comment} */ (anchor).data !== '[') {
anchor = /** @type {import('#client').TemplateNode} */ (anchor.nextSibling);
}
anchor = /** @type {import('#client').TemplateNode} */ (hydrate_anchor(anchor));
}

@@ -35,3 +41,3 @@

dom = render_fn(hydrating ? null : anchor) ?? null;
dom = render_fn(anchor) ?? null;
});

@@ -46,5 +52,5 @@

if (was_hydrating) {
set_hydrate_nodes(previous_hydrate_nodes);
set_hydrate_nodes(/** @type {import('#client').TemplateNode[]} */ (previous_hydrate_nodes));
}
}
}

@@ -101,3 +101,3 @@ import { createClassComponent } from '../../../../legacy/legacy-client.js';

return (anchor) => {
const node = open(anchor, () => {
const node = open(() => {
const slot = document.createElement('slot');

@@ -104,0 +104,0 @@ if (name !== 'default') {

@@ -1,4 +0,1 @@

import { schedule_task } from './task.js';
import { empty } from './operations.js';
/**

@@ -23,109 +20,50 @@ * Use this variable to guard everything related to hydration code so it can be treeshaken out

/**
* @param {null | import('#client').TemplateNode[]} nodes
* @returns {void}
*/
/** @param {import('#client').TemplateNode[]} nodes */
export function set_hydrate_nodes(nodes) {
hydrate_nodes = /** @type {import('#client').TemplateNode[]} */ (nodes);
hydrate_nodes = nodes;
}
/**
* @param {Node | null} first
* @param {boolean} [insert_text] Whether to insert an empty text node if `nodes` is empty
* This function is only called when `hydrating` is true. If passed a `<![>` opening
* hydration marker, it finds the corresponding closing marker and sets `hydrate_nodes`
* to everything between the markers, before returning the closing marker.
* @param {Node} node
* @returns {Node}
*/
export function update_hydrate_nodes(first, insert_text) {
const nodes = get_hydrate_nodes(first, insert_text);
set_hydrate_nodes(nodes);
return nodes;
}
export function hydrate_anchor(node) {
if (node.nodeType !== 8) {
return node;
}
/**
* Returns all nodes between the first `<![>...<!]>` comment tag pair encountered.
* @param {Node | null} node
* @param {boolean} [insert_text] Whether to insert an empty text node if `nodes` is empty
* @returns {import('#client').TemplateNode[] | null}
*/
function get_hydrate_nodes(node, insert_text = false) {
/** @type {import('#client').TemplateNode[]} */
var nodes = [];
var current = /** @type {Node | null} */ (node);
var current_node = /** @type {null | import('#client').TemplateNode} */ (node);
// TODO this could have false positives, if a user comment consisted of `[`. need to tighten that up
if (/** @type {Comment} */ (current)?.data !== '[') {
return node;
}
/** @type {Node[]} */
var nodes = [];
var depth = 0;
var will_start = false;
var started = false;
while ((current = /** @type {Node} */ (current).nextSibling) !== null) {
if (current.nodeType === 8) {
var data = /** @type {Comment} */ (current).data;
while (current_node !== null) {
if (current_node.nodeType === 8) {
var data = /** @type {Comment} */ (current_node).data;
if (data === '[') {
depth += 1;
will_start = true;
} else if (data === ']') {
if (!started) {
// TODO get rid of this — it exists because each blocks are doubly wrapped
return null;
if (depth === 0) {
hydrate_nodes = /** @type {import('#client').TemplateNode[]} */ (nodes);
return current;
}
if (--depth === 0) {
if (insert_text && nodes.length === 0) {
var text = empty();
nodes.push(text);
current_node.before(text);
}
return nodes;
}
depth -= 1;
}
}
if (started) {
nodes.push(current_node);
}
current_node = /** @type {null | import('#client').TemplateNode} */ (current_node.nextSibling);
started = will_start;
nodes.push(current);
}
return null;
throw new Error('Expected a closing hydration marker');
}
/**
* @param {Node} node
* @returns {void}
*/
export function hydrate_block_anchor(node) {
if (!hydrating) return;
// @ts-ignore
var nodes = node.$$fragment ?? get_hydrate_nodes(node);
set_hydrate_nodes(nodes);
}
/**
* Expects to only be called in hydration mode
* @param {Node} node
* @returns {Node}
*/
export function capture_fragment_from_node(node) {
if (
node.nodeType === 8 &&
/** @type {Comment} */ (node).data === '[' &&
hydrate_nodes[hydrate_nodes.length - 1] !== node
) {
const nodes = /** @type {Node[]} */ (get_hydrate_nodes(node));
const last_child = nodes[nodes.length - 1] || node;
const target = /** @type {Node} */ (last_child.nextSibling);
// @ts-ignore
target.$$fragment = nodes;
schedule_task(() => {
// @ts-expect-error clean up memory
target.$$fragment = undefined;
});
return target;
}
return node;
}
import { run } from '../../../common.js';
import { pre_effect, user_effect } from '../../reactivity/effects.js';
import { user_pre_effect, user_effect } from '../../reactivity/effects.js';
import {
current_component_context,
current_effect,
deep_read_state,

@@ -22,3 +23,3 @@ flush_local_render_effects,

if (callbacks.b.length) {
pre_effect(() => {
user_pre_effect(() => {
observe_all(context);

@@ -29,3 +30,6 @@ callbacks.b.forEach(run);

// now hidden because beforeUpdate did set an if block to false.
flush_local_render_effects();
const parent = current_effect?.parent;
if (parent != null) {
flush_local_render_effects(parent);
}
});

@@ -32,0 +36,0 @@ }

@@ -1,2 +0,2 @@

import { capture_fragment_from_node, hydrate_nodes, hydrating } from './hydration.js';
import { hydrate_anchor, hydrate_nodes, hydrating } from './hydration.js';
import { get_descriptor } from '../utils.js';

@@ -135,3 +135,3 @@

return capture_fragment_from_node(child);
return hydrate_anchor(child);
}

@@ -163,7 +163,3 @@

if (first_node !== null) {
return capture_fragment_from_node(first_node);
}
return first_node;
return hydrate_anchor(first_node);
}

@@ -181,24 +177,22 @@

if (hydrating) {
// if a sibling {expression} is empty during SSR, there might be no
// text node to hydrate — we must therefore create one
if (is_text && next_sibling?.nodeType !== 3) {
const text = empty();
if (next_sibling) {
const index = hydrate_nodes.indexOf(/** @type {Text | Comment | Element} */ (next_sibling));
hydrate_nodes.splice(index, 0, text);
next_sibling.before(text);
} else {
hydrate_nodes.push(text);
}
if (!hydrating) {
return next_sibling;
}
return text;
// if a sibling {expression} is empty during SSR, there might be no
// text node to hydrate — we must therefore create one
if (is_text && next_sibling?.nodeType !== 3) {
const text = empty();
if (next_sibling) {
const index = hydrate_nodes.indexOf(/** @type {Text | Comment | Element} */ (next_sibling));
hydrate_nodes.splice(index, 0, text);
next_sibling.before(text);
} else {
hydrate_nodes.push(text);
}
if (next_sibling !== null) {
return capture_fragment_from_node(next_sibling);
}
return text;
}
return next_sibling;
return hydrate_anchor(/** @type {Node} */ (next_sibling));
}

@@ -205,0 +199,0 @@

@@ -1,3 +0,2 @@

import { append_child } from './operations.js';
import { hydrate_nodes, hydrate_block_anchor, hydrating } from './hydration.js';
import { hydrate_nodes, hydrating } from './hydration.js';
import { is_array } from '../utils.js';

@@ -34,3 +33,2 @@

* @param {Text | Element | Comment} sibling
* @returns {Text | Element | Comment}
*/

@@ -44,8 +42,5 @@ export function insert(current, sibling) {

}
return current[0];
} else {
sibling.before(/** @type {Node} */ (current));
}
sibling.before(/** @type {Node} */ (current));
return /** @type {Text | Element | Comment} */ (current);
}

@@ -79,3 +74,2 @@

export function reconcile_html(target, value, svg) {
hydrate_block_anchor(target);
if (hydrating) {

@@ -82,0 +76,0 @@ return hydrate_nodes;

@@ -29,14 +29,2 @@ import { run_all } from '../../common.js';

*/
export function schedule_task(fn) {
if (!is_task_queued) {
is_task_queued = true;
setTimeout(process_task, 0);
}
current_queued_tasks.push(fn);
}
/**
* @param {() => void} fn
* @returns {void}
*/
export function schedule_raf_task(fn) {

@@ -43,0 +31,0 @@ if (!is_raf_queued) {

@@ -1,2 +0,2 @@

import { hydrate_nodes, hydrate_block_anchor, hydrating } from './hydration.js';
import { hydrate_nodes, hydrating } from './hydration.js';
import { child, clone_node, empty } from './operations.js';

@@ -86,3 +86,2 @@ import {

* @param {boolean} use_clone_node
* @param {null | Text | Comment | Element} anchor
* @param {() => Node} [template_element_fn]

@@ -92,9 +91,4 @@ * @returns {Element | DocumentFragment | Node[]}

/*#__NO_SIDE_EFFECTS__*/
function open_template(is_fragment, use_clone_node, anchor, template_element_fn) {
function open_template(is_fragment, use_clone_node, template_element_fn) {
if (hydrating) {
if (anchor !== null) {
// TODO why is this sometimes null and sometimes not? needs clear documentation
hydrate_block_anchor(anchor);
}
return is_fragment ? hydrate_nodes : /** @type {Element} */ (hydrate_nodes[0]);

@@ -109,3 +103,2 @@ }

/**
* @param {null | Text | Comment | Element} anchor
* @param {() => Node} template_element_fn

@@ -115,8 +108,7 @@ * @param {boolean} [use_clone_node]

*/
export function open(anchor, template_element_fn, use_clone_node = true) {
return /** @type {Element} */ (open_template(false, use_clone_node, anchor, template_element_fn));
export function open(template_element_fn, use_clone_node = true) {
return /** @type {Element} */ (open_template(false, use_clone_node, template_element_fn));
}
/**
* @param {null | Text | Comment | Element} anchor
* @param {() => Node} template_element_fn

@@ -126,53 +118,32 @@ * @param {boolean} [use_clone_node]

*/
export function open_frag(anchor, template_element_fn, use_clone_node = true) {
return open_template(true, use_clone_node, anchor, template_element_fn);
export function open_frag(template_element_fn, use_clone_node = true) {
return open_template(true, use_clone_node, template_element_fn);
}
const space_template = template(' ', false);
const comment_template = template('<!>', true);
/**
* @param {Text | Comment | Element | null} anchor
* @param {Text | Comment | Element} anchor
*/
/*#__NO_SIDE_EFFECTS__*/
export function space_frag(anchor) {
/** @type {Node | null} */
var node = /** @type {any} */ (open(anchor, space_template));
// if an {expression} is empty during SSR, there might be no
// text node to hydrate (or an anchor comment is falsely detected instead)
// — we must therefore create one
if (hydrating && node?.nodeType !== 3) {
node = empty();
// @ts-ignore in this case the anchor should always be a comment,
// if not something more fundamental is wrong and throwing here is better to bail out early
anchor.before(node);
export function text(anchor) {
if (!hydrating) return empty();
var node = hydrate_nodes[0];
if (!node) {
// if an {expression} is empty during SSR, `hydrate_nodes` will be empty.
// we need to insert an empty text node
anchor.before((node = empty()));
}
return node;
}
/**
* @param {Text | Comment | Element} anchor
*/
/*#__NO_SIDE_EFFECTS__*/
export function space(anchor) {
// if an {expression} is empty during SSR, there might be no
// text node to hydrate (or an anchor comment is falsely detected instead)
// — we must therefore create one
if (hydrating && anchor.nodeType !== 3) {
const node = empty();
anchor.before(node);
return node;
}
return anchor;
export function comment() {
return open_frag(comment_template);
}
/**
* @param {null | Text | Comment | Element} anchor
*/
/*#__NO_SIDE_EFFECTS__*/
export function comment(anchor) {
return open_frag(anchor, comment_template);
}
/**
* Assign the created (or in hydration mode, traversed) dom elements to the current block

@@ -182,3 +153,3 @@ * and insert the elements into the dom (in client mode).

* @param {boolean} is_fragment
* @param {null | Text | Comment | Element} anchor
* @param {Text | Comment | Element} anchor
* @returns {import('#client').Dom}

@@ -196,6 +167,4 @@ */

if (anchor !== null) {
// TODO as with `open_template — why is this sometimes null and sometimes not?
insert(current, anchor);
}
// TODO ideally we'd do `anchor.before(dom)`, but that fails because `dom` can be an array of nodes in the SVG case
insert(current, anchor);
}

@@ -209,3 +178,3 @@

/**
* @param {null | Text | Comment | Element} anchor
* @param {Text | Comment | Element} anchor
* @param {Element | Text} dom

@@ -218,3 +187,3 @@ */

/**
* @param {null | Text | Comment | Element} anchor
* @param {Text | Comment | Element} anchor
* @param {Element | Text} dom

@@ -221,0 +190,0 @@ */

@@ -10,4 +10,6 @@ import { DEV } from 'esm-env';

get,
is_flushing_effect,
remove_reactions,
schedule_effect,
set_is_flushing_effect,
set_signal_status,

@@ -24,3 +26,4 @@ untrack

INERT,
IS_ELSEIF
IS_ELSEIF,
EFFECT_RAN
} from '../constants.js';

@@ -40,3 +43,3 @@ import { set } from './sources.js';

/** @type {import('#client').Effect} */
const signal = {
const effect = {
parent: current_effect,

@@ -57,3 +60,3 @@ dom: null,

if (current_effect !== null) {
signal.l = current_effect.l + 1;
effect.l = current_effect.l + 1;
}

@@ -63,5 +66,5 @@

if (current_reaction.effects === null) {
current_reaction.effects = [signal];
current_reaction.effects = [effect];
} else {
current_reaction.effects.push(signal);
current_reaction.effects.push(effect);
}

@@ -71,6 +74,18 @@ }

if (init) {
schedule_effect(signal, sync);
if (sync) {
const previously_flushing_effect = is_flushing_effect;
try {
set_is_flushing_effect(true);
execute_effect(effect);
effect.f |= EFFECT_RAN;
} finally {
set_is_flushing_effect(previously_flushing_effect);
}
} else {
schedule_effect(effect);
}
}
return signal;
return effect;
}

@@ -118,2 +133,20 @@

/**
* Internal representation of `$effect.pre(...)`
* @param {() => void | (() => void)} fn
* @returns {import('#client').Effect}
*/
export function user_pre_effect(fn) {
if (current_effect === null) {
throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
: '')
);
}
return pre_effect(fn);
}
/**
* Internal representation of `$effect.root(...)`

@@ -139,21 +172,2 @@ * @param {() => void | (() => void)} fn

/**
* Internal representation of `$effect.pre(...)`
* @param {() => void | (() => void)} fn
* @returns {import('#client').Effect}
*/
export function pre_effect(fn) {
if (current_effect === null) {
throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
: '')
);
}
const sync = current_effect !== null && (current_effect.f & RENDER_EFFECT) !== 0;
return create_effect(PRE_EFFECT, fn, sync);
}
/**
* Internal representation of `$: ..`

@@ -169,15 +183,11 @@ * @param {() => any} deps

const token = {};
return create_effect(
PRE_EFFECT,
() => {
deps();
if (component_context.l1.includes(token)) {
return;
}
component_context.l1.push(token);
set(component_context.l2, true);
return untrack(fn);
},
true
);
return pre_effect(() => {
deps();
if (component_context.l1.includes(token)) {
return;
}
component_context.l1.push(token);
set(component_context.l2, true);
return untrack(fn);
});
}

@@ -199,9 +209,6 @@

/**
* This effect is used to ensure binding are kept in sync. We use a pre effect to ensure we run before the
* bindings which are in later effects. However, we don't use a pre_effect directly as we don't want to flush anything.
*
* @param {() => void | (() => void)} fn
* @returns {import('#client').Effect}
*/
export function invalidate_effect(fn) {
export function pre_effect(fn) {
return create_effect(PRE_EFFECT, fn, true);

@@ -219,3 +226,3 @@ }

return create_effect(flags, /** @type {any} */ (fn), true);
return create_effect(flags, fn, true);
}

@@ -222,0 +229,0 @@

@@ -138,3 +138,3 @@ import { DEV } from 'esm-env';

set_signal_status(current_effect, DIRTY);
schedule_effect(current_effect, false);
schedule_effect(current_effect);
} else {

@@ -141,0 +141,0 @@ if (current_untracked_writes === null) {

@@ -14,8 +14,7 @@ import { DEV } from 'esm-env';

import {
hydrate_anchor,
hydrate_nodes,
hydrate_block_anchor,
hydrating,
set_hydrate_nodes,
set_hydrating,
update_hydrate_nodes
set_hydrating
} from './dom/hydration.js';

@@ -70,3 +69,2 @@ import { array_from } from './utils.js';

export function slot(anchor, slot_fn, slot_props, fallback_fn) {
hydrate_block_anchor(anchor);
if (slot_fn === undefined) {

@@ -143,8 +141,2 @@ if (fallback_fn !== null) {

// Call with insert_text == true to prevent empty {expressions} resulting in an empty
// `nodes` array, resulting in a hydration error down the line
// TODO is both this and the `container.appendChild(anchor)` below necessary?
const nodes = update_hydrate_nodes(first_child, true);
set_hydrating(true);
let hydrated = false;

@@ -155,4 +147,7 @@

return flush_sync(() => {
const anchor = nodes === null ? container.appendChild(empty()) : null;
set_hydrating(true);
const anchor = hydrate_anchor(first_child);
const instance = _mount(component, { ...options, anchor });
// flush_sync will run this callback and then synchronously run any pending effects,

@@ -162,6 +157,7 @@ // which don't belong to the hydration phase anymore - therefore reset it here

hydrated = true;
return instance;
}, false);
} catch (error) {
if (!hydrated && options.recover !== false && nodes !== null) {
if (!hydrated && options.recover !== false) {
// eslint-disable-next-line no-console

@@ -196,3 +192,3 @@ console.error(

* target: Document | Element | ShadowRoot;
* anchor: null | Text;
* anchor: Node;
* props?: Props;

@@ -199,0 +195,0 @@ * events?: { [Property in keyof Events]: (e: Events[Property]) => any };

@@ -11,3 +11,3 @@ import { DEV } from 'esm-env';

import { unstate } from './proxy.js';
import { destroy_effect, pre_effect } from './reactivity/effects.js';
import { destroy_effect, user_pre_effect } from './reactivity/effects.js';
import {

@@ -25,4 +25,3 @@ EFFECT,

MANAGED,
STATE_SYMBOL,
EFFECT_RAN
STATE_SYMBOL
} from './constants.js';

@@ -41,3 +40,9 @@ import { flush_tasks } from './dom/task.js';

let is_micro_task_queued = false;
let is_flushing_effect = false;
export let is_flushing_effect = false;
/** @param {boolean} value */
export function set_is_flushing_effect(value) {
is_flushing_effect = value;
}
// Used for $inspect

@@ -216,5 +221,2 @@ export let is_batching_effect = false;

export function execute_reaction_fn(signal) {
const fn = signal.fn;
const flags = signal.f;
const previous_dependencies = current_dependencies;

@@ -231,7 +233,7 @@ const previous_dependencies_index = current_dependencies_index;

current_reaction = signal;
current_skip_reaction = !is_flushing_effect && (flags & UNOWNED) !== 0;
current_skip_reaction = !is_flushing_effect && (signal.f & UNOWNED) !== 0;
current_untracking = false;
try {
let res = fn();
let res = signal.fn();
let dependencies = /** @type {import('./types.js').Value<unknown>[]} **/ (signal.deps);

@@ -381,23 +383,25 @@ if (current_dependencies !== null) {

/**
* @param {import('./types.js').Effect} signal
* @param {import('./types.js').Effect} effect
* @returns {void}
*/
export function execute_effect(signal) {
if ((signal.f & DESTROYED) !== 0) {
export function execute_effect(effect) {
if ((effect.f & DESTROYED) !== 0) {
return;
}
const previous_effect = current_effect;
const previous_component_context = current_component_context;
set_signal_status(effect, CLEAN);
const component_context = signal.ctx;
var component_context = effect.ctx;
current_effect = signal;
var previous_effect = current_effect;
var previous_component_context = current_component_context;
current_effect = effect;
current_component_context = component_context;
try {
destroy_children(signal);
signal.teardown?.();
const teardown = execute_reaction_fn(signal);
signal.teardown = typeof teardown === 'function' ? teardown : null;
destroy_children(effect);
effect.teardown?.();
var teardown = execute_reaction_fn(effect);
effect.teardown = typeof teardown === 'function' ? teardown : null;
} finally {

@@ -407,5 +411,6 @@ current_effect = previous_effect;

}
const parent = effect.parent;
if ((signal.f & PRE_EFFECT) !== 0 && current_queued_pre_and_render_effects.length > 0) {
flush_local_pre_effects(component_context);
if ((effect.f & PRE_EFFECT) !== 0 && parent !== null) {
flush_local_pre_effects(parent);
}

@@ -446,3 +451,2 @@ }

if (check_dirtiness(signal)) {
set_signal_status(signal, CLEAN);
execute_effect(signal);

@@ -477,117 +481,155 @@ }

* @param {import('./types.js').Effect} signal
* @param {boolean} sync
* @returns {void}
*/
export function schedule_effect(signal, sync) {
export function schedule_effect(signal) {
const flags = signal.f;
if (sync) {
const previously_flushing_effect = is_flushing_effect;
try {
is_flushing_effect = true;
execute_effect(signal);
set_signal_status(signal, CLEAN);
} finally {
is_flushing_effect = previously_flushing_effect;
if (current_scheduler_mode === FLUSH_MICROTASK) {
if (!is_micro_task_queued) {
is_micro_task_queued = true;
queueMicrotask(process_microtask);
}
}
if ((flags & EFFECT) !== 0) {
current_queued_effects.push(signal);
// Prevent any nested user effects from potentially triggering
// before this effect is scheduled. We know they will be destroyed
// so we can make them inert to avoid having to find them in the
// queue and remove them.
if ((flags & MANAGED) === 0) {
mark_subtree_children_inert(signal, true);
}
} else {
if (current_scheduler_mode === FLUSH_MICROTASK) {
if (!is_micro_task_queued) {
is_micro_task_queued = true;
queueMicrotask(process_microtask);
}
}
if ((flags & EFFECT) !== 0) {
current_queued_effects.push(signal);
// Prevent any nested user effects from potentially triggering
// before this effect is scheduled. We know they will be destroyed
// so we can make them inert to avoid having to find them in the
// queue and remove them.
if ((flags & MANAGED) === 0) {
mark_subtree_children_inert(signal, true);
}
} else {
// We need to ensure we insert the signal in the right topological order. In other words,
// we need to evaluate where to insert the signal based off its level and whether or not it's
// a pre-effect and within the same block. By checking the signals in the queue in reverse order
// we can find the right place quickly. TODO: maybe opt to use a linked list rather than an array
// for these operations.
const length = current_queued_pre_and_render_effects.length;
let should_append = length === 0;
// We need to ensure we insert the signal in the right topological order. In other words,
// we need to evaluate where to insert the signal based off its level and whether or not it's
// a pre-effect and within the same block. By checking the signals in the queue in reverse order
// we can find the right place quickly. TODO: maybe opt to use a linked list rather than an array
// for these operations.
const length = current_queued_pre_and_render_effects.length;
let should_append = length === 0;
if (!should_append) {
const target_level = signal.l;
const is_pre_effect = (flags & PRE_EFFECT) !== 0;
let target_signal;
let target_signal_level;
let is_target_pre_effect;
let i = length;
while (true) {
target_signal = current_queued_pre_and_render_effects[--i];
target_signal_level = target_signal.l;
if (target_signal_level <= target_level) {
if (i + 1 === length) {
should_append = true;
} else {
is_target_pre_effect = (target_signal.f & PRE_EFFECT) !== 0;
if (
target_signal_level < target_level ||
target_signal !== signal ||
(is_target_pre_effect && !is_pre_effect)
) {
i++;
}
current_queued_pre_and_render_effects.splice(i, 0, signal);
if (!should_append) {
const target_level = signal.l;
const is_pre_effect = (flags & PRE_EFFECT) !== 0;
let target_signal;
let target_signal_level;
let is_target_pre_effect;
let i = length;
while (true) {
target_signal = current_queued_pre_and_render_effects[--i];
target_signal_level = target_signal.l;
if (target_signal_level <= target_level) {
if (i + 1 === length) {
should_append = true;
} else {
is_target_pre_effect = (target_signal.f & PRE_EFFECT) !== 0;
if (
target_signal_level < target_level ||
target_signal !== signal ||
(is_target_pre_effect && !is_pre_effect)
) {
i++;
}
break;
current_queued_pre_and_render_effects.splice(i, 0, signal);
}
if (i === 0) {
current_queued_pre_and_render_effects.unshift(signal);
break;
}
break;
}
if (i === 0) {
current_queued_pre_and_render_effects.unshift(signal);
break;
}
}
}
if (should_append) {
current_queued_pre_and_render_effects.push(signal);
}
if (should_append) {
current_queued_pre_and_render_effects.push(signal);
}
}
signal.f |= EFFECT_RAN;
}
/**
*
* This function recursively collects effects in topological order from the starting effect passed in.
* Effects will be collected when they match the filtered bitwise flag passed in only. The collected
* array will be populated with all the effects.
*
* @param {import('./types.js').Effect} effect
* @param {number} filter_flags
* @param {import('./types.js').Effect[]} collected
* @returns {void}
*/
export function flush_local_render_effects() {
const effects = [];
for (let i = 0; i < current_queued_pre_and_render_effects.length; i++) {
const effect = current_queued_pre_and_render_effects[i];
if ((effect.f & RENDER_EFFECT) !== 0 && effect.ctx === current_component_context) {
effects.push(effect);
current_queued_pre_and_render_effects.splice(i, 1);
i--;
function collect_effects(effect, filter_flags, collected) {
var effects = effect.effects;
if (effects === null) {
return;
}
var i, s, child, flags;
var render = [];
var user = [];
for (i = 0; i < effects.length; i++) {
child = effects[i];
flags = child.f;
if ((flags & CLEAN) !== 0) {
continue;
}
if ((flags & PRE_EFFECT) !== 0) {
if ((filter_flags & PRE_EFFECT) !== 0) {
collected.push(child);
}
collect_effects(child, filter_flags, collected);
} else if ((flags & RENDER_EFFECT) !== 0) {
render.push(child);
} else if ((flags & EFFECT) !== 0) {
user.push(child);
}
}
flush_queued_effects(effects);
if (render.length > 0) {
if ((filter_flags & RENDER_EFFECT) !== 0) {
collected.push(...render);
}
for (s = 0; s < render.length; s++) {
collect_effects(render[s], filter_flags, collected);
}
}
if (user.length > 0) {
if ((filter_flags & EFFECT) !== 0) {
collected.push(...user);
}
for (s = 0; s < user.length; s++) {
collect_effects(user[s], filter_flags, collected);
}
}
}
/**
* @param {null | import('./types.js').ComponentContext} context
* @param {import('./types.js').Effect} effect
* @returns {void}
*/
export function flush_local_pre_effects(context) {
const effects = [];
for (let i = 0; i < current_queued_pre_and_render_effects.length; i++) {
const effect = current_queued_pre_and_render_effects[i];
if ((effect.f & PRE_EFFECT) !== 0 && effect.ctx === context) {
effects.push(effect);
current_queued_pre_and_render_effects.splice(i, 1);
i--;
}
}
flush_queued_effects(effects);
export function flush_local_render_effects(effect) {
/**
* @type {import("./types.js").Effect[]}
*/
var render_effects = [];
collect_effects(effect, RENDER_EFFECT, render_effects);
flush_queued_effects(render_effects);
}
/**
* @param {import('./types.js').Effect} effect
* @returns {void}
*/
export function flush_local_pre_effects(effect) {
/**
* @type {import("./types.js").Effect[]}
*/
var pre_effects = [];
collect_effects(effect, PRE_EFFECT, pre_effects);
flush_queued_effects(pre_effects);
}
/**
* Synchronously flushes any pending state changes and those that result from it.

@@ -708,3 +750,3 @@ * @param {() => void} [fn]

set_signal_status(current_effect, DIRTY);
schedule_effect(current_effect, false);
schedule_effect(current_effect);
}

@@ -785,3 +827,3 @@ }

if (!inert && (flags & CLEAN) === 0) {
schedule_effect(signal, false);
schedule_effect(signal);
}

@@ -833,3 +875,3 @@ }

} else {
schedule_effect(/** @type {import('#client').Effect} */ (reaction), false);
schedule_effect(/** @type {import('#client').Effect} */ (reaction));
}

@@ -1090,3 +1132,3 @@ }

for (let i = 0; i < effects.length; i++) {
schedule_effect(effects[i], false);
schedule_effect(effects[i]);
}

@@ -1217,3 +1259,3 @@ }

pre_effect(() => {
user_pre_effect(() => {
const fn = () => {

@@ -1220,0 +1262,0 @@ const value = untrack(() => get_value().map((v) => deep_unstate(v)));

@@ -9,3 +9,3 @@ // generated during release, do not modify

*/
export const VERSION = '5.0.0-next.84';
export const VERSION = '5.0.0-next.85';
export const PUBLIC_VERSION = '5';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc