minigame-std
Version:
Cross-platform standard library for WeChat minigame and web browsers with unified APIs for crypto, fs, fetch, storage, and more.
1 lines • 15.3 kB
Source Map (JSON)
{"version":3,"file":"performance.mjs","names":[],"sources":["../src/macros/env.ts","../src/std/platform/base.ts","../src/std/platform/user_agent.ts","../src/std/platform/device.ts","../src/std/platform/target.ts","../src/std/performance/mod.ts"],"sourcesContent":["/**\n * @internal\n * 小游戏环境宏模块。\n */\n\n/**\n * 小游戏环境宏。\n *\n * 可通过打包工具在 build 时修改,如 esbuild webpack vite 等。\n */\ndeclare const __MINIGAME_STD_MINA__: boolean;\n\n/**\n * 如果在小游戏环境中返回 true,否则返回 false。\n */\nexport const IS_MINA = __MINIGAME_STD_MINA__;\n","/**\n * 平台类型,Web 或者小游戏。\n * @since 1.0.0\n * @example\n * ```ts\n * import { platform, type TargetType } from 'minigame-std';\n *\n * const type: TargetType = platform.getTargetType();\n * console.log(type); // 'minigame' 或 'web'\n * ```\n */\nexport type TargetType = 'minigame' | 'web';\n\n/**\n * 获取当前的平台类型。\n * @returns 返回当前的运行环境类型,可能是 'minigame' 或 'web'。\n * @since 1.0.0\n * @example\n * ```ts\n * const type = getTargetType();\n * console.log('当前平台:', type); // 'minigame' 或 'web'\n * ```\n */\nexport function getTargetType(): TargetType {\n return 'wx' in globalThis ? 'minigame' : 'web';\n}\n\n/**\n * 判断当前是否在 Web 环境中。\n * @returns 如果在 Web 环境中返回 true,否则返回 false。\n * @since 1.0.0\n * @example\n * ```ts\n * if (isWeb()) {\n * console.log('当前在浏览器环境');\n * }\n * ```\n */\nexport function isWeb(): boolean {\n return getTargetType() === 'web';\n}\n\n/**\n * 判断当前是否在小游戏环境中。\n * @returns 如果在小游戏环境中返回 true,否则返回 false。\n * @since 1.0.0\n * @example\n * ```ts\n * if (isMiniGame()) {\n * console.log('当前在小游戏环境');\n * }\n * ```\n */\nexport function isMiniGame(): boolean {\n return getTargetType() === 'minigame';\n}","/**\n * 解析 userAgent 获取设备信息。\n * @param ua - 要解析的 userAgent 字符串,默认为 navigator.userAgent。\n * @returns 解析后的设备信息,包含 model、platform 和 system。\n * @internal\n */\nexport function parseUserAgent(ua: string = navigator.userAgent): { model: string; platform: string; system: string; } {\n // iOS 设备: iPhone/iPad/iPod\n // 示例: Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X)\n // wx.getDeviceInfo: model=\"iPhone 17 Pro<iPhone18,1>\", system=\"iOS 26.2\"\n const iosMatch = ua.match(/\\((iPhone|iPad|iPod);.*?OS (\\d+[_\\d]*)/);\n if (iosMatch) {\n const model = iosMatch[1];\n const version = iosMatch[2].replace(/_/g, '.');\n return { model, platform: 'ios', system: `iOS ${version}` };\n }\n\n // Android 设备\n // 示例1: Linux; Android 12; ELS-AN00 Build/HUAWEIELS-AN00\n // wx.getDeviceInfo: model=\"ELS-AN00\", system=\"Android 12\"\n // 示例2: Linux; U; Android 13; zh-cn; 22127RK46C Build/TKQ1.220905.001\n // wx.getDeviceInfo: model=\"22127RK46C\", system=\"Android 13\"\n // 注意: model 是 Build/ 前面的最后一个字段\n const androidMatch = ua.match(/Android\\s+([\\d.]+);(?:.*?;\\s*)?([^;]+)\\s+Build/);\n if (androidMatch) {\n const version = androidMatch[1];\n const model = androidMatch[2].trim();\n return { model, platform: 'android', system: `Android ${version}` };\n }\n\n // Mac\n // 示例: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)\n const macMatch = ua.match(/Mac OS X (\\d+[_\\d]*)/);\n if (macMatch) {\n const version = macMatch[1].replace(/_/g, '.');\n return { model: 'Mac', platform: 'mac', system: `macOS ${version}` };\n }\n\n // Windows\n // 示例: Mozilla/5.0 (Windows NT 10.0; Win64; x64)\n const winMatch = ua.match(/Windows NT ([\\d.]+)/);\n if (winMatch) {\n return { model: 'PC', platform: 'windows', system: `Windows NT ${winMatch[1]}` };\n }\n\n // Linux\n if (ua.includes('Linux')) {\n return { model: 'Linux', platform: 'linux', system: 'Linux' };\n }\n\n return { model: 'unknown', platform: 'unknown', system: 'unknown' };\n}\n","import { Lazy, Ok, OnceAsync, type AsyncIOResult } from 'happy-rusty';\nimport { IS_MINA } from '../../macros/env.ts';\nimport { asyncIOResultify } from '../utils/mod.ts';\nimport { parseUserAgent } from './user_agent.ts';\n\n// #region Internal Variables\n\n// 以下变量一旦获取则不会变化\n// 兼容基础库低版本\nconst deviceInfo = /*#__PURE__*/ Lazy<DeviceInfo>(() => IS_MINA\n ? (wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync()) as unknown as DeviceInfo\n : getWebDeviceInfo(),\n);\nconst benchmarkLevel = /*#__PURE__*/ OnceAsync<number>();\n\n// #endregion\n\n/**\n * 获取设备信息。\n * @returns 返回小游戏的设备信息对象。\n * @since 1.0.0\n * @example\n * ```ts\n * const info = getDeviceInfo();\n * console.log('设备平台:', info.platform);\n * console.log('设备品牌:', info.brand);\n * console.log('设备型号:', info.model);\n * ```\n */\nexport function getDeviceInfo(): DeviceInfo {\n return deviceInfo.force();\n}\n\n/**\n * 获取设备性能等级, web 环境返回 -2。\n * @returns 返回设备性能等级。\n * @since 1.10.0\n * @example\n * ```ts\n * const result = await getDeviceBenchmarkLevel();\n * if (result.isOk()) {\n * const level = result.unwrap();\n * if (level >= 30) {\n * console.log('高性能设备');\n * } else if (level >= 20) {\n * console.log('中等性能设备');\n * } else {\n * console.log('低性能设备');\n * }\n * }\n * ```\n */\nexport async function getDeviceBenchmarkLevel(): AsyncIOResult<number> {\n // 小游戏从-1开始,-2表示web环境\n if (!IS_MINA) {\n return Ok(-2);\n }\n\n if (benchmarkLevel.isInitialized()) {\n return Ok(benchmarkLevel.get().unwrap());\n }\n\n // 优先使用新 API\n if (typeof wx.getDeviceBenchmarkInfo === 'function') {\n return await benchmarkLevel.getOrTryInit(async () => {\n const benchmarkInfoRes = await asyncIOResultify(wx.getDeviceBenchmarkInfo)();\n\n return benchmarkInfoRes.map(x => x.benchmarkLevel);\n });\n }\n\n // 兼容低版本基础库\n const level = getDeviceInfo().benchmarkLevel;\n benchmarkLevel.set(level);\n\n return Ok(level);\n}\n\n/**\n * 获取窗口信息。\n * @returns 包含窗口和屏幕相关信息的对象。\n * @since 1.7.0\n * @example\n * ```ts\n * const info = getWindowInfo();\n * console.log('窗口尺寸:', info.windowWidth, 'x', info.windowHeight);\n * console.log('屏幕尺寸:', info.screenWidth, 'x', info.screenHeight);\n * console.log('设备像素比:', info.pixelRatio);\n * ```\n */\nexport function getWindowInfo(): WechatMinigame.WindowInfo {\n return IS_MINA ? wx.getWindowInfo() : getWebWindowInfo();\n}\n\n/**\n * 平台类型。\n * @since 1.0.0\n * @example\n * ```ts\n * import { platform, type Platform } from 'minigame-std';\n *\n * const info = platform.getDeviceInfo();\n * const devicePlatform: Platform = info.platform;\n * console.log(devicePlatform); // 'ios' | 'android' | 'mac' | ...\n * ```\n */\nexport type Platform = 'ios' | 'android' | 'mac' | 'windows' | 'ohos' | 'ohos_pc' | 'devtools' | 'linux' | 'unknown';\n\n/**\n * 设备信息类型。\n * 修正了 `memorySize` 的类型为 `number`(小游戏 API 实际返回数字,但官方类型定义错误地声明为 string)。\n * @see https://github.com/wechat-miniprogram/minigame-api-typings/issues/27\n * @since 1.0.0\n * @example\n * ```ts\n * import { platform, type DeviceInfo } from 'minigame-std';\n *\n * const info: DeviceInfo = platform.getDeviceInfo();\n * console.log('平台:', info.platform);\n * console.log('内存:', info.memorySize, 'MB');\n * ```\n */\nexport type DeviceInfo = Omit<WechatMinigame.DeviceInfo, 'abi' | 'cpuType' | 'deviceAbi' | 'memorySize' | 'platform'> & {\n abi?: string;\n cpuType?: string;\n deviceAbi?: string;\n /** 设备内存大小,单位为 MB */\n memorySize: number;\n /** 设备平台 */\n platform: Platform;\n};\n\n// #region Internal Functions\n\n/**\n * 获取 Web 环境下的设备信息。\n */\nfunction getWebDeviceInfo(): DeviceInfo {\n const { model, platform, system } = parseUserAgent();\n const memorySize = ((navigator as Navigator & { deviceMemory?: number; }).deviceMemory ?? 0) * 1024;\n\n return {\n benchmarkLevel: -2, // Web 环境固定返回 -2\n brand: '', // Web 环境无法可靠获取品牌信息\n memorySize,\n model,\n platform: platform as Platform,\n system,\n };\n}\n\n/**\n * 获取 Web 环境下的窗口信息。\n */\nfunction getWebWindowInfo(): WechatMinigame.WindowInfo {\n return {\n pixelRatio: devicePixelRatio,\n screenHeight: screen.height,\n screenTop,\n screenWidth: screen.width,\n windowHeight: innerHeight,\n windowWidth: innerWidth,\n statusBarHeight: 0,\n safeArea: {\n left: 0,\n right: innerWidth,\n top: 0,\n bottom: innerHeight,\n width: innerWidth,\n height: innerHeight,\n },\n };\n}\n\n// #endregion\n","import { isMiniGame } from './base.ts';\nimport { getDeviceInfo } from './device.ts';\n\n/**\n * 判断当前是否在小游戏的运行时环境中。\n * @returns 如果在小游戏的运行时环境中返回 true,否则返回 false。\n * @since 1.9.0\n * @example\n * ```ts\n * if (isMiniGameRuntime()) {\n * console.log('在小游戏真机环境中');\n * }\n * ```\n */\nexport function isMiniGameRuntime(): boolean {\n return isMiniGame() && getPlatform() !== 'devtools';\n}\n\n/**\n * 判断当前是否在小游戏的开发者工具中。\n * @returns 如果在小游戏的开发者工具中返回 true,否则返回 false。\n * @since 1.9.0\n * @example\n * ```ts\n * if (isMiniGameDevtools()) {\n * console.log('在开发者工具中');\n * }\n * ```\n */\nexport function isMiniGameDevtools(): boolean {\n return isMiniGame() && getPlatform() === 'devtools';\n}\n\n/**\n * 判断当前是否在小游戏的 iOS 环境中。\n * @returns 如果在小游戏的 iOS 环境中返回 true,否则返回 false。\n * @since 1.9.0\n * @example\n * ```ts\n * if (isMiniGameIOS()) {\n * console.log('在 iOS 设备上运行');\n * }\n * ```\n */\nexport function isMiniGameIOS(): boolean {\n return isMiniGame() && getPlatform() === 'ios';\n}\n\n/**\n * 判断当前是否在小游戏的 Android 环境中。\n * @returns 如果在小游戏的 Android 环境中返回 true,否则返回 false。\n * @since 1.9.0\n * @example\n * ```ts\n * if (isMiniGameAndroid()) {\n * console.log('在 Android 设备上运行');\n * }\n * ```\n */\nexport function isMiniGameAndroid(): boolean {\n return isMiniGame() && getPlatform() === 'android';\n}\n\n/**\n * 判断当前是否在小游戏的 Windows 环境中。\n * @returns 如果在小游戏的 Windows 环境中返回 true,否则返回 false。\n * @since 1.9.0\n * @example\n * ```ts\n * if (isMiniGameWin()) {\n * console.log('在 Windows 设备上运行');\n * }\n * ```\n */\nexport function isMiniGameWin(): boolean {\n return isMiniGame() && getPlatform() === 'windows';\n}\n\n/**\n * 判断当前是否在小游戏的 Mac 环境中。\n * @returns 如果在小游戏的 Mac 环境中返回 true,否则返回 false。\n * @since 1.9.0\n * @example\n * ```ts\n * if (isMiniGameMac()) {\n * console.log('在 Mac 设备上运行');\n * }\n * ```\n */\nexport function isMiniGameMac(): boolean {\n return isMiniGame() && getPlatform() === 'mac';\n}\n\n/**\n * 判断当前是否在小游戏的 HarmonyOS 环境中。\n * @returns 如果在小游戏的 HarmonyOS 环境中返回 true,否则返回 false。\n * @since 1.9.0\n * @example\n * ```ts\n * if (isMiniGameHarmonyOS()) {\n * console.log('在 HarmonyOS 设备上运行');\n * }\n * ```\n */\nexport function isMiniGameHarmonyOS(): boolean {\n return isMiniGame() && getPlatform() === 'ohos';\n}\n\n/**\n * 判断当前是否在小游戏的 HarmonyOS PC 环境中。\n * @returns 如果在小游戏的 HarmonyOS PC 环境中返回 true,否则返回 false。\n * @since 2.4.0\n * @example\n * ```ts\n * if (isMiniGameHarmonyPC()) {\n * console.log('在 HarmonyOS PC 设备上运行');\n * }\n * ```\n */\nexport function isMiniGameHarmonyPC(): boolean {\n return isMiniGame() && getPlatform() === 'ohos_pc';\n}\n\n// #region Internal Functions\n\n/**\n * 获取当前平台类型。\n */\nfunction getPlatform(): string {\n return getDeviceInfo().platform.toLowerCase();\n}\n\n// #endregion","/**\n * 性能模块,提供高精度时间戳获取功能。\n * @module performance\n */\nimport { Lazy } from 'happy-rusty';\nimport { IS_MINA } from '../../macros/env.ts';\nimport { isMiniGameDevtools } from '../platform/target.ts';\n\n// #region Internal Variables\n\n/**\n * 小游戏性能管理器实例(延迟初始化)。\n */\nconst minaPerformance = /*#__PURE__*/ Lazy(() => wx.getPerformance());\n\n// #endregion\n\n/**\n * 参见`performance.now()`\n * @returns 当前时间以毫秒为单位的时间戳\n * @since 2.0.0\n * @example\n * ```ts\n * const start = getPerformanceNow();\n * // 执行一些操作...\n * const end = getPerformanceNow();\n * console.log('耗时:', end - start, 'ms');\n * ```\n */\nexport function getPerformanceNow(): number {\n return IS_MINA\n // 小游戏 的 performance.now() 返回的是微秒\n // NOTE: 但是小游戏开发者工具返回的是毫秒\n ? minaPerformance.force().now() / (isMiniGameDevtools() ? 1 : 1000)\n : performance.now();\n}\n"],"mappings":";;;;;AAeA,MAAa,UAAU;;;;;;;;;;;;;ACQvB,SAAgB,gBAA4B;CACxC,OAAO,QAAQ,aAAa,aAAa;AAC7C;;;;;;;;;;;;AA4BA,SAAgB,aAAsB;CAClC,OAAO,cAAc,MAAM;AAC/B;;;;;;;;;ACjDA,SAAgB,eAAe,KAAa,UAAU,WAAiE;CAInH,MAAM,WAAW,GAAG,MAAM,wCAAwC;CAClE,IAAI,UAGA,OAAO;EAAE,OAFK,SAAS;EAEP,UAAU;EAAO,QAAQ,OADzB,SAAS,EAAE,CAAC,QAAQ,MAAM,GACM;CAAU;CAS9D,MAAM,eAAe,GAAG,MAAM,gDAAgD;CAC9E,IAAI,cAAc;EACd,MAAM,UAAU,aAAa;EAE7B,OAAO;GAAE,OADK,aAAa,EAAE,CAAC,KACrB;GAAO,UAAU;GAAW,QAAQ,WAAW;EAAU;CACtE;CAIA,MAAM,WAAW,GAAG,MAAM,sBAAsB;CAChD,IAAI,UAEA,OAAO;EAAE,OAAO;EAAO,UAAU;EAAO,QAAQ,SADhC,SAAS,EAAE,CAAC,QAAQ,MAAM,GACe;CAAU;CAKvE,MAAM,WAAW,GAAG,MAAM,qBAAqB;CAC/C,IAAI,UACA,OAAO;EAAE,OAAO;EAAM,UAAU;EAAW,QAAQ,cAAc,SAAS;CAAK;CAInF,IAAI,GAAG,SAAS,OAAO,GACnB,OAAO;EAAE,OAAO;EAAS,UAAU;EAAS,QAAQ;CAAQ;CAGhE,OAAO;EAAE,OAAO;EAAW,UAAU;EAAW,QAAQ;CAAU;AACtE;;;AC1CA,MAAM,aAA2B,yBAAuB,UACjD,GAAG,gBAAgB,GAAG,cAAc,IAAI,GAAG,kBAAkB,IAC9D,iBAAiB,CACvB;;;;;;;;;;;;;AAiBA,SAAgB,gBAA4B;CACxC,OAAO,WAAW,MAAM;AAC5B;;;;AA0GA,SAAS,mBAA+B;CACpC,MAAM,EAAE,OAAO,UAAU,WAAW,eAAe;CAGnD,OAAO;EACH,gBAAgB;EAChB,OAAO;EACP,aALiB,UAAqD,gBAAgB,KAAK;EAM3F;EACU;EACV;CACJ;AACJ;;;;;;;;;;;;;;ACxHA,SAAgB,qBAA8B;CAC1C,OAAO,WAAW,KAAK,YAAY,MAAM;AAC7C;;;;AAiGA,SAAS,cAAsB;CAC3B,OAAO,cAAc,CAAC,CAAC,SAAS,YAAY;AAChD;;;;;;;;;;ACrHA,MAAM,kBAAgC,yBAAW,GAAG,eAAe,CAAC;;;;;;;;;;;;;AAgBpE,SAAgB,oBAA4B;CACxC,OAAO,UAGD,gBAAgB,MAAM,CAAC,CAAC,IAAI,KAAK,mBAAmB,IAAI,IAAI,OAC5D,YAAY,IAAI;AAC1B"}