Skip to content

Commit a9eb846

Browse files
committed
Merge remote-tracking branch 'upstream/main' into $state-invalidate
2 parents 1d3833f + 475b5db commit a9eb846

File tree

14 files changed

+98
-124
lines changed

14 files changed

+98
-124
lines changed

.changeset/nervous-kids-shake.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/stupid-vans-draw.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

documentation/docs/01-introduction/04-svelte-js-files.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: .svelte.js and .svelte.ts files
44

55
Besides `.svelte` files, Svelte also operates on `.svelte.js` and `.svelte.ts` files.
66

7-
These behave like any other `.js` or `.ts` module, except that you can use runes. This is useful for creating reusable reactive logic, or sharing reactive state across your app.
7+
These behave like any other `.js` or `.ts` module, except that you can use runes. This is useful for creating reusable reactive logic, or sharing reactive state across your app (though note that you [cannot export reassigned state]($state#Passing-state-across-modules)).
88

99
> [!LEGACY]
1010
> This is a concept that didn't exist prior to Svelte 5

documentation/docs/02-runes/02-$state.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,83 @@ console.log(total.value); // 7
291291
```
292292

293293
...though if you find yourself writing code like that, consider using [classes](#Classes) instead.
294+
295+
## Passing state across modules
296+
297+
You can declare state in `.svelte.js` and `.svelte.ts` files, but you can only _export_ that state if it's not directly reassigned. In other words you can't do this:
298+
299+
```js
300+
/// file: state.svelte.js
301+
export let count = $state(0);
302+
303+
export function increment() {
304+
count += 1;
305+
}
306+
```
307+
308+
That's because every reference to `count` is transformed by the Svelte compiler — the code above is roughly equivalent to this:
309+
310+
```js
311+
/// file: state.svelte.js (compiler output)
312+
// @filename: index.ts
313+
interface Signal<T> {
314+
value: T;
315+
}
316+
317+
interface Svelte {
318+
state<T>(value?: T): Signal<T>;
319+
get<T>(source: Signal<T>): T;
320+
set<T>(source: Signal<T>, value: T): void;
321+
}
322+
declare const $: Svelte;
323+
// ---cut---
324+
export let count = $.state(0);
325+
326+
export function increment() {
327+
$.set(count, $.get(count) + 1);
328+
}
329+
```
330+
331+
> [!NOTE] You can see the code Svelte generates by clicking the 'JS Output' tab in the [playground](/playground).
332+
333+
Since the compiler only operates on one file at a time, if another file imports `count` Svelte doesn't know that it needs to wrap each reference in `$.get` and `$.set`:
334+
335+
```js
336+
// @filename: state.svelte.js
337+
export let count = 0;
338+
339+
// @filename: index.js
340+
// ---cut---
341+
import { count } from './state.svelte.js';
342+
343+
console.log(typeof count); // 'object', not 'number'
344+
```
345+
346+
This leaves you with two options for sharing state between modules — either don't reassign it...
347+
348+
```js
349+
// This is allowed — since we're updating
350+
// `counter.count` rather than `counter`,
351+
// Svelte doesn't wrap it in `$.state`
352+
export const counter = $state({
353+
count: 0
354+
});
355+
356+
export function increment() {
357+
counter.count += 1;
358+
}
359+
```
360+
361+
...or don't directly export it:
362+
363+
```js
364+
let count = $state(0);
365+
366+
export function getCount() {
367+
return count;
368+
}
369+
370+
export function increment() {
371+
count += 1;
372+
}
373+
```

documentation/docs/98-reference/.generated/client-errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ A component is attempting to bind to a non-bindable property `%key%` belonging t
2121
### component_api_changed
2222

2323
```
24-
%parent% called `%method%` on an instance of %component%, which is no longer valid in Svelte 5
24+
Calling `%method%` on a component instance (of %component%) is no longer valid in Svelte 5
2525
```
2626

2727
See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.

packages/svelte/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# svelte
22

3+
## 5.25.10
4+
5+
### Patch Changes
6+
7+
- fix: set deriveds as `CLEAN` if they are assigned to ([#15592](https://github.com/sveltejs/svelte/pull/15592))
8+
9+
- fix: better scope `:global()` with nesting selector `&` ([#15671](https://github.com/sveltejs/svelte/pull/15671))
10+
311
## 5.25.9
412

513
### Patch Changes

packages/svelte/messages/client-errors/errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
1313
## component_api_changed
1414

15-
> %parent% called `%method%` on an instance of %component%, which is no longer valid in Svelte 5
15+
> Calling `%method%` on a component instance (of %component%) is no longer valid in Svelte 5
1616
1717
See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.
1818

packages/svelte/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "svelte",
33
"description": "Cybernetically enhanced web apps",
44
"license": "MIT",
5-
"version": "5.25.9",
5+
"version": "5.25.10",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {

packages/svelte/src/compiler/phases/3-transform/client/transform-client.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,9 +536,6 @@ export function client_component(analysis, options) {
536536
b.assignment('=', b.member(b.id(analysis.name), '$.FILENAME', true), b.literal(filename))
537537
)
538538
);
539-
540-
body.unshift(b.stmt(b.call(b.id('$.mark_module_start'))));
541-
body.push(b.stmt(b.call(b.id('$.mark_module_end'), b.id(analysis.name))));
542539
}
543540

544541
if (!analysis.runes) {

packages/svelte/src/internal/client/dev/legacy.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as e from '../errors.js';
22
import { component_context } from '../context.js';
33
import { FILENAME } from '../../../constants.js';
4-
import { get_component } from './ownership.js';
54

65
/** @param {Function & { [FILENAME]: string }} target */
76
export function check_target(target) {
@@ -15,9 +14,7 @@ export function legacy_api() {
1514

1615
/** @param {string} method */
1716
function error(method) {
18-
// @ts-expect-error
19-
const parent = get_component()?.[FILENAME] ?? 'Something';
20-
e.component_api_changed(parent, method, component[FILENAME]);
17+
e.component_api_changed(method, component[FILENAME]);
2118
}
2219

2320
return {

0 commit comments

Comments
 (0)