⛓️

r-pipeline をnpmで公開してみた

に公開

経緯

ライブラリ公開してみたかったから、型安全なPipelineをライブラリとして公開してみました。

https://www.npmjs.com/package/r-pipeline

色々大変ではあって、元々あったやつ(できる限りType-Safe Pipeline — 流れる構造のデザイン

コイツを元ネタにはしたのだけど、穴があったり整理したりと色々やってたら、だいぶ違うものになってしまった。

ただ、出来上がったものは、型の推論がぐるぐると走ってくれて、処理を繋げばつなぐほど楽しくなってくる仕組みになったので自分としては満足です。

コード

コードはこちらで公開しているので、興味がある方はこちらからご覧ください。
https://github.com/risk/r-pipeline

本体

本体はこのあたりにあるので、どれが何処に繋がって何が起こってるか見ていただくと
私が頭抱えながら試行錯誤していた流れがみえるかもしれませんw
https://github.com/risk/r-pipeline/blob/main/src/pipeline/pipe.ts

本体の解説を事細かにしてもよかったのですが、なんか需要なさそうな気がしてるので、こんな感じでつかえるよ!の方を書いておこうと思います。

大雑把な使い方

https://github.com/risk/r-pipeline/blob/main/src/exsamples/standard.ts

関数を、繋いでいくことには変わらないのですが
関数の入力と出力が、次のパイプに繋がっていきます。

どういうことかというと・・・

単独のパイプ処理なら
https://github.com/risk/r-pipeline/blob/11e5390cdc8ced7b9446545b5a66966718fa20c2/src/exsamples/standard.ts#L8-L11
こんな感じになります

型を変化させながらつなぐパイプ

途中で戻り値を変えてあげれば、こんな感じで、受け取る側の型が変化していきます。
なので、パイプの中で変換処理を行えば、データを変化させていくことが出来るようになっています。
https://github.com/risk/r-pipeline/blob/11e5390cdc8ced7b9446545b5a66966718fa20c2/src/exsamples/standard.ts#L22-L34

また、変化した型は、次のPipeの引数のメソッドで、自動で推測されているので、受け渡されるものを指定しなくても勝手に推論してくれます。

ちょぴっと特殊なエラー判定

https://github.com/risk/r-pipeline/blob/11e5390cdc8ced7b9446545b5a66966718fa20c2/src/exsamples/standard.ts#L41-L49
処理自体がエラーを発生させた場合、次のPipeに「復旧するのか?」を選択できる口(recover)を用意しています。
これは、何もしなければそのままエラーで終わるのですが、次のパイプがエラーを拾っておきたかったり、前工程の値さえあれば みたいなときに、手前の工程で強制終了させると、後工程はなすすべ無しとなってしまいます。
これ自体は正しい動きではあるのですが、それでも次の人は何かしら処理したいケースがあり得ると考えており、前のエラー情報 + そのエラーが発生したときの入力を受け取ることが出来る仕組みを用意してみました。

設計としてどうなんだ?という面はあるにしろ、終わりかどうか判断するのがメソッドか?と言われると、自分的には違和感あった(パイプが続くかどうかは、Pipe全体の意思に近いと考えた)ので、この仕組みを作りました。

パイプラインのパーツ化

パイプライン同士を接続して、新しいPipelineを作り出す処理も入っとります。
https://github.com/risk/r-pipeline/blob/11e5390cdc8ced7b9446545b5a66966718fa20c2/src/exsamples/standard.ts#L51-L75
素材の使い回しができるので、いつものヤツ + 変換処理 みたいなことをやると、なかなかおもしろい使い道があるのではないかと。

最後に

ちょっとまだやってないこともあり、これ、async扱えないと使いみち無いかもとかは思っているので、これからPipeにasync仕込めるようにしようかなとか考えています。
もっと拡張はしたいものの、このコード少し触るとバランスが崩れて、大事故になるので気をつけて触ろうと思います。

追記: async つかえるようにしました
https://zenn.dev/risk/articles/ea9258ef977b4d

Discussion