@wiajs/core 1.2.3 → 2.1.0

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/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * wia core v1.2.3
2
+ * wia core v2.1.0
3
3
  * (c) 2015-2026 Sibyl Yu and contributors
4
4
  * Released under the MIT License.
5
5
  */
@@ -2073,227 +2073,193 @@ class Event {
2073
2073
  }
2074
2074
  }
2075
2075
 
2076
- /*!
2077
- * wia util v3.4.25
2078
- * (c) 2018-2024 Yan (Sibyl) Yu and Yuxi (Evan) You and wia/vue contributors
2079
- * Released under the MIT License.
2080
- */
2081
2076
  /**
2082
- * Created by way on 10/6/16.
2083
- * Part of the code comes from @vue/shared
2077
+ * @typedef {Object} LogOptions
2078
+ * @property {string} m - 模块名称
2079
+ */
2080
+
2081
+ /**
2082
+ * @typedef {((...args: any[]) => void) & { debug: (...args: any[])=>void, info: (...args: any[])=>void, warn: (...args: any[])=>void, error: (...args: any[])=>void, err: (...args: any[])=>void }} ScopedLogger
2084
2083
  */
2085
2084
 
2086
-
2087
2085
  /**
2088
- * 前端日志输出,封装 console日志,简化代码,支持模块或直接输出
2089
- * 调用时,描述字符串后置,便于可选缺省,输出时,自带前置,类似 后端pino,保持前后端一致性
2090
- * m 为模块,fn 为函数名称
2086
+ * @typedef {((...args: any[]) => void) & { log: (...args: any[])=>void, debug: (...args: any[])=>void, info: (...args: any[])=>void, warn: (...args: any[])=>void, error: (...args: any[])=>void, err: (...args: any[])=>void, fn: (name: string) => ScopedLogger }} LoggerFn
2087
+ */
2088
+
2089
+ // 1. 安全地获取开发环境状态(兼容打包工具、浏览器和 Node.js)
2090
+ // 如果 Rspack 注入了 __DEV__,就用注入的值;如果是在 Node.js 下,就回退读取 "production"
2091
+ const isDev = typeof __DEV__ !== 'undefined' ? __DEV__ : "production" !== 'production';
2092
+
2093
+ /**
2094
+ * 前端日志输出,封装 console 日志,简化代码
2095
+ * 自动识别并重排提示符与对象,保持前后端一致性
2091
2096
  */
2092
2097
  class Log {
2093
- /** @type {string} 模块 */
2098
+ /** @type {string} 模块名称 */
2094
2099
  m = ''
2095
2100
 
2096
- /** @type {string} 函数 */
2097
- fn = ''
2101
+ /** @type {string} 函数名称 */
2102
+ fnName = ''
2098
2103
 
2099
2104
  /**
2100
- * @param {string} m 模块
2105
+ * @param {string} [m=''] 模块
2106
+ * @param {string} [fnName=''] 函数
2101
2107
  */
2102
- constructor(m) {
2108
+ constructor(m = '', fnName = '') {
2103
2109
  this.m = m;
2110
+ this.fnName = fnName;
2104
2111
  }
2105
2112
 
2106
2113
  /**
2107
- * get log desc
2108
- * 描述字符串后置调用,前置显示
2109
- * @param {*[]} args
2110
- * @returns {string}
2114
+ * 格式化参数:提取提示符,构建前缀,将对象后置
2115
+ * 格式要求:[模块名称:函数名称]提示符: {对象}
2116
+ * @param {any[]} args
2117
+ * @returns {any[]} 返回处理后传递给 console 的参数数组
2111
2118
  */
2112
- getDesc(args) {
2119
+ formatArgs(args) {
2113
2120
  let R = '';
2121
+ const _ = this;
2114
2122
  try {
2115
- const _ = this;
2116
- const { m } = _;
2117
- let fn = '',
2118
- desc = '';
2119
-
2120
- if (args.length > 1) {
2121
- const last = args.at(-1);
2122
- if (typeof last === 'object') {
2123
- ;({ desc, fn } = last);
2124
- } else if (typeof last === 'string') desc = last;
2125
- if (desc || fn) {
2126
- fn = fn || _.fn;
2127
- _.fn = fn;
2128
- args.pop();
2129
- }
2123
+ const msgs = [];
2124
+ const objs = [];
2125
+
2126
+ // 1. 将字符串(提示符)和非字符串(对象/数值等)分开
2127
+ for (const arg of args) {
2128
+ if (typeof arg === 'string') msgs.push(arg);
2129
+ else objs.push(arg);
2130
2130
  }
2131
- fn = fn || _.fn;
2132
- if (m) desc = `${desc}[${m}${fn ? ':' + fn : ''}]`; // eslint-disable-line
2133
- R = desc;
2131
+
2132
+ let prefix = '';
2133
+
2134
+ // 2. 添加模块与函数前缀
2135
+ if (_.m) prefix = `[${_.m}${_.fnName ? ':' + _.fnName : ''}]`;
2136
+ else if (_.fnName) prefix = `[:${_.fnName}]`;
2137
+
2138
+ // 3. 拼接提示符
2139
+ const msg = msgs.join(' ');
2140
+ if (msg) prefix += msg;
2141
+
2142
+ R = [];
2143
+ if (prefix) R.push(prefix);
2144
+ R.push(...objs);
2134
2145
  } catch (e) {
2135
- console.error(`getDesc exp:${e.message}`);
2146
+ console.error(`formatArgs exp:${e.message}`);
2136
2147
  }
2137
2148
 
2138
2149
  return R
2139
2150
  }
2140
2151
 
2141
- /** @param {...any} args - params */
2152
+ /** @param {...any} args */
2142
2153
  log(...args) {
2143
- const _ = this;
2144
- const last = args.at(-1);
2145
- // clear fn
2146
- if (args.length === 1 && typeof last === 'object' && last.fn) _.fn = '';
2147
- else {
2148
- const desc = _.getDesc(args);
2149
- console.log(desc, ...args);
2150
- }
2154
+ // 生产环境安全剔除 (需 Rspack DefinePlugin 注入 __DEV__)
2155
+ if (isDev) console.log(...this.formatArgs(args));
2151
2156
  }
2152
2157
 
2153
- /** @param {...any} args - params */
2158
+ /** @param {...any} args */
2154
2159
  debug(...args) {
2155
- const _ = this;
2156
- const desc = _.getDesc(args);
2157
- if (desc) console.log(desc, ...args);
2158
- else console.log(...args);
2160
+ if (isDev) console.debug(...this.formatArgs(args));
2159
2161
  }
2160
2162
 
2161
- /** @param {...any} args - params */
2163
+ /** @param {...any} args */
2162
2164
  info(...args) {
2163
- const _ = this;
2164
- const desc = _.getDesc(args);
2165
- if (desc) console.info(desc, ...args);
2166
- else console.log(...args);
2165
+ if (isDev) console.info(...this.formatArgs(args));
2167
2166
  }
2168
2167
 
2169
- /** @param {...any} args - params */
2168
+ /** @param {...any} args */
2170
2169
  warn(...args) {
2171
- const _ = this;
2172
- const { desc, arg } = _.getDesc(args);
2173
- if (desc) console.warn(desc, ...arg);
2174
- else console.log(...args);
2170
+ if (isDev) console.warn(...this.formatArgs(args));
2175
2171
  }
2176
2172
 
2177
- /** @param {...any} args - params */
2173
+ /** @param {...any} args */
2178
2174
  trace(...args) {
2179
- const _ = this;
2180
- const { desc, arg } = _.getDesc(args);
2181
- if (desc) console.trace(desc, ...arg);
2182
- else console.trace(...args);
2175
+ if (isDev) console.trace(...this.formatArgs(args));
2183
2176
  }
2184
2177
 
2185
- /** @param {...any} args - params */
2178
+ /** * error 会在生产环境保留
2179
+ * @param {...any} args
2180
+ */
2186
2181
  error(...args) {
2187
- const _ = this;
2188
- const desc = _.getDesc(args);
2189
- if (desc) console.error(desc, ...args);
2190
- else console.log(...args);
2182
+ console.error(...this.formatArgs(args));
2191
2183
  }
2192
2184
 
2193
2185
  /**
2194
- * 用于 catch(e) log.err(e)
2195
- * @param {...any} args - params */
2186
+ * 用于 catch(e) log.err(e) 或 log.err("提示符", e) 或 log.err(e, "提示符")
2187
+ * 自动对齐前缀 [模块:函数] 提示符: Error对象,并保留堆栈
2188
+ * @param {...any} args
2189
+ */
2196
2190
  err(...args) {
2197
- const _ = this;
2198
- const first = args?.[0];
2199
- if (
2200
- first instanceof Error ||
2201
- (first && first.message && first.cause && first.stack)
2202
- )
2203
- args[0] = { exp: args[0].message };
2204
- _.error(...args);
2191
+ // 生产环境安全输出,不会被 Tree-shaking 摇掉
2192
+ // formatArgs 会自动分离字符串与 Error 对象,并补全冒号
2193
+ const formattedArgs = this.formatArgs(args);
2194
+
2195
+ // 原生打印,保持 stack trace 可点击跳转!
2196
+ console.error(...formattedArgs);
2205
2197
  }
2206
- }
2207
2198
 
2208
- function getDesc(args) {
2209
- let desc = '';
2210
- const last = args.at(-1);
2211
- if (typeof last === 'string') {
2212
- desc = last;
2213
- args.pop();
2199
+ /**
2200
+ * 派生函数级别日志实例 (完美对齐后端 log.fn)
2201
+ * @param {string} name 函数名称
2202
+ * @returns {ScopedLogger}
2203
+ */
2204
+ fn(name) {
2205
+ const scopedLog = new Log(this.m, name);
2206
+
2207
+ /** @type {any} */
2208
+ const R = (...args) => scopedLog.log(...args);
2209
+
2210
+ R.debug = scopedLog.debug.bind(scopedLog);
2211
+ R.info = scopedLog.info.bind(scopedLog);
2212
+ R.warn = scopedLog.warn.bind(scopedLog);
2213
+ R.trace = scopedLog.trace.bind(scopedLog);
2214
+ R.error = scopedLog.error.bind(scopedLog);
2215
+ R.err = scopedLog.err.bind(scopedLog);
2216
+
2217
+ return /** @type {ScopedLogger} */ (R)
2214
2218
  }
2215
- return desc
2216
2219
  }
2217
2220
 
2221
+ // 实例化唯一的全局日志单例
2222
+ const _log = new Log();
2223
+
2218
2224
  /**
2219
2225
  * 标准日志输出或构建模块日志类实例,用于模块中带[m:xxx]标记日志输出
2220
- * 启用 {f:fn} 标记时,需在函数尾部清除f(log({f:''})),否则会溢出到其他函数
2226
+ * 传入 { m: '模块名' } 构建实例,或直接传入参数输出全局日志
2221
2227
  * @param {...any} args - params
2222
2228
  * returns {*}
2223
2229
  */
2224
2230
  function log(...args) {
2225
2231
  const last = args.at(-1);
2226
2232
 
2227
- // 全局日志
2228
- if (args.length !== 1 || !last?.m) {
2229
- const desc = getDesc(args);
2230
- desc ? console.log(desc, ...args) : console.log(...args);
2231
- return
2232
- }
2233
-
2234
- // 唯一 m 属性,则构造新的 log 实例,这种写法,能被jsDoc识别子属性
2235
- const lg = new Log(last?.m);
2236
- /** @param {*} args2 */
2237
- const R = (...args2) => lg.log(...args2);
2238
- R.debug = lg.debug.bind(lg);
2239
- R.info = lg.info.bind(lg);
2240
- R.warn = lg.warn.bind(lg);
2241
- R.info = lg.info.bind(lg);
2242
- R.trace = lg.trace.bind(lg);
2243
- R.error = lg.error.bind(lg);
2244
- R.err = lg.err.bind(lg);
2245
-
2246
- return R
2247
- }
2233
+ // 1. 如果只有一个参数且带 m 属性,说明是构造 Logger 实例 (如: const log = Log({m: 'User'}))
2234
+ if (args.length === 1 && typeof last === 'object' && last !== null && 'm' in last) {
2235
+ const lg = new Log(last.m);
2248
2236
 
2249
- /**
2250
- * 用于 catch(e) log.err(e)
2251
- * @param {...any} args - params */
2252
- log.err = (...args) => {
2253
- const desc = getDesc(args);
2254
- const first = args?.[0];
2255
- if (
2256
- first instanceof Error ||
2257
- (first && first.message && first.cause && first.stack)
2258
- )
2259
- args[0] = { exp: args[0].message };
2260
- desc ? console.error(desc, ...args) : console.error(...args);
2261
- };
2237
+ /** @type {any} */
2238
+ const R = (...args2) => lg.log(...args2);
2262
2239
 
2263
- /**
2264
- * @param {...any} args - params */
2265
- log.error = (...args) => {
2266
- const desc = getDesc(args);
2267
- desc ? console.error(desc, ...args) : console.error(...args);
2268
- };
2269
-
2270
- /**
2271
- * @param {...any} args - params */
2272
- log.warn = (...args) => {
2273
- const desc = getDesc(args);
2274
- desc ? console.warn(desc, ...args) : console.warn(...args);
2275
- };
2240
+ R.log = lg.log.bind(lg);
2241
+ R.debug = lg.debug.bind(lg);
2242
+ R.info = lg.info.bind(lg);
2243
+ R.warn = lg.warn.bind(lg);
2244
+ R.trace = lg.trace.bind(lg);
2245
+ R.error = lg.error.bind(lg);
2246
+ R.err = lg.err.bind(lg);
2247
+ R.fn = lg.fn.bind(lg); // 暴露派生函数作用域方法
2276
2248
 
2277
- /**
2278
- * @param {...any} args - params */
2279
- log.info = (...args) => {
2280
- const desc = getDesc(args);
2281
- desc ? console.info(desc, ...args) : console.info(...args);
2282
- };
2249
+ return /** @type {LoggerFn} */ (R)
2250
+ }
2283
2251
 
2284
- /**
2285
- * @param {...any} args - params */
2286
- log.debug = (...args) => {
2287
- const desc = getDesc(args);
2288
- desc ? console.log(desc, ...args) : console.log(...args);
2289
- };
2252
+ // 2. 否则作为全局普通日志直接输出
2253
+ _log.log(...args);
2254
+ }
2290
2255
 
2291
- /**
2292
- * @param {...any} args - params */
2293
- log.trace = (...args) => {
2294
- const desc = getDesc(args);
2295
- desc ? console.trace(desc, ...args) : console.trace(...args);
2296
- };
2256
+ // 绑定全局快捷方法,方便直接调用 log.err(e) 等
2257
+ log.err = _log.err.bind(_log);
2258
+ log.error = _log.error.bind(_log);
2259
+ log.warn = _log.warn.bind(_log);
2260
+ log.info = _log.info.bind(_log);
2261
+ log.debug = _log.debug.bind(_log);
2262
+ log.trace = _log.trace.bind(_log);
2297
2263
 
2298
2264
  /**
2299
2265
  * 所有页面从该类继承,并必须实现 load 事件!
@@ -2323,7 +2289,6 @@ log.trace = (...args) => {
2323
2289
  *
2324
2290
  */
2325
2291
 
2326
-
2327
2292
  class Page extends Event {
2328
2293
  constructor(app, name, title, style) {
2329
2294
  super(null, [app]);
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * wia core v1.2.3
2
+ * wia core v2.1.0
3
3
  * (c) 2015-2026 Sibyl Yu and contributors
4
4
  * Released under the MIT License.
5
5
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wiajs/core",
3
- "version": "1.2.3",
3
+ "version": "2.1.0",
4
4
  "description": "wia app core package",
5
5
  "keywords": [
6
6
  "core",
package/util/log.d.ts ADDED
@@ -0,0 +1,113 @@
1
+ /**
2
+ * 模块日志选项
3
+ */
4
+ export interface LogOptions {
5
+ /** 模块名称 */
6
+ m: string
7
+ }
8
+
9
+ /**
10
+ * 派生函数级别的日志实例(支持直接作为函数调用,或调用内部方法)
11
+ */
12
+ export interface ScopedLogger {
13
+ (...args: any[]): void
14
+ debug(...args: any[]): void
15
+ info(...args: any[]): void
16
+ warn(...args: any[]): void
17
+ error(...args: any[]): void
18
+ err(...args: any[]): void
19
+ trace(...args: any[]): void
20
+ }
21
+
22
+ /**
23
+ * 模块级别的日志实例(带有派生子函数 .fn 的能力)
24
+ */
25
+ export interface LoggerFn {
26
+ (...args: any[]): void
27
+ log(...args: any[]): void
28
+ debug(...args: any[]): void
29
+ info(...args: any[]): void
30
+ warn(...args: any[]): void
31
+ error(...args: any[]): void
32
+ err(...args: any[]): void
33
+ trace(...args: any[]): void
34
+ /**
35
+ * 派生函数级别日志实例 (完美对齐后端 log.fn)
36
+ * @param name 函数名称
37
+ */
38
+ fn(name: string): ScopedLogger
39
+ }
40
+
41
+ /**
42
+ * 前端日志输出核心类
43
+ * 自动识别并重排提示符与对象,保持前后端一致性
44
+ */
45
+ export class Log {
46
+ /** 模块名称 */
47
+ m: string
48
+ /** 函数名称 */
49
+ fnName: string
50
+
51
+ constructor(m?: string, fnName?: string)
52
+
53
+ /**
54
+ * 格式化参数:提取提示符,构建前缀,将对象后置
55
+ * 格式要求:[模块名称:函数名称]提示符: {对象}
56
+ * @param args
57
+ * @returns 返回处理后传递给 console 的参数数组
58
+ */
59
+ formatArgs(args: any[]): any[]
60
+
61
+ log(...args: any[]): void
62
+ debug(...args: any[]): void
63
+ info(...args: any[]): void
64
+ warn(...args: any[]): void
65
+ trace(...args: any[]): void
66
+
67
+ /**
68
+ * error 会在生产环境保留
69
+ */
70
+ error(...args: any[]): void
71
+
72
+ /**
73
+ * 用于 catch(e) log.err(e) 或 log.err("提示符", e) 或 log.err(e, "提示符")
74
+ * 自动对齐前缀 [模块:函数] 提示符: Error对象,并保留堆栈
75
+ */
76
+ err(...args: any[]): void
77
+
78
+ /**
79
+ * 派生函数级别日志实例
80
+ * @param name 函数名称
81
+ */
82
+ fn(name: string): ScopedLogger
83
+ }
84
+
85
+ /**
86
+ * 全局的 log 实例接口
87
+ * 实现了函数重载,支持构造日志模块对象,或是直接调用
88
+ */
89
+ export interface GlobalLogger {
90
+ /**
91
+ * 构建模块日志类实例
92
+ * @example const uploaderLog = log({ m: 'uploader' })
93
+ */
94
+ (opt: LogOptions): LoggerFn
95
+
96
+ /**
97
+ * 标准日志输出 (无模块前缀)
98
+ * @example log('普通提示', { data: 1 })
99
+ */
100
+ (...args: any[]): void
101
+
102
+ err(...args: any[]): void
103
+ error(...args: any[]): void
104
+ warn(...args: any[]): void
105
+ info(...args: any[]): void
106
+ debug(...args: any[]): void
107
+ trace(...args: any[]): void
108
+ }
109
+
110
+ /**
111
+ * 标准日志输出或构建模块日志类实例
112
+ */
113
+ export const log: GlobalLogger
package/util/log.js ADDED
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @typedef {Object} LogOptions
3
+ * @property {string} m - 模块名称
4
+ */
5
+
6
+ /**
7
+ * @typedef {((...args: any[]) => void) & { debug: (...args: any[])=>void, info: (...args: any[])=>void, warn: (...args: any[])=>void, error: (...args: any[])=>void, err: (...args: any[])=>void }} ScopedLogger
8
+ */
9
+
10
+ /**
11
+ * @typedef {((...args: any[]) => void) & { log: (...args: any[])=>void, debug: (...args: any[])=>void, info: (...args: any[])=>void, warn: (...args: any[])=>void, error: (...args: any[])=>void, err: (...args: any[])=>void, fn: (name: string) => ScopedLogger }} LoggerFn
12
+ */
13
+
14
+ // 1. 安全地获取开发环境状态(兼容打包工具、浏览器和 Node.js)
15
+ // 如果 Rspack 注入了 __DEV__,就用注入的值;如果是在 Node.js 下,就回退读取 process.env.NODE_ENV
16
+ const isDev = typeof __DEV__ !== 'undefined' ? __DEV__ : process.env.NODE_ENV !== 'production'
17
+
18
+ /**
19
+ * 前端日志输出,封装 console 日志,简化代码
20
+ * 自动识别并重排提示符与对象,保持前后端一致性
21
+ */
22
+ class Log {
23
+ /** @type {string} 模块名称 */
24
+ m = ''
25
+
26
+ /** @type {string} 函数名称 */
27
+ fnName = ''
28
+
29
+ /**
30
+ * @param {string} [m=''] 模块
31
+ * @param {string} [fnName=''] 函数
32
+ */
33
+ constructor(m = '', fnName = '') {
34
+ this.m = m
35
+ this.fnName = fnName
36
+ }
37
+
38
+ /**
39
+ * 格式化参数:提取提示符,构建前缀,将对象后置
40
+ * 格式要求:[模块名称:函数名称]提示符: {对象}
41
+ * @param {any[]} args
42
+ * @returns {any[]} 返回处理后传递给 console 的参数数组
43
+ */
44
+ formatArgs(args) {
45
+ let R = ''
46
+ const _ = this
47
+ try {
48
+ const msgs = []
49
+ const objs = []
50
+
51
+ // 1. 将字符串(提示符)和非字符串(对象/数值等)分开
52
+ for (const arg of args) {
53
+ if (typeof arg === 'string') msgs.push(arg)
54
+ else objs.push(arg)
55
+ }
56
+
57
+ let prefix = ''
58
+
59
+ // 2. 添加模块与函数前缀
60
+ if (_.m) prefix = `[${_.m}${_.fnName ? ':' + _.fnName : ''}]`
61
+ else if (_.fnName) prefix = `[:${_.fnName}]`
62
+
63
+ // 3. 拼接提示符
64
+ const msg = msgs.join(' ')
65
+ if (msg) prefix += msg
66
+
67
+ R = []
68
+ if (prefix) R.push(prefix)
69
+ R.push(...objs)
70
+ } catch (e) {
71
+ console.error(`formatArgs exp:${e.message}`)
72
+ }
73
+
74
+ return R
75
+ }
76
+
77
+ /** @param {...any} args */
78
+ log(...args) {
79
+ // 生产环境安全剔除 (需 Rspack DefinePlugin 注入 __DEV__)
80
+ if (isDev) console.log(...this.formatArgs(args))
81
+ }
82
+
83
+ /** @param {...any} args */
84
+ debug(...args) {
85
+ if (isDev) console.debug(...this.formatArgs(args))
86
+ }
87
+
88
+ /** @param {...any} args */
89
+ info(...args) {
90
+ if (isDev) console.info(...this.formatArgs(args))
91
+ }
92
+
93
+ /** @param {...any} args */
94
+ warn(...args) {
95
+ if (isDev) console.warn(...this.formatArgs(args))
96
+ }
97
+
98
+ /** @param {...any} args */
99
+ trace(...args) {
100
+ if (isDev) console.trace(...this.formatArgs(args))
101
+ }
102
+
103
+ /** * error 会在生产环境保留
104
+ * @param {...any} args
105
+ */
106
+ error(...args) {
107
+ console.error(...this.formatArgs(args))
108
+ }
109
+
110
+ /**
111
+ * 用于 catch(e) log.err(e) 或 log.err("提示符", e) 或 log.err(e, "提示符")
112
+ * 自动对齐前缀 [模块:函数] 提示符: Error对象,并保留堆栈
113
+ * @param {...any} args
114
+ */
115
+ err(...args) {
116
+ // 生产环境安全输出,不会被 Tree-shaking 摇掉
117
+ // formatArgs 会自动分离字符串与 Error 对象,并补全冒号
118
+ const formattedArgs = this.formatArgs(args)
119
+
120
+ // 原生打印,保持 stack trace 可点击跳转!
121
+ console.error(...formattedArgs)
122
+ }
123
+
124
+ /**
125
+ * 派生函数级别日志实例 (完美对齐后端 log.fn)
126
+ * @param {string} name 函数名称
127
+ * @returns {ScopedLogger}
128
+ */
129
+ fn(name) {
130
+ const scopedLog = new Log(this.m, name)
131
+
132
+ /** @type {any} */
133
+ const R = (...args) => scopedLog.log(...args)
134
+
135
+ R.debug = scopedLog.debug.bind(scopedLog)
136
+ R.info = scopedLog.info.bind(scopedLog)
137
+ R.warn = scopedLog.warn.bind(scopedLog)
138
+ R.trace = scopedLog.trace.bind(scopedLog)
139
+ R.error = scopedLog.error.bind(scopedLog)
140
+ R.err = scopedLog.err.bind(scopedLog)
141
+
142
+ return /** @type {ScopedLogger} */ (R)
143
+ }
144
+ }
145
+
146
+ // 实例化唯一的全局日志单例
147
+ const _log = new Log()
148
+
149
+ /**
150
+ * 标准日志输出或构建模块日志类实例,用于模块中带[m:xxx]标记日志输出
151
+ * 传入 { m: '模块名' } 构建实例,或直接传入参数输出全局日志
152
+ * @param {...any} args - params
153
+ * returns {*}
154
+ */
155
+ function log(...args) {
156
+ const last = args.at(-1)
157
+
158
+ // 1. 如果只有一个参数且带 m 属性,说明是构造 Logger 实例 (如: const log = Log({m: 'User'}))
159
+ if (args.length === 1 && typeof last === 'object' && last !== null && 'm' in last) {
160
+ const lg = new Log(last.m)
161
+
162
+ /** @type {any} */
163
+ const R = (...args2) => lg.log(...args2)
164
+
165
+ R.log = lg.log.bind(lg)
166
+ R.debug = lg.debug.bind(lg)
167
+ R.info = lg.info.bind(lg)
168
+ R.warn = lg.warn.bind(lg)
169
+ R.trace = lg.trace.bind(lg)
170
+ R.error = lg.error.bind(lg)
171
+ R.err = lg.err.bind(lg)
172
+ R.fn = lg.fn.bind(lg) // 暴露派生函数作用域方法
173
+
174
+ return /** @type {LoggerFn} */ (R)
175
+ }
176
+
177
+ // 2. 否则作为全局普通日志直接输出
178
+ _log.log(...args)
179
+ }
180
+
181
+ // 绑定全局快捷方法,方便直接调用 log.err(e) 等
182
+ log.err = _log.err.bind(_log)
183
+ log.error = _log.error.bind(_log)
184
+ log.warn = _log.warn.bind(_log)
185
+ log.info = _log.info.bind(_log)
186
+ log.debug = _log.debug.bind(_log)
187
+ log.trace = _log.trace.bind(_log)
188
+
189
+ export {log, Log}