@wcstack/magnetometer 1.20.0 → 1.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -7,7 +7,7 @@
7
7
  `@wcstack/state` と組み合わせると、`<wcs-magnetometer>` はパス契約で直接バインドできます:
8
8
 
9
9
  - **入力サーフェス**: `frequency`(サンプリングレート、Hz)
10
- - **出力 state サーフェス**: `x`、`y`、`z`、`error`
10
+ - **出力 state サーフェス**: `x`、`y`、`z`、`error`、`errorInfo`
11
11
 
12
12
  `@wcstack/magnetometer` は [CSBC](https://github.com/csbc-dev/arch/blob/main/README.md)(Core / Shell / Binding Contract)アーキテクチャに従います:
13
13
 
@@ -100,6 +100,7 @@ npm install @wcstack/magnetometer
100
100
  | `y` | `wcs-magnetometer:reading` | y軸方向の磁束密度。 |
101
101
  | `z` | `wcs-magnetometer:reading` | z軸方向の磁束密度。 |
102
102
  | `error` | `wcs-magnetometer:error` | 正規化された`{ error, message }`、無ければ`null`。 |
103
+ | `errorInfo` | `wcs-magnetometer:error-info-changed` | シリアライズ可能な失敗分類(`WcsIoErrorInfo` — 安定した `code` / `phase` / `recoverable`)、無ければ`null`。`error`から派生する追加的な出力で、既存の`error`の形状は不変。 |
103
104
 
104
105
  `x`/`y`/`z`は単一の`wcs-magnetometer:reading`イベントから派生します(ネイティブの1回の`reading`イベントで3軸が同時に更新される)。
105
106
 
@@ -161,6 +162,7 @@ wcs-magnetometer:state(error) ~ .fallback { display: block; }
161
162
 
162
163
  - **`_gen`世代ガードは無し。** `start()`/`stop()`は同期的な購読/購読解除のトグルであり、`dispose()`とレースしうる非同期probeが存在しません(`docs/sensor-tag-design.md` §1.5)。
163
164
  - **`error`は sticky(据え置き)です。** 最後に観測した失敗(`unsupported`、`SecurityError`等)を保持し、その後の`start()`成功や`reading`受信では自動クリアされません。`stop()`+`start()`でリトライが成功しても直前の`error`は残り続けます。必要なら利用側の state でクリア/再解釈してください。
165
+ - **`errorInfo` 分類(taxonomy)。** 同じ失敗をシリアライズ可能な `WcsIoErrorInfo`(安定した `code` / `phase` / `recoverable`)に分類する**追加的な**バインド可能出力(`wcs-magnetometer:error-info-changed`)で、`error`の形状は変更しません。正規化された error 名に応じて対応づけます: `unsupported` → `capability-missing`(phase `probe`)、`SecurityError` / `NotAllowedError` → `not-allowed`(phase `start`)、`NotReadableError` → `not-readable`(phase `execute`)、その他のセンサー失敗 → `sensor-error`(phase `execute`)。いずれも `recoverable: false` です。`errorInfo` は `error` と完全に同じタイミングで遷移するため、同様に **sticky** で、`error` が `null` に戻るときにのみ `null` に戻ります。共有の `WcsIoErrorInfo` 型と `WCS_MAGNETOMETER_ERROR_CODE` 定数はエクスポートされます。
164
166
  - **`frequency`は`start()`時にのみ読み取られます。** `attributeChangedCallback`は無く、`start()`は既に開始済みの間は冪等(再度呼んでも何もしない、上記コマンド参照)であるため、稼働中に`frequency`(属性またはプロパティ)を変更しても反映されません。新しいサンプリングレートを適用するには`stop()`してから`start()`し直してください。
165
167
  - **再親付け(別の親要素への移動)はセンサーを停止し、自動再開しません。** 接続中の`<wcs-magnetometer>`要素を別の親へ移動すると`disconnectedCallback`→`connectedCallback`が発火します。Shellは接続時に自動開始しないため(上記クイックスタート参照)、これは実質的な停止であり自動再開はされません。`x`/`y`/`z`は最後のサンプル値のまま凍結され、`error`も発生しません — `start`を再度発行するまでセンサーは inert のままです。
166
168
  - **生の`new Magnetometer(...)`は唯一のガード付き構築ヘルパー以外では呼ばない。** 権限拒否・Permissions-Policyブロックは同期的に例外を投げます。
package/README.md CHANGED
@@ -8,7 +8,7 @@ It is an **async primitive node** that turns device magnetic field readings into
8
8
  With `@wcstack/state`, `<wcs-magnetometer>` can be bound directly through path contracts:
9
9
 
10
10
  - **input surface**: `frequency` (sampling rate in Hz)
11
- - **output state surface**: `x`, `y`, `z`, `error`
11
+ - **output state surface**: `x`, `y`, `z`, `error`, `errorInfo`
12
12
 
13
13
  This means compass/magnetic-field-driven UI can be expressed declaratively in HTML, without writing `Magnetometer`/`reading`/`error`-listener glue in your UI layer.
14
14
 
@@ -103,6 +103,7 @@ Every bound state path must be declared up front — binding an undeclared path
103
103
  | `y` | `wcs-magnetometer:reading` | Magnetic flux density along the y-axis. |
104
104
  | `z` | `wcs-magnetometer:reading` | Magnetic flux density along the z-axis. |
105
105
  | `error` | `wcs-magnetometer:error` | Normalized `{ error, message }`, or `null`. |
106
+ | `errorInfo` | `wcs-magnetometer:error-info-changed` | Serializable failure taxonomy (`WcsIoErrorInfo` — stable `code` / `phase` / `recoverable`), or `null`. Additive, derived from `error`; the existing `error` shape is unchanged. |
106
107
 
107
108
  `x`/`y`/`z` all derive from the single `wcs-magnetometer:reading` event (one native `reading` event updates all three axes together).
108
109
 
@@ -166,6 +167,7 @@ DevTools open; it is not a supported styling hook.
166
167
 
167
168
  - **No `_gen` generation guard.** `start()`/`stop()` are a synchronous subscribe/unsubscribe toggle with no asynchronous probe to race against a `dispose()` — see `docs/sensor-tag-design.md` §1.5.
168
169
  - **`error` is sticky.** It holds the last observed failure (e.g. `unsupported`, `SecurityError`) and is **not** auto-cleared by a later successful `start()` or by incoming `reading`s. A `stop()` + `start()` retry that succeeds still leaves the previous `error` in place — clear or reinterpret it in your own state if needed.
170
+ - **`errorInfo` taxonomy.** An **additive** bindable output (`wcs-magnetometer:error-info-changed`) that classifies the same failure into a serializable `WcsIoErrorInfo` with a stable `code` / `phase` / `recoverable`, without changing the `error` shape. The mapping keys off the normalized error name: `unsupported` → `capability-missing` (phase `probe`); `SecurityError` / `NotAllowedError` → `not-allowed` (phase `start`); `NotReadableError` → `not-readable` (phase `execute`); any other sensor failure → `sensor-error` (phase `execute`). All are `recoverable: false`. `errorInfo` transitions exactly when `error` does, so it is **sticky** in the same way and only returns to `null` when `error` does. The shared `WcsIoErrorInfo` type and the `WCS_MAGNETOMETER_ERROR_CODE` constants are exported.
169
171
  - **`frequency` is read only at `start()`.** There is no `attributeChangedCallback`, and `start()` is idempotent while already started (a redundant call is a no-op — see Commands above), so changing the `frequency` attribute/property on a running sensor has no effect. To apply a new sampling rate, `stop()` then `start()` again.
170
172
  - **Reparenting stops the sensor and does not resume it.** Moving a connected `<wcs-magnetometer>` element to a different parent runs `disconnectedCallback` → `connectedCallback`; since the Shell does not auto-start on connect (see Quick Start above), this is effectively a stop with no automatic restart. `x`/`y`/`z` freeze at their last sample, and no `error` is raised — the sensor stays inert until `start` is invoked again.
171
173
  - **Never call the raw `new Magnetometer(...)` anywhere but the one guarded construction helper** — permission denial and Permissions-Policy blocks throw synchronously.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,14 @@
1
+ /** operation error の phase(taxonomy)。 */
2
+ type WcsIoErrorPhase = "probe" | "start" | "execute" | "decode" | "commit" | "dispose";
3
+ /** serializable な error info(non-cloneable な cause とは分離。DevTools / remote へは info のみ)。 */
4
+ interface WcsIoErrorInfo {
5
+ readonly code: string;
6
+ readonly phase: WcsIoErrorPhase;
7
+ readonly recoverable: boolean;
8
+ readonly capabilityId?: string;
9
+ readonly message: string;
10
+ }
11
+
1
12
  interface IWcBindableProperty {
2
13
  readonly name: string;
3
14
  readonly event: string;
@@ -13,7 +24,8 @@ interface IWcBindableCommand {
13
24
  }
14
25
  interface IWcBindable {
15
26
  readonly protocol: "wc-bindable";
16
- readonly version: 1;
27
+ /** Integer protocol version. All versions >= 1 are core-compatible. */
28
+ readonly version: number;
17
29
  readonly properties: readonly IWcBindableProperty[];
18
30
  readonly inputs?: readonly IWcBindableInput[];
19
31
  readonly commands?: readonly IWcBindableCommand[];
@@ -64,6 +76,8 @@ interface WcsMagnetometerErrorDetail {
64
76
  */
65
77
  interface WcsMagnetometerCoreValues extends WcsMagnetometerReading {
66
78
  error: WcsMagnetometerErrorDetail | null;
79
+ /** Additive failure taxonomy derived from `error` (stable code / phase / recoverable). */
80
+ errorInfo: WcsIoErrorInfo | null;
67
81
  }
68
82
  /**
69
83
  * Value types for the Shell (`<wcs-magnetometer>`) — identical observable
@@ -115,18 +129,27 @@ declare class MagnetometerCore extends EventTarget {
115
129
  private _target;
116
130
  private _reading;
117
131
  private _error;
132
+ private _errorInfo;
118
133
  private _sensor;
119
134
  constructor(target?: EventTarget);
120
135
  get x(): number | null;
121
136
  get y(): number | null;
122
137
  get z(): number | null;
123
138
  get error(): WcsMagnetometerErrorDetail | null;
139
+ /**
140
+ * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /
141
+ * `recoverable`), or null. Additive wc-bindable property (event
142
+ * `wcs-magnetometer:error-info-changed`), derived from `error`; the existing
143
+ * `error` property/event are unchanged.
144
+ */
145
+ get errorInfo(): WcsIoErrorInfo | null;
124
146
  /** No asynchronous probe to await: start()/stop() are synchronous
125
147
  * (docs/async-io-node-guidelines.md §3.8 is satisfied trivially, mirroring
126
148
  * NetworkCore). */
127
149
  get ready(): Promise<void>;
128
150
  private _setReading;
129
151
  private _setError;
152
+ private _commitErrorInfo;
130
153
  /**
131
154
  * Start the sensor at the given `frequency` (Hz), or the platform default
132
155
  * when omitted. Idempotent while already started: a redundant start() does
@@ -218,6 +241,7 @@ declare class WcsMagnetometer extends HTMLElement {
218
241
  get y(): number | null;
219
242
  get z(): number | null;
220
243
  get error(): WcsMagnetometerErrorDetail | null;
244
+ get errorInfo(): WcsIoErrorInfo | null;
221
245
  get connectedCallbackPromise(): Promise<void>;
222
246
  start(): void;
223
247
  stop(): void;
@@ -225,5 +249,30 @@ declare class WcsMagnetometer extends HTMLElement {
225
249
  disconnectedCallback(): void;
226
250
  }
227
251
 
228
- export { MagnetometerCore, WcsMagnetometer, bootstrapMagnetometer, getConfig };
229
- export type { IWritableConfig, IWritableTagNames, WcsMagnetometerCoreValues, WcsMagnetometerErrorDetail, WcsMagnetometerReading, WcsMagnetometerValues };
252
+ /**
253
+ * magnetometerCapabilities.ts
254
+ *
255
+ * Magnetometer node 固有の error code(taxonomy)と derivation。汎用の error info 型は
256
+ * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から
257
+ * import する。sensor は監視系(継続 subscribe/unsubscribe)で競合する operation を持た
258
+ * ないため lane は持たず、error taxonomy(errorInfo)のみを採用する。
259
+ *
260
+ * sensor family(accelerometer / gyroscope / magnetometer / ambient-light-sensor)は
261
+ * error 面が構造同一(`{ error: <name>, message }`、`.error` が Error.name / "unsupported"
262
+ * / "error" fallback)なので、taxonomy も 4 兄弟で一致させる。
263
+ */
264
+
265
+ /** 安定した magnetometer error code(taxonomy)。値は公開キーとして固定。 */
266
+ declare const WCS_MAGNETOMETER_ERROR_CODE: {
267
+ /** Sensor API 非対応(`globalThis.Magnetometer` 不在)。 */
268
+ readonly CapabilityMissing: "capability-missing";
269
+ /** `SecurityError` / `NotAllowedError` — 権限拒否・feature-policy ブロック。 */
270
+ readonly NotAllowed: "not-allowed";
271
+ /** `NotReadableError` — センサーハードウェアを読めない。 */
272
+ readonly NotReadable: "not-readable";
273
+ /** その他の SensorErrorEvent / 想定外の失敗。 */
274
+ readonly SensorError: "sensor-error";
275
+ };
276
+
277
+ export { MagnetometerCore, WCS_MAGNETOMETER_ERROR_CODE, WcsMagnetometer, bootstrapMagnetometer, getConfig };
278
+ export type { IWritableConfig, IWritableTagNames, WcsIoErrorInfo, WcsIoErrorPhase, WcsMagnetometerCoreValues, WcsMagnetometerErrorDetail, WcsMagnetometerReading, WcsMagnetometerValues };
package/dist/index.esm.js CHANGED
@@ -36,6 +36,53 @@ function setConfig(partialConfig) {
36
36
  frozenConfig = null;
37
37
  }
38
38
 
39
+ /**
40
+ * magnetometerCapabilities.ts
41
+ *
42
+ * Magnetometer node 固有の error code(taxonomy)と derivation。汎用の error info 型は
43
+ * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から
44
+ * import する。sensor は監視系(継続 subscribe/unsubscribe)で競合する operation を持た
45
+ * ないため lane は持たず、error taxonomy(errorInfo)のみを採用する。
46
+ *
47
+ * sensor family(accelerometer / gyroscope / magnetometer / ambient-light-sensor)は
48
+ * error 面が構造同一(`{ error: <name>, message }`、`.error` が Error.name / "unsupported"
49
+ * / "error" fallback)なので、taxonomy も 4 兄弟で一致させる。
50
+ */
51
+ /** 安定した magnetometer error code(taxonomy)。値は公開キーとして固定。 */
52
+ const WCS_MAGNETOMETER_ERROR_CODE = {
53
+ /** Sensor API 非対応(`globalThis.Magnetometer` 不在)。 */
54
+ CapabilityMissing: "capability-missing",
55
+ /** `SecurityError` / `NotAllowedError` — 権限拒否・feature-policy ブロック。 */
56
+ NotAllowed: "not-allowed",
57
+ /** `NotReadableError` — センサーハードウェアを読めない。 */
58
+ NotReadable: "not-readable",
59
+ /** その他の SensorErrorEvent / 想定外の失敗。 */
60
+ SensorError: "sensor-error",
61
+ };
62
+ /**
63
+ * sensor の失敗を serializable な error taxonomy に写す。`name` は error detail の
64
+ * `.error`(`Error.name` / "unsupported" / "error" fallback)。
65
+ *
66
+ * - "unsupported" は開始前の能力欠如 → phase="probe" / capability-missing。
67
+ * - `SecurityError` / `NotAllowedError` は sensor 構築時の権限拒否 → phase="start" /
68
+ * not-allowed。いずれも retry で回復しない(recoverable=false)。
69
+ * - `NotReadableError` は稼働中のハードウェア読取失敗 → phase="execute" / not-readable。
70
+ * - それ以外(SensorErrorEvent の他 name / "error" fallback)は phase="execute" /
71
+ * sensor-error。
72
+ */
73
+ function deriveMagnetometerErrorInfo(name, message) {
74
+ if (name === "unsupported") {
75
+ return { code: WCS_MAGNETOMETER_ERROR_CODE.CapabilityMissing, phase: "probe", recoverable: false, message };
76
+ }
77
+ if (name === "SecurityError" || name === "NotAllowedError") {
78
+ return { code: WCS_MAGNETOMETER_ERROR_CODE.NotAllowed, phase: "start", recoverable: false, message };
79
+ }
80
+ if (name === "NotReadableError") {
81
+ return { code: WCS_MAGNETOMETER_ERROR_CODE.NotReadable, phase: "execute", recoverable: false, message };
82
+ }
83
+ return { code: WCS_MAGNETOMETER_ERROR_CODE.SensorError, phase: "execute", recoverable: false, message };
84
+ }
85
+
39
86
  const NULL_READING = Object.freeze({ x: null, y: null, z: null });
40
87
  /**
41
88
  * Headless Magnetometer primitive. A thin, framework-agnostic wrapper around
@@ -81,12 +128,18 @@ class MagnetometerCore extends EventTarget {
81
128
  { name: "y", event: "wcs-magnetometer:reading", getter: (e) => e.detail.y },
82
129
  { name: "z", event: "wcs-magnetometer:reading", getter: (e) => e.detail.z },
83
130
  { name: "error", event: "wcs-magnetometer:error" },
131
+ // Serializable failure taxonomy (stable code / phase / recoverable), or null.
132
+ // Additive bindable output derived from `error.error` (the Error.name /
133
+ // "unsupported"); the existing `error` property/event are unchanged. Fires
134
+ // wcs-magnetometer:error-info-changed. No lane — the sensor is a monitor.
135
+ { name: "errorInfo", event: "wcs-magnetometer:error-info-changed" },
84
136
  ],
85
137
  commands: [{ name: "start" }, { name: "stop" }],
86
138
  };
87
139
  _target;
88
140
  _reading = NULL_READING;
89
141
  _error = null;
142
+ _errorInfo = null;
90
143
  // The live sensor instance while started (null otherwise), kept so stop()
91
144
  // can remove its listeners precisely and so start() can detect "already
92
145
  // started" without a separate boolean (docs/async-io-node-guidelines.md
@@ -108,6 +161,15 @@ class MagnetometerCore extends EventTarget {
108
161
  get error() {
109
162
  return this._error;
110
163
  }
164
+ /**
165
+ * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /
166
+ * `recoverable`), or null. Additive wc-bindable property (event
167
+ * `wcs-magnetometer:error-info-changed`), derived from `error`; the existing
168
+ * `error` property/event are unchanged.
169
+ */
170
+ get errorInfo() {
171
+ return this._errorInfo;
172
+ }
111
173
  /** No asynchronous probe to await: start()/stop() are synchronous
112
174
  * (docs/async-io-node-guidelines.md §3.8 is satisfied trivially, mirroring
113
175
  * NetworkCore). */
@@ -134,11 +196,25 @@ class MagnetometerCore extends EventTarget {
134
196
  if (this._error?.error === error?.error && this._error?.message === error?.message)
135
197
  return;
136
198
  this._error = error;
199
+ // Keep the additive `errorInfo` taxonomy in sync with `error`: derive from the
200
+ // error name (or null on clear). Fires before the `error` event so an observer
201
+ // binding both sees the classification first, mirroring the io-node family.
202
+ this._commitErrorInfo(error === null ? null : deriveMagnetometerErrorInfo(error.error, error.message));
137
203
  this._target.dispatchEvent(new CustomEvent("wcs-magnetometer:error", {
138
204
  detail: error,
139
205
  bubbles: true,
140
206
  }));
141
207
  }
208
+ // Called only from _setError (which already same-value-guards on the error name
209
+ // + message), so errorInfo transitions exactly when error does — no separate
210
+ // guard needed here.
211
+ _commitErrorInfo(info) {
212
+ this._errorInfo = info;
213
+ this._target.dispatchEvent(new CustomEvent("wcs-magnetometer:error-info-changed", {
214
+ detail: info,
215
+ bubbles: true,
216
+ }));
217
+ }
142
218
  // --- Public API ---
143
219
  /**
144
220
  * Start the sensor at the given `frequency` (Hz), or the platform default
@@ -381,6 +457,9 @@ class WcsMagnetometer extends HTMLElement {
381
457
  get error() {
382
458
  return this._core.error;
383
459
  }
460
+ get errorInfo() {
461
+ return this._core.errorInfo;
462
+ }
384
463
  get connectedCallbackPromise() {
385
464
  return this._connectedCallbackPromise;
386
465
  }
@@ -425,5 +504,5 @@ function bootstrapMagnetometer(userConfig) {
425
504
  registerComponents();
426
505
  }
427
506
 
428
- export { MagnetometerCore, WcsMagnetometer, bootstrapMagnetometer, getConfig };
507
+ export { MagnetometerCore, WCS_MAGNETOMETER_ERROR_CODE, WcsMagnetometer, bootstrapMagnetometer, getConfig };
429
508
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/MagnetometerCore.ts","../src/components/Magnetometer.ts","../src/registerComponents.ts","../src/bootstrapMagnetometer.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n magnetometer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n magnetometer: \"wcs-magnetometer\",\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, WcsMagnetometerReading, WcsMagnetometerErrorDetail } from \"../types.js\";\n\nconst NULL_READING: WcsMagnetometerReading = Object.freeze({ x: null, y: null, z: null });\n\n/**\n * Headless Magnetometer primitive. A thin, framework-agnostic wrapper around\n * the Generic Sensor API's `Magnetometer` class exposed through the\n * wc-bindable protocol.\n *\n * The platform `Sensor` base class (shared by `Accelerometer` / `Gyroscope` /\n * `Magnetometer` / `AmbientLightSensor`) reports failure through an `'error'`\n * event rather than a rejected promise, so this Core can satisfy never-throw\n * (docs/async-io-node-guidelines.md §3.6) by simply forwarding that event —\n * see docs/sensor-tag-design.md §0. The one place a synchronous\n * exception *can* still escape the platform API is the `Magnetometer`\n * constructor itself (e.g. `SecurityError` on permission denial or a\n * feature-policy block); `_createSensor()` wraps that single call in\n * try/catch, mirroring FetchCore's `_doFetch` try/catch around\n * `globalThis.fetch` (packages/fetch/src/core/FetchCore.ts).\n *\n * `x`/`y`/`z` are three getters derived from the single `wcs-magnetometer:reading`\n * event (mirroring how NetworkCore exposes effectiveType/downlink/… from one\n * `wcs-network:change` event): the native `reading` event already reports all\n * three axes together, so they are not split into independent events. `reading`\n * is an event-like signal (a fresh sample every time, not a settled state) and\n * is therefore deliberately NOT same-value guarded — every sample dispatches.\n * `error` is state-like (denial / unsupported does not change from tick to\n * tick) and IS same-value guarded, and is published on its own\n * `wcs-magnetometer:error` event, independent of `reading`.\n *\n * No `_gen` generation guard: start()/stop() are a synchronous\n * subscribe/unsubscribe toggle with no asynchronous probe whose stale\n * resolution could race a dispose() — see docs/sensor-tag-design.md §1.5\n * (the same reasoning as NetworkCore, docs/network-tag-design.md §5).\n *\n * Permissions: this Core does not query `navigator.permissions` itself.\n * Compose with `<wcs-permission name=\"magnetometer\">` instead — see\n * docs/sensor-tag-design.md §\"2番目の決定: Permissions APIとの合成\".\n */\nexport class MagnetometerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"x\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.x },\n { name: \"y\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.y },\n { name: \"z\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.z },\n { name: \"error\", event: \"wcs-magnetometer:error\" },\n ],\n commands: [{ name: \"start\" }, { name: \"stop\" }],\n };\n\n private _target: EventTarget;\n private _reading: WcsMagnetometerReading = NULL_READING;\n private _error: WcsMagnetometerErrorDetail | null = null;\n\n // The live sensor instance while started (null otherwise), kept so stop()\n // can remove its listeners precisely and so start() can detect \"already\n // started\" without a separate boolean (docs/async-io-node-guidelines.md\n // §3.5 idempotency).\n private _sensor: (EventTarget & { start(): void; stop(): void }) | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get x(): number | null {\n return this._reading.x;\n }\n\n get y(): number | null {\n return this._reading.y;\n }\n\n get z(): number | null {\n return this._reading.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._error;\n }\n\n /** No asynchronous probe to await: start()/stop() are synchronous\n * (docs/async-io-node-guidelines.md §3.8 is satisfied trivially, mirroring\n * NetworkCore). */\n get ready(): Promise<void> {\n return Promise.resolve();\n }\n\n // --- State setters ---\n\n // Deliberately NOT same-value guarded: a `reading` is a fresh sample, not a\n // settled state, so it must dispatch every time even when the values happen\n // to repeat (docs/sensor-tag-design.md §1.1).\n private _setReading(reading: WcsMagnetometerReading): void {\n this._reading = reading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:reading\", {\n detail: reading,\n bubbles: true,\n }));\n }\n\n private _setError(error: WcsMagnetometerErrorDetail | null): void {\n // Same-value guard (by error name + message): error is state-like, unlike\n // reading — a repeated identical error (same name and message) must not\n // redispatch. Note `error` is also STICKY: nothing calls _setError(null),\n // so a successful (re)start does not clear a prior failure — the monitoring\n // sensor family deliberately keeps the last observed error (docs/sensor-tag-design.md §1.5).\n if (this._error?.error === error?.error && this._error?.message === error?.message) return;\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start the sensor at the given `frequency` (Hz), or the platform default\n * when omitted. Idempotent while already started: a redundant start() does\n * not construct a second sensor instance (which would leak the first).\n * Restart with a different frequency via stop() + start().\n *\n * Synchronous, mirroring the native `Sensor.start()` — never throws\n * (docs/async-io-node-guidelines.md §3.6): both \"unsupported\" and a\n * synchronous constructor exception (permission denial, feature-policy\n * block) are converted to the `error` property instead of propagating.\n */\n start(frequency?: number): void {\n if (this._sensor) return;\n const sensor = this._createSensor(frequency);\n if (!sensor) return;\n sensor.addEventListener(\"reading\", this._onReading as EventListener);\n sensor.addEventListener(\"error\", this._onError as EventListener);\n this._sensor = sensor;\n try {\n sensor.start();\n } catch (e: any) {\n // Defensive: the platform contract says start()/stop() do not throw\n // (failures surface via the 'error' event), but never-throw is a hard\n // requirement here, so guard against a non-conformant implementation\n // too.\n this._teardownSensor();\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n }\n }\n\n /** Stop the sensor and detach its listeners. Safe to call when not started. */\n stop(): void {\n if (!this._sensor) return;\n try {\n this._sensor.stop();\n } catch {\n // Never-throw defensive guard, symmetric with start(). Teardown below\n // still runs so listeners are detached regardless.\n }\n this._teardownSensor();\n }\n\n /** Lifecycle alias for start(), so the Shell's connectedCallback can drive\n * this Core the same way as other IO nodes' observe()/dispose() pair. No\n * asynchronous probe, so the returned promise always resolves immediately. */\n observe(frequency?: number): Promise<void> {\n this.start(frequency);\n return this.ready;\n }\n\n /** Lifecycle alias for stop(), invoked from the Shell's disconnectedCallback. */\n dispose(): void {\n this.stop();\n }\n\n // --- Internal ---\n\n // Both call sites (start()'s catch, stop()) only ever invoke this once\n // `this._sensor` is already known non-null, so there is no null-guard here\n // (nothing to defend against).\n private _teardownSensor(): void {\n this._sensor!.removeEventListener(\"reading\", this._onReading as EventListener);\n this._sensor!.removeEventListener(\"error\", this._onError as EventListener);\n this._sensor = null;\n }\n\n /**\n * Construct the platform `Magnetometer`, guarding both non-support and a\n * synchronous constructor exception. Never calls the raw `new Magnetometer(...)`\n * anywhere else in this class — see docs/sensor-tag-design.md §1.5.\n *\n * API resolution is call-time (docs/async-io-node-guidelines.md §3.7):\n * re-checked on every start(), never cached, so tests can install/remove\n * the global freely and an unsupported environment is always reported\n * correctly.\n */\n private _createSensor(frequency?: number): (EventTarget & { start(): void; stop(): void }) | null {\n const Ctor = (globalThis as any).Magnetometer;\n if (typeof Ctor !== \"function\") {\n this._setError({ error: \"unsupported\", message: \"Magnetometer is not supported\" });\n return null;\n }\n try {\n return new Ctor(frequency !== undefined ? { frequency } : undefined);\n } catch (e: any) {\n // SecurityError (permission denial, feature-policy block) or any other\n // synchronous construction failure. Mirrors the FetchCore._doFetch\n // try/catch structure (packages/fetch/src/core/FetchCore.ts) — a\n // synchronous constructor call here instead of an awaited fetch().\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n return null;\n }\n }\n\n private _onReading = (event: Event): void => {\n const sensor = event.target as unknown as { x: number | null; y: number | null; z: number | null };\n this._setReading({ x: sensor.x, y: sensor.y, z: sensor.z });\n };\n\n private _onError = (event: Event): void => {\n const err = (event as any).error as { name?: string; message?: string } | undefined;\n // Fallback is a meaningful constant, NOT String(err): a SensorErrorEvent\n // without an `error` field would otherwise stringify `undefined` into the\n // literal message \"undefined\" (aligned across the sensor family).\n this._setError({ error: err?.name ?? \"error\", message: err?.message ?? \"Sensor error\" });\n };\n}\n","import { IWcBindable, WcsMagnetometerErrorDetail } from \"../types.js\";\nimport { MagnetometerCore } from \"../core/MagnetometerCore.js\";\n\n/**\n * `<wcs-magnetometer>` — declarative Generic Sensor API (`Magnetometer`)\n * monitor + start/stop control.\n *\n * Unlike `<wcs-network>` / `<wcs-permission>` (pure monitors), this Shell is a\n * bidirectional node: `start`/`stop` commands (command-token: state → element)\n * alongside the `x`/`y`/`z`/`error` observable surface (event-token: element →\n * state). The `frequency` attribute is the sole configuration input, forwarded\n * to the platform `Magnetometer` constructor's `{ frequency }` option\n * (docs/sensor-tag-design.md §1.2). The getter normalizes it: a non-finite or\n * non-positive value (NaN, 0, negative) reads back as `null` — meaning \"no\n * frequency specified\" — so start() falls back to the platform default rather\n * than forwarding a value the sensor would reject. Any positive finite value is\n * passed through verbatim (no upper-bound clamping — an out-of-range-but-positive\n * rate is still left to the browser/sensor to reject via `error`).\n *\n * Permission handling is intentionally NOT implemented here. Compose with\n * `<wcs-permission name=\"magnetometer\">` instead (see the README's permission\n * example, \"Gate on permission, then start\", and docs/sensor-tag-design.md).\n */\nexport class WcsMagnetometer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...MagnetometerCore.wcBindable,\n inputs: [{ name: \"frequency\" }],\n // Core の commands をそのまま継承(単一情報源)。\n commands: MagnetometerCore.wcBindable.commands,\n };\n\n private _core: MagnetometerCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new MagnetometerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-magnetometer:error\": (d) => ({ error: d != null }),\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 (docs/async-io-node-guidelines.md §3.6): attachInternals is\n // absent 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 /**\n * Sampling frequency in Hz. Reads back `null` when unset, blank, or when the\n * attribute does not parse to a positive finite number (NaN, `\"0\"`, negative)\n * — in every such \"no usable value\" case the platform default applies.\n *\n * Note the deliberate set/get asymmetry: `set frequency(0)` (or any\n * non-positive/non-finite value) still writes the attribute verbatim for\n * transparency/inspectability, but the getter normalizes it back to `null`.\n * A round-trip through a non-positive value therefore does NOT preserve it —\n * that value carries no valid sampling meaning, so it is treated as \"unset\"\n * on read. Only positive finite frequencies survive a set→get round-trip.\n *\n * This value is read only at `start()` time. There is no\n * `attributeChangedCallback`, and `MagnetometerCore.start()` is idempotent\n * while already started (a redundant call is a no-op), so setting\n * `frequency` (attribute or property) on an already-running sensor has no\n * effect until the caller `stop()`s and `start()`s again (see the README's\n * \"Notes & limitations\").\n */\n get frequency(): number | null {\n const attr = this.getAttribute(\"frequency\");\n if (attr === null || attr.trim() === \"\") return null;\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n }\n\n set frequency(value: number | null | undefined) {\n if (value === null || value === undefined) {\n this.removeAttribute(\"frequency\");\n } else {\n this.setAttribute(\"frequency\", String(value));\n }\n }\n\n // --- Core delegated getters ---\n\n get x(): number | null {\n return this._core.x;\n }\n\n get y(): number | null {\n return this._core.y;\n }\n\n get z(): number | null {\n return this._core.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._core.error;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n start(): void {\n this._core.start(this.frequency ?? undefined);\n }\n\n stop(): void {\n this._core.stop();\n }\n\n // --- Lifecycle ---\n\n // Deliberately does NOT auto-start the sensor on connect. Unlike\n // Geolocation (whose default phase acquires a fix immediately unless\n // `manual` is set), Magnetometer has no such \"connect implies observing\"\n // precedent in the design doc (docs/sensor-tag-design.md §1.3):\n // start/stop are the only commands, so connecting the element merely makes\n // it inert until a command-token `start` (or the `start()` method) is\n // invoked. This also keeps behavior predictable when composed with\n // `<wcs-permission name=\"magnetometer\">`: the caller decides when to start,\n // typically gated on `granted`.\n connectedCallback(): void {\n this.style.display = \"none\";\n // No asynchronous probe to await (docs/async-io-node-guidelines.md §3.8);\n // kept for SSR uniformity with other IO nodes.\n this._connectedCallbackPromise = this._core.ready;\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsMagnetometer } from \"./components/Magnetometer.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.magnetometer)) {\n customElements.define(config.tagNames.magnetometer, WcsMagnetometer);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapMagnetometer(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/magnetometerCapabilities.ts","../src/core/MagnetometerCore.ts","../src/components/Magnetometer.ts","../src/registerComponents.ts","../src/bootstrapMagnetometer.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n magnetometer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n magnetometer: \"wcs-magnetometer\",\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","/**\n * magnetometerCapabilities.ts\n *\n * Magnetometer node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。sensor は監視系(継続 subscribe/unsubscribe)で競合する operation を持た\n * ないため lane は持たず、error taxonomy(errorInfo)のみを採用する。\n *\n * sensor family(accelerometer / gyroscope / magnetometer / ambient-light-sensor)は\n * error 面が構造同一(`{ error: <name>, message }`、`.error` が Error.name / \"unsupported\"\n * / \"error\" fallback)なので、taxonomy も 4 兄弟で一致させる。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 安定した magnetometer error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_MAGNETOMETER_ERROR_CODE = {\n /** Sensor API 非対応(`globalThis.Magnetometer` 不在)。 */\n CapabilityMissing: \"capability-missing\",\n /** `SecurityError` / `NotAllowedError` — 権限拒否・feature-policy ブロック。 */\n NotAllowed: \"not-allowed\",\n /** `NotReadableError` — センサーハードウェアを読めない。 */\n NotReadable: \"not-readable\",\n /** その他の SensorErrorEvent / 想定外の失敗。 */\n SensorError: \"sensor-error\",\n} as const;\n\n/**\n * sensor の失敗を serializable な error taxonomy に写す。`name` は error detail の\n * `.error`(`Error.name` / \"unsupported\" / \"error\" fallback)。\n *\n * - \"unsupported\" は開始前の能力欠如 → phase=\"probe\" / capability-missing。\n * - `SecurityError` / `NotAllowedError` は sensor 構築時の権限拒否 → phase=\"start\" /\n * not-allowed。いずれも retry で回復しない(recoverable=false)。\n * - `NotReadableError` は稼働中のハードウェア読取失敗 → phase=\"execute\" / not-readable。\n * - それ以外(SensorErrorEvent の他 name / \"error\" fallback)は phase=\"execute\" /\n * sensor-error。\n */\nexport function deriveMagnetometerErrorInfo(name: string, message: string): WcsIoErrorInfo {\n if (name === \"unsupported\") {\n return { code: WCS_MAGNETOMETER_ERROR_CODE.CapabilityMissing, phase: \"probe\", recoverable: false, message };\n }\n if (name === \"SecurityError\" || name === \"NotAllowedError\") {\n return { code: WCS_MAGNETOMETER_ERROR_CODE.NotAllowed, phase: \"start\", recoverable: false, message };\n }\n if (name === \"NotReadableError\") {\n return { code: WCS_MAGNETOMETER_ERROR_CODE.NotReadable, phase: \"execute\", recoverable: false, message };\n }\n return { code: WCS_MAGNETOMETER_ERROR_CODE.SensorError, phase: \"execute\", recoverable: false, message };\n}\n","import { IWcBindable, WcsMagnetometerReading, WcsMagnetometerErrorDetail } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveMagnetometerErrorInfo } from \"./magnetometerCapabilities.js\";\n\nconst NULL_READING: WcsMagnetometerReading = Object.freeze({ x: null, y: null, z: null });\n\n/**\n * Headless Magnetometer primitive. A thin, framework-agnostic wrapper around\n * the Generic Sensor API's `Magnetometer` class exposed through the\n * wc-bindable protocol.\n *\n * The platform `Sensor` base class (shared by `Accelerometer` / `Gyroscope` /\n * `Magnetometer` / `AmbientLightSensor`) reports failure through an `'error'`\n * event rather than a rejected promise, so this Core can satisfy never-throw\n * (docs/async-io-node-guidelines.md §3.6) by simply forwarding that event —\n * see docs/sensor-tag-design.md §0. The one place a synchronous\n * exception *can* still escape the platform API is the `Magnetometer`\n * constructor itself (e.g. `SecurityError` on permission denial or a\n * feature-policy block); `_createSensor()` wraps that single call in\n * try/catch, mirroring FetchCore's `_doFetch` try/catch around\n * `globalThis.fetch` (packages/fetch/src/core/FetchCore.ts).\n *\n * `x`/`y`/`z` are three getters derived from the single `wcs-magnetometer:reading`\n * event (mirroring how NetworkCore exposes effectiveType/downlink/… from one\n * `wcs-network:change` event): the native `reading` event already reports all\n * three axes together, so they are not split into independent events. `reading`\n * is an event-like signal (a fresh sample every time, not a settled state) and\n * is therefore deliberately NOT same-value guarded — every sample dispatches.\n * `error` is state-like (denial / unsupported does not change from tick to\n * tick) and IS same-value guarded, and is published on its own\n * `wcs-magnetometer:error` event, independent of `reading`.\n *\n * No `_gen` generation guard: start()/stop() are a synchronous\n * subscribe/unsubscribe toggle with no asynchronous probe whose stale\n * resolution could race a dispose() — see docs/sensor-tag-design.md §1.5\n * (the same reasoning as NetworkCore, docs/network-tag-design.md §5).\n *\n * Permissions: this Core does not query `navigator.permissions` itself.\n * Compose with `<wcs-permission name=\"magnetometer\">` instead — see\n * docs/sensor-tag-design.md §\"2番目の決定: Permissions APIとの合成\".\n */\nexport class MagnetometerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"x\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.x },\n { name: \"y\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.y },\n { name: \"z\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.z },\n { name: \"error\", event: \"wcs-magnetometer:error\" },\n // Serializable failure taxonomy (stable code / phase / recoverable), or null.\n // Additive bindable output derived from `error.error` (the Error.name /\n // \"unsupported\"); the existing `error` property/event are unchanged. Fires\n // wcs-magnetometer:error-info-changed. No lane — the sensor is a monitor.\n { name: \"errorInfo\", event: \"wcs-magnetometer:error-info-changed\" },\n ],\n commands: [{ name: \"start\" }, { name: \"stop\" }],\n };\n\n private _target: EventTarget;\n private _reading: WcsMagnetometerReading = NULL_READING;\n private _error: WcsMagnetometerErrorDetail | null = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n\n // The live sensor instance while started (null otherwise), kept so stop()\n // can remove its listeners precisely and so start() can detect \"already\n // started\" without a separate boolean (docs/async-io-node-guidelines.md\n // §3.5 idempotency).\n private _sensor: (EventTarget & { start(): void; stop(): void }) | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get x(): number | null {\n return this._reading.x;\n }\n\n get y(): number | null {\n return this._reading.y;\n }\n\n get z(): number | null {\n return this._reading.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-magnetometer:error-info-changed`), derived from `error`; the existing\n * `error` property/event are unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n /** No asynchronous probe to await: start()/stop() are synchronous\n * (docs/async-io-node-guidelines.md §3.8 is satisfied trivially, mirroring\n * NetworkCore). */\n get ready(): Promise<void> {\n return Promise.resolve();\n }\n\n // --- State setters ---\n\n // Deliberately NOT same-value guarded: a `reading` is a fresh sample, not a\n // settled state, so it must dispatch every time even when the values happen\n // to repeat (docs/sensor-tag-design.md §1.1).\n private _setReading(reading: WcsMagnetometerReading): void {\n this._reading = reading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:reading\", {\n detail: reading,\n bubbles: true,\n }));\n }\n\n private _setError(error: WcsMagnetometerErrorDetail | null): void {\n // Same-value guard (by error name + message): error is state-like, unlike\n // reading — a repeated identical error (same name and message) must not\n // redispatch. Note `error` is also STICKY: nothing calls _setError(null),\n // so a successful (re)start does not clear a prior failure — the monitoring\n // sensor family deliberately keeps the last observed error (docs/sensor-tag-design.md §1.5).\n if (this._error?.error === error?.error && this._error?.message === error?.message) return;\n this._error = error;\n // Keep the additive `errorInfo` taxonomy in sync with `error`: derive from the\n // error name (or null on clear). Fires before the `error` event so an observer\n // binding both sees the classification first, mirroring the io-node family.\n this._commitErrorInfo(error === null ? null : deriveMagnetometerErrorInfo(error.error, error.message));\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (which already same-value-guards on the error name\n // + message), so errorInfo transitions exactly when error does — no separate\n // guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start the sensor at the given `frequency` (Hz), or the platform default\n * when omitted. Idempotent while already started: a redundant start() does\n * not construct a second sensor instance (which would leak the first).\n * Restart with a different frequency via stop() + start().\n *\n * Synchronous, mirroring the native `Sensor.start()` — never throws\n * (docs/async-io-node-guidelines.md §3.6): both \"unsupported\" and a\n * synchronous constructor exception (permission denial, feature-policy\n * block) are converted to the `error` property instead of propagating.\n */\n start(frequency?: number): void {\n if (this._sensor) return;\n const sensor = this._createSensor(frequency);\n if (!sensor) return;\n sensor.addEventListener(\"reading\", this._onReading as EventListener);\n sensor.addEventListener(\"error\", this._onError as EventListener);\n this._sensor = sensor;\n try {\n sensor.start();\n } catch (e: any) {\n // Defensive: the platform contract says start()/stop() do not throw\n // (failures surface via the 'error' event), but never-throw is a hard\n // requirement here, so guard against a non-conformant implementation\n // too.\n this._teardownSensor();\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n }\n }\n\n /** Stop the sensor and detach its listeners. Safe to call when not started. */\n stop(): void {\n if (!this._sensor) return;\n try {\n this._sensor.stop();\n } catch {\n // Never-throw defensive guard, symmetric with start(). Teardown below\n // still runs so listeners are detached regardless.\n }\n this._teardownSensor();\n }\n\n /** Lifecycle alias for start(), so the Shell's connectedCallback can drive\n * this Core the same way as other IO nodes' observe()/dispose() pair. No\n * asynchronous probe, so the returned promise always resolves immediately. */\n observe(frequency?: number): Promise<void> {\n this.start(frequency);\n return this.ready;\n }\n\n /** Lifecycle alias for stop(), invoked from the Shell's disconnectedCallback. */\n dispose(): void {\n this.stop();\n }\n\n // --- Internal ---\n\n // Both call sites (start()'s catch, stop()) only ever invoke this once\n // `this._sensor` is already known non-null, so there is no null-guard here\n // (nothing to defend against).\n private _teardownSensor(): void {\n this._sensor!.removeEventListener(\"reading\", this._onReading as EventListener);\n this._sensor!.removeEventListener(\"error\", this._onError as EventListener);\n this._sensor = null;\n }\n\n /**\n * Construct the platform `Magnetometer`, guarding both non-support and a\n * synchronous constructor exception. Never calls the raw `new Magnetometer(...)`\n * anywhere else in this class — see docs/sensor-tag-design.md §1.5.\n *\n * API resolution is call-time (docs/async-io-node-guidelines.md §3.7):\n * re-checked on every start(), never cached, so tests can install/remove\n * the global freely and an unsupported environment is always reported\n * correctly.\n */\n private _createSensor(frequency?: number): (EventTarget & { start(): void; stop(): void }) | null {\n const Ctor = (globalThis as any).Magnetometer;\n if (typeof Ctor !== \"function\") {\n this._setError({ error: \"unsupported\", message: \"Magnetometer is not supported\" });\n return null;\n }\n try {\n return new Ctor(frequency !== undefined ? { frequency } : undefined);\n } catch (e: any) {\n // SecurityError (permission denial, feature-policy block) or any other\n // synchronous construction failure. Mirrors the FetchCore._doFetch\n // try/catch structure (packages/fetch/src/core/FetchCore.ts) — a\n // synchronous constructor call here instead of an awaited fetch().\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n return null;\n }\n }\n\n private _onReading = (event: Event): void => {\n const sensor = event.target as unknown as { x: number | null; y: number | null; z: number | null };\n this._setReading({ x: sensor.x, y: sensor.y, z: sensor.z });\n };\n\n private _onError = (event: Event): void => {\n const err = (event as any).error as { name?: string; message?: string } | undefined;\n // Fallback is a meaningful constant, NOT String(err): a SensorErrorEvent\n // without an `error` field would otherwise stringify `undefined` into the\n // literal message \"undefined\" (aligned across the sensor family).\n this._setError({ error: err?.name ?? \"error\", message: err?.message ?? \"Sensor error\" });\n };\n}\n","import { IWcBindable, WcsMagnetometerErrorDetail } from \"../types.js\";\nimport { MagnetometerCore } from \"../core/MagnetometerCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\n\n/**\n * `<wcs-magnetometer>` — declarative Generic Sensor API (`Magnetometer`)\n * monitor + start/stop control.\n *\n * Unlike `<wcs-network>` / `<wcs-permission>` (pure monitors), this Shell is a\n * bidirectional node: `start`/`stop` commands (command-token: state → element)\n * alongside the `x`/`y`/`z`/`error` observable surface (event-token: element →\n * state). The `frequency` attribute is the sole configuration input, forwarded\n * to the platform `Magnetometer` constructor's `{ frequency }` option\n * (docs/sensor-tag-design.md §1.2). The getter normalizes it: a non-finite or\n * non-positive value (NaN, 0, negative) reads back as `null` — meaning \"no\n * frequency specified\" — so start() falls back to the platform default rather\n * than forwarding a value the sensor would reject. Any positive finite value is\n * passed through verbatim (no upper-bound clamping — an out-of-range-but-positive\n * rate is still left to the browser/sensor to reject via `error`).\n *\n * Permission handling is intentionally NOT implemented here. Compose with\n * `<wcs-permission name=\"magnetometer\">` instead (see the README's permission\n * example, \"Gate on permission, then start\", and docs/sensor-tag-design.md).\n */\nexport class WcsMagnetometer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...MagnetometerCore.wcBindable,\n inputs: [{ name: \"frequency\" }],\n // Core の commands をそのまま継承(単一情報源)。\n commands: MagnetometerCore.wcBindable.commands,\n };\n\n private _core: MagnetometerCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new MagnetometerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-magnetometer:error\": (d) => ({ error: d != null }),\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 (docs/async-io-node-guidelines.md §3.6): attachInternals is\n // absent 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 /**\n * Sampling frequency in Hz. Reads back `null` when unset, blank, or when the\n * attribute does not parse to a positive finite number (NaN, `\"0\"`, negative)\n * — in every such \"no usable value\" case the platform default applies.\n *\n * Note the deliberate set/get asymmetry: `set frequency(0)` (or any\n * non-positive/non-finite value) still writes the attribute verbatim for\n * transparency/inspectability, but the getter normalizes it back to `null`.\n * A round-trip through a non-positive value therefore does NOT preserve it —\n * that value carries no valid sampling meaning, so it is treated as \"unset\"\n * on read. Only positive finite frequencies survive a set→get round-trip.\n *\n * This value is read only at `start()` time. There is no\n * `attributeChangedCallback`, and `MagnetometerCore.start()` is idempotent\n * while already started (a redundant call is a no-op), so setting\n * `frequency` (attribute or property) on an already-running sensor has no\n * effect until the caller `stop()`s and `start()`s again (see the README's\n * \"Notes & limitations\").\n */\n get frequency(): number | null {\n const attr = this.getAttribute(\"frequency\");\n if (attr === null || attr.trim() === \"\") return null;\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n }\n\n set frequency(value: number | null | undefined) {\n if (value === null || value === undefined) {\n this.removeAttribute(\"frequency\");\n } else {\n this.setAttribute(\"frequency\", String(value));\n }\n }\n\n // --- Core delegated getters ---\n\n get x(): number | null {\n return this._core.x;\n }\n\n get y(): number | null {\n return this._core.y;\n }\n\n get z(): number | null {\n return this._core.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n start(): void {\n this._core.start(this.frequency ?? undefined);\n }\n\n stop(): void {\n this._core.stop();\n }\n\n // --- Lifecycle ---\n\n // Deliberately does NOT auto-start the sensor on connect. Unlike\n // Geolocation (whose default phase acquires a fix immediately unless\n // `manual` is set), Magnetometer has no such \"connect implies observing\"\n // precedent in the design doc (docs/sensor-tag-design.md §1.3):\n // start/stop are the only commands, so connecting the element merely makes\n // it inert until a command-token `start` (or the `start()` method) is\n // invoked. This also keeps behavior predictable when composed with\n // `<wcs-permission name=\"magnetometer\">`: the caller decides when to start,\n // typically gated on `granted`.\n connectedCallback(): void {\n this.style.display = \"none\";\n // No asynchronous probe to await (docs/async-io-node-guidelines.md §3.8);\n // kept for SSR uniformity with other IO nodes.\n this._connectedCallbackPromise = this._core.ready;\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsMagnetometer } from \"./components/Magnetometer.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.magnetometer)) {\n customElements.define(config.tagNames.magnetometer, WcsMagnetometer);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapMagnetometer(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={tagNames:{magnetometer:"wcs-magnetometer"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const r of Object.keys(e))t(e[r]);return e}function r(e){if(null===e||"object"!=typeof e)return e;const t={};for(const s of Object.keys(e))t[s]=r(e[s]);return t}let s=null;const n=e;function o(){return s||(s=t(r(e))),s}const i=Object.freeze({x:null,y:null,z:null});class a extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"x",event:"wcs-magnetometer:reading",getter:e=>e.detail.x},{name:"y",event:"wcs-magnetometer:reading",getter:e=>e.detail.y},{name:"z",event:"wcs-magnetometer:reading",getter:e=>e.detail.z},{name:"error",event:"wcs-magnetometer:error"}],commands:[{name:"start"},{name:"stop"}]};_target;_reading=i;_error=null;_sensor=null;constructor(e){super(),this._target=e??this}get x(){return this._reading.x}get y(){return this._reading.y}get z(){return this._reading.z}get error(){return this._error}get ready(){return Promise.resolve()}_setReading(e){this._reading=e,this._target.dispatchEvent(new CustomEvent("wcs-magnetometer:reading",{detail:e,bubbles:!0}))}_setError(e){this._error?.error===e?.error&&this._error?.message===e?.message||(this._error=e,this._target.dispatchEvent(new CustomEvent("wcs-magnetometer:error",{detail:e,bubbles:!0})))}start(e){if(this._sensor)return;const t=this._createSensor(e);if(t){t.addEventListener("reading",this._onReading),t.addEventListener("error",this._onError),this._sensor=t;try{t.start()}catch(e){this._teardownSensor(),this._setError({error:e?.name??"error",message:e?.message??String(e)})}}}stop(){if(this._sensor){try{this._sensor.stop()}catch{}this._teardownSensor()}}observe(e){return this.start(e),this.ready}dispose(){this.stop()}_teardownSensor(){this._sensor.removeEventListener("reading",this._onReading),this._sensor.removeEventListener("error",this._onError),this._sensor=null}_createSensor(e){const t=globalThis.Magnetometer;if("function"!=typeof t)return this._setError({error:"unsupported",message:"Magnetometer is not supported"}),null;try{return new t(void 0!==e?{frequency:e}:void 0)}catch(e){return this._setError({error:e?.name??"error",message:e?.message??String(e)}),null}}_onReading=e=>{const t=e.target;this._setReading({x:t.x,y:t.y,z:t.z})};_onError=e=>{const t=e.error;this._setError({error:t?.name??"error",message:t?.message??"Sensor error"})}}class c extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...a.wcBindable,inputs:[{name:"frequency"}],commands:a.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new a(this),this._internals=this._initInternals(),this._wireStates({"wcs-magnetometer:error":e=>({error:null!=e})})}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[r,s]of Object.entries(e))this.addEventListener(r,e=>{const r=this.hasAttribute("debug-states");for(const[n,o]of Object.entries(s(e.detail))){try{o?t.add(n):t.delete(n)}catch{}r&&this.toggleAttribute(`data-wcs-state-${n}`,o)}})}get frequency(){const e=this.getAttribute("frequency");if(null===e||""===e.trim())return null;const t=Number(e);return Number.isFinite(t)&&t>0?t:null}set frequency(e){null==e?this.removeAttribute("frequency"):this.setAttribute("frequency",String(e))}get x(){return this._core.x}get y(){return this._core.y}get z(){return this._core.z}get error(){return this._core.error}get connectedCallbackPromise(){return this._connectedCallbackPromise}start(){this._core.start(this.frequency??void 0)}stop(){this._core.stop()}connectedCallback(){this.style.display="none",this._connectedCallbackPromise=this._core.ready}disconnectedCallback(){this._core.dispose()}}function l(t){var r;t&&((r=t).tagNames&&Object.assign(e.tagNames,r.tagNames),s=null),customElements.get(n.tagNames.magnetometer)||customElements.define(n.tagNames.magnetometer,c)}export{a as MagnetometerCore,c as WcsMagnetometer,l as bootstrapMagnetometer,o as getConfig};
1
+ const e={tagNames:{magnetometer:"wcs-magnetometer"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const r of Object.keys(e))t(e[r]);return e}function r(e){if(null===e||"object"!=typeof e)return e;const t={};for(const s of Object.keys(e))t[s]=r(e[s]);return t}let s=null;const n=e;function o(){return s||(s=t(r(e))),s}const a={CapabilityMissing:"capability-missing",NotAllowed:"not-allowed",NotReadable:"not-readable",SensorError:"sensor-error"};const i=Object.freeze({x:null,y:null,z:null});class c extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"x",event:"wcs-magnetometer:reading",getter:e=>e.detail.x},{name:"y",event:"wcs-magnetometer:reading",getter:e=>e.detail.y},{name:"z",event:"wcs-magnetometer:reading",getter:e=>e.detail.z},{name:"error",event:"wcs-magnetometer:error"},{name:"errorInfo",event:"wcs-magnetometer:error-info-changed"}],commands:[{name:"start"},{name:"stop"}]};_target;_reading=i;_error=null;_errorInfo=null;_sensor=null;constructor(e){super(),this._target=e??this}get x(){return this._reading.x}get y(){return this._reading.y}get z(){return this._reading.z}get error(){return this._error}get errorInfo(){return this._errorInfo}get ready(){return Promise.resolve()}_setReading(e){this._reading=e,this._target.dispatchEvent(new CustomEvent("wcs-magnetometer:reading",{detail:e,bubbles:!0}))}_setError(e){var t,r;this._error?.error===e?.error&&this._error?.message===e?.message||(this._error=e,this._commitErrorInfo(null===e?null:(t=e.error,r=e.message,"unsupported"===t?{code:a.CapabilityMissing,phase:"probe",recoverable:!1,message:r}:"SecurityError"===t||"NotAllowedError"===t?{code:a.NotAllowed,phase:"start",recoverable:!1,message:r}:"NotReadableError"===t?{code:a.NotReadable,phase:"execute",recoverable:!1,message:r}:{code:a.SensorError,phase:"execute",recoverable:!1,message:r})),this._target.dispatchEvent(new CustomEvent("wcs-magnetometer:error",{detail:e,bubbles:!0})))}_commitErrorInfo(e){this._errorInfo=e,this._target.dispatchEvent(new CustomEvent("wcs-magnetometer:error-info-changed",{detail:e,bubbles:!0}))}start(e){if(this._sensor)return;const t=this._createSensor(e);if(t){t.addEventListener("reading",this._onReading),t.addEventListener("error",this._onError),this._sensor=t;try{t.start()}catch(e){this._teardownSensor(),this._setError({error:e?.name??"error",message:e?.message??String(e)})}}}stop(){if(this._sensor){try{this._sensor.stop()}catch{}this._teardownSensor()}}observe(e){return this.start(e),this.ready}dispose(){this.stop()}_teardownSensor(){this._sensor.removeEventListener("reading",this._onReading),this._sensor.removeEventListener("error",this._onError),this._sensor=null}_createSensor(e){const t=globalThis.Magnetometer;if("function"!=typeof t)return this._setError({error:"unsupported",message:"Magnetometer is not supported"}),null;try{return new t(void 0!==e?{frequency:e}:void 0)}catch(e){return this._setError({error:e?.name??"error",message:e?.message??String(e)}),null}}_onReading=e=>{const t=e.target;this._setReading({x:t.x,y:t.y,z:t.z})};_onError=e=>{const t=e.error;this._setError({error:t?.name??"error",message:t?.message??"Sensor error"})}}class l extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...c.wcBindable,inputs:[{name:"frequency"}],commands:c.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new c(this),this._internals=this._initInternals(),this._wireStates({"wcs-magnetometer:error":e=>({error:null!=e})})}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[r,s]of Object.entries(e))this.addEventListener(r,e=>{const r=this.hasAttribute("debug-states");for(const[n,o]of Object.entries(s(e.detail))){try{o?t.add(n):t.delete(n)}catch{}r&&this.toggleAttribute(`data-wcs-state-${n}`,o)}})}get frequency(){const e=this.getAttribute("frequency");if(null===e||""===e.trim())return null;const t=Number(e);return Number.isFinite(t)&&t>0?t:null}set frequency(e){null==e?this.removeAttribute("frequency"):this.setAttribute("frequency",String(e))}get x(){return this._core.x}get y(){return this._core.y}get z(){return this._core.z}get error(){return this._core.error}get errorInfo(){return this._core.errorInfo}get connectedCallbackPromise(){return this._connectedCallbackPromise}start(){this._core.start(this.frequency??void 0)}stop(){this._core.stop()}connectedCallback(){this.style.display="none",this._connectedCallbackPromise=this._core.ready}disconnectedCallback(){this._core.dispose()}}function u(t){var r;t&&((r=t).tagNames&&Object.assign(e.tagNames,r.tagNames),s=null),customElements.get(n.tagNames.magnetometer)||customElements.define(n.tagNames.magnetometer,l)}export{c as MagnetometerCore,a as WCS_MAGNETOMETER_ERROR_CODE,l as WcsMagnetometer,u as bootstrapMagnetometer,o 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/MagnetometerCore.ts","../src/components/Magnetometer.ts","../src/bootstrapMagnetometer.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n magnetometer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n magnetometer: \"wcs-magnetometer\",\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, WcsMagnetometerReading, WcsMagnetometerErrorDetail } from \"../types.js\";\n\nconst NULL_READING: WcsMagnetometerReading = Object.freeze({ x: null, y: null, z: null });\n\n/**\n * Headless Magnetometer primitive. A thin, framework-agnostic wrapper around\n * the Generic Sensor API's `Magnetometer` class exposed through the\n * wc-bindable protocol.\n *\n * The platform `Sensor` base class (shared by `Accelerometer` / `Gyroscope` /\n * `Magnetometer` / `AmbientLightSensor`) reports failure through an `'error'`\n * event rather than a rejected promise, so this Core can satisfy never-throw\n * (docs/async-io-node-guidelines.md §3.6) by simply forwarding that event —\n * see docs/sensor-tag-design.md §0. The one place a synchronous\n * exception *can* still escape the platform API is the `Magnetometer`\n * constructor itself (e.g. `SecurityError` on permission denial or a\n * feature-policy block); `_createSensor()` wraps that single call in\n * try/catch, mirroring FetchCore's `_doFetch` try/catch around\n * `globalThis.fetch` (packages/fetch/src/core/FetchCore.ts).\n *\n * `x`/`y`/`z` are three getters derived from the single `wcs-magnetometer:reading`\n * event (mirroring how NetworkCore exposes effectiveType/downlink/… from one\n * `wcs-network:change` event): the native `reading` event already reports all\n * three axes together, so they are not split into independent events. `reading`\n * is an event-like signal (a fresh sample every time, not a settled state) and\n * is therefore deliberately NOT same-value guarded — every sample dispatches.\n * `error` is state-like (denial / unsupported does not change from tick to\n * tick) and IS same-value guarded, and is published on its own\n * `wcs-magnetometer:error` event, independent of `reading`.\n *\n * No `_gen` generation guard: start()/stop() are a synchronous\n * subscribe/unsubscribe toggle with no asynchronous probe whose stale\n * resolution could race a dispose() — see docs/sensor-tag-design.md §1.5\n * (the same reasoning as NetworkCore, docs/network-tag-design.md §5).\n *\n * Permissions: this Core does not query `navigator.permissions` itself.\n * Compose with `<wcs-permission name=\"magnetometer\">` instead — see\n * docs/sensor-tag-design.md §\"2番目の決定: Permissions APIとの合成\".\n */\nexport class MagnetometerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"x\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.x },\n { name: \"y\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.y },\n { name: \"z\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.z },\n { name: \"error\", event: \"wcs-magnetometer:error\" },\n ],\n commands: [{ name: \"start\" }, { name: \"stop\" }],\n };\n\n private _target: EventTarget;\n private _reading: WcsMagnetometerReading = NULL_READING;\n private _error: WcsMagnetometerErrorDetail | null = null;\n\n // The live sensor instance while started (null otherwise), kept so stop()\n // can remove its listeners precisely and so start() can detect \"already\n // started\" without a separate boolean (docs/async-io-node-guidelines.md\n // §3.5 idempotency).\n private _sensor: (EventTarget & { start(): void; stop(): void }) | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get x(): number | null {\n return this._reading.x;\n }\n\n get y(): number | null {\n return this._reading.y;\n }\n\n get z(): number | null {\n return this._reading.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._error;\n }\n\n /** No asynchronous probe to await: start()/stop() are synchronous\n * (docs/async-io-node-guidelines.md §3.8 is satisfied trivially, mirroring\n * NetworkCore). */\n get ready(): Promise<void> {\n return Promise.resolve();\n }\n\n // --- State setters ---\n\n // Deliberately NOT same-value guarded: a `reading` is a fresh sample, not a\n // settled state, so it must dispatch every time even when the values happen\n // to repeat (docs/sensor-tag-design.md §1.1).\n private _setReading(reading: WcsMagnetometerReading): void {\n this._reading = reading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:reading\", {\n detail: reading,\n bubbles: true,\n }));\n }\n\n private _setError(error: WcsMagnetometerErrorDetail | null): void {\n // Same-value guard (by error name + message): error is state-like, unlike\n // reading — a repeated identical error (same name and message) must not\n // redispatch. Note `error` is also STICKY: nothing calls _setError(null),\n // so a successful (re)start does not clear a prior failure — the monitoring\n // sensor family deliberately keeps the last observed error (docs/sensor-tag-design.md §1.5).\n if (this._error?.error === error?.error && this._error?.message === error?.message) return;\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start the sensor at the given `frequency` (Hz), or the platform default\n * when omitted. Idempotent while already started: a redundant start() does\n * not construct a second sensor instance (which would leak the first).\n * Restart with a different frequency via stop() + start().\n *\n * Synchronous, mirroring the native `Sensor.start()` — never throws\n * (docs/async-io-node-guidelines.md §3.6): both \"unsupported\" and a\n * synchronous constructor exception (permission denial, feature-policy\n * block) are converted to the `error` property instead of propagating.\n */\n start(frequency?: number): void {\n if (this._sensor) return;\n const sensor = this._createSensor(frequency);\n if (!sensor) return;\n sensor.addEventListener(\"reading\", this._onReading as EventListener);\n sensor.addEventListener(\"error\", this._onError as EventListener);\n this._sensor = sensor;\n try {\n sensor.start();\n } catch (e: any) {\n // Defensive: the platform contract says start()/stop() do not throw\n // (failures surface via the 'error' event), but never-throw is a hard\n // requirement here, so guard against a non-conformant implementation\n // too.\n this._teardownSensor();\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n }\n }\n\n /** Stop the sensor and detach its listeners. Safe to call when not started. */\n stop(): void {\n if (!this._sensor) return;\n try {\n this._sensor.stop();\n } catch {\n // Never-throw defensive guard, symmetric with start(). Teardown below\n // still runs so listeners are detached regardless.\n }\n this._teardownSensor();\n }\n\n /** Lifecycle alias for start(), so the Shell's connectedCallback can drive\n * this Core the same way as other IO nodes' observe()/dispose() pair. No\n * asynchronous probe, so the returned promise always resolves immediately. */\n observe(frequency?: number): Promise<void> {\n this.start(frequency);\n return this.ready;\n }\n\n /** Lifecycle alias for stop(), invoked from the Shell's disconnectedCallback. */\n dispose(): void {\n this.stop();\n }\n\n // --- Internal ---\n\n // Both call sites (start()'s catch, stop()) only ever invoke this once\n // `this._sensor` is already known non-null, so there is no null-guard here\n // (nothing to defend against).\n private _teardownSensor(): void {\n this._sensor!.removeEventListener(\"reading\", this._onReading as EventListener);\n this._sensor!.removeEventListener(\"error\", this._onError as EventListener);\n this._sensor = null;\n }\n\n /**\n * Construct the platform `Magnetometer`, guarding both non-support and a\n * synchronous constructor exception. Never calls the raw `new Magnetometer(...)`\n * anywhere else in this class — see docs/sensor-tag-design.md §1.5.\n *\n * API resolution is call-time (docs/async-io-node-guidelines.md §3.7):\n * re-checked on every start(), never cached, so tests can install/remove\n * the global freely and an unsupported environment is always reported\n * correctly.\n */\n private _createSensor(frequency?: number): (EventTarget & { start(): void; stop(): void }) | null {\n const Ctor = (globalThis as any).Magnetometer;\n if (typeof Ctor !== \"function\") {\n this._setError({ error: \"unsupported\", message: \"Magnetometer is not supported\" });\n return null;\n }\n try {\n return new Ctor(frequency !== undefined ? { frequency } : undefined);\n } catch (e: any) {\n // SecurityError (permission denial, feature-policy block) or any other\n // synchronous construction failure. Mirrors the FetchCore._doFetch\n // try/catch structure (packages/fetch/src/core/FetchCore.ts) — a\n // synchronous constructor call here instead of an awaited fetch().\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n return null;\n }\n }\n\n private _onReading = (event: Event): void => {\n const sensor = event.target as unknown as { x: number | null; y: number | null; z: number | null };\n this._setReading({ x: sensor.x, y: sensor.y, z: sensor.z });\n };\n\n private _onError = (event: Event): void => {\n const err = (event as any).error as { name?: string; message?: string } | undefined;\n // Fallback is a meaningful constant, NOT String(err): a SensorErrorEvent\n // without an `error` field would otherwise stringify `undefined` into the\n // literal message \"undefined\" (aligned across the sensor family).\n this._setError({ error: err?.name ?? \"error\", message: err?.message ?? \"Sensor error\" });\n };\n}\n","import { IWcBindable, WcsMagnetometerErrorDetail } from \"../types.js\";\nimport { MagnetometerCore } from \"../core/MagnetometerCore.js\";\n\n/**\n * `<wcs-magnetometer>` — declarative Generic Sensor API (`Magnetometer`)\n * monitor + start/stop control.\n *\n * Unlike `<wcs-network>` / `<wcs-permission>` (pure monitors), this Shell is a\n * bidirectional node: `start`/`stop` commands (command-token: state → element)\n * alongside the `x`/`y`/`z`/`error` observable surface (event-token: element →\n * state). The `frequency` attribute is the sole configuration input, forwarded\n * to the platform `Magnetometer` constructor's `{ frequency }` option\n * (docs/sensor-tag-design.md §1.2). The getter normalizes it: a non-finite or\n * non-positive value (NaN, 0, negative) reads back as `null` — meaning \"no\n * frequency specified\" — so start() falls back to the platform default rather\n * than forwarding a value the sensor would reject. Any positive finite value is\n * passed through verbatim (no upper-bound clamping — an out-of-range-but-positive\n * rate is still left to the browser/sensor to reject via `error`).\n *\n * Permission handling is intentionally NOT implemented here. Compose with\n * `<wcs-permission name=\"magnetometer\">` instead (see the README's permission\n * example, \"Gate on permission, then start\", and docs/sensor-tag-design.md).\n */\nexport class WcsMagnetometer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...MagnetometerCore.wcBindable,\n inputs: [{ name: \"frequency\" }],\n // Core の commands をそのまま継承(単一情報源)。\n commands: MagnetometerCore.wcBindable.commands,\n };\n\n private _core: MagnetometerCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new MagnetometerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-magnetometer:error\": (d) => ({ error: d != null }),\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 (docs/async-io-node-guidelines.md §3.6): attachInternals is\n // absent 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 /**\n * Sampling frequency in Hz. Reads back `null` when unset, blank, or when the\n * attribute does not parse to a positive finite number (NaN, `\"0\"`, negative)\n * — in every such \"no usable value\" case the platform default applies.\n *\n * Note the deliberate set/get asymmetry: `set frequency(0)` (or any\n * non-positive/non-finite value) still writes the attribute verbatim for\n * transparency/inspectability, but the getter normalizes it back to `null`.\n * A round-trip through a non-positive value therefore does NOT preserve it —\n * that value carries no valid sampling meaning, so it is treated as \"unset\"\n * on read. Only positive finite frequencies survive a set→get round-trip.\n *\n * This value is read only at `start()` time. There is no\n * `attributeChangedCallback`, and `MagnetometerCore.start()` is idempotent\n * while already started (a redundant call is a no-op), so setting\n * `frequency` (attribute or property) on an already-running sensor has no\n * effect until the caller `stop()`s and `start()`s again (see the README's\n * \"Notes & limitations\").\n */\n get frequency(): number | null {\n const attr = this.getAttribute(\"frequency\");\n if (attr === null || attr.trim() === \"\") return null;\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n }\n\n set frequency(value: number | null | undefined) {\n if (value === null || value === undefined) {\n this.removeAttribute(\"frequency\");\n } else {\n this.setAttribute(\"frequency\", String(value));\n }\n }\n\n // --- Core delegated getters ---\n\n get x(): number | null {\n return this._core.x;\n }\n\n get y(): number | null {\n return this._core.y;\n }\n\n get z(): number | null {\n return this._core.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._core.error;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n start(): void {\n this._core.start(this.frequency ?? undefined);\n }\n\n stop(): void {\n this._core.stop();\n }\n\n // --- Lifecycle ---\n\n // Deliberately does NOT auto-start the sensor on connect. Unlike\n // Geolocation (whose default phase acquires a fix immediately unless\n // `manual` is set), Magnetometer has no such \"connect implies observing\"\n // precedent in the design doc (docs/sensor-tag-design.md §1.3):\n // start/stop are the only commands, so connecting the element merely makes\n // it inert until a command-token `start` (or the `start()` method) is\n // invoked. This also keeps behavior predictable when composed with\n // `<wcs-permission name=\"magnetometer\">`: the caller decides when to start,\n // typically gated on `granted`.\n connectedCallback(): void {\n this.style.display = \"none\";\n // No asynchronous probe to await (docs/async-io-node-guidelines.md §3.8);\n // kept for SSR uniformity with other IO nodes.\n this._connectedCallbackPromise = this._core.ready;\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 bootstrapMagnetometer(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsMagnetometer } from \"./components/Magnetometer.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.magnetometer)) {\n customElements.define(config.tagNames.magnetometer, WcsMagnetometer);\n }\n}\n"],"names":["_config","tagNames","magnetometer","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","NULL_READING","x","y","z","MagnetometerCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","commands","_target","_reading","_error","_sensor","constructor","target","super","this","error","ready","Promise","resolve","_setReading","reading","dispatchEvent","CustomEvent","bubbles","_setError","message","start","frequency","sensor","_createSensor","addEventListener","_onReading","_onError","_teardownSensor","String","stop","observe","dispose","removeEventListener","Ctor","globalThis","Magnetometer","undefined","err","WcsMagnetometer","HTMLElement","wcBindable","inputs","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","attr","getAttribute","trim","parsed","Number","isFinite","value","removeAttribute","setAttribute","connectedCallbackPromise","connectedCallback","style","display","disconnectedCallback","bootstrapMagnetometer","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/magnetometerCapabilities.ts","../src/core/MagnetometerCore.ts","../src/components/Magnetometer.ts","../src/bootstrapMagnetometer.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n magnetometer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n magnetometer: \"wcs-magnetometer\",\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","/**\n * magnetometerCapabilities.ts\n *\n * Magnetometer node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。sensor は監視系(継続 subscribe/unsubscribe)で競合する operation を持た\n * ないため lane は持たず、error taxonomy(errorInfo)のみを採用する。\n *\n * sensor family(accelerometer / gyroscope / magnetometer / ambient-light-sensor)は\n * error 面が構造同一(`{ error: <name>, message }`、`.error` が Error.name / \"unsupported\"\n * / \"error\" fallback)なので、taxonomy も 4 兄弟で一致させる。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 安定した magnetometer error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_MAGNETOMETER_ERROR_CODE = {\n /** Sensor API 非対応(`globalThis.Magnetometer` 不在)。 */\n CapabilityMissing: \"capability-missing\",\n /** `SecurityError` / `NotAllowedError` — 権限拒否・feature-policy ブロック。 */\n NotAllowed: \"not-allowed\",\n /** `NotReadableError` — センサーハードウェアを読めない。 */\n NotReadable: \"not-readable\",\n /** その他の SensorErrorEvent / 想定外の失敗。 */\n SensorError: \"sensor-error\",\n} as const;\n\n/**\n * sensor の失敗を serializable な error taxonomy に写す。`name` は error detail の\n * `.error`(`Error.name` / \"unsupported\" / \"error\" fallback)。\n *\n * - \"unsupported\" は開始前の能力欠如 → phase=\"probe\" / capability-missing。\n * - `SecurityError` / `NotAllowedError` は sensor 構築時の権限拒否 → phase=\"start\" /\n * not-allowed。いずれも retry で回復しない(recoverable=false)。\n * - `NotReadableError` は稼働中のハードウェア読取失敗 → phase=\"execute\" / not-readable。\n * - それ以外(SensorErrorEvent の他 name / \"error\" fallback)は phase=\"execute\" /\n * sensor-error。\n */\nexport function deriveMagnetometerErrorInfo(name: string, message: string): WcsIoErrorInfo {\n if (name === \"unsupported\") {\n return { code: WCS_MAGNETOMETER_ERROR_CODE.CapabilityMissing, phase: \"probe\", recoverable: false, message };\n }\n if (name === \"SecurityError\" || name === \"NotAllowedError\") {\n return { code: WCS_MAGNETOMETER_ERROR_CODE.NotAllowed, phase: \"start\", recoverable: false, message };\n }\n if (name === \"NotReadableError\") {\n return { code: WCS_MAGNETOMETER_ERROR_CODE.NotReadable, phase: \"execute\", recoverable: false, message };\n }\n return { code: WCS_MAGNETOMETER_ERROR_CODE.SensorError, phase: \"execute\", recoverable: false, message };\n}\n","import { IWcBindable, WcsMagnetometerReading, WcsMagnetometerErrorDetail } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveMagnetometerErrorInfo } from \"./magnetometerCapabilities.js\";\n\nconst NULL_READING: WcsMagnetometerReading = Object.freeze({ x: null, y: null, z: null });\n\n/**\n * Headless Magnetometer primitive. A thin, framework-agnostic wrapper around\n * the Generic Sensor API's `Magnetometer` class exposed through the\n * wc-bindable protocol.\n *\n * The platform `Sensor` base class (shared by `Accelerometer` / `Gyroscope` /\n * `Magnetometer` / `AmbientLightSensor`) reports failure through an `'error'`\n * event rather than a rejected promise, so this Core can satisfy never-throw\n * (docs/async-io-node-guidelines.md §3.6) by simply forwarding that event —\n * see docs/sensor-tag-design.md §0. The one place a synchronous\n * exception *can* still escape the platform API is the `Magnetometer`\n * constructor itself (e.g. `SecurityError` on permission denial or a\n * feature-policy block); `_createSensor()` wraps that single call in\n * try/catch, mirroring FetchCore's `_doFetch` try/catch around\n * `globalThis.fetch` (packages/fetch/src/core/FetchCore.ts).\n *\n * `x`/`y`/`z` are three getters derived from the single `wcs-magnetometer:reading`\n * event (mirroring how NetworkCore exposes effectiveType/downlink/… from one\n * `wcs-network:change` event): the native `reading` event already reports all\n * three axes together, so they are not split into independent events. `reading`\n * is an event-like signal (a fresh sample every time, not a settled state) and\n * is therefore deliberately NOT same-value guarded — every sample dispatches.\n * `error` is state-like (denial / unsupported does not change from tick to\n * tick) and IS same-value guarded, and is published on its own\n * `wcs-magnetometer:error` event, independent of `reading`.\n *\n * No `_gen` generation guard: start()/stop() are a synchronous\n * subscribe/unsubscribe toggle with no asynchronous probe whose stale\n * resolution could race a dispose() — see docs/sensor-tag-design.md §1.5\n * (the same reasoning as NetworkCore, docs/network-tag-design.md §5).\n *\n * Permissions: this Core does not query `navigator.permissions` itself.\n * Compose with `<wcs-permission name=\"magnetometer\">` instead — see\n * docs/sensor-tag-design.md §\"2番目の決定: Permissions APIとの合成\".\n */\nexport class MagnetometerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"x\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.x },\n { name: \"y\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.y },\n { name: \"z\", event: \"wcs-magnetometer:reading\", getter: (e: Event) => (e as CustomEvent).detail.z },\n { name: \"error\", event: \"wcs-magnetometer:error\" },\n // Serializable failure taxonomy (stable code / phase / recoverable), or null.\n // Additive bindable output derived from `error.error` (the Error.name /\n // \"unsupported\"); the existing `error` property/event are unchanged. Fires\n // wcs-magnetometer:error-info-changed. No lane — the sensor is a monitor.\n { name: \"errorInfo\", event: \"wcs-magnetometer:error-info-changed\" },\n ],\n commands: [{ name: \"start\" }, { name: \"stop\" }],\n };\n\n private _target: EventTarget;\n private _reading: WcsMagnetometerReading = NULL_READING;\n private _error: WcsMagnetometerErrorDetail | null = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n\n // The live sensor instance while started (null otherwise), kept so stop()\n // can remove its listeners precisely and so start() can detect \"already\n // started\" without a separate boolean (docs/async-io-node-guidelines.md\n // §3.5 idempotency).\n private _sensor: (EventTarget & { start(): void; stop(): void }) | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get x(): number | null {\n return this._reading.x;\n }\n\n get y(): number | null {\n return this._reading.y;\n }\n\n get z(): number | null {\n return this._reading.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-magnetometer:error-info-changed`), derived from `error`; the existing\n * `error` property/event are unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n /** No asynchronous probe to await: start()/stop() are synchronous\n * (docs/async-io-node-guidelines.md §3.8 is satisfied trivially, mirroring\n * NetworkCore). */\n get ready(): Promise<void> {\n return Promise.resolve();\n }\n\n // --- State setters ---\n\n // Deliberately NOT same-value guarded: a `reading` is a fresh sample, not a\n // settled state, so it must dispatch every time even when the values happen\n // to repeat (docs/sensor-tag-design.md §1.1).\n private _setReading(reading: WcsMagnetometerReading): void {\n this._reading = reading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:reading\", {\n detail: reading,\n bubbles: true,\n }));\n }\n\n private _setError(error: WcsMagnetometerErrorDetail | null): void {\n // Same-value guard (by error name + message): error is state-like, unlike\n // reading — a repeated identical error (same name and message) must not\n // redispatch. Note `error` is also STICKY: nothing calls _setError(null),\n // so a successful (re)start does not clear a prior failure — the monitoring\n // sensor family deliberately keeps the last observed error (docs/sensor-tag-design.md §1.5).\n if (this._error?.error === error?.error && this._error?.message === error?.message) return;\n this._error = error;\n // Keep the additive `errorInfo` taxonomy in sync with `error`: derive from the\n // error name (or null on clear). Fires before the `error` event so an observer\n // binding both sees the classification first, mirroring the io-node family.\n this._commitErrorInfo(error === null ? null : deriveMagnetometerErrorInfo(error.error, error.message));\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (which already same-value-guards on the error name\n // + message), so errorInfo transitions exactly when error does — no separate\n // guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-magnetometer:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start the sensor at the given `frequency` (Hz), or the platform default\n * when omitted. Idempotent while already started: a redundant start() does\n * not construct a second sensor instance (which would leak the first).\n * Restart with a different frequency via stop() + start().\n *\n * Synchronous, mirroring the native `Sensor.start()` — never throws\n * (docs/async-io-node-guidelines.md §3.6): both \"unsupported\" and a\n * synchronous constructor exception (permission denial, feature-policy\n * block) are converted to the `error` property instead of propagating.\n */\n start(frequency?: number): void {\n if (this._sensor) return;\n const sensor = this._createSensor(frequency);\n if (!sensor) return;\n sensor.addEventListener(\"reading\", this._onReading as EventListener);\n sensor.addEventListener(\"error\", this._onError as EventListener);\n this._sensor = sensor;\n try {\n sensor.start();\n } catch (e: any) {\n // Defensive: the platform contract says start()/stop() do not throw\n // (failures surface via the 'error' event), but never-throw is a hard\n // requirement here, so guard against a non-conformant implementation\n // too.\n this._teardownSensor();\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n }\n }\n\n /** Stop the sensor and detach its listeners. Safe to call when not started. */\n stop(): void {\n if (!this._sensor) return;\n try {\n this._sensor.stop();\n } catch {\n // Never-throw defensive guard, symmetric with start(). Teardown below\n // still runs so listeners are detached regardless.\n }\n this._teardownSensor();\n }\n\n /** Lifecycle alias for start(), so the Shell's connectedCallback can drive\n * this Core the same way as other IO nodes' observe()/dispose() pair. No\n * asynchronous probe, so the returned promise always resolves immediately. */\n observe(frequency?: number): Promise<void> {\n this.start(frequency);\n return this.ready;\n }\n\n /** Lifecycle alias for stop(), invoked from the Shell's disconnectedCallback. */\n dispose(): void {\n this.stop();\n }\n\n // --- Internal ---\n\n // Both call sites (start()'s catch, stop()) only ever invoke this once\n // `this._sensor` is already known non-null, so there is no null-guard here\n // (nothing to defend against).\n private _teardownSensor(): void {\n this._sensor!.removeEventListener(\"reading\", this._onReading as EventListener);\n this._sensor!.removeEventListener(\"error\", this._onError as EventListener);\n this._sensor = null;\n }\n\n /**\n * Construct the platform `Magnetometer`, guarding both non-support and a\n * synchronous constructor exception. Never calls the raw `new Magnetometer(...)`\n * anywhere else in this class — see docs/sensor-tag-design.md §1.5.\n *\n * API resolution is call-time (docs/async-io-node-guidelines.md §3.7):\n * re-checked on every start(), never cached, so tests can install/remove\n * the global freely and an unsupported environment is always reported\n * correctly.\n */\n private _createSensor(frequency?: number): (EventTarget & { start(): void; stop(): void }) | null {\n const Ctor = (globalThis as any).Magnetometer;\n if (typeof Ctor !== \"function\") {\n this._setError({ error: \"unsupported\", message: \"Magnetometer is not supported\" });\n return null;\n }\n try {\n return new Ctor(frequency !== undefined ? { frequency } : undefined);\n } catch (e: any) {\n // SecurityError (permission denial, feature-policy block) or any other\n // synchronous construction failure. Mirrors the FetchCore._doFetch\n // try/catch structure (packages/fetch/src/core/FetchCore.ts) — a\n // synchronous constructor call here instead of an awaited fetch().\n this._setError({ error: e?.name ?? \"error\", message: e?.message ?? String(e) });\n return null;\n }\n }\n\n private _onReading = (event: Event): void => {\n const sensor = event.target as unknown as { x: number | null; y: number | null; z: number | null };\n this._setReading({ x: sensor.x, y: sensor.y, z: sensor.z });\n };\n\n private _onError = (event: Event): void => {\n const err = (event as any).error as { name?: string; message?: string } | undefined;\n // Fallback is a meaningful constant, NOT String(err): a SensorErrorEvent\n // without an `error` field would otherwise stringify `undefined` into the\n // literal message \"undefined\" (aligned across the sensor family).\n this._setError({ error: err?.name ?? \"error\", message: err?.message ?? \"Sensor error\" });\n };\n}\n","import { IWcBindable, WcsMagnetometerErrorDetail } from \"../types.js\";\nimport { MagnetometerCore } from \"../core/MagnetometerCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\n\n/**\n * `<wcs-magnetometer>` — declarative Generic Sensor API (`Magnetometer`)\n * monitor + start/stop control.\n *\n * Unlike `<wcs-network>` / `<wcs-permission>` (pure monitors), this Shell is a\n * bidirectional node: `start`/`stop` commands (command-token: state → element)\n * alongside the `x`/`y`/`z`/`error` observable surface (event-token: element →\n * state). The `frequency` attribute is the sole configuration input, forwarded\n * to the platform `Magnetometer` constructor's `{ frequency }` option\n * (docs/sensor-tag-design.md §1.2). The getter normalizes it: a non-finite or\n * non-positive value (NaN, 0, negative) reads back as `null` — meaning \"no\n * frequency specified\" — so start() falls back to the platform default rather\n * than forwarding a value the sensor would reject. Any positive finite value is\n * passed through verbatim (no upper-bound clamping — an out-of-range-but-positive\n * rate is still left to the browser/sensor to reject via `error`).\n *\n * Permission handling is intentionally NOT implemented here. Compose with\n * `<wcs-permission name=\"magnetometer\">` instead (see the README's permission\n * example, \"Gate on permission, then start\", and docs/sensor-tag-design.md).\n */\nexport class WcsMagnetometer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...MagnetometerCore.wcBindable,\n inputs: [{ name: \"frequency\" }],\n // Core の commands をそのまま継承(単一情報源)。\n commands: MagnetometerCore.wcBindable.commands,\n };\n\n private _core: MagnetometerCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new MagnetometerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-magnetometer:error\": (d) => ({ error: d != null }),\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 (docs/async-io-node-guidelines.md §3.6): attachInternals is\n // absent 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 /**\n * Sampling frequency in Hz. Reads back `null` when unset, blank, or when the\n * attribute does not parse to a positive finite number (NaN, `\"0\"`, negative)\n * — in every such \"no usable value\" case the platform default applies.\n *\n * Note the deliberate set/get asymmetry: `set frequency(0)` (or any\n * non-positive/non-finite value) still writes the attribute verbatim for\n * transparency/inspectability, but the getter normalizes it back to `null`.\n * A round-trip through a non-positive value therefore does NOT preserve it —\n * that value carries no valid sampling meaning, so it is treated as \"unset\"\n * on read. Only positive finite frequencies survive a set→get round-trip.\n *\n * This value is read only at `start()` time. There is no\n * `attributeChangedCallback`, and `MagnetometerCore.start()` is idempotent\n * while already started (a redundant call is a no-op), so setting\n * `frequency` (attribute or property) on an already-running sensor has no\n * effect until the caller `stop()`s and `start()`s again (see the README's\n * \"Notes & limitations\").\n */\n get frequency(): number | null {\n const attr = this.getAttribute(\"frequency\");\n if (attr === null || attr.trim() === \"\") return null;\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n }\n\n set frequency(value: number | null | undefined) {\n if (value === null || value === undefined) {\n this.removeAttribute(\"frequency\");\n } else {\n this.setAttribute(\"frequency\", String(value));\n }\n }\n\n // --- Core delegated getters ---\n\n get x(): number | null {\n return this._core.x;\n }\n\n get y(): number | null {\n return this._core.y;\n }\n\n get z(): number | null {\n return this._core.z;\n }\n\n get error(): WcsMagnetometerErrorDetail | null {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n start(): void {\n this._core.start(this.frequency ?? undefined);\n }\n\n stop(): void {\n this._core.stop();\n }\n\n // --- Lifecycle ---\n\n // Deliberately does NOT auto-start the sensor on connect. Unlike\n // Geolocation (whose default phase acquires a fix immediately unless\n // `manual` is set), Magnetometer has no such \"connect implies observing\"\n // precedent in the design doc (docs/sensor-tag-design.md §1.3):\n // start/stop are the only commands, so connecting the element merely makes\n // it inert until a command-token `start` (or the `start()` method) is\n // invoked. This also keeps behavior predictable when composed with\n // `<wcs-permission name=\"magnetometer\">`: the caller decides when to start,\n // typically gated on `granted`.\n connectedCallback(): void {\n this.style.display = \"none\";\n // No asynchronous probe to await (docs/async-io-node-guidelines.md §3.8);\n // kept for SSR uniformity with other IO nodes.\n this._connectedCallbackPromise = this._core.ready;\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 bootstrapMagnetometer(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsMagnetometer } from \"./components/Magnetometer.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.magnetometer)) {\n customElements.define(config.tagNames.magnetometer, WcsMagnetometer);\n }\n}\n"],"names":["_config","tagNames","magnetometer","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","WCS_MAGNETOMETER_ERROR_CODE","CapabilityMissing","NotAllowed","NotReadable","SensorError","NULL_READING","x","y","z","MagnetometerCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","commands","_target","_reading","_error","_errorInfo","_sensor","constructor","target","super","this","error","errorInfo","ready","Promise","resolve","_setReading","reading","dispatchEvent","CustomEvent","bubbles","_setError","message","_commitErrorInfo","code","phase","recoverable","info","start","frequency","sensor","_createSensor","addEventListener","_onReading","_onError","_teardownSensor","String","stop","observe","dispose","removeEventListener","Ctor","globalThis","Magnetometer","undefined","err","WcsMagnetometer","HTMLElement","wcBindable","inputs","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","attr","getAttribute","trim","parsed","Number","isFinite","value","removeAttribute","setAttribute","connectedCallbackPromise","connectedCallback","style","display","disconnectedCallback","bootstrapMagnetometer","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/magnetometer",
3
- "version": "1.20.0",
3
+ "version": "1.21.1",
4
4
  "description": "Declarative Magnetometer component for Web Components. Framework-agnostic Generic Sensor API (Magnetometer) monitor via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",