UNPKG

@nexe/config-manager

Version:

Nexe Config Manager - A flexible configuration management solution with multiple sources and hot reload support

169 lines 5.33 kB
import { __decorate, __metadata } from "tslib"; import { createLogger } from '@nexe/logger'; import { injectable } from 'tsyringe'; const logger = createLogger('RemoteApiConfigSource'); /** * 远程API配置源 */ let RemoteApiConfigSource = class RemoteApiConfigSource { /** * @param baseUrl 远程API基础URL * @param headers 请求头 * @param pollingInterval 轮询间隔(毫秒),如果设置则启用轮询更新 */ constructor(baseUrl, headers = {}, pollingInterval) { this.cache = {}; this.callbacks = new Map(); this.baseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; this.headers = headers; this.pollingInterval = pollingInterval; if (this.pollingInterval && this.pollingInterval > 0) { this.startPolling(); } } /** * 从远程API加载配置 */ async load(key, _pathPrefix) { try { if (Object.keys(this.cache).length === 0) { await this.fetchAllConfig(); } if (!key) { return this.cache; } return this.getNestedValue(this.cache, key); } catch (error) { logger.error(`从远程API加载配置失败: ${error instanceof Error ? error.message : String(error)}`); return undefined; } } /** * 获取配置源名称 */ getName() { return `RemoteApiConfigSource(${this.baseUrl})`; } /** * 是否支持热更新 */ supportsHotReload() { return !!this.pollingInterval; } /** * 订阅配置变更 */ subscribe(key, callback) { if (!this.supportsHotReload()) { logger.warn('此配置源未启用热更新,无法订阅变更'); return; } const callbacks = this.callbacks.get(key) ?? []; callbacks.push(callback); this.callbacks.set(key, callbacks); } /** * 取消订阅配置变更 */ unsubscribe(key) { this.callbacks.delete(key); } /** * 开始轮询更新 */ startPolling() { if (this.pollingTimer) { clearInterval(this.pollingTimer); } this.pollingTimer = setInterval(() => { this.pollForChanges().catch(error => { logger.error(`轮询配置更新失败: ${error instanceof Error ? error.message : String(error)}`); }); }, this.pollingInterval); } /** * 轮询检查配置变更 */ async pollForChanges() { const oldCache = { ...this.cache }; await this.fetchAllConfig(); // 通知所有订阅者 this.callbacks.forEach((callbacks, key) => { const newValue = this.getNestedValue(this.cache, key); const oldValue = this.getNestedValue(oldCache, key); if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) { callbacks.forEach(callback => callback(newValue)); } }); } /** * 获取特定键的配置值 */ // private async fetchConfig(key: string): Promise<unknown> { // try { // const url = `${this.baseUrl}/config/${encodeURIComponent(key)}`; // const response = await fetch(url, { headers: this.headers }); // if (!response.ok) { // throw new Error( // `API返回错误: ${response.status} ${response.statusText}`, // ); // } // const data = await response.json() as { value?: unknown }; // return data.value; // 根据实际API响应格式调整 // } catch (error) { // logger.error( // `获取配置值失败: ${error instanceof Error ? error.message : String(error)}`, // ); // return undefined; // } // } /** * 获取所有配置 */ async fetchAllConfig() { try { const url = `${this.baseUrl}/config`; const response = await fetch(url, { headers: this.headers }); if (!response.ok) { throw new Error(`API返回错误: ${response.status} ${response.statusText}`); } const data = (await response.json()); this.cache = data; } catch (error) { throw new Error(`获取所有配置失败: ${error instanceof Error ? error.message : String(error)}`); } } /** * 获取嵌套对象的属性值 */ getNestedValue(obj, key) { const parts = key.split('.'); let current = obj; for (const part of parts) { if (current === undefined || current === null || typeof current !== 'object') { return undefined; } current = current[part]; } return current; } /** * 关闭资源 */ dispose() { if (this.pollingTimer) { clearInterval(this.pollingTimer); this.pollingTimer = undefined; } } }; RemoteApiConfigSource = __decorate([ injectable(), __metadata("design:paramtypes", [String, Object, Number]) ], RemoteApiConfigSource); export { RemoteApiConfigSource }; //# sourceMappingURL=remote-api-config-source.js.map