Skip to content

Commit 17848e9

Browse files
committed
more legible
1 parent 1c38090 commit 17848e9

File tree

1 file changed

+100
-60
lines changed
  • packages/svelte/src/internal/client

1 file changed

+100
-60
lines changed

packages/svelte/src/internal/client/hmr.js

Lines changed: 100 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ import { current_hydration_fragment } from './hydration.js';
44
import { child_frag } from './operations.js';
55
import { proxy } from './proxy/proxy.js';
66

7+
/**
8+
* @typedef {Record<string | symbol, any> | undefined} ComponentReturn
9+
*
10+
* @typedef {any[]} ComponentArgs
11+
*
12+
* @typedef {(...args: ComponentArgs) => ComponentReturn} Component
13+
*
14+
* @typedef {{
15+
* set_component: (new_component: Component) => void
16+
* proxy_component?: (...args: ComponentArgs) => ComponentReturn
17+
* }} HotData<Component>
18+
*/
19+
720
function find_surrounding_ssr_commments() {
821
if (!current_hydration_fragment?.[0]) return null;
922

@@ -42,76 +55,103 @@ function find_surrounding_ssr_commments() {
4255
}
4356

4457
/**
45-
* @template {any[]} ComponentArgs
46-
* @template {Record<string | symbol, any> | undefined} ComponentReturn
47-
* @template {(...args: ComponentArgs) => ComponentReturn} Component
48-
*
49-
* @param {{
50-
* component_signal: ReturnType<typeof source<Component>>,
51-
* proxy?: (...args: ComponentArgs) => ComponentReturn
52-
* }} hot_data
5358
* @param {Component} new_component
5459
*/
55-
export function hmr(hot_data, new_component) {
56-
if (hot_data.proxy) {
57-
set(hot_data.component_signal, new_component);
58-
} else {
59-
hot_data.component_signal = source(new_component);
60+
function create_proxy_component(new_component) {
61+
const component_signal = source(new_component);
6062

61-
// @ts-ignore
62-
hot_data.proxy = function ($$anchor, ...args) {
63-
const accessors_proxy = proxy(/** @type {import('./proxy/proxy.js').StateObject} */ ({}));
64-
/** @type {Set<string>} */
65-
const accessors_keys = new Set();
63+
let component_name = '';
6664

67-
// During hydration the root component will receive a null $$anchor. The
68-
// following is a hack to get our `key` a node to render to, all while
69-
// avoiding it to "consume" the SSR marker.
70-
//
71-
// TODO better get the eyes of someone with understanding of hydration on this
72-
//
73-
// If this failes, we get an ugly hydration failure message, but HMR should
74-
// still work after that... Maybe we can show a more specific error message than
75-
// the generic hydration failure one (that could be misleading in this case).
76-
//
77-
if (!$$anchor && current_hydration_fragment?.[0]) {
78-
const ssr0 = find_surrounding_ssr_commments();
79-
if (ssr0) {
80-
const [before, after] = ssr0;
81-
current_hydration_fragment.unshift(before);
82-
current_hydration_fragment.push(after);
83-
$$anchor = child_frag(current_hydration_fragment);
84-
}
65+
/**
66+
* @type {HotData["set_component"]}
67+
*/
68+
function set_component(new_component) {
69+
component_name = new_component.name;
70+
set(component_signal, new_component);
71+
}
72+
73+
// @ts-ignore
74+
function proxy_component($$anchor, ...args) {
75+
const accessors_proxy = proxy(/** @type {import('./proxy/proxy.js').StateObject} */ ({}));
76+
/** @type {Set<string>} */
77+
const accessors_keys = new Set();
78+
79+
// During hydration the root component will receive a null $$anchor. The
80+
// following is a hack to get our `key` a node to render to, all while
81+
// avoiding it to "consume" the SSR marker.
82+
//
83+
// TODO better get the eyes of someone with understanding of hydration on this
84+
//
85+
// If this fails, we get an ugly hydration failure message, but HMR should
86+
// still work after that... Maybe we can show a more specific error message than
87+
// the generic hydration failure one (that could be misleading in this case).
88+
//
89+
if (!$$anchor && current_hydration_fragment?.[0]) {
90+
const ssr0 = find_surrounding_ssr_commments();
91+
if (ssr0) {
92+
const [before, after] = ssr0;
93+
current_hydration_fragment.unshift(before);
94+
current_hydration_fragment.push(after);
95+
$$anchor = child_frag(current_hydration_fragment);
8596
}
97+
}
8698

87-
key(
88-
$$anchor,
89-
() => get(hot_data.component_signal),
90-
($$anchor) => {
91-
const component = get(hot_data.component_signal);
92-
// @ts-ignore
93-
const new_accessors = component($$anchor, ...args);
94-
95-
const removed_keys = new Set(accessors_keys);
96-
97-
if (new_accessors) {
98-
for (const [key, value] of Object.entries(new_accessors)) {
99-
accessors_proxy[key] = value;
100-
accessors_keys.add(key);
101-
removed_keys.delete(key);
102-
}
103-
}
99+
key(
100+
$$anchor,
101+
() => get(component_signal),
102+
($$anchor) => {
103+
const component = get(component_signal);
104104

105-
for (const key of removed_keys) {
106-
accessors_keys.delete(key);
107-
accessors_proxy[key] = undefined;
105+
// @ts-ignore
106+
const new_accessors = component($$anchor, ...args);
107+
108+
const removed_keys = new Set(accessors_keys);
109+
110+
if (new_accessors) {
111+
for (const [key, value] of Object.entries(new_accessors)) {
112+
accessors_proxy[key] = value;
113+
accessors_keys.add(key);
114+
removed_keys.delete(key);
108115
}
109116
}
110-
);
111117

112-
return accessors_proxy;
113-
};
118+
for (const key of removed_keys) {
119+
accessors_keys.delete(key);
120+
accessors_proxy[key] = undefined;
121+
}
122+
}
123+
);
124+
125+
try {
126+
Object.defineProperty(proxy_component, 'name', {
127+
get() {
128+
return component_name;
129+
}
130+
});
131+
} catch (err) {
132+
console.warn("[Svelte HMR] Failed to proxy component function's name", err);
133+
}
134+
135+
return accessors_proxy;
136+
}
137+
138+
return { proxy_component, set_component };
139+
}
140+
141+
/**
142+
* @param {HotData} hot_data
143+
* @param {Component} new_component
144+
*/
145+
export function hmr(hot_data, new_component) {
146+
if (hot_data.set_component) {
147+
hot_data.set_component(new_component);
148+
} else {
149+
({
150+
//
151+
proxy_component: hot_data.proxy_component,
152+
set_component: hot_data.set_component
153+
} = create_proxy_component(new_component));
114154
}
115155

116-
return hot_data.proxy;
156+
return hot_data.proxy_component;
117157
}

0 commit comments

Comments
 (0)