stable-sort-domain.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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 { getDomain, getSubdomain } from 'tldts-experimental';
  5. import { sort } from './timsort';
  6. import { looseTldtsOpt } from '../constants/loose-tldts-opt';
  7. export const compare = (a: string, b: string) => {
  8. if (a === b) return 0;
  9. return (a.length - b.length) || a.localeCompare(b);
  10. };
  11. export const 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 topD = getDomain(cur, looseTldtsOpt);
  18. domainMap.set(cur, topD ?? cur);
  19. // if (!subdomainMap.has(cur)) {
  20. const subD = getSubdomain(cur, looseTldtsOpt);
  21. subdomainMap.set(cur, subD ?? cur);
  22. }
  23. }
  24. return { domainMap, subdomainMap };
  25. };
  26. export const sortDomains = (
  27. inputs: string[],
  28. domainMap?: Map<string, string>,
  29. subdomainMap?: Map<string, string>
  30. ) => {
  31. if (!domainMap || !subdomainMap) {
  32. const { domainMap: dm, subdomainMap: sm } = buildParseDomainMap(inputs);
  33. domainMap = dm;
  34. subdomainMap = sm;
  35. }
  36. const sorter = (a: string, b: string) => {
  37. if (a === b) return 0;
  38. const main_domain_a = domainMap.get(a)!;
  39. const main_domain_b = domainMap.get(b)!;
  40. let t = compare(
  41. main_domain_a,
  42. main_domain_b
  43. ) || compare(
  44. /** subdomain_a */ subdomainMap.get(a)!,
  45. /** subdomain_b */ subdomainMap.get(b)!
  46. );
  47. if (t !== 0) return t;
  48. if (a !== main_domain_a || b !== main_domain_b) {
  49. t = compare(a, b);
  50. }
  51. return t;
  52. };
  53. return sort(inputs, sorter);
  54. };