@ovok/native 0.4.3 → 0.4.4
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.
- package/lib/commonjs/modules/data-sync/components/android/android-health-sync.js +11 -1
- package/lib/commonjs/modules/data-sync/components/android/android-health-sync.js.map +1 -1
- package/lib/commonjs/modules/data-sync/components/apple/apple-health-sync.js +33 -1
- package/lib/commonjs/modules/data-sync/components/apple/apple-health-sync.js.map +1 -1
- package/lib/commonjs/modules/data-sync/services/base-health-sync-service.js +4 -0
- package/lib/commonjs/modules/data-sync/services/base-health-sync-service.js.map +1 -1
- package/lib/commonjs/modules/data-sync/services/managers/storage-manager.js +30 -2
- package/lib/commonjs/modules/data-sync/services/managers/storage-manager.js.map +1 -1
- package/lib/commonjs/modules/data-sync/services/managers/sync-state-manager.js +19 -0
- package/lib/commonjs/modules/data-sync/services/managers/sync-state-manager.js.map +1 -1
- package/lib/module/modules/data-sync/components/android/android-health-sync.js +11 -1
- package/lib/module/modules/data-sync/components/android/android-health-sync.js.map +1 -1
- package/lib/module/modules/data-sync/components/apple/apple-health-sync.js +33 -1
- package/lib/module/modules/data-sync/components/apple/apple-health-sync.js.map +1 -1
- package/lib/module/modules/data-sync/services/base-health-sync-service.js +4 -0
- package/lib/module/modules/data-sync/services/base-health-sync-service.js.map +1 -1
- package/lib/module/modules/data-sync/services/managers/storage-manager.js +30 -2
- package/lib/module/modules/data-sync/services/managers/storage-manager.js.map +1 -1
- package/lib/module/modules/data-sync/services/managers/sync-state-manager.js +19 -0
- package/lib/module/modules/data-sync/services/managers/sync-state-manager.js.map +1 -1
- package/lib/typescript/commonjs/src/modules/data-sync/components/android/android-health-sync.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/data-sync/components/apple/apple-health-sync.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/data-sync/services/base-health-sync-service.d.ts +2 -0
- package/lib/typescript/commonjs/src/modules/data-sync/services/base-health-sync-service.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/data-sync/services/managers/storage-manager.d.ts +20 -0
- package/lib/typescript/commonjs/src/modules/data-sync/services/managers/storage-manager.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/data-sync/services/managers/sync-state-manager.d.ts +13 -0
- package/lib/typescript/commonjs/src/modules/data-sync/services/managers/sync-state-manager.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/data-sync/components/android/android-health-sync.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/data-sync/components/apple/apple-health-sync.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/data-sync/services/base-health-sync-service.d.ts +2 -0
- package/lib/typescript/module/src/modules/data-sync/services/base-health-sync-service.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/data-sync/services/managers/storage-manager.d.ts +20 -0
- package/lib/typescript/module/src/modules/data-sync/services/managers/storage-manager.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/data-sync/services/managers/sync-state-manager.d.ts +13 -0
- package/lib/typescript/module/src/modules/data-sync/services/managers/sync-state-manager.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -63,7 +63,17 @@ const AndroidHealthSync = exports.AndroidHealthSync = /*#__PURE__*/React.memo(({
|
|
|
63
63
|
}, [onError, onProgress]);
|
|
64
64
|
React.useEffect(() => {
|
|
65
65
|
return () => {
|
|
66
|
-
|
|
66
|
+
/*
|
|
67
|
+
* A teardown that throws takes the unmount with it, and React has no
|
|
68
|
+
* boundary for a cleanup function — so a sync that fails to stop
|
|
69
|
+
* became a crash on the way out of a screen. The error goes to the
|
|
70
|
+
* app's own handler, which is what `onError` is for.
|
|
71
|
+
*/
|
|
72
|
+
try {
|
|
73
|
+
serviceRef.current?.stopSync();
|
|
74
|
+
} catch (error) {
|
|
75
|
+
onErrorRef.current?.(error);
|
|
76
|
+
}
|
|
67
77
|
serviceRef.current = null;
|
|
68
78
|
};
|
|
69
79
|
}, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_core","require","_netinfo","React","_interopRequireWildcard","_androidHealthSyncService","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","AndroidHealthSync","exports","memo","dataToSync","chunkSize","onError","onProgress","client","useClient","patient","useMedplumProfile","serviceRef","useRef","isConnected","type","useNetInfo","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","AndroidHealthSyncService","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/android/android-health-sync.tsx"],"mappings":"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
|
|
1
|
+
{"version":3,"names":["_core","require","_netinfo","React","_interopRequireWildcard","_androidHealthSyncService","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","AndroidHealthSync","exports","memo","dataToSync","chunkSize","onError","onProgress","client","useClient","patient","useMedplumProfile","serviceRef","useRef","isConnected","type","useNetInfo","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","AndroidHealthSyncService","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/android/android-health-sync.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -45,6 +45,28 @@ const AppleHealthSync = exports.AppleHealthSync = /*#__PURE__*/React.memo(({
|
|
|
45
45
|
onErrorRef.current?.(error);
|
|
46
46
|
}
|
|
47
47
|
}, [client, dataToSync, chunkSize, patient?.id, updateProgress]);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The first sync, which nothing used to start.
|
|
51
|
+
*
|
|
52
|
+
* `useListenChanges` subscribes to HealthKit observer queries, and the
|
|
53
|
+
* native side scopes those to samples that start from NOW —
|
|
54
|
+
* `HKQuery.predicateForSamples(withStart: Date.init(), …)` in
|
|
55
|
+
* `@kingstinct/react-native-healthkit`. So the subscription can never fire
|
|
56
|
+
* for data that already exists, and the only other caller, the network
|
|
57
|
+
* effect below, returns early while `serviceRef.current` is null — which
|
|
58
|
+
* only this path assigns. A patient installed the app, granted HealthKit
|
|
59
|
+
* and saw nothing: their existing history was never read, and nothing new
|
|
60
|
+
* arrived unless they moved with the app open.
|
|
61
|
+
*
|
|
62
|
+
* `startSync` reads the per-code watermark off the server and pages
|
|
63
|
+
* forward from it, so it IS the initial sync; it just had no caller here.
|
|
64
|
+
* `AndroidHealthSync` has had this effect all along — this is the platform
|
|
65
|
+
* catching up with its sibling, not a new mechanism.
|
|
66
|
+
*/
|
|
67
|
+
React.useEffect(() => {
|
|
68
|
+
syncData();
|
|
69
|
+
}, [syncData]);
|
|
48
70
|
(0, _useListenChanges.useListenChanges)(dataToSync, () => {
|
|
49
71
|
syncData();
|
|
50
72
|
});
|
|
@@ -64,7 +86,17 @@ const AppleHealthSync = exports.AppleHealthSync = /*#__PURE__*/React.memo(({
|
|
|
64
86
|
}, [onError, onProgress]);
|
|
65
87
|
React.useEffect(() => {
|
|
66
88
|
return () => {
|
|
67
|
-
|
|
89
|
+
/*
|
|
90
|
+
* A teardown that throws takes the unmount with it, and React has no
|
|
91
|
+
* boundary for a cleanup function — so a sync that fails to stop
|
|
92
|
+
* became a crash on the way out of a screen. The error goes to the
|
|
93
|
+
* app's own handler, which is what `onError` is for.
|
|
94
|
+
*/
|
|
95
|
+
try {
|
|
96
|
+
serviceRef.current?.stopSync();
|
|
97
|
+
} catch (error) {
|
|
98
|
+
onErrorRef.current?.(error);
|
|
99
|
+
}
|
|
68
100
|
serviceRef.current = null;
|
|
69
101
|
};
|
|
70
102
|
}, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_core","require","_netinfo","React","_interopRequireWildcard","_useListenChanges","_appleHealthSyncService","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","AppleHealthSync","exports","memo","dataToSync","chunkSize","onError","onProgress","client","useClient","patient","useMedplumProfile","serviceRef","useRef","isConnected","type","useNetInfo","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","AppleHealthSyncService","getInstance","patientId","id","onSyncError","error","startSync","
|
|
1
|
+
{"version":3,"names":["_core","require","_netinfo","React","_interopRequireWildcard","_useListenChanges","_appleHealthSyncService","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","AppleHealthSync","exports","memo","dataToSync","chunkSize","onError","onProgress","client","useClient","patient","useMedplumProfile","serviceRef","useRef","isConnected","type","useNetInfo","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","AppleHealthSyncService","getInstance","patientId","id","onSyncError","error","startSync","useEffect","useListenChanges","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/apple/apple-health-sync.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -19,7 +19,11 @@ class BaseHealthSyncService {
|
|
|
19
19
|
this.storageManager = new _storageManager.StorageManager(props.client, this.getProviderName());
|
|
20
20
|
this.dataProcessor = new _dataProcessor.DataProcessor(props.client, props.patientId, this.getProviderName(), props.chunkSize ?? 5000, this.storageManager, this.getTotalCountsFunction(), this.getDataFromProviderFunction(), this.getConverterFunction());
|
|
21
21
|
}
|
|
22
|
+
/** One run at a time; see `SyncStateManager.once` for why that matters. */
|
|
22
23
|
async startSync() {
|
|
24
|
+
return this.stateManager.once(() => this.runSync());
|
|
25
|
+
}
|
|
26
|
+
async runSync() {
|
|
23
27
|
try {
|
|
24
28
|
if (!this.client.isInitialized) {
|
|
25
29
|
this.onSyncError(new Error("Client not initialized"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_dataProcessor","require","_storageManager","_syncProgressManager","_syncStateManager","BaseHealthSyncService","constructor","props","client","patientId","dataToSync","onSyncError","progressManager","SyncProgressManager","updateProgress","stateManager","SyncStateManager","storageManager","StorageManager","getProviderName","dataProcessor","DataProcessor","chunkSize","getTotalCountsFunction","getDataFromProviderFunction","getConverterFunction","startSync","isInitialized","Error","resume","setNotStartedStatuses","initialDataFetched","initializeSync","processAllDataTypes","setPauseStatuses","error","stopSync","resetAll","reset","shouldStopSync","pauseSync","pause","latestObservationDates","getLatestObservationDates","calculateTotalCounts","key","Object","keys","measurementTypeKey","data","getDataForMeasurementType","latestValidStartDate","getLatestValidStartDate","totalCount","getTotalRecordsCountForType","setTotalObservations","setStatus","syncDataByType","hasAnchor","observationBodies","currentHasAnchor","getObservationBodiesForType","entries","generateObservationEntries","incrementSyncedObservations","length","result","saveObservations","addResult","exports"],"sourceRoot":"../../../../../src","sources":["modules/data-sync/services/base-health-sync-service.ts"],"mappings":";;;;;;AAkBA,IAAAA,cAAA,GAAAC,OAAA;AACA,IAAAC,eAAA,GAAAD,OAAA;AACA,IAAAE,oBAAA,GAAAF,OAAA;AACA,IAAAG,iBAAA,GAAAH,OAAA;AAEO,MAAeI,qBAAqB,CAUzC;EAeAC,WAAWA,CAACC,KAAoC,EAAE;IAChD,IAAI,CAACC,MAAM,GAAGD,KAAK,CAACC,MAAM;IAC1B,IAAI,CAACC,SAAS,GAAGF,KAAK,CAACE,SAAS;IAChC,IAAI,CAACC,UAAU,GAAGH,KAAK,CAACG,UAAU;IAClC,IAAI,CAACC,WAAW,GAAGJ,KAAK,CAACI,WAAW;IAEpC,IAAI,CAACC,eAAe,GAAG,IAAIC,wCAAmB,CAC5CN,KAAK,CAACO,cAAc,EACpBP,KAAK,CAACG,UACR,CAAC;IACD,IAAI,CAACK,YAAY,GAAG,IAAIC,kCAAgB,CAAC,CAAC;IAC1C,IAAI,CAACC,cAAc,GAAG,IAAIC,8BAAc,CACtCX,KAAK,CAACC,MAAM,EACZ,IAAI,CAACW,eAAe,CAAC,CACvB,CAAC;IACD,IAAI,CAACC,aAAa,GAAG,IAAIC,4BAAa,CACpCd,KAAK,CAACC,MAAM,EACZD,KAAK,CAACE,SAAS,EACf,IAAI,CAACU,eAAe,CAAC,CAAC,EACtBZ,KAAK,CAACe,SAAS,IAAI,IAAI,EACvB,IAAI,CAACL,cAAc,EACnB,IAAI,CAACM,sBAAsB,CAAC,CAAC,EAC7B,IAAI,CAACC,2BAA2B,CAAC,CAAC,EAClC,IAAI,CAACC,oBAAoB,CAAC,CAC5B,CAAC;EACH;EAgBA,MAAaC,SAASA,CAAA,EAAkB;IACtC,IAAI;MACF,IAAI,CAAC,IAAI,
|
|
1
|
+
{"version":3,"names":["_dataProcessor","require","_storageManager","_syncProgressManager","_syncStateManager","BaseHealthSyncService","constructor","props","client","patientId","dataToSync","onSyncError","progressManager","SyncProgressManager","updateProgress","stateManager","SyncStateManager","storageManager","StorageManager","getProviderName","dataProcessor","DataProcessor","chunkSize","getTotalCountsFunction","getDataFromProviderFunction","getConverterFunction","startSync","once","runSync","isInitialized","Error","resume","setNotStartedStatuses","initialDataFetched","initializeSync","processAllDataTypes","setPauseStatuses","error","stopSync","resetAll","reset","shouldStopSync","pauseSync","pause","latestObservationDates","getLatestObservationDates","calculateTotalCounts","key","Object","keys","measurementTypeKey","data","getDataForMeasurementType","latestValidStartDate","getLatestValidStartDate","totalCount","getTotalRecordsCountForType","setTotalObservations","setStatus","syncDataByType","hasAnchor","observationBodies","currentHasAnchor","getObservationBodiesForType","entries","generateObservationEntries","incrementSyncedObservations","length","result","saveObservations","addResult","exports"],"sourceRoot":"../../../../../src","sources":["modules/data-sync/services/base-health-sync-service.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,6 +6,25 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.StorageManager = void 0;
|
|
7
7
|
var _saveBundleObservations = require("../../utils/save-bundle-observations.js");
|
|
8
8
|
class StorageManager {
|
|
9
|
+
/**
|
|
10
|
+
* Where an anchor goes when the host client has no storage.
|
|
11
|
+
*
|
|
12
|
+
* `clientStorage` is assigned from `OvokClient`'s `storage` option and from
|
|
13
|
+
* nowhere else, so a host that constructs its client without one leaves it
|
|
14
|
+
* `undefined` — and the `?.` below then swallowed every write while
|
|
15
|
+
* `getAnchor` answered `undefined` for ever. That is not a lost
|
|
16
|
+
* optimisation: `getObservationBodiesForType` reports `hasAnchor` from the
|
|
17
|
+
* anchor the provider just returned, and `syncDataByType` loops while it is
|
|
18
|
+
* true. An anchor that never advances means the next read starts from the
|
|
19
|
+
* beginning again, returns the same first chunk and the same anchor, and
|
|
20
|
+
* uploads it — for ever.
|
|
21
|
+
*
|
|
22
|
+
* The sync must not depend on what the host passed. This map keeps the
|
|
23
|
+
* anchor for the life of the service instance, which is what lets the loop
|
|
24
|
+
* end; when the host DOES provide storage the anchor also survives a
|
|
25
|
+
* restart, which is what keeps the next cold start short.
|
|
26
|
+
*/
|
|
27
|
+
inMemoryAnchors = new Map();
|
|
9
28
|
constructor(client, provider) {
|
|
10
29
|
this.client = client;
|
|
11
30
|
this.provider = provider;
|
|
@@ -17,10 +36,19 @@ class StorageManager {
|
|
|
17
36
|
});
|
|
18
37
|
}
|
|
19
38
|
saveAnchor(typeIdentifier, anchor) {
|
|
20
|
-
this.
|
|
39
|
+
const key = this.anchorKey(typeIdentifier);
|
|
40
|
+
if (this.client.clientStorage) {
|
|
41
|
+
this.client.clientStorage.setString(key, anchor);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.inMemoryAnchors.set(key, anchor);
|
|
21
45
|
}
|
|
22
46
|
getAnchor(typeIdentifier) {
|
|
23
|
-
|
|
47
|
+
const key = this.anchorKey(typeIdentifier);
|
|
48
|
+
return this.client.clientStorage ? this.client.clientStorage.getString(key) : this.inMemoryAnchors.get(key);
|
|
49
|
+
}
|
|
50
|
+
anchorKey(typeIdentifier) {
|
|
51
|
+
return `${this.provider}-sync-${typeIdentifier}-anchor`;
|
|
24
52
|
}
|
|
25
53
|
saveAnchors(anchors) {
|
|
26
54
|
anchors.forEach(({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_saveBundleObservations","require","StorageManager","constructor","client","provider","saveObservations","entries","saveBundleObservations","saveAnchor","typeIdentifier","anchor","clientStorage","setString","getAnchor","getString","saveAnchors","anchors","forEach","exports"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/storage-manager.ts"],"mappings":";;;;;;AAIA,IAAAA,uBAAA,GAAAC,OAAA;AAEO,MAAMC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"names":["_saveBundleObservations","require","StorageManager","inMemoryAnchors","Map","constructor","client","provider","saveObservations","entries","saveBundleObservations","saveAnchor","typeIdentifier","anchor","key","anchorKey","clientStorage","setString","set","getAnchor","getString","get","saveAnchors","anchors","forEach","exports"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/storage-manager.ts"],"mappings":";;;;;;AAIA,IAAAA,uBAAA,GAAAC,OAAA;AAEO,MAAMC,cAAc,CAAC;EAC1B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACmBC,eAAe,GAAG,IAAIC,GAAG,CAAiB,CAAC;EAE5DC,WAAWA,CACDC,MAAkB,EAClBC,QAAwB,EAChC;IAAA,KAFQD,MAAkB,GAAlBA,MAAkB;IAAA,KAClBC,QAAwB,GAAxBA,QAAwB;EAC/B;EAEH,MAAMC,gBAAgBA,CACpBC,OAAgE,EAClC;IAC9B,OAAO,IAAAC,8CAAsB,EAAC;MAC5BD,OAAO;MACPH,MAAM,EAAE,IAAI,CAACA;IACf,CAAC,CAAC;EACJ;EAEAK,UAAUA,CAACC,cAAsB,EAAEC,MAAc,EAAQ;IACvD,MAAMC,GAAG,GAAG,IAAI,CAACC,SAAS,CAACH,cAAc,CAAC;IAE1C,IAAI,IAAI,CAACN,MAAM,CAACU,aAAa,EAAE;MAC7B,IAAI,CAACV,MAAM,CAACU,aAAa,CAACC,SAAS,CAACH,GAAG,EAAED,MAAM,CAAC;MAEhD;IACF;IAEA,IAAI,CAACV,eAAe,CAACe,GAAG,CAACJ,GAAG,EAAED,MAAM,CAAC;EACvC;EAEAM,SAASA,CAACP,cAAsB,EAAsB;IACpD,MAAME,GAAG,GAAG,IAAI,CAACC,SAAS,CAACH,cAAc,CAAC;IAE1C,OAAO,IAAI,CAACN,MAAM,CAACU,aAAa,GAC5B,IAAI,CAACV,MAAM,CAACU,aAAa,CAACI,SAAS,CAACN,GAAG,CAAC,GACxC,IAAI,CAACX,eAAe,CAACkB,GAAG,CAACP,GAAG,CAAC;EACnC;EAEQC,SAASA,CAACH,cAAsB,EAAU;IAChD,OAAO,GAAG,IAAI,CAACL,QAAQ,SAASK,cAAc,SAAS;EACzD;EAEAU,WAAWA,CACTC,OAA0D,EACpD;IACNA,OAAO,CAACC,OAAO,CAAC,CAAC;MAAEZ,cAAc;MAAEC;IAAO,CAAC,KAAK;MAC9C,IAAI,CAACF,UAAU,CAACC,cAAc,EAAEC,MAAM,CAAC;IACzC,CAAC,CAAC;EACJ;AACF;AAACY,OAAA,CAAAvB,cAAA,GAAAA,cAAA","ignoreList":[]}
|
|
@@ -5,6 +5,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.SyncStateManager = void 0;
|
|
7
7
|
class SyncStateManager {
|
|
8
|
+
/**
|
|
9
|
+
* A sync in flight, so a second caller joins it rather than starting another.
|
|
10
|
+
*
|
|
11
|
+
* There are three callers and they overlap by construction:
|
|
12
|
+
* `InstanceManager.getInstanceInternal` starts one as a side effect of
|
|
13
|
+
* handing back the instance, the component starts one on mount, and the
|
|
14
|
+
* change subscription starts one whenever the provider reports new samples.
|
|
15
|
+
* Two runs over one data type read the same chunk and upload it twice,
|
|
16
|
+
* because the read cursor only advances once a read has returned.
|
|
17
|
+
*/
|
|
18
|
+
|
|
8
19
|
shouldStopSync = false;
|
|
9
20
|
initialDataFetched = false;
|
|
10
21
|
latestObservationDates = [];
|
|
@@ -12,6 +23,14 @@ class SyncStateManager {
|
|
|
12
23
|
addResult(result) {
|
|
13
24
|
this.results.push(result);
|
|
14
25
|
}
|
|
26
|
+
|
|
27
|
+
/** Runs `sync`, or joins the run already under way. */
|
|
28
|
+
async once(sync) {
|
|
29
|
+
this.inFlight ??= sync().finally(() => {
|
|
30
|
+
this.inFlight = undefined;
|
|
31
|
+
});
|
|
32
|
+
return this.inFlight;
|
|
33
|
+
}
|
|
15
34
|
reset() {
|
|
16
35
|
this.shouldStopSync = false;
|
|
17
36
|
this.initialDataFetched = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SyncStateManager","shouldStopSync","initialDataFetched","latestObservationDates","results","addResult","result","push","reset","pause","resume","exports"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/sync-state-manager.ts"],"mappings":";;;;;;AAEO,MAAMA,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"names":["SyncStateManager","shouldStopSync","initialDataFetched","latestObservationDates","results","addResult","result","push","once","sync","inFlight","finally","undefined","reset","pause","resume","exports"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/sync-state-manager.ts"],"mappings":";;;;;;AAEO,MAAMA,gBAAgB,CAAC;EAC5B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGSC,cAAc,GAAG,KAAK;EACtBC,kBAAkB,GAAG,KAAK;EAC1BC,sBAAsB,GAGxB,EAAE;EACAC,OAAO,GAA0B,EAAE;EAE1CC,SAASA,CAACC,MAA2B,EAAQ;IAC3C,IAAI,CAACF,OAAO,CAACG,IAAI,CAACD,MAAM,CAAC;EAC3B;;EAEA;EACA,MAAME,IAAIA,CAACC,IAAyB,EAAiB;IACnD,IAAI,CAACC,QAAQ,KAAKD,IAAI,CAAC,CAAC,CAACE,OAAO,CAAC,MAAM;MACrC,IAAI,CAACD,QAAQ,GAAGE,SAAS;IAC3B,CAAC,CAAC;IAEF,OAAO,IAAI,CAACF,QAAQ;EACtB;EAEAG,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACZ,cAAc,GAAG,KAAK;IAC3B,IAAI,CAACC,kBAAkB,GAAG,KAAK;IAC/B,IAAI,CAACC,sBAAsB,GAAG,EAAE;IAChC,IAAI,CAACC,OAAO,GAAG,EAAE;EACnB;EAEAU,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACb,cAAc,GAAG,IAAI;EAC5B;EAEAc,MAAMA,CAAA,EAAS;IACb,IAAI,CAACd,cAAc,GAAG,KAAK;EAC7B;AACF;AAACe,OAAA,CAAAhB,gBAAA,GAAAA,gBAAA","ignoreList":[]}
|
|
@@ -58,7 +58,17 @@ export const AndroidHealthSync = /*#__PURE__*/React.memo(({
|
|
|
58
58
|
}, [onError, onProgress]);
|
|
59
59
|
React.useEffect(() => {
|
|
60
60
|
return () => {
|
|
61
|
-
|
|
61
|
+
/*
|
|
62
|
+
* A teardown that throws takes the unmount with it, and React has no
|
|
63
|
+
* boundary for a cleanup function — so a sync that fails to stop
|
|
64
|
+
* became a crash on the way out of a screen. The error goes to the
|
|
65
|
+
* app's own handler, which is what `onError` is for.
|
|
66
|
+
*/
|
|
67
|
+
try {
|
|
68
|
+
serviceRef.current?.stopSync();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
onErrorRef.current?.(error);
|
|
71
|
+
}
|
|
62
72
|
serviceRef.current = null;
|
|
63
73
|
};
|
|
64
74
|
}, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","AndroidHealthSyncService","AndroidHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/android/android-health-sync.tsx"],"mappings":";;AAAA,SAEEA,SAAS,EACTC,iBAAiB,QACZ,YAAY;AACnB,SAASC,UAAU,QAAQ,iCAAiC;AAC5D,OAAO,KAAKC,KAAK,MAAM,OAAO;AAE9B,SAASC,wBAAwB,QAAQ,+CAA4C;AAIrF,OAAO,MAAMC,iBAAiB,gBAAGF,KAAK,CAACG,IAAI,CACzC,CAAC;EAAEC,UAAU;EAAEC,SAAS;EAAEC,OAAO;EAAEC;AAAmC,CAAC,KAAK;EAC1E,MAAMC,MAAM,GAAGX,SAAS,CAAC,CAAC;EAC1B,MAAMY,OAAO,GAAGX,iBAAiB,CAAC,CAAC;EACnC,MAAMY,UAAU,GAAGV,KAAK,CAACW,MAAM,CAAkC,IAAI,CAAC;EACtE,MAAM;IAAEC,WAAW;IAAEC;EAAK,CAAC,GAAGd,UAAU,CAAC,CAAC;EAE1C,MAAMe,UAAU,GAAGd,KAAK,CAACW,MAAM,CAACL,OAAO,CAAC;EACxC,MAAMS,aAAa,GAAGf,KAAK,CAACW,MAAM,CAACJ,UAAU,CAAC;EAE9C,MAAMS,WAAW,GAAGhB,KAAK,CAACW,MAAM,CAE9B,CAAC,CAAC,CAAC;EAEL,MAAMM,cAAc,GAAGjB,KAAK,CAACkB,WAAW,CAAEC,QAAsB,IAAK;IACnEH,WAAW,CAACI,OAAO,CAACD,QAAQ,CAACE,kBAAkB,CAAC,GAAGF,QAAQ;IAE3DJ,aAAa,CAACK,OAAO,GAAGJ,WAAW,CAACI,OAAO,CAAC;EAC9C,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,QAAQ,GAAGtB,KAAK,CAACkB,WAAW,CAAC,YAAY;IAC7C,IAAI;MACFR,UAAU,CAACU,OAAO,GAAGnB,wBAAwB,CAACsB,WAAW,CAAC;QACxDf,MAAM;QACNgB,SAAS,EAAEf,OAAO,EAAEgB,EAAE,IAAI,EAAE;QAC5BrB,UAAU;QACVC,SAAS;QACTqB,WAAW,EAAGC,KAAY,IAAKb,UAAU,CAACM,OAAO,GAAGO,KAAK,CAAC;QAC1DV;MACF,CAAC,CAAC;MAEF,MAAMP,UAAU,CAACU,OAAO,CAACQ,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,OAAOD,KAAK,EAAE;MACdb,UAAU,CAACM,OAAO,GAAGO,KAAc,CAAC;IACtC;EACF,CAAC,EAAE,CAACnB,MAAM,EAAEJ,UAAU,EAAEC,SAAS,EAAEI,OAAO,EAAEgB,EAAE,EAAER,cAAc,CAAC,CAAC;EAEhEjB,KAAK,CAAC6B,SAAS,CAAC,MAAM;IACpBP,QAAQ,CAAC,CAAC;EACZ,CAAC,EAAE,CAACA,QAAQ,CAAC,CAAC;EAEdtB,KAAK,CAAC6B,SAAS,CAAC,MAAM;IACpB,IAAI,CAACnB,UAAU,CAACU,OAAO,EAAE;MACvB;IACF;IAEA,IAAI,CAACR,WAAW,IAAIC,IAAI,KAAK,MAAM,EAAE;MACnCH,UAAU,CAACU,OAAO,CAACU,SAAS,CAAC,CAAC;MAE9B;IACF;IAEApB,UAAU,CAACU,OAAO,CAACQ,SAAS,CAAC,CAAC;EAChC,CAAC,EAAE,CAAChB,WAAW,EAAEC,IAAI,CAAC,CAAC;EAEvBb,KAAK,CAAC6B,SAAS,CAAC,MAAM;IACpBf,UAAU,CAACM,OAAO,GAAGd,OAAO;IAC5BS,aAAa,CAACK,OAAO,GAAGb,UAAU;EACpC,CAAC,EAAE,CAACD,OAAO,EAAEC,UAAU,CAAC,CAAC;EAEzBP,KAAK,CAAC6B,SAAS,CAAC,MAAM;IACpB,OAAO,MAAM;
|
|
1
|
+
{"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","AndroidHealthSyncService","AndroidHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/android/android-health-sync.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -40,6 +40,28 @@ export const AppleHealthSync = /*#__PURE__*/React.memo(({
|
|
|
40
40
|
onErrorRef.current?.(error);
|
|
41
41
|
}
|
|
42
42
|
}, [client, dataToSync, chunkSize, patient?.id, updateProgress]);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The first sync, which nothing used to start.
|
|
46
|
+
*
|
|
47
|
+
* `useListenChanges` subscribes to HealthKit observer queries, and the
|
|
48
|
+
* native side scopes those to samples that start from NOW —
|
|
49
|
+
* `HKQuery.predicateForSamples(withStart: Date.init(), …)` in
|
|
50
|
+
* `@kingstinct/react-native-healthkit`. So the subscription can never fire
|
|
51
|
+
* for data that already exists, and the only other caller, the network
|
|
52
|
+
* effect below, returns early while `serviceRef.current` is null — which
|
|
53
|
+
* only this path assigns. A patient installed the app, granted HealthKit
|
|
54
|
+
* and saw nothing: their existing history was never read, and nothing new
|
|
55
|
+
* arrived unless they moved with the app open.
|
|
56
|
+
*
|
|
57
|
+
* `startSync` reads the per-code watermark off the server and pages
|
|
58
|
+
* forward from it, so it IS the initial sync; it just had no caller here.
|
|
59
|
+
* `AndroidHealthSync` has had this effect all along — this is the platform
|
|
60
|
+
* catching up with its sibling, not a new mechanism.
|
|
61
|
+
*/
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
syncData();
|
|
64
|
+
}, [syncData]);
|
|
43
65
|
useListenChanges(dataToSync, () => {
|
|
44
66
|
syncData();
|
|
45
67
|
});
|
|
@@ -59,7 +81,17 @@ export const AppleHealthSync = /*#__PURE__*/React.memo(({
|
|
|
59
81
|
}, [onError, onProgress]);
|
|
60
82
|
React.useEffect(() => {
|
|
61
83
|
return () => {
|
|
62
|
-
|
|
84
|
+
/*
|
|
85
|
+
* A teardown that throws takes the unmount with it, and React has no
|
|
86
|
+
* boundary for a cleanup function — so a sync that fails to stop
|
|
87
|
+
* became a crash on the way out of a screen. The error goes to the
|
|
88
|
+
* app's own handler, which is what `onError` is for.
|
|
89
|
+
*/
|
|
90
|
+
try {
|
|
91
|
+
serviceRef.current?.stopSync();
|
|
92
|
+
} catch (error) {
|
|
93
|
+
onErrorRef.current?.(error);
|
|
94
|
+
}
|
|
63
95
|
serviceRef.current = null;
|
|
64
96
|
};
|
|
65
97
|
}, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","useListenChanges","AppleHealthSyncService","AppleHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/apple/apple-health-sync.tsx"],"mappings":";;AAAA,SAEEA,SAAS,EACTC,iBAAiB,QACZ,YAAY;AACnB,SAASC,UAAU,QAAQ,iCAAiC;AAC5D,OAAO,KAAKC,KAAK,MAAM,OAAO;AAE9B,SAASC,gBAAgB,QAAQ,mCAAgC;AACjE,SAASC,sBAAsB,QAAQ,6CAA0C;AAIjF,OAAO,MAAMC,eAAe,gBAAGH,KAAK,CAACI,IAAI,CACvC,CAAC;EAAEC,UAAU;EAAEC,SAAS;EAAEC,OAAO;EAAEC;AAAiC,CAAC,KAAK;EACxE,MAAMC,MAAM,GAAGZ,SAAS,CAAC,CAAC;EAC1B,MAAMa,OAAO,GAAGZ,iBAAiB,CAAC,CAAC;EACnC,MAAMa,UAAU,GAAGX,KAAK,CAACY,MAAM,CAAgC,IAAI,CAAC;EACpE,MAAM;IAAEC,WAAW;IAAEC;EAAK,CAAC,GAAGf,UAAU,CAAC,CAAC;EAE1C,MAAMgB,UAAU,GAAGf,KAAK,CAACY,MAAM,CAACL,OAAO,CAAC;EACxC,MAAMS,aAAa,GAAGhB,KAAK,CAACY,MAAM,CAACJ,UAAU,CAAC;EAE9C,MAAMS,WAAW,GAAGjB,KAAK,CAACY,MAAM,CAE9B,CAAC,CAAC,CAAC;EAEL,MAAMM,cAAc,GAAGlB,KAAK,CAACmB,WAAW,CAAEC,QAAsB,IAAK;IACnEH,WAAW,CAACI,OAAO,CAACD,QAAQ,CAACE,kBAAkB,CAAC,GAAGF,QAAQ;IAE3DJ,aAAa,CAACK,OAAO,GAAGJ,WAAW,CAACI,OAAO,CAAC;EAC9C,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,QAAQ,GAAGvB,KAAK,CAACmB,WAAW,CAAC,YAAY;IAC7C,IAAI;MACFR,UAAU,CAACU,OAAO,GAAGnB,sBAAsB,CAACsB,WAAW,CAAC;QACtDf,MAAM;QACNgB,SAAS,EAAEf,OAAO,EAAEgB,EAAE,IAAI,EAAE;QAC5BrB,UAAU;QACVC,SAAS;QACTqB,WAAW,EAAGC,KAAK,IAAKb,UAAU,CAACM,OAAO,GAAGO,KAAc,CAAC;QAC5DV;MACF,CAAC,CAAC;MAEF,MAAMP,UAAU,CAACU,OAAO,CAACQ,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,OAAOD,KAAK,EAAE;MACdb,UAAU,CAACM,OAAO,GAAGO,KAAc,CAAC;IACtC;EACF,CAAC,EAAE,CAACnB,MAAM,EAAEJ,UAAU,EAAEC,SAAS,EAAEI,OAAO,EAAEgB,EAAE,EAAER,cAAc,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["useClient","useMedplumProfile","useNetInfo","React","useListenChanges","AppleHealthSyncService","AppleHealthSync","memo","dataToSync","chunkSize","onError","onProgress","client","patient","serviceRef","useRef","isConnected","type","onErrorRef","onProgressRef","progressRef","updateProgress","useCallback","progress","current","measurementTypeKey","syncData","getInstance","patientId","id","onSyncError","error","startSync","useEffect","pauseSync","stopSync"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/components/apple/apple-health-sync.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -15,7 +15,11 @@ export class BaseHealthSyncService {
|
|
|
15
15
|
this.storageManager = new StorageManager(props.client, this.getProviderName());
|
|
16
16
|
this.dataProcessor = new DataProcessor(props.client, props.patientId, this.getProviderName(), props.chunkSize ?? 5000, this.storageManager, this.getTotalCountsFunction(), this.getDataFromProviderFunction(), this.getConverterFunction());
|
|
17
17
|
}
|
|
18
|
+
/** One run at a time; see `SyncStateManager.once` for why that matters. */
|
|
18
19
|
async startSync() {
|
|
20
|
+
return this.stateManager.once(() => this.runSync());
|
|
21
|
+
}
|
|
22
|
+
async runSync() {
|
|
19
23
|
try {
|
|
20
24
|
if (!this.client.isInitialized) {
|
|
21
25
|
this.onSyncError(new Error("Client not initialized"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["DataProcessor","StorageManager","SyncProgressManager","SyncStateManager","BaseHealthSyncService","constructor","props","client","patientId","dataToSync","onSyncError","progressManager","updateProgress","stateManager","storageManager","getProviderName","dataProcessor","chunkSize","getTotalCountsFunction","getDataFromProviderFunction","getConverterFunction","startSync","isInitialized","Error","resume","setNotStartedStatuses","initialDataFetched","initializeSync","processAllDataTypes","setPauseStatuses","error","stopSync","resetAll","reset","shouldStopSync","pauseSync","pause","latestObservationDates","getLatestObservationDates","calculateTotalCounts","key","Object","keys","measurementTypeKey","data","getDataForMeasurementType","latestValidStartDate","getLatestValidStartDate","totalCount","getTotalRecordsCountForType","setTotalObservations","setStatus","syncDataByType","hasAnchor","observationBodies","currentHasAnchor","getObservationBodiesForType","entries","generateObservationEntries","incrementSyncedObservations","length","result","saveObservations","addResult"],"sourceRoot":"../../../../../src","sources":["modules/data-sync/services/base-health-sync-service.ts"],"mappings":";;AAkBA,SAASA,aAAa,QAAQ,8BAA2B;AACzD,SAASC,cAAc,QAAQ,+BAA4B;AAC3D,SAASC,mBAAmB,QAAQ,qCAAkC;AACtE,SAASC,gBAAgB,QAAQ,kCAA+B;AAEhE,OAAO,MAAeC,qBAAqB,CAUzC;EAeAC,WAAWA,CAACC,KAAoC,EAAE;IAChD,IAAI,CAACC,MAAM,GAAGD,KAAK,CAACC,MAAM;IAC1B,IAAI,CAACC,SAAS,GAAGF,KAAK,CAACE,SAAS;IAChC,IAAI,CAACC,UAAU,GAAGH,KAAK,CAACG,UAAU;IAClC,IAAI,CAACC,WAAW,GAAGJ,KAAK,CAACI,WAAW;IAEpC,IAAI,CAACC,eAAe,GAAG,IAAIT,mBAAmB,CAC5CI,KAAK,CAACM,cAAc,EACpBN,KAAK,CAACG,UACR,CAAC;IACD,IAAI,CAACI,YAAY,GAAG,IAAIV,gBAAgB,CAAC,CAAC;IAC1C,IAAI,CAACW,cAAc,GAAG,IAAIb,cAAc,CACtCK,KAAK,CAACC,MAAM,EACZ,IAAI,CAACQ,eAAe,CAAC,CACvB,CAAC;IACD,IAAI,CAACC,aAAa,GAAG,IAAIhB,aAAa,CACpCM,KAAK,CAACC,MAAM,EACZD,KAAK,CAACE,SAAS,EACf,IAAI,CAACO,eAAe,CAAC,CAAC,EACtBT,KAAK,CAACW,SAAS,IAAI,IAAI,EACvB,IAAI,CAACH,cAAc,EACnB,IAAI,CAACI,sBAAsB,CAAC,CAAC,EAC7B,IAAI,CAACC,2BAA2B,CAAC,CAAC,EAClC,IAAI,CAACC,oBAAoB,CAAC,CAC5B,CAAC;EACH;EAgBA,MAAaC,SAASA,CAAA,EAAkB;IACtC,IAAI;MACF,IAAI,CAAC,IAAI,
|
|
1
|
+
{"version":3,"names":["DataProcessor","StorageManager","SyncProgressManager","SyncStateManager","BaseHealthSyncService","constructor","props","client","patientId","dataToSync","onSyncError","progressManager","updateProgress","stateManager","storageManager","getProviderName","dataProcessor","chunkSize","getTotalCountsFunction","getDataFromProviderFunction","getConverterFunction","startSync","once","runSync","isInitialized","Error","resume","setNotStartedStatuses","initialDataFetched","initializeSync","processAllDataTypes","setPauseStatuses","error","stopSync","resetAll","reset","shouldStopSync","pauseSync","pause","latestObservationDates","getLatestObservationDates","calculateTotalCounts","key","Object","keys","measurementTypeKey","data","getDataForMeasurementType","latestValidStartDate","getLatestValidStartDate","totalCount","getTotalRecordsCountForType","setTotalObservations","setStatus","syncDataByType","hasAnchor","observationBodies","currentHasAnchor","getObservationBodiesForType","entries","generateObservationEntries","incrementSyncedObservations","length","result","saveObservations","addResult"],"sourceRoot":"../../../../../src","sources":["modules/data-sync/services/base-health-sync-service.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
import { saveBundleObservations } from "../../utils/save-bundle-observations.js";
|
|
4
4
|
export class StorageManager {
|
|
5
|
+
/**
|
|
6
|
+
* Where an anchor goes when the host client has no storage.
|
|
7
|
+
*
|
|
8
|
+
* `clientStorage` is assigned from `OvokClient`'s `storage` option and from
|
|
9
|
+
* nowhere else, so a host that constructs its client without one leaves it
|
|
10
|
+
* `undefined` — and the `?.` below then swallowed every write while
|
|
11
|
+
* `getAnchor` answered `undefined` for ever. That is not a lost
|
|
12
|
+
* optimisation: `getObservationBodiesForType` reports `hasAnchor` from the
|
|
13
|
+
* anchor the provider just returned, and `syncDataByType` loops while it is
|
|
14
|
+
* true. An anchor that never advances means the next read starts from the
|
|
15
|
+
* beginning again, returns the same first chunk and the same anchor, and
|
|
16
|
+
* uploads it — for ever.
|
|
17
|
+
*
|
|
18
|
+
* The sync must not depend on what the host passed. This map keeps the
|
|
19
|
+
* anchor for the life of the service instance, which is what lets the loop
|
|
20
|
+
* end; when the host DOES provide storage the anchor also survives a
|
|
21
|
+
* restart, which is what keeps the next cold start short.
|
|
22
|
+
*/
|
|
23
|
+
inMemoryAnchors = new Map();
|
|
5
24
|
constructor(client, provider) {
|
|
6
25
|
this.client = client;
|
|
7
26
|
this.provider = provider;
|
|
@@ -13,10 +32,19 @@ export class StorageManager {
|
|
|
13
32
|
});
|
|
14
33
|
}
|
|
15
34
|
saveAnchor(typeIdentifier, anchor) {
|
|
16
|
-
this.
|
|
35
|
+
const key = this.anchorKey(typeIdentifier);
|
|
36
|
+
if (this.client.clientStorage) {
|
|
37
|
+
this.client.clientStorage.setString(key, anchor);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.inMemoryAnchors.set(key, anchor);
|
|
17
41
|
}
|
|
18
42
|
getAnchor(typeIdentifier) {
|
|
19
|
-
|
|
43
|
+
const key = this.anchorKey(typeIdentifier);
|
|
44
|
+
return this.client.clientStorage ? this.client.clientStorage.getString(key) : this.inMemoryAnchors.get(key);
|
|
45
|
+
}
|
|
46
|
+
anchorKey(typeIdentifier) {
|
|
47
|
+
return `${this.provider}-sync-${typeIdentifier}-anchor`;
|
|
20
48
|
}
|
|
21
49
|
saveAnchors(anchors) {
|
|
22
50
|
anchors.forEach(({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["saveBundleObservations","StorageManager","constructor","client","provider","saveObservations","entries","saveAnchor","typeIdentifier","anchor","clientStorage","setString","getAnchor","getString","saveAnchors","anchors","forEach"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/storage-manager.ts"],"mappings":";;AAIA,SAASA,sBAAsB,QAAQ,yCAAsC;AAE7E,OAAO,MAAMC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"names":["saveBundleObservations","StorageManager","inMemoryAnchors","Map","constructor","client","provider","saveObservations","entries","saveAnchor","typeIdentifier","anchor","key","anchorKey","clientStorage","setString","set","getAnchor","getString","get","saveAnchors","anchors","forEach"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/storage-manager.ts"],"mappings":";;AAIA,SAASA,sBAAsB,QAAQ,yCAAsC;AAE7E,OAAO,MAAMC,cAAc,CAAC;EAC1B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACmBC,eAAe,GAAG,IAAIC,GAAG,CAAiB,CAAC;EAE5DC,WAAWA,CACDC,MAAkB,EAClBC,QAAwB,EAChC;IAAA,KAFQD,MAAkB,GAAlBA,MAAkB;IAAA,KAClBC,QAAwB,GAAxBA,QAAwB;EAC/B;EAEH,MAAMC,gBAAgBA,CACpBC,OAAgE,EAClC;IAC9B,OAAOR,sBAAsB,CAAC;MAC5BQ,OAAO;MACPH,MAAM,EAAE,IAAI,CAACA;IACf,CAAC,CAAC;EACJ;EAEAI,UAAUA,CAACC,cAAsB,EAAEC,MAAc,EAAQ;IACvD,MAAMC,GAAG,GAAG,IAAI,CAACC,SAAS,CAACH,cAAc,CAAC;IAE1C,IAAI,IAAI,CAACL,MAAM,CAACS,aAAa,EAAE;MAC7B,IAAI,CAACT,MAAM,CAACS,aAAa,CAACC,SAAS,CAACH,GAAG,EAAED,MAAM,CAAC;MAEhD;IACF;IAEA,IAAI,CAACT,eAAe,CAACc,GAAG,CAACJ,GAAG,EAAED,MAAM,CAAC;EACvC;EAEAM,SAASA,CAACP,cAAsB,EAAsB;IACpD,MAAME,GAAG,GAAG,IAAI,CAACC,SAAS,CAACH,cAAc,CAAC;IAE1C,OAAO,IAAI,CAACL,MAAM,CAACS,aAAa,GAC5B,IAAI,CAACT,MAAM,CAACS,aAAa,CAACI,SAAS,CAACN,GAAG,CAAC,GACxC,IAAI,CAACV,eAAe,CAACiB,GAAG,CAACP,GAAG,CAAC;EACnC;EAEQC,SAASA,CAACH,cAAsB,EAAU;IAChD,OAAO,GAAG,IAAI,CAACJ,QAAQ,SAASI,cAAc,SAAS;EACzD;EAEAU,WAAWA,CACTC,OAA0D,EACpD;IACNA,OAAO,CAACC,OAAO,CAAC,CAAC;MAAEZ,cAAc;MAAEC;IAAO,CAAC,KAAK;MAC9C,IAAI,CAACF,UAAU,CAACC,cAAc,EAAEC,MAAM,CAAC;IACzC,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
export class SyncStateManager {
|
|
4
|
+
/**
|
|
5
|
+
* A sync in flight, so a second caller joins it rather than starting another.
|
|
6
|
+
*
|
|
7
|
+
* There are three callers and they overlap by construction:
|
|
8
|
+
* `InstanceManager.getInstanceInternal` starts one as a side effect of
|
|
9
|
+
* handing back the instance, the component starts one on mount, and the
|
|
10
|
+
* change subscription starts one whenever the provider reports new samples.
|
|
11
|
+
* Two runs over one data type read the same chunk and upload it twice,
|
|
12
|
+
* because the read cursor only advances once a read has returned.
|
|
13
|
+
*/
|
|
14
|
+
|
|
4
15
|
shouldStopSync = false;
|
|
5
16
|
initialDataFetched = false;
|
|
6
17
|
latestObservationDates = [];
|
|
@@ -8,6 +19,14 @@ export class SyncStateManager {
|
|
|
8
19
|
addResult(result) {
|
|
9
20
|
this.results.push(result);
|
|
10
21
|
}
|
|
22
|
+
|
|
23
|
+
/** Runs `sync`, or joins the run already under way. */
|
|
24
|
+
async once(sync) {
|
|
25
|
+
this.inFlight ??= sync().finally(() => {
|
|
26
|
+
this.inFlight = undefined;
|
|
27
|
+
});
|
|
28
|
+
return this.inFlight;
|
|
29
|
+
}
|
|
11
30
|
reset() {
|
|
12
31
|
this.shouldStopSync = false;
|
|
13
32
|
this.initialDataFetched = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SyncStateManager","shouldStopSync","initialDataFetched","latestObservationDates","results","addResult","result","push","reset","pause","resume"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/sync-state-manager.ts"],"mappings":";;AAEA,OAAO,MAAMA,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"names":["SyncStateManager","shouldStopSync","initialDataFetched","latestObservationDates","results","addResult","result","push","once","sync","inFlight","finally","undefined","reset","pause","resume"],"sourceRoot":"../../../../../../src","sources":["modules/data-sync/services/managers/sync-state-manager.ts"],"mappings":";;AAEA,OAAO,MAAMA,gBAAgB,CAAC;EAC5B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGSC,cAAc,GAAG,KAAK;EACtBC,kBAAkB,GAAG,KAAK;EAC1BC,sBAAsB,GAGxB,EAAE;EACAC,OAAO,GAA0B,EAAE;EAE1CC,SAASA,CAACC,MAA2B,EAAQ;IAC3C,IAAI,CAACF,OAAO,CAACG,IAAI,CAACD,MAAM,CAAC;EAC3B;;EAEA;EACA,MAAME,IAAIA,CAACC,IAAyB,EAAiB;IACnD,IAAI,CAACC,QAAQ,KAAKD,IAAI,CAAC,CAAC,CAACE,OAAO,CAAC,MAAM;MACrC,IAAI,CAACD,QAAQ,GAAGE,SAAS;IAC3B,CAAC,CAAC;IAEF,OAAO,IAAI,CAACF,QAAQ;EACtB;EAEAG,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACZ,cAAc,GAAG,KAAK;IAC3B,IAAI,CAACC,kBAAkB,GAAG,KAAK;IAC/B,IAAI,CAACC,sBAAsB,GAAG,EAAE;IAChC,IAAI,CAACC,OAAO,GAAG,EAAE;EACnB;EAEAU,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACb,cAAc,GAAG,IAAI;EAC5B;EAEAc,MAAMA,CAAA,EAAS;IACb,IAAI,CAACd,cAAc,GAAG,KAAK;EAC7B;AACF","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"android-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/android/android-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,eAAO,MAAM,iBAAiB,6EACqB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"android-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/android/android-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,eAAO,MAAM,iBAAiB,6EACqB,sBAAsB,UA+ExE,CAAC"}
|
package/lib/typescript/commonjs/src/modules/data-sync/components/apple/apple-health-sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apple-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/apple/apple-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAG3E,eAAO,MAAM,eAAe,6EACuB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"apple-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/apple/apple-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAG3E,eAAO,MAAM,eAAe,6EACuB,oBAAoB,UAqGtE,CAAC"}
|
package/lib/typescript/commonjs/src/modules/data-sync/services/base-health-sync-service.d.ts
CHANGED
|
@@ -23,7 +23,9 @@ export declare abstract class BaseHealthSyncService<TDataToSync extends AndroidH
|
|
|
23
23
|
protected abstract getTotalCountsFunction(): (props: GetTotalCountProps<TTypeIdentifier>) => Promise<number>;
|
|
24
24
|
protected abstract getDataFromProviderFunction(): (props: GetDataFromProviderProps<TTypeIdentifier>) => Promise<DataFromProviderResult<TDataFromProvider, TTypeIdentifier>>;
|
|
25
25
|
protected abstract getConverterFunction(): (props: ConvertDataProps<TDataFromProvider>) => Promise<Observation[]>;
|
|
26
|
+
/** One run at a time; see `SyncStateManager.once` for why that matters. */
|
|
26
27
|
startSync(): Promise<void>;
|
|
28
|
+
private runSync;
|
|
27
29
|
stopSync(): Promise<void>;
|
|
28
30
|
pauseSync(): Promise<void>;
|
|
29
31
|
private initializeSync;
|
package/lib/typescript/commonjs/src/modules/data-sync/services/base-health-sync-service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-health-sync-service.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/data-sync/services/base-health-sync-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ1D,8BAAsB,qBAAqB,CACzC,WAAW,SACP,sBAAsB,CAAC,YAAY,CAAC,GACpC,oBAAoB,CAAC,YAAY,CAAC,EACtC,eAAe,SAAS,wBAAwB,GAAG,UAAU,EAC7D,iBAAiB,GAAG,eAAe,SAAS,UAAU,GAClD,YAAY,CAAC,eAAe,CAAC,GAC7B,eAAe,SAAS,wBAAwB,GAC9C,gBAAgB,CAAC,eAAe,CAAC,GACjC,KAAK;IAEX,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IAErD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;gBAEU,KAAK,EAAE,gBAAgB,CAAC,WAAW,CAAC;IA2BhD,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,cAAc;IAEpD,SAAS,CAAC,QAAQ,CAAC,sBAAsB,IAAI,CAC3C,KAAK,EAAE,kBAAkB,CAAC,eAAe,CAAC,KACvC,OAAO,CAAC,MAAM,CAAC;IAEpB,SAAS,CAAC,QAAQ,CAAC,2BAA2B,IAAI,CAChD,KAAK,EAAE,wBAAwB,CAAC,eAAe,CAAC,KAC7C,OAAO,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAExE,SAAS,CAAC,QAAQ,CAAC,oBAAoB,IAAI,CACzC,KAAK,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,KACvC,OAAO,CAAC,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"base-health-sync-service.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/data-sync/services/base-health-sync-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ1D,8BAAsB,qBAAqB,CACzC,WAAW,SACP,sBAAsB,CAAC,YAAY,CAAC,GACpC,oBAAoB,CAAC,YAAY,CAAC,EACtC,eAAe,SAAS,wBAAwB,GAAG,UAAU,EAC7D,iBAAiB,GAAG,eAAe,SAAS,UAAU,GAClD,YAAY,CAAC,eAAe,CAAC,GAC7B,eAAe,SAAS,wBAAwB,GAC9C,gBAAgB,CAAC,eAAe,CAAC,GACjC,KAAK;IAEX,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IAErD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;gBAEU,KAAK,EAAE,gBAAgB,CAAC,WAAW,CAAC;IA2BhD,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,cAAc;IAEpD,SAAS,CAAC,QAAQ,CAAC,sBAAsB,IAAI,CAC3C,KAAK,EAAE,kBAAkB,CAAC,eAAe,CAAC,KACvC,OAAO,CAAC,MAAM,CAAC;IAEpB,SAAS,CAAC,QAAQ,CAAC,2BAA2B,IAAI,CAChD,KAAK,EAAE,wBAAwB,CAAC,eAAe,CAAC,KAC7C,OAAO,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAExE,SAAS,CAAC,QAAQ,CAAC,oBAAoB,IAAI,CACzC,KAAK,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,KACvC,OAAO,CAAC,WAAW,EAAE,CAAC;IAE3B,2EAA2E;IAC9D,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;YAIzB,OAAO;IA6BR,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAMzB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;YAIzB,cAAc;YAUd,oBAAoB;YAuBpB,mBAAmB;YAqBnB,cAAc;IAoD5B,OAAO,CAAC,yBAAyB;CAGlC"}
|
package/lib/typescript/commonjs/src/modules/data-sync/services/managers/storage-manager.d.ts
CHANGED
|
@@ -5,10 +5,30 @@ import { saveBundleObservations } from "../../utils/save-bundle-observations";
|
|
|
5
5
|
export declare class StorageManager {
|
|
6
6
|
private client;
|
|
7
7
|
private provider;
|
|
8
|
+
/**
|
|
9
|
+
* Where an anchor goes when the host client has no storage.
|
|
10
|
+
*
|
|
11
|
+
* `clientStorage` is assigned from `OvokClient`'s `storage` option and from
|
|
12
|
+
* nowhere else, so a host that constructs its client without one leaves it
|
|
13
|
+
* `undefined` — and the `?.` below then swallowed every write while
|
|
14
|
+
* `getAnchor` answered `undefined` for ever. That is not a lost
|
|
15
|
+
* optimisation: `getObservationBodiesForType` reports `hasAnchor` from the
|
|
16
|
+
* anchor the provider just returned, and `syncDataByType` loops while it is
|
|
17
|
+
* true. An anchor that never advances means the next read starts from the
|
|
18
|
+
* beginning again, returns the same first chunk and the same anchor, and
|
|
19
|
+
* uploads it — for ever.
|
|
20
|
+
*
|
|
21
|
+
* The sync must not depend on what the host passed. This map keeps the
|
|
22
|
+
* anchor for the life of the service instance, which is what lets the loop
|
|
23
|
+
* end; when the host DOES provide storage the anchor also survives a
|
|
24
|
+
* restart, which is what keeps the next cold start short.
|
|
25
|
+
*/
|
|
26
|
+
private readonly inMemoryAnchors;
|
|
8
27
|
constructor(client: OvokClient, provider: HealthProvider);
|
|
9
28
|
saveObservations(entries: Parameters<typeof saveBundleObservations>[0]["entries"]): Promise<Bundle<Observation>>;
|
|
10
29
|
saveAnchor(typeIdentifier: string, anchor: string): void;
|
|
11
30
|
getAnchor(typeIdentifier: string): string | undefined;
|
|
31
|
+
private anchorKey;
|
|
12
32
|
saveAnchors(anchors: Array<{
|
|
13
33
|
typeIdentifier: string;
|
|
14
34
|
anchor: string;
|
package/lib/typescript/commonjs/src/modules/data-sync/services/managers/storage-manager.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/storage-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,qBAAa,cAAc;
|
|
1
|
+
{"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/storage-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,qBAAa,cAAc;IAsBvB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAtBlB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;gBAGnD,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,cAAc;IAG5B,gBAAgB,CACpB,OAAO,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAC/D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAO/B,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAYxD,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQrD,OAAO,CAAC,SAAS;IAIjB,WAAW,CACT,OAAO,EAAE,KAAK,CAAC;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,GACzD,IAAI;CAKR"}
|
package/lib/typescript/commonjs/src/modules/data-sync/services/managers/sync-state-manager.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { Bundle, Observation } from "@medplum/fhirtypes";
|
|
2
2
|
export declare class SyncStateManager {
|
|
3
|
+
/**
|
|
4
|
+
* A sync in flight, so a second caller joins it rather than starting another.
|
|
5
|
+
*
|
|
6
|
+
* There are three callers and they overlap by construction:
|
|
7
|
+
* `InstanceManager.getInstanceInternal` starts one as a side effect of
|
|
8
|
+
* handing back the instance, the component starts one on mount, and the
|
|
9
|
+
* change subscription starts one whenever the provider reports new samples.
|
|
10
|
+
* Two runs over one data type read the same chunk and upload it twice,
|
|
11
|
+
* because the read cursor only advances once a read has returned.
|
|
12
|
+
*/
|
|
13
|
+
private inFlight;
|
|
3
14
|
shouldStopSync: boolean;
|
|
4
15
|
initialDataFetched: boolean;
|
|
5
16
|
latestObservationDates: Array<{
|
|
@@ -8,6 +19,8 @@ export declare class SyncStateManager {
|
|
|
8
19
|
}>;
|
|
9
20
|
results: Bundle<Observation>[];
|
|
10
21
|
addResult(result: Bundle<Observation>): void;
|
|
22
|
+
/** Runs `sync`, or joins the run already under way. */
|
|
23
|
+
once(sync: () => Promise<void>): Promise<void>;
|
|
11
24
|
reset(): void;
|
|
12
25
|
pause(): void;
|
|
13
26
|
resume(): void;
|
package/lib/typescript/commonjs/src/modules/data-sync/services/managers/sync-state-manager.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-state-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/sync-state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEzD,qBAAa,gBAAgB;
|
|
1
|
+
{"version":3,"file":"sync-state-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/sync-state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEzD,qBAAa,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ,CAA4B;IAErC,cAAc,UAAS;IACvB,kBAAkB,UAAS;IAC3B,sBAAsB,EAAE,KAAK,CAAC;QACnC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;KAC1B,CAAC,CAAM;IACD,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAM;IAE3C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI;IAI5C,uDAAuD;IACjD,IAAI,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD,KAAK,IAAI,IAAI;IAOb,KAAK,IAAI,IAAI;IAIb,MAAM,IAAI,IAAI;CAGf"}
|
package/lib/typescript/module/src/modules/data-sync/components/android/android-health-sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"android-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/android/android-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,eAAO,MAAM,iBAAiB,6EACqB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"android-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/android/android-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,eAAO,MAAM,iBAAiB,6EACqB,sBAAsB,UA+ExE,CAAC"}
|
package/lib/typescript/module/src/modules/data-sync/components/apple/apple-health-sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apple-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/apple/apple-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAG3E,eAAO,MAAM,eAAe,6EACuB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"apple-health-sync.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/components/apple/apple-health-sync.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAG3E,eAAO,MAAM,eAAe,6EACuB,oBAAoB,UAqGtE,CAAC"}
|
|
@@ -23,7 +23,9 @@ export declare abstract class BaseHealthSyncService<TDataToSync extends AndroidH
|
|
|
23
23
|
protected abstract getTotalCountsFunction(): (props: GetTotalCountProps<TTypeIdentifier>) => Promise<number>;
|
|
24
24
|
protected abstract getDataFromProviderFunction(): (props: GetDataFromProviderProps<TTypeIdentifier>) => Promise<DataFromProviderResult<TDataFromProvider, TTypeIdentifier>>;
|
|
25
25
|
protected abstract getConverterFunction(): (props: ConvertDataProps<TDataFromProvider>) => Promise<Observation[]>;
|
|
26
|
+
/** One run at a time; see `SyncStateManager.once` for why that matters. */
|
|
26
27
|
startSync(): Promise<void>;
|
|
28
|
+
private runSync;
|
|
27
29
|
stopSync(): Promise<void>;
|
|
28
30
|
pauseSync(): Promise<void>;
|
|
29
31
|
private initializeSync;
|
package/lib/typescript/module/src/modules/data-sync/services/base-health-sync-service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-health-sync-service.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/data-sync/services/base-health-sync-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ1D,8BAAsB,qBAAqB,CACzC,WAAW,SACP,sBAAsB,CAAC,YAAY,CAAC,GACpC,oBAAoB,CAAC,YAAY,CAAC,EACtC,eAAe,SAAS,wBAAwB,GAAG,UAAU,EAC7D,iBAAiB,GAAG,eAAe,SAAS,UAAU,GAClD,YAAY,CAAC,eAAe,CAAC,GAC7B,eAAe,SAAS,wBAAwB,GAC9C,gBAAgB,CAAC,eAAe,CAAC,GACjC,KAAK;IAEX,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IAErD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;gBAEU,KAAK,EAAE,gBAAgB,CAAC,WAAW,CAAC;IA2BhD,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,cAAc;IAEpD,SAAS,CAAC,QAAQ,CAAC,sBAAsB,IAAI,CAC3C,KAAK,EAAE,kBAAkB,CAAC,eAAe,CAAC,KACvC,OAAO,CAAC,MAAM,CAAC;IAEpB,SAAS,CAAC,QAAQ,CAAC,2BAA2B,IAAI,CAChD,KAAK,EAAE,wBAAwB,CAAC,eAAe,CAAC,KAC7C,OAAO,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAExE,SAAS,CAAC,QAAQ,CAAC,oBAAoB,IAAI,CACzC,KAAK,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,KACvC,OAAO,CAAC,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"base-health-sync-service.d.ts","sourceRoot":"","sources":["../../../../../../../src/modules/data-sync/services/base-health-sync-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ1D,8BAAsB,qBAAqB,CACzC,WAAW,SACP,sBAAsB,CAAC,YAAY,CAAC,GACpC,oBAAoB,CAAC,YAAY,CAAC,EACtC,eAAe,SAAS,wBAAwB,GAAG,UAAU,EAC7D,iBAAiB,GAAG,eAAe,SAAS,UAAU,GAClD,YAAY,CAAC,eAAe,CAAC,GAC7B,eAAe,SAAS,wBAAwB,GAC9C,gBAAgB,CAAC,eAAe,CAAC,GACjC,KAAK;IAEX,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IAErD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;gBAEU,KAAK,EAAE,gBAAgB,CAAC,WAAW,CAAC;IA2BhD,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,cAAc;IAEpD,SAAS,CAAC,QAAQ,CAAC,sBAAsB,IAAI,CAC3C,KAAK,EAAE,kBAAkB,CAAC,eAAe,CAAC,KACvC,OAAO,CAAC,MAAM,CAAC;IAEpB,SAAS,CAAC,QAAQ,CAAC,2BAA2B,IAAI,CAChD,KAAK,EAAE,wBAAwB,CAAC,eAAe,CAAC,KAC7C,OAAO,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAExE,SAAS,CAAC,QAAQ,CAAC,oBAAoB,IAAI,CACzC,KAAK,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,KACvC,OAAO,CAAC,WAAW,EAAE,CAAC;IAE3B,2EAA2E;IAC9D,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;YAIzB,OAAO;IA6BR,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAMzB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;YAIzB,cAAc;YAUd,oBAAoB;YAuBpB,mBAAmB;YAqBnB,cAAc;IAoD5B,OAAO,CAAC,yBAAyB;CAGlC"}
|
|
@@ -5,10 +5,30 @@ import { saveBundleObservations } from "../../utils/save-bundle-observations";
|
|
|
5
5
|
export declare class StorageManager {
|
|
6
6
|
private client;
|
|
7
7
|
private provider;
|
|
8
|
+
/**
|
|
9
|
+
* Where an anchor goes when the host client has no storage.
|
|
10
|
+
*
|
|
11
|
+
* `clientStorage` is assigned from `OvokClient`'s `storage` option and from
|
|
12
|
+
* nowhere else, so a host that constructs its client without one leaves it
|
|
13
|
+
* `undefined` — and the `?.` below then swallowed every write while
|
|
14
|
+
* `getAnchor` answered `undefined` for ever. That is not a lost
|
|
15
|
+
* optimisation: `getObservationBodiesForType` reports `hasAnchor` from the
|
|
16
|
+
* anchor the provider just returned, and `syncDataByType` loops while it is
|
|
17
|
+
* true. An anchor that never advances means the next read starts from the
|
|
18
|
+
* beginning again, returns the same first chunk and the same anchor, and
|
|
19
|
+
* uploads it — for ever.
|
|
20
|
+
*
|
|
21
|
+
* The sync must not depend on what the host passed. This map keeps the
|
|
22
|
+
* anchor for the life of the service instance, which is what lets the loop
|
|
23
|
+
* end; when the host DOES provide storage the anchor also survives a
|
|
24
|
+
* restart, which is what keeps the next cold start short.
|
|
25
|
+
*/
|
|
26
|
+
private readonly inMemoryAnchors;
|
|
8
27
|
constructor(client: OvokClient, provider: HealthProvider);
|
|
9
28
|
saveObservations(entries: Parameters<typeof saveBundleObservations>[0]["entries"]): Promise<Bundle<Observation>>;
|
|
10
29
|
saveAnchor(typeIdentifier: string, anchor: string): void;
|
|
11
30
|
getAnchor(typeIdentifier: string): string | undefined;
|
|
31
|
+
private anchorKey;
|
|
12
32
|
saveAnchors(anchors: Array<{
|
|
13
33
|
typeIdentifier: string;
|
|
14
34
|
anchor: string;
|
package/lib/typescript/module/src/modules/data-sync/services/managers/storage-manager.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/storage-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,qBAAa,cAAc;
|
|
1
|
+
{"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/storage-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,qBAAa,cAAc;IAsBvB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAtBlB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;gBAGnD,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,cAAc;IAG5B,gBAAgB,CACpB,OAAO,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAC/D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAO/B,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAYxD,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQrD,OAAO,CAAC,SAAS;IAIjB,WAAW,CACT,OAAO,EAAE,KAAK,CAAC;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,GACzD,IAAI;CAKR"}
|
package/lib/typescript/module/src/modules/data-sync/services/managers/sync-state-manager.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { Bundle, Observation } from "@medplum/fhirtypes";
|
|
2
2
|
export declare class SyncStateManager {
|
|
3
|
+
/**
|
|
4
|
+
* A sync in flight, so a second caller joins it rather than starting another.
|
|
5
|
+
*
|
|
6
|
+
* There are three callers and they overlap by construction:
|
|
7
|
+
* `InstanceManager.getInstanceInternal` starts one as a side effect of
|
|
8
|
+
* handing back the instance, the component starts one on mount, and the
|
|
9
|
+
* change subscription starts one whenever the provider reports new samples.
|
|
10
|
+
* Two runs over one data type read the same chunk and upload it twice,
|
|
11
|
+
* because the read cursor only advances once a read has returned.
|
|
12
|
+
*/
|
|
13
|
+
private inFlight;
|
|
3
14
|
shouldStopSync: boolean;
|
|
4
15
|
initialDataFetched: boolean;
|
|
5
16
|
latestObservationDates: Array<{
|
|
@@ -8,6 +19,8 @@ export declare class SyncStateManager {
|
|
|
8
19
|
}>;
|
|
9
20
|
results: Bundle<Observation>[];
|
|
10
21
|
addResult(result: Bundle<Observation>): void;
|
|
22
|
+
/** Runs `sync`, or joins the run already under way. */
|
|
23
|
+
once(sync: () => Promise<void>): Promise<void>;
|
|
11
24
|
reset(): void;
|
|
12
25
|
pause(): void;
|
|
13
26
|
resume(): void;
|
package/lib/typescript/module/src/modules/data-sync/services/managers/sync-state-manager.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-state-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/sync-state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEzD,qBAAa,gBAAgB;
|
|
1
|
+
{"version":3,"file":"sync-state-manager.d.ts","sourceRoot":"","sources":["../../../../../../../../src/modules/data-sync/services/managers/sync-state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEzD,qBAAa,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ,CAA4B;IAErC,cAAc,UAAS;IACvB,kBAAkB,UAAS;IAC3B,sBAAsB,EAAE,KAAK,CAAC;QACnC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;KAC1B,CAAC,CAAM;IACD,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAM;IAE3C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI;IAI5C,uDAAuD;IACjD,IAAI,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD,KAAK,IAAI,IAAI;IAOb,KAAK,IAAI,IAAI;IAIb,MAAM,IAAI,IAAI;CAGf"}
|