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

@okrug/test-1

v0.0.4-1

Published

Data exchange via the JSON-RPC 2.0 protocol using a message port (postMessage, MessageChannel, MessagePort)

Readme

This is an experimental package; do not use it!

Обмен данными iframe с родительским окном

  • Обмен данными с родительских окном производится посредством обмена сообщениями по протоколу JSON-RPC 2.0
  • Транспортом для обмена является MessageChannel.
  • MessagePort для такого обмена получается путём отправки/обработки запроса getMessagePort через postMessage родительского окна (window.parent).

Данный клиент реализует базовое взаимодействие и может быть не всегда удобен с учётом использования вашего набора библиотек. Вы можете реализовать свои функции оборачивающие ответ в удобный для вас формат или технологию (promise/rxjs/singals и т.п.). Примеры таких хэлперов для async/await есть ниже в разделе с примерами.

Функции клиента JsonRpcClient

  • getMessagePort: получение порта для осуществления обмена данными.
    Одновременно с портом можно запросить данные необходимые для первичной инициализации. Сам вызов функции возвращает объект с функцией dispose() для возможности отписаться от вызова коллбэка. Аргумент коллбэка аналогичен аргументу коллбэка функции call.
  • call: вызов одного метода сервера.
    Результат обрабатывается в коллбэке. Сам вызов функции возвращает объект содержащий функцию dispose() для возможности отписаться от обработки ответа и вызова коллбэка. В единственный аргумент коллбэка передаются три объекта:
    • response - объект с ответом формата JSON-RPC
    • request - оригинальный запрос формата JSON-RPC переданный при вызове (поле jsonrpc: "2.0" заполняется автоматически при отправке запроса, поэтому может отсутствовать в оригинальном запросе если вы его не передавали.)
    • disposable - объект содержащий функцию dispose() для возможности отмены обработки ответа и вызова коллбэка.
      Это ровно тот же объект который возращается и самой функцией call (а также batch/watch/getMessagePort).
      Данный объект не очень полезен при выполнении одноразовых запросов, но может быть полезен для записи в него любых необходимых вас данных при использовании функции watch
  • batch: вызов нескольких методов сервера.
    Результат обрабатывается в коллбэке. Сам вызов функции возвращает объект с методом dispose() для возможности отписаться от вызова коллбэка. Аргумент коллбэка аналогичен аргументу коллбэка функции call.
  • watch: запрос периодических уведомлений об изменении указанных данных на сервере.
    Возможность наблюдения за изменяемыми значениями не является частью стандарта JSON-RPC, но форматы запросов/ответов соответстуют стандарту.
    Сам вызов функции возвращает объект с функцией dispose() для возможности прекратить наблюдение за изменениями и отписаться от вызова коллбэка. Аргумент коллбэка аналогичен аргументу коллбэка функции call.
    Объект disposable передаваемый в аргументе может использоваться для хранения необходимой вам информации между вызовами поскольку ссылка на него не меняется на время подписки. При использовании его в этом качестве будьте осторожны, чтобы не затереть функцию dispose() которую он содержит для отмены обработки ответа.
  • getUnuqId: генерация уникального строкового идентификтора для запроса.
    Используется простейшая логика создания уникального строкового идентификатора. Можно использовать любой другой генератор уникальных строковых или целочисленных значений.
  • isReady: готовность клиента к обмену данными с сервером (проверяется наличие MessagePort)
  • getResponseError: проверка ответа на предмет ошибки.
    Результатом будет объект ошибки формата JSON-RPC или null. Эта функция не очень полезна при вызове запросов с помощью call или watch поскольку результатом ответа всегда будет объект, а результат ответа легко проверить наличием поля error в ответе.
    В случае c batch результатом ответа может быть как массив так и объект с ошибкой. В этом случае можно проверить ошибку с помощью данной функции. Функция не проверяет наличие вложенных ошибок в массиве ответов.

Примеры использования

Все методы сервера в примера явлюятся вымышленными, у вас будет другой набор реальных метода вашего сервера

Инициализация/запрос порта

const client = createJsonRpcClient();

function init(data) {
  console.log("init", data);
}

client.getMessagePort(
  { 
    id: client.getUniqId(),
    params: ["host.themeMode", "host.language", "user.id"],
  },
  ({ response }) => {
    if (!response.error) {
      return init(response.result)
    }

    console.log("error", response.error)    
  }
);

Вызов одного метода сервера

client.сall(
  {
    method: "user.id",
    id: client.getUniqId(),
  },
  ({ response }) => {
    if (response.error) {
      console.log("error", response.error);

      return;
    }

    console.log("success", response.result);
  },
);

Вызов нескольких методов сервера (batch)

client.batch([
    { method: "user.id", id: client.getUniqId() },
    { method: "host.themeMode", id: client.getUniqId() },
  ])
  .then({ response }) => {
    const error = client.getResponseError(response)
    
    if (error) {
      return console.log("error", error);
    }

    console.log("success", response.result);
  },
);

Наблюдение за изменениями значений

При первом событии будет возращён объект содержащий полный набор запрошенных данных. В последующем будут объект будет только объект с данными по которым произошло изменение (формат и логика ответов Вашего сервера может быть иной).

client.watch(
  {
    method: "changes",
    id: client.getUniqId(),
    params: ["host.themeMode", "host.language"],
  },
  ({ response, disposable }) => {
    if (response.error) {  
      disposable.dispose();
      console.log("error", response.error);

      return;
    }
    
    disposable.count = 'count' in disposable ? disposable.count++ : 0;    

    console.log("success", disposable.count, response.result);
  },
);

Остановка наблюдения за изменениями значений

const disposable = client.watch(
  {
    method: "changes",
    id: client.getUniqId(),
    params: ["host.themeMode"],
  },
  (data) => console.log("data", data),
);

setTimeout(() => {
  disposable.dispose();
}, 5000);