@vrtmrz/livesync-commonlib 0.1.23 → 0.1.25

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 (53) hide show
  1. package/dist/API/processSetting.d.ts +1 -1
  2. package/dist/API/processSetting.js +10 -6
  3. package/dist/common/ConnectionString.js +15 -8
  4. package/dist/common/models/setting.const.qr.js +5 -0
  5. package/dist/common/models/setting.lifecycle.js +5 -3
  6. package/dist/common/models/setting.p2p.d.ts +10 -0
  7. package/dist/common/models/setting.p2p.js +13 -0
  8. package/dist/common/models/setting.type.d.ts +10 -0
  9. package/dist/common/models/tweak.compatibility.d.ts +34 -0
  10. package/dist/common/models/tweak.compatibility.js +110 -0
  11. package/dist/common/models/tweak.definition.d.ts +110 -19
  12. package/dist/common/models/tweak.definition.js +62 -29
  13. package/dist/common/settingConstants.d.ts +5 -0
  14. package/dist/common/types.d.ts +6 -3
  15. package/dist/common/types.js +6 -0
  16. package/dist/common/utils.js +4 -1
  17. package/dist/p2p/P2PService.d.ts +7 -1
  18. package/dist/p2p/P2PService.js +13 -7
  19. package/dist/p2p/index.d.ts +3 -1
  20. package/dist/p2p/index.js +6 -0
  21. package/dist/pouchdb/LiveSyncDBFunctions.d.ts +3 -3
  22. package/dist/pouchdb/LiveSyncDBFunctions.js +9 -15
  23. package/dist/replication/CentralCompatibility.d.ts +4 -2
  24. package/dist/replication/CentralCompatibility.js +5 -3
  25. package/dist/replication/couchdb/LiveSyncReplicator.js +10 -2
  26. package/dist/replication/journal/LiveSyncJournalReplicator.d.ts +2 -2
  27. package/dist/replication/journal/LiveSyncJournalReplicator.js +18 -4
  28. package/dist/replication/trystero/P2PRoomSessionOwner.d.ts +22 -1
  29. package/dist/replication/trystero/P2PRoomSessionOwner.js +193 -13
  30. package/dist/replication/trystero/TrysteroReplicator.js +12 -7
  31. package/dist/replication/trystero/TrysteroReplicatorP2PServer.d.ts +1 -0
  32. package/dist/replication/trystero/TrysteroReplicatorP2PServer.js +10 -3
  33. package/dist/replication/trystero/p2pReplicatorConfigurationIdentity.js +6 -3
  34. package/dist/replication/trystero/useP2PReplicatorFeature.d.ts +6 -1
  35. package/dist/replication/trystero/useP2PReplicatorFeature.js +7 -4
  36. package/dist/rpc/transports/trysteroUtils.d.ts +2 -2
  37. package/dist/rpc/transports/trysteroUtils.js +32 -2
  38. package/dist/serviceFeatures/remoteConfig.js +3 -0
  39. package/dist/services/base/IService.d.ts +3 -3
  40. package/dist/services/base/ReplicationService.d.ts +2 -2
  41. package/dist/services/base/ReplicationService.js +14 -11
  42. package/dist/services/base/SettingService.d.ts +1 -0
  43. package/dist/services/base/SettingService.js +37 -9
  44. package/dist/services/base/TweakValueService.d.ts +5 -3
  45. package/dist/services/implements/injectable/InjectableTweakValueService.d.ts +5 -5
  46. package/dist/settings.d.ts +3 -0
  47. package/dist/settings.js +2 -0
  48. package/dist/worker/bgWorker.js +1 -1
  49. package/docs/development.md +3 -3
  50. package/docs/p2p-transport-lifecycle.md +86 -4
  51. package/docs/proven-in-use.md +32 -0
  52. package/docs/settings-lifecycle.md +20 -1
  53. package/package.json +1 -1
@@ -63,6 +63,7 @@ export declare abstract class SettingService<T extends ServiceContext = ServiceC
63
63
  */
64
64
  saveSettingData(): Promise<void>;
65
65
  private encryptRemoteConfigurationUris;
66
+ private hasManagedP2PProfileURI;
66
67
  private decryptRemoteConfigurationUris;
67
68
  /**
68
69
  * Event triggered before realising the settings.
@@ -5,6 +5,7 @@ import {
5
5
  LOG_LEVEL_VERBOSE,
6
6
  SALT_OF_PASSPHRASE,
7
7
  SETTING_KEY_P2P_DEVICE_NAME,
8
+ omitP2PRuntimeSettings,
8
9
  prepareSettingsForLoad
9
10
  } from "../../common/types.js";
10
11
  import { handlers } from "../lib/HandlerUtils.js";
@@ -143,12 +144,7 @@ class SettingService extends ServiceBase {
143
144
  async saveSettingData() {
144
145
  this.saveDeviceAndVaultName();
145
146
  const previousSettings = this._lastPersistedSettings ?? this.cloneSettings(this.settings);
146
- const settings = {
147
- ...this.settings,
148
- remoteConfigurations: Object.fromEntries(
149
- Object.entries(this.settings.remoteConfigurations || {}).map(([id, config]) => [id, { ...config }])
150
- )
151
- };
147
+ const settings = this.cloneSettings(this.settings);
152
148
  const hookResults = await this.onBeforeSaveSettingData(settings, previousSettings);
153
149
  for (const patch of hookResults) {
154
150
  if (patch instanceof Error || !patch) continue;
@@ -161,7 +157,15 @@ class SettingService extends ServiceBase {
161
157
  this.setSmallConfig(SETTING_KEY_P2P_DEVICE_NAME, settings.P2P_DevicePeerName.trim());
162
158
  settings.P2P_DevicePeerName = "";
163
159
  }
160
+ delete settings.P2P_managedType;
161
+ delete settings.P2P_managedId;
162
+ delete settings.P2P_managedToken;
164
163
  if (this.usedPassphrase == "" && !await this.getPassphrase(settings)) {
164
+ if (Object.values(settings.remoteConfigurations).some((config) => this.hasManagedP2PProfileURI(config.uri))) {
165
+ const message = "Failed to retrieve a passphrase for managed P2P source data. Settings were not saved.";
166
+ this._log(message, LOG_LEVEL_URGENT);
167
+ throw new Error(message);
168
+ }
165
169
  this._log("Failed to retrieve passphrase. data.json contains unencrypted items!", LOG_LEVEL_NOTICE);
166
170
  } else {
167
171
  if (settings.couchDB_PASSWORD != "" || settings.couchDB_URI != "" || settings.couchDB_USER != "" || settings.couchDB_DBNAME) {
@@ -218,8 +222,24 @@ class SettingService extends ServiceBase {
218
222
  if (config.isEncrypted || config.uri.trim() === "") {
219
223
  continue;
220
224
  }
221
- const encryptedURI = await this.encryptConfigurationItem(config.uri, settings);
225
+ const managedP2PProfile = this.hasManagedP2PProfileURI(config.uri);
226
+ let encryptedURI;
227
+ try {
228
+ encryptedURI = await this.encryptConfigurationItem(config.uri, settings);
229
+ } catch (error) {
230
+ if (managedP2PProfile) {
231
+ const message = `Failed to encrypt managed P2P remote configuration '${id}'. Settings were not saved.`;
232
+ this._log(message, LOG_LEVEL_URGENT);
233
+ throw new Error(message);
234
+ }
235
+ throw error;
236
+ }
222
237
  if (encryptedURI === "") {
238
+ if (managedP2PProfile) {
239
+ const message = `Failed to encrypt managed P2P remote configuration '${id}'. Settings were not saved.`;
240
+ this._log(message, LOG_LEVEL_URGENT);
241
+ throw new Error(message);
242
+ }
223
243
  this._log(
224
244
  `Failed to encrypt remote configuration '${id}'. This entry will be saved in plain text.`,
225
245
  LOG_LEVEL_URGENT
@@ -233,6 +253,14 @@ class SettingService extends ServiceBase {
233
253
  };
234
254
  }
235
255
  }
256
+ hasManagedP2PProfileURI(uri) {
257
+ const trimmed = uri.trim();
258
+ if (!trimmed.startsWith("sls+p2p://")) return false;
259
+ const queryStart = trimmed.indexOf("?");
260
+ if (queryStart < 0) return false;
261
+ const query = trimmed.slice(queryStart + 1).split("#", 1)[0];
262
+ return (new URLSearchParams(query).get("managedType") ?? "").trim().length > 0;
263
+ }
236
264
  async decryptRemoteConfigurationUris(settings, passphrase) {
237
265
  const configs = settings.remoteConfigurations || {};
238
266
  for (const [id, config] of Object.entries(configs)) {
@@ -321,7 +349,7 @@ class SettingService extends ServiceBase {
321
349
  try {
322
350
  this.settings = await this.adjustSettings({
323
351
  ...this.settings,
324
- ...partial
352
+ ...omitP2PRuntimeSettings(partial)
325
353
  });
326
354
  } catch (ex) {
327
355
  this._log("Error in applying external settings: ", LOG_LEVEL_URGENT);
@@ -550,7 +578,7 @@ class SettingService extends ServiceBase {
550
578
  }
551
579
  cloneSettings(settings) {
552
580
  return {
553
- ...settings,
581
+ ...omitP2PRuntimeSettings(settings),
554
582
  remoteConfigurations: Object.fromEntries(
555
583
  Object.entries(settings.remoteConfigurations || {}).map(([id, config]) => [id, { ...config }])
556
584
  )
@@ -1,4 +1,4 @@
1
- import type { ObsidianLiveSyncSettings, RemoteDBSettings, RemotePreferredTweakResult, TweakValues } from "../../common/types.js";
1
+ import type { ObsidianLiveSyncSettings, RemoteDBSettings, RemotePreferredTweakResult, TweakAssessment, TweakValues } from "../../common/types.js";
2
2
  import type { ITweakValueService } from "./IService.js";
3
3
  import { ServiceBase, type ServiceContext } from "./ServiceBase.js";
4
4
  /**
@@ -13,14 +13,16 @@ export declare abstract class TweakValueService<T extends ServiceContext = Servi
13
13
  /**
14
14
  * Check and ask the user to resolve any mismatched tweak values.
15
15
  * @param preferred The preferred tweak values to check against.
16
+ * @param assessment The exact compatibility assessment from the calling operation, when available.
16
17
  */
17
- abstract checkAndAskResolvingMismatched(preferred: Partial<TweakValues>): Promise<[TweakValues | boolean, boolean]>;
18
+ abstract checkAndAskResolvingMismatched(preferred: Partial<TweakValues>, assessment?: TweakAssessment): Promise<[TweakValues | boolean, boolean]>;
18
19
  /**
19
20
  * Ask the user to resolve any mismatched tweak values.
20
21
  * @param preferredSource The preferred tweak values to resolve against.
21
22
  * @param updatePreferredRemote Optional exact-context writer supplied by the failed operation.
23
+ * @param assessment The exact compatibility assessment from the failed operation, when available.
22
24
  */
23
- abstract askResolvingMismatched(preferredSource: TweakValues, updatePreferredRemote?: (setting: ObsidianLiveSyncSettings) => Promise<boolean>): Promise<"OK" | "CHECKAGAIN" | "IGNORE">;
25
+ abstract askResolvingMismatched(preferredSource: TweakValues, updatePreferredRemote?: (setting: ObsidianLiveSyncSettings) => Promise<boolean>, assessment?: TweakAssessment): Promise<"OK" | "CHECKAGAIN" | "IGNORE">;
24
26
  /**
25
27
  * Check and ask the user to use the remote configuration.
26
28
  * @param settings The remote database settings to connect.
@@ -2,14 +2,14 @@ import type { ServiceContext } from "../../base/ServiceBase.js";
2
2
  import { TweakValueService } from "../../base/TweakValueService.js";
3
3
  export declare class InjectableTweakValueService<T extends ServiceContext> extends TweakValueService<T> {
4
4
  fetchRemotePreferred: import("../../lib/HandlerUtils.js").HandlerFunction<(trialSetting: import("../../../settings.js").RemoteDBSettings) => Promise<import("../../../common/types.js").RemotePreferredTweakResult>, unknown>;
5
- checkAndAskResolvingMismatched: import("../../lib/HandlerUtils.js").HandlerFunction<(preferred: Partial<import("../../../common/types.js").TweakValues>) => Promise<[import("../../../common/types.js").TweakValues | boolean, boolean]>, unknown>;
6
- askResolvingMismatched: import("../../lib/HandlerUtils.js").HandlerFunction<(preferredSource: import("../../../common/types.js").TweakValues, updatePreferredRemote?: (setting: import("../../../settings.js").ObsidianLiveSyncSettings) => Promise<boolean>) => Promise<"OK" | "CHECKAGAIN" | "IGNORE">, unknown>;
5
+ checkAndAskResolvingMismatched: import("../../lib/HandlerUtils.js").HandlerFunction<(preferred: Partial<import("../../../settings.js").TweakValues>, assessment?: import("../../../settings.js").TweakAssessment) => Promise<[import("../../../settings.js").TweakValues | boolean, boolean]>, unknown>;
6
+ askResolvingMismatched: import("../../lib/HandlerUtils.js").HandlerFunction<(preferredSource: import("../../../settings.js").TweakValues, updatePreferredRemote?: (setting: import("../../../settings.js").ObsidianLiveSyncSettings) => Promise<boolean>, assessment?: import("../../../settings.js").TweakAssessment) => Promise<"OK" | "CHECKAGAIN" | "IGNORE">, unknown>;
7
7
  checkAndAskUseRemoteConfiguration: import("../../lib/HandlerUtils.js").HandlerFunction<(settings: import("../../../settings.js").RemoteDBSettings) => Promise<{
8
- result: false | import("../../../common/types.js").TweakValues;
8
+ result: false | import("../../../settings.js").TweakValues;
9
9
  requireFetch: boolean;
10
10
  }>, unknown>;
11
- askUseRemoteConfiguration: import("../../lib/HandlerUtils.js").HandlerFunction<(trialSetting: import("../../../settings.js").RemoteDBSettings, preferred: import("../../../common/types.js").TweakValues) => Promise<{
12
- result: false | import("../../../common/types.js").TweakValues;
11
+ askUseRemoteConfiguration: import("../../lib/HandlerUtils.js").HandlerFunction<(trialSetting: import("../../../settings.js").RemoteDBSettings, preferred: import("../../../settings.js").TweakValues) => Promise<{
12
+ result: false | import("../../../settings.js").TweakValues;
13
13
  requireFetch: boolean;
14
14
  }>, unknown>;
15
15
  }
@@ -7,4 +7,7 @@ export { DEFAULT_SETTINGS, NEW_VAULT_SETTINGS, P2P_DEFAULT_SETTINGS, SETTINGS_SC
7
7
  export { PREFERRED_BASE, PREFERRED_JOURNAL_SYNC, PREFERRED_SETTING_CLOUDANT, PREFERRED_SETTING_SELF_HOSTED, } from "./common/models/setting.const.preferred.js";
8
8
  export { CURRENT_SETTING_VERSION } from "./common/models/setting.const.js";
9
9
  export { prepareSettingsForLoad, SettingsMigrationReviewCodes, type PreparedSettings, type SettingsMigrationReviewCode, type SettingsMigrationReviewReason, type SettingsMigrationState, } from "./common/models/setting.lifecycle.js";
10
+ export { assessTweakCompatibility } from "./common/models/tweak.compatibility.js";
11
+ export type { TweakAssessment, TweakAssessmentEntry, TweakAssessmentRelation, TweakAssessmentValue, TweakTransition, TweakTransitionReason, } from "./common/models/tweak.compatibility.js";
12
+ export type { TweakReconstruction, TweakValues } from "./common/models/tweak.definition.js";
10
13
  export type { ObsidianLiveSyncSettings, RemoteDBSettings, RemoteTypeSettings, } from "./common/models/setting.type.js";
package/dist/settings.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  prepareSettingsForLoad,
17
17
  SettingsMigrationReviewCodes
18
18
  } from "./common/models/setting.lifecycle.js";
19
+ import { assessTweakCompatibility } from "./common/models/tweak.compatibility.js";
19
20
  export {
20
21
  CURRENT_SETTING_VERSION,
21
22
  DEFAULT_SETTINGS,
@@ -27,6 +28,7 @@ export {
27
28
  PREFERRED_SETTING_SELF_HOSTED,
28
29
  SETTINGS_SCHEMA_DEFAULTS,
29
30
  SettingsMigrationReviewCodes,
31
+ assessTweakCompatibility,
30
32
  createNewVaultSettings,
31
33
  prepareSettingsForLoad
32
34
  };