UNPKG

tdl

Version:

Node.js bindings to TDLib (Telegram Database library)

199 lines (198 loc) 7.34 kB
"use strict"; /// <reference types="prebuilt-tdlib" /> 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 __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.UnknownError = exports.TDLibError = exports.execute = void 0; exports.configure = configure; exports.init = init; exports.setLogMessageCallback = setLogMessageCallback; exports.createClient = createClient; exports.createBareClient = createBareClient; const path = __importStar(require("node:path")); const debug_1 = __importDefault(require("debug")); const client_1 = require("./client"); Object.defineProperty(exports, "TDLibError", { enumerable: true, get: function () { return client_1.TDLibError; } }); Object.defineProperty(exports, "UnknownError", { enumerable: true, get: function () { return client_1.UnknownError; } }); const addon_1 = require("./addon"); const util_1 = require("./util"); const debug = (0, debug_1.default)('tdl'); let tdjsonAddon = null; const defaultLibraryFile = (() => { switch (process.platform) { case 'win32': return 'tdjson.dll'; case 'darwin': return 'libtdjson.dylib'; default: return 'libtdjson.so'; } })(); const cfg = { tdjson: defaultLibraryFile, libdir: '', verbosityLevel: 1, receiveTimeout: 10, useOldTdjsonInterface: false }; function configure(opts = {}) { if (tdjsonAddon) throw Error('TDLib is already initialized; too late to configure'); if (opts.tdjson != null) cfg.tdjson = opts.tdjson; if (opts.libdir != null) cfg.libdir = opts.libdir; if (opts.verbosityLevel != null) cfg.verbosityLevel = opts.verbosityLevel; if (opts.receiveTimeout != null) cfg.receiveTimeout = opts.receiveTimeout; if (opts.useOldTdjsonInterface != null) cfg.useOldTdjsonInterface = opts.useOldTdjsonInterface; } function init() { if (tdjsonAddon != null) return; debug('Initializing the node addon'); const lib = path.join(cfg.libdir, cfg.tdjson); tdjsonAddon = (0, addon_1.loadAddon)(lib, cfg.useOldTdjsonInterface); if (cfg.verbosityLevel !== 'default') { debug('Executing setLogVerbosityLevel', cfg.verbosityLevel); const request = JSON.stringify({ '@type': 'setLogVerbosityLevel', new_verbosity_level: cfg.verbosityLevel }); const response = !cfg.useOldTdjsonInterface ? tdjsonAddon.tdnew.execute(request) : tdjsonAddon.tdold.execute(null, request); debug('setLogVerbosityLevel response:', response); } } const execute = function execute(request) { if (tdjsonAddon == null) { init(); if (tdjsonAddon == null) throw Error('TDLib is uninitialized'); } debug('execute', request); request = JSON.stringify((0, util_1.deepRenameKey)('_', '@type', request)); const response = !cfg.useOldTdjsonInterface ? tdjsonAddon.tdnew.execute(request) : tdjsonAddon.tdold.execute(null, request); return (0, util_1.deepRenameKey)('@type', '_', JSON.parse(response)); }; exports.execute = execute; function setLogMessageCallback(maxVerbosityLevel, callback) { if (tdjsonAddon == null) { init(); if (tdjsonAddon == null) throw Error('TDLib is uninitialized'); } tdjsonAddon.setLogMessageCallback(maxVerbosityLevel, callback); } const clientMap = new Map(); let tdnInitialized = false; let runningReceiveLoop = false; // Loop for the new tdjson interface async function receiveLoop() { debug('Starting tdn receive loop'); if (tdjsonAddon == null) throw new Error('TDLib is uninitialized'); runningReceiveLoop = true; try { tdjsonAddon.tdnew.ref(); while (true) { if (clientMap.size < 1) { debug('Stopping receive loop'); break; } const responseString = await tdjsonAddon.tdnew.receive(); if (responseString == null) { debug('Receive loop: got empty response'); continue; } const res = JSON.parse(responseString); const clientId = res['@client_id']; const client = clientId != null ? clientMap.get(clientId) : undefined; if (client == null) { debug(`Cannot find client_id ${clientId}`); continue; } delete res['@client_id']; // Note that delete is somewhat slow client.handleReceive(res); } } finally { runningReceiveLoop = false; tdjsonAddon.tdnew.unref(); } } function createAnyClient(opts, bare = false) { if (tdjsonAddon == null) { init(); if (tdjsonAddon == null) throw Error('TDLib is uninitialized'); } const managingOpts = { bare, receiveTimeout: cfg.receiveTimeout, executeFunc: exports.execute, useOldTdjsonInterface: false }; if (cfg.useOldTdjsonInterface) { const tdoManaging = { ...managingOpts, useOldTdjsonInterface: true }; return new client_1.Client(tdjsonAddon, tdoManaging, opts); } if (!tdnInitialized) { tdjsonAddon.tdnew.init(cfg.receiveTimeout); tdnInitialized = true; } const client = new client_1.Client(tdjsonAddon, managingOpts, opts); const clientId = client.getClientId(); clientMap.set(clientId, client); client.once('close', () => { debug(`Deleting client_id ${clientId}`); clientMap.delete(clientId); }); if (!runningReceiveLoop) receiveLoop(); return client; } function createClient(opts) { return createAnyClient(opts); } function createBareClient() { return createAnyClient({}, true); } // TODO: We could possibly export an unsafe/unstable getRawTdjson() : Tdjson // function that allows to access underlying tdjson functions