UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

87 lines (86 loc) 4.35 kB
/** * 蓝牙"碰一碰"纯函数工具集 * * 这里的所有函数都是 *无副作用* 的纯函数,不依赖 wx / 全局状态, * 因此可以脱离微信小程序环境直接 jest 单测。 */ import type { BluetoothBumpPayload, BluetoothDeviceInfo, ShouldTriggerBumpParams } from './types'; /** 生成 6 位随机大写临时 ID(写到广播特征值里) */ export declare function genTempId(): string; /** 把字符串编码为 ArrayBuffer,用于写入特征值 */ export declare function str2ArrayBuffer(str: string): ArrayBuffer; /** ArrayBuffer 转十六进制大写字符串 */ export declare function arrayBuffer2Hex(buf: ArrayBuffer | undefined | null): string; /** 反转十六进制字符串的字节序(小端 ↔ 大端) */ export declare function reverseHexBytes(hex: string): string; /** * 判断扫到的设备是否携带我们的 service * * iOS 上 startBluetoothDevicesDiscovery 不传 services 时收到的设备都需要手动过滤。 * 依次检查:advertisServiceUUIDs / serviceData / advertisData / 设备名前缀(BUMP_)。 * * ⚠️ iOS↔iOS 时前 3 项几乎都拿不到,必须靠设备名前缀做最终兜底。 */ export declare function matchesService(dev: BluetoothDeviceInfo, serviceUuid: string): boolean; /** * 判断这次扫描结果是否应该触发"碰一碰" * * 条件: * 1. RSSI 不低于阈值(够近) * 2. 距离上次同设备触发已超过冷却时间(避免重复) * * 抽成纯函数后,边界条件可以一行测一个。 */ export declare function shouldTriggerBump(params: ShouldTriggerBumpParams): boolean; /** * 把 myTempId / seenPeerId 组装为广播 payload 字符串。 * 固定长度,便于解析:`${myTempId}|${seenPeerId}` → 13 字节。 * * - myTempId 如果不足 TEMP_ID_LENGTH 位会自动补 '-'(防御性处理) * - seenPeerId 为空时填占位符 '------' */ export declare function encodePayload(myTempId: string, seenPeerId?: string | null): string; /** * 把 payload 编码进设备名(iOS Peripheral 唯一可控的广播字段)。 * `BUMP_<myTempId>_<seenPeerId>` → 例 `BUMP_ABC123_------`(19 字符) * * 不少机型对 localName 长度有限制(iOS Peripheral 推荐 ≤ 28 字节),这里 19 字符够用。 */ export declare function encodeBumpName(myTempId: string, seenPeerId?: string | null): string; /** * 解析设备名形如 `BUMP_ABC123_XYZ789` → { myTempId, seenPeerId }。 * 仅需 myTempId 时(旧格式 `BUMP_ABC123`)也兼容,seenPeerId 返回空串。 */ export declare function parseBumpName(name: string | undefined | null): BluetoothBumpPayload | null; /** * 解析广播 payload 字符串 → { myTempId, seenPeerId } * 解析失败返回 null(payload 不是本协议)。 * * seenPeerId 为占位符 '------' 时返回空字符串,方便上层 `if (seenPeerId)` 判断。 */ export declare function parsePayloadString(raw: string | undefined | null): BluetoothBumpPayload | null; /** * 从扫描到的设备里提取 mutual 协议 payload。 * * 解析顺序(按"iOS 上能拿到的可能性"由高到低): * 1. 设备名 / localName 前缀 `BUMP_` —— iOS↔iOS 唯一可靠通道 * 2. serviceData[serviceUuid] —— Android 标准方案 * 3. advertisData 整段 —— 部分机型把 payload 塞这里 * 4. 设备名按旧格式 `myTempId|seenPeerId` 解析(向后兼容) */ export declare function parsePayload(dev: BluetoothDeviceInfo, serviceUuid: string): BluetoothBumpPayload | null; /** 候选 peer 的内存记录 */ export interface PeerRecord { peerTempId: string; /** 对方广播里携带的"它看到的对方 ID"(用于判断是否是双向互认) */ seenPeerId: string; rssi: number; /** 最近一次见到的时间戳 */ lastSeen: number; /** 对应的原始设备,便于回传给业务方 */ dev: BluetoothDeviceInfo; } /** 从候选池里挑选"信号最强且在 TTL 内"的 peer(用于决定广播里要"点名"谁) */ export declare function pickBestPeer(peers: Map<string, PeerRecord>, now: number, ttlMs: number, rssiThreshold: number): PeerRecord | null; /** 清理候选池里过期的 peer(就地修改) */ export declare function pruneExpiredPeers(peers: Map<string, PeerRecord>, now: number, ttlMs: number): void;