single-file-cli 2.0.26 → 2.0.28
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 +60 -66
- package/lib/deno-polyfill.js +10 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/single-file-launcher.js +13 -2
- package/single-file-node.bat +1 -1
package/deno.json
CHANGED
package/lib/cdp-client.js
CHANGED
|
@@ -161,64 +161,78 @@ async function loadPage({ Page, Runtime }, options) {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
function getTopFrameContextId({ Page, Runtime }, options) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
164
|
+
async function getTopFrameContextId({ Page, Runtime }, options) {
|
|
165
|
+
const FRAME_NAVIGATED_EVENT = "frameNavigated";
|
|
166
|
+
const CONTEXT_CREATED_EVENT = "executionContextCreated";
|
|
167
|
+
const contextIds = [];
|
|
168
|
+
let topFrameId;
|
|
169
|
+
try {
|
|
170
170
|
Page.addEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
|
|
171
171
|
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
|
-
}
|
|
172
|
+
await waitForPageReady({ Page }, options);
|
|
173
|
+
const contextId = await getContextId();
|
|
174
|
+
if (contextId === undefined) {
|
|
175
|
+
throw new Error("Execution context not found");
|
|
176
|
+
} else {
|
|
177
|
+
return contextId;
|
|
188
178
|
}
|
|
179
|
+
} finally {
|
|
180
|
+
Page.removeEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
|
|
181
|
+
Runtime.removeEventListener(CONTEXT_CREATED_EVENT, onExecutionContextCreated);
|
|
182
|
+
}
|
|
189
183
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (
|
|
194
|
-
|
|
184
|
+
function onFrameNavigated({ params }) {
|
|
185
|
+
const { frame } = params;
|
|
186
|
+
if (!frame.parentId) {
|
|
187
|
+
if (frame.unreachableUrl) {
|
|
188
|
+
throw new Error("Unreachable URL: " + frame.unreachableUrl);
|
|
195
189
|
} else {
|
|
196
|
-
|
|
190
|
+
topFrameId = frame.id;
|
|
197
191
|
}
|
|
198
192
|
}
|
|
193
|
+
}
|
|
199
194
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
195
|
+
function onExecutionContextCreated({ params }) {
|
|
196
|
+
const { context } = params;
|
|
197
|
+
const { name, auxData = {} } = context;
|
|
198
|
+
if (name === SINGLE_FILE_WORLD_NAME && topFrameId !== undefined && auxData.frameId === topFrameId) {
|
|
199
|
+
contextIds.unshift(context.id);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function waitForPageReady({ Page }, options) {
|
|
204
|
+
await Page.setLifecycleEventsEnabled({ enabled: true });
|
|
205
|
+
try {
|
|
206
|
+
await new Promise(resolve => {
|
|
207
|
+
const LIFE_CYCLE_EVENT = "lifecycleEvent";
|
|
208
|
+
Page.addEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
|
|
209
|
+
|
|
210
|
+
function onLifecycleEvent({ params }) {
|
|
211
|
+
const { frameId, name } = params;
|
|
212
|
+
if (frameId === topFrameId && (name === options.browserWaitUntil || name === DEFAULT_NETWORK_STATE)) {
|
|
213
|
+
Page.removeEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
|
|
214
|
+
resolve();
|
|
207
215
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
} finally {
|
|
219
|
+
await Page.setLifecycleEventsEnabled({ enabled: false });
|
|
212
220
|
}
|
|
221
|
+
}
|
|
213
222
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
223
|
+
async function getContextId() {
|
|
224
|
+
let contextId;
|
|
225
|
+
if (contextIds.length) {
|
|
226
|
+
let contextIdIndex = 0;
|
|
227
|
+
do {
|
|
228
|
+
if (await testExecutionContext(contextIds[contextIdIndex])) {
|
|
229
|
+
contextId = contextIds[contextIdIndex];
|
|
230
|
+
}
|
|
231
|
+
contextIdIndex++;
|
|
232
|
+
} while (contextId === undefined && contextIdIndex < contextIds.length);
|
|
220
233
|
}
|
|
221
|
-
|
|
234
|
+
return contextId;
|
|
235
|
+
}
|
|
222
236
|
|
|
223
237
|
async function testExecutionContext(contextId) {
|
|
224
238
|
try {
|
|
@@ -253,26 +267,6 @@ function waitForLoadTimeout(abortSignal, maxDelay) {
|
|
|
253
267
|
});
|
|
254
268
|
}
|
|
255
269
|
|
|
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
270
|
async function waitForDebuggerReady({ Debugger }) {
|
|
277
271
|
await Debugger.enable();
|
|
278
272
|
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.28";
|
package/package.json
CHANGED
package/single-file-launcher.js
CHANGED
|
@@ -22,10 +22,21 @@
|
|
|
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", async () => {
|
|
32
|
+
await closeBrowser();
|
|
33
|
+
exit();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
addSignalListener("SIGINT", async () => {
|
|
37
|
+
await closeBrowser();
|
|
38
|
+
exit();
|
|
39
|
+
});
|
|
29
40
|
|
|
30
41
|
export { run };
|
|
31
42
|
|
|
@@ -104,4 +115,4 @@ function parseCookies(textValue) {
|
|
|
104
115
|
}
|
|
105
116
|
})
|
|
106
117
|
.filter(cookieData => cookieData);
|
|
107
|
-
}
|
|
118
|
+
}
|
package/single-file-node.bat
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@echo off
|
|
2
|
-
node "%~dp0\single-file" %*
|
|
2
|
+
node "%~dp0\single-file-node.js" %*
|