@wcstack/share 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -113,6 +113,60 @@ const canShare: boolean = shareEl.canShare({ url: "https://example.com" });
113
113
 
114
114
  **無し。** `share(data)` の `data` は呼び出しごとに変わる値であり、属性としてあらかじめ要素に貼っておく設定値ではなく、コマンド引数です。
115
115
 
116
+ ## `:state()` による CSS スタイリング
117
+
118
+ `<wcs-share>` は 3 つの boolean 出力ステートを
119
+ [`ElementInternals` の `CustomStateSet`](https://developer.mozilla.org/ja/docs/Web/API/CustomStateSet)
120
+ に反映します。そのため `data-wcs` バインディングやクラスの手動トグルなしに、CSS の
121
+ `:state()` 疑似クラスで直接スタイリングできます。
122
+
123
+ | ステート | on になる条件 |
124
+ |----------|----------------|
125
+ | `loading` | `wcs-share:loading-changed` が `true` で発火(`false` でクリア) |
126
+ | `cancelled` | `wcs-share:cancelled-changed` が `true` で発火(`false` でクリア) |
127
+ | `error` | `wcs-share:error` が非 `null` の detail で発火(`null` でクリア) |
128
+
129
+ ```css
130
+ wcs-share:state(loading) ~ .spinner { display: block; }
131
+ wcs-share:state(loading) ~ .spinner { display: none; } /* デフォルト */
132
+
133
+ wcs-share:state(cancelled) ~ .hint { display: block; }
134
+ form:has(wcs-share:state(error)) .banner { display: block; }
135
+ ```
136
+
137
+ 属性やクラスと異なり `:state()` は要素の外部から書き込めないため、この出力ステートが
138
+ 入力と混同される心配がありません。
139
+
140
+ **対応ブラウザ**(新構文 `:state(x)`): Chrome/Edge 125+、Safari 17.4+、Firefox 126+。
141
+ 非対応の環境ではステートが一切 set されないだけです — `:state()` セレクタがマッチしなく
142
+ なりますが、`<wcs-share>` 自体は通常どおり動作し続けます(graceful degradation・never-throw)。
143
+
144
+ **SSR:** `:state()` は HTML にシリアライズできないため、サーバーレンダリングされた
145
+ マークアップの初期ペイントにはこれらのステートは乗りません(`@wcstack/server` は無改変)。
146
+ ハイドレーション前の見た目を制御したい場合は、代わりに `wcs-share:not(:defined)` と組み合わせてください。
147
+
148
+ ### デバッグ
149
+
150
+ カスタムステートは DevTools の Elements パネルには表示されず、`attachInternals()`
151
+ は同一要素に 2 回呼べないため、コンソールから直接覗く手段がありません。そのための
152
+ デバッグ専用の補助を 2 つ用意しています:
153
+
154
+ - `el.debugStates` — 現在 on になっているステート名の**スナップショット**配列
155
+ (例: `["loading"]`)。`wc-bindable` の一部ではなく(バインド対象ではない)、
156
+ 形状も契約として保証されません — デバッグ用途にのみ使ってください。
157
+ - `debug-states` 属性(opt-in・既定 OFF)は、ステート変化を要素の
158
+ `data-wcs-state-loading` / `data-wcs-state-cancelled` /
159
+ `data-wcs-state-error` 属性にミラーします。
160
+ Elements パネルを開いておけば、トグルのたびにハイライトされます:
161
+
162
+ ```html
163
+ <wcs-share debug-states></wcs-share>
164
+ ```
165
+
166
+ **CSS は `data-wcs-state-*` ではなく `:state()` に書いてください。** ミラーされた
167
+ 属性は、DevTools を開いた状態でステート変化を可視化するためだけのものであり、
168
+ スタイリング用の正式なフックではありません。
169
+
116
170
  ## 注意・制限
117
171
 
118
172
  - **`autoTrigger` を持たない。** `navigator.share()` は実際のユーザー操作の文脈内から呼び出す必要があります。ノード側が自動トリガーを提供しても、そのトリガー自体がジェスチャー文脈を継承しないため、`@wcstack/fullscreen` と同様にこのノードは自動トリガーを持ちません。クリックハンドラを直接 `$command.doShare.emit(...)` に配線してください。
package/README.md CHANGED
@@ -113,6 +113,62 @@ It returns `false` (rather than throwing) when `navigator.canShare` is absent.
113
113
 
114
114
  **None.** `share(data)`'s `data` varies on every call — it is a command argument, not a value to park on the element ahead of time as an attribute.
115
115
 
116
+ ## CSS styling with `:state()`
117
+
118
+ `<wcs-share>` reflects three boolean output states onto its
119
+ [`ElementInternals` `CustomStateSet`](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet),
120
+ so you can style it directly from CSS with the `:state()` pseudo-class — no
121
+ `data-wcs` binding or extra class toggling required.
122
+
123
+ | State | On when |
124
+ |-------|---------|
125
+ | `loading` | `wcs-share:loading-changed` fires with `true` (cleared on `false`) |
126
+ | `cancelled` | `wcs-share:cancelled-changed` fires with `true` (cleared on `false`) |
127
+ | `error` | `wcs-share:error` fires with a non-`null` detail (cleared on `null`) |
128
+
129
+ ```css
130
+ wcs-share:state(loading) ~ .spinner { display: block; }
131
+ wcs-share:state(loading) ~ .spinner { display: none; } /* default */
132
+
133
+ wcs-share:state(cancelled) ~ .hint { display: block; }
134
+ form:has(wcs-share:state(error)) .banner { display: block; }
135
+ ```
136
+
137
+ Unlike attributes or classes, `:state()` cannot be written from outside the
138
+ element, so there is no risk of confusing this output state with an input.
139
+
140
+ **Browser support** (`:state(x)` syntax): Chrome/Edge 125+, Safari 17.4+,
141
+ Firefox 126+. In older browsers the states are simply never set — `:state()`
142
+ selectors never match, but `<wcs-share>` itself keeps working normally
143
+ (graceful degradation, never-throw).
144
+
145
+ **SSR**: `:state()` cannot be serialized into HTML, so server-rendered markup
146
+ never carries these states on first paint (`@wcstack/server` is unaffected).
147
+ If you need to style the pre-hydration gap, pair your rule with
148
+ `wcs-share:not(:defined)` instead.
149
+
150
+ ### Debugging
151
+
152
+ Custom states are invisible in DevTools' Elements panel and `attachInternals()`
153
+ cannot be called twice, so there is no console way to inspect them directly.
154
+ Two debug-only aids are provided for that:
155
+
156
+ - `el.debugStates` — a **snapshot** array of the currently-on state names
157
+ (e.g. `["loading"]`). It is not part of `wc-bindable` (not a bind target)
158
+ and its shape is not a guaranteed contract — use it for debugging only.
159
+ - The `debug-states` attribute (opt-in, default off) mirrors state changes
160
+ onto `data-wcs-state-loading` / `data-wcs-state-cancelled` /
161
+ `data-wcs-state-error` attributes on the element, so the Elements panel
162
+ highlights them as they toggle:
163
+
164
+ ```html
165
+ <wcs-share debug-states></wcs-share>
166
+ ```
167
+
168
+ **Write your CSS against `:state()`, not `data-wcs-state-*`.** The mirrored
169
+ attributes exist purely to make state changes visible while debugging with
170
+ DevTools open; they are not a supported styling hook.
171
+
116
172
  ## Notes & limitations
117
173
 
118
174
  - **No `autoTrigger`.** `navigator.share()` must be invoked from within a real user gesture. A node-provided auto-trigger would not itself carry that gesture context, so — like `@wcstack/fullscreen` — this node has none. Wire the click handler directly to `$command.doShare.emit(...)`.
package/dist/index.d.ts CHANGED
@@ -136,7 +136,11 @@ declare class WcsShare extends HTMLElement {
136
136
  static wcBindable: IWcBindable;
137
137
  private _core;
138
138
  private _connectedCallbackPromise;
139
+ private _internals;
139
140
  constructor();
141
+ get debugStates(): string[];
142
+ private _initInternals;
143
+ private _wireStates;
140
144
  get value(): WcsShareData | null;
141
145
  get loading(): boolean;
142
146
  get error(): any;
package/dist/index.esm.js CHANGED
@@ -236,9 +236,64 @@ class WcsShare extends HTMLElement {
236
236
  };
237
237
  _core;
238
238
  _connectedCallbackPromise = Promise.resolve();
239
+ _internals = null;
239
240
  constructor() {
240
241
  super();
241
242
  this._core = new ShareCore(this);
243
+ this._internals = this._initInternals();
244
+ this._wireStates({
245
+ "wcs-share:loading-changed": (d) => ({ loading: d === true }),
246
+ "wcs-share:cancelled-changed": (d) => ({ cancelled: d === true }),
247
+ "wcs-share:error": (d) => ({ error: d != null }),
248
+ });
249
+ }
250
+ // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of
251
+ // wc-bindable (not a bind target); see README "CSS styling with :state()".
252
+ // MUST NOT return the live CustomStateSet (that would let callers write
253
+ // states from outside, defeating the point of :state() being read-only).
254
+ get debugStates() {
255
+ return this._internals ? [...this._internals.states] : [];
256
+ }
257
+ _initInternals() {
258
+ // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent
259
+ // in happy-dom / older environments, and pre-125 Chromium rejects
260
+ // non-dashed state names from states.add() (probed and discarded here).
261
+ // Either case silently disables reflection — the component still works,
262
+ // it just doesn't expose :state() selectors.
263
+ try {
264
+ if (typeof this.attachInternals !== "function")
265
+ return null;
266
+ const internals = this.attachInternals();
267
+ internals.states.add("wcs-probe");
268
+ internals.states.delete("wcs-probe");
269
+ return internals;
270
+ }
271
+ catch {
272
+ return null;
273
+ }
274
+ }
275
+ _wireStates(map) {
276
+ if (this._internals === null)
277
+ return;
278
+ const states = this._internals.states;
279
+ for (const [event, toStates] of Object.entries(map)) {
280
+ this.addEventListener(event, (e) => {
281
+ const debug = this.hasAttribute("debug-states");
282
+ for (const [name, on] of Object.entries(toStates(e.detail))) {
283
+ try {
284
+ if (on) {
285
+ states.add(name);
286
+ }
287
+ else {
288
+ states.delete(name);
289
+ }
290
+ }
291
+ catch { /* never-throw */ }
292
+ if (debug)
293
+ this.toggleAttribute(`data-wcs-state-${name}`, on);
294
+ }
295
+ });
296
+ }
242
297
  }
243
298
  // --- Core delegated getters ---
244
299
  get value() {
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/ShareCore.ts","../src/components/Share.ts","../src/registerComponents.ts","../src/bootstrapShare.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n share: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n share: \"wcs-share\",\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, WcsShareData } from \"../types.js\";\n\n/**\n * Headless Web Share primitive. A thin, framework-agnostic wrapper around\n * `navigator.share(data)` exposed through the wc-bindable protocol.\n *\n * This is a simplified derivative of `FetchCore._doFetch`\n * (docs/web-share-tag-design.md §2): it keeps the single `_gen` generation\n * guard, the same-value-guarded private setters, and the never-throw\n * try/catch wrapper, but drops `AbortController`/`abort()` entirely —\n * `navigator.share()` accepts no `AbortSignal` and there is no platform\n * mechanism for a caller to cancel an in-flight share dialog. A share dialog\n * is also a single system-modal surface (at most one open at a time), so the\n * \"a new call supersedes the previous one\" plumbing that `FetchCore` needs\n * has no counterpart here either.\n */\nexport class ShareCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-share:complete\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-share:loading-changed\" },\n { name: \"error\", event: \"wcs-share:error\" },\n { name: \"cancelled\", event: \"wcs-share:cancelled-changed\" },\n ],\n commands: [\n { name: \"share\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _value: WcsShareData | null = null;\n private _loading: boolean = false;\n private _error: any = null;\n private _cancelled: boolean = false;\n // Generation guard (§3.4 of the guidelines): bumped ONLY by dispose(). A\n // share() that settles after dispose() has a stale `gen` and MUST NOT write\n // state to a torn-down element. Unlike FetchCore/EyedropperCore, share()\n // itself does NOT bump `_gen` on each call: docs/web-share-tag-design.md §2\n // deliberately drops the \"a new call supersedes the previous one\" plumbing\n // those cores need, because the platform allows only one open share dialog\n // at a time (a second concurrent share() rejects with InvalidStateError on\n // its own). Bumping `_gen` per call would instead let a fast-failing second\n // call incorrectly invalidate a still-pending first call's eventual\n // success. Also not bumped on the unsupported early-return — no\n // asynchronous work is started, so there is no generation to protect\n // (docs/web-share-tag-design.md §8).\n private _gen = 0;\n // SSR (§3.8): no asynchronous probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get value(): WcsShareData | null {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n get cancelled(): boolean {\n return this._cancelled;\n }\n\n // Lifecycle (§3.5). Share is command-driven with no subscription to\n // establish, so observe() is an idempotent no-op that resolves once ready;\n // dispose() only invalidates any in-flight share() (there is nothing to\n // abort or unsubscribe).\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n }\n\n private _setLoading(loading: boolean): void {\n if (this._loading === loading) return;\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // Deliberately NO same-value guard (unlike error/loading/cancelled below).\n // `value` is a success-completion signal, not idempotent state: it is written\n // only on a successful share(), and wcs-share:complete is the *sole* success\n // notification. Two consecutive successful shares — even with the same `data`\n // object reference, or a data-less share echoing null when value is already\n // null — are two distinct completions and must each re-fire wcs-share:complete\n // so an `$on`/eventToken consumer (and a `value:` binding) sees every success.\n // This matches clipboard `_setRead` / broadcast `_setMessage`, which carve\n // result/event values out of the §3.3 guard for the same reason.\n private _setValue(value: WcsShareData | null): void {\n this._value = value;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:complete\", {\n detail: { value },\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n if (this._error === error) return;\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setCancelled(cancelled: boolean): void {\n if (this._cancelled === cancelled) return;\n this._cancelled = cancelled;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:cancelled-changed\", {\n detail: cancelled,\n bubbles: true,\n }));\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.share freely and lets an unsupported environment be detected\n // correctly on every call.\n private _api(): ((data?: WcsShareData) => Promise<void>) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav?.share === \"function\" ? nav.share.bind(nav) : undefined;\n }\n\n async share(data?: WcsShareData): Promise<WcsShareData | null> {\n // never-throw + unsupported (§8): resolve API at call time and bail out\n // immediately if absent. No _gen bump — no asynchronous work is started,\n // so there is no generation to protect, and navigator.share() itself is\n // never invoked.\n const shareFn = this._api();\n if (!shareFn) {\n this._setError({ message: \"Web Share API is not supported in this browser.\" });\n return null;\n }\n\n // Captured, not bumped (see the `_gen` field docs above): share() does\n // not supersede a prior in-flight call, only dispose() invalidates.\n const gen = this._gen;\n\n this._setLoading(true);\n // Reset the previous outcome before starting a new share so a stale\n // cancelled/error does not linger into this call's result\n // (docs/web-share-tag-design.md §3).\n this._setError(null);\n this._setCancelled(false);\n\n try {\n await shareFn(data);\n\n // Stale completion (dispose() ran while the share dialog was open).\n // Drop the result without writing state.\n if (gen !== this._gen) {\n return null;\n }\n\n // navigator.share() resolves `Promise<void>` — there is no payload to\n // read off the API, so `value` is synthesized as an echo of the caller's\n // `data`, signalling \"this share completed successfully\"\n // (docs/web-share-tag-design.md §4).\n this._setValue(data ?? null);\n this._setLoading(false);\n return data ?? null;\n } catch (e: any) {\n // Stale completion (dispose() ran while the share dialog was open).\n if (gen !== this._gen) {\n return null;\n }\n if (e?.name === \"AbortError\") {\n // The user dismissed the share sheet — a routine cancellation, not a\n // platform failure. Kept out of `error` (docs/web-share-tag-design.md §3).\n this._setCancelled(true);\n } else {\n this._setError(e);\n }\n this._setLoading(false);\n return null;\n }\n }\n}\n","import { IWcBindable, WcsShareData } from \"../types.js\";\nimport { ShareCore } from \"../core/ShareCore.js\";\n\n/**\n * `<wcs-share>` — declarative Web Share API primitive.\n *\n * The smallest command-only Shell in the batch (docs/web-share-tag-design.md\n * §10): no attributes at all. `share(data)`'s `data` is a per-call argument,\n * not a declarative setting to park on the element ahead of time.\n */\nexport class WcsShare extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so the state binder can await it uniformly across\n // all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...ShareCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。\n commands: ShareCore.wcBindable.commands,\n };\n\n private _core: ShareCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new ShareCore(this);\n }\n\n // --- Core delegated getters ---\n\n get value(): WcsShareData | null {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get cancelled(): boolean {\n return this._core.cancelled;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n share(data?: WcsShareData): Promise<WcsShareData | null> {\n return this._core.share(data);\n }\n\n /**\n * Synchronous, side-effect-free delegation to `navigator.canShare(data)`\n * (docs/web-share-tag-design.md §6). Deliberately outside `wcBindable`\n * (not a `properties`/`commands` entry): the platform method takes an\n * argument that varies per call, which does not fit the \"observe with no\n * arguments\" shape of a bindable property, and is synchronous, which does\n * not fit the fire-and-observe-via-event shape of a command.\n *\n * No never-throw wrapping: the platform method itself is synchronous and\n * side-effect-free, so a throw here would indicate a browser bug rather\n * than a condition this Shell should paper over. `navigator.canShare` is\n * still resolved defensively (some environments lack it even when `share`\n * exists), returning `false` rather than throwing in that case.\n */\n canShare(data?: WcsShareData): boolean {\n const nav = (globalThis as any).navigator;\n return typeof nav?.canShare === \"function\" ? nav.canShare(data) : false;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsShare } from \"./components/Share.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.share)) {\n customElements.define(config.tagNames.share, WcsShare);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapShare(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"AAQA,MAAM,OAAO,GAAoB;AAC/B,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE,WAAW;AACnB,KAAA;CACF;AAED,SAAS,UAAU,CAAI,GAAM,EAAA;AAC3B,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,QAAA,OAAO,GAAG;AACvD,IAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IAClB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AAClC,QAAA,UAAU,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC;IACnD;AACA,IAAA,OAAO,GAAG;AACZ;AAEA,SAAS,SAAS,CAAI,GAAM,EAAA;AAC1B,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,QAAA,OAAO,GAAG;IACvD,MAAM,KAAK,GAA4B,EAAE;IACzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAClC,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC;IAC/D;AACA,IAAA,OAAO,KAAU;AACnB;AAEA,IAAI,YAAY,GAAmB,IAAI;AAEhC,MAAM,MAAM,GAAY,OAAkB;SAEjC,SAAS,GAAA;IACvB,IAAI,CAAC,YAAY,EAAE;QACjB,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/C;AACA,IAAA,OAAO,YAAY;AACrB;AAEM,SAAU,SAAS,CAAC,aAA8B,EAAA;AACtD,IAAA,IAAI,aAAa,CAAC,QAAQ,EAAE;QAC1B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;IACzD;IACA,YAAY,GAAG,IAAI;AACrB;;AC9CA;;;;;;;;;;;;;AAaG;AACG,MAAO,SAAU,SAAQ,WAAW,CAAA;IACxC,OAAO,UAAU,GAAgB;AAC/B,QAAA,QAAQ,EAAE,aAAa;AACvB,QAAA,OAAO,EAAE,CAAC;AACV,QAAA,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,CAAC,CAAQ,KAAM,CAAiB,CAAC,MAAM,CAAC,KAAK,EAAE;AACrG,YAAA,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE;AACvD,YAAA,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE;AAC3C,YAAA,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,6BAA6B,EAAE;AAC5D,SAAA;AACD,QAAA,QAAQ,EAAE;AACR,YAAA,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;AAC/B,SAAA;KACF;AAEO,IAAA,OAAO;IACP,MAAM,GAAwB,IAAI;IAClC,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAQ,IAAI;IAClB,UAAU,GAAY,KAAK;;;;;;;;;;;;;IAa3B,IAAI,GAAG,CAAC;;AAER,IAAA,MAAM,GAAkB,OAAO,CAAC,OAAO,EAAE;AAEjD,IAAA,WAAA,CAAY,MAAoB,EAAA;AAC9B,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,IAAI;IAC/B;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO,IAAI,CAAC,QAAQ;IACtB;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,IAAI,SAAS,GAAA;QACX,OAAO,IAAI,CAAC,UAAU;IACxB;;;;;IAMA,OAAO,GAAA;QACL,OAAO,IAAI,CAAC,MAAM;IACpB;IAEA,OAAO,GAAA;QACL,IAAI,CAAC,IAAI,EAAE;IACb;AAEQ,IAAA,WAAW,CAAC,OAAgB,EAAA;AAClC,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE;AAC/B,QAAA,IAAI,CAAC,QAAQ,GAAG,OAAO;QACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,2BAA2B,EAAE;AACtE,YAAA,MAAM,EAAE,OAAO;AACf,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;;;;;;;;;;AAWQ,IAAA,SAAS,CAAC,KAA0B,EAAA;AAC1C,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;QACnB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,oBAAoB,EAAE;YAC/D,MAAM,EAAE,EAAE,KAAK,EAAE;AACjB,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,SAAS,CAAC,KAAU,EAAA;AAC1B,QAAA,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK;YAAE;AAC3B,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;QACnB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,iBAAiB,EAAE;AAC5D,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,aAAa,CAAC,SAAkB,EAAA;AACtC,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE;AACnC,QAAA,IAAI,CAAC,UAAU,GAAG,SAAS;QAC3B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,6BAA6B,EAAE;AACxE,YAAA,MAAM,EAAE,SAAS;AACjB,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;;;;IAKQ,IAAI,GAAA;AACV,QAAA,MAAM,GAAG,GAAI,UAAkB,CAAC,SAAS;QACzC,OAAO,OAAO,GAAG,EAAE,KAAK,KAAK,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS;IAC3E;IAEA,MAAM,KAAK,CAAC,IAAmB,EAAA;;;;;AAK7B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE;QAC3B,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;AAC9E,YAAA,OAAO,IAAI;QACb;;;AAIA,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI;AAErB,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;;;;AAItB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AACpB,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;AAEzB,QAAA,IAAI;AACF,YAAA,MAAM,OAAO,CAAC,IAAI,CAAC;;;AAInB,YAAA,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAA,OAAO,IAAI;YACb;;;;;AAMA,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC;AAC5B,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YACvB,OAAO,IAAI,IAAI,IAAI;QACrB;QAAE,OAAO,CAAM,EAAE;;AAEf,YAAA,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAA,OAAO,IAAI;YACb;AACA,YAAA,IAAI,CAAC,EAAE,IAAI,KAAK,YAAY,EAAE;;;AAG5B,gBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;YAC1B;iBAAO;AACL,gBAAA,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACnB;AACA,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AACvB,YAAA,OAAO,IAAI;QACb;IACF;;;AC/LF;;;;;;AAMG;AACG,MAAO,QAAS,SAAQ,WAAW,CAAA;;;;AAIvC,IAAA,OAAO,2BAA2B,GAAG,IAAI;IAEzC,OAAO,UAAU,GAAgB;QAC/B,GAAG,SAAS,CAAC,UAAU;AACvB,QAAA,MAAM,EAAE,EAAE;;AAEV,QAAA,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ;KACxC;AAEO,IAAA,KAAK;AACL,IAAA,yBAAyB,GAAkB,OAAO,CAAC,OAAO,EAAE;AAEpE,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;QACP,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC;IAClC;;AAIA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK;IACzB;AAEA,IAAA,IAAI,OAAO,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO;IAC3B;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK;IACzB;AAEA,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS;IAC7B;AAEA,IAAA,IAAI,wBAAwB,GAAA;QAC1B,OAAO,IAAI,CAAC,yBAAyB;IACvC;;AAIA,IAAA,KAAK,CAAC,IAAmB,EAAA;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAC/B;AAEA;;;;;;;;;;;;;AAaG;AACH,IAAA,QAAQ,CAAC,IAAmB,EAAA;AAC1B,QAAA,MAAM,GAAG,GAAI,UAAkB,CAAC,SAAS;AACzC,QAAA,OAAO,OAAO,GAAG,EAAE,QAAQ,KAAK,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK;IACzE;;IAIA,iBAAiB,GAAA;AACf,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;QAC3B,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;IACvD;IAEA,oBAAoB,GAAA;AAClB,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;IACtB;;;SCpFc,kBAAkB,GAAA;AAChC,IAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAC9C,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACxD;AACF;;ACHM,SAAU,cAAc,CAAC,UAA4B,EAAA;IACzD,IAAI,UAAU,EAAE;QACd,SAAS,CAAC,UAAU,CAAC;IACvB;AACA,IAAA,kBAAkB,EAAE;AACtB;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/ShareCore.ts","../src/components/Share.ts","../src/registerComponents.ts","../src/bootstrapShare.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n share: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n share: \"wcs-share\",\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, WcsShareData } from \"../types.js\";\n\n/**\n * Headless Web Share primitive. A thin, framework-agnostic wrapper around\n * `navigator.share(data)` exposed through the wc-bindable protocol.\n *\n * This is a simplified derivative of `FetchCore._doFetch`\n * (docs/web-share-tag-design.md §2): it keeps the single `_gen` generation\n * guard, the same-value-guarded private setters, and the never-throw\n * try/catch wrapper, but drops `AbortController`/`abort()` entirely —\n * `navigator.share()` accepts no `AbortSignal` and there is no platform\n * mechanism for a caller to cancel an in-flight share dialog. A share dialog\n * is also a single system-modal surface (at most one open at a time), so the\n * \"a new call supersedes the previous one\" plumbing that `FetchCore` needs\n * has no counterpart here either.\n */\nexport class ShareCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-share:complete\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-share:loading-changed\" },\n { name: \"error\", event: \"wcs-share:error\" },\n { name: \"cancelled\", event: \"wcs-share:cancelled-changed\" },\n ],\n commands: [\n { name: \"share\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _value: WcsShareData | null = null;\n private _loading: boolean = false;\n private _error: any = null;\n private _cancelled: boolean = false;\n // Generation guard (§3.4 of the guidelines): bumped ONLY by dispose(). A\n // share() that settles after dispose() has a stale `gen` and MUST NOT write\n // state to a torn-down element. Unlike FetchCore/EyedropperCore, share()\n // itself does NOT bump `_gen` on each call: docs/web-share-tag-design.md §2\n // deliberately drops the \"a new call supersedes the previous one\" plumbing\n // those cores need, because the platform allows only one open share dialog\n // at a time (a second concurrent share() rejects with InvalidStateError on\n // its own). Bumping `_gen` per call would instead let a fast-failing second\n // call incorrectly invalidate a still-pending first call's eventual\n // success. Also not bumped on the unsupported early-return — no\n // asynchronous work is started, so there is no generation to protect\n // (docs/web-share-tag-design.md §8).\n private _gen = 0;\n // SSR (§3.8): no asynchronous probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get value(): WcsShareData | null {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n get cancelled(): boolean {\n return this._cancelled;\n }\n\n // Lifecycle (§3.5). Share is command-driven with no subscription to\n // establish, so observe() is an idempotent no-op that resolves once ready;\n // dispose() only invalidates any in-flight share() (there is nothing to\n // abort or unsubscribe).\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n }\n\n private _setLoading(loading: boolean): void {\n if (this._loading === loading) return;\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // Deliberately NO same-value guard (unlike error/loading/cancelled below).\n // `value` is a success-completion signal, not idempotent state: it is written\n // only on a successful share(), and wcs-share:complete is the *sole* success\n // notification. Two consecutive successful shares — even with the same `data`\n // object reference, or a data-less share echoing null when value is already\n // null — are two distinct completions and must each re-fire wcs-share:complete\n // so an `$on`/eventToken consumer (and a `value:` binding) sees every success.\n // This matches clipboard `_setRead` / broadcast `_setMessage`, which carve\n // result/event values out of the §3.3 guard for the same reason.\n private _setValue(value: WcsShareData | null): void {\n this._value = value;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:complete\", {\n detail: { value },\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n if (this._error === error) return;\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setCancelled(cancelled: boolean): void {\n if (this._cancelled === cancelled) return;\n this._cancelled = cancelled;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:cancelled-changed\", {\n detail: cancelled,\n bubbles: true,\n }));\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.share freely and lets an unsupported environment be detected\n // correctly on every call.\n private _api(): ((data?: WcsShareData) => Promise<void>) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav?.share === \"function\" ? nav.share.bind(nav) : undefined;\n }\n\n async share(data?: WcsShareData): Promise<WcsShareData | null> {\n // never-throw + unsupported (§8): resolve API at call time and bail out\n // immediately if absent. No _gen bump — no asynchronous work is started,\n // so there is no generation to protect, and navigator.share() itself is\n // never invoked.\n const shareFn = this._api();\n if (!shareFn) {\n this._setError({ message: \"Web Share API is not supported in this browser.\" });\n return null;\n }\n\n // Captured, not bumped (see the `_gen` field docs above): share() does\n // not supersede a prior in-flight call, only dispose() invalidates.\n const gen = this._gen;\n\n this._setLoading(true);\n // Reset the previous outcome before starting a new share so a stale\n // cancelled/error does not linger into this call's result\n // (docs/web-share-tag-design.md §3).\n this._setError(null);\n this._setCancelled(false);\n\n try {\n await shareFn(data);\n\n // Stale completion (dispose() ran while the share dialog was open).\n // Drop the result without writing state.\n if (gen !== this._gen) {\n return null;\n }\n\n // navigator.share() resolves `Promise<void>` — there is no payload to\n // read off the API, so `value` is synthesized as an echo of the caller's\n // `data`, signalling \"this share completed successfully\"\n // (docs/web-share-tag-design.md §4).\n this._setValue(data ?? null);\n this._setLoading(false);\n return data ?? null;\n } catch (e: any) {\n // Stale completion (dispose() ran while the share dialog was open).\n if (gen !== this._gen) {\n return null;\n }\n if (e?.name === \"AbortError\") {\n // The user dismissed the share sheet — a routine cancellation, not a\n // platform failure. Kept out of `error` (docs/web-share-tag-design.md §3).\n this._setCancelled(true);\n } else {\n this._setError(e);\n }\n this._setLoading(false);\n return null;\n }\n }\n}\n","import { IWcBindable, WcsShareData } from \"../types.js\";\nimport { ShareCore } from \"../core/ShareCore.js\";\n\n/**\n * `<wcs-share>` — declarative Web Share API primitive.\n *\n * The smallest command-only Shell in the batch (docs/web-share-tag-design.md\n * §10): no attributes at all. `share(data)`'s `data` is a per-call argument,\n * not a declarative setting to park on the element ahead of time.\n */\nexport class WcsShare extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so the state binder can await it uniformly across\n // all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...ShareCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。\n commands: ShareCore.wcBindable.commands,\n };\n\n private _core: ShareCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new ShareCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-share:loading-changed\": (d) => ({ loading: d === true }),\n \"wcs-share:cancelled-changed\": (d) => ({ cancelled: d === true }),\n \"wcs-share: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 (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Core delegated getters ---\n\n get value(): WcsShareData | null {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get cancelled(): boolean {\n return this._core.cancelled;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n share(data?: WcsShareData): Promise<WcsShareData | null> {\n return this._core.share(data);\n }\n\n /**\n * Synchronous, side-effect-free delegation to `navigator.canShare(data)`\n * (docs/web-share-tag-design.md §6). Deliberately outside `wcBindable`\n * (not a `properties`/`commands` entry): the platform method takes an\n * argument that varies per call, which does not fit the \"observe with no\n * arguments\" shape of a bindable property, and is synchronous, which does\n * not fit the fire-and-observe-via-event shape of a command.\n *\n * No never-throw wrapping: the platform method itself is synchronous and\n * side-effect-free, so a throw here would indicate a browser bug rather\n * than a condition this Shell should paper over. `navigator.canShare` is\n * still resolved defensively (some environments lack it even when `share`\n * exists), returning `false` rather than throwing in that case.\n */\n canShare(data?: WcsShareData): boolean {\n const nav = (globalThis as any).navigator;\n return typeof nav?.canShare === \"function\" ? nav.canShare(data) : false;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsShare } from \"./components/Share.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.share)) {\n customElements.define(config.tagNames.share, WcsShare);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapShare(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"AAQA,MAAM,OAAO,GAAoB;AAC/B,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE,WAAW;AACnB,KAAA;CACF;AAED,SAAS,UAAU,CAAI,GAAM,EAAA;AAC3B,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,QAAA,OAAO,GAAG;AACvD,IAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IAClB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AAClC,QAAA,UAAU,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC;IACnD;AACA,IAAA,OAAO,GAAG;AACZ;AAEA,SAAS,SAAS,CAAI,GAAM,EAAA;AAC1B,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,QAAA,OAAO,GAAG;IACvD,MAAM,KAAK,GAA4B,EAAE;IACzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAClC,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC;IAC/D;AACA,IAAA,OAAO,KAAU;AACnB;AAEA,IAAI,YAAY,GAAmB,IAAI;AAEhC,MAAM,MAAM,GAAY,OAAkB;SAEjC,SAAS,GAAA;IACvB,IAAI,CAAC,YAAY,EAAE;QACjB,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/C;AACA,IAAA,OAAO,YAAY;AACrB;AAEM,SAAU,SAAS,CAAC,aAA8B,EAAA;AACtD,IAAA,IAAI,aAAa,CAAC,QAAQ,EAAE;QAC1B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;IACzD;IACA,YAAY,GAAG,IAAI;AACrB;;AC9CA;;;;;;;;;;;;;AAaG;AACG,MAAO,SAAU,SAAQ,WAAW,CAAA;IACxC,OAAO,UAAU,GAAgB;AAC/B,QAAA,QAAQ,EAAE,aAAa;AACvB,QAAA,OAAO,EAAE,CAAC;AACV,QAAA,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,CAAC,CAAQ,KAAM,CAAiB,CAAC,MAAM,CAAC,KAAK,EAAE;AACrG,YAAA,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE;AACvD,YAAA,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE;AAC3C,YAAA,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,6BAA6B,EAAE;AAC5D,SAAA;AACD,QAAA,QAAQ,EAAE;AACR,YAAA,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;AAC/B,SAAA;KACF;AAEO,IAAA,OAAO;IACP,MAAM,GAAwB,IAAI;IAClC,QAAQ,GAAY,KAAK;IACzB,MAAM,GAAQ,IAAI;IAClB,UAAU,GAAY,KAAK;;;;;;;;;;;;;IAa3B,IAAI,GAAG,CAAC;;AAER,IAAA,MAAM,GAAkB,OAAO,CAAC,OAAO,EAAE;AAEjD,IAAA,WAAA,CAAY,MAAoB,EAAA;AAC9B,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,IAAI;IAC/B;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,IAAI,OAAO,GAAA;QACT,OAAO,IAAI,CAAC,QAAQ;IACtB;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEA,IAAA,IAAI,SAAS,GAAA;QACX,OAAO,IAAI,CAAC,UAAU;IACxB;;;;;IAMA,OAAO,GAAA;QACL,OAAO,IAAI,CAAC,MAAM;IACpB;IAEA,OAAO,GAAA;QACL,IAAI,CAAC,IAAI,EAAE;IACb;AAEQ,IAAA,WAAW,CAAC,OAAgB,EAAA;AAClC,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE;AAC/B,QAAA,IAAI,CAAC,QAAQ,GAAG,OAAO;QACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,2BAA2B,EAAE;AACtE,YAAA,MAAM,EAAE,OAAO;AACf,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;;;;;;;;;;AAWQ,IAAA,SAAS,CAAC,KAA0B,EAAA;AAC1C,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;QACnB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,oBAAoB,EAAE;YAC/D,MAAM,EAAE,EAAE,KAAK,EAAE;AACjB,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,SAAS,CAAC,KAAU,EAAA;AAC1B,QAAA,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK;YAAE;AAC3B,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;QACnB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,iBAAiB,EAAE;AAC5D,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;AAEQ,IAAA,aAAa,CAAC,SAAkB,EAAA;AACtC,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE;AACnC,QAAA,IAAI,CAAC,UAAU,GAAG,SAAS;QAC3B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,6BAA6B,EAAE;AACxE,YAAA,MAAM,EAAE,SAAS;AACjB,YAAA,OAAO,EAAE,IAAI;AACd,SAAA,CAAC,CAAC;IACL;;;;IAKQ,IAAI,GAAA;AACV,QAAA,MAAM,GAAG,GAAI,UAAkB,CAAC,SAAS;QACzC,OAAO,OAAO,GAAG,EAAE,KAAK,KAAK,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS;IAC3E;IAEA,MAAM,KAAK,CAAC,IAAmB,EAAA;;;;;AAK7B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE;QAC3B,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;AAC9E,YAAA,OAAO,IAAI;QACb;;;AAIA,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI;AAErB,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;;;;AAItB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AACpB,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;AAEzB,QAAA,IAAI;AACF,YAAA,MAAM,OAAO,CAAC,IAAI,CAAC;;;AAInB,YAAA,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAA,OAAO,IAAI;YACb;;;;;AAMA,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC;AAC5B,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YACvB,OAAO,IAAI,IAAI,IAAI;QACrB;QAAE,OAAO,CAAM,EAAE;;AAEf,YAAA,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAA,OAAO,IAAI;YACb;AACA,YAAA,IAAI,CAAC,EAAE,IAAI,KAAK,YAAY,EAAE;;;AAG5B,gBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;YAC1B;iBAAO;AACL,gBAAA,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACnB;AACA,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AACvB,YAAA,OAAO,IAAI;QACb;IACF;;;AC/LF;;;;;;AAMG;AACG,MAAO,QAAS,SAAQ,WAAW,CAAA;;;;AAIvC,IAAA,OAAO,2BAA2B,GAAG,IAAI;IAEzC,OAAO,UAAU,GAAgB;QAC/B,GAAG,SAAS,CAAC,UAAU;AACvB,QAAA,MAAM,EAAE,EAAE;;AAEV,QAAA,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ;KACxC;AAEO,IAAA,KAAK;AACL,IAAA,yBAAyB,GAAkB,OAAO,CAAC,OAAO,EAAE;IAC5D,UAAU,GAA4B,IAAI;AAElD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;QACP,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC;AAChC,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE;QACvC,IAAI,CAAC,WAAW,CAAC;AACf,YAAA,2BAA2B,EAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;AAC/D,YAAA,6BAA6B,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;AACjE,YAAA,iBAAiB,EAAc,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;AAC7D,SAAA,CAAC;IACJ;;;;;AAMA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE;IAC3D;IAEQ,cAAc,GAAA;;;;;;AAMpB,QAAA,IAAI;AACF,YAAA,IAAI,OAAO,IAAI,CAAC,eAAe,KAAK,UAAU;AAAE,gBAAA,OAAO,IAAI;AAC3D,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE;AACxC,YAAA,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;AACjC,YAAA,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;AACpC,YAAA,OAAO,SAAS;QAClB;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,IAAI;QACb;IACF;AAEQ,IAAA,WAAW,CAAC,GAA6D,EAAA;AAC/E,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE;AAC9B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM;AACrC,QAAA,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACnD,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAI;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;AAC/C,gBAAA,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAE,CAAiB,CAAC,MAAM,CAAC,CAAC,EAAE;AAC5E,oBAAA,IAAI;wBACF,IAAI,EAAE,EAAE;AAAE,4BAAA,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;wBAAE;6BAAO;AAAE,4BAAA,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;wBAAE;oBAC5D;AAAE,oBAAA,MAAM,oBAAoB;AAC5B,oBAAA,IAAI,KAAK;wBAAE,IAAI,CAAC,eAAe,CAAC,CAAA,eAAA,EAAkB,IAAI,CAAA,CAAE,EAAE,EAAE,CAAC;gBAC/D;AACF,YAAA,CAAC,CAAC;QACJ;IACF;;AAIA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK;IACzB;AAEA,IAAA,IAAI,OAAO,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO;IAC3B;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK;IACzB;AAEA,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS;IAC7B;AAEA,IAAA,IAAI,wBAAwB,GAAA;QAC1B,OAAO,IAAI,CAAC,yBAAyB;IACvC;;AAIA,IAAA,KAAK,CAAC,IAAmB,EAAA;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAC/B;AAEA;;;;;;;;;;;;;AAaG;AACH,IAAA,QAAQ,CAAC,IAAmB,EAAA;AAC1B,QAAA,MAAM,GAAG,GAAI,UAAkB,CAAC,SAAS;AACzC,QAAA,OAAO,OAAO,GAAG,EAAE,QAAQ,KAAK,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK;IACzE;;IAIA,iBAAiB,GAAA;AACf,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;QAC3B,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;IACvD;IAEA,oBAAoB,GAAA;AAClB,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;IACtB;;;SCpIc,kBAAkB,GAAA;AAChC,IAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAC9C,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACxD;AACF;;ACHM,SAAU,cAAc,CAAC,UAA4B,EAAA;IACzD,IAAI,UAAU,EAAE;QACd,SAAS,CAAC,UAAU,CAAC;IACvB;AACA,IAAA,kBAAkB,EAAE;AACtB;;;;"}
@@ -1,2 +1,2 @@
1
- const e={tagNames:{share:"wcs-share"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const s of Object.keys(e))t(e[s]);return e}function s(e){if(null===e||"object"!=typeof e)return e;const t={};for(const r of Object.keys(e))t[r]=s(e[r]);return t}let r=null;const n=e;function a(){return r||(r=t(s(e))),r}class c extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"value",event:"wcs-share:complete",getter:e=>e.detail.value},{name:"loading",event:"wcs-share:loading-changed"},{name:"error",event:"wcs-share:error"},{name:"cancelled",event:"wcs-share:cancelled-changed"}],commands:[{name:"share",async:!0}]};_target;_value=null;_loading=!1;_error=null;_cancelled=!1;_gen=0;_ready=Promise.resolve();constructor(e){super(),this._target=e??this}get ready(){return this._ready}get value(){return this._value}get loading(){return this._loading}get error(){return this._error}get cancelled(){return this._cancelled}observe(){return this._ready}dispose(){this._gen++}_setLoading(e){this._loading!==e&&(this._loading=e,this._target.dispatchEvent(new CustomEvent("wcs-share:loading-changed",{detail:e,bubbles:!0})))}_setValue(e){this._value=e,this._target.dispatchEvent(new CustomEvent("wcs-share:complete",{detail:{value:e},bubbles:!0}))}_setError(e){this._error!==e&&(this._error=e,this._target.dispatchEvent(new CustomEvent("wcs-share:error",{detail:e,bubbles:!0})))}_setCancelled(e){this._cancelled!==e&&(this._cancelled=e,this._target.dispatchEvent(new CustomEvent("wcs-share:cancelled-changed",{detail:e,bubbles:!0})))}_api(){const e=globalThis.navigator;return"function"==typeof e?.share?e.share.bind(e):void 0}async share(e){const t=this._api();if(!t)return this._setError({message:"Web Share API is not supported in this browser."}),null;const s=this._gen;this._setLoading(!0),this._setError(null),this._setCancelled(!1);try{return await t(e),s!==this._gen?null:(this._setValue(e??null),this._setLoading(!1),e??null)}catch(e){return s!==this._gen||("AbortError"===e?.name?this._setCancelled(!0):this._setError(e),this._setLoading(!1)),null}}}class l extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...c.wcBindable,inputs:[],commands:c.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();constructor(){super(),this._core=new c(this)}get value(){return this._core.value}get loading(){return this._core.loading}get error(){return this._core.error}get cancelled(){return this._core.cancelled}get connectedCallbackPromise(){return this._connectedCallbackPromise}share(e){return this._core.share(e)}canShare(e){const t=globalThis.navigator;return"function"==typeof t?.canShare&&t.canShare(e)}connectedCallback(){this.style.display="none",this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}}function o(t){var s;t&&((s=t).tagNames&&Object.assign(e.tagNames,s.tagNames),r=null),customElements.get(n.tagNames.share)||customElements.define(n.tagNames.share,l)}export{c as ShareCore,l as WcsShare,o as bootstrapShare,a as getConfig};
1
+ const e={tagNames:{share:"wcs-share"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const s of Object.keys(e))t(e[s]);return e}function s(e){if(null===e||"object"!=typeof e)return e;const t={};for(const n of Object.keys(e))t[n]=s(e[n]);return t}let n=null;const r=e;function a(){return n||(n=t(s(e))),n}class i extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"value",event:"wcs-share:complete",getter:e=>e.detail.value},{name:"loading",event:"wcs-share:loading-changed"},{name:"error",event:"wcs-share:error"},{name:"cancelled",event:"wcs-share:cancelled-changed"}],commands:[{name:"share",async:!0}]};_target;_value=null;_loading=!1;_error=null;_cancelled=!1;_gen=0;_ready=Promise.resolve();constructor(e){super(),this._target=e??this}get ready(){return this._ready}get value(){return this._value}get loading(){return this._loading}get error(){return this._error}get cancelled(){return this._cancelled}observe(){return this._ready}dispose(){this._gen++}_setLoading(e){this._loading!==e&&(this._loading=e,this._target.dispatchEvent(new CustomEvent("wcs-share:loading-changed",{detail:e,bubbles:!0})))}_setValue(e){this._value=e,this._target.dispatchEvent(new CustomEvent("wcs-share:complete",{detail:{value:e},bubbles:!0}))}_setError(e){this._error!==e&&(this._error=e,this._target.dispatchEvent(new CustomEvent("wcs-share:error",{detail:e,bubbles:!0})))}_setCancelled(e){this._cancelled!==e&&(this._cancelled=e,this._target.dispatchEvent(new CustomEvent("wcs-share:cancelled-changed",{detail:e,bubbles:!0})))}_api(){const e=globalThis.navigator;return"function"==typeof e?.share?e.share.bind(e):void 0}async share(e){const t=this._api();if(!t)return this._setError({message:"Web Share API is not supported in this browser."}),null;const s=this._gen;this._setLoading(!0),this._setError(null),this._setCancelled(!1);try{return await t(e),s!==this._gen?null:(this._setValue(e??null),this._setLoading(!1),e??null)}catch(e){return s!==this._gen||("AbortError"===e?.name?this._setCancelled(!0):this._setError(e),this._setLoading(!1)),null}}}class l extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...i.wcBindable,inputs:[],commands:i.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new i(this),this._internals=this._initInternals(),this._wireStates({"wcs-share:loading-changed":e=>({loading:!0===e}),"wcs-share:cancelled-changed":e=>({cancelled:!0===e}),"wcs-share: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[s,n]of Object.entries(e))this.addEventListener(s,e=>{const s=this.hasAttribute("debug-states");for(const[r,a]of Object.entries(n(e.detail))){try{a?t.add(r):t.delete(r)}catch{}s&&this.toggleAttribute(`data-wcs-state-${r}`,a)}})}get value(){return this._core.value}get loading(){return this._core.loading}get error(){return this._core.error}get cancelled(){return this._core.cancelled}get connectedCallbackPromise(){return this._connectedCallbackPromise}share(e){return this._core.share(e)}canShare(e){const t=globalThis.navigator;return"function"==typeof t?.canShare&&t.canShare(e)}connectedCallback(){this.style.display="none",this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}}function c(t){var s;t&&((s=t).tagNames&&Object.assign(e.tagNames,s.tagNames),n=null),customElements.get(r.tagNames.share)||customElements.define(r.tagNames.share,l)}export{i as ShareCore,l as WcsShare,c as bootstrapShare,a 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/ShareCore.ts","../src/components/Share.ts","../src/bootstrapShare.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n share: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n share: \"wcs-share\",\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, WcsShareData } from \"../types.js\";\n\n/**\n * Headless Web Share primitive. A thin, framework-agnostic wrapper around\n * `navigator.share(data)` exposed through the wc-bindable protocol.\n *\n * This is a simplified derivative of `FetchCore._doFetch`\n * (docs/web-share-tag-design.md §2): it keeps the single `_gen` generation\n * guard, the same-value-guarded private setters, and the never-throw\n * try/catch wrapper, but drops `AbortController`/`abort()` entirely —\n * `navigator.share()` accepts no `AbortSignal` and there is no platform\n * mechanism for a caller to cancel an in-flight share dialog. A share dialog\n * is also a single system-modal surface (at most one open at a time), so the\n * \"a new call supersedes the previous one\" plumbing that `FetchCore` needs\n * has no counterpart here either.\n */\nexport class ShareCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-share:complete\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-share:loading-changed\" },\n { name: \"error\", event: \"wcs-share:error\" },\n { name: \"cancelled\", event: \"wcs-share:cancelled-changed\" },\n ],\n commands: [\n { name: \"share\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _value: WcsShareData | null = null;\n private _loading: boolean = false;\n private _error: any = null;\n private _cancelled: boolean = false;\n // Generation guard (§3.4 of the guidelines): bumped ONLY by dispose(). A\n // share() that settles after dispose() has a stale `gen` and MUST NOT write\n // state to a torn-down element. Unlike FetchCore/EyedropperCore, share()\n // itself does NOT bump `_gen` on each call: docs/web-share-tag-design.md §2\n // deliberately drops the \"a new call supersedes the previous one\" plumbing\n // those cores need, because the platform allows only one open share dialog\n // at a time (a second concurrent share() rejects with InvalidStateError on\n // its own). Bumping `_gen` per call would instead let a fast-failing second\n // call incorrectly invalidate a still-pending first call's eventual\n // success. Also not bumped on the unsupported early-return — no\n // asynchronous work is started, so there is no generation to protect\n // (docs/web-share-tag-design.md §8).\n private _gen = 0;\n // SSR (§3.8): no asynchronous probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get value(): WcsShareData | null {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n get cancelled(): boolean {\n return this._cancelled;\n }\n\n // Lifecycle (§3.5). Share is command-driven with no subscription to\n // establish, so observe() is an idempotent no-op that resolves once ready;\n // dispose() only invalidates any in-flight share() (there is nothing to\n // abort or unsubscribe).\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n }\n\n private _setLoading(loading: boolean): void {\n if (this._loading === loading) return;\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // Deliberately NO same-value guard (unlike error/loading/cancelled below).\n // `value` is a success-completion signal, not idempotent state: it is written\n // only on a successful share(), and wcs-share:complete is the *sole* success\n // notification. Two consecutive successful shares — even with the same `data`\n // object reference, or a data-less share echoing null when value is already\n // null — are two distinct completions and must each re-fire wcs-share:complete\n // so an `$on`/eventToken consumer (and a `value:` binding) sees every success.\n // This matches clipboard `_setRead` / broadcast `_setMessage`, which carve\n // result/event values out of the §3.3 guard for the same reason.\n private _setValue(value: WcsShareData | null): void {\n this._value = value;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:complete\", {\n detail: { value },\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n if (this._error === error) return;\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setCancelled(cancelled: boolean): void {\n if (this._cancelled === cancelled) return;\n this._cancelled = cancelled;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:cancelled-changed\", {\n detail: cancelled,\n bubbles: true,\n }));\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.share freely and lets an unsupported environment be detected\n // correctly on every call.\n private _api(): ((data?: WcsShareData) => Promise<void>) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav?.share === \"function\" ? nav.share.bind(nav) : undefined;\n }\n\n async share(data?: WcsShareData): Promise<WcsShareData | null> {\n // never-throw + unsupported (§8): resolve API at call time and bail out\n // immediately if absent. No _gen bump — no asynchronous work is started,\n // so there is no generation to protect, and navigator.share() itself is\n // never invoked.\n const shareFn = this._api();\n if (!shareFn) {\n this._setError({ message: \"Web Share API is not supported in this browser.\" });\n return null;\n }\n\n // Captured, not bumped (see the `_gen` field docs above): share() does\n // not supersede a prior in-flight call, only dispose() invalidates.\n const gen = this._gen;\n\n this._setLoading(true);\n // Reset the previous outcome before starting a new share so a stale\n // cancelled/error does not linger into this call's result\n // (docs/web-share-tag-design.md §3).\n this._setError(null);\n this._setCancelled(false);\n\n try {\n await shareFn(data);\n\n // Stale completion (dispose() ran while the share dialog was open).\n // Drop the result without writing state.\n if (gen !== this._gen) {\n return null;\n }\n\n // navigator.share() resolves `Promise<void>` — there is no payload to\n // read off the API, so `value` is synthesized as an echo of the caller's\n // `data`, signalling \"this share completed successfully\"\n // (docs/web-share-tag-design.md §4).\n this._setValue(data ?? null);\n this._setLoading(false);\n return data ?? null;\n } catch (e: any) {\n // Stale completion (dispose() ran while the share dialog was open).\n if (gen !== this._gen) {\n return null;\n }\n if (e?.name === \"AbortError\") {\n // The user dismissed the share sheet — a routine cancellation, not a\n // platform failure. Kept out of `error` (docs/web-share-tag-design.md §3).\n this._setCancelled(true);\n } else {\n this._setError(e);\n }\n this._setLoading(false);\n return null;\n }\n }\n}\n","import { IWcBindable, WcsShareData } from \"../types.js\";\nimport { ShareCore } from \"../core/ShareCore.js\";\n\n/**\n * `<wcs-share>` — declarative Web Share API primitive.\n *\n * The smallest command-only Shell in the batch (docs/web-share-tag-design.md\n * §10): no attributes at all. `share(data)`'s `data` is a per-call argument,\n * not a declarative setting to park on the element ahead of time.\n */\nexport class WcsShare extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so the state binder can await it uniformly across\n // all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...ShareCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。\n commands: ShareCore.wcBindable.commands,\n };\n\n private _core: ShareCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new ShareCore(this);\n }\n\n // --- Core delegated getters ---\n\n get value(): WcsShareData | null {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get cancelled(): boolean {\n return this._core.cancelled;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n share(data?: WcsShareData): Promise<WcsShareData | null> {\n return this._core.share(data);\n }\n\n /**\n * Synchronous, side-effect-free delegation to `navigator.canShare(data)`\n * (docs/web-share-tag-design.md §6). Deliberately outside `wcBindable`\n * (not a `properties`/`commands` entry): the platform method takes an\n * argument that varies per call, which does not fit the \"observe with no\n * arguments\" shape of a bindable property, and is synchronous, which does\n * not fit the fire-and-observe-via-event shape of a command.\n *\n * No never-throw wrapping: the platform method itself is synchronous and\n * side-effect-free, so a throw here would indicate a browser bug rather\n * than a condition this Shell should paper over. `navigator.canShare` is\n * still resolved defensively (some environments lack it even when `share`\n * exists), returning `false` rather than throwing in that case.\n */\n canShare(data?: WcsShareData): boolean {\n const nav = (globalThis as any).navigator;\n return typeof nav?.canShare === \"function\" ? nav.canShare(data) : false;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapShare(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsShare } from \"./components/Share.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.share)) {\n customElements.define(config.tagNames.share, WcsShare);\n }\n}\n"],"names":["_config","tagNames","share","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","ShareCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","value","commands","async","_target","_value","_loading","_error","_cancelled","_gen","_ready","Promise","resolve","constructor","target","super","this","ready","loading","error","cancelled","observe","dispose","_setLoading","dispatchEvent","CustomEvent","bubbles","_setValue","_setError","_setCancelled","_api","nav","globalThis","navigator","bind","undefined","data","shareFn","message","gen","WcsShare","HTMLElement","wcBindable","inputs","_core","_connectedCallbackPromise","connectedCallbackPromise","canShare","connectedCallback","style","display","disconnectedCallback","bootstrapShare","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/ShareCore.ts","../src/components/Share.ts","../src/bootstrapShare.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n share: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n share: \"wcs-share\",\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, WcsShareData } from \"../types.js\";\n\n/**\n * Headless Web Share primitive. A thin, framework-agnostic wrapper around\n * `navigator.share(data)` exposed through the wc-bindable protocol.\n *\n * This is a simplified derivative of `FetchCore._doFetch`\n * (docs/web-share-tag-design.md §2): it keeps the single `_gen` generation\n * guard, the same-value-guarded private setters, and the never-throw\n * try/catch wrapper, but drops `AbortController`/`abort()` entirely —\n * `navigator.share()` accepts no `AbortSignal` and there is no platform\n * mechanism for a caller to cancel an in-flight share dialog. A share dialog\n * is also a single system-modal surface (at most one open at a time), so the\n * \"a new call supersedes the previous one\" plumbing that `FetchCore` needs\n * has no counterpart here either.\n */\nexport class ShareCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-share:complete\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-share:loading-changed\" },\n { name: \"error\", event: \"wcs-share:error\" },\n { name: \"cancelled\", event: \"wcs-share:cancelled-changed\" },\n ],\n commands: [\n { name: \"share\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _value: WcsShareData | null = null;\n private _loading: boolean = false;\n private _error: any = null;\n private _cancelled: boolean = false;\n // Generation guard (§3.4 of the guidelines): bumped ONLY by dispose(). A\n // share() that settles after dispose() has a stale `gen` and MUST NOT write\n // state to a torn-down element. Unlike FetchCore/EyedropperCore, share()\n // itself does NOT bump `_gen` on each call: docs/web-share-tag-design.md §2\n // deliberately drops the \"a new call supersedes the previous one\" plumbing\n // those cores need, because the platform allows only one open share dialog\n // at a time (a second concurrent share() rejects with InvalidStateError on\n // its own). Bumping `_gen` per call would instead let a fast-failing second\n // call incorrectly invalidate a still-pending first call's eventual\n // success. Also not bumped on the unsupported early-return — no\n // asynchronous work is started, so there is no generation to protect\n // (docs/web-share-tag-design.md §8).\n private _gen = 0;\n // SSR (§3.8): no asynchronous probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get value(): WcsShareData | null {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get error(): any {\n return this._error;\n }\n\n get cancelled(): boolean {\n return this._cancelled;\n }\n\n // Lifecycle (§3.5). Share is command-driven with no subscription to\n // establish, so observe() is an idempotent no-op that resolves once ready;\n // dispose() only invalidates any in-flight share() (there is nothing to\n // abort or unsubscribe).\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n }\n\n private _setLoading(loading: boolean): void {\n if (this._loading === loading) return;\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n // Deliberately NO same-value guard (unlike error/loading/cancelled below).\n // `value` is a success-completion signal, not idempotent state: it is written\n // only on a successful share(), and wcs-share:complete is the *sole* success\n // notification. Two consecutive successful shares — even with the same `data`\n // object reference, or a data-less share echoing null when value is already\n // null — are two distinct completions and must each re-fire wcs-share:complete\n // so an `$on`/eventToken consumer (and a `value:` binding) sees every success.\n // This matches clipboard `_setRead` / broadcast `_setMessage`, which carve\n // result/event values out of the §3.3 guard for the same reason.\n private _setValue(value: WcsShareData | null): void {\n this._value = value;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:complete\", {\n detail: { value },\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n if (this._error === error) return;\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setCancelled(cancelled: boolean): void {\n if (this._cancelled === cancelled) return;\n this._cancelled = cancelled;\n this._target.dispatchEvent(new CustomEvent(\"wcs-share:cancelled-changed\", {\n detail: cancelled,\n bubbles: true,\n }));\n }\n\n // API resolution is call-time, never cached (§3.7): lets tests install/remove\n // navigator.share freely and lets an unsupported environment be detected\n // correctly on every call.\n private _api(): ((data?: WcsShareData) => Promise<void>) | undefined {\n const nav = (globalThis as any).navigator;\n return typeof nav?.share === \"function\" ? nav.share.bind(nav) : undefined;\n }\n\n async share(data?: WcsShareData): Promise<WcsShareData | null> {\n // never-throw + unsupported (§8): resolve API at call time and bail out\n // immediately if absent. No _gen bump — no asynchronous work is started,\n // so there is no generation to protect, and navigator.share() itself is\n // never invoked.\n const shareFn = this._api();\n if (!shareFn) {\n this._setError({ message: \"Web Share API is not supported in this browser.\" });\n return null;\n }\n\n // Captured, not bumped (see the `_gen` field docs above): share() does\n // not supersede a prior in-flight call, only dispose() invalidates.\n const gen = this._gen;\n\n this._setLoading(true);\n // Reset the previous outcome before starting a new share so a stale\n // cancelled/error does not linger into this call's result\n // (docs/web-share-tag-design.md §3).\n this._setError(null);\n this._setCancelled(false);\n\n try {\n await shareFn(data);\n\n // Stale completion (dispose() ran while the share dialog was open).\n // Drop the result without writing state.\n if (gen !== this._gen) {\n return null;\n }\n\n // navigator.share() resolves `Promise<void>` — there is no payload to\n // read off the API, so `value` is synthesized as an echo of the caller's\n // `data`, signalling \"this share completed successfully\"\n // (docs/web-share-tag-design.md §4).\n this._setValue(data ?? null);\n this._setLoading(false);\n return data ?? null;\n } catch (e: any) {\n // Stale completion (dispose() ran while the share dialog was open).\n if (gen !== this._gen) {\n return null;\n }\n if (e?.name === \"AbortError\") {\n // The user dismissed the share sheet — a routine cancellation, not a\n // platform failure. Kept out of `error` (docs/web-share-tag-design.md §3).\n this._setCancelled(true);\n } else {\n this._setError(e);\n }\n this._setLoading(false);\n return null;\n }\n }\n}\n","import { IWcBindable, WcsShareData } from \"../types.js\";\nimport { ShareCore } from \"../core/ShareCore.js\";\n\n/**\n * `<wcs-share>` — declarative Web Share API primitive.\n *\n * The smallest command-only Shell in the batch (docs/web-share-tag-design.md\n * §10): no attributes at all. `share(data)`'s `data` is a per-call argument,\n * not a declarative setting to park on the element ahead of time.\n */\nexport class WcsShare extends HTMLElement {\n // SSR (§4.4): observe() completes synchronously, but the Shell still exposes\n // connectedCallbackPromise so the state binder can await it uniformly across\n // all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static wcBindable: IWcBindable = {\n ...ShareCore.wcBindable,\n inputs: [],\n // Core の commands をそのまま継承(単一情報源)。\n commands: ShareCore.wcBindable.commands,\n };\n\n private _core: ShareCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new ShareCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-share:loading-changed\": (d) => ({ loading: d === true }),\n \"wcs-share:cancelled-changed\": (d) => ({ cancelled: d === true }),\n \"wcs-share: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 (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Core delegated getters ---\n\n get value(): WcsShareData | null {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get cancelled(): boolean {\n return this._core.cancelled;\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Commands ---\n\n share(data?: WcsShareData): Promise<WcsShareData | null> {\n return this._core.share(data);\n }\n\n /**\n * Synchronous, side-effect-free delegation to `navigator.canShare(data)`\n * (docs/web-share-tag-design.md §6). Deliberately outside `wcBindable`\n * (not a `properties`/`commands` entry): the platform method takes an\n * argument that varies per call, which does not fit the \"observe with no\n * arguments\" shape of a bindable property, and is synchronous, which does\n * not fit the fire-and-observe-via-event shape of a command.\n *\n * No never-throw wrapping: the platform method itself is synchronous and\n * side-effect-free, so a throw here would indicate a browser bug rather\n * than a condition this Shell should paper over. `navigator.canShare` is\n * still resolved defensively (some environments lack it even when `share`\n * exists), returning `false` rather than throwing in that case.\n */\n canShare(data?: WcsShareData): boolean {\n const nav = (globalThis as any).navigator;\n return typeof nav?.canShare === \"function\" ? nav.canShare(data) : false;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapShare(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsShare } from \"./components/Share.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.share)) {\n customElements.define(config.tagNames.share, WcsShare);\n }\n}\n"],"names":["_config","tagNames","share","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","ShareCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","value","commands","async","_target","_value","_loading","_error","_cancelled","_gen","_ready","Promise","resolve","constructor","target","super","this","ready","loading","error","cancelled","observe","dispose","_setLoading","dispatchEvent","CustomEvent","bubbles","_setValue","_setError","_setCancelled","_api","nav","globalThis","navigator","bind","undefined","data","shareFn","message","gen","WcsShare","HTMLElement","wcBindable","inputs","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","addEventListener","debug","hasAttribute","on","toggleAttribute","connectedCallbackPromise","canShare","connectedCallback","style","display","disconnectedCallback","bootstrapShare","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/share",
3
- "version": "1.16.0",
3
+ "version": "1.17.0",
4
4
  "description": "Declarative Web Share component for Web Components. Framework-agnostic navigator.share primitive via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",