forked from mengyxu/noob-components
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
53 lines
1.4 KiB
53 lines
1.4 KiB
|
3 months ago
|
import { isReactive, isReadonly, isRef, toRaw, unref } from "vue";
|
||
|
|
|
||
|
|
export const CIRCULAR_REFERENCE_TEXT = "[Circular]";
|
||
|
|
|
||
|
|
export interface CircularReferenceMarker {
|
||
|
|
__jsonViewCircular: true;
|
||
|
|
path?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createCircularReferenceMarker(path?: string): CircularReferenceMarker {
|
||
|
|
return {
|
||
|
|
__jsonViewCircular: true,
|
||
|
|
path,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function isCircularReferenceMarker(value: unknown): value is CircularReferenceMarker {
|
||
|
|
return Boolean(
|
||
|
|
value &&
|
||
|
|
typeof value === "object" &&
|
||
|
|
"__jsonViewCircular" in value &&
|
||
|
|
(value as { __jsonViewCircular?: boolean }).__jsonViewCircular
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatCircularReference(path?: string) {
|
||
|
|
return path ? `[Circular: ${path}]` : CIRCULAR_REFERENCE_TEXT;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function normalizeVueValue(
|
||
|
|
value: unknown,
|
||
|
|
currentPath?: string,
|
||
|
|
seenRefs = new WeakMap<object, string | undefined>()
|
||
|
|
): unknown {
|
||
|
|
let current = value;
|
||
|
|
|
||
|
|
while (isRef(current)) {
|
||
|
|
const reference = current as object;
|
||
|
|
const existingPath = seenRefs.get(reference);
|
||
|
|
if (existingPath !== undefined || seenRefs.has(reference)) {
|
||
|
|
return createCircularReferenceMarker(existingPath ?? currentPath);
|
||
|
|
}
|
||
|
|
seenRefs.set(reference, currentPath);
|
||
|
|
current = unref(current);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (current !== null && typeof current === "object" && (isReactive(current) || isReadonly(current))) {
|
||
|
|
return toRaw(current);
|
||
|
|
}
|
||
|
|
|
||
|
|
return current;
|
||
|
|
}
|