20 lines
1.1 KiB
TypeScript
20 lines
1.1 KiB
TypeScript
/**
|
|
* 对已适合 JSON 往返的数据做脱离与冻结,并记录该次捕获的来源。
|
|
* 输入是否合法由调用边界负责;来源证明不等于组件 schema、owner 或引用已合法。
|
|
*/
|
|
import {clone,freeze} from './values.ts';
|
|
|
|
// Private provenance for a fresh, recursively frozen JSON clone. A caller can
|
|
// request a detached copy, but cannot grant this fact to an existing object.
|
|
const detached=new WeakSet<object>();
|
|
/** JSON 复制后递归冻结;仅对象结果记录到 WeakSet。
|
|
* 输入先经过 JSON 序列化语义:toJSON/getter 可能执行,稀疏槽/数组中的非法 JSON 值可能转为 null。
|
|
* 循环或 BigInt 等仍会抛错;它不保留任意输入原貌,不能替代迁移输入的严格捕获校验。 */
|
|
export function detachJsonData<T>(input:T):T {
|
|
const value=freeze(clone(input));
|
|
if(value&&typeof value==='object')detached.add(value);
|
|
return value;
|
|
}
|
|
/** 只查询本模块产生的对象身份,不从外部 frozen 状态反推来源。 */
|
|
export const hasDetachedJsonData=(value:object)=>detached.has(value);
|