@wcstack/state 2.0.0 → 2.1.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/dist/auto.min.js +1 -1
- package/dist/auto.min.js.map +1 -1
- package/dist/index.d.ts +22 -3
- package/dist/index.esm.js +59 -10
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -91,7 +91,6 @@ interface IStateProxy extends IState {
|
|
|
91
91
|
type Mutability = "readonly" | "writable";
|
|
92
92
|
|
|
93
93
|
interface IStateElement {
|
|
94
|
-
readonly name: string;
|
|
95
94
|
/**
|
|
96
95
|
* state のロードが完了しているか。`initializePromise` の同期版で、
|
|
97
96
|
* DCC のアクセサが「今すぐ読み書きしてよいか」を判断するのに使う。
|
|
@@ -867,6 +866,13 @@ type DevtoolsEvent = {
|
|
|
867
866
|
readonly tokenName: string;
|
|
868
867
|
readonly args: readonly unknown[];
|
|
869
868
|
readonly subscriberCount: number;
|
|
869
|
+
/**
|
|
870
|
+
* 発火元ツリーの state 要素(protocol v2 追補 2026-09-05・additive)。
|
|
871
|
+
* registry(getOrCreate*Token)経由で作られた token だけが持つ — 直接生成された
|
|
872
|
+
* token や旧ランタイムの payload には無い(optional)。無い emit の実測は
|
|
873
|
+
* ツリー別に分けられないため、消費側は全ツリーの照会へ合算で残す。
|
|
874
|
+
*/
|
|
875
|
+
readonly stateElement?: IStateElement;
|
|
870
876
|
} | {
|
|
871
877
|
readonly type: "state:watch-error";
|
|
872
878
|
/** throw 元。cur の評価(getter)とハンドラ本体では原因も直し方も違う */
|
|
@@ -883,6 +889,13 @@ type DevtoolsEvent = {
|
|
|
883
889
|
readonly type: "state:watch-fired";
|
|
884
890
|
/** `$watch` の宣言キー(ワイルドカードを含む生のパス) */
|
|
885
891
|
readonly path: string;
|
|
892
|
+
/**
|
|
893
|
+
* 発火元ツリーの state 要素(protocol v2 追補 2026-09-05・additive)。
|
|
894
|
+
* 複数ツリーが同名の watch パスを宣言するページで実測台帳をツリー別に
|
|
895
|
+
* 分けるための識別。旧ランタイムの payload には無い(optional)— 無い発火は
|
|
896
|
+
* 消費側が全ツリーの照会へ合算で残す。値を載せない契約(§4.3.1)は不変。
|
|
897
|
+
*/
|
|
898
|
+
readonly stateElement?: IStateElement;
|
|
886
899
|
} | {
|
|
887
900
|
readonly type: "state:path-unresolved";
|
|
888
901
|
/** 書き手が書いた面。診断 code が binding / watch で変わる */
|
|
@@ -988,13 +1001,19 @@ declare function analyzeContract(manifest: IContractManifest): readonly Contract
|
|
|
988
1001
|
declare class State extends HTMLElementBase implements IStateElement {
|
|
989
1002
|
static hasConnectedCallbackPromise: boolean;
|
|
990
1003
|
static getBindingsReady(rootNode: Node): Promise<void>;
|
|
1004
|
+
/**
|
|
1005
|
+
* `mount` の動的変更は未サポート(再マウントは非目標 — 設計書 §4-7)。
|
|
1006
|
+
* 初期化済み要素での変更は無言で捨てず warn で知らせる。初期化前の属性設定
|
|
1007
|
+
* (パース時・接続前の setAttribute)は正規の使い方なので黙る。
|
|
1008
|
+
* `name` は connectedCallback 冒頭で fail-fast 済みなので観測しない。
|
|
1009
|
+
*/
|
|
1010
|
+
static get observedAttributes(): string[];
|
|
991
1011
|
private __state;
|
|
992
1012
|
private _hasUpdatedCallback;
|
|
993
1013
|
/** enable-ssr のスナップショットから初期化された(D14: ボリュームはデータを採用する) */
|
|
994
1014
|
private _hydratedFromSsr;
|
|
995
1015
|
private _crossRowListPaths;
|
|
996
1016
|
private _indexDependentGetterPaths;
|
|
997
|
-
private _name;
|
|
998
1017
|
private _initialized;
|
|
999
1018
|
private _initializePromise;
|
|
1000
1019
|
private _resolveInitialize;
|
|
@@ -1036,7 +1055,7 @@ declare class State extends HTMLElementBase implements IStateElement {
|
|
|
1036
1055
|
constructor();
|
|
1037
1056
|
private get _state();
|
|
1038
1057
|
private set _state(value);
|
|
1039
|
-
|
|
1058
|
+
attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
|
|
1040
1059
|
private _loadFromSsrElement;
|
|
1041
1060
|
/** state / src / json / inner <script> / API set のソース解決(_initialize とボリュームで共用)。 */
|
|
1042
1061
|
private _loadStateFromSource;
|
package/dist/index.esm.js
CHANGED
|
@@ -3655,8 +3655,15 @@ class Token {
|
|
|
3655
3655
|
// EventToken は共有 pub/sub プリミティブ Token の薄い特化(element→state 方向)。
|
|
3656
3656
|
// instanceof による型判別を成立させるため独立クラスとして維持する。
|
|
3657
3657
|
class EventToken extends Token {
|
|
3658
|
-
|
|
3658
|
+
/**
|
|
3659
|
+
* 属する state 要素(devtools のツリー識別 — protocol v2 追補)。
|
|
3660
|
+
* registry(getOrCreateEventToken)経由の生成でのみ渡る optional 参照。
|
|
3661
|
+
* 寿命は registry 側の WeakMap が管理する(CommandToken と同じ位置づけ)。
|
|
3662
|
+
*/
|
|
3663
|
+
_stateElement;
|
|
3664
|
+
constructor(name, stateElement) {
|
|
3659
3665
|
super(name);
|
|
3666
|
+
this._stateElement = stateElement;
|
|
3660
3667
|
}
|
|
3661
3668
|
emit(...args) {
|
|
3662
3669
|
if (devtoolsSink !== null) {
|
|
@@ -3666,6 +3673,7 @@ class EventToken extends Token {
|
|
|
3666
3673
|
tokenName: this.name,
|
|
3667
3674
|
args,
|
|
3668
3675
|
subscriberCount: this.size,
|
|
3676
|
+
stateElement: this._stateElement,
|
|
3669
3677
|
});
|
|
3670
3678
|
}
|
|
3671
3679
|
return super.emit(...args);
|
|
@@ -3681,7 +3689,8 @@ function getOrCreateEventToken(stateElement, name) {
|
|
|
3681
3689
|
}
|
|
3682
3690
|
let token = registry.get(name);
|
|
3683
3691
|
if (typeof token === "undefined") {
|
|
3684
|
-
|
|
3692
|
+
// stateElement を渡すのは devtools のツリー識別(protocol v2 追補)のため
|
|
3693
|
+
token = new EventToken(name, stateElement);
|
|
3685
3694
|
registry.set(name, token);
|
|
3686
3695
|
}
|
|
3687
3696
|
return token;
|
|
@@ -3806,8 +3815,16 @@ function detachEventTokenHandler(binding) {
|
|
|
3806
3815
|
// instanceof による型判別を成立させるため独立クラスとして維持する。
|
|
3807
3816
|
//
|
|
3808
3817
|
class CommandToken extends Token {
|
|
3809
|
-
|
|
3818
|
+
/**
|
|
3819
|
+
* 属する state 要素(devtools のツリー識別 — protocol v2 追補)。
|
|
3820
|
+
* registry(getOrCreateCommandToken)経由の生成でのみ渡る optional 参照で、
|
|
3821
|
+
* token の寿命は registry 側の WeakMap が state 要素に紐づけている(ここが
|
|
3822
|
+
* 寿命を延ばす新しい経路にはならない)。emit の payload にだけ載せる。
|
|
3823
|
+
*/
|
|
3824
|
+
_stateElement;
|
|
3825
|
+
constructor(name, stateElement) {
|
|
3810
3826
|
super(name);
|
|
3827
|
+
this._stateElement = stateElement;
|
|
3811
3828
|
}
|
|
3812
3829
|
emit(...args) {
|
|
3813
3830
|
if (devtoolsSink !== null) {
|
|
@@ -3819,6 +3836,7 @@ class CommandToken extends Token {
|
|
|
3819
3836
|
tokenName: this.name,
|
|
3820
3837
|
args,
|
|
3821
3838
|
subscriberCount: this.size,
|
|
3839
|
+
stateElement: this._stateElement,
|
|
3822
3840
|
});
|
|
3823
3841
|
}
|
|
3824
3842
|
return super.emit(...args);
|
|
@@ -9164,7 +9182,7 @@ async function buildBindings(root) {
|
|
|
9164
9182
|
}
|
|
9165
9183
|
}
|
|
9166
9184
|
|
|
9167
|
-
var version = "2.
|
|
9185
|
+
var version = "2.1.0";
|
|
9168
9186
|
var pkg = {
|
|
9169
9187
|
version: version};
|
|
9170
9188
|
|
|
@@ -11186,7 +11204,8 @@ function getOrCreateCommandToken(stateElement, name) {
|
|
|
11186
11204
|
}
|
|
11187
11205
|
let token = registry.get(name);
|
|
11188
11206
|
if (typeof token === "undefined") {
|
|
11189
|
-
|
|
11207
|
+
// stateElement を渡すのは devtools のツリー識別(protocol v2 追補)のため
|
|
11208
|
+
token = new CommandToken(name, stateElement);
|
|
11190
11209
|
registry.set(name, token);
|
|
11191
11210
|
}
|
|
11192
11211
|
return token;
|
|
@@ -12774,8 +12793,10 @@ function fireOne(hit) {
|
|
|
12774
12793
|
}
|
|
12775
12794
|
// 正常発火の観測(設計書 §11 の予約イベント・配線カバレッジの実測面)。
|
|
12776
12795
|
// 値は載せない。イベント生成は sink 接続時のみ(ゼロコスト契約)。
|
|
12796
|
+
// stateElement は発火元ツリーの識別(protocol v2 追補)— これが無いと
|
|
12797
|
+
// 複数ツリーが同名 watch パスを宣言するページで実測が合算される。
|
|
12777
12798
|
if (devtoolsSink !== null) {
|
|
12778
|
-
devtoolsSink({ type: "state:watch-fired", path: entry.path });
|
|
12799
|
+
devtoolsSink({ type: "state:watch-fired", path: entry.path, stateElement });
|
|
12779
12800
|
}
|
|
12780
12801
|
entry.handler.call(state, cur, prev, ...indexes);
|
|
12781
12802
|
});
|
|
@@ -15317,6 +15338,14 @@ function updatedCallback(target, refs, receiver, handler) {
|
|
|
15317
15338
|
}
|
|
15318
15339
|
const pathInfo = ref.absolutePathInfo.pathInfo;
|
|
15319
15340
|
const pathName = pathInfo.path;
|
|
15341
|
+
// D20/D21: マーカーパス(`#m<id>` セグメント = マウント私有キーの内部アドレス)は
|
|
15342
|
+
// マウントインスタンスの私有語彙。ルートの $updatedCallback へ素通しすると、
|
|
15343
|
+
// 作者に解釈不能で再初期化のたびに変わる内部 id が漏れるため配送しない
|
|
15344
|
+
// (`#` はパス文法で書けない文字 — ツリーパスとは構造的に衝突しない)。
|
|
15345
|
+
// 私有キーの可視化は devtools の overlays() 経由(プロトコル v2)。
|
|
15346
|
+
if (pathName.indexOf("#") !== -1) {
|
|
15347
|
+
continue;
|
|
15348
|
+
}
|
|
15320
15349
|
paths.add(pathName);
|
|
15321
15350
|
if (pathInfo.wildcardCount > 0) {
|
|
15322
15351
|
const indexes = getScopedIndexes(ref.listIndex, pathInfo.wildcardCount);
|
|
@@ -15349,6 +15378,10 @@ function updatedCallback(target, refs, receiver, handler) {
|
|
|
15349
15378
|
if (path !== volume.mountPath && !path.startsWith(prefix)) {
|
|
15350
15379
|
continue;
|
|
15351
15380
|
}
|
|
15381
|
+
// マーカーパス(マウント私有キー)はボリューム相対配送にも漏らさない(上と同じ D20/D21)
|
|
15382
|
+
if (path.indexOf("#") !== -1) {
|
|
15383
|
+
continue;
|
|
15384
|
+
}
|
|
15352
15385
|
const relative = path === volume.mountPath ? "" : path.slice(prefix.length);
|
|
15353
15386
|
if (relative === "") {
|
|
15354
15387
|
continue; // マウントポイント自身(接ぎ木そのもの)は相対で表せない
|
|
@@ -16386,6 +16419,15 @@ class State extends HTMLElementBase {
|
|
|
16386
16419
|
static getBindingsReady(rootNode) {
|
|
16387
16420
|
return getBindingsReady(rootNode);
|
|
16388
16421
|
}
|
|
16422
|
+
/**
|
|
16423
|
+
* `mount` の動的変更は未サポート(再マウントは非目標 — 設計書 §4-7)。
|
|
16424
|
+
* 初期化済み要素での変更は無言で捨てず warn で知らせる。初期化前の属性設定
|
|
16425
|
+
* (パース時・接続前の setAttribute)は正規の使い方なので黙る。
|
|
16426
|
+
* `name` は connectedCallback 冒頭で fail-fast 済みなので観測しない。
|
|
16427
|
+
*/
|
|
16428
|
+
static get observedAttributes() {
|
|
16429
|
+
return ["mount"];
|
|
16430
|
+
}
|
|
16389
16431
|
__state;
|
|
16390
16432
|
_hasUpdatedCallback = false;
|
|
16391
16433
|
/** enable-ssr のスナップショットから初期化された(D14: ボリュームはデータを採用する) */
|
|
@@ -16396,7 +16438,6 @@ class State extends HTMLElementBase {
|
|
|
16396
16438
|
// $1 等のインデックスを読んだ getter パス(実行時検出)。位置のみ変わった行の
|
|
16397
16439
|
// 静的子展開はこの集合の subtree に限定される。追加のみ・クリアしない(安全側)。
|
|
16398
16440
|
_indexDependentGetterPaths = new Set();
|
|
16399
|
-
_name = 'default';
|
|
16400
16441
|
_initialized = false;
|
|
16401
16442
|
_initializePromise;
|
|
16402
16443
|
_resolveInitialize = null;
|
|
@@ -16530,8 +16571,14 @@ class State extends HTMLElementBase {
|
|
|
16530
16571
|
}
|
|
16531
16572
|
this._resolveLoading?.();
|
|
16532
16573
|
}
|
|
16533
|
-
|
|
16534
|
-
|
|
16574
|
+
attributeChangedCallback(_name, oldValue, newValue) {
|
|
16575
|
+
// observedAttributes は "mount" のみ。同値 set(oldValue === newValue)は変更ではない
|
|
16576
|
+
if (!this._initialized || oldValue === newValue) {
|
|
16577
|
+
return;
|
|
16578
|
+
}
|
|
16579
|
+
console.warn(`[@wcstack/state] Changing the "mount" attribute after initialization is not supported and is ignored ` +
|
|
16580
|
+
`(was ${oldValue === null ? "absent" : `"${oldValue}"`}, now ${newValue === null ? "absent" : `"${newValue}"`}). ` +
|
|
16581
|
+
`Remove this <${config.tagNames.state}> element and create a new one with the desired mount path instead.`);
|
|
16535
16582
|
}
|
|
16536
16583
|
_loadFromSsrElement() {
|
|
16537
16584
|
if (!this.hasAttribute('enable-ssr'))
|
|
@@ -16571,7 +16618,9 @@ class State extends HTMLElementBase {
|
|
|
16571
16618
|
else {
|
|
16572
16619
|
const script = this.querySelector('script[type="module"]');
|
|
16573
16620
|
if (script) {
|
|
16574
|
-
|
|
16621
|
+
// sourceURL ラベル。v2 はルートに 1 ツリーなので名前次元は無く、要素の
|
|
16622
|
+
// タグ名(DCC 経路が host のタグ名を渡すのと同じ流儀)で特定十分
|
|
16623
|
+
return await loadFromInnerScript(script, config.tagNames.state);
|
|
16575
16624
|
}
|
|
16576
16625
|
else {
|
|
16577
16626
|
const timerId = setTimeout(() => {
|