@cariva-dev/exercise-sdk 2.0.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 (82) hide show
  1. package/CarivaExerciseSdk.podspec +20 -0
  2. package/README.md +374 -0
  3. package/android/build.gradle +66 -0
  4. package/android/src/main/AndroidManifest.xml +40 -0
  5. package/android/src/main/java/com/carivaexercisesdk/CarivaExerciseSdkPackage.kt +30 -0
  6. package/android/src/main/java/com/carivaexercisesdk/HealthConnectModule.kt +222 -0
  7. package/android/src/main/java/com/carivaexercisesdk/HealthConnectPermissionUsageActivity.kt +11 -0
  8. package/android/src/main/java/com/carivaexercisesdk/HealthConnectPermissionsRationaleActivity.kt +11 -0
  9. package/android/src/main/java/com/carivaexercisesdk/Pagination.kt +23 -0
  10. package/android/src/main/java/com/carivaexercisesdk/application/connection/command/ConnectCommand.kt +12 -0
  11. package/android/src/main/java/com/carivaexercisesdk/application/connection/dto/ConnectResultDto.kt +13 -0
  12. package/android/src/main/java/com/carivaexercisesdk/application/connection/handler/ConnectHandler.kt +79 -0
  13. package/android/src/main/java/com/carivaexercisesdk/application/connection/port/HealthConnectConnectionPort.kt +16 -0
  14. package/android/src/main/java/com/carivaexercisesdk/application/connection/port/PermissionRequestPort.kt +5 -0
  15. package/android/src/main/java/com/carivaexercisesdk/application/datasource/command/SetDatasourcePolicyCommand.kt +6 -0
  16. package/android/src/main/java/com/carivaexercisesdk/application/datasource/handler/GetDatasourcePolicyHandler.kt +10 -0
  17. package/android/src/main/java/com/carivaexercisesdk/application/datasource/handler/SetDatasourcePolicyHandler.kt +22 -0
  18. package/android/src/main/java/com/carivaexercisesdk/application/datasource/port/DatasourcePolicyRepository.kt +9 -0
  19. package/android/src/main/java/com/carivaexercisesdk/application/exercise/dto/BasalReadResultDto.kt +11 -0
  20. package/android/src/main/java/com/carivaexercisesdk/application/exercise/dto/ExerciseDataDto.kt +41 -0
  21. package/android/src/main/java/com/carivaexercisesdk/application/exercise/handler/GetExerciseDataHandler.kt +346 -0
  22. package/android/src/main/java/com/carivaexercisesdk/application/exercise/port/ExerciseRecordPort.kt +45 -0
  23. package/android/src/main/java/com/carivaexercisesdk/application/exercise/query/GetExerciseDataQuery.kt +9 -0
  24. package/android/src/main/java/com/carivaexercisesdk/domain/connection/entity/ConnectionAggregate.kt +13 -0
  25. package/android/src/main/java/com/carivaexercisesdk/domain/connection/service/ConnectionDecisionService.kt +37 -0
  26. package/android/src/main/java/com/carivaexercisesdk/domain/connection/valueobject/ConnectionNextAction.kt +8 -0
  27. package/android/src/main/java/com/carivaexercisesdk/domain/connection/valueobject/HealthConnectStatus.kt +8 -0
  28. package/android/src/main/java/com/carivaexercisesdk/domain/connection/valueobject/PermissionScope.kt +36 -0
  29. package/android/src/main/java/com/carivaexercisesdk/domain/datasource/entity/DatasourcePolicy.kt +8 -0
  30. package/android/src/main/java/com/carivaexercisesdk/domain/datasource/valueobject/DatasourceType.kt +14 -0
  31. package/android/src/main/java/com/carivaexercisesdk/domain/exercise/services/ExerciseDomainService.kt +89 -0
  32. package/android/src/main/java/com/carivaexercisesdk/domain/exercise/services/HealthConnectCaloriesFallbackMerger.kt +351 -0
  33. package/android/src/main/java/com/carivaexercisesdk/domain/exercise/services/HealthConnectInternalsConstants.kt +55 -0
  34. package/android/src/main/java/com/carivaexercisesdk/domain/exercise/services/HealthConnectModuleInternals.kt +316 -0
  35. package/android/src/main/java/com/carivaexercisesdk/domain/exercise/services/HealthConnectOverlapNormalizer.kt +400 -0
  36. package/android/src/main/java/com/carivaexercisesdk/domain/exercise/services/HealthConnectSourceTrust.kt +249 -0
  37. package/android/src/main/java/com/carivaexercisesdk/domain/exercise/services/HealthConnectUnifiedRecordBuilder.kt +316 -0
  38. package/android/src/main/java/com/carivaexercisesdk/infrastructure/healthconnect/HealthConnectConnectionAdapter.kt +156 -0
  39. package/android/src/main/java/com/carivaexercisesdk/infrastructure/healthconnect/HealthConnectExerciseRecordAdapter.kt +464 -0
  40. package/android/src/main/java/com/carivaexercisesdk/infrastructure/persistence/InMemoryDatasourcePolicyRepository.kt +21 -0
  41. package/android/src/main/java/com/carivaexercisesdk/infrastructure/reactnative/ConnectResultMapper.kt +23 -0
  42. package/android/src/main/java/com/carivaexercisesdk/infrastructure/reactnative/DatasourcePolicyJsonParser.kt +51 -0
  43. package/android/src/main/java/com/carivaexercisesdk/infrastructure/reactnative/DatasourcePolicyMapper.kt +46 -0
  44. package/android/src/main/java/com/carivaexercisesdk/infrastructure/reactnative/ExerciseDataMapper.kt +99 -0
  45. package/android/src/test/java/com/carivaexercisesdk/ArchitectureDependencyRuleTest.kt +60 -0
  46. package/android/src/test/java/com/carivaexercisesdk/HealthConnectModuleDatasourceParserTest.kt +69 -0
  47. package/android/src/test/java/com/carivaexercisesdk/HealthConnectModuleInternalsTest.kt +406 -0
  48. package/android/src/test/java/com/carivaexercisesdk/application/connection/handler/ConnectHandlerTest.kt +153 -0
  49. package/android/src/test/java/com/carivaexercisesdk/application/datasource/handler/DatasourcePolicyRoundTripTest.kt +63 -0
  50. package/android/src/test/java/com/carivaexercisesdk/application/datasource/handler/SetDatasourcePolicyHandlerTest.kt +42 -0
  51. package/android/src/test/java/com/carivaexercisesdk/domain/connection/service/ConnectionDecisionServiceTest.kt +68 -0
  52. package/android/src/test/java/com/carivaexercisesdk/infrastructure/reactnative/DatasourcePolicyMapperTest.kt +22 -0
  53. package/ios/CarivaExerciseSdk.h +5 -0
  54. package/ios/CarivaExerciseSdk.mm +7 -0
  55. package/lib/module/connect/index.js +7 -0
  56. package/lib/module/connect/index.js.map +1 -0
  57. package/lib/module/datasource/index.js +10 -0
  58. package/lib/module/datasource/index.js.map +1 -0
  59. package/lib/module/exercise/index.js +7 -0
  60. package/lib/module/exercise/index.js.map +1 -0
  61. package/lib/module/index.js +6 -0
  62. package/lib/module/index.js.map +1 -0
  63. package/lib/module/native/module.js +13 -0
  64. package/lib/module/native/module.js.map +1 -0
  65. package/lib/module/package.json +1 -0
  66. package/lib/typescript/package.json +1 -0
  67. package/lib/typescript/src/connect/index.d.ts +16 -0
  68. package/lib/typescript/src/connect/index.d.ts.map +1 -0
  69. package/lib/typescript/src/datasource/index.d.ts +12 -0
  70. package/lib/typescript/src/datasource/index.d.ts.map +1 -0
  71. package/lib/typescript/src/exercise/index.d.ts +64 -0
  72. package/lib/typescript/src/exercise/index.d.ts.map +1 -0
  73. package/lib/typescript/src/index.d.ts +4 -0
  74. package/lib/typescript/src/index.d.ts.map +1 -0
  75. package/lib/typescript/src/native/module.d.ts +14 -0
  76. package/lib/typescript/src/native/module.d.ts.map +1 -0
  77. package/package.json +127 -0
  78. package/src/connect/index.ts +34 -0
  79. package/src/datasource/index.ts +20 -0
  80. package/src/exercise/index.ts +75 -0
  81. package/src/index.tsx +22 -0
  82. package/src/native/module.ts +23 -0
package/package.json ADDED
@@ -0,0 +1,127 @@
1
+ {
2
+ "name": "@cariva-dev/exercise-sdk",
3
+ "version": "2.0.0",
4
+ "description": "Cariva exercise SDK",
5
+ "main": "./lib/module/index.js",
6
+ "types": "./lib/typescript/src/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "source": "./src/index.tsx",
10
+ "types": "./lib/typescript/src/index.d.ts",
11
+ "default": "./lib/module/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "files": [
16
+ "src",
17
+ "lib",
18
+ "android",
19
+ "ios",
20
+ "cpp",
21
+ "*.podspec",
22
+ "react-native.config.js",
23
+ "!ios/build",
24
+ "!android/build",
25
+ "!android/gradle",
26
+ "!android/gradlew",
27
+ "!android/gradlew.bat",
28
+ "!android/local.properties",
29
+ "!**/__tests__",
30
+ "!**/__fixtures__",
31
+ "!**/__mocks__",
32
+ "!**/.*"
33
+ ],
34
+ "scripts": {
35
+ "example": "yarn workspace cariva-exercise-sdk-example",
36
+ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
37
+ "prepare": "bob build",
38
+ "typecheck": "tsc",
39
+ "lint": "eslint \"**/*.{js,ts,tsx}\""
40
+ },
41
+ "keywords": [
42
+ "react-native",
43
+ "ios",
44
+ "android"
45
+ ],
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/cariva/cariva-exercise-sdk.git"
49
+ },
50
+ "author": "Cariva <dev@cariva.com> (https://cariva.com)",
51
+ "license": "MIT",
52
+ "bugs": {
53
+ "url": "https://github.com/cariva/cariva-exercise-sdk/issues"
54
+ },
55
+ "homepage": "https://github.com/cariva/cariva-exercise-sdk#readme",
56
+ "publishConfig": {
57
+ "registry": "https://registry.npmjs.org/",
58
+ "access": "public"
59
+ },
60
+ "devDependencies": {
61
+ "@eslint/compat": "^1.3.2",
62
+ "@eslint/eslintrc": "^3.3.1",
63
+ "@eslint/js": "^9.35.0",
64
+ "@react-native/babel-preset": "0.83.0",
65
+ "@react-native/eslint-config": "0.83.0",
66
+ "@types/react": "^19.2.0",
67
+ "del-cli": "^6.0.0",
68
+ "eslint": "^9.35.0",
69
+ "eslint-config-prettier": "^10.1.8",
70
+ "eslint-plugin-prettier": "^5.5.4",
71
+ "prettier": "^2.8.8",
72
+ "react": "19.2.0",
73
+ "react-native": "0.83.0",
74
+ "react-native-builder-bob": "^0.40.18",
75
+ "turbo": "^2.5.6",
76
+ "typescript": "^5.9.2"
77
+ },
78
+ "peerDependencies": {
79
+ "react": "*",
80
+ "react-native": "*"
81
+ },
82
+ "workspaces": [
83
+ "example"
84
+ ],
85
+ "packageManager": "yarn@4.11.0",
86
+ "react-native-builder-bob": {
87
+ "source": "src",
88
+ "output": "lib",
89
+ "targets": [
90
+ [
91
+ "module",
92
+ {
93
+ "esm": true
94
+ }
95
+ ],
96
+ [
97
+ "typescript",
98
+ {
99
+ "project": "tsconfig.build.json"
100
+ }
101
+ ]
102
+ ]
103
+ },
104
+ "codegenConfig": {
105
+ "name": "CarivaExerciseSdkSpec",
106
+ "type": "modules",
107
+ "jsSrcsDir": "src",
108
+ "android": {
109
+ "javaPackageName": "com.carivaexercisesdk"
110
+ }
111
+ },
112
+ "prettier": {
113
+ "quoteProps": "consistent",
114
+ "singleQuote": true,
115
+ "tabWidth": 2,
116
+ "trailingComma": "es5",
117
+ "useTabs": false
118
+ },
119
+ "create-react-native-library": {
120
+ "type": "turbo-module",
121
+ "languages": "kotlin-objc",
122
+ "tools": [
123
+ "eslint"
124
+ ],
125
+ "version": "0.57.2"
126
+ }
127
+ }
@@ -0,0 +1,34 @@
1
+ import { getHealthConnectModule } from '../native/module';
2
+
3
+ export type PermissionScope =
4
+ | 'steps'
5
+ | 'activetimes'
6
+ | 'calories'
7
+ | 'distances';
8
+
9
+ export type ConnectOptions = {
10
+ onMissingApp?: 'status' | 'open';
11
+ requestPermission?: boolean;
12
+ permissionScope?: PermissionScope[];
13
+ };
14
+
15
+ export type ConnectResult = {
16
+ ready: boolean;
17
+ healthConnectInstalled: boolean;
18
+ healthConnectStatus:
19
+ | 'AVAILABLE'
20
+ | 'PROVIDER_UPDATE_REQUIRED'
21
+ | 'UNAVAILABLE'
22
+ | 'UNKNOWN';
23
+ hasPermissions: boolean;
24
+ nextAction:
25
+ | 'INSTALL_HEALTH_CONNECT'
26
+ | 'UPDATE_HEALTH_CONNECT'
27
+ | 'REQUEST_PERMISSION'
28
+ | 'NONE';
29
+ requestedPermissions?: string[];
30
+ };
31
+
32
+ export function connect(options: ConnectOptions = {}): Promise<ConnectResult> {
33
+ return getHealthConnectModule().connect(JSON.stringify(options));
34
+ }
@@ -0,0 +1,20 @@
1
+ import { getHealthConnectModule } from '../native/module';
2
+
3
+ export type DatasourceType = 'manual_input' | 'device' | 'app' | 'unknown';
4
+
5
+ export type DatasourceConfig = {
6
+ allowlist: DatasourceType[];
7
+ scope?: {
8
+ packages?: string[];
9
+ };
10
+ };
11
+
12
+ export function setAllowDatasource(
13
+ config: DatasourceConfig
14
+ ): Promise<{ success: boolean }> {
15
+ return getHealthConnectModule().setAllowDatasource(JSON.stringify(config));
16
+ }
17
+
18
+ export function getAllowDatasource(): Promise<DatasourceConfig> {
19
+ return getHealthConnectModule().getAllowDatasource();
20
+ }
@@ -0,0 +1,75 @@
1
+ import { getHealthConnectModule } from '../native/module';
2
+
3
+ export type TrustLevel = 'trusted' | 'low_confidence';
4
+
5
+ export type UnifiedRecordMeta = {
6
+ source: string;
7
+ device: string;
8
+ deviceModel: string;
9
+ trustLevel: TrustLevel;
10
+ };
11
+
12
+ export type UnifiedIntervalRecord = {
13
+ steps: number;
14
+ activeCalories: number;
15
+ activeCaloriesUnit: 'kcal';
16
+ distance: number;
17
+ distanceUnit: 'km';
18
+ activeTime: number;
19
+ activeTimeUnit: 'milliseconds';
20
+ startDate: string;
21
+ endDate: string;
22
+ meta: UnifiedRecordMeta;
23
+ };
24
+
25
+ export type ExerciseData = {
26
+ totalKcal: number;
27
+ totalSteps: number;
28
+ totalActiveTimeMillis: number;
29
+ // Deprecated backward-compatible alias. Prefer totalActiveTimeMillis.
30
+ totalActiveTime?: number;
31
+ totalDistanceMeters: number;
32
+ timeZone: string;
33
+ records: UnifiedIntervalRecord[];
34
+ warnings?: string[];
35
+ integrity?: {
36
+ projectionPreserved: boolean;
37
+ roundingScale: number;
38
+ };
39
+ diagnostics?: {
40
+ fallbackUsedSegments: number;
41
+ fallbackSuppressedSegments: number;
42
+ idleGateSuppressedSegments: number;
43
+ basalSeedApplied: boolean;
44
+ seededFromBeforeSince: boolean;
45
+ basalSeedAgeHours?: number;
46
+ };
47
+ debug?: {
48
+ directActiveCaloriesKcal: number;
49
+ totalCaloriesKcal: number;
50
+ basalCaloriesKcal: number;
51
+ mergedActiveCaloriesKcal: number;
52
+ fallbackContributionKcal: number;
53
+ fallbackUsedSegments: number;
54
+ fallbackSuppressedSegments: number;
55
+ idleGateSuppressedSegments: number;
56
+ basalSeedApplied: boolean;
57
+ seededFromBeforeSince: boolean;
58
+ basalSeedAgeHours?: number;
59
+ basalIntervalsCount: number;
60
+ };
61
+ };
62
+
63
+ export type GetExerciseDataOptions = {
64
+ sinceMillis: number;
65
+ untilMillis: number;
66
+ type?: 'steps' | 'activetimes' | 'calories' | 'distances' | 'all';
67
+ bucketPeriod?: 'daily' | 'hourly';
68
+ debug?: boolean;
69
+ };
70
+
71
+ export function getExerciseData(
72
+ options: GetExerciseDataOptions
73
+ ): Promise<ExerciseData> {
74
+ return getHealthConnectModule().getExerciseData(JSON.stringify(options));
75
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,22 @@
1
+ export {
2
+ connect,
3
+ type ConnectOptions,
4
+ type ConnectResult,
5
+ type PermissionScope,
6
+ } from './connect';
7
+
8
+ export {
9
+ getExerciseData,
10
+ type ExerciseData,
11
+ type GetExerciseDataOptions,
12
+ type TrustLevel,
13
+ type UnifiedIntervalRecord,
14
+ type UnifiedRecordMeta,
15
+ } from './exercise';
16
+
17
+ export {
18
+ getAllowDatasource,
19
+ setAllowDatasource,
20
+ type DatasourceConfig,
21
+ type DatasourceType,
22
+ } from './datasource';
@@ -0,0 +1,23 @@
1
+ import { NativeModules } from 'react-native';
2
+
3
+ import type { ConnectResult } from '../connect';
4
+ import type { DatasourceConfig } from '../datasource';
5
+ import type { ExerciseData } from '../exercise';
6
+
7
+ type HealthConnectModuleSpec = {
8
+ connect(optionsJson: string): Promise<ConnectResult>;
9
+ getExerciseData(optionsJson: string): Promise<ExerciseData>;
10
+ setAllowDatasource(configJson: string): Promise<{ success: boolean }>;
11
+ getAllowDatasource(): Promise<DatasourceConfig>;
12
+ };
13
+
14
+ const { HealthConnectModule } = NativeModules as {
15
+ HealthConnectModule?: HealthConnectModuleSpec;
16
+ };
17
+
18
+ export function getHealthConnectModule(): HealthConnectModuleSpec {
19
+ if (!HealthConnectModule) {
20
+ throw new Error('HealthConnectModule is not linked or unavailable.');
21
+ }
22
+ return HealthConnectModule;
23
+ }