@kelnishi/satmouse-client 0.9.9 → 0.9.13
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/chunk-I47ZOX3M.js +64 -0
- package/dist/chunk-I47ZOX3M.js.map +1 -0
- package/dist/chunk-LDSDVYCV.cjs +69 -0
- package/dist/chunk-LDSDVYCV.cjs.map +1 -0
- package/dist/{connection-CH2YsPn1.d.cts → connection-5KQFvHoJ.d.cts} +8 -1
- package/dist/{connection-CH2YsPn1.d.ts → connection-5KQFvHoJ.d.ts} +8 -1
- package/dist/core/index.cjs +16 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +16 -0
- package/dist/core/index.js.map +1 -1
- package/dist/elements/index.cjs +301 -0
- package/dist/elements/index.cjs.map +1 -0
- package/dist/elements/index.d.cts +35 -0
- package/dist/elements/index.d.ts +35 -0
- package/dist/elements/index.js +295 -0
- package/dist/elements/index.js.map +1 -0
- package/dist/react/index.cjs +71 -7
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +16 -2
- package/dist/react/index.d.ts +16 -2
- package/dist/react/index.js +71 -7
- package/dist/react/index.js.map +1 -1
- package/dist/utils/index.cjs +75 -75
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +9 -2
- package/dist/utils/index.d.ts +9 -2
- package/dist/utils/index.js +58 -69
- package/dist/utils/index.js.map +1 -1
- package/package.json +9 -3
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/discovery.ts","../../src/core/decode.ts","../../src/core/transports/webtransport.ts","../../src/core/transports/websocket.ts","../../src/core/connection.ts","../../src/core/launch.ts"],"names":[],"mappings":";;;;AASA,eAAsB,sBAAsB,KAAA,EAA0C;AACpF,EAAA,MAAM,GAAA,GAAM,MAAM,UAAA,CAAW,KAAA,CAAM,KAAK,CAAA;AACxC,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AACrE,EAAA,OAAO,IAAI,IAAA,EAAK;AAClB;AAGO,SAAS,iBAAiB,EAAA,EAAyC;AACxE,EAAA,MAAM,SAA4B,EAAC;AAEnC,EAAA,MAAM,YAAA,GAAe,EAAA,CAAG,MAAA,EAAQ,WAAA,EAAa,SAAS,EAAC;AAEvD,EAAA,MAAM,SAAS,YAAA,CAAa,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgB,cAAc,CAAA;AACxE,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAA,CAAO,YAAA,GAAe;AAAA,MACpB,KAAK,MAAA,CAAO,IAAA;AAAA,MACZ,QAAA,EAAU,GAAG,mBAAmB;AAAA,KAClC;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,YAAA,CAAa,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgB,WAAW,CAAA;AACrE,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAA,CAAO,SAAA,GAAY,EAAE,GAAA,EAAK,MAAA,CAAO,IAAA,EAAK;AAAA,EACxC;AAEA,EAAA,MAAM,UAAA,GAAa,EAAA,CAAG,UAAA,EAAY,UAAA,EAAY,QAAQ,CAAC,CAAA;AACvD,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAA,CAAO,gBAAgB,UAAA,CAAW,IAAA;AAAA,EACpC;AAEA,EAAA,OAAO,MAAA;AACT;;;ACrCO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,MAAM,GAAA,GAAM,MAAA,YAAkB,WAAA,GAAc,MAAA,CAAO,aAAa,MAAA,CAAO,UAAA;AACvE,EAAA,IAAI,MAAM,EAAA,EAAI;AACZ,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,sDAAA,EAAoD,GAAG,CAAA,CAAE,CAAA;AAAA,EAChF;AACA,EAAA,MAAM,EAAA,GAAK,MAAA,YAAkB,WAAA,GAAc,MAAA,GAAS,MAAA,CAAO,MAAA;AAC3D,EAAA,MAAM,MAAA,GAAS,MAAA,YAAkB,UAAA,GAAa,MAAA,CAAO,UAAA,GAAa,CAAA;AAClE,EAAA,MAAM,IAAA,GAAO,IAAI,QAAA,CAAS,EAAA,EAAI,MAAM,CAAA;AACpC,EAAA,OAAO;AAAA,IACL,WAAA,EAAa;AAAA,MACX,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,IAAI,CAAA;AAAA,MACxB,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,IAAI,CAAA;AAAA,MACzB,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,IAAI;AAAA,KAC3B;AAAA,IACA,QAAA,EAAU;AAAA,MACR,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,IAAI,CAAA;AAAA,MACzB,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,IAAI,CAAA;AAAA,MACzB,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,IAAI;AAAA,KAC3B;AAAA,IACA,SAAA,EAAW,IAAA,CAAK,UAAA,CAAW,CAAA,EAAG,IAAI;AAAA,GACpC;AACF;AAGO,SAAS,oBACd,MAAA,EACgG;AAChG,EAAA,MAAM,QAAQ,MAAA,YAAkB,UAAA,GAAa,MAAA,GAAS,IAAI,WAAW,MAAM,CAAA;AAC3E,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAE7B,EAAA,MAAM,UAAA,GAAa,MAAM,CAAC,CAAA;AAC1B,EAAA,IAAI,UAAA,KAAe,CAAA,IAAQ,KAAA,CAAM,MAAA,IAAU,EAAA,EAAI;AAC7C,IAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,iBAAA,CAAkB,MAAM,QAAA,CAAS,CAAA,EAAG,EAAE,CAAC,CAAA,EAAE;AAAA,EAC/E;AACA,EAAA,IAAI,eAAe,CAAA,EAAM;AACvB,IAAA,MAAM,IAAA,GAAO,IAAI,WAAA,EAAY,CAAE,OAAO,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAA;AACvD,IAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,MAAM,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAiB;AAAA,EACtE;AACA,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,mBACd,MAAA,EACmE;AACnE,EAAA,MAAM,SAAwB,EAAC;AAC/B,EAAA,IAAI,GAAA,GAAM,CAAA;AAEV,EAAA,OAAO,GAAA,GAAM,CAAA,IAAK,MAAA,CAAO,MAAA,EAAQ;AAC/B,IAAA,MAAM,OAAO,IAAI,QAAA,CAAS,OAAO,MAAA,EAAQ,MAAA,CAAO,aAAa,GAAG,CAAA;AAChE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,IAAI,CAAA;AAElC,IAAA,IAAI,MAAM,KAAA,IAAS,GAAA,GAAM,CAAA,GAAI,GAAA,GAAM,OAAO,MAAA,EAAQ;AAClD,IAAA,MAAM,IAAA,GAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,MAAA,CAAO,QAAA,CAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,CAAA,GAAI,GAAG,CAAC,CAAA;AAC7E,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,MAAA,IAAI,OAAO,KAAA,CAAM,MAAA,KAAW,YAAY,OAAO,KAAA,CAAM,YAAY,SAAA,EAAW;AAC1E,QAAA,MAAA,CAAO,KAAK,KAAoB,CAAA;AAAA,MAClC;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,GAAA,IAAO,CAAA,GAAI,GAAA;AAAA,EACb;AAEA,EAAA,OAAO,EAAE,MAAA,EAAQ,SAAA,EAAW,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAE;AACnD;;;ACjEO,IAAM,sBAAN,MAA+C;AAAA,EAC3C,QAAA,GAAW,cAAA;AAAA,EAEpB,aAAA,GAAsD,IAAA;AAAA,EACtD,aAAA,GAAsD,IAAA;AAAA,EACtD,OAAA,GAA+B,IAAA;AAAA,EAC/B,OAAA,GAA2C,IAAA;AAAA,EAEnC,SAAA,GAAiB,IAAA;AAAA,EACjB,GAAA;AAAA,EACA,QAAA;AAAA,EAER,WAAA,CAAY,KAAa,QAAA,EAAmB;AAC1C,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AAAA,EAEA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAI,OAAO,UAAA,CAAW,YAAA,KAAiB,WAAA,EAAa;AAClD,MAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,IACrE;AAEA,IAAA,MAAM,UAAe,EAAC;AACtB,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAA,CAAQ,uBAAA,GAA0B;AAAA,QAChC;AAAA,UACE,SAAA,EAAW,SAAA;AAAA,UACX,KAAA,EAAO,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,CAAE,UAAA,CAAW,CAAC,CAAC;AAAA;AACpE,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,YAAY,IAAK,UAAA,CAAmB,YAAA,CAAa,IAAA,CAAK,KAAK,OAAO,CAAA;AACvE,IAAA,MAAM,KAAK,SAAA,CAAU,KAAA;AAErB,IAAA,IAAA,CAAK,aAAA,EAAc;AACnB,IAAA,IAAA,CAAK,WAAA,EAAY;AAEjB,IAAA,IAAA,CAAK,SAAA,CAAU,MAAA,CACZ,IAAA,CAAK,MAAM,IAAA,CAAK,OAAA,IAAW,CAAA,CAC3B,KAAA,CAAM,MAAM,IAAA,CAAK,OAAA,IAAW,CAAA;AAAA,EACjC;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,IACxB,CAAA,CAAA,MAAQ;AAAA,IAAC;AACT,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA,EAEA,MAAc,aAAA,GAA+B;AAC3C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,SAAS,SAAA,EAAU;AAC3D,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,QAAA,IAAI,IAAA,EAAM;AACV,QAAA,IAAA,CAAK,aAAA,GAAgB,iBAAA,CAAkB,KAAK,CAAC,CAAA;AAAA,MAC/C;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAc,WAAA,GAA6B;AACzC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,6BAAA,CAA8B,SAAA,EAAU;AACtE,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,MAAK,GAAI,MAAM,OAAO,IAAA,EAAK;AAClD,QAAA,IAAI,IAAA,EAAM;AACV,QAAA,IAAA,CAAK,iBAAiB,MAAM,CAAA;AAAA,MAC9B;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAc,iBAAiB,MAAA,EAA4B;AACzD,IAAA,MAAM,MAAA,GAAS,OAAO,SAAA,EAAU;AAChC,IAAA,IAAI,MAAA,GAAsC,IAAI,UAAA,CAAW,CAAC,CAAA;AAE1D,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,EAAM;AACX,QAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,QAAA,IAAI,IAAA,EAAM;AAEV,QAAA,MAAM,SAAS,IAAI,UAAA,CAAW,MAAA,CAAO,MAAA,GAAS,MAAM,MAAM,CAAA;AAC1D,QAAA,MAAA,CAAO,IAAI,MAAM,CAAA;AACjB,QAAA,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,MAAA,CAAO,MAAM,CAAA;AAE/B,QAAA,MAAM,EAAE,MAAA,EAAQ,SAAA,EAAU,GAAI,mBAAmB,MAAM,CAAA;AACvD,QAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,UAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAAA,QAC5B;AACA,QAAA,MAAA,GAAS,SAAA;AAAA,MACX;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF,CAAA;;;ACnGO,IAAM,mBAAN,MAA4C;AAAA,EACxC,QAAA,GAAW,WAAA;AAAA,EAEpB,aAAA,GAAsD,IAAA;AAAA,EACtD,aAAA,GAAsD,IAAA;AAAA,EACtD,cAAA,GAA6F,IAAA;AAAA,EAC7F,OAAA,GAA+B,IAAA;AAAA,EAC/B,OAAA,GAA2C,IAAA;AAAA,EAEnC,EAAA,GAAuB,IAAA;AAAA,EACvB,GAAA;AAAA,EACA,WAAA;AAAA,EAER,WAAA,CAAY,GAAA,EAAa,WAAA,GAAsB,eAAA,EAAiB;AAC9D,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,WAAA,GAAc,WAAA;AAAA,EACrB;AAAA,EAEA,MAAM,OAAA,GAAyB;AAC7B,IAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC5C,MAAA,IAAA,CAAK,KAAK,IAAI,UAAA,CAAW,UAAU,IAAA,CAAK,GAAA,EAAK,KAAK,WAAW,CAAA;AAC7D,MAAA,IAAI,IAAA,CAAK,gBAAgB,iBAAA,EAAmB;AAC1C,QAAA,IAAA,CAAK,GAAG,UAAA,GAAa,aAAA;AAAA,MACvB;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,MAAA,GAAS,MAAM,OAAA,EAAQ;AAE/B,MAAA,IAAA,CAAK,EAAA,CAAG,UAAU,MAAM;AACtB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,IAAA,CAAK,GAAG,EAAE,CAAC,CAAA;AAAA,MAC9D,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,SAAA,GAAY,CAAC,KAAA,KAAwB;AAC3C,QAAA,IAAI,IAAA,CAAK,WAAA,KAAgB,iBAAA,IAAqB,KAAA,CAAM,gBAAgB,WAAA,EAAa;AAC/E,UAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,KAAA,CAAM,IAAI,CAAA;AAC9C,UAAA,IAAI,SAAS,IAAA,KAAS,aAAA,EAAe,IAAA,CAAK,aAAA,GAAgB,QAAQ,IAAI,CAAA;AAAA,eAAA,IAC7D,SAAS,IAAA,KAAS,aAAA,EAAe,IAAA,CAAK,aAAA,GAAgB,QAAQ,IAAI,CAAA;AAAA,QAC7E,CAAA,MAAA,IAAW,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,EAAU;AACzC,UAAA,IAAI;AACF,YAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA;AACjC,YAAA,IAAI,IAAI,IAAA,KAAS,aAAA,EAAe,IAAA,CAAK,aAAA,GAAgB,IAAI,IAAI,CAAA;AAAA,iBAAA,IACpD,IAAI,IAAA,KAAS,aAAA,EAAe,IAAA,CAAK,aAAA,GAAgB,IAAI,IAAI,CAAA;AAAA,iBAAA,IACzD,GAAA,CAAI,SAAS,cAAA,EAAgB;AACpC,cAAA,IAAA,CAAK,iBAAiB,GAAA,CAAI,IAAA,CAAK,KAAA,EAAO,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,YACvD;AAAA,UACF,CAAA,CAAA,MAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,IAAU;AAAA,IACzC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,IAAI,KAAA,EAAM;AAAA,IACjB,CAAA,CAAA,MAAQ;AAAA,IAAC;AACT,IAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AAAA,EACZ;AACF,CAAA;;;AChDO,SAAS,iBAAiB,IAAA,GAAO,WAAA,EAAa,MAAA,GAAS,KAAA,EAAO,SAAS,KAAA,EAAe;AAC3F,EAAA,OAAO,2BAA2B,kBAAA,CAAmB,IAAI,CAAC,CAAA,QAAA,EAAW,MAAM,WAAW,MAAM,CAAA,CAAA;AAC9F;AAQO,SAAS,iBAAiB,GAAA,EAA8D;AAC7F,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,GAAG,CAAA;AACvB,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA,IAAK,WAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,IAAK,OAAA;AACjD,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,IAAK,OAAA;AACjD,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAA,OAAA,EAAU,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,QAAA,CAAA;AAAA,IAC/B,KAAA,EAAO,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,QAAA,CAAA;AAAA,IAC7B,KAAA,EAAO,CAAA,QAAA,EAAW,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA;AAAA,GAClC;AACF;AAEA,IAAM,eAAA,GAEF;AAAA,EACF,UAAA,EAAY,CAAC,cAAA,EAAgB,WAAW,CAAA;AAAA,EACxC,cAAA,EAAgB,GAAA;AAAA,EAChB,aAAA,EAAe;AACjB,CAAA;AAQO,IAAM,kBAAA,GAAN,cAAiC,YAAA,CAA6B;AAAA,EAC3D,OAAA;AAAA,EACA,SAAA,GAA8B,IAAA;AAAA,EAC9B,cAAA,GAAuD,IAAA;AAAA,EACvD,gBAAA,GAAmB,KAAA;AAAA,EACnB,aAAA,GAA+B,IAAA;AAAA,EAE/B,MAAA,GAA0B,cAAA;AAAA,EAC1B,SAAA,GAA+B,MAAA;AAAA,EAEvC,IAAI,KAAA,GAAyB;AAC3B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EACA,IAAI,QAAA,GAA8B;AAChC,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,YAAY,OAAA,EAA0B;AACpC,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,OAAA,GAAU,EAAE,GAAG,eAAA,EAAiB,GAAG,OAAA,EAAQ;AAAA,EAClD;AAAA,EAEA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,IAAA,IAAA,CAAK,QAAA,CAAS,cAAc,MAAM,CAAA;AAGlC,IAAA,IAAI,KAAA,GAAQ,KAAK,OAAA,CAAQ,KAAA;AACzB,IAAA,IAAI,KAAA,GAAQ,KAAK,OAAA,CAAQ,KAAA;AACzB,IAAA,IAAI,QAAA,GAAW,KAAK,OAAA,CAAQ,QAAA;AAE5B,IAAA,IAAI,IAAA,CAAK,QAAQ,GAAA,EAAK;AACpB,MAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAChD,MAAA,KAAA,GAAQ,SAAS,MAAA,CAAO,KAAA;AACxB,MAAA,KAAA,GAAQ,SAAS,MAAA,CAAO,KAAA;AACxB,MAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,SAAS,MAAA,CAAO,KAAA;AAAA,IACpD;AAEA,IAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,EAAO;AACpB,MAAA,MAAM,KAAA,GACJ,IAAA,CAAK,OAAA,CAAQ,KAAA,IACb,IAAI,GAAA,CAAI,UAAA,EAAY,UAAA,CAAW,QAAA,EAAU,MAAA,IAAU,wBAAwB,CAAA,CAAE,IAAA;AAE/E,MAAA,IAAI;AACF,QAAA,MAAM,EAAA,GAAK,MAAM,qBAAA,CAAsB,KAAK,CAAA;AAC5C,QAAA,MAAM,SAAA,GAAY,iBAAiB,EAAE,CAAA;AACrC,QAAA,KAAA,GAAQ,UAAU,YAAA,EAAc,GAAA;AAChC,QAAA,KAAA,GAAQ,UAAU,SAAA,EAAW,GAAA;AAC7B,QAAA,QAAA,GAAW,QAAA,IAAY,UAAU,YAAA,EAAc,QAAA;AAC/C,QAAA,IAAA,CAAK,aAAA,GAAgB,UAAU,aAAA,IAAiB,IAAA;AAAA,MAClD,SAAS,GAAA,EAAK;AACZ,QAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAEtE,QAAA,KAAA,GAAQ,CAAA,KAAA,EAAQ,WAAW,QAAA,EAAU,QAAA,IAAY,WAAW,CAAA,CAAA,EAAI,UAAA,CAAW,QAAA,EAAU,IAAA,IAAQ,OAAO,CAAA,QAAA,CAAA;AAAA,MACtG;AAAA,IACF;AAGA,IAAA,KAAA,MAAW,KAAA,IAAS,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY;AAC3C,MAAA,IAAI,KAAA,KAAU,kBAAkB,KAAA,EAAO;AACrC,QAAA,IAAI;AACF,UAAA,IAAI,OAAO,UAAA,CAAW,YAAA,KAAiB,WAAA,EAAa;AACpD,UAAA,MAAM,OAAA,GAAU,IAAI,mBAAA,CAAoB,KAAA,EAAO,QAAQ,CAAA;AACvD,UAAA,IAAI,MAAM,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA,EAAG;AAAA,QACxC,CAAA,CAAA,MAAQ;AACN,UAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA,IAAI,KAAA,KAAU,eAAe,KAAA,EAAO;AAClC,QAAA,IAAI;AACF,UAAA,MAAM,UAAU,IAAI,gBAAA,CAAiB,KAAA,EAAO,IAAA,CAAK,QAAQ,aAAa,CAAA;AACtE,UAAA,IAAI,MAAM,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA,EAAG;AAAA,QACxC,CAAA,CAAA,MAAQ;AACN,UAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,gBAAgB,MAAM,CAAA;AACpC,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA,EAEA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAA,CAAK,cAAA,EAAe;AACpB,IAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AACtB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,IAAA,CAAK,QAAA,CAAS,gBAAgB,MAAM,CAAA;AAAA,EACtC;AAAA,EAEA,MAAM,eAAA,GAAyC;AAC7C,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,EAAe,OAAO,EAAC;AACjC,IAAA,MAAM,GAAA,GAAM,MAAM,UAAA,CAAW,KAAA,CAAM,KAAK,aAAa,CAAA;AACrD,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,EAAC;AACrB,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,OAAO,IAAA,CAAK,WAAW,EAAC;AAAA,EAC1B;AAAA,EAEA,MAAc,aAAa,OAAA,EAAsC;AAC/D,IAAA,OAAA,CAAQ,gBAAgB,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,CAAK,eAAe,IAAI,CAAA;AAC/D,IAAA,OAAA,CAAQ,gBAAgB,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,CAAK,eAAe,IAAI,CAAA;AAC/D,IAAA,OAAA,CAAQ,UAAU,CAAC,GAAA,KAAQ,IAAA,CAAK,IAAA,CAAK,SAAS,GAAG,CAAA;AAEjD,IAAA,IAAI,oBAAoB,OAAA,EAAS;AAC/B,MAAC,OAAA,CAAgB,cAAA,GAAiB,CAAC,KAAA,EAAqC,MAAA,KAAuB;AAC7F,QAAA,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,KAAA,EAAO,MAAM,CAAA;AAAA,MACzC,CAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,UAAU,MAAM;AACtB,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,MAAA,IAAA,CAAK,QAAA,CAAS,gBAAgB,MAAM,CAAA;AACpC,MAAA,IAAI,CAAC,IAAA,CAAK,gBAAA,EAAkB,IAAA,CAAK,iBAAA,EAAkB;AAAA,IACrD,CAAA;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,OAAA,EAAQ;AACtB,MAAA,IAAA,CAAK,SAAA,GAAY,OAAA;AACjB,MAAA,IAAA,CAAK,QAAA,CAAS,WAAA,EAAa,OAAA,CAAQ,QAAQ,CAAA;AAC3C,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AACtE,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,QAAA,CAAS,OAAwB,QAAA,EAAmC;AAC1E,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,KAAA,IAAS,IAAA,CAAK,cAAc,QAAA,EAAU;AAC1D,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AACjB,IAAA,IAAA,CAAK,IAAA,CAAK,aAAA,EAAe,KAAA,EAAO,QAAQ,CAAA;AAAA,EAC1C;AAAA,EAEQ,iBAAA,GAA0B;AAChC,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,cAAA,IAAkB,CAAA,IAAK,KAAK,gBAAA,EAAkB;AAC/D,IAAA,IAAA,CAAK,cAAA,EAAe;AACpB,IAAA,IAAA,CAAK,cAAA,GAAiB,WAAW,MAAM;AACrC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,MAAA,IAAA,CAAK,OAAA,EAAQ;AAAA,IACf,CAAA,EAAG,IAAA,CAAK,OAAA,CAAQ,cAAc,CAAA;AAAA,EAChC;AAAA,EAEQ,cAAA,GAAuB;AAC7B,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAChC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AAAA,EACF;AACF;;;ACxMA,IAAM,UAAA,GAAa,mBAAA;AACnB,IAAM,WAAA,GAAc,sDAAA;AAmBb,SAAS,eAAe,OAAA,EAA2C;AACxE,EAAA,MAAM,SAAA,GAAY,SAAS,SAAA,IAAa,UAAA;AACxC,EAAA,MAAM,OAAA,GAAU,SAAS,OAAA,IAAW,IAAA;AAGpC,EAAA,IAAI,WAAA,GAAc,WAAA;AAClB,EAAA,IAAI,SAAS,WAAA,EAAa;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,OAAA,CAAQ,WAAW,CAAA;AAC1C,MAAA,IAAI,MAAA,CAAO,QAAA,KAAa,OAAA,IAAW,MAAA,CAAO,aAAa,QAAA,EAAU;AAC/D,QAAA,WAAA,GAAc,OAAA,CAAQ,WAAA;AAAA,MACxB;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAAC;AAAA,EACX;AAEA,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAE9B,IAAA,IAAI,QAAA,GAAW,KAAA;AAEf,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,QAAA,GAAW,IAAA;AAAA,IACb,CAAA;AACA,IAAA,UAAA,CAAW,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AAG1C,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,MAAM,OAAA,GAAU,MAAA;AACvB,IAAA,MAAA,CAAO,GAAA,GAAM,SAAA;AACb,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAEhC,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,UAAA,CAAW,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAC7C,MAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAEhC,MAAA,IAAI,QAAA,IAAY,SAAS,MAAA,EAAQ;AAC/B,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,MACd,CAAA,MAAO;AAEL,QAAA,UAAA,CAAW,SAAS,IAAA,GAAO,WAAA;AAC3B,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF,GAAG,OAAO,CAAA;AAAA,EACZ,CAAC,CAAA;AACH","file":"index.js","sourcesContent":["import type { ThingDescription } from \"./types.js\";\n\nexport interface ResolvedEndpoints {\n webtransport?: { url: string; certHash?: string };\n websocket?: { url: string };\n deviceInfoUrl?: string;\n}\n\n/** Fetch the WoT Thing Description from the bridge */\nexport async function fetchThingDescription(tdUrl: string): Promise<ThingDescription> {\n const res = await globalThis.fetch(tdUrl);\n if (!res.ok) throw new Error(`Failed to fetch TD: HTTP ${res.status}`);\n return res.json() as Promise<ThingDescription>;\n}\n\n/** Extract WebTransport, WebSocket, and device info endpoints from a Thing Description */\nexport function resolveEndpoints(td: ThingDescription): ResolvedEndpoints {\n const result: ResolvedEndpoints = {};\n\n const spatialForms = td.events?.spatialData?.forms ?? [];\n\n const wtForm = spatialForms.find((f) => f.subprotocol === \"webtransport\");\n if (wtForm) {\n result.webtransport = {\n url: wtForm.href,\n certHash: td[\"satmouse:certHash\"],\n };\n }\n\n const wsForm = spatialForms.find((f) => f.subprotocol === \"websocket\");\n if (wsForm) {\n result.websocket = { url: wsForm.href };\n }\n\n const deviceForm = td.properties?.deviceInfo?.forms?.[0];\n if (deviceForm) {\n result.deviceInfoUrl = deviceForm.href;\n }\n\n return result;\n}\n","import type { SpatialData, ButtonEvent } from \"./types.js\";\n\n/** Decode 24-byte binary spatial data datagram (WebTransport or raw binary) */\nexport function decodeBinaryFrame(buffer: ArrayBuffer | Uint8Array): SpatialData {\n const len = buffer instanceof ArrayBuffer ? buffer.byteLength : buffer.byteLength;\n if (len < 20) {\n throw new RangeError(`Spatial frame too short: expected ≥20 bytes, got ${len}`);\n }\n const ab = buffer instanceof ArrayBuffer ? buffer : buffer.buffer;\n const offset = buffer instanceof Uint8Array ? buffer.byteOffset : 0;\n const view = new DataView(ab, offset);\n return {\n translation: {\n x: view.getInt16(8, true),\n y: view.getInt16(10, true),\n z: view.getInt16(12, true),\n },\n rotation: {\n x: view.getInt16(14, true),\n y: view.getInt16(16, true),\n z: view.getInt16(18, true),\n },\n timestamp: view.getFloat64(0, true),\n };\n}\n\n/** Decode WebSocket binary frame (1-byte type prefix + 24-byte payload) */\nexport function decodeWsBinaryFrame(\n buffer: ArrayBuffer | Uint8Array,\n): { type: \"spatialData\"; data: SpatialData } | { type: \"buttonEvent\"; data: ButtonEvent } | null {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n if (bytes.length < 1) return null;\n\n const typePrefix = bytes[0];\n if (typePrefix === 0x01 && bytes.length >= 25) {\n return { type: \"spatialData\", data: decodeBinaryFrame(bytes.subarray(1, 25)) };\n }\n if (typePrefix === 0x02) {\n const json = new TextDecoder().decode(bytes.subarray(1));\n return { type: \"buttonEvent\", data: JSON.parse(json) as ButtonEvent };\n }\n return null;\n}\n\n/** Decode length-prefixed JSON button events from a WebTransport stream chunk */\nexport function decodeButtonStream(\n buffer: Uint8Array<ArrayBufferLike>,\n): { events: ButtonEvent[]; remainder: Uint8Array<ArrayBufferLike> } {\n const events: ButtonEvent[] = [];\n let pos = 0;\n\n while (pos + 4 <= buffer.length) {\n const view = new DataView(buffer.buffer, buffer.byteOffset + pos);\n const len = view.getUint32(0, true);\n // Guard against absurd lengths\n if (len > 65536 || pos + 4 + len > buffer.length) break;\n const json = new TextDecoder().decode(buffer.subarray(pos + 4, pos + 4 + len));\n try {\n const event = JSON.parse(json);\n if (typeof event.button === \"number\" && typeof event.pressed === \"boolean\") {\n events.push(event as ButtonEvent);\n }\n } catch {\n // Skip malformed JSON frames\n }\n pos += 4 + len;\n }\n\n return { events, remainder: buffer.subarray(pos) };\n}\n","import type { Transport } from \"./transport.js\";\nimport type { SpatialData, ButtonEvent } from \"../types.js\";\nimport { decodeBinaryFrame, decodeButtonStream } from \"../decode.js\";\n\nexport class WebTransportAdapter implements Transport {\n readonly protocol = \"webtransport\" as const;\n\n onSpatialData: ((data: SpatialData) => void) | null = null;\n onButtonEvent: ((data: ButtonEvent) => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private transport: any = null;\n private url: string;\n private certHash?: string;\n\n constructor(url: string, certHash?: string) {\n this.url = url;\n this.certHash = certHash;\n }\n\n async connect(): Promise<void> {\n if (typeof globalThis.WebTransport === \"undefined\") {\n throw new Error(\"WebTransport is not available in this environment\");\n }\n\n const options: any = {};\n if (this.certHash) {\n options.serverCertificateHashes = [\n {\n algorithm: \"sha-256\",\n value: Uint8Array.from(atob(this.certHash), (c) => c.charCodeAt(0)),\n },\n ];\n }\n\n this.transport = new (globalThis as any).WebTransport(this.url, options);\n await this.transport.ready;\n\n this.readDatagrams();\n this.readStreams();\n\n this.transport.closed\n .then(() => this.onClose?.())\n .catch(() => this.onClose?.());\n }\n\n close(): void {\n try {\n this.transport?.close();\n } catch {}\n this.transport = null;\n }\n\n private async readDatagrams(): Promise<void> {\n const reader = this.transport.datagrams.readable.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n this.onSpatialData?.(decodeBinaryFrame(value));\n }\n } catch {\n // Transport closed\n }\n }\n\n private async readStreams(): Promise<void> {\n const reader = this.transport.incomingUnidirectionalStreams.getReader();\n try {\n while (true) {\n const { value: stream, done } = await reader.read();\n if (done) break;\n this.readButtonStream(stream);\n }\n } catch {\n // Transport closed\n }\n }\n\n private async readButtonStream(stream: any): Promise<void> {\n const reader = stream.getReader();\n let buffer: Uint8Array<ArrayBufferLike> = new Uint8Array(0);\n\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n\n const newBuf = new Uint8Array(buffer.length + value.length);\n newBuf.set(buffer);\n newBuf.set(value, buffer.length);\n\n const { events, remainder } = decodeButtonStream(newBuf);\n for (const event of events) {\n this.onButtonEvent?.(event);\n }\n buffer = remainder;\n }\n } catch {\n // Stream closed\n }\n }\n}\n","import type { Transport } from \"./transport.js\";\nimport type { SpatialData, ButtonEvent, DeviceInfo } from \"../types.js\";\nimport { decodeWsBinaryFrame } from \"../decode.js\";\n\nexport class WebSocketAdapter implements Transport {\n readonly protocol = \"websocket\" as const;\n\n onSpatialData: ((data: SpatialData) => void) | null = null;\n onButtonEvent: ((data: ButtonEvent) => void) | null = null;\n onDeviceStatus: ((event: \"connected\" | \"disconnected\", device: DeviceInfo) => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private ws: WebSocket | null = null;\n private url: string;\n private subprotocol: string;\n\n constructor(url: string, subprotocol: string = \"satmouse-json\") {\n this.url = url;\n this.subprotocol = subprotocol;\n }\n\n async connect(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.ws = new globalThis.WebSocket(this.url, this.subprotocol);\n if (this.subprotocol === \"satmouse-binary\") {\n this.ws.binaryType = \"arraybuffer\";\n }\n\n this.ws.onopen = () => resolve();\n\n this.ws.onerror = () => {\n reject(new Error(`WebSocket connection failed: ${this.url}`));\n };\n\n this.ws.onmessage = (event: MessageEvent) => {\n if (this.subprotocol === \"satmouse-binary\" && event.data instanceof ArrayBuffer) {\n const decoded = decodeWsBinaryFrame(event.data);\n if (decoded?.type === \"spatialData\") this.onSpatialData?.(decoded.data);\n else if (decoded?.type === \"buttonEvent\") this.onButtonEvent?.(decoded.data);\n } else if (typeof event.data === \"string\") {\n try {\n const msg = JSON.parse(event.data);\n if (msg.type === \"spatialData\") this.onSpatialData?.(msg.data);\n else if (msg.type === \"buttonEvent\") this.onButtonEvent?.(msg.data);\n else if (msg.type === \"deviceStatus\") {\n this.onDeviceStatus?.(msg.data.event, msg.data.device);\n }\n } catch {\n // Ignore malformed messages\n }\n }\n };\n\n this.ws.onclose = () => this.onClose?.();\n });\n }\n\n close(): void {\n try {\n this.ws?.close();\n } catch {}\n this.ws = null;\n }\n}\n","import { TypedEmitter } from \"./emitter.js\";\nimport { fetchThingDescription, resolveEndpoints } from \"./discovery.js\";\nimport { WebTransportAdapter } from \"./transports/webtransport.js\";\nimport { WebSocketAdapter } from \"./transports/websocket.js\";\nimport type { Transport } from \"./transports/transport.js\";\nimport type {\n ConnectOptions,\n ConnectionState,\n DeviceInfo,\n SatMouseEvents,\n TransportProtocol,\n} from \"./types.js\";\n\n/**\n * Build a satmouse:// connect URI from connection parameters.\n */\nexport function buildSatMouseUri(host = \"localhost\", wsPort = 18945, wtPort = 18946): string {\n return `satmouse://connect?host=${encodeURIComponent(host)}&wsPort=${wsPort}&wtPort=${wtPort}`;\n}\n\n/**\n * Parse a satmouse:// URI into connection parameters.\n *\n * Format: satmouse://connect?host=<ip>&wsPort=<port>&wtPort=<port>\n * All query params are optional. Defaults: host=localhost, wsPort=4444, wtPort=4443.\n */\nexport function parseSatMouseUri(uri: string): { tdUrl: string; wsUrl: string; wtUrl: string } {\n const url = new URL(uri);\n const host = url.searchParams.get(\"host\") ?? \"localhost\";\n const wsPort = url.searchParams.get(\"wsPort\") ?? \"18945\";\n const wtPort = url.searchParams.get(\"wtPort\") ?? \"18946\";\n return {\n tdUrl: `http://${host}:${wsPort}/td.json`,\n wsUrl: `ws://${host}:${wsPort}/spatial`,\n wtUrl: `https://${host}:${wtPort}`,\n };\n}\n\nconst DEFAULT_OPTIONS: Required<\n Pick<ConnectOptions, \"transports\" | \"reconnectDelay\" | \"wsSubprotocol\">\n> = {\n transports: [\"webtransport\", \"websocket\"],\n reconnectDelay: 2000,\n wsSubprotocol: \"satmouse-json\",\n};\n\n/**\n * Core connection to a SatMouse bridge.\n *\n * Handles discovery (via WoT Thing Description), transport negotiation\n * (WebTransport with WebSocket fallback), event dispatch, and auto-reconnect.\n */\nexport class SatMouseConnection extends TypedEmitter<SatMouseEvents> {\n private options: ConnectOptions & typeof DEFAULT_OPTIONS;\n private transport: Transport | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalClose = false;\n private deviceInfoUrl: string | null = null;\n\n private _state: ConnectionState = \"disconnected\";\n private _protocol: TransportProtocol = \"none\";\n\n get state(): ConnectionState {\n return this._state;\n }\n get protocol(): TransportProtocol {\n return this._protocol;\n }\n\n constructor(options?: ConnectOptions) {\n super();\n this.options = { ...DEFAULT_OPTIONS, ...options };\n }\n\n async connect(): Promise<void> {\n this.intentionalClose = false;\n this.setState(\"connecting\", \"none\");\n\n // Resolve endpoints — satmouse:// URI takes priority\n let wtUrl = this.options.wtUrl;\n let wsUrl = this.options.wsUrl;\n let certHash = this.options.certHash;\n\n if (this.options.uri) {\n const parsed = parseSatMouseUri(this.options.uri);\n wtUrl = wtUrl ?? parsed.wtUrl;\n wsUrl = wsUrl ?? parsed.wsUrl;\n this.options.tdUrl = this.options.tdUrl ?? parsed.tdUrl;\n }\n\n if (!wtUrl && !wsUrl) {\n const tdUrl =\n this.options.tdUrl ??\n new URL(\"/td.json\", globalThis.location?.origin ?? \"http://localhost:18945\").href;\n\n try {\n const td = await fetchThingDescription(tdUrl);\n const endpoints = resolveEndpoints(td);\n wtUrl = endpoints.webtransport?.url;\n wsUrl = endpoints.websocket?.url;\n certHash = certHash ?? endpoints.webtransport?.certHash;\n this.deviceInfoUrl = endpoints.deviceInfoUrl ?? null;\n } catch (err) {\n this.emit(\"error\", err instanceof Error ? err : new Error(String(err)));\n // Fall back to default WS URL\n wsUrl = `ws://${globalThis.location?.hostname ?? \"localhost\"}:${globalThis.location?.port ?? \"18945\"}/spatial`;\n }\n }\n\n // Try transports in preference order\n for (const proto of this.options.transports) {\n if (proto === \"webtransport\" && wtUrl) {\n try {\n if (typeof globalThis.WebTransport === \"undefined\") continue;\n const adapter = new WebTransportAdapter(wtUrl, certHash);\n if (await this.tryTransport(adapter)) return;\n } catch {\n continue;\n }\n }\n if (proto === \"websocket\" && wsUrl) {\n try {\n const adapter = new WebSocketAdapter(wsUrl, this.options.wsSubprotocol);\n if (await this.tryTransport(adapter)) return;\n } catch {\n continue;\n }\n }\n }\n\n this.setState(\"disconnected\", \"none\");\n this.scheduleReconnect();\n }\n\n disconnect(): void {\n this.intentionalClose = true;\n this.clearReconnect();\n this.transport?.close();\n this.transport = null;\n this.setState(\"disconnected\", \"none\");\n }\n\n async fetchDeviceInfo(): Promise<DeviceInfo[]> {\n if (!this.deviceInfoUrl) return [];\n const res = await globalThis.fetch(this.deviceInfoUrl);\n if (!res.ok) return [];\n const data = await res.json();\n return data.devices ?? [];\n }\n\n private async tryTransport(adapter: Transport): Promise<boolean> {\n adapter.onSpatialData = (data) => this.emit(\"spatialData\", data);\n adapter.onButtonEvent = (data) => this.emit(\"buttonEvent\", data);\n adapter.onError = (err) => this.emit(\"error\", err);\n\n if (\"onDeviceStatus\" in adapter) {\n (adapter as any).onDeviceStatus = (event: \"connected\" | \"disconnected\", device: DeviceInfo) => {\n this.emit(\"deviceStatus\", event, device);\n };\n }\n\n adapter.onClose = () => {\n this.transport = null;\n this.setState(\"disconnected\", \"none\");\n if (!this.intentionalClose) this.scheduleReconnect();\n };\n\n try {\n await adapter.connect();\n this.transport = adapter;\n this.setState(\"connected\", adapter.protocol);\n return true;\n } catch (err) {\n this.emit(\"error\", err instanceof Error ? err : new Error(String(err)));\n return false;\n }\n }\n\n private setState(state: ConnectionState, protocol: TransportProtocol): void {\n if (this._state === state && this._protocol === protocol) return;\n this._state = state;\n this._protocol = protocol;\n this.emit(\"stateChange\", state, protocol);\n }\n\n private scheduleReconnect(): void {\n if (this.options.reconnectDelay <= 0 || this.intentionalClose) return;\n this.clearReconnect();\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, this.options.reconnectDelay);\n }\n\n private clearReconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n}\n","const SCHEME_URL = \"satmouse://launch\";\nconst PROJECT_URL = \"https://github.com/kelnishi/SatMouse/releases/latest\";\n\nexport interface LaunchOptions {\n /** URL scheme to open. Default: \"satmouse://launch\" */\n schemeUrl?: string;\n /** Fallback URL if the app is not installed. Default: GitHub releases page */\n fallbackUrl?: string;\n /** Timeout in ms before assuming the app is not installed. Default: 2500 */\n timeout?: number;\n}\n\n/**\n * Attempt to launch SatMouse via the `satmouse://` URL scheme.\n *\n * If the app is installed and registered, the OS opens it. If not,\n * navigates to the fallback URL (project releases page) after a timeout.\n *\n * Returns true if the scheme likely opened, false if it fell back.\n */\nexport function launchSatMouse(options?: LaunchOptions): Promise<boolean> {\n const schemeUrl = options?.schemeUrl ?? SCHEME_URL;\n const timeout = options?.timeout ?? 2500;\n\n // Validate fallback URL — only allow http/https to prevent javascript: or data: injection\n let fallbackUrl = PROJECT_URL;\n if (options?.fallbackUrl) {\n try {\n const parsed = new URL(options.fallbackUrl);\n if (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") {\n fallbackUrl = options.fallbackUrl;\n }\n } catch {}\n }\n\n return new Promise((resolve) => {\n // Track if we leave the page (scheme handler opened the app)\n let launched = false;\n\n const onBlur = () => {\n launched = true;\n };\n globalThis.addEventListener(\"blur\", onBlur);\n\n // Use a hidden iframe to trigger the scheme without navigating away\n const iframe = document.createElement(\"iframe\");\n iframe.style.display = \"none\";\n iframe.src = schemeUrl;\n document.body.appendChild(iframe);\n\n setTimeout(() => {\n globalThis.removeEventListener(\"blur\", onBlur);\n document.body.removeChild(iframe);\n\n if (launched || document.hidden) {\n resolve(true);\n } else {\n // App not installed — redirect to project page\n globalThis.location.href = fallbackUrl;\n resolve(false);\n }\n }, timeout);\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/discovery.ts","../../src/core/decode.ts","../../src/core/transports/webtransport.ts","../../src/core/transports/websocket.ts","../../src/core/connection.ts","../../src/core/launch.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ThingDescription } from \"./types.js\";\n\nexport interface ResolvedEndpoints {\n webtransport?: { url: string; certHash?: string };\n websocket?: { url: string };\n deviceInfoUrl?: string;\n}\n\n/** Fetch the WoT Thing Description from the bridge */\nexport async function fetchThingDescription(tdUrl: string): Promise<ThingDescription> {\n const res = await globalThis.fetch(tdUrl);\n if (!res.ok) throw new Error(`Failed to fetch TD: HTTP ${res.status}`);\n return res.json() as Promise<ThingDescription>;\n}\n\n/** Extract WebTransport, WebSocket, and device info endpoints from a Thing Description */\nexport function resolveEndpoints(td: ThingDescription): ResolvedEndpoints {\n const result: ResolvedEndpoints = {};\n\n const spatialForms = td.events?.spatialData?.forms ?? [];\n\n const wtForm = spatialForms.find((f) => f.subprotocol === \"webtransport\");\n if (wtForm) {\n result.webtransport = {\n url: wtForm.href,\n certHash: td[\"satmouse:certHash\"],\n };\n }\n\n const wsForm = spatialForms.find((f) => f.subprotocol === \"websocket\");\n if (wsForm) {\n result.websocket = { url: wsForm.href };\n }\n\n const deviceForm = td.properties?.deviceInfo?.forms?.[0];\n if (deviceForm) {\n result.deviceInfoUrl = deviceForm.href;\n }\n\n return result;\n}\n","import type { SpatialData, ButtonEvent } from \"./types.js\";\n\n/** Decode 24-byte binary spatial data datagram (WebTransport or raw binary) */\nexport function decodeBinaryFrame(buffer: ArrayBuffer | Uint8Array): SpatialData {\n const len = buffer instanceof ArrayBuffer ? buffer.byteLength : buffer.byteLength;\n if (len < 20) {\n throw new RangeError(`Spatial frame too short: expected ≥20 bytes, got ${len}`);\n }\n const ab = buffer instanceof ArrayBuffer ? buffer : buffer.buffer;\n const offset = buffer instanceof Uint8Array ? buffer.byteOffset : 0;\n const view = new DataView(ab, offset);\n return {\n translation: {\n x: view.getInt16(8, true),\n y: view.getInt16(10, true),\n z: view.getInt16(12, true),\n },\n rotation: {\n x: view.getInt16(14, true),\n y: view.getInt16(16, true),\n z: view.getInt16(18, true),\n },\n timestamp: view.getFloat64(0, true),\n };\n}\n\n/** Decode WebSocket binary frame (1-byte type prefix + 24-byte payload) */\nexport function decodeWsBinaryFrame(\n buffer: ArrayBuffer | Uint8Array,\n): { type: \"spatialData\"; data: SpatialData } | { type: \"buttonEvent\"; data: ButtonEvent } | null {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n if (bytes.length < 1) return null;\n\n const typePrefix = bytes[0];\n if (typePrefix === 0x01 && bytes.length >= 25) {\n return { type: \"spatialData\", data: decodeBinaryFrame(bytes.subarray(1, 25)) };\n }\n if (typePrefix === 0x02) {\n const json = new TextDecoder().decode(bytes.subarray(1));\n return { type: \"buttonEvent\", data: JSON.parse(json) as ButtonEvent };\n }\n return null;\n}\n\n/** Decode length-prefixed JSON button events from a WebTransport stream chunk */\nexport function decodeButtonStream(\n buffer: Uint8Array<ArrayBufferLike>,\n): { events: ButtonEvent[]; remainder: Uint8Array<ArrayBufferLike> } {\n const events: ButtonEvent[] = [];\n let pos = 0;\n\n while (pos + 4 <= buffer.length) {\n const view = new DataView(buffer.buffer, buffer.byteOffset + pos);\n const len = view.getUint32(0, true);\n // Guard against absurd lengths\n if (len > 65536 || pos + 4 + len > buffer.length) break;\n const json = new TextDecoder().decode(buffer.subarray(pos + 4, pos + 4 + len));\n try {\n const event = JSON.parse(json);\n if (typeof event.button === \"number\" && typeof event.pressed === \"boolean\") {\n events.push(event as ButtonEvent);\n }\n } catch {\n // Skip malformed JSON frames\n }\n pos += 4 + len;\n }\n\n return { events, remainder: buffer.subarray(pos) };\n}\n","import type { Transport } from \"./transport.js\";\nimport type { SpatialData, ButtonEvent } from \"../types.js\";\nimport { decodeBinaryFrame, decodeButtonStream } from \"../decode.js\";\n\nexport class WebTransportAdapter implements Transport {\n readonly protocol = \"webtransport\" as const;\n\n onSpatialData: ((data: SpatialData) => void) | null = null;\n onButtonEvent: ((data: ButtonEvent) => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private transport: any = null;\n private url: string;\n private certHash?: string;\n\n constructor(url: string, certHash?: string) {\n this.url = url;\n this.certHash = certHash;\n }\n\n async connect(): Promise<void> {\n if (typeof globalThis.WebTransport === \"undefined\") {\n throw new Error(\"WebTransport is not available in this environment\");\n }\n\n const options: any = {};\n if (this.certHash) {\n options.serverCertificateHashes = [\n {\n algorithm: \"sha-256\",\n value: Uint8Array.from(atob(this.certHash), (c) => c.charCodeAt(0)),\n },\n ];\n }\n\n this.transport = new (globalThis as any).WebTransport(this.url, options);\n await this.transport.ready;\n\n this.readDatagrams();\n this.readStreams();\n\n this.transport.closed\n .then(() => this.onClose?.())\n .catch(() => this.onClose?.());\n }\n\n close(): void {\n try {\n this.transport?.close();\n } catch {}\n this.transport = null;\n }\n\n private async readDatagrams(): Promise<void> {\n const reader = this.transport.datagrams.readable.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n this.onSpatialData?.(decodeBinaryFrame(value));\n }\n } catch {\n // Transport closed\n }\n }\n\n private async readStreams(): Promise<void> {\n const reader = this.transport.incomingUnidirectionalStreams.getReader();\n try {\n while (true) {\n const { value: stream, done } = await reader.read();\n if (done) break;\n this.readButtonStream(stream);\n }\n } catch {\n // Transport closed\n }\n }\n\n private async readButtonStream(stream: any): Promise<void> {\n const reader = stream.getReader();\n let buffer: Uint8Array<ArrayBufferLike> = new Uint8Array(0);\n\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n\n const newBuf = new Uint8Array(buffer.length + value.length);\n newBuf.set(buffer);\n newBuf.set(value, buffer.length);\n\n const { events, remainder } = decodeButtonStream(newBuf);\n for (const event of events) {\n this.onButtonEvent?.(event);\n }\n buffer = remainder;\n }\n } catch {\n // Stream closed\n }\n }\n}\n","import type { Transport } from \"./transport.js\";\nimport type { SpatialData, ButtonEvent, DeviceInfo } from \"../types.js\";\nimport { decodeWsBinaryFrame } from \"../decode.js\";\n\nexport class WebSocketAdapter implements Transport {\n readonly protocol = \"websocket\" as const;\n\n onSpatialData: ((data: SpatialData) => void) | null = null;\n onButtonEvent: ((data: ButtonEvent) => void) | null = null;\n onDeviceStatus: ((event: \"connected\" | \"disconnected\", device: DeviceInfo) => void) | null = null;\n onClose: (() => void) | null = null;\n onError: ((error: Error) => void) | null = null;\n\n private ws: WebSocket | null = null;\n private url: string;\n private subprotocol: string;\n\n constructor(url: string, subprotocol: string = \"satmouse-json\") {\n this.url = url;\n this.subprotocol = subprotocol;\n }\n\n async connect(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.ws = new globalThis.WebSocket(this.url, this.subprotocol);\n if (this.subprotocol === \"satmouse-binary\") {\n this.ws.binaryType = \"arraybuffer\";\n }\n\n this.ws.onopen = () => resolve();\n\n this.ws.onerror = () => {\n reject(new Error(`WebSocket connection failed: ${this.url}`));\n };\n\n this.ws.onmessage = (event: MessageEvent) => {\n if (this.subprotocol === \"satmouse-binary\" && event.data instanceof ArrayBuffer) {\n const decoded = decodeWsBinaryFrame(event.data);\n if (decoded?.type === \"spatialData\") this.onSpatialData?.(decoded.data);\n else if (decoded?.type === \"buttonEvent\") this.onButtonEvent?.(decoded.data);\n } else if (typeof event.data === \"string\") {\n try {\n const msg = JSON.parse(event.data);\n if (msg.type === \"spatialData\") this.onSpatialData?.(msg.data);\n else if (msg.type === \"buttonEvent\") this.onButtonEvent?.(msg.data);\n else if (msg.type === \"deviceStatus\") {\n this.onDeviceStatus?.(msg.data.event, msg.data.device);\n }\n } catch {\n // Ignore malformed messages\n }\n }\n };\n\n this.ws.onclose = () => this.onClose?.();\n });\n }\n\n close(): void {\n try {\n this.ws?.close();\n } catch {}\n this.ws = null;\n }\n}\n","import { TypedEmitter } from \"./emitter.js\";\nimport { fetchThingDescription, resolveEndpoints } from \"./discovery.js\";\nimport { WebTransportAdapter } from \"./transports/webtransport.js\";\nimport { WebSocketAdapter } from \"./transports/websocket.js\";\nimport type { Transport } from \"./transports/transport.js\";\nimport type {\n ConnectOptions,\n ConnectionState,\n DeviceInfo,\n SatMouseEvents,\n TransportProtocol,\n} from \"./types.js\";\n\n/**\n * Build a satmouse:// connect URI from connection parameters.\n */\nexport function buildSatMouseUri(host = \"localhost\", wsPort = 18945, wtPort = 18946): string {\n return `satmouse://connect?host=${encodeURIComponent(host)}&wsPort=${wsPort}&wtPort=${wtPort}`;\n}\n\n/**\n * Parse a satmouse:// URI into connection parameters.\n *\n * Format: satmouse://connect?host=<ip>&wsPort=<port>&wtPort=<port>\n * All query params are optional. Defaults: host=localhost, wsPort=4444, wtPort=4443.\n */\nexport function parseSatMouseUri(uri: string): { tdUrl: string; wsUrl: string; wtUrl: string } {\n const url = new URL(uri);\n const host = url.searchParams.get(\"host\") ?? \"localhost\";\n const wsPort = url.searchParams.get(\"wsPort\") ?? \"18945\";\n const wtPort = url.searchParams.get(\"wtPort\") ?? \"18946\";\n return {\n tdUrl: `http://${host}:${wsPort}/td.json`,\n wsUrl: `ws://${host}:${wsPort}/spatial`,\n wtUrl: `https://${host}:${wtPort}`,\n };\n}\n\nconst DEFAULT_OPTIONS: Required<\n Pick<ConnectOptions, \"transports\" | \"reconnectDelay\" | \"maxRetries\" | \"wsSubprotocol\">\n> = {\n transports: [\"webtransport\", \"websocket\"],\n reconnectDelay: 2000,\n maxRetries: 3,\n wsSubprotocol: \"satmouse-json\",\n};\n\n/**\n * Core connection to a SatMouse bridge.\n *\n * Handles discovery (via WoT Thing Description), transport negotiation\n * (WebTransport with WebSocket fallback), event dispatch, and auto-reconnect.\n */\nexport class SatMouseConnection extends TypedEmitter<SatMouseEvents> {\n private options: ConnectOptions & typeof DEFAULT_OPTIONS;\n private transport: Transport | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalClose = false;\n private deviceInfoUrl: string | null = null;\n private retryCount = 0;\n\n private _state: ConnectionState = \"disconnected\";\n private _protocol: TransportProtocol = \"none\";\n\n get state(): ConnectionState {\n return this._state;\n }\n get protocol(): TransportProtocol {\n return this._protocol;\n }\n\n constructor(options?: ConnectOptions) {\n super();\n this.options = { ...DEFAULT_OPTIONS, ...options };\n }\n\n async connect(): Promise<void> {\n this.intentionalClose = false;\n this.setState(\"connecting\", \"none\");\n\n // Resolve endpoints — satmouse:// URI takes priority\n let wtUrl = this.options.wtUrl;\n let wsUrl = this.options.wsUrl;\n let certHash = this.options.certHash;\n\n if (this.options.uri) {\n const parsed = parseSatMouseUri(this.options.uri);\n wtUrl = wtUrl ?? parsed.wtUrl;\n wsUrl = wsUrl ?? parsed.wsUrl;\n this.options.tdUrl = this.options.tdUrl ?? parsed.tdUrl;\n }\n\n if (!wtUrl && !wsUrl) {\n const tdUrl =\n this.options.tdUrl ??\n new URL(\"/td.json\", globalThis.location?.origin ?? \"http://localhost:18945\").href;\n\n try {\n const td = await fetchThingDescription(tdUrl);\n const endpoints = resolveEndpoints(td);\n wtUrl = endpoints.webtransport?.url;\n wsUrl = endpoints.websocket?.url;\n certHash = certHash ?? endpoints.webtransport?.certHash;\n this.deviceInfoUrl = endpoints.deviceInfoUrl ?? null;\n } catch (err) {\n this.emit(\"error\", err instanceof Error ? err : new Error(String(err)));\n // Fall back to default WS URL\n wsUrl = `ws://${globalThis.location?.hostname ?? \"localhost\"}:${globalThis.location?.port ?? \"18945\"}/spatial`;\n }\n }\n\n // Try transports in preference order\n for (const proto of this.options.transports) {\n if (proto === \"webtransport\" && wtUrl) {\n try {\n if (typeof globalThis.WebTransport === \"undefined\") continue;\n const adapter = new WebTransportAdapter(wtUrl, certHash);\n if (await this.tryTransport(adapter)) return;\n } catch {\n continue;\n }\n }\n if (proto === \"websocket\" && wsUrl) {\n try {\n const adapter = new WebSocketAdapter(wsUrl, this.options.wsSubprotocol);\n if (await this.tryTransport(adapter)) return;\n } catch {\n continue;\n }\n }\n }\n\n this.setState(\"disconnected\", \"none\");\n this.scheduleReconnect();\n }\n\n /** Reset retry count and reconnect. Use after \"failed\" state. */\n retry(): void {\n this.retryCount = 0;\n this.intentionalClose = false;\n this.connect();\n }\n\n disconnect(): void {\n this.intentionalClose = true;\n this.clearReconnect();\n this.transport?.close();\n this.transport = null;\n this.setState(\"disconnected\", \"none\");\n }\n\n async fetchDeviceInfo(): Promise<DeviceInfo[]> {\n if (!this.deviceInfoUrl) return [];\n const res = await globalThis.fetch(this.deviceInfoUrl);\n if (!res.ok) return [];\n const data = await res.json();\n return data.devices ?? [];\n }\n\n private async tryTransport(adapter: Transport): Promise<boolean> {\n adapter.onSpatialData = (data) => this.emit(\"spatialData\", data);\n adapter.onButtonEvent = (data) => this.emit(\"buttonEvent\", data);\n adapter.onError = (err) => this.emit(\"error\", err);\n\n if (\"onDeviceStatus\" in adapter) {\n (adapter as any).onDeviceStatus = (event: \"connected\" | \"disconnected\", device: DeviceInfo) => {\n this.emit(\"deviceStatus\", event, device);\n };\n }\n\n adapter.onClose = () => {\n this.transport = null;\n this.setState(\"disconnected\", \"none\");\n if (!this.intentionalClose) this.scheduleReconnect();\n };\n\n try {\n await adapter.connect();\n this.transport = adapter;\n this.retryCount = 0;\n this.setState(\"connected\", adapter.protocol);\n return true;\n } catch (err) {\n this.emit(\"error\", err instanceof Error ? err : new Error(String(err)));\n return false;\n }\n }\n\n private setState(state: ConnectionState, protocol: TransportProtocol): void {\n if (this._state === state && this._protocol === protocol) return;\n this._state = state;\n this._protocol = protocol;\n this.emit(\"stateChange\", state, protocol);\n }\n\n private scheduleReconnect(): void {\n if (this.options.reconnectDelay <= 0 || this.intentionalClose) return;\n\n this.retryCount++;\n console.log(`[SatMouse] Reconnect attempt ${this.retryCount}/${this.options.maxRetries}`);\n if (this.retryCount > this.options.maxRetries) {\n console.log(\"[SatMouse] Max retries exceeded, giving up\");\n this.setState(\"failed\", \"none\");\n return;\n }\n\n this.clearReconnect();\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, this.options.reconnectDelay);\n }\n\n private clearReconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n}\n","const SCHEME_URL = \"satmouse://launch\";\nconst PROJECT_URL = \"https://github.com/kelnishi/SatMouse/releases/latest\";\n\nexport interface LaunchOptions {\n /** URL scheme to open. Default: \"satmouse://launch\" */\n schemeUrl?: string;\n /** Fallback URL if the app is not installed. Default: GitHub releases page */\n fallbackUrl?: string;\n /** Timeout in ms before assuming the app is not installed. Default: 2500 */\n timeout?: number;\n}\n\n/**\n * Attempt to launch SatMouse via the `satmouse://` URL scheme.\n *\n * If the app is installed and registered, the OS opens it. If not,\n * navigates to the fallback URL (project releases page) after a timeout.\n *\n * Returns true if the scheme likely opened, false if it fell back.\n */\nexport function launchSatMouse(options?: LaunchOptions): Promise<boolean> {\n const schemeUrl = options?.schemeUrl ?? SCHEME_URL;\n const timeout = options?.timeout ?? 2500;\n\n // Validate fallback URL — only allow http/https to prevent javascript: or data: injection\n let fallbackUrl = PROJECT_URL;\n if (options?.fallbackUrl) {\n try {\n const parsed = new URL(options.fallbackUrl);\n if (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") {\n fallbackUrl = options.fallbackUrl;\n }\n } catch {}\n }\n\n return new Promise((resolve) => {\n // Track if we leave the page (scheme handler opened the app)\n let launched = false;\n\n const onBlur = () => {\n launched = true;\n };\n globalThis.addEventListener(\"blur\", onBlur);\n\n // Use a hidden iframe to trigger the scheme without navigating away\n const iframe = document.createElement(\"iframe\");\n iframe.style.display = \"none\";\n iframe.src = schemeUrl;\n document.body.appendChild(iframe);\n\n setTimeout(() => {\n globalThis.removeEventListener(\"blur\", onBlur);\n document.body.removeChild(iframe);\n\n if (launched || document.hidden) {\n resolve(true);\n } else {\n // App not installed — redirect to project page\n globalThis.location.href = fallbackUrl;\n resolve(false);\n }\n }, timeout);\n });\n}\n"]}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkLDSDVYCV_cjs = require('../chunk-LDSDVYCV.cjs');
|
|
4
|
+
|
|
5
|
+
// src/elements/registry.ts
|
|
6
|
+
var globalManager = null;
|
|
7
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
8
|
+
function registerSatMouse(manager) {
|
|
9
|
+
globalManager = manager;
|
|
10
|
+
for (const fn of listeners) fn(manager);
|
|
11
|
+
listeners.clear();
|
|
12
|
+
}
|
|
13
|
+
function getManager() {
|
|
14
|
+
return globalManager;
|
|
15
|
+
}
|
|
16
|
+
function onManagerReady(fn) {
|
|
17
|
+
if (globalManager) fn(globalManager);
|
|
18
|
+
else listeners.add(fn);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/elements/satmouse-status.ts
|
|
22
|
+
var TEMPLATE = `
|
|
23
|
+
<style>
|
|
24
|
+
:host { display: inline-flex; align-items: center; gap: 8px; font-family: inherit; font-size: 13px; }
|
|
25
|
+
.dot { width: 8px; height: 8px; border-radius: 50%; background: #e74c3c; transition: background 0.3s; }
|
|
26
|
+
.dot[data-state="connected"] { background: #2ecc71; }
|
|
27
|
+
.dot[data-state="connecting"] { background: #f39c12; }
|
|
28
|
+
.dot[data-state="failed"] { background: #e74c3c; }
|
|
29
|
+
.protocol { color: #7f8c8d; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }
|
|
30
|
+
.launch { padding: 4px 12px; background: #2980b9; color: #fff; border-radius: 4px; font-size: 11px;
|
|
31
|
+
text-decoration: none; cursor: pointer; border: none; font-family: inherit; display: none; }
|
|
32
|
+
.launch:hover { background: #3498db; }
|
|
33
|
+
</style>
|
|
34
|
+
<span class="dot"></span>
|
|
35
|
+
<span class="text">Disconnected</span>
|
|
36
|
+
<span class="protocol"></span>
|
|
37
|
+
<button class="launch">Launch SatMouse</button>
|
|
38
|
+
`;
|
|
39
|
+
var SatMouseStatus = class extends HTMLElement {
|
|
40
|
+
dot;
|
|
41
|
+
text;
|
|
42
|
+
proto;
|
|
43
|
+
launch;
|
|
44
|
+
disconnectTimer = null;
|
|
45
|
+
constructor() {
|
|
46
|
+
super();
|
|
47
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
48
|
+
shadow.innerHTML = TEMPLATE;
|
|
49
|
+
this.dot = shadow.querySelector(".dot");
|
|
50
|
+
this.text = shadow.querySelector(".text");
|
|
51
|
+
this.proto = shadow.querySelector(".protocol");
|
|
52
|
+
this.launch = shadow.querySelector(".launch");
|
|
53
|
+
this.launch.addEventListener("click", () => {
|
|
54
|
+
window.location.href = "satmouse://launch";
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
if (!document.hidden) {
|
|
57
|
+
if (confirm("SatMouse doesn't appear to be installed. Go to the download page?")) {
|
|
58
|
+
window.open("https://github.com/kelnishi/SatMouse/releases/latest", "_blank", "noopener");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}, 1e3);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
connectedCallback() {
|
|
65
|
+
this.disconnectTimer = setTimeout(() => {
|
|
66
|
+
this.launch.style.display = "inline-block";
|
|
67
|
+
}, 3e3);
|
|
68
|
+
onManagerReady((manager) => this.bind(manager));
|
|
69
|
+
}
|
|
70
|
+
bind(manager) {
|
|
71
|
+
manager.on("stateChange", (state, protocol) => {
|
|
72
|
+
this.dot.dataset.state = state;
|
|
73
|
+
this.proto.textContent = protocol !== "none" ? protocol : "";
|
|
74
|
+
if (this.disconnectTimer) {
|
|
75
|
+
clearTimeout(this.disconnectTimer);
|
|
76
|
+
this.disconnectTimer = null;
|
|
77
|
+
}
|
|
78
|
+
if (state === "connected") {
|
|
79
|
+
this.text.textContent = "Connected";
|
|
80
|
+
this.launch.style.display = "none";
|
|
81
|
+
} else if (state === "connecting") {
|
|
82
|
+
this.text.textContent = "Connecting...";
|
|
83
|
+
this.launch.style.display = "none";
|
|
84
|
+
} else if (state === "failed") {
|
|
85
|
+
this.text.textContent = "Not running";
|
|
86
|
+
this.launch.style.display = "inline-block";
|
|
87
|
+
} else {
|
|
88
|
+
this.text.textContent = "Disconnected";
|
|
89
|
+
this.launch.style.display = "none";
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
customElements.define("satmouse-status", SatMouseStatus);
|
|
95
|
+
|
|
96
|
+
// src/elements/satmouse-devices.ts
|
|
97
|
+
var AXES = ["tx", "ty", "tz", "rx", "ry", "rz"];
|
|
98
|
+
var STYLES = `
|
|
99
|
+
<style>
|
|
100
|
+
:host { display: block; font-family: inherit; font-size: 12px; }
|
|
101
|
+
.panel { background: #0f3460; border: 1px solid #1a4a8a; border-radius: 6px; padding: 10px; margin-bottom: 8px; }
|
|
102
|
+
summary { cursor: pointer; font-weight: 600; color: #e0e0e0; font-size: 13px; }
|
|
103
|
+
.type { font-size: 10px; color: #7f8c8d; text-transform: uppercase; margin-left: 6px; }
|
|
104
|
+
.controls { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
|
|
105
|
+
.slider-row { display: flex; align-items: center; gap: 6px; }
|
|
106
|
+
.slider-row label { color: #7f8c8d; font-weight: 600; width: 38px; flex-shrink: 0; }
|
|
107
|
+
.slider-row input[type="range"] { flex: 1; min-width: 0; height: 4px; accent-color: #3498db; }
|
|
108
|
+
.slider-row span { color: #7f8c8d; font-family: monospace; font-size: 10px; min-width: 44px; text-align: right; }
|
|
109
|
+
.flip-group { display: flex; flex-direction: column; gap: 4px; }
|
|
110
|
+
.flip-row { display: flex; gap: 8px; }
|
|
111
|
+
.flip-row label { display: flex; align-items: center; gap: 2px; color: #7f8c8d; min-width: 36px; }
|
|
112
|
+
.flip-row input { accent-color: #e74c3c; }
|
|
113
|
+
.remap-group { display: grid; grid-template-columns: 1fr 1fr; gap: 3px 8px; }
|
|
114
|
+
.remap-row { display: flex; gap: 4px; align-items: center; }
|
|
115
|
+
.remap-row label { color: #7f8c8d; width: 24px; flex-shrink: 0; }
|
|
116
|
+
.remap-row select { background: #16213e; color: #e0e0e0; border: 1px solid #1a4a8a; border-radius: 3px;
|
|
117
|
+
font-size: 11px; padding: 1px 4px; flex: 1; min-width: 0; }
|
|
118
|
+
.empty { color: #7f8c8d; font-style: italic; }
|
|
119
|
+
</style>
|
|
120
|
+
`;
|
|
121
|
+
function mapSlider(v) {
|
|
122
|
+
return 1e-4 * Math.pow(500, v / 100);
|
|
123
|
+
}
|
|
124
|
+
function unmapSlider(v) {
|
|
125
|
+
return 100 * Math.log(v / 1e-4) / Math.log(500);
|
|
126
|
+
}
|
|
127
|
+
var SatMouseDevices = class extends HTMLElement {
|
|
128
|
+
manager = null;
|
|
129
|
+
container;
|
|
130
|
+
constructor() {
|
|
131
|
+
super();
|
|
132
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
133
|
+
shadow.innerHTML = STYLES + `<div class="container"><span class="empty">No devices</span></div>`;
|
|
134
|
+
this.container = shadow.querySelector(".container");
|
|
135
|
+
}
|
|
136
|
+
connectedCallback() {
|
|
137
|
+
onManagerReady((manager) => {
|
|
138
|
+
this.manager = manager;
|
|
139
|
+
manager.on("deviceStatus", (event, device) => {
|
|
140
|
+
if (event === "connected") this.addDevice(device);
|
|
141
|
+
else this.removeDevice(device);
|
|
142
|
+
});
|
|
143
|
+
manager.on("stateChange", (state) => {
|
|
144
|
+
if (state === "connected") {
|
|
145
|
+
manager.fetchDeviceInfo().then((devices) => devices.forEach((d) => this.addDevice(d)));
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
addDevice(device) {
|
|
151
|
+
if (this.shadowRoot.getElementById(`dev-${device.id}`)) return;
|
|
152
|
+
const empty = this.container.querySelector(".empty");
|
|
153
|
+
if (empty) empty.remove();
|
|
154
|
+
const mgr = this.manager;
|
|
155
|
+
const cfg = mgr.getDeviceConfig(device.id);
|
|
156
|
+
const panel = document.createElement("details");
|
|
157
|
+
panel.className = "panel";
|
|
158
|
+
panel.id = `dev-${device.id}`;
|
|
159
|
+
panel.open = true;
|
|
160
|
+
const summary = document.createElement("summary");
|
|
161
|
+
summary.innerHTML = `${device.model ?? device.name}<span class="type">${device.connectionType ?? ""}</span>`;
|
|
162
|
+
panel.appendChild(summary);
|
|
163
|
+
const controls = document.createElement("div");
|
|
164
|
+
controls.className = "controls";
|
|
165
|
+
for (const type of ["translation", "rotation"]) {
|
|
166
|
+
const row = document.createElement("div");
|
|
167
|
+
row.className = "slider-row";
|
|
168
|
+
const val = cfg.sensitivity?.[type] ?? mgr.config.sensitivity[type];
|
|
169
|
+
row.innerHTML = `<label>${type === "translation" ? "Trans" : "Rot"}</label><input type="range" min="0" max="100" value="${Math.round(unmapSlider(val))}"><span>${val.toFixed(4)}</span>`;
|
|
170
|
+
const slider = row.querySelector("input");
|
|
171
|
+
const span = row.querySelector("span");
|
|
172
|
+
slider.addEventListener("input", () => {
|
|
173
|
+
const v = mapSlider(+slider.value);
|
|
174
|
+
span.textContent = v.toFixed(4);
|
|
175
|
+
mgr.updateDeviceConfig(device.id, {
|
|
176
|
+
sensitivity: { ...mgr.getDeviceConfig(device.id).sensitivity, [type]: v }
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
controls.appendChild(row);
|
|
180
|
+
}
|
|
181
|
+
const flipGroup = document.createElement("div");
|
|
182
|
+
flipGroup.className = "flip-group";
|
|
183
|
+
for (const group of [["tx", "ty", "tz"], ["rx", "ry", "rz"]]) {
|
|
184
|
+
const row = document.createElement("div");
|
|
185
|
+
row.className = "flip-row";
|
|
186
|
+
for (const axis of group) {
|
|
187
|
+
const label = document.createElement("label");
|
|
188
|
+
const cb = document.createElement("input");
|
|
189
|
+
cb.type = "checkbox";
|
|
190
|
+
cb.checked = cfg.flip?.[axis] ?? mgr.config.flip[axis];
|
|
191
|
+
cb.addEventListener("change", () => {
|
|
192
|
+
mgr.updateDeviceConfig(device.id, {
|
|
193
|
+
flip: { ...mgr.getDeviceConfig(device.id).flip, [axis]: cb.checked }
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
label.appendChild(cb);
|
|
197
|
+
label.appendChild(document.createTextNode(axis.toUpperCase()));
|
|
198
|
+
row.appendChild(label);
|
|
199
|
+
}
|
|
200
|
+
flipGroup.appendChild(row);
|
|
201
|
+
}
|
|
202
|
+
controls.appendChild(flipGroup);
|
|
203
|
+
const remapGroup = document.createElement("div");
|
|
204
|
+
remapGroup.className = "remap-group";
|
|
205
|
+
const actionMap = cfg.actionMap ?? mgr.config.actionMap;
|
|
206
|
+
for (const action of AXES) {
|
|
207
|
+
const row = document.createElement("div");
|
|
208
|
+
row.className = "remap-row";
|
|
209
|
+
row.innerHTML = `<label>${action.toUpperCase()}</label>`;
|
|
210
|
+
const sel = document.createElement("select");
|
|
211
|
+
for (const src of AXES) {
|
|
212
|
+
const opt = document.createElement("option");
|
|
213
|
+
opt.value = src;
|
|
214
|
+
opt.textContent = src.toUpperCase();
|
|
215
|
+
if (actionMap[action]?.source === src) opt.selected = true;
|
|
216
|
+
sel.appendChild(opt);
|
|
217
|
+
}
|
|
218
|
+
sel.addEventListener("change", () => {
|
|
219
|
+
const current = mgr.getDeviceConfig(device.id).actionMap ?? { ...chunkLDSDVYCV_cjs.DEFAULT_ACTION_MAP };
|
|
220
|
+
current[action] = { ...current[action], source: sel.value };
|
|
221
|
+
mgr.updateDeviceConfig(device.id, { actionMap: current });
|
|
222
|
+
});
|
|
223
|
+
row.appendChild(sel);
|
|
224
|
+
remapGroup.appendChild(row);
|
|
225
|
+
}
|
|
226
|
+
controls.appendChild(remapGroup);
|
|
227
|
+
panel.appendChild(controls);
|
|
228
|
+
this.container.appendChild(panel);
|
|
229
|
+
}
|
|
230
|
+
removeDevice(device) {
|
|
231
|
+
this.shadowRoot.getElementById(`dev-${device.id}`)?.remove();
|
|
232
|
+
if (this.container.children.length === 0) {
|
|
233
|
+
this.container.innerHTML = `<span class="empty">No devices</span>`;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
customElements.define("satmouse-devices", SatMouseDevices);
|
|
238
|
+
|
|
239
|
+
// src/elements/satmouse-debug.ts
|
|
240
|
+
var TEMPLATE2 = `
|
|
241
|
+
<style>
|
|
242
|
+
:host { display: block; font-family: monospace; font-size: 12px; }
|
|
243
|
+
.row { display: flex; justify-content: space-between; padding: 2px 0; }
|
|
244
|
+
.label { color: #7f8c8d; font-weight: 600; width: 28px; }
|
|
245
|
+
.value { color: #3498db; text-align: right; min-width: 50px; }
|
|
246
|
+
.meta { color: #7f8c8d; font-size: 11px; padding: 2px 0; }
|
|
247
|
+
</style>
|
|
248
|
+
<div class="meta"><span class="state">Disconnected</span> \xB7 <span class="protocol"></span> \xB7 <span class="fps">0</span> fps</div>
|
|
249
|
+
<div class="row"><span class="label">TX</span><span class="value" id="tx">0</span></div>
|
|
250
|
+
<div class="row"><span class="label">TY</span><span class="value" id="ty">0</span></div>
|
|
251
|
+
<div class="row"><span class="label">TZ</span><span class="value" id="tz">0</span></div>
|
|
252
|
+
<div class="row"><span class="label">RX</span><span class="value" id="rx">0</span></div>
|
|
253
|
+
<div class="row"><span class="label">RY</span><span class="value" id="ry">0</span></div>
|
|
254
|
+
<div class="row"><span class="label">RZ</span><span class="value" id="rz">0</span></div>
|
|
255
|
+
`;
|
|
256
|
+
var SatMouseDebug = class extends HTMLElement {
|
|
257
|
+
els = {};
|
|
258
|
+
frameCount = 0;
|
|
259
|
+
constructor() {
|
|
260
|
+
super();
|
|
261
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
262
|
+
shadow.innerHTML = TEMPLATE2;
|
|
263
|
+
for (const id of ["tx", "ty", "tz", "rx", "ry", "rz"]) {
|
|
264
|
+
this.els[id] = shadow.getElementById(id);
|
|
265
|
+
}
|
|
266
|
+
this.els.state = shadow.querySelector(".state");
|
|
267
|
+
this.els.protocol = shadow.querySelector(".protocol");
|
|
268
|
+
this.els.fps = shadow.querySelector(".fps");
|
|
269
|
+
}
|
|
270
|
+
connectedCallback() {
|
|
271
|
+
onManagerReady((manager) => this.bind(manager));
|
|
272
|
+
}
|
|
273
|
+
bind(manager) {
|
|
274
|
+
manager.on("rawSpatialData", (data) => {
|
|
275
|
+
this.frameCount++;
|
|
276
|
+
this.els.tx.textContent = String(Math.round(data.translation.x));
|
|
277
|
+
this.els.ty.textContent = String(Math.round(data.translation.y));
|
|
278
|
+
this.els.tz.textContent = String(Math.round(data.translation.z));
|
|
279
|
+
this.els.rx.textContent = String(Math.round(data.rotation.x));
|
|
280
|
+
this.els.ry.textContent = String(Math.round(data.rotation.y));
|
|
281
|
+
this.els.rz.textContent = String(Math.round(data.rotation.z));
|
|
282
|
+
});
|
|
283
|
+
manager.on("stateChange", (state, protocol) => {
|
|
284
|
+
this.els.state.textContent = state;
|
|
285
|
+
this.els.protocol.textContent = protocol !== "none" ? protocol : "";
|
|
286
|
+
});
|
|
287
|
+
setInterval(() => {
|
|
288
|
+
this.els.fps.textContent = String(this.frameCount);
|
|
289
|
+
this.frameCount = 0;
|
|
290
|
+
}, 1e3);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
customElements.define("satmouse-debug", SatMouseDebug);
|
|
294
|
+
|
|
295
|
+
exports.SatMouseDebug = SatMouseDebug;
|
|
296
|
+
exports.SatMouseDevices = SatMouseDevices;
|
|
297
|
+
exports.SatMouseStatus = SatMouseStatus;
|
|
298
|
+
exports.getManager = getManager;
|
|
299
|
+
exports.registerSatMouse = registerSatMouse;
|
|
300
|
+
//# sourceMappingURL=index.cjs.map
|
|
301
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/elements/registry.ts","../../src/elements/satmouse-status.ts","../../src/elements/satmouse-devices.ts","../../src/elements/satmouse-debug.ts"],"names":["DEFAULT_ACTION_MAP","TEMPLATE"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { InputManager } from \"../utils/input-manager.js\";\n\n/**\n * Global registry for SatMouse Web Components.\n *\n * Usage:\n * import { registerSatMouse } from \"@kelnishi/satmouse-client/elements\";\n * registerSatMouse(manager);\n * // All <satmouse-*> elements auto-connect to this manager\n */\n\nlet globalManager: InputManager | null = null;\nconst listeners = new Set<(m: InputManager) => void>();\n\nexport function registerSatMouse(manager: InputManager): void {\n globalManager = manager;\n for (const fn of listeners) fn(manager);\n listeners.clear();\n}\n\nexport function getManager(): InputManager | null {\n return globalManager;\n}\n\nexport function onManagerReady(fn: (m: InputManager) => void): void {\n if (globalManager) fn(globalManager);\n else listeners.add(fn);\n}\n","import { onManagerReady } from \"./registry.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { ConnectionState, TransportProtocol } from \"../core/types.js\";\n\nconst TEMPLATE = `\n<style>\n :host { display: inline-flex; align-items: center; gap: 8px; font-family: inherit; font-size: 13px; }\n .dot { width: 8px; height: 8px; border-radius: 50%; background: #e74c3c; transition: background 0.3s; }\n .dot[data-state=\"connected\"] { background: #2ecc71; }\n .dot[data-state=\"connecting\"] { background: #f39c12; }\n .dot[data-state=\"failed\"] { background: #e74c3c; }\n .protocol { color: #7f8c8d; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }\n .launch { padding: 4px 12px; background: #2980b9; color: #fff; border-radius: 4px; font-size: 11px;\n text-decoration: none; cursor: pointer; border: none; font-family: inherit; display: none; }\n .launch:hover { background: #3498db; }\n</style>\n<span class=\"dot\"></span>\n<span class=\"text\">Disconnected</span>\n<span class=\"protocol\"></span>\n<button class=\"launch\">Launch SatMouse</button>\n`;\n\nexport class SatMouseStatus extends HTMLElement {\n private dot!: HTMLElement;\n private text!: HTMLElement;\n private proto!: HTMLElement;\n private launch!: HTMLButtonElement;\n private disconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = TEMPLATE;\n this.dot = shadow.querySelector(\".dot\")!;\n this.text = shadow.querySelector(\".text\")!;\n this.proto = shadow.querySelector(\".protocol\")!;\n this.launch = shadow.querySelector(\".launch\")!;\n\n this.launch.addEventListener(\"click\", () => {\n // Try the URL scheme — if installed, the OS opens the app\n window.location.href = \"satmouse://launch\";\n // If we're still here after 1s, the scheme wasn't handled\n setTimeout(() => {\n if (!document.hidden) {\n if (confirm(\"SatMouse doesn't appear to be installed. Go to the download page?\")) {\n window.open(\"https://github.com/kelnishi/SatMouse/releases/latest\", \"_blank\", \"noopener\");\n }\n }\n }, 1000);\n });\n }\n\n connectedCallback() {\n // Show launch button if still disconnected after 3s (covers cold page load)\n this.disconnectTimer = setTimeout(() => { this.launch.style.display = \"inline-block\"; }, 3000);\n onManagerReady((manager) => this.bind(manager));\n }\n\n private bind(manager: InputManager): void {\n manager.on(\"stateChange\", (state: ConnectionState, protocol: TransportProtocol) => {\n this.dot.dataset.state = state;\n this.proto.textContent = protocol !== \"none\" ? protocol : \"\";\n\n if (this.disconnectTimer) { clearTimeout(this.disconnectTimer); this.disconnectTimer = null; }\n\n if (state === \"connected\") {\n this.text.textContent = \"Connected\";\n this.launch.style.display = \"none\";\n } else if (state === \"connecting\") {\n this.text.textContent = \"Connecting...\";\n this.launch.style.display = \"none\";\n } else if (state === \"failed\") {\n this.text.textContent = \"Not running\";\n this.launch.style.display = \"inline-block\";\n } else {\n this.text.textContent = \"Disconnected\";\n this.launch.style.display = \"none\";\n }\n });\n }\n}\n\ncustomElements.define(\"satmouse-status\", SatMouseStatus);\n","import { onManagerReady } from \"./registry.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { DeviceInfo } from \"../core/types.js\";\nimport type { InputAxis } from \"../utils/action-map.js\";\nimport { DEFAULT_ACTION_MAP } from \"../utils/action-map.js\";\n\nconst AXES: InputAxis[] = [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\"];\n\nconst STYLES = `\n<style>\n :host { display: block; font-family: inherit; font-size: 12px; }\n .panel { background: #0f3460; border: 1px solid #1a4a8a; border-radius: 6px; padding: 10px; margin-bottom: 8px; }\n summary { cursor: pointer; font-weight: 600; color: #e0e0e0; font-size: 13px; }\n .type { font-size: 10px; color: #7f8c8d; text-transform: uppercase; margin-left: 6px; }\n .controls { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }\n .slider-row { display: flex; align-items: center; gap: 6px; }\n .slider-row label { color: #7f8c8d; font-weight: 600; width: 38px; flex-shrink: 0; }\n .slider-row input[type=\"range\"] { flex: 1; min-width: 0; height: 4px; accent-color: #3498db; }\n .slider-row span { color: #7f8c8d; font-family: monospace; font-size: 10px; min-width: 44px; text-align: right; }\n .flip-group { display: flex; flex-direction: column; gap: 4px; }\n .flip-row { display: flex; gap: 8px; }\n .flip-row label { display: flex; align-items: center; gap: 2px; color: #7f8c8d; min-width: 36px; }\n .flip-row input { accent-color: #e74c3c; }\n .remap-group { display: grid; grid-template-columns: 1fr 1fr; gap: 3px 8px; }\n .remap-row { display: flex; gap: 4px; align-items: center; }\n .remap-row label { color: #7f8c8d; width: 24px; flex-shrink: 0; }\n .remap-row select { background: #16213e; color: #e0e0e0; border: 1px solid #1a4a8a; border-radius: 3px;\n font-size: 11px; padding: 1px 4px; flex: 1; min-width: 0; }\n .empty { color: #7f8c8d; font-style: italic; }\n</style>\n`;\n\nfunction mapSlider(v: number): number { return 0.0001 * Math.pow(500, v / 100); }\nfunction unmapSlider(v: number): number { return (100 * Math.log(v / 0.0001)) / Math.log(500); }\n\nexport class SatMouseDevices extends HTMLElement {\n private manager: InputManager | null = null;\n private container!: HTMLElement;\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = STYLES + `<div class=\"container\"><span class=\"empty\">No devices</span></div>`;\n this.container = shadow.querySelector(\".container\")!;\n }\n\n connectedCallback() {\n onManagerReady((manager) => {\n this.manager = manager;\n manager.on(\"deviceStatus\", (event, device) => {\n if (event === \"connected\") this.addDevice(device);\n else this.removeDevice(device);\n });\n manager.on(\"stateChange\", (state) => {\n if (state === \"connected\") {\n manager.fetchDeviceInfo().then((devices) => devices.forEach((d) => this.addDevice(d)));\n }\n });\n });\n }\n\n private addDevice(device: DeviceInfo): void {\n if (this.shadowRoot!.getElementById(`dev-${device.id}`)) return;\n const empty = this.container.querySelector(\".empty\");\n if (empty) empty.remove();\n\n const mgr = this.manager!;\n const cfg = mgr.getDeviceConfig(device.id);\n\n const panel = document.createElement(\"details\");\n panel.className = \"panel\";\n panel.id = `dev-${device.id}`;\n panel.open = true;\n\n const summary = document.createElement(\"summary\");\n summary.innerHTML = `${device.model ?? device.name}<span class=\"type\">${device.connectionType ?? \"\"}</span>`;\n panel.appendChild(summary);\n\n const controls = document.createElement(\"div\");\n controls.className = \"controls\";\n\n // Sensitivity sliders\n for (const type of [\"translation\", \"rotation\"] as const) {\n const row = document.createElement(\"div\");\n row.className = \"slider-row\";\n const val = cfg.sensitivity?.[type] ?? mgr.config.sensitivity[type];\n row.innerHTML = `<label>${type === \"translation\" ? \"Trans\" : \"Rot\"}</label>` +\n `<input type=\"range\" min=\"0\" max=\"100\" value=\"${Math.round(unmapSlider(val))}\">` +\n `<span>${val.toFixed(4)}</span>`;\n const slider = row.querySelector(\"input\")! as HTMLInputElement;\n const span = row.querySelector(\"span\")!;\n slider.addEventListener(\"input\", () => {\n const v = mapSlider(+slider.value);\n span.textContent = v.toFixed(4);\n mgr.updateDeviceConfig(device.id, {\n sensitivity: { ...mgr.getDeviceConfig(device.id).sensitivity, [type]: v },\n });\n });\n controls.appendChild(row);\n }\n\n // Flip checkboxes\n const flipGroup = document.createElement(\"div\");\n flipGroup.className = \"flip-group\";\n for (const group of [[\"tx\", \"ty\", \"tz\"], [\"rx\", \"ry\", \"rz\"]] as InputAxis[][]) {\n const row = document.createElement(\"div\");\n row.className = \"flip-row\";\n for (const axis of group) {\n const label = document.createElement(\"label\");\n const cb = document.createElement(\"input\");\n cb.type = \"checkbox\";\n cb.checked = cfg.flip?.[axis] ?? mgr.config.flip[axis];\n cb.addEventListener(\"change\", () => {\n mgr.updateDeviceConfig(device.id, {\n flip: { ...mgr.getDeviceConfig(device.id).flip, [axis]: cb.checked },\n });\n });\n label.appendChild(cb);\n label.appendChild(document.createTextNode(axis.toUpperCase()));\n row.appendChild(label);\n }\n flipGroup.appendChild(row);\n }\n controls.appendChild(flipGroup);\n\n // Axis remap\n const remapGroup = document.createElement(\"div\");\n remapGroup.className = \"remap-group\";\n const actionMap = cfg.actionMap ?? mgr.config.actionMap;\n for (const action of AXES) {\n const row = document.createElement(\"div\");\n row.className = \"remap-row\";\n row.innerHTML = `<label>${action.toUpperCase()}</label>`;\n const sel = document.createElement(\"select\");\n for (const src of AXES) {\n const opt = document.createElement(\"option\");\n opt.value = src;\n opt.textContent = src.toUpperCase();\n if (actionMap[action]?.source === src) opt.selected = true;\n sel.appendChild(opt);\n }\n sel.addEventListener(\"change\", () => {\n const current = mgr.getDeviceConfig(device.id).actionMap ?? { ...DEFAULT_ACTION_MAP };\n current[action] = { ...current[action], source: sel.value as InputAxis };\n mgr.updateDeviceConfig(device.id, { actionMap: current });\n });\n row.appendChild(sel);\n remapGroup.appendChild(row);\n }\n controls.appendChild(remapGroup);\n\n panel.appendChild(controls);\n this.container.appendChild(panel);\n }\n\n private removeDevice(device: DeviceInfo): void {\n this.shadowRoot!.getElementById(`dev-${device.id}`)?.remove();\n if (this.container.children.length === 0) {\n this.container.innerHTML = `<span class=\"empty\">No devices</span>`;\n }\n }\n}\n\ncustomElements.define(\"satmouse-devices\", SatMouseDevices);\n","import { onManagerReady } from \"./registry.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { SpatialData, ConnectionState, TransportProtocol } from \"../core/types.js\";\n\nconst TEMPLATE = `\n<style>\n :host { display: block; font-family: monospace; font-size: 12px; }\n .row { display: flex; justify-content: space-between; padding: 2px 0; }\n .label { color: #7f8c8d; font-weight: 600; width: 28px; }\n .value { color: #3498db; text-align: right; min-width: 50px; }\n .meta { color: #7f8c8d; font-size: 11px; padding: 2px 0; }\n</style>\n<div class=\"meta\"><span class=\"state\">Disconnected</span> · <span class=\"protocol\"></span> · <span class=\"fps\">0</span> fps</div>\n<div class=\"row\"><span class=\"label\">TX</span><span class=\"value\" id=\"tx\">0</span></div>\n<div class=\"row\"><span class=\"label\">TY</span><span class=\"value\" id=\"ty\">0</span></div>\n<div class=\"row\"><span class=\"label\">TZ</span><span class=\"value\" id=\"tz\">0</span></div>\n<div class=\"row\"><span class=\"label\">RX</span><span class=\"value\" id=\"rx\">0</span></div>\n<div class=\"row\"><span class=\"label\">RY</span><span class=\"value\" id=\"ry\">0</span></div>\n<div class=\"row\"><span class=\"label\">RZ</span><span class=\"value\" id=\"rz\">0</span></div>\n`;\n\nexport class SatMouseDebug extends HTMLElement {\n private els: Record<string, HTMLElement> = {};\n private frameCount = 0;\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = TEMPLATE;\n for (const id of [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\"]) {\n this.els[id] = shadow.getElementById(id)!;\n }\n this.els.state = shadow.querySelector(\".state\")!;\n this.els.protocol = shadow.querySelector(\".protocol\")!;\n this.els.fps = shadow.querySelector(\".fps\")!;\n }\n\n connectedCallback() {\n onManagerReady((manager) => this.bind(manager));\n }\n\n private bind(manager: InputManager): void {\n manager.on(\"rawSpatialData\", (data: SpatialData) => {\n this.frameCount++;\n this.els.tx.textContent = String(Math.round(data.translation.x));\n this.els.ty.textContent = String(Math.round(data.translation.y));\n this.els.tz.textContent = String(Math.round(data.translation.z));\n this.els.rx.textContent = String(Math.round(data.rotation.x));\n this.els.ry.textContent = String(Math.round(data.rotation.y));\n this.els.rz.textContent = String(Math.round(data.rotation.z));\n });\n\n manager.on(\"stateChange\", (state: ConnectionState, protocol: TransportProtocol) => {\n this.els.state.textContent = state;\n this.els.protocol.textContent = protocol !== \"none\" ? protocol : \"\";\n });\n\n setInterval(() => {\n this.els.fps.textContent = String(this.frameCount);\n this.frameCount = 0;\n }, 1000);\n }\n}\n\ncustomElements.define(\"satmouse-debug\", SatMouseDebug);\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InputManager } from '../utils/index.cjs';
|
|
2
|
+
import '../connection-5KQFvHoJ.cjs';
|
|
3
|
+
|
|
4
|
+
declare class SatMouseStatus extends HTMLElement {
|
|
5
|
+
private dot;
|
|
6
|
+
private text;
|
|
7
|
+
private proto;
|
|
8
|
+
private launch;
|
|
9
|
+
private disconnectTimer;
|
|
10
|
+
constructor();
|
|
11
|
+
connectedCallback(): void;
|
|
12
|
+
private bind;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare class SatMouseDevices extends HTMLElement {
|
|
16
|
+
private manager;
|
|
17
|
+
private container;
|
|
18
|
+
constructor();
|
|
19
|
+
connectedCallback(): void;
|
|
20
|
+
private addDevice;
|
|
21
|
+
private removeDevice;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare class SatMouseDebug extends HTMLElement {
|
|
25
|
+
private els;
|
|
26
|
+
private frameCount;
|
|
27
|
+
constructor();
|
|
28
|
+
connectedCallback(): void;
|
|
29
|
+
private bind;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare function registerSatMouse(manager: InputManager): void;
|
|
33
|
+
declare function getManager(): InputManager | null;
|
|
34
|
+
|
|
35
|
+
export { SatMouseDebug, SatMouseDevices, SatMouseStatus, getManager, registerSatMouse };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InputManager } from '../utils/index.js';
|
|
2
|
+
import '../connection-5KQFvHoJ.js';
|
|
3
|
+
|
|
4
|
+
declare class SatMouseStatus extends HTMLElement {
|
|
5
|
+
private dot;
|
|
6
|
+
private text;
|
|
7
|
+
private proto;
|
|
8
|
+
private launch;
|
|
9
|
+
private disconnectTimer;
|
|
10
|
+
constructor();
|
|
11
|
+
connectedCallback(): void;
|
|
12
|
+
private bind;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare class SatMouseDevices extends HTMLElement {
|
|
16
|
+
private manager;
|
|
17
|
+
private container;
|
|
18
|
+
constructor();
|
|
19
|
+
connectedCallback(): void;
|
|
20
|
+
private addDevice;
|
|
21
|
+
private removeDevice;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare class SatMouseDebug extends HTMLElement {
|
|
25
|
+
private els;
|
|
26
|
+
private frameCount;
|
|
27
|
+
constructor();
|
|
28
|
+
connectedCallback(): void;
|
|
29
|
+
private bind;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare function registerSatMouse(manager: InputManager): void;
|
|
33
|
+
declare function getManager(): InputManager | null;
|
|
34
|
+
|
|
35
|
+
export { SatMouseDebug, SatMouseDevices, SatMouseStatus, getManager, registerSatMouse };
|