diff --git a/packages/core/src/latus.js b/packages/core/src/latus.js index cab001d..9ab5b9d 100644 --- a/packages/core/src/latus.js +++ b/packages/core/src/latus.js @@ -275,6 +275,45 @@ export default class Latus { }); } + refresh(plugin, M) { + const keys = Object.keys(this.hooks); + for (let j = 0; j < keys.length; j++) { + const key = keys[j]; + if (this.hooks[key]) { + const index = this.hooks[key].findIndex(({plugin: hookPlugin}) => hookPlugin === plugin); + if (-1 !== index) { + this.hooks[key].splice(index, 1); + } + } + } + if (M.default) { + const {default: {hooks}} = M; + if (hooks) { + const keys = Object.keys(hooks); + debug("hooks for '%s': %O", plugin, keys); + for (let j = 0; j < keys.length; j++) { + const key = keys[j]; + if (!this.hooks[key]) { + this.hooks[key] = []; + } + this.hooks[key].push({ + plugin, + fn: hooks[key], + }); + } + } + } + else { + debug(`'${plugin}' has no default export`); + } + const defaultConfig = this.invoke('@latus/core/config'); + this.config[plugin] = { + ...defaultConfig[plugin], + ...this.config[plugin], + }; + this.invokeFlat('@latus/core/config/alter', this.config); + } + static runtimePath(path) { try { R.resolve(path); diff --git a/packages/http/src/build/neutrino/virtual.js b/packages/http/src/build/neutrino/virtual.js index a088322..38f8fd9 100644 --- a/packages/http/src/build/neutrino/virtual.js +++ b/packages/http/src/build/neutrino/virtual.js @@ -41,6 +41,7 @@ module.exports = async (latus) => { const contexts = new Set(); paths.forEach((path) => { source.push(` module.hot.accept('${path}', () => {`); + source.push(` window.latus.refresh('${path}', require('${path}'));`); source.push(` window.latus.invoke('@latus/core/hmr', '${path}');`); source.push(' });'); const context = join(dirname(R.resolve(path)), 'assets'); diff --git a/packages/react/src/hooks/use-latus.js b/packages/react/src/hooks/use-latus.js index 72869c3..9cdfb72 100644 --- a/packages/react/src/hooks/use-latus.js +++ b/packages/react/src/hooks/use-latus.js @@ -1,6 +1,21 @@ -import {useContext} from 'react'; +import {useContext, useEffect, useState} from 'react'; // eslint-disable-next-line import/no-extraneous-dependencies import {LatusContext} from '@latus/react/client'; -export default () => useContext(LatusContext); +export default () => { + const [, setId] = useState(0); + const latus = useContext(LatusContext); + useEffect(() => { + if (!latus.hooks['@latus/core/hmr']) { + latus.hooks['@latus/core/hmr'] = []; + } + latus.hooks['@latus/core/hmr'].push({ + plugin: '@latus/react/hmr', + fn: () => { + setId(Math.random()); + }, + }); + }, [latus]); + return latus; +};