@vrtmrz/livesync-commonlib 0.1.0-rc.2 → 0.1.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/API/DirectFileManipulatorV2.d.ts +3 -0
  2. package/dist/common/configForDoc.js +8 -4
  3. package/dist/common/messages/combinedMessages.prod.d.ts +9 -0
  4. package/dist/common/messages/combinedMessages.prod.js +9 -0
  5. package/dist/common/messages/def.d.ts +3 -0
  6. package/dist/common/messagesJson/en.json +3 -0
  7. package/dist/common/models/setting.const.defaults.js +1 -0
  8. package/dist/common/models/setting.const.preferred.js +1 -2
  9. package/dist/common/models/setting.lifecycle.d.ts +1 -0
  10. package/dist/common/models/setting.lifecycle.js +9 -1
  11. package/dist/common/models/setting.type.d.ts +8 -3
  12. package/dist/common/models/shared.definition.configNames.js +2 -2
  13. package/dist/common/models/tweak.definition.js +1 -6
  14. package/dist/common/settingConstants.js +4 -4
  15. package/dist/interfaces/Confirm.d.ts +2 -1
  16. package/dist/replication/LiveSyncAbstractReplicator.d.ts +1 -2
  17. package/dist/replication/couchdb/LiveSyncReplicator.d.ts +0 -1
  18. package/dist/replication/couchdb/LiveSyncReplicator.js +0 -3
  19. package/dist/replication/journal/LiveSyncJournalReplicator.d.ts +0 -1
  20. package/dist/replication/journal/LiveSyncJournalReplicator.js +0 -3
  21. package/dist/replication/trystero/LiveSyncTrysteroReplicator.d.ts +1 -2
  22. package/dist/replication/trystero/LiveSyncTrysteroReplicator.js +1 -4
  23. package/dist/serviceFeatures/checkRemoteSize.d.ts +5 -3
  24. package/dist/serviceFeatures/checkRemoteSize.js +51 -11
  25. package/dist/serviceModules/Rebuilder.d.ts +0 -4
  26. package/dist/serviceModules/Rebuilder.js +2 -10
  27. package/dist/services/base/IService.d.ts +1 -5
  28. package/dist/services/base/ReplicationService.d.ts +1 -1
  29. package/dist/services/base/ReplicationService.js +5 -15
  30. package/dist/services/base/SettingService.d.ts +0 -8
  31. package/dist/services/base/SettingService.js +0 -5
  32. package/dist/services/implements/headless/HeadlessAPIService.d.ts +2 -2
  33. package/dist/services/implements/headless/HeadlessAPIService.js +1 -1
  34. package/dist/worker/bgWorker.js +1 -1
  35. package/docs/development.md +8 -0
  36. package/docs/proven-in-use.md +9 -7
  37. package/docs/releasing.md +3 -1
  38. package/docs/settings-lifecycle.md +5 -3
  39. package/package.json +1 -1
@@ -27,6 +27,9 @@ export type DirectFileManipulatorOptions = {
27
27
  enableChunkSplitterV2?: boolean;
28
28
  enableCompression?: boolean;
29
29
  handleFilenameCaseSensitive?: boolean;
30
+ /**
31
+ * @deprecated Chunk revisions are always derived from their content.
32
+ */
30
33
  doNotUseFixedRevisionForChunks?: boolean;
31
34
  chunkSplitterVersion?: ChunkSplitterVersion;
32
35
  E2EEAlgorithm?: E2EEAlgorithm;
@@ -20,12 +20,12 @@ const DoctorRegulationV0_24_16 = {
20
20
  rules: {
21
21
  sendChunksBulk: {
22
22
  value: false,
23
- reason: "This is an obsolete setting and we should not enable this no more",
23
+ reason: "Automatic bulk chunk pre-send is obsolete and must remain disabled",
24
24
  level: 0 /* Must */
25
25
  },
26
26
  sendChunksBulkMaxSize: {
27
27
  value: 1,
28
- reason: "This is an obsolete setting and we should not enable this no more",
28
+ reason: "Use a conservative request size for the explicit manual chunk resend tool",
29
29
  level: 0 /* Must */
30
30
  },
31
31
  doNotUseFixedRevisionForChunks: {
@@ -111,7 +111,8 @@ const DoctorRegulationV0_25_27 = {
111
111
  version: "0.25.27",
112
112
  rules: {
113
113
  ...DoctorRegulationV0_25_0.rules,
114
- useIndexedDBAdapter: void 0
114
+ useIndexedDBAdapter: void 0,
115
+ doNotUseFixedRevisionForChunks: void 0
115
116
  }
116
117
  };
117
118
  const DoctorRegulation = DoctorRegulationV0_25_27;
@@ -263,7 +264,10 @@ async function performDoctorConsultation(env, settings, {
263
264
  }),
264
265
  options,
265
266
  {
266
- title: translate("Doctor.Dialogue.TitleFix", { current: `${++idx}`, total: `${issueItems.length}` }),
267
+ title: translate("Doctor.Dialogue.TitleFix", {
268
+ current: `${++idx}`,
269
+ total: `${issueItems.length}`
270
+ }),
267
271
  defaultAction: OPT_FIX
268
272
  }
269
273
  );
@@ -2597,6 +2597,12 @@ export declare const allMessages: {
2597
2597
  readonly ru: "Можно установить предупреждение о максимальной ёмкости базы данных.";
2598
2598
  readonly zh: "我们可以设置一个最大数据库容量警告,**以便在远程存储空间耗尽前采取行动**。\n您想启用这个功能吗?\n\n> [!MORE]-\n> - 0: 不警告存储大小。\n> 如果您在远程存储(尤其是自托管)上有足够的空间,则推荐此选项。您可以手动检查存储大小并重建。\n> - 800: 如果远程存储大小超过 800MB 则发出警告。\n> 如果您使用的是 fly.io(1GB 限制) 或 IBM Cloudant,则推荐此选项。\n> - 2000: 如果远程存储大小超过 2GB 则发出警告。\n\n如果达到限制,系统会要求我们逐步增大限制\n";
2599
2599
  };
2600
+ readonly "moduleCheckRemoteSize.noticeExceeded": {
2601
+ readonly def: "Remote storage size is ${measuredSize}, above the configured ${notifySize} notification threshold. {HERE}";
2602
+ };
2603
+ readonly "moduleCheckRemoteSize.noticeNotConfigured": {
2604
+ readonly def: "Remote storage size notifications are not configured. {HERE}";
2605
+ };
2600
2606
  readonly "moduleCheckRemoteSize.option2GB": {
2601
2607
  readonly def: "2GB (Standard)";
2602
2608
  readonly es: "2GB (Estándar)";
@@ -2667,6 +2673,9 @@ export declare const allMessages: {
2667
2673
  readonly ru: "Перестроить всё сейчас";
2668
2674
  readonly zh: "立即重建所有内容";
2669
2675
  };
2676
+ readonly "moduleCheckRemoteSize.optionReview": {
2677
+ readonly def: "Review options";
2678
+ };
2670
2679
  readonly "moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded": {
2671
2680
  readonly def: "Remote storage size exceeded the limit";
2672
2681
  readonly es: "El tamaño del almacenamiento remoto superó el límite";
@@ -2597,6 +2597,12 @@ const allMessages = {
2597
2597
  ru: "\u041C\u043E\u0436\u043D\u043E \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u043F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u0435 \u043E \u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0439 \u0451\u043C\u043A\u043E\u0441\u0442\u0438 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445.",
2598
2598
  zh: "\u6211\u4EEC\u53EF\u4EE5\u8BBE\u7F6E\u4E00\u4E2A\u6700\u5927\u6570\u636E\u5E93\u5BB9\u91CF\u8B66\u544A,**\u4EE5\u4FBF\u5728\u8FDC\u7A0B\u5B58\u50A8\u7A7A\u95F4\u8017\u5C3D\u524D\u91C7\u53D6\u884C\u52A8**\u3002\n\u60A8\u60F3\u542F\u7528\u8FD9\u4E2A\u529F\u80FD\u5417?\n\n> [!MORE]-\n> - 0: \u4E0D\u8B66\u544A\u5B58\u50A8\u5927\u5C0F\u3002\n> \u5982\u679C\u60A8\u5728\u8FDC\u7A0B\u5B58\u50A8(\u5C24\u5176\u662F\u81EA\u6258\u7BA1)\u4E0A\u6709\u8DB3\u591F\u7684\u7A7A\u95F4,\u5219\u63A8\u8350\u6B64\u9009\u9879\u3002\u60A8\u53EF\u4EE5\u624B\u52A8\u68C0\u67E5\u5B58\u50A8\u5927\u5C0F\u5E76\u91CD\u5EFA\u3002\n> - 800: \u5982\u679C\u8FDC\u7A0B\u5B58\u50A8\u5927\u5C0F\u8D85\u8FC7 800MB \u5219\u53D1\u51FA\u8B66\u544A\u3002\n> \u5982\u679C\u60A8\u4F7F\u7528\u7684\u662F fly.io(1GB \u9650\u5236) \u6216 IBM Cloudant,\u5219\u63A8\u8350\u6B64\u9009\u9879\u3002\n> - 2000: \u5982\u679C\u8FDC\u7A0B\u5B58\u50A8\u5927\u5C0F\u8D85\u8FC7 2GB \u5219\u53D1\u51FA\u8B66\u544A\u3002\n\n\u5982\u679C\u8FBE\u5230\u9650\u5236,\u7CFB\u7EDF\u4F1A\u8981\u6C42\u6211\u4EEC\u9010\u6B65\u589E\u5927\u9650\u5236\n"
2599
2599
  },
2600
+ "moduleCheckRemoteSize.noticeExceeded": {
2601
+ def: "Remote storage size is ${measuredSize}, above the configured ${notifySize} notification threshold. {HERE}"
2602
+ },
2603
+ "moduleCheckRemoteSize.noticeNotConfigured": {
2604
+ def: "Remote storage size notifications are not configured. {HERE}"
2605
+ },
2600
2606
  "moduleCheckRemoteSize.option2GB": {
2601
2607
  def: "2GB (Standard)",
2602
2608
  es: "2GB (Est\xE1ndar)",
@@ -2667,6 +2673,9 @@ const allMessages = {
2667
2673
  ru: "\u041F\u0435\u0440\u0435\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u0432\u0441\u0451 \u0441\u0435\u0439\u0447\u0430\u0441",
2668
2674
  zh: "\u7ACB\u5373\u91CD\u5EFA\u6240\u6709\u5185\u5BB9"
2669
2675
  },
2676
+ "moduleCheckRemoteSize.optionReview": {
2677
+ def: "Review options"
2678
+ },
2670
2679
  "moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded": {
2671
2680
  def: "Remote storage size exceeded the limit",
2672
2681
  es: "El tama\xF1o del almacenamiento remoto super\xF3 el l\xEDmite",
@@ -278,6 +278,8 @@ export declare const PartialMessages: {
278
278
  "moduleCheckRemoteSize.msgConfirmRebuild": string;
279
279
  "moduleCheckRemoteSize.msgDatabaseGrowing": string;
280
280
  "moduleCheckRemoteSize.msgSetDBCapacity": string;
281
+ "moduleCheckRemoteSize.noticeExceeded": string;
282
+ "moduleCheckRemoteSize.noticeNotConfigured": string;
281
283
  "moduleCheckRemoteSize.option2GB": string;
282
284
  "moduleCheckRemoteSize.option800MB": string;
283
285
  "moduleCheckRemoteSize.optionAskMeLater": string;
@@ -285,6 +287,7 @@ export declare const PartialMessages: {
285
287
  "moduleCheckRemoteSize.optionIncreaseLimit": string;
286
288
  "moduleCheckRemoteSize.optionNoWarn": string;
287
289
  "moduleCheckRemoteSize.optionRebuildAll": string;
290
+ "moduleCheckRemoteSize.optionReview": string;
288
291
  "moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded": string;
289
292
  "moduleCheckRemoteSize.titleDatabaseSizeNotify": string;
290
293
  "moduleInputUIObsidian.defaultTitleConfirmation": string;
@@ -277,6 +277,8 @@
277
277
  "moduleCheckRemoteSize.msgConfirmRebuild": "This may take a bit of a long time. Do you really want to rebuild everything now?",
278
278
  "moduleCheckRemoteSize.msgDatabaseGrowing": "**Your database is getting larger!** But do not worry, we can address it now. The time before running out of space on the remote storage.\n\n| Measured size | Configured size |\n| --- | --- |\n| ${estimatedSize} | ${maxSize} |\n\n> [!MORE]-\n> If you have been using it for many years, there may be unreferenced chunks - that is, garbage - accumulating in the database. Therefore, we recommend rebuilding everything. It will probably become much smaller.\n>\n> If the volume of your vault is simply increasing, it is better to rebuild everything after organizing the files. Self-hosted LiveSync does not delete the actual data even if you delete it to speed up the process. It is roughly [documented](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/tech_info.md).\n>\n> If you don't mind the increase, you can increase the notification limit by 100MB. This is the case if you are running it on your own server. However, it is better to rebuild everything from time to time.\n>\n\n> [!WARNING]\n> If you perform rebuild everything, make sure all devices are synchronised. The plug-in will merge as much as possible, though.\n",
279
279
  "moduleCheckRemoteSize.msgSetDBCapacity": "We can set a maximum database capacity warning, **to take action before running out of space on the remote storage**.\nDo you want to enable this?\n\n> [!MORE]-\n> - 0: Do not warn about storage size.\n> This is recommended if you have enough space on the remote storage especially you have self-hosted. And you can check the storage size and rebuild manually.\n> - 800: Warn if the remote storage size exceeds 800MB.\n> This is recommended if you are using fly.io with 1GB limit or IBM Cloudant.\n> - 2000: Warn if the remote storage size exceeds 2GB.\n\nIf we have reached the limit, we will be asked to enlarge the limit step by step.\n",
280
+ "moduleCheckRemoteSize.noticeExceeded": "Remote storage size is ${measuredSize}, above the configured ${notifySize} notification threshold. {HERE}",
281
+ "moduleCheckRemoteSize.noticeNotConfigured": "Remote storage size notifications are not configured. {HERE}",
280
282
  "moduleCheckRemoteSize.option2GB": "2GB (Standard)",
281
283
  "moduleCheckRemoteSize.option800MB": "800MB (Cloudant, fly.io)",
282
284
  "moduleCheckRemoteSize.optionAskMeLater": "Ask me later",
@@ -284,6 +286,7 @@
284
286
  "moduleCheckRemoteSize.optionIncreaseLimit": "increase to ${newMax}MB",
285
287
  "moduleCheckRemoteSize.optionNoWarn": "No, never warn please",
286
288
  "moduleCheckRemoteSize.optionRebuildAll": "Rebuild Everything Now",
289
+ "moduleCheckRemoteSize.optionReview": "Review options",
287
290
  "moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded": "Remote storage size exceeded the limit",
288
291
  "moduleCheckRemoteSize.titleDatabaseSizeNotify": "Setting up database size notification",
289
292
  "moduleInputUIObsidian.defaultTitleConfirmation": "Confirmation",
@@ -146,6 +146,7 @@ const SETTINGS_SCHEMA_DEFAULTS = {
146
146
  handleFilenameCaseSensitive: void 0,
147
147
  doNotUseFixedRevisionForChunks: true,
148
148
  showLongerLogInsideEditor: false,
149
+ /** @deprecated Retained for settings and Setup URI compatibility. */
149
150
  sendChunksBulk: false,
150
151
  sendChunksBulkMaxSize: 1,
151
152
  /**
@@ -2,7 +2,6 @@ import { E2EEAlgorithms } from "./setting.const.js";
2
2
  const PREFERRED_BASE = {
3
3
  syncMaxSizeInMB: 50,
4
4
  chunkSplitterVersion: "v3-rabin-karp",
5
- doNotUseFixedRevisionForChunks: false,
6
5
  usePluginSyncV2: true,
7
6
  handleFilenameCaseSensitive: false,
8
7
  E2EEAlgorithm: E2EEAlgorithms.V2
@@ -16,7 +15,7 @@ const PREFERRED_SETTING_CLOUDANT = {
16
15
  };
17
16
  const PREFERRED_SETTING_SELF_HOSTED = {
18
17
  ...PREFERRED_BASE,
19
- customChunkSize: 50,
18
+ customChunkSize: 60,
20
19
  sendChunksBulkMaxSize: 1,
21
20
  concurrencyOfReadChunksOnline: 30,
22
21
  minimumIntervalOfReadChunksOnline: 25
@@ -2,6 +2,7 @@ import type { ObsidianLiveSyncSettings } from "./setting.type.js";
2
2
  export declare const SettingsMigrationReviewCodes: {
3
3
  readonly LegacyUpdatePending: "legacy-update-review-pending";
4
4
  readonly FutureSchema: "settings-schema-newer-than-runtime";
5
+ readonly FilenameCaseSensitivityUnresolved: "filename-case-sensitivity-unresolved";
5
6
  };
6
7
  export type SettingsMigrationReviewCode = (typeof SettingsMigrationReviewCodes)[keyof typeof SettingsMigrationReviewCodes];
7
8
  export interface SettingsMigrationReviewReason {
@@ -6,7 +6,8 @@ import {
6
6
  } from "./setting.const.js";
7
7
  const SettingsMigrationReviewCodes = {
8
8
  LegacyUpdatePending: "legacy-update-review-pending",
9
- FutureSchema: "settings-schema-newer-than-runtime"
9
+ FutureSchema: "settings-schema-newer-than-runtime",
10
+ FilenameCaseSensitivityUnresolved: "filename-case-sensitivity-unresolved"
10
11
  };
11
12
  const SETTINGS_MIGRATIONS = [
12
13
  {
@@ -92,6 +93,13 @@ function prepareSettingsForLoad(storedSettings) {
92
93
  `No setting migration reaches schema ${CURRENT_SETTING_VERSION} from schema ${sourceVersion}.`
93
94
  );
94
95
  }
96
+ if (typeof migrated.handleFilenameCaseSensitive !== "boolean") {
97
+ reviewReasons.push({
98
+ code: SettingsMigrationReviewCodes.FilenameCaseSensitivityUnresolved,
99
+ fromVersion: sourceVersion,
100
+ toVersion: targetVersion
101
+ });
102
+ }
95
103
  return {
96
104
  settings: cloneSettings(migrated, SETTINGS_SCHEMA_DEFAULTS),
97
105
  sourceVersion,
@@ -599,7 +599,10 @@ interface ChunkSettings {
599
599
  */
600
600
  enableChunkSplitterV2: boolean;
601
601
  /**
602
- * Flag indicating whether to avoid using a fixed revision for chunks.
602
+ * Retained for stored-setting and Setup URI compatibility. Chunk revisions
603
+ * are always derived from their content, irrespective of this value.
604
+ *
605
+ * @deprecated This behaviour is no longer configurable.
603
606
  */
604
607
  doNotUseFixedRevisionForChunks: boolean;
605
608
  /**
@@ -668,11 +671,13 @@ interface ObsoleteRemoteDBSettings {
668
671
  */
669
672
  disableRequestURI: boolean;
670
673
  /**
671
- * Indicates whether to send data in bulk chunks.
674
+ * Retained for settings and Setup URI compatibility.
675
+ * Automatic bulk chunk pre-send is no longer supported.
676
+ * @deprecated
672
677
  */
673
678
  sendChunksBulk: boolean;
674
679
  /**
675
- * The maximum size of the bulk chunks to be sent.
680
+ * The maximum request size used by the explicit manual chunk resend tool, in MB.
676
681
  */
677
682
  sendChunksBulkMaxSize: number;
678
683
  /**
@@ -61,8 +61,8 @@ const configurationNames = {
61
61
  desc: "If this enabled, All files are handled as case-Sensitive (Previous behaviour)."
62
62
  },
63
63
  doNotUseFixedRevisionForChunks: {
64
- name: "Compute revisions for chunks (Previous behaviour)",
65
- desc: "If this enabled, all chunks will be stored with the revision made from its content. (Previous behaviour)"
64
+ name: "Content-derived chunk revisions (obsolete setting)",
65
+ desc: "Chunk revisions are always derived from their content. This stored key is retained only for compatibility."
66
66
  },
67
67
  useSegmenter: {
68
68
  name: "Use Segmented-splitter",
@@ -16,7 +16,6 @@ const TweakValuesShouldMatchedTemplate = {
16
16
  maxAgeInEden: 10,
17
17
  usePluginSyncV2: false,
18
18
  handleFilenameCaseSensitive: false,
19
- doNotUseFixedRevisionForChunks: true,
20
19
  useSegmenter: false,
21
20
  E2EEAlgorithm: E2EEAlgorithms.V2,
22
21
  chunkSplitterVersion: ChunkAlgorithms.RabinKarp
@@ -28,10 +27,7 @@ const IncompatibleChanges = [
28
27
  "handleFilenameCaseSensitive"
29
28
  ];
30
29
  const CompatibleButLossyChanges = ["hashAlg", "customChunkSize", "chunkSplitterVersion"];
31
- const IncompatibleChangesInSpecificPattern = [
32
- { key: "doNotUseFixedRevisionForChunks", from: true, to: false, isRecommendation: true },
33
- { key: "doNotUseFixedRevisionForChunks", to: true, isRecommendation: false }
34
- ];
30
+ const IncompatibleChangesInSpecificPattern = [];
35
31
  const TweakValuesRecommendedTemplate = {
36
32
  useIgnoreFiles: false,
37
33
  useCustomRequestHandler: false,
@@ -49,7 +45,6 @@ const TweakValuesRecommendedTemplate = {
49
45
  enableChunkSplitterV2: false,
50
46
  usePluginSyncV2: true,
51
47
  handleFilenameCaseSensitive: false,
52
- doNotUseFixedRevisionForChunks: false,
53
48
  E2EEAlgorithm: E2EEAlgorithms.V2,
54
49
  chunkSplitterVersion: ChunkAlgorithms.RabinKarp
55
50
  };
@@ -324,12 +324,12 @@ const SettingInformation = {
324
324
  desc: "If this enabled, All files are handled as case-Sensitive (Previous behaviour)."
325
325
  },
326
326
  doNotUseFixedRevisionForChunks: {
327
- name: "Compute revisions for chunks",
328
- desc: "If this enabled, all chunks will be stored with the revision made from its content."
327
+ name: "Content-derived chunk revisions (obsolete setting)",
328
+ desc: "Chunk revisions are always derived from their content. This stored key is retained only for compatibility."
329
329
  },
330
330
  sendChunksBulkMaxSize: {
331
- name: "Maximum size of chunks to send in one request",
332
- desc: "MB"
331
+ name: "Maximum request size for manually resending chunks",
332
+ desc: "MB per request"
333
333
  },
334
334
  useAdvancedMode: {
335
335
  name: "Enable advanced features"
@@ -1,3 +1,4 @@
1
+ export type ConfirmActionLayout = "auto" | "vertical";
1
2
  export interface Confirm {
2
3
  askYesNo(message: string): Promise<"yes" | "no">;
3
4
  askString(title: string, key: string, placeholder: string, isPassword?: boolean): Promise<string | false>;
@@ -20,5 +21,5 @@ export interface Confirm {
20
21
  * interactive action.
21
22
  */
22
23
  askInPopup(key: string, dialogText: string, anchorCallback: (anchor: HTMLAnchorElement) => void, durationMs?: number): void;
23
- confirmWithMessage(title: string, contentMd: string, buttons: string[], defaultAction: (typeof buttons)[number], timeout?: number): Promise<(typeof buttons)[number] | false>;
24
+ confirmWithMessage(title: string, contentMd: string, buttons: string[], defaultAction: (typeof buttons)[number], timeout?: number, actionLayout?: ConfirmActionLayout): Promise<(typeof buttons)[number] | false>;
24
25
  }
@@ -34,7 +34,6 @@ export declare abstract class LiveSyncAbstractReplicator {
34
34
  remoteLockedAndDeviceNotAccepted: boolean;
35
35
  tweakSettingsMismatched: boolean;
36
36
  preferredTweakValue?: TweakValues;
37
- abstract get isChunkSendingSupported(): boolean;
38
37
  get database(): import("../pouchdb/LiveSyncLocalDB.js").LiveSyncLocalDB;
39
38
  get rawDatabase(): PouchDB.Database<EntryDoc>;
40
39
  get currentSettings(): import("../common/types.js").ObsidianLiveSyncSettings;
@@ -49,7 +48,7 @@ export declare abstract class LiveSyncAbstractReplicator {
49
48
  abstract openReplication(setting: RemoteDBSettings, keepAlive: boolean, showResult: boolean, ignoreCleanLock: boolean): Promise<void | boolean>;
50
49
  updateInfo: () => void;
51
50
  abstract tryConnectRemote(setting: RemoteDBSettings, showResult?: boolean): Promise<boolean>;
52
- abstract replicateAllToServer(setting: RemoteDBSettings, showingNotice?: boolean, sendChunksInBulkDisabled?: boolean): Promise<boolean>;
51
+ abstract replicateAllToServer(setting: RemoteDBSettings, showingNotice?: boolean): Promise<boolean>;
53
52
  abstract replicateAllFromServer(setting: RemoteDBSettings, showingNotice?: boolean): Promise<boolean>;
54
53
  abstract closeReplication(): void;
55
54
  abstract tryResetRemoteDatabase(setting: RemoteDBSettings): Promise<void>;
@@ -5,7 +5,6 @@ export interface LiveSyncCouchDBReplicatorEnv extends LiveSyncReplicatorEnv {
5
5
  services: ServiceHub;
6
6
  }
7
7
  export declare class LiveSyncCouchDBReplicator extends LiveSyncAbstractReplicator {
8
- get isChunkSendingSupported(): boolean;
9
8
  isMobile(): boolean;
10
9
  constructor(env: LiveSyncCouchDBReplicatorEnv);
11
10
  getInitialSyncParameters(setting: RemoteDBSettings): Promise<SyncParameters>;
@@ -85,9 +85,6 @@ async function* genReplication(s, signal) {
85
85
  }
86
86
  }
87
87
  class LiveSyncCouchDBReplicator extends LiveSyncAbstractReplicator {
88
- get isChunkSendingSupported() {
89
- return true;
90
- }
91
88
  isMobile() {
92
89
  return this.env.services.API.isMobile();
93
90
  }
@@ -7,7 +7,6 @@ import { type SimpleStore } from "../../common/utils.js";
7
7
  import type { LiveSyncJournalReplicatorEnv } from "./LiveSyncJournalReplicatorEnv.js";
8
8
  export declare class LiveSyncJournalReplicator extends LiveSyncAbstractReplicator {
9
9
  env: LiveSyncJournalReplicatorEnv;
10
- get isChunkSendingSupported(): boolean;
11
10
  get client(): JournalSyncCore;
12
11
  get simpleStore(): SimpleStore<CheckPointInfo>;
13
12
  _client: JournalSyncCore;
@@ -19,9 +19,6 @@ const currentVersionRange = {
19
19
  current: 2
20
20
  };
21
21
  class LiveSyncJournalReplicator extends LiveSyncAbstractReplicator {
22
- get isChunkSendingSupported() {
23
- return false;
24
- }
25
22
  get client() {
26
23
  return this.setupJournalSyncClient();
27
24
  }
@@ -23,7 +23,6 @@ export declare class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicat
23
23
  get openReplicationUI(): (showResult: boolean) => Promise<boolean | void>;
24
24
  get rawReplicator(): TrysteroReplicator;
25
25
  get rawHost(): P2PHost;
26
- get isChunkSendingSupported(): boolean;
27
26
  getReplicationPBKDF2Salt(_setting: RemoteDBSettings, _refresh?: boolean): Promise<Uint8Array<ArrayBuffer>>;
28
27
  terminateSync(): void;
29
28
  private _buildEnv;
@@ -70,7 +69,7 @@ export declare class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicat
70
69
  makeSureOpened(): Promise<void>;
71
70
  openReplication(_setting: RemoteDBSettings, _keepAlive: boolean, showResult: boolean, _ignoreCleanLock: boolean): Promise<void | boolean>;
72
71
  tryConnectRemote(_setting: RemoteDBSettings, _showResult?: boolean): Promise<boolean>;
73
- replicateAllToServer(_setting: RemoteDBSettings, _showingNotice?: boolean, _sendChunksInBulkDisabled?: boolean): Promise<boolean>;
72
+ replicateAllToServer(_setting: RemoteDBSettings, _showingNotice?: boolean): Promise<boolean>;
74
73
  selectPeer(settingPeerName: string, r: TrysteroReplicator, logLevel: LOG_LEVEL): Promise<string | false>;
75
74
  tryUntilSuccess<T>(func: () => Promise<T | false>, repeat: number, logLevel: LOG_LEVEL): Promise<T | false>;
76
75
  replicateAllFromServer(setting: RemoteDBSettings, showingNotice?: boolean): Promise<boolean>;
@@ -29,9 +29,6 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
29
29
  get rawHost() {
30
30
  return this._p2pHost;
31
31
  }
32
- get isChunkSendingSupported() {
33
- return false;
34
- }
35
32
  getReplicationPBKDF2Salt(_setting, _refresh) {
36
33
  return Promise.resolve(new Uint8Array(32));
37
34
  }
@@ -215,7 +212,7 @@ class LiveSyncTrysteroReplicator extends LiveSyncAbstractReplicator {
215
212
  tryConnectRemote(_setting, _showResult) {
216
213
  return Promise.resolve(false);
217
214
  }
218
- replicateAllToServer(_setting, _showingNotice, _sendChunksInBulkDisabled) {
215
+ replicateAllToServer(_setting, _showingNotice) {
219
216
  return Promise.resolve(false);
220
217
  }
221
218
  async selectPeer(settingPeerName, r, logLevel) {
@@ -1,10 +1,11 @@
1
1
  import { createInstanceLogFunction, type LogFunction } from "../services/lib/logUtils.js";
2
2
  import type { NecessaryServices } from "../interfaces/ServiceModule.js";
3
+ type RemoteSizeReviewMode = "notice" | "dialogue";
3
4
  /**
4
5
  * Notify when checking remote storage size is not configured.
5
6
  * @returns true if the check is passed or user has configured the notification, false to block subsequent processes. (always true).
6
7
  */
7
- export declare function onNotifyRemoteSizeNotConfiguredFactory(host: NecessaryServices<"appLifecycle" | "API" | "setting", never>, log: ReturnType<typeof createInstanceLogFunction>): () => Promise<boolean>;
8
+ export declare function onNotifyRemoteSizeNotConfiguredFactory(host: NecessaryServices<"appLifecycle" | "API" | "setting", never>, log: ReturnType<typeof createInstanceLogFunction>, mode?: RemoteSizeReviewMode): () => Promise<boolean>;
8
9
  /**
9
10
  * Notify when the remote storage size exceed the threshold.
10
11
  * @returns true if the check is passed or user has chosen to ignore the warning, false to block subsequent processes.
@@ -12,7 +13,7 @@ export declare function onNotifyRemoteSizeNotConfiguredFactory(host: NecessarySe
12
13
  * @param log
13
14
  * @returns
14
15
  */
15
- export declare function onNotifyRemoteSizeExceedFactory(host: NecessaryServices<"API" | "setting" | "replicator", "rebuilder">, log: ReturnType<typeof createInstanceLogFunction>): () => Promise<boolean>;
16
+ export declare function onNotifyRemoteSizeExceedFactory(host: NecessaryServices<"API" | "setting" | "replicator", "rebuilder">, log: ReturnType<typeof createInstanceLogFunction>, mode?: RemoteSizeReviewMode): () => Promise<boolean>;
16
17
  /**
17
18
  * Scan the remote storage size and notify if it is not configured or exceed the threshold.
18
19
  * @param host The necessary services required for the operation.
@@ -20,9 +21,10 @@ export declare function onNotifyRemoteSizeExceedFactory(host: NecessaryServices<
20
21
  * @param resetThreshold Whether to reset the notification threshold before scanning. This is useful when you want to force the notification to show up again.
21
22
  * @returns A promise that resolves to true if all checks pass or user has configured the notification.
22
23
  */
23
- export declare function scanAllStat(host: NecessaryServices<"API" | "setting" | "replicator" | "appLifecycle", "rebuilder">, log: LogFunction, resetThreshold?: boolean): Promise<boolean>;
24
+ export declare function scanAllStat(host: NecessaryServices<"API" | "setting" | "replicator" | "appLifecycle", "rebuilder">, log: LogFunction, resetThreshold?: boolean, mode?: RemoteSizeReviewMode): Promise<boolean>;
24
25
  /**
25
26
  * Associate the remote storage size check feature with the app lifecycle events.
26
27
  * @param host
27
28
  */
28
29
  export declare function useCheckRemoteSize(host: NecessaryServices<"API" | "setting" | "replicator" | "appLifecycle", "rebuilder">): void;
30
+ export {};
@@ -2,7 +2,17 @@ import { sizeToHumanReadable } from "octagonal-wheels/number";
2
2
  import { LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "../common/types.js";
3
3
  import { createInstanceLogFunction } from "../services/lib/logUtils.js";
4
4
  import { EVENT_REQUEST_CHECK_REMOTE_SIZE } from "../events/coreEvents.js";
5
- function onNotifyRemoteSizeNotConfiguredFactory(host, log) {
5
+ import { fireAndForget } from "../common/utils.js";
6
+ const REMOTE_SIZE_NOTICE_DURATION_MS = 5 * 60 * 1e3;
7
+ function configureReviewAnchor(anchor, label, review) {
8
+ anchor.href = "#";
9
+ anchor.textContent = label;
10
+ anchor.addEventListener("click", (event) => {
11
+ event.preventDefault();
12
+ fireAndForget(review);
13
+ });
14
+ }
15
+ function onNotifyRemoteSizeNotConfiguredFactory(host, log, mode = "notice") {
6
16
  return async () => {
7
17
  const translate = host.services.context.translate;
8
18
  log(translate("moduleCheckRemoteSize.logCheckingStorageSizes"), LOG_LEVEL_VERBOSE);
@@ -15,13 +25,25 @@ function onNotifyRemoteSizeNotConfiguredFactory(host, log) {
15
25
  const ANSWER_800 = translate("moduleCheckRemoteSize.option800MB");
16
26
  const ANSWER_2000 = translate("moduleCheckRemoteSize.option2GB");
17
27
  const ASK_ME_NEXT_TIME = translate("moduleCheckRemoteSize.optionAskMeLater");
28
+ if (mode === "notice") {
29
+ host.services.API.confirm.askInPopup(
30
+ "remote-size-not-configured",
31
+ translate("moduleCheckRemoteSize.noticeNotConfigured"),
32
+ (anchor) => configureReviewAnchor(
33
+ anchor,
34
+ translate("moduleCheckRemoteSize.optionReview"),
35
+ () => onNotifyRemoteSizeNotConfiguredFactory(host, log, "dialogue")()
36
+ ),
37
+ REMOTE_SIZE_NOTICE_DURATION_MS
38
+ );
39
+ return true;
40
+ }
18
41
  const ret = await host.services.API.confirm.askSelectStringDialogue(
19
42
  message,
20
43
  [ANSWER_0, ANSWER_800, ANSWER_2000, ASK_ME_NEXT_TIME],
21
44
  {
22
45
  defaultAction: ASK_ME_NEXT_TIME,
23
- title: translate("moduleCheckRemoteSize.titleDatabaseSizeNotify"),
24
- timeout: 40
46
+ title: translate("moduleCheckRemoteSize.titleDatabaseSizeNotify")
25
47
  }
26
48
  );
27
49
  if (ret == ANSWER_0) {
@@ -49,7 +71,7 @@ function onNotifyRemoteSizeNotConfiguredFactory(host, log) {
49
71
  return true;
50
72
  };
51
73
  }
52
- function onNotifyRemoteSizeExceedFactory(host, log) {
74
+ function onNotifyRemoteSizeExceedFactory(host, log, mode = "notice") {
53
75
  return async () => {
54
76
  const translate = host.services.context.translate;
55
77
  const settings = host.services.setting.currentSettings();
@@ -89,13 +111,28 @@ function onNotifyRemoteSizeExceedFactory(host, log) {
89
111
  });
90
112
  const ANSWER_REBUILD = translate("moduleCheckRemoteSize.optionRebuildAll");
91
113
  const ANSWER_IGNORE = translate("moduleCheckRemoteSize.optionDismiss");
114
+ if (mode === "notice") {
115
+ host.services.API.confirm.askInPopup(
116
+ "remote-size-exceeded",
117
+ translate("moduleCheckRemoteSize.noticeExceeded", {
118
+ measuredSize: sizeToHumanReadable(estimatedSize),
119
+ notifySize: sizeToHumanReadable(maxSize)
120
+ }),
121
+ (anchor) => configureReviewAnchor(
122
+ anchor,
123
+ translate("moduleCheckRemoteSize.optionReview"),
124
+ () => onNotifyRemoteSizeExceedFactory(host, log, "dialogue")()
125
+ ),
126
+ REMOTE_SIZE_NOTICE_DURATION_MS
127
+ );
128
+ return true;
129
+ }
92
130
  const ret = await host.services.API.confirm.askSelectStringDialogue(
93
131
  message,
94
132
  [ANSWER_ENLARGE_LIMIT, ANSWER_REBUILD, ANSWER_IGNORE],
95
133
  {
96
134
  defaultAction: ANSWER_IGNORE,
97
- title: translate("moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded"),
98
- timeout: 60
135
+ title: translate("moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded")
99
136
  }
100
137
  );
101
138
  if (ret == ANSWER_REBUILD) {
@@ -142,7 +179,7 @@ function onNotifyRemoteSizeExceedFactory(host, log) {
142
179
  return true;
143
180
  };
144
181
  }
145
- async function scanAllStat(host, log, resetThreshold = false) {
182
+ async function scanAllStat(host, log, resetThreshold = false, mode = "notice") {
146
183
  if (resetThreshold) {
147
184
  await host.services.setting.applyPartial(
148
185
  {
@@ -151,8 +188,8 @@ async function scanAllStat(host, log, resetThreshold = false) {
151
188
  true
152
189
  );
153
190
  }
154
- const onNotifyNotConfigured = onNotifyRemoteSizeNotConfiguredFactory(host, log);
155
- const onNotifyExceed = onNotifyRemoteSizeExceedFactory(host, log);
191
+ const onNotifyNotConfigured = onNotifyRemoteSizeNotConfiguredFactory(host, log, mode);
192
+ const onNotifyExceed = onNotifyRemoteSizeExceedFactory(host, log, mode);
156
193
  return await onNotifyNotConfigured() && await onNotifyExceed();
157
194
  }
158
195
  function useCheckRemoteSize(host) {
@@ -163,10 +200,13 @@ function useCheckRemoteSize(host) {
163
200
  id: "livesync-reset-remote-size-threshold-and-check",
164
201
  name: "Reset notification threshold and check the remote database usage",
165
202
  callback: async () => {
166
- await scanAllStat(host, log, true);
203
+ await scanAllStat(host, log, true, "dialogue");
167
204
  }
168
205
  });
169
- host.services.context.events.onEvent(EVENT_REQUEST_CHECK_REMOTE_SIZE, () => scanAllStat(host, log, true));
206
+ host.services.context.events.onEvent(
207
+ EVENT_REQUEST_CHECK_REMOTE_SIZE,
208
+ () => scanAllStat(host, log, true, "dialogue")
209
+ );
170
210
  return Promise.resolve(true);
171
211
  });
172
212
  }
@@ -48,10 +48,6 @@ export declare class ServiceRebuilder extends ServiceModuleBase<ServiceRebuilder
48
48
  constructor(services: ServiceRebuilderDependencies);
49
49
  $performRebuildDB(method: "localOnly" | "remoteOnly" | "rebuildBothByThisDevice" | "localOnlyWithChunks"): Promise<void>;
50
50
  informOptionalFeatures(): Promise<void>;
51
- askUsingOptionalFeature(opt: {
52
- enableFetch?: boolean;
53
- enableOverwrite?: boolean;
54
- }): Promise<void>;
55
51
  rebuildRemote(): Promise<void>;
56
52
  private performRemoteRebuild;
57
53
  $rebuildRemote(): Promise<void>;
@@ -67,14 +67,6 @@ Please enable them from the settings screen after setup is complete.`,
67
67
  ["OK"]
68
68
  );
69
69
  }
70
- async askUsingOptionalFeature(opt) {
71
- if (await this.UI.confirm.askYesNoDialog(
72
- "Do you want to enable extra features? If you are new to Self-hosted LiveSync, try the core feature first!",
73
- { title: "Enable extra features", defaultOption: "No", timeout: 15 }
74
- ) == "yes") {
75
- await this.setting.suggestOptionalFeatures(opt);
76
- }
77
- }
78
70
  async rebuildRemote() {
79
71
  await this.replicator.runBoundedRemoteActivity(() => this.performRemoteRebuild(), {
80
72
  label: "rebuild-remote"
@@ -95,7 +87,7 @@ Please enable them from the settings screen after setup is complete.`,
95
87
  await delay(1e3);
96
88
  await this.replication.replicateAllToRemote(true);
97
89
  await delay(1e3);
98
- await this.replication.replicateAllToRemote(true, true);
90
+ await this.replication.replicateAllToRemote(true);
99
91
  }
100
92
  $rebuildRemote() {
101
93
  return this.rebuildRemote();
@@ -123,7 +115,7 @@ Please enable them from the settings screen after setup is complete.`,
123
115
  await delay(1e3);
124
116
  await this.replication.replicateAllToRemote(true);
125
117
  await delay(1e3);
126
- await this.replication.replicateAllToRemote(true, true);
118
+ await this.replication.replicateAllToRemote(true);
127
119
  }
128
120
  $rebuildEverything() {
129
121
  return this.rebuildEverything();
@@ -128,7 +128,7 @@ export interface IReplicationService {
128
128
  databaseQueueCount: ReactiveSource<number>;
129
129
  storageApplyingCount: ReactiveSource<number>;
130
130
  replicationResultCount: ReactiveSource<number>;
131
- replicateAllToRemote(showingNotice?: boolean, sendChunksInBulkDisabled?: boolean): Promise<boolean>;
131
+ replicateAllToRemote(showingNotice?: boolean): Promise<boolean>;
132
132
  replicateAllFromRemote(showingNotice?: boolean): Promise<boolean>;
133
133
  markLocked(lockByClean?: boolean): Promise<void>;
134
134
  markUnlocked(): Promise<void>;
@@ -189,10 +189,6 @@ export interface ISettingService {
189
189
  onRealiseSetting(): Promise<boolean>;
190
190
  suspendAllSync(): Promise<boolean>;
191
191
  suspendExtraSync(): Promise<boolean>;
192
- suggestOptionalFeatures(opt: {
193
- enableFetch?: boolean;
194
- enableOverwrite?: boolean;
195
- }): Promise<boolean>;
196
192
  enableOptionalFeature(mode: keyof OPTIONAL_SYNC_FEATURES): Promise<boolean>;
197
193
  clearUsedPassphrase(): void;
198
194
  decryptSettings(settings: ObsidianLiveSyncSettings): Promise<ObsidianLiveSyncSettings>;
@@ -85,7 +85,7 @@ export declare abstract class ReplicationService<T extends ServiceContext = Serv
85
85
  storageApplyingCount: import("octagonal-wheels/dataobject/reactive_v2").ReactiveSource<number>;
86
86
  replicationResultCount: import("octagonal-wheels/dataobject/reactive_v2").ReactiveSource<number>;
87
87
  getActiveReplicatorFor(usage: string): false | LiveSyncAbstractReplicator;
88
- replicateAllToRemote(showingNotice?: boolean, sendChunksInBulkDisabled?: boolean): Promise<boolean>;
88
+ replicateAllToRemote(showingNotice?: boolean): Promise<boolean>;
89
89
  replicateAllFromRemote(showingNotice?: boolean): Promise<boolean>;
90
90
  private _getReplicatorAndPerform;
91
91
  markLocked(lockByClean?: boolean): Promise<void>;