cereb 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/keyboard/keyboard.d.ts +27 -1
- package/dist/browser/keyboard/keyboard.d.ts.map +1 -1
- package/dist/browser/wheel/wheel.d.ts +20 -3
- package/dist/browser/wheel/wheel.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +158 -149
- package/dist/index.js.map +1 -1
- package/dist/operators/extend.d.ts +4 -0
- package/dist/operators/extend.d.ts.map +1 -0
- package/dist/operators/index.d.ts +5 -5
- package/dist/operators/index.d.ts.map +1 -1
- package/dist/operators/keyboard-held.d.ts +36 -14
- package/dist/operators/keyboard-held.d.ts.map +1 -1
- package/dist/operators/reduce.d.ts +30 -0
- package/dist/operators/reduce.d.ts.map +1 -0
- package/dist/operators/zoom.d.ts +3 -10
- package/dist/operators/zoom.d.ts.map +1 -1
- package/dist/operators.cjs +1 -1
- package/dist/operators.cjs.map +1 -1
- package/dist/operators.js +240 -281
- package/dist/operators.js.map +1 -1
- package/dist/share-B2LTRNsa.js +138 -0
- package/dist/share-B2LTRNsa.js.map +1 -0
- package/dist/share-CGVoYCXk.cjs +2 -0
- package/dist/share-CGVoYCXk.cjs.map +1 -0
- package/package.json +1 -1
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
import { Stream } from '../../core/stream.js';
|
|
2
2
|
import { KeyboardSignal } from './keyboard-signal.js';
|
|
3
|
+
export type ModifierKey = "meta" | "ctrl" | "alt" | "shift";
|
|
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
|
+
*/
|
|
10
|
+
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
|
+
*/
|
|
15
|
+
modifiers?: ModifierKey[];
|
|
16
|
+
/**
|
|
17
|
+
* If true, calls preventDefault() on matching events.
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
preventDefault?: boolean;
|
|
21
|
+
}
|
|
3
22
|
/**
|
|
4
23
|
* Creates a stream of keyboard signals from keydown and keyup events on the target.
|
|
24
|
+
* Optionally filters by key and/or modifier keys.
|
|
5
25
|
*
|
|
6
26
|
* @example
|
|
7
27
|
* ```typescript
|
|
28
|
+
* // All keyboard events
|
|
8
29
|
* keyboard(window).subscribe(signal => {
|
|
9
30
|
* console.log(signal.value.key, signal.value.phase);
|
|
10
31
|
* });
|
|
32
|
+
*
|
|
33
|
+
* // Only +/- keys with Ctrl or Cmd
|
|
34
|
+
* keyboard(window, { key: ['+', '-'], modifiers: ['meta', 'ctrl'] }).subscribe(signal => {
|
|
35
|
+
* // zoom in/out
|
|
36
|
+
* });
|
|
11
37
|
* ```
|
|
12
38
|
*/
|
|
13
|
-
export declare function keyboard(target: EventTarget): Stream<KeyboardSignal>;
|
|
39
|
+
export declare function keyboard(target: EventTarget, options?: KeyboardOptions): Stream<KeyboardSignal>;
|
|
14
40
|
//# 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
|
|
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,4 +1,5 @@
|
|
|
1
1
|
import { Stream } from '../../core/stream.js';
|
|
2
|
+
import { ModifierKey } from '../keyboard/keyboard.js';
|
|
2
3
|
import { WheelSignal } from './wheel-signal.js';
|
|
3
4
|
export interface WheelOptions {
|
|
4
5
|
/**
|
|
@@ -7,9 +8,21 @@ export interface WheelOptions {
|
|
|
7
8
|
* @default true
|
|
8
9
|
*/
|
|
9
10
|
passive?: boolean;
|
|
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
|
+
*/
|
|
15
|
+
modifiers?: ModifierKey[];
|
|
16
|
+
/**
|
|
17
|
+
* If true, calls preventDefault() on matching events.
|
|
18
|
+
* Requires passive: false to work.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
preventDefault?: boolean;
|
|
10
22
|
}
|
|
11
23
|
/**
|
|
12
24
|
* Creates a stream of wheel signals from wheel events on the target.
|
|
25
|
+
* Automatically shares the wheel stream for the same EventTarget and passive option.
|
|
13
26
|
*
|
|
14
27
|
* @example
|
|
15
28
|
* ```typescript
|
|
@@ -18,9 +31,13 @@ export interface WheelOptions {
|
|
|
18
31
|
* console.log(signal.value.deltaY);
|
|
19
32
|
* });
|
|
20
33
|
*
|
|
21
|
-
* // With
|
|
22
|
-
* wheel(element, {
|
|
23
|
-
*
|
|
34
|
+
* // With modifier filter and preventDefault
|
|
35
|
+
* wheel(element, {
|
|
36
|
+
* passive: false,
|
|
37
|
+
* modifiers: ['meta', 'ctrl'],
|
|
38
|
+
* preventDefault: true
|
|
39
|
+
* }).subscribe(signal => {
|
|
40
|
+
* // Only fires when Ctrl or Cmd is held
|
|
24
41
|
* });
|
|
25
42
|
* ```
|
|
26
43
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wheel.d.ts","sourceRoot":"","sources":["../../../src/browser/wheel/wheel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"wheel.d.ts","sourceRoot":"","sources":["../../../src/browser/wheel/wheel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjF,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAE1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAqCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,CAgDtF"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./signal-C5rctKeC.cjs"),d=require("./share-CGVoYCXk.cjs"),b=require("./types-BGR5Mhw9.cjs"),w=require("./single-pointer/pointer.cjs"),x="dom-event";function g(e){return a.createSignal(x,e)}function D(e,r,o){return a.createStream(t=>{const n=i=>{t.next(g(i))};return e.addEventListener(r,n,o),()=>{e.removeEventListener(r,n,o)}})}const m=["mousedown","mousemove","mouseup"];function T(e,r){return a.createStream(o=>{const t=n=>{o.next(g(n))};for(let n=0;n<m.length;n++){const i=m[n];e.addEventListener(i,t,r)}return()=>{for(let n=0;n<m.length;n++){const i=m[n];e.removeEventListener(i,t,r)}}})}const f=["pointerdown","pointermove","pointerup","pointercancel"];function S(e,r){return a.createStream(o=>{const t=n=>{o.next(g(n))};for(let n=0;n<f.length;n++){const i=f[n];e.addEventListener(i,t,r)}return()=>{for(let n=0;n<f.length;n++){const i=f[n];e.removeEventListener(i,t,r)}}})}const h=["touchstart","touchmove","touchend","touchcancel"];function A(e,r){return a.createStream(o=>{const t=n=>{o.next(g(n))};for(let n=0;n<h.length;n++){const i=h[n];e.addEventListener(i,t,r)}return()=>{for(let n=0;n<h.length;n++){const i=h[n];e.removeEventListener(i,t,r)}}})}const W="multi-pointer";function Y(e){return a.createSignal(W,e)}function k(e,r={}){const o={maxPointers:r.maxPointers??2},t=new Map;let n="idle";function i(s,c){return s===0?n==="active"&&c>0?"ended":"idle":"active"}return{process(s){const c=e(s,t,o);if(c===null)return null;const u=c.endedPointerIds;for(const _ of u)t.delete(_);const l=Array.from(t.values()),E=i(l.length,u.length);n=E==="ended"?"idle":E;const L={phase:E,pointers:l,count:l.length};return Y(L)},get isActive(){return t.size>0},get activeCount(){return t.size},reset(){t.clear(),n="idle"},dispose(){this.reset()}}}function z(e={}){function r(o,t,n){const i=o.value,s=`${i.pointerType}-${i.pointerId}`,c=[];switch(i.type){case"pointerdown":{if(t.size>=n.maxPointers)return null;t.set(s,p(i,"start"));break}case"pointermove":{if(!t.has(s))return null;t.set(s,p(i,"move"));break}case"pointerup":{if(!t.has(s))return null;t.set(s,p(i,"end")),c.push(s);break}case"pointercancel":{if(!t.has(s))return null;t.set(s,p(i,"cancel")),c.push(s);break}default:return null}return{pointers:t,endedPointerIds:c}}return k(r,e)}function y(e={}){return r=>a.createStream(o=>{const t=z(e),n=r.subscribe({next(i){const s=t.process(i);s&&o.next(s)},error(i){o.error?.(i)},complete(){o.complete?.()}});return()=>{n(),t.dispose()}})}function p(e,r){const o=r==="start"||r==="end"?b.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:O(e.pointerType),button:o,pressure:e.pressure}}function O(e){switch(e){case"mouse":return"mouse";case"touch":return"touch";case"pen":return"pen";default:return"unknown"}}function X(e,r={}){const o=S(e);return y(r)(o)}function R(e,r={}){const o=S(e);return w.singlePointerRecognizer(r)(o)}const P="wheel";function K(e){return a.createSignal(P,e)}function F(e){switch(e){case 0:return"pixel";case 1:return"line";case 2:return"page";default:return"pixel"}}function I(e){return K({deltaX:e.deltaX,deltaY:e.deltaY,deltaZ:e.deltaZ,deltaMode:F(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 v=new WeakMap;function G(e,r){let o=v.get(e);o||(o=new Map,v.set(e,o));let t=o.get(r);return t||(t=d.share()(M(e,r)),o.set(r,t)),t}function M(e,r){return a.createStream(o=>{const t=n=>{o.next(I(n))};return e.addEventListener("wheel",t,{passive:r}),()=>{e.removeEventListener("wheel",t)}})}function q(e,r){const o=r?.passive??!0,t=r?.modifiers,n=r?.preventDefault??!1,i=G(e,o);if(!t?.length&&!n)return i;const s=c=>!t||t.length===0?!0:t.some(u=>{switch(u){case"meta":return c.metaKey;case"ctrl":return c.ctrlKey;case"alt":return c.altKey;case"shift":return c.shiftKey;default:return!1}});return a.createStream(c=>i.subscribe({next(u){try{s(u.value)&&(n&&u.value.originalEvent.preventDefault(),c.next(u))}catch(l){c.error?.(l)}},error:c.error?.bind(c),complete:c.complete?.bind(c)}))}function C(...e){return r=>N(r,...e)}function N(e,...r){return r.reduce((o,t)=>t(o),e)}exports.createSignal=a.createSignal;exports.createStream=a.createStream;exports.setCerebDeviceId=a.setCerebDeviceId;exports.KEYBOARD_SIGNAL_KIND=d.KEYBOARD_SIGNAL_KIND;exports.createKeyboardSignal=d.createKeyboardSignal;exports.createKeyboardSignalFromEvent=d.createKeyboardSignalFromEvent;exports.keyboard=d.keyboard;exports.WHEEL_SIGNAL_KIND=P;exports.compose=C;exports.createWheelSignal=K;exports.createWheelSignalFromEvent=I;exports.domEvent=D;exports.mouseEvents=T;exports.multiPointer=X;exports.multiPointerFromPointer=y;exports.pipe=N;exports.pointerEvents=S;exports.singlePointer=R;exports.touchEvents=A;exports.wheel=q;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -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/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\nexport function domEvent(\n target: EventTarget,\n eventName: string,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<Event>> {\n return createStream<DomEventSignal<Event>>((observer) => {\n const handler = (e: Event) => {\n observer.next(createDomEventSignal(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\n/**\n * Creates a stream of keyboard signals from keydown and keyup events on the target.\n *\n * @example\n * ```typescript\n * keyboard(window).subscribe(signal => {\n * console.log(signal.value.key, signal.value.phase);\n * });\n * ```\n */\nexport function keyboard(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","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 { 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/**\n * Creates a stream of wheel signals from wheel events on the target.\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 passive: false to allow preventDefault\n * wheel(element, { passive: false }).subscribe(signal => {\n * signal.value.originalEvent.preventDefault();\n * });\n * ```\n */\nexport function wheel(target: EventTarget, options?: WheelOptions): Stream<WheelSignal> {\n const passive = options?.passive ?? true;\n\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","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","e","MOUSE_EVENTS","mouseEvents","i","POINTER_EVENTS","pointerEvents","TOUCH_EVENTS","touchEvents","KEYBOARD_SIGNAL_KIND","createKeyboardSignal","value","createKeyboardSignalFromEvent","phase","keyboard","handleKeyDown","handleKeyUp","MULTI_POINTER_SIGNAL_KIND","createMultiPointerSignal","multiPointer","createMultiPointerRecognizer","processor","opts","activePointers","previousPhase","computePhase","count","endedCount","inputSignal","result","endedPointerIds","id","pointers","createPointerRecognizer","domEventSignal","pointerMap","createPointerInfo","multiPointerFromPointer","source","recognizer","unsub","signal","err","button","toSinglePointerButton","normalizePointerType","type","singlePointer","singlePointerFromPointer","WHEEL_SIGNAL_KIND","createWheelSignal","toDeltaMode","mode","createWheelSignalFromEvent","wheel","passive","compose","operators","pipe","prev","op"],"mappings":"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"}
|
|
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/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\nexport function domEvent(\n target: EventTarget,\n eventName: string,\n options?: AddEventListenerOptions,\n): Stream<DomEventSignal<Event>> {\n return createStream<DomEventSignal<Event>>((observer) => {\n const handler = (e: Event) => {\n observer.next(createDomEventSignal(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\";\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","e","MOUSE_EVENTS","mouseEvents","i","POINTER_EVENTS","pointerEvents","TOUCH_EVENTS","touchEvents","MULTI_POINTER_SIGNAL_KIND","createMultiPointerSignal","multiPointer","createMultiPointerRecognizer","processor","opts","activePointers","previousPhase","computePhase","count","endedCount","inputSignal","result","endedPointerIds","id","pointers","phase","createPointerRecognizer","domEventSignal","pointerMap","createPointerInfo","multiPointerFromPointer","source","recognizer","unsub","signal","err","button","toSinglePointerButton","normalizePointerType","type","singlePointer","singlePointerFromPointer","WHEEL_SIGNAL_KIND","createWheelSignal","value","toDeltaMode","mode","createWheelSignalFromEvent","sharedWheelStreams","getSharedWheel","passive","passiveMap","stream","share","createWheelStream","wheel","modifiers","preventDefault","matchesModifiers","mod","compose","operators","pipe","prev","op"],"mappings":"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"}
|