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":"platform.cjs","names":[],"sources":["../src/std/platform/base.ts","../src/macros/env.ts","../src/std/platform/user_agent.ts","../src/std/platform/device.ts","../src/std/platform/target.ts"],"sourcesContent":["/**\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 * @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 * 解析 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"],"mappings":"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"}