tdlib-native
Version:
🚀 Telegram TDLib native nodejs wrapper
182 lines (181 loc) • 4.52 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const path = require("path");
const path$1 = require("./path.js");
const module$1 = require("module");
const async = require("../shared/async.js");
const builtinAddonPath = path.resolve(
path$1.getAddonFolderPath(),
"..",
"..",
"build",
"Release",
"td.node"
);
async function loadAddon(addonPath = builtinAddonPath) {
const baseDirectory = path$1.getAddonFolderPath();
const load = module$1.createRequire(baseDirectory);
const addon = load(addonPath);
return addon;
}
async function getTDLibPath() {
const { tdlibPath } = await Promise.resolve().then(() => require("../../node_modules/@tdlib-native/tdjson/index.js"));
return tdlibPath;
}
class ReceiveQueueEntry {
constructor(client, promise) {
this.client = client;
this.promise = promise;
Object.freeze(this);
}
}
class ClientMeta {
constructor(timeout) {
this.timeout = timeout;
}
destroyed = false;
}
class TDLibAddon {
/**
* Creates an instance of TDLibAddon.
* @param {Addon} _addon
* @memberof TDLibAddon
*/
constructor(_addon) {
this._addon = _addon;
}
/**
*
*
* @static
* @param {string} [tdlibPath] Resolves to prebuild TDLib for your platform
* @param {string} [addonPath]
* @returns {Promise<TDLib>}
* @memberof TDLibAddon
*/
static async create(tdlibPath, addonPath) {
tdlibPath ??= await getTDLibPath();
const addon = await loadAddon(addonPath);
addon.load_tdjson(tdlibPath);
return new TDLibAddon(addon);
}
_isTDLib = true;
_clients = /* @__PURE__ */ new WeakMap();
/**
*
*
* @readonly
* @memberof TDLibAddon
*/
get name() {
return "addon";
}
/**
*
*
* @returns {TDLibClient} {TDLibClient}
* @memberof TDLibAddon
*/
create(timeout) {
const client = this._addon.td_json_client_create(timeout);
this._clients.set(client, new ClientMeta(timeout));
return client;
}
_getMeta(client) {
const meta = this._clients.get(client);
if (!meta) {
throw new Error("Unknown client");
}
return meta;
}
/**
*
*
* @param {TDLibClient} client
* @memberof TDLibAddon
* @returns {Promise<void>}
*/
async destroy(client) {
if (this._getMeta(client).destroyed) {
throw new Error("Client already destroyed");
}
for (const entry of this._queue) {
if (entry.client === client) {
entry.promise.reject(new Error("Client is destroyed"));
}
}
await this._thread;
this._addon.td_json_client_destroy(client);
}
/**
*
*
* @param {(TDLibClient | null)} client
* @param {string} json
* @returns {(string | null)} {(string | null)}
* @memberof TDLibAddon
*/
execute(client, json) {
return this._addon.td_json_client_execute(client, json);
}
_queue = [];
_thread;
async _receive() {
while (this._queue.length > 0) {
const task = this._queue.shift();
if (!task) break;
await this._addon.td_json_client_receive(task.client).then(task.promise.resolve, task.promise.reject);
}
}
/**
*
*
* @param {TDLibClient} client
* @returns {Promise<string|null>} {(Promise<string | null>)}
* @memberof TDLibAddon
*/
receive(client) {
const meta = this._getMeta(client);
if (meta.destroyed) {
return Promise.reject(new Error("Client is destroyed"));
}
const entryWithSameClient = this._queue.find((entry2) => entry2.client === client);
if (entryWithSameClient) {
return Promise.reject(new Error("This client is already receiving updates"));
}
const promise = async.promiseWithResolvers();
const entry = new ReceiveQueueEntry(client, promise);
this._queue.push(entry);
if (!this._thread) {
this._thread = this._receive().finally(() => {
this._thread = void 0;
});
}
return promise.promise;
}
/**
*
*
* @param {TDLibClient} client
* @param {string} json
* @memberof TDLibAddon
* @returns {void}
*/
send(client, json) {
if (this._getMeta(client).destroyed) {
throw new Error("Client is destroyed");
}
this._addon.td_json_client_send(client, json);
}
/**
*
*
* @param {function(errorMessage: string): void=} callback
* @memberof TDLibAddon
* @returns {void}
*/
setLogMessageCallback(level, callback) {
this._addon.td_set_log_message_callback(level, callback);
}
}
exports.TDLibAddon = TDLibAddon;