@ovok/native 1.16.1-dev.2099 → 1.16.1-dev.2101

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.
Files changed (73) hide show
  1. package/lib/commonjs/modules/next/bluetooth/channel.js +89 -0
  2. package/lib/commonjs/modules/next/bluetooth/channel.js.map +1 -0
  3. package/lib/commonjs/modules/next/bluetooth/driver.js +48 -0
  4. package/lib/commonjs/modules/next/bluetooth/driver.js.map +1 -0
  5. package/lib/commonjs/modules/next/bluetooth/drivers.js +20 -0
  6. package/lib/commonjs/modules/next/bluetooth/drivers.js.map +1 -0
  7. package/lib/commonjs/modules/next/bluetooth/index.js +65 -0
  8. package/lib/commonjs/modules/next/bluetooth/index.js.map +1 -0
  9. package/lib/commonjs/modules/next/bluetooth/legacy-driver.js +55 -0
  10. package/lib/commonjs/modules/next/bluetooth/legacy-driver.js.map +1 -0
  11. package/lib/commonjs/modules/next/bluetooth/link.js +105 -0
  12. package/lib/commonjs/modules/next/bluetooth/link.js.map +1 -0
  13. package/lib/commonjs/modules/next/bluetooth/result-policy.js +69 -0
  14. package/lib/commonjs/modules/next/bluetooth/result-policy.js.map +1 -0
  15. package/lib/commonjs/modules/next/bluetooth/sig-profiles.js +164 -0
  16. package/lib/commonjs/modules/next/bluetooth/sig-profiles.js.map +1 -0
  17. package/lib/commonjs/modules/next/bluetooth/sig-values.js +46 -0
  18. package/lib/commonjs/modules/next/bluetooth/sig-values.js.map +1 -0
  19. package/lib/module/modules/next/bluetooth/channel.js +85 -0
  20. package/lib/module/modules/next/bluetooth/channel.js.map +1 -0
  21. package/lib/module/modules/next/bluetooth/driver.js +45 -0
  22. package/lib/module/modules/next/bluetooth/driver.js.map +1 -0
  23. package/lib/module/modules/next/bluetooth/drivers.js +17 -0
  24. package/lib/module/modules/next/bluetooth/drivers.js.map +1 -0
  25. package/lib/module/modules/next/bluetooth/index.js +8 -0
  26. package/lib/module/modules/next/bluetooth/index.js.map +1 -0
  27. package/lib/module/modules/next/bluetooth/legacy-driver.js +51 -0
  28. package/lib/module/modules/next/bluetooth/legacy-driver.js.map +1 -0
  29. package/lib/module/modules/next/bluetooth/link.js +103 -0
  30. package/lib/module/modules/next/bluetooth/link.js.map +1 -0
  31. package/lib/module/modules/next/bluetooth/result-policy.js +61 -0
  32. package/lib/module/modules/next/bluetooth/result-policy.js.map +1 -0
  33. package/lib/module/modules/next/bluetooth/sig-profiles.js +156 -0
  34. package/lib/module/modules/next/bluetooth/sig-profiles.js.map +1 -0
  35. package/lib/module/modules/next/bluetooth/sig-values.js +38 -0
  36. package/lib/module/modules/next/bluetooth/sig-values.js.map +1 -0
  37. package/lib/typescript/commonjs/src/modules/next/bluetooth/channel.d.ts +19 -0
  38. package/lib/typescript/commonjs/src/modules/next/bluetooth/channel.d.ts.map +1 -0
  39. package/lib/typescript/commonjs/src/modules/next/bluetooth/driver.d.ts +32 -0
  40. package/lib/typescript/commonjs/src/modules/next/bluetooth/driver.d.ts.map +1 -0
  41. package/lib/typescript/commonjs/src/modules/next/bluetooth/drivers.d.ts +7 -0
  42. package/lib/typescript/commonjs/src/modules/next/bluetooth/drivers.d.ts.map +1 -0
  43. package/lib/typescript/commonjs/src/modules/next/bluetooth/index.d.ts +9 -0
  44. package/lib/typescript/commonjs/src/modules/next/bluetooth/index.d.ts.map +1 -0
  45. package/lib/typescript/commonjs/src/modules/next/bluetooth/legacy-driver.d.ts +8 -0
  46. package/lib/typescript/commonjs/src/modules/next/bluetooth/legacy-driver.d.ts.map +1 -0
  47. package/lib/typescript/commonjs/src/modules/next/bluetooth/link.d.ts +13 -0
  48. package/lib/typescript/commonjs/src/modules/next/bluetooth/link.d.ts.map +1 -0
  49. package/lib/typescript/commonjs/src/modules/next/bluetooth/result-policy.d.ts +14 -0
  50. package/lib/typescript/commonjs/src/modules/next/bluetooth/result-policy.d.ts.map +1 -0
  51. package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-profiles.d.ts +16 -0
  52. package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-profiles.d.ts.map +1 -0
  53. package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-values.d.ts +15 -0
  54. package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-values.d.ts.map +1 -0
  55. package/lib/typescript/module/src/modules/next/bluetooth/channel.d.ts +19 -0
  56. package/lib/typescript/module/src/modules/next/bluetooth/channel.d.ts.map +1 -0
  57. package/lib/typescript/module/src/modules/next/bluetooth/driver.d.ts +32 -0
  58. package/lib/typescript/module/src/modules/next/bluetooth/driver.d.ts.map +1 -0
  59. package/lib/typescript/module/src/modules/next/bluetooth/drivers.d.ts +7 -0
  60. package/lib/typescript/module/src/modules/next/bluetooth/drivers.d.ts.map +1 -0
  61. package/lib/typescript/module/src/modules/next/bluetooth/index.d.ts +9 -0
  62. package/lib/typescript/module/src/modules/next/bluetooth/index.d.ts.map +1 -0
  63. package/lib/typescript/module/src/modules/next/bluetooth/legacy-driver.d.ts +8 -0
  64. package/lib/typescript/module/src/modules/next/bluetooth/legacy-driver.d.ts.map +1 -0
  65. package/lib/typescript/module/src/modules/next/bluetooth/link.d.ts +13 -0
  66. package/lib/typescript/module/src/modules/next/bluetooth/link.d.ts.map +1 -0
  67. package/lib/typescript/module/src/modules/next/bluetooth/result-policy.d.ts +14 -0
  68. package/lib/typescript/module/src/modules/next/bluetooth/result-policy.d.ts.map +1 -0
  69. package/lib/typescript/module/src/modules/next/bluetooth/sig-profiles.d.ts +16 -0
  70. package/lib/typescript/module/src/modules/next/bluetooth/sig-profiles.d.ts.map +1 -0
  71. package/lib/typescript/module/src/modules/next/bluetooth/sig-values.d.ts +15 -0
  72. package/lib/typescript/module/src/modules/next/bluetooth/sig-values.d.ts.map +1 -0
  73. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_next","require","_bloodPressureStates","_sigUuid","_sigValues","KPA_TO_MMHG","KG_PER_SI_COUNT","KG_PER_IMPERIAL_COUNT","WEIGHT_UNSUCCESSFUL","DATE_TIME_BYTES","BP_KPA","BP_TIMESTAMP","BP_PULSE","BP_USER","BP_STATUS","BP_BODY_MOVEMENT","BP_LOOSE_CUFF","BP_IRREGULAR_PULSE","TEMPERATURE_FAHRENHEIT","TEMPERATURE_TIMESTAMP","WEIGHT_IMPERIAL","WEIGHT_TIMESTAMP","PLX_TIMESTAMP","HEART_RATE_UINT16","HEART_RATE_CONTACT_BITS","HEART_RATE_NO_CONTACT","bloodPressureStatus","status","BloodPressureStates","DISTURB_DETECTED","LOOSE_SLEEVE","REGULAR","bloodPressureExtras","view","flags","offset","extras","recordedAt","dateTimeAt","heartRate","sfloatAt","user","getUint8","memorySlot","undefined","getUint16","irregularHeartbeat","bloodPressure","pressure","value","roundTo","systolic","diastolic","mean","map","reading","measurementTypeKey","MeasurementTypeKey","withDefined","meanArterialPressure","exports","temperature","floatAt","bodyTemp","bodyWeight","counts","pulseOximetry","bloodOxygen","pulseRate","bloodOxygenPulseRate","subscribed","service","characteristic","decode","link","frame","subscribe","sigUuid","decodeFrame","SIG_PROTOCOLS","Map"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/sig-profiles.ts"],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AASA,IAAAC,oBAAA,GAAAD,OAAA;AACA,IAAAE,QAAA,GAAAF,OAAA;AAGA,IAAAG,UAAA,GAAAH,OAAA;AAEA,MAAMI,WAAW,GAAG,OAAO;AAC3B,MAAMC,eAAe,GAAG,KAAK;AAC7B,MAAMC,qBAAqB,GAAG,IAAI,GAAG,UAAU;AAC/C,MAAMC,mBAAmB,GAAG,MAAM;AAClC,MAAMC,eAAe,GAAG,CAAC;AAEzB,MAAMC,MAAM,GAAG,IAAI;AACnB,MAAMC,YAAY,GAAG,IAAI;AACzB,MAAMC,QAAQ,GAAG,IAAI;AACrB,MAAMC,OAAO,GAAG,IAAI;AACpB,MAAMC,SAAS,GAAG,IAAI;AACtB,MAAMC,gBAAgB,GAAG,IAAI;AAC7B,MAAMC,aAAa,GAAG,IAAI;AAC1B,MAAMC,kBAAkB,GAAG,IAAI;AAE/B,MAAMC,sBAAsB,GAAG,IAAI;AACnC,MAAMC,qBAAqB,GAAG,IAAI;AAClC,MAAMC,eAAe,GAAG,IAAI;AAC5B,MAAMC,gBAAgB,GAAG,IAAI;AAC7B,MAAMC,aAAa,GAAG,IAAI;AAC1B,MAAMC,iBAAiB,GAAG,IAAI;AAC9B,MAAMC,uBAAuB,GAAG,IAAI;AACpC,MAAMC,qBAAqB,GAAG,IAAI;;AAElC;;AAGA,MAAMC,mBAAmB,GAAIC,MAAc,IAA0B;EACnE,IAAIA,MAAM,GAAGZ,gBAAgB,EAAE;IAC7B,OAAOa,wCAAmB,CAACC,gBAAgB;EAC7C;EAEA,OAAOF,MAAM,GAAGX,aAAa,GAAGY,wCAAmB,CAACE,YAAY,GAAGF,wCAAmB,CAACG,OAAO;AAChG,CAAC;;AAED;AACA,MAAMC,mBAAmB,GAAGA,CAACC,IAAc,EAAEC,KAAa,KAAgC;EACxF,IAAIC,MAAM,GAAG,CAAC;EACd,MAAMC,MAAiC,GAAG,CAAC,CAAC;EAE5C,IAAIF,KAAK,GAAGvB,YAAY,EAAE;IACxByB,MAAM,CAACC,UAAU,GAAG,IAAAC,qBAAU,EAACL,IAAI,EAAEE,MAAM,CAAC;IAC5CA,MAAM,IAAI1B,eAAe;EAC3B;EACA,IAAIyB,KAAK,GAAGtB,QAAQ,EAAE;IACpBwB,MAAM,CAACG,SAAS,GAAG,IAAAC,mBAAQ,EAACP,IAAI,EAAEE,MAAM,CAAC;IACzCA,MAAM,IAAI,CAAC;EACb;EACA,IAAID,KAAK,GAAGrB,OAAO,EAAE;IACnB,MAAM4B,IAAI,GAAGR,IAAI,CAACS,QAAQ,CAACP,MAAM,CAAC;IAElCC,MAAM,CAACO,UAAU,GAAGF,IAAI,GAAG,CAAC,GAAGA,IAAI,GAAG,CAAC,GAAGG,SAAS;IACnDT,MAAM,IAAI,CAAC;EACb;EACA,IAAID,KAAK,GAAGpB,SAAS,EAAE;IACrB,MAAMa,MAAM,GAAGM,IAAI,CAACY,SAAS,CAACV,MAAM,EAAE,IAAI,CAAC;IAE3CC,MAAM,CAACT,MAAM,GAAGD,mBAAmB,CAACC,MAAM,CAAC;IAC3CS,MAAM,CAACU,kBAAkB,GAAGnB,MAAM,GAAGV,kBAAkB,GAAG,IAAI,GAAG2B,SAAS;EAC5E;EAEA,OAAOR,MAAM;AACf,CAAC;;AAED;AACA,MAAMW,aAAsB,GAAId,IAAI,IAAK;EACvC,MAAMC,KAAK,GAAGD,IAAI,CAACS,QAAQ,CAAC,CAAC,CAAC;EAC9B,MAAMM,QAAQ,GAAIC,KAAa,IAAMf,KAAK,GAAGxB,MAAM,GAAG,IAAAwC,kBAAO,EAACD,KAAK,GAAG5C,WAAW,EAAE,CAAC,CAAC,GAAG4C,KAAM;EAC9F,MAAM,CAACE,QAAQ,EAAEC,SAAS,EAAEC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAACC,GAAG,CAAEnB,MAAM,IAAK,IAAAK,mBAAQ,EAACP,IAAI,EAAEE,MAAM,CAAC,CAAC;EAErF,IAAIgB,QAAQ,KAAKP,SAAS,IAAIQ,SAAS,KAAKR,SAAS,EAAE;IACrD,OAAOA,SAAS;EAClB;EAEA,MAAMW,OAAyB,GAAG;IAChCC,kBAAkB,EAAEC,wBAAkB,CAACV,aAAa;IACpDI,QAAQ,EAAEH,QAAQ,CAACG,QAAQ,CAAC;IAC5BC,SAAS,EAAEJ,QAAQ,CAACI,SAAS;EAC/B,CAAC;EAED,OAAO,IAAAM,sBAAW,EAACH,OAAO,EAAE;IAC1BI,oBAAoB,EAAEN,IAAI,KAAKT,SAAS,GAAGA,SAAS,GAAGI,QAAQ,CAACK,IAAI,CAAC;IACrE,GAAGrB,mBAAmB,CAACC,IAAI,EAAEC,KAAK;EACpC,CAAC,CAAC;AACJ,CAAC;;AAED;AAAA0B,OAAA,CAAAb,aAAA,GAAAA,aAAA;AACA,MAAMc,WAAoB,GAAI5B,IAAI,IAAK;EACrC,MAAMC,KAAK,GAAGD,IAAI,CAACS,QAAQ,CAAC,CAAC,CAAC;EAC9B,MAAMO,KAAK,GAAG,IAAAa,kBAAO,EAAC7B,IAAI,EAAE,CAAC,CAAC;EAE9B,IAAIgB,KAAK,KAAKL,SAAS,EAAE;IACvB,OAAOA,SAAS;EAClB;EAEA,MAAMW,OAAmC,GAAG;IAC1CC,kBAAkB,EAAEC,wBAAkB,CAACI,WAAW;IAClDE,QAAQ,EAAE7B,KAAK,GAAGhB,sBAAsB,GAAG,IAAAgC,kBAAO,EAAE,CAACD,KAAK,GAAG,EAAE,IAAI,CAAC,GAAI,CAAC,EAAE,CAAC,CAAC,GAAGA;EAClF,CAAC;EAED,OAAOf,KAAK,GAAGf,qBAAqB,GAAG,IAAAuC,sBAAW,EAACH,OAAO,EAAE;IAAElB,UAAU,EAAE,IAAAC,qBAAU,EAACL,IAAI,EAAE,CAAC;EAAE,CAAC,CAAC,GAAGsB,OAAO;AAC5G,CAAC;;AAED;AAAAK,OAAA,CAAAC,WAAA,GAAAA,WAAA;AACA,MAAMG,UAAmB,GAAI/B,IAAI,IAAK;EACpC,MAAMC,KAAK,GAAGD,IAAI,CAACS,QAAQ,CAAC,CAAC,CAAC;EAC9B,MAAMuB,MAAM,GAAGhC,IAAI,CAACY,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC;EAEtC,IAAIoB,MAAM,KAAKzD,mBAAmB,EAAE;IAClC,OAAOoC,SAAS;EAClB;EAEA,MAAMW,OAA8B,GAAG;IACrCC,kBAAkB,EAAEC,wBAAkB,CAACO,UAAU;IACjDA,UAAU,EAAE,IAAAd,kBAAO,EAACe,MAAM,IAAI/B,KAAK,GAAGd,eAAe,GAAGb,qBAAqB,GAAGD,eAAe,CAAC,EAAE,CAAC;EACrG,CAAC;EAED,OAAO4B,KAAK,GAAGb,gBAAgB,GAAG,IAAAqC,sBAAW,EAACH,OAAO,EAAE;IAAElB,UAAU,EAAE,IAAAC,qBAAU,EAACL,IAAI,EAAE,CAAC;EAAE,CAAC,CAAC,GAAGsB,OAAO;AACvG,CAAC;;AAED;AAAAK,OAAA,CAAAI,UAAA,GAAAA,UAAA;AACA,MAAME,aAAsB,GAAIjC,IAAI,IAAK;EACvC,MAAMC,KAAK,GAAGD,IAAI,CAACS,QAAQ,CAAC,CAAC,CAAC;EAC9B,MAAMyB,WAAW,GAAG,IAAA3B,mBAAQ,EAACP,IAAI,EAAE,CAAC,CAAC;EACrC,MAAMmC,SAAS,GAAG,IAAA5B,mBAAQ,EAACP,IAAI,EAAE,CAAC,CAAC;EAEnC,IAAIkC,WAAW,KAAKvB,SAAS,IAAIwB,SAAS,KAAKxB,SAAS,EAAE;IACxD,OAAOA,SAAS;EAClB;EAEA,MAAMW,OAAiC,GAAG;IACxCC,kBAAkB,EAAEC,wBAAkB,CAACY,oBAAoB;IAC3DF,WAAW;IACXC;EACF,CAAC;EAED,OAAOlC,KAAK,GAAGZ,aAAa,GAAG,IAAAoC,sBAAW,EAACH,OAAO,EAAE;IAAElB,UAAU,EAAE,IAAAC,qBAAU,EAACL,IAAI,EAAE,CAAC;EAAE,CAAC,CAAC,GAAGsB,OAAO;AACpG,CAAC;;AAED;AAAAK,OAAA,CAAAM,aAAA,GAAAA,aAAA;AACA,MAAM3B,SAAkB,GAAIN,IAAI,IAAK;EACnC,MAAMC,KAAK,GAAGD,IAAI,CAACS,QAAQ,CAAC,CAAC,CAAC;EAE9B,IAAI,CAACR,KAAK,GAAGV,uBAAuB,MAAMC,qBAAqB,EAAE;IAC/D,OAAOmB,SAAS;EAClB;EAEA,MAAMW,OAA6B,GAAG;IACpCC,kBAAkB,EAAEC,wBAAkB,CAAClB,SAAS;IAChDA,SAAS,EAAEL,KAAK,GAAGX,iBAAiB,GAAGU,IAAI,CAACY,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,GAAGZ,IAAI,CAACS,QAAQ,CAAC,CAAC;EAClF,CAAC;EAED,OAAOa,OAAO;AAChB,CAAC;AAACK,OAAA,CAAArB,SAAA,GAAAA,SAAA;AAEF,MAAM+B,UAAU,GAAGA,CAACC,OAAe,EAAEC,cAAsB,EAAEC,MAAe,KAC1E,iBAAiBC,IAAI,EAAE;EACrB,WAAW,MAAMC,KAAK,IAAID,IAAI,CAACE,SAAS,CAAC,IAAAC,gBAAO,EAACN,OAAO,CAAC,EAAE,IAAAM,gBAAO,EAACL,cAAc,CAAC,CAAC,EAAE;IACnF,MAAMjB,OAAO,GAAG,IAAAuB,sBAAW,EAACL,MAAM,EAAEE,KAAK,CAAC;IAE1C,IAAIpB,OAAO,EAAE;MACX,MAAMA,OAAO;IACf;EACF;AACF,CAAC;;AAEH;AACA,MAAMwB,aAAkD,GAAAnB,OAAA,CAAAmB,aAAA,GAAG,IAAIC,GAAG,CAAC,CACjE,CAAC,yBAAyB,EAAEV,UAAU,CAAC,MAAM,EAAE,MAAM,EAAEvB,aAAa,CAAC,CAAC,EACtE,CAAC,2BAA2B,EAAEuB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAET,WAAW,CAAC,CAAC,EACtE,CAAC,sBAAsB,EAAES,UAAU,CAAC,MAAM,EAAE,MAAM,EAAEN,UAAU,CAAC,CAAC,EAChE,CAAC,kCAAkC,EAAEM,UAAU,CAAC,MAAM,EAAE,MAAM,EAAEJ,aAAa,CAAC,CAAC,EAC/E,CAAC,qBAAqB,EAAEI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE/B,SAAS,CAAC,CAAC,CAC/D,CAAC","ignoreList":[]}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.withDefined = exports.sfloatAt = exports.roundTo = exports.floatAt = exports.decodeFrame = exports.dateTimeAt = void 0;
7
+ var _decodeMedicalFloat = require("../../bt-management/utils/decode-medical-float.js");
8
+ /** Reads one GATT value; undefined when it holds no reading. */
9
+
10
+ const sfloatAt = (view, offset) => (0, _decodeMedicalFloat.decodeMedicalFloat)(view.getUint16(offset, true), 4, 12);
11
+ exports.sfloatAt = sfloatAt;
12
+ const floatAt = (view, offset) => (0, _decodeMedicalFloat.decodeMedicalFloat)(view.getUint32(offset, true), 8, 24);
13
+
14
+ /** The SIG Date Time characteristic as a phone-local date; undefined for unknown or impossible fields. */
15
+ exports.floatAt = floatAt;
16
+ const dateTimeAt = (view, offset) => {
17
+ const fields = [view.getUint16(offset, true), ...[2, 3, 4, 5, 6].map(index => view.getUint8(offset + index))];
18
+ const [year = 0, month = 0, day = 0, hours = 0, minutes = 0, seconds = 0] = fields;
19
+ const date = new Date(year, month - 1, day, hours, minutes, seconds);
20
+ const stored = [date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()];
21
+ return fields.every((field, index) => field === stored[index]) ? date : undefined;
22
+ };
23
+ exports.dateTimeAt = dateTimeAt;
24
+ const roundTo = (value, decimals) => Number(value.toFixed(decimals));
25
+
26
+ /** `reading` plus each of `fields` that has a value. */
27
+ exports.roundTo = roundTo;
28
+ const withDefined = (reading, fields) => ({
29
+ ...reading,
30
+ ...Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined))
31
+ });
32
+
33
+ /** A frame too short for what its flags announce holds no reading. */
34
+ exports.withDefined = withDefined;
35
+ const decodeFrame = (decode, frame) => {
36
+ try {
37
+ return decode(new DataView(frame.buffer, frame.byteOffset, frame.byteLength));
38
+ } catch (error) {
39
+ if (error instanceof RangeError) {
40
+ return undefined;
41
+ }
42
+ throw error;
43
+ }
44
+ };
45
+ exports.decodeFrame = decodeFrame;
46
+ //# sourceMappingURL=sig-values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_decodeMedicalFloat","require","sfloatAt","view","offset","decodeMedicalFloat","getUint16","exports","floatAt","getUint32","dateTimeAt","fields","map","index","getUint8","year","month","day","hours","minutes","seconds","date","Date","stored","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","every","field","undefined","roundTo","value","decimals","Number","toFixed","withDefined","reading","Object","fromEntries","entries","filter","decodeFrame","decode","frame","DataView","buffer","byteOffset","byteLength","error","RangeError"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/sig-values.ts"],"mappings":";;;;;;AAEA,IAAAA,mBAAA,GAAAC,OAAA;AAEA;;AAGA,MAAMC,QAAQ,GAAGA,CAACC,IAAc,EAAEC,MAAc,KAC9C,IAAAC,sCAAkB,EAACF,IAAI,CAACG,SAAS,CAACF,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;AAACG,OAAA,CAAAL,QAAA,GAAAA,QAAA;AAE1D,MAAMM,OAAO,GAAGA,CAACL,IAAc,EAAEC,MAAc,KAC7C,IAAAC,sCAAkB,EAACF,IAAI,CAACM,SAAS,CAACL,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;;AAEzD;AAAAG,OAAA,CAAAC,OAAA,GAAAA,OAAA;AACA,MAAME,UAAU,GAAGA,CAACP,IAAc,EAAEC,MAAc,KAAuB;EACvE,MAAMO,MAAM,GAAG,CAACR,IAAI,CAACG,SAAS,CAACF,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAACQ,GAAG,CAAEC,KAAK,IAAKV,IAAI,CAACW,QAAQ,CAACV,MAAM,GAAGS,KAAK,CAAC,CAAC,CAAC;EAC/G,MAAM,CAACE,IAAI,GAAG,CAAC,EAAEC,KAAK,GAAG,CAAC,EAAEC,GAAG,GAAG,CAAC,EAAEC,KAAK,GAAG,CAAC,EAAEC,OAAO,GAAG,CAAC,EAAEC,OAAO,GAAG,CAAC,CAAC,GAAGT,MAAM;EAClF,MAAMU,IAAI,GAAG,IAAIC,IAAI,CAACP,IAAI,EAAEC,KAAK,GAAG,CAAC,EAAEC,GAAG,EAAEC,KAAK,EAAEC,OAAO,EAAEC,OAAO,CAAC;EACpE,MAAMG,MAAM,GAAG,CAACF,IAAI,CAACG,WAAW,CAAC,CAAC,EAAEH,IAAI,CAACI,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAEJ,IAAI,CAACK,OAAO,CAAC,CAAC,EAAEL,IAAI,CAACM,QAAQ,CAAC,CAAC,EAAEN,IAAI,CAACO,UAAU,CAAC,CAAC,EAAEP,IAAI,CAACQ,UAAU,CAAC,CAAC,CAAC;EAE/H,OAAOlB,MAAM,CAACmB,KAAK,CAAC,CAACC,KAAK,EAAElB,KAAK,KAAKkB,KAAK,KAAKR,MAAM,CAACV,KAAK,CAAC,CAAC,GAAGQ,IAAI,GAAGW,SAAS;AACnF,CAAC;AAACzB,OAAA,CAAAG,UAAA,GAAAA,UAAA;AAEF,MAAMuB,OAAO,GAAGA,CAACC,KAAa,EAAEC,QAAgB,KAAaC,MAAM,CAACF,KAAK,CAACG,OAAO,CAACF,QAAQ,CAAC,CAAC;;AAE5F;AAAA5B,OAAA,CAAA0B,OAAA,GAAAA,OAAA;AACA,MAAMK,WAAW,GAAGA,CAAwBC,OAAU,EAAE5B,MAAkB,MAAS;EACjF,GAAG4B,OAAO;EACV,GAAGC,MAAM,CAACC,WAAW,CAACD,MAAM,CAACE,OAAO,CAAC/B,MAAM,CAAC,CAACgC,MAAM,CAAC,CAAC,GAAGT,KAAK,CAAC,KAAKA,KAAK,KAAKF,SAAS,CAAC;AACzF,CAAC,CAAC;;AAEF;AAAAzB,OAAA,CAAA+B,WAAA,GAAAA,WAAA;AACA,MAAMM,WAAW,GAAGA,CAACC,MAAe,EAAEC,KAAiB,KAA8B;EACnF,IAAI;IACF,OAAOD,MAAM,CAAC,IAAIE,QAAQ,CAACD,KAAK,CAACE,MAAM,EAAEF,KAAK,CAACG,UAAU,EAAEH,KAAK,CAACI,UAAU,CAAC,CAAC;EAC/E,CAAC,CAAC,OAAOC,KAAK,EAAE;IACd,IAAIA,KAAK,YAAYC,UAAU,EAAE;MAC/B,OAAOpB,SAAS;IAClB;IACA,MAAMmB,KAAK;EACb;AACF,CAAC;AAAC5C,OAAA,CAAAqC,WAAA,GAAAA,WAAA","ignoreList":[]}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ const DONE = {
4
+ value: undefined,
5
+ done: true
6
+ };
7
+
8
+ /** Callback-pushed values as an async iterator for one consumer; `onClose` runs once, however it ends. */
9
+ class Channel {
10
+ buffered = [];
11
+ closed = false;
12
+ constructor(onClose = () => {}) {
13
+ this.onClose = onClose;
14
+ }
15
+ push(value) {
16
+ if (this.closed) {
17
+ return;
18
+ }
19
+ const waiter = this.takeWaiter();
20
+ if (waiter) {
21
+ waiter.resolve({
22
+ value,
23
+ done: false
24
+ });
25
+ } else {
26
+ this.buffered.push(value);
27
+ }
28
+ }
29
+ end() {
30
+ if (this.close()) {
31
+ this.takeWaiter()?.resolve(DONE);
32
+ }
33
+ }
34
+ fail(error) {
35
+ if (this.close()) {
36
+ this.failure = {
37
+ error
38
+ };
39
+ this.takeWaiter()?.reject(error);
40
+ }
41
+ }
42
+ next() {
43
+ if (this.buffered.length > 0) {
44
+ return Promise.resolve({
45
+ value: this.buffered.shift(),
46
+ done: false
47
+ });
48
+ }
49
+ if (this.failure) {
50
+ return Promise.reject(this.failure.error);
51
+ }
52
+ if (this.closed) {
53
+ return Promise.resolve(DONE);
54
+ }
55
+ return new Promise((resolve, reject) => {
56
+ this.waiter = {
57
+ resolve,
58
+ reject
59
+ };
60
+ });
61
+ }
62
+ return() {
63
+ this.buffered.length = 0;
64
+ this.end();
65
+ return Promise.resolve(DONE);
66
+ }
67
+ [Symbol.asyncIterator]() {
68
+ return this;
69
+ }
70
+ close() {
71
+ if (this.closed) {
72
+ return false;
73
+ }
74
+ this.closed = true;
75
+ this.onClose();
76
+ return true;
77
+ }
78
+ takeWaiter() {
79
+ const waiter = this.waiter;
80
+ this.waiter = undefined;
81
+ return waiter;
82
+ }
83
+ }
84
+ export { Channel };
85
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DONE","value","undefined","done","Channel","buffered","closed","constructor","onClose","push","waiter","takeWaiter","resolve","end","close","fail","error","failure","reject","next","length","Promise","shift","return","Symbol","asyncIterator"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/channel.ts"],"mappings":";;AAKA,MAAMA,IAAqC,GAAG;EAAEC,KAAK,EAAEC,SAAS;EAAEC,IAAI,EAAE;AAAK,CAAC;;AAE9E;AACA,MAAMC,OAAO,CAAwC;EAClCC,QAAQ,GAAQ,EAAE;EAG3BC,MAAM,GAAG,KAAK;EAEfC,WAAWA,CAAkBC,OAAmB,GAAGA,CAAA,KAAM,CAAC,CAAC,EAAE;IAAA,KAAhCA,OAAmB,GAAnBA,OAAmB;EAAc;EAE9DC,IAAIA,CAACR,KAAQ,EAAQ;IAC1B,IAAI,IAAI,CAACK,MAAM,EAAE;MACf;IACF;IAEA,MAAMI,MAAM,GAAG,IAAI,CAACC,UAAU,CAAC,CAAC;IAEhC,IAAID,MAAM,EAAE;MACVA,MAAM,CAACE,OAAO,CAAC;QAAEX,KAAK;QAAEE,IAAI,EAAE;MAAM,CAAC,CAAC;IACxC,CAAC,MAAM;MACL,IAAI,CAACE,QAAQ,CAACI,IAAI,CAACR,KAAK,CAAC;IAC3B;EACF;EAEOY,GAAGA,CAAA,EAAS;IACjB,IAAI,IAAI,CAACC,KAAK,CAAC,CAAC,EAAE;MAChB,IAAI,CAACH,UAAU,CAAC,CAAC,EAAEC,OAAO,CAACZ,IAAI,CAAC;IAClC;EACF;EAEOe,IAAIA,CAACC,KAAc,EAAQ;IAChC,IAAI,IAAI,CAACF,KAAK,CAAC,CAAC,EAAE;MAChB,IAAI,CAACG,OAAO,GAAG;QAAED;MAAM,CAAC;MACxB,IAAI,CAACL,UAAU,CAAC,CAAC,EAAEO,MAAM,CAACF,KAAK,CAAC;IAClC;EACF;EAEOG,IAAIA,CAAA,EAA+B;IACxC,IAAI,IAAI,CAACd,QAAQ,CAACe,MAAM,GAAG,CAAC,EAAE;MAC5B,OAAOC,OAAO,CAACT,OAAO,CAAC;QAAEX,KAAK,EAAE,IAAI,CAACI,QAAQ,CAACiB,KAAK,CAAC,CAAM;QAAEnB,IAAI,EAAE;MAAM,CAAC,CAAC;IAC5E;IAEA,IAAI,IAAI,CAACc,OAAO,EAAE;MAChB,OAAOI,OAAO,CAACH,MAAM,CAAC,IAAI,CAACD,OAAO,CAACD,KAAK,CAAC;IAC3C;IAEA,IAAI,IAAI,CAACV,MAAM,EAAE;MACf,OAAOe,OAAO,CAACT,OAAO,CAACZ,IAAI,CAAC;IAC9B;IAEA,OAAO,IAAIqB,OAAO,CAAC,CAACT,OAAO,EAAEM,MAAM,KAAK;MACtC,IAAI,CAACR,MAAM,GAAG;QAAEE,OAAO;QAAEM;MAAO,CAAC;IACnC,CAAC,CAAC;EACJ;EAEOK,MAAMA,CAAA,EAA+B;IAC1C,IAAI,CAAClB,QAAQ,CAACe,MAAM,GAAG,CAAC;IACxB,IAAI,CAACP,GAAG,CAAC,CAAC;IAEV,OAAOQ,OAAO,CAACT,OAAO,CAACZ,IAAI,CAAC;EAC9B;EAEA,CAAQwB,MAAM,CAACC,aAAa,IAA8B;IACxD,OAAO,IAAI;EACb;EAEQX,KAAKA,CAAA,EAAY;IACvB,IAAI,IAAI,CAACR,MAAM,EAAE;MACf,OAAO,KAAK;IACd;IAEA,IAAI,CAACA,MAAM,GAAG,IAAI;IAClB,IAAI,CAACE,OAAO,CAAC,CAAC;IAEd,OAAO,IAAI;EACb;EAEQG,UAAUA,CAAA,EAA0B;IAC1C,MAAMD,MAAM,GAAG,IAAI,CAACA,MAAM;IAE1B,IAAI,CAACA,MAAM,GAAGR,SAAS;IAEvB,OAAOQ,MAAM;EACf;AACF;AAEA,SAASN,OAAO","ignoreList":[]}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ import { DeviceStatus } from "../../bt-management/types/device-status.js";
4
+ import { createStableResultId } from "../../bt-management/utils/result-identity.js";
5
+ import { openBleLink } from "./link.js";
6
+
7
+ /** Connects to a scanned device and reports what happens until it disconnects or `signal` aborts. */
8
+
9
+ /** One device's conversation over a link, as the readings it produces. */
10
+
11
+ const readingIdentity = (deviceName, device) => ({
12
+ id: device.id,
13
+ name: deviceName,
14
+ localName: device.localName ?? "",
15
+ manufacturerData: device.manufacturerData ?? "",
16
+ sn: "",
17
+ measurementTypes: []
18
+ });
19
+
20
+ /** Runs a protocol over a fresh BLE link. */
21
+ const gattDriver = (deviceName, protocol) => async function* (device, signal) {
22
+ const link = await openBleLink(device, signal);
23
+ const identity = readingIdentity(deviceName, device);
24
+ try {
25
+ yield {
26
+ kind: "status",
27
+ status: DeviceStatus.CONNECTED
28
+ };
29
+ for await (const reading of protocol(link)) {
30
+ yield {
31
+ kind: "reading",
32
+ id: createStableResultId(identity, reading),
33
+ reading
34
+ };
35
+ }
36
+ yield {
37
+ kind: "status",
38
+ status: DeviceStatus.DISCONNECTED
39
+ };
40
+ } finally {
41
+ await link.close();
42
+ }
43
+ };
44
+ export { gattDriver };
45
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DeviceStatus","createStableResultId","openBleLink","readingIdentity","deviceName","device","id","name","localName","manufacturerData","sn","measurementTypes","gattDriver","protocol","signal","link","identity","kind","status","CONNECTED","reading","DISCONNECTED","close"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/driver.ts"],"mappings":";;AAMA,SAASA,YAAY,QAAQ,4CAAyC;AACtE,SAASC,oBAAoB,QAAQ,8CAA2C;AAEhF,SAAeC,WAAW,QAAQ,WAAQ;;AAU1C;;AAGA;;AAGA,MAAMC,eAAe,GAAGA,CAACC,UAAqB,EAAEC,MAAc,MAAM;EAClEC,EAAE,EAAED,MAAM,CAACC,EAAE;EACbC,IAAI,EAAEH,UAAU;EAChBI,SAAS,EAAEH,MAAM,CAACG,SAAS,IAAI,EAAE;EACjCC,gBAAgB,EAAEJ,MAAM,CAACI,gBAAgB,IAAI,EAAE;EAC/CC,EAAE,EAAE,EAAE;EACNC,gBAAgB,EAAE;AACpB,CAAC,CAAC;;AAEF;AACA,MAAMC,UAAU,GAAGA,CAACR,UAAqB,EAAES,QAAwB,KACjE,iBAAiBR,MAAM,EAAES,MAAM,EAAE;EAC/B,MAAMC,IAAI,GAAG,MAAMb,WAAW,CAACG,MAAM,EAAES,MAAM,CAAC;EAC9C,MAAME,QAAQ,GAAGb,eAAe,CAACC,UAAU,EAAEC,MAAM,CAAC;EAEpD,IAAI;IACF,MAAM;MAAEY,IAAI,EAAE,QAAQ;MAAEC,MAAM,EAAElB,YAAY,CAACmB;IAAU,CAAC;IACxD,WAAW,MAAMC,OAAO,IAAIP,QAAQ,CAACE,IAAI,CAAC,EAAE;MAC1C,MAAM;QAAEE,IAAI,EAAE,SAAS;QAAEX,EAAE,EAAEL,oBAAoB,CAACe,QAAQ,EAAEI,OAAO,CAAC;QAAEA;MAAQ,CAAC;IACjF;IACA,MAAM;MAAEH,IAAI,EAAE,QAAQ;MAAEC,MAAM,EAAElB,YAAY,CAACqB;IAAa,CAAC;EAC7D,CAAC,SAAS;IACR,MAAMN,IAAI,CAACO,KAAK,CAAC,CAAC;EACpB;AACF,CAAC;AAEH,SAASV,UAAU","ignoreList":[]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ import { DeviceCreator } from "../../bt-management/services/device-creator.js";
4
+ import { gattDriver } from "./driver.js";
5
+ import { legacyDriver } from "./legacy-driver.js";
6
+ import { SIG_PROTOCOLS } from "./sig-profiles.js";
7
+
8
+ /** The driver for each device key `accepted` can resolve: its native protocol, else its legacy class. */
9
+ const createDrivers = accepted => {
10
+ const creator = new DeviceCreator(accepted);
11
+ return deviceName => {
12
+ const protocol = SIG_PROTOCOLS.get(String(deviceName));
13
+ return protocol ? gattDriver(deviceName, protocol) : legacyDriver(creator, deviceName);
14
+ };
15
+ };
16
+ export { createDrivers };
17
+ //# sourceMappingURL=drivers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DeviceCreator","gattDriver","legacyDriver","SIG_PROTOCOLS","createDrivers","accepted","creator","deviceName","protocol","get","String"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/drivers.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,gDAA6C;AAI3E,SAAiBC,UAAU,QAAQ,aAAU;AAC7C,SAASC,YAAY,QAAQ,oBAAiB;AAC9C,SAASC,aAAa,QAAQ,mBAAgB;;AAE9C;AACA,MAAMC,aAAa,GAAIC,QAAmC,IAA0C;EAClG,MAAMC,OAAO,GAAG,IAAIN,aAAa,CAACK,QAAQ,CAAC;EAE3C,OAAQE,UAAU,IAAK;IACrB,MAAMC,QAAQ,GAAGL,aAAa,CAACM,GAAG,CAACC,MAAM,CAACH,UAAU,CAAC,CAAC;IAEtD,OAAOC,QAAQ,GAAGP,UAAU,CAACM,UAAU,EAAEC,QAAQ,CAAC,GAAGN,YAAY,CAACI,OAAO,EAAEC,UAAU,CAAC;EACxF,CAAC;AACH,CAAC;AAED,SAASH,aAAa","ignoreList":[]}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ export { gattDriver } from "./driver.js";
4
+ export { createDrivers } from "./drivers.js";
5
+ export { openBleLink } from "./link.js";
6
+ export { dailyTotalsOnly, everyReading, firstReadingPerKind, keepReadings, policyByKind } from "./result-policy.js";
7
+ export { SIG_PROTOCOLS } from "./sig-profiles.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["gattDriver","createDrivers","openBleLink","dailyTotalsOnly","everyReading","firstReadingPerKind","keepReadings","policyByKind","SIG_PROTOCOLS"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/index.ts"],"mappings":";;AAAA,SAASA,UAAU,QAAQ,aAAU;AAErC,SAASC,aAAa,QAAQ,cAAW;AACzC,SAASC,WAAW,QAAQ,WAAQ;AAEpC,SAASC,eAAe,EAAEC,YAAY,EAAEC,mBAAmB,EAAEC,YAAY,EAAEC,YAAY,QAAQ,oBAAiB;AAEhH,SAASC,aAAa,QAAQ,mBAAgB","ignoreList":[]}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ import { DeviceStatus } from "../../bt-management/types/device-status.js";
4
+ import { Channel } from "./channel.js";
5
+ /** Runs a device class from `@ovok/native/bt-management` until its protocol moves to a `DeviceProtocol`. */
6
+ const legacyDriver = (creator, deviceName) => (device, signal) => {
7
+ const events = new Channel(() => void managed.disconnect());
8
+ const managed = creator.createDevice({
9
+ device,
10
+ deviceName,
11
+ onResult: ({
12
+ id,
13
+ data
14
+ }) => events.push({
15
+ kind: "reading",
16
+ id,
17
+ reading: data
18
+ }),
19
+ onDeviceStatusChanged: ({
20
+ status
21
+ }) => {
22
+ events.push({
23
+ kind: "status",
24
+ status
25
+ });
26
+ if (status === DeviceStatus.DISCONNECTED) {
27
+ events.end();
28
+ }
29
+ },
30
+ onConnectionEvent: ({
31
+ deviceData: _deviceData,
32
+ ...event
33
+ }) => events.push({
34
+ kind: "connection",
35
+ event
36
+ }),
37
+ onError: ({
38
+ error
39
+ }) => events.push({
40
+ kind: "error",
41
+ error
42
+ })
43
+ });
44
+ signal.addEventListener("abort", () => events.end(), {
45
+ once: true
46
+ });
47
+ managed.connect().catch(error => events.fail(error));
48
+ return events;
49
+ };
50
+ export { legacyDriver };
51
+ //# sourceMappingURL=legacy-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DeviceStatus","Channel","legacyDriver","creator","deviceName","device","signal","events","managed","disconnect","createDevice","onResult","id","data","push","kind","reading","onDeviceStatusChanged","status","DISCONNECTED","end","onConnectionEvent","deviceData","_deviceData","event","onError","error","addEventListener","once","connect","catch","fail"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/legacy-driver.ts"],"mappings":";;AAKA,SAASA,YAAY,QAAQ,4CAAyC;AAEtE,SAASC,OAAO,QAAQ,cAAW;AAGnC;AACA,MAAMC,YAAY,GAAGA,CAACC,OAAiD,EAAEC,UAAqB,KAC5F,CAACC,MAAM,EAAEC,MAAM,KAAK;EAClB,MAAMC,MAAM,GAAG,IAAIN,OAAO,CAAc,MAAM,KAAKO,OAAO,CAACC,UAAU,CAAC,CAAC,CAAC;EAExE,MAAMD,OAAO,GAAGL,OAAO,CAACO,YAAY,CAAC;IACnCL,MAAM;IACND,UAAU;IACVO,QAAQ,EAAEA,CAAC;MAAEC,EAAE;MAAEC;IAAK,CAAC,KAAKN,MAAM,CAACO,IAAI,CAAC;MAAEC,IAAI,EAAE,SAAS;MAAEH,EAAE;MAAEI,OAAO,EAAEH;IAAoB,CAAC,CAAC;IAC9FI,qBAAqB,EAAEA,CAAC;MAAEC;IAAO,CAAC,KAAK;MACrCX,MAAM,CAACO,IAAI,CAAC;QAAEC,IAAI,EAAE,QAAQ;QAAEG;MAAO,CAAC,CAAC;MACvC,IAAIA,MAAM,KAAKlB,YAAY,CAACmB,YAAY,EAAE;QACxCZ,MAAM,CAACa,GAAG,CAAC,CAAC;MACd;IACF,CAAC;IACDC,iBAAiB,EAAEA,CAAC;MAAEC,UAAU,EAAEC,WAAW;MAAE,GAAGC;IAAM,CAAC,KAAKjB,MAAM,CAACO,IAAI,CAAC;MAAEC,IAAI,EAAE,YAAY;MAAES;IAAM,CAAC,CAAC;IACxGC,OAAO,EAAEA,CAAC;MAAEC;IAAM,CAAC,KAAKnB,MAAM,CAACO,IAAI,CAAC;MAAEC,IAAI,EAAE,OAAO;MAAEW;IAAM,CAAC;EAC9D,CAAC,CAAC;EAEFpB,MAAM,CAACqB,gBAAgB,CAAC,OAAO,EAAE,MAAMpB,MAAM,CAACa,GAAG,CAAC,CAAC,EAAE;IAAEQ,IAAI,EAAE;EAAK,CAAC,CAAC;EACpEpB,OAAO,CAACqB,OAAO,CAAC,CAAC,CAACC,KAAK,CAAEJ,KAAc,IAAKnB,MAAM,CAACwB,IAAI,CAACL,KAAK,CAAC,CAAC;EAE/D,OAAOnB,MAAM;AACf,CAAC;AAEH,SAASL,YAAY","ignoreList":[]}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ import { toBluetoothError } from "../../bt-management/types/bluetooth-error.js";
4
+ import { sentryLogger } from "../../helpers/utils/sentry-logger.js";
5
+ import { Channel } from "./channel.js";
6
+
7
+ /** An open GATT connection: bytes in, bytes out, no knowledge of any device. */
8
+
9
+ const CONNECT_ATTEMPTS = 5;
10
+ const FIRST_RETRY_DELAY_MS = 1000;
11
+ const MAX_RETRY_DELAY_MS = 5000;
12
+
13
+ /** BleErrorCode.OperationCancelled and DeviceDisconnected; the enum is not available at runtime. */
14
+ const ENDS_THE_LINK = new Set([2, 201]);
15
+ const toBytes = base64 => Uint8Array.from(atob(base64), char => char.charCodeAt(0));
16
+ const toBase64 = bytes => btoa(String.fromCharCode(...bytes));
17
+ const retryDelay = attempt => Math.min(FIRST_RETRY_DELAY_MS * 2 ** (attempt - 1), MAX_RETRY_DELAY_MS);
18
+ const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
19
+ const abortReason = signal => signal.reason ?? new Error("The Bluetooth connection was cancelled");
20
+ async function connectWithRetries(device, signal) {
21
+ for (let attempt = 1;; attempt += 1) {
22
+ if (signal.aborted) {
23
+ throw abortReason(signal);
24
+ }
25
+ try {
26
+ if (!(await device.isConnected())) {
27
+ await device.connect();
28
+ }
29
+ return;
30
+ } catch (error) {
31
+ if (attempt >= CONNECT_ATTEMPTS) {
32
+ sentryLogger("error", "BLUETOOTH: Connection failed", {
33
+ errorCode: toBluetoothError(error).code,
34
+ attempts: attempt
35
+ });
36
+ throw error;
37
+ }
38
+ await wait(retryDelay(attempt));
39
+ }
40
+ }
41
+ }
42
+ class BleLink {
43
+ channels = new Set();
44
+ ended = false;
45
+ constructor(device) {
46
+ this.device = device;
47
+ this.disconnected = device.onDisconnected(() => this.endAll());
48
+ }
49
+ subscribe(service, characteristic) {
50
+ const channel = new Channel(() => {
51
+ subscription.remove();
52
+ this.channels.delete(channel);
53
+ });
54
+ const subscription = this.device.monitorCharacteristicForService(service, characteristic, (error, value) => {
55
+ if (error) {
56
+ this.endOrFail(channel, error);
57
+ } else if (value?.value) {
58
+ channel.push(toBytes(value.value));
59
+ }
60
+ });
61
+ this.channels.add(channel);
62
+ if (this.ended) {
63
+ channel.end();
64
+ }
65
+ return channel;
66
+ }
67
+ async write(service, characteristic, bytes) {
68
+ await this.device.writeCharacteristicWithResponseForService(service, characteristic, toBase64(bytes));
69
+ }
70
+ async close() {
71
+ this.endAll();
72
+ this.disconnected.remove();
73
+ await this.device.cancelConnection().catch(() => undefined);
74
+ }
75
+ endOrFail(channel, error) {
76
+ if (ENDS_THE_LINK.has(error.errorCode)) {
77
+ channel.end();
78
+ } else {
79
+ channel.fail(toBluetoothError(error));
80
+ }
81
+ }
82
+ endAll() {
83
+ this.ended = true;
84
+ [...this.channels].forEach(channel => channel.end());
85
+ }
86
+ }
87
+
88
+ /** Connects (retrying with backoff) and discovers services; aborting `signal` closes the link. */
89
+ async function openBleLink(device, signal) {
90
+ await connectWithRetries(device, signal);
91
+ await device.discoverAllServicesAndCharacteristics();
92
+ const link = new BleLink(device);
93
+ if (signal.aborted) {
94
+ await link.close();
95
+ throw abortReason(signal);
96
+ }
97
+ signal.addEventListener("abort", () => void link.close(), {
98
+ once: true
99
+ });
100
+ return link;
101
+ }
102
+ export { openBleLink };
103
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["toBluetoothError","sentryLogger","Channel","CONNECT_ATTEMPTS","FIRST_RETRY_DELAY_MS","MAX_RETRY_DELAY_MS","ENDS_THE_LINK","Set","toBytes","base64","Uint8Array","from","atob","char","charCodeAt","toBase64","bytes","btoa","String","fromCharCode","retryDelay","attempt","Math","min","wait","ms","Promise","resolve","setTimeout","abortReason","signal","reason","Error","connectWithRetries","device","aborted","isConnected","connect","error","errorCode","code","attempts","BleLink","channels","ended","constructor","disconnected","onDisconnected","endAll","subscribe","service","characteristic","channel","subscription","remove","delete","monitorCharacteristicForService","value","endOrFail","push","add","end","write","writeCharacteristicWithResponseForService","close","cancelConnection","catch","undefined","has","fail","forEach","openBleLink","discoverAllServicesAndCharacteristics","link","addEventListener","once"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/link.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ import { dailyTotalDay } from "../../bt-management/utils/daily-total-day.js";
4
+
5
+ /** Makes, for each connection, the test of which readings to keep. */
6
+
7
+ const everyReading = () => () => true;
8
+ const firstReadingPerKind = () => {
9
+ const reported = new Set();
10
+ return ({
11
+ measurementTypeKey
12
+ }) => {
13
+ if (reported.has(measurementTypeKey)) {
14
+ return false;
15
+ }
16
+ reported.add(measurementTypeKey);
17
+ return true;
18
+ };
19
+ };
20
+
21
+ /** Activity totals count only once their day has closed, and each day only once. */
22
+ const dailyTotalsOnly = () => {
23
+ const reported = new Set();
24
+ return reading => {
25
+ const day = dailyTotalDay(reading, Date.now());
26
+ if (day === undefined) {
27
+ return true;
28
+ }
29
+ const key = `${reading.measurementTypeKey}:${day}`;
30
+ if (day === "future" || reported.has(key)) {
31
+ return false;
32
+ }
33
+ reported.add(key);
34
+ return true;
35
+ };
36
+ };
37
+ const policyByKind = (policies, fallback = everyReading) => () => {
38
+ const tests = new Map();
39
+ const fallbackTest = fallback();
40
+ return reading => {
41
+ const policy = policies[reading.measurementTypeKey];
42
+ if (!policy) {
43
+ return fallbackTest(reading);
44
+ }
45
+ const test = tests.get(reading.measurementTypeKey) ?? policy();
46
+ tests.set(reading.measurementTypeKey, test);
47
+ return test(reading);
48
+ };
49
+ };
50
+
51
+ /** A driver's events minus the readings `policy` drops. */
52
+ async function* keepReadings(events, policy) {
53
+ const keep = policy();
54
+ for await (const event of events) {
55
+ if (event.kind !== "reading" || keep(event.reading)) {
56
+ yield event;
57
+ }
58
+ }
59
+ }
60
+ export { dailyTotalsOnly, everyReading, firstReadingPerKind, keepReadings, policyByKind };
61
+ //# sourceMappingURL=result-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["dailyTotalDay","everyReading","firstReadingPerKind","reported","Set","measurementTypeKey","has","add","dailyTotalsOnly","reading","day","Date","now","undefined","key","policyByKind","policies","fallback","tests","Map","fallbackTest","policy","test","get","set","keepReadings","events","keep","event","kind"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/result-policy.ts"],"mappings":";;AAEA,SAASA,aAAa,QAAQ,8CAA2C;;AAIzE;;AAGA,MAAMC,YAA0B,GAAGA,CAAA,KAAM,MAAM,IAAI;AAEnD,MAAMC,mBAAiC,GAAGA,CAAA,KAAM;EAC9C,MAAMC,QAAQ,GAAG,IAAIC,GAAG,CAAqB,CAAC;EAE9C,OAAO,CAAC;IAAEC;EAAmB,CAAC,KAAK;IACjC,IAAIF,QAAQ,CAACG,GAAG,CAACD,kBAAkB,CAAC,EAAE;MACpC,OAAO,KAAK;IACd;IAEAF,QAAQ,CAACI,GAAG,CAACF,kBAAkB,CAAC;IAEhC,OAAO,IAAI;EACb,CAAC;AACH,CAAC;;AAED;AACA,MAAMG,eAA6B,GAAGA,CAAA,KAAM;EAC1C,MAAML,QAAQ,GAAG,IAAIC,GAAG,CAAS,CAAC;EAElC,OAAQK,OAAO,IAAK;IAClB,MAAMC,GAAG,GAAGV,aAAa,CAACS,OAAO,EAAEE,IAAI,CAACC,GAAG,CAAC,CAAC,CAAC;IAE9C,IAAIF,GAAG,KAAKG,SAAS,EAAE;MACrB,OAAO,IAAI;IACb;IAEA,MAAMC,GAAG,GAAG,GAAGL,OAAO,CAACJ,kBAAkB,IAAIK,GAAG,EAAE;IAElD,IAAIA,GAAG,KAAK,QAAQ,IAAIP,QAAQ,CAACG,GAAG,CAACQ,GAAG,CAAC,EAAE;MACzC,OAAO,KAAK;IACd;IAEAX,QAAQ,CAACI,GAAG,CAACO,GAAG,CAAC;IAEjB,OAAO,IAAI;EACb,CAAC;AACH,CAAC;AAED,MAAMC,YAAY,GAAGA,CACnBC,QAA2D,EAC3DC,QAAsB,GAAGhB,YAAY,KAErC,MAAM;EACJ,MAAMiB,KAAK,GAAG,IAAIC,GAAG,CAAwD,CAAC;EAC9E,MAAMC,YAAY,GAAGH,QAAQ,CAAC,CAAC;EAE/B,OAAQR,OAAO,IAAK;IAClB,MAAMY,MAAM,GAAGL,QAAQ,CAACP,OAAO,CAACJ,kBAAkB,CAAC;IAEnD,IAAI,CAACgB,MAAM,EAAE;MACX,OAAOD,YAAY,CAACX,OAAO,CAAC;IAC9B;IAEA,MAAMa,IAAI,GAAGJ,KAAK,CAACK,GAAG,CAACd,OAAO,CAACJ,kBAAkB,CAAC,IAAIgB,MAAM,CAAC,CAAC;IAE9DH,KAAK,CAACM,GAAG,CAACf,OAAO,CAACJ,kBAAkB,EAAEiB,IAAI,CAAC;IAE3C,OAAOA,IAAI,CAACb,OAAO,CAAC;EACtB,CAAC;AACH,CAAC;;AAEH;AACA,gBAAgBgB,YAAYA,CAACC,MAAkC,EAAEL,MAAoB,EAA8B;EACjH,MAAMM,IAAI,GAAGN,MAAM,CAAC,CAAC;EAErB,WAAW,MAAMO,KAAK,IAAIF,MAAM,EAAE;IAChC,IAAIE,KAAK,CAACC,IAAI,KAAK,SAAS,IAAIF,IAAI,CAACC,KAAK,CAACnB,OAAO,CAAC,EAAE;MACnD,MAAMmB,KAAK;IACb;EACF;AACF;AAEA,SAASpB,eAAe,EAAEP,YAAY,EAAEC,mBAAmB,EAAEuB,YAAY,EAAEV,YAAY","ignoreList":[]}
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+
3
+ import { MeasurementTypeKey } from "@ovok/core/next";
4
+ import { BloodPressureStates } from "../../bt-management/types/blood-pressure-states.js";
5
+ import { sigUuid } from "../../bt-management/utils/sig-uuid.js";
6
+ import { dateTimeAt, decodeFrame, floatAt, roundTo, sfloatAt, withDefined } from "./sig-values.js";
7
+ const KPA_TO_MMHG = 7.50062;
8
+ const KG_PER_SI_COUNT = 0.005;
9
+ const KG_PER_IMPERIAL_COUNT = 0.01 * 0.45359237;
10
+ const WEIGHT_UNSUCCESSFUL = 0xffff;
11
+ const DATE_TIME_BYTES = 7;
12
+ const BP_KPA = 0x01;
13
+ const BP_TIMESTAMP = 0x02;
14
+ const BP_PULSE = 0x04;
15
+ const BP_USER = 0x08;
16
+ const BP_STATUS = 0x10;
17
+ const BP_BODY_MOVEMENT = 0x01;
18
+ const BP_LOOSE_CUFF = 0x02;
19
+ const BP_IRREGULAR_PULSE = 0x04;
20
+ const TEMPERATURE_FAHRENHEIT = 0x01;
21
+ const TEMPERATURE_TIMESTAMP = 0x02;
22
+ const WEIGHT_IMPERIAL = 0x01;
23
+ const WEIGHT_TIMESTAMP = 0x02;
24
+ const PLX_TIMESTAMP = 0x01;
25
+ const HEART_RATE_UINT16 = 0x01;
26
+ const HEART_RATE_CONTACT_BITS = 0x06;
27
+ const HEART_RATE_NO_CONTACT = 0x04;
28
+
29
+ /** Core does not export its status enum; this one has the same values. */
30
+
31
+ const bloodPressureStatus = status => {
32
+ if (status & BP_BODY_MOVEMENT) {
33
+ return BloodPressureStates.DISTURB_DETECTED;
34
+ }
35
+ return status & BP_LOOSE_CUFF ? BloodPressureStates.LOOSE_SLEEVE : BloodPressureStates.REGULAR;
36
+ };
37
+
38
+ /** The fields a blood-pressure frame's flags add after the pressures, each in flag order. */
39
+ const bloodPressureExtras = (view, flags) => {
40
+ let offset = 7;
41
+ const extras = {};
42
+ if (flags & BP_TIMESTAMP) {
43
+ extras.recordedAt = dateTimeAt(view, offset);
44
+ offset += DATE_TIME_BYTES;
45
+ }
46
+ if (flags & BP_PULSE) {
47
+ extras.heartRate = sfloatAt(view, offset);
48
+ offset += 2;
49
+ }
50
+ if (flags & BP_USER) {
51
+ const user = view.getUint8(offset);
52
+ extras.memorySlot = user < 2 ? user + 1 : undefined;
53
+ offset += 1;
54
+ }
55
+ if (flags & BP_STATUS) {
56
+ const status = view.getUint16(offset, true);
57
+ extras.status = bloodPressureStatus(status);
58
+ extras.irregularHeartbeat = status & BP_IRREGULAR_PULSE ? true : undefined;
59
+ }
60
+ return extras;
61
+ };
62
+
63
+ /** Blood Pressure Measurement 0x2A35, in mmHg. */
64
+ const bloodPressure = view => {
65
+ const flags = view.getUint8(0);
66
+ const pressure = value => flags & BP_KPA ? roundTo(value * KPA_TO_MMHG, 0) : value;
67
+ const [systolic, diastolic, mean] = [1, 3, 5].map(offset => sfloatAt(view, offset));
68
+ if (systolic === undefined || diastolic === undefined) {
69
+ return undefined;
70
+ }
71
+ const reading = {
72
+ measurementTypeKey: MeasurementTypeKey.bloodPressure,
73
+ systolic: pressure(systolic),
74
+ diastolic: pressure(diastolic)
75
+ };
76
+ return withDefined(reading, {
77
+ meanArterialPressure: mean === undefined ? undefined : pressure(mean),
78
+ ...bloodPressureExtras(view, flags)
79
+ });
80
+ };
81
+
82
+ /** Temperature Measurement 0x2A1C, in Celsius. */
83
+ const temperature = view => {
84
+ const flags = view.getUint8(0);
85
+ const value = floatAt(view, 1);
86
+ if (value === undefined) {
87
+ return undefined;
88
+ }
89
+ const reading = {
90
+ measurementTypeKey: MeasurementTypeKey.temperature,
91
+ bodyTemp: flags & TEMPERATURE_FAHRENHEIT ? roundTo((value - 32) * 5 / 9, 2) : value
92
+ };
93
+ return flags & TEMPERATURE_TIMESTAMP ? withDefined(reading, {
94
+ recordedAt: dateTimeAt(view, 5)
95
+ }) : reading;
96
+ };
97
+
98
+ /** Weight Measurement 0x2A9D, in kilograms. */
99
+ const bodyWeight = view => {
100
+ const flags = view.getUint8(0);
101
+ const counts = view.getUint16(1, true);
102
+ if (counts === WEIGHT_UNSUCCESSFUL) {
103
+ return undefined;
104
+ }
105
+ const reading = {
106
+ measurementTypeKey: MeasurementTypeKey.bodyWeight,
107
+ bodyWeight: roundTo(counts * (flags & WEIGHT_IMPERIAL ? KG_PER_IMPERIAL_COUNT : KG_PER_SI_COUNT), 3)
108
+ };
109
+ return flags & WEIGHT_TIMESTAMP ? withDefined(reading, {
110
+ recordedAt: dateTimeAt(view, 3)
111
+ }) : reading;
112
+ };
113
+
114
+ /** PLX Spot-Check Measurement 0x2A5E. */
115
+ const pulseOximetry = view => {
116
+ const flags = view.getUint8(0);
117
+ const bloodOxygen = sfloatAt(view, 1);
118
+ const pulseRate = sfloatAt(view, 3);
119
+ if (bloodOxygen === undefined || pulseRate === undefined) {
120
+ return undefined;
121
+ }
122
+ const reading = {
123
+ measurementTypeKey: MeasurementTypeKey.bloodOxygenPulseRate,
124
+ bloodOxygen,
125
+ pulseRate
126
+ };
127
+ return flags & PLX_TIMESTAMP ? withDefined(reading, {
128
+ recordedAt: dateTimeAt(view, 5)
129
+ }) : reading;
130
+ };
131
+
132
+ /** Heart Rate Measurement 0x2A37; a strap reporting no skin contact has no reading. */
133
+ const heartRate = view => {
134
+ const flags = view.getUint8(0);
135
+ if ((flags & HEART_RATE_CONTACT_BITS) === HEART_RATE_NO_CONTACT) {
136
+ return undefined;
137
+ }
138
+ const reading = {
139
+ measurementTypeKey: MeasurementTypeKey.heartRate,
140
+ heartRate: flags & HEART_RATE_UINT16 ? view.getUint16(1, true) : view.getUint8(1)
141
+ };
142
+ return reading;
143
+ };
144
+ const subscribed = (service, characteristic, decode) => async function* (link) {
145
+ for await (const frame of link.subscribe(sigUuid(service), sigUuid(characteristic))) {
146
+ const reading = decodeFrame(decode, frame);
147
+ if (reading) {
148
+ yield reading;
149
+ }
150
+ }
151
+ };
152
+
153
+ /** By the ids the SDK catalog gives the Bluetooth SIG profiles. */
154
+ const SIG_PROTOCOLS = new Map([["standard-blood-pressure", subscribed("1810", "2a35", bloodPressure)], ["standard-body-temperature", subscribed("1809", "2a1c", temperature)], ["standard-body-weight", subscribed("181d", "2a9d", bodyWeight)], ["standard-blood-oxygen-pulse-rate", subscribed("1822", "2a5e", pulseOximetry)], ["standard-heart-rate", subscribed("180d", "2a37", heartRate)]]);
155
+ export { bloodPressure, bodyWeight, heartRate, pulseOximetry, SIG_PROTOCOLS, temperature };
156
+ //# sourceMappingURL=sig-profiles.js.map