single-file-cli 2.0.27 → 2.0.29
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/deno.json +1 -1
- package/lib/cdp-client.js +69 -70
- package/lib/deno-polyfill.js +10 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/single-file-launcher.js +10 -1
package/deno.json
CHANGED
package/lib/cdp-client.js
CHANGED
|
@@ -116,7 +116,7 @@ async function getPageData(options) {
|
|
|
116
116
|
if (subtype === "error") {
|
|
117
117
|
throw new Error(description);
|
|
118
118
|
}
|
|
119
|
-
if (
|
|
119
|
+
if (Array.isArray(value.content)) {
|
|
120
120
|
value.content = new Uint8Array(value.content);
|
|
121
121
|
}
|
|
122
122
|
return value;
|
|
@@ -161,64 +161,83 @@ async function loadPage({ Page, Runtime }, options) {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
function getTopFrameContextId({ Page, Runtime }, options) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
let frameId;
|
|
170
|
-
Page.addEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
|
|
164
|
+
async function getTopFrameContextId({ Page, Runtime }, options) {
|
|
165
|
+
const CONTEXT_CREATED_EVENT = "executionContextCreated";
|
|
166
|
+
const contextIds = [];
|
|
167
|
+
let topFrameId;
|
|
168
|
+
try {
|
|
171
169
|
Runtime.addEventListener(CONTEXT_CREATED_EVENT, onExecutionContextCreated);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
reject(new Error("Unreachable URL: " + frame.unreachableUrl));
|
|
179
|
-
} else {
|
|
180
|
-
frameId = frame.id;
|
|
181
|
-
await onTopFrameNavigated();
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
} finally {
|
|
185
|
-
Page.removeEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
|
|
186
|
-
Runtime.removeEventListener(CONTEXT_CREATED_EVENT, onExecutionContextCreated);
|
|
187
|
-
}
|
|
170
|
+
await waitForPageReady({ Page }, options);
|
|
171
|
+
const contextId = await getContextId();
|
|
172
|
+
if (contextId === undefined) {
|
|
173
|
+
throw new Error("Execution context not found");
|
|
174
|
+
} else {
|
|
175
|
+
return contextId;
|
|
188
176
|
}
|
|
177
|
+
} finally {
|
|
178
|
+
Runtime.removeEventListener(CONTEXT_CREATED_EVENT, onExecutionContextCreated);
|
|
179
|
+
}
|
|
189
180
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
} else {
|
|
196
|
-
resolve(contextId);
|
|
197
|
-
}
|
|
181
|
+
function onExecutionContextCreated({ params }) {
|
|
182
|
+
const { context } = params;
|
|
183
|
+
const { name, auxData = {} } = context;
|
|
184
|
+
if (name === SINGLE_FILE_WORLD_NAME && topFrameId !== undefined && auxData.frameId === topFrameId) {
|
|
185
|
+
contextIds.unshift(context.id);
|
|
198
186
|
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function waitForPageReady({ Page }, options) {
|
|
190
|
+
await Page.setLifecycleEventsEnabled({ enabled: true });
|
|
191
|
+
try {
|
|
192
|
+
await new Promise((resolve, reject) => {
|
|
193
|
+
const LIFE_CYCLE_EVENT = "lifecycleEvent";
|
|
194
|
+
const FRAME_NAVIGATED_EVENT = "frameNavigated";
|
|
195
|
+
Page.addEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
|
|
196
|
+
Page.addEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
|
|
199
197
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (await testExecutionContext(contextIds[contextIdIndex])) {
|
|
206
|
-
contextId = contextIds[contextIdIndex];
|
|
198
|
+
function onLifecycleEvent({ params }) {
|
|
199
|
+
const { frameId, name } = params;
|
|
200
|
+
if (frameId === topFrameId && (name === options.browserWaitUntil || name === DEFAULT_NETWORK_STATE)) {
|
|
201
|
+
removeListeners();
|
|
202
|
+
resolve();
|
|
207
203
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function onFrameNavigated({ params }) {
|
|
207
|
+
const { frame } = params;
|
|
208
|
+
if (!frame.parentId) {
|
|
209
|
+
if (frame.unreachableUrl) {
|
|
210
|
+
removeListeners();
|
|
211
|
+
reject(new Error("Unreachable URL: " + frame.unreachableUrl));
|
|
212
|
+
} else {
|
|
213
|
+
topFrameId = frame.id;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function removeListeners() {
|
|
219
|
+
Page.removeEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
|
|
220
|
+
Page.removeEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
} finally {
|
|
224
|
+
await Page.setLifecycleEventsEnabled({ enabled: false });
|
|
212
225
|
}
|
|
226
|
+
}
|
|
213
227
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
228
|
+
async function getContextId() {
|
|
229
|
+
let contextId;
|
|
230
|
+
if (contextIds.length) {
|
|
231
|
+
let contextIdIndex = 0;
|
|
232
|
+
do {
|
|
233
|
+
if (await testExecutionContext(contextIds[contextIdIndex])) {
|
|
234
|
+
contextId = contextIds[contextIdIndex];
|
|
235
|
+
}
|
|
236
|
+
contextIdIndex++;
|
|
237
|
+
} while (contextId === undefined && contextIdIndex < contextIds.length);
|
|
220
238
|
}
|
|
221
|
-
|
|
239
|
+
return contextId;
|
|
240
|
+
}
|
|
222
241
|
|
|
223
242
|
async function testExecutionContext(contextId) {
|
|
224
243
|
try {
|
|
@@ -253,26 +272,6 @@ function waitForLoadTimeout(abortSignal, maxDelay) {
|
|
|
253
272
|
});
|
|
254
273
|
}
|
|
255
274
|
|
|
256
|
-
async function waitForPageReady({ Page }, topFrameId, options) {
|
|
257
|
-
await Page.setLifecycleEventsEnabled({ enabled: true });
|
|
258
|
-
try {
|
|
259
|
-
await new Promise(resolve => {
|
|
260
|
-
const LIFE_CYCLE_EVENT = "lifecycleEvent";
|
|
261
|
-
Page.addEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
|
|
262
|
-
|
|
263
|
-
function onLifecycleEvent({ params }) {
|
|
264
|
-
const { name, frameId } = params;
|
|
265
|
-
if (frameId === topFrameId && (name === options.browserWaitUntil || name === DEFAULT_NETWORK_STATE)) {
|
|
266
|
-
Page.removeEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
|
|
267
|
-
resolve();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
} finally {
|
|
272
|
-
await Page.setLifecycleEventsEnabled({ enabled: false });
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
275
|
async function waitForDebuggerReady({ Debugger }) {
|
|
277
276
|
await Debugger.enable();
|
|
278
277
|
try {
|
package/lib/deno-polyfill.js
CHANGED
|
@@ -80,7 +80,7 @@ const Command = DENO_RUNTIME_DETECTED ? Deno.Command : class Command {
|
|
|
80
80
|
return {
|
|
81
81
|
status: new Promise((resolve, reject) => {
|
|
82
82
|
child.on("exit", code => {
|
|
83
|
-
if (code === 0 || code === 143) {
|
|
83
|
+
if (code === 0 || code === 143 || code === 130) {
|
|
84
84
|
resolve();
|
|
85
85
|
} else {
|
|
86
86
|
reject(new Error(`Process exited with code ${code}`));
|
|
@@ -108,6 +108,7 @@ const DenoAPI = {
|
|
|
108
108
|
remove,
|
|
109
109
|
stdout,
|
|
110
110
|
exit,
|
|
111
|
+
addSignalListener,
|
|
111
112
|
build,
|
|
112
113
|
errors,
|
|
113
114
|
Command
|
|
@@ -207,6 +208,14 @@ function exit(code) {
|
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
function addSignalListener(signal, listener) {
|
|
212
|
+
if (DENO_RUNTIME_DETECTED) {
|
|
213
|
+
Deno.addSignalListener(signal, listener);
|
|
214
|
+
} else {
|
|
215
|
+
process.once(signal, listener);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
210
219
|
async function dirname(filePath) {
|
|
211
220
|
return path.dirname(filePath);
|
|
212
221
|
}
|
package/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "2.0.
|
|
1
|
+
export const version = "2.0.29";
|
package/package.json
CHANGED
package/single-file-launcher.js
CHANGED
|
@@ -22,10 +22,14 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { initialize } from "./single-file-cli-api.js";
|
|
25
|
+
import { closeBrowser } from "./lib/browser.js";
|
|
25
26
|
import { Deno } from "./lib/deno-polyfill.js";
|
|
26
27
|
import options from "./options.js";
|
|
27
28
|
|
|
28
|
-
const { readTextFile, exit } = Deno;
|
|
29
|
+
const { readTextFile, exit, addSignalListener } = Deno;
|
|
30
|
+
|
|
31
|
+
addSignalListener("SIGTERM", closeBrowserAndExit);
|
|
32
|
+
addSignalListener("SIGINT", closeBrowserAndExit);
|
|
29
33
|
|
|
30
34
|
export { run };
|
|
31
35
|
|
|
@@ -104,4 +108,9 @@ function parseCookies(textValue) {
|
|
|
104
108
|
}
|
|
105
109
|
})
|
|
106
110
|
.filter(cookieData => cookieData);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function closeBrowserAndExit() {
|
|
114
|
+
await closeBrowser();
|
|
115
|
+
exit();
|
|
107
116
|
}
|