@kelnishi/satmouse-client 0.10.9 → 0.12.3

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