single-file-cli 2.0.28 → 2.0.30

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@single-file/single-file-cli",
3
- "version": "2.0.28",
3
+ "version": "2.0.30",
4
4
  "description": "SingleFile CLI",
5
5
  "nodeModulesDir": true,
6
6
  "exports": {
package/lib/browser.js CHANGED
@@ -34,6 +34,8 @@ async function launchBrowser(options = {}, indexPath = 0) {
34
34
  const executablePath = options.executablePath || BROWSER_PATHS[build.os][indexPath];
35
35
  const args = Array.from(BROWSER_ARGS);
36
36
  profilePath = await makeTempDir();
37
+ const debugPort = await getDebugPort();
38
+ args.push("--remote-debugging-port=" + debugPort);
37
39
  if (options.headless && !options.debug) {
38
40
  args.push("--headless");
39
41
  } else {
@@ -64,7 +66,7 @@ async function launchBrowser(options = {}, indexPath = 0) {
64
66
  } catch (error) {
65
67
  if (error instanceof errors.NotFound) {
66
68
  if (indexPath + 1 < BROWSER_PATHS[build.os].length) {
67
- await launchBrowser(options, indexPath + 1);
69
+ return launchBrowser(options, indexPath + 1);
68
70
  } else {
69
71
  throw error;
70
72
  }
@@ -73,7 +75,20 @@ async function launchBrowser(options = {}, indexPath = 0) {
73
75
  }
74
76
  }
75
77
  child.ref();
76
- return child;
78
+ return debugPort;
79
+ }
80
+
81
+ async function getDebugPort(port = 9222) {
82
+ try {
83
+ await fetch("http://localhost:" + port + "/json/version");
84
+ } catch (error) {
85
+ return port;
86
+ }
87
+ if (port < 9286) {
88
+ return getDebugPort(port + 1);
89
+ } else {
90
+ throw new Error("No available debugging port");
91
+ }
77
92
  }
78
93
 
79
94
  async function closeBrowser() {
package/lib/cdp-client.js CHANGED
@@ -25,22 +25,21 @@
25
25
 
26
26
  import { launchBrowser, closeBrowser } from "./browser.js";
27
27
  import { getScriptSource, getHookScriptSource } from "./single-file-script.js";
28
- import { CDP } from "simple-cdp";
28
+ import { CDP, options } from "simple-cdp";
29
29
 
30
30
  const LOAD_TIMEOUT_ERROR = "ERR_LOAD_TIMEOUT";
31
- const DEFAULT_NETWORK_STATE = "networkIdle";
32
31
  const NETWORK_STATES = ["InteractiveTime", "networkIdle", "networkAlmostIdle", "load", "DOMContentLoaded"];
33
32
  const MINIMIZED_WINDOW_STATE = "minimized";
34
33
  const SINGLE_FILE_WORLD_NAME = "singlefile";
35
34
  const EMPTY_PAGE_URL = "about:blank";
36
35
 
37
- export { initialize, getPageData, hasPageTargets, closeBrowser };
36
+ export { initialize, getPageData, closeBrowser };
38
37
 
39
- async function initialize(options) {
38
+ async function initialize(singleFileOptions) {
40
39
  if (options.browserRemoteDebuggingURL) {
41
- CDP.remoteDebuggingUrl = options.browserRemoteDebuggingURL;
40
+ options.apiUrl = singleFileOptions.browserRemoteDebuggingURL;
42
41
  } else {
43
- await launchBrowser(getBrowserOptions(options));
42
+ options.apiUrl = "http://localhost:" + (await launchBrowser(getBrowserOptions(singleFileOptions)));
44
43
  }
45
44
  }
46
45
 
@@ -116,7 +115,7 @@ async function getPageData(options) {
116
115
  if (subtype === "error") {
117
116
  throw new Error(description);
118
117
  }
119
- if (options.compressContent) {
118
+ if (Array.isArray(value.content)) {
120
119
  value.content = new Uint8Array(value.content);
121
120
  }
122
121
  return value;
@@ -136,11 +135,6 @@ async function getPageData(options) {
136
135
  }
137
136
  }
138
137
 
139
- async function hasPageTargets() {
140
- const targets = await CDP.getTargets();
141
- return targets.filter(target => target.type === "page").length > 0;
142
- }
143
-
144
138
  async function loadPage({ Page, Runtime }, options) {
145
139
  await Runtime.enable();
146
140
  await Page.enable();
@@ -162,12 +156,10 @@ async function loadPage({ Page, Runtime }, options) {
162
156
  }
163
157
 
164
158
  async function getTopFrameContextId({ Page, Runtime }, options) {
165
- const FRAME_NAVIGATED_EVENT = "frameNavigated";
166
159
  const CONTEXT_CREATED_EVENT = "executionContextCreated";
167
160
  const contextIds = [];
168
161
  let topFrameId;
169
162
  try {
170
- Page.addEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
171
163
  Runtime.addEventListener(CONTEXT_CREATED_EVENT, onExecutionContextCreated);
172
164
  await waitForPageReady({ Page }, options);
173
165
  const contextId = await getContextId();
@@ -177,21 +169,9 @@ async function getTopFrameContextId({ Page, Runtime }, options) {
177
169
  return contextId;
178
170
  }
179
171
  } finally {
180
- Page.removeEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
181
172
  Runtime.removeEventListener(CONTEXT_CREATED_EVENT, onExecutionContextCreated);
182
173
  }
183
174
 
184
- function onFrameNavigated({ params }) {
185
- const { frame } = params;
186
- if (!frame.parentId) {
187
- if (frame.unreachableUrl) {
188
- throw new Error("Unreachable URL: " + frame.unreachableUrl);
189
- } else {
190
- topFrameId = frame.id;
191
- }
192
- }
193
- }
194
-
195
175
  function onExecutionContextCreated({ params }) {
196
176
  const { context } = params;
197
177
  const { name, auxData = {} } = context;
@@ -203,17 +183,36 @@ async function getTopFrameContextId({ Page, Runtime }, options) {
203
183
  async function waitForPageReady({ Page }, options) {
204
184
  await Page.setLifecycleEventsEnabled({ enabled: true });
205
185
  try {
206
- await new Promise(resolve => {
186
+ await new Promise((resolve, reject) => {
207
187
  const LIFE_CYCLE_EVENT = "lifecycleEvent";
188
+ const FRAME_NAVIGATED_EVENT = "frameNavigated";
208
189
  Page.addEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
190
+ Page.addEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
209
191
 
210
192
  function onLifecycleEvent({ params }) {
211
193
  const { frameId, name } = params;
212
- if (frameId === topFrameId && (name === options.browserWaitUntil || name === DEFAULT_NETWORK_STATE)) {
213
- Page.removeEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
194
+ if (frameId === topFrameId && name === options.browserWaitUntil) {
195
+ removeListeners();
214
196
  resolve();
215
197
  }
216
198
  }
199
+
200
+ function onFrameNavigated({ params }) {
201
+ const { frame } = params;
202
+ if (!frame.parentId) {
203
+ if (frame.unreachableUrl) {
204
+ removeListeners();
205
+ reject(new Error("Unreachable URL: " + frame.unreachableUrl));
206
+ } else {
207
+ topFrameId = frame.id;
208
+ }
209
+ }
210
+ }
211
+
212
+ function removeListeners() {
213
+ Page.removeEventListener(LIFE_CYCLE_EVENT, onLifecycleEvent);
214
+ Page.removeEventListener(FRAME_NAVIGATED_EVENT, onFrameNavigated);
215
+ }
217
216
  });
218
217
  } finally {
219
218
  await Page.setLifecycleEventsEnabled({ enabled: false });
package/lib/constants.js CHANGED
@@ -52,7 +52,6 @@ const BROWSER_ARGS = [
52
52
  "--enable-use-zoom-for-dsf=false",
53
53
  "--no-sandbox",
54
54
  "--no-startup-window",
55
- "--remote-debugging-port=9222",
56
55
  "--bwsi"
57
56
  ];
58
57
  const BROWSER_PATHS = {
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const version = "2.0.28";
1
+ export const version = "2.0.30";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-cli",
3
- "version": "2.0.28",
3
+ "version": "2.0.30",
4
4
  "description": "SingleFile CLI",
5
5
  "author": "Gildas Lormeau",
6
6
  "engines": {
@@ -151,7 +151,7 @@ async function finish(options) {
151
151
  }
152
152
  }
153
153
  }
154
- if (!options.browserDebug && !options.browserRemoteDebuggingURL && !(await backend.hasPageTargets())) {
154
+ if (!options.browserDebug && !options.browserRemoteDebuggingURL) {
155
155
  return backend.closeBrowser();
156
156
  }
157
157
  }
@@ -28,15 +28,8 @@ import options from "./options.js";
28
28
 
29
29
  const { readTextFile, exit, addSignalListener } = Deno;
30
30
 
31
- addSignalListener("SIGTERM", async () => {
32
- await closeBrowser();
33
- exit();
34
- });
35
-
36
- addSignalListener("SIGINT", async () => {
37
- await closeBrowser();
38
- exit();
39
- });
31
+ addSignalListener("SIGTERM", closeBrowserAndExit);
32
+ addSignalListener("SIGINT", closeBrowserAndExit);
40
33
 
41
34
  export { run };
42
35
 
@@ -116,3 +109,8 @@ function parseCookies(textValue) {
116
109
  })
117
110
  .filter(cookieData => cookieData);
118
111
  }
112
+
113
+ async function closeBrowserAndExit() {
114
+ await closeBrowser();
115
+ exit();
116
+ }