cereb 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -76
- package/dist/browser/keyboard/keyboard.d.ts +2 -2
- package/dist/browser/wheel/wheel.d.ts +2 -2
- package/dist/core/stream.d.ts +14 -2
- package/dist/core/stream.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +101 -109
- package/dist/index.js.map +1 -1
- package/dist/internal/subject.d.ts.map +1 -1
- package/dist/operators/compose.d.ts.map +1 -0
- package/dist/operators/index.d.ts +1 -0
- package/dist/operators/index.d.ts.map +1 -1
- package/dist/operators/share.d.ts.map +1 -1
- package/dist/operators/spy.d.ts +8 -10
- package/dist/operators/spy.d.ts.map +1 -1
- package/dist/operators/when.d.ts +1 -1
- package/dist/operators/zoom.d.ts +1 -1
- package/dist/operators.cjs +1 -1
- package/dist/operators.cjs.map +1 -1
- package/dist/operators.js +179 -175
- package/dist/operators.js.map +1 -1
- package/dist/share-BEu5SsOX.js +97 -0
- package/dist/share-BEu5SsOX.js.map +1 -0
- package/dist/share-vzh9f3Jn.cjs +2 -0
- package/dist/share-vzh9f3Jn.cjs.map +1 -0
- package/dist/single-pointer/mouse.cjs +1 -1
- package/dist/single-pointer/mouse.cjs.map +1 -1
- package/dist/single-pointer/mouse.js +4 -4
- package/dist/single-pointer/mouse.js.map +1 -1
- package/dist/single-pointer/pointer.cjs +1 -1
- package/dist/single-pointer/pointer.cjs.map +1 -1
- package/dist/single-pointer/pointer.js +15 -15
- package/dist/single-pointer/pointer.js.map +1 -1
- package/dist/single-pointer/touch.cjs +1 -1
- package/dist/single-pointer/touch.cjs.map +1 -1
- package/dist/single-pointer/touch.js +8 -8
- package/dist/single-pointer/touch.js.map +1 -1
- package/dist/stream-BvdJvQie.cjs +2 -0
- package/dist/stream-BvdJvQie.cjs.map +1 -0
- package/dist/stream-Y3XFAhlB.js +41 -0
- package/dist/stream-Y3XFAhlB.js.map +1 -0
- package/package.json +1 -1
- package/dist/ochestrations/compose.d.ts.map +0 -1
- package/dist/ochestrations/index.d.ts +0 -3
- package/dist/ochestrations/index.d.ts.map +0 -1
- package/dist/ochestrations/pipe.d.ts +0 -13
- package/dist/ochestrations/pipe.d.ts.map +0 -1
- package/dist/share-DT0L7vCb.cjs +0 -2
- package/dist/share-DT0L7vCb.cjs.map +0 -1
- package/dist/share-Dv3-CdCE.js +0 -89
- package/dist/share-Dv3-CdCE.js.map +0 -1
- package/dist/stream-CDK0RZPi.js +0 -33
- package/dist/stream-CDK0RZPi.js.map +0 -1
- package/dist/stream-Cp6eCZs2.cjs +0 -2
- package/dist/stream-Cp6eCZs2.cjs.map +0 -1
- /package/dist/{ochestrations → operators}/compose.d.ts +0 -0
package/README.md
CHANGED
|
@@ -16,8 +16,8 @@ import { singlePointer } from "cereb";
|
|
|
16
16
|
|
|
17
17
|
// Create a stream from pointer events
|
|
18
18
|
singlePointer(canvas)
|
|
19
|
-
//
|
|
20
|
-
.
|
|
19
|
+
// Listen to stream events
|
|
20
|
+
.on((signal) => {
|
|
21
21
|
// Receive signals from the stream
|
|
22
22
|
const { phase, x, y } = signal.value;
|
|
23
23
|
switch (phase){
|
|
@@ -44,21 +44,20 @@ npm install --save cereb @cereb/pinch
|
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
|
-
import { pipe } from "cereb";
|
|
48
47
|
import { zoom } from "cereb/operators";
|
|
49
48
|
import { pinch } from "@cereb/pinch";
|
|
50
49
|
|
|
51
50
|
// pipe creates a pipeline where signals flow through operators
|
|
52
51
|
// Each operator extends the signal (signals are immutable)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
zoom({ minScale: 0.5, maxScale: 3.0 })
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
});
|
|
52
|
+
pinch(element)
|
|
53
|
+
// Operator: Determine scale value.
|
|
54
|
+
.pipe(zoom({ minScale: 0.5, maxScale: 3.0 }))
|
|
55
|
+
.on((signal) => {
|
|
56
|
+
// The scale property is extended from the value.
|
|
57
|
+
// - pinch emits distance → zoom calculates scale
|
|
58
|
+
// - zoom also works with other inputs (keyboard, wheel, etc.)
|
|
59
|
+
element.style.transform = `scale(${signal.value.scale})`;
|
|
60
|
+
});
|
|
62
61
|
```
|
|
63
62
|
|
|
64
63
|
## API overview
|
|
@@ -73,87 +72,98 @@ In the meantime, check the source—it's well-typed and commented:
|
|
|
73
72
|
|
|
74
73
|
### 1. Event-Driven Code Becomes Spaghetti
|
|
75
74
|
|
|
76
|
-
Traditional event handlers create **scattered logic, side effects, and duplicated code** that's hard to maintain.
|
|
75
|
+
Traditional event handlers create **scattered logic, side effects, and duplicated code** that's hard to maintain.
|
|
77
76
|
See how this plays out in a multi-input zoom implementation:
|
|
78
77
|
|
|
79
78
|
```typescript
|
|
80
79
|
// Before: Scattered handlers, shared state, duplicated logic
|
|
81
80
|
let currentScale = 1;
|
|
82
|
-
let
|
|
81
|
+
let isZoomMode = false;
|
|
82
|
+
let initialPinchDistance = 0;
|
|
83
83
|
|
|
84
|
-
// Track Ctrl key
|
|
85
84
|
window.addEventListener('keydown', e => {
|
|
86
|
-
if (e.key === '
|
|
87
|
-
|
|
88
|
-
if (isCtrlPressed && (e.key === '+' || e.key === '-')) {
|
|
85
|
+
if (e.key === 'z') { isZoomMode = true; toggleZoomModeIndicator(true); }
|
|
86
|
+
if (isZoomMode && (e.key === '+' || e.key === '=' || e.key === '-')) {
|
|
89
87
|
e.preventDefault();
|
|
90
|
-
currentScale = Math.max(
|
|
91
|
-
|
|
88
|
+
currentScale = Math.max(MIN, Math.min(MAX, currentScale + ...));
|
|
89
|
+
render(currentScale); // min/max logic here
|
|
92
90
|
}
|
|
93
91
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
92
|
+
window.addEventListener('keyup', e => { /* isZoomMode = false ... */ });
|
|
93
|
+
|
|
94
|
+
box.addEventListener('wheel', e => {
|
|
95
|
+
if (!isZoomMode) return;
|
|
96
|
+
currentScale = Math.max(MIN, Math.min(MAX, ...)); // duplicated
|
|
97
|
+
render(currentScale);
|
|
98
|
+
}, { passive: false });
|
|
99
|
+
|
|
100
|
+
// Pinch: touchstart/touchmove/touchend, track two fingers, calculate distance...
|
|
101
|
+
box.addEventListener('touchstart', e => { /* ... */ });
|
|
102
|
+
box.addEventListener('touchmove', e => {
|
|
103
|
+
// ... 10+ lines: distance calculation, ratio, min/max again
|
|
105
104
|
});
|
|
105
|
+
box.addEventListener('touchend', () => { /* cleanup */ });
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
//
|
|
109
|
-
// ... min/max logic duplicated yet again
|
|
110
|
-
|
|
111
|
-
// Problem: 6+ scattered handlers, shared state, logic duplicated 3 times
|
|
107
|
+
slider.addEventListener('input', e => { /* ... min/max again */ });
|
|
108
|
+
// 8 handlers, 3+ shared states, min/max duplicated everywhere
|
|
112
109
|
```
|
|
113
110
|
|
|
114
111
|
<br>
|
|
115
112
|
|
|
116
|
-
Cereb's solution:
|
|
113
|
+
Cereb's solution:
|
|
117
114
|
Model events as streams, and you get readable, reusable, extensible declarative pipelines.
|
|
118
115
|
|
|
119
116
|
```typescript
|
|
120
117
|
// After: Clear flow, no side effects, composable
|
|
121
|
-
import {
|
|
118
|
+
import { keyboard, keyboardHeld, wheel, domEvent } from "cereb";
|
|
122
119
|
import { zoom, extend, when } from "cereb/operators";
|
|
123
120
|
import { pinch } from "@cereb/pinch";
|
|
124
121
|
|
|
125
122
|
const MIN_SCALE = 0.2, MAX_SCALE = 5;
|
|
126
|
-
let currentScale = 1;
|
|
127
123
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
124
|
+
// 'z' key pressed to enter Zoom Mode Stream
|
|
125
|
+
const isInZoomMode$ = keyboardHeld(window, { key: "z" });
|
|
126
|
+
isInZoomMode$.on(toggleZoomModeIndicator);
|
|
127
|
+
|
|
128
|
+
// Pinch Zoom
|
|
129
|
+
pinch(box, { threshold: 10 })
|
|
130
|
+
.pipe(zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE }))
|
|
131
|
+
.on(render);
|
|
132
|
+
|
|
133
|
+
// 'z' + '+/-'
|
|
134
|
+
keyboard(window, { key: ["+", "=", "-"], preventDefault: true })
|
|
135
|
+
.pipe(
|
|
136
|
+
when(isInZoomMode$),
|
|
137
|
+
extend<KeyboardSignal, ZoomInput>((signal) => ({
|
|
138
|
+
ratio: zoomManager.getScale() + (signal.value.key === "+" || signal.value.key === "=" ? 0.15 : -0.15),
|
|
139
|
+
})),
|
|
140
|
+
zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE }),
|
|
141
|
+
).on(render);
|
|
142
|
+
|
|
143
|
+
// 'z' + 'wheel'
|
|
144
|
+
wheel(box, { passive: false, preventDefault: true })
|
|
145
|
+
.pipe(
|
|
146
|
+
when(isInZoomMode$),
|
|
147
|
+
extend<WheelSignal, ZoomInput>((signal) => ({
|
|
148
|
+
ratio: zoomManager.getScale() + (-signal.value.deltaY * 0.005),
|
|
149
|
+
})),
|
|
150
|
+
zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE }),
|
|
151
|
+
).on(render);
|
|
152
|
+
|
|
153
|
+
// 'Slider Input'
|
|
154
|
+
domEvent(slider, "input")
|
|
155
|
+
.pipe(
|
|
156
|
+
extend<DomEventSignal<Event>, ZoomInput>((signal) => {
|
|
157
|
+
const inputElement = signal.value.target as HTMLInputElement;
|
|
158
|
+
const value = Number(inputElement.value);
|
|
159
|
+
const logScale = logMin + (value / 100) * (logMax - logMin);
|
|
160
|
+
const scale = Math.exp(logScale);
|
|
161
|
+
return {
|
|
162
|
+
ratio: clamp(scale, MIN_SCALE, MAX_SCALE),
|
|
163
|
+
};
|
|
164
|
+
}),
|
|
165
|
+
zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE, baseScale: zoomManager.getScale() }),
|
|
166
|
+
).on(render);
|
|
157
167
|
```
|
|
158
168
|
|
|
159
169
|
### 2. Lightweight Bundle Size
|
|
@@ -179,19 +189,19 @@ window.addEventListener('keydown', handler3);
|
|
|
179
189
|
|
|
180
190
|
// After: Shared stream, single listener
|
|
181
191
|
// addEventListener called once
|
|
182
|
-
keyboard(window).
|
|
183
|
-
keyboard(window).
|
|
184
|
-
keyboard(window).
|
|
192
|
+
keyboard(window).on(handler1);
|
|
193
|
+
keyboard(window).on(handler2);
|
|
194
|
+
keyboard(window).on(handler3);
|
|
185
195
|
```
|
|
186
196
|
|
|
187
197
|
**2. Single Responsibility Operators**
|
|
188
198
|
|
|
189
199
|
```typescript
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
)
|
|
200
|
+
pan(element) // Pan gesture recognition
|
|
201
|
+
.pipe(
|
|
202
|
+
offset({ target }), // Element-relative coordinates
|
|
203
|
+
axisLock() // Lock to horizontal/vertical
|
|
204
|
+
)
|
|
195
205
|
```
|
|
196
206
|
|
|
197
207
|
## License
|
|
@@ -15,8 +15,8 @@ export interface KeyboardOptions {
|
|
|
15
15
|
* Creates a keyboard signal stream. Shares underlying listeners per EventTarget.
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
|
-
* keyboard(window).
|
|
19
|
-
* keyboard(window, { key: 'z', modifiers: ['meta'] }).
|
|
18
|
+
* keyboard(window).on(signal => console.log(signal.value.key));
|
|
19
|
+
* keyboard(window, { key: 'z', modifiers: ['meta'] }).on(handleUndo);
|
|
20
20
|
*/
|
|
21
21
|
export declare function keyboard(target: EventTarget, options?: KeyboardOptions): Stream<KeyboardSignal>;
|
|
22
22
|
//# sourceMappingURL=keyboard.d.ts.map
|
|
@@ -27,7 +27,7 @@ export interface WheelOptions {
|
|
|
27
27
|
* @example
|
|
28
28
|
* ```typescript
|
|
29
29
|
* // Basic usage (passive by default for performance)
|
|
30
|
-
* wheel(element).
|
|
30
|
+
* wheel(element).on(signal => {
|
|
31
31
|
* console.log(signal.value.deltaY);
|
|
32
32
|
* });
|
|
33
33
|
*
|
|
@@ -36,7 +36,7 @@ export interface WheelOptions {
|
|
|
36
36
|
* passive: false,
|
|
37
37
|
* modifiers: ['meta', 'ctrl'],
|
|
38
38
|
* preventDefault: true
|
|
39
|
-
* }).
|
|
39
|
+
* }).on(signal => {
|
|
40
40
|
* // Only fires when Ctrl or Cmd is held
|
|
41
41
|
* });
|
|
42
42
|
* ```
|
package/dist/core/stream.d.ts
CHANGED
|
@@ -5,22 +5,34 @@ export interface Observer<T extends Signal> {
|
|
|
5
5
|
error?(err: unknown): void;
|
|
6
6
|
complete?(): void;
|
|
7
7
|
}
|
|
8
|
+
export type Operator<T extends Signal, R extends Signal> = (source: Stream<T>) => Stream<R>;
|
|
8
9
|
/**
|
|
9
10
|
* Stream is the core reactive abstraction in Cereb.
|
|
10
11
|
* All streams are blockable - when blocked, events are silently dropped.
|
|
11
12
|
* By default, streams support a single observer. Use share() for multicast.
|
|
12
13
|
*/
|
|
13
14
|
export interface Stream<T extends Signal> {
|
|
14
|
-
|
|
15
|
+
on(observer: Observer<T> | ((value: T) => void)): Unsubscribe;
|
|
15
16
|
/** Block event propagation. Events are dropped, not queued. */
|
|
16
17
|
block(): void;
|
|
17
18
|
/** Unblock event propagation, resuming normal flow. */
|
|
18
19
|
unblock(): void;
|
|
19
20
|
/** Returns true if the stream is currently blocked. */
|
|
20
21
|
readonly isBlocked: boolean;
|
|
22
|
+
/** Chain operators to transform this stream. */
|
|
23
|
+
pipe(): Stream<T>;
|
|
24
|
+
pipe<A extends Signal>(op1: Operator<T, A>): Stream<A>;
|
|
25
|
+
pipe<A extends Signal, B extends Signal>(op1: Operator<T, A>, op2: Operator<A, B>): Stream<B>;
|
|
26
|
+
pipe<A extends Signal, B extends Signal, C extends Signal>(op1: Operator<T, A>, op2: Operator<A, B>, op3: Operator<B, C>): Stream<C>;
|
|
27
|
+
pipe<A extends Signal, B extends Signal, C extends Signal, D extends Signal>(op1: Operator<T, A>, op2: Operator<A, B>, op3: Operator<B, C>, op4: Operator<C, D>): Stream<D>;
|
|
28
|
+
pipe<A extends Signal, B extends Signal, C extends Signal, D extends Signal, E extends Signal>(op1: Operator<T, A>, op2: Operator<A, B>, op3: Operator<B, C>, op4: Operator<C, D>, op5: Operator<D, E>): Stream<E>;
|
|
29
|
+
pipe<A extends Signal, B extends Signal, C extends Signal, D extends Signal, E extends Signal, F extends Signal>(op1: Operator<T, A>, op2: Operator<A, B>, op3: Operator<B, C>, op4: Operator<C, D>, op5: Operator<D, E>, op6: Operator<E, F>): Stream<F>;
|
|
30
|
+
pipe<A extends Signal, B extends Signal, C extends Signal, D extends Signal, E extends Signal, F extends Signal, G extends Signal>(op1: Operator<T, A>, op2: Operator<A, B>, op3: Operator<B, C>, op4: Operator<C, D>, op5: Operator<D, E>, op6: Operator<E, F>, op7: Operator<F, G>): Stream<G>;
|
|
31
|
+
pipe<A extends Signal, B extends Signal, C extends Signal, D extends Signal, E extends Signal, F extends Signal, G extends Signal, H extends Signal>(op1: Operator<T, A>, op2: Operator<A, B>, op3: Operator<B, C>, op4: Operator<C, D>, op5: Operator<D, E>, op6: Operator<E, F>, op7: Operator<F, G>, op8: Operator<G, H>): Stream<H>;
|
|
32
|
+
pipe(...operators: Operator<Signal, Signal>[]): Stream<Signal>;
|
|
21
33
|
}
|
|
22
|
-
export type Operator<T extends Signal, R extends Signal> = (source: Stream<T>) => Stream<R>;
|
|
23
34
|
export declare function toObserver<T extends Signal>(observerOrNext: Observer<T> | ((value: T) => void)): Observer<T>;
|
|
35
|
+
export declare function pipeStream<T extends Signal>(stream: Stream<T>, operators: Operator<Signal, Signal>[]): Stream<Signal>;
|
|
24
36
|
/**
|
|
25
37
|
* Creates a Stream from a subscribe function.
|
|
26
38
|
* The stream can be blocked/unblocked to control event flow.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/core/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,MAAM;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,IAAI,IAAI,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC,SAAS,MAAM;IACtC,
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/core/stream.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./stream-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./stream-BvdJvQie.cjs"),m=require("./recognizer-DbiEtBOM.cjs"),I=require("./share-vzh9f3Jn.cjs"),X=require("./types-BGR5Mhw9.cjs"),F=require("./single-pointer/pointer.cjs"),q="dom-event";function L(e){return m.createSignal(q,e)}function $(e,r,o){return d.createStream(t=>{const n=c=>{t.next(L(c))};return e.addEventListener(r,n,o),()=>{e.removeEventListener(r,n,o)}})}const K=["mousedown","mousemove","mouseup"];function U(e,r){return d.createStream(o=>{const t=n=>{o.next(L(n))};for(let n=0;n<K.length;n++){const c=K[n];e.addEventListener(c,t,r)}return()=>{for(let n=0;n<K.length;n++){const c=K[n];e.removeEventListener(c,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 c=S[n];e.addEventListener(c,t,r)}return()=>{for(let n=0;n<S.length;n++){const c=S[n];e.removeEventListener(c,t,r)}}})}const E=["touchstart","touchmove","touchend","touchcancel"];function V(e,r){return d.createStream(o=>{const t=n=>{o.next(L(n))};for(let n=0;n<E.length;n++){const c=E[n];e.addEventListener(c,t,r)}return()=>{for(let n=0;n<E.length;n++){const c=E[n];e.removeEventListener(c,t,r)}}})}const M="keyboard";function T(e){return m.createSignal(M,e)}function P(e,r){return T({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 x=new WeakMap,D=new WeakMap;function B(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=x.get(e);return r||(r=I.share()(B(e)),x.set(e,r)),r}function b(e,r){const o=r.toLowerCase();let t=D.get(e);t||(t=new Map,D.set(e,t));let n=t.get(o);if(!n){const c=w(e),s=d.createStream(i=>c.on({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 Z(e,r){if(!r)return w(e);const o=r.modifiers,t=r.preventDefault??!1,n=r.allowRepeat??!1,c=typeof r.key=="string",s=r.key&&Array.isArray(r.key)?r.key.map(a=>a.toLowerCase()):null,i=c?b(e,r.key):w(e);if(c&&!o&&!t&&!n)return i;const u=a=>s?s.includes(a.toLowerCase()):!0,f=a=>!o||o.length===0?!0:o.some(l=>{switch(l){case"meta":return a.metaKey;case"ctrl":return a.ctrlKey;case"alt":return a.altKey;case"shift":return a.shiftKey;default:return!1}});return d.createStream(a=>i.on({next(l){const{key:y,repeat:k}=l.value;!n&&k||u(y)&&f(l.value)&&(t&&l.value.originalEvent.preventDefault(),a.next(l))},error:a.error?.bind(a),complete:a.complete?.bind(a)}))}const A="keyboard-held";function j(e,r){const{key:o,modifiers:t}=r,n=o.toLowerCase(),s=t&&t.length>0?w(e):b(e,o),i=new Set;if(t)for(const a of t)a==="meta"&&i.add("meta"),a==="ctrl"&&i.add("control"),a==="alt"&&i.add("alt"),a==="shift"&&i.add("shift");const u=a=>i.has(a.toLowerCase()),f=a=>!t||t.length===0?!0:t.some(l=>{switch(l){case"meta":return a.metaKey;case"ctrl":return a.ctrlKey;case"alt":return a.altKey;case"shift":return a.shiftKey;default:return!1}});return d.createStream(a=>{let l=!1,y;const k=h=>{h!==y&&(y=h,a.next(m.createSignal(A,{opened:h})))};return s.on({next(h){try{const{key:p,phase:v,repeat:Y}=h.value;if(Y)return;const z=p.toLowerCase()===n,G=u(p);z?l=v==="down":(v==="down"||G&&v==="up")&&(l=!1);const O=f(h.value);k(l&&O)}catch(p){a.error?.(p)}},error:a.error?.bind(a),complete:a.complete?.bind(a)})})}const J="multi-pointer";function Q(e){return m.createSignal(J,e)}function ee(e,r={}){const o={maxPointers:r.maxPointers??2},t=new Map;let n="idle";function c(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()),a=c(f.length,u.length);n=a==="ended"?"idle":a;const l={phase:a,pointers:f,count:f.length};return Q(l)},get isActive(){return t.size>0},get activeCount(){return t.size},reset(){t.clear(),n="idle"},dispose(){this.reset()}}}function te(e={}){function r(o,t,n){const c=o.value,s=`${c.pointerType}-${c.pointerId}`,i=[];switch(c.type){case"pointerdown":{if(t.size>=n.maxPointers)return null;t.set(s,g(c,"start"));break}case"pointermove":{if(!t.has(s))return null;t.set(s,g(c,"move"));break}case"pointerup":{if(!t.has(s))return null;t.set(s,g(c,"end")),i.push(s);break}case"pointercancel":{if(!t.has(s))return null;t.set(s,g(c,"cancel")),i.push(s);break}default:return null}return{pointers:t,endedPointerIds:i}}return ee(r,e)}function C(e={}){return r=>d.createStream(o=>{const t=te(e),n=r.on({next(c){const s=t.process(c);s&&o.next(s)},error(c){o.error?.(c)},complete(){o.complete?.()}});return()=>{n(),t.dispose()}})}function g(e,r){const o=r==="start"||r==="end"?X.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:re(e.pointerType),button:o,pressure:e.pressure}}function re(e){switch(e){case"mouse":return"mouse";case"touch":return"touch";case"pen":return"pen";default:return"unknown"}}function ne(e,r={}){const o=N(e);return C(r)(o)}function oe(e,r={}){const o=N(e);return F.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 _=new WeakMap;function ce(e,r){let o=_.get(e);o||(o=new Map,_.set(e,o));let t=o.get(r);return t||(t=I.share()(ie(e,r)),o.set(r,t)),t}function ie(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 se(e,r){const o=r?.passive??!0,t=r?.modifiers,n=r?.preventDefault??!1,c=ce(e,o);if(!t?.length&&!n)return c;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=>c.on({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)}))}exports.createStream=d.createStream;exports.createSignal=m.createSignal;exports.setCerebDeviceId=m.setCerebDeviceId;exports.HELD_SIGNAL_KIND=A;exports.KEYBOARD_SIGNAL_KIND=M;exports.WHEEL_SIGNAL_KIND=W;exports.createKeyboardSignal=T;exports.createKeyboardSignalFromEvent=P;exports.createWheelSignal=H;exports.createWheelSignalFromEvent=R;exports.domEvent=$;exports.keyboard=Z;exports.keyboardHeld=j;exports.mouseEvents=U;exports.multiPointer=ne;exports.multiPointerFromPointer=C;exports.pointerEvents=N;exports.singlePointer=oe;exports.touchEvents=V;exports.wheel=se;
|
|
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/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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"}
|
|
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"],"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.on({\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).on(signal => console.log(signal.value.key));\n * keyboard(window, { key: 'z', modifiers: ['meta'] }).on(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.on({\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.on({\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.on({\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).on(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 * }).on(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.on({\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"],"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"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC"}
|