索引
SynStateはアプリケーションの状態を管理するためのシンプルで直感的なAPIを提供します:
createState:InitializedObservableとsetterで状態を作成。createReducer: reducerと初期値で状態を作成。createBooleanState: 真偽値に特化した状態管理。
イベントシステム
Section titled “イベントシステム”イベント駆動パターンのための組み込みイベントエミッター:
createValueEmitter: 型安全なイベントエミッターを作成。createEventEmitter: ペイロードなしのイベントエミッターを作成。
Observable API
Section titled “Observable API”複雑なシナリオに対応するため、SynStateはObservableベースのAPIを提供します:
source<T>(): 新しいObservableソースを作成(RxJSのsubjectとほぼ同等)。just(value): 単一の静的な値を保持し即座に完了するObservableを作成。switchMap内の同期フォールバックとして有用。empty(): 値を持たず即座に完了しているObservableを作成(RxJS のEMPTYとほぼ同等)。switchMapで何も追わない分岐に有用。fromPromise(promise): PromiseからObservableを作成。fromAbortablePromise(factory):AbortSignalを受け取る Promise のファクトリから Observable を作成。Observable が complete すると(switchMapが切り替えたときなど)abort される。fromSubscribable(): 任意のsubscribableオブジェクトからObservableを作成。counter(ms): すぐに 0 を発行し、その後一定間隔で 1, 2, … を発行(RxJSのtimer(0, ms)とほぼ同等。{ emitInitial: false }を渡すとinterval(ms)とほぼ同等。{ times: n }を渡すとn回発行した直後に complete)。timer(delay): 遅延後に発行。
combine(observables): 複数のソースから最新の値を結合(別名:combineLatest)。derive(observables, fn): 複数のソースの最新値から 1 つの値を、1 つの Observable として派生。merge(observables): 複数のストリームをマージ。zip(observables): インデックスごとに値をペアリング。
map(fn): 値を変換。mapTo(value): すべての値を定数にマッピング。getKey(key): オブジェクトからプロパティ値を抽出(別名:pluck)。attachIndex(): 各値にインデックスを付与(別名:withIndex)。
Result/Optional
Section titled “Result/Optional”mapOptional(fn): Optional値に対してmapを適用。mapResultOk(fn): Resultのok値に対してmapを適用。mapResultErr(fn): Resultのerror値に対してmapを適用。unwrapOptional(): Optional値をundefinedにアンラップ。unwrapResultOk(): Resultのok値をundefinedにアンラップ。unwrapResultErr(): Resultのerror値をundefinedにアンラップ。
Flat map
Section titled “Flat map”mergeMap(fn): Observableにマッピングしてすべてをマージ(並列実行)(別名:flatMap)。switchMap(fn): Observableにマッピングして最新に切り替え(前のものをキャンセル)。
フィルタリング
Section titled “フィルタリング”filter(predicate): 値をフィルタリング。skipIfNoChange(): 重複する値をスキップ(別名:distinctUntilChanged)。skip(n): 最初のn回の発行をスキップ。take(n): 最初のn回の発行を取得して完了。skipWhile(predicate): 述語がtrueの間、値をスキップ。takeWhile(predicate): 述語がtrueの間、値を発行し、その後完了。skipUntil(notifier): notifierが発行するまで値をスキップ。takeUntil(notifier): notifierの発行で完了。
audit(ms): 指定した時間ウィンドウ後に最後の値を発行(RxJSのauditTimeとほぼ同等)。debounce(ms): 発行をデバウンス(RxJSのdebounceTimeとほぼ同等)。throttle(ms): 発行をスロットル(RxJSのthrottleTimeとほぼ同等)。
pairwise(): 前回と今回の値をペアとして発行。scan(reducer, seed): 値を蓄積。withBuffered(observable): Observableからの値をバッファリングし、親とともに発行(別名:withBufferedFrom)。withCurrentValueFrom(observable): 別のObservableから現在の値をサンプリング(別名:withLatestFrom)。withInitialValue(value): 未初期化のObservableに初期値を提供。keepEqualParts(options?): 前の値と等しい部分を前の値のもので置き換え、全体が等しい値は流さない(構造共有)。自分で書き込む状態にはcreateStateのkeepEqualPartsオプションを優先。
スコープ(ライブラリ作成者向け)
Section titled “スコープ(ライブラリ作成者向け)”ページの一部をマウント・破棄する UI 束縛のような、SynState の上に載るライブラリのための API。モジュールのトップレベルで定義したアプリの状態はどのスコープにも属さず、これを使う必要はない。
createScope(parent?, { after? }): スコープを作る。scope.run(body)の中で同期的に作られた Observable はそのスコープに属し、scope.dispose()は派生元の共有された Observable を complete せずにそれらを dispose する。そこで行ったsubscribeもそのスコープに属し、dispose()で購読が解除される。parentを渡すと親と一緒に dispose される。afterを渡すと、そのスコープと子スコープの中で派生した Observable は、ソースから何段目であってもafterより後に更新される。分岐をそのスコープにマウントする切り替えが、切り替えの元になる値を渡すと、次の値で外れる分岐を、分岐がその値を計算する前に破棄できる。getCurrentScope():runを実行中のスコープ(無ければundefined)。スコープに入るのは同期的に作られたものだけなので、awaitの後の処理は同期部分で取っておいたスコープのrunで包む。onScopeDispose(cleanup): 現在のスコープが dispose されるときにcleanupを呼ぶ。untracked(body): 現在のスコープ無しでbodyを呼び、その中で作られたものと購読を、囲むスコープより長く生かす。
dispose() は購読、子スコープ、onScopeDispose の関数、所有する Observable の順に、それぞれ新しいものから破棄する。そのため、スコープの中で行った購読は、onScopeDispose の関数が書いた値も、スコープやその子が dispose する Observable の complete も受け取らない。更新の伝搬と complete の通知は、どのスコープが値を書いたか、complete したかによらずスコープ無しで行われるので、それを受けて subscriber が行った購読や作った Observable は、subscriber 自身がスコープを run しない限りどのスコープにも属さない。dispose 済みのスコープで run すると warning を出し、その中で作られたものはどのスコープにも属さない。
ユーティリティ
Section titled “ユーティリティ”isChildObservable(obs): ObservableがChild Observableかどうかを判定。isManagerObservable(obs): ObservableがManager Observableかどうかを判定。isRootObservable(obs): ObservableがRoot Observableかどうかを判定。
フレームワーク連携
Section titled “フレームワーク連携”React / Preact Hooks (synstate-react-hooks / synstate-preact-hooks)
Section titled “React / Preact Hooks (synstate-react-hooks / synstate-preact-hooks)”両パッケージは同一のAPI面を持ちます。React 18+にはsynstate-react-hooks、Preactにはsynstate-preact-hooksを使用してください。
useObservableValue(observable$): Observableを購読し、現在の値をコンポーネントの状態として返す。内部的にuseSyncExternalStoreを使用し、Observableが値を発行するとコンポーネントが再レンダリングされる。useObservableValue(observable$, fallback): 上記と同じ。初期値を持たないObservableに対するフォールバック値を指定。useObservableEffect(observable$, fn): コンポーネントがマウントされている間fnを購読する(詳細)。useValueAsObservable(value): コンポーネントのpropやstateの値をsynstateのObservableに変換。React/Preactの状態をObservableグラフに橋渡しする際に有用。Observable はコンポーネントのアンマウントで完了する。React では<Activity>が隠れてから再び表示されると別の Observable に置き換わるので、最初のものを持ち続けず、毎回のレンダーで受け取ったものを使う。
状態ラッパー
Section titled “状態ラッパー”コアのcreateState / createReducer / createBooleanStateを再エクスポートしますが、タプルの最初の要素としてraw Observableの代わりにフック(useCurrentValue)を返します:
createState(initialValue):[useCurrentValue, setState, { state, updateState, resetState, getSnapshot, initialState }]を返す。createReducer(reducer, initialState):[useCurrentValue, dispatch, { state, getSnapshot, initialState }]を返す。createBooleanState(initialValue):[useCurrentValue, { state, setTrue, setFalse, toggle, setState, updateState, resetState, getSnapshot, initialState }]を返す。
Preact Signals (synstate-preact-signals)
Section titled “Preact Signals (synstate-preact-signals)”synstateのObservableとPreact Signalsを橋渡しし、コンポーネントの再レンダリングなしにきめ細かいDOM更新を実現します。hooksアプローチとの比較はインタラクティブデモを参照してください。
ブリッジ関数
Section titled “ブリッジ関数”toSignal(observable$):Observable(またはInitializedObservable)をPreactのReadonlySignalに変換。SignalはObservableと同期し続ける。JSXに直接埋め込み可能 — コンポーネント全体ではなく、影響を受けるテキストノードのみが更新される。toSignal(observable$, fallback): 上記と同じ。初期値を持たないObservableに対するフォールバック値を指定。fromSignal(signal): PreactのSignalをsynstateのInitializedSourceObservableに変換。[observable, dispose]を返す。ObservableはSignalの値をミラーリングし、synstateのオペレーターチェーン(map、debounce、switchMap等)を適用可能。
状態ラッパー
Section titled “状態ラッパー”hooksラッパーと同じですが、フックの代わりに**ReadonlySignal**を返します:
createState(initialValue):[signal, setState, { state, updateState, resetState, getSnapshot, initialState }]を返す。createReducer(reducer, initialState):[signal, dispatch, { state, getSnapshot, initialState }]を返す。createBooleanState(initialValue):[signal, { state, setTrue, setFalse, toggle, setState, updateState, resetState, getSnapshot, initialState }]を返す。