@vrtmrz/livesync-commonlib 0.1.0-rc.5 → 0.1.0-rc.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -9
- package/dist/common/configForDoc.js +7 -2
- package/dist/common/models/setting.type.d.ts +2 -1
- package/dist/common/models/tweak.definition.d.ts +1 -1
- package/dist/common/settingConstants.d.ts +3 -2
- package/dist/common/settingConstants.js +2 -2
- package/dist/context.d.ts +2 -1
- package/dist/context.js +4 -0
- package/dist/platform/node/storage.d.ts +4 -0
- package/dist/platform/node/storage.js +86 -25
- package/dist/replication/LiveSyncAbstractReplicator.d.ts +2 -1
- package/dist/replication/trystero/addP2PEventHandlers.js +1 -4
- package/dist/replication/trystero/useP2PReplicatorFeature.js +24 -14
- package/dist/serviceModules/Rebuilder.js +8 -3
- package/dist/services/BrowserServices.d.ts +2 -0
- package/dist/services/BrowserServices.js +4 -1
- package/dist/services/HeadlessServices.d.ts +2 -0
- package/dist/services/HeadlessServices.js +2 -1
- package/dist/services/base/CommonlibMessages.d.ts +318 -0
- package/dist/services/base/CommonlibMessages.js +313 -0
- package/dist/services/base/MessageTranslator.d.ts +5 -2
- package/dist/services/base/MessageTranslator.js +21 -0
- package/dist/services/base/ServiceBase.d.ts +1 -1
- package/dist/services/base/ServiceBase.js +2 -4
- package/dist/services/base/SettingService.d.ts +3 -0
- package/dist/services/base/SettingService.js +3 -2
- package/docs/development.md +28 -15
- package/docs/p2p-transport-lifecycle.md +14 -4
- package/docs/platform-storage.md +2 -0
- package/docs/proven-in-use.md +18 -12
- package/docs/releasing.md +14 -0
- package/package.json +1 -26
- package/dist/common/i18n.d.ts +0 -18
- package/dist/common/i18n.js +0 -101
- package/dist/common/messages/combinedMessages.dev.d.ts +0 -7
- package/dist/common/messages/combinedMessages.dev.js +0 -44
- package/dist/common/messages/combinedMessages.prod.d.ts +0 -9276
- package/dist/common/messages/combinedMessages.prod.js +0 -9283
- package/dist/common/messages/de.d.ts +0 -297
- package/dist/common/messages/de.js +0 -7
- package/dist/common/messages/def.d.ts +0 -1123
- package/dist/common/messages/def.js +0 -7
- package/dist/common/messages/es.d.ts +0 -689
- package/dist/common/messages/es.js +0 -7
- package/dist/common/messages/fr.d.ts +0 -582
- package/dist/common/messages/fr.js +0 -7
- package/dist/common/messages/he.d.ts +0 -583
- package/dist/common/messages/he.js +0 -7
- package/dist/common/messages/ja.d.ts +0 -838
- package/dist/common/messages/ja.js +0 -7
- package/dist/common/messages/ko.d.ts +0 -800
- package/dist/common/messages/ko.js +0 -7
- package/dist/common/messages/ru.d.ts +0 -858
- package/dist/common/messages/ru.js +0 -7
- package/dist/common/messages/zh-tw.d.ts +0 -384
- package/dist/common/messages/zh-tw.js +0 -7
- package/dist/common/messages/zh.d.ts +0 -1093
- package/dist/common/messages/zh.js +0 -7
- package/dist/common/messagesJson/de.json +0 -295
- package/dist/common/messagesJson/en.json +0 -1121
- package/dist/common/messagesJson/es.json +0 -687
- package/dist/common/messagesJson/fr.json +0 -580
- package/dist/common/messagesJson/he.json +0 -581
- package/dist/common/messagesJson/ja.json +0 -836
- package/dist/common/messagesJson/ko.json +0 -798
- package/dist/common/messagesJson/ru.json +0 -856
- package/dist/common/messagesJson/zh-tw.json +0 -382
- package/dist/common/messagesJson/zh.json +0 -1091
- package/dist/common/rosetta.d.ts +0 -42
- package/dist/common/rosetta.js +0 -57
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
const commonlibEnglishMessages = {
|
|
2
|
+
"(BETA) Always overwrite with a newer file": "(BETA) Always overwrite with a newer file",
|
|
3
|
+
"(Beta) Use ignore files": "(Beta) Use ignore files",
|
|
4
|
+
"(Days passed, 0 to disable automatic-deletion)": "(Days passed, 0 to disable automatic-deletion)",
|
|
5
|
+
"(MB) If this is set, changes to local and remote files that are larger than this will be skipped. If the file becomes smaller again, a newer one will be used.": "(MB) If this is set, changes to local and remote files that are larger than this will be skipped. If the file becomes smaller again, a newer one will be used.",
|
|
6
|
+
"(Mega chars)": "(Mega chars)",
|
|
7
|
+
"(Not recommended) If set, credentials will be stored in the file.": "(Not recommended) If set, credentials will be stored in the file.",
|
|
8
|
+
"(Obsolete) Use an old adapter for compatibility": "(Obsolete) Use an old adapter for compatibility",
|
|
9
|
+
"(ex. Read chunks online) If this option is enabled, LiveSync reads chunks online directly instead of replicating them locally. Increasing Custom chunk size is recommended.": "(ex. Read chunks online) If this option is enabled, LiveSync reads chunks online directly instead of replicating them locally. Increasing Custom chunk size is recommended.",
|
|
10
|
+
"Access Key": "Access Key",
|
|
11
|
+
"Active Remote Type": "Active Remote Type",
|
|
12
|
+
"Always prompt merge conflicts": "Always prompt merge conflicts",
|
|
13
|
+
"Application ID": "Application ID",
|
|
14
|
+
"Apply Latest Change if Conflicting": "Apply Latest Change if Conflicting",
|
|
15
|
+
"Apply preset configuration": "Apply preset configuration",
|
|
16
|
+
"Auto-accept compatible tweak mismatches": "Auto-accept compatible tweak mismatches",
|
|
17
|
+
"Automatically Sync all files when opening Obsidian.": "Automatically Sync all files when opening Obsidian.",
|
|
18
|
+
"Automatically accepts mismatches that are compatible but potentially lossy by comparing tweak modification times.": "Automatically accepts mismatches that are compatible but potentially lossy by comparing tweak modification times.",
|
|
19
|
+
"Automatically broadcast changes to connected peers": "Automatically broadcast changes to connected peers",
|
|
20
|
+
"Automatically start P2P connection on launch": "Automatically start P2P connection on launch",
|
|
21
|
+
"Batch database update": "Batch database update",
|
|
22
|
+
"Batch limit": "Batch limit",
|
|
23
|
+
"Batch size": "Batch size",
|
|
24
|
+
"Batch size of on-demand fetching": "Batch size of on-demand fetching",
|
|
25
|
+
"Before v0.17.16, we used an old adapter for the local database. Now the new adapter is preferred. However, it needs local database rebuilding. Please disable this toggle when you have enough time. If leave it enabled, also while fetching from the remote database, you will be asked to disable this.": "Before v0.17.16, we used an old adapter for the local database. Now the new adapter is preferred. However, it needs local database rebuilding. Please disable this toggle when you have enough time. If leave it enabled, also while fetching from the remote database, you will be asked to disable this.",
|
|
26
|
+
"Bucket Name": "Bucket Name",
|
|
27
|
+
"Chunk Splitter": "Chunk Splitter",
|
|
28
|
+
"Chunk revisions are always derived from their content. This stored key is retained only for compatibility.": "Chunk revisions are always derived from their content. This stored key is retained only for compatibility.",
|
|
29
|
+
"Comma separated `.gitignore, .dockerignore`": "Comma separated `.gitignore, .dockerignore`",
|
|
30
|
+
"Content-derived chunk revisions (obsolete setting)": "Content-derived chunk revisions (obsolete setting)",
|
|
31
|
+
"Custom Headers": "Custom Headers",
|
|
32
|
+
"Custom headers for requesting the CouchDB. e.g. `x-custom-header1: value1\n x-custom-header2: value2`": "Custom headers for requesting the CouchDB. e.g. `x-custom-header1: value1\n x-custom-header2: value2`",
|
|
33
|
+
"Custom headers for requesting the bucket. e.g. `x-custom-header1: value1\n x-custom-header2: value2`": "Custom headers for requesting the bucket. e.g. `x-custom-header1: value1\n x-custom-header2: value2`",
|
|
34
|
+
"Data Compression": "Data Compression",
|
|
35
|
+
"Database Name": "Database Name",
|
|
36
|
+
"Database suffix": "Database suffix",
|
|
37
|
+
"Delay conflict resolution of inactive files": "Delay conflict resolution of inactive files",
|
|
38
|
+
"Delay merge conflict prompt for inactive files.": "Delay merge conflict prompt for inactive files.",
|
|
39
|
+
"Delete old metadata of deleted files on start-up": "Delete old metadata of deleted files on start-up",
|
|
40
|
+
"Desktop only; uses more battery and network.": "Desktop only; uses more battery and network.",
|
|
41
|
+
"Device name": "Device name",
|
|
42
|
+
"Disables logging, only shows notifications. Please disable if you report an issue.": "Disables logging, only shows notifications. Please disable if you report an issue.",
|
|
43
|
+
"Display Language": "Display Language",
|
|
44
|
+
"Do not check configuration mismatch before replication": "Do not check configuration mismatch before replication",
|
|
45
|
+
"Do not keep metadata of deleted files.": "Do not keep metadata of deleted files.",
|
|
46
|
+
"Do not split chunks in the background": "Do not split chunks in the background",
|
|
47
|
+
"Do not use internal API": "Do not use internal API",
|
|
48
|
+
"Doctor.Button.DismissThisVersion": "No, and do not ask again until the next release",
|
|
49
|
+
"Doctor.Button.Fix": "Fix it",
|
|
50
|
+
"Doctor.Button.FixButNoRebuild": "Fix it but no rebuild",
|
|
51
|
+
"Doctor.Button.No": "No",
|
|
52
|
+
"Doctor.Button.Skip": "Leave it as is",
|
|
53
|
+
"Doctor.Button.Yes": "Yes",
|
|
54
|
+
"Doctor.Dialogue.Main": "Hi! Config Doctor has been activated because of ${activateReason}!\nAnd, unfortunately some configurations were detected as potential problems.\nPlease be assured. Let's solve them one by one.\n\nTo let you know ahead of time, we will ask you about the following items.\n\n${issues}\n\nShall we get started?",
|
|
55
|
+
"Doctor.Dialogue.MainFix": "\n## ${name}\n\n| Current | Ideal |\n|:---:|:---:|\n| ${current} | ${ideal} |\n\n**Recommendation Level:** ${level}\n\n### Why this has been detected?\n\n${reason}\n\n${note}\n\nFix this to the ideal value?",
|
|
56
|
+
"Doctor.Dialogue.Title": "Self-hosted LiveSync Config Doctor",
|
|
57
|
+
"Doctor.Dialogue.TitleAlmostDone": "Almost done!",
|
|
58
|
+
"Doctor.Dialogue.TitleFix": "Fix issue ${current}/${total}",
|
|
59
|
+
"Doctor.Level.Must": "Must",
|
|
60
|
+
"Doctor.Level.Necessary": "Necessary",
|
|
61
|
+
"Doctor.Level.Optional": "Optional",
|
|
62
|
+
"Doctor.Level.Recommended": "Recommended",
|
|
63
|
+
"Doctor.Message.NoIssues": "No issues detected!",
|
|
64
|
+
"Doctor.Message.RebuildLocalRequired": "Attention! A local database rebuild is required to apply this!",
|
|
65
|
+
"Doctor.Message.RebuildRequired": "Attention! A rebuild is required to apply this!",
|
|
66
|
+
"Doctor.Message.SomeSkipped": "We left some issues as is. Shall I ask you again on next startup?",
|
|
67
|
+
"Doctor.RULES.E2EE_V02500.REASON": "The End-to-End Encryption has got now more robust and faster. Also because, the previous E2EE was found to be compromised in a re-conducted code review. It should be applied as soon as possible. Really apologises for your inconvenience. And, this setting is not forward compatible. All synchronised devices must be updated to v0.25.0 or higher. Rebuilds are not required and will be converted from the new transfer to the new format, However, it is recommended to rebuild whenever possible.",
|
|
68
|
+
"Effectively a directory. Should end with `/`. e.g., `vault-name/`.": "Effectively a directory. Should end with `/`. e.g., `vault-name/`.",
|
|
69
|
+
"Enable Developers' Debug Tools (If available).": "Enable Developers' Debug Tools (If available).",
|
|
70
|
+
"Enable P2P Synchronization": "Enable P2P Synchronization",
|
|
71
|
+
"Enable advanced features": "Enable advanced features",
|
|
72
|
+
"Enable customization sync": "Enable customization sync",
|
|
73
|
+
"Enable edge case treatment features": "Enable edge case treatment features",
|
|
74
|
+
"Enable forcePathStyle": "Enable forcePathStyle",
|
|
75
|
+
"Enable per-file customization sync": "Enable per-file customization sync",
|
|
76
|
+
"Enable poweruser features": "Enable poweruser features",
|
|
77
|
+
"Enable this if your Object Storage doesn't support CORS": "Enable this if your Object Storage doesn't support CORS",
|
|
78
|
+
"Enable this option to automatically apply the most recent change to documents even when it conflicts": "Enable this option to automatically apply the most recent change to documents even when it conflicts",
|
|
79
|
+
"Encrypt contents on the remote database. If you use the plugin's synchronization feature, enabling this is recommended.": "Encrypt contents on the remote database. If you use the plugin's synchronization feature, enabling this is recommended.",
|
|
80
|
+
"Encrypting sensitive configuration items": "Encrypting sensitive configuration items",
|
|
81
|
+
"Encryption passphrase. If changed, you should overwrite the server's database with the new (encrypted) files.": "Encryption passphrase. If changed, you should overwrite the server's database with the new (encrypted) files.",
|
|
82
|
+
"End-to-End Encryption": "End-to-End Encryption",
|
|
83
|
+
"End-to-End Encryption Algorithm": "End-to-End Encryption Algorithm",
|
|
84
|
+
"Endpoint URL": "Endpoint URL",
|
|
85
|
+
"Enhance chunk size": "Enhance chunk size",
|
|
86
|
+
"Fetch chunks on demand": "Fetch chunks on demand",
|
|
87
|
+
"Fetch database with previous behaviour": "Fetch database with previous behaviour",
|
|
88
|
+
"File prefix on the bucket": "File prefix on the bucket",
|
|
89
|
+
Filename: "Filename",
|
|
90
|
+
"Files with modification times greater than this value (in seconds since the Unix epoch) will not have their events reflected. Set to 0 to disable this limit.": "Files with modification times greater than this value (in seconds since the Unix epoch) will not have their events reflected. Set to 0 to disable this limit.",
|
|
91
|
+
"Forces the file to be synced when opened.": "Forces the file to be synced when opened.",
|
|
92
|
+
"Handle files as Case-Sensitive": "Handle files as Case-Sensitive",
|
|
93
|
+
"How to display network errors when the sync server is unreachable.": "How to display network errors when the sync server is unreachable.",
|
|
94
|
+
"If disabled(toggled), chunks will be split on the UI thread (Previous behaviour).": "If disabled(toggled), chunks will be split on the UI thread (Previous behaviour).",
|
|
95
|
+
"If enabled per-filed efficient customization sync will be used. We need a small migration when enabling this. And all devices should be updated to v0.23.18. Once we enabled this, we lost a compatibility with old versions.": "If enabled per-filed efficient customization sync will be used. We need a small migration when enabling this. And all devices should be updated to v0.23.18. Once we enabled this, we lost a compatibility with old versions.",
|
|
96
|
+
"If enabled, changes will be automatically broadcasted to all connected peers. Notified peers will start fetching the changes.": "If enabled, changes will be automatically broadcasted to all connected peers. Notified peers will start fetching the changes.",
|
|
97
|
+
"If enabled, chunks will be split into no more than 100 items. However, dedupe is slightly weaker.": "If enabled, chunks will be split into no more than 100 items. However, dedupe is slightly weaker.",
|
|
98
|
+
"If enabled, efficient per-file customization sync will be used. A minor migration is required when enabling this feature, and all devices must be updated to v0.23.18. Enabling this feature will result in losing compatibility with older versions.": "If enabled, efficient per-file customization sync will be used. A minor migration is required when enabling this feature, and all devices must be updated to v0.23.18. Enabling this feature will result in losing compatibility with older versions.",
|
|
99
|
+
"If enabled, newly created chunks are temporarily kept within the document, and graduated to become independent chunks once stabilised.": "If enabled, newly created chunks are temporarily kept within the document, and graduated to become independent chunks once stabilised.",
|
|
100
|
+
"If enabled, the P2P connection will be automatically started when the application launches.": "If enabled, the P2P connection will be automatically started when the application launches.",
|
|
101
|
+
"If enabled, the file properties will be encrypted in the remote database. This is useful for protecting sensitive information in file paths, sizes, and IDs of its chunks. If you are using V1 E2EE, this only obfuscates the file path.": "If enabled, the file properties will be encrypted in the remote database. This is useful for protecting sensitive information in file paths, sizes, and IDs of its chunks. If you are using V1 E2EE, this only obfuscates the file path.",
|
|
102
|
+
"If enabled, the file under 1kb will be processed in the UI thread.": "If enabled, the file under 1kb will be processed in the UI thread.",
|
|
103
|
+
"If enabled, the forcePathStyle option will be used for bucket operations.": "If enabled, the forcePathStyle option will be used for bucket operations.",
|
|
104
|
+
"If enabled, the notification of hidden files change will be suppressed.": "If enabled, the notification of hidden files change will be suppressed.",
|
|
105
|
+
"If enabled, the plugin will not attempt to connect to the remote database even if the chunk was not found locally.": "If enabled, the plugin will not attempt to connect to the remote database even if the chunk was not found locally.",
|
|
106
|
+
"If enabled, the request API will be used to avoid `inevitable` CORS problems. This is a workaround and may not work in all cases. PLEASE READ THE DOCUMENTATION BEFORE USING THIS OPTION. This is a less-secure option.": "If enabled, the request API will be used to avoid `inevitable` CORS problems. This is a workaround and may not work in all cases. PLEASE READ THE DOCUMENTATION BEFORE USING THIS OPTION. This is a less-secure option.",
|
|
107
|
+
"If enabled, the \u26D4 icon will be shown inside the status instead of the file warnings banner. No details will be shown.": "If enabled, the \u26D4 icon will be shown inside the status instead of the file warnings banner. No details will be shown.",
|
|
108
|
+
"If this enabled, All files are handled as case-Sensitive (Previous behaviour).": "If this enabled, All files are handled as case-Sensitive (Previous behaviour).",
|
|
109
|
+
"If this enabled, JWT will be used for authentication.": "If this enabled, JWT will be used for authentication.",
|
|
110
|
+
"If this enabled, chunks will be split into semantically meaningful segments. Not all platforms support this feature.": "If this enabled, chunks will be split into semantically meaningful segments. Not all platforms support this feature.",
|
|
111
|
+
"If this is set, changes to local files which are matched by the ignore files will be skipped. Remote changes are determined using local ignore files.": "If this is set, changes to local files which are matched by the ignore files will be skipped. Remote changes are determined using local ignore files.",
|
|
112
|
+
"If this option is enabled, PouchDB will hold the connection open for 60 seconds, and if no change arrives in that time, close and reopen the socket, instead of holding it open indefinitely. Useful when a proxy limits request duration but can increase resource usage.": "If this option is enabled, PouchDB will hold the connection open for 60 seconds, and if no change arrives in that time, close and reopen the socket, instead of holding it open indefinitely. Useful when a proxy limits request duration but can increase resource usage.",
|
|
113
|
+
"Ignore files": "Ignore files",
|
|
114
|
+
"Incubate Chunks in Document": "Incubate Chunks in Document",
|
|
115
|
+
"Internal timestamp for resolving compatible tweak mismatches.": "Internal timestamp for resolving compatible tweak mismatches.",
|
|
116
|
+
"Interval (sec)": "Interval (sec)",
|
|
117
|
+
"JWT Algorithm": "JWT Algorithm",
|
|
118
|
+
"K.long_p2p_sync": "%{title_p2p_sync}",
|
|
119
|
+
"K.title_p2p_sync": "Peer-to-Peer Sync",
|
|
120
|
+
"Keep empty folder": "Keep empty folder",
|
|
121
|
+
"Keep replication active in the background": "Keep replication active in the background",
|
|
122
|
+
"Key ID": "Key ID",
|
|
123
|
+
"Keypair or pre-shared key": "Keypair or pre-shared key",
|
|
124
|
+
"Last tweak modified timestamp": "Last tweak modified timestamp",
|
|
125
|
+
"LiveSync could not handle multiple vaults which have same name without different prefix, This should be automatically configured.": "LiveSync could not handle multiple vaults which have same name without different prefix, This should be automatically configured.",
|
|
126
|
+
"Longest chunk line threshold value (Not Configurable from the UI Now).": "Longest chunk line threshold value (Not Configurable from the UI Now).",
|
|
127
|
+
"MB (0 to disable).": "MB (0 to disable).",
|
|
128
|
+
"MB per request": "MB per request",
|
|
129
|
+
"Maximum Incubating Chunk Size": "Maximum Incubating Chunk Size",
|
|
130
|
+
"Maximum Incubating Chunks": "Maximum Incubating Chunks",
|
|
131
|
+
"Maximum Incubation Period": "Maximum Incubation Period",
|
|
132
|
+
"Maximum delay for batch database updating": "Maximum delay for batch database updating",
|
|
133
|
+
"Maximum file modification time for reflected file events": "Maximum file modification time for reflected file events",
|
|
134
|
+
"Maximum file size": "Maximum file size",
|
|
135
|
+
"Maximum request size for manually resending chunks": "Maximum request size for manually resending chunks",
|
|
136
|
+
"Memory cache size (by total characters)": "Memory cache size (by total characters)",
|
|
137
|
+
"Memory cache size (by total items)": "Memory cache size (by total items)",
|
|
138
|
+
"Minimum Chunk Size (Not Configurable from the UI Now).": "Minimum Chunk Size (Not Configurable from the UI Now).",
|
|
139
|
+
"Minimum delay for batch database updating": "Minimum delay for batch database updating",
|
|
140
|
+
"Minimum interval for syncing": "Minimum interval for syncing",
|
|
141
|
+
"Move remotely deleted files to the trash, instead of deleting. (This setting is ineffective from Obsidian v1.7.2 onwards, as deletion always respects your Obsidian preferences.)": "Move remotely deleted files to the trash, instead of deleting. (This setting is ineffective from Obsidian v1.7.2 onwards, as deletion always respects your Obsidian preferences.)",
|
|
142
|
+
"Network warning style": "Network warning style",
|
|
143
|
+
'Not all messages have been translated. And, please revert to "Default" when reporting errors.': 'Not all messages have been translated. And, please revert to "Default" when reporting errors.',
|
|
144
|
+
"Notify all setting files": "Notify all setting files",
|
|
145
|
+
"Notify customized": "Notify customized",
|
|
146
|
+
"Notify when other device has newly customized.": "Notify when other device has newly customized.",
|
|
147
|
+
"Notify when the estimated remote storage size exceeds on start up": "Notify when the estimated remote storage size exceeds on start up",
|
|
148
|
+
"Now we can choose how to split the chunks; V3 is the most efficient. If you have troubled, please make this Default or Legacy.": "Now we can choose how to split the chunks; V3 is the most efficient. If you have troubled, please make this Default or Legacy.",
|
|
149
|
+
"Number of batches to process at a time. Defaults to 40. Minimum is 2. This along with batch size controls how many docs are kept in memory at a time.": "Number of batches to process at a time. Defaults to 40. Minimum is 2. This along with batch size controls how many docs are kept in memory at a time.",
|
|
150
|
+
"Number of changes to sync at a time. Defaults to 50. Minimum is 2.": "Number of changes to sync at a time. Defaults to 50. Minimum is 2.",
|
|
151
|
+
"P2P.AskPassphraseForDecrypt": "The remote peer shared the configuration. Please input the passphrase to decrypt the configuration.",
|
|
152
|
+
"P2P.AskPassphraseForShare": "The remote peer requested this device configuration. Please input the passphrase to share the configuration. You can ignore the request by cancelling this dialogue.",
|
|
153
|
+
"P2P.DisabledButNeed": "%{title_p2p_sync} is disabled. Do you really want to enable it?",
|
|
154
|
+
"P2P.NoAutoSyncPeers": "No auto-sync peers found. Please set peers on the %{long_p2p_sync} pane.",
|
|
155
|
+
"P2P.NoKnownPeers": "No peers has been detected, waiting incoming other peers...",
|
|
156
|
+
"P2P.NotEnabled": "%{title_p2p_sync} is not enabled. We cannot open a new connection.",
|
|
157
|
+
"P2P.ReplicatorInstanceMissing": "P2P Sync replicator is not found, possibly not have been configured or enabled.",
|
|
158
|
+
"P2P.SeemsOffline": "Peer ${name} seems offline, skipped.",
|
|
159
|
+
"P2P.SyncAlreadyRunning": "P2P Sync is already running.",
|
|
160
|
+
"P2P.SyncCompleted": "P2P Sync completed.",
|
|
161
|
+
"P2P.SyncStartedWith": "P2P Sync with ${name} have been started.",
|
|
162
|
+
Passphrase: "Passphrase",
|
|
163
|
+
"Passphrase of sensitive configuration items": "Passphrase of sensitive configuration items",
|
|
164
|
+
Password: "Password",
|
|
165
|
+
"Per-file-saved customization sync": "Per-file-saved customization sync",
|
|
166
|
+
"Periodic Sync interval": "Periodic Sync interval",
|
|
167
|
+
"Please select 'Cancel' explicitly to cancel this operation.": "Please select 'Cancel' explicitly to cancel this operation.",
|
|
168
|
+
"Please use V2, V1 is deprecated and will be removed in the future, It was not a very appropriate algorithm. Only for compatibility V1 is kept.": "Please use V2, V1 is deprecated and will be removed in the future, It was not a very appropriate algorithm. Only for compatibility V1 is kept.",
|
|
169
|
+
Presets: "Presets",
|
|
170
|
+
"Process files even if seems to be corrupted": "Process files even if seems to be corrupted",
|
|
171
|
+
"Process small files in the foreground": "Process small files in the foreground",
|
|
172
|
+
"Property Encryption": "Property Encryption",
|
|
173
|
+
"Reducing the frequency with which on-disk changes are reflected into the DB": "Reducing the frequency with which on-disk changes are reflected into the DB",
|
|
174
|
+
Region: "Region",
|
|
175
|
+
"Remote server type": "Remote server type",
|
|
176
|
+
"Replicator.Message.Cleaned": "Database cleaning up is in process. replication has been cancelled",
|
|
177
|
+
"Replicator.Message.InitialiseFatalError": "No replicator is available, this is the fatal error.",
|
|
178
|
+
"Replicator.Message.Pending": "Some file events are pending. Replication has been cancelled.",
|
|
179
|
+
"Replicator.Message.SomeModuleFailed": "Replication has been cancelled by some module failure",
|
|
180
|
+
"Replicator.Message.VersionUpFlash": "An update has been detected. Please open the Settings dialogue and check the Change Log. Replication has been cancelled.",
|
|
181
|
+
"Requires restart of Obsidian.": "Requires restart of Obsidian.",
|
|
182
|
+
"Room ID": "Room ID",
|
|
183
|
+
"Rotation Duration": "Rotation Duration",
|
|
184
|
+
"Save settings to a markdown file. You will be notified when new settings arrive. You can set different files by the platform.": "Save settings to a markdown file. You will be notified when new settings arrive. You can set different files by the platform.",
|
|
185
|
+
"Saving will be performed forcefully after this number of seconds.": "Saving will be performed forcefully after this number of seconds.",
|
|
186
|
+
"Scan changes on customization sync": "Scan changes on customization sync",
|
|
187
|
+
"Scan customization automatically": "Scan customization automatically",
|
|
188
|
+
"Scan customization before replicating.": "Scan customization before replicating.",
|
|
189
|
+
"Scan customization every 1 minute.": "Scan customization every 1 minute.",
|
|
190
|
+
"Scan customization periodically": "Scan customization periodically",
|
|
191
|
+
"Scan for hidden files before replication": "Scan for hidden files before replication",
|
|
192
|
+
"Scan hidden files periodically": "Scan hidden files periodically",
|
|
193
|
+
"Seconds, 0 to disable": "Seconds, 0 to disable",
|
|
194
|
+
"Seconds. Saving to the local database will be delayed until this value after we stop typing or saving.": "Seconds. Saving to the local database will be delayed until this value after we stop typing or saving.",
|
|
195
|
+
"Secret Key": "Secret Key",
|
|
196
|
+
"Server URI": "Server URI",
|
|
197
|
+
"Setup.QRCode": 'We have generated a QR code to transfer the settings. Please scan the QR code with your phone or other device.\nNote: The QR code is not encrypted, so be careful to open this.\n\n>[!FOR YOUR EYES ONLY]-\n> <div class="sls-qr">${qr_image}</div>',
|
|
198
|
+
"Should we keep folders that don't have any files inside?": "Should we keep folders that don't have any files inside?",
|
|
199
|
+
"Should we only check for conflicts when a file is opened?": "Should we only check for conflicts when a file is opened?",
|
|
200
|
+
"Should we prompt you about conflicting files when a file is opened?": "Should we prompt you about conflicting files when a file is opened?",
|
|
201
|
+
"Should we prompt you for every single merge, even if we can safely merge automatcially?": "Should we prompt you for every single merge, even if we can safely merge automatcially?",
|
|
202
|
+
"Show only notifications": "Show only notifications",
|
|
203
|
+
"Show status as icons only": "Show status as icons only",
|
|
204
|
+
"Show status icon instead of file warnings banner": "Show status icon instead of file warnings banner",
|
|
205
|
+
"Show status inside the editor": "Show status inside the editor",
|
|
206
|
+
"Show status on the status bar": "Show status on the status bar",
|
|
207
|
+
"Show verbose log. Please enable if you report an issue.": "Show verbose log. Please enable if you report an issue.",
|
|
208
|
+
"Signalling Relays": "Signalling Relays",
|
|
209
|
+
"Starts synchronisation when a file is saved.": "Starts synchronisation when a file is saved.",
|
|
210
|
+
"Stop reflecting database changes to storage files.": "Stop reflecting database changes to storage files.",
|
|
211
|
+
"Stop watching for file changes.": "Stop watching for file changes.",
|
|
212
|
+
"Subject (whoami)": "Subject (whoami)",
|
|
213
|
+
"Suppress notification of hidden files change": "Suppress notification of hidden files change",
|
|
214
|
+
"Suspend database reflecting": "Suspend database reflecting",
|
|
215
|
+
"Suspend file watching": "Suspend file watching",
|
|
216
|
+
"Sync Mode": "Sync Mode",
|
|
217
|
+
"Sync after merging file": "Sync after merging file",
|
|
218
|
+
"Sync automatically after merging files": "Sync automatically after merging files",
|
|
219
|
+
"Sync on Editor Save": "Sync on Editor Save",
|
|
220
|
+
"Sync on File Open": "Sync on File Open",
|
|
221
|
+
"Sync on Save": "Sync on Save",
|
|
222
|
+
"Sync on Startup": "Sync on Startup",
|
|
223
|
+
"TURN Credential": "TURN Credential",
|
|
224
|
+
"TURN Servers": "TURN Servers",
|
|
225
|
+
"TURN Username": "TURN Username",
|
|
226
|
+
"Testing only - Resolve file conflicts by syncing newer copies of the file, this can overwrite modified files. Be Warned.": "Testing only - Resolve file conflicts by syncing newer copies of the file, this can overwrite modified files. Be Warned.",
|
|
227
|
+
"The Application ID for P2P connection. This should be same among your devices. Default is 'self-hosted-livesync' and could not be modified from the UI.": "The Application ID for P2P connection. This should be same among your devices. Default is 'self-hosted-livesync' and could not be modified from the UI.",
|
|
228
|
+
"The Hash algorithm for chunk IDs": "The Hash algorithm for chunk IDs",
|
|
229
|
+
"The Nostr relay servers to establish connections for P2P connections. Multiple servers can be separated by commas.": "The Nostr relay servers to establish connections for P2P connections. Multiple servers can be separated by commas.",
|
|
230
|
+
"The Passphrase for P2P connection. This should be same among your devices.": "The Passphrase for P2P connection. This should be same among your devices.",
|
|
231
|
+
"The Room ID for P2P connection. This should be same among your devices.": "The Room ID for P2P connection. This should be same among your devices.",
|
|
232
|
+
"The Rotation duration of token in minutes. Each generated tokens will be valid only within this duration.": "The Rotation duration of token in minutes. Each generated tokens will be valid only within this duration.",
|
|
233
|
+
"The TURN servers to use for P2P connections. Multiple servers can be separated by commas.": "The TURN servers to use for P2P connections. Multiple servers can be separated by commas.",
|
|
234
|
+
"The algorithm used for JWT authentication.": "The algorithm used for JWT authentication.",
|
|
235
|
+
"The credential/password for the TURN servers.": "The credential/password for the TURN servers.",
|
|
236
|
+
"The delay for consecutive on-demand fetches": "The delay for consecutive on-demand fetches",
|
|
237
|
+
"The key (PSK in HSxxx in base64, or private key in ESxxx in PEM) used for JWT authentication.": "The key (PSK in HSxxx in base64, or private key in ESxxx in PEM) used for JWT authentication.",
|
|
238
|
+
"The key ID. this should be matched with CouchDB->jwt_keys->ALG:_`kid`.": "The key ID. this should be matched with CouchDB->jwt_keys->ALG:_`kid`.",
|
|
239
|
+
"The maximum duration for which chunks can be incubated within the document. Chunks exceeding this period will graduate to independent chunks.": "The maximum duration for which chunks can be incubated within the document. Chunks exceeding this period will graduate to independent chunks.",
|
|
240
|
+
"The maximum number of chunks that can be incubated within the document. Chunks exceeding this number will immediately graduate to independent chunks.": "The maximum number of chunks that can be incubated within the document. Chunks exceeding this number will immediately graduate to independent chunks.",
|
|
241
|
+
"The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.": "The maximum total size of chunks that can be incubated within the document. Chunks exceeding this size will immediately graduate to independent chunks.",
|
|
242
|
+
"The minimum interval for automatic synchronisation on event.": "The minimum interval for automatic synchronisation on event.",
|
|
243
|
+
"The subject for JWT authentication. Mostly username.": "The subject for JWT authentication. Mostly username.",
|
|
244
|
+
"The username for the TURN servers.": "The username for the TURN servers.",
|
|
245
|
+
"This passphrase will not be copied to another device. It will be set to `Default` until you configure it again.": "This passphrase will not be copied to another device. It will be set to `Default` until you configure it again.",
|
|
246
|
+
"Unique name between all synchronized devices. To edit this setting, please disable customization sync once.": "Unique name between all synchronized devices. To edit this setting, please disable customization sync once.",
|
|
247
|
+
"Use Custom HTTP Handler": "Use Custom HTTP Handler",
|
|
248
|
+
"Use JWT instead of Basic Authentication": "Use JWT instead of Basic Authentication",
|
|
249
|
+
"Use Only Local Chunks": "Use Only Local Chunks",
|
|
250
|
+
"Use Request API to avoid `inevitable` CORS problem": "Use Request API to avoid `inevitable` CORS problem",
|
|
251
|
+
"Use Segmented-splitter": "Use Segmented-splitter",
|
|
252
|
+
"Use dynamic iteration count": "Use dynamic iteration count",
|
|
253
|
+
"Use splitting-limit-capped chunk splitter": "Use splitting-limit-capped chunk splitter",
|
|
254
|
+
"Use the trash bin": "Use the trash bin",
|
|
255
|
+
"Use timeouts instead of heartbeats": "Use timeouts instead of heartbeats",
|
|
256
|
+
Username: "Username",
|
|
257
|
+
"Verbose Log": "Verbose Log",
|
|
258
|
+
"Warning! This will have a serious impact on performance. And the logs will not be synchronised under the default name. Please be careful with logs; they often contain your confidential information.": "Warning! This will have a serious impact on performance. And the logs will not be synchronised under the default name. Please be careful with logs; they often contain your confidential information.",
|
|
259
|
+
"When you save a file in the editor, start a sync automatically": "When you save a file in the editor, start a sync automatically",
|
|
260
|
+
"While enabled, it causes very performance impact but debugging replication testing and other features will be enabled. Please disable this if you have not read the source code. Requires restart of Obsidian. Sometimes there is no implementation.": "While enabled, it causes very performance impact but debugging replication testing and other features will be enabled. Please disable this if you have not read the source code. Requires restart of Obsidian. Sometimes there is no implementation.",
|
|
261
|
+
"Write credentials in the file": "Write credentials in the file",
|
|
262
|
+
"Write logs into the file": "Write logs into the file",
|
|
263
|
+
"You can enable this setting to process the files with size mismatches, these files can be created by some APIs or integrations.": "You can enable this setting to process the files with size mismatches, these files can be created by some APIs or integrations.",
|
|
264
|
+
"liveSyncReplicator.beforeLiveSync": "Before LiveSync, start OneShot once...",
|
|
265
|
+
"liveSyncReplicator.cantReplicateLowerValue": "We can't replicate more lower value.",
|
|
266
|
+
"liveSyncReplicator.checkingLastSyncPoint": "Looking for the point last synchronized point.",
|
|
267
|
+
"liveSyncReplicator.couldNotConnectTo": "Could not connect to ${uri} : ${name}\n(${db})",
|
|
268
|
+
"liveSyncReplicator.couldNotConnectToRemoteDb": "Could not connect to remote database: ${d}",
|
|
269
|
+
"liveSyncReplicator.couldNotConnectToServer": "The connection to the remote has been prevented, or failed.",
|
|
270
|
+
"liveSyncReplicator.couldNotConnectToURI": "Could not connect to ${uri}:${dbRet}",
|
|
271
|
+
"liveSyncReplicator.couldNotMarkResolveRemoteDb": "Could not mark resolve remote database.",
|
|
272
|
+
"liveSyncReplicator.liveSyncBegin": "LiveSync begin...",
|
|
273
|
+
"liveSyncReplicator.lockRemoteDb": "Lock remote database to prevent data corruption",
|
|
274
|
+
"liveSyncReplicator.markDeviceResolved": "Mark this device as 'resolved'.",
|
|
275
|
+
"liveSyncReplicator.mismatchedTweakDetected": "Some mismatches have been detected in the configuration between devices. Running a manual replication will attempt to resolve this issue.",
|
|
276
|
+
"liveSyncReplicator.oneShotSyncBegin": "OneShot Sync begin... (${syncMode})",
|
|
277
|
+
"liveSyncReplicator.remoteDbCorrupted": "Remote database is newer or corrupted, make sure to latest version of self-hosted-livesync installed",
|
|
278
|
+
"liveSyncReplicator.remoteDbCreatedOrConnected": "Remote Database Created or Connected",
|
|
279
|
+
"liveSyncReplicator.remoteDbDestroyError": "Something happened on Remote Database Destroy:",
|
|
280
|
+
"liveSyncReplicator.remoteDbDestroyed": "Remote Database Destroyed",
|
|
281
|
+
"liveSyncReplicator.remoteDbMarkedResolved": "Remote database has been marked resolved.",
|
|
282
|
+
"liveSyncReplicator.replicationClosed": "Replication closed",
|
|
283
|
+
"liveSyncReplicator.replicationInProgress": "Replication is already in progress",
|
|
284
|
+
"liveSyncReplicator.retryLowerBatchSize": "Retry with lower batch size:${batch_size}/${batches_limit}",
|
|
285
|
+
"liveSyncReplicator.unlockRemoteDb": "Unlock remote database to prevent data corruption",
|
|
286
|
+
"moduleCheckRemoteSize.logCheckingStorageSizes": "Checking storage sizes",
|
|
287
|
+
"moduleCheckRemoteSize.logCurrentStorageSize": "Remote storage size: ${measuredSize}",
|
|
288
|
+
"moduleCheckRemoteSize.logExceededWarning": "Remote storage size: ${measuredSize} exceeded ${notifySize}",
|
|
289
|
+
"moduleCheckRemoteSize.logThresholdEnlarged": "Threshold has been enlarged to ${size}MB",
|
|
290
|
+
"moduleCheckRemoteSize.msgConfirmRebuild": "This may take a bit of a long time. Do you really want to rebuild everything now?",
|
|
291
|
+
"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",
|
|
292
|
+
"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",
|
|
293
|
+
"moduleCheckRemoteSize.noticeExceeded": "Remote storage size is ${measuredSize}, above the configured ${notifySize} notification threshold. {HERE}",
|
|
294
|
+
"moduleCheckRemoteSize.noticeNotConfigured": "Remote storage size notifications are not configured. {HERE}",
|
|
295
|
+
"moduleCheckRemoteSize.option2GB": "2GB (Standard)",
|
|
296
|
+
"moduleCheckRemoteSize.option800MB": "800MB (Cloudant, fly.io)",
|
|
297
|
+
"moduleCheckRemoteSize.optionAskMeLater": "Ask me later",
|
|
298
|
+
"moduleCheckRemoteSize.optionDismiss": "Dismiss",
|
|
299
|
+
"moduleCheckRemoteSize.optionIncreaseLimit": "increase to ${newMax}MB",
|
|
300
|
+
"moduleCheckRemoteSize.optionNoWarn": "No, never warn please",
|
|
301
|
+
"moduleCheckRemoteSize.optionRebuildAll": "Rebuild Everything Now",
|
|
302
|
+
"moduleCheckRemoteSize.optionReview": "Review options",
|
|
303
|
+
"moduleCheckRemoteSize.titleDatabaseSizeLimitExceeded": "Remote storage size exceeded the limit",
|
|
304
|
+
"moduleCheckRemoteSize.titleDatabaseSizeNotify": "Setting up database size notification",
|
|
305
|
+
"moduleLiveSyncMain.logUnloadingPlugin": "Unloading plugin...",
|
|
306
|
+
"moduleLocalDatabase.logWaitingForReady": "Waiting for ready...",
|
|
307
|
+
password: "password",
|
|
308
|
+
username: "username",
|
|
309
|
+
"xxhash64 is the current default.": "xxhash64 is the current default."
|
|
310
|
+
};
|
|
311
|
+
export {
|
|
312
|
+
commonlibEnglishMessages
|
|
313
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { type CommonlibMessageKey } from "./CommonlibMessages.js";
|
|
1
2
|
/** Placeholder values substituted by a host translator. */
|
|
2
3
|
export type TranslationParameters = Readonly<Record<string, string>>;
|
|
3
4
|
/** A message translator supplied by the host for one service context. */
|
|
4
|
-
export type MessageTranslator
|
|
5
|
-
/** Default translator
|
|
5
|
+
export type MessageTranslator<TKey extends string = CommonlibMessageKey> = (key: TKey, params?: TranslationParameters) => string;
|
|
6
|
+
/** Default translator which renders Commonlib's canonical English messages. */
|
|
7
|
+
export declare const englishMessageTranslator: MessageTranslator;
|
|
8
|
+
/** Compatibility translator for hosts which intentionally render raw message keys. */
|
|
6
9
|
export declare const passthroughMessageTranslator: MessageTranslator;
|
|
@@ -1,4 +1,25 @@
|
|
|
1
|
+
import { commonlibEnglishMessages } from "./CommonlibMessages.js";
|
|
2
|
+
function resolveEnglishMessage(key, seen = /* @__PURE__ */ new Set()) {
|
|
3
|
+
if (seen.has(key)) return key;
|
|
4
|
+
seen.add(key);
|
|
5
|
+
const message = commonlibEnglishMessages[key] ?? key;
|
|
6
|
+
return message.replace(/%\{([^}]+)\}/g, (_token, referencedKey) => {
|
|
7
|
+
const directKey = referencedKey;
|
|
8
|
+
const keywordKey = `K.${referencedKey}`;
|
|
9
|
+
if (directKey in commonlibEnglishMessages) return resolveEnglishMessage(directKey, new Set(seen));
|
|
10
|
+
if (keywordKey in commonlibEnglishMessages) return resolveEnglishMessage(keywordKey, new Set(seen));
|
|
11
|
+
return `%{${referencedKey}}`;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const englishMessageTranslator = (key, params = {}) => {
|
|
15
|
+
let message = resolveEnglishMessage(key);
|
|
16
|
+
for (const [placeholder, value] of Object.entries(params)) {
|
|
17
|
+
message = message.replaceAll(`\${${placeholder}}`, value);
|
|
18
|
+
}
|
|
19
|
+
return message;
|
|
20
|
+
};
|
|
1
21
|
const passthroughMessageTranslator = (key) => key;
|
|
2
22
|
export {
|
|
23
|
+
englishMessageTranslator,
|
|
3
24
|
passthroughMessageTranslator
|
|
4
25
|
};
|
|
@@ -4,7 +4,7 @@ import { type MessageTranslator } from "./MessageTranslator.js";
|
|
|
4
4
|
export interface ServiceContextOptions {
|
|
5
5
|
/** An isolated event channel. A new channel is created when omitted. */
|
|
6
6
|
events?: LiveSyncEventHub;
|
|
7
|
-
/**
|
|
7
|
+
/** Optional host-provided translation. Canonical English is used when omitted. */
|
|
8
8
|
translate?: MessageTranslator;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { createLiveSyncEventHub } from "../../hub/hub.js";
|
|
2
|
-
import {
|
|
3
|
-
passthroughMessageTranslator
|
|
4
|
-
} from "./MessageTranslator.js";
|
|
2
|
+
import { englishMessageTranslator } from "./MessageTranslator.js";
|
|
5
3
|
class ServiceContext {
|
|
6
4
|
events;
|
|
7
5
|
translate;
|
|
8
6
|
constructor(options = {}) {
|
|
9
7
|
this.events = options.events ?? createLiveSyncEventHub();
|
|
10
|
-
this.translate = options.translate ??
|
|
8
|
+
this.translate = options.translate ?? englishMessageTranslator;
|
|
11
9
|
}
|
|
12
10
|
}
|
|
13
11
|
function createServiceContext(options = {}) {
|
|
@@ -4,10 +4,13 @@ import { ServiceBase, type ServiceContext } from "./ServiceBase.js";
|
|
|
4
4
|
import { createInstanceLogFunction } from "../lib/logUtils.js";
|
|
5
5
|
export interface SettingServiceDependencies {
|
|
6
6
|
APIService: IAPIService;
|
|
7
|
+
/** Optional host hook for applying the loaded display language to its catalogue. */
|
|
8
|
+
onDisplayLanguageChanged?: (language: ObsidianLiveSyncSettings["displayLanguage"]) => void;
|
|
7
9
|
}
|
|
8
10
|
export declare abstract class SettingService<T extends ServiceContext = ServiceContext> extends ServiceBase<T> implements ISettingService {
|
|
9
11
|
deviceAndVaultName: string;
|
|
10
12
|
protected APIService: IAPIService;
|
|
13
|
+
private readonly onDisplayLanguageChanged?;
|
|
11
14
|
protected abstract setItem(key: string, value: string): void;
|
|
12
15
|
protected abstract getItem(key: string): string;
|
|
13
16
|
protected abstract deleteItem(key: string): void;
|
|
@@ -12,7 +12,6 @@ import { ServiceBase } from "./ServiceBase.js";
|
|
|
12
12
|
import { createInstanceLogFunction } from "../lib/logUtils.js";
|
|
13
13
|
import { isCloudantURI } from "../../pouchdb/utils_couchdb.js";
|
|
14
14
|
import { decryptString, encryptString } from "../../encryption/stringEncryption.js";
|
|
15
|
-
import { setLang } from "../../common/i18n.js";
|
|
16
15
|
import {
|
|
17
16
|
activateP2PRemoteConfiguration,
|
|
18
17
|
activateRemoteConfiguration,
|
|
@@ -23,6 +22,7 @@ import { ConnectionStringParser } from "../../common/ConnectionString.js";
|
|
|
23
22
|
class SettingService extends ServiceBase {
|
|
24
23
|
deviceAndVaultName = "";
|
|
25
24
|
APIService;
|
|
25
|
+
onDisplayLanguageChanged;
|
|
26
26
|
_settings;
|
|
27
27
|
get settings() {
|
|
28
28
|
return this._settings;
|
|
@@ -39,6 +39,7 @@ class SettingService extends ServiceBase {
|
|
|
39
39
|
constructor(context, dependencies) {
|
|
40
40
|
super(context);
|
|
41
41
|
this.APIService = dependencies.APIService;
|
|
42
|
+
this.onDisplayLanguageChanged = dependencies.onDisplayLanguageChanged;
|
|
42
43
|
this._log = createInstanceLogFunction("SettingService", this.APIService);
|
|
43
44
|
}
|
|
44
45
|
/**
|
|
@@ -475,7 +476,7 @@ class SettingService extends ServiceBase {
|
|
|
475
476
|
}
|
|
476
477
|
}
|
|
477
478
|
this.settings = await this.decryptSettings(settings);
|
|
478
|
-
|
|
479
|
+
this.onDisplayLanguageChanged?.(this.settings.displayLanguage);
|
|
479
480
|
await this.adjustSettings(this.settings);
|
|
480
481
|
const migratedLegacyRemoteConfigurations = !hadRemoteConfigurations && Object.keys(this.settings.remoteConfigurations ?? {}).length > 0;
|
|
481
482
|
const migratedP2PActiveRemoteConfiguration = migratedLegacyRemoteConfigurations && migrateP2PActiveRemoteConfigurationIdInPlace(this.settings);
|
package/docs/development.md
CHANGED
|
@@ -6,9 +6,11 @@ This document is for Commonlib developers. Package consumers should begin with t
|
|
|
6
6
|
|
|
7
7
|
The source tree is larger than the supported package surface. Consumers may import only paths in the generated package export map:
|
|
8
8
|
|
|
9
|
-
- `src/index.ts`, `src/context.ts`, `src/settings.ts`, `src/remoteConfigurations.ts`, `src/platform/browser/index.ts`, `src/platform/node/index.ts
|
|
9
|
+
- `src/index.ts`, `src/context.ts`, `src/settings.ts`, `src/remoteConfigurations.ts`, `src/platform/browser/index.ts`, and `src/platform/node/index.ts` define the focused entries;
|
|
10
|
+
- `src/rpc/index.ts` defines a transitional entry for the existing LiveSync P2P composition, not a stable Commonlib 1.0 contract;
|
|
10
11
|
- `_tools/build-package.mjs` compiles those entries and creates the publishable manifest under `.package`;
|
|
11
12
|
- `docs/migration/downstream-imports.json` is the reviewed inventory from which explicit `compat/*` exports are generated;
|
|
13
|
+
- `docs/migration/compatibility-classification.json` assigns every inventoried compatibility path to one reviewed owner and migration policy, with a boundary test preventing omissions and duplicate classifications;
|
|
12
14
|
- colocated `*.unit.spec.ts` and `*.unit.test.ts` files exercise implementation and result contracts; and
|
|
13
15
|
- colocated `*.integration.spec.ts` files, `test/integration`, and the integration runner own checks against disposable CouchDB and S3-compatible services.
|
|
14
16
|
|
|
@@ -57,7 +59,7 @@ The multiple-remote profile contract has focused unit coverage in `src/serviceFe
|
|
|
57
59
|
|
|
58
60
|
### P2P composition ownership
|
|
59
61
|
|
|
60
|
-
`useP2PReplicatorFeature` is the sole owner of the active `LiveSyncTrysteroReplicator` and its lifecycle bindings. It creates or replaces the outer replicator when `ReplicatorService` requests one, closes the previous instance before replacement, and returns a stable result object whose `replicator` property resolves the current instance.
|
|
62
|
+
`useP2PReplicatorFeature` is the sole owner of the active `LiveSyncTrysteroReplicator` and its lifecycle bindings. It creates or replaces the outer replicator when `ReplicatorService` requests one, closes the previous instance before replacement, shares an in-flight replacement between concurrent callers, and returns a stable result object whose `replicator` property resolves the current instance.
|
|
61
63
|
|
|
62
64
|
Consumers must preserve that result object and read `result.replicator` at the point of use. Do not destructure the property into a command, event handler, view, or other long-lived closure: a database reinitialisation or remote-type transition can close and replace the captured instance, and calling `open()` on that obsolete outer object can create a second connection outside the active service state.
|
|
63
65
|
|
|
@@ -73,7 +75,11 @@ The physical room, WebRTC peer, and relay-socket boundaries are documented in [P
|
|
|
73
75
|
|
|
74
76
|
Self-hosted LiveSync remains the principal downstream consumer. A Commonlib change is not ready for publication until the exact packed artefact has also passed the applicable LiveSync type checks, unit and integration tests, application builds, CLI E2E, and focused real-Obsidian E2E.
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
Commonlib owner tests exercise the real implementation behind each focused result and lifecycle contract. A consumer-owned unit test may inject the smallest structural capability it uses and provide its own fake or spy when that current test needs isolation. Do not publish Vitest-specific mocks, expose private service constructors, or refactor a production boundary merely to create possible future test infrastructure. Mock and spy helpers are not a prerequisite for the LiveSync 1.0 package-boundary work; add them only with the consumer test which requires them, or after that release work.
|
|
79
|
+
|
|
80
|
+
Prefer an object or callback injected at the host composition boundary over replacing an ESM module namespace. If a proposed focused API would require global mutation, import-order coupling, hidden construction, or private nominal types to substitute later, stop and review the production design before stabilising it. Exact-package downstream checks and focused real-runtime E2E remain responsible for proving the real package and host composition together.
|
|
81
|
+
|
|
82
|
+
Commonlib publishes the typed English messages which it owns and uses them when a host does not provide a translator. A host may inject a translator through `ServiceContext`; the full multilingual catalogue and language-selection state belong to that host and are not part of the Commonlib package.
|
|
77
83
|
|
|
78
84
|
Keep [the maintained-host evidence](proven-in-use.md) aligned with the downstream source and gates. If a host no longer consumes a focused entry, a test is retired, or a compatibility path receives a reviewed replacement, update the consumer-facing account as part of the same maintenance rather than leaving historical adoption as a current support claim.
|
|
79
85
|
|
|
@@ -89,15 +95,11 @@ This command requires Docker Compose, creates only test credentials and data, an
|
|
|
89
95
|
|
|
90
96
|
To test services that are already running, use `npm run test:integration`. The runner accepts `hostname`, `username`, and `password` for CouchDB, and `minioEndpoint`, `accessKey`, `secretKey`, and `bucketName` for S3-compatible storage. Without overrides, it uses the endpoints and test credentials from the managed Compose environment. The selected MinIO bucket must already exist when services are not managed by the runner.
|
|
91
97
|
|
|
92
|
-
##
|
|
93
|
-
|
|
94
|
-
Human-edited translations live under `src/common/messagesYAML`. Regenerate derived JSON and TypeScript resources with:
|
|
98
|
+
## Messages and translation
|
|
95
99
|
|
|
96
|
-
|
|
97
|
-
npm run i18n:bake
|
|
98
|
-
```
|
|
100
|
+
`src/services/base/CommonlibMessages.ts` is the canonical English definition and key type for messages requested by Commonlib. Keep a meaningful English value for every symbolic key. Hosts may translate that typed key set, but translation is optional and omission must remain safe for users.
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
Application language catalogues and their generation tools belong to the application repository. Do not add a process-global language selection or a complete application catalogue to Commonlib.
|
|
101
103
|
|
|
102
104
|
## Public API documentation
|
|
103
105
|
|
|
@@ -105,18 +107,29 @@ New reviewed public entry points require TSDoc describing ownership, lifecycle,
|
|
|
105
107
|
|
|
106
108
|
Generated API reference is deferred until the compatibility export surface has been narrowed. Generating documentation for every current `compat/*` path would make migration-only implementation paths look like stable public API.
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
The proposed generated-reference allow-list is deliberately entry-based:
|
|
111
|
+
|
|
112
|
+
- include `/context`, `/browser`, `/node`, `/remote-configurations`, and `/settings`;
|
|
113
|
+
- exclude the root entry until `createLiveSyncFileClient` replaces `DirectFileManipulator` after the LiveSync 1.0 work;
|
|
114
|
+
- leave possible `/setup-uri` and `/database-version` entries for later review rather than creating them to clean up imports before LiveSync 1.0; and
|
|
115
|
+
- exclude `/rpc`, every `compat/*` path, and the metadata-only `package.json` export.
|
|
116
|
+
|
|
117
|
+
Generate reference only for this reviewed current allow-list. Future entries require their own accepted result and lifecycle contracts before joining it.
|
|
109
118
|
|
|
110
119
|
## Open 1.0 documentation decisions
|
|
111
120
|
|
|
112
121
|
Resolve these questions before describing the corresponding behaviour as stable:
|
|
113
122
|
|
|
114
|
-
- define the high-level client façade and the readiness, enumeration, watch, failure, conflict, concurrency, and disposal semantics currently left open by `DirectFileManipulator`;
|
|
115
|
-
- classify the selected Node built-in convenience exports as either supported platform contracts or migration-only compatibility exports;
|
|
116
|
-
- decide whether the RPC entry and its draft wire protocol belong to the Commonlib 1.0 contract, remain experimental, or move to a separately versioned package;
|
|
117
123
|
- classify compatibility paths whose owner or migration destination is still unclear, and remove obsolete paths rather than preserving the source layout; and
|
|
118
124
|
- introduce generated API reference only for the reviewed public allow-list, with TSDoc coverage for ownership, lifecycle, errors, platform constraints, and disposal.
|
|
119
125
|
|
|
126
|
+
The platform and RPC ownership decisions are accepted:
|
|
127
|
+
|
|
128
|
+
- `/node` and `/browser` are supported platform façades. They deliberately hide platform-specific imports, adapters, and review exceptions behind package-owned boundaries. The selected Node built-in re-exports are part of that boundary; package tests must continue to prove that browser-capable entries do not reach Node-only code.
|
|
129
|
+
- `/rpc` is transitional and is not part of the stable Commonlib 1.0 contract. Keep it only while the maintained LiveSync P2P composition requires the existing implementation. The RPC core, transport integration, wire protocol, and PouchDB bridge are planned for an independently owned rewrite in Fancy Kit; do not encourage new Commonlib consumers to adopt the current entry.
|
|
130
|
+
- The high-level composition target is a narrow asynchronous `createLiveSyncFileClient` factory, not a general Service Hub factory. It must keep the context, service graph, database implementation, protocol setup, watches, reconnect work, and shutdown order private. It resolves only after readiness and returns a small file façade with `list`, `get`, `put`, `delete`, `watch`, and `close`. Full Obsidian, CLI, and browser applications retain host-specific composition because they own UI, persistence, permissions, storage events, and process policy.
|
|
131
|
+
- `DirectFileManipulator` is a migration source for that file client rather than the stable target contract. Do not carry its fire-and-forget constructor initialisation, exposed service graph and database documents, incomplete enumeration, implicit watch retry, or deprecated settings options into the new public API. Define the exact result, conflict, concurrency, watch checkpoint, retry, and error semantics only after the LiveSync 1.0 work rather than making that future client a release gate.
|
|
132
|
+
|
|
120
133
|
## Compatibility exports
|
|
121
134
|
|
|
122
135
|
The package build records each compatibility path explicitly. Do not add a wildcard export. A new compatibility path requires a real downstream import, a packed-consumer or downstream test, and a migration plan towards a focused public entry or the owning package.
|
|
@@ -129,6 +142,6 @@ npm run update:downstream-import-inventory -- --downstream /path/to/obsidian-liv
|
|
|
129
142
|
|
|
130
143
|
The command recognises both the former `@lib/*` source aliases and current `@vrtmrz/livesync-commonlib/compat/*` package imports. It ignores focused package entries. Review the resulting paths and recorded downstream commit before accepting them. Regenerate the export map only for a new package version: do not change the contents represented by an immutable published version.
|
|
131
144
|
|
|
132
|
-
|
|
145
|
+
The classification in `docs/migration/compatibility-classification.json` is accepted for LiveSync 1.0 planning. A destination still requires its own result and lifecycle contract before it becomes a stable public entry. Remove obsolete paths rather than documenting accidental layout as API.
|
|
133
146
|
|
|
134
147
|
Release preparation and staged-publication checks are documented in [the maintainer runbook](releasing.md).
|
|
@@ -31,10 +31,18 @@ It is therefore a logical LiveSync disconnection and a physical signalling-serve
|
|
|
31
31
|
|
|
32
32
|
## Reconnection and replacement
|
|
33
33
|
|
|
34
|
-
An explicit open resumes Trystero relay reconnection before joining the configured room. Settings application may change the relay URLs, room ID, passphrase, or TURN configuration, so the owning service closes and discards the former LiveSync instance before constructing the replacement. No fixed close-to-open delay is required: lifecycle operations are serialised, and peer readiness is observed through discovery.
|
|
34
|
+
An explicit open resumes Trystero relay reconnection before joining the configured room. Settings application may change the relay URLs, room ID, passphrase, or TURN configuration, so the owning service closes and discards the former LiveSync instance before constructing the replacement. Concurrent replacement requests share the same in-flight replacement and receive the same new owner. No fixed close-to-open delay is required: lifecycle operations are serialised, and peer readiness is observed through discovery.
|
|
35
|
+
|
|
36
|
+
Saving settings with P2P or automatic start disabled always requests `close()`, even when the room has not started serving. This cancels an in-flight open through the same lifecycle queue, so a connection cannot appear after the disabling setting has been applied.
|
|
35
37
|
|
|
36
38
|
Do not replace a relay socket's `onclose` handler. Trystero 0.25 shares relay clients by URL and uses its own handler to retire and recreate them. Use the exported pause and resume functions around explicit disconnection instead.
|
|
37
39
|
|
|
40
|
+
## First-device and additional-device setup
|
|
41
|
+
|
|
42
|
+
P2P has no central remote database. A first-device rebuild initialises the local database, then returns without attempting to lock, reset, or seed a remote database.
|
|
43
|
+
|
|
44
|
+
An additional-device Fetch uses one explicit peer-selection pass. The selected peer supplies the complete finite replication from the beginning, after which the rebuild service resumes database and Vault reflection. The generic second convergence pass remains appropriate for central remote types, but must not be applied to P2P: an injected Obsidian rebuild UI would otherwise ask the user to select the same peer twice and leave reflection suspended while the second dialogue waits.
|
|
45
|
+
|
|
38
46
|
## Unsupported forced close
|
|
39
47
|
|
|
40
48
|
Do not close the raw values returned by `room.getPeers()`. Both closing them before room departure and closing captured values after departure have prevented the same peer from being rediscovered within 60 seconds in the real-transport replacement test.
|
|
@@ -43,10 +51,12 @@ Commonlib consequently does not expose a forced physical-disconnection command.
|
|
|
43
51
|
|
|
44
52
|
## Verification
|
|
45
53
|
|
|
46
|
-
Maintain all
|
|
54
|
+
Maintain all five boundaries when this lifecycle changes:
|
|
47
55
|
|
|
48
|
-
- Commonlib unit tests must prove that normal close leaves the room without directly closing Trystero-owned peers,
|
|
49
|
-
-
|
|
56
|
+
- Commonlib unit tests must prove that normal close leaves the room without directly closing Trystero-owned peers, that disabling settings cancel a pending open, and that concurrent replacement requests leave one current owner;
|
|
57
|
+
- Commonlib rebuild tests must prove that first-device P2P initialisation does not reset a remote database and that an additional-device P2P Fetch performs one explicit peer-selection pass before resuming reflection;
|
|
58
|
+
- the Self-hosted LiveSync Compose P2P lifecycle test must replace a current replicator, rediscover the same real peer, perform bidirectional RPC, and verify transferred content from a separate process;
|
|
59
|
+
- the Self-hosted LiveSync real-Obsidian P2P Setup URI workflow must generate the second-device URI on the first device, accept both peer directions visibly, and verify a two-way note round-trip; and
|
|
50
60
|
- the relay-disconnect test must observe the original WebSocket reach `CLOSED`, remain closed while reconnection is paused, and be replaced after reconnection resumes.
|
|
51
61
|
|
|
52
62
|
The corresponding product decision and rejected alternatives are recorded in Self-hosted LiveSync's P2P room and transport lifecycle ADR.
|