Skip to content

Commit b5afe79

Browse files
committed
Drop Svelte 2 from HMR
1 parent 8b7d9bc commit b5afe79

File tree

5 files changed

+96
-184
lines changed

5 files changed

+96
-184
lines changed

lib/hot-api.js

+87-35
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,103 @@
1-
import { Registry, configure as configureProxy, createProxy } from 'svelte-dev-helper';
1+
import { makeApplyHmr } from 'svelte-hmr/runtime';
22

3-
let hotOptions = {
4-
noPreserveState: false
5-
};
3+
// eslint-disable-next-line no-undef
4+
const g = typeof window !== 'undefined' ? window : global;
65

7-
export function configure(options) {
8-
hotOptions = Object.assign(hotOptions, options);
9-
configureProxy(hotOptions);
10-
}
6+
const globalKey =
7+
typeof Symbol !== 'undefined'
8+
? Symbol('SVELTE_LOADER_HOT')
9+
: '__SVELTE_LOADER_HOT';
1110

12-
export function register(id, component) {
11+
if (!g[globalKey]) {
12+
// do updating refs counting to know when a full update has been applied
13+
let updatingCount = 0;
1314

14-
//store original component in registry
15-
Registry.set(id, {
16-
rollback: null,
17-
component,
18-
instances: []
19-
});
15+
const notifyStart = () => {
16+
updatingCount++;
17+
};
2018

21-
//create the proxy itself
22-
const proxy = createProxy(id);
19+
const notifyError = reload => err => {
20+
const errString = (err && err.stack) || err;
21+
// eslint-disable-next-line no-console
22+
console.error(
23+
'[HMR] Failed to accept update (nollup compat mode)',
24+
errString
25+
);
26+
reload();
27+
notifyEnd();
28+
};
2329

24-
//patch the registry record with proxy constructor
25-
const record = Registry.get(id);
26-
record.proxy = proxy;
27-
Registry.set(id, record);
30+
const notifyEnd = () => {
31+
updatingCount--;
32+
if (updatingCount === 0) {
33+
// NOTE this message is important for timing in tests
34+
// eslint-disable-next-line no-console
35+
console.log('[HMR:Svelte] Up to date');
36+
}
37+
};
2838

29-
return proxy;
39+
g[globalKey] = {
40+
hotStates: {},
41+
notifyStart,
42+
notifyError,
43+
notifyEnd,
44+
};
3045
}
3146

32-
export function reload(id, component) {
47+
const runAcceptHandlers = acceptHandlers => {
48+
const queue = [...acceptHandlers];
49+
const next = () => {
50+
const cur = queue.shift();
51+
if (cur) {
52+
return cur(null).then(next);
53+
} else {
54+
return Promise.resolve(null);
55+
}
56+
};
57+
return next();
58+
};
3359

34-
const record = Registry.get(id);
60+
export const applyHmr = makeApplyHmr(args => {
61+
const { notifyStart, notifyError, notifyEnd } = g[globalKey];
62+
const { m, reload } = args;
3563

36-
//keep reference to previous version to enable rollback
37-
record.rollback = record.component;
64+
let acceptHandlers = (m.hot.data && m.hot.data.acceptHandlers) || [];
65+
let nextAcceptHandlers = [];
3866

39-
//replace component in registry with newly loaded component
40-
record.component = component;
67+
m.hot.dispose(data => {
68+
data.acceptHandlers = nextAcceptHandlers;
69+
});
4170

42-
Registry.set(id, record);
71+
const dispose = (...args) => m.hot.dispose(...args);
4372

44-
//re-render the proxy instances
45-
record.instances.slice().forEach(function(instance) {
46-
instance && instance._rerender();
73+
const accept = handler => {
74+
if (nextAcceptHandlers.length === 0) {
75+
m.hot.accept();
76+
}
77+
nextAcceptHandlers.push(handler);
78+
};
79+
80+
const check = status => {
81+
if (status === 'ready') {
82+
notifyStart();
83+
} else if (status === 'idle') {
84+
runAcceptHandlers(acceptHandlers)
85+
.then(notifyEnd)
86+
.catch(notifyError(reload));
87+
}
88+
};
89+
90+
m.hot.addStatusHandler(check);
91+
92+
m.hot.dispose(() => {
93+
m.hot.removeStatusHandler(check);
4794
});
4895

49-
//return the original proxy constructor that was `register()`-ed
50-
return record.proxy;
51-
}
96+
const hot = {
97+
data: m.hot.data,
98+
dispose,
99+
accept,
100+
};
101+
102+
return Object.assign({}, args, { hot });
103+
});

lib/make-hot.js

+7-24
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,12 @@
1-
const posixify = require('./posixify');
1+
const { walk } = require('./resolve-svelte');
2+
const { createMakeHot } = require('svelte-hmr');
23

34
const hotApi = require.resolve('./hot-api.js');
45

5-
function makeHot(id, code, hotOptions) {
6-
const options = JSON.stringify(hotOptions);
7-
const replacement = `
8-
if (module.hot) {
9-
const { configure, register, reload } = require('${posixify(hotApi)}');
10-
11-
module.hot.accept();
12-
13-
if (!module.hot.data) {
14-
// initial load
15-
configure(${options});
16-
$2 = register(${id}, $2);
17-
} else {
18-
// hot update
19-
$2 = reload(${id}, $2);
20-
}
21-
}
22-
23-
export default $2;
24-
`;
25-
26-
return code.replace(/(export default ([^;]*));/, replacement);
27-
}
6+
const makeHot = createMakeHot({
7+
walk,
8+
meta: 'module',
9+
hotApi,
10+
});
2811

2912
module.exports = makeHot;

lib/resolve-svelte.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,14 @@ const resolveSvelte = () => {
2525
};
2626

2727
const { req, base } = resolveSvelte();
28-
29-
const { version } = req(`${base}/package.json`);
30-
31-
const major_version = +version[0];
32-
33-
const { compile, preprocess, walk } =
34-
major_version >= 3 ? req(`${base}/compiler`) : req(`${base}`);
28+
const { compile, preprocess, walk } = req(`${base}/compiler`);
3529

3630
module.exports = {
37-
major_version,
3831
compile,
3932
preprocess,
4033
walk,
4134
};
4235

4336
// NOTE svelte3/make-hot requires this module to get the walk function, so we
4437
// need to have walk available on module.exports before requiring it from here
45-
module.exports.makeHot =
46-
major_version >= 3 ? require('./svelte3/make-hot') : require('./make-hot');
38+
module.exports.makeHot = require('./make-hot');

lib/svelte3/hot-api.js

-103
This file was deleted.

lib/svelte3/make-hot.js

-12
This file was deleted.

0 commit comments

Comments
 (0)