Skip to content

Commit 05963fb

Browse files
committed
feature(@putout/engine-loader) loadProcessors -> loadProcessorsAsync
1 parent f8fad38 commit 05963fb

8 files changed

Lines changed: 159 additions & 24 deletions

File tree

packages/engine-loader/README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,31 @@ const plugins = loadPlugins({
6161
});
6262
```
6363

64-
### loadProcessors
64+
### loadProcessorsAsync
6565

6666
```js
6767
const {loadProcessors} = require('@putout/engine-loader');
6868

69-
const plugins = loadProcessors({
69+
const plugins = await loadProcessorsAsync({
7070
processors: [
7171
['javascript', 'on'],
7272
['markdown', 'off'],
7373
],
7474
});
7575
```
7676

77+
### createAsyncLoader
78+
79+
Gives ability to create loader for `processor` or `formatter`.
80+
81+
```js
82+
const {createAsyncLoader} = require('@putout/engine-loader');
83+
const {loadProcessor} = createAsyncLoader('processor');
84+
85+
await loadProcessors('markdown');
86+
// loads @putout/processor-markdown
87+
```
88+
7789
## License
7890

7991
MIT
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'use strict';
2+
3+
const tryToCatch = require('try-to-catch');
4+
const {simpleImportDefault} = require('./simple-import');
5+
6+
const {assign} = Object;
7+
const stub = () => () => {};
8+
9+
module.exports.createAsyncLoader = (type) => async (name) => {
10+
if (name === 'none')
11+
return stub();
12+
13+
const [e, reporter] = await cleverLoad([
14+
`@putout/${type}-${name}`,
15+
`putout-${type}-${name}`,
16+
]);
17+
18+
if (e)
19+
throw e;
20+
21+
return reporter;
22+
};
23+
24+
async function cleverLoad(names) {
25+
let e;
26+
let reporter;
27+
28+
for (const name of names) {
29+
[e, reporter] = await tryToCatch(simpleImportDefault, name);
30+
31+
if (!e)
32+
return [null, reporter];
33+
34+
if (e.code === 'ERR_MODULE_NOT_FOUND')
35+
continue;
36+
37+
assign(e, {
38+
message: `${name}: ${e.message}`,
39+
});
40+
41+
return [e];
42+
}
43+
44+
assign(e, {
45+
message: e.message.replace(/\simported.*/, ''),
46+
});
47+
48+
return [e];
49+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
'use strict';
2+
3+
const tryToCatch = require('try-to-catch');
4+
5+
const test = require('supertape');
6+
const stub = require('@cloudcmd/stub');
7+
const mockRequire = require('mock-require');
8+
9+
const {reRequire, stopAll} = mockRequire;
10+
const {assign} = Object;
11+
12+
test('putout: loader: async-loader: none', async (t) => {
13+
const {createAsyncLoader} = reRequire('./async-loader');
14+
const loadAsync = createAsyncLoader('formatter');
15+
16+
const result = await loadAsync('none');
17+
18+
t.equal(typeof result, 'function');
19+
t.end();
20+
});
21+
22+
test('putout: loader: async-loader: calls', async (t) => {
23+
const simpleImportDefault = stub()
24+
.rejects(assign(Error('not found'), {
25+
code: 'ERR_MODULE_NOT_FOUND',
26+
}));
27+
28+
mockRequire('./simple-import', {
29+
simpleImportDefault,
30+
});
31+
32+
const {createAsyncLoader} = reRequire('./async-loader');
33+
const loadAsync = createAsyncLoader('formatter');
34+
35+
await tryToCatch(loadAsync, 'xxx');
36+
const expected = [
37+
['@putout/formatter-xxx'],
38+
['putout-formatter-xxx'],
39+
];
40+
41+
stopAll();
42+
reRequire('./async-loader');
43+
44+
t.deepEqual(simpleImportDefault.args, expected);
45+
t.end();
46+
});
47+
48+
test('putout: loader: async-loader: rejects', async (t) => {
49+
const simpleImportDefault = stub()
50+
.rejects(assign(Error('not found'), {
51+
code: 'Syntax Error',
52+
}));
53+
54+
mockRequire('./simple-import', {
55+
simpleImportDefault,
56+
});
57+
58+
const {createAsyncLoader} = reRequire('./async-loader');
59+
const loadAsync = createAsyncLoader('formatter');
60+
61+
const [error] = await tryToCatch(loadAsync, 'xxx');
62+
const expected = Error('@putout/formatter-xxx: not found');
63+
64+
stopAll();
65+
reRequire('./async-loader');
66+
67+
t.deepEqual(error, expected);
68+
t.end();
69+
});

packages/engine-loader/lib/index.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
const memo = require('nano-memoize');
44

55
const isEnabled = require('./is-enabled');
6-
const {
7-
loadPlugin,
8-
loadProcessor,
9-
} = require('./load');
6+
const {loadPlugin} = require('./load');
7+
const {createAsyncLoader} = require('./async-loader');
108
const parsePluginNames = require('./parse-plugin-names');
119
const parseProcessorNames = require('./parse-processor-names');
1210
const parseRules = require('./parse-rules');
@@ -40,30 +38,32 @@ const mergeRules = ([rule, plugin], rules) => {
4038
};
4139
};
4240

43-
module.exports.loadProcessors = memo((options) => {
41+
module.exports.loadProcessorsAsync = memo(async (options) => {
4442
check(options);
4543

4644
const {
4745
processors = [],
4846
} = options;
4947

5048
const parsedProcessors = parseProcessorNames(processors);
49+
const loadProcessor = createAsyncLoader('processor');
5150

5251
const list = [];
53-
const namespace = 'putout';
5452

5553
for (const [name, fn] of parsedProcessors) {
5654
if (fn) {
5755
list.push(fn);
5856
continue;
5957
}
6058

61-
list.push(loadProcessor({name, namespace}));
59+
list.push(loadProcessor(name));
6260
}
6361

64-
return list;
62+
return await Promise.all(list);
6563
});
6664

65+
module.exports.createAsyncLoader = createAsyncLoader;
66+
6767
module.exports.loadPlugins = (options) => {
6868
check(options);
6969

packages/engine-loader/lib/load.spec.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
'use strict';
22

33
const tryCatch = require('try-catch');
4-
54
const mockRequire = require('mock-require');
6-
75
const {test, stub} = require('supertape');
86

97
const {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict';
2+
3+
// How in other way to mock import using mock require in CommonJS?
4+
module.exports.simpleImportDefault = async (url) => (await import(url)).default;
5+

packages/engine-loader/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
"diff-match-patch": "^1.0.4",
3030
"nano-memoize": "^1.1.8",
3131
"once": "^1.4.0",
32-
"try-catch": "^3.0.0"
32+
"try-catch": "^3.0.0",
33+
"try-to-catch": "^3.0.1"
3334
},
3435
"keywords": [
3536
"putout",
@@ -39,6 +40,7 @@
3940
"devDependencies": {
4041
"@babel/plugin-codemod-object-assign-to-object-spread": "^7.7.4",
4142
"@cloudcmd/stub": "^3.0.0",
43+
"@putout/formatter-progress": "*",
4244
"@putout/plugin-convert-commonjs-to-esm": "*",
4345
"@putout/plugin-remove-unused-variables": "*",
4446
"@putout/processor-javascript": "*",

packages/engine-loader/test/load-processors.js renamed to packages/engine-loader/test/load-processors-async.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
const test = require('supertape');
44

55
const markdown = require('@putout/processor-markdown');
6-
const {loadProcessors} = require('..');
6+
const {loadProcessorsAsync} = require('..');
77

8-
test('putout: engine-loader: load processors', (t) => {
8+
test('putout: engine-loader: load processors', async (t) => {
99
const processorJavascript = require('@putout/processor-javascript');
1010

11-
const list = loadProcessors({
11+
const list = await loadProcessorsAsync({
1212
processors: [
1313
'javascript',
1414
],
@@ -22,21 +22,21 @@ test('putout: engine-loader: load processors', (t) => {
2222
t.end();
2323
});
2424

25-
test('putout: engine-loader: load processors: no processors', (t) => {
26-
const list = loadProcessors({});
25+
test('putout: engine-loader: load processors: no processors', async (t) => {
26+
const list = await loadProcessorsAsync({});
2727

2828
t.deepEqual(list, []);
2929
t.end();
3030
});
3131

32-
test('putout: engine-loader: load processors: function', (t) => {
32+
test('putout: engine-loader: load processors: function', async (t) => {
3333
const throwProcessor = {
3434
preProcess() {
3535
throw'Preprocess error';
3636
},
3737
};
3838

39-
const list = loadProcessors({
39+
const list = await loadProcessorsAsync({
4040
processors: [
4141
['throwProcessor', throwProcessor],
4242
],
@@ -50,8 +50,8 @@ test('putout: engine-loader: load processors: function', (t) => {
5050
t.end();
5151
});
5252

53-
test('putout: engine-loader: load processors: off', (t) => {
54-
const list = loadProcessors({
53+
test('putout: engine-loader: load processors: off', async (t) => {
54+
const list = await loadProcessorsAsync({
5555
processors: [
5656
['markdown', 'off'],
5757
],
@@ -64,8 +64,8 @@ test('putout: engine-loader: load processors: off', (t) => {
6464
t.end();
6565
});
6666

67-
test('putout: engine-loader: load processors: on', (t) => {
68-
const list = loadProcessors({
67+
test('putout: engine-loader: load processors: on', async (t) => {
68+
const list = await loadProcessorsAsync({
6969
processors: [
7070
['markdown', 'on'],
7171
],

0 commit comments

Comments
 (0)