1 | /**
|
2 | * @license
|
3 | * Copyright 2018 Google Inc.
|
4 | * SPDX-License-Identifier: Apache-2.0
|
5 | */
|
6 |
|
7 | import {UnsupportedOperation} from '../common/Errors.js';
|
8 | import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
9 | import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
10 | import type {EvaluateFunc, HandleFor} from '../common/types.js';
|
11 | import {withSourcePuppeteerURLIfNone} from '../common/util.js';
|
12 |
|
13 | import type {CDPSession} from './CDPSession.js';
|
14 | import type {Realm} from './Realm.js';
|
15 |
|
16 | /**
|
17 | * This class represents a
|
18 | * {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | WebWorker}.
|
19 | *
|
20 | * @remarks
|
21 | * The events `workercreated` and `workerdestroyed` are emitted on the page
|
22 | * object to signal the worker lifecycle.
|
23 | *
|
24 | * @example
|
25 | *
|
26 | * ```ts
|
27 | * page.on('workercreated', worker =>
|
28 | * console.log('Worker created: ' + worker.url()),
|
29 | * );
|
30 | * page.on('workerdestroyed', worker =>
|
31 | * console.log('Worker destroyed: ' + worker.url()),
|
32 | * );
|
33 | *
|
34 | * console.log('Current workers:');
|
35 | * for (const worker of page.workers()) {
|
36 | * console.log(' ' + worker.url());
|
37 | * }
|
38 | * ```
|
39 | *
|
40 | * @public
|
41 | */
|
42 | export abstract class WebWorker extends EventEmitter<
|
43 | Record<EventType, unknown>
|
44 | > {
|
45 | /**
|
46 | * @internal
|
47 | */
|
48 | readonly timeoutSettings = new TimeoutSettings();
|
49 |
|
50 | readonly #url: string;
|
51 |
|
52 | /**
|
53 | * @internal
|
54 | */
|
55 | constructor(url: string) {
|
56 | super();
|
57 |
|
58 | this.#url = url;
|
59 | }
|
60 |
|
61 | /**
|
62 | * @internal
|
63 | */
|
64 | abstract mainRealm(): Realm;
|
65 |
|
66 | /**
|
67 | * The URL of this web worker.
|
68 | */
|
69 | url(): string {
|
70 | return this.#url;
|
71 | }
|
72 |
|
73 | /**
|
74 | * The CDP session client the WebWorker belongs to.
|
75 | */
|
76 | abstract get client(): CDPSession;
|
77 |
|
78 | /**
|
79 | * Evaluates a given function in the {@link WebWorker | worker}.
|
80 | *
|
81 | * @remarks If the given function returns a promise,
|
82 | * {@link WebWorker.evaluate | evaluate} will wait for the promise to resolve.
|
83 | *
|
84 | * As a rule of thumb, if the return value of the given function is more
|
85 | * complicated than a JSON object (e.g. most classes), then
|
86 | * {@link WebWorker.evaluate | evaluate} will _likely_ return some truncated
|
87 | * value (or `{}`). This is because we are not returning the actual return
|
88 | * value, but a deserialized version as a result of transferring the return
|
89 | * value through a protocol to Puppeteer.
|
90 | *
|
91 | * In general, you should use
|
92 | * {@link WebWorker.evaluateHandle | evaluateHandle} if
|
93 | * {@link WebWorker.evaluate | evaluate} cannot serialize the return value
|
94 | * properly or you need a mutable {@link JSHandle | handle} to the return
|
95 | * object.
|
96 | *
|
97 | * @param func - Function to be evaluated.
|
98 | * @param args - Arguments to pass into `func`.
|
99 | * @returns The result of `func`.
|
100 | */
|
101 | async evaluate<
|
102 | Params extends unknown[],
|
103 | Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
104 | >(func: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>> {
|
105 | func = withSourcePuppeteerURLIfNone(this.evaluate.name, func);
|
106 | return await this.mainRealm().evaluate(func, ...args);
|
107 | }
|
108 |
|
109 | /**
|
110 | * Evaluates a given function in the {@link WebWorker | worker}.
|
111 | *
|
112 | * @remarks If the given function returns a promise,
|
113 | * {@link WebWorker.evaluate | evaluate} will wait for the promise to resolve.
|
114 | *
|
115 | * In general, you should use
|
116 | * {@link WebWorker.evaluateHandle | evaluateHandle} if
|
117 | * {@link WebWorker.evaluate | evaluate} cannot serialize the return value
|
118 | * properly or you need a mutable {@link JSHandle | handle} to the return
|
119 | * object.
|
120 | *
|
121 | * @param func - Function to be evaluated.
|
122 | * @param args - Arguments to pass into `func`.
|
123 | * @returns A {@link JSHandle | handle} to the return value of `func`.
|
124 | */
|
125 | async evaluateHandle<
|
126 | Params extends unknown[],
|
127 | Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
128 | >(
|
129 | func: Func | string,
|
130 | ...args: Params
|
131 | ): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
132 | func = withSourcePuppeteerURLIfNone(this.evaluateHandle.name, func);
|
133 | return await this.mainRealm().evaluateHandle(func, ...args);
|
134 | }
|
135 |
|
136 | async close(): Promise<void> {
|
137 | throw new UnsupportedOperation('WebWorker.close() is not supported');
|
138 | }
|
139 | }
|