@kelnishi/satmouse-client 0.10.9 → 0.12.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.
@@ -472,35 +472,45 @@ function readAxis(data, axis) {
472
472
  return data.rotation.y;
473
473
  case "rz":
474
474
  return data.rotation.z;
475
+ case "w":
476
+ return data.w ?? 0;
475
477
  default:
476
478
  return 0;
477
479
  }
478
480
  }
479
- function writeAxis(t, r, axis, value) {
481
+ function writeAxis(acc, axis, value) {
480
482
  const isNeg = axis.endsWith("-");
481
483
  const base = axis.replace(/[+-]$/, "");
482
484
  const sign = isNeg ? -1 : 1;
485
+ if (base === "w") {
486
+ acc.w += value * sign;
487
+ return;
488
+ }
483
489
  const group = base[0];
484
490
  const key = base[1];
485
- if (group === "t") t[key] += value * sign;
486
- else r[key] += value * sign;
491
+ if (group === "t") acc.t[key] += value * sign;
492
+ else acc.r[key] += value * sign;
487
493
  }
488
- function applyRoutes(data, routes, scale = 1) {
489
- const t = { x: 0, y: 0, z: 0 };
490
- const r = { x: 0, y: 0, z: 0 };
494
+ function applyRoutes(data, routes, translateScale = 1, rotateScale = 1, wScale = 1) {
495
+ const acc = { t: { x: 0, y: 0, z: 0 }, r: { x: 0, y: 0, z: 0 }, w: 0 };
491
496
  for (const route of routes) {
492
497
  let value = readAxis(data, route.source);
493
498
  if (route.flip) value = -value;
499
+ const targetBase = route.target.replace(/[+-]$/, "");
500
+ const scale = targetBase === "w" ? wScale : targetBase[0] === "t" ? translateScale : rotateScale;
494
501
  value *= scale;
495
- writeAxis(t, r, route.target, value);
502
+ writeAxis(acc, route.target, value);
496
503
  }
497
- return { translation: t, rotation: r, timestamp: data.timestamp, deviceId: data.deviceId };
504
+ return { translation: acc.t, rotation: acc.r, w: acc.w || void 0, timestamp: data.timestamp, deviceId: data.deviceId };
498
505
  }
499
506
 
500
507
  // src/utils/config.ts
501
508
  var DEFAULT_CONFIG = {
502
509
  routes: DEFAULT_ROUTES,
503
- scale: 1e-3,
510
+ buttonRoutes: [],
511
+ translateScale: 1e-3,
512
+ rotateScale: 1e-3,
513
+ wScale: 1e-3,
504
514
  deadZone: 0,
505
515
  dominant: false,
506
516
  lockPosition: false,
@@ -534,6 +544,7 @@ function mergeConfig(base, partial) {
534
544
  ...base,
535
545
  ...partial,
536
546
  routes: partial.routes ?? [...base.routes],
547
+ buttonRoutes: partial.buttonRoutes ?? [...base.buttonRoutes],
537
548
  devices: { ...base.devices }
538
549
  };
539
550
  if (partial.devices) {
@@ -559,7 +570,10 @@ function resolveDeviceConfig(config, deviceId) {
559
570
  return {
560
571
  ...config,
561
572
  routes: deviceOverride.routes ?? config.routes,
562
- scale: deviceOverride.scale ?? config.scale,
573
+ buttonRoutes: deviceOverride.buttonRoutes ?? config.buttonRoutes,
574
+ translateScale: deviceOverride.translateScale ?? config.translateScale,
575
+ rotateScale: deviceOverride.rotateScale ?? config.rotateScale,
576
+ wScale: deviceOverride.wScale ?? config.wScale,
563
577
  deadZone: deviceOverride.deadZone ?? config.deadZone,
564
578
  dominant: deviceOverride.dominant ?? config.dominant
565
579
  };
@@ -663,7 +677,10 @@ var InputManager = class extends TypedEmitter {
663
677
  const resolved = resolveDeviceConfig(this._config, deviceId);
664
678
  return {
665
679
  routes: resolved.routes,
666
- scale: resolved.scale,
680
+ buttonRoutes: resolved.buttonRoutes,
681
+ translateScale: resolved.translateScale,
682
+ rotateScale: resolved.rotateScale,
683
+ wScale: resolved.wScale,
667
684
  deadZone: resolved.deadZone,
668
685
  dominant: resolved.dominant
669
686
  };
@@ -711,11 +728,15 @@ var InputManager = class extends TypedEmitter {
711
728
  tz: processed.translation.z,
712
729
  rx: processed.rotation.x,
713
730
  ry: processed.rotation.y,
714
- rz: processed.rotation.z
731
+ rz: processed.rotation.z,
732
+ w: processed.w ?? 0
715
733
  });
716
734
  this.accDirty = true;
717
735
  });
718
- connection.on("buttonEvent", (event) => this.emit("buttonEvent", event));
736
+ connection.on("buttonEvent", (event) => {
737
+ this.dispatchButtonKeys(event);
738
+ this.emit("buttonEvent", event);
739
+ });
719
740
  connection.on("stateChange", (state, proto) => {
720
741
  this._state = state;
721
742
  this._protocol = proto;
@@ -729,7 +750,7 @@ var InputManager = class extends TypedEmitter {
729
750
  }
730
751
  flushAccumulator() {
731
752
  if (!this.accDirty) return;
732
- const merged = { tx: 0, ty: 0, tz: 0, rx: 0, ry: 0, rz: 0 };
753
+ const merged = { tx: 0, ty: 0, tz: 0, rx: 0, ry: 0, rz: 0, w: 0 };
733
754
  for (const acc of this.deviceAccumulators.values()) {
734
755
  merged.tx += acc.tx;
735
756
  merged.ty += acc.ty;
@@ -737,12 +758,14 @@ var InputManager = class extends TypedEmitter {
737
758
  merged.rx += acc.rx;
738
759
  merged.ry += acc.ry;
739
760
  merged.rz += acc.rz;
761
+ merged.w += acc.w;
740
762
  }
741
763
  this.deviceAccumulators.clear();
742
764
  this.accDirty = false;
743
765
  let data = {
744
766
  translation: { x: merged.tx, y: merged.ty, z: merged.tz },
745
767
  rotation: { x: merged.rx, y: merged.ry, z: merged.rz },
768
+ w: merged.w || void 0,
746
769
  timestamp: performance.now() * 1e3
747
770
  };
748
771
  if (this._config.lockPosition) {
@@ -783,7 +806,7 @@ var InputManager = class extends TypedEmitter {
783
806
  }
784
807
  const device = this.knownDevices.get(deviceId);
785
808
  const deviceRoutes = this.resolveRoutes(deviceId, device);
786
- data = applyRoutes(data, deviceRoutes, cfg.scale);
809
+ data = applyRoutes(data, deviceRoutes, cfg.translateScale, cfg.rotateScale, cfg.wScale);
787
810
  return data;
788
811
  }
789
812
  /** Get the effective routes for a device: device config override > device axes metadata > global default */
@@ -798,6 +821,27 @@ var InputManager = class extends TypedEmitter {
798
821
  if (device?.axes) return buildRoutes(device.axes);
799
822
  return DEFAULT_ROUTES;
800
823
  }
824
+ /** Dispatch KeyboardEvents for button routes matching this button event */
825
+ dispatchButtonKeys(event) {
826
+ if (typeof document === "undefined") return;
827
+ const allRoutes = this.collectButtonRoutes();
828
+ for (const route of allRoutes) {
829
+ if (route.button === event.button) {
830
+ document.dispatchEvent(new KeyboardEvent(
831
+ event.pressed ? "keydown" : "keyup",
832
+ { key: route.key, code: route.code ?? "", bubbles: true }
833
+ ));
834
+ }
835
+ }
836
+ }
837
+ /** Gather all button routes from global config + all device configs */
838
+ collectButtonRoutes() {
839
+ const routes = [...this._config.buttonRoutes];
840
+ for (const devCfg of Object.values(this._config.devices)) {
841
+ if (devCfg.buttonRoutes) routes.push(...devCfg.buttonRoutes);
842
+ }
843
+ return routes;
844
+ }
801
845
  };
802
846
  var SatMouseContext = createContext(null);
803
847
  function SatMouseProvider({