UNPKG

@vitarx/responsive

Version:
113 lines (112 loc) 4.95 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _a, _ReadonlyHandler_cache, _ReadonlyHandler_options; import { isObject } from '@vitarx/utils'; import { Observer } from '../../../observer/index.js'; /** 只读对象标识 */ const READONLY_OBJECT_SYMBOL = Symbol('READONLY_OBJECT_SYMBOL'); /** * 只读代理 */ export class ReadonlyHandler { constructor(options) { _ReadonlyHandler_options.set(this, void 0); __classPrivateFieldSet(this, _ReadonlyHandler_options, { deep: options?.deep ?? true, write: options?.write ?? 'error', message: 'the object is read-only, and the ${prop} attribute cannot be modify!' }, "f"); } /** * 创建只读代理 * * @param target - 目标对象 * @param options - 代理选项 */ static create(target, options) { if (!__classPrivateFieldGet(this, _a, "f", _ReadonlyHandler_cache).has(target)) { __classPrivateFieldGet(this, _a, "f", _ReadonlyHandler_cache).set(target, new Proxy(target, new _a(options))); } return __classPrivateFieldGet(this, _a, "f", _ReadonlyHandler_cache).get(target); } set(target, prop, value) { if (__classPrivateFieldGet(this, _ReadonlyHandler_options, "f").write === 'error') { throw new Error(this.createMessage(prop, 'ERROR')); } if (import.meta.env.DEV) console.warn(this.createMessage(prop, 'WARN')); if (__classPrivateFieldGet(this, _ReadonlyHandler_options, "f").write === 'warningAndWrite') { return Reflect.set(target, prop, value); } return true; } deleteProperty(target, prop) { if (__classPrivateFieldGet(this, _ReadonlyHandler_options, "f").write === 'error') { throw new Error(this.createMessage(prop, 'ERROR')); } if (import.meta.env.DEV) console.warn(this.createMessage(prop, 'WARN')); if (__classPrivateFieldGet(this, _ReadonlyHandler_options, "f").write === 'warningAndWrite') { return Reflect.deleteProperty(target, prop); } return true; } /** * 创建提示信息 * * @param prop * @param type * @private */ createMessage(prop, type) { return `[Readonly][${type}]:` + __classPrivateFieldGet(this, _ReadonlyHandler_options, "f").message.replace('${prop}', String(prop)); } get(target, prop, receiver) { // 只读标识 if (prop === READONLY_OBJECT_SYMBOL) return true; // 返回监听目标 if (prop === Observer.TARGET_SYMBOL) return target; const data = Reflect.get(target, prop, receiver); if (__classPrivateFieldGet(this, _ReadonlyHandler_options, "f").deep && isObject(data) && !isReadonly(data)) { return _a.create(data, __classPrivateFieldGet(this, _ReadonlyHandler_options, "f")); } return data; } } _a = ReadonlyHandler, _ReadonlyHandler_options = new WeakMap(); _ReadonlyHandler_cache = { value: new WeakMap() }; /** * ## 判断是否为只读对象 * * 检查一个值是否是通过 `readonly()` 或 `shallowReadonly()` 创建的只读代理对象。 * 注意:此函数仅检查对象是否为只读代理,不能用于判断对象是否为响应式对象。 * * @template T - 要检查的对象类型 * @param {T} obj - 要检查的对象 * @returns {boolean} 如果对象是只读代理则返回true,否则返回false * @example * ```typescript * const original = { count: 0 } * const readonlyObj = readonly(original) * const shallowReadonlyObj = shallowReadonly(original) * * isReadonly(readonlyObj) // true * isReadonly(shallowReadonlyObj) // true * isReadonly(original) // false * isReadonly(null) // false * ``` */ export function isReadonly(obj) { return obj?.[READONLY_OBJECT_SYMBOL] === true; }