UNPKG

@msom/common

Version:

@msom/common

1,284 lines (1,283 loc) 36.9 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); function assert(condition) { let message = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : ""; if (!condition) throw Error(message); } function nil(data, defaultData) { if (data === void 0 || data === null) { return defaultData; } return data; } class Collection { /** * 创建集合实例 * @param getKey 获取元素键值的函数 */ constructor(getKey) { assert(getKey, "miss get unique key"); this.getKey = getKey; this.elements = new Array(); this.elMap = /* @__PURE__ */ new Map(); this.indexMap = /* @__PURE__ */ new Map(); } /** * 获得集合的实际元素数量 */ size() { return Reflect.ownKeys(this.elements).length; } /** * 根据键值获取元素 * @param key 元素的键值 * @returns 对应的元素或undefined */ get(key) { return this.elMap.get(key); } /** * 检查是否存在指定键值的元素 * @param key 要检查的键值 * @returns 是否存在 */ hasKey(key) { return this.elMap.has(key); } /** * 检查元素是否在集合中 * @param element 要检查的元素 * @returns 是否存在 */ hasElement(element) { return this.hasKey(this.getKey(element)); } /** * 添加元素到集合 * @param element 要添加的元素 * @param force 当元素已存在时是否强制替换,默认为false */ add(element, force) { const key = this.getKey(element); const has = this.elMap.has(key); if (!has) { const index = this.elements.push(element) - 1; this.indexMap.set(key, index); this.elMap.set(key, element); } else if (force) { const index = this.indexMap.get(key); assert(index); this.elMap.set(key, element); this.elements.splice(index, 1, element); } } /** * 使用指定的键值添加元素 * @param key 指定的键值 * @param element 要添加的元素 * @param force 当键值已存在时是否强制替换,默认为false */ addKey(key, element, force) { const has = this.elMap.has(key); if (!has) { const index = this.elements.push(element) - 1; this.indexMap.set(key, index); this.elMap.set(key, element); } else if (force) { const index = this.indexMap.get(key); assert(index != void 0); this.elMap.set(key, element); this.elements.splice(index, 1, element); } } /** * 批量添加元素 * @param iterator 可迭代的元素集合 * @param force 当元素已存在时是否强制替换,默认为false */ addAll(iterator, force) { const { next } = iterator[Symbol.iterator](); let result = next(); while (!result.done) { this.add(result.value, force); result = next(); } } /** * 在指定位置插入元素 * @param element 待插入的元素 * @param index 插入位置,范围[0, length]。如果超出范围会被自动调整到有效范围内 * @param exist 当元素已存在时的处理选项 * @param exist.index 是否保持原有元素的位置。true: 保持原位置,false: 使用新位置 * @param exist.element 是否使用新元素替换原有元素。true: 使用新元素,false: 保持原有元素 */ insert(element, index, exist) { const key = this.getKey(element); const has = this.elMap.has(key); const { index: cIndex, element: cElement } = exist || {}; if (!has) { this.elMap.set(key, element); index = Math.min(this.elements.length, Math.max(0, index)); this.elements.splice(index, 0, element); } else { const oIndex = this.indexMap.get(key); assert(oIndex); const oElement = this.elements[oIndex]; const placeholder = Symbol("placegholder"); this.elements[oIndex] = placeholder; if (!cIndex) { index = oIndex; } if (!cElement) { element = oElement; } this.elements.splice(index, 0, element); this.elements = this.elements.filter((v) => v !== placeholder); this.updateIndexMap(); } } /** * 移除指定元素 * @param element 要移除的元素 * @returns 是否成功移除 */ removeElement(element) { const key = this.getKey(element); return !!this.remove(key); } /** * 根据键值移除元素 * @param key 要移除的元素的键值 * @returns 被移除的元素,如果元素不存在则返回undefined */ remove(key) { const has = this.elMap.has(key); if (has) { const index = this.indexMap.get(key); assert(index); this.elements.splice(index, 1); this.updateIndexMap(); this.elMap.delete(key); } return void 0; } /** * 清空集合中的所有元素 */ clear() { this.elMap.clear(); this.elements.length = 0; this.indexMap.clear(); } /** * 更新索引映射 * 当元素数组发生变化时,需要重新计算每个元素的索引 * @private */ updateIndexMap() { const { elements, indexMap } = this; const { length } = elements; indexMap.clear(); for (let i = 0; i < length; i++) { const element = elements[i]; const key = this.getKey(element); indexMap.set(key, i); } } /** * 实现Iterable接口,使集合可以被迭代 * 使用生成器函数遍历集合中的所有元素 * @yields 集合中的每个元素 */ [Symbol.iterator]() { let i = 0; return { next: () => { const j = i; i++; return { value: this.elements[j], done: j >= this.elements.length }; } }; } /** * 遍历集合中的所有元素 * @param handler 处理每个元素的回调函数 */ each(handler) { this.elMap.forEach((el, k) => handler(el, k, this)); } toArray(filter, mapper) { const result = []; const elements = this.elements; for (let i = 0; i < elements.length; i++) { const element = elements[i]; const key = this.getKey(element); if (filter && !filter(element, key, this)) { continue; } const value = mapper ? mapper(element, key, this) : element; result.push(value); } return result; } } const symbolKeys = new Collection((keys) => keys.key); function GeneratSymbolKey(key) { if (symbolKeys.hasKey(key)) { return symbolKeys.get(key).symbolKey; } else { const symbolKey = Symbol(key); symbolKeys.add({ key, symbolKey }); return symbolKey; } } function setGlobalData(key, data) { const symbolKey = GeneratSymbolKey(key); Object.assign(globalThis, { [symbolKey]: data }); return data; } function getGlobalData(key) { const symbolKey = GeneratSymbolKey(key); const data = Reflect.get(globalThis, symbolKey); if (!data) { if (key.startsWith("@msom/")) { throw `The GlobalData of ${key} is must init before get.`; } return setGlobalData(key, {}); } return data; } const ENUMERABLE = 4; const WRITABLE = 2; const CONFIGURABLE = 1; function defineProperty(target, propKey) { let flag = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 7; let value = arguments.length > 3 ? arguments[3] : void 0; Object.defineProperty(target, propKey, { value, writable: !!(WRITABLE & flag), enumerable: !!(ENUMERABLE & flag), configurable: !!(CONFIGURABLE & flag) }); } function defineAccesser(target, propKey) { let flag = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 5; let getter = arguments.length > 3 ? arguments[3] : void 0; let setter = arguments.length > 4 ? arguments[4] : void 0; Object.defineProperty(target, propKey, { enumerable: !!(ENUMERABLE & flag), configurable: !!(CONFIGURABLE & flag), get: getter, set: setter }); } function tryCall(call, data, receiver, error) { if (typeof call === "function") { try { return Reflect.apply(call, receiver, data || []); } catch (e) { throw error ? error(e) : e; } } throw `${typeof call === "object" ? Reflect.get(call, "name", call) : call} is not a function.`; } function equal(value, otherValue) { return Object.is(value, otherValue); } function ownKeysAndPrototypeOwnKeys($events) { let keys = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : new Collection((key) => key); Object.keys($events).forEach((key) => keys.add(key)); const prototype = Reflect.getPrototypeOf($events); if (prototype) { ownKeysAndPrototypeOwnKeys(prototype, keys); } return keys; } const EVENTS = Symbol("__EVENTS__"); const EK = EVENTS; class Event { constructor() { defineProperty(this, EK, 0, /* @__PURE__ */ Object.create(null)); } on(type, handler) { const _events = this[EK]; let handlers = _events[type]; if (!handlers) { handlers = _events[type] = []; } handlers.push(handler); return this; } un(type, handler) { const _events = this[EK]; const handlers = _events[type]; if (!handlers) { return this; } const index = handlers.findIndex((_handler) => handler === _handler); if (index === -1) return this; handlers.splice(index, 1); return this; } emit(type, event) { const _events = this[EK]; const handlers = _events[type]; if (!handlers) { return; } handlers.forEach((handler) => handler(event, type, this)); } } function clearEvent(target) { if (!target || !(target instanceof Event)) { throw "the target should be Event instance"; } return Reflect.deleteProperty(target, EK); } function curry(cb) { if (cb.length < 2) { return cb; } const args = []; const _curry = () => { return (arg) => { args.push(arg); if (args.length < cb.length) { return _curry(); } else if (args.length === cb.length) { return cb(...args); } else { throw new Error(`This function '${cb.name}' can take up to ${cb.length} parameters at most`); } }; }; return _curry(); } class OcPromiseRejectError extends Error { } const PENDDING = "pendding"; const FULFILLED = "fulfilled"; const REJECTED = "rejected"; const CANCELED = "canceled"; function isPromiseLike(data) { return !!data && (typeof data === "function" || typeof data === "object" && data !== null) && typeof data["then"] === "function"; } function isOcPromiseLike(data) { return isPromiseLike(data) && typeof data["cancel"] === "function"; } const nextTickStore = { id: 0, tickMap: /* @__PURE__ */ new Map() }; const nextTick = (task) => { const { id, tickMap } = nextTickStore; const option = /* @__PURE__ */ Object.create(null); const _option = { canceled: false }; tickMap.set(id, option); nextTickStore.id++; const _task = () => { option.cancel = () => { _option.canceled = true; option.cancel = void 0; }; return () => { if (!_option.canceled) { task(); } option.cancel = void 0; }; }; if (typeof process !== "undefined" && process.nextTick) { process.nextTick(_task()); } else if (typeof queueMicrotask !== "undefined") { queueMicrotask(_task()); } else if (typeof MutationObserver !== "undefined") { const ob = new MutationObserver(() => { if (!_option.canceled) { task(); } option.cancel = void 0; }); const dom = document.createTextNode(String(id)); ob.observe(dom, { characterData: true }); dom.data = String(id + 1); option.cancel = () => { _option.canceled = true; option.cancel = void 0; }; ob.disconnect(); dom.remove(); } else { const id2 = setTimeout(task, 0); option.cancel = () => { clearTimeout(id2); option.cancel = void 0; }; } return id; }; class OcPromise { /** * 创建 OcPromise 实例 * @param executor 执行器函数,接收 resolve、reject 和 cancel 函数 */ constructor(executor) { this.status = PENDDING; this.handlers = []; const resolve = (data) => { if (isOcPromise(data) || isOcPromiseLike(data)) { data.then(resolve, reject, cancel); } else if (isPromiseLike(data)) { data.then(resolve, reject); } else { this.changeStatus(FULFILLED, data); } }; const reject = (reason) => { this.changeStatus(REJECTED, reason); }; const cancel = (reason) => { this.changeStatus(CANCELED, reason); }; try { executor(resolve, reject, cancel); } catch (e) { reject(e); } } /** * 改变 Promise 状态 * @private * @template T - 目标状态类型 * @template D - 数据类型 * @param status - 新状态 * @param data - 相关数据 */ changeStatus(status, data) { if (this.status !== PENDDING) { return; } this.status = status; this.data = data; this._runThens(); } /** * 执行处理函数队列 * @private */ _runThens() { if (this.status === PENDDING) { return; } while (this.handlers.length) { const handler = this.handlers.shift(); const { resolve, reject, cancel, onfulfilled, onrejected, oncanceled } = handler; const exe = this.status === FULFILLED ? onfulfilled ? ( // 如果有完成处理函数,则调用它 () => tryCall(onfulfilled, [this.data]) ) : ( // 否则直接调用 resolve (resolve(this.data), void 0) ) : this.status === REJECTED ? onrejected ? ( // 如果有拒绝处理函数,则调用它 () => tryCall(onrejected, [this.data]) ) : ( // 否则直接调用 reject (reject(this.data), void 0) ) : oncanceled ? ( // 如果有取消处理函数,则调用它 () => tryCall(oncanceled, [this.data]) ) : ( // 否则直接调用 cancel (cancel(this.data), void 0) ); if (!exe) continue; const task = () => { try { const data = exe(); if (isOcPromise(data) || isOcPromiseLike(data)) { nextTick(() => { data.then(resolve, reject, (reason) => (this.cancel(reason), cancel(reason))); }); } else if (isPromiseLike(data)) { nextTick(() => { data.then(resolve, reject); }); } else { resolve(data); } } catch (e) { reject(e); } }; nextTick(task); } } /** * 添加完成、错误和取消的处理函数 * @template TR - 完成处理函数的返回类型 * @template TE - 错误处理函数的返回类型 * @template TC - 取消处理函数的返回类型 * @template FR - 最终返回值类型 */ then(onfulfilled, onrejected, oncanceled) { const res = new OcPromise((resolve, reject, cancel) => { this.handlers.push({ resolve, reject, cancel, onfulfilled, onrejected, oncanceled }); this._runThens(); }); res.parrent = this; return res; } /** * 取消 Promise * @param reason - 取消原因 */ cancel(reason) { if (this.parrent) { this.parrent.cancel(reason); } else { this.changeStatus(CANCELED, reason); } } /** * 等待所有 Promise 完成 * @static * @template T - 元素类型 * @param proms - Promise 或值的可迭代对象 * @returns 包含所有结果的 Promise */ static all(proms) { const result = []; return new OcPromise((resolve, reject, cancel) => { const _resolve = (data, index) => { result[index] = data; finished++; if (finished === i) resolve(result); }; let i = 0, finished = 0; const iterator = proms[Symbol.iterator](); let next = iterator.next(); while (!next.done) { const j = i; i++; const { value } = next; if (isOcPromise(value)) { value.then((data) => _resolve(data, j), reject, cancel); } else if (isPromiseLike(value)) { value.then((data) => _resolve(data, j), reject); } else { result[j] = value; finished++; } next = iterator.next(); } if (finished === i) { resolve(result); } }); } /** * 创建一个已完成的 Promise * @static * @template T - 值的类型 * @param value - 要解析的值 */ static resolve(value) { if (isOcPromise(value)) { return value; } if (isOcPromiseLike(value)) { return new OcPromise((resolve, reject, cancel) => { value.then(resolve, reject, cancel); }); } if (isPromiseLike(value)) { return new OcPromise((resolve, reject) => { value.then(resolve, reject); }); } return new OcPromise((resolve) => { resolve(value); }); } /** * 创建一个已拒绝的 Promise * @static * @template E - 错误类型 * @param reason - 拒绝原因 */ static reject(reason) { return new OcPromise((_, reject) => { reject(reason); }); } /** * 添加取消处理函数 * @param oncanceled - 取消处理函数 */ canceled(oncanceled) { return this.then(null, null, oncanceled); } /** * 添加错误处理函数 * @param onRejected - 错误处理函数 */ catch(onRejected) { return this.then(null, onRejected, null); } /** 获取当前数据 */ getData() { return this.data; } /** 获取当前状态 */ getStatus() { return this.status; } } function isOcPromise(data) { return data instanceof OcPromise; } function createCancelRequest(url, init) { const controller = new AbortController(); init = init || {}; if (init.signal) { init.signal.addEventListener("abort", () => controller.abort(), { once: true }); } init.signal = controller.signal; const promise = new OcPromise((resolve, reject) => { fetch(url, init).then((data) => { resolve(data); }, reject); }); promise.canceled(() => controller.abort()); return promise; } function createJsonRequest(url, init) { const headers = new Headers(init?.headers); headers.delete("content-type"); headers.append("content-type", "application/json"); return createCancelRequest(url, { ...init || {}, headers }); } function json(response) { return response.then((res) => res.json()); } function createRequestJson(url, init) { return json(createCancelRequest(url, init)); } function createJsonRequestJson(url, init) { return json(createJsonRequest(url, init)); } class SuperTaskController { /** * 创建任务控制器实例 * @param option 控制器配置选项 */ constructor(option) { option = option || {}; this.accompanyingCount = Number(option.accompanyingCount) || 2; this.tasks = []; this.runningCount = 0; } /** * 添加新任务到控制器 * @template T 任务返回值的类型 * @param task 要执行的任务函数 * @returns 返回一个Promise,当任务执行完成时解决 */ addTask(task) { return new OcPromise((resolve, reject) => { this.tasks.push({ task, resolve, reject }); this.run(); }); } /** * 执行任务的私有方法 * 根据并发限制和任务队列状态来执行任务 * @private */ run() { while (this.runningCount <= this.accompanyingCount && this.tasks.length > 0) { const { task, resolve, reject } = this.tasks.shift(); this.runningCount++; new Promise((resolve2) => resolve2(task())).then(resolve, reject).finally(() => { this.runningCount--; this.run(); }); } } } function performChunk(tasks) { let option = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; if (tasks.length === 0) return; let { chunkSplitor, onEnd } = option; if (typeof chunkSplitor !== "function" && typeof globalThis.requestIdleCallback === "function") { chunkSplitor = (task) => { globalThis.requestIdleCallback((idle) => { task((elapsedTime) => idle.timeRemaining() > 0); }); }; } if (!chunkSplitor) { chunkSplitor = (task) => { task((elapsedTime) => elapsedTime < FRAME_INTERVAL); }; } const _chunkSplitor = chunkSplitor; let i = 0; function _run() { if (i === tasks.length) { onEnd && onEnd(); return; } _chunkSplitor((isContinue) => { const now = Date.now(); while (isContinue(Date.now() - now) && i < tasks.length) { console.info(i, tasks.length); tasks[i](i); i++; } }); _run(); } _run(); } const FRAME_INTERVAL = 1e3 / 60; function inRange(data, _ref) { let { min, max } = _ref; if (min != void 0 && max != void 0) { assert(min <= max, "max can't less than min"); return Math.min(max, Math.max(min, data)); } if (min != void 0) { return Math.max(min, data); } if (max != void 0) { return Math.min(max, data); } return data; } const TYPE_SPLITOR = ","; const OVERlOAD_KEY = Symbol("overload"); const ADD_IMPLEMENT = "addImplement"; function createOverload(impls) { const overloadCollection = new Collection((m) => { return Reflect.get(m, OVERlOAD_KEY); }); const Method = { method() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } const overloadKey = args.map((v) => typeof v).join(TYPE_SPLITOR); const overload = overloadCollection.get(overloadKey); assert(overload, "No implementation found"); return overload.apply(this, args); }, add() { for (var _len2 = arguments.length, impl = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { impl[_key2] = arguments[_key2]; } const overload = impl.pop(); if (typeof overload !== "function") { throw Error("The last parameter must be a function"); } const overloadKey = impl.join(TYPE_SPLITOR); overloadCollection.addKey(overloadKey, overload, true); } }; defineProperty(Method.method, ADD_IMPLEMENT, 0, Method.add); if (impls) { for (const impl of impls) { Method.add(...impl); } } return Method.method; } const example = createOverload([["string", "number", function(a) { let c = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 1; return Number(a) + c; }], ["string", (a) => a], ["number", (a) => a]]); example("1", 2); example("1"); example(1); example[ADD_IMPLEMENT]("string", "number", function(a) { let c = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 1; return Number(a) + c; }); const onlyUsedMap = { observer: "observer decorator only be used with instance property.", option: "option decorator only be used with instance property or accessor property for setter.", component: "component decorator only be used with class.", computed: "computed decorator only be used with instance method or accessor property for getter." }; function decoratorUsedErrorOptionHandler(decoratorName, option) { const { defineMessage } = option; if (defineMessage) { return typeof defineMessage === "function" ? defineMessage() : defineMessage; } const should = ["(", onlyUsedMap[decoratorName], ")"]; let notIndex = ""; if (option.NotStatic) { notIndex = "static property or method"; } else if (option.NotInComponent) { notIndex = "outside a Component"; } else if (option.NotSetter) { notIndex = "accessor property for not setter"; } else if (option.NotMethod) { notIndex = "a instance method"; } else if (option.NotAccessor) { notIndex = "accessor property"; } else if (option.NotClass) { notIndex = "not a class"; } else if (option.NotProperty) { notIndex = "a instance property"; } else ; return `${notIndex ? `not allow used with ${notIndex}.` : ""} ${notIndex ? should.join("") : should[1]}`.trim(); } class ObserverDUE extends Error { constructor() { let option = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; super(decoratorUsedErrorOptionHandler("observer", option)); } } const ObserverDecoratorUsedError = ObserverDUE; class OptionDUE extends Error { constructor() { let option = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; super(decoratorUsedErrorOptionHandler("option", option)); } } const OptionDecoratorUsedError = OptionDUE; class ComponentDUE extends Error { constructor() { let option = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; super(decoratorUsedErrorOptionHandler("component", option)); } } const ComponentDecoratorUsedError = ComponentDUE; class ComputedDUE extends Error { constructor() { let option = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; super(decoratorUsedErrorOptionHandler("computed", option)); } } const ComputedDecoratorUsedError = ComputedDUE; function isArray(o) { return Array.isArray(o); } function compareArray(newArr, oldArr, insert, del) { const objectKey = /* @__PURE__ */ new WeakMap(); const oldMaps = { primitiveMap: /* @__PURE__ */ new Map(), objectMap: /* @__PURE__ */ new Map() }; const newMaps = { primitiveMap: /* @__PURE__ */ new Map(), objectMap: /* @__PURE__ */ new Map() }; const addMap = (maps, key) => { if (key === null || typeof key === "object" || typeof key === "function") { const objKey = key; const keySymbol = objectKey.get(objKey) || createAndSetSymbol(objKey); const value = maps.objectMap.get(keySymbol) || createObjectMapEntry(maps, keySymbol, objKey); value.count++; } else { const primitiveKey = key; const value = maps.primitiveMap.get(primitiveKey) || createMapEntry(maps.primitiveMap, primitiveKey); value.count++; } }; const createAndSetSymbol = (key) => { const keySymbol = Symbol(); objectKey.set(key, keySymbol); return keySymbol; }; const createObjectMapEntry = (maps, keySymbol, obj) => { const value = { count: 0, obj }; maps.objectMap.set(keySymbol, value); return value; }; const createMapEntry = (map, key) => { const value = { count: 0 }; map.set(key, value); return value; }; oldArr.forEach((item) => addMap(oldMaps, item)); newArr.forEach((item) => addMap(newMaps, item)); const inserts = []; const dels = []; compareMapEntries(oldMaps.primitiveMap, newMaps.primitiveMap, inserts, dels); compareObjectMapEntries(oldMaps.objectMap, newMaps.objectMap, objectKey, inserts, dels); if (inserts.length > 0 && insert) { tryCall(insert, [inserts]); } if (dels.length > 0 && del) { tryCall(del, [dels]); } } function compareMapEntries(oldMap, newMap, inserts, dels) { oldMap.forEach((value, key) => { const newValue = newMap.get(key); updateArrays(key, value.count, newValue?.count || 0, inserts, dels); newMap.delete(key); }); newMap.forEach((value, key) => { inserts.push(...new Array(value.count).fill(key)); }); } function compareObjectMapEntries(oldMap, newMap, objectKey, inserts, dels) { oldMap.forEach((value) => { const keySymbol = objectKey.get(value.obj); if (keySymbol) { const newValue = newMap.get(keySymbol); updateArrays(value.obj, value.count, newValue?.count || 0, inserts, dels); newMap.delete(keySymbol); } }); newMap.forEach((value) => { inserts.push(...new Array(value.count).fill(value.obj)); }); } function updateArrays(item, oldCount, newCount, inserts, dels) { if (newCount < oldCount) { dels.push(...new Array(oldCount - newCount).fill(item)); } else if (newCount > oldCount) { inserts.push(...new Array(newCount - oldCount).fill(item)); } } function compareObjects(obj1, obj2) { if (obj1 === obj2) { return true; } if (!obj1 || !obj2 || typeof obj1 !== "object" || typeof obj2 !== "object") { return false; } if (isArray(obj1) !== isArray(obj2)) { return false; } const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) { return false; } for (const key of keys1) { const val1 = obj1[key]; const val2 = obj2[key]; if (typeof val1 === "object" && typeof val2 === "object" && val1 !== null && val2 !== null) { if (!compareObjects(val1, val2)) { return false; } } else if (val1 !== val2) { return false; } } return true; } function isObject(value) { return typeof value === "object" && value !== null; } function cloneObject(data, deep) { function _clone(data2) { let cache = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : /* @__PURE__ */ new WeakMap(); const _cache = cache.get(data2); if (_cache) { return _cache; } const cloned = Object.create(Reflect.getPrototypeOf(data2)); cache.set(data2, cloned); const keys = Reflect.ownKeys(data2); for (let i = 0; i < keys.length; i++) { const desc = Reflect.getOwnPropertyDescriptor(data2, keys[i]); if (!desc) { continue; } if (Reflect.has(desc, "value")) { const value = Reflect.get(desc, "value", desc); Reflect.set(desc, "value", deep && isObject(value) ? _clone(value, cache) : value, desc); } Reflect.defineProperty(cloned, keys[i], desc); } return cloned; } return _clone(data); } function camelToKebab(text) { let option = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; const _option = { beforReturn: (text2) => text2, ...option }; const result = text.replace(/([A-Z]+)([A-Z][a-z]?)/g, "$1-$2").replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z]+)/g, "$1-$2").toLowerCase(); return nil(_option.beforReturn(result, text), result); } function parseClass(classType) { if (typeof classType === "string") return classType.trim(); if (isArray(classType)) { return classType.reduce((className, _classType) => { if (typeof _classType === "string" && _classType !== "") { return `${className} ${_classType}`; } return className; }, "").trim(); } return Object.entries(classType).reduce((className, _ref) => { let [_classType, IS] = _ref; return IS ? `${className} ${_classType}` : className; }, "").trim(); } function parseStyle(style) { if (typeof style === "string") return style; if (isArray(style)) { style = style.reduce((a, b) => { a[b[0]] = b[1]; return a; }, {}); } return Object.entries(style).map((_ref2) => { let [n, v] = _ref2; n = camelToKebab(n, { beforReturn(text) { if (text.startsWith("webkit")) { return "-" + text; } } }); if (v == void 0) { return ""; } if (typeof v === "number" && !isNumericCSSProperty(n)) { v = `${v}px`; } return `${n}: ${v}`; }).join("; ").trim(); } function isNumericCSSProperty(camelCaseProp) { const cssProperty = camelToKebab(camelCaseProp, { beforReturn(text) { if (text.startsWith("webkit")) { return "-" + text; } } }); const numericProperties = /* @__PURE__ */ new Set([ "z-index", // 层级 "opacity", // 透明度 "flex-grow", // 弹性扩展比例 "flex-shrink", // 弹性收缩比例 "order", // 弹性项目排序 "font-weight", // 字体粗细(数值形式) "line-height", // 行高(可接受无单位数值) "column-count", // 列数 "counter-increment", // 计数器增量 "counter-reset", // 计数器重置 "grid-row-start", // 网格行起始位置 "grid-row-end", // 网格行结束位置 "grid-column-start", // 网格列起始位置 "grid-column-end", // 网格列结束位置 "orphans", // 分页时保留的底部行数 "widows", // 分页时保留的顶部行数 "scale", // 变换比例 "fill-opacity", // 填充不透明度 "stroke-opacity", // 描边不透明度 "stroke-width", // 描边宽度(在某些上下文中可接受无单位值) "shape-image-threshold" // 形状图像阈值 ]); return numericProperties.has(cssProperty); } const componentGlobalData = setGlobalData("@msom/component", { componentDefinitionKey: Symbol("component_definition"), componentMap: /* @__PURE__ */ new Map() }); function initComponentDefinition(prototype) { const { componentDefinitionKey } = componentGlobalData; prototype = typeof prototype === "function" ? prototype.prototype : prototype; const prototype_prototype = Object.getPrototypeOf(prototype); const prototype_prototype_definition = getComponentDefinition(prototype_prototype); try { Object.setPrototypeOf(prototype, null); let definition = Reflect.get(prototype, componentDefinitionKey); if (!definition) { definition = /* @__PURE__ */ Object.create(null); assert(definition); Object.assign(definition, { // 将组件的属性、事件、监听器通过原型链接起来 $options: Object.create(prototype_prototype_definition?.["$options"] || null), $events: Object.create(prototype_prototype_definition?.["$events"] || null), $observers: Object.create(prototype_prototype_definition?.["$observers"] || null) }); defineProperty(prototype, componentDefinitionKey, 0, definition); } return definition; } finally { Object.setPrototypeOf(prototype, prototype_prototype); } } function getComponentDefinition(prototype) { const { componentDefinitionKey } = componentGlobalData; prototype = typeof prototype === "function" ? prototype.prototype : prototype; const oldProptotype = Object.getPrototypeOf(prototype); try { Object.setPrototypeOf(prototype, null); return Reflect.get(prototype, componentDefinitionKey); } finally { Object.setPrototypeOf(prototype, oldProptotype); } } function isComponent(ctor) { const { componentDefinitionKey } = componentGlobalData; const target = typeof ctor === "function" ? ctor.prototype : ctor; const prototype = Object.getPrototypeOf(target); try { Object.setPrototypeOf(target, null); return Reflect.has(target, componentDefinitionKey); } finally { Object.setPrototypeOf(target, prototype); } } exports.CANCELED = CANCELED; exports.CONFIGURABLE = CONFIGURABLE; exports.Collection = Collection; exports.ComponentDecoratorUsedError = ComponentDecoratorUsedError; exports.ComputedDecoratorUsedError = ComputedDecoratorUsedError; exports.ENUMERABLE = ENUMERABLE; exports.Event = Event; exports.FRAME_INTERVAL = FRAME_INTERVAL; exports.FULFILLED = FULFILLED; exports.GeneratSymbolKey = GeneratSymbolKey; exports.ObserverDecoratorUsedError = ObserverDecoratorUsedError; exports.OcPromise = OcPromise; exports.OcPromiseRejectError = OcPromiseRejectError; exports.OptionDecoratorUsedError = OptionDecoratorUsedError; exports.PENDDING = PENDDING; exports.REJECTED = REJECTED; exports.SuperTaskController = SuperTaskController; exports.WRITABLE = WRITABLE; exports.assert = assert; exports.clearEvent = clearEvent; exports.cloneObject = cloneObject; exports.compareArray = compareArray; exports.compareMapEntries = compareMapEntries; exports.compareObjectMapEntries = compareObjectMapEntries; exports.compareObjects = compareObjects; exports.createCancelRequest = createCancelRequest; exports.createJsonRequest = createJsonRequest; exports.createJsonRequestJson = createJsonRequestJson; exports.createOverload = createOverload; exports.createRequestJson = createRequestJson; exports.curry = curry; exports.defineAccesser = defineAccesser; exports.defineProperty = defineProperty; exports.equal = equal; exports.getComponentDefinition = getComponentDefinition; exports.getGlobalData = getGlobalData; exports.inRange = inRange; exports.initComponentDefinition = initComponentDefinition; exports.isArray = isArray; exports.isComponent = isComponent; exports.isObject = isObject; exports.isOcPromise = isOcPromise; exports.isOcPromiseLike = isOcPromiseLike; exports.isPromiseLike = isPromiseLike; exports.nil = nil; exports.ownKeysAndPrototypeOwnKeys = ownKeysAndPrototypeOwnKeys; exports.parseClass = parseClass; exports.parseStyle = parseStyle; exports.performChunk = performChunk; exports.setGlobalData = setGlobalData; exports.tryCall = tryCall; exports.updateArrays = updateArrays; //# sourceMappingURL=index.cjs.js.map