From bdc1f5ec82e124ca0e6beeb921eeb6b28e804065 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Mon, 2 Jun 2025 00:44:07 +0800 Subject: [PATCH] Refactor: use `foxts` more --- Build/build-apple-cdn.ts | 4 +-- Build/build-chn-cidr.ts | 4 +-- ...c-direct-lan-ruleset-dns-mapping-module.ts | 4 +-- Build/build-microsoft-cdn.ts | 4 +-- Build/build-telegram-cidr.ts | 4 +-- Build/lib/is-domain-alive.ts | 18 +++++++------ Build/lib/memo-promise.ts | 26 ------------------- package.json | 2 +- pnpm-lock.yaml | 24 ++++++++--------- 9 files changed, 33 insertions(+), 57 deletions(-) delete mode 100644 Build/lib/memo-promise.ts diff --git a/Build/build-apple-cdn.ts b/Build/build-apple-cdn.ts index c9710e1c..d0642b79 100644 --- a/Build/build-apple-cdn.ts +++ b/Build/build-apple-cdn.ts @@ -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()); diff --git a/Build/build-chn-cidr.ts b/Build/build-chn-cidr.ts index 0f285a97..777bc102 100644 --- a/Build/build-chn-cidr.ts +++ b/Build/build-chn-cidr.ts @@ -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), fetchRemoteTextByLine('https://gaoyifan.github.io/china-operator-ip/china6.txt', true).then(Array.fromAsync) diff --git a/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts b/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts index ed0e6ec2..133c74be 100644 --- a/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts +++ b/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts @@ -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[] = []; diff --git a/Build/build-microsoft-cdn.ts b/Build/build-microsoft-cdn.ts index c2acc4d7..d4e30f2f 100644 --- a/Build/build-microsoft-cdn.ts +++ b/Build/build-microsoft-cdn.ts @@ -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>(async () => { const res = await pool.exec( 'getMicrosoftCdnRuleset', [import.meta.url] diff --git a/Build/build-telegram-cidr.ts b/Build/build-telegram-cidr.ts index 875d5573..875459c2 100644 --- a/Build/build-telegram-cidr.ts +++ b/Build/build-telegram-cidr.ts @@ -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(); diff --git a/Build/lib/is-domain-alive.ts b/Build/lib/is-domain-alive.ts index b3cfcd88..d4d70c37 100644 --- a/Build/lib/is-domain-alive.ts +++ b/Build/lib/is-domain-alive.ts @@ -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 { +export async function isDomainAlive( + domain: string, + // we dont need to check domain[0] here, this is only from runAgainstSourceFile + isIncludeAllSubdomain: boolean +): Promise { 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; }); } diff --git a/Build/lib/memo-promise.ts b/Build/lib/memo-promise.ts deleted file mode 100644 index 97123c17..00000000 --- a/Build/lib/memo-promise.ts +++ /dev/null @@ -1,26 +0,0 @@ -const notError = Symbol('notError'); - -export function createMemoizedPromise( - fn: () => Promise, - /** whether to create promise immediately or only create after first access */ - preload = true -): () => Promise { - let error: Error | typeof notError = notError; - - let promise: Promise | 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; - }; -} diff --git a/package.json b/package.json index b5b5ee6c..3ada87bf 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "fast-cidr-tools": "^0.3.2", "fast-fifo": "^1.3.2", "fdir": "^6.4.5", - "foxts": "^3.3.3", + "foxts": "^3.4.0", "hash-wasm": "^4.12.0", "json-stringify-pretty-compact": "3.0.0", "null-prototype-object": "^1.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f356693..be1fb8c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: ^6.4.5 version: 6.4.5(picomatch@4.0.2) foxts: - specifier: ^3.3.3 - version: 3.3.3 + specifier: ^3.4.0 + version: 3.4.0 hash-wasm: specifier: ^4.12.0 version: 4.12.0 @@ -1200,8 +1200,8 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-escape-html@1.0.0: - resolution: {integrity: sha512-f5flzdfLAWKlW2hJAHFh2iyMhTlX6tEMaBuRXwvSKtyYEqv9OR0y7mJz6tHs3CDB2opBU5hTWpm9AROhfWTK7A==} + fast-escape-html@1.1.0: + resolution: {integrity: sha512-nRvjfywv8gzIBs0fM/ht6S5scNUamm+o+91p/69cYYNWODb7b/UiQfjFx+6n8NMtdHs6K80kh+hW1dPNS/opIA==} fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} @@ -1257,8 +1257,8 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - foxts@3.3.3: - resolution: {integrity: sha512-9TkeFw6bXXphI9Pu7SOI/+gO8g5bNjs3/s2kPDRwRHnJ46weDxoB6V+gG7mzr+9xsVedjSVxv+4xErNGpgDOtQ==} + foxts@3.4.0: + resolution: {integrity: sha512-zpI41ZJ/ZjG745XMVJy338CU1WLwkp1AobgGNKvFDEvSz8y7Lv+DTUpAj/BUyXg7TocGDpSwRH6o9XyAvkMO5A==} fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -2764,7 +2764,7 @@ snapshots: eslint-plugin-regexp: 2.7.0(eslint@9.27.0) eslint-plugin-sukka: 6.20.0(eslint@9.27.0)(typescript@5.8.3) eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0)(typescript@5.8.3))(eslint@9.27.0)(typescript@5.8.3))(eslint@9.27.0) - foxts: 3.3.3 + foxts: 3.4.0 jsonc-eslint-parser: 2.4.0 picocolors: 1.1.1 typescript-eslint: 8.32.1(eslint@9.27.0)(typescript@5.8.3) @@ -2898,7 +2898,7 @@ snapshots: '@eslint-sukka/shared': 6.20.0(eslint@9.27.0)(typescript@5.8.3) '@typescript-eslint/type-utils': 8.32.1(eslint@9.27.0)(typescript@5.8.3) '@typescript-eslint/utils': 8.32.1(eslint@9.27.0)(typescript@5.8.3) - foxts: 3.3.3 + foxts: 3.4.0 optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -3002,7 +3002,7 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-escape-html@1.0.0: {} + fast-escape-html@1.1.0: {} fast-fifo@1.3.2: {} @@ -3055,9 +3055,9 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - foxts@3.3.3: + foxts@3.4.0: dependencies: - fast-escape-html: 1.0.0 + fast-escape-html: 1.1.0 fs-constants@1.0.0: {} @@ -3656,7 +3656,7 @@ snapshots: undici-cache-store-better-sqlite3@1.0.0(undici@7.10.0): dependencies: better-sqlite3: 11.10.0 - foxts: 3.3.3 + foxts: 3.4.0 undici: 7.10.0 undici-types@6.21.0: {}