@wcstack/debounce 1.14.0 → 1.15.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/dist/index.d.ts +32 -21
- package/dist/index.esm.js +54 -7
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
interface IWcBindableProperty {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly event: string;
|
|
4
|
+
readonly getter?: (event: Event) => any;
|
|
5
|
+
}
|
|
6
|
+
interface IWcBindableInput {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly attribute?: string;
|
|
9
|
+
}
|
|
10
|
+
interface IWcBindableCommand {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly async?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface IWcBindable {
|
|
15
|
+
readonly protocol: "wc-bindable";
|
|
16
|
+
readonly version: 1;
|
|
17
|
+
readonly properties: readonly IWcBindableProperty[];
|
|
18
|
+
readonly inputs?: readonly IWcBindableInput[];
|
|
19
|
+
readonly commands?: readonly IWcBindableCommand[];
|
|
20
|
+
}
|
|
21
|
+
|
|
1
22
|
interface ITagNames {
|
|
2
23
|
readonly debounce: string;
|
|
3
24
|
readonly throttle: string;
|
|
@@ -16,26 +37,7 @@ interface IWritableConfig {
|
|
|
16
37
|
triggerAttribute?: string;
|
|
17
38
|
tagNames?: IWritableTagNames;
|
|
18
39
|
}
|
|
19
|
-
|
|
20
|
-
readonly name: string;
|
|
21
|
-
readonly event: string;
|
|
22
|
-
readonly getter?: (event: Event) => any;
|
|
23
|
-
}
|
|
24
|
-
interface IWcBindableInput {
|
|
25
|
-
readonly name: string;
|
|
26
|
-
readonly attribute?: string;
|
|
27
|
-
}
|
|
28
|
-
interface IWcBindableCommand {
|
|
29
|
-
readonly name: string;
|
|
30
|
-
readonly async?: boolean;
|
|
31
|
-
}
|
|
32
|
-
interface IWcBindable {
|
|
33
|
-
readonly protocol: "wc-bindable";
|
|
34
|
-
readonly version: number;
|
|
35
|
-
readonly properties: IWcBindableProperty[];
|
|
36
|
-
readonly inputs?: IWcBindableInput[];
|
|
37
|
-
readonly commands?: IWcBindableCommand[];
|
|
38
|
-
}
|
|
40
|
+
|
|
39
41
|
/**
|
|
40
42
|
* Tuning options for {@link DebounceCore}. Mirrors lodash's `debounce` knobs.
|
|
41
43
|
* - `wait`: quiet period (ms) the signal must be idle before a trailing fire.
|
|
@@ -66,7 +68,7 @@ interface WcsDebounceFiredDetail {
|
|
|
66
68
|
}
|
|
67
69
|
/**
|
|
68
70
|
* Value types for DebounceCore (headless) — the observable state properties.
|
|
69
|
-
* Use with `bind()` from
|
|
71
|
+
* Use with `bind()` from `a wc-bindable binding core` for compile-time type checking.
|
|
70
72
|
*/
|
|
71
73
|
interface WcsDebounceCoreValues {
|
|
72
74
|
value: any;
|
|
@@ -132,13 +134,19 @@ declare class DebounceCore extends EventTarget {
|
|
|
132
134
|
private _lastCallTime;
|
|
133
135
|
private _lastInvokeTime;
|
|
134
136
|
private _timerId;
|
|
137
|
+
private _timerGen;
|
|
135
138
|
private _pendingKind;
|
|
136
139
|
private _pendingValue;
|
|
137
140
|
private _pendingArgs;
|
|
138
141
|
private _value;
|
|
139
142
|
private _lastArgs;
|
|
140
143
|
private _pending;
|
|
144
|
+
private _gen;
|
|
145
|
+
private _ready;
|
|
141
146
|
constructor(prefix?: string, target?: EventTarget, options?: DebounceOptions);
|
|
147
|
+
get ready(): Promise<void>;
|
|
148
|
+
observe(): Promise<void>;
|
|
149
|
+
dispose(): void;
|
|
142
150
|
/**
|
|
143
151
|
* Update the tuning knobs. The Shell calls this with the element's current
|
|
144
152
|
* attributes before each schedule, so live attribute edits take effect on the
|
|
@@ -170,6 +178,7 @@ declare class DebounceCore extends EventTarget {
|
|
|
170
178
|
private _invoke;
|
|
171
179
|
private _setPending;
|
|
172
180
|
private _dispatch;
|
|
181
|
+
private _armTimer;
|
|
173
182
|
private _clearTimer;
|
|
174
183
|
}
|
|
175
184
|
|
|
@@ -202,7 +211,9 @@ declare class Debounce extends HTMLElement {
|
|
|
202
211
|
static wcBindable: IWcBindable;
|
|
203
212
|
protected _core: DebounceCore;
|
|
204
213
|
private _source;
|
|
214
|
+
private _connectedCallbackPromise;
|
|
205
215
|
constructor();
|
|
216
|
+
get connectedCallbackPromise(): Promise<void>;
|
|
206
217
|
get wait(): number;
|
|
207
218
|
set wait(value: number);
|
|
208
219
|
get leading(): boolean;
|
package/dist/index.esm.js
CHANGED
|
@@ -122,6 +122,9 @@ class DebounceCore extends EventTarget {
|
|
|
122
122
|
_lastCallTime = undefined;
|
|
123
123
|
_lastInvokeTime = 0;
|
|
124
124
|
_timerId = null;
|
|
125
|
+
// Generation stamped onto the live timer at arm time, compared in
|
|
126
|
+
// `_timerExpired` against `_gen` to drop callbacks that outlived a dispose().
|
|
127
|
+
_timerGen = 0;
|
|
125
128
|
// Last-wins pending payload. `_pendingKind === null` doubles as the "consumed /
|
|
126
129
|
// empty" sentinel (lodash clears `lastArgs` in invokeFunc): a trailing edge with
|
|
127
130
|
// no fresh call since the last fire sees `null` and does not re-fire, which is
|
|
@@ -133,6 +136,15 @@ class DebounceCore extends EventTarget {
|
|
|
133
136
|
_value = undefined;
|
|
134
137
|
_lastArgs = [];
|
|
135
138
|
_pending = false;
|
|
139
|
+
// Generation guard (§3.4): bumped on dispose() so a timer that survives a
|
|
140
|
+
// tear-down can no longer settle into a detached element. A pending timer is
|
|
141
|
+
// also cleared by dispose() → cancel(), so the guard is defensive: it stops
|
|
142
|
+
// any callback that has already been dequeued by the host event loop from
|
|
143
|
+
// writing state after dispose().
|
|
144
|
+
_gen = 0;
|
|
145
|
+
// SSR (§3.8): the debounce engine is purely timer-driven with no asynchronous
|
|
146
|
+
// probe to await, so readiness is immediate.
|
|
147
|
+
_ready = Promise.resolve();
|
|
136
148
|
constructor(prefix = "wcs-debounce", target, options) {
|
|
137
149
|
super();
|
|
138
150
|
this._prefix = prefix;
|
|
@@ -141,6 +153,22 @@ class DebounceCore extends EventTarget {
|
|
|
141
153
|
this.configure(options);
|
|
142
154
|
}
|
|
143
155
|
}
|
|
156
|
+
// --- Lifecycle (§3.5 / §3.8) ---
|
|
157
|
+
get ready() {
|
|
158
|
+
return this._ready;
|
|
159
|
+
}
|
|
160
|
+
// Debounce is command-driven (setSource / trigger schedule work on demand)
|
|
161
|
+
// with no subscription to establish, so observe() is an idempotent no-op that
|
|
162
|
+
// resolves once ready.
|
|
163
|
+
observe() {
|
|
164
|
+
return this._ready;
|
|
165
|
+
}
|
|
166
|
+
// Tear down the pending timer and invalidate the generation so a stale timer
|
|
167
|
+
// callback cannot fire after the element is detached.
|
|
168
|
+
dispose() {
|
|
169
|
+
this._gen++;
|
|
170
|
+
this.cancel();
|
|
171
|
+
}
|
|
144
172
|
// --- Configuration ---
|
|
145
173
|
/**
|
|
146
174
|
* Update the tuning knobs. The Shell calls this with the element's current
|
|
@@ -240,13 +268,13 @@ class DebounceCore extends EventTarget {
|
|
|
240
268
|
// same) — overwriting `_timerId` without clearing would orphan the old
|
|
241
269
|
// timer and let it fire spuriously later.
|
|
242
270
|
this._clearTimer();
|
|
243
|
-
this.
|
|
271
|
+
this._armTimer(this._wait);
|
|
244
272
|
this._invoke(now);
|
|
245
273
|
return;
|
|
246
274
|
}
|
|
247
275
|
}
|
|
248
276
|
if (this._timerId === null) {
|
|
249
|
-
this.
|
|
277
|
+
this._armTimer(this._wait);
|
|
250
278
|
}
|
|
251
279
|
}
|
|
252
280
|
_shouldInvoke(now) {
|
|
@@ -267,6 +295,11 @@ class DebounceCore extends EventTarget {
|
|
|
267
295
|
: timeWaiting;
|
|
268
296
|
}
|
|
269
297
|
_timerExpired = () => {
|
|
298
|
+
// §3.4 generation guard: a timer dequeued by the host before dispose() could
|
|
299
|
+
// clear it must not settle into a torn-down element. Capture the generation
|
|
300
|
+
// when the timer is scheduled (via `_armTimer`) and bail if it is stale.
|
|
301
|
+
if (this._timerGen !== this._gen)
|
|
302
|
+
return;
|
|
270
303
|
const now = Date.now();
|
|
271
304
|
if (this._shouldInvoke(now)) {
|
|
272
305
|
this._trailingEdge(now);
|
|
@@ -274,11 +307,11 @@ class DebounceCore extends EventTarget {
|
|
|
274
307
|
}
|
|
275
308
|
// Fired before the quiet period elapsed (a later call moved the deadline) —
|
|
276
309
|
// re-arm for the remaining time instead of settling now.
|
|
277
|
-
this.
|
|
310
|
+
this._armTimer(this._remainingWait(now));
|
|
278
311
|
};
|
|
279
312
|
_leadingEdge(now) {
|
|
280
313
|
this._lastInvokeTime = now;
|
|
281
|
-
this.
|
|
314
|
+
this._armTimer(this._wait);
|
|
282
315
|
if (this._leading) {
|
|
283
316
|
this._invoke(now);
|
|
284
317
|
}
|
|
@@ -319,6 +352,12 @@ class DebounceCore extends EventTarget {
|
|
|
319
352
|
_dispatch(type, detail) {
|
|
320
353
|
this._target.dispatchEvent(new CustomEvent(type, { detail, bubbles: true }));
|
|
321
354
|
}
|
|
355
|
+
// Arm the settle timer, stamping the current generation so a callback that the
|
|
356
|
+
// host dequeues after a dispose() can detect it is stale (§3.4).
|
|
357
|
+
_armTimer(delay) {
|
|
358
|
+
this._timerGen = this._gen;
|
|
359
|
+
this._timerId = setTimeout(this._timerExpired, delay);
|
|
360
|
+
}
|
|
322
361
|
_clearTimer() {
|
|
323
362
|
if (this._timerId !== null) {
|
|
324
363
|
clearTimeout(this._timerId);
|
|
@@ -369,7 +408,7 @@ const DEFAULT_WAIT = 250;
|
|
|
369
408
|
* subclasses this with `"wcs-throttle"` and throttle defaults.
|
|
370
409
|
*/
|
|
371
410
|
class Debounce extends HTMLElement {
|
|
372
|
-
static hasConnectedCallbackPromise =
|
|
411
|
+
static hasConnectedCallbackPromise = true;
|
|
373
412
|
static eventPrefix = "wcs-debounce";
|
|
374
413
|
static wcBindable = {
|
|
375
414
|
protocol: "wc-bindable",
|
|
@@ -396,10 +435,14 @@ class Debounce extends HTMLElement {
|
|
|
396
435
|
};
|
|
397
436
|
_core;
|
|
398
437
|
_source = undefined;
|
|
438
|
+
_connectedCallbackPromise = Promise.resolve();
|
|
399
439
|
constructor() {
|
|
400
440
|
super();
|
|
401
441
|
this._core = new DebounceCore(this.constructor.eventPrefix, this);
|
|
402
442
|
}
|
|
443
|
+
get connectedCallbackPromise() {
|
|
444
|
+
return this._connectedCallbackPromise;
|
|
445
|
+
}
|
|
403
446
|
// --- Attribute accessors ---
|
|
404
447
|
get wait() {
|
|
405
448
|
const attr = this.getAttribute("wait");
|
|
@@ -508,10 +551,14 @@ class Debounce extends HTMLElement {
|
|
|
508
551
|
if (config.autoTrigger) {
|
|
509
552
|
registerAutoTrigger();
|
|
510
553
|
}
|
|
554
|
+
// §4.1/§4.4 Shell SSR: expose connectedCallbackPromise backed by observe().
|
|
555
|
+
// observe() is a no-op resolving once ready (the engine is command-driven).
|
|
556
|
+
this._connectedCallbackPromise = this._core.observe();
|
|
511
557
|
}
|
|
512
558
|
disconnectedCallback() {
|
|
513
|
-
// Drop any in-flight timer so a detached element leaks nothing
|
|
514
|
-
|
|
559
|
+
// Drop any in-flight timer so a detached element leaks nothing, and bump the
|
|
560
|
+
// Core generation so a surviving timer callback cannot settle (§3.5).
|
|
561
|
+
this._core.dispose();
|
|
515
562
|
}
|
|
516
563
|
}
|
|
517
564
|
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/wcBindableFactory.ts","../src/core/DebounceCore.ts","../src/autoTrigger.ts","../src/components/Debounce.ts","../src/components/Throttle.ts","../src/registerComponents.ts","../src/bootstrapDebounce.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n debounce: string;\n throttle: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-debouncetarget\",\n tagNames: {\n debounce: \"wcs-debounce\",\n throttle: \"wcs-throttle\",\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 (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindableProperty } from \"./types.js\";\n\n/**\n * Build the wc-bindable `properties` list for a debounce/throttle element, with\n * every event name derived from a single `prefix`. `<wcs-debounce>` uses\n * `\"wcs-debounce\"`, `<wcs-throttle>` uses `\"wcs-throttle\"`, so the two tags share\n * one engine (DebounceCore) yet advertise distinct event namespaces from one\n * source of truth — no hand-duplicated property tables (cf. the geolocation Shell\n * which overrode its wcBindable by hand).\n *\n * - `value` — the debounced value of the latest `source` write (value surface),\n * read from the `<prefix>:settled` event.\n * - `fired` — the coalesced args of the latest `trigger()` pulse (signal\n * surface), read from the `<prefix>:fired` event. Declared as a\n * property (not just an event) so state can subscribe via the\n * event-token protocol (`eventToken.fired: <name>`).\n * - `pending` — whether a debounce is currently in flight.\n */\nexport function makeDebounceProperties(prefix: string): IWcBindableProperty[] {\n return [\n { name: \"value\", event: `${prefix}:settled`, getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"fired\", event: `${prefix}:fired`, getter: (e: Event) => (e as CustomEvent).detail.args },\n { name: \"pending\", event: `${prefix}:pending-changed` },\n ];\n}\n","import { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\ntype PendingKind = \"value\" | \"signal\" | null;\n\n/**\n * Headless debounce/throttle primitive. A framework-agnostic port of lodash's\n * `debounce` algorithm (`shouldInvoke` / `leadingEdge` / `trailingEdge` /\n * `remainingWait`, timed via `Date.now()`), exposed through the wc-bindable\n * protocol.\n *\n * It coalesces a stream of *signals* and emits at most one per quiet period.\n * Two surfaces share the single timer:\n *\n * - **value** — writing {@link setSource} schedules a settle; on fire the\n * debounced value is published via the `<prefix>:settled` event and the\n * `value` getter. Wire it as `source: src; value: debounced`.\n * - **signal** — calling {@link trigger}`(...args)` coalesces a burst of pulses;\n * on fire one `<prefix>:fired` event carries the latest args (relayed by state\n * through the command-token / event-token protocols).\n *\n * A given instance is meant to be used for one surface at a time. Because each\n * surface keeps its own field (`_value` vs `_lastArgs`), the getters never\n * pollute each other; if both are driven on one instance the *last* scheduled\n * signal wins (lodash's last-args semantics).\n *\n * Throttle is the same engine with `maxWait === wait` (and `leading` on by\n * default), so `<wcs-throttle>` reuses this class with a different `eventPrefix`.\n */\nexport class DebounceCore extends EventTarget {\n // The static contract advertises the *default* `wcs-debounce:*` event names. A\n // headless Core constructed with a non-default `eventPrefix` (e.g.\n // `\"wcs-throttle\"`) dispatches under that prefix, so its events won't match\n // this metadata — rebuild the property table with `makeDebounceProperties(prefix)`\n // for that case. (The `<wcs-throttle>` Shell already overrides its own\n // `wcBindable` this way, so binding through an element is always consistent.)\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n private readonly _prefix: string;\n private _target: EventTarget;\n\n // Tuning (lodash knobs).\n private _wait: number = 0;\n private _leading: boolean = false;\n private _trailing: boolean = true;\n private _maxWait: number = 0;\n private _hasMaxWait: boolean = false;\n\n // Timing bookkeeping.\n private _lastCallTime: number | undefined = undefined;\n private _lastInvokeTime: number = 0;\n private _timerId: ReturnType<typeof setTimeout> | null = null;\n\n // Last-wins pending payload. `_pendingKind === null` doubles as the \"consumed /\n // empty\" sentinel (lodash clears `lastArgs` in invokeFunc): a trailing edge with\n // no fresh call since the last fire sees `null` and does not re-fire, which is\n // what stops a single leading pulse from also firing on the trailing edge.\n private _pendingKind: PendingKind = null;\n private _pendingValue: any = undefined;\n private _pendingArgs: any[] | undefined = undefined;\n\n // Observable state (getter backing).\n private _value: any = undefined;\n private _lastArgs: any[] = [];\n private _pending: boolean = false;\n\n constructor(prefix: string = \"wcs-debounce\", target?: EventTarget, options?: DebounceOptions) {\n super();\n this._prefix = prefix;\n this._target = target ?? this;\n if (options) {\n this.configure(options);\n }\n }\n\n // --- Configuration ---\n\n /**\n * Update the tuning knobs. The Shell calls this with the element's current\n * attributes before each schedule, so live attribute edits take effect on the\n * next signal. `maxWait` is clamped to at least `wait` (lodash semantics); an\n * absent / invalid `maxWait` disables maxWait entirely.\n */\n configure(options: DebounceOptions = {}): void {\n if (typeof options.wait === \"number\" && Number.isFinite(options.wait) && options.wait >= 0) {\n this._wait = options.wait;\n }\n if (typeof options.leading === \"boolean\") {\n this._leading = options.leading;\n }\n if (typeof options.trailing === \"boolean\") {\n this._trailing = options.trailing;\n }\n const mw = options.maxWait;\n if (typeof mw === \"number\" && Number.isFinite(mw) && mw >= 0) {\n this._maxWait = Math.max(mw, this._wait);\n this._hasMaxWait = true;\n } else {\n this._maxWait = 0;\n this._hasMaxWait = false;\n }\n }\n\n // --- Observable getters ---\n\n get value(): any {\n return this._value;\n }\n\n get fired(): any[] {\n return this._lastArgs;\n }\n\n get pending(): boolean {\n return this._pending;\n }\n\n // --- Public entry points ---\n\n /** Value surface: schedule a settle carrying `value` (last write wins). */\n setSource(value: any): void {\n this._schedule(\"value\", value, undefined);\n }\n\n /** Signal surface: coalesce a pulse carrying `args` (last call wins). */\n trigger(...args: any[]): void {\n this._schedule(\"signal\", undefined, args);\n }\n\n /** Drop any pending fire without emitting. Getters keep their last values. */\n cancel(): void {\n this._clearTimer();\n this._lastInvokeTime = 0;\n this._lastCallTime = undefined;\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n /**\n * Emit any buffered payload immediately, then clear pending. Unlike lodash's\n * `flush` (which honours `trailing`), this fires whatever is buffered — the\n * command's intent is \"publish now\" — but is a no-op when nothing is pending.\n */\n flush(): void {\n if (this._timerId === null && this._pendingKind === null) return;\n const now = Date.now();\n this._clearTimer();\n if (this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n // --- Engine (lodash port) ---\n\n private _schedule(kind: Exclude<PendingKind, null>, value: any, args: any[] | undefined): void {\n const now = Date.now();\n const isInvoking = this._shouldInvoke(now);\n\n this._pendingKind = kind;\n if (kind === \"value\") {\n this._pendingValue = value;\n } else {\n this._pendingArgs = args;\n }\n this._lastCallTime = now;\n this._setPending(true);\n\n if (isInvoking) {\n if (this._timerId === null) {\n this._leadingEdge(now);\n return;\n }\n if (this._hasMaxWait) {\n // Continuous input that has reached maxWait: restart the steady timer and\n // invoke now so a fire happens at least every maxWait ms (throttle path).\n // Clear the pending handle first (lodash's \"tight loop\" branch does the\n // same) — overwriting `_timerId` without clearing would orphan the old\n // timer and let it fire spuriously later.\n this._clearTimer();\n this._timerId = setTimeout(this._timerExpired, this._wait);\n this._invoke(now);\n return;\n }\n }\n if (this._timerId === null) {\n this._timerId = setTimeout(this._timerExpired, this._wait);\n }\n }\n\n private _shouldInvoke(now: number): boolean {\n if (this._lastCallTime === undefined) return true;\n const timeSinceLastCall = now - this._lastCallTime;\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n return (\n timeSinceLastCall >= this._wait ||\n timeSinceLastCall < 0 ||\n (this._hasMaxWait && timeSinceLastInvoke >= this._maxWait)\n );\n }\n\n private _remainingWait(now: number): number {\n const timeSinceLastCall = now - (this._lastCallTime as number);\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n const timeWaiting = this._wait - timeSinceLastCall;\n return this._hasMaxWait\n ? Math.min(timeWaiting, this._maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n private _timerExpired = (): void => {\n const now = Date.now();\n if (this._shouldInvoke(now)) {\n this._trailingEdge(now);\n return;\n }\n // Fired before the quiet period elapsed (a later call moved the deadline) —\n // re-arm for the remaining time instead of settling now.\n this._timerId = setTimeout(this._timerExpired, this._remainingWait(now));\n };\n\n private _leadingEdge(now: number): void {\n this._lastInvokeTime = now;\n this._timerId = setTimeout(this._timerExpired, this._wait);\n if (this._leading) {\n this._invoke(now);\n }\n }\n\n private _trailingEdge(now: number): void {\n this._timerId = null;\n // Only fire when there is an unconsumed payload (a call arrived since the last\n // invoke). After a lone leading fire `_pendingKind` is null, so a single pulse\n // does not double-fire on its trailing edge.\n if (this._trailing && this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n private _invoke(now: number): void {\n this._lastInvokeTime = now;\n const kind = this._pendingKind;\n if (kind === \"value\") {\n this._value = this._pendingValue;\n this._dispatch(`${this._prefix}:settled`, { value: this._value });\n } else if (kind === \"signal\") {\n this._lastArgs = this._pendingArgs ?? [];\n this._dispatch(`${this._prefix}:fired`, { args: this._lastArgs });\n }\n // Mark consumed (mirrors lodash clearing `lastArgs`).\n this._pendingKind = null;\n }\n\n private _setPending(pending: boolean): void {\n if (this._pending === pending) return;\n this._pending = pending;\n this._dispatch(`${this._prefix}:pending-changed`, pending);\n }\n\n private _dispatch(type: string, detail: any): void {\n this._target.dispatchEvent(new CustomEvent(type, { detail, bubbles: true }));\n }\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n clearTimeout(this._timerId);\n this._timerId = null;\n }\n }\n}\n","import { config } from \"./config.js\";\n\nlet registered = false;\n\ninterface Triggerable extends Element {\n trigger(...args: unknown[]): void;\n}\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const id = triggerElement.getAttribute(config.triggerAttribute);\n if (!id) return;\n\n // Resolve the registered constructors at call time (avoids a components ⇄\n // autoTrigger import cycle, mirroring <wcs-timer>). The DOM trigger fires a\n // single coalesced pulse on the referenced <wcs-debounce> / <wcs-throttle>.\n const DebounceCtor = customElements.get(config.tagNames.debounce);\n const ThrottleCtor = customElements.get(config.tagNames.throttle);\n const el = document.getElementById(id);\n if (!el) return;\n const isDebounce = DebounceCtor && el instanceof DebounceCtor;\n const isThrottle = ThrottleCtor && el instanceof ThrottleCtor;\n if (!isDebounce && !isThrottle) return;\n\n // Suppress the element's default action so a debounce can fire without\n // navigating. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (el as unknown as Triggerable).trigger();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { DebounceCore } from \"../core/DebounceCore.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nconst DEFAULT_WAIT = 250;\n\n/**\n * `<wcs-debounce>` — declarative debounce. See {@link DebounceCore} for the\n * engine. The `eventPrefix` defaults to `\"wcs-debounce\"`; `<wcs-throttle>`\n * subclasses this with `\"wcs-throttle\"` and throttle defaults.\n */\nexport class Debounce extends HTMLElement {\n static hasConnectedCallbackPromise = false;\n protected static eventPrefix = \"wcs-debounce\";\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n // `source` is the value-surface input (its debounced echo comes back on the\n // `value` property). `trigger` / `cancel` / `flush` are commands from the\n // Core. No momentary boolean `trigger` property exists — the signal surface\n // is driven by the `trigger` command (command-token) or a DOM click\n // (autoTrigger), which sidesteps the attribute/method name clash that forced\n // <wcs-geo>'s watch → watchPosition rename.\n inputs: [\n { name: \"source\" },\n { name: \"wait\", attribute: \"wait\" },\n { name: \"leading\", attribute: \"leading\" },\n { name: \"trailing\", attribute: \"trailing\" },\n { name: \"maxWait\", attribute: \"max-wait\" },\n ],\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n protected _core: DebounceCore;\n private _source: any = undefined;\n\n constructor() {\n super();\n this._core = new DebounceCore((this.constructor as typeof Debounce).eventPrefix, this);\n }\n\n // --- Attribute accessors ---\n\n get wait(): number {\n const attr = this.getAttribute(\"wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultWait();\n // Strict parse via Number() (\"100px\" -> NaN, not 100). Fall back to the\n // default for any non-finite or negative value.\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultWait();\n }\n\n set wait(value: number) {\n this.setAttribute(\"wait\", String(value));\n }\n\n get leading(): boolean {\n return this.hasAttribute(\"leading\");\n }\n\n set leading(value: boolean) {\n if (value) {\n this.setAttribute(\"leading\", \"\");\n } else {\n this.removeAttribute(\"leading\");\n }\n }\n\n // `trailing` defaults to true; the boolean `no-trailing` attribute opts out (a\n // bare `trailing` attribute can't express \"false\", so the negative flag carries\n // the override).\n get trailing(): boolean {\n return !this.hasAttribute(\"no-trailing\");\n }\n\n set trailing(value: boolean) {\n if (value) {\n this.removeAttribute(\"no-trailing\");\n } else {\n this.setAttribute(\"no-trailing\", \"\");\n }\n }\n\n get maxWait(): number | undefined {\n const attr = this.getAttribute(\"max-wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultMaxWait();\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultMaxWait();\n }\n\n set maxWait(value: number) {\n this.setAttribute(\"max-wait\", String(value));\n }\n\n // --- Value-surface input ---\n\n get source(): any {\n return this._source;\n }\n\n set source(value: any) {\n this._source = value;\n this._core.configure(this._options());\n this._core.setSource(value);\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get fired(): any[] {\n return this._core.fired;\n }\n\n get pending(): boolean {\n return this._core.pending;\n }\n\n // --- Commands ---\n\n trigger(...args: any[]): void {\n this._core.configure(this._options());\n this._core.trigger(...args);\n }\n\n cancel(): void {\n this._core.cancel();\n }\n\n flush(): void {\n this._core.flush();\n }\n\n // --- Internal ---\n\n // Overridden by <wcs-throttle> to bias the defaults toward throttle (leading\n // on, maxWait pinned to wait).\n protected _defaultWait(): number {\n return DEFAULT_WAIT;\n }\n\n // Resolves the effective `leading` value (not a static default). It is a method\n // rather than reading `this.leading` directly because <wcs-throttle> inverts the\n // default (on, opt out via `no-leading`) while sharing the inherited `leading`\n // attribute setter — overriding the getter alone would desync getter and setter.\n protected _resolveLeading(): boolean {\n return this.leading;\n }\n\n protected _defaultMaxWait(): number | undefined {\n return undefined;\n }\n\n protected _options(): DebounceOptions {\n return {\n wait: this.wait,\n leading: this._resolveLeading(),\n trailing: this.trailing,\n maxWait: this.maxWait,\n };\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n }\n\n disconnectedCallback(): void {\n // Drop any in-flight timer so a detached element leaks nothing.\n this._core.cancel();\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { Debounce } from \"./Debounce.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\n/**\n * `<wcs-throttle>` — the same {@link DebounceCore} engine biased to throttle:\n * `maxWait === wait` (a fire happens at least every `wait` ms under continuous\n * input) and `leading` on by default. It advertises its own `wcs-throttle:*`\n * event namespace (via `makeDebounceProperties(\"wcs-throttle\")`), and the Core\n * dispatches under that prefix because the constructor passes it through.\n */\nexport class Throttle extends Debounce {\n protected static eventPrefix = \"wcs-throttle\";\n static wcBindable: IWcBindable = {\n ...Debounce.wcBindable,\n properties: makeDebounceProperties(\"wcs-throttle\"),\n };\n\n // leading defaults on for throttle; `no-leading` opts out (symmetric with the\n // inherited `no-trailing`).\n protected _resolveLeading(): boolean {\n return !this.hasAttribute(\"no-leading\");\n }\n\n // Pin maxWait to wait so throttle fires on a steady cadence; an explicit\n // `max-wait` attribute still overrides via the inherited getter.\n protected _defaultMaxWait(): number | undefined {\n return this.wait;\n }\n}\n","import { Debounce } from \"./components/Debounce.js\";\nimport { Throttle } from \"./components/Throttle.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.debounce)) {\n customElements.define(config.tagNames.debounce, Debounce);\n }\n if (!customElements.get(config.tagNames.throttle)) {\n customElements.define(config.tagNames.throttle, Throttle);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapDebounce(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/wcBindableFactory.ts","../src/core/DebounceCore.ts","../src/autoTrigger.ts","../src/components/Debounce.ts","../src/components/Throttle.ts","../src/registerComponents.ts","../src/bootstrapDebounce.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n debounce: string;\n throttle: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-debouncetarget\",\n tagNames: {\n debounce: \"wcs-debounce\",\n throttle: \"wcs-throttle\",\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 (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindableProperty } from \"./types.js\";\n\n/**\n * Build the wc-bindable `properties` list for a debounce/throttle element, with\n * every event name derived from a single `prefix`. `<wcs-debounce>` uses\n * `\"wcs-debounce\"`, `<wcs-throttle>` uses `\"wcs-throttle\"`, so the two tags share\n * one engine (DebounceCore) yet advertise distinct event namespaces from one\n * source of truth — no hand-duplicated property tables (cf. the geolocation Shell\n * which overrode its wcBindable by hand).\n *\n * - `value` — the debounced value of the latest `source` write (value surface),\n * read from the `<prefix>:settled` event.\n * - `fired` — the coalesced args of the latest `trigger()` pulse (signal\n * surface), read from the `<prefix>:fired` event. Declared as a\n * property (not just an event) so state can subscribe via the\n * event-token protocol (`eventToken.fired: <name>`).\n * - `pending` — whether a debounce is currently in flight.\n */\nexport function makeDebounceProperties(prefix: string): IWcBindableProperty[] {\n return [\n { name: \"value\", event: `${prefix}:settled`, getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"fired\", event: `${prefix}:fired`, getter: (e: Event) => (e as CustomEvent).detail.args },\n { name: \"pending\", event: `${prefix}:pending-changed` },\n ];\n}\n","import { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\ntype PendingKind = \"value\" | \"signal\" | null;\n\n/**\n * Headless debounce/throttle primitive. A framework-agnostic port of lodash's\n * `debounce` algorithm (`shouldInvoke` / `leadingEdge` / `trailingEdge` /\n * `remainingWait`, timed via `Date.now()`), exposed through the wc-bindable\n * protocol.\n *\n * It coalesces a stream of *signals* and emits at most one per quiet period.\n * Two surfaces share the single timer:\n *\n * - **value** — writing {@link setSource} schedules a settle; on fire the\n * debounced value is published via the `<prefix>:settled` event and the\n * `value` getter. Wire it as `source: src; value: debounced`.\n * - **signal** — calling {@link trigger}`(...args)` coalesces a burst of pulses;\n * on fire one `<prefix>:fired` event carries the latest args (relayed by state\n * through the command-token / event-token protocols).\n *\n * A given instance is meant to be used for one surface at a time. Because each\n * surface keeps its own field (`_value` vs `_lastArgs`), the getters never\n * pollute each other; if both are driven on one instance the *last* scheduled\n * signal wins (lodash's last-args semantics).\n *\n * Throttle is the same engine with `maxWait === wait` (and `leading` on by\n * default), so `<wcs-throttle>` reuses this class with a different `eventPrefix`.\n */\nexport class DebounceCore extends EventTarget {\n // The static contract advertises the *default* `wcs-debounce:*` event names. A\n // headless Core constructed with a non-default `eventPrefix` (e.g.\n // `\"wcs-throttle\"`) dispatches under that prefix, so its events won't match\n // this metadata — rebuild the property table with `makeDebounceProperties(prefix)`\n // for that case. (The `<wcs-throttle>` Shell already overrides its own\n // `wcBindable` this way, so binding through an element is always consistent.)\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n private readonly _prefix: string;\n private _target: EventTarget;\n\n // Tuning (lodash knobs).\n private _wait: number = 0;\n private _leading: boolean = false;\n private _trailing: boolean = true;\n private _maxWait: number = 0;\n private _hasMaxWait: boolean = false;\n\n // Timing bookkeeping.\n private _lastCallTime: number | undefined = undefined;\n private _lastInvokeTime: number = 0;\n private _timerId: ReturnType<typeof setTimeout> | null = null;\n // Generation stamped onto the live timer at arm time, compared in\n // `_timerExpired` against `_gen` to drop callbacks that outlived a dispose().\n private _timerGen: number = 0;\n\n // Last-wins pending payload. `_pendingKind === null` doubles as the \"consumed /\n // empty\" sentinel (lodash clears `lastArgs` in invokeFunc): a trailing edge with\n // no fresh call since the last fire sees `null` and does not re-fire, which is\n // what stops a single leading pulse from also firing on the trailing edge.\n private _pendingKind: PendingKind = null;\n private _pendingValue: any = undefined;\n private _pendingArgs: any[] | undefined = undefined;\n\n // Observable state (getter backing).\n private _value: any = undefined;\n private _lastArgs: any[] = [];\n private _pending: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() so a timer that survives a\n // tear-down can no longer settle into a detached element. A pending timer is\n // also cleared by dispose() → cancel(), so the guard is defensive: it stops\n // any callback that has already been dequeued by the host event loop from\n // writing state after dispose().\n private _gen = 0;\n // SSR (§3.8): the debounce engine is purely timer-driven with no asynchronous\n // probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(prefix: string = \"wcs-debounce\", target?: EventTarget, options?: DebounceOptions) {\n super();\n this._prefix = prefix;\n this._target = target ?? this;\n if (options) {\n this.configure(options);\n }\n }\n\n // --- Lifecycle (§3.5 / §3.8) ---\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Debounce is command-driven (setSource / trigger schedule work on demand)\n // with no subscription to establish, so observe() is an idempotent no-op that\n // resolves once ready.\n observe(): Promise<void> {\n return this._ready;\n }\n\n // Tear down the pending timer and invalidate the generation so a stale timer\n // callback cannot fire after the element is detached.\n dispose(): void {\n this._gen++;\n this.cancel();\n }\n\n // --- Configuration ---\n\n /**\n * Update the tuning knobs. The Shell calls this with the element's current\n * attributes before each schedule, so live attribute edits take effect on the\n * next signal. `maxWait` is clamped to at least `wait` (lodash semantics); an\n * absent / invalid `maxWait` disables maxWait entirely.\n */\n configure(options: DebounceOptions = {}): void {\n if (typeof options.wait === \"number\" && Number.isFinite(options.wait) && options.wait >= 0) {\n this._wait = options.wait;\n }\n if (typeof options.leading === \"boolean\") {\n this._leading = options.leading;\n }\n if (typeof options.trailing === \"boolean\") {\n this._trailing = options.trailing;\n }\n const mw = options.maxWait;\n if (typeof mw === \"number\" && Number.isFinite(mw) && mw >= 0) {\n this._maxWait = Math.max(mw, this._wait);\n this._hasMaxWait = true;\n } else {\n this._maxWait = 0;\n this._hasMaxWait = false;\n }\n }\n\n // --- Observable getters ---\n\n get value(): any {\n return this._value;\n }\n\n get fired(): any[] {\n return this._lastArgs;\n }\n\n get pending(): boolean {\n return this._pending;\n }\n\n // --- Public entry points ---\n\n /** Value surface: schedule a settle carrying `value` (last write wins). */\n setSource(value: any): void {\n this._schedule(\"value\", value, undefined);\n }\n\n /** Signal surface: coalesce a pulse carrying `args` (last call wins). */\n trigger(...args: any[]): void {\n this._schedule(\"signal\", undefined, args);\n }\n\n /** Drop any pending fire without emitting. Getters keep their last values. */\n cancel(): void {\n this._clearTimer();\n this._lastInvokeTime = 0;\n this._lastCallTime = undefined;\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n /**\n * Emit any buffered payload immediately, then clear pending. Unlike lodash's\n * `flush` (which honours `trailing`), this fires whatever is buffered — the\n * command's intent is \"publish now\" — but is a no-op when nothing is pending.\n */\n flush(): void {\n if (this._timerId === null && this._pendingKind === null) return;\n const now = Date.now();\n this._clearTimer();\n if (this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n // --- Engine (lodash port) ---\n\n private _schedule(kind: Exclude<PendingKind, null>, value: any, args: any[] | undefined): void {\n const now = Date.now();\n const isInvoking = this._shouldInvoke(now);\n\n this._pendingKind = kind;\n if (kind === \"value\") {\n this._pendingValue = value;\n } else {\n this._pendingArgs = args;\n }\n this._lastCallTime = now;\n this._setPending(true);\n\n if (isInvoking) {\n if (this._timerId === null) {\n this._leadingEdge(now);\n return;\n }\n if (this._hasMaxWait) {\n // Continuous input that has reached maxWait: restart the steady timer and\n // invoke now so a fire happens at least every maxWait ms (throttle path).\n // Clear the pending handle first (lodash's \"tight loop\" branch does the\n // same) — overwriting `_timerId` without clearing would orphan the old\n // timer and let it fire spuriously later.\n this._clearTimer();\n this._armTimer(this._wait);\n this._invoke(now);\n return;\n }\n }\n if (this._timerId === null) {\n this._armTimer(this._wait);\n }\n }\n\n private _shouldInvoke(now: number): boolean {\n if (this._lastCallTime === undefined) return true;\n const timeSinceLastCall = now - this._lastCallTime;\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n return (\n timeSinceLastCall >= this._wait ||\n timeSinceLastCall < 0 ||\n (this._hasMaxWait && timeSinceLastInvoke >= this._maxWait)\n );\n }\n\n private _remainingWait(now: number): number {\n const timeSinceLastCall = now - (this._lastCallTime as number);\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n const timeWaiting = this._wait - timeSinceLastCall;\n return this._hasMaxWait\n ? Math.min(timeWaiting, this._maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n private _timerExpired = (): void => {\n // §3.4 generation guard: a timer dequeued by the host before dispose() could\n // clear it must not settle into a torn-down element. Capture the generation\n // when the timer is scheduled (via `_armTimer`) and bail if it is stale.\n if (this._timerGen !== this._gen) return;\n const now = Date.now();\n if (this._shouldInvoke(now)) {\n this._trailingEdge(now);\n return;\n }\n // Fired before the quiet period elapsed (a later call moved the deadline) —\n // re-arm for the remaining time instead of settling now.\n this._armTimer(this._remainingWait(now));\n };\n\n private _leadingEdge(now: number): void {\n this._lastInvokeTime = now;\n this._armTimer(this._wait);\n if (this._leading) {\n this._invoke(now);\n }\n }\n\n private _trailingEdge(now: number): void {\n this._timerId = null;\n // Only fire when there is an unconsumed payload (a call arrived since the last\n // invoke). After a lone leading fire `_pendingKind` is null, so a single pulse\n // does not double-fire on its trailing edge.\n if (this._trailing && this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n private _invoke(now: number): void {\n this._lastInvokeTime = now;\n const kind = this._pendingKind;\n if (kind === \"value\") {\n this._value = this._pendingValue;\n this._dispatch(`${this._prefix}:settled`, { value: this._value });\n } else if (kind === \"signal\") {\n this._lastArgs = this._pendingArgs ?? [];\n this._dispatch(`${this._prefix}:fired`, { args: this._lastArgs });\n }\n // Mark consumed (mirrors lodash clearing `lastArgs`).\n this._pendingKind = null;\n }\n\n private _setPending(pending: boolean): void {\n if (this._pending === pending) return;\n this._pending = pending;\n this._dispatch(`${this._prefix}:pending-changed`, pending);\n }\n\n private _dispatch(type: string, detail: any): void {\n this._target.dispatchEvent(new CustomEvent(type, { detail, bubbles: true }));\n }\n\n // Arm the settle timer, stamping the current generation so a callback that the\n // host dequeues after a dispose() can detect it is stale (§3.4).\n private _armTimer(delay: number): void {\n this._timerGen = this._gen;\n this._timerId = setTimeout(this._timerExpired, delay);\n }\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n clearTimeout(this._timerId);\n this._timerId = null;\n }\n }\n}\n","import { config } from \"./config.js\";\n\nlet registered = false;\n\ninterface Triggerable extends Element {\n trigger(...args: unknown[]): void;\n}\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const id = triggerElement.getAttribute(config.triggerAttribute);\n if (!id) return;\n\n // Resolve the registered constructors at call time (avoids a components ⇄\n // autoTrigger import cycle, mirroring <wcs-timer>). The DOM trigger fires a\n // single coalesced pulse on the referenced <wcs-debounce> / <wcs-throttle>.\n const DebounceCtor = customElements.get(config.tagNames.debounce);\n const ThrottleCtor = customElements.get(config.tagNames.throttle);\n const el = document.getElementById(id);\n if (!el) return;\n const isDebounce = DebounceCtor && el instanceof DebounceCtor;\n const isThrottle = ThrottleCtor && el instanceof ThrottleCtor;\n if (!isDebounce && !isThrottle) return;\n\n // Suppress the element's default action so a debounce can fire without\n // navigating. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (el as unknown as Triggerable).trigger();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { DebounceCore } from \"../core/DebounceCore.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nconst DEFAULT_WAIT = 250;\n\n/**\n * `<wcs-debounce>` — declarative debounce. See {@link DebounceCore} for the\n * engine. The `eventPrefix` defaults to `\"wcs-debounce\"`; `<wcs-throttle>`\n * subclasses this with `\"wcs-throttle\"` and throttle defaults.\n */\nexport class Debounce extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n protected static eventPrefix = \"wcs-debounce\";\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n // `source` is the value-surface input (its debounced echo comes back on the\n // `value` property). `trigger` / `cancel` / `flush` are commands from the\n // Core. No momentary boolean `trigger` property exists — the signal surface\n // is driven by the `trigger` command (command-token) or a DOM click\n // (autoTrigger), which sidesteps the attribute/method name clash that forced\n // <wcs-geo>'s watch → watchPosition rename.\n inputs: [\n { name: \"source\" },\n { name: \"wait\", attribute: \"wait\" },\n { name: \"leading\", attribute: \"leading\" },\n { name: \"trailing\", attribute: \"trailing\" },\n { name: \"maxWait\", attribute: \"max-wait\" },\n ],\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n protected _core: DebounceCore;\n private _source: any = undefined;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new DebounceCore((this.constructor as typeof Debounce).eventPrefix, this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get wait(): number {\n const attr = this.getAttribute(\"wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultWait();\n // Strict parse via Number() (\"100px\" -> NaN, not 100). Fall back to the\n // default for any non-finite or negative value.\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultWait();\n }\n\n set wait(value: number) {\n this.setAttribute(\"wait\", String(value));\n }\n\n get leading(): boolean {\n return this.hasAttribute(\"leading\");\n }\n\n set leading(value: boolean) {\n if (value) {\n this.setAttribute(\"leading\", \"\");\n } else {\n this.removeAttribute(\"leading\");\n }\n }\n\n // `trailing` defaults to true; the boolean `no-trailing` attribute opts out (a\n // bare `trailing` attribute can't express \"false\", so the negative flag carries\n // the override).\n get trailing(): boolean {\n return !this.hasAttribute(\"no-trailing\");\n }\n\n set trailing(value: boolean) {\n if (value) {\n this.removeAttribute(\"no-trailing\");\n } else {\n this.setAttribute(\"no-trailing\", \"\");\n }\n }\n\n get maxWait(): number | undefined {\n const attr = this.getAttribute(\"max-wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultMaxWait();\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultMaxWait();\n }\n\n set maxWait(value: number) {\n this.setAttribute(\"max-wait\", String(value));\n }\n\n // --- Value-surface input ---\n\n get source(): any {\n return this._source;\n }\n\n set source(value: any) {\n this._source = value;\n this._core.configure(this._options());\n this._core.setSource(value);\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get fired(): any[] {\n return this._core.fired;\n }\n\n get pending(): boolean {\n return this._core.pending;\n }\n\n // --- Commands ---\n\n trigger(...args: any[]): void {\n this._core.configure(this._options());\n this._core.trigger(...args);\n }\n\n cancel(): void {\n this._core.cancel();\n }\n\n flush(): void {\n this._core.flush();\n }\n\n // --- Internal ---\n\n // Overridden by <wcs-throttle> to bias the defaults toward throttle (leading\n // on, maxWait pinned to wait).\n protected _defaultWait(): number {\n return DEFAULT_WAIT;\n }\n\n // Resolves the effective `leading` value (not a static default). It is a method\n // rather than reading `this.leading` directly because <wcs-throttle> inverts the\n // default (on, opt out via `no-leading`) while sharing the inherited `leading`\n // attribute setter — overriding the getter alone would desync getter and setter.\n protected _resolveLeading(): boolean {\n return this.leading;\n }\n\n protected _defaultMaxWait(): number | undefined {\n return undefined;\n }\n\n protected _options(): DebounceOptions {\n return {\n wait: this.wait,\n leading: this._resolveLeading(),\n trailing: this.trailing,\n maxWait: this.maxWait,\n };\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // §4.1/§4.4 Shell SSR: expose connectedCallbackPromise backed by observe().\n // observe() is a no-op resolving once ready (the engine is command-driven).\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n // Drop any in-flight timer so a detached element leaks nothing, and bump the\n // Core generation so a surviving timer callback cannot settle (§3.5).\n this._core.dispose();\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { Debounce } from \"./Debounce.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\n/**\n * `<wcs-throttle>` — the same {@link DebounceCore} engine biased to throttle:\n * `maxWait === wait` (a fire happens at least every `wait` ms under continuous\n * input) and `leading` on by default. It advertises its own `wcs-throttle:*`\n * event namespace (via `makeDebounceProperties(\"wcs-throttle\")`), and the Core\n * dispatches under that prefix because the constructor passes it through.\n */\nexport class Throttle extends Debounce {\n protected static eventPrefix = \"wcs-throttle\";\n static wcBindable: IWcBindable = {\n ...Debounce.wcBindable,\n properties: makeDebounceProperties(\"wcs-throttle\"),\n };\n\n // leading defaults on for throttle; `no-leading` opts out (symmetric with the\n // inherited `no-trailing`).\n protected _resolveLeading(): boolean {\n return !this.hasAttribute(\"no-leading\");\n }\n\n // Pin maxWait to wait so throttle fires on a steady cadence; an explicit\n // `max-wait` attribute still overrides via the inherited getter.\n protected _defaultMaxWait(): number | undefined {\n return this.wait;\n }\n}\n","import { Debounce } from \"./components/Debounce.js\";\nimport { Throttle } from \"./components/Throttle.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.debounce)) {\n customElements.define(config.tagNames.debounce, Debounce);\n }\n if (!customElements.get(config.tagNames.throttle)) {\n customElements.define(config.tagNames.throttle, Throttle);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapDebounce(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.esm.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const t={autoTrigger:!0,triggerAttribute:"data-debouncetarget",tagNames:{debounce:"wcs-debounce",throttle:"wcs-throttle"}};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const i of Object.keys(t))e(t[i]);return t}function i(t){if(null===t||"object"!=typeof t)return t;const e={};for(const n of Object.keys(t))e[n]=i(t[n]);return e}let n=null;const s=t;function
|
|
1
|
+
const t={autoTrigger:!0,triggerAttribute:"data-debouncetarget",tagNames:{debounce:"wcs-debounce",throttle:"wcs-throttle"}};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const i of Object.keys(t))e(t[i]);return t}function i(t){if(null===t||"object"!=typeof t)return t;const e={};for(const n of Object.keys(t))e[n]=i(t[n]);return e}let n=null;const s=t;function r(){return n||(n=e(i(t))),n}function a(t){return[{name:"value",event:`${t}:settled`,getter:t=>t.detail.value},{name:"fired",event:`${t}:fired`,getter:t=>t.detail.args},{name:"pending",event:`${t}:pending-changed`}]}class l extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:a("wcs-debounce"),commands:[{name:"trigger"},{name:"cancel"},{name:"flush"}]};_prefix;_target;_wait=0;_leading=!1;_trailing=!0;_maxWait=0;_hasMaxWait=!1;_lastCallTime=void 0;_lastInvokeTime=0;_timerId=null;_timerGen=0;_pendingKind=null;_pendingValue=void 0;_pendingArgs=void 0;_value=void 0;_lastArgs=[];_pending=!1;_gen=0;_ready=Promise.resolve();constructor(t="wcs-debounce",e,i){super(),this._prefix=t,this._target=e??this,i&&this.configure(i)}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.cancel()}configure(t={}){"number"==typeof t.wait&&Number.isFinite(t.wait)&&t.wait>=0&&(this._wait=t.wait),"boolean"==typeof t.leading&&(this._leading=t.leading),"boolean"==typeof t.trailing&&(this._trailing=t.trailing);const e=t.maxWait;"number"==typeof e&&Number.isFinite(e)&&e>=0?(this._maxWait=Math.max(e,this._wait),this._hasMaxWait=!0):(this._maxWait=0,this._hasMaxWait=!1)}get value(){return this._value}get fired(){return this._lastArgs}get pending(){return this._pending}setSource(t){this._schedule("value",t,void 0)}trigger(...t){this._schedule("signal",void 0,t)}cancel(){this._clearTimer(),this._lastInvokeTime=0,this._lastCallTime=void 0,this._pendingKind=null,this._pendingValue=void 0,this._pendingArgs=void 0,this._setPending(!1)}flush(){if(null===this._timerId&&null===this._pendingKind)return;const t=Date.now();this._clearTimer(),null!==this._pendingKind&&this._invoke(t),this._pendingKind=null,this._pendingValue=void 0,this._pendingArgs=void 0,this._setPending(!1)}_schedule(t,e,i){const n=Date.now(),s=this._shouldInvoke(n);if(this._pendingKind=t,"value"===t?this._pendingValue=e:this._pendingArgs=i,this._lastCallTime=n,this._setPending(!0),s){if(null===this._timerId)return void this._leadingEdge(n);if(this._hasMaxWait)return this._clearTimer(),this._armTimer(this._wait),void this._invoke(n)}null===this._timerId&&this._armTimer(this._wait)}_shouldInvoke(t){if(void 0===this._lastCallTime)return!0;const e=t-this._lastCallTime,i=t-this._lastInvokeTime;return e>=this._wait||e<0||this._hasMaxWait&&i>=this._maxWait}_remainingWait(t){const e=t-this._lastCallTime,i=t-this._lastInvokeTime,n=this._wait-e;return this._hasMaxWait?Math.min(n,this._maxWait-i):n}_timerExpired=()=>{if(this._timerGen!==this._gen)return;const t=Date.now();this._shouldInvoke(t)?this._trailingEdge(t):this._armTimer(this._remainingWait(t))};_leadingEdge(t){this._lastInvokeTime=t,this._armTimer(this._wait),this._leading&&this._invoke(t)}_trailingEdge(t){this._timerId=null,this._trailing&&null!==this._pendingKind&&this._invoke(t),this._pendingKind=null,this._pendingValue=void 0,this._pendingArgs=void 0,this._setPending(!1)}_invoke(t){this._lastInvokeTime=t;const e=this._pendingKind;"value"===e?(this._value=this._pendingValue,this._dispatch(`${this._prefix}:settled`,{value:this._value})):"signal"===e&&(this._lastArgs=this._pendingArgs??[],this._dispatch(`${this._prefix}:fired`,{args:this._lastArgs})),this._pendingKind=null}_setPending(t){this._pending!==t&&(this._pending=t,this._dispatch(`${this._prefix}:pending-changed`,t))}_dispatch(t,e){this._target.dispatchEvent(new CustomEvent(t,{detail:e,bubbles:!0}))}_armTimer(t){this._timerGen=this._gen,this._timerId=setTimeout(this._timerExpired,t)}_clearTimer(){null!==this._timerId&&(clearTimeout(this._timerId),this._timerId=null)}}let o=!1;function h(t){const e=t.target;if(!(e instanceof Element))return;const i=e.closest(`[${s.triggerAttribute}]`);if(!i)return;const n=i.getAttribute(s.triggerAttribute);if(!n)return;const r=customElements.get(s.tagNames.debounce),a=customElements.get(s.tagNames.throttle),l=document.getElementById(n);if(!l)return;(r&&l instanceof r||a&&l instanceof a)&&(t.preventDefault(),l.trigger())}class g extends HTMLElement{static hasConnectedCallbackPromise=!0;static eventPrefix="wcs-debounce";static wcBindable={protocol:"wc-bindable",version:1,properties:a("wcs-debounce"),inputs:[{name:"source"},{name:"wait",attribute:"wait"},{name:"leading",attribute:"leading"},{name:"trailing",attribute:"trailing"},{name:"maxWait",attribute:"max-wait"}],commands:[{name:"trigger"},{name:"cancel"},{name:"flush"}]};_core;_source=void 0;_connectedCallbackPromise=Promise.resolve();constructor(){super(),this._core=new l(this.constructor.eventPrefix,this)}get connectedCallbackPromise(){return this._connectedCallbackPromise}get wait(){const t=this.getAttribute("wait");if(null===t||""===t.trim())return this._defaultWait();const e=Number(t);return Number.isFinite(e)&&e>=0?e:this._defaultWait()}set wait(t){this.setAttribute("wait",String(t))}get leading(){return this.hasAttribute("leading")}set leading(t){t?this.setAttribute("leading",""):this.removeAttribute("leading")}get trailing(){return!this.hasAttribute("no-trailing")}set trailing(t){t?this.removeAttribute("no-trailing"):this.setAttribute("no-trailing","")}get maxWait(){const t=this.getAttribute("max-wait");if(null===t||""===t.trim())return this._defaultMaxWait();const e=Number(t);return Number.isFinite(e)&&e>=0?e:this._defaultMaxWait()}set maxWait(t){this.setAttribute("max-wait",String(t))}get source(){return this._source}set source(t){this._source=t,this._core.configure(this._options()),this._core.setSource(t)}get value(){return this._core.value}get fired(){return this._core.fired}get pending(){return this._core.pending}trigger(...t){this._core.configure(this._options()),this._core.trigger(...t)}cancel(){this._core.cancel()}flush(){this._core.flush()}_defaultWait(){return 250}_resolveLeading(){return this.leading}_defaultMaxWait(){}_options(){return{wait:this.wait,leading:this._resolveLeading(),trailing:this.trailing,maxWait:this.maxWait}}connectedCallback(){this.style.display="none",s.autoTrigger&&(o||(o=!0,document.addEventListener("click",h))),this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}}class u extends g{static eventPrefix="wcs-throttle";static wcBindable={...g.wcBindable,properties:a("wcs-throttle")};_resolveLeading(){return!this.hasAttribute("no-leading")}_defaultMaxWait(){return this.wait}}function d(e){var i;e&&("boolean"==typeof(i=e).autoTrigger&&(t.autoTrigger=i.autoTrigger),"string"==typeof i.triggerAttribute&&(t.triggerAttribute=i.triggerAttribute),i.tagNames&&Object.assign(t.tagNames,i.tagNames),n=null),customElements.get(s.tagNames.debounce)||customElements.define(s.tagNames.debounce,g),customElements.get(s.tagNames.throttle)||customElements.define(s.tagNames.throttle,u)}export{l as DebounceCore,g as WcsDebounce,u as WcsThrottle,d as bootstrapDebounce,r as getConfig,a as makeDebounceProperties};
|
|
2
2
|
//# sourceMappingURL=index.esm.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/wcBindableFactory.ts","../src/core/DebounceCore.ts","../src/autoTrigger.ts","../src/components/Debounce.ts","../src/components/Throttle.ts","../src/bootstrapDebounce.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n debounce: string;\n throttle: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-debouncetarget\",\n tagNames: {\n debounce: \"wcs-debounce\",\n throttle: \"wcs-throttle\",\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 (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindableProperty } from \"./types.js\";\n\n/**\n * Build the wc-bindable `properties` list for a debounce/throttle element, with\n * every event name derived from a single `prefix`. `<wcs-debounce>` uses\n * `\"wcs-debounce\"`, `<wcs-throttle>` uses `\"wcs-throttle\"`, so the two tags share\n * one engine (DebounceCore) yet advertise distinct event namespaces from one\n * source of truth — no hand-duplicated property tables (cf. the geolocation Shell\n * which overrode its wcBindable by hand).\n *\n * - `value` — the debounced value of the latest `source` write (value surface),\n * read from the `<prefix>:settled` event.\n * - `fired` — the coalesced args of the latest `trigger()` pulse (signal\n * surface), read from the `<prefix>:fired` event. Declared as a\n * property (not just an event) so state can subscribe via the\n * event-token protocol (`eventToken.fired: <name>`).\n * - `pending` — whether a debounce is currently in flight.\n */\nexport function makeDebounceProperties(prefix: string): IWcBindableProperty[] {\n return [\n { name: \"value\", event: `${prefix}:settled`, getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"fired\", event: `${prefix}:fired`, getter: (e: Event) => (e as CustomEvent).detail.args },\n { name: \"pending\", event: `${prefix}:pending-changed` },\n ];\n}\n","import { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\ntype PendingKind = \"value\" | \"signal\" | null;\n\n/**\n * Headless debounce/throttle primitive. A framework-agnostic port of lodash's\n * `debounce` algorithm (`shouldInvoke` / `leadingEdge` / `trailingEdge` /\n * `remainingWait`, timed via `Date.now()`), exposed through the wc-bindable\n * protocol.\n *\n * It coalesces a stream of *signals* and emits at most one per quiet period.\n * Two surfaces share the single timer:\n *\n * - **value** — writing {@link setSource} schedules a settle; on fire the\n * debounced value is published via the `<prefix>:settled` event and the\n * `value` getter. Wire it as `source: src; value: debounced`.\n * - **signal** — calling {@link trigger}`(...args)` coalesces a burst of pulses;\n * on fire one `<prefix>:fired` event carries the latest args (relayed by state\n * through the command-token / event-token protocols).\n *\n * A given instance is meant to be used for one surface at a time. Because each\n * surface keeps its own field (`_value` vs `_lastArgs`), the getters never\n * pollute each other; if both are driven on one instance the *last* scheduled\n * signal wins (lodash's last-args semantics).\n *\n * Throttle is the same engine with `maxWait === wait` (and `leading` on by\n * default), so `<wcs-throttle>` reuses this class with a different `eventPrefix`.\n */\nexport class DebounceCore extends EventTarget {\n // The static contract advertises the *default* `wcs-debounce:*` event names. A\n // headless Core constructed with a non-default `eventPrefix` (e.g.\n // `\"wcs-throttle\"`) dispatches under that prefix, so its events won't match\n // this metadata — rebuild the property table with `makeDebounceProperties(prefix)`\n // for that case. (The `<wcs-throttle>` Shell already overrides its own\n // `wcBindable` this way, so binding through an element is always consistent.)\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n private readonly _prefix: string;\n private _target: EventTarget;\n\n // Tuning (lodash knobs).\n private _wait: number = 0;\n private _leading: boolean = false;\n private _trailing: boolean = true;\n private _maxWait: number = 0;\n private _hasMaxWait: boolean = false;\n\n // Timing bookkeeping.\n private _lastCallTime: number | undefined = undefined;\n private _lastInvokeTime: number = 0;\n private _timerId: ReturnType<typeof setTimeout> | null = null;\n\n // Last-wins pending payload. `_pendingKind === null` doubles as the \"consumed /\n // empty\" sentinel (lodash clears `lastArgs` in invokeFunc): a trailing edge with\n // no fresh call since the last fire sees `null` and does not re-fire, which is\n // what stops a single leading pulse from also firing on the trailing edge.\n private _pendingKind: PendingKind = null;\n private _pendingValue: any = undefined;\n private _pendingArgs: any[] | undefined = undefined;\n\n // Observable state (getter backing).\n private _value: any = undefined;\n private _lastArgs: any[] = [];\n private _pending: boolean = false;\n\n constructor(prefix: string = \"wcs-debounce\", target?: EventTarget, options?: DebounceOptions) {\n super();\n this._prefix = prefix;\n this._target = target ?? this;\n if (options) {\n this.configure(options);\n }\n }\n\n // --- Configuration ---\n\n /**\n * Update the tuning knobs. The Shell calls this with the element's current\n * attributes before each schedule, so live attribute edits take effect on the\n * next signal. `maxWait` is clamped to at least `wait` (lodash semantics); an\n * absent / invalid `maxWait` disables maxWait entirely.\n */\n configure(options: DebounceOptions = {}): void {\n if (typeof options.wait === \"number\" && Number.isFinite(options.wait) && options.wait >= 0) {\n this._wait = options.wait;\n }\n if (typeof options.leading === \"boolean\") {\n this._leading = options.leading;\n }\n if (typeof options.trailing === \"boolean\") {\n this._trailing = options.trailing;\n }\n const mw = options.maxWait;\n if (typeof mw === \"number\" && Number.isFinite(mw) && mw >= 0) {\n this._maxWait = Math.max(mw, this._wait);\n this._hasMaxWait = true;\n } else {\n this._maxWait = 0;\n this._hasMaxWait = false;\n }\n }\n\n // --- Observable getters ---\n\n get value(): any {\n return this._value;\n }\n\n get fired(): any[] {\n return this._lastArgs;\n }\n\n get pending(): boolean {\n return this._pending;\n }\n\n // --- Public entry points ---\n\n /** Value surface: schedule a settle carrying `value` (last write wins). */\n setSource(value: any): void {\n this._schedule(\"value\", value, undefined);\n }\n\n /** Signal surface: coalesce a pulse carrying `args` (last call wins). */\n trigger(...args: any[]): void {\n this._schedule(\"signal\", undefined, args);\n }\n\n /** Drop any pending fire without emitting. Getters keep their last values. */\n cancel(): void {\n this._clearTimer();\n this._lastInvokeTime = 0;\n this._lastCallTime = undefined;\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n /**\n * Emit any buffered payload immediately, then clear pending. Unlike lodash's\n * `flush` (which honours `trailing`), this fires whatever is buffered — the\n * command's intent is \"publish now\" — but is a no-op when nothing is pending.\n */\n flush(): void {\n if (this._timerId === null && this._pendingKind === null) return;\n const now = Date.now();\n this._clearTimer();\n if (this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n // --- Engine (lodash port) ---\n\n private _schedule(kind: Exclude<PendingKind, null>, value: any, args: any[] | undefined): void {\n const now = Date.now();\n const isInvoking = this._shouldInvoke(now);\n\n this._pendingKind = kind;\n if (kind === \"value\") {\n this._pendingValue = value;\n } else {\n this._pendingArgs = args;\n }\n this._lastCallTime = now;\n this._setPending(true);\n\n if (isInvoking) {\n if (this._timerId === null) {\n this._leadingEdge(now);\n return;\n }\n if (this._hasMaxWait) {\n // Continuous input that has reached maxWait: restart the steady timer and\n // invoke now so a fire happens at least every maxWait ms (throttle path).\n // Clear the pending handle first (lodash's \"tight loop\" branch does the\n // same) — overwriting `_timerId` without clearing would orphan the old\n // timer and let it fire spuriously later.\n this._clearTimer();\n this._timerId = setTimeout(this._timerExpired, this._wait);\n this._invoke(now);\n return;\n }\n }\n if (this._timerId === null) {\n this._timerId = setTimeout(this._timerExpired, this._wait);\n }\n }\n\n private _shouldInvoke(now: number): boolean {\n if (this._lastCallTime === undefined) return true;\n const timeSinceLastCall = now - this._lastCallTime;\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n return (\n timeSinceLastCall >= this._wait ||\n timeSinceLastCall < 0 ||\n (this._hasMaxWait && timeSinceLastInvoke >= this._maxWait)\n );\n }\n\n private _remainingWait(now: number): number {\n const timeSinceLastCall = now - (this._lastCallTime as number);\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n const timeWaiting = this._wait - timeSinceLastCall;\n return this._hasMaxWait\n ? Math.min(timeWaiting, this._maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n private _timerExpired = (): void => {\n const now = Date.now();\n if (this._shouldInvoke(now)) {\n this._trailingEdge(now);\n return;\n }\n // Fired before the quiet period elapsed (a later call moved the deadline) —\n // re-arm for the remaining time instead of settling now.\n this._timerId = setTimeout(this._timerExpired, this._remainingWait(now));\n };\n\n private _leadingEdge(now: number): void {\n this._lastInvokeTime = now;\n this._timerId = setTimeout(this._timerExpired, this._wait);\n if (this._leading) {\n this._invoke(now);\n }\n }\n\n private _trailingEdge(now: number): void {\n this._timerId = null;\n // Only fire when there is an unconsumed payload (a call arrived since the last\n // invoke). After a lone leading fire `_pendingKind` is null, so a single pulse\n // does not double-fire on its trailing edge.\n if (this._trailing && this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n private _invoke(now: number): void {\n this._lastInvokeTime = now;\n const kind = this._pendingKind;\n if (kind === \"value\") {\n this._value = this._pendingValue;\n this._dispatch(`${this._prefix}:settled`, { value: this._value });\n } else if (kind === \"signal\") {\n this._lastArgs = this._pendingArgs ?? [];\n this._dispatch(`${this._prefix}:fired`, { args: this._lastArgs });\n }\n // Mark consumed (mirrors lodash clearing `lastArgs`).\n this._pendingKind = null;\n }\n\n private _setPending(pending: boolean): void {\n if (this._pending === pending) return;\n this._pending = pending;\n this._dispatch(`${this._prefix}:pending-changed`, pending);\n }\n\n private _dispatch(type: string, detail: any): void {\n this._target.dispatchEvent(new CustomEvent(type, { detail, bubbles: true }));\n }\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n clearTimeout(this._timerId);\n this._timerId = null;\n }\n }\n}\n","import { config } from \"./config.js\";\n\nlet registered = false;\n\ninterface Triggerable extends Element {\n trigger(...args: unknown[]): void;\n}\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const id = triggerElement.getAttribute(config.triggerAttribute);\n if (!id) return;\n\n // Resolve the registered constructors at call time (avoids a components ⇄\n // autoTrigger import cycle, mirroring <wcs-timer>). The DOM trigger fires a\n // single coalesced pulse on the referenced <wcs-debounce> / <wcs-throttle>.\n const DebounceCtor = customElements.get(config.tagNames.debounce);\n const ThrottleCtor = customElements.get(config.tagNames.throttle);\n const el = document.getElementById(id);\n if (!el) return;\n const isDebounce = DebounceCtor && el instanceof DebounceCtor;\n const isThrottle = ThrottleCtor && el instanceof ThrottleCtor;\n if (!isDebounce && !isThrottle) return;\n\n // Suppress the element's default action so a debounce can fire without\n // navigating. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (el as unknown as Triggerable).trigger();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { DebounceCore } from \"../core/DebounceCore.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nconst DEFAULT_WAIT = 250;\n\n/**\n * `<wcs-debounce>` — declarative debounce. See {@link DebounceCore} for the\n * engine. The `eventPrefix` defaults to `\"wcs-debounce\"`; `<wcs-throttle>`\n * subclasses this with `\"wcs-throttle\"` and throttle defaults.\n */\nexport class Debounce extends HTMLElement {\n static hasConnectedCallbackPromise = false;\n protected static eventPrefix = \"wcs-debounce\";\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n // `source` is the value-surface input (its debounced echo comes back on the\n // `value` property). `trigger` / `cancel` / `flush` are commands from the\n // Core. No momentary boolean `trigger` property exists — the signal surface\n // is driven by the `trigger` command (command-token) or a DOM click\n // (autoTrigger), which sidesteps the attribute/method name clash that forced\n // <wcs-geo>'s watch → watchPosition rename.\n inputs: [\n { name: \"source\" },\n { name: \"wait\", attribute: \"wait\" },\n { name: \"leading\", attribute: \"leading\" },\n { name: \"trailing\", attribute: \"trailing\" },\n { name: \"maxWait\", attribute: \"max-wait\" },\n ],\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n protected _core: DebounceCore;\n private _source: any = undefined;\n\n constructor() {\n super();\n this._core = new DebounceCore((this.constructor as typeof Debounce).eventPrefix, this);\n }\n\n // --- Attribute accessors ---\n\n get wait(): number {\n const attr = this.getAttribute(\"wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultWait();\n // Strict parse via Number() (\"100px\" -> NaN, not 100). Fall back to the\n // default for any non-finite or negative value.\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultWait();\n }\n\n set wait(value: number) {\n this.setAttribute(\"wait\", String(value));\n }\n\n get leading(): boolean {\n return this.hasAttribute(\"leading\");\n }\n\n set leading(value: boolean) {\n if (value) {\n this.setAttribute(\"leading\", \"\");\n } else {\n this.removeAttribute(\"leading\");\n }\n }\n\n // `trailing` defaults to true; the boolean `no-trailing` attribute opts out (a\n // bare `trailing` attribute can't express \"false\", so the negative flag carries\n // the override).\n get trailing(): boolean {\n return !this.hasAttribute(\"no-trailing\");\n }\n\n set trailing(value: boolean) {\n if (value) {\n this.removeAttribute(\"no-trailing\");\n } else {\n this.setAttribute(\"no-trailing\", \"\");\n }\n }\n\n get maxWait(): number | undefined {\n const attr = this.getAttribute(\"max-wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultMaxWait();\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultMaxWait();\n }\n\n set maxWait(value: number) {\n this.setAttribute(\"max-wait\", String(value));\n }\n\n // --- Value-surface input ---\n\n get source(): any {\n return this._source;\n }\n\n set source(value: any) {\n this._source = value;\n this._core.configure(this._options());\n this._core.setSource(value);\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get fired(): any[] {\n return this._core.fired;\n }\n\n get pending(): boolean {\n return this._core.pending;\n }\n\n // --- Commands ---\n\n trigger(...args: any[]): void {\n this._core.configure(this._options());\n this._core.trigger(...args);\n }\n\n cancel(): void {\n this._core.cancel();\n }\n\n flush(): void {\n this._core.flush();\n }\n\n // --- Internal ---\n\n // Overridden by <wcs-throttle> to bias the defaults toward throttle (leading\n // on, maxWait pinned to wait).\n protected _defaultWait(): number {\n return DEFAULT_WAIT;\n }\n\n // Resolves the effective `leading` value (not a static default). It is a method\n // rather than reading `this.leading` directly because <wcs-throttle> inverts the\n // default (on, opt out via `no-leading`) while sharing the inherited `leading`\n // attribute setter — overriding the getter alone would desync getter and setter.\n protected _resolveLeading(): boolean {\n return this.leading;\n }\n\n protected _defaultMaxWait(): number | undefined {\n return undefined;\n }\n\n protected _options(): DebounceOptions {\n return {\n wait: this.wait,\n leading: this._resolveLeading(),\n trailing: this.trailing,\n maxWait: this.maxWait,\n };\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n }\n\n disconnectedCallback(): void {\n // Drop any in-flight timer so a detached element leaks nothing.\n this._core.cancel();\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { Debounce } from \"./Debounce.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\n/**\n * `<wcs-throttle>` — the same {@link DebounceCore} engine biased to throttle:\n * `maxWait === wait` (a fire happens at least every `wait` ms under continuous\n * input) and `leading` on by default. It advertises its own `wcs-throttle:*`\n * event namespace (via `makeDebounceProperties(\"wcs-throttle\")`), and the Core\n * dispatches under that prefix because the constructor passes it through.\n */\nexport class Throttle extends Debounce {\n protected static eventPrefix = \"wcs-throttle\";\n static wcBindable: IWcBindable = {\n ...Debounce.wcBindable,\n properties: makeDebounceProperties(\"wcs-throttle\"),\n };\n\n // leading defaults on for throttle; `no-leading` opts out (symmetric with the\n // inherited `no-trailing`).\n protected _resolveLeading(): boolean {\n return !this.hasAttribute(\"no-leading\");\n }\n\n // Pin maxWait to wait so throttle fires on a steady cadence; an explicit\n // `max-wait` attribute still overrides via the inherited getter.\n protected _defaultMaxWait(): number | undefined {\n return this.wait;\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapDebounce(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { Debounce } from \"./components/Debounce.js\";\nimport { Throttle } from \"./components/Throttle.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.debounce)) {\n customElements.define(config.tagNames.debounce, Debounce);\n }\n if (!customElements.get(config.tagNames.throttle)) {\n customElements.define(config.tagNames.throttle, Throttle);\n }\n}\n"],"names":["_config","autoTrigger","triggerAttribute","tagNames","debounce","throttle","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","makeDebounceProperties","prefix","name","event","getter","e","detail","value","args","DebounceCore","EventTarget","static","protocol","version","properties","commands","_prefix","_target","_wait","_leading","_trailing","_maxWait","_hasMaxWait","_lastCallTime","undefined","_lastInvokeTime","_timerId","_pendingKind","_pendingValue","_pendingArgs","_value","_lastArgs","_pending","constructor","target","options","super","this","configure","wait","Number","isFinite","leading","trailing","mw","maxWait","Math","max","fired","pending","setSource","_schedule","trigger","cancel","_clearTimer","_setPending","flush","now","Date","_invoke","kind","isInvoking","_shouldInvoke","_leadingEdge","setTimeout","_timerExpired","timeSinceLastCall","timeSinceLastInvoke","_remainingWait","timeWaiting","min","_trailingEdge","_dispatch","type","dispatchEvent","CustomEvent","bubbles","clearTimeout","registered","handleClick","Element","triggerElement","closest","id","getAttribute","DebounceCtor","customElements","get","ThrottleCtor","el","document","getElementById","preventDefault","Debounce","HTMLElement","inputs","attribute","_core","_source","eventPrefix","attr","trim","_defaultWait","parsed","setAttribute","String","hasAttribute","removeAttribute","_defaultMaxWait","source","_options","_resolveLeading","connectedCallback","style","display","addEventListener","disconnectedCallback","Throttle","wcBindable","bootstrapDebounce","userConfig","partialConfig","assign","define"],"mappings":"AAWA,MAAMA,EAA2B,CAC/BC,aAAa,EACbC,iBAAkB,sBAClBC,SAAU,CACRC,SAAU,eACVC,SAAU,iBAId,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,EAAkBf,WAEfgB,IAId,OAHKF,IACHA,EAAeR,EAAWM,EAAUZ,KAE/Bc,CACT,CC7BM,SAAUG,EAAuBC,GACrC,MAAO,CACL,CAAEC,KAAM,QAASC,MAAO,GAAGF,YAAkBG,OAASC,GAAcA,EAAkBC,OAAOC,OAC7F,CAAEL,KAAM,QAASC,MAAO,GAAGF,UAAgBG,OAASC,GAAcA,EAAkBC,OAAOE,MAC3F,CAAEN,KAAM,UAAWC,MAAO,GAAGF,qBAEjC,CCKM,MAAOQ,UAAqBC,YAOhCC,kBAAiC,CAC/BC,SAAU,cACVC,QAAS,EACTC,WAAYd,EAAuB,gBACnCe,SAAU,CACR,CAAEb,KAAM,WACR,CAAEA,KAAM,UACR,CAAEA,KAAM,WAIKc,QACTC,QAGAC,MAAgB,EAChBC,UAAoB,EACpBC,WAAqB,EACrBC,SAAmB,EACnBC,aAAuB,EAGvBC,mBAAoCC,EACpCC,gBAA0B,EAC1BC,SAAiD,KAMjDC,aAA4B,KAC5BC,mBAAqBJ,EACrBK,kBAAkCL,EAGlCM,YAAcN,EACdO,UAAmB,GACnBC,UAAoB,EAE5B,WAAAC,CAAYhC,EAAiB,eAAgBiC,EAAsBC,GACjEC,QACAC,KAAKrB,QAAUf,EACfoC,KAAKpB,QAAUiB,GAAUG,KACrBF,GACFE,KAAKC,UAAUH,EAEnB,CAUA,SAAAG,CAAUH,EAA2B,IACP,iBAAjBA,EAAQI,MAAqBC,OAAOC,SAASN,EAAQI,OAASJ,EAAQI,MAAQ,IACvFF,KAAKnB,MAAQiB,EAAQI,MAEQ,kBAApBJ,EAAQO,UACjBL,KAAKlB,SAAWgB,EAAQO,SAEM,kBAArBP,EAAQQ,WACjBN,KAAKjB,UAAYe,EAAQQ,UAE3B,MAAMC,EAAKT,EAAQU,QACD,iBAAPD,GAAmBJ,OAAOC,SAASG,IAAOA,GAAM,GACzDP,KAAKhB,SAAWyB,KAAKC,IAAIH,EAAIP,KAAKnB,OAClCmB,KAAKf,aAAc,IAEnBe,KAAKhB,SAAW,EAChBgB,KAAKf,aAAc,EAEvB,CAIA,SAAIf,GACF,OAAO8B,KAAKP,MACd,CAEA,SAAIkB,GACF,OAAOX,KAAKN,SACd,CAEA,WAAIkB,GACF,OAAOZ,KAAKL,QACd,CAKA,SAAAkB,CAAU3C,GACR8B,KAAKc,UAAU,QAAS5C,OAAOiB,EACjC,CAGA,OAAA4B,IAAW5C,GACT6B,KAAKc,UAAU,cAAU3B,EAAWhB,EACtC,CAGA,MAAA6C,GACEhB,KAAKiB,cACLjB,KAAKZ,gBAAkB,EACvBY,KAAKd,mBAAgBC,EACrBa,KAAKV,aAAe,KACpBU,KAAKT,mBAAgBJ,EACrBa,KAAKR,kBAAeL,EACpBa,KAAKkB,aAAY,EACnB,CAOA,KAAAC,GACE,GAAsB,OAAlBnB,KAAKX,UAA2C,OAAtBW,KAAKV,aAAuB,OAC1D,MAAM8B,EAAMC,KAAKD,MACjBpB,KAAKiB,cACqB,OAAtBjB,KAAKV,cACPU,KAAKsB,QAAQF,GAEfpB,KAAKV,aAAe,KACpBU,KAAKT,mBAAgBJ,EACrBa,KAAKR,kBAAeL,EACpBa,KAAKkB,aAAY,EACnB,CAIQ,SAAAJ,CAAUS,EAAkCrD,EAAYC,GAC9D,MAAMiD,EAAMC,KAAKD,MACXI,EAAaxB,KAAKyB,cAAcL,GAWtC,GATApB,KAAKV,aAAeiC,EACP,UAATA,EACFvB,KAAKT,cAAgBrB,EAErB8B,KAAKR,aAAerB,EAEtB6B,KAAKd,cAAgBkC,EACrBpB,KAAKkB,aAAY,GAEbM,EAAY,CACd,GAAsB,OAAlBxB,KAAKX,SAEP,YADAW,KAAK0B,aAAaN,GAGpB,GAAIpB,KAAKf,YASP,OAHAe,KAAKiB,cACLjB,KAAKX,SAAWsC,WAAW3B,KAAK4B,cAAe5B,KAAKnB,YACpDmB,KAAKsB,QAAQF,EAGjB,CACsB,OAAlBpB,KAAKX,WACPW,KAAKX,SAAWsC,WAAW3B,KAAK4B,cAAe5B,KAAKnB,OAExD,CAEQ,aAAA4C,CAAcL,GACpB,QAA2BjC,IAAvBa,KAAKd,cAA6B,OAAO,EAC7C,MAAM2C,EAAoBT,EAAMpB,KAAKd,cAC/B4C,EAAsBV,EAAMpB,KAAKZ,gBACvC,OACEyC,GAAqB7B,KAAKnB,OAC1BgD,EAAoB,GACnB7B,KAAKf,aAAe6C,GAAuB9B,KAAKhB,QAErD,CAEQ,cAAA+C,CAAeX,GACrB,MAAMS,EAAoBT,EAAOpB,KAAKd,cAChC4C,EAAsBV,EAAMpB,KAAKZ,gBACjC4C,EAAchC,KAAKnB,MAAQgD,EACjC,OAAO7B,KAAKf,YACRwB,KAAKwB,IAAID,EAAahC,KAAKhB,SAAW8C,GACtCE,CACN,CAEQJ,cAAgB,KACtB,MAAMR,EAAMC,KAAKD,MACbpB,KAAKyB,cAAcL,GACrBpB,KAAKkC,cAAcd,GAKrBpB,KAAKX,SAAWsC,WAAW3B,KAAK4B,cAAe5B,KAAK+B,eAAeX,KAG7D,YAAAM,CAAaN,GACnBpB,KAAKZ,gBAAkBgC,EACvBpB,KAAKX,SAAWsC,WAAW3B,KAAK4B,cAAe5B,KAAKnB,OAChDmB,KAAKlB,UACPkB,KAAKsB,QAAQF,EAEjB,CAEQ,aAAAc,CAAcd,GACpBpB,KAAKX,SAAW,KAIZW,KAAKjB,WAAmC,OAAtBiB,KAAKV,cACzBU,KAAKsB,QAAQF,GAEfpB,KAAKV,aAAe,KACpBU,KAAKT,mBAAgBJ,EACrBa,KAAKR,kBAAeL,EACpBa,KAAKkB,aAAY,EACnB,CAEQ,OAAAI,CAAQF,GACdpB,KAAKZ,gBAAkBgC,EACvB,MAAMG,EAAOvB,KAAKV,aACL,UAATiC,GACFvB,KAAKP,OAASO,KAAKT,cACnBS,KAAKmC,UAAU,GAAGnC,KAAKrB,kBAAmB,CAAET,MAAO8B,KAAKP,UACtC,WAAT8B,IACTvB,KAAKN,UAAYM,KAAKR,cAAgB,GACtCQ,KAAKmC,UAAU,GAAGnC,KAAKrB,gBAAiB,CAAER,KAAM6B,KAAKN,aAGvDM,KAAKV,aAAe,IACtB,CAEQ,WAAA4B,CAAYN,GACdZ,KAAKL,WAAaiB,IACtBZ,KAAKL,SAAWiB,EAChBZ,KAAKmC,UAAU,GAAGnC,KAAKrB,0BAA2BiC,GACpD,CAEQ,SAAAuB,CAAUC,EAAcnE,GAC9B+B,KAAKpB,QAAQyD,cAAc,IAAIC,YAAYF,EAAM,CAAEnE,SAAQsE,SAAS,IACtE,CAEQ,WAAAtB,GACgB,OAAlBjB,KAAKX,WACPmD,aAAaxC,KAAKX,UAClBW,KAAKX,SAAW,KAEpB,EC5RF,IAAIoD,GAAa,EAMjB,SAASC,EAAY5E,GACnB,MAAM+B,EAAS/B,EAAM+B,OACrB,KAAMA,aAAkB8C,SAAU,OAElC,MAAMC,EAAiB/C,EAAOgD,QAAiB,IAAIpF,EAAOb,qBAC1D,IAAKgG,EAAgB,OAErB,MAAME,EAAKF,EAAeG,aAAatF,EAAOb,kBAC9C,IAAKkG,EAAI,OAKT,MAAME,EAAeC,eAAeC,IAAIzF,EAAOZ,SAASC,UAClDqG,EAAeF,eAAeC,IAAIzF,EAAOZ,SAASE,UAClDqG,EAAKC,SAASC,eAAeR,GACnC,IAAKM,EAAI,QACUJ,GAAgBI,aAAcJ,GAC9BG,GAAgBC,aAAcD,KAKjDrF,EAAMyF,iBACLH,EAA8BrC,UACjC,CCpBM,MAAOyC,UAAiBC,YAC5BnF,oCAAqC,EAC3BA,mBAAqB,eAC/BA,kBAAiC,CAC/BC,SAAU,cACVC,QAAS,EACTC,WAAYd,EAAuB,gBAOnC+F,OAAQ,CACN,CAAE7F,KAAM,UACR,CAAEA,KAAM,OAAQ8F,UAAW,QAC3B,CAAE9F,KAAM,UAAW8F,UAAW,WAC9B,CAAE9F,KAAM,WAAY8F,UAAW,YAC/B,CAAE9F,KAAM,UAAW8F,UAAW,aAEhCjF,SAAU,CACR,CAAEb,KAAM,WACR,CAAEA,KAAM,UACR,CAAEA,KAAM,WAIF+F,MACFC,aAAe1E,EAEvB,WAAAS,GACEG,QACAC,KAAK4D,MAAQ,IAAIxF,EAAc4B,KAAKJ,YAAgCkE,YAAa9D,KACnF,CAIA,QAAIE,GACF,MAAM6D,EAAO/D,KAAK+C,aAAa,QAC/B,GAAa,OAATgB,GAAiC,KAAhBA,EAAKC,OAAe,OAAOhE,KAAKiE,eAGrD,MAAMC,EAAS/D,OAAO4D,GACtB,OAAO5D,OAAOC,SAAS8D,IAAWA,GAAU,EAAIA,EAASlE,KAAKiE,cAChE,CAEA,QAAI/D,CAAKhC,GACP8B,KAAKmE,aAAa,OAAQC,OAAOlG,GACnC,CAEA,WAAImC,GACF,OAAOL,KAAKqE,aAAa,UAC3B,CAEA,WAAIhE,CAAQnC,GACNA,EACF8B,KAAKmE,aAAa,UAAW,IAE7BnE,KAAKsE,gBAAgB,UAEzB,CAKA,YAAIhE,GACF,OAAQN,KAAKqE,aAAa,cAC5B,CAEA,YAAI/D,CAASpC,GACPA,EACF8B,KAAKsE,gBAAgB,eAErBtE,KAAKmE,aAAa,cAAe,GAErC,CAEA,WAAI3D,GACF,MAAMuD,EAAO/D,KAAK+C,aAAa,YAC/B,GAAa,OAATgB,GAAiC,KAAhBA,EAAKC,OAAe,OAAOhE,KAAKuE,kBACrD,MAAML,EAAS/D,OAAO4D,GACtB,OAAO5D,OAAOC,SAAS8D,IAAWA,GAAU,EAAIA,EAASlE,KAAKuE,iBAChE,CAEA,WAAI/D,CAAQtC,GACV8B,KAAKmE,aAAa,WAAYC,OAAOlG,GACvC,CAIA,UAAIsG,GACF,OAAOxE,KAAK6D,OACd,CAEA,UAAIW,CAAOtG,GACT8B,KAAK6D,QAAU3F,EACf8B,KAAK4D,MAAM3D,UAAUD,KAAKyE,YAC1BzE,KAAK4D,MAAM/C,UAAU3C,EACvB,CAIA,SAAIA,GACF,OAAO8B,KAAK4D,MAAM1F,KACpB,CAEA,SAAIyC,GACF,OAAOX,KAAK4D,MAAMjD,KACpB,CAEA,WAAIC,GACF,OAAOZ,KAAK4D,MAAMhD,OACpB,CAIA,OAAAG,IAAW5C,GACT6B,KAAK4D,MAAM3D,UAAUD,KAAKyE,YAC1BzE,KAAK4D,MAAM7C,WAAW5C,EACxB,CAEA,MAAA6C,GACEhB,KAAK4D,MAAM5C,QACb,CAEA,KAAAG,GACEnB,KAAK4D,MAAMzC,OACb,CAMU,YAAA8C,GACR,OA7IiB,GA8InB,CAMU,eAAAS,GACR,OAAO1E,KAAKK,OACd,CAEU,eAAAkE,GAEV,CAEU,QAAAE,GACR,MAAO,CACLvE,KAAMF,KAAKE,KACXG,QAASL,KAAK0E,kBACdpE,SAAUN,KAAKM,SACfE,QAASR,KAAKQ,QAElB,CAIA,iBAAAmE,GACE3E,KAAK4E,MAAMC,QAAU,OACjBpH,EAAOd,cD3IT8F,IACJA,GAAa,EACbY,SAASyB,iBAAiB,QAASpC,IC4InC,CAEA,oBAAAqC,GAEE/E,KAAK4D,MAAM5C,QACb,EC5KI,MAAOgE,UAAiBxB,EAClBlF,mBAAqB,eAC/BA,kBAAiC,IAC5BkF,EAASyB,WACZxG,WAAYd,EAAuB,iBAK3B,eAAA+G,GACR,OAAQ1E,KAAKqE,aAAa,aAC5B,CAIU,eAAAE,GACR,OAAOvE,KAAKE,IACd,ECxBI,SAAUgF,EAAkBC,GN6C5B,IAAoBC,EM5CpBD,IN6CqC,kBADjBC,EM3CZD,GN4CaxI,cACvBD,EAAQC,YAAcyI,EAAczI,aAEQ,iBAAnCyI,EAAcxI,mBACvBF,EAAQE,iBAAmBwI,EAAcxI,kBAEvCwI,EAAcvI,UAChBK,OAAOmI,OAAO3I,EAAQG,SAAUuI,EAAcvI,UAEhDW,EAAe,MOtDVyF,eAAeC,IAAIzF,EAAOZ,SAASC,WACtCmG,eAAeqC,OAAO7H,EAAOZ,SAASC,SAAU0G,GAE7CP,eAAeC,IAAIzF,EAAOZ,SAASE,WACtCkG,eAAeqC,OAAO7H,EAAOZ,SAASE,SAAUiI,EDApD"}
|
|
1
|
+
{"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/wcBindableFactory.ts","../src/core/DebounceCore.ts","../src/autoTrigger.ts","../src/components/Debounce.ts","../src/components/Throttle.ts","../src/bootstrapDebounce.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n debounce: string;\n throttle: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-debouncetarget\",\n tagNames: {\n debounce: \"wcs-debounce\",\n throttle: \"wcs-throttle\",\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 (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindableProperty } from \"./types.js\";\n\n/**\n * Build the wc-bindable `properties` list for a debounce/throttle element, with\n * every event name derived from a single `prefix`. `<wcs-debounce>` uses\n * `\"wcs-debounce\"`, `<wcs-throttle>` uses `\"wcs-throttle\"`, so the two tags share\n * one engine (DebounceCore) yet advertise distinct event namespaces from one\n * source of truth — no hand-duplicated property tables (cf. the geolocation Shell\n * which overrode its wcBindable by hand).\n *\n * - `value` — the debounced value of the latest `source` write (value surface),\n * read from the `<prefix>:settled` event.\n * - `fired` — the coalesced args of the latest `trigger()` pulse (signal\n * surface), read from the `<prefix>:fired` event. Declared as a\n * property (not just an event) so state can subscribe via the\n * event-token protocol (`eventToken.fired: <name>`).\n * - `pending` — whether a debounce is currently in flight.\n */\nexport function makeDebounceProperties(prefix: string): IWcBindableProperty[] {\n return [\n { name: \"value\", event: `${prefix}:settled`, getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"fired\", event: `${prefix}:fired`, getter: (e: Event) => (e as CustomEvent).detail.args },\n { name: \"pending\", event: `${prefix}:pending-changed` },\n ];\n}\n","import { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\ntype PendingKind = \"value\" | \"signal\" | null;\n\n/**\n * Headless debounce/throttle primitive. A framework-agnostic port of lodash's\n * `debounce` algorithm (`shouldInvoke` / `leadingEdge` / `trailingEdge` /\n * `remainingWait`, timed via `Date.now()`), exposed through the wc-bindable\n * protocol.\n *\n * It coalesces a stream of *signals* and emits at most one per quiet period.\n * Two surfaces share the single timer:\n *\n * - **value** — writing {@link setSource} schedules a settle; on fire the\n * debounced value is published via the `<prefix>:settled` event and the\n * `value` getter. Wire it as `source: src; value: debounced`.\n * - **signal** — calling {@link trigger}`(...args)` coalesces a burst of pulses;\n * on fire one `<prefix>:fired` event carries the latest args (relayed by state\n * through the command-token / event-token protocols).\n *\n * A given instance is meant to be used for one surface at a time. Because each\n * surface keeps its own field (`_value` vs `_lastArgs`), the getters never\n * pollute each other; if both are driven on one instance the *last* scheduled\n * signal wins (lodash's last-args semantics).\n *\n * Throttle is the same engine with `maxWait === wait` (and `leading` on by\n * default), so `<wcs-throttle>` reuses this class with a different `eventPrefix`.\n */\nexport class DebounceCore extends EventTarget {\n // The static contract advertises the *default* `wcs-debounce:*` event names. A\n // headless Core constructed with a non-default `eventPrefix` (e.g.\n // `\"wcs-throttle\"`) dispatches under that prefix, so its events won't match\n // this metadata — rebuild the property table with `makeDebounceProperties(prefix)`\n // for that case. (The `<wcs-throttle>` Shell already overrides its own\n // `wcBindable` this way, so binding through an element is always consistent.)\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n private readonly _prefix: string;\n private _target: EventTarget;\n\n // Tuning (lodash knobs).\n private _wait: number = 0;\n private _leading: boolean = false;\n private _trailing: boolean = true;\n private _maxWait: number = 0;\n private _hasMaxWait: boolean = false;\n\n // Timing bookkeeping.\n private _lastCallTime: number | undefined = undefined;\n private _lastInvokeTime: number = 0;\n private _timerId: ReturnType<typeof setTimeout> | null = null;\n // Generation stamped onto the live timer at arm time, compared in\n // `_timerExpired` against `_gen` to drop callbacks that outlived a dispose().\n private _timerGen: number = 0;\n\n // Last-wins pending payload. `_pendingKind === null` doubles as the \"consumed /\n // empty\" sentinel (lodash clears `lastArgs` in invokeFunc): a trailing edge with\n // no fresh call since the last fire sees `null` and does not re-fire, which is\n // what stops a single leading pulse from also firing on the trailing edge.\n private _pendingKind: PendingKind = null;\n private _pendingValue: any = undefined;\n private _pendingArgs: any[] | undefined = undefined;\n\n // Observable state (getter backing).\n private _value: any = undefined;\n private _lastArgs: any[] = [];\n private _pending: boolean = false;\n\n // Generation guard (§3.4): bumped on dispose() so a timer that survives a\n // tear-down can no longer settle into a detached element. A pending timer is\n // also cleared by dispose() → cancel(), so the guard is defensive: it stops\n // any callback that has already been dequeued by the host event loop from\n // writing state after dispose().\n private _gen = 0;\n // SSR (§3.8): the debounce engine is purely timer-driven with no asynchronous\n // probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(prefix: string = \"wcs-debounce\", target?: EventTarget, options?: DebounceOptions) {\n super();\n this._prefix = prefix;\n this._target = target ?? this;\n if (options) {\n this.configure(options);\n }\n }\n\n // --- Lifecycle (§3.5 / §3.8) ---\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Debounce is command-driven (setSource / trigger schedule work on demand)\n // with no subscription to establish, so observe() is an idempotent no-op that\n // resolves once ready.\n observe(): Promise<void> {\n return this._ready;\n }\n\n // Tear down the pending timer and invalidate the generation so a stale timer\n // callback cannot fire after the element is detached.\n dispose(): void {\n this._gen++;\n this.cancel();\n }\n\n // --- Configuration ---\n\n /**\n * Update the tuning knobs. The Shell calls this with the element's current\n * attributes before each schedule, so live attribute edits take effect on the\n * next signal. `maxWait` is clamped to at least `wait` (lodash semantics); an\n * absent / invalid `maxWait` disables maxWait entirely.\n */\n configure(options: DebounceOptions = {}): void {\n if (typeof options.wait === \"number\" && Number.isFinite(options.wait) && options.wait >= 0) {\n this._wait = options.wait;\n }\n if (typeof options.leading === \"boolean\") {\n this._leading = options.leading;\n }\n if (typeof options.trailing === \"boolean\") {\n this._trailing = options.trailing;\n }\n const mw = options.maxWait;\n if (typeof mw === \"number\" && Number.isFinite(mw) && mw >= 0) {\n this._maxWait = Math.max(mw, this._wait);\n this._hasMaxWait = true;\n } else {\n this._maxWait = 0;\n this._hasMaxWait = false;\n }\n }\n\n // --- Observable getters ---\n\n get value(): any {\n return this._value;\n }\n\n get fired(): any[] {\n return this._lastArgs;\n }\n\n get pending(): boolean {\n return this._pending;\n }\n\n // --- Public entry points ---\n\n /** Value surface: schedule a settle carrying `value` (last write wins). */\n setSource(value: any): void {\n this._schedule(\"value\", value, undefined);\n }\n\n /** Signal surface: coalesce a pulse carrying `args` (last call wins). */\n trigger(...args: any[]): void {\n this._schedule(\"signal\", undefined, args);\n }\n\n /** Drop any pending fire without emitting. Getters keep their last values. */\n cancel(): void {\n this._clearTimer();\n this._lastInvokeTime = 0;\n this._lastCallTime = undefined;\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n /**\n * Emit any buffered payload immediately, then clear pending. Unlike lodash's\n * `flush` (which honours `trailing`), this fires whatever is buffered — the\n * command's intent is \"publish now\" — but is a no-op when nothing is pending.\n */\n flush(): void {\n if (this._timerId === null && this._pendingKind === null) return;\n const now = Date.now();\n this._clearTimer();\n if (this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n // --- Engine (lodash port) ---\n\n private _schedule(kind: Exclude<PendingKind, null>, value: any, args: any[] | undefined): void {\n const now = Date.now();\n const isInvoking = this._shouldInvoke(now);\n\n this._pendingKind = kind;\n if (kind === \"value\") {\n this._pendingValue = value;\n } else {\n this._pendingArgs = args;\n }\n this._lastCallTime = now;\n this._setPending(true);\n\n if (isInvoking) {\n if (this._timerId === null) {\n this._leadingEdge(now);\n return;\n }\n if (this._hasMaxWait) {\n // Continuous input that has reached maxWait: restart the steady timer and\n // invoke now so a fire happens at least every maxWait ms (throttle path).\n // Clear the pending handle first (lodash's \"tight loop\" branch does the\n // same) — overwriting `_timerId` without clearing would orphan the old\n // timer and let it fire spuriously later.\n this._clearTimer();\n this._armTimer(this._wait);\n this._invoke(now);\n return;\n }\n }\n if (this._timerId === null) {\n this._armTimer(this._wait);\n }\n }\n\n private _shouldInvoke(now: number): boolean {\n if (this._lastCallTime === undefined) return true;\n const timeSinceLastCall = now - this._lastCallTime;\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n return (\n timeSinceLastCall >= this._wait ||\n timeSinceLastCall < 0 ||\n (this._hasMaxWait && timeSinceLastInvoke >= this._maxWait)\n );\n }\n\n private _remainingWait(now: number): number {\n const timeSinceLastCall = now - (this._lastCallTime as number);\n const timeSinceLastInvoke = now - this._lastInvokeTime;\n const timeWaiting = this._wait - timeSinceLastCall;\n return this._hasMaxWait\n ? Math.min(timeWaiting, this._maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n private _timerExpired = (): void => {\n // §3.4 generation guard: a timer dequeued by the host before dispose() could\n // clear it must not settle into a torn-down element. Capture the generation\n // when the timer is scheduled (via `_armTimer`) and bail if it is stale.\n if (this._timerGen !== this._gen) return;\n const now = Date.now();\n if (this._shouldInvoke(now)) {\n this._trailingEdge(now);\n return;\n }\n // Fired before the quiet period elapsed (a later call moved the deadline) —\n // re-arm for the remaining time instead of settling now.\n this._armTimer(this._remainingWait(now));\n };\n\n private _leadingEdge(now: number): void {\n this._lastInvokeTime = now;\n this._armTimer(this._wait);\n if (this._leading) {\n this._invoke(now);\n }\n }\n\n private _trailingEdge(now: number): void {\n this._timerId = null;\n // Only fire when there is an unconsumed payload (a call arrived since the last\n // invoke). After a lone leading fire `_pendingKind` is null, so a single pulse\n // does not double-fire on its trailing edge.\n if (this._trailing && this._pendingKind !== null) {\n this._invoke(now);\n }\n this._pendingKind = null;\n this._pendingValue = undefined;\n this._pendingArgs = undefined;\n this._setPending(false);\n }\n\n private _invoke(now: number): void {\n this._lastInvokeTime = now;\n const kind = this._pendingKind;\n if (kind === \"value\") {\n this._value = this._pendingValue;\n this._dispatch(`${this._prefix}:settled`, { value: this._value });\n } else if (kind === \"signal\") {\n this._lastArgs = this._pendingArgs ?? [];\n this._dispatch(`${this._prefix}:fired`, { args: this._lastArgs });\n }\n // Mark consumed (mirrors lodash clearing `lastArgs`).\n this._pendingKind = null;\n }\n\n private _setPending(pending: boolean): void {\n if (this._pending === pending) return;\n this._pending = pending;\n this._dispatch(`${this._prefix}:pending-changed`, pending);\n }\n\n private _dispatch(type: string, detail: any): void {\n this._target.dispatchEvent(new CustomEvent(type, { detail, bubbles: true }));\n }\n\n // Arm the settle timer, stamping the current generation so a callback that the\n // host dequeues after a dispose() can detect it is stale (§3.4).\n private _armTimer(delay: number): void {\n this._timerGen = this._gen;\n this._timerId = setTimeout(this._timerExpired, delay);\n }\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n clearTimeout(this._timerId);\n this._timerId = null;\n }\n }\n}\n","import { config } from \"./config.js\";\n\nlet registered = false;\n\ninterface Triggerable extends Element {\n trigger(...args: unknown[]): void;\n}\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const id = triggerElement.getAttribute(config.triggerAttribute);\n if (!id) return;\n\n // Resolve the registered constructors at call time (avoids a components ⇄\n // autoTrigger import cycle, mirroring <wcs-timer>). The DOM trigger fires a\n // single coalesced pulse on the referenced <wcs-debounce> / <wcs-throttle>.\n const DebounceCtor = customElements.get(config.tagNames.debounce);\n const ThrottleCtor = customElements.get(config.tagNames.throttle);\n const el = document.getElementById(id);\n if (!el) return;\n const isDebounce = DebounceCtor && el instanceof DebounceCtor;\n const isThrottle = ThrottleCtor && el instanceof ThrottleCtor;\n if (!isDebounce && !isThrottle) return;\n\n // Suppress the element's default action so a debounce can fire without\n // navigating. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (el as unknown as Triggerable).trigger();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, DebounceOptions } from \"../types.js\";\nimport { DebounceCore } from \"../core/DebounceCore.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nconst DEFAULT_WAIT = 250;\n\n/**\n * `<wcs-debounce>` — declarative debounce. See {@link DebounceCore} for the\n * engine. The `eventPrefix` defaults to `\"wcs-debounce\"`; `<wcs-throttle>`\n * subclasses this with `\"wcs-throttle\"` and throttle defaults.\n */\nexport class Debounce extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n protected static eventPrefix = \"wcs-debounce\";\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: makeDebounceProperties(\"wcs-debounce\"),\n // `source` is the value-surface input (its debounced echo comes back on the\n // `value` property). `trigger` / `cancel` / `flush` are commands from the\n // Core. No momentary boolean `trigger` property exists — the signal surface\n // is driven by the `trigger` command (command-token) or a DOM click\n // (autoTrigger), which sidesteps the attribute/method name clash that forced\n // <wcs-geo>'s watch → watchPosition rename.\n inputs: [\n { name: \"source\" },\n { name: \"wait\", attribute: \"wait\" },\n { name: \"leading\", attribute: \"leading\" },\n { name: \"trailing\", attribute: \"trailing\" },\n { name: \"maxWait\", attribute: \"max-wait\" },\n ],\n commands: [\n { name: \"trigger\" },\n { name: \"cancel\" },\n { name: \"flush\" },\n ],\n };\n\n protected _core: DebounceCore;\n private _source: any = undefined;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new DebounceCore((this.constructor as typeof Debounce).eventPrefix, this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get wait(): number {\n const attr = this.getAttribute(\"wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultWait();\n // Strict parse via Number() (\"100px\" -> NaN, not 100). Fall back to the\n // default for any non-finite or negative value.\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultWait();\n }\n\n set wait(value: number) {\n this.setAttribute(\"wait\", String(value));\n }\n\n get leading(): boolean {\n return this.hasAttribute(\"leading\");\n }\n\n set leading(value: boolean) {\n if (value) {\n this.setAttribute(\"leading\", \"\");\n } else {\n this.removeAttribute(\"leading\");\n }\n }\n\n // `trailing` defaults to true; the boolean `no-trailing` attribute opts out (a\n // bare `trailing` attribute can't express \"false\", so the negative flag carries\n // the override).\n get trailing(): boolean {\n return !this.hasAttribute(\"no-trailing\");\n }\n\n set trailing(value: boolean) {\n if (value) {\n this.removeAttribute(\"no-trailing\");\n } else {\n this.setAttribute(\"no-trailing\", \"\");\n }\n }\n\n get maxWait(): number | undefined {\n const attr = this.getAttribute(\"max-wait\");\n if (attr === null || attr.trim() === \"\") return this._defaultMaxWait();\n const parsed = Number(attr);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : this._defaultMaxWait();\n }\n\n set maxWait(value: number) {\n this.setAttribute(\"max-wait\", String(value));\n }\n\n // --- Value-surface input ---\n\n get source(): any {\n return this._source;\n }\n\n set source(value: any) {\n this._source = value;\n this._core.configure(this._options());\n this._core.setSource(value);\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get fired(): any[] {\n return this._core.fired;\n }\n\n get pending(): boolean {\n return this._core.pending;\n }\n\n // --- Commands ---\n\n trigger(...args: any[]): void {\n this._core.configure(this._options());\n this._core.trigger(...args);\n }\n\n cancel(): void {\n this._core.cancel();\n }\n\n flush(): void {\n this._core.flush();\n }\n\n // --- Internal ---\n\n // Overridden by <wcs-throttle> to bias the defaults toward throttle (leading\n // on, maxWait pinned to wait).\n protected _defaultWait(): number {\n return DEFAULT_WAIT;\n }\n\n // Resolves the effective `leading` value (not a static default). It is a method\n // rather than reading `this.leading` directly because <wcs-throttle> inverts the\n // default (on, opt out via `no-leading`) while sharing the inherited `leading`\n // attribute setter — overriding the getter alone would desync getter and setter.\n protected _resolveLeading(): boolean {\n return this.leading;\n }\n\n protected _defaultMaxWait(): number | undefined {\n return undefined;\n }\n\n protected _options(): DebounceOptions {\n return {\n wait: this.wait,\n leading: this._resolveLeading(),\n trailing: this.trailing,\n maxWait: this.maxWait,\n };\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // §4.1/§4.4 Shell SSR: expose connectedCallbackPromise backed by observe().\n // observe() is a no-op resolving once ready (the engine is command-driven).\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n // Drop any in-flight timer so a detached element leaks nothing, and bump the\n // Core generation so a surviving timer callback cannot settle (§3.5).\n this._core.dispose();\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { Debounce } from \"./Debounce.js\";\nimport { makeDebounceProperties } from \"../wcBindableFactory.js\";\n\n/**\n * `<wcs-throttle>` — the same {@link DebounceCore} engine biased to throttle:\n * `maxWait === wait` (a fire happens at least every `wait` ms under continuous\n * input) and `leading` on by default. It advertises its own `wcs-throttle:*`\n * event namespace (via `makeDebounceProperties(\"wcs-throttle\")`), and the Core\n * dispatches under that prefix because the constructor passes it through.\n */\nexport class Throttle extends Debounce {\n protected static eventPrefix = \"wcs-throttle\";\n static wcBindable: IWcBindable = {\n ...Debounce.wcBindable,\n properties: makeDebounceProperties(\"wcs-throttle\"),\n };\n\n // leading defaults on for throttle; `no-leading` opts out (symmetric with the\n // inherited `no-trailing`).\n protected _resolveLeading(): boolean {\n return !this.hasAttribute(\"no-leading\");\n }\n\n // Pin maxWait to wait so throttle fires on a steady cadence; an explicit\n // `max-wait` attribute still overrides via the inherited getter.\n protected _defaultMaxWait(): number | undefined {\n return this.wait;\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapDebounce(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { Debounce } from \"./components/Debounce.js\";\nimport { Throttle } from \"./components/Throttle.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.debounce)) {\n customElements.define(config.tagNames.debounce, Debounce);\n }\n if (!customElements.get(config.tagNames.throttle)) {\n customElements.define(config.tagNames.throttle, Throttle);\n }\n}\n"],"names":["_config","autoTrigger","triggerAttribute","tagNames","debounce","throttle","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","makeDebounceProperties","prefix","name","event","getter","e","detail","value","args","DebounceCore","EventTarget","static","protocol","version","properties","commands","_prefix","_target","_wait","_leading","_trailing","_maxWait","_hasMaxWait","_lastCallTime","undefined","_lastInvokeTime","_timerId","_timerGen","_pendingKind","_pendingValue","_pendingArgs","_value","_lastArgs","_pending","_gen","_ready","Promise","resolve","constructor","target","options","super","this","configure","ready","observe","dispose","cancel","wait","Number","isFinite","leading","trailing","mw","maxWait","Math","max","fired","pending","setSource","_schedule","trigger","_clearTimer","_setPending","flush","now","Date","_invoke","kind","isInvoking","_shouldInvoke","_leadingEdge","_armTimer","timeSinceLastCall","timeSinceLastInvoke","_remainingWait","timeWaiting","min","_timerExpired","_trailingEdge","_dispatch","type","dispatchEvent","CustomEvent","bubbles","delay","setTimeout","clearTimeout","registered","handleClick","Element","triggerElement","closest","id","getAttribute","DebounceCtor","customElements","get","ThrottleCtor","el","document","getElementById","preventDefault","Debounce","HTMLElement","inputs","attribute","_core","_source","_connectedCallbackPromise","eventPrefix","connectedCallbackPromise","attr","trim","_defaultWait","parsed","setAttribute","String","hasAttribute","removeAttribute","_defaultMaxWait","source","_options","_resolveLeading","connectedCallback","style","display","addEventListener","disconnectedCallback","Throttle","wcBindable","bootstrapDebounce","userConfig","partialConfig","assign","define"],"mappings":"AAWA,MAAMA,EAA2B,CAC/BC,aAAa,EACbC,iBAAkB,sBAClBC,SAAU,CACRC,SAAU,eACVC,SAAU,iBAId,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,EAAkBf,WAEfgB,IAId,OAHKF,IACHA,EAAeR,EAAWM,EAAUZ,KAE/Bc,CACT,CC7BM,SAAUG,EAAuBC,GACrC,MAAO,CACL,CAAEC,KAAM,QAASC,MAAO,GAAGF,YAAkBG,OAASC,GAAcA,EAAkBC,OAAOC,OAC7F,CAAEL,KAAM,QAASC,MAAO,GAAGF,UAAgBG,OAASC,GAAcA,EAAkBC,OAAOE,MAC3F,CAAEN,KAAM,UAAWC,MAAO,GAAGF,qBAEjC,CCKM,MAAOQ,UAAqBC,YAOhCC,kBAAiC,CAC/BC,SAAU,cACVC,QAAS,EACTC,WAAYd,EAAuB,gBACnCe,SAAU,CACR,CAAEb,KAAM,WACR,CAAEA,KAAM,UACR,CAAEA,KAAM,WAIKc,QACTC,QAGAC,MAAgB,EAChBC,UAAoB,EACpBC,WAAqB,EACrBC,SAAmB,EACnBC,aAAuB,EAGvBC,mBAAoCC,EACpCC,gBAA0B,EAC1BC,SAAiD,KAGjDC,UAAoB,EAMpBC,aAA4B,KAC5BC,mBAAqBL,EACrBM,kBAAkCN,EAGlCO,YAAcP,EACdQ,UAAmB,GACnBC,UAAoB,EAOpBC,KAAO,EAGPC,OAAwBC,QAAQC,UAExC,WAAAC,CAAYrC,EAAiB,eAAgBsC,EAAsBC,GACjEC,QACAC,KAAK1B,QAAUf,EACfyC,KAAKzB,QAAUsB,GAAUG,KACrBF,GACFE,KAAKC,UAAUH,EAEnB,CAIA,SAAII,GACF,OAAOF,KAAKP,MACd,CAKA,OAAAU,GACE,OAAOH,KAAKP,MACd,CAIA,OAAAW,GACEJ,KAAKR,OACLQ,KAAKK,QACP,CAUA,SAAAJ,CAAUH,EAA2B,IACP,iBAAjBA,EAAQQ,MAAqBC,OAAOC,SAASV,EAAQQ,OAASR,EAAQQ,MAAQ,IACvFN,KAAKxB,MAAQsB,EAAQQ,MAEQ,kBAApBR,EAAQW,UACjBT,KAAKvB,SAAWqB,EAAQW,SAEM,kBAArBX,EAAQY,WACjBV,KAAKtB,UAAYoB,EAAQY,UAE3B,MAAMC,EAAKb,EAAQc,QACD,iBAAPD,GAAmBJ,OAAOC,SAASG,IAAOA,GAAM,GACzDX,KAAKrB,SAAWkC,KAAKC,IAAIH,EAAIX,KAAKxB,OAClCwB,KAAKpB,aAAc,IAEnBoB,KAAKrB,SAAW,EAChBqB,KAAKpB,aAAc,EAEvB,CAIA,SAAIf,GACF,OAAOmC,KAAKX,MACd,CAEA,SAAI0B,GACF,OAAOf,KAAKV,SACd,CAEA,WAAI0B,GACF,OAAOhB,KAAKT,QACd,CAKA,SAAA0B,CAAUpD,GACRmC,KAAKkB,UAAU,QAASrD,OAAOiB,EACjC,CAGA,OAAAqC,IAAWrD,GACTkC,KAAKkB,UAAU,cAAUpC,EAAWhB,EACtC,CAGA,MAAAuC,GACEL,KAAKoB,cACLpB,KAAKjB,gBAAkB,EACvBiB,KAAKnB,mBAAgBC,EACrBkB,KAAKd,aAAe,KACpBc,KAAKb,mBAAgBL,EACrBkB,KAAKZ,kBAAeN,EACpBkB,KAAKqB,aAAY,EACnB,CAOA,KAAAC,GACE,GAAsB,OAAlBtB,KAAKhB,UAA2C,OAAtBgB,KAAKd,aAAuB,OAC1D,MAAMqC,EAAMC,KAAKD,MACjBvB,KAAKoB,cACqB,OAAtBpB,KAAKd,cACPc,KAAKyB,QAAQF,GAEfvB,KAAKd,aAAe,KACpBc,KAAKb,mBAAgBL,EACrBkB,KAAKZ,kBAAeN,EACpBkB,KAAKqB,aAAY,EACnB,CAIQ,SAAAH,CAAUQ,EAAkC7D,EAAYC,GAC9D,MAAMyD,EAAMC,KAAKD,MACXI,EAAa3B,KAAK4B,cAAcL,GAWtC,GATAvB,KAAKd,aAAewC,EACP,UAATA,EACF1B,KAAKb,cAAgBtB,EAErBmC,KAAKZ,aAAetB,EAEtBkC,KAAKnB,cAAgB0C,EACrBvB,KAAKqB,aAAY,GAEbM,EAAY,CACd,GAAsB,OAAlB3B,KAAKhB,SAEP,YADAgB,KAAK6B,aAAaN,GAGpB,GAAIvB,KAAKpB,YASP,OAHAoB,KAAKoB,cACLpB,KAAK8B,UAAU9B,KAAKxB,YACpBwB,KAAKyB,QAAQF,EAGjB,CACsB,OAAlBvB,KAAKhB,UACPgB,KAAK8B,UAAU9B,KAAKxB,MAExB,CAEQ,aAAAoD,CAAcL,GACpB,QAA2BzC,IAAvBkB,KAAKnB,cAA6B,OAAO,EAC7C,MAAMkD,EAAoBR,EAAMvB,KAAKnB,cAC/BmD,EAAsBT,EAAMvB,KAAKjB,gBACvC,OACEgD,GAAqB/B,KAAKxB,OAC1BuD,EAAoB,GACnB/B,KAAKpB,aAAeoD,GAAuBhC,KAAKrB,QAErD,CAEQ,cAAAsD,CAAeV,GACrB,MAAMQ,EAAoBR,EAAOvB,KAAKnB,cAChCmD,EAAsBT,EAAMvB,KAAKjB,gBACjCmD,EAAclC,KAAKxB,MAAQuD,EACjC,OAAO/B,KAAKpB,YACRiC,KAAKsB,IAAID,EAAalC,KAAKrB,SAAWqD,GACtCE,CACN,CAEQE,cAAgB,KAItB,GAAIpC,KAAKf,YAAce,KAAKR,KAAM,OAClC,MAAM+B,EAAMC,KAAKD,MACbvB,KAAK4B,cAAcL,GACrBvB,KAAKqC,cAAcd,GAKrBvB,KAAK8B,UAAU9B,KAAKiC,eAAeV,KAG7B,YAAAM,CAAaN,GACnBvB,KAAKjB,gBAAkBwC,EACvBvB,KAAK8B,UAAU9B,KAAKxB,OAChBwB,KAAKvB,UACPuB,KAAKyB,QAAQF,EAEjB,CAEQ,aAAAc,CAAcd,GACpBvB,KAAKhB,SAAW,KAIZgB,KAAKtB,WAAmC,OAAtBsB,KAAKd,cACzBc,KAAKyB,QAAQF,GAEfvB,KAAKd,aAAe,KACpBc,KAAKb,mBAAgBL,EACrBkB,KAAKZ,kBAAeN,EACpBkB,KAAKqB,aAAY,EACnB,CAEQ,OAAAI,CAAQF,GACdvB,KAAKjB,gBAAkBwC,EACvB,MAAMG,EAAO1B,KAAKd,aACL,UAATwC,GACF1B,KAAKX,OAASW,KAAKb,cACnBa,KAAKsC,UAAU,GAAGtC,KAAK1B,kBAAmB,CAAET,MAAOmC,KAAKX,UACtC,WAATqC,IACT1B,KAAKV,UAAYU,KAAKZ,cAAgB,GACtCY,KAAKsC,UAAU,GAAGtC,KAAK1B,gBAAiB,CAAER,KAAMkC,KAAKV,aAGvDU,KAAKd,aAAe,IACtB,CAEQ,WAAAmC,CAAYL,GACdhB,KAAKT,WAAayB,IACtBhB,KAAKT,SAAWyB,EAChBhB,KAAKsC,UAAU,GAAGtC,KAAK1B,0BAA2B0C,GACpD,CAEQ,SAAAsB,CAAUC,EAAc3E,GAC9BoC,KAAKzB,QAAQiE,cAAc,IAAIC,YAAYF,EAAM,CAAE3E,SAAQ8E,SAAS,IACtE,CAIQ,SAAAZ,CAAUa,GAChB3C,KAAKf,UAAYe,KAAKR,KACtBQ,KAAKhB,SAAW4D,WAAW5C,KAAKoC,cAAeO,EACjD,CAEQ,WAAAvB,GACgB,OAAlBpB,KAAKhB,WACP6D,aAAa7C,KAAKhB,UAClBgB,KAAKhB,SAAW,KAEpB,ECxUF,IAAI8D,GAAa,EAMjB,SAASC,EAAYtF,GACnB,MAAMoC,EAASpC,EAAMoC,OACrB,KAAMA,aAAkBmD,SAAU,OAElC,MAAMC,EAAiBpD,EAAOqD,QAAiB,IAAI9F,EAAOb,qBAC1D,IAAK0G,EAAgB,OAErB,MAAME,EAAKF,EAAeG,aAAahG,EAAOb,kBAC9C,IAAK4G,EAAI,OAKT,MAAME,EAAeC,eAAeC,IAAInG,EAAOZ,SAASC,UAClD+G,EAAeF,eAAeC,IAAInG,EAAOZ,SAASE,UAClD+G,EAAKC,SAASC,eAAeR,GACnC,IAAKM,EAAI,QACUJ,GAAgBI,aAAcJ,GAC9BG,GAAgBC,aAAcD,KAKjD/F,EAAMmG,iBACLH,EAA8BtC,UACjC,CCpBM,MAAO0C,UAAiBC,YAC5B7F,oCAAqC,EAC3BA,mBAAqB,eAC/BA,kBAAiC,CAC/BC,SAAU,cACVC,QAAS,EACTC,WAAYd,EAAuB,gBAOnCyG,OAAQ,CACN,CAAEvG,KAAM,UACR,CAAEA,KAAM,OAAQwG,UAAW,QAC3B,CAAExG,KAAM,UAAWwG,UAAW,WAC9B,CAAExG,KAAM,WAAYwG,UAAW,YAC/B,CAAExG,KAAM,UAAWwG,UAAW,aAEhC3F,SAAU,CACR,CAAEb,KAAM,WACR,CAAEA,KAAM,UACR,CAAEA,KAAM,WAIFyG,MACFC,aAAepF,EACfqF,0BAA2CzE,QAAQC,UAE3D,WAAAC,GACEG,QACAC,KAAKiE,MAAQ,IAAIlG,EAAciC,KAAKJ,YAAgCwE,YAAapE,KACnF,CAEA,4BAAIqE,GACF,OAAOrE,KAAKmE,yBACd,CAIA,QAAI7D,GACF,MAAMgE,EAAOtE,KAAKoD,aAAa,QAC/B,GAAa,OAATkB,GAAiC,KAAhBA,EAAKC,OAAe,OAAOvE,KAAKwE,eAGrD,MAAMC,EAASlE,OAAO+D,GACtB,OAAO/D,OAAOC,SAASiE,IAAWA,GAAU,EAAIA,EAASzE,KAAKwE,cAChE,CAEA,QAAIlE,CAAKzC,GACPmC,KAAK0E,aAAa,OAAQC,OAAO9G,GACnC,CAEA,WAAI4C,GACF,OAAOT,KAAK4E,aAAa,UAC3B,CAEA,WAAInE,CAAQ5C,GACNA,EACFmC,KAAK0E,aAAa,UAAW,IAE7B1E,KAAK6E,gBAAgB,UAEzB,CAKA,YAAInE,GACF,OAAQV,KAAK4E,aAAa,cAC5B,CAEA,YAAIlE,CAAS7C,GACPA,EACFmC,KAAK6E,gBAAgB,eAErB7E,KAAK0E,aAAa,cAAe,GAErC,CAEA,WAAI9D,GACF,MAAM0D,EAAOtE,KAAKoD,aAAa,YAC/B,GAAa,OAATkB,GAAiC,KAAhBA,EAAKC,OAAe,OAAOvE,KAAK8E,kBACrD,MAAML,EAASlE,OAAO+D,GACtB,OAAO/D,OAAOC,SAASiE,IAAWA,GAAU,EAAIA,EAASzE,KAAK8E,iBAChE,CAEA,WAAIlE,CAAQ/C,GACVmC,KAAK0E,aAAa,WAAYC,OAAO9G,GACvC,CAIA,UAAIkH,GACF,OAAO/E,KAAKkE,OACd,CAEA,UAAIa,CAAOlH,GACTmC,KAAKkE,QAAUrG,EACfmC,KAAKiE,MAAMhE,UAAUD,KAAKgF,YAC1BhF,KAAKiE,MAAMhD,UAAUpD,EACvB,CAIA,SAAIA,GACF,OAAOmC,KAAKiE,MAAMpG,KACpB,CAEA,SAAIkD,GACF,OAAOf,KAAKiE,MAAMlD,KACpB,CAEA,WAAIC,GACF,OAAOhB,KAAKiE,MAAMjD,OACpB,CAIA,OAAAG,IAAWrD,GACTkC,KAAKiE,MAAMhE,UAAUD,KAAKgF,YAC1BhF,KAAKiE,MAAM9C,WAAWrD,EACxB,CAEA,MAAAuC,GACEL,KAAKiE,MAAM5D,QACb,CAEA,KAAAiB,GACEtB,KAAKiE,MAAM3C,OACb,CAMU,YAAAkD,GACR,OAlJiB,GAmJnB,CAMU,eAAAS,GACR,OAAOjF,KAAKS,OACd,CAEU,eAAAqE,GAEV,CAEU,QAAAE,GACR,MAAO,CACL1E,KAAMN,KAAKM,KACXG,QAAST,KAAKiF,kBACdvE,SAAUV,KAAKU,SACfE,QAASZ,KAAKY,QAElB,CAIA,iBAAAsE,GACElF,KAAKmF,MAAMC,QAAU,OACjBhI,EAAOd,cDhJTwG,IACJA,GAAa,EACbY,SAAS2B,iBAAiB,QAAStC,KCmJjC/C,KAAKmE,0BAA4BnE,KAAKiE,MAAM9D,SAC9C,CAEA,oBAAAmF,GAGEtF,KAAKiE,MAAM7D,SACb,ECrLI,MAAOmF,UAAiB1B,EAClB5F,mBAAqB,eAC/BA,kBAAiC,IAC5B4F,EAAS2B,WACZpH,WAAYd,EAAuB,iBAK3B,eAAA2H,GACR,OAAQjF,KAAK4E,aAAa,aAC5B,CAIU,eAAAE,GACR,OAAO9E,KAAKM,IACd,ECxBI,SAAUmF,EAAkBC,GN6C5B,IAAoBC,EM5CpBD,IN6CqC,kBADjBC,EM3CZD,GN4CapJ,cACvBD,EAAQC,YAAcqJ,EAAcrJ,aAEQ,iBAAnCqJ,EAAcpJ,mBACvBF,EAAQE,iBAAmBoJ,EAAcpJ,kBAEvCoJ,EAAcnJ,UAChBK,OAAO+I,OAAOvJ,EAAQG,SAAUmJ,EAAcnJ,UAEhDW,EAAe,MOtDVmG,eAAeC,IAAInG,EAAOZ,SAASC,WACtC6G,eAAeuC,OAAOzI,EAAOZ,SAASC,SAAUoH,GAE7CP,eAAeC,IAAInG,EAAOZ,SAASE,WACtC4G,eAAeuC,OAAOzI,EAAOZ,SAASE,SAAU6I,EDApD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wcstack/debounce",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "Declarative debounce/throttle components for Web Components. Framework-agnostic signal coalescing via wc-bindable-protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.esm.js",
|