stable-sort-domain.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // tldts-experimental is way faster than tldts, but very little bit inaccurate
  2. // (since it is hashes based). But the result is still deterministic, which is
  3. // enough when sorting.
  4. import * as tldts from 'tldts-experimental';
  5. import { looseTldtsOpt } from '../constants/loose-tldts-opt';
  6. import { fastStringCompare } from './misc';
  7. export function compare(a: string, b: string) {
  8. if (a === b) return 0;
  9. return (a.length - b.length) || fastStringCompare(a, b);
  10. }
  11. export function buildParseDomainMap(inputs: string[]) {
  12. const domainMap = new Map<string, string>();
  13. const subdomainMap = new Map<string, string>();
  14. for (let i = 0, len = inputs.length; i < len; i++) {
  15. const cur = inputs[i];
  16. if (!domainMap.has(cur)) {
  17. const parsed = tldts.parse(cur, looseTldtsOpt);
  18. domainMap.set(cur, parsed.domain ?? cur);
  19. // if (!subdomainMap.has(cur)) {
  20. subdomainMap.set(cur, parsed.subdomain ?? cur);
  21. }
  22. }
  23. return { domainMap, subdomainMap };
  24. }
  25. export function sortDomains(
  26. inputs: string[],
  27. domainMap?: Map<string, string> | null,
  28. subdomainMap?: Map<string, string> | null
  29. ) {
  30. if (!domainMap || !subdomainMap) {
  31. const { domainMap: dm, subdomainMap: sm } = buildParseDomainMap(inputs);
  32. domainMap = dm;
  33. subdomainMap = sm;
  34. }
  35. const sorter = (a: string, b: string) => {
  36. if (a === b) return 0;
  37. const main_domain_a = domainMap.get(a)!;
  38. const main_domain_b = domainMap.get(b)!;
  39. let t = compare(main_domain_a, main_domain_b)
  40. || compare(
  41. /** subdomain_a */ subdomainMap.get(a)!,
  42. /** subdomain_b */ subdomainMap.get(b)!
  43. );
  44. if (t !== 0) return t;
  45. if (a !== main_domain_a || b !== main_domain_b) {
  46. t = compare(a, b);
  47. }
  48. return t;
  49. };
  50. return inputs.sort(sorter);
  51. }