@comapeo/core 5.1.4 → 5.1.5
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/dist/mapeo-manager.d.ts.map +1 -1
- package/dist/sync/sync-api.d.ts +8 -1
- package/dist/sync/sync-api.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/mapeo-manager.js +10 -82
- package/src/sync/sync-api.js +26 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapeo-manager.d.ts","sourceRoot":"","sources":["../src/mapeo-manager.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mapeo-manager.d.ts","sourceRoot":"","sources":["../src/mapeo-manager.js"],"names":[],"mappings":"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"}
|
package/dist/sync/sync-api.d.ts
CHANGED
|
@@ -112,9 +112,16 @@ export class SyncApi extends TypedEmitter<SyncEvents> {
|
|
|
112
112
|
setAutostopDataSyncTimeout(autostopDataSyncAfter: null | number): void;
|
|
113
113
|
/**
|
|
114
114
|
* @param {SyncType} type
|
|
115
|
+
* @param {object} [options]
|
|
116
|
+
* @param {number} [options.timeoutMs] Timeout in milliseconds for max time
|
|
117
|
+
* to wait between sync state updates before giving up. As long as syncing is
|
|
118
|
+
* happening, this will never timeout, but if more than timeoutMs passes
|
|
119
|
+
* without any sync activity, then this will reject.
|
|
115
120
|
* @returns {Promise<void>}
|
|
116
121
|
*/
|
|
117
|
-
waitForSync(type: SyncType
|
|
122
|
+
waitForSync(type: SyncType, { timeoutMs }?: {
|
|
123
|
+
timeoutMs?: number | undefined;
|
|
124
|
+
} | undefined): Promise<void>;
|
|
118
125
|
[kHandleDiscoveryKey](discoveryKey: Buffer, protomux: import("protomux")<import("@hyperswarm/secret-stream")>): void;
|
|
119
126
|
/**
|
|
120
127
|
* Request a graceful stop to all sync.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-api.d.ts","sourceRoot":"","sources":["../../src/sync/sync-api.js"],"names":[],"mappings":"AAcA,2EAA2E;AAC3E,yCAAyC;AACzC,4DAA4D;AAC5D,iFAAiF;AACjF,mEAAmE;AAEnE,gDAAiE;AACjE,uCAA8C;AAC9C,6CAAoD;AACpD,oDAA2D;AAC3D,wDAEC;AAED;;GAEG;AAEH;;GAEG;AAEH;;;;;;;GAOG;AAEH;;;;;;GAMG;AAEH;;;;;GAKG;AAEH;;;;;GAKG;AAEH;;;GAGG;AAEH;;GAEG;AACH;IA4BE;;;;;;;;;;;OAWG;IACH,gJAVG;QAA6D,WAAW,EAAhE,OAAO,0BAA0B,EAAE,WAAW;QAC1B,aAAa,EAAjC,aAAa;QACqB,KAAK,EAAvC,OAAO,aAAa,EAAE,KAAK;QACO,aAAa,UAAzC,MAAM,KAAK,SAAS;QACY,sBAAsB,EAA5D,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACD,oBAAoB,EAAlD,MAAM,iBAAiB;QAC0B,SAAS,EAA1D,OAAO,wBAAwB,EAAE,SAAS;QAC5B,UAAU;QACV,MAAM;KAAC,EAkD/B;IA8BD;;;OAGG;IACH,YAFa,KAAK,CAIjB;IAqHD;;OAEG;IACH,kBAFa,IAAI,CAsDhB;IAED;;OAEG;IACH,qBAFa,IAAI,CAQhB;IAED;;;;;;;;;;OAUG;IACH;;yBAOC;IAED;;;;OAIG;IACH,aAGC;IAkBD;;;OAGG;IACH,kDAHW,IAAI,GAAG,MAAM,GACX,IAAI,CAOhB;IAED
|
|
1
|
+
{"version":3,"file":"sync-api.d.ts","sourceRoot":"","sources":["../../src/sync/sync-api.js"],"names":[],"mappings":"AAcA,2EAA2E;AAC3E,yCAAyC;AACzC,4DAA4D;AAC5D,iFAAiF;AACjF,mEAAmE;AAEnE,gDAAiE;AACjE,uCAA8C;AAC9C,6CAAoD;AACpD,oDAA2D;AAC3D,wDAEC;AAED;;GAEG;AAEH;;GAEG;AAEH;;;;;;;GAOG;AAEH;;;;;;GAMG;AAEH;;;;;GAKG;AAEH;;;;;GAKG;AAEH;;;GAGG;AAEH;;GAEG;AACH;IA4BE;;;;;;;;;;;OAWG;IACH,gJAVG;QAA6D,WAAW,EAAhE,OAAO,0BAA0B,EAAE,WAAW;QAC1B,aAAa,EAAjC,aAAa;QACqB,KAAK,EAAvC,OAAO,aAAa,EAAE,KAAK;QACO,aAAa,UAAzC,MAAM,KAAK,SAAS;QACY,sBAAsB,EAA5D,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACD,oBAAoB,EAAlD,MAAM,iBAAiB;QAC0B,SAAS,EAA1D,OAAO,wBAAwB,EAAE,SAAS;QAC5B,UAAU;QACV,MAAM;KAAC,EAkD/B;IA8BD;;;OAGG;IACH,YAFa,KAAK,CAIjB;IAqHD;;OAEG;IACH,kBAFa,IAAI,CAsDhB;IAED;;OAEG;IACH,qBAFa,IAAI,CAQhB;IAED;;;;;;;;;;OAUG;IACH;;yBAOC;IAED;;;;OAIG;IACH,aAGC;IAkBD;;;OAGG;IACH,kDAHW,IAAI,GAAG,MAAM,GACX,IAAI,CAOhB;IAED;;;;;;;;OAQG;IACH,kBARW,QAAQ;;oBAMN,OAAO,CAAC,IAAI,CAAC,CAwBzB;oFA1BiC,2BAA2B;IAhC7D;;OAEG;IACH,2BAGC;IAED;;OAEG;IACH,kCAGC;IA8CD;;;;OAIG;IACH,wCAJW,MAAM,eACN,WAAW,GACT,OAAO,CAAC,IAAI,CAAC,CA6BzB;IApXC,wBAME;;CA6fL;uBA5mBY,SAAS,GAAG,MAAM;+BAIlB,MAAM,GAAG,SAAS,GAAG,KAAK;;WAMzB,MAAM;YACN,MAAM;gBACN,MAAM;YACN,MAAM;;;;;;mBAMN,OAAO;;;;UACP,MAAM;;;;YACN,MAAM;;;;;;;;;aAMN,mCAAmC;;;;UACnC,mCAAmC;;;;;;aAKnC;QAAE,aAAa,EAAE,OAAO,CAAA;KAAE;;;;UAC1B;QAAE,aAAa,EAAE,OAAO,CAAA;KAAE;;;;2BAC1B,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC;;;kBAKrC,CAAC,SAAS,EAAE,KAAK,KAAK,IAAI;;6BArEX,oBAAoB;0BAEvB,iBAAiB;mCAcR,sBAAsB;sBAfnC,IAAI;uCAiByB,aAAa;uBAdzC,cAAc"}
|
package/package.json
CHANGED
package/src/mapeo-manager.js
CHANGED
|
@@ -47,13 +47,8 @@ import { getFastifyServerAddress } from './fastify-plugins/utils.js'
|
|
|
47
47
|
import { LocalPeers } from './local-peers.js'
|
|
48
48
|
import { InviteApi } from './invite/invite-api.js'
|
|
49
49
|
import { LocalDiscovery } from './discovery/local-discovery.js'
|
|
50
|
-
import { Roles } from './roles.js'
|
|
51
50
|
import { Logger } from './logger.js'
|
|
52
|
-
import {
|
|
53
|
-
kSyncState,
|
|
54
|
-
kRequestFullStop,
|
|
55
|
-
kRescindFullStopRequest,
|
|
56
|
-
} from './sync/sync-api.js'
|
|
51
|
+
import { kRequestFullStop, kRescindFullStopRequest } from './sync/sync-api.js'
|
|
57
52
|
import { NotFoundError } from './errors.js'
|
|
58
53
|
import { WebSocket } from 'ws'
|
|
59
54
|
import { excludeKeys } from 'filter-obj'
|
|
@@ -79,6 +74,9 @@ const CLIENT_SQLITE_FILE_NAME = 'client.db'
|
|
|
79
74
|
// other things e.g. SQLite and other parts of the app.
|
|
80
75
|
const MAX_FILE_DESCRIPTORS = 768
|
|
81
76
|
|
|
77
|
+
// This is the timeout for waiting for sync state updates during initial sync (when adding a project or leaving a project)
|
|
78
|
+
const INITIAL_SYNC_TIMEOUT_MS = 45_000 // 45 seconds
|
|
79
|
+
|
|
82
80
|
// Prefix names for routes registered with http server
|
|
83
81
|
const BLOBS_PREFIX = 'blobs'
|
|
84
82
|
const ICONS_PREFIX = 'icons'
|
|
@@ -767,7 +765,9 @@ export class MapeoManager extends TypedEmitter {
|
|
|
767
765
|
// 5. Wait for initial project sync
|
|
768
766
|
if (waitForSync) {
|
|
769
767
|
try {
|
|
770
|
-
await
|
|
768
|
+
await project.$sync.waitForSync('initial', {
|
|
769
|
+
timeoutMs: INITIAL_SYNC_TIMEOUT_MS,
|
|
770
|
+
})
|
|
771
771
|
} catch (e) {
|
|
772
772
|
this.#l.log('ERROR: could not do initial project sync', e)
|
|
773
773
|
}
|
|
@@ -776,80 +776,6 @@ export class MapeoManager extends TypedEmitter {
|
|
|
776
776
|
return projectPublicId
|
|
777
777
|
}
|
|
778
778
|
|
|
779
|
-
/**
|
|
780
|
-
* Sync initial data: the `auth` cores which contain the role messages,
|
|
781
|
-
* and the `config` cores which contain the project name & custom config (if
|
|
782
|
-
* it exists). The API consumer should await this after `client.addProject()`
|
|
783
|
-
* to ensure that the device is fully added to the project.
|
|
784
|
-
*
|
|
785
|
-
* @param {MapeoProject} project
|
|
786
|
-
* @param {object} [opts]
|
|
787
|
-
* @param {number} [opts.timeoutMs=45_000] Timeout in milliseconds for max time
|
|
788
|
-
* to wait between sync status updates before giving up. As long as syncing is
|
|
789
|
-
* happening, this will never timeout, but if more than timeoutMs passes
|
|
790
|
-
* without any sync activity, then this will resolve `false` e.g. data has not
|
|
791
|
-
* synced
|
|
792
|
-
* @returns {Promise<boolean>}
|
|
793
|
-
*/
|
|
794
|
-
async #waitForInitialSync(project, { timeoutMs = 45_000 } = {}) {
|
|
795
|
-
const [ownRole, isProjectSettingsSynced] = await Promise.all([
|
|
796
|
-
project.$getOwnRole(),
|
|
797
|
-
project.$hasSyncedProjectSettings(),
|
|
798
|
-
])
|
|
799
|
-
const {
|
|
800
|
-
auth: { localState: authState },
|
|
801
|
-
config: { localState: configState },
|
|
802
|
-
} = project.$sync[kSyncState].getState()
|
|
803
|
-
const isRoleSynced = ownRole !== Roles.NO_ROLE
|
|
804
|
-
// Assumes every project that someone is invited to has at least one record
|
|
805
|
-
// in the auth store - the row record for the invited device
|
|
806
|
-
const isAuthSynced = authState.want === 0 && authState.have > 0
|
|
807
|
-
// Assumes every project that someone is invited to has at least one record
|
|
808
|
-
// in the config store - defining the name of the project.
|
|
809
|
-
// TODO: Enforce adding a project name in the invite method
|
|
810
|
-
const isConfigSynced = configState.want === 0 && configState.have > 0
|
|
811
|
-
if (isRoleSynced && ownRole.sync.config === 'blocked' && isAuthSynced) {
|
|
812
|
-
return true
|
|
813
|
-
}
|
|
814
|
-
if (
|
|
815
|
-
isRoleSynced &&
|
|
816
|
-
isProjectSettingsSynced &&
|
|
817
|
-
isAuthSynced &&
|
|
818
|
-
isConfigSynced
|
|
819
|
-
) {
|
|
820
|
-
return true
|
|
821
|
-
} else {
|
|
822
|
-
this.#l.log(
|
|
823
|
-
'Pending initial sync: role %s, projectSettings %o, auth %o, config %o',
|
|
824
|
-
isRoleSynced,
|
|
825
|
-
isProjectSettingsSynced,
|
|
826
|
-
isAuthSynced,
|
|
827
|
-
isConfigSynced
|
|
828
|
-
)
|
|
829
|
-
}
|
|
830
|
-
return new Promise((resolve, reject) => {
|
|
831
|
-
/** @param {import('./sync/sync-state.js').State} syncState */
|
|
832
|
-
const onSyncState = (syncState) => {
|
|
833
|
-
clearTimeout(timeoutId)
|
|
834
|
-
if (
|
|
835
|
-
syncState.auth.dataToSync ||
|
|
836
|
-
(syncState.config.dataToSync && ownRole.sync.config === 'allowed')
|
|
837
|
-
) {
|
|
838
|
-
timeoutId = setTimeout(onTimeout, timeoutMs)
|
|
839
|
-
return
|
|
840
|
-
}
|
|
841
|
-
project.$sync[kSyncState].off('state', onSyncState)
|
|
842
|
-
this.#waitForInitialSync(project, { timeoutMs }).then(resolve, reject)
|
|
843
|
-
}
|
|
844
|
-
const onTimeout = () => {
|
|
845
|
-
project.$sync[kSyncState].off('state', onSyncState)
|
|
846
|
-
reject(new Error('Sync timeout'))
|
|
847
|
-
}
|
|
848
|
-
let timeoutId = setTimeout(onTimeout, timeoutMs)
|
|
849
|
-
project.$sync[kSyncState].on('state', onSyncState)
|
|
850
|
-
})
|
|
851
|
-
}
|
|
852
|
-
|
|
853
779
|
/**
|
|
854
780
|
* @typedef {import('./schema/client.js').DeviceInfoParam['deviceType']} RPCDeviceType
|
|
855
781
|
*/
|
|
@@ -1074,7 +1000,9 @@ export class MapeoManager extends TypedEmitter {
|
|
|
1074
1000
|
await project[kProjectLeave]()
|
|
1075
1001
|
|
|
1076
1002
|
// Sync any role changes from project leave
|
|
1077
|
-
await
|
|
1003
|
+
await project.$sync.waitForSync('initial', {
|
|
1004
|
+
timeoutMs: INITIAL_SYNC_TIMEOUT_MS,
|
|
1005
|
+
})
|
|
1078
1006
|
}
|
|
1079
1007
|
|
|
1080
1008
|
async getMapStyleJsonUrl() {
|
package/src/sync/sync-api.js
CHANGED
|
@@ -441,18 +441,34 @@ export class SyncApi extends TypedEmitter {
|
|
|
441
441
|
|
|
442
442
|
/**
|
|
443
443
|
* @param {SyncType} type
|
|
444
|
+
* @param {object} [options]
|
|
445
|
+
* @param {number} [options.timeoutMs] Timeout in milliseconds for max time
|
|
446
|
+
* to wait between sync state updates before giving up. As long as syncing is
|
|
447
|
+
* happening, this will never timeout, but if more than timeoutMs passes
|
|
448
|
+
* without any sync activity, then this will reject.
|
|
444
449
|
* @returns {Promise<void>}
|
|
445
450
|
*/
|
|
446
|
-
async waitForSync(type) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
451
|
+
async waitForSync(type, { timeoutMs } = {}) {
|
|
452
|
+
return new Promise((resolve, reject) => {
|
|
453
|
+
/** @type {NodeJS.Timeout | undefined} */
|
|
454
|
+
let timeoutId
|
|
455
|
+
const onTimeout = () => {
|
|
456
|
+
this[kSyncState].off('state', onState)
|
|
457
|
+
reject(new Error('Sync timeout'))
|
|
458
|
+
}
|
|
459
|
+
/** @param {import('./sync-state.js').State} state */
|
|
460
|
+
const onState = (state) => {
|
|
461
|
+
clearTimeout(timeoutId)
|
|
462
|
+
if (typeof timeoutMs === 'number') {
|
|
463
|
+
timeoutId = setTimeout(onTimeout, timeoutMs)
|
|
464
|
+
}
|
|
465
|
+
if (isSynced(state, type, this.#peerSyncControllers)) {
|
|
466
|
+
this[kSyncState].off('state', onState)
|
|
467
|
+
resolve()
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
this[kSyncState].on('state', onState)
|
|
471
|
+
onState(this[kSyncState].getState())
|
|
456
472
|
})
|
|
457
473
|
}
|
|
458
474
|
|