@tstdl/base 0.83.28 → 0.84.1

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.
Files changed (43) hide show
  1. package/application/application.d.ts +1 -1
  2. package/application/application.js +3 -3
  3. package/browser/browser-context-controller.d.ts +32 -0
  4. package/browser/browser-context-controller.js +88 -0
  5. package/browser/browser-controller.d.ts +30 -11
  6. package/browser/browser-controller.js +40 -30
  7. package/browser/browser.service.d.ts +9 -7
  8. package/browser/browser.service.js +31 -34
  9. package/browser/index.d.ts +1 -1
  10. package/browser/index.js +1 -1
  11. package/browser/page-controller.d.ts +33 -35
  12. package/browser/page-controller.js +58 -81
  13. package/browser/pdf-options.d.ts +5 -1
  14. package/browser/pdf-options.js +9 -5
  15. package/browser/utils.d.ts +6 -0
  16. package/browser/utils.js +60 -0
  17. package/data-structures/cache.d.ts +11 -0
  18. package/data-structures/cache.js +69 -0
  19. package/data-structures/index.d.ts +1 -0
  20. package/data-structures/index.js +1 -0
  21. package/disposable/async-disposer.d.ts +2 -1
  22. package/error/index.d.ts +1 -0
  23. package/error/index.js +1 -0
  24. package/error/timeout.error.d.ts +5 -0
  25. package/{browser/types.js → error/timeout.error.js} +16 -2
  26. package/examples/browser/basic.js +2 -2
  27. package/examples/pdf/basic.js +10 -6
  28. package/http/client/adapters/undici-http-client.adapter.js +1 -1
  29. package/http/client/http-client-request.js +1 -1
  30. package/http/server/node/node-http-server.js +1 -1
  31. package/lock/web/web-lock.js +2 -2
  32. package/package.json +8 -6
  33. package/pdf/pdf.service.d.ts +15 -21
  34. package/pdf/pdf.service.js +23 -62
  35. package/pool/pool.d.ts +1 -0
  36. package/pool/pool.js +3 -0
  37. package/queue/mongo/queue.js +2 -2
  38. package/types.d.ts +2 -2
  39. package/utils/cancellation-token.d.ts +11 -16
  40. package/utils/cancellation-token.js +10 -39
  41. package/utils/timing.d.ts +7 -1
  42. package/utils/timing.js +23 -3
  43. package/browser/types.d.ts +0 -3
@@ -11,7 +11,7 @@ export declare class Application {
11
11
  private readonly moduleInstances;
12
12
  private readonly shutdownPromise;
13
13
  private readonly _shutdownToken;
14
- readonly shutdownToken: ReadonlyCancellationToken;
14
+ get shutdownToken(): ReadonlyCancellationToken;
15
15
  static get shutdownToken(): ReadonlyCancellationToken;
16
16
  constructor(logger: Logger);
17
17
  static registerModule(moduleType: Type<Module>): void;
@@ -59,7 +59,6 @@ let Application = Application_1 = class Application2 {
59
59
  if ((0, import_type_guards.isUndefined)(this._instance)) {
60
60
  this._instance = import_container.container.resolve(Application_1);
61
61
  this._instance._shutdownToken = import_process_shutdown.shutdownToken;
62
- this._instance.shutdownToken = import_process_shutdown.shutdownToken.asReadonly;
63
62
  }
64
63
  return this._instance;
65
64
  }
@@ -68,7 +67,9 @@ let Application = Application_1 = class Application2 {
68
67
  moduleInstances;
69
68
  shutdownPromise;
70
69
  _shutdownToken;
71
- shutdownToken;
70
+ get shutdownToken() {
71
+ return this._shutdownToken.asReadonly();
72
+ }
72
73
  static get shutdownToken() {
73
74
  return Application_1.instance.shutdownToken;
74
75
  }
@@ -78,7 +79,6 @@ let Application = Application_1 = class Application2 {
78
79
  this.moduleInstances = /* @__PURE__ */ new Set();
79
80
  this.shutdownPromise = new import_deferred_promise.DeferredPromise();
80
81
  this._shutdownToken = import_process_shutdown.shutdownToken.createChild();
81
- this.shutdownToken = this._shutdownToken.asReadonly;
82
82
  }
83
83
  static registerModule(moduleType) {
84
84
  Application_1.instance.registerModule(moduleType);
@@ -0,0 +1,32 @@
1
+ import type { BrowserContext } from 'playwright';
2
+ import type { Injectable } from '../container/interfaces.js';
3
+ import { resolveArgumentType } from '../container/interfaces.js';
4
+ import type { AsyncDisposable } from '../disposable/disposable.js';
5
+ import { disposeAsync } from '../disposable/disposable.js';
6
+ import type { Json } from '../types.js';
7
+ import type { Opaque } from 'type-fest';
8
+ import type { NewBrowserContextOptions } from './browser-controller.js';
9
+ import type { PageControllerOptions } from './page-controller.js';
10
+ import { PageController } from './page-controller.js';
11
+ export type BrowserContextControllerOptions = {
12
+ defaultNewPageOptions?: NewPageOptions;
13
+ };
14
+ export type NewPageOptions = {
15
+ extraHttpHeaders?: Record<string, string>;
16
+ controllerOptions?: PageControllerOptions;
17
+ };
18
+ export type BrowserContextState = Opaque<Json, 'BrowserContextState'>;
19
+ export type BrowserContextControllerArgument = NewBrowserContextOptions;
20
+ export declare class BrowserContextController implements AsyncDisposable, Injectable<BrowserContextControllerArgument> {
21
+ private readonly options;
22
+ /** @deprecated should be avoided */
23
+ readonly context: BrowserContext;
24
+ readonly [resolveArgumentType]: BrowserContextControllerArgument;
25
+ constructor(context: BrowserContext, options?: BrowserContextControllerOptions);
26
+ [disposeAsync](): Promise<void>;
27
+ close(): Promise<void>;
28
+ getState(): Promise<BrowserContextState>;
29
+ setExtraHttpHeaders(headers: Record<string, string>): Promise<void>;
30
+ newPage(options?: NewPageOptions): Promise<PageController>;
31
+ waitForClose(): Promise<void>;
32
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var browser_context_controller_exports = {};
20
+ __export(browser_context_controller_exports, {
21
+ BrowserContextController: () => BrowserContextController
22
+ });
23
+ module.exports = __toCommonJS(browser_context_controller_exports);
24
+ var import_decorators = require("../container/decorators.js");
25
+ var import_interfaces = require("../container/interfaces.js");
26
+ var import_disposable = require("../disposable/disposable.js");
27
+ var import_type_guards = require("../utils/type-guards.js");
28
+ var import_browser_controller = require("./browser-controller.js");
29
+ var import_page_controller = require("./page-controller.js");
30
+ var __decorate = function(decorators, target, key, desc) {
31
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
32
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
33
+ r = Reflect.decorate(decorators, target, key, desc);
34
+ else
35
+ for (var i = decorators.length - 1; i >= 0; i--)
36
+ if (d = decorators[i])
37
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
38
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
39
+ };
40
+ var __metadata = function(k, v) {
41
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
42
+ return Reflect.metadata(k, v);
43
+ };
44
+ let BrowserContextController = class BrowserContextController2 {
45
+ options;
46
+ /** @deprecated should be avoided */
47
+ context;
48
+ constructor(context, options = {}) {
49
+ this.context = context;
50
+ this.options = options;
51
+ }
52
+ async [import_disposable.disposeAsync]() {
53
+ await this.close();
54
+ }
55
+ async close() {
56
+ await this.context.close();
57
+ }
58
+ async getState() {
59
+ const state = await this.context.storageState();
60
+ return state;
61
+ }
62
+ async setExtraHttpHeaders(headers) {
63
+ await this.context.setExtraHTTPHeaders(headers);
64
+ }
65
+ async newPage(options) {
66
+ const page = await this.context.newPage();
67
+ const mergedOptions = { ...this.options.defaultNewPageOptions, ...options };
68
+ const controller = new import_page_controller.PageController(page, mergedOptions.controllerOptions);
69
+ if ((0, import_type_guards.isDefined)(mergedOptions.extraHttpHeaders)) {
70
+ await controller.setExtraHttpHeaders(mergedOptions.extraHttpHeaders);
71
+ }
72
+ return controller;
73
+ }
74
+ async waitForClose() {
75
+ return new Promise((resolve) => this.context.once("close", () => resolve()));
76
+ }
77
+ };
78
+ BrowserContextController = __decorate([
79
+ (0, import_decorators.injectable)({
80
+ provider: {
81
+ useFactory: async (argument, context) => {
82
+ const browserController = await context.resolveAsync(import_browser_controller.BrowserController);
83
+ return browserController.newContext(argument);
84
+ }
85
+ }
86
+ }),
87
+ __metadata("design:paramtypes", [Object, Object])
88
+ ], BrowserContextController);
@@ -1,26 +1,45 @@
1
+ import type { Browser } from 'playwright';
1
2
  import type { Injectable } from '../container/interfaces.js';
2
3
  import { resolveArgumentType } from '../container/interfaces.js';
3
4
  import type { AsyncDisposable } from '../disposable/disposable.js';
4
5
  import { disposeAsync } from '../disposable/disposable.js';
5
- import * as puppeteer from 'puppeteer';
6
+ import type { BrowserContextControllerOptions, BrowserContextState, NewPageOptions } from './browser-context-controller.js';
7
+ import { BrowserContextController } from './browser-context-controller.js';
6
8
  import type { NewBrowserOptions } from './browser.service.js';
7
- import type { PageControllerOptions } from './page-controller.js';
8
- import { PageController } from './page-controller.js';
9
+ import type { PageController } from './page-controller.js';
9
10
  export type BrowserControllerOptions = {
10
- defaultNewPageOptions?: NewPageOptions;
11
+ defaultNewContextOptions?: NewBrowserContextOptions;
11
12
  };
12
- export type NewPageOptions = {
13
+ export type NewBrowserContextOptions = {
14
+ state?: BrowserContextState;
15
+ locale?: string;
13
16
  extraHttpHeaders?: Record<string, string>;
14
- controllerOptions?: PageControllerOptions;
17
+ controllerOptions?: BrowserContextControllerOptions;
18
+ viewport?: {
19
+ width: number;
20
+ height: number;
21
+ } | null;
22
+ proxy?: {
23
+ server: string;
24
+ bypass?: string;
25
+ username?: string;
26
+ password?: string;
27
+ };
15
28
  };
16
- export declare class BrowserController implements AsyncDisposable, Injectable<NewBrowserOptions> {
29
+ export type BrowserControllerArgument = NewBrowserOptions;
30
+ export declare class BrowserController implements AsyncDisposable, Injectable<BrowserControllerArgument> {
17
31
  /** @deprecated should be avoided */
18
- readonly browser: puppeteer.Browser;
32
+ readonly browser: Browser;
19
33
  readonly options: BrowserControllerOptions | undefined;
20
- readonly [resolveArgumentType]: NewBrowserOptions;
21
- constructor(browser: puppeteer.Browser, options?: BrowserControllerOptions);
34
+ readonly [resolveArgumentType]: BrowserControllerArgument;
35
+ constructor(browser: Browser, options?: BrowserControllerOptions);
22
36
  [disposeAsync](): Promise<void>;
37
+ newContext(options?: NewBrowserContextOptions): Promise<BrowserContextController>;
38
+ /**
39
+ * Creates a new context and a new page. Context is automatically closed on page close.
40
+ * Only use for isolated or "use once" scenarios, otherwise all the contexts are more expensive than using a single context.
41
+ */
42
+ newPage(options?: NewBrowserContextOptions & NewPageOptions): Promise<PageController>;
23
43
  close(): Promise<void>;
24
- newPage(options?: NewPageOptions): Promise<PageController>;
25
44
  waitForClose(): Promise<void>;
26
45
  }
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var browser_controller_exports = {};
30
20
  __export(browser_controller_exports, {
@@ -34,11 +24,9 @@ module.exports = __toCommonJS(browser_controller_exports);
34
24
  var import_decorators = require("../container/decorators.js");
35
25
  var import_interfaces = require("../container/interfaces.js");
36
26
  var import_disposable = require("../disposable/disposable.js");
37
- var import_object = require("../utils/object/object.js");
38
- var import_type_guards = require("../utils/type-guards.js");
39
- var puppeteer = __toESM(require("puppeteer"), 1);
27
+ var import_browser_context_controller = require("./browser-context-controller.js");
40
28
  var import_browser_service = require("./browser.service.js");
41
- var import_page_controller = require("./page-controller.js");
29
+ var import_utils = require("./utils.js");
42
30
  var __decorate = function(decorators, target, key, desc) {
43
31
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
44
32
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -62,28 +50,50 @@ let BrowserController = class BrowserController2 {
62
50
  this.options = options;
63
51
  }
64
52
  async [import_disposable.disposeAsync]() {
65
- return this.close();
53
+ await this.close();
54
+ }
55
+ async newContext(options) {
56
+ const mergedOptions = (0, import_utils.mergeNewBrowserContextOptions)(this.options?.defaultNewContextOptions, options);
57
+ const context = await this.browser.newContext({
58
+ storageState: mergedOptions.state,
59
+ locale: mergedOptions.locale,
60
+ viewport: mergedOptions.viewport,
61
+ proxy: mergedOptions.proxy,
62
+ extraHTTPHeaders: mergedOptions.extraHttpHeaders
63
+ });
64
+ return new import_browser_context_controller.BrowserContextController(context, mergedOptions.controllerOptions);
65
+ }
66
+ /**
67
+ * Creates a new context and a new page. Context is automatically closed on page close.
68
+ * Only use for isolated or "use once" scenarios, otherwise all the contexts are more expensive than using a single context.
69
+ */
70
+ async newPage(options) {
71
+ const context = await this.newContext(options);
72
+ try {
73
+ const page = await context.newPage(options);
74
+ page.ownedContext = context;
75
+ return page;
76
+ } catch (error) {
77
+ await context.close();
78
+ throw error;
79
+ }
66
80
  }
67
81
  async close() {
68
82
  if (this.browser.isConnected()) {
83
+ for (const context of this.browser.contexts()) {
84
+ await context.close();
85
+ }
69
86
  await this.browser.close();
70
87
  }
71
88
  }
72
- async newPage(options) {
73
- const mergedExtraHttpHeaderEntries = [...(0, import_object.objectEntries)(options?.extraHttpHeaders ?? {}), ...(0, import_object.objectEntries)(this.options?.defaultNewPageOptions?.extraHttpHeaders ?? {})];
74
- const newPageOptions = {
75
- controllerOptions: options?.controllerOptions ?? this.options?.defaultNewPageOptions?.controllerOptions,
76
- extraHttpHeaders: mergedExtraHttpHeaderEntries.length > 0 ? (0, import_object.fromEntries)(mergedExtraHttpHeaderEntries) : void 0
77
- };
78
- const page = await this.browser.newPage();
79
- const controller = new import_page_controller.PageController(page, newPageOptions.controllerOptions);
80
- if ((0, import_type_guards.isDefined)(newPageOptions.extraHttpHeaders)) {
81
- await controller.setExtraHttpHeaders(newPageOptions.extraHttpHeaders);
82
- }
83
- return controller;
84
- }
85
89
  async waitForClose() {
86
- return new Promise((resolve) => this.browser.once("disconnected", resolve));
90
+ return new Promise((resolve) => {
91
+ if (!this.browser.isConnected()) {
92
+ resolve();
93
+ } else {
94
+ this.browser.once("disconnected", () => resolve());
95
+ }
96
+ });
87
97
  }
88
98
  };
89
99
  BrowserController = __decorate([
@@ -95,5 +105,5 @@ BrowserController = __decorate([
95
105
  }
96
106
  }
97
107
  }),
98
- __metadata("design:paramtypes", [puppeteer.Browser, Object])
108
+ __metadata("design:paramtypes", [Object, Object])
99
109
  ], BrowserController);
@@ -2,31 +2,33 @@ import type { Injectable } from '../container/interfaces.js';
2
2
  import { afterResolve, resolveArgumentType } from '../container/interfaces.js';
3
3
  import type { AsyncDisposable } from '../disposable/disposable.js';
4
4
  import { disposeAsync } from '../disposable/disposable.js';
5
- import type { BrowserControllerOptions } from './browser-controller.js';
5
+ import { BrowserContextController } from './browser-context-controller.js';
6
+ import type { BrowserControllerOptions, NewBrowserContextOptions } from './browser-controller.js';
6
7
  import { BrowserController } from './browser-controller.js';
7
8
  export declare class BrowserServiceOptions {
8
9
  defaultNewBrowserOptions?: NewBrowserOptions;
9
10
  }
10
11
  export type BrowserServiceArgument = BrowserServiceOptions;
11
12
  export type NewBrowserOptions = {
13
+ browser?: 'chromium' | 'firefox' | 'webkit';
12
14
  headless?: boolean;
13
- width?: number;
14
- height?: number;
15
- language?: string;
16
- proxy?: string;
15
+ windowSize?: {
16
+ width: number;
17
+ height: number;
18
+ };
17
19
  /** @deprecated should be avoided */
18
20
  browserArguments?: string[];
19
- /** @deprecated should be avoided */
20
- browserEnvironment?: Record<string, string | undefined>;
21
21
  controllerOptions?: BrowserControllerOptions;
22
22
  };
23
23
  export declare class BrowserService implements AsyncDisposable, Injectable<BrowserServiceArgument> {
24
24
  private readonly browsers;
25
+ private readonly persistentBrowserContexts;
25
26
  readonly options: BrowserServiceOptions | undefined;
26
27
  readonly [resolveArgumentType]: BrowserServiceArgument;
27
28
  constructor(options?: BrowserServiceOptions);
28
29
  [afterResolve](): void;
29
30
  [disposeAsync](): Promise<void>;
30
31
  newBrowser(options?: NewBrowserOptions): Promise<BrowserController>;
32
+ newPersistentContext(dataDirectory: string, browserOptions?: NewBrowserOptions, contextOptions?: NewBrowserContextOptions): Promise<BrowserContextController>;
31
33
  dispose(): Promise<void>;
32
34
  }
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var browser_service_exports = {};
30
20
  __export(browser_service_exports, {
@@ -36,9 +26,9 @@ var import_decorators = require("../container/decorators.js");
36
26
  var import_interfaces = require("../container/interfaces.js");
37
27
  var import_core = require("../core.js");
38
28
  var import_disposable = require("../disposable/disposable.js");
39
- var import_type_guards = require("../utils/type-guards.js");
40
- var puppeteer = __toESM(require("puppeteer"), 1);
29
+ var import_browser_context_controller = require("./browser-context-controller.js");
41
30
  var import_browser_controller = require("./browser-controller.js");
31
+ var import_utils = require("./utils.js");
42
32
  var __decorate = function(decorators, target, key, desc) {
43
33
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
44
34
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -63,10 +53,12 @@ class BrowserServiceOptions {
63
53
  }
64
54
  let BrowserService = class BrowserService2 {
65
55
  browsers;
56
+ persistentBrowserContexts;
66
57
  options;
67
58
  constructor(options) {
68
59
  this.options = options;
69
- this.browsers = [];
60
+ this.browsers = /* @__PURE__ */ new Set();
61
+ this.persistentBrowserContexts = /* @__PURE__ */ new Set();
70
62
  }
71
63
  [import_interfaces.afterResolve]() {
72
64
  import_core.disposer.add(this);
@@ -74,33 +66,38 @@ let BrowserService = class BrowserService2 {
74
66
  async [import_disposable.disposeAsync]() {
75
67
  return this.dispose();
76
68
  }
77
- async newBrowser(options) {
78
- const { width = 1e3, height = 1e3, browserArguments, browserEnvironment, proxy, language, headless, controllerOptions } = { ...this.options?.defaultNewBrowserOptions, ...options };
79
- const args = [`--window-size=${width},${height}`, ...browserArguments ?? []];
80
- const env = { ...process.env, ...browserEnvironment };
81
- if ((0, import_type_guards.isDefined)(proxy)) {
82
- args.push(`--proxy-server=${proxy}`);
83
- }
84
- if ((0, import_type_guards.isDefined)(language)) {
85
- args.push(`--lang=${language}`);
86
- env["LANGUAGE"] = language;
87
- }
88
- const browser = await puppeteer.launch({
89
- headless: headless == true ? "new" : false,
90
- args,
91
- env,
92
- defaultViewport: { width, height }
69
+ async newBrowser(options = {}) {
70
+ const mergedOptions = { ...this.options?.defaultNewBrowserOptions, ...options };
71
+ const launchOptions = (0, import_utils.getLaunchOptions)(mergedOptions);
72
+ const browser = await (0, import_utils.getBrowserType)(mergedOptions.browser).launch(launchOptions);
73
+ this.browsers.add(browser);
74
+ browser.once("disconnected", () => this.browsers.delete(browser));
75
+ return new import_browser_controller.BrowserController(browser, mergedOptions.controllerOptions);
76
+ }
77
+ async newPersistentContext(dataDirectory, browserOptions = {}, contextOptions = {}) {
78
+ const mergedBrowserOptions = { ...this.options?.defaultNewBrowserOptions, ...browserOptions };
79
+ const mergedContextOptions = (0, import_utils.mergeNewBrowserContextOptions)(this.options?.defaultNewBrowserOptions?.controllerOptions?.defaultNewContextOptions, browserOptions.controllerOptions?.defaultNewContextOptions, contextOptions);
80
+ const launchOptions = (0, import_utils.getLaunchOptions)(mergedBrowserOptions);
81
+ const context = await (0, import_utils.getBrowserType)(mergedBrowserOptions.browser).launchPersistentContext(dataDirectory, {
82
+ ...launchOptions,
83
+ locale: mergedContextOptions.locale,
84
+ viewport: mergedContextOptions.viewport,
85
+ proxy: mergedContextOptions.proxy,
86
+ extraHTTPHeaders: mergedContextOptions.extraHttpHeaders
93
87
  });
94
- this.browsers.push(new WeakRef(browser));
95
- return new import_browser_controller.BrowserController(browser, controllerOptions);
88
+ this.persistentBrowserContexts.add(context);
89
+ context.once("close", () => this.persistentBrowserContexts.delete(context));
90
+ return new import_browser_context_controller.BrowserContextController(context, mergedBrowserOptions.controllerOptions?.defaultNewContextOptions?.controllerOptions);
96
91
  }
97
92
  async dispose() {
98
- for (const browserRef of this.browsers) {
99
- const browser = browserRef.deref();
100
- if ((0, import_type_guards.isDefined)(browser) && browser.isConnected()) {
93
+ for (const browser of this.browsers) {
94
+ if (browser.isConnected()) {
101
95
  await browser.close();
102
96
  }
103
97
  }
98
+ for (const context of this.persistentBrowserContexts) {
99
+ await context.close();
100
+ }
104
101
  }
105
102
  };
106
103
  BrowserService = __decorate([
@@ -1,4 +1,4 @@
1
+ export * from './browser-context-controller.js';
1
2
  export * from './browser-controller.js';
2
3
  export * from './browser.service.js';
3
4
  export * from './page-controller.js';
4
- export * from './types.js';
package/browser/index.js CHANGED
@@ -15,7 +15,7 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
15
15
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
16
  var browser_exports = {};
17
17
  module.exports = __toCommonJS(browser_exports);
18
+ __reExport(browser_exports, require("./browser-context-controller.js"), module.exports);
18
19
  __reExport(browser_exports, require("./browser-controller.js"), module.exports);
19
20
  __reExport(browser_exports, require("./browser.service.js"), module.exports);
20
21
  __reExport(browser_exports, require("./page-controller.js"), module.exports);
21
- __reExport(browser_exports, require("./types.js"), module.exports);
@@ -1,7 +1,7 @@
1
- import * as puppeteer from 'puppeteer';
1
+ import type { Page } from 'playwright';
2
2
  import type { AsyncDisposable } from '../disposable/disposable.js';
3
3
  import { disposeAsync } from '../disposable/disposable.js';
4
- import type { WritableOneOrMany } from '../types.js';
4
+ import type { BrowserContextController } from './browser-context-controller.js';
5
5
  import type { PdfRenderOptions } from './pdf-options.js';
6
6
  export type Delay = number | DelayProvider;
7
7
  export type DelayProvider = () => number;
@@ -9,48 +9,46 @@ export type PageControllerOptions = {
9
9
  actionDelay?: Delay;
10
10
  typeDelay?: Delay;
11
11
  };
12
- export type SelectorOptions = {
13
- xpath?: boolean;
14
- };
15
- export type WaitForElementOptions = {
12
+ export type WaitOptions = {
16
13
  timeout?: number;
17
14
  };
18
- export type PageLifecycleEvent = puppeteer.PuppeteerLifeCycleEvent;
19
- export type WaitForOptions = {
20
- timeout?: number;
21
- waitUntil?: WritableOneOrMany<PageLifecycleEvent>;
15
+ export type LoadState = 'load' | 'domcontentloaded' | 'networkidle';
16
+ export type WaitForStateOptions = {
17
+ waitUntil: LoadState;
18
+ };
19
+ export type DelayOptions = {
20
+ delay?: Delay;
21
+ };
22
+ export type Abortable = {
23
+ abort?: AbortSignal;
24
+ };
25
+ /** @deprecated for internal use only */
26
+ export type PageControllerInternal = {
27
+ ownedContext?: BrowserContextController;
22
28
  };
23
29
  export declare class PageController implements AsyncDisposable {
30
+ private readonly ownedContext?;
24
31
  /** @deprecated should be avoided */
25
- readonly page: puppeteer.Page;
32
+ readonly page: Page;
26
33
  readonly options: PageControllerOptions;
27
- constructor(pageOrFrame: puppeteer.Page | puppeteer.Frame, options?: PageControllerOptions);
34
+ constructor(page: Page, options?: PageControllerOptions);
28
35
  [disposeAsync](): Promise<void>;
29
36
  close(): Promise<void>;
30
- setContent(html: string, options?: WaitForOptions): Promise<void>;
37
+ setContent(html: string, options?: WaitOptions & WaitForStateOptions): Promise<void>;
31
38
  setExtraHttpHeaders(headers: Record<string, string>): Promise<void>;
32
- authenticate(username: string, password: string): Promise<void>;
33
- navigate(url: string, options?: WaitForOptions): Promise<void>;
39
+ navigate(url: string, options?: WaitOptions & WaitForStateOptions): Promise<void>;
34
40
  waitForClose(): Promise<void>;
35
- waitForIdle(options?: {
36
- idleTime?: number;
37
- timeout?: number;
38
- }): Promise<void>;
39
- waitForUrl(urlOrPredicate: string | ((url: string) => boolean | Promise<boolean>), options?: {
40
- timeout?: number;
41
- }): Promise<void>;
42
- waitForFrame(selector: string, options?: SelectorOptions): Promise<PageController>;
43
- waitForFrameByUrl(urlOrPredicate: string | ((frame: puppeteer.Frame) => boolean | Promise<boolean>), options?: {
44
- timeout?: number;
45
- }): Promise<PageController>;
46
- getDeepestFrame(): PageController;
47
- type(handleOrSelector: puppeteer.ElementHandle | string, text: string, options?: SelectorOptions): Promise<void>;
48
- select(handleOrSelector: puppeteer.ElementHandle | string, value: string, options?: SelectorOptions): Promise<void>;
49
- click(handleOrSelector: puppeteer.ElementHandle | string, options?: SelectorOptions): Promise<void>;
50
- getValue(handleOrSelector: puppeteer.ElementHandle | string, options?: SelectorOptions): Promise<string>;
51
- waitForElement(selector: string, options?: WaitForElementOptions & SelectorOptions): Promise<void>;
52
- renderPdf(options?: PdfRenderOptions): Promise<Uint8Array>;
53
- renderPdfStream(options?: PdfRenderOptions): ReadableStream<Uint8Array>;
54
- private waitForElementHandle;
41
+ waitForState(state: LoadState, options?: WaitOptions): Promise<void>;
42
+ waitForNetworkIdle(options?: WaitOptions): Promise<void>;
43
+ waitForUrl(urlOrPredicate: string | RegExp | ((url: URL) => boolean), options?: WaitOptions): Promise<void>;
44
+ waitForFrame(selector: string, options?: WaitOptions): Promise<PageController>;
45
+ fill(selector: string, text: string, options?: DelayOptions & WaitOptions): Promise<void>;
46
+ type(selector: string, text: string, options?: DelayOptions & WaitOptions): Promise<void>;
47
+ selectOption(selector: string, value: string | string[], options?: WaitOptions): Promise<void>;
48
+ click(selector: string, options?: WaitOptions): Promise<void>;
49
+ getValue(selector: string, options?: WaitOptions): Promise<string>;
50
+ waitForElement(selector: string, options?: WaitOptions): Promise<void>;
51
+ renderPdf(options?: PdfRenderOptions & Abortable): Promise<Uint8Array>;
52
+ renderPdfStream(options?: PdfRenderOptions & Abortable): ReadableStream<Uint8Array>;
55
53
  private prepareAction;
56
54
  }