mirror of
https://github.com/SukkaW/Surge.git
synced 2026-01-28 17:41:54 +08:00
Refactor: use foxts more
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { parseFelixDnsmasqFromResp } from './lib/parse-dnsmasq';
|
||||
import { task } from './trace';
|
||||
import { SHARED_DESCRIPTION } from './constants/description';
|
||||
import { createMemoizedPromise } from './lib/memo-promise';
|
||||
import { once } from 'foxts/once';
|
||||
import { DomainsetOutput } from './lib/rules/domainset';
|
||||
import { $$fetch } from './lib/fetch-retry';
|
||||
|
||||
export const getAppleCdnDomainsPromise = createMemoizedPromise(() => $$fetch('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf').then(parseFelixDnsmasqFromResp));
|
||||
export const getAppleCdnDomainsPromise = once(() => $$fetch('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf').then(parseFelixDnsmasqFromResp));
|
||||
|
||||
export const buildAppleCdn = task(require.main === module, __filename)(async (span) => {
|
||||
const res: string[] = await span.traceChildPromise('get apple cdn domains', getAppleCdnDomainsPromise());
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { fetchRemoteTextByLine } from './lib/fetch-text-by-line';
|
||||
import { task } from './trace';
|
||||
|
||||
import { createMemoizedPromise } from './lib/memo-promise';
|
||||
import { once } from 'foxts/once';
|
||||
import { IPListOutput } from './lib/rules/ip';
|
||||
import { createFileDescription } from './constants/description';
|
||||
|
||||
export const getChnCidrPromise = createMemoizedPromise(async function getChnCidr() {
|
||||
export const getChnCidrPromise = once(async function getChnCidr() {
|
||||
return Promise.all([
|
||||
fetchRemoteTextByLine('https://chnroutes2.cdn.skk.moe/chnroutes.txt', true).then(Array.fromAsync<string>),
|
||||
fetchRemoteTextByLine('https://gaoyifan.github.io/china-operator-ip/china6.txt', true).then(Array.fromAsync<string>)
|
||||
|
||||
@@ -7,7 +7,7 @@ import { readFileIntoProcessedArray } from './lib/fetch-text-by-line';
|
||||
import { compareAndWriteFile } from './lib/create-file';
|
||||
import { task } from './trace';
|
||||
import { SHARED_DESCRIPTION } from './constants/description';
|
||||
import { createMemoizedPromise } from './lib/memo-promise';
|
||||
import { once } from 'foxts/once';
|
||||
import * as yaml from 'yaml';
|
||||
import { appendArrayInPlace } from 'foxts/append-array-in-place';
|
||||
import { OUTPUT_INTERNAL_DIR, OUTPUT_MODULES_DIR, OUTPUT_MODULES_RULES_DIR, SOURCE_DIR } from './constants/dir';
|
||||
@@ -52,7 +52,7 @@ export function createGetDnsMappingRule(allowWildcard: boolean) {
|
||||
};
|
||||
}
|
||||
|
||||
export const getDomesticAndDirectDomainsRulesetPromise = createMemoizedPromise(async () => {
|
||||
export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
|
||||
const domestics = await readFileIntoProcessedArray(path.join(SOURCE_DIR, 'non_ip/domestic.conf'));
|
||||
const directs = await readFileIntoProcessedArray(path.resolve(SOURCE_DIR, 'non_ip/direct.conf'));
|
||||
const lans: string[] = [];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { task } from './trace';
|
||||
import { SHARED_DESCRIPTION } from './constants/description';
|
||||
import { createMemoizedPromise } from './lib/memo-promise';
|
||||
import { once } from 'foxts/once';
|
||||
import { RulesetOutput } from './lib/rules/ruleset';
|
||||
import Worktank from 'worktank';
|
||||
|
||||
@@ -44,7 +44,7 @@ const pool = new Worktank({
|
||||
}
|
||||
});
|
||||
|
||||
export const getMicrosoftCdnRulesetPromise = createMemoizedPromise<[domains: string[], domainSuffixes: string[]]>(async () => {
|
||||
export const getMicrosoftCdnRulesetPromise = once<Promise<[domains: string[], domainSuffixes: string[]]>>(async () => {
|
||||
const res = await pool.exec(
|
||||
'getMicrosoftCdnRuleset',
|
||||
[import.meta.url]
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
import { createReadlineInterfaceFromResponse } from './lib/fetch-text-by-line';
|
||||
import { task } from './trace';
|
||||
import { SHARED_DESCRIPTION } from './constants/description';
|
||||
import { createMemoizedPromise } from './lib/memo-promise';
|
||||
import { once } from 'foxts/once';
|
||||
import { RulesetOutput } from './lib/rules/ruleset';
|
||||
import { $$fetch } from './lib/fetch-retry';
|
||||
import { fastIpVersion } from './lib/misc';
|
||||
|
||||
export const getTelegramCIDRPromise = createMemoizedPromise(async () => {
|
||||
export const getTelegramCIDRPromise = once(async () => {
|
||||
const resp = await $$fetch('https://core.telegram.org/resources/cidr.txt');
|
||||
const lastModified = resp.headers.get('last-modified');
|
||||
const date = lastModified ? new Date(lastModified) : new Date();
|
||||
|
||||
@@ -80,7 +80,11 @@ const domesticDohServers: Array<[string, DNS2.DnsResolver]> = ([
|
||||
|
||||
const domainAliveMutex = createKeyedAsyncMutex('isDomainAlive');
|
||||
|
||||
export async function isDomainAlive(domain: string, isIncludeAllSubdomain: boolean = domain[0] === '.'): Promise<boolean> {
|
||||
export async function isDomainAlive(
|
||||
domain: string,
|
||||
// we dont need to check domain[0] here, this is only from runAgainstSourceFile
|
||||
isIncludeAllSubdomain: boolean
|
||||
): Promise<boolean> {
|
||||
if (domainAliveMap.has(domain)) {
|
||||
return domainAliveMap.get(domain)!;
|
||||
}
|
||||
@@ -102,8 +106,6 @@ export async function isDomainAlive(domain: string, isIncludeAllSubdomain: boole
|
||||
return domainAliveMutex.acquire(domain, async () => {
|
||||
domain = domain[0] === '.' ? domain.slice(1) : domain;
|
||||
|
||||
const $domain = isIncludeAllSubdomain ? '.' + domain : domain;
|
||||
|
||||
const aDns: string[] = [];
|
||||
const aaaaDns: string[] = [];
|
||||
|
||||
@@ -113,7 +115,7 @@ export async function isDomainAlive(domain: string, isIncludeAllSubdomain: boole
|
||||
// eslint-disable-next-line no-await-in-loop -- sequential
|
||||
const aRecords = (await $resolve(domain, 'A', servers[i]));
|
||||
if (aRecords.answers.length > 0) {
|
||||
domainAliveMap.set($domain, true);
|
||||
domainAliveMap.set(domain, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ export async function isDomainAlive(domain: string, isIncludeAllSubdomain: boole
|
||||
// eslint-disable-next-line no-await-in-loop -- sequential
|
||||
const aaaaRecords = (await $resolve(domain, 'AAAA', servers[i]));
|
||||
if (aaaaRecords.answers.length > 0) {
|
||||
domainAliveMap.set($domain, true);
|
||||
domainAliveMap.set(domain, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,7 +137,7 @@ export async function isDomainAlive(domain: string, isIncludeAllSubdomain: boole
|
||||
// eslint-disable-next-line no-await-in-loop -- sequential
|
||||
const aRecords = (await $resolve(domain, 'A', pickOne(domesticDohServers)));
|
||||
if (aRecords.answers.length > 0) {
|
||||
domainAliveMap.set($domain, true);
|
||||
domainAliveMap.set(domain, true);
|
||||
return true;
|
||||
}
|
||||
aDns.push(aRecords.dns);
|
||||
@@ -144,7 +146,7 @@ export async function isDomainAlive(domain: string, isIncludeAllSubdomain: boole
|
||||
// eslint-disable-next-line no-await-in-loop -- sequential
|
||||
const aaaaRecords = (await $resolve(domain, 'AAAA', pickOne(domesticDohServers)));
|
||||
if (aaaaRecords.answers.length > 0) {
|
||||
domainAliveMap.set($domain, true);
|
||||
domainAliveMap.set(domain, true);
|
||||
return true;
|
||||
}
|
||||
aaaaDns.push(aaaaRecords.dns);
|
||||
@@ -152,7 +154,7 @@ export async function isDomainAlive(domain: string, isIncludeAllSubdomain: boole
|
||||
|
||||
console.log(picocolors.red('[domain dead]'), 'no A/AAAA records', { domain, a: aDns, aaaa: aaaaDns });
|
||||
|
||||
domainAliveMap.set($domain, false);
|
||||
domainAliveMap.set(domain, false);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
const notError = Symbol('notError');
|
||||
|
||||
export function createMemoizedPromise<T>(
|
||||
fn: () => Promise<T>,
|
||||
/** whether to create promise immediately or only create after first access */
|
||||
preload = true
|
||||
): () => Promise<T> {
|
||||
let error: Error | typeof notError = notError;
|
||||
|
||||
let promise: Promise<T> | null = preload
|
||||
? fn().catch(e => {
|
||||
// Here we record the error so that we can throw it later when the function is called
|
||||
error = e;
|
||||
// Here we make sure the Promise still returns the never type
|
||||
throw e;
|
||||
})
|
||||
: null;
|
||||
|
||||
return () => {
|
||||
if (error !== notError) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
promise ??= fn();
|
||||
return promise;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user