ホームページ >ウェブフロントエンド >jsチュートリアル >PeerSplit を構築した方法: 無料のピアツーピア経費分割アプリ - アイデアから立ち上げまでわずか数週間で完了
私は、Splitwise に代わる無料のピアツーピア代替手段である PeerSplit を、アイデアから立ち上げまでわずか 2 週間で構築しました。
PeerSplit は、グループ費用を分割するためのローカルファーストのアプリです。オフラインで動作し、完全に無料かつプライベートであり、サインアップや個人データは必要ありません。
これが私がそれを構築した方法と、その過程で学んだすべてのことです。
私は友人やルームメイトとの出費管理に長年 Splitwise を利用してきました。しかし、最近の 1 日のトランザクション制限と煩わしい広告のせいで、使用するのがイライラしてきました。
サーバーにデータを保存したり同期したりする必要がない、プライバシーを最優先した無料の代替手段が必要でした。サードパーティのサーバーに経費を預けるつもりはありません。
ワークアウトトラッカーや気を散らさないライティングアプリなど、ピアツーピアでローカルファーストのプロジェクトに取り組んだ後、同じアプローチを経費分割に適用できることに気付きました。
こうして PeerSplit が誕生しました。アプリのデザインを始めました。
私は UI のデザインが苦手です。
数か月前までは、PeerSplit ほど洗練された UI を構築できるとは思っていませんでした (Splitwise よりも UX が優れているという人もいます)。
では、どうやってそれを行うことができたのでしょうか? Nuxt UI。
Nuxt UI は素晴らしく、素晴らしい開発者エクスペリエンス (DX) を備えています。
@nuxt/icon、@nuxtjs/tailwindcss、@nuxtjs/colormode などの他の便利な Nuxt モジュールも付属しています。
私がしなければならなかったのは原色を選択することだけで、PeerSplit の UI を統合するために必要なコンポーネント (アイコン、ダーク モード、その他すべて) がすべて揃っていました。
ローカル データ ストレージと同期には、wa-sqlite 上に構築され、CRDT (競合のない複製されたデータ型) を使用する cr-sqlite を使用しました。
CRDT は競合を自動的に処理するため、ピアツーピア システムに最適です。そのため、ユーザーはオフラインで作業でき、再接続すると変更がシームレスにマージされます。
ただし、cr-sqlite 自体はネットワーク経由で変更を同期しません。変更をエクスポートおよびマージするための API のみを提供します。これらの変更はデバイス間で手動で送信する必要があります。
安全なピアツーピア同期を処理するために、ピアツーピアの分散グラフ データベースを提供する Gun.js を使用しました。
Gun の Gun.user API を使用すると、グループごとに暗号化されたノードを作成できます。グループのすべての変更はそのノードに保存され、グループ メンバーとのみ同期され、すべてがプライベートに保たれます。
ユーザーがアクションを実行すると、cr-sqlite からエクスポートされた変更を取得してノードにプッシュします。ユーザーがオンラインに戻ると、Gun は新しい変更を同期し、全員を最新の状態に保ちます。
これをパフォーマンスの高い方法で実装するのは困難でした。詳細については、ここでソース コードをチェックアウトできます。
Splitwise (そして現在は PeerSplit) の優れた機能の 1 つは、「借金の簡素化」です。
仕組みは次のとおりです。A が B に借金をしており、B が C に借金がある場合、A は C に直接支払うだけで、返済回数が減る可能性があります。
PeerSplit では、まず各人の純残高を計算します。次に、それらの残高を分類し、毎回少なくとも 1 人の残高がゼロになるように 1 つずつ支払いを提案します。
この並べ替えにより、全員のデバイスに同じ返済額が表示されるようになります。
これは 100% 最適というわけではありません (グループによっては最大 n-1 回の支払いがある場合もあります) が、ほとんどの場合はうまく機能します。
最適なソリューションは計算が指数関数的であり、ほんの数回の支払いしか節約できません。つまり、これがシンプルさとスピードの最良のトレードオフでした!
export const groupGetPayments = (group) => { const payments = []; const balances = Object.entries(groupGetBalances(group)).map(([a, b]) => [ b, a, ]); balances.sort(); let i = 0, j = balances.length - 1; while (i < j) { if (balances[i][0] === 0) { i++; } else if (balances[j][0] === 0) { j--; } else if (-balances[i][0] > balances[j][0]) { payments.push({ from: balances[i][1], to: balances[j][1], value: round(balances[j][0]), }); balances[i][0] += balances[j][0]; balances[j][0] = 0; } else { payments.push({ from: balances[i][1], to: balances[j][1], value: round(-balances[i][0]), }); balances[j][0] += balances[i][0]; balances[i][0] = 0; } } return payments; };
PeerSplit をオフライン アプリとして機能させたいと考えていましたが、複数のネイティブ アプリケーションを構築したり、アプリ ストアに公開するという長いプロセスに対処したりする手間はかけたくありませんでした。したがって、Progressive Web App (PWA) を選択するのは明らかな選択でした。
PWA は Web アプリとモバイル アプリの長所を組み合わせたもので、ユーザーはオフライン機能を利用しながらデバイスに PWA をインストールできます。
Nuxt アプリを PWA に変換するには、vite-pwa を使用しました。
私は Figma で SVG ロゴをデザインし、それを使用して vite-pwa のアセット ジェネレーターを通じて必要なすべての PWA アセットを生成しました。
その後、PWA マニフェストを構成すると、vite-pwa が Service Worker を自動的にセットアップしました。
アプリがオフラインでも完全に機能できるように、すべてのルートを事前レンダリングするように Nuxt を構成しました。
これで終わりです。読んでいただきありがとうございます!
PeerSplit が Product Hunt でリリースされました!初めての立ち上げなので、サポートとフィードバックをお待ちしています。
Product Hunt で PeerSplit をチェックしてください
PeerSplit は公正なソースであるため、GitHub で自由に貢献したり、機能リクエストを送信したりできます。
PeerSplit は、グループ費用を簡単かつ非公開で分割および追跡できる無料のローカルファーストのピアツーピア アプリです。
以上がPeerSplit を構築した方法: 無料のピアツーピア経費分割アプリ - アイデアから立ち上げまでわずか数週間で完了の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。