cereb 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,55 +1,43 @@
1
1
  import { Signal } from '../../core/signal.js';
2
2
  import { Stream } from '../../core/stream.js';
3
3
  import { ModifierKey } from './keyboard.js';
4
- export interface HeldValue {
5
- held: boolean;
4
+ interface HeldValue {
5
+ opened: boolean;
6
6
  }
7
- export interface HeldSignal extends Signal<"held", HeldValue> {
7
+ export interface HeldSignal extends Signal<"keyboard-held", HeldValue> {
8
8
  }
9
- export declare const HELD_SIGNAL_KIND: "held";
9
+ export declare const HELD_SIGNAL_KIND: "keyboard-held";
10
10
  export interface KeyboardHeldOptions {
11
11
  /**
12
12
  * The key to track. Case-insensitive.
13
- * @example 'z', 'Enter', 'Escape'
13
+ * @example 'z', 'Space', 'Escape'
14
14
  */
15
15
  key: string;
16
16
  /**
17
17
  * Modifier keys that must also be held. Uses OR logic.
18
+ *
19
+ * ⚠️ WARNING: On macOS, OS-level modifiers (especially Meta/Command) can swallow
20
+ * keyup events. This is a known platform limitation, not a bug. For reliable
21
+ * "hold to activate" behavior, prefer using non-modifier keys (Space, Shift, etc.)
22
+ * as the primary key instead of relying on modifier combinations.
23
+ *
18
24
  * @example ['meta', 'ctrl'] - matches if metaKey OR ctrlKey is pressed
19
25
  */
20
26
  modifiers?: ModifierKey[];
21
27
  }
22
28
  /**
23
- * Creates a stream that tracks whether a specific key (and optionally modifiers) is being held down.
24
- *
25
- * Automatically shares the keyboard stream for the same EventTarget, so multiple
26
- * keyboardHeld calls on the same target reuse the same underlying event listeners.
27
- *
28
- * This function correctly handles the case where modifier keys are released before
29
- * the main key. It tracks the main key's down/up state independently and checks
30
- * modifier states from each keyboard event.
31
- *
32
- * @param target - EventTarget to listen for keyboard events (e.g., window, document, element)
33
- * @param options - Key and modifier configuration
34
- * @returns Stream that emits { held: true } when conditions are met, { held: false } otherwise
29
+ * Tracks whether a specific key (with optional modifiers) is being held down.
30
+ * Emits only when state changes.
35
31
  *
36
32
  * @example
37
33
  * ```typescript
38
- * // Track if Ctrl+Z or Cmd+Z is held
39
- * const isZoomModeHeld$ = keyboardHeld(window, {
40
- * key: 'z',
41
- * modifiers: ['meta', 'ctrl']
42
- * });
43
- *
44
- * // Multiple calls on same target share the keyboard stream
45
- * const isXHeld$ = keyboardHeld(window, { key: 'x' });
34
+ * // Prefer: use non-modifier key for reliable hold detection
35
+ * const spaceHeld$ = keyboardHeld(window, { key: 'Space' });
46
36
  *
47
- * // Use with when() operator
48
- * pipe(
49
- * wheel(element),
50
- * when(isZoomModeHeld$)
51
- * ).subscribe(...)
37
+ * // Caution: modifier combos may miss keyup on macOS
38
+ * const cmdZHeld$ = keyboardHeld(window, { key: 'z', modifiers: ['meta'] });
52
39
  * ```
53
40
  */
54
41
  export declare function keyboardHeld(target: EventTarget, options: KeyboardHeldOptions): Stream<HeldSignal>;
42
+ export {};
55
43
  //# sourceMappingURL=keyboard-held.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-held.d.ts","sourceRoot":"","sources":["../../../src/browser/keyboard/keyboard-held.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAG3D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,UAAW,SAAQ,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;CAAG;AAEhE,eAAO,MAAM,gBAAgB,EAAG,MAAe,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;CAC3B;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,mBAAmB,GAC3B,MAAM,CAAC,UAAU,CAAC,CAkDpB"}
1
+ {"version":3,"file":"keyboard-held.d.ts","sourceRoot":"","sources":["../../../src/browser/keyboard/keyboard-held.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,UAAU,SAAS;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAW,SAAQ,MAAM,CAAC,eAAe,EAAE,SAAS,CAAC;CAAG;AAEzE,eAAO,MAAM,gBAAgB,EAAG,eAAwB,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,mBAAmB,GAC3B,MAAM,CAAC,UAAU,CAAC,CA+EpB"}
@@ -2,39 +2,21 @@ import { Stream } from '../../core/stream.js';
2
2
  import { KeyboardSignal } from './keyboard-signal.js';
3
3
  export type ModifierKey = "meta" | "ctrl" | "alt" | "shift";
4
4
  export interface KeyboardOptions {
5
- /**
6
- * Filter by key value(s). Uses OR logic if array.
7
- * Comparison is case-insensitive.
8
- * @example 'z' or ['+', '-', '=']
9
- */
5
+ /** Filter by key value(s). Case-insensitive. Uses OR logic if array. */
10
6
  key?: string | string[];
11
- /**
12
- * Filter by modifier keys. Uses OR logic (matches if any is pressed).
13
- * @example ['meta', 'ctrl'] - matches if metaKey OR ctrlKey is pressed
14
- */
7
+ /** Filter by modifier keys. Uses OR logic. */
15
8
  modifiers?: ModifierKey[];
16
- /**
17
- * If true, calls preventDefault() on matching events.
18
- * @default false
19
- */
9
+ /** If true, calls preventDefault() on matching events. @default false */
20
10
  preventDefault?: boolean;
11
+ /** If true, allows repeated keydown events. @default false */
12
+ allowRepeat?: boolean;
21
13
  }
22
14
  /**
23
- * Creates a stream of keyboard signals from keydown and keyup events on the target.
24
- * Optionally filters by key and/or modifier keys.
15
+ * Creates a keyboard signal stream. Shares underlying listeners per EventTarget.
25
16
  *
26
17
  * @example
27
- * ```typescript
28
- * // All keyboard events
29
- * keyboard(window).subscribe(signal => {
30
- * console.log(signal.value.key, signal.value.phase);
31
- * });
32
- *
33
- * // Only +/- keys with Ctrl or Cmd
34
- * keyboard(window, { key: ['+', '-'], modifiers: ['meta', 'ctrl'] }).subscribe(signal => {
35
- * // zoom in/out
36
- * });
37
- * ```
18
+ * keyboard(window).subscribe(signal => console.log(signal.value.key));
19
+ * keyboard(window, { key: 'z', modifiers: ['meta'] }).subscribe(handleUndo);
38
20
  */
39
21
  export declare function keyboard(target: EventTarget, options?: KeyboardOptions): Stream<KeyboardSignal>;
40
22
  //# sourceMappingURL=keyboard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../../src/browser/keyboard/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1F,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAE1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,CA2D/F"}
1
+ {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../../src/browser/keyboard/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,CA2D/F"}
@@ -0,0 +1,7 @@
1
+ import { Stream } from '../../core/stream.js';
2
+ import { KeyboardSignal } from './keyboard-signal.js';
3
+ /** Shared keyboard stream for the given target. */
4
+ export declare function getSharedKeyboard(target: EventTarget): Stream<KeyboardSignal>;
5
+ /** Shared keyboard stream filtered by a specific key. Filters out repeated events. */
6
+ export declare function getSharedKeyboardForKey(target: EventTarget, key: string): Stream<KeyboardSignal>;
7
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/browser/keyboard/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAyB1F,mDAAmD;AACnD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,CAO7E;AAED,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CA4BhG"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("./stream-Cp6eCZs2.cjs"),h=require("./recognizer-DbiEtBOM.cjs"),k=require("./share-DT0L7vCb.cjs"),Y=require("./types-BGR5Mhw9.cjs"),z=require("./single-pointer/pointer.cjs"),C="dom-event";function S(e){return h.createSignal(C,e)}function H(e,t,o){return f.createStream(r=>{const n=i=>{r.next(S(i))};return e.addEventListener(t,n,o),()=>{e.removeEventListener(t,n,o)}})}const y=["mousedown","mousemove","mouseup"];function M(e,t){return f.createStream(o=>{const r=n=>{o.next(S(n))};for(let n=0;n<y.length;n++){const i=y[n];e.addEventListener(i,r,t)}return()=>{for(let n=0;n<y.length;n++){const i=y[n];e.removeEventListener(i,r,t)}}})}const p=["pointerdown","pointermove","pointerup","pointercancel"];function v(e,t){return f.createStream(o=>{const r=n=>{o.next(S(n))};for(let n=0;n<p.length;n++){const i=p[n];e.addEventListener(i,r,t)}return()=>{for(let n=0;n<p.length;n++){const i=p[n];e.removeEventListener(i,r,t)}}})}const E=["touchstart","touchmove","touchend","touchcancel"];function G(e,t){return f.createStream(o=>{const r=n=>{o.next(S(n))};for(let n=0;n<E.length;n++){const i=E[n];e.addEventListener(i,r,t)}return()=>{for(let n=0;n<E.length;n++){const i=E[n];e.removeEventListener(i,r,t)}}})}const P="keyboard";function I(e){return h.createSignal(P,e)}function g(e,t){return I({phase:t,key:e.key,code:e.code,repeat:e.repeat,altKey:e.altKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,originalEvent:e})}function N(e,t){const o=t?.key?Array.isArray(t.key)?t.key.map(s=>s.toLowerCase()):[t.key.toLowerCase()]:null,r=t?.modifiers,n=t?.preventDefault??!1,i=s=>o?o.includes(s.toLowerCase()):!0,a=s=>!r||r.length===0?!0:r.some(u=>{switch(u){case"meta":return s.metaKey;case"ctrl":return s.ctrlKey;case"alt":return s.altKey;case"shift":return s.shiftKey;default:return!1}}),c=s=>i(s.key)&&a(s);return f.createStream(s=>{const u=m=>{const l=m;c(l)&&(n&&l.preventDefault(),s.next(g(l,"down")))},d=m=>{const l=m;c(l)&&(n&&l.preventDefault(),s.next(g(l,"up")))};return e.addEventListener("keydown",u),e.addEventListener("keyup",d),()=>{e.removeEventListener("keydown",u),e.removeEventListener("keyup",d)}})}const D="held",L=new WeakMap;function O(e){let t=L.get(e);return t||(t=k.share()(N(e)),L.set(e,t)),t}function X(e,t){const{key:o,modifiers:r}=t,n=o.toLowerCase(),i=O(e),a=c=>!r||r.length===0?!0:r.some(s=>{switch(s){case"meta":return c.metaKey;case"ctrl":return c.ctrlKey;case"alt":return c.altKey;case"shift":return c.shiftKey;default:return!1}});return f.createStream(c=>{let s=!1;return i.subscribe({next(u){try{const{key:d,phase:m}=u.value;d.toLowerCase()===n&&(s=m==="down");const l=a(u.value),W=s&&l;c.next(h.createSignal(D,{held:W}))}catch(d){c.error?.(d)}},error:c.error?.bind(c),complete:c.complete?.bind(c)})})}const R="multi-pointer";function F(e){return h.createSignal(R,e)}function q(e,t={}){const o={maxPointers:t.maxPointers??2},r=new Map;let n="idle";function i(a,c){return a===0?n==="active"&&c>0?"ended":"idle":"active"}return{process(a){const c=e(a,r,o);if(c===null)return null;const s=c.endedPointerIds;for(const l of s)r.delete(l);const u=Array.from(r.values()),d=i(u.length,s.length);n=d==="ended"?"idle":d;const m={phase:d,pointers:u,count:u.length};return F(m)},get isActive(){return r.size>0},get activeCount(){return r.size},reset(){r.clear(),n="idle"},dispose(){this.reset()}}}function U(e={}){function t(o,r,n){const i=o.value,a=`${i.pointerType}-${i.pointerId}`,c=[];switch(i.type){case"pointerdown":{if(r.size>=n.maxPointers)return null;r.set(a,K(i,"start"));break}case"pointermove":{if(!r.has(a))return null;r.set(a,K(i,"move"));break}case"pointerup":{if(!r.has(a))return null;r.set(a,K(i,"end")),c.push(a);break}case"pointercancel":{if(!r.has(a))return null;r.set(a,K(i,"cancel")),c.push(a);break}default:return null}return{pointers:r,endedPointerIds:c}}return q(t,e)}function _(e={}){return t=>f.createStream(o=>{const r=U(e),n=t.subscribe({next(i){const a=r.process(i);a&&o.next(a)},error(i){o.error?.(i)},complete(){o.complete?.()}});return()=>{n(),r.dispose()}})}function K(e,t){const o=t==="start"||t==="end"?Y.toSinglePointerButton(e.button):"none";return{id:`${e.pointerType}-${e.pointerId}`,phase:t,x:e.clientX,y:e.clientY,pageX:e.pageX,pageY:e.pageY,pointerType:V(e.pointerType),button:o,pressure:e.pressure}}function V(e){switch(e){case"mouse":return"mouse";case"touch":return"touch";case"pen":return"pen";default:return"unknown"}}function $(e,t={}){const o=v(e);return _(t)(o)}function B(e,t={}){const o=v(e);return z.singlePointerRecognizer(t)(o)}const x="wheel";function b(e){return h.createSignal(x,e)}function Z(e){switch(e){case 0:return"pixel";case 1:return"line";case 2:return"page";default:return"pixel"}}function A(e){return b({deltaX:e.deltaX,deltaY:e.deltaY,deltaZ:e.deltaZ,deltaMode:Z(e.deltaMode),x:e.clientX,y:e.clientY,pageX:e.pageX,pageY:e.pageY,altKey:e.altKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,originalEvent:e})}const w=new WeakMap;function j(e,t){let o=w.get(e);o||(o=new Map,w.set(e,o));let r=o.get(t);return r||(r=k.share()(J(e,t)),o.set(t,r)),r}function J(e,t){return f.createStream(o=>{const r=n=>{o.next(A(n))};return e.addEventListener("wheel",r,{passive:t}),()=>{e.removeEventListener("wheel",r)}})}function Q(e,t){const o=t?.passive??!0,r=t?.modifiers,n=t?.preventDefault??!1,i=j(e,o);if(!r?.length&&!n)return i;const a=c=>!r||r.length===0?!0:r.some(s=>{switch(s){case"meta":return c.metaKey;case"ctrl":return c.ctrlKey;case"alt":return c.altKey;case"shift":return c.shiftKey;default:return!1}});return f.createStream(c=>i.subscribe({next(s){try{a(s.value)&&(n&&s.value.originalEvent.preventDefault(),c.next(s))}catch(u){c.error?.(u)}},error:c.error?.bind(c),complete:c.complete?.bind(c)}))}function ee(...e){return t=>T(t,...e)}function T(e,...t){return t.reduce((o,r)=>r(o),e)}exports.createStream=f.createStream;exports.createSignal=h.createSignal;exports.setCerebDeviceId=h.setCerebDeviceId;exports.HELD_SIGNAL_KIND=D;exports.KEYBOARD_SIGNAL_KIND=P;exports.WHEEL_SIGNAL_KIND=x;exports.compose=ee;exports.createKeyboardSignal=I;exports.createKeyboardSignalFromEvent=g;exports.createWheelSignal=b;exports.createWheelSignalFromEvent=A;exports.domEvent=H;exports.keyboard=N;exports.keyboardHeld=X;exports.mouseEvents=M;exports.multiPointer=$;exports.multiPointerFromPointer=_;exports.pipe=T;exports.pointerEvents=v;exports.singlePointer=B;exports.touchEvents=G;exports.wheel=Q;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./stream-Cp6eCZs2.cjs"),m=require("./recognizer-DbiEtBOM.cjs"),I=require("./share-DT0L7vCb.cjs"),F=require("./types-BGR5Mhw9.cjs"),q=require("./single-pointer/pointer.cjs"),$="dom-event";function L(e){return m.createSignal($,e)}function U(e,r,o){return d.createStream(t=>{const n=a=>{t.next(L(a))};return e.addEventListener(r,n,o),()=>{e.removeEventListener(r,n,o)}})}const K=["mousedown","mousemove","mouseup"];function V(e,r){return d.createStream(o=>{const t=n=>{o.next(L(n))};for(let n=0;n<K.length;n++){const a=K[n];e.addEventListener(a,t,r)}return()=>{for(let n=0;n<K.length;n++){const a=K[n];e.removeEventListener(a,t,r)}}})}const S=["pointerdown","pointermove","pointerup","pointercancel"];function N(e,r){return d.createStream(o=>{const t=n=>{o.next(L(n))};for(let n=0;n<S.length;n++){const a=S[n];e.addEventListener(a,t,r)}return()=>{for(let n=0;n<S.length;n++){const a=S[n];e.removeEventListener(a,t,r)}}})}const E=["touchstart","touchmove","touchend","touchcancel"];function B(e,r){return d.createStream(o=>{const t=n=>{o.next(L(n))};for(let n=0;n<E.length;n++){const a=E[n];e.addEventListener(a,t,r)}return()=>{for(let n=0;n<E.length;n++){const a=E[n];e.removeEventListener(a,t,r)}}})}const _="keyboard";function M(e){return m.createSignal(_,e)}function P(e,r){return M({phase:r,key:e.key,code:e.code,repeat:e.repeat,altKey:e.altKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,originalEvent:e})}const b=new WeakMap,x=new WeakMap;function Z(e){return d.createStream(r=>{const o=n=>{r.next(P(n,"down"))},t=n=>{r.next(P(n,"up"))};return e.addEventListener("keydown",o),e.addEventListener("keyup",t),()=>{e.removeEventListener("keydown",o),e.removeEventListener("keyup",t)}})}function w(e){let r=b.get(e);return r||(r=I.share()(Z(e)),b.set(e,r)),r}function T(e,r){const o=r.toLowerCase();let t=x.get(e);t||(t=new Map,x.set(e,t));let n=t.get(o);if(!n){const a=w(e),s=d.createStream(i=>a.subscribe({next(u){u.value.repeat||u.value.key.toLowerCase()===o&&i.next(u)},error:i.error?.bind(i),complete:i.complete?.bind(i)}));n=I.share()(s),t.set(o,n)}return n}function j(e,r){if(!r)return w(e);const o=r.modifiers,t=r.preventDefault??!1,n=r.allowRepeat??!1,a=typeof r.key=="string",s=r.key&&Array.isArray(r.key)?r.key.map(c=>c.toLowerCase()):null,i=a?T(e,r.key):w(e);if(a&&!o&&!t&&!n)return i;const u=c=>s?s.includes(c.toLowerCase()):!0,f=c=>!o||o.length===0?!0:o.some(l=>{switch(l){case"meta":return c.metaKey;case"ctrl":return c.ctrlKey;case"alt":return c.altKey;case"shift":return c.shiftKey;default:return!1}});return d.createStream(c=>i.subscribe({next(l){const{key:y,repeat:k}=l.value;!n&&k||u(y)&&f(l.value)&&(t&&l.value.originalEvent.preventDefault(),c.next(l))},error:c.error?.bind(c),complete:c.complete?.bind(c)}))}const A="keyboard-held";function J(e,r){const{key:o,modifiers:t}=r,n=o.toLowerCase(),s=t&&t.length>0?w(e):T(e,o),i=new Set;if(t)for(const c of t)c==="meta"&&i.add("meta"),c==="ctrl"&&i.add("control"),c==="alt"&&i.add("alt"),c==="shift"&&i.add("shift");const u=c=>i.has(c.toLowerCase()),f=c=>!t||t.length===0?!0:t.some(l=>{switch(l){case"meta":return c.metaKey;case"ctrl":return c.ctrlKey;case"alt":return c.altKey;case"shift":return c.shiftKey;default:return!1}});return d.createStream(c=>{let l=!1,y;const k=h=>{h!==y&&(y=h,c.next(m.createSignal(A,{opened:h})))};return s.subscribe({next(h){try{const{key:p,phase:v,repeat:z}=h.value;if(z)return;const G=p.toLowerCase()===n,O=u(p);G?l=v==="down":(v==="down"||O&&v==="up")&&(l=!1);const X=f(h.value);k(l&&X)}catch(p){c.error?.(p)}},error:c.error?.bind(c),complete:c.complete?.bind(c)})})}const Q="multi-pointer";function ee(e){return m.createSignal(Q,e)}function te(e,r={}){const o={maxPointers:r.maxPointers??2},t=new Map;let n="idle";function a(s,i){return s===0?n==="active"&&i>0?"ended":"idle":"active"}return{process(s){const i=e(s,t,o);if(i===null)return null;const u=i.endedPointerIds;for(const y of u)t.delete(y);const f=Array.from(t.values()),c=a(f.length,u.length);n=c==="ended"?"idle":c;const l={phase:c,pointers:f,count:f.length};return ee(l)},get isActive(){return t.size>0},get activeCount(){return t.size},reset(){t.clear(),n="idle"},dispose(){this.reset()}}}function re(e={}){function r(o,t,n){const a=o.value,s=`${a.pointerType}-${a.pointerId}`,i=[];switch(a.type){case"pointerdown":{if(t.size>=n.maxPointers)return null;t.set(s,g(a,"start"));break}case"pointermove":{if(!t.has(s))return null;t.set(s,g(a,"move"));break}case"pointerup":{if(!t.has(s))return null;t.set(s,g(a,"end")),i.push(s);break}case"pointercancel":{if(!t.has(s))return null;t.set(s,g(a,"cancel")),i.push(s);break}default:return null}return{pointers:t,endedPointerIds:i}}return te(r,e)}function C(e={}){return r=>d.createStream(o=>{const t=re(e),n=r.subscribe({next(a){const s=t.process(a);s&&o.next(s)},error(a){o.error?.(a)},complete(){o.complete?.()}});return()=>{n(),t.dispose()}})}function g(e,r){const o=r==="start"||r==="end"?F.toSinglePointerButton(e.button):"none";return{id:`${e.pointerType}-${e.pointerId}`,phase:r,x:e.clientX,y:e.clientY,pageX:e.pageX,pageY:e.pageY,pointerType:ne(e.pointerType),button:o,pressure:e.pressure}}function ne(e){switch(e){case"mouse":return"mouse";case"touch":return"touch";case"pen":return"pen";default:return"unknown"}}function oe(e,r={}){const o=N(e);return C(r)(o)}function ce(e,r={}){const o=N(e);return q.singlePointerRecognizer(r)(o)}const W="wheel";function H(e){return m.createSignal(W,e)}function ae(e){switch(e){case 0:return"pixel";case 1:return"line";case 2:return"page";default:return"pixel"}}function R(e){return H({deltaX:e.deltaX,deltaY:e.deltaY,deltaZ:e.deltaZ,deltaMode:ae(e.deltaMode),x:e.clientX,y:e.clientY,pageX:e.pageX,pageY:e.pageY,altKey:e.altKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,originalEvent:e})}const D=new WeakMap;function ie(e,r){let o=D.get(e);o||(o=new Map,D.set(e,o));let t=o.get(r);return t||(t=I.share()(se(e,r)),o.set(r,t)),t}function se(e,r){return d.createStream(o=>{const t=n=>{o.next(R(n))};return e.addEventListener("wheel",t,{passive:r}),()=>{e.removeEventListener("wheel",t)}})}function ue(e,r){const o=r?.passive??!0,t=r?.modifiers,n=r?.preventDefault??!1,a=ie(e,o);if(!t?.length&&!n)return a;const s=i=>!t||t.length===0?!0:t.some(u=>{switch(u){case"meta":return i.metaKey;case"ctrl":return i.ctrlKey;case"alt":return i.altKey;case"shift":return i.shiftKey;default:return!1}});return d.createStream(i=>a.subscribe({next(u){try{s(u.value)&&(n&&u.value.originalEvent.preventDefault(),i.next(u))}catch(f){i.error?.(f)}},error:i.error?.bind(i),complete:i.complete?.bind(i)}))}function le(...e){return r=>Y(r,...e)}function Y(e,...r){return r.reduce((o,t)=>t(o),e)}exports.createStream=d.createStream;exports.createSignal=m.createSignal;exports.setCerebDeviceId=m.setCerebDeviceId;exports.HELD_SIGNAL_KIND=A;exports.KEYBOARD_SIGNAL_KIND=_;exports.WHEEL_SIGNAL_KIND=W;exports.compose=le;exports.createKeyboardSignal=M;exports.createKeyboardSignalFromEvent=P;exports.createWheelSignal=H;exports.createWheelSignalFromEvent=R;exports.domEvent=U;exports.keyboard=j;exports.keyboardHeld=J;exports.mouseEvents=V;exports.multiPointer=oe;exports.multiPointerFromPointer=C;exports.pipe=Y;exports.pointerEvents=N;exports.singlePointer=ce;exports.touchEvents=B;exports.wheel=ue;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/browser/dom-event/dom-event-signal.ts","../src/browser/dom-event/dom-event.ts","../src/browser/dom-event/mouse-events.ts","../src/browser/dom-event/pointer-events.ts","../src/browser/dom-event/touch-events.ts","../src/browser/keyboard/keyboard-signal.ts","../src/browser/keyboard/keyboard.ts","../src/browser/keyboard/keyboard-held.ts","../src/browser/multi-pointer/multi-pointer-signal.ts","../src/browser/multi-pointer/recognizer.ts","../src/browser/multi-pointer/recognizer-from-pointer.ts","../src/browser/multi-pointer/default-factory.ts","../src/browser/single-pointer/default-factory.ts","../src/browser/wheel/wheel-signal.ts","../src/browser/wheel/wheel.ts","../src/ochestrations/compose.ts","../src/ochestrations/pipe.ts"],"sourcesContent":["import { createSignal, type Signal } from \"../../core/signal.js\";\n\nexport interface DomEventSignal<E extends Event> extends Signal<\"dom-event\", E> {}\n\nexport const DOM_EVENT_SIGNAL_KIND = \"dom-event\" as const;\n\nexport function createDomEventSignal<E extends Event>(event: E): DomEventSignal<E> {\n return createSignal(DOM_EVENT_SIGNAL_KIND, event);\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\ntype AnyEventMap = Record<string, Event>;\n\n/**\n * Strongly-typed event target for custom event maps.\n * Useful for non-DOM EventTargets that still have named events.\n */\nexport type TypedEventTarget<M extends AnyEventMap> = EventTarget & {\n addEventListener<K extends keyof M>(\n type: K,\n listener: (event: M[K]) => void,\n options?: AddEventListenerOptions,\n ): void;\n removeEventListener<K extends keyof M>(\n type: K,\n listener: (event: M[K]) => void,\n options?: AddEventListenerOptions,\n ): void;\n};\n\nexport function domEvent<K extends keyof WindowEventMap>(\n target: Window,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<WindowEventMap[K]>>;\nexport function domEvent<K extends keyof DocumentEventMap>(\n target: Document,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<DocumentEventMap[K]>>;\nexport function domEvent<K extends keyof HTMLElementEventMap>(\n target: HTMLElement,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<HTMLElementEventMap[K]>>;\nexport function domEvent<K extends keyof SVGElementEventMap>(\n target: SVGElement,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<SVGElementEventMap[K]>>;\nexport function domEvent<M extends AnyEventMap, K extends keyof M>(\n target: TypedEventTarget<M>,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<M[K]>>;\nexport function domEvent<E extends Event = Event>(\n target: EventTarget,\n eventName: string,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<E>>;\nexport function domEvent<E extends Event = Event>(\n target: EventTarget,\n eventName: string,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<E>> {\n return createStream<DomEventSignal<E>>((observer) => {\n // NOTE: EventTarget's base signature expects an EventListener (Event),\n // so we accept Event and cast to the inferred event type for the signal.\n const handler: EventListener = (event) => {\n observer.next(createDomEventSignal(event as E));\n };\n\n target.addEventListener(eventName, handler, options);\n\n return () => {\n target.removeEventListener(eventName, handler, options);\n };\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\nconst MOUSE_EVENTS = [\"mousedown\", \"mousemove\", \"mouseup\"] as const;\n\nexport function mouseEvents(\n target: EventTarget,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<MouseEvent>> {\n return createStream<DomEventSignal<MouseEvent>>((observer) => {\n const handler = (event: Event) => {\n observer.next(createDomEventSignal(event as MouseEvent));\n };\n\n for (let i = 0; i < MOUSE_EVENTS.length; i++) {\n const eventName = MOUSE_EVENTS[i];\n target.addEventListener(eventName, handler, options);\n }\n\n return () => {\n for (let i = 0; i < MOUSE_EVENTS.length; i++) {\n const eventName = MOUSE_EVENTS[i];\n target.removeEventListener(eventName, handler, options);\n }\n };\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\nconst POINTER_EVENTS = [\"pointerdown\", \"pointermove\", \"pointerup\", \"pointercancel\"] as const;\n\nexport function pointerEvents(\n target: EventTarget,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<PointerEvent>> {\n return createStream<DomEventSignal<PointerEvent>>((observer) => {\n const handler = (event: Event) => {\n observer.next(createDomEventSignal(event as PointerEvent));\n };\n\n for (let i = 0; i < POINTER_EVENTS.length; i++) {\n const eventName = POINTER_EVENTS[i];\n target.addEventListener(eventName, handler, options);\n }\n\n return () => {\n for (let i = 0; i < POINTER_EVENTS.length; i++) {\n const eventName = POINTER_EVENTS[i];\n target.removeEventListener(eventName, handler, options);\n }\n };\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\nconst TOUCH_EVENTS = [\"touchstart\", \"touchmove\", \"touchend\", \"touchcancel\"] as const;\n\nexport function touchEvents(\n target: EventTarget,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<TouchEvent>> {\n return createStream((observer) => {\n const handler = (event: Event) => {\n observer.next(createDomEventSignal(event as TouchEvent));\n };\n\n for (let i = 0; i < TOUCH_EVENTS.length; i++) {\n const eventName = TOUCH_EVENTS[i];\n target.addEventListener(eventName, handler, options);\n }\n\n return () => {\n for (let i = 0; i < TOUCH_EVENTS.length; i++) {\n const eventName = TOUCH_EVENTS[i];\n target.removeEventListener(eventName, handler, options);\n }\n };\n });\n}\n","import { createSignal, type Signal } from \"../../core/signal.js\";\n\nexport type KeyboardPhase = \"down\" | \"up\";\n\n/**\n * Keyboard event data normalized into a consistent structure.\n * Provides both logical key (what the key represents) and physical code (where the key is).\n */\nexport interface KeyboardValue {\n phase: KeyboardPhase;\n /** Logical key value (e.g., \"+\", \"-\", \"a\", \"Meta\", \"Control\") */\n key: string;\n /** Physical key code (e.g., \"Equal\", \"Minus\", \"KeyA\", \"MetaLeft\") */\n code: string;\n /** True if this is a repeat event from holding the key down */\n repeat: boolean;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n /** Original DOM KeyboardEvent for advanced use cases like preventDefault */\n originalEvent: KeyboardEvent;\n}\n\nexport interface KeyboardSignal extends Signal<\"keyboard\", KeyboardValue> {}\n\nexport const KEYBOARD_SIGNAL_KIND = \"keyboard\" as const;\n\nexport function createKeyboardSignal(value: KeyboardValue): KeyboardSignal {\n return createSignal(KEYBOARD_SIGNAL_KIND, value);\n}\n\nexport function createKeyboardSignalFromEvent(\n event: KeyboardEvent,\n phase: KeyboardPhase,\n): KeyboardSignal {\n return createKeyboardSignal({\n phase,\n key: event.key,\n code: event.code,\n repeat: event.repeat,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n originalEvent: event,\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createKeyboardSignalFromEvent, type KeyboardSignal } from \"./keyboard-signal.js\";\n\nexport type ModifierKey = \"meta\" | \"ctrl\" | \"alt\" | \"shift\";\n\nexport interface KeyboardOptions {\n /**\n * Filter by key value(s). Uses OR logic if array.\n * Comparison is case-insensitive.\n * @example 'z' or ['+', '-', '=']\n */\n key?: string | string[];\n\n /**\n * Filter by modifier keys. Uses OR logic (matches if any is pressed).\n * @example ['meta', 'ctrl'] - matches if metaKey OR ctrlKey is pressed\n */\n modifiers?: ModifierKey[];\n\n /**\n * If true, calls preventDefault() on matching events.\n * @default false\n */\n preventDefault?: boolean;\n}\n\n/**\n * Creates a stream of keyboard signals from keydown and keyup events on the target.\n * Optionally filters by key and/or modifier keys.\n *\n * @example\n * ```typescript\n * // All keyboard events\n * keyboard(window).subscribe(signal => {\n * console.log(signal.value.key, signal.value.phase);\n * });\n *\n * // Only +/- keys with Ctrl or Cmd\n * keyboard(window, { key: ['+', '-'], modifiers: ['meta', 'ctrl'] }).subscribe(signal => {\n * // zoom in/out\n * });\n * ```\n */\nexport function keyboard(target: EventTarget, options?: KeyboardOptions): Stream<KeyboardSignal> {\n const keyList = options?.key\n ? Array.isArray(options.key)\n ? options.key.map((k) => k.toLowerCase())\n : [options.key.toLowerCase()]\n : null;\n const modifiers = options?.modifiers;\n const preventDefault = options?.preventDefault ?? false;\n\n const matchesKey = (key: string): boolean => {\n if (!keyList) return true;\n return keyList.includes(key.toLowerCase());\n };\n\n const matchesModifiers = (e: KeyboardEvent): boolean => {\n if (!modifiers || modifiers.length === 0) return true;\n return modifiers.some((mod) => {\n switch (mod) {\n case \"meta\":\n return e.metaKey;\n case \"ctrl\":\n return e.ctrlKey;\n case \"alt\":\n return e.altKey;\n case \"shift\":\n return e.shiftKey;\n default:\n return false;\n }\n });\n };\n\n const matches = (e: KeyboardEvent): boolean => {\n return matchesKey(e.key) && matchesModifiers(e);\n };\n\n return createStream<KeyboardSignal>((observer) => {\n const handleKeyDown = (e: Event) => {\n const event = e as KeyboardEvent;\n if (!matches(event)) return;\n if (preventDefault) event.preventDefault();\n observer.next(createKeyboardSignalFromEvent(event, \"down\"));\n };\n\n const handleKeyUp = (e: Event) => {\n const event = e as KeyboardEvent;\n if (!matches(event)) return;\n if (preventDefault) event.preventDefault();\n observer.next(createKeyboardSignalFromEvent(event, \"up\"));\n };\n\n target.addEventListener(\"keydown\", handleKeyDown);\n target.addEventListener(\"keyup\", handleKeyUp);\n\n return () => {\n target.removeEventListener(\"keydown\", handleKeyDown);\n target.removeEventListener(\"keyup\", handleKeyUp);\n };\n });\n}\n","import type { Signal } from \"../../core/signal.js\";\nimport { createSignal } from \"../../core/signal.js\";\nimport type { Stream } from \"../../core/stream.js\";\nimport { createStream } from \"../../core/stream.js\";\nimport { share } from \"../../operators/share.js\";\nimport { keyboard, type ModifierKey } from \"./keyboard.js\";\nimport type { KeyboardSignal } from \"./keyboard-signal.js\";\n\nexport interface HeldValue {\n held: boolean;\n}\n\nexport interface HeldSignal extends Signal<\"held\", HeldValue> {}\n\nexport const HELD_SIGNAL_KIND = \"held\" as const;\n\nexport interface KeyboardHeldOptions {\n /**\n * The key to track. Case-insensitive.\n * @example 'z', 'Enter', 'Escape'\n */\n key: string;\n\n /**\n * Modifier keys that must also be held. Uses OR logic.\n * @example ['meta', 'ctrl'] - matches if metaKey OR ctrlKey is pressed\n */\n modifiers?: ModifierKey[];\n}\n\n/**\n * Cache for shared keyboard streams per EventTarget.\n * Using WeakMap ensures streams are garbage collected when targets are removed.\n */\nconst sharedKeyboardStreams = new WeakMap<EventTarget, Stream<KeyboardSignal>>();\n\nfunction getSharedKeyboard(target: EventTarget): Stream<KeyboardSignal> {\n let stream = sharedKeyboardStreams.get(target);\n if (!stream) {\n stream = share<KeyboardSignal>()(keyboard(target));\n sharedKeyboardStreams.set(target, stream);\n }\n return stream;\n}\n\n/**\n * Creates a stream that tracks whether a specific key (and optionally modifiers) is being held down.\n *\n * Automatically shares the keyboard stream for the same EventTarget, so multiple\n * keyboardHeld calls on the same target reuse the same underlying event listeners.\n *\n * This function correctly handles the case where modifier keys are released before\n * the main key. It tracks the main key's down/up state independently and checks\n * modifier states from each keyboard event.\n *\n * @param target - EventTarget to listen for keyboard events (e.g., window, document, element)\n * @param options - Key and modifier configuration\n * @returns Stream that emits { held: true } when conditions are met, { held: false } otherwise\n *\n * @example\n * ```typescript\n * // Track if Ctrl+Z or Cmd+Z is held\n * const isZoomModeHeld$ = keyboardHeld(window, {\n * key: 'z',\n * modifiers: ['meta', 'ctrl']\n * });\n *\n * // Multiple calls on same target share the keyboard stream\n * const isXHeld$ = keyboardHeld(window, { key: 'x' });\n *\n * // Use with when() operator\n * pipe(\n * wheel(element),\n * when(isZoomModeHeld$)\n * ).subscribe(...)\n * ```\n */\nexport function keyboardHeld(\n target: EventTarget,\n options: KeyboardHeldOptions,\n): Stream<HeldSignal> {\n const { key, modifiers } = options;\n const keyLower = key.toLowerCase();\n const source = getSharedKeyboard(target);\n\n const checkModifiers = (value: KeyboardSignal[\"value\"]): boolean => {\n if (!modifiers || modifiers.length === 0) return true;\n return modifiers.some((mod) => {\n switch (mod) {\n case \"meta\":\n return value.metaKey;\n case \"ctrl\":\n return value.ctrlKey;\n case \"alt\":\n return value.altKey;\n case \"shift\":\n return value.shiftKey;\n default:\n return false;\n }\n });\n };\n\n return createStream((observer) => {\n let keyHeld = false;\n\n return source.subscribe({\n next(signal) {\n try {\n const { key: eventKey, phase } = signal.value;\n\n // Update key state only for the target key\n if (eventKey.toLowerCase() === keyLower) {\n keyHeld = phase === \"down\";\n }\n\n // Check modifier state from current event\n const modifierHeld = checkModifiers(signal.value);\n\n // Emit held: true only when both conditions are met\n const held = keyHeld && modifierHeld;\n observer.next(createSignal(HELD_SIGNAL_KIND, { held }));\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: observer.error?.bind(observer),\n complete: observer.complete?.bind(observer),\n });\n });\n}\n","import { createSignal, type Signal } from \"../../core/signal.js\";\nimport type {\n SinglePointerButton,\n SinglePointerPhase,\n SinglePointerType,\n} from \"../single-pointer/types.js\";\n\nexport interface MultiPointerSignal extends Signal<\"multi-pointer\", MultiPointer> {}\n\nexport const MULTI_POINTER_SIGNAL_KIND = \"multi-pointer\" as const;\n\n/**\n * Represents the complete state of all active pointers at a given moment.\n * Emitted as a snapshot whenever any pointer changes state.\n */\nexport interface MultiPointer {\n /** Session-level phase: tracks the overall multi-pointer interaction lifecycle */\n phase: MultiPointerPhase;\n /** Array of currently active pointers */\n pointers: readonly PointerInfo[];\n /** Total number of active pointers */\n count: number;\n}\n\n/**\n * Session-level phase for multi-pointer interactions:\n * - \"idle\": No active pointers\n * - \"active\": One or more pointers are active\n * - \"ended\": All pointers have ended (transition state)\n */\nexport type MultiPointerPhase = \"idle\" | \"active\" | \"ended\";\n\n/**\n * Information about a single pointer within a multi-pointer context.\n */\nexport interface PointerInfo {\n id: string;\n phase: SinglePointerPhase;\n x: number;\n y: number;\n pageX: number;\n pageY: number;\n pointerType: SinglePointerType;\n button: SinglePointerButton;\n /** 0.0 ~ 1.0, default 0.5 if unsupported */\n pressure: number;\n}\n\nexport function createMultiPointerSignal(multiPointer: MultiPointer): MultiPointerSignal {\n return createSignal(MULTI_POINTER_SIGNAL_KIND, multiPointer);\n}\n\nexport function createDefaultPointerInfo(): PointerInfo {\n return {\n id: \"\",\n phase: \"move\",\n x: 0,\n y: 0,\n pageX: 0,\n pageY: 0,\n pointerType: \"unknown\",\n button: \"none\",\n pressure: 0.5,\n };\n}\n","import type { Signal } from \"../../core/signal.js\";\nimport {\n createMultiPointerSignal,\n type MultiPointer,\n type MultiPointerPhase,\n type MultiPointerSignal,\n type PointerInfo,\n} from \"./multi-pointer-signal.js\";\nimport type { MultiPointerOptions } from \"./types.js\";\n\nexport interface MultiPointerRecognizer<InputSignal extends Signal> {\n process(event: InputSignal): MultiPointerSignal | null;\n readonly isActive: boolean;\n readonly activeCount: number;\n reset(): void;\n dispose(): void;\n}\n\n/**\n * Result of processing an input event.\n * - null: No signal should be emitted (e.g., pointer ignored due to maxPointers)\n * - pointers: Updated pointer map after processing the event\n */\nexport interface PointerUpdateResult {\n pointers: Map<string, PointerInfo>;\n endedPointerIds: string[];\n}\n\n/**\n * Creates a recognizer that tracks multiple pointers and emits snapshot signals.\n * Maintains internal state of all active pointers using a Map.\n */\nexport function createMultiPointerRecognizer<InputSignal extends Signal>(\n processor: (\n inputSignal: InputSignal,\n pointerMap: Map<string, PointerInfo>,\n options: Required<MultiPointerOptions>,\n ) => PointerUpdateResult | null,\n options: MultiPointerOptions = {},\n): MultiPointerRecognizer<InputSignal> {\n const opts: Required<MultiPointerOptions> = {\n maxPointers: options.maxPointers ?? 2,\n };\n\n const activePointers = new Map<string, PointerInfo>();\n let previousPhase: MultiPointerPhase = \"idle\";\n\n function computePhase(count: number, endedCount: number): MultiPointerPhase {\n if (count === 0) {\n return previousPhase === \"active\" && endedCount > 0 ? \"ended\" : \"idle\";\n }\n return \"active\";\n }\n\n return {\n process(inputSignal: InputSignal): MultiPointerSignal | null {\n const result = processor(inputSignal, activePointers, opts);\n if (result === null) {\n return null;\n }\n\n const endedPointerIds = result.endedPointerIds;\n for (const id of endedPointerIds) {\n activePointers.delete(id);\n }\n\n const pointers = Array.from(activePointers.values());\n const phase = computePhase(pointers.length, endedPointerIds.length);\n previousPhase = phase === \"ended\" ? \"idle\" : phase;\n\n const multiPointer: MultiPointer = {\n phase,\n pointers,\n count: pointers.length,\n };\n\n return createMultiPointerSignal(multiPointer);\n },\n\n get isActive(): boolean {\n return activePointers.size > 0;\n },\n\n get activeCount(): number {\n return activePointers.size;\n },\n\n reset(): void {\n activePointers.clear();\n previousPhase = \"idle\";\n },\n\n dispose(): void {\n this.reset();\n },\n };\n}\n","import type { Operator } from \"../../core/stream.js\";\nimport { createStream } from \"../../core/stream.js\";\nimport type { DomEventSignal } from \"../dom-event/dom-event-signal.js\";\nimport type {\n SinglePointerButton,\n SinglePointerPhase,\n SinglePointerType,\n} from \"../single-pointer/types.js\";\nimport { toSinglePointerButton } from \"../single-pointer/types.js\";\nimport type { MultiPointerSignal, PointerInfo } from \"./multi-pointer-signal.js\";\nimport {\n createMultiPointerRecognizer,\n type MultiPointerRecognizer,\n type PointerUpdateResult,\n} from \"./recognizer.js\";\nimport type { MultiPointerOptions } from \"./types.js\";\n\nexport function createPointerRecognizer(\n options: MultiPointerOptions = {},\n): MultiPointerRecognizer<DomEventSignal<PointerEvent>> {\n function processor(\n domEventSignal: DomEventSignal<PointerEvent>,\n pointerMap: Map<string, PointerInfo>,\n opts: Required<MultiPointerOptions>,\n ): PointerUpdateResult | null {\n const e = domEventSignal.value;\n const id = `${e.pointerType}-${e.pointerId}`;\n const endedPointerIds: string[] = [];\n\n switch (e.type) {\n case \"pointerdown\": {\n if (pointerMap.size >= opts.maxPointers) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"start\"));\n break;\n }\n\n case \"pointermove\": {\n if (!pointerMap.has(id)) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"move\"));\n break;\n }\n\n case \"pointerup\": {\n if (!pointerMap.has(id)) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"end\"));\n endedPointerIds.push(id);\n break;\n }\n\n case \"pointercancel\": {\n if (!pointerMap.has(id)) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"cancel\"));\n endedPointerIds.push(id);\n break;\n }\n\n default:\n return null;\n }\n\n return { pointers: pointerMap, endedPointerIds };\n }\n\n return createMultiPointerRecognizer(processor, options);\n}\n\nexport function multiPointerFromPointer(\n options: MultiPointerOptions = {},\n): Operator<DomEventSignal<PointerEvent>, MultiPointerSignal> {\n return (source) =>\n createStream((observer) => {\n const recognizer = createPointerRecognizer(options);\n\n const unsub = source.subscribe({\n next(event) {\n const signal = recognizer.process(event);\n if (signal) {\n observer.next(signal);\n }\n },\n error(err) {\n observer.error?.(err);\n },\n complete() {\n observer.complete?.();\n },\n });\n\n return () => {\n unsub();\n recognizer.dispose();\n };\n });\n}\n\nfunction createPointerInfo(e: PointerEvent, phase: SinglePointerPhase): PointerInfo {\n const button: SinglePointerButton =\n phase === \"start\" || phase === \"end\" ? toSinglePointerButton(e.button) : \"none\";\n\n return {\n id: `${e.pointerType}-${e.pointerId}`,\n phase,\n x: e.clientX,\n y: e.clientY,\n pageX: e.pageX,\n pageY: e.pageY,\n pointerType: normalizePointerType(e.pointerType),\n button,\n pressure: e.pressure,\n };\n}\n\nfunction normalizePointerType(type: string): SinglePointerType {\n switch (type) {\n case \"mouse\":\n return \"mouse\";\n case \"touch\":\n return \"touch\";\n case \"pen\":\n return \"pen\";\n default:\n return \"unknown\";\n }\n}\n","import type { Stream } from \"../../core/stream.js\";\nimport { pointerEvents } from \"../dom-event/pointer-events.js\";\nimport type { MultiPointerSignal } from \"./multi-pointer-signal.js\";\nimport { multiPointerFromPointer } from \"./recognizer-from-pointer.js\";\nimport type { MultiPointerOptions } from \"./types.js\";\n\nexport function multiPointer(\n target: EventTarget,\n options: MultiPointerOptions = {},\n): Stream<MultiPointerSignal> {\n const source = pointerEvents(target);\n return multiPointerFromPointer(options)(source);\n}\n","import type { Stream } from \"../../core/stream.js\";\nimport { pointerEvents } from \"../dom-event/pointer-events.js\";\nimport { singlePointerFromPointer } from \"./recognizer-from-pointer.js\";\nimport type { SinglePointerSignal } from \"./single-pointer-signal.js\";\nimport type { SinglePointerOptions } from \"./types.js\";\n\nexport function singlePointer(\n target: EventTarget,\n options: SinglePointerOptions = {},\n): Stream<SinglePointerSignal> {\n const source = pointerEvents(target);\n return singlePointerFromPointer(options)(source);\n}\n","import { createSignal, type Signal } from \"../../core/signal.js\";\n\nexport type WheelDeltaMode = \"pixel\" | \"line\" | \"page\";\n\n/**\n * Wheel event data normalized into a consistent structure.\n * Provides scroll deltas and position information.\n */\nexport interface WheelValue {\n /** Horizontal scroll delta */\n deltaX: number;\n /** Vertical scroll delta (positive = scroll down/zoom out) */\n deltaY: number;\n /** Z-axis scroll delta (rare, used by some 3D mice) */\n deltaZ: number;\n /** Unit of the delta values */\n deltaMode: WheelDeltaMode;\n /** Client X coordinate (viewport-relative) */\n x: number;\n /** Client Y coordinate (viewport-relative) */\n y: number;\n /** Page X coordinate (document-relative) */\n pageX: number;\n /** Page Y coordinate (document-relative) */\n pageY: number;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n /** Original DOM WheelEvent for advanced use cases like preventDefault */\n originalEvent: WheelEvent;\n}\n\nexport interface WheelSignal extends Signal<\"wheel\", WheelValue> {}\n\nexport const WHEEL_SIGNAL_KIND = \"wheel\" as const;\n\nexport function createWheelSignal(value: WheelValue): WheelSignal {\n return createSignal(WHEEL_SIGNAL_KIND, value);\n}\n\nfunction toDeltaMode(mode: number): WheelDeltaMode {\n switch (mode) {\n case 0:\n return \"pixel\";\n case 1:\n return \"line\";\n case 2:\n return \"page\";\n default:\n return \"pixel\";\n }\n}\n\nexport function createWheelSignalFromEvent(event: WheelEvent): WheelSignal {\n return createWheelSignal({\n deltaX: event.deltaX,\n deltaY: event.deltaY,\n deltaZ: event.deltaZ,\n deltaMode: toDeltaMode(event.deltaMode),\n x: event.clientX,\n y: event.clientY,\n pageX: event.pageX,\n pageY: event.pageY,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n originalEvent: event,\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { share } from \"../../operators/share.js\";\nimport type { ModifierKey } from \"../keyboard/keyboard.js\";\nimport { createWheelSignalFromEvent, type WheelSignal } from \"./wheel-signal.js\";\n\nexport interface WheelOptions {\n /**\n * Whether to use passive event listener.\n * Set to false if you need to call preventDefault() on the originalEvent.\n * @default true\n */\n passive?: boolean;\n\n /**\n * Filter by modifier keys. Uses OR logic (matches if any is pressed).\n * @example ['meta', 'ctrl'] - matches if metaKey OR ctrlKey is pressed\n */\n modifiers?: ModifierKey[];\n\n /**\n * If true, calls preventDefault() on matching events.\n * Requires passive: false to work.\n * @default false\n */\n preventDefault?: boolean;\n}\n\n/**\n * Cache for shared wheel streams per EventTarget and passive option.\n * Using WeakMap ensures streams are garbage collected when targets are removed.\n */\nconst sharedWheelStreams = new WeakMap<EventTarget, Map<boolean, Stream<WheelSignal>>>();\n\nfunction getSharedWheel(target: EventTarget, passive: boolean): Stream<WheelSignal> {\n let passiveMap = sharedWheelStreams.get(target);\n if (!passiveMap) {\n passiveMap = new Map();\n sharedWheelStreams.set(target, passiveMap);\n }\n\n let stream = passiveMap.get(passive);\n if (!stream) {\n stream = share<WheelSignal>()(createWheelStream(target, passive));\n passiveMap.set(passive, stream);\n }\n return stream;\n}\n\nfunction createWheelStream(target: EventTarget, passive: boolean): Stream<WheelSignal> {\n return createStream<WheelSignal>((observer) => {\n const handler = (e: Event) => {\n observer.next(createWheelSignalFromEvent(e as WheelEvent));\n };\n\n target.addEventListener(\"wheel\", handler, { passive });\n\n return () => {\n target.removeEventListener(\"wheel\", handler);\n };\n });\n}\n\n/**\n * Creates a stream of wheel signals from wheel events on the target.\n * Automatically shares the wheel stream for the same EventTarget and passive option.\n *\n * @example\n * ```typescript\n * // Basic usage (passive by default for performance)\n * wheel(element).subscribe(signal => {\n * console.log(signal.value.deltaY);\n * });\n *\n * // With modifier filter and preventDefault\n * wheel(element, {\n * passive: false,\n * modifiers: ['meta', 'ctrl'],\n * preventDefault: true\n * }).subscribe(signal => {\n * // Only fires when Ctrl or Cmd is held\n * });\n * ```\n */\nexport function wheel(target: EventTarget, options?: WheelOptions): Stream<WheelSignal> {\n const passive = options?.passive ?? true;\n const modifiers = options?.modifiers;\n const preventDefault = options?.preventDefault ?? false;\n\n const source = getSharedWheel(target, passive);\n\n // If no filtering needed, return shared stream directly\n if (!modifiers?.length && !preventDefault) {\n return source;\n }\n\n const matchesModifiers = (value: WheelSignal[\"value\"]): boolean => {\n if (!modifiers || modifiers.length === 0) return true;\n return modifiers.some((mod) => {\n switch (mod) {\n case \"meta\":\n return value.metaKey;\n case \"ctrl\":\n return value.ctrlKey;\n case \"alt\":\n return value.altKey;\n case \"shift\":\n return value.shiftKey;\n default:\n return false;\n }\n });\n };\n\n return createStream<WheelSignal>((observer) => {\n return source.subscribe({\n next(signal) {\n try {\n if (matchesModifiers(signal.value)) {\n if (preventDefault) {\n signal.value.originalEvent.preventDefault();\n }\n observer.next(signal);\n }\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: observer.error?.bind(observer),\n complete: observer.complete?.bind(observer),\n });\n });\n}\n","import type { Signal } from \"../core/signal.js\";\nimport type { Operator } from \"../core/stream.js\";\nimport { pipe } from \"../index.js\";\n\nexport function compose<T extends Signal, A extends Signal>(op1: Operator<T, A>): Operator<T, A>;\nexport function compose<T extends Signal, A extends Signal, B extends Signal>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n): Operator<T, B>;\nexport function compose<T extends Signal, A extends Signal, B extends Signal, C extends Signal>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n): Operator<T, C>;\nexport function compose<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n): Operator<T, D>;\nexport function compose<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n): Operator<T, E>;\nexport function compose(...operators: Operator<Signal, Signal>[]): Operator<Signal, Signal>;\nexport function compose(...operators: Operator<Signal, Signal>[]): Operator<Signal, Signal> {\n return (source) => pipe(source, ...operators);\n}\n","import type { Signal } from \"../core/signal.js\";\nimport type { Operator, Stream } from \"../core/stream.js\";\n\nexport function pipe<T extends Signal>(source: Stream<T>): Stream<T>;\nexport function pipe<T extends Signal, A extends Signal>(\n source: Stream<T>,\n op1: Operator<T, A>,\n): Stream<A>;\nexport function pipe<T extends Signal, A extends Signal, B extends Signal>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n): Stream<B>;\nexport function pipe<T extends Signal, A extends Signal, B extends Signal, C extends Signal>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n): Stream<C>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n): Stream<D>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n): Stream<E>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n F extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n op6: Operator<E, F>,\n): Stream<F>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n F extends Signal,\n G extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n op6: Operator<E, F>,\n op7: Operator<F, G>,\n): Stream<G>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n F extends Signal,\n G extends Signal,\n H extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n op6: Operator<E, F>,\n op7: Operator<F, G>,\n op8: Operator<G, H>,\n): Stream<H>;\nexport function pipe<T extends Signal>(\n source: Stream<T>,\n ...operators: Operator<Signal, Signal>[]\n): Stream<Signal>;\nexport function pipe<T extends Signal>(\n source: Stream<T>,\n ...operators: Operator<Signal, Signal>[]\n): Stream<Signal> {\n return operators.reduce((prev, op) => op(prev), source as Stream<Signal>);\n}\n"],"names":["DOM_EVENT_SIGNAL_KIND","createDomEventSignal","event","createSignal","domEvent","target","eventName","options","createStream","observer","handler","MOUSE_EVENTS","mouseEvents","i","POINTER_EVENTS","pointerEvents","TOUCH_EVENTS","touchEvents","KEYBOARD_SIGNAL_KIND","createKeyboardSignal","value","createKeyboardSignalFromEvent","phase","keyboard","keyList","k","modifiers","preventDefault","matchesKey","key","matchesModifiers","e","mod","matches","handleKeyDown","handleKeyUp","HELD_SIGNAL_KIND","sharedKeyboardStreams","getSharedKeyboard","stream","share","keyboardHeld","keyLower","source","checkModifiers","keyHeld","signal","eventKey","modifierHeld","held","err","MULTI_POINTER_SIGNAL_KIND","createMultiPointerSignal","multiPointer","createMultiPointerRecognizer","processor","opts","activePointers","previousPhase","computePhase","count","endedCount","inputSignal","result","endedPointerIds","id","pointers","createPointerRecognizer","domEventSignal","pointerMap","createPointerInfo","multiPointerFromPointer","recognizer","unsub","button","toSinglePointerButton","normalizePointerType","type","singlePointer","singlePointerFromPointer","WHEEL_SIGNAL_KIND","createWheelSignal","toDeltaMode","mode","createWheelSignalFromEvent","sharedWheelStreams","getSharedWheel","passive","passiveMap","createWheelStream","wheel","compose","operators","pipe","prev","op"],"mappings":"8QAIaA,EAAwB,YAE9B,SAASC,EAAsCC,EAA6B,CACjF,OAAOC,EAAAA,aAAaH,EAAuBE,CAAK,CAClD,CC4CO,SAASE,EACdC,EACAC,EACAC,EAC2B,CAC3B,OAAOC,EAAAA,aAAiCC,GAAa,CAGnD,MAAMC,EAA0BR,GAAU,CACxCO,EAAS,KAAKR,EAAqBC,CAAU,CAAC,CAChD,EAEA,OAAAG,EAAO,iBAAiBC,EAAWI,EAASH,CAAO,EAE5C,IAAM,CACXF,EAAO,oBAAoBC,EAAWI,EAASH,CAAO,CACxD,CACF,CAAC,CACH,CCnEA,MAAMI,EAAe,CAAC,YAAa,YAAa,SAAS,EAElD,SAASC,EACdP,EACAE,EACoC,CACpC,OAAOC,EAAAA,aAA0CC,GAAa,CAC5D,MAAMC,EAAWR,GAAiB,CAChCO,EAAS,KAAKR,EAAqBC,CAAmB,CAAC,CACzD,EAEA,QAASW,EAAI,EAAGA,EAAIF,EAAa,OAAQE,IAAK,CAC5C,MAAMP,EAAYK,EAAaE,CAAC,EAChCR,EAAO,iBAAiBC,EAAWI,EAASH,CAAO,CACrD,CAEA,MAAO,IAAM,CACX,QAASM,EAAI,EAAGA,EAAIF,EAAa,OAAQE,IAAK,CAC5C,MAAMP,EAAYK,EAAaE,CAAC,EAChCR,EAAO,oBAAoBC,EAAWI,EAASH,CAAO,CACxD,CACF,CACF,CAAC,CACH,CCvBA,MAAMO,EAAiB,CAAC,cAAe,cAAe,YAAa,eAAe,EAE3E,SAASC,EACdV,EACAE,EACsC,CACtC,OAAOC,EAAAA,aAA4CC,GAAa,CAC9D,MAAMC,EAAWR,GAAiB,CAChCO,EAAS,KAAKR,EAAqBC,CAAqB,CAAC,CAC3D,EAEA,QAASW,EAAI,EAAGA,EAAIC,EAAe,OAAQD,IAAK,CAC9C,MAAMP,EAAYQ,EAAeD,CAAC,EAClCR,EAAO,iBAAiBC,EAAWI,EAASH,CAAO,CACrD,CAEA,MAAO,IAAM,CACX,QAASM,EAAI,EAAGA,EAAIC,EAAe,OAAQD,IAAK,CAC9C,MAAMP,EAAYQ,EAAeD,CAAC,EAClCR,EAAO,oBAAoBC,EAAWI,EAASH,CAAO,CACxD,CACF,CACF,CAAC,CACH,CCvBA,MAAMS,EAAe,CAAC,aAAc,YAAa,WAAY,aAAa,EAEnE,SAASC,EACdZ,EACAE,EACoC,CACpC,OAAOC,EAAAA,aAAcC,GAAa,CAChC,MAAMC,EAAWR,GAAiB,CAChCO,EAAS,KAAKR,EAAqBC,CAAmB,CAAC,CACzD,EAEA,QAASW,EAAI,EAAGA,EAAIG,EAAa,OAAQH,IAAK,CAC5C,MAAMP,EAAYU,EAAaH,CAAC,EAChCR,EAAO,iBAAiBC,EAAWI,EAASH,CAAO,CACrD,CAEA,MAAO,IAAM,CACX,QAASM,EAAI,EAAGA,EAAIG,EAAa,OAAQH,IAAK,CAC5C,MAAMP,EAAYU,EAAaH,CAAC,EAChCR,EAAO,oBAAoBC,EAAWI,EAASH,CAAO,CACxD,CACF,CACF,CAAC,CACH,CCAO,MAAMW,EAAuB,WAE7B,SAASC,EAAqBC,EAAsC,CACzE,OAAOjB,EAAAA,aAAae,EAAsBE,CAAK,CACjD,CAEO,SAASC,EACdnB,EACAoB,EACgB,CAChB,OAAOH,EAAqB,CAC1B,MAAAG,EACA,IAAKpB,EAAM,IACX,KAAMA,EAAM,KACZ,OAAQA,EAAM,OACd,OAAQA,EAAM,OACd,QAASA,EAAM,QACf,QAASA,EAAM,QACf,SAAUA,EAAM,SAChB,cAAeA,CAAA,CAChB,CACH,CCJO,SAASqB,EAASlB,EAAqBE,EAAmD,CAC/F,MAAMiB,EAAUjB,GAAS,IACrB,MAAM,QAAQA,EAAQ,GAAG,EACvBA,EAAQ,IAAI,IAAKkB,GAAMA,EAAE,aAAa,EACtC,CAAClB,EAAQ,IAAI,YAAA,CAAa,EAC5B,KACEmB,EAAYnB,GAAS,UACrBoB,EAAiBpB,GAAS,gBAAkB,GAE5CqB,EAAcC,GACbL,EACEA,EAAQ,SAASK,EAAI,YAAA,CAAa,EADpB,GAIjBC,EAAoBC,GACpB,CAACL,GAAaA,EAAU,SAAW,EAAU,GAC1CA,EAAU,KAAMM,GAAQ,CAC7B,OAAQA,EAAA,CACN,IAAK,OACH,OAAOD,EAAE,QACX,IAAK,OACH,OAAOA,EAAE,QACX,IAAK,MACH,OAAOA,EAAE,OACX,IAAK,QACH,OAAOA,EAAE,SACX,QACE,MAAO,EAAA,CAEb,CAAC,EAGGE,EAAWF,GACRH,EAAWG,EAAE,GAAG,GAAKD,EAAiBC,CAAC,EAGhD,OAAOvB,EAAAA,aAA8BC,GAAa,CAChD,MAAMyB,EAAiBH,GAAa,CAClC,MAAM7B,EAAQ6B,EACTE,EAAQ/B,CAAK,IACdyB,KAAsB,eAAA,EAC1BlB,EAAS,KAAKY,EAA8BnB,EAAO,MAAM,CAAC,EAC5D,EAEMiC,EAAeJ,GAAa,CAChC,MAAM7B,EAAQ6B,EACTE,EAAQ/B,CAAK,IACdyB,KAAsB,eAAA,EAC1BlB,EAAS,KAAKY,EAA8BnB,EAAO,IAAI,CAAC,EAC1D,EAEA,OAAAG,EAAO,iBAAiB,UAAW6B,CAAa,EAChD7B,EAAO,iBAAiB,QAAS8B,CAAW,EAErC,IAAM,CACX9B,EAAO,oBAAoB,UAAW6B,CAAa,EACnD7B,EAAO,oBAAoB,QAAS8B,CAAW,CACjD,CACF,CAAC,CACH,CCxFO,MAAMC,EAAmB,OAoB1BC,MAA4B,QAElC,SAASC,EAAkBjC,EAA6C,CACtE,IAAIkC,EAASF,EAAsB,IAAIhC,CAAM,EAC7C,OAAKkC,IACHA,EAASC,EAAAA,MAAA,EAAwBjB,EAASlB,CAAM,CAAC,EACjDgC,EAAsB,IAAIhC,EAAQkC,CAAM,GAEnCA,CACT,CAkCO,SAASE,EACdpC,EACAE,EACoB,CACpB,KAAM,CAAE,IAAAsB,EAAK,UAAAH,CAAA,EAAcnB,EACrBmC,EAAWb,EAAI,YAAA,EACfc,EAASL,EAAkBjC,CAAM,EAEjCuC,EAAkBxB,GAClB,CAACM,GAAaA,EAAU,SAAW,EAAU,GAC1CA,EAAU,KAAMM,GAAQ,CAC7B,OAAQA,EAAA,CACN,IAAK,OACH,OAAOZ,EAAM,QACf,IAAK,OACH,OAAOA,EAAM,QACf,IAAK,MACH,OAAOA,EAAM,OACf,IAAK,QACH,OAAOA,EAAM,SACf,QACE,MAAO,EAAA,CAEb,CAAC,EAGH,OAAOZ,EAAAA,aAAcC,GAAa,CAChC,IAAIoC,EAAU,GAEd,OAAOF,EAAO,UAAU,CACtB,KAAKG,EAAQ,CACX,GAAI,CACF,KAAM,CAAE,IAAKC,EAAU,MAAAzB,CAAA,EAAUwB,EAAO,MAGpCC,EAAS,YAAA,IAAkBL,IAC7BG,EAAUvB,IAAU,QAItB,MAAM0B,EAAeJ,EAAeE,EAAO,KAAK,EAG1CG,EAAOJ,GAAWG,EACxBvC,EAAS,KAAKN,EAAAA,aAAaiC,EAAkB,CAAE,KAAAa,CAAA,CAAM,CAAC,CACxD,OAASC,EAAK,CACZzC,EAAS,QAAQyC,CAAG,CACtB,CACF,EACA,MAAOzC,EAAS,OAAO,KAAKA,CAAQ,EACpC,SAAUA,EAAS,UAAU,KAAKA,CAAQ,CAAA,CAC3C,CACH,CAAC,CACH,CCzHO,MAAM0C,EAA4B,gBAuClC,SAASC,EAAyBC,EAAgD,CACvF,OAAOlD,EAAAA,aAAagD,EAA2BE,CAAY,CAC7D,CClBO,SAASC,EACdC,EAKAhD,EAA+B,GACM,CACrC,MAAMiD,EAAsC,CAC1C,YAAajD,EAAQ,aAAe,CAAA,EAGhCkD,MAAqB,IAC3B,IAAIC,EAAmC,OAEvC,SAASC,EAAaC,EAAeC,EAAuC,CAC1E,OAAID,IAAU,EACLF,IAAkB,UAAYG,EAAa,EAAI,QAAU,OAE3D,QACT,CAEA,MAAO,CACL,QAAQC,EAAqD,CAC3D,MAAMC,EAASR,EAAUO,EAAaL,EAAgBD,CAAI,EAC1D,GAAIO,IAAW,KACb,OAAO,KAGT,MAAMC,EAAkBD,EAAO,gBAC/B,UAAWE,KAAMD,EACfP,EAAe,OAAOQ,CAAE,EAG1B,MAAMC,EAAW,MAAM,KAAKT,EAAe,QAAQ,EAC7CnC,EAAQqC,EAAaO,EAAS,OAAQF,EAAgB,MAAM,EAClEN,EAAgBpC,IAAU,QAAU,OAASA,EAE7C,MAAM+B,EAA6B,CACjC,MAAA/B,EACA,SAAA4C,EACA,MAAOA,EAAS,MAAA,EAGlB,OAAOd,EAAyBC,CAAY,CAC9C,EAEA,IAAI,UAAoB,CACtB,OAAOI,EAAe,KAAO,CAC/B,EAEA,IAAI,aAAsB,CACxB,OAAOA,EAAe,IACxB,EAEA,OAAc,CACZA,EAAe,MAAA,EACfC,EAAgB,MAClB,EAEA,SAAgB,CACd,KAAK,MAAA,CACP,CAAA,CAEJ,CC/EO,SAASS,EACd5D,EAA+B,GACuB,CACtD,SAASgD,EACPa,EACAC,EACAb,EAC4B,CAC5B,MAAMzB,EAAIqC,EAAe,MACnBH,EAAK,GAAGlC,EAAE,WAAW,IAAIA,EAAE,SAAS,GACpCiC,EAA4B,CAAA,EAElC,OAAQjC,EAAE,KAAA,CACR,IAAK,cAAe,CAClB,GAAIsC,EAAW,MAAQb,EAAK,YAC1B,OAAO,KAETa,EAAW,IAAIJ,EAAIK,EAAkBvC,EAAG,OAAO,CAAC,EAChD,KACF,CAEA,IAAK,cAAe,CAClB,GAAI,CAACsC,EAAW,IAAIJ,CAAE,EACpB,OAAO,KAETI,EAAW,IAAIJ,EAAIK,EAAkBvC,EAAG,MAAM,CAAC,EAC/C,KACF,CAEA,IAAK,YAAa,CAChB,GAAI,CAACsC,EAAW,IAAIJ,CAAE,EACpB,OAAO,KAETI,EAAW,IAAIJ,EAAIK,EAAkBvC,EAAG,KAAK,CAAC,EAC9CiC,EAAgB,KAAKC,CAAE,EACvB,KACF,CAEA,IAAK,gBAAiB,CACpB,GAAI,CAACI,EAAW,IAAIJ,CAAE,EACpB,OAAO,KAETI,EAAW,IAAIJ,EAAIK,EAAkBvC,EAAG,QAAQ,CAAC,EACjDiC,EAAgB,KAAKC,CAAE,EACvB,KACF,CAEA,QACE,OAAO,IAAA,CAGX,MAAO,CAAE,SAAUI,EAAY,gBAAAL,CAAA,CACjC,CAEA,OAAOV,EAA6BC,EAAWhD,CAAO,CACxD,CAEO,SAASgE,EACdhE,EAA+B,GAC6B,CAC5D,OAAQoC,GACNnC,eAAcC,GAAa,CACzB,MAAM+D,EAAaL,EAAwB5D,CAAO,EAE5CkE,EAAQ9B,EAAO,UAAU,CAC7B,KAAKzC,EAAO,CACV,MAAM4C,EAAS0B,EAAW,QAAQtE,CAAK,EACnC4C,GACFrC,EAAS,KAAKqC,CAAM,CAExB,EACA,MAAMI,EAAK,CACTzC,EAAS,QAAQyC,CAAG,CACtB,EACA,UAAW,CACTzC,EAAS,WAAA,CACX,CAAA,CACD,EAED,MAAO,IAAM,CACXgE,EAAA,EACAD,EAAW,QAAA,CACb,CACF,CAAC,CACL,CAEA,SAASF,EAAkB,EAAiBhD,EAAwC,CAClF,MAAMoD,EACJpD,IAAU,SAAWA,IAAU,MAAQqD,wBAAsB,EAAE,MAAM,EAAI,OAE3E,MAAO,CACL,GAAI,GAAG,EAAE,WAAW,IAAI,EAAE,SAAS,GACnC,MAAArD,EACA,EAAG,EAAE,QACL,EAAG,EAAE,QACL,MAAO,EAAE,MACT,MAAO,EAAE,MACT,YAAasD,EAAqB,EAAE,WAAW,EAC/C,OAAAF,EACA,SAAU,EAAE,QAAA,CAEhB,CAEA,SAASE,EAAqBC,EAAiC,CAC7D,OAAQA,EAAA,CACN,IAAK,QACH,MAAO,QACT,IAAK,QACH,MAAO,QACT,IAAK,MACH,MAAO,MACT,QACE,MAAO,SAAA,CAEb,CC7HO,SAASxB,EACdhD,EACAE,EAA+B,GACH,CAC5B,MAAMoC,EAAS5B,EAAcV,CAAM,EACnC,OAAOkE,EAAwBhE,CAAO,EAAEoC,CAAM,CAChD,CCNO,SAASmC,EACdzE,EACAE,EAAgC,GACH,CAC7B,MAAMoC,EAAS5B,EAAcV,CAAM,EACnC,OAAO0E,EAAAA,wBAAyBxE,CAAO,EAAEoC,CAAM,CACjD,CCuBO,MAAMqC,EAAoB,QAE1B,SAASC,EAAkB7D,EAAgC,CAChE,OAAOjB,EAAAA,aAAa6E,EAAmB5D,CAAK,CAC9C,CAEA,SAAS8D,EAAYC,EAA8B,CACjD,OAAQA,EAAA,CACN,IAAK,GACH,MAAO,QACT,IAAK,GACH,MAAO,OACT,IAAK,GACH,MAAO,OACT,QACE,MAAO,OAAA,CAEb,CAEO,SAASC,EAA2BlF,EAAgC,CACzE,OAAO+E,EAAkB,CACvB,OAAQ/E,EAAM,OACd,OAAQA,EAAM,OACd,OAAQA,EAAM,OACd,UAAWgF,EAAYhF,EAAM,SAAS,EACtC,EAAGA,EAAM,QACT,EAAGA,EAAM,QACT,MAAOA,EAAM,MACb,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,QAASA,EAAM,QACf,QAASA,EAAM,QACf,SAAUA,EAAM,SAChB,cAAeA,CAAA,CAChB,CACH,CCvCA,MAAMmF,MAAyB,QAE/B,SAASC,EAAejF,EAAqBkF,EAAuC,CAClF,IAAIC,EAAaH,EAAmB,IAAIhF,CAAM,EACzCmF,IACHA,MAAiB,IACjBH,EAAmB,IAAIhF,EAAQmF,CAAU,GAG3C,IAAIjD,EAASiD,EAAW,IAAID,CAAO,EACnC,OAAKhD,IACHA,EAASC,EAAAA,MAAA,EAAqBiD,EAAkBpF,EAAQkF,CAAO,CAAC,EAChEC,EAAW,IAAID,EAAShD,CAAM,GAEzBA,CACT,CAEA,SAASkD,EAAkBpF,EAAqBkF,EAAuC,CACrF,OAAO/E,EAAAA,aAA2BC,GAAa,CAC7C,MAAMC,EAAWqB,GAAa,CAC5BtB,EAAS,KAAK2E,EAA2BrD,CAAe,CAAC,CAC3D,EAEA,OAAA1B,EAAO,iBAAiB,QAASK,EAAS,CAAE,QAAA6E,EAAS,EAE9C,IAAM,CACXlF,EAAO,oBAAoB,QAASK,CAAO,CAC7C,CACF,CAAC,CACH,CAuBO,SAASgF,EAAMrF,EAAqBE,EAA6C,CACtF,MAAMgF,EAAUhF,GAAS,SAAW,GAC9BmB,EAAYnB,GAAS,UACrBoB,EAAiBpB,GAAS,gBAAkB,GAE5CoC,EAAS2C,EAAejF,EAAQkF,CAAO,EAG7C,GAAI,CAAC7D,GAAW,QAAU,CAACC,EACzB,OAAOgB,EAGT,MAAMb,EAAoBV,GACpB,CAACM,GAAaA,EAAU,SAAW,EAAU,GAC1CA,EAAU,KAAMM,GAAQ,CAC7B,OAAQA,EAAA,CACN,IAAK,OACH,OAAOZ,EAAM,QACf,IAAK,OACH,OAAOA,EAAM,QACf,IAAK,MACH,OAAOA,EAAM,OACf,IAAK,QACH,OAAOA,EAAM,SACf,QACE,MAAO,EAAA,CAEb,CAAC,EAGH,OAAOZ,EAAAA,aAA2BC,GACzBkC,EAAO,UAAU,CACtB,KAAKG,EAAQ,CACX,GAAI,CACEhB,EAAiBgB,EAAO,KAAK,IAC3BnB,GACFmB,EAAO,MAAM,cAAc,eAAA,EAE7BrC,EAAS,KAAKqC,CAAM,EAExB,OAASI,EAAK,CACZzC,EAAS,QAAQyC,CAAG,CACtB,CACF,EACA,MAAOzC,EAAS,OAAO,KAAKA,CAAQ,EACpC,SAAUA,EAAS,UAAU,KAAKA,CAAQ,CAAA,CAC3C,CACF,CACH,CC1FO,SAASkF,MAAWC,EAAiE,CAC1F,OAAQjD,GAAWkD,EAAKlD,EAAQ,GAAGiD,CAAS,CAC9C,CCiEO,SAASC,EACdlD,KACGiD,EACa,CAChB,OAAOA,EAAU,OAAO,CAACE,EAAMC,IAAOA,EAAGD,CAAI,EAAGnD,CAAwB,CAC1E"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/browser/dom-event/dom-event-signal.ts","../src/browser/dom-event/dom-event.ts","../src/browser/dom-event/mouse-events.ts","../src/browser/dom-event/pointer-events.ts","../src/browser/dom-event/touch-events.ts","../src/browser/keyboard/keyboard-signal.ts","../src/browser/keyboard/shared.ts","../src/browser/keyboard/keyboard.ts","../src/browser/keyboard/keyboard-held.ts","../src/browser/multi-pointer/multi-pointer-signal.ts","../src/browser/multi-pointer/recognizer.ts","../src/browser/multi-pointer/recognizer-from-pointer.ts","../src/browser/multi-pointer/default-factory.ts","../src/browser/single-pointer/default-factory.ts","../src/browser/wheel/wheel-signal.ts","../src/browser/wheel/wheel.ts","../src/ochestrations/compose.ts","../src/ochestrations/pipe.ts"],"sourcesContent":["import { createSignal, type Signal } from \"../../core/signal.js\";\n\nexport interface DomEventSignal<E extends Event> extends Signal<\"dom-event\", E> {}\n\nexport const DOM_EVENT_SIGNAL_KIND = \"dom-event\" as const;\n\nexport function createDomEventSignal<E extends Event>(event: E): DomEventSignal<E> {\n return createSignal(DOM_EVENT_SIGNAL_KIND, event);\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\ntype AnyEventMap = Record<string, Event>;\n\n/**\n * Strongly-typed event target for custom event maps.\n * Useful for non-DOM EventTargets that still have named events.\n */\nexport type TypedEventTarget<M extends AnyEventMap> = EventTarget & {\n addEventListener<K extends keyof M>(\n type: K,\n listener: (event: M[K]) => void,\n options?: AddEventListenerOptions,\n ): void;\n removeEventListener<K extends keyof M>(\n type: K,\n listener: (event: M[K]) => void,\n options?: AddEventListenerOptions,\n ): void;\n};\n\nexport function domEvent<K extends keyof WindowEventMap>(\n target: Window,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<WindowEventMap[K]>>;\nexport function domEvent<K extends keyof DocumentEventMap>(\n target: Document,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<DocumentEventMap[K]>>;\nexport function domEvent<K extends keyof HTMLElementEventMap>(\n target: HTMLElement,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<HTMLElementEventMap[K]>>;\nexport function domEvent<K extends keyof SVGElementEventMap>(\n target: SVGElement,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<SVGElementEventMap[K]>>;\nexport function domEvent<M extends AnyEventMap, K extends keyof M>(\n target: TypedEventTarget<M>,\n eventName: K,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<M[K]>>;\nexport function domEvent<E extends Event = Event>(\n target: EventTarget,\n eventName: string,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<E>>;\nexport function domEvent<E extends Event = Event>(\n target: EventTarget,\n eventName: string,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<E>> {\n return createStream<DomEventSignal<E>>((observer) => {\n // NOTE: EventTarget's base signature expects an EventListener (Event),\n // so we accept Event and cast to the inferred event type for the signal.\n const handler: EventListener = (event) => {\n observer.next(createDomEventSignal(event as E));\n };\n\n target.addEventListener(eventName, handler, options);\n\n return () => {\n target.removeEventListener(eventName, handler, options);\n };\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\nconst MOUSE_EVENTS = [\"mousedown\", \"mousemove\", \"mouseup\"] as const;\n\nexport function mouseEvents(\n target: EventTarget,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<MouseEvent>> {\n return createStream<DomEventSignal<MouseEvent>>((observer) => {\n const handler = (event: Event) => {\n observer.next(createDomEventSignal(event as MouseEvent));\n };\n\n for (let i = 0; i < MOUSE_EVENTS.length; i++) {\n const eventName = MOUSE_EVENTS[i];\n target.addEventListener(eventName, handler, options);\n }\n\n return () => {\n for (let i = 0; i < MOUSE_EVENTS.length; i++) {\n const eventName = MOUSE_EVENTS[i];\n target.removeEventListener(eventName, handler, options);\n }\n };\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\nconst POINTER_EVENTS = [\"pointerdown\", \"pointermove\", \"pointerup\", \"pointercancel\"] as const;\n\nexport function pointerEvents(\n target: EventTarget,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<PointerEvent>> {\n return createStream<DomEventSignal<PointerEvent>>((observer) => {\n const handler = (event: Event) => {\n observer.next(createDomEventSignal(event as PointerEvent));\n };\n\n for (let i = 0; i < POINTER_EVENTS.length; i++) {\n const eventName = POINTER_EVENTS[i];\n target.addEventListener(eventName, handler, options);\n }\n\n return () => {\n for (let i = 0; i < POINTER_EVENTS.length; i++) {\n const eventName = POINTER_EVENTS[i];\n target.removeEventListener(eventName, handler, options);\n }\n };\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { createDomEventSignal, type DomEventSignal } from \"./dom-event-signal.js\";\n\nconst TOUCH_EVENTS = [\"touchstart\", \"touchmove\", \"touchend\", \"touchcancel\"] as const;\n\nexport function touchEvents(\n target: EventTarget,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<TouchEvent>> {\n return createStream((observer) => {\n const handler = (event: Event) => {\n observer.next(createDomEventSignal(event as TouchEvent));\n };\n\n for (let i = 0; i < TOUCH_EVENTS.length; i++) {\n const eventName = TOUCH_EVENTS[i];\n target.addEventListener(eventName, handler, options);\n }\n\n return () => {\n for (let i = 0; i < TOUCH_EVENTS.length; i++) {\n const eventName = TOUCH_EVENTS[i];\n target.removeEventListener(eventName, handler, options);\n }\n };\n });\n}\n","import { createSignal, type Signal } from \"../../core/signal.js\";\n\nexport type KeyboardPhase = \"down\" | \"up\";\n\n/**\n * Keyboard event data normalized into a consistent structure.\n * Provides both logical key (what the key represents) and physical code (where the key is).\n */\nexport interface KeyboardValue {\n phase: KeyboardPhase;\n /** Logical key value (e.g., \"+\", \"-\", \"a\", \"Meta\", \"Control\") */\n key: string;\n /** Physical key code (e.g., \"Equal\", \"Minus\", \"KeyA\", \"MetaLeft\") */\n code: string;\n /** True if this is a repeat event from holding the key down */\n repeat: boolean;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n /** Original DOM KeyboardEvent for advanced use cases like preventDefault */\n originalEvent: KeyboardEvent;\n}\n\nexport interface KeyboardSignal extends Signal<\"keyboard\", KeyboardValue> {}\n\nexport const KEYBOARD_SIGNAL_KIND = \"keyboard\" as const;\n\nexport function createKeyboardSignal(value: KeyboardValue): KeyboardSignal {\n return createSignal(KEYBOARD_SIGNAL_KIND, value);\n}\n\nexport function createKeyboardSignalFromEvent(\n event: KeyboardEvent,\n phase: KeyboardPhase,\n): KeyboardSignal {\n return createKeyboardSignal({\n phase,\n key: event.key,\n code: event.code,\n repeat: event.repeat,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n originalEvent: event,\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { share } from \"../../operators/share.js\";\nimport { createKeyboardSignalFromEvent, type KeyboardSignal } from \"./keyboard-signal.js\";\n\nconst sharedKeyboardStreams = new WeakMap<EventTarget, Stream<KeyboardSignal>>();\nconst sharedKeyStreams = new WeakMap<EventTarget, Map<string, Stream<KeyboardSignal>>>();\n\nfunction createRawKeyboardStream(target: EventTarget): Stream<KeyboardSignal> {\n return createStream<KeyboardSignal>((observer) => {\n const handleKeyDown = (e: Event) => {\n observer.next(createKeyboardSignalFromEvent(e as KeyboardEvent, \"down\"));\n };\n\n const handleKeyUp = (e: Event) => {\n observer.next(createKeyboardSignalFromEvent(e as KeyboardEvent, \"up\"));\n };\n\n target.addEventListener(\"keydown\", handleKeyDown);\n target.addEventListener(\"keyup\", handleKeyUp);\n\n return () => {\n target.removeEventListener(\"keydown\", handleKeyDown);\n target.removeEventListener(\"keyup\", handleKeyUp);\n };\n });\n}\n\n/** Shared keyboard stream for the given target. */\nexport function getSharedKeyboard(target: EventTarget): Stream<KeyboardSignal> {\n let stream = sharedKeyboardStreams.get(target);\n if (!stream) {\n stream = share<KeyboardSignal>()(createRawKeyboardStream(target));\n sharedKeyboardStreams.set(target, stream);\n }\n return stream;\n}\n\n/** Shared keyboard stream filtered by a specific key. Filters out repeated events. */\nexport function getSharedKeyboardForKey(target: EventTarget, key: string): Stream<KeyboardSignal> {\n const keyLower = key.toLowerCase();\n\n let keyMap = sharedKeyStreams.get(target);\n if (!keyMap) {\n keyMap = new Map();\n sharedKeyStreams.set(target, keyMap);\n }\n\n let stream = keyMap.get(keyLower);\n if (!stream) {\n const baseStream = getSharedKeyboard(target);\n const filteredStream = createStream<KeyboardSignal>((observer) => {\n return baseStream.subscribe({\n next(signal) {\n if (signal.value.repeat) return;\n if (signal.value.key.toLowerCase() !== keyLower) return;\n observer.next(signal);\n },\n error: observer.error?.bind(observer),\n complete: observer.complete?.bind(observer),\n });\n });\n stream = share<KeyboardSignal>()(filteredStream);\n keyMap.set(keyLower, stream);\n }\n\n return stream;\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport type { KeyboardSignal } from \"./keyboard-signal.js\";\nimport { getSharedKeyboard, getSharedKeyboardForKey } from \"./shared.js\";\n\nexport type ModifierKey = \"meta\" | \"ctrl\" | \"alt\" | \"shift\";\n\nexport interface KeyboardOptions {\n /** Filter by key value(s). Case-insensitive. Uses OR logic if array. */\n key?: string | string[];\n /** Filter by modifier keys. Uses OR logic. */\n modifiers?: ModifierKey[];\n /** If true, calls preventDefault() on matching events. @default false */\n preventDefault?: boolean;\n /** If true, allows repeated keydown events. @default false */\n allowRepeat?: boolean;\n}\n\n/**\n * Creates a keyboard signal stream. Shares underlying listeners per EventTarget.\n *\n * @example\n * keyboard(window).subscribe(signal => console.log(signal.value.key));\n * keyboard(window, { key: 'z', modifiers: ['meta'] }).subscribe(handleUndo);\n */\nexport function keyboard(target: EventTarget, options?: KeyboardOptions): Stream<KeyboardSignal> {\n if (!options) return getSharedKeyboard(target);\n\n const modifiers = options.modifiers;\n const preventDefault = options.preventDefault ?? false;\n const allowRepeat = options.allowRepeat ?? false;\n\n const isSingleKey = typeof options.key === \"string\";\n const keyList = options.key\n ? Array.isArray(options.key)\n ? options.key.map((k) => k.toLowerCase())\n : null\n : null;\n\n const baseStream = isSingleKey\n ? getSharedKeyboardForKey(target, options.key as string)\n : getSharedKeyboard(target);\n\n if (isSingleKey && !modifiers && !preventDefault && !allowRepeat) {\n return baseStream;\n }\n\n const matchesKey = (key: string): boolean => {\n if (!keyList) return true;\n return keyList.includes(key.toLowerCase());\n };\n\n const matchesModifiers = (value: KeyboardSignal[\"value\"]): boolean => {\n if (!modifiers || modifiers.length === 0) return true;\n return modifiers.some((mod) => {\n switch (mod) {\n case \"meta\":\n return value.metaKey;\n case \"ctrl\":\n return value.ctrlKey;\n case \"alt\":\n return value.altKey;\n case \"shift\":\n return value.shiftKey;\n default:\n return false;\n }\n });\n };\n\n return createStream<KeyboardSignal>((observer) => {\n return baseStream.subscribe({\n next(signal) {\n const { key, repeat } = signal.value;\n if (!allowRepeat && repeat) return;\n if (!matchesKey(key)) return;\n if (!matchesModifiers(signal.value)) return;\n if (preventDefault) signal.value.originalEvent.preventDefault();\n observer.next(signal);\n },\n error: observer.error?.bind(observer),\n complete: observer.complete?.bind(observer),\n });\n });\n}\n","import type { Signal } from \"../../core/signal.js\";\nimport { createSignal } from \"../../core/signal.js\";\nimport type { Stream } from \"../../core/stream.js\";\nimport { createStream } from \"../../core/stream.js\";\nimport type { ModifierKey } from \"./keyboard.js\";\nimport type { KeyboardSignal } from \"./keyboard-signal.js\";\nimport { getSharedKeyboard, getSharedKeyboardForKey } from \"./shared.js\";\n\ninterface HeldValue {\n opened: boolean;\n}\n\nexport interface HeldSignal extends Signal<\"keyboard-held\", HeldValue> {}\n\nexport const HELD_SIGNAL_KIND = \"keyboard-held\" as const;\n\nexport interface KeyboardHeldOptions {\n /**\n * The key to track. Case-insensitive.\n * @example 'z', 'Space', 'Escape'\n */\n key: string;\n\n /**\n * Modifier keys that must also be held. Uses OR logic.\n *\n * ⚠️ WARNING: On macOS, OS-level modifiers (especially Meta/Command) can swallow\n * keyup events. This is a known platform limitation, not a bug. For reliable\n * \"hold to activate\" behavior, prefer using non-modifier keys (Space, Shift, etc.)\n * as the primary key instead of relying on modifier combinations.\n *\n * @example ['meta', 'ctrl'] - matches if metaKey OR ctrlKey is pressed\n */\n modifiers?: ModifierKey[];\n}\n\n/**\n * Tracks whether a specific key (with optional modifiers) is being held down.\n * Emits only when state changes.\n *\n * @example\n * ```typescript\n * // Prefer: use non-modifier key for reliable hold detection\n * const spaceHeld$ = keyboardHeld(window, { key: 'Space' });\n *\n * // Caution: modifier combos may miss keyup on macOS\n * const cmdZHeld$ = keyboardHeld(window, { key: 'z', modifiers: ['meta'] });\n * ```\n */\nexport function keyboardHeld(\n target: EventTarget,\n options: KeyboardHeldOptions,\n): Stream<HeldSignal> {\n const { key, modifiers } = options;\n const keyLower = key.toLowerCase();\n const hasModifiers = modifiers && modifiers.length > 0;\n\n // With modifiers, use base stream to receive modifier keyup events\n const source = hasModifiers ? getSharedKeyboard(target) : getSharedKeyboardForKey(target, key);\n\n const modifierKeyNames = new Set<string>();\n if (modifiers) {\n for (const mod of modifiers) {\n if (mod === \"meta\") modifierKeyNames.add(\"meta\");\n if (mod === \"ctrl\") modifierKeyNames.add(\"control\");\n if (mod === \"alt\") modifierKeyNames.add(\"alt\");\n if (mod === \"shift\") modifierKeyNames.add(\"shift\");\n }\n }\n\n const isModifierKey = (eventKey: string): boolean => {\n return modifierKeyNames.has(eventKey.toLowerCase());\n };\n\n const checkModifiers = (value: KeyboardSignal[\"value\"]): boolean => {\n if (!modifiers || modifiers.length === 0) return true;\n return modifiers.some((mod) => {\n switch (mod) {\n case \"meta\":\n return value.metaKey;\n case \"ctrl\":\n return value.ctrlKey;\n case \"alt\":\n return value.altKey;\n case \"shift\":\n return value.shiftKey;\n default:\n return false;\n }\n });\n };\n\n return createStream((observer) => {\n let keyHeld = false;\n let lastEmittedHeld: boolean | undefined;\n\n const emitIfChanged = (held: boolean) => {\n if (held !== lastEmittedHeld) {\n lastEmittedHeld = held;\n observer.next(createSignal(HELD_SIGNAL_KIND, { opened: held }));\n }\n };\n\n return source.subscribe({\n next(signal) {\n try {\n const { key: eventKey, phase, repeat } = signal.value;\n if (repeat) return;\n\n const eventKeyLower = eventKey.toLowerCase();\n const isTargetKey = eventKeyLower === keyLower;\n const isModifier = isModifierKey(eventKey);\n\n if (isTargetKey) {\n keyHeld = phase === \"down\";\n } else if (phase === \"down\" || (isModifier && phase === \"up\")) {\n // Reset on any other keydown or modifier keyup (handles missing keyup on macOS)\n keyHeld = false;\n }\n\n const modifierHeld = checkModifiers(signal.value);\n const held = keyHeld && modifierHeld;\n emitIfChanged(held);\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: observer.error?.bind(observer),\n complete: observer.complete?.bind(observer),\n });\n });\n}\n","import { createSignal, type Signal } from \"../../core/signal.js\";\nimport type {\n SinglePointerButton,\n SinglePointerPhase,\n SinglePointerType,\n} from \"../single-pointer/types.js\";\n\nexport interface MultiPointerSignal extends Signal<\"multi-pointer\", MultiPointer> {}\n\nexport const MULTI_POINTER_SIGNAL_KIND = \"multi-pointer\" as const;\n\n/**\n * Represents the complete state of all active pointers at a given moment.\n * Emitted as a snapshot whenever any pointer changes state.\n */\nexport interface MultiPointer {\n /** Session-level phase: tracks the overall multi-pointer interaction lifecycle */\n phase: MultiPointerPhase;\n /** Array of currently active pointers */\n pointers: readonly PointerInfo[];\n /** Total number of active pointers */\n count: number;\n}\n\n/**\n * Session-level phase for multi-pointer interactions:\n * - \"idle\": No active pointers\n * - \"active\": One or more pointers are active\n * - \"ended\": All pointers have ended (transition state)\n */\nexport type MultiPointerPhase = \"idle\" | \"active\" | \"ended\";\n\n/**\n * Information about a single pointer within a multi-pointer context.\n */\nexport interface PointerInfo {\n id: string;\n phase: SinglePointerPhase;\n x: number;\n y: number;\n pageX: number;\n pageY: number;\n pointerType: SinglePointerType;\n button: SinglePointerButton;\n /** 0.0 ~ 1.0, default 0.5 if unsupported */\n pressure: number;\n}\n\nexport function createMultiPointerSignal(multiPointer: MultiPointer): MultiPointerSignal {\n return createSignal(MULTI_POINTER_SIGNAL_KIND, multiPointer);\n}\n\nexport function createDefaultPointerInfo(): PointerInfo {\n return {\n id: \"\",\n phase: \"move\",\n x: 0,\n y: 0,\n pageX: 0,\n pageY: 0,\n pointerType: \"unknown\",\n button: \"none\",\n pressure: 0.5,\n };\n}\n","import type { Signal } from \"../../core/signal.js\";\nimport {\n createMultiPointerSignal,\n type MultiPointer,\n type MultiPointerPhase,\n type MultiPointerSignal,\n type PointerInfo,\n} from \"./multi-pointer-signal.js\";\nimport type { MultiPointerOptions } from \"./types.js\";\n\nexport interface MultiPointerRecognizer<InputSignal extends Signal> {\n process(event: InputSignal): MultiPointerSignal | null;\n readonly isActive: boolean;\n readonly activeCount: number;\n reset(): void;\n dispose(): void;\n}\n\n/**\n * Result of processing an input event.\n * - null: No signal should be emitted (e.g., pointer ignored due to maxPointers)\n * - pointers: Updated pointer map after processing the event\n */\nexport interface PointerUpdateResult {\n pointers: Map<string, PointerInfo>;\n endedPointerIds: string[];\n}\n\n/**\n * Creates a recognizer that tracks multiple pointers and emits snapshot signals.\n * Maintains internal state of all active pointers using a Map.\n */\nexport function createMultiPointerRecognizer<InputSignal extends Signal>(\n processor: (\n inputSignal: InputSignal,\n pointerMap: Map<string, PointerInfo>,\n options: Required<MultiPointerOptions>,\n ) => PointerUpdateResult | null,\n options: MultiPointerOptions = {},\n): MultiPointerRecognizer<InputSignal> {\n const opts: Required<MultiPointerOptions> = {\n maxPointers: options.maxPointers ?? 2,\n };\n\n const activePointers = new Map<string, PointerInfo>();\n let previousPhase: MultiPointerPhase = \"idle\";\n\n function computePhase(count: number, endedCount: number): MultiPointerPhase {\n if (count === 0) {\n return previousPhase === \"active\" && endedCount > 0 ? \"ended\" : \"idle\";\n }\n return \"active\";\n }\n\n return {\n process(inputSignal: InputSignal): MultiPointerSignal | null {\n const result = processor(inputSignal, activePointers, opts);\n if (result === null) {\n return null;\n }\n\n const endedPointerIds = result.endedPointerIds;\n for (const id of endedPointerIds) {\n activePointers.delete(id);\n }\n\n const pointers = Array.from(activePointers.values());\n const phase = computePhase(pointers.length, endedPointerIds.length);\n previousPhase = phase === \"ended\" ? \"idle\" : phase;\n\n const multiPointer: MultiPointer = {\n phase,\n pointers,\n count: pointers.length,\n };\n\n return createMultiPointerSignal(multiPointer);\n },\n\n get isActive(): boolean {\n return activePointers.size > 0;\n },\n\n get activeCount(): number {\n return activePointers.size;\n },\n\n reset(): void {\n activePointers.clear();\n previousPhase = \"idle\";\n },\n\n dispose(): void {\n this.reset();\n },\n };\n}\n","import type { Operator } from \"../../core/stream.js\";\nimport { createStream } from \"../../core/stream.js\";\nimport type { DomEventSignal } from \"../dom-event/dom-event-signal.js\";\nimport type {\n SinglePointerButton,\n SinglePointerPhase,\n SinglePointerType,\n} from \"../single-pointer/types.js\";\nimport { toSinglePointerButton } from \"../single-pointer/types.js\";\nimport type { MultiPointerSignal, PointerInfo } from \"./multi-pointer-signal.js\";\nimport {\n createMultiPointerRecognizer,\n type MultiPointerRecognizer,\n type PointerUpdateResult,\n} from \"./recognizer.js\";\nimport type { MultiPointerOptions } from \"./types.js\";\n\nexport function createPointerRecognizer(\n options: MultiPointerOptions = {},\n): MultiPointerRecognizer<DomEventSignal<PointerEvent>> {\n function processor(\n domEventSignal: DomEventSignal<PointerEvent>,\n pointerMap: Map<string, PointerInfo>,\n opts: Required<MultiPointerOptions>,\n ): PointerUpdateResult | null {\n const e = domEventSignal.value;\n const id = `${e.pointerType}-${e.pointerId}`;\n const endedPointerIds: string[] = [];\n\n switch (e.type) {\n case \"pointerdown\": {\n if (pointerMap.size >= opts.maxPointers) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"start\"));\n break;\n }\n\n case \"pointermove\": {\n if (!pointerMap.has(id)) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"move\"));\n break;\n }\n\n case \"pointerup\": {\n if (!pointerMap.has(id)) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"end\"));\n endedPointerIds.push(id);\n break;\n }\n\n case \"pointercancel\": {\n if (!pointerMap.has(id)) {\n return null;\n }\n pointerMap.set(id, createPointerInfo(e, \"cancel\"));\n endedPointerIds.push(id);\n break;\n }\n\n default:\n return null;\n }\n\n return { pointers: pointerMap, endedPointerIds };\n }\n\n return createMultiPointerRecognizer(processor, options);\n}\n\nexport function multiPointerFromPointer(\n options: MultiPointerOptions = {},\n): Operator<DomEventSignal<PointerEvent>, MultiPointerSignal> {\n return (source) =>\n createStream((observer) => {\n const recognizer = createPointerRecognizer(options);\n\n const unsub = source.subscribe({\n next(event) {\n const signal = recognizer.process(event);\n if (signal) {\n observer.next(signal);\n }\n },\n error(err) {\n observer.error?.(err);\n },\n complete() {\n observer.complete?.();\n },\n });\n\n return () => {\n unsub();\n recognizer.dispose();\n };\n });\n}\n\nfunction createPointerInfo(e: PointerEvent, phase: SinglePointerPhase): PointerInfo {\n const button: SinglePointerButton =\n phase === \"start\" || phase === \"end\" ? toSinglePointerButton(e.button) : \"none\";\n\n return {\n id: `${e.pointerType}-${e.pointerId}`,\n phase,\n x: e.clientX,\n y: e.clientY,\n pageX: e.pageX,\n pageY: e.pageY,\n pointerType: normalizePointerType(e.pointerType),\n button,\n pressure: e.pressure,\n };\n}\n\nfunction normalizePointerType(type: string): SinglePointerType {\n switch (type) {\n case \"mouse\":\n return \"mouse\";\n case \"touch\":\n return \"touch\";\n case \"pen\":\n return \"pen\";\n default:\n return \"unknown\";\n }\n}\n","import type { Stream } from \"../../core/stream.js\";\nimport { pointerEvents } from \"../dom-event/pointer-events.js\";\nimport type { MultiPointerSignal } from \"./multi-pointer-signal.js\";\nimport { multiPointerFromPointer } from \"./recognizer-from-pointer.js\";\nimport type { MultiPointerOptions } from \"./types.js\";\n\nexport function multiPointer(\n target: EventTarget,\n options: MultiPointerOptions = {},\n): Stream<MultiPointerSignal> {\n const source = pointerEvents(target);\n return multiPointerFromPointer(options)(source);\n}\n","import type { Stream } from \"../../core/stream.js\";\nimport { pointerEvents } from \"../dom-event/pointer-events.js\";\nimport { singlePointerFromPointer } from \"./recognizer-from-pointer.js\";\nimport type { SinglePointerSignal } from \"./single-pointer-signal.js\";\nimport type { SinglePointerOptions } from \"./types.js\";\n\nexport function singlePointer(\n target: EventTarget,\n options: SinglePointerOptions = {},\n): Stream<SinglePointerSignal> {\n const source = pointerEvents(target);\n return singlePointerFromPointer(options)(source);\n}\n","import { createSignal, type Signal } from \"../../core/signal.js\";\n\nexport type WheelDeltaMode = \"pixel\" | \"line\" | \"page\";\n\n/**\n * Wheel event data normalized into a consistent structure.\n * Provides scroll deltas and position information.\n */\nexport interface WheelValue {\n /** Horizontal scroll delta */\n deltaX: number;\n /** Vertical scroll delta (positive = scroll down/zoom out) */\n deltaY: number;\n /** Z-axis scroll delta (rare, used by some 3D mice) */\n deltaZ: number;\n /** Unit of the delta values */\n deltaMode: WheelDeltaMode;\n /** Client X coordinate (viewport-relative) */\n x: number;\n /** Client Y coordinate (viewport-relative) */\n y: number;\n /** Page X coordinate (document-relative) */\n pageX: number;\n /** Page Y coordinate (document-relative) */\n pageY: number;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n /** Original DOM WheelEvent for advanced use cases like preventDefault */\n originalEvent: WheelEvent;\n}\n\nexport interface WheelSignal extends Signal<\"wheel\", WheelValue> {}\n\nexport const WHEEL_SIGNAL_KIND = \"wheel\" as const;\n\nexport function createWheelSignal(value: WheelValue): WheelSignal {\n return createSignal(WHEEL_SIGNAL_KIND, value);\n}\n\nfunction toDeltaMode(mode: number): WheelDeltaMode {\n switch (mode) {\n case 0:\n return \"pixel\";\n case 1:\n return \"line\";\n case 2:\n return \"page\";\n default:\n return \"pixel\";\n }\n}\n\nexport function createWheelSignalFromEvent(event: WheelEvent): WheelSignal {\n return createWheelSignal({\n deltaX: event.deltaX,\n deltaY: event.deltaY,\n deltaZ: event.deltaZ,\n deltaMode: toDeltaMode(event.deltaMode),\n x: event.clientX,\n y: event.clientY,\n pageX: event.pageX,\n pageY: event.pageY,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n originalEvent: event,\n });\n}\n","import { createStream, type Stream } from \"../../core/stream.js\";\nimport { share } from \"../../operators/share.js\";\nimport type { ModifierKey } from \"../keyboard/keyboard.js\";\nimport { createWheelSignalFromEvent, type WheelSignal } from \"./wheel-signal.js\";\n\nexport interface WheelOptions {\n /**\n * Whether to use passive event listener.\n * Set to false if you need to call preventDefault() on the originalEvent.\n * @default true\n */\n passive?: boolean;\n\n /**\n * Filter by modifier keys. Uses OR logic (matches if any is pressed).\n * @example ['meta', 'ctrl'] - matches if metaKey OR ctrlKey is pressed\n */\n modifiers?: ModifierKey[];\n\n /**\n * If true, calls preventDefault() on matching events.\n * Requires passive: false to work.\n * @default false\n */\n preventDefault?: boolean;\n}\n\n/**\n * Cache for shared wheel streams per EventTarget and passive option.\n * Using WeakMap ensures streams are garbage collected when targets are removed.\n */\nconst sharedWheelStreams = new WeakMap<EventTarget, Map<boolean, Stream<WheelSignal>>>();\n\nfunction getSharedWheel(target: EventTarget, passive: boolean): Stream<WheelSignal> {\n let passiveMap = sharedWheelStreams.get(target);\n if (!passiveMap) {\n passiveMap = new Map();\n sharedWheelStreams.set(target, passiveMap);\n }\n\n let stream = passiveMap.get(passive);\n if (!stream) {\n stream = share<WheelSignal>()(createWheelStream(target, passive));\n passiveMap.set(passive, stream);\n }\n return stream;\n}\n\nfunction createWheelStream(target: EventTarget, passive: boolean): Stream<WheelSignal> {\n return createStream<WheelSignal>((observer) => {\n const handler = (e: Event) => {\n observer.next(createWheelSignalFromEvent(e as WheelEvent));\n };\n\n target.addEventListener(\"wheel\", handler, { passive });\n\n return () => {\n target.removeEventListener(\"wheel\", handler);\n };\n });\n}\n\n/**\n * Creates a stream of wheel signals from wheel events on the target.\n * Automatically shares the wheel stream for the same EventTarget and passive option.\n *\n * @example\n * ```typescript\n * // Basic usage (passive by default for performance)\n * wheel(element).subscribe(signal => {\n * console.log(signal.value.deltaY);\n * });\n *\n * // With modifier filter and preventDefault\n * wheel(element, {\n * passive: false,\n * modifiers: ['meta', 'ctrl'],\n * preventDefault: true\n * }).subscribe(signal => {\n * // Only fires when Ctrl or Cmd is held\n * });\n * ```\n */\nexport function wheel(target: EventTarget, options?: WheelOptions): Stream<WheelSignal> {\n const passive = options?.passive ?? true;\n const modifiers = options?.modifiers;\n const preventDefault = options?.preventDefault ?? false;\n\n const source = getSharedWheel(target, passive);\n\n // If no filtering needed, return shared stream directly\n if (!modifiers?.length && !preventDefault) {\n return source;\n }\n\n const matchesModifiers = (value: WheelSignal[\"value\"]): boolean => {\n if (!modifiers || modifiers.length === 0) return true;\n return modifiers.some((mod) => {\n switch (mod) {\n case \"meta\":\n return value.metaKey;\n case \"ctrl\":\n return value.ctrlKey;\n case \"alt\":\n return value.altKey;\n case \"shift\":\n return value.shiftKey;\n default:\n return false;\n }\n });\n };\n\n return createStream<WheelSignal>((observer) => {\n return source.subscribe({\n next(signal) {\n try {\n if (matchesModifiers(signal.value)) {\n if (preventDefault) {\n signal.value.originalEvent.preventDefault();\n }\n observer.next(signal);\n }\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: observer.error?.bind(observer),\n complete: observer.complete?.bind(observer),\n });\n });\n}\n","import type { Signal } from \"../core/signal.js\";\nimport type { Operator } from \"../core/stream.js\";\nimport { pipe } from \"../index.js\";\n\nexport function compose<T extends Signal, A extends Signal>(op1: Operator<T, A>): Operator<T, A>;\nexport function compose<T extends Signal, A extends Signal, B extends Signal>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n): Operator<T, B>;\nexport function compose<T extends Signal, A extends Signal, B extends Signal, C extends Signal>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n): Operator<T, C>;\nexport function compose<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n): Operator<T, D>;\nexport function compose<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n>(\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n): Operator<T, E>;\nexport function compose(...operators: Operator<Signal, Signal>[]): Operator<Signal, Signal>;\nexport function compose(...operators: Operator<Signal, Signal>[]): Operator<Signal, Signal> {\n return (source) => pipe(source, ...operators);\n}\n","import type { Signal } from \"../core/signal.js\";\nimport type { Operator, Stream } from \"../core/stream.js\";\n\nexport function pipe<T extends Signal>(source: Stream<T>): Stream<T>;\nexport function pipe<T extends Signal, A extends Signal>(\n source: Stream<T>,\n op1: Operator<T, A>,\n): Stream<A>;\nexport function pipe<T extends Signal, A extends Signal, B extends Signal>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n): Stream<B>;\nexport function pipe<T extends Signal, A extends Signal, B extends Signal, C extends Signal>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n): Stream<C>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n): Stream<D>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n): Stream<E>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n F extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n op6: Operator<E, F>,\n): Stream<F>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n F extends Signal,\n G extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n op6: Operator<E, F>,\n op7: Operator<F, G>,\n): Stream<G>;\nexport function pipe<\n T extends Signal,\n A extends Signal,\n B extends Signal,\n C extends Signal,\n D extends Signal,\n E extends Signal,\n F extends Signal,\n G extends Signal,\n H extends Signal,\n>(\n source: Stream<T>,\n op1: Operator<T, A>,\n op2: Operator<A, B>,\n op3: Operator<B, C>,\n op4: Operator<C, D>,\n op5: Operator<D, E>,\n op6: Operator<E, F>,\n op7: Operator<F, G>,\n op8: Operator<G, H>,\n): Stream<H>;\nexport function pipe<T extends Signal>(\n source: Stream<T>,\n ...operators: Operator<Signal, Signal>[]\n): Stream<Signal>;\nexport function pipe<T extends Signal>(\n source: Stream<T>,\n ...operators: Operator<Signal, Signal>[]\n): Stream<Signal> {\n return operators.reduce((prev, op) => op(prev), source as Stream<Signal>);\n}\n"],"names":["DOM_EVENT_SIGNAL_KIND","createDomEventSignal","event","createSignal","domEvent","target","eventName","options","createStream","observer","handler","MOUSE_EVENTS","mouseEvents","i","POINTER_EVENTS","pointerEvents","TOUCH_EVENTS","touchEvents","KEYBOARD_SIGNAL_KIND","createKeyboardSignal","value","createKeyboardSignalFromEvent","phase","sharedKeyboardStreams","sharedKeyStreams","createRawKeyboardStream","handleKeyDown","e","handleKeyUp","getSharedKeyboard","stream","share","getSharedKeyboardForKey","key","keyLower","keyMap","baseStream","filteredStream","signal","keyboard","modifiers","preventDefault","allowRepeat","isSingleKey","keyList","k","matchesKey","matchesModifiers","mod","repeat","HELD_SIGNAL_KIND","keyboardHeld","source","modifierKeyNames","isModifierKey","eventKey","checkModifiers","keyHeld","lastEmittedHeld","emitIfChanged","held","isTargetKey","isModifier","modifierHeld","err","MULTI_POINTER_SIGNAL_KIND","createMultiPointerSignal","multiPointer","createMultiPointerRecognizer","processor","opts","activePointers","previousPhase","computePhase","count","endedCount","inputSignal","result","endedPointerIds","id","pointers","createPointerRecognizer","domEventSignal","pointerMap","createPointerInfo","multiPointerFromPointer","recognizer","unsub","button","toSinglePointerButton","normalizePointerType","type","singlePointer","singlePointerFromPointer","WHEEL_SIGNAL_KIND","createWheelSignal","toDeltaMode","mode","createWheelSignalFromEvent","sharedWheelStreams","getSharedWheel","passive","passiveMap","createWheelStream","wheel","compose","operators","pipe","prev","op"],"mappings":"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"}