【Elysia/Bun】チャートライブラリccchartのElysiaプラグイン化計画(1)

最近触ってる Elysia などに触発されて、作ってから11年(厳密には16年)も経った自作のチャートライブラリ [ ccchart ](ccchart.com) が流石にいろいろ古くて、いじりたくなってきた。
[
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7103/f33a5178-93b7-2f2a-372a-a39e2bdff30f.png)
](https://ccchart.com) 

モダンな環境で例えばプラグインのように呼び出したいとか、TailwindCSS の purge のように type lineやbarなどを使うものだけを送信したいとか夢は山ほどあるのだけど、

とりあえず、昨日 Elysia のプラグインを作ったのを良い機会ということで、ccchart を　Elysiaプラグインにしてみようと思った。

今回はその作成物語です。

# 目標
<ul>
<li>ccchatのコードをElysia のプラグインとして利用する
<li>URLをブラウザへ送るのではなく SSRまたはSSGとして生成して渡す
<li>ブラウザへ送る前にminifyする
<li>(希望)毎回全コード送るのではなく棒グラフだけ使うなら棒グラフだけにパージしたい。
<li>(希望)Elysiaのコミュニティプラグインに登録してみたい
<li>もし、追加したい機能が思いつけば都度追加する
</ul>
こんなとこかな？今日はminifyまでやる。

そういえば、レジストリからダウンロードされたすべてのパッケージは、~/.bun/install/cache のグローバル キャッシュに保存されるわけだから、プラグインに登録するとできるのだろうか？今度やってみたい。npmの方だろうか？

# Elysia プラグインのドキュメント

<b>Elysia > Plugins</b>

https://elysiajs.com/essential/plugin.html

# 今回の環境
クラウド： Azure VM (これは何でも良い)
OS：　Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-1050-azure x86_64)
Bun：　v1.0.18
Elysia： v0.7.30

BunのインストールやElysia プロジェクト作成は、本家や[前回](https://qiita.com/drafts/c0ecf87f86bf50a2912b/edit) などを参考にしてみてください。

# 今回はこんなディレクトリを作ります

ざっくりいうと

<b>lib/</b> にソース(ccchart.js など)
<b>src/</b>  に起動ファイル(index.ts)とプラグイン(ccchart_plugin.ts)

を配置しています。(まぁ、プロジェクトの方針次第ですが)

src/plugins/ccchart_plugin.ts というプラグインファイルは、lib のソースからテキストコードを取り出して minify し、起動ファイル index.ts のHTTPサーバーが lissen している GET メソッドに渡します。

```
.ccchart/
├─ lib/
│    └─ ccchart.js // ccchart オリジナルファイル
├─ src/
│    ├─ ( ccchart.js // 生成されたminifyファイル )
│    ├─ index.ts  // bun dev で起動するファイル
│    └─ plugins
│          └─ ccchart_plugin.ts //プラグインファイル
│  
├─ README.md
├─ bun.lockb
├─ node_modules/
├─ package.json
└─ tsconfig.json
```

この ccchart のデータ は、別の WebSocket サーバーから受信してリアルタイム表示してるのですが、今回はプラグイン作成の話なので省略します。気になる方は、下記やQiita検索を ccchart でしてみてください。

https://qiita.com/toshirot/items/3af83303f95ac7baa546
### 結果
その結果、ブラウザにはこんな動くチャートが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7103/5c30e240-cd85-e207-bc2f-b729b759d956.png)

# 今回の動作サンプル

まぁ、今回も作ったものを pm2 start "bun dev" してあげておきます。まぁ期間限定になるとは思いますが、参考までにどうぞ。

http://74.226.208.203:9010/

# 起動ファイルの中身

起動ファイルは src/index.ts です。
 
```
├─ src/
│    ├─ ( ccchart.js // 生成されたminifyファイル )
│    ├─ index.ts  // bun dev で起動するファイル
│    └─ plugins
│          └─ ccchart_plugin.ts //プラグインファイル
```

pacage.jsonのscriptは以下のようになっていますので、「$ bun dev」で実行できます。パラメータ「--watch 」は[  ホットリロード ](https://qiita.com/toshirot/items/4c8e14c9525d9e89b55f) です。ファイルが変更された時に、自動的に再起動してくれます。

```json:pacage.jsonのscript
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "bun run --watch src/index.ts"
  },
```
cssなどは分けていないので、実際に使う時は適当に配置しましょう。
因みに、ccchartは個々のチャートのスタイルをchartDfaultOptions や config 
で設定することが多いです。
```ts: src/index.tsの中身
import { Elysia } from "elysia";
import { html } from '@elysiajs/html';
import { ccchart } from './plugins/ccchart_plugin.ts';

// メインのHTTPサーバー
const app = new Elysia()
    .use(html)
    .use(ccchart)
    //.use(chartDfaultOptions)
    .get('/', ({ ccchart }) =>{
      return `
      <style>
      #hoge0{
          display: block;
          background-color: rgb(255, 255, 255);
          border: 1px solid #ccc;
          background-color: rgba(120,120,120,0.0);
          box-shadow: 12px 12px 12px rgba(100,100,100,0.3), inset 1px 1px 1px 5px rgba(250,250,250,0.5);
          border-radius: 12px;
          margin: 10px;
      }
      </style>
      <div class="chart"><canvas id="hoge0"></canvas></div>
      <script>${ ccchart }</script>
      <script>
      
      // 共通スタイル
      const chartDfaultOptions = {
        "config": {
          "title": "",
          "subTitle": "",
          "type": "line",
          "minY": 0,
          "maxY": 100,
          "width": 560,
          "height": 300 ,
          "lineWidth": 1,
          "xScaleSkip": 5,
          "useMarker": "maru", // canvas版の丸で高速化 ツールチップが必要なら ＞cssハイブリッド版"css-maru"
          "markerWidth": 8,
          "xLines": [
                {"val":66,"color":"rgba(0,0,0,0.7)"}
              ],
          "bg": "#fff",
          "textColors": {"title":"#777","subTitle":"#777","x":"#999","y":"#999","hanrei":"#777","unit":"#777","memo":"#666"},
          "colorSet": 
                ["#DDA0DD","#3CB000"],
          "shadows": {
            "hanrei" : ['#aaa', 5, 5, 5],
            "xline": ['#555', 7, 7, 5],
            "line": ['#666', 5, 5, 5],
            "bar": ['#bbb', 5, 5, 5],
            "stacked": ['#bbb', 5, -5, 5],
            "stackedarea": ['#666', 5, 5, 5],
            "bezi": ['#666', 5, 5, 5],
            "bezi2": ['#666', 5, 5, 5]
          }
        }
      };
      
      // 共有スタイルに個々のスタイルをマージする
      const chartCfg0 = ccchart.util.cnfExtend( chartDfaultOptions, {
        // 個々のスタイル
        config: {
          title : "useRowData: 0",
          subTitle : "水平カスタム線に2件目のデータ使用",
          xLines: [
                {"useRow": 1, "color":"rgba(250,0,0,0.7)"}
              ]
        },
        // 受信したデータを入れる配列
        "data": [
          ["時間"],
          ["1件目"],
          ["2件目"]
        ]
      });
      
      // ccchart を実行する
      ccchart
        .init('hoge0', chartCfg0)
        .ws('wss://ccchart.com:8016')
        .on('message', ccchart.wscase.oneColAtATime);
              //oneColAtATimeは、WebSocketの受信パターン関数
              // 一度に1列ずつ [["2013"],[435],[600]] と
              // いった配列で届く場合用
      
      </script>

      `})  
    .listen(9010);

```

# プラグインの中身

では、プラグイン関連のコード( src/plugins/ccchart_plugin.ts )を見ていきましょう
```ts:ccchart_plugin.tsの中身
import { Elysia } from "elysia";

// ファイル名
const fileName = '/ccchart.js';
// ソースファイルのあるディレクトリ
const fromDir = './lib';
// ミニファイファイルを出力するディレクトリ
const toDir = './src';

// minify する
await Bun.build({
    entrypoints: [fromDir + fileName],
    outdir: toDir,
    minify: true, // default false
})

// plugin を作る
const ccchart_str =  Bun.file(toDir + fileName)
export const ccchart= new Elysia()
    .decorate('ccchart', await ccchart_str.text())

```

まぁ、難しいことはやってません。
Elysia のプラグイン化し、minify したソースをccchartという名前で export しているだけです。

minifyの方法については、 Bun の Build のところにいろいろな方法が載っています。

<b>Bun >　Build</b>

https://bun.sh/docs/bundler#minify



あと目標でできてないのは、分割選択送信とプラグイン登録だけど、たぶん分割はものすごく時間っがかかりそう。。できるかなぁ。

まぁ、とりま今日はここまで。



# 最近 Qiita に書いた Bun 関連の記事10選

https://qiita.com/advent-calendar/2023/bunjs

https://qiita.com/toshirot/items/c0ecf87f86bf50a2912b

https://qiita.com/toshirot/items/01c7f779d87985b1f9be

https://qiita.com/toshirot/items/2f0db79b3c2480e64f41

https://qiita.com/toshirot/items/94616478d3e73e7cc5b9

https://qiita.com/toshirot/items/f6bd561bc2522f1d26e0

https://qiita.com/toshirot/items/a5dc53ef191d20bbeb42

https://qiita.com/toshirot/items/74476af27e67d8534c5a

https://qiita.com/toshirot/items/94961b6dde72be80ab0c

https://qiita.com/toshirot/items/7a0555b46b3a64a4f643

https://qiita.com/toshirot/items/c4d090bc38f9b85d8cdd