feat: hooks!
This commit is contained in:
parent
3b3ee97e70
commit
2fdee43950
|
@ -5,3 +5,11 @@ export function arrayUnique(array) {
|
|||
export function flatten(array) {
|
||||
return array.reduce((flattened, elm) => flattened.concat(elm), []);
|
||||
}
|
||||
|
||||
export function fromObject(object) {
|
||||
const array = [];
|
||||
for (const key in object) {
|
||||
array.push(object[key]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
|
1
packages/core/hook/entry.js
Normal file
1
packages/core/hook/entry.js
Normal file
|
@ -0,0 +1 @@
|
|||
// I don't know how to create assets out of thin air with webpack.
|
72
packages/core/hook/loader.js
Normal file
72
packages/core/hook/loader.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
const glob = require('glob');
|
||||
const {getOptions} = require('loader-utils');
|
||||
const path = require('path');
|
||||
const validateOptions = require('schema-utils');
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
paths: {
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
type: 'array',
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'paths',
|
||||
],
|
||||
};
|
||||
|
||||
// Dynamically require all traits.
|
||||
module.exports = function(source) {
|
||||
const options = getOptions(this);
|
||||
// Validate schema.
|
||||
validateOptions(schema, options, 'Avocado hooks');
|
||||
// Extract options.
|
||||
const {paths} = options;
|
||||
// Search avocado.
|
||||
const avocadoPath = path.normalize(
|
||||
path.join(__dirname, '..', '..'),
|
||||
);
|
||||
paths.push(avocadoPath);
|
||||
// Get source paths.
|
||||
const sourcePaths = [];
|
||||
paths.forEach((path) => {
|
||||
const files = glob.sync(`${path}/**/hooks.js`, {
|
||||
follow: true,
|
||||
});
|
||||
sourcePaths.push(...files);
|
||||
});
|
||||
// Build registers.
|
||||
const registers = sourcePaths.map((sourcePath) => {
|
||||
const relativePath = path.relative(__dirname, sourcePath);
|
||||
const basename = path.basename(relativePath, '.js');
|
||||
const parts = relativePath.split('/');
|
||||
// Chop off basename.
|
||||
parts.pop();
|
||||
// Module or local?
|
||||
let importDirectory;
|
||||
if ('..' === parts[0]) {
|
||||
const avocadoPathParts = ['@avocado', 'core', 'hook'].concat(parts);
|
||||
importDirectory = path.normalize(avocadoPathParts.join('/'));
|
||||
}
|
||||
else if ('node_modules' === parts[0]) {
|
||||
importDirectory = parts.slice(1).join('/');
|
||||
}
|
||||
else {
|
||||
importDirectory = `./${parts.join('/')}`;
|
||||
}
|
||||
// Register hooks.
|
||||
const importPath = `${importDirectory}/hooks`;
|
||||
return [
|
||||
`registerHooks('${importDirectory}', require('${importPath}'));`,
|
||||
].join('\n');
|
||||
});
|
||||
// Import trait registry first.
|
||||
const output = [
|
||||
`import {registerHooks} from '@avocado/core/hook/registry'`,
|
||||
'',
|
||||
...registers
|
||||
].join('\n');
|
||||
return output;
|
||||
}
|
27
packages/core/hook/registry.js
Normal file
27
packages/core/hook/registry.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import {fromObject} from '../array';
|
||||
|
||||
const impl = {};
|
||||
export function registerHooks(name, implementations) {
|
||||
for (const hook in implementations) {
|
||||
if (!impl[hook]) {
|
||||
impl[hook] = {};
|
||||
}
|
||||
impl[hook][name] = implementations[hook];
|
||||
}
|
||||
}
|
||||
|
||||
export function invoke(hook, ...args) {
|
||||
const hookImpl = impl[hook];
|
||||
if (!hookImpl) {
|
||||
return {};
|
||||
}
|
||||
const result = {};
|
||||
for (const name in hookImpl) {
|
||||
result[name] = hookImpl[name](...args);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function invokeFlat(hook, ...args) {
|
||||
return fromObject(invoke(hook, ...args));
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
export {arrayUnique, flatten} from './array';
|
||||
export {arrayUnique, flatten, fromObject as arrayFromObject} from './array';
|
||||
export {EventEmitterMixin as EventEmitter} from './event-emitter';
|
||||
export {invoke as invokeHook, invokeFlat as invokeHookFlat} from './hook/registry';
|
||||
export {merge} from './merge';
|
||||
export {
|
||||
mergeDiff,
|
||||
|
|
Loading…
Reference in New Issue
Block a user