tailwind-screen-size
Version:
A framework-agnostic screen size indicator optimized for TailwindCSS but customizable for any CSS framework. Features real-time dimensions, breakpoints, themes, and development tools.
1,916 lines (1,634 loc) • 157 kB
JavaScript
'use strict';
var svelte = require('svelte');
// generated during release, do not modify
const PUBLIC_VERSION = '5';
if (typeof window !== 'undefined')
// @ts-ignore
(window.__svelte ||= { v: new Set() }).v.add(PUBLIC_VERSION);
const PROPS_IS_BINDABLE = 1 << 3;
const TEMPLATE_FRAGMENT = 1;
const TEMPLATE_USE_IMPORT_NODE = 1 << 1;
const UNINITIALIZED = Symbol();
// Dev-time component properties
const FILENAME = Symbol('filename');
const node_env = globalThis.process?.env?.NODE_ENV;
if (!node_env) {
console.warn('If bundling, conditions should include development or production. If not bundling, conditions or NODE_ENV should include development or production. See https://www.npmjs.com/package/esm-env for tips on setting conditions in popular bundlers and runtimes.');
}
var DEV = node_env && !node_env.toLowerCase().includes('prod');
/* This file is generated by scripts/process-messages/index.js. Do not edit! */
var bold = 'font-weight: bold';
var normal = 'font-weight: normal';
/**
* %component% mutated a value owned by %owner%. This is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead
* @param {string | undefined | null} [component]
* @param {string | undefined | null} [owner]
*/
function ownership_invalid_mutation(component, owner) {
if (DEV) {
console.warn(`%c[svelte] ownership_invalid_mutation\n%c${component ? `${component} mutated a value owned by ${owner}. This is strongly discouraged. Consider passing values to child components with \`bind:\`, or use a callback instead` : "Mutating a value outside the component that created it is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead"}`, bold, normal);
} else {
// TODO print a link to the documentation
console.warn("ownership_invalid_mutation");
}
}
/**
* Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results
* @param {string} operator
*/
function state_proxy_equality_mismatch(operator) {
if (DEV) {
console.warn(`%c[svelte] state_proxy_equality_mismatch\n%cReactive \`$state(...)\` proxies and the values they proxy have different identities. Because of this, comparisons with \`${operator}\` will produce unexpected results`, bold, normal);
} else {
// TODO print a link to the documentation
console.warn("state_proxy_equality_mismatch");
}
}
// Store the references to globals in case someone tries to monkey patch these, causing the below
// to de-opt (this occurs often when using popular extensions).
var is_array = Array.isArray;
var define_property = Object.defineProperty;
var get_descriptor = Object.getOwnPropertyDescriptor;
var object_prototype = Object.prototype;
var array_prototype = Array.prototype;
var get_prototype_of = Object.getPrototypeOf;
const DERIVED = 1 << 1;
const EFFECT = 1 << 2;
const RENDER_EFFECT = 1 << 3;
const BLOCK_EFFECT = 1 << 4;
const BRANCH_EFFECT = 1 << 5;
const ROOT_EFFECT = 1 << 6;
const UNOWNED = 1 << 7;
const DISCONNECTED = 1 << 8;
const CLEAN = 1 << 9;
const DIRTY = 1 << 10;
const MAYBE_DIRTY = 1 << 11;
const INERT = 1 << 12;
const DESTROYED = 1 << 13;
const EFFECT_RAN = 1 << 14;
/** 'Transparent' effects do not create a transition boundary */
const EFFECT_TRANSPARENT = 1 << 15;
const INSPECT_EFFECT = 1 << 17;
const HEAD_EFFECT = 1 << 18;
const EFFECT_HAS_DERIVED = 1 << 19;
const STATE_SYMBOL = Symbol('$state');
const STATE_SYMBOL_METADATA = Symbol('$state metadata');
const LEGACY_PROPS = Symbol('legacy props');
/** @import { Equals } from '#client' */
/** @type {Equals} */
function equals(value) {
return value === this.v;
}
/* This file is generated by scripts/process-messages/index.js. Do not edit! */
/**
* Component %component% has an export named `%key%` that a consumer component is trying to access using `bind:%key%`, which is disallowed. Instead, use `bind:this` (e.g. `<%name% bind:this={component} />`) and then access the property on the bound component instance (e.g. `component.%key%`)
* @param {string} component
* @param {string} key
* @param {string} name
* @returns {never}
*/
function bind_invalid_export(component, key, name) {
if (DEV) {
const error = new Error(`bind_invalid_export\nComponent ${component} has an export named \`${key}\` that a consumer component is trying to access using \`bind:${key}\`, which is disallowed. Instead, use \`bind:this\` (e.g. \`<${name} bind:this={component} />\`) and then access the property on the bound component instance (e.g. \`component.${key}\`)`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("bind_invalid_export");
}
}
/**
* A component is attempting to bind to a non-bindable property `%key%` belonging to %component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable: `let { %key% = $bindable() } = $props()`
* @param {string} key
* @param {string} component
* @param {string} name
* @returns {never}
*/
function bind_not_bindable(key, component, name) {
if (DEV) {
const error = new Error(`bind_not_bindable\nA component is attempting to bind to a non-bindable property \`${key}\` belonging to ${component} (i.e. \`<${name} bind:${key}={...}>\`). To mark a property as bindable: \`let { ${key} = $bindable() } = $props()\``);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("bind_not_bindable");
}
}
/**
* %parent% called `%method%` on an instance of %component%, which is no longer valid in Svelte 5. See https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes for more information
* @param {string} parent
* @param {string} method
* @param {string} component
* @returns {never}
*/
function component_api_changed(parent, method, component) {
if (DEV) {
const error = new Error(`component_api_changed\n${parent} called \`${method}\` on an instance of ${component}, which is no longer valid in Svelte 5. See https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes for more information`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("component_api_changed");
}
}
/**
* Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `compatibility.componentApi` compiler option to `4` to keep it working. See https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes for more information
* @param {string} component
* @param {string} name
* @returns {never}
*/
function component_api_invalid_new(component, name) {
if (DEV) {
const error = new Error(`component_api_invalid_new\nAttempted to instantiate ${component} with \`new ${name}\`, which is no longer valid in Svelte 5. If this component is not under your control, set the \`compatibility.componentApi\` compiler option to \`4\` to keep it working. See https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes for more information`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("component_api_invalid_new");
}
}
/**
* A derived value cannot reference itself recursively
* @returns {never}
*/
function derived_references_self() {
if (DEV) {
const error = new Error(`derived_references_self\nA derived value cannot reference itself recursively`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("derived_references_self");
}
}
/**
* Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops
* @returns {never}
*/
function effect_update_depth_exceeded() {
if (DEV) {
const error = new Error(`effect_update_depth_exceeded\nMaximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("effect_update_depth_exceeded");
}
}
/**
* Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value
* @param {string} key
* @returns {never}
*/
function props_invalid_value(key) {
if (DEV) {
const error = new Error(`props_invalid_value\nCannot do \`bind:${key}={undefined}\` when \`${key}\` has a fallback value`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("props_invalid_value");
}
}
/**
* The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
* @param {string} rune
* @returns {never}
*/
function rune_outside_svelte(rune) {
if (DEV) {
const error = new Error(`rune_outside_svelte\nThe \`${rune}\` rune is only available inside \`.svelte\` and \`.svelte.js/ts\` files`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("rune_outside_svelte");
}
}
/**
* Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.
* @returns {never}
*/
function state_descriptors_fixed() {
if (DEV) {
const error = new Error(`state_descriptors_fixed\nProperty descriptors defined on \`$state\` objects must contain \`value\` and always be \`enumerable\`, \`configurable\` and \`writable\`.`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("state_descriptors_fixed");
}
}
/**
* Cannot set prototype of `$state` object
* @returns {never}
*/
function state_prototype_fixed() {
if (DEV) {
const error = new Error(`state_prototype_fixed\nCannot set prototype of \`$state\` object`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("state_prototype_fixed");
}
}
/**
* Reading state that was created inside the same derived is forbidden. Consider using `untrack` to read locally created state
* @returns {never}
*/
function state_unsafe_local_read() {
if (DEV) {
const error = new Error(`state_unsafe_local_read\nReading state that was created inside the same derived is forbidden. Consider using \`untrack\` to read locally created state`);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("state_unsafe_local_read");
}
}
/**
* Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
* @returns {never}
*/
function state_unsafe_mutation() {
if (DEV) {
const error = new Error(`state_unsafe_mutation\nUpdating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without \`$state\``);
error.name = 'Svelte error';
throw error;
} else {
// TODO print a link to the documentation
throw new Error("state_unsafe_mutation");
}
}
let legacy_mode_flag = false;
/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */
let inspect_effects = new Set();
/**
* @param {Set<any>} v
*/
function set_inspect_effects(v) {
inspect_effects = v;
}
/**
* @template V
* @param {V} v
* @returns {Source<V>}
*/
function source(v) {
return {
f: 0, // TODO ideally we could skip this altogether, but it causes type errors
v,
reactions: null,
equals,
version: 0
};
}
/**
* @template V
* @param {V} v
*/
function state(v) {
return push_derived_source(source(v));
}
/**
* @template V
* @param {Source<V>} source
*/
/*#__NO_SIDE_EFFECTS__*/
function push_derived_source(source) {
if (active_reaction !== null && (active_reaction.f & DERIVED) !== 0) {
if (derived_sources === null) {
set_derived_sources([source]);
} else {
derived_sources.push(source);
}
}
return source;
}
/**
* @template V
* @param {Source<V>} source
* @param {V} value
* @returns {V}
*/
function set(source, value) {
if (
active_reaction !== null &&
is_runes() &&
(active_reaction.f & (DERIVED | BLOCK_EFFECT)) !== 0 &&
// If the source was created locally within the current derived, then
// we allow the mutation.
(derived_sources === null || !derived_sources.includes(source))
) {
state_unsafe_mutation();
}
return internal_set(source, value);
}
/**
* @template V
* @param {Source<V>} source
* @param {V} value
* @returns {V}
*/
function internal_set(source, value) {
if (!source.equals(value)) {
source.v = value;
source.version = increment_version();
mark_reactions(source, DIRTY);
// If the current signal is running for the first time, it won't have any
// reactions as we only allocate and assign the reactions after the signal
// has fully executed. So in the case of ensuring it registers the reaction
// properly for itself, we need to ensure the current effect actually gets
// scheduled. i.e: `$effect(() => x++)`
if (
active_effect !== null &&
(active_effect.f & CLEAN) !== 0 &&
(active_effect.f & BRANCH_EFFECT) === 0
) {
if (new_deps !== null && new_deps.includes(source)) {
set_signal_status(active_effect, DIRTY);
schedule_effect(active_effect);
} else {
if (untracked_writes === null) {
set_untracked_writes([source]);
} else {
untracked_writes.push(source);
}
}
}
if (DEV && inspect_effects.size > 0) {
const inspects = Array.from(inspect_effects);
var previously_flushing_effect = is_flushing_effect;
set_is_flushing_effect(true);
try {
for (const effect of inspects) {
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
// instead of just updating the effects - this way we avoid overfiring.
if ((effect.f & CLEAN) !== 0) {
set_signal_status(effect, MAYBE_DIRTY);
}
if (check_dirtiness(effect)) {
update_effect(effect);
}
}
} finally {
set_is_flushing_effect(previously_flushing_effect);
}
inspect_effects.clear();
}
}
return value;
}
/**
* @param {Value} signal
* @param {number} status should be DIRTY or MAYBE_DIRTY
* @returns {void}
*/
function mark_reactions(signal, status) {
var reactions = signal.reactions;
if (reactions === null) return;
var length = reactions.length;
for (var i = 0; i < length; i++) {
var reaction = reactions[i];
var flags = reaction.f;
// Skip any effects that are already dirty
if ((flags & DIRTY) !== 0) continue;
// Inspect effects need to run immediately, so that the stack trace makes sense
if (DEV && (flags & INSPECT_EFFECT) !== 0) {
inspect_effects.add(reaction);
continue;
}
set_signal_status(reaction, status);
// If the signal a) was previously clean or b) is an unowned derived, then mark it
if ((flags & (CLEAN | UNOWNED)) !== 0) {
if ((flags & DERIVED) !== 0) {
mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY);
} else {
schedule_effect(/** @type {Effect} */ (reaction));
}
}
}
}
/** @import { Derived, Effect } from '#client' */
/**
* @template V
* @param {() => V} fn
* @returns {Derived<V>}
*/
/*#__NO_SIDE_EFFECTS__*/
function derived(fn) {
var flags = DERIVED | DIRTY;
if (active_effect === null) {
flags |= UNOWNED;
} else {
// Since deriveds are evaluated lazily, any effects created inside them are
// created too late to ensure that the parent effect is added to the tree
active_effect.f |= EFFECT_HAS_DERIVED;
}
var parent_derived =
active_reaction !== null && (active_reaction.f & DERIVED) !== 0
? /** @type {Derived} */ (active_reaction)
: null;
/** @type {Derived<V>} */
const signal = {
children: null,
ctx: component_context,
deps: null,
equals,
f: flags,
fn,
reactions: null,
v: /** @type {V} */ (null),
version: 0,
parent: parent_derived ?? active_effect
};
if (parent_derived !== null) {
(parent_derived.children ??= []).push(signal);
}
return signal;
}
/**
* @param {Derived} derived
* @returns {void}
*/
function destroy_derived_children(derived) {
var children = derived.children;
if (children !== null) {
derived.children = null;
for (var i = 0; i < children.length; i += 1) {
var child = children[i];
if ((child.f & DERIVED) !== 0) {
destroy_derived(/** @type {Derived} */ (child));
} else {
destroy_effect(/** @type {Effect} */ (child));
}
}
}
}
/**
* The currently updating deriveds, used to detect infinite recursion
* in dev mode and provide a nicer error than 'too much recursion'
* @type {Derived[]}
*/
let stack = [];
/**
* @param {Derived} derived
* @returns {Effect | null}
*/
function get_derived_parent_effect(derived) {
var parent = derived.parent;
while (parent !== null) {
if ((parent.f & DERIVED) === 0) {
return /** @type {Effect} */ (parent);
}
parent = parent.parent;
}
return null;
}
/**
* @template T
* @param {Derived} derived
* @returns {T}
*/
function execute_derived(derived) {
var value;
var prev_active_effect = active_effect;
set_active_effect(get_derived_parent_effect(derived));
if (DEV) {
let prev_inspect_effects = inspect_effects;
set_inspect_effects(new Set());
try {
if (stack.includes(derived)) {
derived_references_self();
}
stack.push(derived);
destroy_derived_children(derived);
value = update_reaction(derived);
} finally {
set_active_effect(prev_active_effect);
set_inspect_effects(prev_inspect_effects);
stack.pop();
}
} else {
try {
destroy_derived_children(derived);
value = update_reaction(derived);
} finally {
set_active_effect(prev_active_effect);
}
}
return value;
}
/**
* @param {Derived} derived
* @returns {void}
*/
function update_derived(derived) {
var value = execute_derived(derived);
var status =
(skip_reaction || (derived.f & UNOWNED) !== 0) && derived.deps !== null ? MAYBE_DIRTY : CLEAN;
set_signal_status(derived, status);
if (!derived.equals(value)) {
derived.v = value;
derived.version = increment_version();
}
}
/**
* @param {Derived} derived
* @returns {void}
*/
function destroy_derived(derived) {
destroy_derived_children(derived);
remove_reactions(derived, 0);
set_signal_status(derived, DESTROYED);
derived.v = derived.children = derived.deps = derived.ctx = derived.reactions = null;
}
/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, Reaction, TemplateNode, TransitionManager } from '#client' */
/**
* @param {Effect} effect
* @param {Effect} parent_effect
*/
function push_effect(effect, parent_effect) {
var parent_last = parent_effect.last;
if (parent_last === null) {
parent_effect.last = parent_effect.first = effect;
} else {
parent_last.next = effect;
effect.prev = parent_last;
parent_effect.last = effect;
}
}
/**
* @param {number} type
* @param {null | (() => void | (() => void))} fn
* @param {boolean} sync
* @param {boolean} push
* @returns {Effect}
*/
function create_effect(type, fn, sync, push = true) {
var is_root = (type & ROOT_EFFECT) !== 0;
var parent_effect = active_effect;
if (DEV) {
// Ensure the parent is never an inspect effect
while (parent_effect !== null && (parent_effect.f & INSPECT_EFFECT) !== 0) {
parent_effect = parent_effect.parent;
}
}
/** @type {Effect} */
var effect = {
ctx: component_context,
deps: null,
deriveds: null,
nodes_start: null,
nodes_end: null,
f: type | DIRTY,
first: null,
fn,
last: null,
next: null,
parent: is_root ? null : parent_effect,
prev: null,
teardown: null,
transitions: null,
version: 0
};
if (DEV) {
effect.component_function = dev_current_component_function;
}
if (sync) {
var previously_flushing_effect = is_flushing_effect;
try {
set_is_flushing_effect(true);
update_effect(effect);
effect.f |= EFFECT_RAN;
} catch (e) {
destroy_effect(effect);
throw e;
} finally {
set_is_flushing_effect(previously_flushing_effect);
}
} else if (fn !== null) {
schedule_effect(effect);
}
// if an effect has no dependencies, no DOM and no teardown function,
// don't bother adding it to the effect tree
var inert =
sync &&
effect.deps === null &&
effect.first === null &&
effect.nodes_start === null &&
effect.teardown === null &&
(effect.f & EFFECT_HAS_DERIVED) === 0;
if (!inert && !is_root && push) {
if (parent_effect !== null) {
push_effect(effect, parent_effect);
}
// if we're in a derived, add the effect there too
if (active_reaction !== null && (active_reaction.f & DERIVED) !== 0) {
var derived = /** @type {Derived} */ (active_reaction);
(derived.children ??= []).push(effect);
}
}
return effect;
}
/**
* @param {() => void | (() => void)} fn
* @returns {Effect}
*/
function effect(fn) {
return create_effect(EFFECT, fn, false);
}
/**
* @param {() => void | (() => void)} fn
* @returns {Effect}
*/
function template_effect(fn) {
if (DEV) {
define_property(fn, 'name', {
value: '{expression}'
});
}
return block(fn);
}
/**
* @param {(() => void)} fn
* @param {number} flags
*/
function block(fn, flags = 0) {
return create_effect(RENDER_EFFECT | BLOCK_EFFECT | flags, fn, true);
}
/**
* @param {(() => void)} fn
* @param {boolean} [push]
*/
function branch(fn, push = true) {
return create_effect(RENDER_EFFECT | BRANCH_EFFECT, fn, true, push);
}
/**
* @param {Effect} effect
*/
function execute_effect_teardown(effect) {
var teardown = effect.teardown;
if (teardown !== null) {
const previous_reaction = active_reaction;
set_active_reaction(null);
try {
teardown.call(null);
} finally {
set_active_reaction(previous_reaction);
}
}
}
/**
* @param {Effect} signal
* @returns {void}
*/
function destroy_effect_deriveds(signal) {
var deriveds = signal.deriveds;
if (deriveds !== null) {
signal.deriveds = null;
for (var i = 0; i < deriveds.length; i += 1) {
destroy_derived(deriveds[i]);
}
}
}
/**
* @param {Effect} signal
* @param {boolean} remove_dom
* @returns {void}
*/
function destroy_effect_children(signal, remove_dom = false) {
var effect = signal.first;
signal.first = signal.last = null;
while (effect !== null) {
var next = effect.next;
destroy_effect(effect, remove_dom);
effect = next;
}
}
/**
* @param {Effect} signal
* @returns {void}
*/
function destroy_block_effect_children(signal) {
var effect = signal.first;
while (effect !== null) {
var next = effect.next;
if ((effect.f & BRANCH_EFFECT) === 0) {
destroy_effect(effect);
}
effect = next;
}
}
/**
* @param {Effect} effect
* @param {boolean} [remove_dom]
* @returns {void}
*/
function destroy_effect(effect, remove_dom = true) {
var removed = false;
if ((remove_dom || (effect.f & HEAD_EFFECT) !== 0) && effect.nodes_start !== null) {
/** @type {TemplateNode | null} */
var node = effect.nodes_start;
var end = effect.nodes_end;
while (node !== null) {
/** @type {TemplateNode | null} */
var next = node === end ? null : /** @type {TemplateNode} */ (get_next_sibling(node));
node.remove();
node = next;
}
removed = true;
}
destroy_effect_children(effect, remove_dom && !removed);
destroy_effect_deriveds(effect);
remove_reactions(effect, 0);
set_signal_status(effect, DESTROYED);
var transitions = effect.transitions;
if (transitions !== null) {
for (const transition of transitions) {
transition.stop();
}
}
execute_effect_teardown(effect);
var parent = effect.parent;
// If the parent doesn't have any children, then skip this work altogether
if (parent !== null && parent.first !== null) {
unlink_effect(effect);
}
if (DEV) {
effect.component_function = null;
}
// `first` and `child` are nulled out in destroy_effect_children
effect.next =
effect.prev =
effect.teardown =
effect.ctx =
effect.deps =
effect.parent =
effect.fn =
effect.nodes_start =
effect.nodes_end =
null;
}
/**
* Detach an effect from the effect tree, freeing up memory and
* reducing the amount of work that happens on subsequent traversals
* @param {Effect} effect
*/
function unlink_effect(effect) {
var parent = effect.parent;
var prev = effect.prev;
var next = effect.next;
if (prev !== null) prev.next = next;
if (next !== null) next.prev = prev;
if (parent !== null) {
if (parent.first === effect) parent.first = next;
if (parent.last === effect) parent.last = prev;
}
}
/**
* When a block effect is removed, we don't immediately destroy it or yank it
* out of the DOM, because it might have transitions. Instead, we 'pause' it.
* It stays around (in memory, and in the DOM) until outro transitions have
* completed, and if the state change is reversed then we _resume_ it.
* A paused effect does not update, and the DOM subtree becomes inert.
* @param {Effect} effect
* @param {() => void} [callback]
*/
function pause_effect(effect, callback) {
/** @type {TransitionManager[]} */
var transitions = [];
pause_children(effect, transitions, true);
run_out_transitions(transitions, () => {
destroy_effect(effect);
if (callback) callback();
});
}
/**
* @param {TransitionManager[]} transitions
* @param {() => void} fn
*/
function run_out_transitions(transitions, fn) {
var remaining = transitions.length;
if (remaining > 0) {
var check = () => --remaining || fn();
for (var transition of transitions) {
transition.out(check);
}
} else {
fn();
}
}
/**
* @param {Effect} effect
* @param {TransitionManager[]} transitions
* @param {boolean} local
*/
function pause_children(effect, transitions, local) {
if ((effect.f & INERT) !== 0) return;
effect.f ^= INERT;
if (effect.transitions !== null) {
for (const transition of effect.transitions) {
if (transition.is_global || local) {
transitions.push(transition);
}
}
}
var child = effect.first;
while (child !== null) {
var sibling = child.next;
var transparent = (child.f & EFFECT_TRANSPARENT) !== 0 || (child.f & BRANCH_EFFECT) !== 0;
// TODO we don't need to call pause_children recursively with a linked list in place
// it's slightly more involved though as we have to account for `transparent` changing
// through the tree.
pause_children(child, transitions, transparent ? local : false);
child = sibling;
}
}
/**
* The opposite of `pause_effect`. We call this if (for example)
* `x` becomes falsy then truthy: `{#if x}...{/if}`
* @param {Effect} effect
*/
function resume_effect(effect) {
resume_children(effect, true);
}
/**
* @param {Effect} effect
* @param {boolean} local
*/
function resume_children(effect, local) {
if ((effect.f & INERT) === 0) return;
// If a dependency of this effect changed while it was paused,
// apply the change now
if (check_dirtiness(effect)) {
update_effect(effect);
}
// Ensure we toggle the flag after possibly updating the effect so that
// each block logic can correctly operate on inert items
effect.f ^= INERT;
var child = effect.first;
while (child !== null) {
var sibling = child.next;
var transparent = (child.f & EFFECT_TRANSPARENT) !== 0 || (child.f & BRANCH_EFFECT) !== 0;
// TODO we don't need to call resume_children recursively with a linked list in place
// it's slightly more involved though as we have to account for `transparent` changing
// through the tree.
resume_children(child, transparent ? local : false);
child = sibling;
}
if (effect.transitions !== null) {
for (const transition of effect.transitions) {
if (transition.is_global || local) {
transition.in();
}
}
}
}
/** @import { ProxyMetadata } from '#client' */
/** @typedef {{ file: string, line: number, column: number }} Location */
/** @type {Record<string, Array<{ start: Location, end: Location, component: Function }>>} */
const boundaries = {};
const chrome_pattern = /at (?:.+ \()?(.+):(\d+):(\d+)\)?$/;
const firefox_pattern = /@(.+):(\d+):(\d+)$/;
function get_stack() {
const stack = new Error().stack;
if (!stack) return null;
const entries = [];
for (const line of stack.split('\n')) {
let match = chrome_pattern.exec(line) ?? firefox_pattern.exec(line);
if (match) {
entries.push({
file: match[1],
line: +match[2],
column: +match[3]
});
}
}
return entries;
}
/**
* Determines which `.svelte` component is responsible for a given state change
* @returns {Function | null}
*/
function get_component() {
// first 4 lines are svelte internals; adjust this number if we change the internal call stack
const stack = get_stack()?.slice(4);
if (!stack) return null;
for (let i = 0; i < stack.length; i++) {
const entry = stack[i];
const modules = boundaries[entry.file];
if (!modules) {
// If the first entry is not a component, that means the modification very likely happened
// within a .svelte.js file, possibly triggered by a component. Since these files are not part
// of the bondaries/component context heuristic, we need to bail in this case, else we would
// have false positives when the .svelte.ts file provides a state creator function, encapsulating
// the state and its mutations, and is being called from a component other than the one who
// called the state creator function.
if (i === 0) return null;
continue;
}
for (const module of modules) {
if (module.end == null) {
return null;
}
if (module.start.line < entry.line && module.end.line > entry.line) {
return module.component;
}
}
}
return null;
}
/**
* Together with `mark_module_end`, this function establishes the boundaries of a `.svelte` file,
* such that subsequent calls to `get_component` can tell us which component is responsible
* for a given state change
*/
function mark_module_start() {
const start = get_stack()?.[2];
if (start) {
(boundaries[start.file] ??= []).push({
start,
// @ts-expect-error
end: null,
// @ts-expect-error we add the component at the end, since HMR will overwrite the function
component: null
});
}
}
/**
* @param {Function} component
*/
function mark_module_end(component) {
const end = get_stack()?.[2];
if (end) {
const boundaries_file = boundaries[end.file];
const boundary = boundaries_file[boundaries_file.length - 1];
boundary.end = end;
boundary.component = component;
}
}
/**
* @param {ProxyMetadata | null} from
* @param {ProxyMetadata} to
*/
function widen_ownership(from, to) {
if (to.owners === null) {
return;
}
while (from) {
if (from.owners === null) {
to.owners = null;
break;
}
for (const owner of from.owners) {
to.owners.add(owner);
}
from = from.parent;
}
}
/**
* @param {ProxyMetadata} metadata
* @param {Function} component
* @returns {boolean}
*/
function has_owner(metadata, component) {
if (metadata.owners === null) {
return true;
}
return (
metadata.owners.has(component) ||
(metadata.parent !== null && has_owner(metadata.parent, component))
);
}
/**
* @param {ProxyMetadata} metadata
* @returns {any}
*/
function get_owner(metadata) {
return (
metadata?.owners?.values().next().value ??
get_owner(/** @type {ProxyMetadata} */ (metadata.parent))
);
}
/**
* @param {ProxyMetadata} metadata
*/
function check_ownership(metadata) {
const component = get_component();
if (component && !has_owner(metadata, component)) {
let original = get_owner(metadata);
// @ts-expect-error
if (original[FILENAME] !== component[FILENAME]) {
// @ts-expect-error
ownership_invalid_mutation(component[FILENAME], original[FILENAME]);
} else {
ownership_invalid_mutation();
}
}
}
/** @import { ComponentContext, Derived, Effect, Reaction, Signal, Source, Value } from '#client' */
// Used for DEV time error handling
/** @param {WeakSet<Error>} value */
const handled_errors = new WeakSet();
// Used for handling scheduling
let is_micro_task_queued = false;
let is_flushing_effect = false;
/** @param {boolean} value */
function set_is_flushing_effect(value) {
is_flushing_effect = value;
}
// Handle effect queues
/** @type {Effect[]} */
let queued_root_effects = [];
let flush_count = 0;
/** @type {Effect[]} Stack of effects, dev only */
let dev_effect_stack = [];
// Handle signal reactivity tree dependencies and reactions
/** @type {null | Reaction} */
let active_reaction = null;
/** @param {null | Reaction} reaction */
function set_active_reaction(reaction) {
active_reaction = reaction;
}
/** @type {null | Effect} */
let active_effect = null;
/** @param {null | Effect} effect */
function set_active_effect(effect) {
active_effect = effect;
}
/**
* When sources are created within a derived, we record them so that we can safely allow
* local mutations to these sources without the side-effect error being invoked unnecessarily.
* @type {null | Source[]}
*/
let derived_sources = null;
/**
* @param {Source[] | null} sources
*/
function set_derived_sources(sources) {
derived_sources = sources;
}
/**
* The dependencies of the reaction that is currently being executed. In many cases,
* the dependencies are unchanged between runs, and so this will be `null` unless
* and until a new dependency is accessed — we track this via `skipped_deps`
* @type {null | Value[]}
*/
let new_deps = null;
let skipped_deps = 0;
/**
* Tracks writes that the effect it's executed in doesn't listen to yet,
* so that the dependency can be added to the effect later on if it then reads it
* @type {null | Source[]}
*/
let untracked_writes = null;
/** @param {null | Source[]} value */
function set_untracked_writes(value) {
untracked_writes = value;
}
/** @type {number} Used by sources and deriveds for handling updates to unowned deriveds */
let current_version = 0;
// If we are working with a get() chain that has no active container,
// to prevent memory leaks, we skip adding the reaction.
let skip_reaction = false;
// Handling runtime component context
/** @type {ComponentContext | null} */
let component_context = null;
/**
* The current component function. Different from current component context:
* ```html
* <!-- App.svelte -->
* <Foo>
* <Bar /> <!-- context == Foo.svelte, function == App.svelte -->
* </Foo>
* ```
* @type {ComponentContext['function']}
*/
let dev_current_component_function = null;
function increment_version() {
return ++current_version;
}
/** @returns {boolean} */
function is_runes() {
return !legacy_mode_flag;
}
/**
* Determines whether a derived or effect is dirty.
* If it is MAYBE_DIRTY, will set the status to CLEAN
* @param {Reaction} reaction
* @returns {boolean}
*/
function check_dirtiness(reaction) {
var flags = reaction.f;
if ((flags & DIRTY) !== 0) {
return true;
}
if ((flags & MAYBE_DIRTY) !== 0) {
var dependencies = reaction.deps;
var is_unowned = (flags & UNOWNED) !== 0;
if (dependencies !== null) {
var i;
if ((flags & DISCONNECTED) !== 0) {
for (i = 0; i < dependencies.length; i++) {
(dependencies[i].reactions ??= []).push(reaction);
}
reaction.f ^= DISCONNECTED;
}
for (i = 0; i < dependencies.length; i++) {
var dependency = dependencies[i];
if (check_dirtiness(/** @type {Derived} */ (dependency))) {
update_derived(/** @type {Derived} */ (dependency));
}
// If we are working with an unowned signal as part of an effect (due to !skip_reaction)
// and the version hasn't changed, we still need to check that this reaction
// is linked to the dependency source – otherwise future updates will not be caught.
if (
is_unowned &&
active_effect !== null &&
!skip_reaction &&
!dependency?.reactions?.includes(reaction)
) {
(dependency.reactions ??= []).push(reaction);
}
if (dependency.version > reaction.version) {
return true;
}
}
}
// Unowned signals should never be marked as clean.
if (!is_unowned) {
set_signal_status(reaction, CLEAN);
}
}
return false;
}
/**
* @param {Error} error
* @param {Effect} effect
* @param {ComponentContext | null} component_context
*/
function handle_error(error, effect, component_context) {
// Given we don't yet have error boundaries, we will just always throw.
if (!DEV || handled_errors.has(error) || component_context === null) {
throw error;
}
const component_stack = [];
const effect_name = effect.fn?.name;
if (effect_name) {
component_stack.push(effect_name);
}
/** @type {ComponentContext | null} */
let current_context = component_context;
while (current_context !== null) {
if (DEV) {
/** @type {string} */
var filename = current_context.function?.[FILENAME];
if (filename) {
const file = filename.split('/').pop();
component_stack.push(file);
}
}
current_context = current_context.p;
}
const indent = /Firefox/.test(navigator.userAgent) ? ' ' : '\t';
define_property(error, 'message', {
value: error.message + `\n${component_stack.map((name) => `\n${indent}in ${name}`).join('')}\n`
});
const stack = error.stack;
// Filter out internal files from callstack
if (stack) {
const lines = stack.split('\n');
const new_lines = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.includes('svelte/src/internal')) {
continue;
}
new_lines.push(line);
}
define_property(error, 'stack', {
value: error.stack + new_lines.join('\n')
});
}
handled_errors.add(error);
throw error;
}
/**
* @template V
* @param {Reaction} reaction
* @returns {V}
*/
function update_reaction(reaction) {
var previous_deps = new_deps;
var previous_skipped_deps = skipped_deps;
var previous_untracked_writes = untracked_writes;
var previous_reaction = active_reaction;
var previous_skip_reaction = skip_reaction;
var prev_derived_sources = derived_sources;
var previous_component_context = component_context;
var flags = reaction.f;
new_deps = /** @type {null | Value[]} */ (null);
skipped_deps = 0;
untracked_writes = null;
active_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null;
skip_reaction = !is_flushing_effect && (flags & UNOWNED) !== 0;
derived_sources = null;
component_context = reaction.ctx;
try {
var result = /** @type {Function} */ (0, reaction.fn)();
var deps = reaction.deps;
if (new_deps !== null) {
var i;
remove_reactions(reaction, skipped_deps);
if (deps !== null && skipped_deps > 0) {
deps.length = skipped_deps + new_deps.length;
for (i = 0; i < new_deps.length; i++) {
deps[skipped_deps + i] = new_deps[i];
}
} else {
reaction.deps = deps = new_deps;
}
if (!skip_reaction) {
for (i = skipped_deps; i < deps.length; i++) {
(deps[i].reactions ??= []).push(reaction);
}
}
} else if (deps !== null && skipped_deps < deps.length) {
remove_reactions(reaction, skipped_deps);
deps.length = skipped_deps;
}
return result;
} finally {
new_deps = previous_deps;
skipped_deps = previous_skipped_deps;
untracked_writes = previous_untracked_writes;
active_reaction = previous_reaction;
skip_reaction = previous_skip_reaction;
derived_sources = prev_derived_sources;
component_context = previous_component_context;
}
}
/**
* @template V
* @param {Reaction} signal
* @param {Value<V>} dependency
* @returns {void}
*/
function remove_reaction(signal, dependency) {
let reactions = dependency.reactions;
if (reactions !== null) {
var index = reactions.indexOf(signal);
if (index !== -1) {
var new_length = reactions.length - 1;
if (new_length === 0) {
reactions = dependency.reactions = null;
} else {
// Swap with last element and then remove.
reactions[index] = reactions[new_length];
reactions.pop();
}
}
}
// If the derived has no reactions, then we can disconnect it from the graph,
// allowing it to either reconnect in the future, or be GC'd by the VM.
if (
reactions === null &&
(dependency.f & DERIVED) !== 0 &&
// Destroying a child effect while updating a parent effect can cause a dependency to appear
// to be unused, when in fact it is used by the currently-updating parent. Checking `new_deps`
// allows us to skip the expensive work of disconnecting and immediately reconnecting it
(new_deps === null || !new_deps.includes(dependency))
) {
set_signal_status(dependency, MAYBE_DIRTY);
// If we are working with a derived that is owned by an effect, then mark it as being
// disconnected.
if ((dependency.f & (UNOWNED | DISCONNECTED)) === 0) {
dependency.f ^= DISCONNECTED;
}
remove_reactions(/** @type {Derived} **/ (dependency), 0);
}
}
/**
* @param {Reaction} signal
* @param {number} start_index
* @returns {void}
*/
function remove_reactions(signal, start_index) {
var dependencies = signal.deps;
if (dependencies === null) return;
for (var i = start_index; i < dependencies.length; i++) {
remove_reaction(signal, dependencies[i]);
}
}
/**
* @param {Effect} effect
* @returns {void}
*/
function update_effect(effect) {
var flags = effect.f;
if ((flags & DESTROYED) !== 0) {
return;
}
set_signal_status(effect, CLEAN);
var previous_effect = active_effect;
var previous_component_context = component_context;
active_effect = effect;
if (DEV) {
var previous_component_fn = dev_current_component_function;
dev_current_component_function = effect.component_function;
}
try {
if ((flags & BLOCK_EFFECT) !== 0) {
destroy_block_effect_children(effect);
} else {
destroy_effect_children(effect);
}
destroy_effect_deriveds(effect);
execute_effect_teardown(effect);
var teardown = update_reaction(effect);
effect.teardown = typeof teardown === 'function' ? teardown : null;
effect.version = current_version;
if (DEV) {
dev_effect_stack.push(effect);
}
} catch (error) {
handle_error(/** @type {Error} */ (error), effect, previous_component_context);
} finally {
active_effect = previous_effect;
if (DEV) {
dev_current_component_function = previous_component_fn;
}
}
}
function infinite_loop_guard() {
if (flush_count > 1000) {
flush_count = 0;
if (DEV) {
try {
effect_update_depth_exceeded();
} catch (error) {
// stack is garbage, ignore. Instead add a console.error message.
define_property(error, 'stack', {
value: ''
});
// eslint-disable-next-line no-console
console.error(
'Last ten effects were: ',
dev_effect_stack.slice(-10).map((d) => d.fn)
);
dev_effect_stack = [];
throw error;
}
} else {
effect_update_depth_exceeded();
}
}
flush_count++;
}
/**
* @param {Array<Effect>} root_effects
* @returns {void}
*/
function flush_queued_root_effects(root_effects) {
var length = root_effects.length;
if (length === 0) {
return;
}
infinite_loop_guard();
var previously_flushing_effect = is_flushing_effect;
is_flushing_effect = true;
try {
for (var i = 0; i < length; i++) {
var effect = root_effects[i];
if ((effect.f & CLEAN) === 0) {
effect.f ^= CLEAN;
}
/** @type {Effect[]} */
var collected_effects = [];
process_effects(effect, collected_effects);
flush_queued_effects(collected_effects);
}
} finally {
is_flushing_effect = previously_flushing_effect;
}
}
/**
* @param {Array<Effect>} effects
* @returns {void}
*/
function flush_queued_effects(effects) {
var length = effects.length;
if (length === 0) return;
for (var i = 0; i < length; i++) {
var effect = effects[i];
if ((effect.f & (DESTROYED | INERT)) === 0 && check_dirtiness(effect)) {
update_effect(effect);
// Effects with no dependencies or teardown do not get added to the effect tree.
// Deferred effects (e.g. `$effect(...)`) _are_ added to the tree because we
// don't know if we need to keep them until they are executed. Doing the check
// here (rather than in `update_effect`) allows us to skip the work for
// immediate effects.
if (effect.deps === null && effect.first === null && effect.nodes_start === null) {
if (effect.teardown === null) {
// remove this effect from the graph
unlink_effect(effect);
} else {
// keep the effect in the graph, but free up some memory
effect.fn = null;
}
}
}
}
}
function process_deferred() {
is_micro_task_queued = false;
if (flush_count > 1001) {
return;
}
const previous_queued_root_effects = queued_root_effects;
queued_root_effects = [];
flush_queued_root_effects(previous_queued_root_effects);
if (!is_micro_task_queued) {
flush_count = 0;
if (DEV) {
dev_effect_stack = [];
}
}
}
/**
* @param {Effect} signal
* @returns {void}
*/
function schedule_effect(signal) {
{
if (!is_micro_task_queued) {
is_micro_task_queued = true;
queueMicrotask(process_deferred);
}
}
var effect = signal;
while (effect.parent !== null) {
effect = effect.parent;
var flags = effect.f;
if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {
if ((flags & CLEAN) === 0) return;
effect.f ^= CLEAN;
}
}
queued_root_effects.push(effect);
}
/**
*
* This function both runs render effects and collects user 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 effects array will be populated with all the user
* effects to be flushed.
*
* @param {Effect} effect
* @param {Effect[]} collected_effects
* @returns {void}
*/
function process_effects(effect, collected_effects) {
var current_effect = effect.first;
var effects = [];
main_loop: while (current_effect !== null) {
var flags = current_effect.f;
var is_branch = (flags & BRANCH_EFFECT) !== 0;
var is_skippable_branch = is_branch && (flags & CLEAN) !== 0;
if (!is_skippable_branch && (flags & INERT) === 0) {
if ((flags & RENDER_EFFECT) !== 0) {
if (is_branch) {
current_effect.f ^= CLEAN;
} else if (check_dirtiness(current_effect)) {
update_effect(current_effect);
}
var child = current_effect.first;
if (child !== null) {
current_effect = child;
continue;
}
} else if ((flags & EFFECT) !== 0) {
effects.push(current_effect);
}
}
var sibling = current_effect.next;
if (sibling === null) {
let parent = current_effect.parent;
while (parent !== null) {
if (effect === parent) {
break main_loop;
}
var parent_sibling = parent.next;
if (parent_sibling !== null) {
current_effect = parent_sibling;
continue main_loop;
}
parent = parent.parent;
}
}
current_effect = sibling;
}
// We might be dealing with many effects here, far more than can be spread into
// an array push call (callstack overflow). So let's deal with each effect in a loop.
for (var i = 0; i < effects.length; i++) {
child = effects[i];
collected_effects.push(child);
process_effects(child, collected_effects);
}
}
/**
* @template V
* @param {Value<V>} signal
* @returns {V}
*/
function get(signal) {
var flags = signal.f;
var is_derived = (flags & DERIVED) !== 0;
// If the derived is destroyed, just execute it again without retaining
// its memoisation properties as the derived is stale
if (is_derived && (flags & DESTROYED) !== 0) {
var value = execute_derived(/** @type {Derived} */ (signal));
// Ensure the derived remains destroyed
destroy_derived(/** @type {Derived} */ (signal));
return value;
}
// Register the dependency on the current reaction signal.
if (active_reaction !== null) {
if (derived_sources !== null && derived_sources.includes(signal)) {
state_unsafe_local_read();
}
var deps = active_reaction.deps;
// If the signal is accessing the same dependencies in the same
// order as it did last time, increment `skipped_deps`
// rather than updating `new_deps`, which creates GC cost
if (new_deps === null && deps !== null && deps[skipped_deps] === signal) {
skipped_deps++;
} else if (new_deps === null) {
new_deps = [signal];
} else {
new_deps.push(signal);
}
if (
untracked_writes !== null &&
active_effect !== null &&
(active_effect.f & CLEAN) !== 0 &&
(active_effect.f & BRANCH_EFFECT) === 0 &&
untracked_writes.includes(signal)
) {
set_signal_status(active_effect, DIRTY);
schedule_effect(active_effect);
}
} else if (is_derived && /** @type {Derived} */ (signal).deps === null) {
var derived = /** @type {Derived} */ (signal);
var parent = derived.parent;
var target = derived;
while (parent !== null) {
// Attach the derived to the nearest parent effect, if there are deriveds
// in between then we also need to attach them too
if ((parent.f & DERIVED) !== 0) {
var parent_derived = /** @type {Derived} */ (parent);
target = parent_derived;
parent = parent_derived.parent;
} else {
var parent_effect = /** @type {Effect} */ (parent);
if (!parent_effect.deriveds?.includes(target)) {
(parent_effect.deriveds ??= []).push(target);
}
break;
}
}
}
if (is_derived) {
derived = /** @type {Derived} */ (signal);
if (check_dirtiness(derived)) {
update_derived(derived);
}
}
return signal.v;
}
const STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);
/**
* @param {Signal} signal
* @param {number} status
* @returns {void}
*/
function set_signal_status(signal, status) {
signal.f = (signal.f & STATUS_MASK) | status;
}
/**
* @param {Record<string, unknown>} props
* @param {any} runes
* @param {Function} [fn]
* @returns {void}
*/
function push(props, runes = false, fn) {
component_context = {
p: component_context,
c: null,
e: null,
m: false,
s: props,
x: null,
l: