@h-ai/core 0.1.0-alpha5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.d.ts ADDED
@@ -0,0 +1,82 @@
1
+ import { H as HaiError, a as HaiResult, C as CoreOptions, b as CoreLogger, I as I18nFn, c as IdFn, T as TypeUtilFn, O as ObjectFn, S as StringFn, A as ArrayFn, d as AsyncFn, e as TimeFn, E as ErrorFn, M as ModuleFn } from './core-util-module-B-wH5_ZT.js';
2
+ export { f as CoreConfig, g as CoreConfigSchema, h as CoreFunctions, i as Env, j as EnvSchema, k as ErrorInfo, l as ErrorInfoValue, m as HaiCommonError, n as HaiConfigError, o as HaiErrorDef, p as IdConfig, q as IdConfigSchema, r as InterpolationParams, L as Locale, s as LocaleInfo, t as LocaleMessages, u as LogContext, v as LogFormat, w as LogFormatSchema, x as LogLevel, y as LogLevelSchema, z as Logger, B as LoggerFunctions, D as LoggerOptions, F as LoggingConfig, G as LoggingConfigSchema, J as MatchHandlers, K as MessageDictionary, N as MessageOptions, P as PaginatedResult, Q as PaginationOptions, R as PaginationOptionsInput, U as err, V as ok } from './core-util-module-B-wH5_ZT.js';
3
+ import * as zod from 'zod';
4
+
5
+ /**
6
+ * @h-ai/core — 配置管理(Node.js 专用)
7
+ *
8
+ * 提供 YAML 配置文件加载、环境变量插值、缓存管理。
9
+ * @module core-function-config
10
+ */
11
+
12
+ /**
13
+ * 监听回调类型。
14
+ *
15
+ * @template T - 配置数据类型
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const callback: WatchCallback<AppConfig> = (cfg, error) => {
20
+ * if (error) { core.logger.error('Config reload failed', { error }); return }
21
+ * // 使用更新后的 cfg
22
+ * }
23
+ * ```
24
+ */
25
+ type WatchCallback<T = unknown> = (config: T | null, error?: HaiError) => void;
26
+
27
+ /**
28
+ * Core 服务对象 - 聚合常用功能(Node.js)。
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * import { core } from '@h-ai/core'
33
+ * core.init({ configDir: './config' })
34
+ * ```
35
+ */
36
+ declare const core: {
37
+ /** 配置管理 */
38
+ config: {
39
+ load<T>(name: string, filePath: string, schema?: zod.ZodType<T>): HaiResult<T>;
40
+ validate<T>(name: string, schema: zod.ZodType<T>): HaiResult<T>;
41
+ get<T>(name: string): T | undefined;
42
+ getOrThrow<T>(name: string): T;
43
+ reload(name: string): HaiResult<unknown>;
44
+ has(name: string): boolean;
45
+ clear(name?: string): void;
46
+ keys(): string[];
47
+ watch<T = unknown>(name: string, callback: WatchCallback<T>): () => void;
48
+ unwatch(name?: string): void;
49
+ isWatching(name: string): boolean;
50
+ };
51
+ /** 初始化 Core */
52
+ init: typeof initCore;
53
+ logger: CoreLogger;
54
+ i18n: I18nFn;
55
+ id: IdFn;
56
+ typeUtils: TypeUtilFn;
57
+ object: ObjectFn;
58
+ string: StringFn;
59
+ array: ArrayFn;
60
+ async: AsyncFn;
61
+ time: TimeFn;
62
+ error: ErrorFn;
63
+ module: ModuleFn;
64
+ };
65
+ /**
66
+ * 初始化 Core(内部实现,通过 `core.init()` 调用)。
67
+ *
68
+ * 执行流程:
69
+ * 1. 配置日志(若提供 `options.logging`)
70
+ * 2. 扫描并加载配置目录中的所有 YAML 文件
71
+ * 3. 启用配置文件监听(若 `options.watchConfig` 为 true)
72
+ *
73
+ * @param options - 初始化选项
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * core.init({ configDir: './config', watchConfig: true })
78
+ * ```
79
+ */
80
+ declare function initCore(options?: CoreOptions): void;
81
+
82
+ export { CoreLogger, CoreOptions, HaiError, HaiResult, core };
package/dist/node.js ADDED
@@ -0,0 +1,643 @@
1
+ import { createCore, CoreConfigSchema, i18n, err, HaiConfigError, ok, typeUtils } from './chunk-2GTCDC56.js';
2
+ export { CoreConfigSchema, EnvSchema, HaiCommonError, HaiConfigError, IdConfigSchema, LogFormatSchema, LogLevelSchema, LoggingConfigSchema, err, ok } from './chunk-2GTCDC56.js';
3
+ import { existsSync, readdirSync, watch, readFileSync } from 'fs';
4
+ import { join } from 'path';
5
+ import process2 from 'process';
6
+ import { parse } from 'yaml';
7
+ import { execSync } from 'child_process';
8
+ import pino from 'pino';
9
+
10
+ var ENV_VAR_PATTERN = /\$\{([^}:]+)(?::([^}]*))?\}/g;
11
+ var FULL_VAR_PATTERN = /^\$\{[^}:]+(?::[^}]*)?\}$/;
12
+ function interpolateEnv(value) {
13
+ if (typeof value === "string") {
14
+ let result = value;
15
+ ENV_VAR_PATTERN.lastIndex = 0;
16
+ while (true) {
17
+ const match = ENV_VAR_PATTERN.exec(value);
18
+ if (!match)
19
+ break;
20
+ const [fullMatch, varName, defaultValue] = match;
21
+ const envValue = process2.env[varName];
22
+ if (envValue === void 0 && defaultValue === void 0) {
23
+ return err(HaiConfigError.CONFIG_ENV_VAR_MISSING, i18n.coreM("core_configEnvVarMissing", { params: { varName } }));
24
+ }
25
+ result = result.replace(fullMatch, envValue ?? defaultValue ?? "");
26
+ }
27
+ if (FULL_VAR_PATTERN.test(value)) {
28
+ try {
29
+ const coerced = parse(result);
30
+ if (coerced !== void 0)
31
+ return ok(coerced);
32
+ } catch {
33
+ }
34
+ }
35
+ return ok(result);
36
+ }
37
+ if (Array.isArray(value)) {
38
+ const results = [];
39
+ for (const item of value) {
40
+ const r = interpolateEnv(item);
41
+ if (!r.success)
42
+ return r;
43
+ results.push(r.data);
44
+ }
45
+ return ok(results);
46
+ }
47
+ if (typeUtils.isObject(value)) {
48
+ const results = {};
49
+ for (const [k, v] of Object.entries(value)) {
50
+ const r = interpolateEnv(v);
51
+ if (!r.success)
52
+ return r;
53
+ results[k] = r.data;
54
+ }
55
+ return ok(results);
56
+ }
57
+ return ok(value);
58
+ }
59
+ var configCache = /* @__PURE__ */ new Map();
60
+ var watchEntries = /* @__PURE__ */ new Map();
61
+ function createNotLoadedError(name) {
62
+ const result = err(HaiConfigError.CONFIG_NOT_LOADED, i18n.coreM("core_configNotLoaded", { params: { name } }));
63
+ if (!result.success)
64
+ return result.error;
65
+ throw new Error("unreachable");
66
+ }
67
+ function notifyWatchCallbacks(name, result) {
68
+ const entry = watchEntries.get(name);
69
+ if (!entry)
70
+ return;
71
+ if (result.success) {
72
+ for (const callback of entry.callbacks) {
73
+ try {
74
+ callback(result.data, void 0);
75
+ } catch {
76
+ }
77
+ }
78
+ } else {
79
+ for (const callback of entry.callbacks) {
80
+ try {
81
+ callback(null, result.error);
82
+ } catch {
83
+ }
84
+ }
85
+ }
86
+ }
87
+ function loadYaml(filePath) {
88
+ if (!existsSync(filePath)) {
89
+ return err(HaiConfigError.CONFIG_FILE_NOT_FOUND, i18n.coreM("core_configFileNotExist", { params: { filePath } }));
90
+ }
91
+ try {
92
+ const content = readFileSync(filePath, "utf-8");
93
+ const parsed = parse(content);
94
+ return interpolateEnv(parsed);
95
+ } catch (error) {
96
+ return err(HaiConfigError.CONFIG_PARSE_ERROR, i18n.coreM("core_configParseFailed", { params: { filePath } }), error);
97
+ }
98
+ }
99
+ function loadConfig(filePath, schema) {
100
+ const yamlResult = loadYaml(filePath);
101
+ if (!yamlResult.success)
102
+ return yamlResult;
103
+ const parseResult = schema.safeParse(yamlResult.data);
104
+ if (!parseResult.success) {
105
+ return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM("core_configValidationFailed"), parseResult.error.issues);
106
+ }
107
+ return ok(parseResult.data);
108
+ }
109
+ function loadAndCache(name, filePath, schema) {
110
+ const result = schema ? loadConfig(filePath, schema) : loadYaml(filePath);
111
+ if (result.success) {
112
+ configCache.set(name, {
113
+ data: result.data,
114
+ filePath,
115
+ schema,
116
+ loadedAt: Date.now()
117
+ });
118
+ }
119
+ return result;
120
+ }
121
+ function validateLoadedConfig(name, schema) {
122
+ const entry = configCache.get(name);
123
+ if (!entry) {
124
+ return err(createNotLoadedError(name));
125
+ }
126
+ const parseResult = schema.safeParse(entry.data);
127
+ if (!parseResult.success) {
128
+ return err(HaiConfigError.CONFIG_VALIDATION_ERROR, i18n.coreM("core_configValidationFailed"), parseResult.error.issues);
129
+ }
130
+ const validated = parseResult.data;
131
+ configCache.set(name, {
132
+ ...entry,
133
+ data: validated,
134
+ schema,
135
+ loadedAt: Date.now()
136
+ });
137
+ return ok(validated);
138
+ }
139
+ function reloadAndNotify(name) {
140
+ const entry = configCache.get(name);
141
+ if (!entry) {
142
+ const result2 = err(createNotLoadedError(name));
143
+ notifyWatchCallbacks(name, result2);
144
+ return result2;
145
+ }
146
+ const result = entry.schema ? loadConfig(entry.filePath, entry.schema) : loadYaml(entry.filePath);
147
+ if (result.success) {
148
+ configCache.set(name, {
149
+ ...entry,
150
+ data: result.data,
151
+ loadedAt: Date.now()
152
+ });
153
+ }
154
+ notifyWatchCallbacks(name, result);
155
+ return result;
156
+ }
157
+ function startFileWatcher(name) {
158
+ const existing = watchEntries.get(name);
159
+ if (existing)
160
+ return existing;
161
+ const entry = configCache.get(name);
162
+ if (!entry)
163
+ return null;
164
+ try {
165
+ const watchEntry = {
166
+ watcher: null,
167
+ callbacks: /* @__PURE__ */ new Set(),
168
+ debounceTimer: null
169
+ };
170
+ const watcher = watch(entry.filePath, (eventType) => {
171
+ if (eventType === "change") {
172
+ if (watchEntry.debounceTimer)
173
+ clearTimeout(watchEntry.debounceTimer);
174
+ watchEntry.debounceTimer = setTimeout(() => {
175
+ watchEntry.debounceTimer = null;
176
+ reloadAndNotify(name);
177
+ }, 100);
178
+ }
179
+ });
180
+ watchEntry.watcher = watcher;
181
+ watchEntries.set(name, watchEntry);
182
+ return watchEntry;
183
+ } catch {
184
+ return null;
185
+ }
186
+ }
187
+ function registerWatch(name, callback) {
188
+ const entry = startFileWatcher(name);
189
+ if (!entry) {
190
+ callback(null, createNotLoadedError(name));
191
+ return () => {
192
+ };
193
+ }
194
+ entry.callbacks.add(callback);
195
+ return () => {
196
+ const current = watchEntries.get(name);
197
+ if (!current)
198
+ return;
199
+ current.callbacks.delete(callback);
200
+ if (current.callbacks.size === 0) {
201
+ if (current.debounceTimer)
202
+ clearTimeout(current.debounceTimer);
203
+ current.watcher.close();
204
+ watchEntries.delete(name);
205
+ }
206
+ };
207
+ }
208
+ function stopWatching(name) {
209
+ if (name) {
210
+ const entry = watchEntries.get(name);
211
+ if (entry) {
212
+ if (entry.debounceTimer)
213
+ clearTimeout(entry.debounceTimer);
214
+ entry.watcher.close();
215
+ watchEntries.delete(name);
216
+ }
217
+ } else {
218
+ for (const entry of watchEntries.values()) {
219
+ if (entry.debounceTimer)
220
+ clearTimeout(entry.debounceTimer);
221
+ entry.watcher.close();
222
+ }
223
+ watchEntries.clear();
224
+ }
225
+ }
226
+ function clearCache(name) {
227
+ if (name) {
228
+ configCache.delete(name);
229
+ stopWatching(name);
230
+ } else {
231
+ configCache.clear();
232
+ stopWatching();
233
+ }
234
+ }
235
+ var config = {
236
+ /**
237
+ * 加载配置到缓存。
238
+ *
239
+ * 加载 YAML 文件并可选地用 Zod Schema 校验,成功后写入缓存。
240
+ *
241
+ * @param name - 配置名称(缓存 key)
242
+ * @param filePath - YAML 文件路径
243
+ * @param schema - 可选 Zod Schema(不传则跳过校验)
244
+ * @returns 成功时返回解析后的配置数据;失败时返回 HaiError
245
+ *
246
+ * @example
247
+ * ```ts
248
+ * const result = config.load('core', './config/_core.yml', CoreConfigSchema)
249
+ * if (result.success) {
250
+ * // result.data 为校验后的配置
251
+ * }
252
+ * ```
253
+ */
254
+ load(name, filePath, schema) {
255
+ return loadAndCache(name, filePath, schema);
256
+ },
257
+ /**
258
+ * 验证已加载的配置数据。
259
+ *
260
+ * 对缓存中的配置数据重新用 Schema 校验,校验通过后更新缓存。
261
+ *
262
+ * @param name - 配置名称
263
+ * @param schema - Zod 验证模式
264
+ * @returns 校验结果;未加载时返回 NOT_LOADED,格式错误返回 VALIDATION_ERROR
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * const result = config.validate('app', AppSchema)
269
+ * if (!result.success) {
270
+ * // result.error.code 可能为 NOT_LOADED 或 VALIDATION_ERROR
271
+ * }
272
+ * ```
273
+ */
274
+ validate(name, schema) {
275
+ return validateLoadedConfig(name, schema);
276
+ },
277
+ /**
278
+ * 获取已加载的配置。
279
+ *
280
+ * @param name - 配置名称
281
+ * @returns 配置数据;未加载时返回 undefined
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * const cfg = config.get<CoreConfig>('core')
286
+ * if (cfg) {
287
+ * // 使用 cfg
288
+ * }
289
+ * ```
290
+ */
291
+ get(name) {
292
+ return configCache.get(name)?.data;
293
+ },
294
+ /**
295
+ * 获取配置,不存在时抛出错误。
296
+ *
297
+ * @param name - 配置名称
298
+ * @returns 配置数据
299
+ * @throws 配置未加载时抛出 Error
300
+ *
301
+ * @example
302
+ * ```ts
303
+ * try {
304
+ * const cfg = config.getOrThrow<CoreConfig>('core')
305
+ * } catch (e) {
306
+ * // 配置未加载
307
+ * }
308
+ * ```
309
+ */
310
+ getOrThrow(name) {
311
+ const data = this.get(name);
312
+ if (data === void 0) {
313
+ throw new Error(i18n.coreM("core_configNotLoaded", { params: { name } }));
314
+ }
315
+ return data;
316
+ },
317
+ /**
318
+ * 重新加载配置。
319
+ *
320
+ * 从磁盘重新读取配置文件并更新缓存,同时通知所有 watch 回调。
321
+ *
322
+ * @param name - 配置名称
323
+ * @returns 重载结果;未加载时返回 NOT_LOADED
324
+ *
325
+ * @example
326
+ * ```ts
327
+ * const result = config.reload('app')
328
+ * ```
329
+ */
330
+ reload(name) {
331
+ return reloadAndNotify(name);
332
+ },
333
+ /**
334
+ * 检查配置是否已加载。
335
+ *
336
+ * @param name - 配置名称
337
+ * @returns 是否已加载到缓存
338
+ *
339
+ * @example
340
+ * ```ts
341
+ * if (config.has('db')) {
342
+ * const dbCfg = config.get('db')
343
+ * }
344
+ * ```
345
+ */
346
+ has(name) {
347
+ return configCache.has(name);
348
+ },
349
+ /**
350
+ * 清除配置缓存(同时停止对应监听)。
351
+ *
352
+ * @param name - 配置名称;不传则清除全部
353
+ *
354
+ * @example
355
+ * ```ts
356
+ * config.clear('app') // 清除单个
357
+ * config.clear() // 清除全部
358
+ * ```
359
+ */
360
+ clear(name) {
361
+ clearCache(name);
362
+ },
363
+ /**
364
+ * 获取所有已加载的配置名称。
365
+ *
366
+ * @returns 配置名称数组
367
+ *
368
+ * @example
369
+ * ```ts
370
+ * const names = config.keys() // ['core', 'db', 'app']
371
+ * ```
372
+ */
373
+ keys() {
374
+ return Array.from(configCache.keys());
375
+ },
376
+ /**
377
+ * 监听配置文件变更并自动重载。
378
+ *
379
+ * 文件变更时自动重新加载并调用回调。配置未加载时立即回调 NOT_LOADED 错误。
380
+ *
381
+ * @param name - 配置名称
382
+ * @param callback - 配置变更回调,接收新配置或错误
383
+ * @returns 取消监听函数
384
+ *
385
+ * @example
386
+ * ```ts
387
+ * const unwatch = config.watch('app', (cfg, error) => {
388
+ * if (error) { core.logger.error('reload failed', { error }); return }
389
+ * core.logger.info('config updated', { cfg })
390
+ * })
391
+ * // 取消监听
392
+ * unwatch()
393
+ * ```
394
+ */
395
+ watch(name, callback) {
396
+ return registerWatch(name, callback);
397
+ },
398
+ /**
399
+ * 停止配置文件监听。
400
+ *
401
+ * @param name - 配置名称;不传则停止所有监听
402
+ *
403
+ * @example
404
+ * ```ts
405
+ * config.unwatch('app') // 停止单个
406
+ * config.unwatch() // 停止全部
407
+ * ```
408
+ */
409
+ unwatch(name) {
410
+ stopWatching(name);
411
+ },
412
+ /**
413
+ * 检查是否正在监听某个配置。
414
+ *
415
+ * @param name - 配置名称
416
+ * @returns 是否有活跃的 watcher
417
+ *
418
+ * @example
419
+ * ```ts
420
+ * if (config.isWatching('app')) {
421
+ * config.unwatch('app')
422
+ * }
423
+ * ```
424
+ */
425
+ isWatching(name) {
426
+ return watchEntries.has(name);
427
+ }
428
+ };
429
+ if (process2.platform === "win32" && process2.stdout.isTTY) {
430
+ try {
431
+ execSync("chcp 65001 > nul", { stdio: "ignore" });
432
+ if (process2.stdout.setDefaultEncoding) {
433
+ process2.stdout.setDefaultEncoding("utf8");
434
+ }
435
+ if (process2.stderr.setDefaultEncoding) {
436
+ process2.stderr.setDefaultEncoding("utf8");
437
+ }
438
+ process2.env.LANG = "zh_CN.UTF-8";
439
+ process2.env.LC_ALL = "zh_CN.UTF-8";
440
+ process2.env.PYTHONIOENCODING = "utf-8";
441
+ } catch (_e) {
442
+ }
443
+ }
444
+ var globalLevel = "info";
445
+ var globalFormat = "pretty";
446
+ var globalContext = {};
447
+ var globalRedact = [];
448
+ var defaultLogger = null;
449
+ function configureLogger(config2) {
450
+ if (config2.level)
451
+ globalLevel = config2.level;
452
+ if (config2.format)
453
+ globalFormat = config2.format;
454
+ if (config2.context)
455
+ globalContext = { ...globalContext, ...config2.context };
456
+ if (config2.redact)
457
+ globalRedact = config2.redact;
458
+ defaultLogger = null;
459
+ }
460
+ function setLogLevel(level) {
461
+ globalLevel = level;
462
+ }
463
+ function getLogLevel() {
464
+ return globalLevel;
465
+ }
466
+ function wrapPino(pinoLogger, context) {
467
+ return {
468
+ trace(message, ctx) {
469
+ pinoLogger.trace({ ...context, ...ctx }, message);
470
+ },
471
+ debug(message, ctx) {
472
+ pinoLogger.debug({ ...context, ...ctx }, message);
473
+ },
474
+ info(message, ctx) {
475
+ pinoLogger.info({ ...context, ...ctx }, message);
476
+ },
477
+ warn(message, ctx) {
478
+ pinoLogger.warn({ ...context, ...ctx }, message);
479
+ },
480
+ error(message, ctx) {
481
+ pinoLogger.error({ ...context, ...ctx }, message);
482
+ },
483
+ fatal(message, ctx) {
484
+ pinoLogger.fatal({ ...context, ...ctx }, message);
485
+ },
486
+ child(childContext) {
487
+ return wrapPino(pinoLogger.child(childContext), { ...context, ...childContext });
488
+ }
489
+ };
490
+ }
491
+ function createLogger(options = {}) {
492
+ const level = options.level ?? globalLevel;
493
+ const format = options.format ?? globalFormat;
494
+ const context = { ...globalContext, ...options.context };
495
+ const pinoOptions = {
496
+ level,
497
+ name: options.name,
498
+ formatters: {
499
+ level: (label) => ({ level: label })
500
+ }
501
+ };
502
+ if (globalRedact.length > 0) {
503
+ pinoOptions.redact = {
504
+ paths: globalRedact,
505
+ censor: "[REDACTED]"
506
+ };
507
+ }
508
+ let pinoInstance;
509
+ if (format === "pretty") {
510
+ pinoInstance = pino({
511
+ ...pinoOptions,
512
+ transport: {
513
+ target: "pino-pretty",
514
+ options: {
515
+ colorize: true,
516
+ translateTime: "SYS:standard",
517
+ ignore: "pid,hostname"
518
+ }
519
+ }
520
+ });
521
+ } else {
522
+ pinoInstance = pino(pinoOptions);
523
+ }
524
+ return wrapPino(pinoInstance, context);
525
+ }
526
+ function getLogger() {
527
+ if (!defaultLogger) {
528
+ defaultLogger = createLogger();
529
+ }
530
+ return defaultLogger;
531
+ }
532
+ var logger = {
533
+ configureLogger,
534
+ setLogLevel,
535
+ getLogLevel,
536
+ createLogger,
537
+ getLogger
538
+ };
539
+
540
+ // src/core-main.node.ts
541
+ function createNodeCore() {
542
+ const baseCore = createCore({
543
+ createLogger: logger.createLogger,
544
+ getLogger: logger.getLogger,
545
+ configureLogger: logger.configureLogger,
546
+ setLogLevel: logger.setLogLevel,
547
+ getLogLevel: logger.getLogLevel
548
+ });
549
+ return {
550
+ ...baseCore,
551
+ /** 配置管理 */
552
+ config,
553
+ /** 初始化 Core */
554
+ init: initCore
555
+ };
556
+ }
557
+ var core = createNodeCore();
558
+ function scanConfigDir(configDir) {
559
+ const logger2 = core.logger;
560
+ const items = [];
561
+ if (!existsSync(configDir)) {
562
+ logger2.warn(`[core] Config directory not found: ${configDir}`);
563
+ return items;
564
+ }
565
+ const files = readdirSync(configDir).filter(
566
+ (f) => f.endsWith(".yml") || f.endsWith(".yaml")
567
+ );
568
+ for (const file of files) {
569
+ const filePath = join(configDir, file);
570
+ const baseName = file.replace(/\.ya?ml$/, "");
571
+ if (baseName.startsWith("_")) {
572
+ const moduleName = baseName.slice(1);
573
+ items.push({
574
+ name: moduleName,
575
+ filePath
576
+ });
577
+ } else {
578
+ items.push({
579
+ name: baseName,
580
+ filePath
581
+ });
582
+ }
583
+ }
584
+ return items;
585
+ }
586
+ function initCore(options = {}) {
587
+ const startTime = Date.now();
588
+ const logger2 = core.logger;
589
+ if (options.logging) {
590
+ core.logger.configure(options.logging);
591
+ }
592
+ logger2.info("[core] Initializing...");
593
+ let configItems = [];
594
+ if (options.configDir) {
595
+ configItems = scanConfigDir(options.configDir);
596
+ }
597
+ for (const item of configItems) {
598
+ if (item.name === "core") {
599
+ const result = config.load(item.name, item.filePath, CoreConfigSchema);
600
+ if (result.success) {
601
+ if (!options.logging) {
602
+ core.logger.configure(result.data.logging || {});
603
+ }
604
+ logger2.info(`[core] Config loaded: ${item.name} <- ${item.filePath}`);
605
+ } else {
606
+ logger2.error(`[core] Config load failed: ${item.name}`, {
607
+ error: result.error
608
+ });
609
+ }
610
+ } else {
611
+ const result = config.load(item.name, item.filePath);
612
+ if (result.success) {
613
+ logger2.info(`[core] Config loaded: ${item.name} <- ${item.filePath}`);
614
+ } else {
615
+ logger2.error(`[core] Config load failed: ${item.name}`, {
616
+ error: result.error
617
+ });
618
+ }
619
+ }
620
+ }
621
+ if (options.watchConfig && configItems.length > 0) {
622
+ setupConfigWatch(configItems);
623
+ }
624
+ const duration = Date.now() - startTime;
625
+ logger2.info(`[core] Initialized (${duration}ms)`);
626
+ }
627
+ function setupConfigWatch(configs) {
628
+ const logger2 = core.logger;
629
+ for (const item of configs) {
630
+ config.watch(item.name, (_config, error) => {
631
+ if (error) {
632
+ logger2.error(`[core] Config reload failed: ${item.name}`, { error });
633
+ return;
634
+ }
635
+ logger2.info(`[core] Config reloaded: ${item.name}`);
636
+ });
637
+ logger2.debug(`[core] Config watch enabled: ${item.name}`);
638
+ }
639
+ }
640
+
641
+ export { core };
642
+ //# sourceMappingURL=node.js.map
643
+ //# sourceMappingURL=node.js.map