@wcstack/state 1.33.0 → 2.0.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/index.d.ts CHANGED
@@ -98,14 +98,6 @@ interface IStateElement {
98
98
  * optional なのはテスト用モック互換のため(undefined は「不明=未初期化扱い」)。
99
99
  */
100
100
  readonly initialized?: boolean;
101
- /**
102
- * この state element が今使えるか(= 接続済みで rootNode を保持しているか)。
103
- * `createState` は rootNode を要求するので、false のときに呼ぶと raiseError する。
104
- * 台帳に載っていること(登録済み)と使えることは別で、要素をキーにした台帳には
105
- * 切断済みの state element が残る窓がある(§1.9)。
106
- * optional なのはテスト用モック互換のため(undefined は「不明=使える扱い」)。
107
- */
108
- readonly hasRootNode?: boolean;
109
101
  readonly initializePromise: Promise<void>;
110
102
  readonly connectedCallbackPromise: Promise<void>;
111
103
  readonly listPaths: Set<string>;
@@ -122,22 +114,34 @@ interface IStateElement {
122
114
  * `bind-component` で束ねられているコンポーネント要素(親スコープ側のノード)。
123
115
  * マッピング規則の引き当てに使う。optional なのはテスト用モック互換のため。
124
116
  */
125
- readonly boundComponent?: Element | null;
126
117
  /**
127
118
  * この state の実体が innerState proxy(= 値の正本が親スコープの state にある
128
119
  * mapped な `bind-component`)か。真のときだけ越境アドレスの受け渡しと
129
120
  * リストパスの外向き伝播が働く(§1.8)。
130
121
  * optional なのはテスト用モック互換のため(undefined は plain 扱い)。
131
122
  */
132
- readonly hasMappedComponentState?: boolean;
133
- markComponentStateMapped?(): void;
123
+ /**
124
+ * この state element にマウント(Phase 2 の単一ツリー — webComponent/mount.ts)が
125
+ * 1 つでも登録されているか。偽のとき getByAddress / isCacheable / `$n` 補正は
126
+ * boolean 判定 1 個でオーバーレイ経路を抜ける(設計書 D18)。
127
+ * optional なのはテスト用モック互換のため(undefined は「マウント無し」扱い)。
128
+ */
129
+ readonly hasMounts?: boolean;
130
+ markHasMounts?(): void;
131
+ /**
132
+ * この state element に接ぎ木済みのボリューム(`mount=` — webComponent/volume.ts)が
133
+ * 1 つでもあるか。偽のとき setByAddress の D22 後段ガード(マウントポイントを含む
134
+ * 親の丸ごと書き検査)は boolean 判定 1 個で抜ける(設計書 D18 と同じ形)。
135
+ * optional なのはテスト用モック互換のため(undefined は「ボリューム無し」扱い)。
136
+ */
137
+ readonly hasGraftedVolumes?: boolean;
138
+ markHasGraftedVolumes?(): void;
134
139
  /**
135
140
  * この state 要素に束ねられた(`setPathInfo` を通った)パスの集合。丸ごとマウント
136
141
  * (ルート規則)の親→子通知が「登録済みパス全部を読み直せ」を組み立てるのに使う
137
142
  * (webComponent/rootReloadPaths.ts)。
138
143
  * optional なのはテスト用モック互換のため(undefined は「登録なし」扱い)。
139
144
  */
140
- readonly boundPaths?: ReadonlySet<string>;
141
145
  /**
142
146
  * DCC の `$bindables` から生成した「パス → 変更イベント名」表。
143
147
  * 唯一の書き手は defineDCC で、読み手は setByAddress。
@@ -191,13 +195,20 @@ interface IStateElement {
191
195
  * `source` は存在検査の診断 code と適用範囲を決める(pathDiagnostics.ts)。
192
196
  * 省略時は `"binding"`(テスト用モック互換のため optional)。
193
197
  */
198
+ /** ボリュームの宣言面の合流(webComponent/volume.ts 専用・実装は State のみ) */
199
+ addVolumeWatchPaths?(paths: ReadonlySet<string>): void;
200
+ mergeVolumeListKeys?(entries: ReadonlyMap<string, ListKeySpec>): void;
201
+ enableUpdatedCallback?(): void;
202
+ /** enable-ssr スナップショットから初期化されたか(D14)。 */
203
+ readonly hydratedFromSsr?: boolean;
204
+ /** ボリュームのアクセサ登録(webComponent/volume.ts 専用) */
205
+ defineTreeAccessor(path: string, descriptor: PropertyDescriptor): void;
194
206
  setPathInfo(path: string, bindingType: BindingType, source?: PathInfoSource): void;
195
207
  addStaticDependency(parentPath: string, childPath: string): boolean;
196
208
  addDynamicDependency(fromPath: string, toPath: string): boolean;
197
209
  createStateAsync(mutability: Mutability, callback: (state: IStateProxy) => Promise<void>): Promise<void>;
198
210
  createState(mutability: Mutability, callback: (state: IStateProxy) => void): void;
199
211
  nextVersion(): number;
200
- bindProperty(prop: string, desc: PropertyDescriptor): void;
201
212
  setInitialState(state: Record<string, any>): void;
202
213
  }
203
214
 
@@ -232,7 +243,6 @@ interface IStateAddress {
232
243
  readonly parentAddress: IStateAddress | null;
233
244
  }
234
245
  interface IAbsolutePathInfo {
235
- readonly stateName: string;
236
246
  readonly stateElement: IStateElement;
237
247
  readonly pathInfo: IPathInfo;
238
248
  readonly parentAbsolutePathInfo: IAbsolutePathInfo | null;
@@ -276,7 +286,6 @@ interface IParsedBinding {
276
286
  readonly propModifiers: string[];
277
287
  readonly statePathName: string;
278
288
  readonly statePathInfo: IPathInfo;
279
- readonly stateName: string;
280
289
  readonly inFilters: IFilterInfo[];
281
290
  readonly outFilters: IFilterInfo[];
282
291
  readonly bindingType: BindingType;
@@ -371,7 +380,6 @@ declare function getBindingsReady(rootNode: Node): Promise<void>;
371
380
  declare const HTMLElementBase: typeof HTMLElement;
372
381
 
373
382
  interface ISsrElement {
374
- readonly name: string;
375
383
  readonly version: string;
376
384
  readonly stateData: IState;
377
385
  readonly templates: Map<string, HTMLTemplateElement>;
@@ -383,7 +391,6 @@ declare class Ssr extends HTMLElementBase implements ISsrElement {
383
391
  private _stateData;
384
392
  private _templates;
385
393
  private _hydrateProps;
386
- get name(): string;
387
394
  get version(): string;
388
395
  get stateData(): IState;
389
396
  get templates(): Map<string, HTMLTemplateElement>;
@@ -400,7 +407,7 @@ declare class Ssr extends HTMLElementBase implements ISsrElement {
400
407
  private _loadStateData;
401
408
  private _loadTemplates;
402
409
  private _loadHydrateProps;
403
- static findByName(root: Node, name: string): ISsrElement | null;
410
+ static find(root: Node): ISsrElement | null;
404
411
  /**
405
412
  * stateData と構造テンプレート・プロパティから <wcs-ssr> の中身を構築する。
406
413
  * server パッケージの renderToString から呼ばれる。
@@ -758,12 +765,11 @@ interface IWcsManifest {
758
765
  pathDelimiter: string;
759
766
  /** ワイルドカード(`*`) */
760
767
  wildcard: string;
761
- /** バインディング構文 `[prop][#mod]: [path][@state][|filter...]` の区切り文字 */
768
+ /** バインディング構文 `[prop][#mod]: [path][|filter...]` の区切り文字 */
762
769
  delimiters: {
763
770
  binding: string;
764
771
  propValue: string;
765
772
  modifier: string;
766
- stateName: string;
767
773
  filter: string;
768
774
  };
769
775
  /** 構造ディレクティブ(`<template data-wcs="for: ...">` 等) */
@@ -828,12 +834,10 @@ declare function getWcsManifest(): IWcsManifest;
828
834
 
829
835
  type DevtoolsEvent = {
830
836
  readonly type: "state:element-registered";
831
- readonly name: string;
832
837
  readonly rootNode: Node;
833
838
  readonly element: IStateElement;
834
839
  } | {
835
840
  readonly type: "state:element-unregistered";
836
- readonly name: string;
837
841
  readonly rootNode: Node;
838
842
  readonly element: IStateElement;
839
843
  } | {
@@ -860,7 +864,6 @@ type DevtoolsEvent = {
860
864
  } | {
861
865
  readonly type: "state:token-emit";
862
866
  readonly kind: "command" | "event";
863
- readonly stateName: string | null;
864
867
  readonly tokenName: string;
865
868
  readonly args: readonly unknown[];
866
869
  readonly subscriberCount: number;
@@ -868,7 +871,6 @@ type DevtoolsEvent = {
868
871
  readonly type: "state:watch-error";
869
872
  /** throw 元。cur の評価(getter)とハンドラ本体では原因も直し方も違う */
870
873
  readonly phase: "prime" | "evaluate" | "handler";
871
- readonly stateName: string;
872
874
  /** `$watch` の宣言キー(ワイルドカードを含む生のパス) */
873
875
  readonly path: string;
874
876
  readonly error: unknown;
@@ -879,21 +881,18 @@ type DevtoolsEvent = {
879
881
  readonly paths: readonly string[];
880
882
  } | {
881
883
  readonly type: "state:watch-fired";
882
- readonly stateName: string;
883
884
  /** `$watch` の宣言キー(ワイルドカードを含む生のパス) */
884
885
  readonly path: string;
885
886
  } | {
886
887
  readonly type: "state:path-unresolved";
887
888
  /** 書き手が書いた面。診断 code が binding / watch で変わる */
888
889
  readonly source: "binding" | "watch";
889
- readonly stateName: string;
890
890
  /** 宣言されたパス(ワイルドカードを含む生の文字列) */
891
891
  readonly path: string;
892
892
  /** 解決に失敗したセグメント */
893
893
  readonly missingSegment: string;
894
894
  } | {
895
895
  readonly type: "state:binding-apply-error";
896
- readonly stateName: string;
897
896
  /** バインディングの state パス(ワイルドカードを含む生の文字列) */
898
897
  readonly path: string;
899
898
  readonly bindingType: string;
@@ -991,6 +990,8 @@ declare class State extends HTMLElementBase implements IStateElement {
991
990
  static getBindingsReady(rootNode: Node): Promise<void>;
992
991
  private __state;
993
992
  private _hasUpdatedCallback;
993
+ /** enable-ssr のスナップショットから初期化された(D14: ボリュームはデータを採用する) */
994
+ private _hydratedFromSsr;
994
995
  private _crossRowListPaths;
995
996
  private _indexDependentGetterPaths;
996
997
  private _name;
@@ -1018,7 +1019,14 @@ declare class State extends HTMLElementBase implements IStateElement {
1018
1019
  private _rootNode;
1019
1020
  private _boundComponent;
1020
1021
  private _boundComponentStateProp;
1021
- private _hasMappedComponentState;
1022
+ private _hasMounts;
1023
+ private _hasGraftedVolumes;
1024
+ /** ボリューム(mount=): 接ぎ木済みの控え($disconnectedCallback 用) */
1025
+ private _volumeGraftInfo;
1026
+ /** ボリューム: スロット予約済み・接ぎ木進行中(ロード完了前の再接続の再入ガード) */
1027
+ private _volumeInitializing;
1028
+ /** v2 マウント(Phase 2): この bind-component 要素が構築したマウント記録 */
1029
+ private _mountRecord;
1022
1030
  private _bindableEventMap;
1023
1031
  private _commandTokenNames;
1024
1032
  private _eventTokenNames;
@@ -1030,42 +1038,24 @@ declare class State extends HTMLElementBase implements IStateElement {
1030
1038
  private set _state(value);
1031
1039
  get name(): string;
1032
1040
  private _loadFromSsrElement;
1033
- private _initialize;
1034
- private _initializeBindWebComponent;
1041
+ /** state / src / json / inner <script> / API set のソース解決(_initialize とボリュームで共用)。 */
1042
+ private _loadStateFromSource;
1035
1043
  /**
1036
- * Light DOM の mapped コンポーネントが、自分のサブツリーのバインディングを張る(§1.13)。
1037
- *
1038
- * Shadow DOM 形では子スコープが別 rootNode にあり、`setStateElementByName` の初回登録から
1039
- * その root ぶんの `buildBindings` が別パスとして起動する。Light DOM ではホストと同じ root に
1040
- * いるためそのパスが存在せず、かといってホストのパスに混ぜると `@name` の解決が
1041
- * この要素の名前登録より先に来てしまう。そこで `getSubscriberNodes` がホスト側の走査から
1042
- * このサブツリーを外し、名前登録が済んだここで同じことを自前で行う。
1043
- *
1044
- * `{{ }}` の変換だけはホストのパスが root 全体に対して済ませている(純粋にテキスト操作で
1045
- * state に依存しないため)。構造フラグメントの収集は fragment info を rootNode + state 名で
1046
- * 登録するので state 依存であり、ホストのパスからは外してここで走らせる。
1047
- *
1048
- * ループ文脈を null で渡すのは Shadow DOM 形(`initializeBindings(shadowRoot, null)`)と
1049
- * 揃えるため —— 子孫の `getLoopContextByNode` はコンポーネント要素まで遡って
1050
- * 親スコープの行を見つける。
1044
+ * ボリューム(`<wcs-state mount="path">`): 独立ツリーを持たず、ロード完了で
1045
+ * ルートに接ぎ木する(webComponent/volume.ts)。接続時にスロットを予約(D22)。
1046
+ * ルートより先に接続されてもよい ルート登録が保留分を引き取る(V5)。
1051
1047
  */
1052
- private _initializeLightDomComponentScope;
1048
+ private _initializeVolume;
1049
+ private _initialize;
1053
1050
  /**
1054
- * mapped な `bind-component` が切断 再接続したときに、束ねているパスを読み直させる(§1.9)。
1055
- *
1056
- * リスト行の content は再利用されるので、行が作り直されると子はこの経路を通る
1057
- * (`_initialized` が真なので `_initializeBindWebComponent` / `_initialize` は走らず、
1058
- * 子のバインディングは張り直されない)。切断中に親で起きた変更の通知は
1059
- * `applyChangeToWebComponent` が切断済みを理由に落としているため、ここで読み直さないと
1060
- * 子のビューだけが古い値のまま取り残される。何が変わったかは分からないので、
1061
- * プライマリ規則の粒度で丸ごと読み直す。
1062
- *
1063
- * 読み直しの前に派生規則の memo を捨てる。派生規則の購読者(親スコープに立つ
1064
- * バインディング)は切断で teardown されており、memo が残っていると導出が二度と
1065
- * 走らないため購読者も張り直されない = 以後この子だけがサブパスの書き込みを
1066
- * 受け取れなくなる。捨てておけば、直後の読み直しで導出と購読者登録が走る。
1051
+ * 設定エラーでの fail-fast。initializePromise 等を解決してから raise する —
1052
+ * 未解決のまま投げると waitForStateInitialize(ホストの buildBindings)が
1053
+ * この要素を待ち続け、**ページ全体が無言でウェッジする**(1 つの設定ミスが
1054
+ * 無関係なバインディングまで道連れにする)。エラー自体は unhandled rejection
1055
+ * として loud に残る。
1067
1056
  */
1068
- private _reloadMappedPathsAfterReconnect;
1057
+ private _failInitialization;
1058
+ private _initializeBindWebComponent;
1069
1059
  private _callStateConnectedCallback;
1070
1060
  private _initializeDCC;
1071
1061
  private _callStateDisconnectedCallback;
@@ -1078,6 +1068,21 @@ declare class State extends HTMLElementBase implements IStateElement {
1078
1068
  get listKeys(): ListKeyMap | null;
1079
1069
  get watchPaths(): ReadonlySet<string> | null;
1080
1070
  get elementPaths(): Set<string>;
1071
+ /**
1072
+ * ボリューム(webComponent/volume.ts)のアクセサ登録: ツリーパスをキーにした
1073
+ * quoted-path アクセサを state オブジェクトに定義し、getter / setter 台帳と
1074
+ * 依存グラフに載せる。ルートのワイルドカード getter(`"children.*.label"`)と
1075
+ * 同じ機構に乗るので、評価は pushAddress 下・依存はグラフに載る。
1076
+ */
1077
+ /** ボリュームの watch パスをホットパス用ゲート(watchPaths)へ合流させる。 */
1078
+ addVolumeWatchPaths(paths: ReadonlySet<string>): void;
1079
+ /** ボリュームの $listKeys(接頭辞翻訳済み)をルートの表へ合流させる。衝突は設定ミス。 */
1080
+ mergeVolumeListKeys(entries: ReadonlyMap<string, ListKeySpec>): void;
1081
+ /** ボリュームが $updatedCallback を持つとき、収集ゲートを開ける(apply/applyChange.ts)。 */
1082
+ enableUpdatedCallback(): void;
1083
+ /** enable-ssr スナップショットから初期化されたか(D14 — webComponent/volume.ts が読む)。 */
1084
+ get hydratedFromSsr(): boolean;
1085
+ defineTreeAccessor(path: string, descriptor: PropertyDescriptor): void;
1081
1086
  get getterPaths(): Set<string>;
1082
1087
  get setterPaths(): Set<string>;
1083
1088
  get loopContextStack(): ILoopContextStack;
@@ -1085,20 +1090,13 @@ declare class State extends HTMLElementBase implements IStateElement {
1085
1090
  get staticDependency(): Map<string, string[]>;
1086
1091
  get version(): number;
1087
1092
  get rootNode(): Node;
1088
- /**
1089
- * `rootNode` を保持しているか = `createState` を呼んでよいか(§1.9)。
1090
- * disconnect で落ち、connect の冒頭で復活する。
1091
- */
1092
- get hasRootNode(): boolean;
1093
1093
  get boundComponentStateProp(): string | null;
1094
- get boundComponent(): Element | null;
1095
- get hasMappedComponentState(): boolean;
1096
- get boundPaths(): ReadonlySet<string>;
1097
- /**
1098
- * この state の実体が innerState proxy であることを記録する。唯一の呼び手は
1099
- * `bindWebComponent` の mapped 分岐(§1.8)。
1100
- */
1101
- markComponentStateMapped(): void;
1094
+ get hasMounts(): boolean;
1095
+ /** 唯一の呼び手は webComponent/mount.ts の registerMountRecord(Phase 2)。 */
1096
+ markHasMounts(): void;
1097
+ get hasGraftedVolumes(): boolean;
1098
+ /** 唯一の呼び手は webComponent/volume.ts graftVolume(D22 後段のガードが読む)。 */
1099
+ markHasGraftedVolumes(): void;
1102
1100
  get bindableEventMap(): Record<string, string>;
1103
1101
  get commandTokenNames(): ReadonlySet<string>;
1104
1102
  get eventTokenNames(): ReadonlySet<string>;
@@ -1140,7 +1138,6 @@ declare class State extends HTMLElementBase implements IStateElement {
1140
1138
  addCrossRowListPath(path: string): void;
1141
1139
  get indexDependentGetterPaths(): ReadonlySet<string>;
1142
1140
  addIndexDependentGetterPath(path: string): void;
1143
- bindProperty(prop: string, desc: PropertyDescriptor): void;
1144
1141
  setInitialState(state: Record<string, any>): void;
1145
1142
  }
1146
1143