Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/puppet-chrome/lib/NavigationLoader.ts
1028 views
1
import Resolvable from '@secret-agent/commons/Resolvable';
2
import { ILifecycleEvents, IPuppetNavigationLoader } from '@secret-agent/interfaces/IPuppetFrame';
3
import { IBoundLog } from '@secret-agent/interfaces/ILog';
4
5
export class NavigationLoader {
6
public get isNavigationComplete() {
7
return this.navigationResolver.isResolved;
8
}
9
10
public readonly lifecycle: ILifecycleEvents = {};
11
public navigationResolver = new Resolvable<Error | string>();
12
public url: string;
13
14
private afterStoppedLoadingTimeout: NodeJS.Timeout;
15
private logger: IBoundLog;
16
17
constructor(readonly id: string, logger: IBoundLog) {
18
this.logger = logger.createChild(module, {
19
loaderId: this.id,
20
});
21
}
22
23
public setNavigationResult(result?: Error | string) {
24
this.navigationResolver.resolve(result ?? null);
25
if (result && typeof result === 'string') {
26
this.url = result;
27
}
28
}
29
30
public clearStoppedLoading(): void {
31
clearTimeout(this.afterStoppedLoadingTimeout);
32
}
33
34
public onStoppedLoading() {
35
clearTimeout(this.afterStoppedLoadingTimeout);
36
37
this.afterStoppedLoadingTimeout = setTimeout(this.markLoaded.bind(this), 50).unref();
38
}
39
40
public onLifecycleEvent(name: string) {
41
if (
42
(name === 'commit' || name === 'DOMContentLoaded' || name === 'load') &&
43
!this.isNavigationComplete
44
) {
45
this.logger.info('Resolving loader on lifecycle', { lifecycleEvent: name });
46
this.clearStoppedLoading();
47
this.setNavigationResult();
48
}
49
50
this.lifecycle[name] ??= new Date();
51
}
52
53
public markLoaded(): void {
54
if (!this.lifecycle.load) {
55
this.onLifecycleEvent('DOMContentLoaded');
56
this.onLifecycleEvent('load');
57
}
58
}
59
60
public toJSON(): IPuppetNavigationLoader {
61
return {
62
id: this.id,
63
isNavigationComplete: this.isNavigationComplete,
64
lifecycle: this.lifecycle,
65
url: this.url,
66
};
67
}
68
}
69
70