fix: all hooks are orderable
This commit is contained in:
parent
ed73e3a8f3
commit
e4a3a912cd
|
@ -62,10 +62,10 @@ class Flecks {
|
||||||
|
|
||||||
config = {};
|
config = {};
|
||||||
|
|
||||||
$$expandedFlecksCache = {};
|
|
||||||
|
|
||||||
flecks = {};
|
flecks = {};
|
||||||
|
|
||||||
|
$$flecksImplementingCache = {};
|
||||||
|
|
||||||
$$gathered = {};
|
$$gathered = {};
|
||||||
|
|
||||||
hooks = {};
|
hooks = {};
|
||||||
|
@ -254,7 +254,7 @@ class Flecks {
|
||||||
* Destroy this instance.
|
* Destroy this instance.
|
||||||
*/
|
*/
|
||||||
destroy() {
|
destroy() {
|
||||||
this.$$expandedFlecksCache = {};
|
this.$$flecksImplementingCache = {};
|
||||||
this.config = {};
|
this.config = {};
|
||||||
this.$$gathered = {};
|
this.$$gathered = {};
|
||||||
this.hooks = {};
|
this.hooks = {};
|
||||||
|
@ -314,9 +314,9 @@ class Flecks {
|
||||||
* @param {string} hook
|
* @param {string} hook
|
||||||
* @returns {string[]} The expanded list of flecks.
|
* @returns {string[]} The expanded list of flecks.
|
||||||
*/
|
*/
|
||||||
expandedFlecks(hook) {
|
flecksImplementing(hook) {
|
||||||
if (this.$$expandedFlecksCache[hook]) {
|
if (this.$$flecksImplementingCache[hook]) {
|
||||||
return [...this.$$expandedFlecksCache[hook]];
|
return [...this.$$flecksImplementingCache[hook]];
|
||||||
}
|
}
|
||||||
const flecks = this.lookupFlecks(hook);
|
const flecks = this.lookupFlecks(hook);
|
||||||
let expanded = [];
|
let expanded = [];
|
||||||
|
@ -338,7 +338,7 @@ class Flecks {
|
||||||
expanded.splice(index, 1);
|
expanded.splice(index, 1);
|
||||||
// Expand elided flecks.
|
// Expand elided flecks.
|
||||||
const elided = [];
|
const elided = [];
|
||||||
const implementing = this.flecksImplementing(hook);
|
const implementing = this.hooks[hook]?.map(({fleck}) => fleck) || [];
|
||||||
for (let i = 0; i < implementing.length; ++i) {
|
for (let i = 0; i < implementing.length; ++i) {
|
||||||
const fleck = implementing[i];
|
const fleck = implementing[i];
|
||||||
if (!expanded.includes(fleck)) {
|
if (!expanded.includes(fleck)) {
|
||||||
|
@ -400,10 +400,10 @@ class Flecks {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Filter unimplemented.
|
// Filter unimplemented.
|
||||||
this.$$expandedFlecksCache[hook] = expanded // eslint-disable-line no-return-assign
|
this.$$flecksImplementingCache[hook] = expanded // eslint-disable-line no-return-assign
|
||||||
.filter((fleck) => this.fleckImplementation(fleck, hook));
|
.filter((fleck) => this.fleckImplementation(fleck, hook));
|
||||||
this.constructor.debugSilly("cached hook expansion for '%s': %O", hook, expanded);
|
this.constructor.debugSilly("cached hook expansion for '%s': %O", hook, expanded);
|
||||||
return [...this.$$expandedFlecksCache[hook]];
|
return [...this.$$flecksImplementingCache[hook]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -435,16 +435,6 @@ class Flecks {
|
||||||
return found.fn;
|
return found.fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of flecks implementing a hook.
|
|
||||||
*
|
|
||||||
* @param {string} hook
|
|
||||||
* @returns {string[]}
|
|
||||||
*/
|
|
||||||
flecksImplementing(hook) {
|
|
||||||
return this.hooks[hook]?.map(({fleck}) => fleck) || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a dependency graph from a list of flecks.
|
* Create a dependency graph from a list of flecks.
|
||||||
* @param {string[]} flecks
|
* @param {string[]} flecks
|
||||||
|
@ -662,8 +652,7 @@ class Flecks {
|
||||||
if (!this.hooks[hook]) {
|
if (!this.hooks[hook]) {
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
const flecks = this.expandedFlecks(hook);
|
return this.flecksImplementing(hook)
|
||||||
return flecks
|
|
||||||
.reduce((r, fleck) => this.invokeFleck(hook, fleck, r, ...args), initial);
|
.reduce((r, fleck) => this.invokeFleck(hook, fleck, r, ...args), initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,8 +665,7 @@ class Flecks {
|
||||||
if (!this.hooks[hook]) {
|
if (!this.hooks[hook]) {
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
const flecks = this.expandedFlecks(hook);
|
return this.flecksImplementing(hook)
|
||||||
return flecks
|
|
||||||
.reduce(async (r, fleck) => this.invokeFleck(hook, fleck, await r, ...args), arg);
|
.reduce(async (r, fleck) => this.invokeFleck(hook, fleck, await r, ...args), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +680,8 @@ class Flecks {
|
||||||
if (!this.hooks[hook]) {
|
if (!this.hooks[hook]) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return this.hooks[hook].map(({fleck}) => this.invokeFleck(hook, fleck, ...args));
|
return this.flecksImplementing(hook)
|
||||||
|
.map((fleck) => this.invokeFleck(hook, fleck, ...args));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -831,7 +820,7 @@ class Flecks {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const results = [];
|
const results = [];
|
||||||
const flecks = this.expandedFlecks(hook);
|
const flecks = this.flecksImplementing(hook);
|
||||||
while (flecks.length > 0) {
|
while (flecks.length > 0) {
|
||||||
const fleck = flecks.shift();
|
const fleck = flecks.shift();
|
||||||
results.push(this.invokeFleck(hook, fleck, ...args));
|
results.push(this.invokeFleck(hook, fleck, ...args));
|
||||||
|
@ -849,7 +838,7 @@ class Flecks {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const results = [];
|
const results = [];
|
||||||
const flecks = this.expandedFlecks(hook);
|
const flecks = this.flecksImplementing(hook);
|
||||||
while (flecks.length > 0) {
|
while (flecks.length > 0) {
|
||||||
const fleck = flecks.shift();
|
const fleck = flecks.shift();
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
@ -888,7 +877,7 @@ class Flecks {
|
||||||
if (!this.hooks[hook]) {
|
if (!this.hooks[hook]) {
|
||||||
return (...args) => args.pop()();
|
return (...args) => args.pop()();
|
||||||
}
|
}
|
||||||
const flecks = this.expandedFlecks(hook);
|
const flecks = this.flecksImplementing(hook);
|
||||||
if (0 === flecks.length) {
|
if (0 === flecks.length) {
|
||||||
// No flecks, immediate dispatch.
|
// No flecks, immediate dispatch.
|
||||||
return (...args) => args.pop()();
|
return (...args) => args.pop()();
|
||||||
|
|
|
@ -12,7 +12,7 @@ it('includes all by default', async () => {
|
||||||
two: {hooks: {'one.test': () => {}}},
|
two: {hooks: {'one.test': () => {}}},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(flecks.expandedFlecks('one.test'))
|
expect(flecks.flecksImplementing('one.test'))
|
||||||
.to.deep.equal(['one', 'two']);
|
.to.deep.equal(['one', 'two']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ it('respects elision', async () => {
|
||||||
four: {hooks: {'one.test': () => {}}},
|
four: {hooks: {'one.test': () => {}}},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const expanded = flecks.expandedFlecks('one.test');
|
const expanded = flecks.flecksImplementing('one.test');
|
||||||
expect(expanded.shift())
|
expect(expanded.shift())
|
||||||
.to.equal('two');
|
.to.equal('two');
|
||||||
expect(expanded.pop())
|
expect(expanded.pop())
|
||||||
|
@ -49,7 +49,7 @@ it('detects yet allows suspicious hook ordering', async () => {
|
||||||
Flecks.debug = (message) => {
|
Flecks.debug = (message) => {
|
||||||
suspected = message.includes('Suspicious ordering specification');
|
suspected = message.includes('Suspicious ordering specification');
|
||||||
};
|
};
|
||||||
expect(flecks.expandedFlecks('one.test'))
|
expect(flecks.flecksImplementing('one.test'))
|
||||||
.to.deep.equal(['one', 'two']);
|
.to.deep.equal(['one', 'two']);
|
||||||
expect(suspected)
|
expect(suspected)
|
||||||
.to.be.true;
|
.to.be.true;
|
||||||
|
@ -62,6 +62,6 @@ it('throws on cyclic dependency', async () => {
|
||||||
two: {hooks: {'one.test': Flecks.priority(() => {}, {before: 'one'})}},
|
two: {hooks: {'one.test': Flecks.priority(() => {}, {before: 'one'})}},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(() => flecks.expandedFlecks('one.test'))
|
expect(() => flecks.flecksImplementing('one.test'))
|
||||||
.to.throw(/Illegal ordering specification/);
|
.to.throw(/Illegal ordering specification/);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user