@ovok/native 0.4.3 → 0.4.5

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 (145) hide show
  1. package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.device.js +8 -23
  2. package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.device.js.map +1 -1
  3. package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.frame-reader.js +89 -0
  4. package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.frame-reader.js.map +1 -0
  5. package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.main-services.js +50 -21
  6. package/lib/commonjs/modules/bt-management/services/devices/bp2/bp2.main-services.js.map +1 -1
  7. package/lib/commonjs/modules/bt-management/services/devices/bt-connection-handler.js +25 -1
  8. package/lib/commonjs/modules/bt-management/services/devices/bt-connection-handler.js.map +1 -1
  9. package/lib/commonjs/modules/bt-management/services/devices/bt-data-processor.js +80 -85
  10. package/lib/commonjs/modules/bt-management/services/devices/bt-data-processor.js.map +1 -1
  11. package/lib/commonjs/modules/bt-management/services/devices/bt-managed-device.js +25 -3
  12. package/lib/commonjs/modules/bt-management/services/devices/bt-managed-device.js.map +1 -1
  13. package/lib/commonjs/modules/bt-management/services/devices/frame-parser.js +54 -0
  14. package/lib/commonjs/modules/bt-management/services/devices/frame-parser.js.map +1 -0
  15. package/lib/commonjs/modules/bt-management/services/devices/measurement-state-machine.js +63 -0
  16. package/lib/commonjs/modules/bt-management/services/devices/measurement-state-machine.js.map +1 -0
  17. package/lib/commonjs/modules/bt-management/types/frame-read-result.js +6 -0
  18. package/lib/commonjs/modules/bt-management/types/frame-read-result.js.map +1 -0
  19. package/lib/commonjs/modules/bt-management/types/frame-read-status.js +17 -0
  20. package/lib/commonjs/modules/bt-management/types/frame-read-status.js.map +1 -0
  21. package/lib/commonjs/modules/bt-management/types/frame-reader.js +6 -0
  22. package/lib/commonjs/modules/bt-management/types/frame-reader.js.map +1 -0
  23. package/lib/commonjs/modules/bt-management/utils/calculate-crc-8.js +43 -0
  24. package/lib/commonjs/modules/bt-management/utils/calculate-crc-8.js.map +1 -0
  25. package/lib/commonjs/modules/bt-management/utils/convert-bp-state-flag.js +8 -1
  26. package/lib/commonjs/modules/bt-management/utils/convert-bp-state-flag.js.map +1 -1
  27. package/lib/commonjs/modules/bt-management/utils/le-16-from-hex.js.map +1 -1
  28. package/lib/commonjs/modules/data-sync/components/android/android-health-sync.js +11 -1
  29. package/lib/commonjs/modules/data-sync/components/android/android-health-sync.js.map +1 -1
  30. package/lib/commonjs/modules/data-sync/components/apple/apple-health-sync.js +33 -1
  31. package/lib/commonjs/modules/data-sync/components/apple/apple-health-sync.js.map +1 -1
  32. package/lib/commonjs/modules/data-sync/services/base-health-sync-service.js +4 -0
  33. package/lib/commonjs/modules/data-sync/services/base-health-sync-service.js.map +1 -1
  34. package/lib/commonjs/modules/data-sync/services/managers/storage-manager.js +30 -2
  35. package/lib/commonjs/modules/data-sync/services/managers/storage-manager.js.map +1 -1
  36. package/lib/commonjs/modules/data-sync/services/managers/sync-state-manager.js +19 -0
  37. package/lib/commonjs/modules/data-sync/services/managers/sync-state-manager.js.map +1 -1
  38. package/lib/module/modules/bt-management/services/devices/bp2/bp2.device.js +9 -23
  39. package/lib/module/modules/bt-management/services/devices/bp2/bp2.device.js.map +1 -1
  40. package/lib/module/modules/bt-management/services/devices/bp2/bp2.frame-reader.js +84 -0
  41. package/lib/module/modules/bt-management/services/devices/bp2/bp2.frame-reader.js.map +1 -0
  42. package/lib/module/modules/bt-management/services/devices/bp2/bp2.main-services.js +50 -21
  43. package/lib/module/modules/bt-management/services/devices/bp2/bp2.main-services.js.map +1 -1
  44. package/lib/module/modules/bt-management/services/devices/bt-connection-handler.js +25 -1
  45. package/lib/module/modules/bt-management/services/devices/bt-connection-handler.js.map +1 -1
  46. package/lib/module/modules/bt-management/services/devices/bt-data-processor.js +80 -85
  47. package/lib/module/modules/bt-management/services/devices/bt-data-processor.js.map +1 -1
  48. package/lib/module/modules/bt-management/services/devices/bt-managed-device.js +25 -3
  49. package/lib/module/modules/bt-management/services/devices/bt-managed-device.js.map +1 -1
  50. package/lib/module/modules/bt-management/services/devices/frame-parser.js +50 -0
  51. package/lib/module/modules/bt-management/services/devices/frame-parser.js.map +1 -0
  52. package/lib/module/modules/bt-management/services/devices/measurement-state-machine.js +58 -0
  53. package/lib/module/modules/bt-management/services/devices/measurement-state-machine.js.map +1 -0
  54. package/lib/module/modules/bt-management/types/frame-read-result.js +4 -0
  55. package/lib/module/modules/bt-management/types/frame-read-result.js.map +1 -0
  56. package/lib/module/modules/bt-management/types/frame-read-status.js +13 -0
  57. package/lib/module/modules/bt-management/types/frame-read-status.js.map +1 -0
  58. package/lib/module/modules/bt-management/types/frame-reader.js +4 -0
  59. package/lib/module/modules/bt-management/types/frame-reader.js.map +1 -0
  60. package/lib/module/modules/bt-management/utils/calculate-crc-8.js +38 -0
  61. package/lib/module/modules/bt-management/utils/calculate-crc-8.js.map +1 -0
  62. package/lib/module/modules/bt-management/utils/convert-bp-state-flag.js +9 -1
  63. package/lib/module/modules/bt-management/utils/convert-bp-state-flag.js.map +1 -1
  64. package/lib/module/modules/bt-management/utils/le-16-from-hex.js.map +1 -1
  65. package/lib/module/modules/data-sync/components/android/android-health-sync.js +11 -1
  66. package/lib/module/modules/data-sync/components/android/android-health-sync.js.map +1 -1
  67. package/lib/module/modules/data-sync/components/apple/apple-health-sync.js +33 -1
  68. package/lib/module/modules/data-sync/components/apple/apple-health-sync.js.map +1 -1
  69. package/lib/module/modules/data-sync/services/base-health-sync-service.js +4 -0
  70. package/lib/module/modules/data-sync/services/base-health-sync-service.js.map +1 -1
  71. package/lib/module/modules/data-sync/services/managers/storage-manager.js +30 -2
  72. package/lib/module/modules/data-sync/services/managers/storage-manager.js.map +1 -1
  73. package/lib/module/modules/data-sync/services/managers/sync-state-manager.js +19 -0
  74. package/lib/module/modules/data-sync/services/managers/sync-state-manager.js.map +1 -1
  75. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts +3 -1
  76. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts.map +1 -1
  77. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts +14 -0
  78. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts.map +1 -0
  79. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bp2/bp2.main-services.d.ts.map +1 -1
  80. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-connection-handler.d.ts +9 -1
  81. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-connection-handler.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-data-processor.d.ts +27 -10
  83. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-data-processor.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-managed-device.d.ts +23 -1
  85. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-managed-device.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/frame-parser.d.ts +19 -0
  87. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/frame-parser.d.ts.map +1 -0
  88. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/measurement-state-machine.d.ts +30 -0
  89. package/lib/typescript/commonjs/src/modules/bt-management/services/devices/measurement-state-machine.d.ts.map +1 -0
  90. package/lib/typescript/commonjs/src/modules/bt-management/types/frame-read-result.d.ts +21 -0
  91. package/lib/typescript/commonjs/src/modules/bt-management/types/frame-read-result.d.ts.map +1 -0
  92. package/lib/typescript/commonjs/src/modules/bt-management/types/frame-read-status.d.ts +10 -0
  93. package/lib/typescript/commonjs/src/modules/bt-management/types/frame-read-status.d.ts.map +1 -0
  94. package/lib/typescript/commonjs/src/modules/bt-management/types/frame-reader.d.ts +13 -0
  95. package/lib/typescript/commonjs/src/modules/bt-management/types/frame-reader.d.ts.map +1 -0
  96. package/lib/typescript/commonjs/src/modules/bt-management/utils/calculate-crc-8.d.ts +10 -0
  97. package/lib/typescript/commonjs/src/modules/bt-management/utils/calculate-crc-8.d.ts.map +1 -0
  98. package/lib/typescript/commonjs/src/modules/bt-management/utils/convert-bp-state-flag.d.ts +7 -0
  99. package/lib/typescript/commonjs/src/modules/bt-management/utils/convert-bp-state-flag.d.ts.map +1 -1
  100. package/lib/typescript/commonjs/src/modules/bt-management/utils/le-16-from-hex.d.ts +1 -1
  101. package/lib/typescript/commonjs/src/modules/bt-management/utils/le-16-from-hex.d.ts.map +1 -1
  102. package/lib/typescript/commonjs/src/modules/data-sync/components/android/android-health-sync.d.ts.map +1 -1
  103. package/lib/typescript/commonjs/src/modules/data-sync/components/apple/apple-health-sync.d.ts.map +1 -1
  104. package/lib/typescript/commonjs/src/modules/data-sync/services/base-health-sync-service.d.ts +2 -0
  105. package/lib/typescript/commonjs/src/modules/data-sync/services/base-health-sync-service.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/src/modules/data-sync/services/managers/storage-manager.d.ts +20 -0
  107. package/lib/typescript/commonjs/src/modules/data-sync/services/managers/storage-manager.d.ts.map +1 -1
  108. package/lib/typescript/commonjs/src/modules/data-sync/services/managers/sync-state-manager.d.ts +13 -0
  109. package/lib/typescript/commonjs/src/modules/data-sync/services/managers/sync-state-manager.d.ts.map +1 -1
  110. package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts +3 -1
  111. package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.device.d.ts.map +1 -1
  112. package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts +14 -0
  113. package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.frame-reader.d.ts.map +1 -0
  114. package/lib/typescript/module/src/modules/bt-management/services/devices/bp2/bp2.main-services.d.ts.map +1 -1
  115. package/lib/typescript/module/src/modules/bt-management/services/devices/bt-connection-handler.d.ts +9 -1
  116. package/lib/typescript/module/src/modules/bt-management/services/devices/bt-connection-handler.d.ts.map +1 -1
  117. package/lib/typescript/module/src/modules/bt-management/services/devices/bt-data-processor.d.ts +27 -10
  118. package/lib/typescript/module/src/modules/bt-management/services/devices/bt-data-processor.d.ts.map +1 -1
  119. package/lib/typescript/module/src/modules/bt-management/services/devices/bt-managed-device.d.ts +23 -1
  120. package/lib/typescript/module/src/modules/bt-management/services/devices/bt-managed-device.d.ts.map +1 -1
  121. package/lib/typescript/module/src/modules/bt-management/services/devices/frame-parser.d.ts +19 -0
  122. package/lib/typescript/module/src/modules/bt-management/services/devices/frame-parser.d.ts.map +1 -0
  123. package/lib/typescript/module/src/modules/bt-management/services/devices/measurement-state-machine.d.ts +30 -0
  124. package/lib/typescript/module/src/modules/bt-management/services/devices/measurement-state-machine.d.ts.map +1 -0
  125. package/lib/typescript/module/src/modules/bt-management/types/frame-read-result.d.ts +21 -0
  126. package/lib/typescript/module/src/modules/bt-management/types/frame-read-result.d.ts.map +1 -0
  127. package/lib/typescript/module/src/modules/bt-management/types/frame-read-status.d.ts +10 -0
  128. package/lib/typescript/module/src/modules/bt-management/types/frame-read-status.d.ts.map +1 -0
  129. package/lib/typescript/module/src/modules/bt-management/types/frame-reader.d.ts +13 -0
  130. package/lib/typescript/module/src/modules/bt-management/types/frame-reader.d.ts.map +1 -0
  131. package/lib/typescript/module/src/modules/bt-management/utils/calculate-crc-8.d.ts +10 -0
  132. package/lib/typescript/module/src/modules/bt-management/utils/calculate-crc-8.d.ts.map +1 -0
  133. package/lib/typescript/module/src/modules/bt-management/utils/convert-bp-state-flag.d.ts +7 -0
  134. package/lib/typescript/module/src/modules/bt-management/utils/convert-bp-state-flag.d.ts.map +1 -1
  135. package/lib/typescript/module/src/modules/bt-management/utils/le-16-from-hex.d.ts +1 -1
  136. package/lib/typescript/module/src/modules/bt-management/utils/le-16-from-hex.d.ts.map +1 -1
  137. package/lib/typescript/module/src/modules/data-sync/components/android/android-health-sync.d.ts.map +1 -1
  138. package/lib/typescript/module/src/modules/data-sync/components/apple/apple-health-sync.d.ts.map +1 -1
  139. package/lib/typescript/module/src/modules/data-sync/services/base-health-sync-service.d.ts +2 -0
  140. package/lib/typescript/module/src/modules/data-sync/services/base-health-sync-service.d.ts.map +1 -1
  141. package/lib/typescript/module/src/modules/data-sync/services/managers/storage-manager.d.ts +20 -0
  142. package/lib/typescript/module/src/modules/data-sync/services/managers/storage-manager.d.ts.map +1 -1
  143. package/lib/typescript/module/src/modules/data-sync/services/managers/sync-state-manager.d.ts +13 -0
  144. package/lib/typescript/module/src/modules/data-sync/services/managers/sync-state-manager.d.ts.map +1 -1
  145. package/package.json +1 -1
@@ -18,6 +18,28 @@ export class BTManagedDevice {
18
18
  * @returns The handled data.
19
19
  */
20
20
 
21
+ /**
22
+ * Locates frame boundaries inside the notification buffer.
23
+ *
24
+ * A device that leaves this undefined has its whole buffer handed to
25
+ * `validatePackage` and parsed as a single frame, which only holds while a
26
+ * notification can neither split a frame nor carry more than one.
27
+ */
28
+
29
+ /**
30
+ * MTU to ask for once connected.
31
+ *
32
+ * A larger MTU carries a frame in fewer notifications, which matters most for the
33
+ * long payloads. Devices that leave this undefined keep the platform default.
34
+ */
35
+
36
+ /**
37
+ * Decides whether the buffer holds a parseable frame.
38
+ *
39
+ * Only consulted for devices that declare no frameReader. A device that declares
40
+ * neither parses nothing, so an unknown buffer is never decoded on trust.
41
+ */
42
+
21
43
  constructor(device, {
22
44
  deviceName,
23
45
  onError: onErrorCallback,
@@ -109,11 +131,11 @@ export class BTManagedDevice {
109
131
  onDataReceived: (uuid, hexValue) => {
110
132
  this.dataProcessor?.processData(uuid, hexValue);
111
133
  }
112
- });
134
+ }, this.preferredMtu);
113
135
  this.dataProcessor = new BTDataProcessor(this.device, this.mainServices, this.stuckDataTimeout, {
114
136
  onStatusChanged: this.onDeviceStatusChanged?.bind(this),
115
137
  onStreamStart: this.onStreamStart?.bind(this),
116
- validatePackage: this.validatePackage.bind(this),
138
+ validatePackage: this.validatePackage?.bind(this) ?? (() => false),
117
139
  onResult: (parsedData, collectedValues) => {
118
140
  try {
119
141
  return this.handleSuccessResult.bind(this)(parsedData, collectedValues);
@@ -124,7 +146,7 @@ export class BTManagedDevice {
124
146
  onSendCommandToDevice: this.connectionHandler?.sendCommandToDevice?.bind(this),
125
147
  onError: this.onError?.bind(this),
126
148
  handleDependentResult: this.handleDependentResult?.bind(this)
127
- });
149
+ }, this.frameReader);
128
150
  await this.connectionHandler.connect();
129
151
  };
130
152
  getSupportedMeasurementTypeKeys = () => {
@@ -1 +1 @@
1
- {"version":3,"names":["sentryLogger","DeviceStatus","BTConnectionHandler","BTDataProcessor","BTManagedDevice","constructor","device","deviceName","onError","onErrorCallback","onDeviceStatusChanged","onDeviceStatusChangedCallback","onResult","onResultCallback","onDeviceDisconnected","onDeviceDisconnectedCallback","deviceId","id","deviceData","name","localName","manufacturerData","sn","measurementTypes","status","measurementTypeKey","error","Error","message","caseType","_","data","diagramPoints","length","undefined","destroy","connectionHandler","dataProcessor","connect","getSupportedMeasurementTypeKeys","mainServices","onStatusChanged","bind","DISCONNECTED","onDataReceived","uuid","hexValue","processData","stuckDataTimeout","onStreamStart","validatePackage","parsedData","collectedValues","handleSuccessResult","onSendCommandToDevice","sendCommandToDevice","handleDependentResult","flatMap","service","monitorUuids","parsingModel","cases","map","c","filter","type","uniqueMeasurementTypes","Set","flat"],"sourceRoot":"../../../../../../src","sources":["modules/bt-management/services/devices/bt-managed-device.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["sentryLogger","DeviceStatus","BTConnectionHandler","BTDataProcessor","BTManagedDevice","constructor","device","deviceName","onError","onErrorCallback","onDeviceStatusChanged","onDeviceStatusChangedCallback","onResult","onResultCallback","onDeviceDisconnected","onDeviceDisconnectedCallback","deviceId","id","deviceData","name","localName","manufacturerData","sn","measurementTypes","status","measurementTypeKey","error","Error","message","caseType","_","data","diagramPoints","length","undefined","destroy","connectionHandler","dataProcessor","connect","getSupportedMeasurementTypeKeys","mainServices","onStatusChanged","bind","DISCONNECTED","onDataReceived","uuid","hexValue","processData","preferredMtu","stuckDataTimeout","onStreamStart","validatePackage","parsedData","collectedValues","handleSuccessResult","onSendCommandToDevice","sendCommandToDevice","handleDependentResult","frameReader","flatMap","service","monitorUuids","parsingModel","cases","map","c","filter","type","uniqueMeasurementTypes","Set","flat"],"sourceRoot":"../../../../../../src","sources":["modules/bt-management/services/devices/bt-managed-device.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ import { parseMeasurement } from "../../utils/parse-measurement.js";
4
+
5
+ /**
6
+ * Turns a verified frame into a measurement, by selecting the parsing case the frame
7
+ * matches and applying that case's field definitions.
8
+ *
9
+ * A frame whose characteristic is unknown, whose selector bytes match no declared case,
10
+ * or whose fields do not parse yields nothing: it is the caller's decision whether that
11
+ * is worth reporting.
12
+ */
13
+ export class FrameParser {
14
+ constructor(mainServices) {
15
+ this.mainServices = mainServices;
16
+ }
17
+ parse(uuid, frame) {
18
+ const parsingModel = this.findParsingModel(uuid);
19
+ if (!parsingModel) {
20
+ return;
21
+ }
22
+ const caseValue = this.readCaseValue(parsingModel, frame);
23
+ const parsingCase = parsingModel.cases?.find(declared => declared.caseValue === caseValue);
24
+ if (!parsingCase) {
25
+ return;
26
+ }
27
+ const parsedData = parseMeasurement(frame, parsingCase);
28
+ if (!parsedData) {
29
+ return;
30
+ }
31
+ return {
32
+ parsingCase,
33
+ measurementTypeKey: parsingCase.measurementTypeKey,
34
+ parsedData: parsedData
35
+ };
36
+ }
37
+ findParsingModel(uuid) {
38
+ for (const mainService of this.mainServices) {
39
+ const characteristic = mainService.monitorUuids.find(monitored => monitored.uuid.toLowerCase() === uuid.toLowerCase());
40
+ if (characteristic) {
41
+ return characteristic.parsingModel;
42
+ }
43
+ }
44
+ return undefined;
45
+ }
46
+ readCaseValue(parsingModel, frame) {
47
+ return parsingModel.caseValuePosition?.map(index => frame[index]).join("") || "";
48
+ }
49
+ }
50
+ //# sourceMappingURL=frame-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["parseMeasurement","FrameParser","constructor","mainServices","parse","uuid","frame","parsingModel","findParsingModel","caseValue","readCaseValue","parsingCase","cases","find","declared","parsedData","measurementTypeKey","mainService","characteristic","monitorUuids","monitored","toLowerCase","undefined","caseValuePosition","map","index","join"],"sourceRoot":"../../../../../../src","sources":["modules/bt-management/services/devices/frame-parser.ts"],"mappings":";;AAMA,SAASA,gBAAgB,QAAQ,kCAA+B;;AAEhE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,CAAwB;EAC9CC,WAAWA,CAAkBC,YAA2C,EAAE;IAAA,KAA7CA,YAA2C,GAA3CA,YAA2C;EAAG;EAEpEC,KAAKA,CACVC,IAAY,EACZC,KAAe,EAC8B;IAC7C,MAAMC,YAAY,GAAG,IAAI,CAACC,gBAAgB,CAACH,IAAI,CAAC;IAEhD,IAAI,CAACE,YAAY,EAAE;MACjB;IACF;IAEA,MAAME,SAAS,GAAG,IAAI,CAACC,aAAa,CAACH,YAAY,EAAED,KAAK,CAAC;IAEzD,MAAMK,WAAW,GAAGJ,YAAY,CAACK,KAAK,EAAEC,IAAI,CACzCC,QAAQ,IAAKA,QAAQ,CAACL,SAAS,KAAKA,SACvC,CAAC;IAED,IAAI,CAACE,WAAW,EAAE;MAChB;IACF;IAEA,MAAMI,UAAU,GAAGf,gBAAgB,CAACM,KAAK,EAAEK,WAAW,CAAC;IAEvD,IAAI,CAACI,UAAU,EAAE;MACf;IACF;IAEA,OAAO;MACLJ,WAAW;MACXK,kBAAkB,EAAEL,WAAW,CAACK,kBAAkB;MAClDD,UAAU,EAAEA;IACd,CAAC;EACH;EAEQP,gBAAgBA,CAACH,IAAY,EAA4B;IAC/D,KAAK,MAAMY,WAAW,IAAI,IAAI,CAACd,YAAY,EAAE;MAC3C,MAAMe,cAAc,GAAGD,WAAW,CAACE,YAAY,CAACN,IAAI,CACjDO,SAAS,IAAKA,SAAS,CAACf,IAAI,CAACgB,WAAW,CAAC,CAAC,KAAKhB,IAAI,CAACgB,WAAW,CAAC,CACnE,CAAC;MAED,IAAIH,cAAc,EAAE;QAClB,OAAOA,cAAc,CAACX,YAAY;MACpC;IACF;IAEA,OAAOe,SAAS;EAClB;EAEQZ,aAAaA,CAACH,YAA0B,EAAED,KAAe,EAAU;IACzE,OACEC,YAAY,CAACgB,iBAAiB,EAAEC,GAAG,CAAEC,KAAK,IAAKnB,KAAK,CAACmB,KAAK,CAAC,CAAC,CAACC,IAAI,CAAC,EAAE,CAAC,IACrE,EAAE;EAEN;AACF","ignoreList":[]}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ import { CaseType } from "../../types/case-type.js";
4
+ import { DeviceStatus } from "../../types/device-status.js";
5
+ /**
6
+ * Moves a device between measuring and connected as parsed frames arrive, and decides
7
+ * which of them is worth reporting.
8
+ *
9
+ * A result is reported whether or not a stream preceded it, because a device already
10
+ * holding a finished measurement when the app connects has a real reading to hand over.
11
+ * Repeats are suppressed on the case transition rather than on the values, so a second
12
+ * measurement that happens to read the same as the first is still reported.
13
+ */
14
+ export class MeasurementStateMachine {
15
+ isMeasuring = false;
16
+ constructor(callbacks) {
17
+ this.callbacks = callbacks;
18
+ }
19
+ reset = () => {
20
+ this.isMeasuring = false;
21
+ this.lastCaseValue = undefined;
22
+ };
23
+ advance = ({
24
+ parsingCase,
25
+ measurementTypeKey,
26
+ parsedData
27
+ }, frame) => {
28
+ const isResult = parsingCase.caseType === CaseType.RESULT;
29
+ const isRepeatedResult = isResult && parsingCase.caseValue === this.lastCaseValue;
30
+ this.lastCaseValue = parsingCase.caseValue;
31
+ if (parsingCase.caseType === CaseType.STREAM && !this.isMeasuring) {
32
+ this.startMeasuring(measurementTypeKey);
33
+ }
34
+ if (this.isMeasuring && parsingCase.caseType === CaseType.OTHER) {
35
+ this.stopMeasuring(measurementTypeKey);
36
+ }
37
+ if (isRepeatedResult) {
38
+ return;
39
+ }
40
+ let keepMeasuring = false;
41
+ if (this.isMeasuring || isResult) {
42
+ keepMeasuring = this.callbacks.onResult?.(parsedData, frame) ?? false;
43
+ }
44
+ if (isResult && !keepMeasuring) {
45
+ this.stopMeasuring(measurementTypeKey);
46
+ }
47
+ };
48
+ startMeasuring = measurementTypeKey => {
49
+ this.callbacks.onStreamStart?.();
50
+ this.callbacks.onStatusChanged?.(DeviceStatus.MEASURING, measurementTypeKey);
51
+ this.isMeasuring = true;
52
+ };
53
+ stopMeasuring = measurementTypeKey => {
54
+ this.isMeasuring = false;
55
+ this.callbacks.onStatusChanged?.(DeviceStatus.CONNECTED, measurementTypeKey);
56
+ };
57
+ }
58
+ //# sourceMappingURL=measurement-state-machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["CaseType","DeviceStatus","MeasurementStateMachine","isMeasuring","constructor","callbacks","reset","lastCaseValue","undefined","advance","parsingCase","measurementTypeKey","parsedData","frame","isResult","caseType","RESULT","isRepeatedResult","caseValue","STREAM","startMeasuring","OTHER","stopMeasuring","keepMeasuring","onResult","onStreamStart","onStatusChanged","MEASURING","CONNECTED"],"sourceRoot":"../../../../../../src","sources":["modules/bt-management/services/devices/measurement-state-machine.ts"],"mappings":";;AAEA,SAASA,QAAQ,QAAQ,0BAAuB;AAEhD,SAASC,YAAY,QAAQ,8BAA2B;AAexD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,uBAAuB,CAAwB;EAClDC,WAAW,GAAY,KAAK;EAGpCC,WAAWA,CAAkBC,SAAoC,EAAE;IAAA,KAAtCA,SAAoC,GAApCA,SAAoC;EAAG;EAE7DC,KAAK,GAAGA,CAAA,KAAY;IACzB,IAAI,CAACH,WAAW,GAAG,KAAK;IACxB,IAAI,CAACI,aAAa,GAAGC,SAAS;EAChC,CAAC;EAEMC,OAAO,GAAGA,CACf;IACEC,WAAW;IACXC,kBAAkB;IAClBC;EAC+B,CAAC,EAClCC,KAAe,KACN;IACT,MAAMC,QAAQ,GAAGJ,WAAW,CAACK,QAAQ,KAAKf,QAAQ,CAACgB,MAAM;IAEzD,MAAMC,gBAAgB,GACpBH,QAAQ,IAAIJ,WAAW,CAACQ,SAAS,KAAK,IAAI,CAACX,aAAa;IAE1D,IAAI,CAACA,aAAa,GAAGG,WAAW,CAACQ,SAAS;IAE1C,IAAIR,WAAW,CAACK,QAAQ,KAAKf,QAAQ,CAACmB,MAAM,IAAI,CAAC,IAAI,CAAChB,WAAW,EAAE;MACjE,IAAI,CAACiB,cAAc,CAACT,kBAAkB,CAAC;IACzC;IAEA,IAAI,IAAI,CAACR,WAAW,IAAIO,WAAW,CAACK,QAAQ,KAAKf,QAAQ,CAACqB,KAAK,EAAE;MAC/D,IAAI,CAACC,aAAa,CAACX,kBAAkB,CAAC;IACxC;IAEA,IAAIM,gBAAgB,EAAE;MACpB;IACF;IAEA,IAAIM,aAAa,GAAG,KAAK;IAEzB,IAAI,IAAI,CAACpB,WAAW,IAAIW,QAAQ,EAAE;MAChCS,aAAa,GAAG,IAAI,CAAClB,SAAS,CAACmB,QAAQ,GAAGZ,UAAU,EAAEC,KAAK,CAAC,IAAI,KAAK;IACvE;IAEA,IAAIC,QAAQ,IAAI,CAACS,aAAa,EAAE;MAC9B,IAAI,CAACD,aAAa,CAACX,kBAAkB,CAAC;IACxC;EACF,CAAC;EAEOS,cAAc,GAAIT,kBAAuC,IAAW;IAC1E,IAAI,CAACN,SAAS,CAACoB,aAAa,GAAG,CAAC;IAChC,IAAI,CAACpB,SAAS,CAACqB,eAAe,GAAGzB,YAAY,CAAC0B,SAAS,EAAEhB,kBAAkB,CAAC;IAC5E,IAAI,CAACR,WAAW,GAAG,IAAI;EACzB,CAAC;EAEOmB,aAAa,GAAIX,kBAAuC,IAAW;IACzE,IAAI,CAACR,WAAW,GAAG,KAAK;IACxB,IAAI,CAACE,SAAS,CAACqB,eAAe,GAC5BzB,YAAY,CAAC2B,SAAS,EACtBjB,kBACF,CAAC;EACH,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export {};
4
+ //# sourceMappingURL=frame-read-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../../../src","sources":["modules/bt-management/types/frame-read-result.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ /** Outcome of trying to read one frame from a notification buffer. */
4
+ export let FrameReadStatus = /*#__PURE__*/function (FrameReadStatus) {
5
+ /** No complete frame yet. The buffer must keep growing. */
6
+ FrameReadStatus["INCOMPLETE"] = "incomplete";
7
+ /** A frame was found but failed its integrity check and must not be parsed. */
8
+ FrameReadStatus["CORRUPT"] = "corrupt";
9
+ /** A complete, verified frame was isolated. */
10
+ FrameReadStatus["COMPLETE"] = "complete";
11
+ return FrameReadStatus;
12
+ }({});
13
+ //# sourceMappingURL=frame-read-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FrameReadStatus"],"sourceRoot":"../../../../../src","sources":["modules/bt-management/types/frame-read-status.ts"],"mappings":";;AAAA;AACA,WAAYA,eAAe,0BAAfA,eAAe;EAEzB;EAFUA,eAAe;EAKzB;EALUA,eAAe;EAQzB;EARUA,eAAe;EAAA,OAAfA,eAAe;AAAA","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export {};
4
+ //# sourceMappingURL=frame-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../../../src","sources":["modules/bt-management/types/frame-reader.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ import { hexToByte } from "./hex-to-byte.js";
4
+ const CRC8_POLYNOMIAL = 0x07;
5
+ const BYTE_VALUE_COUNT = 256;
6
+ const BITS_PER_BYTE = 8;
7
+ const HIGH_BIT = 0x80;
8
+ const BYTE_MASK = 0xff;
9
+ const buildLookupTable = () => {
10
+ const table = new Uint8Array(BYTE_VALUE_COUNT);
11
+ for (let value = 0; value < BYTE_VALUE_COUNT; value++) {
12
+ let remainder = value;
13
+ for (let bit = 0; bit < BITS_PER_BYTE; bit++) {
14
+ const isHighBitSet = (remainder & HIGH_BIT) !== 0;
15
+ remainder = isHighBitSet ? (remainder << 1 ^ CRC8_POLYNOMIAL) & BYTE_MASK : remainder << 1 & BYTE_MASK;
16
+ }
17
+ table[value] = remainder;
18
+ }
19
+ return table;
20
+ };
21
+ const LOOKUP_TABLE = buildLookupTable();
22
+
23
+ /**
24
+ * CRC-8/ATM (polynomial 0x07, initial value 0x00) over the first `byteCount` bytes.
25
+ *
26
+ * Lepu devices store a frame's checksum in its final byte, so a frame is verified by
27
+ * running this over every byte except that one and comparing the result against it.
28
+ * The byte count is explicit rather than implied so the caller states which bytes are
29
+ * covered instead of relying on a convention hidden in here.
30
+ */
31
+ export const calculateCrc8 = (hex, byteCount) => {
32
+ let remainder = 0;
33
+ for (let index = 0; index < byteCount; index++) {
34
+ remainder = LOOKUP_TABLE[remainder ^ hexToByte(hex[index] || "0")] || 0;
35
+ }
36
+ return remainder;
37
+ };
38
+ //# sourceMappingURL=calculate-crc-8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["hexToByte","CRC8_POLYNOMIAL","BYTE_VALUE_COUNT","BITS_PER_BYTE","HIGH_BIT","BYTE_MASK","buildLookupTable","table","Uint8Array","value","remainder","bit","isHighBitSet","LOOKUP_TABLE","calculateCrc8","hex","byteCount","index"],"sourceRoot":"../../../../../src","sources":["modules/bt-management/utils/calculate-crc-8.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,kBAAe;AAEzC,MAAMC,eAAe,GAAG,IAAI;AAC5B,MAAMC,gBAAgB,GAAG,GAAG;AAC5B,MAAMC,aAAa,GAAG,CAAC;AACvB,MAAMC,QAAQ,GAAG,IAAI;AACrB,MAAMC,SAAS,GAAG,IAAI;AAEtB,MAAMC,gBAAgB,GAAGA,CAAA,KAAkB;EACzC,MAAMC,KAAK,GAAG,IAAIC,UAAU,CAACN,gBAAgB,CAAC;EAE9C,KAAK,IAAIO,KAAK,GAAG,CAAC,EAAEA,KAAK,GAAGP,gBAAgB,EAAEO,KAAK,EAAE,EAAE;IACrD,IAAIC,SAAS,GAAGD,KAAK;IAErB,KAAK,IAAIE,GAAG,GAAG,CAAC,EAAEA,GAAG,GAAGR,aAAa,EAAEQ,GAAG,EAAE,EAAE;MAC5C,MAAMC,YAAY,GAAG,CAACF,SAAS,GAAGN,QAAQ,MAAM,CAAC;MAEjDM,SAAS,GAAGE,YAAY,GACpB,CAAEF,SAAS,IAAI,CAAC,GAAIT,eAAe,IAAII,SAAS,GAC/CK,SAAS,IAAI,CAAC,GAAIL,SAAS;IAClC;IAEAE,KAAK,CAACE,KAAK,CAAC,GAAGC,SAAS;EAC1B;EAEA,OAAOH,KAAK;AACd,CAAC;AAED,MAAMM,YAAY,GAAGP,gBAAgB,CAAC,CAAC;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMQ,aAAa,GAAGA,CAACC,GAAa,EAAEC,SAAiB,KAAa;EACzE,IAAIN,SAAS,GAAG,CAAC;EAEjB,KAAK,IAAIO,KAAK,GAAG,CAAC,EAAEA,KAAK,GAAGD,SAAS,EAAEC,KAAK,EAAE,EAAE;IAC9CP,SAAS,GAAGG,YAAY,CAACH,SAAS,GAAGV,SAAS,CAACe,GAAG,CAACE,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;EACzE;EAEA,OAAOP,SAAS;AAClB,CAAC","ignoreList":[]}
@@ -1,6 +1,14 @@
1
1
  "use strict";
2
2
 
3
3
  import { BloodPressureStates } from "../types/blood-pressure-states.js";
4
+
5
+ /**
6
+ * Maps the device's measurement status byte onto a known state.
7
+ *
8
+ * An unrecognised flag reports a device error rather than a regular reading: firmware
9
+ * may report a failure this SDK has not seen, and treating that as a good measurement
10
+ * would publish a reading the device did not vouch for.
11
+ */
4
12
  export const convertBpStateFlag = stateFlag => {
5
13
  switch (stateFlag) {
6
14
  case "00":
@@ -14,7 +22,7 @@ export const convertBpStateFlag = stateFlag => {
14
22
  case "04":
15
23
  return BloodPressureStates.DEVICE_ERROR;
16
24
  default:
17
- return BloodPressureStates.REGULAR;
25
+ return BloodPressureStates.DEVICE_ERROR;
18
26
  }
19
27
  };
20
28
  //# sourceMappingURL=convert-bp-state-flag.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["BloodPressureStates","convertBpStateFlag","stateFlag","REGULAR","LOOSE_SLEEVE","DISTURB_DETECTED","WEAK_SIGNAL","DEVICE_ERROR"],"sourceRoot":"../../../../../src","sources":["modules/bt-management/utils/convert-bp-state-flag.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,mCAAgC;AAEpE,OAAO,MAAMC,kBAAkB,GAAIC,SAAiB,IAA0B;EAC5E,QAAQA,SAAS;IACf,KAAK,IAAI;MACP,OAAOF,mBAAmB,CAACG,OAAO;IACpC,KAAK,IAAI;MACP,OAAOH,mBAAmB,CAACI,YAAY;IACzC,KAAK,IAAI;MACP,OAAOJ,mBAAmB,CAACK,gBAAgB;IAC7C,KAAK,IAAI;MACP,OAAOL,mBAAmB,CAACM,WAAW;IACxC,KAAK,IAAI;MACP,OAAON,mBAAmB,CAACO,YAAY;IACzC;MACE,OAAOP,mBAAmB,CAACG,OAAO;EACtC;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["BloodPressureStates","convertBpStateFlag","stateFlag","REGULAR","LOOSE_SLEEVE","DISTURB_DETECTED","WEAK_SIGNAL","DEVICE_ERROR"],"sourceRoot":"../../../../../src","sources":["modules/bt-management/utils/convert-bp-state-flag.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,mCAAgC;;AAEpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,kBAAkB,GAAIC,SAAiB,IAA0B;EAC5E,QAAQA,SAAS;IACf,KAAK,IAAI;MACP,OAAOF,mBAAmB,CAACG,OAAO;IACpC,KAAK,IAAI;MACP,OAAOH,mBAAmB,CAACI,YAAY;IACzC,KAAK,IAAI;MACP,OAAOJ,mBAAmB,CAACK,gBAAgB;IAC7C,KAAK,IAAI;MACP,OAAOL,mBAAmB,CAACM,WAAW;IACxC,KAAK,IAAI;MACP,OAAON,mBAAmB,CAACO,YAAY;IACzC;MACE,OAAOP,mBAAmB,CAACO,YAAY;EAC3C;AACF,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["hexToByte","le16FromHex","hex","i","lo","hi"],"sourceRoot":"../../../../../src","sources":["modules/bt-management/utils/le-16-from-hex.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,kBAAe;;AAEzC;AACA,OAAO,MAAMC,WAAW,GAAGA,CAACC,GAAa,EAAEC,CAAS,KAAa;EAC/D,MAAMC,EAAE,GAAGJ,SAAS,CAACE,GAAG,CAACC,CAAC,CAAC,IAAI,GAAG,CAAC;EACnC,MAAME,EAAE,GAAGL,SAAS,CAACE,GAAG,CAACC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;EAEvC,OAAOC,EAAE,GAAIC,EAAE,IAAI,CAAE;AACvB,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["hexToByte","le16FromHex","hex","i","lo","hi"],"sourceRoot":"../../../../../src","sources":["modules/bt-management/utils/le-16-from-hex.ts"],"mappings":";;AAAA,SAASA,SAAS,QAAQ,kBAAe;;AAEzC;AACA,OAAO,MAAMC,WAAW,GAAGA,CAACC,GAAsB,EAAEC,CAAS,KAAa;EACxE,MAAMC,EAAE,GAAGJ,SAAS,CAACE,GAAG,CAACC,CAAC,CAAC,IAAI,GAAG,CAAC;EACnC,MAAME,EAAE,GAAGL,SAAS,CAACE,GAAG,CAACC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;EAEvC,OAAOC,EAAE,GAAIC,EAAE,IAAI,CAAE;AACvB,CAAC","ignoreList":[]}
@@ -58,7 +58,17 @@ export const AndroidHealthSync = /*#__PURE__*/React.memo(({
58
58
  }, [onError, onProgress]);
59
59
  React.useEffect(() => {
60
60
  return () => {
61
- serviceRef.current?.stopSync();
61
+ /*
62
+ * A teardown that throws takes the unmount with it, and React has no
63
+ * boundary for a cleanup function — so a sync that fails to stop
64
+ * became a crash on the way out of a screen. The error goes to the
65
+ * app's own handler, which is what `onError` is for.
66
+ */
67
+ try {
68
+ serviceRef.current?.stopSync();
69
+ } catch (error) {
70
+ onErrorRef.current?.(error);
71
+ }
62
72
  serviceRef.current = null;
63
73
  };
64
74
  }, []);
@@ -1 +1 @@
1
- {"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","AndroidHealthSyncService","AndroidHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/android/android-health-sync.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","AndroidHealthSyncService","AndroidHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/android/android-health-sync.tsx"],"mappings":"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","ignoreList":[]}
@@ -40,6 +40,28 @@ export const AppleHealthSync = /*#__PURE__*/React.memo(({
40
40
  onErrorRef.current?.(error);
41
41
  }
42
42
  }, [client, dataToSync, chunkSize, patient?.id, updateProgress]);
43
+
44
+ /**
45
+ * The first sync, which nothing used to start.
46
+ *
47
+ * `useListenChanges` subscribes to HealthKit observer queries, and the
48
+ * native side scopes those to samples that start from NOW —
49
+ * `HKQuery.predicateForSamples(withStart: Date.init(), …)` in
50
+ * `@kingstinct/react-native-healthkit`. So the subscription can never fire
51
+ * for data that already exists, and the only other caller, the network
52
+ * effect below, returns early while `serviceRef.current` is null — which
53
+ * only this path assigns. A patient installed the app, granted HealthKit
54
+ * and saw nothing: their existing history was never read, and nothing new
55
+ * arrived unless they moved with the app open.
56
+ *
57
+ * `startSync` reads the per-code watermark off the server and pages
58
+ * forward from it, so it IS the initial sync; it just had no caller here.
59
+ * `AndroidHealthSync` has had this effect all along — this is the platform
60
+ * catching up with its sibling, not a new mechanism.
61
+ */
62
+ React.useEffect(() => {
63
+ syncData();
64
+ }, [syncData]);
43
65
  useListenChanges(dataToSync, () => {
44
66
  syncData();
45
67
  });
@@ -59,7 +81,17 @@ export const AppleHealthSync = /*#__PURE__*/React.memo(({
59
81
  }, [onError, onProgress]);
60
82
  React.useEffect(() => {
61
83
  return () => {
62
- serviceRef.current?.stopSync();
84
+ /*
85
+ * A teardown that throws takes the unmount with it, and React has no
86
+ * boundary for a cleanup function — so a sync that fails to stop
87
+ * became a crash on the way out of a screen. The error goes to the
88
+ * app's own handler, which is what `onError` is for.
89
+ */
90
+ try {
91
+ serviceRef.current?.stopSync();
92
+ } catch (error) {
93
+ onErrorRef.current?.(error);
94
+ }
63
95
  serviceRef.current = null;
64
96
  };
65
97
  }, []);
@@ -1 +1 @@
1
- {"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","useListenChanges","AppleHealthSyncService","AppleHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/apple/apple-health-sync.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","useListenChanges","AppleHealthSyncService","AppleHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/apple/apple-health-sync.tsx"],"mappings":"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","ignoreList":[]}
@@ -15,7 +15,11 @@ export class BaseHealthSyncService {
15
15
  this.storageManager = new StorageManager(props.client, this.getProviderName());
16
16
  this.dataProcessor = new DataProcessor(props.client, props.patientId, this.getProviderName(), props.chunkSize ?? 5000, this.storageManager, this.getTotalCountsFunction(), this.getDataFromProviderFunction(), this.getConverterFunction());
17
17
  }
18
+ /** One run at a time; see `SyncStateManager.once` for why that matters. */
18
19
  async startSync() {
20
+ return this.stateManager.once(() => this.runSync());
21
+ }
22
+ async runSync() {
19
23
  try {
20
24
  if (!this.client.isInitialized) {
21
25
  this.onSyncError(new Error("Client not initialized"));
@@ -1 +1 @@
1
- {"version":3,"names":["DataProcessor","StorageManager","SyncProgressManager","SyncStateManager","BaseHealthSyncService","constructor","props","client","patientId","dataToSync","onSyncError","progressManager","updateProgress","stateManager","storageManager","getProviderName","dataProcessor","chunkSize","getTotalCountsFunction","getDataFromProviderFunction","getConverterFunction","startSync","isInitialized","Error","resume","setNotStartedStatuses","initialDataFetched","initializeSync","processAllDataTypes","setPauseStatuses","error","stopSync","resetAll","reset","shouldStopSync","pauseSync","pause","latestObservationDates","getLatestObservationDates","calculateTotalCounts","key","Object","keys","measurementTypeKey","data","getDataForMeasurementType","latestValidStartDate","getLatestValidStartDate","totalCount","getTotalRecordsCountForType","setTotalObservations","setStatus","syncDataByType","hasAnchor","observationBodies","currentHasAnchor","getObservationBodiesForType","entries","generateObservationEntries","incrementSyncedObservations","length","result","saveObservations","addResult"],"sourceRoot":"../../../../../src","sources":["modules/data-sync/services/base-health-sync-service.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["DataProcessor","StorageManager","SyncProgressManager","SyncStateManager","BaseHealthSyncService","constructor","props","client","patientId","dataToSync","onSyncError","progressManager","updateProgress","stateManager","storageManager","getProviderName","dataProcessor","chunkSize","getTotalCountsFunction","getDataFromProviderFunction","getConverterFunction","startSync","once","runSync","isInitialized","Error","resume","setNotStartedStatuses","initialDataFetched","initializeSync","processAllDataTypes","setPauseStatuses","error","stopSync","resetAll","reset","shouldStopSync","pauseSync","pause","latestObservationDates","getLatestObservationDates","calculateTotalCounts","key","Object","keys","measurementTypeKey","data","getDataForMeasurementType","latestValidStartDate","getLatestValidStartDate","totalCount","getTotalRecordsCountForType","setTotalObservations","setStatus","syncDataByType","hasAnchor","observationBodies","currentHasAnchor","getObservationBodiesForType","entries","generateObservationEntries","incrementSyncedObservations","length","result","saveObservations","addResult"],"sourceRoot":"../../../../../src","sources":["modules/data-sync/services/base-health-sync-service.ts"],"mappings":"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","ignoreList":[]}
@@ -2,6 +2,25 @@
2
2
 
3
3
  import { saveBundleObservations } from "../../utils/save-bundle-observations.js";
4
4
  export class StorageManager {
5
+ /**
6
+ * Where an anchor goes when the host client has no storage.
7
+ *
8
+ * `clientStorage` is assigned from `OvokClient`'s `storage` option and from
9
+ * nowhere else, so a host that constructs its client without one leaves it
10
+ * `undefined` — and the `?.` below then swallowed every write while
11
+ * `getAnchor` answered `undefined` for ever. That is not a lost
12
+ * optimisation: `getObservationBodiesForType` reports `hasAnchor` from the
13
+ * anchor the provider just returned, and `syncDataByType` loops while it is
14
+ * true. An anchor that never advances means the next read starts from the
15
+ * beginning again, returns the same first chunk and the same anchor, and
16
+ * uploads it — for ever.
17
+ *
18
+ * The sync must not depend on what the host passed. This map keeps the
19
+ * anchor for the life of the service instance, which is what lets the loop
20
+ * end; when the host DOES provide storage the anchor also survives a
21
+ * restart, which is what keeps the next cold start short.
22
+ */
23
+ inMemoryAnchors = new Map();
5
24
  constructor(client, provider) {
6
25
  this.client = client;
7
26
  this.provider = provider;
@@ -13,10 +32,19 @@ export class StorageManager {
13
32
  });
14
33
  }
15
34
  saveAnchor(typeIdentifier, anchor) {
16
- this.client.clientStorage?.setString(`${this.provider}-sync-${typeIdentifier}-anchor`, anchor);
35
+ const key = this.anchorKey(typeIdentifier);
36
+ if (this.client.clientStorage) {
37
+ this.client.clientStorage.setString(key, anchor);
38
+ return;
39
+ }
40
+ this.inMemoryAnchors.set(key, anchor);
17
41
  }
18
42
  getAnchor(typeIdentifier) {
19
- return this.client.clientStorage?.getString(`${this.provider}-sync-${typeIdentifier}-anchor`);
43
+ const key = this.anchorKey(typeIdentifier);
44
+ return this.client.clientStorage ? this.client.clientStorage.getString(key) : this.inMemoryAnchors.get(key);
45
+ }
46
+ anchorKey(typeIdentifier) {
47
+ return `${this.provider}-sync-${typeIdentifier}-anchor`;
20
48
  }
21
49
  saveAnchors(anchors) {
22
50
  anchors.forEach(({
@@ -1 +1 @@
1
- {"version":3,"names":["saveBundleObservations","StorageManager","constructor","client","provider","saveObservations","entries","saveAnchor","typeIdentifier","anchor","clientStorage","setString","getAnchor","getString","saveAnchors","anchors","forEach"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/storage-manager.ts"],"mappings":";;AAIA,SAASA,sBAAsB,QAAQ,yCAAsC;AAE7E,OAAO,MAAMC,cAAc,CAAC;EAC1BC,WAAWA,CACDC,MAAkB,EAClBC,QAAwB,EAChC;IAAA,KAFQD,MAAkB,GAAlBA,MAAkB;IAAA,KAClBC,QAAwB,GAAxBA,QAAwB;EAC/B;EAEH,MAAMC,gBAAgBA,CACpBC,OAAgE,EAClC;IAC9B,OAAON,sBAAsB,CAAC;MAC5BM,OAAO;MACPH,MAAM,EAAE,IAAI,CAACA;IACf,CAAC,CAAC;EACJ;EAEAI,UAAUA,CAACC,cAAsB,EAAEC,MAAc,EAAQ;IACvD,IAAI,CAACN,MAAM,CAACO,aAAa,EAAEC,SAAS,CAClC,GAAG,IAAI,CAACP,QAAQ,SAASI,cAAc,SAAS,EAChDC,MACF,CAAC;EACH;EAEAG,SAASA,CAACJ,cAAsB,EAAsB;IACpD,OAAO,IAAI,CAACL,MAAM,CAACO,aAAa,EAAEG,SAAS,CACzC,GAAG,IAAI,CAACT,QAAQ,SAASI,cAAc,SACzC,CAAC;EACH;EAEAM,WAAWA,CACTC,OAA0D,EACpD;IACNA,OAAO,CAACC,OAAO,CAAC,CAAC;MAAER,cAAc;MAAEC;IAAO,CAAC,KAAK;MAC9C,IAAI,CAACF,UAAU,CAACC,cAAc,EAAEC,MAAM,CAAC;IACzC,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
1
+ {"version":3,"names":["saveBundleObservations","StorageManager","inMemoryAnchors","Map","constructor","client","provider","saveObservations","entries","saveAnchor","typeIdentifier","anchor","key","anchorKey","clientStorage","setString","set","getAnchor","getString","get","saveAnchors","anchors","forEach"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/storage-manager.ts"],"mappings":";;AAIA,SAASA,sBAAsB,QAAQ,yCAAsC;AAE7E,OAAO,MAAMC,cAAc,CAAC;EAC1B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACmBC,eAAe,GAAG,IAAIC,GAAG,CAAiB,CAAC;EAE5DC,WAAWA,CACDC,MAAkB,EAClBC,QAAwB,EAChC;IAAA,KAFQD,MAAkB,GAAlBA,MAAkB;IAAA,KAClBC,QAAwB,GAAxBA,QAAwB;EAC/B;EAEH,MAAMC,gBAAgBA,CACpBC,OAAgE,EAClC;IAC9B,OAAOR,sBAAsB,CAAC;MAC5BQ,OAAO;MACPH,MAAM,EAAE,IAAI,CAACA;IACf,CAAC,CAAC;EACJ;EAEAI,UAAUA,CAACC,cAAsB,EAAEC,MAAc,EAAQ;IACvD,MAAMC,GAAG,GAAG,IAAI,CAACC,SAAS,CAACH,cAAc,CAAC;IAE1C,IAAI,IAAI,CAACL,MAAM,CAACS,aAAa,EAAE;MAC7B,IAAI,CAACT,MAAM,CAACS,aAAa,CAACC,SAAS,CAACH,GAAG,EAAED,MAAM,CAAC;MAEhD;IACF;IAEA,IAAI,CAACT,eAAe,CAACc,GAAG,CAACJ,GAAG,EAAED,MAAM,CAAC;EACvC;EAEAM,SAASA,CAACP,cAAsB,EAAsB;IACpD,MAAME,GAAG,GAAG,IAAI,CAACC,SAAS,CAACH,cAAc,CAAC;IAE1C,OAAO,IAAI,CAACL,MAAM,CAACS,aAAa,GAC5B,IAAI,CAACT,MAAM,CAACS,aAAa,CAACI,SAAS,CAACN,GAAG,CAAC,GACxC,IAAI,CAACV,eAAe,CAACiB,GAAG,CAACP,GAAG,CAAC;EACnC;EAEQC,SAASA,CAACH,cAAsB,EAAU;IAChD,OAAO,GAAG,IAAI,CAACJ,QAAQ,SAASI,cAAc,SAAS;EACzD;EAEAU,WAAWA,CACTC,OAA0D,EACpD;IACNA,OAAO,CAACC,OAAO,CAAC,CAAC;MAAEZ,cAAc;MAAEC;IAAO,CAAC,KAAK;MAC9C,IAAI,CAACF,UAAU,CAACC,cAAc,EAAEC,MAAM,CAAC;IACzC,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
@@ -1,6 +1,17 @@
1
1
  "use strict";
2
2
 
3
3
  export class SyncStateManager {
4
+ /**
5
+ * A sync in flight, so a second caller joins it rather than starting another.
6
+ *
7
+ * There are three callers and they overlap by construction:
8
+ * `InstanceManager.getInstanceInternal` starts one as a side effect of
9
+ * handing back the instance, the component starts one on mount, and the
10
+ * change subscription starts one whenever the provider reports new samples.
11
+ * Two runs over one data type read the same chunk and upload it twice,
12
+ * because the read cursor only advances once a read has returned.
13
+ */
14
+
4
15
  shouldStopSync = false;
5
16
  initialDataFetched = false;
6
17
  latestObservationDates = [];
@@ -8,6 +19,14 @@ export class SyncStateManager {
8
19
  addResult(result) {
9
20
  this.results.push(result);
10
21
  }
22
+
23
+ /** Runs `sync`, or joins the run already under way. */
24
+ async once(sync) {
25
+ this.inFlight ??= sync().finally(() => {
26
+ this.inFlight = undefined;
27
+ });
28
+ return this.inFlight;
29
+ }
11
30
  reset() {
12
31
  this.shouldStopSync = false;
13
32
  this.initialDataFetched = false;
@@ -1 +1 @@
1
- {"version":3,"names":["SyncStateManager","shouldStopSync","initialDataFetched","latestObservationDates","results","addResult","result","push","reset","pause","resume"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/sync-state-manager.ts"],"mappings":";;AAEA,OAAO,MAAMA,gBAAgB,CAAC;EACrBC,cAAc,GAAG,KAAK;EACtBC,kBAAkB,GAAG,KAAK;EAC1BC,sBAAsB,GAGxB,EAAE;EACAC,OAAO,GAA0B,EAAE;EAE1CC,SAASA,CAACC,MAA2B,EAAQ;IAC3C,IAAI,CAACF,OAAO,CAACG,IAAI,CAACD,MAAM,CAAC;EAC3B;EAEAE,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACP,cAAc,GAAG,KAAK;IAC3B,IAAI,CAACC,kBAAkB,GAAG,KAAK;IAC/B,IAAI,CAACC,sBAAsB,GAAG,EAAE;IAChC,IAAI,CAACC,OAAO,GAAG,EAAE;EACnB;EAEAK,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACR,cAAc,GAAG,IAAI;EAC5B;EAEAS,MAAMA,CAAA,EAAS;IACb,IAAI,CAACT,cAAc,GAAG,KAAK;EAC7B;AACF","ignoreList":[]}
1
+ {"version":3,"names":["SyncStateManager","shouldStopSync","initialDataFetched","latestObservationDates","results","addResult","result","push","once","sync","inFlight","finally","undefined","reset","pause","resume"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/sync-state-manager.ts"],"mappings":";;AAEA,OAAO,MAAMA,gBAAgB,CAAC;EAC5B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGSC,cAAc,GAAG,KAAK;EACtBC,kBAAkB,GAAG,KAAK;EAC1BC,sBAAsB,GAGxB,EAAE;EACAC,OAAO,GAA0B,EAAE;EAE1CC,SAASA,CAACC,MAA2B,EAAQ;IAC3C,IAAI,CAACF,OAAO,CAACG,IAAI,CAACD,MAAM,CAAC;EAC3B;;EAEA;EACA,MAAME,IAAIA,CAACC,IAAyB,EAAiB;IACnD,IAAI,CAACC,QAAQ,KAAKD,IAAI,CAAC,CAAC,CAACE,OAAO,CAAC,MAAM;MACrC,IAAI,CAACD,QAAQ,GAAGE,SAAS;IAC3B,CAAC,CAAC;IAEF,OAAO,IAAI,CAACF,QAAQ;EACtB;EAEAG,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACZ,cAAc,GAAG,KAAK;IAC3B,IAAI,CAACC,kBAAkB,GAAG,KAAK;IAC/B,IAAI,CAACC,sBAAsB,GAAG,EAAE;IAChC,IAAI,CAACC,OAAO,GAAG,EAAE;EACnB;EAEAU,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACb,cAAc,GAAG,IAAI;EAC5B;EAEAc,MAAMA,CAAA,EAAS;IACb,IAAI,CAACd,cAAc,GAAG,KAAK;EAC7B;AACF","ignoreList":[]}
@@ -3,6 +3,7 @@ import { IntegratedDevices } from "../../../types/integrated-devices";
3
3
  import { MeasurementWithCaseType } from "../../../types/measurement-with-case-type";
4
4
  import { IService } from "../../../types/service.type";
5
5
  import { BTManagedDevice } from "../bt-managed-device";
6
+ import { BP2FrameReader } from "./bp2.frame-reader";
6
7
  export declare class BP2Device extends BTManagedDevice<IntegratedDevices.BP2> {
7
8
  private collectedValues;
8
9
  private diagramPoints;
@@ -10,7 +11,8 @@ export declare class BP2Device extends BTManagedDevice<IntegratedDevices.BP2> {
10
11
  protected mainServices: IService[];
11
12
  protected stuckDataTimeout: number;
12
13
  protected onStreamStart: () => void;
13
- protected validatePackage: (pkg: string[]) => boolean;
14
+ protected frameReader: BP2FrameReader;
15
+ protected preferredMtu: number;
14
16
  protected handleSuccessResult(successResult: MeasurementWithCaseType<MeasurementTypeForDevices<[IntegratedDevices.BP2]>>, collectedValues: string[]): void | boolean;
15
17
  private handleEcgResult;
16
18
  private handleEcgStream;
@@ -1 +1 @@
1
- {"version":3,"file":"bp2.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bp2/bp2.device.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAIvD,qBAAa,SAAU,SAAQ,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC;IACnE,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAa;IAE7B,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAmB;IACrD,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAS;IAE3C,SAAS,CAAC,aAAa,EAAE,MAAM,IAAI,CAIjC;IAEF,SAAS,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,OAAO,CA4BnD;IAEF,SAAS,CAAC,mBAAmB,CAC3B,aAAa,EAAE,uBAAuB,CACpC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CACnD,EACD,eAAe,EAAE,MAAM,EAAE,GACxB,IAAI,GAAG,OAAO;IA0BjB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,yBAAyB;IAgBjC,OAAO,CAAC,+BAA+B;IAwCvC,OAAO,CAAC,qBAAqB;CAuC9B"}
1
+ {"version":3,"file":"bp2.device.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/modules/bt-management/services/devices/bp2/bp2.device.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AASpD,qBAAa,SAAU,SAAQ,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC;IACnE,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAa;IAE7B,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAmB;IACrD,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAS;IAE3C,SAAS,CAAC,aAAa,EAAE,MAAM,IAAI,CAIjC;IAEF,SAAS,CAAC,WAAW,EAAE,cAAc,CAAwB;IAC7D,SAAS,CAAC,YAAY,EAAE,MAAM,CAAqB;IAEnD,SAAS,CAAC,mBAAmB,CAC3B,aAAa,EAAE,uBAAuB,CACpC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CACnD,EACD,eAAe,EAAE,MAAM,EAAE,GACxB,IAAI,GAAG,OAAO;IA0BjB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,yBAAyB;IAgBjC,OAAO,CAAC,+BAA+B;IAwCvC,OAAO,CAAC,qBAAqB;CAuC9B"}
@@ -0,0 +1,14 @@
1
+ import { FrameReadResult } from "../../../types/frame-read-result";
2
+ import { FrameReader } from "../../../types/frame-reader";
3
+ /**
4
+ * Reads Lepu protocol frames as used by the BP2.
5
+ *
6
+ * Layout: `a5 | cmd | ~cmd | type | seq | lenLow lenHigh | payload | crc8`, where the
7
+ * checksum covers every byte before it. The complement of the command byte only narrows
8
+ * the search for a start; the checksum is what actually decides a frame is trustworthy.
9
+ */
10
+ export declare class BP2FrameReader implements FrameReader {
11
+ readFrame(buffer: readonly string[]): FrameReadResult;
12
+ private hasValidChecksum;
13
+ }
14
+ //# sourceMappingURL=bp2.frame-reader.d.ts.map