typedsocket/ts/typedsocket.classes.typedsocket.ts
2021-01-23 04:51:48 +00:00

158 lines
5.4 KiB
TypeScript

import * as plugins from './typedsocket.plugins';
import type * as smartexpress from '@pushrocks/smartexpress';
const publicRoleName = 'publicRoleName';
const publicRolePass = 'publicRolePass';
export class TypedSocket {
// STATIC
/**
* creates a typedsocket server
* note: this will fail in browser environments as server libs are not bundled.
*/
public static async createServer(
typedrouterArg: plugins.typedrequest.TypedRouter,
smartexpressServerArg?: smartexpress.Server
): Promise<TypedSocket> {
const smartsocketServer = new plugins.smartsocket.Smartsocket({
port: 3000,
});
if (smartexpressServerArg) {
smartsocketServer.setExternalServer('smartexpress', smartexpressServerArg);
}
const publicRole = new plugins.smartsocket.SocketRole({
name: publicRoleName,
passwordHash: await plugins.isohash.sha256FromString(publicRolePass),
});
smartsocketServer.addSocketRoles([publicRole]);
smartsocketServer.socketFunctions.add(
new plugins.smartsocket.SocketFunction({
funcName: 'processMessage',
allowedRoles: [publicRole],
funcDef: async (dataArg, socketConnectionArg) => {
return typedrouterArg.routeAndAddResponse(dataArg);
},
})
);
const typedsocket = new TypedSocket(
typedrouterArg,
async <T extends plugins.typedrequestInterfaces.ITypedRequest>(
dataArg: T,
targetConnectionArg?: plugins.smartsocket.SocketConnection
): Promise<T> => {
if (!targetConnectionArg) {
if ((smartsocketServer.socketConnections.getArray().length = 1)) {
console.log(
'Since no targetConnection was supplied and there is only one active one present, choosing that one automatically'
);
targetConnectionArg = smartsocketServer.socketConnections.getArray()[0];
} else {
throw new Error('you need to specify the wanted targetConnection');
}
}
const response: T = await smartsocketServer.clientCall(
'processMessage',
dataArg,
targetConnectionArg
) as any;
return response;
},
smartsocketServer
);
await smartsocketServer.start();
return typedsocket;
}
public static async createClient(
typedrouterArg: plugins.typedrequest.TypedRouter,
serverUrlArg: string,
aliasArg = 'clientArg'
): Promise<TypedSocket> {
const domain = new plugins.smartstring.Domain(serverUrlArg);
const smartsocketClient = new plugins.smartsocket.SmartsocketClient({
alias: aliasArg,
role: publicRoleName,
password: publicRolePass,
port: domain.port || 3000,
url: `${domain.nodeParsedUrl.protocol}//${domain.nodeParsedUrl.host}`,
autoReconnect: true,
});
smartsocketClient.addSocketFunction(
new plugins.smartsocket.SocketFunction({
funcName: 'processMessage',
allowedRoles: [],
funcDef: async (dataArg, socketConnectionArg) => {
return typedrouterArg.routeAndAddResponse(dataArg);
},
})
);
const typedsocket = new TypedSocket(
typedrouterArg,
async <T extends plugins.typedrequestInterfaces.ITypedRequest>(dataArg: T): Promise<T> => {
const response: T = (smartsocketClient.serverCall('processMessage', dataArg) as any) as T;
return response;
},
smartsocketClient
);
await smartsocketClient.connect();
return typedsocket;
}
// INSTANCE
public typedrouter: plugins.typedrequest.TypedRouter;
private postMethod: plugins.typedrequest.IPostMethod &
((
typedRequestPostObject: plugins.typedrequestInterfaces.ITypedRequest,
socketConnectionArg?: plugins.smartsocket.SocketConnection
) => Promise<plugins.typedrequestInterfaces.ITypedRequest>);
private socketServerOrClient: plugins.smartsocket.Smartsocket | plugins.smartsocket.SmartsocketClient;
constructor(
typedrouterArg: plugins.typedrequest.TypedRouter,
postMethodArg: plugins.typedrequest.IPostMethod,
socketServerOrClientArg: plugins.smartsocket.Smartsocket | plugins.smartsocket.SmartsocketClient
) {
this.typedrouter = typedrouterArg;
this.postMethod = postMethodArg;
this.socketServerOrClient = socketServerOrClientArg;
}
public createTypedRequest<T extends plugins.typedrequestInterfaces.ITypedRequest>(
methodName: T['method'],
targetConnection?: plugins.smartsocket.SocketConnection
): plugins.typedrequest.TypedRequest<T> {
const typedrequest = new plugins.typedrequest.TypedRequest<T>(
new plugins.typedrequest.TypedTarget({
postMethod: async (requestDataArg) => {
const result = await this.postMethod(requestDataArg, targetConnection);
return result;
},
}),
methodName
);
return typedrequest;
}
public async findTargetConnection(
findFuncArg: (connectionArg: plugins.smartsocket.SocketConnection) => boolean
) {
if (this.socketServerOrClient instanceof plugins.smartsocket.Smartsocket) {
for (const socketConnection of this.socketServerOrClient.socketConnections.getArray()) {
if (findFuncArg(socketConnection)) {
return socketConnection;
}
}
} else {
console.warn('this method >>findTargetConnection<< is only available from the server');
}
}
public async stop() {
await this.socketServerOrClient.stop()
}
}