|
1 | 1 | 'use strict';
|
2 |
| -// TODO: Clean up. |
3 |
| -let isMainThread = true; |
4 |
| -let supportsWorkers = false; |
5 |
| -try { |
6 |
| - ({isMainThread} = require('worker_threads')); |
7 |
| - supportsWorkers = true; |
8 |
| -} catch {} |
9 |
| - |
10 |
| -const {classify, hasExtension, isHelperish, matches, normalizeFileForMatching, normalizeGlobs, normalizePatterns} = require('./lib/globs'); |
11 |
| - |
12 |
| -let resolveGlobs; |
13 |
| -let resolveGlobsSync; |
14 |
| - |
15 |
| -if (!supportsWorkers || !isMainThread) { |
16 |
| - const normalizeExtensions = require('./lib/extensions'); |
17 |
| - const {loadConfig, loadConfigSync} = require('./lib/load-config'); |
18 |
| - const providerManager = require('./lib/provider-manager'); |
19 |
| - |
20 |
| - const configCache = new Map(); |
21 |
| - |
22 |
| - const collectProviders = ({conf, projectDir}) => { |
23 |
| - const providers = []; |
24 |
| - if (Reflect.has(conf, 'babel')) { |
25 |
| - const {level, main} = providerManager.babel(projectDir); |
26 |
| - providers.push({ |
27 |
| - level, |
28 |
| - main: main({config: conf.babel}), |
29 |
| - type: 'babel' |
30 |
| - }); |
31 |
| - } |
32 |
| - |
33 |
| - if (Reflect.has(conf, 'typescript')) { |
34 |
| - const {level, main} = providerManager.typescript(projectDir); |
35 |
| - providers.push({ |
36 |
| - level, |
37 |
| - main: main({config: conf.typescript}), |
38 |
| - type: 'typescript' |
39 |
| - }); |
40 |
| - } |
| 2 | +const v8 = require('v8'); |
| 3 | +const {Worker} = require('worker_threads'); |
41 | 4 |
|
42 |
| - return providers; |
43 |
| - }; |
44 |
| - |
45 |
| - const buildGlobs = ({conf, providers, projectDir, overrideExtensions, overrideFiles}) => { |
46 |
| - const extensions = overrideExtensions ? |
47 |
| - normalizeExtensions(overrideExtensions) : |
48 |
| - normalizeExtensions(conf.extensions, providers); |
49 |
| - |
50 |
| - return { |
51 |
| - cwd: projectDir, |
52 |
| - ...normalizeGlobs({ |
53 |
| - extensions, |
54 |
| - files: overrideFiles ? overrideFiles : conf.files, |
55 |
| - providers |
56 |
| - }) |
57 |
| - }; |
58 |
| - }; |
| 5 | +const {classify, hasExtension, isHelperish, matches, normalizeFileForMatching, normalizePatterns} = require('./lib/globs'); |
59 | 6 |
|
60 |
| - resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => { |
61 |
| - if (!configCache.has(projectDir)) { |
62 |
| - const conf = loadConfigSync({resolveFrom: projectDir}); |
63 |
| - const providers = collectProviders({conf, projectDir}); |
64 |
| - configCache.set(projectDir, {conf, providers}); |
65 |
| - } |
| 7 | +const MAX_DATA_LENGTH_EXCLUSIVE = 100 * 1024; // Allocate 100 KiB to exchange globs. |
66 | 8 |
|
67 |
| - const {conf, providers} = configCache.get(projectDir); |
68 |
| - return buildGlobs({conf, providers, projectDir, overrideExtensions, overrideFiles}); |
69 |
| - }; |
| 9 | +let data; |
| 10 | +let sync; |
| 11 | +let worker; |
70 | 12 |
|
71 |
| - resolveGlobs = async (projectDir, overrideExtensions, overrideFiles) => { |
72 |
| - if (!configCache.has(projectDir)) { |
73 |
| - configCache.set(projectDir, loadConfig({resolveFrom: projectDir}).then(conf => { // eslint-disable-line promise/prefer-await-to-then |
74 |
| - const providers = collectProviders({conf, projectDir}); |
75 |
| - return {conf, providers}; |
76 |
| - })); |
77 |
| - } |
| 13 | +const resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => { |
| 14 | + if (worker === undefined) { |
| 15 | + const dataBuffer = new SharedArrayBuffer(MAX_DATA_LENGTH_EXCLUSIVE); |
| 16 | + data = new Uint8Array(dataBuffer); |
78 | 17 |
|
79 |
| - const {conf, providers} = await configCache.get(projectDir); |
80 |
| - return buildGlobs({conf, providers, projectDir, overrideExtensions, overrideFiles}); |
81 |
| - }; |
82 |
| -} |
| 18 | + const syncBuffer = new SharedArrayBuffer(4); |
| 19 | + sync = new Int32Array(syncBuffer); |
83 | 20 |
|
84 |
| -if (supportsWorkers) { |
85 |
| - const v8 = require('v8'); |
86 |
| - |
87 |
| - const MAX_DATA_LENGTH_EXCLUSIVE = 100 * 1024; // Allocate 100 KiB to exchange globs. |
88 |
| - |
89 |
| - if (isMainThread) { |
90 |
| - const {Worker} = require('worker_threads'); |
91 |
| - let data; |
92 |
| - let sync; |
93 |
| - let worker; |
94 |
| - |
95 |
| - resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => { |
96 |
| - if (worker === undefined) { |
97 |
| - const dataBuffer = new SharedArrayBuffer(MAX_DATA_LENGTH_EXCLUSIVE); |
98 |
| - data = new Uint8Array(dataBuffer); |
99 |
| - |
100 |
| - const syncBuffer = new SharedArrayBuffer(4); |
101 |
| - sync = new Int32Array(syncBuffer); |
102 |
| - |
103 |
| - worker = new Worker(__filename, { |
104 |
| - workerData: { |
105 |
| - dataBuffer, |
106 |
| - syncBuffer, |
107 |
| - firstMessage: {projectDir, overrideExtensions, overrideFiles} |
108 |
| - } |
109 |
| - }); |
110 |
| - worker.unref(); |
111 |
| - } else { |
112 |
| - worker.postMessage({projectDir, overrideExtensions, overrideFiles}); |
| 21 | + worker = new Worker('./lib/eslint-plugin-helper-worker.js', { |
| 22 | + workerData: { |
| 23 | + dataBuffer, |
| 24 | + syncBuffer, |
| 25 | + firstMessage: {projectDir, overrideExtensions, overrideFiles} |
113 | 26 | }
|
114 |
| - |
115 |
| - Atomics.wait(sync, 0, 0); |
116 |
| - |
117 |
| - const byteLength = Atomics.exchange(sync, 0, 0); |
118 |
| - if (byteLength === MAX_DATA_LENGTH_EXCLUSIVE) { |
119 |
| - throw new Error('Globs are over 100 KiB and cannot be resolved'); |
120 |
| - } |
121 |
| - |
122 |
| - const globsOrError = v8.deserialize(data.slice(0, byteLength)); |
123 |
| - if (globsOrError instanceof Error) { |
124 |
| - throw globsOrError; |
125 |
| - } |
126 |
| - |
127 |
| - return globsOrError; |
128 |
| - }; |
| 27 | + }); |
| 28 | + worker.unref(); |
129 | 29 | } else {
|
130 |
| - const {parentPort, workerData} = require('worker_threads'); |
131 |
| - const data = new Uint8Array(workerData.dataBuffer); |
132 |
| - const sync = new Int32Array(workerData.syncBuffer); |
133 |
| - |
134 |
| - const handleMessage = async ({projectDir, overrideExtensions, overrideFiles}) => { |
135 |
| - let encoded; |
136 |
| - try { |
137 |
| - const globs = await resolveGlobs(projectDir, overrideExtensions, overrideFiles); |
138 |
| - encoded = v8.serialize(globs); |
139 |
| - } catch (error) { |
140 |
| - encoded = v8.serialize(error); |
141 |
| - } |
| 30 | + worker.postMessage({projectDir, overrideExtensions, overrideFiles}); |
| 31 | + } |
142 | 32 |
|
143 |
| - const byteLength = encoded.length < MAX_DATA_LENGTH_EXCLUSIVE ? encoded.copy(data) : MAX_DATA_LENGTH_EXCLUSIVE; |
144 |
| - Atomics.store(sync, 0, byteLength); |
145 |
| - Atomics.notify(sync, 0); |
146 |
| - }; |
| 33 | + Atomics.wait(sync, 0, 0); |
147 | 34 |
|
148 |
| - parentPort.on('message', handleMessage); |
149 |
| - handleMessage(workerData.firstMessage); |
150 |
| - delete workerData.firstMessage; |
| 35 | + const byteLength = Atomics.exchange(sync, 0, 0); |
| 36 | + if (byteLength === MAX_DATA_LENGTH_EXCLUSIVE) { |
| 37 | + throw new Error('Globs are over 100 KiB and cannot be resolved'); |
151 | 38 | }
|
152 |
| -} |
| 39 | + |
| 40 | + const globsOrError = v8.deserialize(data.slice(0, byteLength)); |
| 41 | + if (globsOrError instanceof Error) { |
| 42 | + throw globsOrError; |
| 43 | + } |
| 44 | + |
| 45 | + return globsOrError; |
| 46 | +}; |
153 | 47 |
|
154 | 48 | const helperCache = new Map();
|
155 | 49 |
|
|
0 commit comments