Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/puppet-chrome/lib/Connection.ts
1028 views
1
/**
2
* Copyright 2018 Google Inc. All rights reserved.
3
* Modifications copyright (c) Data Liberation Foundation Inc.
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*/
17
import { TypedEventEmitter } from '@secret-agent/commons/eventUtils';
18
import IConnectionTransport from '@secret-agent/interfaces/IConnectionTransport';
19
import Log from '@secret-agent/commons/Logger';
20
import { DevtoolsSession } from './DevtoolsSession';
21
22
const { log } = Log(module);
23
24
export class Connection extends TypedEventEmitter<{ disconnected: void }> {
25
public readonly rootSession: DevtoolsSession;
26
public isClosed = false;
27
28
private lastId = 0;
29
private sessionsById = new Map<string, DevtoolsSession>();
30
31
constructor(readonly transport: IConnectionTransport) {
32
super();
33
34
transport.onMessageFn = this.onMessage.bind(this);
35
transport.onCloseFns.push(this.onClosed);
36
37
this.rootSession = new DevtoolsSession(this, 'browser', '');
38
this.sessionsById.set('', this.rootSession);
39
}
40
41
public sendMessage(message: object): number {
42
this.lastId += 1;
43
const id = this.lastId;
44
this.transport.send(JSON.stringify({ ...message, id }));
45
return id;
46
}
47
48
public getSession(sessionId: string): DevtoolsSession | undefined {
49
return this.sessionsById.get(sessionId);
50
}
51
52
public dispose(): void {
53
this.onClosed();
54
this.transport.close();
55
}
56
57
private onMessage(message: string): void {
58
const timestamp = new Date();
59
const object = JSON.parse(message);
60
object.timestamp = timestamp;
61
const devtoolsSessionId = object.params?.sessionId;
62
63
if (object.method === 'Target.attachedToTarget') {
64
const session = new DevtoolsSession(this, object.params.targetInfo.type, devtoolsSessionId);
65
this.sessionsById.set(devtoolsSessionId, session);
66
}
67
if (object.method === 'Target.detachedFromTarget') {
68
const session = this.sessionsById.get(devtoolsSessionId);
69
if (session) {
70
session.onClosed();
71
this.sessionsById.delete(devtoolsSessionId);
72
}
73
}
74
75
const devtoolsSession = this.sessionsById.get(object.sessionId || '');
76
if (devtoolsSession) {
77
devtoolsSession.onMessage(object);
78
} else {
79
log.warn('MessageWithUnknownSession', { sessionId: null, message: object });
80
}
81
}
82
83
private onClosed(): void {
84
if (this.isClosed) return;
85
this.isClosed = true;
86
for (const [id, session] of this.sessionsById) {
87
session.onClosed();
88
this.sessionsById.delete(id);
89
}
90
this.transport.onMessageFn = null;
91
this.emit('disconnected');
92
}
93
}
94
95