@percy/core 1.0.0-beta.69 → 1.0.0-beta.72
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/dist/browser.js +38 -25
- package/dist/config.js +5 -4
- package/dist/index.js +8 -6
- package/dist/network.js +14 -7
- package/dist/page.js +16 -6
- package/dist/percy.js +224 -174
- package/dist/queue.js +67 -25
- package/dist/server.js +12 -5
- package/dist/session.js +9 -3
- package/dist/snapshot.js +48 -41
- package/dist/utils.js +90 -28
- package/package.json +14 -14
- package/test/helpers/server.js +5 -1
package/dist/percy.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default = void 0;
|
|
6
|
+
exports.default = exports.Percy = void 0;
|
|
7
7
|
|
|
8
8
|
var _client = _interopRequireDefault(require("@percy/client"));
|
|
9
9
|
|
|
@@ -21,13 +21,15 @@ var _server = _interopRequireDefault(require("./server"));
|
|
|
21
21
|
|
|
22
22
|
var _snapshot = require("./snapshot");
|
|
23
23
|
|
|
24
|
+
var _utils2 = require("./utils");
|
|
25
|
+
|
|
24
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
27
|
|
|
26
|
-
function
|
|
28
|
+
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
27
29
|
|
|
28
|
-
function
|
|
30
|
+
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
29
31
|
|
|
30
|
-
function
|
|
32
|
+
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; }
|
|
31
33
|
|
|
32
34
|
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
33
35
|
|
|
@@ -39,8 +41,6 @@ var _uploads = /*#__PURE__*/new WeakMap();
|
|
|
39
41
|
|
|
40
42
|
var _snapshots = /*#__PURE__*/new WeakMap();
|
|
41
43
|
|
|
42
|
-
var _total = /*#__PURE__*/new WeakMap();
|
|
43
|
-
|
|
44
44
|
// A Percy instance will create a new build when started, handle snapshot
|
|
45
45
|
// creation, asset discovery, and resource uploads, and will finalize the build
|
|
46
46
|
// when stopped. Snapshots are processed concurrently and the build is not
|
|
@@ -73,40 +73,198 @@ class Percy {
|
|
|
73
73
|
port = 5338,
|
|
74
74
|
// options such as `snapshot` and `discovery` that are valid Percy config
|
|
75
75
|
// options which will become accessible via the `.config` property
|
|
76
|
-
...
|
|
76
|
+
..._options
|
|
77
77
|
} = {}) {
|
|
78
78
|
_defineProperty(this, "log", (0, _logger.default)('core'));
|
|
79
79
|
|
|
80
80
|
_defineProperty(this, "readyState", null);
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
_classPrivateFieldInitSpec(this, _uploads, {
|
|
83
83
|
writable: true,
|
|
84
84
|
value: new _queue.default()
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
_classPrivateFieldInitSpec(this, _snapshots, {
|
|
88
88
|
writable: true,
|
|
89
89
|
value: new _queue.default()
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
});
|
|
92
|
+
_defineProperty(this, "idle", () => (0, _utils2.generatePromise)(async function* () {
|
|
93
|
+
yield* _classPrivateFieldGet(this, _snapshots).idle();
|
|
94
|
+
yield* _classPrivateFieldGet(this, _uploads).idle();
|
|
95
|
+
}.bind(this)));
|
|
96
|
+
|
|
97
|
+
_defineProperty(this, "start", options => (0, _utils2.generatePromise)(async function* () {
|
|
98
|
+
// already starting or started
|
|
99
|
+
if (this.readyState != null) return;
|
|
100
|
+
this.readyState = 0; // create a percy build as the first immediately queued task
|
|
101
|
+
|
|
102
|
+
let buildTask = _classPrivateFieldGet(this, _uploads).push('build/create', () => {
|
|
103
|
+
// pause other queued tasks until after the build is created
|
|
104
|
+
_classPrivateFieldGet(this, _uploads).stop();
|
|
105
|
+
|
|
106
|
+
return this.client.createBuild().then(({
|
|
107
|
+
data: {
|
|
108
|
+
id,
|
|
109
|
+
attributes
|
|
110
|
+
}
|
|
111
|
+
}) => {
|
|
112
|
+
this.build = {
|
|
113
|
+
id
|
|
114
|
+
};
|
|
115
|
+
this.build.number = attributes['build-number'];
|
|
116
|
+
this.build.url = attributes['web-url'];
|
|
117
|
+
|
|
118
|
+
_classPrivateFieldGet(this, _uploads).run();
|
|
119
|
+
});
|
|
120
|
+
}, 0); // handle deferred build errors
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
if (this.deferUploads) {
|
|
124
|
+
buildTask.catch(err => {
|
|
125
|
+
this.log.error('Failed to create build');
|
|
126
|
+
this.log.error(err);
|
|
127
|
+
this.close();
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
var _this$server;
|
|
133
|
+
|
|
134
|
+
// when not deferred, wait until the build is created first
|
|
135
|
+
if (!this.deferUploads) await buildTask; // maybe launch the discovery browser
|
|
136
|
+
|
|
137
|
+
if (!this.dryRun && (options === null || options === void 0 ? void 0 : options.browser) !== false) {
|
|
138
|
+
yield this.browser.launch();
|
|
139
|
+
} // start the server after everything else is ready
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
yield (_this$server = this.server) === null || _this$server === void 0 ? void 0 : _this$server.listen(this.port); // mark instance as started
|
|
143
|
+
|
|
144
|
+
this.log.info('Percy has started!');
|
|
145
|
+
this.readyState = 1;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
var _this$server2;
|
|
148
|
+
|
|
149
|
+
// on error, close any running server and browser
|
|
150
|
+
await ((_this$server2 = this.server) === null || _this$server2 === void 0 ? void 0 : _this$server2.close());
|
|
151
|
+
await this.browser.close(); // mark instance as closed
|
|
152
|
+
|
|
153
|
+
this.readyState = 3; // when uploads are deferred, cancel build creation
|
|
154
|
+
|
|
155
|
+
if (error.canceled && this.deferUploads) {
|
|
156
|
+
_classPrivateFieldGet(this, _uploads).cancel('build/create');
|
|
157
|
+
|
|
158
|
+
this.readyState = null;
|
|
159
|
+
} // throw an easier-to-understand error when the port is taken
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if (error.code === 'EADDRINUSE') {
|
|
163
|
+
throw new Error('Percy is already running or the port is in use');
|
|
164
|
+
} else {
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}.bind(this)));
|
|
169
|
+
|
|
170
|
+
_defineProperty(this, "flush", close => (0, _utils2.generatePromise)(async function* () {
|
|
171
|
+
// close the snapshot queue and wait for it to empty
|
|
172
|
+
if (_classPrivateFieldGet(this, _snapshots).size) {
|
|
173
|
+
if (close) _classPrivateFieldGet(this, _snapshots).close();
|
|
174
|
+
yield* _classPrivateFieldGet(this, _snapshots).flush(s => {
|
|
175
|
+
// do not log a count when not closing or while dry-running
|
|
176
|
+
if (!close || this.dryRun) return;
|
|
177
|
+
this.log.progress(`Processing ${s} snapshot${s !== 1 ? 's' : ''}...`, !!s);
|
|
178
|
+
});
|
|
179
|
+
} // run, close, and wait for the upload queue to empty
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
if (!this.skipUploads && _classPrivateFieldGet(this, _uploads).size) {
|
|
183
|
+
if (close) _classPrivateFieldGet(this, _uploads).close();
|
|
184
|
+
yield* _classPrivateFieldGet(this, _uploads).flush(s => {
|
|
185
|
+
// do not log a count when not closing or while creating a build
|
|
186
|
+
if (!close || _classPrivateFieldGet(this, _uploads).has('build/create')) return;
|
|
187
|
+
this.log.progress(`Uploading ${s} snapshot${s !== 1 ? 's' : ''}...`, !!s);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}.bind(this)).canceled(() => {
|
|
191
|
+
// reopen closed queues when canceled
|
|
192
|
+
_classPrivateFieldGet(this, _snapshots).open();
|
|
193
|
+
|
|
194
|
+
_classPrivateFieldGet(this, _uploads).open();
|
|
195
|
+
}));
|
|
196
|
+
|
|
197
|
+
_defineProperty(this, "stop", force => (0, _utils2.generatePromise)(async function* () {
|
|
198
|
+
var _this$server3, _this$build;
|
|
199
|
+
|
|
200
|
+
// not started, but the browser was launched
|
|
201
|
+
if (!this.readyState && this.browser.isConnected()) {
|
|
202
|
+
await this.browser.close();
|
|
203
|
+
} // not started or already stopped
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
if (!this.readyState || this.readyState > 2) return; // close queues asap
|
|
207
|
+
|
|
208
|
+
if (force) this.close(); // already stopping
|
|
209
|
+
|
|
210
|
+
if (this.readyState === 2) return;
|
|
211
|
+
this.readyState = 2; // log when force stopping
|
|
212
|
+
|
|
213
|
+
if (force) this.log.info('Stopping percy...'); // process uploads and close queues
|
|
214
|
+
|
|
215
|
+
yield* this.flush(true); // if dry-running, log the total number of snapshots
|
|
216
|
+
|
|
217
|
+
if (this.dryRun && _classPrivateFieldGet(this, _uploads).size) {
|
|
218
|
+
let total = _classPrivateFieldGet(this, _uploads).size - 1; // subtract the build task
|
|
219
|
+
|
|
220
|
+
this.log.info(`Found ${total} snapshot${total !== 1 ? 's' : ''}`);
|
|
221
|
+
} // close any running server and browser
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
await ((_this$server3 = this.server) === null || _this$server3 === void 0 ? void 0 : _this$server3.close());
|
|
225
|
+
await this.browser.close(); // finalize and log build info
|
|
226
|
+
|
|
227
|
+
let meta = {
|
|
228
|
+
build: this.build
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
if ((_this$build = this.build) !== null && _this$build !== void 0 && _this$build.failed) {
|
|
232
|
+
// do not finalize failed builds
|
|
233
|
+
this.log.warn(`Build #${this.build.number} failed: ${this.build.url}`, meta);
|
|
234
|
+
} else if (this.build) {
|
|
235
|
+
// finalize the build
|
|
236
|
+
await this.client.finalizeBuild(this.build.id);
|
|
237
|
+
this.log.info(`Finalized build #${this.build.number}: ${this.build.url}`, meta);
|
|
238
|
+
} else {
|
|
239
|
+
// no build was ever created (likely failed while deferred)
|
|
240
|
+
this.log.warn('Build not created', meta);
|
|
241
|
+
} // mark instance as stopped
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
this.readyState = 3;
|
|
245
|
+
}.bind(this)).canceled(() => {
|
|
246
|
+
// reset ready state when canceled
|
|
247
|
+
this.readyState = 1;
|
|
248
|
+
}));
|
|
96
249
|
|
|
97
250
|
if (loglevel) this.loglevel(loglevel);
|
|
98
251
|
this.dryRun = !!dryRun;
|
|
99
252
|
this.skipUploads = this.dryRun || !!skipUploads;
|
|
100
253
|
this.deferUploads = this.skipUploads || !!deferUploads;
|
|
254
|
+
if (this.deferUploads) _classPrivateFieldGet(this, _uploads).stop();
|
|
101
255
|
this.config = _config.default.load({
|
|
102
|
-
overrides:
|
|
256
|
+
overrides: _options,
|
|
103
257
|
path: config
|
|
104
258
|
});
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
259
|
+
|
|
260
|
+
if (this.config.discovery.concurrency) {
|
|
261
|
+
let {
|
|
262
|
+
concurrency
|
|
263
|
+
} = this.config.discovery;
|
|
264
|
+
_classPrivateFieldGet(this, _uploads).concurrency = concurrency;
|
|
265
|
+
_classPrivateFieldGet(this, _snapshots).concurrency = concurrency;
|
|
266
|
+
}
|
|
267
|
+
|
|
110
268
|
this.client = new _client.default({
|
|
111
269
|
token,
|
|
112
270
|
clientInfo,
|
|
@@ -158,23 +316,21 @@ class Percy {
|
|
|
158
316
|
this.config = (0, _utils.merge)([this.config, config], (path, prev, next) => {
|
|
159
317
|
// replace arrays instead of merging
|
|
160
318
|
return Array.isArray(next) && [path, next];
|
|
161
|
-
});
|
|
319
|
+
}); // adjust concurrency if necessary
|
|
320
|
+
|
|
321
|
+
if (this.config.discovery.concurrency) {
|
|
322
|
+
let {
|
|
323
|
+
concurrency
|
|
324
|
+
} = this.config.discovery;
|
|
325
|
+
_classPrivateFieldGet(this, _uploads).concurrency = concurrency;
|
|
326
|
+
_classPrivateFieldGet(this, _snapshots).concurrency = concurrency;
|
|
327
|
+
}
|
|
328
|
+
|
|
162
329
|
return this.config;
|
|
163
330
|
} // Resolves once snapshot and upload queues are idle
|
|
164
331
|
|
|
165
332
|
|
|
166
|
-
|
|
167
|
-
await _classPrivateFieldGet(this, _snapshots).idle();
|
|
168
|
-
await _classPrivateFieldGet(this, _uploads).idle();
|
|
169
|
-
} // Waits for snapshot idle and flushes the upload queue
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
async dispatch() {
|
|
173
|
-
await _classPrivateFieldGet(this, _snapshots).idle();
|
|
174
|
-
if (!this.skipUploads) await _classPrivateFieldGet(this, _uploads).flush();
|
|
175
|
-
} // Immediately stops all queues, preventing any more tasks from running
|
|
176
|
-
|
|
177
|
-
|
|
333
|
+
// Immediately stops all queues, preventing any more tasks from running
|
|
178
334
|
close() {
|
|
179
335
|
_classPrivateFieldGet(this, _snapshots).close(true);
|
|
180
336
|
|
|
@@ -183,122 +339,7 @@ class Percy {
|
|
|
183
339
|
// at a later time when uploads are deferred, or run immediately when not deferred.
|
|
184
340
|
|
|
185
341
|
|
|
186
|
-
|
|
187
|
-
// already starting or started
|
|
188
|
-
if (this.readyState != null) return;
|
|
189
|
-
this.readyState = 0; // create a percy build as the first immediately queued task
|
|
190
|
-
|
|
191
|
-
let buildTask = _classPrivateFieldGet(this, _uploads).push('build/create', () => {
|
|
192
|
-
// pause other queued tasks until after the build is created
|
|
193
|
-
_classPrivateFieldGet(this, _uploads).stop();
|
|
194
|
-
|
|
195
|
-
return this.client.createBuild().then(({
|
|
196
|
-
data: {
|
|
197
|
-
id,
|
|
198
|
-
attributes
|
|
199
|
-
}
|
|
200
|
-
}) => {
|
|
201
|
-
this.build = {
|
|
202
|
-
id
|
|
203
|
-
};
|
|
204
|
-
this.build.number = attributes['build-number'];
|
|
205
|
-
this.build.url = attributes['web-url'];
|
|
206
|
-
|
|
207
|
-
_classPrivateFieldGet(this, _uploads).run();
|
|
208
|
-
});
|
|
209
|
-
}, 0); // handle deferred build errors
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (this.deferUploads) {
|
|
213
|
-
buildTask.catch(err => {
|
|
214
|
-
this.log.error('Failed to create build');
|
|
215
|
-
this.log.error(err);
|
|
216
|
-
this.close();
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
try {
|
|
221
|
-
var _this$server;
|
|
222
|
-
|
|
223
|
-
// when not deferred, wait until the build is created first
|
|
224
|
-
if (!this.deferUploads) await buildTask; // launch the discovery browser
|
|
225
|
-
|
|
226
|
-
if (!this.dryRun) await this.browser.launch(); // if there is a server, start listening
|
|
227
|
-
|
|
228
|
-
await ((_this$server = this.server) === null || _this$server === void 0 ? void 0 : _this$server.listen(this.port)); // mark this process as running
|
|
229
|
-
|
|
230
|
-
this.log.info('Percy has started!');
|
|
231
|
-
this.readyState = 1;
|
|
232
|
-
} catch (error) {
|
|
233
|
-
var _this$server2;
|
|
234
|
-
|
|
235
|
-
// on error, close any running server and browser
|
|
236
|
-
await ((_this$server2 = this.server) === null || _this$server2 === void 0 ? void 0 : _this$server2.close());
|
|
237
|
-
await this.browser.close();
|
|
238
|
-
this.readyState = 3; // throw an easier-to-understand error when the port is taken
|
|
239
|
-
|
|
240
|
-
if (error.code === 'EADDRINUSE') {
|
|
241
|
-
throw new Error('Percy is already running or the port is in use');
|
|
242
|
-
} else {
|
|
243
|
-
throw error;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
} // Stops the local API server and browser once snapshots have completed and finalizes the Percy
|
|
247
|
-
// build. Does nothing if not running. When `force` is true, any queued tasks are cleared.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
async stop(force) {
|
|
251
|
-
var _this$server3, _this$build;
|
|
252
|
-
|
|
253
|
-
// not started or already stopped
|
|
254
|
-
if (!this.readyState || this.readyState > 2) return; // close queues asap
|
|
255
|
-
|
|
256
|
-
if (force) this.close(); // already stopping
|
|
257
|
-
|
|
258
|
-
if (this.readyState === 2) return;
|
|
259
|
-
this.readyState = 2; // log when force stopping
|
|
260
|
-
|
|
261
|
-
let meta = {
|
|
262
|
-
build: this.build
|
|
263
|
-
};
|
|
264
|
-
if (force) this.log.info('Stopping percy...', meta); // close the snapshot queue and wait for it to empty
|
|
265
|
-
|
|
266
|
-
if (_classPrivateFieldGet(this, _snapshots).close().size) {
|
|
267
|
-
await _classPrivateFieldGet(this, _snapshots).empty(s => !this.dryRun && this.log.progress(`Processing ${s} snapshot${s !== 1 ? 's' : ''}...`, !!s));
|
|
268
|
-
} // run, close, and wait for the upload queue to empty
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (!this.skipUploads && _classPrivateFieldGet(this, _uploads).run().close().size) {
|
|
272
|
-
await _classPrivateFieldGet(this, _uploads).empty(s => {
|
|
273
|
-
this.log.progress(`Uploading ${s} snapshot${s !== 1 ? 's' : ''}...`, !!s);
|
|
274
|
-
});
|
|
275
|
-
} // if dry-running, print the total number of snapshots at the end
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (this.dryRun && _classPrivateFieldGet(this, _total)) {
|
|
279
|
-
this.log.info(`Found ${_classPrivateFieldGet(this, _total)} snapshot${_classPrivateFieldGet(this, _total) !== 1 ? 's' : ''}`);
|
|
280
|
-
} // close the any running server and browser
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
await ((_this$server3 = this.server) === null || _this$server3 === void 0 ? void 0 : _this$server3.close());
|
|
284
|
-
await this.browser.close();
|
|
285
|
-
|
|
286
|
-
if ((_this$build = this.build) !== null && _this$build !== void 0 && _this$build.failed) {
|
|
287
|
-
// do not finalize failed builds
|
|
288
|
-
this.log.warn(`Build #${this.build.number} failed: ${this.build.url}`, meta);
|
|
289
|
-
} else if (this.build) {
|
|
290
|
-
// finalize the build
|
|
291
|
-
await this.client.finalizeBuild(this.build.id);
|
|
292
|
-
this.log.info(`Finalized build #${this.build.number}: ${this.build.url}`, meta);
|
|
293
|
-
} else {
|
|
294
|
-
// no build was ever created (likely failed while deferred)
|
|
295
|
-
this.log.warn('Build not created', meta);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
this.readyState = 3;
|
|
299
|
-
} // Deprecated capture method
|
|
300
|
-
|
|
301
|
-
|
|
342
|
+
// Deprecated capture method
|
|
302
343
|
capture(options) {
|
|
303
344
|
this.log.deprecated('The #capture() method will be ' + 'removed in 1.0.0. Use #snapshot() instead.');
|
|
304
345
|
return this.snapshot(options);
|
|
@@ -319,39 +360,46 @@ class Percy {
|
|
|
319
360
|
} // get derived snapshot config options
|
|
320
361
|
|
|
321
362
|
|
|
322
|
-
let snapshot = (0, _snapshot.getSnapshotConfig)(this, options); // clear any existing
|
|
323
|
-
|
|
324
|
-
_classPrivateFieldGet(this, _uploads).clear(`upload/${snapshot.name}`); // resolves after asset discovery has finished and the upload has been queued
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
return _classPrivateFieldGet(this, _snapshots).push(`snapshot/${snapshot.name}`, async () => {
|
|
328
|
-
var _snapshot$additionalS, _snapshot$additionalS2;
|
|
363
|
+
let snapshot = (0, _snapshot.getSnapshotConfig)(this, options); // clear any existing snapshot uploads of the same name (for retries)
|
|
329
364
|
|
|
330
|
-
|
|
365
|
+
for (let {
|
|
366
|
+
name
|
|
367
|
+
} of [snapshot, ...(snapshot.additionalSnapshots || [])]) {
|
|
368
|
+
_classPrivateFieldGet(this, _uploads).cancel(`upload/${name}`);
|
|
369
|
+
} // resolves after asset discovery has finished and uploads have been queued
|
|
331
370
|
|
|
332
|
-
(0, _snapshot.debugSnapshotConfig)(snapshot, this.dryRun);
|
|
333
|
-
if (this.dryRun) return;
|
|
334
371
|
|
|
372
|
+
return _classPrivateFieldGet(this, _snapshots).push(`snapshot/${snapshot.name}`, async function* () {
|
|
335
373
|
try {
|
|
336
|
-
|
|
337
|
-
this.log.info(`Snapshot taken: ${
|
|
374
|
+
yield* (0, _snapshot.discoverSnapshotResources)(this, snapshot, (snap, resources) => {
|
|
375
|
+
if (!this.dryRun) this.log.info(`Snapshot taken: ${snap.name}`, snap.meta);
|
|
338
376
|
|
|
339
|
-
this._scheduleUpload(
|
|
377
|
+
this._scheduleUpload(snap.name, { ...snap,
|
|
378
|
+
resources
|
|
379
|
+
});
|
|
340
380
|
});
|
|
341
381
|
} catch (error) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
382
|
+
if (error.canceled) {
|
|
383
|
+
this.log.error('Received a duplicate snapshot name, ' + `the previous snapshot was canceled: ${snapshot.name}`);
|
|
384
|
+
} else {
|
|
385
|
+
this.log.error(`Encountered an error taking snapshot: ${snapshot.name}`, snapshot.meta);
|
|
386
|
+
this.log.error(error, snapshot.meta);
|
|
387
|
+
}
|
|
388
|
+
} // fixes an issue in Node 12 where implicit returns do not correctly resolve the async
|
|
389
|
+
// generator objects — https://crbug.com/v8/10238
|
|
347
390
|
|
|
348
391
|
|
|
349
|
-
|
|
350
|
-
|
|
392
|
+
return; // eslint-disable-line no-useless-return
|
|
393
|
+
}.bind(this));
|
|
394
|
+
} // Queues a snapshot upload with the provided options
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
_scheduleUpload(name, options) {
|
|
398
|
+
return _classPrivateFieldGet(this, _uploads).push(`upload/${name}`, async () => {
|
|
351
399
|
try {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
400
|
+
/* istanbul ignore if: useful for other internal packages */
|
|
401
|
+
if (typeof options === 'function') options = await options();
|
|
402
|
+
await this.client.sendSnapshot(this.build.id, options);
|
|
355
403
|
} catch (error) {
|
|
356
404
|
var _error$response, _failed$detail;
|
|
357
405
|
|
|
@@ -360,8 +408,8 @@ class Percy {
|
|
|
360
408
|
|
|
361
409
|
return ((_e$source = e.source) === null || _e$source === void 0 ? void 0 : _e$source.pointer) === '/data/attributes/build';
|
|
362
410
|
});
|
|
363
|
-
this.log.error(`Encountered an error uploading snapshot: ${
|
|
364
|
-
this.log.error((_failed$detail = failed === null || failed === void 0 ? void 0 : failed.detail) !== null && _failed$detail !== void 0 ? _failed$detail : error,
|
|
411
|
+
this.log.error(`Encountered an error uploading snapshot: ${name}`, options.meta);
|
|
412
|
+
this.log.error((_failed$detail = failed === null || failed === void 0 ? void 0 : failed.detail) !== null && _failed$detail !== void 0 ? _failed$detail : error, options.meta); // build failed at some point, stop accepting snapshots
|
|
365
413
|
|
|
366
414
|
if (failed) {
|
|
367
415
|
this.build.failed = true;
|
|
@@ -373,4 +421,6 @@ class Percy {
|
|
|
373
421
|
|
|
374
422
|
}
|
|
375
423
|
|
|
376
|
-
exports.
|
|
424
|
+
exports.Percy = Percy;
|
|
425
|
+
var _default = Percy;
|
|
426
|
+
exports.default = _default;
|
package/dist/queue.js
CHANGED
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default = void 0;
|
|
6
|
+
exports.default = exports.Queue = void 0;
|
|
7
7
|
|
|
8
8
|
var _utils = require("./utils");
|
|
9
9
|
|
|
10
|
+
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
11
|
+
|
|
12
|
+
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
13
|
+
|
|
10
14
|
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; }
|
|
11
15
|
|
|
12
16
|
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
@@ -25,12 +29,12 @@ class Queue {
|
|
|
25
29
|
|
|
26
30
|
_defineProperty(this, "closed", false);
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
_classPrivateFieldInitSpec(this, _queued, {
|
|
29
33
|
writable: true,
|
|
30
34
|
value: new Map()
|
|
31
35
|
});
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
_classPrivateFieldInitSpec(this, _pending, {
|
|
34
38
|
writable: true,
|
|
35
39
|
value: new Map()
|
|
36
40
|
});
|
|
@@ -39,7 +43,11 @@ class Queue {
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
push(id, callback, priority) {
|
|
42
|
-
if (this.closed
|
|
46
|
+
if (this.closed && !id.startsWith('@@/')) {
|
|
47
|
+
throw new Error('Closed');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.cancel(id);
|
|
43
51
|
let task = {
|
|
44
52
|
id,
|
|
45
53
|
callback,
|
|
@@ -51,8 +59,6 @@ class Queue {
|
|
|
51
59
|
reject
|
|
52
60
|
});
|
|
53
61
|
|
|
54
|
-
_classPrivateFieldGet(this, _queued).delete(id);
|
|
55
|
-
|
|
56
62
|
_classPrivateFieldGet(this, _queued).set(id, task);
|
|
57
63
|
|
|
58
64
|
this._dequeue();
|
|
@@ -60,12 +66,22 @@ class Queue {
|
|
|
60
66
|
return task.promise;
|
|
61
67
|
}
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
cancel(id) {
|
|
70
|
+
var _classPrivateFieldGet2, _classPrivateFieldGet3;
|
|
71
|
+
|
|
72
|
+
(_classPrivateFieldGet2 = _classPrivateFieldGet(this, _pending).get(id)) === null || _classPrivateFieldGet2 === void 0 ? void 0 : (_classPrivateFieldGet3 = _classPrivateFieldGet2.cancel) === null || _classPrivateFieldGet3 === void 0 ? void 0 : _classPrivateFieldGet3.call(_classPrivateFieldGet2);
|
|
73
|
+
|
|
74
|
+
_classPrivateFieldGet(this, _pending).delete(id);
|
|
75
|
+
|
|
76
|
+
_classPrivateFieldGet(this, _queued).delete(id);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
has(id) {
|
|
80
|
+
return _classPrivateFieldGet(this, _queued).has(id) || _classPrivateFieldGet(this, _pending).has(id);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
clear() {
|
|
84
|
+
_classPrivateFieldGet(this, _queued).clear();
|
|
69
85
|
|
|
70
86
|
return this.size;
|
|
71
87
|
}
|
|
@@ -87,30 +103,48 @@ class Queue {
|
|
|
87
103
|
return this;
|
|
88
104
|
}
|
|
89
105
|
|
|
106
|
+
open() {
|
|
107
|
+
this.closed = false;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
|
|
90
111
|
close(abort) {
|
|
91
112
|
if (abort) this.stop().clear();
|
|
92
113
|
this.closed = true;
|
|
93
114
|
return this;
|
|
94
115
|
}
|
|
95
116
|
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
idle(callback) {
|
|
118
|
+
return (0, _utils.waitFor)(() => {
|
|
119
|
+
callback === null || callback === void 0 ? void 0 : callback(_classPrivateFieldGet(this, _pending).size);
|
|
120
|
+
return !_classPrivateFieldGet(this, _pending).size;
|
|
121
|
+
}, {
|
|
98
122
|
idle: 10
|
|
99
123
|
});
|
|
100
124
|
}
|
|
101
125
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
126
|
+
empty(callback) {
|
|
127
|
+
return (0, _utils.waitFor)(() => {
|
|
128
|
+
callback === null || callback === void 0 ? void 0 : callback(this.size);
|
|
105
129
|
return !this.size;
|
|
106
130
|
}, {
|
|
107
131
|
idle: 10
|
|
108
132
|
});
|
|
109
133
|
}
|
|
110
134
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
135
|
+
flush(callback) {
|
|
136
|
+
let stopped = !this.running;
|
|
137
|
+
this.run().push('@@/flush', () => {
|
|
138
|
+
if (stopped) this.stop();
|
|
139
|
+
});
|
|
140
|
+
return this.idle(pend => {
|
|
141
|
+
let left = [..._classPrivateFieldGet(this, _queued).keys()].indexOf('@@/flush');
|
|
142
|
+
if (!~left && !_classPrivateFieldGet(this, _pending).has('@@/flush')) left = 0;
|
|
143
|
+
callback === null || callback === void 0 ? void 0 : callback(pend + left);
|
|
144
|
+
}).canceled(() => {
|
|
145
|
+
if (stopped) this.stop();
|
|
146
|
+
this.cancel('@@/flush');
|
|
147
|
+
});
|
|
114
148
|
}
|
|
115
149
|
|
|
116
150
|
next() {
|
|
@@ -134,8 +168,12 @@ class Queue {
|
|
|
134
168
|
|
|
135
169
|
_classPrivateFieldGet(this, _pending).set(task.id, task);
|
|
136
170
|
|
|
137
|
-
let done =
|
|
138
|
-
|
|
171
|
+
let done = callback => arg => {
|
|
172
|
+
var _task$cancel;
|
|
173
|
+
|
|
174
|
+
if (!((_task$cancel = task.cancel) !== null && _task$cancel !== void 0 && _task$cancel.triggered)) {
|
|
175
|
+
_classPrivateFieldGet(this, _pending).delete(task.id);
|
|
176
|
+
}
|
|
139
177
|
|
|
140
178
|
callback(arg);
|
|
141
179
|
|
|
@@ -143,12 +181,16 @@ class Queue {
|
|
|
143
181
|
};
|
|
144
182
|
|
|
145
183
|
try {
|
|
146
|
-
|
|
184
|
+
let gen = (0, _utils.generatePromise)(task.callback);
|
|
185
|
+
task.cancel = gen.cancel;
|
|
186
|
+
return gen.then(done(task.resolve), done(task.reject));
|
|
147
187
|
} catch (err) {
|
|
148
|
-
done(task.reject
|
|
188
|
+
done(task.reject)(err);
|
|
149
189
|
}
|
|
150
190
|
}
|
|
151
191
|
|
|
152
192
|
}
|
|
153
193
|
|
|
154
|
-
exports.
|
|
194
|
+
exports.Queue = Queue;
|
|
195
|
+
var _default = Queue;
|
|
196
|
+
exports.default = _default;
|