unprint 0.19.2 → 0.19.4
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/package.json +1 -1
- package/src/app.js +20 -2
- package/src/server.js +26 -1
- package/tests/remote.js +2 -1
package/package.json
CHANGED
package/src/app.js
CHANGED
|
@@ -1222,11 +1222,13 @@ const clients = new Map();
|
|
|
1222
1222
|
/* eslint-enable no-param-reassign */
|
|
1223
1223
|
async function getBrowserInstance(scope, options, useProxy = false) {
|
|
1224
1224
|
const scopeKey = `${scope}_${useProxy ? 'proxy' : 'direct'}_${options.browser ? hashObject(options.browser) : 'default'}_${options.context ? hashObject(options.context) : 'default'}`;
|
|
1225
|
+
const now = new Date();
|
|
1225
1226
|
|
|
1226
1227
|
if (clients.has(scopeKey)) {
|
|
1227
1228
|
const client = clients.get(scopeKey);
|
|
1228
1229
|
|
|
1229
1230
|
client.uses += 1;
|
|
1231
|
+
client.lastUsedAt = now;
|
|
1230
1232
|
|
|
1231
1233
|
if (client.uses >= (options.clientRetirement || 20)) {
|
|
1232
1234
|
client.retired = true;
|
|
@@ -1262,6 +1264,8 @@ async function getBrowserInstance(scope, options, useProxy = false) {
|
|
|
1262
1264
|
active: 0,
|
|
1263
1265
|
uses: 1,
|
|
1264
1266
|
retired: false,
|
|
1267
|
+
createdAt: now,
|
|
1268
|
+
lastUsedAt: now,
|
|
1265
1269
|
};
|
|
1266
1270
|
|
|
1267
1271
|
if (scope) {
|
|
@@ -1274,12 +1278,18 @@ async function getBrowserInstance(scope, options, useProxy = false) {
|
|
|
1274
1278
|
return client;
|
|
1275
1279
|
}
|
|
1276
1280
|
|
|
1281
|
+
function getAllBrowsers() {
|
|
1282
|
+
return clients;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1277
1285
|
async function closeAllBrowsers() {
|
|
1278
1286
|
const closingClients = Array.from(clients.values());
|
|
1279
1287
|
|
|
1280
1288
|
await Promise.all(closingClients.map(async (client) => {
|
|
1281
1289
|
await client.context.close();
|
|
1282
1290
|
await client.browser.close();
|
|
1291
|
+
|
|
1292
|
+
clients.delete(client.key);
|
|
1283
1293
|
}));
|
|
1284
1294
|
|
|
1285
1295
|
events.emit('browserClose', {
|
|
@@ -1290,20 +1300,26 @@ async function closeAllBrowsers() {
|
|
|
1290
1300
|
});
|
|
1291
1301
|
}
|
|
1292
1302
|
|
|
1293
|
-
async function closeBrowser(client, options) {
|
|
1303
|
+
async function closeBrowser(client, options = {}) {
|
|
1294
1304
|
if (options.client === null // this browser is single-use
|
|
1295
1305
|
|| (client.retired && client.active === 0)) { // this browser is retired to minimize garbage build-up
|
|
1296
1306
|
// this browser won't be reused, browser close DOES NOT automatically close context https://github.com/microsoft/playwright/issues/15163
|
|
1297
1307
|
await client.context.close();
|
|
1298
1308
|
await client.browser.close();
|
|
1299
1309
|
|
|
1310
|
+
clients.delete(client.key);
|
|
1311
|
+
|
|
1300
1312
|
events.emit('browserClose', {
|
|
1301
1313
|
keys: [client.key],
|
|
1302
1314
|
active: client.active,
|
|
1303
1315
|
retired: !!client.retired,
|
|
1304
1316
|
clients: clients.size,
|
|
1305
1317
|
});
|
|
1318
|
+
|
|
1319
|
+
return true;
|
|
1306
1320
|
}
|
|
1321
|
+
|
|
1322
|
+
return false;
|
|
1307
1323
|
}
|
|
1308
1324
|
|
|
1309
1325
|
function getAgent(options, url) {
|
|
@@ -1392,7 +1408,7 @@ function useRemoteRequest(options, method) {
|
|
|
1392
1408
|
return true;
|
|
1393
1409
|
}
|
|
1394
1410
|
|
|
1395
|
-
if (options.remote.methods.includes(method.toLowerCase())) {
|
|
1411
|
+
if (options.remote.methods.includes(method.toLowerCase()) && options.useRemote !== false) {
|
|
1396
1412
|
return true;
|
|
1397
1413
|
}
|
|
1398
1414
|
}
|
|
@@ -1729,7 +1745,9 @@ const unprint = {
|
|
|
1729
1745
|
request,
|
|
1730
1746
|
browserRequest,
|
|
1731
1747
|
browser: browserRequest,
|
|
1748
|
+
closeBrowser,
|
|
1732
1749
|
closeAllBrowsers,
|
|
1750
|
+
getAllBrowsers,
|
|
1733
1751
|
initialize: init,
|
|
1734
1752
|
initializeAll: initAll,
|
|
1735
1753
|
init,
|
package/src/server.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const express = require('express');
|
|
5
|
+
const timers = require('timers/promises');
|
|
5
6
|
|
|
6
7
|
require('dotenv').config();
|
|
7
8
|
|
|
@@ -79,6 +80,26 @@ async function handleRequest(req, res, unprint, method) {
|
|
|
79
80
|
});
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
async function monitorBrowsers(unprint) {
|
|
84
|
+
await timers.setTimeout(60_000);
|
|
85
|
+
|
|
86
|
+
const clients = unprint.getAllBrowsers();
|
|
87
|
+
|
|
88
|
+
const checkedClients = await Promise.all(Array.from(clients.values()).map(async (client) => {
|
|
89
|
+
if (new Date() - client.lastUsedAt > 300_000) { // 5 minute expiry
|
|
90
|
+
return unprint.closeBrowser(client, { client: null });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return false;
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
const closedClients = checkedClients.filter(Boolean).length;
|
|
97
|
+
|
|
98
|
+
logger.info(`Closed ${closedClients}/${checkedClients.length} browsers`);
|
|
99
|
+
|
|
100
|
+
monitorBrowsers(unprint);
|
|
101
|
+
}
|
|
102
|
+
|
|
82
103
|
async function initServer(address, unprint) {
|
|
83
104
|
const app = express();
|
|
84
105
|
const addressComponents = typeof address === 'boolean' ? [] : String(address).split(':');
|
|
@@ -88,7 +109,7 @@ async function initServer(address, unprint) {
|
|
|
88
109
|
|
|
89
110
|
app.use(express.json());
|
|
90
111
|
|
|
91
|
-
app.use(async (req,
|
|
112
|
+
app.use(async (req, _res, next) => {
|
|
92
113
|
if (process.env.UNPRINT_KEY) {
|
|
93
114
|
if (process.env.UNPRINT_KEY.length !== req.headers['unprint-key']?.length
|
|
94
115
|
|| !crypto.timingSafeEqual(Buffer.from(process.env.UNPRINT_KEY, 'utf16le'), Buffer.from(req.headers['unprint-key'], 'utf16le'))) {
|
|
@@ -114,6 +135,8 @@ async function initServer(address, unprint) {
|
|
|
114
135
|
|
|
115
136
|
unprint.options(curateOptions(req.body));
|
|
116
137
|
|
|
138
|
+
logger.info('Configuration updated');
|
|
139
|
+
|
|
117
140
|
res.status(204).send();
|
|
118
141
|
});
|
|
119
142
|
|
|
@@ -134,6 +157,8 @@ async function initServer(address, unprint) {
|
|
|
134
157
|
|
|
135
158
|
logger.info(`Started unprint server on ${host}:${port}`);
|
|
136
159
|
});
|
|
160
|
+
|
|
161
|
+
monitorBrowsers(unprint);
|
|
137
162
|
}
|
|
138
163
|
|
|
139
164
|
module.exports = initServer;
|
package/tests/remote.js
CHANGED
|
@@ -13,9 +13,10 @@ unprint.configure({
|
|
|
13
13
|
|
|
14
14
|
async function init() {
|
|
15
15
|
unprint.on('requestInit', (event) => console.log('INIT', event));
|
|
16
|
+
unprint.on('browserClose', (event) => console.log('CLOSE', event));
|
|
16
17
|
|
|
17
18
|
const res = await unprint.browser('https://www.google.com', {
|
|
18
|
-
useRemote:
|
|
19
|
+
useRemote: true,
|
|
19
20
|
async control(page) {
|
|
20
21
|
const form = await page.locator('form');
|
|
21
22
|
|