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

madoi-client

v0.3.0

Published

A Client library of Madoi Server for Distributed Sharing

Readme

madoi-client-ts-js

A TypeScript/JavaScript Client library for Distributed Information Sharing Platform: Madoi.

分散情報共有基盤MadoiのTypeScript/JavaScript用クライアントライブラリ。

Reactと組み合わせて使う場合は madoi-react も参照してください。

Current Release Licence

Install

npm i madoi-client

Getting started

Prepare HTML

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf8" />
</head>
<body>
<div>
  <button id="counter1" type="button">count is 0</button>
  <button id="counter2" type="button">count is 0</button>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

Sharing a function execution (Madoi.registerFunction)

関数の実行をウェブアプリケーション間で共有する例を以下に示します。

import { Madoi } from 'madoi-client'

window.addEventListener("load", ()=>{
  const madoi = new Madoi("wss://host/madoi-server/rooms/room001", "MADOI_API_KEY");

  const element1 = document.querySelector('#counter1')!;
  let counter1 = 0;
  const incrementCounter = madoi.registerFunction(() => {
    counter1++;
    element1.innerHTML = `count is ${counter1}`
  });
  element1.addEventListener('click', () => incrementCount());  // incrementCounter is executed at all applications joined to same room.
});

MadoiクラスのregisterFunctionメソッドに関数を渡すと、新たな関数を返します。 返された関数を実行すると、Madoiサーバに関数の登録番号と引数が送信され、自身も含め同じルームに参加しているアプリケーション全てにそれが送信され、それを受信すると、registerFunctionに渡された関数が実行されます。このように、registerFunctionを使うと、簡単に関数の実行を共有できます。複数のアプリケーションで同時に実行された場合でも、サーバから各アプリケーションへは同じ順番でメッセージが届くので、アプリケーション間での振る舞いを統一できます。

ここで、新しいアプリケーションが参加してきた時の状態共有を考えてみます。上記の例では、incrementCounter関数でcounterを+1しているため、最新時の状態に追いつくには、それまでの全ての実行を再現する必要があります。そのためMadoiは、関数の実行履歴を全て保存しており、新しくアプリケーションが参加するとその履歴を渡しています。しかし実行回数が増えてくると、このやり方は非効率です。この問題を解決する方法を次に紹介します。

Sharing a model (Madoi.register)

まず、同期したい状態と、その状態を変更・取得・設定するメソッドを持つクラスを作成します。

class Counter{
  private element: HTMLElement
  private count = 0; // 同期したい状態
  constructor(element: HTMLElement){
    this.element = element;
  }
  // 状態を変更するメソッド
  @Share()
  increment(){
    this.count++;
    this.element.innerHTML = `count is ${this.count}`;
  }
  // 状態を取得するメソッド
  @GetState()
  getCount(){
    return this.count;
  }
  // 状態を変更するメソッド
  @SetState()
  setCount(count: number){
    this.count = count;
    this.element.innerHTML = `count is ${this.count}`;
  }
}

Counterクラスは、状態の変更を行うincrement、状態を取得するgetCount、状態を設定するsetCountメソッドを持つシンプルなクラスです。状態を取得するメソッドには@GetState()デコレータを、状態を設定するメソッドには@SetState()デコレータを、状態を変更するメソッドには、@Share()デコレータを付けます。Madoiクライアントは、状態共有を行うために、これらのメソッドを適切に呼び出します。

次に、Counterクラスのインスタンスを作成し、Madoiクライアントに登録します。

import { Madoi } from 'madoi-client'

window.addEventListener("load", ()=>{
  const madoi = new Madoi("wss://host/madoi-server/rooms/room001", "MADOI_API_KEY");

  const element2 = document.querySelector<HTMLDivElement>('#counter2')!;
  let counter2 = new Counter(element2);
  madoi.register(counter2);
  element2.addEventListener('click', () => counter2.increment());  // counter2.increment() is executed at all applications joining same room.
});

Madoiクライアントにオブジェクトを登録すると、デコレータがつけられたメソッドを介して、状態が管理されます。この例では、incrementメソッドが実行されると、同じMadoiサーバのルームに参加している他のアプリケーションのincrementメソッドも実行されます。また、定期的にgetCountメソッドが呼び出され、状態が取得され、Madoiサーバに送信されます。新しくアプリケーションが参加してくると、最新の状態と、それ以降のメソッド実行履歴が送信され、アプリケーション内で状態の設定(setCount)とメソッドの実行が行われ、最新の状態に追いつきます。

このように、Madoiクライアントを利用すると、コラボレーションツールなどの実装に必要な状態同期を、クライアントアプリケーション側の宣言的な記述のみで(サーバ実装やクライアントのネットワーク関連処理、状態管理処理無しで)実現できます。