@wcstack/network 1.22.5 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.ja.md +7 -19
  2. package/README.md +7 -19
  3. package/package.json +1 -1
package/README.ja.md CHANGED
@@ -52,11 +52,6 @@ npm install @wcstack/network
52
52
  get imgSrc() {
53
53
  return this.lowQuality ? "/thumb.jpg" : "/full.jpg";
54
54
  },
55
- // 初回スナップショットはバインド確立前に発火するため、一度だけ pull する(「注意・制限」参照)。
56
- async $connectedCallback() {
57
- await customElements.whenDefined("wcs-network");
58
- this.effectiveType = document.querySelector("wcs-network").effectiveType;
59
- },
60
55
  };
61
56
  </script>
62
57
  </wcs-state>
@@ -66,7 +61,7 @@ npm install @wcstack/network
66
61
  <img data-wcs="attr.src: imgSrc">
67
62
  ```
68
63
 
69
- このページの全例に共通するタイミング規則が1つあります: `<wcs-network>` はスナップショットを `wcs-network:change` イベントで公開しますが、*初回*のスナップショットは接続時に同期発火するため、`@wcstack/state` がバインドリスナーを張るより先に流れてしまい、バインドしたパスは*次*の回線変化からしか更新されません。上の `$connectedCallback` ブロックはその初回スナップショットを一度だけ pull しています。これが無いと、読込時点で既に低速回線だった場合にページが適応しません(「注意・制限」参照)。
64
+ このページの全例に共通するタイミング規則が1つあります: `<wcs-network>` はスナップショットを `wcs-network:change` イベントで公開しますが、*初回*のスナップショットは接続時に同期発火するため、`@wcstack/state` がバインドリスナーを張るより先に流れてしまいます。それでも初期値が届くのは、`<wcs-network>` の観測可能プロパティがすべて output-only(`properties` にのみ宣言され `inputs` に無い)だからです — 既定の binding authority が `element` になり、バインド確立時に**イベントを待たずプロパティを直接読みます**(directional initial sync、v1.21.0 以降は既定 ON)。手動 pull は不要です(「注意・制限」参照)。
70
65
 
71
66
  ### 2. データセーバーを尊重する
72
67
 
@@ -74,12 +69,9 @@ npm install @wcstack/network
74
69
  <wcs-state>
75
70
  <script type="module">
76
71
  export default {
72
+ // 読込時点で既にデータセーバーONでも、初期スナップショットが
73
+ // バインド確立時に pull されるので追加の配線は要りません。
77
74
  saveData: null,
78
- // 例1と同じ初期 pull — 読込時点で既にデータセーバーONの場合があるため。
79
- async $connectedCallback() {
80
- await customElements.whenDefined("wcs-network");
81
- this.saveData = document.querySelector("wcs-network").saveData;
82
- },
83
75
  };
84
76
  </script>
85
77
  </wcs-state>
@@ -98,12 +90,6 @@ npm install @wcstack/network
98
90
  export default {
99
91
  netSupported: false,
100
92
  effectiveType: null,
101
- async $connectedCallback() {
102
- await customElements.whenDefined("wcs-network");
103
- const net = document.querySelector("wcs-network");
104
- this.netSupported = net.supported;
105
- this.effectiveType = net.effectiveType;
106
- },
107
93
  };
108
94
  </script>
109
95
  </wcs-state>
@@ -112,7 +98,7 @@ npm install @wcstack/network
112
98
  <div data-wcs="hidden: netSupported|not">回線: <span data-wcs="textContent: effectiveType"></span></div>
113
99
  ```
114
100
 
115
- バインドする state パスは必ず事前に宣言してください — 未宣言パスへのバインドは初期化時に例外になります。例2の `saveData` と異なり `supported` は厳密な boolean(`null` になり得ない)なので、ここでは `|not` が安全です。この例では初期 pull が*必須*です: `supported` は接続時に一度だけ確定し、安定した回線では以後 `change` が二度と発火しないため、pull が無いと対応ブラウザでも UI が永久に隠れたままになります。非対応ブラウザでは pull が `false` を読むだけなので、UI はそのまま隠れ続けます。
101
+ バインドする state パスは必ず事前に宣言してください — 未宣言パスへのバインドは初期化時に例外になります。例2の `saveData` と異なり `supported` は厳密な boolean(`null` になり得ない)なので、ここでは `|not` が安全です。この例は初期スナップショットの pull に**最も強く依存**します: `supported` は接続時に一度だけ確定し、安定した回線では以後 `change` が二度と発火しないため、バインド確立時の pull が唯一の到達経路です(実ブラウザ回帰 = `e2e/tests/monitor-initial-snapshot.spec.ts`)。非対応ブラウザでは pull が `false` を読むだけなので、UI はそのまま隠れ続けます。
116
102
 
117
103
  ## 観測可能プロパティ(出力)
118
104
 
@@ -139,7 +125,7 @@ npm install @wcstack/network
139
125
  ## 注意・制限
140
126
 
141
127
  - **Firefox と Safari は `navigator.connection` を実装していません。** これらのブラウザでは `supported` は `false` のまま、他の4プロパティは `null` のままです — これを例外ケースでなく常態として設計してください。
142
- - **初回スナップショットはバインドに届きません。** 最初の `wcs-network:change` は `connectedCallback` 中に同期発火しますが、`@wcstack/state` のバインドリスナー確立はそれより後です(バインド構築は後続の microtask に遅延 — `docs/timing-and-firing-contract.md` §4.1 参照)。イベントは後から購読した相手に再送されないため、バインドしたパスは*次*の回線変化からしか更新されません。初期値が重要な場合(`supported` `saveData` ではほぼ常に重要)は、クイックスタートの各例のように `$connectedCallback` で一度だけ pull してください。これは全 monitor ノード共通の wc-bindable イベント契約の性質であり、本パッケージ固有の癖ではありません。
128
+ - **初回スナップショットの*イベント*はバインドに届きませんが、値は届きます。** 最初の `wcs-network:change` は `connectedCallback` 中に同期発火しますが、`@wcstack/state` のバインドリスナー確立はそれより後です(バインド構築は後続の microtask に遅延 — `docs/timing-and-firing-contract.md` §4.1 参照)。イベントは後から購読した相手に再送されません。それでも初期値が失われないのは、本ノードの観測可能プロパティがすべて output-only(`properties` のみ・`inputs` に無い)で、既定の binding authority が `element` になるためです: バインドは確立時にプロパティを直接読みます(directional initial sync、v1.21.0 以降は既定 ON)。手動 pull は不要で、これは全 monitor ノード共通の挙動です。`enableDirectionalInitialSync: false` に倒した構成でのみ、`$connectedCallback` + `whenDefined` での手動 pull が再び必要になります。
143
129
  - **`_gen` 世代ガードが無い。** 他の大半の wcstack IO ノードと異なり、`navigator.connection` の `change` イベント購読・購読解除は完全に同期的です。dispose() とレースしうる非同期probeの解決が存在しません。詳細は `docs/network-tag-design.md` §5。
144
130
  - **再接続で再購読。** 要素を取り外して再挿入すると、切断時に `change` リスナーを解除し、再接続時に(その時点の `navigator.connection` に対して)再確立します。
145
131
  - **SSR(`@wcstack/server`)。** `static hasConnectedCallbackPromise = true` を宣言し `connectedCallbackPromise` を公開しますが、`observe()` が同期的なため、この promise は常に即座に settle します。
@@ -217,6 +203,8 @@ console.log(net.effectiveType);
217
203
  net.dispose(); // live な `change` リスナーを外す
218
204
  ```
219
205
 
206
+ Core の構造サーフェスは wcstack I/O ノード横断の規範です([async-io-node-guidelines §3.9](../../docs/async-io-node-guidelines.md))。要素なしで signals に束縛するには [@wcstack/signals — Core を直接束縛する](../signals/README.ja.md#core-を直接束縛する要素なし) を参照。
207
+
220
208
  ## ライセンス
221
209
 
222
210
  MIT
package/README.md CHANGED
@@ -52,11 +52,6 @@ npm install @wcstack/network
52
52
  get imgSrc() {
53
53
  return this.lowQuality ? "/thumb.jpg" : "/full.jpg";
54
54
  },
55
- // The initial snapshot fires before bindings attach — pull it once (see Notes).
56
- async $connectedCallback() {
57
- await customElements.whenDefined("wcs-network");
58
- this.effectiveType = document.querySelector("wcs-network").effectiveType;
59
- },
60
55
  };
61
56
  </script>
62
57
  </wcs-state>
@@ -66,7 +61,7 @@ npm install @wcstack/network
66
61
  <img data-wcs="attr.src: imgSrc">
67
62
  ```
68
63
 
69
- One timing rule applies to every example on this page: `<wcs-network>` publishes its snapshot through `wcs-network:change` events, and the *first* snapshot fires synchronously at connect — before `@wcstack/state` has attached its binding listeners so bound paths only start updating from the *next* connection change. The `$connectedCallback` block pulls that initial snapshot once; without it, this page would not adapt when the connection is already slow at load time (see Notes & limitations).
64
+ One timing rule applies to every example on this page: `<wcs-network>` publishes its snapshot through `wcs-network:change` events, and the *first* snapshot fires synchronously at connect — before `@wcstack/state` has attached its binding listeners. The initial value still arrives, because every observable property on `<wcs-network>` is output-only (declared in `properties`, absent from `inputs`): that makes the default binding authority `element`, so the binding **reads the property directly when it attaches** instead of waiting for an event it already missed (directional initial sync, on by default since v1.21.0). No manual pull is needed (see Notes & limitations).
70
65
 
71
66
  ### 2. Respect Data Saver
72
67
 
@@ -74,12 +69,9 @@ One timing rule applies to every example on this page: `<wcs-network>` publishes
74
69
  <wcs-state>
75
70
  <script type="module">
76
71
  export default {
72
+ // Data Saver may already be on at load time; the initial snapshot is
73
+ // pulled when the binding attaches, so no extra wiring is needed.
77
74
  saveData: null,
78
- // Initial pull, as in example 1 — Data Saver may already be on at load time.
79
- async $connectedCallback() {
80
- await customElements.whenDefined("wcs-network");
81
- this.saveData = document.querySelector("wcs-network").saveData;
82
- },
83
75
  };
84
76
  </script>
85
77
  </wcs-state>
@@ -98,12 +90,6 @@ One timing rule applies to every example on this page: `<wcs-network>` publishes
98
90
  export default {
99
91
  netSupported: false,
100
92
  effectiveType: null,
101
- async $connectedCallback() {
102
- await customElements.whenDefined("wcs-network");
103
- const net = document.querySelector("wcs-network");
104
- this.netSupported = net.supported;
105
- this.effectiveType = net.effectiveType;
106
- },
107
93
  };
108
94
  </script>
109
95
  </wcs-state>
@@ -112,7 +98,7 @@ One timing rule applies to every example on this page: `<wcs-network>` publishes
112
98
  <div data-wcs="hidden: netSupported|not">Connection: <span data-wcs="textContent: effectiveType"></span></div>
113
99
  ```
114
100
 
115
- Every bound state path must be declared up front — binding an undeclared path throws at initialization. Unlike `saveData` above, `supported` is a strict boolean (never `null`), so `|not` is safe here. The initial pull is *essential* in this example: `supported` is set exactly once at connect, and a stable connection never fires another `change` without the pull the UI would stay hidden forever even in supporting browsers. In an unsupported browser the pull reads `false`, so the UI simply stays hidden.
101
+ Every bound state path must be declared up front — binding an undeclared path throws at initialization. Unlike `saveData` above, `supported` is a strict boolean (never `null`), so `|not` is safe here. This example leans hardest on the initial snapshot pull: `supported` is set exactly once at connect and a stable connection never fires another `change`, so the read at binding-attach time is its only delivery path (real-browser regression: `e2e/tests/monitor-initial-snapshot.spec.ts`). In an unsupported browser that read returns `false`, so the UI simply stays hidden.
116
102
 
117
103
  ## Observable Properties (outputs)
118
104
 
@@ -139,7 +125,7 @@ All five derive from the single `wcs-network:change` event (a full snapshot disp
139
125
  ## Notes & limitations
140
126
 
141
127
  - **Firefox and Safari do not implement `navigator.connection`.** `supported` stays `false` and the other four properties stay `null` in those browsers — design around this as the common case, not an edge case.
142
- - **The initial snapshot does not reach bindings.** The first `wcs-network:change` fires synchronously during `connectedCallback` — before `@wcstack/state` attaches its binding listeners (binding setup is deferred to a later microtask; see `docs/timing-and-firing-contract.md` §4.1) — and events are not replayed to late subscribers, so bound paths update only from the *next* connection change. If the initial value matters (it almost always does for `supported` and `saveData`), pull it once in `$connectedCallback` as the Quick Start examples do. This is a property of the wc-bindable event contract shared by all monitor nodes, not a quirk of this package.
128
+ - **The initial snapshot *event* misses bindings, but the value still arrives.** The first `wcs-network:change` fires synchronously during `connectedCallback` — before `@wcstack/state` attaches its binding listeners (binding setup is deferred to a later microtask; see `docs/timing-and-firing-contract.md` §4.1) — and events are not replayed to late subscribers. The value is not lost, because every observable property here is output-only (`properties` only, never `inputs`), which makes the default binding authority `element`: the binding reads the property directly when it attaches (directional initial sync, on by default since v1.21.0). No manual pull is needed, and this holds for every monitor node. Only if you explicitly set `enableDirectionalInitialSync: false` do you need the older `$connectedCallback` + `whenDefined` pull again.
143
129
  - **No `_gen` generation guard.** Unlike most wcstack IO nodes, subscribing to `navigator.connection`'s `change` event is fully synchronous — there is no asynchronous probe whose stale resolution could race a `dispose()`. See `docs/network-tag-design.md` §5.
144
130
  - **Reconnect re-subscribes.** Removing and re-inserting the element tears down the `change` listener on disconnect and re-establishes it (against whatever `navigator.connection` currently is) on reconnect.
145
131
  - **SSR (`@wcstack/server`).** Declares `static hasConnectedCallbackPromise = true` and exposes `connectedCallbackPromise`, though since `observe()` is synchronous this promise always settles immediately.
@@ -219,6 +205,8 @@ console.log(net.effectiveType);
219
205
  net.dispose(); // detach the live `change` listener
220
206
  ```
221
207
 
208
+ The structural Core surface is normative across wcstack IO nodes ([async-io-node-guidelines §3.9](../../docs/async-io-node-guidelines.md)); to bind it into signals with no element at all, see [@wcstack/signals — Binding a Core directly](../signals/README.md#binding-a-core-directly-no-element).
209
+
222
210
  ## License
223
211
 
224
212
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/network",
3
- "version": "1.22.5",
3
+ "version": "1.23.0",
4
4
  "description": "Declarative Network Information component for Web Components. Framework-agnostic navigator.connection monitor via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",