zynor 0.0.77 → 0.0.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -685,19 +685,60 @@ declare const EmailProviders: readonly [
685
685
  readonly name: "Outlook";
686
686
  readonly domains: readonly [
687
687
  "@outlook.com",
688
+ "@outlook.com.au",
689
+ "@outlook.com.br",
690
+ "@outlook.cl",
691
+ "@outlook.cz",
692
+ "@outlook.de",
693
+ "@outlook.dk",
694
+ "@outlook.es",
695
+ "@outlook.fr",
696
+ "@outlook.hu",
697
+ "@outlook.ie",
698
+ "@outlook.in",
699
+ "@outlook.it",
700
+ "@outlook.jp",
701
+ "@outlook.kr",
702
+ "@outlook.lv",
703
+ "@outlook.my",
704
+ "@outlook.ph",
705
+ "@outlook.pt",
706
+ "@outlook.sa",
707
+ "@outlook.sg",
708
+ "@outlook.sk",
709
+ "@outlook.co.id",
710
+ "@outlook.co.th",
688
711
  "@hotmail.com",
712
+ "@hotmail.com.ar",
713
+ "@hotmail.com.au",
714
+ "@hotmail.com.br",
689
715
  "@hotmail.co.uk",
716
+ "@hotmail.de",
717
+ "@hotmail.es",
690
718
  "@hotmail.fr",
719
+ "@hotmail.gr",
691
720
  "@hotmail.it",
692
- "@hotmail.es",
693
- "@hotmail.de",
721
+ "@hotmail.jp",
722
+ "@hotmail.nl",
723
+ "@hotmail.no",
724
+ "@hotmail.se",
694
725
  "@live.com",
726
+ "@live.com.ar",
727
+ "@live.com.au",
728
+ "@live.com.mx",
695
729
  "@live.co.uk",
730
+ "@live.ca",
731
+ "@live.cl",
732
+ "@live.cn",
733
+ "@live.de",
734
+ "@live.dk",
696
735
  "@live.fr",
697
- "@live.nl",
698
736
  "@live.it",
699
- "@live.com.au",
700
- "@live.ca",
737
+ "@live.jp",
738
+ "@live.nl",
739
+ "@live.no",
740
+ "@live.ru",
741
+ "@live.se",
701
742
  "@msn.com"
702
743
  ];
703
744
  },
@@ -1612,6 +1653,338 @@ declare const EmailProviders: readonly [
1612
1653
  "@tutamail.com",
1613
1654
  "@keemail.me"
1614
1655
  ];
1656
+ },
1657
+ {
1658
+ readonly name: "DuckDuckGo Email";
1659
+ readonly domains: readonly [
1660
+ "@duck.com"
1661
+ ];
1662
+ },
1663
+ {
1664
+ readonly name: "SimpleLogin";
1665
+ readonly domains: readonly [
1666
+ "@simplelogin.com",
1667
+ "@simplelogin.fr",
1668
+ "@simplelogin.co",
1669
+ "@simplelogin.io",
1670
+ "@aleeas.com",
1671
+ "@silomails.com",
1672
+ "@slmails.com",
1673
+ "@slmail.me"
1674
+ ];
1675
+ },
1676
+ {
1677
+ readonly name: "Addy.io";
1678
+ readonly domains: readonly [
1679
+ "@addy.io",
1680
+ "@anonaddy.com",
1681
+ "@anonaddy.me"
1682
+ ];
1683
+ },
1684
+ {
1685
+ readonly name: "Firefox Relay";
1686
+ readonly domains: readonly [
1687
+ "@mozmail.com"
1688
+ ];
1689
+ },
1690
+ {
1691
+ readonly name: "StartMail";
1692
+ readonly domains: readonly [
1693
+ "@startmail.com"
1694
+ ];
1695
+ },
1696
+ {
1697
+ readonly name: "Runbox";
1698
+ readonly domains: readonly [
1699
+ "@runbox.com"
1700
+ ];
1701
+ },
1702
+ {
1703
+ readonly name: "Disroot";
1704
+ readonly domains: readonly [
1705
+ "@disroot.org"
1706
+ ];
1707
+ },
1708
+ {
1709
+ readonly name: "Riseup";
1710
+ readonly domains: readonly [
1711
+ "@riseup.net"
1712
+ ];
1713
+ },
1714
+ {
1715
+ readonly name: "CounterMail";
1716
+ readonly domains: readonly [
1717
+ "@countermail.com"
1718
+ ];
1719
+ },
1720
+ {
1721
+ readonly name: "Soverin";
1722
+ readonly domains: readonly [
1723
+ "@soverin.net"
1724
+ ];
1725
+ },
1726
+ {
1727
+ readonly name: "WP";
1728
+ readonly domains: readonly [
1729
+ "@wp.pl",
1730
+ "@o2.pl",
1731
+ "@tlen.pl"
1732
+ ];
1733
+ },
1734
+ {
1735
+ readonly name: "Onet";
1736
+ readonly domains: readonly [
1737
+ "@onet.pl",
1738
+ "@op.pl",
1739
+ "@vp.pl",
1740
+ "@onet.eu"
1741
+ ];
1742
+ },
1743
+ {
1744
+ readonly name: "Interia";
1745
+ readonly domains: readonly [
1746
+ "@interia.pl",
1747
+ "@interia.eu",
1748
+ "@poczta.fm"
1749
+ ];
1750
+ },
1751
+ {
1752
+ readonly name: "Gazeta.pl";
1753
+ readonly domains: readonly [
1754
+ "@gazeta.pl"
1755
+ ];
1756
+ },
1757
+ {
1758
+ readonly name: "Seznam";
1759
+ readonly domains: readonly [
1760
+ "@seznam.cz",
1761
+ "@email.cz",
1762
+ "@post.cz"
1763
+ ];
1764
+ },
1765
+ {
1766
+ readonly name: "Centrum";
1767
+ readonly domains: readonly [
1768
+ "@centrum.cz",
1769
+ "@centrum.sk"
1770
+ ];
1771
+ },
1772
+ {
1773
+ readonly name: "Volny";
1774
+ readonly domains: readonly [
1775
+ "@volny.cz"
1776
+ ];
1777
+ },
1778
+ {
1779
+ readonly name: "Freemail HU";
1780
+ readonly domains: readonly [
1781
+ "@freemail.hu",
1782
+ "@citromail.hu"
1783
+ ];
1784
+ },
1785
+ {
1786
+ readonly name: "In.gr";
1787
+ readonly domains: readonly [
1788
+ "@in.gr"
1789
+ ];
1790
+ },
1791
+ {
1792
+ readonly name: "Sify";
1793
+ readonly domains: readonly [
1794
+ "@sifymail.com",
1795
+ "@sify.com"
1796
+ ];
1797
+ },
1798
+ {
1799
+ readonly name: "Indiatimes";
1800
+ readonly domains: readonly [
1801
+ "@indiatimes.com"
1802
+ ];
1803
+ },
1804
+ {
1805
+ readonly name: "BSNL";
1806
+ readonly domains: readonly [
1807
+ "@bsnl.in",
1808
+ "@dataone.in"
1809
+ ];
1810
+ },
1811
+ {
1812
+ readonly name: "Locaweb";
1813
+ readonly domains: readonly [
1814
+ "@lwmail.com.br"
1815
+ ];
1816
+ },
1817
+ {
1818
+ readonly name: "Movistar";
1819
+ readonly domains: readonly [
1820
+ "@telefonica.net",
1821
+ "@movistar.es"
1822
+ ];
1823
+ },
1824
+ {
1825
+ readonly name: "Telkom SA";
1826
+ readonly domains: readonly [
1827
+ "@telkomsa.net",
1828
+ "@vodamail.co.za",
1829
+ "@webmail.co.za"
1830
+ ];
1831
+ },
1832
+ {
1833
+ readonly name: "BIGLOBE";
1834
+ readonly domains: readonly [
1835
+ "@biglobe.ne.jp"
1836
+ ];
1837
+ },
1838
+ {
1839
+ readonly name: "@nifty";
1840
+ readonly domains: readonly [
1841
+ "@nifty.com",
1842
+ "@nifty.ne.jp"
1843
+ ];
1844
+ },
1845
+ {
1846
+ readonly name: "OCN";
1847
+ readonly domains: readonly [
1848
+ "@ocn.ne.jp"
1849
+ ];
1850
+ },
1851
+ {
1852
+ readonly name: "Rakuten";
1853
+ readonly domains: readonly [
1854
+ "@rakuten.co.jp",
1855
+ "@gol.com"
1856
+ ];
1857
+ },
1858
+ {
1859
+ readonly name: "Excite Japan";
1860
+ readonly domains: readonly [
1861
+ "@excite.co.jp"
1862
+ ];
1863
+ },
1864
+ {
1865
+ readonly name: "So-net";
1866
+ readonly domains: readonly [
1867
+ "@so-net.ne.jp"
1868
+ ];
1869
+ },
1870
+ {
1871
+ readonly name: "Xtra";
1872
+ readonly domains: readonly [
1873
+ "@xtra.co.nz"
1874
+ ];
1875
+ },
1876
+ {
1877
+ readonly name: "Spectrum";
1878
+ readonly domains: readonly [
1879
+ "@spectrum.net"
1880
+ ];
1881
+ },
1882
+ {
1883
+ readonly name: "RoadRunner";
1884
+ readonly domains: readonly [
1885
+ "@rr.com",
1886
+ "@twc.com",
1887
+ "@roadrunner.com",
1888
+ "@nc.rr.com",
1889
+ "@sc.rr.com",
1890
+ "@socal.rr.com",
1891
+ "@tampabay.rr.com",
1892
+ "@cinci.rr.com",
1893
+ "@nycap.rr.com",
1894
+ "@neo.rr.com"
1895
+ ];
1896
+ },
1897
+ {
1898
+ readonly name: "Mediacom";
1899
+ readonly domains: readonly [
1900
+ "@mediacombb.net",
1901
+ "@mchsi.com"
1902
+ ];
1903
+ },
1904
+ {
1905
+ readonly name: "Optimum";
1906
+ readonly domains: readonly [
1907
+ "@optimum.net"
1908
+ ];
1909
+ },
1910
+ {
1911
+ readonly name: "Suddenlink";
1912
+ readonly domains: readonly [
1913
+ "@suddenlink.net"
1914
+ ];
1915
+ },
1916
+ {
1917
+ readonly name: "RCN";
1918
+ readonly domains: readonly [
1919
+ "@rcn.com"
1920
+ ];
1921
+ },
1922
+ {
1923
+ readonly name: "Breezeline";
1924
+ readonly domains: readonly [
1925
+ "@atlanticbb.net",
1926
+ "@breezeline.com"
1927
+ ];
1928
+ },
1929
+ {
1930
+ readonly name: "BT Internet";
1931
+ readonly domains: readonly [
1932
+ "@btinternet.com",
1933
+ "@btopenworld.com",
1934
+ "@talk21.com"
1935
+ ];
1936
+ },
1937
+ {
1938
+ readonly name: "Virgin Media";
1939
+ readonly domains: readonly [
1940
+ "@virginmedia.com",
1941
+ "@virgin.net"
1942
+ ];
1943
+ },
1944
+ {
1945
+ readonly name: "TalkTalk";
1946
+ readonly domains: readonly [
1947
+ "@talktalk.net"
1948
+ ];
1949
+ },
1950
+ {
1951
+ readonly name: "Plusnet";
1952
+ readonly domains: readonly [
1953
+ "@plus.net",
1954
+ "@force9.co.uk",
1955
+ "@free-online.net"
1956
+ ];
1957
+ },
1958
+ {
1959
+ readonly name: "Rogers";
1960
+ readonly domains: readonly [
1961
+ "@rogers.com"
1962
+ ];
1963
+ },
1964
+ {
1965
+ readonly name: "Bell";
1966
+ readonly domains: readonly [
1967
+ "@bell.net"
1968
+ ];
1969
+ },
1970
+ {
1971
+ readonly name: "Telus";
1972
+ readonly domains: readonly [
1973
+ "@telus.net"
1974
+ ];
1975
+ },
1976
+ {
1977
+ readonly name: "Videotron";
1978
+ readonly domains: readonly [
1979
+ "@videotron.ca",
1980
+ "@videotron.qc.ca"
1981
+ ];
1982
+ },
1983
+ {
1984
+ readonly name: "Cogeco";
1985
+ readonly domains: readonly [
1986
+ "@cogeco.ca"
1987
+ ];
1615
1988
  }
1616
1989
  ];
1617
1990
  export type ProviderNames = typeof EmailProviders[number]["name"];
@@ -2186,7 +2559,6 @@ export interface ValidateCacheEntry {
2186
2559
  method?: "shallow" | "deep";
2187
2560
  }
2188
2561
  export declare class EmailValidator {
2189
- private resolver;
2190
2562
  private findIpKeys;
2191
2563
  private roles;
2192
2564
  private records;
@@ -2347,6 +2719,66 @@ export declare class EmailValidator {
2347
2719
  signal?: AbortSignal;
2348
2720
  timeout?: number;
2349
2721
  }): Promise<EmailResponse[]>;
2722
+ /**
2723
+ * Streams validation results as they complete, in completion order.
2724
+ *
2725
+ * Unlike {@link validateBulk}, which waits for every input before returning,
2726
+ * `each` invokes `onBatch` as soon as enough results have accumulated
2727
+ * (`returnBatch`, default 10) and continues until every input has been
2728
+ * processed. Designed for very large inputs (millions) where time-to-first
2729
+ * result matters and holding the entire result array in memory is wasteful.
2730
+ *
2731
+ * Concurrency is controlled here, not by the DNS layer: every validation
2732
+ * routes through the validator-internal direct path, which bypasses the
2733
+ * per-provider PQueue and rate limiter. DoH providers are load-balanced
2734
+ * round-robin per validation.
2735
+ *
2736
+ * Backpressure: `onBatch` is awaited serially. If the callback is slow and
2737
+ * the in-memory buffer reaches `10 * returnBatch`, workers pause picking
2738
+ * new emails until the buffer drains below the cap. This keeps memory
2739
+ * bounded for truly large inputs.
2740
+ *
2741
+ * Errors:
2742
+ * - Per-email errors become error-shaped {@link EmailResponse} entries in
2743
+ * the stream — they never abort the batch.
2744
+ * - An error thrown by `onBatch` aborts production: workers stop picking
2745
+ * new emails, in-flight work is awaited, and the returned promise
2746
+ * rejects with the first such error.
2747
+ *
2748
+ * Abort: when the supplied `signal` fires, workers stop picking new
2749
+ * emails, in-flight validations finish, the buffer is flushed via
2750
+ * `onBatch`, and the returned promise resolves cleanly.
2751
+ *
2752
+ * @param emails - The list of email addresses to validate
2753
+ * @param options - Streaming options
2754
+ * @param options.concurrency - Max parallel validations (default 500)
2755
+ * @param options.returnBatch - Min results buffered before invoking onBatch (default 10)
2756
+ * @param options.deep - Enable deep validation per email
2757
+ * @param options.logo - Fetch provider logo per email
2758
+ * @param options.signal - AbortSignal to cancel the batch
2759
+ * @param options.timeout - Per-validation timeout in ms
2760
+ * @param onBatch - Invoked with each completed batch; may return a Promise
2761
+ * @returns Resolves once every input has been processed and flushed
2762
+ *
2763
+ * @example
2764
+ * ```typescript
2765
+ * await validator.each(
2766
+ * emails, // could be millions
2767
+ * { concurrency: 500, returnBatch: 50, deep: true },
2768
+ * async (batch) => {
2769
+ * await db.insertMany(batch);
2770
+ * },
2771
+ * );
2772
+ * ```
2773
+ */
2774
+ each(emails: string[], options: {
2775
+ concurrency?: number;
2776
+ returnBatch?: number;
2777
+ deep?: boolean;
2778
+ logo?: boolean;
2779
+ signal?: AbortSignal;
2780
+ timeout?: number;
2781
+ } | undefined, onBatch: (batch: EmailResponse[]) => void | Promise<void>): Promise<void>;
2350
2782
  private is_wale4r_zimbra;
2351
2783
  private is_zimbra;
2352
2784
  private is_webmail;
@@ -2722,6 +3154,13 @@ export declare class Zynor {
2722
3154
  private dnsCache;
2723
3155
  private dnsTtl;
2724
3156
  private inflight;
3157
+ private rrIndex;
3158
+ private dnsInFlight;
3159
+ /** Epoch-ms until which a DoH provider is considered failing and excluded
3160
+ * from {@link pickFreestProvider}. Native is never paused — libuv errors
3161
+ * are local concerns, not upstream-health signals. */
3162
+ private dohPausedUntil;
3163
+ private static readonly DOH_PAUSE_MS;
2725
3164
  /**
2726
3165
  * Creates a new Zynor resolver instance.
2727
3166
  * @param config - Configuration for all providers
@@ -3000,6 +3439,36 @@ export declare class Zynor {
3000
3439
  * ```
3001
3440
  */
3002
3441
  resolve: IResolver["resolve"];
3442
+ /**
3443
+ * @internal Validator-only. Picks the enabled provider with the most spare
3444
+ * capacity (advertised `concurrency` minus current in-flight count),
3445
+ * skipping any DoH provider currently paused after a failure. Round-robin
3446
+ * breaks ties so we don't always hit the same one when load is even.
3447
+ * Native is included in the pool — it rides libuv's thread pool rather
3448
+ * than the shared HTTP socket pool DoH providers contend for, so mixing
3449
+ * it in spreads load across independent I/O substrates. If every enabled
3450
+ * provider is paused, the pause filter is dropped (we'd rather retry than
3451
+ * fail).
3452
+ */
3453
+ private pickFreestProvider;
3454
+ /**
3455
+ * Distinguishes "this provider is broken/slow" from cases that don't
3456
+ * indicate provider health:
3457
+ * - DNS-level no-such-name answers (ENOTFOUND/NODATA): authoritative,
3458
+ * not the provider's fault.
3459
+ * - AbortError: caller-initiated cancellation or per-call timeout.
3460
+ * A user's tight deadline shouldn't make us blacklist a healthy provider.
3461
+ */
3462
+ private isProviderFailure;
3463
+ /**
3464
+ * @internal Validator-only. Direct DNS path that bypasses the per-provider
3465
+ * PQueue and rate limiter while keeping LRU cache + singleflight. Provider
3466
+ * is chosen by least-loaded-first (the validator does not need to know or
3467
+ * pick); the in-flight counter is incremented inside the singleflight
3468
+ * closure so coalesced waiters don't overcount upstream load. Public
3469
+ * consumers must continue to use the queued resolve* methods.
3470
+ */
3471
+ _resolveDirect<T>(hostname: string, type: RecordType, options?: AbortOptions): Promise<T>;
3003
3472
  /**
3004
3473
  * Returns the sum of concurrency limits across all enabled DNS providers.
3005
3474
  * Used by `validateBulk` to determine default parallelism.
@@ -3029,6 +3498,32 @@ export declare class Zynor {
3029
3498
  signal?: AbortSignal;
3030
3499
  timeout?: number;
3031
3500
  }): Promise<EmailResponse[]>;
3501
+ /**
3502
+ * Streams validation results as they complete. Forwards to
3503
+ * {@link EmailValidator.each} on the singleton validator. See `each` for
3504
+ * full semantics — defaults are `concurrency: 500`, `returnBatch: 10`, and
3505
+ * all validator-routed DNS calls bypass the per-provider queue.
3506
+ *
3507
+ * @param emails - The list of email addresses to validate
3508
+ * @param options - Streaming options (concurrency, returnBatch, deep, etc.)
3509
+ * @param onBatch - Callback invoked with each completed batch
3510
+ * @returns Resolves once every input has been processed and flushed
3511
+ *
3512
+ * @example
3513
+ * ```typescript
3514
+ * await Zynor.each(emails, { returnBatch: 50 }, async (batch) => {
3515
+ * await db.insertMany(batch);
3516
+ * });
3517
+ * ```
3518
+ */
3519
+ static each(emails: string[], options: {
3520
+ concurrency?: number;
3521
+ returnBatch?: number;
3522
+ deep?: boolean;
3523
+ logo?: boolean;
3524
+ signal?: AbortSignal;
3525
+ timeout?: number;
3526
+ } | undefined, onBatch: Parameters<EmailValidator["each"]>[2]): Promise<void>;
3032
3527
  }
3033
3528
  /**
3034
3529
  * Resets the default resolver instance.