@wcstack/state 1.21.5 → 1.21.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -867,6 +867,7 @@ export default {
867
867
  | `this.$resolve(path, indexes, value?)` | ワイルドカードパスを特定のインデックスで解決 |
868
868
  | `this.$postUpdate(path)` | 指定パスの更新通知を手動で発行 |
869
869
  | `this.$trackDependency(path)` | キャッシュ無効化のための依存関係を手動で登録 |
870
+ | `this.$untrackDependency(fn)` | fn 実行中の依存追跡を抑止して値を読む(`$trackDependency` と対称) |
870
871
  | `this.$stateElement` | `IStateElement` インスタンスへのアクセス |
871
872
  | `this.$1`, `this.$2`, ... | 現在のループインデックス(1始まりの命名、0始まりの値) |
872
873
 
@@ -1831,6 +1832,47 @@ buildBindings(root)
1831
1832
  - **StateAddress** — PathInfo + ListIndex の組み合わせ
1832
1833
  - **AbsoluteStateAddress** — 状態名 + StateAddress(クロス状態参照用)
1833
1834
 
1835
+ ## パフォーマンス
1836
+
1837
+ リポジトリ同梱の [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) 流
1838
+ ドライバ(`e2e/bench/jsfb-verify.mjs`・`e2e/bench/memory-profile.mjs`)で、標準の
1839
+ 1,000 / 10,000 行テーブルページを計測(headless Chromium・中央値・両実装を同一
1840
+ セッションで連続実行)。`@wcstack/state` は公式の keyed 判定に合格しつつ、行 DOM
1841
+ を上限 1,000 行の有界プールでリサイクルします。
1842
+
1843
+ | 所要時間(ms・中央値) | `@wcstack/state` | [`@wcstack/signals`](../signals/) |
1844
+ |---|---|---|
1845
+ | 1,000 行の生成 | 25.2 | 9.5 |
1846
+ | 1,000 行の全置換 | 18.8 | 12.5 |
1847
+ | 10,000 行の 10 行ごと更新 | 11.4 | 4.7 |
1848
+ | 行の選択 | 0.1 | 0.4 |
1849
+ | 2 行の入れ替え | 0.9 | 0.4 |
1850
+ | 行の削除 | 2.8 | 0.6 |
1851
+ | 10,000 行への 1,000 行追加 | 48.6 | 14.2 |
1852
+ | 10,000 行のクリア | 54.6 | 52.2 |
1853
+
1854
+ | 強制 GC 後のヒープ(MB) | `@wcstack/state` | `@wcstack/signals` |
1855
+ |---|---|---|
1856
+ | ページ表示直後 | 1.0 | 0.6 |
1857
+ | 1,000 行生成後 | 5.6 | 3.5 |
1858
+ | 1,000 行×5 回置換後 | 6.4 | 3.7 |
1859
+ | 10,000 行生成後 | 35.1 | 18.0 |
1860
+ | 10,000 行生成 + クリア後 | 13.2 | 1.9 |
1861
+
1862
+ 正直な読み方:
1863
+
1864
+ - 対話系の操作(選択 / 入れ替え / 削除)は数ミリ秒以下で、巨大リストのクリアは
1865
+ signals 実装と同等です。
1866
+ - 行の生成・追加は `@wcstack/signals` の約 2.5〜3.5 倍のコストです。これは本
1867
+ パッケージが行ごとに構築する宣言的バインディング台帳の対価で、`data-wcs` の
1868
+ 検査・DevTools の配線表示・SSR ハイドレーションを支えているのは同じ台帳です。
1869
+ 両パッケージは相互運用できるため、ホットなリストだけ signals の `For` で描画
1870
+ し、残りのページは宣言的なまま保てます。
1871
+ - クリア後に残るヒープは、次のリスト生成を安くする有界の行プールです。
1872
+
1873
+ 絶対値は 1 台の開発機での計測です(v1.21.6 + PR#87 の clear リーク修正)。
1874
+ `e2e/bench/` のドライバで手元のハードウェアでも再現できます。
1875
+
1834
1876
  ## サーバーサイドレンダリング
1835
1877
 
1836
1878
  `@wcstack/state` は [`@wcstack/server`](../server/) パッケージと連携して SSR をサポートしています。クライアント用に書いたテンプレートがそのままサーバーでレンダリングされます — 変更不要。
package/README.md CHANGED
@@ -867,6 +867,7 @@ Inside state objects (getters / methods), the following APIs are available via `
867
867
  | `this.$resolve(path, indexes, value?)` | Resolve a wildcard path with specific indexes |
868
868
  | `this.$postUpdate(path)` | Manually trigger update notification for a path |
869
869
  | `this.$trackDependency(path)` | Manually register a dependency for cache invalidation |
870
+ | `this.$untrackDependency(fn)` | Read values inside fn without registering dependencies (symmetric to `$trackDependency`) |
870
871
  | `this.$command.<name>` | Access a `CommandToken` declared in `$commandTokens` (see [Command Token](#command-token-method-binding)) |
871
872
  | `this.$stateElement` | Access to the `IStateElement` instance |
872
873
  | `this.$1`, `this.$2`, ... | Current loop index (1-based naming, 0-based value) |
@@ -1833,6 +1834,50 @@ Paths like `users.*.name` are decomposed into:
1833
1834
  - **StateAddress** — combination of PathInfo + ListIndex
1834
1835
  - **AbsoluteStateAddress** — state name + StateAddress (for cross-state references)
1835
1836
 
1837
+ ## Performance
1838
+
1839
+ Measured with the repository's [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark)-style
1840
+ drivers (`e2e/bench/jsfb-verify.mjs`, `e2e/bench/memory-profile.mjs`) against the
1841
+ standard 1,000 / 10,000-row table page — headless Chromium, medians, both
1842
+ implementations measured back-to-back in the same session. `@wcstack/state`
1843
+ passes the official keyed-mode classification while recycling row DOM through a
1844
+ bounded pool (up to 1,000 rows).
1845
+
1846
+ | Duration (ms, median) | `@wcstack/state` | [`@wcstack/signals`](../signals/) |
1847
+ |---|---|---|
1848
+ | create 1,000 rows | 25.2 | 9.5 |
1849
+ | replace all 1,000 rows | 18.8 | 12.5 |
1850
+ | update every 10th of 10,000 | 11.4 | 4.7 |
1851
+ | select row | 0.1 | 0.4 |
1852
+ | swap 2 rows | 0.9 | 0.4 |
1853
+ | remove row | 2.8 | 0.6 |
1854
+ | append 1,000 to 10,000 | 48.6 | 14.2 |
1855
+ | clear 10,000 rows | 54.6 | 52.2 |
1856
+
1857
+ | Heap after forced GC (MB) | `@wcstack/state` | `@wcstack/signals` |
1858
+ |---|---|---|
1859
+ | page ready | 1.0 | 0.6 |
1860
+ | after create 1,000 | 5.6 | 3.5 |
1861
+ | after 5× replace 1,000 | 6.4 | 3.7 |
1862
+ | after create 10,000 | 35.1 | 18.0 |
1863
+ | after create 10,000 + clear | 13.2 | 1.9 |
1864
+
1865
+ How to read this, honestly:
1866
+
1867
+ - Interactive operations (select / swap / remove) run in a few milliseconds or
1868
+ less, and clearing a huge list matches the signals implementation.
1869
+ - Creating and appending rows costs ~2.5–3.5× `@wcstack/signals`. That is the
1870
+ price of the declarative binding ledger this package builds per row — the same
1871
+ ledger that powers `data-wcs` inspection, DevTools wiring, and SSR hydration.
1872
+ The two packages interoperate, so a hot list can be rendered with signals'
1873
+ `For` while the rest of the page stays declarative.
1874
+ - The heap retained after a clear is the bounded row pool that makes the next
1875
+ list population cheap.
1876
+
1877
+ Absolute numbers are from one development machine (v1.21.6 + the clear-leak fix
1878
+ in PR#87); the drivers in `e2e/bench/` reproduce the comparison on your own
1879
+ hardware.
1880
+
1836
1881
  ## Server-Side Rendering
1837
1882
 
1838
1883
  `@wcstack/state` supports SSR via the companion [`@wcstack/server`](../server/) package. The same templates you write for the client render on the server — no changes needed.
package/dist/index.d.ts CHANGED
@@ -440,6 +440,13 @@ interface WcsStateApi {
440
440
  * computed getter 内で動的にパスを組み立てる場合に使用。
441
441
  */
442
442
  $trackDependency(path: string): void;
443
+ /**
444
+ * コールバック実行中の依存追跡(動的依存・`$1` インデックス依存の登録)を
445
+ * 抑止して fn を実行し、その戻り値を返す(`$trackDependency` と対称)。
446
+ * リスト行 getter が「行外の単一値」を読みたいが、その値の変更で全行を
447
+ * 再評価させたくない場合に使う(該当行へ直接書き込む設計と組で用いる)。
448
+ */
449
+ $untrackDependency<T>(fn: () => T): T;
443
450
  /** `<wcs-state>` 要素への参照 */
444
451
  readonly $stateElement: HTMLElement;
445
452
  /**