feat: native background sync engine v2 + dual-unit hkUnit#344
Open
oakleaf wants to merge 3 commits intokingstinct:masterfrom
Open
feat: native background sync engine v2 + dual-unit hkUnit#344oakleaf wants to merge 3 commits intokingstinct:masterfrom
oakleaf wants to merge 3 commits intokingstinct:masterfrom
Conversation
Rewrite the native HealthKit sync engine with: - Four sample-kind handlers (cumulativeQuantity, discreteQuantity, categorySample, workout) replacing the old cumulative-only path - Configurable lookback window (consumer sets lookbackDays; default 1) - Swift concurrency with 20s deadline per observer wake - Sleep category value mapping with @unknown default + raw-value fallback - iOS 17+ workout.statistics(for:) with graceful pre-17 fallback - Deterministic native-first dispatch: native sync always runs on wake, JS callback fires in parallel for reactive foreground UI - Native breadcrumb channel persisted in UserDefaults, flushed to the consumer's backend on next successful push via clientFailuresSince - Every record carries timeZone (IANA), timeZoneOffsetMinutes, localDate BackgroundDeliveryManager registers one observer per distinct kind (not per type) and stores registrations + kind in UserDefaults for cold-launch restore. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…chment SyncTypeConfig gains optional hkUnit field for when a consumer's wire unit differs from Apple's HKUnit factorization grammar (e.g. "bpm" vs "count/min"). Set hkUnit for HealthKit queries, unit for the wire. Omit hkUnit when they match — falls back to unit automatically. Configure-time validation in configureBackgroundSync surfaces invalid HKUnit strings synchronously instead of silently dropping records on background wake hours later. NativeSyncEngine now emits device (HKDevice), source (HKSourceRevision), and metadata on all sample-based records (discrete, category, workout). Cumulative queries return aggregated HKStatistics — no per-sample metadata to expose. Companion pod gains SWIFT_ACTIVE_COMPILATION_CONDITIONS so NativeSyncEngine compiles cleanly in both pod targets: calls BGSafeHKUnitFromString in the companion pod, falls back to HKUnitFromStringCatchingExceptions in the main pod. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 02ecd01 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
Member
|
I don't understand how metadata gets exposed this way? Also it seems like the native build broke with this latest change. Also there's now two change sets - I think one is enough :) |
3 tasks
…ut record types - Delete duplicate v1 changeset (native-background-sync.md) — keep only v2 - Exclude BackgroundDeliveryManager.swift and NativeSyncEngine.swift from the main pod's source_files glob — these @objc singletons were being compiled by both the main and companion pods, causing duplicate HKHealthStore instances and DispatchQueue lock contention that hung the contract test suite - Add TypeScript interfaces for output record shapes (SyncRecordDevice, SyncRecordSource, SyncRecordCumulative, SyncRecordDiscrete, SyncRecordCategory, SyncRecordWorkout) so consumers can type their backend request handlers and the metadata flow is explicit in the PR diff Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SyncTypeConfig.hkUnitlets consumers specify Apple's HKUnit factorization grammar separately from their wire format — e.g.unit: "bpm"for the backend,hkUnit: "count/min"for HealthKit queries. Configure-time validation surfaces invalid strings immediatelydevice(HKDevice),source(HKSourceRevision), andmetadatafields. Cumulative queries return aggregated stats — no per-sample metadata to exposeclientFailuresSincetimeZone(IANA),timeZoneOffsetMinutes,localDateBreaking changes
SyncTypeConfig.kindreplaces the oldcumulative: boolean— now a string union (cumulativeQuantity/discreteQuantity/categorySample/workout)BackgroundSyncEndpoint.lookbackDaysadded (default1— today only)Design decisions
hkUnit/unit; neither is guessedconfigureBackgroundSyncthrows synchronouslyBackgroundHKUnitCatcheris a separate ObjC NSException catcher withextern "C"linkage, excluded from the main pod to avoid duplicate symbols.SWIFT_ACTIVE_COMPILATION_CONDITIONSletsNativeSyncEngine.swiftcompile in both pod targetsTest plan
NSInvalidArgumentExceptioncrashsyncPath: "native"and correct data typesdevice,source,metadatafieldstimeZone,timeZoneOffsetMinutes,localDate) present on all records"bpm"not"count/min"on heart_rate records)tsc --noEmitclean