Path: blob/main/puppet-chrome/lib/NavigationLoader.ts
1028 views
import Resolvable from '@secret-agent/commons/Resolvable';1import { ILifecycleEvents, IPuppetNavigationLoader } from '@secret-agent/interfaces/IPuppetFrame';2import { IBoundLog } from '@secret-agent/interfaces/ILog';34export class NavigationLoader {5public get isNavigationComplete() {6return this.navigationResolver.isResolved;7}89public readonly lifecycle: ILifecycleEvents = {};10public navigationResolver = new Resolvable<Error | string>();11public url: string;1213private afterStoppedLoadingTimeout: NodeJS.Timeout;14private logger: IBoundLog;1516constructor(readonly id: string, logger: IBoundLog) {17this.logger = logger.createChild(module, {18loaderId: this.id,19});20}2122public setNavigationResult(result?: Error | string) {23this.navigationResolver.resolve(result ?? null);24if (result && typeof result === 'string') {25this.url = result;26}27}2829public clearStoppedLoading(): void {30clearTimeout(this.afterStoppedLoadingTimeout);31}3233public onStoppedLoading() {34clearTimeout(this.afterStoppedLoadingTimeout);3536this.afterStoppedLoadingTimeout = setTimeout(this.markLoaded.bind(this), 50).unref();37}3839public onLifecycleEvent(name: string) {40if (41(name === 'commit' || name === 'DOMContentLoaded' || name === 'load') &&42!this.isNavigationComplete43) {44this.logger.info('Resolving loader on lifecycle', { lifecycleEvent: name });45this.clearStoppedLoading();46this.setNavigationResult();47}4849this.lifecycle[name] ??= new Date();50}5152public markLoaded(): void {53if (!this.lifecycle.load) {54this.onLifecycleEvent('DOMContentLoaded');55this.onLifecycleEvent('load');56}57}5859public toJSON(): IPuppetNavigationLoader {60return {61id: this.id,62isNavigationComplete: this.isNavigationComplete,63lifecycle: this.lifecycle,64url: this.url,65};66}67}686970