lynkeus-client 0.3.0 → 0.5.0
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.
- package/lib/index.js +14 -1
- package/package.json +2 -2
- package/src/index.ts +13 -1
package/lib/index.js
CHANGED
|
@@ -15,6 +15,8 @@ export class AgentServer extends EventEmitter {
|
|
|
15
15
|
port;
|
|
16
16
|
host;
|
|
17
17
|
#token;
|
|
18
|
+
/** An app connected and stayed silent after the auth: the sign of a token that does not match. */
|
|
19
|
+
#unanswered = false;
|
|
18
20
|
#session = Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
19
21
|
#server = null;
|
|
20
22
|
#socket = null;
|
|
@@ -69,7 +71,11 @@ export class AgentServer extends EventEmitter {
|
|
|
69
71
|
return new Promise((resolve, reject) => {
|
|
70
72
|
const timer = setTimeout(() => {
|
|
71
73
|
this.off('hello', onHello);
|
|
72
|
-
|
|
74
|
+
// An app that dials in and never says hello is one whose token is not ours: the agent stays silent then.
|
|
75
|
+
const why = this.#unanswered
|
|
76
|
+
? ' An app connected but did not answer: its token is not this one. Start Metro with the LYNKEUS_TOKEN this driver has (.lynkeus/token or the environment), with --reset-cache.'
|
|
77
|
+
: ' Is a dev build running with <Lynkeus>?';
|
|
78
|
+
reject(new AgentError(`No app attached on ${this.host}:${this.port} within ${timeoutMs}ms.${why}`));
|
|
73
79
|
}, timeoutMs);
|
|
74
80
|
const onHello = (hello) => {
|
|
75
81
|
clearTimeout(timer);
|
|
@@ -114,6 +120,11 @@ export class AgentServer extends EventEmitter {
|
|
|
114
120
|
this.#hello = null;
|
|
115
121
|
this.#cancelGrace();
|
|
116
122
|
socket.send(JSON.stringify({ event: 'auth', session: this.#session, token: this.#token }));
|
|
123
|
+
const silence = setTimeout(() => {
|
|
124
|
+
if (this.#socket === socket && !this.#hello && socket.readyState === WebSocket.OPEN)
|
|
125
|
+
this.#unanswered = true;
|
|
126
|
+
}, 2000);
|
|
127
|
+
socket.once('close', () => clearTimeout(silence));
|
|
117
128
|
socket.on('message', (data) => {
|
|
118
129
|
let message;
|
|
119
130
|
try {
|
|
@@ -125,6 +136,8 @@ export class AgentServer extends EventEmitter {
|
|
|
125
136
|
if ('event' in message) {
|
|
126
137
|
if (message.event === 'hello') {
|
|
127
138
|
this.#hello = message;
|
|
139
|
+
this.#unanswered = false;
|
|
140
|
+
clearTimeout(silence);
|
|
128
141
|
// Resend what the previous socket may have dropped, but only once this one has spoken the
|
|
129
142
|
// protocol: a bare local connection could be any process.
|
|
130
143
|
if (socket.readyState === WebSocket.OPEN) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lynkeus-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Node driver for apps running lynkeus-agent: attach, read the screen, press, type, wait.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"node": ">=22"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"lynkeus-protocol": "^0.
|
|
34
|
+
"lynkeus-protocol": "^0.5.0",
|
|
35
35
|
"ws": "^8.18.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -39,6 +39,8 @@ export class AgentServer extends EventEmitter {
|
|
|
39
39
|
readonly host: string;
|
|
40
40
|
|
|
41
41
|
#token?: string;
|
|
42
|
+
/** An app connected and stayed silent after the auth: the sign of a token that does not match. */
|
|
43
|
+
#unanswered = false;
|
|
42
44
|
#session = Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
43
45
|
#server: WebSocketServer | null = null;
|
|
44
46
|
#socket: WebSocket | null = null;
|
|
@@ -101,7 +103,11 @@ export class AgentServer extends EventEmitter {
|
|
|
101
103
|
return new Promise<HelloEvent>((resolve, reject) => {
|
|
102
104
|
const timer = setTimeout(() => {
|
|
103
105
|
this.off('hello', onHello);
|
|
104
|
-
|
|
106
|
+
// An app that dials in and never says hello is one whose token is not ours: the agent stays silent then.
|
|
107
|
+
const why = this.#unanswered
|
|
108
|
+
? ' An app connected but did not answer: its token is not this one. Start Metro with the LYNKEUS_TOKEN this driver has (.lynkeus/token or the environment), with --reset-cache.'
|
|
109
|
+
: ' Is a dev build running with <Lynkeus>?';
|
|
110
|
+
reject(new AgentError(`No app attached on ${this.host}:${this.port} within ${timeoutMs}ms.${why}`));
|
|
105
111
|
}, timeoutMs);
|
|
106
112
|
const onHello = (hello: HelloEvent) => {
|
|
107
113
|
clearTimeout(timer);
|
|
@@ -152,6 +158,10 @@ export class AgentServer extends EventEmitter {
|
|
|
152
158
|
this.#hello = null;
|
|
153
159
|
this.#cancelGrace();
|
|
154
160
|
socket.send(JSON.stringify({ event: 'auth', session: this.#session, token: this.#token }));
|
|
161
|
+
const silence = setTimeout(() => {
|
|
162
|
+
if (this.#socket === socket && !this.#hello && socket.readyState === WebSocket.OPEN) this.#unanswered = true;
|
|
163
|
+
}, 2000);
|
|
164
|
+
socket.once('close', () => clearTimeout(silence));
|
|
155
165
|
|
|
156
166
|
socket.on('message', (data) => {
|
|
157
167
|
let message: Response | AgentEvent;
|
|
@@ -163,6 +173,8 @@ export class AgentServer extends EventEmitter {
|
|
|
163
173
|
if ('event' in message) {
|
|
164
174
|
if (message.event === 'hello') {
|
|
165
175
|
this.#hello = message;
|
|
176
|
+
this.#unanswered = false;
|
|
177
|
+
clearTimeout(silence);
|
|
166
178
|
// Resend what the previous socket may have dropped, but only once this one has spoken the
|
|
167
179
|
// protocol: a bare local connection could be any process.
|
|
168
180
|
if (socket.readyState === WebSocket.OPEN) {
|