chore: trim shared lodash helpers
This commit is contained in:
@@ -11,11 +11,8 @@ export * from './resources';
|
||||
export * from './state-handler';
|
||||
export * from './to';
|
||||
export * from './tree';
|
||||
export * from './object';
|
||||
export * from './unique';
|
||||
export * from './update-css-variables';
|
||||
export * from './util';
|
||||
export * from './window';
|
||||
export { default as cloneDeep } from 'lodash.clonedeep';
|
||||
export { default as get } from 'lodash.get';
|
||||
export { default as isEqual } from 'lodash.isequal';
|
||||
export { default as set } from 'lodash.set';
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
type KeyPath = Array<number | string> | number | string;
|
||||
|
||||
const keyPathPattern = /[^.[\]]+|\[(\d+)\]/g;
|
||||
|
||||
function toKeyPath(path: KeyPath): Array<number | string> {
|
||||
if (Array.isArray(path)) {
|
||||
return path;
|
||||
}
|
||||
if (typeof path === 'number') {
|
||||
return [path];
|
||||
}
|
||||
const keys: Array<number | string> = [];
|
||||
path.replace(keyPathPattern, (match, index) => {
|
||||
keys.push(index === undefined ? match : Number(index));
|
||||
return match;
|
||||
});
|
||||
return keys;
|
||||
}
|
||||
|
||||
function cloneDeep<T>(value: T): T {
|
||||
if (value === null || typeof value !== 'object') {
|
||||
return value;
|
||||
}
|
||||
if (value instanceof Date) {
|
||||
return new Date(value) as T;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => cloneDeep(item)) as T;
|
||||
}
|
||||
if (value instanceof Map) {
|
||||
return new Map(
|
||||
[...value.entries()].map(([key, item]) => [cloneDeep(key), cloneDeep(item)]),
|
||||
) as T;
|
||||
}
|
||||
if (value instanceof Set) {
|
||||
return new Set([...value.values()].map((item) => cloneDeep(item))) as T;
|
||||
}
|
||||
|
||||
const result = {} as Record<string, unknown>;
|
||||
for (const [key, item] of Object.entries(value)) {
|
||||
result[key] = cloneDeep(item);
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
|
||||
function get<T = any>(
|
||||
object: any,
|
||||
path: KeyPath,
|
||||
defaultValue?: T,
|
||||
): T | undefined {
|
||||
let result = object;
|
||||
for (const key of toKeyPath(path)) {
|
||||
if (result == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
result = result[key as keyof typeof result];
|
||||
}
|
||||
return result === undefined ? defaultValue : result;
|
||||
}
|
||||
|
||||
function set<T extends Record<string, any>>(
|
||||
object: T,
|
||||
path: KeyPath,
|
||||
value: unknown,
|
||||
): T {
|
||||
const keys = toKeyPath(path);
|
||||
let cursor: Record<string, any> = object;
|
||||
|
||||
keys.forEach((key, index) => {
|
||||
if (index === keys.length - 1) {
|
||||
cursor[key] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
const nextKey = keys[index + 1];
|
||||
cursor[key] ??= typeof nextKey === 'number' ? [] : {};
|
||||
cursor = cursor[key];
|
||||
});
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
function isEqual(left: unknown, right: unknown): boolean {
|
||||
if (Object.is(left, right)) {
|
||||
return true;
|
||||
}
|
||||
if (left instanceof Date && right instanceof Date) {
|
||||
return left.getTime() === right.getTime();
|
||||
}
|
||||
if (
|
||||
left === null ||
|
||||
right === null ||
|
||||
typeof left !== 'object' ||
|
||||
typeof right !== 'object'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(left) || Array.isArray(right)) {
|
||||
if (!Array.isArray(left) || !Array.isArray(right)) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
left.length === right.length &&
|
||||
left.every((item, index) => isEqual(item, right[index]))
|
||||
);
|
||||
}
|
||||
|
||||
const leftKeys = Object.keys(left);
|
||||
const rightKeys = Object.keys(right);
|
||||
return (
|
||||
leftKeys.length === rightKeys.length &&
|
||||
leftKeys.every((key) =>
|
||||
isEqual(
|
||||
(left as Record<string, unknown>)[key],
|
||||
(right as Record<string, unknown>)[key],
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export { cloneDeep, get, isEqual, set };
|
||||
Reference in New Issue
Block a user