xstate
XState v5 のステートマシンおよびステートチャートを TypeScript でモダンな v5 パターンを用いて設計・実装・レビュー・移行します。XState、アクター、ステートマシン、ステートチャート、ガード、トランジション、ワークフロー、Stately に関する言及や、XState を使用するコードベースで複雑な UI・アプリ・プロセスのロジックをモデル化する際に活用してください。要件が曖昧な場合はコードの前に簡潔なマシンのスケッチを提示し、ステートマシンが不要なほど問題がシンプルな場合は代わりに `@xstate/store` を提案します。
description の原文を見る
Design, implement, review, and migrate XState v5 state machines and statecharts in TypeScript using modern v5 patterns. Use this whenever the user mentions XState, actors, state machines, statecharts, guards, transitions, workflows, or Stately, or is modeling non-trivial UI/app/process logic in a codebase that uses XState. Prefer a short machine sketch before code when requirements are fuzzy. If the problem is too simple for a state machine, say so and recommend @xstate/store instead.
SKILL.md 本文
XState v5
このスキルはステートマシンとステートチャート設計を最優先に、次に API の正確性を重視します。
このスキルは v5 のみ対応です。例、ブログ記事、回答、またはローカルコードが v4 っぽい場合は、バージョンを混ぜずに翻訳してください。ローカルリポジトリのコードと公式 v5 ドキュメントを一般的な知識よりも優先します。
あなたの仕事:
xstateと@xstate/storeの使い分け- 曖昧な要件から健全なマシンまたはアクターシステムを設計する
- モダン XState v5 TypeScript コードを一貫したスタイルで書く
- 既存の XState コードをレビュー、修復、改善する
- レガシー v4 っぽいパターンをマイグレーションする
- 問題が単なる
assign(...)とfromPromise(...)ではない場合、適切なアクタータイプとアクション形を選択する @xstate/react、@xstate/vue、@xstate/svelte、または@xstate/solidにマシンとアクターを接続する
First pass
既存のコードベースでは:
- ローカルの
package.jsonファイルとインポートを検査する - 周辺のマシン、ストア、アクター、アダプター使用状況を読む
- コード作成方法の意見度を選択する前に、新規コード、ローカル編集、マイグレーション作業を区別する
- デフォルトでは周辺のスタイルを保持する
Task mode
コード作成前にモードを選択する:
- 新規コード: このスキルのモダン v5 パターンを優先します
- ローカル編集: 現在のコードが混在、破損、またはクリーンアップが要求されている場合を除き、ローカル構造と命名を保持する
- マイグレーション: 最小限で安全な v5 への翻訳を優先します。より広範な正規化が要求されていない限り、構造とセマンティクスを保持する
マイグレーションとローカル編集では、正確性のために必要、ローカルの複雑さを大幅に削減、または明確に要求されていない限り、setup(...)、名前付き実装、オブジェクト形式の guard/action、タグ、またはアクター分解を導入しないでください。
ツール選択
以下の場合、@xstate/store を優先する:
- 調整、オーケストレーション、または明示的なライフサイクルモデリングが必要な意味のある有限モード がない
- invoked async プロセスがない
- アクター通信がない
- ガード付き遷移、遅延遷移、並列状態、またはヒストリーなどのステートマシンまたはステートチャート概念が不要
単純なフェッチまたは mutation ロジックでも、マシンレベルのオーケストレーションが不要であれば、@xstate/store に適合できます。
以下のいずれかを持つドメインの場合、XState を優先する:
- 動作または UI にとって重要な有限モード
- async ワークフロー、リトライ、キャンセル、またはバックグラウンドプロセス
- 複数の相互作用するプロセスまたはチャイルドアクター
- 明示的な guard、遅延、タグ、または遷移ルール
- 単なる状態更新ではなく、ビジネスプロセスフローをモデル化する必要
問題がマシンには単純すぎる場合、明確に述べ、@xstate/store を推奨してください。
Workflow
要件が曖昧な場合:
- マシン形を最初にスケッチします
- 重要な状態、イベント、コンテキスト、アクター、タグに名前を付ける
- 不確実性またはトレードオフを簡潔に明記する
- その後、コードを書く
要件がすでに明確な場合、スケッチを短くするか暗黙的に保ち、コードに進みます。
概念的な純粋性のために既存のコードを過度にリファクタリングしないでください。モデルが重要な場所では改善しますが、より大きなリライトが正当化されない場合は、動作中の構造を保持します。
モデリングの質問
コード作成または修正前に以下の質問を使用してください:
- 有限状態は何ですか? モードをコンテキストではなく状態に置く
- コンテキストに何が属しますか? 耐久データのみを保持し、導出可能なブール値または重複するモード ではない
- ドメインイベントは何ですか? 意味のある名前 (例:
form.submittedまたはorder.confirmedのようにドット区切り) を優先する - guard と別の分岐状態のどちらにすべきですか?
- どの副作用が invoked アクターと遷移 action にすべきですか?
- イベントが必要なデータを持つのではなく、後の状態で使用するために一時的なリレー データをコンテキストに格納すべきですか?
fromPromise(...)は実際に正しいアクターですか、それとも時間をかけてイベントを送り返すコールバック/サブスクリプションプロトコルですか?- マシンはコンシューマーにコンテキストからすべてを推論させるのではなく、周囲のシステムにイベントを発行すべきですか?
- チャイルド関心は、より多くの親複雑さの代わりに、spawned/invoked アクターであるべきですか?
- 親は本当にこれらの余分な中間状態が必要ですか、それともチャイルドアクターがその内部詳細を所有すべきですか?
- どの状態に
'loading'、'error'、'dirty'などの UI セマンティクス用タグが必要ですか? - UI は
snapshot.matches(...)、タグ、またはsnapshot.can(...)を余分なブール値の代わりに使用できますか?
推奨される v5 パターン
新規コードでは、ローカルコードベースに強い理由がない限り、以下のパターンを優先する:
- TypeScript のみ
setup({...}).createMachine({...})を優先するsetup(...)で名前付きactions、guards、actors、delaysを定義する- 一貫性を改善する場合、ショートハンドよりも
{ target: 'next' }のような遷移オブジェクトを優先する - 形を一貫性のある状態に保つ場合、単一のアクションでも
actionsに配列を使用する - 意図が再利用可能または名前付きの場合、
{ type: 'track' }または{ type: 'isValid', params: ... }などのアクションおよび guard オブジェクトを優先する - UI セマンティクスおよびクロスカッティング状態の意味のために
tags: []を優先する - ドメイン指向イベント名を優先; すでに確立されている場合はローカル命名規則を保持する
- コンテキストに導出データを格納する代わりに、導出値にはプレーン関数を優先する
- 1 つの状態が次のステップにのみデータを渡す必要がある場合、一時的なコンテキストリレーよりもイベントペイロードを優先する
- イベントに直接到達する代わりに、
params経由で名前付き action と guard にデータを渡す assign(...)を唯一のアクションパターンとして扱わないでください。単純なコンテキスト更新を超える型付き再利用可能なロジックの場合、const machineSetup = setup(...)オブジェクトからの setup スコープヘルパー (machineSetup.createAction(...)、machineSetup.enqueueActions(...)、machineSetup.emit(...)) または動作がより適切に適合する場合は名前付き action オブジェクトを検討する- 名前付き
assign(...)action が複数のコンテキストプロパティを更新する場合、すべてのプロパティアップデーターは同じparams型を共有する。すべての更新フィールドに対して 1 つの一貫した params オブジェクトを使用するか、作業を別の名前付き action に分割する。1 つの assigner 内で互換性のない params シェイプを混ぜないでください - 実装が
eventを検査する必要があり、型が明らかでない場合、絞り込みのためにassertEvent(...)を優先する - 例とファイナルコードで
as anyおよび他の緩いキャストを避ける (よりクリーンなローカルオプションがない場合を除く) - アクターロジックを意図的に選択する: 1 つのリクエスト/1 つの結果には
fromPromise(...)を優先し、サブスクリプション、タイマー、外部コールバック、および時間をかけてイベントを送り返すマルチイベントプロトコルにはfromCallback(...)を優先する - マシンが周囲のシステムに直接通知すべき場合は
emit(...)を検討する - 可能な限り親状態を粗く保つ。余分な中間状態が主に実装詳細をモデル化する場合、チャイルドアクターがその内部動作を所有することを優先する
- 複数のファイルを表示する場合は、完全に配線する。参照されるモジュールとコンポーネントの実際のインポート/エクスポート を含める、または例をより小さく保つ
イベント命名を一貫性のある状態に保つ。イベント名の . は有用で意味があり、部分的なイベント記述子とより明確なドメイングループを含める。公式ドキュメント events and transitions および TypeScript narrowing with assertEvent(...) を参照してください。
正規のコード形については references/examples.md を、型付きアクション (assign(...) を超える)、コールバックアクター、emitted イベント、または永続化/ハイドレーション を含むタスクについては references/advanced-patterns.md を、fromObservable(...)、検査、ブラウザインスペクターパターンについては references/observables-and-inspection.md を参照してください。
UI integration
マシンに UI 動作を駆動させることを優先する:
- 有限モードチェックには
snapshot.matches(...)を使用する - loading、saving、dirty などのセマンティクスチェックにはタグを使用する
- イベントが現在有効かどうかを駆動するには
snapshot.can(...)を使用する - マシン真実を再度述べる手動ブール値の平行スタックを避ける
コンポーネントが小さなローカルアクターを所有する場合、useMachine(...) は多くの場合十分です。
アクターが共有、長寿命、またはパフォーマンス制約がある場合:
- アクター ref を一度作成または取得する
useSelector(...)でスライスを読む- アクターがサブツリー全体で共有される場合は、アクターコンテキスト/プロバイダーヘルパーを使用する
簡潔なアダプターガイダンスについては references/adapters.md を、React フックの選択、input 配線、ネストされた状態マッチング、カスタムフック パターンについては references/react.md を参照してください。
レビューと修復ガイダンス
XState コードをレビューまたは修正する場合、以下を探す:
- コンテキストではなく状態に格納された有限モード
- チャイルドアクターに分割すべき巨大なマシン
- ランダムなコールバックに隠された副作用または assigner に混ぜられたもの
- 同じマシンに混在された v4 と v5 概念
- UI メカニクスではなくドメイン意味を説明する状態と イベント名
matches(...)、タグ、またはセレクターで置き換えるべき余分なブール値- 問題が単純な場合、
@xstate/store使用の機会を見落とし - プロパティアップデーターが暗黙的に異なる
paramsシェイプを期待する名前付きassign(...)action
分解をあまりに進めない。アクター境界は、明確性、所有権、またはコンカレンシーを改善する場合に有用です。それ自体のために分割しないでください。
マイグレーション
レガシーコードが存在する場合、ユーザーがより広いマイグレーションを要求していない限り、段階的かつローカル的に v5 に向かって翻訳する。
一般的なマイグレーションターゲットは以下を含む:
cond->guardschema->typesservices->actorsinterpret(...)->createActor(...)- 古い関数シグネチャ ->
({ context, event })などの非構造化 v5 引数
マイグレーションタスクの場合:
- ローカル構造を最優先
- 正確性、互換性、または明確さのために必要なもののみ変更する
- ユーザーがそれを要求していない限り、完全な推奨ハウススタイルに正規化しないでください
- 選択する非ローカルリファクター を説明する
- ちょうど周辺に存在したからといって、デッド または無効なフック option パターンを保持しないでください
- React 使用をマイグレーションする場合、古い
interpretスタイル実装上書きをuseMachine(...)に密輸しようとするのではなく、有効な現在のフック サーフェスを優先する
クイック翻訳パターンについては references/v4-to-v5-quick-ref.md を使用してください。
Persistence
永続化またはハイドレーションが重要な場合:
- コンテキストのみの復元が本当に十分でない限り、コンテキストのみではなくスナップショットを永続化する
- マシン状態を保存するには
actor.getPersistedSnapshot()を優先する createActor(machine, { snapshot })またはアダプター/プロバイダースナップショット option でハイドレーションを優先する (利用可能な場合)- 状態値の推測とコンテキスト blob の部分的なハイドレーション を手作業で復元しない
具体的な永続化とハイドレーション パターンについては references/advanced-patterns.md を参照してください。
Testing
ユーザーがテストについて質問したり、テストをリクエストしたりしない限り、テストガイダンスを導入しないでください。
テストについて質問がある場合は、簡潔に保つ:
- 主要な遷移と guard をテストする
- happy path と失敗 path のアクター動作をテストする
- 状態フル ロジックを複製する代わりに、マシン状態に対して UI をテストする
- 有用な場合はモデルベーステスト ユーティリティに言及する
リンクが役立つ場合は、XState testing と graph/path generation ドキュメントをポイントしてください。
オプションツール
Stately Studio とインスペクションツールは設計、デバッグ、通信に役立つ場合がありますが、オプションです。ユーザーがマシンを設計している場合、ビジュアライゼーションが必要な場合、またはより良いデバッグ可視性が必要な場合に言及してください。
- Stately Studio ビジュアルモデリングとコラボレーション用
- Inspection API アクターシステム観察用
- Stately Inspector 実行中アプリでのビジュアルインスペクション用
出力形式
この出力形を優先する:
- 要件が曖昧な場合は短いマシンスケッチ
- コード
- 状態、イベント、コンテキスト、アクター、タグを説明する簡潔な根拠
- マイグレーション注記 (関連する場合のみ)
より多くの完全ファイルよりも、より大きくても部分的に配線された例を優先する。完全に配線されていない限り、余分なシェルファイルをスケッチしないでください。
時間をかけて成長できるより正規のコード例については references/examples.md を参照してください。
最終セルフチェック
回答する前に、コンパイル認識パスを実行する:
- 別のファイルの JSX コンポーネントはすべて実際のインポートを持つ
- インポートされたすべてのシンボルは、実際に表示されたファイルによってエクスポートされている
- すべての
send(...)とsnapshot.can(...)呼び出しは実際のイベントオブジェクトを使用している - async 作業はレガシー形ではなく、
actors/fromPromiseとinvoke.inputを使用している - プロンプトまたは周囲のシステムから外部ヘルパーを参照する場合、署名を宣言するか、例が独立して立つために十分な型付き形を表示する
- マイグレーション例は、デッドローカルコードを保持するためだけに、無効な実装上書きオブジェクトをフックに渡さない
- コード フェンス内に、実行可能であることが意図されていない、プレースホルダーシェルファイル、省略されたインポート、
...、またはpseudocode がない
完全なマルチファイル答えが嵩張って いる場合、シェルファイルを削除し、パターンを正確に示す実行ファイルセットを保つ。
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- seed-hypermedia
- リポジトリ
- seed-hypermedia/seed
- ライセンス
- Apache-2.0
- 最終更新
- 不明
Source: https://github.com/seed-hypermedia/seed / ライセンス: Apache-2.0
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。