Converts JS files to TS

Closes bitburner-official/bitburner-filesync#12
This commit is contained in:
Heinous Tugboat 2022-09-30 20:10:49 -04:00
parent bef0628e79
commit 778b8d492a
10 changed files with 83 additions and 48 deletions

View file

@ -1,9 +1,11 @@
import CheapWatch from "cheap-watch"; import CheapWatch from "cheap-watch";
import { config } from "./config.js"; import { config } from "./config";
import { EventType } from "./eventTypes.js"; import { EventType } from "./eventTypes";
import { resolve } from "path"; import { resolve } from "path";
import type { Signal } from 'signal-js';
import type { File } from './interfaces';
function fileFilter(file) { function fileFilter(file: File) {
if (config.get("allowedFiletypes").some(extension => file.path.endsWith(extension))) if (config.get("allowedFiletypes").some(extension => file.path.endsWith(extension)))
return true; return true;
if (file.stats.isDirectory()) if (file.stats.isDirectory())
@ -11,7 +13,7 @@ function fileFilter(file) {
return false; return false;
} }
export async function setupWatch(signaller) { export async function setupWatch(signaller: Signal) {
const watch = new CheapWatch({ const watch = new CheapWatch({
dir: config.get("scriptsFolder"), dir: config.get("scriptsFolder"),
filter: fileFilter, filter: fileFilter,
@ -32,4 +34,4 @@ export async function setupWatch(signaller) {
} }
return watch; return watch;
} }

View file

@ -1,11 +1,11 @@
"use strict" import { setupWatch } from "./fileWatch";
import { setupWatch } from "./fileWatch.js"; import { config, loadConfig } from "./config";
import { config, loadConfig } from "./config.js"; import { setupSocket } from "./networking/webSocket";
import { setupSocket } from "./networking/webSocket.js";
import signal from "signal-js"; import signal from "signal-js";
import { fileChangeEventToMsg, fileRemovalEventToMsg, requestFilenames, requestDefinitionFile } from "./networking/messageGenerators.js"; import { fileChangeEventToMsg, fileRemovalEventToMsg, requestFilenames, requestDefinitionFile } from "./networking/messageGenerators";
import { EventType } from "./eventTypes.js"; import { EventType } from "./eventTypes";
import { messageHandler } from "./networking/messageHandler.js"; import { messageHandler } from "./networking/messageHandler";
import { FileEvent, Message } from './interfaces';
export async function start() { export async function start() {
loadConfig(); loadConfig();
@ -13,7 +13,7 @@ export async function start() {
const socket = setupSocket(signal); const socket = setupSocket(signal);
// Add a handler for received messages. // Add a handler for received messages.
signal.on(EventType.MessageReceived, msg => messageHandler(signal, msg, watch.paths)); signal.on(EventType.MessageReceived, (msg: Message) => messageHandler(signal, msg, watch.paths));
// Add a handler for when a connection to a game is made. // Add a handler for when a connection to a game is made.
signal.on(EventType.ConnectionMade, () => { signal.on(EventType.ConnectionMade, () => {
@ -27,7 +27,7 @@ export async function start() {
const extensions = config.get("allowedFiletypes"); const extensions = config.get("allowedFiletypes");
for (const path of watch.paths.keys()) { for (const path of watch.paths.keys()) {
if (extensions.some(extension => path.endsWith(extension))) if (extensions.some(extension => path.endsWith(extension)))
signal.emit(EventType.MessageSend, fileChangeEventToMsg({ path: path })) signal.emit(EventType.MessageSend, fileChangeEventToMsg({ path }))
} }
} else { } else {
// Upload missing files to the game. // Upload missing files to the game.
@ -36,14 +36,14 @@ export async function start() {
}) })
// Add a handler for changed files. // Add a handler for changed files.
signal.on(EventType.FileChanged, fileEvent => { signal.on(EventType.FileChanged, (fileEvent: FileEvent) => {
if (!config.get("quiet")) console.log(fileEvent.path + " changed"); if (!config.get("quiet")) console.log(fileEvent.path + " changed");
signal.emit(EventType.MessageSend, fileChangeEventToMsg(fileEvent)) signal.emit(EventType.MessageSend, fileChangeEventToMsg(fileEvent))
}); });
// Add a handler for removed files, if allowed. // Add a handler for removed files, if allowed.
if (config.get("allowDeletingFiles")) if (config.get("allowDeletingFiles"))
signal.on(EventType.FileDeleted, fileEvent => signal.on(EventType.FileDeleted, (fileEvent: FileEvent) =>
signal.emit(EventType.MessageSend, fileRemovalEventToMsg(fileEvent))); signal.emit(EventType.MessageSend, fileRemovalEventToMsg(fileEvent)));
console.log(`Server is ready, running on ${config.get("port")}!`) console.log(`Server is ready, running on ${config.get("port")}!`)

16
src/interfaces.ts Normal file
View file

@ -0,0 +1,16 @@
import type { Stats } from 'fs';
export interface Message {
id: string;
method?: string;
jsonrpc: string;
params?: object;
}
export interface FileEvent {
path: string;
}
export interface File extends FileEvent {
stats: Stats
}

View file

@ -1,10 +1,11 @@
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import { config } from "../config.js"; import { config } from "../config";
import { join } from "path"; import { join } from "path";
import type { FileEvent, Message } from '../interfaces';
let messageCounter = 0; let messageCounter = 0;
export function fileChangeEventToMsg({ path }) { export function fileChangeEventToMsg({ path }: FileEvent): Message {
return { return {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "pushFile", "method": "pushFile",
@ -13,11 +14,11 @@ export function fileChangeEventToMsg({ path }) {
"filename": addLeadingSlash(path), "filename": addLeadingSlash(path),
"content": readFileSync(join(config.get("scriptsFolder"), path)).toString() "content": readFileSync(join(config.get("scriptsFolder"), path)).toString()
}, },
"id": messageCounter++ "id": (messageCounter++).toString()
} }
} }
export function fileRemovalEventToMsg({ path }) { export function fileRemovalEventToMsg({ path }: FileEvent): Message {
return { return {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "deleteFile", "method": "deleteFile",
@ -25,30 +26,30 @@ export function fileRemovalEventToMsg({ path }) {
"server": "home", "server": "home",
"filename": addLeadingSlash(path), "filename": addLeadingSlash(path),
}, },
"id": messageCounter++ "id": (messageCounter++).toString()
} }
} }
export function requestDefinitionFile() { export function requestDefinitionFile(): Message {
return { return {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "getDefinitionFile", "method": "getDefinitionFile",
"id": messageCounter++ "id": (messageCounter++).toString()
} }
} }
export function requestFilenames() { export function requestFilenames(): Message {
return { return {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "getFileNames", "method": "getFileNames",
"params": { "params": {
"server": "home", "server": "home",
}, },
"id": messageCounter++ "id": (messageCounter++).toString()
} }
} }
function addLeadingSlash(path){ function addLeadingSlash(path: string): string {
const slashes = path.match('/'); const slashes = path.match('/');
if (slashes) if (slashes)
return `/${path}` return `/${path}`

View file

@ -1,10 +1,12 @@
import { messageTracker } from "./messageTracker.js"; import { messageTracker } from "./messageTracker";
import { writeFile } from "fs"; import { Stats, writeFile } from "fs";
import { config } from "../config.js"; import { config } from "../config";
import { EventType } from "../eventTypes.js"; import { EventType } from "../eventTypes";
import { fileChangeEventToMsg } from "./messageGenerators.js"; import { fileChangeEventToMsg } from "./messageGenerators";
import type { Signal } from 'signal-js';
import { Message } from '../interfaces';
export function messageHandler(signaller, msg, paths) { export function messageHandler(signaller: Signal, msg: Message, paths: Map<string, Stats>) {
let incoming; let incoming;
try { incoming = JSON.parse(msg.toString()); } try { incoming = JSON.parse(msg.toString()); }
@ -25,7 +27,7 @@ export function messageHandler(signaller, msg, paths) {
if (request?.method && if (request?.method &&
request.method == "getFileNames" request.method == "getFileNames"
&& incoming.result) { && incoming.result) {
const gameFiles = incoming.result.map(file => removeLeadingSlash(file)); const gameFiles = incoming.result.map((file: string) => removeLeadingSlash(file));
paths.forEach((stats, fileName) => { paths.forEach((stats, fileName) => {
if (!stats.isDirectory() && !gameFiles.includes(fileName)) if (!stats.isDirectory() && !gameFiles.includes(fileName))
@ -35,7 +37,7 @@ export function messageHandler(signaller, msg, paths) {
} }
} }
function removeLeadingSlash(path) { function removeLeadingSlash(path: string) {
const reg = /^\//; const reg = /^\//;
return path.replace(reg, "") return path.replace(reg, "")
} }

View file

@ -1,8 +1,10 @@
class MessageTracker { import type { Message } from '../interfaces';
data = new Map()
#maxLength = 200
push(msg) { class MessageTracker {
data = new Map<string, Message>();
#maxLength = 200;
push(msg: Message) {
this.data.set(msg.id, msg); this.data.set(msg.id, msg);
if (this.data.size > this.#maxLength) { if (this.data.size > this.#maxLength) {
@ -11,9 +13,9 @@ class MessageTracker {
} }
} }
get(index) { get(index: string) {
return this.data.get(index); return this.data.get(index);
} }
} }
export const messageTracker = new MessageTracker(); export const messageTracker = new MessageTracker();

View file

@ -1,16 +1,18 @@
import type { Signal } from 'signal-js';
import { WebSocketServer } from 'ws'; import { WebSocketServer } from 'ws';
import { config } from "../config.js"; import { config } from "../config";
import { EventType } from "../eventTypes.js" import { EventType } from "../eventTypes"
import { requestDefinitionFile } from './messageGenerators.js'; import { Message } from '../interfaces';
import { messageTracker } from "./messageTracker.js" import { requestDefinitionFile } from './messageGenerators';
import { messageTracker } from "./messageTracker"
export function setupSocket(signaller) { export function setupSocket(signaller: Signal) {
const wss = new WebSocketServer({ port: config.get("port") }); const wss = new WebSocketServer({ port: config.get("port") });
wss.on('connection', function connection(ws) { wss.on('connection', function connection(ws) {
function sendMessage(msg) { function sendMessage(msg: Message) {
messageTracker.push(msg); messageTracker.push(msg);
ws.send(JSON.stringify(msg)); ws.send(JSON.stringify(msg));
} }
@ -19,7 +21,7 @@ export function setupSocket(signaller) {
signaller.emit(EventType.MessageReceived, msg); signaller.emit(EventType.MessageReceived, msg);
}); });
signaller.on(EventType.MessageSend, msg => { signaller.on(EventType.MessageSend, (msg: Message) => {
sendMessage(msg); sendMessage(msg);
}); });

10
src/signals.d.ts vendored Normal file
View file

@ -0,0 +1,10 @@
declare module 'signal-js' {
export type Signal = typeof signal;
export default class signal {
static on<T>(event: string, callback: (data: T) => void): void
static emit<T>(event: string, data: T): void
static trigger(event: string): void
}
}