| 123456789101112131415161718192021222324252627282930 |
- // lib/messageKey.ts:由 lib/utils.ts 按职责拆分(实现未改)
- let messageSeq = 0;
- // 极端情况兜底(对象被冻结/密封等无法挂属性时),用 WeakMap 记录
- const messageKeyFallback = new WeakMap<object, string>();
- /**
- * 消息的稳定标识:同一条消息在整个生命周期内返回同一个 key,供列表渲染与「按消息」存储的局部状态
- * (思考折叠、引用折叠、复制态、编辑态、回答切换位置)使用。
- *
- * 不能用下标:消息被截断重发或重新生成后下标会整体前移,这些状态就会跟错消息。
- * 也不能用后端 id:那是流式结束后才回填的,key 变化会导致节点重建、状态丢失。
- * uid 挂在消息对象上且不可枚举,不会进入请求体或序列化结果。
- */
- export const getMessageKey = (message: unknown): string => {
- const target = message as Record<string, unknown> | null | undefined;
- if (!target || typeof target !== 'object') return 'unknown';
- if (typeof target.__uid !== 'string') {
- const uid = `msg-${++messageSeq}`;
- try {
- Object.defineProperty(target, '__uid', { value: uid, enumerable: false, configurable: true, writable: true });
- } catch {
- const existing = messageKeyFallback.get(target);
- if (existing) return existing;
- messageKeyFallback.set(target, uid);
- return uid;
- }
- }
- return target.__uid as string;
- };
|