@kelnishi/satmouse-client 0.9.1 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react/index.cjs +84 -6
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +33 -3
- package/dist/react/index.d.ts +33 -3
- package/dist/react/index.js +84 -6
- package/dist/react/index.js.map +1 -1
- package/dist/utils/index.cjs +85 -6
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +37 -5
- package/dist/utils/index.d.ts +37 -5
- package/dist/utils/index.js +85 -7
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -119,7 +119,18 @@ type AxisMap = {
|
|
|
119
119
|
rz: keyof Vec3;
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
+
/** Per-device transform overrides. Any field left undefined inherits from global defaults. */
|
|
123
|
+
interface DeviceConfig {
|
|
124
|
+
sensitivity?: Partial<SensitivityConfig>;
|
|
125
|
+
flip?: Partial<FlipConfig>;
|
|
126
|
+
deadZone?: number;
|
|
127
|
+
dominant?: boolean;
|
|
128
|
+
axisRemap?: Partial<AxisMap>;
|
|
129
|
+
lockPosition?: boolean;
|
|
130
|
+
lockRotation?: boolean;
|
|
131
|
+
}
|
|
122
132
|
interface InputConfig {
|
|
133
|
+
/** Global defaults applied to all devices */
|
|
123
134
|
sensitivity: SensitivityConfig;
|
|
124
135
|
flip: FlipConfig;
|
|
125
136
|
deadZone: number;
|
|
@@ -127,6 +138,12 @@ interface InputConfig {
|
|
|
127
138
|
axisRemap: AxisMap;
|
|
128
139
|
lockPosition: boolean;
|
|
129
140
|
lockRotation: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
|
|
143
|
+
* or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
|
|
144
|
+
* Values override global defaults for matching devices.
|
|
145
|
+
*/
|
|
146
|
+
devices: Record<string, DeviceConfig>;
|
|
130
147
|
}
|
|
131
148
|
|
|
132
149
|
interface StorageAdapter {
|
|
@@ -148,18 +165,25 @@ interface InputManagerEvents {
|
|
|
148
165
|
/** Configuration changed */
|
|
149
166
|
configChange: (config: InputConfig) => void;
|
|
150
167
|
}
|
|
168
|
+
/** A connected device paired with its resolved configuration */
|
|
169
|
+
interface DeviceWithConfig {
|
|
170
|
+
device: DeviceInfo$1;
|
|
171
|
+
config: DeviceConfig;
|
|
172
|
+
}
|
|
151
173
|
/**
|
|
152
174
|
* Unified device service that wraps one or more SatMouseConnections
|
|
153
175
|
* and provides a single processed event stream.
|
|
154
176
|
*
|
|
155
|
-
* Applies a configurable transform pipeline
|
|
177
|
+
* Applies a configurable transform pipeline per-device:
|
|
156
178
|
* deadZone → dominant → flip → axisRemap → sensitivity → lock
|
|
157
179
|
*
|
|
158
|
-
*
|
|
180
|
+
* Per-device overrides are resolved from InputConfig.devices using
|
|
181
|
+
* device ID matching (exact or pattern with wildcard "*").
|
|
159
182
|
*/
|
|
160
183
|
declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
161
184
|
private connections;
|
|
162
185
|
private storage?;
|
|
186
|
+
private knownDevices;
|
|
163
187
|
private _config;
|
|
164
188
|
get config(): InputConfig;
|
|
165
189
|
constructor(config?: Partial<InputConfig>, storage?: StorageAdapter);
|
|
@@ -173,8 +197,14 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
|
173
197
|
disconnect(): void;
|
|
174
198
|
/** Fetch device info from all connections */
|
|
175
199
|
fetchDeviceInfo(): Promise<DeviceInfo$1[]>;
|
|
176
|
-
/**
|
|
200
|
+
/** Get all known connected devices paired with their resolved config */
|
|
201
|
+
getDevicesWithConfig(): DeviceWithConfig[];
|
|
202
|
+
/** Get the resolved per-device config (global defaults + device overrides) */
|
|
203
|
+
getDeviceConfig(deviceId: string): DeviceConfig;
|
|
204
|
+
/** Update global configuration. Persists by default. */
|
|
177
205
|
updateConfig(partial: Partial<InputConfig>, persist?: boolean): void;
|
|
206
|
+
/** Update configuration for a specific device. Persists by default. */
|
|
207
|
+
updateDeviceConfig(deviceId: string, partial: DeviceConfig, persist?: boolean): void;
|
|
178
208
|
/** Register a callback for processed spatial data. Returns unsubscribe function. */
|
|
179
209
|
onSpatialData(callback: (data: SpatialData) => void): () => void;
|
|
180
210
|
/** Register a callback for button events. Returns unsubscribe function. */
|
package/dist/react/index.d.ts
CHANGED
|
@@ -119,7 +119,18 @@ type AxisMap = {
|
|
|
119
119
|
rz: keyof Vec3;
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
+
/** Per-device transform overrides. Any field left undefined inherits from global defaults. */
|
|
123
|
+
interface DeviceConfig {
|
|
124
|
+
sensitivity?: Partial<SensitivityConfig>;
|
|
125
|
+
flip?: Partial<FlipConfig>;
|
|
126
|
+
deadZone?: number;
|
|
127
|
+
dominant?: boolean;
|
|
128
|
+
axisRemap?: Partial<AxisMap>;
|
|
129
|
+
lockPosition?: boolean;
|
|
130
|
+
lockRotation?: boolean;
|
|
131
|
+
}
|
|
122
132
|
interface InputConfig {
|
|
133
|
+
/** Global defaults applied to all devices */
|
|
123
134
|
sensitivity: SensitivityConfig;
|
|
124
135
|
flip: FlipConfig;
|
|
125
136
|
deadZone: number;
|
|
@@ -127,6 +138,12 @@ interface InputConfig {
|
|
|
127
138
|
axisRemap: AxisMap;
|
|
128
139
|
lockPosition: boolean;
|
|
129
140
|
lockRotation: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
|
|
143
|
+
* or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
|
|
144
|
+
* Values override global defaults for matching devices.
|
|
145
|
+
*/
|
|
146
|
+
devices: Record<string, DeviceConfig>;
|
|
130
147
|
}
|
|
131
148
|
|
|
132
149
|
interface StorageAdapter {
|
|
@@ -148,18 +165,25 @@ interface InputManagerEvents {
|
|
|
148
165
|
/** Configuration changed */
|
|
149
166
|
configChange: (config: InputConfig) => void;
|
|
150
167
|
}
|
|
168
|
+
/** A connected device paired with its resolved configuration */
|
|
169
|
+
interface DeviceWithConfig {
|
|
170
|
+
device: DeviceInfo$1;
|
|
171
|
+
config: DeviceConfig;
|
|
172
|
+
}
|
|
151
173
|
/**
|
|
152
174
|
* Unified device service that wraps one or more SatMouseConnections
|
|
153
175
|
* and provides a single processed event stream.
|
|
154
176
|
*
|
|
155
|
-
* Applies a configurable transform pipeline
|
|
177
|
+
* Applies a configurable transform pipeline per-device:
|
|
156
178
|
* deadZone → dominant → flip → axisRemap → sensitivity → lock
|
|
157
179
|
*
|
|
158
|
-
*
|
|
180
|
+
* Per-device overrides are resolved from InputConfig.devices using
|
|
181
|
+
* device ID matching (exact or pattern with wildcard "*").
|
|
159
182
|
*/
|
|
160
183
|
declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
161
184
|
private connections;
|
|
162
185
|
private storage?;
|
|
186
|
+
private knownDevices;
|
|
163
187
|
private _config;
|
|
164
188
|
get config(): InputConfig;
|
|
165
189
|
constructor(config?: Partial<InputConfig>, storage?: StorageAdapter);
|
|
@@ -173,8 +197,14 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
|
173
197
|
disconnect(): void;
|
|
174
198
|
/** Fetch device info from all connections */
|
|
175
199
|
fetchDeviceInfo(): Promise<DeviceInfo$1[]>;
|
|
176
|
-
/**
|
|
200
|
+
/** Get all known connected devices paired with their resolved config */
|
|
201
|
+
getDevicesWithConfig(): DeviceWithConfig[];
|
|
202
|
+
/** Get the resolved per-device config (global defaults + device overrides) */
|
|
203
|
+
getDeviceConfig(deviceId: string): DeviceConfig;
|
|
204
|
+
/** Update global configuration. Persists by default. */
|
|
177
205
|
updateConfig(partial: Partial<InputConfig>, persist?: boolean): void;
|
|
206
|
+
/** Update configuration for a specific device. Persists by default. */
|
|
207
|
+
updateDeviceConfig(deviceId: string, partial: DeviceConfig, persist?: boolean): void;
|
|
178
208
|
/** Register a callback for processed spatial data. Returns unsubscribe function. */
|
|
179
209
|
onSpatialData(callback: (data: SpatialData) => void): () => void;
|
|
180
210
|
/** Register a callback for button events. Returns unsubscribe function. */
|
package/dist/react/index.js
CHANGED
|
@@ -433,15 +433,57 @@ var DEFAULT_CONFIG = {
|
|
|
433
433
|
dominant: false,
|
|
434
434
|
axisRemap: { tx: "x", ty: "y", tz: "z", rx: "x", ry: "y", rz: "z" },
|
|
435
435
|
lockPosition: false,
|
|
436
|
-
lockRotation: false
|
|
436
|
+
lockRotation: false,
|
|
437
|
+
devices: {}
|
|
437
438
|
};
|
|
438
439
|
function mergeConfig(base, partial) {
|
|
439
|
-
|
|
440
|
+
const merged = {
|
|
440
441
|
...base,
|
|
441
442
|
...partial,
|
|
442
443
|
sensitivity: { ...base.sensitivity, ...partial.sensitivity },
|
|
443
444
|
flip: { ...base.flip, ...partial.flip },
|
|
444
|
-
axisRemap: { ...base.axisRemap, ...partial.axisRemap }
|
|
445
|
+
axisRemap: { ...base.axisRemap, ...partial.axisRemap },
|
|
446
|
+
devices: { ...base.devices }
|
|
447
|
+
};
|
|
448
|
+
if (partial.devices) {
|
|
449
|
+
for (const [key, devCfg] of Object.entries(partial.devices)) {
|
|
450
|
+
merged.devices[key] = mergeDeviceConfig(merged.devices[key], devCfg);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return merged;
|
|
454
|
+
}
|
|
455
|
+
function mergeDeviceConfig(base, partial) {
|
|
456
|
+
if (!base) return partial;
|
|
457
|
+
return {
|
|
458
|
+
...base,
|
|
459
|
+
...partial,
|
|
460
|
+
sensitivity: partial.sensitivity ? { ...base.sensitivity, ...partial.sensitivity } : base.sensitivity,
|
|
461
|
+
flip: partial.flip ? { ...base.flip, ...partial.flip } : base.flip,
|
|
462
|
+
axisRemap: partial.axisRemap ? { ...base.axisRemap, ...partial.axisRemap } : base.axisRemap
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
function resolveDeviceConfig(config, deviceId) {
|
|
466
|
+
let deviceOverride;
|
|
467
|
+
if (config.devices[deviceId]) {
|
|
468
|
+
deviceOverride = config.devices[deviceId];
|
|
469
|
+
} else {
|
|
470
|
+
for (const [pattern, cfg] of Object.entries(config.devices)) {
|
|
471
|
+
if (pattern.endsWith("*") && deviceId.startsWith(pattern.slice(0, -1))) {
|
|
472
|
+
deviceOverride = cfg;
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
if (!deviceOverride) return config;
|
|
478
|
+
return {
|
|
479
|
+
...config,
|
|
480
|
+
sensitivity: { ...config.sensitivity, ...deviceOverride.sensitivity },
|
|
481
|
+
flip: { ...config.flip, ...deviceOverride.flip },
|
|
482
|
+
deadZone: deviceOverride.deadZone ?? config.deadZone,
|
|
483
|
+
dominant: deviceOverride.dominant ?? config.dominant,
|
|
484
|
+
axisRemap: { ...config.axisRemap, ...deviceOverride.axisRemap },
|
|
485
|
+
lockPosition: deviceOverride.lockPosition ?? config.lockPosition,
|
|
486
|
+
lockRotation: deviceOverride.lockRotation ?? config.lockRotation
|
|
445
487
|
};
|
|
446
488
|
}
|
|
447
489
|
|
|
@@ -553,6 +595,7 @@ function applyAxisRemap(data, map) {
|
|
|
553
595
|
var InputManager = class extends TypedEmitter {
|
|
554
596
|
connections = [];
|
|
555
597
|
storage;
|
|
598
|
+
knownDevices = /* @__PURE__ */ new Map();
|
|
556
599
|
_config;
|
|
557
600
|
get config() {
|
|
558
601
|
return this._config;
|
|
@@ -585,14 +628,45 @@ var InputManager = class extends TypedEmitter {
|
|
|
585
628
|
/** Fetch device info from all connections */
|
|
586
629
|
async fetchDeviceInfo() {
|
|
587
630
|
const results = await Promise.all(this.connections.map((c) => c.fetchDeviceInfo()));
|
|
588
|
-
|
|
631
|
+
const devices = results.flat();
|
|
632
|
+
for (const d of devices) this.knownDevices.set(d.id, d);
|
|
633
|
+
return devices;
|
|
634
|
+
}
|
|
635
|
+
/** Get all known connected devices paired with their resolved config */
|
|
636
|
+
getDevicesWithConfig() {
|
|
637
|
+
return Array.from(this.knownDevices.values()).map((device) => ({
|
|
638
|
+
device,
|
|
639
|
+
config: this.getDeviceConfig(device.id)
|
|
640
|
+
}));
|
|
641
|
+
}
|
|
642
|
+
/** Get the resolved per-device config (global defaults + device overrides) */
|
|
643
|
+
getDeviceConfig(deviceId) {
|
|
644
|
+
const resolved = resolveDeviceConfig(this._config, deviceId);
|
|
645
|
+
return {
|
|
646
|
+
sensitivity: resolved.sensitivity,
|
|
647
|
+
flip: resolved.flip,
|
|
648
|
+
deadZone: resolved.deadZone,
|
|
649
|
+
dominant: resolved.dominant,
|
|
650
|
+
axisRemap: resolved.axisRemap,
|
|
651
|
+
lockPosition: resolved.lockPosition,
|
|
652
|
+
lockRotation: resolved.lockRotation
|
|
653
|
+
};
|
|
589
654
|
}
|
|
590
|
-
/** Update configuration. Persists by default. */
|
|
655
|
+
/** Update global configuration. Persists by default. */
|
|
591
656
|
updateConfig(partial, persist = true) {
|
|
592
657
|
this._config = mergeConfig(this._config, partial);
|
|
593
658
|
if (persist) saveSettings(this._config, this.storage);
|
|
594
659
|
this.emit("configChange", this._config);
|
|
595
660
|
}
|
|
661
|
+
/** Update configuration for a specific device. Persists by default. */
|
|
662
|
+
updateDeviceConfig(deviceId, partial, persist = true) {
|
|
663
|
+
const existing = this._config.devices[deviceId] ?? {};
|
|
664
|
+
this._config = mergeConfig(this._config, {
|
|
665
|
+
devices: { [deviceId]: { ...existing, ...partial } }
|
|
666
|
+
});
|
|
667
|
+
if (persist) saveSettings(this._config, this.storage);
|
|
668
|
+
this.emit("configChange", this._config);
|
|
669
|
+
}
|
|
596
670
|
/** Register a callback for processed spatial data. Returns unsubscribe function. */
|
|
597
671
|
onSpatialData(callback) {
|
|
598
672
|
this.on("spatialData", callback);
|
|
@@ -611,7 +685,11 @@ var InputManager = class extends TypedEmitter {
|
|
|
611
685
|
});
|
|
612
686
|
connection.on("buttonEvent", (event) => this.emit("buttonEvent", event));
|
|
613
687
|
connection.on("stateChange", (state, proto) => this.emit("stateChange", state, proto));
|
|
614
|
-
connection.on("deviceStatus", (event, device) =>
|
|
688
|
+
connection.on("deviceStatus", (event, device) => {
|
|
689
|
+
if (event === "connected") this.knownDevices.set(device.id, device);
|
|
690
|
+
else this.knownDevices.delete(device.id);
|
|
691
|
+
this.emit("deviceStatus", event, device);
|
|
692
|
+
});
|
|
615
693
|
}
|
|
616
694
|
processSpatialData(raw) {
|
|
617
695
|
const cfg = this._config;
|