Skip to content

Instantly share code, notes, and snippets.

@Segmentational
Created September 9, 2022 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Segmentational/eadf200bedecad3934551f45ef9c81e1 to your computer and use it in GitHub Desktop.
Save Segmentational/eadf200bedecad3934551f45ef9c81e1 to your computer and use it in GitHub Desktop.
Socket + TypeScript Functional Prototyping & Module Namespacing
import * as Network from "net";
/***
* @module Test
*
* **TSC Configuration**
*
* ```json
* {
* "compilerOptions": {
* "target": "esnext",
* "module": "commonjs",
* "skipLibCheck": true
* },
* "files": [
* "./socket.test.ts"
* ]
* }
* ```
*/
export module Test {
function Serializer(buffer: Buffer): Message {
const state: Serial = Object.create({
buffer: buffer,
serialize: (): Object | { raw: string } => {
try {
return JSON.parse(state.string);
} catch (exception) {
/*** Exception ... */
return {
raw: state.string
};
}
},
get transmission() {
return JSON.stringify(state.serial, null, 4) + "\r" + "\n";
},
get string() {
return state.buffer.toString().trim();
},
get serial() {
return state.serialize();
},
get json() {
return JSON.stringify(state.serial, null, 4);
}
});
const instance = Object.create({});
Object.setPrototypeOf(instance, state);
return instance;
}
async function send(connection: Socket, input: object | string): Promise<boolean | NodeJS.ErrnoException> {
console.debug("[Debug] [Server] (Message)" + ":", "String Type -" + " " + (typeof input === "string"));
console.debug("[Debug] [Server] (Message)" + ":", "Object Type -" + " " + (typeof input === "object"));
return new Promise((resolve, reject) => {
if (!(typeof input === "string")) {
try {
const message = JSON.stringify(input, null, 4) + "\r" + "\n";
connection.write(message);
} catch (exception) {
try {
const message = input + "\r" + "\n";
connection.write(message);
} catch (error) {
reject(error);
}
}
} else {
try {
const message = JSON.stringify({
message: input
}, null, 4);
connection.write(message + "\r" + "\n");
} catch (error) {
reject(error);
}
}
resolve(true);
});
}
/***
* ## Running via `node` ##
*
* ```bash
* tsc socket.test.ts \
* --target esnext \
* --module commonjs \
* --skipLibCheck
*
* node socket.test.js
* ```
*
* ## Testing the Module ##
*
* ```bash
* telnet localhost 8124
* ```
*
*/
export async function Socket() {
const Server = Network.createServer(async (connection: Socket) => {
// The Connection Listener
console.log("[Log] [Client] (Connection)" + ":", "Client Connection has been Established");
// Disconnection Handler
connection.on("end", () => {
console.log("[Log] [Client] (End)" + ":", "Client has been Disconnected");
});
// Client Message Event(s)
connection.on("data", (buffer: Buffer) => {
const message: Message = Reflect.construct(Serializer, [buffer]);
console.log("[Log] [Client] (Message)" + ":", message.json);
connection.write(message.transmission);
});
// Ping-Pong Callback
await send(connection, "Connection-Establishment");
});
Server.on("error", (exception: NodeJS.ErrnoException) => {
console.trace(exception);
throw exception;
});
Server.listen(8124, () => {
console.log("[Log] [Server] (Listener)" + ":", "Server is now Listening on Port 8124");
});
}
type Serial = { buffer: Buffer, string: string, serial: object, transmission: string, serialize: Function & (() => Object | { raw: string }), json: () => string };
interface Message extends Serial {
new(buffer: Buffer): Message;
(buffer: Buffer): Message;
}
}
import type {Socket} from "net";
(async () => Test.Socket())();
export default Test;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment