itd-api 0.6.0 → 0.7.0

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
@@ -372,6 +372,55 @@ interface Span {
372
372
  id?: string;
373
373
  }
374
374
  //#endregion
375
+ //#region src/core/buckets.d.ts
376
+ /**
377
+ * Ёмкость серверных счётчиков частоты, запросов в минуту.
378
+ *
379
+ * Таблица действует до первого ответа бакета; дальше ёмкость берётся из заголовка
380
+ * `x-ratelimit-limit` и заменяет табличную. `default` — счётчик любого пути без
381
+ * собственного правила на сервере.
382
+ */
383
+ declare const BUCKET_LIMITS: Readonly<{
384
+ readonly 'posts.stats': 180;
385
+ readonly default: 150;
386
+ readonly feed: 90;
387
+ readonly 'posts.like': 85;
388
+ readonly 'posts.comments': 80;
389
+ readonly hashtags: 50;
390
+ readonly users: 40;
391
+ readonly notifications: 40;
392
+ readonly 'files.get': 40;
393
+ readonly auth: 35;
394
+ readonly 'auth.refresh': 25;
395
+ readonly search: 25;
396
+ readonly 'comments.like': 22;
397
+ readonly 'files.upload': 15;
398
+ readonly 'files.remove': 15;
399
+ readonly 'posts.comment': 14;
400
+ readonly 'hashtags.trending': 13;
401
+ readonly 'posts.repost': 7;
402
+ readonly 'users.follow': 7;
403
+ readonly 'verification.status': 6;
404
+ readonly 'posts.create': 5;
405
+ readonly 'users.updateMe': 3;
406
+ readonly 'reports.create': 3;
407
+ readonly 'verification.submit': 3;
408
+ }>;
409
+ /** Имя встроенного бакета. */
410
+ type RateLimitBucket = keyof typeof BUCKET_LIMITS;
411
+ /** Счётчик, из которого списывается путь без собственного правила на сервере. */
412
+ declare const DEFAULT_RATE_LIMIT_BUCKET: RateLimitBucket;
413
+ /** Реакция на остаток лимита из заголовков ответа. */
414
+ declare const RateLimitPacing: Readonly<{
415
+ /** Задержек нет, пока в бакете есть остаток; исчерпанный бакет ждёт `60000 / limit`. */
416
+ readonly React: "react";
417
+ /** Ровный темп в пределах минутного лимита: задержки идут с первого запроса. */
418
+ readonly Smooth: "smooth";
419
+ /** Остаток на темп не влияет; остаётся пауза после `429`. */
420
+ readonly Off: "off";
421
+ }>;
422
+ type RateLimitPacing = (typeof RateLimitPacing)[keyof typeof RateLimitPacing];
423
+ //#endregion
375
424
  //#region src/core/clock.d.ts
376
425
  /**
377
426
  * Часы, которыми клиент измеряет время и планирует отложенную работу.
@@ -405,6 +454,13 @@ type RetrySafety = (typeof RetrySafety)[keyof typeof RetrySafety];
405
454
  interface OperationDefinition {
406
455
  readonly method: OperationMethod;
407
456
  readonly retrySafety: RetrySafety;
457
+ /**
458
+ * Бакет операции. Опущено — операция списывает из `default`.
459
+ *
460
+ * Счётчик определяется парой «путь + метод»: `GET /api/users/me` — 40 запросов
461
+ * в минуту, `PUT` того же пути — 3, `DELETE` — 150.
462
+ */
463
+ readonly bucket?: RateLimitBucket;
408
464
  }
409
465
  /**
410
466
  * Каталог встроенных операций.
@@ -420,58 +476,72 @@ declare const OPERATIONS: Readonly<{
420
476
  readonly 'auth.signUp': Readonly<{
421
477
  readonly method: "POST";
422
478
  readonly retrySafety: "unsafe";
479
+ readonly bucket: "auth";
423
480
  }>;
424
481
  readonly 'auth.signIn': Readonly<{
425
482
  readonly method: "POST";
426
483
  readonly retrySafety: "safe";
484
+ readonly bucket: "auth";
427
485
  }>;
428
486
  readonly 'auth.verifyOtp': Readonly<{
429
487
  readonly method: "POST";
430
488
  readonly retrySafety: "unsafe";
489
+ readonly bucket: "auth";
431
490
  }>;
432
491
  readonly 'auth.resendOtp': Readonly<{
433
492
  readonly method: "POST";
434
493
  readonly retrySafety: "unsafe";
494
+ readonly bucket: "auth";
435
495
  }>;
436
496
  readonly 'auth.refresh': Readonly<{
437
497
  readonly method: "POST";
438
498
  readonly retrySafety: "unsafe";
499
+ readonly bucket: "auth.refresh";
439
500
  }>;
440
501
  readonly 'auth.logout': Readonly<{
441
502
  readonly method: "POST";
442
503
  readonly retrySafety: "unsafe";
504
+ readonly bucket: "auth";
443
505
  }>;
444
506
  readonly 'auth.forgotPassword': Readonly<{
445
507
  readonly method: "POST";
446
508
  readonly retrySafety: "unsafe";
509
+ readonly bucket: "auth";
447
510
  }>;
448
511
  readonly 'auth.resetPassword': Readonly<{
449
512
  readonly method: "POST";
450
513
  readonly retrySafety: "unsafe";
514
+ readonly bucket: "auth";
451
515
  }>;
452
516
  readonly 'auth.changePassword': Readonly<{
453
517
  readonly method: "POST";
454
518
  readonly retrySafety: "unsafe";
519
+ readonly bucket: "auth";
455
520
  }>;
456
521
  readonly 'auth.sessions': Readonly<{
457
522
  readonly method: "GET";
458
523
  readonly retrySafety: "safe";
524
+ readonly bucket: "auth";
459
525
  }>;
460
526
  readonly 'auth.revokeSession': Readonly<{
461
527
  readonly method: "DELETE";
462
528
  readonly retrySafety: "unsafe";
529
+ readonly bucket: "auth";
463
530
  }>;
464
531
  readonly 'auth.revokeOtherSessions': Readonly<{
465
532
  readonly method: "DELETE";
466
533
  readonly retrySafety: "unsafe";
534
+ readonly bucket: "auth";
467
535
  }>;
468
536
  readonly 'users.me': Readonly<{
469
537
  readonly method: "GET";
470
538
  readonly retrySafety: "safe";
539
+ readonly bucket: "users";
471
540
  }>;
472
541
  readonly 'users.updateMe': Readonly<{
473
542
  readonly method: "PUT";
474
543
  readonly retrySafety: "idempotent";
544
+ readonly bucket: "users.updateMe";
475
545
  }>;
476
546
  readonly 'users.deactivate': Readonly<{
477
547
  readonly method: "DELETE";
@@ -488,38 +558,47 @@ declare const OPERATIONS: Readonly<{
488
558
  readonly 'users.get': Readonly<{
489
559
  readonly method: "GET";
490
560
  readonly retrySafety: "safe";
561
+ readonly bucket: "users";
491
562
  }>;
492
563
  readonly 'users.checkUsername': Readonly<{
493
564
  readonly method: "GET";
494
565
  readonly retrySafety: "safe";
566
+ readonly bucket: "users";
495
567
  }>;
496
568
  readonly 'users.search': Readonly<{
497
569
  readonly method: "GET";
498
570
  readonly retrySafety: "safe";
571
+ readonly bucket: "users";
499
572
  }>;
500
573
  readonly 'users.whoToFollow': Readonly<{
501
574
  readonly method: "GET";
502
575
  readonly retrySafety: "safe";
576
+ readonly bucket: "users";
503
577
  }>;
504
578
  readonly 'users.topClans': Readonly<{
505
579
  readonly method: "GET";
506
580
  readonly retrySafety: "safe";
581
+ readonly bucket: "users";
507
582
  }>;
508
583
  readonly 'users.follow': Readonly<{
509
584
  readonly method: "POST";
510
585
  readonly retrySafety: "unsafe";
586
+ readonly bucket: "users.follow";
511
587
  }>;
512
588
  readonly 'users.unfollow': Readonly<{
513
589
  readonly method: "DELETE";
514
590
  readonly retrySafety: "unsafe";
591
+ readonly bucket: "users.follow";
515
592
  }>;
516
593
  readonly 'users.followers': Readonly<{
517
594
  readonly method: "GET";
518
595
  readonly retrySafety: "safe";
596
+ readonly bucket: "users";
519
597
  }>;
520
598
  readonly 'users.following': Readonly<{
521
599
  readonly method: "GET";
522
600
  readonly retrySafety: "safe";
601
+ readonly bucket: "users";
523
602
  }>;
524
603
  readonly 'users.followStatus': Readonly<{
525
604
  readonly method: "POST";
@@ -536,10 +615,12 @@ declare const OPERATIONS: Readonly<{
536
615
  readonly 'users.blocked': Readonly<{
537
616
  readonly method: "GET";
538
617
  readonly retrySafety: "safe";
618
+ readonly bucket: "users";
539
619
  }>;
540
620
  readonly 'users.getPrivacy': Readonly<{
541
621
  readonly method: "GET";
542
622
  readonly retrySafety: "safe";
623
+ readonly bucket: "users";
543
624
  }>;
544
625
  readonly 'users.updatePrivacy': Readonly<{
545
626
  readonly method: "PUT";
@@ -548,6 +629,7 @@ declare const OPERATIONS: Readonly<{
548
629
  readonly 'users.pins': Readonly<{
549
630
  readonly method: "GET";
550
631
  readonly retrySafety: "safe";
632
+ readonly bucket: "users";
551
633
  }>;
552
634
  readonly 'users.setPin': Readonly<{
553
635
  readonly method: "PUT";
@@ -560,10 +642,12 @@ declare const OPERATIONS: Readonly<{
560
642
  readonly 'posts.list': Readonly<{
561
643
  readonly method: "GET";
562
644
  readonly retrySafety: "safe";
645
+ readonly bucket: "feed";
563
646
  }>;
564
647
  readonly 'posts.create': Readonly<{
565
648
  readonly method: "POST";
566
649
  readonly retrySafety: "unsafe";
650
+ readonly bucket: "posts.create";
567
651
  }>;
568
652
  readonly 'posts.get': Readonly<{
569
653
  readonly method: "GET";
@@ -584,18 +668,22 @@ declare const OPERATIONS: Readonly<{
584
668
  readonly 'posts.like': Readonly<{
585
669
  readonly method: "POST";
586
670
  readonly retrySafety: "unsafe";
671
+ readonly bucket: "posts.like";
587
672
  }>;
588
673
  readonly 'posts.unlike': Readonly<{
589
674
  readonly method: "DELETE";
590
675
  readonly retrySafety: "unsafe";
676
+ readonly bucket: "posts.like";
591
677
  }>;
592
678
  readonly 'posts.repost': Readonly<{
593
679
  readonly method: "POST";
594
680
  readonly retrySafety: "unsafe";
681
+ readonly bucket: "posts.repost";
595
682
  }>;
596
683
  readonly 'posts.unrepost': Readonly<{
597
684
  readonly method: "DELETE";
598
685
  readonly retrySafety: "unsafe";
686
+ readonly bucket: "posts.repost";
599
687
  }>;
600
688
  readonly 'posts.pin': Readonly<{
601
689
  readonly method: "POST";
@@ -612,6 +700,7 @@ declare const OPERATIONS: Readonly<{
612
700
  readonly 'posts.stats': Readonly<{
613
701
  readonly method: "POST";
614
702
  readonly retrySafety: "safe";
703
+ readonly bucket: "posts.stats";
615
704
  }>;
616
705
  readonly 'posts.byUser': Readonly<{
617
706
  readonly method: "GET";
@@ -624,10 +713,12 @@ declare const OPERATIONS: Readonly<{
624
713
  readonly 'posts.comments': Readonly<{
625
714
  readonly method: "GET";
626
715
  readonly retrySafety: "safe";
716
+ readonly bucket: "posts.comments";
627
717
  }>;
628
718
  readonly 'posts.comment': Readonly<{
629
719
  readonly method: "POST";
630
720
  readonly retrySafety: "unsafe";
721
+ readonly bucket: "posts.comment";
631
722
  }>;
632
723
  readonly 'comments.replies': Readonly<{
633
724
  readonly method: "GET";
@@ -652,30 +743,37 @@ declare const OPERATIONS: Readonly<{
652
743
  readonly 'comments.like': Readonly<{
653
744
  readonly method: "POST";
654
745
  readonly retrySafety: "unsafe";
746
+ readonly bucket: "comments.like";
655
747
  }>;
656
748
  readonly 'comments.unlike': Readonly<{
657
749
  readonly method: "DELETE";
658
750
  readonly retrySafety: "unsafe";
751
+ readonly bucket: "comments.like";
659
752
  }>;
660
753
  readonly 'files.upload': Readonly<{
661
754
  readonly method: "POST";
662
755
  readonly retrySafety: "unsafe";
756
+ readonly bucket: "files.upload";
663
757
  }>;
664
758
  readonly 'files.get': Readonly<{
665
759
  readonly method: "GET";
666
760
  readonly retrySafety: "safe";
761
+ readonly bucket: "files.get";
667
762
  }>;
668
763
  readonly 'files.remove': Readonly<{
669
764
  readonly method: "DELETE";
670
765
  readonly retrySafety: "unsafe";
766
+ readonly bucket: "files.remove";
671
767
  }>;
672
768
  readonly 'notifications.list': Readonly<{
673
769
  readonly method: "GET";
674
770
  readonly retrySafety: "safe";
771
+ readonly bucket: "notifications";
675
772
  }>;
676
773
  readonly 'notifications.count': Readonly<{
677
774
  readonly method: "GET";
678
775
  readonly retrySafety: "safe";
776
+ readonly bucket: "notifications";
679
777
  }>;
680
778
  readonly 'notifications.markRead': Readonly<{
681
779
  readonly method: "POST";
@@ -692,6 +790,7 @@ declare const OPERATIONS: Readonly<{
692
790
  readonly 'notifications.getSettings': Readonly<{
693
791
  readonly method: "GET";
694
792
  readonly retrySafety: "safe";
793
+ readonly bucket: "notifications";
695
794
  }>;
696
795
  readonly 'notifications.updateSettings': Readonly<{
697
796
  readonly method: "PUT";
@@ -700,30 +799,37 @@ declare const OPERATIONS: Readonly<{
700
799
  readonly 'realtime.poll.updates': Readonly<{
701
800
  readonly method: "GET";
702
801
  readonly retrySafety: "safe";
802
+ readonly bucket: "notifications";
703
803
  }>;
704
804
  readonly 'realtime.poll.unread': Readonly<{
705
805
  readonly method: "GET";
706
806
  readonly retrySafety: "safe";
807
+ readonly bucket: "notifications";
707
808
  }>;
708
809
  readonly 'hashtags.search': Readonly<{
709
810
  readonly method: "GET";
710
811
  readonly retrySafety: "safe";
812
+ readonly bucket: "hashtags";
711
813
  }>;
712
814
  readonly 'hashtags.trending': Readonly<{
713
815
  readonly method: "GET";
714
816
  readonly retrySafety: "safe";
817
+ readonly bucket: "hashtags.trending";
715
818
  }>;
716
819
  readonly 'hashtags.posts': Readonly<{
717
820
  readonly method: "GET";
718
821
  readonly retrySafety: "safe";
822
+ readonly bucket: "hashtags";
719
823
  }>;
720
824
  readonly 'search.all': Readonly<{
721
825
  readonly method: "GET";
722
826
  readonly retrySafety: "safe";
827
+ readonly bucket: "search";
723
828
  }>;
724
829
  readonly 'reports.create': Readonly<{
725
830
  readonly method: "POST";
726
831
  readonly retrySafety: "unsafe";
832
+ readonly bucket: "reports.create";
727
833
  }>;
728
834
  readonly 'subscription.status': Readonly<{
729
835
  readonly method: "GET";
@@ -756,10 +862,12 @@ declare const OPERATIONS: Readonly<{
756
862
  readonly 'verification.status': Readonly<{
757
863
  readonly method: "GET";
758
864
  readonly retrySafety: "safe";
865
+ readonly bucket: "verification.status";
759
866
  }>;
760
867
  readonly 'verification.submit': Readonly<{
761
868
  readonly method: "POST";
762
869
  readonly retrySafety: "unsafe";
870
+ readonly bucket: "verification.submit";
763
871
  }>;
764
872
  readonly 'platform.version': Readonly<{
765
873
  readonly method: "GET";
@@ -802,6 +910,13 @@ declare function isBuiltInOperationId(value: string): value is BuiltInOperationI
802
910
  declare function operationMethod(id: BuiltInOperationId): OperationMethod;
803
911
  /** Политика автоматического повтора встроенной операции. */
804
912
  declare function operationRetrySafety(id: BuiltInOperationId): RetrySafety;
913
+ /**
914
+ * Бакет операции.
915
+ *
916
+ * `raw` и `custom:*` попадают в `default`; назвать бакет явно позволяет
917
+ * `rateLimitBucket` у запроса.
918
+ */
919
+ declare function operationBucket(id: OperationId): RateLimitBucket;
805
920
  //#endregion
806
921
  //#region src/core/runtime.d.ts
807
922
  /**
@@ -914,31 +1029,65 @@ interface RetryDecisionContext {
914
1029
  method: string;
915
1030
  path: string;
916
1031
  }
1032
+ /** Поправка к одному бакету. */
1033
+ interface RateLimitBucketOverride {
1034
+ /** Одновременных запросов внутри бакета. */
1035
+ concurrency?: number | undefined;
1036
+ /** Ёмкость бакета до первого ответа, запросов в минуту. */
1037
+ limit?: number | undefined;
1038
+ }
1039
+ /** Что известно о запросе в момент выбора бакета. */
1040
+ interface RateLimitBucketContext {
1041
+ operationId: OperationId;
1042
+ method: string;
1043
+ path: string;
1044
+ }
917
1045
  /** Настройки ограничения нагрузки на API. */
918
1046
  interface RateLimitOptions {
919
- /** Сколько запросов выполняется одновременно. По умолчанию 6. */
1047
+ /** Одновременных запросов на всех бакетах вместе. По умолчанию 6. */
920
1048
  concurrency?: number | undefined;
921
1049
  /** Верхняя граница запросов в секунду. По умолчанию без ограничения. */
922
1050
  rps?: number | undefined;
923
1051
  /**
924
- * Паузы перед повторами при ответе `429`, мс.
925
- * По умолчанию `[1000, 5000, 30000, 60000, 90000]`.
1052
+ * Отдельная очередь на каждый бакет. По умолчанию `true`.
926
1053
  *
927
- * Сервер не сообщает, когда сбросится окно лимита, поэтому паузу приходится подбирать.
928
- * Лестница начинается с секунды: если окно почти истекло, работа продолжится почти
929
- * сразу, а если лимит исчерпан всерьёз паузы дорастут до полутора минут.
930
- * Когда лестница закончилась, {@link ItdRateLimitError} пробрасывается вызывающему коду.
1054
+ * `false` одна очередь на направление: её пауза придерживает все запросы разом.
1055
+ * В этом режиме ёмкость отдельного счётчика неизвестна, поэтому `bucketConcurrency`,
1056
+ * `bucketOverrides` и режим `pacing: 'smooth'` не действуют, а исчерпанный остаток
1057
+ * встречается первой ступенью `retryDelays`.
1058
+ */
1059
+ buckets?: boolean | undefined;
1060
+ /**
1061
+ * Одновременных запросов внутри одного бакета. По умолчанию равен `concurrency`.
931
1062
  *
932
- * Этот список не зависит от `retry.attempts`: тот управляет повторами при обрывах
933
- * сети и ошибках сервера, где уместен совсем другой темп.
1063
+ * Встроенное исключение `files.upload` с пределом 1. При `buckets: false` не действует.
934
1064
  */
935
- retryDelays?: readonly number[] | undefined;
1065
+ bucketConcurrency?: number | undefined;
936
1066
  /**
937
- * Тормозить ли очередь по заголовкам ответа. По умолчанию `true`.
1067
+ * Поправки для отдельных бакетов. Неизвестное имя ошибка конфигурации.
938
1068
  *
939
- * Выключите, если управляете темпом сами.
1069
+ * @example
1070
+ * ```ts
1071
+ * rateLimit: { bucketOverrides: { 'posts.create': { limit: 10 }, feed: { concurrency: 2 } } }
1072
+ * ```
940
1073
  */
941
- respectHeaders?: boolean | undefined;
1074
+ bucketOverrides?: Record<string, RateLimitBucketOverride> | undefined;
1075
+ /**
1076
+ * Своё правило выбора бакета. `undefined` из функции отдаёт запрос встроенной карте.
1077
+ *
1078
+ * Возвращайте конечное множество имён: каждое заводит свою очередь.
1079
+ */
1080
+ bucket?: ((request: RateLimitBucketContext) => string | undefined) | undefined;
1081
+ /** Реакция на остаток, см. {@link RateLimitPacing}. По умолчанию `'react'`. */
1082
+ pacing?: RateLimitPacing | undefined;
1083
+ /**
1084
+ * Паузы перед повторами при ответе `429`, мс.
1085
+ * По умолчанию `[1000, 5000, 30000, 60000, 90000]`.
1086
+ *
1087
+ * После последней ступени {@link ItdRateLimitError} пробрасывается вызывающему коду.
1088
+ * От `retry.attempts` не зависит: `retry: false` лестницу не отключает.
1089
+ */
1090
+ retryDelays?: readonly number[] | undefined;
942
1091
  }
943
1092
  /** Данные о запросе, доступные хукам. */
944
1093
  interface RequestContext {
@@ -1039,10 +1188,14 @@ interface ItdClientOptions {
1039
1188
  * Работает, только когда в `auth` переданы email и пароль. По умолчанию `true`.
1040
1189
  */
1041
1190
  reloginOnRefreshFailure?: boolean | undefined;
1042
- /** Своя реализация `fetch`: для Deno, React Native, тестов или прокси. */
1043
- fetch?: typeof fetch | undefined;
1044
- /** Часы для тайм-аутов, повторов и очередей. Обычно подменяются только в тестах. */
1045
- clock?: ItdClock | undefined;
1191
+ /**
1192
+ * Значение заголовка `X-Device-Id`, который уходит с каждым запросом.
1193
+ *
1194
+ * Сервер различает по нему записи в списке сессий, поэтому значение должно быть стабильным.
1195
+ * Если не задать, библиотека заведёт идентификатор сама и сохранит его в {@link ItdSession},
1196
+ * так что при постоянном хранилище он переживёт перезапуск процесса.
1197
+ */
1198
+ deviceId?: string | undefined;
1046
1199
  /** Таймаут запроса в мс. По умолчанию 30000 — столько же использует сайт итд.com. `0` снимает ограничение. */
1047
1200
  timeout?: number | undefined;
1048
1201
  /**
@@ -1057,20 +1210,14 @@ interface ItdClientOptions {
1057
1210
  retry?: RetryOptions | false | undefined;
1058
1211
  /** Ограничение нагрузки. `false` отключает очередь. */
1059
1212
  rateLimit?: RateLimitOptions | false | undefined;
1060
- /** Перехватчики запросов. */
1061
- hooks?: ClientHooks | undefined;
1062
- /** Отладочный вывод. `true` писать в `console`. */
1063
- logger?: Logger | boolean | undefined;
1213
+ /** Своя реализация `fetch`: для Deno, React Native, тестов или прокси. */
1214
+ fetch?: typeof fetch | undefined;
1215
+ /** Часы для тайм-аутов, повторов и очередей. Обычно подменяются только в тестах. */
1216
+ clock?: ItdClock | undefined;
1217
+ /** Как обращаться с cookie. По умолчанию определяется по среде исполнения. */
1218
+ mode?: RuntimeMode | undefined;
1064
1219
  /** Заголовки, добавляемые ко всем запросам, — например `User-Agent` для бота. */
1065
1220
  headers?: Record<string, string> | undefined;
1066
- /**
1067
- * Значение заголовка `X-Device-Id`, который уходит с каждым запросом.
1068
- *
1069
- * Сервер различает по нему записи в списке сессий, поэтому значение должно быть стабильным.
1070
- * Если не задать, библиотека заведёт идентификатор сама и сохранит его в {@link ItdSession},
1071
- * так что при постоянном хранилище он переживёт перезапуск процесса.
1072
- */
1073
- deviceId?: string | undefined;
1074
1221
  /**
1075
1222
  * Значение заголовка `User-Agent`. `false` — не отправлять его вовсе.
1076
1223
  *
@@ -1079,8 +1226,10 @@ interface ItdClientOptions {
1079
1226
  * В браузере опция не действует — там заголовок менять запрещено.
1080
1227
  */
1081
1228
  userAgent?: string | false | undefined;
1082
- /** Как обращаться с cookie. По умолчанию определяется по среде исполнения. */
1083
- mode?: RuntimeMode | undefined;
1229
+ /** Перехватчики запросов. */
1230
+ hooks?: ClientHooks | undefined;
1231
+ /** Отладочный вывод. `true` — писать в `console`. */
1232
+ logger?: Logger | boolean | undefined;
1084
1233
  }
1085
1234
  /**
1086
1235
  * Namespaces расширений отдельной операции.
@@ -1106,6 +1255,17 @@ interface RequestOptions {
1106
1255
  * интеграциям и осознанному переопределению серверного контракта.
1107
1256
  */
1108
1257
  retrySafety?: RetrySafety | undefined;
1258
+ /**
1259
+ * Имя бакета, из которого списывается запрос.
1260
+ *
1261
+ * Встроенные resources берут его из каталога операций; низкоуровневый вызов без этой
1262
+ * опции попадает в `default`.
1263
+ *
1264
+ * Имя сверяется со встроенной картой — незнакомое отвергается {@link ItdConfigError}
1265
+ * до отправки, независимо от того, включена ли очередь. Своё правило `rateLimit.bucket`
1266
+ * заводит собственное пространство имён и проверку снимает.
1267
+ */
1268
+ rateLimitBucket?: string | undefined;
1109
1269
  /** Настройки подключённых operation extensions, сгруппированные по владельцу. */
1110
1270
  extensions?: RequestExtensions | undefined;
1111
1271
  }
@@ -1165,7 +1325,7 @@ interface OperationRequestOptions extends RawRequestOptions {
1165
1325
  //#endregion
1166
1326
  //#region src/core/version.d.ts
1167
1327
  /** Версия библиотеки. Попадает в `User-Agent`. */
1168
- declare const LIBRARY_VERSION = "0.6.0";
1328
+ declare const LIBRARY_VERSION = "0.7.0";
1169
1329
  //#endregion
1170
1330
  //#region src/core/config.d.ts
1171
1331
  /** Базовый URL API итд.com. Домен записан в punycode: `итд.com`. */
@@ -1653,6 +1813,22 @@ interface ClientPlugin {
1653
1813
  install(api: PluginApi): void | PluginTeardown;
1654
1814
  }
1655
1815
  //#endregion
1816
+ //#region src/core/rate-limit.d.ts
1817
+ /** Снимок одного бакета. */
1818
+ interface RateLimitBucketState {
1819
+ /** Origin, на котором ведётся счётчик. `undefined` — очередь без известного направления. */
1820
+ destination: string | undefined;
1821
+ bucket: string;
1822
+ /** Ёмкость из последнего ответа; `undefined`, пока ответов не было. */
1823
+ limit: number | undefined;
1824
+ /** Остаток из последнего ответа. */
1825
+ remaining: number | undefined;
1826
+ /** Запросов бакета прошло в общую очередь и ещё не завершилось. */
1827
+ active: number;
1828
+ /** Запросов бакета ждёт своей очереди — из-за паузы или предела одновременности. */
1829
+ pending: number;
1830
+ }
1831
+ //#endregion
1656
1832
  //#region src/models/users.d.ts
1657
1833
  /** Значок-«пин» в профиле — награда или отметка платформы. */
1658
1834
  interface Pin {
@@ -4523,6 +4699,20 @@ declare class ItdClient {
4523
4699
  * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}
4524
4700
  */
4525
4701
  request<T = unknown>(options: RawRequestOptions): Promise<T>;
4702
+ /**
4703
+ * Остаток серверных лимитов по бакетам, через которые уже проходили запросы.
4704
+ *
4705
+ * Значения берутся из последнего ответа каждого бакета и быстро устаревают: сервер
4706
+ * восстанавливает квоту линейно и границу окна не сообщает. Пустой массив при
4707
+ * `rateLimit: false`. {@link close} снимок сохраняет, {@link dispose} очищает.
4708
+ *
4709
+ * @example
4710
+ * ```ts
4711
+ * const posts = itd.rateLimitState().find((state) => state.bucket === 'posts.create');
4712
+ * if ((posts?.remaining ?? Number.POSITIVE_INFINITY) < 3) await sleep(60_000);
4713
+ * ```
4714
+ */
4715
+ rateLimitState(): RateLimitBucketState[];
4526
4716
  /**
4527
4717
  * Подключает плагин.
4528
4718
  *
@@ -4726,16 +4916,14 @@ interface ItdAccountsOptions extends Omit<ItdClientOptions, 'auth' | 'storage' |
4726
4916
  /** Плагины, подключаемые каждому аккаунту, в том числе добавленному позже. */
4727
4917
  plugins?: readonly ClientPlugin[] | undefined;
4728
4918
  /**
4729
- * Как делить очередь запросов. По умолчанию `'account'` — своя у каждого.
4919
+ * Как делить очередь запросов. По умолчанию `'shared'` — одна на всех.
4730
4920
  *
4731
- * Лимиты итд.com считаются по аккаунту, а при работе через разные прокси общая очередь
4732
- * только мешает. Она нужна в другом случае: когда все аккаунты сидят на одном IP
4733
- * и упираются в ограничение по адресу, — тогда `'shared'` разводит их запросы во времени
4734
- * все разом, а не поаккаунтно.
4921
+ * Лимиты итд.com считаются по IP, поэтому аккаунты с одного адреса тратят общую квоту.
4922
+ * `'account'` даёт каждому свою очередь и нужен, когда у аккаунтов разные адреса
4923
+ * например, при своём прокси у каждого.
4735
4924
  *
4736
- * Настройки самой очереди берутся из общей опции `rateLimit`. Личный объект `rateLimit`
4737
- * в этом режиме запрещён, потому что не может изменить уже созданную очередь;
4738
- * `rateLimit: false` у отдельного аккаунта выводит его из неё.
4925
+ * В режиме `'shared'` настройки очереди берутся из общей опции `rateLimit`; аккаунту
4926
+ * разрешён только `rateLimit: false`, выводящий его из общей очереди.
4739
4927
  */
4740
4928
  rateLimitScope?: RateLimitScope | undefined;
4741
4929
  }
@@ -4743,8 +4931,9 @@ interface ItdAccountsOptions extends Omit<ItdClientOptions, 'auth' | 'storage' |
4743
4931
  * Настройки одного аккаунта. Общее мультихранилище задаёт контейнер, а аккаунт получает
4744
4932
  * свой срез автоматически; остальное — как у `ItdClient`.
4745
4933
  *
4746
- * При `rateLimitScope: 'shared'` объект `rateLimit` задаётся только контейнеру; аккаунту
4747
- * разрешено передать `false`, чтобы не ставить его запросы в общую очередь.
4934
+ * При `rateLimitScope: 'shared'` (умолчание) объект `rateLimit` задаётся только
4935
+ * контейнеру; аккаунту разрешено передать `false`, чтобы не ставить его запросы
4936
+ * в общую очередь.
4748
4937
  */
4749
4938
  type AddAccountOptions = Omit<ItdClientOptions, 'storage'>;
4750
4939
  /** Что можно уточнить при удалении аккаунта. */
@@ -5596,5 +5785,5 @@ interface RenderSpansOptions {
5596
5785
  */
5597
5786
  declare function renderSpans(content: string, spans?: readonly Span[] | null | undefined, options?: RenderSpansOptions): string;
5598
5787
  //#endregion
5599
- export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AccessType, type AccountEvents, type Actor, type AddAccountOptions, type AllowedMimeType, type Announcement, type AnnouncementButton, type Attachment, AttachmentType, type AttemptContext, type AttemptExtensions, type AttemptInterceptor, type AttemptNext, type AudioMimeType, type AuthEvents, type AuthIdentity, type AuthInput, type AuthResource, type AuthState, type Author, type AutoSpansOptions, type BuilderInput, type BuiltInOperationId, type CaptchaCredentials, type ChangelogEntry, type Clan, type ClientHooks, type ClientPlugin, type Comment, type CommentBuilder, type CommentInput, type CommentReplyTo, CommentSort, type CommentsParams, type CommentsResource, type CreateCommentInput, type CreatePollInput, type CreatePostData, type CreatePostInput, type CreateReportInput, type Credentials, type CredentialsAuth, type CustomOperationId, DEFAULT_BASE_URL, type DwellEntry, type EnumerableKeyValueStore, type ErrorContextHook, type FeedParams, FeedTab, type FileContent, type FileContext, type FileInput, type FileStreamContent, type FileStreamOptions, FileTransferMode, type FilesResource, type FollowResult, type ForgotPasswordInput, type FromStreamOptions, type Hashtag, type HashtagPostsParams, type HashtagsResource, IMAGE_MIME_TYPES, type ImageMimeType, IncidentKind, type InteractionEntry, InteractionType, type IsoDate, ItdAbortError, ItdAccounts, type ItdAccountsOptions, ItdApiError, type ItdApiErrorInit, ItdApiErrorKind, ItdAuthError, type ItdBuilder, ItdClient, type ItdClientOptions, type ItdClock, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, type ItdFieldErrors, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, ItdRateLimitError, ItdRealtime, ItdServerError, type ItdSession, ItdStateError, ItdTimeoutError, ItdValidationError, type KeyValueCodec, type KeyValueStore, type KeyValueStoreKeys, type KeyValueStoreResult, LIBRARY_VERSION, type LazyFile, type LikeResult, LikesVisibility, type Listener, type Logger, type Loose, type MarkupBuilder, type MarkupContent, type MarkupInput, type MarkupSpan, MemoryKeyValueStore, MemoryMultiTokenStorage, MemoryTokenStorage, type MultiTokenStorage, type MultiTokenStorageAdapterOptions, type MyProfile, type Notification, type NotificationEvent, type NotificationEventOfType, type NotificationListParams, type NotificationOfType, type NotificationSettings, NotificationType, type NotificationsResource, OPERATIONS, type OperationDefinition, type OperationExtensions, type OperationId, type OperationMethod, type OperationRequestOptions, type OperationTransformer, type Page, type PageState, PaginationMode, type PaginationOptions, Paginator, type PaginatorOptions, type ParseMarkupOptions, type PaymentMethod, type PhotoOpenInput, type Pin, type PinPostResult, type PinsResult, type PlatformClientVersion, type PlatformResource, type PlatformStatus, type PlatformVersions, type PluginApi, type PluginTeardown, type Poll, type PollBuilder, type PollInput, type PollOption, type Portal, type Post, type PostBuilder, type PostInput, type PostStats, type PostUpdateInput, type PostsResource, type PrivacySettings, type Profile, type PublicProfile, type QueryParams, type QueryValue, type RateLimitOptions, type RateLimitScope, type RawRequestOptions, RealtimeComposer, type RealtimeContext, type RealtimeContextBase, type RealtimeEngineEvents, type RealtimeErrorBoundary, type RealtimeErrorContext, type RealtimeEvents, type RealtimeFilter, type RealtimeHandler, type RealtimeMiddleware, type RealtimeMiddlewareGroup, type RealtimeMiddlewareLike, type RealtimeMiddlewareObj, type RealtimeNext, type RealtimeNotificationContext, type RealtimeNotificationFilter, type RealtimeNotificationSelector, type RealtimeNotificationUpdate, type RealtimeOptions, type RealtimePredicate, type RealtimeRequest, type RealtimeRequestInput, type RealtimeRouteSelector, type RealtimeRouteTable, RealtimeRouter, type RealtimeSequentializer, RealtimeStatus, type RealtimeTransport, RealtimeTransportKind, type RealtimeTypeGuard, type RealtimeUnknownUpdate, type RealtimeUnreadCountUpdate, type RealtimeUpdate, type RealtimeUpdateOfType, RealtimeUpdateOrigin, RealtimeUpdateType, type ReconnectOptions, type RecordKeyValueStoreSource, type RemoveAccountOptions, type RenderSpansOptions, type RepliesParams, type Report, type ReportBuilder, type ReportInput, ReportReason, ReportTargetType, type ReportsResource, type RequestContext, type RequestExtensions, type RequestOptions, type ResetPasswordInput, type ResponseContext, type RetryContext, type RetryDecisionContext, type RetryOptions, RetrySafety, RuntimeMode, STATUS_SERVICE, type SearchResource, type SearchResult, type ServiceDefinition, ServiceState, type ServiceStatus, type Session, type SignInResult, SignInStatus, type Span, SpanRenderFormat, SpanType, type StatusDay, type StatusIncidentLine, type StreamFile, type Subscription, type SubscriptionResource, type SubscriptionState, TURNSTILE_SITE_KEY, type TelemetryBatch, type TelemetryBatchOptions, type TelemetryClock, type TelemetryOptions, type TelemetryResource, type TextMarkup, type TokenStorage, type TokenStorageAdapterOptions, type TransportContext, type TransportEvent, UnauthorizedStreamError, type Unsubscribe, type UpdateNotificationSettingsInput, type UpdatePostInput, type UpdatePrivacyInput, type UpdateProfileInput, type UploadOptions, type UploadedFile, type UrlFile, type UrlFileOptions, type UserId, type UserListParams, type UserPostsParams, type UserRef, type UserSummary, type UsersResource, VIDEO_MIME_TYPES, type VerificationResource, type VerificationStatus, type VideoMimeType, type VideoProgressInput, ViewReason, ViewSource, type ViewTracker, type ViewTrackerInput, type ViewTrackerOptions, WallAccess, type WebSocketImplementationOptions, type WebSocketLike, type WebSocketOpenFailureClassifier, WebSocketTransport, type WebSocketTransportOptions, autoSpans, canonicalNotificationType, comment, createAccounts, createClient, createKeyValueStore, createMultiTokenStorage, createRecordKeyValueStore, createTokenStorage, formatNotificationText, fromStream, fromUrl, isBuilder, isBuiltInOperationId, isEnumerableKeyValueStore, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdStateError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, operationMethod, operationRetrySafety, parseHtml, parseMarkdown, poll, post, renderSpans, report, resolveNotificationUrl, runRealtimeMiddleware, scopedTokenStorage, statusDays, systemClock, toDate, utcStampToIso, withCodec, withNamespace };
5788
+ export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AccessType, type AccountEvents, type Actor, type AddAccountOptions, type AllowedMimeType, type Announcement, type AnnouncementButton, type Attachment, AttachmentType, type AttemptContext, type AttemptExtensions, type AttemptInterceptor, type AttemptNext, type AudioMimeType, type AuthEvents, type AuthIdentity, type AuthInput, type AuthResource, type AuthState, type Author, type AutoSpansOptions, BUCKET_LIMITS, type BuilderInput, type BuiltInOperationId, type CaptchaCredentials, type ChangelogEntry, type Clan, type ClientHooks, type ClientPlugin, type Comment, type CommentBuilder, type CommentInput, type CommentReplyTo, CommentSort, type CommentsParams, type CommentsResource, type CreateCommentInput, type CreatePollInput, type CreatePostData, type CreatePostInput, type CreateReportInput, type Credentials, type CredentialsAuth, type CustomOperationId, DEFAULT_BASE_URL, DEFAULT_RATE_LIMIT_BUCKET, type DwellEntry, type EnumerableKeyValueStore, type ErrorContextHook, type FeedParams, FeedTab, type FileContent, type FileContext, type FileInput, type FileStreamContent, type FileStreamOptions, FileTransferMode, type FilesResource, type FollowResult, type ForgotPasswordInput, type FromStreamOptions, type Hashtag, type HashtagPostsParams, type HashtagsResource, IMAGE_MIME_TYPES, type ImageMimeType, IncidentKind, type InteractionEntry, InteractionType, type IsoDate, ItdAbortError, ItdAccounts, type ItdAccountsOptions, ItdApiError, type ItdApiErrorInit, ItdApiErrorKind, ItdAuthError, type ItdBuilder, ItdClient, type ItdClientOptions, type ItdClock, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, type ItdFieldErrors, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, ItdRateLimitError, ItdRealtime, ItdServerError, type ItdSession, ItdStateError, ItdTimeoutError, ItdValidationError, type KeyValueCodec, type KeyValueStore, type KeyValueStoreKeys, type KeyValueStoreResult, LIBRARY_VERSION, type LazyFile, type LikeResult, LikesVisibility, type Listener, type Logger, type Loose, type MarkupBuilder, type MarkupContent, type MarkupInput, type MarkupSpan, MemoryKeyValueStore, MemoryMultiTokenStorage, MemoryTokenStorage, type MultiTokenStorage, type MultiTokenStorageAdapterOptions, type MyProfile, type Notification, type NotificationEvent, type NotificationEventOfType, type NotificationListParams, type NotificationOfType, type NotificationSettings, NotificationType, type NotificationsResource, OPERATIONS, type OperationDefinition, type OperationExtensions, type OperationId, type OperationMethod, type OperationRequestOptions, type OperationTransformer, type Page, type PageState, PaginationMode, type PaginationOptions, Paginator, type PaginatorOptions, type ParseMarkupOptions, type PaymentMethod, type PhotoOpenInput, type Pin, type PinPostResult, type PinsResult, type PlatformClientVersion, type PlatformResource, type PlatformStatus, type PlatformVersions, type PluginApi, type PluginTeardown, type Poll, type PollBuilder, type PollInput, type PollOption, type Portal, type Post, type PostBuilder, type PostInput, type PostStats, type PostUpdateInput, type PostsResource, type PrivacySettings, type Profile, type PublicProfile, type QueryParams, type QueryValue, type RateLimitBucket, type RateLimitBucketContext, type RateLimitBucketOverride, type RateLimitBucketState, type RateLimitOptions, RateLimitPacing, type RateLimitScope, type RawRequestOptions, RealtimeComposer, type RealtimeContext, type RealtimeContextBase, type RealtimeEngineEvents, type RealtimeErrorBoundary, type RealtimeErrorContext, type RealtimeEvents, type RealtimeFilter, type RealtimeHandler, type RealtimeMiddleware, type RealtimeMiddlewareGroup, type RealtimeMiddlewareLike, type RealtimeMiddlewareObj, type RealtimeNext, type RealtimeNotificationContext, type RealtimeNotificationFilter, type RealtimeNotificationSelector, type RealtimeNotificationUpdate, type RealtimeOptions, type RealtimePredicate, type RealtimeRequest, type RealtimeRequestInput, type RealtimeRouteSelector, type RealtimeRouteTable, RealtimeRouter, type RealtimeSequentializer, RealtimeStatus, type RealtimeTransport, RealtimeTransportKind, type RealtimeTypeGuard, type RealtimeUnknownUpdate, type RealtimeUnreadCountUpdate, type RealtimeUpdate, type RealtimeUpdateOfType, RealtimeUpdateOrigin, RealtimeUpdateType, type ReconnectOptions, type RecordKeyValueStoreSource, type RemoveAccountOptions, type RenderSpansOptions, type RepliesParams, type Report, type ReportBuilder, type ReportInput, ReportReason, ReportTargetType, type ReportsResource, type RequestContext, type RequestExtensions, type RequestOptions, type ResetPasswordInput, type ResponseContext, type RetryContext, type RetryDecisionContext, type RetryOptions, RetrySafety, RuntimeMode, STATUS_SERVICE, type SearchResource, type SearchResult, type ServiceDefinition, ServiceState, type ServiceStatus, type Session, type SignInResult, SignInStatus, type Span, SpanRenderFormat, SpanType, type StatusDay, type StatusIncidentLine, type StreamFile, type Subscription, type SubscriptionResource, type SubscriptionState, TURNSTILE_SITE_KEY, type TelemetryBatch, type TelemetryBatchOptions, type TelemetryClock, type TelemetryOptions, type TelemetryResource, type TextMarkup, type TokenStorage, type TokenStorageAdapterOptions, type TransportContext, type TransportEvent, UnauthorizedStreamError, type Unsubscribe, type UpdateNotificationSettingsInput, type UpdatePostInput, type UpdatePrivacyInput, type UpdateProfileInput, type UploadOptions, type UploadedFile, type UrlFile, type UrlFileOptions, type UserId, type UserListParams, type UserPostsParams, type UserRef, type UserSummary, type UsersResource, VIDEO_MIME_TYPES, type VerificationResource, type VerificationStatus, type VideoMimeType, type VideoProgressInput, ViewReason, ViewSource, type ViewTracker, type ViewTrackerInput, type ViewTrackerOptions, WallAccess, type WebSocketImplementationOptions, type WebSocketLike, type WebSocketOpenFailureClassifier, WebSocketTransport, type WebSocketTransportOptions, autoSpans, canonicalNotificationType, comment, createAccounts, createClient, createKeyValueStore, createMultiTokenStorage, createRecordKeyValueStore, createTokenStorage, formatNotificationText, fromStream, fromUrl, isBuilder, isBuiltInOperationId, isEnumerableKeyValueStore, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdStateError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, operationBucket, operationMethod, operationRetrySafety, parseHtml, parseMarkdown, poll, post, renderSpans, report, resolveNotificationUrl, runRealtimeMiddleware, scopedTokenStorage, statusDays, systemClock, toDate, utcStampToIso, withCodec, withNamespace };
5600
5789
  //# sourceMappingURL=index.d.ts.map