@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.cjs 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
  */
@@ -2075,227 +2075,193 @@ class Event {
2075
2075
  }
2076
2076
  }
2077
2077
 
2078
- /*!
2079
- * wia util v3.4.25
2080
- * (c) 2018-2024 Yan (Sibyl) Yu and Yuxi (Evan) You and wia/vue contributors
2081
- * Released under the MIT License.
2082
- */
2083
2078
  /**
2084
- * Created by way on 10/6/16.
2085
- * Part of the code comes from @vue/shared
2079
+ * @typedef {Object} LogOptions
2080
+ * @property {string} m - 模块名称
2081
+ */
2082
+
2083
+ /**
2084
+ * @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
2086
2085
  */
2087
2086
 
2088
-
2089
2087
  /**
2090
- * 前端日志输出,封装 console日志,简化代码,支持模块或直接输出
2091
- * 调用时,描述字符串后置,便于可选缺省,输出时,自带前置,类似 后端pino,保持前后端一致性
2092
- * m 为模块,fn 为函数名称
2088
+ * @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
2089
+ */
2090
+
2091
+ // 1. 安全地获取开发环境状态(兼容打包工具、浏览器和 Node.js)
2092
+ // 如果 Rspack 注入了 __DEV__,就用注入的值;如果是在 Node.js 下,就回退读取 "production"
2093
+ const isDev = typeof __DEV__ !== 'undefined' ? __DEV__ : "production" !== 'production';
2094
+
2095
+ /**
2096
+ * 前端日志输出,封装 console 日志,简化代码
2097
+ * 自动识别并重排提示符与对象,保持前后端一致性
2093
2098
  */
2094
2099
  class Log {
2095
- /** @type {string} 模块 */
2100
+ /** @type {string} 模块名称 */
2096
2101
  m = ''
2097
2102
 
2098
- /** @type {string} 函数 */
2099
- fn = ''
2103
+ /** @type {string} 函数名称 */
2104
+ fnName = ''
2100
2105
 
2101
2106
  /**
2102
- * @param {string} m 模块
2107
+ * @param {string} [m=''] 模块
2108
+ * @param {string} [fnName=''] 函数
2103
2109
  */
2104
- constructor(m) {
2110
+ constructor(m = '', fnName = '') {
2105
2111
  this.m = m;
2112
+ this.fnName = fnName;
2106
2113
  }
2107
2114
 
2108
2115
  /**
2109
- * get log desc
2110
- * 描述字符串后置调用,前置显示
2111
- * @param {*[]} args
2112
- * @returns {string}
2116
+ * 格式化参数:提取提示符,构建前缀,将对象后置
2117
+ * 格式要求:[模块名称:函数名称]提示符: {对象}
2118
+ * @param {any[]} args
2119
+ * @returns {any[]} 返回处理后传递给 console 的参数数组
2113
2120
  */
2114
- getDesc(args) {
2121
+ formatArgs(args) {
2115
2122
  let R = '';
2123
+ const _ = this;
2116
2124
  try {
2117
- const _ = this;
2118
- const { m } = _;
2119
- let fn = '',
2120
- desc = '';
2121
-
2122
- if (args.length > 1) {
2123
- const last = args.at(-1);
2124
- if (typeof last === 'object') {
2125
- ;({ desc, fn } = last);
2126
- } else if (typeof last === 'string') desc = last;
2127
- if (desc || fn) {
2128
- fn = fn || _.fn;
2129
- _.fn = fn;
2130
- args.pop();
2131
- }
2125
+ const msgs = [];
2126
+ const objs = [];
2127
+
2128
+ // 1. 将字符串(提示符)和非字符串(对象/数值等)分开
2129
+ for (const arg of args) {
2130
+ if (typeof arg === 'string') msgs.push(arg);
2131
+ else objs.push(arg);
2132
2132
  }
2133
- fn = fn || _.fn;
2134
- if (m) desc = `${desc}[${m}${fn ? ':' + fn : ''}]`; // eslint-disable-line
2135
- R = desc;
2133
+
2134
+ let prefix = '';
2135
+
2136
+ // 2. 添加模块与函数前缀
2137
+ if (_.m) prefix = `[${_.m}${_.fnName ? ':' + _.fnName : ''}]`;
2138
+ else if (_.fnName) prefix = `[:${_.fnName}]`;
2139
+
2140
+ // 3. 拼接提示符
2141
+ const msg = msgs.join(' ');
2142
+ if (msg) prefix += msg;
2143
+
2144
+ R = [];
2145
+ if (prefix) R.push(prefix);
2146
+ R.push(...objs);
2136
2147
  } catch (e) {
2137
- console.error(`getDesc exp:${e.message}`);
2148
+ console.error(`formatArgs exp:${e.message}`);
2138
2149
  }
2139
2150
 
2140
2151
  return R
2141
2152
  }
2142
2153
 
2143
- /** @param {...any} args - params */
2154
+ /** @param {...any} args */
2144
2155
  log(...args) {
2145
- const _ = this;
2146
- const last = args.at(-1);
2147
- // clear fn
2148
- if (args.length === 1 && typeof last === 'object' && last.fn) _.fn = '';
2149
- else {
2150
- const desc = _.getDesc(args);
2151
- console.log(desc, ...args);
2152
- }
2156
+ // 生产环境安全剔除 (需 Rspack DefinePlugin 注入 __DEV__)
2157
+ if (isDev) console.log(...this.formatArgs(args));
2153
2158
  }
2154
2159
 
2155
- /** @param {...any} args - params */
2160
+ /** @param {...any} args */
2156
2161
  debug(...args) {
2157
- const _ = this;
2158
- const desc = _.getDesc(args);
2159
- if (desc) console.log(desc, ...args);
2160
- else console.log(...args);
2162
+ if (isDev) console.debug(...this.formatArgs(args));
2161
2163
  }
2162
2164
 
2163
- /** @param {...any} args - params */
2165
+ /** @param {...any} args */
2164
2166
  info(...args) {
2165
- const _ = this;
2166
- const desc = _.getDesc(args);
2167
- if (desc) console.info(desc, ...args);
2168
- else console.log(...args);
2167
+ if (isDev) console.info(...this.formatArgs(args));
2169
2168
  }
2170
2169
 
2171
- /** @param {...any} args - params */
2170
+ /** @param {...any} args */
2172
2171
  warn(...args) {
2173
- const _ = this;
2174
- const { desc, arg } = _.getDesc(args);
2175
- if (desc) console.warn(desc, ...arg);
2176
- else console.log(...args);
2172
+ if (isDev) console.warn(...this.formatArgs(args));
2177
2173
  }
2178
2174
 
2179
- /** @param {...any} args - params */
2175
+ /** @param {...any} args */
2180
2176
  trace(...args) {
2181
- const _ = this;
2182
- const { desc, arg } = _.getDesc(args);
2183
- if (desc) console.trace(desc, ...arg);
2184
- else console.trace(...args);
2177
+ if (isDev) console.trace(...this.formatArgs(args));
2185
2178
  }
2186
2179
 
2187
- /** @param {...any} args - params */
2180
+ /** * error 会在生产环境保留
2181
+ * @param {...any} args
2182
+ */
2188
2183
  error(...args) {
2189
- const _ = this;
2190
- const desc = _.getDesc(args);
2191
- if (desc) console.error(desc, ...args);
2192
- else console.log(...args);
2184
+ console.error(...this.formatArgs(args));
2193
2185
  }
2194
2186
 
2195
2187
  /**
2196
- * 用于 catch(e) log.err(e)
2197
- * @param {...any} args - params */
2188
+ * 用于 catch(e) log.err(e) 或 log.err("提示符", e) 或 log.err(e, "提示符")
2189
+ * 自动对齐前缀 [模块:函数] 提示符: Error对象,并保留堆栈
2190
+ * @param {...any} args
2191
+ */
2198
2192
  err(...args) {
2199
- const _ = this;
2200
- const first = args?.[0];
2201
- if (
2202
- first instanceof Error ||
2203
- (first && first.message && first.cause && first.stack)
2204
- )
2205
- args[0] = { exp: args[0].message };
2206
- _.error(...args);
2193
+ // 生产环境安全输出,不会被 Tree-shaking 摇掉
2194
+ // formatArgs 会自动分离字符串与 Error 对象,并补全冒号
2195
+ const formattedArgs = this.formatArgs(args);
2196
+
2197
+ // 原生打印,保持 stack trace 可点击跳转!
2198
+ console.error(...formattedArgs);
2207
2199
  }
2208
- }
2209
2200
 
2210
- function getDesc(args) {
2211
- let desc = '';
2212
- const last = args.at(-1);
2213
- if (typeof last === 'string') {
2214
- desc = last;
2215
- args.pop();
2201
+ /**
2202
+ * 派生函数级别日志实例 (完美对齐后端 log.fn)
2203
+ * @param {string} name 函数名称
2204
+ * @returns {ScopedLogger}
2205
+ */
2206
+ fn(name) {
2207
+ const scopedLog = new Log(this.m, name);
2208
+
2209
+ /** @type {any} */
2210
+ const R = (...args) => scopedLog.log(...args);
2211
+
2212
+ R.debug = scopedLog.debug.bind(scopedLog);
2213
+ R.info = scopedLog.info.bind(scopedLog);
2214
+ R.warn = scopedLog.warn.bind(scopedLog);
2215
+ R.trace = scopedLog.trace.bind(scopedLog);
2216
+ R.error = scopedLog.error.bind(scopedLog);
2217
+ R.err = scopedLog.err.bind(scopedLog);
2218
+
2219
+ return /** @type {ScopedLogger} */ (R)
2216
2220
  }
2217
- return desc
2218
2221
  }
2219
2222
 
2223
+ // 实例化唯一的全局日志单例
2224
+ const _log = new Log();
2225
+
2220
2226
  /**
2221
2227
  * 标准日志输出或构建模块日志类实例,用于模块中带[m:xxx]标记日志输出
2222
- * 启用 {f:fn} 标记时,需在函数尾部清除f(log({f:''})),否则会溢出到其他函数
2228
+ * 传入 { m: '模块名' } 构建实例,或直接传入参数输出全局日志
2223
2229
  * @param {...any} args - params
2224
2230
  * returns {*}
2225
2231
  */
2226
2232
  function log(...args) {
2227
2233
  const last = args.at(-1);
2228
2234
 
2229
- // 全局日志
2230
- if (args.length !== 1 || !last?.m) {
2231
- const desc = getDesc(args);
2232
- desc ? console.log(desc, ...args) : console.log(...args);
2233
- return
2234
- }
2235
-
2236
- // 唯一 m 属性,则构造新的 log 实例,这种写法,能被jsDoc识别子属性
2237
- const lg = new Log(last?.m);
2238
- /** @param {*} args2 */
2239
- const R = (...args2) => lg.log(...args2);
2240
- R.debug = lg.debug.bind(lg);
2241
- R.info = lg.info.bind(lg);
2242
- R.warn = lg.warn.bind(lg);
2243
- R.info = lg.info.bind(lg);
2244
- R.trace = lg.trace.bind(lg);
2245
- R.error = lg.error.bind(lg);
2246
- R.err = lg.err.bind(lg);
2247
-
2248
- return R
2249
- }
2235
+ // 1. 如果只有一个参数且带 m 属性,说明是构造 Logger 实例 (如: const log = Log({m: 'User'}))
2236
+ if (args.length === 1 && typeof last === 'object' && last !== null && 'm' in last) {
2237
+ const lg = new Log(last.m);
2250
2238
 
2251
- /**
2252
- * 用于 catch(e) log.err(e)
2253
- * @param {...any} args - params */
2254
- log.err = (...args) => {
2255
- const desc = getDesc(args);
2256
- const first = args?.[0];
2257
- if (
2258
- first instanceof Error ||
2259
- (first && first.message && first.cause && first.stack)
2260
- )
2261
- args[0] = { exp: args[0].message };
2262
- desc ? console.error(desc, ...args) : console.error(...args);
2263
- };
2239
+ /** @type {any} */
2240
+ const R = (...args2) => lg.log(...args2);
2264
2241
 
2265
- /**
2266
- * @param {...any} args - params */
2267
- log.error = (...args) => {
2268
- const desc = getDesc(args);
2269
- desc ? console.error(desc, ...args) : console.error(...args);
2270
- };
2271
-
2272
- /**
2273
- * @param {...any} args - params */
2274
- log.warn = (...args) => {
2275
- const desc = getDesc(args);
2276
- desc ? console.warn(desc, ...args) : console.warn(...args);
2277
- };
2242
+ R.log = lg.log.bind(lg);
2243
+ R.debug = lg.debug.bind(lg);
2244
+ R.info = lg.info.bind(lg);
2245
+ R.warn = lg.warn.bind(lg);
2246
+ R.trace = lg.trace.bind(lg);
2247
+ R.error = lg.error.bind(lg);
2248
+ R.err = lg.err.bind(lg);
2249
+ R.fn = lg.fn.bind(lg); // 暴露派生函数作用域方法
2278
2250
 
2279
- /**
2280
- * @param {...any} args - params */
2281
- log.info = (...args) => {
2282
- const desc = getDesc(args);
2283
- desc ? console.info(desc, ...args) : console.info(...args);
2284
- };
2251
+ return /** @type {LoggerFn} */ (R)
2252
+ }
2285
2253
 
2286
- /**
2287
- * @param {...any} args - params */
2288
- log.debug = (...args) => {
2289
- const desc = getDesc(args);
2290
- desc ? console.log(desc, ...args) : console.log(...args);
2291
- };
2254
+ // 2. 否则作为全局普通日志直接输出
2255
+ _log.log(...args);
2256
+ }
2292
2257
 
2293
- /**
2294
- * @param {...any} args - params */
2295
- log.trace = (...args) => {
2296
- const desc = getDesc(args);
2297
- desc ? console.trace(desc, ...args) : console.trace(...args);
2298
- };
2258
+ // 绑定全局快捷方法,方便直接调用 log.err(e) 等
2259
+ log.err = _log.err.bind(_log);
2260
+ log.error = _log.error.bind(_log);
2261
+ log.warn = _log.warn.bind(_log);
2262
+ log.info = _log.info.bind(_log);
2263
+ log.debug = _log.debug.bind(_log);
2264
+ log.trace = _log.trace.bind(_log);
2299
2265
 
2300
2266
  /**
2301
2267
  * 所有页面从该类继承,并必须实现 load 事件!
@@ -2325,7 +2291,6 @@ log.trace = (...args) => {
2325
2291
  *
2326
2292
  */
2327
2293
 
2328
-
2329
2294
  class Page extends Event {
2330
2295
  constructor(app, name, title, style) {
2331
2296
  super(null, [app]);