npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@weavix/tracker-plugin-sdk

v0.0.6

Published

Core package for Tracker plugin SDK

Readme

@weavix/tracker-plugin-sdk

Core package for Tracker plugins (Weavix / npm). API surface matches @yandex-data-ui/tracker-plugin-sdk-core without yateamApi.

External flavor. Internal (Yandex): @yandex-data-ui/tracker-plugin-sdk-core.

Низкоуровневое API для взаимодействия с хостом и вызова Tracker Public API.

Для агентов и AI: начните с AGENTS.md и COOKBOOK.

Установка

npm install @weavix/tracker-plugin-sdk

Использование

import { hostApi, trackerApi } from '@weavix/tracker-plugin-sdk';

// Инициализация плагина (чтение параметров из URL, настройка моста)
hostApi.init({ autoResize: true });

// Получение текущей темы
const theme = await hostApi.getTheme(); // 'light' | 'light-hc' | 'dark' | 'dark-hc' | 'system' | undefined

// Получение текущего языка
const language = await hostApi.getLanguage(); // 'ru' | 'en' | undefined 

// Получение контекста слота (например, текущей задачи для слота 'issue.action')
const context = await hostApi.getContext();

// Уведомление хоста о готовности плагина
await hostApi.notifyReady();

// Обновление высоты контейнера плагина
await hostApi.updateContentSize({ height: 500 });

Tracker API

Все вызовы Tracker Public API выполняются через trackerApi.v3 — типизированный прокси над HTTP-методами. Ключи — пути эндпоинтов из OpenAPI (@weavix/tracker-api-types); IDE предоставляет автодополнение и JSDoc.

Подробное описание методов и форматов ответов: Tracker API Reference.

import { trackerApi } from '@weavix/tracker-plugin-sdk';

// GET — возвращает { data, headers }
const { data: issue } = await trackerApi.v3.get['/issues/{id}']({
  pathParams: { id: 'QUEUE-123' },
  queryParams: { expand: ['COMMENTS'] },
});

// POST
await trackerApi.v3.post['/v2/issues']({
  bodyParams: { queue: { key: 'TASK' }, summary: 'Новая задача' },
});

// PATCH
await trackerApi.v3.patch['/v2/issues/{id}']({
  pathParams: { id: 'QUEUE-123' },
  bodyParams: { summary: 'Обновлённое название' },
});

// DELETE
await trackerApi.v3.delete['/v2/issues/{id}']({
  pathParams: { id: 'QUEUE-123' },
});

Очереди

// Получение списка очередей
const { data: queues } = await trackerApi.v3.get['/v2/queues']({
  queryParams: { page: 1, perPage: 100 },
});

// Получение конкретной очереди
const { data: queue } = await trackerApi.v3.get['/v2/queues/{id}']({
  pathParams: { id: 'MYQUEUE' },
});

Задачи

// Получение задачи по ключу
const { data: issue } = await trackerApi.v3.get['/issues/{id}']({
  pathParams: { id: 'QUEUE-123' },
});

// Создание задачи
const { data: newIssue } = await trackerApi.v3.post['/v2/issues']({
  bodyParams: {
    queue: { key: 'QUEUE' },
    summary: 'Название задачи',
  },
});

// Поиск задач
const { data: issues } = await trackerApi.v3.post['/v2/issues/_search']({
  bodyParams: { filter: { queue: 'QUEUE' } },
});

Тосты (Toast notifications)

Плагины могут показывать toast-уведомления в хост-приложении через uiApi.toaster. API максимально приближен к gravity-ui useToaster.

Permission: Требуется "toaster" в permissions.ui манифеста плагина (хост преобразует в scope tracker:ui:toaster).

import { uiApi } from '@weavix/tracker-plugin-sdk';

// Простой тост
uiApi.toaster.add({
  title: 'Сохранено',
  theme: 'success',
});

// Тост с текстовым содержимым и кастомным временем показа
uiApi.toaster.add({
  title: 'Ошибка',
  theme: 'danger',
  content: 'Не удалось загрузить данные',
  autoHiding: 10000,
});

// Тост с кнопкой действия
uiApi.toaster.add({
  title: 'Элемент удалён',
  theme: 'info',
  content: 'QUEUE-123',
  actions: [
    {
      label: 'Отменить',
      onClick: () => {
        // обработка нажатия
      },
    },
  ],
});

uiApi.toaster.add(options)

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | title | string | — | Заголовок тоста (обязательный) | | name | string | auto | Уникальный ключ для дедупликации. Генерируется автоматически, если не передан | | theme | 'success' \| 'danger' \| 'warning' \| 'info' | 'info' | Тема (цвет и иконка) | | content | string | — | Текстовое содержимое под заголовком | | autoHiding | number | 5000 | Время показа в мс (от 1000 до 30000) | | isClosable | boolean | true | Показывать кнопку закрытия | | actions | ToastAction[] | — | Кнопки действий (макс. 2) |

ToastAction:

| Поле | Тип | Описание | |------|-----|----------| | label | string | Текст кнопки (макс. 50 символов) | | onClick | () => void | Callback при нажатии |

Возвращает: Promise<{ name: string }> — имя тоста (для идентификации).

Ограничения:

  • title — макс. 200 символов
  • content — макс. 500 символов
  • actions — макс. 2 кнопки
  • Rate limit — 5 тостов за 10 секунд на плагин

Навигация в хосте

Плагин может открыть путь в хост-приложении или внешний URL через uiApi.navigate:

import { uiApi } from '@weavix/tracker-plugin-sdk';

await uiApi.navigate({
  path: '/queues/MYQUEUE',
  params: { tab: 'settings' },
  options: { newTab: true },
});

| Поле | Тип | Описание | |------|-----|----------| | path | string | Путь или URL (обязательный) | | params | Record<string, string \| number \| boolean \| null \| undefined \| (string \| number \| boolean \| null \| undefined)[]> | Query-параметры | | options.newTab | boolean | Открыть в новой вкладке |

TrackerPluginProvider (react) перехватывает клики по внешним ссылкам в iframe и вызывает uiApi.navigate.

Storage API

storageApi — JSON-хранилище уровня организации, опосредованное хостом. Запись общая на всю организацию: её видят все пользователи плагина, право на запись определяет хост (отдаёт его в поле canWrite каждой прочитанной записи).

На сегодня доступен единственный контекст — storageApi.orgShared.

import { storageApi } from '@weavix/tracker-plugin-sdk';

// Чтение
const record = await storageApi.orgShared.get('settings');
// record: { data: { theme: 'dark' }, version: 5, canWrite: true, ... } | null

// Создание новой записи (на пустом бакете)
await storageApi.orgShared.patch({
    bucket: 'settings',
    data: { theme: 'dark', notifications: true },
    version: 0,
});

// Обновление без знания текущей версии — SDK сам вычитает её и поретраит конфликты
await storageApi.orgShared.patch({
    bucket: 'settings',
    data: { count: 42 },
});

// Удаление отдельного поля — передайте `null`
await storageApi.orgShared.patch({
    bucket: 'settings',
    data: { theme: null },
});

storageApi.orgShared.get(bucket?)

Возвращает Promise<StorageRecord | null> — текущую запись или null, если её ещё нет.

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | bucket | string \| undefined | хост подставляет 'default' | Ключ записи внутри контекста |

storageApi.orgShared.patch(options)

Merge-patch: поля из data накладываются на текущую запись поверх, значение null удаляет ключ. Возвращает полный смерженный StorageRecord с новой версией (включая поля, дописанные параллельными писателями).

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | bucket | string | хост подставляет 'default' | Ключ записи | | data | Record<string, unknown> | — | Merge-doc; null удаляет поле | | version | number \| undefined | auto-resolve | Ожидаемая текущая версия |

Версионирование.

  • С явным version — отправляется один запрос. Любая ошибка, включая VERSION_CONFLICT, пробрасывается вызывающему. Используйте, если приложение само держит актуальную версию и должно реагировать на конфликт (например, показать пользователю «данные изменились, перечитайте»). Для создания записи на пустом бакете передавайте version: 0.
  • Без version — SDK сначала читает текущую версию через get (для пустого бакета берётся 0), затем выполняет patch. На VERSION_CONFLICT цикл повторяется до двух раз, каждый ретрай заново читает версию. Любая другая ошибка пробрасывается мгновенно. В худшем случае — 6 round-trip-ов (3 пары GET + PATCH); на каждом ретрае в консоль пишется console.warn.

Ошибки

Все ошибки storage-методов — экземпляры PluginActionError с числовыми кодами:

| Код | Константа | Когда | |-----|-----------|-------| | 1010 | VERSION_CONFLICT | Переданный version не совпал с текущим | | 1011 | DATA_TOO_LARGE | Размер записи после операции превысил 256 KiB | | 1012 | BAD_KEY | bucket не прошёл валидацию формата или длины |

import { PluginActionError, VERSION_CONFLICT, storageApi } from '@weavix/tracker-plugin-sdk';

try {
    await storageApi.orgShared.patch({ bucket: 'settings', data: { x: 1 }, version: 0 });
} catch (e) {
    if (e instanceof PluginActionError && e.code === VERSION_CONFLICT) {
        // показать пользователю, что версия устарела
    }
}

Типы

import type {
    StorageContextType,  // 'orgShared' (расширяемое в будущем)
    StorageRecord,       // { key, version, data, canWrite, createdAt, updatedAt }
    StorageGetPayload,   // wire-payload для storage.get
    StoragePatchPayload, // wire-payload для storage.patch
} from '@weavix/tracker-plugin-sdk';

Вызов внешних API

Методы hostApi для работы с внешними API через прокси хоста: проверка и запрос учётных данных пользователя по доменам из манифеста и выполнение HTTP-запросов от имени плагина.

Домены и схемы авторизации задаются в манифесте плагина в permissions.external.

import { hostApi } from '@weavix/tracker-plugin-sdk';

// Проверить, указал ли пользователь авторизационные данные для доменов, и при необходимости запросить их через диалог
const { success } = await hostApi.externalApiAuthCheckAndRequest({
    domains: ['api.example.com'],
});
if (!success) {
    // пользователь отменил диалог или истёк таймаут ожидания
    return;
}

// Прокси-вызов внешнего API (учётные данные подставляет хост)
const { status, body } = await hostApi.externalApiCall({
    url: 'https://api.example.com/v1/items',
    method: 'GET',
});

Типичный сценарий: externalApiAuthCheckAndRequest (или пара externalApiAuthGetStatus + externalApiAuthRequest) → externalApiCall. Отзыв сохранённых данных — externalApiAuthRevoke.

hostApi.externalApiAuthGetStatus(payload)

Возвращает статус учётных данных пользователя по доменам.

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | domains | string[] \| undefined | все домены плагина | Список доменов для проверки | | contextType | 'user' \| 'organization' \| undefined | — | Тип контекста учётных данных (в контракте payload) |

Возвращает: Promise<{ domains: ExternalApiAuthGetStatusDomain[] }>.

Если domains не передан или пуст, хост запрашивает статус по всем доменам плагина.

hostApi.externalApiAuthRequest(payload)

Показывает пользователю диалог ввода учётных данных для указанных доменов. При успешном подтверждении хост сохраняет credentials.

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | domains | ExternalApiDomainInfo[] | — | Домены (обязательно, минимум один) |

ExternalApiDomainInfo:

| Поле | Тип | Описание | |------|-----|----------| | domain | string | Домен из манифеста | | instructions | string \| { en?: string; ru?: string } | Подсказка в диалоге (опционально) |

Возвращает: Promise<{ success: boolean }>. success: false — пользователь закрыл диалог или не завершил авторизацию. Ожидание ответа пользователя ограничено по времени (около 5 минут).

hostApi.externalApiAuthRevoke(payload)

Отзывает сохранённую аутентификацию для указанных доменов.

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | domains | string[] | — | Домены для отзыва (обязательно, минимум один) | | contextType | 'user' \| 'organization' \| undefined | — | Тип контекста учётных данных (в контракте payload) |

Возвращает: Promise<{ success: boolean }>. success: true, если отзыв прошёл для всех переданных доменов.

hostApi.externalApiAuthCheckAndRequest(payload)

Комбинирует проверку статуса и запрос credentials только для неаутентифицированных доменов. Payload совпадает с externalApiAuthGetStatus.

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | domains | string[] \| undefined | все домены плагина | Домены для проверки | | contextType | 'user' \| 'organization' \| undefined | — | Тип контекста (в контракте payload) |

Возвращает: Promise<{ success: boolean }>. Если все домены уже аутентифицированы — сразу { success: true } без диалога. Иначе показывается тот же диалог, что и у externalApiAuthRequest; при успехе credentials сохраняются.

hostApi.externalApiCall(payload)

Выполняет HTTP-запрос к внешнему API через прокси платформы. URL должен относиться к домену, разрешённому в permissions.external; заголовки авторизации подставляет хост.

| Параметр | Тип | По умолчанию | Описание | |----------|-----|--------------|----------| | url | string | — | Полный URL запроса (обязательный) | | method | 'GET' \| 'POST' \| 'PUT' \| 'PATCH' \| 'DELETE' | — | HTTP-метод (обязательный) | | headers | Record<string, string> | — | Дополнительные заголовки | | body | Record<string, unknown> | — | Тело запроса (для методов с телом) | | timeoutMs | number | — | Таймаут запроса в миллисекундах | | contextType | 'user' \| 'organization' \| undefined | — | Контекст учётных данных для прокси |

Возвращает: Promise<{ status: number; headers?: Record<string, string>; body?: Record<string, unknown> }>.

При ошибке прокси-запроса (ответ платформы с status, code, message) метод бросает PluginActionError с кодом EXTERNAL_API_CALL_ERROR (1013); детали — в errorData (status, message, code, title).

Ошибки

| Код | Константа | Когда | |-----|-----------|-------| | 1013 | EXTERNAL_API_CALL_ERROR | Прокси-вызов externalApiCall завершился ошибкой |

import {
    EXTERNAL_API_CALL_ERROR,
    PluginActionError,
    hostApi,
} from '@weavix/tracker-plugin-sdk';

try {
    await hostApi.externalApiCall({ url: 'https://api.example.com/x', method: 'GET' });
} catch (e) {
    if (e instanceof PluginActionError && e.code === EXTERNAL_API_CALL_ERROR) {
        console.log(e.errorData);
    }
}

Типы

import type {
    AuthContextType,
    ExternalApiAuthGetStatusPayload,
    ExternalApiAuthGetStatusResult,
    ExternalApiAuthGetStatusDomain,
    ExternalApiAuthRequestPayload,
    ExternalApiAuthRequestResult,
    ExternalApiAuthRevokePayload,
    ExternalApiAuthRevokeResult,
    ExternalApiAuthCheckAndRequestPayload,
    ExternalApiAuthCheckAndRequestResult,
    ExternalApiCallPayload,
    ExternalApiCallResult,
    ExternalApiDomainInfo,
    PluginProxyMethod,
} from '@weavix/tracker-plugin-sdk';

Обработка ошибок

import { trackerApi, PluginActionError } from '@weavix/tracker-plugin-sdk';

try {
  await trackerApi.v3.get['/issues/{id}']({ pathParams: { id: 'BAD' } });
} catch (e) {
  if (e instanceof PluginActionError) {
    console.log(e.code, e.message, e.errorData);
  }
}

API

hostApi

  • init(options?) — инициализация плагина (чтение параметров из URL, настройка моста). Вызывать один раз перед использованием остальных методов.
  • getTheme() — текущая тема ('light' | 'light-hc' | 'dark' | 'dark-hc' | 'system')
  • getLanguage() — текущий код языка ('ru', 'en' и др.)
  • getContext() — контекст слота (тип зависит от слота, см. SlotContextMap)
  • getSlot() — имя текущего слота (вызывать после init())
  • updateContentSize(request) — обновление высоты контейнера плагина
  • notifyReady() — уведомление хоста о готовности плагина
  • disableAutoResize() — отключение автоматического изменения размера
  • externalApiAuthGetStatus(payload) — статус аутентификации по доменам
  • externalApiAuthRequest(payload) — диалог запроса учётных данных
  • externalApiAuthRevoke(payload) — отзыв аутентификации
  • externalApiAuthCheckAndRequest(payload) — проверка и запрос credentials для неаутентифицированных доменов
  • externalApiCall(payload) — прокси HTTP к внешнему API

uiApi

UI-методы хоста (навигация, тосты, confirm и др.).

  • uiApi.navigate(request) — навигация в хост-приложении. Подробности — выше.
  • uiApi.toaster.add(options) — показать toast-уведомление в хост-приложении. Подробности — выше.
  • uiApi.confirm.show(options) — диалог подтверждения (permission confirm в манифесте).

trackerApi.v3

Типизированный прокси над эндпоинтами Tracker Public API v3:

  • trackerApi.v3.get[path](payload) — GET-запрос; payload: pathParams, опционально queryParams
  • trackerApi.v3.post[path](payload) — POST-запрос; payload: bodyParams, опционально pathParams, queryParams
  • trackerApi.v3.put[path](payload) — PUT-запрос
  • trackerApi.v3.patch[path](payload) — PATCH-запрос
  • trackerApi.v3.delete[path](payload) — DELETE-запрос; payload: pathParams, опционально queryParams

Все методы возвращают Promise<{ data, headers }>, где data типизирован согласно ответу эндпоинта.

Типы

  • SlotContextMap, контексты слотов, LocalizedString и связанные типы (Issue в контексте слота, Attachment и т.д.) — из @weavix/tracker-core, реэкспортируются из этого пакета.
  • Типы запросов и ответов HTTP эндпоинтов Tracker Public API (trackerApi.v3) — из @weavix/tracker-api-types.
import type {
  Theme,
  ApiCallResult,
  ApiCallPayload,
  TrackerApiCallOptions,
  ContentSizeUpdateRequest,
  SlotContextMap,
} from '@weavix/tracker-plugin-sdk';

React-интеграция

Для React-приложений используйте @weavix/tracker-plugin-sdk-reactTrackerPluginProvider, useTrackerPluginContext, useLocalizedString.

Полная документация

📖 AGENTS.md — краткий вход для агентов.

📖 COOKBOOK — типовые сценарии.

📖 API Reference — hostApi, trackerApi.v3, типы, ошибки.

Лицензия

UNLICENSED