@wcstack/intersection 1.16.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -143,6 +143,59 @@ export default {
143
143
  | `disconnect()`| すべての観測を停止する。 |
144
144
  | `reset()` | `visible` ラッチをクリアし、後の交差が再びそれを設定できるようにする。 |
145
145
 
146
+ ## `:state()` による CSS スタイリング
147
+
148
+ `<wcs-intersect>` は 3 つの boolean 出力ステートを
149
+ [`ElementInternals` の `CustomStateSet`](https://developer.mozilla.org/ja/docs/Web/API/CustomStateSet)
150
+ に反映します。そのため `data-wcs` バインディングやクラスの手動トグルなしに、CSS の
151
+ `:state()` 疑似クラスで直接スタイリングできます。
152
+
153
+ | ステート | on になる条件 |
154
+ |----------|----------------|
155
+ | `visible` | `wcs-intersect:visible-changed` が `true` で発火(ラッチ — `reset()` が `false` でイベントを発火したときのみクリア) |
156
+ | `observing` | `wcs-intersect:observing-changed` が `true` で発火(`false` でクリア) |
157
+ | `intersecting` | `wcs-intersect:change` が `isIntersecting` が `true` の detail で発火(`false` のときクリア) |
158
+
159
+ `ratio` と `entry` は反映されません(連続値・データ値のため)。
160
+
161
+ ```css
162
+ wcs-intersect:state(intersecting) ~ .marker { opacity: 1; }
163
+ wcs-intersect:state(visible) img { display: block; } /* 遅延読み込みの表示 */
164
+ wcs-intersect:not(:state(observing)) ~ .paused-badge { display: block; }
165
+ ```
166
+
167
+ 属性やクラスと異なり `:state()` は要素の外部から書き込めないため、この出力ステートが
168
+ 入力と混同される心配がありません。
169
+
170
+ **対応ブラウザ**(新構文 `:state(x)`): Chrome/Edge 125+、Safari 17.4+、Firefox 126+。
171
+ 非対応の環境ではステートが一切 set されないだけです — `:state()` セレクタがマッチしなく
172
+ なりますが、`<wcs-intersect>` 自体は通常どおり動作し続けます(graceful degradation・never-throw)。
173
+
174
+ **SSR:** `:state()` は HTML にシリアライズできないため、サーバーレンダリングされた
175
+ マークアップの初期ペイントにはこれらのステートは乗りません(`@wcstack/server` は無改変)。
176
+ ハイドレーション前の見た目を制御したい場合は、代わりに `wcs-intersect:not(:defined)` と組み合わせてください。
177
+
178
+ ### デバッグ
179
+
180
+ カスタムステートは DevTools の Elements パネルには表示されず、`attachInternals()`
181
+ は同一要素に 2 回呼べないため、コンソールから直接覗く手段がありません。そのための
182
+ デバッグ専用の補助を 2 つ用意しています:
183
+
184
+ - `el.debugStates` — 現在 on になっているステート名の**スナップショット**配列
185
+ (例: `["observing", "intersecting"]`)。`wc-bindable` の一部ではなく(バインド対象ではない)、
186
+ 形状も契約として保証されません — デバッグ用途にのみ使ってください。
187
+ - `debug-states` 属性(opt-in・既定 OFF)は、ステート変化を要素の
188
+ `data-wcs-state-visible` / `data-wcs-state-observing` / `data-wcs-state-intersecting`
189
+ 属性にミラーします。Elements パネルを開いておけば、トグルのたびにハイライトされます:
190
+
191
+ ```html
192
+ <wcs-intersect target="#hero" debug-states></wcs-intersect>
193
+ ```
194
+
195
+ **CSS は `data-wcs-state-*` ではなく `:state()` に書いてください。** ミラーされた
196
+ 属性は、DevTools を開いた状態でステート変化を可視化するためだけのものであり、
197
+ スタイリング用の正式なフックではありません。
198
+
146
199
  ## Binding Contract(`wcBindable`)
147
200
 
148
201
  Core と Shell の両方が [wc-bindable](https://github.com/csbc-dev) プロトコルを宣言します。
package/README.md CHANGED
@@ -143,6 +143,63 @@ Point `target` at a section elsewhere in the document; bind `intersecting` to hi
143
143
  | `disconnect()`| Stop all observation. |
144
144
  | `reset()` | Clear the `visible` latch so a later intersection can set it again. |
145
145
 
146
+ ## CSS styling with `:state()`
147
+
148
+ `<wcs-intersect>` reflects three boolean output states onto its
149
+ [`ElementInternals` `CustomStateSet`](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet),
150
+ so you can style it directly from CSS with the `:state()` pseudo-class — no
151
+ `data-wcs` binding or extra class toggling required.
152
+
153
+ | State | On when |
154
+ |-------|---------|
155
+ | `visible` | `wcs-intersect:visible-changed` fires with `true` (a latch — only cleared by `reset()`, which fires the event with `false`) |
156
+ | `observing` | `wcs-intersect:observing-changed` fires with `true` (cleared on `false`) |
157
+ | `intersecting` | `wcs-intersect:change` fires with a detail whose `isIntersecting` is `true` (cleared when it is `false`) |
158
+
159
+ `ratio` and `entry` are not reflected (continuous / data values).
160
+
161
+ ```css
162
+ wcs-intersect:state(intersecting) ~ .marker { opacity: 1; }
163
+ wcs-intersect:state(visible) img { display: block; } /* lazy-load reveal */
164
+ wcs-intersect:not(:state(observing)) ~ .paused-badge { display: block; }
165
+ ```
166
+
167
+ Unlike attributes or classes, `:state()` cannot be written from outside the
168
+ element, so there is no risk of confusing this output state with an input.
169
+
170
+ **Browser support** (`:state(x)` syntax): Chrome/Edge 125+, Safari 17.4+,
171
+ Firefox 126+. In older browsers the states are simply never set — `:state()`
172
+ selectors never match, but `<wcs-intersect>` itself keeps working normally
173
+ (graceful degradation, never-throw).
174
+
175
+ **SSR**: `:state()` cannot be serialized into HTML, so server-rendered markup
176
+ never carries these states on first paint (`@wcstack/server` is unaffected).
177
+ If you need to style the pre-hydration gap, pair your rule with
178
+ `wcs-intersect:not(:defined)` instead.
179
+
180
+ ### Debugging
181
+
182
+ Custom states are invisible in DevTools' Elements panel and `attachInternals()`
183
+ cannot be called twice, so there is no console way to inspect them directly.
184
+ Two debug-only aids are provided for that:
185
+
186
+ - `el.debugStates` — a **snapshot** array of the currently-on state names
187
+ (e.g. `["observing", "intersecting"]`). It is not part of `wc-bindable`
188
+ (not a bind target) and its shape is not a guaranteed contract — use it for
189
+ debugging only.
190
+ - The `debug-states` attribute (opt-in, default off) mirrors state changes
191
+ onto `data-wcs-state-visible` / `data-wcs-state-observing` /
192
+ `data-wcs-state-intersecting` attributes on the element, so the Elements
193
+ panel highlights them as they toggle:
194
+
195
+ ```html
196
+ <wcs-intersect target="#hero" debug-states></wcs-intersect>
197
+ ```
198
+
199
+ **Write your CSS against `:state()`, not `data-wcs-state-*`.** The mirrored
200
+ attributes exist purely to make state changes visible while debugging with
201
+ DevTools open; they are not a supported styling hook.
202
+
146
203
  ## Binding Contract (`wcBindable`)
147
204
 
148
205
  Both the Core and the Shell declare the [wc-bindable](https://github.com/csbc-dev) protocol.
package/dist/index.d.ts CHANGED
@@ -270,7 +270,11 @@ declare class WcsIntersect extends HTMLElement {
270
270
  private _core;
271
271
  private _trigger;
272
272
  private _connectedCallbackPromise;
273
+ private _internals;
273
274
  constructor();
275
+ get debugStates(): string[];
276
+ private _initInternals;
277
+ private _wireStates;
274
278
  get connectedCallbackPromise(): Promise<void>;
275
279
  get target(): string;
276
280
  set target(value: string);
package/dist/index.esm.js CHANGED
@@ -374,9 +374,64 @@ class WcsIntersect extends HTMLElement {
374
374
  _core;
375
375
  _trigger = false;
376
376
  _connectedCallbackPromise = Promise.resolve();
377
+ _internals = null;
377
378
  constructor() {
378
379
  super();
379
380
  this._core = new IntersectionCore(this);
381
+ this._internals = this._initInternals();
382
+ this._wireStates({
383
+ "wcs-intersect:visible-changed": (d) => ({ visible: d === true }),
384
+ "wcs-intersect:observing-changed": (d) => ({ observing: d === true }),
385
+ "wcs-intersect:change": (d) => ({ intersecting: d.isIntersecting === true }),
386
+ });
387
+ }
388
+ // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of
389
+ // wc-bindable (not a bind target); see README "CSS styling with :state()".
390
+ // MUST NOT return the live CustomStateSet (that would let callers write
391
+ // states from outside, defeating the point of :state() being read-only).
392
+ get debugStates() {
393
+ return this._internals ? [...this._internals.states] : [];
394
+ }
395
+ _initInternals() {
396
+ // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent
397
+ // in happy-dom / older environments, and pre-125 Chromium rejects
398
+ // non-dashed state names from states.add() (probed and discarded here).
399
+ // Either case silently disables reflection — the component still works,
400
+ // it just doesn't expose :state() selectors.
401
+ try {
402
+ if (typeof this.attachInternals !== "function")
403
+ return null;
404
+ const internals = this.attachInternals();
405
+ internals.states.add("wcs-probe");
406
+ internals.states.delete("wcs-probe");
407
+ return internals;
408
+ }
409
+ catch {
410
+ return null;
411
+ }
412
+ }
413
+ _wireStates(map) {
414
+ if (this._internals === null)
415
+ return;
416
+ const states = this._internals.states;
417
+ for (const [event, toStates] of Object.entries(map)) {
418
+ this.addEventListener(event, (e) => {
419
+ const debug = this.hasAttribute("debug-states");
420
+ for (const [name, on] of Object.entries(toStates(e.detail))) {
421
+ try {
422
+ if (on) {
423
+ states.add(name);
424
+ }
425
+ else {
426
+ states.delete(name);
427
+ }
428
+ }
429
+ catch { /* never-throw */ }
430
+ if (debug)
431
+ this.toggleAttribute(`data-wcs-state-${name}`, on);
432
+ }
433
+ });
434
+ }
380
435
  }
381
436
  get connectedCallbackPromise() {
382
437
  return this._connectedCallbackPromise;
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/IntersectionCore.ts","../src/components/Intersect.ts","../src/registerComponents.ts","../src/bootstrapIntersection.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n intersect: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n intersect: \"wcs-intersect\",\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, IntersectOptions, WcsIntersectEntry, WcsIntersectRect } from \"../types.js\";\n\n/**\n * Headless visibility primitive. A thin, framework-agnostic wrapper around the\n * IntersectionObserver API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack sensors (geolocation / timer / websocket), the thing\n * being observed is a *DOM element* — so `observe()` takes the target node. The\n * Core stays DOM-resolution-agnostic: it observes whatever element it is handed\n * (the Shell resolves `target` / `root` selectors before calling). It is a\n * read-only producer — element/layout → state only, with no element-bound path.\n *\n * Every observer callback is published via the single `wcs-intersect:change`\n * event; `intersecting` / `ratio` are read from it through getters (mirroring how\n * GeolocationCore exposes latitude/longitude from one `wcs-geo:position` event),\n * so an observer that binds any of them is notified on every change.\n *\n * `visible` is a latch: it flips to `true` the first time the target intersects\n * and stays `true` until `reset()` — ideal for one-way lazy-load bindings\n * (`src@visible`). `observing` reflects whether an observation is currently\n * active (like TimerCore's `running`).\n *\n * Single-target by design: the Shell observes exactly one element, so the state\n * reflects that element. Multi-target observation is intentionally out of scope.\n */\nexport class IntersectionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"entry\", event: \"wcs-intersect:change\" },\n { name: \"intersecting\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.isIntersecting },\n { name: \"ratio\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.intersectionRatio },\n { name: \"visible\", event: \"wcs-intersect:visible-changed\" },\n { name: \"observing\", event: \"wcs-intersect:observing-changed\" },\n ],\n commands: [\n { name: \"observe\" },\n { name: \"reobserve\" },\n { name: \"unobserve\" },\n { name: \"disconnect\" },\n { name: \"reset\" },\n ],\n };\n\n private _target: EventTarget;\n\n // The live observer and the single element it observes. Options are kept so a\n // repeated observe() with identical options is a no-op (avoids the create→\n // observe→disconnect churn an autoloader upgrade can otherwise cause).\n private _observer: IntersectionObserver | null = null;\n private _observed: Element | null = null;\n private _options: IntersectOptions = {};\n\n private _entry: WcsIntersectEntry | null = null;\n private _visible: boolean = false;\n private _observing: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() and on each observe()/reobserve()\n // teardown+rebuild. IntersectionObserver delivers its callback asynchronously off\n // layout, so a callback can fire after the element is disposed or after a rapid\n // disconnect→reconnect rebuilt the observer. Each observer captures the gen live at\n // creation; a callback from a superseded/torn-down observer has a stale gen and\n // MUST NOT write state to a torn-down element. A boolean flag is insufficient\n // (dispose→observe would flip it back and let stale work slip through).\n private _gen = 0;\n\n // SSR (§3.8): IntersectionObserver setup is synchronous (no async probe to await),\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n /** Resolves immediately — there is no asynchronous probe to await (§3.8). */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get entry(): WcsIntersectEntry | null {\n return this._entry;\n }\n\n get intersecting(): boolean {\n return this._entry ? this._entry.isIntersecting : false;\n }\n\n get ratio(): number {\n return this._entry ? this._entry.intersectionRatio : 0;\n }\n\n get visible(): boolean {\n return this._visible;\n }\n\n get observing(): boolean {\n return this._observing;\n }\n\n // --- State setters with event dispatch ---\n\n private _setEntry(entry: WcsIntersectEntry): void {\n // No same-value guard: `change` carries event semantics (every callback is a\n // distinct observation) and `intersecting` / `ratio` are derived getters that\n // must re-fire on each entry, mirroring GeolocationCore's `position`.\n this._entry = entry;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:change\", {\n detail: entry,\n bubbles: true,\n }));\n }\n\n private _setVisible(visible: boolean): void {\n if (this._visible === visible) return;\n this._visible = visible;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:visible-changed\", {\n detail: visible,\n bubbles: true,\n }));\n }\n\n private _setObserving(observing: boolean): void {\n if (this._observing === observing) return;\n this._observing = observing;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:observing-changed\", {\n detail: observing,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `element`. Idempotent while already observing the same\n * element with the same options. Changing the element or options tears down the\n * current observer and builds a new one (IntersectionObserver options are fixed\n * at construction, so reconfiguring requires a fresh observer).\n *\n * If IntersectionObserver is unavailable (SSR) or the options are invalid (e.g.\n * a malformed `rootMargin`, which the constructor rejects), this is a silent\n * no-op — `observing` stays false, consistent with the never-throw design of\n * the other @wcstack sensors.\n */\n observe(element: Element, options: IntersectOptions = {}): Promise<void> {\n if (this._observer && this._observed === element && this._optionsEqual(this._options, options)) {\n return this._ready;\n }\n this._teardownObserver();\n const observer = this._createObserver(options);\n if (!observer) {\n // Creation failed (unsupported environment or invalid options) *after* we\n // tore down any previous observer. If we were already observing, the\n // observation is now gone, so reflect that — otherwise `observing` would\n // keep reporting true with no live observer behind it (e.g. re-observing an\n // active target with a newly-invalid rootMargin).\n this._setObserving(false);\n return this._ready;\n }\n this._observer = observer;\n this._observed = element;\n this._options = options;\n observer.observe(element);\n this._setObserving(true);\n // SSR (§3.5): observe() returns the readiness promise. Observation establishment\n // is synchronous, so this resolves immediately.\n return this._ready;\n }\n\n /**\n * Force a fresh observation of `element`, even when it matches the currently\n * observed target+options. Unlike observe() — which is idempotent and\n * early-returns for an unchanged target+options *without* re-delivering a\n * callback — this always tears the observer down and rebuilds it, so a new\n * IntersectionObserver delivers an initial callback for the element's CURRENT\n * visibility.\n *\n * This is the way to re-arm an edge-driven consumer (e.g. infinite scroll) after\n * the layout changed without a visibility *transition*: IntersectionObserver only\n * fires on a change, so appending a short page that leaves the sentinel visible\n * yields no new callback — a bare observe() can't help (idempotent), but a\n * reobserve() re-reads the current state. Same never-throw guarantees as\n * observe(); `observing` stays true across a successful re-arm (no false blip).\n */\n reobserve(element: Element, options: IntersectOptions = {}): void {\n this._teardownObserver();\n this.observe(element, options);\n }\n\n /**\n * Stop observing `element`. A no-op if it is not the currently observed\n * element. The observer instance is torn down (single-target Core), so a later\n * observe() rebuilds it.\n */\n unobserve(element: Element): void {\n if (this._observed !== element) return;\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Stop all observation and release the observer. */\n disconnect(): void {\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Clear the `visible` latch so a later intersection can set it again. */\n reset(): void {\n this._setVisible(false);\n }\n\n // --- Lifecycle (§3.5) ---\n\n /**\n * `observe()` (the IntersectionObserver-style command above) establishes\n * monitoring, so there is no separate idempotent monitoring entry point — only\n * teardown. `dispose()` invalidates any in-flight observer callback (`_gen++`)\n * and releases the observer. A later observe() revives it (the Shell calls this\n * from `disconnectedCallback`).\n */\n dispose(): void {\n this._gen++;\n this.disconnect();\n }\n\n // --- Internal ---\n\n private _teardownObserver(): void {\n if (this._observer) {\n this._observer.disconnect();\n this._observer = null;\n }\n this._observed = null;\n // Invalidate the torn-down observer's generation: its callback can still fire\n // once asynchronously after disconnect(), and must be dropped (§3.4).\n this._gen++;\n }\n\n private _createObserver(options: IntersectOptions): IntersectionObserver | null {\n if (typeof IntersectionObserver === \"undefined\") return null;\n // Capture the generation live at creation. The callback closure below guards\n // against deliveries from this observer after it has been superseded or\n // disposed (a stale callback fired off layout after teardown).\n const gen = this._gen;\n try {\n return new IntersectionObserver(\n (entries) => this._onIntersect(gen, entries),\n {\n root: options.root ?? null,\n rootMargin: options.rootMargin ?? \"0px\",\n threshold: options.threshold ?? 0,\n },\n );\n } catch {\n // Invalid options (e.g. a malformed rootMargin) — surface nothing and leave\n // observing false, rather than letting the constructor throw escape.\n return null;\n }\n }\n\n private _onIntersect(gen: number, entries: IntersectionObserverEntry[]): void {\n // Stale-generation guard (§3.4): drop callbacks from an observer that was torn\n // down or disposed (e.g. a delivery that landed after disconnect/reconnect).\n if (gen !== this._gen) return;\n for (const entry of entries) {\n const normalized = this._normalizeEntry(entry);\n this._setEntry(normalized);\n // Latch on the first (and any) intersecting observation; never auto-clears.\n if (normalized.isIntersecting) {\n this._setVisible(true);\n }\n }\n }\n\n private _normalizeEntry(entry: IntersectionObserverEntry): WcsIntersectEntry {\n return {\n isIntersecting: entry.isIntersecting,\n intersectionRatio: entry.intersectionRatio,\n time: entry.time,\n boundingClientRect: this._normalizeRect(entry.boundingClientRect),\n intersectionRect: this._normalizeRect(entry.intersectionRect),\n rootBounds: entry.rootBounds ? this._normalizeRect(entry.rootBounds) : null,\n target: entry.target,\n };\n }\n\n private _normalizeRect(rect: DOMRectReadOnly): WcsIntersectRect {\n return {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n left: rect.left,\n };\n }\n\n private _optionsEqual(a: IntersectOptions, b: IntersectOptions): boolean {\n if ((a.root ?? null) !== (b.root ?? null)) return false;\n if ((a.rootMargin ?? \"0px\") !== (b.rootMargin ?? \"0px\")) return false;\n return this._thresholdKey(a.threshold) === this._thresholdKey(b.threshold);\n }\n\n private _thresholdKey(threshold: number | number[] | undefined): string {\n if (threshold === undefined) return \"0\";\n return Array.isArray(threshold) ? threshold.join(\",\") : String(threshold);\n }\n}\n","import { IWcBindable, IntersectOptions, WcsIntersectEntry } from \"../types.js\";\nimport { IntersectionCore } from \"../core/IntersectionCore.js\";\n\n/**\n * `<wcs-intersect>` — declarative IntersectionObserver.\n *\n * The `target` attribute is the single knob that decides both *what* is observed\n * and how the element renders (it never injects a layout box unless asked):\n *\n * | `target` | observes | display | use case |\n * |-----------------|-----------------------|-------------|-------------------|\n * | omitted | first element child | `contents` | lazy-load wrapper |\n * | `\"#hero\"` / sel | the matched element | `none` | scrollspy (single)|\n * | `\"self\"` | the element itself | `block` | infinite-scroll |\n *\n * `display:contents` means wrapping a child injects no box of its own (so a\n * `<wcs-intersect><img></wcs-intersect>` does not disturb a flex/grid parent);\n * only the explicit `target=\"self\"` sentinel takes a box.\n */\nexport class WcsIntersect extends HTMLElement {\n // SSR (§4.4): the first observation is established synchronously on connect, but\n // the Shell still exposes connectedCallbackPromise so the state binder can await\n // it uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n // Only attributes that change *what or how* we observe trigger a re-observe.\n // `once` is intentionally excluded: it is evaluated at intersection fire time\n // (in `_onChange`), so toggling it takes effect without re-observing — and a\n // re-observe on its change would be a pure no-op (same target, same options).\n // `manual` is also excluded: it is a connect-time policy (\"don't auto-observe\n // on connect\"), not a live switch that should start/stop an active observation.\n static observedAttributes = [\"target\", \"root\", \"root-margin\", \"threshold\"];\n\n static wcBindable: IWcBindable = {\n ...IntersectionCore.wcBindable,\n properties: [\n ...IntersectionCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-intersect:trigger-changed\" },\n ],\n // Shell-level settable surface. Each input carries its mirrored `attribute`\n // hint; `trigger` has none — it is a momentary command-property, not a\n // declarative attribute. The observe / reobserve / unobserve / disconnect /\n // reset commands are inherited from the Core via the spread above.\n inputs: [\n { name: \"target\", attribute: \"target\" },\n { name: \"root\", attribute: \"root\" },\n { name: \"rootMargin\", attribute: \"root-margin\" },\n { name: \"threshold\", attribute: \"threshold\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n // Core の commands をそのまま継承(単一情報源)。<wcs-sse>/<wcs-broadcast> と同型。\n // spread でも継承されるが、Core に command 追加時の追従漏れを防ぐため明示参照する。\n commands: IntersectionCore.wcBindable.commands,\n };\n\n private _core: IntersectionCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new IntersectionCore(this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n get root(): string {\n return this.getAttribute(\"root\") ?? \"\";\n }\n\n set root(value: string) {\n this.setAttribute(\"root\", value);\n }\n\n get rootMargin(): string {\n const attr = this.getAttribute(\"root-margin\");\n return attr === null || attr.trim() === \"\" ? \"0px\" : attr;\n }\n\n set rootMargin(value: string) {\n this.setAttribute(\"root-margin\", value);\n }\n\n get threshold(): string {\n return this.getAttribute(\"threshold\") ?? \"\";\n }\n\n set threshold(value: string) {\n this.setAttribute(\"threshold\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean) {\n if (value) {\n this.setAttribute(\"once\", \"\");\n } else {\n this.removeAttribute(\"once\");\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get entry(): WcsIntersectEntry | null {\n return this._core.entry;\n }\n\n get intersecting(): boolean {\n return this._core.intersecting;\n }\n\n get ratio(): number {\n return this._core.ratio;\n }\n\n get visible(): boolean {\n return this._core.visible;\n }\n\n get observing(): boolean {\n return this._core.observing;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write re-runs observe(). Mirrors\n // the trigger flag on <wcs-geo> / <wcs-ws> / <wcs-sse>. Prefer the command-token\n // protocol (`command.observe: $command.start`) for state-driven observation;\n // this exists mainly for simple boolean bindings.\n const v = !!value; // normalize truthy state-bindings, like <wcs-sse>'s setter\n if (v) {\n this._trigger = true;\n // try/finally mirrors <wcs-sse>'s set trigger: observe() is never-throw\n // today, but should a synchronous throw path ever appear, the finally still\n // auto-resets _trigger (no stuck-true latch) and emits the completion notice.\n try {\n this.observe();\n } finally {\n this._trigger = false;\n // Always auto-reset to false after the observe() attempt — this is the\n // *momentary acknowledgement* that the trigger was consumed, NOT a signal\n // that observation succeeded (whether the target resolved is reflected by\n // `observing`, not by this event). Firing unconditionally keeps the bound\n // state's trigger flag from sticking at true regardless of resolution.\n // Read `observing` if you need the actual outcome.\n this.dispatchEvent(new CustomEvent(\"wcs-intersect:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n }\n\n // --- Commands ---\n\n /** Re-resolve the target/root from the DOM and (re)start observing. */\n observe(): void {\n const { element, display } = this._resolveTarget();\n // `display` is derived from the `target` *mode* (self/selector/child), not from\n // whether the selector currently matches — so it is applied unconditionally,\n // before the resolution check. A `target=\"#x\"` whose node is momentarily absent\n // still renders `display:none` (it is a selector pointer, never a box).\n this.style.display = display;\n if (!element) {\n // The target is no longer resolvable (e.g. a `target` selector whose node\n // was removed from the DOM). Tear down any stale observation so `observing`\n // does not keep reporting true against a node that is gone.\n this._core.disconnect();\n return;\n }\n this._core.observe(element, this._options());\n }\n\n /**\n * Force a fresh observation: re-resolve target/root from the DOM and re-observe\n * even when nothing changed. Unlike observe() (idempotent for an unchanged\n * target+options), this rebuilds the observer so a new initial callback fires for\n * the current visibility — the way to re-arm an edge-driven consumer after the\n * layout shifted without a visibility transition (e.g. infinite scroll appended a\n * short page that left this sentinel in view). Resolution/teardown rules match\n * observe(): an unresolvable target tears down any stale observation.\n */\n reobserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n if (!element) {\n this._core.disconnect();\n return;\n }\n this._core.reobserve(element, this._options());\n }\n\n unobserve(): void {\n // Single-target Shell: \"stop observing my target\" is exactly the Core's\n // teardown. Delegate to the Core's tracked state rather than re-resolving the\n // selector, so a target that has since left the DOM can still be stopped\n // (re-resolving would yield null and silently leave the observer running).\n this._core.disconnect();\n }\n\n disconnect(): void {\n this._core.disconnect();\n }\n\n reset(): void {\n this._core.reset();\n }\n\n // --- Internal ---\n\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n // Explicit sentinel: observe the element itself as a (typically zero-height)\n // marker, which requires a layout box.\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n // Selector pointer: observe a referenced element in place, staying invisible.\n const scope = this.getRootNode() as Document | ShadowRoot;\n // A user-authored selector can be syntactically invalid (e.g. `#`, `:::`,\n // `[data-*`), which makes querySelector throw a SyntaxError. Swallow it and\n // treat the target as unresolvable — the same \"nothing to observe\" path as a\n // selector matching no element — so a bad attribute never lets the throw\n // escape observe() → connectedCallback / attributeChangedCallback (never-throw).\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n // Omitted: observe the first element child without injecting a box of our own.\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n // No child to wrap (e.g. used as an empty marker) — fall back to self.\n return { element: this, display: \"block\" };\n }\n\n private _resolveRoot(): Element | null {\n const root = this.root;\n if (root === \"\") return null;\n const scope = this.getRootNode() as Document | ShadowRoot;\n // Same never-throw guard as the target selector: an invalid `root` selector\n // falls back to a null root (the viewport) rather than throwing out of observe().\n return this._safeQuery(scope, root);\n }\n\n // Wrap querySelector so a syntactically invalid user-authored selector resolves\n // to null (unresolvable) instead of letting the SyntaxError escape — keeping the\n // sensor never-throw, mirroring worker/src/autoTrigger.ts's resolveText guard.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n\n private _parseThreshold(): number | number[] {\n const raw = this.threshold.trim();\n if (raw === \"\") return 0;\n // Strict parse via Number() (unlike parseFloat, \"0.5px\" -> NaN, not 0.5); drop\n // any non-finite or out-of-range [0,1] value, matching the README note.\n // Drop empty slots first (\"0,,1\" / \"1,\") — Number(\"\") is 0, which would\n // otherwise smuggle a spurious 0 threshold past the finite/range filter.\n const nums = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\")\n .map((s) => Number(s))\n .filter((n) => Number.isFinite(n) && n >= 0 && n <= 1);\n if (nums.length === 0) return 0;\n return nums.length === 1 ? nums[0] : nums;\n }\n\n private _options(): IntersectOptions {\n return {\n root: this._resolveRoot(),\n rootMargin: this.rootMargin,\n threshold: this._parseThreshold(),\n };\n }\n\n private _onChange = (event: Event): void => {\n // `wcs-intersect:change` bubbles, so a nested `<wcs-intersect>` descendant's\n // change would otherwise reach this (ancestor) listener and let a *child's*\n // intersection tear down *our* observer. Only act on our own Core's event.\n // (This also avoids reading `.detail` off a foreign event shape.)\n if (event.target !== this) return;\n // `once`: tear down after the first intersecting observation (lazy-load idiom).\n // Gated at fire time so toggling the `once` attribute takes effect live.\n if (this.once && (event as CustomEvent).detail.isIntersecting) {\n this._core.disconnect();\n }\n };\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.addEventListener(\"wcs-intersect:change\", this._onChange);\n if (!this.manual) {\n this.observe();\n }\n // SSR (§4.4): readiness is synchronous (observation is established above), but\n // expose the Core's ready promise as connectedCallbackPromise so the state\n // binder can await it uniformly. `manual` defers observation but readiness is\n // still immediate.\n this._connectedCallbackPromise = this._core.ready;\n }\n\n disconnectedCallback(): void {\n this.removeEventListener(\"wcs-intersect:change\", this._onChange);\n // dispose() tears down the observer AND bumps the Core's generation so any\n // IntersectionObserver callback still in flight is dropped (§3.4 / §4.1).\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n // Defensive same-value guard. Per spec attributeChangedCallback only fires on\n // an actual value change, so this is effectively a dead branch today — but\n // setAttribute() with an unchanged value (and some test/tooling paths) can\n // still invoke it, and re-observing on an unchanged attribute would be a\n // wasted observer rebuild. Kept intentionally; do not remove.\n if (oldValue === newValue) return;\n // Only react once connected and in automatic mode. The Core's idempotency\n // guard absorbs the autoloader upgrade case (attributeChangedCallback +\n // connectedCallback both calling observe() with identical options).\n if (!this.isConnected || this.manual) return;\n this.observe();\n }\n}\n","import { WcsIntersect } from \"./components/Intersect.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.intersect)) {\n customElements.define(config.tagNames.intersect, WcsIntersect);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapIntersection(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/IntersectionCore.ts","../src/components/Intersect.ts","../src/registerComponents.ts","../src/bootstrapIntersection.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n intersect: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n intersect: \"wcs-intersect\",\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, IntersectOptions, WcsIntersectEntry, WcsIntersectRect } from \"../types.js\";\n\n/**\n * Headless visibility primitive. A thin, framework-agnostic wrapper around the\n * IntersectionObserver API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack sensors (geolocation / timer / websocket), the thing\n * being observed is a *DOM element* — so `observe()` takes the target node. The\n * Core stays DOM-resolution-agnostic: it observes whatever element it is handed\n * (the Shell resolves `target` / `root` selectors before calling). It is a\n * read-only producer — element/layout → state only, with no element-bound path.\n *\n * Every observer callback is published via the single `wcs-intersect:change`\n * event; `intersecting` / `ratio` are read from it through getters (mirroring how\n * GeolocationCore exposes latitude/longitude from one `wcs-geo:position` event),\n * so an observer that binds any of them is notified on every change.\n *\n * `visible` is a latch: it flips to `true` the first time the target intersects\n * and stays `true` until `reset()` — ideal for one-way lazy-load bindings\n * (`src@visible`). `observing` reflects whether an observation is currently\n * active (like TimerCore's `running`).\n *\n * Single-target by design: the Shell observes exactly one element, so the state\n * reflects that element. Multi-target observation is intentionally out of scope.\n */\nexport class IntersectionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"entry\", event: \"wcs-intersect:change\" },\n { name: \"intersecting\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.isIntersecting },\n { name: \"ratio\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.intersectionRatio },\n { name: \"visible\", event: \"wcs-intersect:visible-changed\" },\n { name: \"observing\", event: \"wcs-intersect:observing-changed\" },\n ],\n commands: [\n { name: \"observe\" },\n { name: \"reobserve\" },\n { name: \"unobserve\" },\n { name: \"disconnect\" },\n { name: \"reset\" },\n ],\n };\n\n private _target: EventTarget;\n\n // The live observer and the single element it observes. Options are kept so a\n // repeated observe() with identical options is a no-op (avoids the create→\n // observe→disconnect churn an autoloader upgrade can otherwise cause).\n private _observer: IntersectionObserver | null = null;\n private _observed: Element | null = null;\n private _options: IntersectOptions = {};\n\n private _entry: WcsIntersectEntry | null = null;\n private _visible: boolean = false;\n private _observing: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() and on each observe()/reobserve()\n // teardown+rebuild. IntersectionObserver delivers its callback asynchronously off\n // layout, so a callback can fire after the element is disposed or after a rapid\n // disconnect→reconnect rebuilt the observer. Each observer captures the gen live at\n // creation; a callback from a superseded/torn-down observer has a stale gen and\n // MUST NOT write state to a torn-down element. A boolean flag is insufficient\n // (dispose→observe would flip it back and let stale work slip through).\n private _gen = 0;\n\n // SSR (§3.8): IntersectionObserver setup is synchronous (no async probe to await),\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n /** Resolves immediately — there is no asynchronous probe to await (§3.8). */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get entry(): WcsIntersectEntry | null {\n return this._entry;\n }\n\n get intersecting(): boolean {\n return this._entry ? this._entry.isIntersecting : false;\n }\n\n get ratio(): number {\n return this._entry ? this._entry.intersectionRatio : 0;\n }\n\n get visible(): boolean {\n return this._visible;\n }\n\n get observing(): boolean {\n return this._observing;\n }\n\n // --- State setters with event dispatch ---\n\n private _setEntry(entry: WcsIntersectEntry): void {\n // No same-value guard: `change` carries event semantics (every callback is a\n // distinct observation) and `intersecting` / `ratio` are derived getters that\n // must re-fire on each entry, mirroring GeolocationCore's `position`.\n this._entry = entry;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:change\", {\n detail: entry,\n bubbles: true,\n }));\n }\n\n private _setVisible(visible: boolean): void {\n if (this._visible === visible) return;\n this._visible = visible;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:visible-changed\", {\n detail: visible,\n bubbles: true,\n }));\n }\n\n private _setObserving(observing: boolean): void {\n if (this._observing === observing) return;\n this._observing = observing;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:observing-changed\", {\n detail: observing,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `element`. Idempotent while already observing the same\n * element with the same options. Changing the element or options tears down the\n * current observer and builds a new one (IntersectionObserver options are fixed\n * at construction, so reconfiguring requires a fresh observer).\n *\n * If IntersectionObserver is unavailable (SSR) or the options are invalid (e.g.\n * a malformed `rootMargin`, which the constructor rejects), this is a silent\n * no-op — `observing` stays false, consistent with the never-throw design of\n * the other @wcstack sensors.\n */\n observe(element: Element, options: IntersectOptions = {}): Promise<void> {\n if (this._observer && this._observed === element && this._optionsEqual(this._options, options)) {\n return this._ready;\n }\n this._teardownObserver();\n const observer = this._createObserver(options);\n if (!observer) {\n // Creation failed (unsupported environment or invalid options) *after* we\n // tore down any previous observer. If we were already observing, the\n // observation is now gone, so reflect that — otherwise `observing` would\n // keep reporting true with no live observer behind it (e.g. re-observing an\n // active target with a newly-invalid rootMargin).\n this._setObserving(false);\n return this._ready;\n }\n this._observer = observer;\n this._observed = element;\n this._options = options;\n observer.observe(element);\n this._setObserving(true);\n // SSR (§3.5): observe() returns the readiness promise. Observation establishment\n // is synchronous, so this resolves immediately.\n return this._ready;\n }\n\n /**\n * Force a fresh observation of `element`, even when it matches the currently\n * observed target+options. Unlike observe() — which is idempotent and\n * early-returns for an unchanged target+options *without* re-delivering a\n * callback — this always tears the observer down and rebuilds it, so a new\n * IntersectionObserver delivers an initial callback for the element's CURRENT\n * visibility.\n *\n * This is the way to re-arm an edge-driven consumer (e.g. infinite scroll) after\n * the layout changed without a visibility *transition*: IntersectionObserver only\n * fires on a change, so appending a short page that leaves the sentinel visible\n * yields no new callback — a bare observe() can't help (idempotent), but a\n * reobserve() re-reads the current state. Same never-throw guarantees as\n * observe(); `observing` stays true across a successful re-arm (no false blip).\n */\n reobserve(element: Element, options: IntersectOptions = {}): void {\n this._teardownObserver();\n this.observe(element, options);\n }\n\n /**\n * Stop observing `element`. A no-op if it is not the currently observed\n * element. The observer instance is torn down (single-target Core), so a later\n * observe() rebuilds it.\n */\n unobserve(element: Element): void {\n if (this._observed !== element) return;\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Stop all observation and release the observer. */\n disconnect(): void {\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Clear the `visible` latch so a later intersection can set it again. */\n reset(): void {\n this._setVisible(false);\n }\n\n // --- Lifecycle (§3.5) ---\n\n /**\n * `observe()` (the IntersectionObserver-style command above) establishes\n * monitoring, so there is no separate idempotent monitoring entry point — only\n * teardown. `dispose()` invalidates any in-flight observer callback (`_gen++`)\n * and releases the observer. A later observe() revives it (the Shell calls this\n * from `disconnectedCallback`).\n */\n dispose(): void {\n this._gen++;\n this.disconnect();\n }\n\n // --- Internal ---\n\n private _teardownObserver(): void {\n if (this._observer) {\n this._observer.disconnect();\n this._observer = null;\n }\n this._observed = null;\n // Invalidate the torn-down observer's generation: its callback can still fire\n // once asynchronously after disconnect(), and must be dropped (§3.4).\n this._gen++;\n }\n\n private _createObserver(options: IntersectOptions): IntersectionObserver | null {\n if (typeof IntersectionObserver === \"undefined\") return null;\n // Capture the generation live at creation. The callback closure below guards\n // against deliveries from this observer after it has been superseded or\n // disposed (a stale callback fired off layout after teardown).\n const gen = this._gen;\n try {\n return new IntersectionObserver(\n (entries) => this._onIntersect(gen, entries),\n {\n root: options.root ?? null,\n rootMargin: options.rootMargin ?? \"0px\",\n threshold: options.threshold ?? 0,\n },\n );\n } catch {\n // Invalid options (e.g. a malformed rootMargin) — surface nothing and leave\n // observing false, rather than letting the constructor throw escape.\n return null;\n }\n }\n\n private _onIntersect(gen: number, entries: IntersectionObserverEntry[]): void {\n // Stale-generation guard (§3.4): drop callbacks from an observer that was torn\n // down or disposed (e.g. a delivery that landed after disconnect/reconnect).\n if (gen !== this._gen) return;\n for (const entry of entries) {\n const normalized = this._normalizeEntry(entry);\n this._setEntry(normalized);\n // Latch on the first (and any) intersecting observation; never auto-clears.\n if (normalized.isIntersecting) {\n this._setVisible(true);\n }\n }\n }\n\n private _normalizeEntry(entry: IntersectionObserverEntry): WcsIntersectEntry {\n return {\n isIntersecting: entry.isIntersecting,\n intersectionRatio: entry.intersectionRatio,\n time: entry.time,\n boundingClientRect: this._normalizeRect(entry.boundingClientRect),\n intersectionRect: this._normalizeRect(entry.intersectionRect),\n rootBounds: entry.rootBounds ? this._normalizeRect(entry.rootBounds) : null,\n target: entry.target,\n };\n }\n\n private _normalizeRect(rect: DOMRectReadOnly): WcsIntersectRect {\n return {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n left: rect.left,\n };\n }\n\n private _optionsEqual(a: IntersectOptions, b: IntersectOptions): boolean {\n if ((a.root ?? null) !== (b.root ?? null)) return false;\n if ((a.rootMargin ?? \"0px\") !== (b.rootMargin ?? \"0px\")) return false;\n return this._thresholdKey(a.threshold) === this._thresholdKey(b.threshold);\n }\n\n private _thresholdKey(threshold: number | number[] | undefined): string {\n if (threshold === undefined) return \"0\";\n return Array.isArray(threshold) ? threshold.join(\",\") : String(threshold);\n }\n}\n","import { IWcBindable, IntersectOptions, WcsIntersectEntry } from \"../types.js\";\nimport { IntersectionCore } from \"../core/IntersectionCore.js\";\n\n/**\n * `<wcs-intersect>` — declarative IntersectionObserver.\n *\n * The `target` attribute is the single knob that decides both *what* is observed\n * and how the element renders (it never injects a layout box unless asked):\n *\n * | `target` | observes | display | use case |\n * |-----------------|-----------------------|-------------|-------------------|\n * | omitted | first element child | `contents` | lazy-load wrapper |\n * | `\"#hero\"` / sel | the matched element | `none` | scrollspy (single)|\n * | `\"self\"` | the element itself | `block` | infinite-scroll |\n *\n * `display:contents` means wrapping a child injects no box of its own (so a\n * `<wcs-intersect><img></wcs-intersect>` does not disturb a flex/grid parent);\n * only the explicit `target=\"self\"` sentinel takes a box.\n */\nexport class WcsIntersect extends HTMLElement {\n // SSR (§4.4): the first observation is established synchronously on connect, but\n // the Shell still exposes connectedCallbackPromise so the state binder can await\n // it uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n // Only attributes that change *what or how* we observe trigger a re-observe.\n // `once` is intentionally excluded: it is evaluated at intersection fire time\n // (in `_onChange`), so toggling it takes effect without re-observing — and a\n // re-observe on its change would be a pure no-op (same target, same options).\n // `manual` is also excluded: it is a connect-time policy (\"don't auto-observe\n // on connect\"), not a live switch that should start/stop an active observation.\n static observedAttributes = [\"target\", \"root\", \"root-margin\", \"threshold\"];\n\n static wcBindable: IWcBindable = {\n ...IntersectionCore.wcBindable,\n properties: [\n ...IntersectionCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-intersect:trigger-changed\" },\n ],\n // Shell-level settable surface. Each input carries its mirrored `attribute`\n // hint; `trigger` has none — it is a momentary command-property, not a\n // declarative attribute. The observe / reobserve / unobserve / disconnect /\n // reset commands are inherited from the Core via the spread above.\n inputs: [\n { name: \"target\", attribute: \"target\" },\n { name: \"root\", attribute: \"root\" },\n { name: \"rootMargin\", attribute: \"root-margin\" },\n { name: \"threshold\", attribute: \"threshold\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n // Core の commands をそのまま継承(単一情報源)。<wcs-sse>/<wcs-broadcast> と同型。\n // spread でも継承されるが、Core に command 追加時の追従漏れを防ぐため明示参照する。\n commands: IntersectionCore.wcBindable.commands,\n };\n\n private _core: IntersectionCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new IntersectionCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-intersect:visible-changed\": (d) => ({ visible: d === true }),\n \"wcs-intersect:observing-changed\": (d) => ({ observing: d === true }),\n \"wcs-intersect:change\": (d) => ({ intersecting: d.isIntersecting === true }),\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 get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n get root(): string {\n return this.getAttribute(\"root\") ?? \"\";\n }\n\n set root(value: string) {\n this.setAttribute(\"root\", value);\n }\n\n get rootMargin(): string {\n const attr = this.getAttribute(\"root-margin\");\n return attr === null || attr.trim() === \"\" ? \"0px\" : attr;\n }\n\n set rootMargin(value: string) {\n this.setAttribute(\"root-margin\", value);\n }\n\n get threshold(): string {\n return this.getAttribute(\"threshold\") ?? \"\";\n }\n\n set threshold(value: string) {\n this.setAttribute(\"threshold\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean) {\n if (value) {\n this.setAttribute(\"once\", \"\");\n } else {\n this.removeAttribute(\"once\");\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get entry(): WcsIntersectEntry | null {\n return this._core.entry;\n }\n\n get intersecting(): boolean {\n return this._core.intersecting;\n }\n\n get ratio(): number {\n return this._core.ratio;\n }\n\n get visible(): boolean {\n return this._core.visible;\n }\n\n get observing(): boolean {\n return this._core.observing;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write re-runs observe(). Mirrors\n // the trigger flag on <wcs-geo> / <wcs-ws> / <wcs-sse>. Prefer the command-token\n // protocol (`command.observe: $command.start`) for state-driven observation;\n // this exists mainly for simple boolean bindings.\n const v = !!value; // normalize truthy state-bindings, like <wcs-sse>'s setter\n if (v) {\n this._trigger = true;\n // try/finally mirrors <wcs-sse>'s set trigger: observe() is never-throw\n // today, but should a synchronous throw path ever appear, the finally still\n // auto-resets _trigger (no stuck-true latch) and emits the completion notice.\n try {\n this.observe();\n } finally {\n this._trigger = false;\n // Always auto-reset to false after the observe() attempt — this is the\n // *momentary acknowledgement* that the trigger was consumed, NOT a signal\n // that observation succeeded (whether the target resolved is reflected by\n // `observing`, not by this event). Firing unconditionally keeps the bound\n // state's trigger flag from sticking at true regardless of resolution.\n // Read `observing` if you need the actual outcome.\n this.dispatchEvent(new CustomEvent(\"wcs-intersect:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n }\n\n // --- Commands ---\n\n /** Re-resolve the target/root from the DOM and (re)start observing. */\n observe(): void {\n const { element, display } = this._resolveTarget();\n // `display` is derived from the `target` *mode* (self/selector/child), not from\n // whether the selector currently matches — so it is applied unconditionally,\n // before the resolution check. A `target=\"#x\"` whose node is momentarily absent\n // still renders `display:none` (it is a selector pointer, never a box).\n this.style.display = display;\n if (!element) {\n // The target is no longer resolvable (e.g. a `target` selector whose node\n // was removed from the DOM). Tear down any stale observation so `observing`\n // does not keep reporting true against a node that is gone.\n this._core.disconnect();\n return;\n }\n this._core.observe(element, this._options());\n }\n\n /**\n * Force a fresh observation: re-resolve target/root from the DOM and re-observe\n * even when nothing changed. Unlike observe() (idempotent for an unchanged\n * target+options), this rebuilds the observer so a new initial callback fires for\n * the current visibility — the way to re-arm an edge-driven consumer after the\n * layout shifted without a visibility transition (e.g. infinite scroll appended a\n * short page that left this sentinel in view). Resolution/teardown rules match\n * observe(): an unresolvable target tears down any stale observation.\n */\n reobserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n if (!element) {\n this._core.disconnect();\n return;\n }\n this._core.reobserve(element, this._options());\n }\n\n unobserve(): void {\n // Single-target Shell: \"stop observing my target\" is exactly the Core's\n // teardown. Delegate to the Core's tracked state rather than re-resolving the\n // selector, so a target that has since left the DOM can still be stopped\n // (re-resolving would yield null and silently leave the observer running).\n this._core.disconnect();\n }\n\n disconnect(): void {\n this._core.disconnect();\n }\n\n reset(): void {\n this._core.reset();\n }\n\n // --- Internal ---\n\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n // Explicit sentinel: observe the element itself as a (typically zero-height)\n // marker, which requires a layout box.\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n // Selector pointer: observe a referenced element in place, staying invisible.\n const scope = this.getRootNode() as Document | ShadowRoot;\n // A user-authored selector can be syntactically invalid (e.g. `#`, `:::`,\n // `[data-*`), which makes querySelector throw a SyntaxError. Swallow it and\n // treat the target as unresolvable — the same \"nothing to observe\" path as a\n // selector matching no element — so a bad attribute never lets the throw\n // escape observe() → connectedCallback / attributeChangedCallback (never-throw).\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n // Omitted: observe the first element child without injecting a box of our own.\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n // No child to wrap (e.g. used as an empty marker) — fall back to self.\n return { element: this, display: \"block\" };\n }\n\n private _resolveRoot(): Element | null {\n const root = this.root;\n if (root === \"\") return null;\n const scope = this.getRootNode() as Document | ShadowRoot;\n // Same never-throw guard as the target selector: an invalid `root` selector\n // falls back to a null root (the viewport) rather than throwing out of observe().\n return this._safeQuery(scope, root);\n }\n\n // Wrap querySelector so a syntactically invalid user-authored selector resolves\n // to null (unresolvable) instead of letting the SyntaxError escape — keeping the\n // sensor never-throw, mirroring worker/src/autoTrigger.ts's resolveText guard.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n\n private _parseThreshold(): number | number[] {\n const raw = this.threshold.trim();\n if (raw === \"\") return 0;\n // Strict parse via Number() (unlike parseFloat, \"0.5px\" -> NaN, not 0.5); drop\n // any non-finite or out-of-range [0,1] value, matching the README note.\n // Drop empty slots first (\"0,,1\" / \"1,\") — Number(\"\") is 0, which would\n // otherwise smuggle a spurious 0 threshold past the finite/range filter.\n const nums = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\")\n .map((s) => Number(s))\n .filter((n) => Number.isFinite(n) && n >= 0 && n <= 1);\n if (nums.length === 0) return 0;\n return nums.length === 1 ? nums[0] : nums;\n }\n\n private _options(): IntersectOptions {\n return {\n root: this._resolveRoot(),\n rootMargin: this.rootMargin,\n threshold: this._parseThreshold(),\n };\n }\n\n private _onChange = (event: Event): void => {\n // `wcs-intersect:change` bubbles, so a nested `<wcs-intersect>` descendant's\n // change would otherwise reach this (ancestor) listener and let a *child's*\n // intersection tear down *our* observer. Only act on our own Core's event.\n // (This also avoids reading `.detail` off a foreign event shape.)\n if (event.target !== this) return;\n // `once`: tear down after the first intersecting observation (lazy-load idiom).\n // Gated at fire time so toggling the `once` attribute takes effect live.\n if (this.once && (event as CustomEvent).detail.isIntersecting) {\n this._core.disconnect();\n }\n };\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.addEventListener(\"wcs-intersect:change\", this._onChange);\n if (!this.manual) {\n this.observe();\n }\n // SSR (§4.4): readiness is synchronous (observation is established above), but\n // expose the Core's ready promise as connectedCallbackPromise so the state\n // binder can await it uniformly. `manual` defers observation but readiness is\n // still immediate.\n this._connectedCallbackPromise = this._core.ready;\n }\n\n disconnectedCallback(): void {\n this.removeEventListener(\"wcs-intersect:change\", this._onChange);\n // dispose() tears down the observer AND bumps the Core's generation so any\n // IntersectionObserver callback still in flight is dropped (§3.4 / §4.1).\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n // Defensive same-value guard. Per spec attributeChangedCallback only fires on\n // an actual value change, so this is effectively a dead branch today — but\n // setAttribute() with an unchanged value (and some test/tooling paths) can\n // still invoke it, and re-observing on an unchanged attribute would be a\n // wasted observer rebuild. Kept intentionally; do not remove.\n if (oldValue === newValue) return;\n // Only react once connected and in automatic mode. The Core's idempotency\n // guard absorbs the autoloader upgrade case (attributeChangedCallback +\n // connectedCallback both calling observe() with identical options).\n if (!this.isConnected || this.manual) return;\n this.observe();\n }\n}\n","import { WcsIntersect } from \"./components/Intersect.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.intersect)) {\n customElements.define(config.tagNames.intersect, WcsIntersect);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapIntersection(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 t={tagNames:{intersect:"wcs-intersect"}};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const r of Object.keys(t))e(t[r]);return t}function r(t){if(null===t||"object"!=typeof t)return t;const e={};for(const s of Object.keys(t))e[s]=r(t[s]);return e}let s=null;const i=t;function n(){return s||(s=e(r(t))),s}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"entry",event:"wcs-intersect:change"},{name:"intersecting",event:"wcs-intersect:change",getter:t=>t.detail.isIntersecting},{name:"ratio",event:"wcs-intersect:change",getter:t=>t.detail.intersectionRatio},{name:"visible",event:"wcs-intersect:visible-changed"},{name:"observing",event:"wcs-intersect:observing-changed"}],commands:[{name:"observe"},{name:"reobserve"},{name:"unobserve"},{name:"disconnect"},{name:"reset"}]};_target;_observer=null;_observed=null;_options={};_entry=null;_visible=!1;_observing=!1;_gen=0;_ready=Promise.resolve();constructor(t){super(),this._target=t??this}get ready(){return this._ready}get entry(){return this._entry}get intersecting(){return!!this._entry&&this._entry.isIntersecting}get ratio(){return this._entry?this._entry.intersectionRatio:0}get visible(){return this._visible}get observing(){return this._observing}_setEntry(t){this._entry=t,this._target.dispatchEvent(new CustomEvent("wcs-intersect:change",{detail:t,bubbles:!0}))}_setVisible(t){this._visible!==t&&(this._visible=t,this._target.dispatchEvent(new CustomEvent("wcs-intersect:visible-changed",{detail:t,bubbles:!0})))}_setObserving(t){this._observing!==t&&(this._observing=t,this._target.dispatchEvent(new CustomEvent("wcs-intersect:observing-changed",{detail:t,bubbles:!0})))}observe(t,e={}){if(this._observer&&this._observed===t&&this._optionsEqual(this._options,e))return this._ready;this._teardownObserver();const r=this._createObserver(e);return r?(this._observer=r,this._observed=t,this._options=e,r.observe(t),this._setObserving(!0),this._ready):(this._setObserving(!1),this._ready)}reobserve(t,e={}){this._teardownObserver(),this.observe(t,e)}unobserve(t){this._observed===t&&(this._teardownObserver(),this._setObserving(!1))}disconnect(){this._teardownObserver(),this._setObserving(!1)}reset(){this._setVisible(!1)}dispose(){this._gen++,this.disconnect()}_teardownObserver(){this._observer&&(this._observer.disconnect(),this._observer=null),this._observed=null,this._gen++}_createObserver(t){if("undefined"==typeof IntersectionObserver)return null;const e=this._gen;try{return new IntersectionObserver(t=>this._onIntersect(e,t),{root:t.root??null,rootMargin:t.rootMargin??"0px",threshold:t.threshold??0})}catch{return null}}_onIntersect(t,e){if(t===this._gen)for(const t of e){const e=this._normalizeEntry(t);this._setEntry(e),e.isIntersecting&&this._setVisible(!0)}}_normalizeEntry(t){return{isIntersecting:t.isIntersecting,intersectionRatio:t.intersectionRatio,time:t.time,boundingClientRect:this._normalizeRect(t.boundingClientRect),intersectionRect:this._normalizeRect(t.intersectionRect),rootBounds:t.rootBounds?this._normalizeRect(t.rootBounds):null,target:t.target}}_normalizeRect(t){return{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}_optionsEqual(t,e){return(t.root??null)===(e.root??null)&&((t.rootMargin??"0px")===(e.rootMargin??"0px")&&this._thresholdKey(t.threshold)===this._thresholdKey(e.threshold))}_thresholdKey(t){return void 0===t?"0":Array.isArray(t)?t.join(","):String(t)}}class a extends HTMLElement{static hasConnectedCallbackPromise=!0;static observedAttributes=["target","root","root-margin","threshold"];static wcBindable={...o.wcBindable,properties:[...o.wcBindable.properties,{name:"trigger",event:"wcs-intersect:trigger-changed"}],inputs:[{name:"target",attribute:"target"},{name:"root",attribute:"root"},{name:"rootMargin",attribute:"root-margin"},{name:"threshold",attribute:"threshold"},{name:"once",attribute:"once"},{name:"manual",attribute:"manual"},{name:"trigger"}],commands:o.wcBindable.commands};_core;_trigger=!1;_connectedCallbackPromise=Promise.resolve();constructor(){super(),this._core=new o(this)}get connectedCallbackPromise(){return this._connectedCallbackPromise}get target(){return this.getAttribute("target")??""}set target(t){this.setAttribute("target",t)}get root(){return this.getAttribute("root")??""}set root(t){this.setAttribute("root",t)}get rootMargin(){const t=this.getAttribute("root-margin");return null===t||""===t.trim()?"0px":t}set rootMargin(t){this.setAttribute("root-margin",t)}get threshold(){return this.getAttribute("threshold")??""}set threshold(t){this.setAttribute("threshold",t)}get once(){return this.hasAttribute("once")}set once(t){t?this.setAttribute("once",""):this.removeAttribute("once")}get manual(){return this.hasAttribute("manual")}set manual(t){t?this.setAttribute("manual",""):this.removeAttribute("manual")}get entry(){return this._core.entry}get intersecting(){return this._core.intersecting}get ratio(){return this._core.ratio}get visible(){return this._core.visible}get observing(){return this._core.observing}get trigger(){return this._trigger}set trigger(t){if(!!t){this._trigger=!0;try{this.observe()}finally{this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-intersect:trigger-changed",{detail:!1,bubbles:!0}))}}}observe(){const{element:t,display:e}=this._resolveTarget();this.style.display=e,t?this._core.observe(t,this._options()):this._core.disconnect()}reobserve(){const{element:t,display:e}=this._resolveTarget();this.style.display=e,t?this._core.reobserve(t,this._options()):this._core.disconnect()}unobserve(){this._core.disconnect()}disconnect(){this._core.disconnect()}reset(){this._core.reset()}_resolveTarget(){const t=this.target;if("self"===t)return{element:this,display:"block"};if(""!==t){const e=this.getRootNode();return{element:this._safeQuery(e,t),display:"none"}}const e=this.firstElementChild;return e?{element:e,display:"contents"}:{element:this,display:"block"}}_resolveRoot(){const t=this.root;if(""===t)return null;const e=this.getRootNode();return this._safeQuery(e,t)}_safeQuery(t,e){try{return t.querySelector(e)}catch{return null}}_parseThreshold(){const t=this.threshold.trim();if(""===t)return 0;const e=t.split(",").map(t=>t.trim()).filter(t=>""!==t).map(t=>Number(t)).filter(t=>Number.isFinite(t)&&t>=0&&t<=1);return 0===e.length?0:1===e.length?e[0]:e}_options(){return{root:this._resolveRoot(),rootMargin:this.rootMargin,threshold:this._parseThreshold()}}_onChange=t=>{t.target===this&&this.once&&t.detail.isIntersecting&&this._core.disconnect()};connectedCallback(){this.addEventListener("wcs-intersect:change",this._onChange),this.manual||this.observe(),this._connectedCallbackPromise=this._core.ready}disconnectedCallback(){this.removeEventListener("wcs-intersect:change",this._onChange),this._core.dispose()}attributeChangedCallback(t,e,r){e!==r&&this.isConnected&&!this.manual&&this.observe()}}function c(e){var r;e&&((r=e).tagNames&&Object.assign(t.tagNames,r.tagNames),s=null),customElements.get(i.tagNames.intersect)||customElements.define(i.tagNames.intersect,a)}export{o as IntersectionCore,a as WcsIntersect,c as bootstrapIntersection,n as getConfig};
1
+ const t={tagNames:{intersect:"wcs-intersect"}};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const s of Object.keys(t))e(t[s]);return t}function s(t){if(null===t||"object"!=typeof t)return t;const e={};for(const r of Object.keys(t))e[r]=s(t[r]);return e}let r=null;const i=t;function n(){return r||(r=e(s(t))),r}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"entry",event:"wcs-intersect:change"},{name:"intersecting",event:"wcs-intersect:change",getter:t=>t.detail.isIntersecting},{name:"ratio",event:"wcs-intersect:change",getter:t=>t.detail.intersectionRatio},{name:"visible",event:"wcs-intersect:visible-changed"},{name:"observing",event:"wcs-intersect:observing-changed"}],commands:[{name:"observe"},{name:"reobserve"},{name:"unobserve"},{name:"disconnect"},{name:"reset"}]};_target;_observer=null;_observed=null;_options={};_entry=null;_visible=!1;_observing=!1;_gen=0;_ready=Promise.resolve();constructor(t){super(),this._target=t??this}get ready(){return this._ready}get entry(){return this._entry}get intersecting(){return!!this._entry&&this._entry.isIntersecting}get ratio(){return this._entry?this._entry.intersectionRatio:0}get visible(){return this._visible}get observing(){return this._observing}_setEntry(t){this._entry=t,this._target.dispatchEvent(new CustomEvent("wcs-intersect:change",{detail:t,bubbles:!0}))}_setVisible(t){this._visible!==t&&(this._visible=t,this._target.dispatchEvent(new CustomEvent("wcs-intersect:visible-changed",{detail:t,bubbles:!0})))}_setObserving(t){this._observing!==t&&(this._observing=t,this._target.dispatchEvent(new CustomEvent("wcs-intersect:observing-changed",{detail:t,bubbles:!0})))}observe(t,e={}){if(this._observer&&this._observed===t&&this._optionsEqual(this._options,e))return this._ready;this._teardownObserver();const s=this._createObserver(e);return s?(this._observer=s,this._observed=t,this._options=e,s.observe(t),this._setObserving(!0),this._ready):(this._setObserving(!1),this._ready)}reobserve(t,e={}){this._teardownObserver(),this.observe(t,e)}unobserve(t){this._observed===t&&(this._teardownObserver(),this._setObserving(!1))}disconnect(){this._teardownObserver(),this._setObserving(!1)}reset(){this._setVisible(!1)}dispose(){this._gen++,this.disconnect()}_teardownObserver(){this._observer&&(this._observer.disconnect(),this._observer=null),this._observed=null,this._gen++}_createObserver(t){if("undefined"==typeof IntersectionObserver)return null;const e=this._gen;try{return new IntersectionObserver(t=>this._onIntersect(e,t),{root:t.root??null,rootMargin:t.rootMargin??"0px",threshold:t.threshold??0})}catch{return null}}_onIntersect(t,e){if(t===this._gen)for(const t of e){const e=this._normalizeEntry(t);this._setEntry(e),e.isIntersecting&&this._setVisible(!0)}}_normalizeEntry(t){return{isIntersecting:t.isIntersecting,intersectionRatio:t.intersectionRatio,time:t.time,boundingClientRect:this._normalizeRect(t.boundingClientRect),intersectionRect:this._normalizeRect(t.intersectionRect),rootBounds:t.rootBounds?this._normalizeRect(t.rootBounds):null,target:t.target}}_normalizeRect(t){return{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}_optionsEqual(t,e){return(t.root??null)===(e.root??null)&&((t.rootMargin??"0px")===(e.rootMargin??"0px")&&this._thresholdKey(t.threshold)===this._thresholdKey(e.threshold))}_thresholdKey(t){return void 0===t?"0":Array.isArray(t)?t.join(","):String(t)}}class a extends HTMLElement{static hasConnectedCallbackPromise=!0;static observedAttributes=["target","root","root-margin","threshold"];static wcBindable={...o.wcBindable,properties:[...o.wcBindable.properties,{name:"trigger",event:"wcs-intersect:trigger-changed"}],inputs:[{name:"target",attribute:"target"},{name:"root",attribute:"root"},{name:"rootMargin",attribute:"root-margin"},{name:"threshold",attribute:"threshold"},{name:"once",attribute:"once"},{name:"manual",attribute:"manual"},{name:"trigger"}],commands:o.wcBindable.commands};_core;_trigger=!1;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new o(this),this._internals=this._initInternals(),this._wireStates({"wcs-intersect:visible-changed":t=>({visible:!0===t}),"wcs-intersect:observing-changed":t=>({observing:!0===t}),"wcs-intersect:change":t=>({intersecting:!0===t.isIntersecting})})}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const t=this.attachInternals();return t.states.add("wcs-probe"),t.states.delete("wcs-probe"),t}catch{return null}}_wireStates(t){if(null===this._internals)return;const e=this._internals.states;for(const[s,r]of Object.entries(t))this.addEventListener(s,t=>{const s=this.hasAttribute("debug-states");for(const[i,n]of Object.entries(r(t.detail))){try{n?e.add(i):e.delete(i)}catch{}s&&this.toggleAttribute(`data-wcs-state-${i}`,n)}})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get target(){return this.getAttribute("target")??""}set target(t){this.setAttribute("target",t)}get root(){return this.getAttribute("root")??""}set root(t){this.setAttribute("root",t)}get rootMargin(){const t=this.getAttribute("root-margin");return null===t||""===t.trim()?"0px":t}set rootMargin(t){this.setAttribute("root-margin",t)}get threshold(){return this.getAttribute("threshold")??""}set threshold(t){this.setAttribute("threshold",t)}get once(){return this.hasAttribute("once")}set once(t){t?this.setAttribute("once",""):this.removeAttribute("once")}get manual(){return this.hasAttribute("manual")}set manual(t){t?this.setAttribute("manual",""):this.removeAttribute("manual")}get entry(){return this._core.entry}get intersecting(){return this._core.intersecting}get ratio(){return this._core.ratio}get visible(){return this._core.visible}get observing(){return this._core.observing}get trigger(){return this._trigger}set trigger(t){if(!!t){this._trigger=!0;try{this.observe()}finally{this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-intersect:trigger-changed",{detail:!1,bubbles:!0}))}}}observe(){const{element:t,display:e}=this._resolveTarget();this.style.display=e,t?this._core.observe(t,this._options()):this._core.disconnect()}reobserve(){const{element:t,display:e}=this._resolveTarget();this.style.display=e,t?this._core.reobserve(t,this._options()):this._core.disconnect()}unobserve(){this._core.disconnect()}disconnect(){this._core.disconnect()}reset(){this._core.reset()}_resolveTarget(){const t=this.target;if("self"===t)return{element:this,display:"block"};if(""!==t){const e=this.getRootNode();return{element:this._safeQuery(e,t),display:"none"}}const e=this.firstElementChild;return e?{element:e,display:"contents"}:{element:this,display:"block"}}_resolveRoot(){const t=this.root;if(""===t)return null;const e=this.getRootNode();return this._safeQuery(e,t)}_safeQuery(t,e){try{return t.querySelector(e)}catch{return null}}_parseThreshold(){const t=this.threshold.trim();if(""===t)return 0;const e=t.split(",").map(t=>t.trim()).filter(t=>""!==t).map(t=>Number(t)).filter(t=>Number.isFinite(t)&&t>=0&&t<=1);return 0===e.length?0:1===e.length?e[0]:e}_options(){return{root:this._resolveRoot(),rootMargin:this.rootMargin,threshold:this._parseThreshold()}}_onChange=t=>{t.target===this&&this.once&&t.detail.isIntersecting&&this._core.disconnect()};connectedCallback(){this.addEventListener("wcs-intersect:change",this._onChange),this.manual||this.observe(),this._connectedCallbackPromise=this._core.ready}disconnectedCallback(){this.removeEventListener("wcs-intersect:change",this._onChange),this._core.dispose()}attributeChangedCallback(t,e,s){e!==s&&this.isConnected&&!this.manual&&this.observe()}}function c(e){var s;e&&((s=e).tagNames&&Object.assign(t.tagNames,s.tagNames),r=null),customElements.get(i.tagNames.intersect)||customElements.define(i.tagNames.intersect,a)}export{o as IntersectionCore,a as WcsIntersect,c as bootstrapIntersection,n 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/IntersectionCore.ts","../src/components/Intersect.ts","../src/bootstrapIntersection.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n intersect: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n intersect: \"wcs-intersect\",\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, IntersectOptions, WcsIntersectEntry, WcsIntersectRect } from \"../types.js\";\n\n/**\n * Headless visibility primitive. A thin, framework-agnostic wrapper around the\n * IntersectionObserver API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack sensors (geolocation / timer / websocket), the thing\n * being observed is a *DOM element* — so `observe()` takes the target node. The\n * Core stays DOM-resolution-agnostic: it observes whatever element it is handed\n * (the Shell resolves `target` / `root` selectors before calling). It is a\n * read-only producer — element/layout → state only, with no element-bound path.\n *\n * Every observer callback is published via the single `wcs-intersect:change`\n * event; `intersecting` / `ratio` are read from it through getters (mirroring how\n * GeolocationCore exposes latitude/longitude from one `wcs-geo:position` event),\n * so an observer that binds any of them is notified on every change.\n *\n * `visible` is a latch: it flips to `true` the first time the target intersects\n * and stays `true` until `reset()` — ideal for one-way lazy-load bindings\n * (`src@visible`). `observing` reflects whether an observation is currently\n * active (like TimerCore's `running`).\n *\n * Single-target by design: the Shell observes exactly one element, so the state\n * reflects that element. Multi-target observation is intentionally out of scope.\n */\nexport class IntersectionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"entry\", event: \"wcs-intersect:change\" },\n { name: \"intersecting\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.isIntersecting },\n { name: \"ratio\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.intersectionRatio },\n { name: \"visible\", event: \"wcs-intersect:visible-changed\" },\n { name: \"observing\", event: \"wcs-intersect:observing-changed\" },\n ],\n commands: [\n { name: \"observe\" },\n { name: \"reobserve\" },\n { name: \"unobserve\" },\n { name: \"disconnect\" },\n { name: \"reset\" },\n ],\n };\n\n private _target: EventTarget;\n\n // The live observer and the single element it observes. Options are kept so a\n // repeated observe() with identical options is a no-op (avoids the create→\n // observe→disconnect churn an autoloader upgrade can otherwise cause).\n private _observer: IntersectionObserver | null = null;\n private _observed: Element | null = null;\n private _options: IntersectOptions = {};\n\n private _entry: WcsIntersectEntry | null = null;\n private _visible: boolean = false;\n private _observing: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() and on each observe()/reobserve()\n // teardown+rebuild. IntersectionObserver delivers its callback asynchronously off\n // layout, so a callback can fire after the element is disposed or after a rapid\n // disconnect→reconnect rebuilt the observer. Each observer captures the gen live at\n // creation; a callback from a superseded/torn-down observer has a stale gen and\n // MUST NOT write state to a torn-down element. A boolean flag is insufficient\n // (dispose→observe would flip it back and let stale work slip through).\n private _gen = 0;\n\n // SSR (§3.8): IntersectionObserver setup is synchronous (no async probe to await),\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n /** Resolves immediately — there is no asynchronous probe to await (§3.8). */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get entry(): WcsIntersectEntry | null {\n return this._entry;\n }\n\n get intersecting(): boolean {\n return this._entry ? this._entry.isIntersecting : false;\n }\n\n get ratio(): number {\n return this._entry ? this._entry.intersectionRatio : 0;\n }\n\n get visible(): boolean {\n return this._visible;\n }\n\n get observing(): boolean {\n return this._observing;\n }\n\n // --- State setters with event dispatch ---\n\n private _setEntry(entry: WcsIntersectEntry): void {\n // No same-value guard: `change` carries event semantics (every callback is a\n // distinct observation) and `intersecting` / `ratio` are derived getters that\n // must re-fire on each entry, mirroring GeolocationCore's `position`.\n this._entry = entry;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:change\", {\n detail: entry,\n bubbles: true,\n }));\n }\n\n private _setVisible(visible: boolean): void {\n if (this._visible === visible) return;\n this._visible = visible;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:visible-changed\", {\n detail: visible,\n bubbles: true,\n }));\n }\n\n private _setObserving(observing: boolean): void {\n if (this._observing === observing) return;\n this._observing = observing;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:observing-changed\", {\n detail: observing,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `element`. Idempotent while already observing the same\n * element with the same options. Changing the element or options tears down the\n * current observer and builds a new one (IntersectionObserver options are fixed\n * at construction, so reconfiguring requires a fresh observer).\n *\n * If IntersectionObserver is unavailable (SSR) or the options are invalid (e.g.\n * a malformed `rootMargin`, which the constructor rejects), this is a silent\n * no-op — `observing` stays false, consistent with the never-throw design of\n * the other @wcstack sensors.\n */\n observe(element: Element, options: IntersectOptions = {}): Promise<void> {\n if (this._observer && this._observed === element && this._optionsEqual(this._options, options)) {\n return this._ready;\n }\n this._teardownObserver();\n const observer = this._createObserver(options);\n if (!observer) {\n // Creation failed (unsupported environment or invalid options) *after* we\n // tore down any previous observer. If we were already observing, the\n // observation is now gone, so reflect that — otherwise `observing` would\n // keep reporting true with no live observer behind it (e.g. re-observing an\n // active target with a newly-invalid rootMargin).\n this._setObserving(false);\n return this._ready;\n }\n this._observer = observer;\n this._observed = element;\n this._options = options;\n observer.observe(element);\n this._setObserving(true);\n // SSR (§3.5): observe() returns the readiness promise. Observation establishment\n // is synchronous, so this resolves immediately.\n return this._ready;\n }\n\n /**\n * Force a fresh observation of `element`, even when it matches the currently\n * observed target+options. Unlike observe() — which is idempotent and\n * early-returns for an unchanged target+options *without* re-delivering a\n * callback — this always tears the observer down and rebuilds it, so a new\n * IntersectionObserver delivers an initial callback for the element's CURRENT\n * visibility.\n *\n * This is the way to re-arm an edge-driven consumer (e.g. infinite scroll) after\n * the layout changed without a visibility *transition*: IntersectionObserver only\n * fires on a change, so appending a short page that leaves the sentinel visible\n * yields no new callback — a bare observe() can't help (idempotent), but a\n * reobserve() re-reads the current state. Same never-throw guarantees as\n * observe(); `observing` stays true across a successful re-arm (no false blip).\n */\n reobserve(element: Element, options: IntersectOptions = {}): void {\n this._teardownObserver();\n this.observe(element, options);\n }\n\n /**\n * Stop observing `element`. A no-op if it is not the currently observed\n * element. The observer instance is torn down (single-target Core), so a later\n * observe() rebuilds it.\n */\n unobserve(element: Element): void {\n if (this._observed !== element) return;\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Stop all observation and release the observer. */\n disconnect(): void {\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Clear the `visible` latch so a later intersection can set it again. */\n reset(): void {\n this._setVisible(false);\n }\n\n // --- Lifecycle (§3.5) ---\n\n /**\n * `observe()` (the IntersectionObserver-style command above) establishes\n * monitoring, so there is no separate idempotent monitoring entry point — only\n * teardown. `dispose()` invalidates any in-flight observer callback (`_gen++`)\n * and releases the observer. A later observe() revives it (the Shell calls this\n * from `disconnectedCallback`).\n */\n dispose(): void {\n this._gen++;\n this.disconnect();\n }\n\n // --- Internal ---\n\n private _teardownObserver(): void {\n if (this._observer) {\n this._observer.disconnect();\n this._observer = null;\n }\n this._observed = null;\n // Invalidate the torn-down observer's generation: its callback can still fire\n // once asynchronously after disconnect(), and must be dropped (§3.4).\n this._gen++;\n }\n\n private _createObserver(options: IntersectOptions): IntersectionObserver | null {\n if (typeof IntersectionObserver === \"undefined\") return null;\n // Capture the generation live at creation. The callback closure below guards\n // against deliveries from this observer after it has been superseded or\n // disposed (a stale callback fired off layout after teardown).\n const gen = this._gen;\n try {\n return new IntersectionObserver(\n (entries) => this._onIntersect(gen, entries),\n {\n root: options.root ?? null,\n rootMargin: options.rootMargin ?? \"0px\",\n threshold: options.threshold ?? 0,\n },\n );\n } catch {\n // Invalid options (e.g. a malformed rootMargin) — surface nothing and leave\n // observing false, rather than letting the constructor throw escape.\n return null;\n }\n }\n\n private _onIntersect(gen: number, entries: IntersectionObserverEntry[]): void {\n // Stale-generation guard (§3.4): drop callbacks from an observer that was torn\n // down or disposed (e.g. a delivery that landed after disconnect/reconnect).\n if (gen !== this._gen) return;\n for (const entry of entries) {\n const normalized = this._normalizeEntry(entry);\n this._setEntry(normalized);\n // Latch on the first (and any) intersecting observation; never auto-clears.\n if (normalized.isIntersecting) {\n this._setVisible(true);\n }\n }\n }\n\n private _normalizeEntry(entry: IntersectionObserverEntry): WcsIntersectEntry {\n return {\n isIntersecting: entry.isIntersecting,\n intersectionRatio: entry.intersectionRatio,\n time: entry.time,\n boundingClientRect: this._normalizeRect(entry.boundingClientRect),\n intersectionRect: this._normalizeRect(entry.intersectionRect),\n rootBounds: entry.rootBounds ? this._normalizeRect(entry.rootBounds) : null,\n target: entry.target,\n };\n }\n\n private _normalizeRect(rect: DOMRectReadOnly): WcsIntersectRect {\n return {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n left: rect.left,\n };\n }\n\n private _optionsEqual(a: IntersectOptions, b: IntersectOptions): boolean {\n if ((a.root ?? null) !== (b.root ?? null)) return false;\n if ((a.rootMargin ?? \"0px\") !== (b.rootMargin ?? \"0px\")) return false;\n return this._thresholdKey(a.threshold) === this._thresholdKey(b.threshold);\n }\n\n private _thresholdKey(threshold: number | number[] | undefined): string {\n if (threshold === undefined) return \"0\";\n return Array.isArray(threshold) ? threshold.join(\",\") : String(threshold);\n }\n}\n","import { IWcBindable, IntersectOptions, WcsIntersectEntry } from \"../types.js\";\nimport { IntersectionCore } from \"../core/IntersectionCore.js\";\n\n/**\n * `<wcs-intersect>` — declarative IntersectionObserver.\n *\n * The `target` attribute is the single knob that decides both *what* is observed\n * and how the element renders (it never injects a layout box unless asked):\n *\n * | `target` | observes | display | use case |\n * |-----------------|-----------------------|-------------|-------------------|\n * | omitted | first element child | `contents` | lazy-load wrapper |\n * | `\"#hero\"` / sel | the matched element | `none` | scrollspy (single)|\n * | `\"self\"` | the element itself | `block` | infinite-scroll |\n *\n * `display:contents` means wrapping a child injects no box of its own (so a\n * `<wcs-intersect><img></wcs-intersect>` does not disturb a flex/grid parent);\n * only the explicit `target=\"self\"` sentinel takes a box.\n */\nexport class WcsIntersect extends HTMLElement {\n // SSR (§4.4): the first observation is established synchronously on connect, but\n // the Shell still exposes connectedCallbackPromise so the state binder can await\n // it uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n // Only attributes that change *what or how* we observe trigger a re-observe.\n // `once` is intentionally excluded: it is evaluated at intersection fire time\n // (in `_onChange`), so toggling it takes effect without re-observing — and a\n // re-observe on its change would be a pure no-op (same target, same options).\n // `manual` is also excluded: it is a connect-time policy (\"don't auto-observe\n // on connect\"), not a live switch that should start/stop an active observation.\n static observedAttributes = [\"target\", \"root\", \"root-margin\", \"threshold\"];\n\n static wcBindable: IWcBindable = {\n ...IntersectionCore.wcBindable,\n properties: [\n ...IntersectionCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-intersect:trigger-changed\" },\n ],\n // Shell-level settable surface. Each input carries its mirrored `attribute`\n // hint; `trigger` has none — it is a momentary command-property, not a\n // declarative attribute. The observe / reobserve / unobserve / disconnect /\n // reset commands are inherited from the Core via the spread above.\n inputs: [\n { name: \"target\", attribute: \"target\" },\n { name: \"root\", attribute: \"root\" },\n { name: \"rootMargin\", attribute: \"root-margin\" },\n { name: \"threshold\", attribute: \"threshold\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n // Core の commands をそのまま継承(単一情報源)。<wcs-sse>/<wcs-broadcast> と同型。\n // spread でも継承されるが、Core に command 追加時の追従漏れを防ぐため明示参照する。\n commands: IntersectionCore.wcBindable.commands,\n };\n\n private _core: IntersectionCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new IntersectionCore(this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n get root(): string {\n return this.getAttribute(\"root\") ?? \"\";\n }\n\n set root(value: string) {\n this.setAttribute(\"root\", value);\n }\n\n get rootMargin(): string {\n const attr = this.getAttribute(\"root-margin\");\n return attr === null || attr.trim() === \"\" ? \"0px\" : attr;\n }\n\n set rootMargin(value: string) {\n this.setAttribute(\"root-margin\", value);\n }\n\n get threshold(): string {\n return this.getAttribute(\"threshold\") ?? \"\";\n }\n\n set threshold(value: string) {\n this.setAttribute(\"threshold\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean) {\n if (value) {\n this.setAttribute(\"once\", \"\");\n } else {\n this.removeAttribute(\"once\");\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get entry(): WcsIntersectEntry | null {\n return this._core.entry;\n }\n\n get intersecting(): boolean {\n return this._core.intersecting;\n }\n\n get ratio(): number {\n return this._core.ratio;\n }\n\n get visible(): boolean {\n return this._core.visible;\n }\n\n get observing(): boolean {\n return this._core.observing;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write re-runs observe(). Mirrors\n // the trigger flag on <wcs-geo> / <wcs-ws> / <wcs-sse>. Prefer the command-token\n // protocol (`command.observe: $command.start`) for state-driven observation;\n // this exists mainly for simple boolean bindings.\n const v = !!value; // normalize truthy state-bindings, like <wcs-sse>'s setter\n if (v) {\n this._trigger = true;\n // try/finally mirrors <wcs-sse>'s set trigger: observe() is never-throw\n // today, but should a synchronous throw path ever appear, the finally still\n // auto-resets _trigger (no stuck-true latch) and emits the completion notice.\n try {\n this.observe();\n } finally {\n this._trigger = false;\n // Always auto-reset to false after the observe() attempt — this is the\n // *momentary acknowledgement* that the trigger was consumed, NOT a signal\n // that observation succeeded (whether the target resolved is reflected by\n // `observing`, not by this event). Firing unconditionally keeps the bound\n // state's trigger flag from sticking at true regardless of resolution.\n // Read `observing` if you need the actual outcome.\n this.dispatchEvent(new CustomEvent(\"wcs-intersect:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n }\n\n // --- Commands ---\n\n /** Re-resolve the target/root from the DOM and (re)start observing. */\n observe(): void {\n const { element, display } = this._resolveTarget();\n // `display` is derived from the `target` *mode* (self/selector/child), not from\n // whether the selector currently matches — so it is applied unconditionally,\n // before the resolution check. A `target=\"#x\"` whose node is momentarily absent\n // still renders `display:none` (it is a selector pointer, never a box).\n this.style.display = display;\n if (!element) {\n // The target is no longer resolvable (e.g. a `target` selector whose node\n // was removed from the DOM). Tear down any stale observation so `observing`\n // does not keep reporting true against a node that is gone.\n this._core.disconnect();\n return;\n }\n this._core.observe(element, this._options());\n }\n\n /**\n * Force a fresh observation: re-resolve target/root from the DOM and re-observe\n * even when nothing changed. Unlike observe() (idempotent for an unchanged\n * target+options), this rebuilds the observer so a new initial callback fires for\n * the current visibility — the way to re-arm an edge-driven consumer after the\n * layout shifted without a visibility transition (e.g. infinite scroll appended a\n * short page that left this sentinel in view). Resolution/teardown rules match\n * observe(): an unresolvable target tears down any stale observation.\n */\n reobserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n if (!element) {\n this._core.disconnect();\n return;\n }\n this._core.reobserve(element, this._options());\n }\n\n unobserve(): void {\n // Single-target Shell: \"stop observing my target\" is exactly the Core's\n // teardown. Delegate to the Core's tracked state rather than re-resolving the\n // selector, so a target that has since left the DOM can still be stopped\n // (re-resolving would yield null and silently leave the observer running).\n this._core.disconnect();\n }\n\n disconnect(): void {\n this._core.disconnect();\n }\n\n reset(): void {\n this._core.reset();\n }\n\n // --- Internal ---\n\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n // Explicit sentinel: observe the element itself as a (typically zero-height)\n // marker, which requires a layout box.\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n // Selector pointer: observe a referenced element in place, staying invisible.\n const scope = this.getRootNode() as Document | ShadowRoot;\n // A user-authored selector can be syntactically invalid (e.g. `#`, `:::`,\n // `[data-*`), which makes querySelector throw a SyntaxError. Swallow it and\n // treat the target as unresolvable — the same \"nothing to observe\" path as a\n // selector matching no element — so a bad attribute never lets the throw\n // escape observe() → connectedCallback / attributeChangedCallback (never-throw).\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n // Omitted: observe the first element child without injecting a box of our own.\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n // No child to wrap (e.g. used as an empty marker) — fall back to self.\n return { element: this, display: \"block\" };\n }\n\n private _resolveRoot(): Element | null {\n const root = this.root;\n if (root === \"\") return null;\n const scope = this.getRootNode() as Document | ShadowRoot;\n // Same never-throw guard as the target selector: an invalid `root` selector\n // falls back to a null root (the viewport) rather than throwing out of observe().\n return this._safeQuery(scope, root);\n }\n\n // Wrap querySelector so a syntactically invalid user-authored selector resolves\n // to null (unresolvable) instead of letting the SyntaxError escape — keeping the\n // sensor never-throw, mirroring worker/src/autoTrigger.ts's resolveText guard.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n\n private _parseThreshold(): number | number[] {\n const raw = this.threshold.trim();\n if (raw === \"\") return 0;\n // Strict parse via Number() (unlike parseFloat, \"0.5px\" -> NaN, not 0.5); drop\n // any non-finite or out-of-range [0,1] value, matching the README note.\n // Drop empty slots first (\"0,,1\" / \"1,\") — Number(\"\") is 0, which would\n // otherwise smuggle a spurious 0 threshold past the finite/range filter.\n const nums = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\")\n .map((s) => Number(s))\n .filter((n) => Number.isFinite(n) && n >= 0 && n <= 1);\n if (nums.length === 0) return 0;\n return nums.length === 1 ? nums[0] : nums;\n }\n\n private _options(): IntersectOptions {\n return {\n root: this._resolveRoot(),\n rootMargin: this.rootMargin,\n threshold: this._parseThreshold(),\n };\n }\n\n private _onChange = (event: Event): void => {\n // `wcs-intersect:change` bubbles, so a nested `<wcs-intersect>` descendant's\n // change would otherwise reach this (ancestor) listener and let a *child's*\n // intersection tear down *our* observer. Only act on our own Core's event.\n // (This also avoids reading `.detail` off a foreign event shape.)\n if (event.target !== this) return;\n // `once`: tear down after the first intersecting observation (lazy-load idiom).\n // Gated at fire time so toggling the `once` attribute takes effect live.\n if (this.once && (event as CustomEvent).detail.isIntersecting) {\n this._core.disconnect();\n }\n };\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.addEventListener(\"wcs-intersect:change\", this._onChange);\n if (!this.manual) {\n this.observe();\n }\n // SSR (§4.4): readiness is synchronous (observation is established above), but\n // expose the Core's ready promise as connectedCallbackPromise so the state\n // binder can await it uniformly. `manual` defers observation but readiness is\n // still immediate.\n this._connectedCallbackPromise = this._core.ready;\n }\n\n disconnectedCallback(): void {\n this.removeEventListener(\"wcs-intersect:change\", this._onChange);\n // dispose() tears down the observer AND bumps the Core's generation so any\n // IntersectionObserver callback still in flight is dropped (§3.4 / §4.1).\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n // Defensive same-value guard. Per spec attributeChangedCallback only fires on\n // an actual value change, so this is effectively a dead branch today — but\n // setAttribute() with an unchanged value (and some test/tooling paths) can\n // still invoke it, and re-observing on an unchanged attribute would be a\n // wasted observer rebuild. Kept intentionally; do not remove.\n if (oldValue === newValue) return;\n // Only react once connected and in automatic mode. The Core's idempotency\n // guard absorbs the autoloader upgrade case (attributeChangedCallback +\n // connectedCallback both calling observe() with identical options).\n if (!this.isConnected || this.manual) return;\n this.observe();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapIntersection(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsIntersect } from \"./components/Intersect.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.intersect)) {\n customElements.define(config.tagNames.intersect, WcsIntersect);\n }\n}\n"],"names":["_config","tagNames","intersect","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","IntersectionCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","isIntersecting","intersectionRatio","commands","_target","_observer","_observed","_options","_entry","_visible","_observing","_gen","_ready","Promise","resolve","constructor","target","super","this","ready","entry","intersecting","ratio","visible","observing","_setEntry","dispatchEvent","CustomEvent","bubbles","_setVisible","_setObserving","observe","element","options","_optionsEqual","_teardownObserver","observer","_createObserver","reobserve","unobserve","disconnect","reset","dispose","IntersectionObserver","gen","entries","_onIntersect","root","rootMargin","threshold","normalized","_normalizeEntry","time","boundingClientRect","_normalizeRect","intersectionRect","rootBounds","rect","x","y","width","height","top","right","bottom","left","a","b","_thresholdKey","undefined","Array","isArray","join","String","WcsIntersect","HTMLElement","wcBindable","inputs","attribute","_core","_trigger","_connectedCallbackPromise","connectedCallbackPromise","getAttribute","value","setAttribute","attr","trim","once","hasAttribute","removeAttribute","manual","trigger","display","_resolveTarget","style","scope","getRootNode","_safeQuery","child","firstElementChild","_resolveRoot","selector","querySelector","_parseThreshold","raw","nums","split","map","s","filter","Number","n","isFinite","length","_onChange","connectedCallback","addEventListener","disconnectedCallback","removeEventListener","attributeChangedCallback","_name","oldValue","newValue","isConnected","bootstrapIntersection","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/IntersectionCore.ts","../src/components/Intersect.ts","../src/bootstrapIntersection.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n intersect: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n intersect: \"wcs-intersect\",\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, IntersectOptions, WcsIntersectEntry, WcsIntersectRect } from \"../types.js\";\n\n/**\n * Headless visibility primitive. A thin, framework-agnostic wrapper around the\n * IntersectionObserver API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack sensors (geolocation / timer / websocket), the thing\n * being observed is a *DOM element* — so `observe()` takes the target node. The\n * Core stays DOM-resolution-agnostic: it observes whatever element it is handed\n * (the Shell resolves `target` / `root` selectors before calling). It is a\n * read-only producer — element/layout → state only, with no element-bound path.\n *\n * Every observer callback is published via the single `wcs-intersect:change`\n * event; `intersecting` / `ratio` are read from it through getters (mirroring how\n * GeolocationCore exposes latitude/longitude from one `wcs-geo:position` event),\n * so an observer that binds any of them is notified on every change.\n *\n * `visible` is a latch: it flips to `true` the first time the target intersects\n * and stays `true` until `reset()` — ideal for one-way lazy-load bindings\n * (`src@visible`). `observing` reflects whether an observation is currently\n * active (like TimerCore's `running`).\n *\n * Single-target by design: the Shell observes exactly one element, so the state\n * reflects that element. Multi-target observation is intentionally out of scope.\n */\nexport class IntersectionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"entry\", event: \"wcs-intersect:change\" },\n { name: \"intersecting\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.isIntersecting },\n { name: \"ratio\", event: \"wcs-intersect:change\", getter: (e: Event) => (e as CustomEvent).detail.intersectionRatio },\n { name: \"visible\", event: \"wcs-intersect:visible-changed\" },\n { name: \"observing\", event: \"wcs-intersect:observing-changed\" },\n ],\n commands: [\n { name: \"observe\" },\n { name: \"reobserve\" },\n { name: \"unobserve\" },\n { name: \"disconnect\" },\n { name: \"reset\" },\n ],\n };\n\n private _target: EventTarget;\n\n // The live observer and the single element it observes. Options are kept so a\n // repeated observe() with identical options is a no-op (avoids the create→\n // observe→disconnect churn an autoloader upgrade can otherwise cause).\n private _observer: IntersectionObserver | null = null;\n private _observed: Element | null = null;\n private _options: IntersectOptions = {};\n\n private _entry: WcsIntersectEntry | null = null;\n private _visible: boolean = false;\n private _observing: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() and on each observe()/reobserve()\n // teardown+rebuild. IntersectionObserver delivers its callback asynchronously off\n // layout, so a callback can fire after the element is disposed or after a rapid\n // disconnect→reconnect rebuilt the observer. Each observer captures the gen live at\n // creation; a callback from a superseded/torn-down observer has a stale gen and\n // MUST NOT write state to a torn-down element. A boolean flag is insufficient\n // (dispose→observe would flip it back and let stale work slip through).\n private _gen = 0;\n\n // SSR (§3.8): IntersectionObserver setup is synchronous (no async probe to await),\n // so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n /** Resolves immediately — there is no asynchronous probe to await (§3.8). */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get entry(): WcsIntersectEntry | null {\n return this._entry;\n }\n\n get intersecting(): boolean {\n return this._entry ? this._entry.isIntersecting : false;\n }\n\n get ratio(): number {\n return this._entry ? this._entry.intersectionRatio : 0;\n }\n\n get visible(): boolean {\n return this._visible;\n }\n\n get observing(): boolean {\n return this._observing;\n }\n\n // --- State setters with event dispatch ---\n\n private _setEntry(entry: WcsIntersectEntry): void {\n // No same-value guard: `change` carries event semantics (every callback is a\n // distinct observation) and `intersecting` / `ratio` are derived getters that\n // must re-fire on each entry, mirroring GeolocationCore's `position`.\n this._entry = entry;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:change\", {\n detail: entry,\n bubbles: true,\n }));\n }\n\n private _setVisible(visible: boolean): void {\n if (this._visible === visible) return;\n this._visible = visible;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:visible-changed\", {\n detail: visible,\n bubbles: true,\n }));\n }\n\n private _setObserving(observing: boolean): void {\n if (this._observing === observing) return;\n this._observing = observing;\n this._target.dispatchEvent(new CustomEvent(\"wcs-intersect:observing-changed\", {\n detail: observing,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `element`. Idempotent while already observing the same\n * element with the same options. Changing the element or options tears down the\n * current observer and builds a new one (IntersectionObserver options are fixed\n * at construction, so reconfiguring requires a fresh observer).\n *\n * If IntersectionObserver is unavailable (SSR) or the options are invalid (e.g.\n * a malformed `rootMargin`, which the constructor rejects), this is a silent\n * no-op — `observing` stays false, consistent with the never-throw design of\n * the other @wcstack sensors.\n */\n observe(element: Element, options: IntersectOptions = {}): Promise<void> {\n if (this._observer && this._observed === element && this._optionsEqual(this._options, options)) {\n return this._ready;\n }\n this._teardownObserver();\n const observer = this._createObserver(options);\n if (!observer) {\n // Creation failed (unsupported environment or invalid options) *after* we\n // tore down any previous observer. If we were already observing, the\n // observation is now gone, so reflect that — otherwise `observing` would\n // keep reporting true with no live observer behind it (e.g. re-observing an\n // active target with a newly-invalid rootMargin).\n this._setObserving(false);\n return this._ready;\n }\n this._observer = observer;\n this._observed = element;\n this._options = options;\n observer.observe(element);\n this._setObserving(true);\n // SSR (§3.5): observe() returns the readiness promise. Observation establishment\n // is synchronous, so this resolves immediately.\n return this._ready;\n }\n\n /**\n * Force a fresh observation of `element`, even when it matches the currently\n * observed target+options. Unlike observe() — which is idempotent and\n * early-returns for an unchanged target+options *without* re-delivering a\n * callback — this always tears the observer down and rebuilds it, so a new\n * IntersectionObserver delivers an initial callback for the element's CURRENT\n * visibility.\n *\n * This is the way to re-arm an edge-driven consumer (e.g. infinite scroll) after\n * the layout changed without a visibility *transition*: IntersectionObserver only\n * fires on a change, so appending a short page that leaves the sentinel visible\n * yields no new callback — a bare observe() can't help (idempotent), but a\n * reobserve() re-reads the current state. Same never-throw guarantees as\n * observe(); `observing` stays true across a successful re-arm (no false blip).\n */\n reobserve(element: Element, options: IntersectOptions = {}): void {\n this._teardownObserver();\n this.observe(element, options);\n }\n\n /**\n * Stop observing `element`. A no-op if it is not the currently observed\n * element. The observer instance is torn down (single-target Core), so a later\n * observe() rebuilds it.\n */\n unobserve(element: Element): void {\n if (this._observed !== element) return;\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Stop all observation and release the observer. */\n disconnect(): void {\n this._teardownObserver();\n this._setObserving(false);\n }\n\n /** Clear the `visible` latch so a later intersection can set it again. */\n reset(): void {\n this._setVisible(false);\n }\n\n // --- Lifecycle (§3.5) ---\n\n /**\n * `observe()` (the IntersectionObserver-style command above) establishes\n * monitoring, so there is no separate idempotent monitoring entry point — only\n * teardown. `dispose()` invalidates any in-flight observer callback (`_gen++`)\n * and releases the observer. A later observe() revives it (the Shell calls this\n * from `disconnectedCallback`).\n */\n dispose(): void {\n this._gen++;\n this.disconnect();\n }\n\n // --- Internal ---\n\n private _teardownObserver(): void {\n if (this._observer) {\n this._observer.disconnect();\n this._observer = null;\n }\n this._observed = null;\n // Invalidate the torn-down observer's generation: its callback can still fire\n // once asynchronously after disconnect(), and must be dropped (§3.4).\n this._gen++;\n }\n\n private _createObserver(options: IntersectOptions): IntersectionObserver | null {\n if (typeof IntersectionObserver === \"undefined\") return null;\n // Capture the generation live at creation. The callback closure below guards\n // against deliveries from this observer after it has been superseded or\n // disposed (a stale callback fired off layout after teardown).\n const gen = this._gen;\n try {\n return new IntersectionObserver(\n (entries) => this._onIntersect(gen, entries),\n {\n root: options.root ?? null,\n rootMargin: options.rootMargin ?? \"0px\",\n threshold: options.threshold ?? 0,\n },\n );\n } catch {\n // Invalid options (e.g. a malformed rootMargin) — surface nothing and leave\n // observing false, rather than letting the constructor throw escape.\n return null;\n }\n }\n\n private _onIntersect(gen: number, entries: IntersectionObserverEntry[]): void {\n // Stale-generation guard (§3.4): drop callbacks from an observer that was torn\n // down or disposed (e.g. a delivery that landed after disconnect/reconnect).\n if (gen !== this._gen) return;\n for (const entry of entries) {\n const normalized = this._normalizeEntry(entry);\n this._setEntry(normalized);\n // Latch on the first (and any) intersecting observation; never auto-clears.\n if (normalized.isIntersecting) {\n this._setVisible(true);\n }\n }\n }\n\n private _normalizeEntry(entry: IntersectionObserverEntry): WcsIntersectEntry {\n return {\n isIntersecting: entry.isIntersecting,\n intersectionRatio: entry.intersectionRatio,\n time: entry.time,\n boundingClientRect: this._normalizeRect(entry.boundingClientRect),\n intersectionRect: this._normalizeRect(entry.intersectionRect),\n rootBounds: entry.rootBounds ? this._normalizeRect(entry.rootBounds) : null,\n target: entry.target,\n };\n }\n\n private _normalizeRect(rect: DOMRectReadOnly): WcsIntersectRect {\n return {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n left: rect.left,\n };\n }\n\n private _optionsEqual(a: IntersectOptions, b: IntersectOptions): boolean {\n if ((a.root ?? null) !== (b.root ?? null)) return false;\n if ((a.rootMargin ?? \"0px\") !== (b.rootMargin ?? \"0px\")) return false;\n return this._thresholdKey(a.threshold) === this._thresholdKey(b.threshold);\n }\n\n private _thresholdKey(threshold: number | number[] | undefined): string {\n if (threshold === undefined) return \"0\";\n return Array.isArray(threshold) ? threshold.join(\",\") : String(threshold);\n }\n}\n","import { IWcBindable, IntersectOptions, WcsIntersectEntry } from \"../types.js\";\nimport { IntersectionCore } from \"../core/IntersectionCore.js\";\n\n/**\n * `<wcs-intersect>` — declarative IntersectionObserver.\n *\n * The `target` attribute is the single knob that decides both *what* is observed\n * and how the element renders (it never injects a layout box unless asked):\n *\n * | `target` | observes | display | use case |\n * |-----------------|-----------------------|-------------|-------------------|\n * | omitted | first element child | `contents` | lazy-load wrapper |\n * | `\"#hero\"` / sel | the matched element | `none` | scrollspy (single)|\n * | `\"self\"` | the element itself | `block` | infinite-scroll |\n *\n * `display:contents` means wrapping a child injects no box of its own (so a\n * `<wcs-intersect><img></wcs-intersect>` does not disturb a flex/grid parent);\n * only the explicit `target=\"self\"` sentinel takes a box.\n */\nexport class WcsIntersect extends HTMLElement {\n // SSR (§4.4): the first observation is established synchronously on connect, but\n // the Shell still exposes connectedCallbackPromise so the state binder can await\n // it uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n // Only attributes that change *what or how* we observe trigger a re-observe.\n // `once` is intentionally excluded: it is evaluated at intersection fire time\n // (in `_onChange`), so toggling it takes effect without re-observing — and a\n // re-observe on its change would be a pure no-op (same target, same options).\n // `manual` is also excluded: it is a connect-time policy (\"don't auto-observe\n // on connect\"), not a live switch that should start/stop an active observation.\n static observedAttributes = [\"target\", \"root\", \"root-margin\", \"threshold\"];\n\n static wcBindable: IWcBindable = {\n ...IntersectionCore.wcBindable,\n properties: [\n ...IntersectionCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-intersect:trigger-changed\" },\n ],\n // Shell-level settable surface. Each input carries its mirrored `attribute`\n // hint; `trigger` has none — it is a momentary command-property, not a\n // declarative attribute. The observe / reobserve / unobserve / disconnect /\n // reset commands are inherited from the Core via the spread above.\n inputs: [\n { name: \"target\", attribute: \"target\" },\n { name: \"root\", attribute: \"root\" },\n { name: \"rootMargin\", attribute: \"root-margin\" },\n { name: \"threshold\", attribute: \"threshold\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n // Core の commands をそのまま継承(単一情報源)。<wcs-sse>/<wcs-broadcast> と同型。\n // spread でも継承されるが、Core に command 追加時の追従漏れを防ぐため明示参照する。\n commands: IntersectionCore.wcBindable.commands,\n };\n\n private _core: IntersectionCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new IntersectionCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-intersect:visible-changed\": (d) => ({ visible: d === true }),\n \"wcs-intersect:observing-changed\": (d) => ({ observing: d === true }),\n \"wcs-intersect:change\": (d) => ({ intersecting: d.isIntersecting === true }),\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 get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n get root(): string {\n return this.getAttribute(\"root\") ?? \"\";\n }\n\n set root(value: string) {\n this.setAttribute(\"root\", value);\n }\n\n get rootMargin(): string {\n const attr = this.getAttribute(\"root-margin\");\n return attr === null || attr.trim() === \"\" ? \"0px\" : attr;\n }\n\n set rootMargin(value: string) {\n this.setAttribute(\"root-margin\", value);\n }\n\n get threshold(): string {\n return this.getAttribute(\"threshold\") ?? \"\";\n }\n\n set threshold(value: string) {\n this.setAttribute(\"threshold\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean) {\n if (value) {\n this.setAttribute(\"once\", \"\");\n } else {\n this.removeAttribute(\"once\");\n }\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get entry(): WcsIntersectEntry | null {\n return this._core.entry;\n }\n\n get intersecting(): boolean {\n return this._core.intersecting;\n }\n\n get ratio(): number {\n return this._core.ratio;\n }\n\n get visible(): boolean {\n return this._core.visible;\n }\n\n get observing(): boolean {\n return this._core.observing;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write re-runs observe(). Mirrors\n // the trigger flag on <wcs-geo> / <wcs-ws> / <wcs-sse>. Prefer the command-token\n // protocol (`command.observe: $command.start`) for state-driven observation;\n // this exists mainly for simple boolean bindings.\n const v = !!value; // normalize truthy state-bindings, like <wcs-sse>'s setter\n if (v) {\n this._trigger = true;\n // try/finally mirrors <wcs-sse>'s set trigger: observe() is never-throw\n // today, but should a synchronous throw path ever appear, the finally still\n // auto-resets _trigger (no stuck-true latch) and emits the completion notice.\n try {\n this.observe();\n } finally {\n this._trigger = false;\n // Always auto-reset to false after the observe() attempt — this is the\n // *momentary acknowledgement* that the trigger was consumed, NOT a signal\n // that observation succeeded (whether the target resolved is reflected by\n // `observing`, not by this event). Firing unconditionally keeps the bound\n // state's trigger flag from sticking at true regardless of resolution.\n // Read `observing` if you need the actual outcome.\n this.dispatchEvent(new CustomEvent(\"wcs-intersect:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n }\n\n // --- Commands ---\n\n /** Re-resolve the target/root from the DOM and (re)start observing. */\n observe(): void {\n const { element, display } = this._resolveTarget();\n // `display` is derived from the `target` *mode* (self/selector/child), not from\n // whether the selector currently matches — so it is applied unconditionally,\n // before the resolution check. A `target=\"#x\"` whose node is momentarily absent\n // still renders `display:none` (it is a selector pointer, never a box).\n this.style.display = display;\n if (!element) {\n // The target is no longer resolvable (e.g. a `target` selector whose node\n // was removed from the DOM). Tear down any stale observation so `observing`\n // does not keep reporting true against a node that is gone.\n this._core.disconnect();\n return;\n }\n this._core.observe(element, this._options());\n }\n\n /**\n * Force a fresh observation: re-resolve target/root from the DOM and re-observe\n * even when nothing changed. Unlike observe() (idempotent for an unchanged\n * target+options), this rebuilds the observer so a new initial callback fires for\n * the current visibility — the way to re-arm an edge-driven consumer after the\n * layout shifted without a visibility transition (e.g. infinite scroll appended a\n * short page that left this sentinel in view). Resolution/teardown rules match\n * observe(): an unresolvable target tears down any stale observation.\n */\n reobserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n if (!element) {\n this._core.disconnect();\n return;\n }\n this._core.reobserve(element, this._options());\n }\n\n unobserve(): void {\n // Single-target Shell: \"stop observing my target\" is exactly the Core's\n // teardown. Delegate to the Core's tracked state rather than re-resolving the\n // selector, so a target that has since left the DOM can still be stopped\n // (re-resolving would yield null and silently leave the observer running).\n this._core.disconnect();\n }\n\n disconnect(): void {\n this._core.disconnect();\n }\n\n reset(): void {\n this._core.reset();\n }\n\n // --- Internal ---\n\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n // Explicit sentinel: observe the element itself as a (typically zero-height)\n // marker, which requires a layout box.\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n // Selector pointer: observe a referenced element in place, staying invisible.\n const scope = this.getRootNode() as Document | ShadowRoot;\n // A user-authored selector can be syntactically invalid (e.g. `#`, `:::`,\n // `[data-*`), which makes querySelector throw a SyntaxError. Swallow it and\n // treat the target as unresolvable — the same \"nothing to observe\" path as a\n // selector matching no element — so a bad attribute never lets the throw\n // escape observe() → connectedCallback / attributeChangedCallback (never-throw).\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n // Omitted: observe the first element child without injecting a box of our own.\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n // No child to wrap (e.g. used as an empty marker) — fall back to self.\n return { element: this, display: \"block\" };\n }\n\n private _resolveRoot(): Element | null {\n const root = this.root;\n if (root === \"\") return null;\n const scope = this.getRootNode() as Document | ShadowRoot;\n // Same never-throw guard as the target selector: an invalid `root` selector\n // falls back to a null root (the viewport) rather than throwing out of observe().\n return this._safeQuery(scope, root);\n }\n\n // Wrap querySelector so a syntactically invalid user-authored selector resolves\n // to null (unresolvable) instead of letting the SyntaxError escape — keeping the\n // sensor never-throw, mirroring worker/src/autoTrigger.ts's resolveText guard.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n\n private _parseThreshold(): number | number[] {\n const raw = this.threshold.trim();\n if (raw === \"\") return 0;\n // Strict parse via Number() (unlike parseFloat, \"0.5px\" -> NaN, not 0.5); drop\n // any non-finite or out-of-range [0,1] value, matching the README note.\n // Drop empty slots first (\"0,,1\" / \"1,\") — Number(\"\") is 0, which would\n // otherwise smuggle a spurious 0 threshold past the finite/range filter.\n const nums = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\")\n .map((s) => Number(s))\n .filter((n) => Number.isFinite(n) && n >= 0 && n <= 1);\n if (nums.length === 0) return 0;\n return nums.length === 1 ? nums[0] : nums;\n }\n\n private _options(): IntersectOptions {\n return {\n root: this._resolveRoot(),\n rootMargin: this.rootMargin,\n threshold: this._parseThreshold(),\n };\n }\n\n private _onChange = (event: Event): void => {\n // `wcs-intersect:change` bubbles, so a nested `<wcs-intersect>` descendant's\n // change would otherwise reach this (ancestor) listener and let a *child's*\n // intersection tear down *our* observer. Only act on our own Core's event.\n // (This also avoids reading `.detail` off a foreign event shape.)\n if (event.target !== this) return;\n // `once`: tear down after the first intersecting observation (lazy-load idiom).\n // Gated at fire time so toggling the `once` attribute takes effect live.\n if (this.once && (event as CustomEvent).detail.isIntersecting) {\n this._core.disconnect();\n }\n };\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.addEventListener(\"wcs-intersect:change\", this._onChange);\n if (!this.manual) {\n this.observe();\n }\n // SSR (§4.4): readiness is synchronous (observation is established above), but\n // expose the Core's ready promise as connectedCallbackPromise so the state\n // binder can await it uniformly. `manual` defers observation but readiness is\n // still immediate.\n this._connectedCallbackPromise = this._core.ready;\n }\n\n disconnectedCallback(): void {\n this.removeEventListener(\"wcs-intersect:change\", this._onChange);\n // dispose() tears down the observer AND bumps the Core's generation so any\n // IntersectionObserver callback still in flight is dropped (§3.4 / §4.1).\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n // Defensive same-value guard. Per spec attributeChangedCallback only fires on\n // an actual value change, so this is effectively a dead branch today — but\n // setAttribute() with an unchanged value (and some test/tooling paths) can\n // still invoke it, and re-observing on an unchanged attribute would be a\n // wasted observer rebuild. Kept intentionally; do not remove.\n if (oldValue === newValue) return;\n // Only react once connected and in automatic mode. The Core's idempotency\n // guard absorbs the autoloader upgrade case (attributeChangedCallback +\n // connectedCallback both calling observe() with identical options).\n if (!this.isConnected || this.manual) return;\n this.observe();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapIntersection(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsIntersect } from \"./components/Intersect.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.intersect)) {\n customElements.define(config.tagNames.intersect, WcsIntersect);\n }\n}\n"],"names":["_config","tagNames","intersect","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","IntersectionCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","isIntersecting","intersectionRatio","commands","_target","_observer","_observed","_options","_entry","_visible","_observing","_gen","_ready","Promise","resolve","constructor","target","super","this","ready","entry","intersecting","ratio","visible","observing","_setEntry","dispatchEvent","CustomEvent","bubbles","_setVisible","_setObserving","observe","element","options","_optionsEqual","_teardownObserver","observer","_createObserver","reobserve","unobserve","disconnect","reset","dispose","IntersectionObserver","gen","entries","_onIntersect","root","rootMargin","threshold","normalized","_normalizeEntry","time","boundingClientRect","_normalizeRect","intersectionRect","rootBounds","rect","x","y","width","height","top","right","bottom","left","a","b","_thresholdKey","undefined","Array","isArray","join","String","WcsIntersect","HTMLElement","wcBindable","inputs","attribute","_core","_trigger","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","add","delete","map","toStates","addEventListener","debug","hasAttribute","on","toggleAttribute","connectedCallbackPromise","getAttribute","value","setAttribute","attr","trim","once","removeAttribute","manual","trigger","display","_resolveTarget","style","scope","getRootNode","_safeQuery","child","firstElementChild","_resolveRoot","selector","querySelector","_parseThreshold","raw","nums","split","s","filter","Number","n","isFinite","length","_onChange","connectedCallback","disconnectedCallback","removeEventListener","attributeChangedCallback","_name","oldValue","newValue","isConnected","bootstrapIntersection","userConfig","partialConfig","assign","customElements","get","define"],"mappings":"AAQA,MAAMA,EAA2B,CAC/BC,SAAU,CACRC,UAAW,kBAIf,SAASC,EAAcC,GACrB,GAAY,OAARA,GAA+B,iBAARA,EAAkB,OAAOA,EACpDC,OAAOC,OAAOF,GACd,IAAK,MAAMG,KAAOF,OAAOG,KAAKJ,GAC5BD,EAAYC,EAAgCG,IAE9C,OAAOH,CACT,CAEA,SAASK,EAAaL,GACpB,GAAY,OAARA,GAA+B,iBAARA,EAAkB,OAAOA,EACpD,MAAMM,EAAiC,CAAA,EACvC,IAAK,MAAMH,KAAOF,OAAOG,KAAKJ,GAC5BM,EAAMH,GAAOE,EAAWL,EAAgCG,IAE1D,OAAOG,CACT,CAEA,IAAIC,EAA+B,KAE5B,MAAMC,EAAkBZ,WAEfa,IAId,OAHKF,IACHA,EAAeR,EAAWM,EAAUT,KAE/BW,CACT,CChBM,MAAOG,UAAyBC,YACpCC,kBAAiC,CAC/BC,SAAU,cACVC,QAAS,EACTC,WAAY,CACV,CAAEC,KAAM,QAASC,MAAO,wBACxB,CAAED,KAAM,eAAgBC,MAAO,uBAAwBC,OAASC,GAAcA,EAAkBC,OAAOC,gBACvG,CAAEL,KAAM,QAASC,MAAO,uBAAwBC,OAASC,GAAcA,EAAkBC,OAAOE,mBAChG,CAAEN,KAAM,UAAWC,MAAO,iCAC1B,CAAED,KAAM,YAAaC,MAAO,oCAE9BM,SAAU,CACR,CAAEP,KAAM,WACR,CAAEA,KAAM,aACR,CAAEA,KAAM,aACR,CAAEA,KAAM,cACR,CAAEA,KAAM,WAIJQ,QAKAC,UAAyC,KACzCC,UAA4B,KAC5BC,SAA6B,CAAA,EAE7BC,OAAmC,KACnCC,UAAoB,EACpBC,YAAsB,EAStBC,KAAO,EAIPC,OAAwBC,QAAQC,UAExC,WAAAC,CAAYC,GACVC,QACAC,KAAKd,QAAUY,GAAUE,IAC3B,CAGA,SAAIC,GACF,OAAOD,KAAKN,MACd,CAEA,SAAIQ,GACF,OAAOF,KAAKV,MACd,CAEA,gBAAIa,GACF,QAAOH,KAAKV,QAASU,KAAKV,OAAOP,cACnC,CAEA,SAAIqB,GACF,OAAOJ,KAAKV,OAASU,KAAKV,OAAON,kBAAoB,CACvD,CAEA,WAAIqB,GACF,OAAOL,KAAKT,QACd,CAEA,aAAIe,GACF,OAAON,KAAKR,UACd,CAIQ,SAAAe,CAAUL,GAIhBF,KAAKV,OAASY,EACdF,KAAKd,QAAQsB,cAAc,IAAIC,YAAY,uBAAwB,CACjE3B,OAAQoB,EACRQ,SAAS,IAEb,CAEQ,WAAAC,CAAYN,GACdL,KAAKT,WAAac,IACtBL,KAAKT,SAAWc,EAChBL,KAAKd,QAAQsB,cAAc,IAAIC,YAAY,gCAAiC,CAC1E3B,OAAQuB,EACRK,SAAS,KAEb,CAEQ,aAAAE,CAAcN,GAChBN,KAAKR,aAAec,IACxBN,KAAKR,WAAac,EAClBN,KAAKd,QAAQsB,cAAc,IAAIC,YAAY,kCAAmC,CAC5E3B,OAAQwB,EACRI,SAAS,KAEb,CAeA,OAAAG,CAAQC,EAAkBC,EAA4B,IACpD,GAAIf,KAAKb,WAAaa,KAAKZ,YAAc0B,GAAWd,KAAKgB,cAAchB,KAAKX,SAAU0B,GACpF,OAAOf,KAAKN,OAEdM,KAAKiB,oBACL,MAAMC,EAAWlB,KAAKmB,gBAAgBJ,GACtC,OAAKG,GASLlB,KAAKb,UAAY+B,EACjBlB,KAAKZ,UAAY0B,EACjBd,KAAKX,SAAW0B,EAChBG,EAASL,QAAQC,GACjBd,KAAKY,eAAc,GAGZZ,KAAKN,SAVVM,KAAKY,eAAc,GACZZ,KAAKN,OAUhB,CAiBA,SAAA0B,CAAUN,EAAkBC,EAA4B,IACtDf,KAAKiB,oBACLjB,KAAKa,QAAQC,EAASC,EACxB,CAOA,SAAAM,CAAUP,GACJd,KAAKZ,YAAc0B,IACvBd,KAAKiB,oBACLjB,KAAKY,eAAc,GACrB,CAGA,UAAAU,GACEtB,KAAKiB,oBACLjB,KAAKY,eAAc,EACrB,CAGA,KAAAW,GACEvB,KAAKW,aAAY,EACnB,CAWA,OAAAa,GACExB,KAAKP,OACLO,KAAKsB,YACP,CAIQ,iBAAAL,GACFjB,KAAKb,YACPa,KAAKb,UAAUmC,aACftB,KAAKb,UAAY,MAEnBa,KAAKZ,UAAY,KAGjBY,KAAKP,MACP,CAEQ,eAAA0B,CAAgBJ,GACtB,GAAoC,oBAAzBU,qBAAsC,OAAO,KAIxD,MAAMC,EAAM1B,KAAKP,KACjB,IACE,OAAO,IAAIgC,qBACRE,GAAY3B,KAAK4B,aAAaF,EAAKC,GACpC,CACEE,KAAMd,EAAQc,MAAQ,KACtBC,WAAYf,EAAQe,YAAc,MAClCC,UAAWhB,EAAQgB,WAAa,GAGtC,CAAE,MAGA,OAAO,IACT,CACF,CAEQ,YAAAH,CAAaF,EAAaC,GAGhC,GAAID,IAAQ1B,KAAKP,KACjB,IAAK,MAAMS,KAASyB,EAAS,CAC3B,MAAMK,EAAahC,KAAKiC,gBAAgB/B,GACxCF,KAAKO,UAAUyB,GAEXA,EAAWjD,gBACbiB,KAAKW,aAAY,EAErB,CACF,CAEQ,eAAAsB,CAAgB/B,GACtB,MAAO,CACLnB,eAAgBmB,EAAMnB,eACtBC,kBAAmBkB,EAAMlB,kBACzBkD,KAAMhC,EAAMgC,KACZC,mBAAoBnC,KAAKoC,eAAelC,EAAMiC,oBAC9CE,iBAAkBrC,KAAKoC,eAAelC,EAAMmC,kBAC5CC,WAAYpC,EAAMoC,WAAatC,KAAKoC,eAAelC,EAAMoC,YAAc,KACvExC,OAAQI,EAAMJ,OAElB,CAEQ,cAAAsC,CAAeG,GACrB,MAAO,CACLC,EAAGD,EAAKC,EACRC,EAAGF,EAAKE,EACRC,MAAOH,EAAKG,MACZC,OAAQJ,EAAKI,OACbC,IAAKL,EAAKK,IACVC,MAAON,EAAKM,MACZC,OAAQP,EAAKO,OACbC,KAAMR,EAAKQ,KAEf,CAEQ,aAAA/B,CAAcgC,EAAqBC,GACzC,OAAKD,EAAEnB,MAAQ,SAAWoB,EAAEpB,MAAQ,SAC/BmB,EAAElB,YAAc,UAAYmB,EAAEnB,YAAc,QAC1C9B,KAAKkD,cAAcF,EAAEjB,aAAe/B,KAAKkD,cAAcD,EAAElB,WAClE,CAEQ,aAAAmB,CAAcnB,GACpB,YAAkBoB,IAAdpB,EAAgC,IAC7BqB,MAAMC,QAAQtB,GAAaA,EAAUuB,KAAK,KAAOC,OAAOxB,EACjE,EClSI,MAAOyB,UAAqBC,YAIhCnF,oCAAqC,EAOrCA,0BAA4B,CAAC,SAAU,OAAQ,cAAe,aAE9DA,kBAAiC,IAC5BF,EAAiBsF,WACpBjF,WAAY,IACPL,EAAiBsF,WAAWjF,WAC/B,CAAEC,KAAM,UAAWC,MAAO,kCAM5BgF,OAAQ,CACN,CAAEjF,KAAM,SAAUkF,UAAW,UAC7B,CAAElF,KAAM,OAAQkF,UAAW,QAC3B,CAAElF,KAAM,aAAckF,UAAW,eACjC,CAAElF,KAAM,YAAakF,UAAW,aAChC,CAAElF,KAAM,OAAQkF,UAAW,QAC3B,CAAElF,KAAM,SAAUkF,UAAW,UAC7B,CAAElF,KAAM,YAIVO,SAAUb,EAAiBsF,WAAWzE,UAGhC4E,MACAC,UAAoB,EACpBC,0BAA2CpE,QAAQC,UACnDoE,WAAsC,KAE9C,WAAAnE,GACEE,QACAC,KAAK6D,MAAQ,IAAIzF,EAAiB4B,MAClCA,KAAKgE,WAAahE,KAAKiE,iBACvBjE,KAAKkE,YAAY,CACf,gCAAkCC,IAAC,CAAQ9D,SAAe,IAAN8D,IACpD,kCAAoCA,IAAC,CAAQ7D,WAAiB,IAAN6D,IACxD,uBAAyBA,KAAShE,cAAmC,IAArBgE,EAAEpF,kBAEtD,CAMA,eAAIqF,GACF,OAAOpE,KAAKgE,WAAa,IAAIhE,KAAKgE,WAAWK,QAAU,EACzD,CAEQ,cAAAJ,GAMN,IACE,GAAoC,mBAAzBjE,KAAKsE,gBAAgC,OAAO,KACvD,MAAMC,EAAYvE,KAAKsE,kBAGvB,OAFAC,EAAUF,OAAOG,IAAI,aACrBD,EAAUF,OAAOI,OAAO,aACjBF,CACT,CAAE,MACA,OAAO,IACT,CACF,CAEQ,WAAAL,CAAYQ,GAClB,GAAwB,OAApB1E,KAAKgE,WAAqB,OAC9B,MAAMK,EAASrE,KAAKgE,WAAWK,OAC/B,IAAK,MAAO1F,EAAOgG,KAAahH,OAAOgE,QAAQ+C,GAC7C1E,KAAK4E,iBAAiBjG,EAAQE,IAC5B,MAAMgG,EAAQ7E,KAAK8E,aAAa,gBAChC,IAAK,MAAOpG,EAAMqG,KAAOpH,OAAOgE,QAAQgD,EAAU9F,EAAkBC,SAAU,CAC5E,IACMiG,EAAMV,EAAOG,IAAI9F,GAAgB2F,EAAOI,OAAO/F,EACrD,CAAE,MAA0B,CACxBmG,GAAO7E,KAAKgF,gBAAgB,kBAAkBtG,IAAQqG,EAC5D,GAGN,CAEA,4BAAIE,GACF,OAAOjF,KAAK+D,yBACd,CAIA,UAAIjE,GACF,OAAOE,KAAKkF,aAAa,WAAa,EACxC,CAEA,UAAIpF,CAAOqF,GACTnF,KAAKoF,aAAa,SAAUD,EAC9B,CAEA,QAAItD,GACF,OAAO7B,KAAKkF,aAAa,SAAW,EACtC,CAEA,QAAIrD,CAAKsD,GACPnF,KAAKoF,aAAa,OAAQD,EAC5B,CAEA,cAAIrD,GACF,MAAMuD,EAAOrF,KAAKkF,aAAa,eAC/B,OAAgB,OAATG,GAAiC,KAAhBA,EAAKC,OAAgB,MAAQD,CACvD,CAEA,cAAIvD,CAAWqD,GACbnF,KAAKoF,aAAa,cAAeD,EACnC,CAEA,aAAIpD,GACF,OAAO/B,KAAKkF,aAAa,cAAgB,EAC3C,CAEA,aAAInD,CAAUoD,GACZnF,KAAKoF,aAAa,YAAaD,EACjC,CAEA,QAAII,GACF,OAAOvF,KAAK8E,aAAa,OAC3B,CAEA,QAAIS,CAAKJ,GACHA,EACFnF,KAAKoF,aAAa,OAAQ,IAE1BpF,KAAKwF,gBAAgB,OAEzB,CAEA,UAAIC,GACF,OAAOzF,KAAK8E,aAAa,SAC3B,CAEA,UAAIW,CAAON,GACLA,EACFnF,KAAKoF,aAAa,SAAU,IAE5BpF,KAAKwF,gBAAgB,SAEzB,CAIA,SAAItF,GACF,OAAOF,KAAK6D,MAAM3D,KACpB,CAEA,gBAAIC,GACF,OAAOH,KAAK6D,MAAM1D,YACpB,CAEA,SAAIC,GACF,OAAOJ,KAAK6D,MAAMzD,KACpB,CAEA,WAAIC,GACF,OAAOL,KAAK6D,MAAMxD,OACpB,CAEA,aAAIC,GACF,OAAON,KAAK6D,MAAMvD,SACpB,CAIA,WAAIoF,GACF,OAAO1F,KAAK8D,QACd,CAEA,WAAI4B,CAAQP,GAMV,KADYA,EACL,CACLnF,KAAK8D,UAAW,EAIhB,IACE9D,KAAKa,SACP,SACEb,KAAK8D,UAAW,EAOhB9D,KAAKQ,cAAc,IAAIC,YAAY,gCAAiC,CAClE3B,QAAQ,EACR4B,SAAS,IAEb,CACF,CACF,CAKA,OAAAG,GACE,MAAMC,QAAEA,EAAO6E,QAAEA,GAAY3F,KAAK4F,iBAKlC5F,KAAK6F,MAAMF,QAAUA,EAChB7E,EAOLd,KAAK6D,MAAMhD,QAAQC,EAASd,KAAKX,YAH/BW,KAAK6D,MAAMvC,YAIf,CAWA,SAAAF,GACE,MAAMN,QAAEA,EAAO6E,QAAEA,GAAY3F,KAAK4F,iBAClC5F,KAAK6F,MAAMF,QAAUA,EAChB7E,EAILd,KAAK6D,MAAMzC,UAAUN,EAASd,KAAKX,YAHjCW,KAAK6D,MAAMvC,YAIf,CAEA,SAAAD,GAKErB,KAAK6D,MAAMvC,YACb,CAEA,UAAAA,GACEtB,KAAK6D,MAAMvC,YACb,CAEA,KAAAC,GACEvB,KAAK6D,MAAMtC,OACb,CAIQ,cAAAqE,GACN,MAAM9F,EAASE,KAAKF,OACpB,GAAe,SAAXA,EAGF,MAAO,CAAEgB,QAASd,KAAM2F,QAAS,SAEnC,GAAe,KAAX7F,EAAe,CAEjB,MAAMgG,EAAQ9F,KAAK+F,cAMnB,MAAO,CAAEjF,QAASd,KAAKgG,WAAWF,EAAOhG,GAAS6F,QAAS,OAC7D,CAEA,MAAMM,EAAQjG,KAAKkG,kBACnB,OAAID,EACK,CAAEnF,QAASmF,EAAON,QAAS,YAG7B,CAAE7E,QAASd,KAAM2F,QAAS,QACnC,CAEQ,YAAAQ,GACN,MAAMtE,EAAO7B,KAAK6B,KAClB,GAAa,KAATA,EAAa,OAAO,KACxB,MAAMiE,EAAQ9F,KAAK+F,cAGnB,OAAO/F,KAAKgG,WAAWF,EAAOjE,EAChC,CAKQ,UAAAmE,CAAWF,EAA8BM,GAC/C,IACE,OAAON,EAAMO,cAAcD,EAC7B,CAAE,MACA,OAAO,IACT,CACF,CAEQ,eAAAE,GACN,MAAMC,EAAMvG,KAAK+B,UAAUuD,OAC3B,GAAY,KAARiB,EAAY,OAAO,EAKvB,MAAMC,EAAOD,EACVE,MAAM,KACN/B,IAAKgC,GAAMA,EAAEpB,QACbqB,OAAQD,GAAY,KAANA,GACdhC,IAAKgC,GAAME,OAAOF,IAClBC,OAAQE,GAAMD,OAAOE,SAASD,IAAMA,GAAK,GAAKA,GAAK,GACtD,OAAoB,IAAhBL,EAAKO,OAAqB,EACP,IAAhBP,EAAKO,OAAeP,EAAK,GAAKA,CACvC,CAEQ,QAAAnH,GACN,MAAO,CACLwC,KAAM7B,KAAKmG,eACXrE,WAAY9B,KAAK8B,WACjBC,UAAW/B,KAAKsG,kBAEpB,CAEQU,UAAarI,IAKfA,EAAMmB,SAAWE,MAGjBA,KAAKuF,MAAS5G,EAAsBG,OAAOC,gBAC7CiB,KAAK6D,MAAMvC,cAMf,iBAAA2F,GACEjH,KAAK4E,iBAAiB,uBAAwB5E,KAAKgH,WAC9ChH,KAAKyF,QACRzF,KAAKa,UAMPb,KAAK+D,0BAA4B/D,KAAK6D,MAAM5D,KAC9C,CAEA,oBAAAiH,GACElH,KAAKmH,oBAAoB,uBAAwBnH,KAAKgH,WAGtDhH,KAAK6D,MAAMrC,SACb,CAEA,wBAAA4F,CAAyBC,EAAeC,EAAyBC,GAM3DD,IAAaC,GAIZvH,KAAKwH,cAAexH,KAAKyF,QAC9BzF,KAAKa,SACP,ECnZI,SAAU4G,EAAsBC,GHuChC,IAAoBC,EGtCpBD,KHsCoBC,EGrCZD,GHsCMnK,UAChBI,OAAOiK,OAAOtK,EAAQC,SAAUoK,EAAcpK,UAEhDU,EAAe,MI3CV4J,eAAeC,IAAI5J,EAAOX,SAASC,YACtCqK,eAAeE,OAAO7J,EAAOX,SAASC,UAAWgG,EDIrD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/intersection",
3
- "version": "1.16.0",
3
+ "version": "1.18.0",
4
4
  "description": "Declarative IntersectionObserver component for Web Components. Framework-agnostic visibility primitive via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",