@kelnishi/satmouse-client 0.9.14 → 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.
@@ -1,99 +1,56 @@
1
- import { V as Vec3, S as SpatialData, D as DeviceInfo, e as TypedEmitter, B as ButtonEvent, a as ConnectionState, d as TransportProtocol, b as SatMouseConnection } from '../connection-5KQFvHoJ.cjs';
1
+ import { S as SpatialData, D as DeviceInfo, e as TypedEmitter, B as ButtonEvent, a as ConnectionState, d as TransportProtocol, b as SatMouseConnection } from '../connection-DQxI5qib.cjs';
2
2
 
3
- interface FlipConfig {
4
- tx: boolean;
5
- ty: boolean;
6
- tz: boolean;
7
- rx: boolean;
8
- ry: boolean;
9
- rz: boolean;
10
- }
11
- interface SensitivityConfig {
12
- translation: number;
13
- rotation: number;
14
- }
15
- /** Maps each input axis to an output axis. E.g., { tx: "tz", tz: "tx" } swaps X and Z translation. */
16
- type AxisMap = {
17
- tx: keyof Vec3;
18
- ty: keyof Vec3;
19
- tz: keyof Vec3;
20
- rx: keyof Vec3;
21
- ry: keyof Vec3;
22
- rz: keyof Vec3;
23
- };
24
- declare const DEFAULT_AXIS_MAP: AxisMap;
25
- declare function applyFlip(data: SpatialData, flip: FlipConfig): SpatialData;
26
- declare function applySensitivity(data: SpatialData, sens: SensitivityConfig): SpatialData;
27
- declare function applyDominant(data: SpatialData): SpatialData;
28
- declare function applyDeadZone(data: SpatialData, threshold: number): SpatialData;
29
- declare function applyAxisRemap(data: SpatialData, map: AxisMap): SpatialData;
30
-
31
- /** Input axis identifier */
32
- type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz";
33
- /** A single action binding — maps one input axis to a named output */
34
- interface ActionBinding {
35
- /** Which input axis drives this action */
3
+ /** Axis identifier — full or half */
4
+ type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz" | "tx+" | "ty+" | "tz+" | "rx+" | "ry+" | "rz+" | "tx-" | "ty-" | "tz-" | "rx-" | "ry-" | "rz-";
5
+ /** The 6 full output axes */
6
+ declare const FULL_AXES: InputAxis[];
7
+ /** A single axis route — reads from source, writes to target */
8
+ interface AxisRoute {
36
9
  source: InputAxis;
37
- /** Scale multiplier (default: 1) */
38
- scale?: number;
39
- /** Invert the value (default: false) */
40
- invert?: boolean;
10
+ target: InputAxis;
11
+ /** Negate the value (default: false) */
12
+ flip?: boolean;
41
13
  }
42
- /**
43
- * ActionMap defines how raw 6DOF axes map to named output actions.
44
- *
45
- * Client apps declare the actions they support and how device axes
46
- * feed into them. Users can reassign axes via the settings UI.
47
- *
48
- * Default: 6 actions matching the 6 input axes (passthrough).
49
- */
50
- type ActionMap = Record<string, ActionBinding>;
51
- /** Default passthrough — each axis maps to itself */
52
- declare const DEFAULT_ACTION_MAP: ActionMap;
53
- /** Result of applying an ActionMap to spatial data */
54
- type ActionValues = Record<string, number>;
55
- /** Apply an ActionMap to SpatialData, producing named action values */
56
- declare function applyActionMap(data: SpatialData, map: ActionMap): ActionValues;
57
- /**
58
- * Convert ActionValues back to SpatialData.
59
- * Only populates tx/ty/tz/rx/ry/rz keys if they exist as actions.
60
- */
61
- declare function actionValuesToSpatialData(values: ActionValues, timestamp: number): SpatialData;
62
- /** Swap two action bindings */
63
- declare function swapActions(map: ActionMap, actionA: string, actionB: string): ActionMap;
14
+ /** Default 6DOF passthrough */
15
+ declare const DEFAULT_ROUTES: AxisRoute[];
16
+ /** Build passthrough routes from a device's axis list. Half-axes target their base axis.
17
+ * Negative half-axes (e.g., "ty-") get flip: true. */
18
+ declare function buildRoutes(axes: string[]): AxisRoute[];
19
+ /** Apply routes to SpatialData. Multiple routes targeting the same axis accumulate.
20
+ * @param scale global scale multiplier applied to all routes */
21
+ declare function applyRoutes(data: SpatialData, routes: AxisRoute[], scale?: number): SpatialData;
64
22
 
65
- /** Per-device transform overrides. Any field left undefined inherits from global defaults. */
23
+ /** Per-device configuration */
66
24
  interface DeviceConfig {
67
- sensitivity?: Partial<SensitivityConfig>;
68
- flip?: Partial<FlipConfig>;
25
+ /** Axis routing — each entry maps a device input to an output with optional flip */
26
+ routes?: AxisRoute[];
27
+ /** Scale multiplier applied to all axes (default: 1) */
28
+ scale?: number;
29
+ /** Dead zone threshold (0-1). Values below this are zeroed. */
69
30
  deadZone?: number;
31
+ /** Only pass the strongest axis, zero all others */
70
32
  dominant?: boolean;
71
- axisRemap?: Partial<AxisMap>;
72
- actionMap?: ActionMap;
73
- lockPosition?: boolean;
74
- lockRotation?: boolean;
75
33
  }
34
+ /** Global configuration */
76
35
  interface InputConfig {
77
- /** Global defaults applied to all devices */
78
- sensitivity: SensitivityConfig;
79
- flip: FlipConfig;
36
+ /** Default axis routes (used when device has no override) */
37
+ routes: AxisRoute[];
38
+ /** Default scale */
39
+ scale: number;
40
+ /** Dead zone threshold */
80
41
  deadZone: number;
42
+ /** Dominant axis mode */
81
43
  dominant: boolean;
82
- axisRemap: AxisMap;
44
+ /** Lock translation to zero */
83
45
  lockPosition: boolean;
46
+ /** Lock rotation to zero */
84
47
  lockRotation: boolean;
85
- /** Action map maps input axes to named output actions. Default: passthrough. */
86
- actionMap: ActionMap;
87
- /**
88
- * Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
89
- * or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
90
- * Values override global defaults for matching devices.
91
- */
48
+ /** Per-device overrides keyed by device ID or pattern (e.g., "cnx-*") */
92
49
  devices: Record<string, DeviceConfig>;
93
50
  }
94
51
  declare const DEFAULT_CONFIG: InputConfig;
95
52
  declare function mergeConfig(base: InputConfig, partial: Partial<InputConfig>): InputConfig;
96
- /** Resolve the effective config for a specific device by merging global + device overrides */
53
+ /** Resolve the effective config for a specific device */
97
54
  declare function resolveDeviceConfig(config: InputConfig, deviceId: string): InputConfig;
98
55
 
99
56
  interface StorageAdapter {
@@ -104,36 +61,17 @@ declare function saveSettings(config: InputConfig, storage?: StorageAdapter): vo
104
61
  declare function loadSettings(storage?: StorageAdapter): Partial<InputConfig> | null;
105
62
 
106
63
  interface InputManagerEvents {
107
- /** Processed spatial data (after all transforms + action map) */
108
64
  spatialData: (data: SpatialData) => void;
109
- /** Named action values from the action map */
110
- actionValues: (values: ActionValues) => void;
111
- /** Raw spatial data (before transforms) */
112
65
  rawSpatialData: (data: SpatialData) => void;
113
- /** Button event (pass-through from connection) */
114
66
  buttonEvent: (data: ButtonEvent) => void;
115
- /** Connection state changed */
116
67
  stateChange: (state: ConnectionState, protocol: TransportProtocol) => void;
117
- /** Device connected/disconnected */
118
68
  deviceStatus: (event: "connected" | "disconnected", device: DeviceInfo) => void;
119
- /** Configuration changed */
120
69
  configChange: (config: InputConfig) => void;
121
70
  }
122
- /** A connected device paired with its resolved configuration */
123
71
  interface DeviceWithConfig {
124
72
  device: DeviceInfo;
125
73
  config: DeviceConfig;
126
74
  }
127
- /**
128
- * Unified device service that wraps one or more SatMouseConnections
129
- * and provides a single processed event stream.
130
- *
131
- * Applies a configurable transform pipeline per-device:
132
- * deadZone → dominant → flip → axisRemap → sensitivity → lock
133
- *
134
- * Per-device overrides are resolved from InputConfig.devices using
135
- * device ID matching (exact or pattern with wildcard "*").
136
- */
137
75
  declare class InputManager extends TypedEmitter<InputManagerEvents> {
138
76
  private connections;
139
77
  private storage?;
@@ -144,36 +82,25 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
144
82
  private _config;
145
83
  get config(): InputConfig;
146
84
  constructor(config?: Partial<InputConfig>, storage?: StorageAdapter);
147
- /** Add a connection to the managed set */
148
85
  addConnection(connection: SatMouseConnection): void;
149
- /** Remove a connection */
150
86
  removeConnection(connection: SatMouseConnection): void;
151
- /** Connect all managed connections */
152
87
  connect(): Promise<void>;
153
- /** Disconnect all managed connections */
154
88
  disconnect(): void;
155
- /** Fetch device info from all connections */
156
89
  fetchDeviceInfo(): Promise<DeviceInfo[]>;
157
- /** Get all known connected devices paired with their resolved config */
158
90
  getDevicesWithConfig(): DeviceWithConfig[];
159
- /** Get the resolved per-device config (global defaults + device overrides) */
160
91
  getDeviceConfig(deviceId: string): DeviceConfig;
161
- /** Update global configuration. Persists by default. */
162
92
  updateConfig(partial: Partial<InputConfig>, persist?: boolean): void;
163
- /** Update configuration for a specific device. Persists by default. */
164
93
  updateDeviceConfig(deviceId: string, partial: DeviceConfig, persist?: boolean): void;
165
- /** Register a callback for processed spatial data. Returns unsubscribe function. */
94
+ resetDeviceConfig(deviceId: string, persist?: boolean): void;
95
+ resetAllConfig(): void;
166
96
  onSpatialData(callback: (data: SpatialData) => void): () => void;
167
- /** Register a callback for button events. Returns unsubscribe function. */
168
97
  onButtonEvent(callback: (data: ButtonEvent) => void): () => void;
169
- /** Register a callback for action values. Returns unsubscribe function. */
170
- onActionValues(callback: (values: ActionValues) => void): () => void;
171
98
  private wireConnection;
172
99
  private flushAccumulator;
173
- /** Per-device transforms: flip, sensitivity, dead zone, dominant, axis remap */
100
+ /** Per-device: deadZone dominant routes (flip + scale + remap in one pass) */
174
101
  private processPerDevice;
175
- /** Global transforms applied after per-device merge: locks + action map */
176
- private applyGlobalTransforms;
102
+ /** Get the effective routes for a device: device config override > device axes metadata > global default */
103
+ private resolveRoutes;
177
104
  }
178
105
 
179
- export { type ActionBinding, type ActionMap, type ActionValues, type AxisMap, DEFAULT_ACTION_MAP, DEFAULT_AXIS_MAP, DEFAULT_CONFIG, type DeviceConfig, type DeviceWithConfig, type FlipConfig, type InputAxis, type InputConfig, InputManager, type InputManagerEvents, type SensitivityConfig, type StorageAdapter, actionValuesToSpatialData, applyActionMap, applyAxisRemap, applyDeadZone, applyDominant, applyFlip, applySensitivity, loadSettings, mergeConfig, resolveDeviceConfig, saveSettings, swapActions };
106
+ export { type AxisRoute, DEFAULT_CONFIG, DEFAULT_ROUTES, type DeviceConfig, type DeviceWithConfig, FULL_AXES, type InputAxis, type InputConfig, InputManager, type InputManagerEvents, type StorageAdapter, applyRoutes, buildRoutes, loadSettings, mergeConfig, resolveDeviceConfig, saveSettings };
@@ -1,99 +1,56 @@
1
- import { V as Vec3, S as SpatialData, D as DeviceInfo, e as TypedEmitter, B as ButtonEvent, a as ConnectionState, d as TransportProtocol, b as SatMouseConnection } from '../connection-5KQFvHoJ.js';
1
+ import { S as SpatialData, D as DeviceInfo, e as TypedEmitter, B as ButtonEvent, a as ConnectionState, d as TransportProtocol, b as SatMouseConnection } from '../connection-DQxI5qib.js';
2
2
 
3
- interface FlipConfig {
4
- tx: boolean;
5
- ty: boolean;
6
- tz: boolean;
7
- rx: boolean;
8
- ry: boolean;
9
- rz: boolean;
10
- }
11
- interface SensitivityConfig {
12
- translation: number;
13
- rotation: number;
14
- }
15
- /** Maps each input axis to an output axis. E.g., { tx: "tz", tz: "tx" } swaps X and Z translation. */
16
- type AxisMap = {
17
- tx: keyof Vec3;
18
- ty: keyof Vec3;
19
- tz: keyof Vec3;
20
- rx: keyof Vec3;
21
- ry: keyof Vec3;
22
- rz: keyof Vec3;
23
- };
24
- declare const DEFAULT_AXIS_MAP: AxisMap;
25
- declare function applyFlip(data: SpatialData, flip: FlipConfig): SpatialData;
26
- declare function applySensitivity(data: SpatialData, sens: SensitivityConfig): SpatialData;
27
- declare function applyDominant(data: SpatialData): SpatialData;
28
- declare function applyDeadZone(data: SpatialData, threshold: number): SpatialData;
29
- declare function applyAxisRemap(data: SpatialData, map: AxisMap): SpatialData;
30
-
31
- /** Input axis identifier */
32
- type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz";
33
- /** A single action binding — maps one input axis to a named output */
34
- interface ActionBinding {
35
- /** Which input axis drives this action */
3
+ /** Axis identifier — full or half */
4
+ type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz" | "tx+" | "ty+" | "tz+" | "rx+" | "ry+" | "rz+" | "tx-" | "ty-" | "tz-" | "rx-" | "ry-" | "rz-";
5
+ /** The 6 full output axes */
6
+ declare const FULL_AXES: InputAxis[];
7
+ /** A single axis route — reads from source, writes to target */
8
+ interface AxisRoute {
36
9
  source: InputAxis;
37
- /** Scale multiplier (default: 1) */
38
- scale?: number;
39
- /** Invert the value (default: false) */
40
- invert?: boolean;
10
+ target: InputAxis;
11
+ /** Negate the value (default: false) */
12
+ flip?: boolean;
41
13
  }
42
- /**
43
- * ActionMap defines how raw 6DOF axes map to named output actions.
44
- *
45
- * Client apps declare the actions they support and how device axes
46
- * feed into them. Users can reassign axes via the settings UI.
47
- *
48
- * Default: 6 actions matching the 6 input axes (passthrough).
49
- */
50
- type ActionMap = Record<string, ActionBinding>;
51
- /** Default passthrough — each axis maps to itself */
52
- declare const DEFAULT_ACTION_MAP: ActionMap;
53
- /** Result of applying an ActionMap to spatial data */
54
- type ActionValues = Record<string, number>;
55
- /** Apply an ActionMap to SpatialData, producing named action values */
56
- declare function applyActionMap(data: SpatialData, map: ActionMap): ActionValues;
57
- /**
58
- * Convert ActionValues back to SpatialData.
59
- * Only populates tx/ty/tz/rx/ry/rz keys if they exist as actions.
60
- */
61
- declare function actionValuesToSpatialData(values: ActionValues, timestamp: number): SpatialData;
62
- /** Swap two action bindings */
63
- declare function swapActions(map: ActionMap, actionA: string, actionB: string): ActionMap;
14
+ /** Default 6DOF passthrough */
15
+ declare const DEFAULT_ROUTES: AxisRoute[];
16
+ /** Build passthrough routes from a device's axis list. Half-axes target their base axis.
17
+ * Negative half-axes (e.g., "ty-") get flip: true. */
18
+ declare function buildRoutes(axes: string[]): AxisRoute[];
19
+ /** Apply routes to SpatialData. Multiple routes targeting the same axis accumulate.
20
+ * @param scale global scale multiplier applied to all routes */
21
+ declare function applyRoutes(data: SpatialData, routes: AxisRoute[], scale?: number): SpatialData;
64
22
 
65
- /** Per-device transform overrides. Any field left undefined inherits from global defaults. */
23
+ /** Per-device configuration */
66
24
  interface DeviceConfig {
67
- sensitivity?: Partial<SensitivityConfig>;
68
- flip?: Partial<FlipConfig>;
25
+ /** Axis routing — each entry maps a device input to an output with optional flip */
26
+ routes?: AxisRoute[];
27
+ /** Scale multiplier applied to all axes (default: 1) */
28
+ scale?: number;
29
+ /** Dead zone threshold (0-1). Values below this are zeroed. */
69
30
  deadZone?: number;
31
+ /** Only pass the strongest axis, zero all others */
70
32
  dominant?: boolean;
71
- axisRemap?: Partial<AxisMap>;
72
- actionMap?: ActionMap;
73
- lockPosition?: boolean;
74
- lockRotation?: boolean;
75
33
  }
34
+ /** Global configuration */
76
35
  interface InputConfig {
77
- /** Global defaults applied to all devices */
78
- sensitivity: SensitivityConfig;
79
- flip: FlipConfig;
36
+ /** Default axis routes (used when device has no override) */
37
+ routes: AxisRoute[];
38
+ /** Default scale */
39
+ scale: number;
40
+ /** Dead zone threshold */
80
41
  deadZone: number;
42
+ /** Dominant axis mode */
81
43
  dominant: boolean;
82
- axisRemap: AxisMap;
44
+ /** Lock translation to zero */
83
45
  lockPosition: boolean;
46
+ /** Lock rotation to zero */
84
47
  lockRotation: boolean;
85
- /** Action map maps input axes to named output actions. Default: passthrough. */
86
- actionMap: ActionMap;
87
- /**
88
- * Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
89
- * or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
90
- * Values override global defaults for matching devices.
91
- */
48
+ /** Per-device overrides keyed by device ID or pattern (e.g., "cnx-*") */
92
49
  devices: Record<string, DeviceConfig>;
93
50
  }
94
51
  declare const DEFAULT_CONFIG: InputConfig;
95
52
  declare function mergeConfig(base: InputConfig, partial: Partial<InputConfig>): InputConfig;
96
- /** Resolve the effective config for a specific device by merging global + device overrides */
53
+ /** Resolve the effective config for a specific device */
97
54
  declare function resolveDeviceConfig(config: InputConfig, deviceId: string): InputConfig;
98
55
 
99
56
  interface StorageAdapter {
@@ -104,36 +61,17 @@ declare function saveSettings(config: InputConfig, storage?: StorageAdapter): vo
104
61
  declare function loadSettings(storage?: StorageAdapter): Partial<InputConfig> | null;
105
62
 
106
63
  interface InputManagerEvents {
107
- /** Processed spatial data (after all transforms + action map) */
108
64
  spatialData: (data: SpatialData) => void;
109
- /** Named action values from the action map */
110
- actionValues: (values: ActionValues) => void;
111
- /** Raw spatial data (before transforms) */
112
65
  rawSpatialData: (data: SpatialData) => void;
113
- /** Button event (pass-through from connection) */
114
66
  buttonEvent: (data: ButtonEvent) => void;
115
- /** Connection state changed */
116
67
  stateChange: (state: ConnectionState, protocol: TransportProtocol) => void;
117
- /** Device connected/disconnected */
118
68
  deviceStatus: (event: "connected" | "disconnected", device: DeviceInfo) => void;
119
- /** Configuration changed */
120
69
  configChange: (config: InputConfig) => void;
121
70
  }
122
- /** A connected device paired with its resolved configuration */
123
71
  interface DeviceWithConfig {
124
72
  device: DeviceInfo;
125
73
  config: DeviceConfig;
126
74
  }
127
- /**
128
- * Unified device service that wraps one or more SatMouseConnections
129
- * and provides a single processed event stream.
130
- *
131
- * Applies a configurable transform pipeline per-device:
132
- * deadZone → dominant → flip → axisRemap → sensitivity → lock
133
- *
134
- * Per-device overrides are resolved from InputConfig.devices using
135
- * device ID matching (exact or pattern with wildcard "*").
136
- */
137
75
  declare class InputManager extends TypedEmitter<InputManagerEvents> {
138
76
  private connections;
139
77
  private storage?;
@@ -144,36 +82,25 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
144
82
  private _config;
145
83
  get config(): InputConfig;
146
84
  constructor(config?: Partial<InputConfig>, storage?: StorageAdapter);
147
- /** Add a connection to the managed set */
148
85
  addConnection(connection: SatMouseConnection): void;
149
- /** Remove a connection */
150
86
  removeConnection(connection: SatMouseConnection): void;
151
- /** Connect all managed connections */
152
87
  connect(): Promise<void>;
153
- /** Disconnect all managed connections */
154
88
  disconnect(): void;
155
- /** Fetch device info from all connections */
156
89
  fetchDeviceInfo(): Promise<DeviceInfo[]>;
157
- /** Get all known connected devices paired with their resolved config */
158
90
  getDevicesWithConfig(): DeviceWithConfig[];
159
- /** Get the resolved per-device config (global defaults + device overrides) */
160
91
  getDeviceConfig(deviceId: string): DeviceConfig;
161
- /** Update global configuration. Persists by default. */
162
92
  updateConfig(partial: Partial<InputConfig>, persist?: boolean): void;
163
- /** Update configuration for a specific device. Persists by default. */
164
93
  updateDeviceConfig(deviceId: string, partial: DeviceConfig, persist?: boolean): void;
165
- /** Register a callback for processed spatial data. Returns unsubscribe function. */
94
+ resetDeviceConfig(deviceId: string, persist?: boolean): void;
95
+ resetAllConfig(): void;
166
96
  onSpatialData(callback: (data: SpatialData) => void): () => void;
167
- /** Register a callback for button events. Returns unsubscribe function. */
168
97
  onButtonEvent(callback: (data: ButtonEvent) => void): () => void;
169
- /** Register a callback for action values. Returns unsubscribe function. */
170
- onActionValues(callback: (values: ActionValues) => void): () => void;
171
98
  private wireConnection;
172
99
  private flushAccumulator;
173
- /** Per-device transforms: flip, sensitivity, dead zone, dominant, axis remap */
100
+ /** Per-device: deadZone dominant routes (flip + scale + remap in one pass) */
174
101
  private processPerDevice;
175
- /** Global transforms applied after per-device merge: locks + action map */
176
- private applyGlobalTransforms;
102
+ /** Get the effective routes for a device: device config override > device axes metadata > global default */
103
+ private resolveRoutes;
177
104
  }
178
105
 
179
- export { type ActionBinding, type ActionMap, type ActionValues, type AxisMap, DEFAULT_ACTION_MAP, DEFAULT_AXIS_MAP, DEFAULT_CONFIG, type DeviceConfig, type DeviceWithConfig, type FlipConfig, type InputAxis, type InputConfig, InputManager, type InputManagerEvents, type SensitivityConfig, type StorageAdapter, actionValuesToSpatialData, applyActionMap, applyAxisRemap, applyDeadZone, applyDominant, applyFlip, applySensitivity, loadSettings, mergeConfig, resolveDeviceConfig, saveSettings, swapActions };
106
+ export { type AxisRoute, DEFAULT_CONFIG, DEFAULT_ROUTES, type DeviceConfig, type DeviceWithConfig, FULL_AXES, type InputAxis, type InputConfig, InputManager, type InputManagerEvents, type StorageAdapter, applyRoutes, buildRoutes, loadSettings, mergeConfig, resolveDeviceConfig, saveSettings };