Releases: KiowDev/itd-api
Release list
v0.7.0
Rate limiting
-
Маршруты итд.com разбиты на бакеты — группы маршрутов со своим счётчиком запросов в минуту. Раньше клиент считал лимит один на весь сайт, и исчерпанная квота на публикацию постов тормозила заодно чтение ленты. Теперь у каждого бакета своя очередь и своя пауза, а общее число одновременных запросов по-прежнему задаёт
concurrency. -
Новая опция
pacingрешает, что делать с остатком квоты.react(по умолчанию) ждёт, только когда остаток кончился,smoothзаранее держит ровный темп,offотключает подстройку. Опция заменилаrespectHeaders. -
Лимиты отдельных бакетов можно поправить через
bucketOverrides, аitd.request()— направить в нужный бакет опциейrateLimitBucket. -
itd.rateLimitState()показывает остаток квоты по каждому бакету — сколько запросов ещё можно отправить и сколько ждёт в очереди. -
Несколько аккаунтов по умолчанию встают в одну очередь: лимиты считаются по IP, а не по аккаунту. Прежнее поведение возвращает
rateLimitScope: 'account'.
Несовместимые изменения
rateLimit.respectHeadersудалён: прежнееtrue— этоpacing: 'react', прежнееfalse—pacing: 'off'.- Умолчание
rateLimitScopeизменено с'account'на'shared'.
Таблица бакетов и настройки — в новом разделе справочника «Ограничения частоты».
Full Changelog: v0.6.0...v0.7.0
v0.6.0
Предсказуемое освобождение клиента, единый сетевой путь и ограниченные очереди
Жизненный цикл клиента
dispose()отменяет незавершённые запросы. Runtime владеет одним сигналом времени жизни, и транспорт объединяет его с сигналом запроса: послеawait itd.dispose()внутри клиента не остаётся ни активных сетевых операций, ни таймеров переподключения. Отменённый запрос получаетItdAbortErrorс
причиной отмены.- Ожидание чужого кода ограничено новой опцией
shutdownTimeout(по умолчанию 10 000 мс). Срок общий на обработчики realtime-потока и на операции, вошедшие в обёртки плагинов. По его истечении ресурсы всё равно освобождаются, включаяteardownплагина, а метод отклоняетсяItdStateErrorс именем
плагина или транспорта потока.shutdownTimeout: 0возвращает ожидание без срока. - Порядок терминальной очистки закреплён: потоки, накопленная телеметрия, отмена запросов, teardown плагинов.
- Поток, исчерпавший попытки переподключения, покидает клиент так же, как после
disconnect():close()иdispose()его больше не касаются, а повторныйconnect()возвращает поток клиенту.
Плагины
next()у operation transformer стал одноразовым. Повторный вызов завершает операциюItdConfigErrorс именем плагина — так же, как это уже работало у attempt interceptor. Раньше плагин мог породить вторую логическую операцию, а дляposts.createэто вторая публикация.
Realtime
- Опрос уведомлений идёт через общий конвейер клиента. В каталог добавлены операции
realtime.poll.updatesиrealtime.poll.unread: опрос занимает слот очереди, виден плагинам и хукам, обновляет токен при401вместо разрыва потока и отменяется вместе с ним. Из транспорта ушли собственное получение
токена, заголовокAuthorization, распознавание401и снятие обёртки{ data: … }. TransportContextполучил необязательный портrequestк конвейеру клиента. SSE по-прежнему работает черезfetch: у соединения другой жизненный цикл.- Очередь обновлений ограничена. Счётчик непрочитанного коалесцируется — ожидающее значение заменяется новым, и обработчик получает последнее; уведомления не коалесцируются. При переполнении поток закрывает соединение, дожидается разбора очереди и переподключается с обычной синхронизацией.
Хранилища
- Запись в record-хранилище стала транзакционной. Изменение видно чтениям только после подтверждения источником: неудачная запись не расходится с backend и больше не отравляет
get()иkeys()собственной ошибкой. Черновик строится внутри очереди записей, поэтому параллельные записи разных ключей не
теряют друг друга. - Нечитаемый ключ больше не ломает перечисление аккаунтов.
accounts()пропускает запись, ключ которой не декодируется, с предупреждением — вместоURIErrorна весь список и пустого результатаrestore().
Full Changelog: v0.5.0...v0.6.0
v0.5.0
Новая модель плагинов, каталог операций и переработанный конвейер запросов
Конвейер запросов
- Очередь применяется к каждой сетевой попытке, а не ко всему логическому запросу: ожидание повтора больше не занимает слот конкурентности, а ограничитель частоты считает реальные обращения к серверу.
- Локальный результат не проходит очередь: ответ из кэша, мок или короткое замыкание плагина возвращаются сразу и не расходуют RPS.
- Очередь выбирается по итоговому
URL.origin, уже после разрешенияserviceи разовогоbaseUrl. Два имени одного хоста делят лимитер, разные хосты изолированы. - Авторизация разделена на три стадии: восстановление после
401вокруг попытки, подготовка токена до очереди и подстановка свежих заголовков непосредственно перед отправкой. - Служебные
auth.signInиauth.refreshпроходят общий конвейер вместе с плагинами и очередью; отдельный урезанный auth-конвейер удалён. - Номер попытки считает фактические входы в транспорт: повтор после обновления токена получает следующий номер, а
auth.refreshведёт собственный счёт. - Порядок стадий и их частота закреплены contract-тестами и описаны в новом справочнике «Request pipeline».
Каталог операций
- Каждый метод SDK получил стабильный
operationId—posts.create,users.me,auth.refreshи так далее. Идентификатор не меняется при переносе HTTP-пути. - Публичный
OPERATIONSхранит HTTP-метод и семантику повтора каждой встроенной операции; доступныoperationMethod(),operationRetrySafety()иisBuiltInOperationId(). - Плагины распознают операции по идентификатору, а не по регулярным выражениям над URL: перенос эндпоинта больше не ломает правила расширений молча.
- Низкоуровневый
itd.request()по умолчанию выполняется как операцияraw; для собственных вызовов доступно пространствоcustom:*.
Плагины
- Два явных уровня расширения.
operations.use()вызывается один раз на логическую операцию и работает с разобранным результатом,attempts.use()оборачивает каждую сетевую попытку и видит итоговый URL, заголовки и сыройResponse. ClientPluginзаменилItdPlugin:install(api)регистрирует преобразователи и перехватчики, а teardown дожидается запросов, уже вошедших в обёртку плагина.- Перехватчик попытки не может незаметно породить вторую отправку: повторный вызов
next()запрещён, короткое замыкание возможно только явным возвратомResponse. - Настройки плагинов передаются через
extensions.<namespace>— регистрация ключей во время выполнения больше не нужна.
Повторы
- Повтор опирается на семантику операции, а не на HTTP-метод.
RetrySafetyразличаетsafe,idempotentиunsafe: читающийPOSTвродеposts.statsповторяется, аposts.create— нет. - Небезопасная операция повторяется автоматически только после ответа, который гарантирует, что запрос не был обработан.
- Отдельно проверяется возможность заново собрать тело: одноразовый поток не делает операцию повторяемой.
- Обычные повторы и лестница пауз после
429считаются раздельно, поэтому последовательность500 → 429начинает лестницу с первой ступени. - Точечное переопределение доступно через
RequestOptions.retrySafety, аshouldRetryполучаетRetryDecisionContextс семантикой операции.
Параметры запросов
- Параметры эндпоинта и настройки выполнения разделены:
itd.posts.list({ limit }, { signal, retry }). - Для итераторов добавлен
PaginationOptions:maxPagesуправляет перебором и не попадает в запрос к эндпоинту. - Настройки загрузки файлов и телеметрии вынесены в собственные аргументы.
Realtime
- Новый транспорт
WebSocketTransportдля сред с WebSocket: путь/api/ws, собственная реализация сокета, заголовки апгрейда и распознавание отказа по недействительному токену. Подключается явно черезtransport; выборautoпо-прежнему использует поток событий или опрос. RealtimeComposerсобирает feature-модуль без доступа к живому потоку:use(),filter()с type guard,route()поверхRealtimeRouterиerrorBoundary()для защищённой ветки обработчиков.- Движок потока отделён от публичного объекта: переподключение, снимки цепочек и конкурентность живут в собственном слое.
Хранилища
- Общий backend
KeyValueStoreпод памятью, файлом,localStorageиsessionStorage.TokenStorageиMultiTokenStorageостались доменными фасадами поверх него. - Добавлены декораторы
withNamespace()иwithCodec(), фабрикиcreateKeyValueStore()иcreateRecordKeyValueStore(). - В
itd-api/webпоявилисьSessionStorageTokenStorage,LocalStorageKeyValueStoreиSessionStorageKeyValueStore. - Файловый backend использует версионированный конверт, а повреждённый JSON больше не выглядит как пустое хранилище: и файл, и Web Storage сообщают об ошибке явно, вместо молчаливого выхода пользователя из сессии.
MultiTokenStorageвыводит список аккаунтов из ключей и не хранит отдельный индекс.
Жизненный цикл клиента
dispose()стал терминальным: после него новые запросы,use(),defineService(),realtime()и повторныйconnect()завершаютсяItdStateError. Повторный вызов возвращает тот же результат очистки,await usingвызывает именно его.close()остаётся перезапускаемой остановкой: закрывает потоки, отправляет накопители телеметрии и гасит очередь.- Накопленная телеметрия отправляется и при
dispose()— до teardown плагинов и не открывая доступ новым пользовательским вызовам. ItdAccountsполучил такой же терминальныйdispose(): контейнер отзывает storage-срезы и подписки.
Пакеты
@itd-api/cache: правила задаются полемoperationsвместоroutes, каталог доступен какCACHE_OPERATIONS. Кэш и граф инвалидации опираются наoperationId, поэтому совпадение URL уitd.request()больше не включает кэш случайно.@itd-api/testing: добавленcreateMockOperations()— подмена логической операции поoperationIdс последовательностями ответов, историей вызовов, passthrough и проверкой неиспользованных сценариев.createMockFetch()остаётся для проверки HTTP-деталей, повторов и ошибок транспорта.@itd-api/crypto: набор шифруемых полей сопоставляется сoperationId, собственное распознавание маршрутов удалено.@itd-api/hydrate: переведён на новые контракты расширения.
Технические улучшения
- Сборка клиента вынесена во внутреннюю фабрику runtime: конфигурация, транспорт, авторизация, очереди и единственный конвейер собираются в одном месте, а
ItdClientостаётся фасадом. - Ресурсы клиента создаются лениво, при первом обращении.
- Пользовательское определение сервиса накладывается на встроенное:
authи заголовки наследуются, пока ключ не задан явно. - Каталоги операций и мутаций заморожены целиком, включая вложенные описания.
- Добавлен справочник «Request pipeline» с инвариантами конвейера и таблицей точек расширения.
Несовместимые изменения
ItdPlugin,PluginContextиTransformerзаменены наClientPlugin,PluginApi,OperationTransformerиAttemptInterceptor; плоскиеuse()иuseHooks()внутри плагина удалены.- Смешанные параметры и настройки запроса разделены во всех методах ресурсов;
optionKeysиREQUEST_OPTION_KEYSудалены вместе с извлечением полей в базовом ресурсе. retryWritesи внутренний повтор сетевых записей удалены — их заменяетRetrySafety.createRecordMultiStorage()заменён наcreateRecordKeyValueStore().dispose()больше не оставляет клиент пригодным для запросов.cache({ routes })иCACHE_ROUTESпереименованы вcache({ operations })иCACHE_OPERATIONSбез переходных псевдонимов.- Совместимые перегрузки намеренно не добавлялись: 0.5.0 меняет публичные контракты один раз, вместо того чтобы надолго оставить два протокола.
Совместимость
@itd-api/cache@0.1.0,@itd-api/crypto@0.1.0,@itd-api/hydrate@0.1.0и@itd-api/testing@0.1.0требуютitd-api@>=0.5.0 <1.0.0.@itd-api/proxyи@itd-api/turnstileне зависят от контракта ядра и не менялись.
Full Changelog: v0.4.0...v0.5.0
v0.4.0
Новый пакет @itd-api/hydrate, улучшенная типизация и внутренняя декомпозиция SDK
@itd-api/hydrate
- Новый пакет
@itd-api/hydrateдобавляет типизированные методы действий непосредственно к моделям постов, комментариев, пользователей, вложений и уведомлений. - Посты получают методы
get(),like(),unlike(),comment(),repost(),remove(),restore(),pin()иunpin(). - Комментарии поддерживают реакции, ответы, изменение, удаление, восстановление и загрузку ответов через
getReplies(). - Авторы, профили и участники уведомлений получают методы работы с подписками, блокировкой и постами пользователя.
- Вложенные модели, страницы,
Paginator,collect(), асинхронный перебор и результаты действий гидратируются автоматически. - Гидратация поддерживается в realtime-контекстах, middleware и обработчиках уведомлений.
- Методы моделей не перечисляются через
Object.keys()и не попадают в JSON. - Пакет совместим с авторизацией, настройками запросов и подключёнными плагинами, включая
@itd-api/cache.
Типизация
- Добавлен публичный тип
CreatePostDataдля нормализованного результатаPostBuilder.build()иresolvePost(). - Входной
CreatePostInputпо-прежнему принимает обычный объект,PollBuilderили функцию настройки опроса. RealtimeRouterтеперь поддерживает собственный тип контекста, что позволяет безопасно использовать его с гидратированными realtime-обновлениями.- Существующие публичные exports основного пакета сохранены.
Технические улучшения
- Модели разделены по доменам: пользователи, контент, уведомления, аккаунты, платформа и статусы.
- Контракты плагинов отделены от registry, порядка установки и выполнения hooks.
- Система вложений разделена на публичные контракты, фабрики, ограничения, настройки и потоковую обработку.
- Mock server из
@itd-api/testingразделён на состояние, seed-данные, сущности и маршруты. - Удалены внутренние фасады, которые больше не требовались для совместимости.
Full Changelog: v0.3.0...v0.4.0
v0.3.0
Новая система обработки realtime и пакет для тестирования.
Realtime
- Промежуточные обработчики обновлений через
stream.use(). Обработчик может преобразовать обновление, выполнить действия до и после следующего обработчика либо остановить его дальнейшую передачу. - Типизированные подписки и фильтры через
onUpdate()иonNotification(). Уведомления можно отбирать по типу, участнику, сущности, родительской сущности и дополнительному условию. - Маршрутизация обновлений через
RealtimeRouter: отдельные цепочки обработчиков для разных типов событий и общий обработчик для остальных обновлений. - Управляемая конкурентность:
concurrencyзадаёт число одновременно обрабатываемых обновлений, аsequentialize()сохраняет порядок для связанных событий. - Единый контекст обновления с нормализованными данными, источником и исходным транспортным кадром.
- Универсальное событие
messageдля низкоуровневого наблюдения за всеми кадрами realtime-транспорта. - Добавлены
drain(), события ошибок обработчиков и предсказуемые снимки цепочек и маршрутов на момент получения обновления.
Тестирование
- Новый пакет
@itd-api/testingдля проверки клиентов, плагинов и прикладных сценариев без настоящего API. createMockFetch()позволяет задавать последовательности ответов, сетевые ошибки, задержки, незавершающиеся запросы и собственные маршруты.createMockServer()предоставляет API-сервер в памяти с общим состоянием пользователей, записей, комментариев, реакций, подписок и уведомлений.- Операции клиентов изменяют состояние сервера: созданные записи и комментарии можно получить, изменить, удалить и восстановить.
- Добавлены готовые заготовки данных, управляемые часы, тестовый realtime-транспорт и ответы Server-Sent Events.
- Поддерживается проверка плагинов, повторных запросов,
raw-ответов и сетевых перехватчиков клиента.
Технические улучшения
- Добавлен интерфейс
ItdClockдля управления тайм-аутами, повторами, ограничением
частоты запросов и переподключением realtime. Retry-Afterв формате HTTP-даты учитывает часы клиента.- Обновлены руководства и справочник realtime.
- Добавлена отдельная документация по
@itd-api/testing.
Совместимость
- Существующие REST-методы и событийные подписки realtime сохраняются.
@itd-api/testing@0.0.1требуетitd-api@^0.3.0.- Требуется Node.js 18 или новее.
Full Changelog: v0.2.0...v0.3.0
v0.2.0
Переработана система аттачей, переустроена архитектура, добавлены методы разметки.
Возможности
- Переработанная система аттачей с новой архитектурой: единая система загрузки
файлов для комментариев, постов и профилей. Улучшенная обработка ошибок, лучшая
типизация, поддержка multipart запросов. Автоматическое определение MIME-типов и
валидация размеров. - Методы работы с текстовой разметкой: новый парсер
parseMarkup()для анализа
форматированного текста, поддержка меншенов, хэштегов, ссылок. Расширенный
telemetryAPI с методами отправки спанов и трассировки. - Утилиты для профиля пользователя:
uploadBanner()иdeleteBanner()для работы
с баннерами,getAppVersions()для получения версий установленных приложений. - Улучшенная обработка хранилища: переделана система работы с сессиями, лучшая
интеграция со Storage API браузера и Node.js файловой системой.
Документация
- Новый сайт документации на GitHub Pages с полным API reference, примерами и гайдами.
- Обновлены все руководства
- Добавлены примеры использования для всех новых методов.
- Расширена документация по конфигурации и работе с ошибками.
Технические улучшения
- Миграция с
tsupнаtsdownдля лучшей производительности сборки и использования более современной библиотеки - Отдельные entry points для
webсреды с оптимизацией для браузеров. - Матрица покрытия кода и улучшенные CI/CD workflows.
Full Changelog: v0.1.0...v0.2.0
v0.1.0
Первая версия библиотеки: ядро, разделы REST/realtime, мульти-аккаунты и экосистема
плагинов собраны в согласованный публичный контракт.
Возможности
- Полный клиент REST + realtime для итд.com: посты, комментарии, пользователи,
подписки, хэштеги, поиск, уведомления, файлы, отчёты, верификация, платформа. - Авторизация «сама»: продление токена по 401, повтор исходного запроса,
единый refresh для параллельных вызовов, событиеauthError. Вход по токену,
паре токенов или email+пароль с Turnstile. - Несколько аккаунтов через
ItdAccounts/FileMultiTokenStorage: именованные
клиенты с раздельными токенами, cookie, deviceId и прокси, общая или раздельные
очереди запросов,restore()без повторной капчи. - Единая пагинация: курсор, страницы и смещение спрятаны за одним
for await
(iterate()/.pages()). - Уведомления из REST и потока приведены к одной форме.
- Система плагинов и официальные дополнения:
@itd-api/crypto,@itd-api/cache,@itd-api/proxy,@itd-api/turnstile. - Билдер разметки и билдер создания постов (
(p) => p.content(...).attach(...)). - Ноль зависимостей у пакета; ESM + CommonJS; полные
.d.tsс описаниями на русском;
Node 18+, браузер, Bun, Deno, React Native. Точка входаitd-api/node— загрузка
файлов по пути и файловое хранилище сессий.
Совместимость
- Публичный API совместим с 0.0.x.
- Требуется Node ≥ 18.
Full Changelog: v0.0.11...v0.1.0