@wcstack/state 2.6.1 → 3.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.
Files changed (64) hide show
  1. package/README.ja.md +91 -46
  2. package/README.md +93 -46
  3. package/dist/auto.min.js +1 -1
  4. package/dist/auto.min.js.map +1 -1
  5. package/dist/define.d.ts +295 -0
  6. package/dist/define.js +1 -0
  7. package/dist/index.d.ts +252 -94
  8. package/dist/index.esm.js +1 -23477
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/manifest.esm.js +21 -37
  11. package/dist/parser.d.ts +37 -39
  12. package/dist/parser.esm.js +147 -1153
  13. package/dist/split/chunks/binder.js +2 -0
  14. package/dist/split/chunks/binder.js.map +1 -0
  15. package/dist/split/chunks/checkDependency.js +2 -0
  16. package/dist/split/chunks/checkDependency.js.map +1 -0
  17. package/dist/split/chunks/diagnosticsHooks.js +2 -0
  18. package/dist/split/chunks/diagnosticsHooks.js.map +1 -0
  19. package/dist/split/chunks/errorGuidance.js +2 -0
  20. package/dist/split/chunks/errorGuidance.js.map +1 -0
  21. package/dist/split/chunks/features.d.ts +29 -0
  22. package/dist/split/chunks/filterRegistry.js +2 -0
  23. package/dist/split/chunks/filterRegistry.js.map +1 -0
  24. package/dist/split/chunks/getAllPropertyDescriptors.js +2 -0
  25. package/dist/split/chunks/getAllPropertyDescriptors.js.map +1 -0
  26. package/dist/split/chunks/lifecycleHooks.js +2 -0
  27. package/dist/split/chunks/lifecycleHooks.js.map +1 -0
  28. package/dist/split/chunks/mount.js +2 -0
  29. package/dist/split/chunks/mount.js.map +1 -0
  30. package/dist/split/chunks/pathDiagnostics.js +2 -0
  31. package/dist/split/chunks/pathDiagnostics.js.map +1 -0
  32. package/dist/split/chunks/registerComponents.js +2 -0
  33. package/dist/split/chunks/registerComponents.js.map +1 -0
  34. package/dist/split/chunks/setAll.js +2 -0
  35. package/dist/split/chunks/setAll.js.map +1 -0
  36. package/dist/split/chunks/version.js +2 -0
  37. package/dist/split/chunks/version.js.map +1 -0
  38. package/dist/split/chunks/watchRuntime.js +2 -0
  39. package/dist/split/chunks/watchRuntime.js.map +1 -0
  40. package/dist/split/core.d.ts +1417 -0
  41. package/dist/split/core.js +2 -0
  42. package/dist/split/core.js.map +1 -0
  43. package/dist/split/features/devtools.d.ts +9 -0
  44. package/dist/split/features/devtools.js +2 -0
  45. package/dist/split/features/devtools.js.map +1 -0
  46. package/dist/split/features/diagnostics.d.ts +11 -0
  47. package/dist/split/features/diagnostics.js +2 -0
  48. package/dist/split/features/diagnostics.js.map +1 -0
  49. package/dist/split/features/formats.d.ts +10 -0
  50. package/dist/split/features/formats.js +2 -0
  51. package/dist/split/features/formats.js.map +1 -0
  52. package/dist/split/features/recursion.d.ts +9 -0
  53. package/dist/split/features/recursion.js +2 -0
  54. package/dist/split/features/recursion.js.map +1 -0
  55. package/dist/split/features/scopes.d.ts +10 -0
  56. package/dist/split/features/scopes.js +2 -0
  57. package/dist/split/features/scopes.js.map +1 -0
  58. package/dist/split/features/ssr.d.ts +9 -0
  59. package/dist/split/features/ssr.js +2 -0
  60. package/dist/split/features/ssr.js.map +1 -0
  61. package/dist/split/features/temporal.d.ts +9 -0
  62. package/dist/split/features/temporal.js +2 -0
  63. package/dist/split/features/temporal.js.map +1 -0
  64. package/package.json +13 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.js","sources":["../../../../../src/dcc/addressHooks.ts","../../../../../src/dcc/dispatchBindableEvent.ts","../../../../../src/dcc/dccPropertyFactories.ts","../../../../../src/dcc/processDccDeclarations.ts","../../../../../src/dcc/defineDCC.ts","../../../../../src/dcc/wcBindable.ts","../../../../../src/dcc/dccLifecycle.ts","../../../../../src/webComponent/volumeShared.ts","../../../../../src/webComponent/exportIndex.ts","../../../../../src/webComponent/overlay.ts","../../../../../src/webComponent/mountScope.ts","../../../../../src/webComponent/addressHooks.ts","../../../../../src/webComponent/volumeLifecycle.ts","../../../../../src/webComponent/volume.ts","../../../../../src/webComponent/completeWebComponent.ts","../../../../../src/webComponent/preCompletionWrites.ts","../../../../../src/webComponent/componentApply.ts","../../../../../src/webComponent/meltFrozenObject.ts","../../../../../src/webComponent/stateElementByWebComponent.ts","../../../../../src/webComponent/outerState.ts","../../../../../src/webComponent/bindWebComponent.ts","../../../../../src/webComponent/ownKeyShadow.ts","../../../../../src/webComponent/bindComponentLifecycle.ts","../../../../../src/webComponent/rootMountBinding.ts","../../../../../src/features/scopes.ts"],"sourcesContent":["/**\n * dcc/addressHooks.ts — `$bindables` を持つ DCC の state に付く hook(設計案 H1、S3)。\n * 書き込み・`$postUpdate` の後の bindable イベント dispatch を core から移し、\n * `$bindables` の無い state では一切走らない。\n */\nimport { IAddressHooks, registerFeatureHooks } from \"../core/addressHooks\";\nimport { dispatchBindableEvent } from \"./dispatchBindableEvent\";\n\nexport const dccAddressHooks: IAddressHooks = {\n // DCC bindable イベントディスパッチ(完全一致 + サブパス → 先頭セグメント、§2.1)\n written: dispatchBindableEvent,\n};\n\nlet installed = false;\n/** 冪等。full エントリでは State が `$bindables` の束ね先になった時点で呼ぶ */\nexport function installDccHooks(): void {\n if (installed) return;\n installed = true;\n registerFeatureHooks(\"dcc\", dccAddressHooks);\n}\n","import { IPathInfo } from \"../address/types\";\nimport { IStateElement } from \"../components/types\";\n\n/**\n * DCC の `$bindables` メンバの変更イベントを host に dispatch する。\n *\n * 対応するのは 3 通り。\n *\n * 1. **完全一致** — `count = 1` が `count` メンバを撃つ。`detail` は書き込んだ値。\n * 2. **サブパス** — `user.name = \"x\"` や `items.0.done = true` が `user` / `items` メンバを撃つ。\n * `$bindables` のエントリは常にフラットなトップレベル名(dotted 名は\n * processDccDeclarations の存在検査で落ちる)なので、先頭セグメントを見れば足りる。\n * この場合 `detail` は付かない — メンバ全体ではない値を載せると誤解を招くため。\n * 3. **`$postUpdate`** — in-place 変異を通知する正規の idiom。書き込んだ値が無いので `detail` は付かない。\n *\n * `detail` に頼らないのが正しい読み方で、`createWcBindable` は各 property に\n * `getter: (event) => event.target[name]` を宣言している。observer はイベントを\n * 「変わった」という通知として受け取り、値は要素から読む。\n *\n * 従来は完全一致しか見ておらず、`$bindables: [\"user\"]` で `user.name` を書いても\n * 発火しなかった。wc-bindable の `properties[].event` は「変更で発火する」契約なので乖離していた\n * (docs/architecture-hardening/15-state-component-mechanism-consistency.md §2.1)。\n *\n * 配列の in-place 変異(`items.push(...)`)は set トラップを通らないため、ここでも捕まらない。\n * これはリアクティブコア全体の規範(in-place 変異は `$postUpdate` で通知する)と同じで、\n * 正しい idiom を踏めば 3 で発火する。\n *\n * `$listKeys` を宣言したリストは、配列代入がキー突合後に per-path 書き込みへ分解されるため\n * (docs/state-list-key-design.md §2)、1 回の代入で `1 + 変化行数` 回発火する。値は要素から\n * 読む契約なので結果は変わらない。詳細は上記 §2.1 の「`$listKeys` との相互作用」。\n */\nexport function dispatchBindableEvent(\n stateElement: IStateElement,\n pathInfo: IPathInfo,\n detail?: { readonly value: unknown },\n): void {\n const map = stateElement.bindableEventMap;\n const exactEventName = map[pathInfo.path];\n const isExact = typeof exactEventName === \"string\";\n const eventName = isExact\n ? exactEventName\n : (pathInfo.segments.length > 1 ? map[pathInfo.segments[0]] : undefined);\n if (typeof eventName !== \"string\") {\n return;\n }\n const rootNode = stateElement.rootNode;\n if (!(rootNode instanceof ShadowRoot)) {\n return;\n }\n rootNode.host.dispatchEvent(new CustomEvent(eventName, {\n // 完全一致のときだけ、書き込んだ値をそのまま載せる(従来互換)。\n detail: isExact && typeof detail !== \"undefined\" ? detail.value : undefined,\n bubbles: true,\n }));\n}\n","import { IStateElement } from \"../components/types\";\n\ninterface IDCCElement extends HTMLElement {\n readonly stateElement: IStateElement | null;\n}\n\nexport function getterFn(name: string) {\n return function (this: IDCCElement) {\n const stateEl = this.stateElement;\n if (!stateEl) return undefined;\n // state のロード前は「まだ値が無い」だけで異常ではない。行がまだ fragment 上にある間の\n // 初期スナップショット読み(BindingSession.readProducerSnapshot)は必ずここを通るので、\n // warn を出すと通常フローが騒がしくなる\n // (docs/architecture-hardening/15-state-component-mechanism-consistency.md §2.2)。\n if (stateEl.initialized !== true) return undefined;\n let value: any;\n try {\n stateEl.createState(\"readonly\", (state) => {\n value = state[name];\n });\n } catch (e) {\n console.warn(`[@wcstack/state] DCC getter \"${name}\" failed:`, e);\n return undefined;\n }\n return value;\n };\n}\n\nexport function setterFn(name: string) {\n return function (this: IDCCElement, value: any) {\n const stateEl = this.stateElement;\n if (!stateEl) return;\n // 初期化済みなら同期で書く。getter は同期なので、ここを常に initializePromise 経由に\n // すると `el.count = 5; el.count` が旧値を返す(§2.2)。未初期化のときだけ遅延させる\n // = 未接続の行に書かれた値が捨てられないための経路(§1.4)はそのまま残る。\n if (stateEl.initialized === true) {\n stateEl.createState(\"writable\", (state) => {\n state[name] = value;\n });\n return;\n }\n stateEl.initializePromise.then(() => {\n stateEl.createState(\"writable\", (state) => {\n state[name] = value;\n });\n });\n };\n}\n\nexport function callFn(name: string, isAsync: boolean) {\n // 戻り値は常に Promise。state 側のメソッドが同期でも初期化待ちが挟まりうるため、\n // 呼び出し側から見た型を揃える(wcBindable.commands が一律 `async: true` を宣言するのと対)。\n if (isAsync) {\n return function (this: IDCCElement, ...args: any[]) {\n const stateEl = this.stateElement;\n if (!stateEl) return undefined;\n return stateEl.initializePromise.then(() => {\n let result: any;\n return stateEl.createStateAsync(\"writable\", async (state) => {\n result = await state[name](...args);\n }).then(() => result);\n });\n };\n }\n return function (this: IDCCElement, ...args: any[]) {\n const stateEl = this.stateElement;\n if (!stateEl) return undefined;\n return stateEl.initializePromise.then(() => {\n let result: any;\n stateEl.createState(\"writable\", (state) => {\n result = state[name](...args);\n });\n return result;\n });\n };\n}\n\nexport function isInternalProperty(name: string): boolean {\n return name.startsWith(\"$\");\n}\n","/**\n * DCC の `$bindables` / `$commands` 宣言を解析・検証する。\n *\n * 検証の強度は `$commandTokens` / `$eventTokens` と揃える\n * (docs/architecture-hardening/15-state-component-mechanism-consistency.md §1.5 / §2.3 / §1.6)。\n * 従来 `$bindables` は `Array.isArray(...) ? ... : []` だけで、\n *\n * - 非配列を無言で空扱いにする\n * - 重複名をそのまま `createWcBindable` に流す\n * - `$` 始まりの名前を通す\n * - state に存在しない名前を通す\n *\n * という 4 つの穴があった。特に重複は害が大きい: `readNamedList`(protocol/wcBindableReader.ts)は\n * 重複名を見つけると `null` を返すため、`readBindableDeclaration()` が宣言全体を棄却し、\n * 双方向バインド・spread・initialSync の bindable 判定が**警告なしで**丸ごと死ぬ。\n * 自前のファクトリが自前の reader に棄却される状態なので、生成前に落とす。\n */\n\nimport { STATE_BINDABLES_NAME, STATE_COMMANDS_NAME, STATE_STREAMS_NAME } from \"../define\";\nimport { didYouMean } from \"../errorGuidance\";\nimport { getAllPropertyDescriptors } from \"../getAllPropertyDescriptors\";\nimport { raiseError } from \"../raiseError\";\nimport { IState } from \"../types\";\n\n/**\n * did-you-mean の候補(エラーパス専用)。`$` 予約名と継承 `constructor` を除き、\n * `$bindables` には値プロパティだけ・`$commands` にはメソッドだけを提案する\n * (逆側を提案すると次は「is a method / is not a method」エラーに嵌まるため)。\n */\nfunction dccCandidateNames(\n descriptors: Record<string, PropertyDescriptor>,\n kind: \"value\" | \"method\",\n): string[] {\n return Object.keys(descriptors).filter((key) => {\n if (key.startsWith(\"$\") || key === \"constructor\") {\n return false;\n }\n const isMethod = typeof descriptors[key].value === \"function\";\n return kind === \"method\" ? isMethod : !isMethod;\n });\n}\n\nfunction readNameList(state: IState, declarationName: string): string[] | null {\n const declared = (state as Record<string, unknown>)[declarationName];\n if (typeof declared === \"undefined\") {\n return null;\n }\n if (!Array.isArray(declared)) {\n raiseError(`${declarationName} must be an array of strings.`);\n }\n const names: string[] = [];\n const seen = new Set<string>();\n for (const name of declared) {\n if (typeof name !== \"string\" || name.length === 0) {\n raiseError(`${declarationName} entries must be non-empty strings.`);\n }\n if (name.startsWith(\"$\")) {\n raiseError(`${declarationName} entry \"${name}\" must not start with \"$\" (internal properties are not exposed on the component).`);\n }\n if (seen.has(name)) {\n raiseError(`${declarationName} entry \"${name}\" is duplicated.`);\n }\n seen.add(name);\n names.push(name);\n }\n return names;\n}\n\n/**\n * `$streams` が宣言している名前。値プロパティはインスタンス側の実体化まで state 上に\n * 現れないため、存在検査ではここも「実在する名前」として扱う(§2.3)。\n * 宣言そのものの妥当性検査は processStreamsDeclaration の責務なので、ここでは\n * キーの取り出しだけを行い、形が違えば黙って空集合を返す。\n */\nfunction getStreamNames(state: IState): Set<string> {\n const declared = (state as Record<string, unknown>)[STATE_STREAMS_NAME];\n if (typeof declared !== \"object\" || declared === null) {\n return new Set<string>();\n }\n return new Set(Object.keys(declared));\n}\n\nexport interface IDccDeclarations {\n /** 観測可能プロパティ。DCC prototype には getter/setter が生える */\n readonly bindables: string[];\n /** 起動可能メソッド。DCC prototype にはメソッドが生える */\n readonly commands: string[];\n /** `$streams` 由来でアクセサを追加生成すべき名前(state 上に descriptor が無いもの) */\n readonly streamBackedBindables: string[];\n}\n\nexport function processDccDeclarations(state: IState): IDccDeclarations {\n const bindables = readNameList(state, STATE_BINDABLES_NAME) ?? [];\n const commands = readNameList(state, STATE_COMMANDS_NAME) ?? [];\n\n const descriptors = getAllPropertyDescriptors(state);\n const streamNames = getStreamNames(state);\n const streamBackedBindables: string[] = [];\n\n for (const name of bindables) {\n const descriptor = descriptors[name];\n if (typeof descriptor === \"undefined\") {\n // `$streams` 由来なら実体化後に現れるので通す。アクセサはこちらで補う。\n if (streamNames.has(name)) {\n streamBackedBindables.push(name);\n continue;\n }\n raiseError(`${STATE_BINDABLES_NAME} entry \"${name}\" is not declared on the state.${didYouMean(name, dccCandidateNames(descriptors, \"value\"))}`);\n }\n if (typeof descriptor.value === \"function\") {\n raiseError(`${STATE_BINDABLES_NAME} entry \"${name}\" is a method. Declare it in ${STATE_COMMANDS_NAME} instead.`);\n }\n }\n\n for (const name of commands) {\n const descriptor = descriptors[name];\n if (typeof descriptor === \"undefined\") {\n raiseError(`${STATE_COMMANDS_NAME} entry \"${name}\" is not declared on the state.${didYouMean(name, dccCandidateNames(descriptors, \"method\"))}`);\n }\n if (typeof descriptor.value !== \"function\") {\n raiseError(`${STATE_COMMANDS_NAME} entry \"${name}\" is not a method. Declare it in ${STATE_BINDABLES_NAME} instead.`);\n }\n }\n\n return { bindables, commands, streamBackedBindables };\n}\n","import { IState } from \"../types\";\nimport { installDccHooks } from \"./addressHooks\";\nimport { DCC_DEFINITION_ATTRIBUTE, STATE_BINDABLES_NAME } from \"../define\";\nimport { config } from \"../config\";\nimport { raiseError } from \"../raiseError\";\nimport { getterFn, setterFn, callFn, isInternalProperty } from \"./dccPropertyFactories\";\nimport { processDccDeclarations } from \"./processDccDeclarations\";\nimport { createWcBindable, createBindableEventMap, IWcBindable } from \"./wcBindable\";\nimport { getAllPropertyDescriptors } from \"../getAllPropertyDescriptors\";\nimport { getCustomElementRegistry, upgradeCustomElement } from \"../platform/customElementRegistry\";\n// 具象 State ではなくインターフェースに依存する(dcc → components の逆参照を断つ、§3.5)。\nimport type { IStateElement } from \"../components/types\";\n\nexport function defineDCC(hostElement: Element, shadowRoot: ShadowRoot, state: IState): void {\n const tagName = hostElement.tagName.toLowerCase();\n\n // バリデーション\n if (!tagName.includes(\"-\")) {\n raiseError(`DCC: \"${tagName}\" is not a valid custom element name (must contain a hyphen).`);\n }\n // 定義先は「定義元ホストを支配するレジストリ」。scoped registry を持つツリーで\n // global に define すると、その定義は自分の兄弟にすら適用されない。\n const definitionRegistry = getCustomElementRegistry(hostElement);\n if (definitionRegistry === null || typeof definitionRegistry.define !== \"function\") {\n raiseError(`DCC: CustomElementRegistry is unavailable for \"${tagName}\".`);\n }\n if (definitionRegistry.get(tagName)) {\n // 重複定義は authoring error として落とす。従来は warn してスキップしていたが、\n // 先勝ちで別テンプレートのインスタンスが生えるため「動いているように見えて中身が違う」\n // 状態になる。state 名の重複(stateElementByName)が raiseError なのと作法を揃える\n // (docs/architecture-hardening/15-state-component-mechanism-consistency.md §3.4)。\n // 一意性はレジストリ単位なので、別スコープの同名 DCC は衝突しない。\n raiseError(`DCC: \"${tagName}\" is already registered. A custom element name can only be defined once.`);\n }\n\n // ShadowRoot 自体は cloneNode 不可なので、子ノードを 1 つずつ template へ取り込む。\n //\n // かつては `template.innerHTML = shadowRoot.innerHTML` と serialize → parse で\n // 往復していた。これをやめたのは 3 点の理由による(docs/csp.md §7):\n // (1) `require-trusted-types-for 'script'` 下では innerHTML sink が弾かれる。\n // ここはテンプレート=作者が書いた DOM の複製でしかないので、policy を作って\n // 署名するより sink 自体を無くすほうが筋が良い(state が CSP の\n // `trusted-types` allowlist を要求しなくなる)。\n // (2) 往復のたびに HTML パーサの再解釈が挟まり、元の DOM と一致しない結果に\n // なり得る(mXSS と同じ機序)。\n // (3) 単純に serialize + parse のぶん遅い。\n //\n // importNode は **取り込み先 document** で要素を作るため、template の inert な\n // contents document 側から呼べば従来どおり「未 upgrade の複製」になる。live\n // document 側で cloneNode すると upgrade reaction が走り、_ensureShadow の明示\n // upgrade と二重になる。\n //\n // 挙動差が 1 つある: script 要素の already-started フラグは複製時に引き継がれる\n // ため、テンプレート内のインライン `<script>` はインスタンス生成のたびにネイティブ\n // 実行されなくなる。`<wcs-state>` の状態定義スクリプトは text を読んで評価する実装\n // (loadFromInnerScript)なので影響を受けない。\n const template = document.createElement(\"template\");\n const inertDocument = template.content.ownerDocument;\n for (const childNode of Array.from(shadowRoot.childNodes)) {\n template.content.appendChild(inertDocument.importNode(childNode, true));\n }\n const shadowRootMode = shadowRoot.mode as ShadowRootMode;\n\n // $bindables / $commands から wcBindable + bindableEventMap を生成\n const { bindables, commands, streamBackedBindables } = processDccDeclarations(state);\n const wcBindable: IWcBindable | null = (bindables.length > 0 || commands.length > 0)\n ? createWcBindable(tagName, bindables, commands)\n : null;\n const bindableEventMap: Record<string, string> = bindables.length > 0\n ? createBindableEventMap(tagName, bindables)\n : {};\n\n // DCC クラス生成\n const stateTagSelector = config.tagNames.state;\n\n const DCCElement = class extends HTMLElement {\n static template = template;\n static shadowRootMode = shadowRootMode;\n static wcBindable = wcBindable;\n static bindableEventMap = bindableEventMap;\n\n private _shadow: ShadowRoot | null = null;\n\n /**\n * shadow を遅延構築する。定義要素(`data-wc-definition`)では null を返す。\n *\n * connectedCallback ではなくここで張るのは、**接続前にアクセサが呼ばれる**ため\n * (§1.4)。`for` の全追加パスは行を fragment に組み立ててからバインドを適用し、\n * fragment を DOM に挿すのは最後なので、`element.count = v` の時点で行はまだ未接続。\n * shadow が無いと `stateElement` が null になり、setterFn が無言で書き込みを捨てていた。\n * ここで構築しておけば、書き込みは inner `<wcs-state>` の initializePromise に\n * 積まれ、接続・state ロード後に適用される。\n *\n * 冪等なので再接続でも張り直さない。shadow tree は host の切断後も保持され、\n * 2 回目の attachShadow は NotSupportedError になる(§1.3)。`if` の false→true\n * 再マウントと `for` の行プーリングはどちらも同一ノードを unmount → mount する。\n * closed mode では `this.shadowRoot` が null なので判定はフィールド側で行う。\n *\n * G4 は「constructor へ前倒し」で決着したが、実装は constructor ではなく\n * この遅延構築を採った。目的(未接続でもアクセサが動く)は同じで、constructor 版だと\n * (1) 定義要素の判定に属性を読む必要があり constructor の作法に反する、\n * (2) 同一タグの `data-wc-definition` が 2 つある場合、DSD の shadow を既に持つ\n * 2 つ目に attachShadow して throw する、の 2 点を踏むため。\n */\n private _ensureShadow(): ShadowRoot | null {\n if (this._shadow !== null) return this._shadow;\n if (this.hasAttribute(DCC_DEFINITION_ATTRIBUTE)) return null;\n this._shadow = this.attachShadow({ mode: DCCElement.shadowRootMode });\n this._shadow.appendChild(DCCElement.template.content.cloneNode(true));\n // template.content は inert なテンプレート所有ドキュメントに属するため、その clone は\n // カスタム要素として upgrade されていない。ホストが接続済みなら appendChild の時点で\n // upgrade されるが、未接続の shadow に挿した場合は upgrade 契機が無く、内側の\n // <wcs-state> が素の HTMLElement のまま残って createState が生えない。明示的に upgrade する。\n const registry = getCustomElementRegistry(this._shadow);\n if (registry !== null) {\n upgradeCustomElement(registry, this._shadow);\n }\n return this._shadow;\n }\n\n connectedCallback() {\n const shadow = this._ensureShadow();\n if (shadow === null) return;\n\n // bindableEventMap の設定。\n // initializePromise は待たない。待つと state のロード完了まで map が空のままで、\n // $connectedCallback 内で行った初期変更が変更イベントを出さない\n // (docs/architecture-hardening/15-state-component-mechanism-consistency.md §2.7)。\n // setBindableEventMap はフィールド代入だけで state を参照しないので、\n // <wcs-state> の初期化前に呼んでも安全。\n if (Object.keys(DCCElement.bindableEventMap).length > 0) {\n const stateEl = shadow.querySelector(stateTagSelector) as IStateElement | null;\n if (stateEl) {\n // 書き込み後の bindable イベントを撃つ hook を、束ねる時点で install する(設計案 H1)\n installDccHooks();\n stateEl.setBindableEventMap(DCCElement.bindableEventMap);\n } else {\n // $bindables を宣言しているのに束ねる先が無い。この分岐に落ちると\n // 変更イベントが一切出ないまま静かに壊れる\n // (docs/architecture-hardening/15-state-component-mechanism-consistency.md §2.5)。\n console.warn(`[@wcstack/state] DCC: \"${tagName}\" declares ${STATE_BINDABLES_NAME} but its template has no <${config.tagNames.state}>. Change events will not be dispatched.`);\n }\n }\n }\n\n get stateElement(): IStateElement | null {\n // 未接続でも shadow を構築して解決する(§1.4)。\n return (this._ensureShadow()?.querySelector(stateTagSelector) ?? null) as IStateElement | null;\n }\n };\n\n // state プロパティを走査して DCC クラスのプロトタイプにgetter/setter/methodを定義。\n // 走査範囲は State の getterPaths / setterPaths 収集と同じ「自身+プロトタイプチェーン」に\n // 揃える。own descriptor だけを見ていた頃は、クラスインスタンスや Object.create(proto) の\n // state で「getterPaths には載るのにアクセサが生えない」乖離が出ていた\n // (docs/architecture-hardening/15-state-component-mechanism-consistency.md §2.4)。\n const descriptors = getAllPropertyDescriptors(state);\n for (const [name, desc] of Object.entries(descriptors)) {\n if (isInternalProperty(name)) continue;\n\n const newDesc: PropertyDescriptor = { configurable: true, enumerable: true };\n if (typeof desc.value === \"function\") {\n const isAsync = desc.value.constructor?.name === \"AsyncFunction\";\n newDesc.value = callFn(name, isAsync);\n } else {\n newDesc.get = getterFn(name);\n newDesc.set = setterFn(name);\n }\n Object.defineProperty(DCCElement.prototype, name, newDesc);\n }\n\n // `$streams` の値プロパティはインスタンス側の processStreamsDeclaration で実体化されるため、\n // defineDCC の時点では state 上に descriptor が無い。$bindables に載っているのに\n // アクセサが生えないと宣言だけが生きて要素側が expando を掴むので、ここで補う(§2.3)。\n for (const name of streamBackedBindables) {\n Object.defineProperty(DCCElement.prototype, name, {\n configurable: true,\n enumerable: true,\n get: getterFn(name),\n set: setterFn(name),\n });\n }\n\n // カスタム要素登録\n definitionRegistry.define(tagName, DCCElement);\n}\n","// wc-bindable protocol manifest types — single source of truth in /protocol/wc-bindable.ts.\nexport type {\n IWcBindable, IWcBindableProperty, IWcBindableInput, IWcBindableCommand,\n} from \"../protocol/wcBindable.js\";\n// This module also uses the types in its runtime helpers below, so import them into scope.\nimport type {\n IWcBindable, IWcBindableCommand, IWcBindableInput, IWcBindableProperty,\n} from \"../protocol/wcBindable.js\";\n\nexport function createWcBindable(\n tagName: string,\n bindables: string[],\n commands: string[] = [],\n): IWcBindable {\n const properties: IWcBindableProperty[] = bindables.map((propName) => ({\n name: propName,\n event: `${tagName}:${propName}-changed`,\n // Read the member off the element instead of trusting event.detail. The event is a\n // notification, not a carrier: a sub-path write (`user.name = \"x\"` against a `user`\n // member) has no single value to put in detail, and a state-side setter may normalize\n // what was written. Both cases are correct through the property.\n getter: (event: Event) => (event.target as unknown as Record<string, unknown>)[propName],\n }));\n // Every $bindables member gets both a getter and a setter on the DCC prototype,\n // so declare it in inputs as well — a property declared only in `properties` is\n // output-only under directional initial sync, which would permanently block\n // parent-state → DCC writes.\n const inputs: IWcBindableInput[] = bindables.map((propName) => ({\n name: propName,\n }));\n const declaration: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties,\n inputs,\n };\n if (commands.length === 0) {\n return declaration;\n }\n // `async: true` is uniform on purpose: dccPropertyFactories.callFn always chains on the\n // inner <wcs-state>'s initializePromise, so a DCC command returns a Promise whether or not\n // the underlying state method was declared `async`. Reporting the state method's own\n // asyncness would describe something callers never observe.\n const declaredCommands: IWcBindableCommand[] = commands.map((name) => ({\n name,\n async: true,\n }));\n return { ...declaration, commands: declaredCommands };\n}\n\nexport function createBindableEventMap(tagName: string, bindables: string[]): Record<string, string> {\n const map: Record<string, string> = {};\n for (const propName of bindables) {\n map[propName] = `${tagName}:${propName}-changed`;\n }\n return map;\n}\n","/**\n * dcc/dccLifecycle.ts — DCC 定義要素(`[data-wc-definition]` ホストの ShadowRoot 内の `<wcs-state>`)の\n * 接続(設計案 H3、S4)。この `<wcs-state>` は自分のツリーを持たない: ソースを読み、ホストの\n * テンプレートからカスタム要素を定義して(defineDCC)初期化を終える。\n *\n * 従来 `State.connectedCallback` の先頭の分岐と private メソッド `_initializeDCC` だったもの。\n * 聞く順は order 10 — ボリューム(20)・bind-component(30)より先という従来の分岐順を番号で固定する。\n * 要素から要るのは内部面の 5 つ(`failInitializeLoudly` / `markTreeless` / `markInitialized` /\n * `clearConnectedRootNode` / `settleInitialization`)だけ。\n */\nimport type { IStateElement } from \"../components/types\";\nimport { ILifecycleHooks, registerLifecycleHooks } from \"../core/lifecycleHooks\";\nimport { DCC_DEFINITION_ATTRIBUTE } from \"../define\";\nimport { raiseError } from \"../raiseError\";\nimport { loadFromInnerScript } from \"../stateLoader/loadFromInnerScript\";\nimport { loadFromScriptFile } from \"../stateLoader/loadFromScriptFile\";\nimport { IState } from \"../types\";\nimport { defineDCC } from \"./defineDCC\";\n\nasync function loadDccState(el: HTMLElement, hostElement: Element): Promise<IState> {\n try {\n if (el.hasAttribute('src')) {\n const src = el.getAttribute('src')!;\n if (src.endsWith('.js')) {\n return await loadFromScriptFile(src);\n }\n raiseError(`DCC: Unsupported src type: ${src}`);\n }\n const script = el.querySelector<HTMLScriptElement>('script[type=\"module\"]');\n if (script) {\n return await loadFromInnerScript(script, hostElement.tagName.toLowerCase());\n }\n raiseError(`DCC: No state source found for \"${hostElement.tagName.toLowerCase()}\".`);\n } catch (e) {\n raiseError(`DCC: Failed to load state: ${e}`);\n }\n}\n\nasync function initializeDcc(element: IStateElement, hostElement: Element, shadowRoot: ShadowRoot): Promise<void> {\n const el = element as unknown as HTMLElement;\n try {\n // DCC と bind-component は排他。DCC の state はテンプレートに属し、\n // インスタンスごとにロードされるので、定義時点のホストのプロパティを\n // ソースにする bind-component とは両立しない。従来はこの return で\n // 無言に無視していた(docs/architecture-hardening/15 §3.1)。\n if (el.hasAttribute(\"bind-component\")) {\n raiseError(`\"bind-component\" cannot be used inside a [${DCC_DEFINITION_ATTRIBUTE}] host. DCC state comes from the template, not from a component property.`);\n }\n const state = await loadDccState(el, hostElement);\n defineDCC(hostElement, shadowRoot, state);\n // 自分のツリーを持たない: 再接続でこの rootNode のツリーとして登録し直さない\n element.markTreeless!();\n element.markInitialized!();\n element.clearConnectedRootNode!(); // disconnectedCallbackでのstate参照を防止\n element.settleInitialization!();\n } catch (error) {\n // _initialize と同じ着地(#257)。DCC のロード失敗もここまでは\n // 「throw が connectedCallback の外へ出るだけ」= 無言のハングだった\n element.failInitializeLoudly!(error);\n }\n}\n\nexport const dccLifecycleHooks: ILifecycleHooks = {\n order: 10,\n connecting(element) {\n // DCC 検出: ShadowRoot 内かつホストに data-wc-definition がある場合\n const parentNode = (element as unknown as HTMLElement).parentNode;\n if (!(parentNode instanceof ShadowRoot) || !parentNode.host.hasAttribute(DCC_DEFINITION_ATTRIBUTE)) {\n return null;\n }\n return initializeDcc(element, parentNode.host, parentNode);\n },\n};\n\nlet installed = false;\n/** 冪等。full / auto では `bootstrapState()` が呼ぶ */\nexport function installDccLifecycle(): void {\n if (installed) return;\n installed = true;\n registerLifecycleHooks(\"dcc\", dccLifecycleHooks);\n}\n","/**\n * webComponent/volumeShared.ts — ボリュームの軽量共有面。\n *\n * ホットパス(proxy/methods/getByAddress・proxy/apis/updatedCallback・pathDiagnostics)が\n * 引く台帳と chroot だけを置く。graft 本体(webComponent/volume.ts)は watch runtime 等の\n * 重い依存を持つため、ここに混ぜると「updater を部分モックするテスト」が import 連鎖で\n * 壊れる(watchRuntime は import 時に drain リスナーを登録する)。\n */\n\nimport { DELIMITER } from \"../define\";\nimport { raiseError } from \"../raiseError\";\nimport { IStateElement } from \"../components/types\";\n\n/**\n * 予約済みスロット(D22)。キーは rootNode、値はマウントパス → 予約した要素(所有者)。\n * 所有者が `null` の枠は持ち主を手放した枠(#265): 読みの寛容(予約下の読みは undefined・\n * 存在の診断は黙る)はそのまま残し、同じマウントパスを別の要素が予約できる。\n */\nconst reservedSlotsByRootNode = new WeakMap<Node, Map<string, object | null>>();\n\nexport function reserveVolumeSlot(rootNode: Node, mountPath: string, owner: object): void {\n let slots = reservedSlotsByRootNode.get(rootNode);\n if (typeof slots === \"undefined\") {\n slots = new Map();\n reservedSlotsByRootNode.set(rootNode, slots);\n }\n const current = slots.get(mountPath);\n if (typeof current !== \"undefined\" && current !== null) {\n raiseError(`Volume slot \"${mountPath}\" is already mounted on this tree.`);\n }\n slots.set(mountPath, owner);\n}\n\n/**\n * 予約を手放す(#265)。`owner` がその枠を予約した要素のときだけ手放す。\n *\n * 所有者を確かめずに手放すと、枠を失った要素(孤児・ロード失敗)の後始末が、同じマウントパスで\n * 後から予約した**生きている別の要素**の枠を奪う(#257 第 3 ラウンドで実測した横取り)。\n * 呼び手は予約した `(rootNode, mountPath)` の組を自分で控えておき、それを渡すこと —\n * 切断時の rootNode や `mount` 属性から読み直した組は、予約した組と一致する保証が無い。\n *\n * 台帳から消さずに持ち主だけを外すのは、読みの寛容を残すため。消すと、接ぎ木しなかった\n * ボリュームの配下を読むページ(ルートの getter・バインド)が「存在しないパス」の raise に変わり、\n * ロード失敗を 1 ボリュームに閉じる規範が破れる。\n */\nexport function releaseVolumeSlot(rootNode: Node, mountPath: string, owner: object): void {\n const slots = reservedSlotsByRootNode.get(rootNode);\n if (slots?.get(mountPath) === owner) {\n slots.set(mountPath, null);\n }\n}\n\n/**\n * パスが予約済みスロットの配下(または祖先)か。pathDiagnostics と getByAddress の\n * ルート欠落 raise が「予約下の読みは undefined が正」(D22)のために引く。\n */\nexport function isPathUnderReservedVolume(rootNode: Node | null, path: string): boolean {\n if (rootNode === null) {\n return false;\n }\n const slots = reservedSlotsByRootNode.get(rootNode);\n if (typeof slots === \"undefined\" || slots.size === 0) {\n return false;\n }\n for (const slot of slots.keys()) {\n if (path === slot || path.startsWith(slot + DELIMITER) || slot.startsWith(path + DELIMITER)) {\n return true;\n }\n }\n return false;\n}\n\n/** このルートに予約(手放した枠も台帳に残る)があるか — ルート登録時にスコープ機能の hook を付ける判定 */\nexport function hasReservedVolumeSlots(rootNode: Node): boolean {\n const slots = reservedSlotsByRootNode.get(rootNode);\n return typeof slots !== \"undefined\" && slots.size > 0;\n}\n\n/**\n * 接ぎ木済みスロット(D22 後段)。キーはルートの state element。\n * setByAddress のガード(findGraftedSlotUnder)と graftVolume(recordGraftedSlot)が使う。\n * 予約(reservedSlots)と別台帳なのは、接ぎ木**前**の中間 `{}` 生成\n * (graftVolume の親作成)をガードに掛けないため。\n */\nconst graftedSlotsByStateElement = new WeakMap<IStateElement, Set<string>>();\n\nexport function recordGraftedSlot(stateElement: IStateElement, mountPath: string): void {\n let slots = graftedSlotsByStateElement.get(stateElement);\n if (typeof slots === \"undefined\") {\n slots = new Set();\n graftedSlotsByStateElement.set(stateElement, slots);\n }\n slots.add(mountPath);\n}\n\n/**\n * 書き込みパスが接ぎ木済みスロットの**真の祖先**なら、そのスロットを返す(D22 後段)。\n * マウントポイントを含む親の丸ごと書きは、接ぎ木データを無言で捨てて quoted-path\n * アクセサだけを宙に浮かせるため throw の根拠になる。スロット自身への書き込みは\n * 通常のデータ差し替えなので対象外。`hasGraftedVolumes` が真のときだけ呼ぶこと。\n */\nexport function findGraftedSlotUnder(stateElement: IStateElement, path: string): string | null {\n const slots = graftedSlotsByStateElement.get(stateElement);\n if (typeof slots === \"undefined\" || slots.size === 0) {\n return null;\n }\n const prefix = path + DELIMITER;\n for (const slot of slots) {\n if (slot.startsWith(prefix)) {\n return slot;\n }\n }\n return null;\n}\n\n/** ボリュームの chroot(相対キー → `<mountPath>.<key>` を receiver に翻訳する薄い proxy)。 */\nexport function createVolumeChroot(mountPath: string, receiver: any): Record<string, any> {\n return new Proxy({} as Record<string, any>, {\n get(_target, prop): any {\n if (typeof prop !== \"string\" || prop === \"then\") {\n return undefined;\n }\n if (prop[0] === \"$\") {\n if (prop === \"$postUpdate\") {\n return (path: string): void => {\n receiver.$postUpdate(mountPath + DELIMITER + path);\n };\n }\n if (prop === \"$getAll\" || prop === \"$setAll\" || prop === \"$resolve\") {\n const api = prop;\n return (path: string, ...rest: unknown[]): unknown =>\n receiver[api](mountPath + DELIMITER + path, ...rest);\n }\n // 他の `$` は親の意味論のまま(宣言面はボリュームが登録時に翻訳する)\n return receiver[prop];\n }\n return receiver[mountPath + DELIMITER + prop];\n },\n set(_target, prop, value): boolean {\n if (typeof prop !== \"string\") {\n return true;\n }\n receiver[mountPath + DELIMITER + prop] = value;\n return true;\n },\n has(_target, prop): boolean {\n // ボリュームの面はツリーそのもの — マウント配下は常に解決する\n return typeof prop === \"string\" && prop[0] !== \"$\" && prop[0] !== \"#\";\n },\n });\n}\n\n/** ボリュームの相対 $updatedCallback(ルート state 要素 → 登録リスト)。 */\nexport interface IVolumeUpdatedCallback {\n readonly mountPath: string;\n readonly callback: (this: unknown, paths: string[], indexesListByPath: Record<string, Array<number[]>>) => unknown;\n}\nconst volumeUpdatedCallbacksByRoot = new WeakMap<IStateElement, IVolumeUpdatedCallback[]>();\n\nconst NO_VOLUME_UPDATED_CALLBACKS: readonly IVolumeUpdatedCallback[] = [];\n\nexport function addVolumeUpdatedCallback(stateElement: IStateElement, entry: IVolumeUpdatedCallback): void {\n let callbacks = volumeUpdatedCallbacksByRoot.get(stateElement);\n if (typeof callbacks === \"undefined\") {\n callbacks = [];\n volumeUpdatedCallbacksByRoot.set(stateElement, callbacks);\n }\n callbacks.push(entry);\n // 相対配送はルートに付いた updated hook が行う(接ぎ木が途中で落ちても配送先は付いている)\n stateElement.markHasVolume?.();\n}\n\nexport function getVolumeUpdatedCallbacks(stateElement: IStateElement): readonly IVolumeUpdatedCallback[] {\n return volumeUpdatedCallbacksByRoot.get(stateElement) ?? NO_VOLUME_UPDATED_CALLBACKS;\n}\n\n/**\n * ルート登録待ちのボリューム(stateElementByName が引き取りを起動する)。\n * graft の実体(webComponent/volume.ts)は import 時にハンドラを注入する —\n * stateElementByName → volume の直接 import は updater までの循環を作るため。\n */\nexport interface IPendingVolumeRequest {\n readonly mountPath: string;\n readonly volumeState: Record<string, any>;\n readonly onGrafted: (info: unknown) => void;\n /**\n * 接ぎ木の直前に、要求した要素がマウントの枠を取る(#265)。握っていれば真、空いていれば取り直して真、\n * 別の要素が握っていれば偽(報告は取る側が出す)。ロード中・保留中に外れた要素は枠を返しているので、\n * ここで取り直す — 外れたままでも接ぎ木する従来の着地を保ちつつ、その間に同じマウントパスを取った\n * 別のボリュームと二重に接ぎ木しない。\n */\n readonly acquireSlot: () => boolean;\n}\nconst pendingVolumesByRootNode = new WeakMap<Node, IPendingVolumeRequest[]>();\n\n/**\n * ルートの state 要素が初期化に失敗した rootNode(#257)。ルート登録(setStateElement)は\n * 二度と起きないので `drainPendingVolumes` も呼ばれず、保留中のボリュームの\n * `onGrafted` が走らないまま initializePromise / connectedCallbackPromise が永久に\n * 未解決になる(ルートの診断だけが出て、同じページのボリュームは無言で消える)。\n * 「ルートは来ない」と確定した時点で保留分を孤児として着地させ、以後に届く保留要求も\n * 同じ着地へ合流させる。D11 の「ルート無し」報告はここには出ない — 検査(State.ts の\n * reportVolumeWithoutRoot)は**要素の存在**で見るので、落ちたルート要素が居る限り黙る。\n *\n * 印は**落ちた要素がこの rootNode に居る間だけ**有効(`clearFailedRootNode`)。持続させると、\n * この PR が案内する復旧(壊れた要素を取り除いて作り直す)と矛盾する: 外してから修正版を\n * 接続するまでの窓で接続したボリュームが即座に孤児化し、正しいルートが来ても採用されない。\n */\nconst failedRootNodes = new WeakSet<Node>();\n\n/** 接ぎ木先を失ったボリュームの着地(graftIsolated の失敗と同じ形 — 1 件 1 報告 + finish(null))。 */\nfunction orphanPendingVolume(request: IPendingVolumeRequest): void {\n console.error(\n `[@wcstack/state] volume \"${request.mountPath}\" was not grafted — the root state element ` +\n `on this root node failed to initialize (its own diagnostic is reported separately). ` +\n `The volume is not at fault: fix the root <wcs-state>.`,\n );\n request.onGrafted(null);\n}\n\n/**\n * 失敗の印を落とす(#257)。呼び手は State の `disconnectedCallback` ただ 1 つで、\n * **初期化に失敗した当の要素**が剥がされたときだけ呼ぶ — 落ちたルートが DOM から\n * 消えた時点で「このルートノードにルートは来ない」は成り立たなくなる(作者は\n * 取り除いて作り直す)。\n *\n * 呼び手を本人に限るのは第 3 ラウンドの修正: 「初期化前に剥がされた要素」全部で\n * 落としていたため、同じ rootNode の別要素(登録されなかった 2 本目・行プールの\n * 張り直し・ロード中の DOM 移動)の切断で印が消え、以後のボリュームが孤児報告を\n * 受けられず永久保留へ戻っていた。\n */\nexport function clearFailedRootNode(rootNode: Node): void {\n failedRootNodes.delete(rootNode);\n}\n\n/** ルートの初期化失敗を確定し、保留中のボリュームを孤児として着地させる(State の _failInitializeLoudly が唯一の呼び手)。 */\nexport function failPendingVolumes(rootNode: Node): void {\n failedRootNodes.add(rootNode);\n const pending = pendingVolumesByRootNode.get(rootNode);\n if (typeof pending === \"undefined\") {\n // 保留はまだ無い(ボリュームのロードのほうが遅い形)— 下の queuePendingVolume が拾う\n return;\n }\n pendingVolumesByRootNode.delete(rootNode);\n for (const request of pending) {\n orphanPendingVolume(request);\n }\n}\n\nlet graftHandler: ((rootStateElement: IStateElement, request: IPendingVolumeRequest) => void) | null = null;\n\nexport function setVolumeGraftHandler(handler: (rootStateElement: IStateElement, request: IPendingVolumeRequest) => void): void {\n graftHandler = handler;\n}\n\nexport function queuePendingVolume(rootNode: Node, request: IPendingVolumeRequest): void {\n if (failedRootNodes.has(rootNode)) {\n // ルートが落ちた後に届いた保留要求(ボリュームのロードのほうが遅い形)。\n // 積んでも引き取り手は永久に来ない\n orphanPendingVolume(request);\n return;\n }\n let pending = pendingVolumesByRootNode.get(rootNode);\n if (typeof pending === \"undefined\") {\n pending = [];\n pendingVolumesByRootNode.set(rootNode, pending);\n }\n pending.push(request);\n}\n\n/** ルート登録時に保留中のボリュームを接ぎ木する(stateElementByName から呼ばれる)。 */\nexport function drainPendingVolumes(rootNode: Node, rootStateElement: IStateElement): void {\n // ルートが成立した = 失敗の印は無効(落ちたルートを外して正しいルートを接続し直した\n // 形。WeakSet.delete は未登録でも安全なので分岐は要らない)\n failedRootNodes.delete(rootNode);\n const pending = pendingVolumesByRootNode.get(rootNode);\n if (typeof pending === \"undefined\" || pending.length === 0 || graftHandler === null) {\n return;\n }\n pendingVolumesByRootNode.delete(rootNode);\n // 登録はルートの _initialize の途中(createState はまだ危うい)— microtask に\n // 遅らせてルートの接続完了後に接ぎ木する\n const handler = graftHandler;\n queueMicrotask(() => {\n for (const request of pending) {\n handler(rootStateElement, request);\n }\n });\n}\n","import { getPathInfo } from \"../address/PathInfo\";\nimport { IStateElement } from \"../components/types\";\nimport { DELIMITER } from \"../define\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { IListIndex } from \"../list/types\";\nimport { setLoopContextSymbol } from \"../proxy/symbols\";\nimport { raiseError } from \"../raiseError\";\nimport { pathDiagnostics } from \"../core/diagnosticsHooks\";\nimport { IExportEntry, IMountRecord, translateInnerPath } from \"./mount\";\n\n/**\n * webComponent/exportIndex.ts — オーバーレイ getter の公開(docs/state-overlay-export-design.md)。\n *\n * 一文: **ツリーに無いキーの読みは、その位置にマウントされたコンポーネントの getter で\n * 答える。ツリーにあるキーはツリーが勝つ。私有キーとメソッドは見せない。**\n *\n * - 索引(X4): 親 state element → 公開パスの親 `P`(`users.*`)→ 接尾キー `k`(`display`)\n * → 記録の集合。引くのは getByAddress / setByAddress の**未存在キー経路**だけで、\n * ツリーに命中する読み書きは今日の経路をそのまま通る(X1・ホットパス不変)\n * - インスタンス解決(X4): 候補記録のうち、ホスト要素のループ文脈 listIndex が\n * 読みの listIndex と一致する(か、その配下にいる)ものを選ぶ。0 件は `undefined`、\n * 2 件以上は raise(同一インスタンスに同名 getter を持つコンポーネントが 2 つ —\n * bind mount の曖昧。設定ミスとして loud)\n * - エイリアス辺(X5): 登録時に `P.#m<id>.k → P.k` を dynamicDependency に張る。\n * 子 getter の dirty が `P.k` の同 listIndex に流れ、`P.k` を読んだ親 getter /\n * バインディングへ届く。\n * `P.k` is absent from getterPaths but wildcard exports use the row cache;\n * alias edges and dirtying after exported writes keep that cache consistent.\n * - 遅延登録・切断(X6): 登録・再接続・切断で `P.k` へ `$postUpdate` を打つ。親 getter は\n * 子の登録前に評価されるので、初回は途中値 → 収束する(ボリュームの D22 と同じ性質)\n */\n\n/** 索引の要素: 記録(WeakRef — byMarker と同じ寿命規約)とその公開エントリ */\ninterface IExportHolder {\n readonly ref: WeakRef<IMountRecord>;\n readonly entry: IExportEntry;\n}\n\ninterface IExportSlot {\n readonly holders: Set<IExportHolder>;\n /** 検証付きキャッシュ(X4): 読みの listIndex → 前回一致した要素。使う前に一致を再確認する */\n readonly byListIndex: WeakMap<IListIndex, IExportHolder>;\n noIndex: IExportHolder | null;\n}\n\nexport interface IResolvedExport {\n readonly record: IMountRecord;\n readonly entry: IExportEntry;\n}\n\nconst exportIndexByStateElement = new WeakMap<IStateElement, Map<string, Map<string, IExportSlot>>>();\nconst reportedShadows = new Set<string>();\n\nexport function clearExportShadowReportsForTesting(): void {\n reportedShadows.clear();\n}\n\n/** テスト用: 索引に任意の WeakRef 風オブジェクトを差し込む(GC 済み記録の遅延 prune を検証する) */\nexport function _setExportRefForTesting(\n stateElement: IStateElement,\n parentPath: string,\n key: string,\n ref: WeakRef<IMountRecord>,\n entry: IExportEntry,\n): void {\n slotFor(stateElement, parentPath, key, true)!.holders.add({ ref, entry });\n}\n\nfunction slotFor(stateElement: IStateElement, parentPath: string, key: string, create: boolean): IExportSlot | null {\n let byParent = exportIndexByStateElement.get(stateElement);\n if (typeof byParent === \"undefined\") {\n if (!create) return null;\n byParent = new Map();\n exportIndexByStateElement.set(stateElement, byParent);\n }\n let byKey = byParent.get(parentPath);\n if (typeof byKey === \"undefined\") {\n if (!create) return null;\n byKey = new Map();\n byParent.set(parentPath, byKey);\n }\n let slot = byKey.get(key);\n if (typeof slot === \"undefined\") {\n if (!create) return null;\n slot = { holders: new Set(), byListIndex: new WeakMap(), noIndex: null };\n byKey.set(key, slot);\n }\n return slot;\n}\n\n/**\n * 記録の getter / setter を公開索引に載せる(初回登録で 1 回・冪等)。\n * translateInnerPath のマーカー化を通すので accessorBySuffixByMarkerParent も同時に埋まる。\n * 翻訳できないアクセサ(ワイルドカード終端・部分マウントのみで接頭辞不一致)と、\n * `$` 名前空間のアクセサ(翻訳されずマーカーが付かない)は公開しない。\n * ルートエントリの無い部分マウントは公開位置(ツリー上のパス)を持たないので対象外。\n */\nexport function registerExports(record: IMountRecord): void {\n if (record.exports.size > 0 || record.rootEntry === null) {\n return;\n }\n const keys = new Set<string>([...record.getterKeys, ...record.setterKeys]);\n for (const key of keys) {\n let markerPath: string;\n try {\n markerPath = translateInnerPath(record, key);\n } catch {\n continue;\n }\n const markerIndex = markerPath.indexOf(DELIMITER + record.marker);\n if (markerIndex === -1) {\n continue;\n }\n // `users.*.#m7.display` → 末端マーカーパス `users.*.#m7`・接尾 `display`・公開 `users.*.display`\n // (接尾は常に非空 — markerizeAccessorPath が空を raise 済み。公開パスはルート\n // エントリの外側パス+接尾なので常に 2 セグメント以上 = 親パスを持つ)\n const markerTerminalPath = markerPath.slice(0, markerIndex + 1 + record.marker.length);\n const suffix = markerPath.slice(markerTerminalPath.length + 1);\n const exportedPath = markerPath.slice(0, markerIndex) + DELIMITER + suffix;\n const exportedInfo = getPathInfo(exportedPath);\n // Internal wildcard accessors need their own row resolution and lifecycle\n // notifications. Only publish accessors at the mount instance's depth.\n if (exportedInfo.wildcardCount !== record.delta) {\n continue;\n }\n const entry: IExportEntry = { markerTerminalPath, suffix, markerPath, exportedPath };\n record.exports.set(exportedPath, entry);\n slotFor(record.parentStateElement, exportedInfo.parentPath!, exportedInfo.lastSegment, true)!\n .holders.add({ ref: new WeakRef(record), entry });\n // エイリアス辺(X5): 子 getter のアドレス → 公開パス\n record.parentStateElement.addDynamicDependency(markerPath, exportedPath);\n // 未存在パスの遅延診断(X7): この公開パスへのバインドは「存在しない」ではない\n pathDiagnostics?.markExported(record.parentStateElement, exportedPath);\n }\n record.parentStateElement.markHasMounts?.();\n}\n\n/** 読みの listIndex がホスト要素のループ文脈と一致するか(配下の深い文脈も一致とみなす) */\nfunction isInstanceOf(record: IMountRecord, listIndex: IListIndex | null): boolean {\n if (!record.component.isConnected) {\n return false;\n }\n const own = getLoopContextByNode(record.component)?.listIndex ?? null;\n if (listIndex === null) {\n return own === null;\n }\n let current: IListIndex | null = own;\n while (current !== null) {\n if (current === listIndex) {\n return true;\n }\n current = current.parentListIndex;\n }\n return false;\n}\n\n/** ホルダーが生きていて、この listIndex のインスタンスなら記録を返す */\nfunction liveInstance(holder: IExportHolder, listIndex: IListIndex | null): IMountRecord | null {\n const record = holder.ref.deref();\n if (typeof record === \"undefined\" || !isInstanceOf(record, listIndex)) {\n return null;\n }\n return record;\n}\n\n/**\n * `P.k`(listIndex)に答える記録を引く。索引に無ければ null(今日どおり undefined 解決)。\n * 複数一致は raise。\n */\nexport function resolveExport(\n stateElement: IStateElement,\n parentPath: string,\n key: string,\n listIndex: IListIndex | null,\n): IResolvedExport | null {\n const slot = slotFor(stateElement, parentPath, key, false);\n if (slot === null) {\n return null;\n }\n const cached = listIndex === null ? slot.noIndex : (slot.byListIndex.get(listIndex) ?? null);\n if (cached !== null) {\n const record = liveInstance(cached, listIndex);\n if (record !== null) {\n return { record, entry: cached.entry };\n }\n }\n let found: IExportHolder | null = null;\n let foundRecord: IMountRecord | null = null;\n for (const holder of slot.holders) {\n const record = holder.ref.deref();\n if (typeof record === \"undefined\") {\n // 記録は回収済み(finalizer 発火前の窓)— 遅延 prune\n slot.holders.delete(holder);\n continue;\n }\n if (!isInstanceOf(record, listIndex)) {\n continue;\n }\n if (foundRecord !== null) {\n raiseError(\n `[wcs/mount-export-ambiguous] \"${parentPath}${DELIMITER}${key}\" is exported by two mounted components on the same instance: ` +\n `<${foundRecord.component.tagName.toLowerCase()}> and <${record.component.tagName.toLowerCase()}>. ` +\n `Mount only one of them there, or rename one accessor. See docs/state-overlay-export-design.md X4.`,\n );\n }\n found = holder;\n foundRecord = record;\n }\n if (found === null || foundRecord === null) {\n return null;\n }\n if (listIndex === null) {\n slot.noIndex = found;\n } else {\n slot.byListIndex.set(listIndex, found);\n }\n return { record: foundRecord, entry: found.entry };\n}\n\n/** 公開パスの `$postUpdate` を、記録のホスト要素のループ文脈で打つ(X6)。 */\nexport function notifyExports(record: IMountRecord): void {\n const parent = record.parentStateElement;\n const loopContext = getLoopContextByNode(record.component);\n if (parent.isConnected === false || (record.delta > 0 && loopContext === null)) {\n // A removed tree needs no notification. A removed row is handled by its\n // parent's list update. Other notification failures must remain visible.\n return;\n }\n for (const entry of record.exports.values()) {\n parent.createState(\"readonly\", (state) => {\n (state as any)[setLoopContextSymbol](loopContext, () => {\n (state as any).$postUpdate(entry.exportedPath);\n });\n });\n }\n}\n\n/**\n * X1: ツリーに同名キーがある公開 getter は親から読まれない(ツリーが勝つ)。\n * 登録時に 1 回 warn(タグ × 公開パス)。行マウントはホスト要素のループ文脈で読む。\n */\nexport function warnShadowedExports(record: IMountRecord): void {\n const loopContext = getLoopContextByNode(record.component);\n if (record.delta > 0 && loopContext === null) {\n // 行マウントでループ文脈が無い(行の実体化前)— 読めないので黙る\n return;\n }\n const tag = record.component.tagName.toLowerCase();\n for (const entry of record.exports.values()) {\n const reportKey = `${tag}|${entry.exportedPath}`;\n if (reportedShadows.has(reportKey)) {\n continue;\n }\n const exportedInfo = getPathInfo(entry.exportedPath);\n let parentValue: unknown = undefined;\n record.parentStateElement.createState(\"readonly\", (state) => {\n (state as any)[setLoopContextSymbol](loopContext, () => {\n parentValue = (state as Record<string, unknown>)[exportedInfo.parentPath!];\n });\n });\n if (parentValue === null || typeof parentValue === \"undefined\"\n || !(exportedInfo.lastSegment in Object(parentValue))) {\n continue;\n }\n reportedShadows.add(reportKey);\n console.warn(\n `[@wcstack/state] [wcs/mount-export-shadowed] <${tag}>.${record.stateProp}.${entry.suffix} is exported at ` +\n `\"${entry.exportedPath}\" but the tree already has that key, so readers outside the component get the tree value. ` +\n `Remove the tree key or rename the accessor. See docs/state-overlay-export-design.md X1.`,\n );\n }\n}\n","import { createStateAddress } from \"../address/StateAddress\";\nimport { getPathInfo } from \"../address/PathInfo\";\nimport { IStateAddress } from \"../address/types\";\nimport { DELIMITER } from \"../define\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { IListIndex } from \"../list/types\";\nimport { checkDependency } from \"../proxy/methods/checkDependency\";\nimport { setLoopContextSymbol } from \"../proxy/symbols\";\nimport { raiseError } from \"../raiseError\";\nimport { IStateHandler, IStateProxy } from \"../proxy/types\";\nimport { composeMountIndexes, IExportEntry, IMountRecord, translateInnerPath, translateInnerWritePath } from \"./mount\";\n\n/**\n * webComponent/overlay.ts — マウントのオーバーレイ(D20 / D21・impl-plan §3-0 の 4)。\n *\n * 親 handler の getByAddress は「**マーカーで終わるパス**(`users.*.#m1`)」に達したとき\n * だけここへ委譲する。返すのは (マウント記録 × マーカー親パス × listIndex) の\n * オーバーレイ値 proxy で、それより深いパスの読み書きは**通常の親ウォークの続き**として\n * この proxy への素の Reflect.get / Reflect.set になる:\n *\n * - `users.*.#m1.editing` の読み → 親ウォークが `#m1` でこの proxy を得て\n * `Reflect.get(proxy, \"editing\")` → 私有データ(listIndex ごとの複製・D21)\n * - `users.*.#m1.editing` への書き込み → setByAddress の fast path が\n * `Reflect.set(proxy, \"editing\", v)` → 私有データへ(enqueue / 依存 walk は\n * setByAddress が済ませている — 通常のツリーキーと同じ経路)\n * - `users.*.#m1.display` の読み → `Reflect.get(proxy, \"display\")` → 作者の getter を\n * **この proxy を `this` に**評価。中の `this.name` は translateInnerPath で\n * `users.*.name` になり、**アクティブな親 receiver** の文字列読みに落ちる —\n * pushAddress 済みなので依存エッジ(users.*.name → users.*.#m1.display)は\n * 素の wildcard getter と同じ機構(checkDependency)で親のグラフに載る\n * - `onclick: save` → 変換済みパス `users.*.#m1.save` の読み → メソッドを\n * この proxy に bind して返す\n *\n * proxy は評価中の (receiver, handler) を閉じ込めるため**キャッシュしない**\n * (isCacheable がマーカー終端を除外する)。私有データそのものは\n * (record, listIndex) ごとに 1 つで、行の swap では listIndex と一緒に動き、\n * 行の差し替えでは新しい listIndex に初期スナップショットから作り直される(D21)。\n */\n\ninterface IPrivateDataTable {\n byListIndex: WeakMap<IListIndex, Record<string, unknown>>;\n noIndex: Record<string, unknown> | null;\n}\n\nconst privateDataByRecord = new WeakMap<IMountRecord, IPrivateDataTable>();\n\n/** マウントインスタンス(record × listIndex)の私有データ。無ければ初期スナップショットから複製 */\nexport function getPrivateData(record: IMountRecord, listIndex: IListIndex | null): Record<string, unknown> {\n let table = privateDataByRecord.get(record);\n if (typeof table === \"undefined\") {\n table = { byListIndex: new WeakMap(), noIndex: null };\n privateDataByRecord.set(record, table);\n }\n if (listIndex === null) {\n return table.noIndex ??= { ...record.privateSnapshot };\n }\n let data = table.byListIndex.get(listIndex);\n if (typeof data === \"undefined\") {\n data = { ...record.privateSnapshot };\n table.byListIndex.set(listIndex, data);\n }\n return data;\n}\n\nclass OverlayValueHandler implements ProxyHandler<Record<string, unknown>> {\n constructor(\n private readonly record: IMountRecord,\n private readonly markerParentPath: string,\n private readonly listIndex: IListIndex | null,\n private readonly isBase: boolean,\n private readonly receiver: any,\n private readonly handler: IStateHandler,\n ) {}\n\n private accessorNameFor(key: string): string | undefined {\n return this.record.accessorBySuffixByMarkerParent.get(this.markerParentPath)?.get(key)?.accessorName;\n }\n\n private accessorAddress(key: string): IStateAddress {\n return createStateAddress(getPathInfo(this.markerParentPath + DELIMITER + key), this.listIndex);\n }\n\n get(target: Record<string, unknown>, prop: string | symbol, _receiver: any): any {\n if (typeof prop !== \"string\") {\n return Reflect.get(target, prop);\n }\n if (prop === \"then\") {\n // Promise と誤認されないための恒例のガード(innerState と同じ)\n return undefined;\n }\n if (prop[0] === \"$\") {\n if (prop === \"$postUpdate\") {\n return (path: string): void => {\n this.receiver.$postUpdate(translateInnerPath(this.record, path));\n };\n }\n // §4-6(P2-9): 相対パス → 接頭辞合成 → ルート API。作者のスコープ相対 indexes の\n // 先頭に、評価中のマーカーアドレスの行添字(=翻訳で増えたワイルドカード分)を足す\n if (prop === \"$getAll\" || prop === \"$setAll\" || prop === \"$resolve\") {\n const record = this.record;\n const contextIndexes = this.listIndex?.indexes ?? [];\n const receiver = this.receiver;\n if (prop === \"$resolve\") {\n return (path: string, indexes: number[] | undefined, ...rest: unknown[]): unknown => {\n // 書き込み形(第 3 引数あり)は読み取り専用マウントを検査する(要件 B14 ①)\n const translated = rest.length > 0 ? translateInnerWritePath(record, path) : translateInnerPath(record, path);\n const composed = composeMountIndexes(record, path, translated, indexes ?? [], contextIndexes);\n return receiver.$resolve(translated, composed, ...rest);\n };\n }\n const api = prop;\n return (path: string, indexes?: number[], ...rest: unknown[]): unknown => {\n const translated = api === \"$setAll\" ? translateInnerWritePath(record, path) : translateInnerPath(record, path);\n const composed = composeMountIndexes(record, path, translated, indexes, contextIndexes);\n return receiver[api](translated, composed, ...rest);\n };\n }\n // `$1` 等は親トラップの Δ 補正がスコープ相対にする。他の `$` API は\n // 親スコープの意味論のまま(接頭辞翻訳は P2-9 — §4-6 の表)\n return this.receiver[prop];\n }\n const accessorName = this.accessorNameFor(prop);\n if (typeof accessorName !== \"undefined\") {\n // 作者の getter を chroot(この proxy)を `this` に評価。マーカーパスを push して\n // 中の読みが依存エッジ(read → このアクセサ)として親グラフに載るようにする\n this.handler.pushAddress(this.accessorAddress(prop));\n try {\n return Reflect.get(this.record.stateObject, accessorName, _receiver);\n } finally {\n this.handler.popAddress();\n }\n }\n if (this.isBase) {\n if (Object.prototype.hasOwnProperty.call(target, prop)) {\n // 私有データの読みはオーバーレイ内で完結し親 proxy を通らないので、\n // 依存エッジ(この私有キー → 評価中の getter)だけは明示的に登録する。\n // 登録しないと `this.suffix` を読む getter が私有キーの書き込みで再評価されない\n checkDependency(this.handler, this.accessorAddress(prop));\n return target[prop];\n }\n const method = this.record.stateObject[prop];\n if (typeof method === \"function\") {\n return method.bind(_receiver);\n }\n }\n // ツリー(規則 3): アクティブな親 receiver の文字列読みに落とす。\n // ループ文脈は push 済みの外側アドレス(マーカー親のワイルドカード)から解決される\n return this.receiver[translateInnerPath(this.record, prop)];\n }\n\n set(target: Record<string, unknown>, prop: string | symbol, value: any, _receiver: any): boolean {\n if (typeof prop !== \"string\") {\n return Reflect.set(target, prop, value);\n }\n const accessorName = this.accessorNameFor(prop);\n if (typeof accessorName !== \"undefined\") {\n if (!this.record.setterKeys.has(accessorName)) {\n // setter の無い getter(computed)への書き込み。下のツリー行きフォールバックへ\n // 落とすと translateInnerPath が同じマーカーパスを返して set が循環し\n // RangeError(無限再帰)になる — 設定ミスとして loud に落とす\n raiseError(\n `Cannot write to \"${accessorName}\" on mounted <${this.record.component.tagName.toLowerCase()}>: ` +\n `the accessor has no setter. Add a setter or write to the underlying state paths instead.`,\n );\n }\n // setter は命令的な代入(依存を張らない)— setByAddress の setter 規約に合わせる\n this.handler.pushAddress(this.accessorAddress(prop));\n this.handler.beginUntrack();\n try {\n return Reflect.set(this.record.stateObject, accessorName, value, _receiver);\n } finally {\n this.handler.endUntrack();\n this.handler.popAddress();\n }\n }\n if (this.isBase && Object.prototype.hasOwnProperty.call(target, prop)) {\n target[prop] = value;\n return true;\n }\n this.receiver[translateInnerWritePath(this.record, prop)] = value;\n return true;\n }\n\n has(target: Record<string, unknown>, prop: string | symbol): boolean {\n if (typeof prop !== \"string\") {\n return Reflect.has(target, prop);\n }\n if (prop[0] === \"$\" || prop[0] === \"#\") {\n return false;\n }\n if (typeof this.accessorNameFor(prop) !== \"undefined\") {\n return true;\n }\n if (this.isBase) {\n if (Object.prototype.hasOwnProperty.call(target, prop)) {\n return true;\n }\n if (typeof this.record.stateObject[prop] === \"function\") {\n return true;\n }\n }\n // 規則 3(ツリー): v1 innerState の has と同じ「規則が解決するか」の意味論。\n // 親 proxy の has は生オブジェクトの Reflect.has なので、複数セグメントの\n // 翻訳後パスを in で聞いても常に偽 — 値の存在でなく規則の存在で答える\n try {\n translateInnerPath(this.record, prop);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * マーカーで終わるアドレスのオーバーレイ値を作る(getByAddress の dispatch 点)。\n * 評価中の receiver / handler を閉じ込めるため、呼び出しごとに作る(キャッシュ不可)。\n */\nexport function createOverlayValue(\n record: IMountRecord,\n address: IStateAddress,\n receiver: any,\n handler: IStateHandler,\n): object {\n const markerParentPath = address.pathInfo.path;\n const isBase = markerParentPath === record.markerBasePath;\n const privateData = isBase ? getPrivateData(record, address.listIndex) : {};\n return new Proxy(privateData, new OverlayValueHandler(\n record,\n markerParentPath,\n address.listIndex,\n isBase,\n receiver,\n handler,\n ));\n}\n\n/**\n * 公開 getter の読み(docs/state-overlay-export-design.md §2-1 の 4)。\n * `P.#m<id>` のオーバーレイ値に対する `Reflect.get(proxy, k)` と等価 — 作者の getter は\n * マーカーアドレスを push して評価されるので、依存辺・キャッシュはマーカー側に載る。\n */\nexport function readExportedAccessor(\n record: IMountRecord,\n entry: IExportEntry,\n listIndex: IListIndex | null,\n receiver: any,\n handler: IStateHandler,\n): unknown {\n const address = createStateAddress(getPathInfo(entry.markerTerminalPath), listIndex);\n const proxy = createOverlayValue(record, address, receiver, handler);\n return Reflect.get(proxy, entry.suffix);\n}\n\n/** 公開 getter への書き込み(X9): setter があれば評価、無ければ overlay の set が raise する。 */\nexport function writeExportedAccessor(\n record: IMountRecord,\n entry: IExportEntry,\n listIndex: IListIndex | null,\n value: unknown,\n receiver: any,\n handler: IStateHandler,\n): boolean {\n const address = createStateAddress(getPathInfo(entry.markerTerminalPath), listIndex);\n const proxy = createOverlayValue(record, address, receiver, handler);\n return Reflect.set(proxy, entry.suffix, value);\n}\n\n/**\n * `element.state` の公開面(chroot・M13)。相対キーを変換して親の proxy を通すだけの\n * 薄い翻訳で、値の解決(私有・getter・ツリー)は全て親ウォーク+オーバーレイが担う。\n * ホスト要素のループ文脈で包む(行マウント `state: .` の `users.*.…` を解決するため —\n * v1 の outerState → innerState と同じ形)。\n */\nfunction createChrootDollarApi(\n record: IMountRecord,\n api: \"$getAll\" | \"$setAll\" | \"$resolve\" | \"$postUpdate\",\n withHostContext: <T>(state: IStateProxy, callback: () => T) => T,\n): (...args: any[]) => unknown {\n const parent = record.parentStateElement;\n const call = (mutability: \"readonly\" | \"writable\", fn: (state: any) => unknown): unknown => {\n let result: unknown;\n parent.createState(mutability, (state) => {\n result = withHostContext(state as IStateProxy, () => fn(state));\n });\n return result;\n };\n if (api === \"$postUpdate\") {\n return (path: string) => call(\"readonly\", (state) => state.$postUpdate(translateInnerPath(record, path)));\n }\n return (path: string, indexes?: number[], ...rest: unknown[]) => {\n const writes = api === \"$setAll\" || (api === \"$resolve\" && rest.length > 0);\n const translated = writes ? translateInnerWritePath(record, path) : translateInnerPath(record, path);\n const contextIndexes = getLoopContextByNode(record.component)?.listIndex.indexes ?? [];\n // $resolve は indexes 必須の API(省略は空列と同義に倒す)。書き込み形(第 3 引数あり)は writable\n const composed = composeMountIndexes(\n record, path, translated, api === \"$resolve\" ? (indexes ?? []) : indexes, contextIndexes);\n const mutability = writes ? \"writable\" : \"readonly\";\n return call(mutability, (state) => state[api](translated, composed, ...rest));\n };\n}\n\nexport function createPublicMountState(record: IMountRecord): Record<string, any> {\n const parent = record.parentStateElement;\n const withHostContext = <T>(state: IStateProxy, callback: () => T): T => {\n const loopContext = getLoopContextByNode(record.component);\n let result!: T;\n state[setLoopContextSymbol](loopContext, () => {\n result = callback();\n });\n return result;\n };\n return new Proxy({} as Record<string, any>, {\n get(_target, prop): any {\n if (typeof prop !== \"string\" || prop === \"then\") {\n return undefined;\n }\n // §4-6(P2-9): 相対パス → 接頭辞合成 → ルート API(chroot 面)。\n // 先頭添字はホスト要素のループ文脈から補う\n if (prop === \"$getAll\" || prop === \"$setAll\" || prop === \"$resolve\" || prop === \"$postUpdate\") {\n return createChrootDollarApi(record, prop, withHostContext);\n }\n let value: unknown;\n parent.createState(\"readonly\", (state) => {\n value = withHostContext(state as IStateProxy, () =>\n (state as Record<string, unknown>)[prop[0] === \"$\" ? prop : translateInnerPath(record, prop)]);\n });\n return value;\n },\n set(_target, prop, value): boolean {\n if (typeof prop !== \"string\") {\n return true;\n }\n parent.createState(\"writable\", (state) => {\n withHostContext(state as IStateProxy, () => {\n (state as Record<string, unknown>)[prop[0] === \"$\" ? prop : translateInnerWritePath(record, prop)] = value;\n });\n });\n return true;\n },\n has(_target, prop): boolean {\n if (typeof prop !== \"string\" || prop[0] === \"$\" || prop[0] === \"#\") {\n return false;\n }\n // 作者の面(私有キー・アクセサ・メソッド)はオブジェクトの own property\n if (Object.prototype.hasOwnProperty.call(record.stateObject, prop)) {\n return true;\n }\n // ツリーは「規則が解決するか」(v1 innerState の has と同じ意味論 — ルート\n // マウントでは常に真、部分マウントのみでは接頭辞が一致するときだけ真)\n try {\n translateInnerPath(record, prop);\n return true;\n } catch {\n return false;\n }\n },\n });\n}\n","import { applyChangeFromBindings } from \"../apply/applyChangeFromBindings\";\nimport { getOrCreateBindingSession } from \"../bindings/BindingSession\";\nimport { getLoopContextByNode, setLoopContextByNode } from \"../list/loopContextByNode\";\nimport { initializeBindings } from \"../bindings/initializeBindings\";\nimport { convertMustacheToComments } from \"../mustache/convertMustacheToComments\";\nimport { setBindingsReadyForScope, setStateElementAlias } from \"../stateElementByName\";\nimport { collectStructuralFragments } from \"../structural/collectStructuralFragments\";\nimport { raiseError } from \"../raiseError\";\nimport { ParseBindTextResult } from \"../bindTextParser/types\";\nimport { IContent } from \"../structural/types\";\nimport { getMountRecordByScopeRoot, getMountRecordsForStateElement, getScopeRootByMountRecord, IMountRecord, registerMountRecord, stateElementHasMounts, translateParsedForMount } from \"./mount\";\nimport { notifyExports, registerExports, warnShadowedExports } from \"./exportIndex\";\n\n/**\n * webComponent/mountScope.ts — マウントされたスコープの構築(Phase 2・impl-plan §3-0)。\n *\n * v1 の buildBindings(rootNode ごとの独立ツリー構築)に対応する、マウント版の 1 パス。\n * やることは 3 つだけで、以後このスコープのバインディングは「親スコープにインラインで\n * 書かれたもの」と完全に同じ経路(台帳・依存グラフ・updater・for/プール)を流れる。\n *\n * 1. マウント記録の登録(ループ文脈の境界ホップとオーバーレイ dispatch が引く)\n * 2. 台帳エイリアス(Shadow DOM 形のみ): 子 rootNode → 親 state element。\n * `getRootNode()` で解決する全サイトがこれで親ツリーに到達する\n * 3. 変換付きの収集: mustache 変換 → 構造フラグメント収集 → バインディング初期化。\n * パース結果は translateParsedForMount で親ツリーの絶対パスに書き換わる\n * (フラグメントは登録時に変換されるので、行の実体化は無改造・無コスト)\n *\n * 呼び手(State._initializeBindWebComponent の v2 経路)は、この完了を\n * `setBindingsReadyForScope` で子 rootNode の ready として公開する。\n */\n/**\n * スコープ根は Shadow DOM 形ならコンポーネントの shadowRoot、Light DOM 形なら\n * コンポーネント要素自身(そのサブツリーがスコープ・D7)。Light DOM は rootNode を\n * ホストと共有するのでエイリアス不要(親の名前登録がそのまま解決に使われる)。\n * ホスト側の走査からの除外は getSubscriberNodes / collectStructuralFragments の\n * Light DOM prune(§1.13 の機構)がそのまま担う。\n */\nexport function initializeMountScope(record: IMountRecord, scopeRoot: ShadowRoot | Element): void {\n const existing = getMountRecordByScopeRoot(scopeRoot);\n // 1 スコープ根 1 マウント(v2): 同じコンポーネントに 2 本目の\n // `<wcs-state bind-component>`(別 stateProp)が来ても受けられない — 受けると\n // 1 本目の session を dispose した上、収集済みノードは registeredNodeSet\n // (collectNodesAndBindingInfos.ts)が弾いて再収集されず、スコープ全体が\n // 無言で死ぬ。設定ミスとして 1 本目に触れる前に loud に落とす\n if (existing !== null && existing.stateProp !== record.stateProp) {\n raiseError(\n `A mount scope is already initialized on this component for \"${existing.stateProp}\" — ` +\n `one <wcs-state bind-component> per component (v2). ` +\n `Merge the \"${record.stateProp}\" wiring into \"${existing.stateProp}\" or split the component.`,\n );\n }\n // 再初期化(コンポーネントが connectedCallback で shadow の innerHTML を張り直し、\n // 新しい <wcs-state> が同じ shadowRoot に入った): 旧スコープのバインディングは\n // 捨てられた DOM を指したまま親の台帳に残りうるので session ごと破棄してから組み直す\n //(普段は session の MutationObserver が先に破棄している — これは取りこぼし保険。\n // dispose は records と deferred を空にするだけで session 自体は使い回せる)。\n // 旧 for が残した lastListValue は applyChangeToFor 側の「content 台帳が空の\n // binding は白紙から描く」ガードが吸収する\n if (existing !== null) {\n getOrCreateBindingSession(scopeRoot).dispose();\n }\n registerMountRecord(scopeRoot, record);\n if (scopeRoot instanceof ShadowRoot) {\n setStateElementAlias(scopeRoot, record.parentStateElement);\n }\n buildMountScopeBindings(record, scopeRoot);\n // Register exports and alias edges once. Notify parents that evaluated before\n // registration, including on reinitialization when values may have changed.\n registerExports(record);\n warnShadowedExports(record);\n notifyExports(record);\n setBindingsReadyForScope(scopeRoot, Promise.resolve());\n}\n\nfunction buildMountScopeBindings(record: IMountRecord, walkRoot: ShadowRoot | Element): void {\n const transform = (parsed: ParseBindTextResult, forPath?: string): ParseBindTextResult =>\n translateParsedForMount(record, parsed, forPath);\n convertMustacheToComments(walkRoot);\n // スコープ直下のバインディングのループ文脈は、行 content の初期化と同じく\n // **直接エントリ**で渡す(ホスト要素の文脈=境界ホップの解決結果)。\n // text binding は登録前に comment が replaceNode に差し替えられて切断される\n //(bindings/replaceToReplaceNode.ts)ため、DOM walk では文脈に届かない —\n // happy-dom は切断後も parentNode を残す非準拠で偶然通るが、実ブラウザでは落ちる\n const parentLoopContext = getLoopContextByNode(record.component);\n // rootNode は「fragment info の setPathInfo が state element を引く場所」。\n // Shadow DOM 形はエイリアス済みの scopeRoot 自身、Light DOM 形はホストの rootNode\n const rootNode = walkRoot instanceof ShadowRoot ? walkRoot : walkRoot.getRootNode();\n collectStructuralFragments(rootNode, walkRoot, undefined, transform);\n initializeBindings(walkRoot, parentLoopContext, transform);\n}\n\n/**\n * プール再利用の再接続(行 content の再利用で、コンポーネント要素が**別の行**に\n * 付け替わった): マウントスコープの全バインディングを現在のループ文脈の listIndex で\n * 台帳へ張り直し、最新値を適用する。v1 の `_reloadMappedPathsAfterReconnect`(派生規則\n * memo の破棄+プライマリ粒度の $postUpdate)に対応する、単一ツリー版の 1 手。\n * swap では listIndex が行と一緒に動くので張り直しは冪等(同じ台帳に戻るだけ)。\n */\nexport function remountScopeBindings(record: IMountRecord, scopeRoot: ShadowRoot | Element): void {\n const session = getOrCreateBindingSession(scopeRoot);\n // スコープ直下の直接エントリを現在の行の文脈へ張り替える(構築時と対称)。\n // 台帳の張り直し(rebindAddresses)はこのエントリ経由で新しい listIndex を読む\n const parentLoopContext = getLoopContextByNode(record.component);\n session.forEachActiveBindingNode((node) => setLoopContextByNode(node, parentLoopContext));\n const rebound = session.rebindAddresses();\n // 空でも呼んで良い(ループが回らないだけ)— 分岐を持たない\n applyChangeFromBindings(rebound);\n // 別の行に付け替わった = その行の公開パスの答えが変わった(X6)\n notifyExports(record);\n}\n\n/**\n * 行 content をその場で使い回したときの張り直し(#4)。\n *\n * 要素書き込みで行を置き換えると `for` は同じ位置の Content を新しい行に使い回す。中の\n * コンポーネント要素は DOM から外れないので、付け替えを知らせる connectedCallback が来ない —\n * マウントスコープのバインディングは前の行の listIndex に張られたままになり、子の表示がそこで\n * 固まる。プール再利用の再接続(State.connectedCallback → remountScopeBindings)と同じ\n * 張り直しを、行の活性化(= ループ文脈の付け替え)の直後に行う。\n */\nexport function remountScopesUnderContent(\n content: IContent,\n stateElement: IMountRecord[\"parentStateElement\"],\n): void {\n if (!stateElementHasMounts(stateElement)) {\n return;\n }\n for (const record of getMountRecordsForStateElement(stateElement)) {\n if (!isNodeInContentRange(record.component, content)) {\n continue;\n }\n const scopeRoot = getScopeRootByMountRecord(record);\n if (scopeRoot === null) {\n continue;\n }\n remountScopeBindings(record, scopeRoot as ShadowRoot | Element);\n }\n}\n\n/** content の DOM レンジ(firstNode..lastNode)の中にあるノードか */\nfunction isNodeInContentRange(node: Node, content: IContent): boolean {\n for (let current = content.firstNode; current !== null; current = current.nextSibling) {\n if (current === node || current.contains(node)) {\n return true;\n }\n if (current === content.lastNode) {\n break;\n }\n }\n return false;\n}\n","/**\n * webComponent/addressHooks.ts — スコープ機能(bind-component のマウント・`mount=` のボリューム)を\n * 持つ state に付く hook(設計案 H1、S3)。従来 core(getByAddress / setByAddress / get トラップ /\n * event/handler / pathDiagnostics / updatedCallback / applyChangeToFor)が直接 import していた分岐をここへ移し、\n * マウントもボリュームも無い state では一切走らない。\n *\n * 付ける時点: マウント記録の登録(State.markHasMounts)・ボリュームのスロット予約と接ぎ木\n * (State.markHasVolume / markHasGraftedVolumes)。ルートより先に予約されたボリュームは、ルートの\n * 登録時(stateElementByName の登録 listener — volume.ts の installVolumeGraft)に付く。\n * hook は要素の寿命の間は付いたままなので、各 hook は従来どおり `hasMounts` / `hasGraftedVolumes` の\n * boolean で自分の分岐を守る。\n */\nimport { DELIMITER } from \"../define\";\nimport { IAddressHooks, NOT_HANDLED, registerFeatureHooks } from \"../core/addressHooks\";\nimport { getScopedIndexes } from \"../list/wildcardLevel\";\nimport { raiseError } from \"../raiseError\";\nimport { resolveExport } from \"./exportIndex\";\nimport { findMountRecordForNode, getIndexShiftForMarkerPath, getMountRecordByPath } from \"./mount\";\nimport { createOverlayValue, readExportedAccessor, writeExportedAccessor } from \"./overlay\";\nimport { remountScopesUnderContent } from \"./mountScope\";\nimport { createVolumeChroot, findGraftedSlotUnder, getVolumeUpdatedCallbacks, isPathUnderReservedVolume } from \"./volumeShared\";\n\nexport const scopeAddressHooks: IAddressHooks = {\n // マウントのオーバーレイ dispatch(Phase 2・D20)。掛かるのは「マーカーで終わるパス」だけで、\n // その下(私有キー・getter・メソッド)の読み書きは通常の親ウォークが返された proxy への\n // 素の Reflect.get / Reflect.set として続く(overlay.ts)\n read(stateElement, address, receiver, handler) {\n if (stateElement.hasMounts === true && address.pathInfo.lastSegment.charCodeAt(0) === 35 /* '#' */) {\n const mountRecord = getMountRecordByPath(stateElement, address.pathInfo.path);\n if (mountRecord !== null) {\n return createOverlayValue(mountRecord, address, receiver, handler);\n }\n }\n return NOT_HANDLED;\n },\n readMissing(stateElement, address, parentValue, receiver, handler) {\n if (parentValue === null) {\n // 予約済みのボリュームスロット(D22): ロード前の読みは undefined が正で、深いパスの\n // 親歩きがルート欠落に落ちても騒がない。読みは createState セッション内でしか起きず、\n // その間 rootNode は必ず有効(切断で null 化されるのは disconnectedCallback — セッション外)\n if (isPathUnderReservedVolume((stateElement as { rootNode?: Node }).rootNode ?? null, address.pathInfo.path)) {\n return undefined;\n }\n return NOT_HANDLED;\n }\n // 公開 getter の dispatch(docs/state-overlay-export-design.md §2-1): 掛かるのは\n // 「ツリーの未存在キー」の分岐だけ(X1 — 命中する読みは無改造)\n if (stateElement.hasMounts === true) {\n const exported = resolveExport(stateElement, address.parentAddress!.pathInfo.path, address.pathInfo.lastSegment, address.listIndex);\n if (exported !== null) {\n return readExportedAccessor(exported.record, exported.entry, address.listIndex, receiver, handler);\n }\n }\n return NOT_HANDLED;\n },\n // D22 後段: 接ぎ木済みボリュームのマウントポイントを**含む親**の丸ごと書きは throw\n // (設計書 §4-2)。黙って通すと接ぎ木データが消え、quoted-path アクセサだけが\n // 宙に浮いて原因の見えない undefined / TypeError になる。スロット自身への書き込みは\n // 通常のデータ差し替えとして通す\n write(stateElement, address) {\n if (stateElement.hasGraftedVolumes === true) {\n const path = address.pathInfo.path;\n const shadowedSlot = findGraftedSlotUnder(stateElement, path);\n if (shadowedSlot !== null) {\n raiseError(\n `Cannot replace \"${path}\" wholesale: a volume is mounted at \"${shadowedSlot}\" under it (D22). ` +\n `Replacing an ancestor of a mount point silently discards the grafted data while its accessors remain. ` +\n `Write \"${shadowedSlot}\" itself, or individual fields inside \"${path}\", instead.`,\n );\n }\n }\n return NOT_HANDLED;\n },\n // 公開 getter への書き込み(docs/state-overlay-export-design.md X9): 未存在キーへの\n // 書き込みは今日「ツリーに作る」が、その位置に公開 getter があると以後ツリーが勝ち\n // (X1)getter を無言で隠す。setter があれば setter、無ければ raise(overlay の set)\n writeMissing(stateElement, address, _parentValue, _key, value, receiver, handler) {\n if (stateElement.hasMounts === true) {\n const exported = resolveExport(stateElement, address.parentAddress!.pathInfo.path, address.pathInfo.lastSegment, address.listIndex);\n if (exported !== null) {\n return writeExportedAccessor(exported.record, exported.entry, address.listIndex, value, receiver, handler);\n }\n }\n return NOT_HANDLED;\n },\n // マウントのアクセサ評価中(マーカーパスが push されている)はスコープ相対の Δ を\n // 足す(設計書 §4-4: `$n → listIndex.at(Δ + n - 1)`。テンプレート側の `$n` は\n // 変換時に織り込み済み — mount.ts の translateInnerPath)\n indexShift(handler, lastAddress) {\n const stateElement = handler.stateElement;\n const lastPath = lastAddress.pathInfo.path;\n if (stateElement.hasMounts === true && lastPath.indexOf('#') !== -1) {\n const mountRecord = getMountRecordByPath(stateElement, lastPath);\n if (mountRecord !== null) {\n return getIndexShiftForMarkerPath(mountRecord, lastPath);\n }\n }\n return 0;\n },\n // マウントされたスコープ(v2): 作者のハンドラが受ける添字は自スコープの\n // ループ分だけ(§4-4 / P2-9)。翻訳で増えたワイルドカード数を落とす。\n // 翻訳された for の台帳に無いループ文脈は外側スコープのもの(境界ホップで\n // 借りた行)なので、作者から見える添字は 0 本。\n // 記録の解決はノードから(findMountRecordForNode)— Shadow 形は rootNode\n // (shadowRoot)で直に引け、Light DOM 形はスコープ根がコンポーネント要素\n // 自身なので祖先走査が要る(rootNode だけ見ると Light DOM で外側の添字が漏れる)\n handlerScope(stateElement, node, rootNode, loopContext, wildcardCount) {\n if (stateElement.hasMounts !== true) {\n return wildcardCount;\n }\n const mountRecord = findMountRecordForNode(node, rootNode);\n if (mountRecord === null) {\n return wildcardCount;\n }\n const shift = mountRecord.indexShiftByLoopElementPath.get(loopContext.pathInfo.path);\n return typeof shift !== \"undefined\" ? wildcardCount - shift : 0;\n },\n // ボリュームの相対 $updatedCallback(volume.ts): 自分の接頭辞配下の更新だけを相対パスで受ける。\n // 呼び出し順はルート自身の $updatedCallback の**後**($watch の order 規約と同じ\n // 「ルート宣言が先」の向き)。ルートのコールバックが async でも待たない(順序の契約は呼び出し順のみ)\n updated(stateElement, refs, receiver) {\n const volumeCallbacks = getVolumeUpdatedCallbacks(stateElement);\n for (const volume of volumeCallbacks) {\n const prefix = volume.mountPath + DELIMITER;\n const relativePaths: Set<string> = new Set();\n const relativeIndexes: Record<string, Array<number[]>> = {};\n for (const ref of refs) {\n if (ref.absolutePathInfo.stateElement !== stateElement) {\n continue;\n }\n const path = ref.absolutePathInfo.pathInfo.path;\n if (path !== volume.mountPath && !path.startsWith(prefix)) {\n continue;\n }\n // マーカーパス(マウント私有キー)はボリューム相対配送にも漏らさない(D20/D21)\n if (path.indexOf(\"#\") !== -1) {\n continue;\n }\n const relative = path === volume.mountPath ? \"\" : path.slice(prefix.length);\n if (relative === \"\") {\n continue; // マウントポイント自身(接ぎ木そのもの)は相対で表せない\n }\n relativePaths.add(relative);\n const wildcardCount = ref.absolutePathInfo.pathInfo.wildcardCount;\n if (wildcardCount > 0 && ref.listIndex !== null) {\n const indexes = getScopedIndexes(ref.listIndex, wildcardCount);\n (relativeIndexes[relative] ??= []).push(indexes);\n }\n }\n if (relativePaths.size > 0) {\n try {\n volume.callback.call(createVolumeChroot(volume.mountPath, receiver), Array.from(relativePaths), relativeIndexes);\n } catch (error) {\n console.error(`[@wcstack/state] volume \"${volume.mountPath}\" $updatedCallback threw.`, error);\n }\n }\n }\n },\n // 予約済みのボリュームスロット配下はロード完了まで undefined が正(D22)。切断中の要素には\n // rootNode が無い(State の getter は投げる)ので予約を引かない — 切断中の再セットも経路情報を\n // 作り直してここへ来る(#267)\n suppressPathDiagnostic(stateElement, path) {\n const rootNode = stateElement.isConnected === false\n ? null\n : (stateElement as { rootNode?: Node }).rootNode ?? null;\n return isPathUnderReservedVolume(rootNode, path);\n },\n // その場で使い回した行は DOM から外れない = 付け替えを知らせる connectedCallback が来ないので、\n // 行の中のマウントスコープを新しい行の listIndex へ張り直す(#4。マウントの無い state は中で抜ける)\n rowReused(stateElement, content) {\n remountScopesUnderContent(content, stateElement);\n },\n};\n\nlet installed = false;\n/** 冪等。full エントリでは State(markHasMounts / markHasVolume)と volume.ts の installVolumeGraft が呼ぶ */\nexport function installScopeHooks(): void {\n if (installed) return;\n installed = true;\n registerFeatureHooks(\"scopes\", scopeAddressHooks);\n}\n","/**\n * webComponent/volumeLifecycle.ts — ボリューム(`<wcs-state mount=\"path\">`)のライフサイクル\n * (設計案 H3、S4)。独立ツリーを持たず、ロード完了でルートに接ぎ木する(volume.ts)。\n * 接続時にスロットを予約(D22)。ルートより先に接続されてもよい — ルート登録が保留分を引き取る(V5)。\n *\n * 従来 `State` の private メソッド(`_initializeVolume` / `_acquireVolumeSlot` / `_releaseVolumeSlot`)と\n * 5 つの private フィールドだったものを、要素ごとの台帳を持つこのモジュールへ移した。要素から要るのは\n * 内部面の 5 つ(`connectedRootNode` / `clearConnectedRootNode` / `markInitialized` /\n * `settleInitialization` / `loadStateFromSource`)だけ。\n */\nimport type { IStateElement } from \"../components/types\";\nimport { CLAIMED, ILifecycleHooks, registerLifecycleHooks } from \"../core/lifecycleHooks\";\nimport { config } from \"../config\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { callVolumeLifecycle, clearFailedRootNode, failPendingVolumes, graftOrQueueVolume, IVolumeGraftInfo, releaseVolumeSlot, reserveVolumeSlot, validateVolumeMountPath } from \"./volume\";\n\n/** 要素ごとのボリュームの控え(従来の `State` の private フィールド 5 つ) */\ninterface IVolumeLedger {\n /** 接ぎ木済みの控え(`$disconnectedCallback` 用) */\n graftInfo: IVolumeGraftInfo | null;\n /** スロット予約済み・接ぎ木進行中(ロード完了前の再接続の再入ガード) */\n initializing: boolean;\n /**\n * 予約したマウントパス(#265)。枠を返した後に取り直すときもこれを使う —\n * `mount` 属性は書き換えられるので読み直さない。\n */\n mountPath: string | null;\n /**\n * いま枠を握っている rootNode(#265)。null は「握っていない」。解放はこの控えと\n * `mountPath` の組でだけ行う。切断時の rootNode(先に null になる)から読み直すと、\n * 予約した組と一致する保証が無く、別の要素の枠を消しうる。\n */\n slotRootNode: Node | null;\n /**\n * ロード中に外れたときに枠を返した rootNode(#265)。同じ rootNode へ付け直した(並べ替えた)\n * ときだけ、接続でその場で枠を取り直すための控え。付け直すたびに null へ戻す。\n */\n detachedFrom: Node | null;\n}\n\nconst ledgerByElement = new WeakMap<IStateElement, IVolumeLedger>();\n\nfunction ledgerOf(element: IStateElement): IVolumeLedger {\n let ledger = ledgerByElement.get(element);\n if (typeof ledger === \"undefined\") {\n ledger = { graftInfo: null, initializing: false, mountPath: null, slotRootNode: null, detachedFrom: null };\n ledgerByElement.set(element, ledger);\n }\n return ledger;\n}\n\nfunction asElement(element: IStateElement): HTMLElement {\n return element as unknown as HTMLElement;\n}\n\n/** 控えている枠を返す(#265)。所有者の確認は `releaseVolumeSlot` が行う。 */\nfunction releaseSlot(element: IStateElement, ledger: IVolumeLedger): void {\n if (ledger.slotRootNode === null) {\n return;\n }\n releaseVolumeSlot(ledger.slotRootNode, ledger.mountPath!, element);\n ledger.slotRootNode = null;\n}\n\n/**\n * 接ぎ木の直前に、`rootNode` のマウントの枠を取る(#265)。握っていれば真。ロード中・保留中に外れて\n * 返していれば取り直して真。外れている間に別の要素が同じマウントパスを取っていれば、横取りせずに\n * 報告して偽 — 黙らせると、作者に見えるのは「データが現れない」だけになる。\n */\nfunction acquireSlot(element: IStateElement, ledger: IVolumeLedger, rootNode: Node): boolean {\n if (ledger.slotRootNode === rootNode) {\n return true;\n }\n const mountPath = ledger.mountPath!;\n try {\n reserveVolumeSlot(rootNode, mountPath, element);\n } catch {\n console.error(\n `[@wcstack/state] <${config.tagNames.state} mount=\"${mountPath}\"> will not graft: another volume already holds ` +\n `the \"${mountPath}\" slot on this root. Keep one volume per mount path.`,\n );\n return false;\n }\n getStateElement(rootNode)?.markHasVolume?.();\n ledger.slotRootNode = rootNode;\n return true;\n}\n\nasync function initializeVolume(element: IStateElement, ledger: IVolumeLedger): Promise<void> {\n const el = asElement(element);\n const rootNode = element.connectedRootNode!;\n const mountPath = el.getAttribute(\"mount\")!;\n try {\n validateVolumeMountPath(mountPath);\n if (el.hasAttribute(\"bind-component\")) {\n raiseError(`\"mount\" cannot be combined with \"bind-component\".`);\n }\n // name 併記は接続の冒頭の name チェックが mount 専用文言で先に落とす\n //(ここに同じ検査を置いても到達しない)\n if (el.hasAttribute(\"enable-ssr\")) {\n // D14: スナップショットはルートに 1 本 — ボリューム側の enable-ssr は意味を持たない\n console.warn(`[@wcstack/state] <${config.tagNames.state} mount=\"${mountPath}\"> ignores \"enable-ssr\" — snapshots are per root tree (the root state element aggregates volume data).`);\n }\n reserveVolumeSlot(rootNode, mountPath, element);\n // ルートが既に居れば今すぐ、まだなら登録時に(volume.ts の adoptVolumesOnRootRegistered)hook を付ける\n getStateElement(rootNode)?.markHasVolume?.();\n ledger.mountPath = mountPath;\n ledger.slotRootNode = rootNode;\n } catch (error) {\n // 設定エラーでも初期化待ちをウェッジさせない(`_failInitialization` と同じ規範 —\n // 未解決のまま投げると waitForStateInitialize がページ全体を無言で止める)。\n // ここを `_failInitializeLoudly` に載せないのは意図(#257 第 3 ラウンド):\n // この要素はルートではないので、あちらの「この rootNode にルートは来ない」着地\n //(markBindingsUnavailable / failPendingVolumes)が**無関係なルートと兄弟\n // ボリュームを巻き添えにする**。promise を解決してから raise する点は\n // `name=` と同じクラスで、reject 側へ動かすのは別の設計判断\n element.settleInitialization!();\n throw error;\n }\n // 予約成立後に立てる(設定エラーの再接続は従来どおり再 raise させる)\n ledger.initializing = true;\n // D11: ルートの居ないページのボリュームを無言にしない(検査は要素の存在・\n // パース完了後 — 下の module 関数を参照)\n if (getStateElement(rootNode) === null) {\n reportVolumeWithoutRoot(rootNode, mountPath);\n }\n const finish = (info: IVolumeGraftInfo | null): void => {\n ledger.graftInfo = info;\n element.markInitialized!();\n if (info === null) {\n // 接ぎ木しないまま決着した(ロード失敗・接ぎ木失敗・孤児・外れたまま)ので枠を返す(#265)。\n // 握ったままだと、同じマウントパスで作り直した要素が \"already mounted\" に弾かれ、\n // 復旧がページの読み直ししか無くなる\n releaseSlot(element, ledger);\n }\n element.settleInitialization!();\n };\n let volumeState: Record<string, any>;\n try {\n volumeState = await element.loadStateFromSource!();\n } catch (error) {\n // ロード失敗(404 / JSON パースエラー / import 失敗)は 1 ボリュームに閉じる\n // (graftIsolated と同じ隔離規範 — 接ぎ木は載らず、枠も返す着地)。\n // 未解決のまま投げると waitForStateInitialize が全 <wcs-state> の\n // initializePromise を Promise.all で待つためページ全体が無言でウェッジし、\n // 上で立てた initializing の再入ガードが remove → append の復旧も握り潰す。\n // 予約成立後の失敗は graft 失敗と同じ着地(finish(null))に合流し、\n // 予約成立前の設定エラー(上の try/catch)だけが fail-fast で再 raise する\n console.error(`[@wcstack/state] volume \"${mountPath}\" failed to load.`, error);\n finish(null);\n return;\n }\n // 接ぎ木先はいま繋がっている rootNode。await 中に剥がされていたら接ぎ木しない(スコープは持っていない)。ロード中に外れて枠を返していれば、ここで取り直す(#265)。\n // 保留に積むなら、ルートが来た時点でもう一度取る — その間に外れて枠を返していることがあり、そのとき\n // 枠が空いていれば外れたままでも接ぎ木する(従来の着地)。別の要素が取っていれば接ぎ木しない\n const graftRootNode = element.connectedRootNode ?? null;\n if (graftRootNode === null) {\n finish(null);\n return;\n }\n if (!acquireSlot(element, ledger, graftRootNode)) {\n finish(null);\n return;\n }\n graftOrQueueVolume(\n graftRootNode,\n getStateElement(graftRootNode),\n mountPath,\n volumeState,\n finish,\n () => acquireSlot(element, ledger, graftRootNode),\n );\n}\n\nexport const volumeLifecycleHooks: ILifecycleHooks = {\n // DCC(10)の後・bind-component(30)の前。従来の分岐順(設計案 H3)\n order: 20,\n connecting(element) {\n const el = asElement(element);\n if (!el.hasAttribute(\"mount\")) {\n return null;\n }\n const ledger = ledgerOf(element);\n // ロード完了前の remove → append 再入: 接ぎ木は進行中の initializeVolume が持っている\n // (connectedCallbackPromise もそちらが解決する)ので再実行しない。再実行すると\n // reserveVolumeSlot を二重に呼ぶ。外れたときに返した枠は、原則として接ぎ木の直前に取り直す(#265 —\n // acquireSlot)。別の root へ移った形でここで取ると、保留の要求が残る元の root と食い違った\n // まま、移った先の枠を握り続ける。同じ root へ付け直した(並べ替えた)だけなら、空いている枠を\n // その場で黙って取り直す — 取らないと、並べ替えの一瞬に後から来た同じパスのボリュームに枠を奪われる。\n // 取れなければ、接ぎ木の直前の取り直しが報告する\n if (ledger.initializing) {\n const rootNode = element.connectedRootNode;\n if (rootNode != null && ledger.detachedFrom === rootNode) {\n try {\n reserveVolumeSlot(rootNode, ledger.mountPath!, element);\n getStateElement(rootNode)?.markHasVolume?.();\n ledger.slotRootNode = rootNode;\n } catch {\n // 外れている間に別のボリュームが取った。接ぎ木の直前の acquireSlot が報告する\n }\n }\n ledger.detachedFrom = null;\n return CLAIMED;\n }\n return initializeVolume(element, ledger);\n },\n reconnecting(element) {\n const el = asElement(element);\n if (!el.hasAttribute(\"mount\")) {\n return false;\n }\n // 初期化済みボリュームの再接続(remove → append): 接ぎ木・アクセサ・宣言はツリーに残っている\n // (disconnecting と対称 — アンマウント未対応)。core の「ルート再登録」に落とすと、独立ツリーを\n // 持たないボリューム自身がこの rootNode のツリー根として登録されてしまう(ルート不在時)か、\n // \"already registered\" で落ちる(ルート健在時)。\n // $connectedCallback だけは要素のライフサイクルとして chroot で再実行する(マウント済み\n // コンポーネントの再接続と同じ意味論)。ルートが既に居ない・別 rootNode へ移された形では\n // 接ぎ木先ツリーに到達できないので呼ばない\n const ledger = ledgerOf(element);\n const rootNode = element.connectedRootNode ?? null;\n if (ledger.graftInfo !== null && rootNode !== null\n && getStateElement(rootNode) === ledger.graftInfo.rootStateElement) {\n callVolumeLifecycle(ledger.graftInfo, \"$connectedCallback\");\n }\n return true;\n },\n replacingState(element) {\n // 読み込み済みのボリューム(#268): 接ぎ木はロード完了時にデータをルートの木へ一度だけ複製する\n // ので、この要素の state を入れ直してもページには届かない(要素自身の読みだけが新しくなる)。\n // 無言の no-op にせず、ルート側の拒否(D22)と同じく loud に落とす。initializing は\n // スロットを予約したボリュームだけが立て、下ろさない — 接ぎ木に失敗した形もここで弾く。\n if (ledgerByElement.get(element)?.initializing !== true) {\n return;\n }\n const mountPath = asElement(element).getAttribute(\"mount\");\n raiseError(\n `Cannot replace the state of <${config.tagNames.state} mount=\"${mountPath}\"> after it has loaded: ` +\n `a volume's data is copied into the root tree when it grafts, so a new state would never reach the page. ` +\n `Write the paths under \"${mountPath}\" on the root state instead.`,\n );\n },\n initializeFailed(_element, rootNode) {\n // このルートノードにルートは来ない: 保留中のボリュームを待たせ続けない(#257)\n failPendingVolumes(rootNode);\n },\n initializeFailureCleared(_element, rootNode) {\n // 落ちたルート要素**本人**が DOM から消えた =「このルートノードにルートは来ない」はもう\n // 成り立たない(作者の復旧は取り除いて作り直す)。印が残ると、外してから修正版を接続する\n // までの窓で接続したボリュームが即座に孤児化する\n clearFailedRootNode(rootNode);\n },\n disconnecting(element) {\n const el = asElement(element);\n if (!el.hasAttribute(\"mount\")) {\n return false;\n }\n // ボリューム: 接ぎ木したデータ・アクセサ・宣言はツリーに残る(アンマウントは\n // 未対応 — 揮発させると依存グラフに残った getter 登録が宙に浮く)。接ぎ木済みなら予約も維持。\n // $disconnectedCallback だけは要素のライフサイクルとして chroot で呼ぶ\n const ledger = ledgerOf(element);\n if (ledger.graftInfo !== null) {\n callVolumeLifecycle(ledger.graftInfo, \"$disconnectedCallback\");\n }\n if (element.initialized !== true) {\n // ロード中(ルート待ちの保留中を含む)に外れた: 枠を返す(#265)。握ったままだと、ソースが\n // 来ないまま外れた要素の枠が漏れ、同じマウントパスで作り直した要素が \"already mounted\" に\n // 弾かれる。枠は接ぎ木の直前に取り直す(acquireSlot)。同じ root へ付け直したときだけは\n // 接続がその場で取り直すので、外れた root を控える\n ledger.detachedFrom = ledger.slotRootNode;\n releaseSlot(element, ledger);\n }\n element.clearConnectedRootNode!();\n return true;\n },\n};\n\nlet installed = false;\n/** 冪等。full / auto では `bootstrapState()` の `installVolumeGraft()` が呼ぶ */\nexport function installVolumeLifecycle(): void {\n if (installed) return;\n installed = true;\n registerLifecycleHooks(\"scopes\", volumeLifecycleHooks);\n}\n\n/**\n * D11(設計 §4-7): ボリュームだけでルートの無いページを無言にしない。\n * 接ぎ木は保留キューで待つ(V5 — ルートが後から来れば成立する)ため throw はせず、\n * 接続内 throw は初期化待ちを永久未解決にする(`_failInitialization` の注記と同じ理由)。\n * そこで文書のパース完了後に「ルート候補(mount も bind-component も無い <wcs-state>)が\n * **要素として**存在するか」を検査し、無ければ console.error で誘導する。登録(ロード完了)でなく\n * 要素の存在で見るのは、ルートの src ロードの遅さで誤検知しないため。ルートを後から動的に足す\n * ページでは報告が出るが、接ぎ木自体はその後も成立する(文言で釈明)。\n */\nfunction reportVolumeWithoutRoot(rootNode: Node, mountPath: string): void {\n const check = (): void => {\n if (getStateElement(rootNode) !== null) {\n return; // ルートが登録された\n }\n // rootNode は Document / ShadowRoot / Element のいずれか — querySelectorAll は必ずある\n const candidates = (rootNode as ParentNode).querySelectorAll(config.tagNames.state);\n for (const el of candidates) {\n if (!el.hasAttribute(\"mount\") && !el.hasAttribute(\"bind-component\")) {\n return; // ルート候補が居る(ロード中かもしれない)— 登録を待つ\n }\n }\n console.error(\n `[@wcstack/state] <${config.tagNames.state} mount=\"${mountPath}\"> has no root state tree to graft onto (D11). ` +\n `A volume mounts onto the root tree — add a root <${config.tagNames.state}> to this root node ` +\n `(an empty <${config.tagNames.state}></${config.tagNames.state}> is enough). ` +\n `If the root is added dynamically later, the graft will still complete and this report can be ignored.`,\n );\n };\n const doc = (rootNode.ownerDocument ?? rootNode) as Document;\n if (doc.readyState === \"loading\") {\n // パース中は後続にルートが書かれていてもまだ DOM に無い — 完了後に検査する\n doc.addEventListener(\"DOMContentLoaded\", () => queueMicrotask(check), { once: true });\n } else {\n setTimeout(check, 0);\n }\n}\n","/**\n * webComponent/volume.ts — ボリューム(`<wcs-state mount=\"path\">` の接ぎ木)。\n * docs/state-mount-design.md §3-1 / §4-2、D11 / D14 / D22。impl-plan P3-1 / P3-2 / P3-3。\n *\n * ボリュームは自分の台帳を持たない。ロード完了で\n *\n * 1. **データ**(own data key の部分木)をルートの書き込み proxy 経由で\n * `root[mountPath] = data` と接ぎ木する — 通知・依存展開は通常の書き込みと同じ。\n * 2. **アクセサ**(getter / setter)を **ルートの state オブジェクトの quoted-path\n * プロパティ**(`\"i18n.t\"`)として定義する — ルートのワイルドカード getter\n * (`\"children.*.label\"`)と同じ機構にそのまま乗るので、評価は pushAddress 下で行われ、\n * 中の読みは依存エッジとして親グラフに載る。`this` は chroot(`this.lang` は\n * `i18n.lang`)— 評価時の receiver(アクティブなルート proxy)を包む翻訳 proxy。\n * 3. `$connectedCallback` を chroot で呼ぶ(V7)。\n *\n * 接続時にはスロットを**予約**する(D22): 予約下のパスの読みは `undefined` で、\n * pathDiagnostics は沈黙する(ロード前の一時状態は「未宣言」ではない)。\n * ルートより先に接続されてもよい(V5)— ルートの登録(setStateElement の\n * `default`)が保留中のボリュームを引き取る。\n *\n * 宣言面: `$watch` は接頭辞翻訳してルートの watch 台帳へ追記(ハンドラの `this` は\n * chroot・indexes は接頭辞が静的なのでスコープ相対のまま)。`$listKeys` は翻訳して\n * ルートの表へ合流(衝突は設定ミスとして throw)。`$updatedCallback` は自分の接頭辞\n * 配下の更新だけを**相対パス**で受ける(proxy/apis/updatedCallback.ts が配送)。\n * `$disconnectedCallback` はボリューム要素の切断時に chroot で呼ばれる(接ぎ木は残る)。\n *\n * D22 後段: 接ぎ木済みスロットの**親**をルート側から丸ごと書く形は setByAddress が\n * throw する(recordGraftedSlot → findGraftedSlotUnder・ゲートは hasGraftedVolumes)。\n *\n * まだ載せていないもの: `$streams` の接頭辞登録(status 名前空間の設計が別途要る —\n * 宣言は raise)、`$commandTokens` / `$eventTokens` / `$on`(トークンは要素の面 —\n * ルートに宣言する。宣言は warn)、ボリュームのメソッドのツリー露出。\n */\n\nimport { getPathInfo } from \"../address/PathInfo\";\nimport { IStateElement } from \"../components/types\";\nimport { DELIMITER, WILDCARD } from \"../define\";\nimport { raiseError } from \"../raiseError\";\nimport { IStateProxy } from \"../proxy/types\";\nimport { addVolumeUpdatedCallback, createVolumeChroot, drainPendingVolumes, hasReservedVolumeSlots, IPendingVolumeRequest, IVolumeUpdatedCallback, queuePendingVolume, recordGraftedSlot, setVolumeGraftHandler } from \"./volumeShared\";\nimport { onStateElementRegistered } from \"../stateElementByName\";\nimport { installScopeHooks } from \"./addressHooks\";\nimport { installVolumeLifecycle } from \"./volumeLifecycle\";\nimport { installBindComponentLifecycle } from \"./bindComponentLifecycle\";\n\nexport { clearFailedRootNode, createVolumeChroot, drainPendingVolumes, failPendingVolumes, getVolumeUpdatedCallbacks, isPathUnderReservedVolume, releaseVolumeSlot, reserveVolumeSlot } from \"./volumeShared\";\nexport type { IVolumeUpdatedCallback } from \"./volumeShared\";\nimport { assertValidWatchPath } from \"../watch/processWatchDeclaration\";\nimport { addVolumeWatchEntries } from \"../watch/watchRegistry\";\nimport { startWatch } from \"../watch/watchRuntime\";\nimport { ListKeySpec } from \"../list/listKeys\";\nimport { RECURSION_WILDCARD, STATE_LIST_KEYS_NAME, STATE_RECURSION_NAME, STATE_UPDATED_CALLBACK_NAME, STATE_WATCH_NAME } from \"../define\";\nimport { getAllPropertyDescriptors } from \"../getAllPropertyDescriptors\";\nimport type { IWatchEntry } from \"../watch/types\";\n\n\n\n/** ボリューム要素の切断時に $disconnectedCallback を chroot で呼ぶための控え。 */\nexport interface IVolumeGraftInfo {\n readonly rootStateElement: IStateElement;\n readonly mountPath: string;\n readonly volumeState: Record<string, any>;\n}\n\n/** chroot を作る($disconnectedCallback など graft 後のライフサイクル呼び出し用)。 */\nexport function callVolumeLifecycle(info: IVolumeGraftInfo, name: string): void {\n const callback = (info.volumeState as Record<string, unknown>)[name];\n if (typeof callback !== \"function\") {\n return;\n }\n info.rootStateElement.createState(\"writable\", (state) => {\n const result = (callback as (this: unknown) => unknown).call(createVolumeChroot(info.mountPath, state as IStateProxy));\n if (result instanceof Promise) {\n result.catch((error) => {\n console.error(`[@wcstack/state] volume \"${info.mountPath}\" ${name} failed.`, error);\n });\n }\n });\n}\n\n\n/** マウントパスの静的検査(§4-2: 静的パスのみ)。 */\nexport function validateVolumeMountPath(mountPath: string): void {\n if (mountPath.length === 0) {\n raiseError(`\"mount\" requires a non-empty tree path.`);\n }\n const pathInfo = getPathInfo(mountPath);\n for (const segment of pathInfo.segments) {\n if (segment.length === 0) {\n raiseError(`\"mount\" path \"${mountPath}\" has an empty segment.`);\n }\n if (segment === WILDCARD) {\n raiseError(`\"mount\" path \"${mountPath}\" must be static (wildcards are not allowed).`);\n }\n // 位置を問わず拒否(includes): 中間の `#`(a#b)はマーカー判定\n // (getMountRecordByPath の lastIndexOf(\"#\"))と D22 診断免除に干渉する。\n // `$` / `@` も文言(reserved characters)どおり対称に includes で見る\n if (segment.includes(\"$\") || segment.includes(\"#\") || segment.includes(\"@\")) {\n raiseError(`\"mount\" path \"${mountPath}\" must not use reserved characters ($, #, @).`);\n }\n }\n}\n\nfunction splitVolumeState(volumeState: Record<string, any>): {\n data: Record<string, unknown>;\n accessors: Map<string, PropertyDescriptor>;\n} {\n const data: Record<string, unknown> = {};\n const accessors = new Map<string, PropertyDescriptor>();\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(volumeState))) {\n if (key.startsWith(\"$\")) {\n continue; // 宣言面($connectedCallback は graftVolume が直接読む・他は P2-9b)\n }\n if (typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\") {\n accessors.set(key, descriptor);\n continue;\n }\n if (typeof descriptor.value === \"function\") {\n continue; // メソッドのツリー露出は未対応(ヘッダ参照)\n }\n data[key] = descriptor.value;\n }\n return { data, accessors };\n}\n\n/**\n * raise しうる宣言面の検査(graftVolume の**冒頭** — データ接ぎ木・スロット記録・\n * アクセサ登録より前)。後ろで検査すると $streams 等の宣言エラーが「データだけ載り\n * アクセサ・宣言面が無い」半端な接ぎ木状態を残し、graftIsolated が握って\n * onGrafted(null) → $disconnectedCallback も呼ばれない形になる。\n */\nfunction validateVolumeDeclarations(\n rootStateElement: IStateElement,\n mountPath: string,\n volumeState: Record<string, any>,\n): void {\n const watchDeclared = (volumeState as Record<string, unknown>)[STATE_WATCH_NAME];\n if (typeof watchDeclared !== \"undefined\") {\n if (typeof watchDeclared !== \"object\" || watchDeclared === null) {\n raiseError(`${STATE_WATCH_NAME} must be an object mapping state paths to handler functions.`);\n }\n for (const [path, handler] of Object.entries(watchDeclared as Record<string, unknown>)) {\n if (typeof handler !== \"function\") {\n raiseError(`${STATE_WATCH_NAME} entry \"${path}\" must be a function.`);\n }\n assertValidWatchPath(path);\n }\n }\n const listKeysDeclared = (volumeState as Record<string, unknown>)[STATE_LIST_KEYS_NAME];\n if (typeof listKeysDeclared !== \"undefined\") {\n if (typeof listKeysDeclared !== \"object\" || listKeysDeclared === null) {\n raiseError(`${STATE_LIST_KEYS_NAME} must be an object mapping list paths to key specs.`);\n }\n for (const [path, spec] of Object.entries(listKeysDeclared as Record<string, unknown>)) {\n if (path.length === 0 || (typeof spec !== \"string\" && typeof spec !== \"function\")) {\n raiseError(`${STATE_LIST_KEYS_NAME} entry \"${path}\" must map a list path to a field name or a key function.`);\n }\n // 衝突(mergeVolumeListKeys の raise と同義)も接ぎ木前に検出する\n if (rootStateElement.listKeys?.has(mountPath + DELIMITER + path)) {\n raiseError(`${STATE_LIST_KEYS_NAME} entry \"${mountPath + DELIMITER + path}\" is declared by both the root and a volume (or two volumes). Keep exactly one.`);\n }\n }\n }\n // $streams は未対応(無言に捨てない)\n if (typeof (volumeState as Record<string, unknown>)[\"$streams\"] !== \"undefined\") {\n raiseError(`Volume \"${mountPath}\" declares $streams, which volumes do not support yet. Declare the stream on the root state.`);\n }\n // $scan も未対応(docs/state-scan-design.md D8)。from / on はルートのツリーと token を前提にする\n if (typeof (volumeState as Record<string, unknown>)[\"$scan\"] !== \"undefined\") {\n raiseError(`Volume \"${mountPath}\" declares $scan, which volumes do not support yet. Declare the scan on the root state.`);\n }\n // $recursion も同じく未対応。宣言だけ受理されたように見えて、どの深さも解決しない\n // 状態を作らない(docs/state-recursive-path-impl-plan.md §7)。\n if (typeof (volumeState as Record<string, unknown>)[STATE_RECURSION_NAME] !== \"undefined\") {\n raiseError(\n `Volume \"${mountPath}\" declares ${STATE_RECURSION_NAME}, which volumes do not support yet. ` +\n `Declare the recursion anchor on the root state — the anchor path is resolved against the root tree.`\n );\n }\n // `**` getter は接ぎ木の**途中で**落ちる(アクセサ登録が getPathInfo の不変条件ガードに\n // 当たる)ので、データだけ載ってアクセサが無い半端な状態が残る。接ぎ木の前に弾く。\n for (const key of Object.keys(getAllPropertyDescriptors(volumeState as object))) {\n if (key.indexOf(RECURSION_WILDCARD) !== -1) {\n raiseError(\n `Volume \"${mountPath}\" declares \"${key}\", which uses \"${RECURSION_WILDCARD}\". ` +\n `Volumes do not support recursive getters yet — declare them on the root state.`\n );\n }\n }\n}\n\n/**\n * 宣言面の接頭辞登録($watch / $listKeys / $updatedCallback — ヘッダ参照)。\n * 宣言の形は validateVolumeDeclarations(接ぎ木より前)で検査済み — ここは登録だけ。\n */\nfunction processVolumeDeclarations(\n rootStateElement: IStateElement,\n mountPath: string,\n volumeState: Record<string, any>,\n): void {\n // $watch: 翻訳してルート台帳へ追記。ハンドラは chroot 包装。\n const watchDeclared = (volumeState as Record<string, unknown>)[STATE_WATCH_NAME];\n if (typeof watchDeclared !== \"undefined\") {\n const entries: IWatchEntry[] = [];\n const paths = new Set<string>();\n let order = 0;\n for (const [path, handler] of Object.entries(watchDeclared as Record<string, unknown>)) {\n const translated = mountPath + DELIMITER + path;\n const wrapped = function (this: unknown, cur: unknown, prev: unknown, ...indexes: number[]): void {\n // `this` は writable なルート proxy(watchRuntime の fireOne)— chroot で包む。\n // 接頭辞は静的(ワイルドカード無し)なので indexes はスコープ相対のまま\n (handler as (this: unknown, cur: unknown, prev: unknown, ...indexes: number[]) => void)\n .call(createVolumeChroot(mountPath, this), cur, prev, ...indexes);\n };\n // order はルート宣言(0 起点)の後に来る大きな値 — 同一バッチではルートの\n // watch が先に発火する(宣言順規約のボリューム拡張)\n entries.push({ path: translated, pathInfo: getPathInfo(translated), handler: wrapped, order: 1_000_000 + order++ });\n paths.add(translated);\n rootStateElement.setPathInfo(translated, \"prop\", \"watch\");\n }\n if (entries.length > 0) {\n addVolumeWatchEntries(rootStateElement, entries);\n rootStateElement.addVolumeWatchPaths?.(paths);\n startWatch(rootStateElement);\n }\n }\n\n // $listKeys: 翻訳してルートの表へ合流(衝突は validate 済み・merge 側の raise は防御)\n const listKeysDeclared = (volumeState as Record<string, unknown>)[STATE_LIST_KEYS_NAME];\n if (typeof listKeysDeclared !== \"undefined\") {\n const translatedEntries = new Map<string, ListKeySpec>();\n for (const [path, spec] of Object.entries(listKeysDeclared as Record<string, unknown>)) {\n translatedEntries.set(mountPath + DELIMITER + path, spec as ListKeySpec);\n }\n rootStateElement.mergeVolumeListKeys?.(translatedEntries);\n }\n\n // $updatedCallback(相対): 自分の接頭辞配下の更新だけが相対パスで届く。\n // 収集ゲート(hasUpdatedCallback)を開けるのはここ\n const updated = (volumeState as Record<string, unknown>)[STATE_UPDATED_CALLBACK_NAME];\n if (typeof updated === \"function\") {\n addVolumeUpdatedCallback(rootStateElement, { mountPath, callback: updated as IVolumeUpdatedCallback[\"callback\"] });\n rootStateElement.enableUpdatedCallback?.();\n }\n\n // $commandTokens / $eventTokens / $on も未対応(トークンはパスではなく要素の面 —\n // ルートに宣言する)。$errorCallback もルート専用(要件 B11 — 以前は無言で無視していた)。\n // 無言に捨てないが、接ぎ木自体は成立させる(warn 止まり)\n for (const name of [\"$commandTokens\", \"$eventTokens\", \"$on\", \"$errorCallback\"]) {\n if (typeof (volumeState as Record<string, unknown>)[name] !== \"undefined\") {\n console.warn(\n `[@wcstack/state] volume \"${mountPath}\" declares ${name}, which volumes do not support. ` +\n `Declare it on the root state instead.`,\n );\n }\n }\n}\n\n/**\n * 接ぎ木の本体。ルートの state 要素が使える状態で呼ぶこと。\n * 衝突検査(D3/D22): マウントパスの位置に既に値があれば throw。\n */\nexport function graftVolume(\n rootStateElement: IStateElement,\n mountPath: string,\n volumeState: Record<string, any>,\n): IVolumeGraftInfo {\n // raise しうる宣言検査は接ぎ木より前(半端な接ぎ木状態を残さない — ここで\n // 落ちた graft は「何も載っていない」が成立し、graftIsolated の隔離と整合する)\n validateVolumeDeclarations(rootStateElement, mountPath, volumeState);\n const { data, accessors } = splitVolumeState(volumeState);\n const pathInfo = getPathInfo(mountPath);\n // D14: enable-ssr のスナップショットから初期化されたルートでは、スロットに既に\n // 値があれば**採用**する — モジュールはロード済み(getter / $ 宣言のため)だが、\n // データは接ぎ木せず、衝突検査も掛けない(スロットは宣言済みボリュームの所有)\n const hydrated = rootStateElement.hydratedFromSsr === true;\n\n rootStateElement.createState(\"writable\", (state) => {\n // 衝突検査(D22: ルートデータとボリューム宣言の両方が揃った時点)。\n // 1 セグメントの proxy 読みは「無いキー」で raise するため in(has トラップ=\n // 生の Reflect.has)と親値の own キー判定で見る\n if (pathInfo.segments.length === 1) {\n if (mountPath in (state as object)) {\n if (hydrated) {\n return; // 採用(D14)\n }\n raiseError(\n `Volume mount \"${mountPath}\" collides with an existing key on the root tree. ` +\n `Remove the root key or mount the volume elsewhere.`,\n );\n }\n }\n // 深いマウント: 中間の `{}` を作る(`a.b` で `a` が無ければ作る)\n let parent = \"\";\n for (let i = 0; i < pathInfo.segments.length - 1; i++) {\n const segment = pathInfo.segments[i];\n const exists = parent === \"\"\n ? (segment in (state as object))\n : typeof (state as Record<string, unknown>)[parent + DELIMITER + segment] !== \"undefined\";\n parent = parent === \"\" ? segment : parent + DELIMITER + segment;\n if (!exists) {\n (state as Record<string, unknown>)[parent] = {};\n }\n }\n if (pathInfo.segments.length > 1\n && typeof (state as Record<string, unknown>)[mountPath] !== \"undefined\") {\n if (hydrated) {\n return; // 採用(D14)\n }\n raiseError(\n `Volume mount \"${mountPath}\" collides with an existing key on the root tree. ` +\n `Remove the root key or mount the volume elsewhere.`,\n );\n }\n // データの接ぎ木 — 通常の書き込みなので通知・依存展開はそのまま走る\n (state as Record<string, unknown>)[mountPath] = data;\n });\n\n // D22 後段: 以後このスロットの**親**の丸ごと書きは setByAddress が throw する\n // (hydrate 採用でもアクセサは登録されるので同様に守る)。ゲートは boolean 1 個(D18)\n recordGraftedSlot(rootStateElement, mountPath);\n rootStateElement.markHasGraftedVolumes?.();\n\n // アクセサをルートの quoted-path アクセサとして登録(`\"i18n.t\"` — ワイルドカード\n // getter と同じ機構)。`this`(receiver)はアクティブなルート proxy なので、\n // chroot で包んで相対読みをマウント配下へ翻訳する\n for (const [key, descriptor] of accessors) {\n const treePath = mountPath + DELIMITER + key;\n const originalGet = descriptor.get;\n const originalSet = descriptor.set;\n const wrapped: PropertyDescriptor = { enumerable: false, configurable: true };\n if (typeof originalGet === \"function\") {\n wrapped.get = function (this: unknown) {\n return originalGet.call(createVolumeChroot(mountPath, this));\n };\n }\n if (typeof originalSet === \"function\") {\n wrapped.set = function (this: unknown, value: unknown) {\n originalSet.call(createVolumeChroot(mountPath, this), value);\n };\n }\n rootStateElement.defineTreeAccessor(treePath, wrapped);\n }\n\n processVolumeDeclarations(rootStateElement, mountPath, volumeState);\n\n // $connectedCallback(V7): chroot で呼ぶ。async でもよい(待たない — ルートの\n // $connectedCallback と同格の「自分のライフサイクル」)\n const connectedCallback = (volumeState as { $connectedCallback?: unknown }).$connectedCallback;\n if (typeof connectedCallback === \"function\") {\n rootStateElement.createState(\"writable\", (state) => {\n let result: unknown;\n try {\n result = connectedCallback.call(createVolumeChroot(mountPath, state as IStateProxy));\n } catch (error) {\n // 同期の throw も非同期の reject と同じく報告に留める。データ・アクセサ・宣言はもう載っているので、\n // ここから投げると接ぎ木済みのボリュームが「接ぎ木に失敗した」扱いになり、枠まで返してしまう\n // (同じマウントパスで作り直した要素が、残ったデータと衝突する — #265)\n console.error(`[@wcstack/state] volume \"${mountPath}\" $connectedCallback failed.`, error);\n return;\n }\n if (result instanceof Promise) {\n result.catch((error) => {\n console.error(`[@wcstack/state] volume \"${mountPath}\" $connectedCallback failed.`, error);\n });\n }\n });\n }\n return { rootStateElement, mountPath, volumeState };\n}\n\n/**\n * ルートがまだ居なければ保留、居れば即接ぎ木。\n * ルートの名前登録(`default`)が保留分を `drainPendingVolumes` で引き取る。\n */\nfunction graftIsolated(rootStateElement: IStateElement, volume: IPendingVolumeRequest): void {\n if (!volume.acquireSlot()) {\n // 接ぎ木の直前に枠を取れなかった(#265)— 要素が外れている間に、別のボリュームが同じマウントパスを\n // 取った。報告は acquireSlot が出す。接ぎ木せずに決着させる\n volume.onGrafted(null);\n return;\n }\n let info: IVolumeGraftInfo | null = null;\n try {\n info = graftVolume(rootStateElement, volume.mountPath, volume.volumeState);\n } catch (error) {\n // 接ぎ木の失敗(衝突など)は 1 ボリュームに閉じる。ルートの初期化や他の\n // ボリュームを道連れにしない(connectedCallback 内の throw は promise を\n // 永久未解決にする — §8.2 と同じ構図)\n console.error(`[@wcstack/state] volume \"${volume.mountPath}\" failed to graft.`, error);\n } finally {\n volume.onGrafted(info);\n }\n}\n\nexport function graftOrQueueVolume(\n rootNode: Node,\n rootStateElement: IStateElement | null,\n mountPath: string,\n volumeState: Record<string, any>,\n onGrafted: (info: IVolumeGraftInfo | null) => void,\n acquireSlot: () => boolean,\n): void {\n const request: IPendingVolumeRequest = {\n mountPath,\n volumeState,\n onGrafted: onGrafted as IPendingVolumeRequest[\"onGrafted\"],\n acquireSlot,\n };\n if (rootStateElement !== null) {\n graftIsolated(rootStateElement, request);\n return;\n }\n // 最初の接ぎ木要求で graft の実体を確実に注入する(bootstrapState() を経ない経路の保険。冪等)\n installVolumeGraft();\n queuePendingVolume(rootNode, request);\n}\n\n// stateElementByName の drainPendingVolumes は import 循環(updater まで届く)を避けて\n// 軽量な volumeShared に住む — graft の実体はここで注入する。モジュール評価時には注入せず、\n// bootstrapState() が registerComponents() より前に呼ぶ(冪等)ので、ルート登録の前には\n// 確実に配線されている。\nlet volumeGraftInstalled = false;\nexport function installVolumeGraft(): void {\n if (volumeGraftInstalled) return;\n volumeGraftInstalled = true;\n installScopeHooks();\n installVolumeLifecycle();\n installBindComponentLifecycle();\n setVolumeGraftHandler(graftIsolated);\n onStateElementRegistered(adoptVolumesOnRootRegistered);\n}\n\n// ルートの登録: 先に予約されたボリュームがあればスコープ機能の hook を付け、保留中の接ぎ木を引き取る\nfunction adoptVolumesOnRootRegistered(rootNode: Node, element: IStateElement): void {\n if (hasReservedVolumeSlots(rootNode)) {\n element.markHasVolume?.();\n }\n drainPendingVolumes(rootNode, element);\n}\n\n","/**\n * `bind-component` の配線が完了した (webComponent, stateProp) の台帳。\n *\n * 完了前は state プロパティがまだ素のオブジェクトなので、親からの適用は\n * `applyChangeToProperty` がそこへ値を積み、`bindWebComponent` が melt して取り込む。\n * 完了後は公開プロパティが outerState proxy に差し替わっているため、親からの適用は\n * 値を運ばない内部通知チャネル(`applyChangeToWebComponent`)へ切り替わる。\n * その切り替え判定がこの台帳。\n *\n * キーは「state プロパティ名」であって state 要素ではない。完了はプロパティ単位の\n * 事実(`defineProperty(component, stateProp, ...)` が済んだか)であり、\n * 粒度もプロパティ単位が正しい(v2 の注記: **マウント**スコープは 1 コンポーネント\n * 1 つに制約される — 2 本目の `<wcs-state bind-component>` は\n * webComponent/mountScope.ts が raise する。プロパティ粒度の台帳自体は\n * 型の取り違え防止として維持する)。\n * 以前は内側の `IStateElement` をキーにしていたが、照会側(apply/applyChange.ts)が\n * 手にしているのは *親スコープ* の `IStateElement` であり、どちらも同じ型なので\n * TypeScript が取り違えを検出できず、判定が恒久的に false になっていた\n * (=親 state 起点の変更が子コンポーネントへ届かない。\n * docs/architecture-hardening/15-state-component-mechanism-consistency.md §1.7)。\n */\nconst completedStatePropsByWebComponent = new WeakMap<Element, Set<string>>();\n\nexport function markWebComponentAsComplete(webComponent: Element, stateProp: string): void {\n let completedStateProps = completedStatePropsByWebComponent.get(webComponent);\n if (!completedStateProps) {\n completedStateProps = new Set<string>();\n completedStatePropsByWebComponent.set(webComponent, completedStateProps);\n }\n completedStateProps.add(stateProp);\n}\n\nexport function isWebComponentComplete(webComponent: Element, stateProp: string): boolean {\n return completedStatePropsByWebComponent.get(webComponent)?.has(stateProp) === true;\n}\n\n/**\n * `<wcs-state bind-component=\"<prop>\">` が接続され、(webComponent, stateProp) を束ねると\n * **宣言した**台帳。完了(上)より前 — ホストの `whenDefined` / `waitInitializeBinding` を\n * 待つ前 — に記録する。\n *\n * 用途は丸ごとマウント `data-wcs=\"state: user\"` の**完了前の初期適用の抑止**。完了前の\n * 1 セグメントバインディングは applyChangeToProperty が `element.state = userObject` と\n * 親のオブジェクトそのものをコンポーネントの state プロパティに書いてしまい、\n * bindWebComponent がそれを子 state の実体として取り込む — own data key が親のキー全部に\n * なり、R1 では全部が私有に化ける。宣言済みなら値を書かずに完了を待つ(子は完了後に\n * innerState 経由でライブに読む — docs/state-mount-design.md §3-2 / impl-plan P1-1)。\n *\n * 未宣言(子がまだ接続していない)の間は従来どおり書く。未 upgrade 要素への own property は\n * upgrade 時のクラスフィールド初期化で置き換わるので、実害は無い。\n */\nconst declaredStatePropsByWebComponent = new WeakMap<Element, Set<string>>();\n\nexport function markWebComponentStatePropDeclared(webComponent: Element, stateProp: string): void {\n let declaredStateProps = declaredStatePropsByWebComponent.get(webComponent);\n if (!declaredStateProps) {\n declaredStateProps = new Set<string>();\n declaredStatePropsByWebComponent.set(webComponent, declaredStateProps);\n }\n declaredStateProps.add(stateProp);\n}\n\nexport function isWebComponentStatePropDeclared(webComponent: Element, stateProp: string): boolean {\n return declaredStatePropsByWebComponent.get(webComponent)?.has(stateProp) === true;\n}\n","/**\n * `bind-component` の**完了前**に親スコープの初期適用がコンポーネントの state プロパティへ\n * 行った書き込みの控え(docs/state-mount-design.md D19 / impl-plan P1-1・P1-10)。\n *\n * 完了前の親→子の適用は `applyChangeToProperty` が素のプロパティに値を積む\n * (webComponent/completeWebComponent.ts)。丸ごとマウントと R1 が入って、この積みが\n * 2 つの取り違えを生むようになった。\n *\n * 1. **丸ごと(1 セグメント・`state: user`)**: `element.state = userObject` と親の\n * オブジェクトそのもので state プロパティを**置き換える**。子がまだ宣言していない\n * タイミング(happy-dom の template clone は upgrade 済みで、挿入前に適用が走る)では\n * 宣言台帳のガードが効かず、作者の state オブジェクト(getter / 私有キー)が失われる。\n * → 置き換え前のオブジェクトを控え、子の初期化時に戻す(`takeOverwrittenObject`)。\n * 2. **部分(2 セグメント・`state.theme: theme`)**: `element.state.theme = themeObject` と\n * 作者のオブジェクトに**キーを注入する**。R1 の判定はこれを own data key と区別できない。\n * → 注入したキーを控え、衝突の報告(ownKeyShadow)から外す(`getInjectedKeys`)。\n * 私有判定そのものは innerState が「部分規則が覆うキー」を静的に除くので、ここには依らない。\n *\n * どちらもカスタム要素・オブジェクト値のときだけ記録するので、通常のプロパティ書き込み\n * (textContent / value / checked …)のホットパスには typeof 判定 1 つしか載らない。\n */\nconst overwrittenObjectByElement = new WeakMap<Element, Map<string, object>>();\nconst injectedKeysByElement = new WeakMap<Element, Map<string, Set<string>>>();\n\n/** 1 セグメント書き込みで置き換えられる直前のオブジェクトを控える。最初の 1 回だけ(作者のもの)。 */\nexport function rememberOverwrittenObject(element: Element, prop: string, previous: object): void {\n let byProp = overwrittenObjectByElement.get(element);\n if (!byProp) {\n byProp = new Map();\n overwrittenObjectByElement.set(element, byProp);\n }\n if (!byProp.has(prop)) {\n byProp.set(prop, previous);\n }\n}\n\n/** 控えを取り出して消す。無ければ undefined。 */\nexport function takeOverwrittenObject(element: Element, prop: string): object | undefined {\n const byProp = overwrittenObjectByElement.get(element);\n if (!byProp) {\n return undefined;\n }\n const previous = byProp.get(prop);\n byProp.delete(prop);\n return previous;\n}\n\n/** 2 セグメント書き込み(`state.theme`)が作者のオブジェクトに無かったキーを作ったことを控える。 */\nexport function recordInjectedKey(element: Element, prop: string, key: string): void {\n let byProp = injectedKeysByElement.get(element);\n if (!byProp) {\n byProp = new Map();\n injectedKeysByElement.set(element, byProp);\n }\n let keys = byProp.get(prop);\n if (!keys) {\n keys = new Set();\n byProp.set(prop, keys);\n }\n keys.add(key);\n}\n\nexport function getInjectedKeys(element: Element, prop: string): ReadonlySet<string> | undefined {\n return injectedKeysByElement.get(element)?.get(prop);\n}\n\nconst overwrittenValuesByElement = new WeakMap<Element, Map<string, Map<string, unknown>>>();\n\n/**\n * 2 セグメント書き込み(`state.row: rows.*` の積み)が作者の**既存**キーを上書きする\n * 直前の値を控える。最初の 1 回だけ(=作者の値)。宣言前の窓(happy-dom は template\n * clone を upgrade 済みにするので、fragment 内の初期適用は宣言より先に走る)では\n * 宣言台帳の抑止が効かず、v2 の厳格 R1 が snapshot する「作者の既定値」が親の値で\n * 汚染される — v2 のマウント構築が snapshot 前にこれで復元する。\n */\nexport function rememberOverwrittenValue(element: Element, prop: string, key: string, previous: unknown): void {\n let byProp = overwrittenValuesByElement.get(element);\n if (!byProp) {\n byProp = new Map();\n overwrittenValuesByElement.set(element, byProp);\n }\n let byKey = byProp.get(prop);\n if (!byKey) {\n byKey = new Map();\n byProp.set(prop, byKey);\n }\n if (!byKey.has(key)) {\n byKey.set(key, previous);\n }\n}\n\n/** 控えた作者の値を state オブジェクトへ戻して消す(v2 のマウント構築時・snapshot 前)。 */\nexport function restoreOverwrittenValues(element: Element, prop: string, state: Record<string, unknown>): void {\n const byKey = overwrittenValuesByElement.get(element)?.get(prop);\n if (typeof byKey === \"undefined\") {\n return;\n }\n for (const [key, previous] of byKey) {\n state[key] = previous;\n }\n overwrittenValuesByElement.get(element)!.delete(prop);\n}\n","/**\n * webComponent/componentApply.ts — bind-component の 2 つの台帳(完了・宣言 — completeWebComponent.ts、\n * 完了前の書き込みの控え — preCompletionWrites.ts)を、親スコープの適用が引く受け口\n * (core/componentApplyHooks.ts)の形に束ねたもの。置くのは bindComponentLifecycle.ts の install。\n * 完了前は素のプロパティへ積んで控え、完了後は値を運ばない通知へ切り替える。\n */\nimport type { IComponentApplyHooks } from \"../core/componentApplyHooks\";\nimport { isWebComponentComplete, isWebComponentStatePropDeclared } from \"./completeWebComponent\";\nimport { recordInjectedKey, rememberOverwrittenObject, rememberOverwrittenValue } from \"./preCompletionWrites\";\n\nexport const bindComponentApplyHooks: IComponentApplyHooks = {\n isComplete: isWebComponentComplete,\n isDeclared: isWebComponentStatePropDeclared,\n rememberOverwrittenObject,\n recordInjectedKey,\n rememberOverwrittenValue,\n};\n","\nfunction cloneWithDescriptors(obj: object) {\n const proto = Object.getPrototypeOf(obj);\n const clone = Object.create(proto);\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n for(const key in descriptors) {\n const descriptor = descriptors[key];\n if (descriptor.writable === false) {\n descriptor.writable = true;\n }\n }\n Object.defineProperties(clone, descriptors);\n return clone;\n}\n\nexport function meltFrozenObject(frozenObj: object) {\n return cloneWithDescriptors(frozenObj);\n}","import { IStateElement } from \"../components/types\";\n\nconst stateElementByWebComponent: WeakMap<Element, Map<string, IStateElement>> = new WeakMap();\n\nexport function setStateElementByWebComponent(webComponent: Element, stateProp: string, stateElement: IStateElement): void {\n let stateMap = stateElementByWebComponent.get(webComponent);\n if (!stateMap) {\n stateMap = new Map();\n stateElementByWebComponent.set(webComponent, stateMap);\n }\n stateMap.set(stateProp, stateElement);\n}\n\nexport function getStateElementByWebComponent(webComponent: Element, stateProp: string): IStateElement | null {\n const stateMap = stateElementByWebComponent.get(webComponent);\n if (!stateMap) {\n return null;\n }\n return stateMap.get(stateProp) ?? null;\n}\n","import { IStateElement } from \"../components/types\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElementByWebComponent } from \"./stateElementByWebComponent\";\nimport { IOuterState } from \"./types\";\n\n/**\n * コンポーネントの `bind-component` プロパティとして露出する proxy。\n * read / write とも子の state proxy へ素通しする。\n *\n * mapped(親から `<prop>.*` をバインドされている)ケースでは、素通し先の\n * innerState proxy がマッピング規則に従って親 state へ解決するので、\n * `this.state.msg` の読みは親の現在値になり、書きは親 state へ届く。\n * plain(親からのバインドなし)ケースでは子のローカル state に解決する。\n * **どちらでも同じ意味論になる**のが要点\n * (docs/architecture-hardening/15-state-component-mechanism-consistency.md §1.1 / G1)。\n *\n * 以前は mapped 専用に「read = 最後に観測した値のキャッシュ/write = 値を捨てて\n * `$postUpdate` 通知のみ」という別 proxy を当てていた。あれは親 → 子の再読込通知という\n * **内部チャネル**としては正しかったが、それが公開 API を兼ねていたため、同じ\n * コンポーネント実装が親ページの書き方で挙動を変えていた。内部チャネルは\n * `applyChangeToWebComponent` が state element を直接引く形へ分離した。\n */\nclass OuterStateProxyHandler implements ProxyHandler<IOuterState> {\n private _innerStateElement: IStateElement;\n constructor(webComponent: Element, stateProp: string) {\n this._innerStateElement = getStateElementByWebComponent(webComponent, stateProp) ?? raiseError('State element not found for web component.');\n }\n\n get(target: IOuterState, prop: string | symbol, receiver: any): any {\n if (typeof prop === 'string') {\n let value;\n this._innerStateElement.createState(\"readonly\", (state) => {\n value = state[prop];\n });\n return value;\n } else {\n return Reflect.get(target, prop, receiver);\n }\n }\n\n set(target: IOuterState, prop: string | symbol, value: any, receiver: any): boolean {\n if (typeof prop === 'string') {\n this._innerStateElement.createState(\"writable\", (state) => {\n state[prop] = value;\n });\n return true;\n } else {\n return Reflect.set(target, prop, value, receiver);\n }\n }\n}\n\nexport function createOuterState(webComponent: Element, stateProp: string): IOuterState {\n const handler = new OuterStateProxyHandler(webComponent, stateProp);\n return new Proxy({}, handler);\n}\n","import { IStateElement } from \"../components/types\";\nimport { WEBCOMPONENT_STATE_READY_CALLBACK_NAME } from \"../define\";\nimport { raiseError } from \"../raiseError\";\nimport { markWebComponentAsComplete } from \"./completeWebComponent\";\nimport { meltFrozenObject } from \"./meltFrozenObject\";\nimport { createOuterState } from \"./outerState\";\nimport { setStateElementByWebComponent } from \"./stateElementByWebComponent\";\nimport { IOuterState } from \"./types\";\n\nconst getOuter = (outerState: IOuterState) => (): IOuterState => outerState;\n\nexport function bindWebComponent(\n innerStateElement: IStateElement,\n component: Element,\n stateProp: string,\n state: Record<string, any>\n): void {\n // v2: ホスト配線(`state[.sub]: path`)のある形は全てマウント(State.ts の v2 経路)に\n // 乗るため、ここへ来るのは **plain**(配線なしの state 注入)だけ。melt した作者の\n // オブジェクトをそのまま自分の state 要素の実体にする。\n setStateElementByWebComponent(component, stateProp, innerStateElement);\n innerStateElement.setInitialState(meltFrozenObject(state));\n // 公開プロパティは outerState proxy(read はライブ・write は自分の state 要素へ)\n const outerState = createOuterState(component, stateProp);\n Object.defineProperty(component, stateProp, {\n get: getOuter(outerState),\n enumerable: true,\n configurable: true,\n });\n markWebComponentAsComplete(component, stateProp);\n invokeStateReadyCallback(component, stateProp);\n}\n\n/** `$stateReadyCallback` の呼び出し(v1 の bindWebComponent と v2 のマウント経路で共用)。 */\nexport function invokeStateReadyCallback(component: Element, stateProp: string): void {\n if (WEBCOMPONENT_STATE_READY_CALLBACK_NAME in component) {\n const func = (component as any)[WEBCOMPONENT_STATE_READY_CALLBACK_NAME];\n if (typeof func === 'function') {\n func.call(component, stateProp).catch((error: any) => {\n raiseError(`Error in ${WEBCOMPONENT_STATE_READY_CALLBACK_NAME}: ${error instanceof Error ? error.message : String(error)}`);\n });\n } else {\n raiseError(`${WEBCOMPONENT_STATE_READY_CALLBACK_NAME} is not a function.`);\n }\n }\n}\n","import { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { setLoopContextSymbol } from \"../proxy/symbols\";\nimport { IMountRecord } from \"./mount\";\n\n/**\n * コンポーネントの own data key とマウントの衝突を、バインド確立時に 1 回だけ報告する\n * (docs/state-mount-design.md D4 / D19、impl-plan P1-10 / P1-11)。\n *\n * 2 つの形がある。\n *\n * - **ルートマウント**(`state: user`): R1 では own data key は私有で、マウント先の\n * 同名キー(`user.name`)を**隠す**。書き手が「既定値」のつもりで置いたキーがツリーを\n * 読まなくなるので、マウント先の値がオブジェクトで同名キーを持つときに報告する。\n * - **部分マウント**(`state.message: x` + `state = { message: \"\" }`)は 3.0 から衝突しない:\n * ホストが明示したエントリが同名の own key に勝つ(要件 B14 ②)。v2 では own key が私有として\n * 勝っていたので、ここで報告していた。\n *\n * 「既定値を消す(ツリーを読む)か、名前を変える(私有のまま)」で直る。\n * 報告はタグ名 × プロパティ × キーで 1 回(リストの行ごとに並ばないように)。\n * ホットパス外(bindWebComponent の中・要素につき 1 回)。\n */\nconst reported = new Set<string>();\n\n/** テスト用: 報告済み台帳を空にする。 */\nexport function clearOwnKeyShadowReportsForTesting(): void {\n reported.clear();\n}\n\n\n\nfunction report(key: string, message: string): void {\n if (reported.has(key)) {\n return;\n }\n reported.add(key);\n console.warn(`[@wcstack/state] [wcs/mount-own-key-shadow] ${message} See docs/state-mount-design.md §4-3.`);\n}\n\n/**\n * v2 マウント(Phase 2)の衝突報告。厳格 R1: 作者の own data key(privateSnapshot)は\n * 私有で、ルートマウントのマウント先の同名キーを**隠す**。積みで注入されたキーと、部分エントリが\n * 明示したキー(要件 B14 ②)は privateSnapshot に入らないので対象外。\n */\nexport function warnOwnKeyShadowsForMount(record: IMountRecord): void {\n const keys = Object.keys(record.privateSnapshot);\n if (keys.length === 0) {\n return;\n }\n const tag = record.component.tagName.toLowerCase();\n const stateProp = record.stateProp;\n let mountTarget: unknown = undefined;\n let mountTargetRead = false;\n for (const key of keys) {\n if (record.rootEntry === null) {\n continue;\n }\n if (!mountTargetRead) {\n mountTarget = readMountRootTarget(record);\n mountTargetRead = true;\n }\n if (typeof mountTarget !== \"object\" || mountTarget === null || !(key in (mountTarget as object))) {\n continue;\n }\n const outerPath = record.rootEntry.outerPathInfo.path;\n report(\n `${tag}|${stateProp}|${key}|root`,\n `<${tag}>.${stateProp}.${key} is private and hides the mounted tree key \"${outerPath}.${key}\" (${stateProp}: ${outerPath}). ` +\n `Remove the default to read the tree, or rename it to keep it private.`,\n );\n }\n}\n\nfunction readMountRootTarget(record: IMountRecord): unknown {\n const rootEntry = record.rootEntry!;\n const loopContext = getLoopContextByNode(record.component);\n if (rootEntry.outerPathInfo.wildcardCount > 0 && loopContext === null) {\n return undefined;\n }\n let value: unknown = undefined;\n record.parentStateElement.createState(\"readonly\", (state) => {\n state[setLoopContextSymbol](loopContext, () => {\n value = (state as Record<string, unknown>)[rootEntry.outerPathInfo.path];\n });\n });\n return value;\n}\n","/**\n * webComponent/bindComponentLifecycle.ts — `bind-component` とマウントスコープのライフサイクル\n * (設計案 H3、S4)。従来 `State` の `_initializeBindWebComponent` と、接続・再接続・切断の\n * マウント分岐だったもの。本体は State.ts から機械的に移しており、`this.` の参照だけを\n * 要素ごとの台帳(`IBindLedger`)と要素の内部面に書き換えてある。\n *\n * 引き取りの形が他の機能と違う: この処理は `bind-component` のある要素で必ず走り、\n * **マウントスコープを組んだときだけ**その後の初期化(独立ツリーの構築)を打ち切る。\n * そのため受け口は `preparing`(「前処理をして、この要素を丸ごと引き取ったかを返す」)。\n */\nimport type { IStateElement } from \"../components/types\";\nimport { ILifecycleHooks, registerLifecycleHooks } from \"../core/lifecycleHooks\";\nimport { setComponentApplyHooks } from \"../core/componentApplyHooks\";\nimport { bindComponentApplyHooks } from \"./componentApply\";\nimport { config } from \"../config\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry\";\nimport { getBindingsByNode } from \"../bindings/getBindingsByNode\";\nimport { waitInitializeBinding } from \"../bindings/initializeBindingPromiseByNode\";\nimport { bindWebComponent, invokeStateReadyCallback } from \"./bindWebComponent\";\nimport { buildMountRecord, callMountLifecycleCallback, getRegisteredMountRecord, IMountRecord, warnMountedDollarDeclarations } from \"./mount\";\nimport { initializeMountScope, remountScopeBindings } from \"./mountScope\";\nimport { createPublicMountState } from \"./overlay\";\nimport { warnOwnKeyShadowsForMount } from \"./ownKeyShadow\";\nimport { markWebComponentAsComplete, markWebComponentStatePropDeclared } from \"./completeWebComponent\";\nimport { getInjectedKeys, restoreOverwrittenValues, takeOverwrittenObject } from \"./preCompletionWrites\";\nimport { hasRootMountBinding } from \"./rootMountBinding\";\nimport { notifyExports } from \"./exportIndex\";\n\n/** 要素ごとの控え(従来の `State` の private フィールド 3 つ) */\ninterface IBindLedger {\n boundComponent: Element | null;\n boundComponentStateProp: string | null;\n /** v2 マウント(Phase 2): この bind-component 要素が構築したマウント記録 */\n mountRecord: IMountRecord | null;\n}\n\nconst ledgerByElement = new WeakMap<IStateElement, IBindLedger>();\n\nfunction ledgerOf(element: IStateElement): IBindLedger {\n let ledger = ledgerByElement.get(element);\n if (typeof ledger === \"undefined\") {\n ledger = { boundComponent: null, boundComponentStateProp: null, mountRecord: null };\n ledgerByElement.set(element, ledger);\n }\n return ledger;\n}\n\n/**\n * 設定エラーでの fail-fast(`State._failInitialization` と同じ着地)。initializePromise 等を\n * 解決してから raise する — 未解決のまま投げると waitForStateInitialize がこの要素を待ち続け、\n * **ページ全体が無言でウェッジする**。\n */\nfunction failInitialization(element: IStateElement, message: string): never {\n element.landInitialization!();\n raiseError(message);\n}\n\nasync function initializeBindWebComponent(element: IStateElement, ledger: IBindLedger): Promise<void> {\n const el = element as unknown as HTMLElement;\n if (el.hasAttribute(\"bind-component\")) {\n // wcs-stateはコンポーネントのトップレベル要素であること\n // ShadowDOM直下: parentNodeがShadowRoot → hostが親コンポーネント\n // LightDOM/ShadowDOM内のLightDOM: parentNodeがElement → それが親コンポーネント\n const parentNode = el.parentNode;\n const boundComponent = parentNode instanceof ShadowRoot\n ? parentNode.host\n : parentNode instanceof Element\n ? parentNode\n : null;\n const customTagName = boundComponent ? getCustomElement(boundComponent) : null;\n if (boundComponent === null || customTagName === null) {\n raiseError(`\"bind-component\" requires <${config.tagNames.state}> to be a direct child of a custom element.`);\n }\n // plain(ホスト配線なし)の Light DOM は廃止(v2・2026-09-03 著者決定)。\n // 共有 rootNode に独立ツリーを置くには名前次元が要り、単一登録簿(P3-6)と\n // 両立しない。shadow を付ければ plain Shadow 形(独立ツリー・$ 宣言込み)に\n // そのままなる。data-wcs が無ければ確実に plain — 従来の位置で fail-fast。\n // data-wcs があるときの判定はホスト配線が要るため下(waitInitializeBinding の後)\n if (!(parentNode instanceof ShadowRoot) && !boundComponent.hasAttribute(config.bindAttributeName)) {\n failInitialization(element, \n `A plain (unwired) Light DOM \"bind-component\" is not supported. ` +\n `Attach a shadow root to <${customTagName}>, or mount it from the host ` +\n `(data-wcs=\"${el.getAttribute(\"bind-component\")}: path\").`,\n );\n }\n // bind-component はコンポーネント側の state プロパティを唯一のソースにする。\n // state / src / json / inner <script> と併記すると、この後の _initialize が\n // そちらを採用して _setStatePromise を await しないため、bindWebComponent が\n // setInitialState で渡した innerState proxy ごと捨てられ、親↔子マッピングが\n // 無言で死ぬ。併記は必ず設定ミスなので fail-fast させる\n // (docs/architecture-hardening/15-state-component-mechanism-consistency.md §2.6)。\n const conflicting = [\"state\", \"src\", \"json\"].filter((name) => el.hasAttribute(name));\n if (el.querySelector('script[type=\"module\"]') !== null) {\n conflicting.push('<script type=\"module\">');\n }\n if (conflicting.length > 0) {\n raiseError(`\"bind-component\" cannot be combined with ${conflicting.join(\", \")}. The component's \"${el.getAttribute(\"bind-component\")}\" property is the only state source.`);\n }\n const boundComponentStateProp = el.getAttribute(\"bind-component\")!;\n // 束ねる意思をここで宣言する(完了はずっと後)。丸ごとマウント `state: user` の\n // 完了前の初期適用は、この宣言を見て書き込みを抑止する\n // (webComponent/completeWebComponent.ts)。下の await より前でなければ、\n // 親の初期適用が先に走って親のオブジェクトを state プロパティに書いてしまう。\n markWebComponentStatePropDeclared(boundComponent, boundComponentStateProp);\n const componentRegistry = getCustomElementRegistry(boundComponent);\n if (componentRegistry === null) {\n // null レジストリのサブツリーではホストは永久に upgrade されない。\n // whenDefined を待つと無言でウェッジするので落とす。\n raiseError(`CustomElementRegistry is unavailable for <${customTagName}>.`);\n }\n await componentRegistry.whenDefined(customTagName.toLowerCase());\n // data-wcs属性がある場合は、上位の状態によりbinding情報の設定が完了するまで待機する\n if (boundComponent.hasAttribute(config.bindAttributeName)) {\n await waitInitializeBinding(boundComponent);\n }\n if (!(boundComponentStateProp in boundComponent)) {\n raiseError(`Component does not have property \"${boundComponentStateProp}\" for state binding.`);\n }\n let state = (boundComponent as any)[boundComponentStateProp] as Record<string, any>;\n if (typeof state !== 'object' || state === null) {\n raiseError(`Component property \"${boundComponentStateProp}\" is not an object for state binding.`);\n }\n // 丸ごとマウント(`state: user`)の完了前の初期適用が、宣言より先に走って state\n // プロパティを親のオブジェクトごと置き換えていたら、作者のオブジェクトに戻す\n // (webComponent/preCompletionWrites.ts)。戻さないと親のキー全部が own data key に\n // なり、R1 で全部が私有に化ける。\n const authored = takeOverwrittenObject(boundComponent, boundComponentStateProp);\n if (typeof authored !== 'undefined' && hasRootMountBinding(boundComponent, boundComponentStateProp)) {\n (boundComponent as any)[boundComponentStateProp] = authored;\n state = authored as Record<string, any>;\n }\n ledger.boundComponent = boundComponent;\n ledger.boundComponentStateProp = boundComponentStateProp;\n element.setBoundComponent!(boundComponent, boundComponentStateProp);\n // data-wcs はあるが state 配線が無い Light DOM も plain(廃止 — 上と同じ誘導)。\n // 判定にホスト配線(台帳)が要るためここ(waitInitializeBinding の後)で行う\n if (!(parentNode instanceof ShadowRoot)\n && !(getBindingsByNode(boundComponent) ?? []).some((b) => b.propSegments[0] === boundComponentStateProp)) {\n failInitialization(element, \n `A plain (unwired) Light DOM \"bind-component\" is not supported. ` +\n `Attach a shadow root to <${customTagName}>, or mount it from the host ` +\n `(data-wcs=\"${boundComponentStateProp}: path\").`,\n );\n }\n // v2 マウント(Phase 2・impl-plan §3-0): この stateProp へのホスト配線\n //(ルートエントリ / 部分マウントのみ、Shadow / Light DOM とも)は単一ツリーで\n // 構築する。ホスト配線が 1 本も無い plain Shadow 形だけが下の bindWebComponent\n //(独立ツリー)に落ちる。\n if (boundComponent.hasAttribute(config.bindAttributeName)) {\n const hostBindings = (getBindingsByNode(boundComponent) ?? []).filter(\n (hostBinding) => hostBinding.propSegments[0] === boundComponentStateProp,\n );\n if (hostBindings.length > 0) {\n // 設定エラーは _failInitialization 経由(未解決 throw は waitForStateInitialize を\n // 永久待ちにしてページ全体をウェッジする — _failInitialization の注記参照)\n const parentStateElement = getStateElement(boundComponent.getRootNode() as Node)\n ?? failInitialization(element, `No state tree found on this root for mount host <${customTagName}>.`);\n // 再初期化(コンポーネントが connectedCallback で shadow の innerHTML を張り直す\n // 作りだと、再接続のたびに新しい <wcs-state> がここへ来る): 記録を再利用して\n // マーカーを安定させる。このとき上の `state` はもう公開プロキシ(下の\n // defineProperty 済み)だが、buildMountRecord を通らないので実害はない\n let record = getRegisteredMountRecord(boundComponent, boundComponentStateProp);\n const isReinitialize = record !== null;\n if (record === null) {\n // 宣言前の窓(fragment 内の初期適用)で積みが作者の既存キーを上書きして\n // いたら、作者の値に戻してから snapshot する(厳格 R1 — D19/D21)\n restoreOverwrittenValues(boundComponent, boundComponentStateProp, state);\n record = buildMountRecord(\n boundComponent,\n boundComponentStateProp,\n hostBindings,\n parentStateElement,\n state,\n getInjectedKeys(boundComponent, boundComponentStateProp),\n );\n warnOwnKeyShadowsForMount(record);\n }\n ledger.mountRecord = record;\n // shadow 張り直しの連打で、上の await 中に自分が剥がされた形。スコープは\n // 次に入った <wcs-state> が組み直すので触らない(_mountRecord は立てて、\n // connectedCallback の続きが v1 の _initialize に落ちないようにする)\n if (el.parentNode !== parentNode) {\n return;\n }\n // スコープ根: Shadow DOM 形はコンポーネントの shadowRoot、\n // Light DOM 形はコンポーネント要素自身(そのサブツリーがスコープ・D7)。\n // 設定エラー(1 スコープ根 1 マウント違反等)でも初期化待ちを\n // ウェッジさせない(_failInitialization と同じ規範 — resolve してから伝播)\n try {\n initializeMountScope(record, parentNode instanceof ShadowRoot ? parentNode : boundComponent);\n } catch (error) {\n // 着地はここで完了(_failInitialization と同じクラス — #257)\n element.landInitialization!();\n throw error;\n }\n if (!isReinitialize) {\n const publicState = createPublicMountState(record);\n Object.defineProperty(boundComponent, boundComponentStateProp, {\n get: () => publicState,\n enumerable: true,\n configurable: true,\n });\n markWebComponentAsComplete(boundComponent, boundComponentStateProp);\n }\n invokeStateReadyCallback(boundComponent, boundComponentStateProp);\n // 宣言面はマウントでは実行しない(1 回だけ誘導 warn — 設計書 §4-6)。\n // ライフサイクルはスコープごとに残る — $connectedCallback を chroot で呼ぶ\n warnMountedDollarDeclarations(record);\n callMountLifecycleCallback(record, \"$connectedCallback\");\n return;\n }\n }\n bindWebComponent(element, ledger.boundComponent!, ledger.boundComponentStateProp!, state);\n }\n}\n\nexport const bindComponentLifecycleHooks: ILifecycleHooks = {\n // ボリューム(20)の後。従来の分岐順(設計案 H3)\n order: 30,\n preparing(element) {\n const el = element as unknown as HTMLElement;\n if (!el.hasAttribute(\"bind-component\")) {\n return null;\n }\n const ledger = ledgerOf(element);\n return initializeBindWebComponent(element, ledger).then(() => {\n if (ledger.mountRecord === null) {\n // ホスト配線の無い plain Shadow 形: 独立ツリーを持つので core の初期化が続く\n return false;\n }\n // v2 マウント: この要素は独立ツリーを持たない(台帳エイリアスが親を指す)。\n // 名前登録・state ロード・$connectedCallback / $watch / $streams は行わない\n // (マウントスコープの $ 面は P2-9 — 設計書 §4-6)\n element.markInitialized!();\n element.settleInitialization!();\n return true;\n });\n },\n reconnecting(element) {\n const ledger = ledgerByElement.get(element);\n if (typeof ledger === \"undefined\" || ledger.mountRecord === null) {\n return false;\n }\n // マウント済みコンポーネントの再接続(行 content のプール再利用): 現在の行の\n // listIndex でマウントスコープの台帳を張り直し、最新値を適用する(§1.9 の v2 版)。\n // microtask に遅らせるのは、この接続が親の行ループ(mountAfter)の最中に同期で発火し、\n // 新しいループ文脈は直後の activateContent が張るため — 同期で張り直すと旧行の\n // listIndex を読んでしまう\n const mountRecord = ledger.mountRecord;\n // Shadow DOM 形は shadowRoot、Light DOM 形はコンポーネント要素自身\n const scopeRoot = (element as unknown as HTMLElement).parentNode as ShadowRoot | Element;\n queueMicrotask(() => {\n if (element.connectedRootNode == null) return; // 再接続後すぐ切断された(プール返却)\n remountScopeBindings(mountRecord, scopeRoot);\n });\n // 接続ごとのライフサイクル(v1 の $connectedCallback 再実行と同じ意味論)\n callMountLifecycleCallback(mountRecord, \"$connectedCallback\");\n return true;\n },\n disconnecting(element) {\n const ledger = ledgerByElement.get(element);\n if (typeof ledger === \"undefined\" || ledger.mountRecord === null) {\n return false;\n }\n // v2 マウント: 名前登録・streams・watch を持たないので後始末は不要。\n // 台帳エイリアスは消さない(プール再利用の再接続が同じスコープに戻る)。\n // $disconnectedCallback だけは要素のライフサイクルとして呼ぶ(例外は隔離)\n callMountLifecycleCallback(ledger.mountRecord, \"$disconnectedCallback\");\n // 公開 getter の答えが消えた(X6)— 親の依存者を再評価させる。プール返却も\n // 恒久破棄もここを通る(行ごと消えた形は $postUpdate が届かず無視される)\n notifyExports(ledger.mountRecord);\n element.clearConnectedRootNode!();\n return true;\n },\n};\n\nlet installed = false;\n/** 冪等。full / auto では `bootstrapState()` の `installVolumeGraft()` が呼ぶ */\nexport function installBindComponentLifecycle(): void {\n if (installed) return;\n installed = true;\n registerLifecycleHooks(\"bindComponent\", bindComponentLifecycleHooks);\n // 親スコープの適用が台帳を引く受け口(core/componentApplyHooks.ts)\n setComponentApplyHooks(bindComponentApplyHooks);\n}\n","import { getBindingsByNode } from \"../bindings/getBindingsByNode\";\nimport { config } from \"../config\";\n\n/**\n * ホストが `<stateProp>: path`(1 セグメント = 丸ごとマウント・ルート規則)を\n * このコンポーネントに書いているか。バインディング初期化が済んだ後に呼ぶこと\n * (`State._initializeBindWebComponent` は `waitInitializeBinding` の後で呼ぶ)。\n */\nexport function hasRootMountBinding(component: Element, stateProp: string): boolean {\n if (!component.hasAttribute(config.bindAttributeName)) {\n return false;\n }\n const bindings = getBindingsByNode(component);\n if (bindings === null) {\n return false;\n }\n for (const binding of bindings) {\n if (binding.propSegments.length === 1 && binding.propSegments[0] === stateProp) {\n return true;\n }\n }\n return false;\n}\n","/**\n * features/scopes.ts — `bind-component` のマウント・`mount=` のボリューム・オーバーレイ・DCC\n * (@wcstack/state/features/scopes)。要素のスコープを作る機能をひとまとめにする。\n */\nimport type { IStateFeature } from \"../core/features\";\nimport { installDccLifecycle } from \"../dcc/dccLifecycle\";\nimport { installVolumeGraft } from \"../webComponent/volume\";\n\nexport const scopes: IStateFeature = {\n name: \"scopes\",\n install(): void {\n // 接ぎ木の実体・スコープの hook・ボリューム / bind-component のライフサイクル\n installVolumeGraft();\n installDccLifecycle();\n },\n};\nexport default scopes;\n"],"names":["dccAddressHooks","written","stateElement","pathInfo","detail","map","bindableEventMap","exactEventName","path","isExact","eventName","segments","length","undefined","rootNode","ShadowRoot","host","dispatchEvent","CustomEvent","value","bubbles","installed","getterFn","name","stateEl","this","initialized","createState","state","e","console","warn","setterFn","initializePromise","then","callFn","isAsync","args","result","createStateAsync","async","isInternalProperty","startsWith","dccCandidateNames","descriptors","kind","Object","keys","filter","key","isMethod","readNameList","declarationName","declared","Array","isArray","raiseError","names","seen","Set","has","add","push","processDccDeclarations","bindables","STATE_BINDABLES_NAME","commands","STATE_COMMANDS_NAME","getAllPropertyDescriptors","streamNames","STATE_STREAMS_NAME","getStreamNames","streamBackedBindables","descriptor","didYouMean","defineDCC","hostElement","shadowRoot","tagName","toLowerCase","includes","definitionRegistry","getCustomElementRegistry","define","get","template","document","createElement","inertDocument","content","ownerDocument","childNode","from","childNodes","appendChild","importNode","shadowRootMode","mode","wcBindable","declaration","protocol","version","properties","propName","event","getter","target","inputs","declaredCommands","createWcBindable","createBindableEventMap","stateTagSelector","config","tagNames","DCCElement","HTMLElement","static","_shadow","_ensureShadow","hasAttribute","DCC_DEFINITION_ATTRIBUTE","attachShadow","cloneNode","registry","upgradeCustomElement","connectedCallback","shadow","querySelector","registerFeatureHooks","setBindableEventMap","desc","entries","newDesc","configurable","enumerable","constructor","set","defineProperty","prototype","initializeDcc","element","el","src","getAttribute","endsWith","loadFromScriptFile","script","loadFromInnerScript","loadDccState","markTreeless","markInitialized","clearConnectedRootNode","settleInitialization","error","failInitializeLoudly","dccLifecycleHooks","order","connecting","parentNode","reservedSlotsByRootNode","WeakMap","reserveVolumeSlot","mountPath","owner","slots","Map","current","isPathUnderReservedVolume","size","slot","DELIMITER","graftedSlotsByStateElement","createVolumeChroot","receiver","Proxy","_target","prop","$postUpdate","api","rest","volumeUpdatedCallbacksByRoot","NO_VOLUME_UPDATED_CALLBACKS","pendingVolumesByRootNode","failedRootNodes","WeakSet","orphanPendingVolume","request","onGrafted","graftHandler","exportIndexByStateElement","reportedShadows","slotFor","parentPath","create","byParent","byKey","holders","byListIndex","noIndex","isInstanceOf","record","listIndex","component","isConnected","own","getLoopContextByNode","parentListIndex","resolveExport","cached","holder","ref","deref","liveInstance","entry","found","foundRecord","delete","notifyExports","parent","parentStateElement","loopContext","delta","exports","values","setLoopContextSymbol","exportedPath","privateDataByRecord","OverlayValueHandler","markerParentPath","isBase","handler","accessorNameFor","accessorBySuffixByMarkerParent","accessorName","accessorAddress","createStateAddress","getPathInfo","_receiver","Reflect","translateInnerPath","contextIndexes","indexes","translated","translateInnerWritePath","composed","composeMountIndexes","$resolve","pushAddress","stateObject","popAddress","hasOwnProperty","call","checkDependency","method","bind","setterKeys","beginUntrack","endUntrack","createOverlayValue","address","markerBasePath","privateData","table","privateSnapshot","data","getPrivateData","createPublicMountState","withHostContext","callback","mutability","fn","writes","createChrootDollarApi","initializeMountScope","scopeRoot","existing","getMountRecordByScopeRoot","stateProp","getOrCreateBindingSession","dispose","registerMountRecord","setStateElementAlias","walkRoot","transform","parsed","forPath","translateParsedForMount","convertMustacheToComments","parentLoopContext","getRootNode","collectStructuralFragments","initializeBindings","buildMountScopeBindings","rootEntry","getterKeys","markerPath","markerIndex","indexOf","marker","markerTerminalPath","slice","suffix","exportedInfo","wildcardCount","lastSegment","WeakRef","addDynamicDependency","pathDiagnostics","markExported","markHasMounts","registerExports","tag","reportKey","parentValue","warnShadowedExports","setBindingsReadyForScope","Promise","resolve","remountScopeBindings","session","forEachActiveBindingNode","node","setLoopContextByNode","rebound","rebindAddresses","applyChangeFromBindings","isNodeInContentRange","firstNode","nextSibling","contains","lastNode","scopeAddressHooks","read","hasMounts","charCodeAt","mountRecord","getMountRecordByPath","NOT_HANDLED","readMissing","exported","parentAddress","proxy","readExportedAccessor","write","hasGraftedVolumes","shadowedSlot","prefix","findGraftedSlotUnder","writeMissing","_parentValue","_key","writeExportedAccessor","indexShift","lastAddress","lastPath","getIndexShiftForMarkerPath","handlerScope","findMountRecordForNode","shift","indexShiftByLoopElementPath","updated","refs","volumeCallbacks","getVolumeUpdatedCallbacks","volume","relativePaths","relativeIndexes","absolutePathInfo","relative","getScopedIndexes","suppressPathDiagnostic","rowReused","stateElementHasMounts","getMountRecordsForStateElement","getScopeRootByMountRecord","remountScopesUnderContent","ledgerByElement","ledgerOf","ledger","graftInfo","initializing","slotRootNode","detachedFrom","releaseSlot","releaseVolumeSlot","acquireSlot","getStateElement","markHasVolume","initializeVolume","connectedRootNode","segment","WILDCARD","validateVolumeMountPath","check","candidates","querySelectorAll","doc","readyState","addEventListener","queueMicrotask","once","setTimeout","reportVolumeWithoutRoot","finish","info","volumeState","loadStateFromSource","graftRootNode","rootStateElement","graftIsolated","installVolumeGraft","pending","queuePendingVolume","graftOrQueueVolume","volumeLifecycleHooks","CLAIMED","reconnecting","callVolumeLifecycle","replacingState","initializeFailed","_element","failPendingVolumes","initializeFailureCleared","clearFailedRootNode","disconnecting","completedStatePropsByWebComponent","markWebComponentAsComplete","webComponent","completedStateProps","declaredStatePropsByWebComponent","overwrittenObjectByElement","injectedKeysByElement","overwrittenValuesByElement","bindComponentApplyHooks","isComplete","isDeclared","rememberOverwrittenObject","previous","byProp","recordInjectedKey","rememberOverwrittenValue","meltFrozenObject","frozenObj","obj","proto","getPrototypeOf","clone","getOwnPropertyDescriptors","writable","defineProperties","cloneWithDescriptors","stateElementByWebComponent","OuterStateProxyHandler","_innerStateElement","stateMap","getStateElementByWebComponent","getOuter","outerState","bindWebComponent","innerStateElement","setStateElementByWebComponent","setInitialState","createOuterState","invokeStateReadyCallback","WEBCOMPONENT_STATE_READY_CALLBACK_NAME","func","catch","Error","message","String","reported","report","readMountRootTarget","outerPathInfo","failInitialization","landInitialization","initializeBindWebComponent","boundComponent","Element","customTagName","getCustomElement","bindAttributeName","conflicting","join","boundComponentStateProp","declaredStateProps","markWebComponentStatePropDeclared","componentRegistry","whenDefined","waitInitializeBinding","authored","takeOverwrittenObject","bindings","getBindingsByNode","binding","propSegments","hasRootMountBinding","setBoundComponent","some","b","hostBindings","hostBinding","getRegisteredMountRecord","isReinitialize","restoreOverwrittenValues","buildMountRecord","getInjectedKeys","mountTarget","mountTargetRead","outerPath","warnOwnKeyShadowsForMount","publicState","warnMountedDollarDeclarations","callMountLifecycleCallback","bindComponentLifecycleHooks","preparing","processVolumeDeclarations","watchDeclared","STATE_WATCH_NAME","paths","wrapped","cur","prev","setPathInfo","addVolumeWatchEntries","addVolumeWatchPaths","startWatch","listKeysDeclared","STATE_LIST_KEYS_NAME","translatedEntries","spec","mergeVolumeListKeys","STATE_UPDATED_CALLBACK_NAME","callbacks","addVolumeUpdatedCallback","enableUpdatedCallback","graftVolume","assertValidWatchPath","listKeys","STATE_RECURSION_NAME","RECURSION_WILDCARD","validateVolumeDeclarations","accessors","splitVolumeState","hydrated","hydratedFromSsr","i","exists","recordGraftedSlot","markHasGraftedVolumes","treePath","originalGet","originalSet","defineTreeAccessor","$connectedCallback","volumeGraftInstalled","registerLifecycleHooks","setComponentApplyHooks","onStateElementRegistered","adoptVolumesOnRootRegistered","hasReservedVolumeSlots","drainPendingVolumes","scopes","install"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { I as IStateFeature } from '../chunks/features.js';
2
+
3
+ /**
4
+ * features/ssr.ts — サーバー描画とハイドレーション(@wcstack/state/features/ssr)。
5
+ */
6
+
7
+ declare const ssr: IStateFeature;
8
+
9
+ export { ssr as default, ssr };