@robinhealth/health-sdk 0.0.1

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.
@@ -0,0 +1,392 @@
1
+ import Healthkit, { WorkoutActivityType as HKWorkoutActivityType, } from '@kingstinct/react-native-healthkit';
2
+ import { HealthDataType, WorkoutActivityType, PermissionStatus, SleepStage, } from '../types';
3
+ import { getPermissionsRequested, setPermissionsRequested } from '../storage';
4
+ const TYPE_MAP = {
5
+ [HealthDataType.Steps]: {
6
+ identifier: 'HKQuantityTypeIdentifierStepCount',
7
+ unit: 'count',
8
+ },
9
+ [HealthDataType.DistanceWalkingRunning]: {
10
+ identifier: 'HKQuantityTypeIdentifierDistanceWalkingRunning',
11
+ unit: 'm',
12
+ },
13
+ [HealthDataType.ActiveEnergyBurned]: {
14
+ identifier: 'HKQuantityTypeIdentifierActiveEnergyBurned',
15
+ unit: 'kcal',
16
+ },
17
+ [HealthDataType.FlightsClimbed]: {
18
+ identifier: 'HKQuantityTypeIdentifierFlightsClimbed',
19
+ unit: 'count',
20
+ },
21
+ [HealthDataType.HeartRate]: {
22
+ identifier: 'HKQuantityTypeIdentifierHeartRate',
23
+ unit: 'bpm',
24
+ },
25
+ [HealthDataType.RestingHeartRate]: {
26
+ identifier: 'HKQuantityTypeIdentifierRestingHeartRate',
27
+ unit: 'bpm',
28
+ },
29
+ [HealthDataType.BloodPressureSystolic]: {
30
+ identifier: 'HKQuantityTypeIdentifierBloodPressureSystolic',
31
+ unit: 'mmHg',
32
+ },
33
+ [HealthDataType.BloodPressureDiastolic]: {
34
+ identifier: 'HKQuantityTypeIdentifierBloodPressureDiastolic',
35
+ unit: 'mmHg',
36
+ },
37
+ [HealthDataType.BloodOxygen]: {
38
+ identifier: 'HKQuantityTypeIdentifierOxygenSaturation',
39
+ unit: '%',
40
+ },
41
+ [HealthDataType.RespiratoryRate]: {
42
+ identifier: 'HKQuantityTypeIdentifierRespiratoryRate',
43
+ unit: 'breaths/min',
44
+ },
45
+ [HealthDataType.SleepAnalysis]: {
46
+ identifier: 'HKCategoryTypeIdentifierSleepAnalysis',
47
+ unit: 'hr',
48
+ isCategory: true,
49
+ },
50
+ [HealthDataType.BodyFatPercentage]: {
51
+ identifier: 'HKQuantityTypeIdentifierBodyFatPercentage',
52
+ unit: '%',
53
+ },
54
+ [HealthDataType.BodyMassIndex]: {
55
+ identifier: 'HKQuantityTypeIdentifierBodyMassIndex',
56
+ unit: 'kg/m²',
57
+ },
58
+ [HealthDataType.BasalEnergyBurned]: {
59
+ identifier: 'HKQuantityTypeIdentifierBasalEnergyBurned',
60
+ unit: 'kcal',
61
+ },
62
+ [HealthDataType.Water]: {
63
+ identifier: 'HKQuantityTypeIdentifierDietaryWater',
64
+ unit: 'mL',
65
+ },
66
+ };
67
+ const WORKOUT_TYPE_MAP = {
68
+ [HKWorkoutActivityType.americanFootball]: WorkoutActivityType.americanFootball,
69
+ [HKWorkoutActivityType.archery]: WorkoutActivityType.archery,
70
+ [HKWorkoutActivityType.australianFootball]: WorkoutActivityType.australianFootball,
71
+ [HKWorkoutActivityType.badminton]: WorkoutActivityType.badminton,
72
+ [HKWorkoutActivityType.baseball]: WorkoutActivityType.baseball,
73
+ [HKWorkoutActivityType.basketball]: WorkoutActivityType.basketball,
74
+ [HKWorkoutActivityType.bowling]: WorkoutActivityType.bowling,
75
+ [HKWorkoutActivityType.boxing]: WorkoutActivityType.boxing,
76
+ [HKWorkoutActivityType.climbing]: WorkoutActivityType.climbing,
77
+ [HKWorkoutActivityType.cricket]: WorkoutActivityType.cricket,
78
+ [HKWorkoutActivityType.crossTraining]: WorkoutActivityType.crossTraining,
79
+ [HKWorkoutActivityType.curling]: WorkoutActivityType.curling,
80
+ [HKWorkoutActivityType.cycling]: WorkoutActivityType.cycling,
81
+ [HKWorkoutActivityType.dance]: WorkoutActivityType.dance,
82
+ [HKWorkoutActivityType.danceInspiredTraining]: WorkoutActivityType.danceInspiredTraining,
83
+ [HKWorkoutActivityType.elliptical]: WorkoutActivityType.elliptical,
84
+ [HKWorkoutActivityType.equestrianSports]: WorkoutActivityType.equestrianSports,
85
+ [HKWorkoutActivityType.fencing]: WorkoutActivityType.fencing,
86
+ [HKWorkoutActivityType.fishing]: WorkoutActivityType.fishing,
87
+ [HKWorkoutActivityType.functionalStrengthTraining]: WorkoutActivityType.functionalStrengthTraining,
88
+ [HKWorkoutActivityType.golf]: WorkoutActivityType.golf,
89
+ [HKWorkoutActivityType.gymnastics]: WorkoutActivityType.gymnastics,
90
+ [HKWorkoutActivityType.handball]: WorkoutActivityType.handball,
91
+ [HKWorkoutActivityType.hiking]: WorkoutActivityType.hiking,
92
+ [HKWorkoutActivityType.hockey]: WorkoutActivityType.hockey,
93
+ [HKWorkoutActivityType.hunting]: WorkoutActivityType.hunting,
94
+ [HKWorkoutActivityType.lacrosse]: WorkoutActivityType.lacrosse,
95
+ [HKWorkoutActivityType.martialArts]: WorkoutActivityType.martialArts,
96
+ [HKWorkoutActivityType.mindAndBody]: WorkoutActivityType.mindAndBody,
97
+ [HKWorkoutActivityType.mixedMetabolicCardioTraining]: WorkoutActivityType.mixedMetabolicCardioTraining,
98
+ [HKWorkoutActivityType.paddleSports]: WorkoutActivityType.paddleSports,
99
+ [HKWorkoutActivityType.play]: WorkoutActivityType.play,
100
+ [HKWorkoutActivityType.preparationAndRecovery]: WorkoutActivityType.preparationAndRecovery,
101
+ [HKWorkoutActivityType.racquetball]: WorkoutActivityType.racquetball,
102
+ [HKWorkoutActivityType.rowing]: WorkoutActivityType.rowing,
103
+ [HKWorkoutActivityType.rugby]: WorkoutActivityType.rugby,
104
+ [HKWorkoutActivityType.running]: WorkoutActivityType.running,
105
+ [HKWorkoutActivityType.sailing]: WorkoutActivityType.sailing,
106
+ [HKWorkoutActivityType.skatingSports]: WorkoutActivityType.skatingSports,
107
+ [HKWorkoutActivityType.snowSports]: WorkoutActivityType.snowSports,
108
+ [HKWorkoutActivityType.soccer]: WorkoutActivityType.soccer,
109
+ [HKWorkoutActivityType.softball]: WorkoutActivityType.softball,
110
+ [HKWorkoutActivityType.squash]: WorkoutActivityType.squash,
111
+ [HKWorkoutActivityType.stairClimbing]: WorkoutActivityType.stairClimbing,
112
+ [HKWorkoutActivityType.surfingSports]: WorkoutActivityType.surfingSports,
113
+ [HKWorkoutActivityType.swimming]: WorkoutActivityType.swimming,
114
+ [HKWorkoutActivityType.tableTennis]: WorkoutActivityType.tableTennis,
115
+ [HKWorkoutActivityType.tennis]: WorkoutActivityType.tennis,
116
+ [HKWorkoutActivityType.trackAndField]: WorkoutActivityType.trackAndField,
117
+ [HKWorkoutActivityType.traditionalStrengthTraining]: WorkoutActivityType.traditionalStrengthTraining,
118
+ [HKWorkoutActivityType.volleyball]: WorkoutActivityType.volleyball,
119
+ [HKWorkoutActivityType.walking]: WorkoutActivityType.walking,
120
+ [HKWorkoutActivityType.waterFitness]: WorkoutActivityType.waterFitness,
121
+ [HKWorkoutActivityType.waterPolo]: WorkoutActivityType.waterPolo,
122
+ [HKWorkoutActivityType.waterSports]: WorkoutActivityType.waterSports,
123
+ [HKWorkoutActivityType.wrestling]: WorkoutActivityType.wrestling,
124
+ [HKWorkoutActivityType.yoga]: WorkoutActivityType.yoga,
125
+ [HKWorkoutActivityType.barre]: WorkoutActivityType.barre,
126
+ [HKWorkoutActivityType.coreTraining]: WorkoutActivityType.coreTraining,
127
+ [HKWorkoutActivityType.crossCountrySkiing]: WorkoutActivityType.crossCountrySkiing,
128
+ [HKWorkoutActivityType.downhillSkiing]: WorkoutActivityType.downhillSkiing,
129
+ [HKWorkoutActivityType.flexibility]: WorkoutActivityType.flexibility,
130
+ [HKWorkoutActivityType.highIntensityIntervalTraining]: WorkoutActivityType.highIntensityIntervalTraining,
131
+ [HKWorkoutActivityType.jumpRope]: WorkoutActivityType.jumpRope,
132
+ [HKWorkoutActivityType.kickboxing]: WorkoutActivityType.kickboxing,
133
+ [HKWorkoutActivityType.pilates]: WorkoutActivityType.pilates,
134
+ [HKWorkoutActivityType.snowboarding]: WorkoutActivityType.snowboarding,
135
+ [HKWorkoutActivityType.stairs]: WorkoutActivityType.stairs,
136
+ [HKWorkoutActivityType.stepTraining]: WorkoutActivityType.stepTraining,
137
+ [HKWorkoutActivityType.wheelchairWalkPace]: WorkoutActivityType.wheelchairWalkPace,
138
+ [HKWorkoutActivityType.wheelchairRunPace]: WorkoutActivityType.wheelchairRunPace,
139
+ [HKWorkoutActivityType.taiChi]: WorkoutActivityType.taiChi,
140
+ [HKWorkoutActivityType.mixedCardio]: WorkoutActivityType.mixedCardio,
141
+ [HKWorkoutActivityType.handCycling]: WorkoutActivityType.handCycling,
142
+ [HKWorkoutActivityType.discSports]: WorkoutActivityType.discSports,
143
+ [HKWorkoutActivityType.fitnessGaming]: WorkoutActivityType.fitnessGaming,
144
+ [HKWorkoutActivityType.cardioDance]: WorkoutActivityType.cardioDance,
145
+ [HKWorkoutActivityType.socialDance]: WorkoutActivityType.socialDance,
146
+ [HKWorkoutActivityType.pickleball]: WorkoutActivityType.pickleball,
147
+ [HKWorkoutActivityType.cooldown]: WorkoutActivityType.cooldown,
148
+ [HKWorkoutActivityType.swimBikeRun]: WorkoutActivityType.swimBikeRun,
149
+ [HKWorkoutActivityType.transition]: WorkoutActivityType.transition,
150
+ [HKWorkoutActivityType.underwaterDiving]: WorkoutActivityType.underwaterDiving,
151
+ [HKWorkoutActivityType.other]: WorkoutActivityType.other,
152
+ };
153
+ const SLEEP_STAGE_MAP = {
154
+ 0: SleepStage.Unknown, // HKCategoryValueSleepAnalysis.inBed
155
+ 1: SleepStage.Unknown, // asleepUnspecified
156
+ 2: SleepStage.Awake, // awake
157
+ 3: SleepStage.Light, // asleepCore
158
+ 4: SleepStage.Deep, // asleepDeep
159
+ 5: SleepStage.REM, // asleepREM
160
+ };
161
+ const dateFilter = (startDate, endDate) => ({
162
+ filter: { date: { startDate, endDate } },
163
+ });
164
+ export class HealthKitProvider {
165
+ async isAvailable() {
166
+ return Healthkit.isHealthDataAvailable();
167
+ }
168
+ async shouldRequestAuthorization(dataTypes) {
169
+ const readIdentifiers = dataTypes
170
+ .map((dt) => TYPE_MAP[dt]?.identifier)
171
+ .filter((id) => id !== undefined);
172
+ const status = await Healthkit.getRequestStatusForAuthorization({
173
+ toRead: [...readIdentifiers, 'HKWorkoutTypeIdentifier'],
174
+ });
175
+ // status 1 = shouldRequest, 2 = unnecessary (already granted)
176
+ return status === 1;
177
+ }
178
+ async requestAuthorization(dataTypes) {
179
+ const readIdentifiers = dataTypes
180
+ .map((dt) => TYPE_MAP[dt]?.identifier)
181
+ .filter((id) => id !== undefined);
182
+ try {
183
+ await Healthkit.requestAuthorization({ toRead: [...readIdentifiers, 'HKWorkoutTypeIdentifier'] });
184
+ return true;
185
+ }
186
+ catch {
187
+ return false;
188
+ }
189
+ finally {
190
+ await setPermissionsRequested();
191
+ }
192
+ }
193
+ async getPermissionStatus() {
194
+ try {
195
+ const wasRequested = await getPermissionsRequested();
196
+ if (!wasRequested)
197
+ return PermissionStatus.UNKNOWN;
198
+ // On iOS, HealthKit does not expose read-permission denial status.
199
+ // getRequestStatusForAuthorization returns status 1 ("shouldRequest") for
200
+ // both genuine denials AND newly added data types that haven't been requested
201
+ // yet. Since we can't distinguish the two, and HealthKit silently returns
202
+ // empty data for denied types (the app still functions), we treat any
203
+ // previously-requested state as GRANTED. This prevents app updates that add
204
+ // new HealthDataTypes from incorrectly blocking all health data access.
205
+ return PermissionStatus.GRANTED;
206
+ }
207
+ catch {
208
+ return PermissionStatus.UNKNOWN;
209
+ }
210
+ }
211
+ async querySamples(type, startDate, endDate) {
212
+ const mapping = TYPE_MAP[type];
213
+ if (!mapping)
214
+ return [];
215
+ if (mapping.isCategory) {
216
+ return this.queryCategorySamples(type, mapping, startDate, endDate);
217
+ }
218
+ const results = await Healthkit.queryQuantitySamples(mapping.identifier, { limit: 0, ...dateFilter(startDate, endDate) });
219
+ return results.map((sample) => ({
220
+ type,
221
+ value: sample.quantity,
222
+ unit: mapping.unit,
223
+ startDate: new Date(sample.startDate),
224
+ endDate: new Date(sample.endDate),
225
+ sourceName: sample.sourceRevision?.source?.name ?? undefined,
226
+ }));
227
+ }
228
+ async queryAggregated(type, startDate, endDate) {
229
+ const mapping = TYPE_MAP[type];
230
+ if (!mapping)
231
+ return { type, unit: '', startDate, endDate };
232
+ if (mapping.isCategory) {
233
+ return this.aggregateCategorySamples(type, mapping, startDate, endDate);
234
+ }
235
+ const identifier = mapping.identifier;
236
+ const options = [
237
+ 'cumulativeSum',
238
+ 'discreteAverage',
239
+ 'discreteMin',
240
+ 'discreteMax',
241
+ ];
242
+ const result = await Healthkit.queryStatisticsForQuantity(identifier, options, dateFilter(startDate, endDate));
243
+ return {
244
+ type,
245
+ sum: result.sumQuantity?.quantity,
246
+ avg: result.averageQuantity?.quantity,
247
+ min: result.minimumQuantity?.quantity,
248
+ max: result.maximumQuantity?.quantity,
249
+ unit: mapping.unit,
250
+ startDate,
251
+ endDate,
252
+ };
253
+ }
254
+ async queryWorkouts(startDate, endDate) {
255
+ const workoutProxies = await Healthkit.queryWorkoutSamples({
256
+ limit: 0,
257
+ ascending: false,
258
+ filter: { date: { startDate, endDate } },
259
+ });
260
+ const workouts = await Promise.all(workoutProxies.map(async (proxy) => {
261
+ const workoutType = WORKOUT_TYPE_MAP[proxy.workoutActivityType] ?? WorkoutActivityType.other;
262
+ let heartRateAvg = null;
263
+ let heartRateMax = null;
264
+ try {
265
+ const hrStats = await proxy.getStatistic('HKQuantityTypeIdentifierHeartRate', 'count/min');
266
+ if (hrStats) {
267
+ heartRateAvg = hrStats.averageQuantity?.quantity ?? null;
268
+ heartRateMax = hrStats.maximumQuantity?.quantity ?? null;
269
+ }
270
+ }
271
+ catch {
272
+ // HR stats not available for this workout
273
+ }
274
+ const rawEnergy = proxy.totalEnergyBurned?.quantity;
275
+ const rawDistance = proxy.totalDistance?.quantity;
276
+ return {
277
+ workoutType,
278
+ duration: proxy.duration.quantity,
279
+ energyBurned: rawEnergy != null && !Number.isNaN(rawEnergy) ? rawEnergy : null,
280
+ distance: rawDistance != null && !Number.isNaN(rawDistance) ? rawDistance : null,
281
+ heartRateAvg,
282
+ heartRateMax,
283
+ startDate: new Date(proxy.startDate),
284
+ endDate: new Date(proxy.endDate),
285
+ sourceName: proxy.sourceRevision?.source?.name ?? 'Unknown',
286
+ };
287
+ }));
288
+ return workouts;
289
+ }
290
+ async queryCategorySamples(type, mapping, startDate, endDate) {
291
+ const results = await Healthkit.queryCategorySamples(mapping.identifier, { limit: 0, ...dateFilter(startDate, endDate) });
292
+ return results.map((sample) => {
293
+ const start = new Date(sample.startDate);
294
+ const end = new Date(sample.endDate);
295
+ const durationHours = (end.getTime() - start.getTime()) / (1000 * 60 * 60);
296
+ return {
297
+ type,
298
+ value: durationHours,
299
+ unit: mapping.unit,
300
+ startDate: start,
301
+ endDate: end,
302
+ sourceName: sample.sourceRevision?.source?.name ?? undefined,
303
+ stage: SLEEP_STAGE_MAP[sample.value] ?? SleepStage.Unknown,
304
+ };
305
+ });
306
+ }
307
+ async querySleepSessions(startDate, endDate) {
308
+ const mapping = TYPE_MAP[HealthDataType.SleepAnalysis];
309
+ if (!mapping)
310
+ return [];
311
+ const samples = await this.queryCategorySamples(HealthDataType.SleepAnalysis, mapping, startDate, endDate);
312
+ // Group samples into sessions: samples within 30 minutes of each other
313
+ // from the same source form one session
314
+ const sessions = [];
315
+ const sortedSamples = [...samples].sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
316
+ let currentGroup = [];
317
+ let currentSource;
318
+ for (const sample of sortedSamples) {
319
+ const lastInGroup = currentGroup[currentGroup.length - 1];
320
+ const sameSource = sample.sourceName === currentSource;
321
+ const withinWindow = lastInGroup &&
322
+ sample.startDate.getTime() - lastInGroup.endDate.getTime() <=
323
+ 30 * 60 * 1000; // 30 minutes
324
+ if (currentGroup.length === 0 || (sameSource && withinWindow)) {
325
+ currentGroup.push(sample);
326
+ currentSource = sample.sourceName;
327
+ }
328
+ else {
329
+ sessions.push(this.buildSleepSession(currentGroup));
330
+ currentGroup = [sample];
331
+ currentSource = sample.sourceName;
332
+ }
333
+ }
334
+ if (currentGroup.length > 0) {
335
+ sessions.push(this.buildSleepSession(currentGroup));
336
+ }
337
+ return sessions;
338
+ }
339
+ buildSleepSession(samples) {
340
+ const stages = {
341
+ awake: 0,
342
+ light: 0,
343
+ deep: 0,
344
+ rem: 0,
345
+ unknown: 0,
346
+ };
347
+ for (const sample of samples) {
348
+ const hours = sample.value;
349
+ switch (sample.stage) {
350
+ case SleepStage.Awake:
351
+ stages.awake += hours;
352
+ break;
353
+ case SleepStage.Light:
354
+ stages.light += hours;
355
+ break;
356
+ case SleepStage.Deep:
357
+ stages.deep += hours;
358
+ break;
359
+ case SleepStage.REM:
360
+ stages.rem += hours;
361
+ break;
362
+ default:
363
+ stages.unknown += hours;
364
+ break;
365
+ }
366
+ }
367
+ const totalDuration = stages.light + stages.deep + stages.rem + stages.unknown;
368
+ return {
369
+ startDate: samples[0].startDate,
370
+ endDate: samples[samples.length - 1].endDate,
371
+ totalDuration,
372
+ stages,
373
+ sourceName: samples[0].sourceName ?? 'Unknown',
374
+ };
375
+ }
376
+ async aggregateCategorySamples(type, mapping, startDate, endDate) {
377
+ const samples = await this.queryCategorySamples(type, mapping, startDate, endDate);
378
+ const values = samples.map((s) => s.value);
379
+ const sum = values.reduce((a, b) => a + b, 0);
380
+ return {
381
+ type,
382
+ sum,
383
+ avg: values.length > 0 ? sum / values.length : undefined,
384
+ min: values.length > 0 ? values.reduce((a, b) => a < b ? a : b) : undefined,
385
+ max: values.length > 0 ? values.reduce((a, b) => a > b ? a : b) : undefined,
386
+ unit: mapping.unit,
387
+ startDate,
388
+ endDate,
389
+ };
390
+ }
391
+ }
392
+ //# sourceMappingURL=healthkit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"healthkit.js","sourceRoot":"","sources":["../../src/providers/healthkit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function getPermissionsRequested(): Promise<boolean>;
2
+ export declare function setPermissionsRequested(): Promise<void>;
3
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAmEA,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC,CAQhE;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAO7D"}
@@ -0,0 +1,71 @@
1
+ const STORAGE_KEY = 'permissions_requested';
2
+ const LEGACY_ASYNC_STORAGE_KEY = '@robin_health_sdk:permissions_requested';
3
+ const DB_NAME = 'robin_health_sdk.db';
4
+ const TABLE = 'kv';
5
+ let db = null;
6
+ let migrationDone = false;
7
+ try {
8
+ const SQLite = require('expo-sqlite');
9
+ db = SQLite.openDatabaseSync(DB_NAME);
10
+ db.execSync(`CREATE TABLE IF NOT EXISTS ${TABLE} (key TEXT PRIMARY KEY, value TEXT NOT NULL)`);
11
+ }
12
+ catch {
13
+ // expo-sqlite not available — getPermissionStatus will always return UNKNOWN
14
+ }
15
+ function getFromDb(key) {
16
+ if (!db)
17
+ return null;
18
+ const row = db.getFirstSync(`SELECT value FROM ${TABLE} WHERE key = ?`, [key]);
19
+ return row?.value ?? null;
20
+ }
21
+ function setInDb(key, value) {
22
+ if (!db)
23
+ return;
24
+ db.runSync(`INSERT OR REPLACE INTO ${TABLE} (key, value) VALUES (?, ?)`, [key, value]);
25
+ }
26
+ /**
27
+ * One-time migration from legacy AsyncStorage to SQLite.
28
+ * Runs at most once per app session. If AsyncStorage is not installed
29
+ * or the legacy key doesn't exist, this is a no-op.
30
+ */
31
+ async function migrateFromAsyncStorage() {
32
+ if (migrationDone || !db)
33
+ return;
34
+ migrationDone = true;
35
+ // Already have a value in SQLite — no migration needed
36
+ if (getFromDb(STORAGE_KEY) !== null)
37
+ return;
38
+ try {
39
+ const AsyncStorage = require('@react-native-async-storage/async-storage').default;
40
+ const legacy = await AsyncStorage.getItem(LEGACY_ASYNC_STORAGE_KEY);
41
+ if (legacy === 'true') {
42
+ setInDb(STORAGE_KEY, 'true');
43
+ await AsyncStorage.removeItem(LEGACY_ASYNC_STORAGE_KEY);
44
+ }
45
+ }
46
+ catch {
47
+ // AsyncStorage not installed or migration failed — not critical
48
+ }
49
+ }
50
+ export async function getPermissionsRequested() {
51
+ try {
52
+ if (!db)
53
+ return false;
54
+ await migrateFromAsyncStorage();
55
+ return getFromDb(STORAGE_KEY) === 'true';
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ }
61
+ export async function setPermissionsRequested() {
62
+ try {
63
+ if (!db)
64
+ return;
65
+ setInDb(STORAGE_KEY, 'true');
66
+ }
67
+ catch {
68
+ // Swallow — worst case next call returns UNKNOWN
69
+ }
70
+ }
71
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAC5C,MAAM,wBAAwB,GAAG,yCAAyC,CAAC;AAC3E,MAAM,OAAO,GAAG,qBAAqB,CAAC;AACtC,MAAM,KAAK,GAAG,IAAI,CAAC;AAQnB,IAAI,EAAE,GAAoB,IAAI,CAAC;AAC/B,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACtC,EAAE,GAAG,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAa,CAAC;IAClD,EAAE,CAAC,QAAQ,CACT,8BAA8B,KAAK,8CAA8C,CAClF,CAAC;AACJ,CAAC;AAAC,MAAM,CAAC;IACP,6EAA6E;AAC/E,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CACzB,qBAAqB,KAAK,gBAAgB,EAC1C,CAAC,GAAG,CAAC,CACN,CAAC;IACF,OAAO,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED,SAAS,OAAO,CAAC,GAAW,EAAE,KAAa;IACzC,IAAI,CAAC,EAAE;QAAE,OAAO;IAChB,EAAE,CAAC,OAAO,CACR,0BAA0B,KAAK,6BAA6B,EAC5D,CAAC,GAAG,EAAE,KAAK,CAAC,CACb,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,uBAAuB;IACpC,IAAI,aAAa,IAAI,CAAC,EAAE;QAAE,OAAO;IACjC,aAAa,GAAG,IAAI,CAAC;IAErB,uDAAuD;IACvD,IAAI,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI;QAAE,OAAO;IAE5C,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,OAAO,CAAC,2CAA2C,CAAC,CAAC,OAAO,CAAC;QAClF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QACpE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAC7B,MAAM,YAAY,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,IAAI,CAAC;QACH,IAAI,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QACtB,MAAM,uBAAuB,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,MAAM,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,IAAI,CAAC;QACH,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;AACH,CAAC"}