creevey 0.9.0-beta.1 → 0.9.0-beta.2
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.
- package/lib/cjs/cli.js +5 -0
- package/lib/cjs/client/addon/Manager.js +412 -0
- package/lib/cjs/client/addon/components/Addon.js +76 -0
- package/lib/cjs/client/addon/components/Icons.js +42 -0
- package/lib/cjs/client/addon/components/Panel.js +68 -0
- package/lib/cjs/client/addon/components/TestSelect.js +63 -0
- package/lib/cjs/client/addon/components/Tools.js +114 -0
- package/lib/cjs/client/addon/decorator.js +11 -0
- package/lib/cjs/client/addon/preset.js +81 -0
- package/lib/cjs/client/addon/readyForCapture.js +12 -0
- package/lib/cjs/client/addon/register.js +96 -0
- package/lib/cjs/client/addon/utils.js +38 -0
- package/lib/cjs/client/addon/withCreevey.js +531 -0
- package/lib/cjs/client/shared/components/ImagesView/BlendView.js +85 -0
- package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +88 -0
- package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +176 -0
- package/lib/cjs/client/shared/components/ImagesView/SlideView.js +179 -0
- package/lib/cjs/client/shared/components/ImagesView/SwapView.js +110 -0
- package/lib/cjs/client/shared/components/ImagesView/index.js +45 -0
- package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +46 -0
- package/lib/cjs/client/shared/components/PageFooter/Paging.js +98 -0
- package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +78 -0
- package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +144 -0
- package/lib/cjs/client/shared/components/ResultsPage.js +173 -0
- package/lib/cjs/client/shared/creeveyClientApi.js +103 -0
- package/lib/cjs/client/shared/helpers.js +482 -0
- package/lib/cjs/client/shared/viewMode.js +17 -0
- package/lib/cjs/client/web/index.html +19 -0
- package/lib/cjs/creevey.js +71 -0
- package/lib/cjs/index.js +62 -0
- package/lib/cjs/server/config.js +96 -0
- package/lib/cjs/server/docker.js +150 -0
- package/lib/cjs/server/extract.js +50 -0
- package/lib/cjs/server/index.js +83 -0
- package/lib/cjs/server/loaders/babel/creevey-plugin.js +88 -0
- package/lib/cjs/server/loaders/babel/helpers.js +479 -0
- package/lib/cjs/server/loaders/babel/register.js +126 -0
- package/lib/cjs/server/loaders/hooks/mdx.js +30 -0
- package/lib/cjs/server/loaders/hooks/svelte.js +65 -0
- package/lib/cjs/server/loaders/webpack/compile.js +286 -0
- package/lib/cjs/server/loaders/webpack/creevey-loader.js +174 -0
- package/lib/cjs/server/loaders/webpack/dummy-hmr.js +44 -0
- package/lib/cjs/server/loaders/webpack/mdx-loader.js +72 -0
- package/lib/cjs/server/loaders/webpack/start.js +41 -0
- package/lib/cjs/server/logger.js +47 -0
- package/lib/cjs/server/master/api.js +71 -0
- package/lib/cjs/server/master/index.js +146 -0
- package/lib/cjs/server/master/master.js +57 -0
- package/lib/cjs/server/master/pool.js +206 -0
- package/lib/cjs/server/master/runner.js +294 -0
- package/lib/cjs/server/master/server.js +129 -0
- package/lib/cjs/server/messages.js +266 -0
- package/lib/cjs/server/selenium/browser.js +680 -0
- package/lib/cjs/server/selenium/index.js +31 -0
- package/lib/cjs/server/selenium/selenoid.js +174 -0
- package/lib/cjs/server/stories.js +170 -0
- package/lib/cjs/server/storybook/entry.js +68 -0
- package/lib/cjs/server/storybook/helpers.js +165 -0
- package/lib/cjs/server/storybook/providers/browser.js +78 -0
- package/lib/cjs/server/storybook/providers/hybrid.js +84 -0
- package/lib/cjs/server/storybook/providers/nodejs.js +239 -0
- package/lib/cjs/server/testsFiles/parser.js +72 -0
- package/lib/cjs/server/testsFiles/register.js +48 -0
- package/lib/cjs/server/update.js +83 -0
- package/lib/cjs/server/utils.js +185 -0
- package/lib/cjs/server/worker/chai-image.js +142 -0
- package/lib/cjs/server/worker/helpers.js +69 -0
- package/lib/cjs/server/worker/index.js +15 -0
- package/lib/cjs/server/worker/reporter.js +120 -0
- package/lib/cjs/server/worker/worker.js +278 -0
- package/lib/cjs/shared.js +124 -0
- package/lib/cjs/types.js +74 -0
- package/lib/esm/cli.js +4 -0
- package/lib/esm/client/addon/Manager.js +396 -0
- package/lib/esm/client/addon/components/Addon.js +58 -0
- package/lib/esm/client/addon/components/Icons.js +27 -0
- package/lib/esm/client/addon/components/Panel.js +49 -0
- package/lib/esm/client/addon/components/TestSelect.js +49 -0
- package/lib/esm/client/addon/components/Tools.js +91 -0
- package/lib/esm/client/addon/decorator.js +2 -0
- package/lib/esm/client/addon/preset.js +56 -0
- package/lib/esm/client/addon/readyForCapture.js +5 -0
- package/lib/esm/client/addon/register.js +75 -0
- package/lib/esm/client/addon/utils.js +31 -0
- package/lib/esm/client/addon/withCreevey.js +509 -0
- package/lib/esm/client/shared/components/ImagesView/BlendView.js +63 -0
- package/lib/esm/client/shared/components/ImagesView/ImagesView.js +65 -0
- package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +151 -0
- package/lib/esm/client/shared/components/ImagesView/SlideView.js +154 -0
- package/lib/esm/client/shared/components/ImagesView/SwapView.js +88 -0
- package/lib/esm/client/shared/components/ImagesView/index.js +5 -0
- package/lib/esm/client/shared/components/PageFooter/PageFooter.js +32 -0
- package/lib/esm/client/shared/components/PageFooter/Paging.js +84 -0
- package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +64 -0
- package/lib/esm/client/shared/components/PageHeader/PageHeader.js +120 -0
- package/lib/esm/client/shared/components/ResultsPage.js +143 -0
- package/lib/esm/client/shared/creeveyClientApi.js +94 -0
- package/lib/esm/client/shared/helpers.js +424 -0
- package/lib/esm/client/shared/viewMode.js +6 -0
- package/lib/esm/creevey.js +56 -0
- package/lib/esm/index.js +7 -0
- package/lib/esm/server/config.js +73 -0
- package/lib/esm/server/docker.js +123 -0
- package/lib/esm/server/extract.js +34 -0
- package/lib/esm/server/index.js +64 -0
- package/lib/esm/server/loaders/babel/creevey-plugin.js +74 -0
- package/lib/esm/server/loaders/babel/helpers.js +462 -0
- package/lib/esm/server/loaders/babel/register.js +105 -0
- package/lib/esm/server/loaders/hooks/mdx.js +15 -0
- package/lib/esm/server/loaders/hooks/svelte.js +49 -0
- package/lib/esm/server/loaders/webpack/compile.js +263 -0
- package/lib/esm/server/loaders/webpack/creevey-loader.js +153 -0
- package/lib/esm/server/loaders/webpack/dummy-hmr.js +36 -0
- package/lib/esm/server/loaders/webpack/mdx-loader.js +58 -0
- package/lib/esm/server/loaders/webpack/start.js +27 -0
- package/lib/esm/server/logger.js +20 -0
- package/lib/esm/server/master/api.js +60 -0
- package/lib/esm/server/master/index.js +125 -0
- package/lib/esm/server/master/master.js +38 -0
- package/lib/esm/server/master/pool.js +187 -0
- package/lib/esm/server/master/runner.js +272 -0
- package/lib/esm/server/master/server.js +105 -0
- package/lib/esm/server/messages.js +234 -0
- package/lib/esm/server/selenium/browser.js +647 -0
- package/lib/esm/server/selenium/index.js +2 -0
- package/lib/esm/server/selenium/selenoid.js +151 -0
- package/lib/esm/server/stories.js +151 -0
- package/lib/esm/server/storybook/entry.js +44 -0
- package/lib/esm/server/storybook/helpers.js +106 -0
- package/lib/esm/server/storybook/providers/browser.js +61 -0
- package/lib/esm/server/storybook/providers/hybrid.js +64 -0
- package/lib/esm/server/storybook/providers/nodejs.js +217 -0
- package/lib/esm/server/testsFiles/parser.js +50 -0
- package/lib/esm/server/testsFiles/register.js +35 -0
- package/lib/esm/server/update.js +65 -0
- package/lib/esm/server/utils.js +146 -0
- package/lib/esm/server/worker/chai-image.js +130 -0
- package/lib/esm/server/worker/helpers.js +60 -0
- package/lib/esm/server/worker/index.js +1 -0
- package/lib/esm/server/worker/reporter.js +98 -0
- package/lib/esm/server/worker/worker.js +248 -0
- package/lib/esm/shared.js +93 -0
- package/lib/esm/types.js +43 -0
- package/lib/types/index.d.ts +2 -4
- package/package.json +1 -1
@@ -0,0 +1,272 @@
|
|
1
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
2
|
+
|
3
|
+
import path from 'path';
|
4
|
+
import { copyFile, mkdir } from 'fs';
|
5
|
+
import { promisify } from 'util';
|
6
|
+
import { EventEmitter } from 'events';
|
7
|
+
import { isDefined } from '../../types';
|
8
|
+
import Pool from './pool';
|
9
|
+
const copyFileAsync = promisify(copyFile);
|
10
|
+
const mkdirAsync = promisify(mkdir);
|
11
|
+
export default class Runner extends EventEmitter {
|
12
|
+
get isRunning() {
|
13
|
+
return Object.values(this.pools).some(pool => pool.isRunning);
|
14
|
+
}
|
15
|
+
|
16
|
+
constructor(config) {
|
17
|
+
super();
|
18
|
+
|
19
|
+
_defineProperty(this, "failFast", void 0);
|
20
|
+
|
21
|
+
_defineProperty(this, "screenDir", void 0);
|
22
|
+
|
23
|
+
_defineProperty(this, "reportDir", void 0);
|
24
|
+
|
25
|
+
_defineProperty(this, "browsers", void 0);
|
26
|
+
|
27
|
+
_defineProperty(this, "pools", {});
|
28
|
+
|
29
|
+
_defineProperty(this, "tests", {});
|
30
|
+
|
31
|
+
_defineProperty(this, "handlePoolMessage", message => {
|
32
|
+
const {
|
33
|
+
id,
|
34
|
+
status,
|
35
|
+
result
|
36
|
+
} = message;
|
37
|
+
const test = this.tests[id];
|
38
|
+
if (!test) return;
|
39
|
+
const {
|
40
|
+
browser,
|
41
|
+
testName,
|
42
|
+
storyPath,
|
43
|
+
storyId
|
44
|
+
} = test; // TODO Handle 'retrying' status
|
45
|
+
|
46
|
+
test.status = status == 'retrying' ? 'failed' : status;
|
47
|
+
|
48
|
+
if (!result) {
|
49
|
+
this.sendUpdate({
|
50
|
+
tests: {
|
51
|
+
[id]: {
|
52
|
+
id,
|
53
|
+
browser,
|
54
|
+
testName,
|
55
|
+
storyPath,
|
56
|
+
status: test.status,
|
57
|
+
storyId
|
58
|
+
}
|
59
|
+
}
|
60
|
+
});
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
|
64
|
+
if (!test.results) {
|
65
|
+
test.results = [];
|
66
|
+
}
|
67
|
+
|
68
|
+
test.results.push(result);
|
69
|
+
this.sendUpdate({
|
70
|
+
tests: {
|
71
|
+
[id]: {
|
72
|
+
id,
|
73
|
+
browser,
|
74
|
+
testName,
|
75
|
+
storyPath,
|
76
|
+
status: test.status,
|
77
|
+
results: [result],
|
78
|
+
storyId
|
79
|
+
}
|
80
|
+
}
|
81
|
+
});
|
82
|
+
if (this.failFast && status == 'failed') this.stop();
|
83
|
+
});
|
84
|
+
|
85
|
+
_defineProperty(this, "handlePoolStop", () => {
|
86
|
+
if (!this.isRunning) {
|
87
|
+
this.sendUpdate({
|
88
|
+
isRunning: false
|
89
|
+
});
|
90
|
+
this.emit('stop');
|
91
|
+
}
|
92
|
+
});
|
93
|
+
|
94
|
+
this.failFast = config.failFast;
|
95
|
+
this.screenDir = config.screenDir;
|
96
|
+
this.reportDir = config.reportDir;
|
97
|
+
this.browsers = Object.keys(config.browsers);
|
98
|
+
this.browsers.map(browser => this.pools[browser] = new Pool(config, browser)).map(pool => pool.on('test', this.handlePoolMessage));
|
99
|
+
}
|
100
|
+
|
101
|
+
async init() {
|
102
|
+
await Promise.all(Object.values(this.pools).map(pool => pool.init()));
|
103
|
+
}
|
104
|
+
|
105
|
+
updateTests(testsDiff) {
|
106
|
+
const tests = {};
|
107
|
+
const removedTests = [];
|
108
|
+
Object.entries(testsDiff).forEach(([id, newTest]) => {
|
109
|
+
const oldTest = this.tests[id];
|
110
|
+
|
111
|
+
if (newTest) {
|
112
|
+
if (oldTest) {
|
113
|
+
this.tests[id] = { ...newTest,
|
114
|
+
retries: oldTest.retries,
|
115
|
+
results: oldTest.results,
|
116
|
+
approved: oldTest.approved
|
117
|
+
};
|
118
|
+
} else this.tests[id] = newTest; // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
119
|
+
|
120
|
+
|
121
|
+
const {
|
122
|
+
story,
|
123
|
+
fn,
|
124
|
+
...restTest
|
125
|
+
} = newTest;
|
126
|
+
tests[id] = { ...restTest,
|
127
|
+
status: 'unknown'
|
128
|
+
};
|
129
|
+
} else if (oldTest) {
|
130
|
+
const {
|
131
|
+
id,
|
132
|
+
browser,
|
133
|
+
testName,
|
134
|
+
storyPath,
|
135
|
+
storyId
|
136
|
+
} = oldTest;
|
137
|
+
removedTests.push({
|
138
|
+
id,
|
139
|
+
browser,
|
140
|
+
testName,
|
141
|
+
storyPath,
|
142
|
+
storyId
|
143
|
+
});
|
144
|
+
delete this.tests[id];
|
145
|
+
}
|
146
|
+
});
|
147
|
+
this.sendUpdate({
|
148
|
+
tests,
|
149
|
+
removedTests
|
150
|
+
});
|
151
|
+
}
|
152
|
+
|
153
|
+
start(ids) {
|
154
|
+
if (this.isRunning) return;
|
155
|
+
const testsToStart = ids.map(id => this.tests[id]).filter(isDefined).filter(test => !test.skip);
|
156
|
+
if (testsToStart.length == 0) return;
|
157
|
+
this.sendUpdate({
|
158
|
+
isRunning: true,
|
159
|
+
tests: testsToStart.reduce((update, {
|
160
|
+
id,
|
161
|
+
storyId,
|
162
|
+
browser,
|
163
|
+
testName,
|
164
|
+
storyPath
|
165
|
+
}) => ({ ...update,
|
166
|
+
[id]: {
|
167
|
+
id,
|
168
|
+
browser,
|
169
|
+
testName,
|
170
|
+
storyPath,
|
171
|
+
status: 'pending',
|
172
|
+
storyId
|
173
|
+
}
|
174
|
+
}), {})
|
175
|
+
});
|
176
|
+
const testsByBrowser = testsToStart.reduce((tests, test) => {
|
177
|
+
const {
|
178
|
+
id,
|
179
|
+
browser,
|
180
|
+
testName,
|
181
|
+
storyPath
|
182
|
+
} = test;
|
183
|
+
const restPath = [...storyPath, testName].filter(isDefined);
|
184
|
+
test.status = 'pending';
|
185
|
+
return { ...tests,
|
186
|
+
[browser]: [...(tests[browser] || []), {
|
187
|
+
id,
|
188
|
+
path: restPath
|
189
|
+
}]
|
190
|
+
};
|
191
|
+
}, {});
|
192
|
+
this.browsers.forEach(browser => {
|
193
|
+
const pool = this.pools[browser];
|
194
|
+
const tests = testsByBrowser[browser];
|
195
|
+
|
196
|
+
if (tests && tests.length > 0 && pool.start(tests)) {
|
197
|
+
pool.once('stop', this.handlePoolStop);
|
198
|
+
}
|
199
|
+
});
|
200
|
+
}
|
201
|
+
|
202
|
+
stop() {
|
203
|
+
if (!this.isRunning) return;
|
204
|
+
this.browsers.forEach(browser => this.pools[browser].stop());
|
205
|
+
}
|
206
|
+
|
207
|
+
get status() {
|
208
|
+
const tests = {};
|
209
|
+
Object.values(this.tests).filter(isDefined) // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
210
|
+
.forEach(({
|
211
|
+
story,
|
212
|
+
fn,
|
213
|
+
...test
|
214
|
+
}) => tests[test.id] = test);
|
215
|
+
return {
|
216
|
+
isRunning: this.isRunning,
|
217
|
+
tests,
|
218
|
+
browsers: this.browsers
|
219
|
+
};
|
220
|
+
}
|
221
|
+
|
222
|
+
async approve({
|
223
|
+
id,
|
224
|
+
retry,
|
225
|
+
image
|
226
|
+
}) {
|
227
|
+
const test = this.tests[id];
|
228
|
+
if (!test || !test.results) return;
|
229
|
+
const result = test.results[retry];
|
230
|
+
if (!result || !result.images) return;
|
231
|
+
const images = result.images[image];
|
232
|
+
if (!images) return;
|
233
|
+
|
234
|
+
if (!test.approved) {
|
235
|
+
test.approved = {};
|
236
|
+
}
|
237
|
+
|
238
|
+
const {
|
239
|
+
browser,
|
240
|
+
testName,
|
241
|
+
storyPath
|
242
|
+
} = test;
|
243
|
+
const restPath = [...storyPath, testName].filter(isDefined);
|
244
|
+
const testPath = path.join(...restPath, image == browser ? '' : browser);
|
245
|
+
const srcImagePath = path.join(this.reportDir, testPath, images.actual);
|
246
|
+
const dstImagePath = path.join(this.screenDir, testPath, `${image}.png`);
|
247
|
+
await mkdirAsync(path.join(this.screenDir, testPath), {
|
248
|
+
recursive: true
|
249
|
+
});
|
250
|
+
await copyFileAsync(srcImagePath, dstImagePath);
|
251
|
+
test.approved[image] = retry;
|
252
|
+
this.sendUpdate({
|
253
|
+
tests: {
|
254
|
+
[id]: {
|
255
|
+
id,
|
256
|
+
browser,
|
257
|
+
testName,
|
258
|
+
storyPath,
|
259
|
+
approved: {
|
260
|
+
[image]: retry
|
261
|
+
},
|
262
|
+
storyId: test.storyId
|
263
|
+
}
|
264
|
+
}
|
265
|
+
});
|
266
|
+
}
|
267
|
+
|
268
|
+
sendUpdate(data) {
|
269
|
+
this.emit('update', data);
|
270
|
+
}
|
271
|
+
|
272
|
+
}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
import path from 'path';
|
2
|
+
import http from 'http';
|
3
|
+
import cluster from 'cluster';
|
4
|
+
import Koa from 'koa';
|
5
|
+
import cors from '@koa/cors';
|
6
|
+
import serve from 'koa-static';
|
7
|
+
import mount from 'koa-mount';
|
8
|
+
import body from 'koa-bodyparser';
|
9
|
+
import WebSocket from 'ws';
|
10
|
+
import { emitStoriesMessage, sendStoriesMessage, subscribeOn, subscribeOnWorker } from '../messages';
|
11
|
+
import { isDefined, noop } from '../../types';
|
12
|
+
import { logger } from '../logger';
|
13
|
+
import { deserializeStory } from '../../shared';
|
14
|
+
export default function server(reportDir, port, ui) {
|
15
|
+
let resolveApi = noop;
|
16
|
+
let setStoriesCounter = 0;
|
17
|
+
const creeveyApi = new Promise(resolve => resolveApi = resolve);
|
18
|
+
const app = new Koa();
|
19
|
+
const server = http.createServer(app.callback());
|
20
|
+
const wss = new WebSocket.Server({
|
21
|
+
server
|
22
|
+
});
|
23
|
+
app.use(cors());
|
24
|
+
app.use(body());
|
25
|
+
app.use(async (ctx, next) => {
|
26
|
+
if (ctx.method == 'GET' && ctx.path == '/ping') {
|
27
|
+
ctx.body = 'pong';
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
|
31
|
+
await next();
|
32
|
+
});
|
33
|
+
|
34
|
+
if (ui) {
|
35
|
+
app.use(async (_, next) => {
|
36
|
+
await creeveyApi;
|
37
|
+
await next();
|
38
|
+
});
|
39
|
+
}
|
40
|
+
|
41
|
+
app.use(async (ctx, next) => {
|
42
|
+
if (ctx.method == 'POST' && ctx.path == '/stories') {
|
43
|
+
const {
|
44
|
+
setStoriesCounter: counter,
|
45
|
+
stories
|
46
|
+
} = ctx.request.body;
|
47
|
+
if (setStoriesCounter >= counter) return;
|
48
|
+
const deserializedStories = stories.map(([file, stories]) => [file, stories.map(deserializeStory)]);
|
49
|
+
setStoriesCounter = counter;
|
50
|
+
emitStoriesMessage({
|
51
|
+
type: 'update',
|
52
|
+
payload: deserializedStories
|
53
|
+
});
|
54
|
+
Object.values(cluster.workers).filter(isDefined).filter(worker => worker.isConnected()).forEach(worker => sendStoriesMessage(worker, {
|
55
|
+
type: 'update',
|
56
|
+
payload: deserializedStories
|
57
|
+
}));
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
|
61
|
+
await next();
|
62
|
+
});
|
63
|
+
app.use(async (ctx, next) => {
|
64
|
+
if (ctx.method == 'POST' && ctx.path == '/capture') {
|
65
|
+
const {
|
66
|
+
workerId,
|
67
|
+
options
|
68
|
+
} = ctx.request.body;
|
69
|
+
const worker = Object.values(cluster.workers).filter(isDefined).find(worker => worker.process.pid == workerId); // NOTE: Hypothetical case when someone send to us capture req and we don't have a worker with browser session for it
|
70
|
+
|
71
|
+
if (!worker) return;
|
72
|
+
await new Promise(resolve => {
|
73
|
+
const unsubscribe = subscribeOnWorker(worker, 'stories', message => {
|
74
|
+
if (message.type != 'capture') return;
|
75
|
+
unsubscribe();
|
76
|
+
resolve();
|
77
|
+
});
|
78
|
+
sendStoriesMessage(worker, {
|
79
|
+
type: 'capture',
|
80
|
+
payload: options
|
81
|
+
});
|
82
|
+
}); // TODO Pass screenshot result to show it in inspector
|
83
|
+
|
84
|
+
ctx.body = 'Ok';
|
85
|
+
return;
|
86
|
+
}
|
87
|
+
|
88
|
+
await next();
|
89
|
+
});
|
90
|
+
app.use(serve(path.join(__dirname, '../../client/web')));
|
91
|
+
app.use(mount('/report', serve(reportDir)));
|
92
|
+
wss.on('error', error => logger.error(error));
|
93
|
+
server.listen(port);
|
94
|
+
subscribeOn('shutdown', () => {
|
95
|
+
server.close();
|
96
|
+
wss.close();
|
97
|
+
});
|
98
|
+
void creeveyApi.then(api => {
|
99
|
+
api.subscribe(wss);
|
100
|
+
wss.on('connection', ws => {
|
101
|
+
ws.on('message', message => api.handleMessage(ws, message));
|
102
|
+
});
|
103
|
+
});
|
104
|
+
return resolveApi;
|
105
|
+
}
|
@@ -0,0 +1,234 @@
|
|
1
|
+
import cluster from 'cluster';
|
2
|
+
|
3
|
+
function emitMessage(message) {
|
4
|
+
var _process$send, _process$send2, _process;
|
5
|
+
|
6
|
+
if (cluster.isWorker && !process.connected) return false;
|
7
|
+
return (_process$send = (_process$send2 = (_process = process).send) === null || _process$send2 === void 0 ? void 0 : _process$send2.call(_process, message)) !== null && _process$send !== void 0 ? _process$send : // @ts-expect-error: wrong typings `process.emit` return boolean
|
8
|
+
process.emit('message', message);
|
9
|
+
}
|
10
|
+
|
11
|
+
export function emitWorkerMessage(message) {
|
12
|
+
return emitMessage({
|
13
|
+
scope: 'worker',
|
14
|
+
...message
|
15
|
+
});
|
16
|
+
}
|
17
|
+
export function emitStoriesMessage(message) {
|
18
|
+
return emitMessage({
|
19
|
+
scope: 'stories',
|
20
|
+
...message
|
21
|
+
});
|
22
|
+
}
|
23
|
+
export function emitTestMessage(message) {
|
24
|
+
return emitMessage({
|
25
|
+
scope: 'test',
|
26
|
+
...message
|
27
|
+
});
|
28
|
+
}
|
29
|
+
export function emitWebpackMessage(message) {
|
30
|
+
return emitMessage({
|
31
|
+
scope: 'webpack',
|
32
|
+
...message
|
33
|
+
});
|
34
|
+
}
|
35
|
+
export function emitDockerMessage(message) {
|
36
|
+
return emitMessage({
|
37
|
+
scope: 'docker',
|
38
|
+
...message
|
39
|
+
});
|
40
|
+
}
|
41
|
+
export function emitShutdownMessage() {
|
42
|
+
return emitMessage({
|
43
|
+
scope: 'shutdown'
|
44
|
+
});
|
45
|
+
}
|
46
|
+
|
47
|
+
function createHandlers() {
|
48
|
+
return Object.assign(Object.create(null), {
|
49
|
+
worker: new Set(),
|
50
|
+
stories: new Set(),
|
51
|
+
test: new Set(),
|
52
|
+
webpack: new Set(),
|
53
|
+
docker: new Set(),
|
54
|
+
shutdown: new Set()
|
55
|
+
});
|
56
|
+
}
|
57
|
+
|
58
|
+
const handlers = createHandlers();
|
59
|
+
|
60
|
+
const handler = message => {
|
61
|
+
switch (message.scope) {
|
62
|
+
case 'worker':
|
63
|
+
return handlers.worker.forEach(h => h(message));
|
64
|
+
|
65
|
+
case 'stories':
|
66
|
+
return handlers.stories.forEach(h => h(message));
|
67
|
+
|
68
|
+
case 'test':
|
69
|
+
return handlers.test.forEach(h => h(message));
|
70
|
+
|
71
|
+
case 'webpack':
|
72
|
+
return handlers.webpack.forEach(h => h(message));
|
73
|
+
|
74
|
+
case 'docker':
|
75
|
+
return handlers.docker.forEach(h => h(message));
|
76
|
+
|
77
|
+
case 'shutdown':
|
78
|
+
return handlers.shutdown.forEach(h => h(message));
|
79
|
+
}
|
80
|
+
};
|
81
|
+
|
82
|
+
process.on('message', handler);
|
83
|
+
export function sendStoriesMessage(target, message) {
|
84
|
+
var _target$send;
|
85
|
+
|
86
|
+
(_target$send = target.send) === null || _target$send === void 0 ? void 0 : _target$send.call(target, {
|
87
|
+
scope: 'stories',
|
88
|
+
...message
|
89
|
+
});
|
90
|
+
}
|
91
|
+
export function sendTestMessage(target, message) {
|
92
|
+
var _target$send2;
|
93
|
+
|
94
|
+
(_target$send2 = target.send) === null || _target$send2 === void 0 ? void 0 : _target$send2.call(target, {
|
95
|
+
scope: 'test',
|
96
|
+
...message
|
97
|
+
});
|
98
|
+
}
|
99
|
+
export function sendDockerMessage(target, message) {
|
100
|
+
var _target$send3;
|
101
|
+
|
102
|
+
(_target$send3 = target.send) === null || _target$send3 === void 0 ? void 0 : _target$send3.call(target, {
|
103
|
+
scope: 'docker',
|
104
|
+
...message
|
105
|
+
});
|
106
|
+
}
|
107
|
+
export function sendShutdownMessage(target) {
|
108
|
+
var _target$send4;
|
109
|
+
|
110
|
+
(_target$send4 = target.send) === null || _target$send4 === void 0 ? void 0 : _target$send4.call(target, {
|
111
|
+
scope: 'shutdown'
|
112
|
+
});
|
113
|
+
}
|
114
|
+
export function subscribeOn(scope, handler) {
|
115
|
+
switch (scope) {
|
116
|
+
case 'worker':
|
117
|
+
{
|
118
|
+
const workerHandler = handler;
|
119
|
+
handlers.worker.add(workerHandler);
|
120
|
+
return () => handlers.worker.delete(workerHandler);
|
121
|
+
}
|
122
|
+
|
123
|
+
case 'stories':
|
124
|
+
{
|
125
|
+
const storiesHandler = handler;
|
126
|
+
handlers.stories.add(storiesHandler);
|
127
|
+
return () => handlers.stories.delete(storiesHandler);
|
128
|
+
}
|
129
|
+
|
130
|
+
case 'test':
|
131
|
+
{
|
132
|
+
const testHandler = handler;
|
133
|
+
handlers.test.add(testHandler);
|
134
|
+
return () => handlers.test.delete(testHandler);
|
135
|
+
}
|
136
|
+
|
137
|
+
case 'webpack':
|
138
|
+
{
|
139
|
+
const webpackHandler = handler;
|
140
|
+
handlers.webpack.add(webpackHandler);
|
141
|
+
return () => handlers.webpack.delete(webpackHandler);
|
142
|
+
}
|
143
|
+
|
144
|
+
case 'docker':
|
145
|
+
{
|
146
|
+
const dockerHandler = handler;
|
147
|
+
handlers.docker.add(dockerHandler);
|
148
|
+
return () => handlers.docker.delete(dockerHandler);
|
149
|
+
}
|
150
|
+
|
151
|
+
case 'shutdown':
|
152
|
+
{
|
153
|
+
const shutdownHandler = handler;
|
154
|
+
handlers.shutdown.add(shutdownHandler);
|
155
|
+
return () => handlers.shutdown.delete(shutdownHandler);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
const workers = new Map();
|
160
|
+
export function subscribeOnWorker(worker, scope, handler) {
|
161
|
+
var _workers$get;
|
162
|
+
|
163
|
+
const workerHandlers = (_workers$get = workers.get(worker)) !== null && _workers$get !== void 0 ? _workers$get : createHandlers();
|
164
|
+
|
165
|
+
if (!workers.has(worker)) {
|
166
|
+
workers.set(worker, workerHandlers);
|
167
|
+
worker.once('exit', () => workers.delete(worker));
|
168
|
+
worker.on('message', message => {
|
169
|
+
switch (message.scope) {
|
170
|
+
case 'worker':
|
171
|
+
return workerHandlers.worker.forEach(h => h(message));
|
172
|
+
|
173
|
+
case 'stories':
|
174
|
+
return workerHandlers.stories.forEach(h => h(message));
|
175
|
+
|
176
|
+
case 'test':
|
177
|
+
return workerHandlers.test.forEach(h => h(message));
|
178
|
+
|
179
|
+
case 'webpack':
|
180
|
+
return workerHandlers.webpack.forEach(h => h(message));
|
181
|
+
|
182
|
+
case 'docker':
|
183
|
+
return workerHandlers.docker.forEach(h => h(message));
|
184
|
+
|
185
|
+
case 'shutdown':
|
186
|
+
return workerHandlers.shutdown.forEach(h => h(message));
|
187
|
+
}
|
188
|
+
});
|
189
|
+
}
|
190
|
+
|
191
|
+
switch (scope) {
|
192
|
+
case 'worker':
|
193
|
+
{
|
194
|
+
const workerHandler = handler;
|
195
|
+
workerHandlers.worker.add(workerHandler);
|
196
|
+
return () => workerHandlers.worker.delete(workerHandler);
|
197
|
+
}
|
198
|
+
|
199
|
+
case 'stories':
|
200
|
+
{
|
201
|
+
const storiesHandler = handler;
|
202
|
+
workerHandlers.stories.add(storiesHandler);
|
203
|
+
return () => workerHandlers.stories.delete(storiesHandler);
|
204
|
+
}
|
205
|
+
|
206
|
+
case 'test':
|
207
|
+
{
|
208
|
+
const testHandler = handler;
|
209
|
+
workerHandlers.test.add(testHandler);
|
210
|
+
return () => workerHandlers.test.delete(testHandler);
|
211
|
+
}
|
212
|
+
|
213
|
+
case 'webpack':
|
214
|
+
{
|
215
|
+
const webpackHandler = handler;
|
216
|
+
workerHandlers.webpack.add(webpackHandler);
|
217
|
+
return () => workerHandlers.webpack.delete(webpackHandler);
|
218
|
+
}
|
219
|
+
|
220
|
+
case 'docker':
|
221
|
+
{
|
222
|
+
const dockerHandler = handler;
|
223
|
+
workerHandlers.docker.add(dockerHandler);
|
224
|
+
return () => workerHandlers.docker.delete(dockerHandler);
|
225
|
+
}
|
226
|
+
|
227
|
+
case 'shutdown':
|
228
|
+
{
|
229
|
+
const shutdownHandler = handler;
|
230
|
+
workerHandlers.shutdown.add(shutdownHandler);
|
231
|
+
return () => workerHandlers.shutdown.delete(shutdownHandler);
|
232
|
+
}
|
233
|
+
}
|
234
|
+
}
|