Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cold-dingos-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: use fine grained for template if the component is not explicitly in legacy mode
20 changes: 20 additions & 0 deletions packages/svelte/src/compiler/phases/2-analyze/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,26 @@ export function analyze_component(root, source, options) {
template,
elements: [],
runes,
// if we are not in runes mode but we have no reserved references ($$props, $$restProps)
// and no `export let` we might be in a wannabe runes component that is using runes in an external
// module...we need to fallback to the runic behavior
maybe_runes:
!runes &&
// if they explicitly disabled runes, use the legacy behavior
options.runes !== false &&
!module.scope.references.keys().some((name) => ['$$props', '$$restProps'].includes(name)) &&
!instance.ast.body.some(
(node) =>
node.type === 'ExportNamedDeclaration' &&
((node.declaration &&
node.declaration.type === 'VariableDeclaration' &&
node.declaration.kind === 'let') ||
node.specifiers.some(
(specifier) =>
specifier.local.type === 'Identifier' &&
instance.scope.get(specifier.local.name)?.declaration_kind === 'let'
))
),
tracing: false,
classes: new Map(),
immutable: runes || options.immutable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ export function validate_mutation(node, context, expression) {
export function build_expression(context, expression, metadata, state = context.state) {
const value = /** @type {Expression} */ (context.visit(expression, state));

if (context.state.analysis.runes) {
if (context.state.analysis.runes || context.state.analysis.maybe_runes) {
return value;
}

Expand Down
1 change: 1 addition & 0 deletions packages/svelte/src/compiler/phases/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface ComponentAnalysis extends Analysis {
/** Used for CSS pruning and scoping */
elements: Array<AST.RegularElement | AST.SvelteElement>;
runes: boolean;
maybe_runes: boolean;
tracing: boolean;
exports: Array<{ name: string; alias: string | null }>;
/** Whether the component uses `$$props` */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '0');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<svelte:options runes={false} />
<script>
import { get, set } from "./test.svelte.js";
</script>

<p>{get()}</p>

<button onclick={()=>set()}></button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let count = $state(0);

export function get() {
return count;
}

export function set() {
count++;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '1');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script>
import { get, set } from "./test.svelte.js";

export const x = 42;
</script>

<p>{get()}</p>

<button onclick={()=>set()}></button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let count = $state(0);

export function get() {
return count;
}

export function set() {
count++;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '1');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import { get, set } from "./test.svelte.js";

let x = 42;

export { x };
</script>

{x}
<p>{get()}</p>

<button onclick={()=>set()}></button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let count = $state(0);

export function get() {
return count;
}

export function set() {
count++;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '1');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
import { get, set } from "./test.svelte.js";
</script>

<p>{get()}</p>

<button onclick={()=>set()}></button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let count = $state(0);

export function get() {
return count;
}

export function set() {
count++;
}
Loading