// jest setup: polyfill structuredClone for fake-indexeddb if (typeof globalThis.structuredClone !== 'function') { // 注意:不能用 JSON 序列化 —— ArrayBuffer/TypedArray 会被破坏成 {}, // fake-indexeddb 存储 AriaEngine 二进制页面(4KB SSTable/WAL)依赖正确的克隆。 // 且不能依赖 instanceof(TextEncoder 产生 node realm 的 ArrayBuffer, // 与 jsdom realm 的构造函数不匹配),需用跨 realm 的 toString 标签检查。 globalThis.structuredClone = (obj) => { const tag = Object.prototype.toString.call(obj); if (tag === '[object ArrayBuffer]') return obj.slice(0); if (ArrayBuffer.isView(obj)) return new obj.constructor(obj); return JSON.parse(JSON.stringify(obj)); }; } // polyfill TextEncoder/TextDecoder for jsdom environment if (typeof globalThis.TextEncoder === 'undefined') { const { TextEncoder: TE, TextDecoder: TD } = require('util'); globalThis.TextEncoder = TE; globalThis.TextDecoder = TD; } if (typeof globalThis.TextDecoder === 'undefined') { const { TextDecoder: TD } = require('util'); globalThis.TextDecoder = TD; } // polyfill WebCrypto (crypto.subtle) — jsdom 仅提供 getRandomValues if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.subtle === 'undefined') { const { webcrypto } = require('crypto'); globalThis.crypto = webcrypto; // jsdom 环境暴露 getRandomValues 的旧引用可能被覆盖,统一替换 Object.defineProperty(globalThis, 'crypto', { value: webcrypto, writable: true, configurable: true, }); }