Comparing version 5.0.5 to 5.1.0
@@ -5,3 +5,3 @@ { | ||
"license": "MIT", | ||
"version": "5.0.5", | ||
"version": "5.1.0", | ||
"type": "module", | ||
@@ -8,0 +8,0 @@ "types": "./types/index.d.ts", |
@@ -13,5 +13,5 @@ [![Cybernetically enhanced web apps: Svelte](https://sveltejs.github.io/assets/banner.png)](https://svelte.dev) | ||
You can play around with Svelte in the [tutorial](https://learn.svelte.dev/), [examples](https://svelte.dev/examples), and [REPL](https://svelte.dev/repl). | ||
You can play around with Svelte in the [tutorial](https://svelte.dev/tutorial), [examples](https://svelte.dev/examples), and [REPL](https://svelte.dev/repl). | ||
When you're ready to build a full-fledge application, we recommend using [SvelteKit](https://kit.svelte.dev): | ||
When you're ready to build a full-fledge application, we recommend using [SvelteKit](https://svelte.dev/docs/kit): | ||
@@ -25,3 +25,3 @@ ```bash | ||
See [the SvelteKit documentation](https://kit.svelte.dev/docs) to learn more. | ||
See [the SvelteKit documentation](https://svelte.dev/docs/kit) to learn more. | ||
@@ -28,0 +28,0 @@ ## Changelog |
@@ -28,2 +28,11 @@ /** @import { VariableDeclarator, Node, Identifier, AssignmentExpression, LabeledStatement, ExpressionStatement } from 'estree' */ | ||
class MigrationError extends Error { | ||
/** | ||
* @param {string} msg | ||
*/ | ||
constructor(msg) { | ||
super(msg); | ||
} | ||
} | ||
/** | ||
@@ -109,3 +118,6 @@ * Does a best-effort migration of Svelte code towards using runes, event attributes and render tags. | ||
derived_labeled_statements: new Set(), | ||
has_svelte_self: false | ||
has_svelte_self: false, | ||
uses_ts: !!parsed.instance?.attributes.some( | ||
(attr) => attr.name === 'lang' && /** @type {any} */ (attr).value[0].data === 'ts' | ||
) | ||
}; | ||
@@ -203,5 +215,2 @@ | ||
} else { | ||
const uses_ts = parsed.instance?.attributes.some( | ||
(attr) => attr.name === 'lang' && /** @type {any} */ (attr).value[0].data === 'ts' | ||
); | ||
const type_name = state.scope.root.unique('Props').name; | ||
@@ -212,3 +221,3 @@ let type = ''; | ||
if (state.has_type_or_fallback || state.props.every((prop) => prop.slot_name)) { | ||
if (uses_ts) { | ||
if (state.uses_ts) { | ||
type = `interface ${type_name} {${newline_separator}${state.props | ||
@@ -234,3 +243,3 @@ .map((prop) => { | ||
let props_declaration = `let {${props_separator}${props}${has_many_props ? `\n${indent}` : ' '}}`; | ||
if (uses_ts) { | ||
if (state.uses_ts) { | ||
if (type) { | ||
@@ -318,4 +327,6 @@ props_declaration = `${type}\n\n${indent}${props_declaration}`; | ||
} catch (e) { | ||
// eslint-disable-next-line no-console | ||
console.error('Error while migrating Svelte code', e); | ||
if (!(e instanceof MigrationError)) { | ||
// eslint-disable-next-line no-console | ||
console.error('Error while migrating Svelte code', e); | ||
} | ||
has_migration_task = true; | ||
@@ -353,2 +364,3 @@ return { | ||
* has_svelte_self: boolean; | ||
* uses_ts: boolean; | ||
* }} State | ||
@@ -408,3 +420,3 @@ */ | ||
if (illegal_specifiers.length > 0) { | ||
throw new Error( | ||
throw new MigrationError( | ||
`Can't migrate code with ${illegal_specifiers.join(' and ')}. Please migrate by hand.` | ||
@@ -473,3 +485,3 @@ ); | ||
// TODO invest time in this? | ||
throw new Error( | ||
throw new MigrationError( | ||
'Encountered an export declaration pattern that is not supported for automigration.' | ||
@@ -505,3 +517,3 @@ ); | ||
if (state.analysis.uses_props && (declarator.init || binding.updated)) { | ||
throw new Error( | ||
throw new MigrationError( | ||
'$$props is used together with named props in a way that cannot be automatically migrated.' | ||
@@ -1078,3 +1090,3 @@ ); | ||
if (name !== slot_name) { | ||
throw new Error( | ||
throw new MigrationError( | ||
'This migration would change the name of a slot making the component unusable' | ||
@@ -1155,2 +1167,6 @@ ); | ||
snippet_name = attribute.value[0].data; | ||
// the default slot in svelte 4 if what the children slot is for svelte 5 | ||
if (snippet_name === 'default') { | ||
snippet_name = 'children'; | ||
} | ||
if (!regex_is_valid_identifier.test(snippet_name)) { | ||
@@ -1319,3 +1335,3 @@ has_migration_task = true; | ||
let cleaned_comment = comment | ||
let cleaned_comment_arr = comment | ||
?.split('\n') | ||
@@ -1335,5 +1351,5 @@ .map((line) => | ||
.filter(Boolean); | ||
const first_at_comment = cleaned_comment?.findIndex((line) => line.startsWith('@')); | ||
comment = cleaned_comment | ||
?.slice(0, first_at_comment !== -1 ? first_at_comment : cleaned_comment.length) | ||
const first_at_comment = cleaned_comment_arr?.findIndex((line) => line.startsWith('@')); | ||
let cleaned_comment = cleaned_comment_arr | ||
?.slice(0, first_at_comment !== -1 ? first_at_comment : cleaned_comment_arr.length) | ||
.join('\n'); | ||
@@ -1346,3 +1362,3 @@ | ||
if (match) { | ||
return { type: match[1], comment }; | ||
return { type: match[1], comment: cleaned_comment }; | ||
} | ||
@@ -1356,7 +1372,7 @@ } | ||
if (type === 'string' || type === 'number' || type === 'boolean') { | ||
return { type, comment }; | ||
return { type, comment: state.uses_ts ? comment : cleaned_comment }; | ||
} | ||
} | ||
return { type: 'any', comment }; | ||
return { type: 'any', comment: state.uses_ts ? comment : cleaned_comment }; | ||
} | ||
@@ -1539,3 +1555,3 @@ | ||
if (new_name !== name) { | ||
throw new Error( | ||
throw new MigrationError( | ||
'This migration would change the name of a slot making the component unusable' | ||
@@ -1542,0 +1558,0 @@ ); |
@@ -130,4 +130,3 @@ /** @import { Visitors } from 'zimmerframe' */ | ||
element, | ||
context.state.stylesheet, | ||
true | ||
context.state.stylesheet | ||
) | ||
@@ -148,4 +147,3 @@ ) { | ||
context.state.element, | ||
context.state.stylesheet, | ||
true | ||
context.state.stylesheet | ||
) | ||
@@ -196,6 +194,5 @@ ) { | ||
* @param {Compiler.Css.StyleSheet} stylesheet | ||
* @param {boolean} check_has Whether or not to check the `:has(...)` selectors | ||
* @returns {boolean} | ||
*/ | ||
function apply_selector(relative_selectors, rule, element, stylesheet, check_has) { | ||
function apply_selector(relative_selectors, rule, element, stylesheet) { | ||
const parent_selectors = relative_selectors.slice(); | ||
@@ -208,13 +205,7 @@ const relative_selector = parent_selectors.pop(); | ||
relative_selector, | ||
parent_selectors, | ||
rule, | ||
element, | ||
stylesheet, | ||
check_has | ||
stylesheet | ||
); | ||
if (possible_match === 'definite_match') { | ||
return true; | ||
} | ||
if (!possible_match) { | ||
@@ -231,4 +222,3 @@ return false; | ||
element, | ||
stylesheet, | ||
check_has | ||
stylesheet | ||
); | ||
@@ -254,3 +244,2 @@ } | ||
* @param {Compiler.Css.StyleSheet} stylesheet | ||
* @param {boolean} check_has Whether or not to check the `:has(...)` selectors | ||
* @returns {boolean} | ||
@@ -264,4 +253,3 @@ */ | ||
element, | ||
stylesheet, | ||
check_has | ||
stylesheet | ||
) { | ||
@@ -291,3 +279,3 @@ const name = combinator.name; | ||
if (parent.type === 'RegularElement' || parent.type === 'SvelteElement') { | ||
if (apply_selector(parent_selectors, rule, parent, stylesheet, check_has)) { | ||
if (apply_selector(parent_selectors, rule, parent, stylesheet)) { | ||
// TODO the `name === ' '` causes false positives, but removing it causes false negatives... | ||
@@ -323,5 +311,3 @@ if (name === ' ' || crossed_component_boundary) { | ||
} | ||
} else if ( | ||
apply_selector(parent_selectors, rule, possible_sibling, stylesheet, check_has) | ||
) { | ||
} else if (apply_selector(parent_selectors, rule, possible_sibling, stylesheet)) { | ||
mark(relative_selector, element); | ||
@@ -405,17 +391,8 @@ sibling_matched = true; | ||
* @param {Compiler.Css.RelativeSelector} relative_selector | ||
* @param {Compiler.Css.RelativeSelector[]} parent_selectors | ||
* @param {Compiler.Css.Rule} rule | ||
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement} element | ||
* @param {Compiler.Css.StyleSheet} stylesheet | ||
* @param {boolean} check_has Whether or not to check the `:has(...)` selectors | ||
* @returns {boolean | 'definite_match'} | ||
* @returns {boolean } | ||
*/ | ||
function relative_selector_might_apply_to_node( | ||
relative_selector, | ||
parent_selectors, | ||
rule, | ||
element, | ||
stylesheet, | ||
check_has | ||
) { | ||
function relative_selector_might_apply_to_node(relative_selector, rule, element, stylesheet) { | ||
// Sort :has(...) selectors in one bucket and everything else into another | ||
@@ -435,3 +412,22 @@ const has_selectors = []; | ||
// In that case ignore this check (because we just came from this) to avoid an infinite loop. | ||
if (check_has && has_selectors.length > 0) { | ||
if (has_selectors.length > 0) { | ||
/** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */ | ||
const child_elements = []; | ||
/** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */ | ||
const descendant_elements = []; | ||
/** | ||
* @param {Compiler.SvelteNode} node | ||
* @param {boolean} is_recursing | ||
*/ | ||
function collect_child_elements(node, is_recursing) { | ||
if (node.type === 'RegularElement' || node.type === 'SvelteElement') { | ||
descendant_elements.push(node); | ||
if (!is_recursing) child_elements.push(node); | ||
node.fragment.nodes.forEach((node) => collect_child_elements(node, true)); | ||
} | ||
} | ||
element.fragment.nodes.forEach((node) => collect_child_elements(node, false)); | ||
// :has(...) is special in that it means "look downwards in the CSS tree". Since our matching algorithm goes | ||
@@ -457,21 +453,16 @@ // upwards and back-to-front, we need to first check the selectors inside :has(...), then check the rest of the | ||
if ( | ||
selectors.length === 0 /* is :global(...) */ || | ||
apply_selector(selectors, rule, element, stylesheet, check_has) | ||
) { | ||
// Treat e.g. `.x:has(.y)` as `.x .y` with the .y part already being matched, | ||
// and now looking upwards for the .x part. | ||
const descendants = | ||
left_most_combinator.name === '>' ? child_elements : descendant_elements; | ||
let selector_matched = false; | ||
// Iterate over all descendant elements and check if the selector inside :has matches | ||
for (const element of descendants) { | ||
if ( | ||
apply_combinator( | ||
left_most_combinator, | ||
selectors[0] ?? [], | ||
[...parent_selectors, relative_selector], | ||
rule, | ||
element, | ||
stylesheet, | ||
false | ||
) | ||
selectors.length === 0 /* is :global(...) */ || | ||
(element.metadata.scoped && selector_matched) || | ||
apply_selector(selectors, rule, element, stylesheet) | ||
) { | ||
complex_selector.metadata.used = true; | ||
matched = true; | ||
selector_matched = matched = true; | ||
} | ||
@@ -499,5 +490,2 @@ } | ||
} | ||
// We return this to signal the parent "don't bother checking the rest of the selectors, I already did that" | ||
return 'definite_match'; | ||
} | ||
@@ -523,3 +511,3 @@ | ||
const complex_selector = args.children[0]; | ||
return apply_selector(complex_selector.children, rule, element, stylesheet, check_has); | ||
return apply_selector(complex_selector.children, rule, element, stylesheet); | ||
} | ||
@@ -537,3 +525,3 @@ | ||
relative.length === 0 /* is :global(...) */ || | ||
apply_selector(relative, rule, element, stylesheet, check_has) | ||
apply_selector(relative, rule, element, stylesheet) | ||
) { | ||
@@ -639,3 +627,3 @@ complex_selector.metadata.used = true; | ||
for (const complex_selector of parent.prelude.children) { | ||
if (apply_selector(truncate(complex_selector), parent, element, stylesheet, check_has)) { | ||
if (apply_selector(truncate(complex_selector), parent, element, stylesheet)) { | ||
complex_selector.metadata.used = true; | ||
@@ -642,0 +630,0 @@ matched = true; |
@@ -80,3 +80,5 @@ /** @import { AST } from '#compiler' */ | ||
node.attributes.some( | ||
(attribute) => attribute.type === 'Attribute' && attribute.name === 'autofocus' | ||
(attribute) => | ||
attribute.type === 'Attribute' && | ||
(attribute.name === 'autofocus' || attribute.name === 'muted') | ||
) | ||
@@ -83,0 +85,0 @@ ) { |
@@ -222,3 +222,4 @@ /** @import { Expression, ExpressionStatement, Identifier, MemberExpression, ObjectExpression, Statement } from 'estree' */ | ||
(node.metadata.svg || node.metadata.mathml || is_custom_element_node(node)) && b.true, | ||
node.name.includes('-') && b.true | ||
node.name.includes('-') && b.true, | ||
context.state | ||
); | ||
@@ -267,2 +268,3 @@ | ||
attribute.name !== 'autofocus' && | ||
attribute.name !== 'muted' && | ||
(attribute.value === true || is_text_attribute(attribute)) | ||
@@ -535,2 +537,8 @@ ) { | ||
// Special case for Firefox who needs it set as a property in order to work | ||
if (name === 'muted') { | ||
state.init.push(b.stmt(b.assignment('=', b.member(node_id, b.id('muted')), value))); | ||
return false; | ||
} | ||
/** @type {Statement} */ | ||
@@ -537,0 +545,0 @@ let update; |
/** @import { Expression, Identifier, ObjectExpression } from 'estree' */ | ||
/** @import { AST, Namespace } from '#compiler' */ | ||
/** @import { ComponentContext } from '../../types' */ | ||
/** @import { ComponentClientTransformState, ComponentContext } from '../../types' */ | ||
import { normalize_attribute } from '../../../../../../utils.js'; | ||
@@ -19,2 +19,3 @@ import { is_ignored } from '../../../../../state.js'; | ||
* @param {false | Expression} is_custom_element | ||
* @param {ComponentClientTransformState} state | ||
*/ | ||
@@ -28,5 +29,5 @@ export function build_set_attributes( | ||
preserve_attribute_case, | ||
is_custom_element | ||
is_custom_element, | ||
state | ||
) { | ||
let needs_isolation = false; | ||
let has_state = false; | ||
@@ -55,8 +56,13 @@ | ||
} else { | ||
values.push(b.spread(/** @type {Expression} */ (context.visit(attribute)))); | ||
// objects could contain reactive getters -> play it safe and always assume spread attributes are reactive | ||
has_state = true; | ||
needs_isolation ||= attribute.metadata.expression.has_call; | ||
let value = /** @type {Expression} */ (context.visit(attribute)); | ||
if (attribute.metadata.expression.has_call) { | ||
const id = b.id(state.scope.generate('spread_with_call')); | ||
state.init.push(b.const(id, create_derived(state, b.thunk(value)))); | ||
value = b.call('$.get', id); | ||
} | ||
values.push(b.spread(value)); | ||
} | ||
@@ -78,10 +84,3 @@ } | ||
context.state.init.push(b.let(attributes_id)); | ||
const update = b.stmt(b.assignment('=', attributes_id, call)); | ||
if (needs_isolation) { | ||
context.state.init.push(build_update(update)); | ||
return false; | ||
} | ||
context.state.update.push(update); | ||
@@ -88,0 +87,0 @@ return true; |
@@ -145,3 +145,3 @@ /** @import { Expression } from 'estree' */ | ||
if (attribute.name === 'autofocus') { | ||
if (attribute.name === 'autofocus' || attribute.name === 'muted') { | ||
return false; | ||
@@ -148,0 +148,0 @@ } |
@@ -105,3 +105,4 @@ /** @import { BlockStatement, Expression, ExpressionStatement, Identifier, ObjectExpression, Statement } from 'estree' */ | ||
b.binary('!==', b.member(element_id, 'namespaceURI'), b.id('$.NAMESPACE_SVG')), | ||
b.call(b.member(b.member(element_id, 'nodeName'), 'includes'), b.literal('-')) | ||
b.call(b.member(b.member(element_id, 'nodeName'), 'includes'), b.literal('-')), | ||
context.state | ||
); | ||
@@ -108,0 +109,0 @@ } |
@@ -213,5 +213,7 @@ // This should contain all the public interfaces (not all of them are actually importable, check current Svelte for which ones are). | ||
* // Errors if these aren't the correct props expected by MyComponent. | ||
* const props: ComponentProps<MyComponent> = { foo: 'bar' }; | ||
* const props: ComponentProps<typeof MyComponent> = { foo: 'bar' }; | ||
* ``` | ||
* | ||
* > [!NOTE] In Svelte 4, you would do `ComponentProps<MyComponent>` because `MyComponent` was a class. | ||
* | ||
* Example: A generic function that accepts some component and infers the type of its props: | ||
@@ -313,2 +315,42 @@ * | ||
/** | ||
* Defines the options accepted by the `mount()` function. | ||
*/ | ||
export type MountOptions<Props extends Record<string, any> = Record<string, any>> = { | ||
/** | ||
* Target element where the component will be mounted. | ||
*/ | ||
target: Document | Element | ShadowRoot; | ||
/** | ||
* Optional node inside `target`. When specified, it is used to render the component immediately before it. | ||
*/ | ||
anchor?: Node; | ||
/** | ||
* Allows the specification of events. | ||
* @deprecated Use callback props instead. | ||
*/ | ||
events?: Record<string, (e: any) => any>; | ||
/** | ||
* Can be accessed via `getContext()` at the component level. | ||
*/ | ||
context?: Map<any, any>; | ||
/** | ||
* Whether or not to play transitions on initial render. | ||
* @default true | ||
*/ | ||
intro?: boolean; | ||
} & ({} extends Props | ||
? { | ||
/** | ||
* Component properties. | ||
*/ | ||
props?: Props; | ||
} | ||
: { | ||
/** | ||
* Component properties. | ||
*/ | ||
props: Props; | ||
}); | ||
export * from './index-client.js'; |
@@ -317,3 +317,3 @@ /** @import { Location } from 'locate-character' */ | ||
handler.apply(element, args); | ||
} else if (has_side_effects || handler != null) { | ||
} else if (has_side_effects || handler != null || error) { | ||
const filename = component?.[FILENAME]; | ||
@@ -320,0 +320,0 @@ const location = loc ? ` at ${filename}:${loc[0]}:${loc[1]}` : ` in ${filename}`; |
/** @import { AnimateFn, Animation, AnimationConfig, EachItem, Effect, TransitionFn, TransitionManager } from '#client' */ | ||
import { noop, is_function } from '../../../shared/utils.js'; | ||
import { effect } from '../../reactivity/effects.js'; | ||
import { active_effect, untrack } from '../../runtime.js'; | ||
import { | ||
active_effect, | ||
active_reaction, | ||
set_active_effect, | ||
set_active_reaction, | ||
untrack | ||
} from '../../runtime.js'; | ||
import { loop } from '../../loop.js'; | ||
@@ -22,6 +28,14 @@ import { should_intro } from '../../render.js'; | ||
/** | ||
* Converts a property to the camel-case format expected by Element.animate(), KeyframeEffect(), and KeyframeEffect.setKeyframes(). | ||
* @param {string} style | ||
* @returns {string} | ||
*/ | ||
function css_style_from_camel_case(style) { | ||
function css_property_to_camelcase(style) { | ||
// in compliance with spec | ||
if (style === 'float') return 'cssFloat'; | ||
if (style === 'offset') return 'cssOffset'; | ||
// do not rename custom @properties | ||
if (style.startsWith('--')) return style; | ||
const parts = style.split('-'); | ||
@@ -50,3 +64,3 @@ if (parts.length === 1) return parts[0]; | ||
const formatted_property = css_style_from_camel_case(property.trim()); | ||
const formatted_property = css_property_to_camelcase(property.trim()); | ||
keyframe[formatted_property] = value.trim(); | ||
@@ -190,8 +204,17 @@ } | ||
function get_options() { | ||
// If a transition is still ongoing, we use the existing options rather than generating | ||
// new ones. This ensures that reversible transitions reverse smoothly, rather than | ||
// jumping to a new spot because (for example) a different `duration` was used | ||
return (current_options ??= get_fn()(element, get_params?.() ?? /** @type {P} */ ({}), { | ||
direction | ||
})); | ||
var previous_reaction = active_reaction; | ||
var previous_effect = active_effect; | ||
set_active_reaction(null); | ||
set_active_effect(null); | ||
try { | ||
// If a transition is still ongoing, we use the existing options rather than generating | ||
// new ones. This ensures that reversible transitions reverse smoothly, rather than | ||
// jumping to a new spot because (for example) a different `duration` was used | ||
return (current_options ??= get_fn()(element, get_params?.() ?? /** @type {P} */ ({}), { | ||
direction | ||
})); | ||
} finally { | ||
set_active_reaction(previous_reaction); | ||
set_active_effect(previous_effect); | ||
} | ||
} | ||
@@ -198,0 +221,0 @@ |
@@ -20,3 +20,4 @@ /** @import { Derived, Effect } from '#client' */ | ||
increment_version, | ||
set_active_effect | ||
set_active_effect, | ||
component_context | ||
} from '../runtime.js'; | ||
@@ -48,2 +49,3 @@ import { equals, safe_equals } from './equality.js'; | ||
children: null, | ||
ctx: component_context, | ||
deps: null, | ||
@@ -174,3 +176,3 @@ equals, | ||
// TODO we need to ensure we remove the derived from any parent derives | ||
signal.v = signal.children = signal.deps = signal.reactions = null; | ||
signal.v = signal.children = signal.deps = signal.ctx = signal.reactions = null; | ||
} |
@@ -20,2 +20,4 @@ import type { ComponentContext, Dom, Equals, TemplateNode, TransitionManager } from '#client'; | ||
export interface Reaction extends Signal { | ||
/** The associated component context */ | ||
ctx: null | ComponentContext; | ||
/** The reaction function */ | ||
@@ -44,4 +46,2 @@ fn: null | Function; | ||
nodes_end: null | TemplateNode; | ||
/** The associated component context */ | ||
ctx: null | ComponentContext; | ||
/** Reactions created inside this signal */ | ||
@@ -48,0 +48,0 @@ deriveds: null | Derived[]; |
/** @import { ComponentContext, Effect, TemplateNode } from '#client' */ | ||
/** @import { Component, ComponentType, SvelteComponent } from '../../index.js' */ | ||
/** @import { Component, ComponentType, SvelteComponent, MountOptions } from '../../index.js' */ | ||
import { DEV } from 'esm-env'; | ||
@@ -68,17 +68,3 @@ import { | ||
* @param {ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>} component | ||
* @param {{} extends Props ? { | ||
* target: Document | Element | ShadowRoot; | ||
* anchor?: Node; | ||
* props?: Props; | ||
* events?: Record<string, (e: any) => any>; | ||
* context?: Map<any, any>; | ||
* intro?: boolean; | ||
* }: { | ||
* target: Document | Element | ShadowRoot; | ||
* props: Props; | ||
* anchor?: Node; | ||
* events?: Record<string, (e: any) => any>; | ||
* context?: Map<any, any>; | ||
* intro?: boolean; | ||
* }} options | ||
* @param {MountOptions<Props>} options | ||
* @returns {Exports} | ||
@@ -179,10 +165,3 @@ */ | ||
* @param {ComponentType<SvelteComponent<any>> | Component<any>} Component | ||
* @param {{ | ||
* target: Document | Element | ShadowRoot; | ||
* anchor?: Node; | ||
* props?: any; | ||
* events?: any; | ||
* context?: Map<any, any>; | ||
* intro?: boolean; | ||
* }} options | ||
* @param {MountOptions} options | ||
* @returns {Exports} | ||
@@ -189,0 +168,0 @@ */ |
@@ -305,2 +305,3 @@ /** @import { ComponentContext, Derived, Effect, Reaction, Signal, Source, Value } from '#client' */ | ||
var prev_derived_sources = derived_sources; | ||
var previous_component_context = component_context; | ||
var flags = reaction.f; | ||
@@ -314,2 +315,3 @@ | ||
derived_sources = null; | ||
component_context = reaction.ctx; | ||
@@ -352,2 +354,3 @@ try { | ||
derived_sources = prev_derived_sources; | ||
component_context = previous_component_context; | ||
} | ||
@@ -428,3 +431,2 @@ } | ||
active_effect = effect; | ||
component_context = effect.ctx; | ||
@@ -456,3 +458,2 @@ if (DEV) { | ||
active_effect = previous_effect; | ||
component_context = previous_component_context; | ||
@@ -459,0 +460,0 @@ if (DEV) { |
@@ -103,7 +103,8 @@ /* This file is generated by scripts/process-messages/index.js. Do not edit! */ | ||
/** | ||
* Detected a migrated `$:` reactive block that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`. | ||
* Detected a migrated `$:` reactive block in `%filename%` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`. | ||
* @param {string} filename | ||
*/ | ||
export function legacy_recursive_reactive_block() { | ||
export function legacy_recursive_reactive_block(filename) { | ||
if (DEV) { | ||
console.warn(`%c[svelte] legacy_recursive_reactive_block\n%cDetected a migrated \`$:\` reactive block that both accesses and updates the same reactive value. This may cause recursive updates when converted to an \`$effect\`.`, bold, normal); | ||
console.warn(`%c[svelte] legacy_recursive_reactive_block\n%cDetected a migrated \`$:\` reactive block in \`${filename}\` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an \`$effect\`.`, bold, normal); | ||
} else { | ||
@@ -110,0 +111,0 @@ // TODO print a link to the documentation |
@@ -9,2 +9,3 @@ /** @import { ComponentConstructorOptions, ComponentType, SvelteComponent, Component } from 'svelte' */ | ||
component_context, | ||
dev_current_component_function, | ||
flush_sync, | ||
@@ -17,2 +18,4 @@ get, | ||
import * as w from '../internal/client/warnings.js'; | ||
import { DEV } from 'esm-env'; | ||
import { FILENAME } from '../constants.js'; | ||
@@ -187,3 +190,8 @@ /** | ||
if ((effect.f & DIRTY) !== 0) { | ||
w.legacy_recursive_reactive_block(); | ||
let filename = "a file (we can't know which one)"; | ||
if (DEV) { | ||
// @ts-ignore | ||
filename = dev_current_component_function?.[FILENAME] ?? filename; | ||
} | ||
w.legacy_recursive_reactive_block(filename); | ||
set_signal_status(effect, MAYBE_DIRTY); | ||
@@ -190,0 +198,0 @@ } |
@@ -9,3 +9,3 @@ // generated during release, do not modify | ||
*/ | ||
export const VERSION = '5.0.5'; | ||
export const VERSION = '5.1.0'; | ||
export const PUBLIC_VERSION = '5'; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2290849
50456
26
44
297
5