mirror of
https://github.com/wisplite/tether-ts.git
synced 2026-05-01 06:22:41 -05:00
separation of concerns
This commit is contained in:
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
export declare class TetherClient {
|
export declare class TetherClient {
|
||||||
private ws;
|
private websocketHandler;
|
||||||
private subscribedQueries;
|
private subscribedQueries;
|
||||||
connect: (url: string) => void;
|
connect: (url: string) => void;
|
||||||
disconnect: () => void;
|
disconnect: () => void;
|
||||||
|
|||||||
Vendored
+7
-38
@@ -1,60 +1,29 @@
|
|||||||
|
import { WebSocketHandler } from './utils/websocket.js';
|
||||||
export class TetherClient {
|
export class TetherClient {
|
||||||
ws = null;
|
websocketHandler = new WebSocketHandler();
|
||||||
subscribedQueries = new Map();
|
subscribedQueries = new Map();
|
||||||
connect = (url) => {
|
connect = (url) => {
|
||||||
this.ws = new WebSocket(url);
|
this.websocketHandler.startConnection(url);
|
||||||
this.ws.onopen = () => {
|
|
||||||
console.log('Connected to Tether');
|
|
||||||
};
|
|
||||||
this.ws.onmessage = (event) => {
|
|
||||||
const data = JSON.parse(event.data);
|
|
||||||
if (data.type === 'query') {
|
|
||||||
this.subscribedQueries.forEach((callback, query) => {
|
|
||||||
if (data.query === query) {
|
|
||||||
callback(data.data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (data.type === 'error') {
|
|
||||||
console.error(data.error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.ws.onclose = () => {
|
|
||||||
console.log('Disconnected from Tether');
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
disconnect = () => {
|
disconnect = () => {
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.close();
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.close();
|
|
||||||
this.ws = null;
|
|
||||||
};
|
};
|
||||||
subscribe = (query, callback) => {
|
subscribe = (query, callback) => {
|
||||||
this.subscribedQueries.set(query, callback);
|
this.subscribedQueries.set(query, callback);
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.send(JSON.stringify({
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.send(JSON.stringify({
|
|
||||||
type: 'subscribe',
|
type: 'subscribe',
|
||||||
query: query
|
query: query
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
unsubscribe = (query) => {
|
unsubscribe = (query) => {
|
||||||
this.subscribedQueries.delete(query);
|
this.subscribedQueries.delete(query);
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.send(JSON.stringify({
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.send(JSON.stringify({
|
|
||||||
type: 'unsubscribe',
|
type: 'unsubscribe',
|
||||||
query: query
|
query: query
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
sendMutation = (mutationName, params) => {
|
sendMutation = (mutationName, params) => {
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.send(JSON.stringify({
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.send(JSON.stringify({
|
|
||||||
type: 'mutation',
|
type: 'mutation',
|
||||||
name: mutationName,
|
name: mutationName,
|
||||||
payload: params,
|
payload: params,
|
||||||
|
|||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
export declare class WebSocketHandler {
|
||||||
|
private ws;
|
||||||
|
private url;
|
||||||
|
private subscribedQueries;
|
||||||
|
private onOpen;
|
||||||
|
private onClose;
|
||||||
|
private reconnectAttempts;
|
||||||
|
private maxReconnectAttempts;
|
||||||
|
private reconnectInterval;
|
||||||
|
private sendQueue;
|
||||||
|
startConnection: (url: string) => void;
|
||||||
|
attemptReconnect: () => void;
|
||||||
|
close: () => void;
|
||||||
|
send: (message: string) => void;
|
||||||
|
}
|
||||||
Vendored
+64
@@ -0,0 +1,64 @@
|
|||||||
|
export class WebSocketHandler {
|
||||||
|
ws = null;
|
||||||
|
url = '';
|
||||||
|
subscribedQueries = new Map();
|
||||||
|
onOpen = () => { };
|
||||||
|
onClose = () => { };
|
||||||
|
reconnectAttempts = 0;
|
||||||
|
maxReconnectAttempts = 5;
|
||||||
|
reconnectInterval = 1000;
|
||||||
|
sendQueue = [];
|
||||||
|
startConnection = (url) => {
|
||||||
|
this.url = url;
|
||||||
|
this.ws = new WebSocket(url);
|
||||||
|
const ws = this.ws;
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log('Connected to Tether');
|
||||||
|
this.onOpen();
|
||||||
|
if (this.sendQueue.length > 0) {
|
||||||
|
this.sendQueue.forEach(message => this.ws?.send(message));
|
||||||
|
this.sendQueue = [];
|
||||||
|
}
|
||||||
|
this.reconnectAttempts = 0;
|
||||||
|
};
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(String(event.data));
|
||||||
|
if (data.type === 'query') {
|
||||||
|
this.subscribedQueries.forEach((callback, query) => {
|
||||||
|
if (data.query === query) {
|
||||||
|
callback(data.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (data.type === 'error') {
|
||||||
|
console.error(data.error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ws.onclose = () => {
|
||||||
|
console.log('Disconnected from Tether');
|
||||||
|
this.attemptReconnect();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
attemptReconnect = () => {
|
||||||
|
this.ws?.close();
|
||||||
|
this.reconnectAttempts++;
|
||||||
|
if (this.reconnectAttempts > this.maxReconnectAttempts) {
|
||||||
|
console.error('Max reconnect attempts reached');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.startConnection(this.url);
|
||||||
|
}, this.reconnectInterval);
|
||||||
|
};
|
||||||
|
close = () => {
|
||||||
|
this.ws?.close();
|
||||||
|
this.ws = null;
|
||||||
|
};
|
||||||
|
send = (message) => {
|
||||||
|
if (this.ws?.readyState !== WebSocket.OPEN) {
|
||||||
|
this.sendQueue.push(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ws?.send(message);
|
||||||
|
};
|
||||||
|
}
|
||||||
+7
-37
@@ -1,43 +1,19 @@
|
|||||||
|
import { WebSocketHandler } from './utils/websocket.js';
|
||||||
export class TetherClient {
|
export class TetherClient {
|
||||||
private ws: WebSocket | null = null;
|
private websocketHandler: WebSocketHandler = new WebSocketHandler();
|
||||||
private subscribedQueries = new Map<string, (data: any) => void>();
|
private subscribedQueries = new Map<string, (data: any) => void>();
|
||||||
|
|
||||||
connect = (url: string) => {
|
connect = (url: string) => {
|
||||||
this.ws = new WebSocket(url);
|
this.websocketHandler.startConnection(url);
|
||||||
this.ws.onopen = () => {
|
|
||||||
console.log('Connected to Tether');
|
|
||||||
};
|
|
||||||
this.ws.onmessage = (event) => {
|
|
||||||
const data = JSON.parse(event.data);
|
|
||||||
if (data.type === 'query') {
|
|
||||||
this.subscribedQueries.forEach((callback, query) => {
|
|
||||||
if (data.query === query) {
|
|
||||||
callback(data.data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (data.type === 'error') {
|
|
||||||
console.error(data.error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.ws.onclose = () => {
|
|
||||||
console.log('Disconnected from Tether');
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
disconnect = () => {
|
disconnect = () => {
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.close();
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.close();
|
|
||||||
this.ws = null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
subscribe = (query: string, callback: (data: any) => void) => {
|
subscribe = (query: string, callback: (data: any) => void) => {
|
||||||
this.subscribedQueries.set(query, callback);
|
this.subscribedQueries.set(query, callback);
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.send(JSON.stringify({
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.send(JSON.stringify({
|
|
||||||
type: 'subscribe',
|
type: 'subscribe',
|
||||||
query: query
|
query: query
|
||||||
}));
|
}));
|
||||||
@@ -45,20 +21,14 @@ export class TetherClient {
|
|||||||
|
|
||||||
unsubscribe = (query: string) => {
|
unsubscribe = (query: string) => {
|
||||||
this.subscribedQueries.delete(query);
|
this.subscribedQueries.delete(query);
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.send(JSON.stringify({
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.send(JSON.stringify({
|
|
||||||
type: 'unsubscribe',
|
type: 'unsubscribe',
|
||||||
query: query
|
query: query
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
sendMutation = (mutationName: string, params: any) => {
|
sendMutation = (mutationName: string, params: any) => {
|
||||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
this.websocketHandler.send(JSON.stringify({
|
||||||
throw new Error('Not connected to Tether');
|
|
||||||
}
|
|
||||||
this.ws.send(JSON.stringify({
|
|
||||||
type: 'mutation',
|
type: 'mutation',
|
||||||
name: mutationName,
|
name: mutationName,
|
||||||
payload: params,
|
payload: params,
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
export class WebSocketHandler {
|
||||||
|
private ws: WebSocket | null = null;
|
||||||
|
private url: string = '';
|
||||||
|
private subscribedQueries = new Map<string, (data: any) => void>();
|
||||||
|
private onOpen: () => void = () => {};
|
||||||
|
private onClose: () => void = () => {};
|
||||||
|
private reconnectAttempts: number = 0;
|
||||||
|
private maxReconnectAttempts: number = 5;
|
||||||
|
private reconnectInterval: number = 1000;
|
||||||
|
private sendQueue: string[] = [];
|
||||||
|
|
||||||
|
startConnection = (url: string) => {
|
||||||
|
this.url = url;
|
||||||
|
this.ws = new WebSocket(url);
|
||||||
|
const ws = this.ws;
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log('Connected to Tether');
|
||||||
|
this.onOpen();
|
||||||
|
if (this.sendQueue.length > 0) {
|
||||||
|
this.sendQueue.forEach(message => this.ws?.send(message));
|
||||||
|
this.sendQueue = [];
|
||||||
|
}
|
||||||
|
this.reconnectAttempts = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (event: MessageEvent) => {
|
||||||
|
const data = JSON.parse(String(event.data)) as {
|
||||||
|
type: string;
|
||||||
|
query?: string;
|
||||||
|
data?: unknown;
|
||||||
|
error?: string;
|
||||||
|
};
|
||||||
|
if (data.type === 'query') {
|
||||||
|
this.subscribedQueries.forEach((callback, query) => {
|
||||||
|
if (data.query === query) {
|
||||||
|
callback(data.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (data.type === 'error') {
|
||||||
|
console.error(data.error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onclose = () => {
|
||||||
|
console.log('Disconnected from Tether');
|
||||||
|
this.attemptReconnect();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
attemptReconnect = () => {
|
||||||
|
this.ws?.close();
|
||||||
|
this.reconnectAttempts++;
|
||||||
|
if (this.reconnectAttempts > this.maxReconnectAttempts) {
|
||||||
|
console.error('Max reconnect attempts reached');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.startConnection(this.url);
|
||||||
|
}, this.reconnectInterval);
|
||||||
|
};
|
||||||
|
|
||||||
|
close = () => {
|
||||||
|
this.ws?.close();
|
||||||
|
this.ws = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
send = (message: string) => {
|
||||||
|
if (this.ws?.readyState !== WebSocket.OPEN) {
|
||||||
|
this.sendQueue.push(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ws?.send(message);
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user