@kingstinct/react-native-healthkit 14.0.2 → 15.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +32 -2
  2. package/app.plugin.js +49 -94
  3. package/app.plugin.ts +6 -40
  4. package/ios/BackgroundDeliveryManager.swift +95 -7
  5. package/ios/BackgroundLaunchHook.mm +41 -0
  6. package/ios/Constants.swift +24 -0
  7. package/ios/CoreModule.swift +64 -18
  8. package/ios/ExceptionCatcher.h +1 -0
  9. package/ios/ExceptionCatcher.mm +15 -0
  10. package/ios/Helpers.swift +29 -1
  11. package/ios/MemoryEstimation.swift +83 -0
  12. package/ios/QuantityTypeModule.swift +34 -26
  13. package/ios/Serializers.swift +18 -3
  14. package/ios/SourceProxy.swift +14 -5
  15. package/ios/WorkoutProxy.swift +41 -12
  16. package/lib/commonjs/generated/healthkit.generated.js +13 -1
  17. package/lib/commonjs/healthkit.ios.js +3 -1
  18. package/lib/commonjs/healthkit.js +4 -2
  19. package/lib/module/generated/healthkit.generated.js +12 -0
  20. package/lib/module/healthkit.ios.js +2 -0
  21. package/lib/module/healthkit.js +2 -0
  22. package/lib/typescript/generated/healthkit.generated.d.ts +16 -3
  23. package/lib/typescript/healthkit.d.ts +1 -0
  24. package/lib/typescript/healthkit.ios.d.ts +2 -0
  25. package/lib/typescript/specs/CoreModule.nitro.d.ts +6 -4
  26. package/lib/typescript/specs/SourceProxy.nitro.d.ts +1 -2
  27. package/lib/typescript/types/QuantityType.d.ts +3 -3
  28. package/lib/typescript/types/Source.d.ts +2 -2
  29. package/lib/typescript/types/Workouts.d.ts +1 -0
  30. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +16 -16
  31. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +23 -12
  32. package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +7 -4
  33. package/nitrogen/generated/ios/c++/HybridCorrelationTypeModuleSpecSwift.hpp +7 -4
  34. package/nitrogen/generated/ios/c++/HybridElectrocardiogramModuleSpecSwift.hpp +7 -4
  35. package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +7 -4
  36. package/nitrogen/generated/ios/c++/HybridMedicationModuleSpecSwift.hpp +7 -4
  37. package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +7 -4
  38. package/nitrogen/generated/ios/c++/HybridStateOfMindModuleSpecSwift.hpp +7 -4
  39. package/nitrogen/generated/ios/c++/HybridWorkoutProxySpecSwift.hpp +3 -4
  40. package/nitrogen/generated/ios/c++/HybridWorkoutsModuleSpecSwift.hpp +6 -3
  41. package/nitrogen/generated/ios/swift/CategoryTypeIdentifier.swift +8 -0
  42. package/nitrogen/generated/ios/swift/CategoryTypeIdentifierWriteable.swift +8 -0
  43. package/nitrogen/generated/ios/swift/ObjectTypeIdentifier.swift +8 -0
  44. package/nitrogen/generated/ios/swift/QueryStatisticsResponse.swift +6 -13
  45. package/nitrogen/generated/ios/swift/QueryStatisticsResponseFromSingleSource.swift +4 -11
  46. package/nitrogen/generated/ios/swift/SampleTypeIdentifier.swift +8 -0
  47. package/nitrogen/generated/ios/swift/SampleTypeIdentifierWriteable.swift +8 -0
  48. package/nitrogen/generated/ios/swift/SourceRevision.swift +4 -11
  49. package/nitrogen/generated/ios/swift/WorkoutActivity.swift +7 -2
  50. package/nitrogen/generated/ios/swift/WorkoutActivityType.swift +8 -0
  51. package/nitrogen/generated/shared/c++/CategoryTypeIdentifier.hpp +67 -59
  52. package/nitrogen/generated/shared/c++/CategoryTypeIdentifierWriteable.hpp +67 -59
  53. package/nitrogen/generated/shared/c++/ObjectTypeIdentifier.hpp +202 -194
  54. package/nitrogen/generated/shared/c++/QueryStatisticsResponse.hpp +8 -9
  55. package/nitrogen/generated/shared/c++/QueryStatisticsResponseFromSingleSource.hpp +8 -9
  56. package/nitrogen/generated/shared/c++/SampleTypeIdentifier.hpp +195 -187
  57. package/nitrogen/generated/shared/c++/SampleTypeIdentifierWriteable.hpp +189 -181
  58. package/nitrogen/generated/shared/c++/SourceRevision.hpp +8 -9
  59. package/nitrogen/generated/shared/c++/WorkoutActivity.hpp +9 -3
  60. package/nitrogen/generated/shared/c++/WorkoutActivityType.hpp +4 -0
  61. package/package.json +5 -3
  62. package/src/generated/healthkit-schema.json +50 -5
  63. package/src/generated/healthkit.generated.ts +18 -2
  64. package/src/healthkit.ios.ts +3 -0
  65. package/src/healthkit.ts +5 -0
  66. package/src/specs/CoreModule.nitro.ts +6 -4
  67. package/src/specs/SourceProxy.nitro.ts +1 -1
  68. package/src/type-tests/generated-typing.ts +36 -0
  69. package/src/types/QuantityType.ts +3 -3
  70. package/src/types/Source.ts +2 -2
  71. package/src/types/Workouts.ts +1 -0
@@ -15,3 +15,18 @@ HKUnit * _Nullable HKUnitFromStringCatchingExceptions(NSString * _Nonnull unitSt
15
15
  return nil;
16
16
  }
17
17
  }
18
+
19
+ BOOL RunBlockCatchingObjCExceptions(void (NS_NOESCAPE ^block)(void), NSError * _Nullable * _Nullable outError) {
20
+ if (outError) { *outError = nil; }
21
+ @try {
22
+ block();
23
+ return YES;
24
+ }
25
+ @catch (NSException *exception) {
26
+ if (outError) {
27
+ NSDictionary *userInfo = exception.userInfo ?: @{};
28
+ *outError = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
29
+ }
30
+ return NO;
31
+ }
32
+ }
package/ios/Helpers.swift CHANGED
@@ -172,7 +172,7 @@ func deserializeHKQueryAnchor(base64String: String?) throws -> HKQueryAnchor? {
172
172
  }
173
173
 
174
174
  func initializeCategoryType(_ identifier: String) throws -> HKCategoryType {
175
- let identifier = HKCategoryTypeIdentifier(rawValue: identifier)
175
+ let identifier = hkCategoryTypeIdentifier(fromIdentifierName: identifier)
176
176
  if let sampleType = HKSampleType.categoryType(forIdentifier: identifier) {
177
177
  return sampleType
178
178
  }
@@ -483,3 +483,31 @@ func buildStatisticsOptions(statistics: [StatisticsOptions], quantityType: HKQua
483
483
  }
484
484
  return opts
485
485
  }
486
+
487
+ private let storeReopenRetryDelay: UInt64 = 1_000_000_000
488
+
489
+ /// HealthKit seals its store the moment the device locks and re-opens it a beat
490
+ /// after it unlocks, and iOS can resume the app inside that beat. A query that
491
+ /// hits the gap fails with `errorDatabaseInaccessible` although protected data is
492
+ /// reported available — the store is re-opening, not sealed. Runs `operation`
493
+ /// and, on exactly that refusal, gives it one more attempt after a short delay.
494
+ /// A refusal while protected data is unavailable is the sealed store itself and
495
+ /// is thrown as-is, as is every other error.
496
+ func retryingWhileStoreReopens<T>(
497
+ _ operation: () async throws -> T
498
+ ) async throws -> T {
499
+ do {
500
+ return try await operation()
501
+ } catch {
502
+ let nsError = error as NSError
503
+ guard nsError.domain == HKError.errorDomain,
504
+ nsError.code == HKError.Code.errorDatabaseInaccessible.rawValue
505
+ else { throw error }
506
+ let protectedDataAvailable = await MainActor.run {
507
+ UIApplication.shared.isProtectedDataAvailable
508
+ }
509
+ guard protectedDataAvailable else { throw error }
510
+ try await Task.sleep(nanoseconds: storeReopenRetryDelay)
511
+ return try await operation()
512
+ }
513
+ }
@@ -0,0 +1,83 @@
1
+ //
2
+ // MemoryEstimation.swift
3
+ // Pods
4
+ //
5
+ // Rough estimates of the native heap kept alive by HybridObject proxies,
6
+ // reported to Nitro via `memorySize` so the JS garbage collector can account
7
+ // for memory it cannot see. Precision is not the goal; the right order of
8
+ // magnitude per object is.
9
+ //
10
+
11
+ import HealthKit
12
+
13
+ /// Approximate per-object bridging overhead of a Nitro HybridObject that Nitro
14
+ /// does not account for itself. The generated `*Spec_cxx.swift` adds the Swift
15
+ /// implementation instance via `MemoryHelper.getSizeOf`; this covers the rest:
16
+ /// the Swift `_cxx` bridge class, the C++ `HybridObject` with its per-runtime
17
+ /// cache map, the `shared_ptr` control block and the reference-state records
18
+ /// behind the JS weak reference. Add it once, in each proxy's `memorySize`.
19
+ let nitroHybridObjectOverheadBytes = 512
20
+
21
+ /// Rough size of an `NSString` on the heap, including its object header.
22
+ func estimateStringMemorySize(_ value: String?) -> Int {
23
+ guard let value = value else {
24
+ return 0
25
+ }
26
+ return 32 + value.utf16.count * 2
27
+ }
28
+
29
+ /// Rough size of a `metadata` dictionary as HealthKit keeps it in memory.
30
+ func estimateMetadataMemorySize(_ metadata: [String: Any]?) -> Int {
31
+ guard let metadata = metadata, !metadata.isEmpty else {
32
+ return 0
33
+ }
34
+ // NSDictionary header plus one bucket per entry.
35
+ var total = 64 + metadata.count * 48
36
+ for (key, value) in metadata {
37
+ total += estimateStringMemorySize(key)
38
+ if let string = value as? String {
39
+ total += estimateStringMemorySize(string)
40
+ } else if value is HKQuantity {
41
+ // HKQuantity: object header, unit object, double.
42
+ total += 128
43
+ } else {
44
+ // NSNumber, NSDate and friends are small tagged or boxed objects.
45
+ total += 32
46
+ }
47
+ }
48
+ return total
49
+ }
50
+
51
+ /// Rough size of one `HKStatistics` entry: the object itself plus the
52
+ /// sum/min/max/average/most-recent quantities and their date interval.
53
+ let estimatedStatisticsEntryMemorySize = 512
54
+
55
+ /// Estimate of the `HKWorkout` object graph only; the proxy adds Nitro's
56
+ /// bridging overhead on top.
57
+ func estimateWorkoutMemorySize(_ workout: HKWorkout) -> Int {
58
+ // HKWorkout object, uuid, dates, HKSourceRevision (+HKSource), HKDevice,
59
+ // and the four total quantities.
60
+ var total = 1_024
61
+ total += estimateMetadataMemorySize(workout.metadata)
62
+
63
+ if let events = workout.workoutEvents {
64
+ for event in events {
65
+ // HKWorkoutEvent: object header, type, NSDateInterval.
66
+ total += 128 + estimateMetadataMemorySize(event.metadata)
67
+ }
68
+ }
69
+
70
+ if #available(iOS 16.0, *) {
71
+ total += workout.allStatistics.count * estimatedStatisticsEntryMemorySize
72
+
73
+ for activity in workout.workoutActivities {
74
+ // HKWorkoutActivity: object header, uuid, dates, HKWorkoutConfiguration.
75
+ total += 512
76
+ total += estimateMetadataMemorySize(activity.metadata)
77
+ total += activity.workoutEvents.count * 128
78
+ total += activity.allStatistics.count * estimatedStatisticsEntryMemorySize
79
+ }
80
+ }
81
+
82
+ return total
83
+ }
@@ -53,7 +53,7 @@ func queryStatisticsForQuantityInternal(
53
53
 
54
54
  func serializeStatistics(gottenStats: HKStatistics, unit: HKUnit) -> QueryStatisticsResponse {
55
55
  let sources = gottenStats.sources?.map { source in
56
- return serializeSource(source)
56
+ return serializeSourceStruct(source)
57
57
  } ?? []
58
58
 
59
59
  var averageQuantity: Quantity?
@@ -244,7 +244,7 @@ func serializeStatisticsPerSource(gottenStats: HKStatistics, unit: HKUnit)
244
244
  }
245
245
 
246
246
  return QueryStatisticsResponseFromSingleSource(
247
- source: serializeSource(source),
247
+ source: serializeSourceStruct(source),
248
248
  startDate: gottenStats.startDate,
249
249
  endDate: gottenStats.endDate,
250
250
  duration: duration,
@@ -313,11 +313,13 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
313
313
  return Promise.async {
314
314
  let quantityType = try initializeQuantityType(identifier.stringValue)
315
315
 
316
- if let gottenStats = try await queryStatisticsForQuantityInternal(
317
- quantityType: quantityType,
318
- statistics: statistics,
319
- options: options
320
- ) {
316
+ if let gottenStats = try await retryingWhileStoreReopens({
317
+ try await queryStatisticsForQuantityInternal(
318
+ quantityType: quantityType,
319
+ statistics: statistics,
320
+ options: options
321
+ )
322
+ }) {
321
323
  let unit = try await getUnitToUse(
322
324
  unitOverride: options?.unit,
323
325
  quantityType: quantityType
@@ -336,13 +338,15 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
336
338
  return Promise.async {
337
339
  let quantityType = try initializeQuantityType(identifier.stringValue)
338
340
 
339
- if let statistics = try await queryStatisticsCollectionForQuantityInternal(
340
- quantityType: quantityType,
341
- statistics: statistics,
342
- anchorDate: anchorDate,
343
- intervalComponents: intervalComponents,
344
- options: options
345
- ) {
341
+ if let statistics = try await retryingWhileStoreReopens({
342
+ try await queryStatisticsCollectionForQuantityInternal(
343
+ quantityType: quantityType,
344
+ statistics: statistics,
345
+ anchorDate: anchorDate,
346
+ intervalComponents: intervalComponents,
347
+ options: options
348
+ )
349
+ }) {
346
350
 
347
351
  let unit = try await getUnitToUse(
348
352
  unitOverride: options?.unit,
@@ -385,11 +389,13 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
385
389
  return Promise.async {
386
390
  let quantityType = try initializeQuantityType(identifier.stringValue)
387
391
 
388
- if let gottenStats = try await queryStatisticsForQuantityInternal(
389
- quantityType: quantityType,
390
- statistics: statistics,
391
- options: options
392
- ) {
392
+ if let gottenStats = try await retryingWhileStoreReopens({
393
+ try await queryStatisticsForQuantityInternal(
394
+ quantityType: quantityType,
395
+ statistics: statistics,
396
+ options: options
397
+ )
398
+ }) {
393
399
  let unit = try await getUnitToUse(
394
400
  unitOverride: options?.unit,
395
401
  quantityType: quantityType
@@ -412,13 +418,15 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
412
418
  return Promise.async {
413
419
  let quantityType = try initializeQuantityType(identifier.stringValue)
414
420
 
415
- if let statistics = try await queryStatisticsCollectionForQuantityInternal(
416
- quantityType: quantityType,
417
- statistics: statistics,
418
- anchorDate: anchorDate,
419
- intervalComponents: intervalComponents,
420
- options: options
421
- ) {
421
+ if let statistics = try await retryingWhileStoreReopens({
422
+ try await queryStatisticsCollectionForQuantityInternal(
423
+ quantityType: quantityType,
424
+ statistics: statistics,
425
+ anchorDate: anchorDate,
426
+ intervalComponents: intervalComponents,
427
+ options: options
428
+ )
429
+ }) {
422
430
  let unit = try await getUnitToUse(
423
431
  unitOverride: options?.unit,
424
432
  quantityType: quantityType
@@ -62,7 +62,9 @@ func serializeDeletedSample(sample: HKDeletedObject) -> DeletedSample {
62
62
 
63
63
  func serializeCategorySample(sample: HKCategorySample) -> CategorySample {
64
64
  return CategorySample(
65
- categoryType: CategoryTypeIdentifier(fromString: sample.categoryType.identifier)!,
65
+ categoryType: CategoryTypeIdentifier(
66
+ fromString: categoryTypeIdentifierName(
67
+ fromHealthKitIdentifier: sample.categoryType.identifier))!,
66
68
  value: Double(sample.value),
67
69
  sampleType: serializeSampleType(sample.sampleType),
68
70
  startDate: sample.startDate,
@@ -75,12 +77,23 @@ func serializeCategorySample(sample: HKCategorySample) -> CategorySample {
75
77
  )
76
78
  }
77
79
 
80
+ /// Wraps an `HKSource` in a proxy HybridObject. Only use this where the
81
+ /// caller explicitly asks for a source handle (`querySources`,
82
+ /// `currentAppSource`); everything embedded in serialized values should use
83
+ /// `serializeSourceStruct` so that no per-sample native object is allocated.
78
84
  func serializeSource(_ source: HKSource) -> SourceProxy {
79
85
  return SourceProxy(
80
86
  source: source
81
87
  )
82
88
  }
83
89
 
90
+ func serializeSourceStruct(_ source: HKSource) -> Source {
91
+ return Source(
92
+ name: source.name,
93
+ bundleIdentifier: source.bundleIdentifier
94
+ )
95
+ }
96
+
84
97
  func serializeUnknownQuantityTyped(quantity: HKQuantity?) -> Quantity? {
85
98
  guard let quantity = quantity else {
86
99
  return nil
@@ -290,7 +303,7 @@ func serializeOperatingSystemVersion(_ version: OperatingSystemVersion) -> Strin
290
303
 
291
304
  func serializeSourceRevision(_ hkSourceRevision: HKSourceRevision) -> SourceRevision {
292
305
  return SourceRevision(
293
- source: serializeSource(hkSourceRevision.source),
306
+ source: serializeSourceStruct(hkSourceRevision.source),
294
307
  version: hkSourceRevision.version,
295
308
  operatingSystemVersion: serializeOperatingSystemVersion(
296
309
  hkSourceRevision.operatingSystemVersion),
@@ -300,7 +313,9 @@ func serializeSourceRevision(_ hkSourceRevision: HKSourceRevision) -> SourceRevi
300
313
 
301
314
  func serializeSampleType(_ sampleType: HKSampleType) -> SampleType {
302
315
  return SampleType(
303
- identifier: sampleType.identifier,
316
+ identifier: sampleType is HKCategoryType
317
+ ? categoryTypeIdentifierName(fromHealthKitIdentifier: sampleType.identifier)
318
+ : sampleType.identifier,
304
319
  allowsRecalibrationForEstimates: sampleType.allowsRecalibrationForEstimates,
305
320
  isMinimumDurationRestricted: sampleType.isMinimumDurationRestricted,
306
321
  isMaximumDurationRestricted: sampleType.isMaximumDurationRestricted
@@ -14,11 +14,7 @@ class SourceProxy: HybridSourceProxySpec {
14
14
  warnWithPrefix("SourceProxy does not support toJSON with key: \(key!)")
15
15
  }
16
16
 
17
- return Source(
18
- name: self.name,
19
- bundleIdentifier: self.bundleIdentifier
20
- )
21
-
17
+ return serializeSourceStruct(source)
22
18
  }
23
19
 
24
20
  let source: HKSource
@@ -31,5 +27,18 @@ class SourceProxy: HybridSourceProxySpec {
31
27
  self.source = source
32
28
  self.name = source.name
33
29
  self.bundleIdentifier = source.bundleIdentifier
30
+ // HKSource object with its own name and bundle identifier strings, plus
31
+ // the Swift copies of those strings. Computed once; Nitro reads it on
32
+ // every conversion to JS.
33
+ self.memorySize =
34
+ 128
35
+ + 2 * estimateStringMemorySize(source.name)
36
+ + 2 * estimateStringMemorySize(source.bundleIdentifier)
37
+ + nitroHybridObjectOverheadBytes
34
38
  }
39
+
40
+ /// Estimated heap footprint of the wrapped `HKSource`, reported to Nitro so
41
+ /// the JS garbage collector accounts for the native memory held by each
42
+ /// proxy. Nitro adds the Swift instance's own size on top.
43
+ let memorySize: Int
35
44
  }
@@ -49,38 +49,43 @@ func getWorkoutRoutesInternal(
49
49
 
50
50
  func getRouteLocations(
51
51
  route: HKWorkoutRoute
52
- ) async -> [CLLocation] {
53
- let locations = try! await withCheckedThrowingContinuation {
52
+ ) async throws -> [CLLocation] {
53
+ return try await withCheckedThrowingContinuation {
54
54
  (continuation: CheckedContinuation<[CLLocation], Error>) in
55
55
  var allLocations: [CLLocation] = []
56
+ // HealthKit streams locations in batches through the same handler; make
57
+ // sure the continuation is resumed exactly once whatever the sequence.
58
+ var hasFinished = false
59
+ let finish = { (result: Result<[CLLocation], Error>) in
60
+ guard !hasFinished else {
61
+ return
62
+ }
63
+ hasFinished = true
64
+ continuation.resume(with: result)
65
+ }
56
66
 
57
67
  let query = HKWorkoutRouteQuery(route: route) {
58
68
  (_, locationsOrNil, done, errorOrNil) in
59
69
 
60
70
  DispatchQueue.main.async {
61
71
  if let error = errorOrNil {
62
- continuation.resume(throwing: error)
63
- return
72
+ return finish(.failure(error))
64
73
  }
65
74
 
66
75
  guard let currentLocationBatch = locationsOrNil else {
67
- return continuation.resume(
68
- throwing: runtimeErrorWithPrefix("Unexpected empty response")
69
- )
76
+ return finish(.failure(runtimeErrorWithPrefix("Unexpected empty response")))
70
77
  }
71
78
 
72
79
  allLocations.append(contentsOf: currentLocationBatch)
73
80
 
74
81
  if done {
75
- continuation.resume(returning: allLocations)
82
+ finish(.success(allLocations))
76
83
  }
77
84
  }
78
85
  }
79
86
 
80
87
  store.execute(query)
81
88
  }
82
-
83
- return locations
84
89
  }
85
90
 
86
91
  func serializeLocation(location: CLLocation, previousLocation: CLLocation?)
@@ -122,7 +127,7 @@ func getSerializedWorkoutLocations(
122
127
  route.metadata
123
128
  )
124
129
 
125
- let routeCLLocations = await getRouteLocations(
130
+ let routeCLLocations = try await getRouteLocations(
126
131
  route: route
127
132
  )
128
133
 
@@ -370,11 +375,23 @@ class WorkoutProxy: HybridWorkoutProxySpec {
370
375
  let hkActivities = workout.workoutActivities
371
376
 
372
377
  return hkActivities.map { activity in
378
+ let rawActivityType = activity.workoutConfiguration.activityType.rawValue
379
+ let activityType = Int32(exactly: rawActivityType).flatMap {
380
+ WorkoutActivityType.init(rawValue: $0)
381
+ }
382
+
383
+ if activityType == nil {
384
+ warnWithPrefix(
385
+ "Unknown workoutActivityType with rawValue: \(rawActivityType), falling back to 'other'"
386
+ )
387
+ }
388
+
373
389
  return WorkoutActivity(
374
390
  startDate: activity.startDate,
375
391
  endDate: activity.endDate ?? activity.startDate,
376
392
  uuid: activity.uuid.uuidString,
377
- duration: activity.duration
393
+ duration: activity.duration,
394
+ activityType: activityType ?? WorkoutActivityType.other
378
395
  )
379
396
  }
380
397
  }
@@ -385,8 +402,20 @@ class WorkoutProxy: HybridWorkoutProxySpec {
385
402
 
386
403
  init(workout: HKWorkout) {
387
404
  self.workout = workout
405
+ // Computed here rather than lazily: proxies are created inside
406
+ // `Promise.async` on a background executor, while Nitro reads `memorySize`
407
+ // on the JS thread every time the proxy is converted to a JS object.
408
+ self.memorySize = estimateWorkoutMemorySize(workout) + nitroHybridObjectOverheadBytes
388
409
  }
389
410
 
411
+ /// Estimated heap footprint of the wrapped `HKWorkout` graph (events,
412
+ /// activities, statistics, metadata), reported to Nitro so the JS garbage
413
+ /// collector sees the native memory kept alive by each proxy. Nitro adds
414
+ /// the Swift instance's own size on top. Rough by design: the goal is the
415
+ /// right order of magnitude per workout, so hundreds of proxies from a query
416
+ /// do not look like hundreds of empty objects.
417
+ let memorySize: Int
418
+
390
419
  func getWorkoutPlan() throws -> Promise<WorkoutPlan?> {
391
420
  return Promise.async {
392
421
  if #available(iOS 17.0.0, *) {
@@ -4,7 +4,7 @@
4
4
  * Source: scripts/generate-healthkit.ts
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.WorkoutSwimmingLocationType = exports.WorkoutEventType = exports.WorkoutActivityType = exports.WeatherCondition = exports.WaterSalinity = exports.VO2MaxTestType = exports.UserMotionContext = exports.SwimmingStrokeStyle = exports.PhysicalEffortEstimationType = exports.InsulinDeliveryReason = exports.HeartRateSensorLocation = exports.HeartRateRecoveryTestType = exports.HeartRateMotionContext = exports.DevicePlacementSide = exports.CyclingFunctionalThresholdPowerTestType = exports.CategoryValueVaginalBleeding = exports.CategoryValueSleepAnalysis = exports.CategoryValueSeverity = exports.CategoryValueProgesteroneTestResult = exports.CategoryValuePresence = exports.CategoryValuePregnancyTestResult = exports.CategoryValueOvulationTestResult = exports.CategoryValueMenstrualFlow = exports.CategoryValueLowCardioFitnessEvent = exports.CategoryValueHeadphoneAudioExposureEvent = exports.CategoryValueEnvironmentalAudioExposureEvent = exports.CategoryValueContraceptive = exports.CategoryValueCervicalMucusQuality = exports.CategoryValueAudioExposureEvent = exports.CategoryValueAppleWalkingSteadinessEvent = exports.CategoryValueAppleStandHour = exports.CategoryValueAppetiteChanges = exports.CategoryValue = exports.BodyTemperatureSensorLocation = exports.BloodGlucoseMealTime = exports.AppleECGAlgorithmVersion = exports.CATEGORY_IDENTIFIER_VALUE_ENUMS = exports.QUANTITY_IDENTIFIER_CANONICAL_UNITS = exports.CATEGORY_IDENTIFIER_IOS_AVAILABILITY = exports.QUANTITY_IDENTIFIER_IOS_AVAILABILITY = void 0;
7
+ exports.WorkoutSwimmingLocationType = exports.WorkoutEventType = exports.WorkoutActivityType = exports.WeatherCondition = exports.WaterSalinity = exports.VO2MaxTestType = exports.UserMotionContext = exports.SwimmingStrokeStyle = exports.PhysicalEffortEstimationType = exports.InsulinDeliveryReason = exports.HeartRateSensorLocation = exports.HeartRateRecoveryTestType = exports.HeartRateMotionContext = exports.DevicePlacementSide = exports.CyclingFunctionalThresholdPowerTestType = exports.CategoryValueVaginalBleeding = exports.CategoryValueSleepAnalysis = exports.CategoryValueSeverity = exports.CategoryValueProgesteroneTestResult = exports.CategoryValuePresence = exports.CategoryValuePregnancyTestResult = exports.CategoryValueOvulationTestResult = exports.CategoryValueMenstrualFlow = exports.CategoryValueMenopausalState = exports.CategoryValueLowCardioFitnessEvent = exports.CategoryValueHeadphoneAudioExposureEvent = exports.CategoryValueEnvironmentalAudioExposureEvent = exports.CategoryValueContraceptive = exports.CategoryValueCervicalMucusQuality = exports.CategoryValueAudioExposureEvent = exports.CategoryValueAppleWalkingSteadinessEvent = exports.CategoryValueAppleStandHour = exports.CategoryValueAppetiteChanges = exports.CategoryValue = exports.BodyTemperatureSensorLocation = exports.BloodGlucoseMealTime = exports.AppleECGAlgorithmVersion = exports.CATEGORY_IDENTIFIER_VALUE_ENUMS = exports.QUANTITY_IDENTIFIER_CANONICAL_UNITS = exports.CATEGORY_IDENTIFIER_IOS_AVAILABILITY = exports.QUANTITY_IDENTIFIER_IOS_AVAILABILITY = void 0;
8
8
  exports.QUANTITY_IDENTIFIER_IOS_AVAILABILITY = {
9
9
  HKQuantityTypeIdentifierActiveEnergyBurned: '8.0',
10
10
  HKQuantityTypeIdentifierAppleExerciseTime: '9.3',
@@ -135,6 +135,7 @@ exports.CATEGORY_IDENTIFIER_IOS_AVAILABILITY = {
135
135
  HKCategoryTypeIdentifierAppleWalkingSteadinessEvent: '15.0',
136
136
  HKCategoryTypeIdentifierAudioExposureEvent: '13.0',
137
137
  HKCategoryTypeIdentifierBladderIncontinence: '14.0',
138
+ HKCategoryTypeIdentifierBleedingAfterMenopause: '27.0',
138
139
  HKCategoryTypeIdentifierBleedingAfterPregnancy: '18.0',
139
140
  HKCategoryTypeIdentifierBleedingDuringPregnancy: '18.0',
140
141
  HKCategoryTypeIdentifierBloating: '13.6',
@@ -172,6 +173,7 @@ exports.CATEGORY_IDENTIFIER_IOS_AVAILABILITY = {
172
173
  HKCategoryTypeIdentifierLowerBackPain: '13.6',
173
174
  HKCategoryTypeIdentifierLowHeartRateEvent: '12.2',
174
175
  HKCategoryTypeIdentifierMemoryLapse: '14.0',
176
+ HKCategoryTypeIdentifierMenopausalState: '27.0',
175
177
  HKCategoryTypeIdentifierMenstrualFlow: '9.0',
176
178
  HKCategoryTypeIdentifierMindfulSession: '10.0',
177
179
  HKCategoryTypeIdentifierMoodChanges: '13.6',
@@ -329,6 +331,7 @@ exports.CATEGORY_IDENTIFIER_VALUE_ENUMS = {
329
331
  HKCategoryTypeIdentifierAppleWalkingSteadinessEvent: 'CategoryValueAppleWalkingSteadinessEvent',
330
332
  HKCategoryTypeIdentifierAudioExposureEvent: null,
331
333
  HKCategoryTypeIdentifierBladderIncontinence: 'CategoryValueSeverity',
334
+ HKCategoryTypeIdentifierBleedingAfterMenopause: 'CategoryValueVaginalBleeding',
332
335
  HKCategoryTypeIdentifierBleedingAfterPregnancy: 'CategoryValueVaginalBleeding',
333
336
  HKCategoryTypeIdentifierBleedingDuringPregnancy: 'CategoryValueVaginalBleeding',
334
337
  HKCategoryTypeIdentifierBloating: 'CategoryValueSeverity',
@@ -366,6 +369,7 @@ exports.CATEGORY_IDENTIFIER_VALUE_ENUMS = {
366
369
  HKCategoryTypeIdentifierLowerBackPain: 'CategoryValueSeverity',
367
370
  HKCategoryTypeIdentifierLowHeartRateEvent: 'CategoryValue',
368
371
  HKCategoryTypeIdentifierMemoryLapse: 'CategoryValueSeverity',
372
+ HKCategoryTypeIdentifierMenopausalState: 'CategoryValueMenopausalState',
369
373
  HKCategoryTypeIdentifierMenstrualFlow: 'CategoryValueMenstrualFlow',
370
374
  HKCategoryTypeIdentifierMindfulSession: 'CategoryValue',
371
375
  HKCategoryTypeIdentifierMoodChanges: 'CategoryValuePresence',
@@ -475,6 +479,12 @@ var CategoryValueLowCardioFitnessEvent;
475
479
  (function (CategoryValueLowCardioFitnessEvent) {
476
480
  CategoryValueLowCardioFitnessEvent[CategoryValueLowCardioFitnessEvent["lowFitness"] = 1] = "lowFitness";
477
481
  })(CategoryValueLowCardioFitnessEvent || (exports.CategoryValueLowCardioFitnessEvent = CategoryValueLowCardioFitnessEvent = {}));
482
+ var CategoryValueMenopausalState;
483
+ (function (CategoryValueMenopausalState) {
484
+ CategoryValueMenopausalState[CategoryValueMenopausalState["menopause"] = 1] = "menopause";
485
+ CategoryValueMenopausalState[CategoryValueMenopausalState["perimenopause"] = 2] = "perimenopause";
486
+ CategoryValueMenopausalState[CategoryValueMenopausalState["none"] = 3] = "none";
487
+ })(CategoryValueMenopausalState || (exports.CategoryValueMenopausalState = CategoryValueMenopausalState = {}));
478
488
  var CategoryValueMenstrualFlow;
479
489
  (function (CategoryValueMenstrualFlow) {
480
490
  CategoryValueMenstrualFlow[CategoryValueMenstrualFlow["unspecified"] = 1] = "unspecified";
@@ -724,6 +734,8 @@ var WorkoutActivityType;
724
734
  WorkoutActivityType[WorkoutActivityType["swimBikeRun"] = 82] = "swimBikeRun";
725
735
  WorkoutActivityType[WorkoutActivityType["transition"] = 83] = "transition";
726
736
  WorkoutActivityType[WorkoutActivityType["underwaterDiving"] = 84] = "underwaterDiving";
737
+ WorkoutActivityType[WorkoutActivityType["rest"] = 2998] = "rest";
738
+ WorkoutActivityType[WorkoutActivityType["group"] = 2999] = "group";
727
739
  WorkoutActivityType[WorkoutActivityType["other"] = 3000] = "other";
728
740
  })(WorkoutActivityType || (exports.WorkoutActivityType = WorkoutActivityType = {}));
729
741
  var WorkoutEventType;
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
20
  exports.querySources = exports.queryWorkoutSamplesWithAnchor = exports.queryWorkoutSamples = exports.queryStatisticsCollectionForQuantitySeparateBySource = exports.queryStatisticsForQuantitySeparateBySource = exports.queryStatisticsCollectionForQuantity = exports.queryStatisticsForQuantity = exports.queryQuantitySamplesWithAnchor = exports.queryQuantitySamples = exports.queryElectrocardiogramSamplesWithAnchor = exports.queryElectrocardiogramSamples = exports.queryHeartbeatSeriesSamplesWithAnchor = exports.queryHeartbeatSeriesSamples = exports.queryCorrelationSamplesWithAnchor = exports.queryCorrelationSamples = exports.queryCategorySamplesWithAnchor = exports.queryCategorySamples = exports.isHealthDataAvailableAsync = exports.isHealthDataAvailable = exports.getWheelchairUse = exports.getRequestStatusForAuthorization = exports.getPreferredUnits = exports.getFitzpatrickSkinType = exports.getDateOfBirth = exports.getBloodType = exports.getBiologicalSex = exports.clearBackgroundTypes = exports.configureBackgroundTypes = exports.enableBackgroundDelivery = exports.disableBackgroundDelivery = exports.disableAllBackgroundDelivery = exports.requestPerObjectReadAuthorization = exports.authorizationStatusFor = exports.useSubscribeToQuantitySamples = exports.useSubscribeToChanges = exports.useSubscribeToCategorySamples = exports.useStatisticsForQuantity = exports.useSources = exports.useMostRecentWorkout = exports.useMostRecentQuantitySample = exports.useMostRecentCategorySample = exports.useIsHealthDataAvailable = exports.useHealthkitAuthorization = exports.subscribeToQuantitySamples = exports.subscribeToChanges = exports.subscribeToCategorySamples = exports.getPreferredUnit = exports.getMostRecentWorkout = exports.getMostRecentQuantitySample = exports.getMostRecentCategorySample = void 0;
21
- exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.currentAppSource = exports.queryMedicationEventsWithAnchor = exports.queryMedicationEvents = exports.queryMedications = exports.requestMedicationsAuthorization = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.isQuantityCompatibleWithUnit = exports.saveStateOfMindSample = exports.queryStateOfMindSamplesWithAnchor = exports.queryStateOfMindSamples = exports.isProtectedDataAvailable = exports.startWatchApp = exports.saveWorkoutSample = exports.saveQuantitySample = exports.saveCorrelationSample = exports.saveCategorySample = exports.deleteObjects = exports.requestAuthorization = void 0;
21
+ exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.currentAppSource = exports.queryMedicationEventsWithAnchor = exports.queryMedicationEvents = exports.queryMedications = exports.requestMedicationsAuthorization = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.isQuantityCompatibleWithUnit = exports.saveStateOfMindSample = exports.queryStateOfMindSamplesWithAnchor = exports.queryStateOfMindSamples = exports.isProtectedDataAvailableAsync = exports.isProtectedDataAvailable = exports.startWatchApp = exports.saveWorkoutSample = exports.saveQuantitySample = exports.saveCorrelationSample = exports.saveCategorySample = exports.deleteObjects = exports.requestAuthorization = void 0;
22
22
  const react_native_1 = require("react-native");
23
23
  const useHealthkitAuthorization_1 = __importDefault(require("./hooks/useHealthkitAuthorization"));
24
24
  exports.useHealthkitAuthorization = useHealthkitAuthorization_1.default;
@@ -129,6 +129,7 @@ exports.saveQuantitySample = modules_1.QuantityTypes.saveQuantitySample.bind(mod
129
129
  exports.saveWorkoutSample = WorkoutBindings.saveWorkoutSample;
130
130
  exports.startWatchApp = modules_1.Workouts.startWatchAppWithWorkoutConfiguration.bind(modules_1.Workouts);
131
131
  exports.isProtectedDataAvailable = modules_1.Core.isProtectedDataAvailable.bind(modules_1.Core);
132
+ exports.isProtectedDataAvailableAsync = modules_1.Core.isProtectedDataAvailableAsync.bind(modules_1.Core);
132
133
  exports.queryStateOfMindSamples = StateOfMindBindings.queryStateOfMindSamples;
133
134
  exports.queryStateOfMindSamplesWithAnchor = StateOfMindBindings.queryStateOfMindSamplesWithAnchor;
134
135
  exports.saveStateOfMindSample = StateOfMindBindings.saveStateOfMindSample;
@@ -205,6 +206,7 @@ exports.default = {
205
206
  subscribeToQuantitySamples: subscribeToQuantitySamples_1.subscribeToQuantitySamples,
206
207
  startWatchApp: exports.startWatchApp,
207
208
  isProtectedDataAvailable: exports.isProtectedDataAvailable,
209
+ isProtectedDataAvailableAsync: exports.isProtectedDataAvailableAsync,
208
210
  queryStateOfMindSamples: exports.queryStateOfMindSamples,
209
211
  queryStateOfMindSamplesWithAnchor: exports.queryStateOfMindSamplesWithAnchor,
210
212
  saveStateOfMindSample: exports.saveStateOfMindSample,
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.useStatisticsForQuantity = exports.useSources = exports.useIsHealthDataAvailable = exports.useHealthkitAuthorization = exports.useSubscribeToChanges = exports.useMostRecentWorkout = exports.getMostRecentWorkout = exports.saveStateOfMindSample = exports.queryCorrelationSamplesWithAnchor = exports.queryStateOfMindSamplesWithAnchor = exports.queryStateOfMindSamples = exports.startWatchApp = exports.saveWorkoutSample = exports.queryWorkoutSamplesWithAnchor = exports.queryWorkoutSamples = exports.queryElectrocardiogramSamplesWithAnchor = exports.queryElectrocardiogramSamples = exports.queryHeartbeatSeriesSamplesWithAnchor = exports.queryHeartbeatSeriesSamples = exports.saveCorrelationSample = exports.queryCorrelationSamples = exports.getWheelchairUse = exports.getFitzpatrickSkinType = exports.getDateOfBirth = exports.getBloodType = exports.getBiologicalSex = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.isProtectedDataAvailable = exports.subscribeToChanges = exports.deleteObjects = exports.requestAuthorization = exports.querySources = exports.isHealthDataAvailableAsync = exports.isHealthDataAvailable = exports.getRequestStatusForAuthorization = exports.getPreferredUnits = exports.clearBackgroundTypes = exports.configureBackgroundTypes = exports.enableBackgroundDelivery = exports.disableBackgroundDelivery = exports.disableAllBackgroundDelivery = exports.authorizationStatusFor = void 0;
18
- exports.requestMedicationsAuthorization = exports.subscribeToCategorySamples = exports.requestPerObjectReadAuthorization = exports.useSubscribeToCategorySamples = exports.useSubscribeToQuantitySamples = exports.queryMedicationEventsWithAnchor = exports.queryMedicationEvents = exports.queryMedications = exports.currentAppSource = exports.subscribeToQuantitySamples = void 0;
17
+ exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.useStatisticsForQuantity = exports.useSources = exports.useIsHealthDataAvailable = exports.useHealthkitAuthorization = exports.useSubscribeToChanges = exports.useMostRecentWorkout = exports.getMostRecentWorkout = exports.saveStateOfMindSample = exports.queryCorrelationSamplesWithAnchor = exports.queryStateOfMindSamplesWithAnchor = exports.queryStateOfMindSamples = exports.startWatchApp = exports.saveWorkoutSample = exports.queryWorkoutSamplesWithAnchor = exports.queryWorkoutSamples = exports.queryElectrocardiogramSamplesWithAnchor = exports.queryElectrocardiogramSamples = exports.queryHeartbeatSeriesSamplesWithAnchor = exports.queryHeartbeatSeriesSamples = exports.saveCorrelationSample = exports.queryCorrelationSamples = exports.getWheelchairUse = exports.getFitzpatrickSkinType = exports.getDateOfBirth = exports.getBloodType = exports.getBiologicalSex = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.isProtectedDataAvailableAsync = exports.isProtectedDataAvailable = exports.subscribeToChanges = exports.deleteObjects = exports.requestAuthorization = exports.querySources = exports.isHealthDataAvailableAsync = exports.isHealthDataAvailable = exports.getRequestStatusForAuthorization = exports.getPreferredUnits = exports.clearBackgroundTypes = exports.configureBackgroundTypes = exports.enableBackgroundDelivery = exports.disableBackgroundDelivery = exports.disableAllBackgroundDelivery = exports.authorizationStatusFor = void 0;
18
+ exports.requestMedicationsAuthorization = exports.subscribeToCategorySamples = exports.requestPerObjectReadAuthorization = exports.useSubscribeToCategorySamples = exports.useSubscribeToQuantitySamples = exports.queryMedicationEventsWithAnchor = exports.queryMedicationEvents = exports.queryMedications = exports.currentAppSource = exports.subscribeToQuantitySamples = exports.getWheelchairUseAsync = void 0;
19
19
  exports.queryQuantitySamples = queryQuantitySamples;
20
20
  exports.queryQuantitySamplesWithAnchor = queryQuantitySamplesWithAnchor;
21
21
  exports.queryStatisticsForQuantity = queryStatisticsForQuantity;
@@ -67,6 +67,7 @@ exports.subscribeToChanges = UnavailableFnFromModule('subscribeToChanges', {
67
67
  remove: () => false,
68
68
  }); // Mocking the observer query UUID
69
69
  exports.isProtectedDataAvailable = UnavailableFnFromModule('isProtectedDataAvailable', false);
70
+ exports.isProtectedDataAvailableAsync = UnavailableFnFromModule('isProtectedDataAvailableAsync', Promise.resolve(false));
70
71
  exports.isObjectTypeAvailable = UnavailableFnFromModule('isObjectTypeAvailable', false);
71
72
  exports.isObjectTypeAvailableAsync = UnavailableFnFromModule('isObjectTypeAvailableAsync', Promise.resolve(false));
72
73
  exports.areObjectTypesAvailable = UnavailableFnFromModule('areObjectTypesAvailable', {});
@@ -331,6 +332,7 @@ const HealthkitModule = {
331
332
  subscribeToChanges: exports.subscribeToChanges,
332
333
  startWatchApp: exports.startWatchApp,
333
334
  isProtectedDataAvailable: exports.isProtectedDataAvailable,
335
+ isProtectedDataAvailableAsync: exports.isProtectedDataAvailableAsync,
334
336
  queryStateOfMindSamples: exports.queryStateOfMindSamples,
335
337
  queryStateOfMindSamplesWithAnchor: exports.queryStateOfMindSamplesWithAnchor,
336
338
  saveStateOfMindSample: exports.saveStateOfMindSample,
@@ -132,6 +132,7 @@ export const CATEGORY_IDENTIFIER_IOS_AVAILABILITY = {
132
132
  HKCategoryTypeIdentifierAppleWalkingSteadinessEvent: '15.0',
133
133
  HKCategoryTypeIdentifierAudioExposureEvent: '13.0',
134
134
  HKCategoryTypeIdentifierBladderIncontinence: '14.0',
135
+ HKCategoryTypeIdentifierBleedingAfterMenopause: '27.0',
135
136
  HKCategoryTypeIdentifierBleedingAfterPregnancy: '18.0',
136
137
  HKCategoryTypeIdentifierBleedingDuringPregnancy: '18.0',
137
138
  HKCategoryTypeIdentifierBloating: '13.6',
@@ -169,6 +170,7 @@ export const CATEGORY_IDENTIFIER_IOS_AVAILABILITY = {
169
170
  HKCategoryTypeIdentifierLowerBackPain: '13.6',
170
171
  HKCategoryTypeIdentifierLowHeartRateEvent: '12.2',
171
172
  HKCategoryTypeIdentifierMemoryLapse: '14.0',
173
+ HKCategoryTypeIdentifierMenopausalState: '27.0',
172
174
  HKCategoryTypeIdentifierMenstrualFlow: '9.0',
173
175
  HKCategoryTypeIdentifierMindfulSession: '10.0',
174
176
  HKCategoryTypeIdentifierMoodChanges: '13.6',
@@ -326,6 +328,7 @@ export const CATEGORY_IDENTIFIER_VALUE_ENUMS = {
326
328
  HKCategoryTypeIdentifierAppleWalkingSteadinessEvent: 'CategoryValueAppleWalkingSteadinessEvent',
327
329
  HKCategoryTypeIdentifierAudioExposureEvent: null,
328
330
  HKCategoryTypeIdentifierBladderIncontinence: 'CategoryValueSeverity',
331
+ HKCategoryTypeIdentifierBleedingAfterMenopause: 'CategoryValueVaginalBleeding',
329
332
  HKCategoryTypeIdentifierBleedingAfterPregnancy: 'CategoryValueVaginalBleeding',
330
333
  HKCategoryTypeIdentifierBleedingDuringPregnancy: 'CategoryValueVaginalBleeding',
331
334
  HKCategoryTypeIdentifierBloating: 'CategoryValueSeverity',
@@ -363,6 +366,7 @@ export const CATEGORY_IDENTIFIER_VALUE_ENUMS = {
363
366
  HKCategoryTypeIdentifierLowerBackPain: 'CategoryValueSeverity',
364
367
  HKCategoryTypeIdentifierLowHeartRateEvent: 'CategoryValue',
365
368
  HKCategoryTypeIdentifierMemoryLapse: 'CategoryValueSeverity',
369
+ HKCategoryTypeIdentifierMenopausalState: 'CategoryValueMenopausalState',
366
370
  HKCategoryTypeIdentifierMenstrualFlow: 'CategoryValueMenstrualFlow',
367
371
  HKCategoryTypeIdentifierMindfulSession: 'CategoryValue',
368
372
  HKCategoryTypeIdentifierMoodChanges: 'CategoryValuePresence',
@@ -472,6 +476,12 @@ export var CategoryValueLowCardioFitnessEvent;
472
476
  (function (CategoryValueLowCardioFitnessEvent) {
473
477
  CategoryValueLowCardioFitnessEvent[CategoryValueLowCardioFitnessEvent["lowFitness"] = 1] = "lowFitness";
474
478
  })(CategoryValueLowCardioFitnessEvent || (CategoryValueLowCardioFitnessEvent = {}));
479
+ export var CategoryValueMenopausalState;
480
+ (function (CategoryValueMenopausalState) {
481
+ CategoryValueMenopausalState[CategoryValueMenopausalState["menopause"] = 1] = "menopause";
482
+ CategoryValueMenopausalState[CategoryValueMenopausalState["perimenopause"] = 2] = "perimenopause";
483
+ CategoryValueMenopausalState[CategoryValueMenopausalState["none"] = 3] = "none";
484
+ })(CategoryValueMenopausalState || (CategoryValueMenopausalState = {}));
475
485
  export var CategoryValueMenstrualFlow;
476
486
  (function (CategoryValueMenstrualFlow) {
477
487
  CategoryValueMenstrualFlow[CategoryValueMenstrualFlow["unspecified"] = 1] = "unspecified";
@@ -721,6 +731,8 @@ export var WorkoutActivityType;
721
731
  WorkoutActivityType[WorkoutActivityType["swimBikeRun"] = 82] = "swimBikeRun";
722
732
  WorkoutActivityType[WorkoutActivityType["transition"] = 83] = "transition";
723
733
  WorkoutActivityType[WorkoutActivityType["underwaterDiving"] = 84] = "underwaterDiving";
734
+ WorkoutActivityType[WorkoutActivityType["rest"] = 2998] = "rest";
735
+ WorkoutActivityType[WorkoutActivityType["group"] = 2999] = "group";
724
736
  WorkoutActivityType[WorkoutActivityType["other"] = 3000] = "other";
725
737
  })(WorkoutActivityType || (WorkoutActivityType = {}));
726
738
  export var WorkoutEventType;
@@ -92,6 +92,7 @@ export const saveQuantitySample = QuantityTypes.saveQuantitySample.bind(Quantity
92
92
  export const saveWorkoutSample = WorkoutBindings.saveWorkoutSample;
93
93
  export const startWatchApp = Workouts.startWatchAppWithWorkoutConfiguration.bind(Workouts);
94
94
  export const isProtectedDataAvailable = Core.isProtectedDataAvailable.bind(Core);
95
+ export const isProtectedDataAvailableAsync = Core.isProtectedDataAvailableAsync.bind(Core);
95
96
  export const queryStateOfMindSamples = StateOfMindBindings.queryStateOfMindSamples;
96
97
  export const queryStateOfMindSamplesWithAnchor = StateOfMindBindings.queryStateOfMindSamplesWithAnchor;
97
98
  export const saveStateOfMindSample = StateOfMindBindings.saveStateOfMindSample;
@@ -168,6 +169,7 @@ export default {
168
169
  subscribeToQuantitySamples,
169
170
  startWatchApp,
170
171
  isProtectedDataAvailable,
172
+ isProtectedDataAvailableAsync,
171
173
  queryStateOfMindSamples,
172
174
  queryStateOfMindSamplesWithAnchor,
173
175
  saveStateOfMindSample,