Skip to content

Commit abdf456

Browse files
committed
Merge branch 'main' into each-without-as
2 parents ea30c9d + 32a1453 commit abdf456

File tree

112 files changed

+1501
-470
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+1501
-470
lines changed

.changeset/hot-frogs-melt.md

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

.changeset/unlucky-icons-sit.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: include method definitions in class private fields

benchmarking/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
output

benchmarking/benchmarks.js renamed to benchmarking/benchmarks/reactivity/index.js

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
import {
2-
kairo_avoidable_owned,
3-
kairo_avoidable_unowned
4-
} from './benchmarks/kairo/kairo_avoidable.js';
5-
import { kairo_broad_owned, kairo_broad_unowned } from './benchmarks/kairo/kairo_broad.js';
6-
import { kairo_deep_owned, kairo_deep_unowned } from './benchmarks/kairo/kairo_deep.js';
7-
import { kairo_diamond_owned, kairo_diamond_unowned } from './benchmarks/kairo/kairo_diamond.js';
8-
import { kairo_mux_unowned, kairo_mux_owned } from './benchmarks/kairo/kairo_mux.js';
9-
import { kairo_repeated_unowned, kairo_repeated_owned } from './benchmarks/kairo/kairo_repeated.js';
10-
import { kairo_triangle_owned, kairo_triangle_unowned } from './benchmarks/kairo/kairo_triangle.js';
11-
import { kairo_unstable_owned, kairo_unstable_unowned } from './benchmarks/kairo/kairo_unstable.js';
12-
import { mol_bench_owned, mol_bench_unowned } from './benchmarks/mol_bench.js';
1+
import { kairo_avoidable_owned, kairo_avoidable_unowned } from './kairo/kairo_avoidable.js';
2+
import { kairo_broad_owned, kairo_broad_unowned } from './kairo/kairo_broad.js';
3+
import { kairo_deep_owned, kairo_deep_unowned } from './kairo/kairo_deep.js';
4+
import { kairo_diamond_owned, kairo_diamond_unowned } from './kairo/kairo_diamond.js';
5+
import { kairo_mux_unowned, kairo_mux_owned } from './kairo/kairo_mux.js';
6+
import { kairo_repeated_unowned, kairo_repeated_owned } from './kairo/kairo_repeated.js';
7+
import { kairo_triangle_owned, kairo_triangle_unowned } from './kairo/kairo_triangle.js';
8+
import { kairo_unstable_owned, kairo_unstable_unowned } from './kairo/kairo_unstable.js';
9+
import { mol_bench_owned, mol_bench_unowned } from './mol_bench.js';
1310
import {
1411
sbench_create_0to1,
1512
sbench_create_1000to1,
@@ -21,12 +18,12 @@ import {
2118
sbench_create_2to1,
2219
sbench_create_4to1,
2320
sbench_create_signals
24-
} from './benchmarks/sbench.js';
21+
} from './sbench.js';
2522

2623
// This benchmark has been adapted from the js-reactivity-benchmark (https://github.com/milomg/js-reactivity-benchmark)
2724
// Not all tests are the same, and many parts have been tweaked to capture different data.
2825

29-
export const benchmarks = [
26+
export const reactivity_benchmarks = [
3027
sbench_create_signals,
3128
sbench_create_0to1,
3229
sbench_create_1to1,

benchmarking/benchmarks/kairo/kairo_avoidable.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_avoidable.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33
import { busy } from './util.js';
44

55
function setup() {

benchmarking/benchmarks/kairo/kairo_broad.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_broad.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
function setup() {
55
let head = $.state(0);

benchmarking/benchmarks/kairo/kairo_deep.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_deep.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
let len = 50;
55
const iter = 50;

benchmarking/benchmarks/kairo/kairo_diamond.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_diamond.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
let width = 5;
55

benchmarking/benchmarks/kairo/kairo_mux.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_mux.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
function setup() {
55
let heads = new Array(100).fill(null).map((_) => $.state(0));

benchmarking/benchmarks/kairo/kairo_repeated.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_repeated.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
let size = 30;
55

benchmarking/benchmarks/kairo/kairo_triangle.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_triangle.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
let width = 10;
55

benchmarking/benchmarks/kairo/kairo_unstable.js renamed to benchmarking/benchmarks/reactivity/kairo/kairo_unstable.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../../utils.js';
2-
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
function setup() {
55
let head = $.state(0);

benchmarking/benchmarks/mol_bench.js renamed to benchmarking/benchmarks/reactivity/mol_bench.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assert, fastest_test } from '../utils.js';
2-
import * as $ from '../../packages/svelte/src/internal/client/index.js';
1+
import { assert, fastest_test } from '../../utils.js';
2+
import * as $ from 'svelte/internal/client';
33

44
/**
55
* @param {number} n

benchmarking/benchmarks/sbench.js renamed to benchmarking/benchmarks/reactivity/sbench.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { fastest_test } from '../utils.js';
2-
import * as $ from '../../packages/svelte/src/internal/client/index.js';
1+
import { fastest_test } from '../../utils.js';
2+
import * as $ from '../../../packages/svelte/src/internal/client/index.js';
33

44
const COUNT = 1e5;
55

benchmarking/benchmarks/ssr/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { wrapper_bench } from './wrapper/wrapper_bench.js';
2+
3+
export const ssr_benchmarks = [wrapper_bench];
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script>
2+
const wrapperWidth = 960;
3+
const wrapperHeight = 720;
4+
const cellSize = 10;
5+
const centerX = wrapperWidth / 2;
6+
const centerY = wrapperHeight / 2;
7+
8+
let angle = 0;
9+
let radius = 0;
10+
11+
let tiles = [];
12+
const step = cellSize;
13+
14+
while (radius < Math.min(wrapperWidth, wrapperHeight) / 2) {
15+
let x = centerX + Math.cos(angle) * radius;
16+
let y = centerY + Math.sin(angle) * radius;
17+
18+
if (x >= 0 && x <= wrapperWidth - cellSize && y >= 0 && y <= wrapperHeight - cellSize) {
19+
tiles.push({ x, y });
20+
}
21+
22+
angle += 0.2;
23+
radius += step * 0.015;
24+
}
25+
</script>
26+
27+
<div id="wrapper">
28+
{#each tiles as { x, y }}
29+
<div class="tile" style="left: {x.toFixed(2)}px; top: {y.toFixed(2)}px;"></div>
30+
{/each}
31+
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { render } from 'svelte/server';
2+
import { fastest_test, read_file, write } from '../../../utils.js';
3+
import { compile } from 'svelte/compiler';
4+
5+
const dir = `${process.cwd()}/benchmarking/benchmarks/ssr/wrapper`;
6+
7+
async function compile_svelte() {
8+
const output = compile(read_file(`${dir}/App.svelte`), {
9+
generate: 'server'
10+
});
11+
write(`${dir}/output/App.js`, output.js.code);
12+
13+
const module = await import(`${dir}/output/App.js`);
14+
15+
return module.default;
16+
}
17+
18+
export async function wrapper_bench() {
19+
const App = await compile_svelte();
20+
// Do 3 loops to warm up JIT
21+
for (let i = 0; i < 3; i++) {
22+
render(App);
23+
}
24+
25+
const { timing } = await fastest_test(10, () => {
26+
for (let i = 0; i < 100; i++) {
27+
render(App);
28+
}
29+
});
30+
31+
return {
32+
benchmark: 'wrapper_bench',
33+
time: timing.time.toFixed(2),
34+
gc_time: timing.gc_time.toFixed(2)
35+
};
36+
}

benchmarking/run.js

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,53 @@
11
import * as $ from '../packages/svelte/src/internal/client/index.js';
2-
import { benchmarks } from './benchmarks.js';
2+
import { reactivity_benchmarks } from './benchmarks/reactivity/index.js';
3+
import { ssr_benchmarks } from './benchmarks/ssr/index.js';
34

45
let total_time = 0;
56
let total_gc_time = 0;
67

8+
const suites = [
9+
{ benchmarks: reactivity_benchmarks, name: 'reactivity benchmarks' },
10+
{ benchmarks: ssr_benchmarks, name: 'server-side rendering benchmarks' }
11+
];
12+
713
// eslint-disable-next-line no-console
8-
console.log('-- Benchmarking Started --');
14+
console.log('\x1b[1m', '-- Benchmarking Started --', '\x1b[0m');
915
$.push({}, true);
1016
try {
11-
for (const benchmark of benchmarks) {
12-
const results = await benchmark();
17+
for (const { benchmarks, name } of suites) {
18+
let suite_time = 0;
19+
let suite_gc_time = 0;
20+
// eslint-disable-next-line no-console
21+
console.log(`\nRunning ${name}...\n`);
22+
23+
for (const benchmark of benchmarks) {
24+
const results = await benchmark();
25+
// eslint-disable-next-line no-console
26+
console.log(results);
27+
total_time += Number(results.time);
28+
total_gc_time += Number(results.gc_time);
29+
suite_time += Number(results.time);
30+
suite_gc_time += Number(results.gc_time);
31+
}
32+
33+
console.log(`\nFinished ${name}.\n`);
34+
1335
// eslint-disable-next-line no-console
14-
console.log(results);
15-
total_time += Number(results.time);
16-
total_gc_time += Number(results.gc_time);
36+
console.log({
37+
suite_time: suite_time.toFixed(2),
38+
suite_gc_time: suite_gc_time.toFixed(2)
39+
});
1740
}
1841
} catch (e) {
1942
// eslint-disable-next-line no-console
20-
console.error('-- Benchmarking Failed --');
43+
console.log('\x1b[1m', '\n-- Benchmarking Failed --\n', '\x1b[0m');
2144
// eslint-disable-next-line no-console
2245
console.error(e);
2346
process.exit(1);
2447
}
2548
$.pop();
2649
// eslint-disable-next-line no-console
27-
console.log('-- Benchmarking Complete --');
50+
console.log('\x1b[1m', '\n-- Benchmarking Complete --\n', '\x1b[0m');
2851
// eslint-disable-next-line no-console
2952
console.log({
3053
total_time: total_time.toFixed(2),

benchmarking/utils.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { performance, PerformanceObserver } from 'node:perf_hooks';
22
import v8 from 'v8-natives';
3+
import * as fs from 'node:fs';
4+
import * as path from 'node:path';
35

46
// Credit to https://github.com/milomg/js-reactivity-benchmark for the logic for timing + GC tracking.
57

@@ -96,3 +98,22 @@ export function assert(a) {
9698
throw new Error('Assertion failed');
9799
}
98100
}
101+
102+
/**
103+
* @param {string} file
104+
*/
105+
export function read_file(file) {
106+
return fs.readFileSync(file, 'utf-8').replace(/\r\n/g, '\n');
107+
}
108+
109+
/**
110+
* @param {string} file
111+
* @param {string} contents
112+
*/
113+
export function write(file, contents) {
114+
try {
115+
fs.mkdirSync(path.dirname(file), { recursive: true });
116+
} catch {}
117+
118+
fs.writeFileSync(file, contents);
119+
}

documentation/docs/06-runtime/01-stores.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,28 @@ Prior to Svelte 5, stores were the go-to solution for creating cross-component r
3838
- when extracting logic, it's better to take advantage of runes' universal reactivity: You can use runes outside the top level of components and even place them into JavaScript or TypeScript files (using a `.svelte.js` or `.svelte.ts` file ending)
3939
- when creating shared state, you can create a `$state` object containing the values you need and then manipulate said state
4040

41+
```ts
42+
/// file: state.svelte.js
43+
export const userState = $state({
44+
name: 'name',
45+
/* ... */
46+
});
47+
```
48+
49+
```svelte
50+
<!--- file: App.svelte --->
51+
<script>
52+
import { userState } from './state.svelte';
53+
</script>
54+
55+
<p>User name: {userState.name}</p>
56+
<button onclick={() => {
57+
userState.name = 'new name';
58+
}}>
59+
change name
60+
</button>
61+
```
62+
4163
Stores are still a good solution when you have complex asynchronous data streams or it's important to have more manual control over updating values or listening to changes. If you're familiar with RxJs and want to reuse that knowledge, the `$` also comes in handy for you.
4264

4365
## svelte/store

documentation/docs/07-misc/07-v5-migration-guide.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,11 @@ This function is deprecated in Svelte 5. Instead, components should accept _call
169169
170170
<Pump
171171
---on:---inflate={(power) => {
172-
size += power---.details---;
172+
size += power---.detail---;
173173
if (size > 75) burst = true;
174174
}}
175175
---on:---deflate={(power) => {
176-
if (size > 0) size -= power---.details---;
176+
if (size > 0) size -= power---.detail---;
177177
}}
178178
/>
179179
@@ -317,7 +317,7 @@ When spreading props, local event handlers must go _after_ the spread, or they r
317317
> - import the function
318318
> - call the function to get a dispatch function
319319
> - call said dispatch function with a string and possibly a payload
320-
> - retrieve said payload on the other end through a `.details` property, because the event itself was always a `CustomEvent`
320+
> - retrieve said payload on the other end through a `.detail` property, because the event itself was always a `CustomEvent`
321321
>
322322
> It was always possible to use component callback props, but because you had to listen to DOM events using `on:`, it made sense to use `createEventDispatcher` for component events due to syntactical consistency. Now that we have event attributes (`onclick`), it's the other way around: Callback props are now the more sensible thing to do.
323323
>

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,12 @@ Expected whitespace
412412
`$host()` can only be used inside custom element component instances
413413
```
414414

415+
### illegal_element_attribute
416+
417+
```
418+
`<%name%>` does not support non-event attributes or spread attributes
419+
```
420+
415421
### import_svelte_internal_forbidden
416422

417423
```

0 commit comments

Comments
 (0)