@wcstack/network 1.16.0 → 1.18.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 +53 -0
- package/README.md +55 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +56 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -143,6 +143,59 @@ npm install @wcstack/network
|
|
|
143
143
|
- **SSR(`@wcstack/server`)。** `static hasConnectedCallbackPromise = true` を宣言し `connectedCallbackPromise` を公開しますが、`observe()` が同期的なため、この promise は常に即座に settle します。
|
|
144
144
|
- **同値ガード。** ブラウザが万一同じ値で `change` を重複発火しても、フィールド単位の防御的比較により冗長な dispatch を抑止します。
|
|
145
145
|
|
|
146
|
+
## `:state()` による CSS スタイリング
|
|
147
|
+
|
|
148
|
+
`<wcs-network>` は 2 つの boolean 出力ステートを
|
|
149
|
+
[`ElementInternals` の `CustomStateSet`](https://developer.mozilla.org/ja/docs/Web/API/CustomStateSet)
|
|
150
|
+
に反映します。そのため `data-wcs` バインディングやクラスの手動トグルなしに、CSS の
|
|
151
|
+
`:state()` 疑似クラスで直接スタイリングできます。
|
|
152
|
+
|
|
153
|
+
| ステート | on になる条件 |
|
|
154
|
+
|----------|----------------|
|
|
155
|
+
| `save-data` | `wcs-network:change` が `saveData === true` で発火(`saveData` が `null`=非対応の場合も含め off) |
|
|
156
|
+
| `supported` | `wcs-network:change` が `supported === true` で発火(`supported === false` で off) |
|
|
157
|
+
|
|
158
|
+
`effectiveType` / `downlink` / `rtt` は反映されません — 理由は `docs/custom-state-reflection-design.md` §3.2(連続値・高頻度値は `:state()` 反映の対象外)を参照してください。
|
|
159
|
+
|
|
160
|
+
```css
|
|
161
|
+
wcs-network:state(supported) ~ .connection-badge { display: block; }
|
|
162
|
+
wcs-network:not(:state(supported)) ~ .connection-badge { display: none; } /* デフォルト */
|
|
163
|
+
|
|
164
|
+
form:has(wcs-network:state(save-data)) .low-res-hint { display: block; }
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
属性やクラスと異なり `:state()` は要素の外部から書き込めないため、この出力ステートが
|
|
168
|
+
入力と混同される心配がありません。
|
|
169
|
+
|
|
170
|
+
**対応ブラウザ**(新構文 `:state(x)`): Chrome/Edge 125+、Safari 17.4+、Firefox 126+。
|
|
171
|
+
非対応の環境ではステートが一切 set されないだけです — `:state()` セレクタがマッチしなく
|
|
172
|
+
なりますが、`<wcs-network>` 自体は通常どおり動作し続けます(graceful degradation・never-throw)。
|
|
173
|
+
|
|
174
|
+
**SSR:** `:state()` は HTML にシリアライズできないため、サーバーレンダリングされた
|
|
175
|
+
マークアップの初期ペイントにはこれらのステートは乗りません(`@wcstack/server` は無改変)。
|
|
176
|
+
ハイドレーション前の見た目を制御したい場合は、代わりに `wcs-network:not(:defined)` と組み合わせてください。
|
|
177
|
+
|
|
178
|
+
### デバッグ
|
|
179
|
+
|
|
180
|
+
カスタムステートは DevTools の Elements パネルには表示されず、`attachInternals()`
|
|
181
|
+
は同一要素に 2 回呼べないため、コンソールから直接覗く手段がありません。そのための
|
|
182
|
+
デバッグ専用の補助を 2 つ用意しています:
|
|
183
|
+
|
|
184
|
+
- `el.debugStates` — 現在 on になっているステート名の**スナップショット**配列
|
|
185
|
+
(例: `["supported"]`)。`wc-bindable` の一部ではなく(バインド対象ではない)、
|
|
186
|
+
形状も契約として保証されません — デバッグ用途にのみ使ってください。
|
|
187
|
+
- `debug-states` 属性(opt-in・既定 OFF)は、ステート変化を要素の
|
|
188
|
+
`data-wcs-state-save-data` / `data-wcs-state-supported` 属性にミラーします。
|
|
189
|
+
Elements パネルを開いておけば、トグルのたびにハイライトされます:
|
|
190
|
+
|
|
191
|
+
```html
|
|
192
|
+
<wcs-network debug-states></wcs-network>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**CSS は `data-wcs-state-*` ではなく `:state()` に書いてください。** ミラーされた
|
|
196
|
+
属性は、DevTools を開いた状態でステート変化を可視化するためだけのものであり、
|
|
197
|
+
スタイリング用の正式なフックではありません。
|
|
198
|
+
|
|
146
199
|
## ヘッドレス利用(`NetworkCore`)
|
|
147
200
|
|
|
148
201
|
Core は DOM 非依存で、`@wc-bindable/core` の `bind()` と直接使えます:
|
package/README.md
CHANGED
|
@@ -143,6 +143,61 @@ All five derive from the single `wcs-network:change` event (a full snapshot disp
|
|
|
143
143
|
- **SSR (`@wcstack/server`).** Declares `static hasConnectedCallbackPromise = true` and exposes `connectedCallbackPromise`, though since `observe()` is synchronous this promise always settles immediately.
|
|
144
144
|
- **Same-value guard.** A defensive field-by-field comparison suppresses a redundant `change` dispatch if the browser were ever to fire `change` with identical values.
|
|
145
145
|
|
|
146
|
+
## CSS styling with `:state()`
|
|
147
|
+
|
|
148
|
+
`<wcs-network>` reflects two boolean output states onto its
|
|
149
|
+
[`ElementInternals` `CustomStateSet`](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet),
|
|
150
|
+
so you can style it directly from CSS with the `:state()` pseudo-class — no
|
|
151
|
+
`data-wcs` binding or extra class toggling required.
|
|
152
|
+
|
|
153
|
+
| State | On when |
|
|
154
|
+
|-------|---------|
|
|
155
|
+
| `save-data` | `wcs-network:change` fires with `saveData === true` (off — including when `saveData` is `null`, i.e. unsupported) |
|
|
156
|
+
| `supported` | `wcs-network:change` fires with `supported === true` (off when `supported === false`) |
|
|
157
|
+
|
|
158
|
+
`effectiveType` / `downlink` / `rtt` are not reflected — see `docs/custom-state-reflection-design.md` §3.2 (continuous/high-frequency values are excluded from `:state()` reflection).
|
|
159
|
+
|
|
160
|
+
```css
|
|
161
|
+
wcs-network:state(supported) ~ .connection-badge { display: block; }
|
|
162
|
+
wcs-network:not(:state(supported)) ~ .connection-badge { display: none; } /* default */
|
|
163
|
+
|
|
164
|
+
form:has(wcs-network:state(save-data)) .low-res-hint { display: block; }
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Unlike attributes or classes, `:state()` cannot be written from outside the
|
|
168
|
+
element, so there is no risk of confusing this output state with an input.
|
|
169
|
+
|
|
170
|
+
**Browser support** (`:state(x)` syntax): Chrome/Edge 125+, Safari 17.4+,
|
|
171
|
+
Firefox 126+. In older browsers the states are simply never set — `:state()`
|
|
172
|
+
selectors never match, but `<wcs-network>` itself keeps working normally
|
|
173
|
+
(graceful degradation, never-throw).
|
|
174
|
+
|
|
175
|
+
**SSR**: `:state()` cannot be serialized into HTML, so server-rendered markup
|
|
176
|
+
never carries these states on first paint (`@wcstack/server` is unaffected).
|
|
177
|
+
If you need to style the pre-hydration gap, pair your rule with
|
|
178
|
+
`wcs-network:not(:defined)` instead.
|
|
179
|
+
|
|
180
|
+
### Debugging
|
|
181
|
+
|
|
182
|
+
Custom states are invisible in DevTools' Elements panel and `attachInternals()`
|
|
183
|
+
cannot be called twice, so there is no console way to inspect them directly.
|
|
184
|
+
Two debug-only aids are provided for that:
|
|
185
|
+
|
|
186
|
+
- `el.debugStates` — a **snapshot** array of the currently-on state names
|
|
187
|
+
(e.g. `["supported"]`). It is not part of `wc-bindable` (not a bind target)
|
|
188
|
+
and its shape is not a guaranteed contract — use it for debugging only.
|
|
189
|
+
- The `debug-states` attribute (opt-in, default off) mirrors state changes
|
|
190
|
+
onto `data-wcs-state-save-data` / `data-wcs-state-supported` attributes on
|
|
191
|
+
the element, so the Elements panel highlights them as they toggle:
|
|
192
|
+
|
|
193
|
+
```html
|
|
194
|
+
<wcs-network debug-states></wcs-network>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Write your CSS against `:state()`, not `data-wcs-state-*`.** The mirrored
|
|
198
|
+
attributes exist purely to make state changes visible while debugging with
|
|
199
|
+
DevTools open; they are not a supported styling hook.
|
|
200
|
+
|
|
146
201
|
## Headless usage (`NetworkCore`)
|
|
147
202
|
|
|
148
203
|
The Core has no DOM dependency and can be used directly with `bind()` from `@wc-bindable/core`:
|
package/dist/index.d.ts
CHANGED
|
@@ -117,7 +117,11 @@ declare class WcsNetwork extends HTMLElement {
|
|
|
117
117
|
static wcBindable: IWcBindable;
|
|
118
118
|
private _core;
|
|
119
119
|
private _connectedCallbackPromise;
|
|
120
|
+
private _internals;
|
|
120
121
|
constructor();
|
|
122
|
+
get debugStates(): string[];
|
|
123
|
+
private _initInternals;
|
|
124
|
+
private _wireStates;
|
|
121
125
|
get effectiveType(): string | null;
|
|
122
126
|
get downlink(): number | null;
|
|
123
127
|
get rtt(): number | null;
|
package/dist/index.esm.js
CHANGED
|
@@ -195,9 +195,65 @@ class WcsNetwork extends HTMLElement {
|
|
|
195
195
|
};
|
|
196
196
|
_core;
|
|
197
197
|
_connectedCallbackPromise = Promise.resolve();
|
|
198
|
+
_internals = null;
|
|
198
199
|
constructor() {
|
|
199
200
|
super();
|
|
200
201
|
this._core = new NetworkCore(this);
|
|
202
|
+
this._internals = this._initInternals();
|
|
203
|
+
this._wireStates({
|
|
204
|
+
"wcs-network:change": (d) => ({
|
|
205
|
+
"save-data": d.saveData === true,
|
|
206
|
+
supported: d.supported === true,
|
|
207
|
+
}),
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
// CSS state reflection (:state()) — debug-only snapshot getter. NOT part of
|
|
211
|
+
// wc-bindable (not a bind target); see README "CSS styling with :state()".
|
|
212
|
+
// MUST NOT return the live CustomStateSet (that would let callers write
|
|
213
|
+
// states from outside, defeating the point of :state() being read-only).
|
|
214
|
+
get debugStates() {
|
|
215
|
+
return this._internals ? [...this._internals.states] : [];
|
|
216
|
+
}
|
|
217
|
+
_initInternals() {
|
|
218
|
+
// never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent
|
|
219
|
+
// in happy-dom / older environments, and pre-125 Chromium rejects
|
|
220
|
+
// non-dashed state names from states.add() (probed and discarded here).
|
|
221
|
+
// Either case silently disables reflection — the component still works,
|
|
222
|
+
// it just doesn't expose :state() selectors.
|
|
223
|
+
try {
|
|
224
|
+
if (typeof this.attachInternals !== "function")
|
|
225
|
+
return null;
|
|
226
|
+
const internals = this.attachInternals();
|
|
227
|
+
internals.states.add("wcs-probe");
|
|
228
|
+
internals.states.delete("wcs-probe");
|
|
229
|
+
return internals;
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
_wireStates(map) {
|
|
236
|
+
if (this._internals === null)
|
|
237
|
+
return;
|
|
238
|
+
const states = this._internals.states;
|
|
239
|
+
for (const [event, toStates] of Object.entries(map)) {
|
|
240
|
+
this.addEventListener(event, (e) => {
|
|
241
|
+
const debug = this.hasAttribute("debug-states");
|
|
242
|
+
for (const [name, on] of Object.entries(toStates(e.detail))) {
|
|
243
|
+
try {
|
|
244
|
+
if (on) {
|
|
245
|
+
states.add(name);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
states.delete(name);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch { /* never-throw */ }
|
|
252
|
+
if (debug)
|
|
253
|
+
this.toggleAttribute(`data-wcs-state-${name}`, on);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
201
257
|
}
|
|
202
258
|
// --- Core delegated getters ---
|
|
203
259
|
get effectiveType() {
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/NetworkCore.ts","../src/components/Network.ts","../src/registerComponents.ts","../src/bootstrapNetwork.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n network: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n network: \"wcs-network\",\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable, WcsNetworkSnapshot } from \"../types.js\";\n\nconst UNSUPPORTED_SNAPSHOT: WcsNetworkSnapshot = Object.freeze({\n effectiveType: null,\n downlink: null,\n rtt: null,\n saveData: null,\n supported: false,\n});\n\n/**\n * Headless Network Information primitive. A thin, framework-agnostic wrapper\n * around `navigator.connection` exposed through the wc-bindable protocol.\n *\n * Unlike most wcstack IO nodes, this Core needs no `_gen` generation guard\n * (§3.4): subscribing/unsubscribing to `navigator.connection`'s `change` event\n * is fully synchronous, so there is no asynchronous probe whose stale\n * resolution could race a dispose() (docs/network-tag-design.md §5).\n *\n * `navigator.connection` is unimplemented in Firefox/Safari — unsupported is\n * the common case here, not an edge case (docs/network-tag-design.md §0). All\n * four data fields collapse to `null` and `supported` to `false` in that case.\n */\nexport class NetworkCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"effectiveType\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.effectiveType },\n { name: \"downlink\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.downlink },\n { name: \"rtt\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.rtt },\n { name: \"saveData\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.saveData },\n { name: \"supported\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.supported },\n ],\n // Pure monitor: navigator.connection has no request()/action method to invoke.\n commands: [],\n };\n\n private _target: EventTarget;\n private _snapshot: WcsNetworkSnapshot = UNSUPPORTED_SNAPSHOT;\n\n // The live NetworkInformation object the `change` listener is attached to (kept\n // so dispose() can remove it precisely; not read for anything else).\n private _connection: EventTarget | null = null;\n\n // True once observe() has attached the live listener (or determined there is\n // nothing to attach to). Guards observe() so a redundant call does not\n // re-subscribe; dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, 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 get effectiveType(): string | null {\n return this._snapshot.effectiveType;\n }\n\n get downlink(): number | null {\n return this._snapshot.downlink;\n }\n\n get rtt(): number | null {\n return this._snapshot.rtt;\n }\n\n get saveData(): boolean | null {\n return this._snapshot.saveData;\n }\n\n get supported(): boolean {\n return this._snapshot.supported;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // is a no-op (no double listener, no redundant dispatch). Synchronous overall\n // (no probe to await), so the returned promise is only for API uniformity\n // with other IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n const api = this._api();\n if (api) {\n this._connection = api;\n api.addEventListener(\"change\", this._onChange);\n }\n this._apply(this._read());\n }\n return this._ready;\n }\n\n dispose(): void {\n this._subscribed = false;\n if (this._connection) {\n this._connection.removeEventListener(\"change\", this._onChange);\n this._connection = null;\n }\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.connection freely and lets an unsupported environment be detected\n // correctly on every observe()/reading.\n private _api(): (EventTarget & { effectiveType?: string; downlink?: number; rtt?: number; saveData?: boolean }) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav !== \"undefined\" && nav.connection ? nav.connection : undefined;\n }\n\n private _read(): WcsNetworkSnapshot {\n const c = this._api();\n if (!c) {\n return UNSUPPORTED_SNAPSHOT;\n }\n return {\n effectiveType: typeof c.effectiveType === \"string\" ? c.effectiveType : null,\n downlink: typeof c.downlink === \"number\" ? c.downlink : null,\n rtt: typeof c.rtt === \"number\" ? c.rtt : null,\n saveData: typeof c.saveData === \"boolean\" ? c.saveData : null,\n supported: true,\n };\n }\n\n private _onChange = (): void => {\n this._apply(this._read());\n };\n\n // Same-value guard (§3.3 MUST): the native `change` event already fires only\n // on a real change, but this Core still verifies field-by-field before\n // dispatching — defense in depth against a browser quirk double-firing\n // `change` with identical values.\n private _apply(next: WcsNetworkSnapshot): void {\n const prev = this._snapshot;\n if (\n prev.effectiveType === next.effectiveType &&\n prev.downlink === next.downlink &&\n prev.rtt === next.rtt &&\n prev.saveData === next.saveData &&\n prev.supported === next.supported\n ) {\n return;\n }\n this._snapshot = next;\n this._target.dispatchEvent(new CustomEvent(\"wcs-network:change\", {\n detail: next,\n // Family-wide MUST (async-io-node-guidelines.md §3.3): the event bubbles\n // from the Shell element so document-level consumers can delegate.\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { NetworkCore } from \"../core/NetworkCore.js\";\n\n/**\n * `<wcs-network>` — declarative Network Information API monitor.\n *\n * The smallest Shell in the batch (docs/network-tag-design.md §9): no\n * attributes at all. `navigator.connection` is a single global with nothing to\n * configure, unlike target-based nodes (`intersection`/`resize`) or\n * descriptor-based ones (`permission`).\n */\nexport class WcsNetwork extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so SSR (@wcstack/server render.ts) can await it\n // uniformly across all IO nodes before snapshotting the HTML. Mirrors\n // WcsPermission.connectedCallbackPromise.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...NetworkCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。permission と同型。\n commands: NetworkCore.wcBindable.commands,\n };\n\n private _core: NetworkCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new NetworkCore(this);\n }\n\n // --- Core delegated getters ---\n\n get effectiveType(): string | null {\n return this._core.effectiveType;\n }\n\n get downlink(): number | null {\n return this._core.downlink;\n }\n\n get rtt(): number | null {\n return this._core.rtt;\n }\n\n get saveData(): boolean | null {\n return this._core.saveData;\n }\n\n get supported(): boolean {\n return this._core.supported;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsNetwork } from \"./components/Network.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.network)) {\n customElements.define(config.tagNames.network, WcsNetwork);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapNetwork(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/NetworkCore.ts","../src/components/Network.ts","../src/registerComponents.ts","../src/bootstrapNetwork.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n network: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n network: \"wcs-network\",\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable, WcsNetworkSnapshot } from \"../types.js\";\n\nconst UNSUPPORTED_SNAPSHOT: WcsNetworkSnapshot = Object.freeze({\n effectiveType: null,\n downlink: null,\n rtt: null,\n saveData: null,\n supported: false,\n});\n\n/**\n * Headless Network Information primitive. A thin, framework-agnostic wrapper\n * around `navigator.connection` exposed through the wc-bindable protocol.\n *\n * Unlike most wcstack IO nodes, this Core needs no `_gen` generation guard\n * (§3.4): subscribing/unsubscribing to `navigator.connection`'s `change` event\n * is fully synchronous, so there is no asynchronous probe whose stale\n * resolution could race a dispose() (docs/network-tag-design.md §5).\n *\n * `navigator.connection` is unimplemented in Firefox/Safari — unsupported is\n * the common case here, not an edge case (docs/network-tag-design.md §0). All\n * four data fields collapse to `null` and `supported` to `false` in that case.\n */\nexport class NetworkCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"effectiveType\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.effectiveType },\n { name: \"downlink\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.downlink },\n { name: \"rtt\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.rtt },\n { name: \"saveData\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.saveData },\n { name: \"supported\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.supported },\n ],\n // Pure monitor: navigator.connection has no request()/action method to invoke.\n commands: [],\n };\n\n private _target: EventTarget;\n private _snapshot: WcsNetworkSnapshot = UNSUPPORTED_SNAPSHOT;\n\n // The live NetworkInformation object the `change` listener is attached to (kept\n // so dispose() can remove it precisely; not read for anything else).\n private _connection: EventTarget | null = null;\n\n // True once observe() has attached the live listener (or determined there is\n // nothing to attach to). Guards observe() so a redundant call does not\n // re-subscribe; dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, 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 get effectiveType(): string | null {\n return this._snapshot.effectiveType;\n }\n\n get downlink(): number | null {\n return this._snapshot.downlink;\n }\n\n get rtt(): number | null {\n return this._snapshot.rtt;\n }\n\n get saveData(): boolean | null {\n return this._snapshot.saveData;\n }\n\n get supported(): boolean {\n return this._snapshot.supported;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // is a no-op (no double listener, no redundant dispatch). Synchronous overall\n // (no probe to await), so the returned promise is only for API uniformity\n // with other IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n const api = this._api();\n if (api) {\n this._connection = api;\n api.addEventListener(\"change\", this._onChange);\n }\n this._apply(this._read());\n }\n return this._ready;\n }\n\n dispose(): void {\n this._subscribed = false;\n if (this._connection) {\n this._connection.removeEventListener(\"change\", this._onChange);\n this._connection = null;\n }\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.connection freely and lets an unsupported environment be detected\n // correctly on every observe()/reading.\n private _api(): (EventTarget & { effectiveType?: string; downlink?: number; rtt?: number; saveData?: boolean }) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav !== \"undefined\" && nav.connection ? nav.connection : undefined;\n }\n\n private _read(): WcsNetworkSnapshot {\n const c = this._api();\n if (!c) {\n return UNSUPPORTED_SNAPSHOT;\n }\n return {\n effectiveType: typeof c.effectiveType === \"string\" ? c.effectiveType : null,\n downlink: typeof c.downlink === \"number\" ? c.downlink : null,\n rtt: typeof c.rtt === \"number\" ? c.rtt : null,\n saveData: typeof c.saveData === \"boolean\" ? c.saveData : null,\n supported: true,\n };\n }\n\n private _onChange = (): void => {\n this._apply(this._read());\n };\n\n // Same-value guard (§3.3 MUST): the native `change` event already fires only\n // on a real change, but this Core still verifies field-by-field before\n // dispatching — defense in depth against a browser quirk double-firing\n // `change` with identical values.\n private _apply(next: WcsNetworkSnapshot): void {\n const prev = this._snapshot;\n if (\n prev.effectiveType === next.effectiveType &&\n prev.downlink === next.downlink &&\n prev.rtt === next.rtt &&\n prev.saveData === next.saveData &&\n prev.supported === next.supported\n ) {\n return;\n }\n this._snapshot = next;\n this._target.dispatchEvent(new CustomEvent(\"wcs-network:change\", {\n detail: next,\n // Family-wide MUST (async-io-node-guidelines.md §3.3): the event bubbles\n // from the Shell element so document-level consumers can delegate.\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { NetworkCore } from \"../core/NetworkCore.js\";\n\n/**\n * `<wcs-network>` — declarative Network Information API monitor.\n *\n * The smallest Shell in the batch (docs/network-tag-design.md §9): no\n * attributes at all. `navigator.connection` is a single global with nothing to\n * configure, unlike target-based nodes (`intersection`/`resize`) or\n * descriptor-based ones (`permission`).\n */\nexport class WcsNetwork extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so SSR (@wcstack/server render.ts) can await it\n // uniformly across all IO nodes before snapshotting the HTML. Mirrors\n // WcsPermission.connectedCallbackPromise.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...NetworkCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。permission と同型。\n commands: NetworkCore.wcBindable.commands,\n };\n\n private _core: NetworkCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new NetworkCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-network:change\": (d) => ({\n \"save-data\": d.saveData === true,\n supported: d.supported === true,\n }),\n });\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 // --- Core delegated getters ---\n\n get effectiveType(): string | null {\n return this._core.effectiveType;\n }\n\n get downlink(): number | null {\n return this._core.downlink;\n }\n\n get rtt(): number | null {\n return this._core.rtt;\n }\n\n get saveData(): boolean | null {\n return this._core.saveData;\n }\n\n get supported(): boolean {\n return this._core.supported;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsNetwork } from \"./components/Network.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.network)) {\n customElements.define(config.tagNames.network, WcsNetwork);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapNetwork(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.esm.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e={tagNames:{network:"wcs-network"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const n of Object.keys(e))t(e[n]);return e}function n(e){if(null===e||"object"!=typeof e)return e;const t={};for(const s of Object.keys(e))t[s]=n(e[s]);return t}let s=null;const
|
|
1
|
+
const e={tagNames:{network:"wcs-network"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const n of Object.keys(e))t(e[n]);return e}function n(e){if(null===e||"object"!=typeof e)return e;const t={};for(const s of Object.keys(e))t[s]=n(e[s]);return t}let s=null;const a=e;function r(){return s||(s=t(n(e))),s}const i=Object.freeze({effectiveType:null,downlink:null,rtt:null,saveData:null,supported:!1});class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"effectiveType",event:"wcs-network:change",getter:e=>e.detail.effectiveType},{name:"downlink",event:"wcs-network:change",getter:e=>e.detail.downlink},{name:"rtt",event:"wcs-network:change",getter:e=>e.detail.rtt},{name:"saveData",event:"wcs-network:change",getter:e=>e.detail.saveData},{name:"supported",event:"wcs-network:change",getter:e=>e.detail.supported}],commands:[]};_target;_snapshot=i;_connection=null;_subscribed=!1;_ready=Promise.resolve();constructor(e){super(),this._target=e??this}get ready(){return this._ready}get effectiveType(){return this._snapshot.effectiveType}get downlink(){return this._snapshot.downlink}get rtt(){return this._snapshot.rtt}get saveData(){return this._snapshot.saveData}get supported(){return this._snapshot.supported}observe(){if(!this._subscribed){this._subscribed=!0;const e=this._api();e&&(this._connection=e,e.addEventListener("change",this._onChange)),this._apply(this._read())}return this._ready}dispose(){this._subscribed=!1,this._connection&&(this._connection.removeEventListener("change",this._onChange),this._connection=null)}_api(){const e=globalThis.navigator;return void 0!==e&&e.connection?e.connection:void 0}_read(){const e=this._api();return e?{effectiveType:"string"==typeof e.effectiveType?e.effectiveType:null,downlink:"number"==typeof e.downlink?e.downlink:null,rtt:"number"==typeof e.rtt?e.rtt:null,saveData:"boolean"==typeof e.saveData?e.saveData:null,supported:!0}:i}_onChange=()=>{this._apply(this._read())};_apply(e){const t=this._snapshot;t.effectiveType===e.effectiveType&&t.downlink===e.downlink&&t.rtt===e.rtt&&t.saveData===e.saveData&&t.supported===e.supported||(this._snapshot=e,this._target.dispatchEvent(new CustomEvent("wcs-network:change",{detail:e,bubbles:!0})))}}class c extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...o.wcBindable,inputs:[],commands:o.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new o(this),this._internals=this._initInternals(),this._wireStates({"wcs-network:change":e=>({"save-data":!0===e.saveData,supported:!0===e.supported})})}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const e=this.attachInternals();return e.states.add("wcs-probe"),e.states.delete("wcs-probe"),e}catch{return null}}_wireStates(e){if(null===this._internals)return;const t=this._internals.states;for(const[n,s]of Object.entries(e))this.addEventListener(n,e=>{const n=this.hasAttribute("debug-states");for(const[a,r]of Object.entries(s(e.detail))){try{r?t.add(a):t.delete(a)}catch{}n&&this.toggleAttribute(`data-wcs-state-${a}`,r)}})}get effectiveType(){return this._core.effectiveType}get downlink(){return this._core.downlink}get rtt(){return this._core.rtt}get saveData(){return this._core.saveData}get supported(){return this._core.supported}get connectedCallbackPromise(){return this._connectedCallbackPromise}connectedCallback(){this.style.display="none",this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}}function l(t){var n;t&&((n=t).tagNames&&Object.assign(e.tagNames,n.tagNames),s=null),customElements.get(a.tagNames.network)||customElements.define(a.tagNames.network,c)}export{o as NetworkCore,c as WcsNetwork,l as bootstrapNetwork,r 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/NetworkCore.ts","../src/components/Network.ts","../src/bootstrapNetwork.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n network: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n network: \"wcs-network\",\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable, WcsNetworkSnapshot } from \"../types.js\";\n\nconst UNSUPPORTED_SNAPSHOT: WcsNetworkSnapshot = Object.freeze({\n effectiveType: null,\n downlink: null,\n rtt: null,\n saveData: null,\n supported: false,\n});\n\n/**\n * Headless Network Information primitive. A thin, framework-agnostic wrapper\n * around `navigator.connection` exposed through the wc-bindable protocol.\n *\n * Unlike most wcstack IO nodes, this Core needs no `_gen` generation guard\n * (§3.4): subscribing/unsubscribing to `navigator.connection`'s `change` event\n * is fully synchronous, so there is no asynchronous probe whose stale\n * resolution could race a dispose() (docs/network-tag-design.md §5).\n *\n * `navigator.connection` is unimplemented in Firefox/Safari — unsupported is\n * the common case here, not an edge case (docs/network-tag-design.md §0). All\n * four data fields collapse to `null` and `supported` to `false` in that case.\n */\nexport class NetworkCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"effectiveType\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.effectiveType },\n { name: \"downlink\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.downlink },\n { name: \"rtt\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.rtt },\n { name: \"saveData\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.saveData },\n { name: \"supported\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.supported },\n ],\n // Pure monitor: navigator.connection has no request()/action method to invoke.\n commands: [],\n };\n\n private _target: EventTarget;\n private _snapshot: WcsNetworkSnapshot = UNSUPPORTED_SNAPSHOT;\n\n // The live NetworkInformation object the `change` listener is attached to (kept\n // so dispose() can remove it precisely; not read for anything else).\n private _connection: EventTarget | null = null;\n\n // True once observe() has attached the live listener (or determined there is\n // nothing to attach to). Guards observe() so a redundant call does not\n // re-subscribe; dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, 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 get effectiveType(): string | null {\n return this._snapshot.effectiveType;\n }\n\n get downlink(): number | null {\n return this._snapshot.downlink;\n }\n\n get rtt(): number | null {\n return this._snapshot.rtt;\n }\n\n get saveData(): boolean | null {\n return this._snapshot.saveData;\n }\n\n get supported(): boolean {\n return this._snapshot.supported;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // is a no-op (no double listener, no redundant dispatch). Synchronous overall\n // (no probe to await), so the returned promise is only for API uniformity\n // with other IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n const api = this._api();\n if (api) {\n this._connection = api;\n api.addEventListener(\"change\", this._onChange);\n }\n this._apply(this._read());\n }\n return this._ready;\n }\n\n dispose(): void {\n this._subscribed = false;\n if (this._connection) {\n this._connection.removeEventListener(\"change\", this._onChange);\n this._connection = null;\n }\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.connection freely and lets an unsupported environment be detected\n // correctly on every observe()/reading.\n private _api(): (EventTarget & { effectiveType?: string; downlink?: number; rtt?: number; saveData?: boolean }) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav !== \"undefined\" && nav.connection ? nav.connection : undefined;\n }\n\n private _read(): WcsNetworkSnapshot {\n const c = this._api();\n if (!c) {\n return UNSUPPORTED_SNAPSHOT;\n }\n return {\n effectiveType: typeof c.effectiveType === \"string\" ? c.effectiveType : null,\n downlink: typeof c.downlink === \"number\" ? c.downlink : null,\n rtt: typeof c.rtt === \"number\" ? c.rtt : null,\n saveData: typeof c.saveData === \"boolean\" ? c.saveData : null,\n supported: true,\n };\n }\n\n private _onChange = (): void => {\n this._apply(this._read());\n };\n\n // Same-value guard (§3.3 MUST): the native `change` event already fires only\n // on a real change, but this Core still verifies field-by-field before\n // dispatching — defense in depth against a browser quirk double-firing\n // `change` with identical values.\n private _apply(next: WcsNetworkSnapshot): void {\n const prev = this._snapshot;\n if (\n prev.effectiveType === next.effectiveType &&\n prev.downlink === next.downlink &&\n prev.rtt === next.rtt &&\n prev.saveData === next.saveData &&\n prev.supported === next.supported\n ) {\n return;\n }\n this._snapshot = next;\n this._target.dispatchEvent(new CustomEvent(\"wcs-network:change\", {\n detail: next,\n // Family-wide MUST (async-io-node-guidelines.md §3.3): the event bubbles\n // from the Shell element so document-level consumers can delegate.\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { NetworkCore } from \"../core/NetworkCore.js\";\n\n/**\n * `<wcs-network>` — declarative Network Information API monitor.\n *\n * The smallest Shell in the batch (docs/network-tag-design.md §9): no\n * attributes at all. `navigator.connection` is a single global with nothing to\n * configure, unlike target-based nodes (`intersection`/`resize`) or\n * descriptor-based ones (`permission`).\n */\nexport class WcsNetwork extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so SSR (@wcstack/server render.ts) can await it\n // uniformly across all IO nodes before snapshotting the HTML. Mirrors\n // WcsPermission.connectedCallbackPromise.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...NetworkCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。permission と同型。\n commands: NetworkCore.wcBindable.commands,\n };\n\n private _core: NetworkCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new NetworkCore(this);\n }\n\n // --- Core delegated getters ---\n\n get effectiveType(): string | null {\n return this._core.effectiveType;\n }\n\n get downlink(): number | null {\n return this._core.downlink;\n }\n\n get rtt(): number | null {\n return this._core.rtt;\n }\n\n get saveData(): boolean | null {\n return this._core.saveData;\n }\n\n get supported(): boolean {\n return this._core.supported;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\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 bootstrapNetwork(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsNetwork } from \"./components/Network.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.network)) {\n customElements.define(config.tagNames.network, WcsNetwork);\n }\n}\n"],"names":["_config","tagNames","network","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","UNSUPPORTED_SNAPSHOT","effectiveType","downlink","rtt","saveData","supported","NetworkCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","commands","_target","_snapshot","_connection","_subscribed","_ready","Promise","resolve","constructor","target","super","this","ready","observe","api","_api","addEventListener","_onChange","_apply","_read","dispose","removeEventListener","nav","globalThis","navigator","connection","undefined","c","next","prev","dispatchEvent","CustomEvent","bubbles","WcsNetwork","HTMLElement","wcBindable","inputs","_core","_connectedCallbackPromise","connectedCallbackPromise","connectedCallback","style","display","disconnectedCallback","bootstrapNetwork","userConfig","partialConfig","assign","customElements","get","define"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/NetworkCore.ts","../src/components/Network.ts","../src/bootstrapNetwork.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n network: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n network: \"wcs-network\",\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable, WcsNetworkSnapshot } from \"../types.js\";\n\nconst UNSUPPORTED_SNAPSHOT: WcsNetworkSnapshot = Object.freeze({\n effectiveType: null,\n downlink: null,\n rtt: null,\n saveData: null,\n supported: false,\n});\n\n/**\n * Headless Network Information primitive. A thin, framework-agnostic wrapper\n * around `navigator.connection` exposed through the wc-bindable protocol.\n *\n * Unlike most wcstack IO nodes, this Core needs no `_gen` generation guard\n * (§3.4): subscribing/unsubscribing to `navigator.connection`'s `change` event\n * is fully synchronous, so there is no asynchronous probe whose stale\n * resolution could race a dispose() (docs/network-tag-design.md §5).\n *\n * `navigator.connection` is unimplemented in Firefox/Safari — unsupported is\n * the common case here, not an edge case (docs/network-tag-design.md §0). All\n * four data fields collapse to `null` and `supported` to `false` in that case.\n */\nexport class NetworkCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"effectiveType\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.effectiveType },\n { name: \"downlink\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.downlink },\n { name: \"rtt\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.rtt },\n { name: \"saveData\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.saveData },\n { name: \"supported\", event: \"wcs-network:change\", getter: (e: Event) => (e as CustomEvent).detail.supported },\n ],\n // Pure monitor: navigator.connection has no request()/action method to invoke.\n commands: [],\n };\n\n private _target: EventTarget;\n private _snapshot: WcsNetworkSnapshot = UNSUPPORTED_SNAPSHOT;\n\n // The live NetworkInformation object the `change` listener is attached to (kept\n // so dispose() can remove it precisely; not read for anything else).\n private _connection: EventTarget | null = null;\n\n // True once observe() has attached the live listener (or determined there is\n // nothing to attach to). Guards observe() so a redundant call does not\n // re-subscribe; dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, 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 get effectiveType(): string | null {\n return this._snapshot.effectiveType;\n }\n\n get downlink(): number | null {\n return this._snapshot.downlink;\n }\n\n get rtt(): number | null {\n return this._snapshot.rtt;\n }\n\n get saveData(): boolean | null {\n return this._snapshot.saveData;\n }\n\n get supported(): boolean {\n return this._snapshot.supported;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // is a no-op (no double listener, no redundant dispatch). Synchronous overall\n // (no probe to await), so the returned promise is only for API uniformity\n // with other IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n const api = this._api();\n if (api) {\n this._connection = api;\n api.addEventListener(\"change\", this._onChange);\n }\n this._apply(this._read());\n }\n return this._ready;\n }\n\n dispose(): void {\n this._subscribed = false;\n if (this._connection) {\n this._connection.removeEventListener(\"change\", this._onChange);\n this._connection = null;\n }\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.connection freely and lets an unsupported environment be detected\n // correctly on every observe()/reading.\n private _api(): (EventTarget & { effectiveType?: string; downlink?: number; rtt?: number; saveData?: boolean }) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav !== \"undefined\" && nav.connection ? nav.connection : undefined;\n }\n\n private _read(): WcsNetworkSnapshot {\n const c = this._api();\n if (!c) {\n return UNSUPPORTED_SNAPSHOT;\n }\n return {\n effectiveType: typeof c.effectiveType === \"string\" ? c.effectiveType : null,\n downlink: typeof c.downlink === \"number\" ? c.downlink : null,\n rtt: typeof c.rtt === \"number\" ? c.rtt : null,\n saveData: typeof c.saveData === \"boolean\" ? c.saveData : null,\n supported: true,\n };\n }\n\n private _onChange = (): void => {\n this._apply(this._read());\n };\n\n // Same-value guard (§3.3 MUST): the native `change` event already fires only\n // on a real change, but this Core still verifies field-by-field before\n // dispatching — defense in depth against a browser quirk double-firing\n // `change` with identical values.\n private _apply(next: WcsNetworkSnapshot): void {\n const prev = this._snapshot;\n if (\n prev.effectiveType === next.effectiveType &&\n prev.downlink === next.downlink &&\n prev.rtt === next.rtt &&\n prev.saveData === next.saveData &&\n prev.supported === next.supported\n ) {\n return;\n }\n this._snapshot = next;\n this._target.dispatchEvent(new CustomEvent(\"wcs-network:change\", {\n detail: next,\n // Family-wide MUST (async-io-node-guidelines.md §3.3): the event bubbles\n // from the Shell element so document-level consumers can delegate.\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { NetworkCore } from \"../core/NetworkCore.js\";\n\n/**\n * `<wcs-network>` — declarative Network Information API monitor.\n *\n * The smallest Shell in the batch (docs/network-tag-design.md §9): no\n * attributes at all. `navigator.connection` is a single global with nothing to\n * configure, unlike target-based nodes (`intersection`/`resize`) or\n * descriptor-based ones (`permission`).\n */\nexport class WcsNetwork extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so SSR (@wcstack/server render.ts) can await it\n // uniformly across all IO nodes before snapshotting the HTML. Mirrors\n // WcsPermission.connectedCallbackPromise.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...NetworkCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。permission と同型。\n commands: NetworkCore.wcBindable.commands,\n };\n\n private _core: NetworkCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new NetworkCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-network:change\": (d) => ({\n \"save-data\": d.saveData === true,\n supported: d.supported === true,\n }),\n });\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 // --- Core delegated getters ---\n\n get effectiveType(): string | null {\n return this._core.effectiveType;\n }\n\n get downlink(): number | null {\n return this._core.downlink;\n }\n\n get rtt(): number | null {\n return this._core.rtt;\n }\n\n get saveData(): boolean | null {\n return this._core.saveData;\n }\n\n get supported(): boolean {\n return this._core.supported;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\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 bootstrapNetwork(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsNetwork } from \"./components/Network.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.network)) {\n customElements.define(config.tagNames.network, WcsNetwork);\n }\n}\n"],"names":["_config","tagNames","network","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","UNSUPPORTED_SNAPSHOT","effectiveType","downlink","rtt","saveData","supported","NetworkCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","commands","_target","_snapshot","_connection","_subscribed","_ready","Promise","resolve","constructor","target","super","this","ready","observe","api","_api","addEventListener","_onChange","_apply","_read","dispose","removeEventListener","nav","globalThis","navigator","connection","undefined","c","next","prev","dispatchEvent","CustomEvent","bubbles","WcsNetwork","HTMLElement","wcBindable","inputs","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","connectedCallbackPromise","connectedCallback","style","display","disconnectedCallback","bootstrapNetwork","userConfig","partialConfig","assign","customElements","get","define"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wcstack/network",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.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",
|