Skip to content

Commit f098008

Browse files
committed
Merge branch 'main' into revert-15196-corepack-bullshit
2 parents 03a9d38 + 1ada302 commit f098008

File tree

12 files changed

+230
-29
lines changed

12 files changed

+230
-29
lines changed

.changeset/long-moles-join.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: ensure tracking returns true, even if in unowned

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,39 @@ If a bindable property has a default value (e.g. `let { foo = $bindable('bar') }
722722
723723
### `accessors` option is ignored
724724
725-
Setting the `accessors` option to `true` makes properties of a component directly accessible on the component instance. In runes mode, properties are never accessible on the component instance. You can use component exports instead if you need to expose them.
725+
Setting the `accessors` option to `true` makes properties of a component directly accessible on the component instance.
726+
727+
```svelte
728+
<svelte:options accessors={true} />
729+
730+
<script>
731+
// available via componentInstance.name
732+
export let name;
733+
</script>
734+
```
735+
736+
In runes mode, properties are never accessible on the component instance. You can use component exports instead if you need to expose them.
737+
738+
```svelte
739+
<script>
740+
let { name } = $props();
741+
// available via componentInstance.getName()
742+
export const getName = () => name;
743+
</script>
744+
```
745+
746+
Alternatively, if the place where they are instantiated is under your control, you can also make use of runes inside `.js/.ts` files by adjusting their ending to include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`, and then use `$state`:
747+
748+
```js
749+
+++import { mount } from 'svelte';+++
750+
import App from './App.svelte'
751+
752+
---const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } });
753+
app.foo = 'baz'---
754+
+++const props = $state({ foo: 'bar' });
755+
const app = mount(App, { target: document.getElementById("app"), props });
756+
props.foo = 'baz';+++
757+
```
726758
727759
### `immutable` option is ignored
728760

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,7 @@ function create_effect(type, fn, sync, push = true) {
164164
* @returns {boolean}
165165
*/
166166
export function effect_tracking() {
167-
if (active_reaction === null || untracking) {
168-
return false;
169-
}
170-
171-
// If it's skipped, that's because we're inside an unowned
172-
// that is not being tracked by another reaction
173-
return !skip_reaction;
167+
return active_reaction !== null && !untracking;
174168
}
175169

176170
/**
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target, logs }) {
6+
const b1 = target.querySelector('button');
7+
8+
b1?.click();
9+
flushSync();
10+
11+
assert.htmlEqual(
12+
target.innerHTML,
13+
`<o>Store: new</o><p>Text: new message</p><button>Change Store</button>`
14+
);
15+
}
16+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script>
2+
import { writable, fromStore, toStore } from "svelte/store";
3+
4+
const store = writable("previous");
5+
let text = $derived(fromStore(store).current + " message");
6+
7+
text; // read derived in a non-tracking context
8+
</script>
9+
10+
<o>Store: {$store}</o>
11+
<p>Text: {text}</p>
12+
<button onclick={() => { store.set("new"); }}>Change Store</button>

playgrounds/sandbox/index.html

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

1313
<script type="module">
1414
import { mount, hydrate, unmount } from 'svelte';
15-
import App from '/src/main.svelte';
15+
import App from '/src/App.svelte';
1616

1717
const root = document.getElementById('root');
1818
const render = root.firstChild?.nextSibling ? hydrate : mount;

playgrounds/sandbox/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@
99
"ssr": "node --conditions=development ./ssr-dev.js",
1010
"build": "vite build --outDir dist/client && vite build --outDir dist/server --ssr ssr-prod.js",
1111
"prod": "npm run build && node dist/server/ssr-prod",
12-
"preview": "vite preview"
12+
"preview": "vite preview",
13+
"download": "node scripts/download.js",
14+
"hash": "node scripts/hash.js"
1315
},
1416
"devDependencies": {
1517
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.6",
1618
"polka": "^1.0.0-next.25",
1719
"svelte": "workspace:*",
1820
"tiny-glob": "^0.2.9",
19-
"vite": "^5.4.6",
21+
"vite": "^5.4.14",
2022
"vite-plugin-inspect": "^0.8.4"
2123
}
2224
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import fs from 'node:fs';
2+
3+
const arg = process.argv[2];
4+
5+
/** @type {URL} */
6+
let url;
7+
8+
try {
9+
url = new URL(arg);
10+
} catch (e) {
11+
console.error(`${arg} is not a URL`);
12+
process.exit(1);
13+
}
14+
15+
if (url.origin !== 'https://svelte.dev' || !url.pathname.startsWith('/playground/')) {
16+
console.error(`${arg} is not a Svelte playground URL`);
17+
process.exit(1);
18+
}
19+
20+
let files;
21+
22+
if (url.hash.length > 1) {
23+
const decoded = atob(url.hash.slice(1).replaceAll('-', '+').replaceAll('_', '/'));
24+
// putting it directly into the blob gives a corrupted file
25+
const u8 = new Uint8Array(decoded.length);
26+
for (let i = 0; i < decoded.length; i++) {
27+
u8[i] = decoded.charCodeAt(i);
28+
}
29+
const stream = new Blob([u8]).stream().pipeThrough(new DecompressionStream('gzip'));
30+
const json = await new Response(stream).text();
31+
32+
files = JSON.parse(json).files;
33+
} else {
34+
const id = url.pathname.split('/')[2];
35+
const response = await fetch(`https://svelte.dev/playground/api/${id}.json`);
36+
37+
files = (await response.json()).components.map((data) => {
38+
const basename = `${data.name}.${data.type}`;
39+
40+
return {
41+
type: 'file',
42+
name: basename,
43+
basename,
44+
contents: data.source,
45+
text: true
46+
};
47+
});
48+
}
49+
50+
for (const file of files) {
51+
fs.writeFileSync(`src/${file.name}`, file.contents);
52+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import fs from 'node:fs';
2+
3+
const files = [];
4+
5+
for (const basename of fs.readdirSync('src')) {
6+
if (fs.statSync(`src/${basename}`).isDirectory()) continue;
7+
8+
files.push({
9+
type: 'file',
10+
name: basename,
11+
basename,
12+
contents: fs.readFileSync(`src/${basename}`, 'utf-8'),
13+
text: true // TODO might not be
14+
});
15+
}
16+
17+
const payload = JSON.stringify({
18+
name: 'sandbox',
19+
files
20+
});
21+
22+
async function compress(payload) {
23+
const reader = new Blob([payload])
24+
.stream()
25+
.pipeThrough(new CompressionStream('gzip'))
26+
.getReader();
27+
28+
let buffer = '';
29+
for (;;) {
30+
const { done, value } = await reader.read();
31+
32+
if (done) {
33+
reader.releaseLock();
34+
return btoa(buffer).replaceAll('+', '-').replaceAll('/', '_');
35+
} else {
36+
for (let i = 0; i < value.length; i++) {
37+
// decoding as utf-8 will make btoa reject the string
38+
buffer += String.fromCharCode(value[i]);
39+
}
40+
}
41+
}
42+
}
43+
44+
const hash = await compress(payload);
45+
console.log(`https://svelte.dev/playground/untitled#${hash}`);

playgrounds/sandbox/ssr-dev.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ polka()
2222
.use(async (req, res) => {
2323
const template = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8');
2424
const transformed_template = await vite.transformIndexHtml(req.url, template);
25-
const { default: App } = await vite.ssrLoadModule('/src/main.svelte');
25+
const { default: App } = await vite.ssrLoadModule('/src/App.svelte');
2626
const { head, body } = render(App);
2727

2828
const html = transformed_template

0 commit comments

Comments
 (0)