@wcstack/state 2.3.0 → 2.4.0
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 +89 -17
- package/README.md +89 -17
- package/dist/auto.min.js +1 -1
- package/dist/auto.min.js.map +1 -1
- package/dist/index.d.ts +144 -5
- package/dist/index.esm.js +2192 -167
- package/dist/index.esm.js.map +1 -1
- package/dist/manifest.esm.js +2 -0
- package/dist/wcs-manifest.json +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -68,6 +68,8 @@ type PathInfoSource =
|
|
|
68
68
|
"binding"
|
|
69
69
|
/** `$watch` の宣言キー */
|
|
70
70
|
| "watch"
|
|
71
|
+
/** `$scan` の `from` / `resetOn`(docs/state-scan-design.md §2-4) */
|
|
72
|
+
| "scan"
|
|
71
73
|
/** ランタイム内部のパス翻訳(mapped な bind-component の外向き伝播)。検査しない */
|
|
72
74
|
| "internal";
|
|
73
75
|
|
|
@@ -253,7 +255,7 @@ declare class RecursionRegistry {
|
|
|
253
255
|
* この世代が生やしたもの(own の生成アクセサ・依存辺・キャッシュ)を忘れる(state の
|
|
254
256
|
* 再セット時、`getStateInfo` の再収集より**前**に呼ぶ)。実体は generation.ts。
|
|
255
257
|
*/
|
|
256
|
-
forgetGenerated(stateElement: IStateElement, previousState: object):
|
|
258
|
+
forgetGenerated(stateElement: IStateElement, previousState: object): ReadonlySet<string>;
|
|
257
259
|
/**
|
|
258
260
|
* `**` 接尾辞の深さ `depth` の具体パス(`concretePathAt` の記憶付き版)。
|
|
259
261
|
* 束縛形の読み(`this["nodes.**.value"]` / 省略形 `$getAll`)は再帰 getter の評価ごとに
|
|
@@ -310,6 +312,14 @@ interface IStateElement {
|
|
|
310
312
|
readonly dynamicDependency: Map<string, string[]>;
|
|
311
313
|
readonly staticDependency: Map<string, string[]>;
|
|
312
314
|
readonly version: number;
|
|
315
|
+
/**
|
|
316
|
+
* state の世代。`_state` の差し替えごとに 1 つ進み、キャッシュ項目の印になる
|
|
317
|
+
* (cache/types.ts の `generation`)。`version`(更新サイクルの番号)とは別のカウンタ。
|
|
318
|
+
* optional なのはテスト用モック互換のため(undefined のモックが載せた項目は
|
|
319
|
+
* undefined 同士で一致し、従来どおりヒットする — `__tests__/proxy.getByAddress.test.ts`
|
|
320
|
+
* の「キャッシュがある場合はキャッシュを返すこと」が固定する)。
|
|
321
|
+
*/
|
|
322
|
+
readonly stateGeneration?: number;
|
|
313
323
|
readonly rootNode: Node;
|
|
314
324
|
readonly boundComponentStateProp: string | null;
|
|
315
325
|
/**
|
|
@@ -395,6 +405,12 @@ interface IStateElement {
|
|
|
395
405
|
* optional なのはテスト用モック互換のため(undefined は「宣言なし」扱い)。
|
|
396
406
|
*/
|
|
397
407
|
readonly watchPaths?: ReadonlySet<string> | null;
|
|
408
|
+
/**
|
|
409
|
+
* `$scan` の `from` パスの集合(docs/state-scan-design.md §2-1)。`watchPaths` と並んで
|
|
410
|
+
* setByAddress の旧値キャプチャのゲートになる(fold に `prev` を渡すため)。
|
|
411
|
+
* 宣言が無ければ null / undefined。optional なのはテスト用モック互換のため。
|
|
412
|
+
*/
|
|
413
|
+
readonly scanPaths?: ReadonlySet<string> | null;
|
|
398
414
|
/**
|
|
399
415
|
* パスを依存グラフへ登録する。DOM バインディング登録(BindingSession)のほか、
|
|
400
416
|
* `$watch` 宣言(processWatchDeclaration)からも呼ばれる — 静的依存グラフに
|
|
@@ -1160,9 +1176,13 @@ type DevtoolsEvent = {
|
|
|
1160
1176
|
readonly stateElement?: IStateElement;
|
|
1161
1177
|
} | {
|
|
1162
1178
|
readonly type: "state:watch-error";
|
|
1163
|
-
/**
|
|
1164
|
-
|
|
1165
|
-
|
|
1179
|
+
/**
|
|
1180
|
+
* throw 元。cur の評価(getter)とハンドラ本体では原因も直し方も違う。
|
|
1181
|
+
* `$scan`(scan/scanReport.ts)は `evaluate`(source / 出力の読み)・`fold`(fold の throw・
|
|
1182
|
+
* Promise の戻り値・接ぎ木で getter になった from)・`write`(出力の書き込み)を使う
|
|
1183
|
+
*/
|
|
1184
|
+
readonly phase: "prime" | "evaluate" | "handler" | "fold" | "write";
|
|
1185
|
+
/** `$watch` の宣言キー(ワイルドカードを含む生のパス)。`$scan` は `$scan.<出力名>` */
|
|
1166
1186
|
readonly path: string;
|
|
1167
1187
|
readonly error: unknown;
|
|
1168
1188
|
} | {
|
|
@@ -1184,7 +1204,7 @@ type DevtoolsEvent = {
|
|
|
1184
1204
|
} | {
|
|
1185
1205
|
readonly type: "state:path-unresolved";
|
|
1186
1206
|
/** 書き手が書いた面。診断 code が binding / watch で変わる */
|
|
1187
|
-
readonly source: "binding" | "watch";
|
|
1207
|
+
readonly source: "binding" | "watch" | "scan";
|
|
1188
1208
|
/** 宣言されたパス(ワイルドカードを含む生の文字列) */
|
|
1189
1209
|
readonly path: string;
|
|
1190
1210
|
/** 解決に失敗したセグメント */
|
|
@@ -1302,6 +1322,20 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1302
1322
|
private _crossRowListPaths;
|
|
1303
1323
|
private _indexDependentGetterPaths;
|
|
1304
1324
|
private _initialized;
|
|
1325
|
+
/**
|
|
1326
|
+
* 初期化(`_initialize`)が失敗した(#257)。`_initialized` の裏返しではない —
|
|
1327
|
+
* 「まだ初期化していない」と「もう初期化できない」を取り違えると、復旧不能の
|
|
1328
|
+
* 要素に `setInitialState` が効いたように見える。真にするのは
|
|
1329
|
+
* `_failInitializeLoudly` だけ。
|
|
1330
|
+
*/
|
|
1331
|
+
private _initializeFailed;
|
|
1332
|
+
/**
|
|
1333
|
+
* この接続サイクルの失敗は**もう着地した**(#257)。設定エラーの fail-fast
|
|
1334
|
+
* (`_failInitialization` と `initializeMountScope` の catch)は自分で promise を
|
|
1335
|
+
* 解決してから raise する — connectedCallbackPromise を**解決**する側のクラスなので、
|
|
1336
|
+
* 下の loud な着地(reject + 診断)に載せ替えると意味論が変わる。接続ごとに畳む。
|
|
1337
|
+
*/
|
|
1338
|
+
private _initializationLanded;
|
|
1305
1339
|
private _initializePromise;
|
|
1306
1340
|
private _resolveInitialize;
|
|
1307
1341
|
private _connectedCallbackPromise;
|
|
@@ -1321,7 +1355,39 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1321
1355
|
private _dynamicDependency;
|
|
1322
1356
|
private _staticDependency;
|
|
1323
1357
|
private _pathSet;
|
|
1358
|
+
/**
|
|
1359
|
+
* state の世代(issue #258 の X10)。`_state` の差し替えごとに 1 つ進み、キャッシュ項目の
|
|
1360
|
+
* 印になる(cache/types.ts の `generation`)。`_version`(更新サイクルの番号)とは別の
|
|
1361
|
+
* カウンタで、増える条件が違う — 再セットは世代だけを進める
|
|
1362
|
+
* (`__tests__/integration.stateGenerationReset.test.ts` の
|
|
1363
|
+
* 「再セットは世代だけを進め、version は動かさない」が固定する)。
|
|
1364
|
+
*/
|
|
1365
|
+
private _stateGeneration;
|
|
1366
|
+
/**
|
|
1367
|
+
* この要素が受け取った `setPathInfo` の台帳(issue #258 の X7)。パス → 種別と呼び出し元。
|
|
1368
|
+
*
|
|
1369
|
+
* `_pathSet` / `_listPaths` / `_elementPaths` は再セットでクリアされるが、それらを登録した
|
|
1370
|
+
* バインドは生き残る(再セットは DOM を作り直さない)。台帳が空のままだと依存ウォークが
|
|
1371
|
+
* `items` をリストとして展開できず、全リスト書き込みが「非リストのアドレスにワイルドカードを
|
|
1372
|
+
* 展開できない」で恒久的に throw する(値と DOM は追従するが、書き込みのたびに投げ続ける)。
|
|
1373
|
+
* クリアのあと、この台帳から作り直す(`_rebuildPathInfo`)。
|
|
1374
|
+
*
|
|
1375
|
+
* `source === "internal"`(再帰の生成アクセサ・ボリュームのツリーアクセサ)は載せない。
|
|
1376
|
+
* あれらは生やした機構が新しい世代で登録し直す(recursion/registry.ts の `_define`)。
|
|
1377
|
+
*/
|
|
1378
|
+
private _pathRegistrations;
|
|
1379
|
+
/**
|
|
1380
|
+
* これまでのどの世代かで再帰レジストリが実体化した具体パス(`nodes.*.total` 等)の累積。
|
|
1381
|
+
* 再セットのたびに `forgetGenerated` の戻り値を足し、`_rebuildPathInfo` の除外に使う。
|
|
1382
|
+
*
|
|
1383
|
+
* 除外は**世代を跨いで累積する**。読みを挟まない連続した再セットでも、生成アクセサの具体パスを
|
|
1384
|
+
* 指す静的辺(`nodes.*` → `nodes.*.total`)が戻らないことは、
|
|
1385
|
+
* `__tests__/integration.stateGenerationReset.test.ts` の
|
|
1386
|
+
* 「読みを挟まない 3 連続の再セットで静的辺が戻らない」が固定する。
|
|
1387
|
+
*/
|
|
1388
|
+
private _generatedPaths;
|
|
1324
1389
|
private _watchPaths;
|
|
1390
|
+
private _scanPaths;
|
|
1325
1391
|
private _version;
|
|
1326
1392
|
private _rootNode;
|
|
1327
1393
|
private _boundComponent;
|
|
@@ -1353,6 +1419,10 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1353
1419
|
* ルートより先に接続されてもよい — ルート登録が保留分を引き取る(V5)。
|
|
1354
1420
|
*/
|
|
1355
1421
|
private _initializeVolume;
|
|
1422
|
+
/**
|
|
1423
|
+
* 初回マウントのロードと登録。戻り値は「この接続で初期化を**完了**したか」で、
|
|
1424
|
+
* `false` は失敗ではなく**中断**(ロード中に要素が剥がされた — 下の注記)。
|
|
1425
|
+
*/
|
|
1356
1426
|
private _initialize;
|
|
1357
1427
|
/**
|
|
1358
1428
|
* 設定エラーでの fail-fast。initializePromise 等を解決してから raise する —
|
|
@@ -1362,6 +1432,54 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1362
1432
|
* として loud に残る。
|
|
1363
1433
|
*/
|
|
1364
1434
|
private _failInitialization;
|
|
1435
|
+
/**
|
|
1436
|
+
* `_initialize` の失敗の着地(#257)。旧挙動は「throw が connectedCallback の外へ
|
|
1437
|
+
* 出るだけ」で、`_initializePromise` も `_connectedCallbackPromise` も永久に未解決の
|
|
1438
|
+
* まま残り、作者が受け取るのは診断ではなく無言のハングだった。載るのは
|
|
1439
|
+
* `_initialize` が投げうるもの全部 — `_state` セッタの宣言検証($recursion /
|
|
1440
|
+
* $commandTokens / $eventTokens / $on / $streams / $listKeys / $watch)、
|
|
1441
|
+
* `_loadStateFromSource` のロード失敗(src の拡張子・json のパース・内包スクリプト・
|
|
1442
|
+
* 外部モジュール)、SSR データの merge、そして `setStateElement` の
|
|
1443
|
+
* 「1 rootNode 1 ツリー」違反(**別の**要素が 2 本目に来た形 — 同じ要素の再登録は
|
|
1444
|
+
* 冪等なので、ロード中の remove → append はここへ来ない)。
|
|
1445
|
+
*
|
|
1446
|
+
* 載**らない**もの: ロード中に要素が剥がされた形。作者のミスが 1 つも無いので
|
|
1447
|
+
* 初期化失敗ではなく中断として扱う(`_initialize` が `false` を返す)。
|
|
1448
|
+
*
|
|
1449
|
+
* もう 1 つ載らないのがボリューム(`mount=`)の失敗。`_initializeVolume` の catch が
|
|
1450
|
+
* 3 つの promise(initialize / loading / connectedCallback)を自分で解決してから raise し、
|
|
1451
|
+
* `connectedCallback` のボリューム分岐はそれを包まないので、ボリュームはこの着地に
|
|
1452
|
+
* 載らず connectedCallbackPromise を**拒否しない**。自前の報告が出るかどうかは失敗の
|
|
1453
|
+
* 種類による。報告が無い形では、逃げ方は `name=`(`_failInitialization` の注記)と
|
|
1454
|
+
* 同じで、throw はカスタム要素リアクションが捨てる戻り Promise へ出ていく
|
|
1455
|
+
* (ブラウザのコンソールには "Uncaught (in promise)" として残るが、promise を待つ側
|
|
1456
|
+
* = renderToString・mount・テストレシピには届かない)。失敗箇所ごとの正確な挙動は
|
|
1457
|
+
* `__tests__/integration.initFailureDiagnostics.test.ts` が固定している。挙動はこの
|
|
1458
|
+
* PR では変えない(枠の寿命は別 Issue)。
|
|
1459
|
+
*
|
|
1460
|
+
* `connectedCallback` が `_initialize` より前に await する 2 つ
|
|
1461
|
+
* (`_initializeDCC` / `_initializeBindWebComponent`)の raise も同じ着地に載る。
|
|
1462
|
+
* 特に「初期化に失敗した要素の再接続」は `bindWebComponent` → `setInitialState` の
|
|
1463
|
+
* 復旧不能 raise でそこへ来るので、包まないと診断ゼロで素通りする。
|
|
1464
|
+
*
|
|
1465
|
+
* `_failInitialization`(設定エラーの fail-fast)との違いは 1 つ:
|
|
1466
|
+
* **connectedCallbackPromise を reject する**。ここまで来た要素は state を 1 つも
|
|
1467
|
+
* 持たない = このツリーは存在しない。resolve すると、それを待つ消費者
|
|
1468
|
+
* (@wcstack/server の renderToString・@wcstack/testing の mount・README の
|
|
1469
|
+
* テストレシピ)に「準備完了」と嘘をつく。下の SSR 経路(_rejectConnectedCallback)と
|
|
1470
|
+
* 同じ規範で、そちらと同じく**元のエラーをそのまま**投げ直す。
|
|
1471
|
+
*
|
|
1472
|
+
* `initializePromise` は従来どおり**解決**する(reject しない)。
|
|
1473
|
+
* `waitForStateInitialize` はページ中の全 `<wcs-state>` の initializePromise を
|
|
1474
|
+
* `Promise.all` で待つので、reject にすると 1 要素の設定ミスが無関係な
|
|
1475
|
+
* バインディングまで道連れになる(_failInitialization の注記と同じ理由)。
|
|
1476
|
+
*
|
|
1477
|
+
* 後始末はしない: `_initialized` を立てないので `disconnectedCallback` は初期化前
|
|
1478
|
+
* ガードで抜ける。`$listKeys` / `$watch` のようにセッタの後半で落ちた形では
|
|
1479
|
+
* `$on` の購読と stream registry が残るが、この要素は復旧不能(setInitialState が
|
|
1480
|
+
* throw する)なので、残骸は要素ごと捨てる前提で放置する。
|
|
1481
|
+
*/
|
|
1482
|
+
private _failInitializeLoudly;
|
|
1365
1483
|
private _initializeBindWebComponent;
|
|
1366
1484
|
private _callStateConnectedCallback;
|
|
1367
1485
|
private _initializeDCC;
|
|
@@ -1376,6 +1494,7 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1376
1494
|
get hasRecursion(): boolean;
|
|
1377
1495
|
get recursionRegistry(): RecursionRegistry | null;
|
|
1378
1496
|
get watchPaths(): ReadonlySet<string> | null;
|
|
1497
|
+
get scanPaths(): ReadonlySet<string> | null;
|
|
1379
1498
|
get elementPaths(): Set<string>;
|
|
1380
1499
|
/**
|
|
1381
1500
|
* ボリューム(webComponent/volume.ts)のアクセサ登録: ツリーパスをキーにした
|
|
@@ -1400,6 +1519,8 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1400
1519
|
get dynamicDependency(): Map<string, string[]>;
|
|
1401
1520
|
get staticDependency(): Map<string, string[]>;
|
|
1402
1521
|
get version(): number;
|
|
1522
|
+
/** state の世代(キャッシュ項目の印の正本 — cache/types.ts の `generation`)。 */
|
|
1523
|
+
get stateGeneration(): number;
|
|
1403
1524
|
get rootNode(): Node;
|
|
1404
1525
|
get boundComponentStateProp(): string | null;
|
|
1405
1526
|
get hasMounts(): boolean;
|
|
@@ -1440,6 +1561,24 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1440
1561
|
*/
|
|
1441
1562
|
addStaticDependency(sourcePath: string, targetPath: string): boolean;
|
|
1442
1563
|
setPathInfo(path: string, bindingType: BindingType, source?: PathInfoSource): void;
|
|
1564
|
+
/**
|
|
1565
|
+
* 再セットで消した経路情報を、生き残ったバインドの登録から作り直す(issue #258 の X7)。
|
|
1566
|
+
*
|
|
1567
|
+
* `_pathSet.clear()` は残す。あのクリアには、`forgetGeneration` が外した静的辺を「行が
|
|
1568
|
+
* 作り直されたときに登録し直させる」自己修復が乗っている(辺が戻ることは
|
|
1569
|
+
* `__tests__/integration.stateGenerationReset.test.ts` の
|
|
1570
|
+
* 「静的な辺 nodes.* → nodes.*.total が戻る」が固定する)。消したうえで、生きているバインド
|
|
1571
|
+
* ぶんだけ `setPathInfo` をやり直す — `$recursion` のアンカーで既に同じことをしている手口を、
|
|
1572
|
+
* バインド全体へ広げたもの。
|
|
1573
|
+
*
|
|
1574
|
+
* `_generatedPaths`(これまでの世代の生成アクセサの具体パス)は張り直さない。行バインドが
|
|
1575
|
+
* 名指していても、新しい世代ではまだ実体化されていないため(recursion/generation.ts)。読みが
|
|
1576
|
+
* 実体化したときに `defineTreeAccessor` が登録し直す。
|
|
1577
|
+
*
|
|
1578
|
+
* 反復中に `setPathInfo` が台帳へ書き戻す(既存キーの上書きのみで新キーは増えない)ので、
|
|
1579
|
+
* 誤解を避けるためスナップショットを取ってから回す。
|
|
1580
|
+
*/
|
|
1581
|
+
private _rebuildPathInfo;
|
|
1443
1582
|
private _createState;
|
|
1444
1583
|
createStateAsync(mutability: Mutability, callback: (state: IStateProxy) => Promise<void>): Promise<void>;
|
|
1445
1584
|
createState(mutability: Mutability, callback: (state: IStateProxy) => void): void;
|