@wcstack/state 3.4.0 → 3.5.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"declarationAliases.js","sources":["../../../../../src/declarationAliases.ts"],"sourcesContent":["/**\n * declarationAliases.ts — 宣言キーの旧名 → 正式名(要件 B12・docs/state-3x-naming.ja.md V13 / V14)。\n *\n * `$updatedCallback` → `$renderedCallback`、`$streams` → `$stream`。旧名は 3.x の間は受け、4.0 で外す(D4)。\n * state オブジェクトがランタイムに入る入口(State の `_state` と `_loadStateFromSource`、マウント記録)で\n * 1 回だけ正規化し、以降のすべての読み手は正式名だけを見る。両方の綴りを宣言したらどちらが効くのか\n * 書き手に見えないので、名指しで落とす(D38)。\n */\nimport { STATE_STREAM_NAME, STATE_RENDERED_CALLBACK_NAME } from \"./define\";\nimport { LINT_HINT } from \"./errorGuidance\";\nimport { raiseError } from \"./raiseError\";\n\nexport const DECLARATION_ALIASES: Readonly<Record<string, string>> = {\n $updatedCallback: STATE_RENDERED_CALLBACK_NAME,\n $streams: STATE_STREAM_NAME,\n};\n\n/** 正規化済みの state オブジェクト(同じオブジェクトの再セット・ボリュームの 2 つの入口で二重に処理しない) */\nconst normalizedStates = new WeakSet<object>();\n\nfunction findOwner(value: object, key: string): object {\n let owner: object | null = value;\n while (owner !== null && !Object.prototype.hasOwnProperty.call(owner, key)) {\n owner = Object.getPrototypeOf(owner);\n }\n return owner!;\n}\n\n/**\n * 旧名で宣言されたキーを正式名へ写す。自前のプロパティなら旧名は消す。class の state でメソッドが\n * プロトタイプにある形(`$updatedCallback() {}`)は、インスタンスに正式名の定義を足すだけにする。\n */\nexport function normalizeDeclarationAliases(state: object): void {\n // state の出どころ(`src=\"./x.json\"` / `<script type=\"application/json\">` / インライン script)は\n // オブジェクト以外も返しうる(`JSON.parse(\"null\")` は `typeof` が \"object\")。ここは state が\n // ランタイムに入る最初の関門なので、`in` 演算子の素の TypeError ではなく形を名指しで落とす\n if (state === null || (typeof state !== \"object\" && typeof state !== \"function\")) {\n raiseError(\n `The state must be an object, got ${state === null ? \"null\" : typeof state}. ` +\n `Check the source of the state element (json / src / the inline <script>).`,\n );\n }\n if (normalizedStates.has(state)) {\n return;\n }\n for (const alias of Object.keys(DECLARATION_ALIASES)) {\n if (!(alias in state)) {\n continue;\n }\n const canonical = DECLARATION_ALIASES[alias];\n if (canonical in state) {\n raiseError(\n `[wcs/declaration-alias] The state declares both \"${alias}\" and \"${canonical}\". ` +\n `\"${alias}\" is the old name of \"${canonical}\" (it works through 3.x) — keep \"${canonical}\".${LINT_HINT}`,\n );\n }\n if (!Object.isExtensible(state)) {\n // 凍結・封印された state には正式名を足せない(`Object.defineProperty` が\n // \"object is not extensible\" で落ちる)。3.1 まで旧名のまま動いていた形なので、\n // 素の TypeError ではなく「正式名に書き換えよ」と名指しで案内する\n raiseError(\n `[wcs/declaration-alias] The state is not extensible, so the old name \"${alias}\" cannot be ` +\n `rewritten to \"${canonical}\". Declare \"${canonical}\" directly (the old name works through 3.x ` +\n `only on an extensible state).${LINT_HINT}`,\n );\n }\n const owner = findOwner(state, alias);\n const descriptor = Object.getOwnPropertyDescriptor(owner, alias)!;\n Object.defineProperty(state, canonical, { ...descriptor, configurable: true });\n if (owner === state) {\n delete (state as Record<string, unknown>)[alias];\n }\n }\n normalizedStates.add(state);\n}\n"],"names":["DECLARATION_ALIASES","$updatedCallback","STATE_RENDERED_CALLBACK_NAME","$streams","STATE_STREAM_NAME","normalizedStates","WeakSet","findOwner","value","key","owner","Object","prototype","hasOwnProperty","call","getPrototypeOf","normalizeDeclarationAliases","state","raiseError","has","alias","keys","canonical","LINT_HINT","isExtensible","descriptor","getOwnPropertyDescriptor","defineProperty","configurable","add"],"mappings":"8FAYO,MAAMA,EAAwD,CACnEC,iBAAkBC,EAClBC,SAAUC,GAINC,EAAmB,IAAIC,QAE7B,SAASC,EAAUC,EAAeC,GAChC,IAAIC,EAAuBF,EAC3B,KAAiB,OAAVE,IAAmBC,OAAOC,UAAUC,eAAeC,KAAKJ,EAAOD,IACpEC,EAAQC,OAAOI,eAAeL,GAEhC,OAAOA,CACT,CAMM,SAAUM,EAA4BC,GAU1C,IANc,OAAVA,GAAoC,iBAAVA,GAAuC,mBAAVA,IACzDC,EACE,oCAA8C,OAAVD,EAAiB,cAAgBA,iFAIrEZ,EAAiBc,IAAIF,GAAzB,CAGA,IAAK,MAAMG,KAAST,OAAOU,KAAKrB,GAAsB,CACpD,KAAMoB,KAASH,GACb,SAEF,MAAMK,EAAYtB,EAAoBoB,GAClCE,KAAaL,GACfC,EACE,oDAAoDE,WAAeE,QAC/DF,0BAA8BE,qCAA6CA,MAAcC,KAG5FZ,OAAOa,aAAaP,IAIvBC,EACE,yEAAyEE,8BACxDE,gBAAwBA,4EACTC,KAGpC,MAAMb,EAAQH,EAAUU,EAAOG,GACzBK,EAAad,OAAOe,yBAAyBhB,EAAOU,GAC1DT,OAAOgB,eAAeV,EAAOK,EAAW,IAAKG,EAAYG,cAAc,IACnElB,IAAUO,UACJA,EAAkCG,EAE9C,CACAf,EAAiBwB,IAAIZ,EA7BrB,CA8BF"}
1
+ {"version":3,"file":"declarationAliases.js","sources":["../../../../../src/declarationAliases.ts"],"sourcesContent":["/**\n * declarationAliases.ts — 宣言キーの旧名 → 正式名(要件 B12・docs/state-3x-naming.ja.md V13 / V14)。\n *\n * `$updatedCallback` → `$renderedCallback`、`$streams` → `$stream`。旧名は 3.x の間は受け、4.0 で外す(D4)。\n * state オブジェクトがランタイムに入る入口(State の `_state` と `_loadStateFromSource`、マウント記録)で\n * 1 回だけ正規化し、以降のすべての読み手は正式名だけを見る。両方の綴りを宣言したらどちらが効くのか\n * 書き手に見えないので、名指しで落とす(D38)。\n */\nimport { STATE_STREAM_NAME, STATE_RENDERED_CALLBACK_NAME } from \"./define\";\nimport { LINT_HINT } from \"./errorGuidance\";\nimport { raiseError } from \"./raiseError\";\nimport { v4Migration } from \"./core/v4MigrationHooks\";\n\nexport const DECLARATION_ALIASES: Readonly<Record<string, string>> = {\n $updatedCallback: STATE_RENDERED_CALLBACK_NAME,\n $streams: STATE_STREAM_NAME,\n};\n\n/** 正規化済みの state オブジェクト(同じオブジェクトの再セット・ボリュームの 2 つの入口で二重に処理しない) */\nconst normalizedStates = new WeakSet<object>();\n\nfunction findOwner(value: object, key: string): object {\n let owner: object | null = value;\n while (owner !== null && !Object.prototype.hasOwnProperty.call(owner, key)) {\n owner = Object.getPrototypeOf(owner);\n }\n return owner!;\n}\n\n/**\n * 旧名で宣言されたキーを正式名へ写す。自前のプロパティなら旧名は消す。class の state でメソッドが\n * プロトタイプにある形(`$updatedCallback() {}`)は、インスタンスに正式名の定義を足すだけにする。\n */\nexport function normalizeDeclarationAliases(state: object): void {\n // state の出どころ(`src=\"./x.json\"` / `<script type=\"application/json\">` / インライン script)は\n // オブジェクト以外も返しうる(`JSON.parse(\"null\")` は `typeof` が \"object\")。ここは state が\n // ランタイムに入る最初の関門なので、`in` 演算子の素の TypeError ではなく形を名指しで落とす\n if (state === null || (typeof state !== \"object\" && typeof state !== \"function\")) {\n raiseError(\n `The state must be an object, got ${state === null ? \"null\" : typeof state}. ` +\n `Check the source of the state element (json / src / the inline <script>).`,\n );\n }\n if (normalizedStates.has(state)) {\n return;\n }\n // 4.0 migration notices (3.5, D39): declaration keys 4.0 removes (old names, `$scan`) and 4.0's\n // `$behavior` / `$features`. Once per state object, before the old names are rewritten. Only the\n // full entries place the receptacle\n v4Migration?.state(state);\n for (const alias of Object.keys(DECLARATION_ALIASES)) {\n if (!(alias in state)) {\n continue;\n }\n const canonical = DECLARATION_ALIASES[alias];\n if (canonical in state) {\n raiseError(\n `[wcs/declaration-alias] The state declares both \"${alias}\" and \"${canonical}\". ` +\n `\"${alias}\" is the old name of \"${canonical}\" (it works through 3.x) — keep \"${canonical}\".${LINT_HINT}`,\n );\n }\n if (!Object.isExtensible(state)) {\n // 凍結・封印された state には正式名を足せない(`Object.defineProperty` が\n // \"object is not extensible\" で落ちる)。3.1 まで旧名のまま動いていた形なので、\n // 素の TypeError ではなく「正式名に書き換えよ」と名指しで案内する\n raiseError(\n `[wcs/declaration-alias] The state is not extensible, so the old name \"${alias}\" cannot be ` +\n `rewritten to \"${canonical}\". Declare \"${canonical}\" directly (the old name works through 3.x ` +\n `only on an extensible state).${LINT_HINT}`,\n );\n }\n const owner = findOwner(state, alias);\n const descriptor = Object.getOwnPropertyDescriptor(owner, alias)!;\n Object.defineProperty(state, canonical, { ...descriptor, configurable: true });\n if (owner === state) {\n delete (state as Record<string, unknown>)[alias];\n }\n }\n normalizedStates.add(state);\n}\n"],"names":["DECLARATION_ALIASES","$updatedCallback","STATE_RENDERED_CALLBACK_NAME","$streams","STATE_STREAM_NAME","normalizedStates","WeakSet","findOwner","value","key","owner","Object","prototype","hasOwnProperty","call","getPrototypeOf","normalizeDeclarationAliases","state","raiseError","has","alias","keys","canonical","LINT_HINT","isExtensible","descriptor","getOwnPropertyDescriptor","defineProperty","configurable","add"],"mappings":"8FAaO,MAAMA,EAAwD,CACnEC,iBAAkBC,EAClBC,SAAUC,GAINC,EAAmB,IAAIC,QAE7B,SAASC,EAAUC,EAAeC,GAChC,IAAIC,EAAuBF,EAC3B,KAAiB,OAAVE,IAAmBC,OAAOC,UAAUC,eAAeC,KAAKJ,EAAOD,IACpEC,EAAQC,OAAOI,eAAeL,GAEhC,OAAOA,CACT,CAMM,SAAUM,EAA4BC,GAU1C,IANc,OAAVA,GAAoC,iBAAVA,GAAuC,mBAAVA,IACzDC,EACE,oCAA8C,OAAVD,EAAiB,cAAgBA,iFAIrEZ,EAAiBc,IAAIF,GAAzB,CAOA,IAAK,MAAMG,KAAST,OAAOU,KAAKrB,GAAsB,CACpD,KAAMoB,KAASH,GACb,SAEF,MAAMK,EAAYtB,EAAoBoB,GAClCE,KAAaL,GACfC,EACE,oDAAoDE,WAAeE,QAC/DF,0BAA8BE,qCAA6CA,MAAcC,KAG5FZ,OAAOa,aAAaP,IAIvBC,EACE,yEAAyEE,8BACxDE,gBAAwBA,4EACTC,KAGpC,MAAMb,EAAQH,EAAUU,EAAOG,GACzBK,EAAad,OAAOe,yBAAyBhB,EAAOU,GAC1DT,OAAOgB,eAAeV,EAAOK,EAAW,IAAKG,EAAYG,cAAc,IACnElB,IAAUO,UACJA,EAAkCG,EAE9C,CACAf,EAAiBwB,IAAIZ,EAjCrB,CAkCF"}
@@ -1 +1 @@
1
- {"version":3,"file":"filterRegistry.js","sources":["../../../../../src/protocol/ssrSnapshot.ts","../../../../../src/config.ts","../../../../../src/binding/filterKey.ts","../../../../../src/core/filterRegistry.ts"],"sourcesContent":["// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/ssr-snapshot.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// ssr-snapshot protocol — how the SSR renderer asks whoever owns reactive\n// state to build hydration snapshots (<wcs-ssr>) as a final pass, after every\n// DOM inserter (router route content, late custom elements) has settled.\n//\n// Without this, the snapshot is built inside <wcs-state>'s connectedCallback\n// and races DOM inserted by other packages: whether a route's structural\n// templates make it into the snapshot depends on document order and state's\n// load mechanism (docs/ssr-router-design.md §5).\n//\n// The provider (@wcstack/state) installs itself on a well-known global symbol\n// at bootstrap. The renderer (@wcstack/server) looks the builder up after\n// running bootstraps: if present it announces orchestration by setting\n// `data-wcs-server=\"orchestrated\"` on the document element BEFORE parsing, and\n// calls build() right before serialization. The provider keeps its inline\n// per-element fallback whenever the attribute value is anything else, so:\n// - old renderer + new provider -> inline build, yesterday's behavior\n// - new renderer + old provider -> no builder found, attribute stays \"\",\n// the old provider builds inline as before\n// - new renderer + new provider -> orchestrated: snapshots are built last\n// and therefore always see settled DOM\n//\n// The symbol (rather than a package import) also pins the builder to the state\n// copy that actually runs on the page — its module-scoped fragment registries\n// are the ones the snapshot must read.\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/ssr-snapshot.ts), then\n// run `node scripts/sync-protocol-types.mjs` to regenerate the per-package\n// copies (packages/<pkg>/src/protocol/ssrSnapshot.ts). Those copies are\n// generated — do not edit them.\n\n/**\n * Global key the snapshot builder installs itself under. `Symbol.for` so\n * independently loaded copies of this file (state's and server's) still agree.\n */\nexport const SSR_SNAPSHOT_BUILDER_KEY = Symbol.for(\"wcstack.ssr.snapshotBuilder\");\n\n/**\n * `data-wcs-server` attribute value announcing that the renderer will call the\n * builder as a final pass. Providers must skip their inline per-element build\n * when they see this value, and keep it for any other value (including \"\").\n */\nexport const SSR_ORCHESTRATED_VALUE = \"orchestrated\";\n\nexport interface IWcsSsrSnapshotBuilder {\n readonly protocol: \"wcs-ssr-snapshot\";\n /** Integer protocol version. All versions >= 1 are participant-compatible. */\n readonly version: number;\n /**\n * Build a hydration snapshot for every enable-ssr state element in `root`\n * that does not already have one. Called once per render, after all\n * waiting-protocol elements have settled and bindings are ready. Must be\n * idempotent with respect to already-snapshotted elements.\n */\n build(root: Document): void;\n /**\n * Drop whatever the provider accumulated for **this render** in module-scoped\n * ledgers, so a long-lived rendering process does not grow one render at a time.\n * The renderer calls it once per render at the very end of its cleanup, after the\n * document is beyond use — never mid-render, because work still settling (bindings\n * finishing on a microtask chain) may read those ledgers.\n *\n * Optional and additive: a renderer must call it as `builder.reset?.()`, and a\n * provider that has nothing to drop may leave it out. Correctness of the *output*\n * must not depend on it — a provider scopes each snapshot to its own document\n * regardless — so an old renderer paired with a new provider only keeps memory\n * longer, it does not leak one render's content into another.\n *\n * It rides the protocol rather than a package import for the same reason `build`\n * does: the symbol pins it to the copy of the provider that actually ran, whose\n * module-scoped registries are the ones holding the garbage.\n */\n reset?(): void;\n}\n\n/**\n * The installed builder, or null when there is none or it speaks a shape this\n * reader does not.\n */\nexport function getSsrSnapshotBuilder(): IWcsSsrSnapshotBuilder | null {\n const candidate = (globalThis as Record<symbol, unknown>)[\n SSR_SNAPSHOT_BUILDER_KEY\n ] as IWcsSsrSnapshotBuilder | undefined;\n if (candidate === undefined || candidate === null) return null;\n if (candidate.protocol !== \"wcs-ssr-snapshot\") return null;\n if (typeof candidate.version !== \"number\" || candidate.version < 1) return null;\n if (typeof candidate.build !== \"function\") return null;\n return candidate;\n}\n","import { IConfig, IWritableConfig } from \"./types.js\";\nimport { SSR_ORCHESTRATED_VALUE } from \"./protocol/ssrSnapshot.js\";\n\n/**\n * サーバー主導スナップショット(orchestrated)の判定\n * (docs/ssr-router-design.md §5)。renderToString が snapshot builder を\n * 見つけたときだけ `data-wcs-server=\"orchestrated\"` を宣言する — 値が他の\n * もの(旧 server の \"\" を含む)なら inline 生成が従来どおり働く。\n * inSsr と同じ理由でキャッシュしない。\n */\nexport function isOrchestratedSsr(): boolean {\n const html = document.documentElement;\n return html ? html.getAttribute('data-wcs-server') === SSR_ORCHESTRATED_VALUE : false;\n}\n\nexport function inSsr(): boolean {\n // キャッシュしない: SSR モードはプロセスの属性ではなく「現在の document」の\n // 属性。@wcstack/server はグローバル document を差し替えてサーバーレンダリング\n // した後、同一プロセスでクライアント側ハイドレーションが走る(SSR→hydrate の\n // e2e が該当)。サーバーフェーズの判定をキャッシュするとクライアントフェーズが\n // SSR モード扱いになり、hydrateBindings の代わりに buildBindings が選ばれて\n // connectedCallbackPromise が永久に未解決になる。\n const html = document.documentElement;\n return html ? html.hasAttribute('data-wcs-server') : false;\n}\n\n/**\n * SSR 描画中に描いた枝・行を外した印(#356)。境界の組は Content の外に置くので、外した枝・行の中に\n * 入れ子で居た組が取り残され得る。取り残しは if の非表示と行の削除(apply/applyChangeToIf・\n * applyChangeToFor)からしか生じないので、立っていなければ `<wcs-ssr>` を書き出すときの探索\n * (ssr/Ssr.ts の removeStaleBlockBoundaries)を省く。下ろすのはサーバーのレンダリング 1 回分の後始末\n * (ssr/buildSsrDocument.ts の resetSsrRenderState)\n */\nexport const ssrBlockRemoval = { seen: false };\n\ninterface IInternalConfig {\n bindAttributeName: string;\n commentTextPrefix: string;\n commentForPrefix: string;\n commentIfPrefix: string;\n commentElseIfPrefix: string;\n commentElsePrefix: string;\n tagNames: {\n state: string;\n ssr: string;\n };\n locale: string;\n debug: boolean;\n enableMustache: boolean;\n enableDirectionalInitialSync: boolean;\n enablePropagationContext: boolean;\n enableContractAnalyzer: boolean;\n sameValueGuard: boolean;\n}\n\nconst _config: IInternalConfig = {\n bindAttributeName: 'data-wcs',\n commentTextPrefix: 'wcs-text',\n commentForPrefix: 'wcs-for',\n commentIfPrefix: 'wcs-if',\n commentElseIfPrefix: 'wcs-elseif',\n commentElsePrefix: 'wcs-else',\n tagNames: {\n state: 'wcs-state',\n ssr: 'wcs-ssr',\n },\n locale: 'en',\n debug: false,\n enableMustache: true,\n enableDirectionalInitialSync: true,\n enablePropagationContext: true,\n // Phase 5b の dev-time contract analyzer は意図的に explicit opt-in(既定 off)。\n // wcstack は buildless / zero-config で NODE_ENV 相当の確実な dev/prod 判定が無く、\n // hostname や minification の heuristic で auto-ON すると誤検出で prod にコストを\n // 乗せうるため、dev 既定 ON は採らない。利用側が setConfig で明示有効化する\n // (docs/architecture-hardening/10-defaulting-rollout-status.md §C)。\n enableContractAnalyzer: false,\n sameValueGuard: true,\n};\n\n// backward compatible export (read-only usage)\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n return config;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n if (typeof partialConfig.bindAttributeName === \"string\") {\n _config.bindAttributeName = partialConfig.bindAttributeName;\n }\n if (typeof partialConfig.commentTextPrefix === \"string\") {\n _config.commentTextPrefix = partialConfig.commentTextPrefix;\n }\n if (typeof partialConfig.commentForPrefix === \"string\") {\n _config.commentForPrefix = partialConfig.commentForPrefix;\n }\n if (typeof partialConfig.commentIfPrefix === \"string\") {\n _config.commentIfPrefix = partialConfig.commentIfPrefix;\n }\n if (typeof partialConfig.commentElseIfPrefix === \"string\") {\n _config.commentElseIfPrefix = partialConfig.commentElseIfPrefix;\n }\n if (typeof partialConfig.commentElsePrefix === \"string\") {\n _config.commentElsePrefix = partialConfig.commentElsePrefix;\n }\n if (typeof partialConfig.locale === \"string\") {\n _config.locale = partialConfig.locale;\n }\n if (typeof partialConfig.debug === \"boolean\") {\n _config.debug = partialConfig.debug;\n }\n if (typeof partialConfig.enableMustache === \"boolean\") {\n _config.enableMustache = partialConfig.enableMustache;\n }\n if (typeof partialConfig.enableDirectionalInitialSync === \"boolean\") {\n _config.enableDirectionalInitialSync = partialConfig.enableDirectionalInitialSync;\n }\n if (typeof partialConfig.enablePropagationContext === \"boolean\") {\n _config.enablePropagationContext = partialConfig.enablePropagationContext;\n }\n if (typeof partialConfig.enableContractAnalyzer === \"boolean\") {\n _config.enableContractAnalyzer = partialConfig.enableContractAnalyzer;\n }\n if (typeof partialConfig.sameValueGuard === \"boolean\") {\n _config.sameValueGuard = partialConfig.sameValueGuard;\n }\n}\n","/**\n * binding/filterKey.ts — フィルタの引数と並びを文字列の鍵にする(**唯一の基準**)。\n *\n * 鍵を作る場所は 2 つあり、規準がずれると必ず取り違えが起きる:\n * - `core/filterRegistry.ts` の解決済み実関数のキャッシュ\n * - ハンドラの共有キー(`event/twowayHandler.ts` / `radioHandler.ts` / `checkboxHandler.ts`)、\n * 束縛キー(`bindings/BindingSession.ts`)、devtools の宣言キー(`devtools/declaredBindings.ts`)\n *\n * どちらも `filterArgsKey` を通すことで、規準のずれを構造的に止める。\n */\n\n/**\n * 引数 1 組の鍵。**原文(`args`)と型付きの値(`literals`)の両方**を書き出す。\n *\n * - 原文だけだと `defaults(0)` と `defaults('0')` が同じ `[\"0\"]` になり、型の違う 2 つの\n * フィルタが同じ実関数・同じハンドラを共有する(要件 B9)。\n * - 型付きの値だけだと `toLiteral` の `Number()` 正規化で `1` / `1.0` / `01` / `+1` が\n * 同じ literal になり、原文を読む工場(`truncate` / `unit` / `join` / `ymd` / `padStart` …)が\n * 別の引数に対して同じ答えを引く。\n */\nexport function filterArgsKey(args: readonly string[], literals: readonly unknown[]): string {\n return `${JSON.stringify(args)}${JSON.stringify(literals)}`;\n}\n\n/** 鍵を作るのに要る最小の形(`IParsedFilter` / `IFilterInfo` と devtools の宣言情報の両方を受ける) */\ninterface IFilterKeySource {\n readonly filterName: string;\n readonly args: readonly string[];\n readonly literals?: readonly unknown[];\n}\n\n/**\n * フィルタの並びの鍵。`handlerByHandlerKey` はモジュール大域なので、ここで区別が付かないと\n * 後から配線された束縛が先の束縛のハンドラ(別のフィルタで畳まれた値を書くもの)を共有する。\n *\n * `literals` は束縛計画の段(`bindings/planFilters.ts`)が落とさずに持ち回している前提。\n * 省略された組み立て(devtools の宣言情報など)は原文で代用する。\n */\nexport function filterListKey(filters: readonly IFilterKeySource[]): string {\n if (filters.length === 0) {\n return \"\";\n }\n let key = \"\";\n for (let i = 0; i < filters.length; i++) {\n const filter = filters[i];\n if (i > 0) key += \"|\";\n key += `${filter.filterName}(${filterArgsKey(filter.args, filter.literals ?? filter.args)})`;\n }\n return key;\n}\n","/**\n * core/filterRegistry.ts — フィルタ実関数の登録簿(設計案 §4、要件 D16)。\n *\n * 文法(`path|filter(args)` の解析)は core に残り、**実関数は登録簿から束縛計画の段で引く**。\n * 解析の段は名前と引数しか作らない(`bindTextParser/parseFilters.ts`)ので、パーサだけを使う\n * tooling(`@wcstack/state/parser`)はフィルタの実装を 1 バイトも引き込まない。\n *\n * 書式フィルタ群(`uc` / `date` / `round` …)は `features/formats` が install で登録する。\n * core が自前で持つのは、エンジン自身が差し込む `not` だけ(`if` / `else` の反転 —\n * structural/notFilter.ts)。未知のフィルタは束縛計画の段で名指しで落ちる(従来は解析時)。\n */\nimport { filterArgsKey } from \"../binding/filterKey\";\nimport { didYouMean, LINT_HINT } from \"../errorGuidance\";\nimport type { FilterFn, FilterIOType, FilterWithOptions } from \"../filters/types\";\nimport { raiseError } from \"../raiseError\";\n\n/** `options` を受け取って実関数を返す工場(`filters/types.ts` の `FilterWithOptions` の要素) */\nexport type FilterFactory = (options?: string[], literals?: readonly unknown[]) => FilterFn;\n\n/**\n * エンジン自身が差し込むフィルタ。`if` / `else` の分岐は `not` を付けた束縛として組み立てられる\n * ので、`features/formats` の無いページでも必ず要る。\n *\n * `Map` であることに意味がある: 素のオブジェクトへのブラケット参照だと `Object.prototype` の\n * メンバがフィルタとして通り(`|toString` / `|constructor` / `|valueOf` / `|hasOwnProperty`)、\n * `[wcs/filter-unknown]` の代わりに意味不明な TypeError が出ていた。\n */\nconst CORE_FILTERS = new Map<string, FilterFactory>([\n [\"not\", () => (value: unknown): boolean => !value],\n]);\n\n/**\n * core が答えるフィルタの引数の個数(要件 B3)。`features/formats` を入れないページでも\n * `|not(1)` が名指しで落ちるように、登録簿とは別にここに持つ。\n */\nconst CORE_ARITIES = new Map<string, readonly [number, number]>([\n [\"not\", [0, 0]],\n]);\n\nconst registries: Record<FilterIOType, Map<string, FilterFactory>> = {\n input: new Map<string, FilterFactory>(),\n output: new Map<string, FilterFactory>(),\n};\n\n/** 受け付ける引数の個数 [最少, 最多]。登録した機能が渡したものだけ(要件 B3) */\nconst aritiesByIOType: Record<FilterIOType, Map<string, readonly [number, number]>> = {\n input: new Map<string, readonly [number, number]>(),\n output: new Map<string, readonly [number, number]>(),\n};\n\n/** 旧名 → 正式名(要件 B12)。解決・引数の個数は正式名で引く。登録した機能が渡したものだけ */\nconst aliasesByIOType: Record<FilterIOType, Map<string, string>> = {\n input: new Map<string, string>(),\n output: new Map<string, string>(),\n};\n\n/** 名前 + 引数 + 入出力ごとに解決済みの実関数(解決は 1 回だけ) */\nconst resolvedByKey = new Map<string, FilterFn>();\n\n/** 機能の install が呼ぶ(冪等 — 同じ名前は置き換え)。hot path には触れない */\nexport function registerFilters(\n filterIOType: FilterIOType,\n filters: FilterWithOptions,\n arity?: Readonly<Record<string, readonly [number, number]>>,\n aliases?: Readonly<Record<string, string>>,\n): void {\n const registry = registries[filterIOType];\n const arities = aritiesByIOType[filterIOType];\n for (const name of Object.keys(filters)) {\n registry.set(name, filters[name] as FilterFactory);\n const bounds = arity?.[name];\n if (typeof bounds === \"undefined\") {\n arities.delete(name);\n } else {\n arities.set(name, bounds);\n }\n }\n // 旧名も arity と同じ規則で掃除する(追加専用だと、登録簿を入れ替える tooling / テストに\n // 前の登録の旧名が残る)。「今回登録した正式名を指す旧名」だけを対象にするので、別の機能が\n // 登録した旧名は消さない\n const nextAliases = aliases ?? {};\n const aliasMap = aliasesByIOType[filterIOType];\n for (const [alias, canonical] of [...aliasMap]) {\n if (Object.prototype.hasOwnProperty.call(filters, canonical) && nextAliases[alias] !== canonical) {\n aliasMap.delete(alias);\n }\n }\n for (const alias of Object.keys(nextAliases)) {\n aliasMap.set(alias, nextAliases[alias]);\n }\n // 登録が変われば解決済みの答えも変わりうる(同じページで 2 回 install することは無いが、\n // テストと tooling は登録簿を入れ替える)\n resolvedByKey.clear();\n}\n\n/** 登録済みの名前(core のものを含む)。診断の did-you-mean が読む */\nexport function knownFilterNames(filterIOType: FilterIOType): string[] {\n return [...new Set([...CORE_FILTERS.keys(), ...registries[filterIOType].keys()])];\n}\n\n/** 解決済みの答えを捨てる(tooling: `@wcstack/state/parser` の clearParserCaches) */\nexport function clearFilterResolutionCache(): void {\n resolvedByKey.clear();\n}\n\n/**\n * 実関数を引く(束縛計画の段)。未知のフィルタはここで落ちる — 解析の段では落とさない。\n * 文言は lint の `wcs/filter-unknown` と同じ語彙・同じ did-you-mean 規準(三面同語彙)。\n */\nexport function resolveFilterFn(\n filterName: string,\n args: string[],\n filterIOType: FilterIOType,\n literals: readonly unknown[] = args,\n): FilterFn {\n // 旧名(`uc` / `fix` …)は正式名で引く — 3.x の間のエイリアス(要件 B12、4.0 で外す)。\n // 鍵も**正式名**で作るので、`uc` と `upper` は同じ実関数を共有する(旧名 1 つにつき\n // クロージャが 1 つ増えていた)\n const canonical = aliasesByIOType[filterIOType].get(filterName) ?? filterName;\n // 引数の鍵は `binding/filterKey.ts` の 1 本に集約する(原文 `args` と型付きの値 `literals` の\n // 両方 — 要件 B3 / B9)。ハンドラ共有キー側と同じ関数を通すことで、規準のずれを構造的に止める\n const key = `${canonical}${filterArgsKey(args, literals)}:${filterIOType}`;\n const resolved = resolvedByKey.get(key);\n if (typeof resolved !== \"undefined\") {\n return resolved;\n }\n const factory = registries[filterIOType].get(canonical) ?? CORE_FILTERS.get(canonical);\n if (typeof factory === \"undefined\") {\n // 書式フィルタ(`uc` / `date` …)は `features/formats` が install で登録する。1 つも\n // 登録されていないページは「打ち間違い」ではなく「機能の入れ忘れ」なので、そこまで案内する\n const missingFormats = registries[filterIOType].size === 0\n ? ` No formatting filters are installed — add them with installFeatures([...]) from \"@wcstack/state/features/formats\".`\n : \"\";\n raiseError(`[wcs/filter-unknown] filter not found: ${filterName}.${didYouMean(filterName, knownFilterNames(filterIOType))}${missingFormats}${LINT_HINT}`);\n }\n const bounds = aritiesByIOType[filterIOType].get(canonical) ?? CORE_ARITIES.get(canonical);\n if (typeof bounds !== \"undefined\" && (args.length < bounds[0] || args.length > bounds[1])) {\n // lint の wcs/filter-arity と同じ語彙\n raiseError(args.length < bounds[0]\n ? `[wcs/filter-arity] filter \"${filterName}\" requires at least ${bounds[0]} argument(s) (${args.length} given).${LINT_HINT}`\n : `[wcs/filter-arity] filter \"${filterName}\" accepts at most ${bounds[1]} argument(s) (${args.length} given).${LINT_HINT}`);\n }\n const filterFn = factory(args, literals);\n resolvedByKey.set(key, filterFn);\n return filterFn;\n}\n"],"names":["SSR_SNAPSHOT_BUILDER_KEY","Symbol","for","isOrchestratedSsr","html","document","documentElement","getAttribute","inSsr","hasAttribute","ssrBlockRemoval","seen","_config","bindAttributeName","commentTextPrefix","commentForPrefix","commentIfPrefix","commentElseIfPrefix","commentElsePrefix","tagNames","state","ssr","locale","debug","enableMustache","enableDirectionalInitialSync","enablePropagationContext","enableContractAnalyzer","sameValueGuard","config","getConfig","setConfig","partialConfig","Object","assign","filterArgsKey","args","literals","JSON","stringify","filterListKey","filters","length","key","i","filter","filterName","CORE_FILTERS","Map","value","CORE_ARITIES","registries","input","output","aritiesByIOType","aliasesByIOType","resolvedByKey","registerFilters","filterIOType","arity","aliases","registry","arities","name","keys","set","bounds","delete","nextAliases","aliasMap","alias","canonical","prototype","hasOwnProperty","call","clear","resolveFilterFn","get","resolved","factory","missingFormats","size","raiseError","didYouMean","Set","knownFilterNames","LINT_HINT","filterFn"],"mappings":"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"}
1
+ {"version":3,"file":"filterRegistry.js","sources":["../../../../../src/protocol/ssrSnapshot.ts","../../../../../src/config.ts","../../../../../src/binding/filterKey.ts","../../../../../src/core/filterRegistry.ts"],"sourcesContent":["// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/ssr-snapshot.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// ssr-snapshot protocol — how the SSR renderer asks whoever owns reactive\n// state to build hydration snapshots (<wcs-ssr>) as a final pass, after every\n// DOM inserter (router route content, late custom elements) has settled.\n//\n// Without this, the snapshot is built inside <wcs-state>'s connectedCallback\n// and races DOM inserted by other packages: whether a route's structural\n// templates make it into the snapshot depends on document order and state's\n// load mechanism (docs/ssr-router-design.md §5).\n//\n// The provider (@wcstack/state) installs itself on a well-known global symbol\n// at bootstrap. The renderer (@wcstack/server) looks the builder up after\n// running bootstraps: if present it announces orchestration by setting\n// `data-wcs-server=\"orchestrated\"` on the document element BEFORE parsing, and\n// calls build() right before serialization. The provider keeps its inline\n// per-element fallback whenever the attribute value is anything else, so:\n// - old renderer + new provider -> inline build, yesterday's behavior\n// - new renderer + old provider -> no builder found, attribute stays \"\",\n// the old provider builds inline as before\n// - new renderer + new provider -> orchestrated: snapshots are built last\n// and therefore always see settled DOM\n//\n// The symbol (rather than a package import) also pins the builder to the state\n// copy that actually runs on the page — its module-scoped fragment registries\n// are the ones the snapshot must read.\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/ssr-snapshot.ts), then\n// run `node scripts/sync-protocol-types.mjs` to regenerate the per-package\n// copies (packages/<pkg>/src/protocol/ssrSnapshot.ts). Those copies are\n// generated — do not edit them.\n\n/**\n * Global key the snapshot builder installs itself under. `Symbol.for` so\n * independently loaded copies of this file (state's and server's) still agree.\n */\nexport const SSR_SNAPSHOT_BUILDER_KEY = Symbol.for(\"wcstack.ssr.snapshotBuilder\");\n\n/**\n * `data-wcs-server` attribute value announcing that the renderer will call the\n * builder as a final pass. Providers must skip their inline per-element build\n * when they see this value, and keep it for any other value (including \"\").\n */\nexport const SSR_ORCHESTRATED_VALUE = \"orchestrated\";\n\nexport interface IWcsSsrSnapshotBuilder {\n readonly protocol: \"wcs-ssr-snapshot\";\n /** Integer protocol version. All versions >= 1 are participant-compatible. */\n readonly version: number;\n /**\n * Build a hydration snapshot for every enable-ssr state element in `root`\n * that does not already have one. Called once per render, after all\n * waiting-protocol elements have settled and bindings are ready. Must be\n * idempotent with respect to already-snapshotted elements.\n */\n build(root: Document): void;\n /**\n * Drop whatever the provider accumulated for **this render** in module-scoped\n * ledgers, so a long-lived rendering process does not grow one render at a time.\n * The renderer calls it once per render at the very end of its cleanup, after the\n * document is beyond use — never mid-render, because work still settling (bindings\n * finishing on a microtask chain) may read those ledgers.\n *\n * Optional and additive: a renderer must call it as `builder.reset?.()`, and a\n * provider that has nothing to drop may leave it out. Correctness of the *output*\n * must not depend on it — a provider scopes each snapshot to its own document\n * regardless — so an old renderer paired with a new provider only keeps memory\n * longer, it does not leak one render's content into another.\n *\n * It rides the protocol rather than a package import for the same reason `build`\n * does: the symbol pins it to the copy of the provider that actually ran, whose\n * module-scoped registries are the ones holding the garbage.\n */\n reset?(): void;\n}\n\n/**\n * The installed builder, or null when there is none or it speaks a shape this\n * reader does not.\n */\nexport function getSsrSnapshotBuilder(): IWcsSsrSnapshotBuilder | null {\n const candidate = (globalThis as Record<symbol, unknown>)[\n SSR_SNAPSHOT_BUILDER_KEY\n ] as IWcsSsrSnapshotBuilder | undefined;\n if (candidate === undefined || candidate === null) return null;\n if (candidate.protocol !== \"wcs-ssr-snapshot\") return null;\n if (typeof candidate.version !== \"number\" || candidate.version < 1) return null;\n if (typeof candidate.build !== \"function\") return null;\n return candidate;\n}\n","import { IConfig, IWritableConfig } from \"./types.js\";\nimport { SSR_ORCHESTRATED_VALUE } from \"./protocol/ssrSnapshot.js\";\n\n/**\n * サーバー主導スナップショット(orchestrated)の判定\n * (docs/ssr-router-design.md §5)。renderToString が snapshot builder を\n * 見つけたときだけ `data-wcs-server=\"orchestrated\"` を宣言する — 値が他の\n * もの(旧 server の \"\" を含む)なら inline 生成が従来どおり働く。\n * inSsr と同じ理由でキャッシュしない。\n */\nexport function isOrchestratedSsr(): boolean {\n const html = document.documentElement;\n return html ? html.getAttribute('data-wcs-server') === SSR_ORCHESTRATED_VALUE : false;\n}\n\nexport function inSsr(): boolean {\n // キャッシュしない: SSR モードはプロセスの属性ではなく「現在の document」の\n // 属性。@wcstack/server はグローバル document を差し替えてサーバーレンダリング\n // した後、同一プロセスでクライアント側ハイドレーションが走る(SSR→hydrate の\n // e2e が該当)。サーバーフェーズの判定をキャッシュするとクライアントフェーズが\n // SSR モード扱いになり、hydrateBindings の代わりに buildBindings が選ばれて\n // connectedCallbackPromise が永久に未解決になる。\n const html = document.documentElement;\n return html ? html.hasAttribute('data-wcs-server') : false;\n}\n\n/**\n * SSR 描画中に描いた枝・行を外した印(#356)。境界の組は Content の外に置くので、外した枝・行の中に\n * 入れ子で居た組が取り残され得る。取り残しは if の非表示と行の削除(apply/applyChangeToIf・\n * applyChangeToFor)からしか生じないので、立っていなければ `<wcs-ssr>` を書き出すときの探索\n * (ssr/Ssr.ts の removeStaleBlockBoundaries)を省く。下ろすのはサーバーのレンダリング 1 回分の後始末\n * (ssr/buildSsrDocument.ts の resetSsrRenderState)\n */\nexport const ssrBlockRemoval = { seen: false };\n\ninterface IInternalConfig {\n bindAttributeName: string;\n commentTextPrefix: string;\n commentForPrefix: string;\n commentIfPrefix: string;\n commentElseIfPrefix: string;\n commentElsePrefix: string;\n tagNames: {\n state: string;\n ssr: string;\n };\n locale: string;\n debug: boolean;\n enableMustache: boolean;\n enableDirectionalInitialSync: boolean;\n enablePropagationContext: boolean;\n enableContractAnalyzer: boolean;\n sameValueGuard: boolean;\n}\n\nconst _config: IInternalConfig = {\n bindAttributeName: 'data-wcs',\n commentTextPrefix: 'wcs-text',\n commentForPrefix: 'wcs-for',\n commentIfPrefix: 'wcs-if',\n commentElseIfPrefix: 'wcs-elseif',\n commentElsePrefix: 'wcs-else',\n tagNames: {\n state: 'wcs-state',\n ssr: 'wcs-ssr',\n },\n locale: 'en',\n debug: false,\n enableMustache: true,\n enableDirectionalInitialSync: true,\n enablePropagationContext: true,\n // Phase 5b の dev-time contract analyzer は意図的に explicit opt-in(既定 off)。\n // wcstack は buildless / zero-config で NODE_ENV 相当の確実な dev/prod 判定が無く、\n // hostname や minification の heuristic で auto-ON すると誤検出で prod にコストを\n // 乗せうるため、dev 既定 ON は採らない。利用側が setConfig で明示有効化する\n // (docs/architecture-hardening/10-defaulting-rollout-status.md §C)。\n enableContractAnalyzer: false,\n sameValueGuard: true,\n};\n\n// backward compatible export (read-only usage)\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n return config;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n if (typeof partialConfig.bindAttributeName === \"string\") {\n _config.bindAttributeName = partialConfig.bindAttributeName;\n }\n if (typeof partialConfig.commentTextPrefix === \"string\") {\n _config.commentTextPrefix = partialConfig.commentTextPrefix;\n }\n if (typeof partialConfig.commentForPrefix === \"string\") {\n _config.commentForPrefix = partialConfig.commentForPrefix;\n }\n if (typeof partialConfig.commentIfPrefix === \"string\") {\n _config.commentIfPrefix = partialConfig.commentIfPrefix;\n }\n if (typeof partialConfig.commentElseIfPrefix === \"string\") {\n _config.commentElseIfPrefix = partialConfig.commentElseIfPrefix;\n }\n if (typeof partialConfig.commentElsePrefix === \"string\") {\n _config.commentElsePrefix = partialConfig.commentElsePrefix;\n }\n if (typeof partialConfig.locale === \"string\") {\n _config.locale = partialConfig.locale;\n }\n if (typeof partialConfig.debug === \"boolean\") {\n _config.debug = partialConfig.debug;\n }\n if (typeof partialConfig.enableMustache === \"boolean\") {\n _config.enableMustache = partialConfig.enableMustache;\n }\n if (typeof partialConfig.enableDirectionalInitialSync === \"boolean\") {\n _config.enableDirectionalInitialSync = partialConfig.enableDirectionalInitialSync;\n }\n if (typeof partialConfig.enablePropagationContext === \"boolean\") {\n _config.enablePropagationContext = partialConfig.enablePropagationContext;\n }\n if (typeof partialConfig.enableContractAnalyzer === \"boolean\") {\n _config.enableContractAnalyzer = partialConfig.enableContractAnalyzer;\n }\n if (typeof partialConfig.sameValueGuard === \"boolean\") {\n _config.sameValueGuard = partialConfig.sameValueGuard;\n }\n}\n","/**\n * binding/filterKey.ts — フィルタの引数と並びを文字列の鍵にする(**唯一の基準**)。\n *\n * 鍵を作る場所は 2 つあり、規準がずれると必ず取り違えが起きる:\n * - `core/filterRegistry.ts` の解決済み実関数のキャッシュ\n * - ハンドラの共有キー(`event/twowayHandler.ts` / `radioHandler.ts` / `checkboxHandler.ts`)、\n * 束縛キー(`bindings/BindingSession.ts`)、devtools の宣言キー(`devtools/declaredBindings.ts`)\n *\n * どちらも `filterArgsKey` を通すことで、規準のずれを構造的に止める。\n */\n\n/**\n * 引数 1 組の鍵。**原文(`args`)と型付きの値(`literals`)の両方**を書き出す。\n *\n * - 原文だけだと `defaults(0)` と `defaults('0')` が同じ `[\"0\"]` になり、型の違う 2 つの\n * フィルタが同じ実関数・同じハンドラを共有する(要件 B9)。\n * - 型付きの値だけだと `toLiteral` の `Number()` 正規化で `1` / `1.0` / `01` / `+1` が\n * 同じ literal になり、原文を読む工場(`truncate` / `unit` / `join` / `ymd` / `padStart` …)が\n * 別の引数に対して同じ答えを引く。\n */\nexport function filterArgsKey(args: readonly string[], literals: readonly unknown[]): string {\n return `${JSON.stringify(args)}${JSON.stringify(literals)}`;\n}\n\n/** 鍵を作るのに要る最小の形(`IParsedFilter` / `IFilterInfo` と devtools の宣言情報の両方を受ける) */\ninterface IFilterKeySource {\n readonly filterName: string;\n readonly args: readonly string[];\n readonly literals?: readonly unknown[];\n}\n\n/**\n * フィルタの並びの鍵。`handlerByHandlerKey` はモジュール大域なので、ここで区別が付かないと\n * 後から配線された束縛が先の束縛のハンドラ(別のフィルタで畳まれた値を書くもの)を共有する。\n *\n * `literals` は束縛計画の段(`bindings/planFilters.ts`)が落とさずに持ち回している前提。\n * 省略された組み立て(devtools の宣言情報など)は原文で代用する。\n */\nexport function filterListKey(filters: readonly IFilterKeySource[]): string {\n if (filters.length === 0) {\n return \"\";\n }\n let key = \"\";\n for (let i = 0; i < filters.length; i++) {\n const filter = filters[i];\n if (i > 0) key += \"|\";\n key += `${filter.filterName}(${filterArgsKey(filter.args, filter.literals ?? filter.args)})`;\n }\n return key;\n}\n","/**\n * core/filterRegistry.ts — フィルタ実関数の登録簿(設計案 §4、要件 D16)。\n *\n * 文法(`path|filter(args)` の解析)は core に残り、**実関数は登録簿から束縛計画の段で引く**。\n * 解析の段は名前と引数しか作らない(`bindTextParser/parseFilters.ts`)ので、パーサだけを使う\n * tooling(`@wcstack/state/parser`)はフィルタの実装を 1 バイトも引き込まない。\n *\n * 書式フィルタ群(`uc` / `date` / `round` …)は `features/formats` が install で登録する。\n * core が自前で持つのは、エンジン自身が差し込む `not` だけ(`if` / `else` の反転 —\n * structural/notFilter.ts)。未知のフィルタは束縛計画の段で名指しで落ちる(従来は解析時)。\n */\nimport { filterArgsKey } from \"../binding/filterKey\";\nimport { didYouMean, LINT_HINT } from \"../errorGuidance\";\nimport type { FilterFn, FilterIOType, FilterWithOptions } from \"../filters/types\";\nimport { raiseError } from \"../raiseError\";\nimport { v4Migration } from \"./v4MigrationHooks\";\n\n/** `options` を受け取って実関数を返す工場(`filters/types.ts` の `FilterWithOptions` の要素) */\nexport type FilterFactory = (options?: string[], literals?: readonly unknown[]) => FilterFn;\n\n/**\n * エンジン自身が差し込むフィルタ。`if` / `else` の分岐は `not` を付けた束縛として組み立てられる\n * ので、`features/formats` の無いページでも必ず要る。\n *\n * `Map` であることに意味がある: 素のオブジェクトへのブラケット参照だと `Object.prototype` の\n * メンバがフィルタとして通り(`|toString` / `|constructor` / `|valueOf` / `|hasOwnProperty`)、\n * `[wcs/filter-unknown]` の代わりに意味不明な TypeError が出ていた。\n */\nconst CORE_FILTERS = new Map<string, FilterFactory>([\n [\"not\", () => (value: unknown): boolean => !value],\n]);\n\n/**\n * core が答えるフィルタの引数の個数(要件 B3)。`features/formats` を入れないページでも\n * `|not(1)` が名指しで落ちるように、登録簿とは別にここに持つ。\n */\nconst CORE_ARITIES = new Map<string, readonly [number, number]>([\n [\"not\", [0, 0]],\n]);\n\nconst registries: Record<FilterIOType, Map<string, FilterFactory>> = {\n input: new Map<string, FilterFactory>(),\n output: new Map<string, FilterFactory>(),\n};\n\n/** 受け付ける引数の個数 [最少, 最多]。登録した機能が渡したものだけ(要件 B3) */\nconst aritiesByIOType: Record<FilterIOType, Map<string, readonly [number, number]>> = {\n input: new Map<string, readonly [number, number]>(),\n output: new Map<string, readonly [number, number]>(),\n};\n\n/** 旧名 → 正式名(要件 B12)。解決・引数の個数は正式名で引く。登録した機能が渡したものだけ */\nconst aliasesByIOType: Record<FilterIOType, Map<string, string>> = {\n input: new Map<string, string>(),\n output: new Map<string, string>(),\n};\n\n/** 名前 + 引数 + 入出力ごとに解決済みの実関数(解決は 1 回だけ) */\nconst resolvedByKey = new Map<string, FilterFn>();\n\n/** 機能の install が呼ぶ(冪等 — 同じ名前は置き換え)。hot path には触れない */\nexport function registerFilters(\n filterIOType: FilterIOType,\n filters: FilterWithOptions,\n arity?: Readonly<Record<string, readonly [number, number]>>,\n aliases?: Readonly<Record<string, string>>,\n): void {\n const registry = registries[filterIOType];\n const arities = aritiesByIOType[filterIOType];\n for (const name of Object.keys(filters)) {\n registry.set(name, filters[name] as FilterFactory);\n const bounds = arity?.[name];\n if (typeof bounds === \"undefined\") {\n arities.delete(name);\n } else {\n arities.set(name, bounds);\n }\n }\n // 旧名も arity と同じ規則で掃除する(追加専用だと、登録簿を入れ替える tooling / テストに\n // 前の登録の旧名が残る)。「今回登録した正式名を指す旧名」だけを対象にするので、別の機能が\n // 登録した旧名は消さない\n const nextAliases = aliases ?? {};\n const aliasMap = aliasesByIOType[filterIOType];\n for (const [alias, canonical] of [...aliasMap]) {\n if (Object.prototype.hasOwnProperty.call(filters, canonical) && nextAliases[alias] !== canonical) {\n aliasMap.delete(alias);\n }\n }\n for (const alias of Object.keys(nextAliases)) {\n aliasMap.set(alias, nextAliases[alias]);\n }\n // 登録が変われば解決済みの答えも変わりうる(同じページで 2 回 install することは無いが、\n // テストと tooling は登録簿を入れ替える)\n resolvedByKey.clear();\n}\n\n/** 登録済みの名前(core のものを含む)。診断の did-you-mean が読む */\nexport function knownFilterNames(filterIOType: FilterIOType): string[] {\n return [...new Set([...CORE_FILTERS.keys(), ...registries[filterIOType].keys()])];\n}\n\n/** 解決済みの答えを捨てる(tooling: `@wcstack/state/parser` の clearParserCaches) */\nexport function clearFilterResolutionCache(): void {\n resolvedByKey.clear();\n}\n\n/**\n * 実関数を引く(束縛計画の段)。未知のフィルタはここで落ちる — 解析の段では落とさない。\n * 文言は lint の `wcs/filter-unknown` と同じ語彙・同じ did-you-mean 規準(三面同語彙)。\n */\nexport function resolveFilterFn(\n filterName: string,\n args: string[],\n filterIOType: FilterIOType,\n literals: readonly unknown[] = args,\n): FilterFn {\n // 旧名(`uc` / `fix` …)は正式名で引く — 3.x の間のエイリアス(要件 B12、4.0 で外す)。\n // 鍵も**正式名**で作るので、`uc` と `upper` は同じ実関数を共有する(旧名 1 つにつき\n // クロージャが 1 つ増えていた)\n const alias = aliasesByIOType[filterIOType].get(filterName);\n if (typeof alias !== \"undefined\") {\n // The 4.0 notice (3.5, D39), before the resolved-key lookup (keyed by the canonical name), so `uc`\n // is named even on a page that resolved `upper` first. Reached only when an old name is written\n v4Migration?.renamed(filterName, alias);\n }\n const canonical = alias ?? filterName;\n // 引数の鍵は `binding/filterKey.ts` の 1 本に集約する(原文 `args` と型付きの値 `literals` の\n // 両方 — 要件 B3 / B9)。ハンドラ共有キー側と同じ関数を通すことで、規準のずれを構造的に止める\n const key = `${canonical}${filterArgsKey(args, literals)}:${filterIOType}`;\n const resolved = resolvedByKey.get(key);\n if (typeof resolved !== \"undefined\") {\n return resolved;\n }\n const factory = registries[filterIOType].get(canonical) ?? CORE_FILTERS.get(canonical);\n if (typeof factory === \"undefined\") {\n // 書式フィルタ(`uc` / `date` …)は `features/formats` が install で登録する。1 つも\n // 登録されていないページは「打ち間違い」ではなく「機能の入れ忘れ」なので、そこまで案内する\n const missingFormats = registries[filterIOType].size === 0\n ? ` No formatting filters are installed — add them with installFeatures([...]) from \"@wcstack/state/features/formats\".`\n : \"\";\n raiseError(`[wcs/filter-unknown] filter not found: ${filterName}.${didYouMean(filterName, knownFilterNames(filterIOType))}${missingFormats}${LINT_HINT}`);\n }\n const bounds = aritiesByIOType[filterIOType].get(canonical) ?? CORE_ARITIES.get(canonical);\n if (typeof bounds !== \"undefined\" && (args.length < bounds[0] || args.length > bounds[1])) {\n // lint の wcs/filter-arity と同じ語彙\n raiseError(args.length < bounds[0]\n ? `[wcs/filter-arity] filter \"${filterName}\" requires at least ${bounds[0]} argument(s) (${args.length} given).${LINT_HINT}`\n : `[wcs/filter-arity] filter \"${filterName}\" accepts at most ${bounds[1]} argument(s) (${args.length} given).${LINT_HINT}`);\n }\n const filterFn = factory(args, literals);\n resolvedByKey.set(key, filterFn);\n return filterFn;\n}\n"],"names":["SSR_SNAPSHOT_BUILDER_KEY","Symbol","for","isOrchestratedSsr","html","document","documentElement","getAttribute","inSsr","hasAttribute","ssrBlockRemoval","seen","_config","bindAttributeName","commentTextPrefix","commentForPrefix","commentIfPrefix","commentElseIfPrefix","commentElsePrefix","tagNames","state","ssr","locale","debug","enableMustache","enableDirectionalInitialSync","enablePropagationContext","enableContractAnalyzer","sameValueGuard","config","getConfig","setConfig","partialConfig","Object","assign","filterArgsKey","args","literals","JSON","stringify","filterListKey","filters","length","key","i","filter","filterName","CORE_FILTERS","Map","value","CORE_ARITIES","registries","input","output","aritiesByIOType","aliasesByIOType","resolvedByKey","registerFilters","filterIOType","arity","aliases","registry","arities","name","keys","set","bounds","delete","nextAliases","aliasMap","alias","canonical","prototype","hasOwnProperty","call","clear","resolveFilterFn","get","resolved","factory","missingFormats","size","raiseError","didYouMean","Set","knownFilterNames","LINT_HINT","filterFn"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{r as t}from"./errorGuidance.js";import{aN as e}from"./binder.js";const n="https://github.com/wcstack/wcstack/blob/main/docs/csp.md";let r=0;async function i(t,e){let i=null;const o=`\n//# sourceURL=${e}#${++r}\n`;let a=!1;const c=t=>{t.effectiveDirective.startsWith("script-src")&&(a=!0)};document.addEventListener("securitypolicyviolation",c);try{if("function"==typeof URL.createObjectURL){const e=new Blob([t.text+o],{type:"application/javascript"}),n=URL.createObjectURL(e);try{i=await import(n)}finally{URL.revokeObjectURL(n)}}else{const e=btoa(String.fromCodePoint(...(new TextEncoder).encode(t.text+o)));i=await import(`data:application/javascript;base64,${e}`)}}catch(t){throw new Error(function(t,e,r){const i=e?.message??String(e);return r?`The inline <script> of state "${t}" was blocked by Content-Security-Policy. Inline state is evaluated through a blob: URL, so script-src must allow blob:. Prefer moving the state into an external file and loading it with src="./state.js", which requires no extra CSP directive. See ${n}`:`Failed to evaluate the inline <script> of state "${t}": ${i}. If this page sets a Content-Security-Policy, see ${n}`}(e,t,a),{cause:t})}finally{document.removeEventListener("securitypolicyviolation",c)}return i&&"object"==typeof i.default?i.default:{}}async function o(e){try{const t=await import(function(t){return new URL(t,document.baseURI).href}(e));return t.default||{}}catch(e){t(`Failed to load script file: ${e}`)}}const a=Promise.resolve(),c=new Map;let s=[];function l(t,e){c.set(t,e),s=Array.from(c.values()).sort((t,e)=>t.order-e.order)}function u(n,r){return t(e(n,r))}function f(t){for(let e=0;e<s.length;e++){const n=s[e].connecting?.(t);if(null!=n)return n}return null}function d(t){for(let e=0;e<s.length;e++){const n=s[e].preparing?.(t);if(null!=n)return n}return null}function p(t){for(let e=0;e<s.length;e++)if(!0===s[e].reconnecting?.(t))return!0;return!1}function h(t){for(let e=0;e<s.length;e++)s[e].replacingState?.(t)}function g(t,e,n){for(let r=0;r<s.length;r++)s[r].initializeFailed?.(t,e,n)}function m(t,e){for(let n=0;n<s.length;n++)s[n].initializeFailureCleared?.(t,e)}function y(t){for(let e=0;e<s.length;e++)if(!0===s[e].disconnecting?.(t))return!0;return!1}export{a as C,i as a,g as b,f as c,u as d,d as e,p as f,y as g,m as h,h as i,o as l,l as r};
1
+ import{r as t}from"./errorGuidance.js";import{aN as e}from"./binder.js";const n="https://github.com/wcstack/wcstack/blob/main/docs/csp.md";let r=0;async function i(t,e){let i=null;const o=`\n//# sourceURL=${e}#${++r}\n`;let a=!1;const c=t=>{t.effectiveDirective.startsWith("script-src")&&(a=!0)};document.addEventListener("securitypolicyviolation",c);try{if("function"==typeof URL.createObjectURL){const e=new Blob([t.text+o],{type:"application/javascript"}),n=URL.createObjectURL(e);try{i=await import(n)}finally{URL.revokeObjectURL(n)}}else{const e=btoa(String.fromCodePoint(...(new TextEncoder).encode(t.text+o)));i=await import(`data:application/javascript;base64,${e}`)}}catch(t){throw await new Promise(t=>setTimeout(t)),new Error(`[@wcstack/state] ${function(t,e,r){const i=e?.message??String(e);return r?`The inline <script> of state "${t}" was blocked by Content-Security-Policy. Inline state is evaluated through a blob: URL: give the page's nonce to the <script> that loads @wcstack/state, or allow blob: in script-src. Moving the state into an external file (src="./state.js") needs neither. See ${n}`:`Failed to evaluate the inline <script> of state "${t}": ${i}. If this page sets a Content-Security-Policy, see ${n}`}(e,t,a)}`,{cause:t})}finally{document.removeEventListener("securitypolicyviolation",c)}return i&&"object"==typeof i.default?i.default:{}}async function o(t){const e=await import(function(t){return new URL(t,document.baseURI).href}(t));return e.default||{}}const a=Promise.resolve(),c=new Map;let s=[];function l(t,e){c.set(t,e),s=Array.from(c.values()).sort((t,e)=>t.order-e.order)}function u(n,r){return t(e(n,r))}function f(t){for(let e=0;e<s.length;e++){const n=s[e].connecting?.(t);if(null!=n)return n}return null}function p(t){for(let e=0;e<s.length;e++){const n=s[e].preparing?.(t);if(null!=n)return n}return null}function d(t){for(let e=0;e<s.length;e++)if(!0===s[e].reconnecting?.(t))return!0;return!1}function h(t){for(let e=0;e<s.length;e++)s[e].replacingState?.(t)}function g(t,e,n){for(let r=0;r<s.length;r++)s[r].initializeFailed?.(t,e,n)}function m(t,e){for(let n=0;n<s.length;n++)s[n].initializeFailureCleared?.(t,e)}function b(t){for(let e=0;e<s.length;e++)if(!0===s[e].disconnecting?.(t))return!0;return!1}export{a as C,i as a,g as b,f as c,u as d,p as e,d as f,b as g,m as h,h as i,o as l,l as r};
2
2
  //# sourceMappingURL=lifecycleHooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycleHooks.js","sources":["../../../../../src/stateLoader/loadFromInnerScript.ts","../../../../../src/stateLoader/loadFromScriptFile.ts","../../../../../src/core/lifecycleHooks.ts"],"sourcesContent":["import { IState } from \"../types\";\n\ntype ScriptModule = { default?: unknown };\n\nconst CSP_GUIDE = \"https://github.com/wcstack/wcstack/blob/main/docs/csp.md\";\n\n/**\n * インライン `<script>` の評価失敗を、原因の分かるメッセージに変換する。\n *\n * CSP にブロックされた動的 import の rejection は\n * \"Failed to fetch dynamically imported module\" としか言わず、CSP には一切言及しない。\n * ブロックされた事実は securitypolicyviolation イベントでしか観測できないため、\n * その観測結果を `cspBlocked` で受け取る。\n *\n * 真ならブロック確定として対処方法まで書く。偽のときは構文エラー等と区別できないので、\n * 元のエラーを主にして CSP は参照先を添えるに留める(誤誘導を避ける)。\n */\nfunction describeImportFailure(name: string, error: unknown, cspBlocked: boolean): string {\n const detail = (error as Error)?.message ?? String(error);\n if (cspBlocked) {\n return `The inline <script> of state \"${name}\" was blocked by Content-Security-Policy. ` +\n `Inline state is evaluated through a blob: URL, so script-src must allow blob:. ` +\n `Prefer moving the state into an external file and loading it with src=\"./state.js\", ` +\n `which requires no extra CSP directive. See ${CSP_GUIDE}`;\n }\n return `Failed to evaluate the inline <script> of state \"${name}\": ${detail}. ` +\n `If this page sets a Content-Security-Policy, see ${CSP_GUIDE}`;\n}\n\n/**\n * ロードごとに増える通し番号。`data:` URL フォールバック(createObjectURL の無い\n * テスト / SSR 環境)では URL がスクリプト本文そのものなので、同じ本文を 2 度\n * 読み込むと ESM ローダーのキャッシュに当たり **同じモジュール = 同じ default export\n * オブジェクト** が返る — 2 つ目の `<wcs-state>` が 1 つ目の state を共有してしまう\n * (テストでは前のテストの書き込みが次のテストに漏れ、SSR では同一テンプレートの\n * 再描画で state が共有される)。blob: URL は生成のたびに一意なのでブラウザでは\n * 起きない。sourceURL コメントに番号を混ぜて本文を毎回変え、両経路を揃える。\n */\nlet loadSequence = 0;\n\nexport async function loadFromInnerScript(script: HTMLScriptElement, sourceLabel: string): Promise<IState> {\n let scriptModule: ScriptModule | null = null;\n const uniq_comment = `\\n//# sourceURL=${sourceLabel}#${++loadSequence}\\n`;\n // import() が失敗した理由が CSP かどうかを判別するために、評価の間だけ違反を購読する。\n let cspBlocked = false;\n const onViolation = (event: Event) => {\n if ((event as SecurityPolicyViolationEvent).effectiveDirective.startsWith(\"script-src\")) {\n cspBlocked = true;\n }\n };\n document.addEventListener(\"securitypolicyviolation\", onViolation);\n try {\n if (typeof URL.createObjectURL === 'function') {\n // Create a blob URL for the script and dynamically import it\n const blob = new Blob([script.text + uniq_comment], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n try {\n scriptModule = await import(url) as ScriptModule;\n } finally {\n // Clean up blob URL to prevent memory leak\n URL.revokeObjectURL(url);\n }\n } else {\n // Fallback: Base64 encoding method (for test environment)\n // Convert script to Base64 and import via data: URL\n const b64 = btoa(String.fromCodePoint(...new TextEncoder().encode(script.text + uniq_comment)));\n scriptModule = await import(`data:application/javascript;base64,${b64}`) as ScriptModule;\n }\n } catch (e) {\n // 呼び出し元(State._initialize / _initializeDCC)が raiseError で\n // `[@wcstack/state]` を付けるため、ここでは prefix を重ねない。\n throw new Error(describeImportFailure(sourceLabel, e, cspBlocked), { cause: e });\n } finally {\n document.removeEventListener(\"securitypolicyviolation\", onViolation);\n }\n return (scriptModule && typeof scriptModule.default === 'object') ? scriptModule.default as IState : {};\n}\n","import { raiseError } from \"../raiseError\";\nimport { IState } from \"../types\";\n\n/**\n * `src` の値を **document の base URL** に対して解決する。\n *\n * `import(url)` の相対解決は「import を書いたモジュール」を基準にする。ここは\n * `@wcstack/state` の中なので、素の `import(url)` は `<wcs-state src>` を\n * **state パッケージの所在**から解決してしまう。同一オリジンに置いたページでは\n * たまたま一致して見えるが、CDN 一発(`https://esm.run/@wcstack/state/auto`)で\n * 読み込んだ瞬間に `src=\"/app.js\"` が CDN 側の URL を指して 404 になる。\n *\n * `src` は HTML 属性なので、正しい基準は document の base URL である\n * (`src=\"*.json\"` 側は `fetch` がそう解決しており、同じ属性が形式によって\n * 違う基準で解決されていた)。絶対 URL・`data:`・`blob:` は URL 解決で\n * そのまま素通りするため、既存の使い方は影響を受けない。\n */\nexport function resolveAgainstDocument(url: string): string {\n return new URL(url, document.baseURI).href;\n}\n\nexport async function loadFromScriptFile(url: string): Promise<IState> {\n try {\n const module = await import(/* @vite-ignore */ resolveAgainstDocument(url));\n return module.default || {};\n } catch (e) {\n raiseError(`Failed to load script file: ${e}`);\n }\n}\n","/**\n * core/lifecycleHooks.ts — ライフサイクルの受け口(設計案 H3・H5、S4)。\n *\n * `connectedCallback` / `disconnectedCallback` の「この要素は自分のものだ」という分岐\n * (ボリューム `mount=`・DCC・bind-component)を機能側へ移すための受け口。機能は\n * `install()` で `registerLifecycleHooks` を呼び、core は登録順ではなく `order` の昇順で聞く\n * (install の順に依存させない — 従来の分岐順が契約なので、番号でそれを固定する)。\n *\n * `connecting` は「引き取らない」を **null** で返す。引き取るときだけ Promise を返すので、\n * 引き取り手の無い素の state(大多数)に microtask の境界を 1 つも足さない。\n */\nimport type { IStateElement } from \"../components/types\";\nimport { raiseError } from \"../raiseError\";\nimport { featureNotInstalledMessage } from \"./featureEntries\";\n\n/** 引き取ったが待つものが無いときの返り値 */\nexport const CLAIMED: Promise<void> = /*#__PURE__*/ Promise.resolve();\n\n/** 引き取るなら「この接続の初期化」の Promise、引き取らないなら null */\nexport type ConnectingHook = (element: IStateElement) => Promise<void> | null;\n/** 引き取って切断を処理したなら true */\nexport type DisconnectingHook = (element: IStateElement) => boolean;\n/**\n * 接続の前処理。「興味が無い」は null、あるなら「この要素を丸ごと引き取ったか」を解決する Promise。\n * `bind-component` のように「必ず走るが、引き取るのは条件つき」という機能のための段。\n */\nexport type PreparingHook = (element: IStateElement) => Promise<boolean> | null;\n/** 初期化済みの要素の再接続を引き取ったなら true */\nexport type ReconnectingHook = (element: IStateElement) => boolean;\n/** ルート要素の初期化が失敗した(このルートノードを待っている機能に知らせる) */\nexport type InitializeFailedHook = (element: IStateElement, rootNode: Node, error: unknown) => void;\n/** 失敗したルート要素自身が DOM から消えた(「このルートにルートは来ない」はもう成り立たない) */\nexport type InitializeFailureClearedHook = (element: IStateElement, rootNode: Node) => void;\n/** state の差し替えを拒むなら throw する(拒まないなら何もしない) */\nexport type ReplacingStateHook = (element: IStateElement) => void;\n\nexport interface ILifecycleHooks {\n /** 聞く順(従来の分岐順: DCC 10 → ボリューム 20 → bind-component 30) */\n readonly order: number;\n readonly connecting?: ConnectingHook;\n readonly preparing?: PreparingHook;\n readonly disconnecting?: DisconnectingHook;\n readonly reconnecting?: ReconnectingHook;\n readonly replacingState?: ReplacingStateHook;\n readonly initializeFailed?: InitializeFailedHook;\n readonly initializeFailureCleared?: InitializeFailureClearedHook;\n}\n\nconst registry = new Map<string, ILifecycleHooks>();\nlet ordered: ILifecycleHooks[] = [];\n\n/** 機能の install が呼ぶ(冪等) */\nexport function registerLifecycleHooks(feature: string, hooks: ILifecycleHooks): void {\n registry.set(feature, hooks);\n ordered = Array.from(registry.values()).sort((a, b) => a.order - b.order);\n}\n\n/**\n * 宣言(属性)が機能を要求したのに誰も引き取らなかった: 未 install として名指しで throw する\n * (readiness barrier、H5 / D13)。full / auto は `bootstrapState()` が install するので起きない。\n */\nexport function requireLifecycleFeature(feature: string, declaration: string): never {\n return raiseError(featureNotInstalledMessage(feature, declaration));\n}\n\n/** 接続を引き取る機能を探す。引き取り手が無ければ null(core が通常の初期化を続ける) */\nexport function runConnecting(element: IStateElement): Promise<void> | null {\n for (let i = 0; i < ordered.length; i++) {\n const claimed = ordered[i].connecting?.(element);\n if (claimed != null) {\n return claimed;\n }\n }\n return null;\n}\n\n/**\n * 接続の前処理を持つ機能を探す。1 つも無ければ null(素の state に microtask の境界を足さない)。\n * 解決値が true なら、その機能がこの要素を丸ごと引き取っている。\n */\nexport function runPreparing(element: IStateElement): Promise<boolean> | null {\n for (let i = 0; i < ordered.length; i++) {\n const prepared = ordered[i].preparing?.(element);\n if (prepared != null) {\n return prepared;\n }\n }\n return null;\n}\n\n/** 初期化済みの要素の再接続を引き取る機能を探す。引き取られたら true */\nexport function runReconnecting(element: IStateElement): boolean {\n for (let i = 0; i < ordered.length; i++) {\n if (ordered[i].reconnecting?.(element) === true) {\n return true;\n }\n }\n return false;\n}\n\n/** state の差し替えを拒む機能に聞く(拒む機能は throw する) */\nexport function runReplacingState(element: IStateElement): void {\n for (let i = 0; i < ordered.length; i++) {\n ordered[i].replacingState?.(element);\n }\n}\n\nexport function runInitializeFailed(element: IStateElement, rootNode: Node, error: unknown): void {\n for (let i = 0; i < ordered.length; i++) {\n ordered[i].initializeFailed?.(element, rootNode, error);\n }\n}\n\nexport function runInitializeFailureCleared(element: IStateElement, rootNode: Node): void {\n for (let i = 0; i < ordered.length; i++) {\n ordered[i].initializeFailureCleared?.(element, rootNode);\n }\n}\n\n/** 切断を引き取る機能を探す。引き取られたら true(core の後始末は走らない) */\nexport function runDisconnecting(element: IStateElement): boolean {\n for (let i = 0; i < ordered.length; i++) {\n if (ordered[i].disconnecting?.(element) === true) {\n return true;\n }\n }\n return false;\n}\n"],"names":["CSP_GUIDE","loadSequence","async","loadFromInnerScript","script","sourceLabel","scriptModule","uniq_comment","cspBlocked","onViolation","event","effectiveDirective","startsWith","document","addEventListener","URL","createObjectURL","blob","Blob","text","type","url","import","revokeObjectURL","b64","btoa","String","fromCodePoint","TextEncoder","encode","e","Error","name","error","detail","message","describeImportFailure","cause","removeEventListener","default","loadFromScriptFile","module","baseURI","href","resolveAgainstDocument","raiseError","CLAIMED","Promise","resolve","registry","Map","ordered","registerLifecycleHooks","feature","hooks","set","Array","from","values","sort","a","b","order","requireLifecycleFeature","declaration","featureNotInstalledMessage","runConnecting","element","i","length","claimed","connecting","runPreparing","prepared","preparing","runReconnecting","reconnecting","runReplacingState","replacingState","runInitializeFailed","rootNode","initializeFailed","runInitializeFailureCleared","initializeFailureCleared","runDisconnecting","disconnecting"],"mappings":"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"}
1
+ {"version":3,"file":"lifecycleHooks.js","sources":["../../../../../src/stateLoader/loadFromInnerScript.ts","../../../../../src/stateLoader/loadFromScriptFile.ts","../../../../../src/core/lifecycleHooks.ts"],"sourcesContent":["import { IState } from \"../types\";\n\ntype ScriptModule = { default?: unknown };\n\nconst CSP_GUIDE = \"https://github.com/wcstack/wcstack/blob/main/docs/csp.md\";\n\n/**\n * インライン `<script>` の評価失敗を、原因の分かるメッセージに変換する。\n *\n * CSP にブロックされた動的 import の rejection は\n * \"Failed to fetch dynamically imported module\" としか言わず、CSP には一切言及しない。\n * ブロックされた事実は securitypolicyviolation イベントでしか観測できないため、\n * その観測結果を `cspBlocked` で受け取る。\n *\n * 真ならブロック確定として対処方法まで書く。偽のときは構文エラー等と区別できないので、\n * 元のエラーを主にして CSP は参照先を添えるに留める(誤誘導を避ける)。\n *\n * The blob: import inherits the nonce of the `<script>` that loaded @wcstack/state (checked on\n * Chromium, Firefox and WebKit), so giving that script the page's nonce is a fix that needs no blob:\n * in script-src.\n */\nfunction describeImportFailure(name: string, error: unknown, cspBlocked: boolean): string {\n const detail = (error as Error)?.message ?? String(error);\n if (cspBlocked) {\n return `The inline <script> of state \"${name}\" was blocked by Content-Security-Policy. ` +\n `Inline state is evaluated through a blob: URL: give the page's nonce to the <script> that loads ` +\n `@wcstack/state, or allow blob: in script-src. Moving the state into an external file ` +\n `(src=\"./state.js\") needs neither. See ${CSP_GUIDE}`;\n }\n return `Failed to evaluate the inline <script> of state \"${name}\": ${detail}. ` +\n `If this page sets a Content-Security-Policy, see ${CSP_GUIDE}`;\n}\n\n/**\n * ロードごとに増える通し番号。`data:` URL フォールバック(createObjectURL の無い\n * テスト / SSR 環境)では URL がスクリプト本文そのものなので、同じ本文を 2 度\n * 読み込むと ESM ローダーのキャッシュに当たり **同じモジュール = 同じ default export\n * オブジェクト** が返る — 2 つ目の `<wcs-state>` が 1 つ目の state を共有してしまう\n * (テストでは前のテストの書き込みが次のテストに漏れ、SSR では同一テンプレートの\n * 再描画で state が共有される)。blob: URL は生成のたびに一意なのでブラウザでは\n * 起きない。sourceURL コメントに番号を混ぜて本文を毎回変え、両経路を揃える。\n */\nlet loadSequence = 0;\n\nexport async function loadFromInnerScript(script: HTMLScriptElement, sourceLabel: string): Promise<IState> {\n let scriptModule: ScriptModule | null = null;\n const uniq_comment = `\\n//# sourceURL=${sourceLabel}#${++loadSequence}\\n`;\n // import() が失敗した理由が CSP かどうかを判別するために、評価の間だけ違反を購読する。\n let cspBlocked = false;\n const onViolation = (event: Event) => {\n if ((event as SecurityPolicyViolationEvent).effectiveDirective.startsWith(\"script-src\")) {\n cspBlocked = true;\n }\n };\n document.addEventListener(\"securitypolicyviolation\", onViolation);\n try {\n if (typeof URL.createObjectURL === 'function') {\n // Create a blob URL for the script and dynamically import it\n const blob = new Blob([script.text + uniq_comment], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n try {\n scriptModule = await import(url) as ScriptModule;\n } finally {\n // Clean up blob URL to prevent memory leak\n URL.revokeObjectURL(url);\n }\n } else {\n // Fallback: Base64 encoding method (for test environment)\n // Convert script to Base64 and import via data: URL\n const b64 = btoa(String.fromCodePoint(...new TextEncoder().encode(script.text + uniq_comment)));\n scriptModule = await import(`data:application/javascript;base64,${b64}`) as ScriptModule;\n }\n } catch (e) {\n // Firefox fires the violation a task after the rejection (Chromium and WebKit before it): wait one\n // task before deciding, while still listening, so a CSP block is named on every engine. Only the\n // failure path waits\n await new Promise((resolve) => setTimeout(resolve));\n // The callers pass this error through unwrapped (connectedCallbackPromise rejects with it),\n // so it carries the package prefix itself, like the other loaders' errors.\n throw new Error(`[@wcstack/state] ${describeImportFailure(sourceLabel, e, cspBlocked)}`, { cause: e });\n } finally {\n document.removeEventListener(\"securitypolicyviolation\", onViolation);\n }\n return (scriptModule && typeof scriptModule.default === 'object') ? scriptModule.default as IState : {};\n}\n","import { IState } from \"../types\";\n\n/**\n * `src` の値を **document の base URL** に対して解決する。\n *\n * `import(url)` の相対解決は「import を書いたモジュール」を基準にする。ここは\n * `@wcstack/state` の中なので、素の `import(url)` は `<wcs-state src>` を\n * **state パッケージの所在**から解決してしまう。同一オリジンに置いたページでは\n * たまたま一致して見えるが、CDN 一発(`https://esm.run/@wcstack/state/auto`)で\n * 読み込んだ瞬間に `src=\"/app.js\"` が CDN 側の URL を指して 404 になる。\n *\n * `src` は HTML 属性なので、正しい基準は document の base URL である\n * (`src=\"*.json\"` 側は `fetch` がそう解決しており、同じ属性が形式によって\n * 違う基準で解決されていた)。絶対 URL・`data:`・`blob:` は URL 解決で\n * そのまま素通りするため、既存の使い方は影響を受けない。\n */\nexport function resolveAgainstDocument(url: string): string {\n return new URL(url, document.baseURI).href;\n}\n\nexport async function loadFromScriptFile(url: string): Promise<IState> {\n // A failure is not wrapped: the import() rejection (the module could not be fetched or parsed)\n // or the value the module itself threw propagates as is, and the element rejects\n // connectedCallbackPromise with that same value. The console report names the src.\n const module = await import(/* @vite-ignore */ resolveAgainstDocument(url));\n return module.default || {};\n}\n","/**\n * core/lifecycleHooks.ts — ライフサイクルの受け口(設計案 H3・H5、S4)。\n *\n * `connectedCallback` / `disconnectedCallback` の「この要素は自分のものだ」という分岐\n * (ボリューム `mount=`・DCC・bind-component)を機能側へ移すための受け口。機能は\n * `install()` で `registerLifecycleHooks` を呼び、core は登録順ではなく `order` の昇順で聞く\n * (install の順に依存させない — 従来の分岐順が契約なので、番号でそれを固定する)。\n *\n * `connecting` は「引き取らない」を **null** で返す。引き取るときだけ Promise を返すので、\n * 引き取り手の無い素の state(大多数)に microtask の境界を 1 つも足さない。\n */\nimport type { IStateElement } from \"../components/types\";\nimport { raiseError } from \"../raiseError\";\nimport { featureNotInstalledMessage } from \"./featureEntries\";\n\n/** 引き取ったが待つものが無いときの返り値 */\nexport const CLAIMED: Promise<void> = /*#__PURE__*/ Promise.resolve();\n\n/** 引き取るなら「この接続の初期化」の Promise、引き取らないなら null */\nexport type ConnectingHook = (element: IStateElement) => Promise<void> | null;\n/** 引き取って切断を処理したなら true */\nexport type DisconnectingHook = (element: IStateElement) => boolean;\n/**\n * 接続の前処理。「興味が無い」は null、あるなら「この要素を丸ごと引き取ったか」を解決する Promise。\n * `bind-component` のように「必ず走るが、引き取るのは条件つき」という機能のための段。\n */\nexport type PreparingHook = (element: IStateElement) => Promise<boolean> | null;\n/** 初期化済みの要素の再接続を引き取ったなら true */\nexport type ReconnectingHook = (element: IStateElement) => boolean;\n/** ルート要素の初期化が失敗した(このルートノードを待っている機能に知らせる) */\nexport type InitializeFailedHook = (element: IStateElement, rootNode: Node, error: unknown) => void;\n/** 失敗したルート要素自身が DOM から消えた(「このルートにルートは来ない」はもう成り立たない) */\nexport type InitializeFailureClearedHook = (element: IStateElement, rootNode: Node) => void;\n/** state の差し替えを拒むなら throw する(拒まないなら何もしない) */\nexport type ReplacingStateHook = (element: IStateElement) => void;\n\nexport interface ILifecycleHooks {\n /** 聞く順(従来の分岐順: DCC 10 → ボリューム 20 → bind-component 30) */\n readonly order: number;\n readonly connecting?: ConnectingHook;\n readonly preparing?: PreparingHook;\n readonly disconnecting?: DisconnectingHook;\n readonly reconnecting?: ReconnectingHook;\n readonly replacingState?: ReplacingStateHook;\n readonly initializeFailed?: InitializeFailedHook;\n readonly initializeFailureCleared?: InitializeFailureClearedHook;\n}\n\nconst registry = new Map<string, ILifecycleHooks>();\nlet ordered: ILifecycleHooks[] = [];\n\n/** 機能の install が呼ぶ(冪等) */\nexport function registerLifecycleHooks(feature: string, hooks: ILifecycleHooks): void {\n registry.set(feature, hooks);\n ordered = Array.from(registry.values()).sort((a, b) => a.order - b.order);\n}\n\n/**\n * 宣言(属性)が機能を要求したのに誰も引き取らなかった: 未 install として名指しで throw する\n * (readiness barrier、H5 / D13)。full / auto は `bootstrapState()` が install するので起きない。\n */\nexport function requireLifecycleFeature(feature: string, declaration: string): never {\n return raiseError(featureNotInstalledMessage(feature, declaration));\n}\n\n/** 接続を引き取る機能を探す。引き取り手が無ければ null(core が通常の初期化を続ける) */\nexport function runConnecting(element: IStateElement): Promise<void> | null {\n for (let i = 0; i < ordered.length; i++) {\n const claimed = ordered[i].connecting?.(element);\n if (claimed != null) {\n return claimed;\n }\n }\n return null;\n}\n\n/**\n * 接続の前処理を持つ機能を探す。1 つも無ければ null(素の state に microtask の境界を足さない)。\n * 解決値が true なら、その機能がこの要素を丸ごと引き取っている。\n */\nexport function runPreparing(element: IStateElement): Promise<boolean> | null {\n for (let i = 0; i < ordered.length; i++) {\n const prepared = ordered[i].preparing?.(element);\n if (prepared != null) {\n return prepared;\n }\n }\n return null;\n}\n\n/** 初期化済みの要素の再接続を引き取る機能を探す。引き取られたら true */\nexport function runReconnecting(element: IStateElement): boolean {\n for (let i = 0; i < ordered.length; i++) {\n if (ordered[i].reconnecting?.(element) === true) {\n return true;\n }\n }\n return false;\n}\n\n/** state の差し替えを拒む機能に聞く(拒む機能は throw する) */\nexport function runReplacingState(element: IStateElement): void {\n for (let i = 0; i < ordered.length; i++) {\n ordered[i].replacingState?.(element);\n }\n}\n\nexport function runInitializeFailed(element: IStateElement, rootNode: Node, error: unknown): void {\n for (let i = 0; i < ordered.length; i++) {\n ordered[i].initializeFailed?.(element, rootNode, error);\n }\n}\n\nexport function runInitializeFailureCleared(element: IStateElement, rootNode: Node): void {\n for (let i = 0; i < ordered.length; i++) {\n ordered[i].initializeFailureCleared?.(element, rootNode);\n }\n}\n\n/** 切断を引き取る機能を探す。引き取られたら true(core の後始末は走らない) */\nexport function runDisconnecting(element: IStateElement): boolean {\n for (let i = 0; i < ordered.length; i++) {\n if (ordered[i].disconnecting?.(element) === true) {\n return true;\n }\n }\n return false;\n}\n"],"names":["CSP_GUIDE","loadSequence","async","loadFromInnerScript","script","sourceLabel","scriptModule","uniq_comment","cspBlocked","onViolation","event","effectiveDirective","startsWith","document","addEventListener","URL","createObjectURL","blob","Blob","text","type","url","import","revokeObjectURL","b64","btoa","String","fromCodePoint","TextEncoder","encode","e","Promise","resolve","setTimeout","Error","name","error","detail","message","describeImportFailure","cause","removeEventListener","default","loadFromScriptFile","module","baseURI","href","resolveAgainstDocument","CLAIMED","registry","Map","ordered","registerLifecycleHooks","feature","hooks","set","Array","from","values","sort","a","b","order","requireLifecycleFeature","declaration","raiseError","featureNotInstalledMessage","runConnecting","element","i","length","claimed","connecting","runPreparing","prepared","preparing","runReconnecting","reconnecting","runReplacingState","replacingState","runInitializeFailed","rootNode","initializeFailed","runInitializeFailureCleared","initializeFailureCleared","runDisconnecting","disconnecting"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{i as t,c as e,b as s}from"./filterRegistry.js";import{l as n,a,b as i,c as o,d as r,e as l,f as d,g as c,h,i as u}from"./lifecycleHooks.js";import{r as p,d as f}from"./errorGuidance.js";import{d as _,j as m,l as g,au as y,c as b,o as k,m as w,av as S,k as P,aw as v,ax as $,ay as C,az as x,aA as I,aB as A,aC as N,aD as E,h as z,w as D,F as R,x as L,aE as j,aF as O,aG as T,aH as H,aI as G,g as M,aJ as F,aK as U,aL as W,aM as K,aN as V}from"./binder.js";import{u as q,v as B,w as J,b as Q,x as X,q as Y,D as Z,W as tt,R as et,g as st,y as nt,z as at,A as it,o as ot,B as rt,I as lt,C as dt,M as ct,c as ht,e as ut,N as pt,m as ft,i as _t,E as mt,k as gt,S as yt,a as bt,r as kt}from"./pathDiagnostics.js";import{n as wt}from"./declarationAliases.js";import{d as St,n as Pt,w as vt,g as $t,e as Ct,r as xt,c as It,b as At,h as Nt,s as Et,a as zt,f as Dt}from"./setAll.js";import{N as Rt,g as Lt,a as jt,c as Ot,b as Tt}from"./getAllPropertyDescriptors.js";import{a as Ht,b as Gt,c as Mt,d as Ft,e as Ut,f as Wt,g as Kt,h as Vt,i as qt,j as Bt}from"./declarationHooks.js";import{g as Jt}from"./checkDependency.js";import{p as Qt}from"./diagnosticsHooks.js";class Xt{_loopContextStack=Array(q).fill(void 0);_length=0;createLoopContext(t,e){null===t.listIndex&&p("Cannot create loop context for a state address that does not have a list index.");const s=t;this._length>=q&&p(`Exceeded maximum loop context stack depth of ${q}. Possible infinite loop.`);const n=this._loopContextStack[this._length-1];if(void 0!==n){n.pathInfo.wildcardCount+1!==s.pathInfo.wildcardCount&&p("Cannot push loop context for a list whose wildcard count is not exactly one more than the current active loop context.");const t=s.pathInfo.wildcardPathInfos[s.pathInfo.wildcardPathInfos.length-2];n.pathInfo!==t&&p("Cannot push loop context for a list whose parent wildcard path info does not match the current active loop context.")}else s.listIndex.length!==s.pathInfo.wildcardCount&&p(`Cannot push loop context when there is no active loop context: the list index chain (length ${s.listIndex.length}) does not cover the wildcard path (wildcard count ${s.pathInfo.wildcardCount}).`);let a;this._loopContextStack[this._length]=s,this._length++;try{a=e(s)}finally{a instanceof Promise?a.finally(()=>{this._length--,this._loopContextStack[this._length]=void 0}):(this._length--,this._loopContextStack[this._length]=void 0)}return a}}function Yt(t,e){if("all"===Jt(e).wildcardType)return!0;const s=t.getterPaths;if(0===s.size)return!1;for(const t of st(e).cumulativePaths)if(s.has(t))return!0;return!1}const Zt=/^\$\d+$/,te=`${ht}${Z}`,ee=`${ut}${Z}`,se=new WeakMap;function ne(t,e,s,n){const a=lt[e];if(void 0===a&&"string"==typeof e&&36===e.charCodeAt(0)&&Zt.test(e)&&p(`[wcs/index-param-range] "${e}" is not a valid list index parameter: they run from ${dt}1 to ${dt}${ct}, with no leading zeros.`),void 0!==a){0===n.addressStackLength&&p(`No active state reference to get list index for "${e.toString()}".`);const t=n.lastAddressStack,s=t?.pathInfo;s&&!n.untracking&&n.stateElement?.getterPaths.has(s.path)&&n.stateElement.addIndexDependentGetterPath?.(s.path);const i=t?.listIndex;null==i&&p(`ListIndex not found: ${e.toString()}`);let o=a;const r=t.pathInfo,l=n.stateElement?.addressHooks;if(l){const e=l.indexShift;for(let s=0;s<e.length;s++)o+=e[s](n,t)}const d=w(i,o,r.wildcardCount);return d?.index??p(`ListIndex not found: ${e.toString()}`)}if("string"==typeof e){const a=n.stateElement?.addressHooks;if(a){const i=a.get;for(let a=0;a<i.length;a++){const o=i[a](n,e,s,t);if(o!==Rt)return o}}if("$"===e[0]){switch(e){case"$stateElement":return n.stateElement;case"$getAll":return(a,i)=>At(t,e,s,n)(a,i);case"$setAll":return(a,i,o,r)=>It(t,e,s,n)(a,i,o,r);case"$postUpdate":return e=>function(t,e,s,n){const a=n.stateElement;return e=>{const i=Jt(e),o=St(t,i,s,n),r=m(i.pathInfo,o),l=g(a,r),d=b();d.enqueueAbsoluteAddress(l),Pt(a,i.pathInfo.path,()=>$t(t,r,s,n),s,n),vt(n.stateElement,r,n.stateElement.staticDependency,n.stateElement.dynamicDependency,n.stateElement.listPaths,s,"new",t=>{const e=g(a,t);y(e),d.enqueueAbsoluteAddress(e)});const c=a.addressHooks;if(c){const t=c.written;for(let e=0;e<t.length;e++)t[e](a,r.pathInfo)}}}(t,0,s,n)(e);case"$resolve":return(a,i,...o)=>xt(t,e,s,n)(a,i,...o);case"$dependOn":case"$trackDependency":return t=>function(t,e,s,n){return t=>{-1!==t.indexOf(et)&&p(`[wcs/recursion-unsupported] ${String(e)}("${t}") cannot take "**" — a dependency is registered against a concrete path (a fixed number of "*"). Track the concrete depth, or read the path through this[...] / $getAll inside the getter so the dependency is recorded automatically.`),0===n.addressStackLength&&p(`No active state reference to track dependency for path "${t}".`);const s=n.lastAddressStack?.pathInfo??p("Internal error: lastAddressStack is null"),a=n.stateElement;n.stateElement.getterPaths.has(s.path)&&s.path!==t&&a.addDynamicDependency(t,s.path)}}(0,e,0,n)(t);case"$eq":return(t,e)=>{const a=n.addressStackLength>0?n.lastAddressStack:null;if(Yt(n.stateElement,t))return null!==a&&n.stateElement.getterPaths.has(a.pathInfo.path)&&S(n.stateElement,t),Object.is(s[t],e);let i;n.beginUntrack();try{i=s[t]}finally{n.endUntrack()}return null!==a&&n.stateElement.getterPaths.has(a.pathInfo.path)&&C(n.stateElement,t,e,g(n.stateElement,a),i),Object.is(i,e)};case"$eqPath":return(t,e)=>{const a=n.addressStackLength>0?n.lastAddressStack:null,i=Yt(n.stateElement,t);let o,r=i?s[t]:void 0;n.beginUntrack();try{i||(r=s[t]),o=s[e]}finally{n.endUntrack()}return null!==a&&n.stateElement.getterPaths.has(a.pathInfo.path)&&(i?S(n.stateElement,t):C(n.stateElement,t,o,g(n.stateElement,a),r)),Object.is(r,o)};case"$eqIndex":return(t,e=1)=>{const a=n.addressStackLength>0?n.lastAddressStack:null;null!==a&&null!==a.listIndex||p(`$eqIndex("${t}") needs a list row scope.`);const i=w(a.listIndex,e-1,a.pathInfo.wildcardCount);if(null===i&&p(`$eqIndex("${t}", ${e}): no list index at that level.`),Yt(n.stateElement,t))return n.stateElement.getterPaths.has(a.pathInfo.path)&&(S(n.stateElement,t),n.stateElement.addIndexDependentGetterPath?.(a.pathInfo.path)),Object.is(s[t],i.index);const o=e===a.pathInfo.wildcardCount;let r,l;n.beginUntrack();try{r=s[t],o&&(l=s[a.pathInfo.wildcardParentPaths[e-1]])}finally{n.endUntrack()}if(n.stateElement.getterPaths.has(a.pathInfo.path)){const e=o?P(l):null;null!==e?v(n.stateElement,t,a.pathInfo,e,r):$(n.stateElement,t,i,g(n.stateElement,a),r)}return Object.is(r,i.index)};case"$untracked":case"$untrackDependency":return t=>function(t,e,s,n){return t=>{n.beginUntrack();try{return t()}finally{n.endUntrack()}}}(0,0,0,n)(t);case J:return Ct(n.stateElement)}if(!e.startsWith(te)&&!e.startsWith(ee))return}const i=Jt(e),o=St(t,i,s,n),r=m(i.pathInfo,o);return $t(t,r,s,n)}if("symbol"==typeof e){const a=function(t){let e=se.get(t);return void 0===e&&(e=new Map,se.set(t,e)),e}(n),i=a.get(e);if(void 0!==i)return i;let o;switch(e){case D:o=(t,e=()=>{})=>function(t,e,s){void 0!==t.loopContext&&p("already in loop context"),t.setLoopContext(e);try{t.pushAddress(e);try{return s()}finally{t.popAddress()}}finally{t.clearLoopContext()}}(n,t,e);break;case z:o=e=>$t(t,e,s,n);break;case E:o=e=>Nt(t,e,s,n);break;case N:o=()=>async function(t,e,s){const n=Reflect.get(t,at);"function"==typeof n&&await n.call(s)}(t,0,s);break;case A:o=()=>function(t,e,s){const n=Reflect.get(t,it);"function"==typeof n&&n.call(s)}(t,0,s);break;case I:o=e=>function(t,e,s,n){const a=Reflect.get(t,ot);let i;if("function"==typeof a){const t=new Set,o={};for(const s of e){if(s.absolutePathInfo.stateElement!==n.stateElement)continue;const e=s.absolutePathInfo.pathInfo,a=e.path;if(-1===a.indexOf("#")&&(t.add(a),e.wildcardCount>0)){const t=k(s.listIndex,e.wildcardCount),n=o[a];void 0===n?o[a]=[t]:n.push(t)}}(t.size>0||0===e.length)&&(i=a.call(s,Array.from(t),o))}const o=n.stateElement?.addressHooks;if(o){const t=o.updated;for(let a=0;a<t.length;a++)t[a](n.stateElement,e,s)}return i}(t,e,s,n);break;case x:o=(e,n)=>function(t,e,s,n){const a=Reflect.get(t,rt);"function"==typeof a&&a.call(n,e,s)}(t,e,n,s);break;default:return Reflect.get(t,e,s)}return a.set(e,o),o}}class ae{_stateElement;_addressStack=Array(q).fill(void 0);_addressStackIndex=-1;_loopContext;_mutability;_untrackDepth=0;constructor(t,e){const s=R(t);null===s&&p("StateHandler: no state tree found on this root."),this._stateElement=s,this._mutability=e}get stateElement(){return this._stateElement}get mutability(){return this._mutability}get lastAddressStack(){let t;return this._addressStackIndex>=0&&(t=this._addressStack[this._addressStackIndex]),void 0===t&&p("Last address stack is undefined."),t}get addressStackLength(){return this._addressStackIndex+1}get loopContext(){return this._loopContext}pushAddress(t){this._addressStackIndex+1>=q&&(this._hasRepeatedAddress()&&p(`[wcs/getter-cycle] Exceeded maximum address stack depth of ${q}. Possible circular dependency between path getters: ${this._describeAddressCycle()}`),p(`[wcs/getter-depth-exceeded] Exceeded maximum address stack depth of ${q} with no address visited twice — the data is simply nested deeper than the engine evaluates in one pass. Deepest path first: ${this._describeAddressCycle()}`)),this._addressStackIndex++,this._addressStack[this._addressStackIndex]=t}_hasRepeatedAddress(){const t=new Set;for(let e=0;e<=this._addressStackIndex;e++){const s=this._addressStack[e];if(s){if(t.has(s))return!0;t.add(s)}}return!1}_tailAddressPaths(){const t=[];for(let e=this._addressStackIndex;e>=0&&t.length<8;e--){const s=this._addressStack[e];s&&t.push(s.pathInfo.path)}return t}_describeAddressCycle(){const t=this._tailAddressPaths();return`${Array.from(new Set(t)).reverse().join(" -> ")} -> ...`}popAddress(){if(this._addressStackIndex<0)return null;const t=this._addressStack[this._addressStackIndex];return void 0===t&&p(`Address stack at index ${this._addressStackIndex} is undefined.`),this._addressStack[this._addressStackIndex]=void 0,this._addressStackIndex--,t}setLoopContext(t){this._loopContext=t}clearLoopContext(){this._loopContext=void 0}get untracking(){return this._untrackDepth>0}beginUntrack(){this._untrackDepth++}endUntrack(){this._untrackDepth--}get(t,e,s){return ne(t,e,s,this)}set(t,e,s,n){return zt(this),function(t,e,s,n,a){if("string"==typeof e){const i=Jt(e),o=St(t,i,n,a),r=m(i.pathInfo,o);return Et(t,r,s,n,a)}return Reflect.set(t,e,s,n)}(t,e,s,n,this)}has(t,e){return Reflect.has(t,e)}deleteProperty(t,e){return zt(this),Reflect.deleteProperty(t,e)}defineProperty(t,e,s){return zt(this),Reflect.defineProperty(t,e,s)}}const ie="undefined"==typeof HTMLElement?class{}:HTMLElement;const oe=new Set(["for","if","elseif","else"]);function re(e,s,n){const a=new Map;for(const t of n){const e=st(t);if(null===e.lastWildcardPath)continue;const s=a.get(e.lastWildcardPath);void 0===s?a.set(e.lastWildcardPath,[e]):s.push(e)}const i=[],o=new Set,r=t=>{const s=g(e,t);if(o.has(s))return;o.add(s);const n=H(s);if(n instanceof Set?i.push(...n):void 0!==n&&i.push(n),null!==t.listIndex){const e=a.get(t.pathInfo.path);if(void 0!==e)for(const s of e)r(m(s,t.listIndex))}};G();try{if(e.createState("readonly",t=>{for(const n of s){const s=m(st(n),null);r(s);try{vt(e,s,e.staticDependency,e.dynamicDependency,e.listPaths,t,"new",r)}catch{}}}),0===i.length)return;const n=function(t){const e=[],s=[];for(const n of t)oe.has(n.bindingType)?e.push(n):s.push(n);return e.sort((t,e)=>0!==(t.replaceNode.compareDocumentPosition(e.replaceNode)&Node.DOCUMENT_POSITION_FOLLOWING)?-1:1),e.concat(s)}(i),a=()=>{L(n,void 0,{updatedCallback:!1})};if(t())return void a();const o=j("state",a);void 0!==o&&o.catch(O)}finally{T()}}const le=[[_t,"watch"],[yt,"scan"],[bt,"streams"],[kt,"recursion"]];class de extends ie{static hasConnectedCallbackPromise=!0;static getBindingsReady(t){return M(t)}static get observedAttributes(){return["mount"]}__state;_hasUpdatedCallback=!1;_hasErrorCallback=!1;_hydratedFromSsr=!1;_crossRowListPaths=new Set;_indexDependentGetterPaths=new Set;_initialized=!1;_initializeFailed=!1;_initializationLanded=!1;_initializePromise;_resolveInitialize=null;_connectedCallbackPromise;_resolveConnectedCallback=null;_rejectConnectedCallback=null;_loadingPromise;_resolveLoading=null;_setStatePromise=null;_resolveSetState=null;_listPaths=new Set;_listKeys=null;_recursionRegistry=null;_elementPaths=new Set;_getterPaths=new Set;_setterPaths=new Set;_loopContextStack=function(){return new Xt}();_dynamicDependency=new Map;_staticDependency=new Map;_pathSet=new Set;_stateGeneration=0;_pathRegistrations=new Map;_pendingReapplyPaths=null;_generatedPaths=new Set;_watchPaths=null;_scanPaths=null;_version=0;_rootNode=null;_boundComponent=null;_boundComponentStateProp=null;_hasMounts=!1;_hasGraftedVolumes=!1;_addressHooks=null;_bindableEventMap={};_commandTokenNames=new Set;_eventTokenNames=new Set;_treeless=!1;_connectGeneration=0;constructor(){super(),this._initializePromise=new Promise(t=>{this._resolveInitialize=t}),this._connectedCallbackPromise=new Promise((t,e)=>{this._resolveConnectedCallback=t,this._rejectConnectedCallback=e}),this._loadingPromise=new Promise(t=>{this._resolveLoading=t}),this._setStatePromise=new Promise(t=>{this._resolveSetState=t})}get _state(){return void 0===this.__state&&p(`${e.tagNames.state} _state is not initialized yet.`),this.__state}set _state(t){wt(t),function(t){for(let e=0;e<le.length;e++){const[s,n]=le[e];s in t&&!Bt(n)&&p(V(n,`"${s}"`))}}(t);const e=this.__state,s=qt();s.set("previousState",e),Ht(this,t,s);const n=function(t){const e=new Set,s=t[B];if(void 0===s)return e;Array.isArray(s)||p(`${B} must be an array of strings.`);for(const t of s)"string"==typeof t&&0!==t.length||p(`${B} entries must be non-empty strings.`),t===J&&p(`${B} entry "${t}" conflicts with the reserved namespace name "${J}".`),e.has(t)&&p(`${B} entry "${t}" is duplicated.`),e.add(t);return e}(t),a=function(t){const e=new Set,s=t[Q];if(void 0===s)return e;Array.isArray(s)||p(`${Q} must be an array of strings.`);for(const t of s)"string"==typeof t&&0!==t.length||p(`${Q} entries must be non-empty strings.`),e.has(t)&&p(`${Q} entry "${t}" is duplicated.`),e.add(t);return e}(t),i=function(t){const e=t[Y];if(void 0===e)return null;"object"==typeof e&&null!==e||p(`${Y} must be an object mapping list paths to key specs.`);const s=new Map;for(const[t,n]of Object.entries(e)){0===t.length&&p(`${Y} entry path must be a non-empty string.`);const e=t.split(Z);e.some(t=>0===t.length)&&p(`${Y} entry "${t}" must not contain empty path segments.`),e[e.length-1]===tt&&p(`${Y} entry "${t}" must be the list path itself, not the element path (drop the trailing "${Z}${tt}").`),-1!==t.indexOf(et)&&p(`[wcs/recursion-unsupported] ${Y} entry "${t}" uses "${et}", which ${Y} does not interpret — a keyed list is one concrete list path. Declare the key per depth instead (for example "nodes${Z}${tt}${Z}children").`),"function"!=typeof n?("string"!=typeof n&&p(`${Y} entry "${t}" key spec must be a field name (string) or a function.`),0===n.length&&p(`${Y} entry "${t}" key field name must be a non-empty string.`),(n.includes(Z)||n.includes(tt))&&p(`${Y} entry "${t}" key field name "${n}" must be a flat property name ("${Z}" / "${tt}" are not allowed).`),n in Object.prototype&&p(`${Y} entry "${t}" key field name "${n}" must not be a property name inherited from Object.prototype (e.g. "__proto__", "constructor").`),s.set(t,n)):s.set(t,n)}return s.size>0?s:null}(t);s.set("eventTokenNames",a),Gt(this,t,s),Mt(this,t,s),this._commandTokenNames=n,this._eventTokenNames=a,this._stateGeneration++,this.__state=t,void 0!==e&&Qt?.reset(this),this._hasUpdatedCallback=ot in t,this._hasErrorCallback=rt in t,F(this),Ft(this,t,s),function(t,e,s){const n=e[X];if(void 0!==n){"object"==typeof n&&null!==n||p(`${X} must be an object mapping event-token names to handler functions.`);for(const[e,a]of Object.entries(n))s.has(e)||p(`${X} entry "${e}" is not declared in $eventTokens.${f(e,s)}`),"function"!=typeof a&&p(`${X} entry "${e}" must be a function.`),_(t,e).subscribe(a)}}(this,t,this._eventTokenNames),this._listPaths.clear(),this._elementPaths.clear(),this._getterPaths.clear(),this._setterPaths.clear(),this._pathSet.clear();const o=function(t){const e=new Set,s=new Set,n=Lt(t);for(const[t,a]of Object.entries(n))"function"==typeof a.get&&e.add(t),"function"==typeof a.set&&s.add(t);return{getterPaths:e,setterPaths:s}}(t);for(const t of o.getterPaths)this._getterPaths.add(t);for(const t of o.setterPaths)this._setterPaths.add(t);Ut(this,t,s),this._listKeys=i,this._rebuildPathInfo(),Wt(this,t,s),Kt(this,null),this._resolveLoading?.()}attributeChangedCallback(t,s,n){this._initialized&&s!==n&&console.warn(`[@wcstack/state] Changing the "mount" attribute after initialization is not supported and is ignored (was ${null===s?"absent":`"${s}"`}, now ${null===n?"absent":`"${n}"`}). Remove this <${e.tagNames.state}> element and create a new one with the desired mount path instead.`)}_loadFromSsrElement(){return this.hasAttribute("enable-ssr")?U('the "enable-ssr" attribute').loadState(this):null}async _loadStateFromSource(){try{if(this.hasAttribute("state")){return function(t){const e=document.getElementById(t);if(e&&"application/json"===e.type)try{return JSON.parse(e.textContent||"{}")}catch(t){p("Failed to parse JSON from script element:"+t)}return{}}(this.getAttribute("state"))}if(!this.hasAttribute("src")){if(this.hasAttribute("json")){const t=this.getAttribute("json");return JSON.parse(t)}{const t=this.querySelector('script[type="module"]');if(t)return await a(t,e.tagNames.state);{const t=setTimeout(()=>{console.warn(`[@wcstack/state] Warning: No state source found for <${e.tagNames.state}> element.`)},pt),s=await this._setStatePromise;return clearTimeout(t),s}}}{const t=this.getAttribute("src");if(t&&t.endsWith(".json"))return await async function(t){try{const e=await fetch(t);return e.ok||p(`Failed to fetch JSON file: ${e.statusText}`),await e.json()}catch(t){return console.error("Failed to load JSON file:",t),{}}}(t);if(t&&t.endsWith(".js"))return await n(t);p(`Unsupported src file type: ${t}`)}}catch(t){p(`Failed to initialize state: ${t}`)}}async _initialize(){const e=t()?null:this._loadFromSsrElement();if(null!==e&&(this._hydratedFromSsr=!0),this._state=await this._loadStateFromSource(),null!==e&&this.__state)for(const[t,s]of Object.entries(e)){if(t in this.__state){const e=Object.getOwnPropertyDescriptor(this.__state,t);if(e&&(e.get||e.set))continue;if("function"==typeof this.__state[t])continue}this.__state[t]=s}return await this._loadingPromise,null!==this._rootNode&&(W(this._rootNode,this),!0)}_failInitialization(t){this._initializationLanded=!0,this._resolveInitialize?.(),this._resolveLoading?.(),this._resolveConnectedCallback?.(),p(t)}_failInitializeLoudly(t,s=!0){if(this._initializationLanded)throw t;throw this._initializeFailed=!0,console.error(`[@wcstack/state] <${e.tagNames.state}> failed to initialize.`,t),this._resolveInitialize?.(),this._resolveLoading?.(),this._connectedCallbackPromise.catch(()=>{}),this._rejectConnectedCallback?.(t),s&&null!==this._rootNode&&null===R(this._rootNode)&&(K(this._rootNode,t),i(this,this._rootNode,t)),t}async _callStateConnectedCallback(){await this.createStateAsync("writable",async t=>{at in t&&await t[N]()})}_callStateDisconnectedCallback(){this.createState("writable",t=>{it in t&&t[A]()})}async connectedCallback(){this._rootNode=this.getRootNode();const n=++this._connectGeneration;if(this._initializationLanded=!1,this._initialized){if(d(this))return void this._resolveConnectedCallback?.();this._treeless||R(this._rootNode)===this||W(this._rootNode,this)}else{this.hasAttribute("name")&&this._failInitialization(this.hasAttribute("mount")?'"mount" replaces "name" — a volume has no name of its own. Remove the name attribute.':`The "name" attribute was removed in v2 — there is a single state tree per root. Mount this state onto the tree instead: <wcs-state mount="${this.getAttribute("name")}" ...> and read it as "${this.getAttribute("name")}.<path>".`);const t=o(this);if(null!==t)return void await t;if(this.hasAttribute("mount"))try{r("scopes",'the "mount" attribute')}catch(t){this._failInitializeLoudly(t,!1)}const s=this.parentNode;if(s instanceof ShadowRoot&&s.host.hasAttribute(ft))try{r("dcc",`a <${e.tagNames.state}> inside a [${ft}] host`)}catch(t){this._failInitializeLoudly(t)}let n=!1;try{const t=l(this);null===t&&this.hasAttribute("bind-component")&&r("scopes",'the "bind-component" attribute'),n=await(t??!1)}catch(t){this._failInitializeLoudly(t)}if(n)return;let a=!1;try{a=await this._initialize()}catch(t){this._failInitializeLoudly(t)}if(!a)return;this._initialized=!0,this._resolveInitialize?.()}if(null!==this._pendingReapplyPaths){const t=this._pendingReapplyPaths;this._pendingReapplyPaths=null,this._reapplyBindings(t)}if(this.hasAttribute("enable-ssr")&&!t()||n!==this._connectGeneration||await this._callStateConnectedCallback(),t()&&this.hasAttribute("enable-ssr")&&!s())try{await U('the "enable-ssr" attribute').emitSnapshot(this)}catch(t){throw this._rejectConnectedCallback?.(t),t}Kt(this,n),this._resolveConnectedCallback?.()}disconnectedCallback(){if(!c(this)&&null!==this._rootNode){if(!this._initialized)return this._initializeFailed&&h(this,this._rootNode),void(this._rootNode=null);try{this._callStateDisconnectedCallback()}finally{W(this.rootNode,null),Dt(this),Vt(this),this._rootNode=null}}}get initialized(){return this._initialized}get connectedRootNode(){return this._rootNode}clearConnectedRootNode(){this._rootNode=null}markInitialized(){this._initialized=!0}settleInitialization(){this._resolveInitialize?.(),this._resolveLoading?.(),this._resolveConnectedCallback?.()}loadStateFromSource(){return this._loadStateFromSource().then(t=>(wt(t),t))}markTreeless(){this._treeless=!0}failInitializeLoudly(t){return this._failInitializeLoudly(t)}get connectGeneration(){return this._connectGeneration}setWatchPaths(t){this._watchPaths=t}setScanPaths(t){this._scanPaths=t}landInitialization(){this._initializationLanded=!0,this._resolveInitialize?.(),this._resolveLoading?.(),this._resolveConnectedCallback?.()}setRecursionRegistry(t){this._recursionRegistry=t}addGeneratedPath(t){this._generatedPaths.add(t)}setBoundComponent(t,e){this._boundComponent=t,this._boundComponentStateProp=e}get initializePromise(){return this._initializePromise}get connectedCallbackPromise(){return this._connectedCallbackPromise}get listPaths(){return this._listPaths}get listKeys(){return this._listKeys}get hasRecursion(){return null!==this._recursionRegistry}get recursionRegistry(){return this._recursionRegistry}get watchPaths(){return this._watchPaths}get scanPaths(){return this._scanPaths}get elementPaths(){return this._elementPaths}addVolumeWatchPaths(t){if(0===t.size)return;const e=new Set(this._watchPaths??[]);for(const s of t)e.add(s);this._watchPaths=e,this.attachAddressHooks("watch",_t)}mergeVolumeListKeys(t){if(0===t.size)return;const e=new Map(this._listKeys??[]);for(const[s,n]of t)e.has(s)&&p(`$listKeys entry "${s}" is declared by both the root and a volume (or two volumes). Keep exactly one.`),e.set(s,n);this._listKeys=e}enableUpdatedCallback(){this._hasUpdatedCallback=!0}get hydratedFromSsr(){return this._hydratedFromSsr}addListPath(t){this._listPaths.add(t)}findStateDescriptor(t){return mt(this._state,t)}defineTreeAccessor(t,e){Object.defineProperty(this._state,t,e),"function"==typeof e.get&&this._getterPaths.add(t),"function"==typeof e.set&&this._setterPaths.add(t),this.setPathInfo(t,"prop","internal")}get getterPaths(){return this._getterPaths}get setterPaths(){return this._setterPaths}get loopContextStack(){return this._loopContextStack}get dynamicDependency(){return this._dynamicDependency}get staticDependency(){return this._staticDependency}get version(){return this._version}get stateGeneration(){return this._stateGeneration}get rootNode(){return null===this._rootNode&&p("State rootNode is not available."),this._rootNode}get boundComponentStateProp(){return this._boundComponentStateProp}get hasMounts(){return this._hasMounts}markHasMounts(){this._hasMounts=!0,this._attachScopeHooks("bind-component")}get hasGraftedVolumes(){return this._hasGraftedVolumes}get addressHooks(){return this._addressHooks}attachAddressHooks(t,e){const s=jt(t,e);null===this._addressHooks&&(this._addressHooks=Ot()),Tt(this._addressHooks,s)}markHasGraftedVolumes(){this._hasGraftedVolumes=!0,this._attachScopeHooks("mount")}markHasVolume(){this._attachScopeHooks("mount")}_attachScopeHooks(t){this.attachAddressHooks("scopes",t)}get bindableEventMap(){return this._bindableEventMap}get commandTokenNames(){return this._commandTokenNames}get eventTokenNames(){return this._eventTokenNames}setBindableEventMap(t){this._bindableEventMap=t,this.attachAddressHooks("dcc",gt)}_addDependency(t,e,s){const n=t.get(e);return void 0===n?(t.set(e,[s]),!0):!n.includes(s)&&(n.push(s),!0)}addDynamicDependency(t,e){if(!this._addDependency(this._dynamicDependency,t,e))return!1;const s=st(t);for(let t=s.parentPathInfo;null!==t&&t.wildcardCount>0&&t.wildcardCount===s.wildcardCount;t=t.parentPathInfo)this._addDependency(this._dynamicDependency,t.path,e);return!0}addStaticDependency(t,e){return this._addDependency(this._staticDependency,t,e)}setPathInfo(t,e,s="binding"){if("internal"!==s){const n=this._pathRegistrations.get(t);void 0===n?this._pathRegistrations.set(t,{bindingType:e,bound:"binding"===s}):"for"!==n.bindingType&&this._pathRegistrations.set(t,{bindingType:e,bound:n.bound||"binding"===s})}if("for"===e&&(this._listPaths.add(t),this._elementPaths.add(t+"."+tt)),!this._pathSet.has(t)){const e=st(t);this._pathSet.add(t);const n=function(t,e){const s=Jt(e);return"all"===s.wildcardType&&1===s.wildcardIndexes.length&&isNaN(+s.segments[0])&&!e.includes("#")&&Object.isExtensible(t)&&!(e in t)}(this.__state,t);if(Qt?.check(this,this.__state,t,s,n),n&&function(t,e){const{segments:s,cumulativePaths:n}=st(e),a=s.length-1,i=(t,i,o)=>{let r,l=!1;for(let d=0;d<=a;d++){const c=s[d];if(l||=!(isNaN(+c)||Array.isArray(r)&&+c in r),i&&d===a)return l?r[c]=o:t[e]=o;r=l?r?.[c]:t[n[d]]}return r},o=function(){return i(this)};nt.set(o,Jt(e).pathInfo.path),t.defineTreeAccessor(e,{get:o,set(t){i(this,!0,t)},configurable:!0})}(this,t),null!==e.parentPath){let t=e;for(;null!==t.parentPath&&this.addStaticDependency(t.parentPath,t.path);)t=st(t.parentPath)}}}_rebuildPathInfo(){for(const[t,e]of Array.from(this._pathRegistrations))e.bound&&!this._generatedPaths.has(t)&&this.setPathInfo(t,e.bindingType)}_createState(t,e,s){try{const n=function(t,e,s){const n=new ae(t,s);return new Proxy(e,n)}(t,this._state,e);return s(n)}finally{}}async createStateAsync(t,e){return await this._createState(this.rootNode,t,e)}createState(t,e){this._createState(this.rootNode,t,e)}nextVersion(){return this._version++,this._version}get hasUpdatedCallback(){return this._hasUpdatedCallback}get hasErrorCallback(){return this._hasErrorCallback}get crossRowListPaths(){return this._crossRowListPaths}addCrossRowListPath(t){this._crossRowListPaths.add(t)}get indexDependentGetterPaths(){return this._indexDependentGetterPaths}addIndexDependentGetterPath(t){this._indexDependentGetterPaths.add(t)}setInitialState(t){if(!this._initialized)return this._initializeFailed&&p(`<${e.tagNames.state}> failed to initialize (the diagnostic was reported when it connected), so its state cannot be replaced. Remove this element and create a new one with the corrected state.`),void this._resolveSetState?.(t);u(this),(this._hasGraftedVolumes||this._hasMounts)&&p("Cannot replace the whole state of a tree that has grafted volumes or mounted components: re-setting would silently drop grafted data, tree accessors and mount ledgers (D22). Write the changed paths instead.");const s=this.__state;this._state=t;const n=function(t){const e=new Set;for(const s of t)if(void 0!==s)for(const[t,n]of Object.entries(Lt(s)))t.startsWith("$")||t.includes(tt)||"function"==typeof n.value||e.add(t);return e}([s,t]);null!==this._rootNode?this._reapplyBindings(n):this._pendingReapplyPaths=new Set([...this._pendingReapplyPaths??[],...n])}_reapplyBindings(t){re(this,t,this._pathRegistrations.keys())}}const ce=[],he=[];function ue(){const t=[];let e=0;for(let s=0;s<he.length;s++){const n=he[s].deref();void 0!==n&&(t.push(n),he[e++]=he[s])}return he.length=e,t}function pe(t){if(!ce.includes(t)){ce.push(t);for(const e of ue())t(e)}}function fe(t=customElements){ue().includes(t)||he.push(new WeakRef(t));for(let e=0;e<ce.length;e++)ce[e](t);t.get(e.tagNames.state)||t.define(e.tagNames.state,de)}export{ie as H,pe as a,fe as r};
1
+ import{i as t,c as e,b as s}from"./filterRegistry.js";import{l as n,a,b as i,c as o,d as r,e as l,f as d,g as c,h,i as u}from"./lifecycleHooks.js";import{r as p,d as f}from"./errorGuidance.js";import{d as _,j as m,l as g,au as y,c as b,o as k,m as w,av as P,k as S,aw as $,ax as v,ay as C,az as x,aA as I,aB as A,aC as N,aD as E,h as z,w as D,F as R,x as j,aE as L,aF as T,aG as H,aH as O,aI as G,g as M,aJ as U,aK as F,aL as W,aM as K,aN as V}from"./binder.js";import{u as q,v as B,w as J,b as Q,x as X,q as Y,D as Z,W as tt,R as et,g as st,y as nt,z as at,A as it,o as ot,B as rt,I as lt,C as dt,M as ct,c as ht,e as ut,N as pt,m as ft,i as _t,E as mt,k as gt,S as yt,a as bt,r as kt}from"./pathDiagnostics.js";import{n as wt}from"./declarationAliases.js";import{d as Pt,n as St,w as $t,g as vt,e as Ct,r as xt,c as It,b as At,h as Nt,s as Et,a as zt,f as Dt}from"./setAll.js";import{N as Rt,g as jt,a as Lt,c as Tt,b as Ht}from"./getAllPropertyDescriptors.js";import{a as Ot,b as Gt,c as Mt,d as Ut,e as Ft,f as Wt,g as Kt,h as Vt,i as qt,j as Bt}from"./declarationHooks.js";import{g as Jt}from"./checkDependency.js";import{p as Qt}from"./diagnosticsHooks.js";class Xt{_loopContextStack=Array(q).fill(void 0);_length=0;createLoopContext(t,e){null===t.listIndex&&p("Cannot create loop context for a state address that does not have a list index.");const s=t;this._length>=q&&p(`Exceeded maximum loop context stack depth of ${q}. Possible infinite loop.`);const n=this._loopContextStack[this._length-1];if(void 0!==n){n.pathInfo.wildcardCount+1!==s.pathInfo.wildcardCount&&p("Cannot push loop context for a list whose wildcard count is not exactly one more than the current active loop context.");const t=s.pathInfo.wildcardPathInfos[s.pathInfo.wildcardPathInfos.length-2];n.pathInfo!==t&&p("Cannot push loop context for a list whose parent wildcard path info does not match the current active loop context.")}else s.listIndex.length!==s.pathInfo.wildcardCount&&p(`Cannot push loop context when there is no active loop context: the list index chain (length ${s.listIndex.length}) does not cover the wildcard path (wildcard count ${s.pathInfo.wildcardCount}).`);let a;this._loopContextStack[this._length]=s,this._length++;try{a=e(s)}finally{a instanceof Promise?a.finally(()=>{this._length--,this._loopContextStack[this._length]=void 0}):(this._length--,this._loopContextStack[this._length]=void 0)}return a}}function Yt(t,e){if("all"===Jt(e).wildcardType)return!0;const s=t.getterPaths;if(0===s.size)return!1;for(const t of st(e).cumulativePaths)if(s.has(t))return!0;return!1}const Zt=/^\$\d+$/,te=`${ht}${Z}`,ee=`${ut}${Z}`,se=new WeakMap;function ne(t,e,s,n){const a=lt[e];if(void 0===a&&"string"==typeof e&&36===e.charCodeAt(0)&&Zt.test(e)&&p(`[wcs/index-param-range] "${e}" is not a valid list index parameter: they run from ${dt}1 to ${dt}${ct}, with no leading zeros.`),void 0!==a){0===n.addressStackLength&&p(`No active state reference to get list index for "${e.toString()}".`);const t=n.lastAddressStack,s=t?.pathInfo;s&&!n.untracking&&n.stateElement?.getterPaths.has(s.path)&&n.stateElement.addIndexDependentGetterPath?.(s.path);const i=t?.listIndex;null==i&&p(`ListIndex not found: ${e.toString()}`);let o=a;const r=t.pathInfo,l=n.stateElement?.addressHooks;if(l){const e=l.indexShift;for(let s=0;s<e.length;s++)o+=e[s](n,t)}const d=w(i,o,r.wildcardCount);return d?.index??p(`ListIndex not found: ${e.toString()}`)}if("string"==typeof e){const a=n.stateElement?.addressHooks;if(a){const i=a.get;for(let a=0;a<i.length;a++){const o=i[a](n,e,s,t);if(o!==Rt)return o}}if("$"===e[0]){switch(e){case"$stateElement":return n.stateElement;case"$getAll":return(a,i)=>At(t,e,s,n)(a,i);case"$setAll":return(a,i,o,r)=>It(t,e,s,n)(a,i,o,r);case"$postUpdate":return e=>function(t,e,s,n){const a=n.stateElement;return e=>{const i=Jt(e),o=Pt(t,i,s,n),r=m(i.pathInfo,o),l=g(a,r),d=b();d.enqueueAbsoluteAddress(l),St(a,i.pathInfo.path,()=>vt(t,r,s,n),s,n),$t(n.stateElement,r,n.stateElement.staticDependency,n.stateElement.dynamicDependency,n.stateElement.listPaths,s,"new",t=>{const e=g(a,t);y(e),d.enqueueAbsoluteAddress(e)});const c=a.addressHooks;if(c){const t=c.written;for(let e=0;e<t.length;e++)t[e](a,r.pathInfo)}}}(t,0,s,n)(e);case"$resolve":return(a,i,...o)=>xt(t,e,s,n)(a,i,...o);case"$trackDependency":case"$dependOn":return t=>function(t,e,s,n){return t=>{-1!==t.indexOf(et)&&p(`[wcs/recursion-unsupported] ${String(e)}("${t}") cannot take "**" — a dependency is registered against a concrete path (a fixed number of "*"). Track the concrete depth, or read the path through this[...] / $getAll inside the getter so the dependency is recorded automatically.`),0===n.addressStackLength&&p(`No active state reference to track dependency for path "${t}".`);const s=n.lastAddressStack?.pathInfo??p("Internal error: lastAddressStack is null"),a=n.stateElement;n.stateElement.getterPaths.has(s.path)&&s.path!==t&&a.addDynamicDependency(t,s.path)}}(0,e,0,n)(t);case"$eq":return(t,e)=>{const a=n.addressStackLength>0?n.lastAddressStack:null;if(Yt(n.stateElement,t))return null!==a&&n.stateElement.getterPaths.has(a.pathInfo.path)&&P(n.stateElement,t),Object.is(s[t],e);let i;n.beginUntrack();try{i=s[t]}finally{n.endUntrack()}return null!==a&&n.stateElement.getterPaths.has(a.pathInfo.path)&&C(n.stateElement,t,e,g(n.stateElement,a),i),Object.is(i,e)};case"$eqPath":return(t,e)=>{const a=n.addressStackLength>0?n.lastAddressStack:null,i=Yt(n.stateElement,t);let o,r=i?s[t]:void 0;n.beginUntrack();try{i||(r=s[t]),o=s[e]}finally{n.endUntrack()}return null!==a&&n.stateElement.getterPaths.has(a.pathInfo.path)&&(i?P(n.stateElement,t):C(n.stateElement,t,o,g(n.stateElement,a),r)),Object.is(r,o)};case"$eqIndex":return(t,e=1)=>{const a=n.addressStackLength>0?n.lastAddressStack:null;null!==a&&null!==a.listIndex||p(`$eqIndex("${t}") needs a list row scope.`);const i=w(a.listIndex,e-1,a.pathInfo.wildcardCount);if(null===i&&p(`$eqIndex("${t}", ${e}): no list index at that level.`),Yt(n.stateElement,t))return n.stateElement.getterPaths.has(a.pathInfo.path)&&(P(n.stateElement,t),n.stateElement.addIndexDependentGetterPath?.(a.pathInfo.path)),Object.is(s[t],i.index);const o=e===a.pathInfo.wildcardCount;let r,l;n.beginUntrack();try{r=s[t],o&&(l=s[a.pathInfo.wildcardParentPaths[e-1]])}finally{n.endUntrack()}if(n.stateElement.getterPaths.has(a.pathInfo.path)){const e=o?S(l):null;null!==e?$(n.stateElement,t,a.pathInfo,e,r):v(n.stateElement,t,i,g(n.stateElement,a),r)}return Object.is(r,i.index)};case"$untrackDependency":case"$untracked":return t=>function(t,e,s,n){return t=>{n.beginUntrack();try{return t()}finally{n.endUntrack()}}}(0,0,0,n)(t);case J:return Ct(n.stateElement)}if(!e.startsWith(te)&&!e.startsWith(ee))return}const i=Jt(e),o=Pt(t,i,s,n),r=m(i.pathInfo,o);return vt(t,r,s,n)}if("symbol"==typeof e){const a=function(t){let e=se.get(t);return void 0===e&&(e=new Map,se.set(t,e)),e}(n),i=a.get(e);if(void 0!==i)return i;let o;switch(e){case D:o=(t,e=()=>{})=>function(t,e,s){void 0!==t.loopContext&&p("already in loop context"),t.setLoopContext(e);try{t.pushAddress(e);try{return s()}finally{t.popAddress()}}finally{t.clearLoopContext()}}(n,t,e);break;case z:o=e=>vt(t,e,s,n);break;case E:o=e=>Nt(t,e,s,n);break;case N:o=()=>async function(t,e,s){const n=Reflect.get(t,at);"function"==typeof n&&await n.call(s)}(t,0,s);break;case A:o=()=>function(t,e,s){const n=Reflect.get(t,it);"function"==typeof n&&n.call(s)}(t,0,s);break;case I:o=e=>function(t,e,s,n){const a=Reflect.get(t,ot);let i;if("function"==typeof a){const t=new Set,o={};for(const s of e){if(s.absolutePathInfo.stateElement!==n.stateElement)continue;const e=s.absolutePathInfo.pathInfo,a=e.path;if(-1===a.indexOf("#")&&(t.add(a),e.wildcardCount>0)){const t=k(s.listIndex,e.wildcardCount),n=o[a];void 0===n?o[a]=[t]:n.push(t)}}(t.size>0||0===e.length)&&(i=a.call(s,Array.from(t),o))}const o=n.stateElement?.addressHooks;if(o){const t=o.updated;for(let a=0;a<t.length;a++)t[a](n.stateElement,e,s)}return i}(t,e,s,n);break;case x:o=(e,n)=>function(t,e,s,n){const a=Reflect.get(t,rt);"function"==typeof a&&a.call(n,e,s)}(t,e,n,s);break;default:return Reflect.get(t,e,s)}return a.set(e,o),o}}class ae{_stateElement;_addressStack=Array(q).fill(void 0);_addressStackIndex=-1;_loopContext;_mutability;_untrackDepth=0;constructor(t,e){const s=R(t);null===s&&p("StateHandler: no state tree found on this root."),this._stateElement=s,this._mutability=e}get stateElement(){return this._stateElement}get mutability(){return this._mutability}get lastAddressStack(){let t;return this._addressStackIndex>=0&&(t=this._addressStack[this._addressStackIndex]),void 0===t&&p("Last address stack is undefined."),t}get addressStackLength(){return this._addressStackIndex+1}get loopContext(){return this._loopContext}pushAddress(t){this._addressStackIndex+1>=q&&(this._hasRepeatedAddress()&&p(`[wcs/getter-cycle] Exceeded maximum address stack depth of ${q}. Possible circular dependency between path getters: ${this._describeAddressCycle()}`),p(`[wcs/getter-depth-exceeded] Exceeded maximum address stack depth of ${q} with no address visited twice — the data is simply nested deeper than the engine evaluates in one pass. Deepest path first: ${this._describeAddressCycle()}`)),this._addressStackIndex++,this._addressStack[this._addressStackIndex]=t}_hasRepeatedAddress(){const t=new Set;for(let e=0;e<=this._addressStackIndex;e++){const s=this._addressStack[e];if(s){if(t.has(s))return!0;t.add(s)}}return!1}_tailAddressPaths(){const t=[];for(let e=this._addressStackIndex;e>=0&&t.length<8;e--){const s=this._addressStack[e];s&&t.push(s.pathInfo.path)}return t}_describeAddressCycle(){const t=this._tailAddressPaths();return`${Array.from(new Set(t)).reverse().join(" -> ")} -> ...`}popAddress(){if(this._addressStackIndex<0)return null;const t=this._addressStack[this._addressStackIndex];return void 0===t&&p(`Address stack at index ${this._addressStackIndex} is undefined.`),this._addressStack[this._addressStackIndex]=void 0,this._addressStackIndex--,t}setLoopContext(t){this._loopContext=t}clearLoopContext(){this._loopContext=void 0}get untracking(){return this._untrackDepth>0}beginUntrack(){this._untrackDepth++}endUntrack(){this._untrackDepth--}get(t,e,s){return ne(t,e,s,this)}set(t,e,s,n){return zt(this),function(t,e,s,n,a){if("string"==typeof e){const i=Jt(e),o=Pt(t,i,n,a),r=m(i.pathInfo,o);return Et(t,r,s,n,a)}return Reflect.set(t,e,s,n)}(t,e,s,n,this)}has(t,e){return Reflect.has(t,e)}deleteProperty(t,e){return zt(this),Reflect.deleteProperty(t,e)}defineProperty(t,e,s){return zt(this),Reflect.defineProperty(t,e,s)}}const ie="undefined"==typeof HTMLElement?class{}:HTMLElement;const oe=new Set(["for","if","elseif","else"]);function re(e,s,n){const a=new Map;for(const t of n){const e=st(t);if(null===e.lastWildcardPath)continue;const s=a.get(e.lastWildcardPath);void 0===s?a.set(e.lastWildcardPath,[e]):s.push(e)}const i=[],o=new Set,r=t=>{const s=g(e,t);if(o.has(s))return;o.add(s);const n=O(s);if(n instanceof Set?i.push(...n):void 0!==n&&i.push(n),null!==t.listIndex){const e=a.get(t.pathInfo.path);if(void 0!==e)for(const s of e)r(m(s,t.listIndex))}};G();try{if(e.createState("readonly",t=>{for(const n of s){const s=m(st(n),null);r(s);try{$t(e,s,e.staticDependency,e.dynamicDependency,e.listPaths,t,"new",r)}catch{}}}),0===i.length)return;const n=function(t){const e=[],s=[];for(const n of t)oe.has(n.bindingType)?e.push(n):s.push(n);return e.sort((t,e)=>0!==(t.replaceNode.compareDocumentPosition(e.replaceNode)&Node.DOCUMENT_POSITION_FOLLOWING)?-1:1),e.concat(s)}(i),a=()=>{j(n,void 0,{updatedCallback:!1})};if(t())return void a();const o=L("state",a);void 0!==o&&o.catch(T)}finally{H()}}const le=[[_t,"watch"],[yt,"scan"],[bt,"streams"],[kt,"recursion"]];class de extends ie{static hasConnectedCallbackPromise=!0;static getBindingsReady(t){return M(t)}static get observedAttributes(){return["mount"]}__state;_hasUpdatedCallback=!1;_hasErrorCallback=!1;_hydratedFromSsr=!1;_crossRowListPaths=new Set;_indexDependentGetterPaths=new Set;_initialized=!1;_initializeFailed=!1;_initializationLanded=!1;_initializePromise;_resolveInitialize=null;_connectedCallbackPromise;_resolveConnectedCallback=null;_rejectConnectedCallback=null;_loadingPromise;_resolveLoading=null;_setStatePromise=null;_resolveSetState=null;_listPaths=new Set;_listKeys=null;_recursionRegistry=null;_elementPaths=new Set;_getterPaths=new Set;_setterPaths=new Set;_loopContextStack=function(){return new Xt}();_dynamicDependency=new Map;_staticDependency=new Map;_pathSet=new Set;_stateGeneration=0;_pathRegistrations=new Map;_pendingReapplyPaths=null;_generatedPaths=new Set;_watchPaths=null;_scanPaths=null;_version=0;_rootNode=null;_boundComponent=null;_boundComponentStateProp=null;_hasMounts=!1;_hasGraftedVolumes=!1;_addressHooks=null;_bindableEventMap={};_commandTokenNames=new Set;_eventTokenNames=new Set;_treeless=!1;_connectGeneration=0;constructor(){super(),this._initializePromise=new Promise(t=>{this._resolveInitialize=t}),this._connectedCallbackPromise=new Promise((t,e)=>{this._resolveConnectedCallback=t,this._rejectConnectedCallback=e}),this._loadingPromise=new Promise(t=>{this._resolveLoading=t}),this._setStatePromise=new Promise(t=>{this._resolveSetState=t})}get _state(){return void 0===this.__state&&p(`${e.tagNames.state} _state is not initialized yet.`),this.__state}set _state(t){wt(t),function(t){for(let e=0;e<le.length;e++){const[s,n]=le[e];s in t&&!Bt(n)&&p(V(n,`"${s}"`))}}(t);const e=this.__state,s=qt();s.set("previousState",e),Ot(this,t,s);const n=function(t){const e=new Set,s=t[B];if(void 0===s)return e;Array.isArray(s)||p(`${B} must be an array of strings.`);for(const t of s)"string"==typeof t&&0!==t.length||p(`${B} entries must be non-empty strings.`),t===J&&p(`${B} entry "${t}" conflicts with the reserved namespace name "${J}".`),e.has(t)&&p(`${B} entry "${t}" is duplicated.`),e.add(t);return e}(t),a=function(t){const e=new Set,s=t[Q];if(void 0===s)return e;Array.isArray(s)||p(`${Q} must be an array of strings.`);for(const t of s)"string"==typeof t&&0!==t.length||p(`${Q} entries must be non-empty strings.`),e.has(t)&&p(`${Q} entry "${t}" is duplicated.`),e.add(t);return e}(t),i=function(t){const e=t[Y];if(void 0===e)return null;"object"==typeof e&&null!==e||p(`${Y} must be an object mapping list paths to key specs.`);const s=new Map;for(const[t,n]of Object.entries(e)){0===t.length&&p(`${Y} entry path must be a non-empty string.`);const e=t.split(Z);e.some(t=>0===t.length)&&p(`${Y} entry "${t}" must not contain empty path segments.`),e[e.length-1]===tt&&p(`${Y} entry "${t}" must be the list path itself, not the element path (drop the trailing "${Z}${tt}").`),-1!==t.indexOf(et)&&p(`[wcs/recursion-unsupported] ${Y} entry "${t}" uses "${et}", which ${Y} does not interpret — a keyed list is one concrete list path. Declare the key per depth instead (for example "nodes${Z}${tt}${Z}children").`),"function"!=typeof n?("string"!=typeof n&&p(`${Y} entry "${t}" key spec must be a field name (string) or a function.`),0===n.length&&p(`${Y} entry "${t}" key field name must be a non-empty string.`),(n.includes(Z)||n.includes(tt))&&p(`${Y} entry "${t}" key field name "${n}" must be a flat property name ("${Z}" / "${tt}" are not allowed).`),n in Object.prototype&&p(`${Y} entry "${t}" key field name "${n}" must not be a property name inherited from Object.prototype (e.g. "__proto__", "constructor").`),s.set(t,n)):s.set(t,n)}return s.size>0?s:null}(t);s.set("eventTokenNames",a),Gt(this,t,s),Mt(this,t,s),this._commandTokenNames=n,this._eventTokenNames=a,this._stateGeneration++,this.__state=t,void 0!==e&&Qt?.reset(this),this._hasUpdatedCallback=ot in t,this._hasErrorCallback=rt in t,U(this),Ut(this,t,s),function(t,e,s){const n=e[X];if(void 0!==n){"object"==typeof n&&null!==n||p(`${X} must be an object mapping event-token names to handler functions.`);for(const[e,a]of Object.entries(n))s.has(e)||p(`${X} entry "${e}" is not declared in $eventTokens.${f(e,s)}`),"function"!=typeof a&&p(`${X} entry "${e}" must be a function.`),_(t,e).subscribe(a)}}(this,t,this._eventTokenNames),this._listPaths.clear(),this._elementPaths.clear(),this._getterPaths.clear(),this._setterPaths.clear(),this._pathSet.clear();const o=function(t){const e=new Set,s=new Set,n=jt(t);for(const[t,a]of Object.entries(n))"function"==typeof a.get&&e.add(t),"function"==typeof a.set&&s.add(t);return{getterPaths:e,setterPaths:s}}(t);for(const t of o.getterPaths)this._getterPaths.add(t);for(const t of o.setterPaths)this._setterPaths.add(t);Ft(this,t,s),this._listKeys=i,this._rebuildPathInfo(),Wt(this,t,s),Kt(this,null),this._resolveLoading?.()}attributeChangedCallback(t,s,n){this._initialized&&s!==n&&console.warn(`[@wcstack/state] Changing the "mount" attribute after initialization is not supported and is ignored (was ${null===s?"absent":`"${s}"`}, now ${null===n?"absent":`"${n}"`}). Remove this <${e.tagNames.state}> element and create a new one with the desired mount path instead.`)}_loadFromSsrElement(){return this.hasAttribute("enable-ssr")?F('the "enable-ssr" attribute').loadState(this):null}async _loadStateFromSource(){if(this.hasAttribute("state")){return function(t){const e=document.getElementById(t);return e&&"application/json"===e.type?JSON.parse(e.textContent||"{}"):(console.warn(`[@wcstack/state] state="${t}": no <script type="application/json" id="${t}"> in the document (3.x does not look inside shadow roots), so the state starts empty.`),{})}(this.getAttribute("state"))}if(!this.hasAttribute("src")){if(this.hasAttribute("json")){const t=this.getAttribute("json");return JSON.parse(t)}{const t=this.querySelector('script[type="module"]');if(t)return await a(t,e.tagNames.state);{const t=setTimeout(()=>{console.warn(`[@wcstack/state] Warning: No state source found for <${e.tagNames.state}> element.`)},pt),s=await this._setStatePromise;return clearTimeout(t),s}}}{const t=this.getAttribute("src");if(t&&t.endsWith(".json"))return await async function(t){let e;try{const s=await fetch(t);if(s.ok)return await s.json();e=`HTTP ${s.status} ${s.statusText}`}catch(t){e=t}return console.error(`[@wcstack/state] Failed to load JSON file "${t}", so the state starts empty (4.0 rejects instead):`,e),{}}(t);if(t&&t.endsWith(".js"))return await n(t);p(`Unsupported src file type: ${t}`)}}async _initialize(){const e=t()?null:this._loadFromSsrElement();if(null!==e&&(this._hydratedFromSsr=!0),this._state=await this._loadStateFromSource(),null!==e&&this.__state)for(const[t,s]of Object.entries(e)){if(t in this.__state){const e=Object.getOwnPropertyDescriptor(this.__state,t);if(e&&(e.get||e.set))continue;if("function"==typeof this.__state[t])continue}this.__state[t]=s}return await this._loadingPromise,null!==this._rootNode&&(W(this._rootNode,this),!0)}_failInitialization(t){this._initializationLanded=!0,this._resolveInitialize?.(),this._resolveLoading?.(),this._resolveConnectedCallback?.(),p(t)}_failInitializeLoudly(t,s=!0){if(this._initializationLanded)throw t;this._initializeFailed=!0;const n=["state","src"].find(t=>this.hasAttribute(t));throw console.error(`[@wcstack/state] <${e.tagNames.state}${n?` ${n}="${this.getAttribute(n)}"`:""}> failed to initialize.`,t),this._resolveInitialize?.(),this._resolveLoading?.(),this._connectedCallbackPromise.catch(()=>{}),this._rejectConnectedCallback?.(t),s&&null!==this._rootNode&&null===R(this._rootNode)&&(K(this._rootNode,t),i(this,this._rootNode,t)),t}async _callStateConnectedCallback(){await this.createStateAsync("writable",async t=>{at in t&&await t[N]()})}_callStateDisconnectedCallback(){this.createState("writable",t=>{it in t&&t[A]()})}async connectedCallback(){this._rootNode=this.getRootNode();const n=++this._connectGeneration;if(this._initializationLanded=!1,this._initialized){if(d(this))return void this._resolveConnectedCallback?.();this._treeless||R(this._rootNode)===this||W(this._rootNode,this)}else{this.hasAttribute("name")&&this._failInitialization(this.hasAttribute("mount")?'"mount" replaces "name" — a volume has no name of its own. Remove the name attribute.':`The "name" attribute was removed in v2 — there is a single state tree per root. Mount this state onto the tree instead: <wcs-state mount="${this.getAttribute("name")}" ...> and read it as "${this.getAttribute("name")}.<path>".`);const t=o(this);if(null!==t)return void await t;if(this.hasAttribute("mount"))try{r("scopes",'the "mount" attribute')}catch(t){this._failInitializeLoudly(t,!1)}const s=this.parentNode;if(s instanceof ShadowRoot&&s.host.hasAttribute(ft))try{r("dcc",`a <${e.tagNames.state}> inside a [${ft}] host`)}catch(t){this._failInitializeLoudly(t)}let n=!1;try{const t=l(this);null===t&&this.hasAttribute("bind-component")&&r("scopes",'the "bind-component" attribute'),n=await(t??!1)}catch(t){this._failInitializeLoudly(t)}if(n)return;let a=!1;try{a=await this._initialize()}catch(t){this._failInitializeLoudly(t)}if(!a)return;this._initialized=!0,this._resolveInitialize?.()}if(null!==this._pendingReapplyPaths){const t=this._pendingReapplyPaths;this._pendingReapplyPaths=null,this._reapplyBindings(t)}if(this.hasAttribute("enable-ssr")&&!t()||n!==this._connectGeneration||await this._callStateConnectedCallback(),t()&&this.hasAttribute("enable-ssr")&&!s())try{await F('the "enable-ssr" attribute').emitSnapshot(this)}catch(t){throw this._rejectConnectedCallback?.(t),t}Kt(this,n),this._resolveConnectedCallback?.()}disconnectedCallback(){if(!c(this)&&null!==this._rootNode){if(!this._initialized)return this._initializeFailed&&h(this,this._rootNode),void(this._rootNode=null);try{this._callStateDisconnectedCallback()}finally{W(this.rootNode,null),Dt(this),Vt(this),this._rootNode=null}}}get initialized(){return this._initialized}get connectedRootNode(){return this._rootNode}clearConnectedRootNode(){this._rootNode=null}markInitialized(){this._initialized=!0}settleInitialization(){this._resolveInitialize?.(),this._resolveLoading?.(),this._resolveConnectedCallback?.()}loadStateFromSource(){return this._loadStateFromSource().then(t=>(wt(t),t))}markTreeless(){this._treeless=!0}failInitializeLoudly(t){return this._failInitializeLoudly(t)}get connectGeneration(){return this._connectGeneration}setWatchPaths(t){this._watchPaths=t}setScanPaths(t){this._scanPaths=t}landInitialization(){this._initializationLanded=!0,this._resolveInitialize?.(),this._resolveLoading?.(),this._resolveConnectedCallback?.()}setRecursionRegistry(t){this._recursionRegistry=t}addGeneratedPath(t){this._generatedPaths.add(t)}setBoundComponent(t,e){this._boundComponent=t,this._boundComponentStateProp=e}get initializePromise(){return this._initializePromise}get connectedCallbackPromise(){return this._connectedCallbackPromise}get listPaths(){return this._listPaths}get listKeys(){return this._listKeys}get hasRecursion(){return null!==this._recursionRegistry}get recursionRegistry(){return this._recursionRegistry}get watchPaths(){return this._watchPaths}get scanPaths(){return this._scanPaths}get elementPaths(){return this._elementPaths}addVolumeWatchPaths(t){if(0===t.size)return;const e=new Set(this._watchPaths??[]);for(const s of t)e.add(s);this._watchPaths=e,this.attachAddressHooks("watch",_t)}mergeVolumeListKeys(t){if(0===t.size)return;const e=new Map(this._listKeys??[]);for(const[s,n]of t)e.has(s)&&p(`$listKeys entry "${s}" is declared by both the root and a volume (or two volumes). Keep exactly one.`),e.set(s,n);this._listKeys=e}enableUpdatedCallback(){this._hasUpdatedCallback=!0}get hydratedFromSsr(){return this._hydratedFromSsr}addListPath(t){this._listPaths.add(t)}findStateDescriptor(t){return mt(this._state,t)}defineTreeAccessor(t,e){Object.defineProperty(this._state,t,e),"function"==typeof e.get&&this._getterPaths.add(t),"function"==typeof e.set&&this._setterPaths.add(t),this.setPathInfo(t,"prop","internal")}get getterPaths(){return this._getterPaths}get setterPaths(){return this._setterPaths}get loopContextStack(){return this._loopContextStack}get dynamicDependency(){return this._dynamicDependency}get staticDependency(){return this._staticDependency}get version(){return this._version}get stateGeneration(){return this._stateGeneration}get rootNode(){return null===this._rootNode&&p("State rootNode is not available."),this._rootNode}get boundComponentStateProp(){return this._boundComponentStateProp}get hasMounts(){return this._hasMounts}markHasMounts(){this._hasMounts=!0,this._attachScopeHooks("bind-component")}get hasGraftedVolumes(){return this._hasGraftedVolumes}get addressHooks(){return this._addressHooks}attachAddressHooks(t,e){const s=Lt(t,e);null===this._addressHooks&&(this._addressHooks=Tt()),Ht(this._addressHooks,s)}markHasGraftedVolumes(){this._hasGraftedVolumes=!0,this._attachScopeHooks("mount")}markHasVolume(){this._attachScopeHooks("mount")}_attachScopeHooks(t){this.attachAddressHooks("scopes",t)}get bindableEventMap(){return this._bindableEventMap}get commandTokenNames(){return this._commandTokenNames}get eventTokenNames(){return this._eventTokenNames}setBindableEventMap(t){this._bindableEventMap=t,this.attachAddressHooks("dcc",gt)}_addDependency(t,e,s){const n=t.get(e);return void 0===n?(t.set(e,[s]),!0):!n.includes(s)&&(n.push(s),!0)}addDynamicDependency(t,e){if(!this._addDependency(this._dynamicDependency,t,e))return!1;const s=st(t);for(let t=s.parentPathInfo;null!==t&&t.wildcardCount>0&&t.wildcardCount===s.wildcardCount;t=t.parentPathInfo)this._addDependency(this._dynamicDependency,t.path,e);return!0}addStaticDependency(t,e){return this._addDependency(this._staticDependency,t,e)}setPathInfo(t,e,s="binding"){if("internal"!==s){const n=this._pathRegistrations.get(t);void 0===n?this._pathRegistrations.set(t,{bindingType:e,bound:"binding"===s}):"for"!==n.bindingType&&this._pathRegistrations.set(t,{bindingType:e,bound:n.bound||"binding"===s})}if("for"===e&&(this._listPaths.add(t),this._elementPaths.add(t+"."+tt)),!this._pathSet.has(t)){const e=st(t);this._pathSet.add(t);const n=function(t,e){const s=Jt(e);return"all"===s.wildcardType&&1===s.wildcardIndexes.length&&isNaN(+s.segments[0])&&!e.includes("#")&&Object.isExtensible(t)&&!(e in t)}(this.__state,t);if(Qt?.check(this,this.__state,t,s,n),n&&function(t,e){const{segments:s,cumulativePaths:n}=st(e),a=s.length-1,i=(t,i,o)=>{let r,l=!1;for(let d=0;d<=a;d++){const c=s[d];if(l||=!(isNaN(+c)||Array.isArray(r)&&+c in r),i&&d===a)return l?r[c]=o:t[e]=o;r=l?r?.[c]:t[n[d]]}return r},o=function(){return i(this)};nt.set(o,Jt(e).pathInfo.path),t.defineTreeAccessor(e,{get:o,set(t){i(this,!0,t)},configurable:!0})}(this,t),null!==e.parentPath){let t=e;for(;null!==t.parentPath&&this.addStaticDependency(t.parentPath,t.path);)t=st(t.parentPath)}}}_rebuildPathInfo(){for(const[t,e]of Array.from(this._pathRegistrations))e.bound&&!this._generatedPaths.has(t)&&this.setPathInfo(t,e.bindingType)}_createState(t,e,s){try{const n=function(t,e,s){const n=new ae(t,s);return new Proxy(e,n)}(t,this._state,e);return s(n)}finally{}}async createStateAsync(t,e){return await this._createState(this.rootNode,t,e)}createState(t,e){this._createState(this.rootNode,t,e)}nextVersion(){return this._version++,this._version}get hasUpdatedCallback(){return this._hasUpdatedCallback}get hasErrorCallback(){return this._hasErrorCallback}get crossRowListPaths(){return this._crossRowListPaths}addCrossRowListPath(t){this._crossRowListPaths.add(t)}get indexDependentGetterPaths(){return this._indexDependentGetterPaths}addIndexDependentGetterPath(t){this._indexDependentGetterPaths.add(t)}setInitialState(t){if(!this._initialized)return this._initializeFailed&&p(`<${e.tagNames.state}> failed to initialize (the diagnostic was reported when it connected), so its state cannot be replaced. Remove this element and create a new one with the corrected state.`),void this._resolveSetState?.(t);u(this),(this._hasGraftedVolumes||this._hasMounts)&&p("Cannot replace the whole state of a tree that has grafted volumes or mounted components: re-setting would silently drop grafted data, tree accessors and mount ledgers (D22). Write the changed paths instead.");const s=this.__state;this._state=t;const n=function(t){const e=new Set;for(const s of t)if(void 0!==s)for(const[t,n]of Object.entries(jt(s)))t.startsWith("$")||t.includes(tt)||"function"==typeof n.value||e.add(t);return e}([s,t]);null!==this._rootNode?this._reapplyBindings(n):this._pendingReapplyPaths=new Set([...this._pendingReapplyPaths??[],...n])}_reapplyBindings(t){re(this,t,this._pathRegistrations.keys())}}const ce=[],he=[];function ue(){const t=[];let e=0;for(let s=0;s<he.length;s++){const n=he[s].deref();void 0!==n&&(t.push(n),he[e++]=he[s])}return he.length=e,t}function pe(t){if(!ce.includes(t)){ce.push(t);for(const e of ue())t(e)}}function fe(t=customElements){ue().includes(t)||he.push(new WeakRef(t));for(let e=0;e<ce.length;e++)ce[e](t);t.get(e.tagNames.state)||t.define(e.tagNames.state,de)}export{ie as H,pe as a,fe as r};
2
2
  //# sourceMappingURL=registerComponents.js.map