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

@multi-indiegame/akashic-serve-extension-dock

v1.0.0

Published

akashic serve の画面で、Akashic 拡張ライブラリの操作盤を 1 か所に並べるためのドック

Readme

@multi-indiegame/akashic-serve-extension-dock

akashic serve の画面に、Akashic 拡張ライブラリの操作盤を 1 か所にまとめて 出すためのドック。

拡張ライブラリを作る人向け。コンテンツにバンドルされるものではなく、sandbox.config.jsclient.external から読ませる akashic serve 用バックエンドの中で使う

ねらい

akashic servesandbox.config.jsclient.external という拡張の口を用意しており、拡張ライブラリは自身の裁量で画面に手を入れることができる。一方で、どこに何を出すかの取り決めは特に無い。

必要なときだけ出して消える UI(akashic serve 自体が出すユーザー名提供の許可ダイアログのようなもの)なら、取り決めが無くても置き場所に迷うことはない。一方、ゲーム開発者がいつでも操作できる UI を出したい拡張ライブラリ(たとえば akashic-player-ban の「ゲーム外から操作」)の場合、画面のどこに置くか、他の拡張ライブラリと場所がぶつからないか、不要なときにどう隠すかを、ライブラリごとに一から決めることになる。

そこで、常時出す UI の置き場をドックとして用意する。各ライブラリは「タブとその中身」を用意する。画面のどこに出すか、他のライブラリとぶつからないか、開閉や on/off をどうするかはドックが引き受ける。ライブラリ間で表示場所を調整し合わなくて済み、ゲーム開発者から見ても操作盤が 1 か所にまとまる。

インストール

npm install -D @multi-indiegame/akashic-serve-extension-dock

devDependency でよい。 実行時に解決される依存ではなく、拡張ライブラリ側が esbuild などで自分の plugin.js に畳み込む前提のパッケージだから(互換性の約束)。

使い方

import {
  getDock,
  create,
  button,
} from "@multi-indiegame/akashic-serve-extension-dock";

const handle = getDock().register({
  id: "player-ban", // 並び順を決める。パッケージ名の末尾を使う
  label: "ゲーム外から操作", // 縦タブに出る
  heading: "ゲーム外から操作(実行基盤の代役)", // パネルの見出し
  build: () => buildPanelBody(), // 中身。開くたびに呼ばれる
  onClose: () => releaseNodes(), // DOM 参照を捨てる
  showTab: tabEnabled(), // false でもプログラムからは開ける
});

handle.open();
handle.toggle();

id は 1 つのページに載る他のライブラリと重複しない名前にする(例: パッケージ名)。重複したときの挙動は互換性の約束を参照。

見た目を揃えるため、パネルの中身も create()button() で組むこと。

互換性の約束

このドックを保守・拡張するときの注意点。

akashic serve はプラグインを「moduleexports しか無いスコープ」で評価する。require() が無いので、プラグインは依存を持たない 1 ファイルでなければならない。つまりこのドックは拡張ライブラリにバンドルされて配られるものであり、1 つのページにドックの実装が複数コピー載る。どの版がいくつ載るかは、そのページに載ったライブラリ群がいつビルドされたか次第で、こちらからは決められない。

そのときの動きは次の通り。

  • getDock()window.akashicServeExtensionDock を見て、先に登録されたドック実装をそのまま返す。実際に動くのは先着 1 つだけで、後から読み込まれたコピーのドック実装は使われずに捨てられる
  • 捨てられるのはドック実装だけ。後から来たコピーが呼ぶ register() は、生き残っている先着のドックに届いてパネルとして出る
  • DOCK_VERSION は見ない。register を持ってさえいれば使う

なので保守するときは次を守る。

  • 新旧どの版のドック実装が採用されても動くようにする。 v1 のドック実装が生き残ったページで最新版のライブラリが register() を呼ぶこともあれば、その逆もある
  • Dock / DockPanelSpec / DockHandle に破壊的変更を入れない。 省略可能なフィールドを足すのは安全(古いドック実装は知らないフィールドを無視するだけ)。既存フィールドの意味を変える、省略可能だったものを必須にする、名前を変える、削る、はすべて古いドック実装が生き残ったページで壊れる
  • GLOBAL_KEY を変えない。 変えると、旧キーを見るコピーと新キーを見るコピーがそれぞれドックを立て、ページ上にドックが 2 つ並ぶ
  • 同じ id の二重登録では、先に登録されたパネルの DockHandle を返す(後勝ちにしない)。 同じライブラリの別版が 2 つ載ると起きる。後勝ちにすると、そのパネルが開いている最中に中身を作った spec と閉じるときに onClose が呼ばれる spec が別物になり、画面に出ている DOM と後片付けが食い違う

URL クエリ

?akashicServeDock=0=false も可)が指定されるとドックはすべてのタブを生成しない。

ライブラリごとにタブを出し分けたい場合は、設定値を showTab に渡す。クエリの命名、値の取得処理ははライブラリ側で実装すること。

const tabEnabled = () =>
  new URLSearchParams(location.search).get("playerBan") !== "0";

getDock().register({ /* ... */, showTab: tabEnabled() });

パネル本体はライブラリ側で handle.open() を呼べば表示される。

拡張ライブラリへの組み込み方

akashic serve 用のプラグインは依存を持たない 1 ファイルでなければならないので、このドックは拡張ライブラリ側のビルドで plugin.js へ畳み込む

  1. その拡張ライブラリの devDependencies に @multi-indiegame/akashic-serve-extension-dockesbuild を足す
  2. akashic serve 用のソースを src/plugin.ts に置き、その中で getDock().register(...) を呼ぶ
  3. esbuild で src/plugin.tsplugin.js へバンドルする(format: "iife"charset: "utf8"module.exports への橋渡しは footer で)
  4. package.jsonexports".": "./plugin.js" を置き、ゲーム開発者が sandbox.config.js から require.resolve() で参照できるようにする

@multi-indiegame/akashic-player-ban-serve が上記に沿った例。参考までに。

開発

npm install
npm run build     # lib/ に .js と .d.ts を出す
npm run format

配るのはコンパイル済みの lib/ だけ。利用側の tsconfig でソースを型検査させないため、src/ は publish に含めない。

ライセンス

MIT