@wcstack/intersection 1.14.0 → 1.16.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
@@ -137,7 +137,8 @@ export default {
137
137
 
138
138
  | コマンド | 説明 |
139
139
  |---------------|-------------|
140
- | `observe()` | DOM から `target` / `root` を再解決し、観測を(再)開始する。 |
140
+ | `observe()` | DOM から `target` / `root` を再解決し、観測を(再)開始する。冪等: ターゲット + オプションが不変なら no-op(新しいコールバックは発火しない)。 |
141
+ | `reobserve()` | ターゲット / オプションが不変でも強制的に新規観測を行う — オブザーバを破棄して作り直すため、*現在の*可視状態に対して新しい初回コールバックが発火する。可視状態の遷移を伴わずレイアウトが変化した後(例: 無限スクロールで短いページが追加された)にエッジ駆動のコンシューマを再武装するのに使う。再武装成功中も `observing` は `true` のまま(誤った瞬断が起きない)。 |
141
142
  | `unobserve()` | 現在のターゲットの観測を停止する。 |
142
143
  | `disconnect()`| すべての観測を停止する。 |
143
144
  | `reset()` | `visible` ラッチをクリアし、後の交差が再びそれを設定できるようにする。 |
@@ -159,7 +160,7 @@ IntersectionCore.wcBindable = {
159
160
  { name: "observing", event: "wcs-intersect:observing-changed" },
160
161
  ],
161
162
  commands: [
162
- { name: "observe" }, { name: "unobserve" }, { name: "disconnect" }, { name: "reset" },
163
+ { name: "observe" }, { name: "reobserve" }, { name: "unobserve" }, { name: "disconnect" }, { name: "reset" },
163
164
  ],
164
165
  };
165
166
  ```
package/dist/index.d.ts CHANGED
@@ -1,15 +1,3 @@
1
- interface ITagNames {
2
- readonly intersect: string;
3
- }
4
- interface IWritableTagNames {
5
- intersect?: string;
6
- }
7
- interface IConfig {
8
- readonly tagNames: ITagNames;
9
- }
10
- interface IWritableConfig {
11
- tagNames?: IWritableTagNames;
12
- }
13
1
  interface IWcBindableProperty {
14
2
  readonly name: string;
15
3
  readonly event: string;
@@ -25,11 +13,25 @@ interface IWcBindableCommand {
25
13
  }
26
14
  interface IWcBindable {
27
15
  readonly protocol: "wc-bindable";
28
- readonly version: number;
29
- readonly properties: IWcBindableProperty[];
30
- readonly inputs?: IWcBindableInput[];
31
- readonly commands?: IWcBindableCommand[];
16
+ readonly version: 1;
17
+ readonly properties: readonly IWcBindableProperty[];
18
+ readonly inputs?: readonly IWcBindableInput[];
19
+ readonly commands?: readonly IWcBindableCommand[];
20
+ }
21
+
22
+ interface ITagNames {
23
+ readonly intersect: string;
24
+ }
25
+ interface IWritableTagNames {
26
+ intersect?: string;
32
27
  }
28
+ interface IConfig {
29
+ readonly tagNames: ITagNames;
30
+ }
31
+ interface IWritableConfig {
32
+ tagNames?: IWritableTagNames;
33
+ }
34
+
33
35
  /**
34
36
  * Plain snapshot of a `DOMRectReadOnly` (e.g. `boundingClientRect`,
35
37
  * `intersectionRect`, `rootBounds`). Unlike the live DOM rect, every field is a
@@ -75,7 +77,7 @@ interface IntersectOptions {
75
77
  }
76
78
  /**
77
79
  * Value types for IntersectionCore (headless) — the observable state properties.
78
- * Use with `bind()` from `@wc-bindable/core` for compile-time type checking.
80
+ * Use with `bind()` from `a wc-bindable binding core` for compile-time type checking.
79
81
  *
80
82
  * @example
81
83
  * ```typescript
@@ -123,7 +125,9 @@ interface WcsIntersectInputs {
123
125
  trigger: boolean;
124
126
  }
125
127
  interface WcsIntersectCoreCommands {
126
- observe(element: Element, options?: IntersectOptions): void;
128
+ observe(element: Element, options?: IntersectOptions): Promise<void>;
129
+ /** Force a fresh observation even when target+options are unchanged (rebuilds the observer). */
130
+ reobserve(element: Element, options?: IntersectOptions): void;
127
131
  unobserve(element: Element): void;
128
132
  disconnect(): void;
129
133
  /** Clear the `visible` latch so it can be set again by a later intersection. */
@@ -132,6 +136,8 @@ interface WcsIntersectCoreCommands {
132
136
  interface WcsIntersectCommands {
133
137
  /** Re-resolve the target/root from the DOM and (re)start observing. */
134
138
  observe(): void;
139
+ /** Re-resolve the target/root and force a fresh observation (rebuilds the observer). */
140
+ reobserve(): void;
135
141
  unobserve(): void;
136
142
  disconnect(): void;
137
143
  reset(): void;
@@ -173,7 +179,11 @@ declare class IntersectionCore extends EventTarget {
173
179
  private _entry;
174
180
  private _visible;
175
181
  private _observing;
182
+ private _gen;
183
+ private _ready;
176
184
  constructor(target?: EventTarget);
185
+ /** Resolves immediately — there is no asynchronous probe to await (§3.8). */
186
+ get ready(): Promise<void>;
177
187
  get entry(): WcsIntersectEntry | null;
178
188
  get intersecting(): boolean;
179
189
  get ratio(): number;
@@ -193,7 +203,7 @@ declare class IntersectionCore extends EventTarget {
193
203
  * no-op — `observing` stays false, consistent with the never-throw design of
194
204
  * the other @wcstack sensors.
195
205
  */
196
- observe(element: Element, options?: IntersectOptions): void;
206
+ observe(element: Element, options?: IntersectOptions): Promise<void>;
197
207
  /**
198
208
  * Force a fresh observation of `element`, even when it matches the currently
199
209
  * observed target+options. Unlike observe() — which is idempotent and
@@ -220,6 +230,14 @@ declare class IntersectionCore extends EventTarget {
220
230
  disconnect(): void;
221
231
  /** Clear the `visible` latch so a later intersection can set it again. */
222
232
  reset(): void;
233
+ /**
234
+ * `observe()` (the IntersectionObserver-style command above) establishes
235
+ * monitoring, so there is no separate idempotent monitoring entry point — only
236
+ * teardown. `dispose()` invalidates any in-flight observer callback (`_gen++`)
237
+ * and releases the observer. A later observe() revives it (the Shell calls this
238
+ * from `disconnectedCallback`).
239
+ */
240
+ dispose(): void;
223
241
  private _teardownObserver;
224
242
  private _createObserver;
225
243
  private _onIntersect;
@@ -251,7 +269,9 @@ declare class WcsIntersect extends HTMLElement {
251
269
  static wcBindable: IWcBindable;
252
270
  private _core;
253
271
  private _trigger;
272
+ private _connectedCallbackPromise;
254
273
  constructor();
274
+ get connectedCallbackPromise(): Promise<void>;
255
275
  get target(): string;
256
276
  set target(value: string);
257
277
  get root(): string;
package/dist/index.esm.js CHANGED
@@ -88,10 +88,25 @@ class IntersectionCore extends EventTarget {
88
88
  _entry = null;
89
89
  _visible = false;
90
90
  _observing = false;
91
+ // Generation guard (§3.4): bumped on dispose() and on each observe()/reobserve()
92
+ // teardown+rebuild. IntersectionObserver delivers its callback asynchronously off
93
+ // layout, so a callback can fire after the element is disposed or after a rapid
94
+ // disconnect→reconnect rebuilt the observer. Each observer captures the gen live at
95
+ // creation; a callback from a superseded/torn-down observer has a stale gen and
96
+ // MUST NOT write state to a torn-down element. A boolean flag is insufficient
97
+ // (dispose→observe would flip it back and let stale work slip through).
98
+ _gen = 0;
99
+ // SSR (§3.8): IntersectionObserver setup is synchronous (no async probe to await),
100
+ // so readiness is immediate.
101
+ _ready = Promise.resolve();
91
102
  constructor(target) {
92
103
  super();
93
104
  this._target = target ?? this;
94
105
  }
106
+ /** Resolves immediately — there is no asynchronous probe to await (§3.8). */
107
+ get ready() {
108
+ return this._ready;
109
+ }
95
110
  get entry() {
96
111
  return this._entry;
97
112
  }
@@ -150,7 +165,7 @@ class IntersectionCore extends EventTarget {
150
165
  */
151
166
  observe(element, options = {}) {
152
167
  if (this._observer && this._observed === element && this._optionsEqual(this._options, options)) {
153
- return;
168
+ return this._ready;
154
169
  }
155
170
  this._teardownObserver();
156
171
  const observer = this._createObserver(options);
@@ -161,13 +176,16 @@ class IntersectionCore extends EventTarget {
161
176
  // keep reporting true with no live observer behind it (e.g. re-observing an
162
177
  // active target with a newly-invalid rootMargin).
163
178
  this._setObserving(false);
164
- return;
179
+ return this._ready;
165
180
  }
166
181
  this._observer = observer;
167
182
  this._observed = element;
168
183
  this._options = options;
169
184
  observer.observe(element);
170
185
  this._setObserving(true);
186
+ // SSR (§3.5): observe() returns the readiness promise. Observation establishment
187
+ // is synchronous, so this resolves immediately.
188
+ return this._ready;
171
189
  }
172
190
  /**
173
191
  * Force a fresh observation of `element`, even when it matches the currently
@@ -208,6 +226,18 @@ class IntersectionCore extends EventTarget {
208
226
  reset() {
209
227
  this._setVisible(false);
210
228
  }
229
+ // --- Lifecycle (§3.5) ---
230
+ /**
231
+ * `observe()` (the IntersectionObserver-style command above) establishes
232
+ * monitoring, so there is no separate idempotent monitoring entry point — only
233
+ * teardown. `dispose()` invalidates any in-flight observer callback (`_gen++`)
234
+ * and releases the observer. A later observe() revives it (the Shell calls this
235
+ * from `disconnectedCallback`).
236
+ */
237
+ dispose() {
238
+ this._gen++;
239
+ this.disconnect();
240
+ }
211
241
  // --- Internal ---
212
242
  _teardownObserver() {
213
243
  if (this._observer) {
@@ -215,12 +245,19 @@ class IntersectionCore extends EventTarget {
215
245
  this._observer = null;
216
246
  }
217
247
  this._observed = null;
248
+ // Invalidate the torn-down observer's generation: its callback can still fire
249
+ // once asynchronously after disconnect(), and must be dropped (§3.4).
250
+ this._gen++;
218
251
  }
219
252
  _createObserver(options) {
220
253
  if (typeof IntersectionObserver === "undefined")
221
254
  return null;
255
+ // Capture the generation live at creation. The callback closure below guards
256
+ // against deliveries from this observer after it has been superseded or
257
+ // disposed (a stale callback fired off layout after teardown).
258
+ const gen = this._gen;
222
259
  try {
223
- return new IntersectionObserver(this._onIntersect, {
260
+ return new IntersectionObserver((entries) => this._onIntersect(gen, entries), {
224
261
  root: options.root ?? null,
225
262
  rootMargin: options.rootMargin ?? "0px",
226
263
  threshold: options.threshold ?? 0,
@@ -232,7 +269,11 @@ class IntersectionCore extends EventTarget {
232
269
  return null;
233
270
  }
234
271
  }
235
- _onIntersect = (entries) => {
272
+ _onIntersect(gen, entries) {
273
+ // Stale-generation guard (§3.4): drop callbacks from an observer that was torn
274
+ // down or disposed (e.g. a delivery that landed after disconnect/reconnect).
275
+ if (gen !== this._gen)
276
+ return;
236
277
  for (const entry of entries) {
237
278
  const normalized = this._normalizeEntry(entry);
238
279
  this._setEntry(normalized);
@@ -241,7 +282,7 @@ class IntersectionCore extends EventTarget {
241
282
  this._setVisible(true);
242
283
  }
243
284
  }
244
- };
285
+ }
245
286
  _normalizeEntry(entry) {
246
287
  return {
247
288
  isIntersecting: entry.isIntersecting,
@@ -296,7 +337,10 @@ class IntersectionCore extends EventTarget {
296
337
  * only the explicit `target="self"` sentinel takes a box.
297
338
  */
298
339
  class WcsIntersect extends HTMLElement {
299
- static hasConnectedCallbackPromise = false;
340
+ // SSR (§4.4): the first observation is established synchronously on connect, but
341
+ // the Shell still exposes connectedCallbackPromise so the state binder can await
342
+ // it uniformly across all IO nodes before snapshotting.
343
+ static hasConnectedCallbackPromise = true;
300
344
  // Only attributes that change *what or how* we observe trigger a re-observe.
301
345
  // `once` is intentionally excluded: it is evaluated at intersection fire time
302
346
  // (in `_onChange`), so toggling it takes effect without re-observing — and a
@@ -329,10 +373,14 @@ class WcsIntersect extends HTMLElement {
329
373
  };
330
374
  _core;
331
375
  _trigger = false;
376
+ _connectedCallbackPromise = Promise.resolve();
332
377
  constructor() {
333
378
  super();
334
379
  this._core = new IntersectionCore(this);
335
380
  }
381
+ get connectedCallbackPromise() {
382
+ return this._connectedCallbackPromise;
383
+ }
336
384
  // --- Attribute accessors ---
337
385
  get target() {
338
386
  return this.getAttribute("target") ?? "";
@@ -569,10 +617,17 @@ class WcsIntersect extends HTMLElement {
569
617
  if (!this.manual) {
570
618
  this.observe();
571
619
  }
620
+ // SSR (§4.4): readiness is synchronous (observation is established above), but
621
+ // expose the Core's ready promise as connectedCallbackPromise so the state
622
+ // binder can await it uniformly. `manual` defers observation but readiness is
623
+ // still immediate.
624
+ this._connectedCallbackPromise = this._core.ready;
572
625
  }
573
626
  disconnectedCallback() {
574
627
  this.removeEventListener("wcs-intersect:change", this._onChange);
575
- this._core.disconnect();
628
+ // dispose() tears down the observer AND bumps the Core's generation so any
629
+ // IntersectionObserver callback still in flight is dropped (§3.4 / §4.1).
630
+ this._core.dispose();
576
631
  }
577
632
  attributeChangedCallback(_name, oldValue, newValue) {
578
633
  // Defensive same-value guard. Per spec attributeChangedCallback only fires on
@@ -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 constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\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 = {}): void {\n if (this._observer && this._observed === element && this._optionsEqual(this._options, options)) {\n return;\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;\n }\n this._observer = observer;\n this._observed = element;\n this._options = options;\n observer.observe(element);\n this._setObserving(true);\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 // --- Internal ---\n\n private _teardownObserver(): void {\n if (this._observer) {\n this._observer.disconnect();\n this._observer = null;\n }\n this._observed = null;\n }\n\n private _createObserver(options: IntersectOptions): IntersectionObserver | null {\n if (typeof IntersectionObserver === \"undefined\") return null;\n try {\n return new IntersectionObserver(this._onIntersect, {\n root: options.root ?? null,\n rootMargin: options.rootMargin ?? \"0px\",\n threshold: options.threshold ?? 0,\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 = (entries: IntersectionObserverEntry[]): void => {\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 static hasConnectedCallbackPromise = false;\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\n constructor() {\n super();\n this._core = new IntersectionCore(this);\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 }\n\n disconnectedCallback(): void {\n this.removeEventListener(\"wcs-intersect:change\", this._onChange);\n this._core.disconnect();\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\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,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;constructor(t){super(),this._target=t??this}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._teardownObserver();const r=this._createObserver(e);r?(this._observer=r,this._observed=t,this._options=e,r.observe(t),this._setObserving(!0)):this._setObserving(!1)}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)}_teardownObserver(){this._observer&&(this._observer.disconnect(),this._observer=null),this._observed=null}_createObserver(t){if("undefined"==typeof IntersectionObserver)return null;try{return new IntersectionObserver(this._onIntersect,{root:t.root??null,rootMargin:t.rootMargin??"0px",threshold:t.threshold??0})}catch{return null}}_onIntersect=t=>{for(const e of t){const t=this._normalizeEntry(e);this._setEntry(t),t.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=!1;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;constructor(){super(),this._core=new o(this)}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()}disconnectedCallback(){this.removeEventListener("wcs-intersect:change",this._onChange),this._core.disconnect()}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 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};
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 constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\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 = {}): void {\n if (this._observer && this._observed === element && this._optionsEqual(this._options, options)) {\n return;\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;\n }\n this._observer = observer;\n this._observed = element;\n this._options = options;\n observer.observe(element);\n this._setObserving(true);\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 // --- Internal ---\n\n private _teardownObserver(): void {\n if (this._observer) {\n this._observer.disconnect();\n this._observer = null;\n }\n this._observed = null;\n }\n\n private _createObserver(options: IntersectOptions): IntersectionObserver | null {\n if (typeof IntersectionObserver === \"undefined\") return null;\n try {\n return new IntersectionObserver(this._onIntersect, {\n root: options.root ?? null,\n rootMargin: options.rootMargin ?? \"0px\",\n threshold: options.threshold ?? 0,\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 = (entries: IntersectionObserverEntry[]): void => {\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 static hasConnectedCallbackPromise = false;\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\n constructor() {\n super();\n this._core = new IntersectionCore(this);\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 }\n\n disconnectedCallback(): void {\n this.removeEventListener(\"wcs-intersect:change\", this._onChange);\n this._core.disconnect();\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","constructor","target","super","this","entry","intersecting","ratio","visible","observing","_setEntry","dispatchEvent","CustomEvent","bubbles","_setVisible","_setObserving","observe","element","options","_optionsEqual","_teardownObserver","observer","_createObserver","reobserve","unobserve","disconnect","reset","IntersectionObserver","_onIntersect","root","rootMargin","threshold","entries","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","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\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":"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,UAE3D,WAAAC,GACEE,QACAC,KAAK6D,MAAQ,IAAIzF,EAAiB4B,KACpC,CAEA,4BAAIgE,GACF,OAAOhE,KAAK+D,yBACd,CAIA,UAAIjE,GACF,OAAOE,KAAKiE,aAAa,WAAa,EACxC,CAEA,UAAInE,CAAOoE,GACTlE,KAAKmE,aAAa,SAAUD,EAC9B,CAEA,QAAIrC,GACF,OAAO7B,KAAKiE,aAAa,SAAW,EACtC,CAEA,QAAIpC,CAAKqC,GACPlE,KAAKmE,aAAa,OAAQD,EAC5B,CAEA,cAAIpC,GACF,MAAMsC,EAAOpE,KAAKiE,aAAa,eAC/B,OAAgB,OAATG,GAAiC,KAAhBA,EAAKC,OAAgB,MAAQD,CACvD,CAEA,cAAItC,CAAWoC,GACblE,KAAKmE,aAAa,cAAeD,EACnC,CAEA,aAAInC,GACF,OAAO/B,KAAKiE,aAAa,cAAgB,EAC3C,CAEA,aAAIlC,CAAUmC,GACZlE,KAAKmE,aAAa,YAAaD,EACjC,CAEA,QAAII,GACF,OAAOtE,KAAKuE,aAAa,OAC3B,CAEA,QAAID,CAAKJ,GACHA,EACFlE,KAAKmE,aAAa,OAAQ,IAE1BnE,KAAKwE,gBAAgB,OAEzB,CAEA,UAAIC,GACF,OAAOzE,KAAKuE,aAAa,SAC3B,CAEA,UAAIE,CAAOP,GACLA,EACFlE,KAAKmE,aAAa,SAAU,IAE5BnE,KAAKwE,gBAAgB,SAEzB,CAIA,SAAItE,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,WAAIoE,GACF,OAAO1E,KAAK8D,QACd,CAEA,WAAIY,CAAQR,GAMV,KADYA,EACL,CACLlE,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,EAAO6D,QAAEA,GAAY3E,KAAK4E,iBAKlC5E,KAAK6E,MAAMF,QAAUA,EAChB7D,EAOLd,KAAK6D,MAAMhD,QAAQC,EAASd,KAAKX,YAH/BW,KAAK6D,MAAMvC,YAIf,CAWA,SAAAF,GACE,MAAMN,QAAEA,EAAO6D,QAAEA,GAAY3E,KAAK4E,iBAClC5E,KAAK6E,MAAMF,QAAUA,EAChB7D,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,cAAAqD,GACN,MAAM9E,EAASE,KAAKF,OACpB,GAAe,SAAXA,EAGF,MAAO,CAAEgB,QAASd,KAAM2E,QAAS,SAEnC,GAAe,KAAX7E,EAAe,CAEjB,MAAMgF,EAAQ9E,KAAK+E,cAMnB,MAAO,CAAEjE,QAASd,KAAKgF,WAAWF,EAAOhF,GAAS6E,QAAS,OAC7D,CAEA,MAAMM,EAAQjF,KAAKkF,kBACnB,OAAID,EACK,CAAEnE,QAASmE,EAAON,QAAS,YAG7B,CAAE7D,QAASd,KAAM2E,QAAS,QACnC,CAEQ,YAAAQ,GACN,MAAMtD,EAAO7B,KAAK6B,KAClB,GAAa,KAATA,EAAa,OAAO,KACxB,MAAMiD,EAAQ9E,KAAK+E,cAGnB,OAAO/E,KAAKgF,WAAWF,EAAOjD,EAChC,CAKQ,UAAAmD,CAAWF,EAA8BM,GAC/C,IACE,OAAON,EAAMO,cAAcD,EAC7B,CAAE,MACA,OAAO,IACT,CACF,CAEQ,eAAAE,GACN,MAAMC,EAAMvF,KAAK+B,UAAUsC,OAC3B,GAAY,KAARkB,EAAY,OAAO,EAKvB,MAAMC,EAAOD,EACVE,MAAM,KACNC,IAAKC,GAAMA,EAAEtB,QACbuB,OAAQD,GAAY,KAANA,GACdD,IAAKC,GAAME,OAAOF,IAClBC,OAAQE,GAAMD,OAAOE,SAASD,IAAMA,GAAK,GAAKA,GAAK,GACtD,OAAoB,IAAhBN,EAAKQ,OAAqB,EACP,IAAhBR,EAAKQ,OAAeR,EAAK,GAAKA,CACvC,CAEQ,QAAAnG,GACN,MAAO,CACLwC,KAAM7B,KAAKmF,eACXrD,WAAY9B,KAAK8B,WACjBC,UAAW/B,KAAKsF,kBAEpB,CAEQW,UAAatH,IAKfA,EAAMmB,SAAWE,MAGjBA,KAAKsE,MAAS3F,EAAsBG,OAAOC,gBAC7CiB,KAAK6D,MAAMvC,cAMf,iBAAA4E,GACElG,KAAKmG,iBAAiB,uBAAwBnG,KAAKiG,WAC9CjG,KAAKyE,QACRzE,KAAKa,UAMPb,KAAK+D,0BAA4B/D,KAAK6D,MAAM5D,KAC9C,CAEA,oBAAAmG,GACEpG,KAAKqG,oBAAoB,uBAAwBrG,KAAKiG,WAGtDjG,KAAK6D,MAAMrC,SACb,CAEA,wBAAA8E,CAAyBC,EAAeC,EAAyBC,GAM3DD,IAAaC,GAIZzG,KAAK0G,cAAe1G,KAAKyE,QAC9BzE,KAAKa,SACP,ECnWI,SAAU8F,EAAsBC,GHuChC,IAAoBC,EGtCpBD,KHsCoBC,EGrCZD,GHsCMrJ,UAChBI,OAAOmJ,OAAOxJ,EAAQC,SAAUsJ,EAActJ,UAEhDU,EAAe,MI3CV8I,eAAeC,IAAI9I,EAAOX,SAASC,YACtCuJ,eAAeE,OAAO/I,EAAOX,SAASC,UAAWgG,EDIrD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/intersection",
3
- "version": "1.14.0",
3
+ "version": "1.16.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",