@kingstinct/react-native-healthkit 9.0.11 → 10.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 (43) hide show
  1. package/README.md +1 -1
  2. package/ios/CorrelationTypeModule.swift +1 -0
  3. package/ios/Helpers.swift +50 -6
  4. package/ios/QuantityTypeModule.swift +61 -53
  5. package/ios/WorkoutsModule.swift +10 -9
  6. package/lib/commonjs/healthkit.js +4 -2
  7. package/lib/module/healthkit.js +4 -2
  8. package/lib/typescript/healthkit.d.ts +5 -5
  9. package/lib/typescript/healthkit.ios.d.ts +2 -2
  10. package/lib/typescript/specs/WorkoutsModule.nitro.d.ts +1 -1
  11. package/lib/typescript/types/CorrelationType.d.ts +1 -0
  12. package/lib/typescript/types/QuantityType.d.ts +2 -0
  13. package/lib/typescript/types/QueryOptions.d.ts +4 -0
  14. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +4 -4
  15. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +86 -24
  16. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +3 -0
  17. package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +3 -0
  18. package/nitrogen/generated/ios/c++/HybridCoreModuleSpecSwift.hpp +3 -0
  19. package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +3 -0
  20. package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +3 -0
  21. package/nitrogen/generated/ios/c++/HybridStateOfMindModuleSpecSwift.hpp +3 -0
  22. package/nitrogen/generated/ios/c++/HybridWorkoutsModuleSpecSwift.hpp +9 -6
  23. package/nitrogen/generated/ios/swift/CorrelationSample.swift +13 -2
  24. package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_margelo__nitro__healthkit__HybridWorkoutProxySpec_.swift +50 -0
  25. package/nitrogen/generated/ios/swift/HybridWorkoutsModuleSpec.swift +1 -1
  26. package/nitrogen/generated/ios/swift/HybridWorkoutsModuleSpec_cxx.swift +10 -7
  27. package/nitrogen/generated/ios/swift/PredicateWithMetadataKey.swift +94 -2
  28. package/nitrogen/generated/ios/swift/PredicateWithMetadataOperator.swift +48 -0
  29. package/nitrogen/generated/ios/swift/QueryStatisticsResponse.swift +59 -1
  30. package/nitrogen/generated/ios/swift/Variant_String_Double_Bool_Date.swift +18 -0
  31. package/nitrogen/generated/shared/c++/CorrelationSample.hpp +6 -1
  32. package/nitrogen/generated/shared/c++/HybridWorkoutsModuleSpec.hpp +5 -6
  33. package/nitrogen/generated/shared/c++/PredicateWithMetadataKey.hpp +16 -3
  34. package/nitrogen/generated/shared/c++/PredicateWithMetadataOperator.hpp +86 -0
  35. package/nitrogen/generated/shared/c++/QueryStatisticsResponse.hpp +11 -2
  36. package/package.json +1 -1
  37. package/src/healthkit.ts +7 -2
  38. package/src/hooks/queryStatisticsForQuantity.test.ts +32 -0
  39. package/src/specs/WorkoutsModule.nitro.ts +1 -1
  40. package/src/types/CorrelationType.ts +1 -0
  41. package/src/types/QuantityType.ts +2 -0
  42. package/src/types/QueryOptions.ts +10 -0
  43. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +0 -46
@@ -18,7 +18,7 @@ public extension QueryStatisticsResponse {
18
18
  /**
19
19
  * Create a new instance of `QueryStatisticsResponse`.
20
20
  */
21
- init(averageQuantity: Quantity?, maximumQuantity: Quantity?, minimumQuantity: Quantity?, sumQuantity: Quantity?, mostRecentQuantity: Quantity?, mostRecentQuantityDateInterval: QuantityDateInterval?, duration: Quantity?) {
21
+ init(averageQuantity: Quantity?, maximumQuantity: Quantity?, minimumQuantity: Quantity?, sumQuantity: Quantity?, mostRecentQuantity: Quantity?, mostRecentQuantityDateInterval: QuantityDateInterval?, duration: Quantity?, startDate: Date?, endDate: Date?) {
22
22
  self.init({ () -> bridge.std__optional_Quantity_ in
23
23
  if let __unwrappedValue = averageQuantity {
24
24
  return bridge.create_std__optional_Quantity_(__unwrappedValue)
@@ -61,6 +61,18 @@ public extension QueryStatisticsResponse {
61
61
  } else {
62
62
  return .init()
63
63
  }
64
+ }(), { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
65
+ if let __unwrappedValue = startDate {
66
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
67
+ } else {
68
+ return .init()
69
+ }
70
+ }(), { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
71
+ if let __unwrappedValue = endDate {
72
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
73
+ } else {
74
+ return .init()
75
+ }
64
76
  }())
65
77
  }
66
78
 
@@ -224,4 +236,50 @@ public extension QueryStatisticsResponse {
224
236
  }()
225
237
  }
226
238
  }
239
+
240
+ var startDate: Date? {
241
+ @inline(__always)
242
+ get {
243
+ return { () -> Date? in
244
+ if let __unwrapped = self.__startDate.value {
245
+ return Date(fromChrono: __unwrapped)
246
+ } else {
247
+ return nil
248
+ }
249
+ }()
250
+ }
251
+ @inline(__always)
252
+ set {
253
+ self.__startDate = { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
254
+ if let __unwrappedValue = newValue {
255
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
256
+ } else {
257
+ return .init()
258
+ }
259
+ }()
260
+ }
261
+ }
262
+
263
+ var endDate: Date? {
264
+ @inline(__always)
265
+ get {
266
+ return { () -> Date? in
267
+ if let __unwrapped = self.__endDate.value {
268
+ return Date(fromChrono: __unwrapped)
269
+ } else {
270
+ return nil
271
+ }
272
+ }()
273
+ }
274
+ @inline(__always)
275
+ set {
276
+ self.__endDate = { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
277
+ if let __unwrappedValue = newValue {
278
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
279
+ } else {
280
+ return .init()
281
+ }
282
+ }()
283
+ }
284
+ }
227
285
  }
@@ -0,0 +1,18 @@
1
+ ///
2
+ /// Variant_String_Double_Bool_Date.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2025 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ /**
9
+ * An Swift enum with associated values representing a Variant/Union type.
10
+ * JS type: `string | number | boolean | date`
11
+ */
12
+ @frozen
13
+ public indirect enum Variant_String_Double_Bool_Date {
14
+ case first(String)
15
+ case second(Double)
16
+ case third(Bool)
17
+ case fourth(Date)
18
+ }
@@ -27,6 +27,7 @@ namespace margelo::nitro::healthkit { struct QuantitySample; }
27
27
  // Forward declaration of `AnyMap` to properly resolve imports.
28
28
  namespace NitroModules { class AnyMap; }
29
29
 
30
+ #include <string>
30
31
  #include "CorrelationTypeIdentifier.hpp"
31
32
  #include <vector>
32
33
  #include <variant>
@@ -42,6 +43,7 @@ namespace margelo::nitro::healthkit {
42
43
  */
43
44
  struct CorrelationSample {
44
45
  public:
46
+ std::string uuid SWIFT_PRIVATE;
45
47
  CorrelationTypeIdentifier correlationType SWIFT_PRIVATE;
46
48
  std::vector<std::variant<CategorySample, QuantitySample>> objects SWIFT_PRIVATE;
47
49
  std::shared_ptr<AnyMap> metadata SWIFT_PRIVATE;
@@ -50,7 +52,7 @@ namespace margelo::nitro::healthkit {
50
52
 
51
53
  public:
52
54
  CorrelationSample() = default;
53
- explicit CorrelationSample(CorrelationTypeIdentifier correlationType, std::vector<std::variant<CategorySample, QuantitySample>> objects, std::shared_ptr<AnyMap> metadata, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate): correlationType(correlationType), objects(objects), metadata(metadata), startDate(startDate), endDate(endDate) {}
55
+ explicit CorrelationSample(std::string uuid, CorrelationTypeIdentifier correlationType, std::vector<std::variant<CategorySample, QuantitySample>> objects, std::shared_ptr<AnyMap> metadata, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate): uuid(uuid), correlationType(correlationType), objects(objects), metadata(metadata), startDate(startDate), endDate(endDate) {}
54
56
  };
55
57
 
56
58
  } // namespace margelo::nitro::healthkit
@@ -65,6 +67,7 @@ namespace margelo::nitro {
65
67
  static inline CorrelationSample fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
66
68
  jsi::Object obj = arg.asObject(runtime);
67
69
  return CorrelationSample(
70
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "uuid")),
68
71
  JSIConverter<CorrelationTypeIdentifier>::fromJSI(runtime, obj.getProperty(runtime, "correlationType")),
69
72
  JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::fromJSI(runtime, obj.getProperty(runtime, "objects")),
70
73
  JSIConverter<std::shared_ptr<AnyMap>>::fromJSI(runtime, obj.getProperty(runtime, "metadata")),
@@ -74,6 +77,7 @@ namespace margelo::nitro {
74
77
  }
75
78
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const CorrelationSample& arg) {
76
79
  jsi::Object obj(runtime);
80
+ obj.setProperty(runtime, "uuid", JSIConverter<std::string>::toJSI(runtime, arg.uuid));
77
81
  obj.setProperty(runtime, "correlationType", JSIConverter<CorrelationTypeIdentifier>::toJSI(runtime, arg.correlationType));
78
82
  obj.setProperty(runtime, "objects", JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::toJSI(runtime, arg.objects));
79
83
  obj.setProperty(runtime, "metadata", JSIConverter<std::shared_ptr<AnyMap>>::toJSI(runtime, arg.metadata));
@@ -86,6 +90,7 @@ namespace margelo::nitro {
86
90
  return false;
87
91
  }
88
92
  jsi::Object obj = value.getObject(runtime);
93
+ if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "uuid"))) return false;
89
94
  if (!JSIConverter<CorrelationTypeIdentifier>::canConvert(runtime, obj.getProperty(runtime, "correlationType"))) return false;
90
95
  if (!JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::canConvert(runtime, obj.getProperty(runtime, "objects"))) return false;
91
96
  if (!JSIConverter<std::shared_ptr<AnyMap>>::canConvert(runtime, obj.getProperty(runtime, "metadata"))) return false;
@@ -13,6 +13,8 @@
13
13
  #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
14
  #endif
15
15
 
16
+ // Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
17
+ namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
16
18
  // Forward declaration of `WorkoutActivityType` to properly resolve imports.
17
19
  namespace margelo::nitro::healthkit { enum class WorkoutActivityType; }
18
20
  // Forward declaration of `QuantitySampleForSaving` to properly resolve imports.
@@ -25,15 +27,14 @@ namespace NitroModules { class AnyMap; }
25
27
  namespace margelo::nitro::healthkit { struct QueryWorkoutSamplesWithAnchorResponse; }
26
28
  // Forward declaration of `WorkoutQueryOptionsWithAnchor` to properly resolve imports.
27
29
  namespace margelo::nitro::healthkit { struct WorkoutQueryOptionsWithAnchor; }
28
- // Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
29
- namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
30
30
  // Forward declaration of `WorkoutQueryOptions` to properly resolve imports.
31
31
  namespace margelo::nitro::healthkit { struct WorkoutQueryOptions; }
32
32
  // Forward declaration of `WorkoutConfiguration` to properly resolve imports.
33
33
  namespace margelo::nitro::healthkit { struct WorkoutConfiguration; }
34
34
 
35
35
  #include <NitroModules/Promise.hpp>
36
- #include <string>
36
+ #include <memory>
37
+ #include "HybridWorkoutProxySpec.hpp"
37
38
  #include "WorkoutActivityType.hpp"
38
39
  #include <vector>
39
40
  #include "QuantitySampleForSaving.hpp"
@@ -42,8 +43,6 @@ namespace margelo::nitro::healthkit { struct WorkoutConfiguration; }
42
43
  #include <NitroModules/AnyMap.hpp>
43
44
  #include "QueryWorkoutSamplesWithAnchorResponse.hpp"
44
45
  #include "WorkoutQueryOptionsWithAnchor.hpp"
45
- #include <memory>
46
- #include "HybridWorkoutProxySpec.hpp"
47
46
  #include "WorkoutQueryOptions.hpp"
48
47
  #include "WorkoutConfiguration.hpp"
49
48
 
@@ -78,7 +77,7 @@ namespace margelo::nitro::healthkit {
78
77
 
79
78
  public:
80
79
  // Methods
81
- virtual std::shared_ptr<Promise<std::string>> saveWorkoutSample(WorkoutActivityType workoutActivityType, const std::vector<QuantitySampleForSaving>& quantities, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate, const WorkoutTotals& totals, const std::shared_ptr<AnyMap>& metadata) = 0;
80
+ virtual std::shared_ptr<Promise<std::shared_ptr<margelo::nitro::healthkit::HybridWorkoutProxySpec>>> saveWorkoutSample(WorkoutActivityType workoutActivityType, const std::vector<QuantitySampleForSaving>& quantities, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate, const WorkoutTotals& totals, const std::shared_ptr<AnyMap>& metadata) = 0;
82
81
  virtual std::shared_ptr<Promise<QueryWorkoutSamplesWithAnchorResponse>> queryWorkoutSamplesWithAnchor(const WorkoutQueryOptionsWithAnchor& options) = 0;
83
82
  virtual std::shared_ptr<Promise<std::vector<std::shared_ptr<margelo::nitro::healthkit::HybridWorkoutProxySpec>>>> queryWorkoutSamples(const WorkoutQueryOptions& options) = 0;
84
83
  virtual std::shared_ptr<Promise<bool>> startWatchAppWithWorkoutConfiguration(const WorkoutConfiguration& workoutConfiguration) = 0;
@@ -18,9 +18,14 @@
18
18
  #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
19
  #endif
20
20
 
21
-
21
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
22
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
22
23
 
23
24
  #include <string>
25
+ #include <optional>
26
+ #include "PredicateWithMetadataOperator.hpp"
27
+ #include <variant>
28
+ #include <chrono>
24
29
 
25
30
  namespace margelo::nitro::healthkit {
26
31
 
@@ -30,10 +35,12 @@ namespace margelo::nitro::healthkit {
30
35
  struct PredicateWithMetadataKey {
31
36
  public:
32
37
  std::string withMetadataKey SWIFT_PRIVATE;
38
+ std::optional<PredicateWithMetadataOperator> operatorType SWIFT_PRIVATE;
39
+ std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>> value SWIFT_PRIVATE;
33
40
 
34
41
  public:
35
42
  PredicateWithMetadataKey() = default;
36
- explicit PredicateWithMetadataKey(std::string withMetadataKey): withMetadataKey(withMetadataKey) {}
43
+ explicit PredicateWithMetadataKey(std::string withMetadataKey, std::optional<PredicateWithMetadataOperator> operatorType, std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>> value): withMetadataKey(withMetadataKey), operatorType(operatorType), value(value) {}
37
44
  };
38
45
 
39
46
  } // namespace margelo::nitro::healthkit
@@ -48,12 +55,16 @@ namespace margelo::nitro {
48
55
  static inline PredicateWithMetadataKey fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
49
56
  jsi::Object obj = arg.asObject(runtime);
50
57
  return PredicateWithMetadataKey(
51
- JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "withMetadataKey"))
58
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "withMetadataKey")),
59
+ JSIConverter<std::optional<PredicateWithMetadataOperator>>::fromJSI(runtime, obj.getProperty(runtime, "operatorType")),
60
+ JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::fromJSI(runtime, obj.getProperty(runtime, "value"))
52
61
  );
53
62
  }
54
63
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const PredicateWithMetadataKey& arg) {
55
64
  jsi::Object obj(runtime);
56
65
  obj.setProperty(runtime, "withMetadataKey", JSIConverter<std::string>::toJSI(runtime, arg.withMetadataKey));
66
+ obj.setProperty(runtime, "operatorType", JSIConverter<std::optional<PredicateWithMetadataOperator>>::toJSI(runtime, arg.operatorType));
67
+ obj.setProperty(runtime, "value", JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::toJSI(runtime, arg.value));
57
68
  return obj;
58
69
  }
59
70
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -62,6 +73,8 @@ namespace margelo::nitro {
62
73
  }
63
74
  jsi::Object obj = value.getObject(runtime);
64
75
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "withMetadataKey"))) return false;
76
+ if (!JSIConverter<std::optional<PredicateWithMetadataOperator>>::canConvert(runtime, obj.getProperty(runtime, "operatorType"))) return false;
77
+ if (!JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::canConvert(runtime, obj.getProperty(runtime, "value"))) return false;
65
78
  return true;
66
79
  }
67
80
  };
@@ -0,0 +1,86 @@
1
+ ///
2
+ /// PredicateWithMetadataOperator.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2025 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/NitroHash.hpp>)
11
+ #include <NitroModules/NitroHash.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
16
+ #include <NitroModules/JSIConverter.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
21
+ #include <NitroModules/NitroDefines.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+
26
+ namespace margelo::nitro::healthkit {
27
+
28
+ /**
29
+ * An enum which can be represented as a JavaScript union (PredicateWithMetadataOperator).
30
+ */
31
+ enum class PredicateWithMetadataOperator {
32
+ EQUALTO SWIFT_NAME(equalto) = 0,
33
+ NOTEQUALTO SWIFT_NAME(notequalto) = 1,
34
+ GREATERTHAN SWIFT_NAME(greaterthan) = 2,
35
+ LESSTHAN SWIFT_NAME(lessthan) = 3,
36
+ } CLOSED_ENUM;
37
+
38
+ } // namespace margelo::nitro::healthkit
39
+
40
+ namespace margelo::nitro {
41
+
42
+ using namespace margelo::nitro::healthkit;
43
+
44
+ // C++ PredicateWithMetadataOperator <> JS PredicateWithMetadataOperator (union)
45
+ template <>
46
+ struct JSIConverter<PredicateWithMetadataOperator> final {
47
+ static inline PredicateWithMetadataOperator fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
48
+ std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
49
+ switch (hashString(unionValue.c_str(), unionValue.size())) {
50
+ case hashString("equalTo"): return PredicateWithMetadataOperator::EQUALTO;
51
+ case hashString("notEqualTo"): return PredicateWithMetadataOperator::NOTEQUALTO;
52
+ case hashString("greaterThan"): return PredicateWithMetadataOperator::GREATERTHAN;
53
+ case hashString("lessThan"): return PredicateWithMetadataOperator::LESSTHAN;
54
+ default: [[unlikely]]
55
+ throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum PredicateWithMetadataOperator - invalid value!");
56
+ }
57
+ }
58
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, PredicateWithMetadataOperator arg) {
59
+ switch (arg) {
60
+ case PredicateWithMetadataOperator::EQUALTO: return JSIConverter<std::string>::toJSI(runtime, "equalTo");
61
+ case PredicateWithMetadataOperator::NOTEQUALTO: return JSIConverter<std::string>::toJSI(runtime, "notEqualTo");
62
+ case PredicateWithMetadataOperator::GREATERTHAN: return JSIConverter<std::string>::toJSI(runtime, "greaterThan");
63
+ case PredicateWithMetadataOperator::LESSTHAN: return JSIConverter<std::string>::toJSI(runtime, "lessThan");
64
+ default: [[unlikely]]
65
+ throw std::invalid_argument("Cannot convert PredicateWithMetadataOperator to JS - invalid value: "
66
+ + std::to_string(static_cast<int>(arg)) + "!");
67
+ }
68
+ }
69
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
70
+ if (!value.isString()) {
71
+ return false;
72
+ }
73
+ std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
74
+ switch (hashString(unionValue.c_str(), unionValue.size())) {
75
+ case hashString("equalTo"):
76
+ case hashString("notEqualTo"):
77
+ case hashString("greaterThan"):
78
+ case hashString("lessThan"):
79
+ return true;
80
+ default:
81
+ return false;
82
+ }
83
+ }
84
+ };
85
+
86
+ } // namespace margelo::nitro
@@ -26,6 +26,7 @@ namespace margelo::nitro::healthkit { struct QuantityDateInterval; }
26
26
  #include <optional>
27
27
  #include "Quantity.hpp"
28
28
  #include "QuantityDateInterval.hpp"
29
+ #include <chrono>
29
30
 
30
31
  namespace margelo::nitro::healthkit {
31
32
 
@@ -41,10 +42,12 @@ namespace margelo::nitro::healthkit {
41
42
  std::optional<Quantity> mostRecentQuantity SWIFT_PRIVATE;
42
43
  std::optional<QuantityDateInterval> mostRecentQuantityDateInterval SWIFT_PRIVATE;
43
44
  std::optional<Quantity> duration SWIFT_PRIVATE;
45
+ std::optional<std::chrono::system_clock::time_point> startDate SWIFT_PRIVATE;
46
+ std::optional<std::chrono::system_clock::time_point> endDate SWIFT_PRIVATE;
44
47
 
45
48
  public:
46
49
  QueryStatisticsResponse() = default;
47
- explicit QueryStatisticsResponse(std::optional<Quantity> averageQuantity, std::optional<Quantity> maximumQuantity, std::optional<Quantity> minimumQuantity, std::optional<Quantity> sumQuantity, std::optional<Quantity> mostRecentQuantity, std::optional<QuantityDateInterval> mostRecentQuantityDateInterval, std::optional<Quantity> duration): averageQuantity(averageQuantity), maximumQuantity(maximumQuantity), minimumQuantity(minimumQuantity), sumQuantity(sumQuantity), mostRecentQuantity(mostRecentQuantity), mostRecentQuantityDateInterval(mostRecentQuantityDateInterval), duration(duration) {}
50
+ explicit QueryStatisticsResponse(std::optional<Quantity> averageQuantity, std::optional<Quantity> maximumQuantity, std::optional<Quantity> minimumQuantity, std::optional<Quantity> sumQuantity, std::optional<Quantity> mostRecentQuantity, std::optional<QuantityDateInterval> mostRecentQuantityDateInterval, std::optional<Quantity> duration, std::optional<std::chrono::system_clock::time_point> startDate, std::optional<std::chrono::system_clock::time_point> endDate): averageQuantity(averageQuantity), maximumQuantity(maximumQuantity), minimumQuantity(minimumQuantity), sumQuantity(sumQuantity), mostRecentQuantity(mostRecentQuantity), mostRecentQuantityDateInterval(mostRecentQuantityDateInterval), duration(duration), startDate(startDate), endDate(endDate) {}
48
51
  };
49
52
 
50
53
  } // namespace margelo::nitro::healthkit
@@ -65,7 +68,9 @@ namespace margelo::nitro {
65
68
  JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "sumQuantity")),
66
69
  JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "mostRecentQuantity")),
67
70
  JSIConverter<std::optional<QuantityDateInterval>>::fromJSI(runtime, obj.getProperty(runtime, "mostRecentQuantityDateInterval")),
68
- JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "duration"))
71
+ JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "duration")),
72
+ JSIConverter<std::optional<std::chrono::system_clock::time_point>>::fromJSI(runtime, obj.getProperty(runtime, "startDate")),
73
+ JSIConverter<std::optional<std::chrono::system_clock::time_point>>::fromJSI(runtime, obj.getProperty(runtime, "endDate"))
69
74
  );
70
75
  }
71
76
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const QueryStatisticsResponse& arg) {
@@ -77,6 +82,8 @@ namespace margelo::nitro {
77
82
  obj.setProperty(runtime, "mostRecentQuantity", JSIConverter<std::optional<Quantity>>::toJSI(runtime, arg.mostRecentQuantity));
78
83
  obj.setProperty(runtime, "mostRecentQuantityDateInterval", JSIConverter<std::optional<QuantityDateInterval>>::toJSI(runtime, arg.mostRecentQuantityDateInterval));
79
84
  obj.setProperty(runtime, "duration", JSIConverter<std::optional<Quantity>>::toJSI(runtime, arg.duration));
85
+ obj.setProperty(runtime, "startDate", JSIConverter<std::optional<std::chrono::system_clock::time_point>>::toJSI(runtime, arg.startDate));
86
+ obj.setProperty(runtime, "endDate", JSIConverter<std::optional<std::chrono::system_clock::time_point>>::toJSI(runtime, arg.endDate));
80
87
  return obj;
81
88
  }
82
89
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -91,6 +98,8 @@ namespace margelo::nitro {
91
98
  if (!JSIConverter<std::optional<Quantity>>::canConvert(runtime, obj.getProperty(runtime, "mostRecentQuantity"))) return false;
92
99
  if (!JSIConverter<std::optional<QuantityDateInterval>>::canConvert(runtime, obj.getProperty(runtime, "mostRecentQuantityDateInterval"))) return false;
93
100
  if (!JSIConverter<std::optional<Quantity>>::canConvert(runtime, obj.getProperty(runtime, "duration"))) return false;
101
+ if (!JSIConverter<std::optional<std::chrono::system_clock::time_point>>::canConvert(runtime, obj.getProperty(runtime, "startDate"))) return false;
102
+ if (!JSIConverter<std::optional<std::chrono::system_clock::time_point>>::canConvert(runtime, obj.getProperty(runtime, "endDate"))) return false;
94
103
  return true;
95
104
  }
96
105
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kingstinct/react-native-healthkit",
3
- "version": "9.0.11",
3
+ "version": "10.1.0",
4
4
  "description": "React Native bindings for HealthKit",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
package/src/healthkit.ts CHANGED
@@ -21,7 +21,10 @@ import {
21
21
  WheelchairUse,
22
22
  } from './types/Characteristics'
23
23
  import type { QuantitySample } from './types/QuantitySample'
24
- import type { QueryOptionsWithAnchor } from './types/QueryOptions'
24
+ import type {
25
+ QueryOptionsWithAnchor,
26
+ QueryOptionsWithSortOrder,
27
+ } from './types/QueryOptions'
25
28
 
26
29
  export * from './types'
27
30
 
@@ -174,6 +177,7 @@ export const isQuantityCompatibleWithUnit = UnavailableFnFromModule(
174
177
  // CategoryTypeModule functions
175
178
  export function queryCategorySamples<T extends CategoryTypeIdentifier>(
176
179
  _categoryTypeIdentifier: T,
180
+ _options?: QueryOptionsWithSortOrder,
177
181
  ): Promise<CategorySampleTyped<T>[]> {
178
182
  if (Platform.OS !== 'ios' && !hasWarned) {
179
183
  console.warn(notAvailableError)
@@ -242,7 +246,8 @@ export const queryWorkoutSamplesWithAnchor = UnavailableFnFromModule(
242
246
  )
243
247
  export const saveWorkoutSample = UnavailableFnFromModule(
244
248
  'saveWorkoutSample',
245
- Promise.resolve(''),
249
+ // biome-ignore lint/suspicious/noExplicitAny: it works
250
+ Promise.resolve(undefined as any as WorkoutProxy),
246
251
  )
247
252
  export const startWatchApp = UnavailableFnFromModule(
248
253
  'startWatchApp',
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Test case to verify that queryStatisticsForQuantity resolves when no data is present
3
+ */
4
+
5
+ import { describe, expect, test } from 'bun:test'
6
+ import type { QueryStatisticsResponse } from '../types/QuantityType'
7
+
8
+ describe('queryStatisticsForQuantity', () => {
9
+ test('should resolve with empty response when no data is present', async () => {
10
+ // This test would normally require running on iOS simulator or device
11
+ // For now, we're just testing the TypeScript interface
12
+
13
+ const mockEmptyResponse: QueryStatisticsResponse = {}
14
+
15
+ // Verify that empty response is properly typed
16
+ expect(mockEmptyResponse.averageQuantity).toBeUndefined()
17
+ expect(mockEmptyResponse.sumQuantity).toBeUndefined()
18
+ expect(mockEmptyResponse.startDate).toBeUndefined()
19
+ expect(mockEmptyResponse.endDate).toBeUndefined()
20
+ })
21
+
22
+ test('should handle date range with no data', async () => {
23
+ // This is more of a documentation of the expected behavior
24
+ // The query should resolve with an empty response object
25
+ // when there's no data in the specified timeframe
26
+ const expectedResult: QueryStatisticsResponse = {
27
+ // All properties should be undefined for empty result
28
+ }
29
+
30
+ expect(expectedResult).toBeDefined()
31
+ })
32
+ })
@@ -18,7 +18,7 @@ export interface WorkoutsModule extends HybridObject<{ ios: 'swift' }> {
18
18
  endDate: Date,
19
19
  totals: WorkoutTotals,
20
20
  metadata: AnyMap,
21
- ): Promise<string>
21
+ ): Promise<WorkoutProxy>
22
22
 
23
23
  queryWorkoutSamplesWithAnchor(
24
24
  options: WorkoutQueryOptionsWithAnchor,
@@ -13,6 +13,7 @@ export type CorrelationTypeIdentifier =
13
13
  type CorrelationObject = CategorySample | QuantitySample
14
14
 
15
15
  export interface CorrelationSample {
16
+ readonly uuid: string
16
17
  readonly correlationType: CorrelationTypeIdentifier
17
18
  readonly objects: readonly CorrelationObject[]
18
19
  readonly metadata: AnyMap
@@ -28,6 +28,8 @@ export interface QueryStatisticsResponse {
28
28
  readonly mostRecentQuantity?: Quantity
29
29
  readonly mostRecentQuantityDateInterval?: QuantityDateInterval
30
30
  readonly duration?: Quantity
31
+ readonly startDate?: Date
32
+ readonly endDate?: Date
31
33
  }
32
34
 
33
35
  export interface QuantitySamplesWithAnchorResponse {
@@ -15,8 +15,18 @@ type PredicateWithStartAndEnd = {
15
15
  readonly strictStartDate?: boolean
16
16
  }
17
17
 
18
+ type PredicateWithMetadataOperator =
19
+ | 'equalTo'
20
+ | 'notEqualTo'
21
+ | 'greaterThan'
22
+ | 'lessThan'
23
+
24
+ type PredicateWithMetadataValue = string | number | Date | boolean
25
+
18
26
  type PredicateWithMetadataKey = {
19
27
  readonly withMetadataKey: string
28
+ readonly operatorType?: PredicateWithMetadataOperator
29
+ readonly value?: PredicateWithMetadataValue
20
30
  }
21
31
 
22
32
  export type FilterForSamplesAnd = {
@@ -1,46 +0,0 @@
1
- ///
2
- /// Func_void_std__string.swift
3
- /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
- /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
6
- ///
7
-
8
- import NitroModules
9
-
10
- /**
11
- * Wraps a Swift `(_ value: String) -> Void` as a class.
12
- * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.
13
- */
14
- public final class Func_void_std__string {
15
- public typealias bridge = margelo.nitro.healthkit.bridge.swift
16
-
17
- private let closure: (_ value: String) -> Void
18
-
19
- public init(_ closure: @escaping (_ value: String) -> Void) {
20
- self.closure = closure
21
- }
22
-
23
- @inline(__always)
24
- public func call(value: std.string) -> Void {
25
- self.closure(String(value))
26
- }
27
-
28
- /**
29
- * Casts this instance to a retained unsafe raw pointer.
30
- * This acquires one additional strong reference on the object!
31
- */
32
- @inline(__always)
33
- public func toUnsafe() -> UnsafeMutableRawPointer {
34
- return Unmanaged.passRetained(self).toOpaque()
35
- }
36
-
37
- /**
38
- * Casts an unsafe pointer to a `Func_void_std__string`.
39
- * The pointer has to be a retained opaque `Unmanaged<Func_void_std__string>`.
40
- * This removes one strong reference from the object!
41
- */
42
- @inline(__always)
43
- public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_std__string {
44
- return Unmanaged<Func_void_std__string>.fromOpaque(pointer).takeRetainedValue()
45
- }
46
- }