@wcstack/websocket 1.15.0 → 1.17.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
@@ -50,12 +50,19 @@ npm install @wcstack/websocket
50
50
  <script type="module" src="https://esm.run/@wcstack/websocket/auto"></script>
51
51
 
52
52
  <wcs-state>
53
- <script type="application/json">
54
- {
55
- "lastMessage": null,
56
- "isConnected": false,
57
- "isLoading": false
58
- }
53
+ <script type="module">
54
+ export default {
55
+ lastMessage: null,
56
+ isConnected: false,
57
+ isLoading: false,
58
+
59
+ get connectionLabel() {
60
+ return this.isConnected ? "接続中" : "切断";
61
+ },
62
+ get lastMessageJson() {
63
+ return JSON.stringify(this.lastMessage, null, 2);
64
+ },
65
+ };
59
66
  </script>
60
67
 
61
68
  <wcs-ws
@@ -63,8 +70,8 @@ npm install @wcstack/websocket
63
70
  data-wcs="message: lastMessage; connected: isConnected; loading: isLoading">
64
71
  </wcs-ws>
65
72
 
66
- <p data-wcs="textContent: isConnected|then('接続中','切断')"></p>
67
- <pre data-wcs="textContent: lastMessage|json"></pre>
73
+ <p data-wcs="textContent: connectionLabel"></p>
74
+ <pre data-wcs="textContent: lastMessageJson"></pre>
68
75
  </wcs-state>
69
76
  ```
70
77
 
@@ -86,6 +93,9 @@ npm install @wcstack/websocket
86
93
  lastMessage: null,
87
94
  outgoing: null,
88
95
 
96
+ get lastMessageJson() {
97
+ return JSON.stringify(this.lastMessage, null, 2);
98
+ },
89
99
  sendChat() {
90
100
  this.outgoing = { type: "chat", content: this.chatInput };
91
101
  this.chatInput = "";
@@ -101,7 +111,7 @@ npm install @wcstack/websocket
101
111
  <input data-wcs="value: chatInput" placeholder="メッセージを入力">
102
112
  <button data-wcs="onclick: sendChat">送信</button>
103
113
 
104
- <pre data-wcs="textContent: lastMessage|json"></pre>
114
+ <pre data-wcs="textContent: lastMessageJson"></pre>
105
115
  </wcs-state>
106
116
  ```
107
117
 
@@ -117,6 +127,9 @@ npm install @wcstack/websocket
117
127
  lastMessage: null,
118
128
  isConnected: false,
119
129
 
130
+ get connectionLabel() {
131
+ return this.isConnected ? "接続中" : "切断";
132
+ },
120
133
  openConnection() {
121
134
  this.shouldConnect = true;
122
135
  },
@@ -130,7 +143,7 @@ npm install @wcstack/websocket
130
143
  </wcs-ws>
131
144
 
132
145
  <button data-wcs="onclick: openConnection">接続</button>
133
- <p data-wcs="textContent: isConnected|then('接続中','切断')"></p>
146
+ <p data-wcs="textContent: connectionLabel"></p>
134
147
  </wcs-state>
135
148
  ```
136
149
 
@@ -190,6 +203,58 @@ HTML、JS、または `@wcstack/state` バインディングから接続とメ
190
203
  | `send` | `any` | 値を設定するとデータを送信(オブジェクトは自動文字列化) |
191
204
  | `manual` | `boolean` | DOM 接続時の自動接続を無効化 |
192
205
 
206
+ ## `:state()` による CSS スタイリング
207
+
208
+ `<wcs-ws>` は 3 つの boolean 出力ステートを
209
+ [`ElementInternals` の `CustomStateSet`](https://developer.mozilla.org/ja/docs/Web/API/CustomStateSet)
210
+ に反映します。そのため `data-wcs` バインディングやクラスの手動トグルなしに、CSS の
211
+ `:state()` 疑似クラスで直接スタイリングできます。
212
+
213
+ | ステート | on になる条件 |
214
+ |----------|----------------|
215
+ | `connected` | `wcs-ws:connected-changed` が `true` で発火(`false` でクリア) |
216
+ | `loading` | `wcs-ws:loading-changed` が `true` で発火(`false` でクリア) |
217
+ | `error` | `wcs-ws:error` が非 `null` の detail で発火(`null` でクリア) |
218
+
219
+ ```css
220
+ wcs-ws:state(connected) ~ .indicator { color: green; }
221
+ wcs-ws:state(loading) ~ .indicator { color: orange; }
222
+
223
+ form:has(wcs-ws:state(error)) .banner { display: block; }
224
+ ```
225
+
226
+ 属性やクラスと異なり `:state()` は要素の外部から書き込めないため、この出力ステートが
227
+ 入力と混同される心配がありません。
228
+
229
+ **対応ブラウザ**(新構文 `:state(x)`): Chrome/Edge 125+、Safari 17.4+、Firefox 126+。
230
+ 非対応の環境ではステートが一切 set されないだけです — `:state()` セレクタがマッチしなく
231
+ なりますが、`<wcs-ws>` 自体は通常どおり動作し続けます(graceful degradation・never-throw)。
232
+
233
+ **SSR:** `:state()` は HTML にシリアライズできないため、サーバーレンダリングされた
234
+ マークアップの初期ペイントにはこれらのステートは乗りません(`@wcstack/server` は無改変)。
235
+ ハイドレーション前の見た目を制御したい場合は、代わりに `wcs-ws:not(:defined)` と組み合わせてください。
236
+
237
+ ### デバッグ
238
+
239
+ カスタムステートは DevTools の Elements パネルには表示されず、`attachInternals()`
240
+ は同一要素に 2 回呼べないため、コンソールから直接覗く手段がありません。そのための
241
+ デバッグ専用の補助を 2 つ用意しています:
242
+
243
+ - `el.debugStates` — 現在 on になっているステート名の**スナップショット**配列
244
+ (例: `["connected"]`)。`wc-bindable` の一部ではなく(バインド対象ではない)、
245
+ 形状も契約として保証されません — デバッグ用途にのみ使ってください。
246
+ - `debug-states` 属性(opt-in・既定 OFF)は、ステート変化を要素の
247
+ `data-wcs-state-connected` / `data-wcs-state-loading` / `data-wcs-state-error`
248
+ 属性にミラーします。Elements パネルを開いておけば、トグルのたびにハイライトされます:
249
+
250
+ ```html
251
+ <wcs-ws url="wss://example.com/socket" debug-states></wcs-ws>
252
+ ```
253
+
254
+ **CSS は `data-wcs-state-*` ではなく `:state()` に書いてください。** ミラーされた
255
+ 属性は、DevTools を開いた状態でステート変化を可視化するためだけのものであり、
256
+ スタイリング用の正式なフックではありません。
257
+
193
258
  ## アーキテクチャ
194
259
 
195
260
  `@wcstack/websocket` は CSBC アーキテクチャに従います。
@@ -310,6 +375,7 @@ wcstack アプリケーションでは、**`trigger` によるステート駆動
310
375
  | `auto-reconnect` | `boolean` | `false` | 自動再接続を有効化 |
311
376
  | `reconnect-interval` | `number` | `3000` | 再接続間隔(ミリ秒) |
312
377
  | `max-reconnects` | `number` | `Infinity` | 最大再接続回数 |
378
+ | `binary-type` | `"blob" \| "arraybuffer"` | `blob` | 受信バイナリフレームを `message` でどう表現するか。`arraybuffer` 以外の値は `blob` に正規化される |
313
379
 
314
380
  | プロパティ | 型 | 説明 |
315
381
  |------------|------|------|
@@ -318,6 +384,7 @@ wcstack アプリケーションでは、**`trigger` によるステート駆動
318
384
  | `loading` | `boolean` | 接続処理中は `true` |
319
385
  | `error` | `WcsWsError \| Event \| null` | エラー情報 |
320
386
  | `readyState` | `number` | WebSocket readyState 定数 |
387
+ | `binaryType` | `"blob" \| "arraybuffer"` | バイナリフレーム表現(`binary-type` 属性を背後に持つ。既定 `blob`) |
321
388
  | `trigger` | `boolean` | `true` を設定すると接続を開始 |
322
389
  | `send` | `any` | 値を設定するとデータを送信 |
323
390
 
@@ -380,6 +447,7 @@ static wcBindable = {
380
447
  { name: "autoReconnect", attribute: "auto-reconnect" },
381
448
  { name: "reconnectInterval", attribute: "reconnect-interval" },
382
449
  { name: "maxReconnects", attribute: "max-reconnects" },
450
+ { name: "binaryType", attribute: "binary-type" },
383
451
  { name: "manual", attribute: "manual" },
384
452
  { name: "trigger" },
385
453
  { name: "send" },
@@ -431,6 +499,7 @@ interface WcsWsInputs {
431
499
  autoReconnect: boolean;
432
500
  reconnectInterval: number;
433
501
  maxReconnects: number;
502
+ binaryType: BinaryType; // "blob" | "arraybuffer"
434
503
  manual: boolean;
435
504
  trigger: boolean;
436
505
  send: unknown;
@@ -442,6 +511,7 @@ interface WcsWsCoreCommands {
442
511
  autoReconnect?: boolean;
443
512
  reconnectInterval?: number;
444
513
  maxReconnects?: number;
514
+ binaryType?: BinaryType;
445
515
  }): void;
446
516
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
447
517
  close(code?: number, reason?: string): void;
package/README.md CHANGED
@@ -50,12 +50,19 @@ When `<wcs-ws>` is connected to the DOM with a `url`, it automatically opens a W
50
50
  <script type="module" src="https://esm.run/@wcstack/websocket/auto"></script>
51
51
 
52
52
  <wcs-state>
53
- <script type="application/json">
54
- {
55
- "lastMessage": null,
56
- "isConnected": false,
57
- "isLoading": false
58
- }
53
+ <script type="module">
54
+ export default {
55
+ lastMessage: null,
56
+ isConnected: false,
57
+ isLoading: false,
58
+
59
+ get connectionLabel() {
60
+ return this.isConnected ? "Connected" : "Disconnected";
61
+ },
62
+ get lastMessageJson() {
63
+ return JSON.stringify(this.lastMessage, null, 2);
64
+ },
65
+ };
59
66
  </script>
60
67
 
61
68
  <wcs-ws
@@ -63,8 +70,8 @@ When `<wcs-ws>` is connected to the DOM with a `url`, it automatically opens a W
63
70
  data-wcs="message: lastMessage; connected: isConnected; loading: isLoading">
64
71
  </wcs-ws>
65
72
 
66
- <p data-wcs="textContent: isConnected|then('Connected','Disconnected')"></p>
67
- <pre data-wcs="textContent: lastMessage|json"></pre>
73
+ <p data-wcs="textContent: connectionLabel"></p>
74
+ <pre data-wcs="textContent: lastMessageJson"></pre>
68
75
  </wcs-state>
69
76
  ```
70
77
 
@@ -86,6 +93,9 @@ Use the `send` property to push data to the server. Setting `send` transmits the
86
93
  lastMessage: null,
87
94
  outgoing: null,
88
95
 
96
+ get lastMessageJson() {
97
+ return JSON.stringify(this.lastMessage, null, 2);
98
+ },
89
99
  sendChat() {
90
100
  this.outgoing = { type: "chat", content: this.chatInput };
91
101
  this.chatInput = "";
@@ -101,7 +111,7 @@ Use the `send` property to push data to the server. Setting `send` transmits the
101
111
  <input data-wcs="value: chatInput" placeholder="Type a message">
102
112
  <button data-wcs="onclick: sendChat">Send</button>
103
113
 
104
- <pre data-wcs="textContent: lastMessage|json"></pre>
114
+ <pre data-wcs="textContent: lastMessageJson"></pre>
105
115
  </wcs-state>
106
116
  ```
107
117
 
@@ -117,6 +127,9 @@ Use `manual` when you want to control when the connection opens.
117
127
  lastMessage: null,
118
128
  isConnected: false,
119
129
 
130
+ get connectionLabel() {
131
+ return this.isConnected ? "Connected" : "Disconnected";
132
+ },
120
133
  openConnection() {
121
134
  this.shouldConnect = true;
122
135
  },
@@ -130,7 +143,7 @@ Use `manual` when you want to control when the connection opens.
130
143
  </wcs-ws>
131
144
 
132
145
  <button data-wcs="onclick: openConnection">Connect</button>
133
- <p data-wcs="textContent: isConnected|then('Connected','Disconnected')"></p>
146
+ <p data-wcs="textContent: connectionLabel"></p>
134
147
  </wcs-state>
135
148
  ```
136
149
 
@@ -190,6 +203,61 @@ These properties control connection and messaging from HTML, JS, or `@wcstack/st
190
203
  | `send` | `any` | Set to transmit data (auto-stringifies objects) |
191
204
  | `manual` | `boolean` | Disables auto-connect on DOM attach |
192
205
 
206
+ ## CSS styling with `:state()`
207
+
208
+ `<wcs-ws>` reflects three boolean output states onto its
209
+ [`ElementInternals` `CustomStateSet`](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet),
210
+ so you can style it directly from CSS with the `:state()` pseudo-class — no
211
+ `data-wcs` binding or extra class toggling required.
212
+
213
+ | State | On when |
214
+ |-------|---------|
215
+ | `connected` | `wcs-ws:connected-changed` fires with `true` (cleared on `false`) |
216
+ | `loading` | `wcs-ws:loading-changed` fires with `true` (cleared on `false`) |
217
+ | `error` | `wcs-ws:error` fires with a non-`null` detail (cleared on `null`) |
218
+
219
+ ```css
220
+ wcs-ws:state(connected) ~ .indicator { color: green; }
221
+ wcs-ws:state(loading) ~ .indicator { color: orange; }
222
+
223
+ form:has(wcs-ws:state(error)) .banner { display: block; }
224
+ ```
225
+
226
+ Unlike attributes or classes, `:state()` cannot be written from outside the
227
+ element, so there is no risk of confusing this output state with an input.
228
+
229
+ **Browser support** (`:state(x)` syntax): Chrome/Edge 125+, Safari 17.4+,
230
+ Firefox 126+. In older browsers the states are simply never set — `:state()`
231
+ selectors never match, but `<wcs-ws>` itself keeps working normally
232
+ (graceful degradation, never-throw).
233
+
234
+ **SSR**: `:state()` cannot be serialized into HTML, so server-rendered markup
235
+ never carries these states on first paint (`@wcstack/server` is unaffected).
236
+ If you need to style the pre-hydration gap, pair your rule with
237
+ `wcs-ws:not(:defined)` instead.
238
+
239
+ ### Debugging
240
+
241
+ Custom states are invisible in DevTools' Elements panel and `attachInternals()`
242
+ cannot be called twice, so there is no console way to inspect them directly.
243
+ Two debug-only aids are provided for that:
244
+
245
+ - `el.debugStates` — a **snapshot** array of the currently-on state names
246
+ (e.g. `["connected"]`). It is not part of `wc-bindable` (not a bind target)
247
+ and its shape is not a guaranteed contract — use it for debugging only.
248
+ - The `debug-states` attribute (opt-in, default off) mirrors state changes
249
+ onto `data-wcs-state-connected` / `data-wcs-state-loading` /
250
+ `data-wcs-state-error` attributes on the element, so the Elements panel
251
+ highlights them as they toggle:
252
+
253
+ ```html
254
+ <wcs-ws url="wss://example.com/socket" debug-states></wcs-ws>
255
+ ```
256
+
257
+ **Write your CSS against `:state()`, not `data-wcs-state-*`.** The mirrored
258
+ attributes exist purely to make state changes visible while debugging with
259
+ DevTools open; they are not a supported styling hook.
260
+
193
261
  ## Architecture
194
262
 
195
263
  `@wcstack/websocket` follows the CSBC architecture.
@@ -310,6 +378,7 @@ In wcstack applications, **state-driven triggering via `trigger`** is usually th
310
378
  | `auto-reconnect` | `boolean` | `false` | Enable automatic reconnection |
311
379
  | `reconnect-interval` | `number` | `3000` | Reconnection delay in ms |
312
380
  | `max-reconnects` | `number` | `Infinity` | Maximum reconnection attempts |
381
+ | `binary-type` | `"blob" \| "arraybuffer"` | `blob` | How incoming binary frames are surfaced on `message`. Any value other than `arraybuffer` normalizes to `blob` |
313
382
 
314
383
  | Property | Type | Description |
315
384
  |----------|------|-------------|
@@ -318,6 +387,7 @@ In wcstack applications, **state-driven triggering via `trigger`** is usually th
318
387
  | `loading` | `boolean` | `true` while connecting |
319
388
  | `error` | `WcsWsError \| Event \| null` | Error info |
320
389
  | `readyState` | `number` | WebSocket readyState constant |
390
+ | `binaryType` | `"blob" \| "arraybuffer"` | Binary frame representation (backs the `binary-type` attribute; default `blob`) |
321
391
  | `trigger` | `boolean` | Set to `true` to open connection |
322
392
  | `send` | `any` | Set to transmit data |
323
393
 
@@ -380,6 +450,7 @@ static wcBindable = {
380
450
  { name: "autoReconnect", attribute: "auto-reconnect" },
381
451
  { name: "reconnectInterval", attribute: "reconnect-interval" },
382
452
  { name: "maxReconnects", attribute: "max-reconnects" },
453
+ { name: "binaryType", attribute: "binary-type" },
383
454
  { name: "manual", attribute: "manual" },
384
455
  { name: "trigger" },
385
456
  { name: "send" },
@@ -431,6 +502,7 @@ interface WcsWsInputs {
431
502
  autoReconnect: boolean;
432
503
  reconnectInterval: number;
433
504
  maxReconnects: number;
505
+ binaryType: BinaryType; // "blob" | "arraybuffer"
434
506
  manual: boolean;
435
507
  trigger: boolean;
436
508
  send: unknown;
@@ -442,6 +514,7 @@ interface WcsWsCoreCommands {
442
514
  autoReconnect?: boolean;
443
515
  reconnectInterval?: number;
444
516
  maxReconnects?: number;
517
+ binaryType?: BinaryType;
445
518
  }): void;
446
519
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
447
520
  close(code?: number, reason?: string): void;
package/dist/index.d.ts CHANGED
@@ -156,8 +156,12 @@ declare class WcsWebSocket extends HTMLElement {
156
156
  private _core;
157
157
  private _trigger;
158
158
  private _connectedCallbackPromise;
159
+ private _internals;
159
160
  constructor();
160
161
  get connectedCallbackPromise(): Promise<void>;
162
+ get debugStates(): string[];
163
+ private _initInternals;
164
+ private _wireStates;
161
165
  get url(): string;
162
166
  set url(value: string);
163
167
  get protocols(): string;
@@ -179,6 +183,7 @@ declare class WcsWebSocket extends HTMLElement {
179
183
  get readyState(): number;
180
184
  get trigger(): boolean;
181
185
  set trigger(value: boolean);
186
+ get send(): any;
182
187
  set send(data: any);
183
188
  connect(): void;
184
189
  sendMessage(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
package/dist/index.esm.js CHANGED
@@ -154,6 +154,14 @@ class WebSocketCore extends EventTarget {
154
154
  }));
155
155
  }
156
156
  _setError(error) {
157
+ // Same-value guard (async-io-node-guidelines.md §3.3). `error` is state-ish,
158
+ // so suppressing redundant null→null dispatches (every connect/send start
159
+ // clears a usually-already-null error) avoids a spurious wcs-ws:error per
160
+ // successful operation. Reference identity is sufficient: each failure builds
161
+ // a fresh object (or the platform's own error Event), and the clear path
162
+ // always passes null.
163
+ if (this._error === error)
164
+ return;
157
165
  this._error = error;
158
166
  this._target.dispatchEvent(new CustomEvent("wcs-ws:error", {
159
167
  detail: error,
@@ -381,13 +389,68 @@ class WcsWebSocket extends HTMLElement {
381
389
  _core;
382
390
  _trigger = false;
383
391
  _connectedCallbackPromise = Promise.resolve();
392
+ _internals = null;
384
393
  constructor() {
385
394
  super();
386
395
  this._core = new WebSocketCore(this);
396
+ this._internals = this._initInternals();
397
+ this._wireStates({
398
+ "wcs-ws:connected-changed": (d) => ({ connected: d === true }),
399
+ "wcs-ws:loading-changed": (d) => ({ loading: d === true }),
400
+ "wcs-ws:error": (d) => ({ error: d != null }),
401
+ });
387
402
  }
388
403
  get connectedCallbackPromise() {
389
404
  return this._connectedCallbackPromise;
390
405
  }
406
+ // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of
407
+ // wc-bindable (not a bind target); see README "CSS styling with :state()".
408
+ // MUST NOT return the live CustomStateSet (that would let callers write
409
+ // states from outside, defeating the point of :state() being read-only).
410
+ get debugStates() {
411
+ return this._internals ? [...this._internals.states] : [];
412
+ }
413
+ _initInternals() {
414
+ // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent
415
+ // in happy-dom / older environments, and pre-125 Chromium rejects
416
+ // non-dashed state names from states.add() (probed and discarded here).
417
+ // Either case silently disables reflection — the component still works,
418
+ // it just doesn't expose :state() selectors.
419
+ try {
420
+ if (typeof this.attachInternals !== "function")
421
+ return null;
422
+ const internals = this.attachInternals();
423
+ internals.states.add("wcs-probe");
424
+ internals.states.delete("wcs-probe");
425
+ return internals;
426
+ }
427
+ catch {
428
+ return null;
429
+ }
430
+ }
431
+ _wireStates(map) {
432
+ if (this._internals === null)
433
+ return;
434
+ const states = this._internals.states;
435
+ for (const [event, toStates] of Object.entries(map)) {
436
+ this.addEventListener(event, (e) => {
437
+ const debug = this.hasAttribute("debug-states");
438
+ for (const [name, on] of Object.entries(toStates(e.detail))) {
439
+ try {
440
+ if (on) {
441
+ states.add(name);
442
+ }
443
+ else {
444
+ states.delete(name);
445
+ }
446
+ }
447
+ catch { /* never-throw */ }
448
+ if (debug)
449
+ this.toggleAttribute(`data-wcs-state-${name}`, on);
450
+ }
451
+ });
452
+ }
453
+ }
391
454
  // --- Attribute accessors ---
392
455
  get url() {
393
456
  return this.getAttribute("url") || "";
@@ -484,6 +547,12 @@ class WcsWebSocket extends HTMLElement {
484
547
  }));
485
548
  }
486
549
  }
550
+ // `send` is a write-only command surface: assigning transmits immediately.
551
+ // Reading always returns null (no payload is retained) — consistent with the
552
+ // null carried by wcs-ws:send-changed and the documented "resets to null".
553
+ get send() {
554
+ return null;
555
+ }
487
556
  set send(data) {
488
557
  if (data === null || data === undefined)
489
558
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.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\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.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\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\" },\n { name: \"error\", event: \"wcs-ws:error\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\" },\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 _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 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 }\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 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 private _setError(error: any): void {\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\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.\" });\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.\" });\n return;\n }\n this._ws.send(data);\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);\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);\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","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.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\" },\n { name: \"send\", event: \"wcs-ws:send-changed\" },\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\n constructor() {\n super();\n this._core = new WebSocketCore(this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string) {\n this.setAttribute(\"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean) {\n if (value) {\n this.setAttribute(\"auto-reconnect\", \"\");\n } else {\n this.removeAttribute(\"auto-reconnect\");\n }\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) {\n this.setAttribute(\"reconnect-interval\", String(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) {\n this.setAttribute(\"max-reconnects\", String(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) {\n if (value == null) {\n this.removeAttribute(\"binary-type\");\n } else {\n this.setAttribute(\"binary-type\", value);\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\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 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 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 if (name === \"url\" && this.isConnected && !this.manual && newValue) {\n this.connect();\n }\n }\n\n connectedCallback(): void {\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 }\n\n disconnectedCallback(): void {\n // dispose() が _gen を bump して進行中のソケット/再接続を無効化し、close() する。\n this._core.dispose();\n }\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.ws)) {\n customElements.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): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"AAUA,MAAM,OAAO,GAAoB;AAC/B,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,gBAAgB,EAAE,eAAe;AACjC,IAAA,QAAQ,EAAE;AACR,QAAA,EAAE,EAAE,QAAQ;AACb,KAAA;CACF;AAED,SAAS,UAAU,CAAI,GAAM,EAAA;AAC3B,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,QAAA,OAAO,GAAG;AACvD,IAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IAClB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AAClC,QAAA,UAAU,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC;IACnD;AACA,IAAA,OAAO,GAAG;AACZ;AAEA,SAAS,SAAS,CAAI,GAAM,EAAA;AAC1B,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,QAAA,OAAO,GAAG;IACvD,MAAM,KAAK,GAA4B,EAAE;IACzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAClC,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC;IAC/D;AACA,IAAA,OAAO,KAAU;AACnB;AAEA,IAAI,YAAY,GAAmB,IAAI;AAEhC,MAAM,MAAM,GAAY,OAAkB;SAEjC,SAAS,GAAA;IACvB,IAAI,CAAC,YAAY,EAAE;QACjB,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/C;AACA,IAAA,OAAO,YAAY;AACrB;AAEM,SAAU,SAAS,CAAC,aAA8B,EAAA;AACtD,IAAA,IAAI,OAAO,aAAa,CAAC,WAAW,KAAK,SAAS,EAAE;AAClD,QAAA,OAAO,CAAC,WAAW,GAAG,aAAa,CAAC,WAAW;IACjD;AACA,IAAA,IAAI,OAAO,aAAa,CAAC,gBAAgB,KAAK,QAAQ,EAAE;AACtD,QAAA,OAAO,CAAC,gBAAgB,GAAG,aAAa,CAAC,gBAAgB;IAC3D;AACA,IAAA,IAAI,aAAa,CAAC,QAAQ,EAAE;QAC1B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;IACzD;IACA,YAAY,GAAG,IAAI;AACrB;;ACxDA;AACA;AACA;AACA;AACA,MAAM,aAAa,GAAG,CAAC;AACvB,MAAM,OAAO,GAAG,CAAC;AACjB,MAAM,SAAS,GAAG,CAAC;AAab,MAAO,aAAc,SAAQ,WAAW,CAAA;IAC5C,OAAO,UAAU,GAAgB;AAC/B,QAAA,QAAQ,EAAE,aAAa;AACvB,QAAA,OAAO,EAAE,CAAC;AACV,QAAA,UAAU,EAAE;AACV,YAAA,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,EAAE;AAC5C,YAAA,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,0BAA0B,EAAE;AACxD,YAAA,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE;AACpD,YAAA,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE;AACxC,YAAA,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,2BAA2B,EAAE;AAC3D,SAAA;AACD,QAAA,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,SAAS,EAAE;YACnB,EAAE,IAAI,EAAE,MAAM,EAAE;YAChB,EAAE,IAAI,EAAE,OAAO,EAAE;AAClB,SAAA;KACF;AAEO,IAAA,OAAO;IACP,GAAG,GAAqB,IAAI;IAC5B,QAAQ,GAAQ,IAAI;IACpB,UAAU,GAAY,KAAK;IAC3B,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAQ,IAAI;IAClB,WAAW,GAAW,SAAS;;IAG/B,cAAc,GAAY,KAAK;IAC/B,kBAAkB,GAAW,IAAI;IACjC,cAAc,GAAW,QAAQ;IACjC,eAAe,GAAW,CAAC;IAC3B,eAAe,GAAyC,IAAI;IAC5D,IAAI,GAAW,EAAE;IACjB,UAAU,GAAkC,SAAS;IACrD,WAAW,GAAe,MAAM;IAChC,iBAAiB,GAAY,KAAK;;;;;;IAOlC,IAAI,GAAG,CAAC;;;;IAIR,UAAU,GAAG,CAAC;;;AAGd,IAAA,MAAM,GAAkB,OAAO,CAAC,OAAO,EAAE;AAEjD,IAAA,WAAA,CAAY,MAAoB,EAAA;AAC9B,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,IAAI;IAC/B;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;;;;;IAMA,OAAO,GAAA;QACL,OAAO,IAAI,CAAC,MAAM;IACpB;IAEA,OAAO,GAAA;QACL,IAAI,CAAC,IAAI,EAAE;QACX,IAAI,CAAC,KAAK,EAAE;IACd;AAEA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO,IAAI,CAAC,QAAQ;IACtB;AAEA,IAAA,IAAI,SAAS,GAAA;QACX,OAAO,IAAI,CAAC,UAAU;IACxB;AAEA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO,IAAI,CAAC,QAAQ;IACtB;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,IAAI,UAAU,GAAA;QACZ,OAAO,IAAI,CAAC,WAAW;IACzB;;AAIQ,IAAA,WAAW,CAAC,OAAY,EAAA;AAC9B,QAAA,IAAI,CAAC,QAAQ,GAAG,OAAO;QACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,gBAAgB,EAAE;AAC3D,YAAA,MAAM,EAAE,OAAO;AACf,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,aAAa,CAAC,SAAkB,EAAA;AACtC,QAAA,IAAI,CAAC,UAAU,GAAG,SAAS;QAC3B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,0BAA0B,EAAE;AACrE,YAAA,MAAM,EAAE,SAAS;AACjB,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,WAAW,CAAC,OAAgB,EAAA;AAClC,QAAA,IAAI,CAAC,QAAQ,GAAG,OAAO;QACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,wBAAwB,EAAE;AACnE,YAAA,MAAM,EAAE,OAAO;AACf,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,SAAS,CAAC,KAAU,EAAA;AAC1B,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;QACnB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,cAAc,EAAE;AACzD,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,cAAc,CAAC,UAAkB,EAAA;AACvC,QAAA,IAAI,CAAC,WAAW,GAAG,UAAU;QAC7B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,2BAA2B,EAAE;AACtE,YAAA,MAAM,EAAE,UAAU;AAClB,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;;AAIA,IAAA,OAAO,CAAC,GAAW,EAAE,OAAA,GAAmC,EAAE,EAAA;;;;QAIxD,IAAI,CAAC,GAAG,EAAE;YACR,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC;YAC/C;QACF;;QAGA,IAAI,CAAC,IAAI,EAAE;;AAGX,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;QAC7B,IAAI,CAAC,cAAc,EAAE;AAErB,QAAA,IAAI,CAAC,IAAI,GAAG,GAAG;AACf,QAAA,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS;QACnC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,IAAI,KAAK;QACpD,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,IAAI,IAAI;QAC3D,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,IAAI,QAAQ;QACvD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,IAAI,MAAM;AAC/C,QAAA,IAAI,CAAC,eAAe,GAAG,CAAC;AACxB,QAAA,IAAI,CAAC,iBAAiB,GAAG,KAAK;QAE9B,IAAI,CAAC,UAAU,EAAE;IACnB;AAEA,IAAA,IAAI,CAAC,IAAuD,EAAA;;;AAG1D,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,KAAK,OAAO,EAAE;YAChD,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC;YAC1D;QACF;AACA,QAAA,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;IACrB;IAEA,KAAK,CAAC,IAAa,EAAE,MAAe,EAAA;AAClC,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;QAC7B,IAAI,CAAC,oBAAoB,EAAE;AAC3B,QAAA,IAAI,IAAI,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;QAC9B;IACF;;IAIQ,UAAU,GAAA;AAChB,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;;;AAKpB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI;AAE3B,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;kBACZ,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU;kBACxC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9B;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AACvB,YAAA,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACjB;QACF;;QAGA,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW;AAEtC,QAAA,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC;QAElC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC;IACnD;IAEQ,OAAO,GAAG,MAAW;AAC3B,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI;YAAE;AACnC,QAAA,IAAI,CAAC,eAAe,GAAG,CAAC;AACxB,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AACvB,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;AAC9B,IAAA,CAAC;AAEO,IAAA,UAAU,GAAG,CAAC,KAAmB,KAAU;AACjD,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI;YAAE;AACnC,QAAA,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI;;AAErB,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AAC5B,YAAA,IAAI;AACF,gBAAA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACzB;AAAE,YAAA,MAAM;;YAER;QACF;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AACxB,IAAA,CAAC;AAEO,IAAA,QAAQ,GAAG,CAAC,KAAY,KAAU;AACxC,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI;YAAE;AACnC,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACvB,IAAA,CAAC;AAEO,IAAA,QAAQ,GAAG,CAAC,KAAiB,KAAU;QAC7C,IAAI,CAAC,gBAAgB,EAAE;AACvB,QAAA,IAAI,CAAC,GAAG,GAAG,IAAI;AACf,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI;YAAE;AACnC,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AACvB,QAAA,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;;QAG9B,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,cAAc,EAAE;YACvH,IAAI,CAAC,kBAAkB,EAAE;QAC3B;AACF,IAAA,CAAC;IAEO,kBAAkB,GAAA;AACxB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI;QACrB,IAAI,CAAC,oBAAoB,EAAE;AAC3B,QAAA,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,MAAK;AACrC,YAAA,IAAI,CAAC,eAAe,GAAG,IAAI;;AAE3B,YAAA,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI;gBAAE;YACvB,IAAI,CAAC,eAAe,EAAE;YACtB,IAAI,CAAC,UAAU,EAAE;AACnB,QAAA,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC;IAC7B;IAEQ,oBAAoB,GAAA;AAC1B,QAAA,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,EAAE;AACjC,YAAA,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC;AAClC,YAAA,IAAI,CAAC,eAAe,GAAG,IAAI;QAC7B;IACF;IAEQ,gBAAgB,GAAA;AACtB,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACb;QACF;QAEA,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC;QAClD,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QACxD,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC;IACtD;IAEQ,cAAc,GAAA;QACpB,IAAI,CAAC,oBAAoB,EAAE;AAC3B,QAAA,IAAI,IAAI,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,gBAAgB,EAAE;AACvB,YAAA,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,KAAK,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,KAAK,aAAa,EAAE;AAC5E,gBAAA,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE;YAClB;AACA,YAAA,IAAI,CAAC,GAAG,GAAG,IAAI;QACjB;;AAEA,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE;AACnB,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAC3B;AACA,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE;AAClC,YAAA,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;QAChC;IACF;;;AChUF,IAAI,UAAU,GAAG,KAAK;AAEtB,SAAS,WAAW,CAAC,KAAY,EAAA;AAC/B,IAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;AAC3B,IAAA,IAAI,EAAE,MAAM,YAAY,OAAO,CAAC;QAAE;AAElC,IAAA,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAU,CAAA,CAAA,EAAI,MAAM,CAAC,gBAAgB,CAAA,CAAA,CAAG,CAAC;AAC9E,IAAA,IAAI,CAAC,cAAc;QAAE;IAErB,MAAM,IAAI,GAAG,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,gBAAgB,CAAC;AACjE,IAAA,IAAI,CAAC,IAAI;QAAE;;;;;;;AAQX,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACrD,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC;IAC/C,IAAI,CAAC,MAAM,IAAI,EAAE,SAAS,YAAY,MAAM,CAAC;QAAE;IAE/C,KAAK,CAAC,cAAc,EAAE;IACrB,SAA0B,CAAC,OAAO,EAAE;AACvC;SAEgB,mBAAmB,GAAA;AACjC,IAAA,IAAI,UAAU;QAAE;IAChB,UAAU,GAAG,IAAI;AACjB,IAAA,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC;AACjD;;AC5BM,MAAO,YAAa,SAAQ,WAAW,CAAA;AAC3C,IAAA,OAAO,2BAA2B,GAAG,IAAI;IACzC,OAAO,UAAU,GAAgB;QAC/B,GAAG,aAAa,CAAC,UAAU;AAC3B,QAAA,UAAU,EAAE;AACV,YAAA,GAAG,aAAa,CAAC,UAAU,CAAC,UAAU;AACtC,YAAA,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE;AACpD,YAAA,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE;AAC/C,SAAA;AACD,QAAA,MAAM,EAAE;AACN,YAAA,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE;AACjC,YAAA,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE;AAC7C,YAAA,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE;AACtD,YAAA,EAAE,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAE,oBAAoB,EAAE;AAC9D,YAAA,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE;AACtD,YAAA,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE;AAChD,YAAA,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE;YACvC,EAAE,IAAI,EAAE,SAAS,EAAE;YACnB,EAAE,IAAI,EAAE,MAAM,EAAE;AACjB,SAAA;AACD,QAAA,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,SAAS,EAAE;YACnB,EAAE,IAAI,EAAE,aAAa,EAAE;YACvB,EAAE,IAAI,EAAE,OAAO,EAAE;AAClB,SAAA;KACF;IACD,WAAW,kBAAkB,GAAA,EAAe,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAEpD,IAAA,KAAK;IACL,QAAQ,GAAY,KAAK;AACzB,IAAA,yBAAyB,GAAkB,OAAO,CAAC,OAAO,EAAE;AAEpE,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;QACP,IAAI,CAAC,KAAK,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC;IACtC;AAEA,IAAA,IAAI,wBAAwB,GAAA;QAC1B,OAAO,IAAI,CAAC,yBAAyB;IACvC;;AAIA,IAAA,IAAI,GAAG,GAAA;QACL,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;IACvC;IAEA,IAAI,GAAG,CAAC,KAAa,EAAA;AACnB,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IACjC;AAEA,IAAA,IAAI,SAAS,GAAA;QACX,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE;IAC7C;IAEA,IAAI,SAAS,CAAC,KAAa,EAAA;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,KAAK,CAAC;IACvC;AAEA,IAAA,IAAI,aAAa,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC;IAC5C;IAEA,IAAI,aAAa,CAAC,KAAc,EAAA;QAC9B,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,EAAE,CAAC;QACzC;aAAO;AACL,YAAA,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC;QACxC;IACF;AAEA,IAAA,IAAI,iBAAiB,GAAA;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC;AACpD,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI;AAC/C,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,MAAM;IAC7C;IAEA,IAAI,iBAAiB,CAAC,KAAa,EAAA;QACjC,IAAI,CAAC,YAAY,CAAC,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACxD;AAEA,IAAA,IAAI,aAAa,GAAA;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC;AAChD,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,QAAQ;AACnD,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,QAAQ,GAAG,MAAM;IACjD;IAEA,IAAI,aAAa,CAAC,KAAa,EAAA;QAC7B,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD;;;AAIA,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,KAAK,aAAa,GAAG,aAAa,GAAG,MAAM;IACpF;IAEA,IAAI,UAAU,CAAC,KAAoB,EAAA;AACjC,QAAA,IAAI,KAAK,IAAI,IAAI,EAAE;AACjB,YAAA,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC;QACrC;aAAO;AACL,YAAA,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC;QACzC;IACF;AAEA,IAAA,IAAI,MAAM,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;IACpC;IAEA,IAAI,MAAM,CAAC,KAAc,EAAA;QACvB,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;QACjC;aAAO;AACL,YAAA,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;QAChC;IACF;;AAIA,IAAA,IAAI,OAAO,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO;IAC3B;AAEA,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS;IAC7B;AAEA,IAAA,IAAI,OAAO,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO;IAC3B;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK;IACzB;AAEA,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU;IAC9B;;AAIA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO,IAAI,CAAC,QAAQ;IACtB;IAEA,IAAI,OAAO,CAAC,KAAc,EAAA;AACxB,QAAA,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK;QACjB,IAAI,CAAC,EAAE;AACL,YAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;YACpB,IAAI,CAAC,OAAO,EAAE;AACd,YAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;AACrB,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,wBAAwB,EAAE;AAC3D,gBAAA,MAAM,EAAE,KAAK;AACb,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA,CAAC,CAAC;QACL;IACF;IAEA,IAAI,IAAI,CAAC,IAAS,EAAA;AAChB,QAAA,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;YAAE;AACzC,QAAA,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AACtE,QAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;AACxB,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,qBAAqB,EAAE;AACxD,YAAA,MAAM,EAAE,IAAI;AACZ,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;;IAIA,OAAO,GAAA;AACL,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC;cACnB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO;cAC3D,SAAS;QAEb,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;AAC3B,YAAA,SAAS,EAAE,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS;YACzE,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,UAAU,EAAE,IAAI,CAAC,UAAU;AAC5B,SAAA,CAAC;IACJ;AAEA,IAAA,WAAW,CAAC,IAAuD,EAAA;AACjE,QAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IACvB;IAEA,KAAK,CAAC,IAAa,EAAE,MAAe,EAAA;QAClC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IAChC;;AAIA,IAAA,wBAAwB,CAAC,IAAY,EAAE,SAAwB,EAAE,QAAuB,EAAA;AACtF,QAAA,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE;YAClE,IAAI,CAAC,OAAO,EAAE;QAChB;IACF;IAEA,iBAAiB,GAAA;AACf,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;AAC3B,QAAA,IAAI,MAAM,CAAC,WAAW,EAAE;AACtB,YAAA,mBAAmB,EAAE;QACvB;;;QAGA,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;QACrD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,OAAO,EAAE;QAChB;IACF;IAEA,oBAAoB,GAAA;;AAElB,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;IACtB;;;SC1Nc,kBAAkB,GAAA;AAChC,IAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;QAC3C,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IACzD;AACF;;ACHM,SAAU,kBAAkB,CAAC,UAA4B,EAAA;IAC7D,IAAI,UAAU,EAAE;QACd,SAAS,CAAC,UAAU,CAAC;IACvB;AACA,IAAA,kBAAkB,EAAE;AACtB;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.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\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.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\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\" },\n { name: \"error\", event: \"wcs-ws:error\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\" },\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 _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 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 }\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 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 private _setError(error: any): 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 this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\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.\" });\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.\" });\n return;\n }\n this._ws.send(data);\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);\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);\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","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.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\" },\n { name: \"send\", event: \"wcs-ws:send-changed\" },\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\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 get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string) {\n this.setAttribute(\"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean) {\n if (value) {\n this.setAttribute(\"auto-reconnect\", \"\");\n } else {\n this.removeAttribute(\"auto-reconnect\");\n }\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) {\n this.setAttribute(\"reconnect-interval\", String(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) {\n this.setAttribute(\"max-reconnects\", String(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) {\n if (value == null) {\n this.removeAttribute(\"binary-type\");\n } else {\n this.setAttribute(\"binary-type\", value);\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\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 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 if (name === \"url\" && this.isConnected && !this.manual && newValue) {\n this.connect();\n }\n }\n\n connectedCallback(): void {\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 }\n\n disconnectedCallback(): void {\n // dispose() が _gen を bump して進行中のソケット/再接続を無効化し、close() する。\n this._core.dispose();\n }\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.ws)) {\n customElements.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): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e={autoTrigger:!0,triggerAttribute:"data-wstarget",tagNames:{ws:"wcs-ws"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const s of Object.keys(e))t(e[s]);return e}function s(e){if(null===e||"object"!=typeof e)return e;const t={};for(const n of Object.keys(e))t[n]=s(e[n]);return t}let n=null;const r=e;function i(){return n||(n=t(s(e))),n}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"message",event:"wcs-ws:message"},{name:"connected",event:"wcs-ws:connected-changed"},{name:"loading",event:"wcs-ws:loading-changed"},{name:"error",event:"wcs-ws:error"},{name:"readyState",event:"wcs-ws:readystate-changed"}],commands:[{name:"connect"},{name:"send"},{name:"close"}]};_target;_ws=null;_message=null;_connected=!1;_loading=!1;_error=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();constructor(e){super(),this._target=e??this}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.close()}get message(){return this._message}get connected(){return this._connected}get loading(){return this._loading}get error(){return this._error}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){this._error=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:error",{detail:e,bubbles:!0}))}_setReadyState(e){this._readyState=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:readystate-changed",{detail:e,bubbles:!0}))}connect(e,t={}){e?(this._gen++,this._intentionalClose=!0,this._closeInternal(),this._url=e,this._protocols=t.protocols,this._autoReconnect=t.autoReconnect??!1,this._reconnectInterval=t.reconnectInterval??3e3,this._maxReconnects=t.maxReconnects??1/0,this._binaryType=t.binaryType??"blob",this._reconnectCount=0,this._intentionalClose=!1,this._doConnect()):this._setError({message:"url is required."})}send(e){this._ws&&1===this._ws.readyState?this._ws.send(e):this._setError({message:"WebSocket is not connected."})}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)}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)};_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 c=!1;function a(e){const t=e.target;if(!(t instanceof Element))return;const s=t.closest(`[${r.triggerAttribute}]`);if(!s)return;const n=s.getAttribute(r.triggerAttribute);if(!n)return;const i=customElements.get(r.tagNames.ws),o=document.getElementById(n);i&&o instanceof i&&(e.preventDefault(),o.connect())}class h extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...o.wcBindable,properties:[...o.wcBindable.properties,{name:"trigger",event:"wcs-ws:trigger-changed"},{name:"send",event:"wcs-ws:send-changed"}],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();constructor(){super(),this._core=new o(this)}get connectedCallbackPromise(){return this._connectedCallbackPromise}get url(){return this.getAttribute("url")||""}set url(e){this.setAttribute("url",e)}get protocols(){return this.getAttribute("protocols")||""}set protocols(e){this.setAttribute("protocols",e)}get autoReconnect(){return this.hasAttribute("auto-reconnect")}set autoReconnect(e){e?this.setAttribute("auto-reconnect",""):this.removeAttribute("auto-reconnect")}get reconnectInterval(){const e=this.getAttribute("reconnect-interval"),t=e?parseInt(e,10):3e3;return Number.isNaN(t)?3e3:t}set reconnectInterval(e){this.setAttribute("reconnect-interval",String(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.setAttribute("max-reconnects",String(e))}get binaryType(){return"arraybuffer"===this.getAttribute("binary-type")?"arraybuffer":"blob"}set binaryType(e){null==e?this.removeAttribute("binary-type"):this.setAttribute("binary-type",e)}get manual(){return this.hasAttribute("manual")}set manual(e){e?this.setAttribute("manual",""):this.removeAttribute("manual")}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 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})))}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,s){"url"===e&&this.isConnected&&!this.manual&&s&&this.connect()}connectedCallback(){this.style.display="none",r.autoTrigger&&(c||(c=!0,document.addEventListener("click",a))),this._connectedCallbackPromise=this._core.observe(),!this.manual&&this.url&&this.connect()}disconnectedCallback(){this._core.dispose()}}function l(t){var s;t&&("boolean"==typeof(s=t).autoTrigger&&(e.autoTrigger=s.autoTrigger),"string"==typeof s.triggerAttribute&&(e.triggerAttribute=s.triggerAttribute),s.tagNames&&Object.assign(e.tagNames,s.tagNames),n=null),customElements.get(r.tagNames.ws)||customElements.define(r.tagNames.ws,h)}export{h as WcsWebSocket,o as WebSocketCore,l as bootstrapWebSocket,i as getConfig};
1
+ const e={autoTrigger:!0,triggerAttribute:"data-wstarget",tagNames:{ws:"wcs-ws"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const s of Object.keys(e))t(e[s]);return e}function s(e){if(null===e||"object"!=typeof e)return e;const t={};for(const n of Object.keys(e))t[n]=s(e[n]);return t}let n=null;const r=e;function i(){return n||(n=t(s(e))),n}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"message",event:"wcs-ws:message"},{name:"connected",event:"wcs-ws:connected-changed"},{name:"loading",event:"wcs-ws:loading-changed"},{name:"error",event:"wcs-ws:error"},{name:"readyState",event:"wcs-ws:readystate-changed"}],commands:[{name:"connect"},{name:"send"},{name:"close"}]};_target;_ws=null;_message=null;_connected=!1;_loading=!1;_error=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();constructor(e){super(),this._target=e??this}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.close()}get message(){return this._message}get connected(){return this._connected}get loading(){return this._loading}get error(){return this._error}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){this._error!==e&&(this._error=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:error",{detail:e,bubbles:!0})))}_setReadyState(e){this._readyState=e,this._target.dispatchEvent(new CustomEvent("wcs-ws:readystate-changed",{detail:e,bubbles:!0}))}connect(e,t={}){e?(this._gen++,this._intentionalClose=!0,this._closeInternal(),this._url=e,this._protocols=t.protocols,this._autoReconnect=t.autoReconnect??!1,this._reconnectInterval=t.reconnectInterval??3e3,this._maxReconnects=t.maxReconnects??1/0,this._binaryType=t.binaryType??"blob",this._reconnectCount=0,this._intentionalClose=!1,this._doConnect()):this._setError({message:"url is required."})}send(e){this._ws&&1===this._ws.readyState?this._ws.send(e):this._setError({message:"WebSocket is not connected."})}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)}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)};_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 c=!1;function a(e){const t=e.target;if(!(t instanceof Element))return;const s=t.closest(`[${r.triggerAttribute}]`);if(!s)return;const n=s.getAttribute(r.triggerAttribute);if(!n)return;const i=customElements.get(r.tagNames.ws),o=document.getElementById(n);i&&o instanceof i&&(e.preventDefault(),o.connect())}class h extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...o.wcBindable,properties:[...o.wcBindable.properties,{name:"trigger",event:"wcs-ws:trigger-changed"},{name:"send",event:"wcs-ws:send-changed"}],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;constructor(){super(),this._core=new o(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){this.setAttribute("url",e)}get protocols(){return this.getAttribute("protocols")||""}set protocols(e){this.setAttribute("protocols",e)}get autoReconnect(){return this.hasAttribute("auto-reconnect")}set autoReconnect(e){e?this.setAttribute("auto-reconnect",""):this.removeAttribute("auto-reconnect")}get reconnectInterval(){const e=this.getAttribute("reconnect-interval"),t=e?parseInt(e,10):3e3;return Number.isNaN(t)?3e3:t}set reconnectInterval(e){this.setAttribute("reconnect-interval",String(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.setAttribute("max-reconnects",String(e))}get binaryType(){return"arraybuffer"===this.getAttribute("binary-type")?"arraybuffer":"blob"}set binaryType(e){null==e?this.removeAttribute("binary-type"):this.setAttribute("binary-type",e)}get manual(){return this.hasAttribute("manual")}set manual(e){e?this.setAttribute("manual",""):this.removeAttribute("manual")}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 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,s){"url"===e&&this.isConnected&&!this.manual&&s&&this.connect()}connectedCallback(){this.style.display="none",r.autoTrigger&&(c||(c=!0,document.addEventListener("click",a))),this._connectedCallbackPromise=this._core.observe(),!this.manual&&this.url&&this.connect()}disconnectedCallback(){this._core.dispose()}}function l(t){var s;t&&("boolean"==typeof(s=t).autoTrigger&&(e.autoTrigger=s.autoTrigger),"string"==typeof s.triggerAttribute&&(e.triggerAttribute=s.triggerAttribute),s.tagNames&&Object.assign(e.tagNames,s.tagNames),n=null),customElements.get(r.tagNames.ws)||customElements.define(r.tagNames.ws,h)}export{h as WcsWebSocket,o as WebSocketCore,l as bootstrapWebSocket,i as getConfig};
2
2
  //# sourceMappingURL=index.esm.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.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\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.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\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\" },\n { name: \"error\", event: \"wcs-ws:error\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\" },\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 _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 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 }\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 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 private _setError(error: any): void {\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\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.\" });\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.\" });\n return;\n }\n this._ws.send(data);\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);\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);\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","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.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\" },\n { name: \"send\", event: \"wcs-ws:send-changed\" },\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\n constructor() {\n super();\n this._core = new WebSocketCore(this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string) {\n this.setAttribute(\"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean) {\n if (value) {\n this.setAttribute(\"auto-reconnect\", \"\");\n } else {\n this.removeAttribute(\"auto-reconnect\");\n }\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) {\n this.setAttribute(\"reconnect-interval\", String(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) {\n this.setAttribute(\"max-reconnects\", String(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) {\n if (value == null) {\n this.removeAttribute(\"binary-type\");\n } else {\n this.setAttribute(\"binary-type\", value);\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\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 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 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 if (name === \"url\" && this.isConnected && !this.manual && newValue) {\n this.connect();\n }\n }\n\n connectedCallback(): void {\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 }\n\n disconnectedCallback(): void {\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): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.ws)) {\n customElements.define(config.tagNames.ws, WcsWebSocket);\n }\n}\n"],"names":["_config","autoTrigger","triggerAttribute","tagNames","ws","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","WebSocketCore","EventTarget","static","protocol","version","properties","name","event","commands","_target","_ws","_message","_connected","_loading","_error","_readyState","_autoReconnect","_reconnectInterval","_maxReconnects","Infinity","_reconnectCount","_reconnectTimer","_url","_protocols","undefined","_binaryType","_intentionalClose","_gen","_socketGen","_ready","Promise","resolve","constructor","target","super","this","ready","observe","dispose","close","message","connected","loading","error","readyState","_setMessage","dispatchEvent","CustomEvent","detail","bubbles","_setConnected","_setLoading","_setError","_setReadyState","connect","url","options","_closeInternal","protocols","autoReconnect","reconnectInterval","maxReconnects","binaryType","_doConnect","send","data","code","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","WcsWebSocket","HTMLElement","wcBindable","inputs","attribute","observedAttributes","_core","_trigger","_connectedCallbackPromise","connectedCallbackPromise","value","setAttribute","hasAttribute","removeAttribute","attr","parsed","parseInt","Number","isNaN","String","manual","trigger","payload","stringify","split","map","p","trim","filter","Boolean","length","sendMessage","attributeChangedCallback","_oldValue","newValue","isConnected","connectedCallback","style","display","disconnectedCallback","bootstrapWebSocket","userConfig","partialConfig","assign","define"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/WebSocketCore.ts","../src/autoTrigger.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\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.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\" },\n { name: \"connected\", event: \"wcs-ws:connected-changed\" },\n { name: \"loading\", event: \"wcs-ws:loading-changed\" },\n { name: \"error\", event: \"wcs-ws:error\" },\n { name: \"readyState\", event: \"wcs-ws:readystate-changed\" },\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 _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 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 }\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 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 private _setError(error: any): 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 this._target.dispatchEvent(new CustomEvent(\"wcs-ws:error\", {\n detail: error,\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.\" });\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.\" });\n return;\n }\n this._ws.send(data);\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);\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);\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","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { WebSocketCore } from \"../core/WebSocketCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.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\" },\n { name: \"send\", event: \"wcs-ws:send-changed\" },\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\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 get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get protocols(): string {\n return this.getAttribute(\"protocols\") || \"\";\n }\n\n set protocols(value: string) {\n this.setAttribute(\"protocols\", value);\n }\n\n get autoReconnect(): boolean {\n return this.hasAttribute(\"auto-reconnect\");\n }\n\n set autoReconnect(value: boolean) {\n if (value) {\n this.setAttribute(\"auto-reconnect\", \"\");\n } else {\n this.removeAttribute(\"auto-reconnect\");\n }\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) {\n this.setAttribute(\"reconnect-interval\", String(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) {\n this.setAttribute(\"max-reconnects\", String(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) {\n if (value == null) {\n this.removeAttribute(\"binary-type\");\n } else {\n this.setAttribute(\"binary-type\", value);\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\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 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 if (name === \"url\" && this.isConnected && !this.manual && newValue) {\n this.connect();\n }\n }\n\n connectedCallback(): void {\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 }\n\n disconnectedCallback(): void {\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): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsWebSocket } from \"./components/WebSocket.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.ws)) {\n customElements.define(config.tagNames.ws, WcsWebSocket);\n }\n}\n"],"names":["_config","autoTrigger","triggerAttribute","tagNames","ws","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","WebSocketCore","EventTarget","static","protocol","version","properties","name","event","commands","_target","_ws","_message","_connected","_loading","_error","_readyState","_autoReconnect","_reconnectInterval","_maxReconnects","Infinity","_reconnectCount","_reconnectTimer","_url","_protocols","undefined","_binaryType","_intentionalClose","_gen","_socketGen","_ready","Promise","resolve","constructor","target","super","this","ready","observe","dispose","close","message","connected","loading","error","readyState","_setMessage","dispatchEvent","CustomEvent","detail","bubbles","_setConnected","_setLoading","_setError","_setReadyState","connect","url","options","_closeInternal","protocols","autoReconnect","reconnectInterval","maxReconnects","binaryType","_doConnect","send","data","code","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","WcsWebSocket","HTMLElement","wcBindable","inputs","attribute","observedAttributes","_core","_trigger","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","connectedCallbackPromise","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","value","setAttribute","removeAttribute","attr","parsed","parseInt","Number","isNaN","String","manual","trigger","payload","stringify","split","p","trim","filter","Boolean","length","sendMessage","attributeChangedCallback","_oldValue","newValue","isConnected","connectedCallback","style","display","disconnectedCallback","bootstrapWebSocket","userConfig","partialConfig","assign","define"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/websocket",
3
- "version": "1.15.0",
3
+ "version": "1.17.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",