Revert "refactor: profile switch (#5197)"

This reverts commit c2dcd86722.
This commit is contained in:
Tunglies
2025-10-30 18:11:04 +08:00
parent 928f226d10
commit a869dbb441
36 changed files with 1257 additions and 5894 deletions
-31
View File
@@ -1,31 +0,0 @@
export class AsyncEventQueue {
private tail: Promise<void> = Promise.resolve();
enqueue(task: () => Promise<void> | void) {
this.tail = this.tail
.then(async () => {
await task();
})
.catch((error) => {
console.error("AsyncEventQueue task failed", error);
});
}
clear() {
this.tail = Promise.resolve();
}
}
export const nextTick = () =>
new Promise<void>((resolve) => {
if (typeof queueMicrotask === "function") {
queueMicrotask(resolve);
} else {
Promise.resolve().then(() => resolve());
}
});
export const afterPaint = () =>
new Promise<void>((resolve) => {
requestAnimationFrame(() => resolve());
});
-205
View File
@@ -1,205 +0,0 @@
import yaml from "js-yaml";
const createProxyItem = (
name: string,
partial: Partial<IProxyItem> = {},
): IProxyItem => ({
name,
type: partial.type ?? "unknown",
udp: partial.udp ?? false,
xudp: partial.xudp ?? false,
tfo: partial.tfo ?? false,
mptcp: partial.mptcp ?? false,
smux: partial.smux ?? false,
history: [],
provider: partial.provider,
testUrl: partial.testUrl,
hidden: partial.hidden,
icon: partial.icon,
fixed: partial.fixed,
});
const createGroupItem = (
name: string,
all: IProxyItem[],
partial: Partial<IProxyGroupItem> = {},
): IProxyGroupItem => {
const rest = { ...partial } as Partial<IProxyItem>;
delete (rest as Partial<IProxyGroupItem>).all;
const base = createProxyItem(name, rest);
return {
...base,
all,
now: partial.now ?? base.now,
};
};
const ensureProxyItem = (
map: Map<string, IProxyItem>,
name: string,
source?: Partial<IProxyItem>,
) => {
const key = String(name);
if (map.has(key)) return map.get(key)!;
const item = createProxyItem(key, source);
map.set(key, item);
return item;
};
const parseProxyEntry = (entry: any): IProxyItem | null => {
if (!entry || typeof entry !== "object") return null;
const name = entry.name || entry.uid || entry.id;
if (!name) return null;
return createProxyItem(String(name), {
type: entry.type ? String(entry.type) : undefined,
udp: Boolean(entry.udp),
xudp: Boolean(entry.xudp),
tfo: Boolean(entry.tfo),
mptcp: Boolean(entry.mptcp),
smux: Boolean(entry.smux),
testUrl: entry.test_url || entry.testUrl,
});
};
const isNonEmptyString = (value: unknown): value is string =>
typeof value === "string" && value.trim().length > 0;
const parseProxyGroup = (
entry: any,
proxyMap: Map<string, IProxyItem>,
): IProxyGroupItem | null => {
if (!entry || typeof entry !== "object") return null;
const name = entry.name;
if (!name) return null;
const rawProxies: unknown[] = Array.isArray(entry.proxies)
? entry.proxies
: [];
const proxyRefs: string[] = rawProxies
.filter(isNonEmptyString)
.map((item) => item.trim());
const uniqueNames: string[] = Array.from(new Set(proxyRefs));
const all = uniqueNames.map((proxyName) =>
ensureProxyItem(proxyMap, proxyName),
);
return createGroupItem(String(name), all, {
type: entry.type ? String(entry.type) : "Selector",
provider: entry.provider,
testUrl: entry.testUrl || entry.test_url,
now: typeof entry.now === "string" ? entry.now : undefined,
});
};
const mapRecords = (
proxies: Map<string, IProxyItem>,
groups: IProxyGroupItem[],
extra: IProxyItem[] = [],
): Record<string, IProxyItem> => {
const result: Record<string, IProxyItem> = {};
proxies.forEach((item, key) => {
result[key] = item;
});
groups.forEach((group) => {
result[group.name] = group as unknown as IProxyItem;
});
extra.forEach((item) => {
result[item.name] = item;
});
return result;
};
export const createProxySnapshotFromProfile = (
yamlContent: string,
): {
global: IProxyGroupItem;
direct: IProxyItem;
groups: IProxyGroupItem[];
records: Record<string, IProxyItem>;
proxies: IProxyItem[];
} | null => {
let parsed: any;
try {
parsed = yaml.load(yamlContent);
} catch (error) {
console.warn("[ProxySnapshot] Failed to parse YAML:", error);
return null;
}
if (!parsed || typeof parsed !== "object") {
return null;
}
const proxyMap = new Map<string, IProxyItem>();
if (Array.isArray((parsed as any).proxies)) {
for (const entry of (parsed as any).proxies) {
const item = parseProxyEntry(entry);
if (item) {
proxyMap.set(item.name, item);
}
}
}
const proxyProviders = (parsed as any)["proxy-providers"];
if (proxyProviders && typeof proxyProviders === "object") {
for (const key of Object.keys(proxyProviders)) {
const provider = proxyProviders[key];
if (provider && Array.isArray(provider.proxies)) {
provider.proxies
.filter(
(proxyName: unknown): proxyName is string =>
typeof proxyName === "string",
)
.forEach((proxyName: string) => ensureProxyItem(proxyMap, proxyName));
}
}
}
const groups: IProxyGroupItem[] = [];
if (Array.isArray((parsed as any)["proxy-groups"])) {
for (const entry of (parsed as any)["proxy-groups"]) {
const groupItem = parseProxyGroup(entry, proxyMap);
if (groupItem) {
groups.push(groupItem);
}
}
}
const direct = createProxyItem("DIRECT", { type: "Direct" });
const reject = createProxyItem("REJECT", { type: "Reject" });
ensureProxyItem(proxyMap, direct.name, direct);
ensureProxyItem(proxyMap, reject.name, reject);
let global = groups.find((group) => group.name === "GLOBAL");
if (!global) {
const globalRefs = groups.flatMap((group) =>
group.all.map((proxy) => proxy.name),
);
const unique = Array.from(new Set(globalRefs));
const all = unique.map((name) => ensureProxyItem(proxyMap, name));
global = createGroupItem("GLOBAL", all, {
type: "Selector",
hidden: true,
});
groups.unshift(global);
}
const proxies = Array.from(proxyMap.values()).filter(
(item) => !groups.some((group) => group.name === item.name),
);
const records = mapRecords(proxyMap, groups, [direct, reject]);
return {
global,
direct,
groups,
records,
proxies,
};
};