monocart-reporter 1.6.36 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,11 +28,14 @@ const saveIstanbulReport = (coverageData, fileSources, options) => {
28
28
  data = {};
29
29
  Object.keys(coverageData).forEach((sourcePath) => {
30
30
  const d = coverageData[sourcePath];
31
- const newSourcePath = options.sourcePath(sourcePath, fileSources);
32
- if (newSourcePath) {
31
+ const s = fileSources[sourcePath];
32
+ const newSourcePath = options.sourcePath(sourcePath);
33
+ if (newSourcePath && newSourcePath !== sourcePath) {
33
34
  sourcePath = newSourcePath;
35
+ // related updates
36
+ fileSources[sourcePath] = s;
37
+ d.path = sourcePath;
34
38
  }
35
- d.path = sourcePath;
36
39
  data[sourcePath] = d;
37
40
  });
38
41
  }
@@ -40,6 +43,12 @@ const saveIstanbulReport = (coverageData, fileSources, options) => {
40
43
 
41
44
  const coverageMap = istanbulLibCoverage.createCoverageMap(data);
42
45
 
46
+ const { watermarks, defaultSummarizer } = options;
47
+ const istanbulOptions = {
48
+ watermarks,
49
+ defaultSummarizer
50
+ };
51
+
43
52
  // https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report
44
53
  const contextOptions = {
45
54
  watermarks: {
@@ -52,7 +61,7 @@ const saveIstanbulReport = (coverageData, fileSources, options) => {
52
61
  // values can be nested/flat/pkg. Defaults to 'pkg'
53
62
  defaultSummarizer: 'nested',
54
63
 
55
- ... options,
64
+ ... istanbulOptions,
56
65
 
57
66
  dir: options.htmlDir,
58
67
  sourceFinder: (filePath) => {
@@ -87,7 +96,7 @@ const saveIstanbulReport = (coverageData, fileSources, options) => {
87
96
  // create a context for report generation
88
97
  const context = istanbulLibReport.createContext(contextOptions);
89
98
 
90
- const htmlReport = istanbulReports.create('html', {});
99
+ const htmlReport = istanbulReports.create('html-spa', {});
91
100
  htmlReport.execute(context);
92
101
 
93
102
  const htmlPath = Util.relativePath(path.resolve(options.htmlDir, 'index.html'));
@@ -181,14 +190,25 @@ const convertV8ToIstanbul = async (v8list, options) => {
181
190
  return p;
182
191
  };
183
192
 
193
+ let failed = false;
184
194
  await v8toIstanbul.load().catch((e) => {
185
- EC.logRed(`[MCR] ${item.filename} v8toIstanbul.load:`, e.message);
195
+ EC.logRed(`[MCR] ${item.sourcePath} v8toIstanbul.load:`, e.message);
196
+ failed = true;
186
197
  });
187
198
 
199
+ if (failed) {
200
+ continue;
201
+ }
202
+
188
203
  try {
189
204
  v8toIstanbul.applyCoverage(item.functions);
190
205
  } catch (e) {
191
- EC.logRed(`[MCR] ${item.filename} v8toIstanbul.applyCoverage:`, e.message);
206
+ EC.logRed(`[MCR] ${item.sourcePath} v8toIstanbul.applyCoverage:`, e.message);
207
+ failed = true;
208
+ }
209
+
210
+ if (failed) {
211
+ continue;
192
212
  }
193
213
 
194
214
  const istanbulData = v8toIstanbul.toIstanbul();
@@ -99,7 +99,7 @@ const findOriginalEndPosition = (consumer, eLoc, generatedMapping, range) => {
99
99
 
100
100
  // =========================================================================================================
101
101
 
102
- const getOriginalMappings = (generatedMapping, consumer, options) => {
102
+ const getOriginalMappings = (consumer, options) => {
103
103
 
104
104
  // source filter
105
105
  let sourceList = consumer.sources;
@@ -152,7 +152,7 @@ const unpackJsSourceMap = async (item, v8list, options) => {
152
152
 
153
153
  const generatedMapping = new PositionMapping(item.source);
154
154
  const consumer = await new SourceMapConsumer(sourceMap);
155
- const originalMappings = getOriginalMappings(generatedMapping, consumer, options);
155
+ const originalMappings = getOriginalMappings(consumer, options);
156
156
 
157
157
  // generated ranges to original ranges
158
158
  item.ranges.forEach((range) => {
@@ -388,10 +388,6 @@ const saveSourceFile = async (filePath, data) => {
388
388
 
389
389
  const collectSourceMaps = async (v8list, options, inlineSourceMap) => {
390
390
 
391
- if (!options.unpackSourceMap) {
392
- return;
393
- }
394
-
395
391
  if (inlineSourceMap) {
396
392
  await collectInlineSourceMaps(v8list);
397
393
  return;
@@ -419,7 +415,9 @@ const filterSourceMapList = (v8list, options) => {
419
415
  return;
420
416
  }
421
417
 
422
- if (options.excludeDistFile) {
418
+ // do not remove in debug mode
419
+ if (!options.debug) {
420
+ // remove dist file if found sourceMap
423
421
  indexes.reverse();
424
422
  indexes.forEach((i) => {
425
423
  v8list.splice(i, 1);
@@ -432,11 +430,6 @@ const filterSourceMapList = (v8list, options) => {
432
430
  // requires ranges before unpack
433
431
  const unpackSourceMaps = async (v8list, options) => {
434
432
 
435
- // collect source maps
436
- if (!options.unpackSourceMap) {
437
- return;
438
- }
439
-
440
433
  const sourceMapList = filterSourceMapList(v8list, options);
441
434
  if (!sourceMapList) {
442
435
  // nothing to unpack
@@ -17,7 +17,7 @@ const getCssSummary = (item) => {
17
17
  const uncovered = total - covered;
18
18
 
19
19
  return {
20
- name: item.filename,
20
+ name: item.sourcePath,
21
21
  type: item.type,
22
22
  url: item.url,
23
23
  total,
@@ -59,7 +59,7 @@ const getJsSummary = (item) => {
59
59
  const covered = total - uncovered;
60
60
 
61
61
  return {
62
- name: item.filename,
62
+ name: item.sourcePath,
63
63
  type: item.type,
64
64
  url: item.url,
65
65
  total,
@@ -3,8 +3,8 @@ const EC = require('eight-colors');
3
3
  const Util = require('../../../utils/util.js');
4
4
  const { getV8Summary } = require('./v8-summary.js');
5
5
  const { dedupeRanges } = require('./dedupe.js');
6
- const { getSourcePath, convertFunctionsToRanges } = require('../coverage-utils.js');
7
- const { collectSourceMaps, unpackSourceMaps } = require('./source-map.js');
6
+ const { getSourcePath } = require('../coverage-utils.js');
7
+ const { collectSourceMaps } = require('./source-map.js');
8
8
  const { mergeScriptCovs } = require('../../../runtime/monocart-coverage.js');
9
9
 
10
10
 
@@ -70,22 +70,6 @@ const initV8ListAndSourcemap = async (v8list, options, inlineSourceMap) => {
70
70
 
71
71
  // ========================================================================================================
72
72
 
73
- const unpackV8List = async (v8list, options) => {
74
- v8list.forEach((item, i) => {
75
- if (item.type === 'js') {
76
- item.ranges = convertFunctionsToRanges(item.functions);
77
- delete item.functions;
78
- }
79
- });
80
-
81
- // requires ranges before unpack
82
- await unpackSourceMaps(v8list, options);
83
-
84
- // console.log(v8list.length);
85
- };
86
-
87
- // ========================================================================================================
88
-
89
73
  // force to async
90
74
  const mergeCssRanges = (itemList) => {
91
75
  return new Promise((resolve) => {
@@ -262,7 +246,6 @@ const saveV8Report = async (v8list, options) => {
262
246
 
263
247
  module.exports = {
264
248
  initV8ListAndSourcemap,
265
- unpackV8List,
266
249
  mergeV8Coverage,
267
250
  saveV8Report
268
251
  };
@@ -0,0 +1,153 @@
1
+ const EC = require('eight-colors');
2
+ const { WebSocket } = require('../../runtime/monocart-vendor.js');
3
+ const Util = require('../../utils/util.js');
4
+
5
+ const getServerUrl = (options = {}) => {
6
+ return `ws://${options.host}:${options.port}`;
7
+ };
8
+
9
+ class Client {
10
+
11
+ constructor(clientOptions) {
12
+ this.options = clientOptions;
13
+ this.requests = new Map();
14
+ this.resolves = [];
15
+
16
+ const serverUrl = getServerUrl(clientOptions);
17
+
18
+ // https://github.com/websockets/ws/blob/master/doc/ws.md
19
+ const ws = new WebSocket(serverUrl);
20
+
21
+ ws.on('error', (err) => {
22
+
23
+ // socket hang up: the port is exists but not websocket server
24
+ // connect ECONNREFUSED: websocket server unavailable
25
+
26
+ if (Util.isList(this.resolves)) {
27
+ this.resolves.forEach((item) => {
28
+ item.reject(err);
29
+ });
30
+ this.resolves = null;
31
+ } else {
32
+ EC.logRed(`[SWS] websocket error: ${err.message}`);
33
+ }
34
+
35
+ });
36
+
37
+ ws.on('message', (data) => {
38
+ this.onMessage(data);
39
+ });
40
+
41
+ ws.on('open', () => {
42
+ this.ws = ws;
43
+ if (Util.isList(this.resolves)) {
44
+ this.resolves.forEach((item) => {
45
+ item.resolve(ws);
46
+ });
47
+ this.resolves = null;
48
+ }
49
+ });
50
+ }
51
+
52
+ connect() {
53
+ return new Promise((resolve, reject) => {
54
+
55
+ if (this.ws) {
56
+ resolve(this.ws);
57
+ return;
58
+ }
59
+
60
+ if (this.resolves) {
61
+ this.resolves.push({
62
+ resolve,
63
+ reject
64
+ });
65
+ } else {
66
+ reject(new Error('[SWS] an error occurs when connecting websocket server'));
67
+ }
68
+ });
69
+ }
70
+
71
+ onMessage(buf) {
72
+ const message = JSON.parse(buf.toString());
73
+ if (!message) {
74
+ return;
75
+ }
76
+ const { id, data } = message;
77
+ if (!id) {
78
+ return;
79
+ }
80
+
81
+ const req = this.requests.get(id);
82
+ if (!req) {
83
+ return;
84
+ }
85
+
86
+ this.requests.delete(id);
87
+
88
+ clearTimeout(req.timeout_id);
89
+ req.resolve(data);
90
+
91
+ }
92
+
93
+ async execute(data) {
94
+
95
+ let err;
96
+ const ws = await this.connect().catch((e) => {
97
+ err = e;
98
+ });
99
+
100
+ return new Promise((resolve, reject) => {
101
+
102
+ if (!ws) {
103
+ reject(err);
104
+ return;
105
+ }
106
+
107
+ const id = Util.uid();
108
+ const timeout = this.options.timeout;
109
+ const timeout_id = setTimeout(() => {
110
+ this.requests.delete(id);
111
+ reject(new Error(`[SWS] Timed out receiving message from websocket server: ${timeout}ms`));
112
+ }, timeout);
113
+
114
+ this.requests.set(id, {
115
+ resolve,
116
+ timeout_id
117
+ });
118
+
119
+ const message = JSON.stringify({
120
+ id,
121
+ data
122
+ });
123
+ ws.send(message);
124
+ });
125
+ }
126
+
127
+ state() {
128
+ return {
129
+ get: (... args) => {
130
+ return this.execute(['get', ... args]);
131
+ },
132
+
133
+ set: (... args) => {
134
+ return this.execute(['set', ... args]);
135
+ },
136
+
137
+ remove: (... args) => {
138
+ return this.execute(['remove', ... args]);
139
+ },
140
+
141
+ send: (... args) => {
142
+ return this.execute(['send', ... args]);
143
+ }
144
+ };
145
+ }
146
+
147
+ }
148
+
149
+
150
+ module.exports = {
151
+ getServerUrl,
152
+ Client
153
+ };
@@ -0,0 +1,178 @@
1
+ const EC = require('eight-colors');
2
+ const { WebSocketServer } = require('../../runtime/monocart-vendor.js');
3
+ const Util = require('../../utils/util.js');
4
+ const { getServerUrl, Client } = require('./client.js');
5
+
6
+ // https://github.com/websockets/ws/blob/master/doc/ws.md
7
+ const defaultServerOptions = {
8
+ host: 'localhost',
9
+ port: 8130
10
+ };
11
+
12
+ const defaultClientOptions = {
13
+ ... defaultServerOptions,
14
+ timeout: 3000
15
+ };
16
+
17
+ const defaultStateOptions = {
18
+
19
+ server: defaultServerOptions,
20
+
21
+ // onReceive: function(... args) {
22
+ // console.log('receive on server', args);
23
+ // return ['custom response', ... args];
24
+ // },
25
+
26
+ // onClose: function(data, config) {
27
+ // Object.assign(config.metadata, data);
28
+ // },
29
+
30
+ // key-value state data
31
+ data: {}
32
+ };
33
+
34
+ // ===============================================================================
35
+
36
+ const clientMap = new Map();
37
+ const useState = (options = {}) => {
38
+ const clientOptions = {
39
+ ... defaultClientOptions,
40
+ ... options
41
+ };
42
+
43
+ const clientKey = Object.keys(defaultClientOptions).map((k) => clientOptions[k]).join('-');
44
+ // console.log('client key', clientKey);
45
+
46
+ let client = clientMap.get(clientKey);
47
+ if (!client) {
48
+ client = new Client(clientOptions);
49
+ clientMap.set(clientKey, client);
50
+ }
51
+
52
+ return client.state();
53
+ };
54
+
55
+ // ===============================================================================
56
+
57
+ const getActions = (stateData) => {
58
+ return {
59
+ get: (... args) => {
60
+ if (args.length) {
61
+ const values = args.map((k) => stateData[k]);
62
+ if (args.length === 1) {
63
+ return values[0];
64
+ }
65
+ return values;
66
+ }
67
+ return stateData;
68
+ },
69
+ set: (... args) => {
70
+ if (args.length) {
71
+ const first = args[0];
72
+ if (args.length === 1 && typeof first === 'object') {
73
+ Object.keys(first).forEach((key) => {
74
+ stateData[key] = first[key];
75
+ });
76
+ return;
77
+ }
78
+ stateData[first] = args[1];
79
+ }
80
+ },
81
+ remove: (... args) => {
82
+ if (args.length) {
83
+ args.forEach((k) => {
84
+ if (Util.hasOwn(stateData, k)) {
85
+ delete stateData[k];
86
+ }
87
+ });
88
+ }
89
+ }
90
+ };
91
+ };
92
+
93
+ const onMessage = async (ws, buf, options) => {
94
+ const message = JSON.parse(buf.toString());
95
+ if (!message) {
96
+ return;
97
+ }
98
+ const { id, data } = message;
99
+ if (!id || !Array.isArray(data)) {
100
+ return;
101
+ }
102
+
103
+ // first argument is action name always
104
+ const action = data.shift();
105
+
106
+ let resData;
107
+ if (action === 'send') {
108
+ // send handler
109
+ if (typeof options.onReceive === 'function') {
110
+ resData = await options.onReceive.apply(options, data);
111
+ }
112
+ } else {
113
+ // get/set/remove handler
114
+ const actions = getActions(options.data);
115
+ const handler = actions[action];
116
+ if (handler) {
117
+ resData = handler.apply(options, data);
118
+ }
119
+ }
120
+
121
+ const response = JSON.stringify({
122
+ id,
123
+ data: resData
124
+ });
125
+
126
+ // always response, like send action
127
+ // otherwise the request will be timeout
128
+ ws.send(response);
129
+
130
+ };
131
+
132
+ const createStateServer = (stateOptions) => {
133
+
134
+ const options = Util.mergeOption(defaultStateOptions, stateOptions);
135
+
136
+ if (!options.data || typeof options.data !== 'object') {
137
+ options.data = {};
138
+ }
139
+
140
+ const serverOptions = options.server;
141
+
142
+ const wss = new WebSocketServer(serverOptions);
143
+
144
+ wss.on('error', (e) => {
145
+ EC.logRed(`[SWS] websocket server error: ${e.message}`);
146
+ });
147
+ wss.on('wsClientError', (e) => {
148
+ EC.logRed(`[SWS] websocket client error: ${e.message}`);
149
+ });
150
+
151
+ wss.on('connection', (ws) => {
152
+
153
+ // data {Buffer|ArrayBuffer|Buffer[]}
154
+ ws.on('message', (data) => {
155
+ // console.log(data, isBinary);
156
+ onMessage(ws, data, options);
157
+ });
158
+ });
159
+
160
+ wss.on('listening', () => {
161
+ const serverUrl = getServerUrl(serverOptions);
162
+ console.log(`[SWS] state websocket server listening on ${EC.cyan(serverUrl)}`);
163
+ });
164
+
165
+ return {
166
+ close: async (config) => {
167
+ wss.close();
168
+ if (typeof options.onClose === 'function') {
169
+ await options.onClose.call(options, options.data, config);
170
+ }
171
+ }
172
+ };
173
+ };
174
+
175
+ module.exports = {
176
+ createStateServer,
177
+ useState
178
+ };