@wcstack/websocket 4.6.2 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -178,6 +178,10 @@ npm install @wcstack/websocket
178
178
  - 最大 `max-reconnects` 回リトライ(デフォルト: Infinity)
179
179
  - 再接続成功時にリトライカウントをリセット
180
180
 
181
+ **閉じられずに死んだ接続** — ノートパソコンのスリープ、接続を落とした NAT や proxy — にブラウザは気づきません: ソケットは `OPEN` のまま、`connected` は `true` のままで、何も届きません(`auto-reconnect` はクローズにしか反応しない)。4.8 から、`stale-after="45000"` は、その時間(ms)メッセージが 1 つも届かない開いた接続を失われたとみなし、異常なクローズと同じに扱います: ソケットを手放し、`connected` が `false` になり、`error` が理由を言い(`errorInfo.recoverable` は `true`)、`auto-reconnect` がつなぎ直します。サーバーはそれより短い間隔でメッセージを送る必要があります — WebSocket の ping フレームはページに見えないので、アプリケーションの層の ping を送ってください。何時間も開いたままのページがほかに通るもの: [開いたままのページ](../../docs/long-lived-pages.ja.md)。
182
+
183
+ **back/forward cache。** 開いた WebSocket は、ページをブラウザの back/forward cache から外します(Chromium: 復元しない、理由 `websocket`)。4.8 から、`<wcs-ws>` はページが cache に入りうるとき(`persisted` の `pagehide`)接続を閉じて `connected: false` をその場で知らせ、cache から戻ったとき(`persisted` の `pageshow`)、接続していたならつなぎ直します — ページは読み直されずに復元されます。その間に届いたものは再送されません: `connected` で、自分の位置から取り直してください。
184
+
181
185
  ## ステートサーフェス vs コマンドサーフェス
182
186
 
183
187
  `<wcs-ws>` は 2 種類のプロパティを公開します。
@@ -203,10 +207,10 @@ HTML、JS、または `@wcstack/state` バインディングから接続とメ
203
207
  |------------|------|------|
204
208
  | `url` | `string` | WebSocket エンドポイント URL |
205
209
  | `trigger` | `boolean` | 単方向の接続トリガー |
206
- | `send` | `any` | 値を設定するとデータを送信(オブジェクトは自動文字列化)。ソケットが開く前は拒まれる: `error`(`invalid-state`)に流れ、メッセージは失われ、要素が `[wcs/command-not-ready]` で警告する(1 要素につき 1 回) |
210
+ | `send` | `any` | 値を設定するとデータを送信(オブジェクトは自動文字列化)。ソケットが開く前は拒まれる: `error`(`invalid-state`)に流れ、メッセージは失われ、要素が `[wcs/command-not-ready]` で警告する(ソケットがまた開くまで 1 回 — 4.8 から。それまでは 1 要素につき 1 回) |
207
211
  | `manual` | `boolean` | DOM 接続時の自動接続を無効化 |
208
212
 
209
- **`null` と `undefined`。** 属性に対応する入力(`url`・`protocols`・`autoReconnect`・`reconnectInterval`・`maxReconnects`・`binaryType`・`manual` — [要素一覧](#要素一覧)参照)は、`null` を「クリア」として扱います。属性を外し、入力は既定値に戻ります。`undefined` は「値が無い」で、属性を最初の書き込みの前の状態 — マークアップに書かれた値、無ければ属性なし — に戻します。どちらも文字列 `"null"` / `"undefined"` として書くことはありません(`@wcstack/state` は `undefined` を書きませんが、React 19 は値のあった prop を外したときに書き、直接の代入でも届きます)。こうして戻った `url` はほかの `url` 変更と同じく接続し直し、クリアした `url` では接続しません。`trigger` と `send` はどちらも無視します。
213
+ **`null` と `undefined`。** 属性に対応する入力(`url`・`protocols`・`autoReconnect`・`reconnectInterval`・`maxReconnects`・`binaryType`・`staleAfter`・`manual` — [要素一覧](#要素一覧)参照)は、`null` を「クリア」として扱います。属性を外し、入力は既定値に戻ります。`undefined` は「値が無い」で、属性を最初の書き込みの前の状態 — マークアップに書かれた値、無ければ属性なし — に戻します。どちらも文字列 `"null"` / `"undefined"` として書くことはありません(`@wcstack/state` は `undefined` を書きませんが、React 19 は値のあった prop を外したときに書き、直接の代入でも届きます)。こうして戻った `url` はほかの `url` 変更と同じく接続し直し、クリアした `url` では接続しません。`trigger` と `send` はどちらも無視します。
210
214
 
211
215
  ## `:state()` による CSS スタイリング
212
216
 
@@ -385,6 +389,7 @@ wcstack アプリケーションでは、**`trigger` によるステート駆動
385
389
  | `reconnect-interval` | `number` | `3000` | 再接続間隔(ミリ秒) |
386
390
  | `max-reconnects` | `number` | `Infinity` | 最大再接続回数 |
387
391
  | `binary-type` | `"blob" \| "arraybuffer"` | `blob` | 受信バイナリフレームを `message` でどう表現するか。`arraybuffer` 以外の値は `blob` に正規化される |
392
+ | `stale-after` | `number` | `0` | この時間(ms)メッセージが届かない開いた接続を失われたとみなす(`0`: しない)。接続するときに読む。4.8 から |
388
393
 
389
394
  | プロパティ | 型 | 説明 |
390
395
  |------------|------|------|
@@ -395,6 +400,7 @@ wcstack アプリケーションでは、**`trigger` によるステート駆動
395
400
  | `errorInfo` | `WcsIoErrorInfo \| null` | 失敗タクソノミ(`code` / `phase` / `recoverable`)。`error` から導出される |
396
401
  | `readyState` | `number` | WebSocket readyState 定数 |
397
402
  | `binaryType` | `"blob" \| "arraybuffer"` | バイナリフレーム表現(`binary-type` 属性を背後に持つ。既定 `blob`) |
403
+ | `staleAfter` | `number` | 何も届かない時間(ms)がこれを超えた開いた接続を失われたとみなす(`stale-after` 属性を背後に持つ。`0`: しない)。4.8 から |
398
404
  | `trigger` | `boolean` | `true` を設定すると接続を開始 |
399
405
  | `send` | `any` | 値を設定するとデータを送信 |
400
406
 
@@ -674,6 +680,7 @@ bootstrapWebSocket({
674
680
 
675
681
  ## 設計メモ
676
682
 
683
+ - **4.8 から、接続時の判断はマイクロタスクを 1 つ待つ。** 接続するか、どの `url` へかは、`connectedCallback`(と `url` の変化)の 1 マイクロタスク後に、そのときの入力で決める([タイミング契約](../../docs/timing-and-firing-contract.ja.md) §23)。`@wcstack/router` はパラメータだけの遷移でルートの要素を入れ直し、`@wcstack/state` が次のルートの入力を書くのはその後 — その場で接続すると、前のルートのソケットを開いてから閉じていた。`connect()` / `trigger` はその場で接続し、同じタスクの `close()` は待っている接続を取り消す。
677
684
  - `message`、`connected`、`loading`、`error`、`readyState` は **出力ステート**
678
685
  - `url`、`trigger`、`send` は **入力 / コマンドサーフェス**
679
686
  - `trigger` は意図的に単方向: `true` を書き込むと接続、リセットで完了を通知
package/README.md CHANGED
@@ -178,6 +178,10 @@ When the connection drops unexpectedly (close code other than 1000), `<wcs-ws>`
178
178
  - retries up to `max-reconnects` times (default: Infinity)
179
179
  - resets the retry count on successful reconnection
180
180
 
181
+ **A connection that died without being closed** — a laptop's sleep, a NAT or a proxy that dropped it — is not noticed by the browser: the socket stays `OPEN`, `connected` stays `true`, and nothing arrives (`auto-reconnect` acts only on a close). Since 4.8, `stale-after="45000"` treats an open connection that received no message for that many milliseconds as lost, as if it had closed abnormally: the socket is let go, `connected` goes `false`, `error` says why (`errorInfo.recoverable` is `true`), and `auto-reconnect` reconnects. The server must send a message more often than that — a WebSocket ping frame is not seen by the page, so send an application-level ping. What else a page left open for hours goes through: [Pages that stay open](../../docs/long-lived-pages.md).
182
+
183
+ **The back/forward cache.** An open WebSocket keeps the page out of the browser's back/forward cache (Chromium: not restored, reason `websocket`). Since 4.8, `<wcs-ws>` closes its connection when the page may enter the cache (`pagehide` with `persisted`), publishing `connected: false` at once, and reconnects when the page comes back from it (`pageshow` with `persisted`) if it was connected — so the page is restored instead of reloaded. What arrived meanwhile is not replayed: resync from your own position on `connected`.
184
+
181
185
  ## State Surface vs Command Surface
182
186
 
183
187
  `<wcs-ws>` exposes two different kinds of properties.
@@ -203,10 +207,10 @@ These properties control connection and messaging from HTML, JS, or `@wcstack/st
203
207
  |----------|------|-------------|
204
208
  | `url` | `string` | WebSocket endpoint URL |
205
209
  | `trigger` | `boolean` | One-way connection trigger |
206
- | `send` | `any` | Set to transmit data (auto-stringifies objects). Before the socket is open it is refused: it goes to `error` (`invalid-state`), the message is lost, and the element warns `[wcs/command-not-ready]` (once per element) |
210
+ | `send` | `any` | Set to transmit data (auto-stringifies objects). Before the socket is open it is refused: it goes to `error` (`invalid-state`), the message is lost, and the element warns `[wcs/command-not-ready]` (once until the socket opens again — since 4.8; before, once per element) |
207
211
  | `manual` | `boolean` | Disables auto-connect on DOM attach |
208
212
 
209
- **`null` and `undefined`.** The inputs backed by an attribute (`url`, `protocols`, `autoReconnect`, `reconnectInterval`, `maxReconnects`, `binaryType`, `manual` — see [Elements](#elements)) take `null` as "clear": the attribute is removed and the input falls back to its default. `undefined` means "no value supplied": the attribute goes back to what it was before the first write — the value written in the markup, or none. Neither is ever written as the string `"null"` / `"undefined"`. (`@wcstack/state` never writes `undefined`; React 19 does when a prop that had a value is removed, and so can a direct assignment.) A `url` restored this way reconnects like any other `url` change; a cleared `url` does not connect. `trigger` and `send` ignore both.
213
+ **`null` and `undefined`.** The inputs backed by an attribute (`url`, `protocols`, `autoReconnect`, `reconnectInterval`, `maxReconnects`, `binaryType`, `staleAfter`, `manual` — see [Elements](#elements)) take `null` as "clear": the attribute is removed and the input falls back to its default. `undefined` means "no value supplied": the attribute goes back to what it was before the first write — the value written in the markup, or none. Neither is ever written as the string `"null"` / `"undefined"`. (`@wcstack/state` never writes `undefined`; React 19 does when a prop that had a value is removed, and so can a direct assignment.) A `url` restored this way reconnects like any other `url` change; a cleared `url` does not connect. `trigger` and `send` ignore both.
210
214
 
211
215
  ## CSS styling with `:state()`
212
216
 
@@ -388,6 +392,7 @@ In wcstack applications, **state-driven triggering via `trigger`** is usually th
388
392
  | `reconnect-interval` | `number` | `3000` | Reconnection delay in ms |
389
393
  | `max-reconnects` | `number` | `Infinity` | Maximum reconnection attempts |
390
394
  | `binary-type` | `"blob" \| "arraybuffer"` | `blob` | How incoming binary frames are surfaced on `message`. Any value other than `arraybuffer` normalizes to `blob` |
395
+ | `stale-after` | `number` | `0` | Treat an open connection that received no message for this many milliseconds as lost (`0`: never). Read when connecting. Since 4.8 |
391
396
 
392
397
  | Property | Type | Description |
393
398
  |----------|------|-------------|
@@ -398,6 +403,7 @@ In wcstack applications, **state-driven triggering via `trigger`** is usually th
398
403
  | `errorInfo` | `WcsIoErrorInfo \| null` | Failure taxonomy (`code` / `phase` / `recoverable`), derived from `error` |
399
404
  | `readyState` | `number` | WebSocket readyState constant |
400
405
  | `binaryType` | `"blob" \| "arraybuffer"` | Binary frame representation (backs the `binary-type` attribute; default `blob`) |
406
+ | `staleAfter` | `number` | Milliseconds without a message after which an open connection is treated as lost (backs the `stale-after` attribute; `0`: never). Since 4.8 |
401
407
  | `trigger` | `boolean` | Set to `true` to open connection |
402
408
  | `send` | `any` | Set to transmit data |
403
409
 
@@ -677,6 +683,7 @@ bootstrapWebSocket({
677
683
 
678
684
  ## Design Notes
679
685
 
686
+ - **Since 4.8, the connect-time decision waits one microtask.** Whether to connect, and to which `url`, is decided one microtask after `connectedCallback` (and after a `url` change), with the inputs as they are then ([timing contract](../../docs/timing-and-firing-contract.md) §23). `@wcstack/router` puts a route's elements back on a parameter-only navigation before `@wcstack/state` writes the next route's inputs: connecting at once opened the previous route's socket and closed it again. `connect()` / `trigger` connect at once; `close()` in the same task cancels the pending connect.
680
687
  - `message`, `connected`, `loading`, `error`, and `readyState` are **output state**
681
688
  - `url`, `trigger`, and `send` are **input / command surface**
682
689
  - `trigger` is intentionally one-way: writing `true` connects, reset emits completion
package/dist/auto.min.js CHANGED
@@ -1,2 +1,2 @@
1
- const e={triggerAttribute:"data-wstarget",tagNames:{ws:"wcs-ws"}},t="invalid-argument",n="invalid-state",s="connection-error";class r extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"message",event:"wcs-ws:message",semantics:"event"},{name:"connected",event:"wcs-ws:connected-changed",semantics:"state"},{name:"loading",event:"wcs-ws:loading-changed",semantics:"state"},{name:"error",event:"wcs-ws:error",semantics:"state"},{name:"errorInfo",event:"wcs-ws:error-info-changed",semantics:"state"},{name:"readyState",event:"wcs-ws:readystate-changed",semantics:"state"}],commands:[{name:"connect"},{name:"send"},{name:"close"}]};_target;_ws=null;_message=null;_connected=!1;_loading=!1;_error=null;_errorInfo=null;_readyState=3;_autoReconnect=!1;_reconnectInterval=3e3;_maxReconnects=1/0;_reconnectCount=0;_reconnectTimer=null;_url="";_protocols=void 0;_binaryType="blob";_intentionalClose=!1;_gen=0;_socketGen=0;_ready=Promise.resolve();_toldNotReady=!1;constructor(e){super(),this._target=e??this}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.close(),this._setConnected(!1),this._setLoading(!1),this._setReadyState(3)}get message(){return this._message}get connected(){return this._connected}get loading(){return this._loading}get error(){return this._error}get errorInfo(){return this._errorInfo}get readyState(){return this._readyState}_setMessage(e){this._message=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:message",{detail:e,bubbles:!0}))}_setConnected(e){this._connected=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:connected-changed",{detail:e,bubbles:!0}))}_setLoading(e){this._loading=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:loading-changed",{detail:e,bubbles:!0}))}_setError(e,r){this._error!==e&&(this._error=e,this._commitErrorInfo(null===e?null:function(e,r){const o=e.message,i="string"==typeof o?o:"WebSocket connection error";return r===t?{code:t,phase:"start",recoverable:!1,message:i}:r===n?{code:n,phase:"execute",recoverable:!1,message:i}:{code:s,phase:"execute",recoverable:!0,message:i}}(e,r)),this._target.dispatchEvent(new CustomEvent("wcs-ws:error",{detail:e,bubbles:!0})))}_commitErrorInfo(e){this._errorInfo=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:error-info-changed",{detail:e,bubbles:!0}))}_setReadyState(e){this._readyState=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:readystate-changed",{detail:e,bubbles:!0}))}connect(e,n={}){e?(this._gen++,this._intentionalClose=!0,this._closeInternal(),this._url=e,this._protocols=n.protocols,this._autoReconnect=n.autoReconnect??!1,this._reconnectInterval=n.reconnectInterval??3e3,this._maxReconnects=n.maxReconnects??1/0,this._binaryType=n.binaryType??"blob",this._reconnectCount=0,this._intentionalClose=!1,this._doConnect()):this._setError({message:"url is required."},t)}send(e){if(!this._ws||1!==this._ws.readyState)return this._setError({message:"WebSocket is not connected."},n),void this._warnNotReady();this._ws.send(e)}_warnNotReady(){this._toldNotReady||(this._toldNotReady=!0,console.warn("[@wcstack/websocket] [wcs/command-not-ready] send() was refused: the WebSocket is not connected, so the message is lost. It goes to `error` too. Send once `connected` is true. (Said once per element.)",this._target))}close(e,t){this._intentionalClose=!0,this._clearReconnectTimer(),this._ws&&this._ws.close(e,t)}_doConnect(){this._setLoading(!0),this._setError(null),this._socketGen=this._gen;try{this._ws=this._protocols?new WebSocket(this._url,this._protocols):new WebSocket(this._url)}catch(e){return this._setLoading(!1),void this._setError(e,s)}this._ws.binaryType=this._binaryType,this._setReadyState(0),this._ws.addEventListener("open",this._onOpen),this._ws.addEventListener("message",this._onMessage),this._ws.addEventListener("error",this._onError),this._ws.addEventListener("close",this._onClose)}_onOpen=()=>{this._socketGen===this._gen&&(this._reconnectCount=0,this._setLoading(!1),this._setConnected(!0),this._setReadyState(1))};_onMessage=e=>{if(this._socketGen!==this._gen)return;let t=e.data;if("string"==typeof t)try{t=JSON.parse(t)}catch{}this._setMessage(t)};_onError=e=>{this._socketGen===this._gen&&this._setError(e,s)};_onClose=e=>{this._removeListeners(),this._ws=null,this._socketGen===this._gen&&(this._setConnected(!1),this._setLoading(!1),this._setReadyState(3),!this._intentionalClose&&this._autoReconnect&&1e3!==e.code&&this._reconnectCount<this._maxReconnects&&this._scheduleReconnect())};_scheduleReconnect(){const e=this._gen;this._clearReconnectTimer(),this._reconnectTimer=setTimeout(()=>{this._reconnectTimer=null,e===this._gen&&(this._reconnectCount++,this._doConnect())},this._reconnectInterval)}_clearReconnectTimer(){null!==this._reconnectTimer&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null)}_removeListeners(){this._ws&&(this._ws.removeEventListener("open",this._onOpen),this._ws.removeEventListener("message",this._onMessage),this._ws.removeEventListener("error",this._onError),this._ws.removeEventListener("close",this._onClose))}_closeInternal(){this._clearReconnectTimer(),this._ws&&(this._removeListeners(),1!==this._ws.readyState&&0!==this._ws.readyState||this._ws.close(),this._ws=null),this._connected&&this._setConnected(!1),3!==this._readyState&&this._setReadyState(3)}}let o=!1;function i(t){const n=t.target;if(!(n instanceof Element))return;const s=n.closest(`[${e.triggerAttribute}]`);if(!s)return;const r=s.getAttribute(e.triggerAttribute);if(!r)return;const o=customElements.get(e.tagNames.ws),i=document.getElementById(r);o&&i instanceof o&&(t.preventDefault(),i.connect())}function c(e,t){let n=Object.getPrototypeOf(e);for(;null!==n;){const e=Object.getOwnPropertyDescriptor(n,t);if(void 0!==e)return"function"==typeof e.get||"function"==typeof e.set;n=Object.getPrototypeOf(n)}return!1}const a=new WeakSet;function h(e,t,n){if(a.has(e))return;a.add(e);const s=e.localName??"element";console.warn(`[wcs/input-as-attribute] <${s}> has the attribute ${t}="${n}": an object was written as an attribute, so the element did not receive it. A framework does that when the property is set before the element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, or assign the property through a ref (Vue: .prop). (Said once per element.)`,e)}const l=new WeakMap;function d(e,t){let n=l.get(e);return void 0===n&&(n=new Map,l.set(e,n)),n.has(t)||n.set(t,e.getAttribute(t)),n.get(t)}function u(e,t,n){null===n?e.removeAttribute(t):e.setAttribute(t,n)}function _(e,t,n){const s=d(e,t);u(e,t,void 0===n?s:null===n?null:String(n))}function g(e,t,n){const s=d(e,t);u(e,t,void 0===n?s:n?"":null)}class m extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...r.wcBindable,properties:[...r.wcBindable.properties,{name:"trigger",event:"wcs-ws:trigger-changed",semantics:"state"},{name:"send",event:"wcs-ws:send-changed",semantics:"state"}],inputs:[{name:"url",attribute:"url"},{name:"protocols",attribute:"protocols"},{name:"autoReconnect",attribute:"auto-reconnect"},{name:"reconnectInterval",attribute:"reconnect-interval"},{name:"maxReconnects",attribute:"max-reconnects"},{name:"binaryType",attribute:"binary-type"},{name:"manual",attribute:"manual"},{name:"trigger"},{name:"send"}],commands:[{name:"connect"},{name:"sendMessage"},{name:"close"}]};static get observedAttributes(){return["url"]}_core;_trigger=!1;_connectedCallbackPromise=Promise.resolve();_internals=null;_attached=!1;constructor(){super(),this._core=new r(this),this._internals=this._initInternals(),this._wireStates({"wcs-ws:connected-changed":e=>({connected:!0===e}),"wcs-ws:loading-changed":e=>({loading:!0===e}),"wcs-ws:error":e=>({error:null!=e})})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const e=this.attachInternals();return e.states.add("wcs-probe"),e.states.delete("wcs-probe"),e}catch{return null}}_wireStates(e){if(null===this._internals)return;const t=this._internals.states;for(const[n,s]of Object.entries(e))this.addEventListener(n,e=>{const n=this.hasAttribute("debug-states");for(const[r,o]of Object.entries(s(e.detail))){try{o?t.add(r):t.delete(r)}catch{}n&&this.toggleAttribute(`data-wcs-state-${r}`,o)}})}get url(){return this.getAttribute("url")||""}set url(e){_(this,"url",e)}get protocols(){return this.getAttribute("protocols")||""}set protocols(e){_(this,"protocols",e)}get autoReconnect(){return this.hasAttribute("auto-reconnect")}set autoReconnect(e){g(this,"auto-reconnect",e)}get reconnectInterval(){const e=this.getAttribute("reconnect-interval"),t=e?parseInt(e,10):3e3;return Number.isNaN(t)?3e3:t}set reconnectInterval(e){_(this,"reconnect-interval",e)}get maxReconnects(){const e=this.getAttribute("max-reconnects"),t=e?parseInt(e,10):1/0;return Number.isNaN(t)?1/0:t}set maxReconnects(e){_(this,"max-reconnects",e)}get binaryType(){return"arraybuffer"===this.getAttribute("binary-type")?"arraybuffer":"blob"}set binaryType(e){_(this,"binary-type",e)}get manual(){return this.hasAttribute("manual")}set manual(e){g(this,"manual",e)}get message(){return this._core.message}get connected(){return this._core.connected}get loading(){return this._core.loading}get error(){return this._core.error}get errorInfo(){return this._core.errorInfo}get readyState(){return this._core.readyState}get trigger(){return this._trigger}set trigger(e){!!e&&(this._trigger=!0,this.connect(),this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-ws:trigger-changed",{detail:!1,bubbles:!0})))}get send(){return null}set send(e){if(null==e)return;const t="string"==typeof e?e:JSON.stringify(e);this._core.send(t),this.dispatchEvent(new CustomEvent("wcs-ws:send-changed",{detail:null,bubbles:!0}))}connect(){const e=this.protocols?this.protocols.split(",").map(e=>e.trim()).filter(Boolean):void 0;this._core.connect(this.url,{protocols:e&&1===e.length?e[0]:e,autoReconnect:this.autoReconnect,reconnectInterval:this.reconnectInterval,maxReconnects:this.maxReconnects,binaryType:this.binaryType})}sendMessage(e){this._core.send(e)}close(e,t){this._core.close(e,t)}attributeChangedCallback(e,t,n){"url"===e&&t!==n&&this._attached&&!this.manual&&n&&this.connect()}connectedCallback(){!function(e){const t=e.constructor?.wcBindable,n=t?.inputs;if(void 0===n)return;const s=e.getAttribute;for(const t of n){const n=t.name,r="function"==typeof s?s.call(e,n.toLowerCase()):null;if(null!==r&&r.startsWith("[object ")&&h(e,n,r),!Object.prototype.hasOwnProperty.call(e,n))continue;if(!c(e,n))continue;const o=e,i=o[n];delete o[n],o[n]=i}}(this),this.style.display="none",o||(o=!0,document.addEventListener("click",i)),this._connectedCallbackPromise=this._core.observe(),!this.manual&&this.url&&this.connect(),this._attached=!0}disconnectedCallback(){this._attached=!1,this._core.dispose()}}var b;!function(t=customElements){t.get(e.tagNames.ws)||t.define(e.tagNames.ws,m)}(b);
1
+ const e={triggerAttribute:"data-wstarget",tagNames:{ws:"wcs-ws"}},t="invalid-argument",s="invalid-state",n="connection-error";class r extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"message",event:"wcs-ws:message",semantics:"event"},{name:"connected",event:"wcs-ws:connected-changed",semantics:"state"},{name:"loading",event:"wcs-ws:loading-changed",semantics:"state"},{name:"error",event:"wcs-ws:error",semantics:"state"},{name:"errorInfo",event:"wcs-ws:error-info-changed",semantics:"state"},{name:"readyState",event:"wcs-ws:readystate-changed",semantics:"state"}],commands:[{name:"connect"},{name:"send"},{name:"close"}]};_target;_ws=null;_message=null;_connected=!1;_loading=!1;_error=null;_errorInfo=null;_readyState=3;_autoReconnect=!1;_reconnectInterval=3e3;_maxReconnects=1/0;_reconnectCount=0;_reconnectTimer=null;_url="";_protocols=void 0;_binaryType="blob";_intentionalClose=!1;_staleAfter=0;_lastActivity=0;_staleTimer=null;_gen=0;_socketGen=0;_ready=Promise.resolve();_toldNotReady=!1;constructor(e){super(),this._target=e??this}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.close(),this._setConnected(!1),this._setLoading(!1),this._setReadyState(3)}suspend(){const e=null!==this._ws||null!==this._reconnectTimer;return this.dispose(),e}get message(){return this._message}get connected(){return this._connected}get loading(){return this._loading}get error(){return this._error}get errorInfo(){return this._errorInfo}get readyState(){return this._readyState}_setMessage(e){this._message=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:message",{detail:e,bubbles:!0}))}_setConnected(e){this._connected=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:connected-changed",{detail:e,bubbles:!0}))}_setLoading(e){this._loading=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:loading-changed",{detail:e,bubbles:!0}))}_setError(e,r){this._error!==e&&(this._error=e,this._commitErrorInfo(null===e?null:function(e,r){const i=e.message,o="string"==typeof i?i:"WebSocket connection error";return r===t?{code:t,phase:"start",recoverable:!1,message:o}:r===s?{code:s,phase:"execute",recoverable:!1,message:o}:{code:n,phase:"execute",recoverable:!0,message:o}}(e,r)),this._target.dispatchEvent(new CustomEvent("wcs-ws:error",{detail:e,bubbles:!0})))}_commitErrorInfo(e){this._errorInfo=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:error-info-changed",{detail:e,bubbles:!0}))}_setReadyState(e){this._readyState=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:readystate-changed",{detail:e,bubbles:!0}))}connect(e,s={}){e?(this._gen++,this._intentionalClose=!0,this._closeInternal(),this._url=e,this._protocols=s.protocols,this._autoReconnect=s.autoReconnect??!1,this._reconnectInterval=s.reconnectInterval??3e3,this._maxReconnects=s.maxReconnects??1/0,this._binaryType=s.binaryType??"blob",this._staleAfter=void 0!==s.staleAfter&&s.staleAfter>0?s.staleAfter:0,this._reconnectCount=0,this._intentionalClose=!1,this._doConnect()):this._setError({message:"url is required."},t)}send(e){if(!this._ws||1!==this._ws.readyState)return this._setError({message:"WebSocket is not connected."},s),void this._warnNotReady();this._ws.send(e)}_warnNotReady(){this._toldNotReady||(this._toldNotReady=!0,console.warn("[@wcstack/websocket] [wcs/command-not-ready] send() was refused: the WebSocket is not connected, so the message is lost. It goes to `error` too. Send once `connected` is true. (Said once until the WebSocket connects again.)",this._target))}close(e,t){this._intentionalClose=!0,this._clearReconnectTimer(),this._clearStaleTimer(),this._ws&&this._ws.close(e,t)}_doConnect(){this._setLoading(!0),this._setError(null),this._socketGen=this._gen;try{this._ws=this._protocols?new WebSocket(this._url,this._protocols):new WebSocket(this._url)}catch(e){return this._setLoading(!1),void this._setError(e,n)}this._ws.binaryType=this._binaryType,this._setReadyState(0),this._ws.addEventListener("open",this._onOpen),this._ws.addEventListener("message",this._onMessage),this._ws.addEventListener("error",this._onError),this._ws.addEventListener("close",this._onClose)}_onOpen=()=>{this._socketGen===this._gen&&(this._reconnectCount=0,this._toldNotReady=!1,this._lastActivity=Date.now(),this._armStale(),this._setLoading(!1),this._setConnected(!0),this._setReadyState(1))};_onMessage=e=>{if(this._socketGen!==this._gen)return;this._lastActivity=Date.now();let t=e.data;if("string"==typeof t)try{t=JSON.parse(t)}catch{}this._setMessage(t)};_onError=e=>{this._socketGen===this._gen&&this._setError(e,n)};_onClose=e=>{this._removeListeners(),this._ws=null,this._socketGen===this._gen&&(this._setConnected(!1),this._setLoading(!1),this._setReadyState(3),!this._intentionalClose&&this._autoReconnect&&1e3!==e.code&&this._reconnectCount<this._maxReconnects&&this._scheduleReconnect())};_scheduleReconnect(){const e=this._gen;this._clearReconnectTimer(),this._reconnectTimer=setTimeout(()=>{this._reconnectTimer=null,e===this._gen&&(this._reconnectCount++,this._doConnect())},this._reconnectInterval)}_armStale(){0!==this._staleAfter&&null===this._staleTimer&&(this._staleTimer=setTimeout(this._checkStale,this._staleAfter))}_checkStale=()=>{this._staleTimer=null;const e=this._ws;if(null===e||1!==this._readyState)return;const t=Date.now()-this._lastActivity;if(t<this._staleAfter)this._staleTimer=setTimeout(this._checkStale,this._staleAfter-t);else{this._removeListeners(),this._ws=null;try{e.close(4e3,"stale")}catch{}this._setConnected(!1),this._setLoading(!1),this._setReadyState(3),this._setError({message:`No message for ${this._staleAfter} ms: the connection is treated as lost.`},n),!this._intentionalClose&&this._autoReconnect&&this._reconnectCount<this._maxReconnects&&this._scheduleReconnect()}};_clearStaleTimer(){null!==this._staleTimer&&(clearTimeout(this._staleTimer),this._staleTimer=null)}_clearReconnectTimer(){null!==this._reconnectTimer&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null)}_removeListeners(){this._ws&&(this._ws.removeEventListener("open",this._onOpen),this._ws.removeEventListener("message",this._onMessage),this._ws.removeEventListener("error",this._onError),this._ws.removeEventListener("close",this._onClose))}_closeInternal(){this._clearReconnectTimer(),this._clearStaleTimer(),this._ws&&(this._removeListeners(),1!==this._ws.readyState&&0!==this._ws.readyState||this._ws.close(),this._ws=null),this._connected&&this._setConnected(!1),3!==this._readyState&&this._setReadyState(3)}}let i=!1;function o(t){const s=t.target;if(!(s instanceof Element))return;const n=s.closest(`[${e.triggerAttribute}]`);if(!n)return;const r=n.getAttribute(e.triggerAttribute);if(!r)return;const i=customElements.get(e.tagNames.ws),o=document.getElementById(r);i&&o instanceof i&&(t.preventDefault(),o.connect())}function a(e,t){let s=Object.getPrototypeOf(e);for(;null!==s;){const e=Object.getOwnPropertyDescriptor(s,t);if(void 0!==e)return"function"==typeof e.get||"function"==typeof e.set;s=Object.getPrototypeOf(s)}return!1}const c=new WeakSet;function h(e,t,s){if(c.has(e))return;c.add(e);const n=e.localName??"element";console.warn(`[wcs/input-as-attribute] <${n}> has the attribute ${t}="${s}": an object was written as an attribute, so the element did not receive it. A framework does that when the property is set before the element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, or assign the property through a ref (Vue: .prop). (Said once per element.)`,e)}const l=new WeakMap;function _(e,t){let s=l.get(e);return void 0===s&&(s=new Map,l.set(e,s)),s.has(t)||s.set(t,e.getAttribute(t)),s.get(t)}function d(e,t,s){null===s?e.removeAttribute(t):e.setAttribute(t,s)}function u(e,t,s){const n=_(e,t);d(e,t,void 0===s?n:null===s?null:String(s))}function g(e,t,s){const n=_(e,t);d(e,t,void 0===s?n:s?"":null)}class m extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...r.wcBindable,properties:[...r.wcBindable.properties,{name:"trigger",event:"wcs-ws:trigger-changed",semantics:"state"},{name:"send",event:"wcs-ws:send-changed",semantics:"state"}],inputs:[{name:"url",attribute:"url"},{name:"protocols",attribute:"protocols"},{name:"autoReconnect",attribute:"auto-reconnect"},{name:"reconnectInterval",attribute:"reconnect-interval"},{name:"maxReconnects",attribute:"max-reconnects"},{name:"binaryType",attribute:"binary-type"},{name:"staleAfter",attribute:"stale-after"},{name:"manual",attribute:"manual"},{name:"trigger"},{name:"send"}],commands:[{name:"connect"},{name:"sendMessage"},{name:"close"}]};static get observedAttributes(){return["url"]}_core;_trigger=!1;_connectedCallbackPromise=Promise.resolve();_internals=null;_attached=!1;_connectPending=!1;constructor(){super(),this._core=new r(this),this._internals=this._initInternals(),this._wireStates({"wcs-ws:connected-changed":e=>({connected:!0===e}),"wcs-ws:loading-changed":e=>({loading:!0===e}),"wcs-ws:error":e=>({error:null!=e})})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const e=this.attachInternals();return e.states.add("wcs-probe"),e.states.delete("wcs-probe"),e}catch{return null}}_wireStates(e){if(null===this._internals)return;const t=this._internals.states;for(const[s,n]of Object.entries(e))this.addEventListener(s,e=>{const s=this.hasAttribute("debug-states");for(const[r,i]of Object.entries(n(e.detail))){try{i?t.add(r):t.delete(r)}catch{}s&&this.toggleAttribute(`data-wcs-state-${r}`,i)}})}get url(){return this.getAttribute("url")||""}set url(e){u(this,"url",e)}get protocols(){return this.getAttribute("protocols")||""}set protocols(e){u(this,"protocols",e)}get autoReconnect(){return this.hasAttribute("auto-reconnect")}set autoReconnect(e){g(this,"auto-reconnect",e)}get reconnectInterval(){const e=this.getAttribute("reconnect-interval"),t=e?parseInt(e,10):3e3;return Number.isNaN(t)?3e3:t}set reconnectInterval(e){u(this,"reconnect-interval",e)}get maxReconnects(){const e=this.getAttribute("max-reconnects"),t=e?parseInt(e,10):1/0;return Number.isNaN(t)?1/0:t}set maxReconnects(e){u(this,"max-reconnects",e)}get binaryType(){return"arraybuffer"===this.getAttribute("binary-type")?"arraybuffer":"blob"}set binaryType(e){u(this,"binary-type",e)}get staleAfter(){const e=Number(this.getAttribute("stale-after"));return Number.isFinite(e)&&e>0?e:0}set staleAfter(e){u(this,"stale-after",e)}get manual(){return this.hasAttribute("manual")}set manual(e){g(this,"manual",e)}get message(){return this._core.message}get connected(){return this._core.connected}get loading(){return this._core.loading}get error(){return this._core.error}get errorInfo(){return this._core.errorInfo}get readyState(){return this._core.readyState}get trigger(){return this._trigger}set trigger(e){!!e&&(this._trigger=!0,this.connect(),this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-ws:trigger-changed",{detail:!1,bubbles:!0})))}get send(){return null}set send(e){if(null==e)return;const t="string"==typeof e?e:JSON.stringify(e);this._core.send(t),this.dispatchEvent(new CustomEvent("wcs-ws:send-changed",{detail:null,bubbles:!0}))}connect(){this._connectPending=!1;const e=this.protocols?this.protocols.split(",").map(e=>e.trim()).filter(Boolean):void 0;this._core.connect(this.url,{protocols:e&&1===e.length?e[0]:e,autoReconnect:this.autoReconnect,reconnectInterval:this.reconnectInterval,maxReconnects:this.maxReconnects,binaryType:this.binaryType,staleAfter:this.staleAfter})}sendMessage(e){this._core.send(e)}close(e,t){this._connectPending=!1,this._core.close(e,t)}attributeChangedCallback(e,t,s){"url"===e&&t!==s&&this._attached&&!this.manual&&s&&this._scheduleConnect()}_scheduleConnect(){this._connectPending||(this._connectPending=!0,queueMicrotask(()=>{this._connectPending&&(this._connectPending=!1,this._attached&&!this.manual&&this.url&&this.connect())}))}connectedCallback(){!function(e){const t=e.constructor?.wcBindable,s=t?.inputs;if(void 0===s)return;const n=e.getAttribute;for(const t of s){const s=t.name,r="function"==typeof n?n.call(e,s.toLowerCase()):null;if(null!==r&&r.startsWith("[object ")&&h(e,s,r),!Object.prototype.hasOwnProperty.call(e,s))continue;if(!a(e,s))continue;const i=e,o=i[s];delete i[s],i[s]=o}}(this),this.style.display="none",i||(i=!0,document.addEventListener("click",o)),this._connectedCallbackPromise=this._core.observe(),this._attached=!0,window.addEventListener("pagehide",this._onPageHide),window.addEventListener("pageshow",this._onPageShow),this._scheduleConnect()}_reopenOnShow=!1;_onPageHide=e=>{e.persisted&&this._core.suspend()&&(this._reopenOnShow=!0)};_onPageShow=e=>{e.persisted&&this._reopenOnShow&&(this._reopenOnShow=!1,this.url&&this.connect())};disconnectedCallback(){this._attached=!1,this._reopenOnShow=!1,window.removeEventListener("pagehide",this._onPageHide),window.removeEventListener("pageshow",this._onPageShow),this._core.dispose()}}var w;!function(t=customElements){t.get(e.tagNames.ws)||t.define(e.tagNames.ws,m)}(w);
2
2
  //# sourceMappingURL=auto.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/websocketCapabilities.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/WebSocket.ts","../src/bootstrapWebSocket.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n ws: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-wstarget\",\n tagNames: {\n ws: \"wcs-ws\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\n/** A misspelt option would otherwise do nothing: `bootstrapWebSocket` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/websocket] bootstrapWebSocket: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","/**\n * websocketCapabilities.ts\n *\n * WebSocket node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。WebSocket は持続的な session / monitor node(1 本の接続を張り続ける)で、\n * 競合する operation を持たないため lane は持たず、error taxonomy(errorInfo)のみを採用する。\n *\n * この node の `_setError` は 4 形態の非 null 入力を受ける(いずれも公開 `error` shape は不変):\n * 1. synthetic な `{ message: \"url is required.\" }`(`.name` 無し)— connect() の引数不備。\n * 2. synthetic な `{ message: \"WebSocket is not connected.\" }`(`.name` 無し)— open 前の send()。\n * 3. caught された生の構築例外 `e`(`new WebSocket()` の同期 throw)。\n * 4. platform の WebSocket `error` Event(`Event`。`.name`/`.message` を持たない)。\n *\n * これらは shape がバラバラで、message からの分類は脆い。そこで呼び出し側が明示的な\n * taxonomy code を discriminator として渡す(storage の `deriveStorageErrorInfo(error, name)`\n * と同じ技法)。derive 側は synthetic / Event / Error を reverse-engineer せず、渡された\n * code で phase / recoverable を決め、message だけを防御的に抽出する。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 安定した websocket error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_WEBSOCKET_ERROR_CODE = {\n /** connect() の `url` 未指定 — 開始前の入力不備。retry では回復しない。 */\n InvalidArgument: \"invalid-argument\",\n /** open 前の send() — 接続が OPEN でない状態での送信。retry では回復しない(先に connect が要る)。 */\n InvalidState: \"invalid-state\",\n /**\n * 接続の確立 / 維持に失敗(`new WebSocket()` の同期例外、または platform の error Event)。\n * WebSocket のエラーは通常一過性で、再接続で回復しうる(recoverable=true)。\n */\n ConnectionError: \"connection-error\",\n} as const;\n\n/**\n * websocket の失敗を serializable な error taxonomy に写す。`code` は呼び出し側が渡す\n * discriminator(公開 `error` shape からは復元しない)。`message` は入力から防御的に抽出し、\n * message を持たない error Event 等では安定した fallback を使う。\n *\n * - `invalid-argument`(url 未指定)は開始前の入力不備 → phase=\"start\" / recoverable=false。\n * - `invalid-state`(open 前 send)は接続状態が満たされない実行時失敗 → phase=\"execute\" /\n * recoverable=false(先に connect() が必要)。\n * - `connection-error`(構築例外 / error Event)は接続の確立 / 維持失敗 → phase=\"execute\" /\n * recoverable=true(再接続で回復しうる)。\n */\nexport function deriveWebSocketErrorInfo(error: unknown, code: string): WcsIoErrorInfo {\n // error は非 null(_setError は error===null を derive 前に分岐する)だが、synthetic /\n // Event / caught 例外 / 生 throw と shape がバラバラなので message は防御的に抽出する。\n // error Event は message を持たないため安定した fallback に落とす。\n const raw = (error as { message?: unknown }).message;\n const message = typeof raw === \"string\" ? raw : \"WebSocket connection error\";\n\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidArgument) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidArgument, phase: \"start\", recoverable: false, message };\n }\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidState) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidState, phase: \"execute\", recoverable: false, message };\n }\n // connection-error(構築例外 / error Event): 接続の確立/維持失敗、再接続で回復しうる。\n return { code: WCS_WEBSOCKET_ERROR_CODE.ConnectionError, phase: \"execute\", recoverable: true, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveWebSocketErrorInfo, WCS_WEBSOCKET_ERROR_CODE } from \"./websocketCapabilities.js\";\n\n// WebSocket readyState values. Hardcoded rather than read from the global\n// WebSocket so the Core does not require WebSocket to exist at module load\n// (referencing `WebSocket.CLOSED` in a field initializer evaluates at class\n// definition time; tests inject a mock). Mirrors SseCore's SSE_CLOSED.\nconst WS_CONNECTING = 0;\nconst WS_OPEN = 1;\nconst WS_CLOSED = 3;\n\nexport interface WebSocketConnectOptions {\n protocols?: string | string[];\n autoReconnect?: boolean;\n reconnectInterval?: number;\n maxReconnects?: number;\n // How incoming binary frames are surfaced on `message`. \"blob\" (the platform\n // default) or \"arraybuffer\" for direct byte processing. Applied to every\n // socket this connection spawns, including auto-reconnects.\n binaryType?: BinaryType;\n}\n\nexport class WebSocketCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"message\", event: \"wcs-ws:message\", semantics: \"event\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\", semantics: \"state\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\", semantics: \"state\" },\n { name: \"error\", event: \"wcs-ws:error\", semantics: \"state\" },\n // Serializable failure taxonomy (stable code / phase / recoverable), or null.\n // Additive bindable output derived from `error` (invalid-argument / invalid-state\n // / connection-error); the existing `error` property/event are unchanged. Fires\n // wcs-ws:error-info-changed. No lane — WebSocket is a persistent session/monitor\n // node, not a competing operation.\n { name: \"errorInfo\", event: \"wcs-ws:error-info-changed\", semantics: \"state\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"send\" },\n { name: \"close\" },\n ],\n };\n\n private _target: EventTarget;\n private _ws: WebSocket | null = null;\n private _message: any = null;\n private _connected: boolean = false;\n private _loading: boolean = false;\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n private _readyState: number = WS_CLOSED;\n\n // 自動再接続\n private _autoReconnect: boolean = false;\n private _reconnectInterval: number = 3000;\n private _maxReconnects: number = Infinity;\n private _reconnectCount: number = 0;\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private _url: string = \"\";\n private _protocols: string | string[] | undefined = undefined;\n private _binaryType: BinaryType = \"blob\";\n private _intentionalClose: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() and at every connect(). A socket\n // event (open/message/error/close) or a scheduled reconnect that fires after\n // dispose / a superseding connect() carries a stale `gen` and MUST NOT write\n // state onto a torn-down element. A boolean flag is insufficient (dispose→observe\n // would let stale work slip through).\n private _gen = 0;\n // Generation captured when the current socket was opened. The shared socket\n // event handlers compare it against _gen to drop events from a superseded /\n // disposed connection.\n private _socketGen = 0;\n // SSR (§3.8): WebSocket is command-driven with no asynchronous probe to await,\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n /**\n * Whether `[wcs/command-not-ready]` was said for this element: a `send()` refused because the\n * element is not ready loses what it carried, and `error` alone told only a page that binds it.\n * Said once per element (docs/v4-direction-2026-10.md, the I/O command policy).\n */\n private _toldNotReady = false;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). WebSocket connections are command-driven (connect()), so\n // observe() is an idempotent no-op that resolves once ready; the Shell's\n // connectedCallback does not auto-establish a subscription here. dispose()\n // invalidates any in-flight socket / pending reconnect and closes the socket.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.close();\n // The socket's close event is dropped as stale (the generation moved), so the\n // connection's end is published here (timing-and-firing-contract §22): a route the\n // element leaves keeps its nodes — bindings included — for the next entry, and\n // state would keep showing a connection that is gone.\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n }\n\n get message(): any {\n return this._message;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-ws:error-info-changed`), derived from `error`; the existing `error`\n * property/event are unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n get readyState(): number {\n return this._readyState;\n }\n\n // --- State setters with event dispatch ---\n\n private _setMessage(message: any): void {\n this._message = message;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:message\", {\n detail: message,\n bubbles: true,\n }));\n }\n\n private _setConnected(connected: boolean): void {\n this._connected = connected;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:connected-changed\", {\n detail: connected,\n bubbles: true,\n }));\n }\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // `code` is an explicit taxonomy discriminator (WCS_WEBSOCKET_ERROR_CODE), passed\n // only from the non-null failure call sites. It stays out of the public `error`\n // shape and is used solely to classify errorInfo without reverse-engineering the\n // heterogeneous `error` values (synthetic {message} / caught Error / raw Event).\n // The clear path passes null and no code.\n private _setError(error: any, code?: string): void {\n // Same-value guard (async-io-node-guidelines.md §3.3). `error` is state-ish,\n // so suppressing redundant null→null dispatches (every connect/send start\n // clears a usually-already-null error) avoids a spurious wcs-ws:error per\n // successful operation. Reference identity is sufficient: each failure builds\n // a fresh object (or the platform's own error Event), and the clear path\n // always passes null.\n if (this._error === error) return;\n this._error = error;\n // Keep the additive `errorInfo` taxonomy in sync with `error`: derive from the\n // explicit `code` (or null on clear). Fires before the `error` event so an\n // observer binding both sees the classification first, mirroring the io-node\n // family. Every non-null error carries a code (the clear path is the only\n // caller without one, and it is short-circuited here), so `code!` holds.\n this._commitErrorInfo(error === null ? null : deriveWebSocketErrorInfo(error, code!));\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (which already same-value-guards on the error\n // reference), so errorInfo transitions exactly when error does — no separate\n // guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n\n private _setReadyState(readyState: number): void {\n this._readyState = readyState;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:readystate-changed\", {\n detail: readyState,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n connect(url: string, options: WebSocketConnectOptions = {}): void {\n // never-throw (§3.6): 引数バリデーション失敗は例外ではなく error プロパティに\n // 流し、サニタイズ値(なにもしない)を返す。command-token 経路(set trigger →\n // connect())からの呼び出しが state 更新サイクルを壊さないようにする。\n if (!url) {\n this._setError({ message: \"url is required.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidArgument);\n return;\n }\n\n // 新しい接続を開始するため世代を更新し、進行中のソケット/再接続を無効化する。\n this._gen++;\n\n // 既存の接続をクローズ\n this._intentionalClose = true;\n this._closeInternal();\n\n this._url = url;\n this._protocols = options.protocols;\n this._autoReconnect = options.autoReconnect ?? false;\n this._reconnectInterval = options.reconnectInterval ?? 3000;\n this._maxReconnects = options.maxReconnects ?? Infinity;\n this._binaryType = options.binaryType ?? \"blob\";\n this._reconnectCount = 0;\n this._intentionalClose = false;\n\n this._doConnect();\n }\n\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n // never-throw (§3.6): 未接続での送信は例外ではなく error に流す。set send の\n // fire-and-forget 経路で例外が伝播するのを防ぐ。\n if (!this._ws || this._ws.readyState !== WS_OPEN) {\n this._setError({ message: \"WebSocket is not connected.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidState);\n this._warnNotReady();\n return;\n }\n this._ws.send(data);\n }\n\n private _warnNotReady(): void {\n if (this._toldNotReady) return;\n this._toldNotReady = true;\n console.warn(\n \"[@wcstack/websocket] [wcs/command-not-ready] send() was refused: the WebSocket is not connected, so the message is lost. \" +\n \"It goes to `error` too. Send once `connected` is true. (Said once per element.)\",\n this._target,\n );\n }\n\n close(code?: number, reason?: string): void {\n this._intentionalClose = true;\n this._clearReconnectTimer();\n if (this._ws) {\n this._ws.close(code, reason);\n }\n }\n\n // --- Internal ---\n\n private _doConnect(): void {\n this._setLoading(true);\n this._setError(null);\n\n // 接続開始時点の世代を捕捉。dispose()/再 connect() 後に発火した古いソケット\n // イベントはこの gen が stale になり、状態を書き換えない(_onOpen ほかが\n // _socketGen と this._gen を突き合わせて判定する)。\n this._socketGen = this._gen;\n\n try {\n this._ws = this._protocols\n ? new WebSocket(this._url, this._protocols)\n : new WebSocket(this._url);\n } catch (e) {\n this._setLoading(false);\n this._setError(e, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n return;\n }\n\n // Binary frames default to Blob; opt into ArrayBuffer for direct byte access.\n this._ws.binaryType = this._binaryType;\n\n this._setReadyState(WS_CONNECTING);\n\n this._ws.addEventListener(\"open\", this._onOpen);\n this._ws.addEventListener(\"message\", this._onMessage);\n this._ws.addEventListener(\"error\", this._onError);\n this._ws.addEventListener(\"close\", this._onClose);\n }\n\n private _onOpen = (): void => {\n if (this._socketGen !== this._gen) return;\n this._reconnectCount = 0;\n this._setLoading(false);\n this._setConnected(true);\n this._setReadyState(WS_OPEN);\n };\n\n private _onMessage = (event: MessageEvent): void => {\n if (this._socketGen !== this._gen) return;\n let data = event.data;\n // JSONの自動パース\n if (typeof data === \"string\") {\n try {\n data = JSON.parse(data);\n } catch {\n // テキストのまま\n }\n }\n this._setMessage(data);\n };\n\n private _onError = (event: Event): void => {\n if (this._socketGen !== this._gen) return;\n this._setError(event, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n };\n\n private _onClose = (event: CloseEvent): void => {\n this._removeListeners();\n this._ws = null;\n if (this._socketGen !== this._gen) return;\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n\n // 異常クローズ時の自動再接続(正常終了 1000 は除外)\n if (!this._intentionalClose && this._autoReconnect && event.code !== 1000 && this._reconnectCount < this._maxReconnects) {\n this._scheduleReconnect();\n }\n };\n\n private _scheduleReconnect(): void {\n const gen = this._gen;\n this._clearReconnectTimer();\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null;\n // dispose()/再 connect() でこの再接続が無効化されていたら何もしない。\n if (gen !== this._gen) return;\n this._reconnectCount++;\n this._doConnect();\n }, this._reconnectInterval);\n }\n\n private _clearReconnectTimer(): void {\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n }\n\n private _removeListeners(): void {\n if (!this._ws) {\n return;\n }\n\n this._ws.removeEventListener(\"open\", this._onOpen);\n this._ws.removeEventListener(\"message\", this._onMessage);\n this._ws.removeEventListener(\"error\", this._onError);\n this._ws.removeEventListener(\"close\", this._onClose);\n }\n\n private _closeInternal(): void {\n this._clearReconnectTimer();\n if (this._ws) {\n this._removeListeners();\n if (this._ws.readyState === WS_OPEN || this._ws.readyState === WS_CONNECTING) {\n this._ws.close();\n }\n this._ws = null;\n }\n // 旧接続の状態をリセット(コンストラクタ例外時に stale 状態が残るのを防止)\n if (this._connected) {\n this._setConnected(false);\n }\n if (this._readyState !== WS_CLOSED) {\n this._setReadyState(WS_CLOSED);\n }\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsWebSocket } from \"./components/WebSocket.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const wsId = triggerElement.getAttribute(config.triggerAttribute);\n if (!wsId) return;\n\n // Resolve the registered constructor at call time instead of importing\n // WcsWebSocket as a value. The value import created a components/WebSocket.ts ⇄\n // autoTrigger.ts cycle (WcsWebSocket.connectedCallback() calls\n // registerAutoTrigger()). instanceof against the customElements registry keeps\n // the exact same identity guarantee — only the registered <wcs-ws> class\n // matches — without the import cycle.\n const WsCtor = customElements.get(config.tagNames.ws);\n const wsElement = document.getElementById(wsId);\n if (!WsCtor || !(wsElement instanceof WsCtor)) return;\n\n event.preventDefault();\n (wsElement as WcsWebSocket).connect();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class WcsWebSocket extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...WebSocketCore.wcBindable,\n properties: [\n ...WebSocketCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-ws:trigger-changed\", semantics: \"state\" },\n { name: \"send\", event: \"wcs-ws:send-changed\", semantics: \"state\" },\n ],\n inputs: [\n { name: \"url\", attribute: \"url\" },\n { name: \"protocols\", attribute: \"protocols\" },\n { name: \"autoReconnect\", attribute: \"auto-reconnect\" },\n { name: \"reconnectInterval\", attribute: \"reconnect-interval\" },\n { name: \"maxReconnects\", attribute: \"max-reconnects\" },\n { name: \"binaryType\", attribute: \"binary-type\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n { name: \"send\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"sendMessage\" },\n { name: \"close\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: WebSocketCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n // connectedCallback が接続の判断を終えてから disconnectedCallback までの間だけ true。\n // url 属性の変化による再接続はこの間に限る — upgrade 時は attributeChangedCallback が\n // connectedCallback より先に(isConnected のまま)呼ばれるので、そこで接続すると\n // connectedCallback の接続と合わせて 2 本になる。初回の接続は connectedCallback が持つ。\n private _attached = false;\n\n constructor() {\n super();\n this._core = new WebSocketCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-ws:connected-changed\": (d) => ({ connected: d === true }),\n \"wcs-ws:loading-changed\": (d) => ({ loading: d === true }),\n \"wcs-ws:error\": (d) => ({ error: d != null }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined (an\n // \"undefined\" url would reconnect to \"undefined\"): `null` removes the\n // attribute (the documented default; an empty url does not connect),\n // `undefined` restores the attribute the element started with (wc-bindable\n // producer guidance P1; React 19 and a direct assignment deliver it,\n // @wcstack/state does not).\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string | null | undefined) {\n reflectAttribute(this, \"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string | null | undefined) {\n reflectAttribute(this, \"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"auto-reconnect\", value);\n }\n\n get reconnectInterval(): number {\n const attr = this.getAttribute(\"reconnect-interval\");\n const parsed = attr ? parseInt(attr, 10) : 3000;\n return Number.isNaN(parsed) ? 3000 : parsed;\n }\n\n set reconnectInterval(value: number | null | undefined) {\n reflectAttribute(this, \"reconnect-interval\", value);\n }\n\n get maxReconnects(): number {\n const attr = this.getAttribute(\"max-reconnects\");\n const parsed = attr ? parseInt(attr, 10) : Infinity;\n return Number.isNaN(parsed) ? Infinity : parsed;\n }\n\n set maxReconnects(value: number | null | undefined) {\n reflectAttribute(this, \"max-reconnects\", value);\n }\n\n // Incoming binary frame representation. Backed by the `binary-type` attribute;\n // any value other than \"arraybuffer\" normalizes to the platform default \"blob\".\n get binaryType(): BinaryType {\n return this.getAttribute(\"binary-type\") === \"arraybuffer\" ? \"arraybuffer\" : \"blob\";\n }\n\n set binaryType(value: string | null | undefined) {\n reflectAttribute(this, \"binary-type\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get message(): any {\n return this._core.message;\n }\n\n get connected(): boolean {\n return this._core.connected;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n get readyState(): number {\n return this._core.readyState;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.connect();\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-ws:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // `send` is a write-only command surface: assigning transmits immediately.\n // Reading always returns null (no payload is retained) — consistent with the\n // null carried by wcs-ws:send-changed and the documented \"resets to null\".\n get send(): any {\n return null;\n }\n\n set send(data: any) {\n if (data === null || data === undefined) return;\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n this._core.send(payload);\n this.dispatchEvent(new CustomEvent(\"wcs-ws:send-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n // --- Public methods ---\n\n connect(): void {\n const protocols = this.protocols\n ? this.protocols.split(\",\").map(p => p.trim()).filter(Boolean)\n : undefined;\n\n this._core.connect(this.url, {\n protocols: protocols && protocols.length === 1 ? protocols[0] : protocols,\n autoReconnect: this.autoReconnect,\n reconnectInterval: this.reconnectInterval,\n maxReconnects: this.maxReconnects,\n binaryType: this.binaryType,\n });\n }\n\n sendMessage(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this._core.send(data);\n }\n\n close(code?: number, reason?: string): void {\n this._core.close(code, reason);\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // 再接続するのは url が「変わった」ときだけ。同じ値の書き込み(url の setter 自身の\n // setAttribute の後に、属性も書く binder — @wcstack/state 3.x の inputs[].attribute ミラー —\n // が同じ値を書く、など)\n // は何もしない。connectedCallback より前(upgrade 中・DOM の外)の変化は、\n // connectedCallback がそのときの url で 1 回だけ接続する。\n if (name === \"url\" && oldValue !== newValue && this._attached && !this.manual && newValue) {\n this.connect();\n }\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)。\n // ここで url の setter が走っても _attached はまだ false なので接続しない —\n // 接続は下で、取り込み後の url / manual を見て 1 回だけ行う。\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // observe() は command-driven node では ready を返す no-op(§3.5)。SSR は\n // connectedCallbackPromise を await して初期スナップショットを取れる。\n this._connectedCallbackPromise = this._core.observe();\n if (!this.manual && this.url) {\n this.connect();\n }\n this._attached = true;\n }\n\n disconnectedCallback(): void {\n this._attached = false;\n // dispose() が _gen を bump して進行中のソケット/再接続を無効化し、close() する。\n this._core.dispose();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapWebSocket(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.ws)) {\n registry.define(config.tagNames.ws, WcsWebSocket);\n }\n}\n"],"names":["config","triggerAttribute","tagNames","ws","WCS_WEBSOCKET_ERROR_CODE","WebSocketCore","EventTarget","static","protocol","version","properties","name","event","semantics","commands","_target","_ws","_message","_connected","_loading","_error","_errorInfo","_readyState","_autoReconnect","_reconnectInterval","_maxReconnects","Infinity","_reconnectCount","_reconnectTimer","_url","_protocols","undefined","_binaryType","_intentionalClose","_gen","_socketGen","_ready","Promise","resolve","_toldNotReady","constructor","target","super","this","ready","observe","dispose","close","_setConnected","_setLoading","_setReadyState","message","connected","loading","error","errorInfo","readyState","_setMessage","dispatchEvent","CustomEvent","detail","bubbles","_setError","code","_commitErrorInfo","raw","phase","recoverable","deriveWebSocketErrorInfo","info","connect","url","options","_closeInternal","protocols","autoReconnect","reconnectInterval","maxReconnects","binaryType","_doConnect","send","data","_warnNotReady","console","warn","reason","_clearReconnectTimer","WebSocket","e","addEventListener","_onOpen","_onMessage","_onError","_onClose","JSON","parse","_removeListeners","_scheduleReconnect","gen","setTimeout","clearTimeout","removeEventListener","registered","handleClick","Element","triggerElement","closest","wsId","getAttribute","WsCtor","customElements","get","wsElement","document","getElementById","preventDefault","hasAccessorOnPrototype","proto","Object","getPrototypeOf","descriptor","getOwnPropertyDescriptor","set","toldObjectAttribute","WeakSet","warnObjectAttribute","element","value","has","add","tag","localName","initialAttributes","WeakMap","initialAttribute","el","byName","Map","writeAttribute","removeAttribute","setAttribute","reflectAttribute","initial","String","reflectBooleanAttribute","WcsWebSocket","HTMLElement","wcBindable","inputs","attribute","observedAttributes","_core","_trigger","_connectedCallbackPromise","_internals","_attached","_initInternals","_wireStates","d","connectedCallbackPromise","debugStates","states","attachInternals","internals","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","attr","parsed","parseInt","Number","isNaN","manual","trigger","payload","stringify","split","p","trim","filter","Boolean","length","sendMessage","attributeChangedCallback","oldValue","newValue","connectedCallback","declaration","input","call","toLowerCase","startsWith","prototype","hasOwnProperty","record","upgradeProperties","style","display","disconnectedCallback","registry","define","registerComponents"],"mappings":"AAUA,MA4BaA,EA5BoB,CAE/BC,iBAAkB,gBAClBC,SAAU,CACRC,GAAI,WCSKC,EAEM,mBAFNA,EAIG,gBAJHA,EASM,mBCTb,MAAOC,UAAsBC,YACjCC,kBAAiC,CAC/BC,SAAU,cACVC,QAAS,EACTC,WAAY,CACV,CAAEC,KAAM,UAAWC,MAAO,iBAAkBC,UAAW,SACvD,CAAEF,KAAM,YAAaC,MAAO,2BAA4BC,UAAW,SACnE,CAAEF,KAAM,UAAWC,MAAO,yBAA0BC,UAAW,SAC/D,CAAEF,KAAM,QAASC,MAAO,eAAgBC,UAAW,SAMnD,CAAEF,KAAM,YAAaC,MAAO,4BAA6BC,UAAW,SACpE,CAAEF,KAAM,aAAcC,MAAO,4BAA6BC,UAAW,UAEvEC,SAAU,CACR,CAAEH,KAAM,WACR,CAAEA,KAAM,QACR,CAAEA,KAAM,WAIJI,QACAC,IAAwB,KACxBC,SAAgB,KAChBC,YAAsB,EACtBC,UAAoB,EACpBC,OAAc,KACdC,WAAoC,KACpCC,YA5CQ,EA+CRC,gBAA0B,EAC1BC,mBAA6B,IAC7BC,eAAyBC,IACzBC,gBAA0B,EAC1BC,gBAAwD,KACxDC,KAAe,GACfC,gBAA4CC,EAC5CC,YAA0B,OAC1BC,mBAA6B,EAO7BC,KAAO,EAIPC,WAAa,EAGbC,OAAwBC,QAAQC,UAOhCC,eAAgB,EAExB,WAAAC,CAAYC,GACVC,QACAC,KAAK5B,QAAU0B,GAAUE,IAC3B,CAEA,SAAIC,GACF,OAAOD,KAAKP,MACd,CAMA,OAAAS,GACE,OAAOF,KAAKP,MACd,CAEA,OAAAU,GACEH,KAAKT,OACLS,KAAKI,QAKLJ,KAAKK,eAAc,GACnBL,KAAKM,aAAY,GACjBN,KAAKO,eAxGS,EAyGhB,CAEA,WAAIC,GACF,OAAOR,KAAK1B,QACd,CAEA,aAAImC,GACF,OAAOT,KAAKzB,UACd,CAEA,WAAImC,GACF,OAAOV,KAAKxB,QACd,CAEA,SAAImC,GACF,OAAOX,KAAKvB,MACd,CAQA,aAAImC,GACF,OAAOZ,KAAKtB,UACd,CAEA,cAAImC,GACF,OAAOb,KAAKrB,WACd,CAIQ,WAAAmC,CAAYN,GAClBR,KAAK1B,SAAWkC,EAChBR,KAAK5B,QAAQ2C,cAAc,IAAIC,YAAY,iBAAkB,CAC3DC,OAAQT,EACRU,SAAS,IAEb,CAEQ,aAAAb,CAAcI,GACpBT,KAAKzB,WAAakC,EAClBT,KAAK5B,QAAQ2C,cAAc,IAAIC,YAAY,2BAA4B,CACrEC,OAAQR,EACRS,SAAS,IAEb,CAEQ,WAAAZ,CAAYI,GAClBV,KAAKxB,SAAWkC,EAChBV,KAAK5B,QAAQ2C,cAAc,IAAIC,YAAY,yBAA0B,CACnEC,OAAQP,EACRQ,SAAS,IAEb,CAOQ,SAAAC,CAAUR,EAAYS,GAOxBpB,KAAKvB,SAAWkC,IACpBX,KAAKvB,OAASkC,EAMdX,KAAKqB,iBAA2B,OAAVV,EAAiB,KDlJrC,SAAmCA,EAAgBS,GAIvD,MAAME,EAAOX,EAAgCH,QACvCA,EAAyB,iBAARc,EAAmBA,EAAM,6BAEhD,OAAIF,IAAS3D,EACJ,CAAE2D,KAAM3D,EAA0C8D,MAAO,QAASC,aAAa,EAAOhB,WAE3FY,IAAS3D,EACJ,CAAE2D,KAAM3D,EAAuC8D,MAAO,UAAWC,aAAa,EAAOhB,WAGvF,CAAEY,KAAM3D,EAA0C8D,MAAO,UAAWC,aAAa,EAAMhB,UAChG,CCmIkDiB,CAAyBd,EAAOS,IAC9EpB,KAAK5B,QAAQ2C,cAAc,IAAIC,YAAY,eAAgB,CACzDC,OAAQN,EACRO,SAAS,KAEb,CAKQ,gBAAAG,CAAiBK,GACvB1B,KAAKtB,WAAagD,EAClB1B,KAAK5B,QAAQ2C,cAAc,IAAIC,YAAY,4BAA6B,CACtEC,OAAQS,EACRR,SAAS,IAEb,CAEQ,cAAAX,CAAeM,GACrBb,KAAKrB,YAAckC,EACnBb,KAAK5B,QAAQ2C,cAAc,IAAIC,YAAY,4BAA6B,CACtEC,OAAQJ,EACRK,SAAS,IAEb,CAIA,OAAAS,CAAQC,EAAaC,EAAmC,IAIjDD,GAML5B,KAAKT,OAGLS,KAAKV,mBAAoB,EACzBU,KAAK8B,iBAEL9B,KAAKd,KAAO0C,EACZ5B,KAAKb,WAAa0C,EAAQE,UAC1B/B,KAAKpB,eAAiBiD,EAAQG,gBAAiB,EAC/ChC,KAAKnB,mBAAqBgD,EAAQI,mBAAqB,IACvDjC,KAAKlB,eAAiB+C,EAAQK,eAAiBnD,IAC/CiB,KAAKX,YAAcwC,EAAQM,YAAc,OACzCnC,KAAKhB,gBAAkB,EACvBgB,KAAKV,mBAAoB,EAEzBU,KAAKoC,cApBHpC,KAAKmB,UAAU,CAAEX,QAAS,oBAAsB/C,EAqBpD,CAEA,IAAA4E,CAAKC,GAGH,IAAKtC,KAAK3B,KAlPE,IAkPK2B,KAAK3B,IAAIwC,WAGxB,OAFAb,KAAKmB,UAAU,CAAEX,QAAS,+BAAiC/C,QAC3DuC,KAAKuC,gBAGPvC,KAAK3B,IAAIgE,KAAKC,EAChB,CAEQ,aAAAC,GACFvC,KAAKJ,gBACTI,KAAKJ,eAAgB,EACrB4C,QAAQC,KACN,2MAEAzC,KAAK5B,SAET,CAEA,KAAAgC,CAAMgB,EAAesB,GACnB1C,KAAKV,mBAAoB,EACzBU,KAAK2C,uBACD3C,KAAK3B,KACP2B,KAAK3B,IAAI+B,MAAMgB,EAAMsB,EAEzB,CAIQ,UAAAN,GACNpC,KAAKM,aAAY,GACjBN,KAAKmB,UAAU,MAKfnB,KAAKR,WAAaQ,KAAKT,KAEvB,IACES,KAAK3B,IAAM2B,KAAKb,WACZ,IAAIyD,UAAU5C,KAAKd,KAAMc,KAAKb,YAC9B,IAAIyD,UAAU5C,KAAKd,KACzB,CAAE,MAAO2D,GAGP,OAFA7C,KAAKM,aAAY,QACjBN,KAAKmB,UAAU0B,EAAGpF,EAEpB,CAGAuC,KAAK3B,IAAI8D,WAAanC,KAAKX,YAE3BW,KAAKO,eArSa,GAuSlBP,KAAK3B,IAAIyE,iBAAiB,OAAQ9C,KAAK+C,SACvC/C,KAAK3B,IAAIyE,iBAAiB,UAAW9C,KAAKgD,YAC1ChD,KAAK3B,IAAIyE,iBAAiB,QAAS9C,KAAKiD,UACxCjD,KAAK3B,IAAIyE,iBAAiB,QAAS9C,KAAKkD,SAC1C,CAEQH,QAAU,KACZ/C,KAAKR,aAAeQ,KAAKT,OAC7BS,KAAKhB,gBAAkB,EACvBgB,KAAKM,aAAY,GACjBN,KAAKK,eAAc,GACnBL,KAAKO,eAjTO,KAoTNyC,WAAc/E,IACpB,GAAI+B,KAAKR,aAAeQ,KAAKT,KAAM,OACnC,IAAI+C,EAAOrE,EAAMqE,KAEjB,GAAoB,iBAATA,EACT,IACEA,EAAOa,KAAKC,MAAMd,EACpB,CAAE,MAEF,CAEFtC,KAAKc,YAAYwB,IAGXW,SAAYhF,IACd+B,KAAKR,aAAeQ,KAAKT,MAC7BS,KAAKmB,UAAUlD,EAAOR,IAGhByF,SAAYjF,IAClB+B,KAAKqD,mBACLrD,KAAK3B,IAAM,KACP2B,KAAKR,aAAeQ,KAAKT,OAC7BS,KAAKK,eAAc,GACnBL,KAAKM,aAAY,GACjBN,KAAKO,eA5US,IA+UTP,KAAKV,mBAAqBU,KAAKpB,gBAAiC,MAAfX,EAAMmD,MAAiBpB,KAAKhB,gBAAkBgB,KAAKlB,gBACvGkB,KAAKsD,uBAID,kBAAAA,GACN,MAAMC,EAAMvD,KAAKT,KACjBS,KAAK2C,uBACL3C,KAAKf,gBAAkBuE,WAAW,KAChCxD,KAAKf,gBAAkB,KAEnBsE,IAAQvD,KAAKT,OACjBS,KAAKhB,kBACLgB,KAAKoC,eACJpC,KAAKnB,mBACV,CAEQ,oBAAA8D,GACuB,OAAzB3C,KAAKf,kBACPwE,aAAazD,KAAKf,iBAClBe,KAAKf,gBAAkB,KAE3B,CAEQ,gBAAAoE,GACDrD,KAAK3B,MAIV2B,KAAK3B,IAAIqF,oBAAoB,OAAQ1D,KAAK+C,SAC1C/C,KAAK3B,IAAIqF,oBAAoB,UAAW1D,KAAKgD,YAC7ChD,KAAK3B,IAAIqF,oBAAoB,QAAS1D,KAAKiD,UAC3CjD,KAAK3B,IAAIqF,oBAAoB,QAAS1D,KAAKkD,UAC7C,CAEQ,cAAApB,GACN9B,KAAK2C,uBACD3C,KAAK3B,MACP2B,KAAKqD,mBAtXK,IAuXNrD,KAAK3B,IAAIwC,YAxXG,IAwXuBb,KAAK3B,IAAIwC,YAC9Cb,KAAK3B,IAAI+B,QAEXJ,KAAK3B,IAAM,MAGT2B,KAAKzB,YACPyB,KAAKK,eAAc,GA7XP,IA+XVL,KAAKrB,aACPqB,KAAKO,eAhYO,EAkYhB,ECzYF,IAAIoD,GAAa,EAEjB,SAASC,EAAY3F,GACnB,MAAM6B,EAAS7B,EAAM6B,OACrB,KAAMA,aAAkB+D,SAAU,OAElC,MAAMC,EAAiBhE,EAAOiE,QAAiB,IAAI1G,EAAOC,qBAC1D,IAAKwG,EAAgB,OAErB,MAAME,EAAOF,EAAeG,aAAa5G,EAAOC,kBAChD,IAAK0G,EAAM,OAQX,MAAME,EAASC,eAAeC,IAAI/G,EAAOE,SAASC,IAC5C6G,EAAYC,SAASC,eAAeP,GACrCE,GAAYG,aAAqBH,IAEtCjG,EAAMuG,iBACLH,EAA2B1C,UAC9B,CCDA,SAAS8C,EAAuB3E,EAAgB9B,GAC9C,IAAI0G,EAAQC,OAAOC,eAAe9E,GAClC,KAAiB,OAAV4E,GAAgB,CACrB,MAAMG,EAAaF,OAAOG,yBAAyBJ,EAAO1G,GAC1D,QAAmBoB,IAAfyF,EACF,MAAiC,mBAAnBA,EAAWT,KAAgD,mBAAnBS,EAAWE,IAEnEL,EAAQC,OAAOC,eAAeF,EAChC,CACA,OAAO,CACT,CAMA,MAAMM,EAAsB,IAAIC,QAEhC,SAASC,EAAoBC,EAAiBnH,EAAcoH,GAC1D,GAAIJ,EAAoBK,IAAIF,GAAU,OACtCH,EAAoBM,IAAIH,GACxB,MAAMI,EAAOJ,EAAmCK,WAAa,UAC7DhD,QAAQC,KACN,6BAA6B8C,wBAA0BvH,MAASoH,kUAIhED,EAEJ,CCjCA,MAAMM,EAAoB,IAAIC,QAG9B,SAASC,EAAiBC,EAAa5H,GACrC,IAAI6H,EAASJ,EAAkBrB,IAAIwB,GAMnC,YALexG,IAAXyG,IACFA,EAAS,IAAIC,IACbL,EAAkBV,IAAIa,EAAIC,IAEvBA,EAAOR,IAAIrH,IAAO6H,EAAOd,IAAI/G,EAAM4H,EAAG3B,aAAajG,IACjD6H,EAAOzB,IAAIpG,EACpB,CAEA,SAAS+H,EAAeH,EAAa5H,EAAcoH,GACnC,OAAVA,EAAgBQ,EAAGI,gBAAgBhI,GAClC4H,EAAGK,aAAajI,EAAMoH,EAC7B,UAMgBc,EAAiBN,EAAa5H,EAAcoH,GAC1D,MAAMe,EAAUR,EAAiBC,EAAI5H,GACrC+H,EAAeH,EAAI5H,OAAgBoB,IAAVgG,EAAsBe,EAAoB,OAAVf,EAAiB,KAAOgB,OAAOhB,GAC1F,UAMgBiB,EAAwBT,EAAa5H,EAAcoH,GACjE,MAAMe,EAAUR,EAAiBC,EAAI5H,GACrC+H,EAAeH,EAAI5H,OAAgBoB,IAAVgG,EAAsBe,EAAUf,EAAQ,GAAK,KACxE,CChDM,MAAOkB,UAAqBC,YAChC3I,oCAAqC,EACrCA,kBAAiC,IAC5BF,EAAc8I,WACjBzI,WAAY,IACPL,EAAc8I,WAAWzI,WAC5B,CAAEC,KAAM,UAAWC,MAAO,yBAA0BC,UAAW,SAC/D,CAAEF,KAAM,OAAQC,MAAO,sBAAuBC,UAAW,UAE3DuI,OAAQ,CACN,CAAEzI,KAAM,MAAO0I,UAAW,OAC1B,CAAE1I,KAAM,YAAa0I,UAAW,aAChC,CAAE1I,KAAM,gBAAiB0I,UAAW,kBACpC,CAAE1I,KAAM,oBAAqB0I,UAAW,sBACxC,CAAE1I,KAAM,gBAAiB0I,UAAW,kBACpC,CAAE1I,KAAM,aAAc0I,UAAW,eACjC,CAAE1I,KAAM,SAAU0I,UAAW,UAC7B,CAAE1I,KAAM,WACR,CAAEA,KAAM,SAEVG,SAAU,CACR,CAAEH,KAAM,WACR,CAAEA,KAAM,eACR,CAAEA,KAAM,WAGZ,6BAAW2I,GAAiC,MAAO,CAAC,MAAQ,CAEpDC,MACAC,UAAoB,EACpBC,0BAA2CpH,QAAQC,UACnDoH,WAAsC,KAKtCC,WAAY,EAEpB,WAAAnH,GACEE,QACAC,KAAK4G,MAAQ,IAAIlJ,EAAcsC,MAC/BA,KAAK+G,WAAa/G,KAAKiH,iBACvBjH,KAAKkH,YAAY,CACf,2BAA6BC,IAAC,CAAQ1G,WAAiB,IAAN0G,IACjD,yBAA6BA,IAAC,CAAQzG,SAAe,IAANyG,IAC/C,eAA6BA,IAAC,CAAQxG,MAAY,MAALwG,KAEjD,CAEA,4BAAIC,GACF,OAAOpH,KAAK8G,yBACd,CAMA,eAAIO,GACF,OAAOrH,KAAK+G,WAAa,IAAI/G,KAAK+G,WAAWO,QAAU,EACzD,CAEQ,cAAAL,GAMN,IACE,GAAoC,mBAAzBjH,KAAKuH,gBAAgC,OAAO,KACvD,MAAMC,EAAYxH,KAAKuH,kBAGvB,OAFAC,EAAUF,OAAOhC,IAAI,aACrBkC,EAAUF,OAAOG,OAAO,aACjBD,CACT,CAAE,MACA,OAAO,IACT,CACF,CAEQ,WAAAN,CAAYQ,GAClB,GAAwB,OAApB1H,KAAK+G,WAAqB,OAC9B,MAAMO,EAAStH,KAAK+G,WAAWO,OAC/B,IAAK,MAAOrJ,EAAO0J,KAAahD,OAAOiD,QAAQF,GAC7C1H,KAAK8C,iBAAiB7E,EAAQ4E,IAC5B,MAAMgF,EAAQ7H,KAAK8H,aAAa,gBAChC,IAAK,MAAO9J,EAAM+J,KAAOpD,OAAOiD,QAAQD,EAAU9E,EAAkB5B,SAAU,CAC5E,IACM8G,EAAMT,EAAOhC,IAAItH,GAAgBsJ,EAAOG,OAAOzJ,EACrD,CAAE,MAA0B,CACxB6J,GAAO7H,KAAKgI,gBAAgB,kBAAkBhK,IAAQ+J,EAC5D,GAGN,CAWA,OAAInG,GACF,OAAO5B,KAAKiE,aAAa,QAAU,EACrC,CAEA,OAAIrC,CAAIwD,GACNc,EAAiBlG,KAAM,MAAOoF,EAChC,CAEA,aAAIrD,GACF,OAAO/B,KAAKiE,aAAa,cAAgB,EAC3C,CAEA,aAAIlC,CAAUqD,GACZc,EAAiBlG,KAAM,YAAaoF,EACtC,CAEA,iBAAIpD,GACF,OAAOhC,KAAK8H,aAAa,iBAC3B,CAEA,iBAAI9F,CAAcoD,GAChBiB,EAAwBrG,KAAM,iBAAkBoF,EAClD,CAEA,qBAAInD,GACF,MAAMgG,EAAOjI,KAAKiE,aAAa,sBACzBiE,EAASD,EAAOE,SAASF,EAAM,IAAM,IAC3C,OAAOG,OAAOC,MAAMH,GAAU,IAAOA,CACvC,CAEA,qBAAIjG,CAAkBmD,GACpBc,EAAiBlG,KAAM,qBAAsBoF,EAC/C,CAEA,iBAAIlD,GACF,MAAM+F,EAAOjI,KAAKiE,aAAa,kBACzBiE,EAASD,EAAOE,SAASF,EAAM,IAAMlJ,IAC3C,OAAOqJ,OAAOC,MAAMH,GAAUnJ,IAAWmJ,CAC3C,CAEA,iBAAIhG,CAAckD,GAChBc,EAAiBlG,KAAM,iBAAkBoF,EAC3C,CAIA,cAAIjD,GACF,MAA4C,gBAArCnC,KAAKiE,aAAa,eAAmC,cAAgB,MAC9E,CAEA,cAAI9B,CAAWiD,GACbc,EAAiBlG,KAAM,cAAeoF,EACxC,CAEA,UAAIkD,GACF,OAAOtI,KAAK8H,aAAa,SAC3B,CAEA,UAAIQ,CAAOlD,GACTiB,EAAwBrG,KAAM,SAAUoF,EAC1C,CAIA,WAAI5E,GACF,OAAOR,KAAK4G,MAAMpG,OACpB,CAEA,aAAIC,GACF,OAAOT,KAAK4G,MAAMnG,SACpB,CAEA,WAAIC,GACF,OAAOV,KAAK4G,MAAMlG,OACpB,CAEA,SAAIC,GACF,OAAOX,KAAK4G,MAAMjG,KACpB,CAEA,aAAIC,GACF,OAAOZ,KAAK4G,MAAMhG,SACpB,CAEA,cAAIC,GACF,OAAOb,KAAK4G,MAAM/F,UACpB,CAIA,WAAI0H,GACF,OAAOvI,KAAK6G,QACd,CAEA,WAAI0B,CAAQnD,KACEA,IAEVpF,KAAK6G,UAAW,EAChB7G,KAAK2B,UACL3B,KAAK6G,UAAW,EAChB7G,KAAKe,cAAc,IAAIC,YAAY,yBAA0B,CAC3DC,QAAQ,EACRC,SAAS,KAGf,CAKA,QAAImB,GACF,OAAO,IACT,CAEA,QAAIA,CAAKC,GACP,GAAIA,QAAqC,OACzC,MAAMkG,EAA0B,iBAATlG,EAAoBA,EAAOa,KAAKsF,UAAUnG,GACjEtC,KAAK4G,MAAMvE,KAAKmG,GAChBxI,KAAKe,cAAc,IAAIC,YAAY,sBAAuB,CACxDC,OAAQ,KACRC,SAAS,IAEb,CAIA,OAAAS,GACE,MAAMI,EAAY/B,KAAK+B,UACnB/B,KAAK+B,UAAU2G,MAAM,KAAKhB,IAAIiB,GAAKA,EAAEC,QAAQC,OAAOC,cACpD1J,EAEJY,KAAK4G,MAAMjF,QAAQ3B,KAAK4B,IAAK,CAC3BG,UAAWA,GAAkC,IAArBA,EAAUgH,OAAehH,EAAU,GAAKA,EAChEC,cAAehC,KAAKgC,cACpBC,kBAAmBjC,KAAKiC,kBACxBC,cAAelC,KAAKkC,cACpBC,WAAYnC,KAAKmC,YAErB,CAEA,WAAA6G,CAAY1G,GACVtC,KAAK4G,MAAMvE,KAAKC,EAClB,CAEA,KAAAlC,CAAMgB,EAAesB,GACnB1C,KAAK4G,MAAMxG,MAAMgB,EAAMsB,EACzB,CAIA,wBAAAuG,CAAyBjL,EAAckL,EAAyBC,GAMjD,QAATnL,GAAkBkL,IAAaC,GAAYnJ,KAAKgH,YAAchH,KAAKsI,QAAUa,GAC/EnJ,KAAK2B,SAET,CAEA,iBAAAyH,IF9MI,SAA4BjE,GAChC,MAAMkE,EAAelE,EAA2DtF,aAAa2G,WACvFC,EAAS4C,GAAa5C,OAC5B,QAAerH,IAAXqH,EAAsB,OAC1B,MAAMxC,EAAgBkB,EAA+DlB,aACrF,IAAK,MAAMqF,KAAS7C,EAAQ,CAC1B,MAAMzI,EAAOsL,EAAMtL,KACb0I,EAAoC,mBAAjBzC,EAA8BA,EAAasF,KAAKpE,EAASnH,EAAKwL,eAAiB,KAExG,GADkB,OAAd9C,GAAsBA,EAAU+C,WAAW,aAAavE,EAAoBC,EAASnH,EAAM0I,IAC1F/B,OAAO+E,UAAUC,eAAeJ,KAAKpE,EAASnH,GAAO,SAC1D,IAAKyG,EAAuBU,EAASnH,GAAO,SAC5C,MAAM4L,EAASzE,EACTC,EAAQwE,EAAO5L,UACd4L,EAAO5L,GACd4L,EAAO5L,GAAQoH,CACjB,CACF,CEkMIyE,CAAkB7J,MAClBA,KAAK8J,MAAMC,QAAU,OHvPnBpG,IACJA,GAAa,EACbW,SAASxB,iBAAiB,QAASc,IG2PjC5D,KAAK8G,0BAA4B9G,KAAK4G,MAAM1G,WACvCF,KAAKsI,QAAUtI,KAAK4B,KACvB5B,KAAK2B,UAEP3B,KAAKgH,WAAY,CACnB,CAEA,oBAAAgD,GACEhK,KAAKgH,WAAY,EAEjBhH,KAAK4G,MAAMzG,SACb,EClSI,IAA2D8J,GCI3D,SAA6BA,EAAkC9F,gBAC9D8F,EAAS7F,IAAI/G,EAAOE,SAASC,KAChCyM,EAASC,OAAO7M,EAAOE,SAASC,GAAI8I,EAExC,CDJE6D,CAAmBF"}
1
+ {"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/websocketCapabilities.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/WebSocket.ts","../src/bootstrapWebSocket.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n ws: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-wstarget\",\n tagNames: {\n ws: \"wcs-ws\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\n/** A misspelt option would otherwise do nothing: `bootstrapWebSocket` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/websocket] bootstrapWebSocket: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","/**\n * websocketCapabilities.ts\n *\n * WebSocket node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。WebSocket は持続的な session / monitor node(1 本の接続を張り続ける)で、\n * 競合する operation を持たないため lane は持たず、error taxonomy(errorInfo)のみを採用する。\n *\n * この node の `_setError` は 4 形態の非 null 入力を受ける(いずれも公開 `error` shape は不変):\n * 1. synthetic な `{ message: \"url is required.\" }`(`.name` 無し)— connect() の引数不備。\n * 2. synthetic な `{ message: \"WebSocket is not connected.\" }`(`.name` 無し)— open 前の send()。\n * 3. caught された生の構築例外 `e`(`new WebSocket()` の同期 throw)。\n * 4. platform の WebSocket `error` Event(`Event`。`.name`/`.message` を持たない)。\n *\n * これらは shape がバラバラで、message からの分類は脆い。そこで呼び出し側が明示的な\n * taxonomy code を discriminator として渡す(storage の `deriveStorageErrorInfo(error, name)`\n * と同じ技法)。derive 側は synthetic / Event / Error を reverse-engineer せず、渡された\n * code で phase / recoverable を決め、message だけを防御的に抽出する。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 安定した websocket error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_WEBSOCKET_ERROR_CODE = {\n /** connect() の `url` 未指定 — 開始前の入力不備。retry では回復しない。 */\n InvalidArgument: \"invalid-argument\",\n /** open 前の send() — 接続が OPEN でない状態での送信。retry では回復しない(先に connect が要る)。 */\n InvalidState: \"invalid-state\",\n /**\n * 接続の確立 / 維持に失敗(`new WebSocket()` の同期例外、または platform の error Event)。\n * WebSocket のエラーは通常一過性で、再接続で回復しうる(recoverable=true)。\n */\n ConnectionError: \"connection-error\",\n} as const;\n\n/**\n * websocket の失敗を serializable な error taxonomy に写す。`code` は呼び出し側が渡す\n * discriminator(公開 `error` shape からは復元しない)。`message` は入力から防御的に抽出し、\n * message を持たない error Event 等では安定した fallback を使う。\n *\n * - `invalid-argument`(url 未指定)は開始前の入力不備 → phase=\"start\" / recoverable=false。\n * - `invalid-state`(open 前 send)は接続状態が満たされない実行時失敗 → phase=\"execute\" /\n * recoverable=false(先に connect() が必要)。\n * - `connection-error`(構築例外 / error Event)は接続の確立 / 維持失敗 → phase=\"execute\" /\n * recoverable=true(再接続で回復しうる)。\n */\nexport function deriveWebSocketErrorInfo(error: unknown, code: string): WcsIoErrorInfo {\n // error は非 null(_setError は error===null を derive 前に分岐する)だが、synthetic /\n // Event / caught 例外 / 生 throw と shape がバラバラなので message は防御的に抽出する。\n // error Event は message を持たないため安定した fallback に落とす。\n const raw = (error as { message?: unknown }).message;\n const message = typeof raw === \"string\" ? raw : \"WebSocket connection error\";\n\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidArgument) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidArgument, phase: \"start\", recoverable: false, message };\n }\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidState) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidState, phase: \"execute\", recoverable: false, message };\n }\n // connection-error(構築例外 / error Event): 接続の確立/維持失敗、再接続で回復しうる。\n return { code: WCS_WEBSOCKET_ERROR_CODE.ConnectionError, phase: \"execute\", recoverable: true, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveWebSocketErrorInfo, WCS_WEBSOCKET_ERROR_CODE } from \"./websocketCapabilities.js\";\n\n// WebSocket readyState values. Hardcoded rather than read from the global\n// WebSocket so the Core does not require WebSocket to exist at module load\n// (referencing `WebSocket.CLOSED` in a field initializer evaluates at class\n// definition time; tests inject a mock). Mirrors SseCore's SSE_CLOSED.\nconst WS_CONNECTING = 0;\nconst WS_OPEN = 1;\nconst WS_CLOSED = 3;\n\nexport interface WebSocketConnectOptions {\n protocols?: string | string[];\n autoReconnect?: boolean;\n reconnectInterval?: number;\n maxReconnects?: number;\n // How incoming binary frames are surfaced on `message`. \"blob\" (the platform\n // default) or \"arraybuffer\" for direct byte processing. Applied to every\n // socket this connection spawns, including auto-reconnects.\n binaryType?: BinaryType;\n // Milliseconds without a message after which an open connection is treated as lost (0 or\n // absent: never). A WebSocket does not notice a connection that died without being closed — a\n // laptop's sleep, a NAT or proxy that dropped it — and stays OPEN; the server must send a message\n // more often than this (a protocol-level ping frame is not seen by the page).\n staleAfter?: number;\n}\n\nexport class WebSocketCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"message\", event: \"wcs-ws:message\", semantics: \"event\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\", semantics: \"state\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\", semantics: \"state\" },\n { name: \"error\", event: \"wcs-ws:error\", semantics: \"state\" },\n // Serializable failure taxonomy (stable code / phase / recoverable), or null.\n // Additive bindable output derived from `error` (invalid-argument / invalid-state\n // / connection-error); the existing `error` property/event are unchanged. Fires\n // wcs-ws:error-info-changed. No lane — WebSocket is a persistent session/monitor\n // node, not a competing operation.\n { name: \"errorInfo\", event: \"wcs-ws:error-info-changed\", semantics: \"state\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"send\" },\n { name: \"close\" },\n ],\n };\n\n private _target: EventTarget;\n private _ws: WebSocket | null = null;\n private _message: any = null;\n private _connected: boolean = false;\n private _loading: boolean = false;\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n private _readyState: number = WS_CLOSED;\n\n // 自動再接続\n private _autoReconnect: boolean = false;\n private _reconnectInterval: number = 3000;\n private _maxReconnects: number = Infinity;\n private _reconnectCount: number = 0;\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private _url: string = \"\";\n private _protocols: string | string[] | undefined = undefined;\n private _binaryType: BinaryType = \"blob\";\n private _intentionalClose: boolean = false;\n // stale-after (ms, 0 = off): the time of the last open / message, and the watchdog's timer\n private _staleAfter: number = 0;\n private _lastActivity: number = 0;\n private _staleTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Generation guard (§3.4): bumped on dispose() and at every connect(). A socket\n // event (open/message/error/close) or a scheduled reconnect that fires after\n // dispose / a superseding connect() carries a stale `gen` and MUST NOT write\n // state onto a torn-down element. A boolean flag is insufficient (dispose→observe\n // would let stale work slip through).\n private _gen = 0;\n // Generation captured when the current socket was opened. The shared socket\n // event handlers compare it against _gen to drop events from a superseded /\n // disposed connection.\n private _socketGen = 0;\n // SSR (§3.8): WebSocket is command-driven with no asynchronous probe to await,\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n /**\n * Whether `[wcs/command-not-ready]` was said in this outage: a `send()` refused because the\n * element is not ready loses what it carried, and `error` alone told only a page that binds it.\n * Said once per outage (docs/v4-direction-2026-10.md, the I/O command policy): the socket opening\n * resets it. Once per element was once per page life — a route puts the same element back on\n * every entry, so the next outage's lost message went unsaid (docs/seam-apps.md, shift-desk).\n */\n private _toldNotReady = false;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). WebSocket connections are command-driven (connect()), so\n // observe() is an idempotent no-op that resolves once ready; the Shell's\n // connectedCallback does not auto-establish a subscription here. dispose()\n // invalidates any in-flight socket / pending reconnect and closes the socket.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.close();\n // The socket's close event is dropped as stale (the generation moved), so the\n // connection's end is published here (timing-and-firing-contract §22): a route the\n // element leaves keeps its nodes — bindings included — for the next entry, and\n // state would keep showing a connection that is gone.\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n }\n\n /**\n * Closes like dispose() — the end is published at once — and says whether a connection was\n * open, opening or about to reopen (auto-reconnect). The Shell uses it when the page may enter\n * the back/forward cache, and reconnects on the way back.\n */\n suspend(): boolean {\n const live = this._ws !== null || this._reconnectTimer !== null;\n this.dispose();\n return live;\n }\n\n get message(): any {\n return this._message;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-ws:error-info-changed`), derived from `error`; the existing `error`\n * property/event are unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n get readyState(): number {\n return this._readyState;\n }\n\n // --- State setters with event dispatch ---\n\n private _setMessage(message: any): void {\n this._message = message;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:message\", {\n detail: message,\n bubbles: true,\n }));\n }\n\n private _setConnected(connected: boolean): void {\n this._connected = connected;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:connected-changed\", {\n detail: connected,\n bubbles: true,\n }));\n }\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // `code` is an explicit taxonomy discriminator (WCS_WEBSOCKET_ERROR_CODE), passed\n // only from the non-null failure call sites. It stays out of the public `error`\n // shape and is used solely to classify errorInfo without reverse-engineering the\n // heterogeneous `error` values (synthetic {message} / caught Error / raw Event).\n // The clear path passes null and no code.\n private _setError(error: any, code?: string): void {\n // Same-value guard (async-io-node-guidelines.md §3.3). `error` is state-ish,\n // so suppressing redundant null→null dispatches (every connect/send start\n // clears a usually-already-null error) avoids a spurious wcs-ws:error per\n // successful operation. Reference identity is sufficient: each failure builds\n // a fresh object (or the platform's own error Event), and the clear path\n // always passes null.\n if (this._error === error) return;\n this._error = error;\n // Keep the additive `errorInfo` taxonomy in sync with `error`: derive from the\n // explicit `code` (or null on clear). Fires before the `error` event so an\n // observer binding both sees the classification first, mirroring the io-node\n // family. Every non-null error carries a code (the clear path is the only\n // caller without one, and it is short-circuited here), so `code!` holds.\n this._commitErrorInfo(error === null ? null : deriveWebSocketErrorInfo(error, code!));\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (which already same-value-guards on the error\n // reference), so errorInfo transitions exactly when error does — no separate\n // guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n\n private _setReadyState(readyState: number): void {\n this._readyState = readyState;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:readystate-changed\", {\n detail: readyState,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n connect(url: string, options: WebSocketConnectOptions = {}): void {\n // never-throw (§3.6): 引数バリデーション失敗は例外ではなく error プロパティに\n // 流し、サニタイズ値(なにもしない)を返す。command-token 経路(set trigger →\n // connect())からの呼び出しが state 更新サイクルを壊さないようにする。\n if (!url) {\n this._setError({ message: \"url is required.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidArgument);\n return;\n }\n\n // 新しい接続を開始するため世代を更新し、進行中のソケット/再接続を無効化する。\n this._gen++;\n\n // 既存の接続をクローズ\n this._intentionalClose = true;\n this._closeInternal();\n\n this._url = url;\n this._protocols = options.protocols;\n this._autoReconnect = options.autoReconnect ?? false;\n this._reconnectInterval = options.reconnectInterval ?? 3000;\n this._maxReconnects = options.maxReconnects ?? Infinity;\n this._binaryType = options.binaryType ?? \"blob\";\n this._staleAfter = options.staleAfter !== undefined && options.staleAfter > 0 ? options.staleAfter : 0;\n this._reconnectCount = 0;\n this._intentionalClose = false;\n\n this._doConnect();\n }\n\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n // never-throw (§3.6): 未接続での送信は例外ではなく error に流す。set send の\n // fire-and-forget 経路で例外が伝播するのを防ぐ。\n if (!this._ws || this._ws.readyState !== WS_OPEN) {\n this._setError({ message: \"WebSocket is not connected.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidState);\n this._warnNotReady();\n return;\n }\n this._ws.send(data);\n }\n\n private _warnNotReady(): void {\n if (this._toldNotReady) return;\n this._toldNotReady = true;\n console.warn(\n \"[@wcstack/websocket] [wcs/command-not-ready] send() was refused: the WebSocket is not connected, so the message is lost. \" +\n \"It goes to `error` too. Send once `connected` is true. (Said once until the WebSocket connects again.)\",\n this._target,\n );\n }\n\n close(code?: number, reason?: string): void {\n this._intentionalClose = true;\n this._clearReconnectTimer();\n this._clearStaleTimer();\n if (this._ws) {\n this._ws.close(code, reason);\n }\n }\n\n // --- Internal ---\n\n private _doConnect(): void {\n this._setLoading(true);\n this._setError(null);\n\n // 接続開始時点の世代を捕捉。dispose()/再 connect() 後に発火した古いソケット\n // イベントはこの gen が stale になり、状態を書き換えない(_onOpen ほかが\n // _socketGen と this._gen を突き合わせて判定する)。\n this._socketGen = this._gen;\n\n try {\n this._ws = this._protocols\n ? new WebSocket(this._url, this._protocols)\n : new WebSocket(this._url);\n } catch (e) {\n this._setLoading(false);\n this._setError(e, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n return;\n }\n\n // Binary frames default to Blob; opt into ArrayBuffer for direct byte access.\n this._ws.binaryType = this._binaryType;\n\n this._setReadyState(WS_CONNECTING);\n\n this._ws.addEventListener(\"open\", this._onOpen);\n this._ws.addEventListener(\"message\", this._onMessage);\n this._ws.addEventListener(\"error\", this._onError);\n this._ws.addEventListener(\"close\", this._onClose);\n }\n\n private _onOpen = (): void => {\n if (this._socketGen !== this._gen) return;\n this._reconnectCount = 0;\n // ready again: a send refused in the next outage is said again\n this._toldNotReady = false;\n this._lastActivity = Date.now();\n this._armStale();\n this._setLoading(false);\n this._setConnected(true);\n this._setReadyState(WS_OPEN);\n };\n\n private _onMessage = (event: MessageEvent): void => {\n if (this._socketGen !== this._gen) return;\n this._lastActivity = Date.now();\n let data = event.data;\n // JSONの自動パース\n if (typeof data === \"string\") {\n try {\n data = JSON.parse(data);\n } catch {\n // テキストのまま\n }\n }\n this._setMessage(data);\n };\n\n private _onError = (event: Event): void => {\n if (this._socketGen !== this._gen) return;\n this._setError(event, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n };\n\n private _onClose = (event: CloseEvent): void => {\n this._removeListeners();\n this._ws = null;\n if (this._socketGen !== this._gen) return;\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n\n // 異常クローズ時の自動再接続(正常終了 1000 は除外)\n if (!this._intentionalClose && this._autoReconnect && event.code !== 1000 && this._reconnectCount < this._maxReconnects) {\n this._scheduleReconnect();\n }\n };\n\n private _scheduleReconnect(): void {\n const gen = this._gen;\n this._clearReconnectTimer();\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null;\n // dispose()/再 connect() でこの再接続が無効化されていたら何もしない。\n if (gen !== this._gen) return;\n this._reconnectCount++;\n this._doConnect();\n }, this._reconnectInterval);\n }\n\n // stale-after の見張り。開いている間、最後の open / メッセージから staleAfter ms 何も届かなければ、\n // 接続は失われたとみなす(docs/seam-apps.md、shift-desk: 閉じられずに死んだ接続 — スリープ・NAT・\n // proxy — に WebSocket は気づかず OPEN のまま、ページは \"connected\" と言い続けた)。タイマーは 1 本\n // だけ持ち、満了のたびに最後の活動からの残りで張り直す(メッセージごとに張り直さない)。\n private _armStale(): void {\n if (this._staleAfter === 0 || this._staleTimer !== null) return;\n this._staleTimer = setTimeout(this._checkStale, this._staleAfter);\n }\n\n private _checkStale = (): void => {\n this._staleTimer = null;\n const ws = this._ws;\n if (ws === null || this._readyState !== WS_OPEN) return;\n const idle = Date.now() - this._lastActivity;\n if (idle < this._staleAfter) {\n this._staleTimer = setTimeout(this._checkStale, this._staleAfter - idle);\n return;\n }\n // 失われたとみなし、異常なクローズと同じに扱う。半開きの TCP では閉じる手順が終わらないので、\n // ソケットはその場で手放し(イベントは外す)、終わりと理由を知らせ、auto-reconnect の規則で\n // つなぎ直す。\n this._removeListeners();\n this._ws = null;\n try {\n ws.close(4000, \"stale\");\n } catch {\n // a socket that cannot be closed any more is gone anyway\n }\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n this._setError({ message: `No message for ${this._staleAfter} ms: the connection is treated as lost.` }, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n if (!this._intentionalClose && this._autoReconnect && this._reconnectCount < this._maxReconnects) {\n this._scheduleReconnect();\n }\n };\n\n private _clearStaleTimer(): void {\n if (this._staleTimer !== null) {\n clearTimeout(this._staleTimer);\n this._staleTimer = null;\n }\n }\n\n private _clearReconnectTimer(): void {\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n }\n\n private _removeListeners(): void {\n if (!this._ws) {\n return;\n }\n\n this._ws.removeEventListener(\"open\", this._onOpen);\n this._ws.removeEventListener(\"message\", this._onMessage);\n this._ws.removeEventListener(\"error\", this._onError);\n this._ws.removeEventListener(\"close\", this._onClose);\n }\n\n private _closeInternal(): void {\n this._clearReconnectTimer();\n this._clearStaleTimer();\n if (this._ws) {\n this._removeListeners();\n if (this._ws.readyState === WS_OPEN || this._ws.readyState === WS_CONNECTING) {\n this._ws.close();\n }\n this._ws = null;\n }\n // 旧接続の状態をリセット(コンストラクタ例外時に stale 状態が残るのを防止)\n if (this._connected) {\n this._setConnected(false);\n }\n if (this._readyState !== WS_CLOSED) {\n this._setReadyState(WS_CLOSED);\n }\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsWebSocket } from \"./components/WebSocket.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const wsId = triggerElement.getAttribute(config.triggerAttribute);\n if (!wsId) return;\n\n // Resolve the registered constructor at call time instead of importing\n // WcsWebSocket as a value. The value import created a components/WebSocket.ts ⇄\n // autoTrigger.ts cycle (WcsWebSocket.connectedCallback() calls\n // registerAutoTrigger()). instanceof against the customElements registry keeps\n // the exact same identity guarantee — only the registered <wcs-ws> class\n // matches — without the import cycle.\n const WsCtor = customElements.get(config.tagNames.ws);\n const wsElement = document.getElementById(wsId);\n if (!WsCtor || !(wsElement instanceof WsCtor)) return;\n\n event.preventDefault();\n (wsElement as WcsWebSocket).connect();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class WcsWebSocket extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...WebSocketCore.wcBindable,\n properties: [\n ...WebSocketCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-ws:trigger-changed\", semantics: \"state\" },\n { name: \"send\", event: \"wcs-ws:send-changed\", semantics: \"state\" },\n ],\n inputs: [\n { name: \"url\", attribute: \"url\" },\n { name: \"protocols\", attribute: \"protocols\" },\n { name: \"autoReconnect\", attribute: \"auto-reconnect\" },\n { name: \"reconnectInterval\", attribute: \"reconnect-interval\" },\n { name: \"maxReconnects\", attribute: \"max-reconnects\" },\n { name: \"binaryType\", attribute: \"binary-type\" },\n { name: \"staleAfter\", attribute: \"stale-after\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n { name: \"send\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"sendMessage\" },\n { name: \"close\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: WebSocketCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n // connectedCallback が接続の判断を終えてから disconnectedCallback までの間だけ true。\n // url 属性の変化による再接続はこの間に限る — upgrade 時は attributeChangedCallback が\n // connectedCallback より先に(isConnected のまま)呼ばれるので、そこで接続すると\n // connectedCallback の接続と合わせて 2 本になる。初回の接続は connectedCallback が持つ。\n private _attached = false;\n // _scheduleConnect のマイクロタスクが待っている間 true\n private _connectPending = false;\n\n constructor() {\n super();\n this._core = new WebSocketCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-ws:connected-changed\": (d) => ({ connected: d === true }),\n \"wcs-ws:loading-changed\": (d) => ({ loading: d === true }),\n \"wcs-ws:error\": (d) => ({ error: d != null }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined (an\n // \"undefined\" url would reconnect to \"undefined\"): `null` removes the\n // attribute (the documented default; an empty url does not connect),\n // `undefined` restores the attribute the element started with (wc-bindable\n // producer guidance P1; React 19 and a direct assignment deliver it,\n // @wcstack/state does not).\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string | null | undefined) {\n reflectAttribute(this, \"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string | null | undefined) {\n reflectAttribute(this, \"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"auto-reconnect\", value);\n }\n\n get reconnectInterval(): number {\n const attr = this.getAttribute(\"reconnect-interval\");\n const parsed = attr ? parseInt(attr, 10) : 3000;\n return Number.isNaN(parsed) ? 3000 : parsed;\n }\n\n set reconnectInterval(value: number | null | undefined) {\n reflectAttribute(this, \"reconnect-interval\", value);\n }\n\n get maxReconnects(): number {\n const attr = this.getAttribute(\"max-reconnects\");\n const parsed = attr ? parseInt(attr, 10) : Infinity;\n return Number.isNaN(parsed) ? Infinity : parsed;\n }\n\n set maxReconnects(value: number | null | undefined) {\n reflectAttribute(this, \"max-reconnects\", value);\n }\n\n // Incoming binary frame representation. Backed by the `binary-type` attribute;\n // any value other than \"arraybuffer\" normalizes to the platform default \"blob\".\n get binaryType(): BinaryType {\n return this.getAttribute(\"binary-type\") === \"arraybuffer\" ? \"arraybuffer\" : \"blob\";\n }\n\n set binaryType(value: string | null | undefined) {\n reflectAttribute(this, \"binary-type\", value);\n }\n\n // 何も届かない時間(ms)がこれを超えた開いている接続を、失われたとみなす(0・未指定・数でない\n // 値は見張らない)。接続オプションの 1 つで、接続するときに読む。\n get staleAfter(): number {\n const parsed = Number(this.getAttribute(\"stale-after\"));\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;\n }\n\n set staleAfter(value: number | null | undefined) {\n reflectAttribute(this, \"stale-after\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get message(): any {\n return this._core.message;\n }\n\n get connected(): boolean {\n return this._core.connected;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n get readyState(): number {\n return this._core.readyState;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.connect();\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-ws:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // `send` is a write-only command surface: assigning transmits immediately.\n // Reading always returns null (no payload is retained) — consistent with the\n // null carried by wcs-ws:send-changed and the documented \"resets to null\".\n get send(): any {\n return null;\n }\n\n set send(data: any) {\n if (data === null || data === undefined) return;\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n this._core.send(payload);\n this.dispatchEvent(new CustomEvent(\"wcs-ws:send-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n // --- Public methods ---\n\n connect(): void {\n // an explicit connect (trigger included) or close takes the pending connect-time decision\n this._connectPending = false;\n const protocols = this.protocols\n ? this.protocols.split(\",\").map(p => p.trim()).filter(Boolean)\n : undefined;\n\n this._core.connect(this.url, {\n protocols: protocols && protocols.length === 1 ? protocols[0] : protocols,\n autoReconnect: this.autoReconnect,\n reconnectInterval: this.reconnectInterval,\n maxReconnects: this.maxReconnects,\n binaryType: this.binaryType,\n staleAfter: this.staleAfter,\n });\n }\n\n sendMessage(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this._core.send(data);\n }\n\n close(code?: number, reason?: string): void {\n this._connectPending = false;\n this._core.close(code, reason);\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // 再接続するのは url が「変わった」ときだけ。同じ値の書き込み(url の setter 自身の\n // setAttribute の後に、属性も書く binder — @wcstack/state 3.x の inputs[].attribute ミラー —\n // が同じ値を書く、など)\n // は何もしない。connectedCallback より前(upgrade 中・DOM の外)の変化は、\n // connectedCallback がそのときの url で 1 回だけ接続する。\n if (name === \"url\" && oldValue !== newValue && this._attached && !this.manual && newValue) {\n this._scheduleConnect();\n }\n }\n\n // 接続の判断はマイクロタスクで、そのときの url / manual で 1 回だけ行う\n // (timing-and-firing-contract §23)。router は遷移で同じノードを入れ直し、新しいルートの\n // params から state が url を書くのはマイクロタスク — その場で接続すると、前の url へ\n // つないでから閉じていた(docs/seam-apps.md、shift-desk)。間の url の変化もここへまとまる。\n private _scheduleConnect(): void {\n if (this._connectPending) return;\n this._connectPending = true;\n queueMicrotask(() => {\n if (!this._connectPending) return; // an explicit command took the decision meanwhile\n this._connectPending = false;\n if (this._attached && !this.manual && this.url) {\n this.connect();\n }\n });\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)。\n // ここで url の setter が走っても _attached はまだ false なので接続しない —\n // 接続は下で、取り込み後の url / manual を見て 1 回だけ行う。\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // observe() は command-driven node では ready を返す no-op(§3.5)。SSR は\n // connectedCallbackPromise を await して初期スナップショットを取れる。\n this._connectedCallbackPromise = this._core.observe();\n this._attached = true;\n window.addEventListener(\"pagehide\", this._onPageHide);\n window.addEventListener(\"pageshow\", this._onPageShow);\n this._scheduleConnect();\n }\n\n // back/forward cache(docs/seam-apps.md、shift-desk): 開いた WebSocket はページを cache から外す\n // (Chromium は復元しない — 理由 \"websocket\")。ページが cache に入りうるとき(pagehide の persisted)\n // 閉じて終わりをその場で知らせ、戻ったとき(pageshow の persisted)、閉じる前に接続していたなら\n // つなぎ直す。ページが自分で閉じると、閉じた知らせは復元の後に届き、pageshow の時点の state は\n // まだ接続中だった。\n private _reopenOnShow = false;\n\n private _onPageHide = (event: Event): void => {\n if (!(event as PageTransitionEvent).persisted) return;\n if (this._core.suspend()) this._reopenOnShow = true;\n };\n\n private _onPageShow = (event: Event): void => {\n if (!(event as PageTransitionEvent).persisted || !this._reopenOnShow) return;\n this._reopenOnShow = false;\n // (the listeners live only while the element is connected)\n if (this.url) this.connect();\n };\n\n disconnectedCallback(): void {\n this._attached = false;\n this._reopenOnShow = false;\n window.removeEventListener(\"pagehide\", this._onPageHide);\n window.removeEventListener(\"pageshow\", this._onPageShow);\n // dispose() が _gen を bump して進行中のソケット/再接続を無効化し、close() する。\n this._core.dispose();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapWebSocket(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.ws)) {\n registry.define(config.tagNames.ws, WcsWebSocket);\n }\n}\n"],"names":["config","triggerAttribute","tagNames","ws","WCS_WEBSOCKET_ERROR_CODE","WebSocketCore","EventTarget","static","protocol","version","properties","name","event","semantics","commands","_target","_ws","_message","_connected","_loading","_error","_errorInfo","_readyState","_autoReconnect","_reconnectInterval","_maxReconnects","Infinity","_reconnectCount","_reconnectTimer","_url","_protocols","undefined","_binaryType","_intentionalClose","_staleAfter","_lastActivity","_staleTimer","_gen","_socketGen","_ready","Promise","resolve","_toldNotReady","constructor","target","super","this","ready","observe","dispose","close","_setConnected","_setLoading","_setReadyState","suspend","live","message","connected","loading","error","errorInfo","readyState","_setMessage","dispatchEvent","CustomEvent","detail","bubbles","_setError","code","_commitErrorInfo","raw","phase","recoverable","deriveWebSocketErrorInfo","info","connect","url","options","_closeInternal","protocols","autoReconnect","reconnectInterval","maxReconnects","binaryType","staleAfter","_doConnect","send","data","_warnNotReady","console","warn","reason","_clearReconnectTimer","_clearStaleTimer","WebSocket","e","addEventListener","_onOpen","_onMessage","_onError","_onClose","Date","now","_armStale","JSON","parse","_removeListeners","_scheduleReconnect","gen","setTimeout","_checkStale","idle","clearTimeout","removeEventListener","registered","handleClick","Element","triggerElement","closest","wsId","getAttribute","WsCtor","customElements","get","wsElement","document","getElementById","preventDefault","hasAccessorOnPrototype","proto","Object","getPrototypeOf","descriptor","getOwnPropertyDescriptor","set","toldObjectAttribute","WeakSet","warnObjectAttribute","element","value","has","add","tag","localName","initialAttributes","WeakMap","initialAttribute","el","byName","Map","writeAttribute","removeAttribute","setAttribute","reflectAttribute","initial","String","reflectBooleanAttribute","WcsWebSocket","HTMLElement","wcBindable","inputs","attribute","observedAttributes","_core","_trigger","_connectedCallbackPromise","_internals","_attached","_connectPending","_initInternals","_wireStates","d","connectedCallbackPromise","debugStates","states","attachInternals","internals","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","attr","parsed","parseInt","Number","isNaN","isFinite","manual","trigger","payload","stringify","split","p","trim","filter","Boolean","length","sendMessage","attributeChangedCallback","oldValue","newValue","_scheduleConnect","queueMicrotask","connectedCallback","declaration","input","call","toLowerCase","startsWith","prototype","hasOwnProperty","record","upgradeProperties","style","display","window","_onPageHide","_onPageShow","_reopenOnShow","persisted","disconnectedCallback","registry","define","registerComponents"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -110,6 +110,7 @@ interface WcsWsCoreCommands {
110
110
  reconnectInterval?: number;
111
111
  maxReconnects?: number;
112
112
  binaryType?: BinaryType;
113
+ staleAfter?: number;
113
114
  }): void;
114
115
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
115
116
  close(code?: number, reason?: string): void;
@@ -130,6 +131,7 @@ interface WebSocketConnectOptions {
130
131
  reconnectInterval?: number;
131
132
  maxReconnects?: number;
132
133
  binaryType?: BinaryType;
134
+ staleAfter?: number;
133
135
  }
134
136
  declare class WebSocketCore extends EventTarget {
135
137
  static wcBindable: IWcBindable;
@@ -150,19 +152,30 @@ declare class WebSocketCore extends EventTarget {
150
152
  private _protocols;
151
153
  private _binaryType;
152
154
  private _intentionalClose;
155
+ private _staleAfter;
156
+ private _lastActivity;
157
+ private _staleTimer;
153
158
  private _gen;
154
159
  private _socketGen;
155
160
  private _ready;
156
161
  /**
157
- * Whether `[wcs/command-not-ready]` was said for this element: a `send()` refused because the
162
+ * Whether `[wcs/command-not-ready]` was said in this outage: a `send()` refused because the
158
163
  * element is not ready loses what it carried, and `error` alone told only a page that binds it.
159
- * Said once per element (docs/v4-direction-2026-10.md, the I/O command policy).
164
+ * Said once per outage (docs/v4-direction-2026-10.md, the I/O command policy): the socket opening
165
+ * resets it. Once per element was once per page life — a route puts the same element back on
166
+ * every entry, so the next outage's lost message went unsaid (docs/seam-apps.md, shift-desk).
160
167
  */
161
168
  private _toldNotReady;
162
169
  constructor(target?: EventTarget);
163
170
  get ready(): Promise<void>;
164
171
  observe(): Promise<void>;
165
172
  dispose(): void;
173
+ /**
174
+ * Closes like dispose() — the end is published at once — and says whether a connection was
175
+ * open, opening or about to reopen (auto-reconnect). The Shell uses it when the page may enter
176
+ * the back/forward cache, and reconnects on the way back.
177
+ */
178
+ suspend(): boolean;
166
179
  get message(): any;
167
180
  get connected(): boolean;
168
181
  get loading(): boolean;
@@ -191,6 +204,9 @@ declare class WebSocketCore extends EventTarget {
191
204
  private _onError;
192
205
  private _onClose;
193
206
  private _scheduleReconnect;
207
+ private _armStale;
208
+ private _checkStale;
209
+ private _clearStaleTimer;
194
210
  private _clearReconnectTimer;
195
211
  private _removeListeners;
196
212
  private _closeInternal;
@@ -205,6 +221,7 @@ declare class WcsWebSocket extends HTMLElement {
205
221
  private _connectedCallbackPromise;
206
222
  private _internals;
207
223
  private _attached;
224
+ private _connectPending;
208
225
  constructor();
209
226
  get connectedCallbackPromise(): Promise<void>;
210
227
  get debugStates(): string[];
@@ -222,6 +239,8 @@ declare class WcsWebSocket extends HTMLElement {
222
239
  set maxReconnects(value: number | null | undefined);
223
240
  get binaryType(): BinaryType;
224
241
  set binaryType(value: string | null | undefined);
242
+ get staleAfter(): number;
243
+ set staleAfter(value: number | null | undefined);
225
244
  get manual(): boolean;
226
245
  set manual(value: boolean | null | undefined);
227
246
  get message(): any;
@@ -238,7 +257,11 @@ declare class WcsWebSocket extends HTMLElement {
238
257
  sendMessage(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
239
258
  close(code?: number, reason?: string): void;
240
259
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
260
+ private _scheduleConnect;
241
261
  connectedCallback(): void;
262
+ private _reopenOnShow;
263
+ private _onPageHide;
264
+ private _onPageShow;
242
265
  disconnectedCallback(): void;
243
266
  }
244
267
 
package/dist/index.esm.js CHANGED
@@ -171,6 +171,10 @@ class WebSocketCore extends EventTarget {
171
171
  _protocols = undefined;
172
172
  _binaryType = "blob";
173
173
  _intentionalClose = false;
174
+ // stale-after (ms, 0 = off): the time of the last open / message, and the watchdog's timer
175
+ _staleAfter = 0;
176
+ _lastActivity = 0;
177
+ _staleTimer = null;
174
178
  // Generation guard (§3.4): bumped on dispose() and at every connect(). A socket
175
179
  // event (open/message/error/close) or a scheduled reconnect that fires after
176
180
  // dispose / a superseding connect() carries a stale `gen` and MUST NOT write
@@ -185,9 +189,11 @@ class WebSocketCore extends EventTarget {
185
189
  // so readiness is immediate.
186
190
  _ready = Promise.resolve();
187
191
  /**
188
- * Whether `[wcs/command-not-ready]` was said for this element: a `send()` refused because the
192
+ * Whether `[wcs/command-not-ready]` was said in this outage: a `send()` refused because the
189
193
  * element is not ready loses what it carried, and `error` alone told only a page that binds it.
190
- * Said once per element (docs/v4-direction-2026-10.md, the I/O command policy).
194
+ * Said once per outage (docs/v4-direction-2026-10.md, the I/O command policy): the socket opening
195
+ * resets it. Once per element was once per page life — a route puts the same element back on
196
+ * every entry, so the next outage's lost message went unsaid (docs/seam-apps.md, shift-desk).
191
197
  */
192
198
  _toldNotReady = false;
193
199
  constructor(target) {
@@ -215,6 +221,16 @@ class WebSocketCore extends EventTarget {
215
221
  this._setLoading(false);
216
222
  this._setReadyState(WS_CLOSED);
217
223
  }
224
+ /**
225
+ * Closes like dispose() — the end is published at once — and says whether a connection was
226
+ * open, opening or about to reopen (auto-reconnect). The Shell uses it when the page may enter
227
+ * the back/forward cache, and reconnects on the way back.
228
+ */
229
+ suspend() {
230
+ const live = this._ws !== null || this._reconnectTimer !== null;
231
+ this.dispose();
232
+ return live;
233
+ }
218
234
  get message() {
219
235
  return this._message;
220
236
  }
@@ -324,6 +340,7 @@ class WebSocketCore extends EventTarget {
324
340
  this._reconnectInterval = options.reconnectInterval ?? 3000;
325
341
  this._maxReconnects = options.maxReconnects ?? Infinity;
326
342
  this._binaryType = options.binaryType ?? "blob";
343
+ this._staleAfter = options.staleAfter !== undefined && options.staleAfter > 0 ? options.staleAfter : 0;
327
344
  this._reconnectCount = 0;
328
345
  this._intentionalClose = false;
329
346
  this._doConnect();
@@ -343,11 +360,12 @@ class WebSocketCore extends EventTarget {
343
360
  return;
344
361
  this._toldNotReady = true;
345
362
  console.warn("[@wcstack/websocket] [wcs/command-not-ready] send() was refused: the WebSocket is not connected, so the message is lost. " +
346
- "It goes to `error` too. Send once `connected` is true. (Said once per element.)", this._target);
363
+ "It goes to `error` too. Send once `connected` is true. (Said once until the WebSocket connects again.)", this._target);
347
364
  }
348
365
  close(code, reason) {
349
366
  this._intentionalClose = true;
350
367
  this._clearReconnectTimer();
368
+ this._clearStaleTimer();
351
369
  if (this._ws) {
352
370
  this._ws.close(code, reason);
353
371
  }
@@ -382,6 +400,10 @@ class WebSocketCore extends EventTarget {
382
400
  if (this._socketGen !== this._gen)
383
401
  return;
384
402
  this._reconnectCount = 0;
403
+ // ready again: a send refused in the next outage is said again
404
+ this._toldNotReady = false;
405
+ this._lastActivity = Date.now();
406
+ this._armStale();
385
407
  this._setLoading(false);
386
408
  this._setConnected(true);
387
409
  this._setReadyState(WS_OPEN);
@@ -389,6 +411,7 @@ class WebSocketCore extends EventTarget {
389
411
  _onMessage = (event) => {
390
412
  if (this._socketGen !== this._gen)
391
413
  return;
414
+ this._lastActivity = Date.now();
392
415
  let data = event.data;
393
416
  // JSONの自動パース
394
417
  if (typeof data === "string") {
@@ -431,6 +454,50 @@ class WebSocketCore extends EventTarget {
431
454
  this._doConnect();
432
455
  }, this._reconnectInterval);
433
456
  }
457
+ // stale-after の見張り。開いている間、最後の open / メッセージから staleAfter ms 何も届かなければ、
458
+ // 接続は失われたとみなす(docs/seam-apps.md、shift-desk: 閉じられずに死んだ接続 — スリープ・NAT・
459
+ // proxy — に WebSocket は気づかず OPEN のまま、ページは "connected" と言い続けた)。タイマーは 1 本
460
+ // だけ持ち、満了のたびに最後の活動からの残りで張り直す(メッセージごとに張り直さない)。
461
+ _armStale() {
462
+ if (this._staleAfter === 0 || this._staleTimer !== null)
463
+ return;
464
+ this._staleTimer = setTimeout(this._checkStale, this._staleAfter);
465
+ }
466
+ _checkStale = () => {
467
+ this._staleTimer = null;
468
+ const ws = this._ws;
469
+ if (ws === null || this._readyState !== WS_OPEN)
470
+ return;
471
+ const idle = Date.now() - this._lastActivity;
472
+ if (idle < this._staleAfter) {
473
+ this._staleTimer = setTimeout(this._checkStale, this._staleAfter - idle);
474
+ return;
475
+ }
476
+ // 失われたとみなし、異常なクローズと同じに扱う。半開きの TCP では閉じる手順が終わらないので、
477
+ // ソケットはその場で手放し(イベントは外す)、終わりと理由を知らせ、auto-reconnect の規則で
478
+ // つなぎ直す。
479
+ this._removeListeners();
480
+ this._ws = null;
481
+ try {
482
+ ws.close(4000, "stale");
483
+ }
484
+ catch {
485
+ // a socket that cannot be closed any more is gone anyway
486
+ }
487
+ this._setConnected(false);
488
+ this._setLoading(false);
489
+ this._setReadyState(WS_CLOSED);
490
+ this._setError({ message: `No message for ${this._staleAfter} ms: the connection is treated as lost.` }, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);
491
+ if (!this._intentionalClose && this._autoReconnect && this._reconnectCount < this._maxReconnects) {
492
+ this._scheduleReconnect();
493
+ }
494
+ };
495
+ _clearStaleTimer() {
496
+ if (this._staleTimer !== null) {
497
+ clearTimeout(this._staleTimer);
498
+ this._staleTimer = null;
499
+ }
500
+ }
434
501
  _clearReconnectTimer() {
435
502
  if (this._reconnectTimer !== null) {
436
503
  clearTimeout(this._reconnectTimer);
@@ -448,6 +515,7 @@ class WebSocketCore extends EventTarget {
448
515
  }
449
516
  _closeInternal() {
450
517
  this._clearReconnectTimer();
518
+ this._clearStaleTimer();
451
519
  if (this._ws) {
452
520
  this._removeListeners();
453
521
  if (this._ws.readyState === WS_OPEN || this._ws.readyState === WS_CONNECTING) {
@@ -629,6 +697,7 @@ class WcsWebSocket extends HTMLElement {
629
697
  { name: "reconnectInterval", attribute: "reconnect-interval" },
630
698
  { name: "maxReconnects", attribute: "max-reconnects" },
631
699
  { name: "binaryType", attribute: "binary-type" },
700
+ { name: "staleAfter", attribute: "stale-after" },
632
701
  { name: "manual", attribute: "manual" },
633
702
  { name: "trigger" },
634
703
  { name: "send" },
@@ -649,6 +718,8 @@ class WcsWebSocket extends HTMLElement {
649
718
  // connectedCallback より先に(isConnected のまま)呼ばれるので、そこで接続すると
650
719
  // connectedCallback の接続と合わせて 2 本になる。初回の接続は connectedCallback が持つ。
651
720
  _attached = false;
721
+ // _scheduleConnect のマイクロタスクが待っている間 true
722
+ _connectPending = false;
652
723
  constructor() {
653
724
  super();
654
725
  this._core = new WebSocketCore(this);
@@ -760,6 +831,15 @@ class WcsWebSocket extends HTMLElement {
760
831
  set binaryType(value) {
761
832
  reflectAttribute(this, "binary-type", value);
762
833
  }
834
+ // 何も届かない時間(ms)がこれを超えた開いている接続を、失われたとみなす(0・未指定・数でない
835
+ // 値は見張らない)。接続オプションの 1 つで、接続するときに読む。
836
+ get staleAfter() {
837
+ const parsed = Number(this.getAttribute("stale-after"));
838
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
839
+ }
840
+ set staleAfter(value) {
841
+ reflectAttribute(this, "stale-after", value);
842
+ }
763
843
  get manual() {
764
844
  return this.hasAttribute("manual");
765
845
  }
@@ -819,6 +899,8 @@ class WcsWebSocket extends HTMLElement {
819
899
  }
820
900
  // --- Public methods ---
821
901
  connect() {
902
+ // an explicit connect (trigger included) or close takes the pending connect-time decision
903
+ this._connectPending = false;
822
904
  const protocols = this.protocols
823
905
  ? this.protocols.split(",").map(p => p.trim()).filter(Boolean)
824
906
  : undefined;
@@ -828,12 +910,14 @@ class WcsWebSocket extends HTMLElement {
828
910
  reconnectInterval: this.reconnectInterval,
829
911
  maxReconnects: this.maxReconnects,
830
912
  binaryType: this.binaryType,
913
+ staleAfter: this.staleAfter,
831
914
  });
832
915
  }
833
916
  sendMessage(data) {
834
917
  this._core.send(data);
835
918
  }
836
919
  close(code, reason) {
920
+ this._connectPending = false;
837
921
  this._core.close(code, reason);
838
922
  }
839
923
  // --- Lifecycle ---
@@ -844,9 +928,26 @@ class WcsWebSocket extends HTMLElement {
844
928
  // は何もしない。connectedCallback より前(upgrade 中・DOM の外)の変化は、
845
929
  // connectedCallback がそのときの url で 1 回だけ接続する。
846
930
  if (name === "url" && oldValue !== newValue && this._attached && !this.manual && newValue) {
847
- this.connect();
931
+ this._scheduleConnect();
848
932
  }
849
933
  }
934
+ // 接続の判断はマイクロタスクで、そのときの url / manual で 1 回だけ行う
935
+ // (timing-and-firing-contract §23)。router は遷移で同じノードを入れ直し、新しいルートの
936
+ // params から state が url を書くのはマイクロタスク — その場で接続すると、前の url へ
937
+ // つないでから閉じていた(docs/seam-apps.md、shift-desk)。間の url の変化もここへまとまる。
938
+ _scheduleConnect() {
939
+ if (this._connectPending)
940
+ return;
941
+ this._connectPending = true;
942
+ queueMicrotask(() => {
943
+ if (!this._connectPending)
944
+ return; // an explicit command took the decision meanwhile
945
+ this._connectPending = false;
946
+ if (this._attached && !this.manual && this.url) {
947
+ this.connect();
948
+ }
949
+ });
950
+ }
850
951
  connectedCallback() {
851
952
  // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)。
852
953
  // ここで url の setter が走っても _attached はまだ false なので接続しない —
@@ -859,13 +960,36 @@ class WcsWebSocket extends HTMLElement {
859
960
  // observe() は command-driven node では ready を返す no-op(§3.5)。SSR は
860
961
  // connectedCallbackPromise を await して初期スナップショットを取れる。
861
962
  this._connectedCallbackPromise = this._core.observe();
862
- if (!this.manual && this.url) {
863
- this.connect();
864
- }
865
963
  this._attached = true;
866
- }
964
+ window.addEventListener("pagehide", this._onPageHide);
965
+ window.addEventListener("pageshow", this._onPageShow);
966
+ this._scheduleConnect();
967
+ }
968
+ // back/forward cache(docs/seam-apps.md、shift-desk): 開いた WebSocket はページを cache から外す
969
+ // (Chromium は復元しない — 理由 "websocket")。ページが cache に入りうるとき(pagehide の persisted)
970
+ // 閉じて終わりをその場で知らせ、戻ったとき(pageshow の persisted)、閉じる前に接続していたなら
971
+ // つなぎ直す。ページが自分で閉じると、閉じた知らせは復元の後に届き、pageshow の時点の state は
972
+ // まだ接続中だった。
973
+ _reopenOnShow = false;
974
+ _onPageHide = (event) => {
975
+ if (!event.persisted)
976
+ return;
977
+ if (this._core.suspend())
978
+ this._reopenOnShow = true;
979
+ };
980
+ _onPageShow = (event) => {
981
+ if (!event.persisted || !this._reopenOnShow)
982
+ return;
983
+ this._reopenOnShow = false;
984
+ // (the listeners live only while the element is connected)
985
+ if (this.url)
986
+ this.connect();
987
+ };
867
988
  disconnectedCallback() {
868
989
  this._attached = false;
990
+ this._reopenOnShow = false;
991
+ window.removeEventListener("pagehide", this._onPageHide);
992
+ window.removeEventListener("pageshow", this._onPageShow);
869
993
  // dispose() が _gen を bump して進行中のソケット/再接続を無効化し、close() する。
870
994
  this._core.dispose();
871
995
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/websocketCapabilities.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/WebSocket.ts","../src/registerComponents.ts","../src/bootstrapWebSocket.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n ws: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-wstarget\",\n tagNames: {\n ws: \"wcs-ws\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\n/** A misspelt option would otherwise do nothing: `bootstrapWebSocket` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/websocket] bootstrapWebSocket: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","/**\n * websocketCapabilities.ts\n *\n * WebSocket node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。WebSocket は持続的な session / monitor node(1 本の接続を張り続ける)で、\n * 競合する operation を持たないため lane は持たず、error taxonomy(errorInfo)のみを採用する。\n *\n * この node の `_setError` は 4 形態の非 null 入力を受ける(いずれも公開 `error` shape は不変):\n * 1. synthetic な `{ message: \"url is required.\" }`(`.name` 無し)— connect() の引数不備。\n * 2. synthetic な `{ message: \"WebSocket is not connected.\" }`(`.name` 無し)— open 前の send()。\n * 3. caught された生の構築例外 `e`(`new WebSocket()` の同期 throw)。\n * 4. platform の WebSocket `error` Event(`Event`。`.name`/`.message` を持たない)。\n *\n * これらは shape がバラバラで、message からの分類は脆い。そこで呼び出し側が明示的な\n * taxonomy code を discriminator として渡す(storage の `deriveStorageErrorInfo(error, name)`\n * と同じ技法)。derive 側は synthetic / Event / Error を reverse-engineer せず、渡された\n * code で phase / recoverable を決め、message だけを防御的に抽出する。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 安定した websocket error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_WEBSOCKET_ERROR_CODE = {\n /** connect() の `url` 未指定 — 開始前の入力不備。retry では回復しない。 */\n InvalidArgument: \"invalid-argument\",\n /** open 前の send() — 接続が OPEN でない状態での送信。retry では回復しない(先に connect が要る)。 */\n InvalidState: \"invalid-state\",\n /**\n * 接続の確立 / 維持に失敗(`new WebSocket()` の同期例外、または platform の error Event)。\n * WebSocket のエラーは通常一過性で、再接続で回復しうる(recoverable=true)。\n */\n ConnectionError: \"connection-error\",\n} as const;\n\n/**\n * websocket の失敗を serializable な error taxonomy に写す。`code` は呼び出し側が渡す\n * discriminator(公開 `error` shape からは復元しない)。`message` は入力から防御的に抽出し、\n * message を持たない error Event 等では安定した fallback を使う。\n *\n * - `invalid-argument`(url 未指定)は開始前の入力不備 → phase=\"start\" / recoverable=false。\n * - `invalid-state`(open 前 send)は接続状態が満たされない実行時失敗 → phase=\"execute\" /\n * recoverable=false(先に connect() が必要)。\n * - `connection-error`(構築例外 / error Event)は接続の確立 / 維持失敗 → phase=\"execute\" /\n * recoverable=true(再接続で回復しうる)。\n */\nexport function deriveWebSocketErrorInfo(error: unknown, code: string): WcsIoErrorInfo {\n // error は非 null(_setError は error===null を derive 前に分岐する)だが、synthetic /\n // Event / caught 例外 / 生 throw と shape がバラバラなので message は防御的に抽出する。\n // error Event は message を持たないため安定した fallback に落とす。\n const raw = (error as { message?: unknown }).message;\n const message = typeof raw === \"string\" ? raw : \"WebSocket connection error\";\n\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidArgument) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidArgument, phase: \"start\", recoverable: false, message };\n }\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidState) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidState, phase: \"execute\", recoverable: false, message };\n }\n // connection-error(構築例外 / error Event): 接続の確立/維持失敗、再接続で回復しうる。\n return { code: WCS_WEBSOCKET_ERROR_CODE.ConnectionError, phase: \"execute\", recoverable: true, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveWebSocketErrorInfo, WCS_WEBSOCKET_ERROR_CODE } from \"./websocketCapabilities.js\";\n\n// WebSocket readyState values. Hardcoded rather than read from the global\n// WebSocket so the Core does not require WebSocket to exist at module load\n// (referencing `WebSocket.CLOSED` in a field initializer evaluates at class\n// definition time; tests inject a mock). Mirrors SseCore's SSE_CLOSED.\nconst WS_CONNECTING = 0;\nconst WS_OPEN = 1;\nconst WS_CLOSED = 3;\n\nexport interface WebSocketConnectOptions {\n protocols?: string | string[];\n autoReconnect?: boolean;\n reconnectInterval?: number;\n maxReconnects?: number;\n // How incoming binary frames are surfaced on `message`. \"blob\" (the platform\n // default) or \"arraybuffer\" for direct byte processing. Applied to every\n // socket this connection spawns, including auto-reconnects.\n binaryType?: BinaryType;\n}\n\nexport class WebSocketCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"message\", event: \"wcs-ws:message\", semantics: \"event\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\", semantics: \"state\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\", semantics: \"state\" },\n { name: \"error\", event: \"wcs-ws:error\", semantics: \"state\" },\n // Serializable failure taxonomy (stable code / phase / recoverable), or null.\n // Additive bindable output derived from `error` (invalid-argument / invalid-state\n // / connection-error); the existing `error` property/event are unchanged. Fires\n // wcs-ws:error-info-changed. No lane — WebSocket is a persistent session/monitor\n // node, not a competing operation.\n { name: \"errorInfo\", event: \"wcs-ws:error-info-changed\", semantics: \"state\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"send\" },\n { name: \"close\" },\n ],\n };\n\n private _target: EventTarget;\n private _ws: WebSocket | null = null;\n private _message: any = null;\n private _connected: boolean = false;\n private _loading: boolean = false;\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n private _readyState: number = WS_CLOSED;\n\n // 自動再接続\n private _autoReconnect: boolean = false;\n private _reconnectInterval: number = 3000;\n private _maxReconnects: number = Infinity;\n private _reconnectCount: number = 0;\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private _url: string = \"\";\n private _protocols: string | string[] | undefined = undefined;\n private _binaryType: BinaryType = \"blob\";\n private _intentionalClose: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() and at every connect(). A socket\n // event (open/message/error/close) or a scheduled reconnect that fires after\n // dispose / a superseding connect() carries a stale `gen` and MUST NOT write\n // state onto a torn-down element. A boolean flag is insufficient (dispose→observe\n // would let stale work slip through).\n private _gen = 0;\n // Generation captured when the current socket was opened. The shared socket\n // event handlers compare it against _gen to drop events from a superseded /\n // disposed connection.\n private _socketGen = 0;\n // SSR (§3.8): WebSocket is command-driven with no asynchronous probe to await,\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n /**\n * Whether `[wcs/command-not-ready]` was said for this element: a `send()` refused because the\n * element is not ready loses what it carried, and `error` alone told only a page that binds it.\n * Said once per element (docs/v4-direction-2026-10.md, the I/O command policy).\n */\n private _toldNotReady = false;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). WebSocket connections are command-driven (connect()), so\n // observe() is an idempotent no-op that resolves once ready; the Shell's\n // connectedCallback does not auto-establish a subscription here. dispose()\n // invalidates any in-flight socket / pending reconnect and closes the socket.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.close();\n // The socket's close event is dropped as stale (the generation moved), so the\n // connection's end is published here (timing-and-firing-contract §22): a route the\n // element leaves keeps its nodes — bindings included — for the next entry, and\n // state would keep showing a connection that is gone.\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n }\n\n get message(): any {\n return this._message;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-ws:error-info-changed`), derived from `error`; the existing `error`\n * property/event are unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n get readyState(): number {\n return this._readyState;\n }\n\n // --- State setters with event dispatch ---\n\n private _setMessage(message: any): void {\n this._message = message;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:message\", {\n detail: message,\n bubbles: true,\n }));\n }\n\n private _setConnected(connected: boolean): void {\n this._connected = connected;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:connected-changed\", {\n detail: connected,\n bubbles: true,\n }));\n }\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // `code` is an explicit taxonomy discriminator (WCS_WEBSOCKET_ERROR_CODE), passed\n // only from the non-null failure call sites. It stays out of the public `error`\n // shape and is used solely to classify errorInfo without reverse-engineering the\n // heterogeneous `error` values (synthetic {message} / caught Error / raw Event).\n // The clear path passes null and no code.\n private _setError(error: any, code?: string): void {\n // Same-value guard (async-io-node-guidelines.md §3.3). `error` is state-ish,\n // so suppressing redundant null→null dispatches (every connect/send start\n // clears a usually-already-null error) avoids a spurious wcs-ws:error per\n // successful operation. Reference identity is sufficient: each failure builds\n // a fresh object (or the platform's own error Event), and the clear path\n // always passes null.\n if (this._error === error) return;\n this._error = error;\n // Keep the additive `errorInfo` taxonomy in sync with `error`: derive from the\n // explicit `code` (or null on clear). Fires before the `error` event so an\n // observer binding both sees the classification first, mirroring the io-node\n // family. Every non-null error carries a code (the clear path is the only\n // caller without one, and it is short-circuited here), so `code!` holds.\n this._commitErrorInfo(error === null ? null : deriveWebSocketErrorInfo(error, code!));\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (which already same-value-guards on the error\n // reference), so errorInfo transitions exactly when error does — no separate\n // guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n\n private _setReadyState(readyState: number): void {\n this._readyState = readyState;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:readystate-changed\", {\n detail: readyState,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n connect(url: string, options: WebSocketConnectOptions = {}): void {\n // never-throw (§3.6): 引数バリデーション失敗は例外ではなく error プロパティに\n // 流し、サニタイズ値(なにもしない)を返す。command-token 経路(set trigger →\n // connect())からの呼び出しが state 更新サイクルを壊さないようにする。\n if (!url) {\n this._setError({ message: \"url is required.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidArgument);\n return;\n }\n\n // 新しい接続を開始するため世代を更新し、進行中のソケット/再接続を無効化する。\n this._gen++;\n\n // 既存の接続をクローズ\n this._intentionalClose = true;\n this._closeInternal();\n\n this._url = url;\n this._protocols = options.protocols;\n this._autoReconnect = options.autoReconnect ?? false;\n this._reconnectInterval = options.reconnectInterval ?? 3000;\n this._maxReconnects = options.maxReconnects ?? Infinity;\n this._binaryType = options.binaryType ?? \"blob\";\n this._reconnectCount = 0;\n this._intentionalClose = false;\n\n this._doConnect();\n }\n\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n // never-throw (§3.6): 未接続での送信は例外ではなく error に流す。set send の\n // fire-and-forget 経路で例外が伝播するのを防ぐ。\n if (!this._ws || this._ws.readyState !== WS_OPEN) {\n this._setError({ message: \"WebSocket is not connected.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidState);\n this._warnNotReady();\n return;\n }\n this._ws.send(data);\n }\n\n private _warnNotReady(): void {\n if (this._toldNotReady) return;\n this._toldNotReady = true;\n console.warn(\n \"[@wcstack/websocket] [wcs/command-not-ready] send() was refused: the WebSocket is not connected, so the message is lost. \" +\n \"It goes to `error` too. Send once `connected` is true. (Said once per element.)\",\n this._target,\n );\n }\n\n close(code?: number, reason?: string): void {\n this._intentionalClose = true;\n this._clearReconnectTimer();\n if (this._ws) {\n this._ws.close(code, reason);\n }\n }\n\n // --- Internal ---\n\n private _doConnect(): void {\n this._setLoading(true);\n this._setError(null);\n\n // 接続開始時点の世代を捕捉。dispose()/再 connect() 後に発火した古いソケット\n // イベントはこの gen が stale になり、状態を書き換えない(_onOpen ほかが\n // _socketGen と this._gen を突き合わせて判定する)。\n this._socketGen = this._gen;\n\n try {\n this._ws = this._protocols\n ? new WebSocket(this._url, this._protocols)\n : new WebSocket(this._url);\n } catch (e) {\n this._setLoading(false);\n this._setError(e, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n return;\n }\n\n // Binary frames default to Blob; opt into ArrayBuffer for direct byte access.\n this._ws.binaryType = this._binaryType;\n\n this._setReadyState(WS_CONNECTING);\n\n this._ws.addEventListener(\"open\", this._onOpen);\n this._ws.addEventListener(\"message\", this._onMessage);\n this._ws.addEventListener(\"error\", this._onError);\n this._ws.addEventListener(\"close\", this._onClose);\n }\n\n private _onOpen = (): void => {\n if (this._socketGen !== this._gen) return;\n this._reconnectCount = 0;\n this._setLoading(false);\n this._setConnected(true);\n this._setReadyState(WS_OPEN);\n };\n\n private _onMessage = (event: MessageEvent): void => {\n if (this._socketGen !== this._gen) return;\n let data = event.data;\n // JSONの自動パース\n if (typeof data === \"string\") {\n try {\n data = JSON.parse(data);\n } catch {\n // テキストのまま\n }\n }\n this._setMessage(data);\n };\n\n private _onError = (event: Event): void => {\n if (this._socketGen !== this._gen) return;\n this._setError(event, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n };\n\n private _onClose = (event: CloseEvent): void => {\n this._removeListeners();\n this._ws = null;\n if (this._socketGen !== this._gen) return;\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n\n // 異常クローズ時の自動再接続(正常終了 1000 は除外)\n if (!this._intentionalClose && this._autoReconnect && event.code !== 1000 && this._reconnectCount < this._maxReconnects) {\n this._scheduleReconnect();\n }\n };\n\n private _scheduleReconnect(): void {\n const gen = this._gen;\n this._clearReconnectTimer();\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null;\n // dispose()/再 connect() でこの再接続が無効化されていたら何もしない。\n if (gen !== this._gen) return;\n this._reconnectCount++;\n this._doConnect();\n }, this._reconnectInterval);\n }\n\n private _clearReconnectTimer(): void {\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n }\n\n private _removeListeners(): void {\n if (!this._ws) {\n return;\n }\n\n this._ws.removeEventListener(\"open\", this._onOpen);\n this._ws.removeEventListener(\"message\", this._onMessage);\n this._ws.removeEventListener(\"error\", this._onError);\n this._ws.removeEventListener(\"close\", this._onClose);\n }\n\n private _closeInternal(): void {\n this._clearReconnectTimer();\n if (this._ws) {\n this._removeListeners();\n if (this._ws.readyState === WS_OPEN || this._ws.readyState === WS_CONNECTING) {\n this._ws.close();\n }\n this._ws = null;\n }\n // 旧接続の状態をリセット(コンストラクタ例外時に stale 状態が残るのを防止)\n if (this._connected) {\n this._setConnected(false);\n }\n if (this._readyState !== WS_CLOSED) {\n this._setReadyState(WS_CLOSED);\n }\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsWebSocket } from \"./components/WebSocket.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const wsId = triggerElement.getAttribute(config.triggerAttribute);\n if (!wsId) return;\n\n // Resolve the registered constructor at call time instead of importing\n // WcsWebSocket as a value. The value import created a components/WebSocket.ts ⇄\n // autoTrigger.ts cycle (WcsWebSocket.connectedCallback() calls\n // registerAutoTrigger()). instanceof against the customElements registry keeps\n // the exact same identity guarantee — only the registered <wcs-ws> class\n // matches — without the import cycle.\n const WsCtor = customElements.get(config.tagNames.ws);\n const wsElement = document.getElementById(wsId);\n if (!WsCtor || !(wsElement instanceof WsCtor)) return;\n\n event.preventDefault();\n (wsElement as WcsWebSocket).connect();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class WcsWebSocket extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...WebSocketCore.wcBindable,\n properties: [\n ...WebSocketCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-ws:trigger-changed\", semantics: \"state\" },\n { name: \"send\", event: \"wcs-ws:send-changed\", semantics: \"state\" },\n ],\n inputs: [\n { name: \"url\", attribute: \"url\" },\n { name: \"protocols\", attribute: \"protocols\" },\n { name: \"autoReconnect\", attribute: \"auto-reconnect\" },\n { name: \"reconnectInterval\", attribute: \"reconnect-interval\" },\n { name: \"maxReconnects\", attribute: \"max-reconnects\" },\n { name: \"binaryType\", attribute: \"binary-type\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n { name: \"send\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"sendMessage\" },\n { name: \"close\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: WebSocketCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n // connectedCallback が接続の判断を終えてから disconnectedCallback までの間だけ true。\n // url 属性の変化による再接続はこの間に限る — upgrade 時は attributeChangedCallback が\n // connectedCallback より先に(isConnected のまま)呼ばれるので、そこで接続すると\n // connectedCallback の接続と合わせて 2 本になる。初回の接続は connectedCallback が持つ。\n private _attached = false;\n\n constructor() {\n super();\n this._core = new WebSocketCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-ws:connected-changed\": (d) => ({ connected: d === true }),\n \"wcs-ws:loading-changed\": (d) => ({ loading: d === true }),\n \"wcs-ws:error\": (d) => ({ error: d != null }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined (an\n // \"undefined\" url would reconnect to \"undefined\"): `null` removes the\n // attribute (the documented default; an empty url does not connect),\n // `undefined` restores the attribute the element started with (wc-bindable\n // producer guidance P1; React 19 and a direct assignment deliver it,\n // @wcstack/state does not).\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string | null | undefined) {\n reflectAttribute(this, \"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string | null | undefined) {\n reflectAttribute(this, \"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"auto-reconnect\", value);\n }\n\n get reconnectInterval(): number {\n const attr = this.getAttribute(\"reconnect-interval\");\n const parsed = attr ? parseInt(attr, 10) : 3000;\n return Number.isNaN(parsed) ? 3000 : parsed;\n }\n\n set reconnectInterval(value: number | null | undefined) {\n reflectAttribute(this, \"reconnect-interval\", value);\n }\n\n get maxReconnects(): number {\n const attr = this.getAttribute(\"max-reconnects\");\n const parsed = attr ? parseInt(attr, 10) : Infinity;\n return Number.isNaN(parsed) ? Infinity : parsed;\n }\n\n set maxReconnects(value: number | null | undefined) {\n reflectAttribute(this, \"max-reconnects\", value);\n }\n\n // Incoming binary frame representation. Backed by the `binary-type` attribute;\n // any value other than \"arraybuffer\" normalizes to the platform default \"blob\".\n get binaryType(): BinaryType {\n return this.getAttribute(\"binary-type\") === \"arraybuffer\" ? \"arraybuffer\" : \"blob\";\n }\n\n set binaryType(value: string | null | undefined) {\n reflectAttribute(this, \"binary-type\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get message(): any {\n return this._core.message;\n }\n\n get connected(): boolean {\n return this._core.connected;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n get readyState(): number {\n return this._core.readyState;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.connect();\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-ws:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // `send` is a write-only command surface: assigning transmits immediately.\n // Reading always returns null (no payload is retained) — consistent with the\n // null carried by wcs-ws:send-changed and the documented \"resets to null\".\n get send(): any {\n return null;\n }\n\n set send(data: any) {\n if (data === null || data === undefined) return;\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n this._core.send(payload);\n this.dispatchEvent(new CustomEvent(\"wcs-ws:send-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n // --- Public methods ---\n\n connect(): void {\n const protocols = this.protocols\n ? this.protocols.split(\",\").map(p => p.trim()).filter(Boolean)\n : undefined;\n\n this._core.connect(this.url, {\n protocols: protocols && protocols.length === 1 ? protocols[0] : protocols,\n autoReconnect: this.autoReconnect,\n reconnectInterval: this.reconnectInterval,\n maxReconnects: this.maxReconnects,\n binaryType: this.binaryType,\n });\n }\n\n sendMessage(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this._core.send(data);\n }\n\n close(code?: number, reason?: string): void {\n this._core.close(code, reason);\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // 再接続するのは url が「変わった」ときだけ。同じ値の書き込み(url の setter 自身の\n // setAttribute の後に、属性も書く binder — @wcstack/state 3.x の inputs[].attribute ミラー —\n // が同じ値を書く、など)\n // は何もしない。connectedCallback より前(upgrade 中・DOM の外)の変化は、\n // connectedCallback がそのときの url で 1 回だけ接続する。\n if (name === \"url\" && oldValue !== newValue && this._attached && !this.manual && newValue) {\n this.connect();\n }\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)。\n // ここで url の setter が走っても _attached はまだ false なので接続しない —\n // 接続は下で、取り込み後の url / manual を見て 1 回だけ行う。\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // observe() は command-driven node では ready を返す no-op(§3.5)。SSR は\n // connectedCallbackPromise を await して初期スナップショットを取れる。\n this._connectedCallbackPromise = this._core.observe();\n if (!this.manual && this.url) {\n this.connect();\n }\n this._attached = true;\n }\n\n disconnectedCallback(): void {\n this._attached = false;\n // dispose() が _gen を bump して進行中のソケット/再接続を無効化し、close() する。\n this._core.dispose();\n }\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.ws)) {\n registry.define(config.tagNames.ws, WcsWebSocket);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapWebSocket(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/websocketCapabilities.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/WebSocket.ts","../src/registerComponents.ts","../src/bootstrapWebSocket.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n ws: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-wstarget\",\n tagNames: {\n ws: \"wcs-ws\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\n/** A misspelt option would otherwise do nothing: `bootstrapWebSocket` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/websocket] bootstrapWebSocket: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","/**\n * websocketCapabilities.ts\n *\n * WebSocket node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。WebSocket は持続的な session / monitor node(1 本の接続を張り続ける)で、\n * 競合する operation を持たないため lane は持たず、error taxonomy(errorInfo)のみを採用する。\n *\n * この node の `_setError` は 4 形態の非 null 入力を受ける(いずれも公開 `error` shape は不変):\n * 1. synthetic な `{ message: \"url is required.\" }`(`.name` 無し)— connect() の引数不備。\n * 2. synthetic な `{ message: \"WebSocket is not connected.\" }`(`.name` 無し)— open 前の send()。\n * 3. caught された生の構築例外 `e`(`new WebSocket()` の同期 throw)。\n * 4. platform の WebSocket `error` Event(`Event`。`.name`/`.message` を持たない)。\n *\n * これらは shape がバラバラで、message からの分類は脆い。そこで呼び出し側が明示的な\n * taxonomy code を discriminator として渡す(storage の `deriveStorageErrorInfo(error, name)`\n * と同じ技法)。derive 側は synthetic / Event / Error を reverse-engineer せず、渡された\n * code で phase / recoverable を決め、message だけを防御的に抽出する。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 安定した websocket error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_WEBSOCKET_ERROR_CODE = {\n /** connect() の `url` 未指定 — 開始前の入力不備。retry では回復しない。 */\n InvalidArgument: \"invalid-argument\",\n /** open 前の send() — 接続が OPEN でない状態での送信。retry では回復しない(先に connect が要る)。 */\n InvalidState: \"invalid-state\",\n /**\n * 接続の確立 / 維持に失敗(`new WebSocket()` の同期例外、または platform の error Event)。\n * WebSocket のエラーは通常一過性で、再接続で回復しうる(recoverable=true)。\n */\n ConnectionError: \"connection-error\",\n} as const;\n\n/**\n * websocket の失敗を serializable な error taxonomy に写す。`code` は呼び出し側が渡す\n * discriminator(公開 `error` shape からは復元しない)。`message` は入力から防御的に抽出し、\n * message を持たない error Event 等では安定した fallback を使う。\n *\n * - `invalid-argument`(url 未指定)は開始前の入力不備 → phase=\"start\" / recoverable=false。\n * - `invalid-state`(open 前 send)は接続状態が満たされない実行時失敗 → phase=\"execute\" /\n * recoverable=false(先に connect() が必要)。\n * - `connection-error`(構築例外 / error Event)は接続の確立 / 維持失敗 → phase=\"execute\" /\n * recoverable=true(再接続で回復しうる)。\n */\nexport function deriveWebSocketErrorInfo(error: unknown, code: string): WcsIoErrorInfo {\n // error は非 null(_setError は error===null を derive 前に分岐する)だが、synthetic /\n // Event / caught 例外 / 生 throw と shape がバラバラなので message は防御的に抽出する。\n // error Event は message を持たないため安定した fallback に落とす。\n const raw = (error as { message?: unknown }).message;\n const message = typeof raw === \"string\" ? raw : \"WebSocket connection error\";\n\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidArgument) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidArgument, phase: \"start\", recoverable: false, message };\n }\n if (code === WCS_WEBSOCKET_ERROR_CODE.InvalidState) {\n return { code: WCS_WEBSOCKET_ERROR_CODE.InvalidState, phase: \"execute\", recoverable: false, message };\n }\n // connection-error(構築例外 / error Event): 接続の確立/維持失敗、再接続で回復しうる。\n return { code: WCS_WEBSOCKET_ERROR_CODE.ConnectionError, phase: \"execute\", recoverable: true, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveWebSocketErrorInfo, WCS_WEBSOCKET_ERROR_CODE } from \"./websocketCapabilities.js\";\n\n// WebSocket readyState values. Hardcoded rather than read from the global\n// WebSocket so the Core does not require WebSocket to exist at module load\n// (referencing `WebSocket.CLOSED` in a field initializer evaluates at class\n// definition time; tests inject a mock). Mirrors SseCore's SSE_CLOSED.\nconst WS_CONNECTING = 0;\nconst WS_OPEN = 1;\nconst WS_CLOSED = 3;\n\nexport interface WebSocketConnectOptions {\n protocols?: string | string[];\n autoReconnect?: boolean;\n reconnectInterval?: number;\n maxReconnects?: number;\n // How incoming binary frames are surfaced on `message`. \"blob\" (the platform\n // default) or \"arraybuffer\" for direct byte processing. Applied to every\n // socket this connection spawns, including auto-reconnects.\n binaryType?: BinaryType;\n // Milliseconds without a message after which an open connection is treated as lost (0 or\n // absent: never). A WebSocket does not notice a connection that died without being closed — a\n // laptop's sleep, a NAT or proxy that dropped it — and stays OPEN; the server must send a message\n // more often than this (a protocol-level ping frame is not seen by the page).\n staleAfter?: number;\n}\n\nexport class WebSocketCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"message\", event: \"wcs-ws:message\", semantics: \"event\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\", semantics: \"state\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\", semantics: \"state\" },\n { name: \"error\", event: \"wcs-ws:error\", semantics: \"state\" },\n // Serializable failure taxonomy (stable code / phase / recoverable), or null.\n // Additive bindable output derived from `error` (invalid-argument / invalid-state\n // / connection-error); the existing `error` property/event are unchanged. Fires\n // wcs-ws:error-info-changed. No lane — WebSocket is a persistent session/monitor\n // node, not a competing operation.\n { name: \"errorInfo\", event: \"wcs-ws:error-info-changed\", semantics: \"state\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"send\" },\n { name: \"close\" },\n ],\n };\n\n private _target: EventTarget;\n private _ws: WebSocket | null = null;\n private _message: any = null;\n private _connected: boolean = false;\n private _loading: boolean = false;\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n private _readyState: number = WS_CLOSED;\n\n // 自動再接続\n private _autoReconnect: boolean = false;\n private _reconnectInterval: number = 3000;\n private _maxReconnects: number = Infinity;\n private _reconnectCount: number = 0;\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private _url: string = \"\";\n private _protocols: string | string[] | undefined = undefined;\n private _binaryType: BinaryType = \"blob\";\n private _intentionalClose: boolean = false;\n // stale-after (ms, 0 = off): the time of the last open / message, and the watchdog's timer\n private _staleAfter: number = 0;\n private _lastActivity: number = 0;\n private _staleTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Generation guard (§3.4): bumped on dispose() and at every connect(). A socket\n // event (open/message/error/close) or a scheduled reconnect that fires after\n // dispose / a superseding connect() carries a stale `gen` and MUST NOT write\n // state onto a torn-down element. A boolean flag is insufficient (dispose→observe\n // would let stale work slip through).\n private _gen = 0;\n // Generation captured when the current socket was opened. The shared socket\n // event handlers compare it against _gen to drop events from a superseded /\n // disposed connection.\n private _socketGen = 0;\n // SSR (§3.8): WebSocket is command-driven with no asynchronous probe to await,\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n /**\n * Whether `[wcs/command-not-ready]` was said in this outage: a `send()` refused because the\n * element is not ready loses what it carried, and `error` alone told only a page that binds it.\n * Said once per outage (docs/v4-direction-2026-10.md, the I/O command policy): the socket opening\n * resets it. Once per element was once per page life — a route puts the same element back on\n * every entry, so the next outage's lost message went unsaid (docs/seam-apps.md, shift-desk).\n */\n private _toldNotReady = false;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). WebSocket connections are command-driven (connect()), so\n // observe() is an idempotent no-op that resolves once ready; the Shell's\n // connectedCallback does not auto-establish a subscription here. dispose()\n // invalidates any in-flight socket / pending reconnect and closes the socket.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.close();\n // The socket's close event is dropped as stale (the generation moved), so the\n // connection's end is published here (timing-and-firing-contract §22): a route the\n // element leaves keeps its nodes — bindings included — for the next entry, and\n // state would keep showing a connection that is gone.\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n }\n\n /**\n * Closes like dispose() — the end is published at once — and says whether a connection was\n * open, opening or about to reopen (auto-reconnect). The Shell uses it when the page may enter\n * the back/forward cache, and reconnects on the way back.\n */\n suspend(): boolean {\n const live = this._ws !== null || this._reconnectTimer !== null;\n this.dispose();\n return live;\n }\n\n get message(): any {\n return this._message;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-ws:error-info-changed`), derived from `error`; the existing `error`\n * property/event are unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n get readyState(): number {\n return this._readyState;\n }\n\n // --- State setters with event dispatch ---\n\n private _setMessage(message: any): void {\n this._message = message;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:message\", {\n detail: message,\n bubbles: true,\n }));\n }\n\n private _setConnected(connected: boolean): void {\n this._connected = connected;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:connected-changed\", {\n detail: connected,\n bubbles: true,\n }));\n }\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // `code` is an explicit taxonomy discriminator (WCS_WEBSOCKET_ERROR_CODE), passed\n // only from the non-null failure call sites. It stays out of the public `error`\n // shape and is used solely to classify errorInfo without reverse-engineering the\n // heterogeneous `error` values (synthetic {message} / caught Error / raw Event).\n // The clear path passes null and no code.\n private _setError(error: any, code?: string): void {\n // Same-value guard (async-io-node-guidelines.md §3.3). `error` is state-ish,\n // so suppressing redundant null→null dispatches (every connect/send start\n // clears a usually-already-null error) avoids a spurious wcs-ws:error per\n // successful operation. Reference identity is sufficient: each failure builds\n // a fresh object (or the platform's own error Event), and the clear path\n // always passes null.\n if (this._error === error) return;\n this._error = error;\n // Keep the additive `errorInfo` taxonomy in sync with `error`: derive from the\n // explicit `code` (or null on clear). Fires before the `error` event so an\n // observer binding both sees the classification first, mirroring the io-node\n // family. Every non-null error carries a code (the clear path is the only\n // caller without one, and it is short-circuited here), so `code!` holds.\n this._commitErrorInfo(error === null ? null : deriveWebSocketErrorInfo(error, code!));\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (which already same-value-guards on the error\n // reference), so errorInfo transitions exactly when error does — no separate\n // guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n\n private _setReadyState(readyState: number): void {\n this._readyState = readyState;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:readystate-changed\", {\n detail: readyState,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n connect(url: string, options: WebSocketConnectOptions = {}): void {\n // never-throw (§3.6): 引数バリデーション失敗は例外ではなく error プロパティに\n // 流し、サニタイズ値(なにもしない)を返す。command-token 経路(set trigger →\n // connect())からの呼び出しが state 更新サイクルを壊さないようにする。\n if (!url) {\n this._setError({ message: \"url is required.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidArgument);\n return;\n }\n\n // 新しい接続を開始するため世代を更新し、進行中のソケット/再接続を無効化する。\n this._gen++;\n\n // 既存の接続をクローズ\n this._intentionalClose = true;\n this._closeInternal();\n\n this._url = url;\n this._protocols = options.protocols;\n this._autoReconnect = options.autoReconnect ?? false;\n this._reconnectInterval = options.reconnectInterval ?? 3000;\n this._maxReconnects = options.maxReconnects ?? Infinity;\n this._binaryType = options.binaryType ?? \"blob\";\n this._staleAfter = options.staleAfter !== undefined && options.staleAfter > 0 ? options.staleAfter : 0;\n this._reconnectCount = 0;\n this._intentionalClose = false;\n\n this._doConnect();\n }\n\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n // never-throw (§3.6): 未接続での送信は例外ではなく error に流す。set send の\n // fire-and-forget 経路で例外が伝播するのを防ぐ。\n if (!this._ws || this._ws.readyState !== WS_OPEN) {\n this._setError({ message: \"WebSocket is not connected.\" }, WCS_WEBSOCKET_ERROR_CODE.InvalidState);\n this._warnNotReady();\n return;\n }\n this._ws.send(data);\n }\n\n private _warnNotReady(): void {\n if (this._toldNotReady) return;\n this._toldNotReady = true;\n console.warn(\n \"[@wcstack/websocket] [wcs/command-not-ready] send() was refused: the WebSocket is not connected, so the message is lost. \" +\n \"It goes to `error` too. Send once `connected` is true. (Said once until the WebSocket connects again.)\",\n this._target,\n );\n }\n\n close(code?: number, reason?: string): void {\n this._intentionalClose = true;\n this._clearReconnectTimer();\n this._clearStaleTimer();\n if (this._ws) {\n this._ws.close(code, reason);\n }\n }\n\n // --- Internal ---\n\n private _doConnect(): void {\n this._setLoading(true);\n this._setError(null);\n\n // 接続開始時点の世代を捕捉。dispose()/再 connect() 後に発火した古いソケット\n // イベントはこの gen が stale になり、状態を書き換えない(_onOpen ほかが\n // _socketGen と this._gen を突き合わせて判定する)。\n this._socketGen = this._gen;\n\n try {\n this._ws = this._protocols\n ? new WebSocket(this._url, this._protocols)\n : new WebSocket(this._url);\n } catch (e) {\n this._setLoading(false);\n this._setError(e, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n return;\n }\n\n // Binary frames default to Blob; opt into ArrayBuffer for direct byte access.\n this._ws.binaryType = this._binaryType;\n\n this._setReadyState(WS_CONNECTING);\n\n this._ws.addEventListener(\"open\", this._onOpen);\n this._ws.addEventListener(\"message\", this._onMessage);\n this._ws.addEventListener(\"error\", this._onError);\n this._ws.addEventListener(\"close\", this._onClose);\n }\n\n private _onOpen = (): void => {\n if (this._socketGen !== this._gen) return;\n this._reconnectCount = 0;\n // ready again: a send refused in the next outage is said again\n this._toldNotReady = false;\n this._lastActivity = Date.now();\n this._armStale();\n this._setLoading(false);\n this._setConnected(true);\n this._setReadyState(WS_OPEN);\n };\n\n private _onMessage = (event: MessageEvent): void => {\n if (this._socketGen !== this._gen) return;\n this._lastActivity = Date.now();\n let data = event.data;\n // JSONの自動パース\n if (typeof data === \"string\") {\n try {\n data = JSON.parse(data);\n } catch {\n // テキストのまま\n }\n }\n this._setMessage(data);\n };\n\n private _onError = (event: Event): void => {\n if (this._socketGen !== this._gen) return;\n this._setError(event, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n };\n\n private _onClose = (event: CloseEvent): void => {\n this._removeListeners();\n this._ws = null;\n if (this._socketGen !== this._gen) return;\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n\n // 異常クローズ時の自動再接続(正常終了 1000 は除外)\n if (!this._intentionalClose && this._autoReconnect && event.code !== 1000 && this._reconnectCount < this._maxReconnects) {\n this._scheduleReconnect();\n }\n };\n\n private _scheduleReconnect(): void {\n const gen = this._gen;\n this._clearReconnectTimer();\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null;\n // dispose()/再 connect() でこの再接続が無効化されていたら何もしない。\n if (gen !== this._gen) return;\n this._reconnectCount++;\n this._doConnect();\n }, this._reconnectInterval);\n }\n\n // stale-after の見張り。開いている間、最後の open / メッセージから staleAfter ms 何も届かなければ、\n // 接続は失われたとみなす(docs/seam-apps.md、shift-desk: 閉じられずに死んだ接続 — スリープ・NAT・\n // proxy — に WebSocket は気づかず OPEN のまま、ページは \"connected\" と言い続けた)。タイマーは 1 本\n // だけ持ち、満了のたびに最後の活動からの残りで張り直す(メッセージごとに張り直さない)。\n private _armStale(): void {\n if (this._staleAfter === 0 || this._staleTimer !== null) return;\n this._staleTimer = setTimeout(this._checkStale, this._staleAfter);\n }\n\n private _checkStale = (): void => {\n this._staleTimer = null;\n const ws = this._ws;\n if (ws === null || this._readyState !== WS_OPEN) return;\n const idle = Date.now() - this._lastActivity;\n if (idle < this._staleAfter) {\n this._staleTimer = setTimeout(this._checkStale, this._staleAfter - idle);\n return;\n }\n // 失われたとみなし、異常なクローズと同じに扱う。半開きの TCP では閉じる手順が終わらないので、\n // ソケットはその場で手放し(イベントは外す)、終わりと理由を知らせ、auto-reconnect の規則で\n // つなぎ直す。\n this._removeListeners();\n this._ws = null;\n try {\n ws.close(4000, \"stale\");\n } catch {\n // a socket that cannot be closed any more is gone anyway\n }\n this._setConnected(false);\n this._setLoading(false);\n this._setReadyState(WS_CLOSED);\n this._setError({ message: `No message for ${this._staleAfter} ms: the connection is treated as lost.` }, WCS_WEBSOCKET_ERROR_CODE.ConnectionError);\n if (!this._intentionalClose && this._autoReconnect && this._reconnectCount < this._maxReconnects) {\n this._scheduleReconnect();\n }\n };\n\n private _clearStaleTimer(): void {\n if (this._staleTimer !== null) {\n clearTimeout(this._staleTimer);\n this._staleTimer = null;\n }\n }\n\n private _clearReconnectTimer(): void {\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n }\n\n private _removeListeners(): void {\n if (!this._ws) {\n return;\n }\n\n this._ws.removeEventListener(\"open\", this._onOpen);\n this._ws.removeEventListener(\"message\", this._onMessage);\n this._ws.removeEventListener(\"error\", this._onError);\n this._ws.removeEventListener(\"close\", this._onClose);\n }\n\n private _closeInternal(): void {\n this._clearReconnectTimer();\n this._clearStaleTimer();\n if (this._ws) {\n this._removeListeners();\n if (this._ws.readyState === WS_OPEN || this._ws.readyState === WS_CONNECTING) {\n this._ws.close();\n }\n this._ws = null;\n }\n // 旧接続の状態をリセット(コンストラクタ例外時に stale 状態が残るのを防止)\n if (this._connected) {\n this._setConnected(false);\n }\n if (this._readyState !== WS_CLOSED) {\n this._setReadyState(WS_CLOSED);\n }\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsWebSocket } from \"./components/WebSocket.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const wsId = triggerElement.getAttribute(config.triggerAttribute);\n if (!wsId) return;\n\n // Resolve the registered constructor at call time instead of importing\n // WcsWebSocket as a value. The value import created a components/WebSocket.ts ⇄\n // autoTrigger.ts cycle (WcsWebSocket.connectedCallback() calls\n // registerAutoTrigger()). instanceof against the customElements registry keeps\n // the exact same identity guarantee — only the registered <wcs-ws> class\n // matches — without the import cycle.\n const WsCtor = customElements.get(config.tagNames.ws);\n const wsElement = document.getElementById(wsId);\n if (!WsCtor || !(wsElement instanceof WsCtor)) return;\n\n event.preventDefault();\n (wsElement as WcsWebSocket).connect();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class WcsWebSocket extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...WebSocketCore.wcBindable,\n properties: [\n ...WebSocketCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-ws:trigger-changed\", semantics: \"state\" },\n { name: \"send\", event: \"wcs-ws:send-changed\", semantics: \"state\" },\n ],\n inputs: [\n { name: \"url\", attribute: \"url\" },\n { name: \"protocols\", attribute: \"protocols\" },\n { name: \"autoReconnect\", attribute: \"auto-reconnect\" },\n { name: \"reconnectInterval\", attribute: \"reconnect-interval\" },\n { name: \"maxReconnects\", attribute: \"max-reconnects\" },\n { name: \"binaryType\", attribute: \"binary-type\" },\n { name: \"staleAfter\", attribute: \"stale-after\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n { name: \"send\" },\n ],\n commands: [\n { name: \"connect\" },\n { name: \"sendMessage\" },\n { name: \"close\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: WebSocketCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n // connectedCallback が接続の判断を終えてから disconnectedCallback までの間だけ true。\n // url 属性の変化による再接続はこの間に限る — upgrade 時は attributeChangedCallback が\n // connectedCallback より先に(isConnected のまま)呼ばれるので、そこで接続すると\n // connectedCallback の接続と合わせて 2 本になる。初回の接続は connectedCallback が持つ。\n private _attached = false;\n // _scheduleConnect のマイクロタスクが待っている間 true\n private _connectPending = false;\n\n constructor() {\n super();\n this._core = new WebSocketCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-ws:connected-changed\": (d) => ({ connected: d === true }),\n \"wcs-ws:loading-changed\": (d) => ({ loading: d === true }),\n \"wcs-ws:error\": (d) => ({ error: d != null }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined (an\n // \"undefined\" url would reconnect to \"undefined\"): `null` removes the\n // attribute (the documented default; an empty url does not connect),\n // `undefined` restores the attribute the element started with (wc-bindable\n // producer guidance P1; React 19 and a direct assignment deliver it,\n // @wcstack/state does not).\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string | null | undefined) {\n reflectAttribute(this, \"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string | null | undefined) {\n reflectAttribute(this, \"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"auto-reconnect\", value);\n }\n\n get reconnectInterval(): number {\n const attr = this.getAttribute(\"reconnect-interval\");\n const parsed = attr ? parseInt(attr, 10) : 3000;\n return Number.isNaN(parsed) ? 3000 : parsed;\n }\n\n set reconnectInterval(value: number | null | undefined) {\n reflectAttribute(this, \"reconnect-interval\", value);\n }\n\n get maxReconnects(): number {\n const attr = this.getAttribute(\"max-reconnects\");\n const parsed = attr ? parseInt(attr, 10) : Infinity;\n return Number.isNaN(parsed) ? Infinity : parsed;\n }\n\n set maxReconnects(value: number | null | undefined) {\n reflectAttribute(this, \"max-reconnects\", value);\n }\n\n // Incoming binary frame representation. Backed by the `binary-type` attribute;\n // any value other than \"arraybuffer\" normalizes to the platform default \"blob\".\n get binaryType(): BinaryType {\n return this.getAttribute(\"binary-type\") === \"arraybuffer\" ? \"arraybuffer\" : \"blob\";\n }\n\n set binaryType(value: string | null | undefined) {\n reflectAttribute(this, \"binary-type\", value);\n }\n\n // 何も届かない時間(ms)がこれを超えた開いている接続を、失われたとみなす(0・未指定・数でない\n // 値は見張らない)。接続オプションの 1 つで、接続するときに読む。\n get staleAfter(): number {\n const parsed = Number(this.getAttribute(\"stale-after\"));\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;\n }\n\n set staleAfter(value: number | null | undefined) {\n reflectAttribute(this, \"stale-after\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get message(): any {\n return this._core.message;\n }\n\n get connected(): boolean {\n return this._core.connected;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n get readyState(): number {\n return this._core.readyState;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.connect();\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-ws:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // `send` is a write-only command surface: assigning transmits immediately.\n // Reading always returns null (no payload is retained) — consistent with the\n // null carried by wcs-ws:send-changed and the documented \"resets to null\".\n get send(): any {\n return null;\n }\n\n set send(data: any) {\n if (data === null || data === undefined) return;\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n this._core.send(payload);\n this.dispatchEvent(new CustomEvent(\"wcs-ws:send-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n // --- Public methods ---\n\n connect(): void {\n // an explicit connect (trigger included) or close takes the pending connect-time decision\n this._connectPending = false;\n const protocols = this.protocols\n ? this.protocols.split(\",\").map(p => p.trim()).filter(Boolean)\n : undefined;\n\n this._core.connect(this.url, {\n protocols: protocols && protocols.length === 1 ? protocols[0] : protocols,\n autoReconnect: this.autoReconnect,\n reconnectInterval: this.reconnectInterval,\n maxReconnects: this.maxReconnects,\n binaryType: this.binaryType,\n staleAfter: this.staleAfter,\n });\n }\n\n sendMessage(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this._core.send(data);\n }\n\n close(code?: number, reason?: string): void {\n this._connectPending = false;\n this._core.close(code, reason);\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // 再接続するのは url が「変わった」ときだけ。同じ値の書き込み(url の setter 自身の\n // setAttribute の後に、属性も書く binder — @wcstack/state 3.x の inputs[].attribute ミラー —\n // が同じ値を書く、など)\n // は何もしない。connectedCallback より前(upgrade 中・DOM の外)の変化は、\n // connectedCallback がそのときの url で 1 回だけ接続する。\n if (name === \"url\" && oldValue !== newValue && this._attached && !this.manual && newValue) {\n this._scheduleConnect();\n }\n }\n\n // 接続の判断はマイクロタスクで、そのときの url / manual で 1 回だけ行う\n // (timing-and-firing-contract §23)。router は遷移で同じノードを入れ直し、新しいルートの\n // params から state が url を書くのはマイクロタスク — その場で接続すると、前の url へ\n // つないでから閉じていた(docs/seam-apps.md、shift-desk)。間の url の変化もここへまとまる。\n private _scheduleConnect(): void {\n if (this._connectPending) return;\n this._connectPending = true;\n queueMicrotask(() => {\n if (!this._connectPending) return; // an explicit command took the decision meanwhile\n this._connectPending = false;\n if (this._attached && !this.manual && this.url) {\n this.connect();\n }\n });\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)。\n // ここで url の setter が走っても _attached はまだ false なので接続しない —\n // 接続は下で、取り込み後の url / manual を見て 1 回だけ行う。\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // observe() は command-driven node では ready を返す no-op(§3.5)。SSR は\n // connectedCallbackPromise を await して初期スナップショットを取れる。\n this._connectedCallbackPromise = this._core.observe();\n this._attached = true;\n window.addEventListener(\"pagehide\", this._onPageHide);\n window.addEventListener(\"pageshow\", this._onPageShow);\n this._scheduleConnect();\n }\n\n // back/forward cache(docs/seam-apps.md、shift-desk): 開いた WebSocket はページを cache から外す\n // (Chromium は復元しない — 理由 \"websocket\")。ページが cache に入りうるとき(pagehide の persisted)\n // 閉じて終わりをその場で知らせ、戻ったとき(pageshow の persisted)、閉じる前に接続していたなら\n // つなぎ直す。ページが自分で閉じると、閉じた知らせは復元の後に届き、pageshow の時点の state は\n // まだ接続中だった。\n private _reopenOnShow = false;\n\n private _onPageHide = (event: Event): void => {\n if (!(event as PageTransitionEvent).persisted) return;\n if (this._core.suspend()) this._reopenOnShow = true;\n };\n\n private _onPageShow = (event: Event): void => {\n if (!(event as PageTransitionEvent).persisted || !this._reopenOnShow) return;\n this._reopenOnShow = false;\n // (the listeners live only while the element is connected)\n if (this.url) this.connect();\n };\n\n disconnectedCallback(): void {\n this._attached = false;\n this._reopenOnShow = false;\n window.removeEventListener(\"pagehide\", this._onPageHide);\n window.removeEventListener(\"pageshow\", this._onPageShow);\n // dispose() が _gen を bump して進行中のソケット/再接続を無効化し、close() する。\n this._core.dispose();\n }\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.ws)) {\n registry.define(config.tagNames.ws, WcsWebSocket);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapWebSocket(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/websocket",
3
- "version": "4.6.2",
3
+ "version": "4.8.0",
4
4
  "description": "Declarative WebSocket component for Web Components. Framework-agnostic real-time communication via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",