@vrtmrz/livesync-commonlib 0.1.0-rc.5 → 0.1.0-rc.6

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 (65) hide show
  1. package/README.md +11 -9
  2. package/dist/common/configForDoc.js +7 -2
  3. package/dist/common/models/setting.type.d.ts +2 -1
  4. package/dist/common/models/tweak.definition.d.ts +1 -1
  5. package/dist/common/settingConstants.d.ts +3 -2
  6. package/dist/common/settingConstants.js +2 -2
  7. package/dist/context.d.ts +2 -1
  8. package/dist/context.js +4 -0
  9. package/dist/replication/LiveSyncAbstractReplicator.d.ts +2 -1
  10. package/dist/serviceModules/Rebuilder.js +8 -3
  11. package/dist/services/BrowserServices.d.ts +2 -0
  12. package/dist/services/BrowserServices.js +4 -1
  13. package/dist/services/HeadlessServices.d.ts +2 -0
  14. package/dist/services/HeadlessServices.js +2 -1
  15. package/dist/services/base/CommonlibMessages.d.ts +318 -0
  16. package/dist/services/base/CommonlibMessages.js +313 -0
  17. package/dist/services/base/MessageTranslator.d.ts +5 -2
  18. package/dist/services/base/MessageTranslator.js +21 -0
  19. package/dist/services/base/ServiceBase.d.ts +1 -1
  20. package/dist/services/base/ServiceBase.js +2 -4
  21. package/dist/services/base/SettingService.d.ts +3 -0
  22. package/dist/services/base/SettingService.js +3 -2
  23. package/docs/development.md +27 -14
  24. package/docs/p2p-transport-lifecycle.md +10 -2
  25. package/docs/proven-in-use.md +18 -12
  26. package/docs/releasing.md +14 -0
  27. package/package.json +1 -26
  28. package/dist/common/i18n.d.ts +0 -18
  29. package/dist/common/i18n.js +0 -101
  30. package/dist/common/messages/combinedMessages.dev.d.ts +0 -7
  31. package/dist/common/messages/combinedMessages.dev.js +0 -44
  32. package/dist/common/messages/combinedMessages.prod.d.ts +0 -9276
  33. package/dist/common/messages/combinedMessages.prod.js +0 -9283
  34. package/dist/common/messages/de.d.ts +0 -297
  35. package/dist/common/messages/de.js +0 -7
  36. package/dist/common/messages/def.d.ts +0 -1123
  37. package/dist/common/messages/def.js +0 -7
  38. package/dist/common/messages/es.d.ts +0 -689
  39. package/dist/common/messages/es.js +0 -7
  40. package/dist/common/messages/fr.d.ts +0 -582
  41. package/dist/common/messages/fr.js +0 -7
  42. package/dist/common/messages/he.d.ts +0 -583
  43. package/dist/common/messages/he.js +0 -7
  44. package/dist/common/messages/ja.d.ts +0 -838
  45. package/dist/common/messages/ja.js +0 -7
  46. package/dist/common/messages/ko.d.ts +0 -800
  47. package/dist/common/messages/ko.js +0 -7
  48. package/dist/common/messages/ru.d.ts +0 -858
  49. package/dist/common/messages/ru.js +0 -7
  50. package/dist/common/messages/zh-tw.d.ts +0 -384
  51. package/dist/common/messages/zh-tw.js +0 -7
  52. package/dist/common/messages/zh.d.ts +0 -1093
  53. package/dist/common/messages/zh.js +0 -7
  54. package/dist/common/messagesJson/de.json +0 -295
  55. package/dist/common/messagesJson/en.json +0 -1121
  56. package/dist/common/messagesJson/es.json +0 -687
  57. package/dist/common/messagesJson/fr.json +0 -580
  58. package/dist/common/messagesJson/he.json +0 -581
  59. package/dist/common/messagesJson/ja.json +0 -836
  60. package/dist/common/messagesJson/ko.json +0 -798
  61. package/dist/common/messagesJson/ru.json +0 -856
  62. package/dist/common/messagesJson/zh-tw.json +0 -382
  63. package/dist/common/messagesJson/zh.json +0 -1091
  64. package/dist/common/rosetta.d.ts +0 -42
  65. 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 = <TKey extends string>(key: TKey, params?: TranslationParameters) => string;
5
- /** Default translator for headless clients which returns the message key unchanged. */
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
- /** Host-provided message translation. Keys pass through unchanged when omitted. */
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 ?? passthroughMessageTranslator;
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
- setLang(this.settings.displayLanguage);
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);
@@ -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`, and `src/rpc/index.ts` define the focused entries;
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
 
@@ -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
- The package publishes the generated production language catalogue as an ordinary ESM module. It does not duplicate that catalogue inside `dist/common/i18n.js`; the final application bundler remains responsible for composing the catalogue for environments such as Obsidian. Source development continues to use the JSON-derived development catalogue.
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
- ## Translation catalogue
93
-
94
- Human-edited translations live under `src/common/messagesYAML`. Regenerate derived JSON and TypeScript resources with:
98
+ ## Messages and translation
95
99
 
96
- ```bash
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
- The generated catalogue remains an optional dependency surface. Core and context imports must not load it.
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
- TODO: introduce generated API reference for a reviewed allow-list of public entry points once the high-level client façade and its lifecycle contract have been accepted.
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
- TODO: classify and document compatibility paths whose purpose is still unclear before stabilising the first public release. Remove obsolete paths rather than documenting accidental layout as API.
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).
@@ -35,6 +35,12 @@ An explicit open resumes Trystero relay reconnection before joining the configur
35
35
 
36
36
  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
37
 
38
+ ## First-device and additional-device setup
39
+
40
+ 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.
41
+
42
+ 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.
43
+
38
44
  ## Unsupported forced close
39
45
 
40
46
  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 +49,12 @@ Commonlib consequently does not expose a forced physical-disconnection command.
43
49
 
44
50
  ## Verification
45
51
 
46
- Maintain all three boundaries when this lifecycle changes:
52
+ Maintain all five boundaries when this lifecycle changes:
47
53
 
48
54
  - Commonlib unit tests must prove that normal close leaves the room without directly closing Trystero-owned peers, and that overlapping open and close requests leave one current owner;
49
- - 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; and
55
+ - 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;
56
+ - 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;
57
+ - 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
58
  - the relay-disconnect test must observe the original WebSocket reach `CLOSED`, remain closed while reconnection is paused, and be replaced after reconnection resumes.
51
59
 
52
60
  The corresponding product decision and rejected alternatives are recorded in Self-hosted LiveSync's P2P room and transport lifecycle ADR.