unprint 0.17.1 → 0.17.3

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/README.md CHANGED
@@ -239,6 +239,7 @@ Returns
239
239
  ok, // (boolean) status code >= 200 and < 300
240
240
  response, // (object) the original axios response object, alias 'res'
241
241
  res, // (object) alias for 'response'
242
+ control, // return value from browser control function
242
243
  }
243
244
  ```
244
245
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unprint",
3
- "version": "0.17.1",
3
+ "version": "0.17.3",
4
4
  "description": "Simplify common web scraping tasks while staying in control of the data.",
5
5
  "main": "src/app.js",
6
6
  "scripts": {},
package/src/app.js CHANGED
@@ -1048,25 +1048,34 @@ const clients = new Map();
1048
1048
  /* eslint-enable no-param-reassign */
1049
1049
  async function getBrowserInstance(scope, options) {
1050
1050
  if (clients.has(scope)) {
1051
- return clients.get(scope);
1051
+ const client = clients.get(scope);
1052
+
1053
+ await client.launchers;
1054
+
1055
+ return client;
1052
1056
  }
1053
1057
 
1054
- const browser = await chromium.launch({
1058
+ // if we await here, we create a race condition, and a second call to getBrowserInstance would launch another browser that will overwrite the first one
1059
+ const browserLauncher = chromium.launch({
1055
1060
  headless: true,
1056
1061
  ...options.browser,
1057
1062
  });
1058
1063
 
1059
- const context = await browser.newContext({
1064
+ const contextLauncher = browserLauncher.then((browser) => browser.newContext({
1060
1065
  userAgent: 'unprint',
1061
1066
  ...options.context,
1062
- });
1067
+ }));
1063
1068
 
1064
- const client = { context, browser };
1069
+ const launchers = Promise.all([browserLauncher, contextLauncher]);
1070
+ const client = { launchers };
1065
1071
 
1066
1072
  if (scope) {
1067
1073
  clients.set(scope, client);
1068
1074
  }
1069
1075
 
1076
+ client.browser = await browserLauncher;
1077
+ client.context = await contextLauncher;
1078
+
1070
1079
  return client;
1071
1080
  }
1072
1081
 
@@ -1074,7 +1083,7 @@ async function closeAllBrowsers() {
1074
1083
  await Promise.all(Array.from(clients.values()).map(async (client) => client.browser.close()));
1075
1084
  }
1076
1085
 
1077
- function curateResponse(res, options, { url, customOptions }) {
1086
+ function curateResponse(res, options, { url, control, customOptions }) {
1078
1087
  const base = {
1079
1088
  ok: true,
1080
1089
  status: res.status,
@@ -1082,6 +1091,7 @@ function curateResponse(res, options, { url, customOptions }) {
1082
1091
  headers: res.headers,
1083
1092
  response: res,
1084
1093
  res,
1094
+ control,
1085
1095
  };
1086
1096
 
1087
1097
  if (['application/json', 'application/javascript'].some((type) => res.headers['content-type']?.includes(type)) && typeof res.data === 'object') {
@@ -1164,8 +1174,10 @@ async function browserRequest(url, customOptions = {}) {
1164
1174
 
1165
1175
  await page.waitForLoadState();
1166
1176
 
1177
+ let control = null;
1178
+
1167
1179
  if (customOptions.control) {
1168
- await customOptions.control(page, { context, browser });
1180
+ control = await customOptions.control(page, { context, browser });
1169
1181
  }
1170
1182
 
1171
1183
  events.emit('controlSuccess', feedbackBase);
@@ -1184,7 +1196,11 @@ async function browserRequest(url, customOptions = {}) {
1184
1196
  status,
1185
1197
  statusText,
1186
1198
  headers,
1187
- }, options, { url, customOptions });
1199
+ }, options, {
1200
+ url,
1201
+ customOptions,
1202
+ control,
1203
+ });
1188
1204
  });
1189
1205
  }
1190
1206
 
package/tests/browser.js CHANGED
@@ -3,12 +3,30 @@
3
3
  const unprint = require('../src/app');
4
4
 
5
5
  async function initTest() {
6
+ // concurrency
7
+ await Promise.all([
8
+ unprint.browser('https://tools-httpstatus.pickup-services.com/200?sleep=500', {
9
+ browser: {
10
+ headless: false,
11
+ },
12
+ }),
13
+ unprint.browser('https://tools-httpstatus.pickup-services.com/200?sleep=500', {
14
+ browser: {
15
+ headless: false,
16
+ },
17
+ }),
18
+ unprint.browser('https://tools-httpstatus.pickup-services.com/200?sleep=500', {
19
+ browser: {
20
+ headless: false,
21
+ },
22
+ }),
23
+ ]);
24
+
6
25
  await Promise.all([
7
26
  unprint.browser('https://tools-httpstatus.pickup-services.com/200?sleep=5000', {
8
27
  browser: {
9
28
  headless: false,
10
29
  },
11
- scope: null,
12
30
  async control(_page) {
13
31
  //
14
32
  },
@@ -22,7 +40,6 @@ async function initTest() {
22
40
  browser: {
23
41
  headless: false,
24
42
  },
25
- scope: null,
26
43
  async control(_page) {
27
44
  //
28
45
  },
@@ -34,13 +51,14 @@ async function initTest() {
34
51
  // await unprint.browser('https://www.scrapingcourse.com/', {
35
52
  headless: false,
36
53
  async control(_page) {
37
- //
54
+ return 'test';
38
55
  },
39
56
  });
40
57
 
41
58
  const cards = res.context.query.contents('h2');
42
59
 
43
60
  console.log('CARD TITLES', cards);
61
+ console.log('CONTROL OUT', res.control);
44
62
 
45
63
  await unprint.closeAllBrowsers();
46
64
  }