@fdm-monster/server
Version:
FDM Monster is a bulk OctoPrint, Klipper, PrusaLink and BambuLab manager to set up, configure and monitor 3D printers. Our aim is to provide neat overview over your farm.
158 lines (157 loc) • 5.34 kB
JavaScript
import "../services/printer-api.interface.js";
import { printerEvents } from "../constants/event.constants.js";
import { errorSummary } from "../utils/error.utils.js";
import { captureException } from "@sentry/node";
//#region src/state/printer-socket.store.ts
var PrinterSocketStore = class PrinterSocketStore {
printerSocketAdaptersById = /* @__PURE__ */ new Map();
logger;
constructor(loggerFactory, socketFactory, eventEmitter2, printerCache) {
this.socketFactory = socketFactory;
this.eventEmitter2 = eventEmitter2;
this.printerCache = printerCache;
this.logger = loggerFactory(PrinterSocketStore.name);
this.subscribeToEvents();
}
getSocketStatesById() {
const socketStatesById = {};
this.printerSocketAdaptersById.forEach((s) => {
if (!s.printerId) return;
socketStatesById[s.printerId] = {
printerId: s.printerId,
printerType: s.printerType,
socket: s.socketState,
api: s.apiState
};
});
return socketStatesById;
}
async loadPrinterSockets() {
await this.printerCache.loadCache();
const printerDtoList = await this.printerCache.listCachedPrinters(false);
this.printerSocketAdaptersById.clear();
for (const printerDto of printerDtoList) try {
this.createOrUpdateSocket(printerDto);
} catch (e) {
captureException(e);
this.logger.error("PrinterSocketStore failed to construct new socket.", errorSummary(e));
}
this.logger.log(`Loaded ${this.printerSocketAdaptersById.size} printer sockets`);
}
listPrinterSockets() {
return Array.from(this.printerSocketAdaptersById.values());
}
reconnectPrinterAdapter(id) {
const socket = this.getPrinterSocket(id);
if (!socket) return;
socket.close();
socket.resetSocketState();
}
getPrinterSocket(id) {
return this.printerSocketAdaptersById.get(id);
}
/**
* Sets up the new WebSocket connections for all printers
*/
async reconnectPrinterSockets() {
let reauthRequested = 0;
let socketSetupRequested = 0;
const socketStates = {};
const apiStates = {};
const promisesReauth = [];
for (const socket of this.printerSocketAdaptersById.values()) try {
if (socket.printerType === 0 && socket.needsReauth()) {
reauthRequested++;
const promise = socket.reauthSession().catch();
promisesReauth.push(promise);
}
} catch (e) {
captureException(e);
}
await Promise.all(promisesReauth);
const promisesOpenSocket = [];
for (const socket of this.printerSocketAdaptersById.values()) {
try {
if (socket.needsSetup() || socket.needsReopen()) {
socketSetupRequested++;
const promise = socket.setupSocketSession().then(() => {
socket.open();
}).catch();
promisesOpenSocket.push(promise);
}
} catch (e) {
captureException(e);
}
const keySocket = socket.socketState;
const valSocket = socketStates[keySocket];
socketStates[keySocket] = valSocket ? valSocket + 1 : 1;
const keyApi = socket.apiState;
const valApi = apiStates[keyApi];
apiStates[keyApi] = valApi ? valApi + 1 : 1;
}
await Promise.all(promisesOpenSocket);
}
createOrUpdateSocket(printer) {
const { enabled, id } = printer;
let foundAdapter = this.printerSocketAdaptersById.get(id);
if (!enabled) {
this.logger.log(`Printer is disabled. Deleting socket`);
this.deleteSocket(id);
return;
}
if (foundAdapter) if (foundAdapter.printerType === printer.printerType) {
foundAdapter.close();
this.logger.log(`Closing printer socket for update`);
} else {
this.logger.log(`Printer type changed from ${foundAdapter.printerType} to ${printer.printerType}. Creating new socket adapter`);
foundAdapter.close();
foundAdapter = this.socketFactory.createInstance(printer.printerType);
this.printerSocketAdaptersById.set(id, foundAdapter);
}
else {
foundAdapter = this.socketFactory.createInstance(printer.printerType);
this.printerSocketAdaptersById.set(id, foundAdapter);
}
foundAdapter.registerCredentials({
printerId: printer.id,
loginDto: {
apiKey: printer.apiKey,
username: printer.username,
password: printer.password,
printerURL: printer.printerURL,
printerType: printer.printerType
}
});
foundAdapter.resetSocketState();
}
handleBatchPrinterCreated(event) {
for (const printer of event.printers) this.handlePrinterCreated({ printer });
}
handlePrinterCreated(event) {
this.createOrUpdateSocket(event.printer);
}
handlePrinterUpdated(event) {
this.logger.log(`Printer updated. Updating socket`);
this.createOrUpdateSocket(event.printer);
}
handlePrintersDeleted(event) {
event.printerIds.forEach((id) => {
this.deleteSocket(id);
});
}
subscribeToEvents() {
this.eventEmitter2.on(printerEvents.printerCreated, this.handlePrinterCreated.bind(this));
this.eventEmitter2.on(printerEvents.printersDeleted, this.handlePrintersDeleted.bind(this));
this.eventEmitter2.on(printerEvents.printerUpdated, this.handlePrinterUpdated.bind(this));
this.eventEmitter2.on(printerEvents.batchPrinterCreated, this.handleBatchPrinterCreated.bind(this));
}
deleteSocket(printerId) {
const socket = this.printerSocketAdaptersById.get(printerId);
socket?.disallowEmittingEvents();
socket?.close();
this.printerSocketAdaptersById.delete(printerId);
}
};
//#endregion
export { PrinterSocketStore };
//# sourceMappingURL=printer-socket.store.js.map