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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@single-file/single-file-cli",
3
- "version": "2.0.27",
3
+ "version": "2.0.29",
4
4
  "description": "SingleFile CLI",
5
5
  "nodeModulesDir": true,
6
6
  "exports": {
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 (options.compressContent) {
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
- return new Promise((resolve, reject) => {
166
- const FRAME_NAVIGATED_EVENT = "frameNavigated";
167
- const CONTEXT_CREATED_EVENT = "executionContextCreated";
168
- const contextIds = [];
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
- async function onFrameNavigated({ params }) {
174
- try {
175
- const { frame } = params;
176
- if (!frame.parentId) {
177
- if (frame.unreachableUrl) {
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
- async function onTopFrameNavigated() {
191
- await waitForPageReady({ Page }, frameId, options);
192
- const contextId = await getContextId();
193
- if (contextId === undefined) {
194
- reject(new Error("Execution context not found"));
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
- async function getContextId() {
201
- let contextId;
202
- if (contextIds.length) {
203
- let contextIdIndex = 0;
204
- do {
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
- contextIdIndex++;
209
- } while (contextId === undefined && contextIdIndex < contextIds.length);
210
- }
211
- return contextId;
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
- function onExecutionContextCreated({ params }) {
215
- const { context } = params;
216
- const { name, origin, auxData } = context;
217
- if (frameId !== undefined && origin === "://" && name === SINGLE_FILE_WORLD_NAME && auxData && auxData.frameId === frameId) {
218
- contextIds.push(context.id);
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 {
@@ -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.27";
1
+ export const version = "2.0.29";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-cli",
3
- "version": "2.0.27",
3
+ "version": "2.0.29",
4
4
  "description": "SingleFile CLI",
5
5
  "author": "Gildas Lormeau",
6
6
  "engines": {
@@ -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
  }