@welshman/net 0.0.1
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/README.md +20 -0
- package/build/Connection.cjs +89 -0
- package/build/Connection.cjs.map +1 -0
- package/build/Connection.d.ts +26 -0
- package/build/Connection.mjs +85 -0
- package/build/Connection.mjs.map +1 -0
- package/build/ConnectionMeta.cjs +162 -0
- package/build/ConnectionMeta.cjs.map +1 -0
- package/build/ConnectionMeta.d.ts +57 -0
- package/build/ConnectionMeta.mjs +158 -0
- package/build/ConnectionMeta.mjs.map +1 -0
- package/build/Context.cjs +27 -0
- package/build/Context.cjs.map +1 -0
- package/build/Context.d.ts +16 -0
- package/build/Context.mjs +23 -0
- package/build/Context.mjs.map +1 -0
- package/build/Executor.cjs +64 -0
- package/build/Executor.cjs.map +1 -0
- package/build/Executor.d.ts +33 -0
- package/build/Executor.mjs +60 -0
- package/build/Executor.mjs.map +1 -0
- package/build/Pool.cjs +44 -0
- package/build/Pool.cjs.map +1 -0
- package/build/Pool.d.ts +13 -0
- package/build/Pool.mjs +40 -0
- package/build/Pool.mjs.map +1 -0
- package/build/Publish.cjs +70 -0
- package/build/Publish.cjs.map +1 -0
- package/build/Publish.d.ts +40 -0
- package/build/Publish.mjs +65 -0
- package/build/Publish.mjs.map +1 -0
- package/build/Socket.cjs +98 -0
- package/build/Socket.cjs.map +1 -0
- package/build/Socket.d.ts +37 -0
- package/build/Socket.mjs +89 -0
- package/build/Socket.mjs.map +1 -0
- package/build/Subscribe.cjs +215 -0
- package/build/Subscribe.cjs.map +1 -0
- package/build/Subscribe.d.ts +52 -0
- package/build/Subscribe.mjs +206 -0
- package/build/Subscribe.mjs.map +1 -0
- package/build/Tracker.cjs +45 -0
- package/build/Tracker.cjs.map +1 -0
- package/build/Tracker.d.ts +9 -0
- package/build/Tracker.mjs +41 -0
- package/build/Tracker.mjs.map +1 -0
- package/build/index.cjs +30 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.mjs +14 -0
- package/build/index.mjs.map +1 -0
- package/build/target/Multi.cjs +25 -0
- package/build/target/Multi.cjs.map +1 -0
- package/build/target/Multi.d.ts +10 -0
- package/build/target/Multi.mjs +21 -0
- package/build/target/Multi.mjs.map +1 -0
- package/build/target/Plex.cjs +27 -0
- package/build/target/Plex.cjs.map +1 -0
- package/build/target/Plex.d.ts +12 -0
- package/build/target/Plex.mjs +23 -0
- package/build/target/Plex.mjs.map +1 -0
- package/build/target/Relay.cjs +26 -0
- package/build/target/Relay.cjs.map +1 -0
- package/build/target/Relay.d.ts +11 -0
- package/build/target/Relay.mjs +22 -0
- package/build/target/Relay.mjs.map +1 -0
- package/build/target/Relays.cjs +29 -0
- package/build/target/Relays.cjs.map +1 -0
- package/build/target/Relays.d.ts +10 -0
- package/build/target/Relays.mjs +25 -0
- package/build/target/Relays.mjs.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# @welshman/net [](https://npmjs.com/package/@welshman/net)
|
|
2
|
+
|
|
3
|
+
Utilities having to do with connection management and nostr messages.
|
|
4
|
+
|
|
5
|
+
- `Connection` - a wrapper for `Socket` with send and receive queues, and a `ConnectionMeta` instance.
|
|
6
|
+
- `ConnectionMeta` - tracks stats for a given `Connection`.
|
|
7
|
+
- `Context` - an object containing a default `Pool` and global configuration options.
|
|
8
|
+
- `Executor` - implements common nostr flows on a given `target`
|
|
9
|
+
- `Pool` - a thin wrapper around `Map` which stores `Connection`s.
|
|
10
|
+
- `Publish` - utilities for publishing events.
|
|
11
|
+
- `Socket` - a wrapper around isomorphic-ws that handles json parsing/serialization.
|
|
12
|
+
- `Subscribe` - utilities for making requests against nostr relays.
|
|
13
|
+
- `Tracker` - tracks which relays a given event was seen on.
|
|
14
|
+
|
|
15
|
+
Executor `target`s extend `Emitter`, and have a `send` method, a `cleanup` method, and a `connections` getter. They are intended to be passed to an `Executor` for use.
|
|
16
|
+
|
|
17
|
+
- `targets/Multi` allows you to compose multiple targets together.
|
|
18
|
+
- `targets/Plex` takes an array of urls and a `Connection` and sends and receives wrapped nostr messages over that connection.
|
|
19
|
+
- `targets/Relay` takes a `Connection` and provides listeners for different verbs.
|
|
20
|
+
- `targets/Relays` takes an array of `Connection`s and provides listeners for different verbs, merging all events into a single stream.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Connection = void 0;
|
|
4
|
+
const lib_1 = require("@welshman/lib");
|
|
5
|
+
const ConnectionMeta_1 = require("./ConnectionMeta.cjs");
|
|
6
|
+
const Socket_1 = require("./Socket.cjs");
|
|
7
|
+
class Connection extends lib_1.Emitter {
|
|
8
|
+
constructor(url) {
|
|
9
|
+
super();
|
|
10
|
+
this.createSender = () => {
|
|
11
|
+
const worker = new lib_1.Worker({
|
|
12
|
+
shouldDefer: (message) => {
|
|
13
|
+
if (!this.socket.isReady()) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
const [verb, ...extra] = (0, Socket_1.asMessage)(message);
|
|
17
|
+
if (['AUTH', 'CLOSE'].includes(verb)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
// Allow relay requests through
|
|
21
|
+
if (verb === 'EVENT' && extra[0].kind === 28934) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
// Only defer for auth if we're not multiplexing
|
|
25
|
+
if ((0, Socket_1.isMessage)(message) && ![ConnectionMeta_1.AuthStatus.Ok, ConnectionMeta_1.AuthStatus.Pending].includes(this.meta.authStatus)) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (verb === 'REQ') {
|
|
29
|
+
return this.meta.pendingRequests.size >= 8;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
worker.addGlobalHandler((message) => {
|
|
35
|
+
// If we ended up handling a CLOSE before we handled the REQ, don't send the REQ
|
|
36
|
+
if (message[0] === 'CLOSE') {
|
|
37
|
+
worker.buffer = worker.buffer.filter(m => !(m[0] === 'REQ' && m[1] === message[1]));
|
|
38
|
+
}
|
|
39
|
+
this.onSend(message);
|
|
40
|
+
});
|
|
41
|
+
return worker;
|
|
42
|
+
};
|
|
43
|
+
this.createReceiver = () => {
|
|
44
|
+
const worker = new lib_1.Worker();
|
|
45
|
+
worker.addGlobalHandler(this.onReceive);
|
|
46
|
+
return worker;
|
|
47
|
+
};
|
|
48
|
+
this.send = (m) => this.sender.push(m);
|
|
49
|
+
this.onOpen = () => this.emit('open', this);
|
|
50
|
+
this.onClose = () => this.emit('close', this);
|
|
51
|
+
this.onError = () => this.emit('fault', this);
|
|
52
|
+
this.onMessage = (m) => this.receiver.push(m);
|
|
53
|
+
this.onSend = (message) => {
|
|
54
|
+
this.emit('send', this, message);
|
|
55
|
+
this.socket.send(message);
|
|
56
|
+
};
|
|
57
|
+
this.onReceive = (message) => {
|
|
58
|
+
this.emit('receive', this, message);
|
|
59
|
+
};
|
|
60
|
+
this.ensureConnected = ({ shouldReconnect = true }) => {
|
|
61
|
+
if (shouldReconnect && !this.socket.isHealthy()) {
|
|
62
|
+
this.disconnect();
|
|
63
|
+
}
|
|
64
|
+
if (this.socket.isPending()) {
|
|
65
|
+
this.socket.connect();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
this.url = url;
|
|
69
|
+
this.socket = new Socket_1.Socket(url, this);
|
|
70
|
+
this.sender = this.createSender();
|
|
71
|
+
this.receiver = this.createReceiver();
|
|
72
|
+
this.meta = new ConnectionMeta_1.ConnectionMeta(this);
|
|
73
|
+
this.setMaxListeners(100);
|
|
74
|
+
}
|
|
75
|
+
disconnect() {
|
|
76
|
+
this.socket.disconnect();
|
|
77
|
+
this.sender.clear();
|
|
78
|
+
this.receiver.clear();
|
|
79
|
+
this.meta.clearPending();
|
|
80
|
+
}
|
|
81
|
+
destroy() {
|
|
82
|
+
this.disconnect();
|
|
83
|
+
this.removeAllListeners();
|
|
84
|
+
this.sender.stop();
|
|
85
|
+
this.receiver.stop();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.Connection = Connection;
|
|
89
|
+
//# sourceMappingURL=Connection.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Connection.cjs","sourceRoot":"","sources":["../Connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Emitter, Worker } from '@welshman/lib';
|
|
2
|
+
import { ConnectionMeta } from './ConnectionMeta';
|
|
3
|
+
import { Socket } from './Socket';
|
|
4
|
+
import type { SocketMessage } from './Socket';
|
|
5
|
+
export declare class Connection extends Emitter {
|
|
6
|
+
url: string;
|
|
7
|
+
socket: Socket;
|
|
8
|
+
sender: Worker<SocketMessage>;
|
|
9
|
+
receiver: Worker<SocketMessage>;
|
|
10
|
+
meta: ConnectionMeta;
|
|
11
|
+
constructor(url: string);
|
|
12
|
+
createSender: () => Worker<SocketMessage>;
|
|
13
|
+
createReceiver: () => Worker<SocketMessage>;
|
|
14
|
+
send: (m: SocketMessage) => void;
|
|
15
|
+
onOpen: () => boolean;
|
|
16
|
+
onClose: () => boolean;
|
|
17
|
+
onError: () => boolean;
|
|
18
|
+
onMessage: (m: SocketMessage) => void;
|
|
19
|
+
onSend: (message: SocketMessage) => void;
|
|
20
|
+
onReceive: (message: SocketMessage) => void;
|
|
21
|
+
ensureConnected: ({ shouldReconnect }: {
|
|
22
|
+
shouldReconnect?: boolean | undefined;
|
|
23
|
+
}) => void;
|
|
24
|
+
disconnect(): void;
|
|
25
|
+
destroy(): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Emitter, Worker } from '@welshman/lib';
|
|
2
|
+
import { AuthStatus, ConnectionMeta } from "./ConnectionMeta.mjs";
|
|
3
|
+
import { Socket, isMessage, asMessage } from "./Socket.mjs";
|
|
4
|
+
export class Connection extends Emitter {
|
|
5
|
+
constructor(url) {
|
|
6
|
+
super();
|
|
7
|
+
this.createSender = () => {
|
|
8
|
+
const worker = new Worker({
|
|
9
|
+
shouldDefer: (message) => {
|
|
10
|
+
if (!this.socket.isReady()) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
const [verb, ...extra] = asMessage(message);
|
|
14
|
+
if (['AUTH', 'CLOSE'].includes(verb)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
// Allow relay requests through
|
|
18
|
+
if (verb === 'EVENT' && extra[0].kind === 28934) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
// Only defer for auth if we're not multiplexing
|
|
22
|
+
if (isMessage(message) && ![AuthStatus.Ok, AuthStatus.Pending].includes(this.meta.authStatus)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if (verb === 'REQ') {
|
|
26
|
+
return this.meta.pendingRequests.size >= 8;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
worker.addGlobalHandler((message) => {
|
|
32
|
+
// If we ended up handling a CLOSE before we handled the REQ, don't send the REQ
|
|
33
|
+
if (message[0] === 'CLOSE') {
|
|
34
|
+
worker.buffer = worker.buffer.filter(m => !(m[0] === 'REQ' && m[1] === message[1]));
|
|
35
|
+
}
|
|
36
|
+
this.onSend(message);
|
|
37
|
+
});
|
|
38
|
+
return worker;
|
|
39
|
+
};
|
|
40
|
+
this.createReceiver = () => {
|
|
41
|
+
const worker = new Worker();
|
|
42
|
+
worker.addGlobalHandler(this.onReceive);
|
|
43
|
+
return worker;
|
|
44
|
+
};
|
|
45
|
+
this.send = (m) => this.sender.push(m);
|
|
46
|
+
this.onOpen = () => this.emit('open', this);
|
|
47
|
+
this.onClose = () => this.emit('close', this);
|
|
48
|
+
this.onError = () => this.emit('fault', this);
|
|
49
|
+
this.onMessage = (m) => this.receiver.push(m);
|
|
50
|
+
this.onSend = (message) => {
|
|
51
|
+
this.emit('send', this, message);
|
|
52
|
+
this.socket.send(message);
|
|
53
|
+
};
|
|
54
|
+
this.onReceive = (message) => {
|
|
55
|
+
this.emit('receive', this, message);
|
|
56
|
+
};
|
|
57
|
+
this.ensureConnected = ({ shouldReconnect = true }) => {
|
|
58
|
+
if (shouldReconnect && !this.socket.isHealthy()) {
|
|
59
|
+
this.disconnect();
|
|
60
|
+
}
|
|
61
|
+
if (this.socket.isPending()) {
|
|
62
|
+
this.socket.connect();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
this.url = url;
|
|
66
|
+
this.socket = new Socket(url, this);
|
|
67
|
+
this.sender = this.createSender();
|
|
68
|
+
this.receiver = this.createReceiver();
|
|
69
|
+
this.meta = new ConnectionMeta(this);
|
|
70
|
+
this.setMaxListeners(100);
|
|
71
|
+
}
|
|
72
|
+
disconnect() {
|
|
73
|
+
this.socket.disconnect();
|
|
74
|
+
this.sender.clear();
|
|
75
|
+
this.receiver.clear();
|
|
76
|
+
this.meta.clearPending();
|
|
77
|
+
}
|
|
78
|
+
destroy() {
|
|
79
|
+
this.disconnect();
|
|
80
|
+
this.removeAllListeners();
|
|
81
|
+
this.sender.stop();
|
|
82
|
+
this.receiver.stop();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=Connection.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Connection.mjs","sourceRoot":"","sources":["../Connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConnectionMeta = exports.ConnectionStatus = exports.AuthStatus = void 0;
|
|
4
|
+
var AuthStatus;
|
|
5
|
+
(function (AuthStatus) {
|
|
6
|
+
AuthStatus["Ok"] = "ok";
|
|
7
|
+
AuthStatus["Pending"] = "pending";
|
|
8
|
+
AuthStatus["Unauthorized"] = "unauthorized";
|
|
9
|
+
AuthStatus["Forbidden"] = "forbidden";
|
|
10
|
+
})(AuthStatus || (exports.AuthStatus = AuthStatus = {}));
|
|
11
|
+
var ConnectionStatus;
|
|
12
|
+
(function (ConnectionStatus) {
|
|
13
|
+
ConnectionStatus["Unauthorized"] = "unauthorized";
|
|
14
|
+
ConnectionStatus["Forbidden"] = "forbidden";
|
|
15
|
+
ConnectionStatus["Error"] = "error";
|
|
16
|
+
ConnectionStatus["Closed"] = "closed";
|
|
17
|
+
ConnectionStatus["Slow"] = "slow";
|
|
18
|
+
ConnectionStatus["Ok"] = "ok";
|
|
19
|
+
})(ConnectionStatus || (exports.ConnectionStatus = ConnectionStatus = {}));
|
|
20
|
+
class ConnectionMeta {
|
|
21
|
+
constructor(cxn) {
|
|
22
|
+
this.cxn = cxn;
|
|
23
|
+
this.authStatus = AuthStatus.Pending;
|
|
24
|
+
this.pendingPublishes = new Map();
|
|
25
|
+
this.pendingRequests = new Map();
|
|
26
|
+
this.publishCount = 0;
|
|
27
|
+
this.requestCount = 0;
|
|
28
|
+
this.eventCount = 0;
|
|
29
|
+
this.lastOpen = 0;
|
|
30
|
+
this.lastClose = 0;
|
|
31
|
+
this.lastFault = 0;
|
|
32
|
+
this.lastPublish = 0;
|
|
33
|
+
this.lastRequest = 0;
|
|
34
|
+
this.lastEvent = 0;
|
|
35
|
+
this.responseCount = 0;
|
|
36
|
+
this.responseTimer = 0;
|
|
37
|
+
this.clearPending = () => {
|
|
38
|
+
this.pendingPublishes.clear();
|
|
39
|
+
this.pendingRequests.clear();
|
|
40
|
+
};
|
|
41
|
+
this.getSpeed = () => this.responseCount ? this.responseTimer / this.responseCount : 0;
|
|
42
|
+
this.getStatus = () => {
|
|
43
|
+
if (this.authStatus === AuthStatus.Unauthorized)
|
|
44
|
+
return ConnectionStatus.Unauthorized;
|
|
45
|
+
if (this.authStatus === AuthStatus.Forbidden)
|
|
46
|
+
return ConnectionStatus.Forbidden;
|
|
47
|
+
if (this.lastFault > this.lastOpen)
|
|
48
|
+
return ConnectionStatus.Error;
|
|
49
|
+
if (this.lastClose > this.lastOpen)
|
|
50
|
+
return ConnectionStatus.Closed;
|
|
51
|
+
if (this.getSpeed() > 1000)
|
|
52
|
+
return ConnectionStatus.Slow;
|
|
53
|
+
return ConnectionStatus.Ok;
|
|
54
|
+
};
|
|
55
|
+
this.getDescription = () => {
|
|
56
|
+
switch (this.getStatus()) {
|
|
57
|
+
case ConnectionStatus.Unauthorized: return 'Logging in';
|
|
58
|
+
case ConnectionStatus.Forbidden: return 'Failed to log in';
|
|
59
|
+
case ConnectionStatus.Error: return 'Failed to connect';
|
|
60
|
+
case ConnectionStatus.Closed: return 'Waiting to reconnect';
|
|
61
|
+
case ConnectionStatus.Slow: return 'Slow Connection';
|
|
62
|
+
case ConnectionStatus.Ok: return 'Connected';
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
cxn.on('open', () => {
|
|
66
|
+
this.lastOpen = Date.now();
|
|
67
|
+
});
|
|
68
|
+
cxn.on('close', () => {
|
|
69
|
+
this.lastClose = Date.now();
|
|
70
|
+
});
|
|
71
|
+
cxn.on('fault', () => {
|
|
72
|
+
this.lastFault = Date.now();
|
|
73
|
+
});
|
|
74
|
+
cxn.on('send', (cxn, message) => {
|
|
75
|
+
if (message[0] === 'REQ')
|
|
76
|
+
this.onSendRequest(message);
|
|
77
|
+
if (message[0] === 'CLOSE')
|
|
78
|
+
this.onSendClose(message);
|
|
79
|
+
if (message[0] === 'EVENT')
|
|
80
|
+
this.onSendEvent(message);
|
|
81
|
+
});
|
|
82
|
+
cxn.on('receive', (cxn, message) => {
|
|
83
|
+
if (message[0] === 'OK')
|
|
84
|
+
this.onReceiveOk(message);
|
|
85
|
+
if (message[0] === 'AUTH')
|
|
86
|
+
this.onReceiveAuth(message);
|
|
87
|
+
if (message[0] === 'EVENT')
|
|
88
|
+
this.onReceiveEvent(message);
|
|
89
|
+
if (message[0] === 'EOSE')
|
|
90
|
+
this.onReceiveEose(message);
|
|
91
|
+
if (message[0] === 'CLOSED')
|
|
92
|
+
this.onReceiveClosed(message);
|
|
93
|
+
if (message[0] === 'NOTICE')
|
|
94
|
+
this.onReceiveNotice(message);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
onSendRequest([verb, subId, ...filters]) {
|
|
98
|
+
this.requestCount++;
|
|
99
|
+
this.lastRequest = Date.now();
|
|
100
|
+
this.pendingRequests.set(subId, {
|
|
101
|
+
filters,
|
|
102
|
+
sent: Date.now(),
|
|
103
|
+
eoseReceived: false,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
onSendClose([verb, subId]) {
|
|
107
|
+
this.pendingRequests.delete(subId);
|
|
108
|
+
}
|
|
109
|
+
onSendEvent([verb, event]) {
|
|
110
|
+
this.publishCount++;
|
|
111
|
+
this.lastPublish = Date.now();
|
|
112
|
+
this.pendingPublishes.set(event.id, { sent: Date.now(), event });
|
|
113
|
+
}
|
|
114
|
+
onReceiveOk([verb, eventId, ok, notice]) {
|
|
115
|
+
const publish = this.pendingPublishes.get(eventId);
|
|
116
|
+
if (ok) {
|
|
117
|
+
this.authStatus = AuthStatus.Ok;
|
|
118
|
+
}
|
|
119
|
+
else if (notice.startsWith('auth-required:')) {
|
|
120
|
+
// Re-enqueue pending reqs when auth challenge is received
|
|
121
|
+
const pub = this.pendingPublishes.get(eventId);
|
|
122
|
+
if (pub) {
|
|
123
|
+
this.cxn.send(['EVENT', pub.event]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (publish) {
|
|
127
|
+
this.responseCount++;
|
|
128
|
+
this.responseTimer += Date.now() - publish.sent;
|
|
129
|
+
this.pendingPublishes.delete(eventId);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
onReceiveAuth([verb, eventId]) {
|
|
133
|
+
this.authStatus = AuthStatus.Unauthorized;
|
|
134
|
+
}
|
|
135
|
+
onReceiveEvent([verb, event]) {
|
|
136
|
+
this.eventCount++;
|
|
137
|
+
this.lastEvent = Date.now();
|
|
138
|
+
}
|
|
139
|
+
onReceiveEose([verb, subId]) {
|
|
140
|
+
const request = this.pendingRequests.get(subId);
|
|
141
|
+
// Only count the first eose
|
|
142
|
+
if (request && !request.eoseReceived) {
|
|
143
|
+
request.eoseReceived = true;
|
|
144
|
+
this.responseCount++;
|
|
145
|
+
this.responseTimer += Date.now() - request.sent;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
onReceiveClosed([verb, id, notice]) {
|
|
149
|
+
if (notice.startsWith('auth-required:')) {
|
|
150
|
+
// Re-enqueue pending reqs when auth challenge is received
|
|
151
|
+
const req = this.pendingRequests.get(id);
|
|
152
|
+
if (req) {
|
|
153
|
+
this.cxn.send(['REQ', id, ...req.filters]);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
onReceiveNotice([verb, notice]) {
|
|
158
|
+
console.warn('NOTICE', this.cxn.url, notice);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.ConnectionMeta = ConnectionMeta;
|
|
162
|
+
//# sourceMappingURL=ConnectionMeta.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionMeta.cjs","sourceRoot":"","sources":["../ConnectionMeta.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Event, Filter } from 'nostr-tools';
|
|
2
|
+
import type { Message } from '@welshman/util';
|
|
3
|
+
import type { Connection } from './Connection';
|
|
4
|
+
export type PublishMeta = {
|
|
5
|
+
sent: number;
|
|
6
|
+
event: Event;
|
|
7
|
+
};
|
|
8
|
+
export type RequestMeta = {
|
|
9
|
+
sent: number;
|
|
10
|
+
filters: Filter[];
|
|
11
|
+
eoseReceived: boolean;
|
|
12
|
+
};
|
|
13
|
+
export declare enum AuthStatus {
|
|
14
|
+
Ok = "ok",
|
|
15
|
+
Pending = "pending",
|
|
16
|
+
Unauthorized = "unauthorized",
|
|
17
|
+
Forbidden = "forbidden"
|
|
18
|
+
}
|
|
19
|
+
export declare enum ConnectionStatus {
|
|
20
|
+
Unauthorized = "unauthorized",
|
|
21
|
+
Forbidden = "forbidden",
|
|
22
|
+
Error = "error",
|
|
23
|
+
Closed = "closed",
|
|
24
|
+
Slow = "slow",
|
|
25
|
+
Ok = "ok"
|
|
26
|
+
}
|
|
27
|
+
export declare class ConnectionMeta {
|
|
28
|
+
readonly cxn: Connection;
|
|
29
|
+
authStatus: AuthStatus;
|
|
30
|
+
pendingPublishes: Map<string, PublishMeta>;
|
|
31
|
+
pendingRequests: Map<string, RequestMeta>;
|
|
32
|
+
publishCount: number;
|
|
33
|
+
requestCount: number;
|
|
34
|
+
eventCount: number;
|
|
35
|
+
lastOpen: number;
|
|
36
|
+
lastClose: number;
|
|
37
|
+
lastFault: number;
|
|
38
|
+
lastPublish: number;
|
|
39
|
+
lastRequest: number;
|
|
40
|
+
lastEvent: number;
|
|
41
|
+
responseCount: number;
|
|
42
|
+
responseTimer: number;
|
|
43
|
+
constructor(cxn: Connection);
|
|
44
|
+
onSendRequest([verb, subId, ...filters]: Message): void;
|
|
45
|
+
onSendClose([verb, subId]: Message): void;
|
|
46
|
+
onSendEvent([verb, event]: Message): void;
|
|
47
|
+
onReceiveOk([verb, eventId, ok, notice]: Message): void;
|
|
48
|
+
onReceiveAuth([verb, eventId]: Message): void;
|
|
49
|
+
onReceiveEvent([verb, event]: Message): void;
|
|
50
|
+
onReceiveEose([verb, subId]: Message): void;
|
|
51
|
+
onReceiveClosed([verb, id, notice]: Message): void;
|
|
52
|
+
onReceiveNotice([verb, notice]: Message): void;
|
|
53
|
+
clearPending: () => void;
|
|
54
|
+
getSpeed: () => number;
|
|
55
|
+
getStatus: () => ConnectionStatus;
|
|
56
|
+
getDescription: () => "Logging in" | "Failed to log in" | "Failed to connect" | "Waiting to reconnect" | "Slow Connection" | "Connected";
|
|
57
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export var AuthStatus;
|
|
2
|
+
(function (AuthStatus) {
|
|
3
|
+
AuthStatus["Ok"] = "ok";
|
|
4
|
+
AuthStatus["Pending"] = "pending";
|
|
5
|
+
AuthStatus["Unauthorized"] = "unauthorized";
|
|
6
|
+
AuthStatus["Forbidden"] = "forbidden";
|
|
7
|
+
})(AuthStatus || (AuthStatus = {}));
|
|
8
|
+
export var ConnectionStatus;
|
|
9
|
+
(function (ConnectionStatus) {
|
|
10
|
+
ConnectionStatus["Unauthorized"] = "unauthorized";
|
|
11
|
+
ConnectionStatus["Forbidden"] = "forbidden";
|
|
12
|
+
ConnectionStatus["Error"] = "error";
|
|
13
|
+
ConnectionStatus["Closed"] = "closed";
|
|
14
|
+
ConnectionStatus["Slow"] = "slow";
|
|
15
|
+
ConnectionStatus["Ok"] = "ok";
|
|
16
|
+
})(ConnectionStatus || (ConnectionStatus = {}));
|
|
17
|
+
export class ConnectionMeta {
|
|
18
|
+
constructor(cxn) {
|
|
19
|
+
this.cxn = cxn;
|
|
20
|
+
this.authStatus = AuthStatus.Pending;
|
|
21
|
+
this.pendingPublishes = new Map();
|
|
22
|
+
this.pendingRequests = new Map();
|
|
23
|
+
this.publishCount = 0;
|
|
24
|
+
this.requestCount = 0;
|
|
25
|
+
this.eventCount = 0;
|
|
26
|
+
this.lastOpen = 0;
|
|
27
|
+
this.lastClose = 0;
|
|
28
|
+
this.lastFault = 0;
|
|
29
|
+
this.lastPublish = 0;
|
|
30
|
+
this.lastRequest = 0;
|
|
31
|
+
this.lastEvent = 0;
|
|
32
|
+
this.responseCount = 0;
|
|
33
|
+
this.responseTimer = 0;
|
|
34
|
+
this.clearPending = () => {
|
|
35
|
+
this.pendingPublishes.clear();
|
|
36
|
+
this.pendingRequests.clear();
|
|
37
|
+
};
|
|
38
|
+
this.getSpeed = () => this.responseCount ? this.responseTimer / this.responseCount : 0;
|
|
39
|
+
this.getStatus = () => {
|
|
40
|
+
if (this.authStatus === AuthStatus.Unauthorized)
|
|
41
|
+
return ConnectionStatus.Unauthorized;
|
|
42
|
+
if (this.authStatus === AuthStatus.Forbidden)
|
|
43
|
+
return ConnectionStatus.Forbidden;
|
|
44
|
+
if (this.lastFault > this.lastOpen)
|
|
45
|
+
return ConnectionStatus.Error;
|
|
46
|
+
if (this.lastClose > this.lastOpen)
|
|
47
|
+
return ConnectionStatus.Closed;
|
|
48
|
+
if (this.getSpeed() > 1000)
|
|
49
|
+
return ConnectionStatus.Slow;
|
|
50
|
+
return ConnectionStatus.Ok;
|
|
51
|
+
};
|
|
52
|
+
this.getDescription = () => {
|
|
53
|
+
switch (this.getStatus()) {
|
|
54
|
+
case ConnectionStatus.Unauthorized: return 'Logging in';
|
|
55
|
+
case ConnectionStatus.Forbidden: return 'Failed to log in';
|
|
56
|
+
case ConnectionStatus.Error: return 'Failed to connect';
|
|
57
|
+
case ConnectionStatus.Closed: return 'Waiting to reconnect';
|
|
58
|
+
case ConnectionStatus.Slow: return 'Slow Connection';
|
|
59
|
+
case ConnectionStatus.Ok: return 'Connected';
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
cxn.on('open', () => {
|
|
63
|
+
this.lastOpen = Date.now();
|
|
64
|
+
});
|
|
65
|
+
cxn.on('close', () => {
|
|
66
|
+
this.lastClose = Date.now();
|
|
67
|
+
});
|
|
68
|
+
cxn.on('fault', () => {
|
|
69
|
+
this.lastFault = Date.now();
|
|
70
|
+
});
|
|
71
|
+
cxn.on('send', (cxn, message) => {
|
|
72
|
+
if (message[0] === 'REQ')
|
|
73
|
+
this.onSendRequest(message);
|
|
74
|
+
if (message[0] === 'CLOSE')
|
|
75
|
+
this.onSendClose(message);
|
|
76
|
+
if (message[0] === 'EVENT')
|
|
77
|
+
this.onSendEvent(message);
|
|
78
|
+
});
|
|
79
|
+
cxn.on('receive', (cxn, message) => {
|
|
80
|
+
if (message[0] === 'OK')
|
|
81
|
+
this.onReceiveOk(message);
|
|
82
|
+
if (message[0] === 'AUTH')
|
|
83
|
+
this.onReceiveAuth(message);
|
|
84
|
+
if (message[0] === 'EVENT')
|
|
85
|
+
this.onReceiveEvent(message);
|
|
86
|
+
if (message[0] === 'EOSE')
|
|
87
|
+
this.onReceiveEose(message);
|
|
88
|
+
if (message[0] === 'CLOSED')
|
|
89
|
+
this.onReceiveClosed(message);
|
|
90
|
+
if (message[0] === 'NOTICE')
|
|
91
|
+
this.onReceiveNotice(message);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
onSendRequest([verb, subId, ...filters]) {
|
|
95
|
+
this.requestCount++;
|
|
96
|
+
this.lastRequest = Date.now();
|
|
97
|
+
this.pendingRequests.set(subId, {
|
|
98
|
+
filters,
|
|
99
|
+
sent: Date.now(),
|
|
100
|
+
eoseReceived: false,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
onSendClose([verb, subId]) {
|
|
104
|
+
this.pendingRequests.delete(subId);
|
|
105
|
+
}
|
|
106
|
+
onSendEvent([verb, event]) {
|
|
107
|
+
this.publishCount++;
|
|
108
|
+
this.lastPublish = Date.now();
|
|
109
|
+
this.pendingPublishes.set(event.id, { sent: Date.now(), event });
|
|
110
|
+
}
|
|
111
|
+
onReceiveOk([verb, eventId, ok, notice]) {
|
|
112
|
+
const publish = this.pendingPublishes.get(eventId);
|
|
113
|
+
if (ok) {
|
|
114
|
+
this.authStatus = AuthStatus.Ok;
|
|
115
|
+
}
|
|
116
|
+
else if (notice.startsWith('auth-required:')) {
|
|
117
|
+
// Re-enqueue pending reqs when auth challenge is received
|
|
118
|
+
const pub = this.pendingPublishes.get(eventId);
|
|
119
|
+
if (pub) {
|
|
120
|
+
this.cxn.send(['EVENT', pub.event]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (publish) {
|
|
124
|
+
this.responseCount++;
|
|
125
|
+
this.responseTimer += Date.now() - publish.sent;
|
|
126
|
+
this.pendingPublishes.delete(eventId);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
onReceiveAuth([verb, eventId]) {
|
|
130
|
+
this.authStatus = AuthStatus.Unauthorized;
|
|
131
|
+
}
|
|
132
|
+
onReceiveEvent([verb, event]) {
|
|
133
|
+
this.eventCount++;
|
|
134
|
+
this.lastEvent = Date.now();
|
|
135
|
+
}
|
|
136
|
+
onReceiveEose([verb, subId]) {
|
|
137
|
+
const request = this.pendingRequests.get(subId);
|
|
138
|
+
// Only count the first eose
|
|
139
|
+
if (request && !request.eoseReceived) {
|
|
140
|
+
request.eoseReceived = true;
|
|
141
|
+
this.responseCount++;
|
|
142
|
+
this.responseTimer += Date.now() - request.sent;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
onReceiveClosed([verb, id, notice]) {
|
|
146
|
+
if (notice.startsWith('auth-required:')) {
|
|
147
|
+
// Re-enqueue pending reqs when auth challenge is received
|
|
148
|
+
const req = this.pendingRequests.get(id);
|
|
149
|
+
if (req) {
|
|
150
|
+
this.cxn.send(['REQ', id, ...req.filters]);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
onReceiveNotice([verb, notice]) {
|
|
155
|
+
console.warn('NOTICE', this.cxn.url, notice);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=ConnectionMeta.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionMeta.mjs","sourceRoot":"","sources":["../ConnectionMeta.ts"],"names":[],"mappings":"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"}
|