@filemap/events-sdk
Version:
SDK for Filemap events. Desktop client for Filemap dev server.
196 lines • 7.66 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnixSocketConnectionService = void 0;
const tsyringe_1 = require("tsyringe");
const net_1 = require("net");
const fs_1 = require("fs");
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const logger_service_1 = require("./logger.service");
const config_service_1 = require("./config.service");
const message_handler_service_1 = require("./message-handler.service");
let UnixSocketConnectionService = class UnixSocketConnectionService {
logger;
configService;
messageHandler;
socket = null;
reconnectTimer = null;
buffer = '';
isClosing = false;
socketPath;
constructor(logger, configService, messageHandler) {
this.logger = logger;
this.configService = configService;
this.messageHandler = messageHandler;
this.socketPath = this.getSocketPath();
}
start() {
this.tryConnect();
}
stop() {
this.isClosing = true;
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
if (this.socket) {
this.socket.destroy();
this.socket = null;
}
}
tryConnect() {
if (this.isClosing)
return;
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
try {
this.socket = (0, net_1.connect)(this.socketPath);
this.socket.on('connect', () => {
this.logger.debug('Connected to Unix socket server');
this.sendClientUp();
});
this.socket.on('data', (chunk) => {
this.handleData(chunk);
});
this.socket.on('error', (err) => {
this.handleError(err);
});
this.socket.on('close', () => {
this.handleClose();
});
}
catch (err) {
this.logger.debug(`Failed to create socket: ${err.message}`);
this.scheduleReconnect();
}
}
sendClientUp() {
if (!this.socket || !this.socket.writable)
return;
const config = this.configService.getConfig();
const message = {
event: 'filemap-client-up',
utilized_apis: config.utilizedApis
};
const payload = JSON.stringify(message) + '\n';
this.socket.write(payload);
this.logger.debug('Sent client-up message');
}
handleData(chunk) {
this.buffer += chunk.toString('utf8');
let newlineIndex;
while ((newlineIndex = this.buffer.indexOf('\n')) >= 0) {
const line = this.buffer.slice(0, newlineIndex).trim();
this.buffer = this.buffer.slice(newlineIndex + 1);
if (!line)
continue;
try {
const message = JSON.parse(line);
this.logger.debug(`Received message: ${JSON.stringify(message)}`);
this.messageHandler.handleMessage(message);
}
catch (err) {
this.logger.debug(`Invalid JSON received: ${line}`);
}
}
}
handleError(err) {
if (this.socket) {
this.socket.destroy();
this.socket = null;
}
if (err.message.includes('ECONNREFUSED') ||
err.message.includes('ENOENT') ||
err.message.includes('ENOTSOCK') ||
err.message.includes('EISDIR')) {
this.logger.debug('Server not available, will retry...');
this.scheduleReconnect();
}
else {
this.logger.debug(`Socket error: ${err.message}`);
this.scheduleReconnect();
}
}
handleClose() {
this.logger.debug('Socket closed');
this.socket = null;
if (!this.isClosing) {
this.scheduleReconnect();
}
}
scheduleReconnect() {
if (this.isClosing || this.reconnectTimer)
return;
const config = this.configService.getConfig();
this.logger.debug(`Scheduling reconnect in ${config.reconnectInterval}ms`);
this.reconnectTimer = setTimeout(() => {
this.reconnectTimer = null;
this.tryConnect();
}, config.reconnectInterval);
}
getSocketPath() {
if (os.platform() === 'win32') {
return '\\\\.\\pipe\\filemap-desktop-sock';
}
const dir = process.env.XDG_RUNTIME_DIR ||
(process.env.HOME ? path.join(process.env.HOME, '.filemap') : '/tmp');
if (!(0, fs_1.existsSync)(dir)) {
try {
(0, fs_1.mkdirSync)(dir, { recursive: true });
}
catch (err) {
this.logger.debug(`Failed to create directory ${dir}: ${err.message}`);
}
}
return path.join(dir, 'filemap-desktop.sock');
}
};
exports.UnixSocketConnectionService = UnixSocketConnectionService;
exports.UnixSocketConnectionService = UnixSocketConnectionService = __decorate([
(0, tsyringe_1.singleton)(),
(0, tsyringe_1.injectable)(),
__param(0, (0, tsyringe_1.inject)(logger_service_1.Logger)),
__param(1, (0, tsyringe_1.inject)(config_service_1.ConfigService)),
__param(2, (0, tsyringe_1.inject)(message_handler_service_1.MessageHandlerService)),
__metadata("design:paramtypes", [logger_service_1.Logger,
config_service_1.ConfigService,
message_handler_service_1.MessageHandlerService])
], UnixSocketConnectionService);
//# sourceMappingURL=unix-socket-connection.service.js.map