@vrtmrz/livesync-commonlib 0.1.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/API/DirectFileManipulator.d.ts +2 -0
  4. package/dist/API/DirectFileManipulator.js +4 -0
  5. package/dist/API/DirectFileManipulatorV2.d.ts +150 -0
  6. package/dist/API/DirectFileManipulatorV2.js +424 -0
  7. package/dist/API/processSetting.d.ts +41 -0
  8. package/dist/API/processSetting.js +140 -0
  9. package/dist/ContentSplitter/ContentSplitter.d.ts +28 -0
  10. package/dist/ContentSplitter/ContentSplitter.js +5 -0
  11. package/dist/ContentSplitter/ContentSplitterBase.d.ts +51 -0
  12. package/dist/ContentSplitter/ContentSplitterBase.js +83 -0
  13. package/dist/ContentSplitter/ContentSplitterRabinKarp.d.ts +9 -0
  14. package/dist/ContentSplitter/ContentSplitterRabinKarp.js +32 -0
  15. package/dist/ContentSplitter/ContentSplitterV1.d.ts +9 -0
  16. package/dist/ContentSplitter/ContentSplitterV1.js +34 -0
  17. package/dist/ContentSplitter/ContentSplitterV2.d.ts +9 -0
  18. package/dist/ContentSplitter/ContentSplitterV2.js +34 -0
  19. package/dist/ContentSplitter/ContentSplitters.d.ts +12 -0
  20. package/dist/ContentSplitter/ContentSplitters.js +29 -0
  21. package/dist/bureau/bureau.d.ts +7 -0
  22. package/dist/bureau/bureau.js +5 -0
  23. package/dist/common/ConnectionString.d.ts +30 -0
  24. package/dist/common/ConnectionString.js +179 -0
  25. package/dist/common/LSError.d.ts +48 -0
  26. package/dist/common/LSError.js +112 -0
  27. package/dist/common/configForDoc.d.ts +79 -0
  28. package/dist/common/configForDoc.js +312 -0
  29. package/dist/common/coreEnvFunctions.d.ts +21 -0
  30. package/dist/common/coreEnvFunctions.js +22 -0
  31. package/dist/common/coreEnvVars.d.ts +3 -0
  32. package/dist/common/coreEnvVars.js +6 -0
  33. package/dist/common/i18n.d.ts +18 -0
  34. package/dist/common/i18n.js +7193 -0
  35. package/dist/common/logger.d.ts +2 -0
  36. package/dist/common/logger.js +1 -0
  37. package/dist/common/messages/combinedMessages.dev.d.ts +7 -0
  38. package/dist/common/messages/combinedMessages.dev.js +44 -0
  39. package/dist/common/messages/combinedMessages.prod.d.ts +9264 -0
  40. package/dist/common/messages/combinedMessages.prod.js +9271 -0
  41. package/dist/common/messages/de.d.ts +297 -0
  42. package/dist/common/messages/de.js +7 -0
  43. package/dist/common/messages/def.d.ts +1119 -0
  44. package/dist/common/messages/def.js +7 -0
  45. package/dist/common/messages/es.d.ts +689 -0
  46. package/dist/common/messages/es.js +7 -0
  47. package/dist/common/messages/fr.d.ts +582 -0
  48. package/dist/common/messages/fr.js +7 -0
  49. package/dist/common/messages/he.d.ts +583 -0
  50. package/dist/common/messages/he.js +7 -0
  51. package/dist/common/messages/ja.d.ts +838 -0
  52. package/dist/common/messages/ja.js +7 -0
  53. package/dist/common/messages/ko.d.ts +800 -0
  54. package/dist/common/messages/ko.js +7 -0
  55. package/dist/common/messages/ru.d.ts +858 -0
  56. package/dist/common/messages/ru.js +7 -0
  57. package/dist/common/messages/zh-tw.d.ts +384 -0
  58. package/dist/common/messages/zh-tw.js +7 -0
  59. package/dist/common/messages/zh.d.ts +1093 -0
  60. package/dist/common/messages/zh.js +7 -0
  61. package/dist/common/messagesJson/de.json +295 -0
  62. package/dist/common/messagesJson/en.json +1117 -0
  63. package/dist/common/messagesJson/es.json +687 -0
  64. package/dist/common/messagesJson/fr.json +580 -0
  65. package/dist/common/messagesJson/he.json +581 -0
  66. package/dist/common/messagesJson/ja.json +836 -0
  67. package/dist/common/messagesJson/ko.json +798 -0
  68. package/dist/common/messagesJson/ru.json +856 -0
  69. package/dist/common/messagesJson/zh-tw.json +382 -0
  70. package/dist/common/messagesJson/zh.json +1091 -0
  71. package/dist/common/models/auth.type.d.ts +41 -0
  72. package/dist/common/models/auth.type.js +0 -0
  73. package/dist/common/models/db.const.d.ts +20 -0
  74. package/dist/common/models/db.const.js +28 -0
  75. package/dist/common/models/db.definition.d.ts +56 -0
  76. package/dist/common/models/db.definition.js +6 -0
  77. package/dist/common/models/db.type.d.ts +142 -0
  78. package/dist/common/models/db.type.js +0 -0
  79. package/dist/common/models/diff.definition.d.ts +16 -0
  80. package/dist/common/models/diff.definition.js +0 -0
  81. package/dist/common/models/fileaccess.const.d.ts +7 -0
  82. package/dist/common/models/fileaccess.const.js +16 -0
  83. package/dist/common/models/fileaccess.type.d.ts +72 -0
  84. package/dist/common/models/fileaccess.type.js +0 -0
  85. package/dist/common/models/redflag.const.d.ts +32 -0
  86. package/dist/common/models/redflag.const.js +27 -0
  87. package/dist/common/models/setting.const.d.ts +49 -0
  88. package/dist/common/models/setting.const.defaults.d.ts +3 -0
  89. package/dist/common/models/setting.const.defaults.js +185 -0
  90. package/dist/common/models/setting.const.js +68 -0
  91. package/dist/common/models/setting.const.preferred.d.ts +5 -0
  92. package/dist/common/models/setting.const.preferred.js +35 -0
  93. package/dist/common/models/setting.const.qr.d.ts +2 -0
  94. package/dist/common/models/setting.const.qr.js +174 -0
  95. package/dist/common/models/setting.type.d.ts +900 -0
  96. package/dist/common/models/setting.type.js +8 -0
  97. package/dist/common/models/shared.const.behabiour.d.ts +28 -0
  98. package/dist/common/models/shared.const.behabiour.js +36 -0
  99. package/dist/common/models/shared.const.d.ts +5 -0
  100. package/dist/common/models/shared.const.js +12 -0
  101. package/dist/common/models/shared.const.symbols.d.ts +9 -0
  102. package/dist/common/models/shared.const.symbols.js +20 -0
  103. package/dist/common/models/shared.definition.configNames.d.ts +36 -0
  104. package/dist/common/models/shared.definition.configNames.js +203 -0
  105. package/dist/common/models/shared.definition.d.ts +22 -0
  106. package/dist/common/models/shared.definition.js +24 -0
  107. package/dist/common/models/shared.type.util.d.ts +8 -0
  108. package/dist/common/models/shared.type.util.js +0 -0
  109. package/dist/common/models/sync.definition.d.ts +18 -0
  110. package/dist/common/models/sync.definition.js +20 -0
  111. package/dist/common/models/tweak.definition.d.ts +191 -0
  112. package/dist/common/models/tweak.definition.js +77 -0
  113. package/dist/common/rosetta.d.ts +42 -0
  114. package/dist/common/rosetta.js +57 -0
  115. package/dist/common/settingConstants.d.ts +216 -0
  116. package/dist/common/settingConstants.js +434 -0
  117. package/dist/common/typeUtils.d.ts +17 -0
  118. package/dist/common/typeUtils.js +51 -0
  119. package/dist/common/types.d.ts +107 -0
  120. package/dist/common/types.js +212 -0
  121. package/dist/common/utils.d.ts +129 -0
  122. package/dist/common/utils.doc.d.ts +11 -0
  123. package/dist/common/utils.doc.js +35 -0
  124. package/dist/common/utils.js +583 -0
  125. package/dist/common/utils.object.d.ts +2 -0
  126. package/dist/common/utils.object.js +14 -0
  127. package/dist/common/utils.patch.d.ts +8 -0
  128. package/dist/common/utils.patch.js +178 -0
  129. package/dist/common/utils.type.d.ts +1 -0
  130. package/dist/common/utils.type.js +0 -0
  131. package/dist/context.d.ts +8 -0
  132. package/dist/context.js +14 -0
  133. package/dist/databases/IndexedDBKeyValueDatabase.d.ts +26 -0
  134. package/dist/databases/IndexedDBKeyValueDatabase.js +130 -0
  135. package/dist/dataobject/StoredMap.d.ts +12 -0
  136. package/dist/dataobject/StoredMap.js +47 -0
  137. package/dist/dev/checks.d.ts +5 -0
  138. package/dist/dev/checks.js +38 -0
  139. package/dist/encryption/encryptHKDF.d.ts +3 -0
  140. package/dist/encryption/encryptHKDF.js +7 -0
  141. package/dist/encryption/stringEncryption.d.ts +27 -0
  142. package/dist/encryption/stringEncryption.js +59 -0
  143. package/dist/events/coreEvents.d.ts +54 -0
  144. package/dist/events/coreEvents.js +46 -0
  145. package/dist/hub/hub.d.ts +11 -0
  146. package/dist/hub/hub.js +7 -0
  147. package/dist/index.d.ts +1 -0
  148. package/dist/index.js +4 -0
  149. package/dist/interfaces/AsyncActivityRunner.d.ts +18 -0
  150. package/dist/interfaces/AsyncActivityRunner.js +7 -0
  151. package/dist/interfaces/Confirm.d.ts +17 -0
  152. package/dist/interfaces/Confirm.js +0 -0
  153. package/dist/interfaces/DatabaseFileAccess.d.ts +14 -0
  154. package/dist/interfaces/DatabaseFileAccess.js +0 -0
  155. package/dist/interfaces/DatabaseRebuilder.d.ts +13 -0
  156. package/dist/interfaces/DatabaseRebuilder.js +0 -0
  157. package/dist/interfaces/FileHandler.d.ts +13 -0
  158. package/dist/interfaces/FileHandler.js +0 -0
  159. package/dist/interfaces/KeyValueDatabase.d.ts +11 -0
  160. package/dist/interfaces/KeyValueDatabase.js +0 -0
  161. package/dist/interfaces/ServiceModule.d.ts +59 -0
  162. package/dist/interfaces/ServiceModule.js +19 -0
  163. package/dist/interfaces/StorageAccess.d.ts +44 -0
  164. package/dist/interfaces/StorageAccess.js +0 -0
  165. package/dist/interfaces/StorageEventManager.d.ts +16 -0
  166. package/dist/interfaces/StorageEventManager.js +5 -0
  167. package/dist/managers/ChangeManager.d.ts +61 -0
  168. package/dist/managers/ChangeManager.js +104 -0
  169. package/dist/managers/ChunkDeliveryCoordinator.d.ts +51 -0
  170. package/dist/managers/ChunkDeliveryCoordinator.js +136 -0
  171. package/dist/managers/ChunkFetcher.d.ts +44 -0
  172. package/dist/managers/ChunkFetcher.js +251 -0
  173. package/dist/managers/ChunkManager.d.ts +2 -0
  174. package/dist/managers/ChunkManager.js +4 -0
  175. package/dist/managers/ConflictManager.d.ts +37 -0
  176. package/dist/managers/ConflictManager.js +322 -0
  177. package/dist/managers/EntryManager/EntryManager.d.ts +37 -0
  178. package/dist/managers/EntryManager/EntryManager.js +73 -0
  179. package/dist/managers/EntryManager/EntryManagerImpls.d.ts +74 -0
  180. package/dist/managers/EntryManager/EntryManagerImpls.js +499 -0
  181. package/dist/managers/HashManager/HashManager.d.ts +60 -0
  182. package/dist/managers/HashManager/HashManager.js +97 -0
  183. package/dist/managers/HashManager/HashManagerCore.d.ts +114 -0
  184. package/dist/managers/HashManager/HashManagerCore.js +99 -0
  185. package/dist/managers/HashManager/PureJSHashManager.d.ts +77 -0
  186. package/dist/managers/HashManager/PureJSHashManager.js +84 -0
  187. package/dist/managers/HashManager/XXHashHashManager.d.ts +96 -0
  188. package/dist/managers/HashManager/XXHashHashManager.js +111 -0
  189. package/dist/managers/LayeredChunkManager/ArrivalWaitLayer.d.ts +30 -0
  190. package/dist/managers/LayeredChunkManager/ArrivalWaitLayer.js +115 -0
  191. package/dist/managers/LayeredChunkManager/CacheLayer.d.ts +59 -0
  192. package/dist/managers/LayeredChunkManager/CacheLayer.js +161 -0
  193. package/dist/managers/LayeredChunkManager/ChunkLayerInterfaces.d.ts +37 -0
  194. package/dist/managers/LayeredChunkManager/ChunkLayerInterfaces.js +0 -0
  195. package/dist/managers/LayeredChunkManager/DatabaseReadLayer.d.ts +14 -0
  196. package/dist/managers/LayeredChunkManager/DatabaseReadLayer.js +78 -0
  197. package/dist/managers/LayeredChunkManager/DatabaseWriteLayer.d.ts +11 -0
  198. package/dist/managers/LayeredChunkManager/DatabaseWriteLayer.js +43 -0
  199. package/dist/managers/LayeredChunkManager/HotPackLayer.d.ts +9 -0
  200. package/dist/managers/LayeredChunkManager/HotPackLayer.js +8 -0
  201. package/dist/managers/LayeredChunkManager/types.d.ts +39 -0
  202. package/dist/managers/LayeredChunkManager/types.js +0 -0
  203. package/dist/managers/LayeredChunkManager.d.ts +53 -0
  204. package/dist/managers/LayeredChunkManager.js +240 -0
  205. package/dist/managers/LiveSyncManagers.d.ts +48 -0
  206. package/dist/managers/LiveSyncManagers.js +136 -0
  207. package/dist/managers/StorageEventManager.d.ts +135 -0
  208. package/dist/managers/StorageEventManager.js +564 -0
  209. package/dist/managers/StorageProcessingManager.d.ts +14 -0
  210. package/dist/managers/StorageProcessingManager.js +48 -0
  211. package/dist/managers/adapters/IStorageEventConverterAdapter.d.ts +16 -0
  212. package/dist/managers/adapters/IStorageEventConverterAdapter.js +0 -0
  213. package/dist/managers/adapters/IStorageEventManagerAdapter.d.ts +18 -0
  214. package/dist/managers/adapters/IStorageEventManagerAdapter.js +0 -0
  215. package/dist/managers/adapters/IStorageEventPersistenceAdapter.d.ts +15 -0
  216. package/dist/managers/adapters/IStorageEventPersistenceAdapter.js +0 -0
  217. package/dist/managers/adapters/IStorageEventStatusAdapter.d.ts +13 -0
  218. package/dist/managers/adapters/IStorageEventStatusAdapter.js +0 -0
  219. package/dist/managers/adapters/IStorageEventTypeGuardAdapter.d.ts +16 -0
  220. package/dist/managers/adapters/IStorageEventTypeGuardAdapter.js +0 -0
  221. package/dist/managers/adapters/IStorageEventWatchAdapter.d.ts +21 -0
  222. package/dist/managers/adapters/IStorageEventWatchAdapter.js +0 -0
  223. package/dist/managers/adapters/index.d.ts +6 -0
  224. package/dist/managers/adapters/index.js +0 -0
  225. package/dist/mock_and_interop/stores.d.ts +21 -0
  226. package/dist/mock_and_interop/stores.js +15 -0
  227. package/dist/mock_and_interop/wrapper.d.ts +7 -0
  228. package/dist/mock_and_interop/wrapper.js +37 -0
  229. package/dist/mods.d.ts +1 -0
  230. package/dist/mods.js +18 -0
  231. package/dist/platform/browser/index.d.ts +1 -0
  232. package/dist/platform/browser/index.js +10 -0
  233. package/dist/platform/browser/storage.d.ts +35 -0
  234. package/dist/platform/browser/storage.js +139 -0
  235. package/dist/platform/node/index.d.ts +23 -0
  236. package/dist/platform/node/index.js +33 -0
  237. package/dist/platform/node/storage.d.ts +31 -0
  238. package/dist/platform/node/storage.js +104 -0
  239. package/dist/platform/storagePath.d.ts +7 -0
  240. package/dist/platform/storagePath.js +20 -0
  241. package/dist/pouchdb/LiveSyncDBFunctions.d.ts +14 -0
  242. package/dist/pouchdb/LiveSyncDBFunctions.js +129 -0
  243. package/dist/pouchdb/LiveSyncLocalDB.d.ts +196 -0
  244. package/dist/pouchdb/LiveSyncLocalDB.js +381 -0
  245. package/dist/pouchdb/PouchDBConstructor.d.ts +3 -0
  246. package/dist/pouchdb/PouchDBConstructor.js +0 -0
  247. package/dist/pouchdb/ReplicatorShim.d.ts +51 -0
  248. package/dist/pouchdb/ReplicatorShim.js +109 -0
  249. package/dist/pouchdb/StreamingFetch.d.ts +19 -0
  250. package/dist/pouchdb/StreamingFetch.js +263 -0
  251. package/dist/pouchdb/chunks.d.ts +38 -0
  252. package/dist/pouchdb/chunks.js +314 -0
  253. package/dist/pouchdb/compress.d.ts +11 -0
  254. package/dist/pouchdb/compress.js +99 -0
  255. package/dist/pouchdb/encryption.d.ts +20 -0
  256. package/dist/pouchdb/encryption.js +458 -0
  257. package/dist/pouchdb/negotiation.d.ts +9 -0
  258. package/dist/pouchdb/negotiation.js +109 -0
  259. package/dist/pouchdb/pouchdb-browser.d.ts +2 -0
  260. package/dist/pouchdb/pouchdb-browser.js +96 -0
  261. package/dist/pouchdb/pouchdb-http.d.ts +2 -0
  262. package/dist/pouchdb/pouchdb-http.js +94 -0
  263. package/dist/pouchdb/pouchdb-test.d.ts +2 -0
  264. package/dist/pouchdb/pouchdb-test.js +12 -0
  265. package/dist/pouchdb/utils_couchdb.d.ts +4 -0
  266. package/dist/pouchdb/utils_couchdb.js +38 -0
  267. package/dist/replication/LiveSyncAbstractReplicator.d.ts +69 -0
  268. package/dist/replication/LiveSyncAbstractReplicator.js +92 -0
  269. package/dist/replication/SyncParamsHandler.d.ts +35 -0
  270. package/dist/replication/SyncParamsHandler.js +118 -0
  271. package/dist/replication/couchdb/LiveSyncReplicator.d.ts +85 -0
  272. package/dist/replication/couchdb/LiveSyncReplicator.js +1132 -0
  273. package/dist/replication/httplib.d.ts +75 -0
  274. package/dist/replication/httplib.js +187 -0
  275. package/dist/replication/journal/JournalSyncCore.d.ts +70 -0
  276. package/dist/replication/journal/JournalSyncCore.js +737 -0
  277. package/dist/replication/journal/JournalSyncTypes.d.ts +9 -0
  278. package/dist/replication/journal/JournalSyncTypes.js +11 -0
  279. package/dist/replication/journal/LiveSyncJournalReplicator.d.ts +40 -0
  280. package/dist/replication/journal/LiveSyncJournalReplicator.js +294 -0
  281. package/dist/replication/journal/LiveSyncJournalReplicatorEnv.d.ts +3 -0
  282. package/dist/replication/journal/LiveSyncJournalReplicatorEnv.js +0 -0
  283. package/dist/replication/journal/objectstore/JournalStorageAdapter.d.ts +15 -0
  284. package/dist/replication/journal/objectstore/JournalStorageAdapter.js +0 -0
  285. package/dist/replication/journal/objectstore/MinioStorageAdapter.d.ts +21 -0
  286. package/dist/replication/journal/objectstore/MinioStorageAdapter.js +204 -0
  287. package/dist/replication/trystero/LiveSyncTrysteroReplicator.d.ts +90 -0
  288. package/dist/replication/trystero/LiveSyncTrysteroReplicator.js +380 -0
  289. package/dist/replication/trystero/P2PLogCollector.d.ts +8 -0
  290. package/dist/replication/trystero/P2PLogCollector.js +91 -0
  291. package/dist/replication/trystero/P2PReplicatorBase.d.ts +19 -0
  292. package/dist/replication/trystero/P2PReplicatorBase.js +0 -0
  293. package/dist/replication/trystero/P2PReplicatorCore.d.ts +12 -0
  294. package/dist/replication/trystero/P2PReplicatorCore.js +126 -0
  295. package/dist/replication/trystero/P2PReplicatorPaneCommon.d.ts +41 -0
  296. package/dist/replication/trystero/P2PReplicatorPaneCommon.js +20 -0
  297. package/dist/replication/trystero/ProxiedDB.d.ts +13 -0
  298. package/dist/replication/trystero/ProxiedDB.js +20 -0
  299. package/dist/replication/trystero/TrysteroReplicator.d.ts +152 -0
  300. package/dist/replication/trystero/TrysteroReplicator.js +683 -0
  301. package/dist/replication/trystero/TrysteroReplicatorP2PClient.d.ts +19 -0
  302. package/dist/replication/trystero/TrysteroReplicatorP2PClient.js +80 -0
  303. package/dist/replication/trystero/TrysteroReplicatorP2PConnection.d.ts +2 -0
  304. package/dist/replication/trystero/TrysteroReplicatorP2PConnection.js +4 -0
  305. package/dist/replication/trystero/TrysteroReplicatorP2PServer.d.ts +117 -0
  306. package/dist/replication/trystero/TrysteroReplicatorP2PServer.js +540 -0
  307. package/dist/replication/trystero/UseP2PReplicatorResult.d.ts +11 -0
  308. package/dist/replication/trystero/UseP2PReplicatorResult.js +0 -0
  309. package/dist/replication/trystero/addP2PEventHandlers.d.ts +35 -0
  310. package/dist/replication/trystero/addP2PEventHandlers.js +43 -0
  311. package/dist/replication/trystero/rpcCompat.d.ts +1 -0
  312. package/dist/replication/trystero/rpcCompat.js +9 -0
  313. package/dist/replication/trystero/types.d.ts +95 -0
  314. package/dist/replication/trystero/types.js +27 -0
  315. package/dist/replication/trystero/useP2PReplicatorCommands.d.ts +7 -0
  316. package/dist/replication/trystero/useP2PReplicatorCommands.js +25 -0
  317. package/dist/replication/trystero/useP2PReplicatorFeature.d.ts +17 -0
  318. package/dist/replication/trystero/useP2PReplicatorFeature.js +82 -0
  319. package/dist/rpc/RpcRoom.d.ts +24 -0
  320. package/dist/rpc/RpcRoom.js +300 -0
  321. package/dist/rpc/RpcSession.d.ts +9 -0
  322. package/dist/rpc/RpcSession.js +32 -0
  323. package/dist/rpc/chunking.d.ts +11 -0
  324. package/dist/rpc/chunking.js +58 -0
  325. package/dist/rpc/errors.d.ts +8 -0
  326. package/dist/rpc/errors.js +26 -0
  327. package/dist/rpc/index.d.ts +6 -0
  328. package/dist/rpc/index.js +12 -0
  329. package/dist/rpc/pouchdb/RpcPouchDBProxy.d.ts +75 -0
  330. package/dist/rpc/pouchdb/RpcPouchDBProxy.js +115 -0
  331. package/dist/rpc/pouchdb/RpcPouchDBServer.d.ts +16 -0
  332. package/dist/rpc/pouchdb/RpcPouchDBServer.js +55 -0
  333. package/dist/rpc/transports/DiagRTCPeerConnections.d.ts +24 -0
  334. package/dist/rpc/transports/DiagRTCPeerConnections.js +208 -0
  335. package/dist/rpc/transports/DiagRTCPeerConnections.types.d.ts +64 -0
  336. package/dist/rpc/transports/DiagRTCPeerConnections.types.js +12 -0
  337. package/dist/rpc/transports/DiagRTCPeerConnections.utils.d.ts +33 -0
  338. package/dist/rpc/transports/DiagRTCPeerConnections.utils.js +217 -0
  339. package/dist/rpc/transports/TrysteroTransport.d.ts +216 -0
  340. package/dist/rpc/transports/TrysteroTransport.js +134 -0
  341. package/dist/rpc/transports/trysteroUtils.d.ts +3 -0
  342. package/dist/rpc/transports/trysteroUtils.js +37 -0
  343. package/dist/rpc/types.d.ts +75 -0
  344. package/dist/rpc/types.js +6 -0
  345. package/dist/serviceFeatures/checkRemoteSize.d.ts +28 -0
  346. package/dist/serviceFeatures/checkRemoteSize.js +178 -0
  347. package/dist/serviceFeatures/offlineScanner.d.ts +128 -0
  348. package/dist/serviceFeatures/offlineScanner.js +553 -0
  349. package/dist/serviceFeatures/prepareDatabaseForUse.d.ts +20 -0
  350. package/dist/serviceFeatures/prepareDatabaseForUse.js +39 -0
  351. package/dist/serviceFeatures/remoteConfig.d.ts +46 -0
  352. package/dist/serviceFeatures/remoteConfig.js +247 -0
  353. package/dist/serviceFeatures/setupObsidian/qrCode.d.ts +4 -0
  354. package/dist/serviceFeatures/setupObsidian/qrCode.js +67 -0
  355. package/dist/serviceFeatures/setupObsidian/setupUri.d.ts +7 -0
  356. package/dist/serviceFeatures/setupObsidian/setupUri.js +70 -0
  357. package/dist/serviceFeatures/setupObsidian/types.d.ts +2 -0
  358. package/dist/serviceFeatures/setupObsidian/types.js +0 -0
  359. package/dist/serviceFeatures/targetFilter.d.ts +24 -0
  360. package/dist/serviceFeatures/targetFilter.js +178 -0
  361. package/dist/serviceModules/FileAccessBase.d.ts +93 -0
  362. package/dist/serviceModules/FileAccessBase.js +219 -0
  363. package/dist/serviceModules/Rebuilder.d.ts +92 -0
  364. package/dist/serviceModules/Rebuilder.js +449 -0
  365. package/dist/serviceModules/ServiceDatabaseFileAccessBase.d.ts +40 -0
  366. package/dist/serviceModules/ServiceDatabaseFileAccessBase.js +306 -0
  367. package/dist/serviceModules/ServiceFileAccessBase.d.ts +64 -0
  368. package/dist/serviceModules/ServiceFileAccessBase.js +312 -0
  369. package/dist/serviceModules/ServiceFileHandlerBase.d.ts +52 -0
  370. package/dist/serviceModules/ServiceFileHandlerBase.js +493 -0
  371. package/dist/serviceModules/ServiceModuleBase.d.ts +10 -0
  372. package/dist/serviceModules/ServiceModuleBase.js +13 -0
  373. package/dist/serviceModules/adapters/IConversionAdapter.d.ts +15 -0
  374. package/dist/serviceModules/adapters/IConversionAdapter.js +0 -0
  375. package/dist/serviceModules/adapters/IFileSystemAdapter.d.ts +47 -0
  376. package/dist/serviceModules/adapters/IFileSystemAdapter.js +0 -0
  377. package/dist/serviceModules/adapters/IPathAdapter.d.ts +15 -0
  378. package/dist/serviceModules/adapters/IPathAdapter.js +0 -0
  379. package/dist/serviceModules/adapters/IStorageAdapter.d.ts +56 -0
  380. package/dist/serviceModules/adapters/IStorageAdapter.js +0 -0
  381. package/dist/serviceModules/adapters/ITypeGuardAdapter.d.ts +14 -0
  382. package/dist/serviceModules/adapters/ITypeGuardAdapter.js +0 -0
  383. package/dist/serviceModules/adapters/IVaultAdapter.d.ts +51 -0
  384. package/dist/serviceModules/adapters/IVaultAdapter.js +0 -0
  385. package/dist/serviceModules/adapters/index.d.ts +6 -0
  386. package/dist/serviceModules/adapters/index.js +0 -0
  387. package/dist/services/BrowserServices.d.ts +36 -0
  388. package/dist/services/BrowserServices.js +123 -0
  389. package/dist/services/HeadlessServices.d.ts +14 -0
  390. package/dist/services/HeadlessServices.js +144 -0
  391. package/dist/services/InjectableServices.d.ts +1 -0
  392. package/dist/services/InjectableServices.js +4 -0
  393. package/dist/services/ServiceHub.d.ts +82 -0
  394. package/dist/services/ServiceHub.js +66 -0
  395. package/dist/services/base/APIService.d.ts +93 -0
  396. package/dist/services/base/APIService.js +44 -0
  397. package/dist/services/base/AppLifecycleService.d.ts +132 -0
  398. package/dist/services/base/AppLifecycleService.js +123 -0
  399. package/dist/services/base/ConfigService.d.ts +7 -0
  400. package/dist/services/base/ConfigService.js +6 -0
  401. package/dist/services/base/ConflictService.d.ts +54 -0
  402. package/dist/services/base/ConflictService.js +22 -0
  403. package/dist/services/base/ControlService.d.ts +54 -0
  404. package/dist/services/base/ControlService.js +103 -0
  405. package/dist/services/base/DatabaseEventService.d.ts +38 -0
  406. package/dist/services/base/DatabaseEventService.js +38 -0
  407. package/dist/services/base/DatabaseService.d.ts +40 -0
  408. package/dist/services/base/DatabaseService.js +79 -0
  409. package/dist/services/base/FileProcessingService.d.ts +25 -0
  410. package/dist/services/base/FileProcessingService.js +28 -0
  411. package/dist/services/base/IService.d.ts +284 -0
  412. package/dist/services/base/IService.js +1 -0
  413. package/dist/services/base/KeyValueDBService.d.ts +42 -0
  414. package/dist/services/base/KeyValueDBService.js +133 -0
  415. package/dist/services/base/MessageTranslator.d.ts +6 -0
  416. package/dist/services/base/MessageTranslator.js +4 -0
  417. package/dist/services/base/PathService.d.ts +38 -0
  418. package/dist/services/base/PathService.js +66 -0
  419. package/dist/services/base/RemoteService.d.ts +61 -0
  420. package/dist/services/base/RemoteService.js +212 -0
  421. package/dist/services/base/ReplicationService.d.ts +92 -0
  422. package/dist/services/base/ReplicationService.js +261 -0
  423. package/dist/services/base/ReplicatorService.d.ts +66 -0
  424. package/dist/services/base/ReplicatorService.js +164 -0
  425. package/dist/services/base/ServiceBase.d.ts +33 -0
  426. package/dist/services/base/ServiceBase.js +27 -0
  427. package/dist/services/base/SettingService.d.ts +112 -0
  428. package/dist/services/base/SettingService.js +543 -0
  429. package/dist/services/base/TestService.d.ts +28 -0
  430. package/dist/services/base/TestService.js +19 -0
  431. package/dist/services/base/TweakValueService.d.ts +40 -0
  432. package/dist/services/base/TweakValueService.js +6 -0
  433. package/dist/services/base/UnresolvedErrorManager.d.ts +15 -0
  434. package/dist/services/base/UnresolvedErrorManager.js +44 -0
  435. package/dist/services/base/VaultService.d.ts +69 -0
  436. package/dist/services/base/VaultService.js +70 -0
  437. package/dist/services/implements/base/SvelteDialog.d.ts +79 -0
  438. package/dist/services/implements/base/SvelteDialog.js +134 -0
  439. package/dist/services/implements/base/UIService.d.ts +24 -0
  440. package/dist/services/implements/base/UIService.js +37 -0
  441. package/dist/services/implements/browser/BrowserAPIService.d.ts +54 -0
  442. package/dist/services/implements/browser/BrowserAPIService.js +298 -0
  443. package/dist/services/implements/browser/BrowserDatabaseService.d.ts +7 -0
  444. package/dist/services/implements/browser/BrowserDatabaseService.js +10 -0
  445. package/dist/services/implements/browser/ConfigServiceBrowserCompat.d.ts +16 -0
  446. package/dist/services/implements/browser/ConfigServiceBrowserCompat.js +23 -0
  447. package/dist/services/implements/headless/HeadlessAPIService.d.ts +52 -0
  448. package/dist/services/implements/headless/HeadlessAPIService.js +127 -0
  449. package/dist/services/implements/headless/HeadlessDatabaseService.d.ts +7 -0
  450. package/dist/services/implements/headless/HeadlessDatabaseService.js +10 -0
  451. package/dist/services/implements/injectable/InjectableAPIService.d.ts +7 -0
  452. package/dist/services/implements/injectable/InjectableAPIService.js +18 -0
  453. package/dist/services/implements/injectable/InjectableAppLifecycleService.d.ts +11 -0
  454. package/dist/services/implements/injectable/InjectableAppLifecycleService.js +14 -0
  455. package/dist/services/implements/injectable/InjectableConflictService.d.ts +11 -0
  456. package/dist/services/implements/injectable/InjectableConflictService.js +14 -0
  457. package/dist/services/implements/injectable/InjectableDatabaseEventService.d.ts +4 -0
  458. package/dist/services/implements/injectable/InjectableDatabaseEventService.js +7 -0
  459. package/dist/services/implements/injectable/InjectableFileProcessingService.d.ts +4 -0
  460. package/dist/services/implements/injectable/InjectableFileProcessingService.js +6 -0
  461. package/dist/services/implements/injectable/InjectablePathService.d.ts +12 -0
  462. package/dist/services/implements/injectable/InjectablePathService.js +36 -0
  463. package/dist/services/implements/injectable/InjectableRemoteService.d.ts +4 -0
  464. package/dist/services/implements/injectable/InjectableRemoteService.js +7 -0
  465. package/dist/services/implements/injectable/InjectableReplicationService.d.ts +4 -0
  466. package/dist/services/implements/injectable/InjectableReplicationService.js +6 -0
  467. package/dist/services/implements/injectable/InjectableReplicatorService.d.ts +4 -0
  468. package/dist/services/implements/injectable/InjectableReplicatorService.js +7 -0
  469. package/dist/services/implements/injectable/InjectableServiceHub.d.ts +72 -0
  470. package/dist/services/implements/injectable/InjectableServiceHub.js +125 -0
  471. package/dist/services/implements/injectable/InjectableServices.d.ts +36 -0
  472. package/dist/services/implements/injectable/InjectableServices.js +1 -0
  473. package/dist/services/implements/injectable/InjectableSettingService.d.ts +11 -0
  474. package/dist/services/implements/injectable/InjectableSettingService.js +33 -0
  475. package/dist/services/implements/injectable/InjectableTestService.d.ts +5 -0
  476. package/dist/services/implements/injectable/InjectableTestService.js +8 -0
  477. package/dist/services/implements/injectable/InjectableTweakValueService.d.ts +15 -0
  478. package/dist/services/implements/injectable/InjectableTweakValueService.js +12 -0
  479. package/dist/services/implements/injectable/InjectableVaultService.d.ts +9 -0
  480. package/dist/services/implements/injectable/InjectableVaultService.js +20 -0
  481. package/dist/services/lib/HandlerUtils.d.ts +374 -0
  482. package/dist/services/lib/HandlerUtils.js +412 -0
  483. package/dist/services/lib/logUtils.d.ts +13 -0
  484. package/dist/services/lib/logUtils.js +28 -0
  485. package/dist/services/lib/remoteActivity.d.ts +13 -0
  486. package/dist/services/lib/remoteActivity.js +11 -0
  487. package/dist/string_and_binary/chunks.d.ts +10 -0
  488. package/dist/string_and_binary/chunks.js +561 -0
  489. package/dist/string_and_binary/convert.d.ts +8 -0
  490. package/dist/string_and_binary/convert.js +46 -0
  491. package/dist/string_and_binary/hash.d.ts +2 -0
  492. package/dist/string_and_binary/hash.js +1 -0
  493. package/dist/string_and_binary/path.d.ts +35 -0
  494. package/dist/string_and_binary/path.js +240 -0
  495. package/dist/worker/bg.common.d.ts +2 -0
  496. package/dist/worker/bg.common.js +6 -0
  497. package/dist/worker/bg.worker.d.ts +1 -0
  498. package/dist/worker/bg.worker.encryption.d.ts +7 -0
  499. package/dist/worker/bg.worker.encryption.js +30 -0
  500. package/dist/worker/bg.worker.js +14 -0
  501. package/dist/worker/bg.worker.splitting.d.ts +6 -0
  502. package/dist/worker/bg.worker.splitting.js +36 -0
  503. package/dist/worker/bgWorker.d.ts +25 -0
  504. package/dist/worker/bgWorker.direct.d.ts +40 -0
  505. package/dist/worker/bgWorker.direct.js +65 -0
  506. package/dist/worker/bgWorker.encryption.d.ts +22 -0
  507. package/dist/worker/bgWorker.encryption.js +40 -0
  508. package/dist/worker/bgWorker.js +348 -0
  509. package/dist/worker/bgWorker.splitting.d.ts +27 -0
  510. package/dist/worker/bgWorker.splitting.js +123 -0
  511. package/dist/worker/universalTypes.d.ts +63 -0
  512. package/dist/worker/universalTypes.js +4 -0
  513. package/docs/development.md +51 -0
  514. package/docs/platform-storage.md +60 -0
  515. package/docs/releasing.md +69 -0
  516. package/package.json +693 -0
@@ -0,0 +1,1132 @@
1
+ import {
2
+ VER,
3
+ MILESTONE_DOCID,
4
+ REPLICATION_BUSY_TIMEOUT,
5
+ LOG_LEVEL_INFO,
6
+ LOG_LEVEL_NOTICE,
7
+ LOG_LEVEL_VERBOSE,
8
+ DEVICE_ID_PREFERRED,
9
+ TweakValuesTemplate,
10
+ DOCID_SYNC_PARAMETERS,
11
+ DEFAULT_SYNC_PARAMETERS,
12
+ ProtocolVersions
13
+ } from "../../common/types.js";
14
+ import {
15
+ resolveWithIgnoreKnownError,
16
+ globalConcurrencyController,
17
+ extractObject,
18
+ wrapException,
19
+ sizeToHumanReadable,
20
+ arrayToChunkedArray,
21
+ parseHeaderValues
22
+ } from "../../common/utils.js";
23
+ import { Logger } from "../../common/logger.js";
24
+ import { checkRemoteVersion, countCompromisedChunks } from "../../pouchdb/negotiation.js";
25
+ import { preprocessOutgoing } from "../../pouchdb/encryption.js";
26
+ import { ensureDatabaseIsCompatible } from "../../pouchdb/LiveSyncDBFunctions.js";
27
+ import {
28
+ LiveSyncAbstractReplicator
29
+ } from "../LiveSyncAbstractReplicator.js";
30
+ import { shareRunningResult } from "octagonal-wheels/concurrency/lock";
31
+ import { Semaphore } from "octagonal-wheels/concurrency/semaphore";
32
+ import { Trench } from "octagonal-wheels/memory/memutil";
33
+ import { StreamInbox } from "octagonal-wheels/bureau/StreamInbox";
34
+ import {
35
+ clearHandlers,
36
+ createSyncParamsHanderForServer,
37
+ SyncParamsFetchError,
38
+ SyncParamsNotFoundError,
39
+ SyncParamsUpdateError
40
+ } from "../SyncParamsHandler.js";
41
+ const currentVersionRange = {
42
+ min: 0,
43
+ max: 2400,
44
+ current: 2
45
+ };
46
+ const selectorOnDemandPull = { selector: { type: { $ne: "leaf" } } };
47
+ async function* genReplication(s, signal) {
48
+ const inbox = new StreamInbox({ capacity: 1e4 });
49
+ const push = function(e) {
50
+ if (signal.aborted || inbox.isClosed) return;
51
+ if (inbox.post(e)) return;
52
+ Logger(`Replication event queue is full: ${e[0]}`, LOG_LEVEL_VERBOSE);
53
+ if (e[0] === "error" || e[0] === "denied") {
54
+ inbox.error(e[1]);
55
+ } else if (e[0] === "complete" || e[0] === "finally") {
56
+ inbox.close();
57
+ }
58
+ };
59
+ void s.on("complete", (result) => push(["complete", result]));
60
+ void s.on("change", (result) => push(["change", result]));
61
+ void s.on("active", () => push(["active"]));
62
+ void s.on("denied", (err) => push(["denied", err]));
63
+ void s.on("error", (err) => push(["error", err]));
64
+ void s.on("paused", (err) => push(["paused", err]));
65
+ void s.then(() => push(["finally"])).catch(() => push(["finally"]));
66
+ const onAbort = () => inbox.close();
67
+ signal.addEventListener("abort", onAbort, { once: true });
68
+ try {
69
+ const reader = inbox.readable.getReader();
70
+ while (!signal.aborted) {
71
+ const { done, value } = await reader.read();
72
+ if (done) break;
73
+ yield value;
74
+ }
75
+ } catch (ex) {
76
+ if (ex instanceof Error && ex.name == "AbortError") {
77
+ Logger(`Replication aborted`, LOG_LEVEL_VERBOSE);
78
+ } else {
79
+ throw ex;
80
+ }
81
+ } finally {
82
+ signal.removeEventListener("abort", onAbort);
83
+ s.cancel();
84
+ inbox.close();
85
+ }
86
+ }
87
+ class LiveSyncCouchDBReplicator extends LiveSyncAbstractReplicator {
88
+ get isChunkSendingSupported() {
89
+ return true;
90
+ }
91
+ isMobile() {
92
+ return this.env.services.API.isMobile();
93
+ }
94
+ constructor(env) {
95
+ super(env);
96
+ this.env = env;
97
+ void this.initializeDatabaseForReplication();
98
+ this.rawDatabase.on("close", () => {
99
+ this.closeReplication();
100
+ });
101
+ }
102
+ getInitialSyncParameters(setting) {
103
+ return Promise.resolve({
104
+ ...DEFAULT_SYNC_PARAMETERS,
105
+ protocolVersion: ProtocolVersions.ADVANCED_E2EE
106
+ });
107
+ }
108
+ async getSyncParameters(setting) {
109
+ try {
110
+ const downloadedSyncParams = await this.fetchRemoteDocument(setting, DOCID_SYNC_PARAMETERS);
111
+ if (!downloadedSyncParams) {
112
+ throw new SyncParamsNotFoundError(`Sync parameters not found on remote server`);
113
+ }
114
+ return downloadedSyncParams;
115
+ } catch (ex) {
116
+ Logger(`Could not retrieve remote sync parameters`, LOG_LEVEL_INFO);
117
+ throw SyncParamsFetchError.fromError(ex);
118
+ }
119
+ }
120
+ async putSyncParameters(setting, params) {
121
+ try {
122
+ const ret = await this.putRemoteDocument(setting, params);
123
+ if (ret.ok) {
124
+ return true;
125
+ } else {
126
+ throw new SyncParamsUpdateError(`Could not store remote sync parameters: ${JSON.stringify(ret)}`);
127
+ }
128
+ } catch (ex) {
129
+ Logger(`Could not store remote sync parameters`, LOG_LEVEL_INFO);
130
+ throw SyncParamsUpdateError.fromError(ex);
131
+ }
132
+ }
133
+ async getReplicationPBKDF2Salt(setting, refresh) {
134
+ const server = `${setting.couchDB_URI.replace(/\/+$/, "")}/${setting.couchDB_DBNAME}`;
135
+ const manager = createSyncParamsHanderForServer(server, {
136
+ put: (params) => this.putSyncParameters(setting, params),
137
+ get: () => this.getSyncParameters(setting),
138
+ create: () => this.getInitialSyncParameters(setting)
139
+ });
140
+ return await manager.getPBKDF2Salt(refresh);
141
+ }
142
+ async migrate(from, to) {
143
+ Logger(`Database updated from ${from} to ${to}`, LOG_LEVEL_NOTICE);
144
+ return Promise.resolve(true);
145
+ }
146
+ terminateSync() {
147
+ if (!this.controller) {
148
+ return;
149
+ }
150
+ this.controller.abort();
151
+ this.controller = void 0;
152
+ }
153
+ async openReplication(setting, keepAlive, showResult, ignoreCleanLock) {
154
+ await this.initializeDatabaseForReplication();
155
+ if (keepAlive) {
156
+ void this.openContinuousReplication(setting, showResult, false);
157
+ } else {
158
+ return this.openOneShotReplication(setting, showResult, false, "sync", ignoreCleanLock);
159
+ }
160
+ }
161
+ replicationActivated(showResult) {
162
+ this.syncStatus = "CONNECTED";
163
+ this.updateInfo();
164
+ Logger("Replication activated", showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO, "sync");
165
+ }
166
+ async replicationChangeDetected(e, showResult, docSentOnStart, docArrivedOnStart) {
167
+ try {
168
+ if (e.direction == "pull") {
169
+ await this.env.services.replication.parseSynchroniseResult(e.change.docs);
170
+ this.docArrived += e.change.docs.length;
171
+ } else {
172
+ this.docSent += e.change.docs.length;
173
+ }
174
+ if (showResult) {
175
+ const maxPullSeq = this.maxPullSeq;
176
+ const maxPushSeq = this.maxPushSeq;
177
+ const lastSyncPullSeq = this.lastSyncPullSeq;
178
+ const lastSyncPushSeq = this.lastSyncPushSeq;
179
+ const pushLast = lastSyncPushSeq == 0 ? "" : lastSyncPushSeq >= maxPushSeq ? " (LIVE)" : ` (${maxPushSeq - lastSyncPushSeq})`;
180
+ const pullLast = lastSyncPullSeq == 0 ? "" : lastSyncPullSeq >= maxPullSeq ? " (LIVE)" : ` (${maxPullSeq - lastSyncPullSeq})`;
181
+ Logger(
182
+ `\u2191${this.docSent - docSentOnStart}${pushLast} \u2193${this.docArrived - docArrivedOnStart}${pullLast}`,
183
+ LOG_LEVEL_NOTICE,
184
+ "sync"
185
+ );
186
+ }
187
+ this.updateInfo();
188
+ } catch (ex) {
189
+ Logger("Replication callback error", LOG_LEVEL_NOTICE, "sync");
190
+ Logger(ex, LOG_LEVEL_VERBOSE);
191
+ }
192
+ }
193
+ replicationCompleted(showResult) {
194
+ this.syncStatus = "COMPLETED";
195
+ this.updateInfo();
196
+ Logger("Replication completed", showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO, showResult ? "sync" : "");
197
+ this.terminateSync();
198
+ }
199
+ replicationDenied(e) {
200
+ this.syncStatus = "ERRORED";
201
+ this.updateInfo();
202
+ this.terminateSync();
203
+ Logger("Replication denied", LOG_LEVEL_NOTICE, "sync");
204
+ Logger(e, LOG_LEVEL_VERBOSE);
205
+ }
206
+ replicationErrored(e) {
207
+ this.syncStatus = "ERRORED";
208
+ this.terminateSync();
209
+ this.updateInfo();
210
+ Logger("Replication error", LOG_LEVEL_NOTICE, "sync");
211
+ Logger(e, LOG_LEVEL_VERBOSE);
212
+ }
213
+ replicationPaused() {
214
+ this.syncStatus = "PAUSED";
215
+ this.updateInfo();
216
+ Logger("Replication paused", LOG_LEVEL_VERBOSE, "sync");
217
+ }
218
+ async processSync(syncHandler, showResult, docSentOnStart, docArrivedOnStart, syncMode, retrying, reportCancelledAsDone = true) {
219
+ const controller = new AbortController();
220
+ if (this.controller) {
221
+ this.controller.abort();
222
+ }
223
+ this.controller = controller;
224
+ const gen = genReplication(syncHandler, controller.signal);
225
+ try {
226
+ for await (const [type, e] of gen) {
227
+ const releaser = await globalConcurrencyController.tryAcquire(1, REPLICATION_BUSY_TIMEOUT);
228
+ if (releaser === false) {
229
+ Logger("Replication stopped for busy.", showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO, "sync");
230
+ return "FAILED";
231
+ }
232
+ releaser();
233
+ switch (type) {
234
+ case "change":
235
+ if ("direction" in e) {
236
+ if (e.direction == "pull") {
237
+ this.lastSyncPullSeq = Number(`${e.change.last_seq}`.split("-")[0]);
238
+ } else {
239
+ this.lastSyncPushSeq = Number(`${e.change.last_seq}`.split("-")[0]);
240
+ }
241
+ await this.replicationChangeDetected(e, showResult, docSentOnStart, docArrivedOnStart);
242
+ } else {
243
+ if (syncMode == "pullOnly") {
244
+ this.lastSyncPullSeq = Number(`${e.last_seq}`.split("-")[0]);
245
+ await this.replicationChangeDetected(
246
+ { direction: "pull", change: e },
247
+ showResult,
248
+ docSentOnStart,
249
+ docArrivedOnStart
250
+ );
251
+ } else if (syncMode == "pushOnly") {
252
+ this.lastSyncPushSeq = Number(`${e.last_seq}`.split("-")[0]);
253
+ this.updateInfo();
254
+ await this.replicationChangeDetected(
255
+ { direction: "push", change: e },
256
+ showResult,
257
+ docSentOnStart,
258
+ docArrivedOnStart
259
+ );
260
+ }
261
+ }
262
+ if (retrying) {
263
+ if (this.docSent - docSentOnStart + (this.docArrived - docArrivedOnStart) > this.originalSetting.batch_size * 2) {
264
+ return "NEED_RESURRECT";
265
+ }
266
+ }
267
+ break;
268
+ case "complete":
269
+ this.replicationCompleted(showResult);
270
+ return "DONE";
271
+ case "active":
272
+ this.replicationActivated(showResult);
273
+ break;
274
+ case "denied":
275
+ this.replicationDenied(e);
276
+ return "FAILED";
277
+ case "error":
278
+ this.replicationErrored(e);
279
+ Logger("Replication stopped.", showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO, "sync");
280
+ if (this.env.services.remote.hadLastPostFailedBySize) {
281
+ if (e && e.status == 413) {
282
+ Logger(
283
+ `Something went wrong during synchronisation. Please check the log!`,
284
+ LOG_LEVEL_NOTICE
285
+ );
286
+ return "FAILED";
287
+ }
288
+ return "NEED_RETRY";
289
+ } else {
290
+ Logger("Replication error", LOG_LEVEL_NOTICE, "sync");
291
+ Logger(e, LOG_LEVEL_VERBOSE);
292
+ }
293
+ return "FAILED";
294
+ case "paused":
295
+ this.replicationPaused();
296
+ break;
297
+ case "finally":
298
+ break;
299
+ default:
300
+ Logger(`Unexpected synchronization status:${JSON.stringify(e)}`);
301
+ }
302
+ }
303
+ if (reportCancelledAsDone) {
304
+ return "DONE";
305
+ }
306
+ return "CANCELLED";
307
+ } catch (ex) {
308
+ Logger(`Unexpected synchronization exception`);
309
+ Logger(ex, LOG_LEVEL_VERBOSE);
310
+ return "FAILED";
311
+ } finally {
312
+ this.terminateSync();
313
+ this.controller = void 0;
314
+ }
315
+ }
316
+ getEmptyMaxEntry(remoteID) {
317
+ return {
318
+ _id: `_local/max_seq_on_chunk-${remoteID}`,
319
+ maxSeq: 0,
320
+ remoteID,
321
+ seqStatusMap: {},
322
+ _rev: void 0
323
+ };
324
+ }
325
+ async getLastTransferredSeqOfChunks(localDB, remoteID) {
326
+ const prevMax = {
327
+ _id: `_local/max_seq_on_chunk-${remoteID}`,
328
+ maxSeq: 0,
329
+ remoteID,
330
+ seqStatusMap: {},
331
+ _rev: void 0
332
+ };
333
+ const previous_max_seq_on_chunk = await wrapException(() => localDB.get(prevMax._id));
334
+ if (previous_max_seq_on_chunk instanceof Error) {
335
+ return prevMax;
336
+ }
337
+ return previous_max_seq_on_chunk;
338
+ }
339
+ async updateMaxTransferredSeqOnChunks(localDB, remoteID, seqStatusMap) {
340
+ const newMax = {
341
+ _id: "_local/max_seq_on_chunk",
342
+ maxSeq: 0,
343
+ remoteID,
344
+ seqStatusMap,
345
+ _rev: void 0
346
+ };
347
+ const seqs = Object.keys(seqStatusMap).map((e) => Number(e));
348
+ let maxSeq = 0;
349
+ for (const seq of seqs) {
350
+ if (!seqStatusMap[seq]) {
351
+ break;
352
+ }
353
+ maxSeq = seq;
354
+ }
355
+ Logger(`Updating max seq on chunk to ${maxSeq}`, LOG_LEVEL_VERBOSE);
356
+ newMax.maxSeq = maxSeq;
357
+ const previous_max_seq_on_chunk = await wrapException(() => localDB.get(newMax._id));
358
+ if (previous_max_seq_on_chunk instanceof Error) {
359
+ delete newMax._rev;
360
+ } else {
361
+ newMax._rev = previous_max_seq_on_chunk._rev;
362
+ newMax.seqStatusMap = { ...previous_max_seq_on_chunk.seqStatusMap, ...seqStatusMap };
363
+ }
364
+ await wrapException(() => localDB.put(newMax));
365
+ return newMax;
366
+ }
367
+ // Used for sending chunks in bulk before replication.
368
+ async sendChunks(setting, remoteDB, showResult, fromSeq) {
369
+ const trench = new Trench(
370
+ this.env.services.keyValueDB.openSimpleStore("sc-"),
371
+ false
372
+ );
373
+ await trench.eraseAllEphemerals();
374
+ if (!remoteDB) {
375
+ const d = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
376
+ if (typeof d === "string") {
377
+ Logger(
378
+ this.translate("liveSyncReplicator.couldNotConnectToRemoteDb", { d }),
379
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
380
+ "fetch"
381
+ );
382
+ return false;
383
+ }
384
+ remoteDB = d.db;
385
+ }
386
+ await this.checkReplicationConnectivity(setting, false, false, false, false);
387
+ Logger(`Bulk sending chunks to remote database...`, showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO, "fetch");
388
+ const remoteMilestone = await remoteDB.get(MILESTONE_DOCID);
389
+ const remoteID = remoteMilestone?.created ?? 0;
390
+ const localDB = this.rawDatabase;
391
+ const te = new TextEncoder();
392
+ Logger(
393
+ this.translate("liveSyncReplicator.checkingLastSyncPoint"),
394
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
395
+ "fetch"
396
+ );
397
+ this.syncStatus = "CONNECTED";
398
+ const limitOneBatch = 250;
399
+ const prev = await this.getLastTransferredSeqOfChunks(localDB, remoteID);
400
+ const seq = fromSeq ?? prev.maxSeq;
401
+ const localScannedDocs = [];
402
+ const sentMap = {};
403
+ const diffChunks = localDB.changes({
404
+ since: seq,
405
+ live: false,
406
+ include_docs: true,
407
+ return_docs: false,
408
+ selector: { type: "leaf" }
409
+ // limit: limitOneBatch,
410
+ }).on("change", (e) => {
411
+ const numSeq = Number(e.seq);
412
+ if (prev.seqStatusMap[numSeq]) {
413
+ return;
414
+ }
415
+ localScannedDocs.push({ id: e.id, seq: Number(e.seq) });
416
+ });
417
+ await diffChunks;
418
+ localScannedDocs.sort((a, b) => a.seq - b.seq);
419
+ const idSeqMap = Object.fromEntries(localScannedDocs.map((e) => [e.id, e.seq]));
420
+ for (const checkDocs of arrayToChunkedArray(localScannedDocs, limitOneBatch)) {
421
+ const remoteDocs = await remoteDB.allDocs({ keys: checkDocs.map((e) => e.id), include_docs: false });
422
+ const remoteDocMap = Object.fromEntries(
423
+ remoteDocs.rows.map((e) => [e.key, "error" in e ? e.error : e.value])
424
+ );
425
+ const sendDocs = checkDocs.filter((e) => remoteDocMap[e.id] == "not_found");
426
+ const sentDocs = checkDocs.filter((e) => remoteDocMap[e.id] != "not_found");
427
+ sendDocs.forEach((e) => sentMap[e.seq] = false);
428
+ sentDocs.forEach((e) => sentMap[e.seq] = true);
429
+ const sendDocsMap = Object.fromEntries(sendDocs.map((e) => [e.id, e.seq]));
430
+ if (sendDocs.length > 0) {
431
+ const localDocs = await localDB.allDocs({ keys: sendDocs.map((e) => e.id), include_docs: true });
432
+ await trench.queue(
433
+ "send-chunks",
434
+ localDocs.rows.filter((e) => "id" in e).map((e) => ({ seq: sendDocsMap[e.id], doc: e.doc, id: e.id }))
435
+ );
436
+ }
437
+ }
438
+ let bulkDocs = [];
439
+ let bulkDocsSizeBytes = 0;
440
+ let bulkDocsSizeCount = 0;
441
+ let maxSeq = 0;
442
+ const maxBatchSizeBytes = setting.sendChunksBulkMaxSize * 1024 * 1024;
443
+ const maxBatchSizeCount = 200;
444
+ const semaphore = Semaphore(4);
445
+ let sendingDocs = 0;
446
+ let sentDocsCount = 0;
447
+ const sendChunks = async (bulkDocs2, bulkDocsSize, seq2) => {
448
+ Logger(
449
+ `Sending ${bulkDocs2.length} (${bulkDocsSize} => ${sizeToHumanReadable(bulkDocsSize)} in plain) chunks to remote database...`,
450
+ LOG_LEVEL_VERBOSE
451
+ );
452
+ const releaser = await semaphore.acquire(1);
453
+ sendingDocs += bulkDocs2.length;
454
+ Logger(
455
+ `\u2191 Uploading chunks
456
+ ${sendingDocs}/(${sentDocsCount} done)`,
457
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
458
+ "send"
459
+ );
460
+ try {
461
+ const uploadBulkDocTasks = bulkDocs2.map((e) => preprocessOutgoing(e));
462
+ const uploadBulkDocs = await Promise.all(uploadBulkDocTasks);
463
+ await remoteDB.bulkDocs(uploadBulkDocs, { new_edits: false });
464
+ uploadBulkDocs.forEach((e) => sentMap[idSeqMap[e._id]] = true);
465
+ await this.updateMaxTransferredSeqOnChunks(localDB, remoteID, sentMap);
466
+ sentDocsCount += bulkDocs2.length;
467
+ Logger(
468
+ `\u2191 Uploading chunks
469
+ ${sendingDocs}/(${sentDocsCount} done)`,
470
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
471
+ "send"
472
+ );
473
+ } catch (ex) {
474
+ Logger("Bulk sending failed.", showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO, "send");
475
+ Logger(ex, LOG_LEVEL_VERBOSE);
476
+ return false;
477
+ } finally {
478
+ releaser();
479
+ }
480
+ return true;
481
+ };
482
+ const tasks = [];
483
+ do {
484
+ const nowSendChunks = await trench.dequeue("send-chunks");
485
+ if (!nowSendChunks || nowSendChunks.length == 0) {
486
+ break;
487
+ }
488
+ for (const chunk of nowSendChunks) {
489
+ const jsonLength = te.encode(JSON.stringify(chunk.doc)).byteLength + 32;
490
+ if ((bulkDocsSizeBytes + jsonLength > maxBatchSizeBytes || bulkDocsSizeCount + 1 > maxBatchSizeCount) && bulkDocs.length > 0) {
491
+ tasks.push(sendChunks([...bulkDocs], bulkDocsSizeBytes, maxSeq));
492
+ bulkDocs = [];
493
+ bulkDocsSizeBytes = 0;
494
+ bulkDocsSizeCount = 0;
495
+ }
496
+ bulkDocs.push(chunk.doc);
497
+ maxSeq = chunk.seq;
498
+ bulkDocsSizeBytes += jsonLength;
499
+ bulkDocsSizeCount += 1;
500
+ }
501
+ if (bulkDocs.length > 0) {
502
+ tasks.push(sendChunks([...bulkDocs], bulkDocsSizeBytes, maxSeq));
503
+ }
504
+ const results = await Promise.all(
505
+ tasks.map(async (e) => {
506
+ try {
507
+ await e;
508
+ } catch (ex) {
509
+ Logger("Bulk sending failed.", showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO, "send");
510
+ Logger(ex, LOG_LEVEL_VERBOSE);
511
+ return false;
512
+ }
513
+ })
514
+ );
515
+ if (results.some((e) => e === false)) {
516
+ return false;
517
+ }
518
+ } while (true);
519
+ return true;
520
+ }
521
+ async openOneShotReplication(setting, showResult, retrying, syncMode, ignoreCleanLock = false) {
522
+ if (await this.ensurePBKDF2Salt(setting, showResult, !retrying) === false) {
523
+ return false;
524
+ }
525
+ const next = await shareRunningResult("oneShotReplication", async () => {
526
+ if (this.controller) {
527
+ Logger(
528
+ this.translate("liveSyncReplicator.replicationInProgress"),
529
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
530
+ "sync"
531
+ );
532
+ return false;
533
+ }
534
+ const localDB = this.rawDatabase;
535
+ Logger(this.translate("liveSyncReplicator.oneShotSyncBegin", { syncMode }));
536
+ const ret = await this.checkReplicationConnectivity(setting, false, retrying, showResult, ignoreCleanLock);
537
+ if (ret === false) {
538
+ Logger(
539
+ this.translate("liveSyncReplicator.couldNotConnectToServer"),
540
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
541
+ "sync"
542
+ );
543
+ return false;
544
+ }
545
+ this.maxPullSeq = Number(`${ret.info.update_seq}`.split("-")[0]);
546
+ this.maxPushSeq = Number(`${(await localDB.info()).update_seq}`.split("-")[0]);
547
+ if (showResult) {
548
+ Logger(this.translate("liveSyncReplicator.checkingLastSyncPoint"), LOG_LEVEL_NOTICE, "sync");
549
+ }
550
+ const { db, syncOptionBase } = ret;
551
+ this.syncStatus = "STARTED";
552
+ this.updateInfo();
553
+ const docArrivedOnStart = this.docArrived;
554
+ const docSentOnStart = this.docSent;
555
+ if (!retrying) {
556
+ this.originalSetting = setting;
557
+ }
558
+ this.terminateSync();
559
+ const syncHandler = syncMode == "sync" ? localDB.sync(db, { ...syncOptionBase }) : syncMode == "pullOnly" ? localDB.replicate.from(db, {
560
+ ...syncOptionBase,
561
+ ...setting.readChunksOnline ? selectorOnDemandPull : {}
562
+ }) : syncMode == "pushOnly" ? localDB.replicate.to(db, { ...syncOptionBase }) : void 0;
563
+ const syncResult = await this.processSync(
564
+ syncHandler,
565
+ showResult,
566
+ docSentOnStart,
567
+ docArrivedOnStart,
568
+ syncMode,
569
+ retrying,
570
+ false
571
+ );
572
+ if (syncResult == "DONE") {
573
+ return true;
574
+ }
575
+ if (syncResult == "CANCELLED") {
576
+ return false;
577
+ }
578
+ if (syncResult == "FAILED") {
579
+ return false;
580
+ }
581
+ if (syncResult == "NEED_RESURRECT") {
582
+ this.terminateSync();
583
+ return async () => await this.openOneShotReplication(
584
+ this.originalSetting,
585
+ showResult,
586
+ false,
587
+ syncMode,
588
+ ignoreCleanLock
589
+ );
590
+ }
591
+ if (syncResult == "NEED_RETRY") {
592
+ const tempSetting = JSON.parse(JSON.stringify(setting));
593
+ tempSetting.batch_size = Math.ceil(tempSetting.batch_size / 2) + 2;
594
+ tempSetting.batches_limit = Math.ceil(tempSetting.batches_limit / 2) + 2;
595
+ if (tempSetting.batch_size <= 5 && tempSetting.batches_limit <= 5) {
596
+ Logger(
597
+ this.translate("liveSyncReplicator.cantReplicateLowerValue"),
598
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO
599
+ );
600
+ return false;
601
+ } else {
602
+ Logger(
603
+ this.translate("liveSyncReplicator.retryLowerBatchSize", {
604
+ batch_size: tempSetting.batch_size.toString(),
605
+ batches_limit: tempSetting.batches_limit.toString()
606
+ }),
607
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO
608
+ );
609
+ return async () => await this.openOneShotReplication(tempSetting, showResult, true, syncMode, ignoreCleanLock);
610
+ }
611
+ }
612
+ return false;
613
+ });
614
+ if (typeof next === "boolean") {
615
+ return next;
616
+ }
617
+ return await next();
618
+ }
619
+ replicateAllToServer(setting, showingNotice) {
620
+ return this.openOneShotReplication(setting, showingNotice ?? false, false, "pushOnly");
621
+ }
622
+ replicateAllFromServer(setting, showingNotice) {
623
+ return this.openOneShotReplication(setting, showingNotice ?? false, false, "pullOnly");
624
+ }
625
+ async checkReplicationConnectivity(setting, keepAlive, skipCheck, showResult, ignoreCleanLock = false) {
626
+ if (setting.versionUpFlash != "") {
627
+ Logger(this.translate("Replicator.Message.VersionUpFlash"), LOG_LEVEL_NOTICE);
628
+ return false;
629
+ }
630
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
631
+ if (this.controller) {
632
+ Logger("Another replication running.");
633
+ return false;
634
+ }
635
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
636
+ if (typeof dbRet === "string") {
637
+ Logger(
638
+ this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }),
639
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO
640
+ );
641
+ return false;
642
+ }
643
+ if (!skipCheck) {
644
+ if (!await checkRemoteVersion(dbRet.db, this.migrate.bind(this), VER)) {
645
+ Logger(this.translate("liveSyncReplicator.remoteDbCorrupted"), LOG_LEVEL_NOTICE);
646
+ return false;
647
+ }
648
+ this.remoteCleaned = false;
649
+ this.remoteLocked = false;
650
+ this.remoteLockedAndDeviceNotAccepted = false;
651
+ this.tweakSettingsMismatched = false;
652
+ this.preferredTweakValue = void 0;
653
+ const progress = `${dbRet.info.update_seq}`;
654
+ const info = {
655
+ app_version: this.env.services.API.getAppVersion(),
656
+ plugin_version: this.env.services.API.getPluginVersion(),
657
+ vault_name: this.env.services.vault.vaultName(),
658
+ device_name: this.env.services.vault.getVaultName(),
659
+ progress
660
+ };
661
+ const ensure = await ensureDatabaseIsCompatible(dbRet.db, setting, this.nodeid, currentVersionRange, info);
662
+ if (ensure == "INCOMPATIBLE") {
663
+ Logger(
664
+ "The remote database has no compatibility with the running version. Please upgrade the plugin.",
665
+ LOG_LEVEL_NOTICE
666
+ );
667
+ return false;
668
+ } else if (ensure == "NODE_LOCKED") {
669
+ Logger(
670
+ "The remote database has been rebuilt or corrupted since we have synchronized last time. Fetch rebuilt DB, explicit unlocking or chunk clean-up is required.",
671
+ LOG_LEVEL_NOTICE
672
+ );
673
+ this.remoteLockedAndDeviceNotAccepted = true;
674
+ this.remoteLocked = true;
675
+ return false;
676
+ } else if (ensure == "LOCKED") {
677
+ this.remoteLocked = true;
678
+ } else if (ensure == "NODE_CLEANED") {
679
+ if (ignoreCleanLock) {
680
+ this.remoteLocked = true;
681
+ } else {
682
+ Logger(
683
+ "The remote database has been cleaned up. Fetch rebuilt DB, explicit unlocking or chunk clean-up is required.",
684
+ LOG_LEVEL_NOTICE
685
+ );
686
+ this.remoteLockedAndDeviceNotAccepted = true;
687
+ this.remoteLocked = true;
688
+ this.remoteCleaned = true;
689
+ return false;
690
+ }
691
+ } else if (ensure == "OK") {
692
+ } else if (ensure[0] == "MISMATCHED") {
693
+ Logger(this.translate("liveSyncReplicator.mismatchedTweakDetected"), LOG_LEVEL_NOTICE);
694
+ this.tweakSettingsMismatched = true;
695
+ this.preferredTweakValue = ensure[1];
696
+ return false;
697
+ }
698
+ }
699
+ const syncOptionBase = {
700
+ batches_limit: setting.batches_limit,
701
+ batch_size: setting.batch_size
702
+ };
703
+ syncOptionBase.push = {};
704
+ if (setting.readChunksOnline) {
705
+ syncOptionBase.pull = { ...selectorOnDemandPull };
706
+ }
707
+ const syncOption = keepAlive ? { live: true, retry: true, heartbeat: setting.useTimeouts ? false : 3e4, ...syncOptionBase } : { ...syncOptionBase };
708
+ return { db: dbRet.db, info: dbRet.info, syncOptionBase, syncOption };
709
+ }
710
+ async openContinuousReplication(setting, showResult, retrying) {
711
+ const next = await shareRunningResult("continuousReplication", async () => {
712
+ if (this.controller) {
713
+ Logger(
714
+ this.translate("liveSyncReplicator.replicationInProgress"),
715
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO
716
+ );
717
+ return false;
718
+ }
719
+ const localDB = this.rawDatabase;
720
+ Logger(this.translate("liveSyncReplicator.beforeLiveSync"));
721
+ const caughtUp = await this.env.services.replicator.runFiniteReplicationActivity(
722
+ () => this.openOneShotReplication(setting, showResult, false, "pullOnly"),
723
+ { label: "replication" }
724
+ );
725
+ if (caughtUp) {
726
+ Logger(this.translate("liveSyncReplicator.liveSyncBegin"));
727
+ const ret = await this.checkReplicationConnectivity(setting, true, true, showResult);
728
+ if (ret === false) {
729
+ Logger(
730
+ this.translate("liveSyncReplicator.couldNotConnectToServer"),
731
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO
732
+ );
733
+ return false;
734
+ }
735
+ if (showResult) {
736
+ Logger(this.translate("liveSyncReplicator.checkingLastSyncPoint"), LOG_LEVEL_NOTICE, "sync");
737
+ }
738
+ const { db, syncOption } = ret;
739
+ this.syncStatus = "STARTED";
740
+ this.maxPullSeq = Number(`${ret.info.update_seq}`.split("-")[0]);
741
+ this.maxPushSeq = Number(`${(await localDB.info()).update_seq}`.split("-")[0]);
742
+ this.updateInfo();
743
+ const docArrivedOnStart = this.docArrived;
744
+ const docSentOnStart = this.docSent;
745
+ if (!retrying) {
746
+ this.originalSetting = setting;
747
+ }
748
+ this.terminateSync();
749
+ const syncHandler = localDB.sync(db, {
750
+ ...syncOption
751
+ });
752
+ const syncMode = "sync";
753
+ const syncResult = await this.processSync(
754
+ syncHandler,
755
+ showResult,
756
+ docSentOnStart,
757
+ docArrivedOnStart,
758
+ syncMode,
759
+ retrying
760
+ );
761
+ if (syncResult == "DONE") {
762
+ return true;
763
+ }
764
+ if (syncResult == "FAILED") {
765
+ return false;
766
+ }
767
+ if (syncResult == "NEED_RESURRECT") {
768
+ this.terminateSync();
769
+ return async () => await this.openContinuousReplication(this.originalSetting, showResult, false);
770
+ }
771
+ if (syncResult == "NEED_RETRY") {
772
+ const tempSetting = JSON.parse(JSON.stringify(setting));
773
+ tempSetting.batch_size = Math.ceil(tempSetting.batch_size / 2) + 2;
774
+ tempSetting.batches_limit = Math.ceil(tempSetting.batches_limit / 2) + 2;
775
+ if (tempSetting.batch_size <= 5 && tempSetting.batches_limit <= 5) {
776
+ Logger(
777
+ this.translate("liveSyncReplicator.cantReplicateLowerValue"),
778
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO
779
+ );
780
+ return false;
781
+ } else {
782
+ Logger(
783
+ this.translate("liveSyncReplicator.retryLowerBatchSize", {
784
+ batch_size: tempSetting.batch_size.toString(),
785
+ batches_limit: tempSetting.batches_limit.toString()
786
+ }),
787
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO
788
+ );
789
+ return async () => await this.openContinuousReplication(tempSetting, showResult, true);
790
+ }
791
+ }
792
+ }
793
+ return false;
794
+ });
795
+ if (typeof next === "boolean") {
796
+ return next;
797
+ }
798
+ return await next();
799
+ }
800
+ closeReplication() {
801
+ if (!this.controller) {
802
+ return;
803
+ }
804
+ this.controller.abort();
805
+ this.controller = void 0;
806
+ this.syncStatus = "CLOSED";
807
+ Logger(this.translate("liveSyncReplicator.replicationClosed"));
808
+ this.updateInfo();
809
+ }
810
+ async tryResetRemoteDatabase(setting) {
811
+ this.closeReplication();
812
+ const con = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
813
+ if (typeof con == "string") return;
814
+ try {
815
+ await con.db.destroy();
816
+ Logger(this.translate("liveSyncReplicator.remoteDbDestroyed"), LOG_LEVEL_NOTICE);
817
+ await this.tryCreateRemoteDatabase(setting);
818
+ } catch (ex) {
819
+ Logger(this.translate("liveSyncReplicator.remoteDbDestroyError"), LOG_LEVEL_NOTICE);
820
+ Logger(ex, LOG_LEVEL_NOTICE);
821
+ }
822
+ clearHandlers();
823
+ await this.ensurePBKDF2Salt(setting, true, false);
824
+ }
825
+ async tryCreateRemoteDatabase(setting) {
826
+ this.closeReplication();
827
+ const con2 = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
828
+ if (typeof con2 === "string") return;
829
+ clearHandlers();
830
+ await this.ensurePBKDF2Salt(setting, true, false);
831
+ Logger(this.translate("liveSyncReplicator.remoteDbCreatedOrConnected"), LOG_LEVEL_NOTICE);
832
+ }
833
+ async markRemoteLocked(setting, locked, lockByClean) {
834
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
835
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
836
+ if (typeof dbRet === "string") {
837
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
838
+ return;
839
+ }
840
+ if (!await checkRemoteVersion(dbRet.db, this.migrate.bind(this), VER)) {
841
+ Logger(this.translate("liveSyncReplicator.remoteDbCorrupted"), LOG_LEVEL_NOTICE);
842
+ return;
843
+ }
844
+ const defInitPoint = {
845
+ _id: MILESTONE_DOCID,
846
+ type: "milestoneinfo",
847
+ created: Date.now(),
848
+ locked,
849
+ cleaned: lockByClean,
850
+ accepted_nodes: [this.nodeid],
851
+ node_chunk_info: { [this.nodeid]: currentVersionRange },
852
+ node_info: {},
853
+ tweak_values: {}
854
+ };
855
+ const remoteMilestone = {
856
+ ...defInitPoint,
857
+ ...await resolveWithIgnoreKnownError(dbRet.db.get(MILESTONE_DOCID), defInitPoint)
858
+ };
859
+ remoteMilestone.node_chunk_info = { ...defInitPoint.node_chunk_info, ...remoteMilestone.node_chunk_info };
860
+ remoteMilestone.accepted_nodes = [this.nodeid];
861
+ remoteMilestone.locked = locked;
862
+ remoteMilestone.cleaned = remoteMilestone.cleaned || lockByClean;
863
+ if (locked) {
864
+ Logger(this.translate("liveSyncReplicator.lockRemoteDb"), LOG_LEVEL_NOTICE);
865
+ } else {
866
+ Logger(this.translate("liveSyncReplicator.unlockRemoteDb"), LOG_LEVEL_NOTICE);
867
+ }
868
+ await dbRet.db.put(remoteMilestone);
869
+ }
870
+ async markRemoteResolved(setting) {
871
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
872
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
873
+ if (typeof dbRet === "string") {
874
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
875
+ return;
876
+ }
877
+ if (!await checkRemoteVersion(dbRet.db, this.migrate.bind(this), VER)) {
878
+ Logger(this.translate("liveSyncReplicator.remoteDbCorrupted"), LOG_LEVEL_NOTICE);
879
+ return;
880
+ }
881
+ const defInitPoint = {
882
+ _id: MILESTONE_DOCID,
883
+ type: "milestoneinfo",
884
+ created: Date.now(),
885
+ locked: false,
886
+ accepted_nodes: [this.nodeid],
887
+ node_info: {},
888
+ node_chunk_info: { [this.nodeid]: currentVersionRange },
889
+ tweak_values: {}
890
+ };
891
+ const remoteMilestone = {
892
+ ...defInitPoint,
893
+ ...await resolveWithIgnoreKnownError(dbRet.db.get(MILESTONE_DOCID), defInitPoint)
894
+ };
895
+ remoteMilestone.node_chunk_info = { ...defInitPoint.node_chunk_info, ...remoteMilestone.node_chunk_info };
896
+ remoteMilestone.accepted_nodes = Array.from(/* @__PURE__ */ new Set([...remoteMilestone.accepted_nodes, this.nodeid]));
897
+ Logger(this.translate("liveSyncReplicator.markDeviceResolved"), LOG_LEVEL_NOTICE);
898
+ const result = await dbRet.db.put(remoteMilestone);
899
+ if (result.ok) {
900
+ Logger(this.translate("liveSyncReplicator.remoteDbMarkedResolved"), LOG_LEVEL_VERBOSE);
901
+ } else {
902
+ Logger(this.translate("liveSyncReplicator.couldNotMarkResolveRemoteDb"), LOG_LEVEL_NOTICE);
903
+ }
904
+ }
905
+ connectRemoteCouchDBWithSetting(settings, isMobile, performSetup = false, skipInfo = false) {
906
+ if (settings.encrypt && settings.passphrase == "" && !settings.permitEmptyPassphrase) {
907
+ return "Empty passphrases cannot be used without explicit permission";
908
+ }
909
+ const customHeaders = parseHeaderValues(settings.couchDB_CustomHeaders);
910
+ const auth = settings.useJWT ? {
911
+ jwtAlgorithm: settings.jwtAlgorithm,
912
+ jwtKey: settings.jwtKey,
913
+ jwtExpDuration: settings.jwtExpDuration,
914
+ jwtKid: settings.jwtKid,
915
+ jwtSub: settings.jwtSub,
916
+ type: "jwt"
917
+ } : {
918
+ username: settings.couchDB_USER,
919
+ password: settings.couchDB_PASSWORD,
920
+ type: "basic"
921
+ };
922
+ return this.env.services.remote.connect(
923
+ settings.couchDB_URI.replace(/\/+$/, "") + (settings.couchDB_DBNAME == "" ? "" : "/" + settings.couchDB_DBNAME),
924
+ auth,
925
+ settings.disableRequestURI || isMobile,
926
+ settings.encrypt ? settings.passphrase : false,
927
+ settings.useDynamicIterationCount,
928
+ performSetup,
929
+ skipInfo,
930
+ settings.enableCompression,
931
+ customHeaders,
932
+ settings.useRequestAPI,
933
+ async () => await this.getReplicationPBKDF2Salt(settings)
934
+ );
935
+ }
936
+ async _ensureConnection(settings, performSetup = false) {
937
+ const ret = await this.connectRemoteCouchDBWithSetting(settings, this.isMobile(), performSetup, true);
938
+ if (typeof ret === "string") {
939
+ throw new Error(`${this.translate("liveSyncReplicator.couldNotConnectToServer")}:${ret}`);
940
+ }
941
+ return ret.db;
942
+ }
943
+ /**
944
+ * Fetch a document from the remote database directly.
945
+ * @param settings RemoteDBSettings for the connection.
946
+ * @param id Document ID to fetch.
947
+ * @param db Optional PouchDB instance to use. If provided, it will use this instance instead of creating a new connection (then settings will be ignored).
948
+ * @returns The fetched document or false if the document does not exist.
949
+ * @throws {Error} Other errors that may occur during the fetch operation.
950
+ */
951
+ async fetchRemoteDocument(settings, id, db) {
952
+ try {
953
+ const connDB = db ?? await this._ensureConnection(settings);
954
+ return await connDB.get(id);
955
+ } catch (ex) {
956
+ if (ex && ex.status == 404) {
957
+ return false;
958
+ }
959
+ throw ex;
960
+ }
961
+ }
962
+ /**
963
+ * Puts a document to the remote database directly
964
+ * @param settings RemoteDBSettings for the connection.
965
+ * @param doc Document to put.
966
+ * @param db Optional PouchDB instance to use. If provided, it will use this instance instead of creating a new connection (then settings will be ignored).
967
+ * @returns Response from the remote database or false if an error occurred.
968
+ * @throws {Error} If the document could not be put.
969
+ */
970
+ async putRemoteDocument(settings, doc, db) {
971
+ const connDB = db ?? await this._ensureConnection(settings, true);
972
+ return await connDB.put(doc);
973
+ }
974
+ async fetchRemoteChunks(missingChunks, showResult) {
975
+ const ret = await this.connectRemoteCouchDBWithSetting(this.currentSettings, this.isMobile(), false, true);
976
+ if (typeof ret === "string") {
977
+ Logger(
978
+ `${this.translate("liveSyncReplicator.couldNotConnectToServer")} ${ret} `,
979
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
980
+ "fetch"
981
+ );
982
+ return false;
983
+ }
984
+ const remoteChunks = await ret.db.allDocs({ keys: missingChunks, include_docs: true });
985
+ if (remoteChunks.rows.some((e) => "error" in e)) {
986
+ Logger(
987
+ `Some chunks are not exists both on remote and local database.`,
988
+ showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO,
989
+ "fetch"
990
+ );
991
+ Logger(`Missing chunks: ${missingChunks.join(",")}`, LOG_LEVEL_VERBOSE);
992
+ Logger(
993
+ `Error chunks: ${remoteChunks.rows.filter((e) => "error" in e).map((e) => e.key).join(",")}`,
994
+ LOG_LEVEL_VERBOSE
995
+ );
996
+ return false;
997
+ }
998
+ const remoteChunkItems = remoteChunks.rows.map((e) => e.doc);
999
+ return remoteChunkItems;
1000
+ }
1001
+ async tryConnectRemote(setting, showResult = true) {
1002
+ const db = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1003
+ if (typeof db === "string") {
1004
+ Logger(
1005
+ this.translate("liveSyncReplicator.couldNotConnectTo", {
1006
+ uri: setting.couchDB_URI,
1007
+ name: setting.couchDB_DBNAME,
1008
+ db
1009
+ }),
1010
+ LOG_LEVEL_NOTICE
1011
+ );
1012
+ return false;
1013
+ }
1014
+ Logger(`Connected to ${db.info.db_name} successfully`, LOG_LEVEL_NOTICE);
1015
+ return true;
1016
+ }
1017
+ async resetRemoteTweakSettings(setting) {
1018
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
1019
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1020
+ if (typeof dbRet === "string") {
1021
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
1022
+ return;
1023
+ }
1024
+ if (!await checkRemoteVersion(dbRet.db, this.migrate.bind(this), VER)) {
1025
+ Logger(this.translate("liveSyncReplicator.remoteDbCorrupted"), LOG_LEVEL_NOTICE);
1026
+ return;
1027
+ }
1028
+ try {
1029
+ const remoteMilestone = await dbRet.db.get(MILESTONE_DOCID);
1030
+ remoteMilestone.tweak_values = {};
1031
+ await dbRet.db.put(remoteMilestone);
1032
+ Logger(`tweak values on the remote database have been cleared`, LOG_LEVEL_VERBOSE);
1033
+ } catch (ex) {
1034
+ Logger(`Could not retrieve remote milestone`, LOG_LEVEL_NOTICE);
1035
+ throw ex;
1036
+ }
1037
+ }
1038
+ async setPreferredRemoteTweakSettings(setting) {
1039
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
1040
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1041
+ if (typeof dbRet === "string") {
1042
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
1043
+ return;
1044
+ }
1045
+ if (!await checkRemoteVersion(dbRet.db, this.migrate.bind(this), VER)) {
1046
+ Logger(this.translate("liveSyncReplicator.remoteDbCorrupted"), LOG_LEVEL_NOTICE);
1047
+ return;
1048
+ }
1049
+ try {
1050
+ const remoteMilestone = await dbRet.db.get(MILESTONE_DOCID);
1051
+ remoteMilestone.tweak_values[DEVICE_ID_PREFERRED] = extractObject(TweakValuesTemplate, { ...setting });
1052
+ await dbRet.db.put(remoteMilestone);
1053
+ Logger(`Preferred tweak values has been registered`, LOG_LEVEL_VERBOSE);
1054
+ } catch (ex) {
1055
+ Logger(`Could not retrieve remote milestone`, LOG_LEVEL_NOTICE);
1056
+ throw ex;
1057
+ }
1058
+ }
1059
+ async getRemotePreferredTweakValues(setting) {
1060
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
1061
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1062
+ if (typeof dbRet === "string") {
1063
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
1064
+ return false;
1065
+ }
1066
+ if (!await checkRemoteVersion(dbRet.db, this.migrate.bind(this), VER)) {
1067
+ Logger(this.translate("liveSyncReplicator.remoteDbCorrupted"), LOG_LEVEL_NOTICE);
1068
+ return false;
1069
+ }
1070
+ try {
1071
+ const remoteMilestone = await dbRet.db.get(MILESTONE_DOCID);
1072
+ if (!remoteMilestone) throw new Error("Remote milestone not found");
1073
+ return remoteMilestone?.tweak_values?.[DEVICE_ID_PREFERRED] || false;
1074
+ } catch (ex) {
1075
+ Logger(`Could not retrieve remote milestone`, LOG_LEVEL_NOTICE);
1076
+ Logger(ex, LOG_LEVEL_VERBOSE);
1077
+ return false;
1078
+ }
1079
+ }
1080
+ async compactRemote(setting) {
1081
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
1082
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1083
+ if (typeof dbRet === "string") {
1084
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
1085
+ return false;
1086
+ }
1087
+ const ret = await dbRet.db.compact({ interval: 1e3 });
1088
+ return ret.ok;
1089
+ }
1090
+ async getRemoteStatus(setting) {
1091
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1092
+ if (typeof dbRet === "string") {
1093
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
1094
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
1095
+ return false;
1096
+ }
1097
+ const info = await dbRet.db.info();
1098
+ return {
1099
+ ...info,
1100
+ estimatedSize: info?.sizes?.file || 0
1101
+ };
1102
+ }
1103
+ async countCompromisedChunks(setting = this.currentSettings) {
1104
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1105
+ if (typeof dbRet === "string") {
1106
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
1107
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
1108
+ return false;
1109
+ }
1110
+ const compromised = await countCompromisedChunks(dbRet.db);
1111
+ return compromised;
1112
+ }
1113
+ async getConnectedDeviceList(setting = this.currentSettings) {
1114
+ const dbRet = await this.connectRemoteCouchDBWithSetting(setting, this.isMobile(), true);
1115
+ if (typeof dbRet === "string") {
1116
+ const uri = setting.couchDB_URI.replace(/\/+$/, "") + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
1117
+ Logger(this.translate("liveSyncReplicator.couldNotConnectToURI", { uri, dbRet }), LOG_LEVEL_NOTICE);
1118
+ return false;
1119
+ }
1120
+ const milestoneDoc = await dbRet.db.get(MILESTONE_DOCID);
1121
+ if (!milestoneDoc) {
1122
+ Logger("Could not retrieve remote milestone", LOG_LEVEL_NOTICE);
1123
+ return false;
1124
+ }
1125
+ const nodeInfo = milestoneDoc.node_info;
1126
+ const acceptedNodes = milestoneDoc.accepted_nodes || [];
1127
+ return { node_info: nodeInfo, accepted_nodes: acceptedNodes };
1128
+ }
1129
+ }
1130
+ export {
1131
+ LiveSyncCouchDBReplicator
1132
+ };