@msom/common
Version:
@msom/common
1,284 lines (1,283 loc) • 36.9 kB
JavaScript
"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