@vitarx/responsive
Version:
Vitarx responsive package
113 lines (112 loc) • 4.95 kB
JavaScript
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;
}