"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.__tsfTypeAliases = exports.MeshService = exports.MeshNoHandlerError = exports.MeshHandlerError = exports.MeshRequestTimeoutError = void 0;
exports.destroyMeshRedis = destroyMeshRedis;
const tslib_1 = require("tslib");
const _a = tslib_1.__importStar(require("@zyno-io/ts-server-foundation/type-metadata-runtime"));
const node_crypto_1 = require("node:crypto");
const node_os_1 = require("node:os");
const redis_1 = require("../helpers/redis/redis");
const leader_1 = require("./leader");
const logger_1 = require("./logger");
const __tsf_metadata_type = _a.createCompactMetadataRegistryV1("[1,[{\"kind\":7},{\"kind\":6},{\"kind\":2,\"typeName\":\"K\"},{\"kind\":2,\"typeName\":\"(data: T[K]['request']) =\\u003e T[K]['response'] | Promise\\u003cT[K]['response']\\u003e\"},{\"kind\":3},{\"kind\":2,\"typeName\":\"(data: B[K], senderInstanceId: number) =\\u003e void | Promise\\u003cvoid\\u003e\"},{\"kind\":2,\"typeName\":\"(instanceId: number) =\\u003e void | Promise\\u003cvoid\\u003e\"},{\"kind\":22,\"type\":{\"kind\":14,\"type\":{\"kind\":18,\"typeName\":\"MeshNode\",\"types\":[{\"kind\":20,\"name\":\"instanceId\",\"type\":{\"kind\":7},\"optional\":false},{\"kind\":20,\"name\":\"hostname\",\"type\":{\"kind\":6},\"optional\":false},{\"kind\":20,\"name\":\"self\",\"type\":{\"kind\":8},\"optional\":false}]}}},{\"kind\":2,\"typeName\":\"T[K]['request']\"},{\"kind\":22,\"type\":{\"kind\":2,\"typeName\":\"T[K]['response']\"}},{\"kind\":2,\"typeName\":\"B[K]\"},{\"kind\":18,\"typeName\":\"MeshBroadcastOptions\",\"types\":[{\"kind\":20,\"name\":\"skipSelf\",\"type\":{\"kind\":12,\"types\":[{\"kind\":8},{\"kind\":4}]},\"optional\":true}]},{\"kind\":22,\"type\":{\"kind\":3}},{\"kind\":18,\"typeName\":\"MeshServiceOptions\",\"types\":[{\"kind\":20,\"name\":\"heartbeatIntervalMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"nodeTtlMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"requestTimeoutMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"leaderOptions\",\"type\":{\"kind\":12,\"types\":[{\"kind\":18,\"typeName\":\"LeaderServiceOptions\",\"types\":[{\"kind\":20,\"name\":\"ttlMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"renewalIntervalMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"retryDelayMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true}]},{\"kind\":4}]},\"optional\":true}]}]]", []);
let _MeshRequestTimeoutErrorMetadata_1;
class MeshRequestTimeoutError extends Error {
    constructor(instanceId, type) {
        super(`Mesh request to instance ${instanceId} timed out (type: ${type})`);
        this.name = 'MeshRequestTimeoutError';
    }
    static __tsfType = _MeshRequestTimeoutErrorMetadata_1 = _a.decodeCompactMetadataV1("[1,{\"kind\":16,\"name\":\"MeshRequestTimeoutError\",\"typeName\":\"MeshRequestTimeoutError\",\"classType\":{\"$tsf\":0},\"properties\":[],\"methods\":[],\"hasConstructor\":true,\"constructorParameters\":[{\"name\":\"instanceId\",\"type\":{\"$tsfType\":0},\"optional\":false,\"default\":false},{\"name\":\"type\",\"type\":{\"$tsfType\":1},\"optional\":false,\"default\":false}]}]", [() => MeshRequestTimeoutError], __tsf_metadata_type);
}
exports.MeshRequestTimeoutError = MeshRequestTimeoutError;
_MeshRequestTimeoutErrorMetadata_1.classType = MeshRequestTimeoutError;
MeshRequestTimeoutError.__tsfType = _MeshRequestTimeoutErrorMetadata_1;
let _MeshHandlerErrorMetadata_1;
class MeshHandlerError extends Error {
    constructor(message) {
        super(message);
        this.name = 'MeshHandlerError';
    }
    static __tsfType = _MeshHandlerErrorMetadata_1 = _a.decodeCompactMetadataV1("[1,{\"kind\":16,\"name\":\"MeshHandlerError\",\"typeName\":\"MeshHandlerError\",\"classType\":{\"$tsf\":0},\"properties\":[],\"methods\":[],\"hasConstructor\":true,\"constructorParameters\":[{\"name\":\"message\",\"type\":{\"$tsfType\":1},\"optional\":false,\"default\":false}]}]", [() => MeshHandlerError], __tsf_metadata_type);
}
exports.MeshHandlerError = MeshHandlerError;
_MeshHandlerErrorMetadata_1.classType = MeshHandlerError;
MeshHandlerError.__tsfType = _MeshHandlerErrorMetadata_1;
let _MeshNoHandlerErrorMetadata_1;
class MeshNoHandlerError extends Error {
    constructor(type) {
        super(`No handler registered for mesh message type: ${type}`);
        this.name = 'MeshNoHandlerError';
    }
    static __tsfType = _MeshNoHandlerErrorMetadata_1 = _a.decodeCompactMetadataV1("[1,{\"kind\":16,\"name\":\"MeshNoHandlerError\",\"typeName\":\"MeshNoHandlerError\",\"classType\":{\"$tsf\":0},\"properties\":[],\"methods\":[],\"hasConstructor\":true,\"constructorParameters\":[{\"name\":\"type\",\"type\":{\"$tsfType\":1},\"optional\":false,\"default\":false}]}]", [() => MeshNoHandlerError], __tsf_metadata_type);
}
exports.MeshNoHandlerError = MeshNoHandlerError;
_MeshNoHandlerErrorMetadata_1.classType = MeshNoHandlerError;
MeshNoHandlerError.__tsfType = _MeshNoHandlerErrorMetadata_1;
// --- Constants ---
const NO_HANDLER_ERROR_PREFIX = 'MESH_NO_HANDLER:';
// --- Lua Scripts ---
const HEARTBEAT_SCRIPT = `
local time = redis.call("time")
local now_ms = tonumber(time[1]) * 1000 + math.floor(tonumber(time[2]) / 1000)
redis.call("zadd", KEYS[1], now_ms, ARGV[1])
return 1
`;
const CLEANUP_SCRIPT = `
local time = redis.call("time")
local now_ms = tonumber(time[1]) * 1000 + math.floor(tonumber(time[2]) / 1000)
local cutoff = now_ms - tonumber(ARGV[1])
local expired = redis.call("zrangebyscore", KEYS[1], "-inf", cutoff)
for i, id in ipairs(expired) do
    redis.call("zrem", KEYS[1], id)
    redis.call("hdel", KEYS[2], id)
end
return expired
`;
const DEREGISTER_SCRIPT = `
redis.call("zrem", KEYS[1], ARGV[1])
redis.call("hdel", KEYS[2], ARGV[1])
return 1
`;
let meshRedis = null;
function getMeshRedis() {
    if (!meshRedis) {
        const { client, prefix } = (0, redis_1.createRedis)('MESH');
        client.defineCommand('HEARTBEAT', { lua: HEARTBEAT_SCRIPT, numberOfKeys: 1 });
        client.defineCommand('CLEANUP', { lua: CLEANUP_SCRIPT, numberOfKeys: 2 });
        client.defineCommand('DEREGISTER', { lua: DEREGISTER_SCRIPT, numberOfKeys: 2 });
        meshRedis = { client: client, prefix };
    }
    return meshRedis;
}
function destroyMeshRedis() {
    if (meshRedis) {
        meshRedis.client.disconnect();
        meshRedis = null;
    }
}
let _MeshServiceMetadata_1;
// --- MeshService ---
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
class MeshService {
    _instanceId = 0;
    key;
    prefix = '';
    running = false;
    heartbeatIntervalMs;
    nodeTtlMs;
    requestTimeoutMs;
    leaderOptions;
    heartbeatTimer = null;
    leaderService = null;
    subscriberClient = null;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    handlers = new Map();
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    broadcastHandlers = new Map();
    pendingRequests = new Map();
    activeHandlerIntervals = new Set();
    nodeCleanedUpCallback = null;
    logger = (0, logger_1.createLogger)(this);
    constructor(key, options) {
        this.key = key;
        this.heartbeatIntervalMs = options?.heartbeatIntervalMs ?? 5000;
        this.nodeTtlMs = options?.nodeTtlMs ?? 15000;
        this.requestTimeoutMs = options?.requestTimeoutMs ?? 10000;
        this.leaderOptions = options?.leaderOptions;
    }
    get instanceId() {
        return this._instanceId;
    }
    registerHandler(type, handler) {
        this.handlers.set(type, handler);
    }
    registerBroadcastHandler(type, handler) {
        this.broadcastHandlers.set(type, handler);
    }
    setNodeCleanedUpCallback(cb) {
        this.nodeCleanedUpCallback = cb;
    }
    async getNodes() {
        if (!this.running) {
            throw new Error('MeshService is not running');
        }
        const { client } = getMeshRedis();
        const members = await client.zrange(this.heartbeatsKey(), 0, -1);
        if (members.length === 0)
            return [];
        const hostnames = await client.hmget(this.nodesKey(), ...members);
        return members.map((id, i) => ({
            instanceId: parseInt(id, 10),
            hostname: hostnames[i] ?? 'unknown',
            self: parseInt(id, 10) === this._instanceId
        }));
    }
    async invoke(instanceId, type, data, timeoutMs) {
        if (!this.running) {
            throw new Error('MeshService is not running');
        }
        const effectiveTimeout = timeoutMs ?? this.requestTimeoutMs;
        // Local invocation - call handler directly
        if (instanceId === this._instanceId) {
            const handler = this.handlers.get(type);
            if (!handler)
                throw new MeshNoHandlerError(type);
            return handler(data);
        }
        // Remote invocation via pub/sub
        const requestId = (0, node_crypto_1.randomUUID)();
        const channel = this.channelForInstance(instanceId);
        // Serialize before registering pending request to avoid leaked timers on stringify failure
        const message = {
            requestId,
            senderInstanceId: this._instanceId,
            type,
            data,
            timeoutMs: effectiveTimeout
        };
        const payload = JSON.stringify(message);
        return new Promise((resolve, reject) => {
            const timer = setTimeout(() => {
                this.pendingRequests.delete(requestId);
                reject(new MeshRequestTimeoutError(instanceId, type));
            }, effectiveTimeout);
            this.pendingRequests.set(requestId, {
                resolve: resolve,
                reject,
                timer,
                type,
                targetInstanceId: instanceId,
                timeoutMs: effectiveTimeout
            });
            const { client } = getMeshRedis();
            client.publish(channel, payload).catch(err => {
                clearTimeout(timer);
                this.pendingRequests.delete(requestId);
                reject(new Error(`Failed to publish mesh request: ${err instanceof Error ? err.message : String(err)}`));
            });
        });
    }
    async broadcast(type, data, options) {
        if (!this.running) {
            throw new Error('MeshService is not running');
        }
        const message = {
            broadcast: true,
            senderInstanceId: this._instanceId,
            type,
            data
        };
        // Deliver locally unless skipSelf
        if (!options?.skipSelf) {
            this.handleBroadcastMessage(message);
        }
        const { client } = getMeshRedis();
        await client.publish(this.broadcastChannel(), JSON.stringify(message));
    }
    async start() {
        if (this.running) {
            throw new Error('MeshService is already running');
        }
        const { client, prefix } = getMeshRedis();
        this.prefix = prefix;
        // Acquire unique instance ID
        this._instanceId = await client.incr(this.nextIdKey());
        // Create subscriber and subscribe to own channel
        const { client: subClient } = (0, redis_1.createRedis)('MESH');
        this.subscriberClient = subClient;
        try {
            const instanceChannel = this.channelForInstance(this._instanceId);
            const broadcastCh = this.broadcastChannel();
            await subClient.subscribe(instanceChannel, broadcastCh);
            subClient.on('message', (channel, message) => {
                if (channel === broadcastCh) {
                    this.handleBroadcastIncoming(message);
                }
                else {
                    this.handleMessage(message);
                }
            });
            // Register heartbeat and node metadata
            await client.HEARTBEAT(this.heartbeatsKey(), String(this._instanceId));
            await client.hset(this.nodesKey(), String(this._instanceId), (0, node_os_1.hostname)());
        }
        catch (err) {
            // Clean up subscriber on partial init failure
            try {
                await subClient.unsubscribe();
                await subClient.quit();
            }
            catch {
                // ignore cleanup errors
            }
            this.subscriberClient = null;
            const failedInstanceId = this._instanceId;
            this._instanceId = 0;
            if (failedInstanceId !== 0) {
                try {
                    await client.DEREGISTER(this.heartbeatsKey(), this.nodesKey(), String(failedInstanceId));
                }
                catch {
                    // Preserve the startup failure; normal TTL/leader cleanup is the fallback.
                }
            }
            throw err;
        }
        this.running = true;
        // Start heartbeat interval
        this.heartbeatTimer = setInterval(() => this.doHeartbeat(), this.heartbeatIntervalMs);
        // Start leader service for cleanup duties
        this.leaderService = new leader_1.LeaderService(`mesh:${this.key}`, this.leaderOptions);
        this.leaderService.start();
        this.logger.info('mesh node started', { instanceId: this._instanceId, key: this.key });
    }
    async stop() {
        this.running = false;
        // Stop leader service
        if (this.leaderService) {
            await this.leaderService.stop();
            this.leaderService = null;
        }
        // Stop heartbeat
        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer);
            this.heartbeatTimer = null;
        }
        // Clear all active handler heartbeat intervals
        for (const interval of this.activeHandlerIntervals) {
            clearInterval(interval);
        }
        this.activeHandlerIntervals.clear();
        // Reject all pending requests
        for (const [requestId, pending] of this.pendingRequests) {
            clearTimeout(pending.timer);
            pending.reject(new Error('MeshService stopped'));
            this.pendingRequests.delete(requestId);
        }
        // Unsubscribe and quit subscriber
        if (this.subscriberClient) {
            try {
                await this.subscriberClient.unsubscribe();
                await this.subscriberClient.quit();
            }
            catch {
                // ignore errors during cleanup
            }
            this.subscriberClient = null;
        }
        // Atomically remove self from heartbeats and nodes
        if (this._instanceId !== 0) {
            const stoppedInstanceId = this._instanceId;
            this._instanceId = 0;
            try {
                const { client } = getMeshRedis();
                await client.DEREGISTER(this.heartbeatsKey(), this.nodesKey(), String(stoppedInstanceId));
            }
            catch {
                // ignore errors during cleanup
            }
            this.logger.info('mesh node stopped', { instanceId: stoppedInstanceId, key: this.key });
        }
    }
    // --- Private ---
    nextIdKey() {
        return `${this.prefix}:mesh:${this.key}:next_id`;
    }
    heartbeatsKey() {
        return `${this.prefix}:mesh:${this.key}:heartbeats`;
    }
    nodesKey() {
        return `${this.prefix}:mesh:${this.key}:nodes`;
    }
    channelForInstance(instanceId) {
        return `${this.prefix}:mesh:${this.key}:node:${instanceId}`;
    }
    broadcastChannel() {
        return `${this.prefix}:mesh:${this.key}:broadcast`;
    }
    async doHeartbeat() {
        if (!this.running)
            return;
        try {
            const { client } = getMeshRedis();
            await client.HEARTBEAT(this.heartbeatsKey(), String(this._instanceId));
        }
        catch (err) {
            this.logger.warn('mesh heartbeat failed', { err });
        }
        // If leader, run cleanup
        if (this.leaderService?.isLeader) {
            await this.doCleanup();
        }
    }
    async doCleanup() {
        try {
            const { client } = getMeshRedis();
            const expired = await client.CLEANUP(this.heartbeatsKey(), this.nodesKey(), String(this.nodeTtlMs));
            if (expired.length > 0) {
                this.logger.info('cleaned up expired mesh nodes', { expired });
                for (const idStr of expired) {
                    const id = parseInt(idStr, 10);
                    try {
                        await this.nodeCleanedUpCallback?.(id);
                    }
                    catch (err) {
                        this.logger.warn('node cleanup callback error', { err, instanceId: id });
                    }
                }
            }
        }
        catch (err) {
            this.logger.warn('mesh cleanup failed', { err });
        }
    }
    handleBroadcastIncoming(raw) {
        if (!this.running)
            return;
        let msg;
        try {
            msg = JSON.parse(raw);
        }
        catch {
            return;
        }
        if (typeof msg !== 'object' || msg === null)
            return;
        const obj = msg;
        // Skip self-sent broadcasts (we already delivered locally in broadcast())
        if (obj.senderInstanceId === this._instanceId)
            return;
        this.handleBroadcastMessage(obj);
    }
    handleBroadcastMessage(msg) {
        const handler = this.broadcastHandlers.get(msg.type);
        if (!handler)
            return;
        Promise.resolve()
            .then(() => handler(msg.data, msg.senderInstanceId))
            .catch(err => {
            this.logger.warn('broadcast handler error', { err, type: msg.type });
        });
    }
    handleMessage(raw) {
        if (!this.running)
            return;
        let msg;
        try {
            msg = JSON.parse(raw);
        }
        catch (err) {
            this.logger.warn('failed to parse mesh message', { err, raw });
            return;
        }
        if (typeof msg !== 'object' || msg === null) {
            this.logger.warn('invalid mesh message: not an object', { raw });
            return;
        }
        const obj = msg;
        if ('heartbeat' in obj && obj.heartbeat) {
            this.handleHeartbeatMessage(obj);
        }
        else if ('reply' in obj && obj.reply) {
            this.handleResponseMessage(obj);
        }
        else {
            this.handleRequestMessage(obj);
        }
    }
    handleHeartbeatMessage(msg) {
        const pending = this.pendingRequests.get(msg.requestId);
        if (!pending)
            return;
        // Reset timeout using the original per-request timeout
        clearTimeout(pending.timer);
        pending.timer = setTimeout(() => {
            this.pendingRequests.delete(msg.requestId);
            pending.reject(new MeshRequestTimeoutError(pending.targetInstanceId, pending.type));
        }, pending.timeoutMs);
    }
    handleResponseMessage(msg) {
        const pending = this.pendingRequests.get(msg.requestId);
        if (!pending)
            return;
        clearTimeout(pending.timer);
        this.pendingRequests.delete(msg.requestId);
        if (msg.error !== undefined) {
            if (typeof msg.error === 'string' && msg.error.startsWith(NO_HANDLER_ERROR_PREFIX)) {
                pending.reject(new MeshNoHandlerError(msg.error.slice(NO_HANDLER_ERROR_PREFIX.length)));
            }
            else {
                pending.reject(new MeshHandlerError(msg.error));
            }
        }
        else {
            pending.resolve(msg.data);
        }
    }
    handleRequestMessage(msg) {
        if (!this.running)
            return;
        if (typeof msg.requestId !== 'string' || typeof msg.senderInstanceId !== 'number' || typeof msg.type !== 'string') {
            this.logger.warn('invalid mesh request: missing or malformed fields', { msg });
            return;
        }
        const handler = this.handlers.get(msg.type);
        const { client } = getMeshRedis();
        const senderChannel = this.channelForInstance(msg.senderInstanceId);
        if (!handler) {
            const response = {
                requestId: msg.requestId,
                reply: true,
                error: `${NO_HANDLER_ERROR_PREFIX}${msg.type}`
            };
            client.publish(senderChannel, JSON.stringify(response)).catch(err => {
                this.logger.warn('failed to publish no-handler response', { err });
            });
            return;
        }
        // Use the caller's timeout for heartbeat interval (fall back to our own)
        const effectiveTimeoutMs = msg.timeoutMs ?? this.requestTimeoutMs;
        const heartbeatInterval = setInterval(() => {
            const heartbeat = {
                requestId: msg.requestId,
                heartbeat: true
            };
            client.publish(senderChannel, JSON.stringify(heartbeat)).catch(err => {
                this.logger.warn('failed to publish handler heartbeat', { err });
            });
        }, effectiveTimeoutMs * 0.75);
        this.activeHandlerIntervals.add(heartbeatInterval);
        // Execute handler
        Promise.resolve()
            .then(() => handler(msg.data))
            .then(result => {
            clearInterval(heartbeatInterval);
            this.activeHandlerIntervals.delete(heartbeatInterval);
            const response = {
                requestId: msg.requestId,
                reply: true,
                data: result
            };
            client.publish(senderChannel, JSON.stringify(response)).catch(err => {
                this.logger.warn('failed to publish handler response', { err });
            });
        })
            .catch(err => {
            clearInterval(heartbeatInterval);
            this.activeHandlerIntervals.delete(heartbeatInterval);
            const response = {
                requestId: msg.requestId,
                reply: true,
                error: err instanceof Error ? err.message : String(err)
            };
            client.publish(senderChannel, JSON.stringify(response)).catch(publishErr => {
                this.logger.warn('failed to publish handler error response', { err: publishErr });
            });
        });
    }
    static __tsfType = _MeshServiceMetadata_1 = _a.decodeCompactMetadataV1("[1,{\"kind\":16,\"name\":\"MeshService\",\"typeName\":\"MeshService\",\"classType\":{\"$tsf\":0},\"properties\":[],\"methods\":[{\"name\":\"registerHandler\",\"parameters\":[{\"name\":\"type\",\"type\":{\"$tsfType\":2},\"optional\":false,\"default\":false},{\"name\":\"handler\",\"type\":{\"$tsfType\":3},\"optional\":false,\"default\":false}],\"returnType\":{\"$tsfType\":4}},{\"name\":\"registerBroadcastHandler\",\"parameters\":[{\"name\":\"type\",\"type\":{\"$tsfType\":2},\"optional\":false,\"default\":false},{\"name\":\"handler\",\"type\":{\"$tsfType\":5},\"optional\":false,\"default\":false}],\"returnType\":{\"$tsfType\":4}},{\"name\":\"setNodeCleanedUpCallback\",\"parameters\":[{\"name\":\"cb\",\"type\":{\"$tsfType\":6},\"optional\":false,\"default\":false}],\"returnType\":{\"$tsfType\":4}},{\"name\":\"getNodes\",\"parameters\":[],\"returnType\":{\"$tsfType\":7}},{\"name\":\"invoke\",\"parameters\":[{\"name\":\"instanceId\",\"type\":{\"$tsfType\":0},\"optional\":false,\"default\":false},{\"name\":\"type\",\"type\":{\"$tsfType\":2},\"optional\":false,\"default\":false},{\"name\":\"data\",\"type\":{\"$tsfType\":8},\"optional\":false,\"default\":false},{\"name\":\"timeoutMs\",\"type\":{\"$tsfType\":0},\"optional\":true,\"default\":false}],\"returnType\":{\"$tsfType\":9}},{\"name\":\"broadcast\",\"parameters\":[{\"name\":\"type\",\"type\":{\"$tsfType\":2},\"optional\":false,\"default\":false},{\"name\":\"data\",\"type\":{\"$tsfType\":10},\"optional\":false,\"default\":false},{\"name\":\"options\",\"type\":{\"$tsfType\":11},\"optional\":true,\"default\":false}],\"returnType\":{\"$tsfType\":12}},{\"name\":\"start\",\"parameters\":[],\"returnType\":{\"$tsfType\":12}},{\"name\":\"stop\",\"parameters\":[],\"returnType\":{\"$tsfType\":12}}],\"hasConstructor\":true,\"constructorParameters\":[{\"name\":\"key\",\"type\":{\"$tsfType\":1},\"optional\":false,\"default\":false},{\"name\":\"options\",\"type\":{\"$tsfType\":13},\"optional\":true,\"default\":false}]}]", [() => MeshService], __tsf_metadata_type);
}
exports.MeshService = MeshService;
_MeshServiceMetadata_1.classType = MeshService;
MeshService.__tsfType = _MeshServiceMetadata_1;
exports.__tsfTypeAliases = _a.decodeCompactMetadataV1("[1,{\"MeshBroadcastMap\":{\"kind\":18,\"typeName\":\"Record\",\"utilityType\":\"Record\",\"typeArguments\":[{\"kind\":6},{\"kind\":2}],\"index\":{\"kind\":2},\"types\":[],\"typeName\":\"MeshBroadcastMap\"},\"MeshBroadcastOptions\":{\"kind\":18,\"typeName\":\"MeshBroadcastOptions\",\"types\":[{\"kind\":20,\"name\":\"skipSelf\",\"type\":{\"kind\":12,\"types\":[{\"kind\":8},{\"kind\":4}]},\"optional\":true}]},\"MeshMessageMap\":{\"kind\":18,\"typeName\":\"Record\",\"utilityType\":\"Record\",\"typeArguments\":[{\"kind\":6},{\"kind\":18,\"types\":[{\"kind\":20,\"name\":\"request\",\"type\":{\"kind\":2},\"optional\":false},{\"kind\":20,\"name\":\"response\",\"type\":{\"kind\":2},\"optional\":false}]}],\"index\":{\"kind\":18,\"types\":[{\"kind\":20,\"name\":\"request\",\"type\":{\"kind\":2},\"optional\":false},{\"kind\":20,\"name\":\"response\",\"type\":{\"kind\":2},\"optional\":false}]},\"types\":[],\"typeName\":\"MeshMessageMap\"},\"MeshNode\":{\"kind\":18,\"typeName\":\"MeshNode\",\"types\":[{\"kind\":20,\"name\":\"instanceId\",\"type\":{\"kind\":7},\"optional\":false},{\"kind\":20,\"name\":\"hostname\",\"type\":{\"kind\":6},\"optional\":false},{\"kind\":20,\"name\":\"self\",\"type\":{\"kind\":8},\"optional\":false}]},\"MeshServiceOptions\":{\"kind\":18,\"typeName\":\"MeshServiceOptions\",\"types\":[{\"kind\":20,\"name\":\"heartbeatIntervalMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"nodeTtlMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"requestTimeoutMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"leaderOptions\",\"type\":{\"kind\":12,\"types\":[{\"kind\":18,\"typeName\":\"LeaderServiceOptions\",\"types\":[{\"kind\":20,\"name\":\"ttlMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"renewalIntervalMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"retryDelayMs\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true}]},{\"kind\":4}]},\"optional\":true}]}}]", [], __tsf_metadata_type);
//# sourceMappingURL=mesh.js.map