Merge branch 'main' into state-link

pull/12545/head
Dominic Gannaway 2 years ago
commit 63916753cb

@ -385,10 +385,12 @@
"nasty-mayflies-smoke", "nasty-mayflies-smoke",
"nasty-yaks-peel", "nasty-yaks-peel",
"neat-boats-shake", "neat-boats-shake",
"neat-boxes-chew",
"neat-dingos-clap", "neat-dingos-clap",
"neat-files-rescue", "neat-files-rescue",
"neat-jokes-beam", "neat-jokes-beam",
"nervous-berries-boil", "nervous-berries-boil",
"nervous-dolphins-allow",
"nervous-ducks-repeat", "nervous-ducks-repeat",
"nervous-spoons-relax", "nervous-spoons-relax",
"nervous-turkeys-end", "nervous-turkeys-end",
@ -645,6 +647,7 @@
"ten-worms-reflect", "ten-worms-reflect",
"tender-lemons-judge", "tender-lemons-judge",
"tender-rocks-walk", "tender-rocks-walk",
"tender-suns-love",
"thick-cycles-rule", "thick-cycles-rule",
"thick-pans-tell", "thick-pans-tell",
"thick-shirts-deliver", "thick-shirts-deliver",
@ -695,6 +698,7 @@
"two-dogs-accept", "two-dogs-accept",
"two-dragons-yell", "two-dragons-yell",
"two-falcons-buy", "two-falcons-buy",
"two-keys-watch",
"unlucky-boxes-obey", "unlucky-boxes-obey",
"unlucky-steaks-warn", "unlucky-steaks-warn",
"unlucky-trees-lick", "unlucky-trees-lick",

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: update original source in HMR update

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: correctly set filename on HMR wrappers

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: only emit binding_property_non_reactive warning in runes mode

@ -1,5 +1,17 @@
# svelte # svelte
## 5.0.0-next.194
### Patch Changes
- fix: bail-out of hydrating head if no anchor is found ([#12541](https://github.com/sveltejs/svelte/pull/12541))
- chore: add warning for invalid render function of createRawSnippet ([#12535](https://github.com/sveltejs/svelte/pull/12535))
- fix: correctly set filename on HMR wrappers ([#12543](https://github.com/sveltejs/svelte/pull/12543))
- fix: only emit binding_property_non_reactive warning in runes mode ([#12544](https://github.com/sveltejs/svelte/pull/12544))
## 5.0.0-next.193 ## 5.0.0-next.193
### Patch Changes ### Patch Changes

@ -2,7 +2,7 @@
"name": "svelte", "name": "svelte",
"description": "Cybernetically enhanced web apps", "description": "Cybernetically enhanced web apps",
"license": "MIT", "license": "MIT",
"version": "5.0.0-next.193", "version": "5.0.0-next.194",
"type": "module", "type": "module",
"types": "./types/index.d.ts", "types": "./types/index.d.ts",
"engines": { "engines": {

@ -417,8 +417,19 @@ export function client_component(source, analysis, options) {
); );
if (options.hmr) { if (options.hmr) {
const id = b.id(analysis.name);
const HMR = b.id('$.HMR');
const existing = b.member(id, HMR, true);
const incoming = b.member(b.id('module.default'), HMR, true);
const accept_fn_body = [ const accept_fn_body = [
b.stmt(b.call('$.set', b.id('s'), b.member(b.id('module.default'), b.id('$.ORIGINAL'), true))) b.stmt(
b.assignment('=', b.member(incoming, b.id('source')), b.member(existing, b.id('source')))
),
b.stmt(
b.call('$.set', b.member(existing, b.id('source')), b.member(incoming, b.id('original')))
)
]; ];
if (analysis.css.hash) { if (analysis.css.hash) {
@ -438,20 +449,10 @@ export function client_component(source, analysis, options) {
} }
const hmr = b.block([ const hmr = b.block([
b.const(b.id('s'), b.call('$.source', b.id(analysis.name))),
b.const(b.id('filename'), b.member(b.id(analysis.name), b.id('filename'))),
b.const(b.id('$$original'), b.id(analysis.name)),
b.stmt(b.assignment('=', b.id(analysis.name), b.call('$.hmr', b.id('s')))),
b.stmt(b.assignment('=', b.member(b.id(analysis.name), b.id('filename')), b.id('filename'))),
// Assign the original component to the wrapper so we can use it on hot reload patching,
// else we would call the HMR function two times
b.stmt( b.stmt(
b.assignment( b.assignment('=', id, b.call('$.hmr', id, b.thunk(b.member(existing, b.id('source')))))
'=',
b.member(b.id(analysis.name), b.id('$.ORIGINAL'), true),
b.id('$$original')
)
), ),
b.stmt(b.call('import.meta.hot.accept', b.arrow([b.id('module')], b.block(accept_fn_body)))) b.stmt(b.call('import.meta.hot.accept', b.arrow([b.id('module')], b.block(accept_fn_body))))
]); ]);

@ -780,7 +780,11 @@ function serialize_inline_component(node, component_name, context, anchor = cont
} else if (attribute.type === 'BindDirective') { } else if (attribute.type === 'BindDirective') {
const expression = /** @type {Expression} */ (context.visit(attribute.expression)); const expression = /** @type {Expression} */ (context.visit(attribute.expression));
if (expression.type === 'MemberExpression' && context.state.options.dev) { if (
expression.type === 'MemberExpression' &&
context.state.options.dev &&
context.state.analysis.runes
) {
context.state.init.push(serialize_validate_binding(context.state, attribute, expression)); context.state.init.push(serialize_validate_binding(context.state, attribute, expression));
} }
@ -2826,7 +2830,11 @@ export const template_visitors = {
const { state, path, visit } = context; const { state, path, visit } = context;
const expression = node.expression; const expression = node.expression;
if (expression.type === 'MemberExpression' && context.state.options.dev) { if (
expression.type === 'MemberExpression' &&
context.state.options.dev &&
context.state.analysis.runes
) {
context.state.init.push( context.state.init.push(
serialize_validate_binding( serialize_validate_binding(
context.state, context.state,

@ -32,7 +32,7 @@ export const UNINITIALIZED = Symbol();
// Dev-time component properties // Dev-time component properties
export const FILENAME = Symbol('filename'); export const FILENAME = Symbol('filename');
export const ORIGINAL = Symbol('original'); export const HMR = Symbol('hmr');
/** List of elements that require raw contents and should not have SSR comments put in them */ /** List of elements that require raw contents and should not have SSR comments put in them */
export const RawTextElements = ['textarea', 'script', 'style', 'title']; export const RawTextElements = ['textarea', 'script', 'style', 'title'];

@ -1,19 +1,22 @@
/** @import { Source, Effect } from '#client' */ /** @import { Source, Effect } from '#client' */
import { FILENAME, HMR } from '../../../constants.js';
import { EFFECT_TRANSPARENT } from '../constants.js'; import { EFFECT_TRANSPARENT } from '../constants.js';
import { block, branch, destroy_effect } from '../reactivity/effects.js'; import { block, branch, destroy_effect } from '../reactivity/effects.js';
import { source } from '../reactivity/sources.js';
import { set_should_intro } from '../render.js'; import { set_should_intro } from '../render.js';
import { get } from '../runtime.js'; import { get } from '../runtime.js';
/** /**
* @template {(anchor: Comment, props: any) => any} Component * @template {(anchor: Comment, props: any) => any} Component
* @param {Source<Component>} source * @param {Component} original
* @param {() => Source<Component>} get_source
*/ */
export function hmr(source) { export function hmr(original, get_source) {
/** /**
* @param {Comment} anchor * @param {Comment} anchor
* @param {any} props * @param {any} props
*/ */
return function (anchor, props) { function wrapper(anchor, props) {
let instance = {}; let instance = {};
/** @type {Effect} */ /** @type {Effect} */
@ -22,6 +25,7 @@ export function hmr(source) {
let ran = false; let ran = false;
block(() => { block(() => {
const source = get_source();
const component = get(source); const component = get(source);
if (effect) { if (effect) {
@ -50,5 +54,20 @@ export function hmr(source) {
ran = true; ran = true;
return instance; return instance;
}
// @ts-expect-error
wrapper[FILENAME] = original[FILENAME];
// @ts-expect-error
wrapper[HMR] = {
// When we accept an update, we set the original source to the new component
original,
// The `get_source` parameter reads `wrapper[HMR].source`, but in the `accept`
// function we always replace it with `previous[HMR].source`, which in practice
// means we only ever update the original
source: source(original)
}; };
return wrapper;
} }

@ -1,4 +1,4 @@
export { FILENAME, ORIGINAL } from '../../constants.js'; export { FILENAME, HMR } from '../../constants.js';
export { add_locations } from './dev/elements.js'; export { add_locations } from './dev/elements.js';
export { hmr } from './dev/hmr.js'; export { hmr } from './dev/hmr.js';
export { export {

@ -1,6 +1,6 @@
/** @import { Component, Payload, RenderOutput } from '#server' */ /** @import { Component, Payload, RenderOutput } from '#server' */
/** @import { Store } from '#shared' */ /** @import { Store } from '#shared' */
export { FILENAME, ORIGINAL } from '../../constants.js'; export { FILENAME, HMR } from '../../constants.js';
import { is_promise, noop } from '../shared/utils.js'; import { is_promise, noop } from '../shared/utils.js';
import { subscribe_to_store } from '../../store/utils.js'; import { subscribe_to_store } from '../../store/utils.js';
import { import {

@ -6,5 +6,5 @@
* https://svelte.dev/docs/svelte-compiler#svelte-version * https://svelte.dev/docs/svelte-compiler#svelte-version
* @type {string} * @type {string}
*/ */
export const VERSION = '5.0.0-next.193'; export const VERSION = '5.0.0-next.194';
export const PUBLIC_VERSION = '5'; export const PUBLIC_VERSION = '5';

@ -0,0 +1,23 @@
import { flushSync } from 'svelte';
import { ok, test } from '../../test';
export default test({
compileOptions: {
dev: true
},
test({ assert, target, window }) {
assert.htmlEqual(target.innerHTML, `<input><p>hello</p>`);
const input = target.querySelector('input');
ok(input);
input.value = 'goodbye';
input.dispatchEvent(new window.Event('input'));
flushSync();
assert.htmlEqual(target.innerHTML, `<input><p>goodbye</p>`);
},
warnings: []
});

@ -0,0 +1,6 @@
<script>
let object = { value: 'hello' };
</script>
<input bind:value={object.value} />
<p>{object.value}</p>

@ -10,16 +10,11 @@ function Hmr($$anchor) {
} }
if (import.meta.hot) { if (import.meta.hot) {
const s = $.source(Hmr); Hmr = $.hmr(Hmr, () => Hmr[$.HMR].source);
const filename = Hmr.filename;
const $$original = Hmr;
Hmr = $.hmr(s);
Hmr.filename = filename;
Hmr[$.ORIGINAL] = $$original;
import.meta.hot.accept((module) => { import.meta.hot.accept((module) => {
$.set(s, module.default[$.ORIGINAL]); module.default[$.HMR].source = Hmr[$.HMR].source;
$.set(Hmr[$.HMR].source, module.default[$.HMR].original);
}); });
} }

Loading…
Cancel
Save