feat: gathered HMR!!
This commit is contained in:
parent
b525489b7e
commit
34170ed0f9
|
@ -6,6 +6,8 @@ import {camelCase} from './string';
|
|||
|
||||
const debug = D('@latus/core/gather');
|
||||
|
||||
export const hotGathered = new Map();
|
||||
|
||||
export const decorateWithLatus = (
|
||||
context,
|
||||
{
|
||||
|
@ -47,30 +49,11 @@ export const gatherWithLatus = (
|
|||
}))
|
||||
);
|
||||
|
||||
export default (
|
||||
latus,
|
||||
{
|
||||
type,
|
||||
idAttribute = 'id',
|
||||
typeAttribute = 'type',
|
||||
check = () => {},
|
||||
},
|
||||
) => {
|
||||
const gathered = latus.invokeReduce(type);
|
||||
check(gathered, type);
|
||||
const composed = latus.invokeComposed(`${type}.decorate`, gathered);
|
||||
check(composed, `${type}.decorate`);
|
||||
let uid = 1;
|
||||
const fromId = {};
|
||||
const fromType = Object.fromEntries(
|
||||
Object.entries(composed)
|
||||
.sort(([lname], [rname]) => (lname < rname ? -1 : 1))
|
||||
.map(([type, Class]) => {
|
||||
const thisUid = uid++;
|
||||
const wrapperClass = (Class, id, idAttribute, type, typeAttribute) => {
|
||||
class Subclass extends Class {
|
||||
|
||||
static get [idAttribute]() {
|
||||
return thisUid;
|
||||
return id;
|
||||
}
|
||||
|
||||
static get [typeAttribute]() {
|
||||
|
@ -78,20 +61,76 @@ export default (
|
|||
}
|
||||
|
||||
}
|
||||
if (!Subclass.name) {
|
||||
Subclass.name = type;
|
||||
}
|
||||
fromId[thisUid] = Subclass;
|
||||
return Subclass;
|
||||
};
|
||||
|
||||
export default (
|
||||
latus,
|
||||
{
|
||||
type: hook,
|
||||
idAttribute = 'id',
|
||||
typeAttribute = 'type',
|
||||
check = () => {},
|
||||
},
|
||||
) => {
|
||||
const raw = latus.invokeReduce(hook);
|
||||
check(raw, hook);
|
||||
const composed = latus.invokeComposed(`${hook}.decorate`, raw);
|
||||
check(composed, `${hook}.decorate`);
|
||||
let uid = 1;
|
||||
const fromId = {};
|
||||
const fromType = Object.fromEntries(
|
||||
Object.entries(composed)
|
||||
.sort(([lname], [rname]) => (lname < rname ? -1 : 1))
|
||||
.map(([type, Class]) => {
|
||||
const id = uid++;
|
||||
const Subclass = wrapperClass(Class, id, idAttribute, type, typeAttribute);
|
||||
fromId[id] = Subclass;
|
||||
return [
|
||||
type,
|
||||
Subclass,
|
||||
];
|
||||
}),
|
||||
);
|
||||
const result = {
|
||||
const gathered = {
|
||||
...fromId,
|
||||
...fromType,
|
||||
};
|
||||
debug("gathered '%s': %O", type, result);
|
||||
return result;
|
||||
hotGathered.set(hook, {
|
||||
idAttribute,
|
||||
gathered,
|
||||
typeAttribute,
|
||||
});
|
||||
debug("gathered '%s': %O", hook, gathered);
|
||||
return gathered;
|
||||
};
|
||||
|
||||
export const refresh = (path, latus) => {
|
||||
const it = hotGathered.entries();
|
||||
for (let current = it.next(); current.done !== true; current = it.next()) {
|
||||
const {
|
||||
value: [
|
||||
hook,
|
||||
{
|
||||
idAttribute,
|
||||
gathered,
|
||||
typeAttribute,
|
||||
},
|
||||
],
|
||||
} = current;
|
||||
const updates = latus.invokePlugin(hook, path);
|
||||
if (!updates) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
const entries = Object.entries(updates);
|
||||
for (let i = 0; i < entries.length; ++i) {
|
||||
const [type, Class] = entries[i];
|
||||
const {[type]: {[idAttribute]: id}} = gathered;
|
||||
const Subclass = wrapperClass(Class, id, idAttribute, type, typeAttribute);
|
||||
gathered[type] = Subclass;
|
||||
gathered[id] = Subclass;
|
||||
latus.invoke('@latus/core/gathered/hmr', Subclass, hook);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// eslint-disable-next-line max-classes-per-file
|
||||
import {refresh} from './gather';
|
||||
|
||||
export {
|
||||
unique as arrayUnique,
|
||||
flatten as arrayFlatten,
|
||||
|
@ -22,5 +25,6 @@ export default {
|
|||
'@latus/core/config': () => ({
|
||||
id: 'latus',
|
||||
}),
|
||||
'@latus/core/hmr': refresh,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user